Redis学习其二(事务,SpringBoot整合,持久化RDB和AOF)

文章目录

  • 5,事务
    • 5.1Redis 事务不保证原子性的原因
    • 5.2事务操作过程
    • 5.3监控
  • 6,SpringBoot整合Redis
    • 6.1Redis客户端
      • 6.1.1Jedis简单使用
      • 6.1.2Lettuce&Jedis
    • 6.2配置相关
    • 6.3使用
      • 6.3.1使用RedisTemplate
      • 6.3.2Redis工具类
  • 7,持久化RDB
    • 7.1RDB持久化原理
    • 7.2触发机制
      • save命令
      • flushall命令
      • bgsave命令
    • 7.3优缺点
  • 8,持久化AOF
    • 8.1AOF持久化原理
    • 8.2相关配置
    • 8.3aof文件重写
    • 8.3优缺点

5,事务

Redis 事务虽然具备一次性、顺序性、排他性(即事务中的命令会按顺序执行,且执行期间不会被其他命令插入)。Redis的单条命令是保证原子性的,但是redis事务不能保证原子性。

Redis 事务的本质是一组命令的集合,其执行过程可概括为三个阶段:

  1. 开启事务MULTI):标记事务的开始,后续命令会被加入队列而非立即执行。
  2. 命令入队:所有输入的命令(如SETHSET等)会按顺序存入事务队列,等待执行。
  3. 执行事务EXEC):一次性执行队列中的所有命令,执行期间不会被其他客户端的命令干扰。

5.1Redis 事务不保证原子性的原因

原子性的核心是 “要么全部成功,要么全部失败”,但 Redis 事务不满足这一点:

  • 若命令语法错误(如命令不存在):在EXEC执行前,Redis 会检测到错误并拒绝执行事务,此时所有命令都不执行(类似 “全部失败”)。
  • 若命令逻辑错误(如对字符串执行INCR):EXEC会正常执行其他命令,错误命令仅自身失败,不会影响其他命令(即 “部分成功,部分失败”)。

例如:

MULTI
SET key1 "123"   // 成功
INCR key1        // 逻辑错误(字符串无法自增)
SET key2 "456"   // 成功
EXEC

执行后,key1key2都会被创建,仅INCR key1失败,事务并未回滚,因此不满足原子性。

5.2事务操作过程

  • 开启事务(multi
  • 命令入队
  • 执行事务(exec

所以事务中的命令在加入时都没有被执行,直到提交时才会开始执行(Exec)一次性完成。

127.0.0.1:6379> multi # 开启事务
OK
127.0.0.1:6379> set k1 v1 # 命令入队
QUEUED
127.0.0.1:6379> set k2 v2 # ..
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> keys *
QUEUED
127.0.0.1:6379> exec # 事务执行
1) OK
2) OK
3) "v1"
4) OK
5) 1) "k3"2) "k2"3) "k1"

取消事务(discurd)

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> DISCARD # 放弃事务
OK
127.0.0.1:6379> EXEC 
(error) ERR EXEC without MULTI # 当前未开启事务
127.0.0.1:6379> get k1 # 被放弃事务中命令并未执行
(nil)

事务错误

代码语法错误(编译时异常)所有的命令都不执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> error k1 # 这是一条语法错误命令
(error) ERR unknown command `error`, with args beginning with: `k1`, # 会报错但是不影响后续命令入队 
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors. # 执行报错
127.0.0.1:6379> get k1 
(nil) # 其他命令并没有被执行

代码逻辑错误 (运行时异常) **其他命令可以正常执行 ** >>> 所以不保证事务原子性

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> INCR k1 # 这条命令逻辑错误(对字符串进行增量)
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) ERR value is not an integer or out of range # 运行时报错
4) "v2" # 其他命令正常执行# 虽然中间有一条命令报错了,但是后面的指令依旧正常执行成功了。
# 所以说Redis单条指令保证原子性,但是Redis事务不能保证原子性。

5.3监控

悲观锁(Pessimistic Locking)

