← 2026-04-19 📂 All Days 2026-04-21 →

📊 NeetCode: 23/150 · SysDesign: 22/40 · Behavioral: 22/40 · Frontend: 22/50 · AI: 11/30

🔥 1-day streak!

🏗️ 系统设计 / System Design

设计新闻流(Twitter / Facebook)/ Design a News Feed

1) 场景 / Scenario

想象你在做一个社交 App:

  • 用户关注很多人
  • 打开首页要看到“关注的人最新动态”(按时间倒序)
  • 需要:快速打开、可无限下拉、支持发帖/删帖、支持隐私(拉黑/仅好友)

You’re building a social app:

  • Users follow many accounts
  • Home timeline shows recent posts from followees (reverse chronological)
  • Requirements: fast load, infinite scroll, post/delete, privacy (blocks / friends-only)

2) 关键 API / Core APIs

  • POST /posts 创建动态 / create post
  • POST /follow 关注 / follow
  • GET /feed?cursor=... 拉取首页流 / fetch feed
  • DELETE /posts/{id} 删除动态 / delete

3) 两种主流方案 / Two common approaches

A. Fanout-on-write(写入时推送)

发帖时把这条 post “复制/投递”到所有粉丝的 inbox/feed 存储。

Pros:

  • 读快:GET /feed 只扫自己的 inbox

Cons:

  • 写放大:大 V 发帖会写爆
  • 需要异步队列 + 回压

B. Fanout-on-read(读取时拉取)

读首页时:查自己关注列表 → 拉取每个关注者的最近 posts → 合并排序(k-way merge)。

Pros:

  • 写轻:发帖只写一份

Cons:

  • 读慢:关注很多人时合并开销大
  • 需要缓存/预计算

现实里通常是 混合:普通用户 fanout-on-write;大 V / 名人用 fanout-on-read 或“部分推送”。

In practice it’s hybrid: push for normal users; pull (or partial push) for celebrities.


4) 推荐架构(混合)/ Suggested architecture (Hybrid)

+-------------------+ Client -->| API Gateway | +---------+---------+ | +---------v---------+ | Feed Service |<-------------------+ +----+---------+----+ | | | | (read path) | | (write path) | | v | +------v--+ +--+----------------+ | | Cache | | Post Service | | | (Redis) | +--+----------------+ | +----+----+ | | | v | | +-----+------+ | | | Post Store | (Cassandra/LSM) | | +-----+------+ | | | | | v | | +-----+------+ +-----------+--------+ | | MQ / Log |----->| Fanout Workers | | | (Kafka) | | (async push) | | +------------+ +-----------+--------+ | | | v | +---------+--------+ +-------------------------->| Inbox Store | | (per user feed) | +------------------+

关键点 / Key ideas:

  • Post Store:存权威 post(可按 authorId + time 索引)
  • Inbox Store:每个用户一个“收件箱时间线”(只存 postId + ts + authorId)
  • MQ:解耦发帖与推送;可重放、可扩容
  • Cache:热点用户首页、关注列表、作者最新 posts

5) 读路径 / Read path (GET /feed)

  1. 先查 Redis:是否有缓存的第一页(或 cursor 对应页)
  2. 没命中:从 Inbox Store 取 N 条(按时间倒序),拿到 postIds
  3. 批量去 Post Store / Cache 取 post 内容(MGET / batch)
  4. 过滤隐私(block / friends-only)并返回

Cursor 设计:用 (lastTimestamp, lastPostId) 做稳定翻页,避免 offset 分页在插入/删除时乱跳。


6) 写路径 / Write path (POST /posts)

  1. 写入 Post Store(生成 snowflake/UUID)
  2. 投递事件到 Kafka:PostCreated(postId, authorId, ts)
  3. Fanout worker:

- 取 author 的 followers

- 对普通作者:批量写入 followers 的 Inbox Store

- 对大 V:不 fanout(只写作者自己的 “author timeline”)


7) 关键取舍 / Key tradeoffs

  • 读延迟 vs 写放大:push 读快但写爆;pull 写轻但读慢
  • 一致性:首页允许 eventual consistency(秒级延迟可接受)
  • 存储成本:inbox 只存指针(postId),否则成本爆炸
  • 名人策略:按 follower 数阈值切换策略(并动态调整)

