[OS] A4-前菜介绍
从你的描述来看,这段话是给你的一些 预备知识 和 mkfs工具的使用 提示,帮助你了解如何构建和管理文件系统,特别是关于 xv6 文件系统的一些基本操作。
我会通过比喻和通俗化的方式逐步解释:
预备知识:xv6 文件系统的基本结构
-
文件系统的构建:
文件系统就像一个巨大的 书库,里面存放着你所有的文件(数据块)。在开始实现文件系统的功能之前,你需要了解这个书库是如何构建的。就像你需要了解书架的设计、每一层存放了多少书、怎么存放书籍,文件系统也是在操作这些基本的“块”(blocks)。 -
mkfs 程序:
mkfs
程序就像是 构建书架 的工具,它根据指定的参数建立一个文件系统(类似创建一个空的书库)。在mkfs
执行时,它会给你一些信息,比如文件系统有多少个“书架”(数据块)可以使用。 -
FSSIZE 参数:
FSSIZE
就是设定书库的 大小,它告诉文件系统最多可以有多少个块(书架)。在你给出的例子中,FSSIZE
被设置为 200,000 个块,这意味着整个文件系统最多可以拥有 200,000 个块来存储数据。 -
输出信息: 当你运行
mkfs
时,它会输出文件系统的基本信息,告诉你文件系统的构建情况。例如:nmeta 70 (boot, super, log blocks 30 inode blocks 13, bitmap blocks 25) blocks 199930 total 200000
这里的意思是,文件系统的总共有 200,000 个块,其中:
- 70 个块用于元数据(这些是描述文件系统本身的数据块)
- 199,930 个块用于实际存储数据(数据块)
你可以把这看作是文件系统构建后,书架和书箱的分配情况:70 个书架用于存放“书库”的管理信息,其余的都用来存放实际的书籍(数据)。
-
重建文件系统:
如果在开发过程中你需要重新构建文件系统(比如修改了文件系统的设计),你可以运行make clean
,这会删除之前的文件系统,强制重新构建一个新的fs.img
。
通俗化解释:
- 你在做这个作业时,可以把 文件系统 想象成一个书库,每本书就是一个数据块。
- mkfs 就像是一个工具,帮助你搭建这个书库,它决定书库一共会有多少个书架(块)。
- 在文件系统创建过程中,FSSIZE 就是控制书库的总容量(有多少个书架)。比如,200,000 块表示书库有 200,000 个“书架”,你可以用它们来存放数据。
- 元数据 是文件系统本身的管理信息,类似书库的管理者放置在特殊书架上的信息,比如如何分类、哪些书架还空着等。
- 数据块 就是实际存放文件内容的块,也就是你可以用来存放实际“书”的地方。
通过这样的理解,你会更清楚文件系统构建的基本框架,以及如何使用 mkfs
来创建一个文件系统。
格式指南
项目的结构如下图所示。你也可以使用 ls
命令检查你的目录结构是否正确。目录结构不匹配将导致扣分。
对于本次作业,你不需要为附加题(Bonus Part)单独创建文件夹。source
文件夹应包含以下四个文件:
fs.c
file.h
fs.h
sysfile.c
如果要提交第 4 次作业的附加题实现,请单独提交以下文件:
fs_ec.h
fs_ec.c
示例目录结构如下:
main@ubuntu:~/Desktop/Assignment_4_120010001$ ls
Report.pdf source/
(一个文件夹和一个 PDF 文件)
在 source
文件夹下:
main@ubuntu:~/Desktop/Assignment_4_120010001/source$ ls
file.h fs.c fs.h sysfile.c
(两个 .c 文件和两个 .h 文件)
请将包含所有所需文件的文件夹压缩成一个 zip 文件,文件名格式应为你的学号,具体如下:
示例文件名:Assignment_4_120010001.zip
报告(Report)应以 PDF 格式提交,并与源代码文件一起包含在压缩包中。格式不符将导致扣分。
压缩代码的示例步骤:
main@ubuntu:~/Desktop$ zip -q -r Assignment_4_120010001.zip Assignment_4_120010001
main@ubuntu:~/Desktop$ ls
Assignment_4_120010001
Assignment_4_120010001.zip
以下是对这段说明的翻译和整理:
指导说明
-
限制范围:
你的实现范围仅限于以下四个文件:fs.c
file.h
fs.h
sysfile.c
代码需要从标记为
"TODO:"
的注释部分开始实现。 -
测试程序入口:
测试程序的入口文件是bigfile.c
和symlinktest.c
,它们位于xv6-labs-2022/user
目录下。
(这是你开始了解测试如何运行的地方。) -
带有 (*) 的部分:
- 这些部分是引导性内容,介绍了工具和函数,帮助你理解系统的功能以及这些组件如何协同工作。
- 这些部分的代码你需要仔细阅读和理解,但不要修改,除非是标记了
"TODO:"
的部分。
指导建议:
- 先理解引导部分的函数是如何工作的,以及如何使用这些函数。
- 在开始实现作业之前,确保你已经对相关内容有了基本的理解。
- 我们认为这些引导部分的内容已经足够完成本次作业。
-
可选内容(兴趣拓展):
- 如果你对 xv6 系统感兴趣并希望深入学习,欢迎阅读《xv6-book》以获取更多细节:
xv6-book PDF
- 如果你对 xv6 系统感兴趣并希望深入学习,欢迎阅读《xv6-book》以获取更多细节:
-
没有 (*) 的部分:
- 这些部分是需要你实现的
"TODO:"
部分,包含逻辑说明。 - 在这些部分,你需要根据引导部分介绍的逻辑和提供的 API 来实现函数。
- 这些部分是需要你实现的
-
实现提示:
- 示例代码不会提供。
- 你需要根据引导部分提供的逻辑和 API 自行推导和实现代码功能。
预先准备与设计(吐槽:这部分作业比3050的指导清晰多了)
任务 1:支持大文件
1. 当前 xv6 文件系统的文件大小限制
- 现状:
- 目前 xv6 文件的最大大小是 268 个块,即 268 × BSIZE 字节(
BSIZE
在 xv6 中是 1024 字节,即一个块的大小)。 - 这个限制来源于 xv6 的 inode 结构:
- 每个 inode 包含 12 个直接块指针 和 1 个单重间接块指针。
- 单重间接块指针 指向一个块,该块中可以存储 256 个数据块的地址。
- 计算文件最大块数:
12 + 256 = 268
。
- 目前 xv6 文件的最大大小是 268 个块,即 268 × BSIZE 字节(
2. 当前测试程序问题:bigfile
命令
- 测试失败原因:
bigfile
命令尝试创建一个 尽可能大的文件 并报告其大小。- 提供的模板程序无法写满 256 块,因为测试期望文件能够支持 65803 块。
- 原因是:未修改的 xv6 系统将文件限制在 268 块,而不是测试期望的 65803 块。
3. 目标:实现双重间接块
-
修改需求:
- 修改 xv6 文件系统,使其支持 双重间接块。
- 每个 inode 添加一个 双重间接块指针。具体逻辑:
- 双重间接块指针 指向一个块(双重间接块),该块包含 256 个单重间接块的地址。
- 每个单重间接块包含 256 个数据块的地址。
-
修改后的最大块数:
- 文件最多可以有:
256 × 256 + 256 + 11 = 65,803 块。- 解释:
- 256 × 256:双重间接块支持的块数(256 个单重间接块,每个单重间接块支持 256 个数据块)。
- 256:单重间接块本身支持的块数。
- 11:剩下的直接块(从原来的 12 减去一个用于双重间接块指针)。
- 解释:
- 文件最多可以有:
4. 可选任务:实现三重间接块(额外加分)
-
三重间接块的工作方式:
- 每个 三重间接块 包含 256 个双重间接块的地址。
- 每个双重间接块又指向 256 个单重间接块,每个单重间接块再指向 256 个数据块。
- 结果是一个文件的块数可以大幅提升,达到: 256 × 256 × 256 + 256 × 256 + 256 + 11。
-
加分实现建议:
- 三重间接块的实现逻辑与双重间接块类似,主要是增加一层指针解析。
- 对文件系统性能要求更高,可以在完成双重间接块后尝试实现。
总结
- 目标任务:
- 修改文件系统的 inode 结构,增加对 双重间接块 的支持,从而提升文件系统的最大文件大小到 65803 块。
- 额外加分任务:
- 在双重间接块的基础上实现 三重间接块,进一步提升文件系统的支持能力。
以下是这段说明的翻译和解析,帮助你理解所需的定义和结构的作用:
定义与说明
阅读参考:
- 如需详细信息,可参阅《xv6-book》第 8.10 节。
- 根据以上提示和定义,代码中提供了修改后的结构,请仔细阅读代码中的注释。
修改后的定义(kernel/fs.h
中的宏定义)
- 宏定义解释:
-
#define NDIRECT 11
- 直接块的数量从 12 减少到 11。
- 这是因为第 12 个直接块的位置被牺牲,改为存储 双重间接块指针。
-
#define NINDIRECT (BSIZE / sizeof(uint))
- 表示单重间接块中可以存储的块指针数量。
- 计算公式:
BSIZE / sizeof(uint)
,即 1024 / 4 = 256。
-
#define DNINDIRECT (NINDIRECT * NINDIRECT)
- 表示双重间接块可以存储的数据块数量。
- 计算公式:
256 × 256 = 65536
。
-
#define MAXFILE (NDIRECT + NINDIRECT + DNINDIRECT)
- 表示一个文件的最大块数(直接块 + 单重间接块 + 双重间接块)。
- 计算公式:
11 + 256 + 65536 = 65803
。
-
修改后的结构(kernel/fs.h
中的 dinode
)
struct dinode
的定义:- 作用:表示磁盘上的 inode 结构,包含文件的元信息和块指针。
- 关键字段解释:
short type
:文件类型。short major
:主设备号(仅适用于设备文件)。short minor
:次设备号(仅适用于设备文件)。short nlink
:文件链接数(硬链接数量)。uint size
:文件的大小(以字节为单位)。uint addrs[NDIRECT + 2]
:addrs
是块地址数组:- 前 11 个地址是直接块指针。
- 第 12 个地址是单重间接块指针。
- 第 13 个地址是双重间接块指针(新增)。
修改后的结构(kernel/file.h
中的 inode
)
struct inode
的定义:- 作用:表示内存中的 inode 结构,是
dinode
的内存副本。 - 关键字段解释:
uint dev
:设备号。uint inum
:inode 编号。int ref
:引用计数。struct sleeplock lock
:锁,用于保护结构中其他字段的并发访问。int valid
:是否已从磁盘加载。uint addrs[NDIRECT + 2]
:- 同
dinode
中的addrs
,用于存储直接块、单重间接块和双重间接块的指针。
- 同
- 作用:表示内存中的 inode 结构,是
修改注意事项
-
修改说明:
- 结构不可更改:上述的结构(
dinode
和inode
)已提供,请勿修改。 - 仅在
TODO
标记部分实现逻辑。
- 结构不可更改:上述的结构(
-
关键变化总结:
- 直接块减少到 11:因为要为双重间接块腾出位置。
- 新增双重间接块支持:在
addrs
的最后一个位置存储双重间接块的指针。
//TODO
这一块主要是定义了文件系统中 inode 结构 和一些与块分配相关的宏,用于支持你在作业中实现对大文件的管理。下面是逐步解释,让你更容易理解它们的作用:
什么是 inode?
inode
(索引节点)是文件系统中用来描述文件的一个核心数据结构。它不是存储文件内容本身,而是存储文件的元信息,比如:
- 文件的类型(普通文件、目录、设备文件等)
- 文件的大小
- 文件的块地址(指向实际存储数据的位置)
在这个作业中,你要修改 xv6 的 inode
结构以支持 双重间接块,从而使文件系统能管理更大的文件。
宏定义的作用
-
NDIRECT
- 表示直接块的数量。
- 直接块是
inode
中直接指向数据块的指针。 - 默认情况下是 12,但为了支持双重间接块,作业中改成了 11,把最后一个位置用于双重间接块指针。
-
NINDIRECT
- 表示单重间接块中可以存储的块地址数量。
- 单重间接块是
inode
指向的一个中间块,这个块不存放数据,而是存储其他块的地址。 - 计算公式是:
NINDIRECT = BSIZE / sizeof(uint)
其中BSIZE = 1024
,sizeof(uint) = 4
,所以NINDIRECT = 1024 / 4 = 256
。
-
DNINDIRECT
- 表示双重间接块中可以存储的块地址数量。
- 双重间接块是一个两级指针:
- 第一层存储指向单重间接块的地址(256 个)。
- 每个单重间接块又存储 256 个数据块的地址。
- 计算公式是:
DNINDIRECT = NINDIRECT * NINDIRECT = 256 × 256 = 65536
。
-
MAXFILE
- 表示一个文件能使用的最大块数,包括:
- 11 个直接块。
- 256 个单重间接块。
- 65536 个双重间接块。
- 计算公式是:
MAXFILE = NDIRECT + NINDIRECT + DNINDIRECT = 11 + 256 + 65536 = 65803
。
- 表示一个文件能使用的最大块数,包括:
dinode
和 inode
结构
1. dinode
(磁盘上的 inode)
- 作用:这是保存在磁盘上的
inode
结构,记录文件的元信息和块指针。 - 字段解释:
uint addrs[NDIRECT + 2]
:- 存储文件块的指针数组:
- 前 11 个是直接块指针。
- 第 12 个是单重间接块指针。
- 第 13 个是双重间接块指针。
- 存储文件块的指针数组:
2. inode
(内存中的 inode)
- 作用:这是加载到内存中的
inode
结构,用于操作文件时临时存储。 - 字段解释:
uint addrs[NDIRECT + 2]
:- 同样存储直接块、单重间接块和双重间接块指针。
总结:这部分的重点
-
你需要了解的变化:
NDIRECT
从 12 改为 11,用于给双重间接块腾出空间。addrs[NDIRECT + 2]
:- 现在包含了双重间接块指针(第 13 个位置)。
-
这些定义和结构不需要修改:
- 它们是预先提供的基础代码,已经为你实现了双重间接块所需的结构调整。
-
你的任务:
- 在作业中,围绕这些结构实现双重间接块的逻辑,包括数据块分配、释放、读取和写入。
块管理相关 API 的详细说明
Block Management(块管理)
文件系统中的块管理是核心部分,用来分配、释放、读取和写入磁盘块。这些 API 主要分为以下几类:
- 定义在
fs.c
中的块操作函数 - 定义在
bio.c
中的缓冲区操作函数 - 定义在
log.c
中的日志记录函数
1. 块管理函数(定义在 fs.c
)
1.1 bzero(int dev, int bno)
- 作用:将指定的磁盘块清零(所有内容置为 0)。
- 参数:
dev
:设备号,表示在哪个设备上执行操作。bno
:块号,表示要清零的块。
- 比喻:这就像你借了一本旧书(磁盘块),需要先擦掉上面的字迹(清零)再开始使用。
1.2 uint balloc(uint dev)
- 作用:分配一个新的磁盘块,并将其内容清零。
- 返回值:
- 成功时返回新分配块的块号。
- 如果磁盘空间不足,返回 0。
- 比喻:这就像向图书管理员申请一本空白的新书。如果图书馆满了(磁盘空间不足),就无法分配。
1.3 void bfree(int dev, uint b)
- 作用:释放一个指定的磁盘块,使其可以被其他文件使用。
- 参数:
dev
:设备号。b
:要释放的块号。
- 比喻:这就像你还书(释放块),让图书管理员把它放回书架,其他人可以借用。
2. 缓冲区管理函数(定义在 bio.c
)
2.1 struct buf* bread(uint dev, uint blockno)
- 作用:从磁盘读取指定块到缓冲区,并返回一个已锁定的缓冲区对象。
- 返回值:返回一个指向缓冲区对象的指针。
- 比喻:这就像从仓库(磁盘)把一本书拿到借阅区(缓冲区),并锁定它以防止其他人同时访问。
2.2 void brelse(struct buf *b)
- 作用:释放缓冲区对象,将其移动到最近使用列表的头部,表示可以被其他进程使用。
- 参数:
b
:指向缓冲区对象的指针。
- 比喻:这就像你看完书后,把书放回借阅区的书架上,让其他人可以继续借阅。
3. 日志管理函数(定义在 log.c
)
3.1 void log_write(struct buf *b)
- 作用:将缓冲区中的数据标记为已修改,并记录日志以便稍后写入磁盘。
- 典型用法:
- 调用
bread()
获取缓冲区。 - 修改缓冲区中的数据。
- 调用
log_write()
记录修改。 - 调用
brelse()
释放缓冲区。
- 调用
- 比喻:这就像你拿到一本书后,在书上做笔记,然后告诉管理员这些修改需要最终保存到书里。
API 使用场景
这些 API 是实现文件系统操作的基础模块,具体用法如下:
-
分配和释放磁盘块:
- 使用
balloc()
分配一个新的磁盘块,并自动清零。 - 使用
bfree()
释放一个不再需要的磁盘块。
- 使用
-
读取和操作磁盘块:
- 使用
bread()
从磁盘读取块到缓冲区。 - 修改缓冲区数据后,使用
log_write()
标记为已修改。 - 使用
brelse()
释放缓冲区。
- 使用
-
清零磁盘块:
- 使用
bzero()
将一个磁盘块的内容清零。
- 使用
总结:API 的关系与比喻
-
分配块:
balloc()
就像借一本新书,同时自动清空书页内容。bfree()
就像还书,让其他人可以使用。
-
操作块:
bread()
就像从仓库把书拿到借阅区,锁定它以防止冲突。- 修改书后,使用
log_write()
记录你的修改,并稍后保存到仓库。 brelse()
就是看完书后,放回借阅区供其他人使用。
下面是包含具体代码的内容以及每行代码的注释和比喻说明:
块管理代码
定义在 fs.c
中
// 将指定的磁盘块清零(将块内容全部置为 0)
static void bzero(int dev, int bno) {struct buf *bp = bread(dev, bno); // 从磁盘读取块 bno 到缓冲区memset(bp->data, 0, BSIZE); // 将缓冲区中的数据清零log_write(bp); // 标记缓冲区为已修改,记录日志brelse(bp); // 释放缓冲区
}
逐行说明:
bread(dev, bno)
:从设备号dev
中读取块号bno
的内容到缓冲区bp
。- 比喻:从仓库(磁盘)取出书(块)到借阅区(缓冲区)。
memset(bp->data, 0, BSIZE)
:将缓冲区的数据清零。- 比喻:把书的内容擦掉,变成一本空白的书。
log_write(bp)
:记录这次清零操作,稍后写回磁盘。- 比喻:告诉管理员这本书已经被清零了,需要保存到仓库。
brelse(bp)
:释放缓冲区。- 比喻:把书放回借阅区的书架上,供其他人使用。
// 分配一个新的磁盘块,并清零其内容
static uint balloc(uint dev) {for (int b = 0; b < FSSIZE; b++) { // 遍历磁盘所有块if (block_is_free(dev, b)) { // 如果块 b 是空闲的bzero(dev, b); // 将块 b 的内容清零mark_block_used(dev, b); // 将块 b 标记为已使用return b; // 返回新分配的块号}}return 0; // 如果没有可用的块,返回 0
}
逐行说明:
- 遍历块:通过循环遍历磁盘中的每个块。
- 比喻:管理员在整个仓库中寻找空白的书架。
block_is_free(dev, b)
:检查块是否是空闲的。- 比喻:检查这个书架是否没有放书。
bzero(dev, b)
:将空闲块的内容清零。- 比喻:如果书架是空的,先清空上面的灰尘。
mark_block_used(dev, b)
:将块标记为已使用。- 比喻:在记录本上标注这本书(块)已经借出去。
- 返回块号:如果找到空闲块,返回其编号。
// 释放一个磁盘块
static void bfree(int dev, uint b) {clear_block_usage(dev, b); // 将块 b 标记为未使用
}
逐行说明:
clear_block_usage(dev, b)
:将块号 b 标记为未使用。- 比喻:把书架上的书还给图书馆,标记这个书架可以再次使用。
定义在 bio.c
中
// 从磁盘读取指定块到缓冲区,并返回缓冲区对象
struct buf* bread(uint dev, uint blockno) {struct buf *bp = buffer_cache_find(dev, blockno); // 在缓存中查找块if (!bp) { // 如果缓存中没有bp = buffer_cache_allocate(dev, blockno); // 分配一个新的缓冲区disk_read(dev, blockno, bp->data); // 从磁盘读取块数据到缓冲区}lock_buffer(bp); // 锁定缓冲区,防止其他进程访问return bp; // 返回缓冲区
}
逐行说明:
buffer_cache_find(dev, blockno)
:先查找缓存中是否已有该块。- 比喻:管理员先在借阅区(缓存)找这本书,看是否已经有人借出。
buffer_cache_allocate(dev, blockno)
:如果缓存中没有,则分配一个新的缓冲区。- 比喻:如果书不在借阅区,就分配一个新空位来存储这本书。
disk_read(dev, blockno, bp->data)
:从磁盘读取块号为blockno
的数据到缓冲区。- 比喻:从仓库(磁盘)搬运书到借阅区。
lock_buffer(bp)
:锁定缓冲区,防止其他进程访问。- 比喻:管理员锁定书本,防止被多个人同时借走。
// 释放缓冲区
void brelse(struct buf *b) {unlock_buffer(b); // 解锁缓冲区move_to_recent_list(b); // 将缓冲区放到最近使用列表的头部
}
逐行说明:
unlock_buffer(b)
:解锁缓冲区。- 比喻:管理员解锁书本,允许其他人查看。
move_to_recent_list(b)
:将缓冲区移到最近使用列表头部。- 比喻:把书放到书架前排,方便下次快速找到。
定义在 log.c
中
// 记录缓冲区的修改,稍后写入磁盘
void log_write(struct buf *b) {pin_buffer(b); // 增加缓冲区的引用计数,防止被替换mark_buffer_dirty(b); // 标记缓冲区为已修改log_commit_buffer(b); // 将修改记录到日志中
}
逐行说明:
pin_buffer(b)
:增加引用计数,防止缓冲区被替换。- 比喻:管理员标注这本书暂时不能借出,还在修改中。
mark_buffer_dirty(b)
:标记缓冲区内容为脏数据,表示需要写回磁盘。- 比喻:书已经被修改,管理员需要保存笔记。
log_commit_buffer(b)
:将缓冲区的修改记录到日志。- 比喻:管理员记录修改内容,稍后存档。
总结
- 这些 API 构成了文件系统中 磁盘块管理和缓存机制 的基础逻辑。
- 它们的主要功能是:
- 分配、释放块(
fs.c
):申请和回收磁盘上的存储空间。 - 缓存管理(
bio.c
):从磁盘读取数据到内存,并提供缓存机制。 - 日志记录(
log.c
):跟踪缓冲区的修改,确保数据一致性。
- 分配、释放块(
相关文章:
[OS] A4-前菜介绍
从你的描述来看,这段话是给你的一些 预备知识 和 mkfs工具的使用 提示,帮助你了解如何构建和管理文件系统,特别是关于 xv6 文件系统的一些基本操作。 我会通过比喻和通俗化的方式逐步解释: 预备知识:xv6 文件系统的基…...
2024农历年余下的数模比赛名单已出炉!
数学建模比赛季又来了!作为一名资深的数学建模辅导老师,我想对你们说:这不仅是挑战智商的时候,也是展现团队合作力、数据分析能力和逻辑思维的最佳舞台!💡 如果你是建模新手,或者想让自己的比赛…...
在开发环境中,前端(手机端),后端(电脑端),那么应该如何设置iisExpress
首先,要想手机端应用能成功请求后端,两个设备至少需在同一个局域网内,且IP地址互通; 因为ajax是http(s)://IP地址端口号的方式请求,但是iisExpress默认是localhost如何解决,并没有IP地址,所以手…...
2.安装docker、docker compose
1. 安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm22. 设置阿里云docker-ce镜像源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo3. docker-ce 安装 yum install -y docker-ce4. docker-compo…...
windows中idea选择bash作为控制台指令集,但是系统环境变量未在其中生效处理
1. 引言 在windows系统中安装node 以及npm时配置其环境,使用window环境变量的配置方式在系统环境变量设置的地方设置了环境变量如下图1-1,设置后在idea中的控制台通过 echo $PATH 查看环境变量发先跟系统中配置的不一致,而且node -v npm -v指…...
如何通过 ADB 安装 xapk
Android开发这么久,今天发现还能这么操作!😂 记录通过ADB安装xapk、apks的两种方式: 1.ADB命令安装使用APK-Splits技术分包的应用程序 这位大佬的方式步骤较为繁琐,不过兼容性应该较好,亲测成功安装。 2.How to install xapk, apks, or multiple-apks via adb? 这个…...
Docker使用教程
Docker 是一个开源的容器化平台,用于开发、打包和分发应用程序。它允许将应用及其依赖环境打包成容器,从而实现跨平台的便捷部署。下面是一个简单的 Docker 使用教程,涵盖从安装到基本命令的使用。 1. 安装 Docker Windows / MacOS 访问 D…...
我的创作纪念日
一、机缘 成为创作者的初衷是从学习C/C语法与数据结构过程中获得的灵感。在日常学习和项目实践中,我发现这些知识既丰富又复杂,对初学者而言尤为困难。因此,我决定通过博客记录自己的学习过程、解决思路以及代码实现,帮助更多人在…...
软件质量保证——单元测试之白盒技术
笔记内容及图片整理自XJTUSE “软件质量保证” 课程ppt,仅供学习交流使用,谢谢。 程序图 程序图定义 程序图P(V,E),V是节点的集合(节点是程序中的语句或语句片段),E是有向边的集合…...
redis中的哨兵
redis中的哨兵 一、哨兵机制的概念二、redis哨兵的部署2.1 docker的安装2.2 编排redis主从节点2.3 配置哨兵节点 三、redis哨兵的选举机制3.1 redis-master宕机之后的情况3.2 重启redis-master后的情况 四、redis哨兵机制的原理4.1主观下线4.2客观下线4.3选举leader节点4.4选出…...
开源对象存储新选择:在Docker上部署MinIO并实现远程管理
文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器,可以在各种环境中运行,例如本地、Docker容器、Kubernetes集群等。它兼…...
15分钟做完一个小程序,腾讯这个工具有点东西
我记得很久之前,我们都在讲什么低代码/无代码平台,这个概念很久了,但是,一直没有很好的落地,整体的效果也不算好。 自从去年 ChatGPT 这类大模型大火以来,各大科技公司也都推出了很多 AI 代码助手ÿ…...
houdini肌肉刷pin点的方法
目标:产生gluetoanimation这个属性 主要节点:attribute paint(或者muscle paint) 步骤1: 导入肌肉资产 导入的是rest shape的肌肉 在有侧边栏可以打开display group and attribute list,方便查看group。不同的肌肉块按照muscl…...
Ubuntu20.04安装NVIDIA显卡驱动
Ubuntu20.04安装NVIDIA显卡驱动 参考资料:https://blog.csdn.net/weixin_39244242/article/details/136282614?fromshareblogdetail&sharetypeblogdetail&sharerId136282614&sharereferPC&sharesourceqq_37397652&sharefromfrom_link 成功配置…...
k8s删除网络组件错误
k8s集群删除calico网络组件重新部署flannel网络组件,再部署pod后出现报错不能分配ip地址 plugin type"calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized 出现该问题是因为删除网络组件后,网…...
民锋视角:多元化策略实现资产稳健增长
在全球化经济的推动下,市场呈现出高度的复杂性与多样性。面对不同经济周期和市场动态,民锋以多元化投资策略为核心,帮助投资者在不确定性中实现资产的稳健增长。 一、多元化策略的核心价值 降低单一市场风险 单一资产或市场的表现可能因不可…...
[已解决]Visual Studio 2022中如何同时打开多个项目多个独立窗口
同时运行两个VS2022程序,即点击运行Visual Studio 2022.exe后,再点击运行一次运行Visual Studio 2022.exe,效果如图...
11、PyTorch中如何进行向量微分、矩阵微分与计算雅克比行列式
文章目录 1. Jacobian matrix2. python 代码 1. Jacobian matrix 计算 f ( x ) [ f 1 x 1 2 2 x 2 f 2 3 x 1 4 x 2 2 ] , J [ ∂ f 1 ∂ x 1 ∂ f 1 ∂ x 2 ∂ f 2 ∂ x 1 ∂ f 2 ∂ x 2 ] [ 2 x 1 2 3 8 x 2 ] \begin{equation} f(x)\begin{bmatrix} f_1x_1^22x_2\\…...
51c自动驾驶~合集35
我自己的原文哦~ https://blog.51cto.com/whaosoft/12206500 #纯视觉方案的智驾在大雾天还能用吗? 碰上大雾天气,纯视觉方案是如何识别车辆和障碍物的呢? 如果真的是纯纯的,特头铁的那种纯视觉方案的话。 可以简单粗暴的理解为…...
位图和布隆过滤器
目录 一.位图 1.位图的概念 2.位图的实现 3.位图的应用 二.布隆过滤器 1.布隆过滤器的概念 2.布隆过滤器的实现 3.布隆过滤器的优缺点 三.整体代码 1.bitset.h 2.BloomFilter 3.Hash.cpp 一.位图 1.位图的概念 1.面试题 给40亿个不重复的无符号整数,没…...
Java—I/O流
Java的I/O流(输入/输出流)是用于在程序和外部资源(如文件、网络连接等)之间进行数据交换的机制。通过I/O流,可以实现从外部资源读取数据(输入流)或将数据写入外部资源(输出流&#x…...
CSS样式
第一章:CSS类型 1、行内样式 <div style"color:red;font-size:30px;font-weight: 900;font-style: italic;">ABCD</div>注意:行内样式,作用力优先级最高,但是不利于html与css的书写以及修改,会…...
idea_卸载与安装
卸载与安装 卸载1、设置 -> 应用2、查找到应用,点击卸载3、把删除记录和设置都勾选上4、删除其它几个位置的残留 安装1、下载安装包2、欢迎安装 -> Next3、选择安装目录 -> Next4、创建快捷图标和添加到环境变量5、确认文件夹的名称 -> Install6、完成安…...
大数据-237 离线数仓 - 广告业务 需求分析 ODS DWD UDF JSON 串解析
点一下关注吧!!!非常感谢!!持续更新!!! Java篇开始了! 目前开始更新 MyBatis,一起深入浅出! 目前已经更新到了: Hadoop࿰…...
视觉语言模型(VLM)学习笔记
目录 应用场景举例 VLM 的总体架构包括: 深度解析:图像编码器的实现 图像编码器:视觉 Transformer 注意力机制 视觉-语言投影器 综合实现 训练及注意事项 总结 应用场景举例 基于文本的图像生成或编辑:你输入 “生成一张…...
Spring 自调用事务失效分析及解决办法
前言 博主在写公司需求的时候,有一个操作涉及到多次对数据库数据的修改。当时就想着要加 Transactional注解来声名事务。并且由于一个方法中有太多行了,于是就想着修改数据库的操作单独提取出来抽象成一个方法。但这个时候,IDEA 提示我自调用…...
【ROS2】Ubuntu22.04安装ROS humble
一. ROS简介 1.1 什么是ROS ROS 是一个适用于机器人的开源的元操作系统。它提供了操作系统应有的服务,包括硬件抽象,底层设备控制,常用函数的实现,进程间消息传递,以及包管理。ROS的核心思想就是将机器人的软件功能做…...
免费开源的微信开发框架
请求参数 Header 参数 export interface ApifoxModel {"X-GEWE-TOKEN": string;[property: string]: any; } Body 参数application/json export interface ApifoxModel {/*** 设备ID*/appId: string;/*** 是否允许*/enabled: boolean;[property: string]: any; }…...
【第二讲】Spring Boot 3.4.0 新特性详解:新的依赖管理功能
Spring Boot 3.4.0 版本引入了一些显著的改进,其中之一就是新的依赖管理功能。这些改进不仅提升了依赖管理的便利性和一致性,还增强了项目的可维护性和可扩展性。本文将详细介绍 Spring Boot 3.4.0 中新的依赖管理功能,提供具体的使用示例和场…...
CSAPP Cache Lab(缓存模拟器)
前言 理解高速缓存对 C 程序性能的影响,通过两部分实验达成:编写高速缓存模拟器;优化矩阵转置函数以减少高速缓存未命中次数。Part A一开始根本不知道要做什么,慢慢看官方文档,以及一些博客,和B站视频&…...
Vue项目通过Nginx部署多个
1.将Vue项目部署到Nginx根 1.1 修改vue.config.js,默认可以不设置 module.exports {publicPath: / } 1.2 修改index.js,默认可以不设置 export default new Router({...base: "/"... }) 1.3 修改nginx.conf location / {root /usr/shar…...
【React】全局状态管理(Context, Reducer)
以下为知行小课学习笔记。 概述 Context 跨组件共享状态 在 Next 项目,封装 useContext。 AppContext.tsx "use client";import React, {createContext, Dispatch, ReactNode, SetStateAction, useContext, useMemo, useState} from react;type State …...
Docker容器ping不通外网问题排查及解决
Docker容器ping不通外网问题排查及解决 解决方案在最下面,不看过程的可直接拉到最下面。 一台虚拟机里突然遇到docker容器一直访问外网失败,网上看到这个解决方案,这边记录一下。 首先需要明确docker的网桥模式,网桥工作在二层…...
VTK的基本概念(一)
文章目录 三维场景的基本要素1.灯光2.相机3.颜色4.纹理映射 三维场景的基本要素 1.灯光 在三维渲染场景中,可以有多个灯光的存在,灯光和相机是三维渲染场景的必备要素,如果没有指定的话,vtkRenderer会自动创建默认的灯光和相机。…...
【动态规划】股票市场交易策略优化
文章目录 一、问题描述二、解决思路状态转移初始化最终结果 三、代码实现执行流程解析时间和空间复杂度 一、问题描述 我们要解决的是一个关于股票买卖的问题:给定一个股票价格数组 stocks,每一天的价格为数组中的一个元素。我们可以通过买入和卖出的操…...
docker-compose 升级
官方下载地址: https://github.com/docker/compose/releases 下载完放到kali root目录下 # mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose # chmod x /usr/local/bin/docker-compose # docker-compose --version...
node.js @ffmpeg-installer/ffmpeg 桌面推流
//安装npm install --save ffmpeg-installer/ffmpeg //stream.js // 引入所需模块 const ffmpeg require(ffmpeg-installer/ffmpeg); const { exec } require(child_process); // 设置 FFmpeg 路径 const ffmpegPath ffmpeg.path; const rtmpUrl "rtmp://localhost…...
电脑启动需要经历哪些过程?
传统BIOS启动流程 1. BIOS BIOS 启动,BIOS程序是烧进主板自带的ROM里的,所以无硬盘也可以启动。BIOS先进行自检,检查内存、显卡、磁盘等关键设备是否存在功能异常,会有蜂鸣器汇报错误,无错误自检飞快结束。 硬件自检…...
MobaXterm Sessions 批量录入导入,会话批量添加
此脚本用于将服务器批量录入到 MobaXterm 会话 使用方法: 1、将IP列定义在 sessions_ip_list 变量中(ssh登录的IP) 2、将登录用户定义在 sessions_user 变量中(ssh登录的用户) 3、将目录名称定义在 folder_name 变…...
ceph的用户管理和cephx认证
用户权限概述 用户格式 参考链接: 权限:https://docs.ceph.com/en/latest/rados/operations/user-management/#authorization-capabilities 用户:https://docs.ceph.com/en/reef/rados/operations/user-management/ ceph的用户格式TYPEID…...
【北京迅为】iTOP-4412全能版使用手册-第二十章 搭建和测试NFS服务器
iTOP-4412全能版采用四核Cortex-A9,主频为1.4GHz-1.6GHz,配备S5M8767 电源管理,集成USB HUB,选用高品质板对板连接器稳定可靠,大厂生产,做工精良。接口一应俱全,开发更简单,搭载全网通4G、支持WIFI、蓝牙、…...
MicroSoft Project2007 安装教程
一、安装教程 访问地址 二、安装链接 通过网盘分享的文件:Project2007CD 链接: https://pan.baidu.com/s/1Y8VnhVPiKjcmAEh8cIR5sQ?pwdp2hk 提取码: p2hk --来自百度网盘超级会员v6的分享...
怎样提高自己的能量
能量转换的基本原则是让别人需要你,而不是你去求对方。别人需要你,你的能量就高,你去求别人你的能量就低。 怎样提高自己的能量? 第一,留意你的气场和格局。气场不是说你表现的多么霸道,而是你的信念、决心…...
ScreenshotToCode安装教程
网页截图生成代码,我测试的效果一般 快速安装教程如下 1,首先你得有OpenAI的账号 国内用这个代理就可以: https://www.closeai-asia.com/ 充值一块钱,在本项目中可以生成两次 2,下载程序 下载程序压缩包࿱…...
工程企业如何做好成本控制?该如何入手?
工程企业的成本控制是企业管理中的核心工作,其直接关系到项目的盈利能力和市场竞争力。以下从几个关键方向阐述如何入手做好成本控制: 一、明确成本控制目标 成本控制的目标不仅是减少支出,更重要的是保证项目质量和工期,避免因低…...
详解桥接模式
引言 在开发过程中,可能会遇到系统设计有多种维度变化的情况,比如我们想画一幅五彩斑斓的画,需要用到12个颜色,但是需要粗细不同的线条(粗、中、细),如果用蜡笔,就需要粗中细三种蜡笔…...
田忌赛马五局三胜问题matlab代码
问题描述:在可以随机选择出场顺序的情况下,如果把比赛规则从三局两胜制改为五局三胜制,齐王胜出的概率是上升了还是下降了?五局三胜的赛制下,大家的马重新分为5个等级。前提条件仍然是齐王每种等级的马都优于田忌同等级…...
Springboot 修改post请求接口入参或重新赋值
前言 很久之前写过一篇就是自动填充接口参数的,利用的 HandlerMethodArgumentResolver 自定义注解 Springboot Controller接口默认自动填充 业务实体参数值_springboot设置入参默认值-CSDN博客 现在这一篇也差不多,达到的目的就是重新去给post请求的参数…...
jmeter学习(7)命令行控制
jmeter -n -t E:\IOT\test2.jmx -l E:\IOT\output\output.jtl -j E:\IOT\output\jmeter.log -e -o E:\IOT\output\report IOT下创建output 文件夹,jmx文件名避免中文,再次执行output.jtl不能有数据要删除...
李春葆《数据结构》-查找-课后习题代码题
一:设计一个折半查找算法,求查找到关键字为 k 的记录所需关键字的比较次数。假设 k 与 R[i].key 的比较得到 3 种情况,即 kR[i].key,k<R[i].key 或者 k>R[i].key,计为 1 次比较(在教材中讨论关键字比…...