当前位置: 首页 > news >正文

设计模式,面试级别的详解(持续更新中)

设计模式,面试级别的详解(持续更新中)

软件的设计原则

常⽤的⾯向对象设计原则包括7个,这些原则并不是孤⽴存在的,它们相互依赖,相互补充

  • 开闭原则(Open Closed Principle,OCP)
  • 单⼀职责原则(Single Responsibility Principle, SRP)
  • ⾥⽒替换原则(Liskov Substitution Principle,LSP)
  • 依赖倒置原则(Dependency Inversion Principle,DIP)
  • 接⼝隔离原则(Interface Segregation Principle,ISP)
  • 合成/聚合复⽤原则(Composite/Aggregate Reuse Principle, C/ARP)
  • 最少知识原则(Least Knowledge Principle,LKP)或者迪⽶特法则 (Law of Demeter,LOD)
    在这里插入图片描述

设计模式的分类

  • 创建型: 在创建对象的同时隐藏创建逻辑,不使用 new 直接实例化对象,程序在判断需要创建哪些对象时更灵活。包括工厂/抽象工厂/单例/建造者/原型模式。
  • 结构型: 通过类和接口间的继承和引用实现创建复杂结构的对象。包括适配器/桥接模式/过滤器/组合/装饰器/外观/享元/代理模式。
  • 行为型: 通过类之间不同通信方式实现不同行为。包括责任链/命名/解释器/迭代器/中介者/备忘录/观察者/状态/策略/模板/访问者模式。

在这里插入图片描述

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。

构造方法必须是私有的、由自己创建一个静态变量存储实例,对外提供一个静态公有方法获取实例

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

单例模式的常见写法

饿汉式,线程安全

饿汉式单例模式,顾名思义,类一加载就创建对象,这种方式比较常用,但容易产生垃圾对象,浪费内存空间。

/*** 单例模式。饿汉式* 比较常用,但是容易产生垃圾对象* 优点:不用加锁,执行效率会很高* 缺点:类加载时就初始化,浪费内存*/
public class SingletonEHan {private static SingletonEHan instance = new SingletonEHan();private SingletonEHan(){}public static SingletonEHan getInstance(){return instance;}
}
  • 优点:线程安全,没有加锁,执行效率较高
  • 缺点:不是懒加载,类加载时就初始化,浪费内存空间
    • 懒加载 (lazy loading):使用的时候再创建对象

饿汉式单例是如何保证线程安全的呢

它是基于类加载机制避免了多线程的同步问题,但是如果类被不同的类加载器加载就会创建不同的实例,比如使用反射来破坏单例

懒汉式,线程安全

通过 synchronized 关键字加锁保证线程安全, synchronized 可以添加在方法上面,也可以添加在代码块上面,这里演示添加在方法上面,存在的问题是 每一次调用getInstance获取实例时都需要加锁和释放锁,这样是非常影响性能的。

/*** 单例模式* 懒汉式,线程安全,但是效率很低* 优点:第一次调用才初始化,避免内存浪费* 缺点:必须枷锁synchronized才能保证单例,枷锁会影响效率*/
public class SingletonLanHan{private static SingletonLanHan instance;private SingletonLanHan(){}public static synchronized SingletonLanHan getInstance(){if(instance == null){instance = new SingletonLanHan();}return instance;}
}
  • 优点:懒加载,线程安全
  • 缺点:必须枷锁synchronized才能保证单例,枷锁会影响效率
双重检查锁(DCL, 即 double-checked locking)

采用双锁机制,安全且能在多线程的情况下保持高性能

public class SingletonDCL{private static volatile SingletonDCL instance;private SingletonDCL(){}publica static SingletonDCL getInstance(){if(instance == null){synchronized(SingletonDCL.class){if(instance == null){instance == new SingletonDCL();}}}return instance;}
}
  • 优点:懒加载,线程安全,效率较高
  • 缺点:实现较复杂

