《Java 后端面试经》设计模式篇

《Java 后端面试经》专栏文章索引:
《Java 后端面试经》Java 基础篇
《Java 后端面试经》Java EE 篇
《Java 后端面试经》数据库篇
《Java 后端面试经》多线程与并发编程篇
《Java 后端面试经》JVM 篇
《Java 后端面试经》操作系统篇
《Java 后端面试经》Linux 篇
《Java 后端面试经》设计模式篇
《Java 后端面试经》计算机网络篇
《Java 后端面试经》微服务篇

🚀你了解的设计模式有哪些?

总的设计模式有 23 种,可以分为三大类:

  1. 创建型模式(共五种)工厂方法模式抽象工厂模式单例模式、建造者模式、原型模式
  2. 结构型模式(共七种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  3. 行为型模式(共十一种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

🚀在 Spring 框架中都用到了哪些设计模式,并举例说明?

  1. 单例模式:Spring 中的 Bean 默认情况下都是单例的。
  2. 工厂模式:工厂模式主要是通过 BeanFactory 和 ApplicationContext 来生产 Bean 对象。
  3. 代理模式:最常见的 AOP 的实现方式就是通过代理来实现,Spring 主要是使用 JDK 动态代理和 CGLIB 代理。
  4. 模板方法模式:主要是一些对数据库操作的类用到,比如 JdbcTemplate、JpaTemplate,因为查询数据库的建立连接、执行查询、关闭连接几个过程,非常适用于模板方法。
  5. 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如 Spring中listener 的实现 ApplicationListener.
  6. 适配器模式:SpringMVC 中的适配器 HandlerAdatper,它会根据 Handler 规则执行不同的 Handler. 即 DispatcherServlet 根据 HandlerMapping 返回的 handler,向 HandlerAdatper 发起请求处理 Handler. HandlerAdapter 根据规则找到对应的 Handler 并让其执行,执行完毕后Handler 会向 HandlerAdapter 返回一个 ModelAndView,最后由 HandlerAdapter 向DispatchServelet 返回一个 ModelAndView.
  7. 策略模式:Spring 框架的资源访问 Resource 接口。该接口提供了更强的资源访问能力,Spring 框架本身大量使用了 Resource 接口来访问底层资源。Resource 接口是具体资源访问策略的抽象,也是所有资源访问类所实现的接口。

🚀设计模式的原则有哪些?

设计模式共有六大原则,分别是:单一职责原则、开闭原则、里氏代换原则、依赖倒转原则、接口隔离原则、迪米特法则:

  1. 单一职责:一个类只负责一个功能领域中相应的职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。
  2. 开闭原则:软件实体应该对扩展开放,对修改关闭。其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。
  3. 里氏代换原则:通俗点讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类。但是,反过来就不行了,有子类出现的地方,父类未必就能适应。
  4. 依赖倒转原则:这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
  5. 接口隔离原则:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
  6. 迪米特法则:为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

🚀谈谈单例模式?

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。例如,在 Hiberate 框架中的 SessionFactory,它充当数据存储源的代理,并负责创建 Session 对象,SessionFactory 并不是轻量级的,一般情况下一个项目通常只需要一个 SessionFactory,这时使用的就是单列模式。

饿汉式单例模式

public class Singleton {    
	private static Singleton instance = new Singleton();     
	// 私有构造方法,保证外界无法直接实例化。     
	private Singleton() {}     
	// 通过公有的静态方法获取对象实例     
	public static Singleton getInstace() {   
	     return instance;     
    } 
}

懒汉式单例模式

public class Singleton { 
    private static Singleton instance = null;     
    // 私有构造方法,保证外界无法直接实例化。     
    private Singleton() {}     
    // 通过公有的静态方法获取对象实例     
    public static Singleton getInstace() {
         if (instance == null) {             
         	instance = new Singleton();      
         }        
         return instance;     
     } 
}

在懒汉式单例模式基础上实现线程同步

public class Singleton {
     private static Singleton instance = null;  
     // 私有构造方法,保证外界无法直接实例化。     
     private Singleton() {}     
     // 通过公有的静态方法获取对象实例     
     public static synchronized  Singleton getInstace() {         
	     if (instance == null) {             
	     	instance = new Singleton();         
	     }         
     	 return instance;     
     } 
}

上述代码对静态方法 getInstance() 进行同步,以确保多线程环境下只创建一个实例。如果getInstance() 方法未被同步,并且线程 A 和线程 B 同时调用此方法,则执行 if (instance == null) 语句时都为真,那么线程 A 和线程 B 都会创建一个对象,在内存中就会出现两个对象,这样就违反了单例模式。而使用 synchronized 关键字进行同步后,则不会出现此种情况。

优缺点

  • 解决了线程安全问题
  • 效率低,每个线程在想获得类的实例的时候,执行 getInstance() 方法都要进行同步,而其实这个方法只执行一次实例化代码代码就够了,对方法进行同步的效率太低。

双重检查的懒汉单例模式

public class Singleton {
     private static volatile Singleton instance;  
     // 私有构造方法,保证外界无法直接实例化。     
     private Singleton() {}     
     // 通过公有的静态方法获取对象实例     
     public static synchronized Singleton getInstace() {         
	     if (instance == null) {  
	     	synchronized(Singleton.class) {
	     		if (instance == null) {
	     			instance = new Singleton(); 
	     		}
	     	}
	     }         
     	 return instance;     
     } 
}

优缺点

  • 进行了两次 if(instance == null) 检查,保证了线程安全。
  • 实例化代码只用执行一次,后面再访问时,判断 if (instance == null) ,直接返回实例化对象,避免了反复进行方法同步。
  • 线程安全,延迟加载,效率较高
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReadThroughLife

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值