当前位置: 首页 > article >正文

Linux 文件系统inode软硬链接

目录

一、理解文件系统

1、前言

2、磁盘

二、inode 

1、创建一个新文件的 4 个操作 

三、软硬链接 

1、软链接

 2、硬链接

3、硬链接的应用 

4、软链接的应用


一、理解文件系统

1、前言

在我们电脑文件里,分为打开的文件和未打开的文件,我们在上几篇文章给大家介绍了打开的文件,现在我们重点介绍未打开的文件

我们知道打开的文件是通过操作系统被进程打开,一旦打开,操作系统就要维护多个文件,所以它是需要被操作系统管理的。也就是说这种方式,磁盘上和内存上都有这个文件,它们不是完全一样的,内存中的文件更强调的是属性和方法,磁盘中的文件更强调的是数据,它们是通过缓冲区关联的;而普通的未打开的文件在磁盘上,未被加载到内存中,它当然也要被管理;其中管理打开的文件和管理未打开的文件在操作系统中有一个功能模块叫做文件系统

之前我们谈过进程 VS 程序,一个被打开的程序就是进程,只不过我们在解释进程时不是严格地把它当作文件来解释,需要明白的是进程是要被加载到内存的,程序就是一个磁盘文件,打开的文件是进程,而普通未打开的文件是程序。

  • 一个文件属性分为这么几块

分别对应: 

  • 权限
  • 硬链接数
  • 文件所有者、所属组
  • 文件大小
  • 最后修改时间
  • 文件名

我们可以用stat命令查看文件更详细信息。

 这些信息我们都看不懂是什么意思,接下来我们要先了解磁盘。

2、磁盘

  • 内存 -- 掉电易失存储介质
  • 磁盘 -- 永久性存储介质 -- SSD、U盘、flash卡、光盘、磁带

磁盘分为机械硬盘(HDD)和固态硬盘(SSD),现在很多的电脑都是机械硬盘和固态硬盘组合使用,但服务器上大多都是机械硬盘,只有一些高效率的存储集群会用到固态硬盘。机械硬盘和固态硬盘在存储技术上肯定是不同的,而我们主要了解机械硬盘,因为它多用于服务器上,其次虽然固态硬盘要比机械硬盘快不少,但在 CPU 看来,两者都很慢,我们这里就了解最慢的。

虽然磁盘的盘面看起来很光滑,但是它上面有一些同心圆,这些同心圆用圆白线划分,每一圈叫做磁道,数据写在这些有颜色的区域上。实际上你并不是把一圈的空间都用完,所以这里还使用了一些直白线划分,被圆白线和直白线划分出来的区域叫做扇区。所以当盘片在旋转、磁头摆动就可以找到这个盘片的任何一个扇区进行读写。 实际磁头和盘面并不是接触的,它们之间的距离就像一架飞机在离平地 1 米的距离滑行。

盘面是有两面的,每个面上都有一个磁头,且两面都是同心圆,数据只能写在同心圆(磁道)上,根据配置不同,有些磁盘可能还有多组盘片,我们可以从上至下的分为不同的盘面,也叫做你是第几个盘面。

C 语言中访问内存的基本单位是 1byte(1B) ,但是在操作系统的角度认为内存的基本单位一般是 4kb,在操作系统看来,内存就是一个数组,每一个元素是 4kb。 

如果我们要malloc 1byte,操作系统不会直接分配4kb给我们,有可能 C 语言本身就缓冲了一部分空间让你去使用,如果超出这一部分空间,操作系统再重新分配。

磁盘存储的基本单位是一个扇区,它是磁盘读取的最小单元,大部分磁盘的一个扇区是 512byte,但你会发现虽然这里好像越靠近圆心,扇区越小,其实它们都是 512byte,原因是越靠近圆心的虽然扇区越小,但是比特位也相对外圈更密集。内存和磁盘之间也是有交互的,它们之间的交互我们称为 output、input,也叫做 IO,一般内存和磁盘之间 IO 交互时,不是纯硬件级别的交互,而是要通过文件系统完成,也就是通过操作系统。


