先修补课:只补项目真正依赖的基础
本课程假定你能写普通Python函数、读JSON、使用Git与命令行,但不假定你已掌握Agent框架。遇到下面问题时按需补,不要求先看完数据库或分布式系统整本教材。
1. Python对象与类型边界
字典是可变对象,赋值不会复制内容;返回原字典会让调用方修改内部状态。C02要求返回新字典,但只做浅拷贝;如果嵌套值也会被修改,需明确深拷贝或不可变结构的契约。不能把“复制了list”误认为里面每个dict也复制了。
Python中bool是int的子类,因此isinstance(True, int)为真。课程金额采用type(value) is int并检查非负;生产API还应由边界Schema与领域校验共同约束。金额存整数最小货币单位,避免二进制浮点的舍入争议;多币种还要显式记录货币和单位。
异常分三类:可预期领域错误,例如NOT_FOUND;暂时环境错误,例如可重试网络失败;程序错误,例如字段名写错。不要把所有Exception都变成“模型再试一次”,这样会掩盖bug并放大成本。向外暴露稳定错误码,内部日志保留脱敏诊断。
2. 异步不是并行万能药
协程在等待I/O时让出执行;CPU密集循环不自动因加上async而变快。并行发工具之前检查数据依赖:需要订单ID才能查物流的两步不能盲目同时运行;两个独立只读查询可以并行,但仍需限流与预算。
任务取消是协作信号。被取消的协程可能需要在finally里关闭连接与清理工件;运行在线程池中的阻塞函数不一定随await取消而立即停止。对子进程需要单独管理进程组、超时与回收;外部服务已收到的请求可能继续执行。
建议阅读Python3.12 asyncio的TaskGroup、timeout和cancellation说明,然后写一个纯本地练习:两个sleep任务与一个失败任务,观察结构化并发如何取消同组任务。明确这不能证明外部支付回滚。S28
3. SQL事务与唯一约束
事务把一组数据库写入一起提交或回滚,但不会自动覆盖任意HTTP请求。课程退款把余额、账本和幂等结果放在同一个SQLite事务中,这是明确的局部原子性。
唯一约束是并发事实判据,不只是性能索引。先SELECT确认不存在,再INSERT,在并发下仍可能有两个线程同时看到不存在;需要数据库唯一键与正确冲突处理。推荐唯一键包含权限域,例如(tenant_id, operation_id),但业务语义决定是否还需要user或订单域。
乐观并发使用version:UPDATE ... WHERE version=expected,检查实际影响行数。悲观锁或BEGIN IMMEDIATE串行化部分写入;二者各有争用与重试代价。SQLite参考为了清晰而牺牲并发细度,不能从小测试推出生产吞吐。
PostgreSQL隔离级别和行锁行为应按实际版本阅读,特别是可重试事务失败与SKIP LOCKED的使用范围;队列消费者可以利用它避免争抢,但它不是通用一致查询语义。S30 S31
4. 网络失败不能直接映射成业务失败
客户端超时可能发生在请求未发出、服务器尚未执行、服务器已执行但响应丢失等不同窗口。调用方只有“没收到响应”这个观测,不能由此推断业务事实。设计操作ID、查询结果与对账状态,就是为了缩小这个知识缺口。
重试需要:错误分类、最大尝试次数、退避/抖动、deadline、幂等契约、总预算。三层各允许三次尝试,最坏下游27次,不是9次。上层重试与SDK内部重试要统一审计。
幂等不是“相同参数一定同一意图”。用户可能两次合法购买相同商品;业务意图ID由请求语义决定。相同意图同参数重试可复用结果,相同key不同参数必须拒绝或明确冲突。S29
5. 单元测试、集成测试与性质测试
单元测试隔离一个小逻辑,适合Schema、金额、RRF、指标公式。集成测试验证组件边界,例如两个数据库连接并发提交。故障注入测试主动在提交前后抛异常,验证不变量。端到端测试检查真实链路,但故障定位更困难。
性质测试描述一类输入上的不变量:重复同意图不增账本;余额不小于零;跨租户缓存键不相同;取消后不新增派发。生成器和随机seed需要记录。发现反例后保留最小例作为固定回归测试;随机测不到不等于形式化证明。
参考测试只证明reference代码在当前测试范围内满足断言。学习者要把相同契约绑定到自己的实现,而不是运行参考测试后宣称自己的代码已通过。把测试改成总是true不是修复。
6. 最小统计与实验习惯
均值、p50和p95回答不同问题。小样本p95很不稳定,nearest-rank与插值定义也可能不同。每个图表写明样本量与计算口径。成功率95%至少需要分母解释:19/20与9500/10000不是同等证据。
比较策略时尽可能用同一批任务、同一模型版本和预算;随机执行顺序以减少时段变化影响。记录失败试次成本,区分任务内重试与独立重复试验。调参集和最终评估集分开;本包公开fixture只作教学,不自称保密测试集。
7. Git与可重复实验
记录基线commit、补丁、依赖锁文件、数据hash、运行命令和环境。不要在实验中途修改测试后把前后数据混在一起。失败优化也保留记录,便于说明为什么回滚。
用代码助手时先写任务契约和验收,再要求其实现。Review时沿信任边界读代码:输入来自哪里、哪个层拥有身份、什么操作有副作用、哪个状态可能因重试重复。比从第一行逐行看到底更容易发现系统性错误。
自查
你能否解释一次超时的三种可能事实?能否写一个两个连接竞争唯一键的测试?能否区分协程取消、子进程退出和外部副作用回滚?能否指出浅拷贝与深拷贝的不同?这些问题卡住时先做相关小练习,再继续主线;不需要等待“所有基础都学完”。