核心思想:总是假设最坏的情况,认为数据随时可能被其他线程修改,因此在访问数据前先加锁,确保只有自己能操作数据。

乐观锁(Optimistic Locking)

核心思想:假设数据一般不会被其他线程修改,因此不上锁,仅在更新数据时检查是否有人在此期间修改过(使用版本号进行检查)。

而Redis使用watch key监控指定数据,相当于乐观锁加锁。监控某一key后,如果key在一个线程/客户端A执行事务时,有另外一个客户端/线程B对key进行修改,则执行A的事务失败(全部失败)。

并且Redis 的 WATCH 是一次性的,且第二次事务没有重新执行 WATCH money

案例一:成功案例

客户端B在客户端A的事务期间执行(multi之后和exec之前)。

-------------客户端A--------------
127.0.0.1:6379[2]> set money 100
OK
127.0.0.1:6379[2]> set use 0
OK
127.0.0.1:6379[2]> watch money
OK
127.0.0.1:6379[2]> multi
OK
127.0.0.1:6379[2]> decrby money 20
QUEUED
127.0.0.1:6379[2]> incrby money 20
QUEUED
127.0.0.1:6379[2]> exec
(nil)
127.0.0.1:6379[2]> get money
"600"
127.0.0.1:6379[2]> get use
"0"
-------------客户端B--------------
127.0.0.1:6379[2]> incrby money 500
(integer) 600

案例二:失败案例

客户端B在客户端A的第二次事务期间执行(multi之后和exec之前)。这就是“Redis 的 WATCH 是一次性的,且第二次事务没有重新执行 WATCH money。”

-------------客户端A--------------
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set use 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby use 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
127.0.0.1:6379> get money
"80"
127.0.0.1:6379> get use
"20"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby use 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 560
2) (integer) 40
-------------客户端B--------------
127.0.0.1:6379> incrby money 500
(integer) 580

6,SpringBoot整合Redis

6.1Redis客户端

什么是客户端?在 Spring Boot 应用中,Redis 客户端是指用于连接和操作 Redis 数据库的工具库。spring-boot-starter-data-redis作为官方提供的启动器,默认集成了Lettuce作为 Redis 客户端。

6.1.1Jedis简单使用

使用Java来操作Redis,Jedis是Redis官方推荐使用的Java连接redis的客户端。

  1. 导入依赖

    <!--导入jredis的包-->
    <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version>
    </dependency>
    <!--fastjson-->
    <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.70</version>
    </dependency>
    
  2. 这里直接在springboot的测试类里测试了

    @SpringBootTest
    public class One {@Testpublic void test() {Jedis jedis = new Jedis("127.0.0.1", 6379);String pong = jedis.ping();System.out.println(pong);}@Testpublic void test2() {Jedis jedis = new Jedis("127.0.0.1", 6379);jedis.select(2);JSONObject jsonObject = new JSONObject();jsonObject.put("hello", "world");jsonObject.put("name", "Selena");// 开启事务Transaction multi = jedis.multi();String result = jsonObject.toJSONString();try {multi.set("user1", result);multi.set("user2", result);// 执行事务multi.exec();}catch (Exception e){// 放弃事务multi.discard();} finally {// 关闭连接System.out.println(jedis.get("user1"));System.out.println(jedis.get("user2"));jedis.close();}}
    }
    

6.1.2Lettuce&Jedis

在 Spring Boot 应用中,spring-boot-starter-data-redis默认使用 Lettuce 作为 Redis 客户端,因为其依赖中包含lettuce-core包。若要切换为 Jedis,需排除 Lettuce 并引入 Jedis 依赖。

特性LettuceJedis
连接模型基于 Netty 的响应式、非阻塞 I/O,支持异步和多路复用基于传统 BIO(阻塞 I/O),每次操作需新建连接
线程安全性线程安全,可多线程共享连接实例线程不安全,需通过连接池管理连接
资源消耗使用 Netty 事件循环,资源消耗少,适合长连接频繁创建 / 销毁连接,资源消耗大,依赖连接池降开销
功能特性支持响应式编程(Reactive Redis API)、集群和哨兵模式提供传统同步 API,适合简单业务场景
适用场景高并发、异步操作、响应式应用(如 Spring WebFlux)简单同步操作、传统 Servlet 应用

6.2配置相关

RedisProperties 是 Spring Boot 中用于配置 Redis 连接信息的核心配置类,位于 org.springframework.boot.autoconfigure.data.redis 包下。它通过 @ConfigurationProperties 注解绑定 spring.redis 前缀的配置项,让你可以在 application.propertiesapplication.yml 中轻松配置 Redis 连接参数。

此外,RedisAutoConfiguration这个类,顾名思义就是Redis的自动化配置。在这个类中,会引入LettuceConnectionConfiguration 和 JedisConnectionConfiguration 两个配置类,分别对应lettuce和jedis两个客户端。而这个两个类上都是用了ConditionalOnClass注解来进行判断是否加载。

而由于我们的项目自动引入了lettuce-core,而没有引入jedis相关依赖,所以LettuceConnectionConfiguration这个类的判断成立会被加载,而Jedis的判断不成立,所以不会加载。进而lettuce的配置生效,所以我们在使用的使用, 默认就是lettuce的客户端。

配置文件(基础配置):

server: # 服务器配置port: 8080servlet:context-path: /
spring:# redis 配置redis:# 地址host: localhost# 端口,默认为6379port: 6379# 数据库索引database: 0# 密码password:# 连接超时时间timeout: 10s

但是有的时候我们想要给我们的redis客户端配置上连接池。就像我们连接mysql的时候,也会配置连接池一样,目的就是增加对于数据连接的管理,提升访问的效率,也保证了对资源的合理利用。

如果使用的是jedis,就把lettuce换成jedis(同时要注意依赖也是要换的)。

spring:# redis 配置redis:# 地址host: localhost# 端口,默认为6379port: 6379# 数据库索引database: 0# 密码password:# 连接超时时间timeout: 10slettuce:pool:# 连接池中的最小空闲连接min-idle: 0# 连接池中的最大空闲连接max-idle: 8# 连接池的最大数据库连接数max-active: 8# #连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1ms

但是仅仅这在配置文件中加入,其实连接池是不会生效的。还少了最关键的一步,就是要导入一个依赖,不导入的话,这么配置也没有用。

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

之后,连接池才会生效。我们可以做一个对比。 在导包前后,观察RedisTemplate对象的值就可以看出来。

添加依赖前:
在这里插入图片描述

添加依赖后:

在这里插入图片描述

6.3使用

6.3.1使用RedisTemplate

简单案例:

@SpringBootTest
public class RedisTemplateTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testRedisTemplate1() {redisTemplate.opsForValue().set("name", "saber");}
}

在 Spring 的RedisTemplate中,opsForValue()是用于获取操作 Redis 字符串(String)类型数据的操作接口,通过它能执行一系列针对字符串的操作。除了opsForValue()外,RedisTemplate还提供了opsForHash()(操作哈希类型数据)、opsForList()(操作列表类型数据 )、opsForSet()(操作集合类型数据 )和opsForZSet()(操作有序集合类型数据)等方法,方便开发者针对不同的 Redis 数据类型进行操作。

拿opsForValue()举例,其常用方法

  • set(String key, Object value):将键值对存储到 Redis 中。如果对应的 key 已经存在,新值会覆盖旧值。
  • get(String key):根据给定的 key,从 Redis 中获取对应的字符串值,如果 key 不存在,则返回null
  • set(String key, Object value, long timeout, TimeUnit unit):存储键值对,并设置该键值对的过期时间。
  • increment(String key, long delta):对存储在 Redis 中的数字类型的 key 进行自增操作,delta表示自增的步长,返回自增后的值。若 key 不存在,会将其初始化为delta的值。
  • decrement(String key, long delta):对存储在 Redis 中的数字类型的 key 进行自减操作,delta表示自减的步长,返回自减后的值。

6.3.2Redis工具类

Redis工具类-CSDN博客

7,持久化RDB

7.1RDB持久化原理

RDB 是 Redis 默认的持久化方式,其核心机制是:

  • 定期执行:Redis 在指定时间间隔内(如 5 分钟),将内存中的数据快照保存为二进制文件(默认名为dump.rdb可以通过配置文件修改)。
  • fork 子进程:执行快照时,Redis 主进程会fork一个子进程,由子进程负责将数据写入磁盘,主进程继续处理客户端请求。
  • 全量复制:RDB 文件包含某一时刻 Redis 的全部数据,恢复时直接加载整个文件。

fork是操作系统提供的一个系统调用,用于创建一个与父进程几乎完全相同的子进程。RDB 持久化需要将内存中的全量数据写入磁盘,如果由主线程直接执行,会导致长时间阻塞(尤其数据量大时),影响 Redis 的响应性能。

在进行 RDB 的时候,redis 的主线程是不会做 io 操作的,主线程会 fork 一个子线程来完成该操作;

  1. Redis 调用forks。同时拥有父进程和子进程。
  2. 子进程将数据集写入到一个临时 RDB 文件中。
  3. 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益(因为是使用子进程进行写操作,而父进程依然可以接收来自客户端的请求。)

1,写时复制(Copy-On-Write):初始时,父子进程共享同一块物理内存;当父进程或子进程修改数据时,才会复制被修改的内存页,避免了全量复制的性能消耗。

2,什么是 “临时的 RDB 文件”?

在 RDB 持久化过程中,子进程并非直接写入最终的 RDB 文件(如默认的dump.rdb),而是先将内存数据写入一个临时文件(例如命名为temp-xxx.rdb)。

临时文件的作用是:

  • 保证数据完整性:如果子进程在写入过程中意外崩溃(如磁盘满、进程被 kill),临时文件会被丢弃,不会影响原有的 RDB 文件(原文件仍可用于恢复数据)。
  • 避免部分写入:如果直接写入目标文件,中途失败会导致目标文件损坏,而临时文件可确保只有当全量数据写入完成后,才会成为有效的 RDB 文件。

3,替换过程是怎样的?

当子进程成功将全量数据写入临时文件后,Redis 会执行原子性的文件替换操作

  1. 子进程完成写入后,通知主进程 “临时文件已就绪”。
  2. 主进程通过操作系统的rename(或类似)系统调用,将临时文件重命名为目标 RDB 文件名(如dump.rdb)。
    • 例如:temp-xxx.rdbdump.rdb
  3. 替换完成后,删除旧的dump.rdb文件(如果存在)。这意味着旧的数据会被新的数据覆盖。

7.2触发机制

  1. save的规则(配置文件中设值,在快照模块,如下)满足的情况下,会自动触发rdb原则
  2. 执行flushall命令,也会触发我们的rdb原则
  3. 退出redis,也会自动产生rdb文件

配置文件相关内容

# 当至少1个key被修改且时间超过900秒(15分钟)时,执行一次快照
save 900 1
# 当至少10个key被修改且时间超过300秒(5分钟)时,执行一次快照
save 300 10
# 当至少10000个key被修改且时间超过60秒时,执行一次快照
save 60 10000# RDB文件保存路径
dir ./# RDB文件名
dbfilename dump.rdb# 启用压缩(可能影响性能)
rdbcompression yes

save命令

使用 save 命令,会立刻对当前内存中的数据进行持久化 ,但是会阻塞,也就是不接受其他操作了;

由于 save 命令是同步命令,会占用Redis的主进程。若Redis数据非常多时,save命令执行速度会非常慢,阻塞所有客户端的请求。

flushall命令

flushall 命令也会触发持久化 ;

bgsave命令

bgsave 是异步进行,进行持久化的时候,redis 还可以将继续响应客户端请求 ;配置文件中的save规则本质上也是bgsave,异步执行数据持久化。
在这里插入图片描述

bgsave和save对比

命令savebgsave
IO类型同步异步
阻塞?是(阻塞发生在fock(),通常非常快)
复杂度O(n)O(n)
优点不会消耗额外的内存不阻塞客户端命令
缺点阻塞客户端命令需要fock子进程,消耗内存

7.3优缺点

优点:

  1. 适合大规模的数据恢复,相比AOF恢复速度快。
  2. 对数据的完整性要求不高

缺点:

  1. 需要一定的时间间隔进行操作,如果redis意外宕机了,这个最后一次修改的数据就没有了,破快数据完整性。
  2. fork进程的时候,会占用一定的内容空间。

8,持久化AOF

8.1AOF持久化原理

Append Only File

将我们所有的命令都记录下来,恢复的时候就把这个文件全部再执行一遍。

AOF 通过追加写命令到日志文件的方式实现持久化:

  1. 命令实时记录:Redis 执行写命令后,会将命令追加到 AOF 缓冲区(内存)。
  2. 缓冲区同步到磁盘:根据配置的同步策略(fsync),将缓冲区中的命令写入磁盘 AOF 文件。
  3. 文件重写(AOF Rewrite):定期通过BGREWRITEAOF命令对 AOF 文件进行瘦身,去除冗余命令。

8.2相关配置

如果要使用AOF,需要修改配置文件:

在这里插入图片描述

appendonly no yes则表示启用AOF

默认是不开启的,我们需要手动配置,然后重启redis,就可以生效了!

相关配置:

appendonly yes  # 默认是不开启aof模式的,默认是使用rdb方式持久化的,在大部分的情况下,rdb完全够用
appendfilename "appendonly.aof"# appendfsync always # 每次修改都会sync 消耗性能
appendfsync everysec # 每秒执行一次 sync 可能会丢失这一秒的数据
# appendfsync no # 不执行 sync ,这时候操作系统自己同步数据,速度最快# AOF文件重写触发条件
auto-aof-rewrite-percentage 100  # 当前AOF文件大小超过上次重写后大小的100%时触发
auto-aof-rewrite-min-size 64mb   # AOF文件最小达到64MB时才考虑重写

8.3aof文件重写

重写的作用:通过生成一个只包含当前数据库最新状态的 AOF 文件,替代旧文件,大幅减小文件体积。随着 Redis 运行,AOF 文件会不断追加写命令,导致文件体积膨胀,例如:对同一 key 多次修改(如SET k 1 → SET k 2 → SET k 3),旧命令变得冗余。就是舍去大量的中间状态,并记录当前数据库最新的状态。

触发方式

  1. 自动触发:当满足以下两个条件时,Redis 自动触发重写:

    auto-aof-rewrite-percentage 100  # 当前AOF文件大小超过上次重写后大小的100%
    auto-aof-rewrite-min-size 64mb   # AOF文件最小达到64MB才考虑重写
    
  2. 手动触发:执行命令:

    redis-cli BGREWRITEAOF
    

重写执行的流程。

  1. 主线程 fork 子进程
    • 主线程通过fork()创建子进程,子进程获得当前内存数据的副本。
    • 关键特性:写时复制(Copy-On-Write),父子进程共享内存,仅在修改数据时复制内存页,避免全量内存拷贝。
  2. 子进程生成新 AOF 文件
    • 子进程遍历内存中的所有键值对,生成对应的写命令序列(如SET k vHSET hash f v)。
    • 新 AOF 文件仅包含重建当前数据库所需的最小命令集,不包含任何冗余命令。
  3. 处理增量写命令
    • 在子进程重写期间,主线程继续处理客户端请求,并将新的写命令同时追加到:
      • 旧 AOF 文件:确保当前持久化过程不受影响。
      • AOF 重写缓冲区:保存重写期间的增量命令。
  4. 替换旧文件
    • 子进程完成重写后,向主线程发送信号。
    • 主线程将 AOF 重写缓冲区中的增量命令追加到新 AOF 文件中。
    • 主线程使用原子性的rename()系统调用,将新 AOF 文件替换旧文件。

8.3优缺点

优点

  1. 每一次修改都会同步,文件的完整性会更加好
  2. 每秒同步一次,可能会丢失一秒的数据
  3. 从不同步,效率最高

缺点

  1. 相对于数据文件来说,aof远远大于rdb,修复速度比rdb慢!
  2. Aof运行效率也要比rdb慢,所以我们redis默认的配置就是rdb持久化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/89366.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot项目部署到K8S

java后台 创建harbor镜像拉取Secret&#xff1a;kubectl create secret docker-registry harbor-regcred \--docker-server \ #harbor仓库地址--docker-username \ #harbor 账号--docker-password \ #harbor密码-n productionDockerfile FROM *harbor地址*/library/custom-jdk…

【FPGA开发】一文轻松入门Modelsim的基本操作

Modelsim仿真的步骤 &#xff08;1&#xff09;创建新的工程。 &#xff08;2&#xff09;在弹出的窗口中&#xff0c;确定项目名和工作路径&#xff0c;库保持为work不变(如有需要可以根据需求进行更改)。 &#xff08;3&#xff09;添加已经存在的文件&#xff08;rtl代码和t…

服务攻防-Java组件安全FastJson高版本JNDI不出网C3P0编码绕WAF写入文件CI链

服务攻防-Java组件安全&FastJson&高版本JNDI&不出网C3P0&编码绕WAF&写入文件CI链26天 原创 朝阳 Sec朝阳 2025年07月18日 09:23 湖北 标题已修改 演示环境&#xff1a; https://github.com/lemono0/FastJsonParty FastJson全版本Docker漏洞环境(涵盖1.…

【Python】DRF核心组件详解:Mixin与Generic视图

在 Django REST Framework (DRF) 中&#xff0c;mixins.CreateModelMixin、mixins.ListModelMixin、GenericAPIView 和 GenericViewSet 是构建 API 视图的核心组件。以下是对这些组件的主要方法及其职责的简要说明&#xff0c;内容清晰且结构化&#xff1a;1. mixins.CreateMod…

HTML+CSS+JS基础

文章目录&#xff08;一&#xff09;html1.常见标签&#xff08;1&#xff09;注释&#xff08;2&#xff09;标题 h1~h6&#xff08;3&#xff09;段落 p&#xff08;4&#xff09;换行与空格 br \ &#xff08;5&#xff09;格式化标签 b i s u&#xff08;6&#xff09;…

Vue导出Html为Word中包含图片在Microsoft Word显示异常问题

问题背景 碰到一个问题&#xff1a;将包含图片和SVG数学公式的HTML内容导出为Word文档时&#xff0c;将图片都转为ase64格式导出&#xff0c;在WPS Word中显示正常&#xff0c;但是在Microsoft Word中出现图片示异常。具体问题表现 WPS兼容性&#xff1a;在WPS中显示正常&#…

椭圆曲线密码学 Elliptic Curve Cryptography

密码学是研究在存在对抗行为的情况下还能安全通信的技术。即算法加密信息&#xff0c;再算法解密出信息。加密分为两类 1. Symmetric-key Encryption (secret key encryption) 即一种密钥&#xff0c;加密和解密使用同一密钥&#xff0c;可相互转换 2. Asymmetric-key Encry…

wedo牛-----第47节(免费分享图纸)

夸克网盘&#xff1a;https://pan.quark.cn/s/4b40a8d18979 高清图纸源文件&#xff0c;需要的请自取

Unity | AmplifyShaderEditor插件基础(第十集:噪声的种类+火焰制作-下)

目录 一、&#x1f44b;&#x1f3fb;前言 二、圆火焰 三、制作梯度 梯度成品预览 1.GradientSample节点 2.gradient的用法 3.time节点 四、添加颜色 Color节点 五、火焰摇摆 1.X方向的移动 2.Y方向的移动 3.Z方向的移动 4.把xyz组合起来 Panner节点 六、摆放和…

黑马Node.js全套入门教程,nodejs新教程含es6模块化+npm+express+webpack+promise等_ts对象笔记

1.1 什么是运行环境&#xff1f; 运行环境是指代码正常运行所需的必要环境&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; V8引擎负责解析和执行JavaScript代码。内置API是由运行环境提供的特殊接口&#xff0c;只能在所属的运行环境中被调用 1.2 JavaScrip…

React 项目环境变量使用指南

在 React 项目中正确使用环境变量是管理不同环境配置的关键技术。以下是完整的解决方案&#xff1a; 1. 创建环境变量文件 React 项目支持以下环境变量文件&#xff08;按优先级从高到低&#xff09;&#xff1a; .env.development.local (本地开发环境).env.development (开发…

Oracle 关于一些连接故障的总结

积累了几次Oracle客户端连接故障&#xff0c;做下总结。 文章目录1、案例案例1&#xff1a;客户端连接报错ORA-12514案例2&#xff1a;客户端连接报错ORA-28547案例3&#xff1a;客户端连接报错&#xff1a;Got minus one from a read call案例4&#xff1a;客户端连接报错&…

V-USB USB设备模拟原理分析

V-USB USB设备模拟原理分析 通过分析V-USB项目的核心文件&#xff0c;详细解释这个项目是如何在AVR微控制器上模拟USB设备的&#xff1a; 1. 整体架构 V-USB是一个纯软件实现的USB低速设备驱动&#xff0c;主要由以下几个核心文件组成&#xff1a; usbdrv.c : USB协议栈的C语言…

kafka3.6下载安装(传统架构/KRaft模式)+实例测试

知识补充&#xff1a; Kafka 和 ZooKeeper 的关系可以用 “协作依赖” 来概括。在 Kafka 的早期版本&#xff08;Kafka 2.8.0 之前&#xff09;中&#xff0c;ZooKeeper 是 Kafka 的核心依赖&#xff0c;用于管理集群元数据、协调 Broker 和 Controller 选举等关键功能。但从 …

华控智能产品特点——产品生态全景与场景化创新

公司构建 “3X”产品战略&#xff0c;以三大核心场景为基础持续拓展技术外延&#xff1a; 1. 智能安防产品线军工级指纹枪盒&#xff1a;采用6061-T6航空铝材&#xff0c;内嵌震动报警模块&#xff0c;非法开箱触发90dB警鸣。为军工企业定制的双人认证版本需两位授权人员同时验…

爬虫核心原理与入门技巧分析

一、爬虫核心原理&#xff1a;模拟人类浏览的“自动化工具” 简单来说&#xff0c;网络爬虫&#xff08;Web Crawler&#xff09;是一种按照一定规则&#xff0c;自动抓取互联网信息的程序或脚本。其核心原理可以类比人类浏览网页的过程&#xff0c;只不过将手动操作转化为了代…

spring-cloud微服务部署-feign服务间调用

1 准备工作 需要安装并启动nacos&#xff0c;作为服务注册中心。地址&#xff1a;https://nacos.io/ 2 项目结构 parent的pom.xml声明依赖&#xff1a; <dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</gr…

IDEA高效开发:Database Navigator插件安装与核心使用指南

目录 1.前言 2.正文 2.1安装流程 2.1.1IDE内部安装 2.1.2手动下载安装 ⚠️ 避坑指南 2.2使用教程 2.2.1连接数据库 2.2.2查看数据库/表 2.2.3查询数据 2.2.4修改表结构 2.2.5生成代码 2.2.6常见故障排除 3.小结 1.前言 “作为Java开发者&#xff0c;日常与数据…

Maven私服仓库,发布jar到私服仓库,依赖的版本号如何设置,规范是什么

Maven私服仓库&#xff0c;发布jar到私服仓库&#xff0c;依赖的版本号如何设置&#xff0c;规范是什么

量子卷积神经网络:量子计算与深度学习的融合革命

引言&#xff1a;当卷积神经网络遇上量子计算在人工智能与量子计算双重浪潮的交汇处&#xff0c;量子卷积神经网络&#xff08;Quantum Convolutional Neural Network, QCNN&#xff09;正成为突破经典算力瓶颈的关键技术。传统卷积神经网络&#xff08;CNN&#xff09;在图像识…