Fish and Shark

I have been through the "Fish vs Shark" dilemma a number of times before. It was like:

The team has a product/tool/service/system called "Fish". Fish works, but has shown a lot of signs of aging. And the team/company/business/people have almost outgrown the Fish. So the team started to build the Shark.

Building Shark and helping users to migrate to Shark takes time, and takes resources from that team who owns Fish and Shark.

The team now struggles: Fish is getting worse, and the users are increasingly unhappy with Fish. Plus, knowing Shark is coming, themselves and the users are more hesitant to invest in Fish. That only makes things deteriorate even faster in Fish. Meanwhile, Shark isn't there yet.

The dilemma is: how much time should the team spend on Fish? Double down on Shark? It's risky. If Shark delays for some reason (including those out of the team’s control), they are dead in the water: Fish is so broken, while Shark isn't there yet.

Should the team carve out some time to keep Fish floating? In both Chinese and English there is the phrase “a bird in the hand is worth two in the bush”. That will keep business going and buy some time for Shark, but that will probably delay Shark.

That’s really a hard decision to make. We surely can look at the data: How close is Shark? How much effort does it take to keep Fish float?

But how "floating" is enough "floating"? How long can users bear with "just floating"? How much confidence you have to get Shark ready on time? At the end of the day, it might still rely on some judgement and gut-feeling.

给老板点赞

有一次在我们项目的Slack频道里,在一件大家争议很大的事情上,我发现我的思路和我老板的思路出奇的一致。我当时犹豫了一下,要不要在我老板的那句话下面加个点赞。我犹豫下来的决定是:我没有点赞。

以前有一次,我是老板。也是一件大家意见很不一致的事情。那次,我下面有几个人就公开站我,结果他们被其他人炮轰,说他们是拍老板马屁。我也连带的被喷了,说我就是古代的昏君,让自己 surrounded by 佞臣。所以我后来明白了,为什么老板都很少发表自己的观点。

拍老板马屁,在以前古代,叫佞臣。古代的官儿们很喜欢给其他官儿扣一顶“佞臣”的帽子。大家的风气是觉得跟皇帝对着干是刚直不阿,支持皇帝的想法是拍马屁、是佞臣。我觉得皇帝心里也很苦闷啊。大家都怕被扣佞臣的帽子,搞得懂自己、支持自己的想法的官儿都不敢说话,皇帝多孤独啊。下次遇到有大臣站自己,皇帝还要担心他们会不会被扣上佞臣的帽子。

大家这么防着佞臣,是要防止有人就是通过拍老板马屁来捞好处,要防止皇帝被马屁精包围了,这样皇帝就不能兼听了,皇帝就不能看到自己的不足。这不是最近大家都在批某大,说许某印就是被马屁精包围了。

At the risk of being overly confident,我觉得我是能分辨清楚我手下谁是 yes-sayer、谁是真正的思路一致的人的。子曰,君子不以言举人。主要就是看行动,看他们做的事情。不过也有很多人会就盯着老板关心的事情做。这样的风气要是不刹住,就没人do the right things和那些看不见的脏活了。而且,从逻辑上来说,可能虽然我觉得我能分辨马屁精,但我实际上还是会被骗。就好像觉得自己不会被金融诈骗的人,还是会被金融诈骗。

但反过来想想,有时候,让自己的手下觉得自己很容易骗,其实不是件坏事。哈哈。

归因难,难于上青天

2021年诺贝尔经济学奖的获奖理由是“因为他们对因果关系分析的方法论贡献”。很多人觉得这个奖给的很水。我觉得一点都不水。因为归因太难了。

那几年,多少次半夜醒来(figuratively speaking),脑子里挥之不去的就是那些问题:你怎么证明这个结果是你做的这些事情的结果?你怎么证明你不做这个事情就没有这个结果了?今天有这个结果,原因很多,你做的这个事情在里面贡献了多少?你怎么量化你做的这个事情的效果?

代码覆盖率从80%提升到90%,效果是什么?节省了多少研发时间?人均每天代码行数因此提升了多少?提升了多少研发幸福感?迭代交付周期因此缩短了多少?需求吞吐量因此提升了多少?对业务增长的贡献是多少?千行代码缺陷率因此下降了多少?降低了多少个P1P2故障?服务可用率提升了多少?资损故障因此下降了多少?

CI通过率从90%提升到99%,效果是什么?节省了多少研发时间?人均每天代码行数因此提升了多少?提升了多少研发幸福感?迭代交付周期因此缩短了多少?需求吞吐量因此提升了多少?对业务增长的贡献是多少?千行代码缺陷率因此下降了多少?降低了多少个P1P2故障?服务可用率提升了多少?资损故障因此下降了多少?

主干开发,效果是什么?节省了多少研发时间?人均每天代码行数因此提升了多少?提升了多少研发幸福感?迭代交付周期因此缩短了多少?需求吞吐量因此提升了多少?对业务增长的贡献是多少?

