首发于Starkwang.log
写在入职腾讯三周年

写在入职腾讯三周年

前几周收到了 HR 公众号发过来的入职周年庆贺邮件,才想起来我已经在腾讯干了整三年了。

三年的工龄,在腾讯内部不算长也不算短,恰恰是一个最为「中坚」的阶段:既要承担一线的 Coding、搬砖,也要开始慢慢学习掌握业务、管理、跨团队协作、商业运作这些程序员的“屠龙技”。

所以我想要写一些东西,记录、总结一下这个节点我的所思所想。

这三年我在腾讯都做了些什么?

17年刚刚毕业入职的时候,我在 QQ 的 Web 团队(AlloyTeam),当时主要就是负责手机QQ、PC QQ里面的一些 Web 承载的页面,面对的场景都是最经典的 hybrid 开发,这块说实话在当时已经趋于完善,对我而言主要就是学到了每天数亿级访问量的页面,是怎么做开发、测试、发布、监控等等(虽然当时内部的基础设施现在看来很落后,但这一套老系统还真的挺完善的)。

后来17年底部门拆分,我所在的小组被拆去了互动视频产品部,这是一个主要做 Now 直播、花样直播、QQ 群视频的部门。当时我的小组一共 9 个人,里面一大半都是近两年毕业的“新人”;业务上,大部分也都是新项目,所以当时可以有大量的机会去尝试前端的新技术,语法特性、框架、浏览器、基建设施,都可以用换成最新的技术栈。这也是我在腾讯“画网页”画得最爽的时候,积累了很多对于前端框架的比较深入的知识。

在这个期间,业余时间很闲,就开始为 Node.js 社区做一些共享,在 18 年初的时候,也被提名成为了 Node.js Core Collaborator。(不过说起来有些惭愧,工作越来越忙,已经很久没有给 Node 社区贡献了)

后来18年的上半年,越来越觉得自己作为一线的“码工”,光是技术上的优化很难对业务产生真正的影响力(毕竟没有谁会因为你的页面体验好,就进来看你家的直播吧?)。所以当时也陷入了迷茫,感觉自己有很强的能力,但是却无法兑现成现实的东西,拳头都打在空气上的感觉。

于是 18 年夏天的时候,在一位前同事的安利下,我决定转岗去了腾讯云,也就是现在我所在的云开发 CloudBase团队(当时还只有「小程序·云开发」这一个产品)。

正式转岗、搬工位的那天下午,正好是 9 月 30 号,也就是腾讯著名的「930 变革」,公司内发了正式的全体邮件,把几乎所有的 toB 业务都划分到了新的 CSIG,而我正是在办公室绵绵不绝的议论声中,收拾东西搬到了腾讯大厦,那个兵荒马乱的下午还真有一种天选之子的感觉(逃)。

到了腾讯云之后,我觉得工作的内容让我愉快了很多很多,因为本身负责的就是面向广大开发者的技术产品,所以我能接触、设计、主导大量硬核的技术需求,而不是简单地画画网页,比如:

  • 设计、开发、维护亿级调用量的 Node.js 服务;
  • 设计几十万开发者都在用的数据库 SDK;
  • 解决 Node.js 一些底层内核问题;
  • 修社区开源项目的 bug;
  • 尝试对业界流行的框架做适配和兼容
  • ……

几乎每一件事情都让我感到兴奋,也可以让我有地方施展拳脚。

后来 19 年的时候,因为团队一时人手不足,有时候我也会充当售前架构师的角色,全国到处飞,去见我们真正的客户,这期间也对国内云计算整个行业有了一定的认识。

所以在云开发团队的这两年,也是我成长最快的两年,无论技术上还是业务上(哈哈我即使说了这句话 leader 也不会给我发红包的,如果看到了请微信转账谢谢)。

程序员的职业价值和发展

首先我想探讨一下程序员或多或少都会思考一个问题,那就是「程序员的价值在哪里体现?」,这个问题我们可以从程序员的几种身份开始说起,我觉得程序员起码会有四种身份:

