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));
}
}