最近有一些朋友从学校毕业了刚入职工业界,来问我有没有一些人生的经验可以听取一下。我也不是谦虚,就把自己反思过往的一些心得发出来,尤其是一些希望当时初入职场的我能够早点知道的事情,希望能给年轻朋友们一些启发。回想刚毕业的我,满腔热情,头发茂盛,时刻准备开卷,但没有努力的方向,更致命的是不知道自己不知道努力的方向。所以南辕北辙,很多力气做了无用功。这篇文章主要就想回答这个问题,什么是重要的,什么是不重要的——这个其实就是价值观,是个非常主观的认知。所以这篇文章仅代表我个人的观点,而且仅适用于北美码农业界,请批判看待,独立思考。
我想讨论的第一个问题就是“技术”到底有多重要。在一些职场新人小伙伴的圈子里,我们经常听到抱怨,某个老年(senior)工程师或者校长(principal)工程师写码还不如我,链表逆序都写不好,他也配lead我?或者隔壁烙印根本不懂技术,嘴炮不断,code交不了几行,凭什么他升得这么快?这其实就陷入了一个常见误区,把写码能力当成了评价码农的主要标准。这里“技术”为什么打引号,是因为它是一个非常宽泛有歧义的东西。这一段我们说的技术主要是狭义的写码的能力。leetcode类的题目写得又快又好,没有bug,一遍成功。各种数据结构和算法信手拈来,而且了解得很深入,深度广度都有。对于这样的技术能力,我的观点是,它其实并不重要。原因有二,一是实际工作中很少遇到这么复杂的算法,更多的是直接调用现成的库。二是这些能力属于底层(low-level)执行力。对于一个复杂的项目来说,执行只占整个项目很少的一部分。招一个执行力100%和200%的人,产出的差异并不大。但一旦整体框架或者技术决策做错了,工程就是成功和失败的区别。所以这些底层执行力在全局上并不重要。
那是不是就是技术在业界就不重要呢?也不是这样。只是这个技术的定义比写码能力更为宽泛。这里要引入一个概念叫软件工程。国内的本科教育对软件工程很不重视,软件工程学院在很多名校都是二级学院,软件工程在很多计算机系也就是一门课。但它是整个码农业界的核心。经过了几十年的发展,除了少数例外,现代的代码项目已经远远超过了一个人能搞定的极限。稍微大点的项目就需要至少三五人的团队几年的时间来构建和维护。为了让这样的大型项目变得可行,就需要一个专门的知识体系,来指导我们进行跨组别和跨时间的大规模合作。这个知识体系非常复杂,它是关于软件的,它的核心是工程(就是造东西),所以叫软件工程。整个码农职场上几乎所有的升职标准都是围绕软件工程来制定的。恰当定义或者概括软件工程远远超出了我的能力,这里举几个容易被新人忽略的例子:
- 扩展性:在写码和设计的时候不仅要想到现在,而且要想到未来。对未来的预见是相当考验人的。很有可能当时预计会做的东西后来因为种种原因没做,围绕这个的设计做了无用功;或者当时觉得不会做的东西,后来临时插进来,又得大改系统。所以扩展性处理得好不好会带来很大的好处或者坏处。这个属于时间跨度上的技能点。
- 维护性:在写码和设计的时候不仅要想到自己维护这个项目,而且要想到别人。这个代码未来的自己或者别人来读,能不能读懂?有没有可能在架构上就让它容易理解?里面有什么坑,容易犯错的地方?能不能把这些地方变得不容易犯错(fool-proof)?有没有足够的测试来让外组的人也可以放心改代码而不用担心把系统搞崩?这个属于组别跨度上的技能点,也是做好做坏可以让一个项目成功或者失败的重要因素。
- 重复工作的自我救赎:软件工程非常强调自动化。手动操作不仅浪费时间,更重要的是可能引入错误。机器可以重复做一件事一万次而不犯错,但人做不到。所以对重复工作的敏感性,并且用自动化来消除重复工作对软件工程是非常重要的。这也是一件很难的事情,刚开始的时候总是手工操作占占主导,想要自动化,哪些重要要先做,哪些不重要可以放一放?有没有可能用一个系统满足多个需求?有没有可能在工作流程上加以创新让它更容易自动化?举个例子,如果好几个客户来说,我想要一匹更快的马/牛/羊,有没有可能他们想要的其实是个汽车?这些对改进整个项目的推进效率有着巨大的好处,一方面可以节约时间,一方面可以避免犯错和返工。这就是基础架构(infrastructure)的由来。
- 前面提到的执行力在软件工程里也是重要的,这里面最核心的是debug的能力。一个复杂系统基本上不可能像写leetcode一样,做出来就跟设计的完全一样一遍成功。面对输出和期待的不一样,如何去debug是每天都会遇到的事情。很多新手的方法是瞎猫撞死耗子(random debugging),拍脑袋想是不是这个原因,改一下,不行,那换个猜测,再改一下。这次可能运气好对了,可能还是不行。但老手就会用一些系统化的方法(principled way),通过观察和设计实验来把问题一步步分解定位,直到确定地找到原因。想一想随机查找和二分查找,就可以理解这二者在效率上的天差地别。
遗憾的是,上面的东西在流行的本科培养方案里都没有。这也是我为什么想写这篇文章,甚至想去大学教书的原因。不过这些技能在工作中都是可以学习的。一方面我们要温故知新,经常审视自己有没有做到这些方面,一方面也要善于学习,观察别人,尤其是自己佩服的人(或者自己讨厌的人),看他们是怎么处理这些方面的。说句题外话,很多同学觉得架构设计面试(system design interview)很难,不理解它到底想要什么样的答案,也可以对照这几条看看。
当然,技术不是工作的全部。如果只会技术的话,在职场上也是走不远的。技术领域已经这么复杂了,非技术领域要做的取舍就更多了。那什么素质是重要的呢?我的观点是这样的:
- 主动进取(take initiative):从学校进入公司,一个巨大的转变就是谁来推动所有的事情。在学校,学生的决策完全是被动的,按部就班上课考试就好。但在公司里这样“老板让干啥就保质保量干好”是远远不够的。更多的精力需要花在更深入的思考上,比如为什么我们这里花了一个月?流程还能不能优化?如果要优化的话需要做什么项目?这个项目最适合组里的哪个人?我如何说服他或者与他合作?我在这个过程中能得到什么好处?有没有办法让组里的利益和我的利益统一?在做一个项目(完成老板布置的任务)的过程中,可以做完就躺平,也可以深入思考挖掘其中的机遇。有没有这个动力来思考,有勇气来承担责任挑大梁,就是进取心的差异。
- 做决策:不论是技术决策还是非技术决策,这是一个核心能力。最简单的例子,高考填志愿就是一个会影响人一辈子的决策。选哪个offer,要不要转组,怎么跟老板提升职,都涉及到决策。它的重要性不言而喻。做决策最难的地方不是给定选项A和B,从里面选出来一个更好的,而是在意识到这里有一个决策可以做。比如估计不会有多少人在跟老板第一次1-1上就说升职的事情,但这不是分析了说升职和不说升职的利弊以后做出的决定,而是根本没想到可以上来就提升职。其实认真想一下的话,为什么不上来就提升职呢?第一次1-1就理解了升职的标准和流程也不是一个坏事。这个决策并不是无脑到可以直接略过(no brainer)。所以如果这里可以意识到有个决策可以做的话,也许就可以带来相当大的影响。当然很多这样的情况属于“我不知道我不知道”(unknown unknown),主要要靠别人(mentor,师兄师姐,老板)来提醒。此外,决策还有一个要点是,有时候看上去选项是A和B,但最终的最优解可能是A+B,或者C。保持创新,不拘泥于选项也是很重要的。
- 沟通:前面也说过,软件工程的一个核心任务就是实现跨组合作。这里面不可避免要牵扯到大量的沟通。具体怎么沟通怎么做ppt,都可以在实践中学习,这里不具体说。最重要的事情是,要去沟通,要意识到有这样一个选项。比如有了一个新想法,但不确定对组里有没有用,就去和相关的人包括但不限于老板聊。这样一方面讨论会带来启发,比如可能跟三四个组聊了以后,你发现大家都有这个需求,就确认了你的基本想法,但每个组的具体需求又有一些差异,说明设计还要做一些细化和改进。另一方面这也会建立个人品牌(branding)。人是敏感的,在跟你沟通几次以后就会知道你感兴趣的地方,擅长的地方在哪里。以后遇到这些东西,就会自然想来找你。当大家看到一个东西,第一个想到你的时候,你就是这个领域的专家,影响力和个人品牌也就这样建立起来了。
- “抢功劳(credit)”:一个自然的顾虑是,我跟别人讲了我的想法,有人把我的想法偷了怎么办?到最后明明是我提出来的,却给别人做了嫁衣。我的观点是,如果你的想法说了几句话就可以给人偷走,一方面说明这个想法很简单,反正没啥用;一方面说明这个领域很拥挤,别人已经有了把它做出来的技能点,就不适合做你深入耕耘的专家领域。这样“初始想法-沟通交流-寻找启发-推进执行”是一个长期迭代的过程,为他人贡献想法很常见,也是一件好事。毕竟credit是越分越多的,人更应该害怕没有灵感没办法给别人贡献credit,而不是害怕credit被人抢了。
说了这么多,有没有什么改进的方法呢?学而不思则罔,思而不学则殆。除了自己实践,有意识地练习(delibrate practice)以外,最重要的是要找个人带。很多事情自己悟要很久,但有个老师/老板/师兄师姐一句话可能就可以省很多时间。(当然反过来也是成立的,很多事情别人教不了,只能靠自己悟)这里主要讲两点,怎么跟老板相处和怎么找mentor。
- 老板:和老板相处的基本原则是,(在IT领域)老板和你是一条船上的。老板的核心任务就是让你开心,让你成长。这样你才能为他高效干活。所以在聊天的时候不用有什么顾虑,比如要让他知道你工作的动力是什么,是解决技术以后的快感,是看到用户真的受益,还是最实惠的加薪升职。这里没有错误的答案,关键是自己要弄清楚(很多人自己都不知道自己想要什么),然后跟老板沟通。这样老板才能更高效地让你开心。有什么计划,野心,工作中不爽的地方,也都可以谈。甚至“我怎么利用老板你这个资源”也是个非常好的话题。另外,老板也是人,有可能擅长做管理,也可能不擅长。所以也要保持对老板的管理,比如如果看到老板哪里做得和你想的不一样也可以提出来探讨,大家一起进步。如果理念实在不同也可以考虑转组(这也是一种选项)。
- mentor:老板一般是经理(manager track),行政事务比较多,所以对技术往往不那么熟练。这是正常的。(否则要你何用?)但这也意味着技术上的进步不太能指望老板。一般来说,在同组或者不同组找一个资深一点的工程师(senior IC)做mentor是一个很好的事情,一方面可以在技术上得到指导,一方面也可以得到其他方面的启发。找mentor最关键的其实是要能让对方有指导的欲望。不论是提出深刻的问题,还是探讨业界最新的技术,总之要保证自己做了功课,这些问题可以用到他的知识和经验,而不是在网上随手一搜就可以搜到的。这样往往可以实现双赢,两边都在交流中获得启发。
- 如何一对一会议(1-1 meeting):再多一句嘴,很多新人(甚至老人)一提到1-1 meeting就发憷,不知道说些什么,最后就变成了项目进度汇报的流水账。这其实是很不划算的。项目进度汇报完全可以用邮件或者聊天工具来弄,老板有问题可以再问你。但1-1是难得的和老板或者mentor直接接触的机会,要珍惜和思考,怎么用对自己最有利。这里给三个例子,也许有启发。第一是聊聊自己。谈一谈想要的东西(某个职位,工资,项目,资源),现在为什么还没有,怎么改进,探讨一下有没有什么项目又适合又可以进步。第二是聊聊组里,流程和制度有什么反馈,之前哪里让你不爽,哪里让你爽,为什么做这个人事变动,为什么做那个工程决策。第三是深入系统地聊聊项目,不是做进度汇报,而是介绍技术决策,多说“为什么”而不是“什么”,这对老板自己理解和帮你给他的老板吹牛是很有好处的。
总的来说,从学生到员工的转变是非常难的一件事,尤其是现在教育和行业的需要存在相当的脱节。如果单纯地依照惯性,就会自然地陷入唯技术论,无法理解职场上发生的各种事情。但只要怀有“这是个全新的世界,我需要学习”的心态,很容易就可以上手。毕竟也都是可以学习的技能。最后想重申一遍,我也是职场小透明一个,分享这些也是里面提到的“沟通交流”的一部分,把一些不成熟的想法放出来大家一起讨论,希望会有启发。里面的内容可能是错的,也欢迎进一步交流。
Comments