首先程序员是有「执行者」这个身份的,这个身份本质上和工地、流水线上的工人并没有太大区别,硬要说有,可能也只是工作内容、专业程度的不同而已。这是最廉价的一层身份,对于公司而言,你只是一个可拔插的生产机器而已,明天换成别人其实也差不多。

然后就是「设计者」这个身份,和上面的区别在于,设计者能对涉及的技术项目产生影响,决定项目的各种选型,而执行者不行。这里的设计可能并不是指产品、业务上的,而是技术上,比如你的公司想要做一个新的应用、新的服务,如何选择合适的技术栈确保业务顺利的运行、增长,就是一个很考验经验的任务了。(对于很多非技术驱动的业务,例如 toC 产品,程序员的天花板很可能就是这里了)

再然后就是「推动者」,和上面的区别在于,推动者可以对业务产生直接的正面影响,可以影响业务的决策,而设计者不行,比如业务本身就是一款技术产品(例如云计算业务、微信小程序),或者业务本身就依赖于技术上的竞争优势(比如各大公司的推荐算法团队)。这也是我当时转岗到腾讯云的原因之一,我希望能靠我的学识、能力,去真正推动一款产品的发展,而不仅仅当一个执行者或者设计者。

最后就是「开创者」,和上面的区别在于,开创者能够开始一个新的赛道,引导业界的下一步走向,而推动者不行。理想主义地说,就是可以用技术让这个世界变得更加不一样。比如各种顶级开源项目的作者,比如学术工业圈两头吃的大佬,这也是包括我在内的很多很多程序员梦想成为的人。

但成为开创者的路是很难很难的:

第一条路就是,你在某个领域拥有绝对专精的能力,并且正好遇到了风口。这条路上的标准模板,就是学术界往工业界转型的大牛们。这一点上,我在大学就确定自己并没有足够的耐心和兴趣做可能看起来没有什么短期收益的学术,我更喜欢解决实际的工程问题,所以已经放弃了。

第二条路是,你是一个文艺复兴式的「全才」,这里的全才不仅包括了技术能力,还有管理、交流、视野、逻辑思辨甚至审美、写作能力等等。这条路上的标准模板,就是优秀的独立开发者,还有大部分技术出身的公司创始人。在技术水平上,他们可能并不是最优秀的那群人,但他们懂得如何面对真正的用户、如何经营自己的项目,这些看起来很务虚的内容,并不会比技术问题简单多少。

刚毕业的时候我是一个技术唯上的人,觉得我只要有 Book Smart 就够了,学好数理化,走遍天下都不怕,这家干得不爽了,我可以立马去下一家,毕竟哪家公司不喜欢一个优质的螺丝钉呢?

但随着工作经验的累积,看到、接触到的范围更广,我发现如果未来需要突破一些天花板,不想当一颗螺丝钉的话,光有 Book Smart 是完全不够的(毕竟走的不是硬核科研路线),Street Smart 在一些时候也是相当重要的:你要学会如何推动手上的事情,如何向上向下管理,如何与别人达成利益一致,如何简单清晰地表达自己的想法,如何更有性价比地投入时间和精力…… 这些也是一个工程师的软实力所在,随着工龄越来越长,这些看起来不那么硬的因素,或许就会成为区分点所在

(PS:不过我也要泼一盆冷水,以当下很多同行的技术水平之差,还轮不到拼这些软实力。)

大公司的生存之道

在腾讯呆了三年,就这样慢慢变成了一根「老油条」,也学到了不少在大公司生存的经验,下面几点是比较有深入体会的,所以想分享一下。

1. 提升你的影响力

