必看的100道MySQL數據庫經典面試題解析,春招我借這份PDF的複習思路

程序員小秘境 2021-09-19 03:54:00 阅读数:181

必看 mysql 解析 pdf 思路

類的生命周期

類從被加載到虛擬機內存中開始,到卸載出內存為止,它的整個生命周期包括:加載,驗證,准備,解析,初始化,使用,卸載這7個階段.其中其中驗證、准備、解析3個部分統稱為連接.

必看的100道MySQL數據庫經典面試題解析,春招我借這份PDF的複習思路_程序員

加載、驗證、准備、初始化和卸載這五個階段的順序是確定的,類型的加載過程必須按照這種順序按部就班地開始,而解析階段則不一定:它在某些情况下可以在初始化階段之後再開始,這是為了支持Java語言的運行時綁定特性(也稱為動態綁定或晚期綁定)

注意,這裏的幾個階段是按順序開始,而不是按順序進行或完成,因為這些階段通常都是互相交叉地混合進行的,通常在一個階段執行的過程中調用或激活另一個階段。

加載:查找並加載類的二進制數據

在加載階段,虛擬機需要完成以下3件事情:

  • 1)通過一個類的全限定名來獲取定義此類的二進制字節流。
  • 2)將這個字節流所代錶的靜態存儲結構轉化為方法區的運行時數據結構。
  • 3)在內存中生成一個代錶這個類的java.lang.Class對象,作為方法區這個類的各種數據的訪問入口。

必看的100道MySQL數據庫經典面試題解析,春招我借這份PDF的複習思路_程序員_02

驗證:確保被加載的類的正確性

驗證是連接階段的第一步,這一階段的目的是為了確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機自身的安全。驗證階段大致會完成4個階段的檢驗動作:

  • 文件格式驗證: 驗證字節流是否符合Class文件格式的規範;例如: 是否以0xCAFEBABE開頭、主次版本號是否在當前虛擬機的處理範圍之內、常量池中的常量是否有不被支持的類型。
  • 元數據驗證:對字節碼描述的信息進行語義分析(注意: 對比javac編譯階段的語義分析),以保證其描述的信息符合Java語言規範的要求;例如: 這個類是否有父類,除了java.lang.Object之外。
  • 字節碼驗證:通過數據流和控制流分析,確定程序語義是合法的、符合邏輯的。
  • 符號引用驗證:確保解析動作能正確執行。

驗證階段是非常重要的,但不是必須的,它對程序運行期沒有影響,如果所引用的類經過反複驗證,那麼可以考慮采用-Xverifynone參數來關閉大部分的類驗證措施,以縮短虛擬機類加載的時間。

准備:為類的靜態變量分配內存,並將其初始化為默認值

准備階段是正式為類變量分配內存並設置類變量初始值的階段,這些變量所使用的內存都將在方法區中進行分配

該階段的注意事項:

  • 這時候進行內存分配的僅包括類變量(被static修飾的變量),而不包括實例變量,實例變量將會在對象實例化時隨著對象一起分配在Java堆中。
  • 這裏所設置的初始值通常情况下是數據類型默認的零值(如00Lnullfalse等),而不是被在Java代碼中被顯式地賦予的值。

比如:假設一個類變量的定義為: public static int value = 3;那麼變量value在准備階段過後的初始值為0,而不是3,因為這時候尚未開始執行任何Java方法,而把value賦值為3的put static指令是在程序編譯後,存放於類構造器()方法之中的,所以把value賦值為3的動作將在初始化階段才會執行。

  • 對基本數據類型來說,對於類變量(static)和全局變量,如果不顯式地對其賦值而直接使用,則系統會為其賦予默認的零值,而對於局部變量來說,在使用前必須顯式地為其賦值,否則編譯時不通過。

  • 對於同時被staticfinal修飾的常量,必須在聲明的時候就為其顯式地賦值,否則編譯時不通過;而只被final修飾的常量則既可以在聲明時顯式地為其賦值,也可以在類初始化時顯式地為其賦值,總之,在使用前必須為其顯式地賦值,系統不會為其賦予默認零值。

  • 對於引用數據類型reference來說,如數組引用、對象引用等,如果沒有對其進行顯式地賦值而直接使用,系統都會為其賦予默認的零值,即null

  • 如果在數組初始化時沒有對數組中的各元素賦值,那麼其中的元素將根據對應的數據類型而被賦予默認的零值。

  • 如果類字段的字段屬性錶中存在ConstantValue屬性,即同時被final和static修飾,那麼在准備階段變量value就會被初始化為ConstValue屬性所指定的值。假設上面的類變量value被定義為: public static final int value = 3;編譯時Javac將會為value生成ConstantValue屬性,在准備階段虛擬機就會根據ConstantValue的設置將value賦值為3。我們可以理解為static final常量在編譯期就將其結果放入了調用它的類的常量池中

解析:把類中的符號引用轉換為直接引用

解析階段是虛擬機將常量池內的符號引用替換為直接引用的過程,解析動作主要針對接口字段類方法接口方法方法類型方法句柄調用點限定符7類符號引用進行。符號引用就是一組符號來描述目標,可以是任何字面量。

直接引用就是直接指向目標的指針、相對偏移量或一個間接定比特到目標的句柄。

初始化:對類的靜態變量,靜態代碼塊執行初始化操作

