自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux 下 日志系统搭建全攻略

DEBUG调试级别INFO信息级别WARN警告级别ERROR错误级别FATAL严重错误级别。

2025-04-05 19:01:06 270

原创 Linux 进程信号

其中1~31号信号是普通信号,34~64号信号是实时信号,普通信号和实时信号各自都有31个,每个信号都有一个编号和一个宏定义名称,这些宏定义可以在/usr/include/x86_64-linux-gnu/bits/signum-generic.h 中找到,例如其中有定义: #define SIGINT 2信号是如何记录的?实际上,当一个进程接收到某种信号后,该信号是被记录在该进程的进程控制块当中的。

2025-04-04 17:06:28 947 7

原创 system V 消息队列&&信息量(了解)

msgget函数创建消息队列创建消息队列也需要使用ftok函数生成一个key值,这个key值作为msgget函数的第一个参数。msgget函数的第二个参数,与创建共享内存时使用的shmget函数的第三个参数相同。消息队列创建成功时,msgget函数返回的一个有效的消息队列标识符(用户层标识符),否则,返回-1,错误原因存于error中。shmget有设置大小的参数,而msgget没有消息队列的释放msgctl函数释放消息队列。

2025-03-26 16:50:42 951

原创 system V 共享内存

称为IPC键值,并返回这个key。在使用shmget函数获取共享内存时,

2025-03-26 08:28:48 782

原创 Linux 进程间通信

进程间通信简称IPC(Interprocess communication),进程间通信就是在不同的进程之间的传播或交换信息管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”例如:统计我们当前使用云服务器上的登录用户个数其中who命令和wc命令都是两个程序,当它们运行起来后就变成了两个进程,who进程通过标准输出将数据打到 “管道” 当中,wc进程再通过标准输入从 ”管道“ 当中读取数据,至此便完成了数据的传输,进而完成数据的进一步加工处理。

2025-03-25 23:41:00 886

原创 Linux 动静态库

完成头文件展开,去掉注释,宏替换,条件编译等,最后形成xxx.i文件完成词法分析,语法分析,语义分析,符号汇总等,最终形成xxx.s文件将汇编指令转换成二进制指令,最终形成xxx.o文件将生成的各个xxx.o文件链接例如:用 a.c b.c c.c d.c 以及main.c形成可执行文件,我们需要先得到这些文件的目标文件(二进制文件)a.o b.o c.o d.o 以及main.o,然后将这些目标文件链接起来,最后形成一个可执行文件。

2025-03-11 13:07:59 911 2

原创 Linux 软硬链接

与软连接不同的是,当硬链接的源文件被删除,硬链接文件依旧能正常执行,只是文件的硬链接数减少了一个,因为此时该文件的文件名少了一个,所谓的建立硬链接,本质就是在特定目录的数据块中新增文件名和指向文件名的inode编号的映射关系。命令我们可以看到,硬链接文件的inode编号和源文件是相同的,并且硬链接文件大小与源文件大小也是相同的,特别注意的是,当创建了一个硬链接文件后,该硬链接文件和源文件的硬链接数(引用计数)都变成了2。1. 软连接是一个独立的文件,有独立的inode,而硬链接没有独立的inode。

2025-03-07 21:43:56 769 1

原创 LInux 文件系统

线性存储介质理解文件系统,首先我们必须将磁盘想象成一个线性的存储介质,例如磁带,当磁带被卷起来时,其就像磁盘一样是圆形的,当我们将磁带拉直后,它就是线性的抽象理解磁盘从逻辑结构来看,磁盘是线性的,所以为了更好的理解磁盘,我们将磁盘理解成一个数组所以我们可以根据下标28888反推回它在线性结构的那个区域,然后进行访问一个磁盘有5个盘片,每个盘面有2w给扇区每个盘面50个磁道,每个磁道400个扇区1.确定在那一面28888 / 20000 = 1面(从第0面开始),它在第一面2.在哪一个扇区。

2025-03-06 22:41:52 1002

原创 C++的类型转换

由于编译器认为const修饰的变量是不会被修改的,因此会将const修饰的变量存放到寄存器当中保存,当需要读取const变量是就会直接从寄存器中进行读取,而我们修改的实际上是内存中变量 a的值,因此打印出来的是修改之前变量a的值。上述代码中,如果传入fun函数的是子类对象的地址,那么在转换后pb1和pb2都会有对应的地址,但如果传入func函数的是父类对象的地址,那么pb1会有对应的地址,而pb2则会返回一个空指针。向上转换是语法天然支持的,不需要进行转换,而向下转换是语法不支持的,需要进行强制类型转换。

