- 博客(31)
- 收藏
- 关注
原创 树相关知识
二叉树前提是一棵树,也就是需要满足我们树的定义的同时,还需要满足以下要求每个节点 最多有两个子节点,分别是左子节点和右子节点。注意我们这里提到的是最多,所以二叉树并不是必须要求每个节点都有两个子节点,也可以有的仅有一个左子节点,有的节点仅有一个右子节点。下面我们来总结一下二叉树的特点· 每个节点最多有两棵子树,也就是说二叉树中不存在度大于2的节点,节点的度可以为0,1,2。· 左子树和右子树是有顺序的,有左右之分。· 假如只有一棵子树,也要区分它是左子树还是右子树。
2026-04-09 01:25:01
650
原创 操作系统-net
摘要:本文介绍了现代高性能设备使用的DMA机制,重点阐述了E1000网卡通过描述符环实现数据传输的原理。发送环(TXRing)采用环形队列结构,CPU将数据包放入队列后由网卡DMA发送;接收环(RXRing)则预先分配缓冲区供网卡存储接收数据。文章详细说明了e1000_transmit和e1000_recv函数的实现流程,包括获取锁、检查状态、更新描述符和推进指针等关键步骤,展示了如何通过DMA技术高效完成网络数据传输。
2026-04-04 18:37:19
693
原创 操作系统-mmap
本文对比分析了传统IO读写与mmap内存映射的原理差异。传统IO通过系统调用实现数据在内核缓冲区和用户空间之间的拷贝,涉及多次上下文切换和数据复制。而mmap通过建立文件到虚拟地址的直接映射,避免了数据拷贝,仅在访问时触发缺页中断加载数据。文章详细阐述了mmap的实现流程,包括VMA结构管理、缺页处理、脏页回写等核心机制,并指出mmap在减少拷贝、提高IO效率方面的优势,同时也讨论了进程fork和退出时的VMA处理等实现细节。
2026-04-02 13:45:00
486
原创 操作系统-FileSystem
本文详细介绍了xv6操作系统的文件系统架构,主要包含以下核心内容: 分层结构:从底层到上层依次为磁盘、缓存、日志层、inode缓存、目录和文件描述符。inode是文件的核心数据结构,通过编号唯一标识文件,不依赖文件名。 磁盘管理:采用静态布局,通过inode将离散物理块虚拟为连续逻辑文件,使用位图高效管理空闲空间。 缓存机制:BufferCache负责缓存和同步,实现LRU算法优化性能,确保同一时间只有一个进程操作磁盘块。 日志系统:提供崩溃一致性保障,采用"先写日志再提交"的事务机制,
2026-04-02 01:00:31
359
原创 操作系统-Multithreading 多线程
本文摘要: 进程和线程是操作系统的基本执行单位。进程是资源分配的基本单位,拥有独立内存空间,类似独立工厂;线程是CPU调度的基本单位,共享进程资源,类似工厂工人。线程切换比进程切换更快,因为共享地址空间。XV6系统中通过swtch函数实现线程上下文切换,保存寄存器状态并恢复新线程状态。在多线程编程中,细粒度锁(如哈希表桶级锁)比全局锁性能更好。Barrier机制用于协调多线程同步。
2026-03-31 20:31:10
695
原创 操作系统-Lock
摘要:竞态条件是并发系统中多个进程/线程同时访问共享资源导致的问题,可通过互斥锁、信号量、原子操作等同步机制解决。锁机制通过硬件原子指令保证临界区互斥访问,自旋锁(spinlock)是常见实现方式。内存分配器(kmem)和缓冲缓存(bcache)通过哈希桶和锁优化性能,避免全局锁竞争。缓冲缓存采用LRU算法管理空闲块,跨桶窃取机制解决局部资源不足问题。处理并发时需注意死锁的四个必要条件,通过统一加锁顺序等方式预防。
2026-03-31 01:13:38
476
原创 操作系统-Copy on Write Fork
在xv6操作系统中,对于fork 的实现是将父进程的用户空间(包括代码、数据和堆栈)全部复制到子进程的用户空间,如果父进程地址空间很大或者子进程随后执行exec()来加载新程序,那么之前复制的所有内存页都会被丢弃,内存空间会造成巨大的浪费。所以产生了写时复制机制(Copy-on-Write,COW),核心目的就是当fork时,父进程不会做实际的内存复制,而是父子进程共享同一份物理内存页,只有当父进程或者子进程尝试写入修改时,才会发生实际的复制。COW原理。
2026-03-30 20:31:32
518
原创 操作系统-lazy allocation
XV6操作系统中通过sbrk()系统调用实现堆内存管理,采用惰性分配策略提升性能。当n>0时仅扩展虚拟地址空间而不分配物理内存,直到发生缺页中断时才真正分配物理页;n<0时立即释放物理内存避免内存泄漏。实现时需修改usertrap()处理缺页中断,调整uvmunmap()、uvmcopy()和walkaddr()等函数以正确处理未映射页表项。这种机制将内存分配开销分摊到实际访问时,特别适合大内存申请场景,但需注意在fork、exit等系统调用中正确处理未映射的虚拟地址空间。
2026-03-30 17:17:22
739
原创 操作系统-Traps
文章摘要: 本文详细分析了xv6-riscv操作系统中的Trap机制实现原理和工作流程。Trap机制负责处理用户态与内核态之间的切换,主要包括系统调用、设备中断和异常三种触发场景。核心流程涉及四个关键函数:uservec(汇编入口)、usertrap(C语言分发处理)、usertrapret(返回准备)和userret(汇编出口)。文章还深入探讨了Backtrace的实现原理和Alarm机制的设计,后者通过在proc结构体添加警报状态字段,实现了用户级时钟中断处理功能。整个Trap机制通过精心设计的寄存器保
2026-03-29 01:19:50
816
原创 操作系统_Page Tables
本文介绍了页表机制在内存管理中的核心作用。页表作为虚拟地址与物理地址的映射表,由操作系统管理并与CPU的MMU协同工作,实现地址转换、权限控制和虚拟内存支持。RISC-V采用三级页表结构,通过TLB缓存加速地址转换。XV6系统为每个进程维护独立页表,内核地址空间直接映射物理地址。文章详细解析了walk()、kvminit()等关键函数的实现原理,并探讨了进程内核页表隔离方案,通过为每个进程创建独立内核页表增强安全性,最后介绍了用户/内核页表同步机制以简化内存访问。
2026-03-27 21:40:42
543
原创 操作系统-System Call
本文详细介绍了xv6操作系统的启动流程和系统调用机制。系统启动经历引导加载、初始化、模式切换和进程创建四个阶段,最终进入用户空间。系统调用通过寄存器传参和ecall指令发起,内核通过陷阱处理和函数表分发执行。文章还阐述了内核态陷阱处理流程、ECALL指令原理,以及系统调用追踪和sysinfo统计的实现方法。重点讲解了用户-内核态数据交互的安全机制,包括copyout函数的地址验证和逐页复制过程。这些机制共同保障了系统调用的安全执行和内核稳定性。
2026-03-27 01:26:54
784
原创 操作系统-Util
本文记录了非科班开发者通过xv6操作系统项目学习操作系统的过程。主要内容包括:1) 环境配置,使用WSL搭建Ubuntu 20.04开发环境并配置QEMU模拟器;2) 实现五个核心功能:sleep系统调用、利用管道实现父子进程通信的pingpong、递归查找文件的find、从标准输入读取参数执行的xargs,以及使用多进程筛选素数的primes。每个功能都详细解析了实现原理和代码逻辑,涉及进程管理、管道通信、文件系统等操作系统核心概念。通过实践项目,作者深入理解了操作系统的进程调度、内存管理和系统调用等关键
2026-03-26 20:01:50
562
原创 fmt使用
本文总结了C++中fmt库的使用优势:相比C的printf和C++的cout,fmt库更简洁安全,能自动识别参数类型,避免格式化漏洞。文章介绍了fmt的核心功能,包括字符串格式化输出(fmt::print/format)、时间格式化、文件输出(fmt::output_file)等基础用法,以及底层实现机制如string_view和内存缓冲区的使用。该库通过类型安全的接口简化了格式化输出操作,提高了开发效率。
2026-03-26 00:17:15
148
原创 数据加密方法
摘要:对称加密(如AES)使用相同密钥加密解密,速度快但安全性较低,适用于大数据处理;非对称加密(如ECDH)采用公私钥对,速度慢但更安全,适合密钥交换和身份验证。AES通过多轮变换(字节代换、行移位等)实现加密,密钥长度影响安全性;ECDH基于椭圆曲线数学特性实现安全密钥交换,支持不同安全级别的曲线。两种加密方式各有适用场景,常结合使用以兼顾效率与安全。
2026-03-24 22:41:13
339
原创 数据压缩方法
摘要:本文系统介绍了数据压缩技术,重点解析了zlib和Zstd两种主流压缩算法。zlib采用LZ77算法结合Huffman编码实现无损压缩,通过滑动窗口和前向缓冲区匹配重复字符串,再通过频率统计优化编码。文章详细说明了zlib的流式API使用方法,包括压缩级别选择、内存管理和错误处理。同时对比介绍了Zstd算法,其压缩率和性能优于zlib,提供了更灵活的压缩参数设置。文中还给出了实际项目中的代码示例,展示了如何实现压缩/解压缩功能,包括缓冲区管理、流式处理和错误检测等关键环节。
2026-03-24 18:14:06
616
原创 GTest(Google Test)
本文介绍了GoogleTest(GTest)的基本用法,包括测试用例格式(TEST/TEST_F)、断言类型(EXPECT_/ASSERT_)和测试夹具(TestFixture)的使用方法。重点说明了两类断言的区别:EXPECT_*会继续执行测试,ASSERT_*会立即终止。文章还提供了通过vcpkg安装GTest、CMake配置和链接GTest库的完整流程,特别强调了在CMake中设置GTEST_ROOT和使用vcpkg工具链的关键步骤。测试夹具部分展示了如何通过继承testing::Test类来实现测试
2026-03-23 16:35:36
268
原创 mmap映射、sendfile
mmap和sendfile是两种高效的I/O优化技术。mmap通过内存映射减少一次CPU拷贝,将文件映射到用户空间,但仍需4次上下文切换。sendfile则完全在内核空间操作,无需用户空间参与,仅需2次上下文切换和1次CPU拷贝,效率最高。mmap适合需要访问文件内容的场景,而sendfile适用于纯数据传输。相比传统I/O的4次拷贝和4次切换,这两种技术显著提升了性能,其中sendfile实现真正的"零拷贝"。
2026-03-22 12:41:39
308
原创 套接字通信-IO多路复用(select/poll/epoll)
IO多路复用是一种高效处理并发网络通信的技术,通过内核监控多个文件描述符状态,避免多进程/线程的开销。主要实现方式包括: select:跨平台但效率较低,使用线性表存储描述符,最多支持1024个连接 poll:Linux专用,取消连接数限制但仍使用线性结构 epoll:Linux专用高性能方案,采用红黑树管理描述符,支持边沿触发模式,效率最高 示例代码展示了select和epoll的实现流程,包括: 创建监听套接字 绑定/监听端口 设置多路复用监控 处理就绪事件(接受连接或通信) epoll特别适合高并发场
2026-03-20 01:58:54
683
原创 并发网络通信-套接字通信
本文介绍了网络通信的基本概念和TCP通信流程。主要内容包括:1)网络分层模型,区分了局域网和广域网;2)IP地址的IPv4和IPv6两种格式;3)端口的作用是定位主机上的进程;4)网络字节序(大端)和主机字节序(小端)的区别及转换函数;5)TCP通信流程,详细说明了服务器端(socket、bind、listen、accept等)和客户端(socket、connect等)的实现步骤;6)相关核心函数的参数说明和使用方法。TCP是一种面向连接、安全可靠的流式传输协议,通过三次握手建立连接,四次挥手断开连接。
2026-03-19 17:15:03
529
原创 socket
本文介绍了TCP和UDP两种网络通信协议的基本实现方法。TCP部分详细说明了sockaddr_in结构体、关键函数(如socket、bind、listen、accept等)的使用方法,并提供了完整的服务端和客户端示例代码。UDP部分重点介绍了recvfrom和sendto函数的用法,同样给出了实现代码。文章最后对比了TCP和UDP的主要区别:TCP需要建立连接且内核记录地址,而UDP是无连接的,每次通信都需要携带地址信息;TCP能检测连接断开,UDP则无法判断对方状态。这些内容为网络编程提供了基础指导。
2026-03-17 09:36:02
109
原创 共享内存 Shared Memory + 信号量
共享内存和信号量实现进程间通信。共享内存速度快但需要同步,信号量通过P/V操作实现资源管理。示例代码展示了生产者-消费者模型:生产者使用信号量控制写入共享内存,消费者读取后释放资源。关键函数包括shmget/shmdt创建销毁共享内存,semget/semop操作信号量。程序通过ftok生成唯一标识符确保进程访问相同资源,实现了安全的进程间数据交换。
2026-03-16 21:56:43
64
原创 消息队列 Message Queues
消息队列本质上是存放在内核中的消息链表,每个消息队列链表由消息队列标识符表示,消息队列存在于内核中,只有主动删除该消息队列或重启内核,消息队列才会被删除进程 A 往队列里丢一个个带有“类型标签”的数据包,进程 B 可以根据标签把特定类型的数据包取走优点:数据被切割成了有意义的数据块,而且通讯是异步的。缺点:每次读写都要在用户态和内核态之间拷贝数据,有性能损耗;队列长度有限制。与管道比较:(1)消息队列收发消息自动保证了同步,不需要由进程自己来提供同步方法,而命名管道需要自行处理同步问题;
2026-03-16 10:42:32
45
原创 IPC进程间通信-Pipes
摘要:本文讲解了进程通信的两种管道方法。匿名管道适用于父子进程间单向通信,通过pipe()创建,配合fork()实现数据传输。命名管道(FIFO)支持无亲缘关系进程间的双向通信,使用mkfifo()创建特殊文件实现。文中提供了C++代码示例,分别演示了匿名管道父子进程通信和命名管道独立进程间通信的实现方法,包括创建管道、读写数据等关键步骤。两种方式都需注意正确关闭文件描述符以避免资源泄漏。
2026-03-13 09:59:54
40
原创 Protobuf(一种数据交换格式)
本文介绍了Protobuf二进制序列化格式的使用方法。序列化是将数据结构转换为可存储或传输格式的过程,反序列化则是逆向过程。文章详细说明了Protobuf的使用步骤:定义.proto文件格式,使用protoc命令生成C++文件,并将生成文件加入项目。重点讲解了序列化(SerializeToString等)和反序列化(ParseFromString等)的常用API函数,以及Protobuf类型与C++类型的对应关系。最后通过一个CMake项目实例,展示了如何集成Protobuf并实现Person结构体的序列化
2026-03-13 09:59:22
252
原创 CMake
本文整理了CMake常用指令,帮助开发者高效管理项目构建。主要内容包括:1)基础指令如cmake_minimum_required、project定义项目;2)构建可执行文件(add_executable)和库文件(add_library);3)变量设置(SET)与路径配置;4)文件搜索(aux_source_directory)和头文件包含(include_directories);5)库链接(link_libraries/target_link_libraries);6)字符串操作和列表处理;7)日志记
2026-03-12 09:49:55
31
原创 GDB常用调试命令参数
本文介绍了GDB调试工具的常用命令及实战应用。主要内容包括:1) 常用GDB命令如run、start、break、step等调试操作;2) 调试时需使用-g参数编译生成包含调试信息的可执行文件;3) 实战演示了设置断点、查看变量、追踪执行等调试过程。文章还说明了如何通过info、display等命令查看调试信息,并提供了循环程序调试的示例。最后建议用户留言咨询不清楚的问题。
2026-03-12 09:49:01
61
原创 Docker定制镜像
本文介绍了使用Dockerfile定制镜像的方法。当从仓库下载的镜像不能满足需求时,可以通过Dockerfile脚本定制镜像,解决重复构建、透明性和体积等问题。文章详细讲解了Dockerfile的核心指令:FROM指定基础镜像、ENV设置环境变量、WORKDIR切换工作目录、RUN执行命令、EXPOSE开放端口、COPY/ADD复制文件等。最后以tomcat为例演示了构建镜像的过程,包括创建文件、设置工作目录等操作,并提醒注意镜像命名规范。通过Dockerfile可以实现镜像的灵活定制,满足个性化需求。
2026-03-11 14:54:25
345
原创 Docker数据卷
Docker数据卷是一种独立于容器的持久化存储方案,解决了容器销毁导致数据丢失的问题。数据卷具有共享性、实时性和持久性等特点,生命周期不依赖容器。通过docker volume create命令创建数据卷,使用-v参数挂载到容器。演示了将index.html文件放入数据卷后,多个容器可共享访问,且宿主机修改会实时同步到所有容器。数据卷存储在/var/lib/docker/volume/目录下,支持查看和删除操作。这种机制避免了重复拷贝文件的操作,实现了高效的数据共享。
2026-03-11 01:19:42
226
原创 Docker 容器
本文介绍了Docker容器的基本操作与管理。主要内容包括:容器的概念及其与虚拟机的区别;查看容器状态的命令(docker ps);启动容器的两种方式(docker run和docker start);停止和删除容器的方法;访问Tomcat容器的配置步骤;进入容器内部操作的方法(docker exec);宿主机与容器间文件交换(docker cp);以及查看容器日志的命令(docker logs)。文章还涉及防火墙配置、容器内文件修改等实用技巧,为Docker初学者提供了全面的基础操作指南。
2026-03-10 15:37:54
255
原创 Docker镜像
本文介绍了Docker镜像的基本操作与管理方法。主要内容包括:1)获取镜像的两种方式(search和pull命令),详细说明了镜像命名格式和版本控制;2)管理本地镜像的操作,包括删除镜像(使用rm/rmi命令)、查看镜像ID和制作历程;3)镜像备份与恢复方法(save和load命令)。文章还简要解释了镜像ID的唯一性原理及UnionFS技术带来的存储优化。这些基础操作是使用Docker容器的重要前提。
2026-03-10 15:37:02
56
原创 Docker
Docker是一个开源容器引擎,可将应用及其依赖打包成轻量级、可移植的容器。它具有性能开销低、环境一致性强等优势,能简化程序部署、节省硬件成本、实现持续交付。本文详细介绍了Docker的安装步骤:包括检查内核版本、卸载冲突包、添加清华源密钥、配置镜像加速器等关键操作,最后通过运行hello-world镜像验证安装成功。Docker极大提升了开发运维效率,是云计算时代的重要工具。
2026-03-09 22:29:32
397
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