逐日AI

面试题库

共 328 题,当前筛选 1 题。

标签
还有 126 个标签
#agent-loop2#api-design2#chunking2#cost-tradeoff2#debugging2#distributed-systems2#error-handling2#hybrid-search2#llm-as-judge2#multi-agent2#multi-hop2#oauth2#operations2#pipeline-design2#prompt-caching2#rag2#recall2#retrospective2#retry2#scheduling2#sse2#tool-permissions2#trade-offs2#access-control1#agentic-rag1#agents-sdk1#analytics1#architecture-review1#behavioral1#budget-control1#caching1#cancellation1#checkpointing1#circuit-breaker1#citation-verification1#client1#client-integration1#coding-agent1#compaction1#compliance1#concurrency1#confused-deputy1#context-engineering1#contextual-retrieval1#copyright1#correctness1#cost-control1#customer-support1#data-quality1#database1#deployment1#distribution1#embedding-migration1#error-propagation1#escalation1#evidence1#faithfulness1#fallback1#feedback-loop1#fencing-token1#filter-pushdown1#filtering1#framework-design1#graph-rag1#guardrails1#handoff1#image-generation1#integration1#iterative-scan1#labeling1#latency1#latency-budget1#least-privilege1#long-context1#long-session1#long-term-memory1#mcp1#message-bus1#methodology1#model-migration1#multi-tenancy1#notifications1#ocr1#offline-testing1#project-storytelling1#protocol-versions1#quality1#query-rewriting1#rate-limiting1#reconnect1#refusal1#replay1#reproducibility1#rerank1#resume1#retrieval1#risk-assessment1#rollout1#routing1#runtime1#safety1#scaling1#self-introduction1#split-brain1#state-management1#state-persistence1#statelessness1#stdio-transport1#storytelling1#subagent1#subagents1#subscriptions1#test-strategy1#thresholds1#timezone1#token-accounting1#tool-design1#tool-schema1#tools1#trust-boundary1#ux1#verification1#versioning1#workflow-design1#workflow-engine1#zero-downtime1

30 天从前端工程师到 Agent 工程师

D29 弱项补强 + 编码热身:rate limiter、LRU、并发控制、流式 JSON 解析

  • 为什么流式场景下不能直接用 JSON.parse?你会怎么做增量解析?Why can't you just call JSON.parse in a streaming response, and how would you parse incrementally?
    国内高频海外高频深入#streaming#json-parsing

    分析过程 · 先想清楚再作答

    1. 这题的区分度几乎全在你开口的第一句话。听到「流式 JSON 解析」就动手写状态机的人,会花二十多分钟写一个大概率有 bug 的东西;先反问一句「是一行一个完整 JSON,还是一个大对象被切成很多片」的人,已经赢了一半。
    2. 先回答为什么不能直接解析:网络分包不认语法边界,一次读取拿到的很可能是半个 JSON。直接扔给解析器只会抛异常,而且这个异常没有任何可恢复的信息。
    3. 然后做那个关键区分。情况 a 是 SSE:每条事件是一行以 data 开头的文本,行内是完整 JSON,LLM 场景 99% 是这一种,解法是行缓冲加逐行解析,二十行代码——把切分出来的最后一段(可能是半行)留在缓冲区里,等下一次读到更多数据再拼。情况 b 是单个大对象跨分片到达,才需要真正的增量解析。
    4. 情况 b 的核心是三个状态变量:括号深度(深度归零说明一个完整对象结束)、是否在字符串内部(字符串里的括号不能计入深度)、前一个字符是不是反斜杠(转义中的引号不切换字符串状态)。三者缺一不可,少一个遇到含括号的文本就算错深度。
    5. 还有一条几乎没人主动说、但一说就加分的坑:分片是按字节切的,一个汉字在 UTF-8 里占三个字节,边界可能落在中间。必须用流式解码器(TextDecoder 的 stream 选项、Python 的增量解码器、Java 的 InputStreamReader),否则会拿到一个永远补不回来的乱码字符。这是「半行缓冲」在字节层的同款问题。
    6. 可以预期的追问:那结尾那个终止标记怎么办?答案是它不是 JSON,必须在解析前先判断并直接返回,拿它去解析必然抛异常——这是这道题里最常见的一行 bug。

    How to reason about it · think before answering

    1. Almost all the signal is in your first sentence. Whoever starts writing a state machine will spend twenty-plus minutes on something probably buggy; whoever first asks 'is it one complete JSON per line, or one big object split across chunks?' has already won half the question.
    2. Answer the why first: network chunking ignores syntax boundaries, so a single read often holds half a JSON document. Handing that to a parser only throws, and the exception carries nothing you can recover from.
    3. Then draw the distinction. Case (a) is SSE: each event is one line prefixed with data, holding one complete JSON object. This covers 99% of LLM work, and the fix is line buffering plus per-line parsing — keep the trailing fragment in the buffer and stitch it onto the next chunk.
    4. Case (b) — one large object arriving in pieces — is the only case needing real incremental parsing, and it rests on three state variables: bracket depth (back to zero means a complete object), whether you are inside a string (brackets in text must not count), and whether the previous character was a backslash (an escaped quote must not toggle string state). Drop any one and text containing brackets breaks the depth count.
    5. One trap almost nobody volunteers: chunks are split on bytes, and a CJK character takes three bytes in UTF-8, so a boundary can land mid-character. Use a streaming decoder — TextDecoder with the stream option, an incremental decoder in Python, InputStreamReader in Java — or you get a replacement character you can never recover. It is the half-line problem one layer down.
    6. Expect the follow-up: what about the terminator line? It is not JSON, so check for it and return before parsing. Feeding it to the parser is the single most common one-line bug in this question.

    答题要点

    • 网络分包不认语法边界,一次读取可能拿到半个 JSON,直接解析必然抛异常且不可恢复
    • 先问清是哪一种:一行一个完整 JSON(SSE,占 LLM 场景的绝大多数)还是一个大对象跨分片到达
    • 前者只需行缓冲加逐行解析:把最后一段可能的半行留在缓冲区,等下一次读到更多数据再拼
    • 后者才需要状态机,核心是括号深度、是否在字符串内部、前一个字符是否为转义反斜杠三个状态
    • 字节层还有一个同款坑:UTF-8 多字节字符可能被分片切开,必须用流式解码器;结尾的终止标记不是 JSON,解析前要先判断

    Key points

    • Network chunking ignores syntax boundaries, so a read can hold half a document; parsing it throws an unrecoverable error
    • Ask which case it is first: one complete JSON per line (SSE, the overwhelming majority of LLM work) or one large object split across chunks
    • The first case only needs line buffering plus per-line parsing, keeping the trailing partial line for the next chunk
    • Only the second case needs a state machine, tracking bracket depth, inside-string, and escaped-previous-character
    • One layer down, a multi-byte UTF-8 character can be split across chunks, so use a streaming decoder; and the terminator line is not JSON, so check for it before parsing