美團(tuán)超詳細(xì)面經(jīng)(附答案)

一面本文公眾號(hào)來(lái)源:程序員喬戈里?
作者:喬戈里qgl
自我介紹
答:自我介紹是面試中唯一的自己主動(dòng)介紹自己的環(huán)節(jié),一定要好好把握好,你數(shù)據(jù)結(jié)構(gòu)學(xué)的號(hào)可以手撕一個(gè)紅黑樹(shù)你就說(shuō)我數(shù)據(jù)結(jié)構(gòu)掌握地很好,反正就是要把自己的優(yōu)勢(shì)凸顯出來(lái),比如我是保研的以及對(duì)于java的知識(shí)較熟悉,我介紹完自己的本科經(jīng)歷以后,我就說(shuō)我是保送到本校繼續(xù)讀研究生,然后最末尾會(huì)加上自己熟悉java,然后面試官就會(huì)問(wèn)java的一些東西;- 項(xiàng)目介紹及其亮點(diǎn)答:這篇文章可以作為你面試的項(xiàng)目亮點(diǎn)的文章,不來(lái)看看嗎?
- java的8種數(shù)據(jù)類型有哪些?答:感覺(jué)這個(gè)問(wèn)題被問(wèn)爛了,int,short,long,float,double,byte,boolean,char;
- 問(wèn)了Integer緩存數(shù)據(jù)的范圍?答:-128-127
- 緊接著問(wèn)了Object類有哪些方法?答:這個(gè)我有背過(guò),clone,getClass,toString,finalize,equals,hashCode,wait,notify,notifyALL。
- 問(wèn)到這里然后拿出了一個(gè)題,面試官有小紙條,題目在上面,String A = "123"; String B = new String("123");,問(wèn)我生成了幾個(gè)String對(duì)象?答:我說(shuō)如果常量池中,原來(lái)沒(méi)有“123”那么就是生成了2個(gè)對(duì)象,如果常量池中有“123”那么只要1個(gè)對(duì)象生成
- 由于提到了wait,順帶問(wèn)了wait和sleep有什么區(qū)別?答:wait的話會(huì)釋放對(duì)象鎖,sleep的話不會(huì)釋放的對(duì)象鎖
- 由于還提及了hashcode,面試官接著問(wèn)我,hashcode用在哪里?答:這個(gè)我不假思索地說(shuō),hashmap和ConcurrentMap,這里我猜面試官肯定要繼續(xù)問(wèn)我這兩個(gè)東西了。
- 果不其然,面試官說(shuō),講一講hashmap?答:hashmap我講了hashmap的數(shù)據(jù)結(jié)構(gòu)數(shù)組鏈表結(jié)構(gòu),講了hashmap的put,get,擴(kuò)容的底層原理,同時(shí)講了hashmap在1.7與1.8中的區(qū)別,put中引入了紅黑樹(shù),以及擴(kuò)容的時(shí)候不同,這些就講了挺長(zhǎng)時(shí)間,最后我說(shuō)了一句hashmap不是線程安全的。
- 這里提及了hashMap是非線程安全的,面試問(wèn)我為啥不是線程安全的,舉幾個(gè)例子?答:我說(shuō)了,在擴(kuò)容的時(shí)候hashmap會(huì)可能產(chǎn)生環(huán),造成死循環(huán);hashmap在插入新的階段的時(shí)候,多個(gè)線程同時(shí)插入,會(huì)把除了最后的那個(gè)線程的其它線程插入的結(jié)點(diǎn)丟失;對(duì)于修改的時(shí)候,多個(gè)線程修改,對(duì)只保留最后的一個(gè)線程的修改結(jié)果;擴(kuò)容的時(shí)候,會(huì)只保留最后一個(gè)線程的擴(kuò)容后的那個(gè)數(shù)組;從擴(kuò)容修改增加說(shuō)了一遍;
- 我本以為要接著問(wèn)ConCurrentMap,額,出乎我的意料,并沒(méi)有問(wèn),可能覺(jué)得我hashmap準(zhǔn)備的很充分,然后接著問(wèn)了我JVM了解嗎?答:我說(shuō)了解;
- 讓我說(shuō)意思JVM的分為哪幾塊?答:方法區(qū),虛擬機(jī)棧,本地方法棧,堆,程序計(jì)數(shù)器,然后我就自己沒(méi)等面試官問(wèn)新的問(wèn)題,繼續(xù)接著說(shuō),方法區(qū)和堆是線程共享的,虛擬機(jī)棧本地方法棧和程序計(jì)數(shù)器是線程私有的,除了程序技術(shù)器不會(huì)發(fā)生內(nèi)存溢出,其它都會(huì)發(fā)生內(nèi)存溢出,并說(shuō)了哪些會(huì)發(fā)生堆溢出哪些會(huì)發(fā)生棧溢出;這里就是大家要學(xué)會(huì)自己吧啦吧啦地說(shuō)一堆,因?yàn)閾?jù)我觀察每個(gè)面試官面試每個(gè)是有一個(gè)固定時(shí)間的,超過(guò)這個(gè)時(shí)間段就結(jié)束了,所以只要面試官不打斷你,你就一頓說(shuō);
- 由于提及到了內(nèi)存溢出,面試官問(wèn)我內(nèi)存溢出和內(nèi)存泄漏的區(qū)別?答:內(nèi)存泄露我說(shuō)就是一塊申請(qǐng)了一塊內(nèi)存以后,無(wú)法去釋放掉這塊內(nèi)存,丟失了這段內(nèi)存的引用;內(nèi)存溢出就是申請(qǐng)的內(nèi)存不夠,撐不起我們需要的內(nèi)存;
- 這里問(wèn)完我就去問(wèn)了數(shù)據(jù)庫(kù),4大特性是啥,舉個(gè)例子?答:原子性,我說(shuō)就是一個(gè)事務(wù)要么全部完成,要么全部失敗,要么做要么不做;一致性,比如a+b=100,一個(gè)事務(wù)改變了a比如增加了a的值,那么必須同時(shí)改變b,保證在事務(wù)結(jié)束以后a+b=100依然成立,這就是一致性;持久性,額就是修改完以后,在數(shù)據(jù)庫(kù)中生效是永久的;隔離性,我就是說(shuō)對(duì)于A對(duì)B進(jìn)行轉(zhuǎn)賬,A沒(méi)把這個(gè)交易完成的時(shí)候,B是不知道A要給他轉(zhuǎn)錢。
- 數(shù)據(jù)的隔離級(jí)別有啥,每個(gè)隔離級(jí)別舉個(gè)例子?答:額,(怎么都要舉例子啊,啊啊啊啊~),內(nèi)心波瀾,臉上面無(wú)表情地說(shuō):1.未提交讀,事務(wù)中發(fā)生了修改,即使沒(méi)有提交,其它事務(wù)也是可見(jiàn)的,舉例子我就說(shuō)對(duì)于一個(gè)數(shù)A原來(lái)50修改為100,但是我還沒(méi)有提交修改,另一個(gè)事務(wù)看到這個(gè)修改,而這個(gè)時(shí)候原事務(wù)發(fā)生了回滾,這時(shí)候A還是50,但是另一個(gè)事務(wù)看到的A是100,這就是未提交讀;2.提交讀,就是說(shuō),對(duì)于一個(gè)事務(wù)從開(kāi)始直到提交之前,所做的任何修改是其它事務(wù)不可見(jiàn)的,舉例就是對(duì)于一個(gè)數(shù)A原來(lái)是50,然后提交修改成100,這個(gè)時(shí)候另一個(gè)事務(wù)在A提交修改之前,讀取到了A是50,剛讀取完,A就被修改成100了,這個(gè)時(shí)候另一個(gè)事務(wù)再進(jìn)行讀取發(fā)現(xiàn)A就突然變成100了;3.可重復(fù)讀;可重復(fù)讀,就是對(duì)于一個(gè)記錄讀取多次的記錄是相同的,舉例就是對(duì)于一個(gè)數(shù)A讀取的話一直是A,前后兩次讀取到的A是一致的;可串行化讀,就是說(shuō)在并發(fā)情況下,和串行化的讀取的結(jié)果是一致的,沒(méi)有什么不同,這個(gè)舉例我就說(shuō),不會(huì)發(fā)生臟讀和幻讀;然后數(shù)據(jù)庫(kù)這一塊就過(guò)去了。
- 接著問(wèn)我計(jì)算機(jī)網(wǎng)絡(luò),問(wèn)了我7層有哪7層?
答:物理層,數(shù)據(jù)鏈路層,網(wǎng)絡(luò)層,傳輸層,會(huì)話層,表示層,應(yīng)用層; - 接著問(wèn)了我TCP在哪層,UDP在哪層,HTTP在哪層?答:TPC和UDP在傳輸層,然后HTTP問(wèn)我在哪個(gè)層,我一下有點(diǎn)忘了,這個(gè)沒(méi)答上來(lái),會(huì)去看了是在應(yīng)用層。
- 問(wèn)到這里就結(jié)束了,然后面試官問(wèn)我有啥想問(wèn)的,我就問(wèn)如何評(píng)價(jià)我的面試表現(xiàn)?答:因?yàn)橐幻娑际菃?wèn)基礎(chǔ)的知識(shí),面試官和我說(shuō),我感覺(jué)你基礎(chǔ)很扎實(shí),他直接和我說(shuō)我這里的話是通過(guò)的,不知道后面的面試官怎么問(wèn)你,然后我說(shuō)了聲謝謝,就去酒店的一個(gè)會(huì)議廳等待二面;
一面過(guò)了沒(méi)多久,就立馬通知二面了,中途感覺(jué)有點(diǎn)餓了,美團(tuán)還挺人性話的,在后面的桌子上放了一堆餅干,忘了餅干的名字了,總之特別好吃,我吃了好幾塊。
自我介紹
項(xiàng)目介紹,及其亮點(diǎn)介紹。
答:這個(gè)繼續(xù)這篇文章就是背;可以作為你面試的項(xiàng)目亮點(diǎn)的文章,不來(lái)看看嗎?
然后問(wèn)了我集合了解嗎,讓我說(shuō)話ArrayList和LinkedList的區(qū)別?
答:ArrayList底層是數(shù)組,LinkedList底層是鏈表,ArrayLIst查找數(shù)據(jù)快,LinkedList插入刪除快;
繼續(xù)問(wèn)我linkedList可以用for循環(huán)遍歷嗎?
答;能不用盡量不要用,linkedList底層是鏈表,它使用for進(jìn)行遍歷,訪問(wèn)每一個(gè)元素都是從頭開(kāi)始訪問(wèn)然后直到找到這個(gè)元素,比如說(shuō)找第三個(gè)節(jié)點(diǎn),需要先找到第一個(gè)節(jié)點(diǎn)然后找到第二個(gè)節(jié)點(diǎn);繼續(xù)找第4個(gè)節(jié)點(diǎn),不是從第三個(gè)節(jié)點(diǎn)開(kāi)始找的,還是從第一個(gè)節(jié)點(diǎn)開(kāi)始,所以非常的慢,不推薦,可以用迭代器進(jìn)行遍歷。
介紹一下ConCurrenthashmap
答:我感覺(jué)是因?yàn)橐幻鎲?wèn)了hashmap,所以二面面試官可能是看見(jiàn)了面試記錄,額,這塊我非常熟,這個(gè)我又講了很長(zhǎng)時(shí)間,講了ConCurrentHashMap的底層的分段鎖的結(jié)構(gòu),講了ConCurrentHashmap的get源碼,get源碼是沒(méi)有使用鎖的,這里我把get源碼背寫(xiě)了下來(lái),并給面試官講了get源碼在插入修改刪除的多線程下是安全的;然后講了put操作,remove,擴(kuò)容操作,然后講了在1.7和1.8的區(qū)別,引入了紅黑樹(shù),鏈表長(zhǎng)度大于8轉(zhuǎn)換成紅黑樹(shù),采用了CAS+synchronized來(lái)保證并發(fā)安全,吧啦吧啦又講了挺長(zhǎng)時(shí)間;
來(lái)看看這道題,說(shuō)著拿出來(lái)一個(gè)小紙條
答:這個(gè)紙條感覺(jué)每個(gè)面試官都是只有紙條,所以盡可能地和周圍的同學(xué)多交流,有一定的肯可能他的面試官就你的面試官。題目:讓我自己手算a,b,c,d的值,
1public?class?Main?{
2????public?static?void?main(String?[]?args)
3????{
4????????int?a?=?10?>>?1;
5????????int?b??=?a++;
6????????int?c?=?++a;
7????????int?d?=?b?*?a++;
8????????System.out.println(a);
9????????System.out.println(b);
10????????System.out.println(c);
11????????System.out.println(d);
12????}
13}結(jié)果是a = 8b=5,c=7,d=35.計(jì)算完我問(wèn)他對(duì)不對(duì),他沒(méi)勒我。。。
然后問(wèn)我單利模式了解不,寫(xiě)一個(gè)單例模式?
答:這個(gè)之前準(zhǔn)備過(guò),我寫(xiě)了一個(gè)雙重鎖的單例模式。
1public?class?SingletonDemo?{
2????private?volatile?static?SingletonDemo?instance;
3????private?SingletonDemo(){
4????????System.out.println("Singleton?has?loaded");
5????}
6????public?static?SingletonDemo?getInstance(){
7????????if(instance==null){
8????????????synchronized?(SingletonDemo.class){
9????????????????if(instance==null){
10????????????????????instance=new?SingletonDemo();
11????????????????}
12????????????}
13????????}
14????????return?instance;
15????}
16}接著問(wèn)了我虛擬機(jī)了解嗎,介紹一些虛擬機(jī)的內(nèi)存模型?
答:這個(gè)之前也準(zhǔn)備過(guò),這里要注意了,虛擬機(jī)的內(nèi)存模型和運(yùn)行時(shí)的數(shù)據(jù)區(qū)域不是一回事;虛擬機(jī)內(nèi)存模型又叫JMM,就是每個(gè)線程有自己的工作內(nèi)存,然后又一個(gè)主內(nèi)存,線程工作的時(shí)候都是在自己的工作內(nèi)存中拷貝一個(gè)主內(nèi)存的副本;還說(shuō)了JMM的happens before原則,程序順序原則,鎖原則,線程中斷原則,傳遞性原則,還有其他的沒(méi)想起來(lái)就沒(méi)說(shuō)了。
介紹一些你了解的垃圾回收算法?
答:標(biāo)記清除,標(biāo)記整理,復(fù)制算法,把每個(gè)算法是啥說(shuō)了一遍;
問(wèn)到這里,問(wèn)了我你知道SurvivorRatio這個(gè)參數(shù)為啥初始是默認(rèn)的8:1:1嗎?
答:這個(gè)由于剛才剛問(wèn)了垃圾回收算法,我覺(jué)得可能有關(guān)聯(lián),于是我說(shuō),方便復(fù)制算法操作,Eden區(qū)域大多數(shù)都是朝生夕死的,這個(gè)比例,可以方便復(fù)制算法的中from和to來(lái)回進(jìn)行復(fù)制存活的對(duì)象,額,說(shuō)完,他沒(méi)有說(shuō)啥,感覺(jué)是默許了吧;
突然又問(wèn),二叉樹(shù)了解嗎,寫(xiě)一個(gè)二叉樹(shù)的深度搜索遍歷?
答:當(dāng)時(shí)我聽(tīng)到中道題,有點(diǎn)懵,什么是二叉樹(shù)的深度搜索遍歷,我只知道層次遍歷,前序后序中序遍歷啊,我想了想,感覺(jué)和后序遍歷挺像的,我覺(jué)得應(yīng)該就是后序遍歷吧,我就先寫(xiě)了個(gè)后序遍歷的遞歸寫(xiě)法
1void?DFS(TreeNode?root)
2{
3????if(root?==?null)
4????????return;
5????if(root.left?!=?null)
6????????DFS(root.left);
7????if(root.right?!=?null)
8????????DFS(root.right);
9????System.out.println(root.val);
10},然后他看了一眼,沒(méi)說(shuō)啥,感覺(jué)這個(gè)面試官有點(diǎn)話少冷淡,全程不和我互動(dòng),emmmm....下來(lái)自己百度了下,對(duì)的。。。
三面這個(gè)代碼問(wèn)完我,讓后讓我去等通知,我感覺(jué)回答的還行,果然沒(méi)過(guò)幾分鐘,通知我去三面;
照例自我介紹和項(xiàng)目介紹;
上來(lái)就讓我手撕一個(gè)單例模式。。。
答:繼續(xù)寫(xiě)我的雙重鎖模式
1public?class?SingletonDemo?{
2????private?volatile?static?SingletonDemo?instance;
3????private?SingletonDemo(){
4????????System.out.println("Singleton?has?loaded");
5????}
6????public?static?SingletonDemo?getInstance(){
7????????if(instance==null){
8????????????synchronized?(SingletonDemo.class){
9????????????????if(instance==null){
10????????????????????instance=new?SingletonDemo();
11????????????????}
12????????????}
13????????}
14????????return?instance;
15????}
16},
讓我講了講代碼是啥啥意思?
答:STEP 1. 線程A訪問(wèn)getInstance()方法,因?yàn)閱卫€沒(méi)有實(shí)例化,所以進(jìn)入了鎖定塊。STEP 2. 線程B訪問(wèn)getInstance()方法,因?yàn)閱卫€沒(méi)有實(shí)例化,得以訪問(wèn)接下來(lái)代碼塊,而接下來(lái)代碼塊已經(jīng)被線程1鎖定。STEP 3. 線程A進(jìn)入下一判斷,因?yàn)閱卫€沒(méi)有實(shí)例化,所以進(jìn)行單例實(shí)例化,成功實(shí)例化后退出代碼塊,解除鎖定。STEP 4. 線程B進(jìn)入接下來(lái)代碼塊,鎖定線程,進(jìn)入下一判斷,因?yàn)橐呀?jīng)實(shí)例化,退出代碼塊,解除鎖定。STEP 5. 線程A初始化并獲取到了單例實(shí)例并返回,線程B獲取了在線程A中初始化的單例。大體是這么回事。
由于我的項(xiàng)目中提及到JVM,所以給我出了一個(gè)場(chǎng)景題,垃圾會(huì)收器中,標(biāo)記清除多次后,由于采用的是標(biāo)記清除算法,那么你覺(jué)得可能會(huì)出現(xiàn)什么問(wèn)題?
答:然后我說(shuō)由于產(chǎn)生了內(nèi)存碎片,所以當(dāng)分配一個(gè)大對(duì)象的時(shí)候,由于內(nèi)存不連續(xù),那么會(huì)產(chǎn)生full GC;
這里提及到了full gc,問(wèn)我,哪些情況會(huì)產(chǎn)生full GC,哪些情況產(chǎn)生minor GC?
答:minor會(huì)產(chǎn)生在eden區(qū)滿了,fullGC產(chǎn)生在老年代的剩余空間不足,以及永久代內(nèi)存不足也會(huì)發(fā)生fullGC。
除了你項(xiàng)目中的內(nèi)存溢出問(wèn)題,你還知道哪些關(guān)于內(nèi)存溢出內(nèi)存泄漏的?
答:這里之前了解過(guò)ThreadLocal,我說(shuō),ThreadLocal中的鍵值對(duì)中的鍵是一個(gè)弱引用,那么在內(nèi)存回收的時(shí)候,這個(gè)鍵很可能會(huì)被回收掉,然后鍵沒(méi)了,就無(wú)法找到value的值,造成了內(nèi)存泄漏;
然后給我出了一個(gè)動(dòng)態(tài)規(guī)劃的手寫(xiě)代碼題,說(shuō)來(lái)寫(xiě)個(gè)代碼吧,大體是在n*m的矩陣方格中,找一個(gè)最大的正方形是幾乘幾的,有點(diǎn)忘了,
答:由于沒(méi)有準(zhǔn)備過(guò)動(dòng)態(tài)規(guī)劃的題目,這個(gè)題目看到我只說(shuō)了暴力解決的方法,然后面試官提示讓我用動(dòng)態(tài)規(guī)劃做,我想了半天沒(méi)想出來(lái)。。。。當(dāng)時(shí)感覺(jué)應(yīng)該是涼了。。。
結(jié)束語(yǔ)時(shí)間差不多的時(shí)候,面試官說(shuō),就到這里吧,然后讓我出去等通知,果然通知我今天面試結(jié)束了,整整一個(gè)下午,特別特別累,前兩面結(jié)束的時(shí)候感覺(jué)特別穩(wěn),沒(méi)想到最后還是因?yàn)槭謱?xiě)代碼這一塊不會(huì)動(dòng)態(tài)規(guī)劃掛掉了,當(dāng)時(shí)感覺(jué)心態(tài)有點(diǎn)崩。。。
最終美團(tuán)面試還是掛了,,,留下了沒(méi)有技術(shù)的眼淚。。。所以痛下決心要好好學(xué)習(xí)算法。
公眾號(hào)文章導(dǎo)航:兩年嘔心瀝血的文章!
長(zhǎng)按掃碼可關(guān)注獲取?
在看和分享對(duì)我非常重要!
