【Linux内核系列】:文件系统
🔥 本文专栏:Linux
🌸作者主页:努力努力再努力wz
★★★ 本文前置知识:
文件系统初识
那么在我们此前关于文件的学习中,我们学习的都是进程与打开的文件之间的关系,以及打开的文件如何进行管理,那么我们文件有打开的文件,那么同样也就相应有未被打开的文件,所以本篇文章将围绕为未被打开的文件,来揭开它神秘的面纱,看看我们操作系统是如何管理未被打开的文件的,那么废话不多说,就让我们进入正文的学习!
1.引入
那么我们知道我们的文件的元数据是存储在外部设备当中,所以要认识未被打开的文件,那么第一步我们得先认识存储该文件的介质或者说设备,而目前我们存储的文件的外部设备就是SSD固态硬盘以及HDD机械硬盘,那么这两种存储设备各有各的优势,那么目前我们大众接触到最多的也就是固态硬盘SSD,那么它内部构造是由晶体管所构成,而我们的文件本质就是一个二进制序列,那么SSD就通过内部的晶体管的电子的状态来表示二进制的0和1,那么通过电信号来访问各个晶体管的电子的状态从而获得二进制的数据,所以它的访问速度是极其快速,但是由于其应用场景实在家用以及办公用的便携式笔记本电脑当中,意味着我们的SSD固态硬盘所占的体积不能过大,所以通过集成电路的技术使其具有较小的体积并且同时保证了其不错的容量,那么必定意味着SSD的制作成本相比于机械磁盘就要高昂一点
那么对于机械磁盘HDD来说,那么它的应用场景则是一些不需要移动的笨重的台式机或者互联网公司的服务器后端数据的存储设备,而对于HDD来说,它的优点就是容量大,并且造价成本便宜,所以这就是为什么大型的互联网公司的服务器后端选择磁盘作为数据的存储设备,但是由于其是机械运动来定位数据,那么必然其访问的效率不如SSD固态硬盘,并且其不能够应用在便携式电脑当中,但是由于HDD在互联网公司的广泛引用,鉴于其重要性,所以我们今天便要着重来研究我们的磁盘的硬件结构
2.磁盘的物理结构以及原理
那么我们的磁盘是由盘片以及磁头以及高转速的马达等部件所构成,那么在这些构成磁盘的部件当中,其中最为重要的那便是磁头与盘片,磁头则是用来定位我们在磁盘当中存储的数据,而我们的在磁盘中存储的所有数据则是保存在盘片上,所以一个磁盘的容量就由盘片的数量以及盘片的存储密度等所决定。
磁盘的盘片有两面,盘片的两面分别有一层磁性的物质,那么我们知道我们的文件的各种元数据的最终形态其实就是一个二进制序列,而二进制序列无非就是由0和1所构成,所以我们如何在盘片上表示出二进制的0和1呢?
那么盘片表面上的磁性物质,我们可以看成有数十亿甚至百亿的磁性颗粒所组成,那么其中对于这每一个磁性的颗粒来说,那么它是具有磁性的,那么一旦具有磁性,那么它便具有特定的磁级指向南或者北,所以我们就可以根据每一个颗粒该磁极的指向的两个状态来分别表示二进制的0和1,那么具体的实现的途径,则是我们磁头通过放电会在其周围产生一个磁场,那么利用该磁场来磁化磁性颗粒使其产生特定的磁极,从而写入二进制序列,那么这就是磁盘写入数据的一个原理
而读取数据则是根据我们的磁头感受到读取位置的磁场变化从而磁生电,转换成电信号,那么利用该电信号得到特定的二进制序列,那么这就是利用我们高中物理的电磁学的原理
那么我们知道我们的数据是存储在我们的磁盘的盘片上,那么我们对于磁盘读取则是依靠磁头以及盘片的机械运动来定位数据的,那么我们磁盘的读取速度的效率则取决于该磁盘定位速度的机械运动的快慢,那么读取越快意味着磁盘定位一个数据所做的机械运动越少,那么我们希望磁盘所做的机械运动尽量的少,那么我们就需要将我们一个文件的数据集合尽可能存放在磁盘的盘片的相邻的物理位置处,这样就能够减少机械的运动了
那么我们知道了如何在磁盘中存储数据,那么我们要在磁盘中读取我们需要的目标数据那么肯定就得有该目标数据在我们的磁盘中的具体位置,所以为了表示一个数据在磁盘中的具体位置,那么我们此时便引入了一个磁道的概念
那么我们对于一个盘片来说,那么它的形状是一个圆形,那么我们以该盘片的中心为圆心,然后往外划分一圈一圈不同的半径的圆,那么该圆的圆弧就是磁道,其中每一个相邻的磁道之间的空间,我们还可以在进行进一步的划分,我们将圆心与每一个不同半径上的圆的圆弧处上的点形成一条条连线,那么该连线将我们的相邻两个磁道之间会划分成一个一个的扇形区域,那么该扇形区域区域我们称之为扇区,那么它就是我们磁盘存储数据的一个最基本单元,那么一般我们磁盘不只有一个盘片,那么每一个盘片都有两个盘面,那么每一面都能够存储数据,那么我们每一个盘面都对应有一个磁头用来定位,其中每一个盘面的划分磁道的数量是相同的,并且对于同一个盘片来说,每个相邻磁道之间的扇区的数量也是一致的,而我们知道越靠近外侧,那么相邻磁道之间的空隙也就越大,越靠近圆心位置处,相邻磁道之间的空隙越小,所以为了达到每一个相邻磁道之间的扇区数量相等,那么我们每一个磁道之间的划分的疏密以及磁道之间的存储密度就不同
所以我们要定位一个扇区的话,那么我们首先磁头就得来回摆动,定位确定是在哪个磁道上,然后我们的盘片通过高速马达的转轴的带动在转动定位到目标扇区
而我们知道我们的盘片是高速转动并且磁头也在摆动,那么也许有的小伙伴就有疑问,那么万一我的磁头刮花了盘片怎么办,盘片上存储着各种数据,那么刮花了岂不是造成了数据的缺失,那么注意虽然看起来磁头是和盘片是挨着的,但是他们其实并没有接触,他们中间有一个间隙,那么一旦盘片高速转动,那么中间的空气会托举着磁头,使其悬浮,应用了空气动力学的原理,所以我们的磁盘的工艺设计其实是非常巧妙的!并且磁盘内部不能有灰尘,一旦有了灰尘,那么灰尘是个颗粒状的固体,那么随着盘片的高速转动,那么其会刮花盘片,所以博主在这里警惕各位读者,如果自己好奇来拆开磁盘来研究,那么对不起,你的磁盘就报废了
而我们知道盘片之间是沿着一个转轴来垂直摆放的,那么不同盘面上的相同半径的磁道在立体的空间当中的集合就称之为一个柱面,所以我们定位,我们只需要确定三个坐标即可,即使它在对应哪个磁头,哪个磁道以及哪个扇区,那么这三个坐标我们也要一个专业术语就是CHS位置
3.磁盘的逻辑结构
那么我们知道磁盘的物理构造之后,那么我们在操作系统层面上怎么来理解描述磁盘这样的物理结构呢
那么我们知道有一个叫做磁带的东西,想必各位读者在小学的时候播放英语教材会用到,那么我们一圈一圈弯曲的磁带,那么我们可以将其整体拉直,那么其磁带上的所有数据就是按照这个拉直过后的磁带呈线性排列
而同理这里对于我们的磁盘来说,我们不同盘面上的磁道就可以理解为一圈一圈的磁带,那么我们也可以将其给拉直,那么我们磁盘上所有的数据就可以按照一个一维的线性数组来表示,那么为了区分磁盘上的不同的扇区,那么我们会给扇区分配一个唯一的编号,那么我们这个一维数组中的每一个元素就是一个扇区,那么该扇区的数组下标就是该扇区的编号,也就是LAB地址,而我们要将扇区的逻辑结构的编号转换成实际物理层面上的坐标,那么也就是确定该扇区的磁头以及磁道和磁道的第几个扇区的话
那么现在有了扇区的编号,那么如何来转换呢?
那么假设每一个盘面上有m个扇区,每个盘面有k个磁道,每个磁道有q个扇区,假设此时我们的扇区的数组下标为i,那么首先确定其在哪个盘面上,那么我们就可以利用公式:
L=i/m
H=i%m
那么如果余数H不为0的话,那么意味着当前处于第L+1盘面处,接着在计算所处的磁道:
O=H/(k*q)
P=H%(k*q)
余数P不为0的话,那么意味着当前处于该盘面的第O+1磁道处,而P就是该磁道的第P个扇区位置
那么我们就可以根据该公式来实现逻辑地址到物理地址的转换,那么我们获取到地址之后,CPU会交给磁盘的寄存器,那么磁盘有4个寄存器,分别是命令寄存器以及地址寄存器和数据寄存器和数据寄存器以及状态寄存器,它们4个的作用就是分别用来记录当前是往磁盘进行读还是写和一个读写的地址以及写入的数据和以及当前写入是否成功
4.如何管理未被打开的文件
那么我们知道了我们操作系统已经有一个逻辑结构也就是一维的线性数组来表示我们整个磁盘中的数据也就是所有扇区,但是我们的扇区的存储的数据量的大小通常是512个字节,那么我们扇区是磁盘的基本存储单元,而我们上文就说过磁盘访问的效率取决于机械运动的次数,况且我们现在的一个文件动不动就是几个甚至上百个GB,那么我们以扇区为单位一次一次的读取的话,那么效率太慢了
所以我们的操作系统以及其采取的文件系统就对此有所优化,那么我们知道此前我们整个文件的逻辑结构是一个一维的线性数组,那么此时对于磁盘访问一个数据的基本单位不再是一个扇区,而是几个扇区的集合作为该文件系统的存储数据的基本单位也称之为逻辑块,比如8个扇区也就是4kb的数据量,那么这样就能提升访问效率,那么原本磁盘的逻辑结构此时在该文件系统的新的视角下便有了不同,那么该一维的线性数组的长度没有发生变化,但是其元素不在是之前的扇区,而是一个一个逻辑块,那么该逻辑块就是由几个扇区所组成,那么以前该一维的线性数组的元素个数假设是1000个,那么现在在该文件系统下比如EXT4,那么逻辑块是由8个扇区所组成,那么个数意味着就是250个,那么每一个逻辑块就有了新的编号也就是数组的下标
而我们的磁盘的容量极大,可以达到800GB甚至1TB,那么管理这么庞大的数据,那么我们操作系统采取的管理策略就是分区
那么按照不同的文件系统,那么可能将这800个G或者1TB的数据给划分成不同的区,那么假设以EXT4文件系统为例,那么其会划分成4个区,那么每一个区此时的容量就是200个G,但是即使划分成不同的区,那么管理的数据量可能还是极大,所以对于每一个区我们又进行·更细致的划分,将其划分成了不同的组,那么我们管理好这整个文件系统,就是管理好这每一个组以及每一个区即可
那么其中对于这每一个分区来说,那么操作系统管理的方式就是我们再熟悉不过的先描述,再组织了,那么它会为其定义一个struct partition结构体,那么每一个结构体记录了每一个区的起始位置以及结束位置和该区的分组的数量等等属性,其中第一个分区的开头会有一个boot block分组,那么该分组就是记录了操作系统开机的有关信息,并且其他区也有该分组的备份
而对于每一个区的组来说,那么它也有对应的一个结构体来描述,其中就包含超级块以及块表和innode表以及数据块等
// 示例结构体定义,用于描述文件系统中的一个区组
struct FileSystemGroup {// 超级块(或超级段)struct SuperBlock {int magicNumber; // 文件系统魔数,用于识别文件系统类型int blockSize; // 逻辑块大小(字节)int totalBlocks; // 区组内总逻辑块数int freeBlocks; // 区组内空闲逻辑块数int totalInodes; // 区组内总inode数int freeInodes; // 区组内空闲inode数// 其他元数据...} superBlock;// 块表(位图)// 假设每个位代表一个逻辑块,1表示已使用,0表示空闲// 这里简化为一个数组表示,实际中可能使用更紧凑的位图存储unsigned char blockBitmap[/* 根据区组大小动态分配 */];// inode表// 每个inode对应一个文件或目录struct Inode {int type; // 文件类型(普通文件、目录等)int permissions; // 文件权限int owner; // 文件所有者int size; // 文件大小(字节)int lastModified; // 最后修改时间戳// 指向数据块的指针数组int dataBlockIndices[/* 根据文件大小动态分配,可能包含多级索引 */];} inodes[/* 根据区组大小动态分配 */];// 数据块表(或数据块区域)// 实际存储文件内容的逻辑块,这里简化为一个指针数组表示// 每个指针指向一个数据块,数据块可能分布在磁盘的不同位置void* dataBlocks[/* 根据区组大小动态分配 */];
};
那么其中这4个属性,我们知道它们本质上也是数据,那么必然就在相应的逻辑块中存放,而我们同一个分组的逻辑块一般是在物理内存的同一个区域,并且其中的属性也是按照特定的顺序来排列,比如超级快块一般在该分组的逻辑块的第一个位置,然后再是块表和inode表依次向后排列,那么这取决于特定的文件系统实现,并且不同的文件系统对于每一个分组所占据的逻辑块的数量也是不同的
那么我来详细介绍一下该组的各个不同的属性:
超级块
::超级块记录了文件系统的类型、大小、块大小、inode数量、空闲块和inode的数量等关键信息。它还包括文件系统的挂载时间、最后写入时间等时间戳信息
块表
:采取的是位图的实现方式,那么其中每一个二进制位的状态用来表示每一个逻辑块是否被使用
inode表
:那么每一个文件都会对应有一个innode结构体用来存储该文件的属性其中就包括权限等字段,其中innode表还会记录一个数组,那么该数组一般长度为15,那么该数组则是记录该文件对应的文件内容的数据的逻辑块,那么每一个数组元素的内容就是逻辑块的索引,那么数组前12个位置则是直接索引,那么他们指向的逻辑块就是直接存储的是文件的内容,而之后的元素则是二级以及三级索引,那么所谓二级索引则是该指向的逻辑块存储的内容不是有效的文件内容的数据,而是指向其他保存文件内容数据的逻辑块,那么这样就能扩展文件的体积,所以innode表则是记录每一个innode所对应的逻辑块的位置,用位图来实现
data block
:那么除了超级块以及快表和inode和inode表所占据的逻辑块,那么其余就是存储文件内容的数据块,所以我们发现Linux下文件的属性以及内容是分开存储的
那么这就是我们操作系统管理未打开文件的方式,采取的是分治以及先描述,再组织的策略
结语
那么这就是本篇文章关于文件系统的全部内容了,那么下一期文章将是软硬件链接,那么下一期博客就是我们Linux文件系统的一个收尾啦,那么文件系统学写完之后,我们便打开了语言与操作系统之间的隔阂,那么我会持续更新,希望你多多管制,如果我的文章有帮组到你的话,还请多多三连加关注哦,你的支持,就是我创作的最大动力!
相关文章:
【Linux内核系列】:文件系统
🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz ★★★ 本文前置知识: 文件系统初识 那么在我们此前关于文件的学习中,我们学习的都是进程与打开的文件之间的关系,以及打开的文件如何进行管理…...
工程化与框架系列(35)--前端微服务架构实践
前端微服务架构实践 🏗️ 引言 随着前端应用规模的不断扩大,微服务架构在前端领域的应用越来越广泛。本文将深入探讨前端微服务架构的实现方案、最佳实践和相关工具。 微服务架构概述 前端微服务架构主要包括以下方面: 应用拆分…...
多条件下的免杀webshell
前言 在做webshell免杀的时候,很多情况下都是对system,eval等命令执行函数进行匹配,如果说把变量当做一个函数来使用的话,那是不是可以bypass了呢?这今天刚好看见有一个回调函数有这样的功能,而且也不会报毒ÿ…...
【算法】动态规划
⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 动态规划总结1、常见动态规划Fibonacci数列杨辉三角最小花费爬楼梯孩子们的游戏 2、组合方案李白打酒加强版(lqb&…...
MySQL事务及索引复习笔记
本文参考小林coding,地址事务隔离级别是怎么实现的? | 小林coding 事务 一、事务是什么? 比如一个程序是转账,你要扣减a的余额,增加b的余额,但是如果程序执行扣减成功然后挂了,就会出现a的余额…...
API调用大模型推理与第三方API实现业务整合
基于Python实现大模型推理与第三方API调用的集成,需要结合Function Call机制与提示词工程。 一、技术架构设计 双阶段流程 推理阶段:大模型解析用户意图,生成结构化API调用指令执行阶段:Python代码解析指令并触发第三方API # 示例…...
GreenKGC: A Lightweight Knowledge Graph Completion Method(论文笔记)
CCF等级:A 发布时间:2023年7月 代码位置 25年3月17日交 目录 一、简介 二、原理 1.整体 2.表示学习 3.特征修剪 4.决策学习 三、实验性能 1.主要结果 2.消融实验 四、结论和未来工作 一、简介 传统知识图谱补全方法中,嵌入维度…...
Android Composable 与 View 的联系和区别
在 Android 开发中,Composable(Jetpack Compose)与View(传统 View 系统)是两种不同的 UI 构建范式。本文将从核心联系、核心区别、代码实现三方面展开对比,并通过实例代码帮助开发者理解其应用场景…...
微信小程序wx.request接口报错(errno: 600001, errMsg: “request:fail -2:net::ERR_FAILED“)
来看看报错 报错如下: 请求发送部分,代码如下: uni.request({url: self.serverUrl "/getRealName",method: GET,data: {"code": self.info.code,},header: {"Authorization": uni.getStorageSync(tokenHead) uni.getStorageSync(token)}}…...
多线程与并发编程 面试专题
多线程与并发编程 面试专题 线程的基础概念基础概念线程的创建线程的状态线程的终止方式start 与 run 区别线程的常用方法 锁锁的分类深入synchronized深入ReentrantLock死锁问题 阻塞队列线程池 线程的基础概念 基础概念 进程与线程 进程:指运行中的程序。 比如我…...
大语言模型-1.2-大模型技术基础
简介 本博客内容是《大语言模型》一书的读书笔记,该书是中国人民大学高瓴人工智能学院赵鑫教授团队出品,覆盖大语言模型训练与使用的全流程,从预训练到微调与对齐,从使用技术到评测应用,帮助学员全面掌握大语言模型的…...
【C++】每日一练(轮转数组)
本篇博客给大家带来的是用C语言来解答轮转数组! 🐟🐟文章专栏:每日一练 🚀🚀若有问题评论区下讨论,我会及时回答 ❤❤欢迎大家点赞、收藏、分享! 今日思想:不服输的少年啊…...
dify本地源码win10部署
我的win10版本还比较老,winR,输入winver 只要高于我这个版本的都没啥大问题吧,我的安装docker Desktop,搞死人了, 就是win10的Win10 22H2 64之前的版本 win10低版本安装,里面包含wdl2安装程序 https://…...
Spring Cloud Config - 动态配置管理与高可用治理
引言:为什么需要配置中心? 在微服务架构中,配置管理面临分散化、多环境、动态更新三大挑战。传统基于application.yml等配置文件的硬编码方式,导致以下问题: • 环境差异:开发、测试、生产环境配置混杂&a…...
大模型最新面试题系列:微调篇之微调框架(一)
一. 在DeepSpeed中配置零冗余优化(ZeRO)实现显存优化的步骤 核心原理 ZeRO通过分片(Sharding)技术将模型参数、梯度和优化器状态分布到多卡,消除冗余存储。三个阶段逐步减少显存占用: Stage 1࿱…...
windows第十三章 GDI绘图技术
文章目录 GDI绘图函数介绍设备上下文函数m_hDC GDI对象画笔画刷位图字体区域 案例分享 GDI绘图函数介绍 绘图函数在CDC类里 设备上下文 DC:device context 设备上下文,显卡驱动程序,控制硬件,每个厂商的都不同,操作系统层面&am…...
使用 Nginx 进行前端灰度发布的策略与实践
1. 引言 灰度发布的概念 灰度发布,也称为金丝雀发布,是一种软件发布策略,通过向一小部分用户群体逐步推出新版本,收集反馈并监控性能,以确保新版本在大规模部署前不会出现问题。这种方法可以有效降低发布风险&#x…...
有了大语言模型还需要 RAG 做什么
一、百炼平台简介 阿里云的百炼平台就像是一个超级智能的大厨房,专门为那些想要做出美味AI大餐的企业和个人厨师准备的。你不需要从头开始做每一道菜,因为这个厨房已经为你准备了很多预制食材(预训练模型),你可以根据…...
pytest快速入门 - 目录:半天掌握pytest
1 pytest快速入门 - 目录 本系列文章将快速的带领用户进入pytest领域,通过阅读本专栏,用户将可以熟练掌握pytest的基本用法,同时对测试前置条件的构造、后置条件的清理等有较深入的了解,特别是后置条件的执行完备度有一个认识。 …...
2.4 python网络编程
在当今数字化的时代,网络连接着世界的每一个角落。从简单的网页浏览到复杂的分布式系统,网络编程无处不在。Python 作为一种功能强大且易于学习的编程语言,在网络编程领域占据着重要的地位。它丰富的库和简洁的语法使得开发者能够高效地构建各…...
网络变压器的主要电性参数与测试方法(4)
Hqst盈盛(华强盛)电子导读:网络变压器的主要电性参数与测试方法(4).. 今天我们继续来看看网络变压器的2个重要电性参数与它的测试方法: 1.反射损耗(Return loss&…...
【Springboot知识】开发属于自己的中间件健康监测HealthIndicate
文章目录 **一、技术栈****二、项目结构****三、依赖配置 (pom.xml)****四、配置文件 (application.yml)****五、自定义健康检查实现****1. Redis健康检查****2. Elasticsearch健康检查****3. Kafka健康检查****4. MySQL健康检查** **六、自定义健康检查接口 (可选)****七、测试…...
蓝桥杯备赛-二分-技能升级
问题描述 小蓝最近正在玩一款 RPG 游戏。他的角色一共有 NN 个可以加攻击力的技能。 其中第 ii 个技能首次升级可以提升 AiAi 点攻击力, 以后每次升级增加的点数 都会减少 Bi。「AiBi⌉Bi。「BiAi⌉ (上取整) 次之后, 再升级该技能将不会改变攻击力。 现在小蓝可以…...
【GPT入门】第18课 langchain介绍与API初步体验
【GPT入门】langchain第一课 langchain介绍与API初步体验 1. langchain介绍定义特点1. 模块化与灵活性2. 链式调用机制3. 数据连接能力4. 记忆管理功能5. 提示工程支持6. 可扩展性 2.langchain核心组件架构图3. 最简单的helloworld入门 1. langchain介绍 LangChain 是一个用于…...
Django部署Filemanagement
Pycharm搭建项目安装虚拟环境 mysqlclient对mysql的安装,配置有要求 pymsql伪装成mysqlclient,pymysql可以操纵mysql pip install pymysql操作sql5.7 mysql8.0会出现与pycharm不兼容问题,会报错,所以降到5.7 # 进入mysql 需要…...
Python的types库学习记录
types 库是 Python 标准库中的一部分,它提供了与 Python 对象类型相关的工具和常量,有助于在运行时处理和操作不同类型的对象。 以下是对 types 库的详细介绍: 主要用途 • 类型检查:在运行时判断对象的类型。 • 动态创建和操作…...
C# 表达式树详解
总目录 前言 在 C# 中,表达式树(Expression Trees)是一种强大的特性,允许开发者将代码表示为数据结构。这使得我们可以在运行时动态地创建和操作代码逻辑,广泛应用于 LINQ 查询、动态方法生成以及反射等领域。本文将深…...
分别用树型和UML结构展示java集合框架常见接口和类
树型结构展示java集合框架常见接口和类 Java 集合框架中的接口和子类关系可以用树形结构来展示。以下是一个简化的树形结构,展示了主要的接口和一些重要的实现类: java.util.Collection ├── java.util.List │ ├── java.util.ArrayList │ ├…...
蓝桥杯备赛-二分-青蛙过河
问题描述 小青蛙住在一条河边, 它想到河对岸的学校去学习。小青蛙打算经过河里 的石头跳到对岸。 河里的石头排成了一条直线, 小青蛙每次跳跃必须落在一块石头或者岸上。 不过, 每块石头有一个高度, 每次小青蛙从一块石头起跳, 这块石头的高度就 会下降 1 , 当石头的高度下降…...
uniapp+微信小程序+最简单局部下拉刷新实现
直接上代码 <scroll-view style"height: 27vh;" :scroll-top"scrollTop" scroll-y"true"scrolltolower"onScrollToLower1" lower-threshold"50"refresher-enabled"true" refresherrefresh"onRefresherR…...
Spring Boot 3.x 中 @NotNull 与 @NonNull 的深度解析
在 Java 开发领域,尤其是在 Spring Boot 生态系统中,空指针异常(NPEs)始终是一个顽固的挑战。这些运行时错误可能导致应用程序崩溃、数据不一致以及糟糕的用户体验。为了应对这一问题,Java 社区开发了各种空安全机制&a…...
SQLark 实战 | 如何从Excel、csv、txt等外部文件进行数据导入
数据导入导出是应用开发者在平时开发中最常用的操作之一,SQLark 里提供了方便的图形化界面来完成导入导出。本文先和大家分享如何从 Excel、csv、txt 等外部文件导入数据到数据库表中。 👉 前往 SQLark 官网:www.sqlark.com 下载全功能免费版…...
MATLAB中envelope函数使用
目录 说明 示例 chirp 的解析包络 使用滤波器计算多通道信号的解析包络 录音信号的移动 RMS 包络 语音信号的峰值包络 不对称序列的包络 envelope函数的功能是提取信号的包络。 语法 [yupper,ylower] envelope(x) [yupper,ylower] envelope(x,fl,analytic) [yupper,…...
ES搭建详细指南+常见错误解决方法
Elasticsearch(ES)是一款开源的、分布式的、RESTful风格的搜索和数据分析引擎。它用于全文搜索、结构化搜索、分析等场景。以下是Elasticsearch的搭建步骤以及处理常见错误的方法。 Elasticsearch搭建步骤: 1.环境准备: 确保你的…...
Unity 封装一个依赖于MonoBehaviour的计时器(上) 基本功能
灵感来自下面这本书的协程部分,因此我就自己尝试写了一个 我的新书Unity3D游戏开发(第3版) | 雨松MOMO程序研究院 如果你不知道什么是协程:unity保姆级教程之协同程序_unity协同-CSDN博客 一句话概括:协程就是单线程的异步操作,其作用于Unity的主线程 1…...
PostgreSQL数据库版本支持策略
PostgreSQL数据库版本支持策略 主要版本会进行复杂的更改,因此无法以向后兼容的方式维护数据目录的内容。重大升级需要转储/重新加载数据库或使用pg_upgrade应用程序。我们还建议您阅读您计划升级到的主要版本的升级部分。您可以从一个主要版本升级到另一个…...
应用层之网络应用模型,HTTP/HTTPS协议
应用层是网络协议栈的最顶层,直接为应用程序提供通信服务,定义了不同主机间应用进程交互的规则,包括报文类型、语法、语义及通信时序 一、网络应用模型 1.定义及特点 模型定义核心特点典型应用场景C/S客户端向服务器发起请求,服…...
(七)Spring Boot学习——Redis使用
有部分内容是常用的,为了避免每次都查询数据库,将部分数据存入Redis。 一、 下载并安装 Redis Windows 版的 Redis 官方已不再维护,你可以使用 微软提供的 Redis for Windows 版本 或者 使用 WSL(Windows Subsystem for Linux&a…...
11 | 给 Gin 服务器添加中间件
提示: 所有体系课见专栏:Go 项目开发极速入门实战课;欢迎加入 云原生 AI 实战 星球,12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力(聚焦于 Go、云原生、AI Infra);本节课最终…...
selenium等待
通常代码执行的速度⽐页⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可以使⽤selenium中提供的三种等待⽅法: 1. 隐式等待(Implicit Wait) 隐式等待适用于全局,它告诉 WebDriver 在查找元素时等待一定的时间,直到元素出现。 如果超时,WebDriver 不…...
为什么List、Set集合无法在遍历的时候修改内部元素
以常用集合ArrayList为例,ArrayList 在遍历过程中无法直接修改内部元素的结构(例如通过 remove() 或 add() 方法修改元素),是因为 遍历的过程中修改结构 可能会导致 不一致的行为、并发修改异常 或 逻辑错误。 注意:和…...
使用 Elasticsearch 构建多模式 RAG 系统:哥谭市的故事
作者:来自 Elastic Alex Salgado 学习如何构建一个多模态检索增强生成 (RAG) 系统,该系统集成文本、音频、视频和图像数据,以提供更丰富的、具有上下文的信息检索。 在这篇博客中,你将学习如何使用 Elasticsearch 构建一个多模态 …...
单一责任原则在Java设计模式中的深度解析
在软件开发中,设计模式提供了一种解决特定问题的思路。在众多的设计原则中,单一责任原则(Single Responsibility Principle,SRP)是一个非常重要的概念。它主要强调一个类应该只有一个责任,也就是说…...
设计模式学习记录
设计模式23种 创建型抽象工厂模式工厂模式生成器模式原型模式单例模式 结构型适配器模式桥接模式组合模式装饰模式外观模式享元模式代理模式 行为型责任链模式命令模式解释器模式迭代器模式中介者模式备忘录模式观察者模式状态模式策略模式模版方法模式访问者模式 创建型 与对…...
set_clock_groups
一、命令参数与工具处理逻辑 核心参数定义 参数定义工具行为工具兼容性-asynchronous完全异步时钟组,无任何相位或频率关系(如独立晶振、不同时钟树)工具完全禁用组间路径的时序分析,但需用户自行处理跨时钟域(CDC&a…...
QT创建项目(项目模板、构建系统、选择类、构建套件)
1. 项目模版 项目类型界面技术适用场景核心依赖模块开发语言Qt Widget ApplicationC Widgets传统桌面应用(复杂控件)Qt WidgetsCQt Console Application无 GUI命令行工具、服务Qt CoreCQt Quick ApplicationQML/Quick现代跨平台应用(动画/触…...
麒麟系统利用pycharm生成deb文件
在麒麟系统(Kylin OS)上使用 PyCharm 进行 Python 开发并生成 .deb 可安装软件包,可以按照以下步骤进行操作: 1. 准备工作 安装 PyCharm:确保已经在麒麟系统上安装了 PyCharm,可以使用官方提供的安装包进…...
超声重建,3D重建 超声三维重建,三维可视化平台 UR 3D Reconstruction
1. 超声波3D重建技术的实现方法与算法 技术概述 3D超声重建是一种基于2D超声图像生成3D体积数据的技术,广泛应用于医学影像领域。通过重建和可视化三维结构,3D超声能够显著提高诊断精度和效率,同时减少医生的脑力负担。本技术文档将详细阐述…...
Qt 信号与槽
目录 Qt信号和槽 connect函数 connect使用方法 自定义信号 与 自定义槽 Qt界面化工具自动生成的槽 自定义信号 带参数的信号和槽 信号与槽的断开 Qt信号和槽 谈到信号,设计3个要素 信号源:谁发出了信号 信号触发条件:哪个控件的哪个…...
卷积神经网络 - 卷积的变种、数学性质
本文我们来学习卷积的变种和相关的数学性质,为后面学习卷积神经网络做准备,有些概念可能不好理解,可以先了解其概念,然后慢慢理解、逐步深入。 在卷积的标准定义基础上,还可以引入卷积核的滑动步长和零填充来增加卷积…...