Redis - 6 ( 9000 字 Redis 入门级教程 )

news2025/1/8 4:34:15

一:Redis Java 集成到 Spring Boot

1.1 使用 Spring Boot 连接 Redis 单机

  1. 在创建项目时,勾选 NoSQL 分类下的 Spring Data Redis,同时勾选 Web 分类下的 Spring Web。这样既能方便集成 Redis,又能通过 Web 接口进行后续测试,简化开发流程。

在这里插入图片描述

  1. 配置 redis 服务地址
spring:
  redis:
    host: 127.0.0.1
    port: 8888
  1. 创建 Controller
@RestController
public class MyController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    // 可以在此添加方法来使用 redisTemplate
}
  1. 使用 String
@GetMapping("/testString")
@ResponseBody
public String testString() {
    // 使用 StringRedisTemplate 的 opsForValue 操作设置键值对
    redisTemplate.opsForValue().set("key", "value");
    
    // 获取键 "key" 的值
    String value = redisTemplate.opsForValue().get("key");
    System.out.println(value); // 打印获取到的值到控制台
    
    // 删除键 "key"
    redisTemplate.delete("key");
    
    // 返回操作结果
    return "OK";
}
  1. 使用 List
@GetMapping("/testList")
@ResponseBody
public String testList() {
    // 向列表 "key" 中左侧插入元素 "a"
    redisTemplate.opsForList().leftPush("key", "a");

    // 向列表 "key" 中左侧批量插入元素 "b", "c", "d"
    redisTemplate.opsForList().leftPushAll("key", "b", "c", "d");

    // 获取列表 "key" 中从索引 1 到索引 2 的元素
    List<String> values = redisTemplate.opsForList().range("key", 1, 2);
    System.out.println(values); // 打印获取到的元素列表到控制台

    // 删除键 "key"
    redisTemplate.delete("key");

    // 返回操作结果
    return "OK";
}
  1. 使用 Hash
@GetMapping("/testHashmap")
@ResponseBody
public String testHashmap() {
    // 在哈希表 "key" 中存储键值对 "name" -> "zhangsan"
    redisTemplate.opsForHash().put("key", "name", "zhangsan");

    // 从哈希表 "key" 中获取键 "name" 的值
    String value = (String) redisTemplate.opsForHash().get("key", "name");
    System.out.println(value); // 打印获取到的值到控制台

    // 删除哈希表 "key" 中的键 "name"
    redisTemplate.opsForHash().delete("key", "name");

    // 检查哈希表 "key" 中是否存在键 "name"
    boolean ok = redisTemplate.opsForHash().hasKey("key", "name");
    System.out.println(ok); // 打印检查结果到控制台

    // 删除整个哈希表 "key"
    redisTemplate.delete("key");

    // 返回操作结果
    return "OK";
}
  1. 使用 Set
@GetMapping("/testSet")
@ResponseBody
public String testSet() {
    // 向集合 "key" 中添加元素 "aaa", "bbb", "ccc"
    redisTemplate.opsForSet().add("key", "aaa", "bbb", "ccc");

    // 检查集合 "key" 是否包含元素 "aaa"
    boolean ok = redisTemplate.opsForSet().isMember("key", "aaa");
    System.out.println(ok); // 打印检查结果到控制台

    // 从集合 "key" 中移除元素 "aaa"
    redisTemplate.opsForSet().remove("key", "aaa");

    // 获取集合 "key" 的元素数量
    long n = redisTemplate.opsForSet().size("key");
    System.out.println(n); // 打印集合大小到控制台

    // 删除集合 "key"
    redisTemplate.delete("key");

    // 返回操作结果
    return "OK";
}
  1. 使用 Zset
@GetMapping("/testZSet")
@ResponseBody
public String testZSet() {
    // 向有序集合 "key" 中添加元素 "吕布",分值为 100
    redisTemplate.opsForZSet().add("key", "吕布", 100);
    // 向有序集合 "key" 中添加元素 "赵云",分值为 98
    redisTemplate.opsForZSet().add("key", "赵云", 98);
    // 向有序集合 "key" 中添加元素 "典韦"(注:原文中“典⻙”为“典韦”),分值为 95
    redisTemplate.opsForZSet().add("key", "典韦", 95);

    // 获取有序集合 "key" 中索引范围 [0, 2] 的元素
    Set<String> values = redisTemplate.opsForZSet().range("key", 0, 2);
    System.out.println(values); // 打印获取到的元素到控制台

    // 统计有序集合 "key" 中分值范围 [95, 100] 的元素数量
    long n = redisTemplate.opsForZSet().count("key", 95, 100);
    System.out.println(n); // 打印统计结果到控制台

    // 删除整个有序集合 "key"
    redisTemplate.delete("key");

    // 返回操作结果
    return "OK";
}

