- 博客(44)
- 收藏
- 关注
原创 进程(7)命令行参数与环境变量
本章主要介绍了Linux系统中的命令行参数和环境变量相关内容。命令行参数包括argc和argv,用于实现命令的不同功能选项;环境变量PATH则决定了系统查找可执行文件的路径。通过export可将本地变量转为全局环境变量,环境变量具有全局性,会由bash传递给子进程。此外还介绍了通过main函数参数、environ变量和getenv系统调用获取环境变量的方法,以及如何修改环境变量配置。这些机制共同构成了Linux系统命令执行和进程运行的基础环境。
2025-12-26 16:27:59
811
原创 进程(6)进程切换,Linux中的进程组织,Linux进程调度算法
本文介绍了Linux操作系统中进程管理的三个核心内容:进程切换、进程组织和调度算法。首先阐述了进程切换的本质是CPU上下文切换,通过保存和恢复PCB中的上下文数据实现。其次详细讲解了Linux采用独特的双向链表结构组织进程,通过list_head封装指针域提高可扩展性和复用性。最后分析了Linux的O(1)调度算法,使用优先级数组和位图结构实现高效进程调度,并采用活跃/过期队列轮转机制。这些机制共同构成了Linux高效进程管理的基础。
2025-12-23 11:36:30
605
原创 进程(5)孤儿进程,优先级PRI和nice值
本文主要介绍了Linux进程管理的三个核心概念:孤儿进程、优先级与nice值,以及进程特性。当父进程提前退出时,子进程会被操作系统托管成为孤儿进程,防止内存泄漏。进程优先级(PRI)和nice值(NI)共同决定调度顺序,其中PRI范围60-99(默认80),NI范围-20到19,通过公式"新PRI=旧PRI+NI"调整优先级。文章还区分了进程的四个特性:竞争性(资源争夺)、独立性(互不干扰)、并行(多CPU同时执行)和并发(单CPU分时切换)。最后指出频繁修改nice值可能导致进程饥饿问
2025-12-21 17:45:33
706
原创 进程(4)操作系统进程状态与linux进程状态
本文介绍了操作系统中的进程状态概念,重点对比了学科理论状态与Linux实际实现状态的区别。理论部分阐述了运行、阻塞和挂起三种基本状态,其中挂起状态涉及内存与磁盘间的数据交换。Linux实现部分详细解析了7种具体状态:R(运行)、S(可中断睡眠)、D(不可中断磁盘睡眠)、T(暂停)、t(跟踪停止)、X(死亡)和Z(僵尸)。特别说明了S状态与阻塞状态的对应关系,以及D状态对磁盘IO的保护机制。文章还穿插介绍了前后台进程的运行特点,通过代码示例展示了状态转换过程。
2025-12-17 18:41:57
526
原创 进程(3)创建进程与fork系统调用详解
本文介绍了Linux进程管理的三个核心内容:1) getpid和getppid系统调用用于获取当前进程及其父进程的PID;2) 进程工作目录(cwd)的概念及其修改方法;3) fork系统调用的原理和使用。重点阐述了fork的独特行为:一次调用产生两个返回值,分别返回给父进程(子进程PID)和子进程(0),并通过写时拷贝技术实现数据隔离。文章通过实例演示了这些系统调用的实际应用,为理解Linux进程创建和管理机制提供了基础。
2025-12-16 14:30:38
884
原创 进程(2)进程概念与基本操作
本文介绍了Linux系统中进程的基本概念和组成结构。主要内容包括:1) 进程与程序的区别,进程由PCB、地址空间、页表等组成;2) Linux中描述进程的task_struct数据结构,包含标识符、运行状态、优先级等关键字段;3) 查看进程的两种方法:ps命令和/proc目录;4) 通过getpid()系统调用获取进程ID的实际示例。文章通过对比理论概念与实际实现,帮助读者理解Linux进程管理的核心机制。
2025-12-15 14:42:22
744
原创 进程(1):冯诺依曼体系架构(数据信号部分)+操作系统概述
本文摘要: 本章主要介绍了计算机体系结构中的两个核心概念:冯诺依曼体系架构和操作系统。首先阐述了冯诺依曼体系的基本组成(CPU、存储器、输入/输出设备)及其工作原理,重点解释了内存作为存储器的必要性,包括存储分级、速度匹配和效率优化等问题。然后讨论了操作系统的基本概念,指出其作为管理软硬件资源的核心软件,通过"先描述再组织"的方式实现管理功能,并通过系统调用和封装接口为用户提供使用环境。文章还通过具体实例说明了计算机间数据传输过程以及操作系统为用户提供的不同层次接口。
2025-12-13 14:40:04
959
原创 gdb常见调试技巧
本文介绍了三种GDB调试技巧:1)使用watch观察变量值变化,适用于检测意外修改的情况;2)通过set var在调试中直接修改变量值,避免反复修改源代码;3)条件断点的两种设置方式,包括直接设置条件断点和给已有断点添加条件。这些方法能有效提升调试效率,帮助开发者快速定位问题。文章采用CGDB演示,指令与GDB相同但提供更直观的代码显示。作者表示未来将保持技术热情,持续产出更精炼的技术文章。
2025-12-13 11:29:30
355
原创 Linux基础开发工具完全指南:从入门到实战
通过掌握这些基础开发工具,你可以建立高效的Linux开发环境:环境准备:使用yum/apt安装所需工具代码编辑:使用Vim高效编写代码编译构建:使用gcc编译,Makefile管理构建过程版本控制:使用Git管理代码变更调试排错:使用GDB定位和修复问题进度展示:实现友好的用户界面
2025-11-23 16:02:32
577
原创 Linux初步认识与指令与权限
1.Linux初步认识2xshell远端登入3.Linux指令3.1shell命令及其运行原理4.Linux权限
2025-08-02 20:23:24
1197
1
原创 红黑树的实现
本章主要介绍了红黑树的实现。红黑树是一种平衡二叉搜索树,通过颜色控制平衡,确保每条路径上的黑色结点数量相同,从而保证最长路径不超过最短路径的两倍。红黑树的规则包括根节点为黑色、结点颜色为红或黑、红结点的子结点必须为黑等。红黑树的插入操作在二叉搜索树的基础上维护颜色平衡,分为变色、单旋转+变色和双旋转+变色三种情况。红黑树的效率为O(logN),与AVL树相比,旋转次数较少。红黑树的结点结构在二叉搜索树的基础上增加了颜色属性,插入时根据父结点和叔叔结点的颜色进行相应调整,确保树的平衡性。
2025-05-18 13:59:17
684
1
原创 二叉搜索树的实现与应用场景
1.二叉搜索树的概念2.二叉搜索树的性能分析3.二叉搜索树的实现4.二叉搜索树的key/key-value的实现场景。
2025-04-26 21:21:59
813
原创 多态以及多态底层的实现原理
1.必须是基类的指针或者引用去调用虚函数2.虚函数必须完成了重写或者覆盖因为我们前面所将的切片的类型兼容转换,只有基类的指针或者引用才能即指向基类对象又指向派生类对象.虚函数的重写或者覆盖所指的是它的实现重写,这样基类和派生类才能有不同的函数.才能实现多态.class Apublic:public:int main()ptr1->a();ptr2->a();return 0;以上就是多态的实现.
2025-04-22 13:12:26
893
1
原创 继承与菱形继承模型(虚基表演示)
在前面我们了解过有关于函数的复用,这一点无论是在c或者c++中都非常的常见,而对于三大面对对象特性之一的继承,更是一种复用,只不过它是在类设计的复用.我们可能会在实际的工程中设计中大量的相似的类,为了减少重复代码的冗余,我们可以使用继承,对于使用继承产生的新类,我们管他叫做子类或者派生类,对于被继承的叫做父类或者基类.我们在派生类增加新的成员变量与成员函数.public:protected:// 姓名private:int _age;protected://学号。
2025-04-20 15:05:32
837
原创 适配器stack和queue的实现及双端队列deque的原理
适配器是一种设计模式,设计模式是经过长期实践的经验总结.它的本质是将一个类的接口,转换为另一个类的接口.在之前我们实现栈和队列的底层的时候,我们使用的是数组和链表来实现它们的增删改查.但是在stl中,我们可以用vector和list来进行转换成stack和queue的形式.
2025-04-16 11:27:48
858
原创 list的使用以及模拟实现
int b;:a(a),b(b)假设我们有这么一个类.我们对这个类list<C> c;while (it!我们要访问struct的成员变量的时候,如果这个类没有实现它的流插入流提取运算符重载.我们需要主动取访问它的内部的变量去间接访问.我们可以提前再迭代器实现->去直接访问它的内部的成员变量.再这里也存在const对象的问题.我们仍然需要传一个模板参数.具体参考代码。
2025-04-10 21:32:17
986
3
原创 vector的使用即模拟实现
i++)在这里面我们并没有用memcpy,我们采用的是一个一个拷贝,因为自定义类型会调用它的赋值运算符重载,完成深拷贝,而memcpy是浅拷贝.
2025-04-08 10:51:53
814
原创 双向链表增删改查的模拟实现
0.双向链表的基本结构1.双向链表的初始化2.头插尾插3.头删尾删4.查找与打印5.在指定位置之前插入数据/在指定位置之后插入数据6.在指定位置之前删除数据/在指定位置之后删除数据7.销毁链表
2025-04-05 17:32:52
729
原创 链表的增删改查的模拟实现
0.链表的基础结构1.头插尾插2.头删尾删3.查找4.在指定位置之前插入数据/在指定位置之后插入数据5.删除pos结点的数据/删除pos结点之后的数据6.销毁链表
2025-04-05 12:11:49
1084
原创 string的模拟实现
string的模拟实现成员变量构造析构.迭代器,遍历相关插入删除相关字符串相关关系操作符的重载构造与赋值运算符重载随机插入和删除查找以及截取字串相关流插入流提取相关
2025-04-01 14:43:58
1106
2
原创 string常见的接口使用(3)
1.Element access类的接口2.Modifiers类的接口3.String operations类的接口。
2025-03-22 20:22:41
1242
原创 stl介绍与string容器常见接口的使用
sti是标准模板库,是c++标准库的重要组成部分.它不仅是一个模板库,更包含各种数据结构和算法.对于stl来说.从它发布至今,已经有许多版本,最早的开始的是有惠普实验室研发,并开源的.最后纳入c++标准之中.允许修改,并且商用.但是唯一的条件是它们如果做出有效的修改,也一定要开源.stl随着多年的迭代更新已经有了许多不同的版本对于我们现在所使用的环境vs22来说,它的底层采用的是jp版本的由P. J. Plauger开发,继承自HP版本.被微软采用.而我们平常学习的是SGI版本。
2025-03-20 12:11:03
955
原创 C++的内存管理及初识泛型编程(模板)
对于c++和c的内存管理的方式,二者在内置类型上并无区别,但是对于c来说,自定义类型的内存管理,初始化的方式就非常困难,而c++的delete和new就能解决这个方式.class Apublic:: _a(a)~A()private:int _a;定义一个类A对于上四者来说,第一个只会申请空间,对于第二个,它会在给a分配空间的同时去调用默认构造,对于第三个来说,它会用三去调用它的构造函数,对于第四个,它它会给这个块连续的空间调用5次构造函数,并且最后一种也支持用花括号进行初始化.
2025-03-19 13:57:16
654
原创 类和对象的拓展补充及默认成员函数(取地址重载和const成员函数)
根据两个的运算符重载来看,他们都返回了一个istream和ostream类型的引用.如果我们这个函数直接写在类里面就会导致它的第一个参数是this指针,而根据运算符重载的规则,对于二元操作符来说,它的第一个操作数对应的是左操作数,第二个操作数对应的是右操作数.那么我们就会在调用的时候相反了变成了。4.c++11支持在成员变量声明的地方给缺省值,这个缺省值主要是给没写在初始化列表的成员变量进行初始化的,如果在初始化列表写了,就会用显示写的那个,而不用声明给的.
2025-03-13 22:31:13
1097
原创 默认成员函数(运算符重载和赋值运算符重载)
当进行自定义类型比较,加减乘除等操作的时候,如果我们直接使用+,-等操作符的时候,就会发生歧义.一个自定义类型里有很多成员,那我们究竟是对什么进行加减,赋值操作呢.为了解决这个问题,c++提出了运算符重载,用operator关键字加上操作符的特殊函数,对原先的操作进行重新的定义.让它具有新的含义从而可以使自定义类型进行上述操作。2.运算符重载的函数的参数列表应该和该运算符的操作数一致,对于二元及以上的运算符来说,它的参数从左往右,第一个参数对应第一个操作数,第二个参数对应第二个操作数.
2025-03-10 21:26:16
570
2
原创 tihs指针和类的默认成员函数(构造,析构,拷贝构造)
在前面的类的内存大小的地方,我们提到,类的成员函数,会存储在一个公共代码段中,当去调用成员函数的时候,公共代码上函数会通过汇编转换为指令,这个函数第一行指令的地址就是这个函数的地址,通过这个地址去调用成员函数.同一个类里不同对象调用的成员对象实际是一个函数,7.我们解释下为什么拷贝构造传值是语法上的无限递归,当我们传值调用拷贝构造,用其他对象进行初始化的时候,自定义变量作为形参,还需要调度拷贝构造,此时就把这个d传给下一个拷贝构造的d,循环往复,就像是击鼓传花,但永远都不会停下一样.
2025-03-08 22:07:24
832
3
原创 归并排序(包括文件外排序)与计数排序
我们不妨定义这个数组的大小为最大值-最小值+1,+1是因为数组索引的特性原因,它和实际的个数总是差一,遵循不对称原则.这样即使再这期间有没有出现的元素,空间上的浪费也要好于第一种.而当我们需要这个元素的时候,只需要当前元素的索引+最小值即可,这个数组就是一个映射出来的.feof也可去定义两个变量去接收输入函数的返回值.再这个数组中1出现了3次,2出现了1次,3出现了2次,4出现了一次,7出现了一次,9出现了两次.我们再按照顺序放回到原数组中,1,1,1,2,3,3,4,7.9,9,这样就排好序了.
2025-03-06 10:35:33
963
原创 类和实例化对象
类用class定义,后接{},同时还有;,不能省略.类的定义与结构体定义相似.类中可以定义成员,叫做类的属性或者成员,相对于c中的结构体,它可以再其中定义函数.c++中的struct,也可以定义类,再c++中struct定义的变量,也可以定义函数直接定义再类中的函数默认是加上inline修饰的,(函数定义和声明分离的不算)public:a = b;b = tmp;int d = 2;
2025-03-05 13:20:41
1061
原创 c++入门
1.定义命名空间,需要用到关键字namespace这个关键字,在这个关键字后面跟着这个命名空间的名字,用空格隔开,接着跟着一堆{},在这个花括号里面可以定义命名的空间的成员,函数,变量,声明等。2.namespace本质上是定义一个域,在c阶段我们知道了全局域,局部域。对与这两个域来说,他们都各自有自己的生命周期和作用规则,在c++阶段,我们会再学习两个域,命名空间域和类域这两个域只影响作用规则,因为二者只能定义在全局。所以他们并不影响生命周期,他们的生命周期仍然是全局的。
2025-03-04 12:40:19
887
原创 快速排序实现及基准值寻找方法
我们在进行循环的时候要首先往栈中压入两元素,也就是这个序列的左右索引,然后进入循环,取出两元素,寻找基准值,如果左右序列不是一个有效的序列,也就是它的左边的序列大于等于右边的情况,等于的时候说明它只有一个元素,大于的情况说明它是空的,关于压栈的时候要注意,根据栈的特性后进先出,我们要先压入右边的元素,再去压入左边的元素,这样循环取堆顶的时候,才能是顺序的。对于快排来说,它的时间复杂度,它的最好的情况是一颗完全二叉树,logn,最坏的情况,没次划分都有一颗子树是空的,此时的时间复杂度就是n²。
2025-02-26 16:58:39
806
原创 选择排序(直接选择和堆排)的实现与时间复杂度
在这里需要提及一个特殊的点,当元素的最大值刚好为begin的时候,我们需要特殊处理,我们,我们拿9,6,3这个数组举例,当遍历完找到最大值和最小值的时候,我们找到最大值和最小值9和3的下标为0和2,我们如果不进行特殊处理的话,直接让最小值和起始位置begin进行交换,此时数组变为3,6,9.最大值的下标仍然指向0,然后最大值和最后一个位置交换,数组又变回了9,6,3,此时数组就无法达到一个排序的需求。这里有一个非常精妙的i点,我们定义一个索引的变量,最后一个元素的索引是n-1,而这个值也正是有效个数减1.
2025-02-25 17:24:28
990
原创 插入排序的实现和时间复杂度
我们能够明显的感觉大部分的情况下,它的时间复杂度是要小于n方的,这与我们c语言阶段学习的冒泡排序相反,对于冒泡的排序的情况,它最好的情况是给一个完全排好序的序列此时的的时间复杂度是n,而大部分的情况都是无序的,那么此时它的复杂度就是n方,从时间复杂度上来讲,直接插入排序的是要优于冒泡排序的。当我们插入第i个元素的时候前面的第i-1,i-2,i-3,i-4的元素都已经是有序的了,我们此时已经排好序的元素,和待排序的元素比大小,找到的它的位置插入,在找好位置之后,它之前的位置都是比它大的,我们就可以停止了。
2025-02-20 16:57:48
425
原创 二叉树的层序遍历和判断是否为完全二叉树的方法
对于多个文件的声明一定要注意,如果二叉树的声明和队列的声明,放在了两个不同的头文件中,如果要在队列的头文件中使用二叉树的头文件的结点用typedef出来的变量一定要在前面提前声明,还有一定要加上struct关键字。说人话就是除最后一层,其他层都是满的,最后一层的结点只能按从左往右的顺序排列,不存在只有右节点没有左节点或者最后一个叶子结点的父节点的度是2,而前面的父节点度是0或1的情况。然后判断的它的左右孩子是否为空,如果不为空进入队列。而我们拿来举例的这张图,就不是完全二叉树,在b的位置,它的度是1.
2025-02-15 23:19:43
424
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