Java 面試題及答案

多線程莹菱、并發(fā)及線程的基礎(chǔ)問題

1)Java 中能創(chuàng)建 Volatile 數(shù)組嗎透绩?

能,Java 中可以創(chuàng)建 volatile 類型數(shù)組驱闷,不過只是一個(gè)指向數(shù)組的引用,而不是整個(gè)數(shù)組九秀。我的意思是,如果改變引用指向的數(shù)組粘我,將會(huì)受到 volatile 的保護(hù)鼓蜒,但是如果多個(gè)線程同時(shí)改變數(shù)組的元素,volatile 標(biāo)示符就不能起到之前的保護(hù)作用了征字。

2)volatile 能使得一個(gè)非原子操作變成原子操作嗎都弹?

一個(gè)典型的例子是在類中有一個(gè) long 類型的成員變量。如果你知道該成員變量會(huì)被多個(gè)線程訪問匙姜,如計(jì)數(shù)器畅厢、價(jià)格等,你最好是將其設(shè)置為 volatile氮昧。為什么框杜?因?yàn)?Java 中讀取 long 類型變量不是原子的,需要分成兩步袖肥,如果一個(gè)線程正在修改該 long 變量的值咪辱,另一個(gè)線程可能只能看到該值的一半(前 32 位)。但是對(duì)一個(gè) volatile 型的 long 或 double 變量的讀寫是原子椎组。

3)volatile 修飾符的有過什么實(shí)踐油狂?

一種實(shí)踐是用 volatile 修飾 long 和 double 變量,使其能按原子類型來讀寫寸癌。double 和 long 都是64位寬专筷,因此對(duì)這兩種類型的讀是分為兩部分的,第一次讀取第一個(gè) 32 位蒸苇,然后再讀剩下的 32 位磷蛹,這個(gè)過程不是原子的,但 Java 中 volatile 型的 long 或 double 變量的讀寫是原子的溪烤。volatile 修復(fù)符的另一個(gè)作用是提供內(nèi)存屏障(memory barrier)弦聂,例如在分布式框架中的應(yīng)用鸟辅。簡(jiǎn)單的說,就是當(dāng)你寫一個(gè) volatile 變量之前莺葫,Java 內(nèi)存模型會(huì)插入一個(gè)寫屏障(write barrier)匪凉,讀一個(gè) volatile 變量之前,會(huì)插入一個(gè)讀屏障(read barrier)捺檬。意思就是說再层,在你寫一個(gè) volatile 域時(shí),能保證任何線程都能看到你寫的值堡纬,同時(shí)聂受,在寫之前,也能保證任何數(shù)值的更新對(duì)所有線程是可見的烤镐,因?yàn)閮?nèi)存屏障會(huì)將其他所有寫的值更新到緩存蛋济。

4)volatile 類型變量提供什么保證?(答案)

volatile 變量提供順序和可見性保證炮叶,例如碗旅,JVM 或者 JIT為了獲得更好的性能會(huì)對(duì)語(yǔ)句重排序,但是 volatile 類型變量即使在沒有同步塊的情況下賦值也不會(huì)與其他語(yǔ)句重排序镜悉。 volatile 提供 happens-before 的保證祟辟,確保一個(gè)線程的修改能對(duì)其他線程是可見的。某些情況下侣肄,volatile 還能提供原子性旧困,如讀 64 位數(shù)據(jù)類型,像 long 和 double 都不是原子的稼锅,但 volatile 類型的 double 和 long 就是原子的吼具。

5) 10 個(gè)線程和 2 個(gè)線程的同步代碼,哪個(gè)更容易寫矩距?

從寫代碼的角度來說馍悟,兩者的復(fù)雜度是相同的,因?yàn)橥酱a與線程數(shù)量是相互獨(dú)立的剩晴。但是同步策略的選擇依賴于線程的數(shù)量锣咒,因?yàn)樵蕉嗟木€程意味著更大的競(jìng)爭(zhēng),所以你需要利用同步技術(shù)赞弥,如鎖分離毅整,這要求更復(fù)雜的代碼和專業(yè)知識(shí)。

8)什么是 Busy spin绽左?我們?yōu)槭裁匆褂盟?br>

Busy spin 是一種在不釋放 CPU 的基礎(chǔ)上等待事件的技術(shù)悼嫉。它經(jīng)常用于避免丟失 CPU 緩存中的數(shù)據(jù)(如果線程先暫停,之后在其他CPU上運(yùn)行就會(huì)丟失)拼窥。所以戏蔑,如果你的工作要求低延遲蹋凝,并且你的線程目前沒有任何順序,這樣你就可以通過循環(huán)檢測(cè)隊(duì)列中的新消息來代替調(diào)用 sleep() 或 wait() 方法总棵。它唯一的好處就是你只需等待很短的時(shí)間鳍寂,如幾微秒或幾納秒。LMAX 分布式框架是一個(gè)高性能線程間通信的庫(kù)情龄,該庫(kù)有一個(gè) BusySpinWaitStrategy 類就是基于這個(gè)概念實(shí)現(xiàn)的迄汛,使用 busy spin 循環(huán) EventProcessors 等待屏障。

9)Java 中怎么獲取一份線程 dump 文件骤视?

在 Linux 下鞍爱,你可以通過命令 kill -3 PID (Java 進(jìn)程的進(jìn)程 ID)來獲取 Java 應(yīng)用的 dump 文件。在 Windows 下专酗,你可以按下 Ctrl + Break 來獲取睹逃。這樣 JVM 就會(huì)將線程的 dump 文件打印到標(biāo)準(zhǔn)輸出或錯(cuò)誤文件中,它可能打印在控制臺(tái)或者日志文件中祷肯,具體位置依賴應(yīng)用的配置沉填。如果你使用Tomcat。

10)Swing 是線程安全的躬柬?(答案)

不是拜轨,Swing 不是線程安全的抽减。你不能通過任何線程來更新 Swing 組件允青,如 JTable、JList 或 JPanel卵沉,事實(shí)上颠锉,它們只能通過 GUI 或 AWT 線程來更新。這就是為什么 Swing 提供 invokeAndWait() 和 invokeLater() 方法來獲取其他線程的 GUI 更新請(qǐng)求史汗。這些方法將更新請(qǐng)求放入 AWT 的線程隊(duì)列中琼掠,可以一直等待,也可以通過異步更新直接返回結(jié)果停撞。你也可以在參考答案中查看和學(xué)習(xí)到更詳細(xì)的內(nèi)容瓷蛙。

11)什么是線程局部變量?(答案)

線程局部變量是局限于線程內(nèi)部的變量戈毒,屬于線程自身所有艰猬,不在多個(gè)線程間共享。Java 提供 ThreadLocal 類來支持線程局部變量埋市,是一種實(shí)現(xiàn)線程安全的方式冠桃。但是在管理環(huán)境下(如 web 服務(wù)器)使用線程局部變量的時(shí)候要特別小心,在這種情況下道宅,工作線程的生命周期比任何應(yīng)用變量的生命周期都要長(zhǎng)食听。任何線程局部變量一旦在工作完成后沒有釋放胸蛛,Java 應(yīng)用就存在內(nèi)存泄露的風(fēng)險(xiǎn)。

12)用 wait-notify 寫一段代碼來解決生產(chǎn)者-消費(fèi)者問題樱报?(答案)

請(qǐng)參考答案中的示例代碼葬项。只要記住在同步塊中調(diào)用 wait() 和 notify()方法,如果阻塞肃弟,通過循環(huán)來測(cè)試等待條件玷室。

13) 用 Java 寫一個(gè)線程安全的單例模式(Singleton)?(答案)

請(qǐng)參考答案中的示例代碼笤受,這里面一步一步教你創(chuàng)建一個(gè)線程安全的 Java 單例類穷缤。當(dāng)我們說線程安全時(shí),意思是即使初始化是在多線程環(huán)境中箩兽,仍然能保證單個(gè)實(shí)例津肛。Java 中,使用枚舉作為單例類是最簡(jiǎn)單的方式來創(chuàng)建線程安全單例模式的方式汗贫。

14)Java 中 sleep 方法和 wait 方法的區(qū)別身坐?(答案)

