设计模式是面试的重头戏,面试必考必问。

前面已经写了设计的模式的快速的学习路线:

设计模式面试大全+视频教学,两天掌握设计模式!!!吊打面试官,offer拿到手疼
往期经典推荐:

1,50个开源项目大全

2,简历怎么写?干货来了!!!看完这篇大大提高你简历通过的概率

3,Mysql面试大全,看完可以吊打面试官!!!

4,我肝了一周,Java从基础到项目教程,Java全栈学习路线,帮你省去培训机构的2万块钱。

5,来自付费粉丝的问题,小孟保姆式解答

目录

  • Q1:设计模式有哪些原则?
  • Q2:设计模式的分类,你知道哪些设计模式?
  • Q3:说⼀说简单⼯⼚模式
  • Q4:说⼀说⼯⼚⽅法模式
  • Q5:抽象⼯⼚模式了解吗?
  • Q6:单例模式的特点是什么?
  • Q7:单例模式有哪些实现?
  • Q8:讲⼀讲代理模式
  • Q9:讲⼀讲装饰器模式
  • Q10:装饰器模式和动态代理的区别?
  • Q11:讲⼀讲适配器模式
  • Q12:适配器模式和和装饰器模式以及代理模式的区别?
  • Q13:讲⼀讲策略模式
  • Q14:讲⼀讲模板模式
  • Q15:讲⼀讲观察者模式

Q1:设计模式有哪些原则?

开闭原则:OOP 中最基础的原则,指⼀个软件实体(类、模块、⽅法等)应该对扩展开放,对修改关闭。强调⽤抽象构建框架,⽤实现扩展细节,提⾼代码的可复⽤性和可维护性。

单⼀职责原则:⼀个类、接⼝或⽅法只负责⼀个职责,降低代码复杂度以及变更引起的⻛险。
依赖倒置原则:程序应该依赖于抽象类或接⼝,⽽不是具体的实现类。

接⼝隔离原则:将不同功能定义在不同接⼝中实现接⼝隔离,避免了类依赖它不需要的接⼝,减少了接⼝之间依赖的冗余性和复杂性。

⾥⽒替换原则:开闭原则的补充,规定了任何⽗类可以出现的地⽅⼦类都⼀定可以出现,可以约束继承 泛滥,加强程序健壮性。

迪⽶特原则:也叫最少知道原则,每个模块对其他模块都要尽可能少地了解和依赖,降低代码耦合度。

合成/聚合原则:尽量使⽤组合(has-a)/聚合(contains-a)⽽不是继承(is-a)达到软件复⽤的⽬的,避免滥
⽤继承带来的⽅法污染和⽅法爆炸,⽅法污染指⽗类的⾏为通过继承传递给⼦类,但⼦类并不具备执
此⾏为的能⼒;⽅法爆炸指继承树不断扩⼤,底层类拥有的⽅法过于繁杂,导致很容易选择错误。

Q2:设计模式的分类,你知道哪些设计模式?

创建型: 在创建对象的同时隐藏创建逻辑,不使⽤ new 直接实例化对象,程序在判断需要创建哪些对象时更灵活。包括⼯⼚/抽象⼯⼚/单例/建造者/原型模式。

结构型: 通过类和接⼝间的继承和引⽤实现创建复杂结构的对象。包括适配器/桥接模式/过滤器/组合/ 装饰器/外观/享元/代理模式。

⾏为型: 通过类之间不同通信⽅式实现不同⾏为。包括责任链/命名/解释器/迭代器/中介者/备忘录/观察者/状态/策略/模板/访问者模式。

Q3:说⼀说简单⼯⼚模式

简单⼯⼚模式指由⼀个⼯⼚对象来创建实例,客户端不需要关注创建逻辑,只需提供传⼊⼯⼚的参数。

适⽤于⼯⼚类负责创建对象较少的情况,缺点是如果要增加新产品,就需要修改⼯⼚类的判断逻辑,违背开闭原则,且产品多的话会使⼯⼚类⽐较复杂。

Calendar 抽象类的⽇历对象。⽅法,调⽤⽅法根据不同的地区参数创建不同的Spring 中的 BeanFactory 使⽤简单⼯⼚模式,根据传⼊⼀个唯⼀的标识来获得 Bean 对象。

Q4:说⼀说⼯⼚⽅法模式

