一篇面試了無(wú)數(shù)公司后總結(jié)的面試題叫挟,學(xué)完面試不上我把工資卡給你

1、什么是線程局部變量限煞?

線程局部變量是局限于線程內(nèi)部的變量抹恳,屬于線程自身所有,不在多個(gè)線程間共享署驻。Java 提供 ThreadLocal 類(lèi)來(lái)支持線程局部變量奋献,是一種實(shí)現(xiàn)線程安全的方式。但是在管理環(huán)境下(如 web 服務(wù)器)使用線程局部變量的時(shí)候要特別小心旺上,在這種情況下瓶蚂,工作線程的生命周期比任何應(yīng)用變量的生命周期都要長(zhǎng)。任何線程局部變量一旦在工作完成后沒(méi)有釋放宣吱,Java 應(yīng)用就存在內(nèi)存泄露的風(fēng)險(xiǎn)窃这。

2.用 wait-notify 寫(xiě)一段代碼來(lái)解決生產(chǎn)者-消費(fèi)者問(wèn)題?

請(qǐng)參考答案中的示例代碼征候。只要記住在同步塊中調(diào)用 wait() 和 notify()方法杭攻,如果阻塞,通過(guò)循環(huán)來(lái)測(cè)試等待條件疤坝。

java面試資料點(diǎn)擊領(lǐng)取

【生產(chǎn)者】

