← 2026-03-31 📂 All Days 2026-04-02 →
📝
📝 Review Quiz
🔄 复习日 Day 15 / Review Day 15

🔄 复习日 Day 15 / Review Day 15

📊 进度 / Progress: Day 15/150 · NeetCode: 14/150 · SysDesign: 13/40 · Behavioral: 13/40 · Frontend: 13/50 · AI: 6/30

🔥 4-day streak!


今天是复习日!回顾过去4天的内容。

Today is a review day! Let's revisit the past 4 days of content.

回顾范围 / Review scope: Days 11–14

  • 🏗️ Consistent Hashing, CAP Theorem, Message Queues, Microservices vs Monolith
  • 💻 Two Sum II, 3Sum, Container With Most Water, Trapping Rain Water
  • 🗣️ Proactive problem-solving, Prioritization, Delivering bad news, Cross-team initiatives
  • 🎨 React useEffect, useRef, useMemo/useCallback, Custom Hooks
  • 🤖 AI News, RLHF, AI News, LoRA & QLoRA

📝 Quick Quiz — 3 Mini-Reviews


Q1: [🏗️ System Design — Consistent Hashing & CAP Theorem]

你在设计一个分布式缓存系统(比如 Redis Cluster)。当一个节点崩溃时,使用普通哈希(hash(key) % N)和一致性哈希(Consistent Hashing)各会发生什么?为什么分布式数据库(如 Cassandra)选择 Eventual Consistency 而不是强一致性?

You're designing a distributed cache (like Redis Cluster). When one node goes down, what happens with regular hashing (hash(key) % N) vs consistent hashing? And why do databases like Cassandra prefer eventual consistency over strong consistency?

<details><summary>显示答案 / Show Answer</summary>

普通哈希的问题 / Regular hashing problem:

当节点数 N 变化(比如从 5 变成 4),几乎所有的 key 都需要重新映射到不同节点 — 导致大规模缓存失效(cache stampede)。

When N changes (5→4), nearly all keys get remapped to different nodes — causing a massive cache miss storm.

一致性哈希的优势 / Consistent hashing advantage:

将节点和 key 都映射到一个"哈希环"上。某节点下线时,只有该节点顺时针方向的 key 需要迁移到下一个节点,其他 key 完全不受影响。通常只影响 1/N 的数据。

Both nodes and keys are mapped onto a ring. When a node goes down, only the keys between the failed node and its predecessor need to migrate to the next node clockwise — roughly 1/N of all keys.

Virtual nodes (VNodes) 虚拟节点进一步让每个物理节点在哈希环上占据多个位置,使数据分布更均匀。

CAP & Eventual Consistency:

CAP 定理说在网络分区(P)发生时,你必须在一致性(C)和可用性(A)之间选一个。Cassandra 选择 AP(可用性 + 分区容忍),允许暂时不一致,通过后台的 gossip protocol 和 hinted handoff 最终达到一致。这对"写多读多"场景更实用 — 写入不会因为网络抖动而失败。

CAP says during a network partition, choose C or A. Cassandra picks AP (availability + partition tolerance), accepting that different replicas may briefly disagree. Background reconciliation (gossip, read repair, hinted handoff) eventually converges. For high-traffic apps, "eventually consistent" is a feature — writes don't fail just because one replica is slow.

核心记忆点 / Key insight: Consistent hashing = minimal redistribution. CAP = pick your tradeoff explicitly.

</details>


Q2: [💻 Algorithms — Two Pointers: Container With Most Water vs Trapping Rain Water]

