- 博客(242)
- 收藏
- 关注
原创 嵌入式系统
来源:《1.1 嵌入式系统设计概述.pdf》IEEE定义:“控制、监视或辅助设备、机器和车间运行的装置”。常见定义:以应用为中心、以计算机技术为基础、可裁剪软硬件、满足严格要求的专用计算机系统。:w:保存:w!:强制保存:q:退出:q!:强制退出:wq:保存并退出:wq!:强制保存退出:set nu:显示行号:set nonu:取消行号:复制行块:移动行块:n1,n2 d:删除行块:替换字符串答案(基于第4页):R0–R15:通用寄存器A1–A4:同R0–R3,用于入口参数、结果、暂存。
2026-01-10 12:05:30
637
原创 利用信号完成这个联动需求
只做基础初始化(创建曲线控件、默认不在此时调用,避免初始化顺序风险。只在时调用;这时所有 DataManager 和 case.json 解析都已经完成,的调用环境是安全的。曲线控件通过即时更新显示变量;MultiTableWidget 的行通过里的动态生成,不依赖全局刷新信号,因此不会引起属性树乱跳。所以,崩溃的本质是:在构造阶段过早调用了依赖全局状态(DataManager/KvislManager)的逻辑,触发了未完全初始化对象的访问。
2025-12-10 21:32:22
829
原创 Pimpl(Pointer to Implementation)设计模式详解
cpp// 传统方式 - MyClass.hpublic:MyClass();private:// 私有数据成员// 需要包含<vector>// 需要包含<map>// 需要包含第三方头文件// ... 更多实现细节问题编译依赖:任何包含MyClass.h的文件都会间接包含所有依赖的头文件编译时间长:修改私有成员会导致所有包含此头文件的文件重新编译暴露实现细节:用户能看到私有成员,违反了封装原则。
2025-12-06 13:32:24
954
原创 极大概率要考的手撕题
确保一个类只有一个实例,并提供一个全局访问点。基本设计:私有构造函数// 私有构造函数,防止外部直接创建对象// 私有拷贝构造函数// 私有移动构造函数// 私有赋值操作符// 私有移动赋值操作符。
2025-11-30 16:06:19
771
原创 【无标题】
HTTP是一种应用层协议,用于在客户端和服务器之间传输超媒体文档(如 HTML)。它是万维网的数据通信基础。简单比喻:HTTP 就像我们日常的邮件通信系统。你写一封信(请求),贴上地址,投递到邮局邮局把信送到收件人收件人读信后写回信(响应),通过邮局送回给你gRPC是一个高性能、开源的远程过程调用框架,由 Google 开发。它基于 HTTP/2 协议,使用 Protocol Buffers 作为接口定义语言。简单比喻:gRPC 就像公司的内部电话系统。你直接拨打分机号(调用方法)
2025-11-30 15:55:01
879
原创 CMakeLists.txt
这是最接近真实项目的场景。假设你的项目由一个可执行文件和一个自己写的库组成,并且还使用了著名的fmt库。项目结构:text├── CMakeLists.txt (根目录的,管理整个项目)├── app/│ ├── CMakeLists.txt (子目录的,管理可执行文件)├── mylib/│ ├── CMakeLists.txt (子目录的,管理自己的库)1. 根目录的cmake。
2025-11-26 11:15:17
633
原创 unique_ptr内部实现细节
/ 编译时检查删除器是否可调用public:// 类型定义// 构造函数// 移动构造函数// 移动赋值操作符if (this!reset();// 析构函数if (ptr) {// 删除拷贝操作public:// 指针操作return ptr;return ptr;return ptr!= nullptr;// 释放所有权// 重置指针ptr = p;
2025-11-23 21:10:13
748
原创 虚假唤醒是啥
虚假唤醒是指:等待在条件变量上的线程,在没有收到任何通知(notify)的情况下,自己从等待状态返回。虚假唤醒是正常的:所有主流操作系统都可能发生总是使用循环检查条件:while循环或带谓词的wait条件变量必须与互斥锁配合使用在修改条件后记得通知或在锁外进行通知:避免被通知线程立即阻塞。
2025-11-23 21:08:42
658
原创 线程的阻塞和等待
buffer.empty()) { // 不断检查,消耗CPU。// 阻塞,等待磁盘I/O。// 阻塞,等待网络连接。// 通知等待的消费者。// 正确等待,不消耗CPU。// 唤醒等待的线程。// 如果锁被占用,线程阻塞。// 等待:有任务或线程池停止。// 2. 忙等待 - 消耗100% CPU核心。// 1. 条件变量等待 - 几乎不消耗CPU。// 1. I/O阻塞 - 几乎不消耗CPU。// 2. 线程进入等待状态。// 3. 网络阻塞 - 几乎不消耗CPU。
2025-11-20 20:24:27
569
原创 i++和++i
根本差异i++需要保存原始值并返回,++i直接返回新值对内置类型:现代编译器通常能优化掉差异对自定义类型++i明显更高效,避免临时对象创建最佳实践:默认使用++i,养成习惯cpp// 推荐:总是使用前置递增it!++it) {// ...// 只有在需要原始值时使用后置递增// 明确需要旧值这个习惯在C++编程中很重要,特别是在处理STL迭代器和自定义类型时。
2025-11-20 19:49:14
611
原创 https
客户端和服务端打招呼,并且把自己支持的TLS版本,加密套件,第1随机数发给服务端服务端打招呼,确认支持的TLS版本以及选择的加密套件,同时也生成一个第2随机数发给客户端,接着服务端还把证书和公钥发送给客户端,发送完毕客户端生成第3随机数,预主密钥(用刚刚收到的公钥进行加密后再发送出去)服务端收到加密后的预主密钥以后,用自己的私钥进行解密,这样服务器就知道预主密钥,而且只有客户端和服务端知道这预主密钥最后客户端,用预主密钥,第1随机数,第2随机数计算出会话密钥。
2025-11-18 21:12:12
1113
原创 堆和栈(程序内存里的和数据结构里的)
栈是快速通道(自动管理,小而快),堆是自由仓库(手动管理,大而慢)。用栈存小东西(局部变量),用堆存大东西(动态对象)——别忘了delete,否则内存会像雪球一样越滚越大!小数据 → 栈(局部变量、小数组)大数据 → 堆(动态数组、对象)堆内存 → 必须delete(否则内存泄漏)栈空间有限 → 别放大数组!💡面试加分句“在项目中,我们用栈存函数参数和局部变量,用堆存需要跨函数存活的数据。为了防止内存泄漏,我们用(C++11)自动管理堆内存。
2025-11-18 21:07:36
662
原创 Redis的主从同步,哨兵集群
主从同步:通过RDB快照 + AOF增量命令实现数据同步哨兵集群:通过多数派投票实现自动故障转移核心思想:用空间换时间(从节点备份),用复杂度换可用性(哨兵监控)记住,面试官问这个问题不只是想知道技术细节,更想了解你是否真正理解分布式系统的高可用设计思想。所以回答时要体现出你的系统思维和实践经验!项目阶段看似简单实际需要我的建议配置文件✅✅但需要理解每个参数含义环境准备❌✅重点!占40%时间故障测试❌✅不能跳过客户端连接❌✅不能直接连主节点监控报警❌✅。
2025-11-17 22:38:58
1005
原创 socket编程
服务器:创建Socket → 绑定 → 监听 → 接受连接 → 通信 → 关闭客户端:创建Socket → 连接服务器 → 通信 → 关闭Socket编程是网络开发的基石,可能一开始会有点难,但一旦掌握了,你就会发现它真的很酷!就像我第一次成功实现一个简单的聊天程序时,那种成就感简直无法形容。💡小贴士:在面试中,不要只说"我用过Socket",要说"我理解Socket的工作原理,知道TCP和UDP的区别,能处理常见的错误,比如连接超时、地址占用等。
2025-11-16 21:51:10
738
原创 有一个rand函数,生成1的概率是p,0的概率是1-p,那么如何用它生成一个rand2(),使得生成1和0的概率都是0.5
连续调用两次 rand(),直到得到不同结果,返回第一个值🧪 代码输出示例(实际运行结果)💡 为什么这个方法最优? 方法 期望调用次数 优点 缺点 成对比较法 ✅ 简单高效 ✅ 理论最优 ❌ 重试时浪费调用 暴力法 无穷 ❌ 无法保证等概率 ❌ 无法实现 期望调用次数计算: 一次尝试(两次调用)成功的概率 = 期望尝试次数 =
2025-11-16 15:47:04
673
原创 给定一个数组,如何用最小的比较次数获得最大最小值
💡:你有4个苹果,想找出最重和最轻的。暴力法:先两两比重→选出最重的(3次),再两两比轻→选出最轻的(3次),总共6次。
2025-11-16 15:41:51
245
原创 [特殊字符] 无锁线程安全循环队列实现(C++)
问题你的担忧事实为什么正确"需要把元素放回""会不会出问题"不需要!元素一旦入队,永久保留在缓冲区无锁实现"会不会有数据竞争"没有使用CAS和原子操作保证线程安全内存顺序"为什么用release/acquire"确保数据可见性避免编译器/处理器重排序💡面试金句"在无锁队列中,元素一旦入队,就永远留在缓冲区,通过指针移动来管理队列,不需要移动元素。这个实现是标准、正确、高效的,完全符合C++并发编程的最佳实践。面试官看到这个实现,会认为你对并发编程有深入理解。
2025-11-16 15:37:05
575
原创 条件变量 wait 方法的两种用法详解
你的改进思路是完全正确的!使用带谓词的wait语法更简洁:一行代码代替多行循环意图更明确:直接表达"等待直到条件成立"更安全:自动处理虚假唤醒更现代:符合C++11的最佳实践唯一的修正点是谓词逻辑需要与原代码的等待条件取反,这样就能获得更清晰、更安全的代码。
2025-11-15 12:45:29
902
原创 《C++ std::forward 完美转发详解》—— 从零开始,手把手教你理解
是 C++ 模板的"传值魔法"在模板函数中,它让参数的值类别(左值/右值)原封不动地传递给下一个函数避免拷贝,实现移动语义,是现代 C++ 高效代码的基石。
2025-11-14 11:43:09
648
原创 try_lock_for 详细解析:如何使用及避免死锁
是 C++ 中实现超时锁的关键机制它通过设置合理超时时间,避免线程无限等待在多锁场景中,能有效破坏死锁的'环路等待'条件使用时需注意超时时间设置和避免重复加锁是避免死锁最常用、最有效的策略之一在实际项目中,与try_lockstd::lock结合使用,能构建出健壮、高效的多线程程序,避免死锁问题。
2025-11-12 19:24:06
677
原创 Muduo库中主线程到子线程的连接分发机制
为了彻底理解Muduo中主线程与子线程的通信机制,我将从Muduo的基本架构讲起,然后深入分析线程间通信的实现。通信机制:使用eventfd进行线程间通信,而不是pipe或其他方式优势:节省文件描述符、内存消耗小、性能高通信流程主线程将任务添加到子线程的pendingFunctors_队列调用wakeup()唤醒子线程子线程执行doPendingFunctors(),处理任务设计思想遵循"one loop per thread"原则每个socket只被一个线程处理。
2025-11-12 18:42:43
627
原创 eventfd
eventfd的本质是一个内核维护的64位无符号整型计数器,通过文件描述符暴露给用户空间。它不是文件,也不是内核缓冲区,而是一种事件通知机制。它符合Linux"一切皆文件"的设计哲学它提供简单的事件通知机制,无需传输实际数据它与epoll等I/O多路复用机制完美集成它的实现轻量级,只需1个文件描述符,内核开销极小相比管道,eventfd更适合用于事件通知场景,而不是数据传输场景。
2025-11-12 18:42:29
793
原创 主从同步配置的步骤
您提供的配置是一个标准的MySQL主从同步配置,基于Docker实现,使用异步复制方式。简单易用,适合开发和测试环境通过Docker实现环境隔离使用ROW模式的binlog确保数据一致性通过read_only设置防止从库被直接写入主从同步是实现高可用、读写分离和数据备份的基础,正确配置主从同步对构建可靠的应用系统至关重要。
2025-11-11 14:29:07
839
原创 C++面试题:结构体内存对齐
问题答案原因对齐模数4时占用内存12字节按默认4字节对齐,需填充最小占用内存8字节通过调整成员顺序(int → short → char)如何修改对齐模数alignas(1)通过编译器指令或C++11特性为什么不能设为1或21:导致未对齐访问,性能下降;2:无法满足int 4字节对齐要求CPU优化基于对齐内存关键点:内存对齐是CPU和编译器共同决定的,不是程序员随意可以修改的。
2025-11-10 18:56:56
883
原创 C++场景题:避免两把锁同时获取的死锁问题
方法优点缺点std::lock简洁、安全、标准库提供需要C++11及以上给锁编号理解原理、可手动实现代码稍复杂,需要手动处理顺序超时获取锁避免永久等待可能需要额外的逻辑处理超时情况在C++面试中,正确回答这个问题,特别是提到std::lock和给锁编号的策略,能展示你对多线程编程和死锁问题的深入理解。
2025-11-10 18:52:40
360
原创 muduo库项目可能会问到的问题
特性selectpollepoll事件驱动❌❌✅无数量限制❌✅✅数据拷贝每次调用拷贝每次调用拷贝仅注册/删除时拷贝时间复杂度O(n)O(n)O(1)LT/ET支持❌❌✅muduo选择LT模式:简单、可靠、代码易维护ET模式适用场景:需要极致性能、大流量处理、对延迟敏感的场景readylist长度:由maxevents参数控制,可以设置得足够大。
2025-11-10 18:31:06
604
原创 C++面试题:Linux常用指令详解
是管理大型项目的必备工具。掌握这些命令不仅能帮助你快速解决问题,还能展示你对Linux环境的熟悉程度,这对于C++开发岗位尤为重要。在实际工作中,我习惯使用。"在C++开发中,熟练使用Linux命令是必不可少的技能。),这些命令能极大提高开发效率。特别是对于C++开发者,确保没有内存泄漏,这些工具大大提高了我的工作效率。是调试内存问题的利器,
2025-11-09 20:22:51
421
原创 C++常见排序算法详解
面试金句:在C++排序算法选择中,没有"最好"的算法,只有"最适合"当前场景的算法。对于大多数C++应用场景,标准库的std::sort是最佳选择,它结合了快速排序、堆排序和插入排序的优势,提供了最优的平均性能。在需要自己实现排序算法时,应根据数据规模、数据特性、内存限制等因素进行选择。"排序算法是计算机科学的基石,但没有银弹。理解各种排序算法的原理、优缺点和适用场景,才能在实际项目中做出正确的技术决策,避免'排序算法选择不当导致性能下降10倍'的悲剧。
2025-11-09 15:32:24
630
原创 什么是跳表
最笨的方法:从第一页开始一页一页翻找 → O(n)聪明的方法:先看目录,找到大概范围,再细找 → 这就是跳表的思想跳表就是一种支持快速查找的有序链表,通过建立多级索引来加速查找过程。实现简单:比平衡树容易理解和实现性能优秀:平均O(log n)的查找、插入、删除支持范围查询:天然支持有序遍历并发友好:更容易实现线程安全版本跳表通过"空间换时间"和"概率平衡"的思想,在保持链表简单性的同时,获得了接近平衡树的性能,是现代系统中广泛使用的重要数据结构。
2025-11-08 17:00:32
663
原创 水平触发 vs 边缘触发
主要基于可靠性和简单性的考虑:水平触发编程模型更简单,不容易遗漏事件或造成数据丢失;在现代Linux系统中,水平触发的性能与边缘触发相差无几;"虽然边缘触发的理论峰值性能可能更高,但在实际网络应用中,瓶颈很少出现在epoll机制本身。:只要文件描述符处于就绪状态(比如读缓冲区有数据,写缓冲区可写),就会持续通知。:在连接数极大且活跃连接比例很低的场景下,边缘触发可能更高效。在现代Linux中,水平触发的性能与边缘触发相差无几。:更简单,不容易遗漏事件,可以分多次处理数据。
2025-11-06 21:30:02
767
原创 面试后查缺补漏--cmake,makefiles,g++,gcc(AI写)
单文件g++ -o 输出文件名 源文件.cpp多文件: 列出所有源文件或分别编译后链接常用选项-Wall(警告),-g(调试),-O(优化)运行./可执行文件名。
2025-11-06 20:07:43
774
原创 面试后查缺补漏--cmake,makefiles,g++,gcc(自写精华版)
自动化: 自动检测文件变化,只重新编译必要的文件高效: 支持并行编译,加快构建速度灵活: 可以定义复杂的构建规则可移植: 在不同 Unix-like 系统上都能工作对于小型到中型 C++ 项目,Makefile 是一个非常实用的构建工具!3.cmake编写生成cmake生成构建系统编译make或其他构建工具运行: 执行生成的可执行文件。
2025-11-06 20:05:56
939
原创 防止缓存穿透
布隆过滤器使用多个哈希函数和一个位数组,通过"一定不存在"的特性来防止缓存穿透。cpp// 伪代码示例private:// 布隆过滤器// Redis客户端// 数据库客户端public:// 1. 布隆过滤器检查if (!log("布隆过滤器拦截: " + key);return "";// 一定不存在,直接返回// 2. 查询Redis// 3. 查询数据库// 写入Redis,设置合理过期时间} else {// 数据库也不存在,可能是布隆过滤器误判。
2025-11-05 21:38:09
577
原创 C++ 锁类型大全详解
基本互斥锁:保护共享数据的基本工具读写锁:优化读多写少的场景锁管理器:基于 RAII 的安全锁管理无锁编程:最高性能的原子操作同步原语:复杂的线程协调工具关键建议优先使用锁管理器,避免手动锁操作根据场景选择合适的锁类型保持临界区尽可能小读写分离场景使用读写锁简单操作用原子变量替代锁掌握这些锁类型,你就能应对各种多线程编程场景了!
2025-11-04 14:53:33
610
原创 C++内存序详解
flag.load(std::memory_order_acquire)) { // 3. 获取标志(保证4在3之后)int r1 = y.load(std::memory_order_relaxed);// 可能看到y=1但x=0。// 1. 准备数据。// r1 == 1 (y已设置) 但 r2 == 0 (x还未设置)// 可能的顺序:1→2→3→4 或 1→3→2→4 等。// 必须对其他线程可见 (release语义)
2025-11-03 09:57:08
990
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