READ · UNDERSTAND · TRANSFER
阅读理解,按需巩固
先沿着原理、问答和迁移案例阅读。需要检查理解时,再切换巩固练习或展开个人记录。
核心知识 · 连接重建与持久任务状态
先理解核心原理
先备概念:幂等提交、事件游标、持久状态机
连接承载进度通知,任务状态由后端持久化。重连只恢复观察位置,重复提交、取消和业务完成都需要独立的明确语义。
浏览器不是任务所有者进程
关闭页面可能因刷新、网络或用户离开,不能据此断言用户要取消。提交先创建稳定任务并返回 run_id;客户端保存提交键,网络重发沿同一键取回任务。任务在后端运行,连接只显示其状态。
游标恢复的是通知
事件 ID 帮助服务器定位断开位置,但必须实际保留可重放事件,客户端去重应用。SSE 的 Last-Event-ID 不是完整任务恢复机制,更不保证业务完成只发生一次。事件过期时返回快照与新的起点,防止客户端无限请求已不存在的历史。
终态可独立读取
完成事件丢了,客户端还应能查询权威任务状态和产物。持续连接正常却任务失败也可能发生,因此 UI 的“完成”绑定业务终态而非流结束。取消走独立鉴权接口,已提交外部效果仍需核对。这里采用通用应用设计;MCP 恢复机制按其协议范围解释,不当作所有网页必需规则。
回到问题:怎样回答?
任务运行独立于浏览器连接,提交返回稳定 run_id,并用幂等提交键防止重复创建。进度写入可恢复事件流,客户端记录最后序号,重连后补齐事件或读取状态快照。流断开不等于任务失败,页面显示完成需要业务终态和产物验收。取消必须是明确接口,不能仅靠关闭 SSE 或 WebSocket。
实现与取舍
提交与订阅分离
POST 创建任务时校验身份、任务参数与客户端幂等键,相同逻辑提交返回同一运行,参数不同却复用键应拒绝。随后订阅 run_id 的事件。用户刷新只重新读取运行状态并订阅,不重新创建任务。访问任务和事件时都核对用户权限,不能凭猜到 ID 就读取别人的日志。
事件必须可以解释
事件包含 run_id、递增序号、类型、时间和必要数据,区分阶段进展、工具完成、等待审批和终态。UI 可展示面向用户的阶段摘要,不需要暴露模型隐藏推理或敏感工具原文。写事件和任务状态的先后要一致或可对账,避免事件说完成但产物尚未提交。
重连、重复与缺口
客户端从 last_seq 后恢复并去重。事件保留期已过时返回可检测的缺口,客户端重新读取带水位的完整状态快照,再从水位继续。慢客户端使用有界缓冲,不能无限占内存。传输重连仅恢复观察,不应触发业务步骤重新执行。
取消与结束
关闭页面默认只关闭观察连接,明确取消请求由服务端处理并传播。对已提交外部动作核验结果,终态可包含部分完成或待核对。测试断线、刷新、重复事件、快照与事件竞争、跨用户订阅和结束事件丢失,确认用户最终看到的状态与服务器事实一致。
代码示例
客户端发现重复事件和序号缺口
仅演示本地事件状态机,不包含身份校验、服务器持久化或真实网络传输。
last_seq = 0
for seq in [1, 2, 2, 4]:
if seq <= last_seq:
print("duplicate", seq)
continue
if seq != last_seq + 1:
print("resync after", last_seq)
break
print("apply", seq)
last_seq = seq
预期输出
apply 1
apply 2
duplicate 2
resync after 2工程推演
- 场景
- 面试假设:手机切到后台导致连接断开,重新打开页面。
- 设计决策
- 复用 run_id,从事件水位恢复,不重新提交生成任务。
- 验证目标
- 进度连续且无重复任务,终态来自服务器。
- 适用边界
- 事件保留期以外通过快照恢复,不承诺无限回放。
连续追问与解答
沿着问题的前提和约束继续向下读。先理解参考解答,再尝试收起答案,用自己的话解释因果和取舍。
第 1 层最后一个完成事件丢了怎么办?
任务与流分离之后,要能修复终态通知丢失。
参考解答
重连后补齐保留事件,或查询权威任务快照与产物校验状态。若后台已完成,返回完成版本;若流过期,明确告诉客户端从快照继续。不能因为没收到最后事件就重新提交,也不能把 SSE 关闭当成功。
沿着这个回答继续深入
第 2 层完成事件已过保留期,任务产物也清理了,页面怎样表达?
父问通过快照补齐通知,子问增加保留期超过后的证据范围。
参考解答
返回任务终态及明确的产物已过期信息;若终态也不再保留,表示无法查询而非编造完成内容。记录保留政策,提供重新发起新任务的明确操作,不把游标过期静默转换成重做旧任务。
沿着这个回答继续深入
第 3 层用户点击重做,能继续使用原提交幂等键吗?
父问允许重新发起,继续澄清新任务与网络重试的身份区别。
参考解答
不应混淆“重发旧请求”和“创建新任务”。明确重做生成新提交键,记录与旧 run_id 的关联,并重新验证授权和外部写风险;旧键仍指向旧任务。用户能理解将产生新工作,防止刷新意外重复。
第 1 层慢客户端积压日志如何处理?
进度持久化也需要资源与保留边界。
参考解答
设有界缓冲、事件保留与快照压缩,优先保留关键状态和错误,非关键逐 token 日志可合并。积压超限可断开并要求快照恢复,任务执行不被无限缓冲拖死;事件不能静默丢失后仍声称无缝恢复。
第 1 层关闭页面应该自动取消吗?
用户连接状态不能自动表达业务取消意图。
参考解答
取决于明确产品语义,默认应区分断开与取消。可让交互式临时会话有显式断开取消策略,持久任务则继续并允许用户返回。取消请求要鉴权、幂等且记录阶段;外部效果已发生时说明取消只能阻止后续动作。
举一反三:条件变了,怎样推导?
先找出改变的条件,再判断原方案中哪些前提仍成立。下面的案例是教学推演,便于将原理迁移到新问题。
移动网络频繁切换
改变的条件:连接反复断开,但任务持续运行。
延伸问题:如何避免多次创建?
推导与参考解答
客户端保存同一提交键和 run_id,服务端原子去重提交;重连仅带事件游标查询允许任务。若客户端丢失键,先通过账号任务列表找回,不以同一自然语言内容猜测任务身份。
保持不变的原理:重复观察不创建新业务任务。
高频 token 流与低频业务状态
改变的条件:通知量很大,关键状态需要长期保存。
延伸问题:所有 token 都永久存储吗?
推导与参考解答
按用途分开临时呈现与持久业务事件,关键状态和产物可读回,token 按明确保留策略处理。客户端遇缺口切快照;不能把完整 token 回放作为恢复业务的唯一依据,权限与资源限制仍独立执行。
保持不变的原理:权威任务状态独立于显示层通知粒度。
易错点
- 刷新直接再提交
- 流结束就显示成功
- 任务 ID 当成授权凭证
参考资料
依据公开技术资料设计;参考资料支持技术机制,场景与评分标准为本站设计,不代表某公司面试原题。 新增问答与迁移案例用于原理讲解,来源核查与案例运行验证分别记录。
检查自己理解到哪一步
读完后可以对照这些标准解释原理、边界和取舍。掌握程度由你自评;需要进一步验证时,再完成下方小任务。
- 基础达标
- 能把创建任务与订阅进度拆开,刷新页面只重新观察任务。
- 中高级信号
- 有事件序号、去重、幂等提交和权限校验。
- 资深信号
- 考虑快照水位、慢消费者、保留期及终态一致性。
巩固练习 按需完成 · 建议 15 分钟
设计事件 1、2、2、4 到达时客户端行为,说明序号 3 缺失的恢复。
展开验收要求与检查点
- 重复事件不重复渲染动作
- 缺口被检测而非忽略
- 刷新不创建新任务
重点检查
- 任务生命周期独立于连接
- 有序事件去重与快照恢复
- 取消与断连区分