我的 Linux 学习计划书
一、为什么是 Linux?参考 鸟叔讲 Linux、品读 Linux 0.11 核心代码 等资源。 二、我的学习目标:「能用」-->「掌控」避免成为「命令背诵者」,目标分阶段实现: 短期(1-3 个月):独立完成 Linux 服务器日常操作,编写可复用 Shell 脚本。 中期(3-6 个月):掌握系统调优、服务部署,解决 80% 常见故障。 长期(6 个月 +):形成「Linux 思维」,从底层逻辑定位问题根源。 三、分阶段执行计划:拆解「大目标」为「每日动作」阶段一:打基础(第 1-4 周)—— 建立操作直觉核心任务是理解操作底层逻辑,主攻文件系统、权限管理等模块。每日投入 1.5 小时,学习时避免贪多,如学 grep 先掌握 -i、-n、-r 基础参数。 阶段二:练实战(第 5-8 周)—— 从「操作」到「解决问题」每日投入 2 小时,跟随鸟叔课程实践,用博客记录 Shell 自动化、日志分析等模块心得。按课程流程完成项目,整理 Markdown 笔记,记录问题与解法。 阶段三:深扎根(6 个月后)—— 形成「技术自洽」通过读工具源码(如 grep 的...
C 语言序列化和反序列化
一、核心概念:什么是序列化与反序列化?在计算机科学中,序列化(Serialization) 和 反序列化(Deserialization) 是数据持久化与传输的核心技术。 序列化:将内存中的数据结构(如结构体、数组等)转换为二进制字节流的过程。这个字节流可以存储到文件、数据库,或通过网络传输到其他设备。 反序列化:将二进制字节流还原为内存中可用数据结构的过程,是序列化的逆操作。 典型应用场景 数据持久化:将程序运行时的临时数据(如用户信息、配置参数)保存到文件,下次启动时恢复。 网络通信:不同进程/设备间通过网络传输数据时,需将数据转换为无格式的二进制流(避免文本协议的解析开销)。 跨平台协作:确保不同系统(如Windows/Linux)间数据格式兼容(需注意字节序问题)。 二、C 语言实现序列化与反序列化C 语言作为面向过程的语言,没有内置的序列化库,但可以通过文件操作函数(如 fwrite/fread)直接操作二进制数据,实现轻量级序列化。以下是完整实现与详细解析。 1....
从进程调度到分布式系统的并发控制(Operating-Systems)
操作系统学习概念、功能和目标进程管理基础存储管理概述文件系统I/O管理操作系统
从Socket编程到QUIC协议(Computer-Networking)
计算机网络学习计算机网络体系结构物理层数据链路层网络层传输层应用层计算机网络计算机网络体系结构物理层数据链路层网络层传输层应用层
从逻辑门到多核CPU的硬件(Computer-Organization)
计算机组成学习计算机系统概论数据的表示和运算系统总线概念指令系统概述CPU的功能和基本结构总线概述I/O系统基本概念计算机组成计算机系统概论数据的表示和运算系统总线概念指令系统概述CPU的功能和基本结构总线概述I/O系统基本概念
从线性表到分布式(Data-Structures)
数据结构学习绪论线性表栈、队列、数组串树与二叉树图查找排序设计模式之禅 大话设计模式 数据结构与算法分析.C语言描述 大话数据结构 算法导论绪论线性表栈、队列、数组串树与二叉树图查找排序
再学习《C程序设计语言》
作为有 C 语言基础的学习者,我整理《C 程序设计语言 第二版》(2004 年版本)这本旧书时倒没费太多功夫。不过得说句实话,这本书里的内容和现在的 C 语言差异不小。要是你刚入门,我真心不建议只啃这本书单打独斗,多去逛逛开源社区,看看大佬们写的开源项目,在实战里摸索,收获肯定比光看书多得多! 导言类型、运算符与表达式控制流函数与程序结构指针与数组结构输入与输出导言:类型、运算符与表达式:控制流:函数与程序结构:指针与数组:结构:输入与输出: 通读此书后,我深刻意识到,书中函数实现的思想内核才是真正的精华所在,这些精妙的思维方式远比单纯的知识罗列更具价值。书中设置的习题也颇具匠心,对编程学习有浓厚兴趣的同学,若能深入钻研,定能收获颇丰。 此次阅读既是学习新程,也是对旧知的梳理与巩固。浏览过程中,许多熟悉的概念重焕清晰,还挖掘出不少被忽略的细节,让知识体系更加完善。虽暂时仅完成主体内容复习,但这只是新起点。后续我会合理规划时间,认真解答课后习题,通过练习让书中思想落地生根,将理论转化为实践能力,稳步前行在编程之路上。
C语言实现二叉搜索树(BST):从增删改查到三种遍历的完整解析
引言二叉搜索树(Binary Search Tree, BST)是一种经典的动态数据结构,因其高效的查找、插入和删除操作(平均时间复杂度O(logn)),广泛应用于数据库索引、缓存系统、排序算法等领域。本文将基于C语言实现一个完整的BST,详细解析其核心原理、关键操作及三种遍历方式,并通过测试用例验证功能正确性。 一、BST基础概念:定义与核心性质1.1 BST的定义二叉搜索树(BST)是一种特殊的二叉树,满足以下性质: 左子树性质:对于任意节点,其左子树中所有节点的键值均小于该节点的键值。 右子树性质:对于任意节点,其右子树中所有节点的键值均大于或等于该节点的键值(注:部分定义要求严格大于,本文采用“大于等于”以支持重复值处理)。 递归结构:左子树和右子树本身也是BST。 1.2...
用C语言文件流实现轻量级图书管理系统:从0到1的实战解析
引言在C语言的学习过程中,文件操作是一个绕不开的核心技能。无论是保存用户数据、记录日志,还是实现小型系统,“如何将数据持久化到本地”都是必须解决的问题。今天,基于之前写的轻量级图书管理系统,通过文件流复现,带你深入理解C语言文件流的核心概念(如文件指针、文本/二进制模式、文件读写逻辑),并展示如何用文件流替代内存存储,解决小型系统的实际需求。 一、为什么选择文件流?——对比内存存储的局限性在开发小型系统时,我们可能会先用数组或链表在内存中存储数据。但内存存储存在两个致命问题: 临时性:程序退出后,内存数据会被操作系统回收,无法长期保存。 容量限制:内存大小有限(如32位系统约4GB),无法处理大规模数据。 而文件流(File...
动态哈希表:从0到1解析C语言动态数组+链表冲突解决方案
引言哈希表(Hash Map)是一种高效的数据结构,通过哈希函数将键映射到数组索引,实现O(1)时间复杂度的插入、查询和删除操作。但传统静态哈希表(固定容量数组)存在空间浪费(数据少时数组空置)和冲突频发(数据多时哈希碰撞概率激增)的痛点。本文将基于C语言,手把手实现一个动态哈希表,通过「动态数组+链表」的组合方案解决这些问题,并深入解析核心设计与实现细节。 一、设计背景:为什么选择「动态数组+链表」?1.1 传统静态哈希表的痛点传统哈希表通常使用固定大小的数组存储键值对,通过哈希函数计算索引。但这种设计存在两大缺陷: 空间浪费:若初始容量过大,数据稀疏时大量数组空间闲置;若初始容量过小,数据增多时频繁扩容(需重新哈希所有数据),效率低下。 冲突频发:当数据量超过数组容量时,哈希碰撞概率激增,链表法(拉链法)虽能解决冲突,但链表过长会导致查询时间退化为O(n)。 1.2...
C语言文件流:从字符到二进制的三种高效实现
引言在C语言中,文件操作是处理数据存储与传输的核心能力。无论是文本文件还是二进制文件(如图片、视频),复制操作都是最常见的需求。但不同场景下,选择不同的复制方式会直接影响程序的性能与数据完整性。本文将结合三种经典复制实现(字符复制、按行复制、二进制复制),深入解析文件流的核心机制,并给出实战优化建议。 一、文件流基础:文本模式vs二进制模式1.1 文件打开模式的选择C语言中,fopen函数的第二个参数(模式)决定了文件的读写方式。最常用的模式有: 文本模式("r"/"w"/"a"):以字符形式读写,自动处理换行符转换(如Windows的\r 转Unix的 )。 二进制模式("rb"/"wb"/"ab"):以字节形式直接读写,不进行任何转换。 1.2...
从0到1实现C语言哈希表:底层原理与实战解析
引言在C语言的标准库中,没有像C++ unordered_map或Java HashMap这样现成的哈希表容器。当我们需要在C中实现高效的键值对存储时,手动实现一个哈希表是绕不开的选择。本文将以我近期实现的轻量级哈希表为例,从数据结构设计、核心逻辑解析到内存管理,带您深入理解哈希表的底层原理,并结合实际测试用例验证其正确性。 一、为什么需要自己实现哈希表?在开始代码解析前,先聊聊为什么选择手动实现哈希表: 场景适配:标准库未提供通用哈希表(C++的unordered_map依赖模板,无法直接用于纯C项目)。 性能可控:手动实现可以针对具体场景优化(如自定义哈希函数、内存分配策略)。 学习价值:理解哈希表的核心原理(哈希冲突、负载因子、动态扩容),是进阶C语言开发的必经之路。 本文的哈希表实现定位为轻量级字符串键值对存储,适用于配置管理、缓存系统等需要快速查找的场景。 二、数据结构设计:从抽象到具体2.1...
从基础到进阶:常见排序算法的C语言实现与深度解析
引言排序算法是计算机科学中最基础且重要的算法之一,广泛应用于数据库查询、日志处理、数据统计等场景。理解不同排序算法的核心思想、时间复杂度及适用场景,不仅能帮助我们写出更高效的代码,还能在实际工程中根据需求选择最优方案。 本文将以C语言实现为切入点,深入解析插入排序、希尔排序、归并排序、快速排序(双向优化)、堆排序五大经典算法,结合代码逐行分析其底层逻辑,并通过测试用例验证正确性。文末附完整可运行源码。 一、插入排序:从“摸牌”到有序1.1 算法思想插入排序的核心思想是将未排序元素逐个插入到已排序序列的正确位置,类似于整理扑克牌的过程:初始时左手为空(已排序序列),每次从桌面(未排序序列)取一张牌,插入左手已有牌中的正确位置。 1.2 代码实现与解析插入排序代码如下(已修正注释格式): 123456789101112131415void insertion_sort(int arr[], int len) { for (int i = 1; i < len; i++) { // 从第2个元素开始(索引1) if...
C语言单链表操作详解(含二级指针深度解析)
一、简介本文档详细解析一段C语言单链表操作的代码,涵盖头插法插入节点、尾插法插入节点、修改头节点值和打印链表四大核心功能。重点讲解二级指针在链表操作中的作用,帮助理解动态内存管理与指针操作的核心逻辑。 二、前置知识:二级指针的本质2.1 什么是二级指针? 一级指针(Node *head):存储某个节点的内存地址(指向节点)。 二级指针(Node **head):存储一级指针的内存地址(指向“指向节点的指针”)。 2.2 为什么链表操作需要二级指针?在C语言中,函数参数传递是值传递。若链表头指针(head)通过一级指针传递,函数内部对head的修改(如让它指向新节点)只会影响函数的局部副本,外部头指针不会改变。 示例对比: 错误写法(一级指针): 12345void insert_head(Node *head, ElementType new_val) { Node *new_node = calloc(1, sizeof(Node)); new_node->next = head; head = new_node; //...
C语言数组与指针深度解析
引言:为什么需要理解数组与指针的差异?在C语言中,数组和指针是最基础且容易混淆的概念。尤其是*p[](指针数组)和(*p)[](数组的数组)的语法差异,涉及类型优先级、内存布局和操作方式的本质区别。本文通过具体代码示例,结合fruits1(二维数组)和fruits2(指针数组)的对比,深入解析两者的核心差异,并探讨实际开发中的应用场景。 核心概念:*p[]与(*p)[]的类型优先级C语言中,运算符优先级决定了表达式的解析顺序。其中,[](下标运算符)的优先级高于*(解引用运算符)。因此: *p[]会被解析为*(p[]),即数组的指针(指针数组):数组的每个元素是指针; (*p)[]会被解析为(*p)[],即数组的数组(二维数组):数组的每个元素是另一个数组。 用户代码中的fruits1和fruits2正是这两种类型的典型代表: 12char fruits1[][10] = { "apple", "banana", "cherry" }; // 二维数组(数组的数组)char...
C语言实现汉诺塔问题:从递归逻辑到代码解析
引言:为什么需要学习汉诺塔?汉诺塔(Hanoi Tower)是计算机科学中最经典的递归问题之一,由法国数学家爱德华·卢卡斯于1883年提出。它不仅是理解递归思想的绝佳案例,更是培养算法思维的基础。本文将通过C语言实现汉诺塔问题的递归解法,详细解析其核心逻辑,并探讨如何通过代码验证和优化提升程序的健壮性。 问题背景:汉诺塔的规则与目标汉诺塔问题描述如下: 假设有3根柱子(起始塔A、辅助塔B、目标塔C),初始时A塔上有n个盘子,按大小顺序从上到下叠放(大盘子在下,小盘子在上)。目标是将所有盘子从A塔移动到C塔,移动过程中需遵守以下规则: 每次只能移动一个盘子; 大盘子不能直接放在小盘子上(即任何时刻,小盘子必须在大盘子之上)。 最少移动步数:对于n个盘子,最少需要2^n - 1步(数学归纳法可证)。 代码核心:递归解法的逻辑拆解代码通过递归函数move实现了汉诺塔的移动步骤输出,并计算了最少步数。以下是代码的核心部分: 1234567891011121314151617181920212223242526272829#define...
C语言命令行参数处理
引言:为什么需要处理命令行参数?在开发命令行工具时,我们经常需要通过参数传递输入数据或配置选项。例如,一个计算器工具可能需要接收两个数值作为输入,一个文本处理工具可能需要指定输入文件路径。C语言中,main函数的argc和argv参数是处理命令行输入的核心接口。本文将通过一个具体案例,详细解析如何从命令行参数中读取数据、进行数值计算,并输出结果。 核心功能:命令行参数的读取与处理用户提供的代码实现了以下核心功能: 读取命令行参数数量(argc)并打印; 遍历所有命令行参数(argv)并打印每个参数的内容; 从指定参数中解析数值(整数num1和浮点数num2); 计算两数之和并格式化输出结果; 使用第四个参数作为结果的描述字符串。 代码逐行解析:从参数获取到结果输出1. main函数参数:argc与argvC语言中,main函数的标准形式为int main(int argc, char *argv[]),其中: argc(Argument Count):命令行参数的数量(包含程序名本身); argv(Argument...
Vector动态数组复现
引言:为什么需要动态数组?在C语言中,静态数组的大小在编译时确定,无法根据运行时需求动态调整。当数据量不确定或需要频繁插入/删除元素时,静态数组会暴露出明显缺陷:要么浪费内存(声明过大),要么溢出(声明过小)。动态数组(Vector)通过堆内存分配和自动扩容机制,完美解决了这一问题。它支持灵活的元素插入、删除,且内存使用更高效,是实现栈、队列等高级数据结构的基础。 核心结构:Vector的设计哲学结构体定义:封装底层细节代码中的Vector结构体通过三个字段封装了动态数组的核心状态: 12345typedef struct { ElemType *table; // 指向堆空间的数组(存储实际元素) int size; // 当前元素个数(逻辑长度) int capacity; // 数组的最大容量(物理长度)}...
C语言位运算
引言:为什么需要掌握位运算?在计算机底层,所有的数据都以二进制形式存储和处理。位运算(Bitwise Operations)作为直接操作二进制位的工具,是高性能计算、嵌入式开发、算法优化的核心技能。今天我们将通过一个实际案例,深入理解**与(&)、或(|)、异或(^)、取反(~)、移位(<<、>>)**等位运算的应用场景,并实现一组实用的位操作函数。 位运算基础:二进制视角下的数字要掌握位运算,首先需要理解二进制数的表示规则: 最低有效位(LSB):二进制数的最右边一位(2⁰位),决定数的奇偶性; 高位:从右往左依次为2¹、2²...2ⁿ位,每一位代表2的幂次; 补码表示:负数在内存中以补码形式存储(原码取反+1),这是位运算处理负数的关键。 实战函数解析:逐个击破位运算问题1. 判断奇数:最低位的「1」密码问题描述:判断一个整数是否为奇数。...
主题修改记录
二零二五年 二月一日 Hexo 主题封面大改造:从失效链接到宫崎骏风 AI 图这篇主题修改的文章好多年不打开了(其实大部分博客都不怎么重新修正,反正是写给自己的),年久失修,许多封面图片链接失效,只剩破碎图标。为重塑博客风采,假借藏书之家,拜谢AI大人,统一更换封面(全用本地图片改起来还好,但终归让人头秃) 二零二二年 六月十一日 Hexo...

