🔄 复习日 Day 10 / Review Day 10
Date: 2026-03-25 | Phase: Foundation
今天是复习日!回顾第 6-9 天的内容。
Today is Review Day! Looking back at Days 6–9.
📊 回顾范围 / Review Scope (Days 6–9):
- 🏗️ Caching Strategies · Database Types · DB Indexing · DB Replication & Sharding
- 💻 Top K Frequent Elements · Product of Array Except Self · Valid Sudoku · Valid Palindrome
- 🗣️ Balancing priorities · Simplifying complex systems · Ambiguous requirements · Pushing back on features
- 🎨 CSS Specificity · Positioning · Animations & Transitions · React useState
- 🤖 Embeddings · Training vs Fine-Tuning vs Prompting
📝 Quick Quiz — 3 Mini-Reviews
Q1: [🏗️ System Design] Caching + Replication
你在设计一个读多写少的社交平台(Read-heavy social feed)。你决定同时使用 缓存 和 数据库只读副本(Read Replicas)。
You're designing a read-heavy social feed. You use both caching and read replicas.
问题 / Question: 这两者的职责分工是什么?什么情况下读副本仍然不够,你必须依赖缓存?
What is the distinct role of each? When are read replicas still insufficient and you MUST rely on the cache?
<details><summary>显示答案 / Show Answer</summary>
Read replicas 通过分散读请求到多个数据库副本来提升吞吐量,但每次请求仍然执行完整的 SQL 查询,延迟在毫秒级别。缓存(Redis/Memcached)则把热点数据存在内存里,延迟在微秒级别,且完全绕开了数据库。
Read replicas scale throughput by distributing SQL queries across copies, but every request still hits disk and parses SQL — latency stays in the millisecond range. A cache holds hot data in RAM (microsecond latency) and bypasses the database entirely.
什么时候必须用缓存 / When you MUST cache:
- 热点数据(Hotspot / Celebrity problem):单个用户/item 被疯狂读取,单个副本也扛不住
- 计算昂贵的结果(Aggregations, ranked feeds):不想每次都重新算
- 外部 API 响应缓存:副本根本不存这些数据
关键洞察: Read replica = 水平扩展数据库。Cache = 彻底逃离数据库。两者互补,不是替代关系。
</details>
Q2: [💻 Algorithms] Product of Array Except Self
给定数组 [1, 2, 3, 4],Product of Array Except Self 要求返回 [24, 12, 8, 6]——即每个位置是除自身以外所有元素的乘积。
Given [1, 2, 3, 4], return [24, 12, 8, 6] — each position is the product of all other elements.
问题 / Question: 不使用除法、O(n) 时间、O(1) 额外空间(输出数组不算)怎么做?解释 prefix product + suffix product 的思路。
Without division, O(n) time, O(1) extra space — explain the prefix × suffix approach.
<details><summary>显示答案 / Show Answer</summary>
核心思路 / Core idea: 位置 i 的答案 = i 左边所有数的乘积 × i 右边所有数的乘积。
Array: [1, 2, 3, 4]
Prefix: [1, 1, 2, 6] # prefix[i] = product of all elements to the LEFT of i
Suffix: [24, 12, 4, 1] # suffix[i] = product of all elements to the RIGHT of i
Result: [24, 12, 8, 6] # prefix[i] * suffix[i]
两趟扫描 / Two-pass O(1) space:
- Pass 1 (left→right): 用输出数组存 prefix product
- Pass 2 (right→left): 用一个变量
suffix滚动累乘,直接乘进输出数组
def productExceptSelf(nums):
n = len(nums)
res = [1] * n
# Pass 1: res[i] = product of everything to the LEFT
for i in range(1, n):
res[i] = res[i-1] * nums[i-1]
# Pass 2: multiply in suffix product on the fly
suffix = 1
for i in range(n-1, -1, -1):
res[i] *= suffix
suffix *= nums[i]
return res
为什么不用除法? 因为数组可能含 0,除法会出错(0/0)。
举一反三: 这个 "prefix + suffix scan" 模式在 Trapping Rain Water 中也用到了——左边最大值 × 右边最大值决定每格存水量。
</details>
Q3: [🎨 Frontend] React useState
看这段代码:
function Counter() {
const [count, setCount] = React.useState(0);
const handleClick = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
return <button onClick={handleClick}>Count: {count}</button>;
}
问题 / Question: 点击一次按钮后,count 变成几?为什么?如果想让 count 每次点击增加 3,怎么修改?
After one click, what is count? Why? How do you fix it to actually add 3?
<details><summary>显示答案 / Show Answer</summary>
答案是 1,不是 3。
原因 / Why: React 在同一个事件处理函数中会批量处理(batch) setState 调用。count 在整个 handleClick 执行期间都是 快照值(stale closure),始终是 0。所以三次 setCount(0 + 1) 其实是三次设置同一个值 1。
如何修复 / Fix — 使用函数式更新(functional update form):
const handleClick = () => {
setCount(prev => prev + 1); // prev = 0 → 1
setCount(prev => prev + 1); // prev = 1 → 2
setCount(prev => prev + 1); // prev = 2 → 3
};
传入函数时,React 会把最新的 state 值作为参数传入,而不是用闭包里的快照。
黄金法则 / Golden Rule: 当新 state 依赖旧 state 时,永远用 setX(prev => ...) 形式,而不是 setX(x + 1)。这在并发模式(React 18+ Concurrent Features)下尤其重要。
</details>
💡 复习巩固记忆,螺旋式上升。每次复习都是在加深神经连接。
Review strengthens memory through spaced repetition — you're literally deepening neural pathways each time.
📅 明天继续新内容!Day 11 starts tomorrow!
Generated: 2026-03-25 | byte-by-byte Day 10 Review