写过代码、当过架构师、也做过CEO:一位程序员的IT职业「血泪史」
【CSDN 编者按】这是一位开发者从软件工程师到架构师、创业 CEO、再到售前岗位的职业回顾。他没有空谈概念,而是结合真实经历,分享了在 CI/CD、测试体系、GitOps、架构演进、文档管理、团队协作等方面踩过的坑与反思。对于正在一线开发、架构设计或带团队的工程师来说,这些故事或许能让你少走弯路,也能帮你更快建立起属于自己的“工程方法论”。
在我的职业生涯中,我先后做过软件工程师、软件架构师、创业公司的创始人兼 CEO,也干过售前岗位。一路走来,踩过不少坑,也积累了一些经验。
坦白说,这些教训并不是什么“新发现”,很多都能在书里找到。但对我而言,真正的价值在于——它们不是抽象概念,而是我亲身经历过、付出过代价之后总结出来的。
CI/CD 不只是“更快”
在一家初创公司时,我们一直在讨论要不要给代码仓库加一条 CI/CD 流水线。大家都知道这算是最佳实践,能省时间,也能真正实现持续集成和持续交付。否则,每次提交代码都要手动跑测试、构建、Lint、部署,简直不可想象。
但是,大家也觉得“搭流水线会花点时间”,于是总是拖延。直到有一天,我们在深夜手动部署时,负责的小伙伴把一个配置参数填错了,结果导致用户的个人资料功能挂了好几个小时,直到我们紧急打补丁才恢复。
这次经历让我明白:CI/CD 不仅是为了节省时间,更是为了减少人为错误。当然,这个道理在书本上早就写过,但当你亲身经历一次事故,感受就完全不同了。
测试是为了“可演进性”
还是在那家初创公司,由于赶时间上线,我们一开始几乎没有写测试。大家都心知肚明这会是“技术债”,但当时觉得顶多就是线上偶尔冒几个 bug,修一修也就算了。
直到后来我们才发现,测试的价值远不止“抓 bug”。它真正的作用在于:让系统可以演进下去。
想象一下,当你需要修改一年前写的某段代码时,你根本无法保证不破坏什么。即使有文档,你也不可能完全掌握当时的上下文和所有依赖。于是,大家都变得“不敢碰旧代码”。
最后的教训就是:只有完整的测试体系,才能让人有信心重构和演进系统。这也是为什么像 Martin Fowler、Michael Feathers 这些作者会把“没有测试的代码”直接定义为“遗留代码”。
后来我做咨询工作时,又在架构层面再次遇到了同样的问题。如果没有验证架构设计的测试(比如 fitness function),架构就很难随着业务演进。为了解决这个问题,社区有一些工具,比如 Java 的 ArchUnit,而我甚至还写了一个 TypeScript 版本的:ArchUnitTS。
Push-based GitOps ≠ 真正的 GitOps
简单回顾一下 GitOps:它强调把 Git 作为唯一事实来源,不仅管代码,还管基础设施、配置和部署流程。
GitOps 有两种方式:
- Push-based:代码合并后,由流水线把改动推送到集群;
- Pull-based GitOps:集群自己从 Git 拉取最新配置并同步。
很多人认为 Push-based GitOps 并不算真正的 GitOps,我以前没太当回事,直到踩了坑。
我们的微服务架构跑在 AWS EKS 上,基础设施用 Terraform 管理。正常情况下,分支合并到主干后,CI/CD 会自动合并改动。但某次 DevOps 工程师休假,线上出现性能问题,于是后端开发临时用 kubectl edit 手动调高了内存限制,问题解决了。
一周后,DevOps 回来部署安全补丁,更新了 Helm 模板,合并进主干,流水线自动跑。结果几分钟后,之前有内存泄漏的服务又崩了,因为配置被还原成了 Git 仓库里的旧值——我们一开始完全搞不懂为什么“一个安全补丁”会导致线上挂掉。
这次事故让我认识到:Push-based GitOps 隐含着巨大的风险,因为任何“手动修改”最终都会被覆盖。后来我们切换到了 Pull-based GitOps,用 ArgoCD 来实现,这样不仅避免了配置被覆盖的问题,还提升了安全性(仓库本身不再拥有对集群的过多权限)。
其他一些教训
有些没那么长的故事,但也同样值得记录:
- 文档要写明 “为什么”
干净的代码(Clean Code)也好,自解释代码也好,很多人都推崇“少写注释”。但再干净的代码,也解释不了“为什么要这么做”。比如为什么选这个算法、这个架构,而不是另一个?我们在初创公司时,文档不少,但很少写“原因”。结果就是——人都走了,或者时间久了,没人记得当初的决策逻辑。后来我们才意识到,像 Architecture Decision Record(ADR)这样的形式,其实非常重要。
- 《人月神话》是真的
项目越复杂,新人上手越难,沟通成本越高。加人并不一定加速,反而可能变慢——这个道理,直到自己带团队才切身体会。
今天犯错比明天犯错好
决策越早做,代价越小。哪怕错了,尽快获得反馈、快速修正,总比拖到后面让整个系统受牵连要好。
- 关注业务价值,而不是炫技
技术不是堆栈越新越潮越好,最终要看业务产出。比如,很多公司盲目追逐微服务,结果搞得比单体更复杂。如果一个单体能跑得好,那它就是更优解。
- 产品驱动增长,而不是短期收益
我创业时最大的感悟之一就是:不要为了“快赢”而牺牲长期价值。好的产品和服务,才能带来更长远的增长。
- 怎么带团队?敏捷 + 文化
对我来说,带团队最有效的方法就是:敏捷(拥抱变化而不是死守计划),再配合“主人翁文化”和“反馈文化”,同时把技术愿景清晰传达出去,这样团队的战斗力才能发挥到极致。
原文链接:https://lukasniessen.medium.com/lessons-learned-in-my-10-years-it-carreer-swe-software-architect-startup-ceo-presales-97b5c6bd25ae
本文来自微信公众号“CSDN”,作者:Lukas Niessen;翻译:郑丽媛,36氪经授权发布。