前言

前段时间刚刚离开了工作三年的前公司。离职之前,有幸能和诸多深交的好友们聊一聊对于工作的看法、经验与教训。在回家的地铁上,逐渐地产生了将这些思考写下的想法。内容很多,关于对技术的认知,关于工作环境,与君共享、共勉。

常怀谦虚与敬畏之心,警惕技术自大主义

越是在技术环境非常友好的地方,就越容易找到top2毕业的天之骄子、ACM竞赛中的传说大佬和论文引用轻松过千的领域专家,这些“天之骄子”是公司水平的保证,但也不可避免地引入了某种程度的“文人相轻”与“恃才傲物”。

这种心态往往是潜藏在这样的话语中:

  • “用户是愚蠢的,体会不到我们设计的精妙”
  • “这篇paper做的很简单,不知道为啥有这么大的影响力”
  • “这么简单的事情,就不要发paper说出来了
  • “这个结论我们早就知道了,只是觉得太简单没好意思往外说”

当然说话的人的本意如何我们无法得知,但是或许换成下面的话,会更合适一些:

  • “用户偶尔会犯傻,所以我们需要一些符合直觉的设计来减少这种事情的发生”
  • “这篇paper做的简单又具有很大的影响力,那么一定有某种我没意识到重要的东西需要我去学习”
  • “这篇文章阐述了一些对我来说显而易见的东西,说明我可能对社区的水平欠缺一定的了解”
  • “对于这种已经知道的结论,虽然不能写成paper,但可以写成blog或者report,对于其他人也是有帮助的”

这种言语的改变绝非简单的“高情商”,而是根植于一种谦逊的心态,深信“别人身上一定有一些我可以借鉴的地方”的想法。我之前遇到过一个实习生,他无意间透露的想法让我印象深刻:“resnet的想法很简单,我也能想到,只是我不知道如何包装而已”。但其实,resnet中提出的方法,后面藏着的对于事物抽丝剥茧式的认知,绝非简单一朝一夕、一拍脑袋能够想起来的。解决问题的方法不是本质的东西,对事物的深刻认知才是。这种深刻的认知会促使我们找到优雅的解决方法,至于什么是优雅,我觉得就是“简单而有效”

在专心做技术的人群中,”技术自大主义”是一种很容易出现的现象,而在技术氛围良好的环境中,更容易受这种思想的影响。甚至我现在也经常需要使用“弱小和无知不是生存的障碍,傲慢才是”来警醒自己。也许有些人或者公司的行为你站在高层视角并不认可,但是这并不妨碍对方在某些领域取得成功。就像是拼多多,你当然不必认可它玩弄人性的各种伎俩,但你要认可它对于在十八线县城中生活的人的深刻洞察

工程是scale的艺术

如果有人问工程的核心是什么,很多工程师的回答可能是“trade-off(权衡)”。但是在读了Software Engineering at Google 之后,我的答案就变成了“scale”。

因为我英文水平有限,不知道这个“scale”应该如何翻译会比较信达雅一些,所以我觉得举一些例子更合适:

  • 规模上的scale:如果你做的工作只有一小部分人会用到,那就是scale很小,而如果很多同行/公司会用你写的代码(比如一些重要的开源软件如numpy),那就是scale很大。
  • 时间上的scale:如果你做的工作只在很短的时间被使用/产生影响,那就是scale很小,而如果你完成一次工作就可以在很长的时间内重复使用/产生影响,那就是scale很大。

“scale”是一个非常神奇的东西,三个房子可能只是三个房子,三千个房子可能就可以称之为城镇了,城镇就会自然涌现出医院、学校、商厦和马路。同理,一个工程项目里面的一行代码,也不仅仅是一行代码那么简单了。

