Java设计模式面试题及详细答案(面试完整版)_第1页
Java设计模式面试题及详细答案(面试完整版)_第2页
Java设计模式面试题及详细答案(面试完整版)_第3页
Java设计模式面试题及详细答案(面试完整版)_第4页
Java设计模式面试题及详细答案(面试完整版)_第5页
已阅读5页,还剩4页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java设计模式面试题及详细答案(面试完整版)一、基础概念类面试题1.什么是设计模式?为什么要使用设计模式?参考答案:设计模式是软件开发中反复出现、经过无数项目验证的优秀代码设计经验总结,是一套可复用、可优化、标准化的代码设计思路,专门用于解决软件设计中的通用问题。使用设计模式的核心目的:1.复用代码:避免重复造轮子,通用场景直接使用成熟设计方案,提升开发效率。2.解耦优化:降低代码耦合度,让模块、类之间依赖更松散,方便修改和扩展。3.规范统一:统一团队代码设计思路,减少个性化杂乱写法,提升代码可读性、可维护性。4.规避问题:规避新手开发中常见的设计缺陷、逻辑漏洞、扩展性差等问题。5.适配开闭原则:多数设计模式遵循开闭原则,对扩展开放、对修改关闭,适配业务迭代更新。2.设计模式的六大设计原则是什么?核心含义?参考答案:六大原则是所有设计模式的底层规范,所有经典模式基本都围绕这六个原则设计:1.开闭原则(核心)对扩展开放,对修改关闭。业务迭代、功能新增时,尽量不修改原有成熟代码,通过新增类、新增方法实现功能,避免改动旧代码引发线上bug。2.单一职责原则一个类、一个方法只负责一个核心职责。如果一个类承担过多功能,一处修改会影响全局,代码容错性、可维护性极差。3.里氏替换原则子类可以完全替换父类出现在程序中,且替换后程序逻辑、功能不会出现异常。子类不能重写父类已实现的核心方法,保证继承的规范性。4.依赖倒置原则高层模块不依赖低层模块,二者都依赖抽象;抽象不依赖细节,细节依赖抽象。开发中面向接口、抽象类编程,而非面向具体实现类,大幅降低耦合。5.接口隔离原则定义精细化、单一的接口,不要设计臃肿、万能接口。类不需要的接口方法坚决不实现,避免接口冗余、代码浪费。6.迪米特法则(最少知道原则)一个类尽量少依赖其他类,只和直接朋友通信,不了解陌生类的内部细节。减少类之间的关联,降低代码耦合。3.设计模式分为哪三类?各自特点?参考答案:经典23种设计模式分为创建型、结构型、行为型三大类:1.创建型模式(5种)核心:控制对象的创建方式,隔离对象创建与使用,让创建逻辑更灵活、统一。包含:单例、工厂方法、抽象工厂、建造者、原型模式。2.结构型模式(7种)核心:组合类或对象,通过组装、适配、代理等方式,优化类与对象的结构,实现功能扩展。包含:适配器、装饰器、代理、桥接、组合、外观、享元模式。3.行为型模式(11种)核心:规范对象之间的交互、通信、职责分配,优化程序运行时的行为逻辑。包含:策略、模板方法、观察者、迭代器、责任链、命令、备忘录、状态、访问者、中介者、解释器模式。二、创建型模式高频面试题1.单例模式是什么?有哪些实现方式?优缺点?参考答案:单例模式是保证一个类在整个程序生命周期中只有一个实例对象,并提供一个全局访问入口的创建型模式。核心场景:工具类、配置类、连接池、缓存对象等,避免重复创建对象消耗资源。常见实现方式及优缺点:1.饿汉式(静态常量)类加载时直接创建实例,线程绝对安全,实现简单;缺点是类加载就初始化,浪费内存,不支持懒加载。2.懒汉式(线程不安全)使用时才创建实例,节省内存;多线程环境下会产生多个实例,线程不安全,生产环境不用。3.双重检查锁DCL(推荐)兼顾懒加载、线程安全、高性能,通过两次判空+volatile禁止指令重排解决并发问题,是项目中最常用的单例实现。4.静态内部类(最优)利用静态内部类的加载特性,天然线程安全、懒加载、无锁开销,性能最优,推荐工具类使用。5.枚举单例写法极简,天然线程安全,彻底杜绝反射、序列化破坏单例,是最安全的单例模式。2.手写DCL双重检查锁单例,为什么加volatile?参考答案:DCL单例代码:java

