精英软件工程师如何保持卓越
我有幸与许多卓越的工程师合作过,他们既来自像 FAANG 这样的大型公司,也来自诸如创业公司这样的小型企业。他们让我领略到了传说中的“10 倍效能”工程师 – 他们确实存在!
这些工程师中的一些已经创办了自己的公司,引领了像 Vercel 这样改变我们认知互联网的开发,或者在如今的大型科技公司里领导着价值数十亿美元的项目。
在与他们的合作中,我发现他们在编程时都有一些共通的习惯。
代码是为人编写的而不是单纯服务于计算机
“任何人都可以编写出计算机能解读的代码,但优秀的程序员,他们能编写出人类也易于理解的代码。” – Martin Fowler。
代码是为人编写的而不是单纯服务于计算机。
代码是为你团队里的工程师编写的,他们需要阅读、维护以及在已有代码的基础上进行扩展。
代码也是为用户编写的,无论他们是玩手机的孩子,还是正在调用你的 API 的开发者,甚至可能是你自己。
我认识的最佳工程师们总是以产品思维为先:首先考虑解决人类面临的问题。
这些顶尖工程师总是评估他们代码的价值,确保满足所有目标受众的需求。
如果他们的代码没有满足其中任一受众的需求,那么这些代码就不会被投入生产使用。
抛开对代码的执着
卓越的工程师不会对代码本身过于执着。
他们敢于在开发过程中,即使已经完成了 90%,也愿意为了更好的最终成果而毫不犹豫地删掉并重新开始。
对他们来说,代码并非私人财产,因此他们能够平和地接受各种反馈。
代码无需追求完美。追求完美的代码并不是重点,重要的是能带来变革的代码。
要学会放下对代码的执着,最好的方法就是意识到,在未来 20 年里,你的许多代码可能会变成技术债务、被废弃,或者被重写。
保持一致性标准
编写代码时,遵循一套一致的标准和编码风格至关重要。这种一致性不仅能让代码更易于被你自己以后的版本理解,也让团队成员更容易阅读和掌握。
统一的编码风格指南有助于团队和代码库的扩展和维护。正是因为这种一致性,公司像 Meta 和 Google 才能快速地处理大量代码,同时保持代码库的清晰和可维护性。
我认识的每一位表现出色的开发者都深入理解团队的编码标准,并尽可能地遵守它,明白这样做的好处。
-
Google 采用了一套可读性流程来保持代码整洁。
-
Google 已经开源了他们的部分风格指南。 (链接)
-
Meta 为他们的一些开源项目制定了 C++ 风格指南。 (链接)
-
小贴士:如果你的团队还没有配置代码格式化工具,那么投入时间来设置一个是非常值得的。
编写易懂的代码
我所了解的顶尖工程师编写的代码,虽然编写过程可能复杂,但成品却容易阅读和理解。最贴切的形容是,他们的代码有着一种美学魅力。
他们的代码整洁、条理清晰、逻辑严密。代码中的每一步决策都是合理的,若有哪里不明显,都会在代码内部详细说明。
要编写整洁的代码,一个好方法是遵循一些编程原则,比如 SOLID 原则。虽然这些原则最初是为面向对象编程 (OOP) 设计的,但它们也适用于通用编程:
-
单一职责原则(Single Responsibility): 一个类应仅承担一个职责。
-
开闭原则(Open-Closed): 软件对象(如类、模块等)应对扩展开放,对修改封闭,这使得代码更可预测、易于维护。
-
里氏替换原则(Liskov Substitution): 子类应该能够无缝替换它们的基类,不影响程序的正确运行。
-
接口隔离原则(Interface Segregation): 代码不应依赖于庞大且未全用的接口。相反,应设计出更小、更专门的接口供导入。
-
依赖倒置原则(Dependency Inversion): 高层模块不应依赖低层模块;两者都应依赖于抽象,这样能促进系统设计的灵活性和解耦。
举个例子,良好的命名习惯。好的命名避免使用难以理解的值,区分清晰,函数名称描述准确,变量易于理解。
代码不应出现意外
代码的运行不应该出现意外。要做到这一点,需要遵循编码原则并编写恰当的测试。
好的代码是可以预测的。
测试确保了代码的清晰性和可预测性。它们增强了开发者的信心。有效的自动化测试让团队可以自信地修改代码,而不必担心会意外破坏某些功能。
好的代码可以预见其行为。
测试的类型包括:
- 单元测试:针对各个组件和独立功能。
- 集成测试:测试多个组件之间的互动。
- 端到端测试:从用户视角评估整个系统的功能。
测试应当简单明了。当测试失败时,应该能轻松找出问题所在。
同样重要的是要知道哪些事情不需要测试。
比如,如果端到端测试的工作量超过了程序本身的实际价值,那么这种测试就可以用周到的文档、监控和向相关人员(如代码所有者)发出警报来替代。
测试还不应涉及代码内部的实现细节,比如在前端代码中测试特定的 CSS 选择器,而应使用数据属性或仅进行截图测试。
经常沟通
没有任何伟大的系统是独立完成的。杰出的工程师们会经过设计审核,积极寻求反馈,并在他们最初的代码设计上不断进行改进。
每个人的知识都有所欠缺,而这些缺口可以通过他人的知识来补充。全新的视角常常能够让代码变得更加清晰,或者提出一些以前未曾想到的新思路。
最优秀的工程师既善于沟通又乐于合作 – 他们不怕投入时间共同协作,以期达到更优的成果。
这种合作可以是简单地邀请团队成员快速审阅一份文档,或者在一个重要的代码提交中增加更多的代码审查人。
速度与质量:编程的双重境界
我所见过的顶尖工程师能迅速完成项目,关键在于他们的编程步骤循序渐进。
这听起来可能有些反直觉。
所有这些原则和习惯虽然会增加编程的初步阶段的时间,但却能够确保项目稳步向前。
他们通过坚持标准、精准测试、遵循原则和频繁交流,最终在整个项目周期内节约了大量时间。
相比之下,我个人在实习和作为初级工程师时也有过急于求成的经历,就像很多人一样,往往是急忙前进三步,遇到障碍,最后不得不退回五步。
不要盲目遵循规则
上面提到的“规则”和“原则”仅仅是一些指导性建议。
事实上,并不是每件事都能够完美地适应这些指导性建议。
有时候,你编写的代码就像是一个方块,硬要塞进圆形框架显然不合适。这种情况是可以理解和接受的。
有些时候,需要打破常规,超越界限。
在这种情况下,记得记录下你的代码为什么要这样写。
如果你不记录下来,将来可能有人(比如未来的你自己)看到这段代码时会疑惑:“我当初怎么这么笨,为什么没按照我们的标准来做?”
然后他们可能会花费 20 个小时重新编码,试图让代码符合标准,但最终还是回到了原点。听起来很眼熟吧?
软件开发的现实是,并不是所有代码都能做到整洁或完全遵循规则。
但代码可以做到一致、清晰、易懂、可测试并且有价值。
关于这些工程师,我还注意到了一些其他特质,我将来会详细介绍:
-
至少在一个领域拥有深厚的专业知识。 我记录的每一位工程师都在他们各自的领域中出类拔萃,因为他们专注并成为了前端基础设施、分布式系统或清晰用户界面等特定领域的专家。[试试我的应用 SWE Quiz,测试你的软件知识盲点,成为领域专家。(http://swequiz.com/)
-
他们经常并恰当地进行个人品牌推广。 这些工程师并不是无名之辈。他们所在团队的每一个成员,以及所有曾与他们合作过的人,都清楚地认识到他们的价值和专长。这是通过恰当的个人品牌推广和参与高影响力项目的组合实现的。