Java面试题——第二篇(设计模式)

1. 工厂方法模式

1.1 普通工厂模式

建立一个工厂类,对实现了同一接口的一些类进行实例的创建。

1.2 抽象工厂模式

抽象多个工厂类,提高工厂的可扩展性

定义抽象工厂接口

java 复制代码
public interface DeviceFactory {  
    Phone createPhone();  
    Computer createComputer();  
}

实现具体工厂类

java 复制代码
// 华为工厂  
public class HuaweiFactory implements DeviceFactory {  
    @Override  
    public Phone createPhone() {  
        return new HuaweiPhone();  
    }  
    @Override  
    public Computer createComputer() {  
        // 假设华为工厂目前只生产手机  
        return null;  
    }  
}  
// 苹果工厂  
public class AppleFactory implements DeviceFactory {  
    @Override  
    public Phone createPhone() {  
        return new iPhone();  
    }  
  
    @Override  
    public Computer createComputer() {  
        return new MacComputer();  
    }  
}

客户端使用

java 复制代码
public class Client {  
    public static void main(String[] args) {  
        // 使用华为工厂  
        DeviceFactory huaweiFactory = new HuaweiFactory();  
        Phone huaweiPhone = huaweiFactory.createPhone();  
        huaweiPhone.call();  
  
        // 使用苹果工厂  
        DeviceFactory appleFactory = new AppleFactory();  
        Phone iphone = appleFactory.createPhone();  
        iphone.call();  
        Computer macComputer = appleFactory.createComputer();  
        macComputer.surfInternet();  
    }  
}

2. 单例模式

保证在一个JVM中,该对象只有一个实例存在。

使用场景:

  • 某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
  • 省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
  • 有些例如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统就会乱掉,所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
  1. 饿汉式:类初始化时创建单例,线程安全,适用于单例占内存小的场景。
java 复制代码
public class Singleton{
 
 private static Singleton instance = new Singleton();
 
 private Singleton(){}
 
 public static Singleton newInstance(){
  return instance;
 }
}
  1. 懒汉式:需要创建单例实例的时候在创建,需要考虑线程安全
java 复制代码
public class Singleton{

 private static Singleton instance = null;
 
 private Singleton(){}
 
 public static synchronized Singleton newInstance(){
  if(null == instance){
    instance = new Singleton();
  }
  return instance;
 }
}
  1. 双重校验锁定

解决问题:假如两个线程A执行了if(null == instance)语句,会认为单例对象没有创建,此时线程切到B也执行了同样语句,B也认为单例对象没有创建,然后两个线程依次执行同步代码块,分别创建了一个对象。

java 复制代码
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;  
    }  
}
  1. 静态内部类方法:可以同时保证延迟加载和线程安全
java 复制代码
public class Singleton {  
    private Singleton() {}  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
}

3. 原型模式

对一个原型对象进行复制、克隆产生类似的新对象:将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。

  • 核心: 他的核心是原型类Prototype,需要实现cloneable接口,和重写Object类中的clone方法。
  • 作用:使用原型模式创建对象比直接new一个对象在性能上好得多,因为Object类的clone方法是一个本地方法,他直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。

4. 适配器模式

为了增强接口的兼容性,将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配造成的类的兼容性问题。

4.1类的适配器模式

示例:有一个source类,拥有一个方法,待适配,目标接口是Targetable,通过Adapter类,将Source功能扩展到Targetable里。

4.2 对象的适配器模式

当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Wrapper类,持有原类的一个实例,在Wrapper类的方法中,调用实例方法即可。

4.3 接口的适配器模式

使用场景:当不希望实现一个接口中所有的方法时,可以创建一个抽象类Wrapper,实现所有方法,我们写别的类时候,继承抽象类即可。

5. 装饰者模式

给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

6. 代理模式(动态代理、静态代理)

持有被代理类的实例,进行操作前后控制。用的最多的模式。

7. 外观模式

集合所有操作到一个类。

8. 桥接模式

把事物和其具体实现分开,使得他们可以各自独立变化。

9. 组合模式

10.享元模式(共享池、数据库连接池)

享元模式的主要目的是实现对象的共享,即共享池。

11.策略模式

策略模式定义了一系列算法,并将每个算法封装起来,使得他们可以相互变化,且算法的变化不会影

响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口。

12. 模版方法模式(抽象方法作为骨架,具体逻辑让那个子类实现)

定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步骤。完成公共动作和特殊动作的分离。

13.观察者模式(发布-订阅模式)

当一个对象变化时,其他依赖该对象的对象都会收到通知,并且随着变化!

14. 迭代器模式(遍历集合)

迭代器模式就是顺序访问聚集中的对象

15. 责任链模式(多任务形成一条链,请求在链上传递)

有多个对象,每个对象持有下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一个对象决定处理该请求。但是发出者并不清楚到底最终哪个对象会处理该请求。所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。

16. 命令模式(实现请求和执行的解耦)

命令模式目的就是达到命令的发出者和执行者之间的解耦。

17. 备忘录模式(保存和恢复对象状态)

主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象。

18.状态模式(对象状态改变时改变其行为)

当对象的状态改变时,同时改变其行为。

19. 建造者模式

工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。

相关推荐
卡尔特斯1 小时前
Android Kotlin 项目代理配置【详细步骤(可选)】
android·java·kotlin
白鲸开源1 小时前
Ubuntu 22 下 DolphinScheduler 3.x 伪集群部署实录
java·ubuntu·开源
ytadpole2 小时前
Java 25 新特性 更简洁、更高效、更现代
java·后端
纪莫2 小时前
A公司一面:类加载的过程是怎么样的? 双亲委派的优点和缺点? 产生fullGC的情况有哪些? spring的动态代理有哪些?区别是什么? 如何排查CPU使用率过高?
java·java面试⑧股
JavaGuide3 小时前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
用户3721574261353 小时前
Java 轻松批量替换 Word 文档文字内容
java
白鲸开源3 小时前
教你数分钟内创建并运行一个 DolphinScheduler Workflow!
java
晨米酱3 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
Java中文社群3 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心4 小时前
从零开始学Flink:数据源
java·大数据·后端·flink