📊 Day 115 — 复习日 / Review Day
NeetCode: 90/150 · SysDesign: 60/40 · Behavioral: 60/40 · Frontend: 37/50 · AI: 30/30
🔥 2-day streak!
🔄 复习日 / Review Day
今天是复习日!回顾过去4天的内容。
(Day 115 is review day — let's consolidate Days 111–114!)
📝 Quick Quiz — 3 Mini-Reviews
Q1: [💻 Algorithms — Course Schedule / 拓扑排序]
You have numCourses courses and a list of prerequisites [a, b] meaning "must take b before a." Write the condition under which it's impossible to finish all courses — and explain why topological sort works here.
<details><summary>显示答案 / Show Answer</summary>
It's impossible when the prerequisite graph contains a cycle — meaning some courses mutually depend on each other (e.g., A requires B, B requires C, C requires A). Topological sort (BFS/Kahn's algorithm) works because it processes nodes with in-degree 0 first (no prerequisites), then reduces in-degrees of neighbors. If the queue runs out before all courses are processed, a cycle exists.
Key insight: if processed_count < numCourses → return False. Time: O(V+E).
</details>
Q2: [🐍 Python Craft — Cryptography Basics]
什么时候用 bcrypt 而不是 hashlib.sha256?为什么用 hashlib 存密码是危险的?
(When do you use bcrypt vs hashlib.sha256? Why is hashlib dangerous for passwords?)
<details><summary>显示答案 / Show Answer</summary>
Use bcrypt for passwords; use hashlib (SHA-256/SHA-3) for data integrity checks, tokens, and non-secret hashing.
hashlib is dangerous for passwords because it's designed to be fast — an attacker can compute billions of SHA-256 hashes per second with a GPU. bcrypt is intentionally slow (cost factor = 2^n rounds), making brute-force attacks computationally prohibitive. It also automatically handles salting to prevent rainbow table attacks.
</details>
Q3: [💻 Algorithms — Number of Connected Components / Graph Valid Tree]
Given n nodes and a list of edges, how do you determine the number of connected components using Union-Find? What's the key invariant you maintain?
<details><summary>显示答案 / Show Answer</summary>
Initialize n components (each node is its own root). For each edge (u, v), find the roots of both nodes — if they differ, union them and decrement the component count by 1. Final answer = component count.
parent = list(range(n))
components = n
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]] # path compression
x = parent[x]
return x
for u, v in edges:
ru, rv = find(u), find(v)
if ru != rv:
parent[ru] = rv
components -= 1
Key invariant: two nodes are in the same component iff they share the same root. For Graph Valid Tree: valid tree iff components == 1 AND len(edges) == n - 1 (no cycles).
</details>
💡 复习巩固记忆,螺旋式上升。Review locks in memory — knowledge compounds.
📅 明天继续新内容!Back to new content tomorrow!