做code review,效果是什么?对业务增长的贡献是多少?千行代码缺陷率因此下降了多少?降低了多少个P1P2故障?服务可用率提升了多少?资损故障因此下降了多少?

今年故障下降了70%,和你做的这些事情有多少关系?你怎么证明?为什么不是因为我们的工程师能力提升了?为什么不是因为我们做了很多架构治理?为什么不是因为今年立项抓得严了?为什么不是因为公司今年更加重视了?为什么不是因为今年比去年少了很多大型重构?

我们做事情都是要讲投入产出比的。你说的这些事情,都是对的。但是要看投入产出比,我们没有无限的资源。你没办法量化度量你这些事情的效果,你怎么衡量这些事情的投入产出比?

你证明不了你做的事情和结果的关系,那凭什么给你好的绩效?你做的事情和结果的关系,是你自己要证明的。你证明不了,那怪不了别人。你证明不了,就算拿到结果了,也是碰运气的,不是可以复制的结果。

所以我觉得2021年诺贝尔经济学奖一点都不水。每一个被“你怎么证明这个结果是因为你做的这个事情”这类问题反复折磨过的人都知道,归因非常难,非常难,非常难。

直道超车

最近几天都在修case。其实不是我的case。都是其他那些team的。自己不看,总是怪infrastructure。那只好我自己来了。

好像中国和美国的程序员都是类似的:自己的用例失败了,总是不会先从自己身上找原因,总是先blame infrastructure。总是要别人一而再再而三的把铁一样的证据放在他们面前了,他们才会承认是自己的用例有问题。

承认了自己用例有问题还要继续找借口:哎呀,你们这个工具不好用啊,排查起来很辛苦;哎呀,你们这个工具不好用呀,我要单独跑一下用例很辛苦;哎呀,你们这个工具不好用呀,能不能把失败的用例给自动重跑一下呀;哎呀,你们这个工具不好用呀,能不能智能一点,做一下智能分类、智能诊断。就是不肯乖乖的把自己的case修修好。

要不说姜还是老的辣。今天修的这个case,那几个兄弟之前都挣扎过了,都挣扎不出。我从中午开始看的,看啊看,看啊看,都是从来没看过的代码。看到晚上,被我灵光一现看出来毛病了:有个地方把now()转成“US_EASTERN”时区的时间。当时就觉得这个地方很fishy。

Fishy 在字典里的意思是 arousing feelings of doubt or suspicion,翻成中文就是:这里看着很可疑,这个地方感觉怪怪的,这里感觉不太对劲。

这不有个故事吗。说有台机器坏了,谁都搞不定。最后请了个老师傅来。老师傅看了看,把一个螺丝拧紧了,机器就好了。老师傅收了1000块钱,人家嫌贵。老师傅说,拧一个螺丝只要10块,但剩下990块是知道拧哪个螺丝。

老程序员就是值这个钱。改一行代码看上去很简单,只值10块钱。但能看出来要改哪一行代码,就凭这个,老程序员的工资就比新兵蛋子高。

写这个“US_EASTERN”的估计也是一个新手,没吃过timezone的苦头的,顺手就写了。他这一顺手,后面好几个人好几天时间就没有了。要是再到线上出问题,或者等到屎山已经很高了再搞技改,那就是动辄几百人日的代价了。

“US_EASTERN”的问题就是:每天有一个小时的时间,当“US_EASTERN”还是10月19日的时候,真正的纽约当地时间已经是10月20日了。就差这一天。每天这一个小时里面这个case必败。大家之前看不出一个头绪,看不出什么pattern,原因之一也是之前败的并不频繁。这是不是从另一个侧面也说明,我司在西海岸的同学们到晚上九点提代码的人就不多了。

这两天还修了一个很有趣的case。有个case,偶尔会败。这个case其实没干啥,就是在本地的DynamoDB里面插好多条假user,然后再读出来,看看对不对。但有时候在PutItem的时候会报错,报“Cannot do operations on a non-existent table”。好几个人看了,看不明白,没头绪。

那天我看了一会儿,也没看出来为啥。但我就看到一个地方很fishy:这个用例,用一个for循环插数据,for循环循环了1000次。我看到那里的时候就眉头一皱:有必要吗?

我就去问这个用例的原作者。还好这个用例还算新,八月底加的,作者还在。作者说,其实1000就是随便放的一个数字,到底是 100还是1000,对这个用例来说并没所谓。我说,那要不我帮你改成100吧。因为这个case时间太长了,现在要跑八九秒钟。我改成100,估计不到1秒就跑完了。他说可。

于是我就路见不平的改了。把循环1000次改成了100次。然后我发现,改完以后,这个用例不flaky了,“Cannot do operations on a non-existent table”彻底消失了。敢情这背后的原因就是循环太多了哇,把本地DynamoDB给压坏了。

那个作者还算心思缜密,还问我,这是不是意味着在线上也会有性能问题。我说,也许吧。也许只是本地DynamoDB比较搓,云上的可能就没这个问题了。你要是实在不放心,去云上直接测一测。总之,就别在CI里面跑压测了。

