← 返回面试目录

🤝 全栈工作流与协作实战

项目全流程 · 需求评审 · 联调实战 · Git工作流 · 部署上线 · 踩坑经验

需求评审 技术方案 前后端联调 Git工作流 部署上线 踩坑经验

1. 项目全周期流程图

一个需求从提出到上线,一般经历以下 8 个环节。每个环节都有明确的产出物和责任人。

1需求评审
产出:PRD定稿
2技术方案
产出:技术文档
3排期
产出:里程碑计划
4开发
产出:代码+自测通过
5联调
产出:接口对齐
6测试
产出:测试报告
7部署
产出:上线完成
8监控
产出:稳定性保障

各环节产出物 & 关键人

环节产出物关键人注意点
需求评审 PRD定稿、需求澄清 产品、前端、后端 边界条件要问清楚
技术方案 技术文档、接口定义 后端(前端参与评审) 方案要过评审
排期 里程碑、提测时间 全组 留 buffer,别排太满
开发 代码、单元测试 前端、后端并行 接口先行,Mock数据
联调 接口对齐、前后端通 前端+后端 最常踩坑的环节
测试 测试报告、Bug列表 QA P0必须全部修完
部署 上线完成、部署记录 后端/运维 灰度发布、回滚方案
监控 告警配置、巡检 后端 上线后盯盘30分钟

2. 需求评审(怎么做)

评审前准备

先读PRD
完整通读一遍
标疑问点
不清楚的地方标出来
画技术草图
大致的技术方案

不要空着手去开会。提前 30 分钟读 PRD,带着问题去评审,效率翻倍。

评审时要问的 5 个问题

这 5 个问题能帮你避开 80% 的返工。

1边界条件是什么?

用户不填会怎样?传负数会怎样?超长文本呢?网络断了怎么办?这些异常/极端情况产品可能没写,但你要问。

2影响范围?哪些旧功能需要改?

新需求可能影响已有功能。比如新增了用户等级,那原有的优惠计算逻辑要不要改?列表页要不要加筛选?

3数据量预估?需要分表吗?

日增多少条?一年多少?需要分库分表吗?历史数据怎么处理?这些影响表结构设计,晚了改成本很高。

4上线策略?灰度还是全量?

是先给 10% 用户试试,还是直接全量?能不能加开关?万一有问题能快速关掉吗?

5回滚方案?出问题了怎么办?

数据库改了能回滚吗?缓存怎么清?万一上线挂了,5 分钟能恢复吗?

需求评审 = 开快递站前的"选品会"。你不会上来就开店,得先确定:卖什么(功能范围)、定价多少(技术复杂度)、备多少料(容量预估)、卖不完怎么办(异常处理)。选品会开好了,后面才不会手忙脚乱。

3. 技术方案文档模板

一份好的技术方案文档,能让评审效率翻倍,也方便后期维护。以下是一个完整模板。

技术方案应该包含什么

背景+目标
方案对比
表设计
API设计
影响面
上线计划
回滚方案
// ============ 技术方案文档模板 ============ ## 1. 背景 & 目标 - 为什么要做这个需求?(业务背景) - 要达到什么效果?(可量化的目标) - 相关PRD链接 / 设计稿链接 ## 2. 方案对比(至少 2 个方案) | 维度 | 方案A | 方案B | |------------|---------------|---------------| | 实现复杂度 | 低 | 中 | | 性能影响 | 无 | 需要加缓存 | | 可扩展性 | 一般 | 好 | | 推荐方案 | ✅ 方案A | | ## 3. 表设计 - 新增表:字段、索引、分表策略 - 修改表:ALTER 语句 - 数据迁移方案(如果有的话) ## 4. API 设计 - 新增接口:路径、方法、入参、出参、错误码 - 修改接口:改了什么、是否向下兼容 ## 5. 影响面分析 - 影响的旧接口 / 旧功能 - 是否需要同步修改其他服务 ## 6. 上线计划 - 发布顺序(先 DB 后服务?先 A 服务后 B 服务?) - 是否灰度?灰度策略 ## 7. 回滚方案 - 代码回滚方式 - 数据库回滚方案 - 缓存清理方案

经验之谈:技术方案不需要写得很长,关键是方案对比回滚方案这两个部分。很多人只写"怎么做",不写"做错了怎么办",这才是最致命的。