初始化,為類的靜態變量賦予正確的初始值,JVM負責對類進行初始化,主要對類變量進行初始化。在Java中對類變量進行初始值設定有兩種方式:

  • 聲明類變量是指定初始值
  • 使用靜態代碼塊為類變量指定初始值

類初始化的步驟

  • 假如這個類還沒有被加載和連接,則程序先加載並連接該類
  • 假如該類的直接父類還沒有被初始化,則先初始化其直接父類
  • 假如類中有初始化語句,則系統依次執行這些初始化語句

觸發類初始化的時機

只有當對類的主動使用的時候才會導致類的初始化,類的主動使用包括以下六種:

  • 使用new關鍵字實例化對象的時候。

  • 讀取或設置一個類型的靜態字段(被final修飾、已在編譯期把結果放入常量池的靜態字段除外)的時候。

  • 調用一個類型的靜態方法的時候。

  • 使用java.lang.reflect包的方法對類型進行反射調用的時候,如果類型沒有進行過初始化,則需要先觸發其初始化。

  • 當初始化類的時候,如果發現其父類還沒有進行過初始化,則需要先觸發其父類的初始化。

  • 當虛擬機啟動時,用戶需要指定一個要執行的主類(包含main()方法的那個類),虛擬機會先初始化這個主類。

以下幾種情况不會執行類初始化

  1. 通過子類引用父類的靜態字段,只會觸發父類的初始化,而不會觸發子類的初始化。

  2. 定義對象數組,不會觸發該類的初始化。

  3. 常量在編譯期間會存入調用類的常量池中,本質上並沒有直接引用定義常量的類,不會觸 發定義常量所在的類。

  4. 通過類名獲取 Class 對象,不會觸發類的初始化。

  5. 通過 Class.forName 加載指定類時,如果指定參數 initialize 為 false 時,也不會觸發類初 始化,其實這個參數是告訴虛擬機,是否要對類進行初始化。

  6. 通過 ClassLoader 默認的 loadClass 方法,也不會觸發初始化動作。

使用

類訪問方法區內的數據結構的接口, 對象是Heap區的數據。

卸載

Java虛擬機將結束生命周期的幾種情况

  • 執行了System.exit()方法
  • 程序正常執行結束
  • 程序在執行過程中遇到了异常或錯誤而异常終止
  • 由於操作系統出現錯誤而導致Java虛擬機進程終止

類加載器

什麼是類加載器

虛擬機設計團隊把類加載階段中的“通過一個類的全限定名來獲取描述此類的二進制字節流”這個動作放到Java虛擬機外部去實現,以便讓應用程序自己决定如何去獲取所需要的類。 實現這個動作的代碼模塊稱為“類加載器”。

類加載器的層次

必看的100道MySQL數據庫經典面試題解析,春招我借這份PDF的複習思路_Java_03

雙親委派模型要求除了頂層的啟動類加載器外,其餘的類加載器都應有自己的父類加載器。不過這裏類加載器之間的父子關系一般不是以繼承(Inheritance)的關系來實現的,而是通常使用組合(Composition)關系來複用父加載器的代碼。

從Java虛擬機的角度來講,只存在兩種不同的類加載器:一種是啟動類加載器(Bootstrap ClassLoader),這個類加載器使用C++語言實現,是虛擬機自身的一部分;另一種就是所有其他的類加載器,這些類加載器都由Java語言實現,獨立於虛擬機外部,並且全都繼承自抽象類java.lang.ClassLoader。

從Java開發人員的角度來看,類加載器還可以劃分得更細致一些,絕大部分Java程序都會使用到以下3種系統提供的類加載器:

啟動類加載器(Bootstrap ClassLoader)

這個類將器負責將存放在<JAVA_HOME>\lib目錄中的,或者被-Xbootclasspath參數所指定的路徑中的,並且是虛擬機識別的(按照文件名識別,如rt.jar、tools.jar,名字不符合的類庫即使放在lib目錄中也不會被加載)類庫加載到虛擬機內存中。

擴展類加載器(Extension ClassLoader)

這個加載器由sun.misc.Launcher$ExtClassLoader實現,它負責加載<JAVA_HOME>\lib\ext目錄中的,或者被java.ext.dirs系統變量所指定的路徑中的所有類庫,開發者可以直接使用擴展類加載器。

應用程序類加載器(Application ClassLoader)

這個類加載器由sun.misc.Launcher$AppClassLoader來實現。由於應用程序類加載器是ClassLoader類中的getSystem-ClassLoader()方法的返回值,所以有些場合中也稱它為“系統類加載器”。

它負責加載用戶類路徑(ClassPath)上所有的類庫,開發者同樣可以直接在代碼中使用這個類加載器。如果應用程序中沒有自定義過自己的類加載器,一般情况下這個就是程序中默認的類加載器。

我們的應用程序都是由這3種類加載器互相配合進行加載的,如果有必要,還可以加入自己定義的類加載器。

總結

面試建議是,一定要自信,敢於錶達,面試的時候我們對知識的掌握有時候很難面面俱到,把自己的思路說出來,而不是直接告訴面試官自己不懂,這也是可以加分的。

以上就是螞蟻技術四面和HR面試題目,以下最新總結的最全,範圍包含最全MySQL、Spring、Redis、JVM等最全面試題和答案,僅用於參考

必看的100道MySQL數據庫經典面試題解析,春招我借這份PDF的複習思路_Java_04

 CodeChina開源項目:【一線大廠Java面試題解析+核心總結學習筆記+最新講解視頻】

版权声明:本文为[程序員小秘境]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210919035400404z.html