几乎每家大公司,无论 OKR 还是 KPI 还是什么别的考评制度,一定都会有一项很重要的因素叫做「影响力」。所以每年考核季的时候(比如腾讯的一月和七月),你就能看到各种奇怪的开源项目、一连发好几篇的技术文章、内部分享课程、公众号推文如同雨后春笋一样冒出来,这些背后的推动力,就是对影响力的考核。(但我始终相信,长期来看影响力这一点并不是能够临时抱佛脚出来的。骗得过一两次考核,骗得了三年五年吗?)

所以如何建立影响力呢?

最简单的方法,就是去吃下一个项目,成为项目的核心维护者,大家遇到这个项目的需求或者问题,都会第一个想到你,把你默认作为 owner。当然这个前提是你有能力吃下项目,并且维护。众所周知几乎国内外所有的公司,很多项目的代码都接近「屎山」,我现在越来越觉得能够短时间内搞清楚一堆屎山,并且渐进式地改良它,也是非常重要的能力

第二个方法,去为团队提供好的、正确的东西或者决策意见,这点在国内尤其重要。目前国内因为行业发展速度太快,基础知识过硬的程序员实际上是少数的,即使是大公司,也有很多人也并不是科班出身,做一些设计的时候更多是基于多年的经验,而不是基于系统化的理论知识(据我观察年纪越大,这点越明显)。

未来可预见的十年内,这个状况会一直保持。这就是能让年轻人打出优势的地方,也是我为什么除了感兴趣之外,平时都会读大量的专业书,哪怕跟我的工作领域并不那么相关。我们要做的是出卖自己的知识、能力、学识给公司,而不是卖自己的人肉劳动力。

2. 与其埋头加班,不如想想怎么提升效率

在国内工作,不可避免的一个问题就是加班,但其实大公司里,加班也分成好多种:

  1. 工作量太大or项目赶时间而加班;
  2. 白天时间都花在开会、讨论、对接各种人上了,没时间干活,只能晚上干;
  3. 反正回家也没事干,不如呆在公司吃吃喝喝吹空调上上网;
  4. 要绩效考核了,表演式加班。

后两种纯粹是自作孽,我们就不做评论了。主要想讨论下前两种加班:

前段时间因为团队业务的扩张,我也遇到了第 1 种的问题,当时的想法其实是很「头铁」的:突然来了这么多工作量,那就正面刚嘛。直接结果就是,我一个人干了好几个人的活,连续几周都处于工作压力很大的状态,对身心健康都造成了负面影响。后来才知道,整个团队的工作量其实并没有那么大,只是存在分配不平衡而已,如果我能把手上的一些任务拆分出去给到其他人,其实大可不必这么辛苦的。

在刚毕业的时候,我完全不需要去考虑怎么分配任务的问题,因为那时候我更多的是一个执行者,把交给我的任务优质地完成就好了。但现在,我也要开始学会如何去承担一个 owner 的职责:把任务合理地拆解,分配给合适的人,并且关注整体进度和交付时间

第 2 种,需要反推团队去提高交流效率,比如规定每次的讨论结果必须落地成文本、每次讨论前需要准备基础的材料发给大家看等等这点上,可以先从自己做起。我曾经也有一段时间,一旦遇到什么问题,就立马去找人聊,后来发现这样其实是很低效的。最高效的方法还是先自己思考清楚要聊什么,自己有哪些想法和备选方案,再找相关的人讨论,这样也节省了双方的时间和精力。

3. 主动承担

「主动承担」这个词听起来很官方,很像宣传标语,也是腾讯每半年考核的一个维度,但我一时也没想到什么更加口语化的说法。

什么叫主动承担呢?日常工作里,总是可以遇到很多边界模糊的东西,比如:

  • 你提交了代码,发现跑了几次测试用例,都是时好时坏,而团队里也没什么人愿意花时间去修复不稳定的用例,多跑几次能过就行;
  • 团队维护的核心服务还是跑在老爷车基础设施上,虽然公司在鼓励上云,虽然老爷车效率很低,但因为还能跑,所以就没有动力去迁移;
  • 团队的项目代码缺乏基本的 lint 工具、git hook、git commit message 格式校验,有的甚至连基本的 CI 都没有;
  • 经常收到各种用户的工单,问的都是同一个问题,也没有人考虑写一篇文档彻底解决疑问。

