【翻译】成功的程序员有哪些共性?

Dave Culter

Dave Culter,今年 74 岁,仍然每天去微软上班写代码。

我第一次听说 Cutler 是在他由于自己 50 年(!)的工作经历而成为计算机历史博物馆 Fellow 的时候。作为一名将一生都贡献给了工程的程序员,他被公认为是“硬核”程序员。

更令人敬佩的是,他的工作影响到了 20 亿用户的体验。他的诸多贡献之一是编写了 Windows NT 的关键部分,而 Windows NT 则是最近 20 年以来所有 Windows 版本的根本。它使得操作系统可以逆向兼容旧版本的软件,从而在早期给微软带来了巨大的市场优势。由此 Culter 被称为是“微软 Windows 操作系统背后的关键技术头脑”。

像 Culter 这样的程序员为何能够成功?我们又能做些什么,来匹及他们即使一小部分的成就呢?这些能够用软件为人们的生活带来巨大改变的程序员与其他普通程序员的差距究竟在哪里呢?

我在写《The Effective Engineer》这本书时,对于这个问题做了详细的研究。编程固然不是工程师唯一的工作,但也是主要任务之一。我采访了许多来自顶级硅谷公司的工程师领袖人物,最终发现高效的程序员们基本都有以下五个共性:

1. 勇于钻研你不理解的代码

搞懂不熟悉的代码是一件艰难甚至令人恐惧的事情,很多人都不敢尝试就放弃了。但这对程序员来说是关键性的技能。想要提高这方面的能力,唯有多练。在这个过程中你会逐渐成长为更优秀的程序员。当开源的第三方库或是来自其他团队的代码表现不服预期时,你要好好把握这样的学习机会,深入研究源码,寻找原因。

对陌生事物的恐惧是不局限于代码的。比如在每次换工作的时候,你可能都会隐隐地担心自己能不能达到上一份工作中那样的优秀表现。严重的甚至会发展成 Imposter Syndrome(出现在成功人士身上的一种现象。这类人无法将自己的成功归因于自己的能力,并总是担心有朝一日会被他人识破自己其实是骗子这件事。)。虽然很少有人公开谈论这个,但曾经有好几位 CTO 都告诉我他们觉得自己像是骗子。

现实是,每个人起点不一样。Cutler 当年读的是文学院,没有接受正式的计算机科学教育。所以跟其他同伴相比,他在起跑线上就落后一大截,只能不断尝试和摸索来追赶别人。

为了能够做得更好,我们要采取进取的心态,并最优化自己的学习策略。只要你愿意花时间,任何技能,像是写代码、沟通、社交、做讲座等等,都是能够学习和提高的。去相关的书,找前人询问。长此以往,挑战不熟悉的内容会变得越来越容易。

2. 熟练掌握调试技巧

作为软件工程师,我们每天都会问自己:“为什么我的代码表现不符预期?”调试代码的能力在很大程度上决定了一个程序员的效率,但这一点却经常在大学教育和技术面试中被忽略或者低估。

如何高效调试?从根本来说,要采取科学的方法:

  • 猜测问题所在
  • 假设猜想正确,找出应该会得到的结果
  • 试图找到跟预想的结果矛盾的证据
  • 如果找到了矛盾,那么猜想不成立,换一个;如果找不到,这个猜想就很有可能是真正的原因。

基于此之上,要进一步提高调试效率,你要学习如何更准确地猜测问题所在,并且熟练掌握哪些能让你更好地观察代码行为的工具和技巧。

要更准确地猜测问题所在,唯有多练;而更好地观察代码行为,需要你提高自己的技术水平。假定所有行为都能被观察到,那么你就要找到合适的工具或是机制使得你能够更快地找到预想的证据。不要把自己的思维局限于只寻找那些你已经熟悉的工具所能提供的观察点。很多时候早就有人开发过能够找到你想要的东西的工具了。

3. 投资在节省时间的工具上

早期的计算机,资源有限而且昂贵,所以那时的程序员在写代码时都精打细算。而现在,用 AWS 做一个小时的云计算花不了一美分。

但有一类资源是这几十年来都没有变的:时间。我们的一周还会是只有 7 天,一天还是只有 24 个小时。也就是说任何需要人工来做的事情,依然是非常容易成为瓶颈的。为了缓解这个问题,我们需要去掌握一些节省时间的工作,同时自动化工作流程。工具能让我们在相同的时间内创造更多的价值,而自动化则能让一些机械性的重复问题在我们睡觉的时候被解决,从而让我们把有更多的时间花在其他问题上。

Bobby Johnson,前 Facebook 工程主管,曾经将 6 个人的基础架构团队带到超过 100 个人为止。他在面试中说过一句话让我印象很深。他说,几乎每一个成功的程序员,都写过很多工具。

可能很多工程师都知道投资工具一定会有回报,但如果我们实际地把花在各类事情上的时间统计一下就会发现,用于开发工具的时间好像并不多。而 Johnson 团队中最好的程序员几乎把三分之一的时间都花在了工具上:代码部署工具、系统监控工具、以及任何能够让他们用更少的时间做到更多的事情的工具。

如果一件事,机器能为你代劳,就不要再自己去做了。

4. 优化迭代速度

假设从一个函数调用找到它的原型需要花费 12 秒,而你每天要做 60 次类似的查找。也就是说你每天要花 12 分钟的时间在查找函数上。如果你能够通过熟练掌握编辑器的键盘快捷键,把 12 秒缩短到 2 秒,那么你每天就能省下 10 分钟。一年就能省下 40 个小时,这就是整整一周的工作时间。

如果再找到 3 处类似的优化,一年就能省下一个月。想想你能用这一个月多做多少事情吧!

又比如说你在调试,你发现每次需要启动应用,先后点击五次鼠标,从而达成对应的条件来触发一个 bug。那么你能不能花 10 分钟写一段模拟代码使得每次重新启动应用都能直接触发 bug 呢?只要 10 分钟,将来的调试都能节省大量的时间,这笔投资不划算吗?

总是系统性地问自己:“我要如何才能更快地迭代?”你将会收获许多,并且随着时间的推移,回报就像利滚利一样变得越来越丰厚。

5. 培养系统层面的思维方式

当你按照技术文档写完了对应的代码,你可能就会觉得自己的工作完成了。但这真的只是冰山一角。躺在仓库里面而不是在生产环境中的代码没有任何价值。

要开发和部署实际有用的代码,你需要将自己的思维提高一个层次,思考自己的代码对整个系统来说有什么影响:

  • 你的代码能跟其他人写的功能很好地共同工作么?
  • 你是否对代码做了充分的测试?如果有 QA 团队,他们能正常地使用你实现的功能么?
  • 要将你的代码部署到生成环境中,需要做哪些改动?
  • 你的代码会对系统中的其他部分造成负面的性能影响吗?
  • 你是否已经考虑到了跟你的代码进行交互的用户会表现出的所有行为?
  • 你的代码是否能够取得预想的商业影响?

这些问题的确很难,都不是轻易能回答的。但你要对自己的代码如何融入整体的环境有一个清晰的认识,从而更好地将时间和精力分配到最能够带来积极影响的地方。


记住这五点,你就已经走上成为成功的程序员的道路了。但前路漫漫,始终牢记,一个优秀的程序员并不是只会写代码而已。

译注

译者:章凌豪

原文链接