一、為什么要整理面試題?
現在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

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/100228.html
標籤:Java
上一篇:求密鑰方法
下一篇:創建多執行緒的4種方式
