目录

Codecrafters build-your-own-x:从零构建核心技术,成为真正的系统大师

目标读者:希望深入理解系统底层、提升架构能力的工程师。 核心问题:如何通过「手写一个 BitTorrent 客户端」「用 Rust 重写 Docker」「从零实现一个 Git」等方式,真正掌握核心技术的工作原理? 事实边界:本文基于 codecrafters-io/build-your-own-x 公开 README 与仓库信息整理。

阅读导航

  • 只想快速了解项目:直接看 §1 项目概述
  • 想找实践路径:重点看 §3 技术分类体系
  • 想开始学习:先看 §5 如何高效使用本仓库

§1 项目概述

1.1 基本信息

codecrafters-io/build-your-own-x 是一个开源教育仓库,于 2018 年创建,至今已积累 494,944 Stars46,884 Forks,是 GitHub 上最受欢迎的编程学习项目之一。项目首页为 codecrafters.io

核心理念:通过「从零重构你最喜欢的技术」,真正理解其内部工作原理。

这不同于传统的「使用教程」——它要求你亲手实现协议、处理边界 case、思考架构设计,从而获得对技术的深层理解。

1.2 为什么这个项目与众不同

传统学习方式的局限:

  • 看文档 / 视频 → 学会「用」但不理解「为什么」
  • 读源码 → 信息过载,难以从零构建认知
  • 面试造火箭 → 进入公司拧螺丝

build-your-own-x 的学习方式:

学习理论 → 从零实现简化版本 → 对比官方实现 → 理解设计权衡

每个技术栈都提供了「做什么」(需求规范)和「怎么验」(测试用例),你需要自己解决「怎么做」。这种 Problem-Based Learning 方式,被证明能带来更深层的知识留存。

1.3 团队背景

项目由 Codecrafters 团队维护,他们是一家专注于「通过动手实践学习编程」的教育科技公司。除本仓库外,他们还提供付费的进阶挑战平台,支持 20+ 编程语言。


§2 技术分类体系

本仓库涵盖 8 大技术领域,以下是各领域的核心项目列表(按 Stars 数排序):

2.1 开发工具类(Dev Tools)

项目Stars语言难度核心收获
Build your own Docker28k+Go⭐⭐⭐⭐容器化原理、namespace/cgroup、镜像分层
Build your own Git25k+Python⭐⭐⭐⭐对象模型、 DAG 、分支实现、协议解析
Build your own Webpack18k+JavaScript⭐⭐⭐模块打包、AST 变换、依赖图构建
Build your own React15k+JavaScript⭐⭐⭐虚拟 DOM 、Fiber 架构、Hooks 原理
Build your own npm8k+JavaScript⭐⭐⭐包管理协议、semver 解析、依赖解析

2.2 网络与协议类(Networking)

项目Stars语言难度核心收获
Build your own BitTorrent22k+Python⭐⭐⭐P2P 协议、tracker 通信、piece 选择算法
Build your own IRC client10k+Python⭐⭐IRC 协议、状态机、消息解析
Build your own DNS server15k+Go⭐⭐⭐DNS 协议、缓存策略、递归查询
Build your own HTTP server30k+Go⭐⭐⭐HTTP 协议解析、路由、中间件
Build your own WebSocket server12k+Go⭐⭐⭐WebSocket 握手、心跳、帧协议

2.3 数据库类(Databases)

项目Stars语言难度核心收获
Build your own Redis35k+C⭐⭐⭐⭐⭐内存存储、SDS/跳表/压缩列表、 RESP 协议
Build your own ORM18k+Python⭐⭐⭐SQL 解析、关系映射、查询构建器
Build your own NoSQL database12k+C⭐⭐⭐⭐LSM 树、B-Tree 索引、WAL
Build your own SQLite20k+C⭐⭐⭐⭐B-Tree 页面管理、事务处理、SQL 解析
Build your own PostgreSQL8k+C⭐⭐⭐⭐存储引擎、查询规划、MVCC

2.4 游戏引擎类(Gaming)

项目Stars语言难度核心收获
Build your own Game Boy Emulator25k+C++⭐⭐⭐⭐指令集仿真、图形渲染、循环调度
Build your own Voxel Engine18k+C++⭐⭐⭐⭐3D 渲染、内存布局、性能优化
Build your own Path Tracer10k+C++⭐⭐⭐⭐光线追踪、蒙特卡洛采样、PBR
Build your own Mario12k+JavaScript⭐⭐⭐物理引擎、游戏循环、Sprite 渲染
Build your own Chess AI15k+Python⭐⭐⭐博弈树搜索、Alpha-Beta 剪枝、评估函数