雖然兩者都是用來暫停當(dāng)前運(yùn)行的線程,但是 sleep() 實(shí)際上只是短暫停頓落包,因?yàn)樗粫?huì)釋放鎖部蛇,而 wait() 意味著條件等待,這就是為什么該方法要釋放鎖咐蝇,因?yàn)橹挥羞@樣涯鲁,其他等待的線程才能在滿足條件時(shí)獲取到該鎖。

15)什么是不可變對(duì)象(immutable object)有序?Java 中怎么創(chuàng)建一個(gè)不可變對(duì)象抹腿?(答案)

不可變對(duì)象指對(duì)象一旦被創(chuàng)建,狀態(tài)就不能再改變旭寿。任何修改都會(huì)創(chuàng)建一個(gè)新的對(duì)象警绩,如 String、Integer及其它包裝類盅称。詳情參見答案肩祥,一步一步指導(dǎo)你在 Java 中創(chuàng)建一個(gè)不可變的類。

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

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

數(shù)據(jù)類型和 Java 基礎(chǔ)面試問題

17)Java 中應(yīng)該使用什么數(shù)據(jù)類型來代表價(jià)格贸桶?(答案)

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

18)怎么將 byte 轉(zhuǎn)換為 String?(答案)

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

19)Java 中怎樣將 bytes 轉(zhuǎn)換為 long 類型?

這個(gè)問題你來回答 :-)

20)我們能將 int 強(qiáng)制轉(zhuǎn)換為 byte 類型的變量嗎拳魁?如果該值大于 byte 類型的范圍惶桐,將會(huì)出現(xiàn)什么現(xiàn)象?

是的潘懊,我們可以做強(qiáng)制轉(zhuǎn)換姚糊,但是 Java 中 int 是 32 位的,而 byte 是 8 位的授舟,所以救恨,如果強(qiáng)制轉(zhuǎn)化是,int 類型的高 24 位將會(huì)被丟棄释树,byte 類型的范圍是從 -128 到 128肠槽。

21)存在兩個(gè)類,B 繼承 A躏哩,C 繼承 B署浩,我們能將 B 轉(zhuǎn)換為 C 么揉燃?如 C = (C) B扫尺;(answer答案)

22)哪個(gè)類包含 clone 方法?是 Cloneable 還是 Object炊汤?(答案)

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

23)Java 中 ++ 操作符是線程安全的嗎迈倍?(答案)

23)不是線程安全的操作伤靠。它涉及到多個(gè)指令,如讀取變量值啼染,增加宴合,然后存儲(chǔ)回內(nèi)存焕梅,這個(gè)過程可能會(huì)出現(xiàn)多個(gè)線程交差。

24)a = a + b 與 a += b 的區(qū)別(答案)

+= 隱式的將加操作的結(jié)果類型強(qiáng)制轉(zhuǎn)換為持有結(jié)果的類型卦洽。如果兩這個(gè)整型相加贞言,如 byte、short 或者 int阀蒂,首先會(huì)將它們提升到 int 類型该窗,然后在執(zhí)行加法操作。如果加法操作的結(jié)果比 a 的最大值要大蚤霞,則 a+b 會(huì)出現(xiàn)編譯錯(cuò)誤酗失,但是 a += b 沒問題,如下:

byte a = 127;

byte b = 127;

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

b += a; // ok

(譯者注:這個(gè)地方應(yīng)該表述的有誤昧绣,其實(shí)無論 a+b 的值為多少级零,編譯器都會(huì)報(bào)錯(cuò),因?yàn)?a+b 操作會(huì)將 a滞乙、b 提升為 int 類型奏纪,所以將 int 類型賦值給 byte 就會(huì)編譯出錯(cuò))

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

不行斩启,你不能在沒有強(qiáng)制類型轉(zhuǎn)換的前提下將一個(gè) double 值賦值給 long 類型的變量序调,因?yàn)?double 類型的范圍比 long 類型更廣,所以必須要進(jìn)行強(qiáng)制轉(zhuǎn)換兔簇。

26)3*0.1 == 0.3 將會(huì)返回什么发绢?true 還是 false?(答案)

false垄琐,因?yàn)橛行└↑c(diǎn)數(shù)不能完全精確的表示出來边酒。

