题目重点:网络chunk不是完整消息,UI需要请求身份和可恢复的事件序列。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练聊天产品前端,不调用或描述某实际产品私有API。流式协议事件有conversation/message/request ID、sequence、delta/done/error。
- server为持久历史权威,浏览器草稿与临时UI状态本地保存;typing效果不应伪装已经收到未生成内容。
解题路线
- 组件划为ConversationList、MessageList/Message、Composer、StreamStatus与Retry控件。normalized数据按conversation/message ID保存,显示顺序单独数组,避免整个消息树每chunk重复复制。
- 提交message带client_request_id,临时user message和assistant placeholder关联request。收到delta只更新对应message,seq去重/检查缺口;换conversation不能让旧请求delta进入新窗口。
- transport可SSE单向server stream或WebSocket双向,UTF-8/协议frame可能跨网络chunk,需要增量decoder及frame buffer。done是应用状态,连接关闭未必完成;error保留已有内容但明确未完成。
- token更新可buffer并按帧或短周期flush到render state,避免每字符重排全部列表。显示内容存在state,连接/abort controller/flush timer可放ref;ref改变不触发render,不能只改ref希望屏幕更新。
- 持久化区分已确认消息、partial回复与草稿,重载先拉server snapshot再从last_seq续流;若协议无resume则标interrupted并由用户决定重试,不能自动拼新生成内容当旧回复。sanitize/render边界、权限和storage敏感性独立处理。
手动走一遍
用户发m后立刻切到另一conversation,旧stream仍按message ID存原会话,不覆盖当前回复。网络每次chunk50bytes,可能把一个UTF-8字符或SSE frame拆开;不能对单chunk做JSON.parse。连接断开有partial文本但无done,UI显示中断及可重试,不误报成功。
规模与取舍
N消息、C流事件,增量更新应随相关文本/可见列表规模;全文Markdown每chunk重解析会累计近似二次成本。大历史虚拟列表减少DOM,持久partial写盘需节流;内存/本地空间设保留上限。
易错点与追问
容易失分的边界
- 连接断开就标回复完成。
- 所有delta追加到当前屏幕最后消息,切会话时串消息。
- 将DOM每字符动画成本忽略。
继续深挖
- 流resume、用户取消和服务端仍运行怎样协商?
- 多设备编辑同草稿与已确认消息怎样区分冲突策略?
技术参考
- React useState:技术语义参考,具体题目按本文约定。
- React useRef:技术语义参考,具体题目按本文约定。
