生活上
本周:
- 本来的计划是周一结束欧洲十天的行程,从斯德哥尔摩回来。还记得那天坐在 ARN 机场的登机口感叹这十天满满当当的行程终于走完了,再也不用担心一会儿要坐陌生的公交去赶哪一班车/飞机或者哪个景点的预约了。命运还是开了个玩笑,Delta 居然在登机口取消了飞机。错愕片刻,在确定能坐次日的补班回来的前提下,我比较淡定地走出机场(需要重新入境申根,因此我收获了一枚申根取消出境章),在斯德哥尔摩接着玩儿了半天,晚上在用航空延误险报销的本地餐厅大快朵颐和在五星级酒店里好好休息,周二才回到了纽约,回来的飞机比较空,平躺着回来的。
- 周一周二在斯德哥尔摩一直在听 ABBA 的歌,周一的时候还路过了他们的博物馆,但没挤出时间来参观。第一次听 ABBA 是 The Martian (2015) 里用 Waterloo 作为背景音乐,但经过这次瑞典之行更加喜欢这个乐队了。听 Gimme! Gimme! Gimme! 的自己特别自信和快乐,走路都带风。
- 大概周三的时候开始感觉鼻子有些不适,终于在周五周六发展成比较严重的感冒。我测了两次都还是 COVID 阴性,也许是这次十一天的行程太 intense 了,累得抵抗力下降了,得了普通感冒。不过这十一天的行程我是相当开心,该走的地方都走得差不多了,时间利用率很高,倒是不后悔这么累。如果是普通感冒的话这几天就好好多休息吧,适度做的事情少一点。
- 周三上午和现在湾区但之前在纽约的DJ同学吃了个 brunch。他去年换组做 MLOps,但吐槽最多的还是湾区生活的无聊 lmao。
- 周五周六晚上参加了两场日语角。周五的这场 J-KURU,疫情前我常去,这次是疫情后第一回,惊讶人数比预期多,自己好像也找人聊天更自然了。周六这场是 Discord 线上的,都是中国人聊的话题更亲近一些。这两天说日语的感觉还是挺开心的。
- 周末在家附近发现了一家专做 Tuscany 面包的 Prato Bakery,环境挺好,面包的种类非常托斯卡纳,我点了个叫做 Siena 的 focaccia 三明治,里面放 prosciutto、cheese 和西红柿,和上周在 Firenze 的 Mercato Centrale 吃到的 prosciutto panini 一模一样,瞬间穿越回意大利托斯卡纳。在这家店坐着也很舒服,周末干活可以常来,本文就是在这里打完的。
下周打算:
- 好好休息,感冒早日康复。
- 做一些之后的旅行 logistics,特别预先开始办英签和申根签,虽然这两个地方应该在明年才有机会再去,但护照的档期尽量充分利用。
- 整理旅行的帐,整理延误报销的文件。


