Java面试第十三山!《设计模式》
大家好,我是陈一。如果文章对你有帮助,请留下一个宝贵的三连哦~ 万分感谢!

一、设计模式入门指南
1. 什么是设计模式?
设计模式是可复用的解决方案模板,用于解决软件开发中常见的架构问题。如同建筑领域的经典设计图纸,它们经历了数十年的实践验证。
2. 为什么要学习?
-
面试必考:90%的中高级Java面试涉及设计模式
-
代码质量:减少重复代码,提升扩展性
-
团队协作:提供统一的术语体系
-
架构思维:培养面向对象设计能力
二、七大核心模式深度解析
1. 单例模式(Singleton)
定义:确保类只有一个实例,并提供全局访问点
场景:数据库连接池、日志记录器、配置管理
/*** 双重校验锁单例实现* 1. volatile防止指令重排序* 2. 双重检查保证线程安全*/
public class DatabasePool {private static volatile DatabasePool instance;// 私有构造器防止外部实例化private DatabasePool() {// 初始化数据库连接}public static DatabasePool getInstance() {if (instance == null) { // 第一次检查synchronized (DatabasePool.class) {if (instance == null) { // 第二次检查instance = new DatabasePool();}}}return instance;}
}
适用场景对比表:
| 实现方式 | 线程安全 | 延迟加载 | 序列化安全 |
|---|---|---|---|
| 饿汉式 | 是 | 否 | 否 |
| 双重检查锁 | 是 | 是 | 否 |
| 静态内部类 | 是 | 是 | 否 |
| Enum实现 | 是 | 否 | 是 |
2. 工厂模式(Factory)
定义:将对象创建逻辑封装,客户端不直接实例化对象
场景:支付渠道选择、日志记录器切换
// 抽象产品接口
interface PaymentGateway {void processPayment(BigDecimal amount);
}// 具体产品实现
class Alipay implements PaymentGateway {@Overridepublic void processPayment(BigDecimal amount) {System.out.println("支付宝支付:" + amount);}
}class WechatPay implements PaymentGateway {@Overridepublic void processPayment(BigDecimal amount) {System.out.println("微信支付:" + amount);}
}// 工厂类
public class PaymentFactory {public static PaymentGateway createGateway(String type) {switch (type.toUpperCase()) {case "ALIPAY":return new Alipay();case "WECHAT":return new WechatPay();default:throw new IllegalArgumentException("不支持的支付类型");}}
}
3. 观察者模式(Observer)
定义:定义对象间的一对多依赖关系,当一个对象状态改变时自动通知依赖对象
场景:订单状态通知、股票价格变动提醒
// 主题接口
interface OrderSubject {void registerObserver(OrderObserver o);void notifyObservers();
}// 具体主题(被观察者)
class Order implements OrderSubject {private List<OrderObserver> observers = new ArrayList<>();private String status;public void setStatus(String status) {this.status = status;notifyObservers();}@Overridepublic void registerObserver(OrderObserver o) {observers.add(o);}@Overridepublic void notifyObservers() {observers.forEach(o -> o.update(this.status));}
}// 观察者接口
interface OrderObserver {void update(String status);
}// 具体观察者
class SMSNotifier implements OrderObserver {@Overridepublic void update(String status) {System.out.println("短信通知:订单状态变更为 " + status);}
}
4. 装饰器模式(Decorator)
定义:动态地为对象添加额外职责,比继承更灵活
场景:数据流处理、IO增强
// 基础组件接口
interface Coffee {String getDescription();BigDecimal getCost();
}// 具体组件
class SimpleCoffee implements Coffee {@Overridepublic String getDescription() {return "普通咖啡";}@Overridepublic BigDecimal getCost() {return new BigDecimal("15.00");}
}// 装饰器抽象类
abstract class CoffeeDecorator implements Coffee {protected Coffee decoratedCoffee;public CoffeeDecorator(Coffee coffee) {this.decoratedCoffee = coffee;}
}// 具体装饰器
class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return decoratedCoffee.getDescription() + " + 牛奶";}@Overridepublic BigDecimal getCost() {return decoratedCoffee.getCost().add(new BigDecimal("3.00"));}
}
5. 策略模式(Strategy)
定义:定义算法族,使它们可以互相替换
场景:促销活动计算、排序算法切换
// 策略接口
interface DiscountStrategy {BigDecimal applyDiscount(BigDecimal originalPrice);
}// 具体策略实现
class FullReductionStrategy implements DiscountStrategy {@Overridepublic BigDecimal applyDiscount(BigDecimal price) {return price.compareTo(new BigDecimal("100")) > 0 ? price.subtract(new BigDecimal("20")) : price;}
}class PercentageDiscountStrategy implements DiscountStrategy {@Overridepublic BigDecimal applyDiscount(BigDecimal price) {return price.multiply(new BigDecimal("0.8"));}
}// 上下文类
class ShoppingCart {private DiscountStrategy strategy;public void setStrategy(DiscountStrategy strategy) {this.strategy = strategy;}public BigDecimal checkout(BigDecimal total) {return strategy.applyDiscount(total);}
}
6. 代理模式(Proxy)
定义:为其他对象提供代理以控制对这个对象的访问
场景:延迟加载、访问控制、日志记录
interface Image {void display();
}class RealImage implements Image {private String filename;public RealImage(String filename) {this.filename = filename;loadFromDisk();}private void loadFromDisk() {System.out.println("加载图片: " + filename);}@Overridepublic void display() {System.out.println("显示图片: " + filename);}
}class ImageProxy implements Image {private RealImage realImage;private String filename;public ImageProxy(String filename) {this.filename = filename;}@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(filename);}realImage.display();}
}
7. 责任链模式(Chain of Responsibility)
定义:将请求的发送者和接收者解耦,使多个对象都有机会处理请求
场景:审批流程、异常处理链
abstract class Approver {protected Approver nextApprover;public void setNext(Approver approver) {this.nextApprover = approver;}public abstract void processRequest(PurchaseRequest request);
}class Manager extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount().compareTo(new BigDecimal("1000")) < 0) {System.out.println("经理审批通过:" + request);} else if (nextApprover != null) {nextApprover.processRequest(request);}}
}class Director extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount().compareTo(new BigDecimal("5000")) < 0) {System.out.println("总监审批通过:" + request);} else if (nextApprover != null) {nextApprover.processRequest(request);}}
}
三、设计模式对比速查表
| 模式 | 类型 | 适用场景 | 关键特征 |
|---|---|---|---|
| 单例模式 | 创建型 | 全局唯一实例 | 私有构造、静态实例 |
| 工厂模式 | 创建型 | 复杂对象创建 | 封装实例化逻辑 |
| 观察者模式 | 行为型 | 事件通知系统 | 发布-订阅机制 |
| 装饰器模式 | 结构型 | 动态功能扩展 | 包装器嵌套 |
| 策略模式 | 行为型 | 算法灵活切换 | 接口多实现 |
| 代理模式 | 结构型 | 访问控制/功能增强 | 间接访问 |
| 责任链模式 | 行为型 | 多级处理流程 | 链式传递 |
四、高频面试问题集锦
1. Spring框架中的设计模式应用
-
工厂模式:BeanFactory
-
代理模式:AOP实现
-
模板方法:JdbcTemplate
-
适配器模式:HandlerAdapter
2. 单例模式双重检查锁原理
if (instance == null) { // 第一次检查synchronized (Singleton.class) { // 同步锁if (instance == null) { // 第二次检查instance = new Singleton(); // 安全初始化}}
}
关键点:volatile防止指令重排序 + 双重检查减少锁竞争
3. 装饰器模式 vs 继承
| 维度 | 装饰器模式 | 继承 |
|---|---|---|
| 扩展方式 | 运行时动态组合 | 编译时静态绑定 |
| 灵活性 | 可多层嵌套不同功能 | 单一父类限制 |
| 类数量 | 按需组合,避免类爆炸 | 容易产生大量子类 |
五、实战应用技巧
-
模式组合:观察者+责任链实现多级审批
-
避免滥用:简单场景不要过度设计
-
重构识别:当发现多重条件判断时考虑策略模式
-
性能考量:代理模式会增加调用层级
真实案例:某电商系统使用装饰器模式实现多级优惠叠加
BigDecimal total = new BigDecimal("200");
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee); // +3元
coffee = new SugarDecorator(coffee); // +1元
System.out.println("总价:" + coffee.getCost()); // 输出19.00
六、学习资源推荐
-
书籍:
-
《Head First设计模式》(图文并茂)
-
《设计模式:可复用面向对象软件的基础》(GoF经典)
-
-
在线资源:
-
Refactoring.Guru(交互式教程)
-
Java Design Patterns(官网示例)
-
-
实战训练:
-
阅读Spring框架源码
-
重构现有项目代码
-
掌握设计模式的关键在于理解思想而非死记硬背。建议从简单模式入手,结合项目实际需求逐步应用。记住:没有最好的模式,只有最合适的场景。
翻过这座山,他们就会听到你的故事!转发本文给需要的朋友,一起备战金三银四! 🚀
相关文章:
Java面试第十三山!《设计模式》
大家好,我是陈一。如果文章对你有帮助,请留下一个宝贵的三连哦~ 万分感谢! 一、设计模式入门指南 1. 什么是设计模式? 设计模式是可复用的解决方案模板,用于解决软件开发中常见的架构问题。如同建筑领域的…...
从 @SpringBootApplication 出发,深度剖析 Spring Boot 自动装配原理
在 Spring Boot 的开发旅程中,SpringBootApplication 注解堪称开启便捷开发之门的钥匙。它不仅是一个简单的注解,更是理解 Spring Boot 自动装配原理的重要入口。接下来,我们将以SpringBootApplication 为切入点,深入探究 Spring …...
使用vue3和vue-router实现动态添加和删除cachedViews数组
以下是一个使用 Vue 3 和 Vue Router 实现动态添加和删除 cachedViews 数组的代码示例,该示例结合 keep-alive 组件来动态控制路由组件的缓存。 src/ ├── App.vue ├── router/ │ └── index.js ├── views/ │ ├── Home.vue │ ├── About.v…...
vue 点击放大,图片预览效果
背景: 在使用vue框架element组件的背景下,我们对图片的展示需要点击放大(单张);如果是多张图片,要支持左右滑动查看多张图片(多张)。 单张图片放大,el-image图片组件,或者原生的img标签。 多张图片放大&…...
如何使用Xshell连接Linux虚拟机
在日常开发和运维工作中,远程连接Linux服务器或虚拟机是一项基本技能。Xshell 是一款功能强大的终端模拟器,支持通过 SSH 协议远程连接 Linux 系统。本文将详细介绍如何使用 Xshell 连接 Linux 虚拟机。准备工作 在开始之前,请确保你已经完成…...
笛卡尔轨迹规划之齐次变换矩阵与欧拉角、四元数的转化
一、笛卡尔轨迹规划需求 笛卡尔轨迹规划本质就是我们对机械臂的末端位置和姿态进行规划,其实也就是对末端坐标系的位姿进行规划。我们清楚末端坐标系的位姿是可以用齐次变换矩阵T来表示的,但这样表示的话,并不利于我们去做规划,所…...
1 存储过程学习: 使用DMSQL程序的优点
DMSQL程序具有以下优点: 与SQL语言的完美结合 SQL语言已成为数据库的标准语言,DMSQL程序支持所有SQL数据类型和所有SQL函数,同时支持所有DM对象类型。在DMSQL程序中可以使用SELECT、INSERT、DELETE、UPDATE数据操作语句,事务控制…...
NPU上如何使能pytorch图模式
1 Pytorch的compile技术 PyTorch 的 torch.compile 是一个强大的功能,用于优化 PyTorch 模型的性能。它通过将 PyTorch 的动态图转换为静态图,并利用 Just-In-Time(JIT)编译技术,显著提高模型的推理速度和训练效率。 …...
进制转换(c++)
由于进制转换属于基础且比较重要,所以我就写一个博客方便自己复习,过程中如有错误,还请指出。 常用的进制有二进制,八进制,十进制和十六进制。 常用的进制转换就是十进制转换成其他进制和其他进制转换成十进制 我们先…...
2025-03-24 学习记录--C/C++-PTA 习题7-7 字符串替换
合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 一、题目描述 ⭐️ 习题7-7 字符串替换 本题要求编写程序,将给定字符串中的大写英文字母按以下对应规则替换&#…...
为什么TCP需要三次握手?一次不行吗?
文章目录 1. 三次握手的过程2. 为什么需要三次握手?3. 握手过程中每一步的具体作用4. 简单比喻5. 为什么是三次握手,而不是两次或四次?6. 三次握手中的序列号有什么作用?7. 总结 1. 三次握手的过程 三次握手是建立 TCP 连接的过程…...
具身系列——NLP工程师切入机器人和具身智能方向
职位高频词汇:VLM调优经验、核心算法(Diffusion、RL、VIT)、pytorch、仿真环境(Isaac Gym、Mujoco、webots) 基于当前具身智能行业发展趋势和岗位需求,以下是为NLP工程师设计的转型路径与策略,…...
SpringBoot2集成Elasticsearch8(使用spring-boot-starter-data-elasticsearch)
写在前面 使用spring-boot-starter-data-elasticsearch集成Elasticsearch8? What? 官方写的不支持啊?让我们来看下官方给出的版本建议。 官方地址: https://docs.spring.io/spring-data/elasticsearch/reference/elasticsearch/versions.…...
【平台优化】持续调度参数在高负载大集群中的影响
持续调度参数在高负载大集群中的影响 背景介绍2种调度通信方式对集群的影响社区相关的讨论结论 背景介绍 这几年经历了我们大数据的Yarn集群的几次扩容,集群从原先的800多台增加到1300多台到现在的1600多台,在集群规模不断增加的过程中,有遇…...
军事级加密通信系统——基于QML的战术地图加密传输
目录 基于QML的战术地图加密传输一、引言二、理论背景与安全需求2.1 战术地图数据的敏感性与安全性要求2.2 QML与PyQt5集成优势2.3 加密算法与数据传输模型三、系统架构与数据流图四、QML前端界面设计与交互功能4.1 QML界面优势与设计理念4.2 功能要求4.3 QML文件示例五、加密传…...
ElasticSearch 可观测性最佳实践
ElasticSearch 概述 ElasticSearch 是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB 级别(大数据时代)的数据。ES 也使用 Java 开…...
(一)飞行器的姿态欧拉角, 欧拉旋转, 完全数学推导(基于坐标基的变换矩阵).(偏航角,俯仰角,横滚角)
(这篇写的全是基矢变换矩阵)不是坐标变换矩阵,坐标变换矩阵的话转置一下,之后会有推导. 是通过M转置变换到P撇点....
基于Spring Boot + Vue的银行管理系统设计与实现
基于Spring Boot Vue的银行管理系统设计与实现 一、引言 随着金融数字化进程加速,传统银行业务向线上化转型成为必然趋势。本文设计并实现了一套基于Spring Boot Vue的银行管理系统,通过模块化架构满足用户、银行职员、管理员三类角色的核心业务需求…...
数据库基础知识点(系列一)
1.数据库的发展历史分哪几个阶段?各有什么特点? 答:数据库技术经历了人工管理阶段、文件系统阶段和数据库系统三个阶段。 1)人工管理阶段 这个时期数据管理的特点是: 数据由计算或处理它的程序自行携带…...
Android Compose 层叠布局(ZStack、Surface)源码深度剖析(十三)
Android Compose 层叠布局(ZStack、Surface)源码深度剖析 一、引言 在 Android 应用开发领域,用户界面(UI)的设计与实现一直是至关重要的环节。随着技术的不断演进,Android Compose 作为一种全新的声明式…...
JVM常用概念之身份哈希码
问题 当我们调用Object.hashCode时,如果没有用户没有提供哈希码,会发生什么? System.identityHashCode如何工作?它是否获取对象地址? 基础知识 在 Java 中,每个对象都有equals和hashCode ,即…...
vue 对接 paypal 订阅和支付
一个是支付一个是订阅,写的时候尝试把他们放到一个里面,但是会报错,所以分开写了 我们的页面,前三个为订阅最后一个是支付,我把他们放到一个数组里面循环展示的,所以我们判断的时候只要判断id是否为4&#…...
Spring Boot - 动态编译 Java 类并实现热加载
为什么需要动态编译? 想象这样一个场景:你的系统需要实时更新业务规则,但重启服务会导致用户体验中断;或者你正在开发一款低代码平台,允许用户编写自定义逻辑并即时生效。这时,动态编译并加载 Java 类的能…...
基于javaweb的SpringBoot实习管理系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...
流影---开源网络流量分析平台(一)(小白超详细)
目录 流影介绍 一、技术架构与核心技术 二、核心功能与特性 流影部署 流影介绍 一、技术架构与核心技术 模块化引擎设计 流影采用四层模块化架构:流量探针(数据采集)、网络行为分析引擎(特征提取)、威胁检测引擎&…...
Spring Boot事件机制详解
Spring Boot事件机制详解 1. 事件机制基础 1.1 什么是事件驱动架构 事件驱动架构(Event-Driven Architecture, EDA)是一种软件设计模式,其中系统组件通过事件的发布与订阅进行通信。在Spring Boot中,事件机制为应用程序提供了松耦合的组件间通信方式&…...
【商城实战(63)】配送区域与运费设置全解析
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
2025高频面试算法总结篇【字符串】
文章目录 直接刷题链接直达无重复字符的最长子串给定一个数,删除K位得到最小值至多包含 K 个不同字符的最长子串字符串的排列至少有K个重复字符的最长子串 直接刷题链接直达 如何找出一个字符串中的最大不重复子串 3. 无重复字符的最长子串 给定一个数࿰…...
Python散点密度图(Scatter Density Plot):数据可视化的强大工具
在数据驱动决策的时代,能够高效地处理和可视化多变量数据是一项 crucial 的技能。今天,我们就来深入探讨散点密度图(Scatter Density Plot),这是一种将散点图和核密度估计相结合的数据可视化技术,主要用于展示大量数据点在二维平面上的分布情况。 一、散点密度图的特点 …...
Oracle 数据库安全评估(DBSAT)简明过程
下载DBSAT 从这里下载。 实际是从MOS中下载,即:Oracle Database Security Assessment Tool (DBSAT) (Doc ID 2138254.1)。 最新版本为3.1.0 (July 2024),名为dbsat.zip,近45MB。 $ ls -lh dbsat.zip -rw-rw-r-- 1 oracle oins…...
