自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 网络基础:数据链路层与其他协议或技术

主域名是用来识别主机名称和主机所属组织机构的一种分层结构名称,例如com:一级域名,表示这是一个企业域名;同级的还有net(网络提供商)、org(非盈利组织)等。baidu:二级域名,公司名。www:只是一种习惯用法;之前人们使用域名时往往命名成类似的格式,来表示主机支持的协议。使用dig工具分析 DNS 过程:安装dig# Ubuntu 系# CentOS系开头位置是 dig 指令的版本号。第二部分是服务器返回的详情,重要的是 status 参数,NOERROR表示查询成功。

2026-11-15 13:32:12 270

原创 网络基础:网络层

如果一个组织内部组建局域网,IP 地址只用于局域网内通信,而不直接连到 Internet 上,理论上使用任意 IP 地址都可以。IPv4 地址是一个 4 字节 32 位的正整数,一共只有 2 的 32 次方个 IP 地址,大约 43 亿左右。包含在这些范围中的都称为私有 IP,其余的则称为全局 IP(或公网 IP)。网络层的作用是:在复杂的网络环境中确定一个合适的路径。转发过程例 1:如果要发送的数据包的目的地址是。转发过程例 2:如果要发送的数据包的目的地址是。IP 地址分为两个部分:网络号和主机号。

2026-11-13 16:55:08 215

原创 Linux网络套接字编程:序列化和反序列化与TCP粘包问题

int id;// 用户编号// 用户名// 消息正文手写序列化时,我们必须约定一个双方都能解析的字节布局。每个变长字段(nametext)前面都带 4 字节长度,这样反序列化时知道要读多少字节。可以承载任意二进制(包括\0),因此长度必须由size()给出,不能用strlen。

2026-11-12 18:16:24 224

原创 网络基础:详解UDP与TCP

在延迟应答基础上,很多情况下客户端服务器在应用层也是“一发一收”,客户端给服务器说“How are you”,服务器回“Fine, thank you”;刚才我们讨论了确认应答策略, 对每一个发送的数据段, 都要给一个ACK确认应答. 收到ACK后再发送下一个数据段.这样做有一个比较大的缺点, 就是性能较差. 尤其是数据往返的时间较长的时候.情况二,数据包直接丢了,发送端连续三次收到同样一个“1001”这样的应答,就会将对应数据 1001-2000 重新发送,这种机制称为“高速重发控制”(快重传)。

2026-11-11 17:06:20 323

原创 网络基础:HTTP

应用层是我们程序员编写的、用于解决实际问题的网络程序所在的层次,它直接面向用户需求,如浏览器、邮件客户端等。无论我们采用方案一, 还是方案二, 还是其他的方案, 只要保证, 一端发送时构造的数据, 在另一端能够正确的进行解析, 就是ok的. 这种约定, 就是。协议是一种"约定".socket api的接口,在读写数据时,都是按"字符串"的方式来发送接收的.如果我们要传输一些 "结构化的数据"怎么办呢?HTTP(超文本传输协议)是应用层最核心的协议,它是基于 TCP 实现的。

2026-11-09 18:09:01 177

原创 Liunx网络编程套接字:TCP