8) 常见坑 / Common mistakes

  • 只做 fanout-on-write:遇到“大 V”直接写入风暴
  • Inbox 存全量 post 内容:重复数据导致存储/回填困难
  • 用 offset 分页:新帖插入后翻页错乱、重复/漏读
  • 忽视隐私与删除:需要支持“撤回/删除”传播(tombstone + read-time filter)

🧒 ELI5

把新闻流想成“报纸投递”:

  • 推送:作者一发文章,就把报纸送到每个订阅者门口(读很快,但送货很累)。
  • 拉取:你想看时自己去每个作者家门口拿最新报纸,再拼成一份(写很轻,但你得跑很多家)。

所以现实里:普通作者直接投递;大明星让你来取。


📚 References

  • https://www.hellointerview.com/learn/system-design/answer-keys/design-twitter
  • https://www.hellointerview.com/learn/system-design/answer-keys/design-facebook-news-feed
  • https://kafka.apache.org/documentation/

📊 NeetCode: 23/150 · SysDesign: 22/40 · Behavioral: 22/40 · Frontend: 22/50 · AI: 11/30

🔥 1-day streak!

💻 算法 / Algorithms — #22 Generate Parentheses (Medium) — Stack

🧩 Stack (4/7) — building on the template from Day 1

今天这题和“括号匹配 / Valid Parentheses”同属一类:用栈表示“当前还没闭合的结构”。不同点是:

  • Valid Parentheses 是“验证”
  • Generate Parentheses 是“生成所有合法结果”

Today is in the same family as Valid Parentheses: use a stack to represent “currently open structures”. Difference:

  • Valid Parentheses = verify
  • Generate Parentheses = generate all valid sequences

🔗 LeetCode: https://leetcode.com/problems/generate-parentheses/ 🟡

📹 NeetCode: https://www.youtube.com/watch?v=s9fokUqJ76A


1) 现实类比 / Real-world analogy

把它想成写代码时的“自动补全括号”功能:你打了 (,编辑器知道你欠一个 );但为了不出错,任何时候都不能让 ) 的数量超过 (。

Think of an editor auto-completing parentheses: every ( creates a debt of ); you can never close more than you opened.


2) 问题重述 / Restate

给定 n 对括号,生成所有长度 2n 的字符串,使得任意前缀里 ( 数量 ≥ ) 数量,且最终 ( == )。

Given n pairs, generate all length-2n strings such that for every prefix, opens ≥ closes, and total opens == closes.


3) 映射到模式 / Map to the pattern

这里的“栈”不一定真的要存字符(也可以只用计数),关键是它代表:

  • stack 里有多少个“还没关掉的左括号”

So the “stack” conceptually is the number of unmatched (.

生成规则(约束驱动):

  • 还能放 (:当 open < n
  • 还能放 ):当 close < open(否则会出现非法前缀)

4) Python 解法(回溯 + 栈含义)/ Python solution (Backtracking)

from typing import List

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        res: List[str] = []

        def dfs(open_cnt: int, close_cnt: int, path: List[str]) -> None:
            # open_cnt: number of '(' used
            # close_cnt: number of ')' used
            # stack size == open_cnt - close_cnt (unmatched opens)
            if open_cnt == n and close_cnt == n:
                res.append(''.join(path))
                return

            # Option 1: add '(' if we still can
            if open_cnt < n:
                path.append('(')
                dfs(open_cnt + 1, close_cnt, path)
                path.pop()

            # Option 2: add ')' only if it won't break validity
            if close_cnt < open_cnt:
                path.append(')')
                dfs(open_cnt, close_cnt + 1, path)
                path.pop()

        dfs(0, 0, [])
        return res

小 trace / Mini trace (n=3)

  • start: open=0 close=0 path=""
  • add "(": open=1 close=0 path="("
  • add "(": open=2 close=0 path="(("
  • add ")": open=2 close=1 path="(()" ✅(因为 close < open)
  • ...

核心:任何时刻都保证 close_cnt <= open_cnt,这等价于“栈从不变成负数”。

