自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 封装 brpc::Channel

本文介绍了基于brpc框架的服务管理设计。主要采用Channel作为客户端与服务端的交互通道,通过service_channel封装服务名称与Channel的映射关系。系统设计包含:1)使用数组管理主机节点地址,哈希表建立地址与Channel的映射;2)采用互斥锁保护共享容器;3)实现RR轮转策略均衡分配Channel;4)提供add_host/del_host动态管理节点;5)ServiceManager通过回调函数处理服务上下线事件,并使用互斥锁保护服务集合和服务-通道映射表。该设计实现了服务节点的动态

2025-07-12 18:18:29 150

原创 brpc 的简单使用

本文介绍了使用brpc框架开发RPC服务的基本流程。服务端开发需继承EchoService基类并重写Echo方法处理请求,通过Server类启动服务;客户端通过Channel与服务器交互,使用Stub类发起请求。文章详细说明了服务端处理请求时的参数使用、done回调机制,以及服务启动的四步流程,同时介绍了客户端创建Channel、发送请求的基本步骤,为brpc框架的入门开发提供了实用指导。

2025-07-12 09:57:40 374

原创 brpc 介绍与安装

本文介绍了C++编写的工业级RPC框架brpc,它广泛应用于高性能系统。brpc通过接口调用实现客户端与服务端通信,简化网络编程。安装步骤包括:先安装git、g++等依赖库,再通过git克隆brpc源码,执行cmake构建和make安装。若出错可能因缺失依赖库。全文简要说明了brpc的作用原理和安装方法。

2025-07-12 08:50:15 123

原创 etcd-cpp-apiv3 二次封装

本文介绍了基于etcd的客户端接口封装,主要包括以下内容: 核心接口类: Value类:存储键值对数据 Event类:记录键值对变化事件 Response类:服务器响应 KeepAlive类:租约保活机制 Client类:客户端操作接口 Watcher类:键值对监控 二次封装: Register类:封装Client和KeepAlive,实现服务注册和自动续约 Discover类:封装Client和Watcher,实现服务发现和变更通知 功能特点: 通过租约机制实现服务自动过期 支持服务注册、发现和监控 提供

2025-07-07 15:36:15 302

原创 Ubuntu 安装 etcd 与 etcd-cpp-apiv3

摘要:本文介绍了etcd的安装配置和使用方法。首先通过apt安装etcd-server和etcd-client,然后在/etc/default/etcd中配置节点名称、数据目录、监听URL等参数。启动etcd服务后,使用etcdctl存储键值对,若报错需设置ETCDCTL_API环境变量。最后详细说明了etcd-cpp-apiv3的安装步骤,包括依赖库安装、源码编译和安装。全文提供了从部署到客户端开发的完整流程说明。

2025-07-05 19:17:59 200

原创 spdlog 项目介绍与二次封装

摘要:本文介绍了对C++开源日志库spdlog的二次封装方案。spdlog提供了5个日志等级(trace至critical)和两种日志输出方式(同步/异步)。通过工厂模式创建日志对象,封装后提供了init_logger()初始化接口,可切换调试模式(同步输出trace级以上日志)和发布模式(异步输出指定等级日志)。封装还定义了LOG_DEBUG等宏,自动附加文件名和行号信息,并设置了默认日志格式(时间、日志名、等级、内容)。使用时需链接spdlog和fmt库。该封装简化了spdlog的使用,同时保留了其核心

2025-07-05 12:38:57 812

原创 gtest 库的安装和使用

GoogleTest是谷歌开源的C++单元测试框架,用于验证程序的正确性。安装可通过sudo apt-get install libgtest-dev完成。使用GoogleTest时,通过TEST宏定义测试用例,第一个参数为测试套件名称,第二个参数为测试样例名称。测试框架通过testing::InitGoogleTest初始化,并通过RUN_ALL_TESTS执行所有测试。例如,测试一个计算器类的加法、减法、乘法和除法功能,可以分别编写四个TEST宏,使用ASSERT_EQ断言验证结果。最后,在main函数

2025-05-19 19:24:15 409 1

原创 gflags 安装及使用

