Linux虚拟文件系统(1)
1 虚拟文件系统(VFS)
虚拟文件系统(Virtual File System, VFS)作为内核的子系统。,它为用户空间的应用程序提供了一个统一的文件系统接口。通过VFS,不同的文件系统可以共存于同一个操作系统中,并且应用程序不需要了解底层具体文件系统的实现细节即可访问这些文件系统。
"一切皆文件"是Linux的基本哲学之一,不仅是普通的文件,包括目录、字符设备、块设备、套接字等,都可以以文件的方式被对待。实现这一行为的基础,正是Linux的虚拟文件系统机制。
主要特点
-
抽象层:VFS作为Linux内核与实际文件系统之间的抽象层,允许不同类型的文件系统(如ext4, NTFS, NFS等)以统一的方式进行交互。
-
通用接口:它提供了一套标准的操作接口,例如打开文件(
open
)、读取文件(read
)、写入文件(write
)、关闭文件(close
)等,使得应用程序可以通过相同的API访问各种存储介质和文件系统类型。 -
支持多种文件系统:无论是本地文件系统还是网络文件系统,VFS都能处理。这包括但不限于磁盘上的文件系统(如ext4, xfs),内存文件系统(如tmpfs),以及网络文件系统(如NFS)。
2 虚拟文件系统的4个主要对象
2.1 超级块
超级块(super_block):每个文件系统都有一个超级块,包含了该文件系统的元数据信息,比如文件系统的大小、空闲块的数量等.
可以通过以下命令查看当前系统的挂载情况,从而确定有多少个超级块实例:
超级块(super_block)一般大小为1024bytes,记录的信息主要有:
- block 与inode 的总量
- 未使用与已使用的inode / block 数量
- 一个valid bit 数值,若此文件系统已被挂载,则valid bit 为0 ,若未被挂载,则valid bit 为1
- block 与inode 的大小 (block 为1, 2, 4K,inode 为128bytes 或256bytes);
- 其他各种文件系统相关信息:filesystem 的挂载时间、最近一次写入资料的时间、最近一次检验磁碟(fsck) 的时
superblock在内核的相关属性结构
struct super_block {/* 1. 链接到全局超级块链表 */struct list_head s_list; // 所有超级块链接成的全局链表/* 2. 设备标识与块大小 */kdev_t s_dev; // 设备号(如 /dev/sda1)unsigned long s_blocksize; // 文件系统块大小(字节单位)unsigned char s_blocksize_bits; // 块大小以 log2 表示(例如 1024=10)/* 3. 状态与标志 */unsigned char s_lock; // 超级块是否被锁住unsigned char s_dirt; // 是否为“脏”(是否需要写回磁盘)/* 4. 文件系统类型与操作函数 */struct file_system_type *s_type; // 指向文件系统的类型(如 ext4_fs_type)const struct super_operations *s_op; // 超级块操作函数(如 alloc_inode、write_super)const struct dquot_operations *dq_op; // 配额操作函数/* 5. 挂载标志与魔数 */unsigned long s_flags; // 挂载标志(如 MS_RDONLY, MS_NOATIME)unsigned long s_magic; // 文件系统魔数(如 EXT4_SUPER_MAGIC = 0xEF53)/* 6. 根目录项 */struct dentry *s_root; // 根目录对应的 dentry(如 / 或 /home)/* 7. 等待队列 */wait_queue_head_t s_wait; // 等待该超级块某些资源可用的进程队列/* 8. 脏 inode 和打开文件列表 */struct list_head s_dirty; // 所有脏 inode 的链表(等待同步到磁盘)struct list_head s_files; // 当前所有打开文件的链表/* 9. 关联的块设备 */struct block_device *s_bdev; // 指向底层块设备结构(如 /dev/sda1)/* 10. 挂载点链表 */struct list_head s_mounts; // 挂载到该超级块的所有 vfsmount 实例链表/* 11. 配额配置选项 */struct quota_mount_options s_dquot; // 磁盘配额相关挂载选项/* 12. 文件系统私有信息(联合体) */union {struct minix_sb_info minix_sb;struct ext2_sb_info ext2_sb;struct hpfs_sb_info hpfs_sb;struct ntfs_sb_info ntfs_sb;struct msdos_sb_info msdos_sb;struct isofs_sb_info isofs_sb;struct nfs_sb_info nfs_sb;struct sysv_sb_info sysv_sb;struct affs_sb_info affs_sb;struct ufs_sb_info ufs_sb;struct efs_sb_info efs_sb;struct shmem_sb_info shmem_sb;struct romfs_sb_info romfs_sb;struct smb_sb_info smbfs_sb;struct hfs_sb_info hfs_sb;struct adfs_sb_info adfs_sb;struct qnx4_sb_info qnx4_sb;struct bfs_sb_info bfs_sb;struct udf_sb_info udf_sb;struct ncp_sb_info ncpfs_sb;struct usbdev_sb_info usbdevfs_sb;void *generic_sbp;} u;/* 13. VFS 内部使用的同步机制 */struct semaphore s_vfs_rename_sem; // rename 操作时的互斥信号量/* 14. NFS 相关路径处理 */struct semaphore s_nfsd_free_path_sem; // NFS 导出路径的同步信号量
};
struct super_operations
是 Linux 内核中定义的一组函数指针,用于操作超级块(super_block
),它提供了对文件系统级别的各种操作接口。这些操作包括创建和销毁索引节点(inode)、读写超级块、同步数据到磁盘等,如下:
struct super_operations {// 创建一个新的索引节点(inode)。在需要创建新文件或目录时调用。struct inode *(*alloc_inode)(struct super_block *sb);// 销毁一个索引节点(inode)。当索引节点不再需要时调用。void (*destroy_inode)(struct inode *);// 从磁盘读取超级块信息并更新超级块结构体。通常在挂载文件系统时调用。void (*read_inode) (struct inode *);// 将脏的超级块信息写回到磁盘。在同步操作中使用。void (*write_inode) (struct inode *, int);// 清理超级块上的脏数据,并将其写回磁盘。在卸载文件系统时调用。void (*put_super) (struct super_block *);// 同步超级块中的所有脏数据到磁盘。用于确保数据一致性。void (*write_super) (struct super_block *);// 检查超级块是否已经被修改(脏)。返回非零值表示已修改。int (*sync_fs)(struct super_block *sb, int wait);// 更新超级块的状态。通常在改变挂载选项后调用。void (*write_super_lockfs) (struct super_block *);// 解除之前由 write_super_lockfs 加上的锁。恢复正常的文件系统操作。void (*unlockfs) (struct super_block *);// 统计文件系统的统计信息,如空闲块数、总块数等。int (*statfs) (struct dentry *, struct kstatfs *);// 重新设置文件系统的大小。对于支持动态调整大小的文件系统有用。int (*remount_fs) (struct super_block *, int *, char *);// 在清除inode时调用,允许文件系统执行一些清理工作。void (*clear_inode) (struct inode *);// 在删除inode时调用,允许文件系统执行一些额外的工作。void (*delete_inode) (struct inode *);// 显示文件系统的特定信息。主要用于调试目的。void (*show_options)(struct seq_file *, struct dentry *);// 检查文件系统是否可以被挂载。可以在挂载前验证文件系统的状态。int (*show_devname)(struct seq_file *, struct dentry *);// 显示文件系统的类型名称。int (*show_path)(struct seq_file *, struct dentry *);// 显示文件系统的UUID或其他唯一标识符。int (*show_stats)(struct seq_file *, struct dentry *);// 其他扩展功能,如加密支持等。int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
};
2.2 索引节点
- 索引节点是VFS中的核心概念,它包含内核在操作文件或目录时需要的全部信息。
- 一个索引节点代表文件系统中的一个文件(这里的文件不仅是指我们平时所认为的普通的文件,还包括目录,特殊设备文件等等)。
- 索引节点和超级块一样是实际存储在磁盘上的,当被应用程序访问到时才会在内存中创建。
文件或目录的inode编号,如下:
stat 命令提供了更详细的文件或文件系统状态信息,包括inode编号、权限、大小等。
检查文件系统的inode使用情况
1.主要记录文件的属性以及该文件实际数据是放置在哪些block中,它记录的信息至少有这些:
- 大小、真正内容的block号码(一个或多个)
- 访问模式(read/write/excute)
- 拥有者与群组(owner/group)
- 各种时间:建立或状态改变的时间、最近一次的读取时间、最近修改的时间
没有文件名!文件名在目录的block中!
- 一个文件占用一个 inode,每个inode有编号
- 注意,这里的文件不单单是普通文件,目录文件也就是文件夹其实也是一个文件
- inode 的数量与大小在格式化时就已经固定了,每个inode 大小均固定为128 bytes (新的ext4 与xfs 可设定到256 bytes)
- 文件系统能够建立的文件数量与inode 的数量有关,存在空间还够但inode不够的情况
- 系统读取文件时需要先找到inode,并分析inode 所记录的权限与使用者是否符合,若符合才能够开始实际读取 block 的内容
- inode 要记录的资料非常多,但偏偏又只有128bytes , 而inode 记录一个block 号码要花掉4byte ,假设我一个文件有400MB 且每个block 为4K 时, 那么至少也要十万条block 号码的记录!inode 哪有这么多空间来存储?为此我们的系统很聪明的将inode 记录block 号码的区域定义为12个直接,一个间接, 一个双间接与一个三间接记录区,见后续章节。
inode在内核的相关属性结构
struct inode {/* 1. 列表指针:用于管理inode */struct list_head i_hash; // 哈希链表,用于快速查找inodestruct list_head i_list; // inode状态链表(如脏inode链表)struct list_head i_dentry; // 指向与该inode关联的所有dentry/* 2. 脏缓冲区列表 */struct list_head i_dirty_buffers; // 脏缓冲区链表,用于回写操作/* 3. 索引节点编号和引用计数 */unsigned long i_ino; // inode编号,唯一标识一个inodeatomic_t i_count; // 引用计数,表示当前有多少用户正在使用这个inodekdev_t i_dev; // 设备号,表示该inode所在的设备/* 4. 文件权限和其他属性 */umode_t i_mode; // 文件模式(权限)nlink_t i_nlink; // 链接数,即有多少硬链接指向此inodeuid_t i_uid; // 用户IDgid_t i_gid; // 组IDkdev_t i_rdev; // 如果是特殊文件(字符设备或块设备),则存储其设备号loff_t i_size; // 文件大小(字节数)/* 5. 时间戳 */time_t i_atime; // 最后访问时间time_t i_mtime; // 最后修改时间time_t i_ctime; // 状态改变时间(如权限、所有者等)/* 6. 块大小和块数 */unsigned long i_blksize; // 逻辑块大小(通常为文件系统的块大小)unsigned long i_blocks; // 文件占用的实际块数/* 7. 版本控制和同步 */unsigned long i_version; // 版本号,用于检测文件变化struct semaphore i_sem; // 信号量,用于保护对inode的并发访问struct semaphore i_zombie; // 处理僵尸inode时使用的信号量/* 8. 操作函数指针 */struct inode_operations *i_op; // inode操作函数集struct file_operations *i_fop; // 文件操作函数集(默认文件操作)/* 9. 超级块和等待队列 */struct super_block *i_sb; // 指向该inode所属的超级块wait_queue_head_t i_wait; // 等待队列头,用于进程等待inode可用/* 10. 文件锁和其他信息 */struct file_lock *i_flock; // 文件锁信息struct address_space *i_mapping;// 映射到地址空间的信息struct address_space i_data; // 地址空间数据(如页缓存)struct dquot *i_dquot[MAXQUOTAS]; // 磁盘配额信息/* 11. 特殊文件信息 */struct pipe_inode_info *i_pipe; // 如果是管道文件,则存储相关信息struct block_device *i_bdev; // 如果是块设备,则存储相关信息/* 12. 目录通知 */unsigned long i_dnotify_mask; // 目录通知事件掩码struct dnotify_struct *i_dnotify; // 目录通知结构/* 13. 状态标志 */unsigned long i_state; // inode的状态标志(如脏、锁定等)unsigned int i_flags; // inode标志(如不可变、追加等)unsigned char i_sock; // 是否为socket/* 14. 写计数和其他标志 */atomic_t i_writecount; // 写计数,表示当前有多少进程正在写入该inodeunsigned int i_attr_flags; // 扩展属性标志__u32 i_generation; // 生成号,用于NFS等需要版本控制的场景/* 15. 文件系统特定信息 */union {struct minix_inode_info minix_i;struct ext2_inode_info ext2_i;struct hpfs_inode_info hpfs_i;struct ntfs_inode_info ntfs_i;struct msdos_inode_info msdos_i;struct umsdos_inode_info umsdos_i;struct iso_inode_info isofs_i;struct nfs_inode_info nfs_i;struct sysv_inode_info sysv_i;struct affs_inode_info affs_i;struct ufs_inode_info ufs_i;struct efs_inode_info efs_i;struct romfs_inode_info romfs_i;struct shmem_inode_info shmem_i;struct coda_inode_info coda_i;struct smb_inode_info smbfs_i;struct hfs_inode_info hfs_i;struct adfs_inode_info adfs_i;struct qnx4_inode_info qnx4_i;struct bfs_inode_info bfs_i;struct udf_inode_info udf_i;struct ncp_inode_info ncpfs_i;struct proc_inode_info proc_i;struct socket socket_i;struct usbdev_inode_info usbdev_i;void *generic_ip;} u; // 文件系统特定的数据结构
};
struct inode_operations
用于操作索引节点(inode)。每个文件系统都需要实现这些函数以支持基本的文件操作。
下面是对 struct inode_operations
结构体的具体内容及其字段的详细注释:
struct inode_operations {// 创建一个新的索引节点(如创建新文件或目录)struct dentry * (*create) (struct inode *,struct dentry *, umode_t, bool);// 查找一个已存在的索引节点(如打开已有文件)struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);// 链接一个已有的索引节点(如创建硬链接)int (*link) (struct dentry *,struct inode *,struct dentry *);// 删除一个硬链接(减少链接计数)int (*unlink) (struct inode *,struct dentry *);// 创建符号链接int (*symlink) (struct inode *,struct dentry *,const char *);// 创建一个指向已有索引节点的新名称(重命名)int (*rename) (struct inode *, struct dentry *,struct inode *, struct dentry *, unsigned int);// 删除一个符号链接int (*readlink) (struct dentry *, char __user *,int);// 获取符号链接的目标路径const char * (*get_link) (struct dentry *, struct inode *, struct delayed_work *);// 文件权限检查int (*permission) (struct user_namespace *, struct inode *, int);// 释放inode资源void (*free_inode) (struct inode *);// 在删除inode前调用,允许执行清理工作void (*destroy_inode)(struct inode *);// 读取目录项int (*read_inode) (struct inode *);// 写入inode信息到磁盘int (*write_inode) (struct inode *, struct writeback_control *wbc);// 截断文件大小int (*truncate) (struct inode *);// 设置文件权限和所有者int (*setattr) (struct dentry *, struct iattr *);// 获取文件属性int (*getattr) (const struct path *, struct kstat *, u32, unsigned int);// 设置扩展属性int (*setxattr) (struct dentry *, const char *,const void *, size_t, int);// 获取扩展属性ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);// 列出扩展属性ssize_t (*listxattr) (struct dentry *, char *, size_t);// 移除扩展属性int (*removexattr) (struct dentry *, const char *);// 更新时间戳int (*update_time)(struct inode *, struct timespec *, int);// 填充统计信息int (*atomic_open)(struct inode *, struct dentry *, struct file *,unsigned open_flag, umode_t create_mode);// 其他可能的操作int (*tmpfile) (struct inode *, struct dentry *, umode_t);
};
struct file_operations 用于处理对文件的各种操作请求。这些操作包括打开、读取、写入、关闭文件等。每个文件系统或设备驱动程序都需要实现这个结构体的部分或全部成员函数,以便与虚拟文件系统(VFS)层进行交互。
以下是 struct file_operations
结构体的具体内容及其字段的详细注释:
struct file_operations {// 打开文件时调用struct module *owner; // 通常设置为 THIS_MODULE,表示该操作集属于哪个模块loff_t (*llseek) (struct file *, loff_t, int); // 改变文件当前偏移量// 从文件中读取数据ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);// 向文件中写入数据ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);// 读取和写入文件(可用于同时执行读和写的操作)ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);// 开始内存映射文件int (*mmap) (struct file *, struct vm_area_struct *);// 打开文件时调用int (*open) (struct inode *, struct file *);// 关闭文件时调用int (*flush) (struct file *, fl_owner_t id);// 释放文件结构体时调用int (*release) (struct inode *, struct file *);// 文件被锁定时调用int (*fsync) (struct file *, loff_t, loff_t, int datasync);// 异步I/O支持int (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);int (*aio_write)(struct kiocb *, const struct iovec *, unsigned long, loff_t);// 检查文件访问权限int (*check_flags)(int);// 文件截断int (*ftruncate) (struct inode *, loff_t);// 锁定文件long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);long (*compat_ioctl) (struct file *, unsigned int, unsigned long);// 发送信号到进程int (*fasync) (int, struct file *, int);// 锁定文件int (*lock) (struct file *, int, struct file_lock *);// 轮询函数,用于等待某些事件发生(如可读、可写)unsigned int (*poll) (struct file *, struct poll_table_struct *);// 使用mmap将文件映射到内存时调用int (*mmap_capabilities) (struct file *);// 用于直接I/Ossize_t (*direct_IO)(struct kiocb *, struct iov_iter *, loff_t offset);// 用于扩展属性int (*setlease)(struct file *, long, struct file_lock **, void **priv);long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len);
};
相关文章:
Linux虚拟文件系统(1)
1 虚拟文件系统(VFS) 虚拟文件系统(Virtual File System, VFS)作为内核的子系统。,它为用户空间的应用程序提供了一个统一的文件系统接口。通过VFS,不同的文件系统可以共存于同一个操作系统中,…...
目标检测评估指标mAP详解:原理与代码
目标检测评估指标mAP详解:原理与代码 目标检测评估指标mAP详解:原理与代码一、前言:为什么需要mAP?二、核心概念解析2.1 PR曲线(Precision-Recall Curve)2.2 AP计算原理 三、代码实现详解3.1 核心函数ap_pe…...
Linux干货(六)
前言 从B站黑马程序员Linux课程摘选的学习干货,新手友好!若有侵权,会第一时间处理。 目录 前言 1.环境变量 1.环境变量的定义 2.env命令的作用 3.$符号的作用 4.PATH的定义和作用 5.修改环境变量的方法 1.临时生效 2.永久生效 2.…...
字符串相乘(43)
43. 字符串相乘 - 力扣(LeetCode) 解法: class Solution { public:string multiply(string num1, string num2) {string res "0";for (int i 0; i < num2.size(); i) {string str multiplyOneNum(num1, num2[num2.size() -…...
【Vue篇】数据秘语:从watch源码看响应式宇宙的蝴蝶效应
目录 引言 一、watch侦听器(监视器) 1.作用: 2.语法: 3.侦听器代码准备 4. 配置项 5.总结 二、翻译案例-代码实现 1.需求 2.代码实现 三、综合案例——购物车案例 1. 需求 2. 代码 引言 💬 欢迎讨论&#…...
esp32课设记录(二)lcd屏显示文字与照片
取模软件链接: 链接: 百度网盘 请输入提取码 提取码: 1234 课设要求如图所示,因此需要在esp32显示文字和照片。在上个文章中我已经写了按键相关内容。这篇主要描述怎么显示文字和照片。我使用的是ESP-IDF库。 本项目使用的是基于ST7789驱动芯片的LCD屏幕…...
Open CASCADE学习|几何体切片处理:OpenMP与OSD_Parallel并行方案深度解析
在三维建模与仿真领域,几何体切片处理是CAE前处理、3D打印路径规划、医学影像分析等场景的关键技术。其核心目标是将三维模型沿特定方向离散为二维截面集合,便于后续分析或制造。OpenCASCADE作为开源几何内核,提供高效的布尔运算与几何算法&a…...
【Android】从Choreographer到UI渲染(二)
【Android】从Choreographer到UI渲染(二) Google 在 2012 年推出的 Project Butter(黄油计划)是 Android 系统发展史上的重要里程碑,旨在解决长期存在的 UI 卡顿、响应延迟等问题,提升用户体验。 在 Androi…...
板凳-------Mysql cookbook学习 (三)
1.22 使长输出行更具可读性 mysql> show full columns from limbs; ------------------------------------------------------------------------------------------------------------- | Field | Type | Collation | Null | Key | Default | Extra | Pri…...
济南国网数字化培训班学习笔记-第三组-2-电力通信光缆网认知
电力通信光缆网认知 光缆网架构现状 基础底座 电路系统是高度复杂,实时性、安全性、可靠性要求极高的巨系统,必须建设专用通信网 相伴相生 电力系统是由发电、输电、变电、配电、用电等一次设施,及保障其正常运行的保护、自动化、通信等…...
黑灰产业链深度解析
黑灰产业链深度解析 大家好,欢迎来到「黑产档案」。本频道专注于反诈教育宣传,通过深度拆解黑灰产业链的运作逻辑,帮助公众识别骗局、规避风险。本节课将聚焦产业链的核心环节,揭示其背后的灰色生态。 一、黑灰产的定义与范畴 要…...
golang选项设计模式
选项设计模式 有时候一个函数会有很多参数,为了方便函数的使用,我们会给希望给一些参数设定默认值,调用时只需要传与默认值不同的参数即可,类似于 python 里面的默认参数和字典参数,虽然 golang 里面既没有默认参数也…...
方案精读:104页DeepSeek金融银行核算流程场景部署建设方案【附全文阅读】
DeepSeek,金融银行核算流程的革新方案! 这份方案专为金融银行从业者打造,旨在解决传统核算流程的难题。当下,金融银行核算面临效率低、错误率高、合规压力大等挑战,DeepSeek 方案正是应对之策。 该方案运用人工智能和大数据技术,实现数据采集、清洗自动化,智能核算对账,…...
【MySQL】02.数据库基础
1. 数据库的引入 之前存储数据用文件就可以了,为什么还要弄个数据库? 文件存储存在安全性问题,文件不利于数据查询和管理,文件不利于存储海量数据,文件在程序中控制不方便。而为了解决上述问题,专家们设计出更加利于…...
STM32项目实战:ADC采集
STM32F103C8T6的ADC配置。PB0对应的是ADC1的通道8。在标准库中,需要初始化ADC,设置通道,时钟,转换模式等。需要配置GPIOB的第0脚为模拟输入模式,然后配置ADC1的通道8,设置转换周期和触发方式。 接下来是I2C…...
《AI语音模型:MiniMax Speech-02》
开场:AI 语音界的震撼弹 在 AI 语音技术的激烈竞争赛道上,MiniMax Speech - 02 的出现宛如一颗震撼弹,瞬间引爆了整个行业。不久前,一则消息在全球 AI 领域引起轩然大波:MiniMax 的新一代语音大模型 Speech - 02&#…...
基于LabVIEW的双音多频系统设计
目录 1 系统设计概述 双音多频(Dual-Tone Multi-Frequency, DTMF)信号是一种广泛应用于电话系统中的音频信号,通过不同的频率组合表示不同的按键。每个按键对应两个频率,一个低频和一个高频,共同组成独特的信号。在虚拟仪器技术快速发展的背景下,利用LabVIEW等图形化编程…...
快速生成角色背景设定:基于Next.js的AI辅助工具开发实践
引言 在游戏开发、小说创作和角色扮演(RP)中,角色背景设定(Headcanon)的构建往往耗时耗力。传统方法依赖手动编写,容易陷入思维定式。本文将分享如何利用Next.js和Tailwind CSS开发一个高效的AI角色设定生…...
轻量级视频剪辑方案:FFmpeg图形化工具体验
FFmpeg小白助手是基于开源FFmpeg开发的本地化视频处理软件,采用绿色免安装设计,解压后即可直接运行。该工具主要面向普通用户的日常音视频处理需求,通过简洁的图形界面降低了FFmpeg的使用门槛。 功能特性 基础编辑功能 格式转换:…...
主成分分析的应用之sklearn.decomposition模块的PCA函数
主成分分析的应用之sklearn.decomposition模块的PCA函数 一、模型建立整体步骤 二、数据 2297.86 589.62 474.74 164.19 290.91 626.21 295.20 199.03 2262.19 571.69 461.25 185.90 337.83 604.78 354.66 198.96 2303.29 589.99 516.21 236.55 403.92 730.05 438.41 225.80 …...
Java基于数组的阻塞队列实现详解
在多线程编程中,阻塞队列是一种非常有用的工具,它可以在生产者和消费者之间提供一个缓冲区,使得生产者可以往队列中添加数据,而消费者可以从队列中取出数据。当队列满时,生产者会被阻塞直到有空间可用;当队…...
ngx_http_random_index_module 模块概述
一、使用场景 随机内容分发 当同一目录下存放多份等价内容(如多张轮播图、不同版本静态页面等)时,可通过随机索引实现负载均衡或流量分散。A/B 测试 通过目录请求自动随机分配用户到不同测试组,无需后端逻辑参与。动态“首页”选…...
你引入的lodash充分利用了吗?
#开发中,发现自己只有cloneDeep的时候才想起来用这个库的便利,搜索了项目内代码,发现大家基本也是这样,其实我们错过了很多好东西# cloneDeep 深拷贝 var objects [{ a: 1 }, { b: 2 }];var deep _.cloneDeep(objects); conso…...
Python爬虫基础
本篇内容中,我们主要分享一些爬虫的前置知识,主要知识点有: 爬虫的概念和作用爬虫的流程【重要】http相关的复习 http和https概念和区别浏览器访问一个网址的过程爬虫中常用的请求头、响应头常见的响应状态码 浏览器自带开发者工具的使用 爬…...
飞帆控件:on_post_get 接口配置
在网页中写一个接口是很基础的要求。 今天我们介绍一个工具,不用写代码,配置即可。 先上链接: on_post_gethttps://fvi.cn/798来看看控件的配置: 使用这个控件,在网页中写 post/get 接口可以告别代码。或许能做到初…...
C++笔试题(金山科技新未来训练营):
题目分布: 17道单选(每题3分)3道多选题(全对3分,部分对1分)2道编程题(每一道20分)。 不过题目太多,就记得一部分了: 单选题: static变量的初始…...
Selenium-Java版(css表达式)
css表达式 前言 根据 tag名、id、class 选择元素 tag名 #id .class 选择子元素和后代元素 定义 语法 根据属性选择 验证CSS Selector 组选择 按次序选择子节点 父元素的第n个子节点 父元素的倒数第n个子节点 父元素的第几个某类型的子节点 父元素的…...
19. 结合Selenium和YAML对页面实例化PO对象改造
19. 结合Selenium和YAML对页面实例化PO对象改造 一、架构升级核心思路 1.1 改造核心目标 # 原始PO模式:显式定义元素定位 username (id, ctl00_MainContent_username)# 改造后PO模式:动态属性访问 self.username.send_keys(Tester) # 自动触发元素定…...
MySQL——5、基本查询
表的增删改查 1、Create1.1、单行数据全列插入1.2、多行数据指定列插入1.3、插入否则更新1.4、替换 2、Retrieve2.1、select列2.2、where条件2.3、结果排序2.4、筛选分页结果 3、Update4、Delete4.1、删除数据4.2、截断表 5、插入查询结果6、聚合函数7、group by子句的使用8、实…...
ngx_http_referer_module 模块概述
一、使用场景 防盗链 仅允许本站或特定域名的页面直接引用图片、视频等资源,拒绝第三方网站直接嵌入。流量控制 阻止来自社交媒体、搜索引擎或未知来源的大量自动化抓取。安全审计 简易记录并过滤可疑 Referer,以减少非法请求。 注意 Referer 头可被伪造…...
Go语言--语法基础5--基本数据类型--类型转换
Go 编程语言中 if 条件语句的语法如下: 1、基本形式 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } If 在布尔表达式为 true 时,其后紧跟的语句块执行,如果为 false 则 不执行。 package main import "fmt" …...
用golang实现二叉搜索树(BST)
目录 一、概念、性质二、二叉搜索树的实现1. 结构2. 查找3. 插入4. 删除5. 中序遍历 中序前驱/后继结点 一、概念、性质 二叉搜索树(Binary Search Tree),简写BST,又称为二叉查找树 它满足: 空树是一颗二叉搜索树对…...
基于FPGA的电子万年历系统开发,包含各模块testbench
目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于FPGA的电子万年历系统开发,包含各模块testbench。主要包含以下核心模块: 时钟控制模块:提供系统基准时钟和计时功能。 日历计算模块:…...
上位机知识篇---Web
文章目录 前言 前言 本文简单介绍了Web。...
2025 ISCC 练武赛Pwn-wp(含附件)
前言 去年个人赛报名了忘记打了(笑), 所以这应该算是我第一次参加ISCC, 体验也是非常非常非常非常的cha(第四声)!!! 主办方也是非常幽默,pwn和web都是公用容器,那web最后都被当成玩具玩坏了 下面是这次练武题的pwn所有附件 通过网盘分享的文件…...
LeetCode Hot100刷题——除自身以外数组的乘积
238. 除自身以外数组的乘积 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&a…...
IDEA - Windows IDEA 代码块展开与折叠(基础折叠操作、高级折叠操作)
一、基础折叠操作 折叠当前代码块:Ctrl - # 操作方式按下 【Ctrl】 键,再按下 【-】 键展开当前代码块:Ctrl # 操作方式按下 【Ctrl】 键,再按下 【】 键折叠所有代码块:Ctrl Shift - # 操作方式按下 【Ctrl】…...
javaSE.Map
Map存储映射关系。键值对。key-value 左边值映射着右边的值,左边相当于钥匙,开到右边的门获取得到信息。 get👇put 是否存在该key👇containsKey() map.values👇 entrySet👇 entrySet()获取map中所有的键…...
Python Requests库完全指南:从入门到精通
引言 在Python的生态系统中,requests库以其简洁优雅的API设计和强大的功能,成为HTTP请求处理领域的标杆工具。无论是数据爬虫开发、API接口调用,还是自动化测试场景,requests都能将复杂的网络交互简化为几行可读性极高的代码。相…...
1.QPushBotton 以及 对象树
目录 1. 创建第一个Qt程序 1.1 初始化设置 🍐 选择存储位置 🍊 Kit 🍋 类信息 🍌 项目管理 1.2 代码 🍉 main.cpp 🍇widget.h 🍓 widget.cpp 1.3 .pro文件 🍈 常见模块…...
GO语言语法---For循环、break、continue
文章目录 1. 基本for循环(类似其他语言的while)2. 经典for循环(初始化;条件;后续操作)3. 无限循环4. 使用break和continue5 . 带标签的循环(可用于break/continue指定循环)1、break带标签2、continue带标签…...
网络编程-select(二)
一、I/O多路复用 1、为什么要多路复用 之前开启多线程能实时接收数据,并且也不是一次性连接服务。但毕竟是一请求一连接,每有一个客户端向服务端发起请求,就会创建一个线程,当请求达到上千上万,就会创建上千上万的线…...
2025年PMP 学习十九 第12章 项目采购管理
2025年PMP 学习十九 第12章 项目采购管理 序号过程过程组1规划采购管理规划2实施采购执行3控制采购监控4合同管理- 文章目录 2025年PMP 学习十九 第12章 项目采购管理12 项目采购管理建立战略合作伙伴关系的意义:细化采购步骤 12.1 规划采购管理1. **定义与作用**2…...
10.11 LangGraph多角色Agent开发实战:生产级AI系统架构与性能优化全解析
LangGraph 项目:High-level API for Multi-actor Agents 关键词:LangGraph 多角色 Agent, 状态管理, 持久化机制, 工作流编排, 生产级 AI 系统 1. LangGraph 设计哲学与架构演进 LangGraph 是 LangChain 生态中首个面向 多角色协作 Agent 的高阶 API 框架,其核心设计思想可…...
计算机网络概要
⽹络相关基础知识 协议 两设备之间使⽤光电信号传输信息数据 要想传递不同信息 那么⼆者ᳵ就需要约定好的数据格式 层 封装 继承 多态是计算机的性质 它们⽀持了软硬件分层的实现 同层协议可以ᳵ接通信 同层协议ᳵ不直接通信 是各⾃调⽤下层提供的结构能⼒完成通信 分层…...
Visual Studio已更新为17.14+集成deepseek实现高效编程
01 Visual Studio 2022 v17.14。 此更新侧重于全面提供出色的开发人员体验,侧重于稳定性和安全性以及 AI 改进。 02 GPT-4o代码完成模式 我们非常高兴地宣布,新的 GPT-4o Copilot 代码完成模型现已在 Visual Studio 17.14 中为 GitHub Copilot 用户…...
axios的基本使用
1. Axios概述 Axios 是一个基于 Promise 的 HTTP 客户端库,专为浏览器和 Node.js 设计,用来发送AJAX请求。可以通过npm install -g axios安装axios库。Axios有以下特征: 跨平台兼容性:同一套代码可运行于浏览器和 Node.js。在浏…...
【第三十六周】LoRA 微调方法
LoRA 摘要Abstract文章信息引言方法LoRA的原理LoRA在Transformer中的应用补充其他细节 实验与分析LoRA的使用论文实验结果分析 总结 摘要 本篇博客介绍了LoRA(Low-Rank Adaptation),这是一种面向大规模预训练语言模型的参数高效微调方法&…...
fcQCA模糊集定性比较分析法-学习笔记
模糊集定性比较分析(fsQCA,Fuzzy-set Qualitative Comparative Analysis) 是一种结合了定性和定量元素的研究方法,用于分析中小样本数据中的复杂因果关系。 1. 理解基础概念 QCA的核心思想: 基于集合论和布尔代数&a…...
基于WebRTC的实时语音对话系统:从语音识别到AI回复
基于WebRTC的实时语音对话系统:从语音识别到AI回复 在当今数字化时代,实时语音交互已成为人机界面的重要组成部分。本文将深入探讨一个基于WebRTC技术的实时语音对话系统,该系统集成了语音识别(ASR)、大语言模型(LLM)和语音合成(TTS)技术&am…...