java面試--java基礎三
1. 談談物件的訪問定位
物件建立起來之後,就會在虛擬機器棧中維護一個本地變量表,用於儲存基礎型別和基礎型別的值,引用型別與引用型別的值。
其中引用型別的值就是堆中物件地址。如何引用堆中地址有兩種方式:
- 控制代碼:在堆中維護一個控制代碼池,控制代碼中包含了物件地址,當物件改變的時候,只需改變控制代碼,不需要改變棧中本地變量表的引用
- 直接指標:物件的地址直接儲存在棧中,這樣做的好處就是訪問速度變快(Hotspot採用該方式)
2. JVM將記憶體主要劃分為哪五部分
方法區、虛擬機器棧、本地方法棧、堆、程式計數器。
3. String的intern()函式作用
這個要分版本來回答:
- 如果是JDK6,如果字串產量池先前已經建立該物件,則返回引用;否則將其新增到字串常量池並返回引用。
- 如果是JDK6+,若字串常量池有則返回引用,如果池中沒有堆中有,則將堆中的引用新增到池中(注意是引用),然後返回引用;若池中也沒有,則在池中建立並返回引用。
4. 本地方法棧和虛擬機器棧區別
本地方法棧與虛擬機器棧所發揮的作用很相似,他們的區別在於虛擬機器棧為執行Java程式碼方法服務,而本地方法棧是為Native方法服務。
5. 分配堆記憶體指令
-Xms -Xmx
前者是堆的初始值,後者是堆能達到的最大值。
6. 程式計數器作用
記錄當前執行緒鎖執行的位元組碼的行號。
- 程式計數器是一塊較小的記憶體空間。
- 處於執行緒獨佔區。
- 執行java方法時,它記錄正在執行的虛擬機器位元組碼指令地址。執行native方法,它的值為undefined
- 該區域是唯一一個沒有規定任何OutOfMemoryError的區域
7. 如何將字串反轉?
- 通過 charAt(int index)返回char值進行字串拼接
- 呼叫StringBuffer中的reverse方法
8. Collection 和 Collections 有什麼區別?
-
Collection 是一個集合介面。它提供了對集合物件進行基本操作的通用介面方法。Collection介面在Java 類庫中有很多具體的實現。Collection介面的意義是為各種具體的集合提供了最大化的統一操作方式。
-
Collections 是一個包裝類。它包含有各種有關集合操作的靜態多型方法。此類不能例項化,就像一個工具類,服務於Java的Collection框架。
9. 在 Queue 中 poll()和 remove()有什麼區別?
- queue的增加元素方法add和offer的區別在於,add方法在佇列滿的情況下將選擇拋異常的方法來表示佇列已經滿了,而offer方法通過返回false表示佇列已經滿了;在有限佇列的情況,使用offer方法優於add方法;
- remove方法和poll方法都是刪除佇列的頭元素,remove方法在佇列為空的情況下將拋異常,而poll方法將返回null;
- element和peek方法都是返回佇列的頭元素,但是不刪除頭元素,區別在與element方法在佇列為空的情況下,將拋異常,而peek方法將返回null.
10. 什麼是迭代器
Iterator介面提供了很多對集合元素進行迭代的方法。每一個集合類都包括了可以返回迭代器例項的迭代方法。迭代器可以在迭代過程中刪除底層集合的元素,但是不可以直接呼叫集合的remove(Object obj)刪除,可以通過迭代器的remove()方法刪除
11. 迭代器的優點
如果用的是for迴圈,就用集合自帶的remove(),而這樣就改變了集合的Size()迴圈的時候會出錯。但如果把集合放入迭代器,既iterator迭代可以遍歷並選擇集合中的每個物件而不改變集合的結構,而把集合放入迭代器,用迭代器的remove()就不會出現問題
12. Java集合類中的Iterator和ListIterator的區別
對List來說,你也可以通過listIterator()取得其迭代器,兩種迭代器在有些時候是不能通用的,Iterator和ListIterator主要區別在以下方面:
-
iterator()方法在set和list介面中都有定義,但是ListIterator()僅存在於list介面中(或實現類中);
-
ListIterator有add()方法,可以向List中新增物件,而Iterator不能
-
ListIterator和Iterator都有hasNext()和next()方法,可以實現順序向後遍歷,但是ListIterator有hasPrevious()和previous()方法,可以實現逆向(順序向前)遍歷。Iterator就不可以。
-
ListIterator可以定位當前的索引位置,nextIndex()和previousIndex()可以實現。Iterator沒有此功能。
-
都可實現刪除物件,但是ListIterator可以實現物件的修改,set()方法可以實現。Iierator僅能遍歷,不能修改。
13. 怎麼確保一個集合不能被修改?
- Java中提供final關鍵字,對基本型別進行修飾,當第一次初始化後,該變數就不可被修改
Collections
工具類中的UnmodifiableList
(不可修改的List、Map、Set等)
14. 並行和併發區別
併發的關鍵是你有處理多個任務的能力,不一定要同時。
15. 說一下你對Daemon執行緒(守護執行緒)的理解?它有什麼意義?一般應用於什麼樣的場景?
所謂守護執行緒是指在程式執行的時候在後臺提供一種通用服務的執行緒,比如垃圾回收執行緒就是一個很稱職的守護者,並且這種執行緒並不屬於程式中不可或缺的部分。因 此,當所有的非守護執行緒結束時,程式也就終止了,同時會殺死程序中的所有守護執行緒。反過來說,只要任何非守護執行緒還在執行,程式就不會終止。
守護執行緒和使用者執行緒的沒啥本質的區別:唯一的不同之處就在於虛擬機器的離開:如果使用者執行緒已經全部退出執行了,只剩下守護執行緒存在了,虛擬機器也就退出了。 因為沒有了被守護者,守護執行緒也就沒有工作可做了,也就沒有繼續執行程式的必要了。
16. sleep() 和 wait() 有什麼區別?
-
對於sleep()方法,我們首先要知道該方法是屬於Thread類中的。而wait()方法,則是屬於Object類中的。sleep()方法導致了程式暫停執行指定的時間,讓出cpu該其他執行緒,但是他的監控狀態依然保持者,當指定的時間到了又會自動恢復執行狀態。在呼叫sleep()方法的過程中,執行緒不會釋放物件鎖。
-
而當呼叫wait()方法的時候,執行緒會放棄物件鎖,進入等待此物件的等待鎖定池,只有針對此物件呼叫notify()方法後本執行緒才進入物件鎖定池準備獲取物件鎖進入執行狀態。
17. notify 和 notifyAll 區別
notify 僅僅通知一個執行緒,並且我們不知道哪個執行緒會收到通知,然而 notifyAll 會通知所有等待中的執行緒。換言之,如果只有一個執行緒在等待一個訊號燈,notify和notifyAll都會通知到這個執行緒。但如果多個執行緒在等待這個訊號燈,那麼notify只會通知到其中一個,而其它執行緒並不會收到任何通知,而notifyAll會喚醒所有等待中的執行緒。
18. 執行緒中start()和run()的區別
-
每個執行緒都有要執行的任務。執行緒的任務處理邏輯可以在Tread類的run例項方法中直接實現或通過該方法進行呼叫,因此run()相當於執行緒的任務處理邏輯的入口方法,它由Java虛擬機器在執行相應執行緒時直接呼叫,而不是由應用程式碼進行呼叫。
-
而start()的作用是啟動相應的執行緒。啟動一個執行緒實際是請求Java虛擬機器執行相應的執行緒,而這個執行緒何時能夠執行是由執行緒排程器決定的。start()呼叫結束並不表示相應執行緒已經開始執行,這個執行緒可能稍後執行,也可能永遠也不會執行。
19. 執行緒池的五種狀態
執行緒池的5種狀態:Running、ShutDown、Stop、Tidying、Terminated。
20. 執行緒池中 submit()和 execute()方法有什麼區別?
-
execute(Runnable x) 沒有返回值。可以執行任務,但無法判斷任務是否成功完成。——實現Runnable介面
-
submit(Runnable x) 返回一個future。可以用這個future來判斷任務是否成功完成。——實現Callable介面