前言(也就是廢話)
今年年底,額,不對,應該說是去年了,我開始進行了一個多月的面試之旅。
面試的公司並不多,但從體量上來看,基本算是一二三線的大廠都囊括了,其中還包括BAT,當然,最後我也是順利的拿到了offer,雖然不是很理想,但我也挺滿意的,畢竟對我這種一直嚮往大廠的人來說,能進大廠已經算是很好的一次職業躍遷。在這個過程中,我也積累了不少面試經驗,並且跟很多朋友交流過,不少人都說讓我寫篇面經分享下經驗(其中也就幾個人)。
我這個人呢,別的優點不說,朋友的善意請求我基本都很少推辭的,既然他們都這麼熱切的請求了,那我也不負君期,捨棄一天假期來寫篇實戰面經分享下。
個人背景
好了,不說廢話了,先介紹一下個人背景,本人是17年畢業的,算到去年年底的話大概是四年半的工作經驗,我當時第一個面試的公司是廣州這邊的歡聚時代集團,也就是yy直播的前身,後來還面試了位元組、Lazada、騰訊、網易等公司,最後拿到歡聚和網易的offer,結果不算圓滿吧,但怎麼說呢,體驗這麼一圈下來,感覺大廠的面試難度也沒想象中那麼誇張,其中位元組和Lazada我都是在技術終面被刷的,詢問過內推的朋友,可能未必是技術方面的原因。當然,這是後話了,我想說的是,就算是面試大廠,只要準備充足的話,還是可以從容應對的。
每一次面試完之後我都有做問題的記錄和覆盤,基於篇幅原因,本文只會分享歡聚的面經,其他公司的面經後面再給大家整理好了。
歡聚時代一面(1h)
先做下自我介紹,固定環節
面試官:既然你用Java語言,那我們先講點Java基礎的東西吧,你說下Java有哪些鎖?
按照機制區分的話,Java中包含的鎖可以分為公平鎖和非公平鎖、樂觀鎖和悲觀鎖,獨佔鎖和共享鎖,還有什麼無鎖,偏向鎖,輕量鎖,重量級鎖之類的吧,比如Synchroized升級的過程中就涉及到這幾種鎖的轉換,大概就這些吧
面試官:好,那你說下Synchroized的升級過程?
這個應該是基本的八股文了吧,不用多說
面試官:用過HashMap吧,它的儲存結構是怎樣的?
不用多說,八股文最常見的,1.8之前的版本就是陣列加連結串列,1.8之後連結串列長度達到8的閾值轉成紅黑樹,當然,回答的時候儘量不要這麼簡單,可以加多點料,比如說下為什麼1.8之後這麼轉換,有什麼優點之類的,充充面子,給面試官有個我們基礎還可以的印象
面試官:Volatile用過吧 ,有什麼作用
修飾變數,保證多執行緒下修改共享變數對其他執行緒可見;禁止指令重排序
面試官:Volatile是怎麼保證可見性的,原理是什麼
基於快取一致協議(MESI)
面試官:執行緒池有哪些引數,有什麼作用,執行過程如何
基礎八股文,不多說
面試官:拒絕策略有哪些,你們用的是哪個
CallerRunsPolicy:執行緒池之外的執行緒直接呼叫run方法執行,除非執行緒池shutdown
AbortPolicy:直接丟棄任務,拋異常,預設策略
DiscardPolicy :丟棄任務,不報錯
DiscardOldestPolicy:拋棄阻塞佇列最早的那個任務,把最新的任務重新放到佇列中
面試官:有哪些阻塞佇列,可以不斷加任務的(SynchronousQueue),如果用SynchronousQueue,有兩個任務進來,哪個能進佇列,還是都不行
取決於執行緒池情況,這個佇列不保留任務的,有任務被提交就直接轉發給執行緒或建立新執行緒執行,如果最大執行緒數滿了,不會進佇列
**面試官:執行緒池如果執行緒空閒,哪個引數可以設定多久銷燬 **
keepAliveTime
面試官:看到你簡歷上專案用了mq啊,為什麼用RocketMQ,不用其他,說下選型原因
上家公司的專案是電商系統,從效能和業務上綜合考慮,RocketMQ比較適合,也足夠用,Kafka的話雖然效能更高,但功能較為單一。總的來說,在效能滿足需求的情況下,大資料、日誌處理場景基本選用Kafka,業務處理相關選擇RocketMQ
面試官: 你們專案用的是哪個垃圾收集器?
CMS
面試官:為什麼用CMS,不用G1?
歷史原因,一開始建立專案用的就是CMS,團隊人員也很少G1方面的調優經驗
面試官:CMS有什麼缺點你知道嗎?
對CPU敏感,如果CPU數量少,吞吐量會下降很多;
無法處理浮動垃圾,併發清除階段使用者執行緒還在執行,可能會產生浮動垃圾,達到某種程度就會出現"Concurrent Mode Failure",然後導致了一次full gc的產生
面試官:針對CMS產生的浮動垃圾,有什麼辦法
可以設定一個引數-XX:CMSFullGCsBeforeCompaction,表示CMS還要再執行多少次full GC才會做壓縮,預設是0就可以。
面試官:什麼時候會發生老年代的GC?
老年代發生垃圾回收說明觸發了FULL GC,一般是老年代空間不足或者呼叫System.gc出發
面試官:你有沒有遇到過線上的一些故障什麼的,舉個例子
排除網路斷電等抽風的情況,一般線上問題都是業務程式碼出現問題或者訪問量過高導致的,檢查的方式也比較通用,就是經典的top命令檢視異常的執行緒,然後再根據是否是VM Thread決定用jstack
還是jstat
命令作進一步的排查
面試官:說下MySQL吧,你瞭解它的索引結構嗎?
資料庫必問到的索引八股文,B+樹
面試官:主鍵索引和非主鍵索引區別,索引覆蓋怎麼回事?
在innodb引擎中,非主鍵索引的葉子節點存放的是主鍵的值,而主鍵索引的葉子節點存放的是整行資料,如果沒有發生索引覆蓋的情況,根據非主鍵索引查到對應的資料還需要到主鍵索引做一次回表查詢。
索引覆蓋指的是一個索引包含了所有需要的欄位,不需要回表查了
面試官:如果有個聯合索引a,b,然後order a asc, b desc,會用到索引嗎
8.0之後的版本可以,之前的版本不支援desc排序
面試官:你們是怎麼做sql優化的?
一般來說,針對sql的優化都是在業務程式碼開發前就要做好的,除了基本的表欄位設計,在開發的過程還要針對業務方法輸出對應的sql語句,然後做好對應的sql review以及explain分析,同時還要考慮到業務的訪問量,如果過高的情況下是否需要走強制索引之類的優化
面試官:你用過Redis做分散式鎖,那你說說Redis分散式鎖的核心要保證哪些因素?
加鎖,解鎖,給鎖設定超時時間
面試官:分散式鎖如果執行緒拿不到鎖,直接就返回嗎
不是,可以設定等待時間,比如Redisson就支援
面試官:分散式鎖如果master掛了,然後鎖沒有同步到其他機器,這時別的執行緒也拿到鎖了,怎麼辦
Redis做分散式並非絕對安全,最保底的方式就是保證業務冪等
面試官:如果鎖即將過期,但業務沒處理完,該怎麼處理
可以參考Redission的看門狗設計,就是定時對即將失效的鎖續期
面試官:冪等性和分散式鎖是同時要的嗎,為什麼都有了冪等性還要加鎖
分散式鎖可以防止使用者誤操或者流量過高的情況,如果完全由業務冪等保底,可能會讓流量都達到db(很好的問題)
面試官:你簡歷上寫了快取異常的處理方案,那你說說快取穿透是什麼樣子,怎麼處理,跟快取雪崩有什麼區別?
快取穿透:指快取和資料庫中都沒有的資料,這樣每次請求都會去查庫,不會查快取,如果同一時間有大量請求進來的話,就會給資料庫造成巨大的查詢壓力,甚至擊垮db系統。
一般解決方案有兩種:
1、快取空物件,但設定一個較短的時間,避免佔用大量記憶體
2、布隆過濾器
快取雪崩:大量的key同一時間失效,導致流量都打到db
解決方案一般是設定給key設定隨機過期時間,或者互斥鎖的方式抵擋請求
面試官:專案有用到布隆過濾器嗎,如果用的話要多大記憶體
沒用到,說不上來,但也別這麼直接,可以適當延伸一下,比如說經過綜合考慮,專案場景在這方面不需要做那麼複雜的功能,或者是運維層面做了大量的異常請求攔截之類的,別讓面試官覺得你這方面沒什麼思考。
面試官:你簡歷上還寫用了Spring,那你瞭解Spring AOP的原理嗎?
常見的八股文,基於Java動態代理,簡單描述下就好
面試官:如果一個類有兩個方法加了註解,然後一個呼叫另一個方法,那個方法的註解會生效嗎?
不會,因為同個類的話不是代理物件呼叫方法
面試官:說說專案方面吧,你簡歷上的領取優惠券有哪些流程,為什麼用快取還要接近100ms的rt
引入了RocketMQ非同步入庫的方式做削峰,防止流量過高的時候介面RT過高,至於為什麼還接近100ms,是因為領取優惠券的邏輯一般是以券包方式,也就是同時領取多張優惠券,判斷的邏輯比較多,所以在高峰期會耗時點。
面試官:你寫了訂單資料是以使用者id維度分表,是基於什麼考慮
業務場景需要滿足使用者可以檢視自己訂單
如果查的維度是其他欄位,比如商品id,怎麼辦
可以把訂單資料放es,或者定時任務將資料加到一張寬表
面試官:你們的專案每臺機設定最大多少執行緒訪問,有測過可以支撐多大的訪問量嗎
見鬼,剛好那時候腦子發昏不記得,所幸轉換了個思路,表達我們專案最高cpu也就達到百分之30,說明還可以撐起至少一倍的訪問量,我真聰明啊
印象中後面又問了幾道專案方面的問題,然後就結束了面試,總的來說,第一面的問題難度不算高吧,雖然針對的點比較多,但也基本是常見的八股文,專案場景方面沒什麼考究,準備好的話還是很好面對的,不出意外,第二天hr那邊就通知我一面通過,然後就約了二面的時間。
二面(1h)
一面隔了一個星期左右就開始第二輪面試,同樣也是遠端視訊,不過跟第一面不同,這一面考察的大多跟專案有關,所以,在面試前對於專案方面的準備是必須下功夫的。
不用問,剛開始肯定是自我介紹了,介紹完面試官眉頭緊鎖了將近一分鐘才開口.........
面試官:看你的簡歷,你在上家公司也呆了兩年了,為什麼要這個時候出來找機會
這點不用說啦,前爸爸不都說了嗎,要麼錢少了,要麼受委屈了,當然面試的時候肯定不能這麼輕浮,就按照常規的說法,比如說個人發展,職業規劃什麼的說下就好
面試官:你覺得現有的公司滿足不了你了嗎
是的,這也是我長久以來的考慮(廢話,不然我閒的蛋疼來面試)
面試官:你說你看過jdk原始碼,你覺得哪個設計驚豔了你
這個因人而異,我就針對比較熟悉的AQS部分和HashMap索引設計那塊做了講解
面試官:快取血崩和穿透該怎麼做
一面就問過了,照著背就行
面試官:你簡歷上寫了sql優化,那你是怎麼針對索引做設計的
常規的八股文,儘量滿足常用查詢的欄位走索引,然後多用explain做分析就可以規劃大部分的情況。
後面的問題基本都是專案方面的細節了,比如優惠券怎麼防刷,工作中你覺得有所成就的是哪一次,做了什麼,這些問題沒有參考答案,每個人的專案不同,工作經歷也不同,只要針對自己的實際情況回答就可以。
不過,這個過程還是有幾點值得跟大家分享下,就是分表遷移方面和高併發突發流量的問題。
因為筆者之前所負責的專案是電商系統,日活量達到百萬級別,對訂單那部分做了分表的處理,也算是技術上的亮點吧,簡歷上肯定是著重說明了,所以面試的時候也是一直被詢問這兩方面的場景。
分表的話呢,我們之前是把訂單的資料從單表同步到100張新表,基於使用者id做sharding key,遷移資料的過程,需要考慮到資料同步的一致性,以及不對現有的業務流程造成影響,所以我們採用的是訂閱binlog的方式來遷移資料,算是比較常規的方案。
但怎麼說呢,雖然方案很常見,但實際操作的時候你會發現需要考慮的點非常的多,比如歷史資料和增量資料的同步問題,是停服還是不停服遷移,資料遷移一致後該怎麼切換新系統,以及新系統上線後出現異常資料該怎麼回滾回舊系統的問題等等,如果有同學做過分表遷移的話,這些方面的問題應該都是頭疼過的。當然,你越頭疼的點面試官就越是喜歡考究,所以,這方面的技術處理事先要考慮到各種可能性,你才能越有餘力應付各種刁鑽的面試題。
除此之外,筆者所從事的電商專案也包含了秒殺那部分的功能,雖然QPS不高,但也需要做好秒殺系統的常規處理,比如限流,高併發扣減庫存,保證不超賣等。
以我個人的經驗來看,處理秒殺的高併發場景無非兩種方案,要麼同步,要麼非同步,實際操作無非就是加機器或者是放到佇列等待,當然,實際要考慮的點非常的多,在高流量下所有的業務缺陷都會被無限放大,你需要考慮各種異常的情況做好預防措施,還有補償機制,限於篇幅,我無法在這裡給大家講解太多,而且我本人也並非對所有的場景有處理經驗,只能介紹幾點思路讓大家去思考,
比如限流方面有什麼策略,怎麼防止大量的惡意請求;
扣減庫存那裡是直接扣db的庫存資料,還是預減庫存,如果是預減庫存的話,Redis減了庫存但db沒減怎麼辦;
秒殺的過程有些服務如Redis掛了,該怎麼處理;
流量突然增大,大到某個商品的訪問量超過了Redis的單機閾值怎麼辦;
如果引入訊息佇列做削峰元件,那麼消費過慢導致使用者一直等待怎麼處理等等。
雖說實際中我們基本沒有機會遇到那麼大的訪問量,但你無法預防面試官是不是會考察,所以,如果你的專案中涉及到高併發場景的話,我是比較建議你在這些方面去下點功夫準備的。
接著說面試吧,問完了專案方面的東西,也基本沒什麼技術題了,剩下的算是一些軟實力方面的問題,比如為什麼寫部落格啊;部落格訪問量挺高的,是有專門運營過嗎;還有未來有什麼職業規劃之類的,這些問題也是因人而異,雖說沒什麼難度,但事前準備的好點還是更利於你面試的過程表達流暢的,所以,也建議大家可以多準備下軟實力方面的題。
結論:這一面八股文問的不多,專案方面問的比較多,軟實力方面也略有涉及,總的來說,難度是有的,面試的流程也挺順利,幾天後就通知面試通過。
三面(2h)
三面的面試官是歡聚的技術總監,也是視訊面試,這一面沒問技術問題,更多像是在聊天一樣,說實話,面試官是真能聊啊,整個面試過程長達兩個小時,他一直在介紹歡聚時代的一些歷史以及我面試崗位那個部門的業務情況,同時還對我未來的技術方向做了一些建議,讓我受益匪淺。總的來說,這一面雖然在技術面試上沒什麼收穫,但能遇到這麼一位熱心的面試官也算是我的運氣了,這裡不勝感激,可惜後面有更好的offer,我也沒機會跟他做同事了。
hr面
hr面也沒什麼好說的,交流了我的職業情況和期待薪資,幾天後給完流水就發了offer。
總結
整個面試過程就大概是這樣了,我想對大家來說,看完文章有收穫的可能是一面和二面的分享,總的來說,歡聚的技術面試難度不算很高,都是比較常規的面試考察點,我個人的話還是那句話,只要事先準備充足,還是可以從容應對的。
個人體會上的話也沒什麼好說的,畢竟整個過程比較順利,沒什麼刁鑽的題,後面我還會寫幾篇面經介紹下我面試其他公司遇到的難題,希望能幫到各位看官少遇點坑。好了,今天就這樣了,我們下期再見。
如果您覺得文章有用的話,歡迎點個推薦支援一下,這將是對我創作的最好鼓勵!
作者:鄙人薛某,一個不拘於技術的網際網路人,喜歡用通俗易懂的語言來解構後端技術的知識點,想看更多精彩文章的可以關注我的公眾號,微信搜尋【鄙人薛某】即可關注