一、JVM:面試中的 “基礎門檻”

JVM 是 Java 跨平台特性的核心,也是面試中最易拉開差距的模塊。面試官不僅會考察理論知識,更會結合 “內存溢出排查”“性能優化” 等實際場景提問。

1.1 核心考點:JVM 內存模型(JDK 8+)

JDK 8 取消了永久代,引入元空間(Metaspace),內存模型主要分為以下區域,需重點區分 “線程私有” 與 “線程共享”:

  • 線程私有區域(隨線程創建 / 銷燬):
  • 程序計數器:記錄當前線程執行字節碼的行號,唯一不會 OOM 的區域;
  • 虛擬機棧:存儲方法調用的棧幀(局部變量表、操作數棧等),棧深度不足會拋StackOverflowError,內存不足會拋OutOfMemoryError;
  • 本地方法棧:與虛擬機棧類似,為 Native 方法服務。
  • 線程共享區域(整個 JVM 進程共享):
  • 堆(Heap):存儲對象實例,垃圾回收(GC)的核心區域,分為年輕代(Eden + Survivor)和老年代;
  • 元空間(Metaspace):存儲類元信息(類結構、方法信息等),默認使用本地內存,避免了永久代 OOM 問題。

面試高頻問題:“JDK 8 為什麼取消永久代,改用元空間?”

參考回答:① 永久代大小難確定,容易因類加載過多導致 OOM;② 元空間使用本地內存,可動態擴展,減少內存溢出風險;③ 便於 HotSpot 與其他 JVM(如 JRockit)融合。

1.2 垃圾回收(GC):從 “理論” 到 “實戰”

GC 是 JVM 面試的重中之重,需掌握 “回收算法”“垃圾收集器”“GC 日誌分析” 三大模塊。

(1)垃圾判定算法

  • 引用計數法:通過對象引用數判斷是否可回收,無法解決循環引用問題(如 A 引用 B,B 引用 A);
  • 可達性分析:以 “GC Roots”(如虛擬機棧引用的對象、靜態變量引用的對象)為起點,遍歷對象引用鏈,不可達的對象標記為可回收。

(2)常見垃圾收集器(JDK 8 + 主流)

需明確不同收集器的適用場景,避免死記硬背:

收集器

適用區域

特點

適用場景

Serial

年輕代

單線程回收,暫停時間長

客户端應用、小型程序

Parallel Scavenge

年輕代

多線程回收,追求高吞吐量

服務器端批量處理任務

CMS(Concurrent Mark Sweep)

老年代

併發回收,低暫停時間

互聯網應用(如 Web 服務)

G1(Garbage-First)

整堆

分區回收,兼顧吞吐量與低延遲

大內存場景(如 16G + 堆內存)

面試高頻問題:“CMS 收集器的工作流程,以及可能出現的問題?”

參考回答:流程分為 4 步:① 初始標記(STW,標記 GC Roots 直接引用的對象);② 併發標記(與用户線程並行,遍歷引用鏈);③ 重新標記(STW,修正併發標記的偏差);④ 併發清除(與用户線程並行,回收垃圾)。

可能問題:① 併發清除階段產生 “浮動垃圾”(新生成的垃圾無法回收);② 內存碎片(標記 - 清除算法導致,需通過 “CMS Full GC” 整理碎片,暫停時間長)。

(3)GC 實戰:內存溢出排查

面試官常問 “如何排查 OOM 問題”,需掌握工具與流程:

  1. 開啓 JVM 參數:添加-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heapdump.hprof,OOM 時自動生成堆轉儲文件;
  2. 分析工具:使用 JDK 自帶的jhat或可視化工具(如 MAT、VisualVM),查看對象引用鏈,定位內存泄漏點(如靜態集合未清理、線程池核心線程持有大對象);
  3. 常見場景:① ArrayList 無限添加元素導致堆 OOM;② 遞歸調用過深導致棧 OOM;③ 類加載過多(如動態生成類)導致元空間 OOM。

二、集合框架:從 “使用” 到 “原理”

