← 2026-06-10 📂 All Days 2026-06-12 →

Day 63 — 系统设计 / System Design

🏗️ 系统设计 / System Design · Day 63 · Expert Phase


设计分布式锁服务 / Design a Distributed Lock Service (Zookeeper/etcd)


真实场景 / Real-World Scenario

想象你有 100 个 worker 进程,都想执行同一个定时任务(比如每天凌晨清理数据),但只能有一个执行。或者多个服务实例要更新同一份配置,必须串行化。你需要一把跨机器的锁——单机的 threading.Lock 帮不了你。

Imagine 100 worker processes all wanting to run the same cron job, but only one should. Single-machine locks are useless across a fleet — you need a lock that lives outside any one process.


核心需求 / Core Requirements

  • 互斥 / Mutual exclusion — 任意时刻只有一个持有者
  • 防死锁 / No deadlock — 持有者崩溃后锁能自动释放(TTL / ephemeral node)
  • 容错 / Fault tolerance — 协调服务本身不能是单点
  • 可重入 / 公平性(可选) — fencing token 防止过期持有者写脏数据

架构图 / Architecture

Client A Client B Client C │ │ │ └──── acquire("/lock/job") ──┘ │ ┌───────────▼────────────┐ │ Coordination Quorum │ ← Raft/ZAB consensus │ ┌────┐ ┌────┐ ┌────┐ │ │ │ L │ │ F │ │ F │ │ Leader + Followers │ └────┘ └────┘ └────┘ │ └─────────────────────────┘ Ephemeral znode / lease key with TTL

两种实现思路 / Two Approaches

Zookeeper (ephemeral sequential nodes):

每个客户端在 `/lock` 下创建一个 ephemeral sequential 节点(`lock-0001`, `lock-0002`...)。**序号最小的获得锁**。其他客户端 watch 前一个节点——避免羊群效应(herd effect)。客户端断开 → session 超时 → ephemeral 节点自动删除 → 锁释放。

etcd (lease + key):

客户端先申请一个有 TTL 的 lease,再用 Txn 原子地 "if key not exist, put key with lease"。持有者周期性 KeepAlive 续租;崩溃则 lease 过期,key 自动删除。

Zookeeper uses ephemeral sequential znodes + watch-the-predecessor to avoid the thundering herd. etcd uses a lease with TTL + a compare-and-swap transaction, with periodic keepalive.


关键权衡 / Key Tradeoffs

  • TTL 太短 → 持有者还在干活但锁被抢走;太长 → 崩溃后等很久才释放。需要 keepalive 自动续租。
  • Fencing token:Martin Kleppmann 的经典论点 — GC 暂停或网络延迟会让"持有者"以为自己还拿着锁。给每次 acquire 返回单调递增的 token,被保护的资源拒绝旧 token 的写入。没有 fencing token 的分布式锁是不安全的。

别踩这个坑 / Common Mistakes

  • ❌ 用单个 Redis SETNX 当生产级锁(无共识 → 主从切换会丢锁)。要用 Redlock,且仍有争议。
  • ❌ 忘记 fencing token,以为锁就 100% 安全。
  • ❌ 业务逻辑耗时 > TTL,锁中途失效自己却不知道。

📚 References

🧒 ELI5: 一群小朋友想玩同一个秋千。他们排队拿号码牌,号码最小的先玩。玩的人要是中途跑掉了,他的号码牌自动消失,下一个就能玩。

Day 63 — 算法 / Algorithms

💻 算法 / Algorithms · Day 63 · Expert Phase


🧩 树遍历模式 (8/15) — 在 Day 56 模版基础上进化 / Building on Template from Day 56

🔗 LeetCode #102 — Binary Tree Level Order Traversal 🟡 Medium

📹 NeetCode Video


这道题与模板的关系 / How This Maps to the Template

之前几天的树问题都用 DFS 递归模板:

def dfs(node):
    if not node: return BASE_CASE
    left = dfs(node.left)
    right = dfs(node.right)
    return COMBINE(node.val, left, right)

今天的变体:这是树遍历模式里的"另一面" — BFS 层序遍历。

当问题关心层级/距离/最短路径时,DFS 不够用,要换成 BFS + 队列。这是树模式必须掌握的第二个工具。

Today's variation flips the template: when a problem cares about levels, distance, or "closest" — switch from DFS recursion to BFS with a queue.


真实场景 / Real-World Analogy

