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

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

Topic: Design a URL Shortener (TinyURL)

Date: 2026-04-07


🏗️ 系统设计 / System Design

设计一个短链接服务(TinyURL)

Design a URL Shortener (TinyURL)


🌍 真实场景 / Real-World Scenario

想象你在 Twitter(现 X)工作。每条推文最多 280 字,但一个普通的 YouTube 链接就能占掉 60 个字符。你的任务:把 https://www.youtube.com/watch?v=dQw4w9WgXcQ 变成 https://tinyurl.com/abc123。

Imagine you're at Twitter (now X). Tweets are 280 chars, but a YouTube URL alone takes 60. Your job: turn https://www.youtube.com/watch?v=dQw4w9WgXcQ into https://tinyurl.com/abc123.

功能需求 / Functional Requirements:

  • 给一个长 URL,生成唯一短链接
  • 访问短链接,重定向到原始 URL
  • 短链接可配置过期时间(可选)

非功能需求 / Non-Functional:

  • 100M 短链/天(写操作)
  • 读写比约 10:1(10亿次重定向/天)
  • 链接可用 5 年(可用 → 高可用)
  • P99 重定向延迟 < 50ms

🏛️ 架构图 / Architecture Diagram

Client │ ▼ [Load Balancer] │ │ ▼ ▼ [App Server] [App Server] ← stateless, horizontally scalable │ ├──► [Cache (Redis)] ← 短链 → 长链,命中率 ~95% │ │ miss ▼ ▼ [Primary DB (PostgreSQL)] ──► [Read Replicas × 3] │ ▼ [ID Generator Service] ← 独立发号器(雪花算法 or 自增)

核心表结构 / Core Schema:

CREATE TABLE url_mappings (
  short_code  VARCHAR(7) PRIMARY KEY,   -- e.g. "abc123f"
  long_url    TEXT NOT NULL,
  created_at  TIMESTAMP DEFAULT NOW(),
  expires_at  TIMESTAMP,
  user_id     BIGINT
);
CREATE INDEX idx_short_code ON url_mappings(short_code);

⚙️ 关键设计决策 / Key Design Decisions

1. 如何生成短码? / How to generate short codes?

方案A — Base62 编码(推荐):

62^7 = 3.5 万亿种组合 ≈ 足够用 100 年
  • 用自增 ID(如 1234567) → Base62 编码 → "b8Xk2mP"
  • 优点:无碰撞,ID 顺序保证短码唯一
  • 缺点:短码可预测(可加随机盐)

方案B — MD5 哈希截取:

  • 取 URL 的 MD5 前 7 位
  • 问题:哈希碰撞,不同 URL 可能得到相同短码
import base62  # pip install pybase62

def shorten(long_url: str, auto_increment_id: int) -> str:
    # Convert unique auto-increment ID to base62
    return base62.encodebytes(auto_increment_id.to_bytes(8, 'big')).decode()[-7:]

# Example: ID 1000000 → "4c92"... → take last 7 chars

2. 重定向类型 / Redirect Type:

  • 301 Permanent:浏览器缓存,减服务器压力,但无法统计点击数
  • 302 Temporary:每次必过服务器,可精确统计 → 大多数短链服务用 302

3. 缓存策略 / Caching:

  • Redis 存储 shortCode → longURL,TTL = 24h
  • 读写比 10:1,缓存命中率可达 95%+
  • LRU 策略驱逐不热门的链接

⚠️ 别踩这个坑 / Common Mistakes

❌ 错误✅ 正确
用 MD5 哈希直接截取,不处理碰撞用自增 ID + Base62,或哈希时加碰撞检测
短码暴露自增 ID(可遍历所有链接)Base62 编码后加随机偏移或加盐
重定向用 301(无法统计点击)根据需求选 301/302;统计场景用 302
单点 ID 生成器(性能瓶颈)用 Snowflake 分布式 ID 或数据库自增分段
忘记过期清理(磁盘无限增长)定时任务 + TTL 字段清理过期链接

📊 容量估算 / Capacity Estimation

写:100M 短链/天 ÷ 86400s ≈ 1160 QPS
读:1B 重定向/天 ÷ 86400s ≈ 11600 QPS
存储:每条记录约 500 bytes × 100M/天 × 365天 × 5年 ≈ 91 TB

📚 参考资料 / References

  1. System Design Interview: URL Shortener — Alex Xu
  2. How TinyURL Works — High Scalability
  3. Base62 Encoding Explained — GeeksForGeeks

🧒 ELI5(用小学生能懂的方式解释)

