北京JAVA基礎面試30天打卡04

1. 單例模式的實現方式及線程安全

單例模式(Singleton Pattern)確保一個類只有一個實例,并提供一個全局訪問點。以下是常見的單例模式實現方式,以及如何保證線程安全:

單例模式的實現方式
  1. 餓漢式(Eager Initialization)

    • 實現:在類加載時就創建實例(靜態初始化)。

    • 代碼示例

      public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}}
      
    • 線程安全:天生線程安全,因為實例在類加載時創建,JVM保證類加載過程是線程安全的。

    • 優缺點:簡單,但可能會導致資源浪費(如果實例未被使用)。

  2. 懶漢式(Lazy Initialization)

    • 實現:在第一次調用時創建實例。

    • 代碼示例(非線程安全)

      public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}
      
    • 線程安全問題:多線程環境下,可能多個線程同時判斷instance == null,導致多次創建實例。

    • 改進(加鎖)

      public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
      }
      
      • 使用synchronized關鍵字保證線程安全,但鎖粒度較大,性能較低。
  3. 雙重檢查鎖(Double-Checked Locking)

    • 實現:在懶漢式基礎上優化,使用雙重檢查和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防止指令重排序,確保實例初始化完成前其他線程不會訪問;雙重檢查減少鎖的開銷。

    • 優缺點:性能較高,但代碼稍復雜。

  4. 靜態內部類(Static Inner Class)

    • 實現:利用靜態內部類的延遲加載特性。

    • 代碼示例

      public class Singleton {private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}}
      
    • 線程安全:JVM保證靜態內部類加載時是線程安全的,且只有在調用getInstance時才加載SingletonHolder,實現懶加載。

    • 優缺點:兼顧懶加載和線程安全,推薦使用。

  5. 枚舉單例(Enum Singleton)

    • 實現:利用Java枚舉類型的特性。

    • 代碼示例

      public enum Singleton {INSTANCE;public void doSomething() {// 業務邏輯}}
      
    • 線程安全:JVM保證枚舉的實例化是線程安全的,且能防止反射和序列化破壞單例。

    • 優缺點:簡潔、安全,但不適合復雜的初始化邏輯。

保證線程安全的關鍵點
  • 餓漢式和枚舉:天生線程安全,依賴JVM類加載機制。

  • 懶漢式:需加鎖(如synchronized)或使用雙重檢查鎖。

  • 雙重檢查鎖:結合volatile和synchronized,防止指令重排序和多線程競爭。

  • 靜態內部類:利用JVM類加載機制,延遲加載且線程安全。

  • 序列化和反射攻擊

    • 防止反射:構造函數拋出異常或使用枚舉。

    • 防止序列化破壞:在類中添加

      readResolve

   private Object readResolve() {return instance;

2. 策略模式(Strategy Pattern)

定義

策略模式是一種行為型設計模式,定義一系列算法(策略),將每個算法封裝起來,并使它們可以互換。客戶端可以根據需要選擇不同的策略,而不改變調用代碼。

核心組成
  • 抽象策略接口(Strategy):定義算法的接口。
  • 具體策略類(ConcreteStrategy):實現具體算法。
  • 上下文類(Context):持有策略接口的引用,負責調用具體策略。
代碼示例
// 策略接口interface Strategy {int execute(int a, int b);
}// 具體策略:加法
class AddStrategy implements Strategy {@Overridepublic int execute(int a, int b) {return a + b;}
}// 具體策略:減法class SubtractStrategy implements Strategy {@Overridepublic int execute(int a, int b) {return a - b;}
}// 上下文class Context {private Strategy strategy;public void setStrategy(Strategy strategy) {this.strategy = strategy;}public int executeStrategy(int a, int b) {return strategy.execute(a, b);}
}// 使用public class Main {public static void main(String[] args) {Context context = new Context();context.setStrategy(new AddStrategy());System.out.println(context.executeStrategy(5, 3)); // 輸出 8context.setStrategy(new SubtractStrategy());System.out.println(context.executeStrategy(5, 3)); // 輸出 2}}
使用場景
  • 多種算法或行為:當一個類有多種行為,且這些行為可以根據上下文動態切換時(如支付方式:微信、支付寶、銀行卡)。

  • 避免條件語句:替代大量if-else或switch語句,使代碼更清晰。

  • 算法獨立性:需要將算法與客戶端代碼解耦,方便擴展和維護。

  • 典型案例

    • 排序算法選擇(如快速排序、歸并排序)。
    • 支付系統(不同支付方式)。
    • 游戲中的角色技能(不同技能效果)。
