阿里雲資料庫核心開發面試經歷:儲存引擎+事務實作深度考察
3年資料庫核心開發經驗,完整覆盤阿里雲PolarDB三輪技術面試,涵蓋C++、B+樹、MVCC、WAL、儲存引擎設計等核心考點,附真題彙總與備考建議。
背景介紹
我做了3年資料庫核心開發,之前在一家資料庫創業公司做儲存引擎相關的工作,主要用C++寫儲存層和事務層的程式碼。對B+樹、LSM-Tree這些資料結構算是比較熟悉了。阿里雲PolarDB的資料庫核心開發崗位是我一直想去的,畢竟PolarDB是國產雲資料庫的標竿,技術深度和工程規模都是頂級的。
我是透過前同事內推的,崗位是PolarDB資料庫核心開發工程師。內推後大概一週收到了面試邀請。整個流程是三輪技術面,沒有單獨的HR面,週期大概三週。
面試流程覆盤
一面:C+++資料結構(約60分鐘)
一面面試官是組裡的進階開發,開場先聊了下我的專案經歷,然後直接進入技術環節。
C++部分:面試官問了智慧指標的實作原理,shared_ptr的參照計數怎麼保證執行緒安全,我說了用原子操作。然後問了RAII機制、move語義、完美轉發。還問了一個比較細節的問題:unique_ptr為什麼不能拷貝,我說了刪除了拷貝建構函式和拷貝指定運算子。面試官又追問了如果要在函式間傳遞unique_ptr怎麼辦,我說用std::move。
資料結構部分:面試官讓我手寫一個LRU Cache,要求O(1)的get和put。我用了雜湊表+雙向鏈結串列的經典方案,寫完面試官讓我分析時間複雜度和空間複雜度。然後問了紅黑樹和B+樹的區別,以及在資料庫索引中為什麼選擇B+樹而不是紅黑樹。我從磁碟IO的角度詳細解釋了B+樹的優勢:更大的扇出、更少的層級、範圍查詢友善。
演算法部分:給了一道題——在一個有序陣列中找到第一個大於等於target的元素,就是lower_bound的實作。我寫了二分搜尋,面試官讓我證明正確性,我用了迴圈不變量來證明。
一面整體感覺偏基礎,但問得比較細,不是那種浮於表面的八股。
二面:B+樹+MVCC+WAL(約90分鐘)
二面是整個面試最硬核的一輪,面試官是資料庫核心的資深專家。
B+樹部分:面試官讓我詳細講B+樹的插入和刪除過程,包括節點的分裂和合併。我畫了分裂的示意圖,講了中間key上提的邏輯。面試官追問了B+樹在並發場景下怎麼做,我講了latch coupling(蟹行協定)的方案,以及B-link Tree的最佳化思路。然後問了一個很深入的問題:B+樹節點分裂時如果crash了怎麼辦?我說了透過WAL日誌保證原子性,分裂操作先寫日誌再修改頁面。
MVCC部分:面試官讓我詳細講InnoDB的MVCC實作,包括隱藏列(DB_TRX_ID、DB_ROLL_PTR)、Undo Log的版本鏈、Read View的可見性判斷規則。我按照RC和RR兩個隔離級別分別講了Read View的生成時機不同。面試官追問了RR級別下為什麼不能完全避免幻讀,我講了當前讀和快照讀的區別,以及Next-Key Lock如何解決幻讀。然後問了一個開放題:如果讓你設計一個MVCC方案,你會怎麼做?我從版本儲存、垃圾回收、可見性判斷三個維度回答了。
WAL部分:面試官問了WAL的原理和作用,Redo Log的寫入流程(先寫Log Buffer再刷盤),以及組提交(Group Commit)的最佳化。然後問了一個關鍵問題:如何保證Redo Log和Binlog的一致性?我講了兩階段提交的方案,XA協定的流程,以及如果某階段crash了怎麼恢復。面試官對這個回答比較滿意,又追問了分散式事務的2PC和資料庫內部2PC的區別。
二面聊了整整90分鐘,感覺腦力消耗巨大,但也確實過癮。
三面:儲存引擎設計+專案深挖(約75分鐘)
三面面試官應該是技術總監級別的,問題更偏向架構和設計。
儲存引擎設計:面試官給了一個開放題——如果讓你設計一個支援高並發寫入的儲存引擎,你會怎麼設計?我從LSM-Tree的架構講起,說了MemTable、Immutable MemTable、SSTable的分層結構,以及Compaction策略。面試官追問了LSM-Tree的讀放大問題怎麼解決,我講了Bloom Filter、索引分層、快取策略。然後面試官讓我比較LSM-Tree和B+ Tree的優劣,以及什麼場景下該選哪個。我從寫放大、讀放大、空間放大三個維度做了對比分析。
專案深挖:面試官讓我詳細講了之前做的一個頁面壓縮功能,從需求背景、方案設計到效能測試。我重點說了字典壓縮和變長頁的方案,面試官對壓縮率的提升很感興趣,問了具體的測試資料。然後問了我遇到過最難的技術問題是什麼,我講了一個並發Bug的排查過程,從現象到定位到修復,面試官聽得很認真。
綜合考察:面試官問了我對雲原生資料庫的理解,儲存計算分離的架構優勢,以及PolarDB和Aurora的架構差異。我從日誌即資料的理念、共享儲存的實作、RO節點的擴展性幾個角度分析了。
真題彙總
1. shared_ptr的參照計數怎麼保證執行緒安全?
2. unique_ptr為什麼不能拷貝?如何在函式間傳遞?
3. 手寫LRU Cache,要求O(1)的get和put
4. 為什麼資料庫索引選擇B+樹而不是紅黑樹?
5. B+樹節點的分裂和合併過程?
6. B+樹在並發場景下怎麼做?latch coupling方案?
7. B+樹節點分裂時crash了怎麼辦?
8. InnoDB的MVCC實作原理?
9. RR級別下為什麼不能完全避免幻讀?
10. 如何設計一個MVCC方案?
11. WAL的原理和作用?Redo Log的寫入流程?
12. 如何保證Redo Log和Binlog的一致性?
13. 設計一個支援高並發寫入的儲存引擎
14. LSM-Tree的讀放大問題怎麼解決?
15. LSM-Tree和B+ Tree的優劣對比?
16. PolarDB和Aurora的架構差異?
心得建議
1. C++基礎要扎實到細節:資料庫核心開發對C++的要求非常高,不是會寫就行,還要理解底層機制。智慧指標、RAII、move語義這些幾乎是必考的,建議仔細讀《Effective C++》和《C++ Concurrency in Action》。
2. 資料結構要能手寫能講清:B+樹是資料庫核心面試的核心考點,不僅要能講清楚原理,還要能手寫關鍵操作。建議自己實作一個簡化版的B+樹。
3. 事務和並發控制是重中之重:MVCC、WAL、2PC這些是資料庫核心的靈魂,面試中幾乎一定會深挖。建議讀《Database System Concepts》的事務章節和《MySQL技術內幕:InnoDB儲存引擎》。
4. 要有系統設計的全域觀:三面的儲存引擎設計不是考你某個元件,而是考你對整個儲存引擎架構的理解。建議讀LevelDB和RocksDB的原始碼,理解LSM-Tree的完整實作。
5. 專案經驗要有深度:面試官會深挖你的專案細節,包括設計決策的原因、遇到的問題和解決方案。建議準備2-3個有深度的專案,用STAR法則梳理。
FAQ
Q:阿里雲資料庫核心面試對C++要求到什麼程度?
A:要求比較高。不是那種「會寫C++就行」的程度,而是要理解C++的記憶體模型、並發機制、模板元程式設計等。建議至少有3萬行以上的C++專案經驗。
Q:沒有資料庫核心經驗能過嗎?
A:很難。阿里雲PolarDB崗位明確要求有資料庫核心開發經驗。如果只有應用層經驗,建議先參與一些開源資料庫專案,比如TiDB、RocksDB。
Q:面試會問作業系統和電腦體系結構嗎?
A:會。資料庫核心和OS緊密相關,面試官會問記憶體管理、檔案系統、CPU快取等相關知識。建議複習作業系統課程的重點章節。
Q:PolarDB團隊的工作強度大嗎?
A:據我了解,PolarDB團隊的工作強度在阿里雲內部算中等偏上,但技術氛圍很好,能學到很多東西。面試官也提到團隊有比較完善的技術分享機制。