翻译 [译] 如何成为更好的开发者

lanzhiheng · 2019年01月17日 · 最后由 Mark24 回复于 2020年09月25日 · 7237 次阅读

关于如何成为一个更好的开发者,我觉得作者总结得很全面。可能有些说法对于一些人来说有点“老掉牙”了,但往往越是这样的东西越有存在的价值,更多的只是看的人眼高手低,知易行难。原文链接:https://medium.com/devtrailsio/how-to-become-a-better-software-developer-dd16072c974e


Software Developer 今天我要分享一些想法,用这些方法,一个软件开发者不仅能够提高他们的专业技能还能够在工作中表现更加出色。这里抛出的话题具有普遍性并不限定于特定技术栈。大部分的建议甚至不只是针对 IT 职业,这些通用的建议是关于如何开发你的人格特质,改善与同事和客户之间的合作,促使你的软件开发职业往前迈进。

虽说这篇文章有些东西是主观的以及个人经历的一些反思,然而除此之外的建议已经被其他人采纳,并为他们带来成功。

理解点对点的流程

许多开发者把软件开发想像成都只是关乎编码的工作,并且除此之外的一切都是惹人厌烦的,并且浪费了他们的宝贵时间。然而,事实并非如此,在你开始编写软件的部分代码之前,需要经历把模糊的想法转换到精心设计的解决方案的过程,这一切都是在为具体实现做准备。当你把最后的修改推送到 Git 仓库之后,软件将被测试,部署,监控,分析和改善。编写代码只是这许多步骤中的一个而已。

那么为何会产生这种想法?多数情况下,特别是在为一个庞大的组织工作的时候,项目不同的阶段会由不同的团队甚至是不同的部门负责。这一切开始于负责需求的商业分析师,接下来这些需求会被设计人员进一步处理并为开发者产生原型。开发者带着原型离去并进行编码工作,然后把工作成果提交给 QA 工程师。如果一切都顺利,这个工艺品就会被发送给运维团队,他们会对相关代码进行部署,并交付到最终用户手上。这个过程就像是一堆彼此分离的步骤的集合,它们之间并没有任何反馈。就因为部门之间缺乏交流,各自的代表们通常也不明白其他部门工作的目的,这会造成误解甚至冲突。

Software process

如上图,软件开发经常被认为是缺乏反馈的多个步骤的集合。

在今天很多人听起来这是不可思议的。随着敏捷方法论的盛行,更多的公司从这种死板的开发方式过渡到由不同的专业人员组成的小团队。但是即便如此,我们依然发现人们还是没有去了解其他人工作的打算。你每隔多长时间会被你的设计师惹怒,只因为他们想要你实现一个定制的多选框,这在你看来只是浪费时间?还是说,你因为忘记使用正确的字体而受到他们的批评?

这里的许多分歧都可以被克服,只需要通过关注其他人的工作。跟你的设计师坐在一起并向他们表明实现一个定制的多选框需要一些时间,而且这个组件库已经提供了一个相似的多选框,我们可以复用它。学习排版印刷的相关基础,就会明白为什么选择正确的字体会对结果有影响。对管理者,商业分析师,QA 工程师,技术支持以及市场专员们都采取相同的态度,T. Huxley 说过

尽可能广泛地涉猎各门学问,并且尽可能深入地择一钻研。

通过在每个人身上学习一些东西,你将能够预估他们的需求,减少反馈的次数并且更频繁地交付。除此之外,你还赢得许多人的喜爱和尊重。

了解你客户的需求

对于你的客户有件重要的事情你需要知道一下:你的绝大部分的工作他们都是无法理解的。敏捷,函数式编程或者非关系型数据库在他们看来都是黑魔法。即便他们中有些人对你的工作感兴趣,并密切关注着你的工作,但大部分时间他们都是处于模糊的状态。每次跟开发者交流他们的表情就会像下图这样

跟软件开发者交流时大部分客户的表情

