Module 19: 项目实战技能
Module 0-18 教你”设计和理解系统”,这个模块教你”把系统做出来”。覆盖日常开发中每天都会用到的基础技能:Git、终端、测试、Scrum、代码审查、源码阅读、AI辅助开发。
17.1 Git 实操
Section titled “17.1 Git 实操”定义:Git 是分布式版本控制系统,记录代码的每一次变更,支持多人协作。不只是”保存”,而是让你能回溯历史、并行开发、安全合并。
为什么重要:所有团队协作的基础。不会Git = 不能参与任何正式项目。
日常必备命令:
# 基础流程git clone <url> # 克隆仓库git status # 查看当前状态git add <file> # 暂存变更git commit -m "message" # 提交git push # 推送到远端git pull # 拉取远端变更
# 分支操作git branch feature-x # 创建分支git checkout feature-x # 切换分支(或 git switch feature-x)git merge main # 合并main到当前分支git branch -d feature-x # 删除分支
# 常用场景git log --oneline -10 # 查看最近10条提交git diff # 查看未暂存的修改git stash # 临时保存未提交的修改git stash pop # 恢复临时保存git reset HEAD~1 # 撤回最近一次提交(保留修改)git cherry-pick <hash> # 把某个提交搬到当前分支常见场景处理:
| 场景 | 命令 |
|---|---|
| 提交了不该提交的文件 | git reset HEAD~1(撤回提交)→ 修改 .gitignore → 重新提交 |
| 合并冲突 | 打开冲突文件 → 手动解决 <<< === >>> 标记 → git add → git commit |
| 想在另一个分支上的改动 | git stash → git checkout other-branch → git stash pop |
| 提交信息写错了 | git commit --amend -m "正确的信息" |
| 把main的更新同步到feature分支 | git checkout feature → git rebase main(或 git merge main) |
| 需要回退到某个版本 | git log 找到hash → git checkout <hash> 查看 → 确认后 git revert <hash> |
Commit Message 规范:
<type>: <简短描述>
type 常用值:feat: 新功能fix: 修复bugrefactor: 重构(不改变功能)docs: 文档test: 测试chore: 构建/工具/依赖变更
示例:feat: add user login with JWTfix: prevent double booking in reservationrefactor: extract payment logic to separate service先想一想 🤔 你在feature分支开发了3天,main分支上有其他人的5个新提交。你用
git merge main还是git rebase main?各自有什么效果?点击查看解析
git merge main:创建一个合并提交,保留完整的分支历史。历史图会有分叉和合并。git rebase main:把你的3天提交”搬”到main最新的后面,历史线性清晰,但改写了提交hash。- 选择:个人分支用rebase(历史干净),公共分支用merge(安全不改写历史)。
17.2 终端与命令行
Section titled “17.2 终端与命令行”定义:终端(Terminal)是与操作系统交互的文字界面。掌握基础命令是开发者的必备技能。
为什么重要:服务器没有图形界面,部署、调试、运维都依赖命令行。很多开发工具(Git、Docker、npm)本质是命令行工具。
必备命令:
# 文件与目录ls -la # 列出文件(含隐藏文件)cd /path/to/dir # 切换目录mkdir -p a/b/c # 创建嵌套目录cp -r src dst # 复制目录mv old new # 移动/重命名rm -rf dir # 删除目录(谨慎!)find . -name "*.go" # 搜索文件grep -r "TODO" . # 搜索内容
# 查看与编辑cat file.txt # 查看文件head -20 file.txt # 查看前20行tail -f log.txt # 实时跟踪日志vim file.txt # 编辑(i进入编辑, Esc退出编辑, :wq保存退出)
# 网络curl -X GET url # 发HTTP请求curl -X POST -d '{}' -H 'Content-Type: application/json' urlping google.com # 测试网络连通ssh user@host # 远程登录
# 进程ps aux | grep node # 查找进程kill <pid> # 终止进程top / htop # 系统资源监控
# 实用技巧command1 | command2 # 管道:把前一个命令的输出作为后一个的输入command > file.txt # 输出重定向到文件command >> file.txt # 追加到文件Ctrl+C # 终止当前命令Ctrl+R # 搜索历史命令!! # 重复上一条命令先想一想 🤔 服务器上的应用突然变慢,你需要快速排查。依次用什么命令?
点击查看解析
top— 看CPU和内存占用最高的进程df -h— 看磁盘空间是否满了free -h— 看内存使用情况tail -100 /var/log/app.log— 看最近的应用日志netstat -tlnp— 看端口占用和连接数curl localhost:8080/health— 检查应用健康状态
17.3 Docker 实操
Section titled “17.3 Docker 实操”定义:Module 16.1-16.2 介绍了 Docker 的概念,这里补充日常开发中的实操命令和调试技巧。
日常命令:
# 镜像操作docker build -t myapp:v1 . # 从Dockerfile构建镜像docker images # 列出本地镜像docker pull postgres:16 # 拉取镜像docker rmi <image_id> # 删除镜像
# 容器操作docker run -d -p 8080:8080 --name myapp myapp:v1 # 后台运行docker ps # 查看运行中的容器docker ps -a # 查看所有容器(含已停止)docker logs -f myapp # 实时查看日志docker exec -it myapp /bin/sh # 进入容器内部docker stop myapp # 停止容器docker rm myapp # 删除容器
# Docker Composedocker compose up -d # 启动所有服务docker compose down # 停止并删除docker compose logs -f api # 查看某个服务的日志docker compose exec api sh # 进入某个服务docker compose ps # 查看服务状态docker compose restart api # 重启某个服务
# 调试docker logs myapp 2>&1 | grep "error" # 搜索错误日志docker inspect myapp # 查看容器详细信息docker stats # 实时资源使用docker compose config # 验证compose文件语法常见问题排查:
| 问题 | 排查方法 |
|---|---|
| 容器启动就退出 | docker logs <name> 看报错 |
| 端口访问不通 | docker ps 检查端口映射;确认应用监听的是 0.0.0.0 不是 localhost |
| 容器间无法通信 | 确认在同一 docker network;用服务名而非localhost作为主机名 |
| 磁盘空间不足 | docker system prune 清理无用镜像/容器/网络 |
| 修改代码后不生效 | 确认用了 volume 挂载本地目录(开发模式)或重新 build 镜像 |
先想一想 🤔 docker-compose.yml 里,API 服务要连接 PostgreSQL。连接字符串里的 host 应该写什么?
点击查看解析
写 Docker Compose 里定义的服务名(如
postgres或db),不是localhost。 Docker Compose 会自动创建网络,服务名会被解析为对应容器的IP。 例:DATABASE_URL=postgres://user:pass@db:5432/mydb
17.4 测试
Section titled “17.4 测试”定义:通过自动化代码验证系统行为是否符合预期。测试分多个层次:单元测试(测函数)、集成测试(测模块交互)、端到端测试(测完整用户流程)。
为什么重要:没有测试 = 每次改代码都在赌”没改坏其他地方”。测试是你的安全网。
测试金字塔:
△ / \ / E2E \ ← 少量:模拟真实用户操作(Playwright/Cypress) /-------\ / 集成测试 \ ← 适量:测试模块间交互(API测试、数据库交互) /-----------\ / 单元测试 \ ← 大量:测试单个函数/方法(快、多、便宜) /_______________\各层次示例(以 Hotel Reservation 为例):
// 单元测试:测试价格计算函数func TestCalculatePrice(t *testing.T) { // 3晚 × 每晚200 = 600 price := CalculatePrice(200, 3) assert.Equal(t, 600, price)}
// 集成测试:测试预订API + 数据库func TestBookingAPI(t *testing.T) { // 准备:数据库里有库存 // 动作:调用POST /api/bookings // 验证:返回201,库存减少,订单创建}
// E2E测试:完整预订流程// 搜索酒店 → 选房型 → 填信息 → 支付 → 确认什么时候写测试:
| 场景 | 建议 |
|---|---|
| 核心业务逻辑(如库存扣减) | 必须有单元+集成测试 |
| API接口 | 集成测试覆盖主流程+边界 |
| 复杂算法 | 单元测试覆盖各种输入 |
| UI交互 | 关键流程E2E测试 |
| 工具函数 | 单元测试 |
| 简单CRUD | 按需,不必追求100%覆盖率 |
给AI的测试指令:
请为以下函数写单元测试,覆盖:1. 正常情况2. 边界值(0、负数、最大值)3. 异常情况(参数为nil、空字符串)用表驱动测试(table-driven test)的方式组织先想一想 🤔 Hotel Reservation 的库存扣减逻辑,你会写什么测试用例?
点击查看解析
- 正常预订:库存5,预订1,库存变4 ✓
- 最后一间:库存1,预订1,库存变0 ✓
- 库存不足:库存0,预订1 → 报错 ✓
- 并发预订:库存1,两人同时预订 → 只有一人成功 ✓
- 取消恢复:预订后取消,库存恢复 ✓
- 跨日期:预订3晚,每晚库存都扣减 ✓
17.5 Scrum 与敏捷开发
Section titled “17.5 Scrum 与敏捷开发”定义:Scrum 是最流行的敏捷开发框架。核心思想:把大项目拆成小迭代(Sprint),每个Sprint(通常2周)交付可工作的功能,快速反馈、快速调整。
为什么重要:瀑布模式(需求→设计→开发→测试→上线)的问题是周期太长,上线时需求可能已经变了。Scrum让你每2周就能交付价值,及时调整方向。
核心角色:
| 角色 | 职责 |
|---|---|
| Product Owner (PO) | 决定做什么、优先级。维护 Product Backlog |
| Scrum Master (SM) | 保障流程运作,移除障碍 |
| 开发团队 | 决定怎么做,自组织完成Sprint目标 |
核心仪式:
| 仪式 | 时间 | 做什么 |
|---|---|---|
| Sprint Planning | Sprint开始 | 从Backlog选取本Sprint要做的任务,评估工作量 |
| Daily Standup | 每天15分钟 | 每人说:昨天做了什么/今天做什么/有什么阻碍 |
| Sprint Review | Sprint结束 | 演示成果,收集反馈 |
| Sprint Retro | Sprint结束 | 回顾:什么做得好/什么要改进/下步行动 |
核心概念:
- Product Backlog:所有待做事项的优先级列表(PO维护)
- Sprint Backlog:本Sprint承诺要完成的任务子集
- User Story:
作为<角色>,我想要<功能>,以便<价值> - Story Points:工作量的相对估算(斐波那契:1, 2, 3, 5, 8, 13)
- Velocity:团队每个Sprint平均完成多少Story Points
- Definition of Done:什么算”完成”(代码写完+测试通过+代码审查+部署到staging)
User Story 示例(Hotel Reservation):
作为旅客,我想要按城市和日期搜索可用酒店,以便找到合适的住处。
验收标准:- [ ] 输入城市+入住/退房日期,返回有库存的酒店列表- [ ] 按价格排序- [ ] 显示每晚最低价- [ ] 无结果时显示提示信息看板(Kanban):
┌──────────┬──────────┬──────────┬──────────┐│ To Do │ In │ In │ Done ││ │ Progress │ Review │ │├──────────┼──────────┼──────────┼──────────┤│ 支付集成 │ 搜索API │ 预订API │ 登录功能 ││ 邮件通知 │ │ │ 数据模型 ││ 取消预订 │ │ │ │└──────────┴──────────┴──────────┴──────────┘先想一想 🤔 一个 User Story 估了13个Story Points,这意味着什么?应该怎么处理?
点击查看解析
13 points 说明这个故事太大了,复杂度高,不确定性大。应该拆分成多个更小的故事(每个3-5 points)。 例:“支付集成”可以拆成:1) 创建支付意图 (3pt) 2) 支付回调处理 (5pt) 3) 退款 (3pt) 如果不能拆,说明需求还没想清楚,先做Spike(技术调研)。
17.6 代码审查(Code Review)
Section titled “17.6 代码审查(Code Review)”定义:在代码合并到主分支之前,由其他开发者审查代码质量、逻辑正确性、安全性的过程。通常通过 Pull Request (PR) / Merge Request (MR) 进行。
为什么重要:发现bug最便宜的时机是在合并之前。同时也是团队知识分享的重要渠道。
审查清单:
功能正确性- [ ] 代码是否实现了需求描述的功能?- [ ] 边界情况是否处理?- [ ] 错误处理是否合理?
代码质量- [ ] 命名是否清晰?(变量/函数/文件名)- [ ] 有没有重复代码可以提取?- [ ] 函数是否过长?(>50行考虑拆分)- [ ] 是否有不必要的复杂度?
安全性(→ Module 14)- [ ] 用户输入是否校验?- [ ] SQL是否参数化?- [ ] 有没有敏感信息硬编码?
性能- [ ] 有N+1查询吗?- [ ] 有不必要的循环/重复计算吗?
测试- [ ] 关键逻辑有测试覆盖吗?- [ ] 测试是否能真正验证功能?提PR的最佳实践:
## PR标题feat: 添加酒店搜索API
## 变更说明- 新增 GET /api/hotels/search 接口- 支持按城市+日期范围搜索- 搜索结果按价格排序,支持分页
## 测试- [x] 单元测试:搜索逻辑- [x] 集成测试:API端到端- [ ] 手动测试:用Postman跑通
## 截图/录屏(如有UI变更)...Review 反馈原则:
- 对代码提意见,不对人
- 用建议而非命令(“考虑用X替代Y?” 而非 “改成X”)
- 重要问题阻塞合并,风格偏好建议但不阻塞
17.7 源码阅读
Section titled “17.7 源码阅读”定义:阅读和理解他人编写的代码库。这是进入任何项目、学习最佳实践、排查问题的核心能力。
为什么重要:开发者80%的时间在读代码,20%在写代码。能快速理解一个陌生代码库 = 生产力的核心。
阅读策略(由外到内):
第1步:全局视角(5分钟)├── README.md — 项目做什么?怎么跑起来?├── 目录结构 — 代码怎么组织的?├── package.json / go.mod — 用了什么依赖?└── 入口文件 — 程序从哪里开始?
第2步:数据流(15分钟)├── 数据模型 — 有哪些实体?关系如何?├── API路由 — 有哪些接口?└── 挑一个API — 从路由→handler→service→数据库走一遍
第3步:关键流程(30分钟)├── 找到核心业务逻辑├── 画出调用链└── 标注不理解的地方用 AI 辅助读源码:
# 让AI解释整体架构"请阅读这个项目的目录结构和核心文件,概括:1. 这个项目做什么?2. 技术栈是什么?3. 代码是怎么组织的?4. 核心业务流程有哪些?"
# 让AI解释具体代码"请解释这个函数的逻辑,重点说明:1. 输入和输出是什么?2. 核心算法/逻辑是什么?3. 有什么边界情况的处理?"
# 让AI画调用链"从 POST /api/bookings 开始,追踪完整的调用链,列出经过的每个函数和文件"先想一想 🤔 你接手一个完全陌生的Go+React项目,第一个小时你会怎么做?
点击查看解析
- 读README(5分钟)— 了解项目是什么、怎么跑
ls看目录结构(2分钟)— 了解代码组织- 跑起来(10分钟)—
docker compose up或按README步骤- 用浏览器/Postman体验功能(10分钟)— 建立直觉
- 看数据模型(10分钟)— models/目录,了解核心实体
- 看路由/API(5分钟)— 有哪些接口
- 挑一个核心API从头追到尾(15分钟)
- 用AI问不理解的部分(剩余时间)
17.8 AI 辅助开发技巧
Section titled “17.8 AI 辅助开发技巧”定义:使用 AI 工具(Claude Code、Cursor、Copilot等)提高开发效率的实践方法。
为什么重要:AI 不会取代开发者,但会用 AI 的开发者会取代不会用的。关键是知道 AI 擅长什么、不擅长什么。
AI 擅长 vs 不擅长:
| AI 擅长 | AI 不擅长 |
|---|---|
| 写重复性代码(CRUD、API) | 架构设计(选什么技术、怎么拆分) |
| 写测试用例 | 理解业务背景和需求优先级 |
| 代码转换(一种语言→另一种) | 判断需求是否合理 |
| 解释代码、找bug | 决定”不做什么”(克制) |
| 生成样板代码 | 跨系统的一致性保证 |
| 重构和优化 | 生产环境的运维决策 |
高效 Prompt 模式:
模式1: 明确需求 + 约束条件"用Go+Gin写一个限流中间件,使用令牌桶算法,支持按IP限流,每分钟100次,用Redis存储计数器"
模式2: 给上下文 + 要求扩展"这是现有的用户模型(附代码),请添加OAuth登录功能,要求:支持GitHub和Google,用JWT返回token"
模式3: 给出问题 + 要求排查"这个API在并发请求时偶尔返回错误的库存数。请检查代码中的并发问题并修复"
模式4: 分步实现第1步: "先创建数据模型和数据库表"第2步: "基于数据模型实现CRUD API"第3步: "添加认证中间件"第4步: "添加测试"(不要一次要求太多,分步迭代质量更高)Vibe Coding 工作流:
1. 用5层框架分析需求(自己做)2. 用 vibe-coding-recipes.md 找到对应配方3. 填入具体需求,给AI生成MVP代码4. 跑起来验证基本功能5. 用 review-checklist.md 审查代码6. 逐步迭代:加认证 → 加缓存 → 加测试 → 加监控17.9 项目管理工具
Section titled “17.9 项目管理工具”定义:帮助团队跟踪任务进度、管理需求、协作沟通的工具。
常用工具对比:
| 工具 | 特点 | 适合 |
|---|---|---|
| GitHub Issues + Projects | 和代码仓库深度集成,Kanban视图 | 开源项目、小团队 |
| Linear | 简洁快速,键盘操作友好 | 初创公司、技术团队 |
| Jira | 功能最全,高度可定制 | 中大型企业 |
| Notion | 灵活的文档+数据库,可当轻量看板 | 个人/小团队 |
| Trello | 简单直观的Kanban | 非技术团队、简单项目 |
GitHub Issues 实践:
# Issue 标题feat: 添加酒店搜索功能
# 描述## 用户故事作为旅客,我想要按城市和日期搜索可用酒店。
## 验收标准- [ ] GET /api/hotels/search?city=&check_in=&check_out=- [ ] 返回有库存的酒店列表- [ ] 按价格排序- [ ] 分页(cursor-based)
## 技术说明- 搜索结果缓存30秒(Redis)- 使用PostGIS进行位置筛选
## 标签enhancement, backend, priority: high17.10 文档编写
Section titled “17.10 文档编写”定义:技术文档是代码之外最重要的产出。好的文档让别人(包括未来的自己)能快速理解和使用项目。
必写的文档:
| 文档 | 内容 | 什么时候写 |
|---|---|---|
| README.md | 项目介绍、如何运行、技术栈、目录结构 | 项目创建时 |
| API文档 | 接口列表、请求/响应格式、认证方式 | API开发完成时 |
| ADR (Architecture Decision Record) | 重要技术决策的记录(选了什么、为什么、考虑过什么替代方案) | 做重要决策时 |
| CHANGELOG | 版本变更记录 | 每次发版时 |
README 模板:
# 项目名
一句话描述这个项目做什么。
## 技术栈- 后端:Go + Gin + PostgreSQL- 前端:React + Vite + Tailwind- 缓存:Redis- 部署:Docker
## 快速开始
### 前置要求- Docker + Docker Compose- Go 1.22+- Node.js 20+
### 运行git clone <url>cp .env.example .envdocker compose up -dcd server && go run .cd web && npm install && npm run dev
### 访问- 前端: http://localhost:5173- API: http://localhost:8080- API文档: http://localhost:8080/swagger
## 目录结构server/ # Go后端 handlers/ # API处理器 models/ # 数据模型 middleware/ # 中间件web/ # React前端 src/pages/ # 页面 src/api/ # API客户端
## 环境变量| 变量 | 说明 | 示例 ||------|------|------|| DATABASE_URL | 数据库连接 | postgres://... || JWT_SECRET | JWT密钥 | random-string |ADR 模板:
# ADR-001: 使用PostgreSQL而非MongoDB
## 状态已采纳 (2024-01-15)
## 背景需要选择主数据库,数据模型有明确的关系(酒店-房型-库存-订单)。
## 决策选择 PostgreSQL。
## 理由- 数据模型有明确关系,外键和事务是核心需求- 库存扣减需要ACID事务保证- PostGIS扩展支持位置搜索- 团队熟悉SQL
## 考虑过的替代方案- MongoDB:schema灵活但缺少事务,不适合库存场景- MySQL:可行但PostgreSQL的JSON和GIS支持更好
## 影响- ORM使用GORM- 需要编写migration管理schema变更练习1: Git 实战
Section titled “练习1: Git 实战”- 创建一个新仓库
- 创建
feature/search分支,提交3次 - 回到
main,故意修改同一个文件,提交 - 合并
feature/search到main,解决冲突 - 用
git log --graph --oneline查看历史
练习2: 完整项目启动
Section titled “练习2: 完整项目启动”模拟从零开始一个项目:
- 用 Scrum 的方式写 3 个 User Story(以 Hotel Reservation 为例)
- 估算 Story Points
- 创建 GitHub 仓库 + README
- 用 Docker Compose 搭建开发环境(Go + PostgreSQL + Redis)
- 创建第一个 PR,互相 Code Review
练习3: 源码阅读
Section titled “练习3: 源码阅读”- 选一个开源项目(如 gin-gonic/gin)
- 用”由外到内”策略,在1小时内理解它的核心架构
- 写一段200字的总结:这个项目做什么?怎么组织的?核心设计决策是什么?