← 2026-04-08 📂 All Days 2026-04-10 →

🏗️ 系统设计 / System Design

想象你在设计... / Imagine you are designing...

一个键值存储系统(Key-Value Store),比如 Amazon DynamoDB 或 Redis。

A Key-Value Store, like Amazon DynamoDB or Redis.

架构图 / Architecture Diagram

Client -> [ API Gateway ] -> [ Load Balancer ]
                                |
                   +------------+------------+
                   |            |            |
             [ Node A ]   [ Node B ]   [ Node C ]
             (Data 1-3)   (Data 4-6)   (Data 7-9)
                   |            |            |
                   +---(Gossip Protocol)-----+

核心权衡 / Key Tradeoffs

  • CAP 定理 (CAP Theorem): 在分布式系统中,你只能在一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)中选择两个。大多数键值存储(如 Dynamo)选择 AP(高可用性),通过最终一致性来解决冲突。
  • 数据分片 (Data Partitioning): 使用一致性哈希(Consistent Hashing)将数据均匀分布在多个节点上,并在节点增减时最小化数据迁移。
  • 数据复制 (Data Replication): 将数据复制到多个节点(如 N=3)以保证高可用性和容错性。

常见误区 / Common Mistakes

  • 单点故障 (Single Point of Failure): 依赖单一的协调节点。应使用去中心化的架构(如 Gossip 协议)进行集群成员管理。
  • 忽略冲突解决 (Ignoring Conflict Resolution): 在最终一致性模型中,并发写入可能导致冲突。需要使用向量时钟(Vector Clocks)或最后写入胜出(LWW)来解决。

📚 References

