欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 明星 > 资深Java工程师的面试题目(三)设计模式

资深Java工程师的面试题目(三)设计模式

2025/9/14 15:02:15 来源:https://blog.csdn.net/haohaizi_liu/article/details/148687595  浏览:    关键词:资深Java工程师的面试题目(三)设计模式

以下是针对Java设计模式的面试题,涵盖常见模式的定义、应用场景、代码示例及优缺点分析,适合评估候选人对设计模式的理解和实际应用能力:


1. 单例模式

题目:

  • 请描述单例模式的实现方式,并说明如何实现线程安全的单例模式。
  • 举一个单例模式的实际应用场景,并解释其优势。

参考答案:

  • 实现方式:

    1. 饿汉式:类加载时初始化实例(线程安全,但可能存在资源浪费)
      public class Singleton {private static final Singleton INSTANCE = new Singleton();private Singleton() {}public static Singleton getInstance() {return INSTANCE;}
      }
      
    2. 懒汉式 + 双重检查锁定(推荐):延迟加载,线程安全且高效
      public class Singleton {private volatile static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
      }
      
    3. 静态内部类:利用类加载机制保证线程安全
      public class Singleton {private Singleton() {}private static class Holder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return Holder.INSTANCE;}
      }
      
  • 应用场景:

    • 数据库连接池:确保全局唯一实例,避免频繁创建/销毁连接。
    • 日志记录器:统一管理日志输出,避免多个实例导致日志混乱。
  • 优势:

    • 节省内存资源,避免重复创建对象。
    • 提供全局访问点,简化系统配置管理。

2. 工厂模式 vs 抽象工厂模式

题目:

  • 比较工厂模式和抽象工厂模式的区别,并举例说明各自的应用场景。
  • 编写一个工厂模式的代码示例,模拟不同类型的数据库连接创建。

参考答案:

  • 区别:

    工厂模式抽象工厂模式
    创建单一产品族的接口(如Shape)。创建多个相关产品族的接口(如DatabaseCache)。
    适用于产品种类较少的场景。适用于需要一组相关对象的场景(如跨平台UI组件)。
  • 工厂模式示例:

    // 接口
    interface Database {void connect();
    }// 具体产品
    class MySQL implements Database {public void connect() {System.out.println("Connected to MySQL");}
    }class PostgreSQL implements Database {public void connect() {System.out.println("Connected to PostgreSQL");}
    }// 工厂类
    class DatabaseFactory {public static Database createDatabase(String type) {if (type.equals("MySQL")) return new MySQL();if (type.equals("PostgreSQL")) return new PostgreSQL();throw new IllegalArgumentException("Unknown database type");}
    }// 使用
    public class Main {public static void main(String[] args) {Database db = DatabaseFactory.createDatabase("MySQL");db.connect();}
    }
    
  • 应用场景:

    • 工厂模式: 数据库连接、日志记录器、支付方式(如支付宝、微信)。
    • 抽象工厂模式: 跨平台UI框架(如Windows和Mac的按钮、文本框)。

3. 观察者模式

题目:

  • 解释观察者模式的定义及其核心组件(主题、观察者),并说明其适用场景。
  • 编写一个观察者模式的代码示例,模拟股票价格更新通知。

