如何成为一名靠谱的程序员:职业素养入门指南

371次阅读  |  发布于11月以前

导读

本文基于我十多年程序员生涯观察,落笔始于 2019 年学习怎么带领团队新人时,在此之前我一直在想,如果当年有人告诉我这些道理,我是不是可以发展得更好,也少一些纠结。本文不是如何成为编程高手的秘籍,也不是介绍如何在职场中为人处世,更不是告诉你怎么成为优秀的程序员,本文只介绍如何处理好工作中的细枝末节,帮助你树立专业的、靠谱的程序员“人设”,是一篇程序员职业素养的《新人须知手册》。友情提醒,长文干货,提前收藏码住!文末还有龙年红包福利!目录

  1. 不靠谱程序员案例
  2. 你的目标
  3. 计划与执行
  4. 需求讨论
  5. 编写代码
  6. 代码评审
  7. 文档编写

01 不靠谱程序员案例

1.1 虚假的交付

十多年前,我们在做一款播放器软件,两周一个迭代对外发布新版本,开发的排期由技术负责人把控,时间压得很紧。某位刚加入没多久的新同事承接了几个富文本窗口的开发,他在承接需求之前并没有彻底地熟悉代码,他也不是经验丰富的开发者,deadline 将近,他把这些需求都从开发中挪到了测试中,交给测试做验收。后面测试同事发现了很多低级的 bug,甚至是有些功能没有实现,这位开发同事,连自测都没做,当然大家也没有去追究他写出太多有 bug 的代码,测试同事也例行地提 bug 单,等待修复后做回归测试。

现在仍然可以看到部分同事在降低完成标准,为了赶在 deadline 之前完成,他把完成定义为代码开发完成,而不是服务发版本或者 App 上线。

1.2 随意的承诺

五六年前,我们在做一款搜索产品,有一段时间要把视频内容也加到搜索结果里,有一位同事抽调去负责这块业务的后台实现,项目两周一个迭代,每次需求排期由开发者给时间计划,但产品同事总是期望能更快地上线,于是需求排期经常变成时间倒排排期,这位同事很愿意看到产品变好,也很有激情,每次都答应了,而为了达成目标,他经常早上 9 点半上班,晚上 10 点半下班,周末也经常加班,即便如此,还是经常因为 bug 众多而导致上线延期或者线上业务出事故,考核的时候也拿了一个较低的绩效。

1.3 推卸责任式的通知

几年前,我们使用的存储介质要做合并降本,A 存储实例的调用需要切换到 B 存储实例,负责切换的同事在一个沟通群里同步了切换时间,然后在时间到的时候将实例缩容下线,但下线的时候还有很多调用者并没有切换走,这导致了业务事故,切换同事说这不是我导致的,我已经通知了,被影响的使用者说我没有收到通知。

协作中,我们把工作传给下一位负责人时,需要确保他接住了工作,而不是把工作丢出去,不管对方有没有接到。

1.4 组织浪费多人时间的会议

某位同事组织了一场会议用来讨论某个大方向的一系列需求,有前端的、后台工程的、后台策略的,把大家都邀请到了会议室,在聊到某个需求的时候,他和后台开发在会议上讨论需求的合理性,聊了一个多小时,而其他人都在边上无聊的刷手机。

1.5 重要事故不向上反馈

某天我们负责的关键服务突然出现故障,导致线上部分请求无法正常返回结果,负责值班的同事收到告警后马上投入处理,过去了几个小时,一直无法解决,产品同事也在体验时发现了业务故障,马上通知到产品负责人和技术负责人,技术负责人立刻电话值班的同事了解情况,此时才知道故障已经发生了几个小时,马上组织更多的人力做排查处理。

1.6 延期不提前预警

我们团队对客户承诺要投入 30 人日,在 1 月 10 号交付某个复杂的大功能,到了 1 月 9 号的时候,做开发的同事向项目管理同事反馈 1 月 10 号完成不了,预计需要延期到 1 月 30 号。

1.7 遗漏工作和疏忽大意

我们有一个服务业务团队的老系统要下线,项目负责人安排小 A 负责推进业务团队做迁移改造。 周一:

负责人:你本周的工作计划遗漏老系统下线,需要跟进下。

小 A:我和业务团队的开发小 B 沟通了,他说要问一下他们的领导,我们后面继续跟进。

负责人:小 B 有说什么时候能给答复吗?

小 A:小 B 好像有紧急告警在处理,他说本周会问他们的领导,我这周晚点再问。

负责人:不急,但需要有明确的时间节奏。

周三:

负责人:时间点有了吗?

小 A:还没,我问问。

(数小时之后)

小 A: 小 B 说本周五才能和他的领导对齐改造节奏。

(这次沟通完,中间过了一个假期,然后小 A 把这件事情忘记了,直到一周之后)一周之后:

