- 博客(34)
- 收藏
- 关注
原创 Linux 命令行参数与环境变量:从 Shell 到 main() 的数据是怎么传进去的?
本文深入解析了程序启动时命令行参数和环境变量的传递机制。通过代码示例和系统视角,揭示了从Shell到进程再到/proc文件的完整数据链路:命令行参数(argv)和环境变量(envp)由父进程通过exec函数传递给子进程,main函数通过argc/argv/envp参数接收,同时环境变量还存在于全局变量environ和/proc/[pid]/environ中。文章特别区分了Shell变量与环境变量的差异(需export才能传递给子进程),并通过汇编代码展示了参数传递的底层实现。最后给出了一个完整实验方案,帮助
2026-06-14 22:35:13
413
3
原创 Linux 进程概念深度解析:从 `task_struct` 到进程状态、优先级、调度与上下文切换
本文围绕 Linux 进程概念展开,从“程序为什么运行后才成为进程”讲起,逐步介绍操作系统如何通过 task_struct 描述进程、通过队列组织进程、通过调度器分配 CPU。文章结合 ps、top、/proc、kill、nice、vmstat 等 Linux 命令,以及 fork、waitpid、僵尸进程、孤儿进程、进程状态、写时拷贝、地址空间、上下文切换和 O(1) 调度等核心内容,配合代码实验、表格和图解,帮助读者从现象理解到底层原理。通过本文,你将建立一条清晰主线:进程不是程序本身,而是程序运行后被
2026-06-13 19:13:38
853
原创 Linux 开发工具收官:用 `Git` 管代码版本,用 `GDB` 定位程序问题
这篇文章介绍了Linux开发中两个核心工具——Git版本控制系统和GDB调试器的基本使用方法,形成完整的终端开发闭环工作流: Git版本管理 解决代码版本混乱问题,记录每次修改历史 核心概念:工作区、暂存区、本地仓库、远程仓库 基本工作流:git add → git commit → git push 重要配置:.gitignore文件避免提交编译产物 GDB程序调试 定位运行时问题,支持断点调试、变量查看和修改 关键编译选项:必须使用-g参数保留调试信息 基本使用:gdb启动程序、list查看源码、bre
2026-06-12 12:43:39
158
2
原创 Linux 开发工具进阶:从 `gcc/g++` 编译流程到 `Makefile` 自动化构建,再手写一个进度条
这篇文章介绍了Linux下从C/C++源代码到可执行程序的完整编译过程,以及如何使用make工具实现自动化构建。主要内容包括: 为什么.c文件不能直接运行:源代码需要经过编译过程转换为机器可执行文件 GCC编译的四个阶段: 预处理(生成.i文件) 编译(生成.s汇编文件) 汇编(生成.o目标文件) 链接(生成最终可执行文件) GCC与G++的区别:G++更适合编译C++程序并自动链接C++标准库 Make工具的作用:解决多文件项目的自动化构建问题,只重新编译修改过的文件 Makefile的基本结构和原理
2026-06-12 12:41:21
468
1
原创 Linux 开发工具入门:从 `yum` 软件安装到 `Vim` 高效编辑,一篇打通基础工作流
文章摘要: 本文针对Linux开发初学者,重点讲解两大基础工具yum和Vim的使用。yum作为包管理器解决软件安装问题,能自动处理依赖关系;Vim则是终端环境下的高效文本编辑器。文章通过常见报错案例引入工具链概念,详细介绍了yum的安装/卸载/查询等基本操作,并解释了Linux软件的三种安装方式及yum的工作原理(基于rpm包管理)。最后还讲解了yum镜像源的配置原理,为后续开发工具链(gcc、make等)的使用打下基础。
2026-06-12 01:18:46
283
2
原创 别再只会 “chmod 777“:一篇真正讲透 Linux 权限的实战笔记
本文围绕 Linux 权限管理展开,从用户身份、文件类型、rwx 权限位入手,系统讲解 su、sudo、chmod、chown、chgrp、umask 与粘滞位等核心内容。文章通过大量终端命令和实际输出,分析普通文件与目录权限的区别,解释 Permission denied、Operation not permitted 等常见报错原因,并给出权限问题的排查流程。通过本文,读者不仅能掌握常用权限命令,更能理解 Linux 如何根据属主、属组和其他用户进行访问控制,从而摆脱只会 chmod 777 的粗暴做法
2026-06-11 23:57:23
354
3
原创 从可变参数模板到 Lambda:C++11 如何让代码更灵活、更优雅
本文聚焦 C++11 在模板与代码表达层面的升级,系统介绍可变参数模板、参数包展开、emplace_back、lambda、function 与 bind 的核心作用。文章围绕“代码如何写得更灵活、更优雅”展开,说明 C++11 不仅重构了对象的创建与流动方式,也显著提升了泛型接口设计、局部逻辑表达与可调用对象组织能力。
2026-06-05 03:36:25
487
2
原创 C++11 如何减少无意义的拷贝:右值引用、`std::move`、移动语义与完美转发
文章摘要: 本文深入探讨C++11引入的移动语义机制,通过对比传统拷贝与移动操作的核心差异,揭示如何优化对象资源管理。文章首先以字符串类为案例展示深拷贝开销,进而解析左右值本质区别——右值引用为资源转移提供了语言级支持。关键点包括:移动构造直接接管临时对象资源,移动赋值需先释放旧资源;被移动对象必须保持有效但未指定状态。实验部分通过典型场景对比拷贝/移动行为差异,最终指出移动语义的核心价值:对即将失效对象优先转移资源而非复制,从而显著提升程序效率。
2026-06-05 03:35:10
325
3
原创 从统一初始化到移动语义:C++11 为什么是现代 C++ 的起点
本文从统一初始化讲到右值引用与移动语义,梳理 C++11 如何重塑对象的创建与资源流动方式。文章结合 initializer_list、花括号初始化、std::move、移动构造与移动赋值等核心内容,说明 C++11 为什么不仅是语法升级,更是现代 C++ 的真正起点。
2026-06-05 03:34:35
406
3
原创 AVL树实现详解:从插入到四种旋转,第一次手写也能学明白
本文结合第一次手写 AVLTree 的实现过程,系统梳理了 AVL 树的核心思想与插入调整逻辑。文章先说明 AVL 树与普通二叉搜索树的区别,再围绕平衡因子定义、BST 插入、祖先路径更新、LL/RR/LR/RL 四种旋转展开分析,并结合代码讲解为什么插入后只需沿父链向上更新。最后通过典型序列手推和测试思路,帮助理解 AVL 树如何在保持二叉搜索树有序性的同时,将树高稳定控制在 O(logN)。
2026-05-31 18:47:46
360
4
原创 双指针,不是背模板,而是把暴力枚举一步步优化掉
双指针并不是简单的两个下标一起移动,更不是靠死记模板就能掌握的技巧。它真正的价值,在于从暴力解法出发,发现重复枚举、无效比较和冗余统计,再借助有序性、单调性、边界关系或循环结构,将问题一步步优化到更高效的解法。本文围绕移动零、复写零、快乐数、盛最多水的容器、有效三角形的个数、和为 s 的两个数字、三数之和、四数之和 8 道经典题展开,系统梳理双指针的常见模型与核心思想。每道题都从暴力思路切入,分析瓶颈所在,再推导出双指针优化过程,并结合代码细节、易错点和方法总结,帮助读者真正理解双指针“为什么能做..
2026-05-29 21:55:25
364
3
原创 C++ map 和 set:为什么这一章不是“会用几个接口”就够了,而是刷题、面试、开发里的高频核心能力?
本文围绕 C++ `set`、`multiset`、`map`、`multimap` 展开,重点讲清它们的核心接口、使用场景和高频误区。文章不只停留在“会用容器”,而是从“按 key 管数据”的角度,分析去重、判重、映射、统计等典型问题,并结合力扣题讲解 `map/set` 在做题中的真实价值,帮助读者建立更清晰的关联式容器思维。
2026-05-26 00:11:17
350
1
原创 二叉搜索树:为什么它能把查找、插入、删除都串成一条线?
本文深入解析了二叉搜索树(BST)的核心原理与实现细节。首先指出BST的本质是通过大小关系快速缩小搜索范围,其效率取决于树高,平衡时可达O(logN),但可能退化为O(N)。文章详细拆解了插入、查找和删除三大操作:插入需找到合法位置再连接父子节点;查找类似二分搜索,通过比较排除无效分支;删除则需根据不同情况(叶子节点、单孩子节点、双孩子节点)采取相应策略,特别是双孩子节点需用右子树最左节点替换。最后解释了中序遍历必然有序的特性,并区分了纯key版(类似set)和key-value版(类似map)的应用场景。
2026-05-25 01:54:00
346
原创 C++ 多态:为什么同一个函数调用,真正执行谁要到运行时才知道?
本文围绕 C++ 多态展开,重点讲解静态多态与动态多态的区别、动态多态的两个必要条件、虚函数重写、重载/隐藏/重写对比、默认参数陷阱、协变、虚析构函数、override/final、纯虚函数与抽象类,以及虚函数表和动态绑定的底层原理。文章从买票、动物叫声等例子切入,说明多态并不是简单的函数同名,而是通过基类指针或引用调用虚函数,在运行时根据真实对象决定执行哪个函数。通过虚表指针、虚函数表和虚表覆盖模型,帮助读者理解“同一调用,不同行为”的实现机制,并总结高频面试问题,适合复习和系统掌握 C++ 多态。
2026-05-23 22:49:12
599
原创 C++ 继承:为什么它不是“少写几行代码”,而是类关系设计的分水岭?
本文围绕 C++ 继承展开,重点讲解继承的设计目的、继承方式与访问权限变化、派生类和基类之间的转换、对象切片、作用域隐藏、派生类默认成员函数、多继承、菱形继承、虚继承以及继承和组合的选择。文章从 Person / Student / Teacher 的关系切入,说明继承并不是单纯为了复用代码,而是为了表达类之间的 is-a 层次关系。通过对象模型分析派生类对象中基类子对象的存在,进一步解释切片、指针偏移、构造析构顺序等问题。同时对隐藏、重载、重写进行对比,帮助读者理清高频面试易混点。
2026-05-23 17:33:10
801
1
原创 C++ 模板进阶:为什么模板不只是“泛型”,更是 STL 设计的底层语言?
本文围绕 C++ 模板进阶展开,重点讲解非类型模板参数、函数模板特化、类模板全特化与偏特化、仿函数、比较器以及模板分离编译等核心内容。文章从“模板为什么不只是泛型”切入,结合 array<T, N>、Less<T*>、priority_queue 比较器和 Data<T1, T2> 特化示例,分析模板如何在编译期生成代码、定制特殊类型逻辑,并进一步理解 STL 泛型设计的底层思想。同时,文章总结了模板常见易错点和面试高频问题,帮助读者从语法、原理到工程应用建立完整认知。
2026-05-22 17:03:29
387
3
原创 C++ 容器适配器:为什么 stack、queue 看起来像容器,其实是在“换接口”?
本文围绕 C++ 容器适配器展开,重点讲解 stack、queue、priority_queue 的设计思想与底层实现。文章从“适配器不是普通容器,而是对已有容器接口的重新封装”切入,说明 stack 如何通过底层容器实现后进先出,queue 如何实现先进先出,以及为什么二者默认常用 deque 作为底层容器。同时,文章进一步分析 priority_queue 的堆结构本质,讲清楚 Less 默认形成大堆、Greater 形成小堆的原因,并结合 AdjustUp、AdjustDown 理解堆的插入和删除过程
2026-05-22 16:21:27
512
4
原创 C++ list:从链表结构到迭代器封装,一篇把 STL list 讲透
本文对比了STL中的vector和list容器,重点分析了list的特性与实现原理。list基于带头双向循环链表实现,其迭代器属于双向迭代器,支持++和--但不支持随机访问。与vector的连续空间不同,list的优势在于任意位置的快速插入删除,仅需修改指针而不移动元素。文章详细讲解了list的底层节点结构、迭代器封装原理、边界处理方式(begin()指向首节点,end()指向头节点作为结束标记),以及为什么需要将迭代器封装为类来维护封装性。
2026-05-21 16:45:16
522
2
原创 C++ vector:为什么它看起来像数组,真正理解却绕不开扩容和迭代器失效?
摘要:本文深入解析C++中vector容器的核心特性与使用要点。vector作为动态数组,兼具数组的随机访问优势与自动扩容能力,通过三个指针管理连续内存空间。文章从底层实现出发,详细讲解构造方式(默认构造、n个val构造、迭代器区间构造)、遍历方法(下标、迭代器、范围for)及常见陷阱(size/capacity区别、迭代器失效等)。重点强调vector不仅是"更好用的数组",更是需要理解其动态扩容机制和连续存储特性的STL容器。
2026-05-19 02:20:36
488
1
原创 二叉树:从线性结构走到分叉结构,数据结构的视角开始真正变了
本文摘要:二叉树是数据结构学习中的重要转折点,从线性结构转向非线性结构。其核心特点在于每个结点最多有两个子结点,形成分叉关系。二叉树适合递归处理,前序、中序、后序遍历的区别在于访问当前结点的时机不同。层序遍历则需借助队列实现。学习二叉树的关键在于建立"当前结点+左右子树"的递归思维模式,这种结构性思考方式对后续算法学习至关重要。通过理解结点连接方式和遍历方法,可以掌握二叉树的基本操作和应用场景。
2026-05-17 00:07:13
335
1
原创 堆:它看起来像树,写起来像数组,用起来却像“优先级机器”
堆是一种特殊的完全二叉树结构,同时具备树、数组和排序工具三重特性。它通过数组实现树形优先级关系,核心在于向上调整和向下调整两种操作:入堆时新元素上浮,出堆时堆顶元素下沉。堆顶始终维护当前最高优先级元素,这使得堆在排序和TopK问题中表现高效。堆排序通过不断取出堆顶元素完成排序,TopK则利用堆动态维护优先级边界。实现时需注意父子节点下标计算和调整方向的一致性。堆的本质是通过局部有序关系高效获取全局重要元素,体现了"局部规则支撑整体高效"的数据结构思想。
2026-05-17 00:06:58
467
原创 队列:先进先出为什么特别适合“流程推进”这类问题
本文摘要: 队列是一种先进先出(FIFO)的线性结构,核心规则是队尾入队、队头出队。相比栈的后进先出特性,队列更适合处理"推进型问题"。链式实现是队列的自然选择,通过维护头尾指针和size变量,可以高效完成入队出队操作。文章详细解析了队列的初始化、销毁、边界处理等关键实现细节,并指出队列在层序遍历、广度优先搜索等场景中的典型应用。队列与栈的对比体现了"回退"与"推进"两种不同的程序组织方式,掌握队列有助于建立流程顺序的结构意识。
2026-05-16 00:06:17
398
原创 栈:后进先出这件事,为什么会这么适合解决“最近的那个先处理”
本文介绍了栈这一经典数据结构的特点与应用。栈遵循"后进先出"原则,只允许在栈顶进行插入和删除操作。文章分析了栈适合顺序表实现的原因,并详细讲解了压栈、出栈等核心操作的实现逻辑。栈虽然接口简单,但能有效处理函数调用、括号匹配等需要"最近状态优先"的场景。作者强调,学习栈的关键在于理解其操作约束带来的优势,以及如何利用这种简单规则解决特定问题。栈不仅是数据结构,更是一种思维模型,适用于需要维护明确状态顺序的场景。
2026-05-16 00:05:48
478
原创 C++ string:为什么这一章看着全是接口,真正动手实现却最容易翻车?
文章摘要: C++中的string类远不止是char*的简单封装,它将字符串数据、操作接口和资源管理统一封装为对象。学习string需掌握两条主线:一是常用接口(构造、遍历、增删查改),二是理解其底层实现(内存管理、深拷贝、扩容机制)。关键点包括:默认构造用""而非nullptr;size/capacity的区别;clear不释放内存;迭代器本质是指针。模拟实现时需重点处理构造函数、拷贝控制及动态扩容,这是理解资源管理类设计的核心案例。
2026-05-15 00:21:15
590
1
原创 双向链表:多一个前驱指针,为什么很多操作会突然舒服很多
摘要:双向链表通过增加prev指针解决了单链表查找前驱的痛点,实现了更高效的插入删除操作。本文分析了带头双向循环链表的优势,包括简化边界条件、统一操作逻辑等,并对比了单链表与双向链表的适用场景。重点指出双向链表的核心价值在于提升局部操作的信息完整度,但需要付出更多空间开销。文章还强调了数据结构设计中的权衡取舍思想,以及画图理解指针操作的重要性。
2026-05-15 00:12:52
371
原创 C/C++内存管理:为什么很多人学完 new/delete,写代码时还是一错再错?
C/C++内存管理核心难点解析 摘要:本文系统剖析C/C++内存管理的核心难点,指出其复杂性源于需要同时处理空间申请、生命周期管理和对象构造析构三套逻辑。文章从程序内存分区(栈、堆、静态区等)的本质差异入手,通过代码示例详解各区域特性,重点对比C的malloc/free与C++的new/delete关键区别:前者仅管理原始内存,后者还负责对象生命周期。特别强调常见易错点,如指针本体与指向内容的位置混淆、realloc的正确用法、new[]/delete[]必须配对等。
2026-05-14 00:10:53
770
原创 C++模板初阶:为什么学完函数重载之后,还必须再学模板?
本文系统讲解了C++模板的核心概念与应用场景。首先对比函数重载与模板的区别,指出模板解决的是"代码复用"而非"函数重载"问题。详细解析了函数模板的工作原理,强调模板是"生成代码的规则"而非现成函数。通过实例分析模板的隐式/显式实例化过程,解释了类型推导规则和匹配优先级。最后介绍了类模板的概念,说明其与函数模板的关键差异在于实例化时机。全文揭示了模板作为C++泛型编程基础工具的本质,帮助读者建立正确的模板思维模型,避免常见理解误区。
2026-05-14 00:06:40
475
原创 单链表:一旦放弃连续空间,插入删除这件事就开始变得轻盈起来
单链表是线性表的链式存储实现,通过指针连接非连续存储的结点。每个结点包含数据域和指向下一结点的指针。相比顺序表,单链表在插入删除操作上更高效,但随机访问性能较差。关键操作包括头插(O(1))、尾插(O(N))和删除,需注意指针修改顺序和边界条件。二级指针用于修改头指针,核心是掌握结点间的指针关系。单链表与顺序表是互补关系,前者适合频繁增删,后者适合随机访问。学习重点在于建立指针操作的直观理解,而非单纯记忆接口。
2026-05-13 01:07:55
556
原创 顺序表:动态数组为什么是线性表里最“像工程”的起点
顺序表是线性表的顺序存储实现,其核心在于通过连续存储空间实现高效随机访问。本文通过代码实例解析了顺序表的本质——动态数组结构(arr/size/capacity),并对比了其与普通数组的区别。重点分析了顺序表的两大特性:O(1)随机访问的高效性,以及插入删除时数据搬移和动态扩容的时间代价。文章指出顺序表最适合尾部操作频繁的场景,而频繁的中间修改会暴露其性能短板。最后强调顺序表的核心教学价值在于建立"存储结构决定操作效率"的底层思维,为后续学习链表等数据结构奠定比较基础。
2026-05-13 01:07:24
362
1
原创 C++类和对象(下):从初始化列表到匿名对象,别再把这些知识学成一堆补丁
本文深入探讨了C++类设计中几个关键特性及其工程意义。首先分析了构造函数初始化列表的必要性,指出引用成员、const成员和无默认构造的类成员必须通过初始化列表完成初始化。随后揭示了初始化列表的本质是构造过程的真正入口,而非语法补充。文章通过实例说明了explicit关键字防止隐式转换的作用,以及static成员属于类而非对象的特性。最后讨论了友元机制在提供便利的同时对封装的破坏性。这些特性共同构成了C++类承担对象组织职责时的核心规则体系,体现了语言在工程实践中的设计考量。
2026-05-12 00:13:33
411
1
原创 C++类和对象(中):从默认成员函数到运算符重载,别再把这些规则背成散点
本文探讨了C++类和对象中默认成员函数的核心逻辑。重点分析了构造函数、析构函数和拷贝构造函数的本质作用:构造函数确保对象初始化为可用状态,析构函数负责资源清理,拷贝构造函数处理对象复制的资源管理问题。文章指出,理解这些函数的关键不在于记忆语法,而在于把握"编译器何时自动生成函数"和"默认行为是否满足需求"这两个核心问题。通过Date和Stack类的对比,说明了不同类对默认成员函数的需求差异:简单值类型可能依赖编译器默认实现,而管理资源的类通常需要自定义实现。这种从设计
2026-05-12 00:12:50
591
原创 C++类和对象(上):从 class 到 this 指针,别再把“类”学成一堆新语法
这篇文章深入浅出地讲解了C++类和对象的核心概念,主要包含以下要点: 类和对象的本质区别:类是抽象的设计图,对象是具体的实例。类描述"有什么"和"能做什么",对象才是真正存储数据的实体。 类的出现是为了将数据和操作这些数据的行为组织在一起,解决了C语言中数据和函数分离的问题。 访问限定符(public/private)的作用:开放必要的接口,保护内部数据,体现了封装的核心思想。 类域的概念:类本身就是一个新的作用域,成员函数需要通过类名限定来明确归属。 实例化的意义:
2026-05-11 21:08:57
606
1
原创 C++入门基础:从 namespace 到 nullptr,别再把这些基础语法学成一地碎片
摘要: C++的语法特性看似零散,实则围绕"代码规范与工程化"展开。命名空间解决全局作用域污染问题,缺省参数优化接口设计,函数重载统一语义表达。这些特性共同构建了C++的工程化体系:命名空间通过作用域划分避免命名冲突;缺省参数减少冗余调用;函数重载保持操作语义一致性。理解这些设计初衷,才能把握C++从"零件"到"系统"的演进逻辑,避免陷入碎片化学习困境。(149字)
2026-05-11 20:48:05
377
2
原创 Linux必备27指令速查手册
本文介绍了27个最常用的Linux指令,涵盖文件操作、系统管理等场景。主要内容包括:基础命令如ls查看目录、pwd显示路径、cd切换目录;文件操作命令如touch创建文件、mkdir创建目录、rm删除文件;查找命令find和grep;压缩解压命令zip和tar;系统监控命令top;以及关机命令shutdown等。每个命令都配有常用选项说明和实际操作示例,适合Linux初学者快速掌握命令行操作。文章强调理解文件路径概念,并演示如何通过这些指令完成从登录服务器到启动网站的全流程。
2025-11-01 13:35:43
874
6
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