- 博客(91)
- 收藏
- 关注
原创 C++之map,set|AVL树|红黑树
{}T _data;int _bf;// 节点的颜色// 红黑树节点的定义{}// 节点的左孩子// 节点的右孩子// 节点的双亲(红黑树需要旋转,为了实现简单给出该字段)// 节点的值域// 节点的颜色。
2023-12-26 20:46:18 920 3
原创 Linux IO多路转接之epoll
有的地方说,epoll使用了内存映射机制,内存映射机制是:内核直接将就绪队列通过mmap的方式映射到用户态,避免了拷贝内存这样的额外性能开销。这种说法是不准确的,我们定义的struct epoll_evnet是我们在用户空间中分配好的内存,势必还是需要将内核中的数据结构拷贝到这个用户空间的内存中的。这些事件都会挂载在红黑树中,如此重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插入效率是logn,其中n为树的高度)在epoll中,对于每一个事件,都会建立一个epitem结构体。
2023-12-05 15:08:33 1193
原创 linux网络之网络层与数据链路层
路由表的destination是目的网络地址,GENMASK是子网掩码,gateway是下一跳地址,iface是发送连接口,flags中的u表示此条目有效,g表示此条目的下一跳地址是某个路由器地址,没有g标识的标识目的网络地址是与本机接口直接相连的网络,不必经过路由器转发。3位标志字段:第一位保留(保留的意思是暂时不用,将来可能会用到),第二位置为1表示禁止分片,这个给时候如果报文长度如果超过MTU,ip模块就会丢弃报文,第三位置表示更多分片,如果分片的话,最后一个分片置为1,其他是0,类似一个结束标记。
2023-11-23 21:44:40 1022
原创 Linux网络之传输层协议tcp/udp
由于我们的请求量很大, 就可能导致TIME_WAIT的连接数很多, 每个连接都会占用一个通信五元组(源ip, 源端口, 目的ip, 目的端口, 协议). 其中服务器的ip和端口和协议是固定的. 如果新来的客户端连接的ip和 端口号和TIME_WAIT占用的链接重复了 , 就会出现问题.确认应答策略, 对每一个发送的数据段, 都要给一个ACK确认应答. 收到ACK后再发送下一个数据段. 这样做有一个比较大的缺点, 就是性能较差. 尤其是数据往返的时间较长的时候。
2023-11-16 17:28:20 677
原创 Linux网络应用层协议之http/https
文章目录目录一、http协议1.URL2.http协议格式3.http的方法4.http的状态码5.http常见header6.实现一个http服务器二、https协议1.加密2.为什么要加密3.常见的加密方式对称加密非对称加密4.https的工作过程探究方案1 只使用对称加密方案2 只使用非对称加密方案3 双方都使用非对称加密方案4 非对称加密+对称加密中间人攻击引入证书CA认证方案5 非对称加密+对称加密+证书认证https的整个工作流程小结总结1.网络版本计算器例子例如,现在要在服务器端实现一个加法器
2023-11-15 21:06:00 1350 2
原创 浅谈设计模式
建造者模式是一种创建型设计模式,使用多个简单的对象一步一步构建成一个复杂的对象,能够将一个复杂的对象的构建与它的表示分离,提供一种创建对象的最佳方式。代理模式指的是代理控制对其他对象的访问,也就是代理对象控制原对象的引用。工厂模式是一种创建型设计模式,在工厂模式中,创建对象时候不会对上层暴露创建逻辑,而是通过一个共同结构指向新创建的对象,以此实现创建-使用的分离。目标类和代理对象实现一个接口,先访问代理对象再通过代理对象访问目标对象。代理模式结构包括:一个真正要访问的对象(目标类),一个是代理对象。
2023-11-10 11:25:38 197
原创 网络编程套接字socket
connect函数试图与套接字地址为addr的服务器建立一个因特网连接,其中addrlen是sizeof(sockaddr_in)。ipv4/ipv6的地址格式定义在netinet/in.h中,ipv4地址用sockaddr_in结构体表示,包括16位地址类型,16位端口号和32位ip地址ipv4/ipv6地址类型分别定义位常数AF_INET 、AF_INET_6,只要取得某种sockaddr的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容。
2023-10-17 17:32:05 194 1
原创 C++11新特性之智能指针|内存泄漏
内存泄漏:内存泄漏指是因为疏忽或者错误造成程序未能释放已经不再使用的内存情况。内存泄漏并不是指内存在物理上的消息,而是应用程序分配某段内存后,因为涉及错误,失去了对该段内存的控制,造成了内存的浪费。内存泄漏的危害:如os,后台服务等,出现内存泄漏会导致程序响应越来越慢,最终卡死。// 1.内存申请了忘记释放// 2.异常安全问题Func();// 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放.
2023-09-23 15:57:11 435
原创 C++11的一些新特性|线程库|包装器|lambda表达式
在c++11之前,涉及到多线程问题,都是和平台相关的,wins和linux下各有自己的接口,这使代码的可移植性比较差,在c++11中最重要的特性就是对线程进行支持了,使用是不需要依赖第三方库。而且在原子操作中还引入了原子类thread():构造一个线程对象,没有关联任何线程函数,即没有启动线程thread(fn,args1,arg2...)构造一个线程对象,并关联线程函数fn,args1,args2...为线程函数参数get_id()获取线程id。
2023-09-22 21:02:47 157
原创 C++11的一些新特性|右值引用|STL中的一些变化
如果没有自己实现移动构造,且没有实现析构,拷贝构造,拷贝赋值重载中的任意一个,那么编译器会自己生成一个默认移动构造。在类中增加移动构造,移动构造本质上是将参数右值的资源窃取,占为己有,那么就不用做深拷贝,所以叫它移动构造,就是窃取别人的资源来构造自己。原来c++类中,有6个默认成员函数:构造,析构,拷贝构造,拷贝赋值,取地址重载,const取地址重载。传统的c++语法中就有引用的语法,而c++11中新增了右值引用的语法特性,无论是左值引用还是右值引用,都是给对象取别名。可以让你更好的控制要使用的默认函数。
2023-09-22 17:09:35 398 1
原创 C++面经之多态|多态的原理|虚函数
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person,Person对象买全价票,Student对象买半价票。1.必须通过基类的指针或者引用调用虚函数2.被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写重写:函数名相同,参数类型相同,返回值相同。
2023-09-14 19:52:22 338 1
原创 C++面经之继承|菱形继承和虚拟继承|一些关于继承的笔试面试题
继承机制是面向对象程序设计,使代码可以复用的最重要的手段,它允许程序员在保持原有特性的基础上进行扩展,增加功能,这样产生新的类称为派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。继承是类设计层次的复用。//基类 personpublic:protected:int _age;//学号;s.print();return 0;
2023-09-13 21:15:48 102
原创 Linux入门-网络基础|网络协议|OSI七层模型|TCP/IP五层模型|网络传输基本流程
OSI 七层模型是一种框架性的设计方法,其最主要的功能使就是帮助不同类型的主机实现数据传输;它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整. 通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。协议是一种约定,计算机之间传输媒介是光电信号,通过频率或强弱来标识0、1信息,想要传递不同的信息,就需要约定好双方的数据格式。OSI七层网络 模型称为开放式互联参考模型,是一个逻辑上的定义和规范。tcp/ip是一组协议的代名词,它还包含了许多协议。
2023-09-11 14:33:24 636
原创 Linux入门之多线程|线程的互斥|锁|封装线程|封装锁|死锁
一、线程互斥1.概念二、线程互斥接口1.互斥量的接口初始化互斥量互斥量的的加锁和解锁销毁互斥量2.互斥量的原理三、线程的封装四、锁的封装五、死锁1.死锁的概念2.产生死锁的必要条件:3.避免死锁:核心思想 破环死锁的4个必要条件的任意一个总结 2.动态分配互斥量的的加锁和解锁销毁互斥量不要销毁一个已经加锁的互斥量已经销毁的互斥量,要确保后面不会有线程再尝试加锁2.互斥量的原理三、线程的封装四、锁的封装五、死锁多线程代码存在并发访
2023-09-05 17:36:35 94
原创 Linux入门之多线程|线程|进程基本概念及库函数
物理内存不是按字节划分的,如果按字节划分,频繁的操作io,注定过多的寻址,就会导致过多的机械运动,所以效率十分低下,所以os和磁盘设备进行交互的时候,是按块为单位。os对物理内存也有自己的管理方式,里面存储每块的属性。实际上虚拟地址是按照10+10+12来划分的,首先高10位,找到第一级页表(页目录),kv找到第二级的页表(中间10位地址在这个页表内kv)找到物理内存对应页框的起始地址,最后用虚拟地址的后12位对应的数据地址找到页内偏移,即采用基地址+偏移量的方法,在物理内存中定位任意一个内存字节的位置。
2023-09-03 21:40:45 172 2
原创 Linux入门之进程信号|信号产生的方式
每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到编号34以上的信号都是实时信号。
2023-09-01 12:02:23 919
原创 Linux通信--构建进程通信IPC的方案之共享内存|实现使用共享内存进行server&client通信
共享内存是最快的IPC形式。一旦这样的内存映射到共享它的进程地址空间,这些进程间数据传递不再涉及到内核,即进程不再通过执行进入内核的系统调用来传递彼此的数据。
2023-08-30 21:17:26 426
原创 Linux基础--文件描述符
pcb中有一张表,存放文件描述符,表中存放struct_file指针,通过表中数组下标索引找到对应文件指针,进而访问文件。所以,本质上文件描述符就是该数据的下标,所以拿到了fd,就可以找到对应的文件。但是对于一个长年累月运行的程序(比如网络服务器),打开的文件描述符一定要记得关闭,否则随着打开的文件越来越多,会占用大量。oldfd指向a.txt,newfd指向b.txt,调用成功后,newfd和b.txt关闭,newfd指向a.txt(oldfd被保留)通过open函数,文件描述符就是一个整数。
2023-08-30 19:07:22 152
原创 Linux通信--构建进程通信System-V 消息队列|信号量
信号量本质就是一个计数器(int count) ,用来描述资源的数量。信号量类似于看电影买票,就是一种预定机制,买票成功后座位锁定。执行流想要访问临界资源中的一个子资源(临界区中有很多临界资源),进入临界区之前,首先要申请信号量(进程申请信号量),退出临界区,释放信号量。被任意一个进程可以看到的资源称为公共资源。但是有些资源需要互斥使用,比如一个进程读,一个进程写,还没写完就不允许读。如果count = 1,就称为二元信号量,完成了互斥的功能。所以,所有的进程都首先要看到信号量,信号量就是共享资源。
2023-08-30 17:00:15 330
原创 Linux通信--构建进程通信的 方案之管道(下)|使用匿名管道实现功能解耦|命名管道实现serve&client通信
需求分析:首先需要创建两个进程,client端和server端,还需要一个common文件来声明共同的定义和方法,所以创建三个文件client.cc,server.cc,common.hpp。1.首先,创建管道,只需要创建一次即可,本次案例在server.cc中创建,client.cc中使用即可。3. 进程A 向管道中写入 进程B从管道中读取并打印到标准输出。3.client端不需要创建文件,只用写方式打开文件就可以。2 创建的命名管道可以让两个进程通信。参数:管道的名字,创建的管道权限。
2023-08-29 21:29:22 331
原创 Linux入门--构建进程间通信的方案之管道(上)
数据传输:一个进程需要将它的数据发送给另一个进程资源共享:多个进程之间共享同样的资源通知事件:一个进程需要向另一个或一组进程发送消息,通知他们发生了某种时间(如进程终止时要通知父进程)进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。管道是Unix中最古老的进程间通信的方式将一个进程连接到另一个进程的一个数据流称为 -- 管道通常用来具有血缘关系的进程,常用于父子通信。
2023-08-28 19:44:58 180 4
原创 c++进阶--二叉搜索树模拟实现
一、二叉搜索树1.二叉搜索树概念二叉搜索树又称为二叉排序树,它或者是一颗空树,或者具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值左、右子树都是二叉搜索树2.二叉搜索树操作1.二叉搜索树的查找从根节点开始比较,查找,如果比根节点值大,往右走查找,比根节点值小,往左走查找最多查找高度次,走到空节点还没找到,则说明这个值在树中不存在。2.二叉搜索树的插入若为空树,则直接新增节点,赋值给root指针。
2023-08-08 17:26:58 383 3
原创 C++入门之stl六大组件--stack和queue源码深度剖析及模拟实现
通过阅读官方文档:1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器并提供一组特定的成员函数来访问其元素,将特定类作为其底层的元素特定容器的尾部(即栈顶)被压入和弹出。3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:empty:判空操作back:获取尾部元素操作。
2023-08-07 15:28:08 250 2
原创 C++入门之stl六大组件--List源码深度剖析及模拟实现
list: 模仿实现stl的list - Gitee.comT _data;//list的成员//list的构造 初始只有一个头节点list()//list的一些成员函数//通过迭代器定位begin和end//通过迭代器对指定pos位置进行增删改查//这里是要通过pos的指针,找到这个节点 对pos进行解引用assert(pos!=end());delete cur;//打印while(it!cout<<*it;
2023-08-06 19:38:39 1121
原创 实战项目——基于多设计模式下的同步&异步日志系统
为什么需要日志系统生产环境的产品喂了保证其稳定性以及安全性是不允许开发人员附加调试器去排查问题,可以借助日志系统来打印一些日志,帮助开发人员解决问题上线客户端的产品出现bug无法复现并解决,可以借助日志系统打印日志并上传到服务器端帮助开发人员进行分析对于一些高频操作(定时器、心跳包),在少量的调试次数下可能无法触发我们想要的行为,通过断点暂停的方式,我们不得不重复操作几十次或更多,导致排查问题效率非常底下,可以借助打印日志的方式查问题。
2023-07-26 21:14:32 601
原创 C++入门之stl六大组件--Vector库函数的介绍,以及模拟实现一些常用接口
本节主要阅读了vector的源码,以及vector的使用vector是表示可变大小数组的序列容器。就像数组,vector也采用连续空间来存储元素,即可以使用下标对vector元素访问,但是它的大小是可以动态改变的,并且它的大小会被容器自动处理本质上,vector使用动态分配数组来存储它的元素,当新元素插入,就需要重新分配大小增加存储空间。它的做法是,动态开辟一个新的数组,然后将元素移动进来。时间代价较高。事实上,每当一个新的元素加入到容器,并不会每次都重新分配空间。
2023-07-26 15:34:42 1066 4
原创 C++入门之stl六大组件--String库函数的模拟实现
本章为了深入了解string类的底层原理,用数据结构的思想来管理资源模拟实现出string类的一些接口。具体来说,1.能像int类型那样定义变量,并且支持赋值,赋值。2.能用做函数的参数类型以及返回类型。3.能用做标准库容器的元素类型,即vector/list/deque的value_type。(摘自coolshell)本文主要模仿stl库中的一些源码,技术有限,如有错误请指正。
2023-07-20 21:57:00 126 1
原创 C++入门之内存管理|复习C中的malloc,realloc,calloc|内存分布|内存管理|new delete|operator new|operator delete
class Apublic://构造: _a(a)//注:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。int main()// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数free(p1);delete p2;// 内置类型是几乎是一样的// Cfree(p3);
2023-07-17 16:02:35 123
原创 C++入门之类和对象(下)
本章对构造函数,static成员,友元,内部类,匿名对象,编译器的优化拷贝对象进行简单总结,技术有限,如有错误请指正。
2023-07-15 12:05:04 225 2
原创 linux入门之进程控制(下)进程程序替换,shell运行原理,手写一个mini-shell
6.1-5号最终都调用6号,6号是os提供的系统调用,1-5号是对6号做的封装。
2023-07-10 14:30:43 161
原创 linux入门之进程控制(上)进程创建,进程等待
这里的status如果是0,就是正常终止,并且运行结果正确,如果非0,就是正常终止,但是运行结果错误。如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程的退出信息。在Linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程,新进程为子进程,原进程为父进程。通常,父子代码共享,父子不再写入时,代码也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。父进程在wait的时候,如果子进程没退出,父进程此时在等待子进程。
2023-07-05 20:42:11 366 1
原创 linux入门之进程概念(下)程序地址空间
比如,有一个富翁(os),有10亿美金(内存),给每个继承人(进程)都画了饼(进程空间地址),这个饼就是将来要继承的东西,此时这个饼需要被管理起来,以防富翁忘记采用先描述再组织的手段,struct mm_struct。我们在使用fork的时候,创建一个变量,在子进程中修改变量的值,但是不影响父进程打印原来的值,这是因为进程具有独立性,进程 = 内核数据结构+代码和数据,我们观察到&value的地址相同,所以该地址。1.同一个变量,地址相同,其实是虚拟地址相同,内容不同是因为被映射到了不同的物理地址。
2023-07-05 15:54:39 113
原创 linux入门进程概念中(僵尸进程,孤儿进程,进程优先级,并行和并发,环境变量)
在代码 int main(int argc, char * argv[ ], char * envp[ ] ) 这三个形参中,char * envp是环境变量表,是一个指针数组,里面存放着char * 类型的地址,比如:" /a/b/c:",如下图:前若干个指向有效地址,最后一个指向NULL。如果一个进程退出了,立马X状态,作为父进程没有机会拿到子进程的退出结果。写一段代码,让父进程运行30s,子进程运行5s,此时子进程先退出,父进程还在运行,同时父进程没有获取到子进程的退出码,子进程进入僵尸状态。
2023-07-04 17:55:45 337
原创 linux入门之进程概念上(冯诺依曼系统,系统概念与定位,PCB,fork初识)
首先要明白,进程都是独立运行的,同样,父子进程也是独立运行的,他们看到的是相同的代码,但是代码是只读的,如果有一个进程修改了代码,不会影响另一个进程,这个过程叫写时拷贝,各自私有一份。当fork函数return 的时候,已经完成了前面创建子进程的工作(创建pcb),甚至可能已经被调度了,return也是语句,再向后执行,父进程被执行,return 跑了两次,所以有两个返回值。我们不难发现,当运行进程和父进程时,中止掉这个程序,再次运行,进程的id改变,但是父进程的id不变,并且,父进程的id就是bash,
2023-06-28 20:42:51 181 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人