Redis深度解析:场景、锁、队列、Big Key与缓存优化

引言

  • 简要介绍Redis
  • Redis的优势和适用场景

一、Redis使用场景

  • 缓存系统:缓存热点数据,减轻数据库压力,提高应用响应速度。
  • 会话存储:替代传统的服务器端会话存储,减轻服务器负载,实现会话数据的快速存取。
  • 计数器:实现快速自增自减操作,常用于限流、统计等场景。
  • 排行榜/排序:基于Redis的有序集合(Sorted Set)实现实时更新的排行榜功能。
  • 分布式锁:实现跨多个服务或实例的同步控制,确保同一时间只有一个客户端能够访问共享资源。
  • 消息队列:Redis可以实现轻量级的消息系统,用于解耦系统、异步处理任务等。

二、Redis实现分布式锁

  • Redis分布式锁原理
  • 使用SETNX、EXPIRE等命令实现分布式锁
  • Java示例代码(使用Jedis或Lettuce库)
// 伪代码片段  
public synchronized boolean tryLock(String lockKey, String requestId, int expireTime) {  
    // 使用SETNX命令尝试获取锁  
    // ...  
    return true; // 或false  
}  
  
public synchronized void unlock(String lockKey, String requestId) {  
    // 释放锁的逻辑  
    // ...  
}

Redis实现分布式锁的原理主要基于Redis的多个实例之间的协作,以确保在分布式系统中多个节点对共享资源的互斥访问。以下是Redis实现分布式锁的详细原理:

一、基本思想

Redis分布式锁通过Redis的SETNX(SET IF NOT EXISTS)命令或SET命令结合多个参数(如NX、PX等)来实现。这些命令允许在键不存在时设置键的值,或者在设置键的值的同时设置键的过期时间。通过这种方式,Redis可以作为一个中央化的锁管理器,协调多个节点对共享资源的访问。

二、实现步骤

  1. 加锁:客户端使用SETNX命令尝试获取锁。如果键不存在,则设置键的值(通常为客户端的唯一标识符,如UUID或请求ID)并返回1,表示加锁成功。如果键已存在,则返回0,表示加锁失败。为了避免客户端永远无法获取到锁(如锁被其他客户端持有且未释放),可以设置锁的过期时间。这可以通过SET命令的PX参数来实现,该参数指定了键的过期时间(以毫秒为单位)。
  2. 释放锁:当客户端完成操作后,需要释放锁。这通常通过DEL命令删除键来实现。然而,为了确保只有锁的持有者才能释放锁,客户端在删除键之前需要检查键的值是否与自己的唯一标识符相匹配。这可以通过GET命令和条件删除(如Lua脚本)来实现。
  3. 解决死锁:如果锁的持有者崩溃或删除锁失败,其他客户端将无法获取到锁,导致死锁。为了解决这个问题,可以在获取锁时检查锁的过期时间。如果锁的过期时间小于当前时间,则认为锁已过期,其他客户端可以尝试获取锁。

三、Redis实现消息队列

  • Redis消息队列的设计
  • 使用List或Stream实现消息队列
  • 发布/订阅模式
  • Java示例代码(使用Jedis或Lettuce库)
// 伪代码片段  
jedis.lpush("mylist", "message1"); // 生产消息  
String message = jedis.rpop("mylist"); // 消费消息

Redis 作为一个内存中的数据结构存储系统,它可以用作数据库、缓存和消息中介。由于其高性能和丰富的数据结构,Redis 在实现消息队列方面非常高效。以下我们将探讨如何使用 Redis 的 List(列表)或 Stream(流)来实现消息队列,以及如何使用 Redis 的发布/订阅模式。

使用List实现消息队列

Redis 的 List 是一种双向链表结构,它支持在两端插入和删除元素。这使得 List 非常适合用作消息队列。生产者可以将消息 LPUSH 到列表的一端,而消费者可以 BRPOP 或 BLPOP 从列表的另一端获取并移除消息。

生产者示例(Java 使用 Jedis)

Jedis jedis = new Jedis("localhost");  
String listKey = "myqueue";  
String message = "Hello, Redis Queue!";  
jedis.lpush(listKey, message);