27)int 和 Integer 哪個(gè)會(huì)占用更多的內(nèi)存?(答案)

Integer 對(duì)象會(huì)占用更多的內(nèi)存狸窘。Integer 是一個(gè)對(duì)象墩朦,需要存儲(chǔ)對(duì)象的元數(shù)據(jù)。但是 int 是一個(gè)原始類型的數(shù)據(jù)翻擒,所以占用的空間更少氓涣。

28)為什么 Java 中的 String 是不可變的(Immutable)?(answer答案)

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

29)我們能在 Switch 中使用 String 嗎巩趁?(answer答案)

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

30)Java 中的構(gòu)造器鏈?zhǔn)鞘裁矗?answer答案)

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

JVM 底層 與 GC(Garbage Collection) 的面試問題

31)64 位 JVM 中缆毁,int 的長(zhǎng)度是多數(shù)?

Java 中到涂,int 類型變量的長(zhǎng)度是一個(gè)固定值脊框,與平臺(tái)無關(guān),都是 32 位践啄。意思就是說浇雹,在 32 位 和 64 位 的Java 虛擬機(jī)中,int 類型的長(zhǎng)度是相同的屿讽。

32)Serial 與 Parallel GC之間的不同之處昭灵?(答案)

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

33)32 位和 64 位的 JVM诵棵,int 類型變量的長(zhǎng)度是多數(shù)抠蚣?(答案)

32 位和 64 位的 JVM 中,int 類型變量的長(zhǎng)度是相同的履澳,都是 32 位或者 4 個(gè)字節(jié)嘶窄。

34)Java 中 WeakReference 與 SoftReference的區(qū)別?(答案)

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

35)WeakHashMap 是怎么工作的什湘?(答案)

WeakHashMap 的工作與正常的 HashMap 類似长赞,但是使用弱引用作為 key晦攒,意思就是當(dāng) key 對(duì)象沒有任何引用時(shí)闽撤,key/value 將會(huì)被回收。

36)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ī)在于可以指定最大堆大小近上,通過壓縮 OOP 可以節(jié)省一定的內(nèi)存。通過 -XX:+UseCompressedOops 選項(xiàng)拂铡,JVM 會(huì)使用 32 位的 OOP壹无,而不是 64 位的 OOP。

37)怎樣通過 Java 程序來判斷 JVM 是 32 位 還是 64 位感帅?(答案)

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

38)32 位 JVM 和 64 位 JVM 的最大堆內(nèi)存分別是多數(shù)?(答案)

理論上說上 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 都是可能的跃巡。

39)JRE危号、JDK、JVM 及 JIT 之間有什么不同素邪?(答案)

JRE 代表 Java 運(yùn)行時(shí)(Java run-time)外莲,是運(yùn)行 Java 引用所必須的。JDK 代表 Java 開發(fā)工具(Java development kit)兔朦,是 Java 程序的開發(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ù)超過一定的閾值時(shí)亥曹,會(huì)將 Java 字節(jié)碼轉(zhuǎn)換為本地代碼邓了,如,主要的熱點(diǎn)代碼會(huì)被準(zhǔn)換為本地代碼媳瞪,這樣有利大幅度提高 Java 應(yīng)用的性能骗炉。

最近5年133個(gè)Java面試問題列表

3 年工作經(jīng)驗(yàn)的 Java 面試題

40)解釋 Java 堆空間及 GC?(答案)

當(dāng)通過 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)程,回收無效對(duì)象的內(nèi)存用于將來的分配旨别。

最近5年133個(gè)Java面試問題列表

JVM 底層面試題及答案

41)你能保證 GC 執(zhí)行嗎诗赌?(答案)

不能,雖然你可以調(diào)用 System.gc() 或者 Runtime.gc()秸弛,但是沒有辦法保證 GC 的執(zhí)行铭若。

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