这里的双重检查是指两次非空判断,锁指的是 synchronized 加锁。

为什么要进行双重判断

其实很简单,第一重判断,如果实例已经存在,那么就不再需要进行同步操作,而是直接返回这个实例,如果没有创建,才会进入同步块,同步块的目的与之前相同,目的是为了防止有多个线程同时调用时,导致生成多个实例,有了同步块,每次只能有一个线程调用访问同步块内容,当第一个抢到锁的调用获取了实例之后,这个实例就会被创建,之后的所有调用都不会进入同步块,直接在第一重判断就返回了单例。

关于内部的第二重空判断的作用,当多个线程一起到达锁位置时,进行锁竞争,其中一个线程获取锁,如果是第一次进入则为 null,会进行单例对象的创建,完成后释放锁,其他线程获取锁后就会被空判断拦截,直接返回已创建的单例对象。

这里为什么要使用 volatile

volatile的两个特性:可⻅性、禁止指令重排序

这是因为 new 关键字创建对象不是原子操作,创建一个对象会经历下面的步骤:

  1. 在堆内存开辟内存空间
  2. 调用构造方法,初始化对象
  3. 引用变量指向堆内存空间

为了提高性能,编译器和处理器常常会对既定的代码执行顺序进行指令重排序,排序后的顺序可能为1、2、3或者1、3、2,因此当某个线程在乱序运行 1、3、2 指令的时候,引用变量指向堆内存空间,这个对象不为 null,但是没有初始化,其他线程有可能这个时候进入了 getInstance 的第一个 if(instance == null) 判断不为 nulll ,导致错误使用了没有初始化的非 null 实例,这样的话就会出现异常,这个就是著名的DCL 失效问题

,其他线程有可能这个时候进入了 getInstance 的第一个 if(instance == null) 判断不为 nulll ,导致错误使用了没有初始化的非 null 实例,这样的话就会出现异常,这个就是著名的DCL 失效问题**。

⼯⼚模式

简单工厂模式

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

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

例子

Calendar 抽象类的 getInstance ⽅法,调⽤createCalendar ⽅法根据不同 的地区参数创建不同的⽇历对象。

Spring 中的 BeanFactory 使⽤简单⼯⼚模式,根据传⼊⼀个唯⼀的标识来 获得 Bean 对象.

⼯⼚⽅法模式

和简单⼯⼚模式中⼯⼚负责⽣产所有产品相⽐,⼯⼚⽅法模式将⽣成具体 产品的任务分发给具体的产品⼯⼚

UML类图如下:
在这里插入图片描述
也就是定义⼀个抽象⼯⼚,其定义了产品的⽣产接⼝,但不负责具体的产品,将⽣产任务交给不同的派⽣类⼯⼚。这样不⽤通过指定类型来创建对象了。

抽象⼯⼚模式

简单⼯⼚模式和⼯⼚⽅法模式不管⼯⼚怎么拆分抽象,都只是针对⼀类产 品,如果要⽣成另⼀种产品,就⽐较难办了!

抽象⼯⼚模式通过在 AbstarctFactory 中增加创建产品的接⼝,并在具体⼦⼯⼚中实现新加产品的创建,当然前提是⼦⼯⼚⽀持⽣产该产品。否则继承的这个接⼝可以什么也不⼲。

UML类图如下:
在这里插入图片描述
从上⾯类图结构中可以清楚的看到如何在⼯⼚⽅法模式中通过增加新产品 接⼝来实现产品的增加的。

相关文章:

设计模式,面试级别的详解(持续更新中)

设计模式,面试级别的详解(持续更新中) 软件的设计原则 常⽤的⾯向对象设计原则包括7个,这些原则并不是孤⽴存在的,它们相互依赖,相互补充。 开闭原则(Open Closed Principle,OCP)单⼀职责原则…...

第9篇:网络访问控制与认证机制