集合框架是 Java 開發的基礎,面試中不僅會考察 API 使用,更會深入底層數據結構與源碼實現(如 HashMap、ConcurrentHashMap)。

2.1 核心集合體系

需明確 Collection 與 Map 兩大接口的繼承關係,避免混淆:

  • Collection:存儲單值元素,主要子類包括 List(有序、可重複)、Set(無序、不可重複)、Queue(隊列,FIFO);
  • Map:存儲鍵值對(Key-Value),主要實現類包括 HashMap、TreeMap、ConcurrentHashMap。

2.2 高頻考點:HashMap(JDK 8)

HashMap 是面試中 “必問” 知識點,需掌握數據結構、擴容機制、線程安全性三大核心。

(1)底層數據結構

JDK 8 中,HashMap 採用 “數組 + 鏈表 + 紅黑樹” 的結構:

  • 數組(哈希桶):存儲鏈表 / 紅黑樹的頭節點,數組長度默認 16(必須是 2 的冪,便於通過(n-1)&hash計算索引);
  • 鏈表:當哈希衝突時,元素以鏈表形式存儲,鏈表長度超過 8 且數組長度≥64 時,轉為紅黑樹(提升查詢效率,從 O (n) 到 O (logn));
  • 紅黑樹:當鏈表長度小於 6 時,紅黑樹轉回鏈表(避免紅黑樹維護成本過高)。

(2)擴容機制

  • 觸發條件:當元素數量(size)超過 “負載因子(默認 0.75)× 數組長度” 時,觸發擴容,數組長度翻倍;
  • 擴容核心:重新計算每個元素的哈希索引((newCap -1)&hash),並遷移元素(JDK 8 優化了遷移邏輯,避免重複計算哈希)。

(3)線程安全性

HashMap 線程不安全,併發場景下可能出現 “鏈表環”(JDK 7)或數據覆蓋問題。解決方式:

  • 替換為ConcurrentHashMap(JDK 8 使用 CAS+synchronized 實現,效率高於 JDK 7 的分段鎖);
  • 使用Collections.synchronizedMap(new HashMap<>())(全局鎖,效率低)。

面試高頻問題:“JDK 7 與 JDK 8 中 HashMap 的區別?”

參考回答:① 數據結構:JDK 7 是 “數組 + 鏈表”,JDK 8 是 “數組 + 鏈表 + 紅黑樹”;② 哈希計算:JDK 7 多次擾動哈希(減少衝突),JDK 8 簡化為 “hashCode ^ (hashCode >>> 16)”;③ 擴容遷移:JDK 7 頭插法(易產生鏈表環),JDK 8 尾插法(避免環);④ 初始化:JDK 7 在構造函數中初始化數組,JDK 8 在第一次 put 時初始化。

三、併發編程:面試中的 “難點與重點”

併發編程是 Java 後端開發的核心能力,面試官會圍繞 “線程池、鎖機制、併發容器” 展開,考察候選人對多線程問題的理解與解決能力。

3.1 線程池:從 “參數” 到 “實戰選型”

線程池是併發編程的 “利器”,也是面試高頻考點,需掌握 “核心參數、工作原理、拒絕策略”。

(1)核心參數(ThreadPoolExecutor)

public ThreadPoolExecutor(

int corePoolSize, // 核心線程數(常駐線程)

int maximumPoolSize, // 最大線程數(核心+臨時線程)

long keepAliveTime, // 臨時線程空閒時間

TimeUnit unit, // 時間單位

BlockingQueue<Runnable> workQueue, // 任務隊列

ThreadFactory threadFactory, // 線程工廠(自定義線程名)

RejectedExecutionHandler handler // 拒絕策略

)

(2)工作原理

  1. 提交任務時,優先創建核心線程執行;
  2. 核心線程滿後,任務放入工作隊列;
  3. 隊列滿後,創建臨時線程執行;
  4. 臨時線程滿後,觸發拒絕策略。

(3)拒絕策略