packagecom.edu.chapter03.test;importjava.util.Vector;importjava.util.logging.Level;importjava.util.logging.Logger;publicclassProducerimplementsRunnable{privatefinalVector sharedQueue;privatefinalintSIZE;publicProducer(Vector sharedQueue,intsize){this.sharedQueue = sharedQueue;this.SIZE = size;}@Overridepublicvoidrun(){// TODO Auto-generated method stubfor (int i = 0; i < 7; i++) {System.out.println("Produced:" + i);try {produce(i);} catch (InterruptedException ex) {Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);}}}private void produce(int i) throws InterruptedException {//wait if queue is fullwhile (sharedQueue.size() == SIZE) {synchronized (sharedQueue) {System.out.println("Queue is full " + Thread.currentThread().getName()+ " is waiting , size: " + sharedQueue.size());sharedQueue.wait();}}//producing element and notify consumerssynchronized (sharedQueue) {sharedQueue.add(i);sharedQueue.notifyAll();}}}

【消費(fèi)者】

packagecom.edu.chapter03.test;importjava.util.Vector;importjava.util.logging.Level;importjava.util.logging.Logger;publicclassConsumerimplementsRunnable{privatefinalVector sharedQueue;privatefinalintSIZE;publicConsumer(Vector sharedQueue,intsize){this.sharedQueue = sharedQueue;this.SIZE = size;}@Overridepublicvoidrun(){// TODO Auto-generated method stubwhile (true) {try {System.out.println("Consumer: " + consume());Thread.sleep(50);} catch (InterruptedException ex) {Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);}}}private int consume() throws InterruptedException {//wait if queue is emptywhile (sharedQueue.isEmpty()) {synchronized (sharedQueue) {System.out.println("Queue is empty " + Thread.currentThread().getName()+ " is waiting , size: " + sharedQueue.size());sharedQueue.wait();}}//otherwise consume element and notify waiting producersynchronized (sharedQueue) {sharedQueue.notifyAll();return (Integer) sharedQueue.remove(0);}}}

【測(cè)試函數(shù)】

packagecom.edu.chapter03.test;importjava.util.Vector;publicclassProducerConsumerSolution{publicstaticvoidmain(String[] args){Vector sharedQueue =newVector();intsize =4;Thread prodThread =newThread(newProducer(sharedQueue, size),"Producer");Thread consThread =newThread(newConsumer(sharedQueue, size),"Consumer");prodThread.start();consThread.start();}}

3. 用 Java 寫(xiě)一個(gè)線程安全的單例模式(Singleton)兆解?

請(qǐng)參考答案中的示例代碼,這里面一步一步教你創(chuàng)建一個(gè)線程安全的 Java 單例類(lèi)跑揉。當(dāng)我們說(shuō)線程安全時(shí)锅睛,意思是即使初始化是在多線程環(huán)境中,仍然能保證單個(gè)實(shí)例。Java 中衣撬,使用枚舉作為單例類(lèi)是最簡(jiǎn)單的方式來(lái)創(chuàng)建線程安全單例模式的方式乖订。

立即加載/餓漢式:

【在調(diào)用方法前,實(shí)例就已經(jīng)被創(chuàng)建】

packagecom.weishiyao.learn.day8.singleton.ep1;publicclassMyObject{// 立即加載方式==惡漢模式private static MyObject myObject = new MyObject();private MyObject() {}public static MyObject getInstance() {// 此代碼版本為立即加載// 此版本代碼的缺點(diǎn)是不能有其他實(shí)例變量// 因?yàn)間etInstance()方法沒(méi)有同步// 所以有可能出現(xiàn)非線程安全的問(wèn)題return myObject;}}

【創(chuàng)建線程類(lèi)】

packagecom.weishiyao.learn.day8.singleton.ep1;publicclassMyThreadextendsThread{@Overridepublicvoidrun(){System.out.println(MyObject.getInstance().hashCode());}}

【創(chuàng)建運(yùn)行類(lèi)】

packagecom.weishiyao.learn.day8.singleton.ep1;publicclassRun{publicstaticvoidmain(String[] args){MyThread t1 =newMyThread();MyThread t2 =newMyThread();MyThread t3 =newMyThread();t1.start();t2.start();t3.start();}}

延遲加載/懶漢式

【建對(duì)象的實(shí)例】

packagecom.weishiyao.learn.day8.singleton.ep2;publicclassMyObject{privatestaticMyObject myObject;privateMyObject(){}publicstaticMyObjectgetInstance(){// 延遲加載if (myObject != null) {} else {myObject = new MyObject();}return myObject;}}

【創(chuàng)建線程類(lèi)】

packagecom.weishiyao.learn.day8.singleton.ep2;publicclassMyThreadextendsThread{@Overridepublicvoidrun(){System.out.println(MyObject.getInstance().hashCode());}}

【創(chuàng)建運(yùn)行類(lèi)】

packagecom.weishiyao.learn.day8.singleton.ep2;publicclassRun{publicstaticvoidmain(String[] args){MyThread t1 =newMyThread();t1.start();}}

【運(yùn)行測(cè)試類(lèi)】

packagecom.weishiyao.learn.day8.singleton.ep2;publicclassRun{publicstaticvoidmain(String[] args){MyThread t1 =newMyThread();MyThread t2 =newMyThread();MyThread t3 =newMyThread();MyThread t4 =newMyThread();MyThread t5 =newMyThread();t1.start();t2.start();t3.start();t4.start();t5.start();}}

4.Java 中 sleep 方法和 wait 方法的區(qū)別具练?

雖然兩者都是用來(lái)暫停當(dāng)前運(yùn)行的線程乍构,但是 sleep() 實(shí)際上只是短暫停頓,因?yàn)樗粫?huì)釋放鎖扛点,而 wait() 意味著條件等待哥遮,這就是為什么該方法要釋放鎖,因?yàn)橹挥羞@樣陵究,其他等待的線程才能在滿足條件時(shí)獲取到該鎖眠饮。

5.什么是不可變對(duì)象(immutable object)?Java 中怎么創(chuàng)建一個(gè)不可變對(duì)象铜邮?

不可變對(duì)象指對(duì)象一旦被創(chuàng)建仪召,狀態(tài)就不能再改變。任何修改都會(huì)創(chuàng)建一個(gè)新的對(duì)象松蒜,如 String扔茅、Integer及其它包裝類(lèi)。詳情參見(jiàn)答案秸苗,一步一步指導(dǎo)你在 Java 中創(chuàng)建一個(gè)不可變的類(lèi)召娜。

6.我們能創(chuàng)建一個(gè)包含可變對(duì)象的不可變對(duì)象嗎?

是的惊楼,我們是可以創(chuàng)建一個(gè)包含可變對(duì)象的不可變對(duì)象的玖瘸,你只需要謹(jǐn)慎一點(diǎn),不要共享可變對(duì)象的引用就可以了檀咙,如果需要變化時(shí)雅倒,就返回原對(duì)象的一個(gè)拷貝。最常見(jiàn)的例子就是對(duì)象中包含一個(gè)日期對(duì)象的引用弧可。

7.Java 中應(yīng)該使用什么數(shù)據(jù)類(lèi)型來(lái)代表價(jià)格蔑匣?

如果不是特別關(guān)心內(nèi)存和性能的話,使用BigDecimal侣诺,否則使用預(yù)定義精度的 double 類(lèi)型殖演。

8.怎么將 byte 轉(zhuǎn)換為 String氧秘?

可以使用 String 接收 byte[] 參數(shù)的構(gòu)造器來(lái)進(jìn)行轉(zhuǎn)換年鸳,需要注意的點(diǎn)是要使用的正確的編碼,否則會(huì)使用平臺(tái)默認(rèn)編碼丸相,這個(gè)編碼可能跟原來(lái)的編碼相同搔确,也可能不同。

9.Java 中 bytes 與其他類(lèi)型的轉(zhuǎn)換?

public class Test {private static ByteBuffer buffer = ByteBuffer.allocate(8);public static void main(String[] args) {//測(cè)試 int 轉(zhuǎn) byteint int0 =234;bytebyte0 = intToByte(int0);System.out.println("byte0="+ byte0);//byte0=-22//測(cè)試byte轉(zhuǎn) intint int1 = byteToInt(byte0);System.out.println("int1="+ int1);//int1=234//測(cè)試 int 轉(zhuǎn)byte數(shù)組int int2 =1417;byte[] bytesInt = intToByteArray(int2);System.out.println("bytesInt="+ bytesInt);//bytesInt=[B@de6ced//測(cè)試byte數(shù)組轉(zhuǎn) intint int3 = byteArrayToInt(bytesInt);System.out.println("int3="+ int3);//int3=1417//測(cè)試 long 轉(zhuǎn)byte數(shù)組long long1 =2223;byte[] bytesLong = longToBytes(long1);System.out.println("bytes="+ bytesLong);//bytes=[B@c17164//測(cè)試byte數(shù)組 轉(zhuǎn) longlong long2 = bytesToLong(bytesLong);System.out.println("long2="+ long2);//long2=2223}//byte與 int 的相互轉(zhuǎn)換public staticbyteintToByte(int x) {return(byte) x;}public static int byteToInt(byteb) {//Java 總是把byte當(dāng)做有符處理膳算;我們可以通過(guò)將其和0xFF進(jìn)行二進(jìn)制與得到它的無(wú)符值returnb &0xFF;}//byte數(shù)組與 int 的相互轉(zhuǎn)換public static int byteArrayToInt(byte[] b) {returnb[3] &0xFF|(b[2] &0xFF) <<8|(b[1] &0xFF) <<16|(b[0] &0xFF) <<24;}public staticbyte[] intToByteArray(int a) {returnnewbyte[] {(byte) ((a >>24) &0xFF),(byte) ((a >>16) &0xFF),(byte) ((a >>8) &0xFF),(byte) (a &0xFF)};}//byte數(shù)組與 long 的相互轉(zhuǎn)換public staticbyte[] longToBytes(long x) {buffer.putLong(0, x);returnbuffer.array();}public static long bytesToLong(byte[] bytes) {buffer.put(bytes,0, bytes.length);buffer.flip();//need flipreturn buffer.getLong();}}

10.我們能將 int 強(qiáng)制轉(zhuǎn)換為 byte 類(lèi)型的變量嗎座硕?如果該值大于 byte 類(lèi)型的范圍,將會(huì)出現(xiàn)什么現(xiàn)象涕蜂?

是的华匾,我們可以做強(qiáng)制轉(zhuǎn)換,但是 Java 中 int 是 32 位的机隙,而 byte 是 8 位的蜘拉,所以,如果強(qiáng)制轉(zhuǎn)化是有鹿,int 類(lèi)型的高 24 位將會(huì)被丟棄旭旭,byte 類(lèi)型的范圍是從 -128 到 128。

11.存在兩個(gè)類(lèi)葱跋,B 繼承 A持寄,C 繼承 B,我們能將 B 轉(zhuǎn)換為 C 么娱俺?如 C = (C) B稍味;

可以,向下轉(zhuǎn)型矢否。但是不建議使用仲闽,容易出現(xiàn)類(lèi)型轉(zhuǎn)型異常。

12.哪個(gè)類(lèi)包含 clone 方法僵朗?是 Cloneable 還是 Object赖欣?

java.lang.Cloneable 是一個(gè)標(biāo)示性接口,不包含任何方法验庙,clone 方法在 object 類(lèi)中定義顶吮。并且需要知道 clone() 方法是一個(gè)本地方法,這意味著它是由 c 或 c++ 或 其他本地語(yǔ)言實(shí)現(xiàn)的粪薛。

13.Java 中 ++ 操作符是線程安全的嗎悴了?

不是線程安全的操作。它涉及到多個(gè)指令违寿,如讀取變量值湃交,增加,然后存儲(chǔ)回內(nèi)存藤巢,這個(gè)過(guò)程可能會(huì)出現(xiàn)多個(gè)線程交叉搞莺。

14.a = a + b 與 a += b 的區(qū)別

+= 隱式的將加操作的結(jié)果類(lèi)型強(qiáng)制轉(zhuǎn)換為持有結(jié)果的類(lèi)型。如果兩這個(gè)整型相加掂咒,如 byte才沧、short 或者 int迈喉,首先會(huì)將它們提升到 int 類(lèi)型,然后再執(zhí)行加法操作温圆。如果加法操作的結(jié)果比 a 的最大值要大挨摸,則 a+b 會(huì)出現(xiàn)編譯錯(cuò)誤,但是 a += b 沒(méi)問(wèn)題岁歉,如下:

byte a = 127;

byte b = 127;

b = a + b; // error : cannot convert from int to byte

b += a; // ok

(譯者注:這個(gè)地方應(yīng)該表述的有誤得运,其實(shí)無(wú)論 a+b 的值為多少,編譯器都會(huì)報(bào)錯(cuò)锅移,因?yàn)?a+b 操作會(huì)將 a澈圈、b 提升為 int 類(lèi)型,所以將 int 類(lèi)型賦值給 byte 就會(huì)編譯出錯(cuò))

15.我能在不進(jìn)行強(qiáng)制轉(zhuǎn)換的情況下將一個(gè) double 值賦值給 long 類(lèi)型的變量嗎帆啃?

不行瞬女,你不能在沒(méi)有強(qiáng)制類(lèi)型轉(zhuǎn)換的前提下將一個(gè) double 值賦值給 long 類(lèi)型的變量,因?yàn)?double 類(lèi)型的范圍比 long 類(lèi)型更廣努潘,所以必須要進(jìn)行強(qiáng)制轉(zhuǎn)換诽偷。

16. 3*0.1 == 0.3 將會(huì)返回什么?true 還是 false疯坤?

false报慕,因?yàn)橛行└↑c(diǎn)數(shù)不能完全精確的表示出來(lái)。

17.int 和 Integer 哪個(gè)會(huì)占用更多的內(nèi)存压怠?

Integer 對(duì)象會(huì)占用更多的內(nèi)存眠冈。Integer 是一個(gè)對(duì)象,需要存儲(chǔ)對(duì)象的元數(shù)據(jù)菌瘫。但是 int 是一個(gè)原始類(lèi)型的數(shù)據(jù)蜗顽,所以占用的空間更少。

18.為什么 Java 中的 String 是不可變的(Immutable)雨让?

Java 中的 String 不可變是因?yàn)?Java 的設(shè)計(jì)者認(rèn)為字符串使用非常頻繁雇盖,將字符串設(shè)置為不可變可以允許多個(gè)客戶端之間共享相同的字符串。更詳細(xì)的內(nèi)容參見(jiàn)答案栖忠。

19.我們能在 Switch 中使用 String 嗎崔挖?

從 Java 7 開(kāi)始,我們可以在 switch case 中使用字符串庵寞,但這僅僅是一個(gè)語(yǔ)法糖狸相。內(nèi)部實(shí)現(xiàn)在 switch 中使用字符串的 hash code。

20.Java 中的構(gòu)造器鏈?zhǔn)鞘裁矗?/p>

當(dāng)你從一個(gè)構(gòu)造器中調(diào)用另一個(gè)構(gòu)造器捐川,就是Java 中的構(gòu)造器鏈脓鹃。這種情況只在重載了類(lèi)的構(gòu)造器的時(shí)候才會(huì)出現(xiàn)。

21.64 位 JVM 中属拾,int 的長(zhǎng)度是多數(shù)将谊?

Java 中,int 類(lèi)型變量的長(zhǎng)度是一個(gè)固定值渐白,與平臺(tái)無(wú)關(guān)尊浓,都是 32 位。意思就是說(shuō)纯衍,在 32 位 和 64 位 的Java 虛擬機(jī)中栋齿,int 類(lèi)型的長(zhǎng)度是相同的。

22.Serial 與 Parallel GC之間的不同之處襟诸?

Serial 與 Parallel 在GC執(zhí)行的時(shí)候都會(huì)引起 stop-the-world瓦堵。它們之間主要不同 serial 收集器是默認(rèn)的復(fù)制收集器,執(zhí)行 GC 的時(shí)候只有一個(gè)線程歌亲,而 parallel 收集器使用多個(gè) GC 線程來(lái)執(zhí)行菇用。

23. 32 位和 64 位的 JVM,int 類(lèi)型變量的長(zhǎng)度是多數(shù)陷揪?

32 位和 64 位的 JVM 中惋鸥,int 類(lèi)型變量的長(zhǎng)度是相同的,都是 32 位或者 4 個(gè)字節(jié)悍缠。

24.Java 中 WeakReference 與 SoftReference的區(qū)別卦绣?

雖然 WeakReference 與 SoftReference 都有利于提高 GC 和 內(nèi)存的效率,但是 WeakReference 飞蚓,一旦失去最后一個(gè)強(qiáng)引用滤港,就會(huì)被 GC 回收,而軟引用雖然不能阻止被回收趴拧,但是可以延遲到 JVM 內(nèi)存不足的時(shí)候溅漾。

25.WeakHashMap 是怎么工作的?

WeakHashMap 的工作與正常的 HashMap 類(lèi)似著榴,但是使用弱引用作為 key樟凄,意思就是當(dāng) key 對(duì)象沒(méi)有任何引用時(shí),key/value 將會(huì)被回收兄渺。

26.JVM 選項(xiàng) -XX:+UseCompressedOops 有什么作用缝龄?為什么要使用?

當(dāng)你將你的應(yīng)用從 32 位的 JVM 遷移到 64 位的 JVM 時(shí)挂谍,由于對(duì)象的指針從 32 位增加到了 64 位叔壤,因此堆內(nèi)存會(huì)突然增加,差不多要翻倍口叙。這也會(huì)對(duì) CPU 緩存(容量比內(nèi)存小很多)的數(shù)據(jù)產(chǎn)生不利的影響炼绘。因?yàn)椋w移到 64 位的 JVM 主要?jiǎng)訖C(jī)在于可以指定最大堆大小妄田,通過(guò)壓縮 OOP 可以節(jié)省一定的內(nèi)存俺亮。通過(guò) -XX:+UseCompressedOops 選項(xiàng)驮捍,JVM 會(huì)使用 32 位的 OOP,而不是 64 位的 OOP脚曾。