想象公司组织架构图,你想知道"每一层级有哪些人":CEO 是第 0 层,直接下属是第 1 层,以此类推。你不会深挖一条线到底(DFS),而是一层一层横扫(BFS)。

An org chart where you list everyone level by level — CEO, then all VPs, then all directors. You sweep horizontally, not dive deep.


问题描述 / Problem

给定二叉树根节点,返回层序遍历结果:[[level0], [level1], ...],每个子列表是该层从左到右的节点值。

Return the level-order traversal: a list of lists, one per level, left to right.


核心洞察 / Key Insight

BFS 用队列,但关键技巧是:每次循环开始时记录当前队列长度 n,只处理这 n 个节点 — 它们恰好是同一层。处理完这一层,队列里剩下的就是下一层。

from collections import deque

def levelOrder(root):
    if not root:
        return []
    result = []
    queue = deque([root])
    while queue:
        n = len(queue)          # 当前层节点数 / size of this level
        level = []
        for _ in range(n):      # 只处理这一层
            node = queue.popleft()
            level.append(node.val)
            if node.left:  queue.append(node.left)
            if node.right: queue.append(node.right)
        result.append(level)
    return result

Trace (树 [3,9,20,null,null,15,7]):

  • 队列 [3] → n=1 → level [3],入队 9,20
  • 队列 [9,20] → n=2 → level [9,20],入队 15,7
  • 队列 [15,7] → n=2 → level [15,7]
  • 结果 [[3],[9,20],[15,7]] ✅

复杂度: Time O(n) 每个节点访问一次;Space O(n) 队列最多装一整层(最坏 n/2 个叶子)。


举一反三 / Connect to the Pattern Block

同一个 BFS 框架,改几行就能解:

  • #199 Right Side View — 每层取最后一个 (level[-1])
  • #1448 Count Good Nodes — BFS 时带上路径最大值
  • #116 Connect Next Right Pointers — 用同层关系串指针
  • 任何"最短路径/最近"的树/图问题 → 优先想 BFS
DFS vs BFS 选择信号: 关心"整棵子树的聚合值"→ DFS;关心"层级/最短/最近"→ BFS。

📚 References

🧒 ELI5: 像剥洋葱一样,一层一层地数树上的果子,先数最上面一排,再数下面一排。

Day 63 — 软技能 / Soft Skills

🗣️ 软技能 / Soft Skills · Day 63 · Expert Phase · Decision Making


Behavioral Question

"Tell me about a time you had to make a decision with incomplete information. How did you decide whether it was reversible?"
"讲一个你在信息不全的情况下做决策的经历。你如何判断它是否可逆?"

为什么面试官问这个 / Why Interviewers Ask This

Senior+ 工程师每天都在信息不全的情况下做决策。面试官想看:

  1. 你如何区分可逆 vs 不可逆决策 — 这决定了你该花多少时间
  2. 你是否会被"分析瘫痪"困住 — 还是能在不确定中前进
  3. 你如何控制下行风险 — 万一错了,代价多大?能不能回滚?

Interviewers want to see if you can move forward under uncertainty while controlling downside risk.


核心框架:Bezos 的"双向门" / The One-Way vs Two-Way Door

亚马逊的经典心智模型:

  • 双向门(可逆)/ Two-way door: 决策错了可以走回来。比如:加一个 feature flag、改一个配置、试一个新库。快速决策,低成本试错。 不要让这类决策走重型评审流程。
  • 单向门(不可逆)/ One-way door: 一旦走过去就回不来。比如:删除生产数据、公开 API 契约、选择数据库引擎、对外承诺。慢决策,多收集信息,多方评审。
关键 insight:大多数决策是可逆的,但我们常常错误地用对待单向门的谨慎去处理双向门,导致团队变慢。

STAR 框架分解 / STAR Breakdown

Situation: 什么决策?信息缺了哪一块?时间压力多大?

Task: 你的角色 — 是你拍板,还是你给出建议?

Action(核心):

  1. 先分类: 这是单向门还是双向门?(明确说出你的判断依据)
  2. 如果可逆: 设计安全网 — feature flag、灰度发布、可回滚的迁移。然后快速决策并执行。
  3. 如果不可逆: 列出关键未知项,定向收集信息(原型、A/B、专家咨询),设定一个"信息足够好"的停止线。
  4. 量化下行: "最坏情况是什么?能承受吗?"

Result: 决策结果 + 你后来如何验证判断对错 + 学到了什么。