两道题都用双指针,都涉及"水",但思路有微妙差别。Container With Most Water(#11)和 Trapping Rain Water(#42)的关键区别是什么?为什么前者一次遍历就够,后者需要追踪历史最大值?

Both problems use two pointers and involve "water", but the logic is subtly different. What's the key difference between Container With Most Water (#11) and Trapping Rain Water (#42)? Why does the first need only one pass while the second requires tracking historical maximums?

<details><summary>显示答案 / Show Answer</summary>

Container With Most Water (#11) — 选最大容器:

你在两个柱子之间装水,水量 = min(left, right) * distance。双指针从两端向中间移动,每次移动较短的那端 — 因为较长端已经尽力了,继续缩小宽度只有移动短板才有可能增加面积。

You're choosing two walls. Water volume = min(left, right) * width. Move the shorter pointer inward — the taller wall can't improve the result unless the other wall gets taller. This greedy choice is provably correct.

Trapping Rain Water (#42) — 计算每个格子的积水:

每个位置能接的水 = min(leftMax, rightMax) - height[i]。关键是每个位置都受其左右两侧最高柱子的限制,需要知道历史最大值。

双指针做法:维护 leftMaxrightMax,哪侧较小就处理哪侧(因为较小侧的瓶颈已经确定)。

Every cell can hold water = min(leftMax, rightMax) - height[i]. Each cell is bounded by the tallest wall on BOTH sides — you must track running maximums. Two-pointer trick: whichever side has the smaller max, process it (its bottleneck is determined regardless of the other side's future values).

核心区别 / Core difference:

  • Container: 两点之间 的最大矩形,贪心移动短板 ✓
  • Trapping: 每个点 上方的积水,需要双侧历史最大值 ✓

记忆口诀: Container = "短板决定上限,移短板求最大";Trapping = "每格水位 = 两侧最高墙的最小值 − 自身高度"

</details>


Q3: [🎨 Frontend — React Hooks: useEffect, useRef, useMemo/useCallback, Custom Hooks]

你在做一个数据密集型 dashboard,需要:

  1. 在组件挂载时 fetch 数据并在卸载时取消请求
  2. 直接操作一个 DOM 元素(聚焦输入框)而不触发重渲染
  3. 避免昂贵的排序函数在每次渲染时重复执行
  4. 把上面的 fetch 逻辑复用到多个组件

请说明应该用哪个 Hook,以及最常见的错误写法。

You're building a data-heavy dashboard and need to: (1) fetch data on mount and cancel on unmount, (2) focus a DOM element without triggering re-renders, (3) avoid re-running an expensive sort on every render, (4) reuse the fetch logic across components. Which hook for each, and what's the most common mistake?

<details><summary>显示答案 / Show Answer</summary>

1. Fetch + 取消请求 → useEffect

useEffect(() => {
  const controller = new AbortController();
  fetch(url, { signal: controller.signal }).then(setData);
  return () => controller.abort(); // cleanup!
}, [url]); // dependency array matters!

❌ 最常见错误:省略 cleanup,导致组件卸载后仍然 setState,产生内存泄漏和 "Can't perform a React state update on an unmounted component" 警告。

❌ Most common mistake: forgetting the cleanup function, causing state updates on unmounted components.

2. 操作 DOM → useRef

const inputRef = useRef(null);
// inputRef.current.focus() — doesn't trigger re-render

useRef 的值改变不会触发重渲染,适合存储 DOM 引用、定时器 ID、或任何"不影响 UI"的可变值。

Changing .current never triggers a re-render — perfect for DOM refs, timer IDs, or previous values.

3. 避免重复计算 → useMemo

const sorted = useMemo(() => expensiveSort(data), [data]);

❌ 过度使用 useMemo 反而增加开销。只在真正昂贵的计算或引用稳定性(传给子组件)时使用。

❌ Over-memoizing adds overhead. Only use for genuinely expensive computations or referential stability.

4. 复用逻辑 → Custom Hook

function useDashboardData(url) {
  const [data, setData] = useState(null);
  useEffect(() => { /* fetch logic */ }, [url]);
  return data;
}

Custom hooks = 把 hook 逻辑从组件里提取出来,不是 HOC,不是 render props,就是普通函数(必须以 use 开头)。

Custom hooks extract stateful logic — not a new React feature, just a naming convention (use prefix) that signals to React's linter.

记忆矩阵 / Memory matrix:

GoalHook
Side effects, fetch, subscriptionsuseEffect
DOM access, mutable value (no re-render)useRef
Expensive computation cacheuseMemo
Stable function referenceuseCallback
Reusable stateful logicCustom Hook

</details>


💡 复习巩固记忆,螺旋式上升。每次回顾不只是"记住了吗",而是"能用自己的话解释吗"。

Review doesn't just ask "do you remember?" — it asks "can you explain it in your own words?"

📅 明天继续新内容!Day 16 coming tomorrow!


Generated by byte-by-byte · Day 15 of 150 · 2026-04-01