27.怎樣通過(guò) Java 程序來(lái)判斷 JVM 是 32 位 還是 64 位东且?

你可以檢查某些系統(tǒng)屬性如 sun.arch.data.model 或 os.arch 來(lái)獲取該信息。

28.32 位 JVM 和 64 位 JVM 的最大堆內(nèi)存分別是多數(shù)本讥?

理論上說(shuō)上 32 位的 JVM 堆內(nèi)存可以到達(dá) 2^32珊泳,即 4GB,但實(shí)際上會(huì)比這個(gè)小很多拷沸。不同操作系統(tǒng)之間不同色查,如 Windows 系統(tǒng)大約 1.5 GB,Solaris 大約 3GB撞芍。64 位 JVM允許指定最大的堆內(nèi)存秧了,理論上可以達(dá)到 2^64,這是一個(gè)非常大的數(shù)字序无,實(shí)際上你可以指定堆內(nèi)存大小到 100GB示惊。甚至有的 JVM,如 Azul愉镰,堆內(nèi)存到 1000G 都是可能的米罚。

29.JRE、JDK丈探、JVM 及 JIT 之間有什么不同录择?

JRE 代表 Java 運(yùn)行時(shí)(Java run-time),是運(yùn)行 Java 引用所必須的碗降。JDK 代表 Java 開(kāi)發(fā)工具(Java development kit)隘竭,是 Java 程序的開(kāi)發(fā)工具,如 Java 編譯器讼渊,它也包含 JRE动看。JVM 代表 Java 虛擬機(jī)(Java virtual machine),它的責(zé)任是運(yùn)行 Java 應(yīng)用爪幻。JIT 代表即時(shí)編譯(Just In Time compilation)菱皆,當(dāng)代碼執(zhí)行的次數(shù)超過(guò)一定的閾值時(shí),會(huì)將 Java 字節(jié)碼轉(zhuǎn)換為本地代碼挨稿,如仇轻,主要的熱點(diǎn)代碼會(huì)被堆換為本地代碼,這樣有利大幅度提高 Java 應(yīng)用的性能奶甘。