负责人:没看到结论反馈,这里的进展怎么样?

小 A:(丢出一个文档)这里有排期,他们会做迁移。

负责人:符合我们预期吗?

小 A:他们把流量迁移完,我们的老服务就可以下线,符合预期,6 月中旬完成。

(负责人看完文档之后)

负责人:“无其他业务需求时做支持,预计 6 月中旬完成”,整个承诺还带有附属条件,我们不能认为他们一定会在 6 月中完成业务迁移,应该要和他们再次确认,给出可以完成的时间点。

这里例子中,小 A 有几个问题:

类似的例子还有很多,我们总是会不经意地掉入各种坑里,不经意地促成某个不靠谱的结果,怎么避开陷阱,建设一个高效可依赖的个人品牌,是本文的核心目标。

02 你的目标

作为组织的一员,我们的第一个评估指标必然是组织目标的完成情况,如果没有合适的目标,完成更无从谈起。靠谱的程序员,每周在做工作计划的时候,都要问自己一句,我的目标是什么,我在完成我的目标吗?如果不明确,应该和你的领导聊聊。

03 计划与执行

很多年前我在一个小型 feature team 做一款新产品的时候,隔壁小组的小 A 每周都很忙碌,其他人晚上 9 点下班,他经常要忙到 11 点,不止是两周一个迭代的需求很多,还因为今天修改需求 1,明天插入需求 2,为了产品能快速占领市场,他觉得都能做,至于技术基建改造,通通往后排,毕竟业务需求更重要。需求堆积越来越多,bug 也越来越多,迭代也越来越慢,基建优化更是从来都排不上时间,怎么办呢,只能更疯狂地加班,但效果并没有更好,需求不断地延期,线上 case 频发,直到他转岗。

这个故事暴露出来很多问题,譬如,产品经理应该想清楚需求,不要临时修改;项目管理应该守住两周一个迭代的规则,提高需求变更的成本;小 A 的领导应该帮助小 A 拦住突发需求,或者安排更多的人力支持;小 A 应该拒绝插入需求,给技术基建改造预留时间。这里我们聚焦在小 A 个人身上,他应该怎么办?他应该说“不”,那他怎么有底气说“不”,底气不是蛮横的拒绝,而是来自有理有据的规划分析,这就是计划与执行复盘。

制定计划并做执行复盘,是我多年来的工作习惯,很多人也会这么做,每周一开始工作之前,制定本周 40 小时的工作计划,为每一项工作安排若干小时,并在本周结束的时候复盘时间的实际投入情况,吸取经验时间预估的教训。经过长期的<计划-复盘>训练,你在预估工作耗时会更有经验,同时,因为你做计划时的深思熟虑,会让你在拒绝插入工作时,更有底气。

最近几年,我带领的团队都采用周计划和执行复盘的模式做自我时间管理。我们也知道,信息透明能让团队更有战斗力,我们团队每一个人的本周工作计划都写在公开的 iwiki(腾讯内部文档沉淀系统)上。

04 需求讨论

这些年互联网公司的研发流程已演进得非常的规范。早些年的各种段子,日常中很少碰到,譬如:

  1. 这个需求很简单,怎么实现我不管

  2. 需求明细我没有,你照着竞品抄

  3. 你先开始写代码,需求单我后面给你补

  4. 写了一半的需求,又改了!...

这些案例几乎绝迹。如果你日常中碰到了这些段子,建议和做项目管理同事(也可能是团队领导)聊聊,把项目流程定下来。还有一种例外情况,你们的小团队正关在一间小屋子里封闭开发做 MVP(最小化可实行产品),此时第一要务是造出产品样例,变化是常态,倒也不必追求标准的研发流程。

在开始写代码之前,通常会有一个需求讨论,这里有四点需要重点关注:讨论前的准备、理解需求的本意、确认和对齐、评估工作量。

4.1 讨论前的准备

我们会要求讨论之前必须先有需求讨论稿,并且讨论稿要提前一天发出给大家做文字评审,缩短会议时间,这对参会者提出了较高的要求,也可以剔除掉非必要的参会者,以及让发起讨论的人能先理清逻辑。如果要讨论一个业务需求,但业务负责人却不能把要做的事情有逻辑地写清楚,那么说明他自己也没想清楚,此时不应该发起和开发者的讨论。如果团队里经常做无稿的需求讨论,靠谱的程序员应该抵制并提出抗议。总之,靠谱的程序员会在会议之前先阅读讨论稿并给出必要的评论。

4.2 理解需求的本意

靠谱的程序员,不是需求的被动承接者,他们会从产品的本质去思考问题,会仔细想对方的需求是否合理,是否考虑周全,他是需要一匹更快的马,还是更快到达目的地的交通工具?如果是更快的马,那么我们应该挖掘更好的马,但如果是更快地到达目的地,我们应该发明汽车。

