自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 传输层——TCP协议

连接建立并非总是成功,通信双方在三次握手过程中,前两次握手能够得到对方的确认,因为每次都有对应的回应。然而,第三次握手缺乏直接的响应报文,如果这一阶段的ACK报文丢失,连接建立就会失败。虽然客户端在完成第三次握手后认为连接已建立,但服务器若未收到这一握手,则不会建立连接。因此,无论采用几次握手,最后一次握手的可靠性都是无法保证的。鉴于连接建立存在不确定性,选择握手次数的关键在于权衡不同次数握手的优点。

2024-06-11 13:59:31 975

原创 传输层——UDP协议

数据会经过一系列的处理和优化。因此,当UDP接收报文时,一旦读取了前8个字节,接下来的数据就都被视为有效载荷,即实际要传输的应用层数据。内核中用哈希的方式维护了端口号与进程ID之间的映射关系,因此传输层可以通过端口号得到对应的进程ID,进而找到对应的应用层进程。操作系统是C语言写的,而UDP协议又是属于内核协议栈的,因此UDP协议也一定是用C语言编写的,UDP报头实际就是一个位段类型。我们限制的是从端口号到进程的唯一性,而没有要求从进程到端口号也必须满足唯一性,因此一个进程是可以绑定多个端口号的。

2024-06-07 11:07:42 842

原创 HTTPS 协议原理

• 数字指纹(数据摘要),其基本原理是利用单向散列函数(Hash函数)对信息进行运算,生成⼀串固定长度的数字摘要。数字指纹并不是⼀种加密机制,但可以用来判断数据有没有被窜改。• 摘要常见算法:有MD5、SHA1、SHA256、SHA512等,算法把无限的映射成有限,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率非常低)• 摘要特征:和加密算法的区别是,摘要严格意义不是加密,因为没有解密,只不过从摘要很难反推原信息,通常用来进行数据对比。

2024-03-21 09:41:41 1541 1

原创 【Linux网络】应用层协议——http协议

虽然我们说,应用层协议是我们程序猿自己定的。但实际上,已经有大佬们定义了一些现成的,又非常好用的应用层协议,供我们直接参考使用。就是其中之一。HTTP(Hyper Text Transfer Protocol)协议又叫做超文本传输协议,是一个简单的请求-响应协议。是一种最基本的客户机/服务器的访问协议。浏览器向服务器发送请求,而服务器回应相应的网页。它是从万维网(WWW)服务器传输超文本到本地浏览器的传送协议。

2024-03-14 16:01:50 944

原创 【实战项目】Boost搜索引擎项目