❌ Bad vs ✅ Good

❌ Bad: "我们没有足够信息,所以我等了两周收集更多数据。" → 暴露了无法在不确定中行动。

✅ Good: "我判断这是个可逆决策——加个 feature flag 就能秒回滚。所以我们当天就上线灰度,用真实流量验证假设,两小时拿到数据,比讨论两周更可靠。"


Senior / Staff Tips

  • 明确说出"reversible / irreversible"这个词 — 展示你有结构化的决策心智模型
  • 强调决策速度本身也是一种成本 — 慢决策让整个团队等待
  • Staff 级别:展示你帮团队建立了这种决策文化,而不只是自己会做

Key Takeaways

  • 可逆决策 → 快、轻、本地化;不可逆决策 → 慢、重、多评审
  • 把不确定性变成"可控的下行风险",而不是行动的借口
  • 永远准备好回答:"你后来怎么知道这个决策是对的?"

📚 References

🧒 ELI5: 有些门推开还能再推回来(随便试),有些门一关就锁死(要想清楚再走)。先看清是哪种门,再决定要多小心。

Day 63 — AI

🤖 AI · Day 63 · News


本周 AI 要闻 / This Week in AI

(NEWS mode — 每条均来自下方搜索来源 / each story sourced below)


1. Anthropic 发布 Claude Fable 5,主攻科研与药物发现 / Anthropic Launches Claude Fable 5 for Drug Discovery

Anthropic 于 6 月 8 日发布 Claude Fable 5,据报道这是首个基于其高端 Mythos 5 模型、专为药物发现和科研设计的模型,声称可将药物设计的部分环节加速约十倍。发布同时引发争议:其"安全护栏"会把涉及生物武器、网络攻击等敏感查询自动转路由到一个旧模型,Anthropic 称此举是为防止滥用。

Claude Fable 5 (June 8) targets drug discovery, reportedly ~10x faster on parts of drug design. Controversial "safeguards" reroute sensitive (bioweapon/cyber) queries to an older model.

🔗 pharmaphorum.com


2. 微软 Build 2026 发布 MAI 系列模型 / Microsoft Ships MAI Models at Build 2026

微软在 Build 2026 发布多款自研 MAI 模型,包括 MAI-Thinking-1(6/1)——一个聚焦推理的稀疏 MoE 模型,据报道有约 350 亿激活参数、256K token 上下文窗口;以及 MAI-Code-1-Flash(6/1)这一快速代码模型。均通过 Azure AI Foundry 及第三方平台提供。

Microsoft's MAI-Thinking-1 (reasoning, sparse MoE, ~35B active params, 256K context) and MAI-Code-1-Flash, both via Azure AI Foundry.

🔗 llm-stats.com/llm-updates


3. NVIDIA 公布 Nemotron 3 Ultra — 最大开源权重模型 / NVIDIA Announces Nemotron 3 Ultra

NVIDIA 于 6 月 2 日公布 Nemotron 3 Ultra,据报道是一个 5500 亿参数的开源 MoE 模型,采用超高效的 4-bit NVFP4 训练,上下文窗口最高达 1M token。NVIDIA 称这是其迄今最大的开源权重模型。

Nemotron 3 Ultra: reportedly a 550B-param open MoE, 4-bit NVFP4 training, up to 1M-token context — NVIDIA's largest open-weight model to date.

🔗 medium.com/nlplanet


4. 开源模型动态 / Open-Source Roundup

  • Dnotitia DNA 3.0(6/5)— 开源 LLM 家族,参数从 0.8B 到 122B
  • Google Gemma 4 QAT checkpoints(6/5)— 面向边缘设备的量化部署优化检查点
  • Google DiffusionGemma 26B-A4B(6/9)— 扩散式语言模型开源发布

🔗 llm-stats.com/llm-updates


💡 给后端工程师的 takeaway / Takeaway for Backend Engineers

本周主题:MoE + 长上下文 + 低比特训练正成为标配。NVFP4 / QAT 这类量化技术让"大模型也能在边缘/低成本硬件跑"从概念走向产品。如果你在做推理基础设施,关注 4-bit 量化推理栈和 MoE 路由的负载均衡——这是接下来一年部署成本优化的主战场。


🧒 ELI5: 这周几家大公司都拿出了新的"AI 大脑":有的专门帮科学家造药,有的特别会写代码,还有的特别大但能塞进小盒子里跑。