技术上
本周:
- 做了一场LC双周赛,不是特别理想,最后一题很有意思但没写出来。感冒对状态还是稍有影响的。
- 终于又开始写简历了,但简历的进度比预想的慢一些。
下周打算:
- 接着在简历上花些时间。
- 也接着再投一些简历。
- RecSys 22 是这一周,可以把大纲过一遍。
本周我还想好好记上一笔的是最近很多关于工作的思考:
- 过去三年,我在Google Cloud的一个做安全产品的组。但纵览这三年,我真正享受这份工作的时刻其实比较少,对比起来在上一个产品反而更享受一些,所以也不能算是我对工作的期待太高。
- 前两年我以为是因为这个项目的代码量太少了,这是安全项目都有的特征,代码量都不大,大量的时间是花在非代码的部分。起初我以为这是因为「写代码」这个本能能给自己带来快乐和享受的活动的份额变少了的结果。
- 但最近有了很多新的感悟。上面的原因都是很表象的。真正的原因是这样的:1)这个项目的产品设计过程和工程系统设计过程都不是特别满足我的兴趣;2)在这个背景下,在这个项目里的成长路径也就不是那么诱人了。
- 下面分别来谈谈这些问题。这是个很有意思的问题,认清自己喜欢什么不喜欢什么,以及认清楚不同的项目和工作能提供什么,对自己的职业生涯规划很重要。
- 产品设计过程:
- 绝大部份的软件工程师都是在商业公司工作。所做的项目也都是产品,而所有的产品都是有其目标 (goal) 和衡量成功的指标 (success metrics) 的。因为大家都是商业公司,所以最终这个衡量成功的指标都是能为股东创造多少利益,有直接和间接的差别。
- 有些项目非常直接,比如直接面向用户的 feature 类项目(比如视频网站等),其 success metrics 一般都是日活用户 (DAU) 或者点击率 (CTR) 等比较容易量化的指标,这种指标对最终的 metrics ——股东利益的贡献也比较直观。
- 有些项目不是那么直接,比如服务其他项目的 infrastructure 类项目(比如内部数据库等),其 success metrics 其实也比较容易衡量,比如这个数据库能支持的并发查询数 (QPS) 或者查询的延迟 (latency) 分布。需要注意的是这里的 success metrics 虽然比较直观,但是对最终的 metrics 股东利益的贡献并没有那么直观:比如这个产品如果以 QPS 作为 success metrics,那么它一定要能以某种方式转化成股东利益,它才是一个好的 success metric——比如 QPS 增长 unblock 用户数量增长,使得另外的产品的 DAU 增长,从而贡献股东利益。而当这样的 metric 不能看到一条比较清晰的贡献股东利益的路径时,它就不是一个好的 success metric,即使这个 metric 本身可能对这个系统(数据库)本身是一个有意义的指标。
- 而有些项目就更加模糊了,大的公司一般会战略性地部署一些前瞻项目,这些项目没有短期内的盈利压力,但这些公司做这些项目一定是有其商业逻辑的。比如我所在的安全产品组就是这样的项目,我们没有短期的盈利指标和用户数指标,我们的目标是成为这个领域内关于安全的事实标准设立者。不在安全领域的例子也有,比如 Docker,其当初的目标就是成为部署领域的标准设立者。这种产品很难有明确的 success metrics——你如何在当下衡量你将来是不是标准设立者呢,虽然它们的 goal 很明确(成为标准设立者)。这也不一定是一件坏事,在这种项目工作比较像是在读 PhD 做科研,自由度比较高,不太容易被短视的 metrics 捆绑,但同时也比较难量化阶段性的成功。
- 对于任何项目,没有清晰的 success metrics 或者 success metrics 看不到一条清晰的转化成股东利益的路径,注定会失败。首先如果 metrics 或者 goal 无法转化成股东利益,那这个项目的商业价值就是零甚至是负数,本就没有存在的道理。而要是没有清晰的 success metrics,即便对于那些 goal 能比较明确地转化为股东利益(比如行业领先地位带来的垄断效应)的项目,如果不能制定出清晰合理的 success metrics 或者说阶段性目标(即便不是量化的目标),那这个团队本身的激励机制就会出问题——你没有办法衡量一个人做的事情是不是对公司更有价值,更何况个人也很难从中找到成就感,而没有激励反馈和成就感的团队是难以为继的,所以对于这种项目,领导者能否设置清晰的 success metrics,以及领导者是否能让整个团队意识到什么样的事情对公司更有价值,是一个决定长期成败的关键。
- 说了这么多产品本身对公司的价值,产品本身对工程师个人也可能有价值。这体现在工程师的个人兴趣是不是和这个产品的最终效果或者 problem space 相关。比如某人对语言学本来就非常感兴趣,那么做输入法这样的产品本身也能给她带来满足感,那这样这个项目对工程师个人也是有价值的。这里要注意的是,产品的商业价值(几乎总是由 success metrics 为指南针)决定了产品的走向,而个人兴趣带来的满足感是由这个产品的社会价值带来的,产品的商业价值并不总是和社会价值重合,如果要在这里找寻自我实现要思考这两个价值有多少重合的部分。
- 绝大部份的软件工程师都是在商业公司工作。所做的项目也都是产品,而所有的产品都是有其目标 (goal) 和衡量成功的指标 (success metrics) 的。因为大家都是商业公司,所以最终这个衡量成功的指标都是能为股东创造多少利益,有直接和间接的差别。
- 工程设计过程:
- 软件工程师创造的都是工程系统 (systems),而它们恰好能被公司拿来直接或者间接包装成产品来赚钱。拨开产品层面的问题,这个 systems 本身也很值得讨论,这其实是绝大部分软件工程师在大部分时间里直接打交道的部分:在确定了产品需求之后,她们需要设计一个系统来服务于这个产品。
- 一个系统本身会有各种各样的 systems metrics,诸如 latency, throughput, correctness, scalability, maintainability 等等等等。但服务的产品不同,这些系统所强调的 systems metrics 也有不同。举个例子,某个搜索或者推荐系统的 latency 可能就比这个系统的其他的 metrics 更重要,因为 latency 可能更能影响用户满意度,直接影响商业上的 success metrics(从这里开始我把上文提到的 success metrics 称作 business metrics,以和这里的 systems metrics 作区分),从而影响股东利益。
- 正是因为 business metrics 的影响,本来看来差不多的系统,在其设计实现维护的生命周期内其需要的技术技能完全不同的。比如同样处理用户数据的 pipelines,即便处理相同量的数据,latency-intensive 的 pipeline 和 correctness-intensive 的 pipeline 的设计实现,对于工程师来说是完全不一样的体验。(什么是correctness-intensive?比如安全功能就是,我们需要宁可错杀一百不可放过一个,或者更好,既不放过一个也不错杀一个。但我们对这个结果是一秒钟还是几秒钟出来不是很关心,而别的工程系统可能正相反。)
- 工程师对于设计不同的系统是有偏好的。就像对程序语言,技术栈等等有偏好一样,在这里 systems metrics 也只是偏好的一个维度,但也是一个不容忽视我认为甚至比语言等更重要的偏好。
- 我自己是特别关注系统的 performance,或者说我很喜欢解决也很擅长解决 how to make systems process more data 和 process data faster 这两个问题。安全产品这种 correctness-intensive 的系统是没法给我在这个维度上提供很多满足感的。
- 但这里也有个误区,就是对于关注 performance 的人可能会认为自己只适合做 infrastructure 相关的项目,比如数据库等俗称的造轮子。其实不然,就像上面解释的,这些造轮子项目之所以吸引这些人,是因为这些轮子的 business metrics 很清晰地等同于它们的 systems metrics,而提高某些 systems metrics (比如 latency, throughput)刚好是这些人的偏好。
- 当然这里实际上更复杂一些,有些人可能就是对数据库本身这个产品层面的 problem space 非常感兴趣。但要明白,像数据库也只是一种产品,也有一种可能你只是被解决的工程问题所吸引,如果是这样的话类似的工程问题其实也会出现在和轮子毫无关系的产品组——做抖音推荐视频的 pipeline 可能和某个做商业数据库的 ETL pipeline 都有非常类似的 latency 优化的工程问题需要解决。
- 在这里实际上重要的是知道自己对什么样的工程问题感兴趣、更擅长,systems metrics 的偏好只是一个维度而已,但我认为是个很重要的维度。
- 在项目里的成长路径:
- 成长也是满足感的很重要的来源之一。成长可以是你自己关心的任何维度上的,责任与能力上的成长,智识与经验上的成长,甚至是金钱和地位上的成长。
- 我的观点是,这个成长的维度一定要是自己所关心的,而不是外界所关心的。自己所关心带来的驱动力(内在动机)和为了满足外界期望和虚荣带来的驱动力(外在动机)的质量和持久力是天差地别。比如金钱很少是一个内在动机,人们大多数时候是为了满足外界期望而赚钱,但有时候它也可能是一个有足够持久力的内在动机——比如当你真的很缺钱很窘迫的时候那金钱驱动是足够持久的——当然我相信只有很少的人处于这种状态。
- 回到实际的项目里,如果自己所关心的成长不是纯内向性的(比如单纯智识上的积累,当然这也是一种很好的成长),那么成长一般体现在对外部 impact 的增大上,这一般体现在:
- 我能解决的问题的 scope 变大了(能力和责任的纵向成长)
- 或者我能让更多人一起更高效地解决某个问题了(能力和责任的横向成长)
- 在这里,能力的纵向成长很好理解,就是你解决的问题的难度和复杂度 (difficulty and complexity) 变大了。这也比较容易衡量。
- 而能力的横向成长很多技术出身的人误解比较多,它同样是在解决问题,这个问题同样也有难度和复杂度,也很有可能很有意思。一个人单靠自己所能做的事情终究是有限的,就像系统里的单个节点所能做的也是有限的,所以我们创造了分布式系统,而团队和公司正是这样的分布式系统。而我们知道,一个本来很简单的计算在分布式系统里可能会变得非常复杂,最难的部分是不同节点之间的通讯和共识 (communication and consensus),这在团队里是同样的,有的人做事快有的人做事慢,有的人有不同的偏好,就像分布式系统里的节点一样。从这个角度看,能力的横向成长,即所谓的领导力 (leadership) 也可以是一个很有趣的问题,而既然是一个有趣的问题,那么自然也会有人有偏好去解决这样的问题。这么想,就不难理解在工程团队里为什么会有纯管理岗位的出现,以及为什么有人非常享受解决纯管理问题,她们对团队和公司带来的价值也就更清楚了(注:有读者反馈,怎么衡量管理者带来的价值是个难题。的确,虽然这个价值定义非常清楚,但是怎么去测量以及测量误差多少,是非常难的)。
- 个体的成长可以是很多维度上的,你可能在这个项目里既获得了纵向的成长,也获得了横向的成长。回到本节一开始的话题,这里一定要有一部分成长是你真正所关心的(所谓内在动机),注意这里是一部分而不是所有。
- 打个比方,你真正关心的是解决某个更大的技术问题 (difficulty),但在有限的时间内你自己是无法完成的,所以你只能直接地管理或者间接地在技术上领导一个团队来完成,所以对你的横向能力 (leadership) 也有成长的需要。但在这种情况下,你的纵向成长是你的目标,而横向成长只是达成目标的手段之一。
- 要明确自己的目标是自己真正关心的部分。这需要对自己有更好的了解。比如我觉得自己是一个问题意识导向的人,会被这个问题的社会价值(social impact,在产品层面)和技术价值(technical difficulty,在系统层面)所吸引,我不排斥甚至非常欢迎对我横向能力 (leadership) 的提升,但这似乎只能作为一个手段,如果把它作为一个目的的话,我很难激励自己去带领一个团队去解决一个我自己不太关心的问题。当然这里只是我的个人情况,有很多人——我在职场上亲历过不少——能做到把 leadership 作为她的目的的,毕竟 leadership 所解决的问题也有它的迷人之处所在,所以你如果是这样的人,那么把目标设置为带领更大的团队是非常合适的,但据我观察这种人并不是大多数,很多人把目标设置为带领更大的团队是为了满足外在的期待和虚荣——这当然也可以,也在一定程度上是有效的,但我比较怀疑这个的持久性和其过程的享受程度。
- 回到我的具体的项目里,在安全产品里我能看到的两个成长路径分别是:1)在产品层面解决更难的安全问题——这需要对安全有更深和更前瞻性的理解;2)或在系统层面设计交付更复杂的系统——而在安全模型 (threat model) 已经被前者确定的情况下交付这个系统的挑战在于要理解内部其他各种不同数据源的数据以及如何 provision 这些不同数据(获取,权限处理等),而当获得这些数据之后怎么处理这些数据是比较简单的。
- 对于第1点,对某些人是很迷人的,我也觉得这个过程是很有趣的,但很不幸成为安全专家不是我的目标,我所获得的能力成长在离开安全领域之后不是 transferrable 的。
- 对于第2点,它所解决的问题也不是一个我很享受的问题,它给我带来的能力成长是能对Google Cloud的各种不同系统的数据获取和权限有更全面的了解,这所隐含的能力成长有:a)能在短时间内理解不同的业务逻辑系统并统筹设计利用的能力,这是一个 transferrable skill。b)和大公司内不同的姊妹团队沟通并取得共识的能力,这是一个非常有用的 transferrable skill。c)带领更大的团队交付这个系统的能力,同样也是 transferrable 的。
- 但就像上两点所分析的,这些 transferrable skill 并不是我特别关心的那一类问题,所以如果我把它们作为我的目标的话是很难持久下去的,虽然中短期内是会有效果和收获的,但不是长期的办法。
- 总结一下的话。软件工程师对自己的成长需求,和对不同项目所能提供的成长路径有更好的理解的话,是能做出更好、更充实的职业规划的。首先要明确自己最关心的成长目标。
- 如果这个目标真的是横向能力上的 (leadership) 那可以寻找相应的机会,比如一个快速成长且有很多管理问题亟待解决的团队。
- 如果这个目标是纵向能力上的,那可以看自己关心的的问题和这个项目所要解决的问题是不是有部分重合,这里既可以是产品层面解决的问题的社会价值和个人所关心的社会价值重合,也可以是系统层面解决的问题和个人的技术兴趣重合,也可以是两者都有。
- 而在产品层面,你自己关心的社会价值和这个产品的商业价值 business metrics 最好有某种程度的关联,否则自己努力的方向和这个商业项目的走向有不一致的风险。
- 在系统层面,自己关心的技术问题也最好和这个系统被 business metrics 定义的 systems metrics 有关联,否则同样也有自己的技术兴趣和商业走向不一致的风险。
- 最后我想说,记得当年刚入职场的去做一个Dart前端项目的时候,我的第一个经理对我说,做什么其实都一样。这句话现在回想起来,既对也不对。对的部分在于,不管做什么项目,前端也好后端也好研究也好,都是要给公司提供商业价值的,而公司也一定是根据你带来的商业价值大小来评价你。不对的部分在于,个体的差异性相当大,每个人所擅长和所喜欢的事情也都不太一样,而如上文分析的,项目本身的问题性质和所能提供的成长路径也都是不一样的,找到能发挥自己所擅长和喜欢的能力的项目,就能把能力发挥出最大效用。不过同样重要的是,这里「自己所擅长和喜欢的」并不是一个不变的常量,保持开放的心态 (keep an open mind)、成长心态 (growth mindset)、好奇心和问题意识,你几乎总是能在各种事情里找到有趣而待解决的问题,而这些问题适不适合你,只有勇于尝试才能揭晓,be a good risk taker。
Leave a Reply