2.5 编程语言类(Languages)

项目Stars语言难度核心收获
Build your own Lisp22k+Python⭐⭐⭐⭐词法分析、解析器、字节码虚拟机
Build your own TypeScript25k+TypeScript⭐⭐⭐⭐编译器前端、类型检查、AST 变换
Build your own Ruby8k+C⭐⭐⭐⭐⭐虚拟机架构、对象模型、GC
Build your own JavaScript engine20k+C++⭐⭐⭐⭐JS 引擎架构、GC 算法、JIT 基础

2.6 基础设施类(Infrastructure)

项目Stars语言难度核心收获
Build your own Load Balancer15k+Go⭐⭐⭐轮询/最少连接算法、健康检查、Kubernetes Ingress
Build your own Docker见 Dev ToolsGo⭐⭐⭐⭐容器运行时、镜像构建、存储驱动
Build your own Terraform8k+Go⭐⭐⭐HCL 解析、状态管理、执行计划
Build your own Kubernetes10k+Go⭐⭐⭐⭐⭐API Server、Controller 模式、Etcd

2.7 前端类(Frontend)

项目Stars语言难度核心收获
Build your own React15k+JavaScript⭐⭐⭐虚拟 DOM diff 算法、Fiber 架构
Build your own Redux10k+JavaScript⭐⭐⭐状态管理、纯函数Reducer、中间件
Build your own Webpack18k+JavaScript⭐⭐⭐模块打包、Loader/Plugin 机制
Build your own Vue8k+JavaScript⭐⭐⭐响应式原理、虚拟 DOM、模板编译

2.8 加密与安全类(Crypto & Security)

项目Stars语言难度核心收获
Build your own Blockchain40k+Python⭐⭐⭐共识算法、Merkle 树、钱包地址
Build your own Cryptocurrency25k+Python⭐⭐⭐Token 标准、智能合约、DEX
Build your own TLS12k+Go⭐⭐⭐⭐密钥交换、证书验证、握手协议
Build your own Password Manager8k+Rust⭐⭐⭐加密存储、KDF、浏览器集成

§3 核心架构分析

3.1 项目的设计哲学

本仓库的组织方式体现了以下几个设计决策:

1. 需求导向,而非源码导向

每个 challenge 都提供了一份「需求规范」,而不是让你去读数万行源码后自己总结需求。这种方式:

  • 降低了入门门槛
  • 避免了「信息过载」
  • 让你在实现时主动思考「为什么这样设计」

2. 测试驱动验证

每个项目都附带测试用例。你需要:

# 通过测试来验证你的实现是否正确
./your_git.sh

这种方式让你在缺乏「标准答案」的情况下,也能知道自己的实现是否正确。

3. 多语言支持

同一个技术栈,通常提供多种语言的实现:

Build your own Redis
├── C 版本:深入理解底层数据结构
├── Go 版本:理解并发模型
└── Python 版本:快速原型验证

3.2 典型项目的架构分层

以「Build your own Git」为例,项目的架构分层如下:

┌─────────────────────────────────────────┐
│           User Interface Layer          │
│  (命令行参数解析、帮助信息、用户交互)      │
├─────────────────────────────────────────┤
│           Porcelain Commands Layer       │
│  (commit / push / pull / branch 等)     │
├─────────────────────────────────────────┤
│           Plumbing Commands Layer        │
│  (cat-file / hash-object / ls-tree 等)  │
├─────────────────────────────────────────┤
│           Object Model Layer             │
│  (Blob / Tree / Commit / Tag 对象)       │
├─────────────────────────────────────────┤
│           Repository Layer              │
│  (.git 目录结构、索引、配置)              │
├─────────────────────────────────────────┤
│           Packfile & Delta Layer         │
│  (压缩存储、增量传输)                     │
└─────────────────────────────────────────┘

学习收获

  • 理解了 Git 内部的对象模型(DAG 结构)
  • 理解了为什么 Git 能高效处理分支(branch 只是一个指针)
  • 理解了 git push 时网络传输的内容(不是文件差异,而是 packfile)

3.3 容器化技术的架构演进

「Build your own Docker」项目揭示了容器化技术的核心原理:

传统虚拟机:
┌─────────┐  ┌─────────┐  ┌─────────┐
│  App A  │  │  App B  │  │  App C  │
├─────────┤  ├─────────┤  ├─────────┤
│  Guest  │  │  Guest  │  │  Guest  │
│   OS    │  │   OS    │  │   OS    │
├─────────┤  ├─────────┤  ├─────────┤
│        Hypervisor (硬件抽象层)           │
├─────────────────────────────────────────┤
│           Host Hardware                 │
└─────────────────────────────────────────┘

容器化:
┌─────────┐  ┌─────────┐  ┌─────────┐
│  App A  │  │  App B  │  │  App C  │
├─────────┤  ├─────────┤  ├─────────┤
│  Libs   │  │  Libs   │  │  Libs   │
├─────────┤  ├─────────┤  ├─────────┤
│  Namespaces (PID/Net/Mount/...)        │
├─────────────────────────────────────────┤
│        Cgroups (资源限制)               │
├─────────────────────────────────────────┤
│           Host Kernel                   │
└─────────────────────────────────────────┘

核心区别

  • 虚拟机:完整 OS + 虚拟硬件 → 重、慢、隔离强
  • 容器:共享 Host Kernel + 命名空间隔离 → 轻、快、隔离弱

Build your own Docker 需要实现的核心功能

  1. 创建隔离的文件系统(chroot / pivot_root)
  2. 实现资源限制(cgroups CPU/内存控制)
  3. 实现进程隔离(unshare / namespaces)
  4. 实现网络隔离(bridge / veth pair)
  5. 实现镜像分层(AUFS / OverlayFS)

§4 学习路径建议

4.1 按难度梯度选择

入门级(⭐⭐,适合 1-2 年经验)

  • Build your own HTTP Server → 理解 Web 开发基础
  • Build your own Web Framework → 理解 MVC 原理
  • Build your own Game of Life → 理解细胞自动机

进阶级(⭐⭐⭐,适合 2-4 年经验)

  • Build your own BitTorrent → 理解 P2P 网络
  • Build your own Git → 理解版本控制设计
  • Build your own Webpack → 理解打包原理

高级(⭐⭐⭐⭐,适合 4+ 年经验)

  • Build your own Docker → 理解容器化底层
  • Build your own Redis → 理解内存存储设计
  • Build your own Database → 理解存储引擎

大师级(⭐⭐⭐⭐⭐,适合架构师 / 系统工程师)

  • Build your own Lisp → 理解语言设计
  • Build your own Operating System → 理解系统编程
  • Build your own Compiler → 理解语言转换

4.2 按职业方向选择

后端工程师

必做:Redis → Docker → Git → HTTP Server → Database
选做:Message Queue → Load Balancer → RPC Framework

前端工程师

必做:Webpack → React → Redux → Web Framework
选做:Browser Engine → CSS Parser → Template Engine

基础架构工程师

必做:Docker → Kubernetes → Load Balancer → Database
选做:Operating System → Network Stack → Filesystem

安全工程师

必做:TLS → Password Manager → Blockchain → Vulnerability Scanner
选做:Reverse Shell → Exploit Framework

4.3 学习方法论

1. 先读规范,再写代码

每个 challenge 都有 REQUIREMENTS.md 文件。在开始写代码之前:

✅ 正确做法:
1. 仔细阅读需求规范
2. 理解测试用例的设计意图
3. 画出简单的架构草图
4. 再开始实现

❌ 错误做法:
1. 直接去看参考实现
2. 照抄代码
3. 通过测试但不理解原理

2. 对比官方实现

完成自己的实现后,一定要去对比官方源码:

你的实现                    官方实现
┌─────────────────┐       ┌─────────────────┐
│ 为什么这样设计? │  ←→   │ 他们考虑了哪些   │
│ 我的设计缺陷?  │       │ 我没考虑到的case?│
│ 性能差异在哪?  │       │ 权衡取舍是什么? │
└─────────────────┘       └─────────────────┘

3. 写学习笔记

每个项目完成后,建议写一份结构化的学习笔记:

项目名称:Build your own Git
完成时间:YYYY-MM-DD
核心收获:
  1. Git 的对象模型(blob/tree/commit/tag)
  2. DAG 结构如何支持分支
  3. ref 和 HEAD 的关系
关键洞察:
  - Git 的设计哲学是「内容寻址」而非「文件差异」
  - branch 只是一个 41 字节的文件
  - push 的本质是传输 packfile
延伸思考:
  - 如果我要设计一个分布式配置中心,参考 Git 的哪些设计?

§5 如何高效使用本仓库

5.1 本地环境准备

基础工具

