Java面試題大全帶答案 110道(持續更新)


本人發現網上雖然有不少Java面試題大全帶答案,但第一未必全,第二未必有答案,第三雖然有答案,但未必能在面試中說,所以在本文里,會不斷收集各種面試題,並站在面試官的立場上,給出我自己的答案

如果不背 Java面試題的答案,肯定面試會掛!

這套Java面試題大全,希望對大家有幫助哈~

博主已將以下這些面試題整理成了一個Java面試手冊,是PDF版的

1、CMS分為哪幾個階段?

CMS已經棄用。生活美好,時間有限,不建議再深入研究了。如果碰到問題,直接祭出回收過程即可。

1、 初始標記

2、 並發標記

3、 並發預清理

4、 並發可取消的預清理

5、 重新標記

6、 並發清理

由於《深入理解java虛擬機》一書的流行,面試時省略3、4步一般也是沒問題的。

2、Thread類的sleep()方法和對象的wait()方法都可以讓線程暫停執行,它們有什么區別?

sleep()方法(休眠)是線程類(Thread)的靜態方法,調用此方法會讓當前線程暫停執行指定的時間,將執行機會(CPU)讓給其他線程,但是對象的鎖依然保持,因此休眠時間結束后會自動恢復(線程回到就緒狀態,請參考第66題中的線程狀態轉換圖)。wait()是Object類的方法,調用對象的wait()方法導致當前線程放棄對象的鎖(線程暫停執行),進入對象的等待池(wait pool),只有調用對象的notify()方法(或notifyAll()方法)時才能喚醒等待池中的線程進入等鎖池(lock pool),如果線程重新獲得對象的鎖就可以進入就緒狀態。

補充:可能不少人對什么是進程,什么是線程還比較模糊,對於為什么需要多線程編程也不是特別理解。簡單的說:進程是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,是操作系統進行資源分配和調度的一個獨立單位;線程是進程的一個實體,是CPU調度和分派的基本單位,是比進程更小的能獨立運行的基本單位。線程的划分尺度小於進程,這使得多線程程序的並發性高;進程在執行時通常擁有獨立的內存單元,而線程之間可以共享內存。使用多線程的編程通常能夠帶來更好的性能和用戶體驗,但是多線程的程序對於其他程序是不友好的,因為它可能占用了更多的CPU資源。當然,也不是線程越多,程序的性能就越好,因為線程之間的調度和切換也會浪費CPU時間。時下很時髦的 Node.js就采用了單線程異步I/O的工作模式。

3、請解釋如何配置Tomcat來使用IIS和NTLM ?

必須遵循isapi_redirector.dll的標准指令

配置IIS使用“集成windows驗證”

確保在服務器.xml中您已經禁用了tomcat身份驗證

4、Java中的繼承是單繼承還是多繼承

Java中既有單繼承,又有多繼承。對於java類來說只能有一個父類,對於接口來說可以同時繼承多個接口

5、事務的使用場景在什么地方?

但一個業務邏輯包括多個數據庫操作的時候,而且需要保證每個數據表操作都執行的成功進行下一個操作,這個時候可以使用事務

6、說一下垃圾分代收集的過程

分為新生代和老年代,新生代默認占總空間的 1/3,老年代默認占 2/3。

新生代使用復制算法,有 3 個分區:Eden、To Survivor、From Survivor,它們的默認占比是 8:1:1。

當新生代中的 Eden 區內存不足時,就會觸發 Minor GC,過程如下:

1、 在 Eden 區執行了第一次 GC 之后,存活的對象會被移動到其中一個 Survivor 分區;

2、 Eden 區再次 GC,這時會采用復制算法,將 Eden 和 from 區一起清理,存活的對象會被復制到 to 區;

3、 移動一次,對象年齡加 1,對象年齡大於一定閥值會直接移動到老年代

4、 Survivor 區相同年齡所有對象大小的總和 (Survivor 區內存大小 * 這個目標使用率)時,大於或等於該年齡的對象直接進入老年代。其中這個使用率通過 -XX:TargetSurvivorRatio 指定,默認為 50%

5、 Survivor 區內存不足會發生擔保分配

6、 超過指定大小的對象可以直接進入老年代