消费者示例(Java 使用 Jedis)

Jedis jedis = new Jedis("localhost");  
String listKey = "myqueue";  
List<String> messages = jedis.brpop(0, listKey); // 等待时间为0表示阻塞直到有消息  
String message = messages.get(1); // 索引1是消息内容,索引0是队列名  
System.out.println(message); // 输出消息内容

使用Stream实现消息队列(Redis 5.0+)

Redis Stream 是 Redis 5.0 引入的一个新特性,它提供了一个可持久化的、只追加的消息队列。与 List 相比,Stream 提供了更多的消费者组(Consumer Group)和消息确认(Message Acknowledgment)机制,使得它更适合复杂的消息处理场景。

生产者示例(Java 使用 Jedis 或 Lettuce)

在 Redis Stream 中,生产者使用 XADD 命令添加消息。

// Jedis 或 Lettuce 的 Stream API 可能会有所不同,这里仅提供伪代码  
String streamName = "mystream";  
Map<String, String> messageBody = new HashMap<>();  
messageBody.put("field1", "value1");  
String messageId = jedis.xadd(streamName, null, messageBody); // 第一个参数是流名,第二个参数是消息ID(可以为null以自动生成),第三个参数是消息内容

消费者示例(Java 使用 Jedis 或 Lettuce)

消费者使用 XREADGROUP 命令从 Stream 中读取消息,并使用 XACK 命令确认消息已被处理。

// 伪代码  
String groupName = "mygroup";  
String consumerName = "myconsumer";  
String startId = "$"; // 从最新消息开始读取  
List<Entry<String, List<Map<String, String>>>> pendingMessages = jedis.xreadgroup(groupName, consumerName, Collections.singletonList(new Entry<>(streamName, startId)));  
// 处理消息...  
// 确认消息已处理  
jedis.xack(streamName, groupName, messageId); // messageId 是需要确认的消息的ID

发布/订阅模式

除了使用 List 或 Stream 来实现点对点的消息队列外,Redis 还提供了发布/订阅模式(Pub/Sub),它允许客户端订阅一个或多个频道(Channel),并接收发送到这些频道的消息。发布/订阅模式通常用于实现广播式的消息传递。

发布者示例(Java 使用 Jedis)

Jedis jedis = new Jedis("localhost");  
String channel = "mychannel";  
String message = "Hello, Redis Subscribers!";  
jedis.publish(channel, message);

订阅者示例(Java 使用 Jedis)

订阅者使用 PSUBSCRIBE 或 SUBSCRIBE 命令订阅频道,并使用 onPMessage 或 onMessage 回调函数来处理接收到的消息。

JedisPubSub jedisPubSub = new JedisPubSub() {  
    @Override  
    public void onPMessage(String pattern, String channel, String message) {  
        System.out.println("Received message on channel " + channel + ": " + message);  
    }  
};  
Jedis jedis = new Jedis("localhost");  
jedis.psubscribe(jedisPubSub, "my*"); // 订阅所有以 "my" 开头的频道  
// 注意:由于订阅是阻塞的,通常在一个单独的线程中执行

四、Redis解决Big Key的问题

  • Big Key的定义和影响
  • 识别Big Key
  • 拆分Big Key
  • 使用Hash数据结构
  • Java示例代码(拆分和查询Hash)
// 伪代码片段  
jedis.hset("bigkeyhash", "field1", "value1"); // 使用Hash存储数据  
Map<String, String> result = jedis.hgetAll("bigkeyhash"); // 获取Hash数据

Redis解决Big Key的问题

Big Key的定义和影响

Big Key 是指 Redis 中存储的键值对(key-value pair)的值部分非常大,比如一个包含成百上千个字段的 Hash 类型,或者一个包含大量元素的 List、Set、Sorted Set 类型。Big Key 会对 Redis 的性能和稳定性产生负面影响:

  1. 内存占用:Big Key 会占用大量的内存空间,可能导致 Redis 内存使用迅速增长,甚至耗尽服务器内存。
  2. 阻塞:在操作 Big Key 时,比如获取(GET)、删除(DEL)、序列化/反序列化等,Redis 会消耗更多的时间处理这些请求,导致其他请求的响应延迟增加,甚至造成阻塞。
  3. 网络传输:当 Big Key 在客户端和 Redis 服务器之间传输时,会占用大量的网络带宽,增加网络延迟。
  4. 备份和恢复:包含 Big Key 的 Redis 数据备份和恢复速度会变慢。
  5. 主从同步:主从复制过程中,Big Key 会导致主节点向从节点发送大量数据,影响同步效率。

