螞蟻金服
一面
一面就做了一道演算法題,要求兩小時內完成,給了長度為N的有重復元素的陣列,要求輸出第10大的數,典型的TopK問題,快排演算法搞定,
演算法題要注意的是合法性校驗、邊界條件以及例外的處理,另外,如果要寫測驗用例,一定要保證測驗覆寫場景盡可能全,加上平時刷刷演算法題,這種考核應該沒問題的,
由于文章篇幅限制,不可能將所有面試題以文字形式把大廠面試題展示出來,本篇為大家精選了一些面試題
多多支持,即可免費獲取資料——三連之后(承諾:100%免費)
快速入手通道:(點這里)下載!誠意滿滿!!!
二面
- 自我介紹
- 開源專案貢獻過代碼么?(Dubbo提過一個列印accesslog的bug算么)
- 目前在部門做什么,業務簡單介紹下,內部有哪些系統,作用和互動程序說下
- Dubbo踩過哪些坑,分別是怎么解決的?(說了例外處理時業務例外捕獲的問題,自定義了一個例外攔截器)
- 開始進入正題,說下你對執行緒安全的理解(多執行緒訪問同一個物件,如果不需要考慮額外的同步,呼叫物件的行為就可以獲得正確的結果就是執行緒安全)
- 事務有哪些特性?(ACID)
- 怎么理解原子性?(同一個事務下,多個操作要么成功要么失敗,不存在部分成功或者部分失敗的情況)
- 樂觀鎖和悲觀鎖的區別?(悲觀鎖假定會發生沖突,訪問的時候都要先獲得鎖,保證同一個時刻只有執行緒獲得鎖,讀讀也會阻塞;樂觀鎖假設不會發生沖突,只有在提交操作的時候檢查是否有沖突)這兩種鎖在Java和MySQL分別是怎么實作的?(Java樂觀鎖通過CAS實作,悲觀鎖通過synchronize實作,mysql樂觀鎖通過MVCC,也就是版本實作,悲觀鎖可以通過select… for update加上排它鎖)
- HashMap為什么不是執行緒安全的?(多執行緒操作無并發控制,順便說了在擴容的時候多執行緒訪問時會造成死鎖,會形成一個環,不過擴容時多執行緒操作形成環的問題在JDK1.8已經解決,但多執行緒下使用HashMap還會有一些其他問題比如資料丟失,所以多執行緒下不應該使用HashMap,而應該使用ConcurrentHashMap)怎么讓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了,
- 實習的時候主管是誰?
- 實習做了哪些事情?
- 你對技術怎么看?平時使用什么技術堆疊?
- 最近有在研究什么東西么
- 你對SRE怎么看
- 對待遇有什么預期么
小結
螞蟻面試比較重視基礎,所以Java那些基本功一定要扎實,螞蟻的作業環境還是挺贊的,因為我面的是穩定性保障部門,還有許多單獨的小組,什么三年1班,很有青春的感覺,面試官基本水平都比較高,基本都P7以上,除了基礎還問了不少架構設計方面的問題,識訓還是挺大的,
拼多多
一面
- 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下,可見性怎么保證?
- 聊專案,系統之間是怎么互動的?
- 系統并發多少,怎么優化?
- 給我一張紙,畫了一個九方格,都填了數字,給一個MN矩陣,從1開始逆時針列印這MN個數,要求時間復雜度盡可能低
- 可以先說下你的思路(想起來了,說了什么時候要變換方向的條件,向右、向下、向左、向上,依此回圈)
有什么想問我的?
二面
- 自我介紹下
- 手上還有其他offer么?(拿了螞蟻的offer)
- 部門組織結構是怎樣的?
- 系統有哪些模塊,每個模塊用了哪些技術,資料怎么流轉的?給了我一張紙,我在上面簡單畫了下系統之間的流轉情況
- 鏈路追蹤的資訊是怎么傳遞的?(RpcContext的attachment,說了Span的結構:parentSpanId + curSpanId)
- SpanId怎么保證唯一性?(UUID,說了下內部的定制改動)
- RpcContext是在什么維度傳遞的?(執行緒)
- Dubbo的遠程呼叫怎么實作的?(講了讀取配置、拼裝url、創建Invoker、服務匯出、服務注冊以及消費者通過動態代理、filter、獲取Invoker串列、負載均衡等程序
- Spring的單例是怎么實作的?(單例注冊表)
- 為什么要單獨實作一個服務治理框架?(說了下內部剛搞微服務不久,主要對服務進行一些監控和性能優化)
- 誰主導的?內部還在使用么?
- 你有想過怎么做成通用么?
- 有什么想問的么?
三面
二面老大面完后就直接HR面了,主要問了些職業發展、是否有其他offer、以及入職意向等問題,順便說了下公司的福利待遇等,都比較常規啦,不過要說的是手上有其他offer或者大廠經歷會有一定加分,
小結
拼多多的面試流程就簡單許多,畢竟是一個成立三年多的公司,面試難度中規中矩,只要基礎扎實應該不是問題,但不得不說作業強度很大,開始面試前HR就提前和我確認能否接受這樣強度的作業,想來的老鐵還是要做好準備,
位元組跳動
一面
- 先自我介紹下
- 聊專案,逆向系統是什么意思
- 聊專案,逆向系統用了哪些技術
- 執行緒池的執行緒數怎么確定?
- 如果是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為什么要設計雙親委派模型?
- 什么時候需要自定義類加載器?
- 我們做一道題吧,手寫一個物件池
- 有什么想問我的么?
小結
頭條的面試確實很專業,每次面試官會提前給你發一個視頻鏈接,然后準點開始面試,而且考察地點都比較全,
面試官都有一個特點,會抓住一個值得深入的點或者你沒說清楚的點深入下去直到你把這個點講清楚,不然面試官會覺得你并沒有真正理解,二面面試官給了我一點建議,研究技術的時候一定要去研究產生的背景,弄明白在什么場景解決什么特定的問題,其實很多技術內部都是相通的,
總結
面試前要做好兩件事:簡歷和自我介紹,簡歷要好好回顧下自己做的一些專案,然后挑幾個亮點專案,自我介紹基本每輪面試都有,所以最好提前自己練習下,想好要講哪些東西,分別怎么講,此外,簡歷提到的技術一定是自己深入研究過的,沒有深入研究也最好找點資料預熱下,不打無準備的仗,
感謝你看到這里,我是程式員麥冬,一個java開發從業者,深耕行業六年了,每天都會分享java相關技術文章或行業資訊
歡迎大家關注和評論文章,快速領取通道:(點這里)免費獲取!誠意滿滿!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/205656.html
標籤:其他
