大三下有幸到了美團(tuán)點(diǎn)評(píng)實(shí)習(xí)。在這半年的時(shí)間里,經(jīng)過(guò)導(dǎo)師和主管的悉心教導(dǎo),無(wú)論是專(zhuān)業(yè)技能還是開(kāi)發(fā)技巧方面都有很大的提升。恰好午休時(shí)間,隨便寫(xiě)寫(xiě),總結(jié)一下這半年的收獲吧。不留下篇文章總感覺(jué)有點(diǎn)遺憾。
一、 初到美團(tuán)
  剛?cè)肼毜臅r(shí)候,其實(shí)自己非常虛,因?yàn)槎臇|西不多。投簡(jiǎn)歷的時(shí)候,自己只是做過(guò)一些Android的Demo,然后就掌握了一點(diǎn)課堂上的知識(shí)吧。(計(jì)算機(jī)網(wǎng)絡(luò),數(shù)據(jù)結(jié)構(gòu)等等)面試的時(shí)候,也是面試了這些,很幸運(yùn)主管讓我通過(guò)了面試。后來(lái)被告知入職之后要學(xué)習(xí)Spring來(lái)開(kāi)發(fā),雖然自己以前寫(xiě)過(guò)一些Servlet的小程序,但是框架、控制反轉(zhuǎn)、依賴(lài)注入和切面這些東西真的是一點(diǎn)都不理解。怎么看網(wǎng)上的博客也不懂,就是和JavaSE中間隔了一堵墻的感覺(jué)。
  入職之后,美團(tuán)給開(kāi)發(fā)配發(fā)的是15寸的mac pro,雖然當(dāng)時(shí)剛使用mac不適應(yīng),但是現(xiàn)在看來(lái),mac的確很適合開(kāi)發(fā)工作。剛開(kāi)始的一周主要是熟悉環(huán)境,熟悉mac的操作,熟悉美團(tuán)點(diǎn)評(píng)的內(nèi)部系統(tǒng)等等。值得一提的是,美團(tuán)的內(nèi)部應(yīng)用很多,并且在工作中很實(shí)用。內(nèi)部交流有專(zhuān)門(mén)的應(yīng)用,類(lèi)似微信,功能強(qiáng)大。最近還出了一個(gè)話(huà)題社區(qū),和知乎差不多??梢哉f(shuō)現(xiàn)在主流的互聯(lián)網(wǎng)產(chǎn)品,美團(tuán)點(diǎn)評(píng)都有相應(yīng)的內(nèi)部應(yīng)用。有一點(diǎn)比較麻煩但是很重要的就是每天要發(fā)工作日?qǐng)?bào),每一周要發(fā)周報(bào)。對(duì)于記錄和思考自己的工作,還是有很大幫助的。
  熟悉了內(nèi)部環(huán)境,就要開(kāi)始學(xué)習(xí)一下開(kāi)發(fā)相關(guān)的知識(shí)了。有兩點(diǎn)讓我感觸很深,一個(gè)是開(kāi)發(fā)使用IDEA,第二個(gè)是Git。說(shuō)一下之前我是這么寫(xiě)程序的吧,用Eclipse,寫(xiě)好類(lèi),在Main函數(shù)里面寫(xiě)寫(xiě)幾句話(huà)就完了,然后也沒(méi)有什么保存的工作。下次繼續(xù)開(kāi)發(fā)就找到項(xiàng)目存儲(chǔ)的地方打開(kāi)項(xiàng)目即可。所以在那個(gè)時(shí)候,我并不理解Git的作用,不就是遠(yuǎn)程保存一下代碼嘛。但實(shí)際上,開(kāi)發(fā)工作并不是一個(gè)人完成的,不可能大家進(jìn)度都一樣,也不可能保存在一個(gè)硬盤(pán)。難道別人開(kāi)發(fā)的時(shí)候,你就把項(xiàng)目拷給別人添加完代碼自己再弄嗎?在導(dǎo)師的指導(dǎo)下,我學(xué)習(xí)了IDEA和Git。
  IDEA是主流的Java開(kāi)發(fā)IDE,用過(guò)AndroidStudio的就明白了,同一個(gè)公司的。主要是好用,能集成的東西很多,個(gè)人感覺(jué)比Eclipse好用。
  至于Git,基本上每天都會(huì)接觸到。最簡(jiǎn)單的用處就是能夠保存代碼,創(chuàng)建了Git項(xiàng)目后,pull到本地,然后編寫(xiě)完代碼后push上去。這樣就算你電腦進(jìn)水了壞了開(kāi)不了了,換了一臺(tái)電腦,你的項(xiàng)目還在的。第二個(gè)用處,當(dāng)一個(gè)項(xiàng)目,已經(jīng)在線(xiàn)上運(yùn)行了,但是你要開(kāi)發(fā)一個(gè)新功能,怎么辦呢?你不可能在現(xiàn)有的項(xiàng)目上改啊,因?yàn)楦牧舜a重新編譯,服務(wù)肯定會(huì)斷掉的,會(huì)影響到使用的用戶(hù)們。還有就是改錯(cuò)了怎么辦呢?Git提供了一個(gè)辦法就是,新開(kāi)一個(gè)dev分支,該分支上的代碼和master分支上一樣的,你可以在dev分支上隨意改。Dev就算改錯(cuò)了,還能回滾到以前的版本。當(dāng)確認(rèn)無(wú)誤了,可以將dev的代碼合并到master分支上。當(dāng)然了,大項(xiàng)目的合并是有權(quán)限的,master分支不能讓你隨便合并。你可以提一個(gè)合并的請(qǐng)求,然后在Git上能看到你修改的地方。當(dāng)管理員查看的你的代碼之后,確認(rèn)沒(méi)有問(wèn)題,他就會(huì)讓合并通過(guò)。如果沒(méi)有沖突,這樣新的功能就添加上去了。第三個(gè)用處就是在服務(wù)器部署很方便。不需要從本地拷貝代碼到服務(wù)器,只需要從git上pull代碼下來(lái),直接跑就可以了。當(dāng)然,重新編譯啟動(dòng)項(xiàng)目要選在使用者較少的時(shí)候。這就能理解為什么一些游戲都選在晚上更新維護(hù)了吧。主要用到的地方,暫時(shí)想到的就這么多吧。說(shuō)實(shí)話(huà),當(dāng)時(shí)我看Git教程也非常迷糊根本不懂,在工作中慢慢接觸就理解明白了。

