自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 【C++】--- 类型转换

class Apublic:A(int a):_a1(a), _a2(a):_a1(a1),_a2(a2)private:int main()//单参和多参的隐式类型转换A aa1 = 1;//隐式类型产生临时对象return 0;int y = b1;return 0;

2025-12-11 16:23:25 771

原创 【C++】--- 特殊类设计

单例模式: 一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。一般情况下,如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,此时使用饿汉模式来避免资源竞争,提高响应速度更好,因为它在程序运行时就构建好了,运行时不用竞争。如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取 文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化, 就会导致程序启动时非常的缓慢。

2025-12-11 13:45:33 606

原创 【C++】--- C++11

在没有增加移动赋值之前,由于原有的拷贝赋值函数采用的是const左值引用接收参数,因此无论赋值时传入的是左值还是右值,都会调用考贝赋值函数。在增加移动赋值之后,由于移动赋值采用的是右值引用接收参数,因此如果赋值时传入的是右值,那么就会调用移动赋值函数(最匹配原则)深拷贝的类的拷贝赋值函数要做的是深拷贝,而移动赋值函数中只需要进行资源的转移即可,因此调用移动赋值的代价比调用拷贝赋值的代价小。

2025-12-10 17:30:11 1111

原创 【Linux】--- 多路转接select / poll / epoll

select的特点select可以监控的fd数量是有上限的,取决于sizeof(fd_set)的值select的fd集是个输入输出型参数,而且将三种事件分离,用户输入时根据需要设置自己所关心的fd和对应关心的事件,输出时返回的是关心的fd中哪些fd就绪了该事件。

2025-12-07 23:17:14 775

原创 【Linux】--- 五种IO模型

虽然采用的是信号驱动,只是改变了等的不同,数据拷贝还得自己做,因此还是属于同步IO,只要参与IO过程的(等+拷贝)就是同步IO,需要注意的是,信号驱动式IO也是只有一个文件描述符,因此IO效率这块还是取决于发送方,效率和非阻塞/阻塞IO没有本质区别,只不过类似非阻塞IO一样,,能合理利用等的时间,而且不用自己轮询。我们首先需要认识到,在任何通信场景中,IO效率一定是存在上限的,好比花盆里长不出参天大树,它一定会受到硬件的限制,比如网卡、带宽等限制,我们需要在硬件自身效率范围内讨论IO,因此我们认为,

2025-12-06 17:16:52 1175

原创 【C++】 --- 哈希

对于线性探测的几个操作:a. 查找:按照哈希函数确定映射位置,从映射位置开始往后找,如果位置状态为EXIST&&该位置元素的key符合我们要查找的key,则返回;如果位置状态为空,说明不存在。b. 插入:在对应元素没有被重复插入的情况下,如果映射位置为空直接插入,否则往后找第一个状态为EMPTY或DELETE后的位置插入。c. 删除:先查找到对应位置,可以复用查找接口,如果存在直接修改对应存储位置的状态为DELETE即可。对于上面的插入操作是存在漏洞的,有没有可能找不到位置插入呢?

2025-11-29 21:17:46 1240

原创 【C++】--- 智能指针

如果管理的是多个对象,需要使用delete【】释放资源,但是unique_ptr默认采用的是delete,此时会产生未定义行为,因此需要显示。上面的代码存在的一个问题是,由于没有显示的实现拷贝构造,因此使用的是默认拷贝构造,默认拷贝构造对内置类型,因此会导致析构两次。weak_ptr虽然不增加shared_ptr的引用计数,但是它内部是有计数的,计数还有多少个shared_ptr存活。6. 但是_next属于node的成员,node1释放了,_next才会析构,而node1由_prev管理,_prev。

2025-11-25 20:42:04 744

原创 【项目】--- Boost搜索引擎

去标签主要是去掉html文档中的标签,提取标签内的内容,从这些内容中提取title、content、url。做完去标签和数据清洗工作,需要保存到一个统一的文件方便建立正/排索引,为了方便读取每一个文件的内容,我们需要进行约定存储格式,这里我们约定每个文档内容之间以\n作为分隔,这样后续提取按行读取的就是一个文档的内容了,而文档内部各个要素之间以‘\3’作为分隔,\3是不外显的,因此不会污染我们的文档,eg:title1\3content1\3url1\3\n(第一个文档)title2\3....

