大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

面試題首頁(yè) > JVM面試題

JVM類加載器面試題

001JDK、JRE、JVM關(guān)系?

JDK (Java Development Kit) : java語(yǔ)言的軟件開(kāi)發(fā)包。包括Java運(yùn)行時(shí)環(huán)境JRE。
JRE (Java Runtime Environment) :Java運(yùn)行時(shí)環(huán)境,包括JVM。
JVM (Java Virtual Machine) :一種用于計(jì)算機(jī)設(shè)備的規(guī)范。
Java語(yǔ)言在不同平臺(tái)上運(yùn)行時(shí)不需要重新編譯。Java語(yǔ)言使用Java虛擬機(jī)屏蔽了與具體平臺(tái)相關(guān)的信息,使得Java語(yǔ)言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。

002什么是類加載器,類加載器有哪些?

實(shí)現(xiàn)通過(guò)類的權(quán)限定名獲取該類的二進(jìn)制字節(jié)流的代碼塊叫做類加載器。
啟動(dòng)類加載器(Bootstrap ClassLoader)用來(lái)加載 java 核心類庫(kù),無(wú)法被 java 程序直接引用。
擴(kuò)展類加載器(extensions class loader):它用來(lái)加載 Java 的擴(kuò)展庫(kù)。Java虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫(kù)目錄。該類加載器在此目錄里面查找并加載 Java 類。
系統(tǒng)類加載器(system class loader):它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH) 來(lái)加載 Java類。一般來(lái)說(shuō),Java應(yīng)用的類都是由它來(lái)完成加載的。可以通過(guò)ClassLoader.getSystemClassLoader()來(lái)獲取它。
用戶自定義類加載器,通過(guò)繼承 java.lang.ClassLoader 類的方式實(shí)現(xiàn)。

003ClassLoader如何工作的?

ClassLoader 顧名思義就是類加載器。Java源代碼首先被jvm編譯成.class文件。類從被加載到虛擬機(jī)內(nèi)存中開(kāi)始,直到卸載出內(nèi)存為止,它的整個(gè)生命周期包括了:加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用和卸載這7個(gè)階段。其中,驗(yàn)證、準(zhǔn)備和解析這三個(gè)部分統(tǒng)稱為連接(linking)。
加載:通過(guò)一個(gè)類的全限定名來(lái)獲取定義此類的二進(jìn)制字節(jié)流,將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu),在內(nèi)存中生成一個(gè)代表這個(gè)類的Class對(duì)象,作為方法去這個(gè)類的各種數(shù)據(jù)的訪問(wèn)入口;
驗(yàn)證:驗(yàn)證是連接階段的第一步,這一階段的目的是確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬自身的安全;
準(zhǔn)備:準(zhǔn)備階段是正式為類變量分配內(nèi)存并設(shè)置類變量初始值的階段,這些變量所使用的內(nèi)存都將在方法去中進(jìn)行分配。這時(shí)候進(jìn)行內(nèi)存分配的僅包括類變量(static),而不包括實(shí)例變量,實(shí)例變量將會(huì)在對(duì)象實(shí)例化時(shí)隨著對(duì)象一起分配在Java堆中。
解析:解析階段是虛擬機(jī)將常量池內(nèi)的符號(hào)(Class文件內(nèi)的符號(hào))引用替換為直接引用(指針)的過(guò)程。
初始化:初始化階段是類加載過(guò)程的最后一步,開(kāi)始執(zhí)行類中定義的Java程序代碼(字節(jié)碼)。

004靜態(tài)代碼塊在程序中的執(zhí)行順序?

父類靜態(tài)域——》子類靜態(tài)域——》父類成員初始化——》父類構(gòu)造塊——》父類構(gòu)造方法——》子類成員初始化——》子類構(gòu)造塊——》子類構(gòu)造方法;

005對(duì)象創(chuàng)建的過(guò)程?