二、 接觸項(xiàng)目
  說(shuō)起來(lái)非常幸運(yùn),實(shí)習(xí)的任務(wù)就是和導(dǎo)師一起負(fù)責(zé)美團(tuán)點(diǎn)評(píng)·眾測(cè)平臺(tái)的后端開(kāi)發(fā)。這個(gè)項(xiàng)目主要是讓用戶(hù)通過(guò)這個(gè)平臺(tái)提交試用美團(tuán)點(diǎn)評(píng)旗下APP發(fā)現(xiàn)的BUG與建議,然后相關(guān)業(yè)務(wù)線(xiàn)的QA能在后臺(tái)處理相關(guān)的問(wèn)題。在我實(shí)習(xí)結(jié)束之前,已經(jīng)進(jìn)行過(guò)四次的線(xiàn)下眾測(cè)活動(dòng)和三次版本迭代。目前的運(yùn)營(yíng)方式就是讓報(bào)名參與眾測(cè)活動(dòng)用戶(hù)(非對(duì)應(yīng)QA)在限定的時(shí)間內(nèi)去測(cè)試某一業(yè)務(wù)組提供的一個(gè)新應(yīng)用包,提交自己發(fā)現(xiàn)的BUG,然后給予相應(yīng)的積分獎(jiǎng)勵(lì)。讓我感到非常驚訝的是,每次活動(dòng)結(jié)束完,都能發(fā)現(xiàn)一百多個(gè)有效BUG。不敢相信一個(gè)待上線(xiàn)的應(yīng)用能有這么多的Bug,第二個(gè)就是感嘆參與的用戶(hù)發(fā)現(xiàn)Bug能力太強(qiáng)了。
  為什么說(shuō)幸運(yùn)呢,我感覺(jué)有兩點(diǎn)。第一點(diǎn)是這個(gè)項(xiàng)目覆蓋面很廣,基本上美團(tuán)點(diǎn)評(píng)線(xiàn)上應(yīng)用很多都通過(guò)了眾測(cè)平臺(tái)來(lái)收集發(fā)現(xiàn)BUG。是個(gè)影響面廣并且很實(shí)用的項(xiàng)目。自己負(fù)責(zé)開(kāi)發(fā)的項(xiàng)目這么多人用到,很有成就感。第二點(diǎn)就是,它不是一個(gè)很難的項(xiàng)目。麻雀雖小五臟俱全,現(xiàn)在想起來(lái),對(duì)于我這種剛起步的Spring學(xué)習(xí)者來(lái)說(shuō)真的最適合不過(guò)了。
  說(shuō)一下項(xiàng)目用到的框架:Spring+SpringMVC+Mybatis,構(gòu)建項(xiàng)目使用了Gradle,數(shù)據(jù)庫(kù)使用MySQL,服務(wù)器是jetty,部署于美團(tuán)點(diǎn)評(píng)的線(xiàn)上機(jī)器。接下來(lái)就簡(jiǎn)單說(shuō)下每個(gè)框架的用處吧。
  Gradle:最簡(jiǎn)單的說(shuō)法,就是管理依賴(lài)??偛荒苊坑玫揭粋€(gè)jar包,就去網(wǎng)上下載,或者在美團(tuán)點(diǎn)評(píng)的庫(kù)上下載,拉進(jìn)項(xiàng)目里面吧。使用gradle,可以在配置文件里面寫(xiě)幾句話(huà)就能管理一堆相應(yīng)的依賴(lài)了。還有一個(gè)就是gradle和jetty的集成,在服務(wù)器上,只要一句命令:gradle apprun,項(xiàng)目就跑起來(lái)了。非常方便實(shí)用。
  Spring:依賴(lài)注入/切面。這個(gè)用處太廣泛常見(jiàn)了,導(dǎo)致我不知道怎么說(shuō)(逃
  SpringMVC:以前處理前端請(qǐng)求的服務(wù)端,都是用Servlet,代碼冗長(zhǎng)。SpringMVC是基于Servlet的框架,對(duì)于前端的請(qǐng)求,只要編寫(xiě)相應(yīng)的Controller,匹配url,然后在函數(shù)里面進(jìn)行相應(yīng)的處理即可,非常簡(jiǎn)單。SpringMVC的返回也非常有意思,可以自定義一個(gè)Result類(lèi),填入相關(guān)數(shù)據(jù),然后轉(zhuǎn)換為Json返回到前端。
  Mybatis:以前使用數(shù)據(jù)庫(kù),要寫(xiě)一堆冗長(zhǎng)的JDBC的代碼,而且拿到了數(shù)據(jù),處理起來(lái)也很麻煩。使用了Mybatis,只需要在Mapper編寫(xiě)相關(guān)的SQL即可。
  以上的框架,我剛開(kāi)始學(xué)習(xí)的時(shí)候,都是一臉懵逼,完全看不懂,從Spring開(kāi)始,是完全不理解的。但是接觸了項(xiàng)目,在經(jīng)過(guò)導(dǎo)師對(duì)我一堆幼稚問(wèn)題的耐心講解,也就慢慢懂了。在這就不講解這些框架了。
  在項(xiàng)目里面,除了框架的學(xué)習(xí),還有一點(diǎn)就是項(xiàng)目里面結(jié)構(gòu)的分層。最著名的應(yīng)該是MVC模式了。但是實(shí)際上,分得要更細(xì)一點(diǎn)。在眾測(cè)里面,簡(jiǎn)單的概括是:
  Bean:用到的類(lèi)。
  Controller:處理請(qǐng)求。
  Config:配置類(lèi)(沒(méi)有用xml,不太直觀(guān)
  Service:服務(wù)類(lèi)(讓controller調(diào)用)
  ServiceImpl:服務(wù)類(lèi)的實(shí)現(xiàn)(邏輯+dao)
  Dao:操縱數(shù)據(jù)庫(kù)的方法。
  Mapper:SQL語(yǔ)句,其實(shí)就是dao的實(shí)現(xiàn)。
  如果不采取分層的話(huà),項(xiàng)目代碼看起來(lái)就非常亂。比如Controller里面,邏輯應(yīng)該盡量簡(jiǎn)單,比如說(shuō)應(yīng)該只是看看執(zhí)行了什么Service。如果把Service的實(shí)現(xiàn)什么的都放進(jìn)去,一個(gè)controller就非常的復(fù)雜,排查問(wèn)題也很困難。對(duì)于分層,印象深刻。因?yàn)榈谝粋€(gè)版本我寫(xiě)得太亂。第二次改版的時(shí)候,導(dǎo)師讓我把代碼趕緊重構(gòu)掉。

三、 添加功能
  眾測(cè)項(xiàng)目上線(xiàn)期間,導(dǎo)師還給我安排了一個(gè)任務(wù),就是給美團(tuán)點(diǎn)評(píng)·云測(cè)平臺(tái)添加設(shè)備預(yù)約功能。云測(cè)平臺(tái)是一個(gè)能個(gè)各個(gè)業(yè)務(wù)線(xiàn)提供真機(jī)自動(dòng)化測(cè)試的項(xiàng)目,用戶(hù)可以自己上傳相關(guān)的app,相關(guān)的測(cè)試項(xiàng),然后這邊的機(jī)器就會(huì)幫你跑app,發(fā)現(xiàn)bug,生成報(bào)告給你。另外還有一個(gè)點(diǎn)評(píng)側(cè)的項(xiàng)目phoneDP是可以在線(xiàn)調(diào)試Android設(shè)備的(當(dāng)初口號(hào)是讓QA
不需要真實(shí)的Android設(shè)備在手即可工作),用到的框架是STF。因?yàn)樵茰y(cè)平臺(tái)下有大量的設(shè)備,自然也能通過(guò)phoneDP占用。但是之前沒(méi)有預(yù)約的功能,用戶(hù)如果想操作指定的機(jī)型的話(huà),只能定期去看看機(jī)型有沒(méi)有在跑自動(dòng)化測(cè)試任務(wù)了。因此,有了預(yù)約這個(gè)需求。
  至于預(yù)約流程,因?yàn)槠颍?jiǎn)單講講自己的思考感悟吧。
  首先肯定是要看云測(cè)項(xiàng)目的代碼的。這一點(diǎn)很重要,鍛煉了自己看代碼的能力。遇到函數(shù)和類(lèi)看不懂,就command+單擊點(diǎn)進(jìn)去,一層層深入去看,刨根問(wèn)底。我發(fā)現(xiàn),這個(gè)項(xiàng)目很有意思,也可以算一個(gè)學(xué)習(xí)的案例。云測(cè)平臺(tái)直接分成了3個(gè)項(xiàng)目:Core/portal/slave。顧名思義,core就是要使用的核心代碼。比如用到的類(lèi)(bean)。Portal就是入口,也是項(xiàng)目的前端。當(dāng)然不是前端頁(yè)面的意思。而是這個(gè)項(xiàng)目處理了前端的所有操作。并用于向slave推送任務(wù)。Slave:就是處理具體任務(wù)的項(xiàng)目。