以下通用服务器实现了一个最基本的单连接版本,即接受了一个客户端后,服务器进程就在内层循环中一直处理该客户端的请求,直到客户端断开。注意:因为TCP是字节流传输,所以这里的Recv()可能会出现只读到一部分内容。等方法整合到一个类中,实现了资源(文件描述符)的自动初始化和关闭,符合RAII设计思想。与UDP类似,针对TCP频繁的API调用,我们需要利用C++面向对象的思想进行封装(TCP编程与UDP不同,它是一种面向连接的协议,因此API的调用流程更复杂。由于 TCP 是面向连接的,客户端不需要在启动时。

2026-11-08 16:35:16 296

原创 Linux的网络编程套接字:UDP

我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?,它会返回这个静态区的指针。注意:UDP的不可靠传输,不是贬义词,而是形容UDP传输时遇到的一系列问题的处理方式。TCP的可靠传输也同理,都是来形容它们的传输时遇到问题的处理方式。我们人类习惯使用点分十进制的字符串(如 “127.0.0.1”)来表示IP地址,而网络传输中IP地址是一个32位的整数。

2026-11-08 15:41:01 457

原创 网络基础(1)

当数据帧到达目的主机后,每层协议会剥掉相应的首部,并根据首部中的“上层协议字段”将数据交给对应的上层协议处理,这个过程称为“分用”。打个简单的说法,就是你给你朋友和家人打电话是你跟通信设备打还是和你的朋友家人打,在逻辑上你是和你的朋友家人打的。TCP/IP是一组协议的代名词,它采用了5层的层级结构(在部分教材中,物理层被归入数据链路层,称为四层模型)。(LAN)通常指覆盖范围较小(如一个办公室、一栋大楼)的网络,计算机数量较多,一般通过交换机和路由器连接在一起,具有高带宽、低延迟的特点。

2026-11-04 15:22:50 164

原创 Linux多线程(下)

线程池是一种线程使用模式。生产者和消费者彼此之间不直接通讯,而 通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者 要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。其与普通的队列区别在于,当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中被放入了元素;当队列满时,往队列里存放元素的操作也会被阻塞,直到有元素被从队列中取出(以上的操作都是基于不同的线程来说的线程在对阻塞队列进程操作时会被阻塞)

2026-11-03 17:10:48 226

原创 Linux多线程(上)

在Linux系统中,线程(Thread)是进程内部的一个执行路线或控制序列。一个进程至少包含一个主执行线程。从操作系统调度的角度来看,线程是CPU调度的最小单位,而进程是资源分配的最小单位。在Linux内核中,线程本质上是轻量级进程(LWP, Light Weight Process),它们在CPU眼中依然被视为PCB(进程控制块),只是比传统进程更轻量化。

2026-11-02 16:57:27 221

原创 Linux 进程信号

每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中有定 义编号34以上的是实时信号,本章只讨论编号34以下的信号,不讨论实时信号。

2026-11-01 20:12:51 417

原创 Linux进程间通信

数据传输:一个进程需要将它的数据发送给另一个进程资源共享:多个进程之间共享同样的资源。通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”

2026-10-30 18:10:04 120571

原创 C++STL之空间配置器

空间配置器,顾名思义就是为各个容器高效的管理空间(空间的申请与回收)的,在默默地工作。虽然在常规使用STL时,可能用不到它,但站在学习研究的角度,学习它的实现原理对我们有很大的帮助。

2026-10-28 17:04:18 272

原创 C++的IO流

C++ 标准库已经为所有内置类型重载了<<和>>,所以cincout可以直接输入输出intdouble等类型。对于自定义类型,如果要支持标准输入输出,需要自己重载流插入运算符<<和流提取运算符>>。通常把它们写成全局函数,并声明为类的友元,以便访问私有成员;返回值必须是流引用,才能支持链式操作和这类写法。public:// 示例规则:年份为 0 时认为无效,可用于结束循环= 0;int _month;int _day;return in;

2026-10-27 16:44:28 83

原创 C++的类型转换

C语言在赋值、函数传参、返回值接收等场景中,如果左右两侧类型不一致,就可能发生类型转换。C语言把类型转换分为两类:隐式类型转换和显式类型转换。隐式转换由编译器在编译阶段自动完成,显式转换由程序员通过强制转换语法完成。 C风格转换的核心问题是“转换形式统一但语义不明确”,容易把精度丢失、指针截断、去除 const 等风险混在一起,导致代码难以审查和排错。我们看上述代码,我们能发现C语言的隐式类型转换问题其实挺大的。那么为什么全部要求显示类型转换不就行了。C++ 在兼容 C风格转换的同时,引入了四种类型转换

2026-10-26 16:55:38 53

原创 C++特殊类设计

为什么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法。最开始部落之间打仗时都是人拼人的对砍。后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后来孙子就总结出了《孙子兵法》。孙子兵法也是类似。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

2026-10-25 17:03:03 460

原创 C++ 智能指针

内存泄漏:程序申请了内存,但因为设计错误或异常路径,失去了对该内存的控制,导致无法释放。不是内存物理消失,而是这部分内存无法再被使用。危害:长期运行的程序,如操作系统、后台服务,内存泄漏会导致响应越来越慢,最终卡死。delete p1;delete p2;抛异常之后就会导致申请的内存无法释放。

2026-10-22 18:17:00 202

原创 C++11(下)

C++11中线程类在C++11之前,涉及多线程问题都是和平台相关的(如Linux下的pthread,Windows下的API),可移植性差。C++11中最重要的特性就是对线程进行支持了。要使用标准库中的线程,必须包含<thread>头文件。thread函数名功能thread()构造一个线程对象,没有关联任何线程函数,即没有启动任何线程构造一个线程对象,并关联线程函数fn,args1,args2,…为线程函数的参数get_id()获取线程idjionable()

2026-10-21 20:42:57 259

原创 C++11(中)

上一章结尾我们说到STL新增了一些容器和接口,容器部分我也了解的差不多了,接口我们还没详细了解,C++11新增的函数接口emplace_back为主的插入函数接口,那为什么要增加这些接口呢?按照语法,右值引用只能引用右值,但右值引用一定不能引用左值吗?函数位于 头文件中,该函数名字具有迷惑性,它并不搬移任何东西,唯一的功能就是将一个左值强制转化为右值引用,然后实现移动语义。在xhs::string中增加移动构造,移动构造本质是将参数右值的资源窃取过来,占位已有,那么就不用做深拷贝了,所以它叫做。

2026-10-21 18:31:01 328

原创 C++11 (上)

C++标准委员会本计划每5年更新一次,原本叫C++07,后来因为完不成改叫C++0x,最终在2011年定稿为C++11。它是一次“10年磨一剑”的更新,包含约140个新特性和约600个缺陷修正。1998年是C++标准委员会成立的第一年,本来计划以后每5年视实际需要更新一次标准,C++国际标准委员会在研究C++ 03的下一个版本的时候,一开始计划是2007年发布,所以最初这个标准叫C++ 07。但是到06年的时候,官方觉得2007年肯定完不成C++ 07,而且官方觉得2008年可能也完不成。

2026-10-20 17:21:17 102

原创 C++ 哈希(下)

解释一下这里find和erase为什么要有返回End(),因为当find的查找我们在之前的使用接口的时候展示过当== end()时就证明没有找到key,所以这里返回End()。比如:向布隆过滤器中插入:“baidu”,这个插入过程布隆过滤器会调用3个哈希函数生成3个哈希值,为什么是3个,因为那个创造布隆过滤器的大佬通过数学的方式计算出来的,最优是3到4个。:使用 (K) 个不同的哈希函数,算出 (K) 个不同的位置,将这 (K) 个比特位置为 1。,那算哈希地址和比较的时候,怎么把 K 抽出来?

2026-10-19 17:06:04 242 1

原创 C++ 哈希(上)

由于表长是定值,α与“填入表中的元素个数”成正比,所以,α越大,表明填入表中的元素越多,产生冲突的可能性就越大;最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同,本文中只对。如果是10乘对应的倍数还是会出现该倍数的因子一直存在,比如扩容3倍,就得30,那么还是会出现2、3、5的因子,最重要的是3倍扩容会极大的浪费空间。如果已存在,则返回对应的。

2026-10-18 17:33:18 385

原创 C++异常

实际项目中,如果每个人随意抛异常,外层调用者无法统一处理。定义一个基类Exception。所有异常继承自它。外层只捕获基类引用,利用多态调用what()。派生类可以携带更多信息,比如 SQL 语句、HTTP 类型等。// 1. 自定义异常基类public:// 使用 virtual 保证多态,noexcept 保证不抛异常protected:int _id;// 2. 派生类:数据库异常public:// 这里为了演示简单拼接,实际应避免在 what 中频繁分配内存。

2026-10-15 17:11:13 148

原创 C++ set 和 map

在初阶阶段,我们已经接触过STL中的部分容器,比如:、、、等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。那什么是关联式容器?它与序列式容器有什么区别?关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的键值对,在数据检索时比序列式容器效率更高。用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中

2026-10-14 17:24:53 161 2

原创 C++ 红黑树

红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。上述5点性质是构建红黑树的必要条件,那么为什么满足上面的性质,红黑树就能保证:其最长路径中节点个数不会超过最短路径节点个数的两倍?我们设最短路径黑色节点数为 。红黑树结构这里节点的定义是为了后续实现关联式容器简单,给红黑树实现增加一个头节点,因为跟节点必须为黑色,为了与根节点进行区分,将

2026-10-13 17:09:44 147

原创 C++ AVL 树

/ 该节点的左孩子// 该节点的右孩子// 该节点的双亲T _data;int _bf;// 该节点的平衡因子。

2026-10-12 16:51:42 161

原创 C++二叉搜索树

二叉搜索树和普通二叉树的区别就在于插入和删除操作,其他的可以说区别并不是很大,因为二叉搜索树需要保证没错插入和删除后中序遍历都必须是有序的。我们知道二叉搜索树每次插入和删除都是先查找的,那么对于有 n 个节点的 BST,若每个元素查找概率相等,则平均查找长度是节点深度的函数。我们发现二叉搜索树的构建条件是:左子树的所有值最小,其次是根,最大的是右子树的值。,KV和K在实现上不同的点是插入和删除操作,KV模型插入时需要将同时插入。替换后,问题转化为删除这个最小节点,而它最多只有右孩子,容易删除。

2026-10-11 17:36:50 122

原创 C++多态

必须通过基类的指针或者引用调用虚函数;被调用的函数必须是虚函数;派生类必须对基类的虚函数进行重写。比如:我们回到刚才谈论的买票操作多态的构成条件中重写我们能理解,毕竟不重写这个函数怎么做到同一个接口不同的行为呢?例外两个我们就不是很能理解,比如为什么必须通过基类的指针或者引用调用虚函数和被调用的函数必须是虚函数?为什么必须通过基类指针/引用调用虚函数,直接赋值再调用不行吗?为什么调用的时候必须是虚函数,不是虚函数不行吗?为什么必须通过基类指针/引用调用虚函数?

2026-10-08 18:57:52 322

原创 C++多继承

很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度及性能上都有问题。多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。

2026-10-06 17:57:08 156

原创 C++继承

继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。public:Person(string name = "张三", int age = 18)_age(age){}protected:int _age;

2026-10-05 16:52:55 230

原创 数据结构番外:环形队列

环形队列用。

2026-10-04 16:53:52 574

原创 C++模板进阶

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。即C/C++程序要运行,一般要经历:预处理 -> 编译 -> 链接。编译时对程序按照语言特性进行词法、语法、语义分析,错误检查无误后生成汇编代码。注意头文件不参与编译,编译器对工程中的多个源文件是分离开单独编译的。链接时将多个obj文件合并成一个,并处理没有解决的地址问题。优点模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生。

2026-10-03 16:52:43 323

原创 C++优先级队列和仿函数

本质是一种容器适配器,底层通过封装其他容器(默认vector)并使用堆算法实现。数据结构:逻辑上是一个堆,默认是大堆(最大元素在堆顶)。操作特性push(x),时间复杂度 O(log n)pop(),时间复杂度 O(log n)top(),时间复杂度 O(1)只能访问堆顶元素,不能遍历。默认行为:使用less<T>比较,构造大堆,即top()返回最大元素。底层容器要求:支持随机访问迭代器,如vectordeque。默认vector仿函数(Functor),也叫。

2026-09-30 16:42:30 235

原创 C++ stack和queue

stack介绍文档本质stack是一种容器适配器,专门用于后进先出(LIFO)的上下文环境。操作限制:只能从容器的一端(栈顶)进行插入和删除。底层结构:作为容器适配器实现,是对特定容器类的封装,提供一组特定成员函数访问元素。元素从底层容器的尾部(栈顶)压入和弹出。底层容器要求,必须支持以下操作:empty():判空back():获取尾部元素:尾部插入pop_back():尾部删除可用底层容器vectordequelist均满足要求。默认底层容器deque。queue的介绍文档本质。

2026-09-29 17:33:37 194

原创 C++list类

list文档介绍list 是 C++ STL 中的序列式容器,底层是带头结点的双向循环链表。可以在常数时间 O(1) 内,在任意位置插入和删除元素。支持前后双向迭代。不支持随机访问,访问第 n 个元素需要从 begin() 或 end() 线性移动,时间复杂度 O(N)。每个节点独立存储,节点中保存前驱和后继指针。与 forward_list 相比,forward_list 是单链表,只能向前迭代,更节省空间,但功能更少。

2026-09-28 19:17:31 232

原创 C++vector类

vector 是 STL 中的序列容器,本质是一个可变大小的动态数组。核心特性:连续存储:和数组一样,元素在内存中连续存放,支持下标随机访问,效率为 O(1)。动态扩容:大小可自动增长,无需手动管理内存。扩容机制:当空间不足时,会分配一块更大的新空间,将旧元素搬移过去,再释放旧空间。这个过程代价较高,因此 vector 不会每次插入都扩容,而是按一定倍数增长(VS 下约 1.5 倍,g++ 下约 2 倍)。适用场景:频繁随机访问、尾部插入/删除高效;非尾部插入/删除效率低(需搬移元素)。

2026-09-27 19:30:17 542

原创 C++模拟实现string类

这种拷贝方式,称为。

2026-09-24 17:42:23 162

原创 C++string类

写时拷贝就是第二种吃的时候在洗碗的表现。本章节我们了解了C++的string类,下一章节我们就开始自己去实现属于直接的string类了,为什么要实现string类,因为我要通过实现string类来了解底层到底是怎么回事从而进一步加强我们对该类的了解。这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。其实还有一些原因就不展开的说了,因为在后续我们对C++的不断的学习就会不断的了解这些原因。

2026-09-23 17:41:41 157

原创 C++了解STL

STL(Standard Template Library-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

2026-09-22 17:27:34 114

原创 C++模板初阶

class 类模板名// 类内成员定义比如:动态顺序表public:, _size(0){}~Vector();注意Vector不是具体的类是编译器根据被实例化的类型生成具体类的模具;类模板中函数放在类外定义时,需要加模板参数列表。

2026-09-21 17:59:40 56

空空如也

空空如也

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

TA关注的人

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