2022年9月25日星期日

帮助别人的正确姿势

大家晋升到一定级别后就会被要求带新人,怎样带新人才算是成功?绩效评价时是只看有还是没有带人,还是要看带人具体的效果?如果要看效果的话那如何衡量效果?这是我在 career coaching 的过程中时不时会遇到的问题,我觉得可以把我的框架写下来分享一下。

首先,带新人以及更广泛的 mentoring 和 coaching 肯定是可以根据结果来衡量做得好还是不好的,但刚刚开始上手这项工作时更应该看重的是效率而不是效果。这不是说完全不看结果,而是说在合理的难度上能及格地完成工作但不追求更好的效果。

这有点像程序员刚刚开始学习编程时写代码的目标:要能够通过编译,执行结果要符合预期,但不考虑执行性能,也不考虑代码是否优雅。首先要会写代码,接着要多写,写得越快就能在同样的时间里写得越多。练习多了以后,再考虑如何提升围绕着编程的其它指标。如果一开始写不出正确的代码,或者练习的数量不够,其它指标均无法优化。


在有机会带人之后,首先要保证别人确实能够从你这里得到帮助。简单地问一句「你觉得这对你有帮助吗?」就够了,绝大多数时候别人都会说「有帮助」。如果你发现对方迟疑一下才告诉你「有帮助」,你可以再追问一下「有哪些方面可以改进吗?」可能你分享了很多信息,但没有回答到点上;可能你提供了很多理论,但对方还是不知道接下来该做什么。多尝试直接或间接地获取反馈,做到对别人提供有效帮助并不难。

在确认别人能够获得帮助后,接着就需要提高效率。我们可以用一个数值来衡量效率:杠杆比例——如果你花 1 倍时间来帮助别人就能让别人省 n 倍时间的话,这个 n 是多少。效率最低时 n=1,这意味着对方需要获取帮助的事情你帮他做了,而且你做得还不比他快多少。(如果 n<1 你要认真考虑一下你是否应该带人。)带新人的话往往一开始就能做到 n=2 甚至 n=3,毕竟你比新人要更熟悉整个技术栈,就算你帮他把他的工作做了,你也应该比他亲自做要快不少。

我通常建议的目标是 n=8,也就是说如果一天工作 8 小时,那你花 1 个小时就能帮助别人省 1 天的时间。从 n=2 到 n=8 有一段距离,没有人可以瞬间做到 n=8,但要把这做为一个长远的目标,不停地想办法优化以提高 n 的数值。这时候有一种意识很重要:只帮对方必须要获得外界帮助的东西,他自己能够缓慢学习提高的东西不需要帮。

打一个比喻:想象一个倾斜的平面上有一个因为摩擦力而没有向低处滑动的物体。因为静摩擦比动摩擦要大很多,重力无法抵消静摩擦所以物体不会运动,但有可能重力比动摩擦要大,只要运动起来就可以加速。你需要做的就是提供一开始克服静摩擦的那个力。如果没有这个力,这个物体可以相对平面永久地静止,但一旦它运动起来了,无论初速度有多低都能逐渐加速。

这跟「授人以渔」是不冲突的。你教会一个人基本的捕鱼技巧之后你就可以让他自己通过训练来提高捕鱼的效率,他应该自己想要捕更多鱼,这样子他才能从饿肚子变成能吃饱,再到能够卖鱼赚钱。他开头的阶段体验可能不太好,自己捕的鱼自己都吃不饱,饿着肚子又要去捕鱼了。但你效率也很重要,你效率越高就可以越大规模地帮助其他还完全不会捕鱼的人,这些人因为完全不会捕鱼都快要饿死了。(前提是确实有很多人能从你的帮助获得价值,都等着从你那里获得帮助。)

为了实现这个目标,在帮助别人之后最好自己复盘一下,想想自己有哪里的效率做得不够高,如果再遇到类似情况的话怎样能够提高性价比。


效率上去之后,你就可以开始关注难题了。就好像你在能够熟练编程以后,你就会想要找难题来解决一样。难题之所以难,是因为你不能通过提供信息(包括知识、数据等)来解决问题,真正的障碍往往来自于你想要帮助的人的意识。可能在他价值观深处藏着一些他自己也不知道的东西,阻止了他达成他的目标。可能你能看出来他的目标在南面,但他的价值观会引导他向北走。

