Java经典面试题整理及答案详解(五)
Java經(jīng)典面試題第五彈來(lái)啦!本節(jié)面試題主要是針對(duì)Java初級(jí)基礎(chǔ)提問(wèn),看看你還記得多少?
1.String str=“hello”,這個(gè)字符串對(duì)象在棧內(nèi)存中明明有一個(gè)引用(str[ox00010]),為什么還說(shuō)這個(gè)字符串是匿名對(duì)象呢?
所謂的字符串是匿名對(duì)象,實(shí)際上是因?yàn)橹灰褂昧恕啊甭暶?#xff0c;那么就表示將在堆內(nèi)存空間里面開(kāi)辟一個(gè)新的字符串對(duì)象(String對(duì)象),這個(gè)對(duì)象是可以直接使用的,例如:““hello”.length()”。這個(gè)時(shí)候的字符串由于沒(méi)有引用,所以稱為匿名對(duì)象,對(duì)于此時(shí)的代碼“String str=“hello””,已經(jīng)明確的為str對(duì)象進(jìn)行實(shí)例化,所以“hello”對(duì)應(yīng)的堆內(nèi)存的地址已經(jīng)有了明確的棧內(nèi)存指向,就不是匿名對(duì)象了。
2.當(dāng)使用直接賦值額的方式實(shí)例化一個(gè)字符串對(duì)象的時(shí)候,他的引用是保存在哪里的?
只要是引用對(duì)象就保存在堆內(nèi)存里面,而我們所有能夠進(jìn)行的內(nèi)存控制,也只有堆內(nèi)存。
3,對(duì)象池(常量池)和棧是什么關(guān)系?
不論是對(duì)象池還是常量池,都是保存在堆內(nèi)存里面的,而堆內(nèi)存需要進(jìn)行一些合理的劃分。
4.不同的操作系統(tǒng)會(huì)由軟件和硬件模擬出不同的虛擬機(jī),但是不同的JVM對(duì)Java程序度支持,能實(shí)現(xiàn)這個(gè)功能的原理是不是:虛擬機(jī)中定義了類(lèi)似于接口這樣的操作,接口中定義了類(lèi)似native抽象方法,然后具體方法的實(shí)現(xiàn)交給操作系統(tǒng)去完成?
對(duì)于JVM有三種實(shí)現(xiàn)標(biāo)準(zhǔn),這三種實(shí)現(xiàn)標(biāo)準(zhǔn)我們使用的是HotSpot虛擬機(jī)標(biāo)準(zhǔn),這個(gè)標(biāo)準(zhǔn)的實(shí)現(xiàn)不是簡(jiǎn)單的調(diào)用一些底層函數(shù)。它里面是需要與一些設(shè)備進(jìn)行交互的,而整個(gè)系統(tǒng)設(shè)計(jì)之中,為了可以讓Java調(diào)用函數(shù)功能,專(zhuān)門(mén)提供有一個(gè)native交由JVM負(fù)責(zé)實(shí)現(xiàn)一些具體功能。
5.JVM內(nèi)存優(yōu)化
(1)JVM優(yōu)化的第一個(gè)問(wèn)題,取消掉伸縮區(qū),讓total=max;
—— CMS問(wèn)題,頻繁的CMS會(huì)導(dǎo)致性能下降;
——伊甸園區(qū)、存活區(qū)、老年代的關(guān)系要說(shuō)明白,JDK1.8之后取消了永久代,而使用元空間代替。
(2)如果你的內(nèi)存過(guò)大,要使用GI收集器來(lái)進(jìn)行收集;
(3)在Tomcat里面由于其使用基于JVM,所以需要設(shè)置一個(gè)“JAVA OPTS”指令,可以將全部的內(nèi)存供Tomcat使用(默認(rèn)的最大可用內(nèi)存為全部?jī)?nèi)存的四分之一,默認(rèn)的total內(nèi)存為全部?jī)?nèi)存的64分之1)。
6.JVM內(nèi)存組成
JVM內(nèi)存組成里面最為關(guān)鍵的幾個(gè)內(nèi)存:
(1)棧內(nèi)存:只是保存有堆內(nèi)存的引用地址,而且從一個(gè)簡(jiǎn)單的角度來(lái)講,棧內(nèi)存可以保存基本類(lèi)型;
(2)堆內(nèi)存:Java沒(méi)有采用句柄的模式進(jìn)行引用,所以它的引用性能是最高的,但是從另外一個(gè)角度來(lái)講,堆內(nèi)存里面實(shí)際上又分為若干個(gè)子內(nèi)存空間:伊甸園區(qū)、存活區(qū)、老年代(FullGC、MajorGC);
①原則:少產(chǎn)生無(wú)用的大量?jī)?nèi)存空間,因?yàn)闀?huì)引發(fā)頻繁的GC,而頻繁的GC會(huì)帶來(lái)CMS問(wèn)題,那么會(huì)導(dǎo)致程序中斷執(zhí)行,所以這個(gè)處理的原則之中對(duì)于程序員的要求;
②讓你初始化的空間大小等于整個(gè)堆內(nèi)存的分配大小,避免伸縮區(qū),這樣可以進(jìn)行性能的提升;
(3)方法區(qū)(JDK1.8以前可以稱為永久代,在JDK1.8之后稱為元空間);
(4)全局?jǐn)?shù)據(jù)區(qū)也可以認(rèn)為其規(guī)劃在堆內(nèi)存里面,因?yàn)闀?huì)發(fā)現(xiàn)全局?jǐn)?shù)據(jù)區(qū)中保存的內(nèi)容有可能是對(duì)象,有可能是基本類(lèi)型,只不過(guò)它采用了一種特殊的處理形式而已。
在面試中還有可能問(wèn)到的是堆內(nèi)存的組成以及GC的處理流程。
7.HashMap需要resize時(shí)擴(kuò)容因子是如何得到的?
如果要想解決這個(gè)問(wèn)題還是需要進(jìn)行源代碼的深入研究,也就是說(shuō)對(duì)于基本的數(shù)據(jù)結(jié)構(gòu)(類(lèi)集)。
在進(jìn)行數(shù)據(jù)添加的時(shí)候這個(gè)里面存在有一個(gè)put()方法:
在put()方法里面可以發(fā)現(xiàn)有一個(gè)putVal方法(),而且可以發(fā)現(xiàn)這個(gè)方法首先進(jìn)行了hash計(jì)算(查找),而后在這個(gè)方法的實(shí)現(xiàn)定義:
它的容量擴(kuò)充指的是一開(kāi)始放30個(gè),如果發(fā)現(xiàn)不夠了,則進(jìn)行位移處理,302,那么再一次擴(kuò)充302*2。
8.說(shuō)出RuntimeException和非RuntimeException的區(qū)別
這里最容易讓你混淆的只是一些名詞:
java.lang.Runtime類(lèi):是一個(gè)具備有單例設(shè)計(jì)模式的開(kāi)發(fā)類(lèi),在每一個(gè)JVM的進(jìn)程中只會(huì)存在一個(gè)Runtime類(lèi)的對(duì)象,這個(gè)類(lèi)給我們最大的幫助在于可以取得一些系統(tǒng)信息或者進(jìn)行一些進(jìn)程的處理操作。基本上使用這個(gè)類(lèi)取得一些內(nèi)存信息或者進(jìn)行垃圾收集處理。(GC)
整個(gè)JVM內(nèi)存劃分存在伸縮區(qū),面對(duì)這樣的問(wèn)題,為了提升性能,往往會(huì)將初始化內(nèi)存與最大內(nèi)存設(shè)為相同。(如果不相同,那么就需要一直進(jìn)行空間的判斷,而后不斷進(jìn)行空間的分配,這樣操作是比較可怕的。)
RuntimeException的異常子類(lèi)不需要強(qiáng)制性處理,可以由用戶選擇性處理,而Exception子類(lèi)必須進(jìn)行處理,RuntimeException是Exception子類(lèi)。
這些問(wèn)題放在一起,就是為了混淆你的認(rèn)識(shí),這樣才有的和你談,也是為了考察你的基本功是不是扎實(shí)。
9.Java內(nèi)存模型
(1)看你是否是知道Java的內(nèi)存劃分;
(2)看你是否有過(guò)具體的工作經(jīng)驗(yàn),因?yàn)樵趯?shí)際的開(kāi)發(fā)之中,如果不調(diào)整內(nèi)存,那么性能將會(huì)造成極大的浪費(fèi);
(3)關(guān)于GC的解釋操作。
說(shuō)到內(nèi)存,可能最直觀的理解就在于Runtime類(lèi)中,這個(gè)類(lèi)采用了單例設(shè)計(jì)模式,這個(gè)類(lèi)之中提供了內(nèi)存信息的取得,以及系統(tǒng)垃圾的收集處理操作。
范例:取得默認(rèn)的內(nèi)存大小:
這三個(gè)方法的返回值類(lèi)型都是long,所以返回的數(shù)據(jù)單位都是字節(jié)。
實(shí)際在Java里面如果想要進(jìn)行內(nèi)存的變更,就需要掌握一下內(nèi)存的結(jié)構(gòu)(內(nèi)存模型)。
在Java里面對(duì)于內(nèi)存的空間可以劃分為如下幾點(diǎn):
1.伊甸園區(qū):新生的對(duì)象都保存在此處,但這些新生的對(duì)象不一定會(huì)一直存活;
此處也屬于內(nèi)存空間,既然是內(nèi)存空間一定會(huì)被占滿,如果占滿了,就會(huì)執(zhí)行GC操作;
2.舊生代區(qū):如果某些對(duì)象其要一直使用,那么就將進(jìn)入到舊生代區(qū),這屬于二級(jí)回收保險(xiǎn);
如果要先執(zhí)行GC,那么肯定先清理伊甸園區(qū),隨后如果發(fā)現(xiàn)空間不足,繼續(xù)清理舊生代區(qū);
3.永久區(qū):永久區(qū)中的數(shù)據(jù)不會(huì)清除,即使程序出現(xiàn)了“OutOfMemoryError”也不會(huì)清除。
范例:直觀的觀察內(nèi)存
調(diào)整內(nèi)存大小:-Xms2048M-Xmx2048M-Xmn1024M
(1)“-Xms”:初始分配的內(nèi)存大小,默認(rèn)在物理內(nèi)存的64分之1,但是小于1G;
(2)“-Xmx”:最大分配內(nèi)存,默認(rèn)大小為物理內(nèi)存的4分之1,但是小于1G;
(3)“-Xmn”:設(shè)置年輕代(伊甸園區(qū))的堆內(nèi)存大小;
只有調(diào)整之后才可以保證系統(tǒng)內(nèi)存會(huì)得到提升,這樣很明顯,你就可以發(fā)揮出你電腦的性能,因?yàn)槟J(rèn)的大小。
更多專(zhuān)業(yè)知識(shí),面試技巧就在面試一點(diǎn)通,持續(xù)更新中……
感謝瀏覽~
本內(nèi)容來(lái)源于阿里云大學(xué)-Java面試技巧
總結(jié)
以上是生活随笔為你收集整理的Java经典面试题整理及答案详解(五)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java经典面试题整理及答案详解(四)
- 下一篇: Java经典面试题整理及答案详解(八)