20 分钟
项目全解析

朋友好学架构总览

从全局视角理解这个项目的技术架构和设计哲学

  • 理解项目的整体架构选择
  • 掌握纯前端架构的优势和局限
  • 理解技术栈选型逻辑
  • 了解项目的数据流

为什么是纯前端架构?

Codecademy、freeCodeCamp这类在线编程教学平台,得靠后端服务器跑用户的代码。朋友好学的设计不一样:完全在浏览器里跑Python,不用后端。

🐍架构决策的底层逻辑

传统方案:用户代码 → 后端服务器执行 → 返回结果。问题:需要服务器成本并发限制安全风险(用户代码可能攻击服务器)网络延迟。Pyodide 方案:Python 编译为 WebAssembly,在浏览器沙箱中运行。优势:零服务器成本无限并发绝对安全(沙箱隔离)零延迟。代价:首次加载约 10MB(WASM 运行时),但可被 Service Worker 缓存。

技术栈全景

Python
# 朋友好学技术栈
print("""
┌─────────────────────────────────────────────┐
│                  浏览器                      │
│  ┌───────────────────────────────────────┐  │
│  │         Next.js 16 (App Router)       │  │
│  │  ┌─────────┐  ┌──────────────────┐   │  │
│  │  │  React   │  │  Monaco Editor   │   │  │
│  │  │  UI 层   │  │  (代码编辑器)     │   │  │
│  │  └────┬─────┘  └────────┬─────────┘   │  │
│  │       │    Zustand       │             │  │
│  │       │   (状态管理)      │             │  │
│  │  ┌────▼──────────────────▼──────────┐  │  │
│  │  │        Pyodide (WASM)            │  │  │
│  │  │   CPython 3.14 编译为 WebAssembly│  │  │
│  │  │   在 Web Worker 线程中运行        │  │  │
│  │  └──────────────────────────────────┘  │  │
│  └───────────────────────────────────────┘  │
│  Tailwind CSS │ Framer Motion │ localStorage│
└─────────────────────────────────────────────┘
         │                    │
    Service Worker       CDN (Pyodide包)
    (离线缓存)           (numpy/pandas)
""")

关键技术选型理由

ℹ️选型决策表

· 框架:Next.js 16 —— SSR / SSG + 路由 + 构建一体化· UI 库:自研 + Tailwind —— 极致定制,无组件库冗余· 编辑器:Monaco Editor —— VS Code 同款,功能最强· Python 运行时:Pyodide(WASM)—— 零后端、安全、零延迟· 状态管理:Zustand —— 轻量(1KB),API 简洁· 服务端状态:React Query —— 缓存、重试、后台刷新· 动画:Framer Motion —— 声明式 API,性能好· 样式:Tailwind CSS —— 原子化,零运行时开销· 数据持久化:localStorage —— 无需后端,离线可用· PWA:Service Worker —— 可安装、离线访问

数据流

理解数据流是理解整个项目的关键。

Python
# 用户点击"运行"后的完整数据流
print("""
1. 用户在 Monaco Editor 中写代码
   ↓ onChange
2. React State 更新(code 变量)
   ↓ 点击"运行"
3. usePythonExecutor.run(code)
   ↓ postMessage
4. Web Worker 接收消息
   ↓ import Pyodide
5. Pyodide 在 WASM 中执行 Python
   ↓ stdout/stderr 回调
6. Worker 收集输出
   ↓ postMessage
7. 主线程接收结果
   ↓ setResult
8. React 重新渲染输出面板
   ↓
9. 判题引擎比对输出(如果是挑战题)
   ↓
10. Zustand 更新进度/XP/成就
    ↓
11. localStorage 持久化
""")
💡Web Worker 的作用

Python 执行放在 Web Worker 中,不阻塞主线程。如果在主线程运行 Pyodide,执行死循环时整个页面会卡死。Worker 线程可以被 terminate() 强制终止,这是超时保护的基础。

选择题

朋友好学选择 Pyodide 而非后端执行 Python 的核心理由是什么?

选择题

朋友好学里,你写的 Python 代码实际运行在哪里?

资深工程师加餐

底层原理 · 大厂视角 · 工程经验,点卡片展开

UI、状态、业务逻辑、数据访问各层单向依赖:换一套 UI 不动业务,换一个数据源不动界面。依赖方向应向内收敛,最核心的业务规则尽量写成不依赖框架的纯函数——纯函数最好测、最好复用,这也是「整洁架构」思想在前端/客户端项目里的落地。

挑战任务

请求-响应配对(执行器核心思想)

简单+50 XP

主线程可能同时发多个请求,Worker 乱序返回结果。实现 match_order(request_ids, results):results 是若干 [请求id, 结果],返回按 request_ids 顺序排好的结果列表。

请求-响应配对(执行器核心思想)
1 个测试用例

课后作业

画出架构图

中等+20 XP

拿纸笔或者画图工具,画出朋友好学的完整架构图,把每一层的技术和数据流向都标清楚。

画出架构图
1 个测试用例