自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 【Linux】初步构建框架—虚拟地址空间(二)—mm_struct结构体揭秘与页表标志位

书接上回,我们已经对虚拟地址空间、页表以及“懒加载”机制和COW机制有了一定的认识,本篇文章我们将再次深化理解,并对相关内容进行拓展

2026-05-26 23:28:50 270 1

原创 【Linux】初步构建框架—虚拟地址空间(一)—“懒加载”机制与COW机制的梦幻联动底层逻辑

Linux进程的高效运行,离不开虚拟地址空间、页表、懒加载与COW机制的精妙配合,大家肯定对这些名词相当陌生,但是没关系,今天我们一起一步步拆解这些底层逻辑。

2026-05-26 19:11:28 450 1

原创 【Linux】环境变量概念、作用、配置与修改详解

环境变量究竟是什么呢?它能给我们带来什么样的作用?该如何去配置和使用它呢?接下来为大家详解

2026-05-23 02:54:13 442 4

原创 【Linux】命令行参数详解

本期详解main函数参数的”真面目“以及这些参数发挥的重要作用是什么,它们与Linux下命令选项功能的实现又有上面密切关系?

2026-05-14 02:12:40 334 7

原创 【Linux】Linux2.6 O(1)调度器超详解 | 进程切换+内核链表 | 面试必背

至此,Linux的整个O(1)的调度算法我们讲解到这里形成了一个逻辑闭环,我们对进程调度塑造了崭新的认识!相信大家此时脑海中对Linux的进程调度已经是可以形成一个动态的过程了!

2026-05-11 00:42:13 426 6

原创 【linux】进程优先级

进程优先级的变化范围只有40个梯度,是有限的,它强制我们更改优先级就不能改的太狠了,我们生活中遇到的操作系统基本上是属于分时操作系统,即多个进程轮流占用资源,实现并发的操作系统,有限的优先级变化范围,这样的调度策略,给进程分配时间片,相对公平公正,能够较为均衡地让不同的进程都能在一段时间内,能够得到CPU资源,同时满足人与互联网的需求。1.进程优先级是CPU资源分配的先后顺序,就是指进程的优先权,与权限不同的是,相比于权限的能不能,这些进程已经确定能够得到CPU的资源分配了,只不过是先后的问题罢了。

2026-05-05 16:05:48 423 7

原创 【linux】僵尸进程与孤儿进程

僵尸进程的状态被称为僵死状态,这是一个比较特殊的状态。当子进程结束但是父进程没有接收到子进程退出的返回代码时,子进程就会处于僵死状态。僵尸进程会以终止状态保持在进程表中,并且会一直等待父进程读取退出状态代码,因此,只要子进程退出,父进程还在运行,但父进程没有读取子进程退出状态代码,子进程就会进入僵死(Z)状态。

2026-04-28 21:36:52 426 3

原创 【Linux】进程状态

创建一个进程之后,一般直接就是就绪状态,在调度队列中等待运行,特殊情况比如内存严重不足,会将就绪状态的进程换出到磁盘swap分区,此时称为就绪挂起状态,进入CPU正在运行的进程状态叫做运行状态,每一个进程在CPU中执行都有时间限制,我们把这个叫做时间片,时间片结束后,进程从运行状态重新回到调度队列中变成就绪状态。

2026-03-09 23:19:10 535 4

原创 【Linux】进程——初识fork机制

还是一样的道理,子进程被创建出来后,跟父进程共享同一段代码,id变量同样也会共享,但是它们是两个不同的进程,而一旦有一个进程的变量被修改了被赋值了,就会立即触发写时复制,两边内存彻底分开,相当于此时父子进程都有独立的id变量,一个是0,一个是子进程PID,两个变量,名字一样,地址看起来也一样,物理内存却完全不同。书接上回,我们最后讲到了每一个进程的PID是随着每次重新启动而增大的,当时我们是使用了系统调用接口getpid()得到的,而在Linux当中,新进程往往是通过父进程的方式创建出来的。

2026-02-24 01:07:10 612 1

原创 【Linux】初步理解进程

那就没意义了,其实CPU当中存在一套寄存器,同一时刻,寄存器只装当前正在跑的进程,该进程结束后,要对进程数据的上下文进行保存到PCB当中,然后再执行下一个进程,再保存下一个进程的上下文数据,周而复始,再次执行到相同的进程后,根据其保存的数据锁定上一次运行到的位置,继续执行,再更新数据,CPU内的寄存器硬件,可以在不同时间段,保存不同进程的数据,每一个进程的PCB的内容都是私有的,因此会有很多PCB来同时存储多个进程的数据。没有PCB,操作系统就看不见这个进程,因此有多少个进程,内核就有多少个PCB。

2026-02-23 00:19:45 1008 1

原创 【Linux】实用调试工具—gdb/cgdb的使用

