Java開發崗面試記錄合集

一、Java 核心

1. 基礎語法
  • final關鍵字的作用

    • 修飾類:類不可被繼承(如String類),保證類的穩定性和安全性。
    • 修飾方法:方法不可被重寫(防止子類篡改父類核心邏輯,如工具類方法)。
    • 修飾變量:
      • 基本類型:值不可修改(如final int a = 10a的值終身不變)。
      • 引用類型:引用地址不可變(對象內容可修改,如final List<String> list = new ArrayList<>()list可添加元素但不能指向新集合)。
  • 深拷貝 vs 淺拷貝

    類型特點實現方式適用場景
    淺拷貝僅復制對象本身及基本類型字段,引用類型字段與原對象共享同一份引用(新舊對象關聯)Object.clone()默認實現(需實現Cloneable接口)、BeanUtils.copyProperties()簡單對象復制,無需完全隔離引用關系
    深拷貝遞歸復制所有字段(包括引用類型),新舊對象完全獨立(無任何關聯)手動遞歸復制、序列化(Serializable)、JSON 工具(如 Jackson)復雜對象復制,需徹底隔離引用關系
2. 集合框架
  • HashMap底層結構(Java 8+)
    采用數組 + 鏈表 + 紅黑樹混合結構,平衡查詢效率與內存開銷:

    • 數組(桶):初始容量為 16(DEFAULT_INITIAL_CAPACITY),擴容時按 2 倍增長(newCap = oldCap << 1),存儲鏈表頭節點或紅黑樹根節點。
    • 鏈表:哈希沖突時(不同 key 計算出相同索引),用鏈表存儲元素,查詢時間復雜度為 O (n)。
    • 紅黑樹:當鏈表長度超過 8(TREEIFY_THRESHOLD)且數組長度≥64(MIN_TREEIFY_CAPACITY)時,鏈表轉為紅黑樹(查詢時間復雜度優化為 O (log n));當長度≤6(UNTREEIFY_THRESHOLD)時,紅黑樹轉回鏈表(降低樹結構維護成本)。

    優化點

    • 哈希計算:(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16),通過高位與低位異或,減少哈希沖突(將高位信息融入低位)。
    • 擴容機制:使用高位掩碼計算新索引(newIndex = oldCap + (index & (oldCap - 1))),避免節點重新哈希,直接定位新位置。
  • HashMap線程安全性
    HashMap非線程安全,多線程并發操作可能導致:

    • 數據覆蓋:多線程同時put時,可能覆蓋彼此的結果。
    • Java 7 死循環:鏈表采用頭插法,擴容時可能導致鏈表成環(Java 8 改為尾插法解決,但仍非線程安全)。

    線程安全的 Map 實現

    • ConcurrentHashMap(推薦):
      • Java 7:基于分段鎖(Segment,每個 Segment 是獨立的哈希表),并發度為 Segment 數量(默認 16)。
      • Java 8:移除 Segment,改用 CAS +?synchronized(只鎖單個桶),并發效率更高,支持computeIfAbsent等原子操作。
    • Hashtable:全表鎖(所有方法用synchronized修飾),并發性能差,已淘汰。
    • Collections.synchronizedMap(Map):包裝普通 Map,通過同步代碼塊(synchronized (mutex))保證安全,性能一般(鎖整個 Map)。
  • ArrayList?vs?LinkedList

    特性ArrayListLinkedList
    底層結構動態數組(連續內存空間)雙向鏈表(非連續內存)
    隨機訪問O (1)(通過索引直接訪問)O (n)(需遍歷鏈表)
    插入 / 刪除中間操作 O (n)(需移動元素),尾部操作 O (1)中間操作 O (1)(修改指針),但定位節點需 O (n)
    內存占用較少(連續空間,有擴容冗余)較多(每個節點含前后指針)
    擴容機制容量不足時擴容為 1.5 倍(oldCap + (oldCap >> 1)無擴容(動態添加節點)
    適用場景頻繁查詢、尾部增刪頻繁中間插入 / 刪除
3. JVM
  • 內存區域劃分

    區域類型包含區域特點可能的異常
    線程私有虛擬機棧存儲棧幀(局部變量表、操作數棧、返回地址等),方法調用時創建,結束時銷毀。棧深度超過限制→StackOverflowError;內存不足→OutOfMemoryError
    本地方法棧native方法(如Object.hashCode())提供內存空間。同虛擬機棧。
    程序計數器記錄當前線程執行的字節碼行號(如分支、循環、跳轉)。唯一不會拋出 OOM 的區域。
    線程共享存儲對象實例、數組,GC 主要工作區域(分新生代、老年代)。內存不足→OutOfMemoryError
    方法區(元空間)存儲類信息(結構、方法數據)、常量池、靜態變量、JIT 編譯后的代碼。JDK 8 前(永久代)可能 OOM;JDK 8 后元空間使用本地內存,默認無上限(可通過-XX:MaxMetaspaceSize限制)。
  • 垃圾回收(GC)判定機制
    采用可達性分析算法

    • GC Roots(根對象):
      • 虛擬機棧中局部變量表引用的對象(如方法內的User user = new User())。
      • 方法區中類靜態變量引用的對象(如static User user = new User())。
      • 方法區中常量引用的對象(如String s = "abc"中的"abc")。
      • 本地方法棧中native方法引用的對象。
    • 判定流程:從 GC Roots 出發,遍歷所有可達對象并標記;未被標記的對象為不可達對象,可被回收(但并非立即回收,需經歷多次標記)。

    引用類型對回收的影響

    • 強引用(User u = new User()):永不回收,OOM 也不釋放。
    • 軟引用(SoftReference<User>):內存不足時回收,用于緩存(如圖片緩存)。
    • 弱引用(WeakReference<User>):GC 時立即回收,用于臨時關聯(如ThreadLocal的 key)。
    • 虛引用(PhantomReference<User>):僅用于跟蹤對象回收,必須配合引用隊列,無實際引用意義(如堆外內存回收)。
  • 類加載機制
    遵循雙親委派模型(防止類重復加載),流程:

    1. 加載(Loading):通過類全限定名(如com.xxx.User)讀取.class文件到內存,生成Class對象(存方法區)。
    2. 驗證(Verification):檢查字節碼合法性(格式、語義、字節碼指令、符號引用),防止惡意 class 文件。
    3. 準備(Preparation):為靜態變量(static)分配內存并賦默認值(如static int a = 10,此處賦 0)。
    4. 解析(Resolution):將符號引用(如類名、方法名)轉為直接引用(內存地址)。
    5. 初始化(Initialization):執行<clinit>()方法(合并靜態變量賦值與靜態代碼塊,按順序執行)。
    6. 使用(Using):實例化對象、調用方法。
    7. 卸載(Unloading):類不再被引用且類加載器被回收時,Class對象被卸載(極少發生)。
  • 垃圾回收機制

    • 分代收集理論

      • 新生代(Young Generation):對象存活時間短(如方法內臨時變量),約 90% 對象會被回收,頻繁觸發Minor GC(年輕代 GC)。
        • 結構:Eden 區(80%) + From Survivor 區(10%) + To Survivor 區(10%)。
        • 算法:復制算法(將 Eden 和 From Survivor 存活對象復制到 To Survivor,清空原區域,無碎片)。
      • 老年代(Old Generation):對象存活時間長(如緩存對象),觸發Full GC(全局 GC)頻率低。
        • 算法:標記 - 清除(標記存活對象,清除未標記對象,可能產生碎片)或標記 - 整理(標記后將存活對象壓縮到一端,消除碎片)。
    • GC 算法實現

      • Serial GC:單線程回收,STW(Stop The World)時間長,適合客戶端應用(如桌面程序)。
      • Parallel GC:多線程回收,以吞吐量(用戶線程運行時間 / 總時間)為目標,JDK 8 默認年輕代收集器。
      • CMS GC(Concurrent Mark Sweep):低延遲優先,步驟:初始標記(STW)→并發標記→重新標記(STW)→并發清除(僅初始和重新標記 STW),缺點:內存碎片多、CPU 消耗高(JDK 9 后廢棄)。
      • G1 GC(Garbage-First):區域化分代式收集器(取代 CMS),將堆分為多個 Region,兼顧吞吐量和延遲,JDK 9 + 默認,適合大堆場景(如 8G 以上)。
  • JVM 調優經驗

    • 核心參數

      bash

      -Xms2g -Xmx2g  # 堆初始和最大大小(設為相同,避免動態擴容)
      -XX:NewRatio=2  # 老年代:新生代=2:1(默認)
      -XX:SurvivorRatio=8  # Eden:From:To=8:1:1
      -XX:MaxMetaspaceSize=256m  # 元空間上限(默認無上限)
      -XX:+UseG1GC  # 使用G1垃圾回收器
      -XX:MaxGCPauseMillis=200  # G1目標最大STW時間(毫秒)
      -XX:+HeapDumpOnOutOfMemoryError  # OOM時生成堆轉儲文件
      -XX:HeapDumpPath=/path/to/dump  # 堆轉儲文件路徑
      
    • 調優場景
      • Full GC頻繁:檢查是否有大對象頻繁進入老年代(如大集合未釋放),增大老年代內存(-Xmx)或調整晉升閾值(-XX:MaxTenuringThreshold,默認 15)。
      • OOM(Java heap space):通過jmap -heap <pid>分析堆使用,結合堆轉儲文件(jhat或 MAT 工具)定位內存泄漏(如靜態集合未清理)。
      • 延遲過高:切換至 G1 或 ZGC(超低延遲),調小-XX:MaxGCPauseMillis
4. 多線程
  • 線程安全集合

    • ConcurrentHashMap:線程安全的哈希表(見上文)。
    • CopyOnWriteArrayList:讀寫分離,寫時復制新數組(add/set時),讀無需鎖,適合讀多寫少場景(如配置列表)。
    • ConcurrentLinkedQueue:無鎖并發隊列,基于 CAS 實現,高效(生產者 - 消費者模型)。
    • BlockingQueue:阻塞隊列(ArrayBlockingQueueLinkedBlockingQueue),支持put(滿時阻塞)和take(空時阻塞),適合異步通信。
  • 線程池

    • 核心參數(ThreadPoolExecutor

      java

      new ThreadPoolExecutor(corePoolSize,    // 核心線程數(長期存活,即使空閑)maximumPoolSize, // 最大線程數(核心 + 臨時線程)keepAliveTime,   // 臨時線程空閑存活時間unit,            // 時間單位(如TimeUnit.SECONDS)workQueue,       // 工作隊列(存放等待執行的任務)threadFactory,   // 線程工廠(自定義線程名、優先級等)handler          // 拒絕策略(隊列滿且線程達最大時觸發)
      )
      
    • 參數設置策略

      • 核心線程數(corePoolSize)
        • CPU 密集型任務(如計算):CPU核心數 + 1(減少線程切換,充分利用 CPU)。
        • IO 密集型任務(如網絡請求、文件讀寫):CPU核心數 * 2(線程多處于等待狀態,需更多線程提高吞吐量)。
      • 最大線程數(maximumPoolSize):通常為核心線程數的 2 倍,需結合隊列容量(隊列滿時才創建臨時線程)。
      • 工作隊列
        • LinkedBlockingQueue:無界隊列(默認容量 Integer.MAX_VALUE),適合高吞吐但需控制內存(避免 OOM)。
        • ArrayBlockingQueue:有界隊列,適合資源有限場景(需合理設置容量,避免隊列過大導致內存溢出)。
        • SynchronousQueue:無緩沖隊列(直接移交任務給線程),適合快速響應場景(配合maximumPoolSize為 Integer.MAX_VALUE)。
      • 拒絕策略
        • AbortPolicy:拋RejectedExecutionException(默認)。
        • CallerRunsPolicy:由提交任務的線程執行(減緩提交速度,自帶限流)。
        • DiscardPolicy:默默丟棄新任務。
        • DiscardOldestPolicy:丟棄隊列中最舊的任務,嘗試提交新任務。
    • 使用示例

      java

      // 構建線程池
      ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS,new LinkedBlockingQueue<>(100),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy()
      );
      // 提交任務
      executor.submit(() -> System.out.println("Task running")); // 返回Future
      // 關閉線程池
      executor.shutdown(); // 執行完現有任務后關閉,不再接受新任務
      
  • synchronized鎖升級
    synchronized通過鎖升級機制優化性能(從低效到高效):

    1. 無鎖狀態:對象剛創建,無線程競爭,Mark Word 存儲對象哈希碼。
    2. 偏向鎖:同一線程多次獲取鎖,Mark Word 記錄線程 ID,避免 CAS 操作(適用于單線程場景)。
    3. 輕量級鎖:多線程交替獲取鎖,通過 CAS 競爭鎖(自旋嘗試),避免重量級鎖開銷(適用于短時間競爭)。
    4. 重量級鎖:多線程并發競爭激烈,自旋失敗后膨脹為重量級鎖(依賴操作系統互斥量),線程阻塞等待(適用于長時間競爭)。

二、MySQL 數據庫

1. 索引
  • 底層結構(InnoDB)
    采用B + 樹,原因:

    • 磁盤友好:非葉子節點僅存索引鍵,葉子節點存儲數據(聚集索引)或主鍵(二級索引),單節點存儲更多鍵,減少 I/O 次數。
    • 范圍查詢高效:葉子節點通過雙向鏈表連接,支持快速范圍掃描(如WHERE id > 100 AND id < 200)。
    • 平衡性好:B + 樹為平衡樹,查詢時間穩定在 O (log n)。

    對比 B 樹:B 樹葉子節點和非葉子節點都存數據,單節點存儲鍵數少,樹高更高,I/O 效率低。

  • 索引類型

    • 聚集索引(主鍵索引):按主鍵排序,葉子節點存儲完整數據行,InnoDB 表必存在(無主鍵則選唯一索引,否則隱式生成 6 字節 ROWID)。
    • 二級索引(非主鍵索引):按索引列排序,葉子節點存儲主鍵值,查詢時需通過主鍵回表(到聚集索引查完整數據)。
    • 聯合索引:多列組合索引(如(a,b,c)),遵循最左前綴原則(查詢條件含aa+ba+b+c時生效)。
  • 索引失效場景

    • 未遵循最左前綴原則(如聯合索引(a,b,c),查詢WHERE b=1則失效)。
    • 對索引列進行計算 / 函數操作(如WHERE YEAR(create_time) = 2023create_time索引失效)。
    • 使用!=<>NOT IN(優化器可能放棄索引,選擇全表掃描)。
    • 隱式類型轉換(如varchar列用數字查詢:WHERE name = 123,索引失效)。
    • OR條件中存在非索引列(如WHERE a=1 OR b=2,僅a有索引則失效)。
    • LIKE以通配符開頭(如WHERE name LIKE '%張',無法使用索引)。
    • 數據量極小(優化器認為全表掃描比走索引更快)。
    • IS NULL/IS NOT NULL(取決于字段是否允許為 NULL 及數據分布)。
  • 索引設計原則

    • 適合建索引:高頻查詢條件(WHERE)、排序 / 分組字段(ORDER BY/GROUP BY)、聯合索引需滿足最左前綴。
    • 不適合建索引:低區分度字段(如性別、狀態,基數低)、頻繁更新字段(索引維護成本高)、表數據量極少(全表掃描更快)。
2. 事務
  • ACID 特性

    • 原子性(Atomicity):事務要么全執行,要么全回滾。由Undo Log實現(記錄數據修改前狀態,回滾時恢復)。
    • 一致性(Consistency):事務執行前后數據狀態合法(如轉賬后總金額不變)。由原子性、隔離性、持久性共同保證。
    • 隔離性(Isolation):多事務并發時,操作互不干擾。由鎖(行鎖、間隙鎖)和 MVCC(多版本并發控制)實現。
    • 持久性(Durability):事務提交后數據永久保存。由Redo Log實現(先寫日志再刷盤,崩潰后重放日志恢復)。
  • 隔離級別

    隔離級別臟讀(讀未提交數據)不可重復讀(重讀數據變)幻讀(新增數據被讀到)實現方式
    讀未提交(RU)存在存在存在無鎖,直接讀取最新數據
    讀已提交(RC)不存在存在存在MVCC(快照讀,每次讀新快照)
    可重復讀(RR)不存在不存在不存在(InnoDB)MVCC + 間隙鎖(防止新增數據)
    串行化(Serial)不存在不存在不存在全表鎖(事務按順序執行)

    幻讀解決:InnoDB 在 RR 級別通過間隙鎖(鎖定索引范圍,如WHERE id > 10會鎖定 10 以上的間隙)防止其他事務插入新行,避免幻讀。顯式加鎖SELECT ... FOR UPDATE也可解決。

3. 日志
日志類型作用特點
Binlog(二進制日志)記錄所有寫操作(DDL、DML),用于主從復制(從庫同步主庫日志)和數據恢復(mysqlbinlog回放)。邏輯日志(記錄 SQL 語句或行變更),追加寫入,可通過expire_logs_days自動清理。
Redo Log(重做日志)InnoDB 引擎日志,記錄數據頁修改,保證事務持久性(崩潰后重放日志恢復數據)。物理日志(記錄頁地址和修改內容),循環寫入(固定大小),有innodb_log_file_size控制大小。
Undo Log(回滾日志)InnoDB 引擎日志,記錄數據修改前狀態,用于事務回滾和 MVCC(提供歷史版本)。事務提交后可刪除,存儲在 undo 表空間。
Slow Query Log(慢查詢日志)記錄執行時間超過long_query_time的 SQL,用于優化慢查詢。默認關閉,需手動開啟(slow_query_log = ON)。
Error Log(錯誤日志)記錄 MySQL 啟動、運行、關閉過程中的錯誤信息,用于排查故障。必開啟,路徑由log_error指定。
4. 慢查詢優化
  • 定位慢查詢

    1. 開啟慢查詢日志:

      sql

      SET GLOBAL slow_query_log = ON;
      SET GLOBAL long_query_time = 2; -- 閾值(秒)
      SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
      
    2. 使用EXPLAIN分析執行計劃,關注:
      • type:訪問類型(ALL全表掃描,ref/range走索引)。
      • key:實際使用的索引(NULL表示未走索引)。
      • rows:預估掃描行數(值越小越好)。
      • ExtraUsing filesort(文件排序,需優化)、Using index(覆蓋索引,優)。
  • 優化措施

    • 索引優化:添加缺失索引,修復失效索引(如避免函數操作索引列)。
    • SQL 改寫:拆分復雜查詢、避免SELECT *(用覆蓋索引)、用JOIN代替子查詢。
    • 數據庫調優:調整innodb_buffer_pool_size(建議設為內存 50%-70%)、分庫分表(數據量超千萬時)。

三、Redis 緩存

1. 數據結構
數據類型底層結構(核心)特點應用場景
String簡單動態字符串(SDS)二進制安全(可存文本、圖片),支持INCR/DECR自增自減緩存(用戶信息)、計數器(閱讀量)、分布式 ID
Hash哈希表(數組 + 鏈表)鍵值對集合(field-value),適合存儲對象存儲用戶信息(user:1 {name: "a", age: 20}
List雙向鏈表 + 壓縮列表(元素少且小)有序,可重復,支持LPUSH/RPOP兩端操作消息隊列、最新列表(熱搜前 10)
Set哈希表 + 整數集合(元素為整數且少)無序,唯一元素,支持SINTER(交集)/SUNION(并集)標簽(文章標簽去重)、共同好友
ZSet跳躍表 + 哈希表score排序,元素唯一,支持ZRANK(排名)排行榜(游戲積分)、延遲隊列(按時間 score 排序)
2. 持久化
持久化方式原理優點缺點
RDB定時生成內存快照(.rdb 文件),通過SAVE(阻塞)或BGSAVE(后臺線程)觸發。恢復速度快(直接加載二進制文件)、文件小可能丟失最后一次快照后的修改(如突發宕機)。
AOF記錄所有寫命令(追加到.aof 文件),通過appendfsync控制同步策略(always/everysec/no)。數據安全性高(everysec最多丟 1 秒數據)文件大(命令冗余)、恢復速度慢(需重放命令)。

混合持久化(Redis 4.0+):AOF 文件開頭為 RDB 快照,后續為增量命令,兼顧兩者優點(aof-use-rdb-preamble yes開啟)。

3. 主從復制
  • 流程

    1. 從節點執行SLAVEOF <master-ip> <port>,建立連接。
    2. 主節點執行BGSAVE生成 RDB,發送給從節點(全量復制)。
    3. 從節點加載 RDB 后,主節點通過repl_backlog_buffer同步增量寫命令(增量復制)。
  • 問題及解決

    • 數據延遲:主從異步復制導致從庫數據滯后,適合讀多寫少場景(寫主讀從)。
    • 腦裂:網絡分區時,從庫被誤認為主庫,導致數據不一致。解決:min-slaves-to-write = 1(主庫至少 1 個從庫連接才允許寫)。
4. 緩存問題(緩存三兄弟)
問題原因解決方案
緩存穿透查詢不存在的數據(如id=-1),緩存和 DB 都無數據,請求直達 DB。1. 布隆過濾器(提前過濾不存在的 key);2. 緩存空值(短期有效,如 5 分鐘)。
緩存擊穿熱點 key 過期瞬間,大量并發請求直達 DB。1. 互斥鎖(Redis?SETNX,只讓一個線程更新緩存);2. 熱點 key 永不過期(后臺異步更新)。
緩存雪崩大量 key 同時過期或緩存集群宕機,請求全壓到 DB。1. 隨機過期時間(避免集中過期);2. 緩存集群(主從 + 哨兵);3. 服務降級 / 限流。
5. 常見用途
  • 緩存:存儲高頻訪問數據(如商品詳情),減輕數據庫壓力(設置合理 TTL 避免雪崩)。
  • 分布式鎖SET key value NX PX 30000(NX:不存在才設置,PX:30 秒過期),釋放鎖時驗證 value(避免誤刪)。
  • 排行榜:ZSET 的ZADD(更新分數)、ZREVRANGE(獲取 TopN)實現實時排名。
  • 計數器INCR/DECR原子操作,適合閱讀量、點贊數等。
  • 消息隊列:List 的LPUSH(生產者)和BRPOP(消費者,阻塞彈出)實現簡單隊列。
6. 引入組件的考慮因素
  • 必要性:是否解決核心問題(如緩存是否真能提升性能,避免過度設計)。
  • 性能:吞吐量(QPS)、延遲(響應時間)是否滿足業務需求(Redis 單機 QPS 可達 10 萬 +)。
  • 運維成本:部署、監控(INFO命令、Prometheus)、擴縮容難度(集群是否支持動態添加節點)。
  • 社區支持:文檔完善度、版本更新頻率(Redis 社區活躍,問題解決快)。
  • 數據一致性:與數據庫的同步策略(Cache-Aside、Write-Through)是否可控。
7. 高可用方案
模式原理特點適用場景
主從復制主節點寫入,從節點同步數據并提供讀服務(一主多從)。部署簡單,提升讀吞吐量;主節點故障需手動切換。讀多寫少,可用性要求不高。
哨兵(Sentinel)哨兵集群監控主從節點,主節點故障時自動選舉新主節點(故障轉移)。自動故障轉移,高可用;需至少 3 個哨兵節點(避免腦裂)。生產環境基礎高可用方案。
Cluster 集群數據分片到 16384 個槽(Slot),每個節點負責部分槽,多主多從(每個主節點有從節點)。水平擴展(動態添加節點)、高可用;支持跨節點操作(MGET需指定槽)。數據量大(超 10GB)、高并發場景。
8. Redis Cluster 的插槽(Slot)
  • 作用
    • 數據分片CRC16(key) % 16384計算 key 所屬槽,每個節點負責部分槽(如 3 個主節點各負責~5461 個槽),實現數據分布式存儲。
    • 路由轉發:客戶端連接任一節點,若 key 不在當前節點負責的槽,節點返回MOVED指令指引至目標節點。
    • 動態擴容:槽可在節點間遷移(CLUSTER MIGRATE),無需停機(遷移過程中雙寫保證數據一致性)。

四、Spring 框架

1. IOC(控制反轉)
  • 核心思想:將對象創建、依賴管理交給 Spring 容器,而非手動new對象,降低耦合。
  • 依賴注入方式
    • @Autowired:按類型注入(默認),配合@Qualifier按名稱注入。
    • @Resource:按名稱注入(默認),無名稱時按類型注入(JDK 注解,非 Spring)。
    • 構造器注入:通過構造方法傳遞依賴(推薦,避免循環依賴問題)。
  • Bean 初始化流程
    1. 讀取配置(XML / 注解)→ 2. 解析為BeanDefinition?→ 3. 實例化(new對象)→ 4. 依賴注入(填充屬性)→ 5. 初始化(@PostConstructInitializingBean等)→ 6. 放入容器。
2. AOP(面向切面編程)
  • 原理:基于動態代理,在不修改源碼的情況下為方法添加額外功能(如日志、事務)。

    • JDK 代理:目標類實現接口時,Proxy.newProxyInstance()生成代理類(實現同一接口)。
    • CGLIB 代理:目標類無接口時,Enhancer生成子類代理(重寫目標方法),無法代理final類 / 方法。
  • 核心概念

    • 切面(@Aspect):封裝橫切邏輯的類(如日志切面)。
    • 切點(@Pointcut):定義攔截哪些方法(如execution(* com.xxx.service.*(..)))。
    • 通知(Advice):切點執行時的動作(@Before前置、@After后置、@Around環繞等)。
  • 應用場景:日志記錄、事務管理(@Transactional)、權限校驗、性能監控。

3. Bean 生命周期
  1. 實例化:容器通過構造方法創建 Bean 對象(new)。
  2. 屬性賦值:注入依賴(@Autowired/setter 方法)。
  3. 初始化
    • 執行Aware接口回調(BeanNameAwareApplicationContextAware等)。
    • 執行@PostConstruct注解方法(JSR-250 規范,初始化前)。
    • 執行InitializingBean.afterPropertiesSet()方法(Spring 接口)。
    • 執行自定義init-method(XML 配置或@Bean(initMethod))。
  4. 使用:Bean 放入容器,供其他組件調用。
  5. 銷毀
    • 執行@PreDestroy注解方法(JSR-250 規范,銷毀前)。
    • 執行DisposableBean.destroy()方法(Spring 接口)。
    • 執行自定義destroy-method(XML 配置或@Bean(destroyMethod))。
4. 循環依賴解決

場景:A 依賴 B,B 依賴 A。

Spring 通過三級緩存解決單例 Bean 循環依賴:

  • 一級緩存(singletonObjects):存放完全初始化的 Bean。
  • 二級緩存(earlySingletonObjects):存放半成品 Bean(已實例化未賦值)。
  • 三級緩存(singletonFactories):存放 Bean 工廠(用于生成代理對象)。

流程

  1. A 實例化后,放入三級緩存 → 2. A 需要注入 B,容器初始化 B → 3. B 需要注入 A,從三級緩存獲取 A 的早期引用(若 A 需代理,通過工廠生成代理),放入二級緩存 → 4. B 初始化完成,注入 A,放入一級緩存 → 5. A 注入 B,完成初始化,放入一級緩存(移除二、三級緩存)。

五、消息隊列(Kafka)

1. 消息不丟失保證
環節措施
生產者-?acks=all:消息需被所有 ISR(同步副本)確認后才算發送成功。
- 開啟重試(retries=N):發送失敗自動重試。
- 用linger.ms批量發送,減少網絡開銷。
Broker-?replication.factor≥3:每個分區至少 3 個副本。
-?min.insync.replicas≥2:ISR 中至少 2 個副本存活才允許寫入。
- 禁用unclean.leader.election.enable(不允許非 ISR 副本成為 leader)。
消費者- 關閉自動提交(enable.auto.commit=false),手動提交偏移量(commitSync())。
- 處理完消息后再提交,避免消費失敗但已提交偏移量。
- 冪等處理:通過消息 ID 去重,防止重復消費。

六、設計模式

1. 單例模式(Singleton Pattern)
  • 概念:保證一個類在整個應用中只有一個實例,并提供一個全局訪問點。
  • 核心思想:通過私有化構造方法,防止外部直接創建實例;在類內部自行創建唯一實例,并提供靜態方法供外部獲取。
  • 適用場景
    • 全局配置類(如讀取配置文件的工具類),確保配置信息一致。
    • 數據庫連接池,避免頻繁創建和關閉連接帶來的性能損耗。
    • 日志工具類,保證日志輸出的一致性和順序性。
  • 注意點:需考慮線程安全問題(如懶漢式需加鎖),以及反射、序列化對單例的破壞。
2. 工廠模式(Factory Pattern)

包括簡單工廠、工廠方法、抽象工廠三種形式:

  • 簡單工廠模式
    • 概念:由一個工廠類根據傳入的參數,動態決定創建哪一種產品類的實例。
    • 適用場景:產品種類較少且固定,如不同類型的日志記錄器(文件日志、控制臺日志)的創建。
  • 工廠方法模式
    • 概念:定義一個創建產品的接口,由子類決定具體創建哪種產品,將產品創建延遲到子類。
    • 適用場景:產品種類可能擴展,如不同數據庫(MySQL、Oracle)的連接工廠,新增數據庫時只需新增對應的工廠子類。
  • 抽象工廠模式
    • 概念:提供一個接口,用于創建一系列相關或相互依賴的產品族,而無需指定具體類。
    • 適用場景:需要創建多個產品族,且產品族內的產品相互關聯,如不同操作系統(Windows、Mac)下的按鈕、文本框等組件族的創建。
3. 觀察者模式(Observer Pattern)
  • 概念:定義對象間的一種一對多依賴關系,當一個對象(被觀察者)狀態發生改變時,所有依賴它的對象(觀察者)會自動收到通知并更新。
  • 核心思想:解耦被觀察者和觀察者,兩者通過抽象接口交互,互不依賴具體實現。
  • 適用場景
    • 事件監聽機制(如 GUI 中的按鈕點擊事件,多個組件監聽同一按鈕)。
    • 消息通知系統(如公眾號推送,訂閱者接收消息)。
    • 狀態變化同步(如股票價格更新,多個指標面板實時刷新)。
4. 裝飾器模式(Decorator Pattern)
  • 概念:動態地給一個對象添加額外的職責,同時不改變其原有的結構。相比繼承,更靈活地擴展功能。
  • 核心思想:通過創建裝飾器類包裹原對象,裝飾器實現與原對象相同的接口,并在調用原對象方法前后添加新功能。
  • 適用場景
    • 功能需要動態擴展且可組合的場景,如 IO 流(BufferedInputStream 裝飾 FileInputStream,增加緩沖功能)。
    • 避免使用多層繼承導致的類爆炸,如給咖啡添加不同配料(牛奶、糖),每種配料作為一個裝飾器。
5. 適配器模式(Adapter Pattern)
  • 概念:將一個類的接口轉換成客戶端期望的另一個接口,使原本因接口不兼容而無法一起工作的類能夠協同工作。
  • 核心思想:創建適配器類,實現目標接口,并持有被適配類的實例,在適配器方法中調用被適配類的對應方法。
  • 適用場景
    • 集成第三方組件,其接口與本地系統接口不匹配時(如第三方支付接口適配本地支付服務)。
    • 舊系統改造,需復用舊類但接口不符合新需求時。
  • 分類
    • 類適配器:通過繼承被適配類實現適配(單繼承限制,較少使用)。
    • 對象適配器:通過持有被適配類實例實現適配(更靈活,常用)。
6. 代理模式(Proxy Pattern)
  • 概念:為其他對象提供一種代理,以控制對原對象的訪問。代理對象在原對象和客戶端之間起到中介作用。
  • 核心思想:代理類與原對象實現同一接口,客戶端通過代理類訪問原對象,代理類可在調用原對象方法前后添加額外邏輯。
  • 適用場景
    • 遠程代理:為遠程對象(如分布式服務)提供本地代理,屏蔽網絡通信細節。
    • 安全代理:控制對敏感對象的訪問(如權限校驗)。
    • 延遲加載:在真正需要時才創建 heavy 資源(如大圖片加載前的代理)。
    • AOP(面向切面編程):如 Spring 的事務管理,通過代理在方法執行前后添加事務控制邏輯。
7. 模板方法模式(Template Method Pattern)
  • 概念:定義一個操作中的算法骨架,將某些步驟延遲到子類中實現。子類可重寫具體步驟,但不改變算法的整體結構。
  • 核心思想:父類中定義模板方法(包含算法骨架),并將可變步驟聲明為抽象方法,由子類實現。
  • 適用場景
    • 多個子類有共同的操作流程,但部分步驟實現不同,如數據庫訪問(連接、執行 SQL、關閉連接的流程固定,SQL 語句和結果處理可變)。
    • 框架設計中,定義核心流程,允許用戶自定義部分邏輯(如 Servlet 的 doGet/doPost 方法,由框架控制調用時機)。
8. 策略模式(Strategy Pattern)
  • 概念:定義一系列算法,將每個算法封裝起來并使它們可相互替換,讓算法的變化獨立于使用算法的客戶端。
  • 核心思想:創建策略接口,不同算法實現該接口;客戶端持有策略接口的引用,可動態切換不同的策略實現。
  • 適用場景
    • 存在多種類似的算法,且需要根據場景動態選擇時(如排序算法,可根據數據量選擇冒泡、快排、歸并等)。
    • 避免使用多重條件判斷(if-else/switch),如電商平臺的折扣策略(新用戶折扣、會員折扣、節日折扣等)。
9. 迭代器模式(Iterator Pattern)
  • 概念:提供一種方法順序訪問聚合對象中的元素,而無需暴露聚合對象的內部結構。
  • 核心思想:定義迭代器接口(包含 hasNext、next 等方法),聚合對象提供獲取迭代器的方法,客戶端通過迭代器遍歷元素。
  • 適用場景
    • 需統一遍歷不同聚合結構(如數組、鏈表、集合)的場景,如 Java 中的 Iterator 接口,可遍歷 List、Set 等不同集合。
    • 避免聚合對象暴露內部實現,如自定義容器類,通過迭代器提供安全的遍歷方式。
10. 命令模式(Command Pattern)
  • 概念:將一個請求封裝為一個對象,使請求的發送者和接收者解耦。發送者只需發送命令對象,無需知道接收者如何處理。
  • 核心思想:創建命令接口(包含執行方法),具體命令類實現接口并持有接收者引用;發送者持有命令對象,通過調用命令的執行方法完成請求。
  • 適用場景
    • 需記錄、撤銷、重做請求的場景(如文本編輯器的撤銷操作,每個編輯命令可被保存和反向執行)。
    • 事件驅動系統(如 GUI 中的按鈕點擊,按鈕持有命令對象,點擊時執行命令)。
    • 批量任務處理(如任務隊列,每個任務封裝為命令,依次執行)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916226.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916226.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916226.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux 系統時間設置(date 和 ntpdate)-linux028

date 命令&#xff1a;查看或設置系統時間1. 查看當前時間date示例輸出&#xff1a;Tue Mar 4 01:36:45 CST 20142. 設置時間&#xff08;不設置日期&#xff09;date -s 09:38:40設置后輸出&#xff1a;Tue Mar 4 09:38:40 CST 20143. 設置完整日期和時間&#xff08;推薦格…

iOS上使用WebRTC推拉流的案例

一、庫集成 首先&#xff0c;確保在你的 Podfile 中添加依賴&#xff1a; pod GoogleWebRTC然后執行 pod install 安裝庫。 二、代碼示例 2.1、權限配置&#xff1a;在 Info.plist 中添加攝像頭、麥克風權限 <!-- 需要在 Info.plist 中添加以下權限 --> <key>NSCam…

API: return response as HTML table

想要把response table變成HTML的table&#xff0c;即想達到下面這種的話<table boarder"1" style"width:100%; boarder-collapse: collapse; text-align:left"><tr><th>Customer</th><th>Date</th><th>Debit Am…

OneNote 當前無法同步筆記。將繼續嘗試。 (錯誤代碼: 0xE00009C8 bb0ur)問題解決

之前因為同步錯誤&#xff0c;導致OneNote一個筆記本內容全部消失&#xff0c;筆記本內容如下圖同步狀態和錯誤如下&#xff1a;提醒錯誤為&#xff1a;OneNote 當前無法同步筆記。將繼續嘗試。 (錯誤代碼: 0xE00009C8 bb0ur)當時心態有點崩&#xff0c;也是查了好些資料&#…

OneCode3.0 Gallery 組件前后端映射機制:從注解配置到前端渲染的完整鏈路

一、注解體系與前端組件的映射基礎 ? OneCode Gallery 組件實現了 Java 注解與前端 UI 組件的深度綁定&#xff0c;通過GalleryAnnotation、GalleryItemAnnotation和GalleryViewAnnotation三個核心注解&#xff0c;構建了從后端配置到前端渲染的完整鏈路。這種映射機制的核心價…

規則分配腳本

需求&#xff1a; 1.根據用戶編寫的要報規則,去mysql庫里SysManage_Rule表獲取已經啟用的規則作為條件&#xff08;例如[{“field”: “關鍵詞”, “logic”: “AND”, “value”: “阿爾法”, “operator”: “”&#xff0c;, “assign_user”: “user222”}]&#xff09;條…

SEO實戰派白楊SEO:SEO中說的框計算、知心搜索(知識圖譜)是什么?有什么用處?

SEO里框計算是什么&#xff1f;有什么用處&#xff1f;SEO里框計劃算是百度2010年提出的&#xff0c;指當用戶搜索某些關鍵詞查詢時&#xff0c;搜索引擎在結果頁直接展示答案的技術&#xff08;如天氣、匯率等&#xff09;&#xff0c;用戶無需點擊網站即可獲取信息&#xff0…

軟件工程:軟件需求

簡介本篇博客記錄了我在軟件工程學習過程中關于軟件需求與面向對象基礎知識的學習體會和要點總結。博客共分為三個關卡內容&#xff1a;第1關圍繞“軟件需求”的定義、分類及分析過程展開&#xff0c;讓我清晰地理解了功能性需求、非功能性需求與約束條件的區別&#xff1b;第2…

MES系統是什么,有哪些特性?

MES系統是一套面向制造企業車間執行層的生產信息化管理系統。它能夠為操作人員和管理人員提供計劃的執行、跟蹤以及所有資源&#xff08;包括人、設備、物料、客戶需求等&#xff09;的當前狀態。通過MES系統可以對從訂單下達到產品完成的整個生產過程進行優化管理。當工廠發生…

Vue2下

六&#xff1a;vue-router &#xff08;重要&#xff09; &#xff08;一&#xff09;. 對路由的理解 1.什么是路由 路由&#xff08;Router&#xff09; 是管理頁面跳轉和 URL 與視圖映射關系的機制&#xff0c;核心作用是&#xff1a;根據不同的 URL 路徑&#xff0c;展示對…

在 Windows 上安裝設置 MongoDB及常見問題

介紹 MongoDB 是一個開源的 NoSQL 數據庫系統&#xff0c;它以一種靈活的類似 JSON 的格式&#xff08;稱為 BSON&#xff08;二進制 JSON&#xff09;&#xff09;存儲數據。它使用動態模式&#xff0c;這意味著與關系型數據庫不同&#xff0c;MongoDB 不需要在向數據庫添加數…

Effective C++ 條款01:視 C++ 為一個語言聯邦

Effective C 條款01&#xff1a;視 C 為一個語言聯邦核心思想&#xff1a;C 是由多個子語言組成的聯邦&#xff0c;每個子語言有自己的編程范式。理解這些子語言及其規則切換&#xff0c;是寫出高效 C 代碼的關鍵。 四個子語言及其規則&#xff1a; C 語言 基礎&#xff1a;過程…

云效CI/CD教程(PHP項目)

參考文檔 參考云效的官方文檔https://help.aliyun.com/zh/yunxiao/ 一、新建代碼庫 這是第一步&#xff0c;和碼云的差不多 二、配SSH密鑰 這個和碼云&#xff0c;github上類似&#xff0c;都需要&#xff0c;云效的SSH密鑰證書不是采用 RSA算法&#xff0c;而是采用了ED2…

單片機是怎么控制的

單片機作為電子系統的控制核心&#xff0c;通過接收外部信號、執行預設程序、驅動外部設備的方式實現控制功能&#xff0c;其控制過程涉及信號輸入、數據處理和指令輸出三個關鍵環節&#xff0c;每個環節的協同配合決定了整體控制效果。 信號輸入&#xff1a;獲取外部信息 單片…

deepseek本地部署,輕松實現編程自由

小伙伴們&#xff0c;大家好&#xff0c;今天我們來實現deepseek本地部署&#xff0c;輕松實現編程自由&#xff01;安裝ollama 安裝ollama 首先我們安裝ollama 打開ollama官網&#xff0c;下載安裝符合自己系統的版本。 找到要安裝的模型deepseek-r1開始-運行 輸入cmd出現…

基礎NLP | 常用工具

編輯器 PycharmVSCodeSpyderPython 自帶 ideVim 機器學習相關python框架 Pytorch 學術界寵兒&#xff0c;調試方便&#xff0c;目前的主流Tensorflow 大名鼎鼎&#xff0c;工程配套完善Keras 高級封裝&#xff0c;簡單好用&#xff0c;現已和Tensorflow合體Gensim 訓練詞向…

Unity3D + VR頭顯 × RTSP|RTMP播放器:構建沉浸式遠程診療系統的技術實踐

一、背景&#xff1a;遠程醫療邁入“沉浸式協同”的新階段 過去&#xff0c;遠程醫療主要依賴視頻會議系統&#xff0c;實現基礎的遠程問診、會診或術中指導。雖然初步解決了地域限制問題&#xff0c;但其單視角、平面化、缺乏沉浸感與交互性的特征&#xff0c;已無法滿足臨床…

海云安斬獲“智能金融創新應用“標桿案例 彰顯AI安全左移技術創新實力

近日&#xff0c;由中國人民銀行廣東省分行、廣東省金融管理局、廣東省政務服務和數據管理局指導&#xff0c;廣東省金融科技協會主辦的“智能金融 創新應用”優秀案例名單最終揭曉&#xff0c;海云安開發者安全助手系統項目憑借其創新的"AI安全左移"技術架構&#x…

Fluent許可與網絡安全策略

在流體動力學模擬領域&#xff0c;Fluent軟件因其卓越的性能和廣泛的應用而備受用戶青睞。然而&#xff0c;隨著網絡安全威脅的不斷增加&#xff0c;確保Fluent許可的安全性和合規性變得尤為重要。本文將探討Fluent許可與網絡安全策略的關系&#xff0c;為您提供一套有效的安全…

如何借助AI工具?打贏通信設備制造的高風險之戰?(案例分享)

你是否曾在項目管理中遇到過那種讓人心跳加速的瞬間&#xff0c;當一項風險突然暴露出來時&#xff0c;全隊似乎都屏住了呼吸&#xff1f;今天&#xff0c;我就來分享一個我親歷的項目案例&#xff0c;講述我們如何借助具體的AI工具&#xff0c;實現從數據到決策的華麗轉變&…