参考答案:

  • 定义:
    观察者模式定义对象间的一对多依赖关系,当主题状态变化时,所有依赖者(观察者)自动收到通知并更新。

  • 核心组件:

    • Subject(主题): 维护观察者列表,提供注册/移除观察者的方法。
    • Observer(观察者): 定义更新接口(如update())。
  • 代码示例:

    // 观察者接口
    interface StockObserver {void update(double price);
    }// 主题
    class StockSubject {private List<StockObserver> observers = new ArrayList<>();private double price;public void addObserver(StockObserver observer) {observers.add(observer);}public void removeObserver(StockObserver observer) {observers.remove(observer);}public void setPrice(double price) {this.price = price;notifyObservers();}private void notifyObservers() {for (StockObserver observer : observers) {observer.update(price);}}
    }// 具体观察者
    class Trader implements StockObserver {private String name;public Trader(String name) {this.name = name;}public void update(double price) {System.out.println(name + " received price update: " + price);}
    }// 使用
    public class Main {public static void main(String[] args) {StockSubject stock = new StockSubject();Trader trader1 = new Trader("Alice");Trader trader2 = new Trader("Bob");stock.addObserver(trader1);stock.addObserver(trader2);stock.setPrice(100.5); // 通知所有观察者}
    }
    
  • 适用场景:

    • 事件驱动系统(如GUI事件监听)。
    • 实时数据更新(如股票行情、天气预报)。

4. 策略模式

题目:

  • 请说明策略模式的核心思想,并描述其与工厂模式的区别。
  • 编写一个策略模式的代码示例,模拟不同支付方式(如支付宝、微信、银联)的实现。

参考答案:

  • 核心思想:
    策略模式将算法封装为独立的类,允许在运行时动态切换策略,避免硬编码条件判断。

  • 与工厂模式的区别:

    • 策略模式:关注算法替换(如支付方式)。
    • 工厂模式:关注对象创建(如创建数据库连接)。
  • 代码示例:

    // 策略接口
    interface PaymentStrategy {void pay(double amount);
    }// 具体策略
    class Alipay implements PaymentStrategy {public void pay(double amount) {System.out.println("Paid " + amount + " via Alipay");}
    }class WeChatPay implements PaymentStrategy {public void pay(double amount) {System.out.println("Paid " + amount + " via WeChat");}
    }// 上下文类
    class PaymentContext {private PaymentStrategy strategy;public void setStrategy(PaymentStrategy strategy) {this.strategy = strategy;}public void executePayment(double amount) {strategy.pay(amount);}
    }// 使用
    public class Main {public static void main(String[] args) {PaymentContext context = new PaymentContext();context.setStrategy(new Alipay());context.executePayment(100.0);context.setStrategy(new WeChatPay());context.executePayment(50.0);}
    }
    
  • 适用场景:

    • 动态切换算法(如排序策略、折扣计算)。
    • 避免冗长的条件判断语句(如支付方式、日志格式)。

5. 装饰器模式

题目:

  • 解释装饰器模式的定义,并说明其与继承的区别。
  • 编写一个装饰器模式的代码示例,模拟为咖啡添加不同配料(如牛奶、糖)。

参考答案:

  • 定义:
    装饰器模式通过组合方式动态添加对象功能,避免子类爆炸问题。

  • 与继承的区别:

    • 继承:静态扩展功能,灵活性差。
    • 装饰器:动态组合功能,更灵活且符合开闭原则。
  • 代码示例:

    // 抽象组件
    interface Coffee {double cost();String description();
    }// 具体组件
    class BlackCoffee implements Coffee {public double cost() { return 2.0; }public String description() { return "Black Coffee"; }
    }// 装饰器抽象类
    abstract class CoffeeDecorator implements Coffee {protected Coffee decoratedCoffee;public CoffeeDecorator(Coffee coffee) {this.decoratedCoffee = coffee;}
    }// 具体装饰器
    class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}public double cost() {return decoratedCoffee.cost() + 0.5;}public String description() {return decoratedCoffee.description() + ", Milk";}
    }class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}public double cost() {return decoratedCoffee.cost() + 0.2;}public String description() {return decoratedCoffee.description() + ", Sugar";}
    }// 使用
    public class Main {public static void main(String[] args) {Coffee coffee = new BlackCoffee();coffee = new MilkDecorator(coffee);coffee = new SugarDecorator(coffee);System.out.println("Cost: " + coffee.cost());System.out.println("Description: " + coffee.description());}
    }
    
  • 适用场景:

    • 动态添加功能(如IO流、文本格式化)。
    • 避免类继承层次过深。

6. 责任链模式

题目:

  • 请描述责任链模式的核心思想,并举一个实际应用场景。
  • 编写一个责任链模式的代码示例,模拟审批流程(如经理、总监、CEO)。

