附录 B 自测答案与解析

第1章

1-1. (B)具有完成标准,因为任何人都可以确认:关闭通知之后,第二天是否还会收到邮件,以及刷新页面后,关闭的状态是否仍然保留。(A)中的“更好用”没有可以确认的方法。可以将它改成能够观察到的结果,例如:“每类通知都有一个开启或关闭的开关,修改之后不需要点击保存按钮就会立即生效,而且刷新页面后仍然保留。”

1-2. 四种状态是:空状态(没有预约记录时,显示说明文字与前往预约的按钮)、加载中(显示加载提示,而且按钮无法点击)、失败(显示带有重试按钮的错误提示)、无权限(先跳转到登录界面,登录后再返回记录界面)。只要为每种状态写出可以观察的结果,就符合答题要求。

1-3. 示例:①顾客提交咨询表单后,显示“已受理”,管理员列表中增加一条记录。②管理员打开咨询,将它改为“已查看”后,列表中的标记随之改变。③受理后,向顾客发送一封通知邮件(测试中通过发送记录确认)。只要每项任务都能产出用户可以使用的结果即可。如果按表、API、界面的顺序划分,就是按层切分,需要重新划分。

1-4. 使用Ctrl+G在文本编辑器中打开计划,直接修改后再继续执行。不需要计划就能直接交付的任务,例如增加一行调试日志,属于能够用一句话概括diff的工作。

1-5. ③无法对应任何需求,而且涉及整个应用,是超出范围的整理工作(问题1、2、5)。另外,计划中还缺少验证步骤(问题4)。反馈时,应同时说明步骤编号与理由,例如:“删除第3步。在第4步之前,加入编写确认申请已保存的测试、执行npm test,以及截取界面的步骤。”

1-6. 当前或上级目录只要存在CLAUDE.md、.claude/CLAUDE.md、CLAUDE.local.md之一,Claude Code默认就读取它而非AGENTS.md。CLAUDE.local.md也包含在内,因此该成员会话遗漏了团队规则。可在根目录添加通过@AGENTS.md导入的CLAUDE.md,或让该成员把个人设置改为同时读取两文件的值(claude-md-and-agents-md)。

1-7. Codex在~/.codex/config.toml的project_doc_fallback_filenames中加入TEAM_GUIDE.md,每个目录按AGENTS.override.md、AGENTS.md后再查该名称。Gemini CLI在settings.json的context.fileName中指定TEAM_GUIDE.md(可为一个名称或列表)。

第2章

2-1. 这表示5173端口已经被另一个进程使用。常见情况是,之前启动的开发服务器仍在运行。可以使用lsof -i :5173确认PID,再用kill <PID>只结束这个进程,或者改用其他端口启动。应避免根据名称模式一次性关闭多个进程,因为这样可能关闭无关的程序。重新安装依赖通常没有作用。

2-2. 一项测试都没有执行,就意味着什么都没有确认。“没有失败”与“已经验证”是两回事。应首先怀疑测试文件的位置、命名规则或测试配置出现问题,或者因为筛选条件而没有选中任何测试,并确认实际执行的测试数量。

2-3. 在控制台中,查看点击时是否出现JavaScript错误;在网络标签页中,查看请求是否已经发出,以及返回什么状态码。如果控制台有错误,或者完全没有请求,就检查界面代码;如果是400段状态码,就检查发送的内容或权限;如果是500段状态码,则属于服务器侧问题,应查看服务器输出与日志。

2-4. src/checkout/summary.ts第47行。调用栈中属于本项目代码的最上面一行,就是实际出错位置,OrderPanel是调用该函数的地方,node_modules是库。读取了null对象的price,应检查订单项为何可能为null。

2-5. 应确认退出码。命令执行之后,立即运行echo $?,结果为0就表示成功。警告并不等于失败,没有错误文字也不等于成功。CI同样根据退出码来判断成功或失败。

2-6. 暂时将修复的代码还原,或者重新引入那个bug,再运行这项测试,查看它是否失败。如果失败,说明测试能够捕捉这个bug;如果仍然通过,说明这项测试与该bug无关。确认之后,要将代码恢复原样。

2-7. Linux区分文件名的大小写,macOS默认的APFS格式则不区分。在Mac上,./components/header可以找到Header.tsx,但在Linux上就找不到。应按照实际文件名称,将import路径修改为./components/Header。

第3章

3-1. git diff比较工作区与暂存区,显示尚未暂存的变更;git diff --staged比较暂存区与最后一次提交,显示将包含在下一次提交中的变更;git diff HEAD则比较工作区与最后一次提交。要一次查看前面两类变更,应使用git diff HEAD。尚未跟踪的新文件,不会出现在上述任何一种比较中。

3-2. 新文件还处于Git尚未跟踪的状态,因此不会出现在git diff中。先在git status中确认它是否标为??,再用git add将它暂存,之后使用git diff --staged查看内容。

3-3. 使用git diff -w忽略空白差异,剩下的就是真正的变更。提交应将功能变更与格式变更分开。通过git add -p只选择功能变更块,先完成提交;格式变更则另外提交,或者回退。