有时候你提供信息(一张地图)给他就行了,他能够从逻辑上分析出来:要么调整价值观,使得价值观能够允许自己往南走;要么放弃这个目标。有时候你会遇到很顽固的人,他觉得只要往北走足够远就能绕地球一圈抵达目标。你需要挖掘他此前怎样的人生经历塑造了他这样的价值观,然后才能确定你是否能做点什么。这些难题的共同点只存在于这个层面:你不可能用你的知识和逻辑去帮助他,你需要搞明白这个人是经历了什么才成为了今天这样子。


这篇文章首发于我的 Patreon,对同类文章感兴趣的话可以考虑在 Patreon 上支持我,付费订户可以提前至少一周阅读到我的最新文章。同时也欢迎大家通过邮件RSS/Atom 免费订阅我的博客。

2022年8月24日星期三

求助于别人的正确姿势

什么情况下应该求助于别人?求助于别人是否就是伸手党,就会被人鄙视?我在做 career coaching 的过程中发现这是个常见问题,决定拿出来专门写一篇文章。Facebook 的 Bootcamp 在这方面对新人做了很多意识方面的训练,非常值得参考。

在 Bootcamp,专门有一个区域是给 mentor 提供 office hour 的,目标类似于学校里的 office hour(课后问答),如果作为新人的 bootcamper 在工作过程中遇到了问题,可以去这个区域进行提问。新人当然会问:那我该什么时候去提问?标准答案是:如果你自己捣腾了一个小时还是毫无进展,你就该去提问了。

跟学校作业不太一样的是,Facebook 布置给 bootcamper 的任务并不是标准答案已知的练习题,而是实际项目中不紧急也不重要的任务,每一个任务都不一样,mentor 不会提前知道问题,也不一定总能找到正确答案。新人在 office hour 提出问题后,mentor 都会问「那你都尝试了哪些办法?」如果有人说不出来,那 mentor 都会说「你先回去自己捣腾一下,如果一个小时了都毫无进展再回来提问」。

在新人解释完自己尝试过的办法后,如果 mentor 知道答案,可能会直接告诉他答案,把相关文档的链接发给他;如果 mentor 也不知道答案,他会亲自动手,把新人写了一半的代码拿过来 debug,试着解决问题;如果 mentor 解决不了,但知道谁可能提供有效帮助,他会把新人介绍过去。

就这样简单地一个过程,它强调了几种在 Facebook 成功必要的意识:

  1. mentor 必须授人以渔,bootcamper 必须求学捕鱼,不可以伸手要鱼。之所以问你尝试过什么办法但不成功,是因为接下来 mentor 必须要告诉你或者示范给你看什么办法能成功。你不能说「我捕不到鱼,请给我一条鱼」,正确的提问方式是「我用这样的方式捕鱼,我试过了但什么鱼也捕不到,请教我正确的捕鱼方式」。
  2. 即使面对你完全不懂毫无经验的问题,动手开干是最好的学习方式。动手开干不一定是写代码,动手开干也可以是搜索和研究。这跟在学校课程遇到问题存在一个本质的区别:学校课程能遇到的问题,都有已知答案,已知答案都属于一个清晰明了的知识体系,教材总能站在一个对该领域无所不知的角度帮你讲清楚一切。实际工作上的问题,往往你只能获取到碎片化的相关信息,然后再加上你自己的捣腾,产出一个可用的结果。你必须拥抱「真相在一定程度上不可知」然后冲上去捣腾。
  3. 你能直接接触到的人不一定有你需要的信息,你需要学会找到正确的人来获取正确的信息。这也是跟学校成体系的知识和课程结构很不一样的。在学校,你可以假设教这一课程的人对课程知识范围无所不知,你去 office hour 提问肯定能得到答案。在工作上需要获取的信息,有可能需要经过多个节点才能获取到,这个人建议你问那个人,那个人建议你问另一个人。你虽然不确定要经过多少个节点才能获取到你需要的信息,但你最好有一套方法能够收敛你和目标的距离。

修炼好这几种意识,即使不在 Facebook 工作也能让你更好地在需要时求助别人。即使你做不好后面两点,你至少要把第一点做好。


我在 career coaching 时有时候会遇到客户这样的顾虑:我向比我资深这么多的人求助,会不会是很浪费他们的时间?面对这种自我怀疑,你必须调整心态,把自己放在一个能够双赢的角度来思考你们的处境。

首先,你要确定你想要求助的事情确实重要。如果是工作上遇到的问题,你要确定解决这类问题是符合公司利益的,站在公司的立场来看这类问题确实值得解决。这时候无论是你解决还是别人解决,这类问题都是要解决的,这奠定了双赢的基础。

接着,你求助的态度必须是「请教会我捕鱼。我也不想总是找你要鱼,所以教会我捕鱼是符合双方利益的双赢选择。」对于公司来说,这是个三赢的选择,公司解决了符合公司利益的问题,你学会了可以重复使用的技能,帮助你的人将来不需要反复地帮助你。