優缺點
  • 優點:靈活、可擴展,符合開閉原則;代碼復用性高。
  • 缺點:客戶端需要了解所有策略;策略類可能較多。

3. 模板方法模式(Template Method Pattern)

定義

模板方法模式是一種行為型設計模式,定義一個操作的算法骨架,將某些步驟延遲到子類實現。父類控制算法流程,子類提供具體實現。

核心組成
  • 抽象模板類(AbstractClass):定義算法骨架(模板方法)和抽象方法。
  • 具體子類(ConcreteClass):實現抽象方法,提供具體邏輯。
代碼示例
// 抽象模板類abstract class AbstractClass {// 模板方法,定義算法骨架public final void templateMethod() {step1();step2();step3();}protected abstract void step1();protected abstract void step2();protected void step3() { // 可選的鉤子方法 也就是子類可以選擇性進行重寫,不重寫默認執行父類方法System.out.println("Default step3");}
}// 具體子類class ConcreteClass extends AbstractClass {@Overrideprotected void step1() {System.out.println("ConcreteClass: Step 1");}@Overrideprotected void step2() {System.out.println("ConcreteClass: Step 2");}@Overrideprotected void step3() {System.out.println("ConcreteClass: Custom Step 3");}
}// 使用public class Main {public static void main(String[] args) {AbstractClass process = new ConcreteClass();process.templateMethod();}}
使用場景
  • 固定算法骨架:當多個類共享相同的算法流程,但部分步驟的實現不同(如數據處理流程:讀取、處理、保存)。

  • 代碼復用:通過父類定義公共邏輯,子類只實現差異化部分。

  • 控制子類擴展:通過final模板方法限制子類修改算法結構。

  • 典型案例

    • 框架中的生命周期方法(如Spring的ApplicationContext初始化)。
    • 游戲開發中關卡流程(加載、運行、結束)。
    • 報表生成(數據采集、格式化、輸出)。
優缺點
  • 優點:提高代碼復用性;算法結構統一,易于維護;符合開閉原則。

  • 缺點:子類數量可能增多;父類設計復雜時可能限制靈活性。

  • 使用場景適合抽象類適合接口
    需要代碼復用? 適合,支持方法和成員變量實現? 不適合(除非 default 方法)
    表示“是什么”(is-a)? 抽象類適合建層次結構? 接口更適合“能做什么”
    表示“能做什么”(has ability to)?? 非常適合,比如 Serializable, Runnable
    要求多個類共享部分邏輯? 用抽象類抽取通用部分? 接口不適合寫邏輯實現
    實現多個類型/能力組合? 不能多繼承? 接口天生支持多繼承

總結對比

  • 單例模式:確保單一實例,關注對象創建,需考慮線程安全(如雙重檢查鎖、靜態內部類)。
  • 策略模式:關注行為切換,適合動態選擇算法,解耦客戶端與算法實現。
  • 模板方法模式:關注算法骨架,適合固定流程但細節可變,強調繼承和復用。

拓展:責任鏈模式(Chain of Responsibility Pattern)是一種行為型設計模式,用于將請求的發送者和接收者解耦,使多個對象都有機會處理這個請求。該模式將處理請求的對象組成一條鏈,請求沿著這條鏈傳遞,直到被某個對象處理為止。