需根據業務場景選擇合適的拒絕策略:

  • AbortPolicy(默認):直接拋RejectedExecutionException,中斷業務;
  • CallerRunsPolicy:由提交任務的線程執行(如主線程),減緩任務提交速度;
  • DiscardPolicy:默默丟棄任務,無任何提示;
  • DiscardOldestPolicy:丟棄隊列中最舊的任務,嘗試提交新任務。

面試高頻問題:“如何設計線程池的核心參數?”

參考回答:需結合業務類型(CPU 密集型 / IO 密集型)判斷:

  • CPU 密集型(如計算任務):核心線程數 = CPU 核心數 + 1(減少線程切換開銷);
  • IO 密集型(如數據庫查詢、HTTP 請求):核心線程數 = CPU 核心數 × 2(線程大部分時間在等待 IO,可多創建線程提高利用率);
  • 隊列選擇:無界隊列(如 LinkedBlockingQueue)適合任務量穩定場景,避免拒絕;有界隊列(如 ArrayBlockingQueue)適合任務量波動大場景,防止內存溢出。

3.2 鎖機制:從 “synchronized” 到 “Lock”

鎖是解決併發安全的核心,需掌握synchronized與Lock的區別,以及 “樂觀鎖”“悲觀鎖” 的應用場景。

(1)synchronized:從 “重量級鎖” 到 “優化”

JDK 6 對synchronized進行了優化,引入 “偏向鎖、輕量級鎖、重量級鎖” 三級鎖狀態,減少性能開銷:

  • 偏向鎖:單線程場景下,避免鎖競爭,直接標記線程 ID;
  • 輕量級鎖:多線程交替執行,通過 CAS 嘗試獲取鎖,避免進入內核態;
  • 重量級鎖:多線程競爭激烈,通過操作系統互斥量(Mutex)實現,會導致線程阻塞(上下文切換開銷大)。

(2)Lock 接口(ReentrantLock)

ReentrantLock是synchronized的補充,支持更多特性:

  • 可中斷鎖:通過lockInterruptibly()中斷等待鎖的線程;
  • 可超時鎖:通過tryLock(long time, TimeUnit unit)避免無限等待;
  • 公平鎖:通過構造函數new ReentrantLock(true)實現,按線程等待順序獲取鎖(默認非公平鎖,效率更高);
  • 條件變量:通過newCondition()實現多線程間的通信(如生產者 - 消費者模型)。

面試高頻問題:“synchronized 與 ReentrantLock 的區別?”

參考回答:① 鎖實現:synchronized 是 JVM 層面的鎖(字節碼指令monitorenter/monitorexit),ReentrantLock 是 Java 層面的鎖(基於 AQS);② 特性:ReentrantLock 支持可中斷、可超時、公平鎖,synchronized 不支持;③ 釋放鎖:synchronized 自動釋放(異常或方法結束),ReentrantLock 需手動釋放(finally中調用unlock());④ 性能:JDK 6 後兩者性能接近,簡單場景用 synchronized,複雜場景用 ReentrantLock。

四、Spring 生態:後端開發的 “基石”

Spring 是 Java 後端開發的主流框架,面試中會圍繞 “Spring IoC、Spring AOP、Spring Boot、Spring Cloud” 展開,考察候選人對框架設計思想與實戰應用的理解。

4.1 Spring IoC:控制反轉與依賴注入

IoC(Inversion of Control)是 Spring 的核心思想,即 “將對象的創建與依賴管理交給 Spring 容器”,避免硬編碼耦合。

(1)依賴注入(DI)的三種方式

  • 構造器注入:通過構造函數注入依賴,強制依賴必須傳入(推薦,避免空指針);
  • Setter 注入:通過 setter 方法注入依賴,適合可選依賴;
  • 字段注入:通過@Autowired直接注入字段,代碼簡潔但不便於測試(不推薦)。

(2)Bean 的作用域與生命週期

  • 作用域:默認singleton(單例,整個容器一個實例),其他包括prototype(每次獲取新實例)、request(每個 HTTP 請求一個實例)、session(每個會話一個實例);
  • 生命週期:① 實例化(調用構造函數);② 屬性注入(設置依賴);③ 初始化(@PostConstruct或InitializingBean);④ 銷燬(@PreDestroy或DisposableBean)。

