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

8种结构型设计模式对比

一、适配器模式

简介

适配器模式是一种结构型设计模式,它用于将不兼容的接口转换为可兼容的接口。适配器模式允许两个不兼容的类能够协同工作,通过将一个类的接口转换为另一个类所期望的接口形式。这样就能够在不修改现有代码的情况下,使两个不兼容的类能够相互协作。

使用场景

适配器模式通常在以下场景中使用:

  • 当需要将现有类的接口转换为其他接口时,可以使用适配器模式。
  • 当需要与一个或多个现有类进行适配以实现特定功能时,适配器模式是一个非常有用的工具。

代码案例

// 目标接口
interface Target {void request();
}// 需要适配的类
class Adaptee {void specificRequest() {System.out.println("Adaptee's specific request");}
}// 适配器类
class Adapter implements Target {private Adaptee adaptee;Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest();}
}// 使用适配器
public class Main {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target target = new Adapter(adaptee);target.request();}
}

优点

  • 适配器模式能够让两个不兼容的接口能够协同工作,提高代码的复用性和灵活性。
  • 适配器模式能够让客户端代码与具体类解耦,减少了客户端代码对具体类的依赖。

缺点

  • 适配器模式可能需要创建更多的类来实现适配器和被适配者之间的关系,增加了代码的复杂性。
  • 适配器模式可能会引入一定的性能损失,因为需要通过适配器来实现接口转换。

对比其他模式

  • 适配器模式和桥接模式类似,但是适配器模式用于处理接口转换,而桥接模式用于处理抽象和实现的分离。
  • 适配器模式和装饰器模式类似,但是适配器模式用于接口转换,而装饰器模式用于动态地给对象添加额外的功能。

二、桥接模式

简介

桥接模式是一种结构型设计模式,它将抽象部分和实现部分分离,使它们可以独立地变化。通过将抽象和实现分离,桥接模式可以使两者能够独立地进行扩展。这种模式的核心目标是通过解耦抽象和实现,来使它们能够相互独立地变化。

使用场景

桥接模式通常在以下场景中使用:

  • 当需要抽象和实现能够独立地变化时,可以使用桥接模式。
  • 当需要避免多重继承的情况下,可以使用桥接模式。
  • 当需要改变一个类的实现时,不影响其他使用该类的类时,可以使用桥接模式。

代码案例

// 实现部分接口
interface Implementor {void operationImp();
}// 具体实现部分A
class ConcreteImplementorA implements Implementor {@Overridepublic void operationImp() {System.out.println("ConcreteImplementorA operationImp");}
}// 具体实现部分B
class ConcreteImplementorB implements Implementor {@Overridepublic void operationImp() {System.out.println("ConcreteImplementorB operationImp");}
}// 抽象部分接口
abstract class Abstraction {protected Implementor implementor;Abstraction(Implementor implementor) {this.implementor = implementor;}abstract void operation();
}// 具体抽象部分
class ConcreteAbstraction extends Abstraction {ConcreteAbstraction(Implementor implementor) {super(implementor);}@Overridevoid operation() {implementor.operationImp();}
}// 使用桥接模式
public class Main {public static void main(String[] args) {Implementor implementorA = new ConcreteImplementorA();Implementor implementorB = new ConcreteImplementorB();Abstraction abstractionA = new ConcreteAbstraction(implementorA);abstractionA.operation();Abstraction abstractionB = new ConcreteAbstraction(implementorB);abstractionB.operation();}
}

优点

  • 桥接模式使抽象部分和实现部分能够独立地变化,解耦了抽象和实现,提高了代码的灵活性和可扩展性。
  • 桥接模式可以在运行时动态地切换实现,不需要修改客户端代码。

缺点

  • 桥接模式可能会增加系统的复杂性,因为需要创建额外的抽象和实现类来进行桥接。
  • 桥接模式可能会增加系统的开销,因为需要通过桥接来实现抽象和实现的分离。

