下面的内容是我在作为一名程序员入职之前阅读的由Gergely Orosz写的The Software Engineer’s Guidebook。我将将阅读时得到的重要的信息总结成中文以供大家分享。
在独自工作时,编码几乎总是构建软件中最具挑战性的部分。而在团队中,与同事合作可能同样具有挑战性。在协作中,许多因素都很重要:确保遵循约定的方法,就使用哪些编码模式达成一致,如何进行测试,遵循哪些命名约定等等。
当你作为更大团队的一部分工作时——例如,当几个团队共同构建一个产品时——你需要确保你的工作方向与其他人保持一致。这可能包括确保你暴露的新API端点能够按照另一个团队的预期方式工作,或者告知某个团队他们正在阻碍你的进度,因为他们需要对其服务进行修改。
在大多数公司中,沟通、协作和团队合作是对全面发展的高级软件工程师的基本期望。在本章中,我们将探讨最常见的协作情况,并深入研究如何在这些方面表现卓越。
一个好的代码审查应该全面考察代码变更及其如何融入现有代码库。审查者需要检查标题和描述的清晰度,理解变更的原因,并关注代码的正确性、测试覆盖率、功能变化,以及是否遵循了编码规范和最佳实践。
高质量的代码审查会指出明显可以改进的地方,比如难以理解的代码、模糊的命名、被注释掉的代码、未经测试的代码或被忽视的边界情况。审查者还会注意到当一次审查中包含了过多的变更时,建议将代码变更保持单一目的,并将其拆分成更聚焦的部分。
更好的代码审查会在更广泛的系统背景下看待变更,检查变更是否易于维护。审查者可能会询问变更的必要性以及它如何影响系统的其他部分。他们会关注引入的抽象如何融入现有的软件架构,并指出可维护性方面的观察,如可以简化的复杂逻辑、测试结构、代码重复等可能的改进点。
代码审查的语气对团队士气有着重要影响。严厉的语气可能会给人一种敌对环境的印象,甚至被视为微攻击。主观性强的语言可能会让人产生防御心理,引发激烈讨论。相反,专业、温和和积极的语气有助于营造包容的环境,使人们更愿意接受建设性反馈,从而促进健康、活跃的讨论。
好的代码审查倾向于提出开放式问题,而不是做出强烈或主观的陈述。审查者会提供可能更优的替代方案和解决方法。他们认识到自己可能会遗漏某些内容,因此在做出纠正前会先寻求澄清。更好的代码审查还体现了同理心,认可代码作者在变更上投入的时间和精力。这些审查会赞赏好的解决方案,总体上保持积极的语气。
好的代码审查不会在存在未解决问题的情况下批准变更。然而,审查者会明确指出哪些问题或评论是非阻塞性的或不重要的,通常将这些称为"小问题"或"nit"。在批准变更时,他们会明确表示,例如给出"LGTM"(looks good to me)的评价。同样,在请求跟进时,他们也会明确表达,并使用代码审查工具或遵循团队惯例来传达这一信息。
更好的代码审查在存在重要问题需要解决时不会批准变更。这些审查在原则上坚定,但在实践中灵活;有时,作者会在后续的代码变更中解决这些问题。对于紧急变更,审查者会尽量让自己有空进行更快的审查。
好的代码审查会提出所需的所有问题,如果修改没有解决这些问题,审查者会指出这一点。当对话变成冗长的来回讨论时,审查者会亲自联系作者,以避免在代码审查工具上浪费更多时间。
大量评论的存在表明可能存在误解,通过面对面交流更容易识别和解决这些问题。高效的工程师知道,亲自接触可以节省时间并避免产生不良情绪。
"小细节"(Nitpick)指的是对不会显著影响拉取请求质量的微小变更的评论,例如建议变量或函数的替代名称,声称变量声明应按字母顺序排列,或者缩进可以改进等。
好的代码审查会明确指出哪些查询是小细节,通常不会包含太多这样的评论。过多的小细节评论可能会令人沮丧,并分散对更重要主题的注意力。
更好的代码审查意识到过多的小细节评论是缺乏工具或标准的迹象。经常遇到这些问题的审查者会寻求在代码审查过程之外解决问题。例如,大多数常见的小细节评论可以通过自动化代码检查来解决。那些无法自动化的问题通常可以通过团队达成某些标准并遵循这些标准来解决,最终可能会实现自动化。
优秀的代码审查对所有人都采用相同的质量标准和方法,不论职位、级别或工作年限。审查意见应当语气温和、积极支持,并明确指出需要在批准前修改的地方。
更好的代码审查会特别注意为新加入的同事提供良好的首次审查体验。审查人员会体谅新同事可能不了解所有的编码规范,尤其是一些不成文的非正式规则。他们也充分意识到新人还在熟悉代码库,可能不清楚代码遵循的某些惯例。
更好的代码审查还会额外花心思解释首选方法,并提供更多学习资源。审查意见语气积极,为新人对代码库做出的首次贡献表示祝贺。
优秀的代码审查会尽可能考虑到分布式工作场所的时区差异。审查人员会尽量在双方都在工作的重叠时间内进行审查。对于需要大量评论的审查,审查人员会主动提出直接交谈或视频通话。
更好的代码审查人员会注意到反复出现的时区问题,并寻求超出代码审查框架的系统性解决方案。这类问题的解决通常并不简单,可能涉及重构和创建新的服务/接口,或者改进工具。解决这种依赖关系可以让双方团队工作更轻松,进展更高效。
如需更多关于如何进行良好代码审查的建议,请参阅:
对于经验不足的工程师来说,配对是一种很好的方式,可以完成困难的任务、学习更多知识并提升自己。但配对对于经验丰富的工程师同样有用。你难免会遇到卡壳的情况,这时与他人配对可以帮助你解决问题。在使用新的代码库或技术时,尤其容易遇到困难。与团队中或相邻团队中的专家配对,可以帮助你更快地克服问题。你还可以向他人学习,建立更牢固的职业关系。
配对可以是结对编程,也可以只是配对解决问题。
结对编程时,如果是面对面,通常是坐在一起,共用同一个屏幕,轮流使用键盘。在远程环境下,通常是通过视频通话和屏幕共享来进行,或者更常见的是使用协作编辑器,双方可以同时输入文本。
配对意味着面对面时坐在一起或使用白板。远程配对通常是通过视频通话,根据需要使用屏幕共享或协作编辑工具。我在下文中用”配对”来指代这两种活动。配对是两个人合作解决问题最简单、最高效的形式。
对软件工程师来说,配对最常用于解决以下问题:
除了传递知识,配对还有助于建立与配对工程师的个人关系。无论谁更有经验,你们都会通过一起解决问题相互学习。
当你在配对中是更有经验的一方时,有一些方法可以让会话更有效:
有时偏离主题是自然的。配对时偏离主题,偏离解决主要问题是很常见的。特别是在没有时间压力的情况下,这种情况可能会发生。这是可以的,也是自然的。配对部分是为了解决问题,部分是为了相互学习,部分是为了更好地了解对方。而且这也很有趣;所以如果你有机会探索一个有趣的领域,就去做吧。
不要害怕询问是否可以与某人配对!虽然这种感觉在经验较少的工程师中更为常见,但我甚至观察到一些高级工程师担心请求与资深或首席工程师配对会被视为承认自己无法胜任工作。但事实并非如此:请求配对是更快完成工作和学习的好方法。
当你请求与某人配对时,要尊重他们的时间,如果他们有紧急事务要处理,要保持灵活。如果这个人很有帮助,要感谢他们抽出时间配对。可以考虑在他人面前这样做。这是一件好事,也可能会鼓励团队成员在看到你这样做并从中受益后提出自己的配对请求。
配对似乎是一种被低估和未充分利用的方法,特别是在远程工作的环境中。我建议你通过主动帮助看起来遇到困难的开发人员,以及与可能帮助你解决问题的同事配对,来使用配对方法帮助你周围的人。
作为高级工程师,你将有很多机会指导同事。同时,向更有经验的导师学习也是个不错的主意。
指导并不一定要是正式的才能成为有效的学习经历。事实上,大多数指导都是非正式的。当开发人员一起工作和协作时,指导自然而然地就发生了。
代码审查或团队项目合作是非正式指导的常见情况。没有固定的结构,只是工程师们一起工作,给予和获得反馈,互相学习。
与其他工程师进行非正式的一对一交流,简单地讨论他们正在处理的事情,也可以是一种非正式指导 - 即使它看起来不像!这仍然很有启发性,通常能提供新的思路和方法。
对开发人员来说,更罕见的指导形式是正式指导。这是一种更有经验的同事同意指导初级工程师,启动指导关系,并定期举行会议以帮助被指导者成长的安排。那么,既然非正式指导无处不在,为什么还要费力进行正式指导呢?有几个原因:
在两个地方很容易开始正式的、有针对性的指导:结构化程度较高的科技公司和在线社区。一些科技公司有指导计划,但这些很少对外公开。优步、PayPal和亚马逊等公司都有内部计划,可以轻松获得有针对性的指导。
在线的导师社区也很欢迎新人,容易上手。有越来越多的网站提供这类服务:可以搜索”开发者指导其他开发者”来获取资源。
在我作为开发人员工作期间,如果有正式指导,我可能会成长得更快。因此,当我转型为工程管理者时,我特意在团队中安排了经验较少的工程师和经验丰富的工程师之间的指导关系。初级工程师因此成长更快并不令人意外。出乎我意料的是,高级工程师通过与资深或首席工程师的正式指导也受益匪浅。
那么,如何建立正式的指导关系呢?和任何项目一样,良好的开端有助于让每个人 - 在这种情况下是导师和被指导者 - 达成共识。
开始正式指导的最佳方式是召开启动会议。我经常建议人们这样接近潜在的导师:“您是我仰慕的人。我能安排一次谈话,讨论一下我想要成长的领域,以及您作为导师可能如何帮助我吗?“最好专门安排时间来分享一些背景,看看你们双方是否愿意并能够承诺进行指导。
准备好在启动会议上讨论的话题列表,例如:
请记住,如果有人邀请你成为导师,说”不”也是可以的。作为寻找导师的被指导者,我曾遇到几位潜在导师婉言谢绝。对有些人来说,是因为时间不够,而其他人则觉得他们没有我所寻求的专业知识。不要因为被拒绝而灰心;问问他们是否有其他潜在导师的推荐。你很快就会找到合适的人选。
以下是成为一名有效导师的方法:
作为一个优秀导师的更多建议:
当建立了固定的交流频率后,如何持续从指导中获得价值?我坚信,作为被指导者,你需要在指导中投入时间和精力才能从中获益。
指导对所有参与者都有重大的长期好处。软件行业其实很小,所以你今天指导的初级人员随着时间的推移会变得更资深,你们可能在不同的场合重新联系。如果你是一个支持性的导师,他们很可能会记住这一点。谁知道一段良好的关系在未来某个时候可能会带来什么好处。
指导没有固定的模式。对大多数人来说,它是非正式知识共享和定期交流的混合。被指导者经常会就一次性问题联系导师。有些人更喜欢面对面指导,而有些指导关系仅限于代码审查。每种指导关系都是不同的;重要的是它对导师和被指导者都有效。
作为高级工程师,你会注意到其他开发者的优秀表现,也会发现他们可以改进的地方。在这两种情况下,你可以选择说些什么,或者保持沉默。我认为,如果不给予反馈,那就是浪费了一个机会,前提是反馈要以尊重的方式进行,并且目的是帮助对方成长。
给予积极反馈看似简单,毕竟这就是在赞美某人。但是有一些方法可以让反馈更有效:
例如,假设你注意到一个新加入者的pull request缺少单元测试,而指南要求必须有测试。你可以直接指出缺少测试,但更好的策略可能是问:“你考虑过如何测试这个变更吗?”
将其表述为一个问题,给他们机会分享更多背景信息,也可以纠正遗漏。在上述情况下,对方可能会以几种方式回应:
注意这些回应中没有负面情绪。这就是在给予反馈前先提问的好处!
你与接受反馈的人之间的信任越多,你就可以越”直接”,而不会冒犯他们。要根据具体情况判断什么是适当的。别忘了,反馈的目的是帮助对方进步。只要你提供的反馈是鼓励而非打击,你就在帮助他们成长。
善于给予反馈是一个巨大的优势。在这方面对我帮助最大的资源是以下两本书:
与其他工程团队协作的原因有很多,例如:
如果你的工作场所采用内部开源模式,即你可以访问大部分代码并为其创建合并请求,那么当你提出合并请求时,其他团队的工程师可能会阻止你的更改。这通常是因为该团队拥有那部分代码,所以在进行更改之前最好先咨询他们 - 尤其是对于大型团队。
在只有少数几名工程师的小公司里,很容易了解开发人员并找出他们的工作内容。例如,在一个包括你在内只有6名工程师的工作场所,你会知道Bob和Suzy负责后端,Sam和Kate负责网页,Tom负责移动端,所以你知道该向谁询问问题。同样,在一家有5个工程团队的公司:平台和核心主要是后端,而网络核心、客户支持和客户体验则是网页、移动和后端工程师的混合团队。
然而,在拥有十几个以上工程团队的公司,弄清楚哪些团队与你的团队有关系变得很棘手。通常,找出该与谁交谈的最佳指示是查看上次谁修改了相关代码行,然后联系他们。
绘制一张与你的团队相连的工程团队地图,并列出与你的团队有联系的团队。列出:
你的团队使用的基础设施团队,即使是间接使用的
绘制完地图后,向你的同事和管理者展示,看看是否有遗漏。
让与你有联系的工程团队认识你。利用与你自己团队相连的团队地图,至少与每个团队的某个人见面。你可能已经在与其中一些团队合作。如果没有,这里有一个建议:与一位有经验的工程师或团队经理安排一个简短的介绍会议。告诉他们你的目标是更多地了解他们的团队,并给名字一个面孔。如果有相关文档,提前阅读。
在会议上,介绍你自己,简要分享你的团队做什么,并询问对方。他们在那里工作了多长时间,他们在团队中的角色是什么,团队做什么,他们使用哪些技术,以及他们面临的挑战是什么?
介绍性会议的目标是双重的:
通过介绍性会议,你可以了解更多关于另一个工程团队的信息,这总是很有趣的!很有可能你会学到新东西,或者受到启发去尝试他们使用的不同工程方法。
作为高级工程师,你在团队和公司中的”影响力”非常重要。你在一个群体中越受尊重、知名度越高或影响力越大,你的声音就越容易被听到,也就越容易引导事情朝你认为正确的方向发展。
那么,作为一名工程师,如何提高自己的影响力呢?以下是一些方法:
什么是”出色”的工作取决于你所处的环境。确保你的工作在质量和速度之间达到适当的平衡。在初创公司,“出色”可能更偏向于快速交付产品,而在大公司,“出色”可能意味着经过充分测试的整洁代码、易于审核的代码变更,或可维护的解决方案。
了解在你所在的工程组织中什么才算”出色”,并定期从同事和管理者那里获得反馈,以了解你的工作表现如何。当你建立起做出色工作的声誉时,其他人就会信任你。
特别是认识工程组织以外的人。试着抽出时间走出你的工程圈子。与产品人员、设计、数据科学等非工程职能部门的同事,以及业务部门的人交流。
这样做的目的是更好地了解产品方向和业务战略。考虑与你的产品经理定期进行一对一的会面 - 比如每月一次 - 以更好地了解产品部门的工作内容、原因以及你如何提供帮助。
加入与其他团队工程师的电话会议。在分布式环境或远程团队中工作时,很可能大部分工作都是通过电子邮件、聊天、文档和编码完成的。
不要完全保持异步沟通;考虑进行视频通话,与你合作的同事”面对面”交谈。找个借口与你平时异步合作的人聊聊天。在通话过程中,试着更多地了解他们。他们在团队中工作多久了?他们还负责什么其他工作?他们所在的地方发生了什么事?
与人交谈而不仅仅专注于工作有几个好处。首先,你们每个人都能感受到那些邮件和拉取请求背后的人是谁。其次,你会了解到更多关于他们工作方式的背景信息。最后,你可能会通过相似的观点、个人兴趣或其他方面建立意想不到的联系。
参与RFC / 设计文档 / 跨团队规划。如果你的公司使用RFC、设计文档或ADR,开始阅读其他团队的计划,并在你的专业知识可以提供帮助时参与其中。
当我加入Uber时,由于其透明的RFC文化,一个新世界向我敞开了大门。仅仅通过阅读其他团队的RFC,我就学到了很多关于他们工作方式的知识,并通过RFC与团队建立了联系,因为我有相关的专业知识和兴趣可以贡献。你的影响力和人际网络是相互关联的;很少有比通过参与有趣的规划文档、学习新东西并帮助其他工程师更有趣的方式来扩展你的网络了。
参与跨团队项目。如果你只与团队成员合作,那么你的影响力就会局限于你的团队。要与团队以外的人建立信任,就要在扩展你的理解的同时一起工作并建立关系。当你在自己的团队中感到舒适时,寻找机会参与不同工程团队和非工程团队的项目。
我发现,建立人际网络的最佳方式之一是根本不去”社交”。相反,只需专注于解决共同的问题。例如,在Uber,我建立的一些最牢固的联系是通过参与那些需要每天与其他工程师、经理、产品经理或设计师交谈以完成重要工作的项目。
确保你的同事和经理知道你做出了出色的工作。我并不是建议你要咄咄逼人。但是,如果你们有团队会议展示每个人的工作,那为什么不也展示一下你的进展和成果呢?如果你的团队要在更大的会议上做演讲,自愿谈谈你负责的领域。
记录你所做的工作,并时不时地通过我们在”掌控你的职业”一章中介绍的工作日志等格式与你的经理分享。
致力于建立强大的个人品牌。Leonard Welter是Bloomberg的一位产品经理。他观察到工程师们都有”个人品牌”。以下是他的建议:
“‘建立个人品牌’的概念可能被视为一种消极的政治行为,尤其是当它偏向于形式大于内容时。然而,思考你在组织中是如何被看待的很重要。我希望有人能在我职业生涯早期就告诉我关于’品牌’的概念。你的’品牌’是被视为能够完成任务的人吗?还是被认为有强烈意见,但很少亲自动手的人?当涉及到这种品牌时,结果并不是唯一重要的因素。”