识别Big Key

为了识别 Big Key,可以使用以下工具和方法:

  1. redis-cli --bigkeys:Redis 官方提供的 redis-cli 工具支持 --bigkeys 选项,用于扫描 Redis 实例并找出 Big Key。
  2. MEMORY USAGE 命令:Redis 提供了 MEMORY USAGE 命令来估算指定键的内存使用情况。
  3. 第三方工具:如 redis-rdb-tools、redis-memory-analyzer 等,这些工具可以分析 RDB 快照文件或实时分析 Redis 内存使用情况。

拆分Big Key

一旦识别出 Big Key,就需要对其进行拆分以减少其大小。以下是几种拆分 Big Key 的方法:

  1. Hash数据结构:将原来的 Big Key 拆分成多个小的 Hash,每个 Hash 存储一部分数据。例如,原本一个包含 1000 个字段的 Hash 可以拆分成 10 个包含 100 个字段的 Hash。
  2. List、Set、Sorted Set 的分页:对于 List、Set、Sorted Set 类型的 Big Key,可以使用分页的方式来获取和处理数据。例如,每次只获取和处理一部分元素,而不是一次性获取整个集合。
  3. 时间序列数据:如果 Big Key 是时间序列数据(如日志、监控数据等),可以考虑使用 Redis 的 Stream 或其他时间序列数据库来存储和查询数据。

使用Hash数据结构

Hash 是 Redis 中一种常用的数据结构,它允许存储多个字段和对应的值。当需要拆分 Big Key 时,可以使用 Hash 来存储原本 Big Key 中的一部分数据。

例如,原本有一个包含 1000 个用户信息的 Big Key(假设为 bigkey:users),每个用户信息包含多个字段(如 id、name、email 等)。可以将这个 Big Key 拆分成多个小的 Hash,每个 Hash 存储一部分用户信息。具体的拆分方式可以根据实际情况来确定,比如按照用户 ID 的范围或哈希值来拆分。

拆分后的 Hash 可以使用类似 user:123、user:456 这样的键来命名,其中 123、456 是用户 ID。每个 Hash 中存储该用户的所有信息。

在拆分 Big Key 并使用 Hash 数据结构时,需要注意以下几点:

  1. 键名设计:合理设计键名以确保可以唯一地标识每个拆分后的 Hash。
  2. 一致性:确保在拆分和合并过程中数据的一致性。
  3. 原子性:如果需要同时更新多个拆分后的 Hash,需要考虑操作的原子性。可以使用 Lua 脚本来实现原子操作。
  4. 监控和告警:定期监控拆分后的 Hash 的大小,并在必要时进行告警或进一步拆分。

五、Redis的缓存淘汰策略

  • LRU(最近最少使用)
  • LFU(最不经常使用)
  • TTL(过期时间)
  • 配置缓存淘汰策略
  • Java中配置Redis缓存淘汰策略(通常在Redis配置文件中设置)

Redis的缓存淘汰策略

Redis提供了多种缓存淘汰策略,用于在内存达到最大限制时,决定哪些数据应该被移除以释放空间。这些策略对于Redis的性能和缓存效率至关重要。

LRU(最近最少使用)

LRU(Least Recently Used)策略会选择最久未使用的数据进行淘汰。当内存不足以容纳新写入数据时,最少使用的数据最先被淘汰。

LFU(最不经常使用)

LFU(Least Frequently Used)策略是Redis 4.0版本中引入的,它会跟踪数据被访问的频率,并淘汰最不经常使用的数据。LFU策略比LRU更精细,因为它不仅考虑数据被访问的时间,还考虑被访问的次数。

TTL(过期时间)

TTL(Time To Live)并不是一种直接的淘汰策略,但Redis允许为数据设置过期时间。当数据达到其TTL时,它会自动从Redis中删除。这可以作为一种间接的缓存淘汰机制,因为过期的数据将不再占用内存。

