这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
C++20 协程深入:co_await 机制、自定义 Awaitable 与生成器
深入 C++20 无栈协程的编译器视角:协程帧布局、co_await/co_yield 的展开机制、promise_type 与自定义 Awaitable、C++23 生成器与异步流,以及协程在服务端 IO 与性能陷阱上的实战经验。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
深入 C++20 无栈协程的编译器视角:协程帧布局、co_await/co_yield 的展开机制、promise_type 与自定义 Awaitable、C++23 生成器与异步流,以及协程在服务端 IO 与性能陷阱上的实战经验。
深入 Akka 与 Akka Cluster:Actor 系统与 ActorRef、监督与容错、集群成员管理与故障检测、集群分片(Cluster Sharding)、集群单例、分布式数据,以及如何用 Akka 构建可扩展的分布式 Actor 系统。
MongoDB Time Series Collection 时序集合的创建、桶化与压缩机制、时序聚合查询、降采样管道,以及与 InfluxDB 的架构对比和 IoT 实战案例
本节讲清编译器在没有标注时如何猜出类型。内容涵盖自下而上推断与自上而下上下文类型这两条相反的流水线、字面量拓宽与 as const 的收窄作用、数组最佳公共类型的合并规则、泛型推断候选的收集与合并顺序、回调参数获得类型的条件,以及隐式 any 与循环推导这两类失败的诊断路径。读完你能判断某处该补显式标注还是该改结构,并解释常见推导结果为何与直觉不同。
本节把 tsc 的编译产物摊开看,讲清类型擦除删掉了什么、留下了什么。内容涵盖擦除的基本规则与产物对照、泛型与 instanceof 为何在运行时不可用、as 断言为何不是校验,以及 enum、namespace、类体、装饰器元数据这些必须生成真实代码的例外。读完你能列出运行时可用的替代手段,用类型谓词与判别联合把校验集中在系统边界,并判断 private、readonly 的真实效力。
本节把「类型 A 能否赋给类型 B」从直觉变成可复述的规则:先对照名义类型理解结构化类型为何只看成员结构,再拆解可赋值性的判定顺序,涵盖成员存在性、递归兼容、参数逆变与返回值协变,并解释数组协变的历史包袱、any 与 unknown 的特殊行为、private 成员如何让比较退化为名义类型,以及结构化兼容放过 bug 时的品牌类型兜底做法。读完你能独立解读 not assignable 报错。
定时任务看似最简单,却最容易在多实例部署下出错。本节先对比系统 crontab、node-cron 与 BullMQ Job Scheduler 三条路径,解释前两者为何在容器多副本下会重复执行;再用 Job Scheduler 与确定性 jobId 解决重复投递;最后讲透并发控制的两层含义——单实例的 concurrency 与跨实例的全局闸,以及 limiter 如何把配额变成硬限制。
投递成功只是开始,任务失败之后才是真正的工程量。本节先区分可重试与不可重试的失败,讲清 BullMQ 的 attempts、backoff 与 UnrecoverableError 三件套;再解释为什么队列只能做到至少一次投递,从而引出幂等键的设计与两种落地方式;最后给出死信队列的搬移、告警与重放闭环。读完本节,你能让一个后台任务系统在失败面前保持可控,而不是无限重试或静默丢单。
本节从「为什么要把工作丢进队列」讲起,拆解 BullMQ 的 Queue、Worker、Job 三个核心对象及其在 Redis 中的存储结构,再重点解决一个工程痛点:如何用泛型把 payload 类型从生产者贯穿到消费者。你会学到 Queue 的类型参数推导、job name 的字面量联合、判别联合注册表的写法,以及 Date 序列化等常见坑。读完能把队列调用从 any 变成端到端可检查。
把缓存声明式地加到图书借阅服务上:讲清 @Cacheable / @CachePut / @CacheEvict / @Caching 的语义差异、key 与 SpEL 的写法陷阱、condition 与 unless 的执行时机、CacheManager 与多级缓存配置,以及同类内部调用失效和 TTL 表达边界。
本节把 record 版 Book 改造成 JPA 实体:讲透 @Entity、@Id、@GeneratedValue、@Column、@Table 与主键生成策略的取舍,说清为什么实体不能用 record 而 record 适合做 DTO,梳理 CrudRepository 与 JpaRepository 的继承关系,并给出实体 equals/hashCode 的可靠写法。
本节讲定时任务的三种形态与延时队列的 ZSET 调度,重点落在幂等键的设计:用 SET NX 抢占、状态机去重与结果缓存保证重复投递只执行一次,并区分「至少一次」投递语义下如何做到业务幂等;最后给出死信队列的人工重放流程与告警口径,全部用 fakeredis 2.39.0 实测。
本节先对比 Celery 与 arq 的模型差异,讲清 broker、worker、结果后端与可见性超时的机制;再用 tenacity 9.2.1 实测指数退避重试,并用纯 asyncio 加 fakeredis 2.39.0 手写一个最小可靠队列,演示 RPOPLPUSH 取任务、失败重试与死信投递的完整链路。
本节把缓存拆成三个可决策的问题:本地缓存与分布式缓存怎么分工,Cache-Aside 与 Write-Through 各自适合什么写场景,以及键命名、TTL 与淘汰策略如何一起设计。再用 fakeredis 2.39.0 实测穿透、击穿、雪崩三类故障的工程对策,并给出基于 SET NX EX 与 WATCH 的分布式锁实现。
本节收尾 TaskAPI 的错误体系。讲清 errors.Is 判根因、errors.As 取回结构化错误类型的区别与用法,实现带字段的 ValidationError 与自定义 Is 方法,并给出哨兵错误、包装、判别三者协作的完整分层方案。
错误需要上下文,也需要保留原始原因。本节给 TaskAPI 的错误加上「操作 + ID」上下文,讲清 %w 与 %v 的差别、错误链与 Unwrap、多层包装的可读性、以及 errors.Join 与多个 %w 的用法,让错误既能读懂又能判别。
错误是 Go 里最普通的值。本节为 TaskAPI 定义 ErrNotFound 与 ErrInvalidTitle 两个哨兵错误,讲清 error 接口的极简设计、errors.New 与 fmt.Errorf 的差别、哨兵错误的判等语义、以及为什么错误要显式返回而不是抛出异常。
ReAct 与 Plan-and-Solve 都是「一次跑到底」,失败了不会回头。本节给循环外面再套一层 Reflexion:执行后由 evaluator 判定成败,失败就生成一段反思文本写回上下文,带着反思重跑,最多 N 轮。我们用 FakeModel 脚本化「第一次算错 → 反思 → 第二次算对」并真跑打印两轮轨迹,最后给何时值得 Reflexion 的决策清单。
ReAct 边想边做,Plan-and-Solve 则先谋后动。本节把循环拆成 Planner 与 Executor 两段:Planner 用结构化输出(JSON 数组)一次性产出子任务列表,Executor 顺序执行每一步且每步内部仍是一个完整小循环。我们用 FakeModel 演示一个三步计划,打印每步状态,并给出与 ReAct 的取舍表。
本节把已有工具循环的可见文本、动作和结果分成 thought/action/observation。它不提取隐藏推理,也不要求供应商输出完整思维过程。天气数据为固定教学值,FakeModel 决定两次查询和最终回答。增加 thought 日志不自动提高模型准确率;是否改善任务效果需要独立评测。