類加載檢查:虛擬機(jī)遇到一條 new 指令時(shí),首先檢查這個(gè)指令的參數(shù)是否能在常量池中定位到這個(gè)類的符號(hào)引用,并且檢查這個(gè)符號(hào)引用代表的類是否已被加載過(guò)、解析和初始化過(guò)。如果沒(méi)有,那必須先執(zhí)行相應(yīng)的類加載過(guò)程。
分配內(nèi)存:在類加載檢查通過(guò)后,接下來(lái)虛擬機(jī)將為新生對(duì)象分配內(nèi)存。對(duì)象所需的內(nèi)存大小在類加載完成后便可確定,為對(duì)象分配空間的任務(wù)等同于把一塊確定大小的內(nèi)存從 Java 堆中劃分出來(lái)。分配方式有 “指針碰撞” 和 “空閑列表” 兩種,選擇那種分配方式由 Java 堆是否規(guī)整決定,而 Java 堆是否規(guī)整又由所采用的垃圾收集器是否帶有壓縮整理功能決定。
初始化零值:內(nèi)存分配完成后,虛擬機(jī)需要將分配到的內(nèi)存空間都初始化為零值(不包括對(duì)象頭),這一步操作保證了對(duì)象的實(shí)例字段在 Java 代碼中可以不賦初始值就直接使用,程序能訪問(wèn)到這些字段的數(shù)據(jù)類型所對(duì)應(yīng)的零值。
設(shè)置對(duì)象頭:初始化零值完成之后,虛擬機(jī)要對(duì)對(duì)象進(jìn)行必要的設(shè)置,例如這個(gè)對(duì)象是哪個(gè)類的實(shí)例、如何才能找到類的元數(shù)據(jù)信息、對(duì)象的哈希碼、對(duì)象的 GC 分代年齡等信息。 這些信息存放在對(duì)象頭中。 另外,根據(jù)虛擬機(jī)當(dāng)前運(yùn)行狀態(tài)的不同,如是否啟用偏向鎖等,對(duì)象頭會(huì)有不同的設(shè)置方式。
執(zhí)行init方法:在上面工作都完成之后,從虛擬機(jī)的視角來(lái)看,一個(gè)新的對(duì)象已經(jīng)產(chǎn)生了,但從 Java 程序的視角來(lái)看,對(duì)象創(chuàng)建才剛開(kāi)始,<init> 方法還沒(méi)有執(zhí)行,所有的字段都還為零。所以一般來(lái)說(shuō),執(zhí)行 new 指令之后會(huì)接著執(zhí)行 <init> 方法,把對(duì)象按照程序員的意愿進(jìn)行初始化,這樣一個(gè)真正可用的對(duì)象才算完全產(chǎn)生出來(lái)。

006什么是雙親委派機(jī)制?

1.如果一個(gè)類加載器收到了類加載請(qǐng)求,它并不會(huì)自己先加載,而是把這個(gè)請(qǐng)求委托給父類的加載器去執(zhí)行;
2.如果父類加載器還存在其父類加載器,則進(jìn)一步向上委托,依次遞歸,請(qǐng)求最終將到達(dá)頂層的引導(dǎo)類加載器;
3.如果父類加載器可以完成類加載任務(wù),就成功返回,倘若父類加載器無(wú)法完成加載任務(wù),子加載器才會(huì)嘗試自己去加載,這就是雙親委派機(jī)制;

007雙親委派機(jī)制的優(yōu)勢(shì)?

避免類的重復(fù)加載,保護(hù)程序安全,防止核心API被隨意篡改。

008如何破壞雙親委派模型?

