- 博客(24)
- 收藏
- 关注
原创 数据结构:顺序栈
栈是插入和删除功能受到一定限制的线性表。栈只允许在同一端进行插入和删除操作,遵循先进后出(FILO,First In Last Out)。栈顶:允许插入、删除的一端栈底:不能做增删操作的另一端空栈:不含任何数据元素的栈栈的插入操作叫做入栈 / 压栈;栈的删除操作叫做出栈 / 弹栈。生活中的例子:手枪弹夹。先压进去的子弹,最后才能被发射出来,完美体现先进后出。top(栈顶指针)指向的是最后一个元素的下一个位置(本文全程采用 PPT 这套定义)顺序栈基于连续数组实现,使用动态数组。
2026-10-18 15:15:41
117
原创 数据结构:带头节点双向循环链表
/ 双向链表节点// 双向链表管理结构// 哨兵头节点// 有效元素个数这里head指向一个哨兵节点,它不存储有效数据,仅作为链表的"锚点"。空表时,哨兵节点的prev和next都指向自己,形成自环。
2026-10-18 12:19:52
253
原创 数据结构:不带头节点的链表
// List.h// 节点结构体} ListNode;// 链表管理结构体// 头指针(直接指向第一个有效节点)// 当前元素个数} LinkList;这里用LinkList结构体统一管理头指针和元素个数,GetSize可以做到 O(1) 返回。
2026-10-17 19:50:58
178
原创 数据结构:带头结点的链表
// List.h// 节点结构体} ListNode;// 链表管理结构体// 头节点指针// 当前元素个数} LinkList;这里用LinkList结构体统一管理头指针和元素个数,相比只维护一个头指针,GetSize可以做到 O(1) 返回,避免了每次遍历计数。带头节点的单链表虽然结构简单,但几乎涵盖了 C 语言指针操作的所有基本功:动态内存管理、指针间接访问、边界条件处理。把这套代码亲手敲一遍、画一遍指针变化图,对理解链表乃至后续的双向链表、树结构都大有裨益。
2026-10-17 19:40:30
412
原创 Linux:应用层协议详解
梳理应用层核心协议HTTP、HTTPS、DNS,包含协议分层、报文格式、版本演进、Cookie/Session、HTTPS加密原理,适合后端开发面试复习。
2026-10-11 14:15:35
226
原创 Linux:操作系统基础
(此时如果要让多个程序并行,只能通过操作系统的时间片轮转法,加上快速切换,这样就能够呈现出宏观上看起来是两个程序在同一时间内同时执行,但是微观上,某一个时刻内只有一天执行流在执行,但是这种做法上下文切换开销极大)低沉郭家沟记住微内核思路,将核心最基础的功能放在内核态,但是像是设备驱动,文件系统、网络协议栈这些模块,依然运行在内核态,不在用户态。应用程序想操做硬件,申请内存,必须发起系统调用,让CPU进入从用户态进入内核态,有内核态帮他完成操做,完成之后CPU切换回用户态继续跑应用代码。
2026-09-16 16:40:23
193
原创 C/C++:static关键字
静态变量存储在数据区域,并不放在类中,也不会放在已经实例化的对象的空间之中,存在于整个类的作用域中,但是并不独属于某个具体的实例,是整个类的所有对象所共有的,也就是说这个静态成员变量在成员对象中不占空间,此时这个类除了存放在数据区的静态成员变量并没有任何其它成员,所以四舍五入也算是一个空类,会有1Byte的占位符。在C++中如果一个类是空类,那么这个类会占用一个字节,但是这个字节里面不存储任何内容,这一个字节的作用就是占位。使其变为内部链接,或只在一个文件中定义,其他文件用。为什么会产生这样的结果?
2026-08-09 10:45:43
302
原创 Linux:线程
线程是操作系统能够进行运算调度的最小单位,是进程内的一条执行路径。线程被称为是轻量级进程,在计算机看来进程就是一个PCB结构体,同样的线程就是一个和线程类似的TCB结构体。一个进程至少有一个主线程,多个线程共享进程的:堆内存、全局变量、文件描述符、信号、地址空间线程私有:线程栈、程序计数器、局部变量、寄存器状态并发是交替做,并行是同时做。多线程并发访问共享数据时,最终结果和单线程顺序执行结果一致,没有数据错乱、数据丢失。多个线程互相持有对方需要的锁,又互相等待对方释放锁,无限阻塞、程序卡死。
2026-07-26 15:23:46
211
原创 Linux:进程
我们常说进是系统资源调度的基本单位,是正在运行中的程序,或者说进程是程序的一次执行过程。这些只不过是在用户看来,我们是能在电脑上看到的,但是对于计算机来说他是无法感知进程存在的,在计算机看来程序只不过就是一堆二进制的文件,程序到底是否在执行它并不知道,计算机只认识二进制,基于此人们为了解决这个问题,人们就想到用一个PCB结构体来对进程进行描述,这就像是一件事情的发生是有一个过程的,这个过程旁观者是无法感受的,我们就可以将这个事情发生的过程描述给旁观者听,这样他们就能够知道这件事的存在了。
2026-07-24 18:04:05
211
原创 程序编译过程中,涉及静态链接和动态链接的详细过程
输入:预处理文件(.i文件输出:汇编代码(.s文件)编译器所作的事情:词法与语法分析:检查你的代码有没有拼写错误、少写分号、括号不匹配等。语义分析:检查类型是否匹配,比如你有没有把指针赋给整数。预处理展开:把#include的文件内容直接复制过来,把宏#define替换成真实值。生成汇编代码:将合法的 C/C++ 逻辑翻译成特定 CPU 架构(如 x86_64)能看懂的汇编指令。同时,当编译器遇到这种外部函数调用时,它不知道这个函数在哪。于是它会在汇编代码里留下一个未定义的符号(占位符)。
2026-07-24 15:18:53
173
原创 程序:预处理 编译 汇编 链接 的四个过程
在 Linux 下开发 C 语言程序时,我们习惯了输入一行或者敲一下make,然后程序就跑起来了。但如果报错了(比如经典的),很多新手就会一脸茫然。其实,从你写下代码到程序运行,中间经历了一场精密复杂的“变身”。预处理、编译、汇编、链接。搞懂这四个步骤,你不仅能写出更规范的代码,排查 Bug 时也能一针见血。阶段输入文件输出文件核心工作常见错误预处理.c.i宏替换、头文件展开头文件路径找不到编译.i.s语法检查、转汇编语法错误 (Syntax Error)汇编.s.o转机器码。
2026-07-11 14:18:50
387
原创 面试常考题目:LRU缓存机制超详细解析(附可运行源码)
本文完整实现了基于哈希表 + 双向链表的经典 LRU 缓存,从数据结构选型、核心方法封装到内存管理、边界校验逐一落地。LRU 作为面试高频考点,不仅要能写出代码,更要理解背后的设计思想:利用双向链表维护访问时序,借助哈希表实现 O (1) 级别的查找效率,二者互补达成最优性能。实际开发中,Redis、浏览器缓存等场景都大量运用了 LRU 淘汰策略。吃透这份基础实现,再去学习进阶的 LFU、分段 LRU 等优化方案,也会轻松很多。如果文中有疏漏或者你有更好的优化思路,欢迎在评论区交流探讨。
2026-06-11 21:23:42
200
原创 C++:动态内存分配
内存管理是 C++ 语言的核心特性之一,也是区分高级开发者与初学者的重要标志。动态内存分配允许程序在运行时向操作系统申请和释放内存,突破了静态内存大小固定、生命周期受限的瓶颈,广泛应用于动态数据结构、高性能容器、大型项目开发中。C++ 提供了new/delete关键字实现动态内存管理,同时兼容 C 语言的,但二者在用法、底层机制、安全性上存在本质区别。C语言的动态内存分配在本人博客的C语言专栏中已经发布,本文将主要讲解 C++中的动态内存分配。
2026-06-10 07:30:00
222
原创 数据结构:顺序表
顺序表使用一段物理地址连续的存储单元,依次存储数据元素。顺序表是线性表的顺序存储结构。逻辑相邻的元素在内存地址中也相邻。其实顺序表的本质就是数组,其实现也是依赖数组所实现的。
2026-06-07 17:11:30
259
原创 数据结构:绪论
算法是一个定义良好的计算过程,它接收输入,经过一系列明确的计算步骤,最终产生输出结果。除了需要具备正确性、可读性和健壮性(即面对非法输入时不会崩溃)之外,最核心的指标是它的执行效率。它指的是相互之间存在一种或多种特定关系的数据元素的集合。简单的说,数据结构阐述的就是数据与数据之间的关系。1. 逻辑结构:反映数据元素之间的存在逻辑关系(如一对一、一对多、多对多),它是独立于计算机的抽象数学模型。3. 数据的运算:定义在该数据结构上的一组基本操作(如初始化、插入、删除、遍历等)。二、 数据的四大逻辑结构。
2026-06-06 21:57:32
204
原创 Linux:进程
1.站在用户的角度:进程就是正在运行中的程序2.站在系统角度:进程就是对运行中的程序的动态描述这个描述在linux中就是一个结构体:struct task_struct(又称为进程控制块(PCB))进程ID,其实就是一个数字在linux底下,通过ps指令可以查看进程信息。
2026-06-01 09:18:19
253
原创 C语言:内存对齐与结构体大小
最终:0~8=9Byte,最大对齐数是4,所以整个结构体的大小必须是4的倍数,距离9最近的4的倍数是12,对齐到12Byte,所以结构体最终大小是12Byte。0~5=>6Byte,经过#pragma pack(1)修改,结构体最大对齐数是1,6是1的倍数,所以结构体最终大小是6Byte。当前地址是8,满足要求,是对齐数1的倍数。当前地址是1,满足要求,是对齐数1的倍数。当前地址是1,满足要求,是对齐数1的倍数。0~7=>8Byte,结构体最大对齐数是4,8是4的倍数,所以结构体最终大小是8Byte。
2026-03-22 10:10:54
422
原创 C语言:结构体
结构体的定义使用structint age;float gpa;注意:上面的代码只是定义了一个“模板”,只是一种类型,比如int,char等只是一个类型。
2026-03-21 20:53:28
378
1
原创 C++:引用
swap3是普通的值传递,如果按照swap3函数进行操作,最终会发现两个变量中的数字并未交换,这是因为,按值传递的时候,实质上是将实参复制了一份给了形参,并未对实参进行任何操作,所以,总结下来就会发现,按值传递,对形参的操作,并不会对实参产生影响。因为变量的引用,起的别名,别名和原名虽然不同名,但是二者永远指向的是同一片空间,也不会改变他们指向的空间。7.指针使用sizeof()对其进行计算的时候,得到的是指针变量的大小,而对引用进行操作的时候,sizeof()得到的结果是变量本身的大小。
2026-03-14 13:39:38
396
原创 C语言:指针
p的含义:根据变量p中存储的地址,找到该地址对应的字节,并从这个字节开始,向后获取sizeof(Type)个字节,取出其中存储的值,并给这个值赋予Type的属性。在声明一个变量的时候,系统会给这个变量分配一块内存空间,这片内存空间可能由1个或者一个以上的字节组成的,而这片空间的第一个字节的地址就是这片空间的地址。(存储的这一个字节的地址,就是某一片空间的地址,这片空间的地址就是这片空间中的第一个字节的地址。2.数组指针:数组指针是指,这个指针代表的是数组的指针,即此指针代表的是整个数组的地址。
2025-12-14 19:53:02
336
原创 C语言:分支与循环
必须强制性从第一个if开始挨个判断,相较于if else if else if……如果while循环的代码出现问题人们在修改的时候会很麻烦,控制while循环进行的三个条件可能相隔很远,这个时候用for循环就会更容易一些。2*每个case语句后面都需要加break,因为switch在执行过程中如果遇到匹配的case 首先会运行本条语句然后依次执行后续语句。continue是跳出当前循环,然后重新进入当前循环体的下一次循环,不会终止循环。的能力,让有限的代码可以处理无限的可能。// 条件为真时执行的代码。
2025-12-04 19:19:17
441
原创 C语言:强制类型转换与可变参
在C语言中,char、short等小于int宽度的整数类型,在作为函数参数(如:printf的可变参数)时,会自动提升为int类型(若值能被int容纳,否则提升为unsigned int),所有的小数,都会自动提升为double类型。上述代码中的a只有1Byte,把a传递给printf函数之后a会提升为int,此时只有4Byte,而printf函数要以%lld的形式输出a,而剩余的4Byte则会被赋予一个随机值,因此最终输出的是一个随机值。(2)如果是无符号的类型,则用0补够需要的字节数即可。
2025-12-01 14:54:22
379
原创 C语言:数据类型
signed long long,是8Byte的有符号的整型,由1Bit的符号位和63Bit的数值位组成,其格式控制符为%lld,可表示的整数范围为:-2^63~2^63-1。signed short,是2Byte的有符号的整型,由1Bit的符号位和15Bit的数值位组成,其格式控制符为%hd,可表示的整数范围为:-32768~32767。signed int,是4Byte的有符号的整型,由1Bit的符号位和31Bit的数值位组成,其格式控制符为%d,可表示的整数范围为:-2^31~2^31-1。
2025-11-29 09:13:13
557
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