跳槽時時刻刻都在發(fā)生忱叭,但是我建議大家跳槽之前碉考,先想清楚為什么要跳槽占锯。切不可跟風袒哥,看到同事一個個都走了狸膏,自己也盲目的開始面試起來(期間也沒有準備充分)够滑,到底是因為技術原因(影響自己的發(fā)展,偏移自己規(guī)劃的軌跡)良蒸,還是錢給少了疑俭,不受重視粮呢。
準備不充分的面試,完全是浪費時間钞艇,更是對自己的不負責(如果title很高,當我沒說)豪硅。今天給大家分享下?Java面試知識點解析——JVM基礎篇
1)Java 是如何實現(xiàn)跨平臺的哩照?
注意:跨平臺的是 Java 程序,而不是 JVM懒浮。JVM 是用 C/C++ 開發(fā)的飘弧,是編譯后的機器碼识藤,不能跨平臺,不同平臺下需要安裝不同版本的 JVM
答:我們編寫的 Java 源碼次伶,編譯后會生成一種 .class 文件痴昧,稱為字節(jié)碼文件。Java 虛擬機(JVM)就是負責將字節(jié)碼文件翻譯成特定平臺下的機器碼然后運行冠王,也就是說赶撰,只要在不同平臺上安裝對應的 JVM,就可以運行字節(jié)碼文件柱彻,運行我們編寫的 Java 程序豪娜。
而這個過程,我們編寫的 Java 程序沒有做任何改變哟楷,僅僅是通過 JVM 這一 “中間層” 瘤载,就能在不同平臺上運行,真正實現(xiàn)了 “一次編譯卖擅,到處運行” 的目的鸣奔。
2)什么是 JVM ?
解析:不僅僅是基本概念惩阶,還有 JVM 的作用溃蔫。
答:JVM,即 Java Virtual Machine琳猫,Java 虛擬機伟叛。它通過模擬一個計算機來達到一個計算機所具有的的計算功能。JVM 能夠跨計算機體系結構來執(zhí)行 Java 字節(jié)碼脐嫂,主要是由于 JVM 屏蔽了與各個計算機平臺相關的軟件或者硬件之間的差異统刮,使得與平臺相關的耦合統(tǒng)一由 JVM 提供者來實現(xiàn)。
3)JVM 由哪些部分組成账千?
解析:這是對 JVM 體系結構的考察
答:JVM 的結構基本上由 4 部分組成:
類加載器侥蒙,在 JVM 啟動時或者類運行時將需要的 class 加載到 JVM 中
執(zhí)行引擎,執(zhí)行引擎的任務是負責執(zhí)行 class 文件中包含的字節(jié)碼指令匀奏,相當于實際機器上的 CPU
內存區(qū)鞭衩,將內存劃分成若干個區(qū)以模擬實際機器上的存儲、記錄和調度功能模塊娃善,如實際機器上的各種功能的寄存器或者 PC 指針的記錄器等
本地方法調用论衍,調用 C 或 C++ 實現(xiàn)的本地方法的代碼返回結果
4)類加載器是有了解嗎?
解析:底層原理的考察聚磺,其中涉及到類加載器的概念坯台,功能以及一些底層的實現(xiàn)。
答:顧名思義瘫寝,類加載器(class loader)用來加載 Java 類到 Java 虛擬機中蜒蕾。一般來說稠炬,Java 虛擬機使用 Java 類的方式如下:Java 源程序(.java 文件)在經過 Java 編譯器編譯之后就被轉換成 Java 字節(jié)代碼(.class 文件)。
類加載器負責讀取 Java 字節(jié)代碼咪啡,并轉換成 java.lang.Class類的一個實例首启。每個這樣的實例用來表示一個 Java 類。通過此實例的 newInstance()方法就可以創(chuàng)建出該類的一個對象撤摸。實際的情況可能更加復雜毅桃,比如 Java 字節(jié)代碼可能是通過工具動態(tài)生成的,也可能是通過網絡下載的愁溜。
面試官:Java 虛擬機是如何判定兩個 Java 類是相同的疾嗅?
答:Java 虛擬機不僅要看類的全名是否相同,還要看加載此類的類加載器是否一樣冕象。只有兩者都相同的情況代承,才認為兩個類是相同的。即便是同樣的字節(jié)代碼渐扮,被不同的類加載器加載之后所得到的類论悴,也是不同的。比如一個 Java 類 com.example.Sample墓律,編譯之后生成了字節(jié)代碼文件 Sample.class膀估。兩個不同的類加載器 ClassLoaderA和 ClassLoaderB分別讀取了這個 Sample.class文件,并定義出兩個 java.lang.Class類的實例來表示這個類耻讽。這兩個實例是不相同的察纯。對于 Java 虛擬機來說,它們是不同的類针肥。試圖對這兩個類的對象進行相互賦值饼记,會拋出運行時異常 ClassCastException。
5)類加載器是如何加載 class 文件的慰枕?
答:下圖所示是 ClassLoader 加載一個 class 文件到 JVM 時需要經過的步驟:
第一個階段是找到 .class 文件并把這個文件包含的字節(jié)碼加載到內存中
第二階段又可以分為三個步驟具则,分別是字節(jié)碼驗證、Class 類數(shù)據(jù)結構分析及相應的內存分配和最后的符號表的鏈接
第三個階段是類中靜態(tài)屬性和初始化賦值具帮,以及靜態(tài)塊的執(zhí)行等
面試官:能詳細講講嗎博肋?
答:
1.加載
查找并加載類的二進制數(shù)據(jù)加載時類加載過程的第一個階段,在加載階段蜂厅,虛擬機需要完成以下三件事情:
通過一個類的全限定名來獲取其定義的二進制字節(jié)流匪凡。
將這個字節(jié)流所代表的靜態(tài)存儲結構轉化為方法區(qū)的運行時數(shù)據(jù)結構。
在Java堆中生成一個代表這個類的 java.lang.Class 對象葛峻,作為對方法區(qū)中這些數(shù)據(jù)的訪問入口锹雏。
相對于類加載的其他階段而言,加載階段(準確地說术奖,是加載階段獲取類的二進制字節(jié)流的動作)是可控性最強的階段礁遵,因為開發(fā)人員既可以使用系統(tǒng)提供的類加載器來完成加載,也可以自定義自己的類加載器來完成加載采记。
加載階段完成后佣耐,虛擬機外部的二進制字節(jié)流就按照虛擬機所需的格式存儲在方法區(qū)之中,而且在Java堆中也創(chuàng)建一個 java.lang.Class類的對象唧龄,這樣便可以通過該對象訪問方法區(qū)中的這些數(shù)據(jù)兼砖。
2.連接
驗證:確保被加載的類的正確性
驗證是連接階段的第一步,這一階段的目的是為了確保Class文件的字節(jié)流中包含的信息符合當前虛擬機的要求既棺,并且不會危害虛擬機自身的安全讽挟。驗證階段大致會完成4個階段的檢驗動作:
文件格式驗證:驗證字節(jié)流是否符合Class文件格式的規(guī)范;例如:是否以 0xCAFEBABE開頭丸冕、主次版本號是否在當前虛擬機的處理范圍之內耽梅、常量池中的常量是否有不被支持的類型。
元數(shù)據(jù)驗證:對字節(jié)碼描述的信息進行語義分析(注意:對比javac編譯階段的語義分析)胖烛,以保證其描述的信息符合Java語言規(guī)范的要求眼姐;例如:這個類是否有父類,除了 java.lang.Object之外佩番。
字節(jié)碼驗證:通過數(shù)據(jù)流和控制流分析众旗,確定程序語義是合法的、符合邏輯的趟畏。
符號引用驗證:確保解析動作能正確執(zhí)行贡歧。
驗證階段是非常重要的,但不是必須的赋秀,它對程序運行期沒有影響利朵,如果所引用的類經過反復驗證,那么可以考慮采用 -Xverifynone 參數(shù)來關閉大部分的類驗證措施沃琅,以縮短虛擬機類加載的時間哗咆。
準備:為類的靜態(tài)變量分配內存,并將其初始化為默認值
準備階段是正式為類變量分配內存并設置類變量初始值的階段益眉,這些內存都將在方法區(qū)中分配晌柬。對于該階段有以下幾點需要注意:
① 這時候進行內存分配的僅包括類變量(static),而不包括實例變量郭脂,實例變量會在對象實例化時隨著對象一塊分配在Java堆中年碘。
② 這里所設置的初始值通常情況下是數(shù)據(jù)類型默認的零值(如0、0L展鸡、null屿衅、false等),而不是被在Java代碼中被顯式地賦予的值莹弊。
假設一個類變量的定義為: public static int value = 3;
那么變量value在準備階段過后的初始值為 0涤久,而不是 3涡尘,因為這時候尚未開始執(zhí)行任何 Java 方法,而把 value 賦值為 3 的public static指令是在程序編譯后响迂,存放于類構造器 <clinit>()方法之中的考抄,所以把value賦值為3的動作將在初始化階段才會執(zhí)行。
這里還需要注意如下幾點:
對基本數(shù)據(jù)類型來說蔗彤,對于類變量(static)和全局變量川梅,如果不顯式地對其賦值而直接使用,則系統(tǒng)會為其賦予默認的零值然遏,而對于局部變量來說贫途,在使用前必須顯式地為其賦值,否則編譯時不通過待侵。
對于同時被static和final修飾的常量丢早,必須在聲明的時候就為其顯式地賦值,否則編譯時不通過诫给;而只被final修飾的常量則既可以在聲明時顯式地為其賦值香拉,也可以在類初始化時顯式地為其賦值,總之中狂,在使用前必須為其顯式地賦值凫碌,系統(tǒng)不會為其賦予默認零值。
對于引用數(shù)據(jù)類型reference來說胃榕,如數(shù)組引用盛险、對象引用等,如果沒有對其進行顯式地賦值而直接使用勋又,系統(tǒng)都會為其賦予默認的零值苦掘,即null。
如果在數(shù)組初始化時沒有對數(shù)組中的各元素賦值楔壤,那么其中的元素將根據(jù)對應的數(shù)據(jù)類型而被賦予默認的零值鹤啡。
③ 如果類字段的字段屬性表中存在 ConstantValue 屬性,即同時被 final 和 static 修飾蹲嚣,那么在準備階段變量 value 就會被初始化為 ConstValue 屬性所指定的值递瑰。
假設上面的類變量 value 被定義為: public static final int value = 3;
編譯時 Javac 將會為 value 生成 ConstantValue 屬性,在準備階段虛擬機就會根據(jù) ConstantValue 的設置將 value 賦值為 3隙畜。我們可以理解為 static final 常量在編譯期就將其結果放入了調用它的類的常量池中
解析:把類中的符號引用轉換為直接引用
解析階段是虛擬機將常量池內的符號引用替換為直接引用的過程抖部,解析動作主要針對類或接口、字段议惰、類方法慎颗、接口方法、方法類型、方法句柄和調用點限定符7類符號引用進行俯萎。符號引用就是一組符號來描述目標傲宜,可以是任何字面量。
直接引用就是直接指向目標的指針讯屈、相對偏移量或一個間接定位到目標的句柄蛋哭。
3.初始化
初始化县习,為類的靜態(tài)變量賦予正確的初始值涮母,JVM負責對類進行初始化,主要對類變量進行初始化躁愿。在Java中對類變量進行初始值設定有兩種方式:
① 聲明類變量是指定初始值
② 使用靜態(tài)代碼塊為類變量指定初始值
JVM初始化步驟
1叛本、假如這個類還沒有被加載和連接,則程序先加載并連接該類
2彤钟、假如該類的直接父類還沒有被初始化来候,則先初始化其直接父類
3、假如類中有初始化語句逸雹,則系統(tǒng)依次執(zhí)行這些初始化語句
類初始化時機:只有當對類的主動使用的時候才會導致類的初始化营搅,類的主動使用包括以下六種:
創(chuàng)建類的實例,也就是new的方式
訪問某個類或接口的靜態(tài)變量梆砸,或者對該靜態(tài)變量賦值
調用類的靜態(tài)方法
反射(如 Class.forName(“com.shengsiyuan.Test”))
初始化某個類的子類转质,則其父類也會被初始化
Java虛擬機啟動時被標明為啟動類的類( JavaTest),直接使用 java.exe命令來運行某個主類
結束生命周期
在如下幾種情況下帖世,Java虛擬機將結束生命周期
執(zhí)行了 System.exit()方法
程序正常執(zhí)行結束
程序在執(zhí)行過程中遇到了異承菪罚或錯誤而異常終止
由于操作系統(tǒng)出現(xiàn)錯誤而導致Java虛擬機進程終止
6)雙親委派模型(Parent Delegation Model)?
解析:類的加載過程采用雙親委派機制日矫,這種機制能更好的保證 Java 平臺的安全性
答:類加載器 ClassLoader 是具有層次結構的赂弓,也就是父子關系,其中哪轿,Bootstrap 是所有類加載器的父親盈魁,如下圖所示:
該模型要求除了頂層的 Bootstrap class loader 啟動類加載器外,其余的類加載器都應當有自己的父類加載器窃诉。子類加載器和父類加載器不是以繼承(Inheritance)的關系來實現(xiàn)杨耙,而是通過組合(Composition)關系來復用父加載器的代碼。每個類加載器都有自己的命名空間(由該加載器及所有父類加載器所加載的類組成褐奴,在同一個命名空間中按脚,不會出現(xiàn)類的完整名字(包括類的包名)相同的兩個類;在不同的命名空間中敦冬,有可能會出現(xiàn)類的完整名字(包括類的包名)相同的兩個類)
面試官:雙親委派模型的工作過程辅搬?
答:
1.當前 ClassLoader 首先從自己已經加載的類中查詢是否此類已經加載,如果已經加載則直接返回原來已經加載的類。
每個類加載器都有自己的加載緩存堪遂,當一個類被加載了以后就會放入緩存介蛉,
等下次加載的時候就可以直接返回了。
2.當前 ClassLoader 的緩存中沒有找到被加載的類的時候溶褪,委托父類加載器去加載币旧,父類加載器采用同樣的策略,首先查看自己的緩存猿妈,然后委托父類的父類去加載吹菱,一直到 bootstrap ClassLoader.
當所有的父類加載器都沒有加載的時候,再由當前的類加載器加載彭则,并將其放入它自己的緩存中鳍刷,以便下次有加載請求的時候直接返回。
面試官:為什么這樣設計呢俯抖?
解析:這是對于使用這種模型來組織累加器的好處
答:主要是為了安全性输瓜,避免用戶自己編寫的類動態(tài)替換 Java 的一些核心類,比如 String芬萍,同時也避免了重復加載尤揣,因為 JVM 中區(qū)分不同類,不僅僅是根據(jù)類名柬祠,相同的 class 文件被不同的 ClassLoader 加載就是不同的兩個類北戏,如果相互轉型的話會拋java.lang.ClassCaseException.
這些資料是小編最近花了幾個月的時間整理出來的,想要獲取上面的資料瓶盛,點擊鏈接 https://jq.qq.com/?_wv=1027&k=5CrpwVu 即可免費獲取