1. 程式人生 > 實用技巧 >阿里、位元組等大佬重磅出盡,整理面試題助力金九銀十,還不收藏

阿里、位元組等大佬重磅出盡,整理面試題助力金九銀十,還不收藏

一、為什麼要整理面試題?

現在JDK都14了,但是很多人可能連JDK 8 新特性都沒玩過,那面試的時候如何高效地和麵試官瞎扯蛋呢?那自然是需要題庫(題庫)啦! 考慮到這一點,小編決定,將市面上設計比較多的

  • 第一梯度:計算機組成原理、作業系統原理、網路通訊原理、資料結構和演算法;
  • 第二梯度:Java SE基礎、JavaWeb相關、Java 工具(Maven/git等)、JDK 工具、Java 各版本新特性、JVM 相關如記憶體模型和、GC 演算法、JVM 效能調優、設計模式;
  • 第三梯度:Spring、Spring MVC、Springboot、Spring Cloud、Mybatis、Dubbo 等主流框架的運用和原理;
  • 第四梯度:MySQL、Redis、RabbitMQ/RocketMQ/Kafka等資料庫或者中介軟體的運用和原理;
  • 第五梯度:CAP 理論、BASE 理論、Paxos 和 Raft 演算法等其他分散式理論;
  • 第六梯度:容器化Docker/Kubernetes、大資料、AI、區塊鏈等等前沿技術理論;
做任何大事,都需要從最細微的小事開始,所以前面幾天的文章會先從基礎開始,
可能大部分人都覺得相對簡單,不過也能查漏補缺,不放過任何細節。

舉一個小栗子,我們就以現在面試過程中,被問到最多的jvm中的GC,先來看一下下面的這些面試題

GC是什麼? 為什麼要有 GC?

Java 提供的GC 功能可以自動監測物件是否超過作用域從而達到自動回收記憶體的目的, Java 語言沒有提供釋放已分配記憶體的顯式操作方法。 在堆中,找到已經無用的物件,並把這些物件佔用的空間收回使其可以重新利用。 要請求垃圾收集,可以呼叫下面的方法之一:

  • System.gc()
  • Runtime.getRuntime().gc() 。

演算法思路:把所有的物件組成一個集合,或者可以理解為樹狀結構,從樹根開始找,只要可以找到的都是活動物件,如果找不到就應該被回收了。

Java 的 GC 哪些記憶體需要回收?

記憶體執行時 JVM 會有一個執行時資料區來管理記憶體。它主要包括 5 大部分:

  • 程式計數器(Program Counter Register)
  • 虛擬機器棧(VM Stack)
  • 本地方法棧(Native Method Stack)
  • 方法區(Method Area)
  • 堆(Heap)

而其中程式計數器、虛擬機器棧、本地方法棧是每個執行緒私有的記憶體空間,隨執行緒而生,隨執行緒而亡。例如棧中每一個棧幀中分配多少記憶體基本上在類結構確定是哪個時就已知了,因此這 3 個區域的記憶體分配和回收都是確定的,無需考慮記憶體回收的問題。 但方法區和堆就不同了,一個介面的多個實現類需要的記憶體可能不一樣,我們只有在程式執行期間才會知道會建立哪些物件,這部分記憶體的分配和回收都是動態的,GC 主要關注的是這部分記憶體。

總結:GC 主要進行回收的記憶體是 JVM 中的方法區和堆

介紹一些常見的垃圾回收器

  • Serial收集器: 單執行緒的收集器,收集垃圾時,必須stop the world,使用複製演算法。
  • ParNew收集器: Serial收集器的多執行緒版本,也需要stop the world,複製演算法。
  • Parallel Scavenge收集器: 新生代收集器,複製演算法的收集器,併發的多執行緒收集器,目標是達到一個可控的吞吐量。如果虛擬機器總共執行100分鐘,其中垃圾花掉1分鐘,吞吐量就是99%。
  • Serial Old收集器: 是Serial收集器的老年代版本,單執行緒收集器,使用標記整理演算法。
  • Parallel Old收集器: 是Parallel Scavenge收集器的老年代版本,使用多執行緒,標記-整理演算法。
  • CMS(Concurrent Mark Sweep) 收集器: 是一種以獲得最短回收停頓時間為目標的收集器,標記清除演算法,運作過程:初始標記,併發標記,重新標記,併發清除,收集結束會產生大量空間碎片。
  • G1收集器: 標記整理演算法實現,運作流程主要包括以下:初始標記,併發標記,最終標記,篩選標記。不會產生空間碎片,可以精確地控制停頓。

CMS收集器和G1收集器的區別?

  • CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用 ,G1收集器收集範圍是老年代和新生代,不需要結合其他收集器使用
  • CMS收集器以最小的停頓時間為目標的收集器 ,G1收集器可預測垃圾回收的停頓時間
  • CMS收集器是使用“標記-清除”演算法進行的垃圾回收,容易產生記憶體碎片,G1收集器使用的是“標記-整理”演算法,進行了空間整合,降低了記憶體空間碎片。

GC的收集方法有哪些?詳細說一下每個的原理與特點?

