Work
knowledge-interview
Interview Questions
1. IoC
Q1: IoC 實現機制
-
反射機制
- Class.forName() 載入類別,獲取 Class 對象
- Constructor.newInstance() 通過無參構造器創建實例
- Field.set() 通過反射設置屬性值,實現依賴注入
-
Bean 生命週期
- BeanDefinition 存儲 Bean 的配置元數據,包括類名、作用域、依賴關係
- BeanFactory 實現 Bean 的創建、配置、管理,提供基本的 IoC 功能
- ApplicationContext 擴展 BeanFactory,提供事件發布、國際化等企業級功能
-
依賴注入流程
- 掃描 @Component 等註解,識別需要管理的 Bean
- 解析依賴關係,構建依賴圖,檢測循環依賴
- 按照依賴順序實例化 Bean,注入依賴,執行生命週期回調
Q2: Bean 建立與注入
-
Bean 建立時機
- 單例模式:容器啟動時創建,緩存在 singletonObjects 中
- 原型模式:每次請求時創建新實例,不緩存
- 懶載入:首次調用 getBean() 時創建,適用於初始化耗時的 Bean
-
依賴注入方式
注入方式 特點 限制 建構子注入 強制依賴、不可變、可測試,Spring 推薦方式 參數多時冗長,需要提供所有依賴 Setter 注入 可選依賴、靈活,支持動態更新 依賴可能未初始化,違反不可變性 欄位注入 簡潔,減少樣板代碼 隱藏依賴、不可測試、NPE風險,不推薦使用
Q3: 循環依賴處理
-
三級快取機制
- 一級緩存:singletonObjects,存儲完全初始化好的 Bean
- 二級緩存:earlySingletonObjects,存儲提前曝光的 Bean
- 三級緩存:singletonFactories,存儲 Bean 的工廠對象
-
處理流程
- 創建 A 實例,放入三級緩存,開始屬性注入
- 發現需要注入 B,創建 B 實例,放入三級緩存
- B 注入 A 時,從三級緩存獲取 A 的工廠對象
- 通過工廠獲取 A 的實例,完成 B 的注入
- 返回 A 的注入過程,完成 A 的初始化
2. AOP
Q1: 實現方式
-
JDK 動態代理
- 基於介面實現,要求目標類必須實現介面
- 使用 Proxy.newProxyInstance() 創建代理對象
- 通過 InvocationHandler 攔截方法調用,實現橫切邏輯
-
CGLIB 代理
- 基於繼承實現,通過字節碼技術生成目標類的子類
- 重寫父類方法,在方法調用前後插入橫切邏輯
- 使用 Enhancer 創建代理對象,攔截方法調用
Q2: 切面順序控制
-
@Order 註解
- 數字越小優先級越高,決定切面執行順序
- 預設值 Integer.MAX_VALUE,表示最低優先級
- 可應用於 @Aspect 類或 @Component 類
-
Ordered 介面
- 實現 getOrder() 方法,返回優先級數值
- 與 @Order 註解等效,但更靈活
- 可動態調整優先級
-
執行順序
- 前置通知:優先級高的先執行,形成棧結構
- 後置通知:優先級高的後執行,形成隊列結構
- 環繞通知:優先級高的在外層,可控制目標方法執行
Q3: 應用場景
-
日誌記錄
- 方法調用日誌:記錄方法名、參數、返回值
- 執行時間統計:計算方法執行時間,識別性能瓶頸
- 參數返回值記錄:追蹤方法調用鏈,方便調試
-
權限控制
- 方法級權限檢查:驗證用戶權限,控制訪問
- 角色驗證:檢查用戶角色,實現細粒度控制
- 訪問控制:記錄訪問日誌,實現審計功能
-
交易管理
- 交易開始提交:自動管理交易邊界
- 異常回滾:捕獲異常,自動回滾交易
- 傳播行為控制:處理嵌套交易,確保數據一致性
3. Exception Handling
Q1: 全域異常處理
-
@ControllerAdvice + @ExceptionHandler
- 處理控制器異常:捕獲所有控制器拋出的異常
- 自定義處理邏輯:根據異常類型返回不同響應
- 統一返回格式:封裝錯誤信息,保持一致性
-
異常分類
- BusinessException:業務邏輯異常,需要特殊處理
- SystemException:系統異常,需要記錄日誌
- ThirdPartyException:第三方服務異常,需要重試
-
錯誤碼結構
- 模組代碼:標識異常來源,便於定位
- 錯誤類型:區分異常嚴重程度
- 錯誤編號:具體錯誤代碼,用於查詢
Q2: 異常處理策略
-
重拋條件
- 系統異常:無法處理的底層異常
- 業務異常:需要上層處理的業務邏輯異常
- 關鍵異常:需要記錄和通知的重要異常
-
吃掉條件
- 可恢復異常:可以自動重試的異常
- 非關鍵異常:不影響核心功能的異常
- 已記錄異常:已經記錄日誌的異常
-
自定義異常條件
- 業務邏輯異常:需要特殊處理的業務錯誤
- 特殊處理異常:需要自定義處理邏輯的異常
- 攜帶額外信息異常:需要傳遞額外信息的異常
4. DB Index
Q1: B+ Tree 特點
-
結構
- 數據在葉節點:所有數據都存儲在葉節點,非葉節點只存索引
- 葉節點相連:葉節點通過指針相連,支持範圍查詢
- 非葉節點存索引:減少非葉節點大小,提高緩存效率
-
查詢
- 穩定查詢時間:所有查詢都需要相同的磁盤 I/O 次數
- 範圍查詢:通過葉節點指針快速遍歷
- 減少磁盤 I/O:通過多路平衡樹減少磁盤訪問
Q2: 索引類型
-
聚簇索引
- 數據索引一體:數據和索引存儲在一起
- 單表一個:一個表只能有一個聚簇索引
- 主鍵索引:通常使用主鍵作為聚簇索引
-
非聚簇索引
- 索引數據分離:索引和數據分開存儲
- 多個索引:一個表可以有多個非聚簇索引
- 回表查詢:需要通過索引找到主鍵,再查詢數據
-
覆蓋索引
- 包含查詢字段:索引包含所有需要查詢的字段
- 避免回表:不需要查詢數據表
- 提升效率:減少磁盤 I/O,提高查詢速度
Q3: 索引失效條件
-
查詢條件
- 函數運算:對索引字段使用函數
- 類型轉換:隱式類型轉換導致索引失效
- != 或 <>:不等於操作符無法使用索引
- LIKE % 開頭:前綴模糊查詢無法使用索引
-
索引設計
- 違反最左前綴:不遵循最左前綴原則
- OR 條件:OR 條件導致索引失效
- 選擇性低:索引列重複值過多
5. MQ
Q1: 選擇標準
-
RabbitMQ
- 複雜路由:支持多種交換機類型和路由規則
- 可靠投遞:支持消息確認和持久化
- 靈活交換機:支持 direct、topic、fanout、headers 等類型
-
Kafka
- 高吞吐:支持每秒百萬級消息處理
- 日誌收集:適合大規模日誌收集場景
- 流式處理:支持實時數據處理和分析
Q2: 可靠性機制
-
生產者
- 確認機制:等待 broker 確認消息接收
- 重試機制:發送失敗時自動重試
- 事務支持:確保消息發送的原子性
-
消費者
- 手動確認:消費者控制消息確認時機
- 重試策略:失敗消息進入重試隊列
- 死信隊列:處理無法消費的消息
-
持久化
- 磁盤存儲:消息持久化到磁盤
- 副本機制:多副本保證數據安全
- 日誌文件:使用日誌文件存儲消息
6. Redis
Q1: 性能因素
-
內存操作
- 內存存儲:數據存儲在內存中
- 無磁盤 I/O:避免磁盤讀寫開銷
- 快速讀寫:內存操作速度遠快於磁盤
-
數據結構
- 動態字符串:支持動態擴展
- 壓縮列表:節省內存空間
- 跳躍表:實現有序集合,支持範圍查詢
-
單線程
- 無線程切換:避免線程切換開銷
- 無鎖競爭:避免鎖競爭開銷
- 簡單高效:代碼簡單,執行效率高
Q2: 持久化
-
RDB
- 定時快照:定期將數據快照保存到磁盤
- 文件緊湊:單個文件存儲所有數據
- 快速恢復:恢復速度快,適合備份
-
AOF
- 實時記錄:記錄所有寫操作命令
- 可讀性好:命令格式易於理解
- 文件較大:需要定期重寫壓縮
Q3: 高可用
-
主從複製
- 數據同步:主節點數據同步到從節點
- 讀寫分離:主節點寫,從節點讀
- 故障轉移:主節點故障時從節點升級
-
哨兵模式
- 監控主節點:檢測主節點狀態
- 自動選主:主節點故障時自動選舉新主
- 配置中心:管理主從節點配置
-
集群模式
- 數據分片:數據分散到多個節點
- 負載均衡:請求分散到不同節點
- 擴展性:支持水平擴展