他们需要对所雇佣的软件开发真有一定程度的信任。当人们需要为某件他们所不理解的事物花费大量金钱的时候,往往会觉得不适。还记得你上次走进不熟悉的汽车维修服务店,并不确定自己是否可以相信他们会把你的坐骑修好时的感觉吗?很好,你的客户对你也是有相同的感觉,不同的只是这里没有汽车,而只有一大堆抽象的并对他们而言是模凌两可的概念,这些概念被假定可以以某种方式具像化为产品以及收益。当与新客户一起工作的时候,获得他们的信任是很重要的。要确保他们理解你的运营方式,目标是每次交付更小的结果但是会更加频繁地进行迭代。这种方式能让他们看到你的工作进度,审核中间产物,并提出他们的意见。

客户通常会倾向于提出他们自己的解决方案,而不是分享他们的问题。当他们对你的能力有一点概念的时候,他们就会意识到自己的解决方案通常是带误导性的,低端的或者说是不切实际的。还记得一句亨利福特的老话(可能是虚构的)

如果我问人们想要什么,他们会说更快的马。

比起随波逐流并且静悄悄地实现客户想要的功能,有些时候更有效的方式是请他们退一步,并讨论他们想要解决的首要问题。结合他们的领域经验以及你的专业知识,你可能会得到一个更好的解决方案。

记住,任何人都不喜欢自己的想法被质疑,实施这个战略的前提是你在客户眼中是睿智的并且是能鼓舞信心的。为了理解问题并提出更好的解决方案,你需要离开舒适区并让自己沉浸在他们的生意场中。如果你是为金融或者健康护理这样的复杂行业工作的话,会有一定的挑战性。然而一旦你做到了,可能顾客下次还会找你合作,并且能够进一步对你敞开心扉。

为工作选择恰当的工具

如果你有一个锤子,一切看起来就像是钉子。

tool

通常的开发者一旦学习了一门技术,就急于用它来解决所有他们遇到的问题。并不意外,但这种方式会引导出许多次优的结果。相反,当处理一个新的问题时,停下来并思考你所支配的工具是否真的适合这类工作。如果你对此有所怀疑,稍微做一下调研,并提出一堆用于解决这类问题的优秀可替代选项。为了使工作更容易,需要编制出一系列问题并且挨个地去审查每一个可选项。虽说每次评估的时候问题会有所不同,但是可以按下面的路线前进:

  • 它必须支持什么平台或者设备?
  • 非功能性需求是什么,比方说性能或者说内存使用?
  • 这个选择是否需要购买证书?或者说你需要免费,开源的东西?
  • 这个解决方案是否提供了超出你需求的东西,或者说你是否需要自己手写一些东西?
  • 你是否有一些其他的限制,比如公司的政策,法律层面的考虑,或者团队中缺少专家?

通过回答这些问题应该可以帮助你组织脑海中的可选项,并缩减“候选人”名单。

安全地进行试验

那么如果你所掌握的东西实际上并不是很符合你案例的需求,你想要尝试一些新的东西该怎么办呢?实际上你对一些事物没有经验并不意味着它超出了你要解决的问题。这只是意味着你需要考虑更多的东西:

  • 你有足够的时间做准备吗? 如果项目交付日期并不是很赶,在开始实现一个功能之前你可以尽可能去学习一些东西,并承受走这条路所需要的时间成本。或者至少采用“成功之前先装一下”的方法,告诉客户你知道你自己在做什么,并以此来安抚他们。

  • 首先确定那些你需要测试的东西。 贯彻“尽早失败”的原则,在你可以对这次试验做总结之前,需要确定有哪些重要的东西是需要评估的。对这个系统的性能有所怀疑?那就尝试构建一个最小的原型,并运行一个负载测试。对采用一个独特的程序库或者集成一个外部的系统没有把握?那就分别实现他们,然后再去构建剩下的东西。

记住,走这条路对无论对你还是客户来说都是有风险的,他们需要知道风险的存在以及潜在的好处。在这之后,可能两周的调研会节省你数个月的工作量,往长远来看这听起来是个不错的成果。即便最后试验失败了,你也只是失去了两周的时间。你的客户对你越信任,就越有可能会同意这类试验。

站在巨人的肩膀上