1.Jieba库的安装和使用GitCode - 开发者的代码家园我们看一下cppjieba工具包的具体构造解决jiaba库的链接使用问题其中我们需要连接使用的是如下三个:cppjieba/include (需要建立对/include目录下文件的链接)cppjieba/dict(词库 )(需要建立对/dict目录下文件的链接,从而获取jieba分词时的字典根据。

2024-03-10 08:42:06 1353

原创 【Linux网络】再谈 “协议“

通过这种方式,我们可以确保通信双方按照预定的格式发送和接收数据,从而实现网络计算器的功能。

2024-03-05 12:01:02 994

原创 【Linux网络】网络编程套接字(守护进程及TCP协议通讯流程)

当调用write函数时,应用程序的数据会被复制到操作系统的内核缓冲区中,至于何时发送这些数据以及每次发送多少,是由TCP协议根据网络状况和接收方的接收窗口大小等因素来决定的。综上所述,进程组是Linux系统中对多个进程进行统一管理和控制的一种机制,而任务最终是要指派给进程组的,是用户或系统需要完成的具体工作,可以由一个或多个进程共同完成。我们用ps命令查看该进程,需要注意的是,连接并不是立马建立成功的,由于TCP属于传输层协议,因此在建立连接时双方的操作系统会自主进行三次协商,最后连接才会建立成功。

2024-02-29 12:24:24 864

原创 【Linux网络】网络编程套接字(TCP)

因此这时我们只看到了两个服务进程,其中一个是一开始用于获取连接的服务进程,还有一个就是孙子进程,该进程为当前客户端提供服务,它的PPID为1,表明这是一个孤儿进程。在这个服务器中,当客户端发送数据时,服务端不会做任何复杂的处理,而是简单地将收到的数据原封不动地返回给客户端。我们使用的是单例模式的线程池,在服务端Start函数调用线程池中的GetInstance函数获取单例,然后对调用线程池中封装的Start函数创建线程,并指定线程池中的线程数量(不指定默认为5个线程),并完成现成的初始化。

2024-02-23 20:21:58 1526 1

原创 【Linux网络】网络编程套接字(预备知识+UDP)

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及UNIX Domain Socket。然而,各种网络协议的地址格式并不相同。

2024-02-18 17:33:05 1295

原创 【Linux】网络基础

因此,尽管客户端和服务端可能运行着不同的操作系统,它们在数据封包和解包操作上的方法是相同的。这种一致性确保了数据在不同操作系统之间能够无缝传输,确保了网络通信的顺畅进行。

2024-02-08 02:32:31 982

原创 【Linux多线程】线程池

单例模式是一种 "经典的, 常用的, 常考的" 设计模式。

2024-02-01 10:34:58 1240

原创 【Linux多线程】POSIX信号量

此时由于生产者生产的很快,运行代码后一瞬间生产者就将环形队列打满了,此时生产者想要再进行生产,但空间资源已经为0了,于是生产者只能在p_space_sem的等待队列下进行阻塞等待,直到由消费者消费完一个数据后对p_space_sem进行了V操作,生产者才会被唤醒进而继续进行生产。虽然消费者消费的很快,但一开始环形队列当中的数据资源为0,因此消费者只能在c_data_sem的等待队列下进行阻塞等待,直到生产者生产完一个数据后对c_data_sem进行了V操作,消费者才会被唤醒进而进行消费。

2024-01-26 11:31:04 979

原创 【Linux多线程】生产者消费者模型

我们看下面这张图,如果我们只看红色方框里面的内容,生产者和消费者就是生产者生产数据和消费者获取数据,而且生产者生产数据和消费数据是同步关系的,消费者必须要等生产者生产数据之后再来消费,如果我们只是这样看生产者消费者模型的话效率是低下的!生产者消费者模型是多线程同步与互斥的一个经典场景,我们生活中也有许多的消费者与生产者模型,下面我们来举一个生活中的生产者消费者模型的例子——超市。从上面基于任务的生产者消费者模型的过程我们可以看到,消费者获取数据后,还需要将数据进行计算,这个过程也是要花时间的!

2024-01-22 10:06:47 900 1

原创 【Linux多线程】线程的互斥与同步

同样的,我们只进行单纯的加锁,如果一个线程竞争力很强,每次都是申请到锁,但是不干活有可能会导致其它线程长时间竞争不到锁,从而引起饥饿问题。通过运行结果我们可以看到,我们唤醒的这五个线程是有顺序性的,主要是因为这几个线程启动时默认都会在该条件变量下去等待,而我们通过pthread_cond_signal函数每次都唤醒的是在当前条件变量下等待的首个线程,当该线程执行完打印操作后会继续排到等待队列的尾部进行wait,所以我们能够唤醒的线程是有顺序性的。所以也就相当于它是拿着钥匙走的,别人是拿不到这把锁的。

2024-01-18 11:09:09 950 1

原创 【Linux】多线程

什么叫线程?我们认为,线程就是操作系统调度的基本单位!!我们上面说线程是在进程内部运行的一个执行分支,这里的内部是什么意思呢?那什么又叫做一个执行分支呢?这里的内部指的是线程是在进程的虚拟地址空间中运行的。执行分支指的是CPU调度的时候只看PCB,每一个PCB曾经被指派过指向方法和数据,CPU是可以直接调度的。什么叫进程?我们之前认为的进程:进程 = 内核数据结构(task struct) + 代码和数据了解了Linux下的线程之后,我们又该如何理解我们之前讲的进程呢?

2023-12-22 16:30:11 958

原创 【Linux】进程信号

除了可以使用kill函数向进程发信号外,我们还可以使用另外两个系统调用向进程发信号:rasie函数与abort函数,下面我就来为大家介绍一下这两个函数。

2023-12-17 15:03:10 1426

原创 【Linux】进程间通信

进程间通信(IPC,InterProcess Communication)是两个或者多个进程实现数据层面的交互。日常生活中,一个大型的应用系统往往需要众多进程协作进行,进程通过与内核及其他进程之间的互相通信来协调它们的行为。但是进程间通信是有成本的,因为进程独立性的存在,导致进程通信的成本较高。管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。举例:who | wc -l。

2023-12-10 19:50:05 1095

原创 【Linux】基础IO

操作系统有自己的刷新机制,我们并不需要去关心操作系统的刷新机制

2023-11-25 16:35:25 1251

原创 【Linux进程】进程控制

main函数的返回值,本质表示:进程运行完成时是否是正确的结果,它又称为进程的退出码!0代表运行正确,如果不是正常退出,可以用不同的数字,表示不同的出错原因!进程退出码只跟代码运行完毕,结果正确或者代码运行完毕,结果不正确这两种情况有关系,进程异常退出我们不再关心他的进程退出码,而是关心为什么会异常退出。只有在main函数中return才能起到退出进程的作用,在非main函数中return表示函数返回。在任意地方调用exit或者_exit函数,都能够起到终止进程的作用,

2023-11-13 20:31:54 276

原创 【Linux进程】进程地址空间

我们发现static修饰的局部变量的地址是在全局数据区的,也就是说虽然static修饰的局部变量作用域是在函数内,但是他的声明周期已经是全局变量了。看完结果我们会有疑问:怎么可能父子进程中g_val变量的地址是一样的,同时读取,打印出来的值却是不一样的。所以之前说‘程序的地址空间’是不准确的,准确的应该说成 进程地址空间 ,那该如何理解呢?我们把它叫做程序地址空间。我们之前学习C语言的时候,应该见过下面的空间布局图。我们在上面代码中把变量a改为static变量。变量内容不一样,所以父子进程输出的变量。

2023-11-06 13:38:54 130 1

原创 【Linux进程】环境变量

因为我们自己的进程本身是没有环境变量,但当他启动起来,变成进程之后就具有环境变量,因为./运行我们的myproc之后,它会变成进程,而./myproc又是我们的bash的一个子进程。我们一个进程在运行时,不要简单认为我的进程启动就是把程序加载到内存,而是当我们的程序变成进程在启动时,我们一定要有人调main函数,其实我们的main函数是可以带参数,并且它是有三个参数的,因为我们平时基本上都不怎么用他们,所以我们并没有将这三个参数给写出来。下面我们再来运行一下系统的指令。1.为什么我们执行指令时不用带路径?

2023-11-03 21:51:46 504

原创 【Linux进程】再谈进程—进程概念

为了让父和子执行不同的事情!需要想办法。

2023-11-03 14:45:31 73 1

原创 【Linux进程】再谈软件—操作系统(Operator System)

操作系统对上,给用户一个稳定高效的执行环境。对下,管理好软硬件资源,提供稳定的软硬件环境。操作系统中,注定了,一定存在大量的数据结构!计算机管理硬件——先描述再组织1. 描述被管理对象,用struct结构体。2. 组织被管理对象,用链表或其他高效的数据结构。用户在使用操作系统的时候,它并不是直接跟操作系统打交道的。因为操作系统为了保证自己数据安全,但是也为了保证给用户能够提供服务,操作系统以接口(系统调用)的方式给用户提供调用的入口。来获取操作系统内部的数据。

2023-11-01 22:03:34 186 1

原创 【Linux进程】先谈硬件—冯诺依曼体系结构

键盘输入消息到内存,CPU处理消息后写回内存,此时你的网卡从内存获取消息并发送到网络,经过处理后,另一端的网卡获取消息并加载到内存,CPU再从内存获取消息并解包处理,然后写回到内存,最后显示器从内存获取消息并并显示在朋友的电脑上。在使用QQ与朋友进行聊天,都是需要联网的,而我们的电脑都是冯诺依曼体系结构,这个聊天的这个过程中,你的键盘相当于输入设备,显示器和网卡相当于输出设备,而你朋友的电脑网卡相当于输入设备,显示器相当于输出设备。从你打开窗口,开始给他发消息,到他的到消息之后的数据流动过程。

2023-11-01 15:36:15 141 1

原创 【Linux】权限和权限管理

Linux严格意义上说的是一个操作系统,我们称之为“核心(kernel)“ ,但我们一般用户,不能直接使用kernel。而是通过kernel的“外壳”程序,也就是所谓的shell,来与kernel沟通。如何理解?为什么不能直接使用kernel?,我们操作windows 不是直接操作windows内核,而是通过图形接口,点击,从而完成我们的操作(比如进入D盘的操作,我们通常是双击D盘盘符.或者运行起来一个应用程序)。,有相同的作用,主要是对我们的指令进行解析,解析指令给Linux内核。

2023-10-30 16:15:40 198 3

原创 【C++】IO流

在C语言中,如果想要将一个整形变量的数据转化为字符串格式,如何去做?1. 使用itoa()函数2. 使用sprintf()函数int main()return 0;运行结果:但是两个函数在转化时,都得需要先给出保存结果的空间,那空间要给多大呢,就不太好界定,而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,可以使用stringstream类对象来避开此问题。在程序中如果想要使用stringstream,必须要包含头文件。

2023-10-24 17:27:41 106

原创 【C++】类型转换

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化。1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败2. 显式类型转化:需要用户自己处理缺陷:转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换。

2023-10-22 15:53:20 125

原创 【C++】特殊类实现

拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可。原因: 1. 设置成私有:如果只声明没有设置成private,用户自己如果在类外定义了,就可以不能禁止拷贝了 2. 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单,而且如果定义了就不会防止成员函数内部

2023-10-21 16:57:32 321

原创 【C++】 智能指针

什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。// 1.内存申请了忘记释放// 2.异常安全问题Func();// 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放.

2023-10-18 16:15:18 184 1

原创 C++11

在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正

2023-10-16 14:14:04 120

原创 【哈希】——哈希的应用-位图/布隆过滤器+海量数据处理

(因为相同set会去重)比如:在布隆过滤器中查找"alibaba"时,假设3个哈希函数计算的哈希值为:1、3、7,刚好和其他元素的比特位重叠,此时布隆过滤器告诉该元素存在,但实该元素是不存在的。具体实现是求出x映射的位置,然后将1移到x的对应位置,其他位为0,0和任何数或都是原来的数,而1与x对应位置&之后都为1,这样就可以做到x对应位置为1。具体实现是求出x映射的位置,然后将1移到x的位置,然后进行取反,则其他位为1,而1与任何数与都为原来的数的值,x位置的数为0,相与之后x位置的值置为0。

2023-10-10 15:40:04 113

原创 【哈希】--unordered系列关联式容器

unordered_map在线文档说明unordered_map是存储键值对的关联式容器,其允许通过keys快速的索引到与其对应的value。在unordered_map中,键值通常用于唯一地标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同。在内部,unordered_map没有对按照任何特定的顺序排序, 为了能在常数范围内找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。

2023-10-08 12:43:35 60 1

原创 红黑树封装map和set

由于map和set的valuetype不同,我们将红黑树的模板参数改为T,T代表的就是valuetype,来区别set和value的数据类型。

2023-09-17 11:03:16 49

原创 map和set的底层结构

/ 该节点的左孩子// 该节点的右孩子// 该节点的双亲int _bf;// 该节点的平衡因子:_kv(kv),_bf(0){}// 节点的颜色RED,BLACK// 红黑树节点的定义// 节点的左孩子// 节点的右孩子// 节点的双亲(红黑树需要旋转,为了实现简单给出该字段)// 节点的值// 节点的颜色,_kv(kv),_col(RED){}思考:在节点的定义中,为什么要将节点的默认颜色给成红色的?

2023-09-13 11:16:32 150

原创 map和set

set文档介绍set是按照一定次序存储元素的容器在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。set在底层是用二叉搜索树(红黑树)实现的。

2023-08-16 15:27:58 56

原创 二叉树进阶

或者是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树。

2023-08-13 17:38:23 47

原创 C++多态

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价。必须通过基类的指针或者引用调用虚函数被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写在虚函数的后面写上 =0 ,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。

2023-08-05 14:41:34 58

原创 C++中的继承

下面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度及性能上都有问题。多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。继承和组合public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。组合是一种has-a的关系。

2023-08-01 14:24:33 135

原创 【Linux】环境基础开发工具使用

三种模式正常模式插入模式底行模式我们一共有12种总模式,大家下来可以研究一下vim操作打开,关闭,查看,查询,插入,删除,替换,撤销,复制等等操作。练习:当堂口头模式切换练习。

2023-07-30 19:16:07 82

原创 反向迭代器 + 模版进阶

【优点】模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生增强了代码的灵活性【缺陷】模板会导致代码膨胀问题,也会导致编译时间变长出现模板编译错误时,错误信息非常凌乱,不易定位错误。

2023-07-28 11:01:44 56

空空如也

空空如也

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

TA关注的人

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