⼯⼚⽅法模式指定义⼀个创建对象的接⼝,让接⼝的实现类决定创建哪种对象,让类的实例化推迟到⼦类中进⾏。

客户端只需关⼼对应⼯⼚⽽⽆需关⼼创建细节,主要解决了产品扩展的问题,在简单⼯⼚模式中如果产品种类变多,⼯⼚的职责会越来越多,不便于维护。

Collection 接⼝这个抽象⼯⼚中定义了⼀个抽象的 ⼯⼚⽅法,返回⼀个 Iterator 类的抽象产
品。该⽅法通过 ArrayList 、HashMap 等具体⼯⼚实现,返回 Itr、KeyIterator 等具体产品。

Spring 的 FactoryBean 接⼝的⽅法也是⼯⼚⽅法。

Q5:抽象⼯⼚模式了解吗?

抽象⼯⼚模式指提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽆需指定它们的具体类。

客户端不依赖于产品类实例如何被创建和实现的细节,主要⽤于系统的产品有多于⼀个的产品族,⽽系 统只消费其中某⼀个产品族产品的情况。抽象⼯⼚模式的缺点是不⽅便扩展产品族,并且增加了系统的 抽象性和理解难度。

java.sql.Connection 接⼝就是⼀个抽象⼯⼚,其中包括很多抽象产品如 Statement、Blob、Savepoint等。