JNDI(Java Naming and Directory Interface,Java命名和目錄接口)便是最典型的例子。JND需要調(diào)用由獨(dú)立廠商實(shí)現(xiàn)并部署在應(yīng)用程序的ClassPath下的JNDI接口提供者(SPI,Service Provider Interface)的代碼,但啟動(dòng)類加載器不可能“認(rèn)識(shí)”這些代碼那該怎么辦?
為了解決這個(gè)問(wèn)題,Java設(shè)計(jì)團(tuán)隊(duì)只好引入了一個(gè)不太優(yōu)雅的設(shè)計(jì):線程上下文類加載器(Thread Context ClassLoader)。這個(gè)類加載器可以通過(guò)java.lang.Thread類的 setContextClassLoaser()方法進(jìn)行設(shè)置。有了線程上下文類加載器,JNDI服務(wù)使用這個(gè)線程上下文類加載器去加載所需要的SPI代碼,也就是父類加載器請(qǐng)求子類加載器去完成類加載的動(dòng)作,這種行為實(shí)際上就是打通了雙親委派模型的層次結(jié)構(gòu)來(lái)逆向使用類加載器,實(shí)際上已經(jīng)違背了雙親委派模型的一般性原則。Java中所有涉及SPI的加載動(dòng)作基本上都采用這種方式,例如JNDI、JDBC、JCE、JAXB和JBI等。
例如JDBC在rt里面定義了這個(gè)SPI,那MySQL有MySQL的JDBC實(shí)現(xiàn),Oracle有Oracle的JDBC實(shí)現(xiàn),反正我java不管你內(nèi)部如何實(shí)現(xiàn)的,反正你們都得統(tǒng)一按我這個(gè)來(lái),這樣我們java開(kāi)發(fā)者才能容易的調(diào)用數(shù)據(jù)庫(kù)操作。所以因?yàn)檫@樣那就不得不違反這個(gè)約束啊,Bootstrap ClassLoader就得委托子類來(lái)加載數(shù)據(jù)庫(kù)廠商們提供的具體實(shí)現(xiàn)。因?yàn)樗氖种荒苊?lt;JAVA_HOME>\lib中,其他的它無(wú)能為力,這就違反了自下而上的委托機(jī)制了。

009可不可以自己寫個(gè)String類?

不可以。因?yàn)樵陬惣虞d中,會(huì)根據(jù)雙親委派機(jī)制去尋找當(dāng)前java.lang.String是否已被加載。由于啟動(dòng)類加載器已在啟動(dòng)時(shí)候加載了所以不會(huì)再次加載,因此使用的String是已在java核心類庫(kù)加載過(guò)的String,而不是新定義的String。

010什么是字節(jié)碼?

Java源程序.java通過(guò)編譯器編譯成字節(jié)碼.class文件,也就是計(jì)算機(jī)可以識(shí)別的二進(jìn)制文件。

011字節(jié)碼文件組成結(jié)構(gòu)是什么?

根據(jù) Java 虛擬機(jī)規(guī)范的規(guī)定,class 文件格式采用一種類似于 C 語(yǔ)言的偽結(jié)構(gòu)來(lái)存儲(chǔ)數(shù)據(jù),這種偽結(jié)構(gòu)中只有兩種數(shù)據(jù)類型:無(wú)符號(hào)數(shù)和表。

無(wú)符號(hào)數(shù)屬于基礎(chǔ)數(shù)據(jù)類型,以 u1、u2、u4、u8 來(lái)分別代表 1 個(gè)字節(jié)、2 個(gè)字節(jié)、4 個(gè)字節(jié)和 8 個(gè)字節(jié)的無(wú)符號(hào)數(shù),無(wú)符號(hào)數(shù)可以用來(lái)描述數(shù)字、索引引用、數(shù)量值或者按照 UTF-8 編碼構(gòu)成的字符串值。
是由多個(gè)無(wú)符號(hào)數(shù)或者其他表作為數(shù)據(jù)項(xiàng)構(gòu)成的復(fù)合數(shù)據(jù)結(jié)構(gòu),所有表都習(xí)慣性地以 _info 結(jié)尾。表用于描述有層次關(guān)系的復(fù)合結(jié)構(gòu)的數(shù)據(jù),整個(gè) class 文件本質(zhì)上就是一張表。

012對(duì)象的finalization機(jī)制。

Java語(yǔ)言提供了對(duì)象終止(finalization)機(jī)制來(lái)允許開(kāi)發(fā)人員提供對(duì)象被銷毀之前的自定義處理邏輯。當(dāng)垃圾回收器發(fā)現(xiàn)沒(méi)有引用指向一個(gè)對(duì)象,即:垃圾回收此對(duì)象之前,總會(huì)先調(diào)用這個(gè)對(duì)象的finalize()方法,finalize()只會(huì)被調(diào)用一次。finalize() 方法允許在子類中被重寫,用于在對(duì)象被回收時(shí)進(jìn)行資源釋放。通常在這個(gè)方法中進(jìn)行一些資源釋放和清理的工作,比如關(guān)閉文件、套接字和數(shù)據(jù)庫(kù)連接等。