到目前为止,我们已经了解了vim、gcc/g++、make/Makefile、git,已经可以在linux上写代码并编译运行以及提交代码了,但是如果我们在vs下写代码,是不是还需要调试代码,那么在vs下我们该如何对写好的代码进行调试呢?那就是我们接下来要学的调试器—gdb/cgdb。目录一、安装gdb/cgdb二、编写code.c文件和Makefile自动化构建三、debug/release 相关知识四、gdb和cgdb的视觉调试区别五、gbd/cgbd调试语法list(可简写成l)1.list+数字n2.

2026-01-26 01:17:08 763 6

原创 【Linux】自动化构建—make/Makefile

1.首先一个工程的源文件不计其数,其按类型、功能、模块被分类到若干个目录中,makefile能够定义一系列规则来指定哪些文件需要先编译、哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。2.其次makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make指令,整个工程完全自动编译,极大的提高了软件开发的效率。

2026-01-20 21:26:03 786 7

原创 C++中auto的那些“雷区”,仿函数里藏着的类型陷阱

相信大家在写C++排序时经常会使用算法库中sort,但是实际应用中我们很少只对数字进行排序,更多的是对一个封装了多种变量的结构体进行排序,那么此时我们就得要自己定义排序规则,以达到我们的排序目的,于是sort的第三个参数就对我们有了重大意义,可以将我们写好的仿函数放到第三个参数中,达到正确的排序目的,接下来,我会一一讲解我在写仿函数代码时所遇到的问题。这是语法所不允许的,尤其是仿函数,它是用于STL库或者算法库的参数的,需要明确参数类型才可以编译,auto本质上并不是明确的参数类型,因此会出现编译报错。

2025-12-29 21:26:45 325 4

原创 Linux编辑器—vim的使用

本期来讲解Linux中常用且高效的编辑器vim的基本使用和指令操作。

2025-12-13 22:35:34 1449 7

原创 算法二:滑动窗口

上篇文章详细讲解了双指针各种场景的运用,相信大家对双指针都有了一定的了解,本篇文章我们再来了解另一种特殊场景的双指针,该场景为左右指针共同维护一段连续的区间,通过特定情况改变左右边界使该区间不断变化,最终得到我们想要的结果,我们把这个方法称为——滑动窗口。同样的,我们将通过八道题来对该算法进行场景详解。

2025-12-09 21:50:05 841 6

原创 算法一:双指针

本篇详细讲解双指针的各类题型使用场景,以下为八道相关的题目,均会进行详解。(每道题均存在多种解法,此篇仅讲解双指针法)

2025-11-27 16:25:45 833 10

原创 C++11——Lambda表达式的用法

算法思路:先用unordered_map把每个数字出现的次数记录下来,然后利用迭代器初始化把无序图的数据初始化给vector,再调用算法库里的sort对vector进行排序,但是由于图的映射关系,第一个数对应的是元素,第二个才是对应出现的次数,因此如果不自己指定排序规则,则最后排序是按照第一个数进行排序的,得不到我们想要的结果,如果没学过lambda表达式,我们一般会想到用仿函数来做模板第三个参数,但此时我们直接用Lambda表达式即可简化代码,最后排序好了之后利用for循环打印出前k个元素即可。

2025-11-01 21:37:21 924 6

原创 详解STL中stack_queue为什么选择deque作为默认容器

vector的元素在内存中是完全连续的,而deque是由多个分散的“内存块”组成,这会造成哪些劣势呢,首先vector的随机访问是真正的O(1),直接通过首地址+偏移量计算,deque虽然也支持随机访问,但是底层实现上需要先计算元素在哪个内存块,再找块内的偏移量,实际效率略低(尤其是数据量巨大时),且vector的CPU缓存命中率更高(连续内存适合CPU预读),遍历速度通常比deque快。,这是优于vector的点,而list还得申请结点(带两个指针的额外内存),内存碎片多,开销更大,而。

2025-09-29 23:28:07 1247 13

原创 C++函数模板详解

函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。

2025-09-29 19:01:04 1028 5

原创 初识string

(空串)");3.string s3(s2) (拷贝构造)第四种方法是将s2的字串给给s3,从下标为1的位置开始往后获取4个字符给s4,也就是说s4为ello,第三个参数有缺省值,不提供也可以,从第一个位置开始往后到结尾的字串都会给给s4(参数给负数或者大于s2长度的数也能达到同样的效果)给定一个const char*类型的字符串,将它的前n个字符给给s5,便如以上操作,如s5的字符串为hello(s6为十个#的字符串)

2025-09-12 21:14:15 887 6

原创 new/delete的原理以及和malloc/free的区别

1.malloc和free是标准库函数,行为固定,不可重载,new和delete属于操作符,operator new/operator delete可以被重载(全局或类内重载),能自定义内存分配逻辑。4.malloc的返回值为void* ,在使用中必须强制转换类型,存在类型安全差异,而new不需要,因为new后直接跟的是空间的类型。2.malloc申请空间时,需要手动计算空间并传递,new只需要在其后跟上空间的类型即可,如果时多个对象,[]中指定对象个数即可。会调用析构函数完成空间中资源的清理释放。

2025-09-04 03:08:42 333 4

原创 数据结构之八大排序算法

