【设计模式】
- 创建型(单例/工厂/生成器)
- 行为型(观察者/迭代器/策略(线程池拒绝策略))
- 结构型(代理/适配器/装饰者)
- Spring中的单例模式(BeanFactory懒加载、ApplicationContext饿汉模式)
- 设计原则(单一责任、开放封闭、接口分离、里氏替换、依赖倒置)
【手写题】
- LRU
- 生产者消费者
- 奇数偶数交替打印
单例模式:
Ⅰ 懒汉式-线程不安全
Ⅱ 饿汉式-线程安全
Ⅲ 懒汉式-线程安全(synchronized)
Ⅳ 双重校验锁-线程安全
public class Singleton{ private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton getUniqueInstance() { if (uniqueInstance == null) { synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }
Ⅴ 静态内部类实现
public class Singleton { private Singleton() { } private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getUniqueInstance() { return SingletonHolder.INSTANCE; } }
Ⅵ 枚举实现
工厂模式:
- 简单工厂(Simple Factory)
- 在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。
- 简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化。
- 工厂方法(Factory Method)
- 定义了一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。
- 在简单工厂中,创建对象的是另一个类,而在工厂方法中,是由子类来创建对象。
- 抽象工厂(Abstract Factory)
- 提供一个接口,用于创建相关的对象家族 。
- 抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory,而工厂方法模式使用了继承。
观察者模式:
- 定义对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖都会收到通知并且自动更新状态。
- 主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。
- 主题(Subject)具有注册和移除观察者、并通知所有观察者的功能,主题是通过维护一张观察者列表来实现这些操作的。
- 观察者(Observer)的注册功能需要调用主题的 registerObserver() 方法。
主题: public interface Subject { void register(Observer o); void remove(Observer o); void notify(); } public class WeatherData implements Subject { private List<Observer> observers; private float temperature; public WeatherData() { observers = new ArrayList<>(); } public void set(float temperature) { this.temperature = temperature; notify(); } @Override public void register(Observer o) { observers.add(o); } @Override public void remove(Observer o) { observers.remove(o); } @Override public void notify() { for (Observer o : observers) { o.update(temperature); } } } 观察者: public interface Observer { void update(float temp); } public class Observer1 implements Observer { public Observer1 (Subject weatherData) { weatherData.register(this); } @Override public void update(float temp) { System.out.println(temp); } }
- 静态代理类:由程序员创建或者由第三方工具生成,再进行编译;在程序运行之前,代理类的.class文件已经存在了。静态代理类通常只代理一个类。静态代理事先知道要代理的是什么。
- jdk动态代理(反射)
- CGLIB动态代理
动态代理对比
- JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。
- JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。
- JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。