参考答案:

  • 核心思想:
    将请求的处理责任链式传递,避免请求发送者与处理者直接耦合。

  • 应用场景:

    • 审批流程(如报销审批、权限校验)。
    • 异常处理(如HTTP中间件)。
  • 代码示例:

    // 处理者接口
    abstract class Approver {protected Approver nextApprover;public void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}public abstract void processRequest(double amount);
    }// 具体处理者
    class Manager extends Approver {public void processRequest(double amount) {if (amount <= 1000) {System.out.println("Manager approved: " + amount);} else if (nextApprover != null) {nextApprover.processRequest(amount);}}
    }class Director extends Approver {public void processRequest(double amount) {if (amount <= 5000) {System.out.println("Director approved: " + amount);} else if (nextApprover != null) {nextApprover.processRequest(amount);}}
    }class CEO extends Approver {public void processRequest(double amount) {System.out.println("CEO approved: " + amount);}
    }// 使用
    public class Main {public static void main(String[] args) {Approver manager = new Manager();Approver director = new Director();Approver ceo = new CEO();manager.setNextApprover(director);director.setNextApprover(ceo);manager.processRequest(800);   // Managermanager.processRequest(3000);  // Directormanager.processRequest(10000); // CEO}
    }
    
  • 优势:

    • 解耦请求发送者和处理者。
    • 灵活调整责任链顺序(如增加新审批角色)。

7. 代理模式

题目:

  • 解释代理模式的定义,并说明静态代理与动态代理的区别。
  • 编写一个代理模式的代码示例,模拟远程服务调用的性能监控。

参考答案:

  • 定义:
    代理模式为其他对象提供一种代理以控制对这个对象的访问。

  • 静态代理 vs 动态代理:

    静态代理动态代理
    手动编写代理类。运行时动态生成代理类(如JDK Proxy)。
    适用于固定接口。适用于任意接口。
  • 代码示例:

    // 接口
    interface Service {void execute();
    }// 实现类
    class RealService implements Service {public void execute() {System.out.println("Executing service...");try {Thread.sleep(1000); // 模拟耗时操作} catch (InterruptedException e) {e.printStackTrace();}}
    }// 代理类
    class ServiceProxy implements Service {private Service realService;public ServiceProxy() {this.realService = new RealService();}public void execute() {long startTime = System.currentTimeMillis();realService.execute();long endTime = System.currentTimeMillis();System.out.println("Execution time: " + (endTime - startTime) + "ms");}
    }// 使用
    public class Main {public static void main(String[] args) {Service service = new ServiceProxy();service.execute();}
    }
    
  • 适用场景:

    • 远程调用(如RPC)。
    • 权限控制、日志记录、缓存等。

8. 模板方法模式

题目:

  • 请描述模板方法模式的核心思想,并编写一个代码示例,模拟不同饮料的制作流程。

参考答案:

  • 核心思想:
    定义算法骨架,将某些步骤延迟到子类实现,避免代码重复。

  • 代码示例:

    // 抽象类
    abstract class Beverage {// 模板方法(final防止覆盖)public final void prepareRecipe() {boilWater();brew();pourInCup();addCondiments();}// 公共步骤private void boilWater() {System.out.println("Boiling water");}protected abstract void brew();private void pourInCup() {System.out.println("Pouring into cup");}protected abstract void addCondiments();// 钩子方法(可选覆盖)public boolean customerWantsCondiments() {return true;}
    }// 具体类
    class Coffee extends Beverage {protected void brew() {System.out.println("Brewing coffee");}protected void addCondiments() {if (customerWantsCondiments()) {System.out.println("Adding sugar and milk");}}public boolean customerWantsCondiments() {return false; // 用户不想要糖和奶}
    }class Tea extends Beverage {protected void brew() {System.out.println("Steeping tea");}protected void addCondiments() {System.out.println("Adding lemon");}
    }// 使用
    public class Main {public static void main(String[] args) {Beverage coffee = new Coffee();coffee.prepareRecipe();Beverage tea = new Tea();tea.prepareRecipe();}
    }
    
  • 适用场景:

    • 多步骤算法(如编译器、测试框架)。
    • 避免重复代码(如日志记录、事务管理)。

9. 适配器模式

题目:

  • 解释适配器模式的定义,并说明其与装饰器模式的区别。
  • 编写一个适配器模式的代码示例,模拟旧接口与新接口的兼容。

参考答案:

  • 定义:
    适配器模式将一个类的接口转换为客户期望的另一个接口,使原本不兼容的类可以协同工作。

  • 与装饰器模式的区别:

    • 适配器适配接口(解决兼容性问题)。
    • 装饰器增强功能(不改变接口,仅扩展行为)。
  • 代码示例:

    // 旧接口
    interface OldService {void oldMethod();
    }// 新接口
    interface NewService {void newMethod();
    }// 适配器类
    class Adapter implements NewService {private OldService oldService;public Adapter(OldService oldService) {this.oldService = oldService;}public void newMethod() {oldService.oldMethod(); // 适配旧接口}
    }// 使用
    public class Main {public static void main(String[] args) {OldService old = new OldService() {public void oldMethod() {System.out.println("Old method called");}};NewService newService = new Adapter(old);newService.newMethod(); // 输出 "Old method called"}
    }
    
  • 适用场景:

    • 集成第三方库(如旧系统对接新API)。
    • 适配遗留代码。

10. 备忘录模式

题目:

  • 请描述备忘录模式的定义,并编写一个代码示例,模拟游戏存档功能。

参考答案:

  • 定义:
    备忘录模式用于保存对象的内部状态,并在需要时恢复状态(撤销/重做)。

  • 代码示例:

    // 原发器类
    class Game {private int level;private int score;public Game(int level, int score) {this.level = level;this.score = score;}public Memento save() {return new Memento(level, score);}public void restore(Memento memento) {this.level = memento.getLevel();this.score = memento.getScore();}public void play() {level++;score += 10;}public void display() {System.out.println("Level: " + level + ", Score: " + score);}
    }// 备忘录类
    class Memento {private final int level;private final int score;public Memento(int level, int score) {this.level = level;this.score = score;}public int getLevel() {return level;}public int getScore() {return score;}
    }// 使用
    public class Main {public static void main(String[] args) {Game game = new Game(1, 0);game.play(); game.display(); // Level 2, Score 10Memento saved = game.save();game.play(); game.display(); // Level 3, Score 20game.restore(saved); game.display(); // 恢复到 Level 2, Score 10}
    }
    
  • 适用场景:

    • 游戏存档、编辑器撤销操作。
    • 事务回滚、数据库快照。

总结

以上题目覆盖了Java设计模式的核心知识点,包括创建型、结构型、行为型模式的应用。通过这些问题,可以全面评估候选人对设计模式的理解深度、实际编码能力以及对面向对象设计原则(如开闭原则、单一职责原则)的掌握程度。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词