对比其他模式

  • 桥接模式和适配器模式类似,但是桥接模式用于处理抽象和实现的分离,而适配器模式用于处理接口转换。
  • 桥接模式和装饰器模式类似,但是桥接模式用于抽象和实现的分离,而装饰器模式用于动态地给对象添加额外的功能。

三、组合模式

简介

组合模式是一种结构型设计模式,它允许将对象组合成树形结构,以表示整体-部分的层次结构。通过使用组合模式,可以以统一的方式处理对象组合和单个对象。

使用场景

  • 当希望将对象以树形结构组织起来的时候,可以使用组合模式。例如,文件系统中的文件和目录可以使用组合模式来表示,每个目录都可以包含子目录和文件。
  • 当需要对整个对象集合或其中一部分进行处理时,可以使用组合模式。例如,统计一个部门的所有员工的工资总和,可以通过遍历部门的树形结构来计算。

代码案例

// 抽象组件
interface Component {void operation();
}// 叶子组件
class Leaf implements Component {public void operation() {System.out.println("Leaf operation");}
}// 复合组件
class Composite implements Component {private List<Component> components = new ArrayList<>();public void add(Component component) {components.add(component);}public void remove(Component component) {components.remove(component);}public void operation() {System.out.println("Composite operation");for (Component component : components) {component.operation();}}
}// 使用示例
public class Main {public static void main(String[] args) {Component leaf1 = new Leaf();Component leaf2 = new Leaf();Component composite1 = new Composite();Component composite2 = new Composite();composite1.add(leaf1);composite1.add(leaf2);composite2.add(composite1);composite2.operation();}
}

优缺点

优点:

  • 可以简化客户端代码,客户端可以统一处理复合对象和叶子对象。
  • 新增或移除组件比较容易,客户端无需关心具体组件的类型。

缺点:

  • 增加了系统的复杂性,部分情况下可能会加重代码的维护负担。
  • 使用组合模式时,需要权衡透明性和安全性,可能会导致设计模糊。

与其他模式对比

  • 组合模式和装饰器模式:两者都涉及对象组合,但装饰器模式注重给对象动态添加功能,而组合模式注重树形结构。
  • 组合模式和桥接模式:两者都涉及对象组合,但桥接模式注重将抽象和实现解耦,而组合模式注重树形结构。
  • 组合模式和享元模式:两者都涉及对象共享,但组合模式注重树形结构,共享的是整体,而享元模式注重细粒度对象的共享。

四、装饰器模式

简介

装饰器模式是一种结构型设计模式,它允许动态地给对象添加额外的功能。装饰器模式通过使用额外的对象来包装原始对象,并在调用原始对象的方法前后执行额外的操作。

使用场景

  • 当需要给对象动态地添加额外功能或行为时,可以使用装饰器模式。例如,为了在运行时对数据库查询结果进行缓存,可以使用装饰器模式来包装查询操作。
  • 当希望继承关系具有更大灵活性时,可以使用装饰器模式。装饰器模式允许动态地给对象添加额外功能,避免了静态继承的限制。

代码案例

# 抽象组件
class Component:def operation(self):pass# 具体组件
class ConcreteComponent(Component):def operation(self):print("ConcreteComponent operation")# 装饰器基类
class Decorator(Component):def __init__(self, component):self._component = componentdef operation(self):self._component.operation()# 具体装饰器
class ConcreteDecoratorA(Decorator):def operation(self):super().operation()print("ConcreteDecoratorA operation")class ConcreteDecoratorB(Decorator):def operation(self):print("ConcreteDecoratorB operation")super().operation()# 使用示例
component = ConcreteComponent()
decoratorA = ConcreteDecoratorA(component)
decoratorB = ConcreteDecoratorB(decoratorA)
decoratorB.operation()

优缺点

优点:

  • 可以动态地给对象添加额外的功能,而不需要修改原始对象的代码。
  • 装饰器模式遵循开闭原则,允许在不修改现有代码的情况下,给对象添加新的功能。

缺点:

  • 增加了系统的复杂性,需要尽量避免过多的装饰器嵌套。
  • 需要注意装饰器的顺序,因为装饰器的执行顺序可能会影响最终结果。

与其他模式对比

  • 装饰器模式和代理模式:两者都涉及对象包装,但装饰器模式注重动态添加功能,而代理模式注重控制对象的访问。
  • 装饰器模式和适配器模式:两者都涉及对象的包装,但适配器模式注重将不同接口的对象适配为统一接口,而装饰器模式注重动态添加功能。
  • 装饰器模式和桥接模式:两者都涉及对象的包装,但装饰器模式注重给对象动态添加功能,而桥接模式注重将抽象部分和实现部分解耦。

五、外观模式

简介

外观模式是一种结构型设计模式,它提供了一个统一的接口,用于访问子系统的一组接口。外观模式通过封装一组复杂的子系统接口,简化了客户端与子系统之间的交互。

使用场景

  • 当希望对复杂子系统进行简化并提供统一接口的时候,可以使用外观模式。例如,客户端需要与数据库、缓存、消息队列等多个组件交互时,可以通过外观模式将这些交互封装起来,对外提供统一的接口。
  • 当需要解耦客户端和子系统之间的依赖关系时,可以使用外观模式。

代码案例

# 子系统A
class SubsystemA:def methodA(self):print("SubsystemA methodA")# 子系统B
class SubsystemB:def methodB(self):print("SubsystemB methodB")# 外观类
class Facade:def __init__(self):self._subsystemA = SubsystemA()self._subsystemB = SubsystemB()def operation(self):self._subsystemA.methodA()self._subsystemB.methodB()# 使用示例
facade = Facade()
facade.operation()

优缺点

优点:

  • 简化了客户端与子系统之间的交互,客户端只需要与外观类交互即可,不需要了解子系统的细节。
  • 解耦了客户端和子系统的依赖关系,客户端只需要依赖外观类即可。

缺点:

  • 太多的依赖于外观类可能会导致系统可维护性下降,不利于系统的扩展。

与其他模式对比

  • 外观模式和适配器模式:两者都涉及封装,但外观模式注重对一组接口的统一封装,而适配器模式注重对不同接口的适配。
  • 外观模式和中介者模式:两者都涉及解耦客户端和子系统的依赖关系,但中介者模式注重通过中介对象进行交互,而外观模式注重提供统一的接口。
  • 外观模式和代理模式:两者都涉及封装,但代理模式注重控制对象的访问,而外观模式注重对一组接口的统一封装。

六、享元模式

简介

享元模式是一种结构型设计模式,它通过共享对象来减少内存使用,以支持大量细粒度的对象。享元模式将对象的状态分为内部状态和外部状态,内部状态可以共享,外部状态可以由客户端传入。

使用场景

  • 当需要创建大量细粒度对象,并且内部状态可以共享时,可以使用享元模式。例如,网页编辑器中的字母对象,可以通过享元模式来实现共享。
  • 当对象的大部分状态可以从外部传入,并且不依赖于具体对象的时候,可以使用享元模式。

代码案例

import java.util.HashMap;
import java.util.Map;// 具体享元类
class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {System.out.println("Intrinsic state: " + intrinsicState);System.out.println("Extrinsic state: " + extrinsicState);}
}// 享元工厂
class FlyweightFactory {private Map<String, Flyweight> flyweights = new HashMap<>();public Flyweight getFlyweight(String key) {if (!flyweights.containsKey(key)) {flyweights.put(key, new ConcreteFlyweight(key));}return flyweights.get(key);}
}// 使用示例
public class Main {public static void main(String[] args) {FlyweightFactory factory = new FlyweightFactory();Flyweight flyweight1 = factory.getFlyweight("key1");flyweight1.operation("state1");Flyweight flyweight2 = factory.getFlyweight("key2");flyweight2.operation("state2");}
}

优缺点

优点:

  • 可以减少内存使用,提高系统的性能。
  • 在大规模细粒度对象的场景下,可以节省大量内存空间。

缺点:

  • 增加了系统的复杂性,需要对外部状态进行管理,可能会引入线程安全问题。
  • 需要权衡在内部状态和外部状态之间的共享程度。

与其他模式对比

  • 享元模式和单例模式:两者都涉及共享对象,但单例模式注重单一实例,而享元模式注重共享细粒度对象。
  • 享元模式和原型模式:两者都涉及创建对象,但原型模式注重克隆对象,而享元模式注重共享对象。
  • 享元模式和代理模式:两者都涉及对象的封装,但代理模式注重控制对象的访问,而享元模式注重共享对象的内部状态。

七、代理模式

简介

代理模式是一种结构型设计模式,用于控制对象的访问,并在访问对象时添加额外的处理。代理模式通过创建一个代理对象来代替原始对象,客户端使用代理对象进行操作,代理对象在执行操作前后可以添加一些额外的逻辑。

使用场景

  • 当需要对对象的访问进行控制时,可以使用代理模式。例如,限制对敏感数据的访问,可以创建一个代理对象,在访问敏感数据前进行身份验证。
  • 当需要在访问对象时添加额外的处理逻辑时,可以使用代理模式。例如,记录日志、缓存结果等操作,都可以在代理对象中完成。

代码案例

// 抽象主题
interface Subject {void operation();
}// 具体主题
class RealSubject implements Subject {public void operation() {System.out.println("RealSubject operation");}
}// 代理类
class Proxy implements Subject {private RealSubject realSubject;public void operation() {beforeOperation();if (realSubject == null) {realSubject = new RealSubject();}realSubject.operation();afterOperation();}private void beforeOperation() {System.out.println("Proxy before operation");}private void afterOperation() {System.out.println("Proxy after operation");}
}// 使用示例
public class Main {public static void main(String[] args) {Proxy proxy = new Proxy();proxy.operation();}
}

优缺点

优点:

  • 可以控制对对象的访问,并在访问对象时添加额外的处理。
  • 代理模式遵循开闭原则,客户端不需要修改原始对象的代码,只需要使用代理对象即可。

缺点:

  • 代理模式增加了系统的复杂性,因为引入了新的对象。
  • 可能会降低系统的性能,因为代理对象需要额外的处理逻辑。

与其他模式对比

  • 代理模式与装饰器模式:两者都涉及对象的封装,但装饰器模式注重给对象动态添加功能,而代理模式注重控制对象的访问。
  • 代理模式与适配器模式:两者都涉及对象的转换,但适配器模式注重将不同接口的对象适配为统一接口,而代理模式注重控制对象的访问。
  • 代理模式与外观模式:两者都涉及封装,但外观模式注重提供统一接口,而代理模式注重控制对象的访问。

八、装饰器模式

简介

装饰器模式是一种结构型设计模式,允许动态地给对象添加额外的功能。装饰器模式通过使用额外的对象来包装原始对象,并在调用原始对象的方法前后执行额外的操作。

使用场景

  • 当需要给对象动态地添加额外的功能或行为时,可以使用装饰器模式。例如,在不修改原有类的情况下,为对象添加日志记录、性能统计、缓存等功能。
  • 当希望继承关系具有更大灵活性时,可以使用装饰器模式。装饰器模式允许动态地给对象添加额外的功能,避免了静态继承带来的类爆炸问题。

代码案例

# 抽象组件
class Component:def operation(self):pass# 具体组件
class ConcreteComponent(Component):def operation(self):print("ConcreteComponent operation")# 装饰器基类
class Decorator(Component):def __init__(self, component):self._component = componentdef operation(self):self._component.operation()# 具体装饰器
class ConcreteDecoratorA(Decorator):def operation(self):print("ConcreteDecoratorA operation")super().operation()class ConcreteDecoratorB(Decorator):def operation(self):super().operation()print("ConcreteDecoratorB operation")# 使用示例
component = ConcreteComponent()
decoratorA = ConcreteDecoratorA(component)
decoratorB = ConcreteDecoratorB(decoratorA)
decoratorB.operation()

优缺点