面試高頻問題:“Spring Bean 的循環依賴如何解決?”

參考回答:循環依賴指 A 依賴 B,B 依賴 A。Spring 通過 “三級緩存” 解決單例 Bean 的循環依賴:

  • 一級緩存:存儲已初始化完成的 Bean;
  • 二級緩存:存儲已實例化但未注入依賴的 Bean;
  • 三級緩存:存儲 Bean 的工廠對象(用於生成代理對象)。

流程:A 實例化後放入三級緩存,注入 B 時發現 B 未創建,B 實例化後放入三級緩存,注入 A 時從三級緩存獲取 A 的工廠對象,生成 A 的代理對象放入二級緩存,B 初始化完成後放入一級緩存,再回到 A 注入 B,A 初始化完成後放入一級緩存。

注意:prototypeBean 不支持循環依賴(每次獲取新實例,無法緩存),會拋BeanCurrentlyInCreationException。

4.2 Spring AOP:面向切面編程

AOP(Aspect-Oriented Programming)是 Spring 的另一核心,通過 “橫切關注點”(如日誌、事務、權限)的提取,實現代碼解耦。

(1)核心概念

  • 切面(Aspect):橫切關注點的封裝(如@Aspect註解的類);
  • 通知(Advice):切面的具體邏輯(如@Before、@After、@Around);
  • 連接點(JoinPoint):程序執行的某個位置(如方法調用、字段賦值);
  • 切入點(Pointcut):篩選連接點的表達式(如execution(* com.xxx.service.*.*(..)));
  • 目標對象(Target):被代理的原始對象。

(2)實現原理

Spring AOP 基於動態代理實現,分為兩種方式:

  • JDK 動態代理:基於接口,代理類實現目標接口,通過Proxy.newProxyInstance()生成代理對象;
  • CGLIB 動態代理:基於類,代理類繼承目標類,通過 ASM 字節碼框架生成代理對象。

規則:如果目標對象實現了接口,默認用 JDK 動態代理;否則用 CGLIB。可通過proxyTargetClass=true強制使用 CGLIB。

面試高頻問題:“Spring 事務的傳播機制有哪些?如何實現的?”

參考回答:事務傳播機制定義了多個事務方法嵌套調用時,事務的行為(如是否新建事務、是否加入現有事務),核心傳播機制包括:

  • REQUIRED(默認):如果當前有事務,加入;否則新建事務;
  • REQUIRES_NEW:無論當前是否有事務,都新建事務(原有事務掛起);
  • SUPPORTS:如果當前有事務,加入;否則以非事務方式執行;
  • NOT_SUPPORTED:以非事務方式執行,原有事務掛起;
  • NEVER:以非事務方式執行,存在事務則拋異常;
  • MANDATORY:必須在事務中執行,無事務則拋異常;
  • NESTED:如果當前有事務,在嵌套事務中執行(獨立提交 / 回滾);否則新建事務。

實現原理:Spring 事務基於 AOP,通過TransactionInterceptor攔截目標方法,在方法執行前開啓事務,執行後提交 / 回滾事務(異常時),底層依賴TransactionManager(如DataSourceTransactionManager)與數據庫事務(JDBC 的Connection)。

五、數據庫:從 “SQL 優化” 到 “事務隔離”

數據庫是後端開發的 “數據存儲核心”,面試中會圍繞 “SQL 優化、索引、事務隔離級別、分庫分表” 展開,考察候選人的數據存儲與性能優化能力。

5.1 索引:提升查詢效率的 “關鍵”

索引是數據庫優化的核心,需掌握 “索引類型、索引原理、失效場景”。

(1)索引類型

  • 按數據結構:B + 樹索引(InnoDB 默認,適合範圍查詢)、Hash 索引(適合等值查詢,不支持範圍)、全文索引(如 Elasticsearch 中用於文本檢索);
  • 按功能:主鍵索引(唯一且非空,InnoDB 中主鍵索引即聚簇索引)、唯一索引(值唯一,允許空)、普通索引(無約束)、聯合索引(多列組合,需遵循 “最左前綴原則”)。

