- 博客(43)
- 收藏
- 关注
原创 Linux 内存管理详解:从物理内存到虚拟地址空间
内存管理是操作系统管理内存资源的机制,包括:分配 / 回收 内存虚拟地址到物理地址映射内存保护和隔离交换空间(Swap)策略缓存管理与页面回写项目说明管理机制虚拟内存、页表、缓存等分配策略Buddy、Slab、mmap 等地址隔离用户/内核空间划分明确关键优势安全、可扩展、支持交换开发关注点避免泄漏、合理分配、理解堆栈布局。
2025-05-06 16:22:36
1103
原创 C++ 中的静态链接和动态链接详解
链接(Linking)是 C++ 编译过程的最后一步。它的作用是将多个**目标文件(.o/.obj)和库文件(.a/.so/.lib/.dll)**整合成一个可执行文件。项目静态链接动态链接文件体积大小启动速度快稍慢内存占用多少(共享库)升级维护不方便方便安装部署简单(只有一个文件)需要一同部署动态库适用场景独立部署,发布发布发布!插件、共享库、多程序共用模块。
2025-05-06 15:41:16
625
原创 libevent库详解:高性能异步IO的利器
libevent是一个轻量级、跨平台的事件通知库,封装了底层的selectpollepoll(Linux)、kqueue(BSD/macOS) 等系统调用,为网络编程提供统一接口。其核心目标是异步事件驱动,适合构建高并发的网络服务程序。
2025-05-02 21:56:11
773
原创 优雅关闭服务:深入理解 SIGINT / SIGTERM 信号处理机制
SIGINT中断信号,通常是用户按下Ctrl + C发出的;SIGTERM终止信号,默认kill命令发送(非kill -9这些信号是可以被捕获、处理或忽略的,适合用于执行清理操作。用signal()或更安全的监听信号处理 SIGINT 和 SIGTERM,避免只处理一个服务必须支持异步关闭机制(gRPC 的Shutdown()、HTTP 的stop()保留资源清理接口(连接池、日志等)结合主线程wait()和后台信号监听线程工作。
2025-05-01 21:44:30
651
原创 全面详解 MySQL 存储过程(Stored Procedure)
存储过程是预编译的 SQL 语句集合,封装在数据库中,用户可以通过名字调用它,并传入参数完成一系列数据库操作。换句话说,存储过程是数据库中的函数,你不必每次都写 SQL,而是只要调用,就能重复使用逻辑。存储过程是数据库中封装 SQL 的重要机制,适用于封装业务逻辑、提高性能和安全性。通过参数实现输入输出控制,配合事务和流程控制增强逻辑性。尽管调试略麻烦,但在一些特定场景(如注册、权限控制、日志写入等)非常实用。推荐配合连接池、后端接口调用实现自动化业务流程。
2025-04-30 11:47:01
725
原创 一文搞懂 JavaScript 中的 Promise、async 和 await
JavaScript 是单线程语言,无法同时执行多个任务,但我们常常会遇到耗时操作(如网络请求、IO读写)。为了不阻塞主线程,JavaScript 引入了异步编程模型。在早期,异步依靠回调函数来实现,但回调嵌套过多就会出现“回调地狱因此,ES6 引入了Promise,ES2017 又引入了,让异步逻辑更加清晰可控。Promise 是一个表示异步操作的最终完成(或失败)及其结果的对象。pending(进行中)fulfilled(已成功)rejected(已失败)特性Promise可读性中等,链式调用。
2025-04-30 11:11:31
1062
原创 通过 Node.js 搭配 Nodemailer 实现邮箱验证码发送
if (!email) {// 生成6位随机验证码// 保存到 Redis,设置过期时间5分钟// 发送邮件from: '你的QQ邮箱@qq.com',to: email,subject: '您的验证码',text: `您的验证码是 ${code},有效期5分钟,请勿泄露。try {res.send({ message: '验证码发送成功' });console.error('发送失败', err);
2025-04-29 09:40:29
982
原创 【超详细讲解】什么是序列化和反序列化?
序列化是将对象的状态转换为可存储或可传输格式的过程。对象在内存中一般以特定的数据结构(指针、引用、哈希表、链表等)存在,直接传输内存数据是不可靠的(不同机器架构不同、数据对齐不同、指针无意义等问题)。所以我们需要将对象转换成连续的字节流(或标准格式的文本),使得:可以写入磁盘文件可以通过网络发送到远端可以被其他进程或设备正确解析简单来说,序列化是让数据“离开内存,去旅行”的必备装备。反序列化就是序列化的逆过程。把收到的字节流或文本格式数据,还原成内存中的对象或数据结构,供程序继续操作。
2025-04-28 11:24:31
1377
原创 gRPC入门与使用详解
gRPC(Google Remote Procedure Call)是 Google 开源的一款高性能、跨语言的远程过程调用(RPC)框架。它基于 HTTP/2 协议进行通信,使用作为默认的序列化方式。通俗地讲,gRPC 就是让不同服务器不同服务之间像调用本地函数一样,远程调用彼此的方法,且速度快、效率高!// 定义一个简单的服务// 请求消息// 响应消息。
2025-04-28 10:57:16
725
原创 深入解析 kmalloc、vmalloc 和 malloc
特性mallockmallocvmalloc使用空间用户空间内核空间内核空间连续性虚拟地址连续虚拟+物理地址连续虚拟地址连续、物理不一定连续速度快很快相对较慢大小适用范围小到大小(<128KB)大(MB甚至更多)释放函数freekfreevfree应用场景应用程序开发驱动开发/小内存块驱动开发/大内存块。
2025-04-27 11:43:09
644
原创 详解Asio网络编程
使用Asio使用io_context驱动事件循环使用async_*方法进行异步 I/O使用回调函数处理完成事件多线程处理高并发欢迎补充讨论。
2025-03-31 15:25:39
384
原创 详解shared_from_this
是 C++ 标准库 () 提供的一个机制,允许类在不创建新的的情况下,获取指向自身的,从而安全地管理对象的共享所有权。避免引发。确保对象生命周期,在回调、事件管理等场景中常用。必须确保对象已由管理,否则调用会导致运行时错误。在 C++ 中,是一个强大而易踩坑的工具,正确使用它可以防止内存泄漏和未定义行为。
2025-03-30 16:58:27
545
原创 设计模式-单例模式
在软件开发中,某些对象只需要一个实例,且该实例应该在整个系统范围内被共享。这种需求催生了单例模式(Singleton Pattern)。单例模式是一种创建型设计模式,它确保一个类在整个应用程序的生命周期中只有一个实例,并提供一个全局访问点。
2025-03-30 15:59:13
721
原创 C++智能指针详解
在计算机编程中,特别是使用C++语言时,内存管理一直是一个复杂且容易出错的任务。程序员需要手动分配和释放内存,稍有不慎就可能导致内存泄漏或悬挂指针问题,这些问题不仅会影响程序的性能,还可能引发严重的错误甚至安全漏洞。为了简化内存管理并减少这些潜在的问题,C++标准库引入了“智能指针”(Smart Pointer)。顾名思义,智能指针是一种封装了原始指针的对象,它能够自动管理指针的生命周期。这意味着程序员不需要手动分配和释放内存,智能指针会自动处理这些任务,确保资源得到合理使用。
2025-03-29 19:43:47
1019
原创 基于 Qt / HTTP/JSON 的智能天气预报系统测试报告
随着人们对生活品质要求的提高,天气预报已成为日常生活的重要组成部分。通过准确的天气信息,用户可以更好地规划出行、穿衣等日常活动。本项目旨在开发一个基于 Qt 框架的天气预报系统,实现实时天气数据的获取、展示以及历史天气数据的查询功能。
2025-03-28 21:43:14
996
原创 使用 Qt 处理 JSON 数据:从入门到精通
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也适合机器解析和生成。它基于 JavaScript 对象语法,并且独立于语言,几乎在所有现代编程语言中都有实现。JSON 的主要特点包括:易读性和简洁性。支持复杂的结构,如对象、数组、字符串、数字、布尔值等。轻量级,解析速度快。通过上述步骤,我们已经成功地生成并解析了 JSON 数据。
2025-03-28 20:33:51
883
原创 详解Http:在QT中使用Http协议
HTTP是Web开发中的核心协议,而Qt提供了强大的网络库来简化HTTP通信。通过和相关类,你可以轻松发送请求、处理响应以及解析数据。无论是简单的GET请求还是复杂的POST操作,Qt都能提供高效且可靠的解决方案。希望这篇帖子能帮助大家更好地理解如何在Qt中使用HTTP!如果有任何问题,请随时讨论。
2025-03-28 17:53:14
1451
原创 [特殊字符] C++ 常见 Socket 错误与优化指南
问题优化方案端口占用允许端口快速复用Socket超时和限制超时时间单线程服务器阻塞使用多线程(std::thread)或epoll/select部分发送/接收send_all()和recv_all()确保完整数据传输欢迎补充问题!
2025-03-23 17:22:35
418
1
原创 深入解析 Socket:网络通信的桥梁
Socket?Socket本质上是一个端点(endpoint),用于在不同设备或进程之间进行数据传输。可以把它想象成电话插孔,只要两端正确连接,就可以通过它进行通信。Socket 依赖IP 地址 + 端口号IP 地址:定位计算机(类似于电话号码)端口号:区分不同进程(类似于电话分机)
2025-03-23 17:13:21
797
原创 深入解析 TCP:可靠传输的基石
你有没有想过,当你刷微博、看视频、玩游戏时,数据是如何稳定地从服务器传输到你的设备上的?这背后有个关键角色——!
2025-03-22 17:39:07
735
原创 基于TCP/QT/C++的网络调试助手测试报告
在网络应用开发和嵌入式系统调试过程中,开发者经常需要模拟客户端-服务器交互,以验证数据传输的正确性和稳定性。然而,传统的网络调试工具通常难以同时支持多个客户端的管理,或者缺乏灵活的调试能力。因此,本项目基于 Qt 框架实现了一款功能强大、易于使用的网络调试助手,旨在提高开发和测试效率。类别功能API/方法TcpServer监听TcpServer连接TcpServer关闭TcpServer信号新连接TcpScoket连接TcpScoket发送TcpScoket接收。
2025-03-22 17:26:51
787
原创 ‘telnet‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件
Telnet(远程登录)是一种用于通过互联网连接到远程计算机的协议。它允许用户在自己的设备上访问并控制另一台计算机,就像直接使用该计算机一样。
2025-03-20 18:18:47
1413
原创 Leetcode349:两个数组的交集
以数组1中的值为键值,给对应位置置1,以数组2中的值为键值,给对应位置减1,如果减1后为0,则表示数组1中存在该值。输出结果中的每个元素一定是。[4,9] 也是可通过的。
2024-12-10 21:22:00
219
原创 Leetcode224:基本计算器
因为题中不涉及乘法除法操作,所以分情况把括号拆开,逐个计算,仅使用一个符号栈即可。注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如。,请你实现一个基本计算器来计算并返回它的值。给你一个字符串表达式。
2024-11-06 21:22:08
160
原创 Leetcode394:字符串解码
使用两个栈,分别存放数字和字符串,当遇到数字时,转换为int型,存放到num,遇到字符时,存放到res中,遇到左括号时,将num、res分别压栈,遇到右括号时,数字栈出栈k,字符栈出栈并循环k次。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数。给定一个经过编码的字符串,返回它解码后的字符串。由小写英文字母、数字和方括号。中所有整数的取值范围为。,表示其中方括号内部的。
2024-11-06 20:12:51
193
原创 Leetcode2:两数相加
要考虑进位的情况,容易忽略的是处理最后的进位问题,在写循环条件时要考虑进位。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。的链表,表示两个非负的整数。它们每位数字都是按照。请你将两个数相加,并以相同形式返回一个表示和的链表。的方式存储的,并且每个节点只能存储。题目数据保证列表表示的数字不含前导零。每个链表中的节点数在范围。
2024-11-05 19:59:44
302
原创 Leetcode150:逆波兰表达式求值
使用栈操作,遍历数组,遇到数字入栈,遇到运算符,出栈两个数字,进行运算,将结果再入栈,值得注意的是,入栈需要将数字转换为整型,数组中存储的是string类型。该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6。该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9。逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。每个操作数(运算对象)都可以是一个整数或者另一个表达式。返回一个表示表达式值的整数。输入是一个根据逆波兰表示法表示的算术表达式。
2024-11-05 17:28:00
366
原创 Leetcode155:最小栈
-> 返回 -3.minStack.getMin();--> 返回 -2.minStack.top();操作,并能在常数时间内检索到最小元素的栈。使用一个辅助栈,在辅助栈栈顶记录最小元素。将元素val推入堆栈。获取堆栈中的最小元素。删除堆栈顶部的元素。获取堆栈顶部的元素。
2024-11-05 17:11:30
351
原创 Leetcode328:奇偶链表
将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。的时间复杂度下解决这个问题。
2024-11-04 17:09:49
316
原创 Leetcode21:合并两个有序链表
新建链表节点,使用三个指针,两个指针用于判断两个链表值的大小,另一个指针控制新链表。新链表是通过拼接给定的两个链表的所有节点组成的。将两个升序链表合并为一个新的。两个链表的节点数目范围是。还可以使用递归的思想。
2024-11-04 16:22:28
518
原创 Leetcode19:删除链表的倒数第N个结点
递归的思想,定义一个计时器,当等于n时返回子链表的下一个,否则返回子链表头。使用快慢指针,快指针比慢指针多走n步。注意,计时器要定义在递归函数外面。给你一个链表,删除链表的倒数第。个结点,并且返回链表的头结点。
2024-11-01 20:32:35
358
原创 Leetcode24:两两交换链表中的节点
第二种方法使用递归,首先判断递归终止的条件,当前节点为空或当前节点指向空时,递归退出,接下来找返回值是什么,返回的是处理过的子链表的头节点,最后思考单次的操作过程,同样以1234为例,假设后面已经处理好了,当前的顺序是1243,则2->1,1->4。给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。链表中节点的数目在范围。
2024-10-24 22:11:28
263
原创 Leetcode88:合并两个有序数组
可以直接合并数组然后使用快排排序,也可以使用双指针的思想,比较两个数组当前指针位置的大小,如果从左到右正向排,会覆盖nums1中前面的元素,我们可以倒序,从右往左排,nums1中后n个元素为0,从后往前不会覆盖前面的元素,使用三个指针,第一个指向nums1前m个元素的末尾,即指向nums1[m-1],第二个指针指向nums2[n-1],第三个指针指向nums1[m+n-1],根据前两个指针位置的大小,判断第三个指针所指元素该填入哪个值。,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
2024-10-22 21:51:16
328
原创 Leetcode66:加一
考虑几种情况,末尾不为9时,不需要进位,直接加一;全为9时,数组需要扩张,创建新数组,数组长度比原来大一个,首位置1,其余位默认为0;最后几位为9时,当前为置0,前一位加一。你可以假设除了整数 0 之外,这个整数不会以零开头。最高位数字存放在数组的首位, 数组中每个元素只存储。数组所表示的非负整数,在该数的基础上加一。加 1 得到了 9 + 1 = 10。因此,结果应该是 [1,0]。输入数组表示数字 4321。输入数组表示数字 123。输入数组表示数字 9。
2024-10-22 21:16:14
217
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人