面試208題:四類核心考點(diǎn)與追問鏈答題技巧)
簡(jiǎn)介這是一份面向Java初學(xué)者與應(yīng)屆培訓(xùn)生的面試復(fù)習(xí)文檔圍繞初級(jí)崗位常見考點(diǎn)整理出208道試題并附參考答案幫助缺乏項(xiàng)目經(jīng)驗(yàn)的求職者快速建立知識(shí)框架、應(yīng)對(duì)技術(shù)面試。資源為單個(gè)docx文件壓縮包約155KB內(nèi)容按十八個(gè)模塊編排涵蓋Java基礎(chǔ)、多線程、反射、對(duì)象拷貝、JavaWeb、異常、網(wǎng)絡(luò)、設(shè)計(jì)模式、Spring/Spring MVC、Spring Boot/SpringCloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis與JVM等方向。其中Java基礎(chǔ)部分對(duì)JDK與JRE的區(qū)別、與equals的差異、hashCode與equals的關(guān)系、final關(guān)鍵字作用、Math.round取值規(guī)則等高頻題給出了代碼示例與逐行解讀便于理解底層原理。目前已有620人學(xué)習(xí)適合作為面試前的速查清單與知識(shí)點(diǎn)查漏補(bǔ)缺之用。1. 初級(jí) Java 崗面試208 道題里真正拉開差距的只有這四類初級(jí) Java 面試有個(gè)反直覺的地方面試官手里那張題庫和你背的那份往往不是同一套。你背了 208 道他可能只問 12 道但這 12 道里有一半會(huì)順著你的回答往下追。真正拉開差距的不是你背了多少而是你能不能在被追問時(shí)穩(wěn)住。這份 Java 初級(jí)面試題匯總按十八個(gè)模塊拆開從 Java 基礎(chǔ)、多線程、反射、對(duì)象拷貝一路鋪到 JavaWeb、異常、網(wǎng)絡(luò)、設(shè)計(jì)模式再到 Spring/Spring MVC、Spring Boot/SpringCloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM一共 208 道。它面向的是剛從學(xué)校出來或者剛培訓(xùn)出來的 Java 人員所以題目難度壓在初級(jí)區(qū)間但覆蓋面鋪得很寬。問題也在這里覆蓋面寬不等于每道都要背到一字不差。初級(jí)崗面試的評(píng)分邏輯是「基礎(chǔ)題不能錯(cuò)進(jìn)階題能說個(gè)大概場(chǎng)景題能接住追問」。下面按考點(diǎn)分布、高頻模塊、易錯(cuò)點(diǎn)、答題技巧四層往下拆你照著練就行。2. 考點(diǎn)分布十八個(gè)模塊里哪幾個(gè)決定你能不能過2.1 先看清分值地圖別把時(shí)間平攤十八個(gè)模塊聽起來嚇人但初級(jí)崗面試的時(shí)間分配極不均勻。按實(shí)際面試出現(xiàn)頻率排Java 基礎(chǔ)、多線程、集合、異常這四塊能占到一半以上的提問量Spring/Spring MVC、MySQL、Redis 再占掉兩成剩下的反射、對(duì)象拷貝、JavaWeb、網(wǎng)絡(luò)、設(shè)計(jì)模式、消息隊(duì)列、Zookeeper、JVM 屬于「問到就答答不上來不致命」的區(qū)間。所以備考順序不是從模塊一背到模塊十八而是先把 Java 基礎(chǔ)和多線程吃透再補(bǔ) Spring 和數(shù)據(jù)庫最后掃一遍邊角模塊。下面這張表幫你判斷每個(gè)模塊該投入多少精力。模塊面試出現(xiàn)頻率建議投入典型問法Java 基礎(chǔ)極高精背 能寫代碼 和 equals、String 類、抽象類與接口多線程極高精背 理解原理線程創(chuàng)建、線程池、synchronized、死鎖集合高精背 對(duì)比記憶HashMap 原理、ArrayList 與 LinkedList異常高理解分類受檢與非受檢、try-catch-finallySpring/Spring MVC高理解流程IOC、AOP、請(qǐng)求處理流程MySQL高理解 會(huì)寫 SQL索引、事務(wù)、鎖Redis中高理解場(chǎng)景數(shù)據(jù)類型、緩存穿透、持久化反射、對(duì)象拷貝中知道概念反射機(jī)制、淺拷貝與深拷貝JavaWeb、網(wǎng)絡(luò)中知道概念HTTP、TCP、Servlet 生命周期設(shè)計(jì)模式中記住幾個(gè)常用的單例、工廠、代理消息隊(duì)列、Zookeeper低知道用途解耦、削峰、分布式協(xié)調(diào)JVM中理解內(nèi)存結(jié)構(gòu)內(nèi)存區(qū)域、GC、類加載這張表的意思是如果你的準(zhǔn)備時(shí)間只有兩周前四行必須滾瓜爛熟中間幾行能說出關(guān)鍵詞最后幾行知道它是干什么的就行。面試官不會(huì)因?yàn)槟阏f不清 Zookeeper 的選舉算法就否定你但會(huì)因?yàn)槟阏f錯(cuò) HashMap 的擴(kuò)容機(jī)制而皺眉。2.2 真題演練基礎(chǔ)模塊的三道必考題題一JDK 和 JRE 有什么區(qū)別這題看著簡(jiǎn)單但很多人答得含糊。答題思路是分三層說第一層說全稱和定位JDK 是 Java Development Kit開發(fā)工具包提供開發(fā)和運(yùn)行環(huán)境JRE 是 Java Runtime Environment運(yùn)行環(huán)境只負(fù)責(zé)運(yùn)行。第二層說包含關(guān)系JDK 里面包含了 JRE同時(shí)還帶了編譯器 javac 以及一堆調(diào)試分析工具。第三層落到使用場(chǎng)景只運(yùn)行 Java 程序裝 JRE 就夠要寫 Java 程序必須裝 JDK。面試官最想聽的是第三層因?yàn)榍皟蓪诱l都會(huì)背能說清「什么時(shí)候用哪個(gè)」才說明你真理解。題二 和 equals 的區(qū)別是什么這題必須分基本類型和引用類型說混在一起說就是翻車現(xiàn)場(chǎng)?;绢愋陀? 比較的是值是否相同引用類型用 比較的是引用是否指向同一個(gè)對(duì)象。equals 默認(rèn)情況下就是 但 String、Integer 這些類重寫了 equals把它變成了值比較。能配上代碼說更好String x string; String y string; String z new String(string); System.out.println(x y); // true指向常量池同一引用 System.out.println(x z); // falsenew 開辟了新堆內(nèi)存 System.out.println(x.equals(y)); // true值相同 System.out.println(x.equals(z)); // true值相同代碼后面的解讀要跟上x 和 y 都指向常量池里的同一個(gè)對(duì)象所以 為 truez 通過 new 在堆上開了新空間引用不同所以 為 falseequals 被 String 重寫成值比較所以兩個(gè)都是 true。這段代碼加解讀基本能拿滿分。題三兩個(gè)對(duì)象的 hashCode() 相同equals() 也一定為 true 嗎答案是「不一定」。這題考的是你對(duì)散列表的理解。hashCode 相同只說明兩個(gè)鍵值對(duì)的哈希值相等但哈希值相等不代表對(duì)象相等。經(jīng)典例子是「通話」和「重地」這兩個(gè)字符串它們的 hashCode 都是 1179395但 equals 返回 false。答題時(shí)補(bǔ)一句反過來如果 equals 為 truehashCode 一定相同這是重寫 equals 時(shí)必須遵守的約定。能說出這個(gè)反向約定面試官會(huì)覺得你基礎(chǔ)扎實(shí)。3. 多線程高頻考點(diǎn)線程池、鎖升級(jí)、死鎖三道硬菜3.1 線程池七種創(chuàng)建方式核心只有一種多線程模塊里線程池是必問的。這份題庫列了七種創(chuàng)建方式newSingleThreadExecutor、newCachedThreadPool、newFixedThreadPool、newSingleThreadScheduledExecutor、newScheduledThreadPool、newWorkStealingPool以及最原始的 ThreadPoolExecutor。前六種都是對(duì) ThreadPoolExecutor 的封裝所以答題時(shí)先說這句再展開各自特點(diǎn)。newSingleThreadExecutor 工作線程數(shù)為 1保證任務(wù)順序執(zhí)行newCachedThreadPool 處理大量短時(shí)任務(wù)線程閑置超過 60 秒就回收內(nèi)部用 SynchronousQueuenewFixedThreadPool 固定線程數(shù)超出任務(wù)在無界隊(duì)列等待newScheduledThreadPool 支持定時(shí)和周期調(diào)度newWorkStealingPool 是 Java 8 加入的內(nèi)部構(gòu)建 ForkJoinPool用 Work-Stealing 算法并行處理不保證順序。面試官追問「為什么阿里規(guī)范不建議用 Executors 創(chuàng)建線程池」你要能接住newFixedThreadPool 和 newSingleThreadExecutor 用的是無界隊(duì)列任務(wù)堆積可能撐爆內(nèi)存newCachedThreadPool 最大線程數(shù)是 Integer.MAX_VALUE可能創(chuàng)建過多線程。所以生產(chǎn)環(huán)境推薦直接 new ThreadPoolExecutor自己指定核心參數(shù)。3.2 真題演練synchronized 鎖升級(jí)和死鎖題一synchronized 鎖升級(jí)的原理是什么這題屬于多線程里的進(jìn)階題初級(jí)崗問到就算加分。答題思路按「對(duì)象頭 → 偏向鎖 → 輕量級(jí)鎖 → 重量級(jí)鎖」的順序說。鎖對(duì)象的對(duì)象頭里有個(gè) threadid 字段。第一次訪問時(shí) threadid 為空J(rèn)VM 讓它持有偏向鎖并把 threadid 設(shè)為該線程 id。再次進(jìn)入時(shí)先判斷 threadid 是否一致一致就直接用不一致就把偏向鎖升級(jí)為輕量級(jí)鎖通過自旋循環(huán)一定次數(shù)獲取鎖。自旋若干次還沒拿到就升級(jí)為重量級(jí)鎖。最后補(bǔ)一句鎖升級(jí)的目的Java 6 之后用這種方式優(yōu)化 synchronized降低鎖帶來的性能消耗。這句話是得分點(diǎn)說明你知道「為什么要有鎖升級(jí)」。題二什么是死鎖怎么防止死鎖死鎖的定義要說得具體線程 A 持有獨(dú)占鎖 a嘗試獲取獨(dú)占鎖 b線程 B 持有獨(dú)占鎖 b嘗試獲取獨(dú)占鎖 a雙方互相持有對(duì)方需要的鎖形成阻塞這就是死鎖。防止死鎖的方法題庫給了四條用 tryLock 設(shè)置超時(shí)時(shí)間超時(shí)退出用 java.util.concurrent 并發(fā)類代替手寫鎖降低鎖的使用粒度不要幾個(gè)功能共用一把鎖減少同步代碼塊的范圍。答題時(shí)可以把這四條歸納成兩個(gè)方向一是破壞「請(qǐng)求與保持」條件用超時(shí)機(jī)制二是破壞「循環(huán)等待」條件降低鎖粒度、避免嵌套加鎖。能歸納出方向比單純背四條更有說服力。3.3 真題演練sleep 和 wait、run 和 start題一sleep() 和 wait() 有什么區(qū)別三個(gè)維度說清楚。類的不同sleep 來自 Threadwait 來自 Object。釋放鎖sleep 不釋放鎖wait 釋放鎖。用法不同sleep 時(shí)間到自動(dòng)恢復(fù)wait 需要用 notify 或 notifyAll 喚醒。這題最容易錯(cuò)的是「釋放鎖」這一條很多人記反。記住一個(gè)口訣wait 是等別人叫醒所以得先把鎖讓出來sleep 是睡一會(huì)兒鎖還攥在手里。題二線程的 run() 和 start() 有什么區(qū)別start() 用于啟動(dòng)線程run() 用于執(zhí)行線程的運(yùn)行時(shí)代碼。run() 可以重復(fù)調(diào)用start() 只能調(diào)用一次。追問「為什么 start 只能調(diào)一次」答調(diào)用 start 后線程進(jìn)入就緒狀態(tài)再由 JVM 調(diào)度執(zhí)行 run重復(fù)調(diào)用會(huì)拋 IllegalThreadStateException。4. 集合與 Spring 模塊HashMap 原理和 IOC 是兩道分水嶺4.1 HashMap 實(shí)現(xiàn)原理答到紅黑樹才算完整HashMap 是集合模塊的核心考點(diǎn)。答題按「put 流程 → hash 沖突 → 鏈表轉(zhuǎn)紅黑樹」的順序說。通過 put(key, value) 存儲(chǔ)get(key) 獲取。傳入 key 時(shí)HashMap 根據(jù) key.hashCode() 計(jì)算 hash 值根據(jù) hash 值把 value 存到 bucket 里。hash 值相同時(shí)叫 hash 沖突HashMap 用鏈表和紅黑樹存儲(chǔ)相同 hash 值的 value。沖突個(gè)數(shù)少時(shí)用鏈表多時(shí)用紅黑樹。面試官可能追問「鏈表轉(zhuǎn)紅黑樹的閾值是多少」答 8「紅黑樹轉(zhuǎn)回鏈表的閾值」答 6。這兩個(gè)數(shù)字能說出來說明你不是只背了概念。配套的對(duì)比題也要準(zhǔn)備HashMap 和 Hashtable 的區(qū)別存儲(chǔ)上 HashMap 允許 key 和 value 為 nullHashtable 不允許線程安全上 Hashtable 安全HashMap 不安全推薦使用上Hashtable 是保留類不建議用單線程用 HashMap多線程用 ConcurrentHashMap。4.2 真題演練ArrayList 與 LinkedList、Iterator題一ArrayList 和 LinkedList 的區(qū)別是什么從三個(gè)維度答。數(shù)據(jù)結(jié)構(gòu)ArrayList 是動(dòng)態(tài)數(shù)組LinkedList 是雙向鏈表。隨機(jī)訪問ArrayList 效率高LinkedList 要移動(dòng)指針從頭找。增刪效率非首尾的增刪LinkedList 比 ArrayList 高因?yàn)?ArrayList 增刪要影響數(shù)組內(nèi)其他元素的下標(biāo)。最后給結(jié)論頻繁讀取用 ArrayList插入刪除多用 LinkedList。這個(gè)結(jié)論是面試官想聽的落地判斷。題二Iterator 怎么使用有什么特點(diǎn)先給代碼ListString list new ArrayList(); IteratorString it list.iterator(); while (it.hasNext()) { String obj it.next(); System.out.println(obj); }然后說特點(diǎn)Iterator 更安全因?yàn)楫?dāng)前遍歷的集合元素被更改時(shí)會(huì)拋 ConcurrentModificationException。追問「為什么用 Iterator 遍歷時(shí)刪除元素會(huì)拋異?!勾餓terator 內(nèi)部維護(hù)了一個(gè) modCount集合結(jié)構(gòu)變化時(shí) modCount 改變Iterator 檢查到不一致就拋異常。正確做法是用 Iterator 自己的 remove 方法。4.3 Spring 模塊IOC 和 AOP 要能舉例Spring/Spring MVC 是初級(jí)崗的高頻模塊。IOC 和 AOP 兩個(gè)概念必須能說清楚還要能舉例子。IOC 是控制反轉(zhuǎn)把對(duì)象的創(chuàng)建和依賴管理交給容器你不需要自己 new 對(duì)象容器幫你注入。舉例Service 里需要 Dao不用自己 new DaoImpl加個(gè)注解容器就注入了。AOP 是面向切面編程把日志、事務(wù)這些橫切邏輯從業(yè)務(wù)代碼里抽出來通過代理在方法前后織入。舉例事務(wù)管理不用在每個(gè)方法里寫開啟和提交事務(wù)加個(gè)注解就行。Spring MVC 的請(qǐng)求處理流程也常問請(qǐng)求到 DispatcherServlet它查 HandlerMapping 找到對(duì)應(yīng) ControllerController 處理完返回 ModelAndViewViewResolver 解析視圖最后渲染返回。這個(gè)流程能按順序說下來就行不用背類名全稱。5. 易錯(cuò)點(diǎn)這五道題初級(jí)崗最容易答錯(cuò)5.1 錯(cuò)在哪Math.round(-1.5) 答成 -2很多人按「四舍五入」的直覺答 -2實(shí)際答案是 -1。錯(cuò)在沒理解 round 的規(guī)則數(shù)軸上取值時(shí)中間值 0.5 向右取整所以正 0.5 往上取整負(fù) 0.5 直接舍棄。正確答法是先說答案 -1再解釋「向右取整」這個(gè)規(guī)則。這題考的是你有沒有真的跑過代碼而不是憑感覺。5.2 錯(cuò)在哪抽象類必須有抽象方法很多人以為抽象類里必須有抽象方法實(shí)際不需要。抽象類可以一個(gè)抽象方法都沒有照樣正常運(yùn)行。錯(cuò)在把「抽象類」和「有抽象方法」畫了等號(hào)。正確答法抽象類不一定有抽象方法但有抽象方法的類一定是抽象類。再補(bǔ)一句 final 不能修飾抽象類因?yàn)槌橄箢惥褪怯脕肀焕^承的final 讓它不能被繼承兩者矛盾。5.3 錯(cuò)在哪String 是基礎(chǔ)數(shù)據(jù)類型String 不是基礎(chǔ)類型?;A(chǔ)類型只有 8 種byte、boolean、char、short、int、float、long、double。String 是對(duì)象。這題錯(cuò)在概念混淆答錯(cuò)會(huì)顯得基礎(chǔ)不牢。正確答法直接說「String 不屬于基礎(chǔ)類型它是對(duì)象」然后把 8 種基礎(chǔ)類型報(bào)一遍。5.4 錯(cuò)在哪poll() 和 remove() 答反Queue 里 poll() 和 remove() 都是返回第一個(gè)元素并刪除區(qū)別在沒元素時(shí)的行為poll() 返回 nullremove() 拋 NoSuchElementException。很多人記反或者只記得「都是刪除」就說沒區(qū)別。正確答法先說相同點(diǎn)再說不同點(diǎn)最后補(bǔ)一句「所以不確定隊(duì)列是否為空時(shí)用 poll 更安全」。5.5 錯(cuò)在哪volatile 能保證原子性volatile 只保證可見性不保證原子性。synchronized 既保證可見性又保證原子性。這題錯(cuò)在把 volatile 的作用夸大了。正確答法volatile 是變量修飾符synchronized 修飾類、方法、代碼段volatile 僅實(shí)現(xiàn)變量修改的可見性不能保證原子性volatile 不會(huì)造成線程阻塞synchronized 可能阻塞。三條對(duì)比說完再補(bǔ)一句「所以 i 這種復(fù)合操作用 volatile 修飾也不安全」。6. 答題技巧初級(jí)崗面試怎么把 208 道題用出最大效果6.1 背題不如背「追問鏈」208 道題如果一道一道背背到第 100 道前面的就忘了。更高效的做法是背「追問鏈」每道題準(zhǔn)備兩層追問。比如背 和 equals就要準(zhǔn)備好「String 為什么重寫 equals」「重寫 equals 為什么必須重寫 hashCode」「hashCode 相同 equals 一定相同嗎」這三個(gè)追問。面試官問第一層你答完主動(dòng)帶一句「這里還涉及 hashCode 的約定」他就順著問了而你已經(jīng)準(zhǔn)備好了。6.2 用「三層答題法」控制節(jié)奏每道題按三層答第一層給結(jié)論第二層說原因第三層舉例子或說場(chǎng)景。比如問線程池創(chuàng)建方式第一層說「核心是 ThreadPoolExecutor其他六種都是它的封裝」第二層說「各自的特點(diǎn)和適用場(chǎng)景」第三層說「生產(chǎn)環(huán)境推薦自己 new ThreadPoolExecutor因?yàn)?Executors 的默認(rèn)隊(duì)列可能撐爆內(nèi)存」。三層答完就停不要一口氣把所有知道的都倒出來。留空間給面試官追問追問是你展示深度的機(jī)會(huì)。6.3 代碼題要能手寫關(guān)鍵片段初級(jí)崗面試經(jīng)常讓你手寫代碼高頻的有字符串反轉(zhuǎn)、單例模式、生產(chǎn)者消費(fèi)者、冒泡排序。字符串反轉(zhuǎn)用 StringBuilder 的 reverse 方法StringBuilder sb new StringBuilder(); sb.append(abcdefg); System.out.println(sb.reverse()); // gfedcba單例模式寫雙重檢查鎖public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance null) { synchronized (Singleton.class) { if (instance null) { instance new Singleton(); } } } return instance; } }注意 volatile 不能省它防止指令重排導(dǎo)致其他線程拿到未初始化完的對(duì)象。這個(gè)點(diǎn)能說出來是加分項(xiàng)。6.4 押題思路把十八個(gè)模塊壓成三張紙最后一周不要再翻 208 道題把它壓成三張紙。第一張寫 Java 基礎(chǔ)和多線程的核心概念對(duì)比比如 與 equals、sleep 與 wait、synchronized 與 Lock、ArrayList 與 LinkedList。第二張寫框架和數(shù)據(jù)庫的關(guān)鍵流程比如 Spring IOC、AOP、Spring MVC 請(qǐng)求流程、MySQL 索引和事務(wù)。第三張寫邊角模塊的關(guān)鍵詞比如反射的三種獲取 Class 方式、淺拷貝與深拷貝、BIO/NIO/AIO 區(qū)別、設(shè)計(jì)模式的單例和工廠。三張紙過一遍能說出來的就過說不出來的標(biāo)記出來重點(diǎn)看。面試前一天只看標(biāo)記的。我當(dāng)年第一次面初級(jí)崗把 208 道題從頭背到尾結(jié)果面試官問「HashMap 擴(kuò)容為什么是 2 倍」我卡住了因?yàn)轭}庫里沒寫。從那以后我每次準(zhǔn)備面試都強(qiáng)制走一遍「追問鏈」每道題至少準(zhǔn)備兩層追問答完第一層主動(dòng)往第二層引。這個(gè)習(xí)慣讓我后來再?zèng)]在基礎(chǔ)題上翻過車。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取