public class AbstractFactoryTest {public static void main(String[] args) {// 抽象工厂String result = (new CoffeeFactory()).createProduct("Latte");System.out.println(result); // output:拿铁}
}
// 抽象工厂
abstract class AbstractFactory{public abstract String createProduct(String product);
}
// 啤酒工厂
class BeerFactory extends AbstractFactory{@Overridepublic String createProduct(String product) {String result = null;switch (product) {case "Hans":result = "汉斯";break;case "Yanjing":result = "燕京";break;default:result = "其他啤酒";break;}return result;}
}
/\* \* 咖啡工厂 \*/
class CoffeeFactory extends AbstractFactory{@Overridepublic String createProduct(String product) {String result = null;switch (product) {case "Mocca":result = "摩卡";break;case "Latte":result = "拿铁";break;default:result = "其他咖啡";break;}return result;}
}

Q6:单例模式的特点是什么?

单例模式属于创建型模式,⼀个单例类在任何情况下都只存在⼀个实例,构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例,对外提供⼀个静态公有⽅法获取实例。

优点是内存中只有⼀个实例,减少了开销,尤其是频繁创建和销毁实例的情况下并且可以避免对资源的多重占⽤。缺点是没有抽象层,难以扩展,与单⼀职责原则冲突。

Spring 的 ApplicationContext 创建的 Bean 实例都是单例对象,还有 ServletContext、数据库连接池等也都是单例模式。

Q7:单例模式有哪些实现?

饿汉式:在类加载时就初始化创建单例对象,线程安全,但不管是否使⽤都创建对象可能会浪费内存。

懒汉式:在外部调⽤时才会加载,线程不安全,可以加锁保证线程安全但效率低。

双重检查锁:使⽤ volatile 以及多重检查来减⼩锁范围,提升效率。

静态内部类:同时解决饿汉式的内存浪费问题和懒汉式的线程安全问题。

枚举:《Effective Java》提倡的⽅式,不仅能避免线程安全问题,还能防⽌反序列化重新创建新的对象,绝对防⽌多次实例化,也能防⽌反射破解单例的问题。

Q8:讲⼀讲代理模式

代理模式属于结构型模式,为其他对象提供⼀种代理以控制对这个对象的访问。优点是可以增强⽬标对 象的功能,降低代码耦合度,扩展性好。缺点是在客户端和⽬标对象之间增加代理对象会导致请求处理速度变慢,增加系统复杂度。

Spring 利⽤动态代理实现 AOP,如果 Bean 实现了接⼝就使⽤ JDK 代理,否则使⽤ CGLib 代理。
静态代理:代理对象持有被代理对象的引⽤,调⽤代理对象⽅法时也会调⽤被代理对象的⽅法,但是会 在被代理对象⽅法的前后增加其他逻辑。需要⼿动完成,在程序运⾏前就已经存在代理类的字节码⽂件,代理类和被代理类的关系在运⾏前就已经确定了。 缺点是⼀个代理类只能为⼀个⽬标服务,如果要服务多种类型会增加⼯作量。

动态代理:动态代理在程序运⾏时通过反射创建具体的代理类,代理类和被代理类的关系在运⾏前是不确定的。动态代理的适⽤性更强,主要分为 JDK 动态代理和 CGLib 动态代理。

JDK 动态代理:通过类的⽅法获取⼀个动态代理对象,需要传⼊三个参数,被代理对象的类加载器、被代理对象实现的接⼝,以及⼀个器来指明具体的逻辑,相⽐静态代理的优势是接⼝中声明的所有⽅法都被转移到调⽤处理的⽅法集中处理。

CGLib 动态代理:JDK 动态代理要求实现被代理对象的接⼝,⽽ CGLib 要求继承被代理对象,如果⼀个类是 final 类则不能使⽤ CGLib 代理。两种代理都在运⾏期⽣成字节码,JDK 动态代理直接写字节码,⽽ CGLib 动态代理使⽤ ASM 框架写字节码,ASM 的⽬的是⽣成、转换和分析以字节数组表示的已编译 Java 类。 JDK 动态代理调⽤代理⽅法通过反射机制实现,⽽ GCLib 动态代理通过 FastClass 机制直接调⽤⽅法,它为代理类和被代理类各⽣成⼀个类,该类为代理类和被代理类的⽅法分配⼀个 int 参数,调⽤⽅法时可以直接定位,因此调⽤效率更⾼。

Q9:讲⼀讲装饰器模式

装饰器模式属于结构型模式,在不改变原有对象的基础上将功能附加到对象,相⽐继承可以更加灵活地 扩展原有对象的功能。

装饰器模式适合的场景:在不想增加很多⼦类的前提下扩展⼀个类的功能。
java.io 包中,InputStream 字节输⼊流通过装饰器 BufferedInputStream 增强为缓冲字节输⼊流。

Q10:装饰器模式和动态代理的区别?

装饰器模式的关注点在于给对象动态添加⽅法,⽽动态代理更注重对象的访问控制。动态代理通常会在 代理类中创建被代理对象的实例,⽽装饰器模式会将装饰者作为构造⽅法的参数。

Q11:讲⼀讲适配器模式

适配器模式属于结构型模式,它作为两个不兼容接⼝之间的桥梁,结合了两个独⽴接⼝的功能,将⼀个 类的接⼝转换成另外⼀个接⼝使得原本由于接⼝不兼容⽽不能⼀起⼯作的类可以⼀起⼯作。
缺点是过多使⽤适配器会让系统⾮常混乱,不易整体把握。

java.io 包中,InputStream 字节输⼊流通过适配器 InputStreamReader 转换为 Reader 字符输⼊流。
Spring MVC 中的 HandlerAdapter,由于 handler 有很多种形式,包括 Controller、HttpRequestHandler、Servlet 等,但调⽤⽅式⼜是确定的,因此需要适配器来进⾏处理,根据适配规则调⽤ handle ⽅法。

Arrays.asList ⽅法,将数组转换为对应的集合(注意不能使⽤修改集合的⽅法,因为返回的 ArrayList
是 Arrays 的⼀个内部类)。
适配器实现的代码如下:

/\* \* 传统的充电线 MicroUSB \*/
interface MicroUSB {void charger();
}
/\* \* TypeC 充电口 \*/
interface ITypeC {void charger();
}
class TypeC implements ITypeC {@Overridepublic void charger() {System.out.println("TypeC 充电");}
}
/\* \* 适配器 \*/
class AdapterMicroUSB implements MicroUSB {private TypeC typeC;public AdapterMicroUSB(TypeC typeC) {this.typeC = typeC;}@Overridepublic void charger() {typeC.charger();}
}
/\* \* 测试调用 \*/
public class AdapterTest {public static void main(String[] args) {TypeC typeC = new TypeC();MicroUSB microUSB = new AdapterMicroUSB(typeC);microUSB.charger();}
}

Q12:适配器模式和和装饰器模式以及代理模式的区别?

适配器模式没有层级关系,适配器和被适配者没有必然连续,满⾜ has-a 的关系,解决不兼容的问题, 是⼀种后置考虑。

装饰器模式具有层级关系,装饰器与被装饰者实现同⼀个接⼝,满⾜ is-a 的关系,注重覆盖和扩展,是⼀种前置考虑。

适配器模式主要改变所考虑对象的接⼝,⽽代理模式不能改变所代理类的接⼝。

Q13:讲⼀讲策略模式

策略模式属于⾏为型模式,定义了⼀系列算法并封装起来,之间可以互相替换。策略模式主要解决在有多种算法相似的情况下,使⽤ if/else 所带来的难以维护。

优点是算法可以⾃由切换,可以避免使⽤多重条件判断并且扩展性良好,缺点是策略类会增多并且所有 策略类都需要对外暴露。

在集合框架中,经常需要通过构造⽅法传⼊⼀个⽐较器 Comparator 进⾏⽐较排序。Comparator 就是
⼀个抽象策略,⼀个类通过实现该接⼝并重写 compare ⽅法成为具体策略类。

创建线程池时,需要传⼊拒绝策略,当创建新线程使当前运⾏的线程数超过 maximumPoolSize 时会使⽤相应的拒绝策略处理。

策略模式实现的代码如下所示:

/\* \* 声明旅行 \*/
interface ITrip {void going();
}
class Bike implements ITrip {@Overridepublic void going() {System.out.println("骑自行车");}
}
class Drive implements ITrip {@Overridepublic void going() {System.out.println("开车");}
}
/\* \* 定义出行类 \*/
class Trip {private ITrip trip;public Trip(ITrip trip) {this.trip = trip;}public void doTrip() {this.trip.going();}
}
/\* \* 执行方法 \*/
public class StrategyTest {public static void main(String[] args) {Trip trip = new Trip(new Bike());trip.doTrip();}
}

程序执行的结果: 骑自行车

Q14:讲⼀讲模板模式

模板模式属于⾏为型模式,使⼦类可以在不改变算法结构的情况下重新定义算法的某些步骤,适⽤于抽 取⼦类重复代码到公共⽗类。

优点是可以封装固定不变的部分,扩展可变的部分。缺点是每⼀个不同实现都需要⼀个⼦类维护,会增 加类的数量。

为防⽌恶意操作,⼀般模板⽅法都以 final 修饰。

HttpServlet 定义了⼀套处理 HTTP 请求的模板,service ⽅法为模板⽅法,定义了处理HTTP请求的基本流程,doXXX 等⽅法为基本⽅法,根据请求⽅法的类型做相应的处理,⼦类可重写这些⽅法。

Q15:讲⼀讲观察者模式

观察者模式属于⾏为型模式,也叫发布订阅模式,定义对象间的⼀种⼀对多的依赖关系,当⼀个对象的 状态发⽣改变时,所有依赖于它的对象都得到通知并被⾃动更新。主要解决⼀个对象状态改变给其他对 象通知的问题,缺点是如果被观察者对象有很多的直接和间接观察者的话通知很耗时, 如果存在循环依赖的话可能导致系统崩溃,另外观察者⽆法知道⽬标对象具体是怎么发⽣变化的。

ServletContextListener 能够监听 ServletContext 对象的⽣命周期,实际上就是监听 Web 应⽤。当Servlet 容器启动 Web 应⽤时调⽤contextInitialized方法,终⽌时调⽤ contextDestroyed方法。

最后录制了完整的设计模式的教程:





教程和文档全部开源了,应该说是非常详细了。

设计模式的视频+文档教程,需要的拿去学习吧

关注公众号:springmeng 回复:设计模式

希望大家都能尽早掌握设计模式,这样在面试中就不会怕设计模式的面试题了。

我是小孟,记得点个赞支持下,谢了!

三天肝完设计模式的面试题,面试再不怕设计模式的问题了相关推荐