1.2 使用 Spring Boot 连接 Redis 集群

  1. 配置 redis 集群地址
spring:
  redis:
    cluster:
      nodes:
        - 172.30.0.101:6379
        - 172.30.0.102:6379
        - 172.30.0.103:6379
        - 172.30.0.104:6379
        - 172.30.0.105:6379
        - 172.30.0.106:6379
        - 172.30.0.107:6379
        - 172.30.0.108:6379
        - 172.30.0.109:6379
    lettuce:
      cluster:
        refresh:
          adaptive: true   # 自适应刷新,当集群中有节点宕机/加⼊新节点之后, 我们的代码能够⾃动感知到集群的变化.
          period: 2000     # 刷新周期,单位为毫秒

配置完成后,无需对其他代码进行任何调整即可正常运行。但需要注意,由于上述 IP 是 Docker 容器的内部 IP,无法直接在 Windows 主机上访问。因此,需要将程序打包成 JAR 文件后部署到 Linux 环境中,通过命令 java -jar [jar包名] 来执行。总结一下:Spring Boot 2 系列内置的 Redis 客户端是 Lettuce,与 Jedis 在使用上存在一定差异。Jedis 的方法基本与 Redis 命令一致,而集成到 Spring Boot 后,Lettuce 的接口与原始 Redis 命令略有不同,但只要熟悉 Redis 的基本操作,理解和使用这些方法并不困难。

二: 持久化

2.1 RDB

RDB 持久化是将当前进程的数据生成快照并保存到硬盘的过程,可通过手动触发或自动触发来实现。

2.1.1 触发机制

手动触发持久化可以通过执行 save 或 bgsave 命令实现,Redis 内部的所有涉及 RDB 的操作都采用类似 bgsave 的⽅式。

命令描述特点
save阻塞当前 Redis 服务器,直到 RDB 过程完成为止。对于内存较大的实例可能导致长时间阻塞,因此基本不使用。阻塞时间较长,不适合高并发场景。
bgsaveRedis 进程通过 fork 操作创建子进程,子进程负责完成 RDB 持久化过程,结束后自动退出。阻塞仅发生在 fork 阶段,时间较短。性能更优,阻塞时间短,适合生产环境,广泛使用。

除了手动触发外,Redis 还支持自动触发 RDB 持久化机制,这种触发方式在实际应用中更具价值。

触发机制描述
使用 save 配置配置规则为 “save m n”,表示在 m 秒内数据集发生 n 次修改时,自动触发 RDB 持久化。
从节点进行全量复制操作当从节点进行全量复制操作时,主节点会自动触发 RDB 持久化,并将生成的 RDB 文件内容发送给从节点。
执行 shutdown 命令关闭 Redis当执行 shutdown 命令关闭 Redis 时,会自动触发 RDB 持久化以保存数据。

2.1.2 流程说明

步骤描述
步骤 1执行 bgsave 命令时,父进程会判断是否存在其他正在执行的子进程(如 RDB 或 AOF 进程),如果存在,bgsave 命令直接返回,不执行操作。
步骤 2父进程通过 fork 操作创建子进程,fork 过程中父进程会阻塞。可以通过 info stats 命令查看 latest_fork_usec 选项,获取最近一次 fork 操作的耗时(单位为微秒)。
步骤 3fork 完成后,bgsave 命令返回 Background saving started 信息,父进程不再阻塞,可以继续响应其他命令。
步骤 4子进程生成 RDB 文件,通过父进程内存创建临时快照文件,完成后原子替换原有 RDB 文件。可以通过执行 lastsave 命令获取最后一次生成 RDB 的时间(对应 info 中的 rdb_last_save_time)。
步骤 5子进程完成后向父进程发送信号,通知完成操作,父进程随即更新相关统计信息。

在这里插入图片描述

