(給ImportNew加星標,提高Java技能)
今天我想跟你探討的話題是:當面試官問你某某組件的實現原理是什麼時,他究竟想了解什麼?你又需要了解到什麼層面上呢?
經歷過面試的你一定知道,社招崗位的面試里一定會包含項目經歷介紹的。面試官會問及一些特定場景下實現方案的設計,還會問你一些基礎知識和基本算法。而在考察基礎知識時,你一定被面試官追問過,某某組件的實現原理是什麼。
那麼,對於僅僅使用組件的開發人員來說,了解組件的實現原理真的很重要嗎?這會不會是面試官的故意刁難呢?在回答這些問題之,我先跟你分享一下我面試候選人的經歷。
當時,候選人已有五年的工作經驗。雖然沒什麼大廠工作經歷,但是從簡歷來看,他對於互聯網領域常見的一些組件,比如 Redis、MSQL、 Dubbo、 Spring Boot 等都有比較深入的了解。這對於求賢若渴的我們來說無疑有着巨大的吸引力,於是邀約了面試。面試過程中,候選人對項目整體的把控不錯,對項目中的問題以及項目未來的發展思路都有一定的見解。可是當我問及一些基礎的知識以及用過的一些組件時,出現了問題。
你為什麼會在項目里使用 Redis 呢?又是如何使用的呢?
當時,我們發現項目中某些讀取接口有一些性能上的問題,所以會使用 Redis 作為緩存提升讀取性能…….還 使用 Redis 做一些數據持久化存儲,兩者的使用規範是……後面發現在擴展性上存在問題,我們又調研了 Redis Cluste 和 Codis。
使用 Redis 時,你用了哪些數據結構呢?
基本的數據結構都有使用,比較常用除了 Key-value 以外還有 Hash 和 SortedSet。
請簡單介紹一些 SortedSet 使用的數據結構。
這個不太了解。
那 SortedSet 是一種排序列表,如果由你來實現的話,你會怎麼實現呢?
嗯……可以用紅黑樹。
那紅黑樹的原理是怎樣的呢?
是這樣的……blablablabla。
那你聽說過跳表嗎?
聽說過,它的原理是這樣的……
那你覺得 Redis 的 SortedSet 結構是使用紅黑樹好,還是使用跳表好呢?
你可以看到,Redis 作為高並發場景下經常使用到的組件,雖然我們僅僅只是使用它,但面試官在詢問你關於它的內部原理時,是想了解組件中使用的基本數據結構、算法以及設計思想你是否真正地了解和掌握。也就是說,他並不是在故意刁難你,而是在考察你的基礎知識是否紮實。
再舉一個例子,Java 面試中經常被問到的個數據結構就是 HashMap。毫不誇張地說,十個 Java 面試中有八個會問到 Hash Map,比如我就會問到這麼幾個問題:
HashMap 實現的底層數據結構是怎樣的?
如果發生 Hash 衝突,要怎麼解決?常見的解決方式是怎樣的?
JDK 8 對 Hash Map 做了什麼樣的優化呢?
紅黑樹的實現原理是怎樣的?相比於鍊表它的優勢和劣勢都是什麼?
HashMap 是線程安全的嗎?
ConcurrentHashMap 是如何做到線程安全的呢?
你大可以試着回答一下 ,看看自己對上面幾個問題是一知半解呢?還是能全部回答上來呢?
你看,雖然面試官問的是 JDK 中一個類的實現原理,但這裡面涉及了數組、鍊表、紅黑樹等基本的算法;解決Hash 衝突的基本思路;並發線程安全的含義,以及解決線程不安全問題的基本思路,並且也可以引出和線程安全相關的一系列問題。
了解了這些基本原理,除了可以夯實你的基礎知識以外,還可以為你的方案設計提供思路。比如說,當需要更高效的讀寫內存中的數據時可以怎麼做,遇到並發問題時要如何來解決等等。
最後,也是最重要的,了解了組件的基本原理你在使用這些組件的時候才能夠充分發揮它的優點、避免踩坑,在遇到問題的時候也會有排查的思路。
我跟你分享一個真實案例。
在之前主導的一個項目中,我們使用 Memcached 作為緩存組件來提升數據的讀取性能。在使用的過程中,我們發現一個存儲用戶認證信息的緩存的命中率極低,只有 20%。
因為這個認證信息只有極少數的用戶會有,大部分的用戶在數據庫中是沒有這個數據的,所以最初我認為是因為查詢數據庫的時候,沒有査詢到數據導致沒有設置到緩存,所以每次查詢緩存的時候就不會命中。
於是,我增加了「從數據庫中查詢到空數據後也回中緩存」的邏輯,但是上線之後效果並不明顯。這時,我查看了一下 Memcached 節點的統計信息,發現單個節點 2G 的內存空間僅僅被使用了300M,而且緩存 item 剔除數非常高,達到了幾十億。
我們知道 Memcached 內部採用的是名為 Slab Allocator 的機制來分配和管理內存的,主要為了解決內存分配碎片的問題。這種機制會預先分配若干組內存區域,每一組稱為一個 slab class,每個 slab class 下的各個內存區域大小是相同的,每個內存區域稱之為 chunk。
當存儲一個數據時,先要看這個數據大小是多少,要存儲在哪一個 slab class 下。如果這個 slab class 沒有足夠的空間了,那麼會查找更大的 slab class 直到找到合適的為止。
於是,我考慮是不是因為緩存用戶認證信息時沒有找到合適的 slab class,才導致數據不斷地被剔除出緩存,從而造成緩存命中率低。所以我看了一下 slab 的統計信息,發現 slab class5 占用了 2G 內存中的 1.9G,而用戶認證信息會被存放在 slab class6 下,而這個 slab class 的剔除數量非常高。再抓取這個 slab class 下的一小部分數據,發現確實都是用戶認證信息數據。此時,我才找到問題的根本原因。
你看,如果不了解 Memcached 的內存分配原理,你可能永遠都無法徹底解決這個問題。
所以,在面試的過程中,當你被問到組件的實現原理時,面試官其實想要了解你,是否對於實現原理中涉及的基礎知識有足夠的了解?在實際開發中,你是否能夠運用這些基礎知識來設計合理的方案?以及,當這些組件發生問題的時候,你是否有思路解決?
所以,其實你無需對組件達到源代碼級別的了解,只需要深入了解它的實現原理,再結合一些基礎知識,如算法、網絡、操作系統等等,就足夠應對 80% 的面試問題。
不過,掌握這些知識並不是一朝一夕的,你需要在課下多多用功,查鬩相關的資料和書籍。在這裡,我提供給你幾點想要了解一些基礎知識,你可以啃一啃這個領域的經典書籍,比如《算法導論》、《TCP/IP 協議詳解》、《深入理解計算機系統》等等。
對於一些開源組件你可以多讀一讀它們的官方文檔,文檔上一般會有這個組件的設計思路,架構講解以及一些細節知識點的介紹,對於一個組件的使用者來說足夠了。
厚積才能薄發,積累得多了,在方案設計和問題排查的時候才會有更多的思路。你在實際工作中,才會更加遊刃有餘。
轉自:JAVA 架構師筆記,
鏈接:zq99299.github.io/note-architect/hc/01/06.html
- EOF -
1、服務端高並發分布式架構演進之路
2、架構與思維:設計容量,到底有多重要 ?
3、8張架構圖告訴你應該如何優雅的設置RPC超時重試
看完本文有收穫?請轉發分享給更多人
關注「ImportNew」,提升Java技能
點讚和在看就是最大的支持❤️