  1. 面试常败给微服务?我总结了一套核心资料三天肝完……

    前言 基于 Spring Cloud 的微服务设计和开发,已经越来越多地得到了更多企业的推广和应用,而 Spring Cloud 社区也在不断的迅速发展壮大之中,近几年时间,Spring Cloud ...

  2. 【金三银四】Java中间件面试题(2021最新版)

    目录 前言 Zookeeper 1. ZooKeeper 是什么? 2. ZooKeeper 提供了什么? 3.Zookeeper 文件系统 4. ZAB 协议? 5. 四种类型的数据节点 Znode ...

  3. 【金三银四】Java集合面试题(2021最新版)

    目录 前言 一.集合容器概述 1. 什么是集合 2. 集合的特点 3. 集合和数组的区别 4. 使用集合框架的好处 5. 常用的集合类有哪些? 6. List,Set,Map三者的区别? 7. 集合框 ...

  4. 【2022最新Java面试宝典】—— 设计模式面试题(14道含答案)

    目录 1.什么是设计模式 2.为什么要学习设计模式 3.设计模式分类 4.设计模式的六大原则 5.单例模式 1.什么是单例 2.那些地方用到了单例模式 3.单例优缺点 4.单例模式使用注意事项: 5. ...

  5. 【金三银四】Spring Boot面试题(2021最新版)