2.1.3 RDB 文件的处理

功能描述
保存RDB 文件保存在 dir 配置指定的目录下(默认 /var/lib/redis/),文件名由 dbfilename 配置(默认 dump.rdb)指定。可通过 config set dir {newDir} 和 config set dbfilename {newFilename} 动态修改,下次运行时 RDB 文件会保存到新目录。
压缩Redis 默认使用 LZF 算法对生成的 RDB 文件进行压缩处理,压缩后的文件远小于内存大小。默认开启,可通过 config set rdbcompression {yes
校验如果 Redis 启动时检测到损坏的 RDB 文件会拒绝启动,可使用 redis-check-dump 工具检测 RDB 文件并生成错误报告。

2.1.4 RDB 的优缺点

特点描述
定义RDB 是一个紧凑压缩的二进制文件,表示 Redis 在某个时间点的数据快照,非常适用于备份和全量复制等场景。比如每隔 6 小时执行 bgsave,并将 RDB 文件复制到远程机器或文件系统(如 hdfs)进行灾备。
恢复速度Redis 加载 RDB 文件恢复数据的速度远快于使用 AOF 的方式。
实时性限制RDB 无法实现实时或秒级持久化,因为每次执行 bgsave 都需要 fork 创建子进程,这是一种重量级操作,频繁执行成本较高。
兼容性风险RDB 文件使用特定的二进制格式保存,随着 Redis 版本的演进存在多个 RDB 版本,因此可能存在兼容性风险。

2.2 AOF

AOF(Append Only File)持久化以独立日志的方式记录每次写操作的命令,并在重启时通过重新执行 AOF 文件中的命令来恢复数据。AOF 的主要优势在于解决了数据持久化的实时性问题,目前已成为 Redis 持久化的主流方式。深入理解和掌握 AOF 持久化机制,有助于在实际应用中更好地兼顾数据的安全性和系统性能。

2.2.1 使用 AOF

要开启 AOF 功能,需要设置配置项 appendonly yes,默认情况下 AOF 是关闭的。AOF 文件名可以通过配置项 appendfilename 设置(默认值为 appendonly.aof),保存目录与 RDB 持久化方式一致,由配置项 dir 指定。AOF 的工作流程包括四个主要步骤:命令写入(append)、文件同步(sync)、文件重写(rewrite)以及重启加载(load)。

步骤描述
步骤 1所有写入命令会追加到 AOF 缓冲区(aof_buf)中。
步骤 2AOF 缓冲区根据配置的同步策略将数据同步到硬盘。
步骤 3随着 AOF 文件不断增大,需定期对其进行重写以达到压缩文件的目的,减少存储占用。
步骤 4当 Redis 服务器启动时,可以加载 AOF 文件来恢复数据。

在这里插入图片描述

2.2.2 命令写入

AOF 命令写入的内容使用文本协议格式。例如,命令 set hello world 在 AOF 缓冲区中会被追加为以下内容:*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n。这遵循 Redis 的协议格式,Redis 选择文本协议的可能原因包括:兼容性好、实现简单且具备可读性。在 AOF 过程中,缓冲区 aof_buf 的作用是提升性能。由于 Redis 使用单线程响应命令,如果每次写 AOF 文件都直接同步到硬盘,IO 操作将极大降低性能。如果先写入缓冲区就可以减少 IO 次数,并且 Redis 提供多种缓冲区同步策略,用户可以根据需求在性能与数据安全性之间做出合理平衡。

2.2.3 文件同步

Redis 提供了多种 AOF 缓冲区同步文件的策略,可通过参数 appendfsync 进行配置和控制。

配置值描述建议
always每次命令写入 aof_buf 后立即调用 fsync 同步到硬盘,待同步完成后再返回。性能较差,在普通 SATA 硬盘上仅支持几百 TPS 写入,适用于极其重要的数据场景。仅在需要保证数据绝对安全且能容忍性能下降的情况下使用,例如金融级别的关键场景。
everysec命令写入 aof_buf 后仅执行 write 操作,同步操作由后台线程每秒调用一次 fsync 完成。该配置是默认值,兼顾数据安全性和性能,理论上最多丢失 1 秒的数据。默认推荐配置,适用于绝大多数场景,兼顾性能和数据安全性,适合生产环境。
no命令写入 aof_buf 后仅执行 write 操作,fsync 频率由操作系统自行控制,性能较高但数据丢失风险增加。适用于对数据安全性要求较低的场景,例如缓存类数据或短期内可快速恢复的非关键数据。

系统调用 write 和 fsync 说明:

系统调用描述
write触发延迟写机制,将数据写入系统缓冲区后立即返回。实际同步到硬盘依赖系统调度机制(如缓冲区空间写满或达到特定时间周期触发)。在同步前若系统宕机,缓冲区内的数据将丢失。
fsync针对单个文件进行强制硬盘同步操作,会阻塞当前进程直到数据完全写入硬盘,确保数据安全性,但性能开销较大。

2.2.4 重写机制

随着命令不断写入 AOF 文件,其体积会逐渐增大。为了解决这一问题,Redis 引入了 AOF 重写机制,通过压缩文件体积来优化存储。AOF 文件重写的过程是将 Redis 内存中的数据重新生成写命令,并同步到新的 AOF 文件中。重写后的 AOF 文件体积减小的原因主要包括以下几点:

原因描述
超时数据不再写入进程内已经超时的数据在重写时不会写入新的 AOF 文件,从而减少文件体积。
无效命令被移除旧的 AOF 文件中无效的命令(如 del、hdel、srem 等)在重写后会被删除,仅保留数据的最终版本,避免冗余操作。
合并多条写操作多条写操作可以合并为一条。例如,将 lpush list a、lpush list b、lpush list c 合并为 lpush list a b c,从而减少命令数量。

较小的 AOF 文件不仅能减少硬盘空间的占用,还能显著提升 Redis 启动时的数据恢复速度。AOF 重写过程可以通过手动触发或自动触发来完成:

触发方式描述
手动触发调用 bgrewriteaof 命令手动执行 AOF 重写。
自动触发auto-aof-rewrite-min-size:表示触发重写的最小 AOF 文件大小,默认值为 64MB。
auto-aof-rewrite-percentage:表示当前 AOF 文件大小相较于上次重写时的增长比例。
步骤描述
执行请求如果当前进程正在执行 AOF 重写,请求将不执行;如果当前进程正在执行 bgsave 操作,AOF 重写命令会延迟到 bgsave 完成后再执行。
创建子进程父进程执行 fork 操作以创建子进程。
重写过程主进程 fork 后继续响应其他命令,修改操作写入 AOF 缓冲区并根据 appendfsync 策略同步到硬盘,确保旧 AOF 文件机制正常。
子进程仅保留 fork 前的内存信息,父进程需将 fork 后的修改操作写入 AOF 重写缓冲区中。
合并命令子进程根据内存快照,将命令合并并写入新的 AOF 文件中。
完成重写子进程完成重写后,发送信号通知父进程。
父进程将 AOF 重写缓冲区中的临时命令追加到新 AOF 文件中。
最终用新 AOF 文件替换旧 AOF 文件。

在这里插入图片描述

2.2.5 启动时数据恢复

当 Redis 启动时,会根据 RDB 文件和 AOF 文件的内容进行数据恢复,确保数据状态与上次持久化时保持一致,如图所示:

在这里插入图片描述

三: Redis 事务

Redis 的事务与 MySQL 的事务在概念上类似,都是将一系列操作绑定为一个整体,以便批量执行。然而,两者在实现和特性上存在显著区别,需要重点理解其中的差异。

特性Redis 的事务特点与 MySQL 的对比
弱化的原子性Redis 没有回滚机制,事务只能实现操作的批量执行,无法在某个操作失败时恢复到初始状态。MySQL 支持回滚,确保事务的完全原子性,即所有操作要么全部成功,要么全部回滚。
不保证一致性Redis 不涉及约束,也没有回滚机制,可能会出现中间的非法状态。MySQL 的一致性确保事务前后的状态均合理有效,避免出现不一致或非法的状态。
不需要隔离性Redis 不提供隔离级别,因为事务不会并发执行,所有请求由单线程依次处理。MySQL 提供多种隔离级别(如读提交、可重复读等)来管理并发事务间的影响。
不需要持久性Redis 的数据存储在内存中,事务的持久性取决于是否开启持久化,与事务本身无关。MySQL 的事务持久性通过日志和磁盘存储来保障,即使系统崩溃也能确保数据完整。

Redis 事务的本质是通过在服务器上维护一个“事务队列”,客户端在事务中执行的每个操作都会被发送到服务器并加入队列,而不会立即执行。只有当收到 EXEC 命令时,队列中的所有操作才会一次性执行。相比于 MySQL,Redis 的事务功能较为弱化,仅能保证事务中的操作是连续执行的,不会被其他客户端的命令插入,但无法提供更高级的事务特性如回滚和一致性保障,下面介绍一些常用的事务操作:

3.1 MULTI

MULTI 命令用于开启一个事务,执行成功后返回 OK。

127.0.0.1:6379> MULTI
OK

3.2 EXEC

EXEC 命令用于真正执行事务队列中的所有操作。

127.0.0.1:6379> MULTI
OK

127.0.0.1:6379> set k1 1
QUEUED

127.0.0.1:6379> set k2 2
QUEUED

127.0.0.1:6379> set k3 3
QUEUED

127.0.0.1:6379> EXEC
1) OK
2) OK
3) OK

