写在 2019 年后的蚂蚁、头条、拼多多的面试总结
不想聽我BB直接進入面試分享:
說起來開始進行面試是年前倒數第二周,上午9點,我還在去公司的公交上,突然收到螞蟻的面試電話,其實算不上真正的面試。面試官只是和我聊了下他們在做的事情(主要是做雙十一這里大促的穩定性保障,偏中間件吧),說的很詳細,然后和我溝通了下是否有興趣,我表示有興趣,后面就收到正式面試的通知,最后沒選擇去螞蟻表示抱歉。
當時我自己也準備出去看看機會,順便看看自己的實力。當時我其實挺糾結的,一方面現在部門也正需要我,還是可以有一番作為的,另一方面覺得近一年來進步緩慢,沒有以前飛速進步的成就感了,而且業務和技術偏于穩定,加上自己也屬于那種比較懶散的人,骨子里還是希望能夠突破現狀,持續在技術上有所精進。
在開始正式的總結之前,還是希望各位同仁能否聽我繼續發泄一會,抱拳!
我翻開自己2018年初立的flag,覺得甚是慚愧。其中就有一條是保持一周寫一篇博客,奈何中間因為各種原因沒能堅持下去。細細想來,主要是自己沒能真正靜下來心認真投入到技術的研究和學習,那么為什么會這樣?說白了還是因為沒有確定目標或者目標不明確,沒有目標或者目標不明確都可能導致行動的失敗。那么問題來了,目標是啥?就我而言,短期目標是深入研究某一項技術,比如最近在研究mysql,那么深入研究一定要動手實踐并且有所產出,這就夠了么?還需要我們能夠舉一反三,結合實際開發場景想一想日常開發要注意什么,這中間有沒有什么坑?可以看出,要進步真的不是一件簡單的事,這種反人類的行為需要我們克服自我的弱點,逐漸形成習慣。真正牛逼的人,從不覺得認真學習是一件多么難的事,因為這已經形成了他的習慣,就和早上起床刷牙洗臉那么自然簡單。
扯了那么多,開始進入正題,先后進行了螞蟻、拼多多和字節跳動的面試。
準備過程
先說說我自己的情況,我2016先在螞蟻實習了將近三個月,然后去了我現在的老東家,2.5年工作經驗,可以說畢業后就一直老老實實在老東家打怪升級,雖說有螞蟻的實習經歷,但是因為時間太短,還是有點虛的。所以面試官看到我簡歷第一個問題絕對是這樣的。
“哇,你在螞蟻待過,不錯啊”,面試官笑嘻嘻地問到。 “是的,還好”,我說。 “為啥才三個月?”,面試官臉色一沉問到。 “嘩啦啦解釋一通。。。”,我解釋道。 “哦,原來如此,那我們開始面試吧”,面試官一本正經說到。
尼瑪,早知道不寫螞蟻的實習經歷了,后面仔細一想,當初寫上螞蟻不就給簡歷加點料嘛。
言歸正傳,準備過程其實很早開始了(當然這不是說我工作時老想著跳槽,因為我明白現在的老東家并不是終點,我還需要不斷提升),具體可追溯到從螞蟻離職的時候,當時出來也面了很多公司,沒啥大公司,面了大概5家公司,都拿到offer了。工作之余常常會去額外研究自己感興趣的技術以及工作用到的技術,力求把原理搞明白,并且會自己實踐一把。此外,買了N多書,基本有時間就會去看,補補基礎,什么操作系統、數據結構與算法、mysql、jdk之類的源碼,基本都好好溫習了(文末會列一下自己看過的書和一些好的資料)。我深知基礎就像“木桶效應”的短板,決定了能裝多少水。
此外,在正式決定看機會之前,我給自己列了一個提綱,主要包括Java要掌握的核心要點,有不懂的就查資料搞懂。我給自己定位還是Java工程師,所以Java體系是一定要做到心中有數的,很多東西沒有常年的積累面試的時候很容易露餡,學習要對得起自己,不要騙人。
剩下的就是找平臺和內推了,除了螞蟻,頭條和拼多多都是找人內推的,感謝螞蟻面試官對我的欣賞,以后說不定會去螞蟻咯?:smile:?。
平臺:脈脈、GitHub、v2
螞蟻金服
一面
一面就做了一道算法題,要求兩小時內完成,給了長度為N的有重復元素的數組,要求輸出第10大的數。典型的TopK問題,快排算法搞定。
算法題要注意的是合法性校驗、邊界條件以及異常的處理。另外,如果要寫測試用例,一定要保證測試覆蓋場景盡可能全。加上平時刷刷算法題,這種考核應該沒問題的。
二面
自我介紹下唄
開源項目貢獻過代碼么?
Dubbo提過一個打印accesslog的bug算么
目前在部門做什么,業務簡單介紹下
內部有哪些系統,作用和交互過程說下
Dubbo踩過哪些坑,分別是怎么解決的?
說了異常處理時業務異常捕獲的問題,自定義了一個異常攔截器
開始進入正題,說下你對線程安全的理解
多線程訪問同一個對象,如果不需要考慮額外的同步,調用對象的行為就可以獲得正確的結果就是線程安全
事務有哪些特性?
ACID
怎么理解原子性?
同一個事務下,多個操作要么成功要么失敗,不存在部分成功或者部分失敗的情況
樂觀鎖和悲觀鎖的區別?
悲觀鎖假定會發生沖突,訪問的時候都要先獲得鎖,保證同一個時刻只有線程獲得鎖,讀讀也會阻塞;樂觀鎖假設不會發生沖突,只有在提交操作的時候檢查是否有沖突
這兩種鎖在Java和MySQL分別是怎么實現的?
select...forupdate
HashMap為什么不是線程安全的?
多線程操作無并發控制,順便說了在擴容的時候多線程訪問時會造成死鎖,會形成一個環
怎么讓HashMap變得線程安全?
Collections的synchronize方法包裝一個線程安全的Map,或者直接用ConcurrentHashMap
兩者的區別是什么?
前者直接在put和get方法加了synchronize同步,后者采用了分段鎖以及CAS支持更高的并發
jdk1.8對ConcurrentHashMap做了哪些優化?
插入的時候如果數組元素使用了紅黑樹,取消了分段鎖設計,synchronize替代了Lock鎖
為什么這樣優化?
避免沖突嚴重時鏈表多長,提高查詢效率,時間復雜度從O(N)提高到O(logN)
redis主從機制了解么?怎么實現的?
有過GC調優的經歷么?
有點虛,答得不是很好
有什么想問的么?
三面
簡單自我介紹下
監控系統怎么做的,分為哪些模塊,模塊之間怎么交互的?
用的什么數據庫?
mysql
使用什么存儲引擎,為什么使用InnnoDB?
支持事務、聚簇索引、MVCC
訂單表有做拆分么,怎么拆的?
垂直拆分和水平拆分
水平拆分后查詢過程描述下
如果落到某個分片的數據很大怎么辦?
按照某種規則,比如哈希取模、range,將單張表拆分為多張表
哈希取模會有什么問題么?
有的,數據分布不均,擴容縮容相對復雜
分庫分表后怎么解決讀寫壓力?
一主多從、多主多從
拆分后主鍵怎么保證惟一?
UUID、Snowflake算法
Snowflake生成的ID是全局遞增唯一么?
不是,只是全局唯一,單機遞增
怎么實現全局遞增的唯一ID?
講了TDDL的一次取一批ID,然后再本地慢慢分配的做法
Mysql的索引結構說下
說了B+樹,B+樹可以對葉子結點順序查找,因為葉子結點存放了數據結點且有序
主鍵索引和普通索引的區別
主鍵索引的葉子結點存放了整行記錄,普通索引的葉子結點存放了主鍵ID,查詢的時候需要做一次回表查詢
一定要回表查詢么?
不一定,當查詢的字段剛好是索引的字段或者索引的一部分,就可以不用回表,這也是索引覆蓋的原理
你們系統目前的瓶頸在哪里?
你打算怎么優化?簡要說下你的優化思路
有什么想問我么?
四面
介紹下自己
為什么要做逆向?
怎么理解微服務?
服務治理怎么實現的?
說了限流、壓測、監控等模塊的實現
這個不是中間件做的事么,為什么你們部門做?
當時沒有單獨的中間件團隊,微服務剛搞不久,需要進行監控和性能優化
說說Spring的生命周期吧
說說GC的過程
說了young gc和full gc的觸發條件和回收過程以及對象創建的過程
CMS GC有什么問題?
并發清除算法,浮動垃圾,短暫停頓
怎么避免產生浮動垃圾?
記得有個VM參數設置可以讓掃描新生代之前進行一次young gc,但是因為gc是虛擬機自動調度的,所以不保證一定執行。但是還有參數可以讓虛擬機強制執行一次young gc
強制young gc會有什么問題?
STW停頓時間變長
知道G1么?
了解一點
回收過程是怎么樣的?
young gc、并發階段、混合階段、full gc,說了Remember Set
你提到的Remember Set底層是怎么實現的?
有什么想問的么?
五面
五面是HRBP面的,和我提前預約了時間,主要聊了之前在螞蟻的實習經歷、部門在做的事情、職業發展、福利待遇等。阿里面試官確實是具有一票否決權的,很看重你的價值觀是否match,一般都比較喜歡皮實的候選人。HR面一定要誠實,不要說謊,只要你說謊HR都會去證實,直接cut了。
之前螞蟻實習三個月怎么不留下來?
實習的時候主管是誰?
實習做了哪些事情?(尼瑪這種也問?)
你對技術怎么看?平時使用什么技術棧?(阿里HR真的是既當爹又當媽,?:joy:?)
最近有在研究什么東西么
你對SRE怎么看
對待遇有什么預期么
最后HR還對我說目前穩定性保障部挺缺人的,希望我盡快回復。
小結
螞蟻面試比較重視基礎,所以Java那些基本功一定要扎實。螞蟻的工作環境還是挺贊的,因為我面的是穩定性保障部門,還有許多單獨的小組,什么三年1班,很有青春的感覺。面試官基本水平都比較高,基本都P7以上,除了基礎還問了不少架構設計方面的問題,收獲還是挺大的。
拼多多
面試前
面完螞蟻后,早就聽聞拼多多這個獨角獸,決定也去面一把。首先我在脈脈找了一個拼多多的HR,加了微信聊了下,發了簡歷便開始我的拼多多面試之旅。這里要非常感謝拼多多HR×××姐,從面試內推到offer確認一直都在幫我,人真的很nice。
一面
為啥螞蟻只待了三個月?沒轉正?
轉正了,解釋了一通。。。
Java中的HashMap、TreeMap解釋下?
TreeMap紅黑樹,有序,HashMap無序,數組+鏈表
TreeMap查詢寫入的時間復雜度多少?
O(logN)
HashMap多線程有什么問題?
線程安全,死鎖
怎么解決?
jdk1.8用了synchronize + CAS,擴容的時候通過CAS檢查是否有修改,是則重試
重試會有什么問題么?
CAS(Compare And Swap)是比較和交換,不會導致線程阻塞,但是因為重試是通過自旋實現的,所以仍然會占用CPU時間,還有ABA的問題
怎么解決?
超時,限定自旋的次數,ABA可以通過原理變量AtomicStampedReference解決,原理利用版本號進行比較
超過重試次數如果仍然失敗怎么辦?
synchronize互斥鎖
CAS和synchronize有什么區別?都用synchronize不行么?
CAS是樂觀鎖,不需要阻塞,硬件級別實現的原子性;synchronize會阻塞,JVM級別實現的原子性。使用場景不同,線程沖突嚴重時CAS會造成CPU壓力過大,導致吞吐量下降,synchronize的原理是先自旋然后阻塞,線程沖突嚴重仍然有較高的吞吐量,因為線程都被阻塞了,不會占用CPU
如果要保證線程安全怎么辦?
ConcurrentHashMap
ConcurrentHashMap怎么實現線程安全的?
分段鎖
get需要加鎖么,為什么?
不用,volatile關鍵字
volatile的作用是什么?
保證內存可見性
底層怎么實現的?
說了主內存和工作內存,讀寫內存屏障,happen-before,并在紙上畫了線程交互圖
在多核CPU下,可見性怎么保證?
思考了一會,總線嗅探技術
聊項目,系統之間是怎么交互的?
系統并發多少,怎么優化?
給我一張紙,畫了一個九方格,都填了數字,給一個M*N矩陣,從1開始逆時針打印這M*N個數,要求時間復雜度盡可能低
(內心OS:之前貌似碰到過這題,最優解是怎么實現來著)思考中。。。
可以先說下你的思路
(想起來了),說了什么時候要變換方向的條件,向右、向下、向左、向上,依此循環
有什么想問我的?
二面
自我介紹下
手上還有其他offer么?
拿了螞蟻的offer
部門組織結構是怎樣的?
。。。這輪不是技術面么,不過還是老老實實說了
系統有哪些模塊,每個模塊用了哪些技術,數據怎么流轉的?
(面試官有點禿頂,一看級別就很高)給了我一張紙,我在上面簡單畫了下系統之間的流轉情況
鏈路追蹤的信息是怎么傳遞的?
RpcContext的attachment,說了Span的結構(parentSpanId + curSpanId)
SpanId怎么保證唯一性?
UUID,說了下內部的定制改動
RpcContext是在什么維度傳遞的?
線程
Dubbo的遠程調用怎么實現的?
講了讀取配置、拼裝url、創建Invoker、服務導出、服務注冊以及消費者通過動態代理、filter、獲取Invoker列表、負載均衡等過程(嘩啦啦講了10多分鐘),我可以喝口水么
Spring的單例是怎么實現的?
單例注冊表
怎么保證線程安全的?
HashMap + synchronize
為什么要單獨實現一個服務治理框架?
說了下內部剛搞微服務不久,主要對服務進行一些監控和性能優化
誰主導的?
內部還在使用么?
逆向有想過怎么做成通用么?
有什么想問的么?
三面
二面老大面完后就直接HR面了,主要問了些職業發展、是否有其他offer、以及入職意向等問題,順便說了下公司的福利待遇等,都比較常規啦。不過要說的是手上有其他offer或者大廠經歷會有一定加分。
小結
拼多多的面試流程就簡單許多,畢竟是一個成立三年多的公司。面試難度中規中矩,只要基礎扎實應該不是問題。但不得不說工作強度很大,開始面試前HR就提前和我確認能否接受這樣強度的工作,想來的老鐵還是要做好準備
字節跳動
面試前
頭條的面試是三家里最專業的,每次面試前有專門的HR和你約時間,確定OK后再進行面試。每次都是通過視頻面試,因為都是之前都是電話面或現場面,所以視頻面試還是有點不自然。也有人覺得視頻面試體驗很贊,當然蘿卜青菜各有所愛。最坑的二面的時候對方面試官的網絡老是掉線,最后很冤枉的掛了(當然有一些點答得不好也是原因之一)。所以還是有點遺憾的。
一面
先自我介紹下
聊項目,逆向系統是什么意思
聊項目,逆向系統用了哪些技術
線程池的線程數怎么確定?
如果是IO操作為主怎么確定?
如果計算型操作又怎么確定?
Redis熟悉么,了解哪些數據結構
說了zset
zset底層怎么實現的
跳表
跳表的查詢過程是怎么樣的,查詢和插入的時間復雜度
說了先從第一層查找,不滿足就下沉到第二層找,因為每一層都是有序的,寫入和插入的時間復雜度都是O(logN)
紅黑樹了解么,時間復雜度
說了是N叉平衡樹,O(logN)
既然兩個數據結構時間復雜度都是O(logN),zset為什么不用紅黑樹
跳表實現簡單,踩坑成本低,紅黑樹每次插入都要通過旋轉以維持平衡,實現復雜
點了點頭,說下Dubbo的原理
說了服務注冊與發布以及消費者調用的過程
踩過什么坑沒有
說了dubbo異常處理的和打印accesslog的問題
CAS了解么
說了CAS的實現
還了解其他同步機制么
說了synchronize以及兩者的區別,一個樂觀鎖,一個悲觀鎖
那我們做一道題吧,數組A,2*n個元素,n個奇數、n個偶數,設計一個算法,使得數組奇數下標位置放置的都是奇數,偶數下標位置放置的都是偶數
先說下你的思路
從0下標開始遍歷,如果是奇數下標判斷該元素是否奇數,是則跳過,否則從該位置尋找下一個奇數
下一個奇數?怎么找?
有點懵逼,思考中。。。
有思路么?
仍然是先遍歷一次數組,并對下標進行判斷,如果下標屬性和該位置元素不匹配從當前下標的下一個遍歷數組元素,然后替換
你這樣時間復雜度有點高,如果要求O(N)要怎么做
思考一會,答道“定義兩個指針,分別從下標0和1開始遍歷,遇見奇數位是是偶數和偶數位是奇數就停下,交換內容”
時間差不多了,先到這吧。你有什么想問我的?
二面
面試官和藹很多,你先介紹下自己吧
你對服務治理怎么理解的?
項目中的限流怎么實現的?
Guava ratelimiter,令牌桶算法
具體怎么實現的?
要點是固定速率且令牌數有限
如果突然很多線程同時請求令牌,有什么問題?
導致很多請求積壓,線程阻塞
怎么解決呢?
可以把積壓的請求放到消息隊列,然后異步處理
如果不用消息隊列怎么解決?
說了RateLimiter預消費的策略
分布式追蹤的上下文是怎么存儲和傳遞的?
ThreadLocal + spanId,當前節點的spanId作為下個節點的父spanId
Dubbo的RpcContext是怎么傳遞的?
ThreadLocal
主線程的ThreadLocal怎么傳遞到線程池?
說了先在主線程通過ThreadLocal的get方法拿到上下文信息,在線程池創建新的ThreadLocal并把之前獲取的上下文信息設置到ThreadLocal中。這里要注意的線程池創建的ThreadLocal要在finally中手動remove,不然會有內存泄漏的問題
你說的內存泄漏具體是怎么產生的?
說了ThreadLocal的結構,主要分兩種場景:主線程仍然對ThreadLocal有引用和主線程不存在對ThreadLocal的引用。第一種場景因為主線程仍然在運行,所以還是有對ThreadLocal的引用,那么ThreadLocal變量的引用和value是不會被回收的。第二種場景雖然主線程不存在對ThreadLocal的引用,且該引用是弱引用,所以會在gc的時候被回收,但是對用的value不是弱引用,不會被內存回收,仍然會造成內存泄漏
線程池的線程是不是必須手動remove才可以回收value?
是的,因為線程池的核心線程是一直存在的,如果不清理,那么核心線程的threadLocals變量會一直持有ThreadLocal變量
那你說的內存泄漏是指主線程還是線程池?
主線程
可是主線程不是都退出了,引用的對象不應該會主動回收么?
(面試官和內存泄漏杠上了),沉默了一會。。。
那你說下SpringMVC不同用戶登錄的信息怎么保證線程安全的?
剛才解釋的有點懵逼,一下沒反應過來,居然回答成鎖了(大腦有點暈了,此時已經一個小時過去了,感覺情況不妙。。。)
這個直接用ThreadLocal不就可以么,你見過SpringMVC有鎖實現的代碼么
有點暈菜。。。
我們聊聊mysql吧,說下索引結構
說了B+樹
為什么使用B+樹?
說了查詢效率高,O(logN),可以充分利用磁盤預讀的特性,多叉樹,深度小,葉子結點有序且存儲數據
什么是索引覆蓋?
忘記了。。。
Java為什么要設計雙親委派模型?
什么時候需要自定義類加載器?
我們做一道題吧,手寫一個對象池
有什么想問我的么
小結
頭條的面試確實很專業,每次面試官會提前給你發一個視頻鏈接,然后準點開始面試,而且考察的點都比較全。
面試官都有一個特點,會抓住一個值得深入的點或者你沒說清楚的點深入下去直到你把這個點講清楚,不然面試官會覺得你并沒有真正理解。二面面試官給了我一點建議,研究技術的時候一定要去研究產生的背景,弄明白在什么場景解決什么特定的問題,其實很多技術內部都是相通的。很誠懇,很感謝這位面試官大大。
總結
從年前開始面試到頭條面完大概一個多月的時間,真的有點身心俱疲的感覺。最后拿到了拼多多、螞蟻的offer,還是蠻幸運的。頭條的面試對我幫助很大,再次感謝面試官對我的誠懇建議,以及拼多多的HR對我的啰嗦的問題詳細解答。
這里要說的是面試前要做好兩件事:簡歷和自我介紹,簡歷要好好回顧下自己做的一些項目,然后挑幾個亮點項目。自我介紹基本每輪面試都有,所以最好提前自己練習下,想好要講哪些東西,分別怎么講。此外,簡歷提到的技術一定是自己深入研究過的,沒有深入研究也最好找點資料預熱下,不打無準備的仗。
這些年看過的書:
《Effective Java》、《現代操作系統》、《TCP/IP詳解:卷一》、《代碼整潔之道》、《重構》、《Java程序性能優化》、《Spring實戰》、《Zookeeper》、《高性能MySQL》、《億級網站架構核心技術》、《可伸縮服務架構》、《Java編程思想》
說實話這些書很多只看了一部分,我通常會帶著問題看書,不然看著看著就睡著了,簡直是催眠良藥?:sweat_smile:?。
最后:歡迎各位學習java和大數據的朋友們加入Java交流學習群: 721506929(我在群里等你喲~)
點擊鏈接加入群聊【java交流學習群】:https://jq.qq.com/?_wv=1027&k=5cjelsQ本群是一個新群,群內提供免費的架構資料還有:Java工程化、高性能及分布式、高性能、深入淺出。高架構。性能調優、Spring,MyBatis,Netty源碼分析和大數據等多個知識點高級進階干貨的免費直播講解 可以進來一起學習交流哦~
轉載于:https://blog.51cto.com/14224832/2371430
總結
以上是生活随笔為你收集整理的写在 2019 年后的蚂蚁、头条、拼多多的面试总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: React组件-事件、状态和生命周期
- 下一篇: eolinker使用初体验(一)