我曾经遇到一个需求,合作的业务团队给我们反馈,说我们的离线计算任务太慢了,应该加速一下,仔细聊下来,发现他们的诉求是数据干预生效太慢,因为当前数据干预依赖离线计算任务,所以他才提出要让离线计算任务做得更快,这个需求后面我们通过让数据干预不依赖离线计算任务,单独走一条数据流解决,实现思路上更合理,效果也更好。总之,靠谱的程序员热爱思考会挖掘需求背后的原因,给出更好的解决方案。

4.3 确认和对齐

有时候我们会经历一场激烈的辩论,辩论到最后大伙都精疲力尽,期望能早点结束,终于开发和产品,上游和下游达成一致,会议结束,大家终于可以去吃饭。等到了联调或者是验收的时候,却发现 A 说达成的方案是这样,B 说达成的方案是那样。

为了避免这样的情况发生,我们讨论达成的结论,务必“白纸黑字”写到需求稿中。一方面是文字表达比口头表达更容易避免漏洞;另一方面是需要参与讨论者确认,避免事后不认账。

4.4 评估工作量

我们通常在会议的结尾会被要求给出工时和排期,如果你之前已经做过很详细的分析工作,此时可以直接给出,但如果不是,建议仔细拆解需求后再给出。工时预估其实是一种猜测,而合作者们会把这个猜测当成你做出的承诺,能不能做到“承诺必达”,这是一个关乎你个人品牌的大事。

虽然过去的工作经验可以参考,但我们从来不会遇到一模一样的需求,我们能做的就是把影响因素考虑得更详细一些,为可能有风险的地方多预留一些时间。

某个数据接入的需求估 2 天工时,是这么考虑的:

  1. 数据来自另一个团队,他们需要开发新接口把数据传给我,这里涉及到协议定制、代码开发、双方联调;我们可以先把协议对齐,然后两边用假数据并行开发,最后约定一个联调时间;这里预估 4 小时用来沟通协议和开发数据接入代码,4 小时用来联调接口;

  2. 数据使用者要求对数据做简单的变换处理,譬如:把标题和内容拼到一起、给文档 id 加一个前缀,这部分需要在数据处理插件工厂里写一个处理插件,代码比较简单,预估 2 小时开发,4 小时代码评审;

  3. 数据处理完后需要发送到消息中间件,供使用者订阅,我们有现成的配置化插件,只需要在业务 meta 配置里添加一段描述即可,预留 1 小时做配置;

  4. 上线,我们有成熟的持续发布(CD)流程,预留 1 小时;

我们把事项拆到小时粒度,同时为有外部依赖的事项预留较长的时间,看起来很合理。但即便如此,我们仍然有可能出现意外,譬如:

  1. 合作方采用一种我们从没用过的新协议,调研新技术用了 2 天;

  2. 虽然只有几十行代码,但是代码质量很差,导师给我做了三轮代码评审才通过,用了 1 天;

  3. 需要写数据说明文档,详细描述数据有哪些字段,以方便众多使用者,用了 0.5 天;

看到了吧,一个看起来很简单的小需求,我们考虑了很多细节(但不是所有细节),仍然有可能出现遗漏,所以一定要给自己足够的时间去全盘的拆解问题。有几点经验之谈:

  1. 把大需求拆小,小到能以小时预估,拆小可以看得更透彻;

  2. 一天以 8 小时或者 6 小时算工作时间,不要算上你的加班时间;

  3. 不要在一段时间内并行做 N 个需求,需求之间切换有损耗,容易预估不准;

  4. 预留 buffer 时间,可以是在你预估的时间上,再乘上一个系数,系数可能是 2 也可能是 1.3,你通过<计划-执行>来得到你的系数;

讲了很多工时预估过短的风险,你可能会有取巧的想法:那我就预估得长一些,譬如,改一行代码预估一周工时。这很难做到,技术管理者会关注工作安排的合理性,这伎俩很快就会被发现,而且在一个实干的团队里,这种做法会被其他正直的同事排斥。

总之,靠谱的程序员不会随便给出承诺,给出了承诺就一定会做到,他们会仔细地做需求评估,避免让自己陷入困境,但总有意外,也许需要每天工作 12 个小时,也许需要节假日都加班,但这都不重要,因为靠谱的程序员承诺必达。

05 编写代码

5.1 编码之前

在写代码之前,应先熟悉团队的研发流程,譬如,有些团队要求先通过代码规范和安全考试,否则代码无法合入仓库主干。大多数团队也会有从研发到版本上线的全套 CICD(持续集成持续发布)流程。还有,要看看团队给大家推荐的研发工具,至少会包括代码规范配套的自动格式化工具。

5.2 注意事项

在编码之前你做了充足的准备,实际写好代码,还有一些规则需要遵守。

