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

java设计模式面试题3道

面试题1:单例模式(Singleton Pattern)
题目:请实现一个线程安全的单例模式,并解释为什么需要使用volatile关键字。
考察点:
对单例模式的理解。
线程安全的实现方式。
对volatile关键字的理解。
参考答案:
单例模式确保一个类只有一个实例,并提供一个全局访问点。线程安全的单例模式可以通过双重校验锁(DCL)实现。代码如下:
java
复制
public class Singleton {
private static volatile Singleton instance = null;

private Singleton() {
    // 私有构造函数,防止外部实例化
}

public static Singleton getInstance() {
    if (instance == null) { // 第一次检查
        synchronized (Singleton.class) { // 同步块
            if (instance == null) { // 第二次检查
                instance = new Singleton();
            }
        }
    }
    return instance;
}

}
解释:
双重校验锁(DCL):通过两次检查instance是否为null,避免不必要的同步,提高性能。
volatile关键字:防止指令重排序问题。在多线程环境下,instance = new Singleton()可能会被JVM优化为以下步骤:
分配内存空间。
调用构造函数初始化对象。
将instance指向分配的内存空间。
如果没有volatile,步骤3可能会被提前,导致其他线程看到未完全初始化的instance,从而引发错误。
拓展问题:
如何通过枚举实现单例模式?
如何防止单例被反射破坏?
面试题2:工厂模式(Factory Pattern)
题目:请实现一个简单的工厂模式,用于创建不同类型的支付方式(如微信支付、支付宝支付)。
考察点:
对工厂模式的理解。
编码能力。
对接口和多态的掌握。
参考答案:
工厂模式是一种创建型设计模式,用于封装对象的创建逻辑。以下是简单工厂模式的实现:
java
复制
// 支付接口
interface Payment {
void pay();
}

// 微信支付
class WeChatPay implements Payment {
@Override
public void pay() {
System.out.println(“Paying via WeChat…”);
}
}

// 支付宝支付
class Alipay implements Payment {
@Override
public void pay() {
System.out.println(“Paying via Alipay…”);
}
}

// 工厂类
class PaymentFactory {
public static Payment getPayment(String type) {
if (“wechat”.equalsIgnoreCase(type)) {
return new WeChatPay();
} else if (“alipay”.equalsIgnoreCase(type)) {
return new Alipay();
} else {
throw new IllegalArgumentException("Unsupported payment type: " + type);
}
}
}

// 客户端代码
public class Client {
public static void main(String[] args) {
Payment payment = PaymentFactory.getPayment(“wechat”);
payment.pay();
}
}
拓展问题:
简单工厂模式和工厂方法模式的区别是什么?
如何将上述代码改为工厂方法模式?
面试题3:策略模式(Strategy Pattern)
题目:请实现一个策略模式,用于计算不同类型的折扣(如无折扣、9折、8折)。
考察点:
对策略模式的理解。
对接口和多态的掌握。
编码能力。
参考答案:
策略模式是一种行为型设计模式,用于定义一系列算法,并将它们封装在独立的类中,客户端可以根据需求动态选择算法。
java
复制
// 折扣策略接口
interface DiscountStrategy {
double calculate(double price);
}

// 无折扣策略
class NoDiscountStrategy implements DiscountStrategy {
@Override
public double calculate(double price) {
return price;
}
}

// 9折策略
class TenPercentDiscountStrategy implements DiscountStrategy {
@Override
public double calculate(double price) {
return price * 0.9;
}
}

// 8折策略
class TwentyPercentDiscountStrategy implements DiscountStrategy {
@Override
public double calculate(double price) {
return price * 0.8;
}
}

// 上下文类
class DiscountContext {
private DiscountStrategy strategy;

public DiscountContext(DiscountStrategy strategy) {
    this.strategy = strategy;
}

public double applyDiscount(double price) {
    return strategy.calculate(price);
}

public void setStrategy(DiscountStrategy strategy) {
    this.strategy = strategy;
}

}

// 客户端代码
public class Client {
public static void main(String[] args) {
DiscountContext context = new DiscountContext(new NoDiscountStrategy());
System.out.println("Price with no discount: " + context.applyDiscount(100));

    context.setStrategy(new TenPercentDiscountStrategy());
    System.out.println("Price with 10% discount: " + context.applyDiscount(100));

    context.setStrategy(new TwentyPercentDiscountStrategy());
    System.out.println("Price with 20% discount: " + context.applyDiscount(100));
}

}


http://www.kler.cn/a/586680.html

相关文章:

  • 高级java每日一道面试题-2025年2月18日-数据库篇-MySQL 如何做到高可用方案?
  • Java开发之数据库应用:记一次医疗系统数据库迁移引发的异常:从MySQL到PostgreSQL的“dual“表陷阱与突围之路
  • 串排序(信息学奥赛一本通-2048)
  • 【虚幻C++笔记】引擎源码下载及编译步骤
  • Let’s Build AI- 实用AI导航网站
  • 正则表达式全解析 + Java常用示例
  • 多线程到底重不重要?
  • 双指针算法专题之——盛最多水的容器
  • 洛谷P4376 [USACO18OPEN] Milking Order G
  • 垃圾收集算法
  • R语言的移动应用开发
  • JavaWeb全链路学习:8、数据库-sql语句
  • 【免费】1949-2020年各省人均GDP数据
  • C++基础 [三] - 面向对象三
  • 基于SpringBoot实现旅游酒店平台功能十六
  • 【实用技巧】如何优雅的批量保存网页快照?
  • 每日复盘20250314
  • 零基础上手Python数据分析 (5):Python文件操作 - 轻松读写,数据导入导出不再是难题
  • 零基础上手Python数据分析 (3):Python核心语法快速入门 (下) - 程序流程控制、函数与模块
  • 嵌入式八股,为什么单片机中不使用malloc函数