最后你当然要把这实践执行到底,不能在别人教你捕鱼时捕到一条鱼就走人。尽管这一条鱼满足你此时此刻的需求,但很可能你还没有扎实的学会捕鱼,下次又要劳烦别人。你表明了你想学,你就必须比教你的人更投入地学。


「求助于别人的正确姿势」应该有一个镜像话题「帮助别人的正确姿势」。这是新手 mentor 时常会遇到的问题:我觉得帮助我的 bootcamper 非常消耗时间,但我不帮他又不行,怎样把握这个度呢?我可以下次写一写这个话题。这个话题不仅仅对 mentor 有用,对 mentee 也有用,因为在知道 mentor 如何才能更高效地帮助你之后,你也能更高效地利用 mentor 的时间。

这篇文章首发于我的 Patreon,对同类文章感兴趣的话可以考虑在 Patreon 上支持我,付费订户可以提前至少一周阅读到我的最新文章。同时也欢迎大家通过邮件RSS/Atom 免费订阅我的博客。

2022年8月13日星期六

面试题:开发新功能和重构老代码之间怎么选?


最近面试的多家公司当中,有至少一家尝试在行为(Behavior Questions,或 BQ)面试中问我这样的问题。尽管可以去猜这家公司到底更重视迭代速度还是代码质量然后从对应的角度去回答,但正确的答案只有一个,那就是不要回答这个问题。


第一原理(英语:First principle),哲学与逻辑名词,是一个最基本的命题或假设,不能被省略或删除,也不能被违反。第一原理相当于是在数学中的公理。最早由亚里士多德提出。——Wikipedia

对于所有商业公司来说,第一原理永远是商业,不是产品也不是技术。(「商业」和「业务」在英文里都是 business,在这里不针对中文进行区分。)产品的存在是为了服务于商业,技术的运用是为了服务于产品和商业。脱离商业探讨技术上的取舍毫无意义,因此如果被问到先开发新功能还是先重构老代码,必须要从商业的角度进行回答。

开发新功能对产品和商业有什么影响?重构老代码又有什么影响?这是你必须和面试官探讨的问题。面试官可以会提供更多具体的场景信息,也可能让你陈述不同场景下不同的取舍。我可以提供一些不同场景的例子。


如果我们是一个创业公司,或者是大公司的内部创业,正在做一个探索新市场的新产品。大家对这个新市场不是特别有信心,希望尽快通过产品验证市场是否存在,不存在的话就换方向或者撤销团队。这时候重构代码的优先级就很低了。或许几个月后发现假象中的新市场并不存在,现在的代码写得再烂,几个月后都随着产品下线而全面删除,谁在乎它烂呢?

这背后是有真实的故事的。Facebook 曾经做过一个针对拉美的应用,叫做 Flash,跟 SnapChat 很类似但这是在 Facebook 主应用之外的一个独立应用。Flash 花了 3 个月就发布了第一个版本,我们团队跟 Flash 团队合作,基于他们的代码进行二次开发,有时候会因为代码质量踩坑,我们非常希望 Flash 团队维持很高的代码质量。但他们的目标就是快速验证拉美是否存在一个低端用户的 SnapChat 市场,所以他们就一直往前冲。又过去了三个月,他们团队进行了一次内部讨论,到底接下来应该继续往前冲,还是先重构一下代码以便将来跑得更快,最后他们选择了继续往前冲。

我们团队虽然不喜欢他们这个决定,但这是一个正确的决定。做决定之后的三个月,他们做了最后的冲锋,把值得做的事情都尝试了一遍,最后的结论就是这个市场不存在或者说不值得做。Flash 应用下线,代码全部删除,团队解散。重构并不会改变这个结果,之后稍微推迟这个结果。从商业的角度来说,重构导致了近期成本,但不会带来长期收益,所以不应该进行重构。


如果我们是一个做券商的金融创业公司,那取舍的方向就可能很不一样。我们的首要目标是评估代码出现逻辑错误导致的财务风险。如果我们做的只是现金业务,财务风险是有上限的,也就是所有用户存放在我们这里的现金总量。在最坏的情况下,我们可以把所有用户存放在我们这里的现金都归还给用户,然后可能再承担对应的监管机构罚款和诉讼赔偿,损失的总额是可以进行估算的。如果我们涉及到证券业务,财务风险可能就是不封顶的,因为证券交易可能涉及杠杆和做空。

在进行这种讨论时,需要注重两方面的思维能力:

第一,对商业运作涉及的风险有基本的认识。可以不是很懂面试这家公司的具体商业模式,但要有商业常识和词汇,能够跟面试官进行这方面的沟通,然后才能进行商业上的趋势。

第二,坚持第一原理思维。不要为了控制商业风险就进行重构,而要思考控制商业风险的最佳手段是什么,用这来判断重构是不是合适的技术手段。商业风险有很多非技术的控制手段,例如说买保险。就算是技术手段,也不一定需要是重构,可能提高测试覆盖比例的性价比更高。总之不要为了合理化重构而找一个商业上的理由,那如同拿着锤子找钉子,本末倒置。


从这一道面试题可以推导出来一个更加广泛适用的思维模式:不要别人问什么你就答什么。考试(包括 LeetCode 形式的上机考试)往往把人训练为问什么就答什么,因为问题是没有协商空间的。但在面试的时候,一个大活人随时准备好跟你对话,你必须先对问题进行协商。

这是我在做 career coaching 中时常会提醒客户的事情。尤其是面试 senior 或以上职位时,搞清楚面试题的第一原理很重要,你找到了第一原理然后才能围绕第一原理进行解题。至于引出问题的说辞,例如「开发新功能和重构代码之间怎么选」,这其实不是重点。有时候这个说辞可能是个「X-Y 问题」,但我们期望资深的程序员有侦测和解决 X-Y 问题的意识。

2022年7月5日星期二

美国互联网公司大多数都是要撤出中国的

很多美国互联网公司在中国的业务做不起来,最终选择从中国撤出,在我看来都能用一句话来解释,「就缺一个李开复」。


我曾经非常近距离地观察过某美国互联网公司尝试进入中国的过程,后来也了解了一下其它公司的故事,基本上中国甚至是亚太地区做不下来都是同一个原因,那就是亚太部门得不到充足的自主权(autonomy)。

同一个故事,在不同的公司、不同的部门反复重演。这可能发生在一个经理和一个总监之间,或者是一个总监和一个副总裁之间,反正都是一对直接汇报的上下级。在这对关系当中,上级之所以成为上级,就是因为过去的成功经历。他参与了公司夺取美国甚至是美洲市场的过程,然后带领公司夺取欧洲和非洲(EMEA)市场。他在这个过程中爬到了公司职级的顶端,现在被委以重任,要把久攻不下的亚太市场打下来。

这个级别的人很清楚这件事不是自己亲历亲为就行的,必须搭建一个专业的本地团队。他从本地公司把人才挖过来,或者从本地其它外企挖。这个人是本地业务的专家,他很清楚怎样做才能成功,他能够搭建自己完全本地的团队。一开始这一切都是欣欣向荣的样子,公司有充足的预算来冷启动一个本地团队,公司上下看着这个团队成长的速度都都觉得进度非常满意。

本地团队搭建好了,真正要开始从本地竞争对手手上抢流量了,问题就会慢慢暴露出来。这一对上下级当中,下级是本地业务的专家,对于如何抢占本地市场他有他的方法。但是亚太市场跟欧美相差得实在是太远了,他做的事情他的上级无法理解,于是他要在两者当中选一个:

一个选择是做上级能够理解并且认可的事情,只有上级认可才能获得更多资源,自己才能爬职级。即使这些事情在本地市场完全没效果也没关系,等大家发现自己实际上打不下来这个市场时,自己已经爬上去了,可以跳槽了。

另一个选择是做正确的事情,然后不断被上级质疑。这时候上级在欧美市场的成功经验会成为最大的障碍。上级从自己的经验来看,下级做的事情都是徒劳的,都不会有结果。别说结果了,他甚至不知道如何衡量进度。他不知道如何向上汇报这个本地市场当前的进度,但不能展现良好的进度就很难获取更多的资源,最终影响自己爬职级。这时候他也只有两个选择:

一个选择是信任下级,让他做正确的事情,即使自己不理解。抛弃自己在欧美市场的成功经验,选择相信自己挑人的眼光,豪赌自己选对了人。这其实是非常难做的一个决定。作为一个投资人,你会投资给一个你完全看不懂甚至进度也测量不了的业务吗?这不是一个理性的选择,大多数爬到这个职级的人都不会做这样的选择。

另外一个选择是亲自下场。既然下级做不出自己满意和能够向上汇报的进度,想想自己在欧美市场的成功经验,相信自己能做得不差,干脆自己做好了。这时候这对上下级之间的矛盾就出现了。(理论上他还有第三个选择,那就是换下级,希望下一个下级是正确的选择,能够做出令人满意的进度来。但这本质上就是回到第一步。)