2025-11-25 17:05:35 943

原创 【Docker】--- Docker初识

容器共享宿主机内核,不需要完整的操作系统,轻量、启动快、资源利用率高,但隔离性略弱于虚拟机。

2025-11-19 16:01:50 1170

原创 【Docker】--- 技术架构演进之路

在单机架构的问题上,我们一般会有两个方向的解决方案。采取的解决方案是一台数据库作为主数据库,主要进行数据库的写入和读取操作,而其他数据库作为从数据库,进行数据库的读取操作,主数据库写入之后往从数据库同步更新,这样子数据库的读请求就能被其他数据库分担,实际场景中读请求是比写居多的,而写操作也得到一定提升,同时一个从数据库挂了,还可以从其他数据库读。在用户量和数据量较小的场景下,单机架构是可以支持较高的并发和较大的数据存储的,而且部署简单成本低,但是如果业务持续增长,并发量提高,是会达到性能瓶颈的,

2025-11-19 15:13:51 1022

原创 【基于one-loop-per-thread的高并发服务器】--- 项目测试

本篇博客是对仿muduo的高性能服务器这个项目的延续,主要对项目进行一些测试,如性能测试、长连接测试、超时连接测试、错误请求测试、连续同时多条请求测试、大文件传输测试、业务处理超时测试等。主要目的是测试服务端是否能维护长链接,测试方案是创建一个客户端持续给服务器发送数据,直到超时时间,查看是否会释放连接,不释放才是正常的,这里我们设置超时时间是10s。本次性能测试采用的是hey,hey是一款使用Golang开发的HTTP压力测试工具,它的主要功能是模拟大量的并发请求,以测试服务器的性能和和稳定性。

2025-11-15 11:01:29 1336

原创 【仿RabbitMQ的发布订阅式消息队列】 ---- 功能测试联调

本篇博客主要是对消息队列项目组件的功能的一个测试,主要测试点在于在不同模式下的交换机,客户端是否能正确收到订阅队列的消息,这里我们测试的是广播交换、直接交换和主题交换。

2025-11-11 15:32:48 545

原创 【基于one-loop-per-thread的高并发服务器】--- 自主实现HttpServer

因此它的内部是需要包含一个TcpServer对象的,同时由于我们支持的是HTTP协议,还需要提供两个接口,一个是连接建立成功的设置上下文接口,还有一个是数据处理接口,收到数据之后需要根据HTTP协议解析请求然后组织回复发送,最后还要包含一个HashMap存储请求与处理函数的映射表,组件使用者向HttpServer设置哪些请求应该使用哪些函数进行处理,等TcpServer收到对应的请求就会使用对应的函数进行处理。该模块是个协议上下文模块,用于在收到数据之后解析数据,记录HTTP请求的接收和处理进度的。

2025-11-10 11:31:21 878 1

原创 【基于one-loop-per-thread的高并发服务器】--- Server模块

管理的内容主要包括套接字的管理,可以对套接字进行各种操作,还有对于连接事件的管理,比如可读、可写、挂断、任意,也有对于缓冲区的管理,方便和Socket进行数据的发送和接收,还有对于协议上下文的管理,用来记录请求数据的发送过程,以及对用户设置各种回调的功能,最后还有连接的状态方便对连接进行维护。基于此,在扩容的时候,如果在写入数据时,写指针后续剩余空闲空间不足,首先应该考虑整体缓冲区空闲空间(写指针后+读指针前)是否足够,足够则将原来区域的可读数据移动到起始位置 ,更新指针,然后再写入新数据;

2025-11-09 15:10:27 1234

原创 【基于one-loop-per-thread的高并发服务器】--- 前置技术

