D7 · 两场模拟面试与定向补弱
本日安排:8 小时净学习。休息另计,算法可独立安排。
- 2 小时:后端模拟 60 分钟 + 复盘 60 分钟。
- 2 小时:Agent 模拟 60 分钟 + 复盘 60 分钟。
- 2 小时:只修复低分项。
- 1 小时:两案例开场与故障追问。
- 1 小时:个人错题页与最后检查。
第七天|两场模拟面试与复盘方式
Section titled “第七天|两场模拟面试与复盘方式”今天不再扩充技术名词。目标是把前六天的机制讲成连贯答案:问题是什么、系统状态由谁维护、哪里会并发、失败后如何知道副作用、怎样验证结果。先做模拟再看参考推演;按时停止答题,复盘具体遗漏。每场 60 分钟回答、60 分钟复盘,建议顺序如下。
- 模拟一:后端与可靠执行:0–8 分钟澄清目标和不变量;8–18 分钟索引、MVCC 与锁;18–28 分钟缓存一致性;28–48 分钟退款事务和支付超时并发;48–55 分钟重试、取消、观测;55–60 分钟总结。复盘时用 20 分钟重画状态流、20 分钟写出失败路径、20 分钟重答最差的追问。
- 模拟二:Agent 与售后工作流:0–8 分钟定义能力边界与成功;8–18 分钟工具调用和权限;18–30 分钟 RAG 故障定位;30–48 分钟审批、异步任务和真实状态验证;48–55 分钟评测、trace、成本;55–60 分钟总结。复盘同样只修具体失分点。
时间分配是训练建议,不代表招聘方的固定面试流程。自己练习时最好录音;听回放只标三类问题:结论错误、机制没说清、边界/故障漏掉。一个术语没背出时,可以说出确定知道的机制、标明未知契约以及会如何验证。不要把下面的教学案例说成自己做过的线上系统。
设计题的答题顺序
Section titled “设计题的答题顺序”设计题先用一两句话复述目标和限制,再确认少数会改变方案的假设。接着说明系统的权威状态在哪里,模型、worker、数据库和外部支付各负责什么。然后走一遍正常请求,再拿一个明确故障推演到状态终点。最后说明如何监控、测试及方案的限制。不要从“我会用 Redis/Kafka/多 Agent”开头;工具名不能代替边界和行为。
答题中可以把后端处理和 Agent 流程共同表述为:提出动作→服务端校验→执行→读取权威结果→验证后置条件→更新任务状态。模型只产生建议或工具请求;调用工具的是受控执行器。索引优化影响查询路径,不会自动产生并发正确性;事务、条件更新、唯一约束或行锁负责各自适用范围内的不变量。缓存保存的是可复用数据,不是付款授权或最新事实。RAG 负责找证据,事实是否被找到、是否适用、是否被正确引用要分开检查。
评分采用 0–3 分:0 表示机制或安全边界根本错误;1 表示能背定义但故障一来没有具体行为;2 表示机制、边界和可执行方案成立;3 表示能处理并发与恢复,并讲出代价或适用条件。关键安全项:授权、额度、幂等、未知结果和业务后置状态均不得为 0。满分不是目标;优先消除会造成越权、重复扣款、丢失真实状态的根本错误。
模拟一推演|退款请求超时,同时用户又提交一次
Section titled “模拟一推演|退款请求超时,同时用户又提交一次”**题面:**订单最多可退 100 元。用户申请退款 70 元。服务检查可退额度后向支付通道发起退款,通道 8 秒未返回;同一用户的重复 HTTP 请求也到达。请设计结果和恢复策略。面试官会追问:超时是不是失败?如何防止两次退款?并发事务和通道调用怎么衔接?
先讲不变量,再讲表和状态
Section titled “先讲不变量,再讲表和状态”先说明三个不变量:同一业务退款意图最多产生一次通道副作用;单笔退款不能超过该订单的可退额度;任何“成功”都必须有支付系统或对账结果支持。数据模型可包含 refund_operation(业务退款意图与状态)、额度预留/退款流水、审计事件和 outbox 事件。对 (tenant_id, business_request_id) 或有明确语义的退款意图键建唯一约束;存金额用最小货币单位并固定币种。客户端幂等键、服务端操作 ID 和支付通道支持的幂等键各自范围不同,需在数据库里保存映射,不能临时用新的随机值重试。
本地数据库事务负责本地原子性:验证订单、校验当前版本/可退余额、创建操作记录并预留额度;必要时通过行锁或条件更新防止两个并发请求同时消费同一额度。事务提交后由 worker 调用通道,并使用稳定的通道幂等身份。不要在持有数据库事务和行锁时等待网络。通道确认成功后,worker 在同一个本地事务中减少预留、增加已退款金额、将业务状态改为 SUCCEEDED 并写出后续事件。只有通道给出不会再执行的最终拒绝,才进入 FAILED_FINAL 并释放预留。局部事务不能把本地数据库和第三方支付变成一个原子事务,因此要设计未知状态的恢复。
正常路径与失败路径
Section titled “正常路径与失败路径”正常路径:服务端认证并确定租户→校验退款条件→事务中按订单锁定或原子预留 70 元并创建操作→提交→worker 用相同 operation identity 调用支付通道→获得明确成功结果→写退款流水并完成状态→读取/验证业务后置条件→响应用户“已完成”。第二个并发 HTTP 请求用同一业务请求键命中已有操作,返回同一操作状态,不再创建第二笔退款。若这是用户明确提出的新退款意图,则仍由数据库余额约束决定是否可受理;不能只凭两次请求内容相似就错误合并。
超时路径:客户端未收到结果不等于支付未执行。操作进入 UNKNOWN 或 PENDING_RECONCILIATION;保留额度预留,阻止新的退款把同一余额花掉。后台先查询通道状态,或用同一幂等键按供应商契约安全重试。若查到成功,补写成功状态和账本;若通道确认未执行,才按契约重新发起或释放额度;若通道仍无法确认,保持未知并告知用户正在核实,不能说失败后重新退款。支付 API 对幂等键的保存时间、参数一致性和错误缓存语义是具体供应商约定,必须查文档,不能假定所有通道都永久幂等。5
用户第二次提交若携带相同幂等键,读取原操作 UNKNOWN,展示查询中并关联同一操作;若换了键但业务语义其实相同,单靠请求键无法防止重复,需要订单级剩余额度约束、明确的业务去重策略和操作查询。不能为了“简化”把所有同额退款都合并,因为用户可能合法地分两次部分退款。
常见错误答法与追问
Section titled “常见错误答法与追问”“HTTP 超时就重试一次”漏掉了通道已执行但响应丢失的窗口。“加 Redis 锁就行”没有说明锁失效、暂停 worker 和资源端拒绝旧持有者等问题,也没有保证余额不超额。“数据库事务包住支付调用”既无法原子提交第三方状态,也延长锁持有时间。“MQ exactly-once 保证只退一次”把消息传递保证误当作外部副作用的业务保证。合格回答应区分请求去重、额度约束、通道幂等、状态查询和账务对账。外部系统不支持查询或稳定幂等键时,要直说保证边界,设置人工核对流程,不能承诺恰好一次。
模拟二推演|RAG 答错退款政策,怎样定位?
Section titled “模拟二推演|RAG 答错退款政策,怎样定位?”**题面:**Agent 引用一份旧政策,建议给不符合条件的订单退款;用户看到的回答有引用,但退款尚未执行。面试官追问:错误来自检索还是生成?如何防止文档注入?如果检索明明找到新政策,Agent 仍选旧证据怎么办?
按证据链由前向后诊断
Section titled “按证据链由前向后诊断”先冻结这次 run 的可用材料:用户问题、租户/市场/日期、查询过滤条件、候选文档 ID 和版本、检索分数、重排结果、进入上下文的片段、模型版本和工具调用、最终答复。只看最终文本无法定位。按阶段问:
- **文档是否正确进入索引?**检查原文、文档版本、生效区间、拆分边界和元数据。最新政策若根本没索引,问题在采集/索引,不是模型重排。
- **检索是否召回适用证据?**查看 ACL、市场、时间过滤和查询词;如果新政策未进入候选,调整查询、混合召回或过滤,再用固定查询集回归。若正确文档在候选里但排名靠后,才检查排序器及其特征。
- **上下文是否保留了决定性条件?**如果切块截断了“仅限未发货”或失效日期,属于切块/拼接问题。模型不能可靠恢复未提供的上下文。
- **模型是否正确解释并引用证据?**若上下文中明确给出新旧版本、适用范围,模型仍引用旧政策,则是证据选择或推理失败。加强版本信息和引用验证,并覆盖模型回归测试。
- **回答是否触发业务操作?**本题说退款未执行,因此输出错误仍需修复,但高风险副作用边界尚未被跨越。Agent 不应把引用存在当作授权;执行前规则/服务端必须依据当前政策版本、订单事实、权限和审批记录再次判断。
要用成对案例检验:新政策适用且旧政策过期;新政策不适用但旧政策也过期;文档缺失;不同市场政策相反;检索结果中夹带“忽略审批”的恶意文本。每例记录正确结论、证据 ID/版本、不得执行的动作。评估检索覆盖与排序,也评估最终答案和业务状态;“有引用”不等于引用支持结论。引用校验应比较声明与具体证据,不只检查 URL/文档 ID 存在。
失败处理与安全路径
Section titled “失败处理与安全路径”若没有可确认适用的有效政策,Agent 应明确缺少证据并转人工,不用最相似的旧文件补空白。若政策文本与确定性退款规则冲突,暂停执行,保留证据并升级核对。将检索片段视作不可信数据,不能让文档内容改写系统权限或工具说明。租户与市场过滤由服务端强制执行;模型建议的 tenant_id、URL 或任意 SQL 不作为授权输入。退款的批准应绑定精确提案;政策版本或订单状态在批准后改变,执行前重新核验并在需要时要求再次批准。
错误答法包括“调大 top-k 就好了”(可能给更多冲突片段但不修 ACL/版本问题)、“上更强模型”(不能补回未检索的文件)、“引用格式正确所以有依据”以及“RAG 只负责建议,后端可以照着做”。诊断必须指出偏差首次出现的层,并用固定用例证明修复有效。
最后一轮定向复习
Section titled “最后一轮定向复习”工具调用与权限
Section titled “工具调用与权限”面试时说明模型输出的是结构化调用请求,执行器校验 schema、对象归属、当前状态和权限后才调用工具。Schema 通过不等于业务语义正确。错误参数应拒绝或要求补问,不能让工具拥有任意 URL、SQL 或凭据。批准属于真实身份的确认记录,不是模型返回的布尔字段。
索引与 MVCC
Section titled “索引与 MVCC”先说查询条件、排序和分页,再说明索引列顺序如何匹配过滤与排序、范围条件对后续列利用的影响要用实际执行计划验证。不要断言“有索引一定快”或“范围列后所有列都失效”。InnoDB 普通一致性读和锁定读的语义不同,行为依赖隔离级别、读视图和语句;锁定读用于当前业务写入校验时,要清楚解释锁住哪些记录/间隙及可能的死锁。索引提高访问效率不替代事务不变量。
缓存题先说缓存对象、key、数据新鲜度和失效,再讲并发写读可能导致脏回填。分布式锁是协作机制,持有者暂停过久、租约过期后继续写时需要资源端版本/fencing 等约束;若目标系统不检查令牌,这个保护不成立。Redis 锁、缓存和消息队列不自动替代关系数据库业务约束。
unknown、RAG、审批、评测
Section titled “unknown、RAG、审批、评测”UNKNOWN 表示没有证据判定外部副作用是否发生,不是失败,也不允许当成功。持有预留、查询相同操作、依赖稳定幂等身份、必要时人工对账。RAG 按采集/过滤/召回/排序/上下文/生成/引用验证逐层排查。审批绑定具体参数与版本,执行前重新验证。评测同时覆盖正常完成、正确拒绝和故障;确定性状态用代码检查,开放语言用经人工校准的 rubric。报告 pass@k/pass^k 时写清独立试验假设和采样方式。
支付通道请求超时后,系统目前无法查询到最终结果。应如何处理?
- A. 立刻释放额度并创建新退款
- B. 标记成功,避免用户重复咨询
- C. 保持未知状态和预留,使用原业务身份查询/核对
- D. 将退款操作删除,等待用户重新提交
答案与解析
正确答案:C。超时只说明没有及时收到响应。A/D 可能造成重复退款或额度错误;B 把未知谎报成成功。
同一时刻两个 70 元退款请求都读到可退 100 元。最核心的数据库保障是什么?
- A. 先普通查询可退额,再分别调用支付通道
- B. 在事务中使用适当的锁/条件更新和约束,原子分配额度
- C. 把“余额=100”写在 Agent prompt 里
- D. 延长 HTTP 超时
答案与解析
正确答案:B。并发竞争必须在权威持久层原子处理。A 存在读后写竞争;C 不构成约束;D 只延长等待,不处理竞态。
RAG 回答引用旧政策,最新政策不在检索候选中。第一步最应该检查什么?
- A. 模型温度是否为零
- B. 最新文档是否被正确采集、索引并通过权限/版本过滤
- C. 改成多 Agent 协作
- D. 直接把 top-k 增加十倍
答案与解析
正确答案:B。候选中缺失时应检查 ingestion、索引和过滤。A 不会补出未给模型的文档;C 增加协调复杂度;D 不能保证召回有效文档,可能只引入噪声。
索引的最合理说明是什么?
- A. 有索引就保证查询更快且结果一致
- B. 索引改善特定查询访问路径,应结合列顺序和执行计划验证
- C. 索引替代事务锁
- D. 任何
WHERE条件都会完整使用所有复合索引列
答案与解析
正确答案:B。索引服务于访问路径,实际利用情况要看谓词、排序、统计信息与计划。A 将性能和一致性混为一谈;C 错,索引不替代并发控制;D 忽略复合索引匹配条件。
人审批准了 70 元退款,但执行前订单版本或金额发生变化。应怎样处理?
- A. 继续执行,因为审批记录已经存在
- B. 让模型判断新金额是否“差不多”
- C. 服务端重新核验,已批准内容不再匹配时重新生成提案并审批
- D. 删除所有审批记录
答案与解析
正确答案:C。批准应绑定内容和版本。A 把批准视为无范围授权;B 把业务判断交给模型;D 破坏审计,且未解决权限问题。
某评测夹具缺少退款模拟器,测试根本没有有效运行。该样本应如何计入?
- A. 系统失败
- B. 系统成功
- C. 记作 invalid 并单独报告
- D. 从记录中悄悄删掉
答案与解析
正确答案:C。评测基础设施失效不能归因于被测系统。A/B 错误分类;D 会隐藏评测质量问题并改变分母。
请用口头方式回答“支付通道超时,随后重复请求到达”。要说出状态、正常恢复和禁止做法。
参考答案与评分点
**参考答案:**先用业务请求身份查已有退款操作;若操作已存在就返回它的当前状态。通道调用用稳定的 operation_id/通道幂等键,具体按供应商契约执行。超时后标记 UNKNOWN,保留额度预留并查询通道或对账;确认成功后补写成功账本,确认未执行后才按约定重试或释放额度。禁止把超时当失败新建退款、把受理当成功、或在支付网络调用期间持有数据库事务锁。若支付方无法查询也不支持稳定幂等能力,要说清系统无法保证自动安全重试,转人工核实。
评分(每项 1 分):
- 识别同一请求并返回已存在的业务操作。
- 超时归为 UNKNOWN,保留必要额度预留。
- 以稳定业务身份查询/核对,确认未执行后再决定恢复。
- 说明不依赖本地事务、Redis 锁或 MQ 获得跨系统恰好一次。
对旧政策导致的错误 RAG 建议,给出从数据到业务执行的排查顺序,并说明如何控制副作用。
参考答案与评分点
**参考答案:**固定 run 证据,检查文档版本和生效范围、采集/索引、ACL 与市场日期过滤、召回候选和排序、上下文是否截断、模型引用和最终业务规则。按最早缺失或错误层修复,用成对数据回归验证。将片段视作不可信内容,权限由服务端施加;没有有效依据时补问/转人工。退款执行独立检查当前政策、订单版本、权限和具体审批,引用有效也不等同授权。
评分(每项 1 分):
- 逐阶段检查文档/索引、过滤召回和排序。
- 检查进入上下文的证据及生成引用是否支持结论。
- 使用固定、对照评测验证定位和修复。
- 保留服务端授权、审批、执行前检查与执行后的业务状态验证。
解释复合索引、MVCC 普通读和锁定读在“两个请求同时退款”场景各解决什么问题。
参考答案与评分点
**参考答案:**复合索引按访问谓词和排序设计,减少查找范围并支持执行路径,但不是正确性保证。MVCC 一致性读按隔离级别和 read view 读取版本,适合一致性查询;不能把普通读出的额度直接当作并发写入的原子授权。写入流程需用条件更新、适当锁定读/行锁及约束把检查和额度占用原子化,并考虑锁范围、死锁和重试;跨支付服务仍有独立的未知结果和对账问题。
评分(每项 1 分):
- 索引主要解决访问路径与性能,不保证不变量。
- 区分 MVCC 一致性读与写入校验/锁定读。
- 指出并发额度校验需原子更新、锁或约束。
- 区分数据库事务范围与支付通道副作用。
给商家售后 Agent 列出至少四类评测任务,并说明何种结果由程序判分、何种结果可由模型评分。
参考答案与评分点
**参考答案:**覆盖符合条件的正常提案/经批准退款、不符合条件时正确拒绝、权限越界、政策过期/注入、工具超时或未知、取消与审批后事实变化。程序检查租户、金额、审批绑定、工具调用禁止项、operation 状态、退款账本和后置条件;模型 judge 可按 rubric 判断解释是否清楚、证据陈述是否完整。模型 judge 需和人工样本对照校准;记录不同类型指标、失败轨迹及 invalid 评测。
评分(每项 1 分):
- 至少覆盖正常、拒绝、越权/注入和故障类别。
- 以程序验证退款、权限和审批等客观业务状态。
- 将模型评分限定于开放文本并用人工结果校准。
- 保存可复现的失败轨迹并分层报告指标。
- 5:阅读具体支付方的幂等语义和适用边界。
- 1:评测目标、数据集和人工校准。
- 2:多轮任务、trial 与结果判分。
- MySQL 8.4 InnoDB MVCC 与 locking reads:数据库语义限定于对应版本和语句类型。
Sources
Section titled “Sources”1 https://developers.openai.com/api/docs/guides/evaluation-best-practices — Evaluation best practices | OpenAI API 2 https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents — Demystifying evals for AI agents | Anthropic 5 https://docs.stripe.com/api/idempotent_requests — Idempotent requests | Stripe API
下面保留原报告的题目和口述参考答案。先自行作答,再展开查看。