很多美国公司最后就死在这一步。自己所有的成功经验都来自于欧美,把成功经验投入到亚太地区导致失败,但请本地专业人才来做又难以衡量进度和结果。这时候唯一可能能赢的选择是盲目地提供给本地团队相当高的信任程度,让他们有充足的自主权做他们认为正确的事情。有可能本地团队所招到的其实是人渣而不是人才,他们都在浪费公司资源追逐私利,但不愿意赌的话就不可能成功。


跟亚太地区比的话,欧美地区是如此地同质化国家之间的区别可以忽略不计。我在美国互联网公司观察过亚太地区不同国家的数据,不同国家之间的文化差别如此之大,一个产品、一种策略在某个国家的数据完全不能用来预测另外一个国家的趋势。

把亚太区拆开,我们只看东亚的数据,中日韩这三个国家的数据没有什么相关性。再把国家拆开,例如说看港澳台地区和内地的数据,依然没什么相关性。亚太市场实在是太难了,每一个国家和地区都不同,都需要进行针对性的产品和运营优化。尝试把整个亚太区看作一体的公司,最终会发现在一个国家适用的产品在另外一个国家不使用。

举一个具体的例子:Facebook 的定位是把现实生活中的好友关系映射到社交媒体上,Facebook 不希望用户把它作为网上匿名交友平台,所以要求用户使用真实姓名。这在 Facebook 拿不下来的日本市场遭受巨大的阻力,为此只能给日本用户开特例,允许他们使用网名。Facebook 对日本用户做调研时发现他们的态度是「我上网时用的就是我网上的名字和身份。就算是现实生活中的朋友,在网上也叫我网名而非真名。我不愿意在 Facebook 上用真名。」

再举一个例子:十多年前百度曾经有一个目标叫做「划洋而治」,意思是占领太平洋这一边的市场但不参与太平洋另一边的竞争。百度进军的第一个国际市场是日本,为日本做了一个全新的贴吧,比当时的中国贴吧要先进,编辑器支持富文本,发贴可以有彩色文字、可以嵌入图片等等。这个产品当然没能占领市场,最后对日本用户进行调研,他们说「我们不需要富文本编辑器,我们习惯使用纯文本编辑器。但是我们必须要有 Emoji,没有 Emoji 我就不用了。」那可是 Emoji 还没标准化为 Unicode 的年代,日本不同运营商使用不同编码表示 Emoji。


回到我最初所说的「就缺一个李开复」,我真正想表达的意思是这些美国公司都缺一个同时能够在公司高管圈内混得开且在深入了解中国的人。如果这两项技能分别来自于两个人,那就会出现我前面所说的上下级矛盾。能够在公司高管圈内混得开的上级跟深入了解中国的下级难以达到心灵默契的状态,前者觉得后者没有做出来合理的进度,后者认为前者完全不懂中国市场。最终中国市场做不起来,撤出中国就是理性选择了。

2022年2月16日星期三

Facebook 工程师文化独特之处

我在 Facebook 工作了 7 年,结合 Facebook 之前和之后的其它公司的经验,我觉得 Facebook 的文化有些独特的地方值得分享一下。尽管我说了「独特」,这不代表其它公司绝对不会这样做,有些公司有相似的文化,有时候相似的文化用力程度不一样得到的结果也不一样。

工程师对产品结果负责任

我见过很多互联网公司只看工程师产出的技术成果,实际产品结果或商业结果在考评中占的比例很大。Facebook 从高级工程师开始,考评主要看对产品结果的产出,而且有时候非常数据驱动。

考评只看技术的公司,或者是 Facebook 没到高级工程师的级别,只要把技术做极致了就行,产品得不到提醒,公司的商业没有变得更成功,工程师都不用负责任,锅可以甩给产品经理。一款新产品一个新功能做出来,代码可靠从不崩溃,性能优化做足从来不卡顿,界面跟设计师出的图完美吻合,等等等等,工程师就算是优秀的工程师了。如果团队的目标是提升用户留存率,这个技术上完美的新功能发布后留存率不仅仅没有上升还下降了,工程师不需要负责任,考评受罚的只有产品经理。

这种模式的问题是工程师和产品经理目标不一致,更容易产生利益冲突。工程师说「我就是要做这个技术上这么复杂的项目,否则晋升委员会觉得我技术不够不让我晋升」,产品经理说「这个项目消耗你很多时间还不太可能提升产品留存率,同样的时间你可以做好几个有可能提升留存率的功能了。」在极端情况下,这会让双方对立。我在百度时就见过一个例子,只是把工程师换成设计师:设计师说这样设计好,产品经理说那样设计好,双方都只是在利用主观判断说服对方,最后产品经理说「如果做你的设计,KPI 掉了你负责任;如果做我的设计,KPI 掉了我负责任。你想要对 KPI 负责任吗?」设计师立即闭嘴。