標記-清除演算法(Mark-Sweep) 從根節點開始標記所有可達物件,其餘沒有標記的即為垃圾物件,執行清除。但回收後的空間是不連續的。標記-清除演算法採用從根集合進行掃描,對存活的物件標記,標記完畢後,在掃描整個空間中未被標記的物件,進行回收。 標記-清除演算法不需要進行物件的移動,並且僅對不存活的物件進行處理,在存活物件比較多的情況下極為高效,但由於標記-清除演算法直接回收不存活的物件,因此會造成記憶體碎片。

複製演算法 複製演算法採用從根集合掃描,並將存活物件複製到一塊新的,沒有使用過的空間中,這種演算法當控制元件存活的物件比較少時,極為高效,但是帶來的成本是需要一塊記憶體交換空間進行物件的移動。也就是s0,s1等空間。

標記-整理法 標記-整理演算法採用標記-清除演算法一樣的方式進行物件的標記,但在清除時,在回收不存活的物件佔用的空間後,會將所有的存活物件網左端空閒空間移動,並更新相應的指標。標記-整理演算法是在標記-清除演算法的基礎上,又進行了物件的移動,因此成本更高,但是卻解決了記憶體碎片的問題。

Java 的 GC 什麼時候回收垃圾?

對於堆中的物件,用可達性分析判斷一個物件是否還存在引用,如果該物件沒有任何引用就應該被回收。根據實際對引用的不同需求,分成了 4 種引用,每種引用的回收機制也是不同的。 對於方法區中的常量和類,當一個常量沒有任何物件引用它,它就可以被回收了。 對於類,如果可以判定它為無用類,就可以被回收了。

如何判斷一個物件是否存活?

判斷一個物件是否存活有兩種方法: 1. 引用計數法 所謂引用計數法就是給每一個物件設定一個引用計數器,每當有一個地方引用這個物件 時,就將計數器加一,引用失效時,計數器就減一。當一個物件的引用計數器為零時,說 明此物件沒有被引用,也就是“死物件”,將會被垃圾回收. 引用計數法有一個缺陷就是無法解決迴圈引用問題,也就是說當物件 A 引用物件 B,物件 B 又引用者物件 A,那麼此時 A,B 物件的引用計數器都不為零,也就造成無法完成垃圾回 收,所以主流的虛擬機器都沒有采用這種演算法。

2.可達性演算法(引用鏈法) 該演算法的思想是:從一個被稱為 GC Roots 的物件開始向下搜尋,如果一個物件到 GC Roots 沒有任何引用鏈相連時,則說明此物件不可用。 在 java 中可以作為 GC Roots 的物件有以下幾種:

  • 虛擬機器棧中引用的物件
  • 方法區類靜態屬性引用的物件
  • 方法區常量池引用的物件
  • 本地方法棧 JNI 引用的物件

雖然這些演算法可以判定一個物件是否能被回收,但是當滿足上述條件時,一個物件比不一定會被回收。 當一個物件不可達 GC Root 時,這個物件並不會立馬被回收,而是出於一個死緩的階段,若要被真正的回收需要經歷兩次標記: 如果物件在可達性分析中沒有與 GC Root 的引用鏈,那麼此時就會被第一次標記並且進行一次篩選,篩選的條件是是否有必要執行 finalize()方法。當物件沒有覆蓋 finalize()方法或者已被虛擬機器呼叫過,那麼就認為是沒必要的。 如果該物件有必要執行 finalize()方法,那麼這個物件將會放在一個稱為 F-Queue 的對佇列中,虛擬機器會觸發一個 Finalize()執行緒去執行,此執行緒是低優先順序的,並且虛擬機器不會承諾一直等待它執行完,這是因為如果 finalize()執行緩慢或者發生了死鎖,那麼就會造成 F-Queue 佇列一直等待,造成了記憶體回收系統的崩潰。GC 對處於 F-Queue 中的物件進行第二次被標記,這時,該物件將被移除”即將回收”集合,等待回收。

什麼是靜態分派與動態分派?

靜態分派 所有依賴靜態型別來定位方法執行版本的分派動作稱為靜態分派,其典型應用是方法過載(根據引數的靜態型別來定位目標方法)。 靜態分派發生在編譯階段,因此確定靜態分派的動作實際上不是由虛擬機器執行的。

動態分派 在執行期根據實際型別確定方法執行版本。


怎麼樣,這只是一個GC,而由GC也可以引出來一系列的問題:jvm--->效能調優--->mysql調優--->負載均衡--->設計模式--->。。。。畢竟技術之間的連貫性還是相當強的,所以整理面試題,從面試出發,根據公司面試的業務需求進行整理,有針對性會幫助你節省不少的時間,就像是大學考試之前劃重點一樣,我也將相應的知識點和來自阿里、位元組的朋友一起整理成了一張思維導圖

除了每一個知識點可以點開檢視之外

我們也儘自己最大的能力,將內容進行整理和改進,形成了xmind格式的思維導圖,但是畢竟這是我們整理的,不一定能滿足所有人的

篇幅原因,就不一一詳細展示了,看一下xmind自己記錄的開啟記錄吧

為了能夠讓大家更好的學習,我們也將相應的問題整理,錄製了一系列的視訊資料,講解相應的知識點問題,並且上傳網盤進行儲存


最後當然是最重磅的面試題

話不多說,直接放上面試題截圖

關注公眾號:Java架構師聯盟,每日更新技術好文,新增小助手:msbxq2020免費獲取

部分資料已經上傳到我的git倉庫中:有需要的可以下載

https://gitee.com/biwangsheng/mxq