配置缓存淘汰策略

在Redis配置文件中(通常是redis.conf),你可以通过maxmemory-policy配置项来设置缓存淘汰策略。以下是一些可能的选项:

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
  • allkeys-lru:使用LRU策略淘汰所有键。
  • allkeys-lfu:使用LFU策略淘汰所有键(需要Redis 4.0或更高版本)。
  • volatile-lru:使用LRU策略淘汰设置了过期时间的键。
  • volatile-lfu:使用LFU策略淘汰设置了过期时间的键(需要Redis 4.0或更高版本)。
  • volatile-ttl:淘汰最接近过期时间的键。
  • volatile-random:随机淘汰设置了过期时间的键。

Java中配置Redis缓存淘汰策略

在Java中,你通常不会直接在代码中配置Redis的缓存淘汰策略。相反,你应该在Redis的配置文件(redis.conf)中进行设置。然后,你的Java应用程序将连接到这个已配置的Redis实例。

然而,如果你使用某种Java客户端(如Jedis、Lettuce或Redisson)和Redis进行交互,并且这些客户端提供了某种形式的配置API,你可能能够检查或报告Redis实例的当前配置(包括缓存淘汰策略),但通常你不能直接通过客户端API更改这些配置。

如果你需要动态更改Redis的配置(包括缓存淘汰策略),你可能需要考虑使用Redis的CONFIG SET命令,但这通常是不推荐的,因为它需要特殊的权限,并且可能会引入风险。在生产环境中,最好是在Redis配置文件中进行静态配置,并在需要时重启Redis服务。

六、Redis的快速读写优化

  • 持久化策略:RDB与AOF
  • 管道(Pipelining)技术
  • 事务(Transactions)
  • Lua脚本
  • 数据结构的选择与优化
  • Redis配置优化(如tcp-backlog、maxmemory等)
  • Java中优化Redis读写(使用连接池、批量操作等)

Redis的快速读写优化

Redis 提供了多种机制和技术来优化其快速读写性能。以下是针对 Redis 性能优化的几个关键方面:

持久化策略:RDB 与 AOF

  • RDB (Redis DataBase):RDB 是 Redis 默认的持久化方式,它会在指定的时间间隔内,将内存中的数据集快照写入磁盘。优点:生成 RDB 文件的速度快,适合用于备份。缺点:数据可能会丢失(因为 RDB 是基于时间间隔的快照)。
  • AOF (Append Only File):AOF 会记录服务器接收到的每一个写操作命令,并在服务器启动时重新执行这些命令来恢复数据。优点:数据持久性更好,几乎不会丢失数据。缺点:AOF 文件比 RDB 文件大,且恢复速度相对较慢。

优化建议

  • 根据业务需求选择适合的持久化策略。
  • 定期检查和优化 AOF 重写和 RDB 快照的频率。

管道(Pipelining)技术

  • 管道技术允许客户端将多个命令打包,一次性发送给服务器,然后等待所有命令的响应。
  • 这减少了网络往返时间(RTT),从而提高了吞吐量。

优化建议

  • 在批量操作或高并发场景下使用管道技术。

事务(Transactions)

  • Redis 提供了简单的事务支持,允许将多个命令打包到一个事务中,确保这些命令的原子性执行。
  • 但请注意,Redis 的事务不支持回滚(除了执行 EXEC 前使用 DISCARD 命令)。

优化建议

  • 在需要确保多个命令原子性执行的场景下使用事务。

Lua 脚本

  • Redis 支持在服务器端执行 Lua 脚本,这允许将多个命令组合到一个脚本中,减少网络往返时间。
  • Lua 脚本在 Redis 服务器内部执行,因此执行速度更快。

优化建议

  • 在需要执行复杂逻辑或需要减少网络往返时间的场景下使用 Lua 脚本。

数据结构的选择与优化

  • Redis 支持多种数据结构,如 String、Hash、List、Set、Sorted Set 等。
  • 选择合适的数据结构对于性能至关重要。

优化建议

  • 根据数据的访问模式和业务需求选择合适的数据结构。
  • 避免使用过于复杂的数据结构,如嵌套的数据结构。