2025-03-02 22:53:13 974 1

原创 Linux基础IO

当fopen以写入的方式打开一个文件时,若文件不存在,则会自动在当前路径创建该文件,那么这里所说的当前路径指的是什么呢?例如,我们在test_2_26目录下运行可执行程序myproc,那么该可执行程序创建的log.txt文件会出现在test_2_26目录下这里是否能说明的“当前路径”是指当前可执行程序所处的路径这时我们删除刚才可执行程序生成的log.txt先删除测试一下:回退到上级目录,在上级目录下运行该可执行程序。

2025-03-01 21:21:53 693 1

原创 Linux 进程程序替换

子进程刚被创建时与父进程共享代码和数据,但当子进程需要进行进程程序替换的时,也就意味着子进程需要对其数据和代码进行写入操作,这时就需要将父子进程共享的代码和数据进行写时拷贝,此后父子进程的代码和数据也就分离了,因此子进程进行程序替换后不会影响父进程的代码和数据。事实上,只有execve才是真正的系统调用,其他五个函数最终都是调用的execve,所以execve在man手册第2节,而其他五个函数在man手册的第3节,也就是说其他五个函数实际上是对系统调用execve进行了封装,以满足不同用户的不同调用场景。

2025-02-21 15:33:02 1192 3

原创 Linux 进程控制(进程创建,进程等待)

我们都知道main函数是代码的入口,但实际上main函数只是用户级别代码的入口,main函数也是被其他函数调用的,例如在VS2022当中main函数就是被一个名为__tmainCRTStartup的函数所调用,而__tmainCRTStartup函数又是通过加载器被操作系统所调用的,也就是说main函数是间接性被操作系统所调用的。在上述的例子中,当子进程未退出时,父进程都在一直等待子进程的退出,在等待期间,在等待期间父进程没有做任何事情,这种父进程处于阻塞状态下的等待叫做阻塞等待。

2025-02-17 17:51:37 827 3

原创 Linux 进程地址空间

在系统当中查找一个最合适调度的进程的时间复杂度是一个常数,不随着进程增多而导致时间成本增 加,我们称之为进程调度O(1)算法!

2025-02-14 14:37:30 1181 5

原创 Linux 环境变量

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但 是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。

2025-02-11 12:48:49 1150 3

原创 Linux进程概念

当一个进程要退出的时候,在系统层面,该进程的资源并不是立刻被释放,而是要暂时存储一段时间,以供操作系统或是其父进程进行读取,如果该进程的退出信息一直未被读取,则相关数据是不会被释放掉的,一共进程若是正在等待其退出信息被读取,那我们就称这种状态为:僵尸状态(zombie)例如,我们写代码时都在主函数最后返回0。观察代码运行结果,在父进程未退出时,子进程的PPID就是父进程的PID,而当父进程退出后,子进程的PPID就变成了1,即子进程退出后,子进程的PPID就变成了1,即子进程被1号进程领养了。

2025-02-09 10:45:57 947 1

原创 初步认识操作系统(Operator System)

管理者管理被管理者,实际上就是对这个。

2025-02-02 10:25:42 715 5

原创 冯·诺依曼体系结构

所以以上体系结构虽然可以使用,但是还不够完善,于是为了解决输入输出设备和cpu配合使用慢的问题,我们可以通过在它们之间加入存储器也就是内存,提高整个体系的速度,内存的速度比输入输出设备快很多,但是比cpu慢,内存在整个体系结构当中起着缓冲的作用,总的来说还是提高了整个体系的速度。登录qq,qq这款软件加载到内存中,然后中央处理器开始执行qq的代码,我使用输入设备(键盘)将信息放到内存中,然后CPU进行打包计算,计算完成之后将数据放回到内存中,通过输出设备(网卡,显示器)

2025-02-01 16:05:18 798 6

原创 Linux环境基础开发工具的使用(apt, vim, gcc, g++, gbd, make/Makefile)

在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序.但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安 装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.软件包和软件包管理器, 就好比 "App" 和 "应用商店" 这样的关系.

2025-01-28 09:50:51 2360 2

原创 C++实现红黑树

/红黑树结点颜色,_kv(kv),_col(Red)//初始值为红色{}思考:在节点的定义中,为什么要将节点的默认颜色给成红色的?如果将结点的默认颜色设置为黑色,那么就会和性质4相冲突,它是必然会发生的如果是红色就会有两种情况:1.它的父亲结点为黑色时,这时可以直接插入,不需要调整2.它的父亲结点为红色时,就会与性质3相冲突,这时将需要进行调整使用黑色作为结点的默认颜色一定会出问题,但是使用红色默认颜色不一定会出问题,这就是为什么使用红色作为默认颜色而不是黑色的原因。