    目录 前言 1. 什么是SpringBoot? 2. 为什么要用SpringBoot 3. SpringBoot与SpringCloud 区别 4. Spring Boot 有哪些优点? 5. Spr ...

  6. 常见面试题:为什么HashMap不是线程安全的呢?(JDK1.7和JDK1.8角度)(看完你就能和面试官笑谈人生了)

    title: 常见面试题:为什么HashMap不是线程安全的呢?(JDK1.7和JDK1.8角度)(看完你就能和面试官笑谈人生了) tags: 面试常见题 常见面试题:为什么HashMap不是线程安全 ...

  7. 一夜之间就能肝完的学生信息管理系统

    只要一个晚上?信息管理系统?对滴,你没有看错.就是一个晚上.如果你很闲的话,如果你还在无所事事的话,如果你还不懂基于MFC编程的话,请花一个晚上的时间(也可以花更多的时间),认真阅读这篇博客,并肝它. ...

  8. 2022广东省安全员A证第三批(主要负责人)培训试题模拟考试平台操作

    题库来源:安全生产模拟考试一点通公众号小程序 2022广东省安全员A证第三批(主要负责人)考试题库是广东省安全员A证第三批(主要负责人)考试题目考前必练习题目!2022广东省安全员A证第三批(主要负责 ...

  9. 为了验证自己Java学的如何,爆肝了10万字面试题,开源给大家

    验证自己Java学得如何,最好的方式就是看看这些面试题,来吧,开始验证你是否精通了没有(爆肝了七天七夜啊) 由于字数太多,所以只分类给出了面试题目,每道题的答案看文末 一.Java基础 1.解释下什么 ...

最新文章

  1. 从配置说tomcat和nginx调优
  2. 人月神话阅读笔记03
  3. Spring-bean之间的关系
  4. 【Java】字符串转Unicode字符串
  5. ElasticSearch5.x实践_day05_03_Mapping_Meta-Fields
  6. python语言程序设计实验答案实验八函数_C++程序设计 实验8 实验报告 标准答案...
  7. 洛谷P3338:力(FFT)
  8. 详解 Flink 指标、监控与告警
  9. 局域网文件自动同步更新服务器版,自同步(局域网文件实时同步工具) V2.1.0 官方安装版...
  10. linux pe系统下载,WINPE LINUX DOS 完美者U盘维护系统V8.1 正式版
  11. 移动端优秀框架--Amaze UI(h5)
  12. 微信公众号 第三方登录 获取微信用户信息(java版)
  13. mmdetection源码笔记(一):train.py解读
  14. 剑指offer | 面试题54:二叉搜索树的第k大节点
  15. Linux7 core是什么系统,Centos7+.NET CORE初探
  16. 一文详解 Interpolator动画插值器
  17. 魅族怎么更改html,魅族默认浏览器设置
  18. java hssffont_Java HSSFFont.setColor方法代碼示例
  19. Hadoop+hive+flask+echarts大数据可视化之系统数据收集
  20. 云上拍客梨视频 基于阿里云的技术实践分享

热门文章

  1. matlab编写连续时间系统的时域分析
  2. “与真实情况不一致”,数禾科技“打脸”母公司分众传媒
  3. ubuntu下实现和windows共享文档
  4. TD-SCDMA系统中随机接入过程分析
  5. 抖音作品和直播间如何获取更多流量
  6. ProxmoxVE 干掉 VMware
  7. 适合 JS 新手学习的开源项目——在 GitHub 学编程
  8. XWPFParagraph设置样式
  9. 实用的60个CSS代码片段
  10. 2023最新网盘不限速下载方法