013如何判斷兩個(gè)class對(duì)象是否相同?

在JVM中表示兩個(gè)class對(duì)象是否為同一個(gè)類存在兩個(gè)必要條件:
1)類的完整類名必須一致,包括包名。
2)加載這個(gè)類的ClassLoader(指ClassLoader實(shí)例對(duì)象)必須相同。

014類的主動(dòng)使用有哪些?

主動(dòng)使用,分為七種情況:
1)創(chuàng)建類的實(shí)例
2)訪問(wèn)某個(gè)類或接口的靜態(tài)變量,或者對(duì)該靜態(tài)變量賦值
3)調(diào)用類的靜態(tài)方法I
4)反射(比如:Class.forName(“com.atguigu.Test”))
5)初始化一個(gè)類的子類
6)Java虛擬機(jī)啟動(dòng)時(shí)被標(biāo)明為啟動(dòng)類的類
7)JDK7開(kāi)始提供的動(dòng)態(tài)語(yǔ)言支持:java.lang.invoke.MethodHandle實(shí)例的解析結(jié)果REF getStatic、REF putStatic、REF invokeStatic句柄對(duì)應(yīng)的類沒(méi)有初始化,則初始化
除了以上七種情況,其他使用Java類的方式都被看作是對(duì)類的被動(dòng)使用,都不會(huì)導(dǎo)致類的初始化。

015深拷貝和淺拷貝區(qū)別?

淺拷貝:只是增加了一個(gè)指針指向已存在的內(nèi)存地址,
深拷貝:是增加了一個(gè)指針并且申請(qǐng)了一個(gè)新的內(nèi)存,使這個(gè)增加的指針指向這個(gè)新的內(nèi)存,使用深拷貝的情況下,釋放內(nèi)存的時(shí)候不會(huì)因?yàn)槌霈F(xiàn)淺拷貝時(shí)釋放同一個(gè)內(nèi)存的錯(cuò)誤。
淺復(fù)制:僅僅是指向被復(fù)制的內(nèi)存地址,如果原地址發(fā)生改變,那么淺復(fù)制出來(lái)的對(duì)象也會(huì)相應(yīng)的改變。
深復(fù)制:在計(jì)算機(jī)中開(kāi)辟一塊新的內(nèi)存地址用于存放復(fù)制的對(duì)象。

016啟動(dòng)程序如何查看加載了哪些類,以及加載順序?

java -XX:+TraceClassLoading 具體類
Java -verbose 具體類

目錄

返回頂部
主站蜘蛛池模板: 色综合视频 | 欧美黄网站 | 热re66久久精品国产99re | 亚洲性另类 | 久久婷婷激情综合中文字幕 | 日韩城人视频 | 欧美一级午夜免费视频你懂的 | 欧美jizzhd精品欧美4k | 欧美91在线 | 婷婷国产偷v国产偷v亚洲 | 四虎免费永久观看 | 最新99国产成人精品视频免费 | 午夜操操 | 国产高清美女一级毛片久久 | 欧美大片日韩精品四虎影视 | 国产一区在线观看视频 | 最新精品在线 | 久久久久久夜精品精品免费啦 | 日本不卡免费高清一级视频 | 久久国产影视免费精品 | 99国产成人高清在线视频 | 久久亚洲国产精品一区二区 | 久久中文字幕在线观看 | 99久久精品国产一区二区三区 | 色吧在线视频 | 久久久久久久久亚洲 | 综合久久影院 | 国内一级特黄女人精品片 | 亚洲国产午夜精品理论片的软件 | 狠狠色成人综合 | 92在线视频 | 国产95在线 | 亚洲 | 毛片在线观看视频 | 一本色道久久综合一区 | 四虎影视在线观看2413 | 日本不卡在线播放 | 中文字幕伦理聚合第一页 | 国产亚洲亚洲精品777 | 国产欧美国产精品第二区 | 九九99视频在线观看视频观看 | 欧美日日射|