参考思路
这一页配研讨题的二十九道题,每题两句:一句要点(这段讨论要落在哪),一句追问(把你拉回具体路径)。思路只是方向,不是标准答案——给出别的做法但能说清代价,同样成立。
1怎么用这一页
本页的用法决定其价值:先讨论,后对照。
- 先讨论,再看这一页。先看则失去分歧,而讨论的价值恰恰在分歧上——两种做法都说得通时,才需要判据。
- 要点看落点,追问看自己。要点说明这段讨论应收束在何处;追问需结合自己仓库的具体路径作答,无法作答说明尚未落实到实现。
- 能说出代价就算对。与这一页不同的做法,只要讲得清代价与触发条件,就是有效的结论;无法说明代价的「都行」不构成结论。
2仓库与协作(四题)
- 密钥进了历史:轮换密钥还是重写历史?轮换密钥才是补救——重写历史只是让仓库里检索不到,拿到过的人不会因为历史被重写而未获取过;忽略规则必须补齐,否则同类问题会再次发生。
追问:重写历史之后,如何证明该密钥未被他人获取?
- 共用一个主干,还是每人一条长期分支?判据是「合并时能不能一次对齐」:分支存活越久,与主干差距越大,合并代价越高;四人规模、改动小步,主干加短生命周期的变更分支总成本更低。
追问:你们的分支最长存活几天?超过这个天数会发生什么?
- 变更名用日期还是能力名?日期前缀利于按时间回溯,能力短名利于按主题检索;两者并用(日期前缀 + 能力短名)代价只是命名更长,两条检索路径均得以保留。
追问:半年后要找「那次改分层的改动」,你会先按什么搜?
- 配置样例是否应填写示例值?填写示例值会诱导成员直接改为明文值提交——该文件已纳入版本控制,稍作修改即可使用,是成本最低的一步;仅写键名的代价由 README 弥补(找谁要、从哪个环境取)。
追问:若样例中填入明文值,谁会在什么阶段发现?
3规约与边界(四题)
- 「用户能提交作业」算不算可判定的需求?「能」没有判定条件;改为带前置条件与可观测结果的表述才可判定——「重复提交只产生一份」「截止后提交被拒并给出明确提示」。
追问:验收时需执行哪个操作,才能判定其已满足?
- 「系统处理成功」为什么不算可观测结果?该表述属系统内部视角,验收者无法观测;应改为当场可见的现象——页面出现提交时间与回执编号、再次进入看到同一份作答。只能从日志看到的不算。
追问:不查看日志,如何确认其已成功?
- 失败路径需覆盖几条?判据是「会不会改变对外行为与用户看到的结果」:权限不足、参数缺项、并发重复提交属于业务语义,必须写;超时与网络重试由统一的重试与超时策略(retry / timeout policy)处理,不必逐条进规约。
追问:该条若不写入规约,实现者会如何处理?两种处理对用户的表现是否一致?
- 为什么「另起一次会话只给出仓库路径与变更名就能照做」能验出规约够不够用?该办法排除了开发者头脑中的上下文。无法做到时通常缺失两类信息——判定条件(什么时候算完成)与任务切分(先做什么后做什么),背景反而不常缺。
追问:无法做到时,你会向谁询问?得到的答案应补入哪一份文件?
4规范与 Harness(五题)
- 「接口必须校验入参」与「给新模块补一套测试」分别写在哪?判据是「每次改代码都要读到」还是「按场景才会用到」:前者常驻,写成规则;后者按需,写成技能。
追问:若写反(校验写成技能、补测试写成规则),会发生什么?
- 规范太细与太松各自的后果?太细(规定函数行数、后缀怎么拼)会使约束退化为格式审查,生成产物为迁就规则而变形;太松(「代码要清晰」)等于没写,不同成员会写出不同实现。判据:若不写就会出现不同实现,才值得写入。
追问:该条规范删除之后,是否会出现不同的实现?
- 规则文件放仓库,还是各人本机?入库并随仓库分发;本机配置仅引用仓库中的那一份。各人本地各存一份必然产生漂移,规范升级时也无法同时切换。
追问:规范升级之后,如何确认四名成员均已加载最新版本?
- 如何验证规范确实生效?比「修改一次代码检查产物」更强的验证手段是:故意实现一个违反规范的用例(例如在接口层直接访问数据访问层),让 Harness 生成或审查,检验是否被指出或拦截,并将结果记入验证记录。
追问:被拦截与未被拦截,分别说明规范的什么问题?
- 规范与规约冲突时先改哪个?先修订规约(设计与需求条目)再继续实现——规范是常驻约束,迁就一次就会留下例外;改动须记入变更说明:哪一条被修改、修改原因、影响哪些任务。
追问:若本次按两层实现,下一课谁会遇到该例外?
5骨架与分层(四题)
- 骨架是否应包含认证与授权?判据是「后续课次都要用」还是「这次就要用」:骨架放机制(授权判定的位置与统一入口),不放策略(谁能访问哪份作业的具体规则),后者留给当次变更。
追问:放入骨架的这部分,下一课是否会被改写?若会改写,即说明放置位置有误。
- 健康检查端点为何免认证?返回哪些算泄露?该端点服务于部署与健康探测,须支持免认证访问;合适的是状态码、服务名、版本,泄露的是依赖地址、配置名、内部拓扑。判据:这条信息会不会帮到外部攻击者。
追问:将该字段返回给外部,能帮助攻击者做什么?
- 哪些东西看似配置、其实该跟代码走?判据是「随环境变」还是「随版本变」:数据库地址与密钥随环境变化,应外置;提示词模板、评分细则、错误码表随版本变化,应入库。
追问:执行一次回滚,该内容是否会随之回到旧版本?若不会,即说明它属于代码。
- 骨架为什么要打标签?标签是可回退的基线——回滚、对比、说明某次改动的来源;未打标签则只能依赖提交号,在说明「我们从哪一步开始」时无法指明。
追问:下一课要说明「本次改了什么」,以什么为起点?
6协作节奏与取舍(四题)
- 三人改同一文件:靠合并还是靠切分?Harness 生成的改动面较大,事后冲突合并数量多且难以判定取舍;事前按层、按文件切分任务,使生成范围互不重叠,成本更低。判据:冲突消解的代价与任务切分的沟通代价,何者更高。
追问:这次冲突里,你能直接判定该保留哪一边吗?
- 一次性生成整套业务,还是每次仅执行一组任务?整套生成出错时,无法判定是骨架、依赖还是业务逻辑中哪一处出错,故障定位需全量阅读代码;每次一组可将错误范围限制在本组,且上一组是已验证的。代价是轮次增加,但每轮的验证结果是可复用的资产。
追问:无法启动时,第一步会阅读哪个文件?
- 代码评审看什么?人工评审关注规约覆盖与业务判定(场景是否真正满足、授权判定是否正确);Harness 审查关注规范一致性(分层、命名、重复代码);代码风格交由规范与格式化工具,不占用人工评审时间。
追问:该条交由 Harness 审查,它能否识别?若不能,则必须由人审。
- 实现过程中发现规约存在错误:先按原规约实现,还是先修订规约?先修订规约再继续实现——按错误规约实现的代码需要返工;变更留痕须写清哪一条被修改、原表述与新表述、影响哪些任务,并同步更新任务清单。顺序相反则会留下「代码与规约不一致」的提交历史。
追问:按错误规约实现完成后,后续由谁发现?发现的代价有多大?
7规范取舍(八题)
- 术语表该写进产品设计规范,还是写进规约?不影响对外契约的界面用词归规范,进入字段与接口的概念归规约;两者交叉的部分以规约为准,规范只引用。判据:改这个词会不会改动请求或响应的字段。
追问:同一个概念在界面叫「资料」、接口叫「文档」,谁最先发现?
- 错误码集中登记,还是各模块自管?集中登记可统一遍历、查重与向外发布清单;判据是「调用方是否需要按模块分支处理」——需要分支即说明聚错了位置。
追问:新增一个错误码,你要走几步才完成登记,第二步容易漏在哪?
- 为什么「跨班一律 404」而不是 403?403 把「不存在」与「无权访问」区分开,等于泄露资源是否真实存在;本项目按班隔离,泄露的是资源的存在性与归属。判据:两个响应能否被区分。
追问:改成 403 之后,攻击者能多用这条信息做什么?
- 覆盖率门槛按代码行数,还是按失败路径数?按行数可在无关的取值方法上凑数,且覆盖率数值越高越容易忽略未覆盖的分支;按失败路径则以规约为分母,可直接对照。判据:删掉某条断言,套件还绿吗?
追问:给你的仓库删掉一条最关键的断言,多久会被发现?
- 回滚能力该什么时候演练?发布之前;未演练过的回滚在故障时同样不可用,且此时再验证要付出停机代价。判据:上一次回滚演练的耗时是否记录在发布记录里。
追问:真要回滚时,谁按哪一行的命令执行,命令写在哪?
- 提示词该放进配置,还是随版本入库?随版本变的东西属于代码:模板入库带版本号与评测结论,改模板走变更流程;判据是它会随环境变化还是随发布变化。
追问:线上跑的这份模板,能在仓库里按版本号找到吗?
- 删除一条数据要删几处?至少五处:业务库记录、向量库切片、对象存储文件、缓存、备份介质;副本清单是文档而不是记忆。判据:执行一次删除演练,逐项核对。
追问:你们项目里这份清单由谁维护,删漏了在哪一步才会被发现?
- 完成定义写在哪,由谁判定?写在根目录说明文件或规则里,每次会话都能读到;会话里的口头共识在换一次会话后即失效。判据:换一个成员来判定,结论是否一致。
追问:口头共识在下次会话里还剩什么?