自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(148)
  • 收藏
  • 关注

原创 讲讲观察者模式

观察者模式(Observer Pattern)也被称为发布 - 订阅模式、模型 - 视图模式,其正式定义为:定义对象间的一对多依赖关系,使得每当一个对象(主题 / 被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都能自动收到通知并同步更新。它的核心设计思想是解耦发布者与订阅者:二者只依赖抽象接口,不依赖对方的具体实现,各自可以独立变化与扩展。观察者模式的核心价值,在于用「抽象依赖」替代「硬编码依赖」,让一对多的对象联动变得灵活、可扩展。

2026-06-14 22:20:21 454 1

原创 C++ 工厂模式:从入门到进阶,彻底掌握对象创建的艺术

工厂模式的本质是封装变化:将对象创建这个最易变的环节隔离封装,让稳定的业务逻辑不再依赖易变的创建细节。设计模式没有绝对的优劣,选择哪种形态,始终取决于业务的复杂度、迭代频率和团队的维护成本。对于绝大多数 C++ 项目,工厂方法模式是扩展性与复杂度的最佳平衡点;而对于中大型系统,注册式工厂是工业界的主流选择,它兼顾了灵活性与可维护性,是真正能支撑项目长期迭代的方案。

2026-06-14 15:53:31 583 1

原创 链式栈的实现

链式栈的每个节点包含数据和指向下一个节点的指针。我们使用模板来实现泛型,使栈可以存储任意类型的数据。// 链式栈节点结构T data;// 数据域// 指针域,指向下一个节点// 构造函数链式栈类包含一个栈顶指针和栈的大小计数器。它提供了入栈、出栈、获取栈顶元素、判断栈是否为空、获取栈大小和清空栈等基本操作。private:// 栈顶指针int count;// 栈中元素的数量public:// 构造函数:创建一个空栈// 析构函数:释放所有节点内存clear();

2026-06-07 14:21:17 259

原创 数据结构 --- 红黑树

节点颜色性质:每个节点要么是红色,要么是黑色。根节点性质:根节点必须是黑色。叶子节点性质:所有叶子节点(NIL 节点,即空节点)都是黑色。红色节点性质:如果一个节点是红色的,那么它的两个子节点都是黑色的。(换句话说,不存在两个连续的红色节点)黑高性质:从任意一个节点到其所有后代叶子节点的简单路径上,包含相同数量的黑色节点。重要概念:黑高 (Black Height)从某个节点 x 出发(不包括 x 本身)到达一个叶子节点的任意一条路径上,黑色节点的个数称为该节点的黑高,记为 bh (x)。

2026-06-07 14:13:47 368

原创 讲讲移动语义

移动语义就是将一个对象的资源(内存、文件句柄、网络连接等)从一个对象转移到另一个对象,而不是复制这些资源。就像我们搬家的时候,直接把箱子搬走,而不是复制里面的东西。移动之后,原来的对象就变成了一个 "空壳",不再拥有任何资源。移动语义是 C++11 最重要的特性之一,它让我们能够以极低的开销转移对象的资源,大幅提升了程序的性能。移动语义:将一个对象的资源从一个对象转移到另一个对象,而不是复制这些资源移动构造函数:用一个右值对象构造一个新对象,转移资源所有权移动赋值运算符。

2026-06-06 22:17:30 346

原创 数据结构 ——BST 树

若左子树非空,则左子树上所有节点的值均小于根节点的值;若右子树非空,则右子树上所有节点的值均大于根节点的值;左、右子树也分别是二叉查找树;通常不允许键值重复(若允许需明确规则)。二叉查找树(BST)是连接线性结构与平衡树形结构的关键桥梁。它基于 “左小右大” 的约束规则,实现了高效的动态有序操作,是理解 AVL 树、红黑树、B 树、B + 树的基础。尽管 BST 在极端情况下会退化,但其思想简洁、应用广泛,是数据结构中必须掌握的核心内容。掌握 BST 的查找、插入、删除三大操作与中序有序。

2026-05-30 23:10:30 424

原创 数据结构 —— 双向循环链表

双向循环链表是一种线性链式存储结构,每个节点包含三部分信息:数据域、前驱指针(prev)、后继指针(next)。双向:每个节点既可以通过后继指针向后访问下一个节点,也可以通过前驱指针向前访问上一个节点;循环:链表的尾节点后继指针指向头节点,头节点的前驱指针指向尾节点,形成一个闭合的环形结构。双向循环链表是链式存储结构的进阶形态,它融合了双向链表的遍历灵活性与循环链表的闭环特性,在需要双向操作、循环访问、动态增删的场景中具备不可替代的优势。

2026-05-30 23:05:59 500

原创 数据结构 -- 二叉搜索树

对于任意节点,其左子树中所有节点的值都小于该节点的值对于任意节点,其右子树中所有节点的值都大于该节点的值左子树和右子树本身也都是二叉搜索树这三条性质是二叉搜索树的灵魂,所有操作和特性都建立在它们之上。int val;// 节点存储的值// 左子节点指针// 右子节点指针二叉搜索树是数据结构与算法学习中的第一个里程碑。它的核心思想 ——通过比较值来划分搜索空间,不仅适用于树结构,更是二分查找、分治算法等众多高级算法的基础。

2026-05-26 22:30:28 573

原创 讲讲硬、软中断、DMA、网卡 网卡驱动

硬中断、软中断、DMA、网卡和网卡驱动是现代计算机网络系统的基石。硬中断负责硬件与 CPU 之间的紧急通知软中断负责将耗时的处理工作延迟执行DMA负责解放 CPU,实现硬件与内存之间的直接数据传输网卡负责物理层和数据链路层的信号转换与帧处理网卡驱动负责连接硬件与内核,协调所有组件的工作深入理解这些概念,不仅能帮助我们写出更高效的网络程序,更能让我们在面对复杂的网络性能问题时,能够快速定位瓶颈并找到解决方案。在高并发、大流量的互联网时代,这些底层知识正是区分普通开发者和优秀架构师的关键所在。

2026-05-26 22:23:59 517

原创 数据结构——AVL二叉平衡树

AVL 树是高度平衡的二叉搜索树,满足两个条件:首先是一棵合法二叉搜索树(满足大小规则)任意节点的左右子树高度差绝对值不超过 11. AVL 是高度平衡二叉搜索树,任意节点左右子树高度差不超过1,依靠平衡因子判断平衡。2. 失衡分为四种:LL(右旋)、RR(左旋)、LR(先左后右)、RL(先右后左)。3. 插入最多两次旋转即可平衡,删除可能多次回溯旋转,维护成本高。4. AVL 查询效率极高,但写操作代价大,适合查多写少场景。

2026-05-24 22:18:29 681

原创 数据结构——栈

栈是一种受限的线性表,仅允许在表的一端进行插入和删除操作,另一端完全封闭,禁止任何操作。后进先出(LIFO,Last In First Out)。弹夹子弹压入弹夹(入栈),最后压进去的子弹,最先被打出去(出栈),最先压入的子弹只能最后出来,完美契合栈的特性。严格遵循后进先出 LIFO不支持随机访问,无法直接查找中间、栈底元素所有操作仅能作用于栈顶,时间复杂度极低结构简单、执行效率极高,无多余遍历开销1. 栈是后进先出(LIFO)的受限线性表,仅支持栈顶增删查,所有操作 O(1)。

2026-05-24 22:02:23 615

原创 讲讲libevent底层机制

libevent 是跨平台事件驱动非阻塞 IO 库,底层封装 epoll/select/poll,实现 Reactor 模式;event_base(反应堆)+event(事件)+ 双向循环链表(事件管理)+ 最小堆(定时器);核心流程:初始化反应堆 → 注册事件 → 事件循环 IO 复用等待 → 就绪执行回调;定时器用最小堆实现,IO 事件依赖系统 IO 复用,信号事件统一调度;优点是跨平台、并发高、稳定;缺点是回调不能阻塞、多线程支持弱;底层大量使用链表、队列、堆、栈。

2026-05-23 23:09:22 463

原创 数据结构——队列

队列是一种先进先出(FIFO,First In First Out)的受限线性表。通俗理解就是排队:先来的人先走,后来的人后走,绝对不允许插队、不允许从中间删除元素。和栈刚好完全相反:栈:后进先出(LIFO)队列:先进先出(FIFO)普通顺序队列:代码最简单,存在假溢出,仅用于入门理解,不实战使用。循环队列:面试必手撕,解决空间浪费,缓存友好,操作系统缓冲区、网络IO底层常用。链式队列:动态扩容无上限,无需处理取模运算,适合任务量波动大的场景,需手动释放内存。1. 队列是先进先出(FIFO)

2026-05-23 22:58:11 703

原创 数据结构 —— 链表

链表是非连续、非顺序的线性表,它不要求内存连续,通过 ** 指针(引用)** 将分散在堆内存中的一个个节点串联起来。数据域(存储业务数据)+指针域(存储下一个节点的内存地址)节点分散在内存各处,不连续排列,靠指针维系前后关系没有下标,不支持随机访问,只能从头节点开始逐个遍历你可以把链表想象成一串带钩子的珠子:每个珠子存数据,同时带一个钩子勾住下一颗珠子;珠子不用挨在一起,靠钩子串联;想要找到第 N 颗珠子,必须从第一颗顺着钩子依次找。// 链表节点T val;// 数据域:存储数据。

2026-05-22 21:22:28 660

原创 数据结构 —— 顺序表

线性表。线性表是具有相同数据类型的 n 个数据元素的有限序列。元素之间是一对一的线性关系有且只有一个第一个元素(表头)和最后一个元素(表尾)除了表头和表尾,每个元素都有且只有一个前驱和一个后继常见的线性表有:顺序表、链表、栈、队列。用一段连续的内存空间 **,依次存储相同类型的数据元素 **。每个柜子大小一样,只能放同一种东西柜子是连续排列的,一个挨着一个每个柜子都有一个唯一的编号(下标),从 0 开始通过编号可以直接找到对应的柜子,不需要挨个找支持随机访问。

2026-05-22 21:18:25 585

原创 讲讲IO复用三个函数的底层逻辑

在没有 IO 复用之前,最原始的 socket 编程采用的是阻塞 IO 模型:一个线程只能处理一个客户端连接。当服务器调用accept()等待客户端连接,或者调用recv()等待客户端发送数据时,如果没有事件发生,整个线程就会被操作系统挂起阻塞,什么也干不了,只能傻等。如果想要支持 1000 个同时在线的客户端,就必须创建 1000 个线程。内存开销巨大:每个线程默认栈空间是 8MB,1000 个线程就要消耗 8GB 内存CPU 调度开销爆炸。

2026-05-22 21:11:05 799

原创 新手必学——git日常提交手册

日常开发严格遵守这个闭环,零报错、零混乱:写代码、改代码,完成功能/修复buggit status查看修改文件git add .暂存所有改动git commit -m "清晰的修改说明"本地存档git pull拉取最新代码(多人协作)git push同步到云端Git 不是高深工具,是开发必备基本功。新手不用死记所有命令,先掌握本文的日常提交、撤回、拉取、推送核心操作,足以应对 99% 的学习和工作场景。

2026-05-22 20:57:15 467

原创 项目——基于C/S架构的文件传输系统平台 (2)——重构

我们已经完成了环境搭建和 MySQL 数据库初始化客户端基本框架(连接服务器、菜单打印、注册 / 登录)数据库操作类的完整实现。

2026-05-20 22:31:52 364

原创 八大排序算法 - 堆排序

堆排序利用大顶堆 / 小顶堆结构实现排序,属于选择排序,不稳定排序。核心思想:先构建大顶堆,把堆顶最大值交换到末尾,再调整堆,重复完成排序。时间复杂度:最优 / 最坏 / 平均 (O(nlog n))空间复杂度:(O(1))不稳定。

2026-05-20 21:00:41 160

原创 线程池学习(四) 实现缓存式线程池

优点线程数动态伸缩,能应对突发高并发空闲线程自动销毁,节省系统资源特别适合 IO 密集型任务,能充分利用 CPU比固定线程池灵活很多缺点逻辑比固定线程池复杂一点,容易出 bug如果任务提交太频繁,会导致线程频繁创建销毁,反而降低性能最大线程数如果设置太大,还是可能把系统资源吃光。

2026-05-19 20:34:24 527

原创 八大排序算法 - 冒泡排序

冒泡排序是最基础的交换类排序,思路简单易懂。原理是相邻元素两两比较,逆序则交换,大数逐步向后沉,小数向前冒,如同气泡上浮。时间复杂度:最优(O(n)) 最坏 / 平均(O(n^2))空间复杂度:(O(1))稳定排序。

2026-05-19 17:20:56 159 1

原创 八大排序算法 - 快速排序

快速排序是分治思想经典排序,实际应用效率极高,属于不稳定排序。基本思想:选一个基准值,把数组分成左小右大两部分,再递归排序左右区间。平均时间复杂度:(O(nlog n))最坏时间复杂度:(O(n^2))空间复杂度:(O(log n))不稳定。

2026-05-18 20:19:35 181

原创 八大排序算法 - 归并排序

归并排序是分治思想代表排序算法,属于稳定排序。核心思路:先拆分、后合并,将数组不断对半拆分至单个元素,再两两有序合并,最终完成整体排序。时间复杂度:最优 / 最坏 / 平均 \(O(n\log n)\)空间复杂度:\(O(n)\)稳定特点:效率稳定,不依赖原始数据顺序,适合大数据量排序。

2026-05-18 19:24:39 145

原创 八大排序算法 - 基数排序

基数排序属于非比较型排序,依靠分配与收集思想完成排序,不依靠元素大小比较。原理:将整数按个位、十位、百位依次排序,从低位到高位逐轮稳定排序,最终实现整体有序,常用LSD 低位优先方式。时间复杂度:\(O(d(n+r))\) d 为最大位数,r 为基数空间复杂度:\(O(n+r)\)稳定排序适用场景:整数、手机号、日期等固定位数数据排序线性排序效率高,数据量大时远超冒泡、插入排序排序稳定,相同数值相对位置不变逻辑简单,容易手写实现。

2026-05-17 22:04:14 157

原创 守护进程编程流程

守护进程编程的核心是“脱离终端、稳定常驻”,其标准7步流程是保障守护进程规范运行的关键:fork创建子进程→setsid脱离终端→二次fork加固→修改工作目录→重置权限掩码→关闭文件描述符→编写常驻业务逻辑。每一步都有明确的设计目的,需严格遵循,避免细节漏洞。对于开发者而言,掌握传统编程流程是理解守护进程原理的基础,而在实际生产环境中,推荐使用systemd管理守护进程,简化开发和运维成本。

2026-05-17 21:52:44 512

原创 项目——基于C/S架构的文件传输系统平台 (1)——重构

也还是,只有做出来才有答案。

2026-05-17 01:06:09 880

原创 linux学习进展 Redis发布订阅 主从复制 缓存 雪崩

负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载。哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个单独的进程,作为进程,他会独立运行。当某个key在过期的瞬间,有大量的请求并发访问,这类数据一般是热点数据,由于缓存过期,会同时访问数据库来查询最新数据,并且写会缓存,会导致数据库瞬间压力过大。数据的复制是单向的,只能从主节点到从节点。

2026-05-16 23:30:50 503

原创 linux学习进展 Redis事务 乐观锁/悲观锁 持久化

允许一次性执行多个命令,这些命令会按顺序串行化执行,在执行过程中不会被其他客户端的命令打断。AOF保存的文件是appendonly.aof。4.备份会自动生成也给dump.rdb文件。:Redis 事务在执行时遇到错误。,会继续执行后续命令!事务日志 + 锁机制。

2026-05-16 20:14:08 482

原创 线程池学习(三) 实现固定线程池

优点逻辑简单易懂,上手最快,适合新手入门学习线程数量固定,系统资源占用平稳,不会突然大量创建线程拖垮程序代码量少,维护简单,稳定性高缺点线程数量固定无法动态调整,任务少时浪费线程资源高并发大量任务堆积时,队列容易积压,处理速度变慢不适合突发大量短时 io 任务场景写完固定线程池之后,彻底理清了线程池最核心的运行逻辑:线程复用、任务队列排队、互斥锁保证安全、条件变量实现休眠唤醒。

2026-05-15 21:20:39 464

原创 linux学习进展 Redis详解

本次笔记系统讲解了Redis的核心知识,从基础认知、Linux环境安装配置,到核心命令、持久化机制、高可用方案,再到实操案例和问题排查,覆盖了Redis新手入门到生产环境应用的全部核心内容,贴合Linux学习的进阶节奏,核心要点总结如下:Redis是高性能内存键值数据库,核心优势是速度快、数据结构丰富、支持持久化和高可用,核心定位是缓存、会话存储、实时统计等场景;Linux环境下,Redis安装有yum和源码编译两种方式,核心是配置redis.conf(绑定IP、关闭保护模式、设置密码、开启持久化);

2026-05-15 20:12:57 521

原创 线程池学习(二)线程池理解

很多人使用线程池时,只知道“创建线程池、提交任务”,却忽略了任务类型,导致线程池配置不合理,性能达不到预期。其实核心逻辑很简单:线程池的线程数,本质是“平衡CPU利用率和任务等待时间”——计算密集型怕CPU过载,所以线程数少;IO密集型怕CPU空闲,所以线程数多。结合我们之前实现的6种线程池,补充适配场景:计算密集型:固定线程池、工作窃取线程池(多核场景下负载均衡,效率更高);IO密集型:缓存线程池、定时调度线程池(如定时网络请求);需要任务顺序/优先级:单线程池、优先级线程池。

2026-05-14 21:26:51 595

原创 linux学习进展 sed awk

sed:行级编辑,核心是“匹配行→执行操作”,常用命令s(替换)、d(删除)、a/i(追加/插入),适合批量修改文本内容,重点记住-i(修改原文件)、-n(静默输出)选项;awk:列级分析,核心是“行→列→处理”,常用内置变量$1、NF、NR,支持条件、循环、函数,适合日志分析、数据统计,重点记住-F(指定分隔符)、BEGIN/END块;区别记忆:sed管“行”,awk管“列”;sed侧重“改”,awk侧重“算”;

2026-05-14 15:40:49 536

原创 线程池学习(一) 理解 进程 线程 协程及上下文切换

进程是操作系统进行资源分配的基本单位。当你启动一个应用程序时,操作系统就会为它创建一个或多个进程。每个进程都拥有独立的地址空间、文件描述符、信号处理函数等资源。工厂有自己的厂房(内存空间)有自己的设备和原材料(文件描述符、网络连接等)有自己的工人(线程)不同工厂之间是相互隔离的,一个工厂出问题不会影响其他工厂线程是操作系统进行 CPU 调度的基本单位,也被称为 "轻量级进程"。一个进程可以包含一个或多个线程,这些线程共享进程的所有资源,但每个线程有自己独立的栈和程序计数器。

2026-05-13 21:47:40 523

原创 linux学习进展 网络编程——HTTPS (补充)

本次补充笔记聚焦Linux环境下HTTPS的实操核心,填补前序理论学习的空白,核心要点总结如下,便于快速记忆和实操应用:HTTPS的核心是“HTTP + SSL/TLS”,通过混合加密机制实现安全通信,解决HTTP明文传输的安全隐患;Linux环境中,OpenSSL是生成SSL证书的核心工具,自签名证书用于测试,CA证书用于公网,私钥权限必须设置为600;Nginx配置HTTPS的关键:启用ssl模块、配置证书绝对路径、开放443端口、设置HTTP自动跳转;

2026-05-13 19:11:05 528

原创 linux学习进展 shell编程

在Linux学习过程中,Shell编程是提升效率、实现自动化运维的核心技能。Shell作为Linux内核与用户之间的“翻译官”,不仅是执行单个命令的交互终端,更是一门简洁高效的脚本编程语言,能够将一系列Linux命令组合起来,实现批量处理、自动化部署、定时任务等复杂操作。无论是后端开发、运维工作,还是日常系统管理,掌握Shell编程都能大幅提升工作效率。本笔记将从Shell基础认知、脚本编写规范、核心语法、实战案例到调试排错,全面详解Shell编程,帮助快速入门并能独立编写实用脚本。在学习Shell编程前,

2026-05-13 14:42:32 537

原创 linux学习进展 守护进程

本文详解了Linux守护进程的核心知识,从概念、特征、手动创建,到systemd管理和问题排查,覆盖了学习和实操的全场景,核心要点总结如下:守护进程是独立于控制终端、后台常驻的系统级进程,PPID为1(被init进程接管),名称通常以d结尾;手动创建守护进程需遵循6步标准流程,核心是“脱终端、稳环境”,重点理解fork和setsid的作用;生产环境优先使用systemd管理守护进程,通过.service文件配置服务,用systemctl命令实现启动、停止、开机自启;

2026-05-12 17:54:31 590

原创 linux学习进展 git详解

本文详解了Linux环境下Git的核心知识,从概念到实操,覆盖了基础操作、进阶技巧和常见问题,核心要点如下:Git的核心是“分布式版本控制”,三大区域(工作区、暂存区、本地仓库)的流转是基础工作流;Linux环境下,Git的安装通过包管理器完成,初始配置需设置用户信息,提升使用效率;基础操作围绕“仓库→修改→暂存→提交→推送/拉取”展开,高频命令需熟练记忆;分支管理、版本回退、stash暂存是应对复杂场景的关键,团队协作需遵循分支规范;遇到权限、乱码、连接、冲突等问题,可按对应解决方案快速排查。

2026-05-12 12:24:24 531

原创 linux学习进展 libevent

libevent是一个用C语言编写的轻量级、跨平台、高性能的事件驱动库,核心作用是封装底层I/O复用机制(Linux下的epoll、BSD下的kqueue、Windows下的IOCP等),为开发者提供统一的事件处理接口,无需关注底层不同系统的I/O复用差异,专注于业务逻辑开发。其核心设计理念是“事件驱动”,即程序不再主动轮询事件,而是由libevent监听事件(如I/O事件、定时器事件、信号事件),当事件就绪时,自动触发预设的回调函数,实现高效的异步处理。

2026-05-11 19:07:50 506

原创 linux学习进展 I/O复用函数——epoll详解(ET,IT模式)

只要fd处于就绪状态(如读缓冲区有数据),每次调用epoll_wait,内核都会重复通知进程该fd就绪,直到进程将数据处理完毕。仅当fd的状态从“非就绪”变为“就绪”时,内核才会通知进程一次,后续即使fd仍处于就绪状态(如还有未读取的数据),内核也不会再通知。对比项水平触发(LT)边缘触发(ET)触发时机fd就绪时,重复通知,直到数据处理完毕仅在fd从非就绪→就绪时,通知一次fd类型要求支持阻塞、非阻塞fd必须使用非阻塞fd数据处理要求可分多次处理,无需一次性读完/写完。

2026-05-11 12:28:06 517

原创 linux学习进展 I/O复用函数——poll详解

无最大文件描述符数量限制:相比select的1024(受FD_SETSIZE限制),poll可以监视更多的fd(数量由系统内存决定,但数量过大性能会下降);接口更简洁:无需维护多个文件描述符集合(读、写、异常),只需一个pollfd数组,事件通过结构体成员设置和返回,逻辑更清晰;事件区分更明确:通过revents返回实际发生的事件,无需像select那样重新检查所有fd的状态,且自动检测错误、挂起等事件。

2026-05-10 22:31:16 581

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除