当前位置: 首页 > news >正文

北京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.lryc.cn/news/612756.html

相关文章:

  • Node.js特训专栏-实战进阶:21.Nginx反向代理配置
  • 使用Spring Boot + Angular构建安全的登录注册系统
  • 剧本杀小程序系统开发:推动社交娱乐产业创新发展
  • GitCode 7月:小程序积分商城更名成长中心、「探索智能仓颉!Cangjie Magic 体验有奖征文活动」圆满收官、深度对话栏目持续热播
  • qt系统--事件
  • OpenAI推出开源GPT-oss-120b与GPT-oss-20b突破性大模型,支持商用与灵活部署!
  • Numpy科学计算与数据分析:Numpy数组操作入门:合并、分割与重塑
  • 水库大坝安全监测系统主要概述
  • Python 数据类型及数据类型转换
  • Python Socket 脚本深度解析与开发指南
  • 目标检测数据集 - 自动驾驶场景道路异常检测数据集下载「包含VOC、COCO、YOLO三种格式」
  • Jenkins全链路教程——Jenkins用户权限矩阵配置
  • 东莞立晟精密硅胶科技有限公司将携重磅产品亮相 AUTO TECH China 2025 广州国际汽车技术展
  • oracle 11G安装大概率遇到问题
  • 计算机网络:固定网络位长度子网划分flsm和可变长子网掩码划分vlsm的区别
  • QT项目 -仿QQ音乐的音乐播放器(第五节)
  • 全局异常处理器
  • [特殊字符] 未来图钉式 AI 时代的智能生态布局:副脑矩阵与人机共振的系统构想
  • Linux->信号
  • 如何在 VS Code 中进行 `cherry-pick`
  • 计算机毕业设计java疫情防控形势下的高校食堂订餐管理系统 高校食堂订餐管理系统在疫情防控背景下的设计与实现 疫情防控期间高校食堂线上订餐管理平台
  • 【已解决】-bash: mvn: command not found
  • 2025数字马力一面面经(社)
  • [优选算法专题一双指针——两数之和](双指针和哈希表)
  • git branch -a无法查看最新的分支
  • 垃圾桶满溢识别准确率↑32%:陌讯多模态融合算法实战解析
  • 计算机基础·linux系统
  • 一篇文章入门TCP与UDP(保姆级别)
  • Android Auto开发指南
  • KUKA库卡焊接机器人氩气节气设备