Key: maintain close_cnt <= open_cnt always (stack never negative).


5) 复杂度 / Complexity

  • 时间:输出规模主导,结果数是第 n 个 Catalan 数 C_n,大约 O(C_n * n)(每个字符串长度 2n)
  • 空间:递归深度 O(n) + 输出

Time is output-dominated: ~O(C_n * n). Space O(n) (excluding output).


6) 举一反三(同一模式块)/ Transfer (same pattern block)

  • #20 Valid Parentheses:栈匹配(验证)
  • #150 Evaluate RPN:栈求值(表达式)
  • #739 Daily Temperatures:单调栈(找下一个更大元素)
  • #84 Largest Rectangle:单调栈(结算区间)

同一个“Stack”家族里,核心都是:把“未完成的东西”压栈,遇到触发条件就出栈结算。

Across the Stack family, the idea is: push unfinished work, pop when a condition resolves it.


🧒 ELI5

你在搭积木:

  • 放 ( 就像搭一层楼
  • 放 ) 就像关掉一层楼

规则是:你不能先关楼再建楼,所以 ) 只能在已经有没关的 ( 时出现。

Like building floors: you can’t close a floor that wasn’t opened.


📚 References

  • https://leetcode.com/problems/generate-parentheses/
  • https://neetcode.io/problems/generate-parentheses
  • https://en.wikipedia.org/wiki/Catalan_number

📊 NeetCode: 23/150 · SysDesign: 22/40 · Behavioral: 22/40 · Frontend: 22/50 · AI: 11/30

🔥 1-day streak!

🗣️ 软技能 / Soft Skills

如何在新团队建立信任?/ How do you build trust with a new team?

为什么重要 / Why this matters

中文:在新团队里,信任不是“人好就有”,而是一个降低协作摩擦的系统:大家相信你会按时交付、沟通透明、在关键时刻站得住。

English: Trust reduces coordination cost. People rely on you to deliver, communicate clearly, and act predictably under pressure.


STAR 拆解 / STAR breakdown

S (Situation)

中文:刚加入团队/跨组接手一个服务,代码和 ownership 都不熟,大家担心你会“乱改”。

English: You join a new team or inherit a service; ownership is unclear and people fear risky changes.

T (Task)

中文:在不打扰团队节奏的前提下,快速形成可靠产出,并让关键同事愿意与你协作。

English: Become productive without disrupting flow, and earn collaboration from key partners.

A (Action)

中文(可直接照着说,偏 Senior/Staff):

  1. 先对齐“成功定义”:1:1 问清楚本季度最重要的指标、风险点、谁是决策者。
  2. 用小而稳的交付建立信用:先做一两个低风险改动(修 bug、补监控、改善 oncall runbook),在 PR 里解释“为什么”。
  3. 默认透明:写 short design doc / RFC,记录 tradeoff;在 standup 里讲进展 + 阻塞 + 下一步。
  4. 让别人更容易跟你合作:缩短 review turnaround;把复杂问题拆成可并行的 task;把“需要谁决定什么”写清楚。
  5. 遇到问题先扛责再复盘:出事故时先稳定系统、同步影响面,再做 blameless postmortem。

English:

  1. Align on what “success” means (metrics, risks, decision makers).
  2. Build credibility with small, low-risk wins (bugfixes, monitoring, runbooks) and explain the “why” in PRs.
  3. Default to transparency (short RFCs, tradeoffs, steady status updates).
  4. Make collaboration easy (fast reviews, parallelizable tasks, explicit decisions needed).
  5. In incidents: stabilize first, communicate clearly, then run a blameless postmortem.

R (Result)

中文:你会得到两类信任:

  • 执行力信任(你说到做到)
  • 判断力信任(你做的选择是靠谱的)

English: You earn both execution trust (you deliver) and judgment trust (your decisions are sound).


❌ Bad vs ✅ Good(示例回答对比)/ Bad vs Good

❌ 中文:

“我会多和大家沟通,努力融入团队。”(太空、不可验证)

✅ 中文:

“前两周我先做两件事:补齐关键指标监控 + 写 oncall runbook,并在每个 PR 里把风险和 rollback 写清楚。第三周开始我会发一个 1 页的 feed latency 优化 RFC,列出 2 个方案和 tradeoff,请 tech lead 做决策。”

❌ English:

“I communicate a lot and try to fit in.” (vague)

✅ English:

“In the first two weeks I shipped monitoring + an oncall runbook, and every PR included risk + rollback. In week three I proposed a 1-page latency RFC with two options and tradeoffs for the TL to decide.”


Senior / Staff 加分点 / Senior/Staff tips

  • 中文:把信任当成 SLO:可预测的节奏(updates、designs、rollbacks)就是可靠性。
  • 中文:用“决策日志”建立判断力:记录你为什么选 A 不选 B,半年后复盘你是否在提升。
  • English: Treat trust like an SLO: predictable cadence beats charisma.
  • English: Keep a decision log to demonstrate and improve judgment.

Key Takeaways

  • 中文:信任=可预测 + 透明 + 稳定交付。
  • 中文:先小胜建立信用,再啃硬骨头。
  • English: Trust = predictability + transparency + delivery.
  • English: Start with small wins, then tackle the hard problems.

🧒 ELI5

中文:你刚加入新班级,大家不认识你。你先按时交作业、说话算数、遇到问题会解释清楚,大家自然就信你。

English: In a new class, you earn trust by doing what you say, on time, and explaining things clearly.


📚 References

  • https://staffeng.com/guides/staff-archetypes/
  • https://www.pmcouncil.org/insights/psychological-safety/
  • https://hbr.org/2019/01/the-fundamental-attribution-error

📊 NeetCode: 23/150 · SysDesign: 22/40 · Behavioral: 22/40 · Frontend: 22/50 · AI: 11/30

🔥 1-day streak!

🎨 前端 / Frontend

Closures & Lexical Scope — JS Interview Classic

场景 / Scenario

中文:你在做一个 dashboard,需要给每一行渲染一个“重试 / Retry”按钮。点击时要带上该行的 rowId。如果你不小心写错闭包,你可能会发现:不管点哪个按钮,拿到的都是同一个 rowId(通常是最后一个)。

English: You’re building a dashboard with a “Retry” button per row. If you misuse closures, every button can end up using the same rowId (often the last one).


核心概念 / Core idea

中文:

  • 词法作用域(lexical scope):变量能否被访问,取决于代码“写在哪里”,不是“从哪里调用”。
  • 闭包(closure):函数 + 它创建时捕获的外部变量环境。

English:

  • Lexical scope: what you can access depends on where code is written, not where it’s called.
  • Closure: a function plus the environment it captured when created.

代码示例 / Code snippet

// The closure captures `rowId`.
export function makeRetryHandler(rowId: string) {
  return async function onRetryClick() {
    // Comments in English
    await fetch(`/api/retry?rowId=${encodeURIComponent(rowId)}`, { method: 'POST' });
  };
}

// Usage (e.g., inside a component render)
const handler = makeRetryHandler(row.id);

中文:makeRetryHandler 返回的内部函数,会把 rowId “记住”。这就是闭包。

English: The inner function “remembers” rowId — that’s a closure.


猜猜输出什么?/ Quiz (A/B/C/D)

const fns: Array<() => number> = [];
for (var i = 0; i < 3; i++) {
  fns.push(() => i);
}
console.log(fns[0](), fns[1](), fns[2]());

A) 0 1 2