(2)索引原理(InnoDB 聚簇索引)

  • InnoDB 中,聚簇索引(主鍵索引)是核心,數據與索引存儲在一起,葉節點存儲完整的行數據;非聚簇索引(如普通索引、唯一索引)的葉節點存儲主鍵值,查詢時需通過主鍵值回表查詢完整數據(即 “回表” 操作)。
    示例:若表 user 主鍵為 id,有普通索引 name,執行 select * from user where name = '張三' 時:
  • 先通過 name 索引找到對應的主鍵值 id=10;
  • 再通過 id 聚簇索引找到 id=10 對應的完整行數據。

(3)索引失效場景(面試高頻)

索引失效會導致全表掃描,需重點規避以下場景:

  • 使用函數或表達式操作索引列:如 where substring(name, 1, 1) = '張'(可用 where name like '張%' 替代);
  • 索引列使用不等於(!=、<>)、not in、is not null:會導致索引失效,轉向全表掃描;
  • 字符串未加引號:如 where name = 123(name 為字符串類型,會觸發類型轉換,導致索引失效);
  • 聯合索引不滿足最左前綴原則:如聯合索引 (name, age),查詢 where age = 20 會導致索引失效;
  • like 以 % 開頭:如 where name like '%三'(無法利用索引,若為 like '張%' 則可利用索引)。

面試高頻問題:“什麼是覆蓋索引?如何避免回表?”

解析:覆蓋索引指查詢的列均可通過索引獲取,無需回表。例如:

  • 表 user 有聯合索引 (name, age),執行 select name, age from user where name = '張三' 時,可直接通過聯合索引獲取 name 和 age,無需回表;
  • 避免回表的核心是:讓查詢的列包含在索引中(如設計合適的聯合索引),減少 “回表” 帶來的性能開銷。

5.2 SQL 優化:從 “慢查詢” 到 “高效執行”

SQL 優化是數據庫面試的核心,需掌握 “慢查詢分析流程”“優化技巧” 兩大模塊。

(1)慢查詢分析流程

  • 開啓慢查詢日誌:在 MySQL 配置文件中添加 slow_query_log = 1(開啓慢查詢)、long_query_time = 1(執行時間超過 1 秒的查詢記錄到日誌)、slow_query_log_file = /var/lib/mysql/slow.log(日誌存儲路徑);
  • 分析慢查詢日誌:使用工具 mysqldumpslow(如 mysqldumpslow -s c -t 10 /var/lib/mysql/slow.log,查看執行次數最多的前 10 條慢查詢)或可視化工具(如 Navicat 慢查詢分析);
  • 查看執行計劃:通過 explain 分析 SQL 執行計劃,重點關注 type(索引類型)、key(實際使用的索引)、rows(預估掃描行數)、Extra(額外信息,如 “Using index”“Using filesort”)。
  • (2)SQL 優化核心技巧
  • 優化查詢語句:避免 select *(只查詢需要的列,便於利用覆蓋索引)、拆分複雜查詢(如將多表關聯的大查詢拆分為多個小查詢);
  • 優化表結構:合理設計字段類型(如用 int 代替 varchar 存儲 ID、用 datetime 代替 varchar 存儲時間)、避免冗餘字段(通過關聯查詢獲取數據,減少數據不一致風險);
  • 優化索引:刪除冗餘索引(如聯合索引 (name, age) 已包含 name 單列索引的功能,無需重複創建 name 索引)、避免過度索引(索引會增加插入 / 更新 / 刪除的開銷);
  • 處理分頁查詢:大數據量分頁(如 limit 100000, 10)會導致全表掃描,可通過主鍵過濾優化:
-- 優化前(全表掃描,效率低)
select * from user limit 100000, 10;
-- 優化後(利用主鍵索引,效率高)
select * from user where id > 100000 limit 10;

5.3 事務隔離級別:解決 “併發一致性問題”