这样,一旦心搏函数tick被调用,超时时间最小的定时器必然到期,我们就可以在tick函数中处理该定时器。也就是说我们这里是个升序链表,每个节点是一个定时任务,按照超时时间排序,因此在链表中添加定时任务,无非是比较各个节点的超时时间,将定时器节点插入到合适位置,调整定时器/删除定时器也类似,需要比较超时时间,保证链表的升序性。计数为2,则第30s的定时任务被释放的时候,计数-1,变为1,并不为0,则并不会执行实际的析构函数,那么就相当于这个第30s的任务失效了,只有在第40s的时候,这个任务才会被真正释放。

2025-11-05 17:03:04 769

原创 【基于one-loop-per-thread的高并发服务器】--- 项目介绍&&模块划分

先看Poller模块,这个模块主要做的是对于一个文件描述符进行各项事件的监控操作,包含有添加,修改,移除事件监控的操作,而每一个Poller管理的描述符又会和Channel模块产生联系,因为Channel模块本身就是用来对于每一个描述符可能包含的事件做出的管理,当管理的描述符内部触发了某种事件,那么就会相应的调用这些事件内部的一些回调函数,这是提前就被设置好的内容。该模块主要是为了对通信连接进行一个整体管理,从而简化外界对连接的不同处理,增加连接操作的灵活性和便捷性。

2025-11-03 21:29:33 1105

原创 【仿RabbitMQ的发布订阅式消息队列】--- 客户端模块

该模块同样是针对muduo库客户端的二次封装(与服务端不同的是,客户端只需要向服务发起一个连接,服务端需要接受多个连接),该模块主要就是向用户提供创建channel信道的接口,创建信道之后,拿着信道对象使用服务。对于普通服务,主要的思路其实都是构造对应的请求,然后发送给服务端等待响应,由于muduo库的接口是异步的,因此需要互斥锁&&条件变量来保证同步等待响应,因此我们统一封装了等待响应的接口。服务端的信道是为客户端的队友请求提供服务的,而客户端的接口服务是为了用户具体需要而服务的,即。

2025-11-02 15:10:40 1028

原创 【仿RabbitMQ的发布订阅式消息队列】--- 服务端模块

该模块主要是对交换机相关数据的管理,主要的是先在内存中管理,再根据是否持久化进行持久化。1. 交换机数据类:a. 交换机名称b. 交换机类型c. 交换机是否持久标志d. 是否自动删除标志e. 其他参数2. 交换机数据持久化类a. 声明/删除交换机表b. 新增交换机数据c. 移除交换机数据d. 查询所有交换机数据 / 恢复历史数据(为内存管理提供的接口)e. 查询指定交换机数据(根据名称)3. 交换机数据内存管理类a. 声明交换机并添加管理(存在则OK,不存在则创建)b. 删除交换机c. 获取指定交换机d.

2025-11-01 22:45:05 1251 1

原创 【仿RabbitMQ的发布订阅式消息队列】--- 前置技术

ProtoBuf(全称Protocol Buffer)是数据结构序列化和反序列化框架,语言无关、平台无关:即ProtoBuf支持Java、C++、Python等多种语言,支持多个平台高效 : 即比XML更小、更快、更为简单扩展性、兼容性好 : 你可以更新数据结构,而不影响和破坏原有的的旧程序编写.proto文件,目的是为了定义结构对象(message)及属内容使用protoc编译器编译.proto文件,生成一系列接口代码,存放在新生成头文件和源文件中。

2025-10-29 16:28:52 1535 1

原创 【仿RabbitMQ的发布订阅式消息队列】--- 模块设计与划分

假设消息都会进行持久化存储 , 操作过程中会存在垃圾回收操作(其实就是将有效消息读取出来,然后重新截断文件,将消息连续写入文件中,操作完文件中都是有效消息),但是垃圾回收会改变消息的存储位置,但是内存中的消息也会存储消息的实际存储位置,垃圾回收后就不一致了,因此每次垃圾回收后要用新的位置去更新持久化消息的信息。当前消费者订阅了某一个队列的消息,这个队列有了消息后,就会将消息推送给这个客户端,这时候收到了消息则使用回调函数进行处理,处理完毕后就会根据确认标志决定是否进行消息确认。但是我们的连接中还有一个。