前端負(fù)責(zé)生成任務(wù),并給slave推送。如果沒(méi)有推送,slave會(huì)定期掃描等待的任務(wù)。如果等待的任務(wù)需求的設(shè)備空閑,那么任務(wù)將會(huì)執(zhí)行。有一個(gè)小細(xì)節(jié)很有意思,slave的掃描,不是固定時(shí)間的。一段時(shí)間內(nèi),掃描沒(méi)有能夠執(zhí)行的任務(wù),那么掃描線(xiàn)程將會(huì)睡眠。睡眠時(shí)間是上一次的兩倍。就是說(shuō)第一次睡眠10s之后掃描沒(méi)有任務(wù)可以執(zhí)行,將會(huì)睡眠20s再次掃描,以此類(lèi)推,當(dāng)發(fā)現(xiàn)有任務(wù)執(zhí)行之后,睡眠時(shí)間刷新回到10s。這樣做的好處就是,不用一直掃描,浪費(fèi)cpu。因?yàn)橐粋€(gè)任務(wù)一般執(zhí)行時(shí)間是很長(zhǎng)的,所以一次掃描到全部都執(zhí)行不了后,其實(shí)也是意味著在往后一段時(shí)間內(nèi)都執(zhí)行不了。
  進(jìn)入開(kāi)發(fā)階段,首先就是要搞清楚,一個(gè)任務(wù),portal是怎么生成的,然后slave又是怎么掃描的,掃描到了之后,進(jìn)行了什么操作。兩個(gè)項(xiàng)目過(guò)程中,又用到了core里面的什么bean。這個(gè)部分就搞了我很久。
  其次,要構(gòu)思預(yù)約的流程。Phonedp遠(yuǎn)程調(diào)試插進(jìn)來(lái)的任務(wù),和用戶(hù)或系統(tǒng)提交的不一樣,會(huì)有特定的標(biāo)志。當(dāng)初的想法比較簡(jiǎn)單。任務(wù)完成的時(shí)候,會(huì)調(diào)用callback的函數(shù),只要在callback里面,檢查有沒(méi)有該設(shè)備預(yù)約,有的話(huà),馬上占用設(shè)備,通知用戶(hù)就完了嘛。