目录 引言 9.1 访问控制策略概述 9.2 认证机制的使用 9.3 密钥分发与证书机制 9.4 访问控制与认证在网络安全中的应用 9.5 网络访问控制与认证的挑战 9.6 总结 第9篇:网络访问控制与认证机制 引言 随着计算机网络的不断普及,安全问题日益受到关…...

CentOS安装NVIDIA驱动、CUDA以及nvidia-container-toolkit

0.提前准备 0.1.更新yum源(以阿里为例) 0.1.1 备份当前的yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 0.1.2 下载新的CentOS-Base.repo 到/etc/yum.repos.d/ CentOS 5 wget -O /etc/yum.repos.d/CentOS-Base…...

STM32调试,发现HAL_Init();之后无法调试,甚至无法让程序停下来

参考文档: STM32调试,发现HAL_Init();之后无法调试,甚至无法让程序停下来 - asml - 博客园 症状 最近开始学习STM32Cube,发现新建工程后无法正常调试,过了HAL_Init();之后就无法继续调试了. 无法进行让程序暂停以及停止等操作.并在输出窗口不断刷出 ERROR: Can n…...

Ajax(web笔记)

文章目录 1.Ajax的概念2.Ajax 的作用3.原生Ajax4.Axios4.1Axios的概念4.2Axios入门 1.Ajax的概念 AsynchronousJavaScriptAndXML,异步的JavaScript和XML 2.Ajax 的作用 数据交换:过Ajax可以给服务器发送请求,并获取服务器响应的数据。异步交互:可以在…...

多入口+vite+vue3预渲染方案

如果你的项目要求加载速度要快,我们如果使用传统的vue3+sfc模式去开发,因为只有一个根节点,空白页面加载出来之后js才回去加载组件渲染,这样页面总是有一个短暂的空白。我们这里不讨论服务器端ssr和预渲染方案,仅仅是为了满足比较极端的优化需求,在这种情况下我的这套方案…...

Vue3+Ts函数封装与应用

目录 一、基础函数 二、实际应用 2.1、根据id找到对应的value值(找第一个) 2.2、根据id找到对应的value值(找所有) 2.3、不重复的升序数组找数字(二分查找) 2.4、重复的无序数组找数字(统计个数) 2.5、将数组整理为树结构(省市区为例) 为什么要积累呢?因为面…...

C语言全局变量和局部变量同时应用的题题型[求一堆数组中10个学生的成绩里最高分、最低分和平均分。]

C语言函数 全局变量与局部结合变量题。 本片代码中包含全局变量max和min。 以及局部变量aver。 全局变量运用于从定义变量开始&#xff0c;局部变量运用于定义它的调用函数内。 正文开始: #include <stdio.h> int max0,min0; int main() { int average(int array[…...

深度学习实战94-基于图卷积神经网络GCN模型的搭建以及在金融领域的场景

大家好,我是微学AI,今天给大家介绍一下深度学习实战94-基于图卷积神经网络GCN模型的搭建以及在金融领域的场景。文章首先介绍了GCN模型的原理及模型结构,随后提供了数据样例,并详细展示了实战代码。通过本文,读者可以深入了解GCN模型在金融场景下的应用,同时掌握代码的具…...

.NET 6新特性 | System.Text.Json功能改进

在.NET 6.0中&#xff0c;JSON处理库得到了显著的改进&#xff0c;主要体现在System.Text.Json上。以下是对.NET 6.0中改进的JSON处理库的详细分析&#xff1a; 一、System.Text.Json的引入与优势 在.NET 6中&#xff0c;Microsoft引入了新的JSON库System.Text.Json作为官方推…...

Matlab如何对全局优化算法启动并行计算

在 MATLAB 中&#xff0c;启用并行计算可以显著提高一些优化算法&#xff08;如遗传算法 ga 和粒子群算法 particleswarm&#xff09;的速度&#xff0c;特别是在种群或粒子群较大时。要启用并行计算&#xff0c;可以使用 UseParallel 参数。 1. 启用并行计算步骤 Step 1: 检…...