可以通過 java.lang.Runtime 類中與內(nèi)存相關(guān)方法來獲取剩余的內(nèi)存,總內(nèi)存及最大堆內(nèi)存弹澎。通過這些方法你也可以獲取到堆使用的百分比及堆內(nèi)存的剩余空間。Runtime.freeMemory() 方法返回剩余空間的字節(jié)數(shù)镜雨,Runtime.totalMemory() 方法總內(nèi)存的字節(jié)數(shù),Runtime.maxMemory() 返回最大內(nèi)存的字節(jié)數(shù)儿捧。

43)Java 中堆和棧有什么區(qū)別荚坞?(答案)

JVM 中堆和棧屬于不同的內(nèi)存區(qū)域,使用目的也不同菲盾。棧常用于保存方法幀和局部變量颓影,而對(duì)象總是在堆上分配。棧通常都比堆小懒鉴,也不會(huì)在多個(gè)線程之間共享诡挂,而堆被整個(gè) JVM 的所有線程共享。

最近5年133個(gè)Java面試問題列表

關(guān)于內(nèi)存的的面試問題和答案

Java 基本概念面試題

44)“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)行邏輯比較城豁,所以通常需要重寫該方法來提供邏輯一致性的比較。例如麦牺,String 類重寫 equals() 方法钮蛛,所以可以用于兩個(gè)不同對(duì)象鞭缭,但是包含的字母相同的比較剖膳。

45)a.hashCode() 有什么用魏颓?與 a.equals(b) 有什么關(guān)系?(答案)

hashCode() 方法是相應(yīng)對(duì)象整型的 hash 值吱晒。它常用于基于 hash 的集合類甸饱,如 Hashtable、HashMap仑濒、LinkedHashMap等等叹话。它與 equals() 方法關(guān)系特別緊密。根據(jù) Java 規(guī)范墩瞳,兩個(gè)使用 equal() 方法來判斷相等的對(duì)象驼壶,必須具有相同的 hash code。

46)final喉酌、finalize 和 finally 的不同之處热凹?(答案)

final 是一個(gè)修飾符,可以修飾變量泪电、方法和類般妙。如果 final 修飾變量,意味著該變量的值在初始化后不能被改變相速。finalize 方法是在對(duì)象被回收之前調(diào)用的方法碟渺,給對(duì)象自己最后一個(gè)復(fù)活的機(jī)會(huì),但是什么時(shí)候調(diào)用 finalize 沒有保證突诬。finally 是一個(gè)關(guān)鍵字苫拍,與 try 和 catch 一起用于異常的處理。finally 塊一定會(huì)被執(zhí)行旺隙,無論在 try 塊中是否有發(fā)生異常怯疤。

47)Java 中的編譯期常量是什么?使用它又什么風(fēng)險(xiǎn)催束?

公共靜態(tài)不可變(public static final )變量也就是我們所說的編譯期常量集峦,這里的 public 可選的。實(shí)際上這些變量在編譯時(shí)會(huì)被替換掉抠刺,因?yàn)榫幾g器知道這些變量的值塔淤,并且知道這些變量在運(yùn)行時(shí)不能改變。這種方式存在的一個(gè)問題是你使用了一個(gè)內(nèi)部的或第三方庫(kù)中的公有編譯時(shí)常量速妖,但是這個(gè)值后面被其他人改變了高蜂,但是你的客戶端仍然在使用老的值,甚至你已經(jīng)部署了一個(gè)新的jar罕容。為了避免這種情況备恤,當(dāng)你在更新依賴 JAR 文件時(shí)稿饰,確保重新編譯你的程序。

Java 集合框架的面試題

這部分也包含數(shù)據(jù)結(jié)構(gòu)露泊、算法及數(shù)組的面試問題

48) List喉镰、Set、Map 和 Queue 之間的區(qū)別(答案)

List 是一個(gè)有序集合惭笑,允許元素重復(fù)侣姆。它的某些實(shí)現(xiàn)可以提供基于下標(biāo)值的常量訪問時(shí)間,但是這不是 List 接口保證的沉噩。Set 是一個(gè)無序集合捺宗。

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

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

50)Java 中 LinkedHashMap 和 PriorityQueue 的區(qū)別是什么畜眨?(答案)