优点:

  • 可以动态地给对象添加额外的功能,而不需要修改原始对象的代码。
  • 装饰器模式遵循开闭原则,允许在不修改现有代码的情况下,给对象添加新的功能。

缺点:

  • 增加了系统的复杂性,需要尽量避免过多的装饰器嵌套。
  • 需要注意装饰器的顺序,因为装饰器的执行顺序可能会影响最终结果。

与其他模式对比

  • 装饰器模式和代理模式:两者都涉及对象包装,但装饰器模式注重动态添加功能,而代理模式注重控制对象的访问。
  • 装饰器模式和适配器模式:两者都涉及对象的包装,但适配器模式注重将不同接口的对象适配为统一接口,而装饰器模式注重动态添加功能。
  • 装饰器模式和桥接模式:两者都涉及对象的包装,但装饰器模式注重给对象动态添加功能,而桥接模式注重将抽象部分和实现部分解耦。

相关文章:

8种结构型设计模式对比

一、适配器模式 简介 适配器模式是一种结构型设计模式&#xff0c;它用于将不兼容的接口转换为可兼容的接口。适配器模式允许两个不兼容的类能够协同工作&#xff0c;通过将一个类的接口转换为另一个类所期望的接口形式。这样就能够在不修改现有代码的情况下&#xff0c;使两…...

【PX4】Ubuntu20.04+ROS Noetic 配置PX4-v1.12.2和Gazebo11联合仿真环境【教程】

【PX4】Ubuntu20.04ROS Noetic 配置PX4-v-v1.12.2和Gazebo11联合仿真环境【教程】 文章目录 【PX4】Ubuntu20.04ROS Noetic 配置PX4-v-v1.12.2和Gazebo11联合仿真环境【教程】0. 安装UbuntuROS1. 安装依赖2. 安装QGC地面站3. 配置PX4-v1.12.23.1 安装PX43.2 测试PX4是否成功安装…...

msvcp120.dll丢失怎么办?(五种方法快速解决)

首先&#xff0c;让我们来了解一下msvcp120.dll这个文件。msvcp120.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C 2012 Redistributable Package的一部分。这个文件的作用是支持一些应用程序的运行&#xff0c;例如游戏、办公软件等。当我们在使用这些软件时&am…...

eslint写jsx报错

eslint写jsx报错 ChatGPT提示 在写JSX时&#xff0c;ESLint可能会报出一些语法错误&#xff0c;这些错误通常是由于ESLint默认配置中不支持JSX语法导致的。为了解决这些错误&#xff0c;我们需要在ESLint配置文件中启用对JSX语法的支持。 首先&#xff0c;需要安装eslint-pl…...

最新适合小白前端 Javascript 高级常见知识点详细教程(每周更新中)

1. window.onload 窗口或者页面的加载事件&#xff0c;当文档内容完全加载完成会触发的事件&#xff08;包括图形&#xff0c;JS脚本&#xff0c;CSS文件&#xff09;&#xff0c;就会调用处理的函数。 <button>点击</button> <script> btn document.q…...

积分值和面积、对称性

积分的基本含义要从积分符号说起&#xff0c;积分号含有加号的意思&#xff0c; ∫ a b f ( x ) d x \int ^b_af(x)dx ∫ab​f(x)dx可以理解为&#xff1a;区间[a,b]无限细分为无穷多个dx,无穷多个f(x)乘以dx的累积和。根据上面的描述&#xff0c;面积可以理解为 ∫ a b ∣ f (…...

springboot 整合es

Spring Boot可以轻松地与Elasticsearch进行整合&#xff0c;以实现高效的搜索和分析功能。 以下是如何在Spring Boot应用程序中使用Elasticsearch的步骤&#xff1a; 1.添加依赖项 在pom.xml文件中添加以下依赖项&#xff1a; <dependency><groupId>org.spring…...

MyBatisPlus使用自定义JsonTypeHandler实现自动转化JSON

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…...

LeetCode 2097. 合法重新排列数对【欧拉通路,DFS】2650

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