这里用户和内存之间交互的基本单元大小是 1byte,一般内存和磁盘之间交互时的基本单元大小是 4kb,所以文件系统在往磁盘读数据时,要读 8 个扇区,这就是数据由磁盘加载到内存的过程。

将数据存储到磁盘 --> 将数据存储到该数组
找到磁盘特定扇区的位置 --> 找到数组特定的位置
对磁盘的管理 --> 对该数组的管理

上面这个指向关系,我们可以看作对磁盘的抽象管理。所以需要对磁盘抽象化处理,将圆状结构的磁盘空间抽象成线性结构的磁盘空间。这里举两个例子方便理解:

  1. 其实在 C 语言中我们见过的 int arr[3][4] 二维数组就是把线性的数据结构抽象成了好理解的有行有列的结构。
  2. 曾经风靡一时的磁带是把数据存储于那条黑色的带子上,可能是为了空间的原因,把带子卷起来形成一个圆状,所以磁带在物理上,既可以是圆状,也可以是线状。

 

比如磁盘的所有磁道被我们抽象成了一条 500GB 的线性空间,我们可以把它看作一个很大的数组 —— 扇区 array[NUM],其中每一个元素是 512byte,操作系统要申请 4kb,那就给数组的 8 个元素。所以将磁盘抽象后,操作系统就摆脱盘面、磁道、扇区的束缚了,操作系统只关心你想访问的哪个下标,这里的地址我们称为逻辑区块地址(Logical Block Address, LBA),这里抽象出来的数组下标是和机械硬盘中盘面、磁道、扇区构成映射关系的,这里的映射关系是由对应的机械磁盘驱动维护的,操作系统想往 2 下标处写数据,最终 2 下标一定是能对应到具体磁盘中某个扇区上。如果要往固态硬盘中写数据,也是把它抽象成线性的数组,它也有自己的固态硬盘驱动维护数组下标和固态硬盘之间的映射关系。至此,通过抽象的方法,就完成了操作系统和磁盘之间的解耦。所以最终操作系统对磁盘的管理,转换成了对数组的管理。 


我们把磁道抽象程一个线性空间,假设我们要找下标为28888的扇区编号。

每个扇面有2w个扇区。 每个扇面有50个磁道。  每个磁道有400个扇区。

如图即为寻找的过程。

 为什么操作系统(文件系统)和磁盘不以 512byte 为单位呢?

太小了,可能会导致多次 IO,进而导致效率的降低。

如果操作系统使用和磁盘一样的大小,万一磁盘的基本大小发生改变,那 OS 的源代码要不要改呢?那岂不是将硬件和软件(OS)进行解耦。

二、inode 

500G 的磁盘空间抽象成每个元素是 512byte 的数组,那样非常大,不易管理,所以操作系统还要对这 500G 的数组进行拆分,比如这里拆分成了 100G、100G、150G、150G,所以这里只要管理好了第一个 100G 的空间,然后把管理的方法复制到其它空间,其它的空间也能被管理好。

把拆分的过程叫做分区,这也就是我们的电脑上为什么会有 C 盘、D 盘、E 盘等。至此我们仅仅是对空间进行划分,要把空间管理好还需要写入相关的管理数据,比如把中国 960 万平方公里,划分了不同大小的省份,要管理好一个省,我们不考虑地质差异等因素,只要一个领导、一个团队,他们把一个省管理好了,那么他们的管理方法就可以复制到其它省。同样的,刚刚我们分区的工作只是把中国划分成不同的省份,接下来我们还要分配每个省的省长、省中每个市的市长、市中每个镇的镇长等,以此来管理一个省。

将这种分配的过程叫做格式化过程,所谓的格式化在计算机中就是写入文件系统,也就是说我们要把文件系统写入某个分区中,这个文件系统的核心包括数据 + 方法,数据就类似这个省有多少人口、粮食等,方法就类似这个省有生育政策、耕种政策等。同样文件系统包含的数据就是文件系统的类型等,方法就是操作各种文件的方法。

当然不同的分区可以使用不同的文件系统,Linux 下就使用五六种不同的文件系统,Linux 可以支持多种文件系统,包括 Ext2、Ext3、fs、usb-fs、sysfs、proc。这就好比各个省份需要因地制宜地分配不同的团队。我们谈的都是 Ext 系列的文件系统,也不谈其它的文件系统如何,我们就认为磁盘上不同分区的文件系统是一样的。

因为一个省也很大,为了更好的管理,还要分配市长、镇长等,同样的分区后的 100G 空间还要再划分,比如这里划分了 10 组 10G 的空间,然后把它看作成一个一个的块组(Block group),一个块组中又有多个 4kb 空间,而磁盘存储是有块基本单位的,文件系统认为一块是 4kb,我们只要把一个块组管好,整个文件系统内的块组就能管好,所以问题又转换为怎么把这 10G 的空间管好,所以接下来划分的才是文件系统写入的相关细节,也是我们要研究的,这个区域的信息大家都有,可能略有差异。

这里 Linux 文件系统以 Ext 系列的为话题,上图为磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区被划分为一个个的 block。一个 block 的大小是由格式化的时候确定的,并且不可以更改。例如 mke2fs 的 -b 选项可以设定 block 大小为 1024、2048 或 4096 字节。而上图中启动块(Boot Block)的大小是确定的,因为不同的文件系统可能略有差异。一般一个磁盘的 0 号分区的 0 号块组上的第一扇区存储着一些启动信息。掌握以下信息能够让一个文件的信息可追溯,可管理。

  • 超级块(Super Block):是文件系统的核心结构,用于存放文件系统本身的结构信息,描述文件系统的属性信息,记录的信息主要有:bolck 和 inode的总量,未使用的 block 和 inode 的数量,一个 block 和 inode 的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。一般计算机启动时,Super Block 会被加载到操作系统,其中每一块组好像都有一个 Super Block,但实际可能 10 个块组中只有两三个有 Super Block。如果 Super Block 的信息被破坏,可以说整文件系统结构就被破坏了。
  • GDT,Group Descriptor Table:块组描述符。Super Block 描述的是整个块组相关的信息,这里描述的是一组的属性信息,每一个块组都必需要有一个 Group Descriptor Table。
  • 块位图(Block Bitmap):Block Bitmap 中记录着 Data Block 中哪个数据块已经被占用,哪个数据块没有被占用。其中比特位为 1 表示该 block 被占用,否则表示可用。
  • Block Group:ext2 文件系统会根据分区的大小划分为数 个Block Group,而每个 Block Group 都有着相同的结构组成。
  • inode 位图(inode Bitmap):每个 bit 表示一个 inode 是否空闲可用,比特位和特定的 inode 是一一对应的。其中,inode bitmap 中比特为 1 表示该 indoe 被占用,否则表示可用。
  • i 节点表:存放文件属性,如文件大小、所有者、最近修改时间等。
  • 数据区:存放文件内容。

我们说过文件 = 内容 + 属性。这里的内容和属性采用分离存储,属性放在 inode Table 中。一个组中可以放多少个 inode 是一定的,基本上一个文件或目录一个 inode,inode 是一个文件的所有属性集合,属性也是数据,也要占用空间。所以即便是一个空文件也要占用空间,这里的属性集合包含文件权限、大小等,但不包含文件名。


内容放在 Date blocks 中。比如这里的块组是 10G,那么 inode Table 占 1G,Date blocks 占了 8G, 一个 inode 是 512byte,粗略的算一下,1G 大概 42 亿多字节,除以 512 大概也有几千万,所以这样一个块组能保存几千万文件的 inode 信息。这里 inode Table 和 Data blocks 的划分可能会出现你用完了、我没用完,或者你没用完、我用完了的情况,这种情况并没有有效的方法解决。


 Date blocks 相当于一个数据块集合,报错的都是特定文件的内容,它以 4kb为单位(Date blocks 可以理解成多个 4kb(扇区*8)大小的集合),对应的数据块属于哪些文件,是由 Data Blocks 和 inode Table 维护的。如下图,inode Table 是一个大小为 128字节的空间,包含了若干大小相同的块,这些块有不同的编号,对应就是对应文件的属性,Data blocks 也包含了若干大小相同的块,这些块也有不同的编号,对应就是文件的内容。此时新建文件或目录,就给文件申请 1 号 inode,并把文件的各种属性写入到 1 号 inode,1 号 inode 中包含了一个数组 block b[32],比如 1 号 inode 需要 2 个数据块,所以 [0] = 2,[1] = 3,所以 1 号 inode 就可以找到对应的数据块。换而言之,要在磁盘上查找一个文件,我们只需要知道这个文件的 inode 是多少,因为 inode 需要标识唯一性,每一个 inode 块都要有一个 inode 编号,至此,我们知道真正标识文件的不是文件名,而是文件的 inode 编号。既然 inode 大小是确定的,万一文件是 10 个 T,此时数据块就不够了,文件系统的处理策略是数据块不仅可以保存数据的内容,还可以保存其它数据块的编号,它类似于 b+ 树。换言之,对于保存较大的文件,可能就需要多级索引的形式。

  • 我们用ls -li 就能看到文件的编号了

 目录是不是文件呢?

我们的上图中就是目录,也有自己的inode,目录也要有自己的属性。

目录也有数据块,里面存放的是文件名和对应文件inode的映射关系。(这就是为什么同一目录下没有同名文件。)

echo “hello world” > file.txt 是先启动进程,这个进程当然知道自己所在的目录,那么它就可以拿着 file.txt 文件名找它对应的 inode,把数据追加到对应的数据块中。所以说 inode 不存储文件名,只是往目录的数据块中写入文件名和文件对应的 inode。

在目录下,我们没有"W"权限时,无法创建文件

因为无法把该映射关系写入到数据块中。

 在目录下,我们没有"R"权限时,无法读写文件

因为无法读取到映射关系,找不到对应的inode,读不到文件

1、创建一个新文件的 4 个操作 

(1)存储属性

内核先找到一个空闲的i节点(这里是263466)。内核把文件信息记录到其中。

(2)存储数据 

该文件需要存储在三个磁盘块,内核找到了三个空闲块:300、500、800。将内核缓冲区的第一块数据复制到 300,下一块复制到 500,以此类推。

(3)记录分配情况 

文件内容按顺序 300、500、800 存放。内核在 inode 上的磁盘分布区记录了上述块列表。

(4)添加文件名到目录 

新的文件名 linux_1。linux 如何在当前的目录中记录这个文件?内核将入口(1052214,linux_1)添加到目录文件。文件名和 inode 之间的对应关系将文件名和文件的内容及属性连接起来。

touch 一个空文件 file.txt,ext* 文件系统,做了什么工作?

它先在 inode Bitmap 申请没有被使用的比特位,然后把文件对应的属性信息 inode Table 里写,再把申请好文件的文件名和 inode 编号写入 Data blocks 建立映射关系。如果想 echo “hello world” > file.txt,现在是在当前目录下,file.txt 和 inode 就找到了,再通过 file.txt 文件的 inode 去对应的 Data blocks 中写入数据。所以就能理解为什么大多数操作系统下同一个目录中不允许存在同名文件。一方面是不方便人查看,另一方面是若一个目录下有同名文件了,那么 inode 去操作文件时操作的就不知道是哪个文件了。

Block Bitmap 和 inode Bitmap 是位图,就是用比特位 0 / 1 来表示的。Block Bitmap 用来标识数据块的使用情况,inode Bitmap 用来标识 inode 的使用情况,每个比特位都对应一个块。换而言之,当你新建文件时,它并不是遍历 inode 区域,因为这样做太慢了,它只需要在系统启动时将 Blok Bitmap 和 inode Bitmap 预加载到系统中。要新建文件就把 inode Bitmap 的比特位由 0 置为 1,文件需要多少数据块,就把 Block Bitmap 的比特位由 0 置为 1。所以我们可以通过位图快速的完成 inode 的申请和释放,同时也能确认当前磁盘的使用情况。但是位图依然还是需要去遍历哪些使用和未使用,以及做位操作等,所以这里通过 Group Descriptor Table 来管理。

如何理解删除文件?

计算机中删除一个文件并不是真正的删除,而是把那块空间标识为无效,就像拷贝一部电影到 U 盘需要 1 分钟,但是删除 U 盘上的电影只需要短暂的一两秒;亦或是盖一个房子需要 1 年,而销毁一个房子只需要在墙上写上拆 。而现在理解的是不用把 inode 属性清空,不用把 inode 对应的数据块清空,只需要把两个位图中对应的比特位由 1 到 0再把所在的目录下中的对应的映射关系去掉,此时空间就是无效的,当下一次再新建文件时,就可以直接把无效的空间覆盖

按上面这样说,删除后的文件当然可以恢复,Windows 下的回收站就是一个目录,当你删除时就是把文件移动到回收站目录下,然后把其它目录下数据块中的映射关系移动到回收站目录下的数据块中。Windows 下就算把回收站的内容删除也是能恢复的,Linux 下如果要恢复删除的文件是有一些恢复工具的,但有可能在恢复过程中创建各种临时文件,可能就会把想恢复的文件的信息覆盖掉。如果想自己恢复删除的文件,就需要更深入的了解文件系统原理。

三、软硬链接 

硬链接是通过  inode  引用另外一个文件,软链接是通过名字引用另外一个文件。

1、软链接

 我们能看到test.exe与testlink建立了软链接,test,exe有独立的inode,说明是一个独立的文件。soft.link 中的数据块中保存着它指向的文件 testLink.txt 的路径

就类似于 Winodws 下的快捷方式,比如桌面看到的软件保存的是其它的路径,在系统中可能你要运行的可执行程序在一个很深的目录下,就可以在较上层的目录中建立软链接。

 2、硬链接

test1.exe与testlink1建立硬链接,我们发现他们的inode和硬链接数是一样的。

硬链接本质上是在特定的目录数据块上新增文件名的指向,我们之前介绍了引用计数,在每个inode的内部都有一个叫做引用计数的计算器的文件的inode的映射。这个计数器记录的是有多少个文件名指向这个inode。

在这个硬链接中,相当于是给testlink1取了一个别名。

我们在删除文件时干了两件事情 

  1. 在目录中将对应的记录删除。
  2. 将硬连接数 -1;如果为 0,则将对应的磁盘释放。

3、硬链接的应用 

 我们能看到一个"."和"..",一个点为当前目录的别名,两个点为上一个目录的别名。

我们在dir目录下创建了dir1目录,为什么硬链接数变成了3了呢?

 在原来的2的基础上,在dir1目录下有".."隐藏文件,是dir的硬链接

所以硬链接能够维持Linux的目录结构。

通常用来进行路径的定位,采用硬链接可以进行目录间的转化。

硬链接不能给目录建立。 

原因就是允许目录的硬链接可能会打破文件系统目录的有向无环图结构,可能创建目录循环,这可能会导致fsck以及其他一些遍历文件树的软件出错。这可能会出现一种你的父目录是你的子目录这种及其奇怪的事情出现,其实就是硬链接以后的目录可能是你的父目录,这导致很多遍历系统的命令如果不跟踪inode的话就没办法用了,因为可能会导致无限循环比如du,ls -r, pwd

 

那为什么又有"." ".."与目录进行硬链接呢? 

因为这是操作系统自己写的,也是特例,操作系统不允许与目录进行硬链接,限制的是用户,因为操作系统不相信任何用户。

4、软链接的应用

 我们先创建一个文件

编译该文件形成可执行程序test.exe并移入我们创建的目录里。

 进行软链接

最后我们发现运行exe.link就能直接运行我们移入目录里的可执行文件。 

这个过程就是我们在上面写的,我们在window系统中点快捷方式就能直接运行该软件。

相关文章:

Linux 文件系统inode软硬链接

目录 一、理解文件系统 1、前言 2、磁盘 二、inode 1、创建一个新文件的 4 个操作 三、软硬链接 1、软链接 2、硬链接 3、硬链接的应用 4、软链接的应用 一、理解文件系统 1、前言 在我们电脑文件里,分为打开的文件和未打开的文件,我们在上…...

多目标粒子群优化算法-MOPSO-(机器人路径规划/多目标信号处理(图像/音频))

具体完整算法请跳转:多目标粒子群优化算法-MOPSO-(机器人路径规划/多目标信号处理(图像/音频)) 多目标粒子群优化算法(Multi-Objective Particle Swarm Optimization,MOPSO)是一种基…...

Unity合批处理优化内存序列帧播放动画

Unity合批处理序列帧优化内存 介绍图片导入到Unity中的处理Unity中图片设置处理Unity中图片裁剪 创建序列帧动画总结 介绍 这里是针对Unity序列帧动画的优化内容,将多个图片合批处理然后为了降低Unity的内存占用,但是相对的质量也会稍微降低。可自行进行…...

LayUi点击查看图片组件layer.photos()用法(图片放大预览后滚动鼠标缩放、底部显示自定义标题)

LayUi官方文档更新后发现图片查看组件layer.photos()没有了 记录一下用法 例&#xff1a; <ul id""><li title"" ng-repeat"(val,item) in Obj" ng-click"gszzxxClick(item)"><img ng-src"{{item.src}}" a…...

DAY07 Collection、Iterator、泛型、数据结构

学习目标 能够说出集合与数组的区别数组:1.是引用数据类型的一种2.可以存储多个元素3.数组的长度是固定的 int[] arr1 new int[10]; int[] arr2 {1,2,3};4.数组即可以存储基本类型的数据,又可以存储引用数据类型的数据int[],double[],String[],Student[]集合:1.是引用数据类…...

k8s集群如何赋权普通用户仅管理指定命名空间资源

文章目录 1. 普通用户2. 创建私钥3. 创建 CertificateSigningRequest4. 批准 CertificateSigningRequest5. 创建 kubeconfig6. 创建角色和角色绑定7. 测试 1. 普通用户 创建用户demo useradd demo2. 创建私钥 下面的脚本展示了如何生成 PKI 私钥和 CSR。 设置 CSR 的 CN 和 …...

DeepSeek与ChatGPT的全面对比

在人工智能&#xff08;AI&#xff09;领域&#xff0c;生成式预训练模型&#xff08;GPT&#xff09;已成为推动技术革新的核心力量。OpenAI的ChatGPT自发布以来&#xff0c;凭借其卓越的自然语言处理能力&#xff0c;迅速占据市场主导地位。然而&#xff0c;近期中国AI初创公…...

C# dynamic 关键字 使用详解

总目录 前言 dynamic 是 C# 4.0 引入的关键字&#xff0c;用于声明动态类型&#xff0c;允许在运行时解析类型和成员&#xff0c;而非编译时。它主要设计用于简化与动态语言&#xff08;如 Python、JavaScript&#xff09;的交互、处理未知结构的数据&#xff08;如 JSON、XML…...

sql server 数据库 锁教程及锁操作

SQL Server数据库 锁的教程 SQL Server 的数据库锁是为了保证数据库的并发性和数据一致性而设计的。锁机制能够确保多个事务不会同时修改同一数据&#xff0c;从而避免数据冲突和不一致的发生。理解 SQL Server 的锁机制对于开发高效、并发性强的数据库应用非常重要。 1. 锁的…...

超全Deepseek资料包,deepseek下载安装部署提示词及本地部署指南介绍

该资料包涵盖了DeepSeek模型的下载、安装、部署以及本地运行的详细指南&#xff0c;适合希望在本地环境中高效运行DeepSeek模型的用户。资料包不仅包括基础的安装步骤&#xff0c;还提供了68G多套独立部署视频教程教程&#xff0c;针对不同硬件配置的模型选择建议&#xff0c;以…...

DeepSeek24小时写作机器人,持续创作高质量文案