往往重新发明的轮子往往会导致奇怪的结果

重新发明轮子通常会导致奇怪的结果

IT 从业者有两个普遍的特征:1. 我们是有发明才能的。2.我们享受我们的工作。这听起来像是好事儿,然而这会带来一个尴尬的副作用:我们倾向于对曾经被解决过的问题提出自己的解决方案,因此,当我们面临到底是使用已有的框架,库,服务还是自己手动去实现这两种选择的时候,我们都倾向于选择后者。这会把我们带上重新发明轮子的无效之旅。下面是一些造成这种结果的常见误区

  • 自己来实现要比学习第三方库要容易。 这可能是一个最有说服力的理由,但重要的是不要过于低估手动实现的难度。通常有些东西一开始看起来很简单,但它会在开发过程中变得越发困难。最终你可能会花费一大串的时间来处理 bug 以及边界值问题,而这些问题可能已经有人帮你处理过了。

  • 这个解决方案提供的东西超出了我的需求。 要说它是个坏东西除非有什么特殊的理由,比如增加了最终产品的体积,添加了一些潜在的风险因素或者说考虑到这会拖慢构建流程。而这并不总是坏事,你可能到后面还是会需要用到它。另一方面,如果添加整一个库最终却只使用了其中的一个函数,就可能是个过度行为了。

  • 我们能比它做得更好。 即便是有一些成功的项目都是以这种说法为开端,但这并不是一个惯例。一个高质量的第三方的解决方案都是由团队维护的,他们有一定的经验,并且为了解决实际问题投入了不少资源。为了完成这些事情,你需要投入的甚至更多。在大多数项目中我们都没有资源来做这些事情,或者说这根本不必要。

  • 从代码的所有权以及长期维护角度来考虑,第三方的方案可能会是个问题。 有些人害怕一旦使用第三方库,你将会陷入因某种原因在某个时间点该项目会被抛弃或者不再稳定的风险当中。这种被项目封禁的危机是真实存在的,你应该要考虑迁移的策略。如果它是一个开源项目,你是否有可能 fork 它并且自己维护?或者说如果它是一个有专利的项目,替换它需要付出什么代价?基于这些问题,你可以对这种冒险是否值得作出一个清醒的抉择。

通过重新实现来学习

这是这则故事的另一面。自己重新实现一些东西实际上是很好的学习方式。为一个生产级别的项目编写你自己的框架总是一个坏的主意,然而通过创建一个框架来练手却有很高的价值。尝试解决相同的问题,能够让你对框架已经解决了的问题有进一步的理解。但不要太过于深入兔子洞中,一个简化了的粗糙实现足以让你对场景有所理解。

当你这样做的时候,要敢于窥探相似项目的源代码。从开源项目中学习,你将会在那些更老练的开发者的经验中受益。

为如何工作而工作

wheel

你需要努力去改善的的不仅仅是技术方面,还应该包括方法伦。如同恰当地设计并且优化过的软件,一个确定的工作流程将会减少你的工作量及工作压力,却能产出更好的结果。建立一个有效且高效的工作流程并不是一个简单的任务,针对这个话题已经有许多的书籍和材料可以参考。不过在开始之前,先考虑改善接下来的几个领域:

  • 团队和项目管理的方法伦。 我们的大多数工作都是团队协作,采用一个能够改善团队成员合作关系并为每个人建立一个通用工作节奏的流程是很重要的。软件开发中的敏捷运动已经孕育出许多被广泛接受的方法伦,比如ScrumKanban。虽说它们能够协助你组织好工作但却不能覆盖所有东西。你还需要其他的方法论帮助你做预算,安排问题的优先级,改善沟通等等。你需要去确定你正在努力工作的领域,并寻求该领域的最佳实践,这将会使你的努力更有价值。

  • 个人流程。 就像是管弦乐队,一个高效的团队必须有相同的节奏,但是这并不意味着每一个团队成员必须用完全相同的方式来工作,每个人都有他们自己的选择权,应该要以对他们而言更高效的方式来工作。举个例子,大多数人都希望在数个小时的编码过程中不被打扰,但我自己则喜欢在一个或者两个小时中添加一些休息间隔(一个不太严格的番茄工作法)。我也不喜欢在家工作,而更喜欢在办公室或者咖啡厅工作,这是为了避免家庭相关的干扰。找出对你有效工作方式的并坚持它,但是要确保你的习惯并不会给团队的其他成员制造问题。

  • 工程实践。 在技术和方法论之间有许多专注于改善开发流程的实践。举个例子,测试驱动开发以及行为驱动开发会协助你更好地组织和测试代码。代码审查会帮助减少代码的缺陷,并在团队中传播知识。持续集成持续交付简化了部署流程,使过程更加健壮。结合其他已经被有效组织的方法论来贯彻这些实践以达到产出最大化。