考评主要看产品结果的公司,把技术做到极致没用,产品完成指定目标才有用。如果团队的目标还是提升用户留存率,留存率提升了,达到预订目标了,工程师和产品经理(以及其它角色)都能考评过关,远超过预订目标的话还能获得奖励;留存率没有提升,或者是提升不够,工程师和产品经理的考评都会受罚。

工程师不能甩锅给产品经理,两者的目标高度重合。工程师知道,「产品经理指错路」不是借口,产品达不到预订的目标就要受罚。因此 Facebook 的工程师往往非常了解自己在做的产品的指标和数据,他们会花时间去看分析产品数据、阅读用户调研报告,而不是等待产品经理搞明白要做什么了再分配任务。如果工程师坚信产品经理指错路,那就必须自己找到正确的方向然后把结果做出来。没有结果就要受罚,可能是不及格的绩效,可能被炒掉,Facebook 不接受任何解释只看结果。

这种模式可以驱动一个产品团队坐下来好好合作,想方设法利用每一个成员的能力,因为只有这样才能达成目标。如果工程师觉得自己擅长做技术且只喜欢做技术,在这种环境下迟早被炒。所有人都在一条船上,要死一起死。「喜欢做什么」有时候就要给「什么必须要做成」让步,因为做不成船就沉了,大家一起死。

这种模式在自顶而下划分任务的公司不可能成功,只有鼓励自底而上解决问题的公司才能成功。自顶而下的公司,就如同只有船长有权向下发布命令,而且很多时候不需要解释命令的意图,所有船员都觉得自己只要执行命令就好,不需要关注其它人在做什么,不需要理解整艘船是如何运作的。如果船快要撞上冰山了,没有船员会觉得自己有能力和责任阻止船真的撞上去,因为只有船长知道船是怎么运作的,其它人只能无奈的等船沉没。

Facebook 的各级经理都鼓励下属自行定义「什么叫做成功」,如果经理觉得成功定义得合理,就放手让下属自己想办法把事情做成,不需要告诉下属「做什么才能成功」、「如何做才能成功」。如果产品团队主动提出「留存率增长 10% 叫做成功」,只要经理觉得这是对公司合理的贡献,产品团队自己想办法把留存里提升 10%。这样做才能要求产品经理和工程师一起对产品结果负责任,因为「当初是谁定义成功就是留存率增长 10% 的?」

基础架构被视为内部产品

有一些公司会强行在内部推广自己的基础架构。基础架构要进行不向下兼容的升级时,所有内部用户必须派人负责升级。据我所知 Google 就是这样做的,例如说 Google 的某个基础架构服务要从 1.0 升级到 2.0,但它们的 API 是互补兼容的,那用到这个服务的所有团队都必须安排工程师负责更新自己的代码,改为调用 2.0 的 API,否则 1.0 一旦下线这个团队就无法使用这个服务。

Facebook 正好是相反的,基础架构在一定程度是也被看作是产品,只是用户是内部用户而已。那作为产品,当然自己要想办法找到自己的用户,自己要想办法把用户留住,自己想办法扩大用户基数,等等等等。一个新的基础架构出来,没有名气,没有成功案例,必须自己想办法推广和招揽用户。潜在的客户可能说,「你这东西看起来不错,但我不是很确定用了是不是真的对完成我的目标有帮助,我也没空学习和使用你的东西」。遇到这种情况,Facebook 的基础架构团队就跟外面的 SaaS 服务提供商一样,要想办法讨好用户,例如说「没关系,我们团队派专人来帮助你们学习和使用我们的东西,觉得好用的话你们接着自己维护,不好用的话也不浪费你们资源」。

当初 React、React Native 等技术出来时也经历同样的过程,在没有名气之前作者就要想办法推广、说服别人来用自己的东西。外面只看到它们发布时的光环,没看到早期推广的各种困难。2016 年我曾经负责调研 React Native 是否适合用户增长部门使用,因为用户增长主要靠做实验,实验周期受客户端升级周期限制,React Native OTA 升级可以突破客户端升级周期限制。在我做完调研后,我给了大大的一个「NO」,因为 Facebook 主要的用户增长来源自 Android 而当时 React Native 的 Android 版性能(加载速度和内存消耗)实在是不行,和内部其它服务的整合也满地是坑。