數據庫事務需滿足 ACID 特性(原子性、一致性、隔離性、持久性),而隔離性是解決併發場景下 “髒讀、不可重複讀、幻讀” 問題的核心。

(1)併發一致性問題

  • 髒讀:一個事務讀取到另一個事務未提交的數據(如事務 A 修改了數據但未提交,事務 B 讀取到該未提交數據,之後事務 A 回滾,事務 B 讀取的數據為 “髒數據”);
  • 不可重複讀:同一事務內,多次讀取同一數據,結果不一致(如事務 A 第一次讀取數據為 100,事務 B 修改數據為 200 並提交,事務 A 再次讀取數據為 200);
  • 幻讀:同一事務內,多次執行同一查詢,返回的結果集行數不一致(如事務 A 查詢 “age> 20” 的用户有 10 條,事務 B 插入一條 “age=25” 的用户並提交,事務 A 再次查詢 “age > 20” 的用户有 11 條)。

(2)MySQL 事務隔離級別(InnoDB 支持)

MySQL 支持 4 種隔離級別,默認隔離級別為 Repeatable Read(可重複讀),不同級別解決的一致性問題不同:

隔離級別

髒讀

不可重複讀

幻讀

實現原理

Read Uncommitted(讀未提交)

允許

允許

允許

無鎖,直接讀取數據

Read Committed(讀已提交)

禁止

允許

允許

行級鎖,讀取已提交的數據

Repeatable Read(可重複讀)

禁止

禁止

禁止

行級鎖 + MVCC(多版本併發控制)

Serializable(串行化)

禁止

禁止

禁止

表級鎖,事務串行執行,性能最低

面試高頻問題:“InnoDB 的 Repeatable Read 級別如何解決幻讀?”

參考回答:InnoDB 通過 MVCC(多版本併發控制) 解決幻讀:

  • MVCC 為每行數據添加隱藏列(DB_TRX_ID 事務 ID、DB_ROLL_PTR 回滾指針),通過回滾日誌維護數據的多個版本;
  • 事務啓動時生成一個 “Read View”(讀視圖),包含當前活躍事務的 ID 列表,查詢時只讀取 “Read View” 之前提交的版本數據;
  • 即使其他事務插入新數據並提交,當前事務的 “Read View” 未變化,查詢時仍讀取舊版本數據,從而避免幻讀。

5.4 分庫分表:解決 “大數據量存儲” 問題

當單表數據量超過 1000 萬或單庫數據量超過 100GB 時,會導致查詢緩慢、索引失效,需通過分庫分表拆分數據。

(1)分庫分表方案

  • 水平拆分(按行拆分):將同一表的數據按規則拆分到多個表 / 庫中,每個表 / 庫的結構相同。
  1. 拆分規則:按範圍(如按 id 分,1-10000 存表 1,10001-20000 存表 2)、按哈希(如 id % 4 分 4 個表)、按時間(如按月份分表,user_202401、user_202402);
  2. 適用場景:單表數據量過大,需分散存儲壓力。
  • 垂直拆分(按列拆分):將同一表的不同列拆分到多個表 / 庫中,每個表 / 庫存儲部分列數據。
  1. 拆分規則:按業務關聯性拆分(如表 user 拆分為 user_base(存儲基本信息:id、name、age)和 user_extend(存儲擴展信息:avatar、address));
  2. 適用場景:表字段過多,部分字段訪問頻率低(如 avatar 訪問頻率低,拆分後可減少查詢時的數據傳輸量)。
  3. (2)分庫分表工具
  • 客户端工具:Sharding-JDBC(輕量級,基於 JDBC 擴展,嵌入應用中,無需額外部署服務);
  • 中間件工具:MyCat(基於 Proxy 模式,獨立部署服務,應用通過 MyCat 訪問數據庫,支持更多高級特性如讀寫分離、容災)。

