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

Redis 在电商秒杀场景中的应用

Redis 在电商秒杀场景中的应用

  • 一、简介
    • 1.1 简介
    • 1.2 场景应用
  • 二、Redis 优势与挑战
    • 2.1 优势
    • 2.2 秒杀场景的挑战
  • 三、应用场景分析
    • 3.1 库存预热
      • 代码示例
    • 3.2 分布式锁
    • 3.3 消息队列
  • 四、系统设计方案
    • 4.1 架构设计
    • 4.2 技术选型
    • 4.3 数据结构设计
  • 五、Redis 性能优化
    • 5.1 集群部署
      • 5.1.1 Redis Sentinel
      • 5.1.2 Redis Cluster
    • 5.2 缓存策略
      • 5.2.1 本地缓存
      • 5.2.2 分布式缓存
    • 5.3 流量控制

一、简介

1.1 简介

在电商平台的特定时期,如双十一、618等节日或促销活动,会有大量用户涌入该平台进行购物。其中,秒杀场景是用户数量最多的,因为消费者可在限定的时间内获得极具性价比的产品和服务。

举例来说,假设某电商平台推出了一款新品,原价为100元。但在秒杀期间,只需要支付10元便可购买该产品,而且该产品总共只有100件。那么这样的秒杀场景既能提高消费者的购买积极性,也能解决商家库存问题。

1.2 场景应用

Redis是一个基于内存的缓存数据库(In-memory data structure store),拥有快速响应和高并发等优点。在电商秒杀场景中,Redis作为数据库或缓存,发挥着极其重要的作用:

  1. 读写能力强:Redis支持多种数据类型操作,并且数据的存储和读取都非常迅速。在秒杀场景中,用户的访问需要在几毫秒内完成,否则用户就会离开。Redis的快速响应能力保证了用户能够顺利地完成秒杀操作。

  2. 分布式锁:在秒杀活动中,如果两个用户同时竞买同一件商品,将会产生资源竞争问题。为了解决这个问题,需要采用分布式锁机制来控制并发,保证数据的完整性和准确性。Redis提供了多种分布式锁的实现方案,使得开发人员在秒杀场景中等高并发下能够更精准、高效地处理业务。

二、Redis 优势与挑战

2.1 优势

  1. 快速读写:Redis的内存读写速度非常快,特别适合对单条数据进行频繁读写的情况,更是秒杀场景中所需的。

  2. 高并发:Redis拥有良好的并发支持,对于增删改查这样频繁地路由请求而言,Redis可以应对秒杀中的高并发访问。

  3. 数据类型多样:Redis支持多种数据类型,如字符串、哈希、集合、有序集合和列表等。在处理复杂的秒杀逻辑时,这些数据类型能显著提升其效率。

2.2 秒杀场景的挑战

  1. 容量不足:由于Redis使用内存来存储缓存,容量较小,可能无法容纳全部数据。

  2. 数据一致性问题:秒杀场景中,如果两个用户同时竞买同一件商品,需要使用分布式锁来解决竞争问题。而使用分布式锁可能会引起数据不一致的问题,需要在设计方案时考虑处理。

  3. 系统可用性问题:在电商秒杀场景中,系统的可用性非常重要。如果Redis服务器宕机或出现其他意外情况,会导致许多的秒杀请求失败,给用户和商家带来交易上的损失。因此,需要采取多种手段,如数据备份、灾备和监控等,保护系统稳定运行。

三、应用场景分析

3.1 库存预热

在一些特定的电商促销活动中,为了避免在秒杀开始时由于读取数据库等操作造成的系统延迟等问题,可以使用 Redis 对库存进行预热。

代码示例

