【再谈设计模式】享元模式~对象共享的优化妙手
一、引言
在软件开发过程中,我们常常面临着创建大量细粒度对象的情况,这可能会导致内存占用过高、性能下降等问题。享元模式(Flyweight Pattern)就像是一位空间管理大师,它能够在不影响功能的前提下,有效地减少对象的数量,从而优化系统资源的使用。
二、定义与描述
享元模式是一种结构型设计模式,它主要用于通过共享尽可能多的相似对象来减少内存使用和提高性能。其核心思想是将对象的状态分为内部状态(intrinsic state)和外部状态(extrinsic state)。内部状态是对象可共享的部分,它不会随环境的改变而改变;外部状态则是随环境变化而变化的部分,不能被共享。
三、抽象背景
假设我们正在开发一个游戏,游戏中有许多相同类型的怪物,这些怪物可能只有一些属性(如生命值、攻击力等)的差异。如果我们为每个怪物都创建一个独立的对象,那么随着怪物数量的增加,内存的消耗将变得非常大。享元模式就可以用来解决这个问题,将怪物的通用属性(如外观、基本行为等内部状态)进行共享,而将每个怪物特有的属性(如当前生命值、当前攻击力等外部状态)单独处理。
四、适用场景与现实问题解决
- 图形绘制系统
- 在图形绘制系统中,可能需要绘制大量相同类型的图形,如圆形、矩形等。这些图形的形状(内部状态)是固定的,但它们的位置、颜色(外部状态)可能不同。通过享元模式,可以共享图形的形状对象,减少内存占用。
- 文档编辑器中的字符处理
- 文档编辑器中有大量的字符,每个字符的字体样式、大小等属性可能不同,但字符的基本形状(内部状态)是相同的。享元模式可以用来共享字符的基本形状对象。
五、享元模式的现实生活的例子
- 汽车租赁公司
- 汽车租赁公司有多种类型的汽车可供租赁,如轿车、SUV等。每一种类型的汽车(内部状态)是固定的,包括车型、座位数等。而汽车的颜色、当前里程数(外部状态)是随每一次租赁而变化的。租赁公司可以将相同类型的汽车看作是享元对象,共享汽车的基本信息,从而更好地管理车辆资源。
- 咖啡店的咖啡杯
- 咖啡店有不同种类的咖啡杯,如拿铁杯、卡布奇诺杯等。杯子的形状(内部状态)是固定的,但是杯子里咖啡的量、是否加糖(外部状态)是不同的。咖啡店可以将相同类型的杯子看作享元对象,共享杯子的基本形状信息。
六、初衷与问题解决
初衷是为了减少内存中对象的数量,提高系统的性能和资源利用率。通过共享内部状态,避免了创建大量重复的对象,从而解决了因对象数量过多导致的内存占用过大和性能下降的问题。
七、代码示例
Java示例
类图:
FlyweightFactory
类有一个私有属性flyweights
(类型为Map<String, Flyweight>
)用于存储享元对象,并且有getFlyweight
方法,根据传入的key
来获取或创建具体的享元对象。Flyweight
是抽象类,有受保护的属性key
,构造方法以及抽象方法operation
,定义了享元对象的基本结构和行为规范。ConcreteFlyweight
类继承自Flyweight
类,实现了自己的构造方法,并覆写了operation
方法,用于提供具体的享元行为实现。
流程图:
首先创建 FlyweightFactory
对象,然后两次调用 getFlyweight
方法来获取享元对象(第二次调用时会复用第一次创建的对象,因为已经存在对应 key
的对象了),最后分别调用获取到的享元对象的 operation
方法来执行具体操作。
代码:
import java.util.HashMap;
import java.util.Map;// 享元工厂类
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);}
}// 抽象享元类
abstract class Flyweight {protected String key;public Flyweight(String key) {this.key = key;}abstract void operation();
}// 具体享元类
class ConcreteFlyweight extends Flyweight {public ConcreteFlyweight(String key) {super(key);}@Overridevoid operation() {System.out.println("具体享元 " + key + " 被调用");}
}public class Main {public static void main(String[] args) {FlyweightFactory factory = new FlyweightFactory();Flyweight flyweight1 = factory.getFlyweight("A");Flyweight flyweight2 = factory.getFlyweight("A");flyweight1.operation();flyweight2.operation();}
}
C++示例
#include <iostream>
#include <unordered_map>// 抽象享元类
class Flyweight {
public:virtual void operation() = 0;virtual ~Flyweight() {}
};// 具体享元类
class ConcreteFlyweight : public Flyweight {
private:std::string key;
public:ConcreteFlyweight(std::string key) : key(key) {}void operation() override {std::cout << "具体享元 " << key << " 被调用" << std::endl;}
};// 享元工厂类
class FlyweightFactory {
private:std::unordered_map<std::string, Flyweight*> flyweights;
public:Flyweight* getFlyweight(std::string key) {if (flyweights.find(key) == flyweights.end()) {flyweights[key] = new ConcreteFlyweight(key);}return flyweights[key];}~FlyweightFactory() {for (auto it : flyweights) {delete it.second;}}
};int main() {FlyweightFactory factory;Flyweight* flyweight1 = factory.getFlyweight("A");Flyweight* flyweight2 = factory.getFlyweight("A");flyweight1->operation();flyweight2->operation();return 0;
}
Python示例
class FlyweightFactory:def __init__(self):self.flyweights = {}def get_flyweight(self, key):if key not in self.flyweights:self.flyweights[key] = ConcreteFlyweight(key)return self.flyweights[key]class Flyweight:def __init__(self, key):self.key = keydef operation(self):passclass ConcreteFlyweight(Flyweight):def operation(self):print(f"具体享元 {self.key} 被调用")if __name__ == "__main__":factory = FlyweightFactory()flyweight1 = factory.get_flyweight("A")flyweight2 = factory.get_flyweight("A")flyweight1.operation()flyweight2.operation()
Go示例
package mainimport ("fmt"
)// 抽象享元接口
type Flyweight interface {operation()
}// 具体享元结构体
type ConcreteFlyweight struct {key string
}func (cf *ConcreteFlyweight) operation() {fmt.Printf("具体享元 %s 被调用\n", cf.key)
}// 享元工厂结构体
type FlyweightFactory struct {flyweights map[string]Flyweight
}func NewFlyweightFactory() *FlyweightFactory {return &FlyweightFactory{flyweights: make(map[string]Flyweight),}
}func (ff *FlyweightFactory) getFlyweight(key string) Flyweight {if _, ok := ff.flyweights[key];!ok {ff.flyweights[key] = &ConcreteFlyweight{key}}return ff.flyweights[key]
}func main() {factory := NewFlyweightFactory()flyweight1 := factory.getFlyweight("A")flyweight2 := factory.getFlyweight("A")flyweight1.operation()flyweight2.operation()
}
八、享元模式的优缺点
-
优点
- 减少内存占用:通过共享对象,大大减少了创建对象所需的内存空间,特别是在处理大量相似对象时效果显著。
- 提高性能:减少了对象的创建和销毁操作,从而提高了系统的运行速度。
- 易于维护:将对象的内部状态和外部状态分离,使得代码结构更加清晰,易于理解和维护。
-
缺点
- 增加复杂性:需要额外的代码来管理享元对象的创建、共享和维护,这可能会增加系统的复杂性。
- 外部状态管理:外部状态的处理需要额外的设计考虑,如果处理不当可能会导致逻辑混乱。
九、享元模式的升级版
一种常见的升级版是组合享元模式(Composite Flyweight Pattern)。在这种模式下,享元对象可以组合成更复杂的结构。例如,在图形绘制系统中,不仅可以共享单个图形(如圆形、矩形)的享元对象,还可以将这些享元对象组合成更复杂的图形(如由多个圆形和矩形组成的复杂图案),而这个复杂图案本身也可以作为一个享元对象被共享。这样可以进一步提高系统的灵活性和资源利用率。
思维导图:
相关文章:
【再谈设计模式】享元模式~对象共享的优化妙手
一、引言 在软件开发过程中,我们常常面临着创建大量细粒度对象的情况,这可能会导致内存占用过高、性能下降等问题。享元模式(Flyweight Pattern)就像是一位空间管理大师,它能够在不影响功能的前提下,有效地…...
NestJS中使用nestjs-plugin-module实现插件系统
1. 安装依赖 npm install brewww/nestjs-plugin-module2. 定义插件接口 首先,我们需要定义一个插件接口,这个接口定义了插件需要实现的方法。 hello/plugin.interface.ts export interface HelloServicePlugin {helloworld(): string;hello(name: st…...
jvm排查问题-实践追踪问题 与思路--堆内堆外内存泄漏排查方针
概述 排查问题的一般思路是:现象 ——> 直接原因 ——>根本原因。 从问题现象出发,可以分为 应用逻辑问题、资源使用问题、虚拟机异常: 应用逻辑可能导致报错增加、死锁、程序退出等;资源问题主要集中在CPU上升和内存上升(OOM Kill);虚拟机问题通常包括GC问题、进…...
Presence:Colyseus用于管理实时分布式数据的工具
Colyseus Presence 详细介绍 Presence 是 Colyseus 中用于管理实时分布式数据的一种工具。它主要用于在多房间、多服务器或分布式部署中实现玩家的实时在线状态、数据共享和通信。Presence 提供了一套简单的 API 来处理诸如在线玩家跟踪、分布式数据存储和发布/订阅模式等功能…...
梳理你的思路(从OOP到架构设计)_认识框架(Framework) 01
目录 1、 是框架的核心要素编辑&i> 范例1: 范例2: 范例3: 1、 <E&I>是框架的核心要素 在特定领域(Domain)里,将EIT造形的<E&I>部份有意义地组合起来,就成为框架(Framework)了。基本…...
【C++11】类型分类、引用折叠、完美转发
目录 一、类型分类 二、引用折叠 三、完美转发 一、类型分类 C11以后,进一步对类型进行了划分,右值被划分纯右值(pure value,简称prvalue)和将亡值 (expiring value,简称xvalue)。 纯右值是指那些字面值常量或求值结果相当于…...
字节跳动Java开发面试题及参考答案(数据结构算法-手撕面试题)
怎么判断两个链表是否相交?怎么优化? 判断两个链表是否相交可以采用多种方法。 一种方法是使用双指针。首先分别遍历两个链表,得到两个链表的长度。然后让长链表的指针先走两个链表长度差的步数。之后,同时移动两个链表的指针,每次比较两个指针是否指向相同的节点。如果指…...
科汛网校KesionEDU CheckOrder SQL注入漏洞复现
0x01 产品简介 科汛网校KesionEDU是KESION科汛开发的在线教育建站系统,支持在线直播教学、课程点播、录播授课等多种教学方式,满足不同场景下的教学需求。提供问答互动、学习点评、在线笔记等功能,增强学员与教师之间的互动交流。拥有在线考试系统,支持单选、多选、问答等…...
【ELK】ES单节点升级为集群模式--太细了!
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言准备工作1. 查看现状【单节点】2. 原节点改集群模式3. 改es配置文件,增加集群相关配置项4. *改docker映射的端口* 启动新节点5. docker-compose起一…...
Spring AOP是什么
目录 谈谈自己对于 AOP 的了解 Spring AOP 和 AspectJ AOP 有什么区别? AOP 常见的通知类型有哪些? 多个切面的执行顺序如何控制? 谈谈自己对于 AOP 的了解 AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑…...
Ch9 形态学图像处理
Ch9 形态学图像处理 blog点此处!<--------- 四大算子相应性质。 腐蚀、膨胀、开闭之间的含义、关系 文章目录 Ch9 形态学图像处理预备知识(Preliminaries)膨胀和腐蚀(Dilation and Erosion)腐蚀膨胀膨胀与腐蚀的对偶关系 开闭操作(Opening and Closing)开运算闭…...
epoll学习
epoll是1个服务端监听n个客户端的多路复用技术(通讯方式socket) epoll:(事件驱动)服务端通过管道通讯方式将有变化事件的客户端保存到1个队列 select/poll:(轮询驱动)服务端主动遍…...
《CS2》报错dxgi.dll缺失怎么办?《CS2》游戏提示dxgi.dll缺失要怎么解决?
一、dxgi.dll缺失的根源 游戏安装问题:dxgi.dll文件是DirectX图形接口的一部分,如果游戏安装不完整或安装过程中出现问题,可能会导致该文件缺失。 系统更新或配置变动:Windows操作系统的更新或某些系统配置的变动,有时…...
Python基础语法之元组
主页有列表,集合和字典的知识点(包含对应练习^V^) 关注我更新更多初学实例(下一个更新元组基础练习,然后集中更新一下C语言) 欢迎纠错 元组 一.元组的应用场景 思考:如果想要存储多个数据&am…...
如何实现 MySQL 的读写分离?
面试题 你们有没有做 MySQL 读写分离?如何实现 MySQL 的读写分离?MySQL 主从复制原理的是啥?如何解决 MySQL 主从同步的延时问题? 面试官心理分析 高并发这个阶段,肯定是需要做读写分离的,啥意思&#x…...
Vue.js框架:在线教育系统的安全性与稳定性
2.1系统开发使用的关键技术 本系统在开发中选择B/S框架进行设计,语言采用Java,数据库采用Mysql,并在设计中加入VUE.js技术,本系统的运行环境为Idea。 2.2 VUE.js技术介绍 VUE.js是一个用来开发前台界面的JavaScript框架࿰…...
[python SQLAlchemy数据库操作入门]-11.面向对象方式操作股票数据
哈喽,大家好,我是木头左! 通过ORM,开发者可以使用Python类来表示数据库表,从而使得数据库操作更加直观和易于维护。本文将介绍如何使用SQLAlchemy ORM来操作股票数据。 安装 SQLAlchemy 需要安装SQLAlchemy库。可以使用pip命令进行安装: pip install sqlalchemy定义股票…...
Windows 11 中利用 WSL - Linux 虚拟环境部署 ChatTTS-Enhanced 项目教程
#工作记录 在使用 Windows 系统尝试部署一些特定项目时,我们可能会遇到各种各样依赖包安装的问题。比如在 Windows 系统下,当我们想要在 Python 3.10 虚拟环境中,使用命令 “pip install resemble-enhance” 以及 “pip install WeTextProces…...
NPM老是无法install,timeout?npm install失败
NPM老是无法install,timeout? 尝试一下如下操作 一、 更换国内源 npm config set registry https://registry.npmmirror.com npm install或指定源install npm install pkg --registry https://registry.npmmirror.com --legacy-peer-deps如下图 二…...
音乐极客的新玩具:香橙派Zero3快速搭建Melody个人音乐平台
文章目录 前言1. 添加镜像源2. 本地部署Melody3. 本地访问与使用演示4. 安装内网穿透5. 配置Melody公网地址6. 配置固定公网地址 前言 今天要给喜欢听音乐的朋友们介绍一个超酷的DIY项目,在香橙派Zero3上使用Melody搭建自己的个人在线音乐平台,并且借助…...
springboot3版本结合knife4j生成接口文档
1.概述 knife4j官网为:介绍 | Knife4j (xiaominfo.com)https://doc.xiaominfo.com/docs/introduction 初步了解的码友可以初步了解一下官网的如下几个模块: 其中在快速开始模块中,不同的springboot版本都有一个使用的案例demo如下图位置&am…...
广州大彩串口屏安卓/linux触摸屏四路CVBS输入实现同时显示!
一、适用范围 适合广州大彩A40系列产品 产品型号: 二、概述 CVBS只需要一条线缆即可完成视频信号的传输,具有兼容性强、使用简单、成本低廉等优点。典型分辨率为720x480(NTSC制)或720x576(PAL制)。 三、…...
pikachu靶场搭建详细步骤
一、靶场下载 点我去下载 二、靶场安装 需要的环境: mysqlApaches(直接使用小皮面板Phpstudy:https://www.xp.cn/),启动他们 设置网站,把靶场的路径对应过来 对应数据库的信息 由于没有核对数据库的信…...
Astherus 联手 PancakeSwap 推出 asCAKE,CAKE 最大化收益的最优解?
Astherus 是本轮市场周期中最具创新性的 DeFi 协议之一,其通过推出 AstherusEx 以及 AstherusEarn 两个产品,正在基于真实收益启动 DeFi 市场的增长,并成为加密投资者捕获收益的最佳协议。PancakeSwap 是 BNB Chain 上最大的 DEX,…...
JVM实战—2.JVM内存设置与对象分配流转
大纲 1.JVM内存划分的原理细节 2.对象在JVM内存中如何分配如何流转 3.部署线上系统时如何设置JVM内存大小 4.如何设置JVM堆内存大小 5.如何设置JVM栈内存与永久代大小 6.问题汇总 1.JVM内存划分的原理细节 (1)背景引入 (2)大部分对象的存活周期都是极短的 (3)少数对象…...
无问社区-无问AI模型
无问AI模型是无问社区新上线的一款AI功能,支持文本图像的输入,在文本理解能力、推理能力、视觉能力上相较于“社区助手”有了很大的提升。 我们在预训练模型的技术上增加1.7亿token的训练数据进行强化训练使其具备更好的效果。 更好的消息是我们准备了…...
【记录】列表自动滚动轮播功能实现
目录 效果展示代码 效果展示 代码 <!-- 首页 --> <template><div class"page_body_item_body" mouseenter"stopScroll" mouseleave"scroll(false)"><ele-tableclass"eleTable":table-options"options"…...
前缀树介绍
数风流人物,还看今朝! 前缀树 Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补全和拼写检查。 前…...
Solon v3.0.5 发布!(Spring 可以退休了吗?)
Solon 框架! 新一代,面向全场景的 Java 应用开发框架。从零开始构建(非 java-ee 架构),有灵活的接口规范与开放生态。 追求: 更快、更小、更简单提倡: 克制、高效、开放、生态 有什么特点&am…...
基础组件:
基础组件: RichText 富文本组件,解析并显示HTML格式文本。 适用场景: RichText组件适用于加载与显示一段HTML字符串,且不需要对显示效果进行较多自定义的应用场景。RichText组件仅支持有限的通用属性和事件。具体见属性与事件…...
【LeetCode 面试经典150题】详细题解之滑动窗口篇
【LeetCode 面试经典150题】详细题解之滑动窗口篇 1 滑动窗口理论基础1.1 算法思想1.2 使用场景1.3 使用思路 2 209.长度最小的子数组2.1 题目分析2.2 算法步骤2.3 代码实现2.4 时间复杂度 3 3.无重复字符的最长字串3.1 题目分析3.2 算法步骤3.3 代码实现3.4 复杂度分析 4 30.串…...
【 CSS 】sass 扩展语言的安装
一、全局安装node-sass Sass世界上最成熟、稳定和强大的CSS扩展语言 | Sass中文网 https://www.npmjs.com/package/node-sass NPM镜像_NPM下载地址_NPM安装教程-阿里巴巴开源镜像站 注意:nodejs版本14以上,否则node-sass安装不成功 npm install -g mi…...
【Linux】Linux中用户信息相关的配置文件:/etc/passwd、/etc/group、/etc/shadow、/etc/sudoers
1 用户信息 1.1 /etc/passwd linux上用户的信息保存在/etc/passwd中,看文件名会以为这里保存的是用户密码,但实际上用户密码保存在另一个文件中。 /etc/passwd文件中每行保存一个用户的信息,例如: root:x:0:0:root:/root:/bin…...
electron-vite_18 设置系统音量loudness报错
loudness是一款控制系统音量输出的一款 Node.js 库;但是在electron-vite中直接使用编译的时候会报错;这个时候需要单独处理; 错误分析 error Error: spawn E:\xxx\out\main\adjust_get_current_system_volume_vista_plus.exe 查看编译后项目…...
springboot测试类里注入不成功且运行报错
目录 出错信息 原因 出错信息 写测试类的时候,一直说我注入不成功 而且我运行的时候报错了 java.lang.IllegalStateException: Unable to find a SpringBootConfiguration, you need to use ContextConfiguration or SpringBootTest(classes...) with your te…...
Harmony 网络请求
Http数据请求 axios第三方网络请求工具 1.下载ohpm 2.安装axios 3.使用axios...
Webpack在Vue CLI中的应用
webpack 作为目前最流行的项目打包工具,被广泛使用于项目的构建和开发过程中,其实说它是打包工具有点大材小用了,我个人认为它是一个集前端自动化、模块化、组件化于一体的可拓展系统,你可以根据自己的需要来进行一系列的配置和安…...
docker-componse集群部署Tdengine3.3.2.0
一、centos7.5集群部署三台机器使用docker-componse进行部署 1、三台服务器分别配置host vim /etc/hosts 192.168.13.244 td.master 192.168.13.245 td.slave1 192.168.12.70 td.slave2 2、...
4.3 数据库HAVING语句
having子句要和group by子句联合起来才能使用,不能单独去使用,接下来咱们看一下为什么要引入having子句语法呢?引入having子句也是出于无奈,因为有些条件查询,用group by子句并不能满足要求,比如说查询部门…...
如何使用React,透传各类组件能力/属性?
在23年的时候,我主要使用的框架还是Vue,当时写了一篇“如何二次封装一个Vue3组件库?”的文章,里面涉及了一些如何使用Vue透传组件能力的方法。在我24年接触React之后,我发现这种扩展组件能力的方式有一个专门的术语&am…...
C# 6.0版本的WebAPI接口部署到Linux服务器
将 C# 6.0 的 Web API 部署到 Linux 服务器涉及多个步骤,包括准备环境、构建和发布应用程序、配置 Web 服务器以及确保应用程序正常运行。以下是详细的部署指南: 1. 准备开发环境 安装 .NET SDK 确保你已经在本地开发环境中安装了 .NET SDK(…...
ArkTs组件(2)
一.下拉列表组件:Select 1.接口 Select(options: Array<SelectOption>) 参数名类型必填说明optionsArray<SelectOption>是设置下拉选项。 SelectOption对象说明 名称类型必填说明valueResourceStr是 下拉选项内容。 iconResourceStr否 下拉选项图片…...
Bash 脚本教程
注:本文为 “Bash 脚本编写” 相关文章合辑。 BASH 脚本编写教程 as good as well于 2017-08-04 22:04:28 发布 这里有个老 American 写的 BASH 脚本编写教程,非常不错,至少没接触过 BASH 的也能看懂! 建立一个脚本 Linux 中有…...
SQL创建和操纵表
本文介绍创建、更改和删除表的基本知识。 1. 创建表 SQL 不仅用于表数据操纵,而且还用来执行数据库和表的所有操作,包括表本身的创建和处理。一般有两种创建表的方法: 多数DBMS 都具有交互式创建和管理数据库表的工具;表也可以…...
1.微服务灰度发布(方案设计)
前言 微服务架构中的灰度发布(也称为金丝雀发布或渐进式发布)是一种在不影响现有用户的情况下,逐步将新版本的服务部署到生产环境的策略。通过灰度发布,你可以先将新版本的服务暴露给一小部分用户或特定的流量,观察其…...
QT笔记- QTreeView + QFileSystemModel 当前位置的保存与恢复 #选中 #保存当前索引
保存当前位置 QString currentPath model->filePath(view->currentIndex()); // 获得当前位置路径 恢复位置 view->setCurrentIndex(model->index(currentPath)); // 设置此路径所在位置为当前位置...
LeetCode - Google 校招100题 第6天 回溯法(Backtracking) (8题)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144743505 LeetCode 合计最常见的 112 题: 校招100题 第1天 链表(List) (19题)校招100题 第2天 树(Tree) (21题)校招100题 第3天 动态规划(DP) (20题)...
k8s,service如何找到容器
Kubernetes之所以需要Service,一方面是因为Pod的IP不是固定的,另一方面则是因为一组Pod实例之间总会有负载均衡的需求 被selector选中的Pod,就称为Service的Endpoints,查看方式: kubectl get endpoints hostnames需要…...
计算机的错误计算(一百九十二)
摘要 用两个大模型计算 csc(0.999), 其中,0.999是以弧度为单位的角度,结果保留5位有效数字。两个大模型均给出了 Python代码与答案。但是,答案是错误的。 例1. 计算 csc(0.999), 其中,0.999是以弧度为单位的角度,结…...
金仓数据库安装-Kingbase v9-centos
在很多年前有个项目用的金仓数据库,上线稳定后就没在这个项目了,只有公司的开发环境还在维护,已经好多年没有安装过了,重温一下金仓数据库安装,体验一下最新版本,也做一个新版本的试验环境; 一、…...