于是我創(chuàng)建了預(yù)約表,記錄預(yù)約情況。還編寫(xiě)了檢查預(yù)約、執(zhí)行預(yù)約、通知用戶(hù)的代碼。結(jié)果一上線(xiàn),完了,有問(wèn)題。為什么呢,任務(wù)執(zhí)行完,執(zhí)行callback的時(shí)候,你去檢查預(yù)約表。但是這個(gè)時(shí)候,是有另一個(gè)線(xiàn)程是在掃描等待任務(wù)的。就是說(shuō)查預(yù)約表,和檢測(cè)等待任務(wù)和空閑設(shè)備的線(xiàn)程,有沖突。這樣就預(yù)約在執(zhí)行狀態(tài)了,設(shè)備卻被其他任務(wù)搶了。所以這個(gè)構(gòu)思不行啊,得重寫(xiě)。
  最后和導(dǎo)師討論,有一點(diǎn)讓我收獲很大:編寫(xiě)侵入性小的代碼。就是說(shuō),這個(gè)預(yù)約功能,最好也看成一個(gè)任務(wù),和之前的任務(wù)一樣,只要分一個(gè)類(lèi)別區(qū)別就好了。這樣的話(huà),線(xiàn)程掃描任務(wù)的時(shí)候,因?yàn)榕抨?duì),會(huì)先掃到預(yù)約任務(wù),不會(huì)沖突。然后自己定義掃描到的預(yù)約任務(wù)要進(jìn)行什么操作就可以了。最后也這么實(shí)現(xiàn)了,的確沒(méi)問(wèn)題。
  編寫(xiě)這個(gè)功能的時(shí)候,因?yàn)楸姕y(cè)得需求還有自己拖拖拉拉和不熟悉業(yè)務(wù),弄了挺久的。但是這個(gè)也讓我受益匪淺,比如查看Mysql錯(cuò)誤日志,打印日志,部署STF環(huán)境,和上海側(cè)的同學(xué)討論接口排期什么的,還有很多零零散散卻非常實(shí)用的知識(shí)。對(duì)了,還有很多細(xì)節(jié)才是重中之重,比如很多出錯(cuò)的情況之類(lèi)的,但是脫離了項(xiàng)目,也沒(méi)什么講的了。

