java面試題全集
在Java的面試中,有哪些面試題目呢?你做好面試準(zhǔn)備了嗎?下面小編已經(jīng)為你們整理了java面試題全集,希望可以幫到你。
java面試題1
1)Java 中能創(chuàng)建 Volatile 數(shù)組嗎?
能,Java 中可以創(chuàng)建 volatile 類型數(shù)組,不過只是一個指向數(shù)組的引用,而不是整個數(shù)組。我的意思是,如果改變引用指向的數(shù)組,將會受到 volatile 的保護(hù),但是如果多個線程同時改變數(shù)組的元素,volatile 標(biāo)示符就不能起到之前的保護(hù)作用了。
2)volatile 能使得一個非原子操作變成原子操作嗎?
一個典型的例子是在類中有一個long 類型的成員變量。如果你知道該成員變量會被多個線程訪問,如計(jì)數(shù)器、價(jià)格等,你最好是將其設(shè)置為 volatile。為什么?因?yàn)?Java 中讀取 long 類型變量不是原子的,需要分成兩步,如果一個線程正在修改該 long 變量的值,另一個線程可能只能看到該值的一半(前 32 位)。但是對一個 volatile 型的 long 或 double 變量的讀寫是原子。
3)volatile 修飾符的有過什么實(shí)踐?
一種實(shí)踐是用 volatile 修飾 long 和 double 變量,使其能按原子類型來讀寫。double 和 long 都是64位寬,因此對這兩種類型的讀是分為兩部分的,第一次讀取第一個 32 位,然后再讀剩下的 32 位,這個過程不是原子的,但 Java 中 volatile 型的 long 或 double 變量的讀寫是原子的。volatile 修復(fù)符的另一個作用是提供內(nèi)存屏障(memory barrier),例如在分布式框架中的應(yīng)用。簡單的說,就是當(dāng)你寫一個 volatile 變量之前,Java 內(nèi)存模型會插入一個寫屏障(writebarrier),讀一個 volatile 變量之前,會插入一個讀屏障(read barrier)。意思就是說,在你寫一個 volatile 域時,能保證任何線程都能看到你寫的值,同時,在寫之前,也能保證任何數(shù)值的更新對所有線程是可見的,因?yàn)閮?nèi)存屏障會將其他所有寫的值更新到緩存。
4)volatile 類型變量提供什么保證?
volatile 變量提供順序和可見性保證,例如,JVM或者 JIT為了獲得更好的性能會對語句重排序,但是 volatile類型變量即使在沒有同步塊的情況下賦值也不會與其他語句重排序。 volatile 提供 happens-before 的保證,確保一個線程的修改能對其他線程是可見的。某些情況下,volatile 還能提供原子性,如讀 64 位數(shù)據(jù)類型,像 long 和 double 都不是原子的,但 volatile 類型的 double 和 long 就是原子的。
5) 10 個線程和 2 個線程的同步代碼,哪個更容易寫?
從寫代碼的角度來說,兩者的復(fù)雜度是相同的,因?yàn)橥酱a與線程數(shù)量是相互獨(dú)立的。但是同步策略的選擇依賴于線程的數(shù)量,因?yàn)樵蕉嗟木€程意味著更大的競爭,所以你需要利用同步技術(shù),如鎖分離,這要求更復(fù)雜的代碼和專業(yè)知識。
6)你是如何調(diào)用 wait()方法的?使用 if 塊還是循環(huán)?為什么?
wait() 方法應(yīng)該在循環(huán)調(diào)用,因?yàn)楫?dāng)線程獲取到CPU 開始執(zhí)行的時候,其他條件可能還沒有滿足,所以在處理前,循環(huán)檢測條件是否滿足會更好。下面是一段標(biāo)準(zhǔn)的使用 wait 和 notify 方法的代碼:
// The standard idiom for using the waitmethodsynchronized (obj) {while (condition does not hold)
obj.wait(); // (Releases lock, andreacquires on wakeup)... // Perform action appropriate to condition}
參見 EffectiveJava 第 69 條,獲取更多關(guān)于為什么應(yīng)該在循環(huán)中來調(diào)用 wait 方法的內(nèi)容。
java面試題2
1)哪個類包含 clone 方法?是 Cloneable 還是 Object?
java.lang.Cloneable 是一個標(biāo)示性接口,不包含任何方法,clone 方法在 object 類中定義。并且需要知道clone() 方法是一個本地方法,這意味著它是由 c 或 c++ 或 其他本地語言實(shí)現(xiàn)的。
2)Java 中 ++ 操作符是線程安全的嗎?
不是線程安全的操作。它涉及到多個指令,如讀取變量值,增加,然后存儲回內(nèi)存,這個過程可能會出現(xiàn)多個線程交差。
3)a = a + b 與 a += b 的區(qū)別
+= 隱式的將加操作的結(jié)果類型強(qiáng)制轉(zhuǎn)換為持有結(jié)果的類型。如果兩這個整型相加,如 byte、short 或者 int,首先會將它們提升到 int 類型,然后在執(zhí)行加法操作。如果加法操作的結(jié)果比 a 的最大值要大,則 a+b 會出現(xiàn)編譯錯誤,但是 a += b 沒問題,如下:
byte a = 127;
byte b = 127;
b = a + b; // error : cannot convert from int to byte
b += a; // ok
(譯者注:這個地方應(yīng)該表述的有誤,其實(shí)無論 a+b的值為多少,編譯器都會報(bào)錯,因?yàn)?a+b 操作會將 a、b提升為 int 類型,所以將 int 類型賦值給 byte 就會編譯出錯)
4)我能在不進(jìn)行強(qiáng)制轉(zhuǎn)換的情況下將一個 double 值賦值給 long 類型的變量嗎?
不行,你不能在沒有強(qiáng)制類型轉(zhuǎn)換的前提下將一個 double 值賦值給 long 類型的變量,因?yàn)?double 類型的范圍比 long 類型更廣,所以必須要進(jìn)行強(qiáng)制轉(zhuǎn)換。
5)為什么 Java 中的 String 是不可變的(Immutable)?
Java 中的 String 不可變是因?yàn)?Java 的設(shè)計(jì)者認(rèn)為字符串使用非常頻繁,將字符串設(shè)置為不可變可以允許多個客戶端之間共享相同的字符串。
java面試題3
1、Java集合框架是什么?說出一些集合框架的優(yōu)點(diǎn)?
答:每種編程語言中都有集合,最初的Java版本包含幾種集合類:Vector、Stack、HashTable和Array。隨著集合的廣泛使用,Java1.2提出了囊括所有集合接口、實(shí)現(xiàn)和算法的集合框架。在保證線程安全的情況下使用泛型和并發(fā)集合類,Java已經(jīng)經(jīng)歷了很久。它還包括在Java并發(fā)包中,阻塞接口以及它們的實(shí)現(xiàn)。集合框架的部分優(yōu)點(diǎn)如下:
(1)使用核心集合類降低開發(fā)成本,而非實(shí)現(xiàn)我們自己的集合類。
(2)隨著使用經(jīng)過嚴(yán)格測試的集合框架類,代碼質(zhì)量會得到提高。
(3)通過使用JDK附帶的集合類,可以降低代碼維護(hù)成本。
(4)復(fù)用性和可操作性。
2、集合框架中的泛型有什么優(yōu)點(diǎn)?
答:Java1.5引入了泛型,所有的集合接口和實(shí)現(xiàn)都大量地使用它。泛型允許我們?yōu)榧咸峁┮粋€可以容納的對象類型,因此,如果你添加其它類型的任何元素,它會在編譯時報(bào)錯。這避免了在運(yùn)行時出現(xiàn)ClassCastException,因?yàn)槟銓诰幾g時得到報(bào)錯信息。泛型也使得代碼整潔,我們不需要使用顯式轉(zhuǎn)換和instanceOf操作符。它也給運(yùn)行時帶來好處,因?yàn)椴粫a(chǎn)生類型檢查的字節(jié)碼指令。
3、Java集合框架的基礎(chǔ)接口有哪些?
答:Collection為集合層級的根接口。一個集合代表一組對象,這些對象即為它的元素。Java平臺不提供這個接口任何直接的實(shí)現(xiàn)。
Set是一個不能包含重復(fù)元素的集合。這個接口對數(shù)學(xué)集合抽象進(jìn)行建模,被用來代表集合,就如一副牌。
List是一個有序集合,可以包含重復(fù)元素。你可以通過它的索引來訪問任何元素。List更像長度動態(tài)變換的數(shù)組。
Map是一個將key映射到value的對象。一個Map不能包含重復(fù)的key:每個key最多只能映射一個value。
一些其它的接口有Queue、Dequeue、SortedSet、SortedMap和ListIterator。
看了“java面試題全集”