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

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…...

DeepSeek R1 + 飞书机器人实现AI智能助手

效果 TFChat项目地址 https://github.com/fish2018/TFChat 腾讯大模型知识引擎用的是DeepSeek R1&#xff0c;项目为sanic和redis实现&#xff0c;利用httpx异步处理流式响应&#xff0c;同时使用buffer来避免频繁调用飞书接口更新卡片的网络耗时。为了进一步减少网络IO消耗&…...

【论文详解】Transformer 论文《Attention Is All You Need》能够并行计算的原因

文章目录 前言一、传统 RNN/CNN 存在的串行计算问题二、Transformer 如何实现并行计算&#xff1f;三、Transformer 的 Encoder 和 Decoder 如何并行四、结论 前言 亲爱的家人们&#xff0c;创作很不容易&#xff0c;若对您有帮助的话&#xff0c;请点赞收藏加关注哦&#xff…...

51c嵌入式~电路~合集12

我自己的原文哦~ https://blog.51cto.com/whaosoft/12318429 一、单端、推挽、桥式拓扑结构变压器对比 单端正激式 单端&#xff1a;通过一只开关器件单向驱动脉冲变压器。 正激&#xff1a;脉冲变压器的原/付边相位关系&#xff0c;确保在开关管导通&#xff0c;驱动脉冲…...

php 获取head参数

php 获取head参数 在PHP中&#xff0c;获取HTTP头部&#xff08;head&#xff09;参数可以通过不同的方式实现&#xff0c;下面为你详细介绍几种常见的方法。 1. 使用$_SERVER超全局变量 $_SERVER 是PHP中的一个超全局变量&#xff0c;它包含了诸如头信息、路径、脚本位置等…...

蓝桥杯嵌入式备赛

前言 嘿&#xff0c;小伙伴们&#xff01;备战蓝桥杯嵌入式比赛的号角已经吹响啦&#xff01;如果你还在为如何入手STM32G431RB这块比赛板子而发愁&#xff0c;别担心&#xff0c;今天我就来给你全方位介绍这块板子&#xff0c;带你快速上手备赛&#xff0c;一起冲向蓝桥杯的赛…...

基于PyTorch实现的自适应注意力卷积网络(AACN)详解

目录 基于PyTorch实现的自适应注意力卷积网络(AACN)详解1. 引言2. 网络结构设计2.1 输入层2.2 初始特征提取层2.3 自适应注意力卷积块(AACB)2.4 下采样与高层特征提取层2.5 全局特征汇聚层2.6 输出层3. 模型优化策略4. 数据集介绍5. PyTorch实现代码详解5.1 完整代码实现5.…...

基于Javase的停车场收费管理系统

基于Javase的停车场收费管理系统 停车场管理系统开发文档 项目概述 1.1 项目背景 随着现代化城市的不断发展&#xff0c;车辆数量不断增加&#xff0c;停车难问题也日益突出。为了更好地管理停车场资 源&#xff0c;提升停车效率&#xff0c;需要一个基于Java SE的停车场管理…...

Cookie与Session:Web开发中的状态管理机制

引言 在Web开发中&#xff0c;HTTP协议是无状态的&#xff0c;这意味着服务器默认不会记住客户端的任何信息。然而&#xff0c;许多应用场景&#xff08;如用户登录、购物车等&#xff09;需要服务器能够识别客户端并保持状态。为了解决这个问题&#xff0c;开发者引入了 Cook…...

python量化交易——金融数据管理最佳实践——qteasy创建本地数据源

文章目录 qteasy金融历史数据管理总体介绍本地数据源——DataSource对象默认数据源查看数据表查看数据源的整体信息最重要的数据表其他的数据表 从数据表中获取数据向数据表中添加数据删除数据表 —— 请尽量小心&#xff0c;删除后无法恢复&#xff01;&#xff01;总结 qteas…...

手机放兜里,支付宝“碰一下”被盗刷?

大家好&#xff0c;我是小悟。 近期&#xff0c;网络上关于“支付宝‘碰一下’支付易被盗刷”的传言甚嚣尘上&#xff0c;不少用户对此心生疑虑。 首先&#xff0c;要明确一点&#xff1a;“碰一下”支付并不会像某些传言中所描述的那样容易被隔空盗刷。这一观点已经得到了支付…...

C/C++语言知识点一

目录 1. 请对这段代码进行解释&#xff1a;char *const *(*next)( ); 2. 函数指针数组&#xff1a;解释这个表达式char *(*c[10])(int **p); 3. 字符串常量&#xff1a;分析下面这段代码。 4. 访问指定内存地址 5. typedef 和 define 的区别 6. 函数返回局部变量地址问…...

前端面试题---在vue中为什么要用路由

在vue中为什么要用路由, 毕竟a标签可以直接跳转页面 在 Vue 中使用 Vue Router 的主要原因是提高 单页面应用&#xff08;SPA&#xff09; 的用户体验和性能。 相比传统的 <a> 标签跳转&#xff0c;Vue Router 提供了以下优势&#xff1a; 避免页面刷新&#xff1a; V…...

Three.js 快速入门教程【十】常见的纹理类型

系列文章目录 Three.js 快速入门教程【一】开启你的 3D Web 开发之旅 Three.js 快速入门教程【二】透视投影相机 Three.js 快速入门教程【三】渲染器 Three.js 快速入门教程【四】三维坐标系 Three.js 快速入门教程【五】动画渲染循环 Three.js 快速入门教程【六】相机控件 Or…...

文档识别-C#中英文文档识别接口-PDF文件内容识别API

文档识别接口可满足用户在数字化转型过程中对文档处理的高效、准确需求。翔云文档识别接口以成熟的文字识别技术、自然语言处理技术、图像识别技术为核心&#xff0c;能够将文档上的非可编辑文本转化为可编辑的数据&#xff0c;从而提升信息处理的速度与实现文档数字化管理的准…...

gRPG协议

gRPG协议是一种用于游戏开发的网络通信协议&#xff0c;全称为Game Real-time Protocol。它主要用于实现实时多人游戏中的数据传输和同步。gRPG协议的设计目标是提供低延迟、高可靠性的数据传输&#xff0c;以支持游戏中的实时互动和状态同步。 gRPG协议的特点 低延迟&#x…...

【maven打包错误】 无效的目标发行版:16

maven打包错误 错误截图 About 故事在一个风和日丽的下午&#xff0c;我一如往常的摸鱼&#xff0c;突如其来的事情打乱我的摸鱼节奏&#xff0c;“为什么测试不能用了” &#xff0c;随着前端帅哥一声轻咦&#xff0c;故事便开始了&#xff0c;我检查发现是是磁盘满了&#x…...

Oracle 查询表空间使用情况及收缩数据文件

本文介绍Oracle收缩数据文件的相关操作&#xff0c;运维工作中有时会需要通过收缩数据文件来释放磁盘空间。 数据文件初始化方式&#xff1a; 1.我们创建表空间一般有两种方式初始化其数据文件&#xff0c;即指定初始大小为32G&#xff08;很大的值&#xff09;或指定初始大小为…...

Transformer 代码剖析1 - 数据处理 (pytorch实现)

引言 Transformer 架构自《Attention Is All You Need》论文发表以来&#xff0c;在自然语言处理领域引起了巨大的变革。它摒弃了传统的循环结构&#xff0c;完全基于注意力机制&#xff0c;显著提高了处理序列数据的效率和性能。本文将通过对一个具体的项目代码结构进行详细分…...

Python异常处理面试题及参考答案

目录 什么是 Python 中的异常?程序为什么需要异常处理机制? 解释 BaseException 和 Exception 的区别 Python 的异常处理与传统的错误代码返回机制相比有哪些优势? 列出至少 5 个 Python 内置异常类型并说明触发场景 语法错误 (SyntaxError) 与运行时异常 (Runtime Erro…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...