30.解釋 Java 堆空間及 GC篷店?

當(dāng)通過(guò) Java 命令啟動(dòng) Java 進(jìn)程的時(shí)候,會(huì)為它分配內(nèi)存臭家。內(nèi)存的一部分用于創(chuàng)建堆空間疲陕,當(dāng)程序中創(chuàng)建對(duì)象的時(shí)候方淤,就從對(duì)空間中分配內(nèi)存。GC 是 JVM 內(nèi)部的一個(gè)進(jìn)程蹄殃,回收無(wú)效對(duì)象的內(nèi)存用于將來(lái)的分配携茂。

31.你能保證 GC 執(zhí)行嗎?

不能窃爷,雖然你可以調(diào)用 System.gc() 或者 Runtime.gc(),但是沒(méi)有辦法保證 GC 的執(zhí)行姓蜂。

32.怎么獲取 Java 程序使用的內(nèi)存按厘?堆使用的百分比?

可以通過(guò) java.lang.Runtime 類(lèi)中與內(nèi)存相關(guān)方法來(lái)獲取剩余的內(nèi)存钱慢,總內(nèi)存及最大堆內(nèi)存逮京。通過(guò)這些方法你也可以獲取到堆使用的百分比及堆內(nèi)存的剩余空間。

Runtime.freeMemory() 方法返回剩余空間的字節(jié)數(shù)束莫,Runtime.totalMemory() 方法總內(nèi)存的字節(jié)數(shù)懒棉,Runtime.maxMemory() 返回最大內(nèi)存的字節(jié)數(shù)。