每次添加操作时,都会提示 “QUEUED”,表示命令已成功加入客户端的事务队列。当执行 EXEC 时,客户端会将这些操作发送到服务器并开始执行,此时才能获取到相关 key 的实际值。

3.3 DISCARD

DISCARD 命令用于放弃当前事务,直接清空事务队列,使之前的所有操作都不会被执行。

127.0.0.1:6379> MULTI
OK

127.0.0.1:6379> set k1 1
QUEUED

127.0.0.1:6379> set k2 2
QUEUED

127.0.0.1:6379> DISCARD
OK

127.0.0.1:6379> get k1
(nil)

127.0.0.1:6379> get k2
(nil)

3.4 WATCH

WATCH 命令用于监控事务中的关键值,如果某个事务中修改的值被别的客户端修改了,此时会导致数据不一致的问题。

# 客户端 1 开始事务
127.0.0.1:6379> MULTI
OK

127.0.0.1:6379> set key 100
QUEUED

# 客户端 2 修改 key 的值
127.0.0.1:6379> set key 200
OK

# 客户端 1 提交事务
127.0.0.1:6379> EXEC
1) OK

此时 key 的值为 “100”。从命令的输入顺序看,客户端 1 先执行了 set key 100,客户端 2 后执行了 set key 200;但从实际执行时间看,客户端 2 的操作先生效,而客户端 1 在提交事务时覆盖了客户端 2 的修改。这种情况容易引发歧义,因此,虽然 Redis 不保证严格的隔离性,但需要提醒用户操作可能存在被其他客户端修改的风险。为了解决这一问题,Redis 提供了 WATCH 命令,用于在客户端上监控一组特定的 key,从而避免数据冲突。

