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

Linux系统:ext2文件系统的核心概念和结构

本节重点

  • 块、块组、分区的引入
  • 块组的构成
  • inode与inode Table
  • 路径解析与路径缓存机制
  • 目录与文件名在文件系统中的存储
  • 分区的初始化与挂载

一、ext2文件系统

1.1 “块”的引入

在前言部分我们说扇区是磁盘硬件的最小读写单位,通常为512字节,但是在操作系统读取硬盘数据的时候不会通过读取一个一个扇区的方式完成读写操作,单个扇区的读写操作效率较低。现代存储设备如硬盘和固态硬盘(SSD)通常具有较高的延迟和较低的吞吐量。每次读写操作都需要进行寻址、旋转等待和数据传输,这些操作的开销较大。

在读取硬盘数据的时候操作系统会一次性读取多个扇区,即一次性读取一个“块”。一个“块”的大小是初始化的时候就确定的,是不可更改的。

块的大小通常是4kb,即8个扇区组成一个“块”,块是文件存取的最小单位。

1.2 “块组”的引入

在ext2文件系统中,块组(Block Group)是将多个块组合在一起,形成的一个更大的管理单元。每个块组包含一定数量的数据块、inode表、位图等信息。

每个块组通常包含以下部分:

  • 超级块(Superblock):存储文件系统的全局信息,如块大小、inode数量等。
  • 组描述符(Group Descriptor):描述块组的元数据,如块组中空闲块和inode的数量。
  • 数据块位图(Block Bitmap):记录块组中哪些数据块已被使用。
  • inode位图(inode Bitmap):记录块组中哪些inode已被使用。
  • inode表(inode Table):存储文件元数据,如文件大小、权限、所有者等。
  • 数据块(Data Blocks):实际存储文件数据的地方。

1.3 “分区”的引入

分区是硬盘或存储设备上被逻辑划分的区域,每个分区可以独立管理和使用。每个分区都是由许多个块组构成的。每个分区可以安装不同的操作系统或存储不同类型的数据。

二、详解块组

 2.1 inode与inode Table

之前我们说过:文件=内容+属性,当我们使用ls -l的时候不仅可以看到文件名,当然也可以看到文件的元数据(属性)。

 文件的内容与元数据存储在磁盘中,ls -l命令读取存储在磁盘的文件信息然后显示出来:

这种信息除了通过这种方式来获取之外,我们还可以通过stat命令看到更多信息:

2.1.1  inode

在磁盘中除了存储文件内容也需要存储文件的元数据,这就说明操作系统除了给文件内容分配足够的数据块,也要给文件的元数据分配相应的数据块。

为了高效管理文件的元数据,操作系统在内核中引入了 inode(索引节点)数据结构。inode 本身在底层通常是一个结构体(struct)存储了文件的元数据,包括文件大小、文件权限、文件所有者、文件组、文件类型、文件链接数、文件的时间戳(如创建时间、修改时间、访问时间)以及文件数据块的指针。具体实现可能因操作系统和文件系统的不同而有所差异。

每个Inode的大小通常为128字节或256字节。

在 Linux 内核中,inode 结构体定义在 include/linux/fs.h 文件中。以下是一个简化的示例:

struct inode {unsigned long i_ino;         // inode 编号umode_t i_mode;              // 文件类型和权限uid_t i_uid;                 // 所有者用户 IDgid_t i_gid;                 // 所有者组 IDloff_t i_size;               // 文件大小struct timespec i_atime;     // 最后访问时间struct timespec i_mtime;     // 最后修改时间struct timespec i_ctime;     // 最后状态改变时间unsigned long i_blocks;      // 文件占用的块数struct address_space *i_mapping; // 文件数据块的映射unsigned long i_data[15];    // 数据块指针
};

一个文件只能对应一个inode,在inode中除了存储对应文件的元数据外还存储了inode号,inode号用来确定唯一的一个inode。在命令行中可以通过ls -li来查看到文件信息与其对应的inode号:

注意:inode中不存储文件名

inode号的分配机制:

分区中的inode号是唯一的,inode号的作用范围仅限于其所在的分区,不同分区inode号可能重复。

在同一分区的不同块组中,inode号的分配考虑块组的负载均衡,将文件和目录均匀地分布在不同的块组中。

同一块组中,inode号是唯一的,不可重复的。

2.1.2 inode Table

Inode Table(索引节点表)是文件系统中用于存储文件元数据的数据结构。每个文件或目录在文件系统中都有一个对应的Inode,Inode Table则是这些Inode的集合。

Inode Table通常是一个固定大小的数组,每个数组元素对应一个Inode。每个Inode的大小是固定的,具体大小取决于文件系统的设计,通常为128字节或256字节。

当文件系统需要访问一个文件时,首先会通过文件名找到对应的inode号,然后通过根据inode号通过相关算法确定所在的块组,在该块组中的inode Table找到对应inode号所对应的inode,这样我们就找到了要访问文件的内容与所对应的元数据(属性)。

inode Table的作用

在文件系统中inode Table(索引节点表)主要提供索引的功能,具体来说就是当用户访问某一文件时,操作系统会将该文件inode号与具体inode结构体通过inode Table快速索引。

2.2 Data Blocks

在ext2文件系统中,Data Blocks是用于存储实际文件数据的部分。每个文件或目录的内容都存储在一个或多个Data Blocks中。在ext2文件系统中,Data Blocks(数据块)占据了块组的主要部分,因为文件内容通常比元数据大得多。

Data Blocks表示数据块的集合,这不过这部分数据块用来存储文件内容。

inode与文件内容(data blocks)的映射 

在Linux系统中,文件的内容与属性(元数据)是分开存储的。元数据存储在inode中,而文件的内容则存储在数据块中,这些数据块分布在磁盘的不同位置。文件系统通过inode中的指针来映射文件的实际数据块的。

相关数据结构:

#define EXT2_N_BLOCKS 15struct ext2_inode {// 其他字段...__le32 i_block[EXT2_N_BLOCKS];  // 指向数据块的指针数组// 其他字段...
};

这里i_block 是一个数组,用于存储指向数据块的指针。EXT2_N_BLOCKS 是一个常量,通常定义为 15,表示 i_block 数组的大小。这个数组用于管理文件的数据块。

其中i_block数组前12个元素是直接块指针,指向文件的实际数据块。接下来的 3 个元素分别是一级间接块指针、二级间接块指针和三级间接块指针

这些间接块指针不会直接指向数据块,而是指向一个指针的集合,这个集合中的指针都指向实际数据块或者另一个间接块指针(如果还需要数据块来存储文件内容)。

  • 一级间接指针:指向一个包含数据块指针的块。
  • 二级间接指针:指向一个包含一级间接指针的块。
  • 三级间接指针:指向一个包含二级间接指针的块。

通过这种方式,文件系统可以有效地管理非常大的文件,而不需要为每个文件存储大量的直接指针。

通过inode与文件内容(data blocks)的映射,我们发现当我们拿到一个文件具体的inode时文件内容与文件属性就已经确定了。

2.3 inode Bitmap 与 Block Bitmap

在文件系统中,inode Bitmap和 inode Bitmap是用于管理存储资源的重要数据结构。它们分别用于跟踪 inode和数据块的使用情况。通过 inode Bitmap 和 inode Bitmap,文件系统能够高效地管理存储资源,确保数据的快速存取和存储空间的合理利用。

2.3.1 inode Bitmap

inode Bitmap是一个位图结构,用于表示inode Bitmap的使用状态。每个位对应一个inode,如果该位为 1,表示对应的inode已被使用;如果为 0,则表示该 inode空闲。

作用:inode Bitmap用于快速查找和分配空闲的inode,从而提高文件系统的效率。

示例:假设一个文件系统有 1024 个 inode,那么 inode Bitmap将包含 1024 位,每个位对应一个 inode的状态。

2.3.2 Block Bitmap

Block Bitmap 同样是一个位图结构,用于表示数据块的使用状态。每个位对应一个数据块,如果该位为 1,表示对应的数据块已被使用;如果为 0,则表示该数据块空闲。

作用:Block Bitmap 用于快速查找和分配空闲的数据块,确保文件系统能够高效地管理存储空间。

示例:假设一个文件系统有 4096 个数据块,那么 Block Bitmap 将包含 4096 位,每个位对应一个数据块的状态。

2.4 GDT

GDT用于存储块组的描述信息,包括块组的起始块、块组的空闲块数、块组的inode表位置等。GDT的存在使得文件系统能够高效地管理和分配磁盘空间。

GDT通常是一个数组,每个元素描述一个块组的信息。在ext文件系统中,GDT的每个条目包含以下信息:

  • 块组的起始块号
  • 块组的空闲块数
  • 块组的inode表位置
  • 块组的位图位置

 查看GDT信息:

在Linux系统中,可以使用dumpe2fs命令查看ext文件系统的GDT信息。以下是一个示例命令:

dumpe2fs /dev/sda1 | grep -i "group descriptors"

该命令会输出文件系统中所有块组的描述符信息,包括每个块组的起始块号、空闲块数等。

总的来看,GDT中主要存储整个所在块组的描述信息,包括块组中inode Table,inode Bitmap,Block Bitmap等区域的起始与终止位置,整个块组中数据块的使用情况等信息。

2.5 Super Block

前面我们讲过,文件系统的基本单位是分区,一块磁盘上会被划分为多个分区。每个分区可以独立格式化并使用不同的文件系统。

Super Block 是文件系统中的一个关键数据结构,用于存储文件系统的元数据。它通常位于文件系统的开头,包含文件系统的整体信息,如大小、块大小、inode 数量等。Super Block 是文件系统管理和维护的基础。

Super Block 通常包含以下信息:

  • 文件系统类型:标识文件系统的类型,如 ext2、ext3、ext4 等。
  • 块大小:文件系统中每个块的大小,通常为 1KB、2KB、4KB 等。
  • 总块数:文件系统中总的块数。
  • 空闲块数:当前可用的空闲块数。
  • inode 数量:文件系统中 inode 的总数。
  • 空闲 inode 数:当前可用的空闲 inode 数。
  • 挂载信息:文件系统的挂载状态、挂载时间等。
  • 文件系统状态:文件系统的状态信息,如是否干净关闭、是否需要检查等。

在 Linux 的 ext2/ext3/ext4 文件系统中,Super Block 的结构可能如下所示:

struct ext2_super_block {uint32_t s_inodes_count;         // 文件系统中 inode 的总数uint32_t s_blocks_count;         // 文件系统中块的总数uint32_t s_r_blocks_count;       // 保留块数uint32_t s_free_blocks_count;    // 空闲块数uint32_t s_free_inodes_count;    // 空闲 inode 数uint32_t s_first_data_block;     // 第一个数据块的块号uint32_t s_log_block_size;       // 块大小的对数uint32_t s_log_frag_size;        // 片段大小的对数uint32_t s_blocks_per_group;     // 每个块组中的块数uint32_t s_frags_per_group;      // 每个块组中的片段数uint32_t s_inodes_per_group;     // 每个块组中的 inode 数uint32_t s_mtime;                // 最后一次挂载时间uint32_t s_wtime;                // 最后一次写入时间uint16_t s_mnt_count;            // 挂载次数uint16_t s_max_mnt_count;        // 最大挂载次数uint16_t s_magic;                // 文件系统魔数uint16_t s_state;                // 文件系统状态uint16_t s_errors;               // 错误处理方式uint16_t s_minor_rev_level;      // 次版本号uint32_t s_lastcheck;            // 最后一次检查时间uint32_t s_checkinterval;        // 检查间隔时间uint32_t s_creator_os;           // 创建文件系统的操作系统uint32_t s_rev_level;            // 版本号uint16_t s_def_resuid;           // 默认保留用户 IDuint16_t s_def_resgid;           // 默认保留组 ID// 其他字段...
};

 这里需要注意的是,Super Block保存整个文件系统的描述信息,而GDT保存所在块组的描述信息

***为什么描述整个文件系统的Super Block会存在于块组中呢?

关键1:Super Block对于整个文件系统至关重要

Super Block 是文件系统的核心数据结构,记录了整个文件系统的关键信息,如文件系统的大小、块大小、空闲块的数量、inode 的数量等。这些信息对于文件系统的初始化和运行至关重要。

如果 Super Block 只存在于文件系统的开头,一旦该区域损坏,整个文件系统将无法访问。

关键2:通过备份提高可靠性和恢复能力

这里我们需要明白的是,不是所有块组中都包含了Super Block。

当整个文件系统遭到损坏和数据丢失时,通过在多个块组中复制 Super Block,即使某个块组的 Super Block 损坏,其他块组中的备份仍可确保文件系统的正常访问。

 三、目录与文件名

在之前我们了解到,操作系统只要找到对应文件的inode就可以确定文件的属性和内容。但是在实际上用户只会给提供文件名并不会提供inode号。

目录也是文件,在磁盘中没有目录的概念只有文件属性+文件内容的概念。而目录的元数据保存在对应的inode中,目录的文件内容就是:文件名与inode号的映射关系

所以访问文件的时候,当用户(进程)提供了一个文件名时操作系统就会打开当前目录,根据文件名查找对应的inode号,然后进行后续文件访问。

比如我们通过:

ls -li code.cc

打印所在目录中code.cc的属性信息时,操作系统首先会打开当前工作目录,查找code.cc对应的inode号进而对文件进行访问。

3.1 路径解析

 当我们需要打印/home/yjh/linux-learning/5_17/code.cc文件的属性信息时,操作系统并非直接访问5_17目录的内容来获取code.cc的inode号。由于5_17本身也是一个文件名,系统需要先确定其对应的inode号。这一过程需要逐级回溯:首先访问linux-learning目录的内容以获取5_17的inode号,接着访问yjh目录的内容以获取linux-learning的inode号,然后访问home目录的内容以获取yjh的inode号,最终通过打开根目录/来获取home的inode号

最终结论:任何文件都有路径,访问目标文件都要从/(更)目录开始,依次访问每个目录下指定的目录直到访问到目标文件(目录),这个过程就叫做路径解析。

3.2 路径缓存

在实际上并不是每次访问目标文件都会从/(根目录)开始进行路径解析,操作系统通过路径缓存缓存已经解析过的路径信息,加速文件路径查找的机制,减少重复查找目录项(dentry)的开销,从而提高文件系统的访问效率。

在Linux系统,在内核中维护树状路径结构的内核结构体叫做:struct dentry

在路径解析的过程中,操作系统会将遇到的文件inode创建dentry结构并链入树形结构,同时该dentry还属于一个LRU链表和哈希表。前者提供淘汰机制移除最久未使用的数据来管理缓存空间,后者方便快速查找:

struct dentry {atomic_t d_count;           // 引用计数unsigned int d_flags;       // 目录项的标志spinlock_t d_lock;          // 自旋锁,用于保护该结构struct inode *d_inode;      // 关联的 inodestruct hlist_node d_hash;   // 哈希表节点struct dentry *d_parent;    // 父目录项struct qstr d_name;         // 目录项的名称struct list_head d_lru;     // LRU 链表struct list_head d_child;   // 子目录项链表struct list_head d_subdirs; // 子目录项链表struct dentry_operations *d_op; // 目录项操作函数指针struct super_block *d_sb;   // 所属的超级块void *d_fsdata;             // 文件系统私有数据unsigned char d_iname[DNAME_INLINE_LEN]; // 内联名称
};

 这个由struct dentry节点组成的树形结构,整体组成了Linux的路径缓存机制,打开或访问任何文件都在先在这棵树下根据路径进行查找,找到就返回属性inode和内容,没找到就从磁盘加载路径,添加dentry节点,缓存新路径。

四、分区的初始化与挂载

分区创建后,磁盘空间被划分为独立的区域,但这些区域尚未包含任何文件系统。操作系统无法识别或访问这些分区中的数据,因为它们没有文件系统来管理数据的存储和检索。

在使用分区之前,需要为其创建文件系统。文件系统是用于管理文件和目录的结构,常见的文件系统包括 ext4、NTFS、FAT32 等。通过格式化分区,可以为其初始化文件系统。

mkfs.ext4 /dev/sdX1

文件系统初始化后,需要将分区挂载到操作系统的目录树中,才能访问和使用。挂载是将分区与特定目录关联的过程,使得该目录成为分区的访问点。通过挂载,操作系统可以访问和管理该分区上的文件和目录。

挂载的方法:

在 Linux 系统中,挂载分区通常使用 mount 命令。以下是一个示例:

sudo mount /dev/sdb1 /mnt/data

上述命令将/dev/sdb1分区挂载到/mnt/data目录。

挂载使得存储设备的内容可以被操作系统识别和访问。将一个硬盘分区挂载到 /mnt/data 目录后,所有对该目录的访问实际上是对该分区内容的访问。

注意事项

挂载时需确保挂载点目录存在且为空,否则可能会导致数据冲突或丢失。

相关文章:

Linux系统:ext2文件系统的核心概念和结构

本节重点 块、块组、分区的引入块组的构成inode与inode Table路径解析与路径缓存机制目录与文件名在文件系统中的存储分区的初始化与挂载 一、ext2文件系统 1.1 “块”的引入 在前言部分我们说扇区是磁盘硬件的最小读写单位,通常为512字节,但是在操作…...

Python 装饰器详解

装饰器是 Python 中一种强大的语法特性,它允许在不修改原函数代码的情况下动态地扩展函数的功能。装饰器本质上是一个高阶函数,它接受一个函数作为参数并返回一个新的函数。 基本装饰器 1. 简单装饰器示例 def my_decorator(func):def wrapper():prin…...

Docker配置容器开机自启或服务重启后自启

要将一个 Docker 容器设置为开机自启,你可以使用 docker update 命令或配置 Docker 服务来实现。以下是两种常见的方法: 方法 1:使用 docker update 设置容器自动重启 使用 docker update 设置容器为开机自启 你可以使用以下命令&#xff0c…...

20250518 黎曼在三维空间中总结的一维二维的规律,推广到高维度合适吗?有没有人提出反对意见

黎曼在三维空间中总结的一维二维的规律,推广到高维度合适吗?有没有人提出反对意见 黎曼几何在数学物理中的广泛应用,尤其是在广义相对论和高维空间理论中,确实是建立在黎曼在三维空间中的推广基础上的。不过,这种推广…...

使用AI 生成PPT 最佳实践方案对比

文章大纲 一、专业AI生成工具(推荐新手)**1. 推荐工具详解****2. 操作流程优化****3. 优势与局限**二、代码生成方案(开发者推荐)**1. Python-pptx进阶用法****2. GitHub推荐**三、混合工作流(平衡效率与定制)**1. 工具链升级****2. 示例Markdown结构**四、网页转换方案(…...

【Docker】Docker Compose方式搭建分布式协调服务(Zookeeper)集群

开发分布式应用时,往往需要高度可靠的分布式协调,Apache ZooKeeper 致力于开发和维护开源服务器,以实现高度可靠的分布式协调。具体内容见zookeeper官网。现代应用往往使用云原生技术进行搭建,如何用Docker搭建Zookeeper集群,这里介绍使用Docker Compose方式搭建分布…...

R for Data Science(3)

R for Data Science以下是关于网页内容的详细笔记: 1. 章节概览 章节主题:数据转换(Data Transformation)核心内容:介绍如何使用 R 中的 dplyr 包进行数据转换,包括对数据框的行、列和组的操作&#xff0…...

深入浅出Hadoop:大数据时代的“瑞士军刀”

深入浅出Hadoop:大数据时代的“瑞士军刀” 在当今这个数据爆炸的时代,每天产生的数据量已经远超人类的想象。从社交媒体的互动到电商平台的交易记录,从物联网设备的实时监控到科学研究的实验数据,大数据已经成为推动各行各业变革…...

《Python星球日记》 第94天:走近自动化训练平台

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、自动化训练平台简介1. Kubeflow Pipelines2. TensorFlow Extended (TFX) 二…...

MetaMask安装及使用-使用水龙头获取测试币的坑?

常见的异常有: 1.unable to request drip, please try again later. 2.You must hold at least 1 LINK on Ethereum Mainnet to request native tokens. 3.The address provided does not have sufficient historical activity or balance on the Ethereum Mainne…...

软件架构之--论微服务的开发方法1

论微服务的开发方法1 摘要 2023年 2月,本人所在集团公司承接了长三角地区某省渔船图纸电子化审查系统项目开发,该项目旨在为长三角地区渔船建造设计院、以及渔船图纸审查机构提供一个便捷的渔船图纸电子化审查服务平台。在此项目中,我作为项目组成员参与项目的建设工作,并…...

SOLID 面对象设计的五大基本原则

SOLID 原则的价值 原则核心价值解决的问题SRP职责分离,提高内聚性代码臃肿、牵一发而动全身OCP通过扩展而非修改实现变化频繁修改现有代码导致的风险LSP确保子类行为的一致性继承滥用导致的系统不稳定ISP定制化接口,避免依赖冗余接口过大导致的实现负担…...

游戏引擎学习第293天:移动Familiars

回顾并为今天的内容定下基调 我们正在做一款完整的游戏,今天的重点是“移动模式”的正式化处理。目前虽然移动机制大致能运作,但写法相对粗糙,不够严谨,我们希望将其清理得更规范,更可靠一点。 目前脑逻辑&#xff0…...

《沙尘暴》观影记:当家庭成为人性的修罗场

起初点开《沙尘暴》,不过是想在碎片时间里寻个消遣,毕竟短剧的篇幅显得轻松无负担。未曾想,这看似简短的故事却如一场裹挟着砂砾的风暴,在心底掀起层层涟漪,让我忍不住在家庭教育、人性幽微处反复踱步沉思。 一、风暴眼…...

牛客网NC21989:牛牛学取余

牛客网NC21989:牛牛学取余 📝 题目描述 ⏱️ 限制条件 时间限制:C/C/Rust/Pascal 1秒,其他语言2秒空间限制:C/C/Rust/Pascal 32 M,其他语言64 M输入范围:两个整数,在int范围内 📥…...

王者荣耀游戏测试场景题

如何测试一个新英雄:方法论与实践维度 测试一个新英雄不仅仅是“打打打”,而是一套完整的测试流程,包括设计文档验证、功能验证、数值验证、性能验证、交互验证等。可以从以下多个角度展开: 🔍 1. 方法论维度 ✅ 测试…...

Spring Boot 与 RabbitMQ 的深度集成实践(二)

集成步骤详解 配置 RabbitMQ 连接信息 在 Spring Boot 项目中,通常在application.properties或application.yml文件中配置 RabbitMQ 的连接信息。以application.yml为例,配置如下: spring: rabbitmq: host: localhost port: 5672 usern…...

医疗信息系统安全防护体系的深度构建与理论实践融合

一、医疗数据访问系统的安全挑战与理论基础 1.1 系统架构安全需求分析 在医疗信息系统中,基于身份标识的信息查询功能通常采用分层架构设计,包括表现层、应用层和数据层。根据ISO/IEC 27001信息安全管理体系要求,此类系统需满足数据保密性…...

多模态大语言模型arxiv论文略读(八十)

## MMWorld: Towards Multi-discipline Multi-faceted World Model Evaluation in Videos ➡️ 论文标题:MMWorld: Towards Multi-discipline Multi-faceted World Model Evaluation in Videos ➡️ 论文作者:Xuehai He, Weixi Feng, Kaizhi Zheng, Yuji…...

FFmpeg:多媒体处理的终极利器

FFmpeg详细介绍 1. 定义与基本概述 FFmpeg是一套开源的跨平台多媒体处理工具集,最初由法国程序员Fabrice Bellard于2000年开发,其名称源自“Fast Forward MPEG”,体现了其高效处理MPEG格式的能力。它不仅是命令行工具,还包含多个库和开发套件,支持视频转码、剪辑、合并、…...

【Leetcode】取余/2的幂次方

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。 示例 1: 输入: num 38 输出: 2 解释: 各位相加的过程为: 38 --> 3 8 --> 11 11 --> 1 1 --> 2 由于 2 是一位数,所以返回 2。 …...

程序代码篇---ESP32的数据采集

文章目录 前言 前言 本文简单介绍了ESP32可以怎样采集数据。...

系统架构设计(十三):虚拟机体系结构风格

概念 虚拟机(Virtual Machine)体系结构风格,是指将整个系统抽象为一台“虚拟机”,通过解释或模拟的方式运行应用程序。 它本质上提供了一种“平台中立”的运行环境,典型代表就是 Java 虚拟机(JVM&#xf…...

lvs-dr部署

实验准备: 准备4台设备,1台作为客户机,3台作为服务器,服务器中1台作为调度器,2台作为后端真实访问服务器。并关闭所有防火墙与核心防护。 systemctl stop firewalld setenforce 0 实验开始 调度器配置 yum -y ins…...

数据库blog2_数据结构与效率

🌿计算机中的数据————存储结构与逻辑结构 🍂存储结构(物理结构) 定义:存储结构是指数据在计算机存储器中的实际存储方式,由计算机硬件特性决定。它涉及到数据的物理位置和存储顺序。存储结构直接影响数…...

聊天室项目总结

已实现的功能点: 存在的问题: 1.没有实现有含金量的创新功能点 2.太过于依赖工具,不喜欢自己看文章总结对知其然而不知其所以然,自己的理解比较少,懒于去思考 3.太过于依赖他人,自己的想法有点少&#x…...

数据结构:二叉树一文详解

数据结构:二叉树一文详解 前言一、二叉树的基本概念与结构特性1.1 二叉树的定义1.2 二叉树的特殊类型1.3 二叉树的性质 二、二叉树的遍历方式2.1 前序遍历(Pre-order Traversal)2.2 中序遍历(In-order Traversal)2.3 后序遍历&…...

2025年- H28-Lc136- 24.两两交换链表中的节点(链表)---java版

1.题目描述 2.思路 cur指针要先放在虚拟头节点,才能去操作第一个数和第二个数 先判断偶数个节点,再判断奇数个节点,否则会犯空指针异常。 (1)如果节点是偶数个节点,只要满足curr.nextnull,就说…...

ubuntu18.04通过cuda_11.3_xxx.run安装失败,电脑黑屏解决办法

项目场景: ubuntu18.04跑DG-SLAM相关代码,安装lietorch包报错,需要用到GPU。 问题描述 跑代码需要cuda11.3,系统里面有另外一个版本,运行cuda_11.3_xxx.run,同时也选择了driver,安装成功后&am…...

Linux之基础IO

目录 一、理解 "文件" 1.1、狭义理解 1.2、广义理解 1.3、文件操作的归类认知 1.4、系统角度 二、回顾C语言接口 2.1、打开文件 2.2、写文件 2.3、读文件 2.4、stdin & stdout & stderr 2.6、打开文件的方式 三、系统文件I/O 3.1、一种传递标志…...

上位机知识篇---涂鸦智能云平台

文章目录 前言 前言 本文简单介绍了涂鸦智能云平台。...

InfluxDB 3 Core + Java 11 + Spring Boot:打造高效物联网数据平台

一、 引言:为什么选择InfluxDB 3? 项目背景: 在我们的隧道风机监控系统中,实时数据的采集、存储和高效查询是至关重要的核心需求。风机运行产生的振动、倾角、电流、温度等参数是典型的时序数据,具有高并发写入、数据…...

Kubernetes控制平面组件:Kubelet详解(七):容器网络接口 CNI

云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...

Pandas 构建并评价聚类模型② 第六章

构建并评价聚类模型 构建并评价聚类模型一、数据读取与准备(代码6 - 6部分)结果代码解析 二、Kmeans聚类(代码6 - 6部分)结果代码解析 三、数据降维可视化(代码6 - 6部分)结果代码解析 四、FMI评价&#xf…...

【simulink】IEEE33节点系统潮流分析模型

目录 主要内容 程序内容 2.1 33节点simulink模型一览 2.2 节点模型图 下载链接 主要内容 该仿真采用simulink模型对33节点网络进行模拟仿真,在simulink模型中定义了33节点系统的电阻、电抗、节点连接关系等参数,通过控制块来实现信号连接关系&…...

彻底解决docker代理配置与无法拉取镜像问题

为什么会有这篇文章? 博主在去年为部署dify研究了docker,最后也是成功部署,但是因为众所周知的原因,卡ziji脖子 ,所以期间遇到各种网络问题的报错,好在最后解决了. 但时隔一年,博主最近因为学习原因又一次使用docker,原本解决的问题却又没来由的出现,且和之前有很多不同(有时…...

Linux 安装 Unreal Engine

需要对在unreal engine官网进行绑定github账号,然后到unreal engine github仓库中进行下载对应的版本,并进行安装unreal engine官网 github地址...

tensorflow图像分类预测

tensorflow图像分类预测 CPU版本和GPU版本二选一 CPU版本 pip -m install --upgrade pippip install matplotlib pillow scikit-learnpip install tensorflow-intel2.18.0GPU版本 工具 miniconda 升级依赖库 conda update --all创建目录 mkdir gpu-tf进入目录 cd gpu-tf创建虚…...

C++数组详解:一维和多维数组的定义、初始化、访问与遍历

1. 引言 数组是C中最基础的数据结构之一,用于存储相同类型的元素的集合。它提供了高效的内存访问方式,适用于需要快速查找和遍历数据的场景。本文将全面介绍: 一维数组的定义、初始化与遍历多维数组(如二维数组)的定…...

linux下编写shell脚本一键编译源码

0 前言 进行linux应用层编程时,经常会使用重复的命令对源码进行编译,然后把编译生成的可执行文件拷贝到工作目录,操作非常繁琐且容易出错。本文编写一个简单的shell脚本一键编译源码。 1 linux下编写shell脚本一键编译源码 shell脚本如下&…...

安卓端互动娱乐房卡系统调试实录:从UI到协议的万字深拆(第一章)

前言:调房卡,不如修空调(但更费脑) 老实说,拿到这套安卓端互动组件源码的时候,我内心是拒绝的。不是因为它不好,而是太好了,目录规整、界面精美、逻辑还算清晰,唯一的问…...

【通用大模型】Serper API 详解:搜索引擎数据获取的核心工具

Serper API 详解:搜索引擎数据获取的核心工具 一、Serper API 的定义与核心功能二、技术架构与核心优势2.1 技术实现原理2.2 对比传统方案的突破性优势 三、典型应用场景与代码示例3.1 SEO 监控系统3.2 竞品广告分析 四、使用成本与配额策略五、开发者注意事项六、替…...

宝塔面板屏蔽垃圾搜索引擎蜘蛛和扫描工具的办法

首先进入宝塔面板,文件管理进入/www/server/nginx/conf目录,新建空白文件kill_bot.conf。然后将以下代码保存到当前文件中。 #禁止垃圾搜索引擎蜘蛛抓取if ($http_user_agent ~* "CheckMarkNetwork|Synapse|Nimbostratus-Bot|Dark|scraper|LMAO|Ha…...

【低成本STM32的T-BOX开发实战:高可靠的车联网解决方案】

基于STM32的车辆远程通信终端(T-BOX)开发实战:低成本高可靠的车联网解决方案 目录 引言:为什么需要T-BOX?系统总体设计:T-BOX的架构与核心功能硬件设计:STM32主控与关键模块解析 STM32F105VCT6…...

聚类算法K-means和Dbscan的对比

K-means和DBSCAN_dbscan和kmeans的区别-CSDN博客...

mysql的高可用

1. 环境准备 2台MySQL服务器(node1: 192.168.1.101,node2: 192.168.1.102)2台HAProxy Keepalived服务器(haproxy1: 192.168.1.103,haproxy2: 192.168.1.104)虚拟IP(VIP: 192.168.1.100&#x…...

vue3 elementplus tabs切换实现

Tabs 标签页 | Element Plus <template><!-- editableTabsValue 是当前tab 的 name --><el-tabsv-model"editableTabsValue"type"border-card"editableedit"handleTabsEdit"><!-- 这个是标签面板 面板数据 遍历 editableT…...

printf在c语言中代表什么(非常详细)

在C语言中&#xff0c;有三个函数可以用来向控制台&#xff08;可以理解为显示器或者屏幕&#xff09;输出数据&#xff0c;它们分别是&#xff1a; 输出函数说明用法演示puts()只能输出字符串&#xff0c;并且输出结束后会自动换行puts("C language is great");put…...

Linux梦开始的地方

1.概率 经过C语言&#xff0c;数据结构&#xff0c;C的学习我们现在要开始学习Linux的学习了。我们学习Linux是从四部分来进行的&#xff1a; 1.Linux初识&#xff0c;Linux环境&#xff0c;Linux指令&#xff0c;Linux开发环境。 2.Linux系统。 3.Linux网络 4.MySQL Lin…...

关于机器学习的实际案例

以下是一些机器学习的实际案例&#xff1a; 营销与销售领域 - 推荐引擎&#xff1a;亚马逊、网飞等网站根据用户的品味、浏览历史和购物车历史进行推荐。 - 个性化营销&#xff1a;营销人员使用机器学习联系将产品留在购物车或退出网站的用户&#xff0c;根据客户兴趣定制营销…...