想象你有一本很厚的字典,每本字典有一个编号。你把网址存进字典,给它一个编号(比如第 12345 条)。然后你把 12345 翻译成一串奇怪的字母(比如 "abcXY")。别人访问 "abcXY" 时,你查字典找到 12345,再找到原来的网址,带他过去。这就是短链接!

Imagine a big dictionary. Every URL gets a unique page number (12345). You translate that number into a short code ("abcXY"). When someone visits "abcXY", you look up 12345 in your dictionary, find the original URL, and send them there. That's it!

💻 算法 / Algorithms — Day 19

Topic: Permutation in String (#567)

Date: 2026-04-07


💻 算法 / Algorithms — #567 Permutation in String (Medium)

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

今天的问题是滑动窗口的经典变体:固定大小窗口。与寻找“最长/最短”子串不同,这里的窗口大小是固定的(等于目标字符串的长度)。

Today's problem is a classic variation: Fixed-Size Window. Unlike finding the "longest/shortest" substring, the window size here is strictly fixed to the length of the target string.

🔗 [LeetCode #567](https://leetcode.com/problems/permutation-in-string/) | 🟡 Medium | 📹 [NeetCode Video](https://www.youtube.com/watch?v=UbyhOgBN834)

🌍 现实场景 / Real-World Analogy

想象你在玩拼字游戏(Scrabble)。你手里有字母 a, b,你想在黑板上的长字符串 eidbaooo 中寻找是否有一段连续的字母正好能用你手里的字母拼出来(顺序无所谓,只要字母和数量对得上)。这就是寻找“排列”(Permutation)。

Imagine playing Scrabble. You have letters a, b. You want to see if there's a contiguous sequence in the string eidbaooo that can be formed using exactly your letters (order doesn't matter, just the counts). That's finding a permutation.


🧠 映射到模版 / Map to Pattern Template

排列(Permutation)的本质是:字符出现的频率完全相同。

我们维护一个大小恒定为 len(s1) 的滑动窗口,在 s2 上滑动。每次向右滑动一步:

  1. Expand: 右边新进来的字符,频率 +1
  2. Shrink: 左边出去的字符,频率 -1(因为窗口大小固定,所以进一个必须出一个)
  3. Check: 如果窗口内的字符频率和 s1 完全一致,就找到了!

A permutation means exact same character frequencies. We maintain a sliding window of strictly size len(s1) over s2. For each step right: add the new char, remove the old char from the left, and check if frequencies match.


💻 Python 实现 / Python Solution

class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        if len(s1) > len(s2):
            return False
            
        # 1. Initialize frequency maps
        s1_count = [0] * 26
        window_count = [0] * 26
        
        for i in range(len(s1)):
            s1_count[ord(s1[i]) - ord('a')] += 1
            window_count[ord(s2[i]) - ord('a')] += 1
            
        # 2. Check the first window
        if s1_count == window_count:
            return True
            
        # 3. Slide the fixed-size window
        left = 0
        for right in range(len(s1), len(s2)):
            # Expand window: add right char
            window_count[ord(s2[right]) - ord('a')] += 1
            
            # Shrink window: remove left char
            window_count[ord(s2[left]) - ord('a')] -= 1
            left += 1
            
            # Check if current window matches
            if s1_count == window_count:
                return True
                
        return False

复杂度 / Complexity:

  • Time: $O(N)$ where $N$ is the length of s2. Comparing two arrays of size 26 takes $O(1)$ time.
  • Space: $O(1)$ because the frequency arrays are always size 26, regardless of string length.

🔄 举一反三 / Connect to Pattern

这道题和 #438 Find All Anagrams in a String 完全一样!Anagram(字母异位词)和 Permutation(排列)在这个语境下是同一个意思。掌握了这个固定窗口频率匹配的技巧,那道题可以直接秒杀。

This is identical to #438 Find All Anagrams in a String! Anagram and Permutation mean the exact same thing here. Master this fixed-window frequency matching, and you get two problems for the price of one.


📚 参考资料 / References

  1. NeetCode: Permutation in String
  2. Sliding Window Pattern — LeetCode Discuss
  3. Python ord() function — W3Schools

🧒 ELI5

你要在一条长长的火车上找两节特定的车厢(比如一节红的,一节蓝的,挨在一起)。你拿一个刚好能罩住两节车厢的框,从车头开始往后套。每次往后挪一节,看看框里的颜色对不对。因为框的大小不变,所以每次挪动,前面进来一节,后面就出去一节。

You're looking for two specific train cars (one red, one blue, next to each other) on a long train. You take a frame that fits exactly two cars and slide it from the front. Each time you move it, one new car enters the frame, and one old car leaves. You just check if the colors inside the frame match what you want!

🗣️ 软技能 / Soft Skills — Day 19

Topic: How do you ensure quality in your team's code and systems?

Date: 2026-04-07


🗣️ 软技能 / Soft Skills

如何保证团队的代码和系统质量?

How do you ensure quality in your team's code and systems?


💡 为什么这个问题很重要? / Why this matters

面试官(特别是面 Senior/Staff 级别时)问这个问题,不是想听你背诵“写单元测试”。他们想知道你是否具备系统性思维和工程文化建设的能力。质量不是靠一个人盯着,而是靠流程、工具和文化。

Interviewers (especially for Senior/Staff roles) aren't looking for "write unit tests." They want to know if you have systems thinking and can build an engineering culture. Quality isn't about one person watching every PR; it's about processes, tooling, and culture.


🌟 STAR 拆解 / STAR Breakdown

Situation:

团队扩张快,代码库变得混乱,线上 bug 频发。

The team was growing fast, the codebase was getting messy, and production bugs were frequent.

Task:

作为 Tech Lead,我需要建立一套机制,在不严重拖慢开发速度的前提下提升质量。

As a Tech Lead, I needed to establish mechanisms to improve quality without severely slowing down feature delivery.

Action:

  1. 自动化 (Automation): 引入 CI/CD pipeline,强制执行 linting (ESLint/Prettier) 和基础测试。
  2. 规范化 (Standardization): 制定并推行 Code Review 规范(例如 PR 模板,要求附带测试截图)。
  3. 可观测性 (Observability): 完善监控和告警(Datadog/Sentry),确保问题在用户报怨前被发现。
  4. 文化建设 (Culture): 每周举办 "Bug Bash" 或 "Post-mortem"(无指责复盘),把踩过的坑变成团队经验。

Result:

线上 P0 故障率下降 60%,新成员 onboarding 时间缩短,代码库一致性显著提升。

Production P0 incidents dropped by 60%, new hire onboarding was faster, and codebase consistency improved significantly.


❌ 错误示范 vs ✅ 正确示范 / Bad vs Good

❌ Bad: "I review every single PR very carefully and tell people when they make mistakes."

(微观管理,无法规模化 / Micromanagement, doesn't scale)

✅ Good: "I believe in 'shift-left' quality. We automated linting and testing in CI so reviewers can focus on architecture and logic, not formatting. We also implemented blameless post-mortems so every outage makes the system stronger."

(系统性思维,自动化,文化建设 / Systems thinking, automation, culture building)


🚀 Senior/Staff 进阶技巧 / Senior/Staff Tips

高级工程师不仅关注代码质量,更关注系统质量和交付质量。

  • Shift-Left (左移): 把质量检查推到开发周期的最早期(本地 pre-commit hooks,IDE 插件)。
  • Blast Radius (爆炸半径): 即使有 bug,如何限制它的影响?(Feature Flags,灰度发布/Canary Releases)。
  • Tech Debt Management: 定期安排时间清理技术债,而不是让它无限堆积。

Senior engineers focus on system quality and delivery quality, not just code.

  • Shift-Left: Push quality checks to the earliest stage (pre-commit hooks).
  • Blast Radius: How do we limit the impact of a bug? (Feature Flags, Canary Releases).
  • Tech Debt: Schedule regular time to pay down technical debt.

📚 参考资料 / References

  1. Google Engineering Practices — Code Review
  2. Shift-Left Testing — Atlassian
  3. Blameless Post-Mortems — SRE Book (Google)

🧒 ELI5

想象你在管理一个厨房。保证菜品质量不能靠你每道菜都尝一口(你会累死)。你要做的是:买好刀具(工具),写好菜谱(规范),装好烟雾报警器(监控),并且在菜做砸了的时候,大家一起讨论怎么改进,而不是骂厨师(文化)。

Imagine managing a kitchen. You can't taste every dish to ensure quality (you'd be exhausted). Instead, you buy good knives (tooling), write clear recipes (standards), install smoke alarms (monitoring), and when a dish fails, you discuss how to improve the recipe instead of yelling at the chef (culture).

🎨 前端 / Frontend — Day 19

Topic: React Server Components (RSC) — What Actually Changes

Date: 2026-04-07


🎨 前端 / Frontend

React Server Components (RSC) — 到底改变了什么?

React Server Components (RSC) — What Actually Changes?


🌍 真实场景 / Real-World Scenario

你在做一个博客文章页面。文章内容很长,包含大量 Markdown 解析库(比如 marked,体积很大)。如果用传统的 React(客户端渲染),用户需要把整个 marked 库下载到浏览器,然后才能看到文章。这太慢了!

You're building a blog post page. The content is long and uses a massive Markdown parsing library (e.g., marked). With traditional React (Client-Side Rendering), the user has to download the entire marked library to their browser just to see the post. That's way too slow!


💻 代码对比 / Code Snippet

❌ 传统 React (Client Component):

import { marked } from 'marked'; // 🚨 整个库被打包发给浏览器!(Bundle size ++!)

export default function BlogPost({ content }) {
  // 浏览器在运行时解析 Markdown
  const html = marked.parse(content);
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
}

✅ React Server Component (RSC - Next.js App Router 默认):

import { marked } from 'marked'; // 🟢 只在服务器端运行,不发给浏览器!(Zero bundle size!)

// 注意:这是一个 async 组件!(RSC 独有超能力)
export default async function BlogPost({ id }) {
  // 直接在组件里查数据库!(Mind blown 🤯)
  const post = await db.posts.findUnique({ where: { id } });
  
  // 服务器解析完 Markdown,直接把生成的 HTML 发给浏览器
  const html = marked.parse(post.content);
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
}

🧠 核心概念 / Core Concept

RSC 的本质是:把组件分成两类,各司其职。

  1. Server Components (默认):

- 跑在服务器上。

- 负责:获取数据(直接读 DB)、繁重的计算(解析 Markdown)。

- 结果:它们的代码永远不会发送到浏览器。浏览器只收到它们渲染出的最终 HTML/UI 树。

  1. Client Components ("use client"):

- 跑在浏览器上(但也支持 SSR 预渲染)。

- 负责:交互(onClick)、状态(useState)、生命周期(useEffect)、浏览器 API(window)。

- 结果:它们的代码会被打包发送给浏览器。

RSC splits components into two types:

  1. Server Components (Default): Run on the server. Fetch data directly, do heavy lifting. Their code is never sent to the client. The client only gets the resulting UI.
  2. Client Components ("use client"): Run on the client. Handle interactivity, state, and browser APIs. Their code is bundled and sent to the client.

⚠️ 常见误区 / Common Mistake

❌ 误区: "Server Components 就是 SSR (Server-Side Rendering)。"

✅ 真相: 不是!SSR 是把整个页面在服务器上渲染成 HTML,然后发给浏览器,浏览器还要下载所有的 JS 代码去 "hydrate"(注水,绑定事件)。RSC 是连 JS 代码都不发了,直接发渲染好的 UI 树。

❌ 误区: "所有的组件都应该变成 Server Components。"

✅ 真相: 需要交互的地方(按钮、输入框、动画)必须用 Client Components。RSC 和 Client Components 是互补的。


🎯 什么时候用什么? / When to use what?

场景Server ComponentClient Component ("use client")
获取数据 (Fetch data)✅❌ (尽量避免)
直接访问后端资源 (DB, API keys)✅❌ (安全风险)
保持大依赖包在服务器 (Large dependencies)✅❌
添加交互 (onClick, onChange)❌✅
使用状态和生命周期 (useState, useEffect)❌✅
使用浏览器 API (window, localStorage)❌✅

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

// app/page.tsx (Next.js App Router)
import Button from './Button';

export default function Page() {
  console.log("Where am I running?");
  return <Button />;
}

选项:

A. 浏览器的控制台

B. 服务器的终端 (Terminal)

C. 都会打印

D. 报错

(答案见下方 JSON)


📚 参考资料 / References

  1. React Server Components — React Docs
  2. Next.js App Router — Server Components
  3. Making Sense of React Server Components — Josh W. Comeau

🧒 ELI5

以前去餐厅(传统 React),厨师(服务器)把生的菜和菜谱(JS 代码)打包寄到你家,让你自己炒(浏览器渲染)。现在有了 RSC,厨师在后厨把菜炒好(服务器渲染),直接端上桌(HTML),你只管吃就行了!只有需要你自己加盐加醋的菜(交互),才会给你调料瓶(Client Components)。

Before (Traditional React), the chef (server) mailed you raw ingredients and a recipe (JS bundle) to cook at home (browser rendering). Now with RSC, the chef cooks the heavy meals in the kitchen and serves them ready-to-eat (HTML). You only get the salt shaker (Client Components) for dishes you need to interact with!

🤖 AI — Day 19

Topic: NEWS

Date: 2026-04-07


🤖 AI

AI 资讯速递 / AI News Roundup


📰 1. Bezos 挖角 xAI 联合创始人 / Bezos' Project Prometheus Poaches xAI Co-founder from OpenAI

发生了什么 (What happened):

Jeff Bezos 的 AI 实验室(Project Prometheus)成功挖走了 xAI 联合创始人 Kyle Kozic(他此前在 OpenAI 任职)。Kozic 将在 Bezos 领导的初创公司专注于 AI 基础设施建设,该公司正致力于利用 AI 改进制造业,已获超 60 亿美元融资。这是近期 AI 领域人才争夺战的最新动向。

Jeff Bezos' AI lab (Project Prometheus) has poached xAI co-founder Kyle Kozic, who had been working at OpenAI. Kozic will focus on AI infrastructure at the well-funded startup, which Bezos co-founded alongside former Google exec Vik Bajaj. Project Prometheus focuses on using AI to improve manufacturing — and has already raised $6.2B. The latest move in the ongoing AI talent war.

为什么重要 (Why it matters):

  • 顶尖 AI 人才的流动正在加速,科技巨头和资金雄厚的初创公司都在争夺核心基础设施专家。
  • AI 在制造业(实体经济)的应用正成为下一个重要战场。

🔗 来源 (Source): The Verge - Jeff Bezos' AI lab poaches xAI cofounder Kyle Kozic from OpenAI


📰 2. Anthropic 与谷歌和博通达成重大基础设施协议 / Anthropic Signs Major Infrastructure Deal with Google and Broadcom

发生了什么 (What happened):

Anthropic 宣布与谷歌和博通(Broadcom)签署了一项大型 AI 基础设施协议。预计从 2027 年开始,将有“数千兆瓦(multiple gigawatts)的下一代 TPU 算力”上线,用于“驱动我们的前沿 Claude 模型”。此外,该公司表示其年化收入已超过 300 亿美元。

Anthropic has signed a massive AI infrastructure deal with Google and Broadcom. "Multiple gigawatts of next-generation TPU capacity" are expected to come online starting in 2027 to "power our frontier Claude models." The company also reported its run-rate revenue has surpassed $30 billion.

为什么重要 (Why it matters):

  • 算力即权力: 确保未来的计算资源是训练下一代大模型的关键。
  • TPU 生态: Anthropic 选择谷歌的 TPU 而非完全依赖 Nvidia GPU,显示了 AI 硬件市场的多元化趋势。
  • 惊人的商业化速度: 300 亿美元的年化收入表明企业级 AI 市场的需求极其强劲。

🔗 来源 (Source): The Verge - Anthropic has signed a big AI infrastructure deal with Google and Broadcom


📰 3. 谷歌推出免费离线 AI 听写应用 / Google Launches Free Offline AI Dictation App

发生了什么 (What happened):

谷歌推出了一款名为 "Google AI Edge Eloquent" 的全新实时 AI 转录应用。该应用免费、无需订阅、没有使用限制,并且可以在离线状态下自动润色你的语音(例如过滤掉“嗯”、“啊”等语气词)。目前仅支持 iOS,但计划未来登陆 Android 和 macOS。

Google has launched "Google AI Edge Eloquent," a new live AI transcription app that is free, offline, requires no subscription, and has no usage limits. It automatically polishes your speech by filtering out filler words like "um." Currently on iOS, with plans for Android and macOS.

为什么重要 (Why it matters):

  • 端侧 AI (Edge AI) 的胜利: 强大的语音处理能力现在可以直接在手机本地运行,无需将音频发送到云端,极大地保护了隐私并降低了延迟。
  • 实用工具的普及: AI 正在从“聊天机器人”变成无缝融入日常工作流的隐形助手。

🔗 来源 (Source): The Verge - Google has launched a free, offline AI dictation app


📚 参考资料 / References

  1. The Verge - Artificial Intelligence
  2. TechCrunch - Artificial Intelligence

🧒 ELI5

今天的新闻就像是一场大富翁游戏:贝索斯花重金请来了 OpenAI 老将帮忙建工厂;Anthropic 提前预订了谷歌未来几年的“超级电脑”来训练更聪明的 Claude;而谷歌则送给大家一个免费的“随身秘书”,能在你不联网的时候帮你把说的话变成漂亮的文章。

Today's news is like a game of Monopoly: Amazon hired an OpenAI veteran to help build their factories; Anthropic pre-ordered Google's future supercomputers to train smarter versions of Claude; and Google gave everyone a free, offline "pocket secretary" that turns your spoken words into polished text without needing the internet.