🧒 ELI5 (Explain Like I'm 5)

想象你有很多个抽屉(节点)来放玩具(数据)。为了不让一个抽屉太满,你用一个特殊的规则(一致性哈希)决定玩具放哪个抽屉。而且,为了防止某个抽屉坏了,你把每个玩具都复制三份,放在不同的抽屉里。

Imagine you have many drawers (nodes) to store toys (data). To avoid overfilling one drawer, you use a special rule (consistent hashing) to decide where each toy goes. Also, in case a drawer breaks, you make 3 copies of each toy and put them in different drawers.

💻 算法 / Algorithms — #76 Minimum Window Substring (Hard) — Sliding Window

🧩 滑动窗口模式 (5/6) — building on the template from Day 19

这个题目是滑动窗口的终极形态。与之前的题目不同,这里我们需要在窗口内包含目标字符串 t 的所有字符,并且要求最短的窗口。

This is the ultimate form of the sliding window. Unlike previous problems, we need to include all characters of the target string t in the window, and we want the shortest window.

🔗 [LeetCode 76](https://leetcode.com/problems/minimum-window-substring/) | 🔴 Hard | 📹 [NeetCode](https://www.youtube.com/watch?v=jSto0O4PIzM)

现实类比 / Real-world Analogy

想象你在寻宝,你需要收集一套特定的宝石(字符串 t)。你沿着一条路(字符串 s)走,把路上的宝石都捡起来(右指针扩张)。一旦你集齐了所有需要的宝石,你就开始扔掉最早捡到的没用的宝石(左指针收缩),直到你不能再扔为止,这时候你手里的宝石就是最短的有效集合。

Imagine you are treasure hunting and need a specific set of gems (string t). You walk along a path (string s), picking up gems (right pointer expands). Once you have all the required gems, you start dropping the earliest useless ones (left pointer shrinks) until you can't drop any more. The gems you hold at that moment form the shortest valid set.

映射到模式 / Map to Pattern

  • Expand (Right Pointer): 将字符加入窗口频率字典。如果该字符是 t 中需要的,并且频率达到了要求,则 have 计数器加一。
  • Shrink (Left Pointer): 当 have == need 时,说明当前窗口有效。记录当前窗口大小和位置,然后尝试收缩:移除左指针字符,如果该字符是 t 中需要的且频率低于要求,则 have 减一。左指针右移。

Python Solution

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        if t == "": return ""

        countT, window = {}, {}
        for c in t:
            countT[c] = 1 + countT.get(c, 0)

        have, need = 0, len(countT)
        res, resLen = [-1, -1], float("infinity")
        l = 0

        for r in range(len(s)):
            c = s[r]
            window[c] = 1 + window.get(c, 0)

            if c in countT and window[c] == countT[c]:
                have += 1

            while have == need:
                # update our result
                if (r - l + 1) < resLen:
                    res = [l, r]
                    resLen = (r - l + 1)
                
                # pop from the left of our window
                window[s[l]] -= 1
                if s[l] in countT and window[s[l]] < countT[s[l]]:
                    have -= 1
                l += 1
                
        l, r = res
        return s[l:r+1] if resLen != float("infinity") else ""

复杂度 / Complexity

  • Time: O(N + M) where N is len(s) and M is len(t). Each character is visited at most twice.
  • Space: O(1) if we consider the character set is fixed (e.g., 26 letters or 128 ASCII characters).

举一反三 / Connect to other problems

  • 这是滑动窗口求最短子串的经典题。对比 #3 Longest Substring Without Repeating Characters,那是求最长,所以是在不满足条件时收缩;而本题是求最短,是在满足条件时收缩。

📚 References

🧒 ELI5

一直往右走,直到集齐了所有需要的卡片。然后看看能不能把最左边没用的卡片扔掉,让手里的卡片越少越好。

Keep walking right until you collect all the needed cards. Then see if you can throw away useless cards from the left to make your hand as small as possible.

🗣️ 软技能 / Soft Skills

Describe a time you had to say no to a popular idea

描述一次你不得不拒绝一个受欢迎的想法的经历。

为什么这很重要 / Why this matters

高级工程师(Senior/Staff)不仅要会写代码,还要能把控项目方向。拒绝一个受欢迎但有风险/不切实际的想法,展现了你的技术判断力、沟通能力和对业务目标的聚焦。

Senior/Staff engineers need to steer project direction. Saying no to a popular but risky/impractical idea shows technical judgment, communication skills, and focus on business goals.

STAR 拆解 / STAR Breakdown

  • Situation: 团队对一个新工具/框架/功能非常热情(例如:大家都想用微服务重构,或者引入一个花哨的 AI 功能)。
  • Task: 评估这个想法的可行性、成本和对当前业务目标的影响。
  • Action: 收集数据(性能测试、维护成本、开发周期)。通过技术文档(RFC/Design Doc)客观展示利弊。组织会议,不直接说“不行”,而是展示“如果这样做,我们需要放弃什么”。提出一个更务实的替代方案。
  • Result: 团队理解了权衡,同意采用替代方案,最终按时交付了项目,避免了技术债务或延期。

❌ 糟糕的回答 vs ✅ 好的回答

  • ❌ Bad: "I told them it was a stupid idea because it would take too long, and I was the tech lead so they had to listen to me." (Arrogant, dictatorial / 傲慢,独裁)
  • ✅ Good: "The team wanted to rewrite our monolith into microservices. I did a cost-benefit analysis showing it would halt feature development for 6 months. I presented this data and proposed we only extract the most heavily loaded module first. The team agreed, and we improved performance without stopping business growth." (Data-driven, collaborative, pragmatic / 数据驱动,协作,务实)

Senior/Staff 提示 / Senior/Staff Tips

  • 永远不要凭直觉拒绝,要用数据和业务目标说话。
  • 给出替代方案 (Alternative),而不是单纯的拒绝。
  • 关注权衡 (Trade-offs),让团队自己意识到成本。

核心收获 / Key Takeaways

Saying "no" is easy; saying "no" while keeping the team motivated and aligned requires data, empathy, and a solid alternative plan.

📚 References

🧒 ELI5

大家都想去游乐园,但你发现钱不够而且会错过晚饭。你没有直接说“不去”,而是算了一笔账给大家看,然后提议去附近的公园吃冰淇淋。大家都很开心。

Everyone wanted to go to the amusement park, but you realized it was too expensive and you'd miss dinner. Instead of just saying "no," you showed everyone the math and suggested going to a local park for ice cream instead. Everyone was happy.

🎨 前端 / Frontend

React Forms — Controlled vs Uncontrolled

React 表单:受控组件与非受控组件

你在做一个 dashboard,需要... / You're building a dashboard and need to...

创建一个包含很多输入字段的复杂表单。你需要决定是由 React 的 state 来管理输入的值,还是让 DOM 自己管理。

Create a complex form with many input fields. You need to decide whether to manage the input values with React state or let the DOM handle it.

代码示例 / Code Snippet

Controlled Component (受控组件)

import { useState } from 'react';

function ControlledForm() {
  const [name, setName] = useState('');

  return (
    <form>
      <input 
        value={name} 
        onChange={(e) => setName(e.target.value)} 
        placeholder="Name" 
      />
      <p>Typing: {name}</p>
    </form>
  );
}

Uncontrolled Component (非受控组件)

import { useRef } from 'react';

function UncontrolledForm() {
  const nameRef = useRef<HTMLInputElement>(null);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.log(nameRef.current?.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input ref={nameRef} defaultValue="Default Name" />
      <button type="submit">Submit</button>
    </form>
  );
}

猜猜这段代码输出什么? / Quiz

If you type "A" in a controlled input but forget to provide the onChange handler:

<input value={name} />

A) The input shows "A" and React throws an error.

B) The input remains empty (or whatever name initially was) and you can't type anything.

C) The input shows "A" but the state doesn't update.

D) The component crashes.

Answer: B. The value is locked to the state. Without onChange to update the state, the input is read-only.

常见误区 / Common Mistake

❌ Bad: 在不需要实时验证或动态 UI 的大表单中使用受控组件,导致每次按键整个表单重新渲染,产生性能问题。

✅ Good: 对于简单表单或需要实时验证的表单使用受控组件;对于庞大且性能敏感的表单,使用非受控组件(或 react-hook-form 库)。

何时使用 / When to use

  • Controlled: 需要实时验证 (live validation)、禁用按钮直到表单有效、强制输入格式(如信用卡号)。
  • Uncontrolled: 只需要在提交时获取值、集成非 React 库、极其复杂的表单且遇到性能瓶颈。

📚 References

🧒 ELI5

受控组件就像一个直升机父母,你每写一个字他都要检查并记录下来。非受控组件就像一个放养的父母,你随便写,写完了交卷(Submit)时他才看一眼。

A controlled component is like a helicopter parent who checks and records every single letter you write. An uncontrolled component is like a hands-off parent who lets you write whatever and only checks when you hand in the paper (Submit).

🤖 AI

CONCEPT: AI Agents vs. LLMs

AI 代理与大语言模型

直观解释 / Intuitive Explanation

大语言模型(LLM)就像一个被关在房间里、读过世界上所有书的聪明人。你问他问题,他靠记忆回答。

AI 代理(Agent)则是这个聪明人拿到了手机、电脑和信用卡。他不仅能回答问题,还能上网搜索、运行代码、发邮件、甚至帮你订外卖。

An LLM is like a brilliant person locked in a room who has read every book. You ask a question, they answer from memory.

An AI Agent is that same person given a phone, a computer, and a credit card. They can search the web, run code, send emails, and order food.

它是如何工作的 / How it works

  1. 感知 (Perception): 接收用户的指令(Prompt)。
  2. 思考 (Thinking/Reasoning): 使用 LLM 分析任务,将其拆解为多个步骤(如 ReAct 或 Chain-of-Thought 模式)。
  3. 行动 (Action): 调用外部工具(Tools/APIs),如计算器、搜索引擎、数据库查询。
  4. 观察 (Observation): 获取工具的返回结果,评估是否完成了任务,如果没有,则循环回到思考阶段。

应用场景 / Applications

  • AutoGPT / BabyAGI: 给定一个目标(如“帮我策划一次去日本的旅行并预订机票”),它会自动拆解任务并执行。
  • Coding Agents: 像 Devin 或 GitHub Copilot Workspace,能够阅读代码库、编写代码、运行测试并修复 bug。
  • Data Analysis: 自动连接数据库,编写 SQL 查询,生成图表并撰写分析报告。

Runnable Python Snippet

一个极简的 Agent 逻辑(伪代码风格):

# pip install openai
import openai

def simple_agent(goal):
    messages = [{"role": "system", "content": "You are an agent. You can use tools: [search(), calculate()]. Think step-by-step."}]
    messages.append({"role": "user", "content": goal})
    
    while True:
        response = openai.ChatCompletion.create(model="gpt-4", messages=messages)
        action = response.choices[0].message.content
        
        if "DONE" in action:
            return action
        elif "search(" in action:
            # Parse query, run real search, append result to messages
            messages.append({"role": "user", "content": "Search result: ..."})
        elif "calculate(" in action:
            # Parse math, calculate, append result
            messages.append({"role": "user", "content": "Calculation result: ..."})

📚 References

  • [LLM Powered Autonomous Agents - Lilian Weng]
  • [ReAct: Synergizing Reasoning and Acting in Language Models]

🧒 ELI5

LLM 是一本会说话的百科全书。Agent 是一个带着这本百科全书、还能帮你跑腿买东西的机器人管家。

An LLM is a talking encyclopedia. An Agent is a robot butler who carries that encyclopedia and can also run errands for you.