gflags是Google开发的一个C++库,用于处理命令行参数。通过包含头文件#include <gflags/gflags.h>,开发者可以使用宏定义命令行参数,如DEFINE_bool、DEFINE_int32等,分别用于定义布尔、整数等类型的参数。定义后,使用google::ParseCommandLineFlags函数解析命令行参数。在代码中使用这些参数时,需加上FLAGS_前缀。gflags还支持通过命令行或配置文件设置参数,如./test --reuse_addr=false或./

2025-05-16 19:20:09 729 1

原创 C++的 I/O 流

我们重点要掌握的是:输入输出流定义的全局对象 cout cin 等, 还有文件输入输出流,熟悉文件输入输出流相关接口。

2025-02-05 16:55:34 1037 1

原创 C++的类型转换

C++ 规范化类型之间转换

2025-02-04 18:05:59 401

原创 C++11(下)线程库

线程, 条件变量, 互斥量, 对象生命周期管理加锁解锁

2025-02-01 23:17:15 837 1

原创 C++11(中)

类新增成员函数, default, delete, 可变模板参数, STL容器的 emplace_back 系列, lambda表达式, function 包装器, std::bind

2025-01-31 19:31:22 876

原创 C++11(上)

列表初始化 {}。 initializer_list 。auto 。nullptr 。左值与右值 。右值为什么可以提高效率 。模板中的万能引用 。属性退化。 完美转发 std::forward<T>()。

2025-01-23 18:11:10 1289

原创 详解常见的寄存器和中断的概念以及CPU的状态

数据寄存器(DR)用来暂时存放CPU执行指令是用的操作数,运算结果, 中间结果地址寄存器(AR)用来存放中某个数据或指令的地址条件码寄存器(CCR)其标志位由CPU硬件设置,例如,一次算数运算可能导致CCR被设置为正, 负, 零, 溢出程序计数器(PC)存放下一周期被执行指令的指令寄存器(IR)存放待执行的指令程序状态字寄存器(PSW)PSW的各个位代表系统中当前各种不同的状态与信息,例如CPU的优先级,用户态, 核心态等中断现场保护寄存器。

2024-12-19 18:54:20 658 1

原创 认识硬件以及理解冯诺依曼体系

片文章是该专栏的第二篇,这篇文章会介绍基本的硬件元素以及冯诺依曼架构

2024-12-18 11:02:25 654 1

原创 操作系统的基本认识

这个词可能或多或少听说过,比如。这些其实都是工程师们经过实践后的产物。而这六个字就是操作系统的抽象化,更准确的说,是很理论化的东西。举一个不是很恰当的例子,和,马哲就是一种比较抽象的理论,而中国特色社会主义是马哲实践后的产物。所以这里要给大家避个坑——如果要学操作系统相关的知识,千万不要盯着操作系统原理去学,一定要从一款具体的操作系统切入(比如Linux)。操作系统原理好比计算机里的哲学,真的很抽象。计算机的硬件(键盘,CPU,显示器,磁盘,内存…)只是冷冰冰的硬件,而操作系统就是硬件的。

2024-12-14 20:07:00 795 2

原创 宽度优先搜索(BFS)思想总结以及做题技巧

上文阐述BFS的两个应用场景,这里我们把BFS算法的模板总结一下,下面是伪代码的形式总结模板//模板一//创建vis数组来标记数组中的元素是否被遍历过,0否1是,也可以用bool表示,m和n表示数组的长和宽//创建队列//进行宽搜//获取队头元素q.pop();//删除队列中的队头元素(...) //如果是树的话,这里获取孩子节点,如果是二维数组的话,就遍历一下周围if(没有越界 && 没有被遍历过 && 符合某种性质) {q.push(...) //入队列//模板二。

2024-12-02 08:16:37 724 2

原创 归并排序思想以及做题技巧总结

这一条件,可以用归并排序的过程来求解,但我们还要知道某个数的原始下标才可以,我们可以用一个index数组(数组初始化为 0, 1, 2, 3 ......)和nums数组绑定——nums数组中的数据怎么挪动,index数组中的数据就怎么挪动,这样我们可以通过index数组找到某个数的原始下标。我们把数组分成左右两个区间,先去左区间找出所有逆序对,再去右区间找出所有逆序对,再一左一右区间找剩余的逆序对。对于归并排序而言,我们只需探讨一左一右区间即可,因为下一层的一左一右区间是上一层的左区间或右区间。