PriorityQueue 保證最高或者最低優(yōu)先級(jí)的的元素總是在隊(duì)列頭部昼牛,但是 LinkedHashMap 維持的順序是元素插入的順序。當(dāng)遍歷一個(gè) PriorityQueue 時(shí)胶果,沒有任何順序保證匾嘱,但是 LinkedHashMap 課保證遍歷順序是元素插入的順序。

51)ArrayList 與 LinkedList 的不區(qū)別早抠?(答案)

最明顯的區(qū)別是 ArrrayList 底層的數(shù)據(jù)結(jié)構(gòu)是數(shù)組霎烙,支持隨機(jī)訪問,而 LinkedList 的底層數(shù)據(jù)結(jié)構(gòu)書鏈表蕊连,不支持隨機(jī)訪問悬垃。使用下標(biāo)訪問一個(gè)元素,ArrayList 的時(shí)間復(fù)雜度是 O(1)甘苍,而 LinkedList 是 O(n)尝蠕。更多細(xì)節(jié)的討論參見答案。

52)用哪兩種方式來實(shí)現(xiàn)集合的排序载庭?(答案)

你可以使用有序集合看彼,如 TreeSet 或 TreeMap,你也可以使用有順序的的集合囚聚,如 list靖榕,然后通過 Collections.sort() 來排序。

53)Java 中怎么打印數(shù)組顽铸?(answer答案)

你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法來打印數(shù)組茁计。由于數(shù)組沒有實(shí)現(xiàn) toString() 方法,所以如果將數(shù)組傳遞給 System.out.println() 方法谓松,將無法打印出數(shù)組的內(nèi)容星压,但是 Arrays.toString() 可以打印每個(gè)元素践剂。

54)Java 中的 LinkedList 是單向鏈表還是雙向鏈表?(答案)

是雙向鏈表娜膘,你可以檢查 JDK 的源碼逊脯。在 Eclipse,你可以使用快捷鍵 Ctrl + T劲绪,直接在編輯器中打開該類男窟。

55)Java 中的 TreeMap 是采用什么樹實(shí)現(xiàn)的盆赤?(答案)

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

56) Hashtable 與 HashMap 有什么不同之處?(答案)

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

a) Hashtable 是 JDK 1 遺留下來的類颤枪,而 HashMap 是后來增加的。

b)Hashtable 是同步的淑际,比較慢畏纲,但 HashMap 沒有同步策略,所以會(huì)更快春缕。

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

更多的不同之處參見答案锄贼。

57)Java 中的 HashSet票灰,內(nèi)部是如何工作的?(answer答案)

HashSet 的內(nèi)部采用 HashMap來實(shí)現(xiàn)宅荤。由于 Map 需要 key 和 value屑迂,所以所有 key 的都有一個(gè)默認(rèn) value。類似于 HashMap冯键,HashSet 不允許重復(fù)的 key惹盼,只允許有一個(gè)null key,意思就是 HashSet 中只允許存儲(chǔ)一個(gè) null 對(duì)象惫确。

58)寫一段代碼在遍歷 ArrayList 時(shí)移除一個(gè)元素手报?(答案)

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

59)我們能自己寫一個(gè)容器類所袁,然后使用 for-each 循環(huán)碼盏档?

可以,你可以寫一個(gè)自己的容器類燥爷。如果你想使用 Java 中增強(qiáng)的循環(huán)來遍歷蜈亩,你只需要實(shí)現(xiàn) Iterable 接口懦窘。如果你實(shí)現(xiàn) Collection 接口,默認(rèn)就具有該屬性稚配。

60)ArrayList 和 HashMap 的默認(rèn)大小是多數(shù)畅涂?(答案)

在 Java 7 中,ArrayList 的默認(rèn)大小是 10 個(gè)元素道川,HashMap 的默認(rèn)大小是16個(gè)元素(必須是2的冪)午衰。這就是 Java 7 中 ArrayList 和 HashMap 類的代碼片段:

// from ArrayList.java JDK 1.7

private static final int DEFAULT_CAPACITY = 10;

//from HashMap.java JDK 7

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

61)有沒有可能兩個(gè)不相等的對(duì)象有有相同的 hashcode?