結構圖(類圖)

Client --> Handler1 --> Handler2 --> Handler3 --> …
核心類圖包括:

Handler(抽象處理者)

定義處理請求的接口。

持有下一個處理者的引用。

ConcreteHandler(具體處理者)

實現請求處理的邏輯。

如果自己不能處理,則將請求轉發給下一個處理者。

Client(客戶端)

創建處理鏈,并將請求傳入第一個處理者。

** 應用場景
審批流程(如:員工請假、軟件發布等)**

Java Web 的 Filter 過濾器鏈

Spring Security 的認證授權鏈

Netty 的 ChannelPipeline

🧑?💻 Java 示例(審批流程)
比如一個請假流程,組長可以審批 1 天,經理可以審批 3 天,總監可以審批 7 天:

抽象處理者


```java
public abstract class LeaveHandler {protected LeaveHandler next;public void setNext(LeaveHandler next) {this.next = next;}public abstract void handleRequest(int days);
}

具體處理者

public class TeamLeader extends LeaveHandler {@Overridepublic void handleRequest(int days) {if (days <= 1) {System.out.println("組長審批了 " + days + " 天的假期");} else if (next != null) {next.handleRequest(days);}}
}public class Manager extends LeaveHandler {@Overridepublic void handleRequest(int days) {if (days <= 3) {System.out.println("經理審批了 " + days + " 天的假期");} else if (next != null) {next.handleRequest(days);}}
}public class Director extends LeaveHandler {@Overridepublic void handleRequest(int days) {if (days <= 7) {System.out.println("總監審批了 " + days + " 天的假期");} else {System.out.println("假期太長,不批準");}}
}

客戶端調用

public class Client {public static void main(String[] args) {LeaveHandler teamLeader = new TeamLeader();LeaveHandler manager = new Manager();LeaveHandler director = new Director();teamLeader.setNext(manager);manager.setNext(director);teamLeader.handleRequest(2); // 輸出:經理審批了 2 天的假期teamLeader.handleRequest(6); // 輸出:總監審批了 6 天的假期teamLeader.handleRequest(10); // 輸出:假期太長,不批準}
}

1.責任鏈模式的優點?
解耦請求發送者和接收者。
動態調整處理鏈,靈活性高。
單一職責,每個處理者專注特定請求。
2.缺點?
請求可能未被處理。
鏈過長影響性能。
調試復雜。

3.使用場景?
日志系統(如不同級別日志處理)。
事件處理(如 GUI 事件傳遞)。
審批流程(如逐級審批)。

4.如何避免請求未被處理?
設置默認處理者。
確保鏈配置完整。

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

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

相關文章

Redis 緩存三大核心問題:穿透、擊穿與雪崩的深度解析

引言在現代互聯網架構中&#xff0c;緩存是提升系統性能、降低數據庫壓力的核心手段之一。而 Redis 作為高性能的內存數據庫&#xff0c;憑借其豐富的數據結構、靈活的配置選項以及高效的網絡模型&#xff0c;已經成為緩存領域的首選工具。本文將從 Redis 的基本原理出發&#…

耘瞳科技國產化點云處理軟件,開啟智能化三維測量新時代

在現代工業制造領域&#xff0c;三維點云數據已成為推動生產效率提升、質量控制優化以及智能制造轉型的關鍵技術之一。三維點云數據能夠提供高精度的物體表面信息&#xff0c;廣泛應用于制造零件的質量檢測&#xff1b;通過點云數據與CAD模型的對比分析&#xff0c;可以快速檢測…

RabbitMQ面試精講 Day 8:死信隊列與延遲隊列實現

【RabbitMQ面試精講 Day 8】死信隊列與延遲隊列實現 文章標簽 RabbitMQ,消息隊列,死信隊列,延遲隊列,面試技巧,分布式系統 文章簡述 本文是"RabbitMQ面試精講"系列第8天&#xff0c;深入講解死信隊列與延遲隊列的實現原理與實戰應用。文章詳細解析死信隊列的觸發…

團結引擎 1.5.0 版本發布:Android App View 功能詳解

核心亮點 原生安卓應用支持 2D & 3D 雙形態呈現 編輯器全流程集成 靈活調控功能 多應用并行展示 智能座艙應用示例 快速入門指南 開發說明 功能支持 實驗性功能 資源鏈接 團結引擎 1.5.0 版本已于 4 月 14 日正式上線。本次更新中&#xff0c;車機版引入了一項突…

基于SpringBoot的OA辦公系統的設計與實現

文章目錄前言詳細視頻演示具體實現截圖后端框架SpringBoot持久層框架MyBaits成功系統案例&#xff1a;代碼參考數據庫源碼獲取前言 博主介紹:CSDN特邀作者、985高校計算機專業畢業、現任某互聯網大廠高級全棧開發工程師、Gitee/掘金/華為云/阿里云/GitHub等平臺持續輸出高質量…

知識隨記-----用 Qt 打造優雅的密碼輸入框:添加右側眼睛圖標切換顯示

Qt 技巧&#xff1a;通過 QLineEdit 右側眼睛圖標實現密碼可見性切換 文章目錄Qt 技巧&#xff1a;通過 QLineEdit 右側眼睛圖標實現密碼可見性切換概要整體架構流程技術名詞解釋技術細節實現效果展示概要 本文介紹如何使用 Qt 框架為 QLineEdit 控件添加一個右側的眼睛圖標&a…

Unity里的對象旋轉數值跳轉問題的原理與解決方案

文章目錄1. 問題描述2. 問題原因3. 解決方案3.1通過多個父子關系從而控制旋轉&#xff08;推薦&#xff09;3.2 使用四元數進行旋轉1. 問題描述 我們現在寫一個3D的Unity程序&#xff0c;我們現在設置了一個物體后&#xff0c;我們想旋轉使其改為我們想要的情況。但是我們如果…

為什么現代 C++ (C++11 及以后) 推薦使用 constexpr和模板 (Templates) 作為宏 (#define) 的替代品??

我們用現實世界的比喻來深入理解??為什么 C 中的宏 (#define) 要謹慎使用&#xff0c;以及為什么現代 C (C11 及以后) 推薦使用 constexpr 和模板 (Templates) 作為替代品。??&#x1f9e9; ??核心問題&#xff1a;宏 (#define) 是文本替換??想象宏是一個 ??“無腦的…

PyCharm vs. VSCode 到底哪個更好用

在 Python 開發者中&#xff0c;關于 PyCharm 和 VSCode 的討論從未停止。一個是功能齊備的集成開發環境&#xff08;IDE&#xff09;&#xff0c;另一個是輕快靈活的代碼編輯器。它們代表了兩種不同的開發哲學&#xff0c;選擇哪個&#xff0c;往往取決于你的項目需求、個人習…

FPGA學習筆記——VGA彩條顯示

目錄 一、任務 二、分析 三、代碼 四、實驗現象 五、更新 一、任務 使用VGA實現彩條顯示&#xff0c;模式是640x48060。 二、分析 首先&#xff0c;模式是640x48060&#xff0c;那么對照以下圖標&#xff0c;知道其它信息&#xff0c;不清楚時序和VGA掃描方式的可以看看這…

ES-301A :讓 Modbus 設備無縫接入工業以太網的高效橋梁

在工業自動化領域&#xff0c;串口設備與以太網的互聯互通是提升系統效率的關鍵。ES-301A 工業以太網串口網關作為上海泗博自動化精心打造的專業解決方案&#xff0c;以強大的協議轉換能力、工業級可靠性和靈活配置特性&#xff0c;成為連接 Modbus RTU/ASCII 設備與 Modbus TC…

【學習筆記】FTP庫函數學習

【學習筆記】FTP庫函數學習 FTP基本指令步驟 1、初始化會話句柄&#xff1a;CURL *curl curl_easy_init(); 2、設置會話選項&#xff1a; 設置服務器地址&#xff0c;設置登錄用戶和密碼 curl_easy_setopt(curl, CURLOPT_URL, ftp_server); curl_easy_setopt(curl, CURLOPT_US…

ARM Cortex-M異常處理高級特性詳解

1. 異常處理概述 ARM Cortex-M處理器提供了高效的異常處理機制&#xff0c;包含多種硬件優化特性&#xff0c;顯著提升了中斷響應性能和系統效率。這些特性對于實時嵌入式系統和網絡協議棧&#xff08;如LwIP&#xff09;的性能至關重要。 1.1 Cortex-M異常處理架構 Cortex-M異…

【圖像算法 - 08】基于 YOLO11 的抽煙檢測系統(包含環境搭建 + 數據集處理 + 模型訓練 + 效果對比 + 調參技巧)

一、項目背景與需求 【打怪升級 - 08】基于 YOLO11 的抽煙檢測系統&#xff08;包含環境搭建 數據集處理 模型訓練 效果對比 調參技巧&#xff09;今天我們使用YOLO11來訓練一個抽煙檢測系統&#xff0c;基于YOLO11的抽煙檢測系統。我們使用了大概兩萬張圖片的數據集訓練了…

vue2升級vue3中v-model的寫法改造

vue2選項式 <template><div><el-rowclass"group-title":title"$t(restore_default_parameters)">{{ $t(restore_default_parameters) }}</el-row><el-form-item :label"$t(restore_default_parameters)" class"…

5G-LEO 簡介

1. 什么是 5G-LEO 5G-LEO 指的是將 5G 新空口&#xff08;5G NR&#xff09;服務擴展到低軌衛星&#xff08;LEO&#xff09;上的非地面網絡&#xff08;NTN, Non-Terrestrial Network&#xff09;方案。通過在距地面約500–2 000 km 的低軌道衛星上部署通信載荷&#xff0c;5G…

【MCAL】AUTOSAR架構下SPI數據同步收發具體實現

目錄 前言 正文 1.依賴的SPI硬件特性 1.1. SPI時隙參數配置 1.2. SPI數據發送和接收模式 2.MCAL中的SPI配置 3.軟件的具體實現 3.1. Spi_SyncTransmit 3.2. Spi_lSyncTransmit 3.3. Spi_lSyncStartJob 3.4. Spi_lSyncTransmitData8Bit 3.5. Spi_lSynTransErrCheck …

SQL157 更新記錄(一)

描述現有一張試卷信息表examination_info&#xff0c;表結構如下圖所示&#xff1a;FiledTypeNullKeyExtraDefaultCommentidint(11)NOPRIauto_increment(NULL)自增IDexam_idint(11)NOUNI(NULL)試卷IDtagchar(32)YES(NULL)類別標簽difficultychar(8)YES(NULL)難度durationint(11…

懸賞任務系統小程序/APP源碼,推薦任務/發布任務/會員服務

1. 我們承諾及優勢本店源碼承諾&#xff1a;1&#xff09;. 店長親測 - 100%完整可運行2&#xff09;. 含詳細安裝文檔3&#xff09;. 支持二次開發定制4&#xff09;. 專業客服隨時解答5&#xff09;. 技術團隊保障質量2. 功能詳細說明主要功能 模塊 角色 解釋說明 用戶登錄和…

Ubuntu20.04系統上使用YOLOv5訓練自己的模型-1

在Ubuntu系統上使用YOLOv5訓練自己的模型&#xff0c;你需要遵循以下步驟。這里我將詳細說明如何從準備數據集到訓練模型的整個過程。 步驟 1: 安裝依賴項 首先&#xff0c;確保你的Ubuntu系統上安裝了Python、PyTorch和必要的庫。你可以使用以下命令安裝這些依賴項&#xff1a…