美团点评半年实习感悟
大三下有幸到了美团点评实习。在这半年的时间里,经过导师和主管的悉心教导,无论是专业技能还是开发技巧方面都有很大的提升。恰好午休时间,随便写写,总结一下这半年的收获吧。不留下篇文章总感觉有点遗憾。
一、 初到美团
刚入职的时候,其实自己非常虚,因为懂的东西不多。投简历的时候,自己只是做过一些Android的Demo,然后就掌握了一点课堂上的知识吧。(计算机网络,数据结构等等)面试的时候,也是面试了这些,很幸运主管让我通过了面试。后来被告知入职之后要学习Spring来开发,虽然自己以前写过一些Servlet的小程序,但是框架、控制反转、依赖注入和切面这些东西真的是一点都不理解。怎么看网上的博客也不懂,就是和JavaSE中间隔了一堵墙的感觉。
入职之后,美团给开发配发的是15寸的mac pro,虽然当时刚使用mac不适应,但是现在看来,mac的确很适合开发工作。刚开始的一周主要是熟悉环境,熟悉mac的操作,熟悉美团点评的内部系统等等。值得一提的是,美团的内部应用很多,并且在工作中很实用。内部交流有专门的应用,类似微信,功能强大。最近还出了一个话题社区,和知乎差不多。可以说现在主流的互联网产品,美团点评都有相应的内部应用。有一点比较麻烦但是很重要的就是每天要发工作日报,每一周要发周报。对于记录和思考自己的工作,还是有很大帮助的。
熟悉了内部环境,就要开始学习一下开发相关的知识了。有两点让我感触很深,一个是开发使用IDEA,第二个是Git。说一下之前我是这么写程序的吧,用Eclipse,写好类,在Main函数里面写写几句话就完了,然后也没有什么保存的工作。下次继续开发就找到项目存储的地方打开项目即可。所以在那个时候,我并不理解Git的作用,不就是远程保存一下代码嘛。但实际上,开发工作并不是一个人完成的,不可能大家进度都一样,也不可能保存在一个硬盘。难道别人开发的时候,你就把项目拷给别人添加完代码自己再弄吗?在导师的指导下,我学习了IDEA和Git。
IDEA是主流的Java开发IDE,用过AndroidStudio的就明白了,同一个公司的。主要是好用,能集成的东西很多,个人感觉比Eclipse好用。
至于Git,基本上每天都会接触到。最简单的用处就是能够保存代码,创建了Git项目后,pull到本地,然后编写完代码后push上去。这样就算你电脑进水了坏了开不了了,换了一台电脑,你的项目还在的。第二个用处,当一个项目,已经在线上运行了,但是你要开发一个新功能,怎么办呢?你不可能在现有的项目上改啊,因为改了代码重新编译,服务肯定会断掉的,会影响到使用的用户们。还有就是改错了怎么办呢?Git提供了一个办法就是,新开一个dev分支,该分支上的代码和master分支上一样的,你可以在dev分支上随意改。Dev就算改错了,还能回滚到以前的版本。当确认无误了,可以将dev的代码合并到master分支上。当然了,大项目的合并是有权限的,master分支不能让你随便合并。你可以提一个合并的请求,然后在Git上能看到你修改的地方。当管理员查看的你的代码之后,确认没有问题,他就会让合并通过。如果没有冲突,这样新的功能就添加上去了。第三个用处就是在服务器部署很方便。不需要从本地拷贝代码到服务器,只需要从git上pull代码下来,直接跑就可以了。当然,重新编译启动项目要选在使用者较少的时候。这就能理解为什么一些游戏都选在晚上更新维护了吧。主要用到的地方,暂时想到的就这么多吧。说实话,当时我看Git教程也非常迷糊根本不懂,在工作中慢慢接触就理解明白了。
二、 接触项目
说起来非常幸运,实习的任务就是和导师一起负责美团点评·众测平台的后端开发。这个项目主要是让用户通过这个平台提交试用美团点评旗下APP发现的BUG与建议,然后相关业务线的QA能在后台处理相关的问题。在我实习结束之前,已经进行过四次的线下众测活动和三次版本迭代。目前的运营方式就是让报名参与众测活动用户(非对应QA)在限定的时间内去测试某一业务组提供的一个新应用包,提交自己发现的BUG,然后给予相应的积分奖励。让我感到非常惊讶的是,每次活动结束完,都能发现一百多个有效BUG。不敢相信一个待上线的应用能有这么多的Bug,第二个就是感叹参与的用户发现Bug能力太强了。
为什么说幸运呢,我感觉有两点。第一点是这个项目覆盖面很广,基本上美团点评线上应用很多都通过了众测平台来收集发现BUG。是个影响面广并且很实用的项目。自己负责开发的项目这么多人用到,很有成就感。第二点就是,它不是一个很难的项目。麻雀虽小五脏俱全,现在想起来,对于我这种刚起步的Spring学习者来说真的最适合不过了。
说一下项目用到的框架:Spring+SpringMVC+Mybatis,构建项目使用了Gradle,数据库使用MySQL,服务器是jetty,部署于美团点评的线上机器。接下来就简单说下每个框架的用处吧。
Gradle:最简单的说法,就是管理依赖。总不能每用到一个jar包,就去网上下载,或者在美团点评的库上下载,拉进项目里面吧。使用gradle,可以在配置文件里面写几句话就能管理一堆相应的依赖了。还有一个就是gradle和jetty的集成,在服务器上,只要一句命令:gradle apprun,项目就跑起来了。非常方便实用。
Spring:依赖注入/切面。这个用处太广泛常见了,导致我不知道怎么说(逃
SpringMVC:以前处理前端请求的服务端,都是用Servlet,代码冗长。SpringMVC是基于Servlet的框架,对于前端的请求,只要编写相应的Controller,匹配url,然后在函数里面进行相应的处理即可,非常简单。SpringMVC的返回也非常有意思,可以自定义一个Result类,填入相关数据,然后转换为Json返回到前端。
Mybatis:以前使用数据库,要写一堆冗长的JDBC的代码,而且拿到了数据,处理起来也很麻烦。使用了Mybatis,只需要在Mapper编写相关的SQL即可。
以上的框架,我刚开始学习的时候,都是一脸懵逼,完全看不懂,从Spring开始,是完全不理解的。但是接触了项目,在经过导师对我一堆幼稚问题的耐心讲解,也就慢慢懂了。在这就不讲解这些框架了。
在项目里面,除了框架的学习,还有一点就是项目里面结构的分层。最著名的应该是MVC模式了。但是实际上,分得要更细一点。在众测里面,简单的概括是:
Bean:用到的类。
Controller:处理请求。
Config:配置类(没有用xml,不太直观
Service:服务类(让controller调用)
ServiceImpl:服务类的实现(逻辑+dao)
Dao:操纵数据库的方法。
Mapper:SQL语句,其实就是dao的实现。
如果不采取分层的话,项目代码看起来就非常乱。比如Controller里面,逻辑应该尽量简单,比如说应该只是看看执行了什么Service。如果把Service的实现什么的都放进去,一个controller就非常的复杂,排查问题也很困难。对于分层,印象深刻。因为第一个版本我写得太乱。第二次改版的时候,导师让我把代码赶紧重构掉。
三、 添加功能
众测项目上线期间,导师还给我安排了一个任务,就是给美团点评·云测平台添加设备预约功能。云测平台是一个能个各个业务线提供真机自动化测试的项目,用户可以自己上传相关的app,相关的测试项,然后这边的机器就会帮你跑app,发现bug,生成报告给你。另外还有一个点评侧的项目phoneDP是可以在线调试Android设备的(当初口号是让QA
不需要真实的Android设备在手即可工作),用到的框架是STF。因为云测平台下有大量的设备,自然也能通过phoneDP占用。但是之前没有预约的功能,用户如果想操作指定的机型的话,只能定期去看看机型有没有在跑自动化测试任务了。因此,有了预约这个需求。
至于预约流程,因为篇幅原因,简单讲讲自己的思考感悟吧。
首先肯定是要看云测项目的代码的。这一点很重要,锻炼了自己看代码的能力。遇到函数和类看不懂,就command+单击点进去,一层层深入去看,刨根问底。我发现,这个项目很有意思,也可以算一个学习的案例。云测平台直接分成了3个项目:Core/portal/slave。顾名思义,core就是要使用的核心代码。比如用到的类(bean)。Portal就是入口,也是项目的前端。当然不是前端页面的意思。而是这个项目处理了前端的所有操作。并用于向slave推送任务。Slave:就是处理具体任务的项目。
前端负责生成任务,并给slave推送。如果没有推送,slave会定期扫描等待的任务。如果等待的任务需求的设备空闲,那么任务将会执行。有一个小细节很有意思,slave的扫描,不是固定时间的。一段时间内,扫描没有能够执行的任务,那么扫描线程将会睡眠。睡眠时间是上一次的两倍。就是说第一次睡眠10s之后扫描没有任务可以执行,将会睡眠20s再次扫描,以此类推,当发现有任务执行之后,睡眠时间刷新回到10s。这样做的好处就是,不用一直扫描,浪费cpu。因为一个任务一般执行时间是很长的,所以一次扫描到全部都执行不了后,其实也是意味着在往后一段时间内都执行不了。
进入开发阶段,首先就是要搞清楚,一个任务,portal是怎么生成的,然后slave又是怎么扫描的,扫描到了之后,进行了什么操作。两个项目过程中,又用到了core里面的什么bean。这个部分就搞了我很久。
其次,要构思预约的流程。Phonedp远程调试插进来的任务,和用户或系统提交的不一样,会有特定的标志。当初的想法比较简单。任务完成的时候,会调用callback的函数,只要在callback里面,检查有没有该设备预约,有的话,马上占用设备,通知用户就完了嘛。
于是我创建了预约表,记录预约情况。还编写了检查预约、执行预约、通知用户的代码。结果一上线,完了,有问题。为什么呢,任务执行完,执行callback的时候,你去检查预约表。但是这个时候,是有另一个线程是在扫描等待任务的。就是说查预约表,和检测等待任务和空闲设备的线程,有冲突。这样就预约在执行状态了,设备却被其他任务抢了。所以这个构思不行啊,得重写。
最后和导师讨论,有一点让我收获很大:编写侵入性小的代码。就是说,这个预约功能,最好也看成一个任务,和之前的任务一样,只要分一个类别区别就好了。这样的话,线程扫描任务的时候,因为排队,会先扫到预约任务,不会冲突。然后自己定义扫描到的预约任务要进行什么操作就可以了。最后也这么实现了,的确没问题。
编写这个功能的时候,因为众测得需求还有自己拖拖拉拉和不熟悉业务,弄了挺久的。但是这个也让我受益匪浅,比如查看Mysql错误日志,打印日志,部署STF环境,和上海侧的同学讨论接口排期什么的,还有很多零零散散却非常实用的知识。对了,还有很多细节才是重中之重,比如很多出错的情况之类的,但是脱离了项目,也没什么讲的了。
四、感谢
在这半年的实习里面,我的主管和我的导师给我很大的帮助。工作中我经常问一些非常简单的幼稚的问题,我的导师都给我一一解答,而且语言组织得很好,我都听明白了。此外还有很多像环境配置,启动项目之类的问题,我的导师刚开始也一一操作给我看。看了他怎么弄,听了他的讲解,然后我自己再照葫芦画瓢。自己弄得多了,再去百度google等地方弄清楚原理,满满就懂了。当时我也是对依赖注入啊什么的概念完全不懂,工作中接触多了,满满就理解了,所以不要太局限于书本,要多动手实践。“纸上得来终觉浅,绝知此事要躬行”,说的就是这个道理吧。还有就是我经常问我导师同事问题,他也细心给我解答了。还有我们的PM,平时相处的也很好,完全没有像知乎上“程序员和PM是死对头”那种感觉。在美团的半年时间里,参加了部门的年会,组内的两次团建,平常同事们也一起吃饭,相处得还是挺愉快的,消除了自己第一次“北漂”的孤独感。
经过了这次实习,学到了很多知识,同时也开阔了眼界,看到了自己的不足之处。大四即将到来,打算给大四定一个小计划:1、保持coding。刷leetcode上的题,保证自己的码感。2、深化自己实习学到的知识,编写一个简单的MVC框架,能够支持依赖注入、切面、请求分发和处理就好。造轮子能够提高自己的代码水平,顺便把这个作为自己的毕业设计,一举两得。半年的实习,感觉自己水平提高了不少。希望大四完结后,对于现在的自己,能有更大的进步。