..

程序员方法论:以终为始 | 青山随笔

以终为始,就是…以结束作为开始。

前两天在《得到》上听吴军老师讲科技史,其中有一讲提到一个故事。19世纪左右,生活在格陵兰岛上的一群因纽特人,因为部落里的长老去世了,而且因纽特人没有文字,导致狩猎武器的制作技艺失传,最后部落的人口减少了一半。当时听到这,我不禁哑然失笑,我们这些生活在21世纪的程序员,好像也没少听说这种事。一个软件项目,主力程序员走了,留下了一堆口口相传的东西,导致项目维护不动了,最后饿死了一半的程序员,好像很合理的样子。

吴军经常强调记录的重要性,因为在记录的基础之上,人做事的时候才能尽可能避开之前犯过的错误,在一次一次正确的做事过程中获取可叠加式的成功。正好也快放假了,我来践行一下这个观点。这次记录一个我在极客时间上学习到的收获颇丰的专栏《10x程序员工作法》。

标题中“10x”的意思是十倍,意思是,程序员的工作效率或者说能力,是有着数量级级别的差距的,这和吴军老师的观点不谋而合,同时我也是这一观点的忠实拥趸。我在之前的文章里提到,我的短期职业目标是成为一个合格的“五级工程师”,那么根据吴军老师的理论,五级工程师和更高一级的四级工程师之间,也是有着数量级的差距的。

这个专栏就是给大家分享一些程序员工作的方法论,具体的知识学习的途径很多,但这种软技能可不是随处都能查得到的,更常见的方式是身边的资历更深的同事对你的言传身教,但把握这种机会的难度,显然比买个专栏难上不少。对知识付费平台的看法,回头有机会再写个文章吧。

下面是笔记和总结。因为专栏刚更完第一模块“以终为始”,但是这个模块就给我带来太多收获了,有必要阶段性总结一下,这不是系统性的总结,我只会记录一些对我有用的部分。

就如同我这些年下来不遗余力地向大家推荐《浪潮之巅》这本书一样,我觉得这个专栏,值得所有程序员,至少是像我一样刚入门的程序员学习一下。也许,人家说的不一定是对的,但总好过“不知道自己不知道”。我翻过愚昧之巅了吗?也许还没有,所以更需要打开眼界。

  1. 面对产品需求的4个思考原则 为什么要做这个特性,它会给用户带来怎样的价值? 什么样的用户会用到这个特性,他们在什么场景下使用,又会怎么使用? 为了达成这个目的,有没有其他办法?(是不是可以不做?) 特性上线以后,怎么衡量有效性? 当程序员面对产品经理时,有必要让产品经理给出以上问题的答案。

“我觉得”、“应该”,这种决策依据最终会伤害所有人。

  1. 上面原则的抽象总结 以终为始 任务分解 沟通反馈 自动化
  2. 事物的两次创造 任何事物都要经过两次创造,一次是在头脑中的创造,然后才是付诸实践的实际构造。

在工作中遇到的很多问题,源于第一次创造就没创造好,导致第二次创造时实际上已经走入了歧途。

以终为始:先考虑结果,根据结果来确定要做什么事情。

亚马逊的产品开发步骤:

写新闻稿; 写FAQ 写用户文档 写代码 这就是一种以终为始的方法。我写出的代码,真的是对客户有价值的代码吗?真的是对产品的商业价值有提升的代码吗?这些劳动成果的半衰期能有多长?是一周之内就烟消云散了,还是能长达数年?

总之,遇到事情,倒着想。

  1. DoD: 对完成的定义 也就是验收标准。程序员在接下来产品经理的功能需求前,双方应先约定好验收标准到底是什么。比如,要有什么功能?单元测试写不写?写不写文档?

用户故事是一种很好的确定DoD的方式,因为用户故事一定是站在使用者的视角,对这个功能需求的一种定义,是结果导向的,如果按照用户故事来验收一个模块,至少不会和PM的预期偏差太多。

  1. 验收 刚才提到了用户故事。用户故事真的是一个很好的方法,我在公司的Jira里很早就看过“User Story”这个词,但是一直也不太明白到底什么是用户故事,为什么在软件开发的过程中还能存在“故事”,而专栏中的文章给我讲的很清楚,你看这就是专栏的价值。

验收一个功能时,除了按照用户故事验证,也需要验证异常的情况。