用例不稳定,基本上每个公司都有这个问题。很多人都想走捷径,老是把“弯道超车”挂在嘴上,想搞个什么大招可以一下搞定,或者想另辟蹊径,绕开这个问题,或者搞个自动重跑什么的先对付着。其实,用例不稳定的问题,只有一条路:好好写代码。不稳定的用例好好分析,好好修,修了就修修好,不要东加一个sleep西加一个retry的糊弄过去。

这就和减肥是一样道理。不想改变不健康的饮食习惯,但还想减肥,那是不可能的。局部减脂,不存在的。代餐,都是智商税。减肥的办法,就是做正确但艰难的事。

美国互联网黑话

昨天写了一篇design spec,关于code ownership的。文档上来就引用米尔顿·弗里德曼的话,在design spec里可以算是逼格非常高的了。

文档是从上周就开始写的,昨天写完的。写了足足有18页。我也很惊讶,居然写了那么多。本来以为四五页就差不多了。Code ownership这个事情说起来其实很简单,一句话就能讲清楚:加一个OWNERS文件。

咋就把一句话变成了18页了呢?这不是要”starting from first principles”嘛。国内互联网也有类似的说法,叫做“你的底层逻辑是什么”。这两年阿里被黑的厉害,其中就包括阿里的人用的那些互联网黑话,像什么“抓手“、”赋能“、”闭环“,还有“底层逻辑”也是。

其实黑话这个事情,东西方都一样。美国也有互联网黑话。比如,刚工作那几年,有一个词我每次听到都想吐:synergy。美国的黑话也在不断进化,这两年synergy听到的少了,有些新的黑话涌现出来,比如我回国前还很少听到有人讲first principles,这次回来后好像用的人多起来了。

因为要“starting from first principles”,所以把一句话就能讲完的事情写了18页。有段时间没写那么长的文档了。上一次是写了一份九十几页ppt的新财年规划。那也是被杠精逼的。不管你怎么写,他们总是能给你挑出点毛病来。

我谈目标,他说你这个没有落地过程。我谈要做什么,他说你没有推导过程。我谈why,他说你能不能告诉我们要做什么。我谈远大的目标,他说你太理想化。我谈具体目标,他说你留白不够。我谈重点, 他说你不全面。我谈全面了,他说你要抓重点,就讲top 3。我谈原则,他说你不要一刀切。我谈原理,他说你不要老是讲概念。我谈抓手,他说你这些是单点,没有体系化。我谈体系,他说你不要讲大道理。我谈最佳实践,他说那套东西在这里未必适用。

没办法,为了堵住杠精的嘴,只能都写上,于是就变成九十几页ppt了。可谁能想到,我把所有东西都谈了,他说你怎么ppt那么多页。

山上最好的草坪

前几天看到鹿叔叔他们家的草坪。真心的漂亮。又绿又厚,而且草坪上有那种均匀整齐的一条条的纹路。我知道那是割草的时候割出来的,而且需要一定的手法,才能割出那样的纹路来。以前我们家住在Education Hill的时候,我也一直想在我们家前院的草坪上割出这种花纹来。但一直没有很成功。

Education Hill,中文可以翻译为“教育山”。Education Hill的那套房子是我第一次住有草坪的房子。刚搬进去的时候,草坪很一般。远远的瞟一眼觉得还可以,挺绿的。但经不起细看,只要走的近些,也不需要太近,只要是从我家门口的人行道上经过,就可能看到草坪上很多的杂草,还有很多秃了的patch。

那时候我立志要把这片草坪整好。而且要原地整,要起死回生。把整片草地铲掉重新铺,固然是能焕然一新的,但我必须要挑战更高难度。后来我做到了。我那时候很自豪我家门口的那片草皮是我们小区最好的。不,甚至可以说是整个教育山上最好的。

那时候朱逢霖老嫌弃我,说为啥要花那么多力气去除杂草呢,杂草也是绿的嘛,剪一剪剪平了,也是绿油油的一片呀。我觉得那就叫不可与夏虫语冰。别的不说,咱不能给中国人丢脸不是?Daphne在底特律给中国人丢的面子,咱要在教育山给挣回来。//tongue-in-cheek

后来搬家了,搬到现在住的这套房子。我现在就坐在后院写这些字,面前就是后院的草坪。这片草我已经基本不打理了,也没打算重新铺。费那劲儿干嘛呢。杂草也没关系,杂草也是绿的嘛,等草太长了的时候拿割草机推一下就可以了,剪平了就都是绿油油的一片。剪草其实也不是为了好看。草太长了,影响郑轶嘉练soccer,球滚不动。

倒也不是我现在对生活品质没追求了。就是觉得彩云易散琉璃脆。以前在教育山的时候草坪整的那么好,都舍不得让郑轶嘉踢球。有时候来个contractor来修个啥的,电线和管子从路边拉到房子里,直接从草皮上压过去,那个心疼啊。现在家里的草坪,怎么zao(第四声)都不心疼。