33.Java 中堆和棧有什么區(qū)別览绿?(答案)

JVM 中堆和棧屬于不同的內(nèi)存區(qū)域策严,使用目的也不同。棧常用于保存方法幀和局部變量饿敲,而對(duì)象總是在堆上分配妻导。棧通常都比堆小,也不會(huì)在多個(gè)線程之間共享怀各,而堆被整個(gè) JVM 的所有線程共享倔韭。

34. “a==b”和”a.equals(b)”有什么區(qū)別?

如果 a 和 b 都是對(duì)象瓢对,則 a==b 是比較兩個(gè)對(duì)象的引用寿酌,只有當(dāng) a 和 b 指向的是堆中的同一個(gè)對(duì)象才會(huì)返回 true,而 a.equals(b) 是進(jìn)行邏輯比較硕蛹,所以通常需要重寫(xiě)該方法來(lái)提供邏輯一致性的比較醇疼。例如,String 類(lèi)重寫(xiě) equals() 方法法焰,所以可以用于兩個(gè)不同對(duì)象僵腺,但是包含的字母相同的比較。

35.a.hashCode() 有什么用壶栋?與 a.equals(b) 有什么關(guān)系辰如?

hashCode() 方法是相應(yīng)對(duì)象整型的 hash 值。它常用于基于 hash 的集合類(lèi)贵试,如 Hashtable琉兜、HashMap凯正、LinkedHashMap等等。它與 equals() 方法關(guān)系特別緊密豌蟋。根據(jù) Java 規(guī)范廊散,兩個(gè)使用 equal() 方法來(lái)判斷相等的對(duì)象,必須具有相同的 hash code梧疲。

