3018 字
约 10 分钟
20
S27-X19 · 项目讲述:把做过的系统说清楚

面试的项目环节不是复述简历。简历上那一行"负责订单系统重构"已经写完了,面试官要的是把它拆开:你到底碰过哪一层、遇到什么在拦你、为什么选了这个方案、结果怎么验证的。

讲不清通常不是表达能力问题,而是自己没想清楚约束是什么。约束缺失,任何决策都无法被评价,听起来就像"我们用了 Kafka,因为 Kafka 好"。


1. 面试官在判断的四个信号

信号 他在听什么 听不到就会怀疑
真实性 具体到模块名、字段、报错、时间点 全程只有"我们团队""大概""后来优化了"
定位能力 你能否指出问题出在哪一层 只描述现象,说不出根因链路
取舍意识 为什么这么选,放弃了什么 只有一个方案,且"没有缺点"
边界认知 这套方案在什么条件下会失效 把方案说成普适的、无代价的

2. 四段结构

① 背景与约束(30 秒)
   - 业务在做什么、规模量级、团队与时间约束、技术栈限制
② 你的职责(20 秒)
   - 我负责哪几个模块,哪些是我决策的,哪些是别人决策我执行的
③ 关键决策与理由(90 秒,主体)
   - 问题 → 可选方案(至少两个)→ 判断依据 → 选了什么 → 代价是什么
④ 结果与验证(30 秒)
   - 用什么度量、怎么观测、上线后看到什么、还有什么没解决

四段的顺序不能换。先讲结果("QPS 提升了")会让后面的技术细节失去参照系——听的人不知道这个数字相对于什么基线。

时长控制按岗位级别调整:初/中级讲 2 分钟到一个决策点;高级讲 4–6 分钟、两到三个决策点。主动留出追问接口比讲完更重要:在决策处说一句"这里当时还有个备选是 X,但代价是 Y,所以没选",面试官自然会追这里。

两分钟版(先给骨架,不展开):
  "我负责订单创建链路:原来一次下单要串行发 3 个 RPC,
   我把它合并成一次批量查询,并加了幂等键防重复。
   约束是 3 人团队、不能停机、库存必须强一致。"

被追问后按层展开:
  机制(怎么合批)→ 参数(超时、批大小)→ 边界(下游部分失败怎么办)

3. "约束"为什么必须最先说

同一个决策在不同约束下评价完全相反:

约束条件 合理选择 不合理的对照
团队 3 人、半年上线 单体 + 模块化,先不拆 上微服务,运维成本压垮进度
日订单 10 万、读多写少 主从 + 缓存 直接上分库分表,复杂度白付
强一致的资金流水 单库事务、串行化关键段 最终一致 + 补偿,对账压力转移给业务
已有 Hadoop 生态、离线为主 复用现有集群 另起一套实时链路,双份成本

讲述时把约束说成事实而不是借口:"当时只有 3 个人、要给双十一前上线,所以没拆服务"——这是约束;"我们觉得微服务太复杂了"——这是偏好。

4. 量化结果:不编数字,说清度量和量级

面试里最容易失分的一句话是"性能提升了 300%"。没有基线、没有度量方式、没有观测窗口,这句话等于零信息,还会引出"你怎么测的"这种必杀追问。

不合格:优化后接口快了很多,QPS 提升 3 倍。
合格(口径示例,数字为示意):这个接口原来 P99 在 800ms 量级(网关侧统计,采样 1 分钟粒度),
        主要耗时在 3 次串行 RPC;改成批量查询后,RPC 次数降到 1 次,
        P99 落到 200ms 量级。这个数字是上线后一周的监控读数,
        高峰期会有波动,具体取决于下游缓存命中率。

三个要点:

  1. 单位与口径:P99 还是均值、网关侧还是应用侧、是否含重试。
  2. 量级而非精确值:"百毫秒量级""下降约一半",比"提升了 287%"更可信。
  3. 归因边界:改动只影响哪一段,其他因素(流量变化、下游升级)是否同时发生。

如果确实没有度量数据,就直说:"这块没有留下可对比的基线,我只知道变更前后的监控曲线形状变了,具体数字不能确认。" ——承认这一点,可信度反而上升。

5. 技术深度怎么展开:从机制讲到边界

被追问"这个方案具体怎么实现的",正确的展开顺序是三层,而不是把结论换个说法重复:

机制层:它内部怎么工作(数据结构、协议、状态机)
  ↓
参数层:关键参数是什么、为什么取这个值、调错了会怎样
  ↓
边界层:什么条件下它会失效、失效时表现是什么、你怎么发现的

举个对照:

追问 差的回答(停在结论) 好的回答(进到边界)
为什么用 Redis 做分布式锁 "Redis 性能好" "SETNX + 过期时间,单实例下够用;主从切换时锁可能丢,所以对强一致场景我改用数据库行锁或 Redisson 的看门狗 + fencing token"
消息为什么不会丢 "Kafka 很可靠" "生产端 acks=all,消费端手动提交 offset,业务幂等靠唯一键;重复消费是允许的,丢失不允许"
缓存怎么保持一致 "用消息队列通知" "先更新库再删缓存,删除失败进重试队列;接受毫秒级不一致,靠 TTL 兜底"

深度不是背更多名词,而是知道这东西在哪里会坏。

6. 常见追问的拆解

追问 真实意图 应答骨架
为什么不用 X? 你有没有比较过 说出 X 的两个具体代价(运维/一致性/学习成本),再说你的场景为什么不能接受
流量涨十倍会怎样? 你知道瓶颈在哪吗 先指瓶颈组件(DB 连接数、单机带宽、锁竞争),再给两级应对(垂直/水平),最后说哪一级先撞墙
出过什么故障? 你是否真在一线 时间点、现象、定位路径、根因、修复、后续预防,六项齐全
怎么发现问题的? 观测能力 告警指标 + 日志/链路定位路径,别只说"用户反馈"
这块是你做的吗? 边界 明确说"设计是我,编码是 A,联调是 B",不模糊

"出过什么故障"这一问几乎必答,且最能区分真假。准备两个案例:一个是自己的代码 bug,一个是架构层面的问题,各讲一条完整链路。

故障讲述六件套(缺一项就会被追着补,以下为骨架示例):
  时间   故障发生的时刻与持续时长(按监控曲线还原,给量级)
  现象   下单接口 5xx 上升,支付回调堆积
  定位   先看网关错误率 → 应用日志发现连接池耗尽 → 定位到慢查询
  根因   新增的列表查询漏了索引,单次扫表把连接吃满
  修复   临时扩池 + 回滚该查询,2 小时后补索引上线
  预防   慢查询告警阈值下调;上线检查单加"新增查询必须 EXPLAIN"

7. 不会的问题:承认边界 + 给推理路径

硬编的代价是后面每一问都会塌。正确做法是三步:

1. 明确边界:"这块我没做过,我只从文档和别人的分享里了解过。"
2. 给推理:"但如果让我做,我会先确认 A(约束),再看 B(可选项),
   倾向选 C,因为在这个场景下 D 的代价更大。"
3. 把决定权交回:"你们实际是怎么处理的?我想知道我的推理哪里偏了。"

这个动作展示的是可迁移的思考,而记忆型问题本来就不是项目环节的重点。

8. 反面示例与改法对照

反面 问题 改法
"我们团队把系统重构成微服务" 主语是团队,个人贡献为零 "我负责把订单与库存的边界拆开,定义了 6 个接口"
"用了 Spring Cloud 全家桶" 只有技术栈,没有决策 "选它是因为团队已熟悉,代价是注册中心成为单点,我们加了本地缓存降级"
"性能提升明显" 无度量 给口径 + 量级 + 观测窗口
"没有遇到什么问题" 不可信 讲一个真实的小坑,比讲十个优点有效
讲了 8 分钟还没到结果 没有层次 先给 30 秒版本,再按追问展开

9. 排错:讲完之后常见的四种反弹

现象 根因 处理
面试官反复问同一个点 你的回答停在结论层 换机制层重讲,主动给参数与失败场景
追问越来越细直到你答不上 开场把范围铺太大 主动收窄:"我只讲订单创建的链路,其他模块我没深入"
对方明显失去兴趣 缺约束与取舍,听起来像背书 立刻插入"当时还有个备选是…"
被质疑"这不是你做的吧" 细节密度不够 补具体报错、字段名、上线时间、评审结论

10. 边界:什么内容不该放进项目讲述

不该讲 原因
公司机密、真实用户数据 换个量级描述即可,不必给真实数字
只属于团队流程的事(排期、评审会) 与个人技术判断无关
无法验证的效果("用户体验提升") 无法度量,等于没讲
纯工具使用("我会用 Jenkins") 放到技能环节,别占项目时间

一句话收口:先给约束,再给职责,决策讲清代价,结果给出口径;深度体现在"它什么时候会坏"。


11. 自测

  1. 为什么"约束"必须先于"决策"讲?举一个约束改变结论的例子。
  2. 说"P99 从 800ms 降到 200ms"时,必须额外交代哪三件事?
  3. 被追问"为什么不用 X",回答里必须包含哪两类信息?
  4. "出过什么故障"这一问,完整链路包含哪六个要素?
  5. 遇到完全没做过的技术问题,三步应答是什么?
  6. 你的项目讲述里,哪一句是"可被追问的接口"?现在能展开到边界层吗?
S27-X19 · 项目讲述:把做过的系统说清楚
https://www.clxhxhhr.top/posts/5923/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。