设计模式精讲 Day 11:享元模式(Flyweight Pattern)
【设计模式精讲 Day 11】享元模式(Flyweight Pattern)
文章内容
在软件开发过程中,我们常常需要处理大量相似对象的创建和管理问题。如果这些对象之间存在大量的重复信息,直接创建每一个对象会导致内存占用过高、系统性能下降。享元模式(Flyweight Pattern) 正是为了解决这类问题而提出的,它通过共享可复用的对象来减少内存开销,提升系统效率。
作为“设计模式精讲”系列的第11天,我们将深入讲解享元模式的核心思想、实现方式、适用场景以及实际应用案例。本篇文章面向Java开发工程师和架构师,结合理论与实践,帮助读者理解如何在项目中高效地使用该模式。
模式定义
享元模式是一种结构型设计模式,它通过共享对象来减少内存使用,提高系统性能。其核心思想是:将对象中可以共享的部分提取出来,作为共享对象;而无法共享的部分则作为外部状态,由客户端进行维护。
该模式适用于对象数量庞大且具有高度相似性的场景,特别适合用于图形界面、文本编辑器、游戏引擎等需要频繁创建和销毁对象的系统中。
模式结构
享元模式包含以下几个关键角色:
角色 | 职责 |
---|---|
Flyweight | 抽象接口,定义了享元对象的公共方法,包括内部状态和外部状态的处理。 |
ConcreteFlyweight | 实现Flyweight接口,负责存储内部状态,并可能提供对外部状态的访问方法。 |
UnsharedConcreteFlyweight | 非共享的具体享元类,用于存储不能共享的状态。 |
FlyweightFactory | 工厂类,负责创建和管理享元对象,确保相同内部状态的对象被共享。 |
UML类图描述(文字版)
Flyweight
是一个抽象类或接口,定义了operation()
方法。ConcreteFlyweight
实现了Flyweight
,并持有内部状态。UnsharedConcreteFlyweight
可选,用于处理不可共享的逻辑。FlyweightFactory
管理所有享元对象,根据内部状态返回对应的实例。
适用场景
享元模式最适合以下几种情况:
场景 | 说明 |
---|---|
大量相似对象 | 当系统中存在大量具有相同属性的对象时,可以通过共享减少内存消耗。 |
对象创建成本高 | 如果创建对象的代价较高,例如涉及数据库连接、文件读取等,共享可以降低资源消耗。 |
需要高性能 | 在图形渲染、游戏开发、文本处理等领域,频繁创建和销毁对象会影响性能,享元模式能有效优化。 |
实现方式
下面是一个基于Java的完整享元模式实现示例,模拟了一个简单的字符绘制系统,其中每个字符可以被多次复用。
// Flyweight 接口
interface Character {void draw(char c, int x, int y);
}// 具体享元类:表示可共享的字符
class ConcreteCharacter implements Character {private char character;public ConcreteCharacter(char c) {this.character = c;}@Overridepublic void draw(char c, int x, int y) {// 内部状态:字符本身System.out.println("Drawing character: " + character + " at (" + x + ", " + y + ")");}
}// 享元工厂类:负责管理享元对象
class CharacterFactory {private Map<Character, Character> characters = new HashMap<>();public Character getCharacter(char c) {if (!characters.containsKey(c)) {characters.put(c, new ConcreteCharacter(c));}return characters.get(c);}
}// 客户端代码
public class FlyweightDemo {public static void main(String[] args) {CharacterFactory factory = new CharacterFactory();// 绘制多个相同的字符,但只创建一次对象Character a = factory.getCharacter('A');a.draw('A', 10, 20);a.draw('A', 30, 40);Character b = factory.getCharacter('B');b.draw('B', 50, 60);b.draw('B', 70, 80);}
}
代码解释
ConcreteCharacter
是具体的享元类,存储了字符的内部状态(即字符本身)。CharacterFactory
是工厂类,负责根据字符生成享元对象,并确保相同字符只创建一次。- 在
main
方法中,我们通过工厂获取字符对象,并多次调用draw
方法,但实际上只创建了一次对象。
工作原理
享元模式的核心在于区分内部状态和外部状态:
- 内部状态:存储在享元对象中,是共享的,不随客户端变化。
- 外部状态:由客户端传递,是不可共享的,每次调用时可能不同。
通过这种方式,享元模式实现了对象的复用,避免了重复创建相同对象所带来的内存浪费。这种机制在处理大量数据或图形元素时尤其有效。
优缺点分析
优点 | 缺点 |
---|---|
减少内存占用,提升系统性能 | 增加了系统的复杂性,需要额外管理内部/外部状态 |
提高对象复用率,适用于大规模对象 | 不适合所有场景,如对象差异较大时效果不明显 |
易于扩展和维护 | 需要合理划分内部和外部状态,设计不当可能导致性能下降 |
案例分析
应用场景:文本编辑器中的字符渲染
在一个文本编辑器中,用户输入的每个字符都可能被多次显示(如复制粘贴、撤销重做等)。如果每个字符都单独创建对象,会占用大量内存。此时,我们可以使用享元模式优化:
- 内部状态:字符的字体、大小、颜色等属性。
- 外部状态:字符的位置、样式等由客户端控制。
通过享元模式,我们只需为每个不同的字符属性创建一次对象,即可在多个位置复用,大大减少了内存消耗。
解决方案
// 享元接口
interface TextElement {void render(int x, int y, String style);
}// 具体享元类:表示可共享的文本元素
class SharedTextElement implements TextElement {private String font;private int size;public SharedTextElement(String font, int size) {this.font = font;this.size = size;}@Overridepublic void render(int x, int y, String style) {System.out.println("Rendering text with font=" + font + ", size=" + size + ", style=" + style + " at (" + x + ", " + y + ")");}
}// 享元工厂类
class TextElementFactory {private Map<String, TextElement> elements = new HashMap<>();public TextElement getTextElement(String font, int size) {String key = font + "-" + size;if (!elements.containsKey(key)) {elements.put(key, new SharedTextElement(font, size));}return elements.get(key);}
}// 客户端代码
public class TextEditorDemo {public static void main(String[] args) {TextElementFactory factory = new TextElementFactory();TextElement a = factory.getTextElement("Arial", 12);a.render(10, 20, "bold");a.render(30, 40, "italic");TextElement b = factory.getTextElement("Times New Roman", 14);b.render(50, 60, "normal");b.render(70, 80, "underline");}
}
在这个例子中,SharedTextElement
表示可共享的文本元素,TextElementFactory
负责管理它们。通过这种方式,我们避免了为每个字符创建独立对象,从而提升了性能。
与其他模式的关系
享元模式常与以下模式结合使用:
模式 | 关系 |
---|---|
单例模式 | 享元模式中的享元对象通常可以使用单例模式来确保唯一性。 |
组合模式 | 在图形系统中,享元模式与组合模式结合使用,实现高效的图形树结构。 |
代理模式 | 享元对象可以作为代理,延迟加载或控制对真实对象的访问。 |
工厂模式 | 享元工厂类本质上是工厂模式的一种变体,负责创建和管理享元对象。 |
总结
本篇详细介绍了享元模式的核心思想、实现方式、适用场景以及实际应用案例。我们通过Java代码展示了如何构建一个完整的享元模式系统,并分析了其在文本编辑器等场景中的价值。
通过享元模式,我们可以有效地减少对象的创建次数,提升系统性能,特别是在处理大量相似对象时表现尤为突出。同时,我们也探讨了该模式与其他设计模式的协同作用,进一步拓展了其应用场景。
下一天我们将进入行为型模式的讲解,重点介绍责任链模式(Chain of Responsibility Pattern),敬请期待!
文章标签
design-patterns,flyweight-pattern,java-design-patterns,software-architecture,object-oriented-programming
文章简述
本文深入讲解了设计模式中的享元模式(Flyweight Pattern),通过理论与实践结合的方式,阐述了该模式的核心思想、实现方式及适用场景。文章提供了完整的Java代码示例,展示了如何通过共享对象减少内存消耗、提升系统性能。此外,还通过文本编辑器的案例分析,展示了享元模式在实际项目中的应用价值。最后,文章对比了该模式与其他设计模式的关系,并总结了其优缺点,帮助开发者更好地理解和应用该模式。
进一步学习资料
- Design Patterns: Elements of Reusable Object-Oriented Software
- Refactoring Guru - Flyweight Pattern
- Java Design Patterns - Flyweight Pattern
- Wikipedia - Flyweight Pattern
核心设计思想总结
本篇文章的核心设计思想是:通过共享对象减少内存占用,提升系统性能。在实际项目中,当我们遇到大量相似对象时,可以考虑使用享元模式,将对象中可共享的部分提取为享元对象,而将不可共享的部分作为外部状态处理。这不仅有助于节省内存资源,还能提升系统的整体性能。在后续开发中,建议结合具体业务场景,灵活运用享元模式,以达到最佳效果。
相关文章:
设计模式精讲 Day 11:享元模式(Flyweight Pattern)
【设计模式精讲 Day 11】享元模式(Flyweight Pattern) 文章内容 在软件开发过程中,我们常常需要处理大量相似对象的创建和管理问题。如果这些对象之间存在大量的重复信息,直接创建每一个对象会导致内存占用过高、系统性能下降。享…...
常用终端命令(Linux/macOS/bash 通用)分类速查表
文件与目录操作 命令作用说明pwd显示当前路径ls列出当前目录内容ls -l以列表形式显示文件详细信息ls -a显示所有文件(包括隐藏文件)cd <目录名>进入指定目录cd ..返回上一级目录cd ~回到用户主目录mkdir <目录名>创建目录mkdir -p a/b/c创建…...
Robyn高性能Web框架系列04:事件、中间件与错误处理
请求-响应过程 应用启动、关闭事件1、启动事件(Startup Events)2、关闭事件(Shutdown Events) 中间件1、前置中间件(BeforeRequest)2、后置中间件(AfterRequest)3、示例:…...
深入理解JavaScript设计模式之迭代器模式
文章目录 深入理解JavaScript设计模式之迭代器模式定义官方翻译白话翻译 实现jQuery中的each迭代器实现数组迭代器迭代器实现创建Dom元素 内部迭代器和外部迭代器内部迭代器外部迭代器 迭代类数组对象和字面量对象倒序迭代器中止迭代器迭代器的应用举例音乐播放器案例待输出更新…...
【项目管理】项目管理资料文档模板(ZIP,PPT,WORD)
项目交付文档 01项目详细调研计划编写规范V1.0.doc 03项目详细调研报告编写规范V1.0.doc 07软件需求规格说明书评审规范V1.0.doc 10.软件需求规格说明.doc 产品检查单,xls 工程评审.zip 软件标准过程集.zip 系统测试管理规程.docx 四)项目管理计划.doc 项目管理系统实施项目管理…...
DeepSeek中的提示库及其用法示例
《DEEPSEEK原生应用与智能体开发实践 图书》【摘要 书评 试读】- 京东图书 为了深入探索DeepSeek提示词样例的丰富内涵,充分挖掘其背后潜藏的无限可能,同时致力于为用户打造更为卓越、便捷且高效的使用体验,DeepSeek官网的API文档匠心独运地…...
292. Nim 游戏
292. Nim 游戏 - 力扣(LeetCode) 想法 枚举问题: n 1 ~ 3 ,由于我先手,我可以直接拿走全部的石头,所以我赢n 4,由于我先手,我拿掉 1 - 3 块石头 ,剩下的可能就是 1 -…...
STM32 串口通信②:蓝牙模块HC-05控制单片机
一 前言 上一篇我们已经成功实现单片机和电脑的连接,接下来,我们学习一个有趣的板块,HC-05蓝牙模块,这个蓝牙模块,我们就要建立手机和单片机的通讯啦,还是比较有趣的一个过程,大家可以跟着多操作…...
艾立泰数字化重塑汽车零部件包装租赁行业
在汽车零部件包装租赁行业,资产利用率低、流转效率差、运输成本高等痛点长期困扰企业。艾立泰科技通过数字化解决方案,成为该行业降本增效的关键合作伙伴,助力企业实现从传统管理模式向智能化的跃迁。 精准库存管理:告别“盲人摸…...
Windows电脑数据恢复终极指南:从原理到实战
Windows电脑数据恢复终极指南:从原理到实战 数据丢失是每个电脑用户都可能遭遇的噩梦。本文将为您全面解析Windows平台下的数据恢复技术,从基础原理到高级技巧,帮助您在文件误删、格式化、系统崩溃等情况下找回宝贵数据。 一、数据恢复基础…...
进入python虚拟环境的方法
首先,切换到虚拟环境所在的目录(即包含venv文件夹的目录): Cmd cd D:\phd\phd1spring\July\pythonstduy\projecton 然后,激活虚拟环境: Cmd .\venv\Scripts\activate 如果上述方法不行,还可…...
大数据时代UI前端的变革:从静态展示到动态交互
hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在大数据时代,信息以前所未有的速度和规模增长。这种数据环境的变化,深…...
海拔案例分享-门店业绩管理小程序
在各大电商平台和直播带货如火如荼来的当下,各行各业的门店都在积极寻求创新的管理方式,以提升业绩、优化运营。长沙的一家策划运营公司,敏锐地捕捉到这一市场需求,他们见过太多门店老板对着Excel表格叹气:美容店算错提…...
Python中的数据可视化:使用Matplotlib绘制图表
数据可视化是将复杂数据集转换为图形或图像表示的过程,旨在简化信息的解释和传达。Python作为一种多功能编程语言,提供了多种强大的库来实现这一目标,其中最受欢迎和广泛使用的是Matplotlib。 首先,我们需要确保已经安装了必要的…...
【VUE】1.准备工作
一、环境准备(本机仅需一次) 安装 Node.js(推荐 LTS 版本,包含 npm) 打开 VSCode,安装插件(推荐): Vetur 或 Volar(用于 Vue 支持) ESLint / Pr…...
Linux下的版本控制器Git(15)
文章目录 如何理解版本控制(9-0.00.00)Git 的理解Git 的历史具体操作和用法补充细节 简介:那个对Git的理解,是我用自己的话语结合故事进行阐述,可能理解的不到位,有些错误还请多多包含!说句实话…...
UI设计 | 审美积累 | 极繁风格(Maximalism / Complex UI)
如果极简追求“只保留必须的”,那极繁的设计思路就是“有条理地堆叠信息和情绪”。它不是无序的炫技,而是在秩序中有意识地填满视觉空间:字体层叠、图文混排、大量干扰信息并置,却又彼此克制。最终目标,是让用户在强信…...
MocapApi 中文文档 和github下载地址 NeuronDataReader(以下简称 NDR)的下一代编程接口
以下是 MocapApi 技术文档 github https://github.com/pnmocap/MocapApi?tabreadme-ov-file 国内可以查找getcode 英文文档 https://mocap-api.noitom.com/mocap_api_en.html 概述 MocapApi 是 NeuronDataReader(以下简称 NDR)的下一代编程接口&…...
c++面试题每日一学记录-C++类型转换
一、C++ 类型转换体系 C++ 提供 4 种命名转换操作符,比 C 风格转换更安全、意图更明确: 转换类型关键字主要用途安全检查静态转换static_cast相关类型转换(数值、类层次上行/下行)编译期动态转换dynamic_cast多态类型的安全下行转换运行时常量转换const_cast添加/移除 con…...
Maven 多模块项目调试与问题排查总结
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
【C#】C#异步编程:异步延时 vs 阻塞延时深度对比
文章目录 前言一、阻塞延时:Thread.Sleep1、 实现方式2、 工作原理3、 缺点 二、异步延时:Task.Delay1、 实现方式2、 工作原理3、 优点 三、深度对比四、实际应用示例对比1、 阻塞延时在UI应用中的问题2、 异步延时在UI应用中的正确用法3、 带取消功能的…...
c#实现halcon的rle编码blob分析
效果展示 实现功能 connection膨胀腐蚀开运算闭运算特征计算 核心代码 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Drawing; using System.Linq;namespace view3d {// 基础对象类,类似于 Halcon 的 HO…...
python基于微信小程序的广西文化传承系统
文章目录 具体实现截图本项目支持的技术路线源码获取详细视频演示:文章底部获取博主联系方式!!!!本系统开发思路进度安排及各阶段主要任务java类核心代码部分展示主要参考文献:源码获取/详细视频演示 ##项目…...
Apache Flink深度解析:现代流处理引擎
好的,我来帮您写一篇关于Flink技术的详细介绍博客: Apache Flink深度解析:现代流处理引擎 一、Flink简介 Apache Flink是一个开源的分布式流处理和批处理统一计算引擎。它提供了数据流上的状态计算、精确一次性语义保证、高吞吐、低延迟等特性,能够运行在所有常见的集群…...
跨平台后端编程ASP.NET CORE Razor新一代Web开发框架C#
asp.net core Razor动态语言编程代替asp.net .aspx更高级吗? https://blog.csdn.net/xiaoyao961/article/details/148846065 C#Blazor应用-跨平台WEB开发VB.NET-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148846437 Products.razor文件,Blazor和…...
【开源工具】一键解决使用代理后无法访问浏览器网页问题 - 基于PyQt5的智能代理开关工具开发全攻略
🌐【开源工具】一键解决使用代理后无法访问浏览器网页问题 - 基于PyQt5的智能代理开关工具开发全攻略 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代…...
uniapp安卓GPIO电平控制
模块简介 本模块为 UniApp 提供了对 Android 系统下 GPIO 的访问能力,支持导出、设置方向、读写电平值等操作。适用于 Android 架构设备(如 RK3288 平台)。 支持功能 功能方法名说明初始化 GPIO 方向initGpio({gpio, direction})设置 GPIO…...
苹果芯片macOS安装版Homebrew(亲测)
在Linux服务器上安装一个软件常用yum,apt、dnf命令,同样macOS可以使用brew命令来安装软件。 brew会自动帮你下载、解压、安装和配置,更重要的是:它还会自动处理好软件之间的依赖关系,它将所有软件都安装在独立的统一目…...
vue | vue-macros 插件升级以及配置
Vue Macros 是一个为 Vue.js 提供更多宏和语法糖的开源项目vue-macros/vue-macros: Explore and extend more macros and syntax sugar to Vue. 问题:npm run build-only 打包时,报错:[Vue] Load plugin failed: vue-macros/volar 排查发现…...
计算机网络:(六)超详细讲解数据链路层 (附带图谱表格更好对比理解)
计算机网络:(六)超详细讲解数据链路层 前言一、数据链路层1. 数据链路层是什么?2. 哪些设备需要数据链路层?3. 数据链路层如何工作?4. 数据链路层的俩种信道4.1 点对点信道:一对一4.2 广播信道&…...
智能生成分析报告系统在危化安全生产监测预警评估中的应用
一、引言 在危险化学品安全生产监管中,传统的分析报告依赖人工整理与审核,效率低、响应慢,且极易受到主观判断、格式不规范、不同地区掌握尺度不一致的影响。而随着工业互联网、大数据、人工智能(AI)特别是大语言模型…...
微算法科技(NASDAQ:MLGO)研发可信共识算法TCA,解决区块链微服务中的数据一致性与安全挑战
随着区块链技术的不断演进和应用场景的拓展,微服务架构因其灵活性、可扩展性以及易于维护的特点,逐渐成为了构建复杂系统的首选架构模式。如何在微服务架构中有效应用区块链技术,确保数据的一致性和安全性,成为了一个亟待解决的问…...
UE5 开发遇到的bug整理
文章目录 一、人物在挂载某个Actor之后,移动有问题,可能是Actor类的碰撞没有关闭,和人物自身发生了碰撞。 一、人物在挂载某个Actor之后,移动有问题,可能是Actor类的碰撞没有关闭,和人物自身发生了碰撞。...
单片机——浮点数转换4位数码管显示
浮点数转换4位数码管显示 static char buffer[5]; int DecimalPlace 0; #define HideChar h void DisplayFloatOn4LED(float value) {long integer roundf(value );if (integer > 9999) //4位{integer 9999;snprintf(buffer, sizeof(buffer), "%4ld", integer…...
广东省专升本英语形容词与副词全梳理
一、形容词核心知识详解 (一)形容词的构成方式(附记忆技巧) 1. 后缀派生法(9 大核心后缀) ① -ly 结尾形容词(易混副词,重点记忆) ✅ 特点:虽以 - ly 结尾…...
GeoServer和GeoTools XML外部实体注入漏洞(CVE-2025-30220)
免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。 对于因不当使用本文信息而造成的任何直…...
Python Django全功能框架开发秘籍
本文在创作过程中借助 AI 工具辅助资料整理与内容优化。图片来源网络。 文章目录 引言一、Django 简介1.1 Django 的诞生与背景1.2 Django 的特点概述 二、Django 的核心特性2.1 ORM 特性2.1.1 ORM 原理与优势2.1.2 ORM 在实际应用中的优势 2.2 模板引擎2.2.1 模板引擎的工作机…...
四核 A53+工业级存储:移远 SC200L 与 pSLC SD NAND 如何重构 T-BOX 性能边界?
博客目录 一、移远 SC200L:T-BOX 的 “智慧大脑”二、米客方德 MKDN064GIL-ZA T-BOX:数据安全的坚固堡垒三、深度协同:拓展 T-BOX 应用边界 在车联网浪潮席卷而来的当下,T-BOX 作为汽车与外界交互的核心枢纽,其性能优劣…...
docker方式启动Jenkins
docker方式启动Jenkins 1.启动命令 我已经打包好了文件,如下命令即可启动 docker run -d -v jenkins_home:/var/jenkins_home -p 8088:8080 -p 50000:50000 --restarton-failure registry.cn-hangzhou.aliyuncs.com/devops_de/jenkins:lts-jdk17 还需要设置一下目录权限,要…...
【目标检测】图像处理基础:像素、分辨率与图像格式解析
🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...
国产免费的k8s管理平台
xkube是一款永久免费且无任何功能限制的k8s集群管理平台,提供PC端和移动端全平台支持,具备完善的集群管理、运维监控和CI/CD发布功能,让企业轻松实现跨集群的统一管理和自动化运维。 技术特点: 1、xkube是一款国产永久免费的k8s…...
火山引擎大模型未来发展趋势
用户可能正在做技术选型或者行业研究,需要预测火山引擎在激烈竞争中的突围方向。从问题简洁性看,ta可能已经有一定基础认知,不需要我从零科普大模型概念。 火山引擎作为字节跳动的技术输出平台,优势在于背靠抖音、今日头条等超级应…...
Java基础(三):逻辑运算符详解
Java基础系列文章 Java基础(一):发展史、技术体系与JDK环境配置详解 Java基础(二):八种基本数据类型详解 Java基础(三):逻辑运算符详解 目录 一、什么是逻辑运算符?二、基础逻辑运算符(3种)1、&&…...
设计模式 | 单例模式
单例模式(Singleton Pattern) 是设计模式中最简单却最常用的模式之一,它确保一个类只有一个实例,并提供全局访问点。本文将深入探讨单例模式的核心思想、实现技巧以及在C中的多种实现方式。 为什么需要单例模式? 在软…...
SQL_Server 基本语法
1.创建数据库 use master go if exists(select * from sysdatabases where nameCourseManageDB) drop database CourseManageDB go --创建数据库 create database CourseManageDB on primary (--数据库的逻辑文件名(就是系统用的,必须唯一)…...
剑指offer39_连续子数组的最大和
连续子数组的最大和 输入一个 非空 整型数组,数组里的数可能为正,也可能为负。 数组中一个或连续的多个整数组成一个子数组。 求所有子数组的和的最大值。 要求时间复杂度为 O ( n ) O(n) O(n)。 数据范围 数组长度 [ 1 , 1000 ] [1,1000] [1,100…...
SPL 实践系列:跨库移植 SQL
背景 应用程序可能要基于不同数据库工作,各种数据库的 SQL 语法大体一致,但仍有些差别,结果就要改造这些 SQL,而这事通常只能手工调整,工作量大还容易出错。 完全自动改造 SQL 几乎是无法做到的,毕竟各种…...
docker启动的rabbitmq搭建并集群和高可用
Docker 搭建 RabbitMQ 集群步骤 以下是使用 Docker 快速搭建 RabbitMQ 集群的详细步骤,包含配置文件、网络设置和集群组建过程。 1. 创建自定义网络 首先创建一个 Docker 网络,使容器间可以通过名称互相访问: docker network create rabb…...
ISCSI存储
ISCSI存储 一、iscsi简介 1. 基本概念 iSCSI(Internet Small Computer System Interface)即互联网小型计算机系统接口,它是一种基于 TCP/IP 协议的存储网络协议,将传统的 SCSI(Small Computer System Interface&…...
算法与数据结构:动态规划DP
文章目录 动态规划算法全面解析一、核心思想与基本概念二、动态规划与其他算法的区别三、动态规划的解题步骤四、经典案例解析1. **斐波那契数列(Fibonacci)**2. **0-1背包问题(0-1 Knapsack)**3. **最长公共子序列(LC…...