2025-01-17 23:09:53 903 9

原创 Shell的运行原理以及Linux中的权限问题

Linux严格意义上说的是一个操作系统,我们称之为“核心(kernel)“ ,但我们一般用户,不能直接使用kernel。 而是通过kernel的“外壳”程序,也就是所谓的shell,来与kernel沟通。如何理解?为什么不能直接使用kernel? 从技术角度,Shell的最简单定义:命令行解释器(command Interpreter)主要包含:对比windows GUI,我们操作windows不是直接操作windows内核,而是通过图接口形,点击,从而完成我们的操作(比如进入D盘的操作,我们通常是双击D盘

2025-01-16 17:40:19 901 2

原创 C++ —— 智能指针

内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内 存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对 该段内存的控制,因而造成了内存的浪费。内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现 内存泄漏会导致响应越来越慢,最终卡死。

2025-01-03 16:53:19 1160 8

原创 C++异常处理

实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家 随意抛异常,那么外层的调用者基本就没办法玩了,所以实际中都会定义一套继承的规范体系。这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了最基础的异常类至少包含错误编号和错误描述两个成员变量,甚至还可以包含当前函数栈帧的调用链等信息。该异常类中一般都会提供两个成员函数,分别来获取错误编号和错误描述。public:, _id(id){}int GetErrid() const //获取错误id。

2024-12-27 22:15:44 1065 21

原创 【C++11】包装器

function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。Func();上面func可能是什么呢?那么func可能是函数名?函数指针?函数对象(仿函数对象)?也有可能 是lamber表达式对象?所以这些都是可调用的类型!如此丰富的类型,可能会导致模板的效率低下!为什么呢?我们继续往下看return x;return i;int main()//使用函数指针//使用仿函数//使用lambda表达式}, 30.0);return 0;

2024-12-26 09:49:08 1164 21

原创 【C++11】可变模板参数

template //Args全称:arguments返回类型 函数名(Args... args)//函数体下面就是一个基本可变参数的函数模板{}Args:是一个可变模板参数包args:是一个函数形参参数包模板参数Args前面有省略号,代表它是一个可变模板参数,我们将带省略号的参数称为“参数包”,这个参数包中可以包含0到任意个模板参数,args则是一个函数形参参数包。

2024-12-21 18:29:03 1421 40

原创 【C++11】lambda表达式

实际中我们使用[&]或[=]的方式捕获变量时,编译器也不一定会把父域中的所有变量捕获进来,编译器可能只会对lambda表达式中用到的变量进行捕获,它不会将用不到的变量捕获进来,主要看编译器的具体实现。就算加上mutable之后,x,y的const属性被取消了,但是使用传值的方式进行的捕获,是无法进行对两个局部变量进行值交换的。实际在底层,lambda表达式的处理方式和函数对象一样。其实可以看到在上面的代码中几个相同的lambda是相同的,类型也是不一样的,类型不一致也就是它们不能相互赋值的根本原因。

2024-12-15 16:30:35 789 15

原创 【C++11】类的新功能

C++11可以让我们更好的控制要使用的默认成员函数,假设在某些情况下我们需要使用某个默认成员函数,但是因为某些原因导致无法生成这个默认成员函数这时可以使用default关键字强制某个默认成员函数public:{}private:int main()Person p;return 0;实例化一个对象,没有给参数进行构造,编译器会报错,因为我们并没有在Person类中实现默认构造函数,并且我们实现了构造函数,编译器也不会自动生成默认构造函数。

2024-12-14 12:01:22 667 34

原创 【C++11】 右值引用和移动语义

左值是一个表示数据的表达式,如变量名或解引用的指针。

2024-12-10 23:22:32 6156 41

原创 【C++11】基础语法篇

这个容器没有提供很多的接口,它用于实现容器多参数类型的隐式转换。

2024-12-07 14:17:52 923 26

原创 【STL】用一张哈希表封装unordered_set和unordered_map

先创建一个哈希表,这里我们使用开散列实现哈希表,为了和库里的哈希表进行区分这里我将哈希表放入到了命名空间1.创建unordered_set和unordered_map,unordered_set和unordered_map分别是Key,Key模型和Key,Value模型,使用一张哈希表封装这两个的容器的话,我们需要同时兼容这两种模型。

2024-12-05 12:30:30 1551 25

原创 哈希表,哈希桶的实现

对于闭散列(开放定址法)来说,负载因子是特别重要的因素,一般控制在0.7~0.8以下,超过0.8会导致在查表时CPU缓存不命中(cache missing)按照指数曲线上升。因此,一些采用开放定址法的hash库,如JAVA的系统库限制了负载因子为0.75,当超过该值时,会对哈希表进行增容增容:而且增容会在一定程度上缓解哈希冲突/碰撞,因为原表部分产生哈希碰撞的值,映射到新表后可能不会产生哈希碰撞。

2024-11-30 18:12:23 1455 22

原创 【STL】用一棵红黑树同时封装set和map

下面我们将对一颗kv模型的红黑树进行封装并且模拟实现出stl库当中的map和set以下是需要使用到的红黑树源代码:红黑树模板参数的控制我们知道set是一个k模型的容器,而map是一个kv模型的容器,那么我们如何使用一颗kv模型的黑红树来同时封装它们两个呢?我们需要控制我们传进红黑树中的模板参数,来进行对set和map的兼容为了和原红黑树的模板参数进行区分,这里我们将红黑树的第二个模板参数修改为TT可以是键值Key,也可以是键值对Key和Value,如果是set容器那么它传入底层红黑树的就是K

2024-11-28 19:37:48 780 8

原创 AVL树详解

这里需要创建一个_parent和_bf,用来保存它的父亲结点和平衡因子//三叉链//储存的键值对int _bf;//balance factor 平衡因子控制平衡:_kv(kv), __bf(0) //平衡因子初始化为0{}这里我们引入平衡因子来控制树的平衡,但是并不是只有这一种方式,引入平衡因子只是与其他方式相比较而言更好理解。

2024-11-22 09:13:49 687

原创 【STL】set,multiset,map,multimap的介绍以及使用

管方英文介绍:中文介绍:1. set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。它的迭代器都是const_iterator3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。

2024-11-14 12:46:31 1228 2

原创 二叉搜索树

例:下面就是一颗搜索二叉树在二叉搜索树中,左子树上节点的值永远都是小于根节点的,右子树也是如此,所以我们通过观察不难发现,我们中序遍历这颗树,它会按升序的顺序将值打印出来。

2024-11-12 23:28:48 1100 2

原创 【STL】priority_queue的使用和模拟实现

优先级队列(priority_queue)它也是一个容器适配器,默认使用的容器是vector,在往队列中放入数据时,它会将容器中放置的数据通过堆算法调整成 大堆/小堆,在使用时我们若不指定建堆方法,它默认会是排大堆(less)它的使用方法其实和stack,queue类似,只是priority_queue在插入元素的基础上进行了调整建堆3.不指定容器和底层使用的堆算法这时它的容器和堆算法默认使用的是vector和less成员函数功能push向队尾插入一个元素,并向上调整排序。

2024-11-10 10:45:35 459

原创 【STL】queue,stack的底层实现

在前面的介绍中我们已经知道了queue和stack是一个容器适配器,它并没有被划分到容器的行列,它只是对其他容器的再封装,在STL中queue和stack默认使用的容器是deque在数据结构的学习中,我们知道stack和queue可以使用顺序表和链表实现,若我们在这里定义一个vector让stack进行包装实现,实际上就是stack中的每个接口的实现都复用了vector的接口。

2024-11-09 11:39:17 592

原创 【C++】多态的语法与底层原理

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。1.必须通过基类的指针或者引用去调用虚函数2.被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写被virtual修饰的成员函数称为:虚函数(只要成员函数才能变成虚函数)public:cout

2024-11-03 22:20:04 1024

原创 【C++】继承

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。teachert;s.Print();

2024-10-28 09:42:40 1254 2

原创 C++ —— 《模板进阶详解》,typename和class的用法,非类型模板参数,模板的特化,模板的分离编译

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。【优点】1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生2. 增强了代码的灵活性【缺陷】1. 模板会导致代码膨胀问题,也会导致编译时间变长2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。

2024-10-22 22:02:36 1195 1

原创 [LeetCode] 232. 用栈实现队列

思路灰常简单,创建两个栈一个输出栈(pushst),另一个是输入栈(popst)来实现队列的输入,输出。将进栈的数据,放到pushst中,进行删除操作时,将pushst中的数据全部放入到popst中,获取第一个元素,然后删除它,后面按照这个思路一直进行即可。返回队列开头元素,如果popst中还有剩余元素,直接返回栈顶元素即可,若没有就将pushst中的元素放入到popst中再出栈顶元素。队列判空,如果pushst或者popst中有元素,则返回false,都没有元素则返回true。

2024-10-20 12:00:00 241

空空如也

空空如也

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

TA关注的人

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