加入现在的团队已经三年了。回顾这段时间,有一些事情让我觉得当时应该做得更好。

测试基础设施(Test Infra) Link to heading

在项目早期,我们的测试基础设施并不完美,但有一个优势:它与大团队的系统是解耦的。大团队的测试既不稳定又耗费资源,通常需要 10 多个小时才能跑完;而我们的测试套件不到 3 小时就能完成。这大大加快了我们的开发速度。

然而,随着业务复杂度不断提升,弊端逐渐显现。我们需要花越来越多的时间去维护自建的测试基础设施,并在其上编写新的测试。模拟依赖服务和数据也变得愈发困难。与此同时,大团队的测试基础设施不断成熟,并且有专门的团队负责维护和改进。

这带来了两个问题:

  • 高维护成本:我们往往花在维护基础设施上的时间比开发新功能还多。
  • 信号误导:由于我们的测试环境没有与整个系统真正集成,有时测试通过了,就让领导和 PM 误以为功能已经“完成”。但一旦进入 staging 环境,伪造依赖的低保真度就会暴露问题,严重干扰了发布流程。

回过头来看,更好的做法是仅将自建的测试环境用作开发加速器,而不是验证信号。功能只有在高保真环境(例如 staging)中通过测试,才能算真正“验证完成”。另外,测试覆盖不足带来的风险也应该明确告知,让 PM 和领导意识到测试资源的缺口,并相应调整优先级。

技术债务(Tech Debt) Link to heading

在紧迫的截止日期下,人们常常会倾向于把长期的修复推迟到后续版本,用临时的 workaround 或 mitigation 来应对当前版本。然而,这往往会带来隐藏的成本。

当客户在当前版本中遇到问题时,我们需要花更多时间去指导他们如何使用这些临时方案。并且在升级过程中,这些临时方案会让迁移变得更加复杂,需要额外精力去清理和移除。最终,这些“捷径”往往比一开始就解决问题耗费更多时间和精力。

与上下游团队的定期同步 Link to heading

在职业生涯早期,我没有投入足够的精力去与上下游团队定期同步。这导致了几个问题:

  1. API 设计不匹配:不了解下游团队的业务背景,导致我设计的一些 API 缺乏灵活性。当有新需求时,现有 API 要么无法满足,要么在补丁后变得混乱。同样,由于对上游团队缺乏了解,我也很难影响他们的 API 设计或及时提供反馈,结果我们不得不在本地实现一些 hack 和 workaround。

  2. 无效的开发投入:有时我们认为某个功能至关重要,但下游团队却已将其降级或延后。由于我们没有及时获得这些信息,投入了大量精力去开发,最后却完全没被使用。

  3. 集成测试延迟:缺乏早期同步,错失了与上下游进行集成测试的机会。结果是问题直到发布前才暴露,被迫在最后时刻修改,增加了交付风险。

文档与 Runbook Link to heading

在早期,我常常抗拒写文档或 runbook,认为这是低优先级的事情。但后来我发现,缺乏清晰文档实际上会浪费更多时间。没有文档,队友或运维人员会反复来问同样的问题,而我也要一遍遍解释。

好的文档和 runbook 不仅能节省时间,还能让团队更独立、更高效地运转。

与大团队的对齐 Link to heading

另一个挑战是,我们团队在很长一段时间里都比较独立运作。结果,大团队往往不了解我们的优先事项和面临的困难;而我们也没有足够关注大团队的横向建设,更没有充分使用他们的共享服务。

这种割裂带来了低效:我们不得不自己维护许多系统,而没有充分利用公共的解决方案。例如测试基础设施就是一个典型案例。回头来看,如果能够更紧密地与大团队方向保持一致,积极参与他们的建设,就能减少重复劳动、提升集成度,并让我们的挑战在组织层面获得更多关注。

版本偏差 / 向后兼容性 Link to heading

我们遇到过一些由版本偏差引发的bug。错误地假设在升级后,所有组件都会立即运行在同一个版本上。实际上,可能会出现一种情况:某个组件仍然运行在旧版本上,而另一个组件却假设它已经升级完毕,从而导致交互不一致和异常响应。

为了避免这种问题,我们在测试中需要明确覆盖混合版本场景,以确保在逐步升级过程中仍能保持向后兼容性。