(3)分庫分表挑戰(面試高頻)

  • 分佈式事務:跨庫 / 跨表操作需保證事務一致性,常用方案有 2PC(兩階段提交,如 Seata AT 模式)、TCC(Try-Confirm-Cancel)、SAGA 模式;
  • 跨庫查詢:如查詢 “所有表中 age> 20 的用户”,需通過工具聚合多表結果(如 Sharding-JDBC 的聯邦查詢);
  • 全局 ID:分庫分表後需保證 ID 唯一,常用方案有 UUID(無序,不利於索引)、雪花算法(Snowflake,生成有序 ID,包含時間戳、機器 ID、序列號)、數據庫自增(如單獨用一個庫的表生成自增 ID)。

面試高頻問題:“分庫分表後,如何實現全局唯一 ID?”

參考回答:推薦使用雪花算法(Snowflake),其結構如下(64 位 Long 類型):

  • 1 位符號位:固定為 0(表示正數);
  • 41 位時間戳:記錄毫秒級時間(可使用約 69 年);
  • 10 位機器 ID:可部署 1024 台機器;
  • 12 位序列號:每台機器每秒可生成 4096 個 ID;

雪花算法生成的 ID 有序,便於索引,且無需依賴數據庫,性能高,是分庫分表中全局 ID 的首選方案。

六、面試實戰:從 “知識” 到 “落地”

掌握核心技術後,還需通過實戰演練提升面試表現,以下為高頻場景的應對策略:

6.1 項目經驗梳理:STAR 法則

面試中 “項目經驗” 是重點,需用 STAR 法則清晰表達:

  • S(Situation):項目背景(如 “為解決電商平台訂單查詢緩慢問題,需優化訂單系統”);
  • T(Task):你的任務(如 “負責訂單表分庫分表設計與實現,以及慢查詢優化”);
  • A(Action):具體行動(如 “使用 Sharding-JDBC 按訂單創建時間分表,優化 3 條慢查詢 SQL,添加 2 個聯合索引”);
  • R(Result):結果與數據(如 “訂單查詢時間從 500ms 降至 50ms 以內,支持日均 100 萬訂單存儲”)。

6.2 技術問題應對:“原理 + 場景 + 優化”

回答技術問題時,需從 “原理” 到 “實際場景” 再到 “優化方案” 展開,避免只説理論:

  • 示例:被問 “HashMap 線程不安全,如何解決?”
  1. 原理:HashMap 併發時會出現數據覆蓋(如 JDK 8)或鏈表環(JDK 7);
  2. 場景:若為高併發讀、低併發寫場景,可使用 ConcurrentHashMap;若為單線程或低併發場景,用 HashMap 即可;
  3. 優化:ConcurrentHashMap JDK 8 用 CAS+synchronized 替代 JDK 7 的分段鎖,性能更高,可優先選擇。

6.3 問題排查:“工具 + 流程 + 結論”

面試官常問 “如何排查線上問題”,需結合工具與流程回答:

  • 示例:“線上應用出現內存溢出(OOM),如何排查?”
  1. 工具:JDK 自帶 jps(查看進程 ID)、jmap(生成堆轉儲文件:jmap -dump:format=b,file=heap.hprof 12345)、MAT(分析堆文件);
  2. 流程:① 開啓 JVM 參數 -XX:+HeapDumpOnOutOfMemoryError 自動生成堆文件;② 用 MAT 打開堆文件,查看 “Leak Suspects”(內存泄漏疑點);③ 定位大對象引用鏈(如靜態集合未清理);
  3. 結論:如 “發現緩存工具類中的靜態 Map 未設置過期時間,導致對象堆積,修改為定時清理後 OOM 問題解決”。

七、總結

Java 後端面試核心圍繞 “JVM、集合框架、併發編程、Spring 生態、數據庫” 五大領域,需做到:

  • 理解原理:不僅要記住結論,更要掌握底層邏輯(如 HashMap 紅黑樹轉換的條件、Spring 三級緩存解決循環依賴的流程);
  • 結合場景:技術需落地到實際場景(如線程池參數設計需區分 CPU 密集型與 IO 密集型);
  • 實戰能力:掌握問題排查工具與流程(如 GC 日誌分析、慢查詢優化、OOM 排查);