内容创作已成为企业、自媒体和创作者的核心竞争力。面对海量的内容需求&#xff0c;人工创作效率低、成本高、质量参差不齐等问题日益凸显。如何在有限时间内产出高质量内容&#xff1f;DeepSeek写作机器人&#xff0c;一款24小时持续创作的智能工具&#xff0c;为企业和个人提…...

用deepseek学大模型08-卷积神经网络(CNN)

yuanbao.tencent.com 从入门到精通卷积神经网络(CNN),着重介绍的目标函数&#xff0c;损失函数&#xff0c;梯度下降 标量和矩阵形式的数学推导&#xff0c;pytorch真实能跑的代码案例以及模型,数据&#xff0c;预测结果的可视化展示&#xff0c; 模型应用场景和优缺点&#xf…...

玩客云 IP查找

1.玩客云使用静态IP在不同网段路由器下不能使用&#xff0c;动态不好找IP地址 1.1使用python3 实现自动获取发送 import requests import os import socket# 从环境变量获取 PushPlus 的 token 和群组编码 PUSH_PLUS_TOKEN os.getenv("PUSH_PLUS_TOKEN") PUSH_PLU…...

【鸿蒙Next】鸿蒙应用发布前的准备

图标生成&#xff1a; https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-apply-generated-icon-V5 debug 与 release使用不同的bundle name 鸿蒙多环境配置 https://segmentfault.com/a/1190000045418731...

【OpenCV】入门教学

&#x1f3e0;大家好&#xff0c;我是Yui_&#x1f4ac; &#x1f351;如果文章知识点有错误的地方&#xff0c;请指正&#xff01;和大家一起学习&#xff0c;一起进步&#x1f440; &#x1f680;如有不懂&#xff0c;可以随时向我提问&#xff0c;我会全力讲解~ &#x1f52…...

嵌入式 lwip http server makefsdata

背景&#xff1a; 基于君正X2000 MCU Freertoslwip架构 实现HTTP server服务&#xff0c;MCU作为HTTP服务器通过网口进行数据包的传输&#xff0c;提供网页服务。其中设计到LWIP提供的工具makefsdata&#xff0c;常用于将文件或目录结构转换为适合嵌入到固件中的二进制格式。 …...

qemu-kvm源码解析-cpu虚拟化

背景 Qemu 虚拟化中&#xff0c;CPU&#xff0c;内存&#xff0c;中断是虚拟化的核心板块。本章主要对CPU虚拟化源码进行分析 而随着技术的发展包括CPU、内存、网卡等常见外设。硬件层面的虚拟化现在已经是云计算的标配。形成了&#xff0c;qemu作为cpu外层控制面&#xff0c…...

【蓝桥杯集训·每日一题2025】 AcWing 6123. 哞叫时间 python

6123. 哞叫时间 Week 1 2月18日 农夫约翰正在试图向埃尔茜描述他最喜欢的 USACO 竞赛&#xff0c;但她很难理解为什么他这么喜欢它。 他说「竞赛中我最喜欢的部分是贝茜说 『现在是哞哞时间』并在整个竞赛中一直哞哞叫」。 埃尔茜仍然不理解&#xff0c;所以农夫约翰将竞赛以…...

数据治理中 大数据处理一般都遵循哪些原则

在数据治理中&#xff0c;大数据处理通常遵循以下原则&#xff1a; 最小化原则&#xff1a;企业应只收集实现特定目的所需的数据&#xff0c;避免数据冗余和安全风险。 合法性原则&#xff1a;企业必须遵守相关法律法规&#xff0c;确保数据处理符合法律要求&#xff0c;降低法…...

Linux 多进程生产者消费者模型实现

Linux 多进程生产者消费者模型实现 一、模型核心组件二、关键代码解析1. 信号量封装类&#xff08;csemp&#xff09;2. 共享内存初始化3. 生产者核心逻辑4. 消费者核心逻辑 三、关键同步机制信号量使用策略操作时序图 四、扩展知识1. System V与POSIX信号量对比2. 共享内存最佳…...