3-4. 通过-m指定作为基准的父提交编号(通常是main一侧的1)。因为合并提交存在两个或更多父提交,必须明确以哪一方为基准来撤销。Git文档警告,撤销合并就相当于声明,将来也不需要此次合并带来的变更。因此,以后即使重新合并同一个分支,已经合入过的提交所包含的变更,也不会再次进入。

3-5. 应使用git stash apply。apply在应用变更之后,会将它继续保留在stash列表中,因此还可以在其他分支上再次应用。pop则会在应用成功后,将它从列表中删除。全部使用完之后,再通过git stash drop清理。

3-6. 使用git reset --keep HEAD~2,在丢弃提交的同时,保留尚未提交的修改。如果某个文件在当前HEAD与目标位置之间内容不同,而且这个文件中还有尚未提交的修改,命令就不会覆盖它,而是中止reset。

3-7. 应返回125。根据Git文档,退出码125表示当前提交无法测试,因此跳过这个提交。0表示正常,1~127中除了125以外的值表示异常,而其他范围的值则会中止bisect。

第4章

4-1. 不会执行。Claude Code按照deny → ask → allow的顺序评估规则,并由第一个匹配的规则决定结果。只要存在匹配的deny规则,即使有范围更宽的allow规则也会被拦截,而且无法用allow为deny建立例外。

4-2. 不会。官方文档明确指出,.claudeignore没有任何效果,应将其中的内容改写为Read(./secrets/**)之类的Read deny规则。如果还需要阻止在shell中运行的其他程序读取这些文件,就要同时设置沙箱的禁止读取规则。

4-3. NEXT_PUBLIC_变量的值,会在next build时嵌入发送到浏览器的代码,并固定下来。另外,Vercel中的环境变量修改,也只会在新部署中生效。必须重新构建并创建新部署,才能看到新的值。

4-4. 这种说法不正确。Claude Code沙箱的默认设置,会将写入限制在工作目录与临时目录,将网络限制在允许列表内,但读取权限仍然覆盖电脑上的大部分位置,包括~/.ssh和云服务凭据文件。应通过沙箱的禁止读取设置拦截敏感路径,并用Read deny规则限制智能体自身的文件工具。

4-5. 用户账户级的推送保护默认开启,如果向公开仓库推送的内容中包含机密值,就会拦截。仓库级的推送保护则默认关闭,需要管理员开启,并且需要GitHub Secret Protection。

4-6. 不会过滤。根据npm文档,--audit-level规定的不是报告内容的过滤条件,而是在存在什么严重程度及以上的漏洞时,命令应以非0退出码结束。如果存在high及以上级别的漏洞,CI就会失败。

4-7. 示例:(A)修改错字时,只允许编辑工作目录内的文档,禁止访问目录之外的位置及网络;这些文档编辑操作可以自动批准。(B)进行调查时,使用只读权限(plan mode或read-only),网络只允许访问软件包注册表与官方文档,并禁止安装软件包。(C)修复bug时,允许写入工作目录和执行测试命令,禁止访问目录之外的位置及不必要的网络;添加依赖与推送则需要人工批准。只要能根据每项任务开放最低限度的必要权限,并说明这样设置的理由,就符合答题要求。

第5章

5-1. 这是生产部署。Vercel对于新项目的首次部署,无论从哪个分支执行,即使不带--prod,也始终创建生产部署。此后,生产分支上的提交或vercel --prod会生成生产部署,其他分支、PR,以及不带--prod的vercel则会生成预览部署。

5-2. 应分享分支URL,因为它始终指向该分支的最新部署。提交URL则固定在某个特定提交的部署上,适合比较两个时点,或者记录“这个版本发生了问题”。

5-3. 不会应用。回滚后的部署仍然按照它当时的设置运行,而环境变量的修改只会在新的部署中生效。创建一个新的部署并提升之后,新值就会生效,同时也会解除回滚状态。

5-4. Hobby套餐只能回到紧邻的上一次部署。Pro与Enterprise套餐则可以回滚到任何曾经绑定过生产域名的部署。从来没有绑定过生产域名的预览部署,在任何套餐中都不属于可选对象。

5-5. vercel logs默认显示最近30分钟内的最新100条记录。可以通过--since 3h等选项扩大查询范围。如果仍然看不到,可能已经超过当前套餐的日志保留期限。

5-6. 在Production环境的Branch Tracking中,关闭Auto-assign Custom Production Domains。之后从生产分支创建部署时,部署不会绑定生产域名,而是等待提升。先在生成的部署URL上检查,确认后再提升。提升时不会重新构建,只会改变域名的指向。需要注意,这次部署使用的是生产环境变量,因此实际访问的也是生产数据。

5-7. 示例(插花课程预约应用):①测试、类型检查、构建全部通过;②在预览中亲自确认课程报名与取消报名的流程;③新使用的短信发送密钥已经加入Production;④学员表的结构没有变化(如果有,则确认与旧代码兼容);⑤支付webhook指向生产地址与生产密钥;⑥确认上一个正常部署与回滚方法。只要每一行都包含实际功能名称,并且能够判断确认结果为真或假,就符合答题要求。