4. 前后端联调(最常踩坑)

联调是项目里最耗时的环节之一,80% 的延期都跟联调有关。提前做好准备,能省很多时间。

联调前准备 Checklist

接口文档对齐了吗?(Swagger / YApi)

字段名、类型、枚举值一致吗?

异常情况怎么返回?(错误码、错误信息格式)

分页格式统一了吗?(pageNum/pageSize vs offset/limit)

日期格式统一了吗?(yyyy-MM-dd HH:mm:ss

时区问题考虑了吗?(前端 UTC vs 后端 CST)

联调常见问题 + 解决方案

问题 1:前端传的数据后端收不到

原因:Content-Type 不对,或者后端用了 @RequestBody 但前端传的是 form 表单。

排查:

• 看浏览器 Network 面板的 Request Headers → Content-Type

• JSON 数据用 application/json + @RequestBody

• 表单数据用 application/x-www-form-urlencoded + @RequestParam

问题 2:跨域问题

现象:浏览器控制台报 CORS policy 错误。

解决方案:

• 开发环境:前端配置代理(webpack 的 proxy / vite 的 server.proxy

• 生产环境:后端加 CORS 头(Access-Control-Allow-Origin)或 Nginx 配置

问题 3:日期格式不对

现象:前端传 2025-06-10,后端解析报错。

解决方案:

• 方案A:统一用时间戳(long 毫秒数),前后端都没有歧义

• 方案B:统一用 ISO 格式(2025-06-10T16:30:00+08:00),带上时区

• 后端 @JsonFormat 注解指定格式

问题 4:枚举值不一致

现象:后端返回 status=1,前端不知道 1 是什么意思。

解决方案:

• 接口文档里写清楚枚举定义(1=待支付, 2=已支付, 3=已取消)

• 最好前后端共用枚举定义文件(一份 JSON 定义)

• 后端返回枚举名称而非数字("PAID" 而非 2

问题 5:大文件上传失败

现象:上传 50MB 文件报 413 或超时。

解决方案:

• 后端:spring.servlet.multipart.max-file-size 调大

• Nginx:client_max_body_size 调大

• 超大文件:分片上传 + 断点续传

5. Git 工作流

分支策略

main
生产分支,只合并
develop
开发主分支
feature/*
功能分支
hotfix/*
紧急修复,从 main 拉出
release/*
发布分支,测试用

提交规范(Commit Convention)

类型说明示例
feat 新功能 feat: 新增用户注册功能
fix 修复Bug fix: 修复订单金额计算错误
docs 文档变更 docs: 更新API接口文档
refactor 重构(不改变功能) refactor: 抽取支付逻辑为独立服务
test 测试相关 test: 补充订单服务单元测试
chore 构建/工具变更 chore: 升级SpringBoot到3.2
# ============ 日常 Git 命令 ============ # 1. 新建功能分支 git checkout develop git pull origin develop git checkout -b feature/user-register # 2. 开发过程中提交 git add . git commit -m "feat: 新增用户注册接口" # 3. 合并回 develop(推荐用 merge,不要用 rebase) git checkout develop git pull origin develop git merge --no-ff feature/user-register # 4. 紧急修复(从 main 拉分支) git checkout main git checkout -b hotfix/fix-order-amount # 5. 查看某行代码是谁改的 git blame src/main/java/OrderService.java # 6. 撤销最后一次 commit(代码保留) git reset --soft HEAD~1

Code Review 清单

每次提交 PR/MR 时,reviewer 应关注以下几个方面:

功能性 & 正确性

功能是否正确实现了需求

边界条件是否处理(null、空字符串、0、负数)

异常处理是否完善(try-catch、错误码、兜底逻辑)

安全性

SQL 注入风险?(是否用了参数化查询)

XSS 风险?(前端输出是否转义)

权限校验?(接口有没有鉴权)

性能

N+1 查询?(循环里调数据库)

大循环里有耗时操作?(循环里调 RPC/HTTP)

大对象查询?(SELECT * 改为查需要的字段)

可维护性

命名是否清晰?(变量名、方法名能看懂)

关键逻辑有注释?

代码分层合理?(Controller 不写业务逻辑)

6. 前后端协作规范

接口文档先行

先定义好接口再开发,这是最重要的协作原则。后端先出接口文档(Swagger/YApi),前端确认后再并行开发。

后端写接口文档
前端确认接口
前后端并行开发

Mock 数据(前端不阻塞)

后端接口还没开发完?前端用 Mock 数据先开发,不等后端。

// Mock 工具推荐 // 1. JSON Server — 快速搭建 mock API npx json-server db.json --port 3001 // 2. Mock.js — 生成随机数据 Mock.mock({ 'list|10': [{ 'id': '@increment', 'name': '@cname', 'price|100-999': 1 }] }) // 3. Apifox / YApi — 接口管理+Mock一体化

错误码统一

前后端约定统一的错误码规范,避免前端到处写 if(code === 50001) 这种魔法数字。

// 统一响应格式 { "code": 0, // 0=成功,非0=失败 "message": "success", "data": { ... } } // 错误码规范(示例) 0成功 40001参数错误 40101未登录 40301无权限 50001服务内部错误 50002数据库错误 50003第三方服务调用失败

日志规范

日志类型记录内容级别
请求日志 请求路径、入参、响应时间、traceId INFO
错误日志 异常堆栈、入参、用户ID、traceId ERROR
业务日志 关键业务操作(下单、支付、退款) INFO
// 请求日志示例 log.info("[REQ] traceId={} method={} path={} params={} cost={}ms", traceId, method, path, params, cost); // 错误日志示例 log.error("[ERR] traceId={} userId={} action={} error={}", traceId, userId, "createOrder", e.getMessage(), e); // 业务日志示例 log.info("[BIZ] orderId={} action=pay amount={} status=success", orderId, amount);

前后端协作 = 前台和后厨的配合。前台(前端)不需要知道每道菜怎么做,但要知道:菜单上有什么(接口列表)、价格多少(字段定义)、这道菜能不能做(接口是否可用)、卖完了怎么告诉客人(错误码)。后厨(后端)改了菜单要提前通知前台,不能等客人点了才知道换了菜。

7. 测试阶段

自测清单(提测前必须通过)

主流程跑通:核心功能路径走一遍

边界条件测试:空值、超长文本、负数、特殊字符

异常情况:网络超时、服务不可用、并发操作

数据正确性:列表排序、分页、筛选结果

样式兼容性:主流浏览器、移动端适配

性能:列表加载速度、大文件上传

提测流程

自测通过
部署测试环境
提测邮件/消息
QA测试
Bug修复
回归测试

提测邮件要写清楚:测试地址、测试账号、功能列表、涉及接口、注意事项。不要只发一句"提测了"。

Bug 修复优先级

优先级定义修复时间示例
P0 紧急 功能完全不可用 / 数据错误 立即修复 支付失败、登录不了
P1 高 核心功能受影响,但有绕过方式 当天修复 搜索结果不准、图片上传偶尔失败
P2 中 非核心功能问题 本迭代修复 样式偏移、文案错误
P3 低 体验优化 / 建议类 有空就修 按钮颜色不够好看

回归测试注意点:修了一个 Bug,别只测那一个点。想想这个修改会不会影响其他功能。特别是公共组件、工具方法的修改,影响面可能很广。每次发版前跑一遍核心流程回归。

8. 部署上线

上线前 Checklist(照着检查!)

数据库变更脚本准备好了吗?(DDL/DML、是否需要提前执行)

配置文件改了吗?(数据库地址、Redis地址、第三方Key)

旧版本能兼容吗?(接口向下兼容、数据库字段只加不删)

回滚方案确认了吗?(回滚步骤、回滚脚本、回滚时间预估)

监控告警配了吗?(接口成功率、RT、错误率)

日志级别调了吗?(生产环境不要用 DEBUG)

灰度发布流程

1部署到灰度环境
内部验证
2开放 5% 流量
观察 10 分钟
3开放 30% 流量
观察 30 分钟
4全量发布
确认无误后全量
5线上验证
走一遍核心流程
6持续观察
盯盘 30~60 分钟

上线后验证

上线完成后,不要立刻走人。按以下步骤验证:

看监控:接口成功率、RT、错误率是否正常

看日志:有没有新的 ERROR 日志

走流程:自己(或让QA)在线上走一遍核心流程

看报警:有没有触发新的告警

盯盘 30 分钟:确认没有异常再离开

铁律:永远不要在周五下午上线!周五下午上线,出了问题周末加班修,而且周末值班人少,排查效率低。最佳上线时间是周二到周四的上午。

9. 踩坑经验 TOP 10

真实工作场景的踩坑记录,不是八股文,是同事和你真正踩过的坑。

1. "接口改了没通知前端"

场景:后端觉得返回字段 userName 改成 nickname 是个小改动,改完就上线了。联调的时候前端一脸懵:"怎么 name 变成 null 了?"

后果:前端紧急改代码 + 重新测试 + 延期一天上线。

教训:接口任何变更都要通知前端,哪怕只是改了字段名。建个"接口变更通知"群。

2. "数据库加了字段忘了通知"

场景:后端在 order 表加了个 discount_type 字段,忘了告诉其他也在用这个表的后端同事。另一个同事的 INSERT 语句没有这个字段,上线后直接报错。

后果:线上下单失败 10 分钟才发现。

教训:数据库变更要走评审,改完要通知所有相关人。DDL 脚本统一管理。

3. "上线忘改配置"

场景:开发环境数据库地址是 dev-db.internal,上线的时候忘了改成生产地址。应用启动成功,但是读的都是测试数据。

后果:用户看到的是测试环境的数据,吓得产品经理直接打电话过来。

教训:配置文件和环境变量要做检查脚本,上线前自动校验。用配置中心(Apollo/Nacos)。

4. "没有回滚方案"

场景:新功能上线后发现有严重 Bug,但是数据库表结构改了(加字段、改类型),代码能回滚,数据回不去了。

后果:只能紧急写修复代码,线上故障持续了 2 小时。

教训:每次上线前必须写回滚方案。数据库变更要保证向下兼容(只加字段不删字段)。

5. "测试环境OK生产不行"

场景:测试环境验证一切正常,上了生产接口响应慢了 10 倍。一查发现:测试环境数据量 1000 条,生产环境 500 万条。SQL 没加索引,全表扫描。

后果:线上接口超时,大量用户投诉。

教训:涉及数据量的功能,要用生产级数据量测试。SQL 必须过 EXPLAIN 审查。

6. "周五下午上线"

场景:产品催得急,周五下午 5 点发版。结果上线后有内存泄漏,到晚上 8 点还没解决,周六日整个团队都在排查。

后果:团队周末加班,周一还得出故障报告。

教训:上线时间定在周二到周四上午。周五只修紧急 hotfix,不做常规发版。

7. "没有监控"

场景:线上服务挂了 2 小时,没人知道。直到客服反馈"用户打不进电话",后端一查发现服务早就挂了。

后果:故障发现太晚,影响了大量用户。

教训:核心接口必须有监控告警(成功率 < 99%、RT > 3s、错误率 > 1% 立刻报警)。监控系统不是可选项。

8. "SQL没review"

场景:新人写了个 SELECT * FROM order WHERE status = 1,没加索引。大促的时候这条 SQL 扫了 2000 万行,把数据库 CPU 打到 100%。

后果:数据库打挂,所有依赖这个数据库的服务都受影响。

教训:SQL 必须 Code Review,新 SQL 必须 EXPLAIN。上线前用慢查询日志扫描。

9. "前端打包路径写死"

场景:前端 publicPath 配的是 /static/,部署到 CDN 后路径变成 /cdn/assets/。所有 JS/CSS 加载 404,页面白屏。

后果:线上白屏 15 分钟,直到改了配置重新部署。

教训:打包路径用环境变量配置,不要写死。部署前在测试环境验证静态资源加载。

10. "并发没考虑"

场景:秒杀活动,100 件商品,代码写的是"先查库存,大于 0 就扣"。结果同一瞬间 200 个请求都查到库存 > 0,都去扣减,最后卖出了 180 件。

后果:超卖 80 件,运营紧急联系用户退款,还被发了社交媒体吐槽。

教训:库存扣减必须用原子操作(数据库乐观锁 / Redis DECR),不能先读再写。

总结:踩坑不可怕,可怕的是同一个坑踩两次。每次踩坑后写个简短的复盘记录,团队共享,下次就能避开。好的工程师不是不踩坑,而是踩过的坑不会踩第二次。