【Python pro】基本数据类型

一、数字类型 1.1 数字类型的组成 1.1.1 整数 &#xff08;1&#xff09;十进制&#xff0c;二进制0b&#xff0c;八进制0o&#xff0c;十六进制0x print(16 0b10000 0o20 0x10) # 输出&#xff1a;True&#xff08;2&#xff09;十进制转其他进制 a bin(16) b oct(1…...

sql server查询IO消耗大的排查sql诊断语句

原文链接&#xff1a; sql server查询IO消耗大的排查sql诊断语句-S3软件[code]select top 50 (total_logical_reads/execution_count) as avg_logical_reads , (total_logical_writes/execution_count) as avg_logical_writes , (tota ... https://blog.s3.sh.cn/thread-120-1…...

Spring Boot 自动装配原理深度剖析

一、引言 在 Java 开发领域&#xff0c;Spring 框架无疑是中流砥柱。而 Spring Boot 的出现&#xff0c;更是极大地简化了 Spring 应用的搭建和开发过程。其中&#xff0c;自动装配原理是 Spring Boot 的核心亮点之一&#xff0c;它让开发者无需手动编写大量繁琐的配置代码&am…...

kubernetes源码分析 kubelet

简介 从官方的架构图中很容易就能找到 kubelet 执行 kubelet -h 看到 kubelet 的功能介绍&#xff1a; kubelet 是每个 Node 节点上都运行的主要“节点代理”。使用如下的一个向 apiserver 注册 Node 节点&#xff1a;主机的 hostname&#xff1b;覆盖 host 的参数&#xff1…...

Golang学习笔记_33——桥接模式

Golang学习笔记_30——建造者模式 Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 文章目录 桥接模式详解一、桥接模式核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、桥接模式的特点三、适用场景1. 多维度变化2. 跨平台开发3. 动态切换实现 四、与其他…...

使用EasyExcel和多线程实现高效数据导出

​ 使用EasyExcel和多线程实现高效数据导出 1. 概述 在企业级应用中&#xff0c;数据导出是一个常见的需求。为了提高导出效率&#xff0c;尤其是在处理大量数据时&#xff0c;我们可以结合使用EasyExcel库和多线程技术。本文将详细介绍如何通过EasyExcel和多线程技术实现高…...

告别冷冰冰:如何训练AI写出温暖人心的广告文案

朋友们&#xff0c;你们是不是也好奇过&#xff0c;如果让AI来写广告文案&#xff0c;会是什么效果&#xff1f; 是冷冰冰的数据堆砌&#xff0c;还是也能玩出创意和温度&#xff1f; 别担心&#xff0c;今天我就来给你揭秘&#xff0c;怎么调教AI&#xff0c;让它写出的广告…...

【js逆向_入门】图灵爬虫练习平台 第四题

(base64解码&#xff09;地址&#xff1a;aHR0cHM6Ly9zdHUudHVsaW5ncHl0b24uY24vcHJvYmxlbS1kZXRhaWwvNC8 请求接口带有加密参数&#xff1a; 全局搜索Sign,找到参数生成位置 一目了然&#xff0c;知道参数是怎么构造生成的 调试代码 测试验证思路是否正确 时间&#xff1a; …...

Mybatis后端数据库查询多对多查询解决方案

问题场景&#xff1a; 我开发的是一个论文选择系统。 后端用一个论文表paper来存储论文信息。 论文信息中&#xff0c;包含前置课程&#xff0c;也就是你需要修过这些课程才能选择这个论文。 而一个论文对应的课程有很多个。 这样就造成了一个数据库存储的问题。一个paper…...

记一次 Git Fetch 后切换分支为空的情况

Git Fetch 后切换分支为空的情况 在使用 Git 时&#xff0c;我遇到这样的情况&#xff1a;执行 git fetch 后切换分支&#xff0c;发现工作目录是空的&#xff0c;没有任何文件&#xff0c;所以插眼记录一下。 原因分析 git fetch 的作用&#xff1a;git fetch 只会从远程仓库…...