我是 Guide 哥,一 Java 後端開發,半個全棧,自由的少年。java
這篇文章是一位 女讀者 (加粗!太可貴)的面試阿里的經歷分享,雖然第二面面完就失敗了,可是這樣的經歷對本身幫助仍是很大的。面試
下面的一些問題很是具備表明性,部分問題我簡單作了修改(有些問題表述的不那麼準確)。這些問題對於你們用於自測或者準備面試都頗有幫助。redis
我只給出了少部分問題的參考答案,由於本身真的抽不出有時間來把每個問題都細心解答一遍了。單單是回答了下面的少部分問題,就從昨晚 9 點一直忙到 12 點半。算法
有答案需求的小夥伴,評論區安排,須要的人多的話,我這週末花時間把一份頂好的參考答案都整出來!數據庫
小聲 BB:寫參考答案其實挺難的,相比於面試的時候回答問題來講。不少面試官本身問的問題可能連本身都不清楚,哈哈哈!單單是回答了下面的少部分問題,就從昨晚 9 點一直忙到 12 點半。
自我介紹就不說了,每一面都會讓你說。後端
這個面試前確定要準備的,Guide 哥的文章中也提到了不少次,我準備的還算充分,面試官比較滿意。
---第 4 題參考答案---設計模式
JDK 動態代理只能只能代理實現了接口的類,而 CGLIB 能夠代理未實現任何接口的類。 另外, CGLIB 動態代理是經過生成一個被代理類的子類來攔截被代理類的方法調用,所以不能代理聲明爲 final 類型的類和方法。就兩者的效率來講,大部分狀況都是 JDK 動態代理更優秀,隨着 JDK 版本的升級,這個優點更加明顯。緩存
---第 5 題參考答案---安全
Java 語言中的類、方法、變量、參數和包等均可以註解標記,程序運行期間咱們能夠獲取到相應的註解以及註解中定義的內容,這樣能夠幫助咱們作一些事情。好比說 Spring 中若是檢測到說你的類被 @Component
註解標記的話,Spring 容器在啓動的時候就會把這個類歸爲本身管理,這樣你就能夠經過 @Autowired
註解注入這個對象了。網絡
---第 6 題參考答案---
反射介紹:
JAVA 反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲 java 語言的反射機制。
反射的優缺點以下:
爲何框架須要反射技術?
在咱們平時的項目開發過程當中,基本上不多會直接使用到反射機制,但這不能說明反射機制沒有用,實際上有不少設計、開發都與反射機制有關,例如模塊化的開發,經過反射去調用對應的字節碼;動態代理設計模式也採用了反射機制,還有咱們平常使用的 Spring/Hibernate 等框架也大量使用到了反射機制。
舉例:
Class.forName()
經過反射加載數據庫的驅動程序;更多 Java 基礎相關的問題,請參考這篇頂好頂完善的文章: 「Java 面試題精華集」Java 基礎知識篇(2020 最新版)附 PDF 版 ! 。
集合框架相關的問題的答案,請參考這篇頂好頂完善的文章: 「Java 面試題精華集」1w 字的 Java 集合框架篇(2020 最新版)附 PDF 版 ! ,裏面介紹的很是詳細很是棒!
---第 6 題參考答案---
線程死鎖描述的是這樣一種狀況:多個線程同時被阻塞,它們中的一個或者所有都在等待某個資源被釋放。因爲線程被無限期地阻塞,所以程序不可能正常終止。
以下圖所示,線程 A 持有資源 2,線程 B 持有資源 1,他們同時都想申請對方的資源,因此這兩個線程就會互相等待而進入死鎖狀態。
---第 7 題參考答案---
一般狀況下,咱們建立的變量是能夠被任何一個線程訪問並修改的。若是想實現每個線程都有本身的專屬本地變量該如何解決呢? JDK 中提供的ThreadLocal
類正是爲了解決這樣的問題。 ThreadLocal
類主要解決的就是讓每一個線程綁定本身的值,能夠將ThreadLocal
類形象的比喻成存放數據的盒子,盒子中能夠存儲每一個線程的私有數據。
若是你建立了一個ThreadLocal
變量,那麼訪問這個變量的每一個線程都會有這個變量的本地副本,這也是ThreadLocal
變量名的由來。他們可使用 get()
和 set()
方法來獲取默認值或將其值更改成當前線程所存的副本的值,從而避免了線程安全問題。
再舉個簡單的例子:
好比有兩我的去寶屋收集寶物,這兩個共用一個袋子的話確定會產生爭執,可是給他們兩我的每一個人分配一個袋子的話就不會出現這樣的問題。若是把這兩我的比做線程的話,那麼 ThreadLocal 就是用來避免這兩個線程競爭的。
ThreadLocal
最終的變量是放在了當前線程的 ThreadLocalMap
中,並非存在 ThreadLocal
上,ThreadLocal
能夠理解爲只是ThreadLocalMap
的封裝,傳遞了變量值。 咱們能夠把 ThreadLocalMap
理解爲ThreadLocal
類實現的定製化的 HashMap
。 ThrealLocal
類中能夠經過Thread.currentThread()
獲取到當前線程對象後,直接經過getMap(Thread t)
能夠訪問到該線程的ThreadLocalMap
對象。
每一個Thread
中都具有一個ThreadLocalMap
,而ThreadLocalMap
能夠存儲以ThreadLocal
爲 key ,Object 對象爲 value 的鍵值對。
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) { ...... }
好比咱們在同一個線程中聲明瞭兩個 ThreadLocal
對象的話,會使用 Thread
內部都是使用僅有那個ThreadLocalMap
存放數據的,ThreadLocalMap
的 key 就是 ThreadLocal
對象,value 就是 ThreadLocal
對象調用set
方法設置的值。
ThreadLocalMap
是ThreadLocal
的靜態內部類。
---第 2 題參考答案---
周志明先生在《深刻理解 Java 虛擬機》第二版中 P92 如是寫道:
「老年代 GC(Major GC/Full GC),指發生在老年代的 GC……」
上面的說法已經在《深刻理解 Java 虛擬機》第三版中被改正過來了。感謝 R 大的回答:
總結:
針對 HotSpot VM 的實現,它裏面的 GC 其實準確分類只有兩大種:
部分收集 (Partial GC):
整堆收集 (Full GC):收集整個 Java 堆和方法區。
---第 3 題參考答案---
方法區也被稱爲永久代。不少人都會分不清方法區和永久代的關係,爲此我也查閱了文獻。
《Java 虛擬機規範》只是規定了有方法區這麼個概念和它的做用,並無規定如何去實現它。那麼,在不一樣的 JVM 上方法區的實現確定是不一樣的了。 方法區和永久代的關係很像 Java 中接口和類的關係,類實現了接口,而永久代就是 HotSpot 虛擬機對虛擬機規範中方法區的一種實現方式。 也就是說,永久代是 HotSpot 的概念,方法區是 Java 虛擬機規範中的定義,是一種規範,而永久代是一種實現,一個是標準一個是實現,其餘的虛擬機實現並無永久代這一說法。
---第 4 題參考答案---
JDK 1.8 的時候,方法區(HotSpot 的永久代)被完全移除了(JDK1.7 就已經開始了),取而代之是元空間,元空間使用的是直接內存。
<p style="text-align:right;font-size:13px;color:gray">https://blogs.oracle.com/poon...</p>
下面是一些經常使用參數:
-XX:MetaspaceSize=N //設置 Metaspace 的初始(和最小大小) -XX:MaxMetaspaceSize=N //設置 Metaspace 的最大大小
與永久代很大的不一樣就是,若是不指定大小的話,隨着更多類的建立,虛擬機會耗盡全部可用的系統內存。
爲何要將永久代 (PermGen) 替換爲元空間 (MetaSpace) 呢?
<p style="text-align:right;font-size:13px;color:gray">https://plumbr.io/handbook/ga...</p>
1.整個永久代有一個 JVM 自己設置固定大小上限,沒法進行調整,而元空間使用的是直接內存,受本機可用內存的限制,雖然元空間仍舊可能溢出,可是比原來出現的概率會更小。
當你元空間溢出時會獲得以下錯誤:
java.lang.OutOfMemoryError: MetaSpace
你可使用 -XX:MaxMetaspaceSize
標誌設置最大元空間大小,默認值爲 unlimited,這意味着它只受系統內存的限制。-XX:MetaspaceSize
調整標誌定義元空間的初始大小若是未指定此標誌,則 Metaspace 將根據運行時的應用程序需求動態地從新調整大小。
2.元空間裏面存放的是類的元數據,這樣加載多少類的元數據就不禁 MaxPermSize
控制了, 而由系統的實際可用空間來控制,這樣能加載的類就更多了。
3.在 JDK8,合併 HotSpot 和 JRockit 的代碼時, JRockit 歷來沒有一個叫永久代的東西, 合併以後就沒有必要額外的設置這麼一個永久代的地方了。
---第 5 題參考答案---
主要進行 gc 的區域是堆,就 HotSpot 虛擬機來講,永久代會發生 gc (full gc),可是,元空間使用的是直接內存不會發生 gc。
---第 1 題參考答案---
說到分層,咱們先從咱們平時使用框架開發一個後臺程序來講,咱們每每會按照每一層作不一樣的事情的原則將系統分爲 三層(複雜的系統分層可能會更多):
複雜的系統須要分層,由於每一層都須要專一於一類事情。咱們的網絡分層的緣由也是同樣,每一層只專一於作一類事情。
爲何計算機網絡要分層呢? ,咱們再來較爲系統的說一說:
說到計算機網絡分層,我想到了計算機世界很是很是有名的一句話,這裏分享一下:
計算機科學領域的任何問題均可以經過增長一個間接的中間層來解決,計算機整個體系從上到下都是按照嚴格的層次結構設計的。
Guide 哥注:若是一層不夠那就加兩層吧!
---第 2 題參考答案---
TCP/IP 4 層模型:
須要注意的是,咱們並不能將 TCP/IP4 層模型 和 OSI7 層模型徹底精確地匹配起來,不過能夠簡單將二者對應起來,以下圖所示:
---第 3 題參考答案---
HTTP 協議 屬於應用層的協議。
HTTP 協議是基於 TCP 協議的,發送 HTTP 請求以前首先要創建 TCP 鏈接也就是要經歷 3 次握手。目前使用的 HTTP 協議大部分都是 1.1。在 1.1 的協議裏面,默認是開啓了 Keep-Alive 的,這樣的話創建的鏈接就能夠在屢次請求中被複用了。
另外, HTTP 協議是」無狀態」的協議,它沒法記錄客戶端用戶的狀態 通常咱們都是經過 Session 來記錄客戶端用戶的狀態。
Guide 的女讀者挺少的,10 個關注個人人中只有一個女性讀者。
最近在這篇文章:《最強(細)校招/社招求職指南:隔壁小姐姐已經收到字節意向書,你的秋招還沒開始?》中還逮到了一個拿到的字節意向書的女讀者(顏值又高,技術又好,太厲害了!),我真的不要太開心了!而後,就厚臉皮地去讓這位小姐姐幫忙寫一下面經(後續可能會安排上)。
還不是爲了大家?我真是操碎了心啊!