1. 程式人生 > 其它 >你頭禿都沒想到還能這樣吧,Java開發進階吃透這一篇必拿60W年薪

你頭禿都沒想到還能這樣吧,Java開發進階吃透這一篇必拿60W年薪

一、什麼情況下會發生棧記憶體溢位?

1、棧是執行緒私有的,棧的生命週期和執行緒一樣,每個方法在執行的時候就會建立一個棧幀,它包含區域性變量表、運算元棧、動態連結、方法出口等資訊,區域性變量表又包括基本資料型別和物件的引用;
2、當執行緒請求的棧深度超過了虛擬機器允許的最大深度時,會丟擲StackOverFlowError異常,方法遞迴呼叫肯可能會出現該問題;

3、調整引數-xss去調整jvm棧的大小

二、詳解JVM記憶體模型?

jvm將虛擬機器分為5大區域,程式計數器、虛擬機器棧、本地方法棧、java堆、方法區;

  • 程式計數器:執行緒私有的,是一塊很小的記憶體空間,作為當前執行緒的行號指示器,用於記錄當前虛擬機器正在執行的執行緒指令地址;
  • 虛擬機器棧:執行緒私有的,每個方法執行的時候都會建立一個棧幀,用於儲存區域性變量表、運算元、動態連結和方法返回等資訊,當執行緒請求的棧深度超過了虛擬機器允許的最大深度時,就會丟擲StackOverFlowError;
  • 本地方法棧:執行緒私有的,儲存的是native方法的資訊,當一個jvm建立的執行緒呼叫native方法後,jvm不會在虛擬機器棧中為該執行緒建立棧幀,而是簡單的動態連結並直接呼叫該方法;
  • 堆:java堆是所有執行緒共享的一塊記憶體,幾乎所有物件的例項和陣列都要在堆上分配記憶體,因此該區域經常發生垃圾回收的操作;
  • 方法區:存放已被載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼資料。即永久代,在jdk1.8中不存在方法區了,被元資料區替代了,原方法區被分成兩部分;1:載入的類資訊,2:執行時常量池;載入的類資訊被儲存在元資料區中,執行時常量池儲存在堆中;

三、JVM中一次完整的GC是什麼樣子的?物件如何晉升到老年代?

java堆 = 新生代+老年代;新生代 = Eden + Suivivor(S0 + S1),預設分配比例是8:1:1;當Eden區空間滿了的時候,就會觸發一次Minor GC,以收集新生代的垃圾,存活下來的物件會被分配到Survivor區大物件(需要大量連續記憶體空間的物件)會直接被分配到老年代如果物件在Eden中出生,並且在經歷過一次Minor GC之後仍然存活,被分配到存活區的話,年齡+1,此後每經歷過一次Minor GC並且存活下來,年齡就+1,當年齡達到15的時候,會被晉升到老年代;當老年代滿了,而無法容納更多物件的話,會觸發一次full gc;full gc儲存的是整個記憶體堆(包括年輕代和老年代);;Major GC是發生在老年代的GC,清理老年區,經常會伴隨至少一次minor gc;

四、Java中的垃圾回收演算法?

java中有四種垃圾回收演算法,分別是標記清除法、標記整理法、複製演算法、分代收集演算法;

  • 標記清除法:第一步:利用可達性去遍歷記憶體,把存活物件和垃圾物件進行標記;第二步:在遍歷一遍,將所有標記的物件回收掉;特點:效率不行,標記和清除的效率都不高;標記和清除後會產生大量的不連續的空間分片,可能會導致之後程式執行的時候需分配大物件而找不到連續分片而不得不觸發一次GC;
  • 標記整理法:第一步:利用可達性去遍歷記憶體,把存活物件和垃圾物件進行標記;第二步:將所有的存活的物件向一段移動,將端邊界以外的物件都回收掉;特點:適用於存活物件多,垃圾少的情況;需要整理的過程,無空間碎片產生;
  • 複製演算法:將記憶體按照容量大小分為大小相等的兩塊,每次只使用一塊,當一塊使用完了,就將還存活的物件移到另一塊上,然後在把使用過的記憶體空間移除;特點:不會產生空間碎片;記憶體使用率極低;
  • 分代收集演算法:根據記憶體物件的存活週期不同,將記憶體劃分成幾塊,java虛擬機器一般將記憶體分成新生代和老生代,在新生代中,有大量物件死去和少量物件存活,所以採用複製演算法,只需要付出少量存活物件的複製成本就可以完成收集;老年代中因為物件的存活率極高,沒有額外的空間對他進行分配擔保,所以採用標記清理或者標記整理演算法進行回收;

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

