21xrx.com
2025-03-21 01:10:45 Friday
文章检索 我的文章 写文章
Java设计模式面试题及答案解析
2023-06-15 10:57:39 深夜i     23     0
Java 设计模式 面试题

在Java面试中,设计模式是一项非常重要的考察内容。面试官通常会问一些与设计模式相关的问题,以此来考察候选人对于软件设计原则及经验的掌握程度。下面是一些常见的Java设计模式面试题和答案解析,希望对于大家面试有所帮助。

一、单例模式

1. 单例模式的定义及作用?

单例模式是指仅有一个实例的类。这种模式下,该类的实例必须由类自身创建,并同时确保只有允许的单个实例存在于系统中。单例模式主要用于控制类的实例数量,节约系统资源,并保证所有的对象状态一致性。在多线程环境下,应该使用线程安全的单例模式。

2. 实现单例模式的方式有哪些?

a. 饿汉式:在该类类加载的时候就已经创建了静态实例,因此线程安全。

public class Singleton {
    private static Singleton instance = new Singleton();
   
    private Singleton() {}
   
    public static Singleton getInstance()
      return instance;
   
  }

b. 懒汉式:该方式在第一次使用时创建实例,并且存在线程安全问题。可以使用synchronized或volatile关键字保证线程安全。

public class Singleton {
    private static Singleton instance = null;
   
    private Singleton() {}
   
    public static synchronized Singleton getInstance() {
      if (instance == null) {
        instance = new Singleton();
      }
      return instance;
    }
  }

3. 如何保证单例模式线程安全?

可以使用synchronized关键字或者使用volatile关键字。

synchronized关键字的方式可以保证线程安全,但会影响程序性能。

volatile关键字可以保证实例对于所有线程的可见性,但不能保证线程安全。

二、工厂模式

1. 工厂模式的定义及作用?

工厂模式是一种对象创建型设计模式。该模式通过定义工厂类来创建对象,而不是直接调用类的构造函数来创建。工厂模式允许客户端不必知道创建对象的具体类名,通过调用工厂方法来获取所需的对象。由于工厂模式将实例化的过程与具体处理解耦,从而实现了灵活的设计。

2. 工厂模式的实现方式?

工厂模式通常分为简单工厂模式、工厂方法模式和抽象工厂模式。

a. 简单工厂模式:通过工厂类的静态方法创建具体的产品类。

public class SimpleFactory {
    public static Product createProduct(String type) {
      if (type.equals("A")) {
        return new ProductA();
      } else if (type.equals("B")) {
        return new ProductB();
      } else
        return null;
     
    }
  }

b. 工厂方法模式:定义一个抽象工厂类,由具体工厂类来生成具体的产品类。

public interface ProductFactory {
    Product createProduct();
  }
 
  public class ProductAFactory implements ProductFactory {
    @Override
    public Product createProduct() {
      return new ProductA();
    }
  }
 
  public class ProductBFactory implements ProductFactory {
    @Override
    public Product createProduct() {
      return new ProductB();
    }
  }

c. 抽象工厂模式:定义一个抽象工厂类来创建一组产品,每个产品由具体工厂类生产。

public interface AbstractFactory {
    Product createProduct();
  }
 
  public class Factory1 implements AbstractFactory {
    @Override
    public Product createProduct() {
      return new ProductA();
    }
   
    public OtherProduct createOtherProduct() {
      return new OtherProductA();
    }
  }
 
  public class Factory2 implements AbstractFactory {
    @Override
    public Product createProduct() {
      return new ProductB();
    }
   
    public OtherProduct createOtherProduct() {
      return new OtherProductB();
    }
  }

三、代理模式

1. 代理模式的定义及作用?

代理模式是一种设计模式,允许通过代理对象控制对于原对象的访问。代理对象通常充当客户端与原对象之间的中介。代理模式主要用于在无法直接访问对象或者方便控制访问对象时使用。代理模式可以分为静态代理和动态代理。

2. 代理模式的实现方式?

a. 静态代理:代理类和原始类实现同一个接口或继承同一个类。

public interface Subject {
    void request();
  }
 
  public class RealSubject implements Subject {
    @Override
    public void request() {
      System.out.println("real subject request");
    }
  }
 
  public class ProxySubject implements Subject {
    private RealSubject realSubject;
   
    public ProxySubject(RealSubject realSubject)
      this.realSubject = realSubject;
   
   
    public void preRequest() {
      System.out.println("proxy subject pre request");
    }
   
    @Override
    public void request() {
      preRequest();
      realSubject.request();
      postRequest();
    }
   
    public void postRequest() {
      System.out.println("proxy subject post request");
    }
  }

b. 动态代理:由代理类在运行时创建和使用。

public interface Subject {
    void request();
  }
 
  public class RealSubject implements Subject {
    @Override
    public void request() {
      System.out.println("real subject request");
    }
  }
 
  public class DynamicProxy implements InvocationHandler {
    private Object target;
   
    public DynamicProxy(Object target)
      this.target = target;
   
   
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
      System.out.println("dynamic proxy pre request");
      Object result = method.invoke(target, args);
      System.out.println("dynamic proxy post request");
      return result;
    }
  }

  动态代理使用方法:

Subject obj = (Subject) Proxy.newProxyInstance(
      Subject.class.getClassLoader(),
      new Class[] {Subject.class},
      new DynamicProxy(new RealSubject()));

  
  

评论区