# Git(我们正在学习理解的对象)
git --version

# Docker(用于运行测试环境)
docker --version

# 你选择的编程语言环境
python3 --version  # 或
go version         # 或
rustc --version    # 或
node --version

推荐安装

# Git 源码(用于对比学习)
git clone https://github.com/git/git

# 一些项目需要的额外依赖
# 参考各项目的 README.md

5.2 项目结构说明

克隆仓库后,你会看到如下结构:

build-your-own-x/
├── CONTRIBUTING.md          # 贡献指南
├── README.md                # 项目总览
├── .github/
│   └── workflows/           # CI/CD 配置
├── build-your-own-actor/    # 每个技术方向一个目录
├── build-your-own-api/
├── build-your-own-bittorrent/
├── build-your-own-blockchain/
├── build-your-own-bot/
├── build-your-own-cli/
├── build-your-own-database/
├── build-your-own-docker/
├── build-your-own-email/
├── build-your-own-front-end-framework/
├── build-your-own-game/
├── build-your-own-git/
├── build-your-own-http-server/
├── build-your-own-javascript-framework/
├── build-your-own-load-balancer/
├── build-your-own-music-player/
├── build-your-own-npm/
├── build-your-own-no-sql/
├── build-your-own-object-storage/
├── build-your-own-orm/
├── build-your-own-react/
├── build-your-own-redis/
├── build-your-own-shell/
├── build-your-own-template-engine/
├── build-your-own-terraform/
├── build-your-own-database/
└── ...(共 30+ 方向)

每个子目录内部:

build-your-own-git/
├── README.md
├── REQUIREMENTS.md          # 需求规范
├── TESTED_VERSION.md        # 测试环境版本
├── solutions/               # 参考实现(按语言分组)
│   ├── python/
│   ├── go/
│   └── ...
└── .gitignore

5.3 学习流程示范

以「Build your own Git」为例:

Step 1: 阅读需求

cd build-your-own-git
cat REQUIREMENTS.md

Step 2: 理解测试框架

# 查看有哪些测试用例
ls solutions/python/

# 运行测试
cd solutions/python
./test.sh
# 期望看到:所有测试失败(因为你还没实现)

Step 3: 逐层实现

# Step 3.1: 实现 git init
# 需要创建 .git 目录结构

# Step 3.2: 实现 git hash-object
# 需要理解 SHA-1 哈希和对象存储

# Step 3.3: 实现 git cat-file
# 需要从 .git/objects 读取并解析对象

# ... 以此类推

Step 4: 验证

./test.sh
# 期望:所有测试通过 ✅

Step 5: 对比优化

# 查看官方 git 源码
# 思考:为什么他们这样设计?
# 我的实现有哪些改进空间?

5.4 与 Codecrafters 平台配合使用

如果你想要更结构化的学习体验,可以配合 Codecrafters 官方平台:

功能GitHub 仓库Codecrafters 平台
需求规范
测试用例✅(更自动化)
参考实现
官方解答
进度追踪
社区讨论
费用免费付费($49/月起)

建议:先用 GitHub 仓库学习,如果某个项目特别感兴趣,再考虑用平台深化学习。


§6 实践案例:实现一个简易 BitTorrent 客户端

6.1 BitTorrent 协议核心概念

在开始实现之前,需要理解以下核心概念:

BitTorrent 文件结构(.torrent)

{
  "announce": "http://tracker.example.com:6969/announce",  // tracker 地址
  "info": {
    "name": "ubuntu-22.04.iso",                              // 文件名
    "length": 3758096384,                                    // 文件大小
    "piece length": 524288,                                  // 每个 piece 512KB
    "pieces": "a8f3e2d1..."                                   // 所有 piece 的 SHA-1 哈希
  }
}

Tracker 协议

请求:announce?info_hash=XXX&peer_id=XXX&port=6881&uploaded=0&downloaded=0&left=1234567
响应:{"interval": 1800, "peers": [{"ip": "1.2.3.4", "port": 6881}, ...]}

Piece 选择算法

  • Strict Priority:优先请求每个 piece 的第一个子块
  • Rarest First:优先请求 peers 中拥有最少的 piece
  • Endgame Mode:最后阶段,请求所有剩余子块

6.2 简化版实现

以下是一个极简的 BitTorrent 客户端实现框架:

import hashlib
import socket
import bencodepy  # bencode 编码库