这种基于“scale”的思考模式在很大程度会影响你的行为:

  • 当你意识到你频繁需要使用一个东西的时候,那么是时候优化你和他人的使用体验了,因为频繁的使用就意味着时间上的scale。比如你写了一个工具,但是隔三差五就会有人跑来这个工具是如何使用的,那么最好将使用的流程写成文档,因为文档本身是随着时间scale的,你写一次文档,就可以节省很多次的说明。再比如我一直维护了一份自己使用的dotfiles,原因之一就是因为在不同的机器上配置自己的环境就属于一个随着时间scale的东西,而在这些dotfiles中我又推崇vim-like的操作习惯,甚至在vscode和chrome浏览器中也要使用vim的插件,因为vim的理念非常契合scale的思考模式:相比画画(写代码),画家(程序员)在画布(编辑器)上停留、浏览与思考的时间更长(scale更大)。
  • 看待大型的工程项目会更偏向scale的视角,会考虑这个项目到底scale了什么,怎么做这种scale。举个例子,pytorch是深度学习领域重要的开源仓库,但是其核心就是对于可以反向传播的算子的scale,换言之,就是如何保证可以加入众多的算子,而整个自动求导系统不会崩溃。为了解决这个问题,torch团队设计了的精妙的Tensor和Autograd体系,引入了算子的registry / dispatch等机制。再比如商汤的mm系列的框架,研究的就是模型的scale,考虑的就是如何很容易地将不同的模型集成入仓库。
管理、team work与环境

因为组织架构的调整,在前公司被迫换了几个不同的组,也算体会过不同的环境之间的差异。所以这一个部分我们聊一下组织与管理。毕竟个人的力量有限,再强的个体也无法处理所有的问题,写出大型codebase中的每一行代码。

第一个要聊的是“什么是团队”,下面是我目前对于团队的理解:团队不是简单的人的集合,团队中个人的强并不代表团队的强大。按照上面提到的scale的说法,团队不是人的scale。就像是打篮球一样,巨星抱团未必能有立竿见影的效果,“化学反应”才是关键,竞技体育中的核心目的是赢球而不是某个人的得分高。在一个所有人都很厉害的团队,很容易出现互不认可然后“大路朝天,各走一边”的情况,有人戏称这种情况叫做“聚是一坨x,散是满天星”。担任这样的团队的leader,技术实力的强弱与否只是一个评价维度,相较来说,能够协调处理各方的冲突,使团队focus共同的目标,是leader更重要的能力

第二个要聊的是团队的环境。我工作期间有幸跟过一些从比较简单、原始的状态开始的项目。现在回看,该走的弯路、该踩的坑,一个都不会少。初期犯错,是为了后期犯更少、更严重的错。作为对比,有些技术非常好的leader可能会不认可他们管辖的人(通常也是执行具体任务的人)的提议,希望项目能够少走一些弯路。这种不认可有很多表现形式,可能是只给你灌输他认可的想法,偏离这种想法的路径都是歪门邪道;可能是默许你做一些自己的创新,但是对于你在新路径上的发现采取不管不顾的态度。虽然后者的态度能让员工保留一些自主性,但是在一个鼓励创新与探索的环境里,这两种态度都是十分有毒的,因为“试错,是走向正确道路的最佳实践,有一些学费是不得不交的。”对于leader来说,指导固然很关键,但是建立鼓励尝试、对错误宽容(但及时反思)的团队氛围的作用要远大于指导。好友xxr说过一句话:一个leader的最大成功就是,团队没有leader也能持续良好地运转下去。员工很多时候需要的是催化剂,而不是导航员

第三个要聊的是我的一些观察,可能不对,但是在我短暂的职业生涯中,能找到一些具体的例子。第一个观察是:团队内的信息流动速度,会很大程度上影响每个人的成长速度。乐于分享的组织,通常员工的个人素质会更高一些,员工之间的私人关系也会更好,也更容易产生化学反应。第二个观察是:越是有口碑的管理者,曾经的部下就越容易追随他/她。这种追随的形式可能很多,比如:在离职之后仍然保持一定强度的联系、缺乏人手的时候愿意主动帮忙推荐一些朋友。最后一个观察,或者说经验,就是:在一个团队里面,如果你总觉得一个事情需要有人去做,那么你也许是最适合的人选。比如你可能会觉得文档需要有人写了,那很可能你就是最适合写文档的人(说明你对缺乏文档这件事情的耐受度比较低);或者你觉得频繁做某项任务太麻烦了,应该写一个工具简化流程,当你在团队里表达了这个想法之后,很可能最后就是交给你来完成。

后记

本来到这里还想写一下过去3年学到的“如何学习”作为第四个部分的,但鉴于篇幅可能比较长,先写到这里,抽空再开一个blog聊一聊学习和成长的问题吧。

无论前公司将来会走向何方,走了何种道路,我都会感恩在过去的时间遇到的每个人和事。关于谦卑、关于工程、关于团队,我又比三年前的我理解地更深了一些。

可叹,有些时候,就是“人生南北多歧路,君向潇湘我向秦”。