2024-11-27 10:48:50 792 2

原创 快速选择算法解决 top K 问题

top K 问题一般是用堆解决的,时间复杂度为,而快速选择算法是基于快排的思想,时间复杂度逼近。下面,我们用快速选择算法解决一道 top K 的力扣题。只要在数组划分三段的思想上分类讨论,即可实现快速选择算法。

2024-11-24 16:11:29 489 1

原创 用数组划分三段思想实现快排

数组的划分三段 以及快排思想优化

2024-11-20 18:38:10 992

原创 高精度加法高精度乘法

大数或高精度运算

2024-11-16 15:24:59 334 2

原创 中心扩展算法

当索引到一个字符是就以该字符为中心向外扩展。

2024-11-16 14:04:46 289

原创 字符串相关题解

这道题更像一道语法题,考察对容器的掌握情况。如果按题目要求去模拟,不仅要分析每个字符串,还要判断其他字符串是否是自己的异位词,时间复杂度会很高,代码实现也会很麻烦。如果两个字符串是异位词,那么这两个字符串排好顺序后是一样的,那么我们可以用一张哈希表映射,k值为排序后的字符串,v值为异位词数组。那么遍历完源字符串数组后,哈希表中所有的v值就是结果N个字符,排序会消耗O(N⋅log(N)) 时间。

2024-11-16 13:53:16 459

原创 一文搞懂链表相关算法

为了防止cur找不到下一个节点,要提前用next保存起来,cur遍历到的节点都会放到newNode的后面,当cur遍历完整个链表后,newNode后面就是逆序后的链表。用快慢双指针算法。慢指针 slow 每次移动一个节点,快指针 fast 每次移动两个节点,slow 和 fast 都初始化(指向)为链表的头节点, 算法如下

2024-11-13 17:08:46 1102 2

原创 【力扣刷题】【滑动窗口算法】水果成篮

2.判断哈希表中的果树种类,如果种类个数为2,更新结果(区间的长度区较大值),如果种类的个数大于2,一直出窗口更新哈希表。用哈希表记录一个区间内果树的种类和对应的数量。当果树的数量在哈希表中为0的时候,就把该果树从哈希表中移除。1.区间相当于窗口,先入窗口,更新哈希表。那区间要怎么维护呢?

2024-11-06 10:52:05 219 2

原创 一文彻底搞懂二分算法的细节

非朴素二分是在朴素二分的思想上进行泛化,判断一道题是否需要二分算法不在是“数组是否查找区间左端点循环条件:left < right下标更新:if (...) left = mid + 1;中点值mid:left + (right - left) / 2查找区间左端点循环条件:left < right下标更新:if (...) left = mid;中点值mid:left + (right - left + 1) / 2模板的思想总结当下标更新为if (...) left = mid + 1;

2024-11-06 10:50:03 1102 2

原创 【力扣刷题】【滑动窗口算法】最大连续1的个数 III

这题读起来有些抽象,它让找数组中连续 1 的最大个数,但连续的 1 中又可以有最多 k 个 0。乍一看没啥思路,其实这这题目可以换一种问法——在子数组中包含 k 个 0 的子数组的最大长度是多少?检查 0 的个数是否超标: 如果超标,依次让左侧元素滑出窗⼝,顺便更新哈希表的值,直到 0 的个数恢复正常;那么我们只需在数组中维护一段区间,当区间的0的个数等于 k 时,我们就更新结果。程序到这⾥,说明窗⼝内元素是符合要求的,更新结果;right++ ,处理下⼀个元素;让当前元素进⼊窗⼝,顺便统计到哈希表中;

2024-11-05 20:46:52 263 1

原创 【力扣刷题】【滑动窗口算法】无重复字符的最长字串

空间复杂度上我们可以用一个哈希表,把空间复杂度降为O(1)。哈希表中存储某个区间字符和字符出现的次数的映射,但我们不必真的定义一个std::unordered_map。暴力解法是用两层循环列举出所有可能,并用O(N)的空间复杂度存储临时的字符来判断某个区间是否重复了。如果这个字符出现的频次超过 1 ,说明窗⼝内有重复元素,那么就从左侧开始划出窗⼝,如果没有超过 1 ,说明当前窗⼝没有重复元素,可以直接更新结果。直到 ch 这个元素的频次变为 1 ,然后再更新结果。