Redis 配置优化

  • Redis 提供了许多配置选项,用于优化其性能。
  • 例如,tcp-backlog、maxmemory、maxmemory-policy、appendfsync 等。

优化建议

  • 根据服务器的硬件和业务需求调整 Redis 配置。
  • 监控 Redis 的性能指标,并根据需要进行调整。

Java 中优化 Redis 读写

  • 使用连接池:连接池可以复用 Redis 连接,减少创建和销毁连接的开销。
  • 批量操作:使用 Redis 的批量操作命令(如 MSET、MGET)或管道技术来减少网络往返时间。
  • 选择合适的序列化方式:使用高效的序列化方式(如 Protocol Buffers、Kryo 等)来减少数据的序列化/反序列化开销。
  • 监控和调优:使用 Redis 监控工具(如 Redis Insight、Redis Commander)来监控 Redis 的性能指标,并根据需要进行调优。

优化建议

  • 在 Java 应用程序中使用 Redis 连接池。
  • 尽可能使用批量操作来减少网络往返时间。
  • 选择合适的序列化方式并监控其性能。
  • 监控 Redis 的性能指标并根据需要进行调优。


项目代码地址:https:
//gitee.com/bseaworkspace/redis-example

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

模拟 ADC 的前端

ADC 的 SPICE 模拟 反复试验的方法将信号发送到 ADC 非常耗时&#xff0c;而且可能有效也可能无效。如果转换器捕获电压信息的关键时刻模拟输入引脚不稳定&#xff0c;则无法获得正确的输出数据。SPICE 模型允许您执行的步是验证所有模拟输入是否稳定&#xff0c;以便没有错误…

全网最详细金融APP测试功能点-测试用例,详细整理(全)

2024软件测试面试刷题&#xff0c;这个小程序&#xff08;永久刷题&#xff09;&#xff0c;靠它快速找到工作了&#xff01;&#xff08;刷题APP的天花板&#xff09;-CSDN博客跳槽涨薪的朋友们有福了&#xff0c;今天给大家推荐一个软件测试面试的刷题小程序。https://blog.c…

mov文件怎么转换成mp4格式?这四种转换方法超级好用!

mov文件怎么转换成mp4格式&#xff1f;在数字娱乐的世界中&#xff0c;你是否曾遇到过MOV格式的视频&#xff1f;也许&#xff0c;对于许多人来说&#xff0c;这并不是一个常见的格式&#xff0c;但这并非偶然&#xff0c;首先&#xff0c;我们来谈谈MOV的兼容性问题&#xff0…

「漏洞复现」时空智友ERP系统updater.uploadStudioFile 任意文件上传漏洞

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

Python处理异常用操作介绍

Python中的异常处理主要用于捕获和处理程序运行过程中出现的错误。 在编写Python程序时&#xff0c;我们经常会遇到各种错误&#xff0c;如语法错误、运行时错误等。为了确保程序的稳定性和健壮性&#xff0c;我们需要对可能出现的错误进行捕获和处理。本文将介绍Python中常用的…

Python入门 2024/7/3

目录 for循环的基础语法 遍历字符串 练习&#xff1a;数一数有几个a range语句 三个语法 语法1 语法2 语法3 练习&#xff1a;有几个偶数 变量作用域 for循环的嵌套使用 打印九九乘法表 发工资案例 continue和break语句 函数的基础定义语法 函数声明 函数调用 …

MLLM QLoRA微调实战:基于最新的袖珍Mini-InternVL模型

引言 大型语言模型&#xff08;LLM&#xff09;的世界正在不断发展&#xff0c;新的进步正在迅速出现。一个令人兴奋的领域是多模态LLM&#xff08;MLLMs&#xff09;的发展&#xff0c;这种模型既能够理解文本又能够理解图像&#xff0c;并与之进行交互。因此&#xff0c;这种…

ICCV2023鲁棒性相关论文速览

Paper1 Towards Better Robustness against Common Corruptions for Unsupervised Domain Adaptation 摘要原文: Recent studies have investigated how to achieve robustness for unsupervised domain adaptation (UDA). While most efforts focus on adversarial robustnes…