记住,没有一个流程会对所有人都有效,你需要自己的环境中试验它。当然,要确保对流程的完全把控并且能够正确地实现它。在已经实践过这些开发流程的团队中寻求建议,从他们的经验中受益。不要忽视相关的软件以及实质性的工具,它们会帮助你接纳一个流程。为持续交付准备一个真实的看板以及一个现代化平台。采纳一个新的流程会需要付出些努力甚至会导致短期的生产力减退。给它一点时间,并对其中的一些事情是否得到改善做个评估。

移除障碍物

关于障碍物的问题需要单独拿出来说一下。人们通常会错误地疏忽一些小的麻烦事,因为它们看起来似乎是无关紧要的,然而却可能会对你的工作有十分负面的影响。你的产品设计师是不是坐在独立办公区或者是另一个楼层?这意味着如果需要进行交流不得不多投入些努力,这会导致一些事情不会被讨论到。写测试是否是件困难的事情?这会导致许多地方没有被测试覆盖。

这些东西在他们自己看来都没有实际的危险,但是问题一旦堆积就会引发严重的后果。危险的状况是,在一切都太晚之前你通常都不会注意到它们,尤其是总会更多严重事故需要跟进的时候。记住温水煮青蛙的预言以及量变产生质变的观点。

在麻烦的事情来临之前保持警惕并与这些事情的根源作斗争。

专注基础

基础概念是构建你职业生涯的砖块

IT 行业是发展极其迅速的行业。每一周都会有新的工具被发布到市场上。我之前的文章曾经提到过名声狼藉的JavaScript 疲劳综合症。许多开发者会感受到压力并觉得自己被强制在每一个新的项目中更换他们的 JS 技术栈,这会让他们发狂。确实,总是使用前沿技术是有挑战性的,这里有一些关于如何让这过程更简单的想法。

首先,把焦点放在基础上。即便新的技术会频繁地出现,新的基础概念其实是很少的。当学习新东西的时候,确定你能够理解引导出这整个实现的底层思想,很有可能,这些思想还会在其他的项目中被用到,一旦你遇到相似的东西,你将会更加容易去掌握它。举个例子,现代的 JavaScript UI 框架都是基于组件的,一旦你明白怎么用 React 去构建一个面向组件的应用程序的时候,这个经验在 Angular 上也能够适用。你会在 Angular 身上找到 Redux 思想的相似实现,Angular 联动式状态管理思想也被 React 社区以 Mobx 的方式实现了。

花费一些时间让自己去熟悉一些经典的书籍里面关于软件开发通用模式的话题,比如 Gregor Hohpe 和 Bobby Woolf 合著的“企业集成模式”,Gang of Four 写的著名的“设计模式:可复用面向对象软件基本单元”或者 Martin Flowler 的“重构”。即便这些书里所描述的一些东西已经过时了,你仍然可以通过它们来学习到设计模式是怎么进化到今天这样的。

第二,不要急于学习每一样新的事物。我明白追随在 Hacker News 上出现的每一样新的事物是很有诱惑力的,但是里面的大多数东西都只是噪音而已。把视线放在那些已经被社区围绕了一段时间,并且对比最初的大肆宣扬已经成熟了的事物。不要陷入害怕错过的情绪中。你只需要稍微关注一些正在发生的事情,就不会错过重要的东西。

额外提示