功能描述
监控 keyWATCH 命令允许客户端监控一组特定的 key,在事务开启时锁定这些 key 的状态。
记录版本号当监控的 key 被修改时,Redis 会记录该 key 的版本号(一个递增的整数,每次修改都会增加)。
事务提交校验在提交事务时,Redis 会检查 key 的版本号是否发生变化。如果版本号超过事务开始时的记录,事务将失败。
解决冲突如果事务失败,客户端可以选择重新尝试或采取其他逻辑,从而有效解决并发修改导致的数据冲突问题。
127.0.0.1:6379> watch k1        # 开始监控 k1
OK

127.0.0.1:6379> MULTI
OK

127.0.0.1:6379> set k1 100      # 进行修改,记录 k1 的版本号为 0 (还未实际修改,版本号不变)
QUEUED

127.0.0.1:6379> set k2 1000     # 将操作入队列,但未提交事务
QUEUED

# 客户端 2 进行操作
127.0.0.1:6379> set k1 200      # 修改成功,服务器端 k1 的版本号从 0 增加到 1
OK

# 客户端 1 提交事务
127.0.0.1:6379> EXEC            # 尝试执行事务,发现 k1 的版本号不一致 (客户端为 0,服务器为 1),事务失败
(nil)

# 查看当前值
127.0.0.1:6379> get k1
"200"

127.0.0.1:6379> get k2
(nil)

3.5 UNWATCH

NWATCH 用于取消对 key 的监控,是 WATCH 命令的逆操作。通过 NWATCH,可以在事务执行前取消对所有被监控 key 的观察,从而恢复 key 的正常状态。