Major GC,指的是老年代的垃圾清理,但並未找到明確說明何時在進行Major GC

FullGC,整個堆的垃圾收集,觸發條件:

1、 每次晉升到老年代的對象平均大小>老年代剩余空間

2、 MinorGC后存活的對象超過了老年代剩余空間

3、 元空間不足

4、 System.gc() 可能會引起

5、 CMS GC異常,promotion failed:MinorGC時,survivor空間放不下,對象只能放入老年代,而老年代也放不下造成;concurrent mode failure:GC時,同時有對象要放入老年代,而老年代空間不足造成

6、 堆內存分配很大的對象

7、可以直接調用Thread類的run ()方法么?

當然可以。但是如果我們調用了Thread的run()方法,它的行為就會和普通的方法一樣,會在當前線程中執行。為了在新的線程中執行我們的代碼,必須使用Thread.start()方法。

8、Math.round(11.5) 等於多少?Math.round(-11.5)等於多少?

Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在參數上加0.5然后進行下取整。

9、字節流與字符流的區別

1、 以字節為單位輸入輸出數據,字節流按照8位傳輸

2、 以字符為單位輸入輸出數據,字符流按照16位傳輸

10、Java 堆的結構是什么樣子的?什么是堆中的永久代(Perm Gen space)

JVM 的堆是運行時數據區,所有類的實例和數組都是在堆上分配內存。它在 JVM 啟動的時候被創建。對象所占的堆內存是由自動內存管理系統也就是垃圾收集器回收。

堆內存是由存活和死亡的對象組成的。存活的對象是應用可以訪問的,不會被垃圾回收。死亡的對象是應用不可訪問尚且還沒有被垃圾收集器回收掉的對象。一直到垃圾收集器把這些 對象回收掉之前,他們會一直占據堆內存空間。

11、Spring中自動裝配的方式有哪些?

1、 no:不進行自動裝配,手動設置Bean的依賴關系。

2、 byName:根據Bean的名字進行自動裝配。

3、 byType:根據Bean的類型進行自動裝配。

4、 constructor:類似於byType,不過是應用於構造器的參數,如果正好有一個Bean與構造器的參數類型相同則可以自動裝配,否則會導致錯誤。

5、 autodetect:如果有默認的構造器,則通過constructor的方式進行自動裝配,否則使用byType的方式進行自動裝配。

12、棧幀里面包含哪些東西?

局部變量表、操作數棧、動態連接、返回地址等

13、你是如何調用 wait() 方法的?使用 if 塊還是循環?為什么?

處於等待狀態的線程可能會收到錯誤警報和偽喚醒,如果不在循環中檢查等待條件,程序就會在沒有滿足結束條件的情況下退出。

wait() 方法應該在循環調用,因為當線程獲取到 CPU 開始執行的時候,其他條件可能還沒有滿足,所以在處理前,循環檢測條件是否滿足會更好。下面是一段標准的使用 wait 和 notify 方法的代碼:

synchronized (monitor) { // 判斷條件謂詞是否得到滿足 while(!locked) { // 等待喚醒 monitor.wait(); } // 處理其他的業務邏輯 }

14、ArrayList與LinkedList有什么區別?

1、 ArrayList與LinkedList都實現了List接口。

2、 ArrayList是線性表,底層是使用數組實現的,它在尾端插入和訪問數據時效率較高,

3、 Linked是雙向鏈表,他在中間插入或者頭部插入時效率較高,在訪問數據時效率較低

15、Super與this表示什么?

1、 Super表示當前類的父類對象

2、 This表示當前類的對象

16、簡述Java的對象結構

Java對象由三個部分組成:對象頭、實例數據、對齊填充。

對象頭由兩部分組成,第一部分存儲對象自身的運行時數據:哈希碼、GC分代年齡、鎖標識狀態、線程持有的鎖、偏向線程ID(一般占32/64 bit)。第二部分是指針類型,指向對象的類元數據類型(即對象代表哪個類)。如果是數組對象,則對象頭中還有一部分用來記錄數組長度。

實例數據用來存儲對象真正的有效信息(包括父類繼承下來的和自己定義的)

對齊填充:JVM要求對象起始地址必須是8字節的整數倍(8字節對齊 )

17、Java 虛擬機棧的作用?

Java 虛擬機棧來描述 Java 方法的內存模型。每當有新線程創建時就會分配一個棧空間,線程結束后棧空間被回收,棧與線程擁有相同的生命周期。棧中元素用於支持虛擬機進行方法調用,每個方法在執行時都會創建一個棧幀存儲方法的局部變量表、操作棧、動態鏈接和方法出口等信息。每個方法從調用到執行完成,就是棧幀從入棧到出棧的過程。

有兩類異常:① 線程請求的棧深度大於虛擬機允許的深度拋出 StackOverflowError。② 如果 JVM 棧容量可以動態擴展,棧擴展無法申請足夠內存拋出 OutOfMemoryError(HotSpot 不可動態擴展,不存在此問題)。

18、實際開發中應用場景哪里用到了模板方法

其實很多框架中都有用到了模板方法模式

例如:

數據庫訪問的封裝、Junit單元測試、servlet中關於doGet/doPost方法的調用等等

19、import java和javax有什么區別

tech.souyunku.com/EasonJim/p/…

20、構造器(constructor)是否可被重寫(override)?

構造器不能被繼承,因此不能被重寫,但可以被重載。

21、volatile 變量和 atomic 變量有什么不同?

volatile 變量可以確保先行關系,即寫操作會發生在后續的讀操作之前, 但它並不能保證原子性。例如用 volatile 修飾 count 變量,那么 count++ 操作就不是原子性的。

而 AtomicInteger 類提供的 atomic 方法可以讓這種操作具有原子性如getAndIncrement()方法會原子性的進行增量操作把當前值加一,其它數據類型和引用變量也可以進行相似操作。

22、堆和棧的區別

棧是運行時單位,代表着邏輯,內含基本數據類型和堆中對象引用,所在區域連續,沒有碎片;堆是存儲單位,代表着數據,可被多個棧共享(包括成員中基本數據類型、引用和引用對象),所在區域不連續,會有碎片。

功能不同

棧內存用來存儲局部變量和方法調用,而堆內存用來存儲Java中的對象。無論是成員變量,局部變量,還是類變量,它們指向的對象都存儲在堆內存中。

共享性不同

棧內存是線程私有的。

堆內存是所有線程共有的。

異常錯誤不同

如果棧內存或者堆內存不足都會拋出異常。

棧空間不足:java.lang.StackOverFlowError。

堆空間不足:java.lang.OutOfMemoryError。

空間大小

棧的空間大小遠遠小於堆的

23、32 位和 64 位的 JVM,int 類型變量的長度是多數?

32 位和 64 位的 JVM 中,int 類型變量的長度是相同的,都是 32 位或者 4 個字節。

24、如何找到死鎖的線程?

死鎖的線程可以使用 jstack 指令 dump 出 JVM 的線程信息。

jstack -l <pidthreads.txt

有時候需要dump出現異常,可以加上 -F 指令,強制導出

jstack -F -l <pidthreads.txt

如果存在死鎖,一般在文件最后會提示找到 deadlock 的數量與線程信息

25、float f=3.4;是否正確?

答:不正確。3.4是雙精度數,將雙精度型(double)賦值給浮點型(float)屬於下轉型(down-casting,也稱為窄化)會造成精度損失,因此需要強制類型轉換float f =(float)3.4; 或者寫成float f =3.4F;。

26、談談永久代

1、 JDK 8 之前,Hotspot 中方法區的實現是永久代(Perm)

2、 JDK 7 開始把原本放在永久代的字符串常量池、靜態變量等移出到堆,JDK 8 開始去除永久代,使用元空間(Metaspace),永久代剩余內容移至元空間,元空間直接在本地內存分配。

27、啟動一個線程是調用run()還是start()方法?

啟動一個線程是調用start()方法,使線程所代表的虛擬處理機處於可運行狀態,這意味着它可以由JVM 調度並執行,這並不意味着線程就會立即運行。run()方法是線程啟動后要進行回調(callback)的方法。

28、在新生代-復制算法

每次垃圾收集都能發現大批對象已死, 只有少量存活、因此選用復制算法, 只需要付出少量存活對象的復制成本就可以完成收集

29、創建一個對象用什么運算符?對象實體與對象引用有何不同?

new運算符,new創建對象實例(對象實例在堆內存中),對象引用指向對象實例(對象引用存放在棧內存中)。一個對象引用可以指向0個或1個對象(一根繩子可以不系氣球,也可以系一個氣球);一個對象可以有n個引用指向它(可以用n條繩子系住一個氣球)

30、什么是線程組,為什么在 Java 中不推薦使用?

1、 ThreadGroup 類,可以把線程歸屬到某一個線程組中,線程組中可以有線程對象,也可以有線程組,組中還可以有線程,這樣的組織結構有點類似於樹的形式。

2、 線程組和線程池是兩個不同的概念,他們的作用完全不同,前者是為了方便線程的管理,后者是為了管理線程的生命周期,復用線程,減少創建銷毀線程的開銷。

3、 為什么不推薦使用線程組?因為使用有很多的安全隱患吧,沒有具體追究,如果需要使用,推薦使用線程池。

31、為什么HashMap中String、Integer這樣的包裝類適合作為K?

String、Integer等包裝類的特性能夠保證Hash值的不可更改性和計算准確性,能夠有效的減少Hash碰撞的幾率

1、 都是final類型,即不可變性,保證key的不可更改性,不會存在獲取hash值不同的情況

2、 內部已重寫了equals()hashCode()等方法,遵守了HashMap內部的規范(不清楚可以去上面看看putValue的過程),不容易出現Hash值計算錯誤的情況;

32、常見的計算機網絡協議有那些?

1、 TCP/IP協議

2、 IPX/SPX協議

3、 NetBEUI協議

33、一個線程運行時發生異常會怎樣?

如果異常沒有被捕獲該線程將會停止執行。Thread.UncaughtExceptionHandler是用於處理未捕獲異常造成線程突然中斷情況的一個內嵌接口。當一個未捕獲異常將造成線程中斷的時候JVM會使用Thread.getUncaughtExceptionHandler()來查詢線程的UncaughtExceptionHandler並將線程和異常作為參數傳遞給handler的uncaughtException()方法進行處理。

34、遍歷一個 List 有哪些不同的方式?每種方法的實現原理是什么?Java 中 List 遍歷的最佳實踐是什么?

遍歷方式有以下幾種:

1、 for 循環遍歷,基於計數器。在集合外部維護一個計數器,然后依次讀取每一個位置的元素,當讀取到最后一個元素后停止。

2、 迭代器遍歷,Iterator。Iterator 是面向對象的一個設計模式,目的是屏蔽不同數據集合的特點,統一遍歷集合的接口。Java 在 Collections 中支持了 Iterator 模式。

3、 foreach 循環遍歷。foreach 內部也是采用了 Iterator 的方式實現,使用時不需要顯式聲明 Iterator 或計數器。優點是代碼簡潔,不易出錯;缺點是只能做簡單的遍歷,不能在遍歷過程中操作數據集合,例如刪除、替換。

最佳實踐:

Java Collections 框架中提供了一個 RandomAccess 接口,用來標記 List 實現是否支持 Random Access。

1、 如果一個數據集合實現了該接口,就意味着它支持 Random Access,按位置讀取元素的平均時間復雜度為 O(1),如ArrayList。

2、 如果沒有實現該接口,表示不支持 Random Access,如LinkedList。

3、 推薦的做法就是,支持 Random Access 的列表可用 for 循環遍歷,否則建議用 Iterator 或 foreach 遍歷。

35、StringBuffer,Stringbuilder有什么區別?

StringBuffer與StringBuilder都繼承了AbstractStringBulder類,而AbtractStringBuilder又實現了CharSequence接口,兩個類都是用來進行字符串操作的。

在做字符串拼接修改刪除替換時,效率比string更高。

StringBuffer是線程安全的,Stringbuilder是非線程安全的。所以Stringbuilder比stringbuffer效率更高,StringBuffer的方法大多都加了synchronized關鍵字

36、什么是線程池?

Java中的線程池是運用場景最多的並發框架,幾乎所有需要異步或並發執行任務的程序都可以使用線程池。在開發過程中,合理地使用線程池能夠帶來許多好處。

1、 降低資源消耗。通過重復利用已創建的線程降低線程創建和銷毀造成的消耗。

2、 提高響應速度。當任務到達時,任務可以不需要等到線程創建就能立即執行。

3、 提高線程的可管理性。線程是稀缺資源,如果無限制地創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一分配、調優和監控。但是,要做到合理利用

37、JDBC操作的步驟

1、 加載數據庫驅動類

2、 打開數據庫連接

3、 執行sql語句

4、 處理返回結果

5、 關閉資源

38、說一下 JVM 調優的工具?

常用調優工具分為兩類,jdk自帶監控工具:jconsole和jvisualvm,第三方有:MAT(Memory AnalyzerTool)、GChisto。

jconsole,Java Monitoring and Management Console是從java5開始,在JDK中自帶的java監控和管理控制台,用於對JVM中內存, 線程和類等的監控。jvisualvm,jdk自帶全能工具,可以分析內存快照、線程快照;監控內存變化、GC變化等。MAT,Memory Analyzer Tool,一個基於Eclipse的內存分析工具,是一個快速、功能豐富的Javaheap分析工具,它可以幫助我們查找內存泄漏和減少內存消耗。GChisto,一款專業分析gc日志的工具。

39、JVM 提供的常用工具

jps:

用來顯示本地的 Java 進程,可以查看本地運行着幾個 Java 程序,並顯示他們的進程號。 命令格式:jps

jinfo:

運行環境參數:Java System 屬性和 JVM 命令行參數,Java class path 等信息。 命令格式:jinfo 進程 pid

jstat:

監視虛擬機各種運行狀態信息的命令行工具。 命令格式:jstat -gc 123 250 20

jstack:

可以觀察到 JVM 中當前所有線程的運行情況和線程當前狀態。 命令格式:jstack 進程 pid

jmap:

觀察運行中的 JVM 物理內存的占用情況(如:產生哪些對象,及其數量)。 命令格式:jmap [option] pid

40、SynchronizedMap和ConcurrentHashMap有什么區別?

SynchronizedMap一次鎖住整張表來保證線程安全,所以每次只能有一個線程來訪為map。

1、 ConcurrentHashMap使用分段鎖來保證在多線程下的性能。ConcurrentHashMap中則是一次鎖住一個桶。ConcurrentHashMap默認將hash表分為16個桶,諸如get,put,remove等常用操作只鎖當前需要用到的桶。這樣,原來只能一個線程進入,現在卻能同時有16個寫線程執行,並發性能的提升是顯而易見的。

2、 另外ConcurrentHashMap使用了一種不同的迭代方式。在這種迭代方式中,當iterator被創建后集合再發生改變就不再是拋出ConcurrentModificationException,取而代之的是在改變時new新的數據從而不影響原有的數據 ,iterator完成后再將頭指針替換為新的數據 ,這樣iterator線程可以使用原來老的數據,而寫線程也可以並發的完成改變。

更多 Java 面試題 70道

01、java中有幾種方法可以實現一個線程?

02、Java 中的 HashSet,內部是如何工作的?

03、redux的工作流程?

04、String類的常用方法有那些?

05、請你談談對OOM的認識

06、ParNew 垃圾收集器(Serial+多線程)

07、Java 中如何格式化一個日期?如格式化為 ddMMyyyy 的形式?

08、什么是Java虛擬機

09、Java 中的同步集合與並發集合有什么區別?

10、適配器模式和代理模式之前有什么不同?

11、說說G1垃圾收集器的工作原理

12、JRE、JDK、JVM 及 JIT 之間有什么不同?

13、當父類引用指向子類對象的時候,子類重寫了父類方法和屬性,那么當訪問屬性的時候,訪問是誰的屬性?調用方法時,調用的是誰的方法?

14、堆溢出的原因?

15、說一下 runnable 和 callable 有什么區別

16、JVM 類加載機制

17、怎么打破雙親委派模型?

18、垃圾收集算法

19、你有哪些手段來排查 OOM 的問題?

20、假設把實例化的數組的變量當成方法參數,當方法執行的時候改變了數組內的元素,那么在方法外,數組元素有發生改變嗎?

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死鎖以及如何避免?

 

如果不背 Java面試題的答案,肯定面試會掛!

這套Java面試題大全,希望對大家有幫助哈~

博主已將以下這些面試題整理成了一個Java面試手冊,是PDF版的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM