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

Java常见设计模式(中):结构型模式

🌈 引言:设计模式就像乐高积木

  • 适配器:让不同形状的积木完美拼接
  • 装饰器:给积木添加炫酷灯光效果
  • 代理:遥控积木完成复杂动作
  • 组合:将小积木搭建成宏伟城堡

结构型模式
主要用于描述对象之间的关系,包括类和对象的组合、接口和继承等方面。这些模式可以帮助我们更好地组织和管理代码,提高代码的可重用性和可维护性。

🧩 七大结构性模式速览

模式名称核心思想生活类比
适配器模式转换接口,让不兼容的类协同工作电源转换器
桥接模式分离抽象与实现,独立变化遥控器和电视的分离
组合模式树形结构管理部分-整体关系公司组织架构
装饰器模式动态添加功能,不修改原有代码给手机加装保护壳
外观模式简化复杂子系统接口酒店前台一站式服务
享元模式共享细粒度对象,节省资源共享单车
代理模式控制对象访问,增强功能明星经纪人

适配器模式 Adapter Pattern-让不兼容的接口协同工作

将一个类的接口转化成客户希望的另一个接口,使得原本由于接口不兼容而无法一起工作的类可以一起工作。

适配器模式包括以下几个组成部分:

  • 目标接口(Target Interface):客户端期望的接口,类似于目标插座。
  • 适配器(Adapter):充当两个不兼容接口之间的桥梁,使得它们可以互相通信,类似于转换插头。
  • 适配者(Adaptee):需要被适配的对象,它的接口与目标接口不兼容,类似于英标插头。
  • 客户端(Client):使用目标接口的对象。

应用场景

  • 当需要将一个已有的类或接口与另一个不兼容的类或接口进行协同工作时。
  • 当需要对一个已有的类或接口进行修改,以满足客户端的需求时,但是不希望修改该类或接口的源代码。
  • 当需要重新使用一个已有的类或接口,但是不能直接使用该类或接口的方法时。

代码实战:让旧设备支持新接口

// 旧设备(Adaptee)
class OldPrinter {void printDocument(String doc) {System.out.println("Old Printer: " + doc);}
}// 新接口(Target)
interface NewPrinter {void print(String content);
}// 适配器(Adapter)
class PrinterAdapter implements NewPrinter {private OldPrinter oldPrinter;public PrinterAdapter(OldPrinter oldPrinter) {this.oldPrinter = oldPrinter;}@Overridepublic void print(String content) {oldPrinter.printDocument(content);}
}// 客户端
public class Client {public static void main(String[] args) {OldPrinter oldPrinter = new OldPrinter();NewPrinter printer = new PrinterAdapter(oldPrinter);printer.print("Hello, Adapter Pattern!");}
}

输出:

Old Printer: Hello, Adapter Pattern!

使用小结
适配器模式是一种非常有用的设计模式,在JDK中被广泛应用,可以提供一致的接口,比如:
1.Java IO 流是一个常见的适配器模式的例子。它提供了一组标准的接口来访问各种类型的数据源,包括文件、网络连接、内存等等。每个数据源都有自己的接口,但是 Java IO 流可以将这些不同的接口转换为标准的接口,从而提供一致的访问方式。
2.Java Servlet API 也是一个常见的适配器模式的例子。它定义了一组接口来处理 HTTP 请求和响应,包括 doGet()、doPost()、doPut() 等等。每个 Servlet 都必须实现这些接口,但是用户只需要实现其中的一部分即可。这些 Servlet 之间的适配工作由 Servlet 容器完成。

桥接模式

将抽象部分与实现部分分离,以便它们可以独立地变化
**使用场景:**当你希望在不同的维度上变化(如图形的形状和颜色)时。
类比: 就像遥控器和电视之间的桥接。
代码示例:

// 实现接口
interface Color {void applyColor();
}// 抽象类
abstract class Shape {protected Color color;public Shape(Color color) { this.color = color; }abstract void draw();
}// 具体实现
class Red implements Color {public void applyColor() { System.out.print("红色的"); }
}class Circle extends Shape {public Circle(Color c) { super(c); }void draw() {color.applyColor();System.out.println("圆形");}
}

组合模式

将对象组合成树形结构以表示 部分-整体 的层次结构,使得客户端使用单个对象或者组合对象具有一致性。
使用场景:当你希望以统一的方式处理单个对象和组合对象时。
类比: 公司组织架构(部门包含子部门)

interface Component {void show();
}class Leaf implements Component {private String name;public Leaf(String name) { this.name = name; }public void show() { System.out.println("叶子:" + name); }
}class Composite implements Component {private List<Component> children = new ArrayList<>();public void add(Component c) { children.add(c); }public void show() {for(Component c : children) {c.show();}}
}

装饰器模式-动态添加功能

在不修改现有对象的情况下,动态地给一个对象添加一些额外的职责(通过将一个对象包装在另一个对象中来扩展它的行为),就增加功能而言,装饰器模式比生成子类方法更加灵活。
应用场景
1.当需要在不修改现有对象结构的前提下增加新的功能或特性时,可以使用装饰器模式。这样可以保持原有代码的稳定性和兼容性,同时也可以增加代码的灵活性和可扩展性。
2.当需要动态地向对象添加或删除功能时,可以使用装饰器模式。这样可以在运行时动态地添加或删除功能,而不需要修改现有的代码。
3.当需要为多个对象添加相同的功能时,可以使用装饰器模式。这样可以将相同的功能封装在装饰器中,以便于复用和管理。

代码实现
 该示例代码中,Shape 是一个接口,定义了一个 draw 方法,表示绘制图形的操作。Circle 是一个实现 Shape 接口的类,表示一个圆形。
ShapeDecorator 是一个装饰器抽象类,实现了 Shape 接口,并包含一个 Shape 类型的变量 decoratedShape,表示要装饰的对象。RedShapeDecorator 是一个具体的装饰器类,继承了 ShapeDecorator 类,并实现了 draw 方法,在绘制图形时添加了一个红色的边框。
在 main 方法中,我们创建了原始对象 Circle,以及两个装饰器对象 RedShapeDecorator,分别装饰了 Circle 和 Rectangle 对象。通过调用 draw 方法,我们可以看到对象被动态地添加了一个红色的边框,而不需要修改原有的代码。

// 定义接口
interface Shape {void draw();
}// 实现接口
class Circle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Circle");}
}class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Rectangle");}
}// 装饰器抽象类
abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape){this.decoratedShape = decoratedShape;}public void draw(){decoratedShape.draw();}
}// 具体装饰器类
class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw();setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape){System.out.println("Border Color: Red");}
}// 测试代码
public class DecoratorPatternDemo {public static void main(String[] args) {// 创建原始对象Shape circle = new Circle();// 创建装饰器对象Shape redCircle = new RedShapeDecorator(new Circle());Shape redRectangle = new RedShapeDecorator(new Rectangle());// 调用方法System.out.println("Circle with normal border");circle.draw();System.out.println("\nCircle of red border");redCircle.draw();System.out.println("\nRectangle of red border");redRectangle.draw();}
}

使用小结
在实际应用中,装饰器模式经常用于图形界面(GUI)开发、输入/输出流处理、缓存机制、日志记录等领域,可以有效地提高程序的可扩展性和可维护性。比如
1.装饰器模式被广泛应用于Java IO流中,以提供各种不同的功能,如缓存、压缩、加密等等。例如,可以使用 BufferedReader 来缓存读取文件的数据,使用 GZIPOutputStream 来压缩数据,使用 CipherOutputStream 来加密数据等等。
2.Java Swing 组件是一个经典的装饰器模式的例子。它允许在运行时动态地向组件添加功能,如边框、背景、文本等等。例如,可以使用 BorderFactory 来向组件添加边框,使用 Color 来设置组件的背景颜色,使用 Font 来设置组件的字体等等。
3.在 Spring 框架中,装饰器模式被广泛应用于实现 AOP。AOP通过代理模式和装饰器模式实现。JDK 动态代理和 CGLIB 动态代理两种方式实现代理模式,使用装饰器模式对目标对象进行包装,从而实现通知 (Advice) 的织入。例如,可以使用 @Transactional 来添加事务处理的功能,使用 @Cacheable 来添加缓存处理的功能,等等。

外观模式

为子系统中的一组接口提供一个一致的接口,使得子系统更容易使用

  • 特点:提供统一入口,简化复杂系统
  • 场景:一键操作(如电脑开机)、API网关
  • 类比:餐厅服务员(隐藏厨房复杂流程)
class CPU { void start() {} }
class Memory { void load() {} }class ComputerFacade {private CPU cpu = new CPU();private Memory memory = new Memory();public void start() {cpu.start();memory.load();System.out.println("电脑启动完成");}
}

享元模式

运用共享技术来有效地支持大量细粒度对象的复用

  • 特点:共享细粒度对象,节省内存
  • 场景:文字编辑器字符对象、棋子游戏
  • 类比:棋盘共享棋子样式(颜色/形状)
class TreeType {private String name;private String color;// 构造函数...
}class TreeFactory {static Map<String, TreeType> cache = new HashMap<>();static TreeType getTreeType(String name, String color) {String key = name + color;if(!cache.containsKey(key)) {cache.put(key, new TreeType(name, color));}return cache.get(key);}
}

代理模式:控制对象访问

解决的问题
代理模式是Java开发中使用较多的一种设计模式。代理设计就是为其他对象提供一种代理以控制对这个真实对象的访问,起到对代理对象已有功能的增强。

分类
➢静态代理(静态定义代理类,就是在程序运行前就已经存在代理类的字节码文件)
➢动态代理(动态生成代理类,在程序运行期间,由JVM根据反射等机制动态生成,在运行前并不存在代理类的字节码文件)

1. 静态代理:专属经纪人模式

角色分工:

  • Subject:抽象主体角色(明星接口):定义核心业务(唱歌、演戏)
  • RealSubject:真实主体角色(真实明星):周杰伦(专注艺术创作)
  • ProxySubject:代理主体角色(经纪人代理):处理商务对接、安保等杂务

代码实战:明星经纪人系统

// 明星接口
interface Star {void sing(String song);void act(String movie);
}// 真实明星
class JayChou implements Star {public void sing(String song) {System.out.println("周杰伦演唱: " + song);}public void act(String movie) {System.out.println("周杰伦出演: " + movie);}
}// 经纪人代理(静态)
class StarAgent implements Star {private Star target;  // 被代理的明星public StarAgent(Star target) {this.target = target;}public void sing(String song) {System.out.println("【经纪人】对接演唱会场地");target.sing(song);System.out.println("【经纪人】处理粉丝互动");}public void act(String movie) {System.out.println("【经纪人】审核剧本");target.act(movie);System.out.println("【经纪人】安排媒体采访");}
}// 客户端调用
public class Client {public static void main(String[] args) {Star jay = new JayChou();Star agent = new StarAgent(jay);agent.sing("七里香");  // 经纪人全权代理}
}

输出

【经纪人】对接演唱会场地
周杰伦演唱: 七里香
【经纪人】处理粉丝互动

静态代理特点

  • ⚙️ 手动编写代理类,且个明星需专属经纪人。当需要代理多个明星,需要编写多个代理类
  • 🛡️ 代理逻辑硬编码(商务流程固定)
  • ➕ 代理类与真实主体类耦合度太高,接口增加方法时,需修改所有代理类

相比与于静态代理,动态代理则不存在上述的诸多问题,下面我们进入 JDK 的动态代理。

2.动态代理:万能代购模式

DK原生动态代理的组成分为三个部分: 抽象主题角色真实主题角色 、 增强主题角色

  • 抽象主题角色和代理模式的抽象主题角色是一样的,都是抽象出来的接口或类,对于JDK原生动态代理而言,抽象主题角色就是接口
  • 真实主题角色和代理模式的真实主题角色一样,都是被代理类
  • 增强主题角色在JDK原生代理中值的是实现了 InvocationHandler 接口的类,其目的是对真实主题角色的方法的增强。 InvocationHandler 接口中只有一个方法 invoke 方法,所有的动态代理对象中的映射方法在执行时都是调用的 InvocationHandler 接口中的 invoke 方法,在调用 invoke 方法时,动态代理对象会将 被代理对象的方法动态代理对象映射的方法的参数 传递给 InvocationHandler 的 invoke 方法, invoke 方法的实现是由程序员编写的,这样程序员就可以在 被代理对象的方法 执行 前后 进行增强。

🔧 核心功能拆解

组件作用生活比喻
接口(Interface)定义核心功能规范明星的工作合同
真实对象(Target)实现接口的核心业务类明星本人
InvocationHandler代理逻辑处理器(处理额外操作)经纪人的工作手册
Proxy.newProxyInstance动态生成代理对象经纪公司生成经纪人
-- 定义抽象主题接口
public interface Star {void act(); // 拍戏void sing(); // 唱歌
}-- 定义真实主体角色类
public class RealStar implements Star {public void act() {System.out.println("周董在拍戏...");}public void sing() {System.out.println("周董在唱《青花瓷》...");}
}-- 经纪人,动态代理
public class StarProxy implements InvocationHandler {private Object target; // 被代理的明星public Object createProxy(Object target) {this.target = target;// 动态生成代理对象return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("【经纪人】签合同");System.out.println("【经纪人】安排化妆");Object result = method.invoke(target, args); // 调用真实对象的方法System.out.println("【经纪人】收尾款");return result;}
}// 客户端动态生成代理
public class Client {public static void main(String[] args) {Star realStar = new RealStar();Star proxy = (Star) new StarProxy().createProxy(realStar);proxy.act(); // 输出:// 【经纪人】签合同// 【经纪人】安排化妆// 周董在拍戏...// 【经纪人】收尾款proxy.sing();// 输出同上流程}
}

动态代理特点

  • 🌀 运行时动态生成代理类(无需提前编写)
  • 🎯 可代理任意接口类型
  • 🔄 新增接口方法自动适配

📊 静态代理 vs 动态代理 核心对比

模式名称静态代理动态代理
实现方式手动编写代理类运行时动态生成代理类
灵活性一个代理类对应一个接口一个处理器可处理多个接口
代码冗杂度接口方法变化需修改代理类接口扩展无需修改代理逻辑
典型应用简单业务场景Spring AOP、RPC框架等
性能开销无额外运行时开销反射调用带来微小性能损耗
实现复杂度简单直观需理解反射机制和InvocationHandler

🔧 技术原理拆解
静态代理实现要点

  • 代理类与真实类实现相同接口
  • 代理类持有真实对象的引用
  • 在调用前后添加增强逻辑

动态代理底层机制

sequenceDiagramClient->>Proxy: 调用代理方法Proxy->>InvocationHandler: 转发调用InvocationHandler->>RealObject: 反射调用真实方法RealObject-->>InvocationHandler: 返回结果InvocationHandler-->>Proxy: 返回增强结果Proxy-->>Client: 最终响应
  • Proxy类:动态生成代理类的工厂
  • InvocationHandler:所有代理方法的统一入口
  • 反射机制:实现方法调用的动态转发

🛠 实战场景选择指南

  • 选静态代理:当代理逻辑简单、接口稳定时(如日志记录)
  • 选动态代理:当需要代理多个不同接口、或代理逻辑需要统一管理时(如事务管理)
    比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时,不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用proxy来进行大图片的打开。
    掌握代理模式的核心,就像从雇佣专属管家升级为拥有AI智能助手!静态代理是精通的开始,动态代理才是企业级开发的常态。理解这一模式,将为学习Spring AOP、MyBatis插件等框架打下坚实基础! 🚀

💡 高频面试三连
装饰器模式与继承的区别?

  • 装饰器:运行时动态扩展,更灵活
  • 继承:编译时静态扩展,耦合度高

代理模式的应用场景?

  • 远程代理(RMI)
  • 虚拟代理(延迟加载)
  • 保护代理(权限控制)

适配器模式的两种实现方式?

  • 类适配器:通过继承实现
  • 对象适配器:通过组合实现

相关文章:

Java常见设计模式(中):结构型模式

&#x1f308; 引言&#xff1a;设计模式就像乐高积木 适配器&#xff1a;让不同形状的积木完美拼接装饰器&#xff1a;给积木添加炫酷灯光效果代理&#xff1a;遥控积木完成复杂动作组合&#xff1a;将小积木搭建成宏伟城堡 结构型模式 主要用于描述对象之间的关系&#xff…...

C#快速调用DeepSeek接口,winform接入DeepSeek查询资料 C#零门槛接入DeepSeek C#接入DeepSeek源代码下载

下载地址<------完整源码 在数字化转型加速的背景下&#xff0c;企业应用系统对智能服务的需求日益增长。DeepSeek作为先进的人工智能服务平台&#xff0c;其自然语言处理、图像识别等核心能力可显著提升业务系统的智能化水平。传统开发模式下&#xff0c;C#开发者需要耗费大…...

Para-Lane: 首个真实世界多车道数据集,目的评估自动驾驶系统中的新型视角合成能力。

2025-02-22&#xff0c;阿里巴巴集团菜鸟自动驾驶实验室和百度研究院共同创建了一个名为 Para-Lane 的真实世界多车道数据集。该数据集目的评估自动驾驶系统中的新型视角合成&#xff08;NVS&#xff09;能力&#xff0c;通过提供大量真实世界的数据&#xff0c;弥补了现有合成…...

STM32--SPI通信讲解

前言 嘿&#xff0c;小伙伴们&#xff01;今天咱们来聊聊STM32的SPI通信。SPI&#xff08;Serial Peripheral Interface&#xff09;是一种超常用的串行通信协议&#xff0c;特别适合微控制器和各种外设&#xff08;比如传感器、存储器、显示屏&#xff09;之间的通信。如果你…...

Maven 基础环境搭建与配置(一)

一、Maven 初印象 在 Java 开发的广袤天地里&#xff0c;Maven 就像是一位神通广大的 “大管家”&#xff0c;为开发者们排忧解难&#xff0c;让项目管理与构建变得轻松高效。它是一个强大的项目管理和构建自动化工具&#xff0c;基于项目对象模型&#xff08;POM&#xff09;…...

[算法--前缀和] 一维前缀和

目录 1. 前缀和: 是一种对暴力求解的优化.2. 前缀和? 如何利用前面的计算结果提高效率?3. 如何预处理前缀和数组(如何让处理前缀和数组的复杂度是O(N))?接下来, 我们开启一个新的专题 -> 前缀和, 第一道是模板题, 一维前缀和 1. 前缀和: 是一种对暴力求解的优化. 前缀和…...

大模型基础概念之神经网络宽度

在大模型中,神经网络宽度是提升模型容量的核心手段之一,与深度、数据规模共同构成性能的三大支柱。合理增加宽度可显著增强模型表达能力,但需结合正则化、硬件优化和结构设计进行平衡。未来趋势可能包括动态宽度调整、稀疏化宽度设计(如MoE)以及更高效宽度-深度复合缩放策…...

LeetCode 每日一题 2025/2/17-2025/2/23

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 2/17 1287. 有序数组中出现次数超过25%的元素2/18 2080. 区间内查询数字的频率2/19 624. 数组列表中的最大距离2/20 2595. 奇偶位数2/21 2209. 用地毯覆盖后的最少白色砖块…...

《零基础学会!如何用 sql+Python 绘制柱状图和折线图,数据可视化一看就懂》

在数据驱动的时代&#xff0c;MySQL 是最常用的关系型数据库管理系统之一&#xff0c;广泛应用于各类数据存储和处理场景。数据分析的过程不仅仅是收集数据&#xff0c;还包括数据的清洗、转换、查询以及最终的报告和可视化。在本文中&#xff0c;我们将通过实际案例来介绍如何…...

【算法系列】归并排序详解

文章目录 归并排序详解1. 基本原理1.1 分治法策略1.2 归并排序步骤1.3 图解示例 2. 时间复杂度与空间复杂度2.1 时间复杂度2.2 空间复杂度 3. 稳定性4. Java 实现示例5. 归并排序的优点与缺点5.1 优点5.2 缺点 6. 总结 归并排序详解 归并排序&#xff08;Merge Sort&#xff0…...

Vue的项目创建以及项目目录与组合式API

一.创建Vue 1.Vue-CLI:创建Vue的脚手架工具 2.Create-vue&#xff1a;是Vue官方提供的脚手架之一,底层采用官方自主研发的vite,快捷&#xff0c;开发方便。 3.准备工作:系统中需要安装nodejs环境&#xff0c;在该环境中提供npm包管理器 4.创建Vue项目的命令:npm init vuela…...

ubuntu-server 安装 navidia 显卡驱动

资料 https://juejin.cn/post/7362562720708280332 过程 ubuntu-drivers devices 选择ubuntu-server安装 rootroot:~# ubuntu-drivers devices udevadm hwdb is deprecated. Use systemd-hwdb instead. udevadm hwdb is deprecated. Use systemd-hwdb instead. udevadm hwd…...

【学习笔记】计算机网络(四)

第4章 网络层 文章目录 第4章 网络层4.1 网络层的几个重要概念4.1.1 网络层提供的两种服务虚电路服务&#xff08;Virtual Circuit Service&#xff09;数据报服务&#xff08;Datagram Service&#xff09; 4.1.2 网络层的两个层面 4.2 网际协议 IP - IPv44.2.1 虚拟互连网络4…...

DeepSeek-R1:通过强化学习激励大语言模型的推理能力

摘要 本文介绍了我们的第一代推理模型&#xff0c;DeepSeek-R1-Zero 和 DeepSeek-R1。DeepSeek-R1-Zero 是通过大规 模强化学习&#xff08;RL&#xff09;训练的模型&#xff0c;在没有使用监督微调&#xff08;SFT&#xff09;这个前置步骤的情况下&#xff0c;展示了卓越的推…...

Linux运维——网络管理

Linux网络管理 一、Linux网络应用要点二、命令常见用法2.1、curl2.1.1、发送GET请求2.1.2、发送POST请求2.1.3、设置请求头2.1.4、处理cookies2.1.5、处理重定向2.1.6、调试和详细信息2.1.7、使用代理2.1.8、文件上传2.1.9、其它常用选项2.1.10、综合示例 2.2、wget2.2.1、基本…...

洛谷 P8705:[蓝桥杯 2020 省 B1] 填空题之“试题 E :矩阵” ← 卡特兰数

【题目来源】 https://www.luogu.com.cn/problem/P8705 【题目描述】 把 1∼2020 放在 21010 的矩阵里。要求同一行中右边的比左边大&#xff0c;同一列中下边的比上边的大。一共有多少种方案? 答案很大&#xff0c;你只需要给出方案数除以 2020 的余数即可。 【答案提交】 …...

基于Flink SQL实现7天用户行为风险识别,结合滚动窗口预聚合与CEP复杂事件处理技术,根据用户7天的动作,包括交易,支付,评价等行为,识别用户的风险等级

一、数据建模与预聚合 1. 数据源定义 CREATE TABLE user_actions (user_id STRING,event_time TIMESTAMP(3),action_type STRING, -- 交易/支付/评价amount DOUBLE,status STRING, -- 交易状态&#xff08;成功/失败&#xff09;review_score INT, -- 评价分数&#x…...

【无标题】网络安全公钥密码体制

第一节 网络安全 概述 一、基本概念 网络安全通信所需要的基本属性“ 机密性&#xff1b;消息完整性&#xff1b;可访问性与可用性&#xff1b;身份认证。 二、网络安全威胁 窃听&#xff1b;插入&#xff1b;假冒&#xff1b;劫持&#xff1b;拒绝服务Dos和分布式拒绝服务…...

【含开题报告+文档+PPT+源码】基于SpringBoot的进销存管理系统的设计与实现

开题报告 本文提出并研发了一款基于Spring Boot框架构建的进销存管理系统&#xff0c;该系统集成了全方位的企业运营管理功能&#xff0c;涵盖了用户登录验证、系统公告管理、员工信息与权限管理、物料全流程&#xff08;采购入库、销售出库、退货处理&#xff09;控制、部门组…...

Linux-SaltStack配置

文章目录 SaltStack配置 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Linux专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年02月24日20点51分 SaltStack配置 SaltStack 中既支持SSH协议也支持我们的一个客户端 #获取公钥&#xff08;…...

DeepSeek-OpenSourceWeek-第二天-DeepEP

DeepSeek正在进行“开源周”活动,在第二天推出了DeepEP,这是一个面向混合专家(MoE)模型训练和推理的开源通信库。DeepSeek此前的成果已令人印象深刻,此次开源关键组件,体现了其对透明度、社区合作以及推动AI进步的决心,通过5个代码库(已发布2个)来展示这一承诺。 第一…...

事务的4个特性和4个隔离级别

事务的4个特性和4个隔离级别 1. 什么是事务2. 事务的ACID特性2.1 原子性2.2 一致性2.3 持久性2.4 隔离性 3. 事务的创建4. 事务并发时出现的问题4.1 DIRTY READ 脏读4.2 NON - REPEATABLR READ 不可重复读4.3 PHANTOM READ 幻读 5. 事务的隔离级别5.1 READ UNCOMMITTED 读未提交…...

对计算机中缓存的理解和使用Redis作为缓存

使用Redis作为缓存缓存例子缓存的引入 Redis缓存的实现 使用Redis作为缓存 缓存 ​什么是缓存&#xff0c;第一次接触这个东西是在考研学习408的时候&#xff0c;计算机组成原理里面学习到Cache缓存&#xff0c;用于降低由于内存和CPU的速度的差异带来的延迟。它是在CPU和内存…...

vue3 下载文件 responseType-blob 或者 a标签

在 Vue 3 中&#xff0c;你可以使用 axios 或 fetch 来下载文件&#xff0c;并将 responseType 设置为 blob 以处理二进制数据。以下是一个使用 axios 的示例&#xff1a; 使用 axios 下载文件 首先&#xff0c;确保你已经安装了 axios&#xff1a; npm install axios然后在你…...

SOME/IP-SD -- 协议英文原文讲解5

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.2.5 S…...

lowagie(itext)老版本手绘PDF,包含页码、水印、图片、复选框、复杂行列合并等。

入口类&#xff1a;exportPdf ​ package xcsy.qms.webapi.service;import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.nacos.common.utils.StringUtils; import com.ibm.icu.text.RuleBasedNumberFormat; import com.lowa…...

MySQL undo log,redo log和bin log日志文件的生成时间点、层级归属、存储位置及生命周期详解

问题&#xff1a; 假如库名叫做A库&#xff0c;表名叫B表&#xff0c;undo log,redo log和bin log&#xff0c;这些日志文件的生成的时间点是什么&#xff1f;是在mysql的哪一层生成的&#xff1f;哪些文件是有buffer的&#xff1f;哪些日志文件是存在磁盘上的&#xff1f;哪些…...

吃一堑长一智

工作中经历&#xff0c;有感触记录下 故事一 以前在一家公司时&#xff0c;自己是一名开发人员&#xff0c;遇到问题请教领导解决方案&#xff0c;当时领导给了建议&#xff0c;后来上线后出问题了&#xff0c;背了锅。心里想的是领导说这样做的呀&#xff0c;为什么出问题还…...

DeepSeek基础之机器学习

文章目录 一、核心概念总结&#xff08;一&#xff09;机器学习基本定义&#xff08;二&#xff09;基本术语&#xff08;三&#xff09;假设空间&#xff08;四&#xff09;归纳偏好&#xff08;五&#xff09;“没有免费的午餐”定理&#xff08;NFL 定理&#xff09; 二、重…...

达梦有没有类似oerr的功能

在oracle 23ai的sqlplus中&#xff0c;直接看异常信息说明&#xff1a; 达梦没有此功能&#xff0c;但是可以造一个 cd /home/dmdba cat >err.sql<<eof set echo off set ver off set timing off set lineshow off set feedback off select * from V\$ERR_INFO wher…...