public class StockPreheating {private static final String HOST = "127.0.0.1";private static final int PORT = 6379;public static void main(String[] args) {// 连接 RedisJedis jedis = new Jedis(HOST, PORT);// 设置预热初始值int stockNum = 100000;String key = "stock";jedis.set(key, String.valueOf(stockNum));// 循环生成商品预热缓存for(int i=1; i<=100000; i++){String skuKey = "sku:" + i;jedis.set(skuKey, "stock");}// 关闭 Redis 连接jedis.close();}
}

说明:
以上示例代码中,我们通过 Jedis Java 客户端连接到 Redis,并使用循环生成商品预热缓存,最后关闭 Redis 连接。

3.2 分布式锁

使用 Redis 的分布式锁可以解决分布式环境下的共享资源互斥问题。常用于秒杀、抢购等高并发场景中。

public class DistributedLock {private static final String HOST = "127.0.0.1";private static final int PORT = 6379;private static Jedis jedis = new Jedis(HOST, PORT);/*** 加锁操作* @param key 要加锁的键名* @param value 键值,在释放锁时需要校验* @param expireTime 锁过期时间,防止死锁* @return 是否加锁成功*/public static boolean lock(String key, String value, int expireTime) {// nx:key不存在时才进行设置,保证锁是互斥的// ex:键值设置后,经过 expireTime 秒自动过期释放锁,避免产生死锁return "OK".equals(jedis.set(key, value, "NX", "EX", expireTime));}/*** 解锁操作* @param key 要加锁的键名* @param value 键值,在加锁时设置的值* @return 是否解锁成功*/public static boolean unlock(String key, String value) {// lua 脚本:先判断键值是否与 value 相等,如果相等则删除 key 并返回 true,否则返回 falseString script ="if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +"then\n" +"    return redis.call(\"del\",KEYS[1])\n" +"else\n" +"    return 0\n" +"end";Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value));return Long.parseLong(result.toString()) == 1;}
}

说明:
以上示例代码中,我们实现了 Redis 的加锁和解锁操作,并配合 Lua 脚本实现了多个命令的原子性,保证了加锁和解锁的一致性。

3.3 消息队列

使用 Redis 可以方便地实现消息队列,对于需要异步处理和业务解耦的场景非常有用。

public class MessageQueue {private static final String HOST = "127.0.0.1";private static final int PORT = 6379;private static Jedis jedis = new Jedis(HOST, PORT);/*** 发布订阅,实现消息队列* @param channel 订阅频道名* @param message 消息内容*/public static void sendMessage(String channel, String message) {jedis.publish(channel, message);}/*** 消息订阅者* @param channel 订阅频道名* @param listener 消息接收监听器*/public static void subscribe(String channel, JedisPubSub listener) {jedis.subscribe(listener, channel);}
}

说明:
以上示例代码中,我们实现了 Redis 的发布订阅消息队列功能,并通过 JedisPubSub 接口进行消息接收监听,实现了消费者消息异步接收处理。

四、系统设计方案

4.1 架构设计

本电商秒杀系统采用分布式架构,包含以下组件:

  • 前端负载均衡器:将用户请求均匀地分发到不同的Web服务器上,使用Nginx负责实现。
  • 应用服务器:接收用户请求并处理,使用Java + Spring Boot框架实现。
  • Redis服务器:作为主要的数据存储和缓存介质,使用单机或集群模式均可。
  • 数据库服务器:保存订单信息等长期存储的数据,使用MySQL数据库。

4.2 技术选型

  • Web服务器:Nginx
  • 后端框架:Spring Boot
  • 数据库:MySQL
  • 缓存:Redis

4.3 数据结构设计

为了保证秒杀活动的效率和可靠性,需要采用以下数据结构来支持系统的运行:

  • 商品库存队列:使用Redis的List结构来保存活动商品的库存数量,每次有人秒杀成功后,将库存队列中的商品数量减1。
  • 用户请求队列:使用Redis的List结构保存用户请求信息,每次请求进来后都先放入请求队列中,再由后台系统取出处理。如果请求队列过长,则说明系统可能已经无法处理更多的请求,需要返回秒杀失败的提示。

下面是Java代码实现:

// 库存队列操作
public class StockQueue {private static final String STOCK_QUEUE_KEY = "stock_queue";// 添加库存数量public static void addStock(int num) {RedisTemplate<String, Integer> redisTemplate = getRedisTemplate();redisTemplate.opsForList().rightPush(STOCK_QUEUE_KEY, num);}// 减少库存数量public static boolean reduceStock() {RedisTemplate<String, Integer> redisTemplate = getRedisTemplate();Long stockNum = redisTemplate.opsForList().leftPop(STOCK_QUEUE_KEY);if (stockNum == null || stockNum <= 0) {return false;}return true;}// 获取当前库存数量public static int getCurrentStock() {RedisTemplate<String, Integer> redisTemplate = getRedisTemplate();List<Integer> stockList = redisTemplate.opsForList().range(STOCK_QUEUE_KEY, 0, -1);int totalStock = 0;for (Integer num : stockList) {totalStock += num;}return totalStock;}private static RedisTemplate<String, Integer> getRedisTemplate() {// 配置Redis连接等操作return redisTemplate;}
}// 用户请求队列操作
public class RequestQueue {private static final String REQUEST_QUEUE_KEY = "request_queue";// 将用户请求添加到队列中public static void addRequest(String request) {RedisTemplate<String, String> redisTemplate = getRedisTemplate();redisTemplate.opsForList().rightPush(REQUEST_QUEUE_KEY, request);}// 从队列中获取一个请求进行处理public static String getRequest() {RedisTemplate<String, String> redisTemplate = getRedisTemplate();String request = redisTemplate.opsForList().leftPop(REQUEST_QUEUE_KEY);return request;}private static RedisTemplate<String, String> getRedisTemplate() {// 配置Redis连接等操作return redisTemplate;}
}

五、Redis 性能优化

5.1 集群部署

5.1.1 Redis Sentinel

Redis Sentinel 是 Redis 官方提供的高可用解决方案。它通过选举一个主节点以及多个备份节点的方式,实现了 Redis 服务的自动切换和故障恢复。在生产环境中建议使用 Redis Sentinel 来保证 Redis 服务的高可用性。

5.1.2 Redis Cluster

Redis Cluster 也是 Redis 官方提供的高可用解决方案。与 Redis Sentinel 不同的是,Redis Cluster 主要是通过分片来实现数据的自动平衡和故障恢复。它提供了强大的横向扩展能力,能够支持更大规模的数据存储和高并发访问。

5.2 缓存策略

5.2.1 本地缓存

本地缓存是指应用程序直接将数据存储在本地内存中,以加快数据的读取速度。应该注意的是,本地缓存一般只适用于数据量较小、相对固定且不怎么变化的情况下。当数据量过大或者经常变化时,本地缓存很容易引起内存溢出等问题。

代码示例:

// 使用 HashMap 作为本地缓存
private static Map<String, Object> localCache = new HashMap<>();public static Object getData(String key) {Object value = localCache.get(key);if (value != null) {return value;}// 从数据库中获取数据value = getDataFromDB(key);if (value != null) {localCache.put(key, value);}return value;
}

5.2.2 分布式缓存

分布式缓存是指将数据缓存在多个服务器节点上,以提高数据的读取速度和可用性。相比于本地缓存,分布式缓存具有更好的扩展性和容错性,能够适应大数据量和高并发访问的场景。

常见的分布式缓存方案包括 Memcached 和 Redis。其中 Redis 的性能和功能都要优于 Memcached,所以在选择分布式缓存方案时建议选择 Redis。

使用 Redis 进行分布式缓存代码示例:

// 创建 JedisPool 对象,用于连接 Redis
JedisPool jedisPool = new JedisPool("localhost", 6379);public static Object getData(String key) {try (Jedis jedis = jedisPool.getResource()) {// 尝试从 Redis 中获取数据byte[] value = jedis.get(key.getBytes());if (value != null) {// 如果存在则直接返回return deserialize(value);} else {// 否则从数据库中获取Object data = getDataFromDB(key);if (data != null) {// 并写入 Redis 中byte[] bytes = serialize(data);jedis.set(key.getBytes(), bytes);}return data;}}
}

5.3 流量控制

流量控制是指对系统中的请求和响应进行限制,以避免因高并发访问而造成系统崩溃或服务不可用。常用的流量控制方案包括限流和熔断。

限流是指通过设置各种限制条件,对请求进行限制的一种方式。常见的限流方式包括漏桶算法、令牌桶算法等。

熔断是指当系统出现故障或异常时,立即切断上游请求或降级处理的一种方式。在使用熔断技术时需要关注熔断恢复、熔断点、熔断时间等问题。

以下是 Java 使用 Google Guava 包进行的限流和熔断的代码示例:

// 创建 RateLimiter 对象,每秒最多处理 100 个请求
private static RateLimiter rateLimiter = RateLimiter.create(100);public static void processRequest(Request request) {if (!rateLimiter.tryAcquire()) {// 请求被拒绝,返回错误信息throw new RuntimeException("系统繁忙,请稍后再试!");}// 处理请求// ...
}// 使用 CircuitBreaker 进行熔断,最多允许出现 3 次错误
private static CircuitBreaker circuitBreaker = CircuitBreaker.create("circuitBreaker", CircuitBreakerConfig.custom().failureRateThreshold(50).ringBufferSizeInClosedState(3).waitDurationInOpenState(Duration.ofMillis(1000)).build());public static Object getData(String key) {try {// 尝试执行业务逻辑circuitBreaker.decorateSupplier(() -> getDataFromDB(key)).get();} catch (Exception e) {// 出现故障或异常,进行降级处理return fallback();}// 处理数据// ...
}

相关文章:

Redis 在电商秒杀场景中的应用

Redis 在电商秒杀场景中的应用 一、简介1.1 简介1.2 场景应用 二、Redis 优势与挑战2.1 优势2.2 秒杀场景的挑战 三、应用场景分析3.1 库存预热代码示例 3.2 分布式锁3.3 消息队列 四、系统设计方案4.1 架构设计4.2 技术选型4.3 数据结构设计 五、Redis 性能优化5.1 集群部署5.…...

大麦订单生成器 大麦一键生成订单

后台一键生成链接&#xff0c;独立后台管理 教程&#xff1a;修改数据库config/Conn.php 不会可以看源码里有教程 下载源码程序&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3...

Java实现Google cloud storage 文件上传,Google oss

storage 控制台位置 创建一个bucket 点进bucket里面&#xff0c;权限配置里&#xff0c;公开访问&#xff0c;在互联网上公开&#xff0c;需要配置角色权限 新增一个访问权限 &#xff0c;账号这里可以模糊搜索&#xff0c; 角色配置 给allUser配置俩角色就可以出现 在互联…...

适配器模式(AdapterPattern)

适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式&#xff0c;它结合了两个独立接口的功能。 优缺点 优点&#xff1a; 单一职责原则。你可以将接口或数据转换代码从程序主要业务逻辑中分…...

Apache Kafka Learning

目录 一、Kafka 1、Message Queue是什么&#xff1f; 2、Kafka 基础架构 3、Kafka安装 4、Offset自动控制 5、Acks & Retries 6、幂等性 7、事务控制 8、数据同步机制 9、Kafka-Eagle 二、Maven项目测试 1、Topic API 2、生产者&消费者 一、Kafka Kafka是…...

手把手教你用idea实现Java连接MySQL数据库

目录 1.下载MySQL 2.下载mysql 的jdbc驱动 3.将驱动jar包导入idea 4.通过Java测试数据库是否连接成功 1.下载MySQL 首先如果没有mysql的需要先下载MySQL&#xff0c;可以看这个教程 MYSQL安装手把手&#xff08;亲测好用&#xff09;_程序小象的博客-CSDN博客 2.下载mysql…...

Ubuntu 22.04安装和使用ROS1可行吗

可行。 测试结果 ROS1可以一直使用下去的&#xff0c;这一点不用担心。Ubuntu会一直维护的。 简要介绍 Debian发行版^_^ AI&#xff1a;在Ubuntu 22.04上安装ROS1是可行的&#xff0c;但需要注意ROS1对Ubuntu的支持只到20.04。因此&#xff0c;如果要在22.04上安装ROS1&am…...

83 | Python可视化篇 —— Bokeh数据可视化

Bokeh 是一种交互式数据可视化库,它可以在 Python 中使用。它的设计目标是提供一个简单、灵活和强大的方式来创建现代数据可视化,同时保持良好的性能。Bokeh 支持多种图表类型,包括线图、散点图、柱状图、饼图、区域图、热力图等。此外,它还支持将这些图表组合在一起以创建…...

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection (arXiv 2018)

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection - 密集目标检测中的焦点损失&#xff08;arXiv 2018&#xff09; 摘要1. 引言2. 相关工作References 声明&#xff1a;此翻译仅为个人学习记录 文章信息 标题&#xff1a;RetinaNet: Focal Loss for Dense Obje…...

MySQL 与MongoDB区别

一、什么是MongoDB呢 ? MongoDB 是由C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。在高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB 将数据存储为一…...

Kaggle First Place Winner Solution Study——多变量回归问题

本期分享一个Kaggle上playground系列多变量回归问题的第一名解决方案。试着分析、复现、学习一下金牌选手的数据分析思路。 赛题链接&#xff1a; Prediction of Wild Blueberry Yield | Kagglehttps://www.kaggle.com/competitions/playground-series-s3e14第一名解决方案链…...

分布式应用:Zookeeper 集群与kafka 集群部署

目录 一、理论 1.Zookeeper 2.部署 Zookeeper 集群 3.消息队列 4.Kafka 5.部署 kafka 集群 6.FilebeatKafkaELK 二、实验 1.Zookeeper 集群部署 2.kafka集群部署 3.FilebeatKafkaELK 三、问题 1.解压文件异常 2.kafka集群建立失败 3.启动 filebeat报错 4.VIM报错…...

Last-Mile Embodied Visual Navigation 论文阅读

论文阅读 题目&#xff1a;Last-Mile Embodied Visual Navigation 作者&#xff1a;JustinWasserman, Karmesh Yadav 来源&#xff1a;CoRL 时间&#xff1a;2023 代码地址&#xff1a;https://jbwasse2.github.io/portfolio/SLING Abstract 现实的长期任务&#xff08;例如…...

thunder gbm

文章目录 背景参考官网信息训练调参模型保存推理 背景 想在 GPU 上使用使用闪电般快速的提升方法&#xff1f;了解这个库就好了。在很多任务上&#xff0c;它都比 LightGBM 和 XGBoost 快。 ThunderGBM 的主要特征如下&#xff1a; 通常是其它库的 10 倍。 支持 Python&#x…...

数据结构--单链表

前言 上一章&#xff0c;我们讲了数据结构--动态顺序表&#xff0c;我们会发现有以下问题&#xff1a; 1.当我们要头部或者插入或删除时&#xff0c;都需要进行位置挪动&#xff0c;腾出某一个位置&#xff0c;时间复杂度为0(N)&#xff1b; 2.增容需要申请新空间&#xff0c;…...

过程:从虚拟机上添加 git 并成功提交到 GitLab 的全过程

Ⅰ、准备工作&#xff1a; 1、Git 查看&#xff1a; 其一、命令&#xff1a;git --version // 此时就能在虚拟机环境下看到 git 的版本为: git version 2.41.0 其二、如何在虚拟机上安装 git &#xff1a; A、命令 &#xff1a; sudo apt-get install git B、然后再输入虚…...

机器学习笔记之优化算法(九)收敛速度的简单认识

机器学习笔记之优化算法——收敛速度的简单认识 引言收敛速度的判别标准 Q \mathcal Q Q-收敛速度 R \mathcal R R-收敛速度关于算法复杂度与收敛速度 引言 本节对收敛速度简单介绍。 收敛速度的判别标准 我们之前几节介绍了线搜索方法 ( Line Search Method ) (\text{Line …...

FPGA学习——Altera IP核调用之PLL篇

文章目录 一、IP核1.1 IP核简介1.2 FPGA中IP核的分类1.3 IP核的缺陷 二、PLL简介2.1 什么是PLL2.2 PLL结构图2.3 C4开发板上PLL的位置 三、IP核调用步骤四、编写测试代码五、总结 一、IP核 1.1 IP核简介 IP核&#xff08;知识产权核&#xff09;&#xff0c;是在集成电路的可…...

经纬度坐标工具

LngLatUtil :用于计算里程数 import cn.hutool.core.util.ArrayUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.Getter; import lombok.Setter;import java.io.FileInputStream; import java.io.Serializable; import java.t…...

如何使用伪元素::before和::after?

伪元素(::before和::after)是CSS中非常有用的特性&#xff0c;它们允许你在元素的内容之前或之后插入额外的内容&#xff0c;并且不需要在HTML结构中添加额外的标记。这样可以方便地在页面上添加装饰性元素、图标、或者样式效果。以下是使用伪元素的基本方法&#xff1a; 1、创…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...