🔄 复习日 / Review Day — Day 30 (2026-04-23)
📊 NeetCode: 26/150 · SysDesign: 25/40 · Behavioral: 25/40 · Frontend: 25/50 · AI: 12/30
🔥 2-day streak!
🔄 复习日 / Review Day
今天是复习日!回顾过去4天的内容。
It's review day! Let's consolidate the last 4 days of learning.
覆盖的主题 / Topics Covered:
- Day 26: Autocomplete/Typeahead · Evaluate Reverse Polish Notation · Handling Tough Feedback · TypeScript Generics · AI Agents (ReAct)
- Day 28: Chat System Design · Daily Temperatures · Build-vs-Buy · Promises & async/await · MCP Protocol
- Day 29: Search Engine Design · Car Fleet · Navigating Org Change · Event Loop · AI News
📝 Quick Quiz — 3 Mini-Reviews
Q1: [🏗️ System Design] 你在设计一个类似 Slack 的聊天系统时,为什么要用 WebSocket 而不是 HTTP 轮询?能说出至少两个技术理由吗?
When designing a chat system like Slack/WhatsApp, why prefer WebSockets over HTTP polling? Name at least two technical reasons.
<details><summary>显示答案 / Show Answer</summary>
WebSocket 的核心优势在于双向持久连接。HTTP 轮询需要客户端反复发起请求(每次都有 TCP 握手和 HTTP 头开销),而 WebSocket 建立一次连接后双方可随时推送数据。
具体理由:
- 低延迟:WebSocket 消息延迟通常 <100ms;轮询间隔造成人为延迟(1-30s)
- 更低开销:WebSocket 帧头只有 2-10 字节,HTTP 请求头动辄几百字节
- 服务端推送:服务器可主动推送新消息,无需客户端反复问"有新消息吗?"
- 连接效率:避免了海量用户同时轮询造成的"惊群效应"
Key insight: WebSocket is a persistent, full-duplex connection established via HTTP Upgrade. Once connected, either side can send data at any time — perfect for real-time chat where the server needs to push messages to clients without them asking.
</details>
Q2: [💻 Algorithms] 在 "Car Fleet" 问题中,为什么要先按起始位置从大到小排序?如果不排序直接用栈会出现什么问题?
In the Car Fleet problem, why must you sort cars by starting position in descending order before using the stack? What goes wrong without sorting?
<details><summary>显示答案 / Show Answer</summary>
核心洞察: 车队的形成依赖于"追及关系"——只有后车能追上前车才能合并成车队。按位置从大到小排序,相当于从最靠近终点的车开始处理,确保每辆车的"追及对象"已经确定。
如果不排序,你无法知道一辆车的"前方是谁"——会错误地把不相邻的车配对,导致错误的车队合并计算。
算法流程:
直觉: 如果一辆车计算出的到达时间 ≤ 前方最近车队的到达时间,说明它会在到达前被"挡住",合并入同一车队。栈顶永远是当前最近的车队时间。
</details>
Q3: [🎨 Frontend] 下面这段代码有什么问题?Event Loop 中 Promise.resolve() 和 setTimeout(() => {}, 0) 谁先执行?
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
What will the output order be, and why?
<details><summary>显示答案 / Show Answer</summary>
原因: JavaScript 事件循环有两种任务队列:
| 队列类型 | 英文 | 例子 | 优先级 |
|---|---|---|---|
| 微任务 | Microtask Queue | Promise.then, queueMicrotask, MutationObserver | 高 |
| 宏任务 | Macrotask Queue | setTimeout, setInterval, I/O | 低 |
执行顺序:
- 同步代码先执行:
console.log('1')→console.log('4')(同步,顺序执行) setTimeout回调进入宏任务队列Promise.then回调进入微任务队列- 当前调用栈清空后,先清空所有微任务:
console.log('3') - 最后处理宏任务:
console.log('2')
关键规则: 每次宏任务执行完毕后,会把当前微任务队列全部清空,然后才执行下一个宏任务。Promise.resolve() 虽然是异步,但属于微任务,比 setTimeout(0) 更早执行。
</details>
💡 复习巩固记忆,螺旋式上升。每一次回顾都让知识更牢固。
Review strengthens memory. Each revisit makes knowledge more durable.
📅 明天继续新内容!Tomorrow: fresh content continues.