判斷一個物件是否存活,分為兩種演算法1:引用計數法;2:可達性分析演算法;

引用計數法:給每一個物件設定一個引用計數器,當有一個地方引用該物件的時候,引用計數器就+1,引用失效時,引用計數器就-1;當引用計數器為0的時候,就說明這個物件沒有被引用,也就是垃圾物件,等待回收;缺點:無法解決迴圈引用的問題,當A引用B,B也引用A的時候,此時AB物件的引用都不為0,此時也就無法垃圾回收,所以一般主流虛擬機器都不採用這個方法;

可達性分析法從一個被稱為GC Roots的物件向下搜尋,如果一個物件到GC Roots沒有任何引用鏈相連線時,說明此物件不可用,在java中可以作為GC Roots的物件有以下幾種:

虛擬機器棧中引用的物件方法區類靜態屬性引用的變數方法區常量池引用的物件本地方法棧JNI引用的物件但一個物件滿足上述條件的時候,不會馬上被回收,還需要進行兩次標記;第一次標記:判斷當前物件是否有finalize()方法並且該方法沒有被執行過,若不存在則標記為垃圾物件,等待回收;若有的話,則進行第二次標記;第二次標記將當前物件放入F-Queue佇列,並生成一個finalize執行緒去執行該方法,虛擬機器不保證該方法一定會被執行,這是因為如果執行緒執行緩慢或進入了死鎖,會導致回收系統的崩潰;如果執行了finalize方法之後仍然沒有與GC Roots有直接或者間接的引用,則該物件會被回收;

最後的內容

在開頭跟大家分享的時候我就說,面試我是沒有做好準備的,全靠平時的積累,確實有點臨時抱佛腳了,以至於我自己還是挺懊惱的。(準備好了或許可以拿個40k,沒做準備只有30k+,你們懂那種感覺嗎)

如何準備面試?

1、前期鋪墊(技術沉積)

程式設計師面試其實是對於技術的一次摸底考試,你的技術牛逼,那你就是大爺。大廠對於技術的要求主要體現在:基礎,原理,深入研究原始碼,廣度,實戰五個方面,也只有將原理理論結合實戰才能把技術點吃透。

下面是我會看的一些資料筆記,希望能幫助大家由淺入深,由點到面的學習Java,應對大廠面試官的靈魂追問

開源分享:【一線大廠Java面試題解析+核心總結學習筆記+最新講解視訊+實戰專案原始碼】

這部分內容過多,小編只貼出部分內容展示給大家了,見諒見諒!

  • Java程式設計師必看《Java開發核心筆記(華山版)》
  • Redis學習筆記
  • Java併發程式設計學習筆記

四部分,詳細拆分併發程式設計——併發程式設計+模式篇+應用篇+原理篇

  • Java程式設計師必看書籍《深入理解 ava虛擬機器第3版》(pdf版)
  • 大廠面試必問——資料結構與演算法彙集筆記

其他像Spring,SpringBoot,SpringCloud,SpringCloudAlibaba,Dubbo,Zookeeper,Kafka,RocketMQ,RabbitMQ,Netty,MySQL,Docker,K8s等等我都整理好,這裡就不一一展示了。

2、狂刷面試題

技術主要是體現在平時的積累實用,面試前準備兩個月的時間再好好複習一遍,緊接著就可以刷面試題了,下面這些面試題都是小編精心整理的,貼給大家看看。

①大廠高頻45道筆試題(智商題)

②BAT大廠面試總結(部分內容截圖)

③面試總結

3、結合實際,修改簡歷

程式設計師的簡歷一定要多下一些功夫,尤其是對一些字眼要再三斟酌,如“精通、熟悉、瞭解”這三者的區別一定要區分清楚,否則就是在給自己挖坑了。當然不會包裝,我可以將我的簡歷給你參考參考,如果還不夠,那下面這些簡歷模板任你挑選:

以上分享,希望大家可以在金三銀四跳槽季找到一份好工作,但千萬也記住,技術一定是平時工作種累計或者自學(或報班跟著老師學)通過實戰累計的,千萬不要臨時抱佛腳。

另外,面試中遇到不會的問題不妨嘗試講講自己的思路,因為有些問題不是考察我們的程式設計能力,而是邏輯思維表達能力;最後平時要進行自我分析與評價,做好職業規劃,不斷摸索,提高自己的程式設計能力和抽象思維能力。