# 客户端 1 开始操作
127.0.0.1:6379> watch k1        # 监控 key k1
OK

127.0.0.1:6379> get k1          # 查看 k1 当前值
(nil)

127.0.0.1:6379> MULTI           # 开启事务
OK

127.0.0.1:6379> set k1 100      # 事务中设置 k1 为 100
QUEUED

127.0.0.1:6379> set k2 200      # 事务中设置 k2 为 200
QUEUED

# 客户端决定取消监控
127.0.0.1:6379> nwatch          # 取消监控所有 key
OK

# 此时可以正常提交事务,操作不再受监控的限制
127.0.0.1:6379> EXEC
1) OK                            # 成功设置 k1 为 100
2) OK                            # 成功设置 k2 为 200

# 查看结果
127.0.0.1:6379> get k1
"100"

127.0.0.1:6379> get k2
"200"

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

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

相关文章

笔记本如何录屏幕视频和声音?快速入门的两种方法

“你好&#xff01;我想要制作线上教学课程&#xff0c;包括录制课程内容和我的声音&#xff0c;然后分享给我的学生&#xff0c;以便他们课后复习&#xff0c;但我不知道笔记本如何录屏幕视频和声音&#xff1f;有没有好的工具推荐&#xff1f;” 随着远程办公、在线学习和直播…

Flutter中的网络请求图片存储为缓存,与定制删除本地缓存

Flutter中的网络请求图片存储为缓存&#xff0c;与定制删除本地缓存 1&#xff1a;封装请求图片函数 2&#xff1a;访问的图片都会转为本地缓存&#xff0c;当相同的请求url&#xff0c;会在本地调用图片 3&#xff1a;本地缓存管理【windows与andriod已经测试】【有页面】【有…

Android设备使用AOA协议进行主机与配件模式通信

1.使用TYPC-C数据线连接两台华为手机&#xff1a; TYPE-C线&#xff0c;先连接下图右边的ACCESSORY 再连接左边的HOST 此时左边的HOST(白色) 会给右边的ACCESSORY(黑色) 充电 接着打开左连接的HostChart会自动调起授权&#xff0c;然后会启动右边的AccessoryChart USB HOS…

机器学习基础-支持向量机SVM

目录 基本概念和定义 1. 超平面&#xff08;Hyperplane&#xff09; 2. 支持向量&#xff08;Support Vectors&#xff09; 3. 线性可分 4. 边界 SVM算法基本思想和分类 基本思想 间隔最大化 间隔&#xff08;Margin&#xff09; 软边距 SVM 核函数的概念 基本概念…

ubuntu开机启动服务

需求背景&#xff1a; 需要监控日志&#xff0c;每次都是手动启动 nohup ./prometheus >/dev/null & nohub ./node_exporter >/dev/null & 需求目标&#xff1a; 重启后系统自动启动服务

图漾相机基础操作

1.客户端概述 1.1 简介 PercipioViewer是图漾基于Percipio Camport SDK开发的一款看图软件&#xff0c;可实时预览相机输出的深度图、彩色图、IR红外图和点云图,并保存对应数据&#xff0c;还支持查看设备基础信息&#xff0c;在线修改gain、曝光等各种调节相机成像的参数功能…

【计算机网络】课程 实验二 交换机基本配置和VLAN 间路由实现

实验二 交换机基本配置和VLAN 间路由实现 一、实验目的 1&#xff0e;了解交换机的管理方式。 2&#xff0e;掌握通过Console接口对交换机进行配置的方法。 3&#xff0e;掌握交换机命令行各种模式的区别&#xff0c;能够使用各种帮助信息以及命令进行基本的配置。 4&…

【论文笔记】QLoRA: Efficient Finetuning of Quantized LLMs

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: QLoRA: Efficient Finetun…

Apache Paimon-实时数据湖

一、Apache Paimon是什么? Flink社区希望能够将 Flink 的 Streaming 实时计算能力和 Lakehouse 新架构优势进一步结合&#xff0c;推出新一代的 Streaming Lakehouse 技术&#xff0c;促进数据在数据湖上真正实时流动起来&#xff0c;并为用户提供实时离线一体化的开发体验。 …

为什么相关性不是因果关系?人工智能中的因果推理探秘