基础架构不仅仅新品需要推广,升级也需要推广。「你们出个 2.0 跟 1.0 不兼容?我们一个高级工程师需要花三个月时间改写我们的代码才能兼容 2.0?那我们不升级了。你们准备准备暂停 1.0 的服务?没关系,我们自己出机器,我们自己跑一个 1.0 的实例,反正公司内所有组可以访问所有代码。你们准备把 1.0 代码改得面目全非?我们现在立即 fork 你们的代码!之后我们自行维护一个 1.0 的 fork。」

不向下兼容的基础架构升级往往还是要想方设法讨好已有用户。「你们可以继续用我们的 1.0 服务,但 2.0 性能更好哦。你们组的目标不是转化率吗?你们之前也做过实验,证明了转化率和性能高度相关,提升性能就能提升转化率。我们来算一下,提升这么多性能就能提升这么多的转化率,这绝对值得你们一个高级工程师花三个月来做啦。」工程师既要做销售又要做客服,实在不容易。

既然基础架构被视为内部产品,那产品有的压力基础架构也有。新的基础架构如果在一定时间内无法获得充足的用户,那就很可能被要求终止。已经垄断内部市场的基础架构也不能松懈,如果服务不稳定,内部用户不开心,他们会用脚投票。这些用户团队可能会自己做一个仅适用于他们的服务来取代你的基础架构,也可能有其它人做一个跟你竞争的基础架构然后趁机挖你的用户。

救火比防火更容易获得回报

Facebook 的文化有优点也有缺点。因为公司非常数据驱动,考评倾向于用数据说话,没有数据等于没有干活,完全不看你有没有苦劳,这导致防御性措施很难吸引人去做,因为成功阻止了坏事发生时你没办法收集数据说你成功阻止了多少件坏事、它们可能有多坏。

喜欢写测试的工程师进入 Facebook 往往会因为多写测试而受到惩罚。「你能证明这些测试实际带来的好处吗?你能量化这些好处吗?不能的话你还不如去做新功能,至少新功能能帮助提升产品指标。」不能量化的事情在 Facebook 是很难吸引人去做的。很多工程师技术非常好,但用数据讲故事的能力不行,这种事情就没办法做。

懂得用数据讲故事的话,好像测试这种不能直接量化的东西,可以找参考数据间接量化。「我们分析了去年的每一次事故并且确定其中 n 次是可以被测试防范的,考虑到今年我们团队多了 50% 的人,如果有测试的话我们今年可以防范了 1.5n 次事故。」如果经理认同这种推理的话,你就可以安心写测试了。(如果真的有人明年回来分析今年的事故的话,你最好能证明其中没有一次事故能被测试防范。」)

这种间接量化还是必须等坏事发生过了才能使用,如果你在坏事尚未发生之前就成功阻止了这一类坏事的发生,你没办法证明你工作的价值。这就导致了一个很不好的现象,我往往用以下的比喻来解释:

假想你是一个小镇的消防队队长,你四处去检查镇上有没有违反消防规范的地方,有你就叫负责人整改。这个小镇上所有人都狠你,见到你来检查消防就叫你滚,因为你给大家制造麻烦而没人觉得这些麻烦带来了任何好处。小镇的商户联合起来说每年这百分之几的成本都是你造成的,没有你的话就能有更高的利润。

在消防队队长这个职位上,你只能默默地等待火灾发生。一个房子烧着了你还不要着急去救,救了大家就会说「火灾的损失也很有限嘛,不知道花那么高的代价去防火」。你利用这个时间着手准备灭一场大火。等房子烧了一片了,小镇居民在路上奔跑呼喊了,你就去救火吧。(当然这一切的前提都是你真的有能力救火。)之后你要颁布什么新的消防规范,所有居民都会主动配合。

这就是为什么 Facebook 内部那么多问题处于起火状态,因为不起火就没有救火英雄。

2021年12月25日星期六

互联网选大厂还是小厂:读了本书还是写了本书

这个系列上次写到《互联网选大厂还是小厂:数据中心里有朵云》,这次简短地写一个小一点的区别。在小公司,你更容易遇到同事说「我读了本书,书上说的这个事情能解决我们遇到的问题。我把书上说的事情投入实际应用后,得到了这么好的效果。」在大公司,你更有可能遇到同事说「我是这本书的作者,有问题欢迎来问我,我也可以定期组织相关的研讨。」