36.final允睹、finalize 和 finally 的不同之處?

final 是一個(gè)修飾符幌氮,可以修飾變量缭受、方法和類(lèi)。如果 final 修飾變量该互,意味著該變量的值在初始化后不能被改變米者。finalize 方法是在對(duì)象被回收之前調(diào)用的方法,給對(duì)象自己最后一個(gè)復(fù)活的機(jī)會(huì)宇智,但是什么時(shí)候調(diào)用 finalize 沒(méi)有保證蔓搞。finally 是一個(gè)關(guān)鍵字,與 try 和 catch 一起用于異常的處理随橘。finally 塊一定會(huì)被執(zhí)行喂分,無(wú)論在 try 塊中是否有發(fā)生異常。

37.Java 中的編譯器常量是什么机蔗?使用它有什么風(fēng)險(xiǎn)妻顶?

公共靜態(tài)不可變(public static final )變量也就是我們所說(shuō)的編譯期常量,這里的 public 可選的蜒车。實(shí)際上這些變量在編譯時(shí)會(huì)被替換掉讳嘱,因?yàn)榫幾g器知道這些變量的值,并且知道這些變量在運(yùn)行時(shí)不能改變酿愧。這種方式存在的一個(gè)問(wèn)題是你使用了一個(gè)內(nèi)部的或第三方庫(kù)中的公有編譯時(shí)常量沥潭,但是這個(gè)值后面被其他人改變了,但是你的客戶端仍然在使用老的值嬉挡,甚至你已經(jīng)部署了一個(gè)新的jar钝鸽。為了避免這種情況,當(dāng)你在更新依賴(lài) JAR 文件時(shí)庞钢,確保重新編譯你的程序拔恰。

