我在美团实习的经历与感想
Disclaimer:本文提及的内容有效范围仅限于后端业务开发岗位,甚至仅限于我所在部门,仅为个人体验与看法,请酌情参考。
上回说到经过了惨烈的春招实习求职之后,我终于获得了美团的实习 offer。现在,这份实习刚刚结束,趁热做个总结吧。
我实习是在单车部门(也就是摩拜)里的营销组,负责单车月卡套餐相关的服务,Java 后端开发。上回也说了,我其实是更想找 infra 的实习,不过仅靠小半年的积累(寒假才开始学),水平确实不太够看。不过虽然和一开始想的不一样,找了一份 Java 业务开发的工作,在自己的观察感受以及和同事、manager 的交流中,也算是另有一番体验和收获。
其实以前我的想法一直是想专心搞技术,觉得业务没意思,Java 没意思。不过最近想法逐渐有点改变。一方面是在大多数情况,对大多数人而言,技术还是要用来解决实际问题的,沉迷于技术要做好孤芳自赏的准备。另一方面,不要人云亦云,成为无脑吹或黑,还是要踏踏实实地学好东西。我觉得从个人的审美角度喜欢某些技术,有理有据的知道一些东西的优点一些东西的缺点,去推广自己喜欢的技术,再或者纯粹的自娱自乐都是没问题的。就是不要产生一些无意义的优越感,成为半壶水的人,不要陷入无聊且无休止的争论之中,成为跟风的小鬼。
收获
总的来说,我觉得实习对我来说是进一步祛魅的过程。虽然我一直以来也并没有对大公司有迷信、崇拜等感情,不过亲自经历过大公司做的事以后,我对工业界项目、大公司的开发流程等东西能够更客观的看待。
大公司的开发流程
实际的企业级项目经历、实际的开发流程可以算是我实习想要学习体验的一大重点。
不同于学校里写代码的随意(虽然我在学校里也并没有多少正经的写代码经历),大公司里确实还是有一套完整的流程。简单的说,有这么一些步骤:
- (产品经理)提出需求
- 多端(前后端、不同的服务)在开发专用环境分别开发,分别自测
- 多端联调
- 提测(让专门的测试人员测),在测试专用环境测试
- 在预发布环境(和线上生产环境一样的环境,有的地方可能叫 staging)测试
- 跑 CI (编译打包、生成镜像、自动化测试等)
- 上线
大概的情况是这样,不过可能有遗漏,也可能视情况有变化,比如还有需求评审、技术评审会议,有时候可能开发自己提需求(尤其是技术需求),另外顺序可能也会有变化。
具体聊聊其中几个点:
前后端分开
听说只有国内会区分前/后端工程师这样的岗位,国外大厂通常都是只有统一的 software engineer,一个工程师要负责项目 end-to-end 的全流程。相应的,“前后端联调”也是一个中国特色的词,国外貌似没有相应的概念。不分开的好处是负责项目的程序员了解项目的方方面面,还能减少沟通成本;分开自然是各司其职,专业化更强。由于我对前端一窍不通,也不太好评价哪种更好。
开发测试分开
还听说国外大厂如 Facebook,Google,微软等都几乎没有专职的测试(SDET/QA),或者曾经有后来没了,功能测试都是由开发人员自己来完成。
是否需要专职的测试也是一件见仁见智的事情,就不细谈了,说几点我自己感受到的。
- 专职测试确实可以起到兜底的作用,但是程序员可能也会因此产生侥幸心理,让别人兜底。但自己写的代码还是自己更了解,尤其是遇到技术需求,或者写的一些通用公共函数,开发自己写单元测试应该更加高效与可靠。
- 提测会 block 项目进展,要等测试人员的排期。不太紧急的需求,尤其是技术需求(比如重构代码)可能会卡很久。虽然也有免测上线的机制,可以绕过测试。
代码质量
我感觉公司项目在代码质量方面要求不是特别高,还有不少提升的空间。有这么一些方面:
- 单元测试不做要求。众所周知测试不能保证程序的正确性,所以我们就不写测试了(×)。我觉得单元测试仍然是成本较低、效果又不错的检查正确性的方法,而且在一定程度上可以充当粗糙的 specification(测试驱动开发了解一下)。
- Code review 有,但不太严格。不过我写了一堆 NPE 被 review 出来了(逃
- 没有供开发阶段用的 CI。有一些打包、部署的 CI,但没有比如静态分析工具、lint 之类的东西。在上线前需要跑自动化测试的 CI,但日常开发好像没什么人用(我用过一次),测试用例也是 QA 负责的,而不是程序员自己写的。
- Legacy code 比较不忍直视……
和 manager 聊到这个话题的时候他也说确实是这样,这是因为互联网公司在快速发展的过程中难免会这样,业务要快速迭代,快速上线验证,比较糙快猛,等到相对平稳一点的阶段就会放慢一点速度,开始重视质量。我感觉这种说法确实也很有道理,典型的像 Facebook “move fast” 的文化:
同时为了求快,我们会放弃掉一部分不确定的复杂性,优先把确定必须要做的做出来。例如说,这个新产品如何支持某某规模的高并发?发布后有没有几万月活都很难说,还想什么高并发,这个问题暂时不在系统设计中考虑。真的规模上来后,我们再重新设计系统。留存做不起来,月活上不去,说这个没意思。
来源:https://www.zhihu.com/question/339135205/answer/862196844
当然 move fast 的代价就是可能产生 legacy code 甚至 tech debt。既然之后一定会重构,为什么不一开始就尽量写好一点?我觉得就还是 tradeoff,尽量做好一点,但不要推敲半天就写个两三行“优雅”的代码(说的就是我)。
我觉得代码质量、代码风格这种问题可能很看组,得看 leader 的要求品味,可能是自上而下的。另外还有业务开发和底层技术毕竟还是不一样,复杂性可能在于业务逻辑,所以需要同样懂这个业务的人才能更好地帮你 code review。像底层技术的话就更关注代码本身,而且迭代也没有业务那么快,相对稳定,所以 code review、代码质量的要求都会更高一点。
关于业务思维
有一个老生常谈的话题,那就是业务思维很重要。我觉得业务思维就是懂产品、用户、行业的痛点,懂商业。为什么程序员要懂业务?我觉得这就和前后端要不要分开有点像,一个程序员要懂不仅程序的全流程,还有产品的完整生命周期。下面这段话对我挺有启发:
还有一个互相对不上的地方在于对技术 leader 的期望。在 Facebook 习惯了对 E5+ 有产品甚至是业务的期望,也就是说不能单纯地解决业务和产品丢过来的技术难题,还要保证只解决正确且重要的问题,这些问题被解决后要能帮助产品和业务成功。如果不能帮助产品和业务成功,解决的技术问题再难也等于白费。如果能够帮助产品和业务获得巨大的成功,就算所需要用到的技术很简单也会得到认可。
感觉这就跟中国公司习惯的做法很不一致。中国公司还是习惯于技术人员就崇尚技术,作为技术 leader 你对产品和业务的话语权十分有限,还是 PM 和其它角色掌管着产品和业务的成败。我觉得这样的领域壁垒对我未来创业没什么帮助,因为创业就必须让技术和产品彻底服务于商业,一个人必须从头到尾地理解技术、产品和业务。
来源:https://www.zhihu.com/question/339135205/answer/862196844
与此相关的一个话题是程序员的绩效怎么评。考评总要看看成果产出的,那正如上述所说,成败要看产品和业务,如果由 PM 全权负责,程序员只负责完成需求,那纵使代码写的再好,命运还是掌握在别人的手上,绩效好不好看分到的项目好不好,得看运气了。Manger 也说他一直希望大家不要只局限于、满足于完成产品的需求,要有自己的思考,考虑产品、业务的目标。
但这听起来还是有点虚,而且等级低的程序员也没啥话语权,所以只能先完成好手头的事情,在此同时多观察、思考,等证明了能力以后逐渐获得更多地资源来做更多的事。业务思维应该是在职业生涯逐渐发展的过程中逐渐变得重要起来的一个东西。
一直以来,我也是一个只(想)关注技术的人,还不知道未来到底会选择业务还是技术哪个方向,但无论哪条路,业务思维应该是我未来会纳入考虑的点。
业务开发需要的技术
在实际体验了以后,我确实感觉到,干业务开发的技术门槛真的不高。一方面我相关的技术栈完全没学过,没写过 Java,但是看看代码很快就能上手了。另一方面,我觉得我继续读书深造或者学更多的技术,对业务开发好像也没有特别直接的帮助,相较之下实际工作经验会更有帮助。
当然,想级别往上升,对技术的要求肯定还是不止于此的。可能提升的方面比如有各种框架、中间件的使用及原理。但我感觉这里面的技术点其实还是很有限的。总共就那么多东西,而且学多了以后很多是相通的,另外业务开发对 under the hood 底层原理的掌握要求可能也很有限,大概知道架构设计就行了,不怎么会遇到 devil in the detail 的实现细节问题。
这个暑假我实习的时候下班回家在搞托福和 side project,所以在 Java、中间件方面的知识没怎么学习。虽然我现在这些东西确实懂的很少,但我对我的学习能力还是很有自信的,相信正式工作以后这些都能慢慢学掉。
业务开发需要的其他技术能力,或者说区分度可能还体现在规模大了以后系统怎么扩展、容错,还有包括多个子系统的大型系统的架构设计等等方面。
总的来说,一个新人程序员如果只写写业务逻辑,那确实门槛不高。如果只满足于写业务逻辑,也很难有提高。所以需要在工作中、工作外多积累技术知识。年轻的时候多积累点技术内功总不会有错,有点算是立身之本的意思。但是积累多了,瓶颈来的也挺快,成为比较 senior 的程序员以后,技术的作用、区分度就小了,需要考虑更多技术之外的问题。领域知识比技术知识更重要。
顺带一提,感觉现在 infra 也是做的越来越好了,一方面是前端界面功能强大,点点就行。另一方面是力争做到“业务透明”的体验,比如业务开发的程序员可以假设数据库可以无限水平扩容,完全不需要考虑底层的细节,不需要考虑数据库分表分片这种侵入业务的 dirty 方案,只要专心写业务逻辑就好。听说 Google 的 infra 在这上面的体验非常出色。假设未来 infra 做的体验越来越好,那程序员确实要做的事情也就越来越少,门槛也越来越低了(失业预警)。
遗憾
这次实习时间不长,只有十周,还是留下了一些遗憾吧。
- 做的东西比较多而杂,看代码、改代码比较多,写的不算多。没有体验到独立负责一个逻辑复杂一点的功能,从设计模块到开发的过程。
- 虽然大大小小的坑排查了不少,不过还是缺乏一点严肃的线上排查问题 debug 的经验。