tip

我们已经在这篇文章中谈论了许多东西了,但是在圆满结束之前我还有一些其他的观点想要强调一下。比起专业技能这些小贴士更多跟你的个人特质有关,但是我依旧相信它们会对你的职业生涯有很大的影响。

分享知识

通常人们会觉得囤积有价值的知识会让他们成为团队中不可或缺的存在。你的团队中如果有这样的人将会把你暴露在巴士因素下,而这样一个人一旦离开项目就会把你置于一个艰难的处境。如果你是这种人中的一员,考虑到让自己在团队中变得不可或缺的话,你的专业知识将会是一种束缚并且你也会没有假期可言。你可能会失去组织里的其他的工作机会,毕竟你已经被捆绑在这个角色上了。反之,尝试跟团队的成员分享知识,如果有可能把你一部分的工作代理给他们并运用好这种合作关系,甚至可以基于他们的工作构建出更好的东西。

不要抱怨你自己或者其他人

记得很久之前由于我的失误导致一个项目遭遇事故。我们被驱赶着迅速修复这次事故,还记得当时我的客户跟我说

你不要在一切都跟随着计划进行的时候去审判一个团队的表现,而是应该在麻烦大了的时候看他们是怎么运作的。

不管你多么优秀,有些事情也会出错。而在这个时候重要的是能够保持冷静,体面地去处理这种场景,团队成员彼此间要相互尊重。当火势蔓延,不要急着寻找替罪羊,这并不会帮助你在未来的日子中避免失误,而只会在公司中传播恐惧及怀疑。反之,你可以与受影响的当事人一起来到事故现场,并做常规的“尸体检查”。把焦点放在事故的源头上,总结事故发生的原因,并且还要头脑风暴一下,为了在未来避免这类问题应该要怎么去改善你的系统还有工作流程。

不要做一个混蛋

开发者社区是一个有意思的地方。一方面我们看到许多受到开源想法驱动的人们通过为开源项目工作,在会议中做演讲或者编写文章来为社区做贡献。另一方面,我们也遇到一些人他们高喊新的思想,不尊重新来的人并且对周围的人表现出粗鲁的行为。不要成为他们中的一份子。保持和蔼并传播爱。

大多数专业的意见可以被总结为4个字

圆满结束

对于我们的工作,最好的一点就是没有限制。有许多新的道路可以走,有许多怪可以刷。不管你是刚开始你的征途还是一个有经验的专家,请把这些东西放在心上。它们会帮助你寻找你自己道路,每执行一步你都会变成一个更好的开发者。

你是否有不一样的建议想要分享给其他人?尽管把它提交到评论中或者开启一个讨论组!


是否有兴趣学习 Web 开发或者更大程度地提升你的技能?切换到devtrails.io,这里有许多有用的指南,它们会协助你围绕着 Web 开发推算出你自己的成长路线。

  • 理解点对点的流程
  • 了解你客户的需求

呵呵,公司请不起产品经理吗?

nouse 回复

你可以这么想,当没有产品经理的时候,你的客户是公司的客户。当有产品经理的时候,你的客户是产品经理。

nouse 回复

确实没有产品经理。

nouse 回复

如果只是想作为一个编码者,那你会写代码就够了 如果对自己有更高的期望,客户,需求,产品,ops 都是需要熟悉的

最喜欢这种扯淡的帖子了,人的时间是有限的,理解需求肯定有帮助,但是如果公司连产品经理都没有,那待在这种公司本身就是浪费时间。

我没有否认这篇文章的价值,但是读了文章之后要思考,哪些步骤更具备可行性。

nouse 回复

读了文章之后要思考,哪些步骤更具备可行性 对于这点我比较同意。

另外关于产品经理的问题我觉得还是看公司的情况不同而定吧。像我的公司是资讯外包公司,一般都没有自己的产品,目前也就没有产品经理。如果需要理清需求还有客户对接一般是项目经理或者对应项目的负责人负责,开发人员也因此要承担更多的责任,虽然一般不需要与客户直接对接但还是需要更多去理解客户的需求。据说之前也有招过产品经理,不过大部分时间都是闲置着了。