B) 3 3 3

C) 0 0 0

D) 抛异常 / throws

答案 / Answer: B

中文解释:var 是函数作用域,循环结束后 i 变成 3;三个函数闭包捕获的是“同一个 i”。

English: var is function-scoped; after the loop i === 3, and all closures reference the same i.


常见错误 vs 正确写法 / Common mistake vs correct

❌ 错误(捕获同一个变量)/ Wrong:

const fns: Array<() => number> = [];
for (var i = 0; i < 3; i++) {
  fns.push(() => i);
}

✅ 正确 1:用 let(块级作用域)/ Correct 1: use let:

const fns: Array<() => number> = [];
for (let i = 0; i < 3; i++) {
  fns.push(() => i);
}

✅ 正确 2:用工厂函数制造新作用域 / Correct 2: scope factory:

const fns: Array<() => number> = [];
for (var i = 0; i < 3; i++) {
  const fn = ((x: number) => () => x)(i);
  fns.push(fn);
}

什么时候用 / 什么时候别用 / When to use / when NOT to

中文(实战判断):

  • ✅ 用闭包:

- 你需要“绑定参数”给回调(事件处理、定时器、重试函数、日志上下文)

- 你需要封装内部状态(不想暴露成全局/类字段)

  • ❌ 小心闭包:

