主题
React + AI 应用开发
AI 应用如何保证幂等、重复提交和消息顺序?
按钮防抖只能减少一类重复,生产系统必须让服务端能识别同一意图,并让客户端拒绝乱序事件。
适合阶段:资深前端 / 分布式系统面试核心能力:幂等 · 顺序 · 一致性
面试官想考什么
- 用户双击发送会发生什么? 考察端到端幂等。
- 流事件乱序如何处理? 考察序列号和重排。
- 消息 id 能否由前端生成? 考察标识和信任边界。
- 重试和超时如何避免重复扣费? 考察副作用控制。
一句话回答
text
把一次用户意图绑定到幂等键和 clientMessageId,服务端持久化请求状态并原子去重;每个流事件带单调序列号或 cursor,客户端只接受连续或更高 revision,副作用工具还要单独使用幂等键和状态查询。面试回答详解
1. 三类标识
- clientMessageId:客户端本地消息身份。
- requestId/attemptId:一次模型执行身份。
- idempotencyKey:同一用户意图的重复请求身份。
它们可以关联但不能混为一个字段。重新生成通常是新的 attempt,重复点击同一提交才复用幂等键。
2. 服务端去重
服务端在创建任务时以 (user, tenant, idempotencyKey) 唯一约束或原子写入。已有记录时返回原任务状态,而不是再次调用模型。状态从 pending 到 completed/failed/cancelled 的迁移要有合法性检查。
3. 顺序处理
事件带 sequence,前端保存 lastSequence。高于下一序号的事件先放 pending buffer,连续后再应用;若协议允许丢片,则请求补发或重新拉取 snapshot。低于等于已应用序号的事件直接丢弃。
4. UI 层防重复
提交后禁用按钮、显示 pending、保留用户输入和错误恢复动作。但 UI 防重复只是体验层,不能作为唯一保证。React Strict Mode、重渲染、网络重试和多个标签页都可能让副作用被触发多次。
5. 副作用工具
发送邮件、创建订单、修改数据等工具要在服务端实现幂等,必要时先查询业务状态再执行。模型回答可以重复生成,外部副作用不能靠“模型应该只调用一次”的假设保护。
可直接背诵的 30 秒回答
text
我会区分 clientMessageId、requestId、attemptId 和 idempotencyKey。用户一次意图复用幂等键,服务端原子创建任务并在重复请求时返回原状态。流事件带 sequence 或 cursor,前端去重、缓存乱序片段并按顺序应用。UI 禁用按钮只是体验优化,真正的副作用幂等必须在服务端。扩展知识
exactly-once 的现实边界
网络系统通常更容易做到 at-least-once 投递,因此应用层要做到幂等消费;不要轻易承诺端到端 exactly-once。
面试官追问链
追问一:前端生成 idempotency key 安全吗?
- 考察点:信任边界。
- 回答方向:可作为关联标识,但服务端要绑定用户和租户、限制有效期,并防止客户端伪造其他用户的 key。
追问二:sequence 缺 1 个事件怎么办?
- 考察点:恢复策略。
- 回答方向:短暂等待并请求补发;超过窗口则拉最终 snapshot,记录 gap,不继续渲染可能误导用户的状态。
追问三:React Strict Mode 会造成重复请求吗?
- 考察点:副作用生命周期。
- 回答方向:开发环境可能暴露不安全 effect;请求应由明确用户动作或可幂等 effect 驱动,cleanup 要取消订阅,服务端仍需幂等。