38.List缝裤、Set照宝、Map 和 Queue 之間的區(qū)別

List 是一個(gè)有序集合,允許元素重復(fù)避诽。它的某些實(shí)現(xiàn)可以提供基于下標(biāo)值的常量訪問(wèn)時(shí)間,但是這不是 List 接口保證的河爹。Set 是一個(gè)無(wú)序集合匠璧。

39.poll() 方法和 remove() 方法的區(qū)別?

poll() 和 remove() 都是從隊(duì)列中取出一個(gè)元素咸这,但是 poll() 在獲取元素失敗的時(shí)候會(huì)返回空夷恍,但是 remove() 失敗的時(shí)候會(huì)拋出異常。

40.Java 中 LinkedHashMap 和 PriorityQueue 的區(qū)別是什么媳维?

PriorityQueue 保證最高或者最低優(yōu)先級(jí)的的元素總是在隊(duì)列頭部酿雪,但是 LinkedHashMap 維持的順序是元素插入的順序。當(dāng)遍歷一個(gè) PriorityQueue 時(shí)侄刽,沒(méi)有任何順序保證指黎,但是 LinkedHashMap 可保證遍歷順序是元素插入的順序。

41.ArrayList 與 LinkedList 的不區(qū)別唠梨?

最明顯的區(qū)別是 ArrrayList 底層的數(shù)據(jù)結(jié)構(gòu)是數(shù)組袋励,支持隨機(jī)訪問(wèn)侥啤,而 LinkedList 的底層數(shù)據(jù)結(jié)構(gòu)書(shū)鏈表当叭,不支持隨機(jī)訪問(wèn)。使用下標(biāo)訪問(wèn)一個(gè)元素盖灸,ArrayList 的時(shí)間復(fù)雜度是 O(1)蚁鳖,而 LinkedList 是 O(n)。更多細(xì)節(jié)的討論參見(jiàn)答案赁炎。

42.用哪兩種方式來(lái)實(shí)現(xiàn)集合的排序醉箕?

你可以使用有序集合,如 TreeSet 或 TreeMap徙垫,你也可以使用有順序的的集合讥裤,如 list,然后通過(guò) Collections.sort() 來(lái)排序姻报。

43.Java 中怎么打印數(shù)組己英?(answe

你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法來(lái)打印數(shù)組。由于數(shù)組沒(méi)有實(shí)現(xiàn) toString() 方法吴旋,所以如果將數(shù)組傳遞給 System.out.println() 方法损肛,將無(wú)法打印出數(shù)組的內(nèi)容,但是 Arrays.toString() 可以打印每個(gè)元素荣瑟。

44.Java 中的 LinkedList 是單向鏈表還是雙向鏈表治拿?

是雙向鏈表,你可以檢查 JDK 的源碼笆焰。在 Eclipse劫谅,你可以使用快捷鍵 Ctrl + T,直接在編輯器中打開(kāi)該類(lèi)。

45.Java 中的 TreeMap 是采用什么樹(shù)實(shí)現(xiàn)的同波?

Java 中的 TreeMap 是使用紅黑樹(shù)實(shí)現(xiàn)的鳄梅。

46. Hashtable 與 HashMap 有什么不同之處?

這兩個(gè)類(lèi)有許多不同的地方未檩,下面列出了一部分:

a) Hashtable 是 JDK 1 遺留下來(lái)的類(lèi)戴尸,而 HashMap 是后來(lái)增加的。

b)Hashtable 是同步的冤狡,比較慢孙蒙,但 HashMap 沒(méi)有同步策略,所以會(huì)更快悲雳。