udp发送数据如果超过1个mtu时,抓包所遇到的问题记录说明

最近在测试Syslog udp发送相关功能&#xff0c;测试环境是centos udp头部的数据长度是2个字节&#xff0c;最大传输长度理论上是65535&#xff0c;除去头部这些字节&#xff0c;可以大概的说是64k。 写了一个超过64k的数据(随便用了一个7w字节的buffer)发送demo&#xff0c;打…

Geotools系列说明之LineString仿高德航路截取说明

需求分析 我们在做webgl的时候经常会遇到这样的需求&#xff0c;计算给定航路的拥堵情况&#xff0c;不同的拥堵显示不同的颜色&#xff0c;航路截取计算等等。基于这类问题统一都可以使用LineString进行处理 实现思路 如上图所示&#xff0c;航路是几个关键的点然后练成线&a…

MySql Innodb 索引有哪些与详解

概述 对于MYSQL的INNODB存储引擎的索引&#xff0c;大家是不陌生的&#xff0c;都能想到是 B树结构&#xff0c;可以加速SQL查询。但对于B树索引&#xff0c;它到底“长”得什么样子&#xff0c;它具体如何由一个个字节构成的&#xff0c;这些的基础知识鲜有人深究。本篇文章从…

2本Top,4本纯正刊,25天即录!7月刊源表已更新!

本周投稿推荐 SCI • 能源技术类&#xff0c;1.5-2.0&#xff08;来稿即录25天&#xff09; • 计算机类&#xff0c;2.0-3.0&#xff08;纯正刊29天录用&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; CNKI • 7天录用-检索&#xff08;急录友好&a…

【微信小程序开发实战项目】——如何制作一个属于自己的花店微信小程序(2)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

Python基于决策树回归模型、多元线性回归模型、随机森林回归模型和LightGBM回归模型实现波士顿房价预测项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 城市住房市场的稳定与健康发展是衡量一个地区经济活力和社会福祉的重要指标之一。波士顿&#xff0c;作…

Three-pass authentication

7.2.3 Mechanism MUT.CR — Three-pass authentication # 参考符号 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7aed1610e49e48729933f8160e5228af.png)

研发驱动 再谱新篇丨美格智能南通研发中心正式成立

近日&#xff0c;美格智能全资设立的众格智能技术&#xff08;南通&#xff09;有限公司&#xff0c;正式在江苏省南通市紫琅科技城揭牌成立&#xff0c;此举也标志着继上海、西安、深圳之后&#xff0c;美格智能研发力量布局再谱新篇&#xff1a;美格智能南通研发中心正式成立…

工商业光伏项目如何快速开发?

一、前期调研与规划 1、屋顶资源评估&#xff1a;详细测量屋顶面积、承重能力及朝向&#xff0c;利用光伏业务管理软件进行日照分析和发电量预测&#xff0c;确保项目可行性。 2、政策与补贴研究&#xff1a;深入了解当地政府对工商业光伏项目的政策支持和补贴情况&#xff0…

KES数据库实践指南:探索KES数据库的事务隔离级别

并发控制 并发控制的重要性 并发控制是数据库管理系统中的一个核心概念&#xff0c;它确保在多用户环境中&#xff0c;对数据库的并发访问不会破坏数据的完整性和一致性。 当多个用户同时对数据库进行读写操作时&#xff0c;如果缺乏有效的并发控制机制&#xff0c;可能会导致数…

动态规划精品课 2024.6.26-24.7.3

一、斐波那契数列模型 0、第N个泰波那契数 class Solution {public int tribonacci(int n) {// 1. 创建 dp 表// 2. 初始化// 3. 填表// 4. 返回结果// 处理边界情况if (n 0)return 0;if (n 1 || n 2)return 1;int[] dp new int[n 1];dp[0] 0;dp[1] dp[2] 1;for (int i…

类型转换与数据绑定【Spring源码学习】

simpleTypeConverter 类型转换 SimpleTypeConverter typeConverter new SimpleTypeConverter(); Integer number typeConverter.convertIfNecessary("13",int.class); System.out.println(number);BeanWrapper 通过反射原理为bean赋值&#xff0c;走的是set方法…
最新文章