MYSQL-查看数据库中的存储过程语法(六)

13.7.5.9 SHOW CREATE PROCEDURE 语句 SHOW CREATE PROCEDURE proc_name此语句是 MySQL 扩展。它返回确切的字符串 &#xff0c;可用于重新创建命名的存储过程。SHOW CREATE FUNCTION&#xff0c;显示有关存储函数的信息 &#xff08;参见第 13.7.5.8 节“ SHOW CREATE FUNCTI…...

【深度学习】(12)--模型部署 <连接客户端与服务端>

文章目录 模型部署一、模型部署的定义与目的二、模型部署的步骤三、模型部署的方式四、Flask框架五、实现模型部署1. 搭建服务端1.1 初始化Flask app1.2 加载模型1.3 数据预处理1.4 构建装饰器1.5 完整代码 2. 搭建客户端2.1 服务端网址2.2 发送请求2.3 完整代码 六、运行使用 …...

优化SQL查询的最佳实践:提升数据库性能的关键

SQL 查询是数据库操作的核心&#xff0c;特别是当数据量庞大时&#xff0c;性能问题尤为明显。优化 SQL 查询不仅能减少响应时间&#xff0c;还能提高系统整体的可伸缩性。本文将从索引、查询结构、数据库设计和缓存等方面详细介绍如何优化 SQL 查询以提升性能。 一、索引的使…...

【AIGC视频生成】视频扩散模型(综述+最新进展)

文章目录 一、综述1.1 扩散模型1.1.1 Denoising Diffusion Probabilistic Models (DDPMs)1.1.2 Score-Based Generative Models (SGMs)1.1.3 Stochastic Differential Equations (Score SDEs) 1.2 相关任务1.3 数据集1.4 评价指标 二、年度进展1.runway gen2.1 Gen-1&#xff1…...

如何下载3GPP协议?

一、进入3GPP网页 https://www.3gpp.org/ 二、点击“Specifications &Technologies” 三、点击“FTP Server” 网址&#xff1a; https://www.3gpp.org/specifications-technologies 四、找到“latest”&#xff0c;查看最新版 网址&#xff1a; https://www.3gpp.org/ftp…...

目标检测系统操作说明【用户使用指南】(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型)

1.100多种【基于YOLOv8/v10/v11的目标检测系统】目录&#xff08;pythonpyside6界面系统源码可训练的数据集也完成的训练模型&#xff09; 2.目标检测系统【环境搭建过程】&#xff08;GPU版本&#xff09; 3.目标检测系统【环境详细配置过程】&#xff08;CPU版本&#xff0…...

Vue中使用路由

目录 单页应用程序&#xff1a;SPA - Single Page Application路由 VueRouterVueRouter使用步骤组件存放目录问题 路由模块封装声明式导航 - 导航连接两个类名自定义匹配类名 声明式导航 - 跳转传参Vue路由 - 重定向Vue路由 - 404Vue路由 - 模式设置 编程式导航 - 基本跳转编程…...

【Linux】多线程安全之道:互斥、加锁技术与底层原理

目录 1.线程的互斥 1.1.进程线程间的互斥相关背景概念 1.2.互斥量mutex的基本概念 所以多线程之间为什么要有互斥&#xff1f; 为什么抢票会抢到负数&#xff0c;无法获得正确结果&#xff1f; 为什么--操作不是原子性的呢&#xff1f; 解决方式&#xff1a; 2.三种加锁…...

收藏多年的四款音频剪辑工具你pick哪一个?

在这个时代&#xff0c;音频剪辑已经成为音乐制作、播客、自媒体等领域的必备技能。而随着网络技术的飞速发展&#xff0c;我们不再需要安装庞大的软件&#xff0c;只需一个浏览器&#xff0c;就能轻松完成音频剪辑工作。今天&#xff0c;就让我为大家推荐几款优秀的在线音频剪…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...