2025-10-28 21:16:47 1032

原创 【仿RabbitMQ的发布订阅式消息队列】--- 概念理解

消息确认后,RabbitMQ才会从队列删除这条消息,RabbitMQ不会为未确认的消息设置超时时间,它判断此消息是否需要重新投递给消费者的唯一依据是消费该消息的消费者连接是否已经断开。"的关系,即一个Exchange可以绑定多个 Queue (可以向多个 Queue 中转发消息) ,一个 Queue 也可以被多个 Exchange 绑定 (一个 Queue 中的消息可以来自于多个 Exchange)•Topic 是发一个画图红包, 发 10 块钱红包, 同时出个题, 得画的像的人, 才能领。

2025-10-28 13:45:55 1161 1

原创 gRPC通信流程学习

需要注意的是,和普通的.proto文件不同的是,普通Proto只关注数据序列化,只描述数据结构,生成而gRPC的.proto还要额外加。注意:Status 是 gRPC 的返回类型,用来表示一个 RPC 调用的状态,表示这次RPC调用是否成功,要与上层设置的错误码进行区分。1. 创建到服务端的channel:它是到服务端的“连接抽象”,封装了 HTTP/2 连接池、重试、负载均衡(按配置)等。序列化格式,支持双向流、多路复用、头部压缩等特性,适用于微服务、移动应用、后端服务等场景。

2025-10-26 22:36:25 888

原创 【仿RabbitMQ的发布订阅式消息队列】--- 介绍

其实就是把阻塞队列封装为一个独立的服务器程序,并且赋予更丰富的功能,它主要用于异步传输数据,允许程序应用程序通过发送和接收消息来进行解耦、异步和可靠的通信。,其中业界有不少成熟的消息队列中间件,比如RabbitMQ,Kafka,RocketMQ等,本项目主要是用来对消息队列内部主要工作和设计流程进行学习的一个组件项目。之前接触类似消息队列的概念,主要是在学习生产者消费者模型中了解到的阻塞队列。在学习分布式系统的时候,发现消息队列的应用较为广泛,它可以作为。2. protobuf安装。5. GTest安装。

2025-10-26 20:24:57 704

原创 【同步 / 异步 日志系统】--- 全局接口 && 性能测试

我们可以看到非安全模式下,没有同步和线程阻塞的开销,不会因为异步工作线程没处理完而阻塞,多线程异步只管多个线程往内存放,虽然锁冲突比单线程严重些,但是多线程所以单位时间处理的数据量要大写,因此锁冲突显得没那么严重了,此时更看重CPU和内存性能的上限。到目前为止,用户可以日志器建造者来创建不同的日志器,必要时,还可以使用全局日志器建造者,添加到管理器中管理,方便全局使用。我们可以看到多线程的性能反而比单线程低,这是因为同步日志器多线程锁冲突严重,同时我们这里落地方向是写磁盘,磁盘性能已经达到上限了。

2025-10-25 20:54:04 1424 1

原创 【同步 / 异步 日志系统】--- 日志器管理器&&全局日志器建造者

因为全局日志器建造者调用build时,会调用GetInistance()获取单例对象,如果单例内部的静态局部变量是第一次构造,此时就会又调用日志管理器的构造造成死循环。前面我们实现了局部日志器的创建 , 但是这会受到日志器所在作用域的访问属性限制,为了突破访问区域的限制,我们可以创建一个。2. 可以在程序的任意位置,获取相同的单例对象,获取其中管理的日志器进行日志输出。这样就能让用户在不创建任何日志器的情况下也能进行标准输出的打印,方便用户的使用。拓展:可以在单例管理器创建的时候,以便于能够在任意位置。

2025-10-24 10:48:48 901 1

原创 【同步 / 异步 日志系统】 --- 日志器模块

