- 01.设计原则类问题
- 02.面向对象设计
- 03.设计模式概括
- 04.代码重构问题
- 06.单例模式问题
- 07.工厂模式问题
- 08.建造者模式问题
- 09.观察者模式问题
- 10.策略者模式问题
- 单一职责原则:关于内聚的原则。高内聚、低耦合的指导方针,类或者方法单纯,只做一件事情。
- 接口隔离原则:关于内聚的原则。要求设计小而单纯的接口(将过大的接口拆分),或者说只暴露必要的接口。
- 开闭原则:关于扩展的原则。对扩展开放对修改关闭,做合理的抽象就能达到增加新功能的时候不修改老代码(能用父类的地方都用父类,在运行时才确定用什么样的子类来替换父类),开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段。
- 里氏替换原则:为了避免继承的副作用,若继承是为了复用,则子类不该改变父类行为,这样子类就可以无副作用地替换父类实例,若继承是为了多态,则因为将父类的实现抽象化
- 依赖倒置原则:即是面向接口编程,面向抽象编程,高层模块不该依赖底层模块,而是依赖抽象
- 01.说说你对设计模式的理解,开发过程中主要用到了哪些设计模式?【这个问题回答一定要是自己熟悉的,面试官一般是追问】
- 01.设计模式主要分为那几大类?创建型主要是解决什么问题?行为型主要是解决什么问题?结构型解决什么问题?
- 目的:在单进程内保证类唯一实例。单例模式手写案例?单例模式解决什么问题?单例模式优缺点分析?
- 静态内部类:虚拟机保证一个类的初始化操作是线程安全的,而且只有使用到的时候才会去初始化,缺点是没办法传递参数。
- 双重校验:第一校验处于性能考虑,若对象存在直接返回,不需要加锁。第二次校验是为了防止重复构建对象。对象引用必须声明为 volatile,通过保证可见性和防止重排序,保证单例线程安全。因为INSTANCE = new instance()不是原子操作,由三个步骤实现1.分配内存2.初始化对象3.将INSTANCE指向新内存,当重排序为1,3,2时,可能让另一个线程在第一个判空处返回未经实例化的单例。
- 手写单例(DCL)模式代码?为什么要这样设计?如何防止反射、序列化攻击单例?
- 手写常见的单例模式代码?synchronized修饰方法和修饰类有什么区别?写完后,请简述它们使用场景和利弊……
- 单利模式下引发的血案,DCL双端锁下的CAS与ABA问题,尝试解释一下具体的原理?
- 目的:解耦。将对象的使用和对象的构建分割开,使得和对象使用相关的代码不依赖于构建对象的细节。
- 增加了一层“抽象”将“变化”封装起来,然后对“抽象”编程,并利用”多态“应对“变化”,对工厂模式来说,“变化”就是创建对象。
- 1.简单工厂模式。将创建具体对象的代码移到工厂类中的静态方法。实现了隐藏细节和封装变化,对变化没有弹性,当需要新增对象时需要修改工厂类。
- 2.工厂方法模式。在父类定义一个创建对象的抽象方法,让子类决定实例化哪一个具体对象。特点:1. 只适用于构建一个对象。2. 使用继承实现多态。
- 3.抽象工厂模式。定义一个创建对象的接口,把多个对象的创建细节集中在一起。特点:使用组合实现多态。
- 目的:简化对象的构建。什么情况下直接用方法构造?复杂构造用set替换可以吗?什么情况下用builder构造?
- 它是一种构造复杂对象的方式,复杂对象有很多可选参数,如果将所有可选参数都作为构造函数的参数,则构造函数太长,建造者模式实现了分批设置可选参数。Builder模式增加了构造过程代码的可读性。
- 建造者模式和工厂模式都可以创建对象,那它们两个的区别在哪里呢?
- 目的:以解耦的方式进行通信。将被观察者和具体的观察行为解耦。是一种一对多的通知方式,被观察者持有观察者的引用。
- ListView的BaseAdapter中有DataSetObservable,在设置适配器的时候会创建观察者并注册,调用notifyDataSetChange时会通知观察者,观察者会requestLayout。
- 阐述一下使用策略者模式的应用场景?如何针对冗长的 if-else 或 switch 分支进行架构层面优化,增强框架拓展?
- 场景分析题,针对贩卖各类书籍的电子商务网站,根据用户vip等级进行折扣,你如何实现?实现策略者模式的结构是怎么样的?
- 目的:代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,而非加强功能。
- 实现:接口 + 委托类 + 代理类 。 最终是通过代理类对象去调用接口中方法执行逻辑。
- 举例子:写一个静态代理的伪代码。通过案例理解委托类和代理类解耦合!
- 问题1:静态代理是如何实现的?应用场景有哪些?静态代理有哪些优缺点?
- 问题2:如果事先不知道委托类,那么该如何做静态代理呢?静态代理有哪些局限性?
- 目的:代理类是在运行时生成的。给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问。
- 类比:代理对象是中介,原对象是房东的房子,客户就是我们需要找房的人。
- 使用场景:某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以再两者之间起到中介作用。运行阶段才指定代理哪个对象。
- 实现:动态代理参与者为:主题接口 + 目标对象 + 代理对象 + 客户端
- 举例子:写一个动态代理的伪代码案例?Subject接口 + RealSubject委托对象 + ProxyHandler代理处理器 + 测试案例
- 问题1:说一下动态代理跟静态代理的区别?什么场景下才需要动态代理?有何优缺点?
- 问题2:动态代理中InvocationHandler的作用是什么?它的核心原理是如何实现的?
- 目的:这个模式就是用来做适配的,它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作。
- 类比:类似USB转接头,既可以链接Android手机,也可以链接IOS手机。
- 实现:类适配器,通过继承来实现(定义接口);对象适配器,通过组合来实现。
- 应用场景:封装有缺陷的接口设计,统一多个类的接口设计。适配器模式可以看作一种“补偿模式”,用来补救设计上的缺陷。
- 举例子:封装有缺陷的接口,设计统一多个类的接口,设计替换依赖的外部系统,对这三种场景举例子学习。
- 问题1:适配器模式主要是解决什么问题?如何判断用类适配器还是对象适配器?判断的依据是什么?
- 问题2:在实际开发中,什么情况下才会出现接口不兼容呢,试着举一些场景?