学习笔记-接口测试(postman、jmeter)

目录 一、什么是接口测试 二、前端和后端 三、get请求和post请求的区别 四、cookie和session 五、接口测试的依据 六、HTTP状态码 七、通用接口用例 八、postman接口测试 九、Jmeter接口测试 一、什么是接口测试 通常做的接口测试指的是系统对外的接口&#xff0c;比…...

如何高效批量查询快递单号,提高工作效率?

在日常生活中&#xff0c;快递单号的查询是一项常规任务。过去&#xff0c;这项任务需要通过人工一个一个地在快递平台上查询&#xff0c;既耗时又费力。然而&#xff0c;随着科技的发展&#xff0c;我们有了更多的工具可以帮助我们高效地完成这项任务。本文将介绍如何使用固乔…...

12万汉语源流词典汉字记性ACCESS\EXCEL数据库

《12万汉语源流词典汉字记性ACCESS数据库》在继承前人经验的基础上&#xff0c;注意吸收今人的研究成果&#xff0c;注重形音义的密切配合&#xff0c;尽可能历史地、正确地反映汉字形音义的发展。在字形方面&#xff0c;简要说明其结构的演变。语义解释遵循古今语义的发展变化…...

深度解剖数据在队列的应用

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 望小伙伴们点赞&#x1f44d;收藏✨加关注哟&#x1f495;&#x1…...

IMX6ULL移植篇-Linux内核源码目录分析二

一. Linux内核源码目录 本文继续来具体说明 Linux内核源码的一些重要文件含义。 本文续上一篇文章&#xff0c;地址如下&#xff1a; IMX6ULL移植篇-Linux内核源码目录分析一_凌肖战的博客-CSDN博客 二. Linux内核源码目录分析 9. init 目录 此目录存放 Linux 内核启动的…...

汽车行业数据治理方案,助力车企研产供销数据一体化

随着数字技术的不断革新和应用&#xff0c;汽车行业已转向大数据、新技术寻求生产力突破&#xff0c;以电动化、网联化、智能化、共享化为标志的“汽车新四化”&#xff0c;为汽车行业带来了翻天覆地的变化。如何抓住“新四化”的机会&#xff0c;在汽车产业变革中赢得先机&…...

canvas-绘图库fabric.js简介

一般情况下简单的绘制&#xff0c;其实canvas原生方法也可以满足&#xff0c;比如画个线&#xff0c;绘制个圆形、正方形、加个文案。 let canvas document.getElementById(canvas);canvas.width 1200;canvas.height 600;canvas.style.width 1200px;canvas.style.height 6…...

代码审计——任意文件下载详解(二)

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 漏洞描述02 审计要点03 漏洞特征04 漏洞案例05 修复方案 01 漏洞描述 网站可能提供文件查看或下载的功能&#xff0c;如果对用户查看或下载的文件不做限制&#xff0c;就能够查看或下载任意的文件&…...

19异常的学习笔记

异常 很重要&#xff0c;有利于我们平时处理问题 异常就是代表程序出现了问题 常见的异常比如说 数组越界除法除0 异常的体系是什么 java.lang.Throwable Error Exception RuntimeException 其他异常 Error 代表的是系统级别的错误&#xff0c;也就是一旦系统出现问题&…...

Jenkins学习笔记4

配置构建流程&#xff1a; Jenkins任务创建&#xff1a; 1&#xff09;创建新任务&#xff1a; 把这个Accept first connection改成 No Validation。问题得到解决。 构建触发器这块暂时没有需要配置的。 传输文件到nginx-server这个web服务器中。 将文件上传到/usr/share/n…...

自学 Java 需要具备哪些基本条件或技能?

新手初学者在自己学习Java时&#xff0c;需要注意两个方面&#xff0c;一个是学习方面&#xff0c;一个是知识点方面&#xff01; 学习方面&#xff1a; 1、做学习计划并保持自律 在我们学习Java的过程中&#xff0c;尽量减少干扰&#xff0c;把自己的全部注意力集中在Java上…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...