总之,对需求理解的偏差是软件开发中一个再常见不过的事情了,为了避免这种情况的发生,我们可以在还没开始写代码之前,就把这个需求的验收标准明确下来,除了用户故事外,验收也应当关注异常流程(对于我们部门来说是测试做这部分工作)。

总之,在做任何需求或任务前,先定好验收标准。如果给我布置任务的人没明确说验收标准,我会追着明确,如果我给别人布置任务时没说明验收标准,那验收时效果如果不满意,那就是我自己的责任。

  1. 面对不靠谱的产品经理.. 估计是作者的血泪教训。

总而言之:默认所有的需求都不做,知道弄清楚为什么要做这件事。

我是一个特别爱问这种问题的程序员,幸好,我的leader对这种问题非常宽容。

  1. 扩大自己的工作上下文 也就是不把自己的角色限定在“程序员”这个角色里。

我觉得我从参加工作的第一天就很好地践行着这个原则,直到今天。但是,显然地,写代码是半衰期长的多的工作。不是说客户支持、产品化、运维工作没有价值,而是对我来说,我写代码能给公司创造更大的价值。

  1. 做事前先进行推演 emm,说到推演,我前两天刚有一个教训。我当时是去客户那边升级一台设备,升级的时候我应当在后台手动备份一些配置文件。一般情况下,我做这种运维操作之前,都会先在脑子里把整体流程过一遍,但是那天可能是我没吃早饭,也可能就是我犯懒了,总之就没细想这事。果然挖了个坑,因为遗漏了一步操作,把自己备份了一半的文件给覆盖了。虽然也没什么损失,但确实多耽误了我20分钟的时间。

总之,动手做一件事情之前,先推演一番。

  1. 你的工作可以用数字衡量吗? 用数字衡量的意思,类似于面对产品需求时的一个思考原则,“特性上线后,怎么衡量有效性?”。

也就是说,我的工作产出,有没有什么量化的指标能用于评估产出的效果?

常见错误范例:增加了这个特性【可能】会让用户增长,做了这个调整【应该】会让系统的压力变小。

软件系统是复杂的,当一个系统复杂到一定程度时,人的感觉是不可信的。

一个程序员吵来吵去,觉得来觉得去,谁也没法说服谁,这时候就需要一些东西。也许是实验数据,也许是实践经验,也许是一个验证方案。总之,总得有点依据。

也许对我来说,如果我的工作内容,能让我们产品的平均无故障时间增长百分之x,让平均故障时长下降百分之y,那这就是我工作成果价值的衡量。

让我最有收获的差不多就是上面这几点,有两三讲我没贴出其中的内容,因为我看不太懂,或者没什么感触。

程序员嘛,解决工程问题。我以前是这样想的,如何衡量一个程序员的价值呢?看他代码产出的质量与效率。现在结合这个专栏的学习,我有了一个进一步的认识,那就是代码产出的价值,得看这个产出和产品最终的价值是否契合。一种常见的情况是,产品的价值就是在商业上获得价值,而商业价值的关键在于用户的认可。那么,当我在设计一个模块,或者写一段代码前,我应当想一想,这些工作内容究竟能否给用户带来价值?

我觉得可以这么说,在绝大多数情况下,只要代码的质量和效率都没问题,那这堆代码就是具有技术价值的。但是具有技术价值的代码,真的能代表产品价值或者商业价值吗?不一定。我曾经写过一些自认为非常牛逼的代码,但是对产品基本没什么卵用(a.k.a. 用户不买账);我也曾写过一些对产品的商业价值非常关键的代码,但当时并没有这么觉得。也许我在这些模块上付出的劳动是什么差别的,但是从客观的角度来看,价值差别巨大,也许能达到数量级的差别,也就是10x的差别。

如何避免自己的劳动产生不了价值呢,如何让自己尽可能走在创造价值的路上呢?以终为始的思考方式,也许是解答这个问题的一个法宝。我现在只是刚刚学习到这个观点,结合自己的工作经验有了一些感悟,但想把以终为始的方法论真正内化到自己日常的工作中,我想还需要时间去刻意练习。

说到刻意练习,其实弹钢琴就是一个刻意练习的过程,小时候不懂这个。我家楼下有小孩练琴,感觉弹的挺流畅,为他感到高兴。

2019年01月29日