CMU15445(2023fall) Project #2 - Extendible Hash Index 匠心分析
胡未灭,鬓已秋,泪空流
此生谁料
心在天山
身老沧州
——诉衷情
完整代码见:
SnowLegend-star/CMU15445-2023fall: Having Conquered the Loftiest Peak, We Stand But a Step Away from Victory in This Stage. With unwavering determination, we press onward, for destiny favors those brave enough to forge ahead, cutting through the thorns and overcoming every obstacle that dares to stand in their way.
Task #1 - Read/Write Page Guards
实验说明分析:
在缓冲池管理器中,FetchPage 和 NewPage 函数返回已经锁定的页面指针。这个锁定机制确保页面在没有任何读取和写入时不会被驱逐。为了表示页面在内存中不再需要,程序员必须手动调用 UnpinPage。
然而,如果程序员忘记调用 UnpinPage,页面将永远不会被驱逐出缓冲池。由于缓冲池实际上只有较少的帧,这将导致更多的页面在磁盘和内存之间交换。这样不仅会影响性能,而且这个 bug 很难被发现。
您将实现 BasicPageGuard 类,它存储指向 BufferPoolManager 和 Page 对象的指针。一个页面保护器确保一旦超出作用域,就会调用 UnpinPage 来解除锁定页面。请注意,它仍然应该提供一个供程序员手动解除锁定页面的方法。
由于 BasicPageGuard 隐藏了底层的页面指针,它还可以提供只读/写数据的 API,这些 API 在编译时进行检查,确保正确设置 is_dirty 标志。
在这个和后续项目中,多个线程将会读取和写入相同的页面,因此需要使用读写锁来确保数据的正确性。请注意,在 Page 类中,已经为此目的提供了相关的锁方法。类似于解除锁定页面,程序员可能会忘记在使用后解除锁定。为了解决这个问题,您将实现 ReadPageGuard 和 WritePageGuard,它们会在作用域结束时自动解除页面的锁定。
由于在2024-fall的project1分析过了类似的,故实现这块不在赘述。说实话我个人还是更喜欢2023f版的,这个版本的对PageGuard进行拆分得恰到好处。先是给出BasicPageGuard让我们对PageGuard的作用有个具体的理解,再Basic的基础上可以进一步升级为ReadPageGuard(下面简写为RPG)和WritePageGuard(简写为WPG)。这一套流程看下来2024f版对PageGuard的拆分程度太高了,上来就要求实现RPG和WPG,理解起来的难度要大不少。
接下来具体分析关于如何使用PageGuard。我相信很多人可能会对As和AsMut的用法有所疑惑。但无论是RPG还是WPG,其As与AsMut都是调用BasicPG的函数。我们只要理解透彻下面四个函数那对于PageGuard的使用也就是手到擒来了。
可以发现,GetData()与As()是配套的,而GetDataMut()和AsMut()也是配套的。而且GetDataMut这个函数中,修改了is_dirty_位,这说明一旦我们选择调用AsMut,那最好是真的对page的内容进行了修改,自然也只有WPG才能调用AsMut的。
那什么时候调用RPG与WPG的情况也就呼之欲出了。只要需要修改page时,才需要调用WPG。如果只是读取page,那调用RPG就可以了。但是!如果你懒得思考要不要修改page那直接调用WPG也不是不行,就是会多造成disk IO降低吞吐率。如果不清楚是否需要修改page,保险起见可以直接调用WPG。
1. auto GetData() -> const char * { return page_->GetData(); }2. 3. template <class T>4. auto As() -> const T * {5. return reinterpret_cast<const T *>(GetData());6. }7. 8. auto GetDataMut() -> char * {9. is_dirty_ = true;
10. return page_->GetData();
11. }
12.
13. template <class T>
14. auto AsMut() -> T * {
15. return reinterpret_cast<T *>(GetDataMut());
16. }
17.
Task #2 - Extendible Hash Table Pages
实验说明分析
哈希表头页面(Hash Table Header Page)
头页面位于基于磁盘的可扩展哈希表的第一层,并且每个哈希表只有一个头页面。它存储指向目录页面的逻辑子指针(作为页面ID)。可以将其视为一个静态的第一层目录页面。头页面具有以下字段:
变量名 | 大小 | 描述 |
directory_page_ids_ | 2048 | 一个目录页面ID的数组 |
max_depth_ | 4 | 头页面可以处理的最大深度 |
请注意,尽管页面的大小是物理限制,您应该使用 max_depth_ 来确定 directory_page_ids_ 数组的上限大小。
您必须通过仅修改其头文件(src/include/storage/page/extendible_htable_header_page.h)和相应的源文件(src/storage/page/extendible_htable_header_page.cpp)来实现可扩展哈希表的头页面。
哈希表目录页面(Hash Table Directory Page)
目录页面位于基于磁盘的可扩展哈希表的第二层。每个目录页面存储指向桶页面的逻辑子指针(作为页面ID),并包含用于处理桶映射以及动态扩展和收缩目录的元数据。目录页面具有以下字段:
变量名 | 大小 | 描述 |
max_depth_ | 4 | 头页面可以处理的最大深度 |
global_depth_ | 4 | 当前目录的全局深度 |
local_depths_ | 512 | 一个桶页面本地深度的数组 |
bucket_page_ids_ | 2048 | 一个桶页面ID的数组 |
请注意,尽管页面的大小是物理限制,您应该使用 max_depth_ 来确定 bucket_page_ids_ 数组的上限大小。
您必须通过仅修改其头文件(src/include/storage/page/extendible_htable_directory_page.h)和相应的源文件(src/storage/page/extendible_htable_directory_page.cpp)来实现可扩展哈希表的目
录页面。
哈希表桶页面(Hash Table Bucket Page)
桶页面位于基于磁盘的可扩展哈希表的第三层。它们实际上存储键值对。桶页面具有以下字段:
变量名 | 大小 | 描述 |
size_ | 4 | 桶中当前存储的键值对的数量 |
max_size_ | 4 | 桶可以存储的最大键值对数量 |
array_ | 小于或等于4088 | 存储键值对的数组 |
请注意,尽管页面的大小是物理限制,您应该使用 max_size_ 来确定 array_ 数组的键值对的上限大小。
您必须通过仅修改其头文件(src/include/storage/page/extendible_htable_bucket_page.h)和相应的源文件(src/storage/page/extendible_htable_bucket_page.cpp)来实现可扩展哈希表的桶页面。
重要说明:
每个可扩展哈希表的头/目录/桶页面对应于通过缓冲池获取的内存页面的内容(即 data_ 部分)。每当您读取或写入页面时,必须先从缓冲池中获取页面(使用其唯一的 page_id),然后将其重新解释为相应的类型,在读取或写入后解锁该页面。我们强烈建议您利用在任务1中实现的 PageGuard API 来实现这一目标。
举例说明可扩展哈希的插入流程
接下来直接举个例子来解释可扩展哈希表的具体实现过程:
初始Global_Depth=0,每个Bucket的Local_Depth=0,Bucket的max_size_=2。假设我们需要插入0 1 2 3 4 5 6 7 8 。
咳咳,又到了展示我精湛画图功力的时候了。Show time!
①插入0,1。由于初始的Bucket空间大小足够,可以直接插入到Bucket0中。紫色笔记表示depth,左侧表示Directory,右侧表示Buckets。
③接下来插入2,发现B0已经满了,无法直接插入。
- 所以B0先尝试local_depth++来进行桶分裂,但是由于此时local_depth已经等于global_detph了,所以loc_d自增失败,需要glo_d先自增。此时glo_d=1
- Loc_d++,即loc_d=1,自增成功可以进行桶分裂。原桶与新桶(brother)的loc_d都是1
- 将原Bucket的元素进行重映射,即遍历B0的所有元素,进行key&loc_depth_mask将元素分配到原桶和新桶中。
如下图。0&1=0,1&1=1。所以0依然放在原桶中,1重新放在下标为1的新桶中。
- 重新尝试插入2。通过2&global_depth_mask即10&1=0来把2放入B0中。
③插入3。通过3&global_depth_mask即11&1=1来把3放入B1中。
④插入4。4&global_depth_mask即100&1=0,发现B0已经满了,故准备进行桶分裂。
- 所以B0先尝试local_depth++来进行桶分裂,但是由于此时local_depth已经等于global_detph了,所以loc_d自增失败,需要glo_d先自增。此时glo_d=2
- Loc_d++,即loc_d=2,自增成功可以进行桶分裂。原桶与新桶(brother)的loc_d都是2
- 将原Bucket的元素进行重映射,即遍历B0的所有元素,进行key&loc_depth_mask将元素分配到原桶和新桶中。
如下图。0&11=00,10&11=10。所以0依然放在原桶B0中,2重新放在下标为2的新桶B10中。
- 重新插入4。4&global_depth_mask即100&11=00,所以把4插入到B0中
⑤插入5,5& global_depth_mask即101&11=01,发现B1这个桶已经满了,准备桶分裂
- Glo_d > loc_d,loc_d++成功,故桶B1可以直接分裂,得到新桶B11
- 将原桶B1的元素进行重映射(key&local_depth_mask)分配到B01和B11中
- 重新尝试插入5,5& global_depth_mask即101&11=01,插入B01成功。如果插入失败继续尝试桶分裂。
⑥插入6,6& global_depth_mask即110&11=10,成功插入到B10中
⑦插入7,7& global_depth_mask即111&11=11,成功插入到B11中
⑧插入8,8& global_depth_mask即1000&11=00,发现桶B00已经满了,尝试进行桶分裂
- 所以B00先尝试local_depth++来进行桶分裂,但是由于此时local_depth已经等于global_detph了,所以loc_d自增失败,需要glo_d先自增。此时glo_d=3
- Loc_d++,即loc_d=2,自增成功可以进行桶分裂。原桶与新桶(brother)的loc_d都是3
- 将原Bucket的元素进行重映射,即遍历B0的所有元素,进行key&loc_depth_mask将元素分配到原桶和新桶中。
- 重新尝试插入8,8& global_depth_mask即1000&111=000插入成功。如果插入失败继续尝试桶分裂。
最后可扩展哈希表如下:
其实这个例子中,应该用page_id来标记唯一的桶,为了方便理解我就直接用下标来标识每个Bucket。
通过上述例子,我们可以总结可扩展哈希表的插入流程
- 尝试插入key。进行key&global_depth_mask从而找到对应的Bucket下标。当前Bucket不满,直接插入成功,return。如果失败进行步骤2
- Bucket满了。
- 当前global_depth > local_depth,此Bucket进行local_depth++成功,可以直接进行桶分裂。进行步骤3
- 当前global_depth =local_depth,此Bucket进行local_depth++失败,不可以可以直接进行桶分裂。进行Global_depth++,所以此Bucket可以进行local_depth++,桶分裂成功。进行步骤3
- 重映射。桶分裂成功后,遍历原Bucket,对其中的每个元素elem进行elem&local_depth_mask,从而将原Bucket的元素分配到原桶和新桶中。重新进行步骤1
实现过程分析
我最近发现了个方法论,把实验需求看了几遍之后,把lab涉及到的头文件,在这里是header_page.h、directory_page.h和bucket_page.h重新归纳一遍。只是硬看的话在实现函数的过程中很容易前面忘了,后面忘了,全忘了~简称忘3
一言蔽之,这个过程就是将插入的key进行各种转换,最终找到相应bucket。我直接将lab给出的图例进行了一番改造,下图就是一个key进行映射的过程。
为了更好地理解lab要求,在粗略浏览一番代码后,我们应该弄清楚以下几个问题:
Q:在Header部分,核心函数HashToDirectoryIndex的目的是什么呢?
A:提取key的最高几位,从而尝试进入对应的Directory。
Q:在Directory部分,如何获得Global_Depth?
A:作为task2的核心部分,大部分功能都是在directory_page.cpp进行实现的。在init()直接将Global_Depth和每个Bucket的Local_Depth都初始化为0就行。
Q:在Directory部分,HashToBucketIndex的目的是什么呢?
A:提取key的最低几位,从而尝试进入对应的bucket。这里用page其实更合适,因为每个bucket本质都是一张page。
Q:搞清楚bucket_index和page_id的区别?
A:bucket_index并不是我以为的
、
、
这种,而仅仅是指directory中的数组下标。而page_id才是真正的bucket序列号,用来区分唯一的bucket。
Q:GetSplitImageIndex()这个函数的作用是什么?
A:这个函数感觉没描述清楚,通俗来说就是获得当前bucekt的兄弟bucket。将当前bucket在Directory的下标最高有效位取反,就可以得到bro。例如,B0的兄弟是B1,B101的兄弟是B001。因为B101和B001都是从B01分裂而来的,所以他俩互为bro。
值得一提的是,task2并不需要实现这个函数。这个函数在task3才需要用到。
理解上述几个问题后,可以先尝试粗糙地将函数功能实现,然后对着测试样例一步步改进细化。
Task #3 - Extendible Hashing Implementation
实现了task2后,对可扩展哈希表的工作流程就已经大体了解得差不多了,现在就是具体实施对(key, value)的处理流程。为了找好着手点,我们可以自行模拟插入三个元素时,hash_table的工作流程。
就GetValue()、Insert()和Remove()三个核心操作而言,有一套共同的前期流程:
1、先从bufferpool中获得Header Page。至于是以ReadGuadPage还是以WriteGuadPage获得就取决于这次操作是否会修改Header Page了。得到key的最高几位后,在Header Page中找到这个key对应的Directory 页表项。如果存在,进入步骤2。
如果没找到对应的Directory,return false或者从bufferpool中申请一个新的page来存放新的Directory Page,即调用InsertToNewDirectory。
2、找到对应Directory的页表项后,以Page Guad的方式从bufferpool中获取这个Directory Page。然后得到key的最低几位后,在Directory Page中找到这个key对应的bucket页表项。如果存在,进入步骤3。
3、同样是以Page Guad的方式从bufferpool中获取这个Bucket Page,然后就可以进行具体的操作了。
4、至于桶分裂、桶合并等操作就需要自己具体实现了。
对于桶合并的问题,分为三种情况:
- 当前bucket并没有bro,即它的local_depth=0
- 当前bucket有bro,但是bro和它指向同一个bucket page,这种连体婴就不需要继续合并了
- 当前bucket有bro,且bro和它指向不同的bucket page,这种情况才可以正常合并
Q:什么时候需要合并呢?
A:当前bucket和bro有一方为空的时候进行合并。
OK,然后就是对着测试样例一步步修正自己的代码了。在提交到gradescope时,果不其然我遇到了两个bug。
遇到的bug
1、合并时机没领悟通透,像下面这种情况是需要继续合并的
2、没有及时释放页面的锁
说实话这个问题过于隐晦了。测试样例将bufferpool_size设置为3。而访问Header Page需要占据一个frame,访问对应的Directory Page需要占据第二个frame,访问对应的Bucket Page需要占据第三个frame。
这个时候,如果需要访问当前bucket的bro,就需要从当前bufferpool中逐出一个page。但是由于我没有及时释放Header Page,就导致前面三个page赖在bufferpool不走了,也就无法访问新的page,造成访问地址错误。
其实我感觉设置bufferpool_size=3是真的过于刻意了,就是盯着只有Header Page只有1个才想出来的馊主意。如果最高级的是root page,而且Header Page不止1个呢,那估计就会设置个bufferpool_size=4来卡一手人了。
总而言之,个人感觉Extendible Hash Index思维难度并不高,代码量也适中。给我的感觉是构建一个b+树demo工作量就能与之一战了。
最后放一张通过的图
相关文章:
CMU15445(2023fall) Project #2 - Extendible Hash Index 匠心分析
胡未灭,鬓已秋,泪空流 此生谁料 心在天山 身老沧州 ——诉衷情 完整代码见: SnowLegend-star/CMU15445-2023fall: Having Conquered the Loftiest Peak, We Stand But a Step Away from Victory in This Stage. With unwavering determinati…...
深度剖析Seata源码:解锁分布式事务处理的核心逻辑
文章目录 写在文章开头如何使用源码(配置转掉)基于AT模式详解Seata全链路流程Seata服务端启动本地服务如何基于GlobalTransaction注解开启事务客户端如何开启分布式事务RM和TC如何协调处理分支事务RM生成回滚日志事务全局提交与回滚小结参考写在文章开头 在当今分布式系统日益…...
python配置mmcv与mmdet环境
首先查看自己的cuda版本 nvcc --version 安装与cuda对应的torch版本,对应关系 Previous PyTorch Versions | PyTorch 安装对应的mmcv版本,使用下面命令可以自动安装匹配的版本,使用mim安装 mim install mmcv-full -f https://download.o…...
ESP 32控制无刷电机2
import machine import time import socket import network from machine import I2C, Pin, ADC def start_ap(): """ 启动ESP32的AP模式 """ ap network.WLAN(network.AP_IF) ap.active(True) ssid ESP32_APTest …...
【uniapp原生】实时记录接口请求延迟,并生成写入文件到安卓设备
在开发实时数据监控应用时,记录接口请求的延迟对于性能分析和用户体验优化至关重要。本文将基于 UniApp 框架,介绍如何实现一个实时记录接口请求延迟的功能,并深入解析相关代码的实现细节。 前期准备&必要的理解 1. 功能概述 该功能的…...
wps角标快速生成
使用^#符号匹配数字,将[^#]内容找到,随后在格式-字体中选择上标,逐个/批量替换即可(比一点点改效率翻倍)...
Azure Speech
1、文字转语音(Text-To-Speech, TTS) 2、语音转文字(Speech-To-Text): Azure Speech to Text 1- 环境配置:Microsoft Azure 注册使用免费服务: 需要信用卡,本人没有,所以没有完成注册...
SHELL32!ILCombine函数分析之连接两个idl
SHELL32!ILCombine函数分析之连接两个idl 第一部分: STDAPI_(LPITEMIDLIST) ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { // Let me pass in NULL pointers if (!pidl1) { if (!pidl2) { return NULL; …...
学习threejs,使用ShaderMaterial自定义着色器材质
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.ShaderMaterial1.1.1…...
使用 Selenium 和 Requests 自动化获取动态 Referer 和 Sign 的完整指南
在现代网络爬虫和自动化任务中,动态生成的参数(如 Referer 和 Sign)常常是绕过反爬虫机制的关键。本文将详细介绍如何使用 Python 的 Selenium 和 Requests 库,从目标网页中提取动态 Referer 和 Sign,并完成后续的请求…...
1.2.3 使用Spring Initializr方式构建Spring Boot项目
本实战概述介绍了如何使用Spring Initializr创建Spring Boot项目,并进行基本配置。首先,通过Spring Initializr生成项目骨架,然后创建控制器HelloController,定义处理GET请求的方法hello,返回HTML字符串。接着…...
Cursor+pycharm接入Codeuim(免费版),Tab自动补全功能平替
如题,笔者在Cursor中使用pycharm写python程序,试用期到了Tab自动补全功能就不能用了,安装Codeuim插件可以代替这个功能。步骤如下: 1. 在应用商店中搜索扩展Codeuim,下载安装 2. 安装完成后左下角会弹出提示框&#x…...
Ruby基础
一、字符串 定义 283.to_s //转为string "something#{a}" //定义字符串,并且插入a变量的值 something//单引号定义变量 %q(aaaaaaaaa) // 定义字符串,()内可以是任何数,自动转义双引号%Q("aaaaa"…...
wzl-django学习
####################################################总的urls.py from django.contrib import admin from django.urls import path,include, re_path from django.views.static import serve from django.conf import settings from drf_yasg import openapi from drf_yas…...
《AI强化学习:元应用中用户行为引导的智能引擎》
在科技飞速发展的当下,元应用正以前所未有的速度融入我们的生活,从沉浸式的虚拟社交到高度仿真的工作模拟,元应用构建出一个个丰富多彩的虚拟世界。而在这背后,人工智能的强化学习技术宛如一位无形却强大的幕后推手,深…...
Django基础环境准备
Django基础环境准备 文章目录 Django基础环境准备1.准备的环境 win11系统(运用虚拟环境搭建)1.1详见我的资源win11环境搭建 2.准备python环境2.1 winr 打开命令提示符 输入cmd 进入控制台2.2 输入python --version 查看是否有python环境2.3在pyhton官网下…...
机器视觉线阵相机分时频闪选型/机器视觉线阵相机分时频闪选型
在机器视觉系统中,线阵相机的分时频闪技术通过单次扫描切换不同光源或亮度,实现在一幅图像中捕捉多角度光照效果,从而提升缺陷检测效率并降低成本。以下是分时频闪线阵相机的选型要点及关键考量因素: 一、分时频闪技术的核心需求 多光源同步控制 分时频闪需相机支持多路光源…...
【企业场景】上线的项目如何进行限流
一、常见的四种速率限流算法 对于限流,最为直接的就是速率限流了 固定窗口算法 比如 10r/s 就是把时间线分为 1s 一段,也就是周期为 1s,对一个时间段的请求进行计数,超过 10 则舍弃,未超过则直接处理经过 1s 后&…...
【FL0090】基于SSM和微信小程序的球馆预约系统
🧑💻博主介绍🧑💻 全网粉丝10W,CSDN全栈领域优质创作者,博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战,以及程序定制化开发…...
用大白话解释缓存Redis +MongoDB是什么有什么用怎么用
Redis和MongoDB是什么? Redis:像你家的“小冰箱”,专门存高频使用的食物(数据)。它是基于内存的键值数据库,读写速度极快(每秒超10万次操作)。比如你每次打开手机App,用…...
软件测试需求分析如何实施?专业软件测试服务公司分享
在现代软件开发中,软件测试需求分析被认为是确保软件质量的关键环节之一。软件测试需求分析是指在软件开发过程中,对测试需求进行系统性分析的过程。它旨在确定软件系统功能、性能及其他非功能性需求的具体细节,从而为后续的测试活动提供指导…...
pg pg_prewarm用法
按照插件 > create extension pg_prewarm ;缓存表 > test# select pg_prewarm(weather,buffer ) ; pg_prewarm > ------------ > 1缓存表部分内容 test# select pg_prewarm(weather,buffer,main,0,0) ;pg_prewarm ------------1 (1 row)表大小只有0号…...
2025年光电科学与智能传感国际学术会议(ICOIS 2025)
重要信息 官网:www.ic-icois.org 时间:2025年3月14-16日 地点:中国-长春 简介 2025年光电科学与智能传感国际学术会议(ICOIS 2025)将于2025年3月14-16日在中国-长春隆重召开。会议将围绕“光学光电”、“智能传感”…...
uni小程序wx.switchTab有时候跳转错误tab问题,解决办法
在一个子页面里面使用uni.switchTab或者wx.switchTab跳转到tab菜单的时候,先发送了一个请求,然后执行跳转到tab菜单,但是这个时候,出错了........也是非常的奇怪,不加请求就没问题......但是业务逻辑就是要先执行某个请…...
python-leetcode-下一个排列
31. 下一个排列 - 力扣(LeetCode) class Solution:def nextPermutation(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""# Step 1: Find the first decreasing element …...
如何获取mac os 安装盘
发现虚拟机VirtualBox支持Mac虚拟,就想尝试一下。但是发现Mac的安装盘特别难拿到,因此留档。 第一种方法 在mac环境下,使用softwareupdate命令来获取mac安装,能获得当前设备支持的系统。 使用这个命令:/usr/sbin/soft…...
常见AI写作工具介绍(ChatGPT 4o、DeepClaude、Claude 3.5 Sonnet 、DeepSeek R1等)
AI写作工具介绍 1. ChatGPT-4o ChatGPT-4o是OpenAI于2024年5月发布的最新旗舰模型,相比之前的版本,它在多模态支持和实时推理能力上有了显著提升。它能够处理和理解音频、图像和文本数据,适用于复杂的图像分析、语音识别等应用场景[1]。 2…...
环境会影响你的决策:K近邻算法(KNN)
环境会影响你的决策:K近邻算法(KNN) 1. 核心思想与流程 KNN是一种基于局部相似性的分类算法,核心思想是“近朱者赤”:待测样本的类别由其最近的k个邻居的多数类别决定。 关键步骤: 定义空间与距离:通常采…...
JMeter 中实现 100 个用户在 3 秒内并发登录
在 JMeter 中实现 100 个用户在 3 秒内并发登录,需要合理配置线程组、定时器和测试逻辑。以下是具体步骤: 1. 创建测试计划 打开 JMeter。右键点击“Test Plan”,选择 Add > Threads (Users) > Thread Group。 : 设置为 100(模拟 100 个用户)。 : 设置为 3...
2-3文件的属性信息
文章目录 1 file命令2 stat命令 1 file命令 用来识别文件类型 # 参数的位置是任意的 file 文件名 [参数]-b 只显示文件类型和文件编码,不显示文件名-i 显示文件的MIME类型-F 设置输出字符串的分隔符-L 查看软链接文件自身文件属性liyblyb:/tmp$ file xxxtmp.log …...
【云原生之kubernetes实战】在k8s环境中高效部署Vikunja任务管理工具(含数据库配置)
【【云原生之kubernetes实战】在k8s环境中高效部署Vikunja任务管理工具(含数据库配置) 前言一、Vikunja介绍1.1 Vikunja简介1.2 Vikunja主要特点1.3 使用场景二、相关知识介绍2.1 本次实践存储介绍2.2 k8s存储介绍三、本次实践介绍3.1 本次实践简介3.2 本次环境规划3.3 部署前…...
(IDE接入DeepSeek)简单了解DeepSeek接入辅助开发与本地部署建议
重点:IDE接入DeepSeek是否收费 收费! 本文章主要是为了给小白避雷,目前很多文章告诉大家怎么接入DeepSeek,但是并未告知大家是否收费。如果是想白嫖的,就可以不用去接入了。 一、引言 最近爆火的AI人工智能工具DeepSe…...
TCP的三次握手与四次挥手:建立与终止连接的关键步骤
引言 TCP(传输控制协议)工作在OSI模型的传输层。OSI模型将计算机网络功能划分为七个层级,从底层到顶层依次是:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。传输层负责在网络节点之间提供可靠的端到端通信&a…...
CMU15445(2023fall) Project #3 - Query Execution(上)详细分析
晚日寒鸦一片愁 柳塘新绿却温柔 若教眼底无离恨 不信人间有白头 ——鹧鸪天 完整代码见: SnowLegend-star/CMU15445-2023fall: Having Conquered the Loftiest Peak, We Stand But a Step Away from Victory in This Stage. With unwavering determination, we pre…...
.sql文件怎么打开
.sql 文件是一个 SQL 脚本文件,通常包含了数据库的 SQL 查询语句,可以是创建数据库、创建表、插入数据、查询数据等操作。要打开并查看 .sql 文件,你可以使用以下几种方法: 1. 使用文本编辑器打开 .sql 文件是一个文本文件&…...
【Swift 算法实战】城市天际线问题解法
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...
Linux的软件安装
Linux命令行内的“应用商店” yum命令安装软件。 yum命令: yum:RPM软件管理器,用于自动化安装配置Linux软件,可以自动解决依赖问题。 语法:yum [-y] [install | remove | search] 软件名称 选项:-y。自动确…...
需求和开发模型
文章目录 什么是需求?用户需求软件需求用户需求和软件需求的不同 开发模型什么是“模型”?软件的生命周期常见的开发模型瀑布模型(Waterfall Model)螺旋模型增量模型、迭代模型敏捷模型 测试模型V 模型W 模型(双 V 模型…...
unity学习61:UI布局layout
目录 1 布局 layout 1.1 先准备测试UI,新增这样一组 panel 和 image 1.2 新增 vertical layout 1.3 现在移动任意一个image 都会影响其他 1.3.1 对比 如果没有这个,就会是覆盖效果了 1.3.2 对比 如果没有这个,就会是覆盖效果了 1.4 总结…...
腾讯混元文生图大模型(Hunyuan-DiT)与Stable Diffusion(SD)对比分析
腾讯混元文生图大模型(Hunyuan-DiT)与Stable Diffusion(SD)对比分析 腾讯混元文生图大模型(Hunyuan-DiT)与Stable Diffusion(SD)作为当前文生图领域的两大代表模型,各自…...
Flume
Flume安装配置 使用的三台主机名称分别为bigdata1,bigdata2,bigdata3。所使用的安装包名称按自己的修改,安装包可去各大官网上下载 1.解压 将Master节点Flume安装包解压到/opt/module目录下 tar -zxvf /opt/software/apache-flume-1.9.0-bi…...
【Python LeetCode】面试经典 150 题
数组 / 字符串快慢指针(双指针)总结88. 合并两个有序数组27. 移除元素26. 删除有序数组中的重复项80. 删除有序数组中的重复项 II Boyer-Moore 投票算法169. 多数元素扩展:寻找 n/3 多数元素 翻转法189. 轮转数组 贪心121. 买卖股票的最佳时机…...
营养助力:进行性核上性麻痹患者的饮食管理
进行性核上性麻痹是一种复杂的神经系统退行性疾病,科学的饮食管理不仅能够改善患者的营养状况,还能为神经系统提供必要的支持,延缓病情进展。 这种疾病会导致吞咽困难、营养吸收障碍等问题,增加营养不良的风险。针对性的饮食调理能…...
spineNET模型详解及代码复现
模型背景 在SpineNet模型诞生之前,多尺度特征融合已成为计算机视觉领域的研究热点。研究者们提出了各种方法来处理不同尺度的特征,如 特征金字塔网络(FPN) 和 深度可分离卷积 。然而,这些方法在跨尺度特征融合方面仍存在局限性。 FPN通过自上而下的路径融合不同尺度的特…...
【Mybatis】如何简单使用mybatis-plus,以及MybatisGenerator自动生成或者实现SQL语句
前言 🌟🌟本期讲解关于mybatis中SQL自动生成的相关知识介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆…...
ds-国内主要显卡
国产显卡 寒武纪思元系列 思元 370:采用 7nm 制程工艺及 chiplet 技术,集成 390 亿个晶体管,最大算力高达 256TOPS(INT8)。是国内第一款公开发布支持 LPDDR5 内存的云端 AI 芯片,内存带宽是上一代产品的 3 …...
类和对象——const修饰的类的对象和函数
const修饰的类的对象和函数 const成员函数和const对象1 const成员函数2 调用关系3 const在成员函数中的位置4 取地址&及const取地址操作符重载 const成员函数和const对象 1 const成员函数 将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数&…...
防火墙的智能选路与NAT实验
实验拓扑 配置IP 防火墙的安全区域划分 销售部和运维部不能互相访问,采取vlan的方式来进行隔离。 在配置vlan之后 ,两个部门将不会通信。 以上是基础配置,只是演示在各个部门不通的情况下,使用什么技术来进行隔离网络,…...
ARM学习(43)armcc HardFault函数链接不到的问题理解
armcc HardFault函数链接不到的问题理解 1、问题背景: 笔者汇编语言编写了一个HardFault异常处理函数,HardFault函数属于芯片架构异常处理函数,没有显著的调用(中断向量表中有该函数地址),且启动函数里面也…...
php序列化与反序列化
文章目录 基础知识魔术方法:在序列化和反序列化过程中自动调用的方法什么是 __destruct() 方法?何时触发 __destruct() 方法?用途:语法示例: 反序列化漏洞利用前提条件一些绕过策略绕过__wakeup函数绕过正则匹配绕过相…...