从上面的使用同步日志器demo代码来看,创建一个日志器需要提前准备后默认限制等级,格式化器对象,日志落地数组等零部件,这对于用户来说难免有些复杂,因此我们可以使用建造者模式来建造日志器,简化创建日志器的行为。前面我们实现了日志消息格式化,日志落地的功能,接下来需要将他们整合为一个日志器对象,提供不同等级的日志输出。但是注意需要加锁来应对线程安全交叉日志输出的问题。异步日志器采用双缓冲区思想,在外界将任务数据添加到输入缓冲区中后,异步线程需要对处理缓冲区中的数据进行处理,处理缓冲区中没数据则交换缓冲区。

2025-10-23 21:31:39 989

原创 【同步 / 异步 日志系统】--- 日志消息格式化&&日志落地

(处理过程中要把相应信息保存起来) 我们这个接口主要要做的是根据格式化字符串创建出一个个格式化子项对象,然后保存到数组里,此时我们需要传约定的格式化字符来说明清楚要创建什么类型的格式化子项对象,同时有的格式化子项还需要额外的数据,因此我们采用键值对key-value的格式保存对应的信息。我们希望对不同落地方向类的采用统一的结构来创建,不对上层暴露创建逻辑,实现创建-使用的分离,因此这里我们使用工厂模式。4. 扩展:支持落地反向的扩展,即用户可以自己编写一个新的落地模块,将日志进行其他方向的落地。

2025-10-23 12:27:50 939

原创 【同步 / 异步 日志系统】 --- 模块设计&&日志等级&&日志消息类

本项目要实现的日志系统主要是为了将一条消息进行格式化成为指定格式的字符串后 , 然后写入到指定位置。来表示各个等级,将来利用枚举值的大小来限制不同等级的输出,同时将来我们日志等级是需要打印出对应字符串给用户展示的,因此我们还需要提供。日志需要写入到指定位置(可以是标准输出,指定文件,滚动文件等),因此日志系统需要支持将日志消息落地到不同为止。对于日志等级,将来每一个项目中都会设置一个默认的日志输出等级,4. 不同日志输出语句有各自的重要程度,因此需要。本篇博客主要是对日志系统的模块进行简单的概述。

2025-10-22 20:37:41 1029

原创 【同步/异步 日志系统】 --- 前置技术

但是这种做法是存在线程安全的,有可能多个线程同时发现指针为null,同时去new多个对象,不满足单例的要求,此时我们需要进行加锁来保证多线程情况下只调用一次。

2025-10-22 16:51:38 827

原创 【同步/异步 日志系统】--- 介绍

之前我简单封装的宏日志打印工具只是单纯使用单线程来执行日志语句的输出,简单的输出到控制台上,这样才能执行后面的业务逻辑,这样的效率无疑是低下的,同时日志输出方向比较死板以及格式不易扩展。在学习和使用了优秀的日志系统,比如spdlog,zlog等日志系统 , 打算做这个高性能的日志系统组件项目, 应用到日志打印工作中,该日志系统亮点是,异步日志的缓冲区主要使用了。异步日志指的是在进行日志输出时,日志输出语句和业务逻辑语句并不在一个线程中运行,而是有专门的线程在进行日志输出。日志输出语句与程序的。

2025-10-21 22:49:12 854

原创 【与C++的邂逅】--- 继承和多态扩展

要注意的是这里必须借助内存窗口才能看到真实的底层对象内存模型 , VS编译器的监视窗口是经过特殊处理的,以它的角度给出了一个方便看的样子,但并不是本来的样子。0x14对应的是十进制的20,我们发现它恰好是d对象模型中B对象部分距离A部分的相对偏移量距离,0x0C对应的是十进制的12,它恰好是d对象模型中C对象部分距离A部分的相对偏移量距离。Q:还存在的一个问题是Derive对象中重写的Base1虚表的func1地址和重写Base2 虚表的func1地址不⼀样,这是为什么呢?而虚表指针是在运行时产生确定的。

2025-10-18 20:57:35 1006

原创 【C语言的小角落】--- 理解函数栈帧的创建与销毁

