← 2026-04-22 📂 All Days 2026-04-24 →

🔄 复习日 / 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 建立一次连接后双方可随时推送数据。

具体理由:

  1. 低延迟:WebSocket 消息延迟通常 <100ms;轮询间隔造成人为延迟(1-30s)
  2. 更低开销:WebSocket 帧头只有 2-10 字节,HTTP 请求头动辄几百字节
  3. 服务端推送:服务器可主动推送新消息,无需客户端反复问"有新消息吗?"
  4. 连接效率:避免了海量用户同时轮询造成的"惊群效应"

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>

核心洞察: 车队的形成依赖于"追及关系"——只有后车能追上前车才能合并成车队。按位置从大到小排序,相当于从最靠近终点的车开始处理,确保每辆车的"追及对象"已经确定。

如果不排序,你无法知道一辆车的"前方是谁"——会错误地把不相邻的车配对,导致错误的车队合并计算。

算法流程:

sort cars by position descending (closest to target first) for each car: time_to_arrive = (target - position) / speed if stack is empty OR time > stack[-1]: stack.append(time) # new fleet # else: this car catches up → same fleet, discard return len(stack)

直觉: 如果一辆车计算出的到达时间 ≤ 前方最近车队的到达时间,说明它会在到达前被"挡住",合并入同一车队。栈顶永远是当前最近的车队时间。

</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>

**输出顺序:** `1 → 4 → 3 → 2`

原因: JavaScript 事件循环有两种任务队列:

队列类型英文例子优先级
微任务Microtask QueuePromise.then, queueMicrotask, MutationObserver高
宏任务Macrotask QueuesetTimeout, setInterval, I/O低

执行顺序:

  1. 同步代码先执行:console.log('1') → console.log('4')(同步,顺序执行)
  2. setTimeout 回调进入宏任务队列
  3. Promise.then 回调进入微任务队列
  4. 当前调用栈清空后,先清空所有微任务:console.log('3')
  5. 最后处理宏任务:console.log('2')

关键规则: 每次宏任务执行完毕后,会把当前微任务队列全部清空,然后才执行下一个宏任务。Promise.resolve() 虽然是异步,但属于微任务,比 setTimeout(0) 更早执行。

</details>


💡 复习巩固记忆,螺旋式上升。每一次回顾都让知识更牢固。

Review strengthens memory. Each revisit makes knowledge more durable.

📅 明天继续新内容!Tomorrow: fresh content continues.