一个迭代的完整开发流程
从需求评审到上线复盘,一个规范的迭代要经过七道关。这篇文章按时间顺序拆解每个阶段的具体动作、产出物,以及最容易出问题的环节。
一、为什么需要流程
小团队常说"流程太重会拖慢速度"。这话有一半是对的——流程的价值取决于它能否减少返工。
一个没有流程的迭代通常长这样:
产品口头说需求 → 开发凭理解写代码 → 测试凭感觉验 → 上线出问题 → 相互甩锅
问题不在于"慢",而在于返工成本被隐藏了:需求理解偏差导致重写、边界场景没考虑导致线上 bug、没有回滚方案导致故障持续时间长。
一套合理的流程,本质上是把这些问题提前暴露。
二、七个阶段
阶段 1:需求评审
输入:需求文档(PRD)、原型图 参与:产品、前端、后端、测试 产出:确认后的需求 + 接口方案初稿
这个阶段要做的事:
| 动作 | 目的 |
|---|---|
| 梳理业务逻辑 | 确认理解一致,不是"听懂了"而是"说得出" |
| 确认边界场景 | 空数据、超限、并发、异常流程怎么处理 |
| 当场提疑问 | 有歧义当场问清,别带回去猜 |
| 评估技术可行性 | 有没有实现不了的点、需要提前调研的技术 |
最容易出问题的环节就在这里。 需求的歧义如果不在评审时澄清,就会在开发时变成"我以为",在测试时变成"这不是 bug",在上线后变成"需求本来就是这样"。
一些值得当场问清的问题:
- 这个状态流转有没有逆向流程?(比如"已发货"能不能撤回"待发货")
- 数据量级是多少?(决定要不要分页、要不要缓存)
- 失败怎么处理?有没有重试、有没有人工介入?
- 和历史数据怎么兼容?
- 权限怎么控制?谁能看、谁能改?
阶段 2:任务拆解与排期
产出:任务列表 + 工时评估 + 交付时间
把大需求拆成可独立开发、可独立验证的细任务:
❌ 粗粒度:"实现订单模块"(无法评估工时,无法并行)
✅ 细粒度:"订单表设计(2h)" / "下单接口(6h)" /
"订单列表接口(4h)" / "超时取消任务(3h)" / "单元测试(3h)"
拆解的两个作用:
- 让估时可信——估一个 40 小时的任务误差极大,估 5 个 8 小时的任务误差小得多
- 让风险可见——某个任务估不出来,说明技术方案还没想清楚,要提前调研
风险点要显式标记:依赖第三方接口、涉及数据迁移、需要压测验证的,都要在排期时标出来,而不是等到做的当天才发现。
阶段 3:开发
技术侧的顺序通常是:
① 设计数据库表 → ② 定义接口 → ③ 写业务逻辑
→ ④ 写单元测试 → ⑤ 本地自测 → ⑥ 联调前端
先设计表、再定接口、最后写逻辑,这个顺序很重要。反过来做(先写逻辑,边写边加字段)几乎必然导致表结构反复改。
开发阶段的几个实践:
| 实践 | 作用 |
|---|---|
| 接口先定义 | 前后端可以并行开发,不用等后端写完 |
| 单元测试 | 覆盖核心逻辑和边界,尤其是金额、状态流转 |
| 本地自测 | 提测前自己先跑通主流程 |
| 代码评审(CR) | 提交前走评审,发现设计和实现问题 |
代码评审不是走形式。有效的 CR 会关注:有没有并发问题、异常处理是否完整、SQL 有没有性能隐患、边界条件是否覆盖。这些都是作者本人容易忽略的视角。
阶段 4:测试
产出:测试报告、bug 列表
测试要覆盖的层次:
| 层次 | 内容 |
|---|---|
| 功能测试 | 主流程能不能跑通 |
| 边界测试 | 空值、极值、超长输入、特殊字符 |
| 异常测试 | 网络中断、依赖服务不可用、超时 |
| 并发测试 | 同时下单、重复提交 |
| 兼容性 | 不同端、不同版本 |
bug 要闭环:修复 → 回归验证 → 关闭。不能出现"改了但没验证"的状态。
一个容易被忽略的点:测试环境的数据要和线上接近。用三条测试数据验证过的分页逻辑,在十万条数据下可能完全不同。
阶段 5:上线准备
产出:数据库脚本、配置变更清单、回滚方案
这个阶段常常被压缩甚至跳过,但它直接决定了出问题时的恢复速度。
| 准备项 | 说明 |
|---|---|
| 数据库变更脚本 | DDL 和 DML 要分开,大表加字段要注意锁表 |
| 配置变更清单 | 新增了哪些配置、默认值是什么 |
| 回滚方案 | 代码怎么回滚、数据怎么回滚 |
| 预发布验证 | 在预发布环境完整走一遍 |
| 依赖检查 | 新依赖的服务、中间件是否就绪 |
大表加字段是个经典坑:直接 ALTER TABLE 在大表上可能锁表几分钟。常见做法是先用 pt-online-schema-change 之类的工具,或者选业务低峰期执行。
阶段 6:生产上线
发布策略:
| 策略 | 做法 | 适用 |
|---|---|---|
| 停机发布 | 停服 → 部署 → 启动 | 内部系统、可接受停机 |
| 滚动发布 | 逐台替换,其余继续服务 | 集群部署的常规选择 |
| 蓝绿发布 | 新旧两套环境,切流量 | 要求快速回滚 |
| 灰度发布 | 先放量给部分用户 | 高风险变更 |
| 夜间发布 | 低峰期执行 | 影响面大的变更 |
上线后必须观察:
- 应用日志有没有异常堆栈
- 监控指标:QPS、响应时间、错误率、CPU/内存
- 数据库:慢查询、连接数
- 业务指标:下单成功率、支付成功率
观察期建议至少 30 分钟,高频业务要更长。很多问题不会在上线瞬间暴露,而是在流量爬升后才显现。
阶段 7:迭代复盘
产出:问题清单 + 改进项
复盘要回答三个问题:
- 这个迭代遇到了什么问题?
- 哪些是可以提前避免的?
- 下次怎么改?
复盘要聚焦流程,不聚焦人。"某某写了个 bug"没有价值,"为什么这个 bug 没被测试发现"才有价值。
三、分支管理
代码管理的基本规则是:禁止直接向主分支提交。
典型的分支流转:
feature/xxx → dev → release/预发布 → master(生产)
开发分支 测试 预发布验证 生产发布
| 分支 | 用途 | 谁能提交 |
|---|---|---|
feature/* |
功能开发 | 开发本人 |
dev |
集成测试 | 通过 CR 后合并 |
release/* |
预发布验证 | 由负责人合并 |
master |
生产 | 只接受 release 合并 |
主分支保护是硬性要求:开启分支保护、禁止 force push、必须通过 CR 才能合并。这些用 Git 平台的设置就能做到,不依赖自觉。
四、那些容易被压缩的环节
实际项目中,排期紧张时最先被砍掉的是下面这些——而它们恰恰是降低风险的关键:
| 被砍掉的 | 短期看 | 长期看 |
|---|---|---|
| 需求评审 | 省了半天 | 返工两天 |
| 单元测试 | 省了几小时 | 线上 bug 排查一天 |
| 代码评审 | 省了一小时 | 设计问题带到线上 |
| 回滚方案 | 省了半小时 | 故障持续几小时 |
| 复盘 | 省了一小时 | 同类问题反复出现 |
一个实用的判断标准:如果某个环节被砍掉后,出问题的成本远大于做它的成本,那它就不该被砍。
五、赶不上交付时间怎么办
这是工程实践中真实且高频的问题。合理的处理方式是切范围,而不是降质量:
第一步:把需求分成"核心闭环"和"边缘增强"
核心闭环:用户能走通主流程(比如"能下单并支付")
边缘增强:运营后台图表、非核心报表、边缘渠道适配
先保核心闭环,边缘的可以下个迭代补。
第二步:准备降级方案
如果某个功能没测完,可以用开关控制:
- 先上线页面,但用配置开关把请求路由到兜底逻辑
- 允许运营在后台临时手工处理少量数据
- 新功能默认关闭,验证后再打开
第三步:调整人力
把熟悉这块业务的开发抽调去攻坚核心难题,其他任务交给能胜任的人。测试侧集中火力测核心路径。
第四步:尽早向上同步
这一步最关键。不要在截止日才说做不完,而是在发现偏差的第一时间就带方案沟通:
"如果必须当天上线,我们能交付 A 和 B,C 和 D 要延期一周。是否可以接受?"
带方案沟通,而不是只报问题——这是工程沟通里最重要的一条。
一个基本判断
"准时上线一个范围收窄的版本" 通常比 "延迟上线一个完整版本" 更符合商业逻辑。
但前提是:范围收窄是有意为之的决策,而不是质量滑坡的结果。两者的区别在于——前者有明确的边界和兜底方案,后者是"没测完就上"。
小结
- 一个迭代的七阶段:需求评审 → 拆解排期 → 开发 → 测试 → 上线准备 → 生产上线 → 复盘
- 需求评审是最容易出问题的环节,歧义不在这里澄清,就会在后面每一步放大
- 开发顺序:先设计表 → 再定接口 → 最后写逻辑,反过来必然反复改表
- 代码评审关注并发、异常、SQL 性能、边界——这些是作者本人容易忽略的视角
- 上线准备不能省:大表加字段注意锁表,回滚方案要提前想好
- 发布后必须观察(建议 ≥30 分钟),很多问题在流量爬升后才暴露
- 分支管理:禁止直接提交主分支,主分支保护靠平台设置而不是自觉
- 排期紧张时优先砍范围,而不是砍质量——先保核心闭环
- 发现偏差要尽早带方案沟通,不要等到截止日
- "准时上线一个收窄的版本"优于"延迟上线一个完整版本",但前提是收窄是主动决策
流程的价值不在于"规范",而在于把返工成本提前暴露。任何环节如果做它的成本低于不做它的返工成本,它就值得保留。
留下点什么
评论基于 GitHub Discussions(giscus)。在项目根目录配置.env.local填入 NEXT_PUBLIC_GISCUS_* 四个变量后自动开启。