c)Hashtable 不允許有個(gè)空的 key挎峦,但是 HashMap 允許出現(xiàn)一個(gè) null key。

更多的不同之處參見(jiàn)答案合瓢。

47.Java 中的 HashSet坦胶,內(nèi)部是如何工作的?

HashSet 的內(nèi)部采用 HashMap來(lái)實(shí)現(xiàn)晴楔。由于 Map 需要 key 和 value顿苇,所以所有 key 的都有一個(gè)默認(rèn) value。類(lèi)似于 HashMap税弃,HashSet 不允許重復(fù)的 key纪岁,只允許有一個(gè)null key,意思就是 HashSet 中只允許存儲(chǔ)一個(gè) null 對(duì)象则果。

48.寫(xiě)一段代碼在遍歷 ArrayList 時(shí)移除一個(gè)元素幔翰?

該問(wèn)題的關(guān)鍵在于面試者使用的是 ArrayList 的 remove() 還是 Iterator 的 remove()方法。這有一段示例代碼西壮,是使用正確的方式來(lái)實(shí)現(xiàn)在遍歷的過(guò)程中移除元素遗增,而不會(huì)出現(xiàn) ConcurrentModificationException 異常的示例代碼。

49.我們能自己寫(xiě)一個(gè)容器類(lèi)款青,然后使用 for-each 循環(huán)碼做修?

可以,你可以寫(xiě)一個(gè)自己的容器類(lèi)可都。如果你想使用 Java 中增強(qiáng)的循環(huán)來(lái)遍歷缓待,你只需要實(shí)現(xiàn) Iterable 接口。如果你實(shí)現(xiàn) Collection 接口渠牲,默認(rèn)就具有該屬性旋炒。

50.ArrayList 和 HashMap 的默認(rèn)大小是多數(shù)?

在 Java 7 中签杈,ArrayList 的默認(rèn)大小是 10 個(gè)元素瘫镇,HashMap 的默認(rèn)大小是16個(gè)元素(必須是2個(gè)冪)鼎兽。這就是 Java 7 中 ArrayList 和 HashMap 類(lèi)的代碼片段:

//fromArrayList.javaJDK1.7privatestaticfinalintDEFAULT_CAPACITY=10;//fromHashMap.javaJDK7staticfinalintDEFAULT_INITIAL_CAPACITY=1<<4;//aka16

java面試資料點(diǎn)擊領(lǐng)取

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市铣除,隨后出現(xiàn)的幾起案子谚咬,更是在濱河造成了極大的恐慌,老刑警劉巖尚粘,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件择卦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡郎嫁,警方通過(guò)查閱死者的電腦和手機(jī)秉继,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)泽铛,“玉大人尚辑,你說(shuō)我怎么就攤上這事】唬” “怎么了杠茬?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)弛随。 經(jīng)常有香客問(wèn)我瓢喉,道長(zhǎng),這世上最難降的妖魔是什么撵幽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任灯荧,我火速辦了婚禮礁击,結(jié)果婚禮上盐杂,老公的妹妹穿的比我還像新娘。我一直安慰自己哆窿,他們只是感情好链烈,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著挚躯,像睡著了一般强衡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上码荔,一...
    開(kāi)封第一講書(shū)人閱讀 52,713評(píng)論 1 312
  • 那天漩勤,我揣著相機(jī)與錄音,去河邊找鬼缩搅。 笑死越败,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的究飞。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼亿傅!你這毒婦竟也來(lái)了媒峡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤葵擎,失蹤者是張志新(化名)和其女友劉穎谅阿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體酬滤,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奔穿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了敏晤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贱田。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嘴脾,靈堂內(nèi)的尸體忽然破棺而出男摧,到底是詐尸還是另有隱情,我是刑警寧澤译打,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布耗拓,位于F島的核電站,受9級(jí)特大地震影響奏司,放射性物質(zhì)發(fā)生泄漏乔询。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一韵洋、第九天 我趴在偏房一處隱蔽的房頂上張望竿刁。 院中可真熱鬧,春花似錦搪缨、人聲如沸食拜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)负甸。三九已至,卻和暖如春痹届,著一層夾襖步出監(jiān)牢的瞬間呻待,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工队腐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚕捉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓香到,卻偏偏與公主長(zhǎng)得像鱼冀,于是被迫代替她去往敵國(guó)和親报破。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容