2024-11-02 15:33:07 276 1

原创 【力扣刷题】【滑动窗口算法】长度最小的子数组

上图中,灰色的区间已经是符合条件的区间了,此时黑色指针向右移动一格,如果是暴力算法,红色指针应该重置到黑色指针的位置,然后向右遍历。我们来讨论一下,红色指针有必要重置吗?题目里说数组里的都是正整数,当区间里已经符合条件了,我们还需要把最右边的指针重置到左边吗。2.灰色区间不符合条件,红色指针被重置后遍历,由于整个区间都是正整数,灰色区间的大小只会增加。1.灰色区间依旧符合条件,红色指针被重置然后遍历,依旧是当前的灰色区间。用两个指针,两层循环,列举出所有的结果,把每次符合的最优结果更新到临时变量里。

2024-11-02 14:51:02 415 1

原创 muduo库TcpConnection类源码解析——链接管理

enum StateE { kDisconnected, //断开连接状态kConnecting, //尝试建立连接的状态kConnected, //成功建立连接的状态kDisconnecting //正在断开连接的状态//把一个链接挂接到EventLoop上进行事件监控//链接的名字//链接的状态 // FIXME: use atomic variable//为true表示链接正在进行读事件监控//IP地址的简单封装//新建链接的回调//消息到来的回调//低水位线回调。

2024-10-27 13:45:06 1233 9

原创 muduo库Buffer类源码解析

我之前写过一篇文章,其思想就是来源于muduo库Buffer类的源码。但代码的细节个人不是很满意,这篇文章带你探秘muduo源码是怎么实现用户级缓冲区。为什么要有用户级缓冲区?在网络通信中TCP的缓冲区是内核缓冲区,要拿到数据,在用户和内核之间始终有一次拷贝,这样似乎就有理由需要一层用户缓冲区来保存数据。但这样的理由似乎是不充分的,因为缓冲区不是处理数据的地方,如果要进行数据处理还需要一次拷贝,似乎,有些浪费性能了?

2024-10-27 09:44:31 963 2

原创 muduo库EventLoop类源码解析

EventLoop也称为事件循环,从调用epoll_wait系统调用捞取到就绪事件到再次阻塞到epoll_wait上(阻塞到内核中的就绪队列上了)称为一次事件循环。muduo库的EventLoop在捞取完就绪事件后会立即执行就绪事件的回调。EventLoop还有一个线程安全的任务队列。在执行完就绪事件的回调后不会立即阻塞到epoll_wait上,他会在执行完任务队列中的任务后在阻塞到就绪队列上。为什么要搞一个线程安全的任务队列呢?muduo库的设计思想是。

2024-10-26 15:42:09 1288 9

原创 高并发服务的核心机制——IO多路转接--->epoll

用于创建epoll模型,返回值是一个文件描述符,也可以理解为epoll模型的一个句柄(Linux里一切接文件)。epoll将会把发生的事件赋值到events数组中 (events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存).当就有文件描述符上的事件就绪了,epoll模型中还有一个双向链表结构,这个数据结构用来存放就绪事件,epoll_wait就是在这上面捞取就绪事件。: 表示对应的文件描述符有紧急的数据可读 (这里应该表示有带外数据到来);

2024-10-26 09:41:56 758

原创 【小洛的VLOG】Web 服务器高并发压力测试(Reactor模型测试)

Webbench,这个工具大家可以搜一下相关的文章,很轻量化,上手成本很低。下载下来只需make编译一下即可,如果你编译不过的话就是有个头文件会报错,根据报错提示,把Webbench源码里报错的头文件去掉就可以啦~Webbench的原理也很简单,就是创建多进程然后同时向服务端发起请求。我用了两台云服务器来模仿服务端和客户端,配置都是2核2G的(恼火),没钱买配置高的服务器(哭)。软件方面是我模仿muduo库写的一个Reactor。

2024-10-20 19:55:46 672 3

原创 【C++】设计用户级缓冲区

底层的容器用std::vector类型。两个下标用uint64_t类型【C++】详解STL容器之一的 vector_c++ vector扩容缩容-CSDN博客//缓冲区//读下标//写下标拷贝数据用std::copy,第一个参数:从哪里拷贝的起始地址,第二个参数:从哪里拷贝的末尾地址,第三参数:从拷贝到哪里的起始地址。查找字符用C语言的strchr,第一个参数:一段空间的起始地址,第二个参数:要查找字符的ASCII,找到了返回字符的地址,失败返回nullptrReadSize。

2024-09-28 14:35:41 2122 89

原创 【C++】C++17中可以存储任意类型数据的对象——any类的使用与设计思想

一提到存储任意类型,第一时间想到的可能就是STL容器,这种容器都是模板。但是,模板类在实例化对象是都要指定类型,例如。那么模板实例化的对象存储的数据类型就是固定的。C++17提供了std::any类,头文件是。any类实例化的对象可以存储任意类型的数据,本文会为大家介绍如何使用any类以及any类是如何实现的。

2024-09-26 11:05:33 1412 65

原创 【C++】检测TCP链接超时——时间轮组件设计

参考钟表的策略,我们可用一个数组代表一个钟表,数组的下标代表时间,指向数组的指针按特定的时间向后移动,指针执行哪个位置,就代表哪个位置的时间到了。智能指针shared_ptr用于任务类的超时时间刷新,在上文提到的高并发服务的场景中,如果触发了链接中的事件,就需要重新刷新时间,但时间轮的指针是一直向后移动的,任务类的下标迟早会被指到,然后该类就会被析构。在我们上述的阐述中,任务是有超时时间的,当时间轮的指针指向这个任务时,说明时间到了,我们该执行这个任务呢——答案是把任务的执行放到析构函数里。

2024-09-24 18:29:58 3660 56

原创 【网络】详解HTTP协议的CGI机制和CGI进程

CGI机制是HTTP协议提供的偏底层的一套机制,也是非常重要的机制——它让大量的业务进程和HTPP协议解耦。而CGI进程是业务层的,用来处理各种数据,比如把用户提交上来的数据插入数据库,再比如做某种运算。CGI机制和CGI进程在概念上是完全不一样的,他们的关系就行老婆和老婆饼一样。客户端通过HTTP协议向服务器提交数据的方式主要有两种:1.GET方法请求,GET方法没有请求正文,一般用来拉取服务器的数据,但也可以通过URL的参数提交数据(URL中?分隔符后面的就是要提交的数据)

2024-09-18 11:34:52 849 21

原创 【Linux系统编程】用互斥量和信号量加锁STL容器,避免并发问题

STL容器并没有保证线程安全,而大多数应用场景下,为了追求效率,多线程是必不可少的。线程先去申请信号量资源,申请到了信号量资源的线程再去竞争互斥量,谁能锁住互斥量,谁就去容器里操作。有了信号量和互斥量的存在,在任意时刻,有且只能有0或1个生产者,0或1个消费者线程在容器里操作。给容器设计两个接口,push()用来向容器填充数据,pop用来向容器取数据。调用push接口的称为生产者,调用pop接口的称为消费者。本文给出的方案是用信号量和互斥量封装vector容器——用两个信号量和两个互斥量封装出环形队列。

2024-09-17 10:14:37 639 7

原创 【Linux系统编程】子进程被程序替换后,如何保持父子进程的通信

子进程exec系列函数后会被目标程序替换,其进程的代码和数据会被替换,但内核数据结构不会被替换(包括文件描述符,环境变量)。建立好信道后,如果直接进行程序替换,被替换后,代码和数据会被目标程序的代码和数据替换掉,那么目标程序也就不知道信道的文件描述符,也就无法和父进程通信。然后再执行exec系列函数,子进程想从信道里读数据,改向标准输入里读,子进程想向信道里写数据,改向标准输出里写。但是每个进程有3个文件描述符是一定确定的0 , 1, 2——分别是标准输入,标准输出,标准错误。方案一:文件描述符的重定向。

2024-09-16 16:06:40 1204 17

linuxlinuxlinuxlinuxlinux

linux

2024-07-24

map和set的模拟实现

封装红黑树,模拟SLT源码实现,封装出map和set

2024-06-06

linux 的 less指令查看大文本

linux 的 less指令查看大文本。

2024-05-12

空空如也

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

TA关注的人

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