自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(五)

摘要:本文介绍了一个虚拟机管理系统,该系统整合了交换机、队列、绑定和消息管理模块,实现了完整的消息队列功能。系统包含交换机管理(声明、删除、查询)、队列管理(声明、删除)、绑定管理(绑定、解绑、查询)以及消息管理(发布、消费、确认)等功能。特别实现了三种交换机路由策略:广播交换(无条件转发)、直接交换(严格匹配routing_key)和主题交换(支持通配符匹配)。在主题交换中,详细设计了binding_key和routing_key的匹配算法,使用动态规划处理"*"和"#&qu

2025-08-01 16:16:42 779

原创 C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(四)

需要特别说明的是,消息的存储并没有使用数据库,因为消息长度通常不定,且有些消息可能会非常庞大,因此并不适合存储在数据库中,因此我们的处理方式(包括RabbitMQ)是直接将消息存储在文件中进行管理,而内存中管理的消息只需要记录好自己在文件中的所在位置和长度即可。为了便于管理,消息管理以队列为单元进行管理,因此每个队列都会有自己独立的数据存储文件,在存储消息时,先存储消息的长度,再存储消息主体。

2025-07-26 15:32:23 797

原创 牛客刷题记录01

给定一个字符串数组strs,再给定两个字符串str1和str2,返回在strs中str1和str2的最小距离,如果str1或str2为null,或不在strs中,返回-1。不难想到,每次对最大的偶数除2即可,我们可以使用堆来获取每次更新后最大的偶数。现在你进行不超过 k k\ k 次操作后,让数组中所有数之和尽可能小。请输出这个最小的和。你能进行最多 k k\ k 次操作。这里的结果需要用long long保存。给一个数组,一共有 n n\ n 个数。

2025-07-25 22:53:45 452

原创 C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(三)

在测试的过程中,发现了一种错误,就是创建数据库表时发生了out of memory错误,开始还以为是系统内存不足,后来发现在构造mapper时忘记了打开数据库,所以得知如果没有打开数据库就创建表就会发生out of memory错误。值得注意的是:在使用unordered_map保存绑定信息的时候,插入和删除的方式与之前不同,具体在注释中给出了解释。当前队列数据的管理,本质上是队列描述信息的管理,描述当前服务器上有哪些队列。绑定信息,本质上就是一个交换机关联了哪些队列的描述。同样与上述类的实现类似。

2025-07-24 21:46:20 429

原创 C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(二)

select测试可能会失败,原因是在交换机中我们使用unordered_map存储其他参数,由于顺序随机,所有使用getArgs获取的字符串中键值对的顺序也是随机的,但是不影响功能。

2025-07-21 21:52:51 587

原创 C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(一)

在这里,uuid 生成,我们采用生成 8 个随机数字,加上 8 字节序号,共 16 字节数组生成 32 位 16 进制字符的组合形式来确保全局唯一的同时能够根据序号来分辨数据。std::mt19937_64对象:64位梅森旋转算法(Mersenne Twister)生成伪随机数,可以使用std::random_device对象生成的随机数作为种子。这里实现了追加写入与在特定位置写入的功能,但是在特定位置写入会覆盖原本的内容,暂时未实现真正的插入功能。件的基础操作,字符串的额外操作等在项目中用到的零碎功能。

2025-07-20 13:53:47 1271

原创 力扣刷题记录(c++)11

说明:前边的3*n的意思是除了目标元素,其他元素都是3个,后边的1个代表的就是目标元素该bit位上的数字。首先看到时空复杂度的要求就知道不能用哈希来解决,这里我们使用位运算的方法来解决。你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。,以从上往下、从左到右进行 Z 字形排列。请你找出并返回那个只出现了一次的元素。外,其余每个元素都恰出现。3*n个0与1个0;3*n个0与1个1;3*n个1与1个0;3*n个1与1个1。

2025-07-18 21:37:00 795

原创 C++ - 仿 RabbitMQ 实现消息队列--需求分析与模块设计

