自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(184)
  • 资源 (2)
  • 收藏
  • 关注

原创 Python 复制、浅拷贝、深拷贝:改副本为什么原对象也变了

系统讲透 Python 复制三兄弟——赋值(共享引用)、浅拷贝(复制外层共享内层)、深拷贝(递归复制完全独立),并深入到 memo 机制、循环引用、不可变对象优化、自定义 __copy__/__deepcopy__ 协议。所有示例在 Python 3.13 下实际运行过,输出为真实结果。

2026-10-26 21:27:54 101

原创 Python is 与 ==:身份和值,一字之差两种坑

系统讲透 is(身份比较)与 ==(值比较)的本质区别,深入到 id() 底层、小整数缓存、字符串驻留(sys.intern)、常量折叠、自定义 __eq__/__ne__/__hash__ 的协议约定、枚举与哨兵对象的单例语义、NaN 特例,给出唯一可靠的判断标准。所有示例在 Python 3.13 下实际运行过,输出为真实结果。

2026-10-26 21:27:26 62

原创 Python 推导式 vs 生成器表达式 vs map/filter:该怎么选

对比列表推导式(list comprehension)、生成器表达式(generator expression)、map/filter 三者的语义、内存占用和适用场景,讲清"什么时候该用哪一个"——列表推导式求结果、生成器表达式省内存、map/filter 适合已命名函数。所有示例在 Python 3.13 下实际运行过,输出为真实结果。

2026-10-26 21:27:10 191

原创 Pydantic v2 完全指南:从数据校验到大模型结构化输出

讲透 Pydantic v2 到底做了什么(校验/转换/序列化三件事都靠类型注解自动完成),对比 dataclass、TypedDict、手写校验、marshmallow 说明为什么用它;再用 OpenAI SDK 调 DeepSeek,靠 Pydantic 把大模型返回的 JSON 变成可信的强类型对象,并手写一个 ReAct Agent,逐字段读懂大模型的完整响应报文。所有示例在 Python 3.13 + Pydantic 2.14 下实际跑通,可直接复制使用。

2026-10-24 00:12:27 441

原创 ReAct Agent 实战:用 OpenAI SDK 逐字段读懂大模型报文

从零讲清 ReAct 是什么、在 Agent 架构谱系里的位置;用 OpenAI 官方 SDK 跑一个最小实现(deepseek-flash),把每一轮真正收发的原始报文一字不差打印出来逐字段读,再用本地抓包代理看穿 HTTP 层——理解大模型输入输出协议的最短路径。

2026-10-22 09:19:01 162

原创 前瞻:std::generator、reflection 与 C++ 的未来方向

