本文回答了 你應該知道的JAVA面試題 基礎篇。
http://ifeve.com/java-interview-question/
Java線程的狀態
答: 線程間的狀態轉換:
(1). 新建(new):新創建了一個線程對象。
(2). 可運行(runnable):線程對象創建后,其他線程(比如main線程)調用了該對象的start()方法。該狀態的線程位于可運行線程池中,等待被線程調度選中,獲取cpu 的使用權 。
(3). 運行(running):可運行狀態(runnable)的線程獲得了cpu 時間片(timeslice) ,執行程序代碼。
(4). 阻塞(block):阻塞狀態是指線程因為某種原因放棄了cpu 使用權,也即讓出了cpu timeslice,暫時停止運行。直到線程進入可運行(runnable)狀態,才有機會再次獲得cpu timeslice 轉到運行(running)狀態。
阻塞的情況分三種:
(一). 等待阻塞:運行(running)的線程執行o.wait()方法,JVM會把該線程放入等待隊列(waitting queue)中。
(二). 同步阻塞:運行(running)的線程在獲取對象的同步鎖時,若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池(lock pool)中。
(三). 其他阻塞:運行(running)的線程執行Thread.sleep(long ms)或t.join()方法,或者發出了I/O請求時,JVM會把該線程置為阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入可運行(runnable)狀態。
(5). 死亡(dead):線程run()、main() 方法執行結束,或者因異常退出了run()方法,則該線程結束生命周期。死亡的線程不可再次復生。進程和線程的區別,進程間如何通訊,線程間如何通訊
答: 進程與線程區別
定義方面:進程是程序在某個數據集合上的一次運行活動;線程是進程中的一個執行路徑。
角色方面:在支持線程機制的系統中,進程是系統資源分配的單位,線程是CPU調度的單位。
資源共享方面:進程之間不能共享資源,而線程共享所在進程的地址空間和其它資源。同時線程還有自己的棧和棧指針,程序計數器等寄存器。
獨立性方面:進程有自己獨立的地址空間,而線程沒有,線程必須依賴于進程而存在。
開銷方面。進程切換的開銷較大。線程相對較小。(前面也提到過,引入線程也出于了開銷的考慮。)
(一)、進程間的通信方式
管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關系的進程間使用。進程的親緣關系通常是指父子進程關系。
有名管道 (namedpipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間的通信。
信號量(semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。
消息隊列( messagequeue ) : 消息隊列是由消息的鏈表,存放在內核中并由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩沖區大小受限等缺點。
信號 (sinal ) : 信號是一種比較復雜的通信方式,用于通知接收進程某個事件已經發生。
共享內存(shared memory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
套接字(socket ) : 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用于不同及其間的進程通信。
(二)、線程間的通信方式
鎖機制:包括互斥鎖、條件變量、讀寫鎖
互斥鎖提供了以排他方式防止數據結構被并發修改的方法。讀寫鎖允許多個線程同時讀共享數據,而對寫操作是互斥的。條件變量可以以原子的方式阻塞進程,直到某個特定條件為真為止。對條件的測試是在互斥鎖的保護下進行的。條件變量始終與互斥鎖一起使用。
信號量機制(Semaphore):包括無名線程信號量和命名線程信號量
信號機制(Signal):類似進程間的信號處理
線程間的通信目的主要是用于線程同步,所以線程沒有像進程通信中的用于數據交換的通信機制。
3.HashMap的數據結構是什么?如何實現的。和HashTable,ConcurrentHashMap的區別
答:數組+鏈表+紅黑樹。具體可以參見以下文章。
http://www.lxweimin.com/p/c0642afe03e0
4.Cookie和Session的區別
答: 簡單說就是HTTP協議是無狀態的,服務器端需要session來跟蹤用戶的狀態。
Session是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據可以保存在集群、數據庫、文件中;Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現Session的一種方式。
http://www.lxweimin.com/p/a2fe1d6441a7
- 索引有什么用?如何建索引?
答: http://blog.csdn.net/evankaka/article/details/46685649
6.ArrayList是如何實現的,ArrayList和LinkedList的區別?ArrayList如何實現擴容。
答: ArrayList 的本質就是數組, ArrayList就是對數組進行動態的擴展,其add, get , remove 等等操作就是對數組的操作。每次擴容到原來大小的1.5倍。
7.equals方法實現
答:當equals重載時,這里有4個會引發equals行為不一致的常見陷阱:
定義了錯誤的equals方法簽名(signature) Defining equals with the wrong signature.
重載了equals的但沒有同時重載hashCode的方法。 Changing equals without also changing hashCode.
建立在會變化字域上的equals定義。 Defining equals in terms of mutable fields.
不滿足等價關系的equals錯誤定義 Failing to define equals as an equivalence relation.
酷殼有篇文章專門講解equals方法。https://coolshell.cn/articles/1051.html
8.面向對象
答:這個題目很寬泛,可以談談封裝,繼承,多態,SOLID原則。Java需要了解接口和抽象類的區別。
9.線程狀態,BLOCKED和WAITING有什么區別
答:
假設t1,t2先后兩個線程,都執行如下代碼:
synchronized(Obj) {
Obj.wait();
}
t1先進,最后在Obj.wait()下卡住,這時java管t1的狀態waitting狀態
t2后進,直接在第一行就卡住了,這時java叫t2為blocked狀態。
判斷是否是BLOCKED可以看該線程是否在等待獲取鎖,WAITING從官方文檔中可以知道調用Object.wait(), Thread.join(), LockSupport.park()會使得線程進入該狀態。
10.JVM如何加載字節碼文件
答:JVM的功能可以歸納為:
加載:通過類加載器加載類文件的過程。
鏈接:鏈接類文件,提交給JVM在運行時執行。
初始化:分配內存和調用類初始化方法設置變量值。
你可能還需要了解JVM的架構圖,方法區,堆空間,棧空間,Native Memory.
http://www.lxweimin.com/p/f4f580289091
- JVM GC,GC算法。
答:這個網上資料很多,主要了解CMS的 Eden、Survivor 和 Tenured/Old 空間。
G1算法的優點,和CMS垃圾收集的區別。
12.什么情況會出現Full GC,什么情況會出現young GC。
答: young GC清理Eden區的內存。FullGC 清理所有內存。Major GC 清理老年代。
Initial Mark 和 Remark會stop the world.
需要注意的是G1 GC正常情況是避免Full GC的,如果G1算法出現了Full GC,意味著系統出現了問題,要進行調優。
G1 GC正常情況下只有young GC 和 mixed GC(Eden和Old區同時GC)。
13.JVM內存模型
答:
http://ifeve.com/java-memory-model-6/
如果能夠看懂這篇文章,對內存使用和理解會更上一層樓。https://www.ibm.com/developerworks/cn/java/j-nativememory-linux/
14.Java運行時數據區
答:見上圖,但是要注意的是在JDK1.8之后,方法區(PermGen)已經去除,相關的內容被移到了元數據區。
http://www.infoq.com/cn/articles/Java-PERMGEN-Removed
http://www.lxweimin.com/p/6173a467165e
15.事務的實現原理
答: https://my.oschina.net/huangyong/blog/160012
https://my.oschina.net/huangyong/blog/1598521.