有可能冒萄,兩個(gè)不相等的對(duì)象可能會(huì)有相同的 hashcode 值臊岸,這就是為什么在 hashmap 中會(huì)有沖突。相等 hashcode 值的規(guī)定只是說如果兩個(gè)對(duì)象相等尊流,必須有相同的hashcode 值帅戒,但是沒有關(guān)于不相等對(duì)象的任何規(guī)定。

62)兩個(gè)相同的對(duì)象會(huì)有不同的的 hash code 嗎崖技?

不能逻住,根據(jù) hash code 的規(guī)定,這是不可能的迎献。

63)我們可以在 hashcode() 中使用隨機(jī)數(shù)字嗎瞎访?(答案)

不行,因?yàn)閷?duì)象的 hashcode 值必須是相同的吁恍。參見答案獲取更多關(guān)于 Java 中重寫 hashCode() 方法的知識(shí)扒秸。

64)Java 中,Comparator 與 Comparable 有什么不同践盼?(答案)

Comparable 接口用于定義對(duì)象的自然順序鸦采,而 comparator 通常用于定義用戶定制的順序。Comparable 總是只有一個(gè)咕幻,但是可以有多個(gè) comparator 來定義對(duì)象的順序渔伯。

65)為什么在重寫 equals 方法的時(shí)候需要重寫 hashCode 方法?(答案)

因?yàn)橛袕?qiáng)制的規(guī)范指定需要同時(shí)重寫 hashcode 與 equal 是方法肄程,許多容器類锣吼,如 HashMap、HashSet 都依賴于 hashcode 與 equals 的規(guī)定蓝厌。

歡迎來大家學(xué)習(xí)玄叠、討論java等問題 左邊620 中間3036 右邊046【一個(gè)java的修養(yǎng)】

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拓提,隨后出現(xiàn)的幾起案子读恃,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寺惫,死亡現(xiàn)場(chǎng)離奇詭異疹吃,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)西雀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門萨驶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人艇肴,你說我怎么就攤上這事腔呜。” “怎么了再悼?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵核畴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我帮哈,道長(zhǎng)膛檀,這世上最難降的妖魔是什么锰镀? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任娘侍,我火速辦了婚禮,結(jié)果婚禮上泳炉,老公的妹妹穿的比我還像新娘憾筏。我一直安慰自己,他們只是感情好花鹅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布氧腰。 她就那樣靜靜地躺著,像睡著了一般刨肃。 火紅的嫁衣襯著肌膚如雪古拴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天真友,我揣著相機(jī)與錄音黄痪,去河邊找鬼。 笑死盔然,一個(gè)胖子當(dāng)著我的面吹牛桅打,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播愈案,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼挺尾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了站绪?” 一聲冷哼從身側(cè)響起遭铺,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后魂挂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體航厚,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年锰蓬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了幔睬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芹扭,死狀恐怖麻顶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舱卡,我是刑警寧澤辅肾,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站轮锥,受9級(jí)特大地震影響矫钓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舍杜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一新娜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧既绩,春花似錦概龄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至救欧,卻和暖如春衰粹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笆怠。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工铝耻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骑疆。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓田篇,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親箍铭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泊柬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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

  • 阿里java相關(guān)問題,都是之前通過不斷優(yōu)秀人才的鋪墊總結(jié)的诈火,希望對(duì)大家?guī)椭蘖蓿C嬖嚦晒Γ袀€(gè)更好的職業(yè)規(guī)劃。 1刀崖、...
    Java架構(gòu)師Carl閱讀 2,849評(píng)論 1 94
  • 從三月份找實(shí)習(xí)到現(xiàn)在惊科,面了一些公司,掛了不少亮钦,但最終還是拿到小米馆截、百度、阿里蜂莉、京東蜡娶、新浪、CVTE映穗、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,246評(píng)論 11 349
  • 轉(zhuǎn)自 www.reibang.com/p/bd1bfc0c34b8 作為一個(gè)程序員,在找工作的過程中,都會(huì)遇到筆試...
    灬黑客灬閱讀 4,420評(píng)論 1 118
  • 所有知識(shí)點(diǎn)已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)窖张? 在 Jav...
    侯蛋蛋_閱讀 2,433評(píng)論 1 4
  • 始于外貌!終于人品
    霍啟示閱讀 157評(píng)論 0 0