设计模式 高频面试题整合篇

        前言:单例模式的就不拿出来说了,有兴趣的小伙伴可以直接跳到 这里:面试篇:单例模式速食篇


谈谈你对深克隆(Deep clone)和浅克隆的理解

本质区别:

  1. 即数据克隆之后,两者之间是否存在关联
  2. 改变一个值是否会影响到另一个数值的变化,如果影响了那么就是浅克隆,不影响则为深克隆。

浅克隆的原则:

        如果是引用类型成员变量,克隆的时候是将引用地址进行克隆。如果是值类型的成员变量,那么克隆的时候是将值进行克隆。

浅克隆常用的API

1. 工具类BeanUtils和PropertyUtils进行对象复制。
    Spring的BeanUtils类中的copyProperty和copyProperties
    commons的BeanUtils类中的copyProperties方法
2. 实现Clonenable接口
3. Array.copyOf(),但是在ArrayList重写了copyOf方法,实现了深克隆的效果,在方法内重新new了一个ArrayList对象。

深克隆的原则

        不管是引用类型还是值类型都是复制值,重新分配内存空间。 

深克隆常用的API

  1. 每个对象都有实现Clonenable接口重写Object类中的clone()方法。object类默认是克隆值,重写后就可以克隆引用了。
  2. 序列化,必须实现Serializable接口序列化每次都会重新分配内存空间,基于字节来操作的完全创建一个新对象。
  3. Apache Commons工具包SerializationUtils.clone(T Object);
  4. 通过JSON工具类实现深克隆。
  5. 通过构造方法实现深克隆(手动new对象)。

链式编程是建造者模式的标配么?

         不是,官方的定义里只是说将复杂对象的构建过程跟表示进行分离,并没有说一定需要链式编程。链式编程只是对建造者模式的一种优化,因为链式编程方便我们在添加值的时候可以保证对象的引用,所有为了重复避免保存对象的引用,索性直接在添加值的时候,把被构造对象的引用返回调用者,省去了构建对象的一个过程

        链式编程的最核心思想就是可以实现零件无序装配


你如何理解静态代理和动态代理

         回答之前,先说一下什么是代理。再说下静态代理与动态代理的区别,再说下动态代理的基本实现原理。

        代理是指在客户端和目标对象之间起到一个中介作用

        静态代理是一个代理只能服务于一种类型的对象,当有n个业务时,就需要n个静态对象,不利于业务的扩展

        动态代理是一个代理类可以服务于所有的业务对象,有两种实现方式,JDK动态代理以及cglib的动态代理

JDK动态代理的基本实现原理

  1. 拿到被代理类的引用,并且获取它的所有接口。
  2. JDK proxy类重新生成一个新的类,实现被代理类的所有接口的方法。
  3. 动态生成JAVA代码,把需要增强的逻辑加入到新生成的代码中。
  4. 编译生成新的Java代码的class文件
  5. JVM重新加载并重新运行新的class,得到一个全新的类

 CGlib和JDK动态代理对比

        一般说的动态、静态的区别后,都会问jdk与cglib的区别的。就直接说答案了

  1. JDK动态代理是实现了被代理对象的接口CGlib是继承了被代理对象
  2. 代理类与被代理类的关系,CGlib是父与子的关系,JDK是兄弟关系。
  3. JDK 和CGlib都是在运行期生成字节码
  4. JDK调用代理方法是通过反射机制调用,CGlib是通过FastClass机制,FastClass会提前编译好保存在某个路径下,JVM会直接加载class文件,所以不需要反射,性能比JDK更好一点
  5. CGlib无法代理final修饰的方法

什么场景下应该用策略模式,什么场景下不应该用?

         适合使用的场景:需要经常自由切换执行逻辑和规则场景

        不适合使用的场景:如果两种逻辑之间关联性本来就比较大,而且变化也比较快。例如折扣活动,经常性打折的场景就不适合,这时候咱们可以通过配置来实现。

说下责任链模式的实现原理

        生活中审批流程就是责任链模式,一环到一环。

实现原理

        单向链表的上下文类。然后声明两个变量,一个head(头),一个尾(tail)。

        Handler1 head -> next-> Handler2 -> next ->Handler3 tail

public class Context{
    Handler head;
    Handler tail;
}

public abstract class Handler{
    protect Handler next;
}

        双向链表上下文 Handler1 head -> next-> Handler2 -> next ->Handler3 tail -> prev -> Handler2

public class Context{
    Handler haed;
    Handler tail;
}

public abstract class Handler{
    protect Handler prev; //上一个
    protect Handler next; //下一个
}

可以直接用下面的总结来回答

责任链分为两种实现方式,一个是 单向链表 ,一个是双向链表

        单向链表需要设计责任链的上下文类与一个处理器handler类, handler类中需要保存责任链元素中头(head)和尾(tail)的引用每个head需要保存下一个head的引用,这样就可以形成一个责任链。

        双向链表在单向链表的基础上,在handler类中新增上一个节点(prev)的元素,引用的时候可以指向上一个接口的引用,形成一个闭环的链表。

责任链模式的优缺点是什么 

优点:

  1. 将请求与处理解耦。

  2. 请求处理者将不是自己职责范围内的请求,转发给下一个节点。

  3. 请求发送者不需要关心链路结构,只需等待请求处理结果即可。

  4. 链路结构灵活,易于扩展新的请求处理节点。

缺点:

  1. 责任链太长或者处理时间过长,会影响整体性能。

  2. 如果节点对象存在循环引用,则会造成死循环,导致程序崩溃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值