消费者在客户端的存在感比较低,因为在用户的使用角度中,只要创建一个信道后,就可以通过信道完成所有的操作,因此对于消费者的感官更多是在订阅的时候传入了一个消费者标识,且当前的简单实现也仅仅是一个信道只能创建订阅一个队列,也就是只能创建一个消费者,它们一一对应,因此更是弱化了消费者的存在。本质上,咱们仿照实现的服务器是通过 muduo 库来实现底层通信的,而这里的连接管理,更多的是对 muduo 库中的 Connection 进行二次封装管理,并额外提供项目所需操作。交换路由模块就是决定这件事情的。

2025-07-18 13:35:37 1018

原创 优先队列的实现

优先队列(Priority Queue)是一种特殊的队列数据结构,其中每个元素都有一个优先级。与普通队列不同,优先队列中的元素不是按照先进先出的原则出队,而是按照优先级的高低出队。本文将详细介绍优先队列的实现,包括其底层数据结构——堆的原理,以及完整的C++实现代码。堆是一种完全二叉树,分为最大堆和最小堆。最大堆中父节点值大于等于子节点,最小堆中父节点值小于等于子节点。优先队列基于堆实现,支持高效获取最高/低优先级元素。删除堆顶元素时,将末尾元素移至堆顶,通过向下调整(访问堆顶元素(即数组首元素)

2025-07-17 22:13:51 939

原创 C++ - 仿 RabbitMQ 实现消息队列--C++11 异步操作实现线程池

std::future 是 C++11 标准库中的一个模板类,它表示一个异步操作的结果。当我们在多线程编程中使用异步任务时,std::future 可以帮助我们在需要的时候获取任务的执行结果。std::future 的一个重要特性是能够阻塞当前线程,直到异步操作完成,从而确保我们在获取结果时不会遇到未完成的操作。

2025-07-17 15:19:52 1284

原创 C++ - 仿 RabbitMQ 实现消息队列--sqlite与gtest快速上手

SQLite 是一个进程内的轻量级数据库,它实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,我们不需要在系统中配置。像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接,SQLite 直接访问其存储文件。C/C++ API 是 SQLite3 数据库的一个客户端, 提供一种用 C/C++操作数据库的方法。

2025-07-16 19:22:34 1192 3

原创 C++ - 仿 RabbitMQ 实现消息队列--muduo快速上手

public:public:/// 当一个新连接建立成功的时候被调用/// 消息的业务处理回调函数---这是收到新连接消息的时候被调用的函数构造函数:loop:进行事件监控的对象。listenAddr:绑定的ip,port。nameArg:服务器的名称。option:是否启用端口复用,默认不启用。setThreadNum:设置线程数目。start:启动服务器。setConnectionCallback:设置收到新链接的时候要调用的回调函数。

2025-07-15 14:59:33 1073

原创 C++ - 仿 RabbitMQ 实现消息队列--protobuf快速上手

编写 .proto 文件,目的是为了定义结构对象(message)及属性内容使用 protoc 编译器编译 .proto 文件,生成一系列接口代码,存放在新生成头文件和源文件中依赖生成的接口,将编译生成的头文件包含进我们的代码中,实现对 .proto 文件中定义的字段进行设置和获取,和对 message 对象进行序列化和反序列化在 message 中我们可以定义其属性字段,字段定义格式为:字段类型 字段名 = 字段唯一编号;字段名称命名规范:全小写字母,多个字母之间用 _ 连接。

2025-07-14 14:50:47 1115

原创 力扣刷题记录(c++)10

这个范围内没有出现在数组中的那个数。实现一个算法,确定一个字符串。的所有字符是否全都不同。

2025-07-14 14:09:34 355

原创 力扣刷题记录(c++)09

题目上说的看起来有点复杂,其实就是对于ans[i][j],返回mat中从i-k到i+k,从j-k到j+k,也就是一个矩阵(如果不符合条件取边界)范围内的数的和。我们可以用一个二维前缀和数组先记录从起始位置到(i,j)这个位置的范围内的所有树的和。的最长连续子数组,并返回该子数组的长度。是所有满足下述条件的元素。,返回其中元素之和可被。, 找到含有相同数量的。

2025-07-13 20:32:02 556

原创 力扣刷题记录(c++)08

然后这里我只想到了枚举区间,用前缀和数组计算区间的和。之中任意元素的全部前缀元素和后缀的乘积都在。首先还是可以用前缀和数组记录一下和。子数组是数组中元素的连续非空序列。之外其余各元素的乘积。时间复杂度内完成此题。

2025-07-12 14:22:33 379

原创 C++ - 仿 RabbitMQ 实现消息队列--项目介绍与环境搭建

首先说一下什么叫做阻塞队列。阻塞队列实际上就是一种生产消费模型,生产者生产数据到队列中,消费者取出数据进行处理。它有很多好处:○ 解耦合 ○ 支持并发 ○ 支持忙闲不均 ○ 削峰填谷而在实际的后端开发中, 尤其是分布式系统里, 跨主机之间使用生产者消费者模型, 也是非常普遍的需求。因此, 我们通常会把阻塞队列封装成一个独立的服务器程序, 并且赋予其更丰富的功能。这样的服务程序我们就称为 消息队列 (Message Queue, MQ)。

2025-07-12 13:47:59 325

原创 红黑树的实现

上图中也分为两种情况,与旋转加变色唯一不同的是c变为了p的右节点,这时如果单纯旋转就会发现,g与c成了连续的红色,所以不可取,然后我们就可以对p进行左旋不变色,那么不就变为了旋转加变色的情况了嘛,再进行前述操作即可。当发生上面这种情况时,即c为红,p为红,u存在且为红,g为黑,出现了连续的红色,需要调整,但又不能影响每条路径的黑色节点的个数,所以将g变为红色,p与u变为黑色即可,即将黑色下放。如果想要增加高度,只能增加红节点了,但是不能有连续的红色,所有红色的个数最多与黑色相等,那么最长路径就是2*h。

2025-07-12 11:20:33 865

原创 力扣刷题记录(c++)07

因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组。是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。如果中心下标位于数组最左端,那么左侧数之和视为。如果数组不存在中心下标,返回。假定仅有一位同学缺席,请返回他的学号。如果数组有多个中心下标,应该返回。

2025-07-11 15:36:05 813

原创 AVL树的实现

概念AVL树是最先发明的⾃平衡⼆叉查找树,AVL是⼀颗空树,或者具备下列性质的⼆叉搜索树:它的左右⼦树都是AVL树,且左右⼦树的⾼度差的绝对值不超过1。AVL树是⼀颗⾼度平衡搜索⼆叉树, 通过控制⾼度差去控制平衡。AVL树实现这⾥我们引⼊⼀个平衡因⼦(balance factor)的概念,每个结点都有⼀个平衡因⼦,任何结点的平衡因⼦等于右⼦树的⾼度减去左⼦树的⾼度,也就是说任何结点的平衡因⼦等于0/1/-1,AVL树并不是必须要平衡因⼦,但是有了平衡因⼦可以更⽅便我们去进⾏观察和控制树是否平衡,

2025-07-10 21:31:37 999

原创 力扣刷题记录(c++)06

它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的。请你找出给定目标值在数组中的开始位置和结束位置。给你一个按照非递减顺序排列的整数数组。的数组,预先按照升序排列,经由。你必须设计并实现时间复杂度为。你必须设计一个时间复杂度为。如果数组中不存在目标值。

2025-07-10 14:22:07 764

原创 二叉搜索树

概念⼆叉搜索树⼜称⼆叉排序树,它或者是⼀棵空树,或者是具有以下性质的⼆叉树:若它的左⼦树不为空,则左⼦树上所有结点的值都⼩于等于根结点的值。若它的右⼦树不为空,则右⼦树上所有结点的值都⼤于等于根结点的值。它的左右⼦树也分别为⼆叉搜索树。⼆叉搜索树中可以⽀持插⼊相等的值,也可以不⽀持插⼊相等的值(这里我们讲解一下不支持的二叉搜索树)。性能分析示例二叉搜索树:可以发现时间复杂度为O(对于右边的二叉搜索树,假设我们需要查找1,按照上述类似的过程,可以发现时间复杂度O(n)。

2025-07-09 22:59:39 1256

原创 力扣刷题记录(c++)05

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。的字符串,返回所有它能表示的字母组合。中所有字符串以任意顺序排列连接起来的子串。

2025-07-09 15:10:33 482

原创 力扣刷题记录(c++)04

然后我们假设dp[i]是以s[i]为结尾的字符串的解码方法个数,可以发现如果s[i]可以被解码,则dp[i]就是dp[i-1],如果s[i-1]与s[i]可以一起被解码,那么dp[i]还要加上一个dp[i-2]。假设s长度为n,我们将dp数组长度设置为n+1,将dp[0]与dp[1]初始化为1,这样就不需要对特殊特殊情况特殊处理了,可结合代码理解。首先一个单字符可以被编码,则必须是大于0的,两个字符可以被编码必须是大于10,小于27的。代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且。

2025-07-08 22:29:58 699

原创 基于多设计模式的同步&异步日志系统--代码设计(六)

我们之前设计了一个local的日志器建造者,其中只是会返回对应的日志器,用户还需要自己将日志器添加到日志器管理者中,提高了操作的复杂度,所以我们设计一个全局的日志器建造者,自动将日志器添加到管理者中。以日志器的名称作为唯一关键字将创建的日志器保存起来,允许用户通过日志器名称获取对应日志器,如果日志器不存在,返回一个默认的日志器。日志器管理者要求全局唯一。我们还需要设计一组宏函数来代理日志器对日志信息的落地,这里提供两组,一组是需要日志器指向的宏函数,一组是直接可以用默认日志器落地的宏函数。

2025-07-08 10:14:34 375

原创 力扣刷题记录(c++)03

这道题的提示其实已经很明显了,假设一个坐标为[x, y],那么ans[x][y] = min(ans[x-1][y],ans[x-1][y-1],ans[x-1][y+1])。假设matrix大小为n*m的,我们将dp数组设计为(n+1)*(m+2)的,除了第一行初始化为0,其余全部初始化为INT_MAX,可以避免我们对边界数据的特殊化处理。可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。

2025-07-07 16:01:22 560

原创 基于多设计模式的同步&异步日志系统--代码设计(五)

这一篇我们将完成对异步日志器的设计。

2025-07-07 15:34:14 594

原创 基于多设计模式的同步&异步日志系统--代码设计(四)

日志器模块是对前述几个模块的整合,实现对日志信息的格式化与落地等功能。这里设计同步和异步两种日志器。需要提供的对外接口接口有:说明:这五种接口(对应物种日志等级)需要用户传入文件名,文件行号,日志主体信息(其他信息在日志器构造时就会确认),先将日志的主体信息(不定参信息)按照fmt转换为字符串,再用所有信息构造一个LogMsg,格式化后进行日志落地。

2025-07-06 13:44:05 686

原创 力扣刷题记录(c++)02

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。你想要尽可能多地收集水果。你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组。网格的左上角 (起始点在下图中标记为 “Start” )。,返回你可以收集的水果的。问总共有多少条不同的路径?

2025-07-06 07:35:11 901

原创 基于多设计模式的同步&异步日志系统--代码设计(三)

在这一模块中我们将完成对日志信息的落地的功能,主要完成三个落地方向的设计:我们还将支持用户自己设计落地反向进行扩展。

2025-07-04 14:31:33 363

原创 力扣刷题记录(c++) 01

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。N皇后是一个典型的深度搜索问题,关键在于我们如何选择正确的搜索结果。的棋盘上,并且使皇后彼此之间不能相互攻击。,请你找出其中不含有重复字符的。的棋子放置方案,该方案中。题目描述:给定一个字符串。每一种解法包含一个不同的。分别代表了皇后和空位。

2025-07-03 23:08:33 363

原创 基于多设计模式的同步&异步日志系统--代码设计(二)

⽇志输出格式化类设计(format.hpp)⽇志输出格式化类设计(format.hpp)在这一模块中我们将完成对日志信息的格式化输出,支持按照用户的需求自定义格式化,但是有几条说明:例如:[%d{%H:%M:%S}][%t][%p][%c][%f:%l]%T%m%n,其中规定%为格式化字符的前缀,%%代表一个普通的%字符,{}中的内容为格式化字符的子格式规则,凡是非格式化字符的字符我们叫做其他字符。

2025-07-03 13:46:54 364

原创 基于多设计模式的同步&异步日志系统--代码设计(一)

本篇开始就要进行项目的代码设计,即真正实现我们的日志系统。

2025-07-02 16:41:19 368

原创 基于多设计模式的同步&异步日志系统--框架设计

本项目实现的是一个多日志器的日志系统,主要实现的功能是让那个程序员可以更加轻松得将程序运行的日志信息落地到指定的位置,并且支持同步和异步两种方式的落地方式。

2025-07-02 16:18:53 640

原创 设计模式的详细介绍

从整体上来理解六大设计原则,可以简单地概括为一句话,用抽象构建框架,用实现扩展细节,具体到每一条设计原则,则对应一条注意事项:(1)单一职责原则:实现类要职责单一;(2)里氏替换原则:不要破坏继承体系;(3)依赖倒置原则:要面向接口编程;(4)接口隔离原则:设计接口时要精简单一;(5)迪米特法则:要降低耦合;(6)开闭原则(总纲):要对扩展开放,对修改关闭。

2025-07-01 19:45:15 1679

原创 基于多设计模式的同步&异步日志系统--项目介绍以及技术准备

(1)生产环境的产品为了保证其稳定性和安全性,不允许开发人员附加调试器排查问题, 可以使用日志系统打印一些日志来帮助开发人员解决问题。(2)上线客户端的产品出现的bug无法复现并解决,可以通过日志系统打印日志并上传到服务器端帮助开发人员分析问题。(3)对于一些高频操作在少量的调试次数下可能无法触发我们想要的行为,导致排查问题的效率十分低下,可以借助日志系统帮我们解决问题。(4)在分布式、多进程/多线程代码中,出现bug比较难以定位,可以借助日志系统打印log来定位bug。

2025-07-01 16:09:15 717

原创 扫雷游戏的实现

然后我们获取一个坐标并进行判断(保证该坐标没有被排查过且在棋盘中),如果正好是雷就返回0,用flag接受来结束游戏,并且打印出我们的mine棋盘来告诉玩家结果,如果不是雷,就进入num函数对此坐标周围雷数进行判断。我们需要一个展示给玩家的棋盘,但是既然要获取雷所在的位置,我们就需要另一个棋盘,因此我们需要创建两个棋盘并且初始化。并且结束游戏的方式可以有两种,一是踩雷,二是找到所有的雷,因此我们需要考虑一下如何完成游戏,这里我使用一个变量(n)来记录找到的雷的个数,一个变量(flag)来决定是否完成了游戏。

2023-12-17 16:29:20 86 1

原创 循环语句中的break与continue

之前我们介绍了c语言中的循环语句,那么现在我们来了解一下循环用于中最常用的控制语句—break与continue。

2023-12-02 22:17:30 73

原创 c语言循环语句之for语句

前边介绍的while语句与do—while语句,而在c语言中最常用的循环语句其实是for语句。接下来我们就来介绍一下。

2023-12-02 21:45:43 104

原创 c语言循环语句之while与do—while

在编程中我们有时会遇到打印1到10数字等类似的问题,如果一遍一遍的打印会十分的繁琐,因此我们就需要另一种结构——循环结构——来实现这类功能。

2023-11-30 16:12:33 105

空空如也

空空如也

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

TA关注的人

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