- 博客(54)
- 收藏
- 关注
原创 Json简单的实现
内存里的 I/O 流”,既能格式化输出,也能解析输入,是 C++ 里小工具级的瑞士军刀。场景用哪种简单枚举静态工厂需要扩展工厂方法一族产品抽象工厂编译期决定模板工厂运行时字符串决定注册式工厂一句话:工厂类把new藏起来,让新增类型不改动旧代码(开闭原则)。
2025-08-02 11:00:00
839
原创 Muduo库
Muduo是一个基于C++11的高性能事件驱动网络库,专为Linux下的高并发TCP服务器设计。它采用epoll+多线程Reactor模型,封装网络细节,开发者只需关注业务逻辑。核心功能包括自动管理连接、线程池和事件循环,适合构建聊天室、RPC框架等高并发服务。典型应用场景包括:快速开发Echo服务器(100行以内代码)、学习网络编程模型等。Muduo原生依赖Boost,已有社区版移除此依赖。对于需要稳定高性能TCP服务器的Linux开发者,Muduo是省心的选择。
2025-07-28 13:30:00
272
原创 TcpEchoServer
这是一个工具类,用于禁止类的拷贝功能。通过和,任何继承自这个类的类都将无法被拷贝。这在需要确保对象唯一性的场景中很有用。
2025-07-28 10:15:00
380
原创 网络地址和主机地址之间进行转换的类
InetAddr类封装了网络地址操作,提供主机和网络格式间的便捷转换。该类支持多种构造方式(sockaddr_in、字符串IP+端口、仅端口),自动处理字节序转换和IP格式转换。核心功能包括获取IP/端口信息、返回网络地址结构、比较运算和地址字符串化。特别实现了线程安全的IP转换方法,并支持服务器监听地址(INADDR_ANY)的便捷构造。该封装简化了底层socket地址操作,使网络编程更直观高效,适合需要处理网络地址的C++网络应用开发。
2025-07-20 22:54:50
141
原创 创建套接字并bind的详细过程
摘要:bind()是套接字编程中的核心函数,用于将套接字与特定IP地址和端口号绑定。服务器端必须调用bind()以固定监听端口,客户端可选择绑定本地端口。函数原型为bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen),成功返回0,失败返回-1。使用时需注意:1)创建套接字;2)设置sockaddr_in结构体;3)调用bind()。常见问题包括端口占用(EADDRINUSE)、权限不足(EACCES)等。TCP/UDP服务器均需bi
2025-07-19 23:00:17
488
原创 TCP 和 UDP 在创建套接字(Socket)时的区别
TCP与UDP套接字的主要区别在于连接方式和可靠性。TCP(SOCK_STREAM)是面向连接的协议,需通过connect()/accept()建立连接,保证可靠传输(不丢包、按序),适用于HTTP、FTP等场景,但效率较低。UDP(SOCK_DGRAM)是无连接的,直接通过sendto()/recvfrom()发送数据,不保证可靠性但传输效率高,适用于DNS、视频流等实时应用。选择依据在于需求:需可靠传输用TCP,重实时性用UDP。
2025-07-19 10:15:00
393
原创 Cookie + Session
本文介绍了Web开发中Cookie和Session两种会话管理技术。Cookie存储在客户端浏览器,用于存储少量数据(如用户偏好),但存在4KB大小限制和安全性风险;Session存储在服务器端,安全性更高,适合存储用户状态信息(如登录状态)。二者通常结合使用:服务器生成Session ID并通过Cookie传递给客户端,后续请求通过该ID识别用户。文章还强调了安全措施:Cookie应使用HttpOnly和Secure标志,Session需使用强随机ID并设置超时。最后指出合理配置这两种技术可以实现高效安全
2025-07-04 23:49:05
704
原创 UDP————套接字socket
摘要:本文介绍了UDP服务器的实现过程,包括套接字创建、绑定、消息接收与发送等核心功能。通过socket()创建UDP套接字,使用bind()绑定IP和端口,利用recvfrom()/sendto()实现无连接通信。服务器初始化时设置IPv4地址族和端口号,接收客户端消息后通过回调函数处理并返回响应。代码展示了网络字节序转换(htons/ntohs)和地址结构体(sockaddr_in)的使用,以及错误处理和日志记录机制。同时提及了客户端实现要点和智能指针(std::unique_ptr)在服务器管理中的应
2025-07-03 11:02:41
702
原创 sockaddr_in
本文介绍了用于IPv4网络编程的sockaddr_in结构体,它包含地址族(AF_INET)、端口号(网络字节序)、IPv4地址和填充字段。通过示例代码展示了如何创建TCP套接字并初始化sockaddr_in结构体,包括设置端口号(8080)和使用INADDR_ANY绑定任意本地地址。最后演示了bind()绑定套接字和listen()监听连接的基本流程,为后续网络通信操作奠定基础。
2025-05-26 19:29:18
248
原创 回调函数的使用
回调函数是一种编程技术,用于在特定事件或操作完成后执行指定代码。它通过函数指针或参数传递实现,常用于异步处理和事件监听。示例展示了如何定义回调类型、实现回调函数并在操作完成后调用它,强调类型匹配和空指针检查的重要性。回调函数提升了代码的模块化和灵活性,适用于扩展功能而无需修改函数签名。
2025-05-26 19:07:33
248
原创 高并发内存池------内存释放
本文主要介绍了内存管理中对象释放和Span合并的相关操作。首先,ReleaseListToSpans函数用于将对象释放到Span中,并在Span使用计数为0时将其释放回PageCache。该函数通过锁机制确保线程安全,并涉及锁的嵌套使用,需注意避免死锁。其次,ListTooLong函数在链表过长时将内存回收到中心缓存。最后,ReleaseSpanToPageCache函数将空闲Span释放到PageCache,并尝试合并相邻Span以减少内存碎片。代码分析中强调了锁的优化、错误处理和代码可读性的改进建议,以
2025-05-17 17:04:09
1118
原创 文件操作与总结
在 C 语言中,文件操作是通过标准库函数(如fopenfclosefprintf等)来完成的。fopen函数用于打开文件,它的第二个参数是一个字符串,指定了文件的打开模式。常见的模式包括"w""a""r"等,每种模式有不同的用途和行为。
2025-05-08 13:05:29
565
原创 高并发内存池------PageCache
1. 当central cache向page cache申请内存时,page cache先检查对应位置有没有span,如果没有则 向更⼤⻚寻找⼀个span,如果找到则分裂成两个。⽐如:申请的是4⻚page,4⻚page后⾯没有挂 span,则向后⾯寻找更⼤的span,假设在10⻚page位置找到⼀个span,则将10⻚page span分裂 为⼀个4⻚page span和⼀个6⻚page span。
2025-05-08 13:00:37
1153
原创 高并发内存池------CentralCache
central cache也是⼀个哈希桶结构,他的哈希桶的映射关系跟threadcache是⼀样的。不同的是他的每个哈希桶位置,挂的是SpanList链表结构,不过每个映射桶下⾯的span中的⼤内存块被按映射关系切成 了⼀个个⼩内存块对象挂在span的⾃由链表中。
2025-05-06 09:00:00
818
原创 多态与虚函数
多态性允许你编写通用的代码,该代码可以操作不同类型的对象,而这些对象可以有不同的内部结构和行为。当你声明一个函数为虚函数时,你是在告诉编译器,这个函数将在派生类(derived class)中可能会被重写(override)。纯虚函数是一种特殊的虚函数,它在基类中没有实现,要求所有派生类必须提供自己的实现。纯虚函数用于定义接口,强制派生类实现特定的函数。虚函数是 C++ 中实现多态的关键,它提供了一种机制,允许你编写灵活、可扩展的代码。是一个纯虚函数,它在。
2025-04-29 13:38:56
268
原创 日志的实现
日志记录可以帮助开发者了解线程池的运行状态,包括线程的创建、执行和销毁等。当线程池中出现错误或异常时,日志可以提供详细的错误信息,帮助开发者快速定位和解决问题。通过记录线程池的运行数据,如线程执行时间、资源消耗等,可以监控线程池的性能。日志可以帮助识别性能瓶颈,如线程创建和销毁的频率、任务执行时间等。日志可以记录线程池中线程对资源的请求和释放情况,如内存申请和释放。这有助于确保资源被正确管理,避免资源泄漏。在需要审计或需要符合特定合规性要求的场景中,日志可以记录所有关键操作,以满足审计和合规性要求。
2025-04-21 12:12:39
407
原创 高并发内存池-----项目简介、设计⼀个定长的内存池
所谓“池化技术”,就是程序先向系统申请过量的资源,然后⾃⼰管理,以备不时之需。之所以要申请过量的资源,是因为每次申请该资源都有较⼤的开销,不如提前申请好了,这样使⽤时就会变得⾮常快捷,⼤⼤提⾼程序运⾏效率。在计算机中,有很多使⽤“池”这种技术的地⽅,除了内存池,还有连接池、线程池、对象池等。以服务器上的线程池为例,它的主要思想是:先启动若⼲数量的线程,让它们处于睡眠状态,当接收到客⼾端的请求时,唤醒池中某个睡眠的线程,让它来处理客⼾端的请求,当处理完这个请求,线程⼜进⼊睡眠状态。
2025-04-21 08:42:43
622
原创 信号量的封装
构造函数初始化队列的最大容量_cap,两个信号量_blank_sem和_data_sem管理空位和数据的可用性,以及_cmutex和_pmutex两个互斥锁管理生产者和消费者对队列的访问。
2025-04-17 13:02:25
745
原创 锁------mutex
互斥锁(mutex)是一种用于多线程编程中,以防止多个线程同时访问共享资源的同步机制。其主要作用是保证在同一时间内,只有一个线程能够访问到共享资源或执行特定的代码段。
2025-04-06 10:30:00
1251
原创 线程的创建
由于不可以调用系统,所以要使用第三方库(第三方库要使用-l) -lpthrerad。3. 一个问题:给线程传递的参数和返回值,可以是任意类型(包括对象)。cpu调度的时候看的是lwp,因为Linux中只有轻量级进程。1. main函数结束,代表主线程结束,一般也代表进程结束。2. 新线程对应的入口函数,运行结束,代表当前线程运行结束。第二个参数:设置线程属性,nullptr表示默认。第一个参数:指向线程标识符的指针。第四个参数:传递给线程函数的参数。:分离线程,系统自动回收资源。第三个参数:线程函数地址。
2025-04-02 18:12:17
396
原创 系统调用与中断
中断(Interrupt)和系统调用(Syscall)是操作系统中两个关键机制,分别用于处理硬件事件和用户程序与内核的交互。它们虽然都涉及从用户模式到内核模式的切换,但设计目的和触发方式不同。处理来自硬件或软件的异步事件,强制CPU暂停当前任务,转而去执行特定的处理程序(如键盘输入、定时器到期、磁盘I/O完成等)。为用户程序提供访问内核功能的接口(如文件操作、进程创建、网络通信),是。从用户模式切换到内核模式的唯一安全途径。
2025-04-01 23:57:30
945
原创 搜索二维矩阵
就是我们在虚拟一维数组中二分查找时当前中间位置的值。我们假设将整个二维矩阵按行展开成一个一维数组。可以正确反映矩阵的有序性(如果矩阵是完全有序的)矩阵有 3 行 4 列(m=3, n=4)这种转换方法的前提是矩阵是按行存储的。每个一维索引唯一对应一个二维位置。一维数组索引范围:0 到 11。给你一个满足下述两条属性的。比目标大就左移(排除当前列)比目标小就下移(排除当前行)是虚拟一维数组的中间索引。用于计算行索引(整数除法)用于计算列索引(取模运算)保持了矩阵元素的行优先顺序。不会错过任何可能的位置。
2025-04-01 23:55:34
895
原创 系统调用 与 中断
中断(Interrupt)和系统调用(Syscall)是操作系统中两个关键机制,分别用于处理硬件事件和用户程序与内核的交互。处理来自硬件或软件的异步事件,强制CPU暂停当前任务,转而去执行特定的处理程序(如键盘输入、定时器到期、磁盘I/O完成等)。:由外部设备(如网卡、键盘)通过中断控制器(如APIC)发送信号给CPU。键盘按下 → 触发中断 → CPU执行键盘驱动的中断服务程序(ISR)。为用户程序提供访问内核功能的接口(如文件操作、进程创建、网络通信),是。从用户模式切换到内核模式的唯一安全途径。
2025-03-27 21:29:28
809
原创 BFS解决最短路径问题(使用BFS解决最短路径问题的黄金法则)
BFS适用最短路径问题的条件、BFS vs 其他最短路径算法对比、BFS的核心优势
2025-03-27 21:20:31
940
原创 如何进行文件操作
在 C 语言中,文件操作是通过标准库函数(如fopenfclosefprintf等)来完成的。fopen函数用于打开文件,它的第二个参数是一个字符串,指定了文件的打开模式。常见的模式包括"w""a""r"等,每种模式有不同的用途和行为。
2025-03-24 23:30:37
931
原创 BFS解决FloodFill算法
• 并且将这个陆地相连的所有陆地,也就是这块「岛屿」,全部「变成海洋」。这样的话,我们下次 遍历到这块岛屿的时候,它「已经是海洋」了,不会影响最终结果。可以先利⽤ bfs 将与边缘相连的 '0' 区域做上标记,然后重新遍历矩阵,将没有标记过的 '0' 修改成 'X' 即可。遍历当前点的四个方向,如果相邻点在图像范围内且颜色与起始点相同,将其加入队列。在上图中,底部的区域没有被捕获,因为它在 board 的边缘并且不能被围绕。遍历网格的每个单元格,对于值为 '1' 的单元格,如果未访问过,则调用。
2025-03-24 23:25:18
779
原创 TopK问题
1.创建一个大小为k的堆(大根堆 or 小根堆)求最小 大根堆 ,求最大 小根堆2.循环:(1)依次进堆(2)判断堆的大小是否超过K3.思考:用大根堆还是小根堆??为什么选择大根堆或者小根堆??方法时间复杂度适用场景排序法数据集较小堆数据集较大,K 远小于 N快速选择O(N)O(N)(平均)数据集较大,对时间要求高。
2025-03-22 16:05:10
663
原创 二叉树最大宽度
被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。最大宽度出现在树的第 4 层,宽度为 7 (6,null,null,null,null,null,7)。遍历当前层的所有节点,对于每个节点,如果其左子节点或右子节点存在,将其加入。最大宽度出现在树的第 3 层,宽度为 4 (5,3,null,9)。最大宽度出现在树的第 2 层,宽度为 2 (3,2)。整体思路:用数组存储二叉树的方式,给节点编号。:计算当前层的最大宽度,并更新。:用于存储下一层的节点和层级。给你一棵二叉树的根节点。
2025-03-20 23:26:01
445
原创 BFS--------N叉树的层序遍历
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。1.这道题就是对N叉树进行层序遍历(BFS),只需要逐层对树进行遍历即可。3.使用队列的FIFO性质,创建一个队列queue<Node*> q。被用作实现 BFS 的数据结构,按照从上到下的顺序访问树的所有节点。:如果子节点不为空,将其加入队列,以便后续访问。获取当前队列中的节点数,即当前层的节点数。给定一个 N 叉树,返回其节点值的。:遍历该节点的所有子节点。:遍历当前层的所有节点。:获取队列头部的节点。:从队列中移除该节点。
2025-03-20 19:39:33
465
原创 map和set的区别
适用于存储唯一元素并快速检查元素是否存在。适用于存储键值对并快速通过键查找对应的值。根据具体需求选择合适的容器可以提高代码的效率和可读性。
2025-03-07 16:30:00
639
原创 哈希表算法
法二:分析⼀下题⽬,出现「⾄少两次」的意思就是数组中存在着重复的元素,因此我们可以⽆需统计元素出现的数⽬。• 如果不符合条件,那么前⼀个下标⼀定不可能与后续相同元素的下标匹配(因为下标在逐渐变 ⼤),那么我们可以⼤胆舍去前⼀个存储的下标,转⽽将其换成新的下标,继续匹配。在遍历数组的时候,⼀边检查哈希表中是否 已经出现过当前元素,⼀边将元素加⼊到哈希表中。2.因此,我们可以使⽤「哈希表」,令数组内的元素做key 值,该元素所对应的下标做val 值,将 「数组元素」和「下标」绑定在⼀起,存⼊到「哈希表」中。
2025-03-07 11:00:00
1063
原创 vector的使用
提供了丰富的接口,支持动态数组的常见操作,包括构造、赋值、访问、修改、容量管理和迭代等。它是 C++ 中最常用的容器之一,适合需要动态调整大小的数组场景。是 C++ 标准库中最常用的动态数组容器,提供了丰富的接口来操作和管理数组。
2025-02-23 21:44:46
982
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人