第一种直接选择排序是由首元素一一与后面的元素对比,把小的依次排到前面,从而达到升序的效果。这种是只把最小的数找出来放前面,那么是否能够找小的同时也找大的放在后面以提高排序效率呢?前面的快排使用了递归的方法以找基准值的方式排序,以下不再使用递归的方式,但是要借助一种数据结构——栈(栈功能在之前实现过了,这里直接使用,在文章末尾也会附上栈的实现代码)前四的排序算法在排序十万个数据的情况下仅仅需要十毫秒以内,从InserSort开始就需要至少1秒的排序时间,排在最后的BubbleSort甚至需要接近10秒。

2025-06-26 16:06:45 436

原创 二叉树OJ——递归的暴力美学

递归的暴力美学

2025-06-22 17:44:15 1462

原创 链式二叉树

二是最后一层的结点从左往右顺序依次排列。如果取队首结点取到了NULL,则结束循环,开始第二次循环,循环条件与第一次相同,如果二次循环取队首结点取到了非空结点,则可以判断不是完全二叉树,因为结点不是从左往右顺序分布的,如果取到NULL,则继续循环,直到队列为空都没有取到非空结点,则可以判断该二叉树是完全二叉树。初始化队列后将根结点放入队列,只要队列不为空就开始循环,取队首结点并打印,然后结点出队,如果该根结点的左右孩子不为空,则将其孩子也放入队列中,重复以上操作,全部打印并出队后,完成遍历结束循环。

2025-06-21 16:02:50 514 1

原创 二叉树之堆结构

从初步认识堆到能够构建堆,完成堆排序,并利用堆的思想解决TOP-K问题

2025-06-20 13:37:24 1097 1

原创 栈和队列代码实现及OJ

思路概括:运用数据结构——栈,遍历字符串,若是左括号则入栈,如果是右括号,则与栈顶的左括号匹配,如果匹配成功,栈顶的左括号出栈,更换新的栈顶,字符串也继续向后遍历,进行新一轮的比较;出栈:要用两个队列实现栈功能,我们知道队列满足先进先出,而栈是先进后出的,假设往一个队列里入队1、2、3、4,正常情况下出队也是按照相同的顺序,但是我们要实现先进后出的栈,因此4必须先出来,所以我们就要借助第二个队列,将前面三个数也就是前面size-1的数入队到第二个空队列中,然后剩余的一个保存后出队,最后返回保存的数即可。

2025-05-09 20:15:49 1619

原创 双向带头循环链表(双向链表)的实现

接下来会有一个误区,初学者可能会在这个时候直接令*pphead指针中的prev和next指向自身来完成初始化,因为此时还未申请空间,这会导致空指针的解引用从而引起空指针异常。直接传一级指针,保证窗口的统一性,然后循环遍历进行销毁操作,但是发现最后会剩下一个头节点无法销毁,因为传的是一级指针(plist的“值”而非“址”),因此调用完销毁函数之后,还得单独对plist进行处理,手动将它置空(plist = NULL),销毁后的plist也将不再使用。相比之下,第二种方法是较为合适的。因此个人较为推荐方法二。

2025-05-03 17:46:24 564

原创 链表基本功能实现+链表oj(下)

碾压链表OJ的视觉盛宴

2025-05-02 13:54:21 1834 2

原创 链表基本功能实现+链表oj(上)

【代码】链表基本功能实现+链表oj(上)

2025-04-30 09:26:36 190

原创 顺序表基本功能的实现 — 纯代码

【代码】顺序表基本功能的实现 — 纯代码。

2025-04-29 21:48:37 315

原创 如何合并两个有序数组?

和方法一相同的是,也会出现其中一个数组先遍历结束的情况,但不同的是,由于这是在num1上“原地”修改,如果是num2先遍历结束,是不是就意味着num2中的元素已经全部插入num1中并且排好序了?因此需要考虑其中一个数组遍历结束后另一个数组的剩余元素未插入到新数组的情况,此时就需要再单独使用两个while循环将num1或者num2剩余的元素放入新数组newnums中,就初步完成了数组的合并,最后将newnums中的所有元素移回num1数组中即可,别忘了free掉newnums的空间并且置空(NULL)。

2025-04-29 19:43:12 483

原创 比特为始,努力为剑,奋而求上

我个人是比较喜欢自学的,因此刚入学我就开始在b站寻找各种C语言的网课,在结合学长学姐的推荐下,我首次接触了比特——鹏哥C语言,对比了其他网课,鹏哥的课程给我的第一印象是 哇靠一节课居然有三个小时这么长!深入浅出通俗易懂,还涉及到了很多在校老师都不会讲的但是有很重要的知识点,也不是质疑学校的老师专业水平,只是一学期就这么几节课,根本讲不了太多内容,只能自己额外找时间尽量多学一点,现在是大一下学期,也是我正式入学比特的时间,我开始重视自己的学业,打算好好学,全部系统的学一遍。

2025-04-24 14:36:06 301

空空如也

空空如也

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

TA关注的人

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