C语言是一门面向过程的语言 , 因此我们会把一个个功能封装为一个个函数,可以说,C语言程序是以函数为基本单位的,那函数是如何调用的?函数返回值是如何带回的?函数参数是如何传递的?这些问题都和函数栈帧有关。简单来说,函数栈帧()就是函数调用过程中在程序的调用栈(call stack函数参数和函数返回值临时变量(包括函数的非静态的局部变量以及编译器自动生产的其他临时变量)保存上下文信息(包括在函数调用前后需要保持不变的寄存器)

2025-10-16 20:37:09 1351

原创 【前端基础】--- HTML

 个人主页  :  9ilk   专栏  :  前端基础 Web前端是用来给用户呈现一个个网页的,一个软件通常情况下是由于前端+后端完成的。生活中我们遇到的Web页面,PC端程序页面,移动端APP页面等就是前端页面,前端是指用户在浏览器中看到并与之交互的部分。 HTML()是前端开发的基础,它用来定义网页的结构和内容。所谓 指的是文本、声音、图片、视频、表格、链接等。我们可以简单的使用记事本编写一个html页面:标签名()放到<>中大部分标签成对出现,为开始标签,为结束标签少数标签只有开始标

2025-04-15 16:13:10 1440 21

原创 【Git】--- 企业级开发流程

测试系统的完善和成熟也是衡量一个软件企业整体水平的重要指标之一,测试往往被忽视,因为它对软件开发企业不产生直接的效益,但是它却是对软件质量的最终保障,乃至项目能否成功的重要因素。对于用户来说 , 他们所在的环境需要是代码稳定,无bug来确保用户体验良好,开发者不能在该环境里做实验或者随意改动,否则会影响用户的正常使用。对于规模比较大的公司来说,其实不止这几个环境,比如项目正式上线前还存在仿真/灰度环境,再比如还存在多套测试环境,以满足不同版本上线前测试的需要。软件的规模也在逐渐变得庞大。

2025-04-12 15:43:19 1451 19

原创 【Git】--- 多人协作实战场景

在同一分支下进行多人协作的工作模式通常是这样:1. 首先,可以试图用git push 远程仓库 远程分支 推送自己的修改。2. 如果推送失败,则因为远程分支比你的本地更新,需要先使用git pull试图合并。3. 如果合并存在冲突,则解决冲突,并在本地提交。4. 没有冲突或解决完冲突之后,再用git push 远程仓库 远程分支 推送即可。5. 功能开发完毕,将分支merge进master,最后删除分支。当多人各自开发一个功能模块时 :1. 各自可以在远程或本地新建分支进行功能开发。

2025-04-10 22:03:29 1014 13

原创 【Git】--- Git远程操作 && 标签管理

1. git clone --- 克隆仓库2. git remote [-v] --- 查看远程仓库信息3. git push 远程仓库名 本地分支:远程分支 --- 向远程仓库推送4. git pull 远程仓库 远程分支:本地分支 --- 拉取远程仓库5. 配置命令别名:git config alias.xxx 命令。

2025-03-25 21:00:00 1528 25

原创 【Git】--- 分支管理

1. 创建分支 : git branch2. 切换分支 : git checout3. 创建 + 切换分支 : git checkout -b4. 合并分支 : git merge5. 删除分支 : git branch -d6. 查看分支情况 : git log --graph --abrev-commit7. no-ff模式合并 : git merge --no-ff -m "message"

2025-03-24 20:20:38 1959 20

原创 【动态规划】--- 路径问题

由状态转移方程得知,我们依赖(i+1,j)和(i,j+1)位置的状态,因此我们应该。

2025-03-18 16:54:05 1237 20

原创 【Git】--- 初识Git && Git基本操作

通过新建或粘贴进目录的文件,并不能称之为向仓库中新增文件,而只是在。

2025-03-16 22:06:03 1664 16

原创 【MySQL】 --- 视图特性 && 用户管理

Table: emp`empno` int(6) unsigned zerofill NOT NULL COMMENT '雇员编号',`ename` varchar(10) DEFAULT NULL COMMENT '雇员姓名',`job` varchar(9) DEFAULT NULL COMMENT '雇员职位',`mgr` int(4) unsigned zerofill DEFAULT NULL COMMENT '雇员领导编号',

2025-02-19 09:41:34 1324 25

空空如也

空空如也

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

TA关注的人

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