- 在热路径里创建大量闭包(每次 render 都 new 很多函数)→ 可能导致子组件重复渲染

- 闭包捕获了会变化的大对象(例如 props/state 的整个对象)→ 容易产生“旧值 / stale value”问题

English (practical):

  • ✅ Use closures to bind parameters to callbacks or to encapsulate private state.
  • ⚠️ Be careful when creating tons of closures on hot render paths, or capturing changing objects that can cause stale values.

小提示(React/TS 实战)/ React/TS production tip

中文:如果你把 handler 传给 React.memo 子组件,并且不想每次 render 都变引用:

  • 用 useCallback,并确保依赖是最小的(不要把整个对象塞进去)。

English: If passing handlers to memoized children, use useCallback with minimal dependencies.


🧒 ELI5

中文:闭包就像你把一个小纸条(变量)塞进函数口袋里。以后不管函数走到哪儿,都能掏出纸条看。

English: A closure is a function carrying a note in its pocket.


📚 References

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
  • https://developer.mozilla.org/en-US/docs/Glossary/Lexical_scope
  • https://react.dev/reference/react/useCallback

📊 NeetCode: 23/150 · SysDesign: 22/40 · Behavioral: 22/40 · Frontend: 22/50 · AI: 11/30

🔥 1-day streak!

🤖 AI 动态 / AI News


📰 本周 AI 要闻 / This Week in AI

1. Sergey Brin:Google 要向 Anthropic 的编码智能体学习

据报道,Google 联合创始人 Sergey Brin 在内部备忘录中写道,Google 工程师必须强制使用内部 AI 智能体完成复杂任务,因为 Anthropic 的编码工具目前领先。他还暗示,赶上 Anthropic 是迈向"AI 自我改进"的一步。

According to reports, Google co-founder Sergey Brin wrote in an internal memo that every Gemini engineer "must be forced to use internal agents for complex, multistep tasks." Brin reportedly said Anthropic's coding tools are currently leading the race, and catching up is a step toward building AI that can improve itself.

🔗 The Verge · The Information原报道


2. Anthropic 发布 Claude Design(Opus 4.7 驱动)

Anthropic 推出 Claude Design,基于最新的 Opus 4.7 模型,允许用户创建设计稿、原型、Pitch Deck 和营销素材。目前在付费用户中以研究预览版开放。

Anthropic launched Claude Design — powered by Claude Opus 4.7 — letting users create designs, prototypes, pitch decks, and marketing materials. Available in research preview for paying subscribers.

🔗 The Verge 报道


3. AI 影响力账号涌入社交媒体

据纽约时报调查,Instagram、TikTok、Facebook 上出现了数百个 AI 生成的假账号,疑似服务于政治目的。随着 AI 生成头像的成本大幅降低,批量创建虚假影响力账号变得前所未有的容易。

The New York Times found hundreds of AI-generated fake accounts across Instagram, TikTok, and Facebook, reportedly pushing political messaging. Experts note that creating such avatars is increasingly cheap and easy, with entire contractor networks specializing in bulk AI avatar deployment.

🔗 The Verge 报道


🧒 ELI5

AI 这周:Google 承认落后了,Anthropic 出了个"AI 设计师",社交媒体上 AI 假人越来越多也越来越便宜。

Google admitted it's behind on AI coding agents, Anthropic shipped an AI designer tool, and fake AI social media accounts are getting cheaper and easier to deploy at scale.

📚 References:

  • https://www.theverge.com/ai-artificial-intelligence
  • https://www.theinformation.com/articles/google-creates-strike-team-improve-coding-models