Java開發面試知識點總結
來源:上海職坐標IT培訓
時間:09-08
Java開發面試知識點有哪些呢?這里詳細介紹了Java開發面試知識點總結,希望對Java語言的學習與面試有一定的幫助。
JVM運行時數據區
線程共享部分:方法區、堆內存
線程獨占部分:虛擬機棧、本地方法棧、程序計數器
方法區
用來存儲加載的類信息、常量、靜態變量、編譯后的代碼等數據
堆內存
用來存放對象的區域,可以細分為:老年代、新生代(Eden、From Survivor、To Survivor)
虛擬機棧
每個線程都在這個空間有一個私有的空間,線程棧由多個棧幀組成。一個線程會執行一個或者多個方法,一個方法對應一個棧幀。
棧幀內容包括:局部變量表、操作數棧、動態鏈接、方法返回地址、附加信息等,棧內存默認是1M。
本地方法棧
和虛擬機棧功能類似,虛擬機棧是為虛擬機執行JAVA方法而準備的,本地方法棧是為虛擬機使用Native本地方法而準備的
程序計數器
記錄當前線程執行字節碼的位置,存儲的是字節碼指令地址,如果執行Native方法,則計數器值為空。
CPU同一時間,只會執行一條線程中的指令。JVM多線程會輪流切換并分配CPU執行時間,為了線程切換后,需要通過程序計數器來恢復正確的執行位置。
Java類加載過程
過程包括加載、驗證、準備、解析、初始化
加載是類加載的個過程,在這個階段,將完成一下三件事情:
通過類的全限定名獲取類的二進制流;
將該二進制流中的靜態存儲結構轉化為方法區運行時數據結構。
在內存中生成該類的java.lang.Class對象,作為該類的數據訪問入口。
驗證的目的是為了確保Class文件的字節流中的信息不回危害到虛擬機.在該階段主要完成以下四鐘驗證:
文件格式驗證:驗證字節流是否符合Class文件的規范,如主次版本號是否在當前虛擬機范圍內,常量池中的常量是否有不被支持的類型。
元數據驗證:對字節碼描述的信息進行語義分析,如這個類是否有父類,是否集成了不被繼承的類等。
字節碼驗證:是整個驗證過程中最復雜的一個階段,通過驗證數據流和控制流的分析,確定程序語義是否正確,主要針對方法體的驗證。如:方法中的類型轉換是否正確,跳轉指令是否正確等。
符號引用驗證:這個動作在后面的解析過程中發生,主要是為了確保解析動作能正確執行。
準備階段是為類的靜態變量分配內存并將其初始化為默認值,這些內存都將在方法區中進行分配。準備階段不分配類中的實例變量的內存,實例變量將會在對象實例化時隨著對象一起分配在Java堆中。
解析階段主要完成符號引用到直接引用的轉換動作。解析動作并不一定在初始化動作完成之前,也有可能在初始化之后。
初始化是類加載的最后一步,前面的類加載過程,除了在加載階段用戶應用程序可以通過自定義類加載器參與之外,其余動作完全由虛擬機主導和控制。到了初始化階段,才真正開始執行類中定義的Java程序代碼。
描述一下JVM加載class文件的原理機制?
JVM中類的裝載是由類加載器(ClassLoader)和它的子類來實現的,Java中的類加載器是一個重要的Java運行時系統組件,它負責在運行時查找和裝入類文件中的類。
由于Java的跨平臺性,經過編譯的Java源程序并不是一個可執行程序,而是一個或多個類文件。當Java程序需要使用某個類時,JVM會確保這個類已經被加載、連接(驗證、準備和解析)和初始化。
類的加載是指把類的.class文件中的數據讀入到內存中,通常是創建一個字節數組讀入.class文件,然后產生與所加載類對應的Class對象。加載完成后,Class對象還不完整,所以此時的類還不可用。當類被加載后就進入連接階段,這一階段包括驗證、準備(為靜態變量分配內存并設置默認的初始值)和解析(將符號引用替換為直接引用)三個步驟。
最后JVM對類進行初始化,包括:
1)如果類存在直接的父類并且這個類還沒有被初始化,那么就先初始化父類;
2)如果類中存在初始化語句,就依次執行這些初始化語句。
類的加載是由類加載器完成的,類加載器包括:
啟動類加載器(Bootstrap ClassLoader)、
擴展類加載器(Extension ClassLoader)、
應用程序類加載器(Application ClassLoader)、
用戶自定義類加載器(java.lang.ClassLoader的子類)。
類加載過程采取了雙親委派模型機制(PDM)。PDM更好的了Java平臺的安全性,在該機制中,JVM自帶的Bootstrap是根加載器,其他的加載器都有且僅有一個父類加載器。類的加載首先請求父類加載器加載,父類加載器無能為力時才由其子類加載器自行加載。JVM不會向Java程序提供對Bootstrap的引用。下面是關于幾個類加載器的說明:
Bootstrap:一般用本地代碼實現,負責加載JVM基礎核心類庫(rt.jar);
Extension:從java.ext.dirs系統屬性所指定的目錄中加載類庫,它的父加載器是Bootstrap;
Application:應用類加載器,其父類是Extension。它是應用最廣泛的類加載器。它從環境變量classpath或者系統屬性java.class.path所指定的目錄中記載類,是用戶自定義加載器的默認父加載器。
破壞雙親委派模型:線程上下文類加載器、OSGi類加載器
線程上下文類加載器:Java中所有涉及SPI的加載動作基本上都采用這種方式,例如JNDI、JDBC、JCE、JAXB和JBI等。
OSGi類加載器:作代碼熱替換(HotSwap)、模塊熱部署(Hot Deployment)等用途。
Java內存模型
Java內存模型的主要目標是定義程序中變量的訪問規則。即在虛擬機中將變量存儲到主內存或者將變量從主內存取出這樣的底層細節。
1)Java內存模型將內存分為了主內存和工作內存。類的狀態,也就是類之間共享的變量,是存儲在主內存中的,每次Java線程用到這些主內存中的變量的時候,會讀一次主內存中的變量,并讓這些內存在自己的工作內存中有一份拷貝,運行自己線程代碼的時候,用到這些變量,操作的都是自己工作內存中的那一份。在線程代碼執行完畢之后,會將最新的值更新到主內存中去
2)定義了幾個原子操作,用于操作主內存和工作內存中的變量
3)定義了volatile變量的使用規則
4)happens-before,即先行發生原則,定義了操作A必然先行發生于操作B的一些規則,比如在同一個線程內控制流前面的代碼一定先行發生于控制流后面的代碼、一個釋放鎖unlock的動作一定先行發生于后面對于同一個鎖進行鎖定lock的動作等等,只要符合這些規則,則不需要額外做同步措施,如果某段代碼不符合所有的happens-before規則,則這段代碼一定是線程非安全的
延伸閱讀
Java內存模型中涉及到的概念有:
主內存:java虛擬機規定所有的變量(不是程序中的變量)都必須在主內存中產生,為了方便理解,可以認為是堆區??梢耘c前面說的物理機的主內存相比,只不過物理機的主內存是整個機器的內存,而虛擬機的主內存是虛擬機內存中的一部分。
工作內存:java虛擬機中每個線程都有自己的工作內存,該內存是線程私有的為了方便理解,可以認為是虛擬機棧??梢耘c前面說的高速緩存相比。線程的工作內存保存了線程需要的變量在主內存中的副本。虛擬機規定,線程對主內存變量的修改必須在線程的工作內存中進行,不能直接讀寫主內存中的變量。不同的線程之間也不能相互訪問對方的工作內存。如果線程之間需要傳遞變量的值,必須通過主內存來作為中介進行傳遞。
內存間交互操作
關于主內存與工作內存之間的具體交互協議,即一個變量如何從主內存拷貝到工作內存、如何從工作內存同步到主內存之間的實現細節,Java內存模型定義了以下八種操作來完成:
lock(鎖定):作用于主內存的變量,把一個變量標識為一條線程獨占狀態。
unlock(解鎖):作用于主內存變量,把一個處于鎖定狀態的變量釋放出來,釋放后的變量才可以被其他線程鎖定。
read(讀?。鹤饔糜谥鲀却孀兞?,把一個變量值從主內存傳輸到線程的工作內存中,以便隨后的load動作使用
load(載入):作用于工作內存的變量,它把read操作從主內存中得到的變量值放入工作內存的變量副本中。
use(使用):作用于工作內存的變量,把工作內存中的一個變量值傳遞給執行引擎,每當虛擬機遇到一個需要使用變量的值的字節碼指令時將會執行這個操作。
assign(賦值):作用于工作內存的變量,它把一個從執行引擎接收到的值賦值給工作內存的變量,每當虛擬機遇到一個給變量賦值的字節碼指令時執行這個操作。
store(存儲):作用于工作內存的變量,把工作內存中的一個變量的值傳送到主內存中,以便隨后的write的操作。
write(寫入):作用于主內存的變量,它把store操作從工作內存中一個變量的值傳送到主內存的變量中。
如果要把一個變量從主內存中復制到工作內存,就需要按順尋地執行read和load操作,如果把變量從工作內存中同步回主內存中,就要按順序地執行store和write操作。Java內存模型只要求上述操作必須按順序執行,而沒有必須是連續執行。也就是read和load之間,store和write之間是可以插入其他指令的,如對主內存中的變量a、b進行訪問時,可能的順序是read a,read b,load b,load a。Java內存模型還規定了在執行上述八種基本操作時,必須滿足如下規則:
不允許read和load、store和write操作之一單獨出現
不允許一個線程丟棄它的最近assign的操作,即變量在工作內存中改變了之后必須同步到主內存中。
不允許一個線程無原因地(沒有發生過任何assign操作)把數據從工作內存同步回主內存中。
一個新的變量只能在主內存中誕生,不允許在工作內存中直接使用一個未被初始化(load或assign)的變量。即就是對一個變量實施use和store操作之前,必須先執行過了assign和load操作。
一個變量在同一時刻只允許一條線程對其進行lock操作,lock和unlock必須成對出現
如果對一個變量執行lock操作,將會清空工作內存中此變量的值,在執行引擎使用這個變量前需要重新執行load或assign操作初始化變量的值
如果一個變量事先沒有被lock操作鎖定,則不允許對它執行unlock操作;也不允許去unlock一個被其他線程鎖定的變量。
對一個變量執行unlock操作之前,必須先把此變量同步到主內存中(執行store和write操作)。
以上就是“Java開發面試知識點總結”的內容介紹,希望對大家學習有所幫助。想要了解更多“Java開發面試培訓”相關資訊歡迎來在線咨詢。
色欲日日拍夜夜嗷嗷叫,国产在视频精品线观看,中国熟妇色XXXXXHD,日本肉体XXXX裸体137大胆
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<蜘蛛词>|
<文本链>
<文本链>
<文本链>
<文本链>
<文本链>
<文本链>