十二、享元模式
文章目录
- 1 基本介绍
- 2 案例
- 2.1 Digit 接口
- 2.2 Color 枚举
- 2.3 BigDigit 类
- 2.4 DigitFactory 类
- 2.5 Client 类
- 2.6 Client 类的测试结果
- 2.7 总结
- 3 各角色之间的关系
- 3.1 角色
- 3.1.1 Flyweight ( 抽象享元 )
- 3.1.2 ConcreteFlyweight ( 具体享元 )
- 3.1.3 UnsharedFlyweight ( 非享元 )
- 3.1.4 FlyweightFactory ( 享元工厂 )
- 3.1.5 Client ( 客户端 )
- 3.2 类图
- 4 注意事项
- 5 在源码中的使用
- 6 优缺点
- 7 适用场景
- 8 总结
1 基本介绍
享元模式(Flyweight Pattern)是一种 结构型 设计模式,其核心思想是通过 共享某些对象 来 复用 它们,和单例模式的单例有相似之处——共享实例对象。
此处的翻译并非直译,中文和英文对应的含义如下:
- 对于中文 享元模式,“享元”实际上是“共享实例对象”的意思。
- 对于英文 Flyweight,Flyweight 的中文翻译是 蝇量级,这个概念原本是拳击比赛的一种重量级,用在此处表示这种模式可以使程序变得更“轻”,即 占用的内存更少。
2 案例
本案例实现了 打印不同颜色的大数字(虽然只有 3 种颜色、3 种大数字)。
2.1 Digit 接口
public interface Digit { // 数字接口void print(Color color); // 按照指定颜色打印对象中所存储的数
}
2.2 Color 枚举
public enum Color { // 颜色的枚举GREEN("\u001B[32m"), // 绿色BLUE("\u001B[34m"), // 蓝色PURPLE("\u001B[35m"); // 紫色Color(String colorStr) {this.colorStr = colorStr;}private String colorStr; // 保存颜色的字符串public String getColorStr() {return colorStr;}
}
2.3 BigDigit 类
import java.io.PrintStream;public class BigDigit implements Digit { // 大数字private String pattern; // 大数字的图像public BigDigit(int num) {switch (num) {case 1:pattern = DIGIT_1_PATTERN;break;case 2:pattern = DIGIT_2_PATTERN;break;case 3:pattern = DIGIT_3_PATTERN;break;default:pattern = "尚未实现,敬请期待!";}}// 按照指定的颜色打印大数字的图像@Overridepublic void print(Color color) {PrintStream defaultPrintStream = System.out; // 保存默认的打印流System.setOut(new ColoredDigitPrintStream(color)); // 将打印流更换为指定颜色的打印流System.out.println(pattern);System.setOut(defaultPrintStream); // 还原默认的打印流}private static final String DIGIT_1_PATTERN = """......................##..........######..............##..............##..............##..............##..........##########...................."""; // 大数字 1 的图像private static final String DIGIT_2_PATTERN = """....................######........##......##..............##..........####..........##............##..............##########...................."""; // 大数字 2 的图像private static final String DIGIT_3_PATTERN = """....................######........##......##..............##..........####................##......##......##........######......................"""; // 大数字 3 的图像private static class ColoredDigitPrintStream extends PrintStream { // 带有颜色的数字打印流private Color color; // 打印流的颜色public ColoredDigitPrintStream(Color color) {super(System.out);this.color = color;}@Overridepublic void println(String x) {super.println(this.color.getColorStr() + x + DEFAULT_COLOR);}private static final String DEFAULT_COLOR = "\u001B[0m"; // 默认的字符颜色}
}
2.4 DigitFactory 类
public class DigitFactory { // 数字的工厂// 数字池,存储 int 数 与 数字 的映射private static Map<Integer, Digit> digitPool = new HashMap<>();/*** 获取指定 int 数对应的数字* 注意本方法是 synchronized 的,防止多个线程同时创建多个共享实例,类似于单例模式** @param num 指定的 int 数* @return 返回指定 int 数对应的数字*/public synchronized static Digit getInstance(int num) {if (!digitPool.containsKey(num)) { // 如果 digitPool 中不存在 num 对应的数字digitPool.put(num, new BigDigit(num)); // 则创建新的大数字}return digitPool.get(num); // 返回 digitPool 中 num 对应的数字}
}
2.5 Client 类
public class Client { // 客户端,测试大数字的输出public static void main(String[] args) {// 可以通过 digit1 打印不同颜色的 1Digit digit1 = DigitFactory.getInstance(1);digit1.print(Color.BLUE);digit1.print(Color.PURPLE);Digit digit2 = DigitFactory.getInstance(2);digit2.print(Color.GREEN);Digit digit3 = DigitFactory.getInstance(3);digit3.print(Color.PURPLE);Digit digit3_1 = DigitFactory.getInstance(3);System.out.println(digit3 == digit3_1); // true,因为 digit3 和 digit3_1 是同一个对象}
}
2.6 Client 类的测试结果
注意:文章中无法显示大数字的颜色,可以自己在 IDEA 上运行一下,即可看到不同的颜色。
................
......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................
................
......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................
................
....######......
..##......##....
..........##....
......####......
....##..........
..##............
..##########....
................
................
....######......
..##......##....
..........##....
......####......
..........##....
..##......##....
....######......
................
true
2.7 总结
通过使用享元模式,减少了创建大数字对象的机会,从而降低了程序的内存占用;通过 Map
管理生成的实例,避免了多次 new
新对象耗费的时间。可谓是时间和空间上的双赢。
此外,认真观察大数字的两个“属性”:图像 和 颜色,可以发现:
- 图像是固定的,不论任何情况都不会改变,所以图像是 应当共享的信息,将其放到
BigDigit
中。 - 颜色不是固定的,随着
Client
需要的颜色而变化,所以颜色是 不应当共享的信息,将其放到其他类Color
中。
3 各角色之间的关系
3.1 角色
3.1.1 Flyweight ( 抽象享元 )
该角色负责 将 UnsharedFlyweight 角色作为参数,定义 ConcreteFlyweight 角色需要实现的方法。如果系统的功能很简单,则不需要该角色。本案例中,Digit
接口扮演该角色。
3.1.2 ConcreteFlyweight ( 具体享元 )
该角色负责 实现 Flyweight 角色定义的方法,定义可以共享的部分。本案例中,BigDigit
类扮演该角色。
3.1.3 UnsharedFlyweight ( 非享元 )
该角色负责 定义无法共享的部分,作为参数传入 Flyweight 角色定义的方法中。本案例中,Color
枚举扮演该角色。
3.1.4 FlyweightFactory ( 享元工厂 )
该角色负责 生成可共享的 Flyweight 角色,内部有一个 池 的字段来保存已生成的 Flyweight 实例,当传入相同的参数时,返回这些已有的实例。要注意 getInstance()
方法需要被 synchronized
关键字修饰,以保证线程安全。本案例中,DigitFactory
类扮演该角色。
3.1.5 Client ( 客户端 )
该角色负责 使用 FlyweightFactory 角色来生成 Flyweight 角色。本案例中,Client
类扮演该角色。
3.2 类图
说明:FlyweightFactory 角色的 pool
字段 和 getInstance()
方法都是 静态 的,使用了 简单(静态)工厂模式。
4 注意事项
- 划分外部状态和内部状态:正确划分 内部状态 和 外部状态 是享元模式应用的关键。
- 内部状态:指对象中 可以共享的信息,这部分信息 存储在享元对象内部,不会随环境的改变而改变。
- 外部状态:指对象中 不可共享的信息,这部分信息 在享元对象外部用新的对象来存储,随环境改变而改变,在方法调用时 以参数形式传入。
- 生成共享实例的工厂:享元模式中的类通常需要一个 工厂 来 控制对象的 创建 和 管理。当客户对象请求一个享元对象时,享元工厂会 先检查系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在,则创建一个新的享元对象。
- 线程安全问题:由于享元模式中的对象可能被多个线程下的客户端 共享,因此必须确保这些对象在并发环境下是线程安全的。这可能需要使用 同步机制 来 保护共享对象的内部状态。
- 性能考虑:虽然享元模式可以显著减少对象的创建和内存使用,但 读取外部状态 可能 会使运行时间稍微变长。在性能敏感的应用中,需要仔细评估这一点。
5 在源码中的使用
在 JDK 中的 Integer
类就使用了享元模式的思想,(如果不设置 VM 参数,则)为常用的 int
数(范围为 [-128, 127]
)提前初始化其对应的 Integer
对象。
在调用 Integer.valueOf()
时,如果传入的参数在 [-128, 127]
之内,则返回提前初始化的 Integer
对象;否则就为传入的参数初始化一个新的 Integer
对象。
Integer
类的部分代码如下所示:
// java.lang.Integer 类
public final class Integer extends ... implements ... {public static Integer valueOf(int i) { // 相当于 享元工厂 的 getInstance()// 如果 i 在范围 [low, high] 内,则直接返回提前初始化好的 Integer 对象if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}private static class IntegerCache { // Integer 的缓存static final int low = -128; // 最小的 int 数static final int high; // 最大的 int 数,可能由 VM 参数指定static final Integer[] cache; // 保持不变的常量池static Integer[] archivedCache; // archive 中的缓存static {// high 的值可能被 VM 参数所指定int h = 127;String integerCacheHighPropValue =VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {try {h = Math.max(parseInt(integerCacheHighPropValue), 127);// 缓存数组的最大长度是 Integer.MAX_VALUEh = Math.min(h, Integer.MAX_VALUE - (-low) -1);} catch( NumberFormatException nfe) {// 如果这个属性不能被解析成一个 int 数,则忽略这个异常}}high = h;// 如果可能的话,从 archive 中加载 IntegerCache.archivedCacheCDS.initializeFromArchive(IntegerCache.class); // 此方法是 native 方法int size = (high - low) + 1;// 如果 archive 缓存 存在 且 足够大,则使用它;否则构建新的缓存if (archivedCache == null || size > archivedCache.length) {// 将范围 [low, high] 内的 Integer 对象提前放入常量池Integer[] c = new Integer[size];int j = low;for(int i = 0; i < c.length; i++) {c[i] = new Integer(j++);}archivedCache = c;}cache = archivedCache;// 确保范围 [-128, 127] 内的 Integer 对象提前将其放入常量池assert IntegerCache.high >= 127;}private IntegerCache() {}}
}
说明:
Integer
类中 写一个静态内部类来创建共享的对象实例,这样可以避免给valueOf()
方法添加synchronized
修饰,因为 类的加载是线程安全 的,所以不可能生成两个相同值的Integer
共享实例。这种思想可以类比到 单例模式 的 静态内部类实现 中。- 在
Integer
类中:valueOf()
方法相当于 FlyweightFactory 角色的getInstance()
方法。IntegerCache.cache
相当于 FlyweightFactory 角色的pool
字段,用于存储已创建的共享实例。
Integer
类并没有完全使用享元模式,它只是提前初始化了部分高频使用的Integer
对象,将其共享,从而减少valueOf()
方法创建过多的对象,引发 内存溢出 问题。此外,这么做还可以减少构建共享对象所花费的时间,使Integer
类更加高效。
6 优缺点
优点:
- 减少内存消耗:享元模式通过 共享对象的内部状态 来 减少内存占用,从而避免为每个相似的对象都创建新的实例。
- 提高性能:由于 减少了对象的创建和销毁次数,享元模式可以 提高系统的性能。特别是在 频繁创建和销毁对象 的场景中,享元模式能够显著减少这些操作带来的开销。
- 降低系统复杂性:享元模式将对象的状态分为 内部状态 和 外部状态,使得系统更容易理解和维护。内部状态 由 享元对象 管理,外部状态 由 客户端 管理,这种分离 降低了系统的复杂性,并有效地 降低了对象间的耦合度。
缺点:
- 增加编程复杂性:实现享元模式需要将对象的状态分为 内部状态 和 外部状态,这要求开发者对系统的 状态管理 有深入的理解。同时,区分内部状态和外部状态可能会使代码逻辑变得复杂,增加编程的难度。
- 可能引入线程安全问题:如果多个线程同时访问和修改共享对象,可能会导致线程安全问题。因此,在使用享元模式时,需要特别注意线程安全的处理。
- 可能增加运行时开销:由于享元对象的 外部状态 是通过参数传递给享元对象的,这可能会增加运行时的开销。特别是在外部状态较多或频繁变化的情况下,这种开销可能会更加明显。
7 适用场景
- 相似对象的大量使用:当系统中存在大量相似对象,即这些对象只有少部分数据不同时,使用享元模式可以显著减少对象的数量,从而降低内存消耗。
- 对象具有许多共同属性:当对象具有许多 共同属性,而这些属性可以 被所有实例共享 时,使用享元模式可以避免在每个实例中重复存储这些属性,从而节省内存。
- 频繁创建和销毁对象:如果系统中频繁地创建和销毁大量对象,这会导致大量的内存分配和回收操作,从而降低系统的性能。使用享元模式可以减少对象的创建和销毁次数,从而提高性能。
- 需要快速响应时间的系统:在一些需要 快速响应时间 的系统中,如实时游戏、实时交易系统等,减少对象的创建和销毁时间 是非常重要的。享元模式可以通过减少对象的数量来降低这些操作的开销,从而提高系统的响应时间。
8 总结
享元模式 是一种 结构型 设计模式,其核心思想是通过 共享某些对象 来 复用 它们,和单例模式的单例有相似之处,可以减少 内存 和 时间 的消耗。
然而,在使用这种模式时不能随心所欲,共有三点需要特别考虑:
- 先明确对象的 外部状态 和 内部状态,然后将 内部状态 放到享元类中,使用享元工厂生产共享实例;将 外部状态 放到另外的类中,在调用共享实例的方法时将其传入。
- 由于享元模式可能应用到多线程的环境中,所以在工厂生成共享实例时需要 保证线程安全。
- 对于一个共享实例的多个引用,如果使用其中一个引用修改这个共享实例,那么会导致所有引用指向的实例都被修改,这也是共享的坏处之一,应该尽可能保证共享实例不会被修改。
相关文章:
十二、享元模式
文章目录 1 基本介绍2 案例2.1 Digit 接口2.2 Color 枚举2.3 BigDigit 类2.4 DigitFactory 类2.5 Client 类2.6 Client 类的测试结果2.7 总结 3 各角色之间的关系3.1 角色3.1.1 Flyweight ( 抽象享元 )3.1.2 ConcreteFlyweight ( 具体享元 )3.1.3 UnsharedFlyweight ( 非享元 )…...
Istio 金丝雀发布
转载:备考ICA-Istio 金丝雀实验4 环境清理 kubectl delete gw/helloworld-gateway vs/helloworld dr/helloworld-destination #测试 kubectl get svc,pods for i in {1..10};do curl $(kubectl get svc helloworld|grep helloworld|awk {print $3":"$5}|a…...
批发行业进销存-登录适配 android 横竖屏幕 源码CyberWinApp-SAAS 本地化及未来之窗行业应用跨平台架构
一、横竖屏切换的意义 以下是移动端横屏竖屏可切换在进销存中的一些重要应用: a、数据录入与查看 在录入商品信息、库存数量等大量数据时,横屏模式可以提供更宽阔的输入区域,减少输入错误。例如,在输入长串的商品编码或详细的商…...
Python进阶 JSON数据,pyecharts制图
目录 json数据格式的转换 什么是json json本质 注意 pyecharts快速入门 画一个最简单的折线图 使用全局配置选项优化折线图 总结 json数据格式的转换 什么是json 一种轻量级的数据交换格式,可以按json指定的格式去组织和封装数据 json本质 带有特定格式的…...
富士乐施5070-V打印机驱动安装
富士乐施5070-V打印机驱动安装 特指打印A3纸张需求,即驱动中能够选择纸张类型(安装选择305df驱动只能打印A4类型) 富士乐施打印机驱动下载网址: https://m3support-fb.fujifilm-fb.com.cn/driver_downloads/www/ 安装流程&…...
目标检测 | yolov4 原理和介绍
1. 简介 YOLOv4是一种高效且准确的目标检测模型,它在YOLOv3的基础上引入了多项改进,这些改进主要集中在网络结构的优化和训练技巧的更新上。以下是YOLOv4中的一些关键技术或模块,它们对提高目标检测性能起到了重要作用: CSPDarkne…...
扩散模型系列笔记(一)——DDPM
直观理解 扩散模型分为前向过程(扩散过程,Data → \to →Noise)和后向过程(生成过程或逆扩散过程,Noise → \to →Data)。在前向过程中,对于每一个观测样本,不断向样本中添加少量噪…...
【Nuxt】自定义插件和生命周期
自定义插件 方式一: app.vue // 创建插件(在app.vue中创建全局可以使用 而在某个页面中创建只有该页面可以使用) // 方式一: const nuxtApp useNuxtApp(); nuxtApp.provide("formDate", () > {return "2023-12-12"; }) nuxtAp…...
【算法】贪心算法
应用场景——集合覆盖问题 假设存在下面需要付费的广播台,以及广播台信号可以覆盖的地区。如何选择最少的广播台,让所有的地区都可以接收到信号 贪心算法介绍 1.贪心算法是指在对问题进行求解时,在每一步选择中都采取最好或者最优的选择 2…...
面试笔记 8.5
面试常见: Jvm,高并发,多线程,数据库,redis,框架 1.N I/O有什么核心组件 Java NIO 基本原理以及三大核心组件_java nio核心组件有哪些-CSDN博客 Buffer 缓冲 Channel 一对一 Channel 读取数据 Selector对应线程…...
redis面试(七)初识lua加锁脚本
redisson redisson如何来进行redis分布式锁实现的源码,基于redis实现各种各样的分布式锁的原理 https://redisson.org/ 这是官网 https://github.com/redisson/redisson/wiki/Table-of-Content 这是官方文档 开始 demo 建一个普通的工程在pom.xml里引入依赖 <…...
【mars3d】加载超图s3m模型说明
建议替换Cesium库,换成 超图版本Cesium mars3d mars3d-supermap ,需要引入的资源为: "mars3d": ["Cesium-supermap/Widgets/widgets.css", //超图版本Cesium "Cesium-supermap/Cesium.js","mars3d/plu…...
android音频录音,(三)MediaRecorder音频录音示例
1. apk触发录音启动或录音停止按键: public void onClick(View v) {switch (v.getId()) {case R.id.btn_Record: //启动录音startRecording();break;case R.id.btn_stop: //停止录音stopRecording();break;default:break;} }2. 创建MediaRecorder对象并初始化&…...
未授权访问漏洞(重点版─=≡Σ(((つ•̀ω•́)つ)
1.* Redis 搭建靶场环境: 进入目录:cd/vulhub-master/redis/4-unacc 启动:docker-compose up-d 检查:docker-compose ps vi docker-compose.yml //查看端口和版本号 安装redis工具 在kali上安装redis进行服务链接 #安装redis apt-get install redis #redi…...
数据中台之数据开发,数据开发概述与数据计算能力的类型
目录 一、数据开发概述 二、数据计算能力的类型 2.1 概述 2.2 批计算 2.2.1 概述 2.2.2 批计算模型 2.2.2.1 传统数据处理方案的问题 2.2.2.2 MapReduce模型 2.2.2.3 Spark框架 2.3 流计算 2.4 批流一体 2.5 在线查询 2.6 即席分析 一、数据开发概述 数据开发是数…...
免费的SD-WAN服务
SD-WAN,SASE,零信任是近年来比较火的概念,SD-WAN发展已经很久了,但是真正能够自主研发做SD-WAN的企业其实并不算太多。 比扬云的SD-WAN产品是自主研发的,可控性强,最重要的是具有免费版本,可以免…...
【C++】:错误处理机制 -- 异常
目录 前言一,C语言传统的处理错误的方式二,C异常的概念三,异常的使用3.1 异常的抛出和匹配原则3.2 在函数调用链中异常栈展开匹配原则3.3 异常的重新抛出3.4 异常规范 四,自定义异常体系五,异常的优缺点 点击跳转至文章…...
Cocos Creator2D游戏开发(10)-飞机大战(8)-计分和结束
现在游戏基本能完了, 飞机能发射子弹,打了敌机,敌机也能炸; 接下来要做计分了; 步骤: 搞出一个lable让lable显示炸了多少飞机 开搞: ①创建一个Lable标签 ② root.ts文件 添加 property(Label) player_score: Label; // 标签属性 标签绑定 ③ 代码添加 注册 然后回调 contac…...
image.convert()函数转换格式及显示图像的RGB三通道图像
引 言 视觉任务处理的图片按照图像通道深度分为单通道图像和多通道图像。单通道图像有grayscale灰度图、binary二值图、PNG图,多通道图像有三通道24位真彩色RGB图,8位伪彩色图像,YCbCr图像等。本文先介绍各种格式图像的特点,随后讲…...
进程学习
今天开始了进程的学习,主要讲了进程的一些命令以及进程的创建、进程的调度、进程相关的函数接口和进程消亡。在函数接口中要注意子进程和父进程的关系以及回收顺序,避免出现僵尸进程。...
【Rabbitmq的消息模型】
消息队列的特性 durable:队列持久化。如果设置持久化,那么无论RabbitMQ在关闭时,就会将队列存储到本地磁盘,无论宕机还是重启,队列也不会删除;如果设置不持久化,那么在RabbitMQ关闭时ÿ…...
The Ether: EvilScience (v1.0.1)打靶渗透【附代码】(权限提升)
靶机下载地址: https://www.vulnhub.com/entry/the-ether-evilscience-v101,212/ 1. 主机发现端口扫描目录扫描敏感信息获取 1.1. 主机发现 nmap -sn 192.168.7.0/24|grep -B 2 00:0C:29:7F:50:FB 1.2. 端口扫描 nmap -p- 192.168.7.172 1.3. 目录扫描 dirb http://192.16…...
java学习day18MyBatis2
MyBatis2 缺点 编写SQL语句工作量较大,对开发人员编写SQL语句的功底有一定的要求。 SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库 优点 MyBatis是免费且开源的。 与JDBC相比,减少了50%以上的代码量。 MyBat…...
算法巩固——旅行商问题
旅行商问题(Traveling Salesman Problem, TSP)简介 问题描述 旅行商问题是一个经典的组合优化问题,具体描述如下: 输入:一组城市及其两两之间的距离(或成本)。目标:找到一条从一个…...
ArcMap如何将shp数据导入oracle数据库
1. 连接数据库 2.在数据库中新建要素类 3.设置要素类名称和别名以及要素类型 4. 选择该要素类的坐标系 5.导入字段,点击导入,选择shp文件,点击添加,字段就导入进来了,点击完成 6. 点击刚才创建的要素类,点击…...
AppBoot:像 Django 一样使用 FastAPI
App Boot 开发 AppBoot 的背景是我一直没能寻找到满意的 FastAPI 项目模板。相比之下,Django 的项目结构和开发方式一直深得我心,因此我决定创建一个类似 Django 的 FastAPI 项目模板。 AppBoot 完全采用异步模式,内置 SQLAlchemy 2.0&…...
2024实验班选拔考试(热身赛)
比赛传送门 邀请码:2024wksyb A. 简单的数列问题 签到,记得开long long。 #include<bits/stdc.h> #define rep(i,a,b) for (int ia;i<b;i) #define per(i,a,b) for (int ia;i>b;--i) #define se second #define fi first #define endl …...
go语言的actor框架和air工具有什么区别?
Go语言的Actor框架和Air工具在多个方面存在显著的区别,主要体现在它们的设计目的、功能特性以及应用场景上。 ### Go语言的Actor框架 **设计目的与功能特性**: * **设计目的**:Actor框架是专为高并发和分布式系统设计的编程模型。它通过将系统…...
文件上传漏洞-HackBar使用
介绍 HackBar 是一个用于浏览器的扩展插件,主要用于进行网络渗透测试和安全评估。它提供了一系列方便的工具和功能,可以帮助用户执行各种网络攻击和测试,包括 XSS、SQL 注入、CSRF、路径穿越等 下载地址 可以到github上面去下载࿰…...
多层次算力网络;雾计算和边缘计算区别
目录 多层次算力网络 云计算 雾计算 边缘计算 海计算 相互协作 雾计算和边缘计算 一、概念与定义 二、目标与实现方式 三、应用场景 四、总结 多层次算力网络 涉及云计算、雾计算、边缘计算和海计算等技术之间的相互协作,这些技术各自具有不同的特点和覆盖范围,能…...
JavaDS —— 红黑树
前言 还是一样,这里的红黑树重点讲述插入代码的实现,如果对红黑树的删除感兴趣,可以去翻阅其他资料。 在数据结构专栏中已经对 AVL 树的旋转调整做了分析和讲解,这里红黑树也会使用到旋转调整的代码,就不讲述旋转代码…...
Python爬虫技术 第27节 API和RESTful服务
Python 爬虫技术是一种自动化获取网页内容的方法,通常用于数据收集、信息抽取或自动化测试。在讲解 Python 爬虫技术时,我们通常会涉及到以下几个关键概念: HTTP 请求:爬虫通过发送 HTTP 请求来获取网页内容,这是爬虫与…...
进程创建,进程消亡
虚拟地址:通过虚拟技术,将外部存储设备的一部分空间,划分给系统,作为在内存不足时临时用作数据缓存。当内存耗尽时,电脑就会自动调用硬盘来充当内存,以缓解内存的紧张。 练习: 编写一个代码实现,一个父…...
完美解决pip命令版本冲突导致对应版本模块包无法安装的问题
解决步骤 使用pip更新/降低指定模块包命令格式降低pip自身至指定版本的命令再次换源安装指定模块包 在对 FasterNet 这篇论文源码复现过程中,我们首先需要安装相关依赖文件( path/to/your/requirements.txt) -extra-index-url https://down…...
openssl 制作 信用库与服务证书
文章目录 前言openssl 制作 信用库与服务证书1. CA 证书2. 服务器证书/秘钥库3. 创建信用库4. 注意事项 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。 而且听说点赞的人每天的运气都不会…...
用Python打造精彩动画与视频,7.3 使用OpenCV在视频生成中的应用
第七章:高级视频和动画技术 7.3 使用OpenCV在视频生成中的应用 在本节中,我们将探索如何使用OpenCV进行一些基本的视频生成和增强技术。这些技术包括视频帧的叠加、视频剪辑、视频滤波等,通过这些技术可以提升视频的表现力。 7.3.1 素材准…...
记录一次Nacos安装启动异常的问题
今天在Linux中启动Nacos遇到了一个这样的错误: ERROR: Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! !! 解决办法: 1:查看JAVA_HOME配置: vi /etc/profile 2ÿ…...
.NET C# Dictionary Hashtable
.NET C# Dictionary & Hashtable 文章目录 .NET C# Dictionary & Hashtable1 Dictionary1.1 底层实现1.2 优点1.3 缺点 2 Hashtable2.1 底层实现2.2 优点2.3 缺点 3 对比总结4 遍历方式,与耗时对比foreach遍历Keys遍历IDictionaryEnumerator遍历耗时对比 1 …...
Spring Boot + Vue(4)授权查看信息
前言 在SpringBoot和Vue的组合中,实现一个查看商品详情信息需商品主人授权的功能,涉及到前后端的协作以及权限管理的设计。以下是一个基本的实现步骤和概念介绍: 一. 设计数据库模型 首先,你需要设计数据库模型来存储商品信息、用…...
面试经典 222. 完全二叉树的节点个数
二叉树我最近刷的特别多,差不多快刷完了,但是有一种题型差点给我忽略了,那就是完全二叉树,这也是一个很重要的题型,今天刚好有一道题目可以来复习一下完全二叉树的特性 题目链接如下:https://leetcode.cn/…...
基于springboot+vue+uniapp的“口腔助手”小程序
开发语言:Java框架:springbootuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包&#…...
Rider中修改默认文件关联,自定义打开方式
问题描述 想用Qt designer打开.ui文件,但是在Rider中,IDE会默认通过text进行打开 解决方法 1,允许用户将特定的文件类型与一个应用程序关联起来 File -> Settings -> Editor -> File Types -> Recognized File Types下&…...
【python】Linux升级版本
目的 迁移项目包路径到服务器上 查看服务器包是否和本地已有项目python版本相同然后发现~嗯不一样 项目上包时用的3.8~ 服务器用的2.7 查看方法: python -version解决方案 一:项目所有包重新下载 二:升级服务器python版本 第二种步骤&…...
CLOS架构
CLOS Networking CLOS Networking 是指使用 Clos 网络拓扑结构(Clos Network Topology)进行网络设计的一种方法。该方法是由贝尔实验室的工程师 Charles Clos 在1950年代提出的,以解决电路交换网络的可扩展性和性能问题。随着现代计算和网络…...
【HarmonyOS NEXT星河版开发学习】小型测试案例01-今日头条置顶练习
个人主页→VON 收录专栏→鸿蒙开发小型案例总结 基础语法部分会发布于github 和 gitee上面 前言 本系列可能是博客首发,鸿蒙开发星河版是一个全新的版本,由于参考视频较少鸿蒙开发不被重视导致csdn上面并没有全套的学习路线,…...
部署Springboot + Vue 项目到远程服务器Windows10系统的详细配置
远程服务器操作系统为Windows系统,Java程序环境,Maven环境都安装有,Mysql ,Redis等都有的前提下 1. mysql数据库导入,非常简单很好操作,这里省略。。比如用HeidiSql 或者Navicat 工具导入数据库 2. 后端javaSpringb…...
Linux笔记-3()
目录 一、Linuⅸ实操篇-定时任务调度 二、Linuⅸ实操篇-Linuⅸ磁盘分区、挂载 三、Linux实操篇-网络配置 一、Linuⅸ实操篇-定时任务调度 1 crond任务调度---crontab进行定时任务的设置1.1 概述任务调度:是指系统在某个时间执行的特定的命令或程序。任务调度分类…...
【深度学习】【语音】TTS,StyleTTS 2,论文
StyleTTS 2 是一款创新的文本转语音(TTS)模型,通过使用样式扩散和大规模语音语言模型(SLM)的对抗训练,实现了接近人类水平的TTS合成。以下是StyleTTS 2在技术上的几个关键点和其在性能上的突出表现: 技术重点 样式扩散(Style Diffusion): StyleTTS 2 将语音样式建模…...
C++中,vector、deque、list、set、multiset、unordered_set和unordered_multiset容器类的总结
最近用set比较多,复习一下基础。 在C中,vector、deque、list、set、multiset、unordered_set和unordered_multiset都是容器类,但它们有不同的特点和用途。下面是对它们的区别和示例说明: 1. vector 特点: 动态数组,…...
手机在网状态接口如何对接?(一)
一、什么是手机在网状态? 传入手机号码,查询该手机号的在网状态,返回内容有正常使用、停机、在网但不可用、不在网(销号/未启用/异常)、预销户等多种状态。 二、手机在网状态使用场景? 1.信贷审核&#…...