本文转载自 InfoQ
这篇文章是对互联网上的一处知识殿堂——Hackernews(news.ycombinator.com)上软件工程主题下一个话题的简要分析。原始的讨论在此
(https://news.ycombinator.com/item?id=25643940),以供参考。
这个话题都是围绕着一般性的“精通”概念展开的。一些开发人员非常注重降低代码的复杂性,一些专注于理解技术的广度和深度,还有一些则不局限于单独的一两项技术措施——他们认为精通软件工程的人们应该在所有相关的领域和过程具备不亚于技术领域的专业水准。一些开发人员甚至提供了一个高级视角来统合所有意见。尽管当我们谈到软件工程专家这个话题时,大家都会想到技术熟练程度这个指标,但看过人们的讨论后你会为他们各自所重视的这么多领域感到惊叹。这是一场激烈的讨论,大家都从自己的个人经验出发,讨论哪些事情在他们眼中是正确的,具体为什么他们会喜欢这种事情,以及自己在非生产领域得到的经验等。虽然 HackerNews 是全世界开发人员浏览技术新闻,并在 AskHN 标签下讨论各种主题的圣地,但你应该意识到这些观察结果和我的总结并不是科学严谨的,而只是思想冲突的汇聚和针对专家领域未知事物的一次探索的解说。
工具和技术水平
一位开发人员认为,要达到一定的软件工程专家水平,开发人员开发一个由开发人员使用的库或工具的能力是基础,并且专家应该有能力想象出新的工具和愿景以提高知识水平。
的确如此,软件工程师的确倾向于专注在框架的应用侧而非理论侧的专业水平上。深入研究我们使用的语言、框架和库需要对语言做很多有条理、专注、深入的工作,这需要大量时间。
但这个论点也有反面看法。对这一主题发表意见的另一位开发人员提到了另一个层面,说当他任职于一家广告代理公司时,(Macromedia/Adobe)Flash 正处于鼎盛时期,开发人员纷纷使用这种技术来开发网站、游戏,而且确实非常熟练。但是,由于没能迅速切换到 React 这样一个基于组件的,使用与 Flash 的 Actionscript 不同的 Javascript 语言的开发平台,他的专业技能很快就化作了背景板上的点缀。
Flash 无法适用于我们当下使用的任何编程或部署范式,这肯定是一个艰难的过渡,它的教训也是值得我们今天思考的。因为在许多技术领域,人们在一项技术上投入大量精力来研究,就不会有那么多资源来了解其他很多技术了。如今,许多语言在语法上的差异都集中在应用程序上面很高的层次上,例如 CI/CD、Devops、容器和云。与 flash 时代不同,今天的软件工程技能更容易在各种范式和领域间转移。尽管没有开发人员在技术的深度与广度问题上制定任何硬性规定,但我们可以假设,开发人员应根据自己的利益或工作组织的需要来决定采用哪种方法。
尽管高级职位可能需要人们具备宏观视角,将解决方案选项放在更大的盘子中来解决问题,但如果你能精通一个领域自然会有其收获,比如说深入了解这个领域的权衡取舍。而且,到底什么是权衡取舍?
在探讨专家水平所需的技术专业程度时,一些评论引发了有趣的共鸣——权衡。
权衡取舍
一位开发人员说,如果你能在技术、解决方案、技术栈甚至算法的弱点或优势之间做出更好的权衡,那么你实际上是在准确地想象问题空间中的一条解决方案曲线。
“专家工程师能够避免没有价值的工作,这可能是他们最突出的技能”
这种想象力不是先天的,而是后天习得的。要做出权衡取舍,你应该清楚地知道在提议的解决方案中什么是对的、什么是错的、什么时候是对的、什么时候是错的,这样你才能知道要舍弃哪些内容、要保留哪些内容以及要添加哪些内容。为此,开发人员需要大量的经验,尝试许多不同的设置,探索许多不同的想法以及更多的反复试验。根据其他一些讨论者的说法,大多数解决方案提议都是错误的,虽然有些是正确的,但也要权衡取舍。因此,新手工程师会很难完成工作,他们只会一头扎进自己想到的第一个解决方案,然后被确认偏见推着往下走(WKPDA:确认偏差,是一种用如下方式搜索、解释、偏爱和回想信息的趋势:确认或支持一个人之前的信念或价值观);而中级工程师可以解决问题,却很难做出权衡取舍;专家工程师则可以使用不同的方法来找出可行的解决方案。
在讨论中提到了很多关于权衡取舍的问题——我们是否应该为了成本或复杂性而牺牲准确度,以及我们在什么情况下会这样做?某些情况可能会重视速度,牺牲精度,而另一种情况下可能会更要求性能而不是可扩展性。有些解决方案可能比其他解决方案更容易更改。根据开发人员的说法,这还取决于组织所运行的业务。如果你不能控制与组织其他部分的对接通道,你就无法成为软件工程专家。我不在乎你的实现在理论上是多么纯粹,或者交付的速度有多快。如果其他业务部门无法轻松连接、使用和习惯你的实现,那就太愚蠢了。有开发人员评论说,这就是专家工程师的工作:提出正确的问题并找出正确的权衡点,并且他们积累的经验让他们可以快速做到这一点。
权衡取舍的能力并不是获得高级软件工程专业水平的唯一决定性因素。专家工程师可能会更主动地介入问题本身。根据另一位开发人员的说法,专家工程师具有从比手头的工程问题更宏观的视角上思考问题的能力。探索问题、对问题提出正确的疑问,甚至完善和简化问题。它可能是描绘出问题空间解决方案曲线的起点。
权衡取舍和问题定义引起了讨论者们的共鸣,大家都认为这是软件工程专家需要的一大能力。而另一个指标则得到了讨论者的一致认可。
交付速度
一位开发人员问到,下面这些软件工程专家有什么共同点呢?
《德军总部 3D》《毁灭战士》《雷神之锤》和其他许多游戏的开发人员 John Carmack。
Jeff Dean,目前是谷歌 AI 的负责人,他的工作横跨 MapReduce 到 TensorFlow。
以及 BitTorrent 协议的作者 Bram Cohen。
正如开发人员所指出的那样,这些成就卓著的程序员在各自领域中引领着一大批程序员,他们的共同特征在于高效完成工作、勤奋工作以及极端专注于交付环节。
在许多编程技能发展文章或指南中都找不到这种指标。什么是极端专注于交付环节?
由于交付速度与产品价值的相关性极高(交付时间越少、产生价值越多),专家工程师可以避免去做没有价值的工作,这可能是他们的最突出技能。一位开发人员评论说,最好的团队可以带领整个团队远离毫无价值的工作。但是,虽然这一指标看起来很合理,但它的确存在一些障碍。
要提升这一指标,你需要一种权限,可以推掉没有价值的工作。另一位开发人员说,我见过很多优秀的工程师,他们具有这种素质,但是没有权限来实践自己的想法,因此他们的真实价值无法呈现。尽管许多人评论说特权位置在完全信任你意见的组织中很少见,这种组织可以让你自由地终止那些你认为没有价值的工作,并且不影响其组织目标,但也有人给出了如何获得这种特权的途径。一位开发人员评论说,当一位高级工程师知道什么是最有价值的工作,并且正在影响 / 推动路线图时,他就会便会赢得这种特权。高级工程师说“不”的次数要比说“是”的次数更多,并且每次会给出合理的理由。
一位开发人员提到,专家工程师可以让组织以更少的精力完成更多的工作,并避免陷入各种陷阱。但这很难做到,因为如果这些问题尚未显现出来,就很难说服管理层。
尽管这一指标可能看起来非常有趣,但对于有抱负的初级工程师而言,当做些探索是有必要的时候,极端专注于交付标可能会适得其反。不过许多开发人员还讨论到了软件专家主题的另一个有趣的矛盾。
管理复杂性
专家水平体现在管理复杂性上,许多开发人员在讨论中都同意这一点。高水平的代码具有某种一目了然的简单性,一切都是可预见和平平无奇的。一名开发人员评论说,你可以从代码中看到程序员的想法以及程序结构的规划。
“软件工程太过多样化、碎片化、混乱和多变了”
专家工程师控制着开发过程中出现的各种复杂性。另一位开发人员在评论中将复杂性视为一种专业水平指标,指出专家能够弄清什么是不可简化的复杂性,复杂性体现在实现、维护、算法还是可伸缩性方面,以及在应用程序的不同组件中如何权衡来解决这些复杂性。专家可以更轻松地将复杂性放在应有的位置,可以更好地权衡取舍,并且他们可以更轻松地估算实现项目所需的工作,因为他们能够凭借自己的经验很好地理解一个问题中不可简化的复杂性体现在哪里。
专家工程师可以识别和消除大部分意外的复杂性,来帮助他人更快地理解代码。意外的复杂性可能来自于小的结构问题到大规模的架构改造等层面。另一位开发人员补充说,一位专家可以解决这个问题,他们能够构建出这样的系统,当系统复杂性增加时,为系统增加更多价值的成本保持不变。
关于专家水平的讨论还在进行,评论中又有了另一种想法,会让你以不一样的角度思考所有这些问题。
旅行家
少数开发人员会说,这方面的工作没有所谓的专家级别。专家水平很难量化,尤其是在代码或工程智能方面更是如此。在软件开发领域有太多的变化和发展,以至于真正的专家很难定义。另一位开发人员说,我的目标仅仅是继续改善自己。我付出了多大的努力来跟上这个行业中成千上万的动态变化并不重要,似乎我们采取的每一项行动都需要权衡取舍,而且我们永远无法做出最好的选择,软件工程太多样化、支离破碎、混乱并且在不断变化。
我们使用的库和工具、我们开发的框架、我们熟悉的语言、每天看到的许多最佳实践和自动化途径,所有这些领域每天都在发展变化,我们会手足无措是很自然的表现。我们很希望看到这些进展描绘出的画面,那就是数以百万计的工程师在为这个行业和社区努力,但也应该有保持稳定和固定下来的东西,为我们进入这些工程荒野打通一条路线。
“为给定问题找到尽可能多的解决方案”
另一位开发人员说,虽然软件工程的专家水平是一个值得质疑的主题,但软件开发和工程技能的确存在一个“旅行家”的级别。正如一位开发人员所描述的那样,我们要经历的是一段旅程,旅途中没有所谓的专家,而是每个人都要经历的事物。不过另一侧还是有一个基准……如果产品不起作用且不可维护,则肯定缺乏专业水平。一位开发人员采用了一种哲学和科学的方法来质疑专家水平的前提。有人能声称自己是某个知识领域的“专家”吗?毕竟每个人眼中对一个领域的看法都有着巨大的差异。在某些方面,要“知道”一种工程方法或范式是“正确的”会困难得多。我们如何让类型来跟踪系统的“重要”不变性?我们如何才能说服自己分布式系统可以保证某些属性,或者对系统进行修改不会破坏这些保证?
这样的观点当然是有道理的。
智 者
在论坛的讨论中,大家提供了许多明智的建议来帮助你提高专业水平,其中很多有趣的建议涉及到我们在日常生活中遇到的一些事情,有些很常见,但也可以视为一种提醒。
一位开发人员指出,你不需要大量经验就能开始实践。有一位导师对我们团队做的事情是:请整个团队列出问题的所有可能解决方案,包括显然很糟糕的方案,然后让我们根据每个方案的优缺点来缩减清单,直到我们就该做什么事情达成共识。尽管这对于平常的问题来说似乎是杀鸡用牛刀,但它可以让我们体会到美妙的细节,打消对实现的担忧,甚至随着时间的推移,让团队能够从心理上计算出权衡取舍。
你永远无法真正做到完美,只能接近完美。了解你的局限性与了解你的能力一样重要。一名开发人员评论说,深度与广度之间很难取舍,而且你的时间有限,无法深入这么多领域。与专家一起工作、编写和删除大量代码、参与代码审阅以及从他人那里阅读更多代码肯定会对你有帮助。另一位开发人员建议,你需要具有交付大量程序的经验,因此,你应该围绕交付尽可能多的优质程序这一目标来优化自己的职业生涯。
很多评论非常肯定地说,最好的工程师产生的错误少于他们要修复的错误,并且很少会遇到“一团糟”的情况,也就是修复一件事会破坏另一件事的窘境。另一条评论则表示,始终如一且可靠地交付好的软件解决方案是关键。始终如一,这不只是侥幸或运气,而表明你知道自己在做什么,并且可以重复做下去。
从字面上看,软件工程是一项团队运动,看起来很多人都同意这一点。你需要知道如何在工程的所有相关领域中编写设计文档、测试计划、架构计划、进度报告和文档。如果你不能有效地传达你的设计或进行战略性交流,即使你知道别人做的事情是好或是坏,你也无法说服他人你是对的。
一位明智的开发人员说,你可以针对给定问题找到尽可能多的解决方案。