nouse 回复

也不尽然啊,如果说你只考虑做项目/产品的公司或团队协作,这么说还有情可原。可开发者并不只局限于此啊。比如说有那种独立开发者,一两个人做一个或几个商业软件出售的,人的确就不是/没有专职的产品经理,用户有什么反馈都是直接 email 或者通过别的 online support 途径来诉求,学会理解客户的需求对他们来说就是功课之一。

还有那种专职做开源软件的,可能某种意义上他们没有(或少有)商业客户,但是他们作品的使用者(大部分也是开发者)其实也是客户啊,提交 issue 或者 feature requests 本质上也是客户需求,他们往往就是自己的产品经理。

限定了工作类型的话,你的说法有道理,不过原文并没有局限“你是哪种开发者”,所以考虑到现实世界的多元性,顶多说那是可选的,仅供参考,但未必是不可行的。

nouse 回复

哈哈,我发现你什么都能怼一怼···

stephen 回复

只能证明你来论坛太晚

lanzhiheng 回复

工作内容如果包含要理解客户需求那就是本职要求,不能算变得更好啊

nouse 回复

对于这个问题,我是觉得程序员在实现一个功能之前还是有必要了解一下客户的需求是什么(哪怕这个需求滑稽得让你无法忍受)这有助于一个程序员对自己开发的功能或者说整个系统有进一步的了解,对于一个程序员来说我觉得是有好处的,可以在某种程度上让一个程序员有那么一点产品的意识。

我不太清楚你们有产品经理的公司是怎么运作的?总不会说产品经理对接完需求之后然后让我们做什么就做什么就只需要关心写代码的事情?

nouse 回复

本职要求,也有做得好与不好之分;把本职要求做得更好,不就是变得更好吗?

文章不错,聊一点个人拙见。

更喜欢将本文标题理解为:开发者如何变得更加优秀、能创造更大的价值?

之所以这样理解,是因为很多人像我一样现在只是一个普通的开发者,但我相信很多年后,随着不断地积累,我们这帮人会慢慢从开发者的角色逐渐分化,变成一个复杂的综合体,也只有这样,才能够真正地实现更大的价值创造,分化的方向大概是:

  • 拥有产品经理的能力
  • 拥有项目经理的能力
  • 拥有 leader 的能力 (判断力、打造团队等)
  • 拥有开发者的能力
  • 拥有搞定人的能力
  • ···

多年后,从开发大军中脱颖而出的人,都会拥有上面这些方向的素质,成为一个复合体。放眼望去,在大的团队或项目中产生核心价值的人,都是这种复合体。大部分节点上的螺丝钉都只是螺丝钉而已,当然这些螺丝钉的价值总和还是会非常大的,只不过均分到人头上就不见得了。

不过,除了上面的分化,部分在技术圈备受崇敬的人还有另一种发展方向,就是成为能搞定高难度技术点的精英,他们会在相对单纯的技术环境下创造价值。不过大部分这种人才其实也具备产品经理和项目经理的能力。

能吃透行业,在某个方向上有深耕的复合体,具有很大的单点价值。

Matz 是开发者吗?不是,他是一名拥有开发能力的和项目管理能力的产品经理。他的核心价值在于设计了 Ruby 这款解放程序员的产品,并在带领开发者迭代 ruby 这个项目。

马化腾是开发者吗?不是,他早期是拥有开发能力的产品经理,现在应该算是懂技术、产品、项目管理、市场···的 leader。

···

一个人只有两只手,一天能写的代码量太有限,高价值的代码更有限。何况岁数变大,体能还在下降····

early 回复

感谢你的长文评论。你所说的观点我完全赞同,几乎都是我近期在反省的事情。当发现自己渐渐演变成螺丝钉的时候,或许应该考虑是不是哪些地方需要改善一下了。

我挺喜欢这个文章。 工程师的视角具有局限性。打开上帝视角也很重要。 如果我们不知道自己是在服务什么,我们能提供的服务也很有局限。技术没有赋予它意义,技术自己也意义有限。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号