- 博客(71)
- 收藏
- 关注
原创 MVCC机制
1.MVCC = 多版本并发控制,核心是“读写不冲突、不阻塞”;2.3个核心组件:数据隐藏字段(版本标记)、undo log(旧版本仓库)、Read View(阅读权限);3.读旧数据不是错误,是事务隔离的正常行为,保证事务内数据一致;4.MVCC不保证写安全,先读后改会覆盖别人数据,需用加锁、原子更新、乐观锁解决;5.undo log不仅用于回滚,更是MVCC的核心,没有undo log就没有MVCC。
2026-05-06 14:26:48
371
原创 C++怎么实现多态
有虚函数的类中会有一个隐藏指针 vptr,指向该类的虚函数表 vtable,vtable 是一个函数指针数组,存放该类所有虚函数地址。调用虚函数时,编译器生成代码从对象取 vptr,再在 vtable 的槽位中找到函数地址并间接调用,从而在运行期决定调用哪个版本。通过基类指针删除派生类对象时,如果基类析构函数非 virtual,会导致只调用基类的析构函数,而不调用派生类的析构函数,导致资源泄露。编译器根据函数参数的类型或数量,直接把函数调用链接到具体的函数地址,无需继承和虚函数。,派生类重写了该虚函数。
2026-04-16 16:08:08
759
原创 给 key 配了 TTL 结果还没消失,“所以 Redis 是到点立刻删,还是访问时才删?”
Redis 的过期时间 Redis 可以给 key 设置,常见命令有EXPIREPEXPIREEXPIREATSET EX等。在Redis 内部会额外维护一张过期字典,记录哪些 key 配了过期时间以及具体过期时间点,只有设置了 TTL 的 key 才会进入过期策略机制。就是“访问时才检查”。当客户端读取或操作某个 key 时,Redis 会先判断这个 key 是否已经过期:如果没过期,正常返回;如果已经过期,先删除,再返回空结果。优点:对 CPU 很友好,不会主动大面积扫描。
2026-04-15 10:14:32
338
原创 MYSQL:执行SQL语句
经过解析器后,接着就要进入执行 SQL 查询语句的流程了,每条SELECT查询语句流程主要可以分为下面这三个阶段:prepare 阶段,也就是预处理阶段;optimize 阶段,也就是优化阶段;execute 阶段,也就是执行阶段;
2026-03-24 17:38:36
316
原创 TCP与UDP的区别
TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)都是 TCP/IP 协议栈中传输层的核心协议,负责在主机之间为应用层提供端到端的通信。下面我将从相同点、是否面向连接、数据传输方式、是否可靠、传输效率、应用场景这六个方面展开详细讲解。
2026-03-24 17:01:30
406
原创 STL:deque
每个 block 是一段连续内存(比如 512 字节)map → 多个连续小块 → 拼起来像连续。如果到块末尾 → 跳到下一个 block。[块][块][块][块]cache 不如 vector。不够 新开一个 block。每个 block(缓冲区)头部还有空间 直接插。数据不是一整块连续内存。两端插入删除 O(1)迭代器复杂(容易失效)
2026-03-20 10:18:36
158
原创 左值引用和右值引用
必须绑定左值一旦绑定不能改绑修改引用 = 修改原变量int a = 10;int& r = a;r = 20;cout << a;// 20不能绑定右值// 错误因为:右值是临时变量,马上销毁引用它会变成悬空引用专门绑定右值可以修改临时对象延长临时对象生命周期r = 20;// 合法。
2026-03-19 14:23:08
32
原创 STL:map与unordered_map
map特点:自动按 key 排序(默认升序)插入后依然保持有序输出顺序:1 2 3元素位置由 hash 函数决定输出顺序(不确定):2 3 1(可能是任何顺序)
2026-03-19 13:31:57
393
原创 详解socket
最简洁定义Socket 是网络通信的端点(endpoint)。两个程序(进程)通过各自的 Socket 建立连接,从而在网络上双向交换数据。类比解释(最常用且形象的比喻):Socket 就像电话插座或电源插座一端(服务器)创建一个“插座”并绑定到特定端口(相当于固定插座位置)。另一端(客户端)“插入”这个插座(通过 IP 地址 + 端口找到它)。连接建立后,两端就可以像打电话或插上电器一样进行数据传输。
2026-03-09 19:24:46
414
原创 详解socket网络编程
Socket 网络编程是计算机网络领域中最基础且核心的编程范式之一,其核心思想源于“端到端通信”的抽象模型。它将复杂的网络协议栈(主要基于 TCP/IP)封装为统一的编程接口(API),使得应用程序无需关心底层物理链路、路由、数据链路等细节,即可实现进程间的跨主机数据交换。以下从概念起源、抽象模型、核心机制、编程流程以及关键思想等方面进行系统详解。
2026-03-09 19:24:35
469
原创 详解libevent
单线程 reactor 模型(默认)事件对象与 event_base 解耦:事件可动态增删持久化(EV_PERSIST)是最常用模式,避免频繁创建/销毁事件回调中不要阻塞:保持回调快速返回是高并发关键资源管理严格:谁创建谁释放,顺序不可颠倒。
2026-03-09 17:28:30
429
原创 0-1背包问题(回溯法)
不选 选 不选 选。物品3 物品3 物品3 物品3。不选 选。物品2 物品2。选 1 + 2 → 重量 4,价值 35。每一条从根到叶子的路径 = 一种方案。(这就是 “01” 的由来)只选 3 → 价值 30。讲解 DP 推导的“母体”叶子节点 = 一种完整选择。回溯 = 在这棵树上。深度优先搜索(DFS)树深度 = 物品个数。所以整个问题就是一棵。
2026-02-08 21:57:11
325
原创 数组快排 链表归并
左边 <= 5 | 5 | >= 5 右边。(STL sort 的核心思想之一)对左边 [3,1,4,2] 再做快排。:用快慢指针把链表从中间断开。原地排序(不需要额外数组)执行完一趟后,5 会到。对右边 [6] 不用排。:递归排序左右两条链表。合并链表天然 O(n)
2026-02-06 23:21:49
355
原创 线程是什么
资源的容器(内存、文件、socket、页表……):真正“干活”的执行单位一个进程里,也可以有多个线程。用户线程完全由进行管理,内核(操作系统)完全感知不到这些线程的存在。内核只看到一个单线程的进程。归属用户程序(如 Java 的早期 Green Threads, Go 的 Goroutines)。。因为线程切换发生在用户态,不需要进行复杂的系统调用(Context Switch 到内核态)。由程序自定义,灵活性高。如果一个用户线程发起了阻塞式系统调用(如等待 I/O),整个进程都会被挂起。
2026-02-06 22:51:43
450
原创 define typedef inline
inline是先将内联函数编译完成生成了函数体直接插入被调用的地方,减少了压栈,跳转和返回的操作。而define用于定义宏,而宏也可以用于定义常量。不分配内存,给出的是立即数,有多少次使用就进行多少次替换。定义的常量,运行时是直接的操作数,并不会存放在内存中。对编译器的一种请求,编译器有可能拒绝这种请求;,只是简单的字符串替换,无类型检查,不安全。语言中是存储在内存中、需要额外的内存空间的;内联函数是一种特殊的函数,会进行类型检查;只是简单的字符串替换,没有类型检查。有对应的数据类型,是要进行判断的。
2026-02-06 22:39:37
178
原创 程序编译链接过程
编译(语法 + 语义 + 优化)从汇编 → 机器码(二进制)const / 引用 / 指针规则。链接时:去 libc 里找真正实现。里:不知道 printf 在哪。把整个头文件内容原地复制进来。| 预处理(文本替换)架构绑定(x86 / ARM),不懂 C++ 语法,只认。,不包含预处理、不包含链接。把 IR → 特定架构汇编。库代码直接拷进可执行文件。只管“像不像合法单词”所以编译器会生成一种。与 CPU 架构无关。链接后:把地址填进去。
2026-02-05 22:13:24
793
原创 算法:二叉树最大路径和
当一个节点(比如 root)向它的父节点汇报工作时,它不能把“左+根+右”这个像拱桥一样的路径汇报上去。我们需要每遍历到一个节点,就计算一下以它为“拐点”的路径和是否比当前的全局最大值 ans 还要大。= root->val + max(左子树能提供的最大单边路径, 右子树能提供的最大单边路径)。max(2, 3) + 1 = 4 (这意味着如果 1 还有父节点,它会汇报 4)。temp (汇报给父节点) = $0 + 0 + 2 = 2$。temp (汇报给父节点) = $0 + 0 + 3 = 3$。
2026-01-31 21:41:03
172
原创 malloc底层实现
malloc它向操作系统brk / mmap),然后在把这些内存。从你调用malloc开始发生了什么?malloc,绝大多数是用户态完成的。heap是 malloc 主要活动区域由brk()sbrk()扩展。
2026-01-31 21:27:20
545
原创 auto和decltype的区别
1. 如果表达式是**变量名** → 返回该变量的声明类型(包括 const 和引用)// decltype(auto) - 用 decltype 的规则推导 auto。auto 让编译器根据**初始化表达式**自动推导变量类型。3. 如果表达式是**将亡值** → 返回 `T&&`2. 如果表达式是**左值** → 返回 `T&`4. 如果表达式是**纯右值** → 返回 `T`在返回值类型推导中的协同使用 (C++14)auto 遵循**模板参数推导规则**auto在函数返回值中 (C++14)
2026-01-28 20:39:14
72
原创 C++-集群聊天室(1):Json
Protobuf 必须先编写.proto协议文件(定义数据结构),再通过工具生成对应语言的代码,才能序列化 / 反序列化。
2026-01-28 16:04:07
568
原创 算法:四数相加||
题目(四数相加 II)本质是:给你 4 个数组 A、B、C、D统计有多少个四元组满足数组长度一般 ≤ 200暴力 4 重循环是O(n^4)→。
2026-01-25 21:28:12
107
原创 详解哈希表
冲突元素在表内寻找下一个空位置(线性探测、二次探测、双重哈希)每个桶存储一个链表或其他数据结构(如平衡树)。实现的数据结构,用于快速存储和查找数据。将 key 映射成数组的索引 (0 到 N-1)插入时将元素加入链表尾部或头部。所有元素存储在数组中,不用链表。不同 key 可能映射到相同的索引 →。:最坏情况退化为链表,查找 O(n)。查找时在链表中遍历。:尽量让 key 均匀分布到各个桶。:相同 key 必须映射到相同位置。:通过 key 快速查找复杂对象。:每个桶用链表存储所有冲突元素。
2026-01-25 20:11:32
322
原创 进程与线程
它是进程重要的组成部分,它记录了操作系统所需的、用于描述进程的当前状态和控制进程的全部信息。线程可以看做轻量级的进程,同一个进程内的线程共享进程的地址空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。是指组成进程的程序和数据所在内存或外存中的首地址,以便在调度该进程时能从其PCB中找到相应的程序和数据。每个进程拥有独立的地址空间,地址空间包括代码区、数据区和堆栈区,进程之间的地址空间是隔离的,互不影响。为了描述进程间的家族关系,通常还设有父进程标识和子进程标识,以表示进程间的家族关系。
2026-01-25 18:13:48
596
原创 详解redis(17):缓存穿透
一种快速判断“某个元素是否存在”的概率型数据结构特点:说“没有” → 一定没有说“有” → 可能有工作流程请求来了↓Bloom Filter 判断↓不存在 → 直接拦截↓存在 → 查 Redis / DB把绝大多数无效请求挡在缓存之前三、参数校验ID 是否合法范围是否合理。
2026-01-25 15:20:32
76
原创 算法:最长回文子串
中心扩散法是一种高效求解最长回文子串问题的算法,其时间复杂度为 O(n²),其中 n 为输入字符串的长度。该方法基于回文串的对称性原理,通过从每个可能的中心点向两侧扩展来检测回文子串,从而避免了暴力枚举所有子串的低效性。下面,我将从原理、算法步骤、代码实现、复杂度分析以及示例演练等方面进行详尽阐述。
2026-01-25 15:20:16
273
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