这些都属于「房间里的大象」,也就是非常显而易见,可是却一直被忽略的东西。它们可能是一些脏活、累活、难活,但对于整个团队的效率、交付质量非常重要,需要有足够的人力投入。

这些边界模糊的东西就是需要去主动承担的点,是除了完成团队本身托付的任务之外,还能创造额外价值的点。

作为一个从小到大性格上都比较强势的人,我经常出于“我靠我实在看不下去了”的心理,去做一些份外的事情,这些份外的事情给我带来额外负担的同时,也让我有机会去引导团队的发展。当然我也希望我的同事都是能够主动承担的人,这样我也不会这样心累了(逃)。

4. 学会引导团队的发展

《乔布斯传》里提到过一句话:“消费者并不知道自己需要什么,直到我们拿出自己的产品,他们就发现,这是我要的东西。”

其实工作上也是如此,即使单纯从技术的层面讲,不少人也并不知道什么是好的、正确的。比如曾经的我,认为以下真理是不言而喻的:

  • 写自动化测试用例不是浪费时间,而是提高效率;
  • 面向对象或者函数式的代码,比面条代码好;
  • 有类型检查,比没有好;
  • 把服务容器化,比跑在虚拟机上好;
  • 严谨的对外 API 设计,比随心所欲的好;
  • 精简到两三句话就能把事情说清楚的文档,比一大坨不知所云的文字好。
  • ……

后来我发现,起码就我接触到的范围内,并不是所有人都会有足够的技术审美、追求和视野,比如有人会质疑, 为什么 git 比 SVN 更适合团队工作流,为什么你写的这段 OOP 代码就是比他的七层 if else 好,为什么项目要写自动化测试并且接 CI,为什么我们要抛弃虚拟机转向容器引擎等等。说服这些“顽固保守派”,也是要花很多时间、口水和精力的事情。

那么要如何引导团队呢?刚毕业那会儿我是一个很激进的人,看不惯一切落后原始的东西,团队内的项目,一刀切上最新的技术就对了,这种做法后来发现阻力很大:

  • 团队成员并不是每个人都了解这些新东西;
  • 新东西往往有很多隐藏的坑,你可能就要当第一个吃螃蟹的人;
  • 现成的业务已经趋于稳定了,虽然可能是个屎山,But It Works !

在了解这些阻力的来源之后,我开始学会如何「渐进式」地去改造现有项目,比如:

  • 项目缺乏最基本的 lint?那先把 husky 加进来,任何人改动的文件,都会被自动化 lint,而不是对整个项目跑一遍全量 lint 和格式化(这样其它人的开发分支全部冲突了);
  • 想给老项目引入 TS 进来?那就允许 TS 和 JS 并存,这样随着项目的开发,JS 就会被慢慢改写成 TS。而不是花一两周时间啥也不干,全量把 JS 切到 TS 上
  • ……

渐进式迁移的好处就是,可以满足绝大部分人的利益,不容易遇到阻力,也不会给项目一次性引入太多的风险和不稳定性。当然对于新项目,我是偏向于激进的,不想给未来留下过多的历史性包袱。

最后

现在全民 CS 的时代,程序员确实是大势所趋,毕竟收入水平摆在那里,即使完全不爱这一行,那也不能和人民币或者美元过不去嘛。

但对我而言或许并不是那样,和《一拳超人》的琦玉老师一样,我是一个兴趣使然的人,一直觉得写代码是一件很酷、很 Geek 的事情,能够学到更多的知识,能够用自己的学识和能力做出、推动一些事情的发展,让世界变得稍稍不一样,这就是我的源动力,而当下的腾讯能够给我这样的舞台。

士不可以不弘毅,任重而道远。

编辑于 2020-07-21 16:52