有资格写书的大神门往往聚集在大厂中,小厂很厉害的话或许能抢到一个这样的大神。这些人已经工作很多年了,积累也很深了,有心情就把知识整理出来写本书。科技理论的前沿往往发生在学术界,但科技落地的前沿是在大厂。大厂把学术界早就搞明白的事情拿过来,然后进行从来没人实践过的落地。在这方面,大厂提供了更多的机会去做探索。因为前人没做过,就算理论摆在那里,也不可能有书把这件事情描述清楚。

小厂正好是反面,走的路往往是无数前人已经走过的路,成长过程中遇到的问题很多其它公司早就遇到过,已经有人把解决问题的方法抽象出来写成书。这即是优点又是缺点,要看你站在什么角度去看。从创造影响力的角度来看,这是优点,一个应届生新人,不需要很强的原创性,不需要很好的研究能力,读本书就有机会为公司解决大问题,然后得到升职加薪之类的回报。在大厂,这是不可能的,写书的作者都在这里了,如果有利用这本书上的知识就能创造影响力的机会,早就已经做了,怎么可能轮到你呢?但在大厂里,你可以直接接触到作者哦,你可以跟他一起工作,直接从他身上学习,这是小厂没办法提供的。

2021年12月4日星期六

互联网选大厂还是小厂:数据中心里有朵云

时常会有人来问我,应该加入大厂还是小厂。提问的方式有时候是很具体的,例如说「我有这几家公司的 offer,他们规模不一样,这会对我的职业发展产生什么影响呢?」有时候是很抽象的,就是讨论一下以后找工作到底应该专注于大概是什么规模的公司。我曾经想要写一篇长长的文章,从不同的角度来对比大厂和小厂的区别,最后发现很难完成。现在我决定换一个方法,想到哪里就写到哪里,写完一个具体能进行对比的角度,我就发一篇文章。

在这篇文章里,我想要对比的是大厂和小厂在规模上的本质区别。如果你希望接触到一些特大规模的技术问题,你就只能选择进大厂,因为小厂不会遇到这类问题,也就没有机会让你去接触这类问题。这里有一个很有意思的故事,叫做「数据中心里有朵云」,是个很好的例子。

Facebook 早期跟那个年代的其它公司一样,也是在别人的机房租机位开始的。后来做大了,就有了自建机房的需求。机房需要廉价的土地、电力和制冷,荒漠能够很好的满足这三个需求。Facebook 为了节能,专门设计了利用荒漠低温空气对服务器进行降温的通风系统,一旦发现室外温度比室内空调温度还要低,巨大的风扇就会启动,吸入室外温度更低的空气进来降温。

荒漠通常是零降水的,但有一次傍晚真的下雨了,导致室外气温迅速下降,机房开始从室外吸入冷空气降温。因为刚刚下过雨,室外空气虽然温度低但湿度非常高,进入室内后迅速被服务器温度加热升温。数据中心天花非常高,高温度高湿度的空气自然会往上跑,最终空气中的水分冷却后变成云。据说当时在数据中心的人听着服务器发出霹雳啪啦的火花声音,但没有任何办法去抢救服务器。他们把这次事故描述为「There is a cloud in the data center」。

Facebook 后来学聪明了,不能简单根据室外空气温度来判断是否应该吸入室外空气来降温,还要加上室外空气湿度作为限制条件。这种类型的问题,现在世界上也就只有几家公司能够遇到,因为现在绝大多数互联网公司只需要用别人的云服务,不需要自己拥有物理机器,更不需要自建数据中心。如果你想要接触到这类其它公司都没解决过的前沿问题,那只有大厂能够有足够的规模去触发这类问题,小厂根本触发不了。

类似的问题在 Facebook 其实不少,但也就只有这种规模的公司能遇上。举个例子,Facebook 曾经用 BitTorrent 来部署 web 服务器的更新,因为 web 服务器数量过多(百万级别),向每一台 web 服务器单独上传几个 GB 的编译文件效率太差。更新不是就覆盖几个 PHP 文件吗?为什么是几个 GB 的编译文件?因为 Facebook 那时候使用 HPHP 把 PHP 转译为 C++ 再编译为二进制文件。那为什么 Facebook 要发明 HPHP?因为 PHP 执行效率太差,当时有人根据历史数据进行拟合,发现 18 个月后 Facebook 的用户服务器比(用户总数除以服务器总数)将会下降到 1.0,就算 Facebook 有那么多钱买服务器,世界上也没有那么多机位放服务器,所以必须想办法提升执行效率。

所有这些规模导致的问题都是一环扣一环的,一个发明创造解决了上一个规模导致的问题,同时也带来了机遇给下一个发明创造。这种类型的发明创造只能发生在大厂里,因为小厂触发不了这个级别的规模问题,也没有充足的资源去进行发明创造。