
每年到八九月校招和跳槽窗口期后臺就會收到大量私信Java 后端技術棧這么多到底怎么復習網(wǎng)上八股文資料滿天飛東看一眼西看一眼最后腦中一片空白。一邊是面試官連環(huán)追問底層原理一邊是項目深挖、場景設計題有些人面了十幾家永遠掛在二面、三面。與其焦慮不如把復習變成一條清晰的主線。本文結合 2025、2026 屆面試高頻題目和主流后端崗位 JD整理了一份適合 7 天沖刺的 Java 后端高頻八股文復習路線。內(nèi)容覆蓋 Java 基礎、JVM、并發(fā)、Spring、MySQL、Redis、Kafka、分布式基礎每個考點拆出面試官真正想聽的“回答錨點”并附帶可落地的代碼示例和排查思路。不管你是在校準備秋招還是工作幾年想跳槽這篇都能幫你快速建立知識框架避免在基礎題上翻車。1. 面試的本質與八股文復習策略1.1 為什么后端面試總愛問“八股文”不少同學一看到“八股文”三個字就開始皺眉。但這里要糾正一個認知后端面試問八股文不是考察背誦能力而是考察知識的體系化和原理理解程度。Java 后端開發(fā)依賴大量基礎設施JVM 運行時、Spring 容器、MySQL 事務、Redis 緩存、消息隊列……這些技術都有復雜度上限。在實際開發(fā)中你可以通過框架和中間件屏蔽細節(jié)但一旦遇到性能問題、線上故障、架構選型就需要你真正理解底層機制。面試官問八股文本質上是在快速驗證一件事你寫代碼時是只知道 API還是理解 API 背后的設計思想你排查問題時是瞎猜瞎試還是能根據(jù)內(nèi)存模型、事務日志、IO 模型定位你做技術選型時是隨大流還是能說出不同中間件的優(yōu)缺點所以八股文要背但不能死背。每道題背后都有“為什么這樣設計”的主線找到這條主線整張技術地圖就通了。1.2 7天沖刺的總體思路7 天時間有限不能按兩千頁的書從頭翻到尾。建議采用“高頻考點 回答錨點 代碼演示 項目串聯(lián)”四個步驟高頻考點只復習面試中出現(xiàn)頻率最高的知識點低頻率冷門知識先跳過?;卮疱^點每道題提煉 2 到 3 個核心關鍵詞先講結論再展開細節(jié)。代碼演示八股文不只靠嘴說手寫 HashMap 原理、手寫線程池、手寫單例都是常見環(huán)節(jié)。項目串聯(lián)把背過的原理映射到你簡歷項目里面試官追問“你項目里遇到這個場景怎么處理”時才能講出深度。文章后面每一章的“回答思路”都可以直接作為你面試表達時的提綱。2. 復習環(huán)境與工具準備2.1 需要準備什么資料面試沖刺階段不建議只收藏不閱讀。建議準備以下資料資料類型推薦方向用途Java 基礎JDK 源碼ArrayList、HashMap、String集合原理、String 不可變性JVM《深入理解 Java 虛擬機》重點章節(jié)內(nèi)存模型、垃圾回收、類加載并發(fā)編程JUC 源碼、AQS 隊列同步器鎖、線程池、并發(fā)容器Spring 源碼Spring IoC 容器、Bean 生命周期Spring 高頻題數(shù)據(jù)庫MySQL 官方文檔、InnoDB 存儲引擎索引、事務、MVCC緩存與消息Redis 官方文檔、Kafka 核心原理緩存擊穿、消息可靠性項目復盤自己簡歷項目畫出架構圖場景題、項目深挖不需要全部看完圍繞“最??嫉?40 個問題”去針對性準備即可。2.2 本地環(huán)境怎么搭建面試復習過程中最好動手跑代碼建議安裝以下環(huán)境JDK推薦 8 或 11部分新項目用 17。面試手上寫的代碼盡量兼容 JDK 8。IDEIntelliJ IDEA 社區(qū)版即可不需要額外收費功能。MySQL本地裝一個 5.7 或 8.0學習索引和事務時可以直接看 explain 執(zhí)行計劃。RedisWindows 可用 Memurai 或 WSL 方案Linux 或 Mac 直接安裝原生版本。Kafka單機模式即可主要理解生產(chǎn)者、消費者、分區(qū)、副本機制。如果你不想在環(huán)境上花時間可以直接用 Docker 一鍵起中間件例如docker run -d --name mysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORDroot mysql:8.0 docker run -d --name redis7 -p 6379:6379 redis:7環(huán)境不必追求最新版本重點是能跑通命令、能看到現(xiàn)象。版本號在不同環(huán)境中差異很大本文所有配置以常規(guī)版本為例實際使用請根據(jù)你的環(huán)境調(diào)整。3. 高頻考點一Java 基礎與集合框架3.1 HashMap 的底層結構與 put 流程HashMap 是 Java 基礎面試中出場率最高的類沒有之一。面試官通常從“你對 HashMap 熟悉嗎”開始一直追問到紅黑樹、擴容和并發(fā)問題。先背結論JDK 1.7 底層是數(shù)組 鏈表擴容時使用頭插法并發(fā)情況下可能形成環(huán)形鏈表。JDK 1.8 底層是數(shù)組 鏈表 紅黑樹鏈表長度大于等于 8 且數(shù)組長度大于等于 64 時鏈表轉為紅黑樹。put 流程計算 key 的 hash 值 - 定位到數(shù)組下標 - 判斷是否為空 - 為空直接放入 - 不為空再判斷是鏈表還是紅黑樹 - 覆蓋舊值或新增節(jié)點 - 最后判斷是否需要擴容。手寫一個簡化的 put 思路可以幫助記憶public class MyHashMapK, V { private static final int DEFAULT_CAPACITY 16; private NodeK, V[] table; private int size; static class NodeK, V { K key; V value; int hash; NodeK, V next; Node(K key, V value, int hash, NodeK, V next) { this.key key; this.value value; this.hash hash; this.next next; } } public MyHashMap() { table new Node[DEFAULT_CAPACITY]; } private int hash(K key) { if (key null) { return 0; } int h key.hashCode(); // 擾動函數(shù)讓高位參與低位的計算減少哈希碰撞 return h ^ (h 16); } public V put(K key, V value) { int index hash(key) (table.length - 1); NodeK, V first table[index]; if (first null) { table[index] new Node(key, value, hash(key), null); size; return null; } NodeK, V node first; while (node ! null) { if (node.hash hash(key) (key node.key || key.equals(node.key))) { V oldValue node.value; node.value value; return oldValue; } node node.next; } // 頭插法僅用于演示JDK 1.8 實際是尾插法 NodeK, V newNode new Node(key, value, hash(key), first); table[index] newNode; size; return null; } }面試官常追問的點為什么容量是 2 的冪次方因為hash (length - 1)等價于hash % length且位運算更快同時能保證下標均勻分布。為什么鏈表轉紅黑樹的閾值是 8根據(jù)泊松分布在負載因子 0.75 下鏈表長度達到 8 的概率已經(jīng)極低轉紅黑樹是為了防止極端哈希沖突導致的性能退化。HashMap 為什么線程不安全因為多線程 put 時可能出現(xiàn)數(shù)據(jù)覆蓋、擴容時死循環(huán)JDK 1.7或 size 計算不準確。3.2 ConcurrentHashMap 如何保證線程安全提到 HashMap 線程不安全緊接著就會問 ConcurrentHashMap。回答錨點JDK 1.7 使用 Segment 分段鎖把一個 Map 分成 16 個 Segment每個 Segment 獨立加鎖理論上支持 16 個線程并發(fā)寫。JDK 1.8 放棄了分段鎖改用 CAS synchronized 鎖住數(shù)組桶中的首節(jié)點鎖粒度更細并發(fā)度更高。讀操作一般不加鎖Node 的 value 和 next 使用 volatile 修飾保證可見性。筆試中常讓寫一個線程安全的單例模式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原因在于instance new Singleton()在 JVM 層面不是原子操作分為分配內(nèi)存、初始化對象、把引用指向內(nèi)存三步。如果不加 volatile可能出現(xiàn)另一個線程拿到了尚未初始化完成的對象引用。3.3 String、StringBuilder、StringBuffer 的區(qū)別這道題屬于“送分題”但總有人答不全。類可變性線程安全適用場景String不可變安全不可變對象字符串常量、少量拼接StringBuilder可變不安全單線程大量拼接StringBuffer可變安全方法加 synchronized多線程字符串拼接追問頻率最高的點是String 的不可變性怎么保證char 數(shù)組用 final 修飾且不對外暴露修改方法。String 不可變有什么好處線程安全、哈希緩存、字符串常量池復用。4. 高頻考點二JVM 與內(nèi)存優(yōu)化4.1 JVM 內(nèi)存區(qū)域怎么劃分JVM 考察的重點是運行時數(shù)據(jù)區(qū)。不要只背名稱要能結合 OOM 異常說明?;卮鸾Y構程序計數(shù)器當前線程執(zhí)行的字節(jié)碼行號指示器線程私有不會 OOM。虛擬機棧線程私有每個方法對應一個棧幀棧幀里有局部變量表、操作數(shù)棧、動態(tài)鏈接、返回地址。棧深度不夠會拋 StackOverflowError。本地方法棧為 native 方法服務。堆線程共享存放對象實例和數(shù)組是垃圾回收的主要區(qū)域。內(nèi)存不足會拋 OutOfMemoryError: Java heap space。方法區(qū) / 元空間存放類信息、常量、靜態(tài)變量。JDK 8 之后方法區(qū)被元空間取代使用本地內(nèi)存。加載類過多可能拋 OutOfMemoryError: Metaspace。4.2 垃圾回收與 GC Roots垃圾回收問題一般從“如何判斷對象已死”開始。判斷算法引用計數(shù)法存在循環(huán)引用問題主流的 JVM 不用。可達性分析從 GC Roots 出發(fā)不可達的對象被判定為可回收。哪些對象可以作為 GC Roots虛擬機棧棧幀本地變量表中引用的對象。方法區(qū)中靜態(tài)屬性引用的對象。方法區(qū)中常量引用的對象。本地方法棧中 JNI 引用的對象。Java 虛擬機內(nèi)部的引用如基本數(shù)據(jù)類型對應的 Class 對象、常駐的異常對象等。常見收集器記憶口訣Serial單線程GC 時暫停所有用戶線程。ParNewSerial 的多線程版本常用于新生代。CMS并發(fā)標記清除目標是降低停頓但會產(chǎn)生內(nèi)存碎片。G1將堆劃分為 Region可預測停頓時間適合大堆。ZGC極低停頓適合超大堆和低延遲場景。面試時給出 JVM 參數(shù)也比空口說更好java -Xms512m -Xmx512m -XX:UseG1GC \ -XX:MaxGCPauseMillis200 \ -XX:HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath/data/logs/app.hprof \ -jar demo.jar這里-Xms和-Xmx設置為相同值避免運行期堆大小動態(tài)伸縮。生產(chǎn)環(huán)境建議顯式打印 GC 日志方便排查問題。4.3 線上 OOM 的排查思路“線上 OOM 了你怎么排查”是后端崗位的熱門場景題直接給出排查鏈路會非常加分。正確回答順序保留現(xiàn)場不要急著重啟加上-XX:HeapDumpOnOutOfMemoryError參數(shù)讓 JVM 自動導出 heap dump。分析 dump 文件使用jmap、jstat、jstack或 MATMemory Analyzer Tool分析。區(qū)分區(qū)域Java heap space 說明堆溢出Metaspace 說明類加載過多unable to create new native thread 說明線程數(shù)達到操作系統(tǒng)限制。根據(jù)線程棧定位通過 jstack 查看線程狀態(tài)看是否存在死鎖、線程池被打滿、大對象頻繁分配等。修復和驗證優(yōu)化代碼、調(diào)整參數(shù)、增加限流或熔斷小流量驗證后全量發(fā)布。5. 高頻考點三并發(fā)編程5.1 synchronized 與 ReentrantLock 的區(qū)別并發(fā)題總是由淺入深。先問 synchronized 怎么用再問鎖升級最后問 AQS。synchronized 關鍵點鎖對象是對象頭中的 Mark Word。JDK 1.6 引入偏向鎖、輕量級鎖、重量級鎖升級過程。是 JVM 層面的關鍵字使用方便異常時自動釋放鎖。ReentrantLock 關鍵點基于 AQS 實現(xiàn)是 API 層面的鎖。支持公平鎖和非公平鎖。支持中斷、超時、多個 Condition條件變量。需要手動 unlock建議在 finally 中釋放。答法示例synchronized 是 JVM 內(nèi)置鎖使用簡單鎖的獲取和釋放由字節(jié)碼指令 monitorenter / monitorexit 控制ReentrantLock 是 JUC 包提供的顯式鎖底層基于 AQS 同步隊列支持公平性選擇、中斷響應和超時獲取。JDK 1.6 之后 synchronized 引入了鎖升級機制兩者性能差距已經(jīng)很小。實際項目中能用 synchronized 就用 synchronized需要靈活控制鎖的時候就選 ReentrantLock。5.2 volatile 與可見性volatile 有兩個核心作用保證線程之間的可見性。禁止指令重排序。但它不能保證原子性。經(jīng)典的 i 問題用 volatile 修飾并不能解決多線程累加結果錯誤??匆欢问纠apublic class VolatileDemo { private static volatile boolean stop false; public static void main(String[] args) throws InterruptedException { Thread worker new Thread(() - { long count 0; while (!stop) { count; } System.out.println(worker stop, count count); }); worker.start(); Thread.sleep(100); stop true; worker.join(); System.out.println(main exit); } }如果不加 volatilestop的修改可能對工作線程不可見造成死循環(huán)。這個例子在面試中可以現(xiàn)場演示比背概念更有說服力。5.3 線程池的核心參數(shù)與實際應用線程池屬于并發(fā)編程的必考內(nèi)容。先記住有七個參數(shù)public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueRunnable workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)核心流程提交任務時如果當前線程數(shù)小于 corePoolSize創(chuàng)建核心線程執(zhí)行。如果核心線程已滿任務進入阻塞隊列。如果隊列已滿且線程數(shù)小于 maximumPoolSize創(chuàng)建非核心線程執(zhí)行。如果線程數(shù)達到 maximumPoolSize觸發(fā)拒絕策略。四種拒絕策略策略行為AbortPolicy直接拋 RejectedExecutionExceptionCallerRunsPolicy調(diào)用者線程執(zhí)行任務DiscardPolicy丟棄任務DiscardOldestPolicy丟棄隊列中最舊的任務阿里 Java 開發(fā)手冊建議用 ThreadPoolExecutor 顯式創(chuàng)建線程池禁止使用 Executors.newFixedThreadPool因為 FixedThreadPool 的隊列是無限長的LinkedBlockingQueue可能導致 OOM。6. 高頻考點四Spring 核心原理6.1 IoC 與 AOP 怎么理解Spring 題目不難但一定要講出自己的理解不要只背概念。IoC控制反轉就是把對象創(chuàng)建和依賴管理的控制權交給 Spring 容器。反過來理解如果沒有 Spring你需要自己 new 對象、自己管理依賴有了 IoC你只需要聲明依賴關系容器負責創(chuàng)建和注入。AOP面向切面編程的核心價值是“無侵入地增強業(yè)務邏輯”。典型場景包括日志記錄、權限校驗、事務管理、性能監(jiān)控。面試常問 Spring AOP 為什么用動態(tài)代理代理對象在運行時生成不需要修改原始字節(jié)碼。JDK 動態(tài)代理基于接口。CGLIB 動態(tài)代理基于繼承代理類繼承目標類。6.2 Bean 生命周期Spring Bean 生命周期是面試官很喜歡深挖的點。推薦按“創(chuàng)建前 - 實例化 - 屬性填充 - 初始化 - 使用 - 銷毀”這個順序回答。簡化回答版掃描并定義 BeanDefinition。通過構造方法或工廠方法實例化 Bean。屬性填充執(zhí)行依賴注入。執(zhí)行各種 Aware 回調(diào)如 BeanNameAware、BeanFactoryAware、ApplicationContextAware。執(zhí)行 BeanPostProcessor 的 postProcessBeforeInitialization。執(zhí)行初始化方法PostConstruct、InitializingBean、init-method。執(zhí)行 BeanPostProcessor 的 postProcessAfterInitialization。Bean 就緒可以正常使用。容器關閉時執(zhí)行銷毀邏輯PreDestroy、DisposableBean、destroy-method。6.3 Spring 事務傳播行為Spring 事務雖然用起來簡單一個Transactional注解就可以但面試題可以從傳播行為問到自調(diào)用失效。常用傳播行為傳播行為說明REQUIRED有事務則加入無事務則新建REQUIRES_NEW無論如何都新建事務NESTED嵌套事務使用 SavepointSUPPORTS有事務則加入無事務則以非事務方式執(zhí)行MANDATORY必須在一個事務中執(zhí)行否則拋異常高頻坑點Spring 事務默認只在 RuntimeException 和 Error 時回滾受檢異常不會觸發(fā)回滾。如果需要回滾用Transactional(rollbackFor Exception.class) public void updateUser(User user) { userMapper.updateById(user); // 業(yè)務代碼 }事務失效的常見原因也要準備方法被 private / final 修飾。同類內(nèi)部方法調(diào)用繞過代理對象。方法不是 public。數(shù)據(jù)庫引擎不支持事務如 MyISAM。異常被 catch 吞掉。rollbackFor 配置不對。7. 高頻考點五MySQL 與 Redis7.1 MySQL 索引與 SQL 優(yōu)化MySQL 題目可以從“慢 SQL 怎么排查”切入考察索引、執(zhí)行計劃、索引失效、分頁優(yōu)化。先掌握最核心的索引知識InnoDB 使用 B 樹索引聚簇索引的葉子節(jié)點存儲整行數(shù)據(jù)二級索引的葉子節(jié)點存儲主鍵值?;乇硗ㄟ^二級索引找到主鍵再通過主鍵查到整行數(shù)據(jù)。覆蓋索引索引中已經(jīng)包含需要查詢的字段避免回表。最左前綴原則聯(lián)合索引按照建立索引時的字段順序生效。SQL 示例假設有一張訂單表CREATE TABLE t_order ( id bigint(20) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, order_no varchar(64) NOT NULL, status tinyint(4) NOT NULL DEFAULT 0, created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_status (user_id, status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;經(jīng)常需要按用戶查詢訂單狀態(tài)就可以利用聯(lián)合索引idx_user_statusEXPLAIN SELECT id, order_no FROM t_order WHERE user_id 1001 AND status 1;索引失效的常見寫法對索引列使用函數(shù)例如WHERE DATE(created_at) 2026-08-01。模糊查詢以%開頭例如WHERE order_no LIKE %1001。隱式類型轉換例如WHERE user_id 1001。聯(lián)合索引不滿足最左前綴原則。OR 連接導致全表掃描。7.2 MySQL 事務隔離級別與 MVCCInnoDB 的四種隔離級別隔離級別臟讀不可重復讀幻讀讀未提交可能可能可能讀已提交不會可能可能可重復讀不會不會InnoDB 通過間隙鎖基本解決串行化不會不會不會MySQL 默認隔離級別是可重復讀Repeatable Read。MVCC 通過隱藏字段、undo log 和 Read View 實現(xiàn)一致性快照讀避免加鎖帶來的性能損失?;卮?MVCC 時推薦這么說每一行數(shù)據(jù)都有隱藏的 trx_id事務 ID和 roll_pointer回滾指針。查詢時InnoDB 會根據(jù)當前事務生成一個 Read View里面記錄活躍事務列表。通過比較 trx_id 與 Read View 的 up_limit_id、low_limit_id決定某行版本對當前事務是否可見。這樣就實現(xiàn)了不同隔離級別下的快照讀。7.3 Redis 緩存穿透、擊穿、雪崩Redis 三道題基本是必背內(nèi)容但面試官現(xiàn)在更看重“你能給出什么方案”。緩存穿透查詢一個根本不存在的 key緩存沒有數(shù)據(jù)庫也沒有導致請求直接打到數(shù)據(jù)庫。解決辦法緩存空值設置一個較短的過期時間。使用布隆過濾器在緩存之前判斷 key 是否存在。接口層做參數(shù)校驗非法參數(shù)直接攔截。緩存擊穿某個熱點 key 過期瞬間大量請求同時打到數(shù)據(jù)庫。解決辦法互斥鎖只讓一個線程去重建緩存其他線程等待或降級。邏輯過期不設置物理過期時間而是存儲過期時間發(fā)現(xiàn)過期后異步重建。熱點 key 設置永不過期。緩存雪崩大量 key 同時過期或者 Redis 節(jié)點宕機導致數(shù)據(jù)庫壓力瞬間增大。解決辦法過期時間加隨機值避免同時過期。熱點 key 用多級緩存本地緩存 Redis。Redis 集群高可用避免單點故障。手寫一個最簡單的緩存穿透防御public class CacheService { private final StringRedisTemplate redisTemplate; private final UserMapper userMapper; public User getUserById(Long id) { String cacheKey user: id; Object value redisTemplate.opsForValue().get(cacheKey); if (value ! null) { // 處理空值緩存標記 return value.toString().length() 0 ? JSON.parseObject(value.toString(), User.class) : null; } User user userMapper.selectById(id); if (user null) { // 緩存空值避免緩存穿透 redisTemplate.opsForValue().set(cacheKey, , 60, TimeUnit.SECONDS); return null; } redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(user), 30, TimeUnit.MINUTES); return user; } }7.4 Redis 分布式鎖Redis 分布式鎖是場景題高頻考點。基礎版本是 SETNX 過期時間推薦直接使用 Redisson 的看門狗自動續(xù)期。Autowired private RedissonClient redissonClient; public void handleOrder(Long orderId) { String lockKey lock:order: orderId; RLock lock redissonClient.getLock(lockKey); boolean locked false; try { locked lock.tryLock(3, 30, TimeUnit.SECONDS); if (!locked) { throw new RuntimeException(系統(tǒng)繁忙請稍后重試); } // 業(yè)務邏輯 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { if (locked lock.isHeldByCurrentThread()) { lock.unlock(); } } }注意釋放鎖時要判斷是否當前線程持有鎖否則可能把別人的鎖釋放掉。8. 高頻考點六消息隊列與分布式基礎8.1 Kafka 的消息可靠性消息隊列常見的三個問題重復消費、消息丟失、順序性。Kafka 消息可靠性需要從生產(chǎn)者、Broker、消費者三段來說生產(chǎn)者設置acksall等待所有副本寫入成功才算發(fā)送成功。Broker分區(qū)副本數(shù)大于 1min.insync.replicas設置為合理值。消費者關閉自動提交位移業(yè)務處理成功后再手動提交。# 生產(chǎn)者配置 acksall retries3 enable.idempotencetrue # 消費者配置 enable.auto.commitfalse消息順序性可以這樣回答Kafka 只能保證分區(qū)內(nèi)有序。如果要保證全局有序可以把同一個業(yè)務 key 路由到同一個分區(qū)比如訂單號取 hash 后指定分區(qū)。實際業(yè)務中保證同一個訂單的創(chuàng)建、支付、發(fā)貨事件有序即可。8.2 分布式事務與冪等設計微服務場景下分布式事務是繞不開的話題。面試常問2PC兩階段提交強一致性方案性能差協(xié)調(diào)者可能成為性能瓶頸。TCCTry、Confirm、Cancel業(yè)務侵入強適合資金類業(yè)務。本地消息表 / 事務消息最終一致性適合大多數(shù)業(yè)務。最大努力通知用于對實時性要求不高的場景。冪等設計是必答項推薦準備以下幾種方案數(shù)據(jù)庫唯一索引如訂單號、流水號唯一約束。狀態(tài)機業(yè)務狀態(tài)流轉判斷已處理狀態(tài)直接返回成功。分布式鎖處理前加鎖處理完釋放。Token 機制請求前獲取一個 token處理時校驗并刪除。8.3 分布式場景中的經(jīng)典問題CAP 理論一致性C、可用性A、分區(qū)容錯性P三者不可兼得。在分布式系統(tǒng)中網(wǎng)絡分區(qū)無法避免所以通常是在 CP 和 AP 之間選擇。Zookeeper 保證 CPEureka 保證 AP。BASE 理論Basically Available基本可用。Soft State軟狀態(tài)。Eventually Consistent最終一致性。這部分不需要答太長關鍵是結合自己的項目說明做了哪些取舍。9. 七天刷題計劃與每日安排理論終究要落到執(zhí)行。下面這份 7 天計劃每天大約花 6 到 8 小時適合有 Java 基礎的同學。Day 1Java 基礎與集合Java 基礎語法、泛型、反射、異常。HashMap、ConcurrentHashMap、ArrayList、LinkedList 源碼對比。String 相關常見問題。動手寫HashMap put 流程描述、手寫單例。Day 2JVM 與內(nèi)存調(diào)優(yōu)運行時數(shù)據(jù)區(qū)。垃圾回收算法與垃圾收集器。類加載機制與雙親委派。動手做使用 jmap 導出 dump并用 MAT 打開分析。Day 3并發(fā)編程synchronized、volatile、CAS、AQS。線程池參數(shù)與拒絕策略。ThreadLocal 原理與內(nèi)存泄漏問題。動手寫自定義線程池代碼演示 CPU 密集型與 IO 密集型參數(shù)設置。Day 4Spring 與 Spring BootIoC、AOP、Bean 生命周期。事務傳播行為和事務失效場景。Spring Boot 自動配置原理。動手做自己畫一遍 Spring Boot 啟動流程圖。Day 5MySQL索引結構與執(zhí)行計劃。事務隔離級別與 MVCC。鎖行鎖、間隙鎖、臨鍵鎖。動手做用 explain 分析慢 SQL改寫優(yōu)化。Day 6Redis 與消息隊列Redis 數(shù)據(jù)結構與持久化。緩存穿透、擊穿、雪崩。分布式鎖。Kafka 消息可靠性與順序性。動手做寫一個緩存工具類包含空值緩存和互斥鎖兩種方案。Day 7項目復盤與模擬面試畫出項目架構圖并講清楚模塊邊界。準備兩個高光場景一個是復雜性能優(yōu)化一個是線上故障排查。模擬面試把前面六天的問題自己復述一遍。10. 面試過程中的臨場表達技巧10.1 不會的題怎么回答面試遇到不會的問題很正常但“直接說不會”和“有邏輯地說不會”是兩種效果。推薦用“確認問題 關聯(lián)已知 表達思路”的方式回答這個問題我了解得還不深我理解它的方向可能是……用它來解決的一般是……場景。如果讓我現(xiàn)在做我會先查找官方文檔再做一個小規(guī)模實驗驗證。目前我掌握的是……不知道我這樣理解對不對。這種回答展示的是學習能力和解決問題的能力面試官通常不會直接淘汰。10.2 項目深挖怎么準備八股文背得再好項目一問就露餡也不行。準備項目時重點準備以下五個問題項目的整體架構是什么用到了哪些技術棧你負責的核心模塊有哪些給你帶來最大成長的點是什么項目中遇到的最大技術難點是什么你怎么解決的如果流量漲十倍你的項目哪里會先出問題怎么優(yōu)化有沒有線上問題排查經(jīng)驗比如 CPU 飆高、內(nèi)存泄漏、接口變慢。回答項目問題時堅持“背景 - 方案 - 結果 - 思考”四段式不要只說“用了 Redis 做緩存”要說清緩存的是什么數(shù)據(jù)、為什么選擇 Redis、遇到什么問題、最后怎么解決。10.3 被面試官連環(huán)追問怎么辦連環(huán)追問代表面試官對你的回答有興趣正在探測你的深度。這時要注意不要頻繁修改自己前面的結論。涉及不確定細節(jié)坦誠說明可以用“這塊我根據(jù)現(xiàn)有知識推斷”來鋪墊?;卮鹪絹碓缴钊霑r注意收斂不要從一個問題發(fā)散到幾個不相干的方向。11. 最佳實踐與長期積累建議面試八股文不是目的真正能拉開差距的是把知識轉化為解決問題的能力。這里分享幾個長期有效的建議。第一源碼閱讀要有主線。不要整個 JDK 源碼平鋪直敘地讀。優(yōu)先讀集合HashMap、ConcurrentHashMap。并發(fā)AQS、ReentrantLock、ThreadPoolExecutor。Spring 核心BeanFactory、ApplicationContext、事務切面。讀源碼時問自己三個問題這個類解決什么問題核心設計是什么如果讓我設計我會怎么做第二寫技術筆記不要只收藏。每個知識點用自己的話說一遍畫一遍流程圖。面試前看筆記復習效率遠比翻收藏夾高。第三多用本地環(huán)境做實驗。比如 MySQL 的事務隔離級別你可以開啟兩個連接實際插入數(shù)據(jù)觀察不同隔離級別下讀取結果的差異。中間件只有在本地跑過面試講出來才不虛。第四項目上線前關注安全和規(guī)范。如果你的簡歷項目要對外發(fā)布至少檢查基礎安全數(shù)據(jù)庫連接不要明文密碼、接口要加鑒權、刪除操作要謹慎、修改生產(chǎn)配置前先備份。對于涉及權限、支付、資金等敏感業(yè)務必須在測試環(huán)境充分驗證遵循最小權限原則避免造成線上事故。第五復盤比刷題重要。每次面試結束記錄面試官問了哪些題目哪些回答卡殼了。一周后回頭看你會發(fā)現(xiàn)知識漏洞其實集中在幾個固定區(qū)域針對性補齊即可。面試終究是一場溝通讓面試官看到你的知識體系、思考路徑和學習能力。7 天時間雖然短暫但主線明確、勤于動手、敢于表達完全可以把高頻核心考點覆蓋到八成熟。Java 后端這條路沒有終點一份 offer 只是開始接下來還有源碼、架構、穩(wěn)定性、業(yè)務復雜度這些更大的題目等著你。希望這篇文章能幫你把“不知道從哪開始”變成“從今天開始”。如果你覺得整理的內(nèi)容對你有幫助可以收藏起來按 7 天計劃每天打開一章邊看邊寫代碼效果會好很多。