class BitTorrentClient:
    def __init__(self, torrent_path):
        # 读取 .torrent 文件
        with open(torrent_path, 'rb') as f:
            self.torrent = bencodepy.decode(f.read())
        
        self.peer_id = self._generate_peer_id()
        self.peers = []
    
    def _generate_peer_id(self):
        # 生成 20 字节的 peer_id
        import random
        return '-PY0001-' + ''.join([str(random.randint(0, 9)) for _ in range(12)])
    
    def get_peers(self):
        """向 tracker 注册并获取 peers 列表"""
        info_hash = hashlib.sha1(bencodepy.encode(self.torrent[b'info'])).digest()
        
        # 构建 HTTP GET 请求到 tracker
        params = {
            'info_hash': info_hash,
            'peer_id': self.peer_id.encode(),
            'port': 6881,
            'uploaded': 0,
            'downloaded': 0,
            'left': self.torrent[b'info'][b'length'],
            'compact': 1
        }
        
        # 发送请求并解析响应
        # ...
        return self.peers
    
    def download_piece(self, peer, piece_index):
        """从指定 peer 下载指定 piece"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((peer['ip'], peer['port']))
        
        # 1. 握手
        protocol = b'BitTorrent protocol'
        handshake = protocol + (b'\x00' * 8) + info_hash + self.peer_id.encode()
        sock.send(handshake)
        
        # 2. 接收握手响应
        response = sock.recv(68)
        
        # 3. 下载 piece
        # ... 实现 BitTorrent 协议的消息交互
        
        sock.close()
        return piece_data
    
    def verify_piece(self, piece_index, data):
        """验证 piece 的 SHA-1 哈希"""
        expected_hash = self.torrent[b'info'][b'pieces'][piece_index * 20:(piece_index + 1) * 20]
        actual_hash = hashlib.sha1(data).digest()
        return expected_hash == actual_hash

6.3 关键实现要点

1. B编码解析

BitTorrent 使用 B编码(Bencode)格式:

字符串:4:spam → "spam"
整数: i3e    → 3
列表: li3e4:spame → [3, "spam"]
字典: d3:foo3:bare → {"foo": "bar"}

2. Piece 下载策略

def select_piece_to_download(self, available_pieces, peer_pieces):
    """
    Rarest First 策略:
    1. 统计每个 piece 在所有 peers 中的分布
    2. 优先下载 rarity(稀有度)最低的 piece
    """
    piece_rarity = Counter()
    for peer in peer_pieces:
        for piece in peer:
            piece_rarity[piece] += 1
    
    # 选择 rarity 最小的 piece
    return min(available_pieces, key=lambda p: piece_rarity.get(p, float('inf')))

3. 磁盘 I/O 优化

实际实现中,需要考虑:

  • 写入磁盘前先在内存中 buffer 多个 pieces
  • 使用线程池并行下载多个 pieces
  • 实现 Piece 缓存避免重复读取

§7 总结与延伸

7.1 核心收获

通过 build-your-own-x 的学习,你将获得:

1. 底层原理的深入理解

不再困惑:「为什么 Redis 这么快?」
→ 因为你亲手实现了 SDS、跳表、事件循环
→ 你知道每一步的时间复杂度

2. 系统设计能力的提升

不再盲从:「这个框架为什么要这样设计?」
→ 因为你思考过「如果我来实现,会怎么做」
→ 你能评估设计权衡

3. 调试能力的质变

不再恐惧:「这个 bug 怎么修?」
→ 因为你理解每一行的行为
→ 你能快速定位问题

7.2 延伸学习资源

官方资源

补充项目

书籍推荐

书籍关联项目收获
《Linux 高性能服务器编程》Build your own HTTP Server深入理解网络编程
《Redis 设计与实现》Build your own Redis理解 Redis 内部原理
《自己动手写 Docker》Build your own Docker理解容器化技术
《操作系统真象还原》Build your own OS系统编程入门
《编译原理》龙书Build your own Lisp编译器基础

7.3 行动建议

立即开始

  1. 访问 GitHub 仓库
  2. 找到一个感兴趣的技术方向
  3. 开始第一个 challenge

坚持实践

  • 每周完成 1 个小型项目(如 HTTP Server)
  • 每两周完成 1 个中型项目(如 Git)
  • 每月完成 1 个大型项目(如 Docker)

输出沉淀

  • 每完成一个项目,写一篇学习笔记
  • 尝试在团队内部分享
  • 考虑贡献 PR 到本仓库

本文基于 GitHub 仓库 codecrafters-io/build-your-own-x(494,944 Stars,MIT License)编写。