《Go 语言编程实战》11.2 契约测试与 mock
解决「依赖别人的服务怎么测」:先用 testify/mock 把 TaskHub 的通知服务抽象成接口做行为验证,再写消费者驱动的契约测试,用 httptest 起提供方真实 handler、校验消费者依赖的字段集合,并用一个改名案例演示契约漂移如何被自动抓到,最后给出 mock 与真实依赖的取舍清单。
tag
解决「依赖别人的服务怎么测」:先用 testify/mock 把 TaskHub 的通知服务抽象成接口做行为验证,再写消费者驱动的契约测试,用 httptest 起提供方真实 handler、校验消费者依赖的字段集合,并用一个改名案例演示契约漂移如何被自动抓到,最后给出 mock 与真实依赖的取舍清单。
给 TaskHub 搭起分层测试:先划清单元、集成、端到端三层的边界与比例,再用 Testcontainers 在测试里拉起真实的 postgres:17-alpine,用 pgx 建表并跑通一次插入查询;同时给出本机 colima 环境下必须设置 DOCKER_HOST 与 socket override 的真实排错过程,以及用 TestMain 共享容器降本的做法。
前面两节都说「用 -race 验证」,本节把 -race 当成正式工具讲透:它是编译期插桩而非采样,能给出带行号的读写双方栈;逐行解读一份真实竞态报告,实测它带来的性能开销,说明它查不出哪些问题、该怎么写并发测试,以及如何固定进 CI 流程。
上一节用锁保护了 store,但「谁等谁结束」「配置只加载一次」「只增不减的缓存」还缺趁手工具。本节讲透 WaitGroup 的 Add/Wait 时序与 Go 1.25 新增的 wg.Go、Once 与 OnceValue 的差别,并用实测数据回答 sync.Map 到底该不该用。
第 10 章的 worker pool 已经在并发读写同一份数据,但 store 还是裸 map,一压就 fatal error。本节讲清数据竞态,用 sync.Mutex 与 RWMutex 把 MemStore 改成并发安全,再用 atomic 计数器统计处理量,并给出四种同步手段的选型表。
《Go 语言运行时原理》全书目录与学习路线。本卷 10 章 29 节,全部采用实验驱动写法:每节给出可复现实验与实测数字、源码定位(文件与函数)、以及可落地的调优决策表。覆盖调度器、内存分配、GC、编译器四大子系统,适合想从「会用」走向「知其所以然」的 Go 开发者。
全书收口:用同一程序在 go1.26 与 go1.27 上对照运行时行为,看哪些指标稳定、哪些结构变了,实测普通负载差异约百分之一、GC 轮数一致;再给出一份可带走的决策清单,覆盖调度、内存、GC、编译器四大子系统的调优判断与版本升级检查项。
把前九章的工具串成一次完整调优:一个每请求 20 次分配、914 字节的处理函数,从基准与 pprof 定位到 reflect 与字符串转换两个热点,改写成零分配版本后快约十八倍;并用 GOGC 扫描做对照,证明只调参数只能拿回约百分之五的收益。
《Go 语言运行时原理》共 10 章 29 节,全卷实验驱动:每节固定三段式——可复现实验(命令与本机实测数字)、源码定位(文件与函数)、调优决策(决策表或清单)。覆盖调度器、内存分配、GC、编译器四大子系统,以及一次端到端调优实战。
MCP 多语言 SDK 生态全景:Python/Go/Rust 官方与社区 SDK 的对比选型、类型系统与异步模型、自定义 SDK 的传输层与协议层实现、框架绑定(LangChain/LlamaIndex),帮你选对语言落地 MCP。
Go 日志与可观测性工程实践:从标准库 log 到 slog 结构化日志、Handler 自定义、日志级别与上下文关联、OpenTelemetry Trace 集成、Metrics 指标与运行时监控、以及生产日志体系与告警的设计原则。
Go 测试与基准工程实践:表驱动测试、子测试与辅助函数、Mock 与测试替身、Fuzz 模糊测试、基准测试与 pprof 分析、覆盖率与 CI 集成,构建从单元到性能的质量闭环。
卷二 9.3 讲过 goleak 的工程用法,本节讲检测原理与测试生命周期:它用 runtime.Stack(all=true) 抓全量栈、靠 20 次指数退避重试容忍短命 goroutine、用四类默认过滤器排除系统栈,以及 VerifyNone 与 VerifyTestMain 的取舍和 CI 集成方式。
把结构化并发当模型来讨论:子任务生命周期受父约束的三条契约、取消传播的三个层次、生命周期所有权与「何时不该结构化」的判断标准,并用 goleak 实测非结构化 scatter 泄漏两个 goroutine、无主后台循环泄漏一个,结构化版本零泄漏,最后给出落地检查清单。
卷二 9 章讲过 errgroup 的工程用法,本节只讲模型与语义:WithContext 的取消契约、context.Cause 如何保留首个错误、Wait 的返回语义、SetLimit 的阻塞背压,以及 semaphore.Weighted 的加权配额、TryAcquire 与 FIFO 公平性的本机实测。
Go 错误处理工程实践深度:error 接口与哨兵错误、fmt.Errorf 与 %w 包装链、errors.Is/As/Unwrap 的判定与提取、自定义错误类型、错误码体系与领域错误设计,以及生产环境日志告警中的错误纪律。
Go 垃圾回收与内存调优深度实战:并发三色标记 GC 原理、逃逸分析与栈上分配、sync.Pool 内存池、GOGC 与 GOMEMLIMIT 调参策略、降低 GC 压力的七种手段与基于 pprof 的验证闭环。
从零实现一个 Terraform Provider:插件协议与 gRPC 通信原理、Schema 定义与 CRUD 生命周期、资源与数据源的实现、导入与状态升级,以及基于 TF_ACC 的验收测试与发布版本管理。
Go 网络编程深度实战:TCP 与 UDP 服务端客户端、Socket 抽象、自定义二进制与文本协议、以及 Go runtime 基于 epoll/kqueue 的事件驱动 IO 模型与生产级网络服务的避坑指南。
给 TaskHub 装上 OpenTelemetry 链路追踪:用 Tracer 建父子 span、标注属性与错误状态,用 stdouttrace 在本地把 span 打出来,用 W3C traceparent 把 trace 跨服务串起来,再把 trace_id 写进 slog,最后讲清采样策略与优雅关闭,并说明本机没有 collector 故 OTLP 导出未实测。