← 2026-05-27 📂 All Days 2026-05-29 →

🏗️ 系统设计 / System Design — Day 44

Design a Feature Flag System (LaunchDarkly)

**难度 / Difficulty:** Advanced | **阶段 / Phase:** Expert | **用时 / Time:** ~3 min

真实场景 / Real-World Scenario

想象你在 Meta 负责一个每天服务 30 亿用户的 News Feed 系统。你要上线一个全新的推荐算法 — 但你不敢直接全量发布:万一出了 Bug,全球用户都受影响。

你需要的是功能开关 (Feature Flag):先放 0.1% 的流量,再 1%,再 10%... 一旦出问题立即关闭,零停机回滚。

Imagine you're at Meta, responsible for a News Feed serving 3 billion daily users. You're shipping a new recommendation algorithm — but you can't just deploy it to everyone at once. If it breaks, the entire world is affected.

You need Feature Flags: start at 0.1% traffic, then 1%, then 10%... and kill it instantly if anything goes wrong. Zero-downtime rollback.


系统架构 / Architecture

┌────────────────────────────┐ │ Admin Dashboard │ │ (Create/Edit/Target Flags) │ └────────────┬───────────────┘ │ Config Changes ┌────────────▼───────────────┐ │ Flag Control Plane │ │ - Flag CRUD API │ │ - Targeting Rules Engine │ │ - Audit Log │ └────────────┬───────────────┘ │ Write ┌──────────────────▼──────────────────┐ │ PostgreSQL │ │ (flags, rules, environments, users) │ └──────────────────┬──────────────────┘ │ CDC / PubSub ┌──────────────────▼──────────────────┐ │ Redis (Flag Cache) │ │ flag_key → {rules, rollout%} │ └────┬─────────────────────────┬───────┘ │ SSE/Long Poll │ ┌─────────▼────────┐ ┌──────────▼────────┐ │ SDK (Server) │ │ SDK (Browser) │ │ Node / Python │ │ React / Next │ └─────────┬────────┘ └──────────┬────────┘ │ │ ┌─────────▼───────────────────────────▼───────┐ │ Your Application │ │ if (flags.isEnabled("new_algo", userId)): │ │ return new_recommendation() │ └──────────────────────────────────────────────┘

核心概念 / Key Concepts

1. Flag 评估 (Evaluation)

每次 isEnabled(flagKey, user) 调用要极快 — 不能每次都打数据库。

SDK 在本地内存缓存全部 flag 规则,通过 SSE/WebSocket 接收增量更新。

Every isEnabled(flagKey, user) call must be extremely fast — no DB lookups per call.

The SDK caches all flag rules in-memory and receives incremental updates via SSE/WebSocket.

2. 灰度策略 / Targeting Rules (in priority order)

Rule 1: userId in ["user_123", "user_456"] → true (内测用户/beta users) Rule 2: country == "US" AND email ends with "@company.com" → true (内部员工/internal) Rule 3: rollout = 10% (hash(userId) % 100 < 10) → true (随机灰度/random rollout) Rule 4: default → false

3. 一致性哈希灰度 / Consistent Rollout

用 hash(userId + flagKey) % 100 而非 random() — 保证同一用户每次看到相同结果。

Use hash(userId + flagKey) % 100 not random() — ensures the same user always gets the same result.

import hashlib

def should_enable(user_id: str, flag_key: str, rollout_pct: int) -> bool:
    # Deterministic: same user always gets same result
    seed = f"{user_id}:{flag_key}"
    hash_val = int(hashlib.md5(seed.encode()).hexdigest(), 16)
    return (hash_val % 100) < rollout_pct

为什么这样设计?/ Key Tradeoffs

决策 / Decision原因 / Why
SDK 本地缓存 rulesP99 评估 <1ms;无单点故障
SSE 推送更新实时性 <100ms;比轮询更高效
hash(userId+flagKey)跨服务一致性;可复现
按环境隔离prod/staging/dev 互不干扰
审计日志合规;回溯事故 "谁在什么时候改了什么"

别踩这个坑 / Common Mistakes

❌ 坑 1: Flag 永不清理

Feature flags 是技术债。很多公司有数千个"废弃"flag 还在代码里。

建立 TTL 机制:flag 超过 90 天自动提醒清理。

Feature flags are tech debt. Many companies have thousands of "dead" flags still in code.

Build TTL: auto-alert to clean up flags older than 90 days.

❌ 坑 2: 把 flag 用作配置系统

Feature flags ≠ 配置管理。不要把数据库连接字符串、超时时间放进 flag。

用专门的配置系统 (AWS AppConfig, Consul)。

Feature flags ≠ config management. Don't put DB connection strings or timeouts in flags.

Use dedicated config systems (AWS AppConfig, Consul).

❌ 坑 3: Flag 评估打数据库

每次请求都去 DB 查询 flag = 系统瘫痪。必须本地缓存 + 增量推送。

Evaluating flags against DB on every request = system meltdown. Must use local cache + push updates.


扩展问题 / Follow-up Questions

  • 如何支持 A/B/C 多变量测试?(multivariate flags)
  • 如何实现 flag 依赖关系?(flag A 必须先开启 flag B 才能生效)
  • 怎么做 flag 评估的可观测性?(哪些用户看到了哪个变体?)

📚 References

🧒 ELI5

Feature flags 就像给代码装了"电灯开关"。你把新功能写好但先关着,然后可以只给自己、或者1%的用户开灯试试,不满意就关掉——完全不用重新部署。

Feature flags are like installing light switches in your code. You write the new feature but keep it "off", then flip it on for just yourself, or 1% of users. If something's wrong, flip it off instantly — no redeployment needed.

💻 算法 / Algorithms — Day 45

#25 Reverse Nodes in K-Group — Hard

模式 / Pattern: 链表技巧模式 (Linked List) | 11/11 — 最终章!


🧩 链表技巧模式 (11/11) — 本模式最后一题!

Building on the template from Day 41 (Reverse Linked List)

这是链表模块的压轴 Hard 题。回顾一下我们走过的路:

#题目核心技巧
1Reverse Linked List迭代/递归反转
2Merge Two Sorted Lists双指针合并
3Linked List Cycle快慢指针
4Reorder List找中点 + 反转 + 合并
5Remove Nth from End双指针间距 n
6Copy List with Random PointerHashMap 映射
7Add Two Numbers模拟进位
8Find the Duplicate NumberFloyd 判圈
9LRU Cache双向链表 + HashMap
10Merge K Sorted Lists堆/分治
11Reverse Nodes in K-Group分组反转 ← 今天

🔗 题目链接 / Links

  • 🟥 LeetCode: https://leetcode.com/problems/reverse-nodes-in-k-group/
  • 📹 NeetCode: https://neetcode.io/problems/reverse-nodes-in-k-group

现实类比 / Real-World Analogy

想象一队士兵 [1,2,3,4,5,6],每 k=2 人一组,原地调换站位:

[2,1,4,3,6,5]

就像 撤销/重做历史 的批量反转操作 — 每次撤销 k 步,顺序倒转。

Imagine a line of soldiers [1,2,3,4,5,6]. Every k=2, reverse their positions: [2,1,4,3,6,5].

Like a batch undo operation — reverse every k operations at once.


问题分析 / Problem Breakdown

Input: 1 → 2 → 3 → 4 → 5, k=2 Output: 2 → 1 → 4 → 3 → 5 Input: 1 → 2 → 3 → 4 → 5, k=3 Output: 3 → 2 → 1 → 4 → 5

难点:

  1. 如何检查剩余节点是否有 k 个?
  2. 如何记录反转前后的连接点?

如何映射到模式 / Mapping to Template

这题不直接用快慢指针,但用的是链表反转的核心操作——这是模式的变体:

标准模版:slow/fast 指针
本题变体:
  1. 用辅助函数检查是否还有 k 个节点 (类似 fast 指针向前探路)
  2. 每次反转 k 个节点 (核心操作与 #206 相同)
  3. 用 dummy head 统一处理边界

Python 解法 / Solution with Trace

from typing import Optional

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def reverseKGroup(head: Optional[ListNode], k: int) -> Optional[ListNode]:
    dummy = ListNode(0, head)
    group_prev = dummy  # tail of the last reversed group
    
    while True:
        # Step 1: Check if k nodes remain (like fast pointer scouting ahead)
        kth = get_kth(group_prev, k)
        if not kth:
            break  # fewer than k nodes left — keep as-is
        
        group_next = kth.next  # node AFTER this k-group
        
        # Step 2: Reverse k nodes (same as #206 Reverse Linked List!)
        prev, curr = group_next, group_prev.next
        while curr != group_next:
            tmp = curr.next
            curr.next = prev
            prev = curr
            curr = tmp
        
        # Step 3: Re-link
        # group_prev.next is still pointing to OLD head of group (now tail)
        tmp = group_prev.next  # old head = new tail
        group_prev.next = kth  # connect prev group to new head (kth)
        group_prev = tmp        # advance group_prev to new tail
    
    return dummy.next


def get_kth(curr: ListNode, k: int) -> Optional[ListNode]:
    """Advance k steps from curr; return None if not enough nodes."""
    while curr and k > 0:
        curr = curr.next
        k -= 1
    return curr

执行追踪 / Trace (k=2, [1,2,3,4])

初始: dummy → 1 → 2 → 3 → 4 ↑ ↑ group_prev 轮1: kth=node(2), group_next=node(3) 反转 [1,2]: 2 → 1 → 3 → 4 dummy → 2 → 1 → 3 → 4 ↑ group_prev 轮2: kth=node(4), group_next=None 反转 [3,4]: 4 → 3 → None dummy → 2 → 1 → 4 → 3 ↑ group_prev 轮3: get_kth 返回 None → break 结果: 2 → 1 → 4 → 3 ✓

复杂度 / Complexity

  • 时间 Time: O(n) — 每个节点最多访问两次 (一次 get_kth,一次 reverse)
  • 空间 Space: O(1) — 原地操作,只用常数额外指针

举一反三 / Pattern Connection

学完整个链表模块,这道 Hard 题其实是 #206 (反转链表) + #141 (快慢指针探路) 的组合:

  • get_kth = 快指针向前探 k 步
  • 内层反转 = 完全复用 #206 的代码
  • 核心洞察:Hard 题往往是多个 Easy 技巧的组合

After the full linked list block, this Hard problem is literally #206 + #141 combined:

  • get_kth = fast pointer scouting k steps ahead
  • Inner reversal = exact same code as #206
  • Key insight: Hard problems are often compositions of Easy techniques

📚 References

🧒 ELI5

给一排玩具按每 k 个一组,把每组里面的顺序倒过来。比如 k=3,[1,2,3,4,5,6] 变成 [3,2,1,6,5,4]。秘诀是先看看够不够 k 个,够的话就原地翻转,然后把各组拼在一起。

Given a row of toys, reverse every k of them. k=3: [1,2,3,4,5,6] → [3,2,1,6,5,4]. The trick: check if k nodes exist, reverse them in place, stitch the groups together.

🗣️ 软技能 / Soft Skills — Day 44

Tell me about a time you had to recover from a major mistake you made

**类别 / Category:** Failure & Growth | **级别 / Level:** Senior/Staff | **用时 / Time:** ~2 min

为什么这道题很重要 / Why This Question Matters

面试官问这道题不是要看你多完美 — 他们要看的是:

  1. 你的自我认知 — 你能正视自己的失误吗?
  2. 你的成熟度 — 遇到问题你是逃避还是承担?
  3. 你的成长能力 — 你从失败中学到了什么?
  4. 你的影响力 — Senior 工程师的错误往往影响整个团队

Interviewers ask this not to see how perfect you are — they want to know:

  1. Self-awareness — can you own your mistakes honestly?
  2. Maturity — do you deflect or take responsibility?
  3. Growth mindset — what did you actually learn?
  4. Scope of impact — Senior mistakes often affect whole teams

STAR 框架 / STAR Breakdown

❌ 反面示例 / Bad Answer

"我在 deploy 的时候忘了跑测试,导致了一个 bug。我们回滚了,然后加了 CI 检查。"

问题:

  • 错误太小,不像 Senior 级别
  • 没有说明自己的具体责任
  • 学到的东西太表面("加了 CI")
  • 面试官会觉得你在隐瞒

✅ 正面示例 / Good Answer

Situation(情境):

"两年前我主导了一个数据库 Schema 迁移。这是一个高流量的核心服务,每天处理约 500 万次写入。"
"Two years ago I led a database schema migration for a high-traffic core service — about 5M writes per day."

Task(任务):

"我的任务是在零停机时间内完成迁移,同时保证数据一致性。"
"My goal was zero-downtime migration while maintaining data consistency."

Action(失误 + 应对):

"我低估了一个细节:新字段有 NOT NULL 约束,但我们有一个后台 job 还在往老 Schema 写入。上线后 5 分钟,报警开始响。我立刻 declare incident,把相关的 5 名工程师拉进来。我做了两件事:一是立刻临时修改约束为 nullable 止血,二是写了一个 backfill script 把历史数据修正。整个 incident 持续了 47 分钟。"
"I underestimated one thing: the new column had a NOT NULL constraint, but a background job was still writing to the old schema. Five minutes after deploy, alerts fired. I immediately declared an incident, pulled in 5 engineers. Two actions: first, temporarily relax the constraint to nullable to stop the bleeding; second, write a backfill script to fix historical data. The incident lasted 47 minutes."

Result + Learning(结果 + 成长):

"我们没有数据丢失,但有 47 分钟的写入失败。事后我做了三件事:1) 写了详细的 postmortem,发给整个 infra 团队;2) 建立了 Schema 迁移 checklist,包括'检查所有写入路径'这一步;3) 在团队知识分享中讲了这次经历。这个 checklist 后来帮我们避免了至少两次类似问题。"
"No data loss, but 47 minutes of write failures. Afterward: 1) wrote a detailed postmortem shared org-wide; 2) created a schema migration checklist including 'audit all write paths'; 3) gave a team talk about this incident. That checklist prevented at least two similar issues since."

Senior/Staff 加分点 / Leveling Up

普通工程师 说的是 "我犯了个错,我修了它。"

Senior 工程师 说的是 "我犯了个错,我修了它,我让整个团队从中受益。"

Staff 工程师 说的是 "这次失败揭示了我们流程中的一个系统性漏洞,我改变了组织的工作方式。"

Regular engineer: "I made a mistake, I fixed it."

Senior engineer: "I made a mistake, fixed it, and made the whole team better."

Staff engineer: "This failure exposed a systemic gap in our process; I changed how the org operates."


关键要点 / Key Takeaways

✅ 选一个真实的、有分量的错误 — 不要选太小的问题,也别选甩锅给别人的

✅ 直接承认责任 — "这是我的判断失误"比"我们当时不知道"有力得多

✅ 强调你的应急响应 — 面试官想看你在压力下的判断力

✅ 量化影响 — 多少用户?多少时间?多少钱?

✅ 成长必须是具体的 — "我学会了要更仔细"是废话;"我建立了这个机制并用于团队"才有价值


📚 References

🧒 ELI5

面试官问你犯过什么大错,是想看你够不够成熟。最好的回答是:我犯了错,我承担了责任,我快速止损,然后我改变了流程让这件事再也不会发生。

When an interviewer asks about a big mistake, they want to see maturity. The best answer: I made a mistake, I owned it, I stopped the bleeding fast, then I changed the process so it can never happen again.

🤖 AI 新闻速递 / AI News Roundup — Day 53

日期 / Date: 2026-05-28 | 模式 / Mode: NEWS


本周 AI 三大动态 / This Week's Top 3 Stories


🚀 Story 1: Agentic AI 正在重塑企业工作流

Microsoft 推出 Agent 365 和 Computer Use 功能

据报道 (via buildez.ai),微软在 5 月发布了 Agent 365——一个专为企业 AI 智能体设计的控制平面,并在 Copilot Studio 中推出了 "computer use" 功能,使企业 AI 系统能像人类员工一样直接操作软件界面。

微软 AI CEO Mustafa Suleyman 预测,AI 系统在未来 12-18 个月内将在大多数基于电脑的专业任务上达到"人类水平"的性能。但微软研究人员同时警告:AI 智能体在长时间运行的工作流中仍不可靠,常常在多步骤任务中引入错误,强调需要人类监督。

技术视角: 这标志着从"工具型 AI"到"代理型 AI"的范式转变。对后端工程师来说意味着:未来系统设计要考虑 AI 智能体作为一类特殊的"用户"——它们会比人类更频繁地调用 API,更需要幂等性设计和细粒度权限控制。

Microsoft launched Agent 365 — a dedicated control plane for enterprise agents — and "computer use" agents in Copilot Studio that can interact directly with software interfaces. While bold claims about human-level performance are being made, Microsoft researchers themselves caution that agents remain unreliable for long-running workflows.

Engineering takeaway: This marks a shift from "tool AI" to "agentic AI." For backend engineers: future system design must treat AI agents as a special class of "user" — calling APIs far more frequently than humans, requiring stronger idempotency guarantees and fine-grained permission controls.


🔬 Story 2: Anthropic 与 OpenAI 的 AI 安全能力引发关注

前沿模型展现出高级网络攻击能力

据英国 AI 安全研究所评估 (reported via marketingprofs.com),Anthropic 的 Claude 和 OpenAI 的 GPT-5.5 据称通过了一个 32 步网络攻击范围模拟测试。英国 AI 安全研究所估计,前沿网络攻击能力每四个月翻一番。

技术视角: 这引发了业界对 AI 安全测试标准化的讨论。作为工程师,这提醒我们:在使用 AI 辅助工具(如代码审查、漏洞扫描)时,模型的能力边界正在快速扩展,需要更严格的访问控制和审计日志。

The UK's AI Security Institute reportedly found that frontier models cleared advanced cybersecurity simulations, with offensive capability reportedly doubling every four months.

Engineering takeaway: Standardized AI safety benchmarking is becoming critical. When using AI-assisted tools for code review or vulnerability scanning, the capability boundary is expanding rapidly — stricter access controls and audit trails are increasingly important.


📊 Story 3: Amnesty International 警告 AI 训练数据的隐私问题

据报道:大规模 AI 训练建立在未经授权的网络抓取上

国际特赦组织发布报告 "Unlawful by Design" (原文链接: amnesty.org),指出驱动主要生成式 AI 系统的海量数据管道建立在大规模侵犯隐私的网络抓取上,违反了隐私权设计原则。

技术视角: 这加速了各国对 AI 训练数据的立法监管。对于使用第三方 AI 服务的工程师:了解你们供应商的数据来源合规性,将成为 2026 年技术审查的重要维度。

Amnesty International's "Unlawful by Design" report highlights that major generative AI data pipelines are built on mass unlawful web scraping, violating privacy-by-design principles.

Engineering takeaway: This accelerates AI training data legislation globally. For engineers using third-party AI services: understanding your vendor's data provenance compliance will become a critical dimension in technical due diligence.


📚 本期引用 / Sources

🧒 ELI5

本周 AI 三件大事:1) 微软的 AI 可以自己操控电脑干活了;2) 最新的 AI 模型据说能模拟黑客攻击,安全研究人员很担心;3) Amnesty International 说很多 AI 的训练数据是"偷"来的,在隐私法上存在问题。

This week in AI: 1) Microsoft's AI can now control computers like a human employee; 2) The latest models reportedly passed advanced hacking simulations, alarming security researchers; 3) Amnesty International says major AI systems trained on data scraped without permission, raising serious privacy law concerns.