Java中级面试题及答案(120道Java中级面试题大汇总)
Java中級面試題及答案【最新版及答案,干貨!!!這是一個中級Java面試系列題中的第一部分。這一部分論述了可變參數,斷言,垃圾回收,初始化器,令牌化,日期,日歷等等Java核心問題。
Java中級面試永遠是程序員邁向成功的第一個門檻,想要面試成功,各種面試題的洗禮是必不可少的,下面就來看看小編精心整理的一些java高級工程師面試題及答案吧。
如果不背 Java面試題的答案,肯定面試會掛!
這套Java面試題大全,希望對大家有幫助哈~
博主已將以下這些面試題整理成了一個Java面試手冊,是PDF版的
1、線程與進程的區別
進程是系統進行資源分配和調度的一個獨立單位,線程是CPU調度和分派的基本單位
進程和線程的關系:
1、?一個線程只能屬于一個進程,而一個進程可以有多個線程,但至少有一個線程。
2、?資源分配給進程,同一進程的所有線程共享該進程的所有資源。
3、?線程在執行過程中,需要協作同步。不同進程的線程間要利用消息通信的辦法實現同步。
4、?線程是指進程內的一個執行單元,也是進程內的可調度實體。
線程與進程的區別:
1、?調度:線程作為調度和分配的基本單位,進程作為擁有資源的基本單位。
2、?并發性:不僅進程之間可以并發執行,同一個進程的多個線程之間也可以并發執行。
3、?擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統資源,但可以訪問隸屬于進程的資源。
4、?系統開銷:在創建或撤銷進程的時候,由于系統都要為之分配和回收資源,導致系統的明顯大于創建或撤銷線程時的開銷。但進程有獨立的地址空間,進程崩潰后,在保護模式下不會對其他的進程產生影響,而線程只是一個進程中的不同的執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉,所以多進程的程序要比多線程的程序健壯,但是在進程切換時,耗費的資源較大,效率要差些。
2、什么是策略模式
定義了一系列的算法 或 邏輯 或 相同意義的操作,并將每一個算法、邏輯、操作封裝起來,而且使它們還可以相互替換。(其實策略模式Java中用的非常非常廣泛)
我覺得主要是為了 簡化 if...else 所帶來的復雜和難以維護。
3、什么是游標?
游標是sql查詢結果集的一個指針,與select語句相關聯。
游標關鍵字是cursor,主要包含兩個部分:游標結果集和游標位置。
1、?游標結果集:執行select語句后的查詢結果
2、?游標位置:一個指向游標結果集內某條記錄的指針。
游標主要有兩個狀態:打開和關閉。
1、?只有當游標處于打開狀態時,才能夠操作結果集中的數據
2、?當游標關閉后,查詢結果集就不存在了
4、單例模式了解嗎?給我解釋一下雙重檢驗鎖方式實現單例模式!”
雙重校驗鎖實現對象單例(線程安全)
說明:
雙鎖機制的出現是為了解決前面同步問題和性能問題,看下面的代碼,簡單分析下確實是解決了多線程并行進來不會出現重復new對象,而且也實現了懶加載
public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton getUniqueInstance() { //先判斷對象是否已經實例過,沒有實例化過才進入加鎖代碼 if (uniqueInstance == null) { //類對象加鎖 synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }
另外,需要注意 uniqueInstance 采用 volatile 關鍵字修飾也是很有必要。
uniqueInstance 采用 volatile 關鍵字修飾也是很有必要的, uniqueInstance = new Singleton(); 這段代碼其實是分為三步執行:
1、?為 uniqueInstance 分配內存空間
2、?初始化 uniqueInstance
3、?將 uniqueInstance 指向分配的內存地址
但是由于 JVM 具有指令重排的特性,執行順序有可能變成 1->3->2。指令重排在單線程環境下不會出現問題,但是在多線程環境下會導致一個線程獲得還沒有初始化的實例。例如,線程 T1 執行了 1 和 3,此時 T2 調用 getUniqueInstance() 后發現 uniqueInstance 不為空,因此返回 uniqueInstance,但此時 uniqueInstance 還未被初始化。
使用 volatile 可以禁止 JVM 的指令重排,保證在多線程環境下也能正常運行。
5、怎么獲取 Java 程序使用的內存?堆使用的百分比?
可以通過 java.lang.Runtime 類中與內存相關方法來獲取剩余的內存,總內存及最大堆內存。通過這些方法你也可以獲取到堆使用的百分比及堆內存的剩余空間。Runtime.freeMemory() 方法返回剩余空間的字節數,Runtime.totalMemory()方法總內存的字節數,Runtime.maxMemory() 返回最大內存的字節數。
6、在java中守護線程和本地線程區別?
java中的線程分為兩種:守護線程(Daemon)和用戶線程(User)。
任何線程都可以設置為守護線程和用戶線程,通過方法Thread.setDaemon(bool on);true則把該線程設置為守護線程,反之則為用戶線程。Thread.setDaemon()必須在Thread.start()之前調用,否則運行時會拋出異常。
兩者的區別:
唯一的區別是判斷虛擬機(JVM)何時離開,Daemon是為其他線程提供服務,如果全部的User Thread已經撤離,Daemon 沒有可服務的線程,JVM撤離。也可以理解為守護線程是JVM自動創建的線程(但不一定),用戶線程是程序創建的線程;比如JVM的垃圾回收線程是一個守護線程,當所有線程已經撤離,不再產生垃圾,守護線程自然就沒事可干了,當垃圾回收線程是Java虛擬機上僅剩的線程時,Java虛擬機會自動離開。
擴展:
Thread Dump打印出來的線程信息,含有daemon字樣的線程即為守護進程,可能會有:服務守護進程、編譯守護進程、windows下的監聽Ctrl+break的守護進程、Finalizer守護進程、引用處理守護進程、GC守護進程。
7、線程之間是如何通信的?
當線程間是可以共享資源時,線程間通信是協調它們的重要的手段。Object類中wait()\notify()\notifyAll()方法可以用于線程間通信關于資源的鎖的狀態。
8、聚集索引與非聚集索引有什么區別?
所有的索引都是為了更快地檢索數據,索引存放在索引頁中,數據存放在數據頁中,索引以B(balance)樹的形式存儲
聚集索引:聚集索引用于決定數據表中的物理存儲順序,一張表最多有一個聚集索引。聚集索引的字段值盡量不能修改,因為修改后,因為修改后數據表的物理順序需要重寫排序。通常主鍵就是聚集索引
非聚集索引:非聚集索引的關鍵自是index,不會決定表的物理存儲順序,在一張表內最多可以有249個非聚集索引。
9、說一下 ArrayList 的優缺點
ArrayList的優點如下:
1、?ArrayList 底層以數組實現,是一種隨機訪問模式。ArrayList 實現了 RandomAccess 接口,因此查找的時候非常快。
2、?ArrayList 在順序添加一個元素的時候非常方便。
ArrayList 的缺點如下:
1、?刪除元素的時候,需要做一次元素復制操作。如果要復制的元素很多,那么就會比較耗費性能。
2、?插入元素的時候,也需要做一次元素復制操作,缺點同上。
3、?ArrayList 比較適合順序添加、隨機訪問的場景。
10、請解釋StackOverflowError和OutOfMemeryError的區別?
通過之前的分析可以發現,實際上每一塊內存中都會存在有一部分的可變伸縮區,其基本流程為:如果空間內存不足,在可變范圍之內擴大內存空間,當一段時間之后發現內存充足,會縮小內存空間。
永久代(JDK 1.8后消失了)
雖然java的版本是JDK1.8,但是java EE 的版本還是jdk1.7,永久代存在于堆內存之中
元空間
元空間在Jdk1.8之后才有的,器功能實際上和永久代沒區別,唯一的區別在于永久代使用的是JVM的堆內存空間,元空間使用的是物理內存,所以元空間的大小受本地內存影響,一般默認在2M 左右。
范例:設置一些參數,讓元空間出錯
Java -XX:MetaspaceSize=1m
11、請闡述Catalina的配置文件有哪些?
Catalina包含的配置文件有:
1、?·policy
2、?·properties
3、?·properties
4、?·xml
5、?·xml
6、?·Tomcat-users.xml
12、Java中有幾種類型的流?
字節流和字符流。字節流繼承于InputStream、OutputStream,字符流繼承于Reader、Writer。在http://java.io?包中還有許多其他的流,主要是為了提高性能和使用方便。關于Java的I/O需要注意的有兩點:一是兩種對稱性(輸入和輸出的對稱性,字節和字符的對稱性);二是兩種設計模式(適配器模式和裝潢模式)。另外Java中的流不同于C#的是它只有一個維度一個方向。
面試題 - 編程實現文件拷貝。(這個題目在筆試的時候經常出現,下面的代碼給出了兩種實現方案) import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public final class MyUtil {private MyUtil() {throw new AssertionError();}public static void fileCopy(String source, String target) throws IOException {try (InputStream in = new FileInputStream(source)) {try (OutputStream out = new FileOutputStream(target)) {byte[] buffer = new byte[4096];int bytesToRead;while ((bytesToRead = in .read(buffer)) != -1) {out.write(buffer, 0, bytesToRead);}}}}public static void fileCopyNIO(String source, String target) throws IOException {try (FileInputStream in = new FileInputStream(source)) {try (FileOutputStream out = new FileOutputStream(target)) {FileChannel inChannel = in .getChannel();FileChannel outChannel = out.getChannel();ByteBuffer buffer = ByteBuffer.allocate(4096);while (inChannel.read(buffer) != -1) {buffer.flip();outChannel.write(buffer);buffer.clear();}}}} } 注意:上面用到Java 7的TWR,使用TWR后可以不用在finally中釋放外部資源 ,從而讓代碼更加優雅。13、當一個線程進入一個對象的synchronized方法A之后,其它線程是否可進入此對象的synchronized方法B?
不能。其它線程只能訪問該對象的非同步方法,同步方法則不能進入。因為非靜態方法上的synchronized修飾符要求執行方法時要獲得對象的鎖,如果已經進入A方法說明對象鎖已經被取走,那么試圖進入B方法的線程就只能在等鎖池(注意不是等待池哦)中等待對象的鎖。
14、什么是不可變對象(immutable object)?Java 中怎么創建一個不可變對象?
不可變對象指對象一旦被創建,狀態就不能再改變。任何修改都會創建一個新的對象,如 String、Integer及其它包裝類。詳情參見答案,一步一步指導你在 Java 中創建一個不可變的類。
15、怎么利用 JUnit 來測試一個方法的異常?
http://javarevisited.blogspot.sg/2013/04/JUnit-tutorial-example-test-exception-thrown-by-java-method.html
16、兩個相同的對象會有不同的的 hash code 嗎?
不能,根據 hash code 的規定,這是不可能的。
17、如果你提交任務時,線程池隊列已滿,這時會發生什么
有倆種可能:
1、?如果使用的是無界隊列 LinkedBlockingQueue,也就是無界隊列的話,沒關系,繼續添加任務到阻塞隊列中等待執行,因為 LinkedBlockingQueue 可以近乎認為是一個無窮大的隊列,可以無限存放任務
2、?如果使用的是有界隊列比如 ArrayBlockingQueue,任務首先會被添加到ArrayBlockingQueue 中,ArrayBlockingQueue 滿了,會根據maximumPoolSize 的值增加線程數量,如果增加了線程數量還是處理不過來,ArrayBlockingQueue 繼續滿,那么則會使用拒絕策略RejectedExecutionHandler 處理滿了的任務,默認是 AbortPolicy
18、GC日志的real、user、sys是什么意思?
real?實際花費的時間,指的是從開始到結束所花費的時間。比如進程在等待I/O完成,這個阻塞時間也會被計算在內。user?指的是進程在用戶態(User Mode)所花費的時間,只統計本進程所使用的時間,是指多核。sys?指的是進程在核心態(Kernel Mode)花費的CPU時間量,指的是內核中的系統調用所花費的時間,只統計本進程所使用的時間。
這個是用來看日志用的,如果你不看日志,那不了解也無妨。不過,這三個參數的意義,在你能看到的地方,基本上都是一致的,比如操作系統。
19、解釋 Java 堆空間及 GC?
當通過 Java 命令啟動 Java 進程的時候,會為它分配內存。內存的一部分用于創建堆空間,當程序中創建對象的時候,就從對空間中分配內存。GC 是 JVM 內部的一個進程,回收無效對象的內存用于將來的分配。
20、類的實例化順序
比如父類靜態數據,構造函數,字段,子類靜態數據,構造函數,字段,他們的執行順序
先靜態、先父后子。
先靜態:父靜態 > 子靜態
優先級:父類 > 子類 靜態代碼塊 > 非靜態代碼塊 > 構造函數
一個類的實例化過程:
1、?父類中的static代碼塊,當前類的static
2、?順序執行父類的普通代碼塊
3、?父類的構造函數
4、?子類普通代碼塊
5、?子類(當前類)的構造函數,按順序執行。
6、?子類方法的執行,
21、Spring中自動裝配的方式有哪些?
1、?no:不進行自動裝配,手動設置Bean的依賴關系。
2、?byName:根據Bean的名字進行自動裝配。
3、?byType:根據Bean的類型進行自動裝配。
4、?constructor:類似于byType,不過是應用于構造器的參數,如果正好有一個Bean與構造器的參數類型相同則可以自動裝配,否則會導致錯誤。
5、?autodetect:如果有默認的構造器,則通過constructor的方式進行自動裝配,否則使用byType的方式進行自動裝配。
22、棧幀里面包含哪些東西?
局部變量表、操作數棧、動態連接、返回地址等
23、你是如何調用 wait() 方法的?使用 if 塊還是循環?為什么?
處于等待狀態的線程可能會收到錯誤警報和偽喚醒,如果不在循環中檢查等待條件,程序就會在沒有滿足結束條件的情況下退出。
wait() 方法應該在循環調用,因為當線程獲取到 CPU 開始執行的時候,其他條件可能還沒有滿足,所以在處理前,循環檢測條件是否滿足會更好。下面是一段標準的使用 wait 和 notify 方法的代碼:
synchronized (monitor) { // 判斷條件謂詞是否得到滿足 while(!locked) { // 等待喚醒 monitor.wait(); } // 處理其他的業務邏輯 }
24、ArrayList與LinkedList有什么區別?
1、?ArrayList與LinkedList都實現了List接口。
2、?ArrayList是線性表,底層是使用數組實現的,它在尾端插入和訪問數據時效率較高,
3、?Linked是雙向鏈表,他在中間插入或者頭部插入時效率較高,在訪問數據時效率較低
25、Super與this表示什么?
1、?Super表示當前類的父類對象
2、?This表示當前類的對象
26、簡述Java的對象結構
Java對象由三個部分組成:對象頭、實例數據、對齊填充。
對象頭由兩部分組成,第一部分存儲對象自身的運行時數據:哈希碼、GC分代年齡、鎖標識狀態、線程持有的鎖、偏向線程ID(一般占32/64 bit)。第二部分是指針類型,指向對象的類元數據類型(即對象代表哪個類)。如果是數組對象,則對象頭中還有一部分用來記錄數組長度。
實例數據用來存儲對象真正的有效信息(包括父類繼承下來的和自己定義的)
對齊填充:JVM要求對象起始地址必須是8字節的整數倍(8字節對齊 )
27、Java 虛擬機棧的作用?
Java 虛擬機棧來描述 Java 方法的內存模型。每當有新線程創建時就會分配一個棧空間,線程結束后棧空間被回收,棧與線程擁有相同的生命周期。棧中元素用于支持虛擬機進行方法調用,每個方法在執行時都會創建一個棧幀存儲方法的局部變量表、操作棧、動態鏈接和方法出口等信息。每個方法從調用到執行完成,就是棧幀從入棧到出棧的過程。
有兩類異常:① 線程請求的棧深度大于虛擬機允許的深度拋出 StackOverflowError。② 如果 JVM 棧容量可以動態擴展,棧擴展無法申請足夠內存拋出 OutOfMemoryError(HotSpot 不可動態擴展,不存在此問題)。
28、實際開發中應用場景哪里用到了模板方法
其實很多框架中都有用到了模板方法模式
例如:
數據庫訪問的封裝、Junit單元測試、servlet中關于doGet/doPost方法的調用等等
29、import java和javax有什么區別
tech.souyunku.com/EasonJim/p/…
31、Spring中自動裝配的方式有哪些?
1、?no:不進行自動裝配,手動設置Bean的依賴關系。
2、?byName:根據Bean的名字進行自動裝配。
3、?byType:根據Bean的類型進行自動裝配。
4、?constructor:類似于byType,不過是應用于構造器的參數,如果正好有一個Bean與構造器的參數類型相同則可以自動裝配,否則會導致錯誤。
5、?autodetect:如果有默認的構造器,則通過constructor的方式進行自動裝配,否則使用byType的方式進行自動裝配。
32、棧幀里面包含哪些東西?
局部變量表、操作數棧、動態連接、返回地址等
33、你是如何調用 wait() 方法的?使用 if 塊還是循環?為什么?
處于等待狀態的線程可能會收到錯誤警報和偽喚醒,如果不在循環中檢查等待條件,程序就會在沒有滿足結束條件的情況下退出。
wait() 方法應該在循環調用,因為當線程獲取到 CPU 開始執行的時候,其他條件可能還沒有滿足,所以在處理前,循環檢測條件是否滿足會更好。下面是一段標準的使用 wait 和 notify 方法的代碼:
synchronized (monitor) { // 判斷條件謂詞是否得到滿足 while(!locked) { // 等待喚醒 monitor.wait(); } // 處理其他的業務邏輯 }
34、ArrayList與LinkedList有什么區別?
1、?ArrayList與LinkedList都實現了List接口。
2、?ArrayList是線性表,底層是使用數組實現的,它在尾端插入和訪問數據時效率較高,
3、?Linked是雙向鏈表,他在中間插入或者頭部插入時效率較高,在訪問數據時效率較低
35、Super與this表示什么?
1、?Super表示當前類的父類對象
2、?This表示當前類的對象
36、簡述Java的對象結構
Java對象由三個部分組成:對象頭、實例數據、對齊填充。
對象頭由兩部分組成,第一部分存儲對象自身的運行時數據:哈希碼、GC分代年齡、鎖標識狀態、線程持有的鎖、偏向線程ID(一般占32/64 bit)。第二部分是指針類型,指向對象的類元數據類型(即對象代表哪個類)。如果是數組對象,則對象頭中還有一部分用來記錄數組長度。
實例數據用來存儲對象真正的有效信息(包括父類繼承下來的和自己定義的)
對齊填充:JVM要求對象起始地址必須是8字節的整數倍(8字節對齊 )
37、Java 虛擬機棧的作用?
Java 虛擬機棧來描述 Java 方法的內存模型。每當有新線程創建時就會分配一個棧空間,線程結束后棧空間被回收,棧與線程擁有相同的生命周期。棧中元素用于支持虛擬機進行方法調用,每個方法在執行時都會創建一個棧幀存儲方法的局部變量表、操作棧、動態鏈接和方法出口等信息。每個方法從調用到執行完成,就是棧幀從入棧到出棧的過程。
有兩類異常:① 線程請求的棧深度大于虛擬機允許的深度拋出 StackOverflowError。② 如果 JVM 棧容量可以動態擴展,棧擴展無法申請足夠內存拋出 OutOfMemoryError(HotSpot 不可動態擴展,不存在此問題)。
38、實際開發中應用場景哪里用到了模板方法
其實很多框架中都有用到了模板方法模式
例如:
數據庫訪問的封裝、Junit單元測試、servlet中關于doGet/doPost方法的調用等等
39、import java和javax有什么區別
tech.souyunku.com/EasonJim/p/…
40、構造器(constructor)是否可被重寫(override)?
構造器不能被繼承,因此不能被重寫,但可以被重載。
更多Java 面試題80道
01、創建socket通訊的步驟?
02、Java 中 sleep 方法和 wait 方法的區別?
03、程序計數器(線程私有)
04、什么是線程調度器(Thread Scheduler)和時間分片(Time Slicing)?
05、迭代器 Iterator 是什么?
06、線程的 sleep()方法和 yield()方法有什么區別?
07、Java 中能創建 volatile 數組嗎?
08、java中equals方法的用法以及==的用法
09、如何創建一個json對象?
10、如何判斷對象是否是垃圾?
11、抽象工廠模式和原型模式之間的區別?
12、在 Java 程序中怎么保證多線程的運行安全?
13、volatile 修飾符的有過什么實踐?
14、Java中各種數據默認值
15、說說Java 垃圾回收機制
16、有沒有可能兩個不相等的對象有有相同的 hashcode?
17、synchronized 和 Lock 有什么區別?
18、什么是Vector
19、對象的訪問定位有哪幾種方式?
20、equals 和 == 的區別?#
21、什么是ThreadPoolExecutor?
22、invokedynamic 指令是干什么的?
23、synchronized、volatile、CAS 比較
24、Iterator 怎么使用?有什么特點?
25、被引用的對象就一定能存活嗎?
26、列出一些你常見的運行時異常?
27、Servlet生命周期內調用的方法過程?
28、闡述靜態變量和實例變量的區別。
29、類加載器雙親委派模型機制?
30、抽象的(abstract)方法是否可同時是靜態的(static),是否可同時是本地方法(native),是否可同時被synchronized修飾?
31、如何判斷一個對象是否存活
32、Int與integer的區別
33、Servlet的生命周期?
34、怎么喚醒一個阻塞的線程
35、虛擬DOM的優劣如何?
36、雙親委派模型是什么?
37、靜態嵌套類(Static Nested Class)和內部類(Inner Class)的不同?
38、如果對象的引用被置為null,垃圾收集器是否會立即釋放對象占用的內存?
39、JVM 出現 fullGC 很頻繁,怎么去線上排查問題
40、JVM 內存區域
41、Parallel Old 收集器(多線程標記整理算法)
42、對象分配內存是否線程安全?
43、當一個線程進入某個對象的一個synchronized的實例方法后,其它線程是否可進入此對象的其它方法?
44、Serial 與 Parallel GC 之間的不同之處?
45、為什么線程通信的方法 wait(), notify()和 notifyAll()被定義在 Object 類里?
46、redux異步中間件之間的優劣?
47、類加載為什么要使用雙親委派模式,有沒有什么場景是打破了這個模式?
48、Hibernate中Session的load和get方法的區別是什么?
49、說一下堆內存中對象的分配的基本策略
50、Java 中如何將字符串轉換為整數?
51、講講什么情況下會出現內存溢出,內存泄漏?
52、樂觀鎖和悲觀鎖的理解及如何實現,有哪些實現方式?
53、線程與進程的區別?
54、Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法分別是做什么的?有什么區別?
55、用代碼演示三種代理
56、stackoverflow錯誤,permgen space錯誤
57、分代收集算法
58、同步方法和同步塊,哪個是更好的選擇?
69、Java 中的編譯期常量是什么?使用它又什么風險?
70、Java死鎖以及如何避免?
71、日期和時間:
72、XML文檔定義有幾種形式?它們之間有何本質區別?解析XML文檔有哪幾種方式?
73、依賴注入和工程模式之間有什么不同?
74、Java 堆的結構是什么樣子的?什么是堆中的永久代(Perm Gen space)
75、如何修改tomcat的端口號?
76、Java有沒有goto?
77、Java 內存分配與回收策率以及 Minor GC 和 Major GC
78、簡述Hibernate常見優化策略。
79、Statement與preparedStatement區別
80、什么是DAO模式?
如果不背 Java面試題的答案,肯定面試會掛!
這套Java面試題大全,希望對大家有幫助哈~
博主已將以下這些面試題整理成了一個Java面試手冊,是PDF版的
總結
以上是生活随笔為你收集整理的Java中级面试题及答案(120道Java中级面试题大汇总)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rapidxml 文件读写,增加删除节点
- 下一篇: UEditor 自定义input,复选框