Interview Bank
328 questions total; 1 shown with current filters.
CourseAllFrom Frontend Engineer to Agent Engineer in 30 DaysPrompt Engineering From Scratch in 5 DaysMastering Claude: From Conversation to Claude Code in 5 DaysMastering Codex and the OpenAI Agents SDK in 5 DaysMCP in 7 Days: Wire Tools Into Any AgentAgent Skills in 7 Days: Turn Experience Into Reusable CapabilityContext Engineering in 5 DaysRAG in 14 Days: From Retrieval to Trustworthy AnswersBuild an AI Short-Drama Production Pipeline With Agents in 14 Days
Tag
All#performance1#reliability22#cost15#architecture12#streaming11#security10#observability9#distributed-systems8#idempotency8#multi-agent8#rag7#system-design7
136 more tagsShow fewer tags
#api-design6#operations6#sse6#deployment5#message-bus5#tool-calling5#agent-loop4#behavioral4#error-handling4#evaluation4#framework-design4#mcp4#routing4#concurrency3#context-engineering3#interview-prep3#langgraph3#llm-basics3#model-routing3#orchestration3#prompt-injection3#protocol3#redis-streams3#scalability3#scheduling3#agent-design2#auth2#checkpointing2#communication2#cost-control2#database2#debugging2#interview-process2#latency2#long-term-memory2#memory2#ordering2#prompt-engineering2#rate-limiting2#react2#resume2#retrieval2#sharding2#state-machine2#state-management2#tool-design2#tool-permissions2#trade-offs2#ux2#agent-basics1#agent-quality1#async1#atomicity1#cancellation1#capacity-planning1#career1#chunking1#compression1#configuration1#consistent-hashing1#context1#context-compression1#context-management1#correctness1#customer-support1#data-modeling1#deliberate-practice1#docker1#documentation1#engineering-tradeoffs1#escalation1#event-driven1#fallback1#fan-out1#fencing-token1#forking1#framework-selection1#frontend1#global-market1#hybrid-search1#interrupt-merge1#isolation1#json-parsing1#jwt1#knowledge-organization1#lease1#least-privilege1#llm-as-judge1#loop-guard1#mobile1#multi-tenancy1#nodejs1#persistence1#pgvector1#portfolio1#prioritization1#proactive-messaging1#product-engineering1#project-storytelling1#prompt1#provider-abstraction1#quiet-hours1#ranking1#recall1#reconnect1#redis1#reflection1#replay1#reporting1#rerank1#retrieval-quality1#retry1#retry-semantics1#rrf1#sampling1#sandboxing1#schema-design1#secrets-management1#self-assessment1#self-introduction1#self-presentation1#service-architecture1#session-management1#split-brain1#star1#stateless1#storytelling1#structured-output1#system-prompt1#testing1#timezone1#tool-execution1#tools1#tracing1#transport1#vector-database1
From Frontend Engineer to Agent Engineer in 30 Days
D25 The Frontend Agent Experience: Streaming Rendering, Visualizing Tool Calls, Interrupt/Retry, SSE Hooks
What is different about frontend state management under streaming, and why not call setState on every token?流式场景下前端的状态管理要注意什么?为什么不能每个 token 都 setState?
Common in ChinaCommon overseasIntermediate#react#streaming#performanceHow to reason about it · think before answering
- This question probes whether you have watched a long reply drop frames. 'Keep messages in useState and setState on each delta' is functionally correct but reveals you only tried short replies.
- Do the arithmetic first: streaming delivers tens of tokens per second, so one setState per token means tens of full render passes per second. The message list keeps growing, so each pass gets more expensive as the conversation goes — the jank peaks late in long replies and long sessions, exactly when it hurts most.
- The fix is batching: append tokens into a ref without rendering, and flush the accumulated text on a 30 ms timer. Thirty milliseconds is roughly 33 fps, still a smooth typewriter, while render count drops by one to two orders of magnitude — measured, 200 tokens produced 8 commits.
- Three details that must ship with it: force a final flush when the stream ends, or the last sub-batch stays in the buffer and the user sees a truncated reply; flush on interrupt too, so the user sees exactly where it stopped; and keep the buffer in a ref, not state, or the code you wrote to avoid renders is itself causing them.
- One level up is layering: streaming logic should live outside React. Parsing, event reduction and batching are pure functions; a store holds state and exposes subscribe and getSnapshot; React only calls useSyncExternalStore. The concrete payoff is that this logic can be unit tested with no browser instead of being click-tested.
- Expected follow-up: why not just use a state library? Libraries solve cross-component sharing and update granularity, while the hard parts here are lifecycle (connect, cancel, cleanup on unmount) and flush cadence — no library does those for you. The interviewer wants your reasoning, not your library list.
分析过程 · 先想清楚再作答
- 这题考的是「你有没有在长回复下真的看过掉帧」。答「用 useState 存消息数组,收到 delta 就 setState」在功能上没错,但它暴露的是只在短回复上试过。
- 先算一笔账:流式一秒来几十个 token,每个 token 一次 setState 就是一秒几十轮完整渲染。而消息列表是越来越长的,每一轮的代价随对话轮数增长——所以卡顿在回复后半段和长会话里最明显,正好是最不该卡的时候。
- 做法是攒批:token 先追加进 ref(不触发渲染),一个定时器每 30 毫秒把攒下的一次性提交。30 毫秒约等于 33 帧每秒,肉眼仍是连续的打字机,渲染次数掉一到两个数量级——实测 200 个 token 只提交 8 次。
- 三个必须配套的细节:流结束时强制 flush 一次(否则最后不足一个批次的内容永远留在缓冲里,用户看到回复少半句);打断时也要 flush(让用户看到停在哪个字);缓冲状态必须放 ref 不放 state,否则你为了省渲染写的代码本身在触发渲染。
- 再往上一层是分层:**流式逻辑应该活在 React 外面。** 解析、事件归并、攒批都是纯函数,store 持有状态并暴露 subscribe 和 getSnapshot,React 侧只用 useSyncExternalStore 订阅。这样做的直接好处是**这套逻辑可以在没有浏览器的环境里跑单元测试**,而不是只能靠手点。
- 可预期的追问:为什么不直接用某个状态库?答:状态库解决的是跨组件共享和更新粒度,而流式的难点在生命周期(连接、取消、卸载清理)和批处理频率——这两件事没有哪个库替你做。面试官问这题想听的是你怎么想,不是你会用哪个库。
Key points
- One setState per token means tens of full renders per second, and each render costs more as the list grows — long replies jank at the end.
- Batch instead: accumulate tokens in a ref and flush every 30 ms; measured, 200 tokens produced only 8 commits.
- Ship the details with it: force a flush on stream end and on interrupt, and keep the buffer in a ref rather than state.
- Keep parsing, event reduction and batching as pure functions outside React; subscribe via useSyncExternalStore.
- The payoff of that split is unit-testable streaming logic with no browser in the loop.
答题要点
- 每个 token 一次 setState 等于一秒几十轮全量渲染,而消息列表越长每轮越贵,长回复后半段必然掉帧。
- 做法是攒批:token 进 ref 不触发渲染,30 毫秒定时 flush 一次,实测 200 个 token 只提交 8 次。
- 必须配套:流结束和打断时强制 flush;缓冲放 ref 不放 state。
- 流式逻辑(解析、归并、攒批)应该是 React 之外的纯函数,React 只用 useSyncExternalStore 订阅。
- 这样分层的直接好处是能脱离浏览器做单元测试,而不是只能手点验证。