四、感謝
  在這半年的實(shí)習(xí)里面,我的主管和我的導(dǎo)師給我很大的幫助。工作中我經(jīng)常問(wèn)一些非常簡(jiǎn)單的幼稚的問(wèn)題,我的導(dǎo)師都給我一一解答,而且語(yǔ)言組織得很好,我都聽(tīng)明白了。此外還有很多像環(huán)境配置,啟動(dòng)項(xiàng)目之類(lèi)的問(wèn)題,我的導(dǎo)師剛開(kāi)始也一一操作給我看。看了他怎么弄,聽(tīng)了他的講解,然后我自己再照葫蘆畫(huà)瓢。自己弄得多了,再去百度google等地方弄清楚原理,滿(mǎn)滿(mǎn)就懂了。當(dāng)時(shí)我也是對(duì)依賴(lài)注入啊什么的概念完全不懂,工作中接觸多了,滿(mǎn)滿(mǎn)就理解了,所以不要太局限于書(shū)本,要多動(dòng)手實(shí)踐?!凹埳系脕?lái)終覺(jué)淺,絕知此事要躬行”,說(shuō)的就是這個(gè)道理吧。還有就是我經(jīng)常問(wèn)我導(dǎo)師同事問(wèn)題,他也細(xì)心給我解答了。還有我們的PM,平時(shí)相處的也很好,完全沒(méi)有像知乎上“程序員和PM是死對(duì)頭”那種感覺(jué)。在美團(tuán)的半年時(shí)間里,參加了部門(mén)的年會(huì),組內(nèi)的兩次團(tuán)建,平常同事們也一起吃飯,相處得還是挺愉快的,消除了自己第一次“北漂”的孤獨(dú)感。

 

  經(jīng)過(guò)了這次實(shí)習(xí),學(xué)到了很多知識(shí),同時(shí)也開(kāi)闊了眼界,看到了自己的不足之處。大四即將到來(lái),打算給大四定一個(gè)小計(jì)劃:1、保持coding。刷leetcode上的題,保證自己的碼感。2、深化自己實(shí)習(xí)學(xué)到的知識(shí),編寫(xiě)一個(gè)簡(jiǎn)單的MVC框架,能夠支持依賴(lài)注入、切面、請(qǐng)求分發(fā)和處理就好。造輪子能夠提高自己的代碼水平,順便把這個(gè)作為自己的畢業(yè)設(shè)計(jì),一舉兩得。半年的實(shí)習(xí),感覺(jué)自己水平提高了不少。希望大四完結(jié)后,對(duì)于現(xiàn)在的自己,能有更大的進(jìn)步。

http://www.cnblogs.com/wzben/p/7233674.html