自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 EFL格式|动态库加载 | 重谈地址空间(2)

通过这篇学习我们需要知道,我们可执行程序的形成之后就已经有了虚拟地址,也就是说在编译期间就已经把地址按照平坦模式编制了。不过如果是多个.o文件的话,需要跳转函数的地址是在链接的时候统一初始化的。elf是一种可执行程序文件。地址空间中堆栈以及共享区域的地址划分是动态创建的,通过vm_area_struct创建节点来维护的。动态库加载的时候进程地址空间拿到的地址其实是.got表的地址,这样多个进程使用同一个动态库就是与地址无关,因为每一个进程中的地址可能都不一样,但是都可以访问同一个动态库。

2025-04-25 14:21:15 907

原创 序列与反序列化 | 守护进程 | 网络版本计算器

像之前的echo server,翻译等等都是在应用层。程序员写的这些代码都是在应用层。牵强的来说之间我们的echo server我们约定都是发送字符串,上述我们约定发送的就是一个命令,这也算是定协议,那么我们能不能发送结构化的数据呢? 为什么要发送结构化的数据?例子:微信聊天,头像,昵称和信息三条消息。当我们一个分发消息的时候有三条信息,,头像,昵称和聊天内容,那我们发送是分别发送还是一起发送呢?那肯定是一起发送!!,分别发送在服务器当中还需要检查之间的相关性。而对于头像而言我们已经上传到服务器当中本质可以

2025-04-08 15:51:25 643

原创 Tcp套接字编程

/服务端不同//我们需要对创建的sockfd进行监听//进行监听,这里的 sockfd就是 socket的返回值//backlog 控制了等待处理连接请求的队列长度,合理设置有助于平衡服务器负载和资源使用。(AI生成)//backlog后面会讲解RETURN VALUE (返回值)://这个返回值才是我们进行IO操作的文件描述符// client_addr: 连接的客户端信息//client_addrlen: 上面的信息结构体的大小当我们accept之后使用返回值进行IO操作。

2025-03-29 18:42:01 898

原创 UDP套接字编程(代码)

这些案列我们使用的接口基本都是一样的,所以在这里我先把接口介绍完,具体的细节后面在说明。

2025-03-23 21:07:33 747

原创 网络基础梳理

/ 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)// 绑定端口号 (TCP/UDP, 服务器)// 开始监听 socket (TCP, 服务器)// 接收请求 (TCP, 服务器)// 建立连接 (TCP, 客户端)从上述接口当中我们可以发现一个特点,那就是都会有一个这个东西,那他究竟是什么呢?网络socket本地socket (unix域间scoket)本地通信。

2025-03-21 10:29:54 911

原创 进程控制 | 手写shell实现

⚠️注意:这里我们最好自己写一个环境变量表,现在我是用的是c++写的,在导入char** environ的时候,会报错与C语言的冲突了,所以我在自己代码中定义了自己的环境变量表,同时一开始进行初始化。,当我们子进程退出的时候,并不会直接退出销毁空间就完事了,还需要让父进程来回收子进程的退出状态,只有这样子进程才可以完全销毁空间,⚠️: 这里在我的系统当中,当我们在家目录的父目录之上的时候,会显示全路径,而在家目录及其子目录时,前面的路径会变为 ~。等待成功了就返回子进程的ID,否则返回-1。

2024-12-30 21:27:35 859

原创 解决Windows与Ubuntu云服务器无法通过Socket(udp)通信问题

问题:如上图,当我在windows的客户端给云服务器上运行的服务端的时候无论怎怎么都发不上去,我一开始一直以为是我代码的问题!!结果是机器的问题😭。

2024-12-06 15:14:48 739

原创 基础IO2

在文件1当中我们主要讲解了什么是文件描述符?同时提出了文件内核缓冲区以及用户级缓冲区的概念,理解了什么是重定向。以上的都是对于已经打开了的文件,他们是存在内存当中的。可以一个磁盘可能有10000个文件,已经打开了100个,那么剩余的9900个文件呢?-》那肯定就是在磁盘当中喽!那么我们想要打开一个在磁盘当中的文件首先这个磁盘当中得有这个文件,。可是每一个文件都有一个地址,。举个例子🌰:17−1024代表着17号柜子1024号。。