是现在就能用的惰性序列工具(gcc 14+,co_yield写起来像 for 循环);contracts 在 gcc 15 已能实验性用(加reflection 还是 C++26 的未来方向,主流编译器都没实现(先用 generator 把协程吃透,contracts 可以在新编译器上尝鲜,reflection 落地前继续用宏和结构化绑定,别在未稳定的语法上押注。

2026-10-20 08:35:42 294

原创 C++ 高频知识体系 · 导航目录

这是本知识库的总目录,目标是把 C++ 从入门讲到能独立做性能优化和工程架构。每一篇都能独立看懂:示例全部真编译真运行过,涉及性能与内存的地方都写清了「哪种写法更优、为什么」。:第一次来,按体系顺序从前往后读——前面的体系是后面所有内容的地基;已经有基础了,直接跳到你关心的那一节。每篇都是独立文章,点标题直接进。

2026-10-18 21:36:28 16

原创 C++23 核心新特性:std::expected、std::print、deducing this、monadic optional

补上「值 or 错误」的缺口,std::print让输出类型安全又简洁,deducing this 消灭 CRTP 样板(需 gcc 14+),monadic optional 让可空值能像流水线一样链式处理——这四个是 C++23 里最值得先上手、也最能立刻替换掉手写样板的一组特性。

2026-10-18 21:36:10 82

原创 C++17 升 C++20 迁移清单:编译开关、破坏性改动与报错对照表

C++17 → C++20 的迁移本质上是一条命令 + 五类报错:改-std=c++20后全量编译,把char8_tallocator成员移除、比较运算符重写、volatile弃用、聚合初始化这几类改动分类批量修完,再用复验一遍,最后才动手引入<=>、Ranges 这些真正改变写法的新特性。

2026-10-18 21:35:36 59

原创 Concepts 把模板错误拦在编译期:C++20 约束的四种写法与重载偏序

concept(概念)的本质是一个编译期布尔谓词,专门用来约束类型。// 定义一个 concept:T 必须是整数类型concept是关键字(C++20 新增),等号右边必须是一个编译期可求值的bool表达式,而且这个表达式里只允许使用模板参数。第二种更常用的形式把右边的「bool 表达式」换成requires表达式,用来检测「某个表达式能不能编译过」:下一节展开。一个坑要记住:concept不能显式特化、也不能递归引用自己。想做「分档判断」,正确做法是用constexpr函数或。

2026-10-18 21:35:18 58

原创 指定初始化器:C++20 给聚合初始化补上的最后一块

C++20 的指定初始化器把「成员名」写进了初始化式,从此合法;它的价值在于抗「加成员 / 调顺序」——位置初始化的语义靠数位置,中间插一个成员就会静默改掉后面所有字段的含义,而指定初始化器要么名字对上、要么编译报错。代价是规则比 C 严得多:必须按声明顺序、不许与位置初始化混用、不许嵌套指定(要写)、只对聚合类型有效、不许窄化、同一成员只能指定一次——六条各有明确的编译报错。没有不变量的纯数据包用聚合 + 指定初始化器,有不变量的类型老老实实写构造函数;聚合初始化天生没法在构造时拦截非法值,别指望它。

2026-10-18 21:35:00 186

原创 C++20 升 C++23 迁移清单:开关、破坏性改动与收益

开关一改基本就能编过(破坏性改动极少),然后按收益顺序替换:先上std::print、monadic optional,用 feature-test 宏做 C++20/C++23 共存的过渡闸门;唯一要记住的坑是 gcc 13 的还是202100L,判特性别用它,用。

2026-10-18 21:34:45 163

原创 std::launder、std::bit_cast 与 placement new:合法绕过别名

跨类型读位模式,是严格别名违规的 UB(哪怕跑起来「看着对」),合法手段是memcpy(C++17 通用)或(C++20,等价且 constexpr),两者都会被优化成零开销的寄存器搬运;原地重建对象后,旧指针指向的是「已死对象」,必须用洗掉编译器的过时缓存假设——这三条路线合起来,就是「合法绕过别名」的完整答案。

2026-10-18 21:33:29 179

原创 perf 与火焰图:从热点到定位(接 Perfetto)

定位热点靠采样:perf 周期采样 + 栈回溯,记录调用栈后用火焰图直观看出「最宽的函数」;perf 管单机 CPU 热点,Perfetto 管端到端 trace,先用 perf 压热点、再用 Perfetto 看全局——「先测量,再优化」是铁律。

2026-10-18 21:33:11 293

原创 C++ 缓存预热与 prefetch:什么时候该手写

手写 prefetch 只解决「硬件预取器猜不出地址」的 pointer-chasing 热点:用软件流水线让探路指针领先dist步提前取数,dist要「够早但别太早」(太小没掩盖延迟、太大污染缓存),而且必须实测验证收益——顺序访问和大多数场景下,硬件预取器已经够用,手写反而添乱。

2026-10-18 21:32:16 161

原创 ReAct 进阶:用 Function Calling 根除模型抢跑

文本版 ReAct 里,模型会「抢跑」——没执行工具就编造 Observation,提示词拦不住。本文用 Function Calling 从协议层面根治,并逐轮展示 Agent 与大模型交互的完整原始报文:请求体、响应体、每个字段怎么读。

2026-10-18 00:40:59 199

原创 ReAct:大模型 Agent 的思考-行动循环(附可运行的 Python 实现)

用四张图、一份零依赖可运行的 Python 实现和一次真实的 DeepSeek 调用记录,逐轮拆解 ReAct 的「思考-行动-观察」循环,讲透 AI Agent 最核心的工作机制。

2026-10-17 09:32:14 48

原创 SIMD 与自动向量化:march=native、__restrict 与 likely

O3打开向量化、升级到 256 位 AVX2(代价是绑定本机 CPU);__restrict承诺指针无别名、帮编译器免去 versioning 检查;[[likely]](或)把冷分支挪出热路径;显式请求向量化。判断是否生效只有一个可靠标准——看汇编里有没有movdqupaddd(128 位)或vmovdquvpaddd(256 位)。

2026-10-17 08:49:01 58

原创 无锁内存回收:hazard pointer 与 epoch-based reclamation 原理

无锁结构里「从结构移除节点」和「物理delete节点」之间隔着一段无人知道的引用窗口,所以不能直接delete;三种回收思路本质都是「延迟释放 + 判定无人引用」。引用计数靠shared_ptr最省心、hazard pointer 靠读者声明「我在用」省读侧开销、epoch-based 靠读者登记 epoch 做到读侧免锁;这三段的代码都是讲原理的最小实现,生产级请直接用libcds或内核 RCU 这类经过验证的现成库,别自己重造。

2026-10-17 08:48:26 67

原创 异常的实现与代价:零成本异常、栈展开与 -fno-exceptions 什么时候用

C++ 异常的「零成本」只针对快乐路径:表驱动的 unwind 让不抛时代码零开销,代价全部集中在抛出那一次(逐帧查 LSDA、逐帧析构局部对象,复杂度随栈深度增长);异常对象被 ABI 提升到独立的共享存储,所以能用存起来跨帧/跨线程再抛;noexcept是「抛了直接terminate」的硬承诺,只给真正不抛的函数;而省的主要是体积和「禁止异常」的强制力,不是速度:它要求你彻底改成返回码式错误处理,是贯穿全项目的架构决策,不是白嫖的编译开关。

2026-10-17 08:48:10 57

原创 三路比较运算符 <=>:C++20 两个运算符换六个

=>一次返回「小于 / 等价 / 大于」,配上运算符改写规则,让a < b变成a!= b变成!(a == b),所以= default一个<=>再加一个==,就换来了全套六个比较运算符,还顺带消灭了「改了==忘改!」这类不一致。说「等价即不可区分」,说「等价但可区分」(忽略大小写就是它),还允许「无序」(NaN默认生成是逐成员字典序、按声明顺序、见异即停,比手写「先!再」的链式比较少做将近一半的成员比较;要排除某些成员参与排序时,用std::tie手写<=>并且别忘了补上operator==,手写<=>

2026-10-17 08:47:45 130

原创 C++20 核心新特性总览:四大特性 + gcc 13 实测清单

C++20 的四大特性里,Concepts 和 Ranges 已经可以放心用,协程能跑但要自己搭基础设施,模块这次也真构建、真跑通了,代价是 CMake ≥ 3.28 + Ninja 生成器 + gcc ≥ 14(这三个条件缺一不可);<=>、指定初始化器、std::spanerase_if,它们才是升级到 C++20 后一周内就能在代码里看到效果的东西。

2026-10-17 08:47:24 232

原创 对象切片(object slicing):多态失效的隐形杀手

对象切片就是「派生类对象被按值当成基类对象拷贝」:拷贝只按进行,派生类部分放不下就被丢掉,vptr 被换成基类虚表,于是重写的虚函数静默失效、派生类数据凭空消失;解法是记住「多态对象永远不按值传递」:参数用Base*,容器用,要复制就走clone(),并按 Core Guidelines C.67 把公开的拷贝操作从基类上摘掉。

2026-10-17 08:47:03 164

原创 C++ 模板实例化膨胀:为什么编译慢、二进制大,怎么治

模板每碰到一个新的实参组合就生成一份独立的机器码与静态数据(实测静态成员地址、函数实例化地址全都互不相同),代价是二进制膨胀、指令缓存命中率下降、编译时间随实例化数量增长;模板错误大多报在实例化点而不是定义处,因为只有代入实参后T才确定。先把不依赖T的代码抽成普通函数(最有效,实测多个实例化共用一份),再用显式实例化 +让其他翻译单元直接复用,然后把长循环体抽出模板,最后用 if constexpr替代多重特化(顺带避免漏写特化导致的静默降级);

2026-10-17 08:46:48 201

原创 clang-tidy 与 cppcheck:静态分析落地

Wall管「合不合法」,clang-tidy 管「合不合意」:前者是编译顺带的底线检查,后者用管现代化改造、bugprone-*抓 move 后再用/整数除法这类语义 bug;cppcheck 再用独立引擎补资源泄漏和越界。落地就三步:写定规则、CI 里跑起来、把bugprone升级成必须修。

2026-10-17 08:46:30 188

原创 PGO 与 LTO:profile-guided 与链接时优化

LTO 用-flto把 IR 留到链接期做全局优化、拆掉编译单元边界(跨 TU 内联让call变成imul,这篇已用 CMake 工程真构建验证);PGO 用插桩、跑代表性负载生成.gcda、再按真实热点重编(沙箱受限、这篇讲流程为主)。两者正交、可叠加,但都是「用构建时间换信息量」——没有跨 TU 小函数和可预测热点,开了也白开。

2026-10-17 08:46:03 200

原创 gdb 实战:断点、watchpoint、core dump 与多线程调试

gdb 的核心就五件事:断点(break)、单步(nextstep)、看值(print)、看栈(backtrace)、观察变化(watch崩溃先看 core dump 的backtrace,多线程卡死用。记住「编译加-g -O0」这个前提。

2026-10-16 08:00:14 8

原创 tag dispatch 与重载偏序实战:按迭代器类别派发算法

读出类别 → 构造空 tag 对象 → 重载解析按「参数越特化越优先」选函数,运行时零开销;C++17 起多数场景可以用写得更集中,但理解 tag dispatch 是读懂标准库算法的前提。

2026-10-16 07:59:58 151

原创 基准测试的陷阱:优化掉、频率漂移、缓存预热

基准测试的三大坑——结果没被观测会被 as-if 规则优化掉(用防)、CPU 频率漂移让单次耗时不可比(多轮取中位数)、缓存冷热让第一轮失真(先预热)——核心心法是:耗时数字不写死、用确定性指标(循环次数、汇编指令、校验和)支撑结论,计时用,结论只建立在同一进程内的相对比较上。

2026-10-16 07:59:39 35

原创 C++ 序列化与版本兼容:没有反射,手写字段也能持久化

C++ 没有反射,序列化靠手写字段;二进制格式要管好端序(,C++20)和版本号——先写 version、读时按版本补默认值,就能让旧存档在新版本里继续读得出来。

2026-10-16 07:59:23 117

原创 C++ 日志与单元测试:无第三方库的最小实现

不引第三方库,日志和测试框架也能写得小而够用:日志靠 C++20 的默认参数自动拿调用点(文件、行号、函数名),测试框架靠EXPECT_EQ字符串化的表达式文本和__LINE__的失败定位。理解了这两点,也就理解了 gtest、spdlog 背后在做什么。

2026-10-16 07:59:04 141

原创 编译期反射模拟:C++ 没有反射怎么办

C++ 没有反射,所以「遍历成员」全靠模拟:宏(X-Macro)能拿到名字但难维护,结构化绑定能拿到值但拿不到名字,boost.pfr 的聚合推导能全自动拿到成员个数和类型但只支持聚合且实现复杂——现阶段用「宏提供名字 + pfr 提供值」的组合最务实,而 C++26 的 P2996 静态反射才是真正的解法。

2026-10-16 07:58:50 89

原创 自定义分配器与内存池:std::pmr 从零到 free list

std::pmr持有一次分配批量释放(实测把 1000 次 push 的系统分配从 11 次降到 0 次),生命周期交错的小对象则交给 free list 内存池复用节点;判断标准是「分配是否频繁 + 生命周期是否整齐」,不满足就别为池子增加复杂度。

2026-10-16 07:58:36 28

原创 C++ 跨平台工程:特性检测与 feature-test 宏实战

跨平台不是「写一份处处兼容的代码」,而是「用 feature-test 宏查能力、用平台宏查系统,在编译期裁剪出适配当前环境的实现」——库宏记得 include 头(或直接用 C++20 的<version>),判断宏用>= 版本号而不是==。

2026-10-16 07:58:20 250

原创 异常安全三级保证:copy-and-swap 实现强保证的完整套路

异常安全不是「有没有catch基本保证(RAII 免费提供:不泄漏、对象仍有效)、强保证(copy-and-swap:所有可能失败的操作在副本上做完,最后用noexcept的swap一次提交)、不抛保证(析构、swap、移动操作的地盘):多数函数做到基本保证就够,只有在「要么全成要么全不变」有真实语义的地方才值得为强保证多付一次拷贝。

2026-10-16 07:57:57 102

原创 C++ 编译期计算:把运行期的工作提前到编译之前

编译期计算是用编译时间和二进制体积去换运行期的计算时间、内存分配和初始化开销;constexpr的价值不在「让编译器会算」(优化器本来就会常量折叠),而在保证编译期求值、以及让结果能站到数组长度、switch标签、模板实参这些位置;查表法(质数表、CRC 表)是它最实在的落地场景,而就是「表确实在编译期生成」的证明;结果只是「值」时优先constexpr函数而不是模板递归,C++20 起连和算法都能进constexpr。

2026-10-16 07:57:38 59

原创 无锁栈:Treiber 栈的 CAS、ABA 问题与 tagged pointer

无锁栈靠一条循环就实现无锁的pushpop,但只比较「值」、不比较「中间有没有变过又变回来」——节点地址被复用后会产生 ABA 问题,CAS 误判成功而丢节点;破解办法是 tagged pointer,把版本号塞进指针高位、每次修改自增,让「同地址重现」也能被识别出来;再往深走还有节点回收的 use-after-free(要 hazard pointer,见 B9),所以生产级别请直接用现成库。

2026-10-15 08:07:22 134

原创 无锁队列(MPSC/MPMC):Vyukov 环形队列与 slot 未就绪问题

无锁队列比栈难在有两个端点,且fetch_add只「分配槽位」不保证「数据已写完」。Vyukov 有界队列用 sequence 数组给每个槽位记轮次号,入队等seq==pos、出队等seq==pos+1,靠 acquire/release 完成生产消费同步;MPSC 消费端单线程、只有生产端抢tail_所以相对好写,MPMC 头尾都要抢、两端都要完整 sequence 协议所以难;无论哪种,正确性都极难手写验证,生产级用 concurrentqueue / Boost.Lockfree 这类现成库。

2026-10-15 08:07:02 44

原创 类型列表与编译期算法:手写 typelist 的 map/filter

typelist 用一个空壳携带一组类型,length/at/map/filter 全靠「头尾分解 + 递归 + 偏特化」实现,结果用在编译期验证;现代 C++ 里它正被 Concepts、折叠表达式、部分取代,但读std::tuple的源码,这套手艺仍然是绕不开的底子。

2026-10-15 08:06:46 133

原创 C++ 错误处理策略:异常 vs 错误码 vs expected 的真实取舍

三种策略各有主场:异常留给「罕见且不可忽略」的逻辑错误(零成本快乐路径、抛出代价高),错误码留给「高频可预期」的常规失败(显式但易漏),C++23 的在两者之间——把错误装进类型、跨库边界安全,是现代库接口的首选。真实项目要分层混用,边界处把异常兜住转错误码,绝不让异常跨过 C ABI。

2026-10-15 08:06:27 181

01_VisualUIDesign.rar

QT入门学习Sample source code 简单的dialog ui设计

2021-09-18

空空如也

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

TA关注的人

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