publicclassSingleton{

//volatile禁止指令重排

privatestaticvolatileSingletoninstance;

//私有构造,禁止外部new

privateSingleton(){}

publicstaticSingletongetInstance(){

//第一次判空:避免每次加锁,提升性能

if(instance==null){

synchronized(Singleton.class){

//第二次判空:防止多线程穿透重复创建

if(instance==null){

instance=newSingleton();

}

}

}

returninstance;

}

}volatile核心作用:new对象并非原子操作,分为三步:1.分配内存空间2.初始化对象3.赋值给引用。JVM会进行指令重排,可能执行顺序变为1-3-2,导致其他线程获取到未初始化完成的半初始化对象,引发空指针、数据异常。volatile的作用就是禁止指令重排序,保证对象初始化完成后再赋值,彻底解决并发安全问题。3.工厂方法、抽象工厂、简单工厂的区别及适用场景?参考答案:1.简单工厂(静态工厂)不属于23种经典模式,是基础工厂写法。由一个工厂类根据参数创建不同产品,优点是简单;缺点是新增产品需要修改工厂代码,违反开闭原则,适合产品少、基本不迭代的场景。2.工厂方法模式定义工厂接口,每个产品对应一个具体工厂,一个工厂只生产一种产品。遵循开闭原则,新增产品只需新增对应工厂类;缺点是类会爆炸,适合单一产品体系、频繁新增产品的场景。3.抽象工厂模式工厂接口可以生产一组相关产品(产品族),比如手机工厂可以生产手机、耳机、充电器。适合存在多个产品体系、产品分组的场景,弊端是新增产品族时改动大。核心区别总结:简单工厂:一个工厂造所有产品;工厂方法:一个工厂造一个产品;抽象工厂:一个工厂造一组产品。4.建造者模式和工厂模式的区别?适用什么场景?参考答案:核心区别:1.工厂模式重点是快速创建完整对象,关注对象创建结果;2.建造者模式重点是分步构建复杂对象,可以灵活搭配不同属性、不同构建步骤,关注创建过程。建造者适用场景:用于创建参数多、参数可选、对象结构复杂的实体类,避免大量重载构造方法、参数传参混乱的问题。比如开发中的实体DTO、复杂配置类、网络请求参数、用户复杂信息类,日常开发中Lombok的@Builder注解就是建造者模式的落地实现。三、结构型模式高频面试题1.代理模式是什么?静态代理和动态代理的区别?参考答案:代理模式是为目标对象提供一个代理对象,通过代理对象控制对目标对象的访问,可以在不修改目标类代码的前提下,对原有方法进行增强、扩展、拦截。1.静态代理需要手动编写代理类和目标类,实现同一个接口,编译期就确定代理关系。优点是简单易懂;缺点是一个代理类只能代理一个接口,接口新增方法代理类必须同步修改,扩展性极差。2.动态代理运行时动态生成代理类,无需手动编写代码。Java原生JDK动态代理只支持接口代理;CGLIB动态代理通过继承目标类实现,支持代理普通类,无需接口。核心区别:静态代理编译期生成代理类、扩展性差;动态代理运行时生成、通用可复用,SpringAOP、Mybatis插件都基于动态代理实现。2.SpringAOP为什么用JDK动态代理和CGLIB代理?怎么选择?参考答案:SpringAOP底层依赖两种动态代理实现方法增强,选择规则非常明确:1.目标类实现了接口:默认使用JDK动态代理,基于接口生成代理对象,性能稳定、无侵入。2.目标类没有实现接口:自动切换为CGLIB代理,通过字节码技术继承目标类生成子类代理。3.SpringBoot2.0之后,默认强制使用CGLIB代理,统一代理方式,无需区分接口和普通类。注意点:CGLIB无法代理被final修饰的类和方法,因为无法继承、重写。3.装饰器模式和代理模式的区别?参考答案:两者代码结构相似,都是包装目标对象、增强方法,但核心目的完全不同:1.代理模式核心是控制访问,代理类全权管理目标对象的访问权限、执行时机,目标对象对调用者透明,侧重权限控制、事务控制、日志拦截、远程调用等。2.装饰器模式核心是动态增强功能,多层装饰可以叠加不同功能,灵活组合扩展,不改变原有核心逻辑。IO流(BufferedReader包装Reader)就是典型装饰器模式。一句话区分:代理是管控,装饰是增强。4.享元模式是什么?应用场景?参考答案:享元模式是对象池技术的核心,通过复用已有对象,减少重复创建、销毁对象的开销,节省内存、提升性能。核心思想:区分内部状态(可共享、不变)和外部状态(不可共享、动态)。典型应用场景:1.JavaInteger缓存:-128~127的整数对象全局缓存,复用对象;2.字符串常量池:复用已有字符串对象;3.线程池、数据库连接池、Redis连接池;4.系统大量重复的固定配置对象、字典对象。四、行为型模式高频面试题1.策略模式是什么?优缺点及实际项目应用?参考答案:策略模式定义一系列独立的算法,将每个算法封装成单独的策略类,让算法可以相互替换,实现算法和业务逻辑解耦。核心优点:1.完美遵循开闭原则,新增算法只需新增策略类,无需修改原有代码;2.消除大量if-else、switch分支判断,代码更整洁;3.算法独立,互不干扰,方便单独维护、测试。缺点:策略过多时会产生大量策略类,增加类文件数量。项目实战场景:1.支付场景:微信支付、支付宝、银行卡支付、余额支付,不同支付方式封装为不同策略;2.折扣计算:满减、打折、优惠券、拼团折扣,不同优惠策略独立封装;3.文件解析:Excel、Word、PDF解析策略。2.观察者模式是什么?应用场景?和发布订阅区别?参考答案:观察者模式定义一对多的依赖关系,当被观察者(主题)状态发生变化时,所有依赖它的观察者都会收到通知、自动更新。典型应用场景:1.Spring事件监听机制、ApplicationEvent;2.消息推送、订单状态变更通知;3.前端监听数据变化、MQ消息消费。观察者vs发布订阅(核心区别):1.观察者模式:主题和观察者直接耦合,主题直接通知观察者,无中间层;2.发布订阅模式:通过中间消息队列/调度中心解耦,发布者和订阅者互不感知对方存在,完全解耦,分布式场景常用。3.责任链模式是什么?实际项目如何使用?参考答案:责任链模式将多个处理节点串联成一条链条,请求从链条头部传入,依次经过每个节点处理,每个节点可以选择处理请求、放行请求或终止请求。核心优势:请求发送者和处理者解耦,可灵活调整节点顺序、动态新增、删除处理节点,扩展性极强。实战场景:1.Spring拦截器、Servlet过滤器;2.权限校验、参数校验、登录校验、风控校验链路;3.多级审批流程(员工-组长-经理-总监审批);4.异常日志逐级处理。4.模板方法模式核心思想?适用场景?参考答案:模板方法模式定义一个固定的算法骨架(流程),将流程中可变的步骤延迟到子类实现,父类固定流程,子类自定义细节。核心特点:流程固定,细节可变,反向控制(父类调用子类方法)。应用场景:1.Spring中大量框架源码使用,比如Bean初始化流程、事务执行流程;2.统一任务执行流程:定时任务、导入导出任务,固定前置校验、执行、后置日志流程,自定义业务逻辑;3.统一接口响应封装、统一异常处理流程。五、源码级面试高频题(进阶)1.说说你在JDK、Spring源码中见过的设计模式?参考答案:1.单例模式:SpringBean默认单例、Runtime.getRuntime();2.工厂模式:BeanFactory、ApplicationContext容器工厂、线程池工厂;3.代理模式:SpringAOP动态代理、JDKProxy;4.装饰器模式:JavaIO流体系、SpringBeanWrapper;5.策略模式:Spring资源加载策略、不同类型Bean解析策略;6.模板方法模式:SpringFramework大量父类模板方法,如AbstractBeanFactory;7.观察者模式:Spring事件发布监听机制;8.享元模式:Integer缓存、字符串常量池;9.建造者模式:SpringBeanDefinitionBuilder。2.单例模式如何防止反射和序列化破坏?参考答案:1.反射破坏解决方案普通饿汉、懒汉、DCL单例都可以通过反射调用私有构造方法创建新实例,破坏单例。枚举单例天然防反射,JDK底层禁止通过反射创建枚举实例,从根源杜绝破坏。2.序列化破坏解决方案实现Serializable接口的单例类,序列化后反序列化会生成新对象。解决方案:重写readResolve()方法,直接返回全局单例实例;枚举单例同样天然防序列化破坏。结论:枚举单例是Java中最安全、最完美

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论