2024-11-17 17:09:55 703

原创 基础IO1

'''r Open text file for reading. The stream is positioned at the beginning of the file. 只读形式r+ Open for reading and writing. The stream is positioned at the beginning of the file.只读+写入每次都清空文件再重新写入,如果不存在就创建文件每次都清空文件再重新写入,如果不存在就创建文件。

2024-11-17 17:09:33 781

原创 Linux进程的学习

CPU中会有一个运行队列,进程在队列中排队等待被调用就叫做进程的优先级。同时在LINUX中优先级使用整数代表。

2024-09-28 08:31:37 1154

原创 C++多态与多态原理

如上图,**当我们派生类中重写的对应的虚函数的时候,派生类当中的虚存储的是派生类自己的虚函数,如果没有重写时则是基类的虚函数。,所以调用析构的时候就是**什么类型的指针调用对应的析构函数,所以这里我们调用的是基类的析构函数。上文提到,我们的重写必须返回值,函数名,参数类型都要相等,但是这里有一个例外,就是我们的返回值如果是继承关系的就可以不一样也可以形成多态。我们的p是一个子类对象的指针,那么析构的时候应该把子类也析构了,但是此时我们的析构函数并不是虚函数,那么。那么上述**指向谁调用谁是如何实现的呢?

2024-09-11 13:14:31 873

原创 C++继承

成员在子类中都是不可用的,这里只是访问不了(也继承了下来),而其他类型的父类成员在子类中的访问权限 ==在我们把一个整形的值赋值给字符类型的时候发生截断,而截断的值我们会存储到一个临时变量中,然后才赋值给i。如上图,当我们父类没有默认构造的时候,我们需要手动调用父类的构造函数,并且规定必须在初始化列表调用。的时候,如果我们要访问我们的名字和电话,我们对象里面有两份,那我们访问哪一个呢?如上图,我们西红柿即是蔬菜也是水果,很合理。,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称。

2024-09-11 13:11:18 931

原创 Linux开发工具的使用

这里我们主要介绍三种模式:命令行模式、插入模式、底行模式当我们使用vim打开一个文件时候默认就是命令行模式,此时无论我们按什么键都写不进去,同时按Esc会变为命令行模式。当我们按i的时候,会进入插入模式,此时我们可以进行书写代码。当我们按Esc回到命令行模式的时候,按shift + :(冒号)进入底行模式,按wq退出vim。set nu显示行号好,make/makefile我们就讲到这里,我们来总一下我们所说过的5条注意事项。

2024-09-06 13:44:50 2117

原创 Linux权限的理解

因为有人已经帮你编译过源代码了,然后放入一个服务器当中,当我们使用自己的服务器的时候使用yum下载,会默认从源中的下载地址然后直接去服务器上下载已经编译好的可执行程序等等。,我们操作windows 不是直接操作windows内核,而是通过图形接口,点击,从而完成我们的操作(比如进入D盘的操作,我们通常是双击D盘盘符.或者运行起来一个应用程序)。,有相同的作用,主要是对我们的指令进行解析,解析指令给Linux内核。,这样与我们的期望不同,我们明明不想让B看我们文件的内容,但是它竟然可以之间删除我们的文件!

2024-09-06 13:35:59 1033

原创 哈希扩展(位图与布隆过滤器)

上图的蓝色方块其实就是一个个的整型,我们创建一个vector来存储每一个整型,在创建vector的时候,我们要根据数据的范围来初始化vector大小,由于一个整型最大为42亿多,所以我们最多需要开辟134217728个整型。= 42亿多,那么其实我们并不需要把每一个数都存储下来,我们可以使用一个bit位来表示它在不在即可,那么一个字节是8个比特位,所以我们所需要的空间为,$2^{32} /$8 ~= 5亿 ~= 500MB。如上段代码,我们用每个整型的前16个bit位和后16个bit位表示出现的次数。

2024-09-06 13:30:49 900

原创 特殊类的设计和类型转换

利用自定义类型的构造函数,这个其实在类和对象我们已经学过了,隐式类型转换。int _b;a1.Print();a2.Print();return 0;如上段代码,我们通过自定义类型的构造函数,让内置类型转换为自定以类型。operator int() //注意这里的int不能写为返回值,只能写在operator后面。

2024-09-06 13:26:47 824

原创 C++11新特性讲解

我们都需要进行完美转发,前面也讲过了,虽然万能引用可以接受左值和右值,但是引用类型如果是右值引用的话会退化,所以为了准确的识别类型我们需要使用完美转发。同时,我们无法直接获取参数包里面的参数,所以只能通过展开参数包的方式来获取每个参数,这也是可变模版参数的一个特点,这使我们无法使用。如果是左值,那么就是左值引用,但是如果是右值,会产出退化,变为左值引用(右值引用本身也是左值),所以才会输出上述结果。如上图,当我们包装类成员函数的时候,需要把this指针也包含进去,这里传入类对象也是可以的,所以可以传入。

2024-09-04 21:23:31 1292

原创 哈希表及其封装

这里有一个小问题:如果我们想要存储一个stringstringstring类型的数据,该如何去找对应的位置呢?可以看到库里面的模版参数上还有一个hash,这时干什么的呢?哈希表本质其实是把一个元素转化为整数,然后去哈希表找对应的关系存起来,对于正数我们直接转就可以了,但是如果是负数、stringstringstring类型呢?所以这就需要一个hash来帮我们把不同类型转化为整数。

2024-08-17 22:09:14 1001

原创 map和set的封装

前面我们讲解了红黑树的插入与删除,STL库里面map和set底层用的就是红黑树,所以我们来模拟一下。这里顺便提一下,在模版当中,当我们需要指定类域去使用里面的内容时,需要指定类型,这个在模版进阶中提到过。如上,如果要求我们打印一边数据呢,此时我们的数据元素不可修改,那么此时我们就需要使用。代表的就是最右边的节点,那么此时我们的–和++操作是类似的。迭代器遍历的结果就是红黑树的中序遍历,所以是有序的,这也就是说我们。去查找所插入的位置,但是上述封装方式我们的,我们节点的。

2024-08-11 21:20:29 412

原创 红黑树的插入与删除

插入过程种,当我们c为红色,p为红色的时候违反了性质三,所以我们需要进行处理,所以处理的结束条件就是当我们p为黑色的时候就不需要处理了。情况二和情况三旋转完之后已经不需要处理了。原因:旋转的时候g有两种情况:1.根 2. 子树作为根的话,旋转完毕就结束了作为子树,它的父节点一定为黑色节点,所以当我们旋转完之后把c变为g的位置的时候,p的指向为黑色节点,所以也不需要继续调整了。由于我们新增节点必须为红色,旋转的条件是一黑一红,而且旋转只能由情况一转化为情况二才进行旋转,那么既然有红色节点那么g。

2024-08-09 23:14:21 848 2

原创 AVL树图解(插入与删除)

2 和 0或者-2 和 0的组合,这个时候就需要对parent和PRightPLeft平衡因子进行特殊处理。之前我们插入过后旋转玩就可以直接跳出循环,不需要再进行更新平衡因子了,但是删除不是,当我们旋转完之后还要继续往上更新平衡因子。因为我们旋转其实就是为了去平衡左右子树的高度差,例如原来平衡因子为:2,这代表我们右子树比左子树要高2,那么我们去旋转完之后可能变为 1 或者 0,所以我们还需要继续往上更新,直到parent的bf为1或者遍历到根节点了。什么时候需要更新平衡因子呢?更新完平衡因子为0。

2024-08-03 20:50:00 933

原创 二叉搜索树(图解)

这个其实就是set的插入原理,所以我们的set才有去重的功能。当我们想要删除的节点左右孩子都有的时候,本质上是需要找到一个替代节点。的,但是如果我们的元素是有序的那么,此时二叉树就会退化为单叉链,查找效率为。符合要求的节点有两个: 1. 左子树的最大节点 2. 右子树的最小节点。如上图,如果我们对现在的二叉搜索树进行中序遍历会得到什么呢?如果此时我们删除的节点是根节点,那么直接让根节点移动即可。我们可以发现,这两种情况可以合并为一种情况,我们以。平常状态小,我们二叉搜索树的查找效率是。

2024-07-31 20:50:31 687

原创 linux基本指令的学习(补充)

这里和windows系统做个过渡:Windows中文件对应的就是linux中的文件,文件夹 --> linux的目录。

2024-07-15 13:52:27 700

原创 内容管理(C++)

对于我们使用newnewnew或deletedeletedelete的时候我们直接配套使用就可以了,最好不要混着使用。当我们使用newnewnew[]开辟空间但我们却使用freefreefree释放空间的时候,我们并没有正确的释放空间(我们并没有调整到存储析构次数空间的那个位置所以运行报错。如下图:此时我们又可以运行了,因为此时我们并不有显示定义,所以前面不会开辟那个空间存储析构次数,所以运行并没有报错,但是。

2024-07-12 08:51:08 652

原创 模版初阶 + 进阶

函数模版类模版。

2024-07-10 22:06:17 1016

原创 类和对象(下)

,如果有自定义类型,那么我们会去调用自定义类型的默认构造函数。那倘若我们自定义类型。

2024-06-29 14:25:39 886

原创 类和对象(中)(补充)

本文主要介绍类中自动生成的构造函数,析构函数,构造拷贝函数。

2024-06-23 19:49:48 975

原创 类和对象(上)

原因: cpu有32跟数据总线(32位平台),每位对应一个bit,那32个就是4个字节,所以我们cpu由于硬件规则一次只能访问4个字节,那如果不对齐的话,例如我们要去 i ,第一次我们只能取前3个字节,第二次我们只取前一个字节,这样我们就需要取两次。如下图:通过反汇编的角度我们可以看到,我们只是把 p 的地址给了寄存器(并没有对空指针解引用),然后调用了 Print()函数的地址,但是上文也说了,我们成员函数存储在一个公共区域呢,那么我们自始至终都没有对p进行解引用,所以程序运行成功。

2024-06-23 16:09:49 658

原创 C++入门二(更新)

那么。

2024-06-20 08:17:29 849

原创 C++入门

命名空间本质是一个域,在同一个域中定以重复变量 -> 重定义。这里跟在局部域中定义两个变量 a 是一样的。

2024-06-19 14:53:16 791

原创 C语言最终文章-二叉树

这篇文章大概就是我C语言学习的最后一篇文章了。二叉树的几个性质,堆、堆排序和用堆实现TopK问题。向上建堆和向下建堆二叉树的练习。

2024-06-17 19:15:40 975

原创 排序讲解(图解)

不过这里我们除了记录key值以外,还要记录此时的keyi(key值下标),然后end往前遍历找小,start往后遍历找大,只有都找到了,才能交换,当start >= end的时候,还有与keyi交换,因为我们是以key作为分界点的。以上只是第一趟的结果,我们还需要不断的调整,[left,keyi-1][keyi+1,right]的区间的顺序,最终才能有序,就是我提到的。希尔排序可以看做是插入排序的优化版,插入排序如果排的是有序数组,那将非常快,我们这次先对原数组进行预排序,先让数组部分有序,怎么做呢?

2024-05-17 21:05:04 1130

原创 环形队列(图解)

如果此时rear == 0,rear-1就为-1,这样就会导致数组越界,所以我们取(rear-1+SIZE+1)%(SIZE+1)位置的元素,此时即便rear = 0,那我们取得也是最后一个元素,同时rear > 0的时候也是满足条件的。(由于我们多开了一个空间,所以我们此时的长度为原数组长度+1),那我们就可以放心的直接。队尾入也是一样的,只需要当rear等于数组+1的时候要对数组加一取模。",同时环形队列的大小是固定的,它可以重复利用某一位置。,环形队列也不例外,只不过这里的。取队头元素简单,直接取。

2024-05-16 13:47:05 2589

原创 结构体补充-位段

为什么会有位段呢?我们直到一个int是4个字节表示32个bit位,但是比如2,3这样的整数,我们只需要2个bit位就可以了,那30个比特位不就是浪费掉了吗,所以位段就产生了位段通过结构体来实现,位段表示方法如下1.位段只能是整形家族,例如int,unsigned int,char等等来表示2.位段中间有一个冒号和一个数字。

2024-05-13 17:29:41 309

原创 c语言实现十进制(整数,小数)转N进制

今天实现了c语言整数和小数转换为对应的N进制。

2024-05-13 11:20:26 774 1

原创 栈和队列讲解

队尾入元素需要判断一下队列是否为空,如果为空就直接复制,不为空的话 ,直接尾插,这里我们直接让rear去移动,队头不变,这样的话从队头出也方便了。栈可不能跟数组一样直接就用了,我们需要判断栈是否为空,如果不是空我们打印栈顶元素,同时把栈顶元素出栈继续访问下一个元素,直到栈为空为止。由于这里我们的top指向的是元素的下一个位置,所以我们只需要返回top–指向的元素就可了,但是我们也得保证此时top是。这里的Queue我们有两个成员,一个指向头,一个指向尾,同时每一个成员都是一个节点的指针。

2024-05-12 17:46:57 839

原创 双向带头循环链表(图解)

单链表地址在单链表中我们只有一个指针指向下一个节点,而双向链表则需要两个指针,一个指向前一个节点,一个指向后一个节点,由于我们需要循环起来,所以最后一个节点我们要指向头节点(这里是指第一个节点) 为了避免搞混我下文把第一个节点称为头节点,哨兵节点就为哨兵节点哨兵节点如下:注意这里我们是要创建一个哨兵节点,所以我们需要返回一个节点,而我们接下来的操作都是在哨兵节点的基础上进行的,所以每一次进行基本增删操作的时候可以传一级指针,因为我们接受的哨兵节点肯定是一个指针类型的。结构定义如下:代码实现:头插首

2024-05-11 16:54:35 1786 1

原创 不使用加减运算符实现整数加和减

也就是1 和 0的时候才会1,那我如果在整数的二进制为中,一边是0,一边是1,我们是不是直接相加就可以了呢?,就为1,那么我们是不是可以用这个来实现我们前面按位与和按位异或的结果相加呢?按位与的结果为0的时候,才能按位或,不然的话还是有可以进位的,如果不这么继续整的话,就会算错。上图中4,5只是一次就搞定了,下面在举一个 15 和 25 的例子。再按位与的结果为0,才可以进行按位或,就和上面那个图一样。,那么如果两边同时为1的话,是不是就该。然后再按位异或找出不同的位数。只有当按位与和按位异或。

2024-04-26 22:46:20 373 1

原创 C语言链表讲解

然后把他的next与newhead。

2024-04-18 22:00:08 1086

原创 C语言动态内存讲解+通讯录2.0

可以看到ptr直接拷贝了原空间的内容,此时后面的空间大小足够,所以直接在原空间后开辟。到这里动态开辟的函数我们讲解就完毕了,前面我已经发过了文件的,接下来我们来对我们上次的通讯录进行。既然我们的通讯录是通过动态开辟来的,那么我们肯定要free掉,所以我们再写一个销毁数据的函数。如图所示,当原空间后的空间不够的时候确实会重新开辟,并把原空间的内容拷贝过去。我们局部变量等是在栈区上开辟空间的,而我们动态开辟的空间在堆上面。这里的数据我们以二进制的形式写入,这样就可以对数据进行一定的保护。

2024-04-01 16:50:30 849 1

ScreenTOGif 水豚鼠标助手

gif录制工具 鼠标指针皮肤

2024-04-01

ScreenTOGif

gif录制工具

2024-04-01

空空如也

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

TA关注的人

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