(1)大范围的修改需要多周知

原则上,我们将代码拆分得足够细,减少大范围的修改代码。但有时候大范围修改不可避免,譬如代码大重构,这种修改量很大,需要周知其他同事后,选择合适的时间,避免出现大量 merge 冲突。

(2)在需求开发中逐步重构

一个函数原来只有一个小功能,后来逐步的增加功能,变成了一个有若干个功能的 100+ 行大函数,当你又做一个新的需求,需要改动到这个函数时,必须对这个函数进行拆分。这样做带来几个好处:1. 后来开发者(可能也是你)可以更快地增加功能,保持敏捷; 2. 代码结构更清晰,不容易隐藏 bug;

(3)写好单元测试

很多开发者不愿在需求开发中逐步重构,很大的原因是怕改出问题,而单元测试可以让你修改代码时更安全。写好单元测试也可以帮助开发者提早发现 bug,避免 bug 在代码评审、上线后才发现,bug 数永远不可能等于零,但靠谱的开发者会想办法让它无限接近零。 失误率永远不可能等于零,但你有责任让它无限接近零。——《程序员的职业素养》。

(4)代码里的 TODO

我们经常会在代码中看到躺了几个月、几年的 TODO,建议不要轻易地写 TODO,如果一定要写,请给它定一个期限。写之前问自己一句,我真的会安排时间来修改吗?很多时候,我们只是求个心理安慰,今天不去完成它,以后也不太可能会来修改,垃圾会慢慢堆积,直到不可收拾。 如果你说有空闲时间才去做,意味着你可能永远都不会做。——《程序员修炼之道-通向务实的最高境界》

(5)持续的练习

写代码是一项专业技能,它需要学习才能获得,初级程序员经过一段时间的练习才能上岗,并且行业在持续的演进,为了跟上趋势,为了更娴熟,靠谱的程序员还需要不断训练,就好像赛场上的运动员,最优秀的运动员除了天赋,勤勉更不可少。 做练习是很多程序员容易忽略的点,他们更喜欢在实际工作项目中尝试新的编程语法,而不是提前做几个练习,相比因循守旧不敢使用新语法的伙伴,他们算是不错了,但还可以做得更好。譬如,安排一些做练习的时间,提升自己的技能,这和工作无关,纯粹是在磨练自己的编程技艺,靠谱的程序员会更负责的对待自己的职业生涯。

06 代码评审

代码评审是建设个人品牌的好时机,并且这样的机会非常多。其他人会看到你的代码,然后在心里给你打上一些标签:质量很好几乎看不出来问题;很一般,还需要继续提升;太粗心了,有很多低级错误;乱七八糟,都写的啥,浪费时间......

靠谱的程序员会很重视代码评审,避免给他人造成麻烦,也避免损害自己的品牌形象。通常会严格执行团队里“CR 前的 checklist”规范,直到自己不能发现错误,才把代码评审单发给评审人。在评审过程中,也会注意和评审人沟通,而不是一味的接受或者一味的反驳。

刚开始接受代码评审的人,可能会有抵触心理,他们把代码视作自己,把对代码的批评视作对自己的批评,因而无法客观的对待,容易陷入无意义的辩论,靠谱的程序员会感谢指出代码错误的人,而不是抵触。

如果你指出他人的代码不合理,他却对你“咆哮”,建议在组织层面寻求共识,这样的事情在鹅厂也并不少见。

07 文档编写

写技术文档是开发者的义务,它和写可读代码一样重要,它也可以体现个人做事态度、逻辑思考能力。

7.1 核心原则

文档是给人阅读的,因此第一要务是面向读者,让读者高效地获得信息,这是文档写作的核心原则。为达成这个目标,通常会有一些关键词,譬如:准确、完整、简洁。

(1)准确文档里不应该出现错误的信息,譬如,在一个申请上线的评审文档里,把收入增长数据写错了,这会误导读者。 (2)完整文档的信息需要完整,譬如,写一个算法性能评测文档,但却没有给出评测是在什么设备上做的,采用了什么数据。 (3)简洁文档内容应该聚焦在主题上,避免发散,避免主次不分,不同类型的文档有不同的风格。譬如:

固定的文档格式,可以让我们文档的样式看起来有模有样,但这还不够,还应该注意一些基础写作常识,以及精简意识。譬如:

反例:

上述的反例违背多个写作常识:随意分段、前后不连贯、文字拖沓啰嗦。 修正:

7.2 规范和培训

团队通常会有一些文档写作规范,譬如我们团队有《技术文档编写建议》,通常也会有一些培训,譬如 PCG 有“知行”课程《像管理代码一样管理技术文档》,建议充分阅读。

本文是《如何成为一名靠谱的程序员》系列文章的上篇,在下篇文章中,我们将聚焦沟通协作、独立思考以及推荐阅读的书籍。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8