目录 一、背景 &#xff08;一&#xff09;聚焦当下人工智能 &#xff08;二&#xff09;基于关联框架的人工智能 &#xff08;三&#xff09;基于因果框架的人工智能 二、因果推理的基本理论 &#xff08;一&#xff09;因果推理基本范式&#xff1a;因果模型&#xff0…

AI Development Notes 1 - introduction with the OpenAI API Development

Official document&#xff1a;https://platform.openai.com/docs/api-reference/chat/create 1. Use APIfox to call APIs 2.Use PyCharm to call APIs 2.1-1 WIN OS.Configure the Enviorment variable #HK代理环境&#xff0c;不需要科学上网(价格便宜、有安全风险&#…

路由组件与一般组件的区别

路由组件与一般组件的区别 1. 基本概念 1.1 路由组件 路由组件是指通过路由规则映射的组件&#xff0c;通常放在 pages 或 views 文件夹中。 1.2 一般组件 一般组件是指通过 import 导入后直接使用的组件&#xff0c;通常放在 components 文件夹中。 2. 主要区别 2.1 存…

K8s高可用集群之Kubernetes集群管理平台、命令补全工具、资源监控工具部署及常用命令

K8s高可用集群之Kubernetes管理平台、补全命令工具、资源监控工具部署及常用命令 1.Kuboard可视化管理平台2.kubectl命令tab补全工具3.MetricsServer资源监控工具4.Kubernetes常用命令 1.Kuboard可视化管理平台 可以选择安装k8s官网的管理平台&#xff1b;我这里是安装的其他开…

【C++】18.继承

文章目录 1.继承的概念及定义1.1 继承的概念1.2 继承定义1.2.1定义格式1.2.2继承关系和访问限定符1.2.3继承基类成员访问方式的变化 1.3 继承类模板 2.基类和派生类对象赋值转换3.继承中的作用域3.1 隐藏规则&#xff1a;3.2 考察继承作用域相关选择题 4.派生类的默认成员函数4…

51单片机——8*8LED点阵

LED 点阵的行则为发光二极管的阳极&#xff0c;LED 点阵的列则为发光二极管的阴极 根据 LED 发光二极管导通原理&#xff0c;当阳极为高电平&#xff0c;阴极为低电平则点亮&#xff0c;否则熄灭。 因此通过单片机P0口可控制点阵列&#xff0c;74HC595可控制点阵行 11 脚 SR…

FastDeploy部署paddlecls分类模型(windows)

目录 写在前面 总体步骤 C SDK编译库 方式1&#xff1a;编译安装 方式2&#xff1a;下载预编译库 准备模型、文件、代码和数据 模型文件类型 samples代码 待预测图像 使用 FastDeploy C SDK 将cpp源码编译为exe 编写cpp代码 cpp代码编译exe 运行可执行程序exe 将…

电脑如何无线控制手机?

想在电脑上无线控制手机&#xff0c;需要用到Total Control控制软件&#xff0c;具体步骤如下&#xff1a; 1、首先我们在电脑上安装上控制软件Total Control并打开。 2、开启手机USB调试和ADB仅充电模式。 3、手机电脑均连接上相同局域网。 4、连接(首次使用需要用手机U…

C++ Qt练习项目 QChar功能测试

个人学习笔记 代码仓库 GitCode - 全球开发者的开源社区,开源代码托管平台 新建项目 设计UI 1、拖入group box去掉名字 2、拖入2个LineEdit 3、拖入两个Label 4、拖入两个PushButton 5、点栅格布局 1、拖入GroupBox 2、拖入4个PushButton 3、点栅格布局 1、拖入GroupBo…

QT c++ 样式 设置 标签(QLabel)的渐变色美化

上一篇文章中描述了按钮的纯色&#xff0c;本文描述标签的渐变色美化。 1.头文件 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> //#include "CustomButton.h"#include <QVBoxLayout> #include <QLinearGradient> #include <QLabel…

【C++面向对象——输入输出流】处理二进制文件(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 一、流类库中常用的类及其成员函数 二、标准输入输出及格式控制 三、文件的应用方法&#xff08;二进制文件、文本文件&#xff09; 编程要求 实验步骤 通关代码 测试结果 任务描述 本关任务&#xff1a; 用二进制方式打开指定的…