按能力维度分类(GitHub 开源题库) · Tech-Specific

分享一次你倡导重构的经历。

Tell me about a time you advocated for refactoring.

答案语言

考察要点

这道题旨在评估你对技术债务的洞察力、你的主人翁精神(Ownership)以及你影响他人(尤其是非技术同事)的能力。对于 Amazon 而言,这直接映射到以下领导力准则(Leadership Principles):

  1. Insist on the Highest Standards: 你不满足于现状,主动寻求提高系统质量和长期可维护性。
  2. Ownership: 你将系统的长期健康视作自己的责任,而不仅仅是完成分配给你的任务。
  3. Think Big: 你不只看眼前的小修复,而是思考如何从根本上解决问题,为未来的业务发展铺路。

高分示范答案(STAR)

Situation(背景) 去年,在我之前的电商公司,我作为一名资深工程师,在我们 5 人组成的订单履约团队。我们的核心系统是一个有 5 年历史的 PHP 单体应用,负责处理从下单到发货的全流程。这个系统代码耦合严重,数据库设计陈旧,任何小改动都牵一发而动全身。

Task(任务) 当时,产品和业务团队计划在一个季度内上线一个名为“灵活打包”的新功能,允许仓库员工将多个子订单合并发货以节省运费。但经过我们初步评估,因为旧系统的复杂性,这个功能至少需要两个季度才能开发和充分测试。我的任务是找到一个方法,既能满足业务的紧急需求,又能从根本上解决这个技术瓶颈,而不是再次在技术债上叠加补丁。

Action(行动) 我的行动分为三步,核心是用数据说话,并提供一个务实的替代方案

  1. 我首先量化了技术债的“成本”:我没有空谈“代码质量差”,而是花了两天时间分析了过去半年的数据。我发现:1)与订单模块相关的线上 Bug 占了所有 Bug 的 40%;2)每次需求开发,有 50% 的时间都花在兼容旧逻辑和回归测试上;3)我做了一个性能压测,模拟了“灵活打包”功能的数据库查询,发现它会导致核心订单表被锁住超过 500ms,这将直接影响下单成功率。

  2. 我设计并提出了一个“两步走”的重构方案:我没有提议一个令人生畏的、为期半年的“完全重写”。相反,我设计了一个微服务化的重构方案。第一步,用一个月时间,将最核心、最独立的“库存扣减”和“包裹创建”两个功能剥离出来,作为两个新的 Go 微服务。旧的 PHP 应用通过 API 与它们交互。第二步,再花一个月时间,在新服务之上开发“灵活打包”功能。这个方案将总时间控制在两个月内,比原计划快,且风险可控。

  3. 我主动向上和同级沟通,争取支持:我准备了一份简短的文档,用我收集到的数据(Bug率、开发耗时、性能瓶颈)向我的经理和产品经理(PM)说明了重构的必要性。我对 PM 解释说:“如果我们现在投资一个月重构,不仅这次能更快交付,未来所有与包裹相关的需求,开发速度都能提升至少一倍。” 同时,我为新服务写好了清晰的接口定义(API Contract),让团队其他成员可以提前开始联调准备,减少了大家对不确定性的担忧。

Result(结果) 我的方案被采纳了。我们团队在一个月内成功将两个核心功能微服务化。

  • 新服务的 P99 延迟稳定在 50ms 以下,相比之前旧接口的 300ms+ 有了显著提升。
  • “灵活打包”功能最终只用了 3 周就开发完成并上线,整个项目比原计划提前了一个月。
  • 在接下来的半年里,订单履约团队的线上 Bug 率下降了 30%,并且我们成功支撑了两次大促,没有出现一次由该模块引发的性能问题。我学到了,成功的技术重构倡议,关键在于将技术问题转化为业务团队能理解的成本和收益。

低分陷阱(常见扣分点)

  • 只谈技术,不谈业务:“我发现代码写得不符合设计模式,耦合度太高,所以我决定重构它。”——这完全没有体现出商业价值,面试官会认为你是一个只活在技术世界里的“代码洁癖”,而不是一个解决业务问题的工程师。
  • 用“我们”模糊个人贡献:“我们觉得系统太旧了,所以我们决定用新技术重写。我们设计了新架构,然后我们分工写代码。”——面试官无法判断“你”在这个过程中到底扮演了什么角色。是你提出的想法吗?是你做的决策吗?还是你只是一个执行者?
  • 缺乏说服过程,像开了“上帝视角”:“老板和 PM 都同意了我的方案。”——这太顺利了,不真实。一个好的故事必须包含你是如何面对阻力、如何通过沟通和数据去说服他人的。这才是“advocate”的精髓。
  • 结果含糊不清:“重构后系统变快了,也更稳定了。”——多快?多稳定?没有量化就等于没有发生。必须用数字来证明你的工作成果。

高概率追问(3 个 + 示范回答要点)

  1. 追问:你遇到的最大阻力是什么?你是如何克服的?

    • 要点 1 (来自 PM 的阻力):PM 最初非常反对,因为他觉得这是纯技术工作,会延误业务功能的上线。我的应对策略是:不谈代码,只谈业务指标。我向他展示了性能压测数据,告诉他如果不重构,新功能上线后大促期间的下单成功率可能会下降 5%,这直接关系到他的 KPI。
    • 要点 2 (来自团队内部的阻力):一些习惯了 PHP 的同事对引入 Go 语言有顾虑,担心学习成本和维护问题。我的应对策略是:主动承担,降低门槛。我组织了两次 Go 语言和微服务基础的分享会,并且主动编写了详细的开发上手文档和项目模板,把最难的“从 0 到 1”的工作自己做了。
  2. 追问:如果时间倒流,你会对这个重构方案做哪些不同的处理?

    • 要点 1 (更早地暴露问题):我会更早、更持续地追踪和暴露技术债的成本,而不是等到一个紧急需求来了才去做分析。比如建立一个常规的“技术健康”看板,让 PM 和管理者能随时看到问题。
    • 要点 2 (更小范围的验证):在提出完整的重构方案前,我可能会先花一周时间,将一个更小的功能点(比如“查询包裹状态”)剥离出来作为 PoC(概念验证),用实际的线上效果来让团队和 PM 建立信心,这样后续的沟通阻力会更小。
  3. 追问:你提到 Bug 率下降了 30%,你是如何衡量和归因的?

    • 要点 1 (数据来源):我们使用 JIRA 来管理 Bug。每个 Bug 都会被标记(Tag)到对应的模块。我统计了重构前三个月和重构后三个月,所有被标记为“订单履约”模块的 P0 和 P1 级别 Bug 的数量。
    • 要点 2 (排除干扰项):为了确保这个结果不是因为其他因素(比如那个季度需求少),我同时对比了“用户中心”模块的 Bug 数量,发现它的 Bug 数基本持平。这通过旁证说明了“订单履约”模块 Bug 率的下降,很大概率是重构带来的直接收益。

故事复用建议

这个故事非常扎实,除了回答“倡导重构”外,还可以稍作调整,用于回答以下问题:

  • Tell me about a time you took ownership. (你主动发现了问题并负责到底)
  • Tell me about a time you insisted on the highest standards. (你没有接受“能跑就行”的方案)
  • Describe a time you had to influence others without authority. (你说服了 PM 和同事)
  • Tell me about a time you used data to make a decision. (你用数据量化了技术债的成本)
  • Give me an example of a complex technical project you led. (你设计并主导了微服务化)
  • Tell me about a time you had to make a trade-off between short-term and long-term goals. (你在业务功能和技术健康之间做了权衡和规划)