Redis篇-7--原理篇6--过期机制(定时删除,惰性删除,Redis过期事件监听和Java实现)

Redis提供了丰富的过期机制,允许用户为键设置一个生存时间(TTL,Time To Live),当键的生存时间到期时,Redis会自动删除该键。为了高效地管理过期键,Redis采用了两种主要的过期策略:定时删除(Active Expiration)和惰性删除(Lazy Expiration)。这两种策略相辅相成,确保了在高并发环境下既能及时删除过期键,又能避免对性能造成过大影响。

1、定时删除(Active Expiration)

(1)、概述

定时删除(Active Expiration)是一种主动的过期策略,Redis会定期检查并删除那些已经过期的键。具体来说,Redis会在后台线程中运行一个定时任务,每隔一段时间扫描一定数量的过期键,并将它们从数据库中删除。

(2)、定时删除的工作原理

  • 过期字典:每个Redis数据库都有一个过期字典(expires字典),用于存储键过期的时间。每当用户为某个键设置了过期时间(例如通过EXPIRE、SETEX、PEXPIRE等命令),Redis会将该键及其过期时间记录到过期字典中。

  • 定时任务:Redis在后台运行一个定时任务,每隔一段时间(通常是100毫秒)检查过期字典中的键。每次检查时,Redis会随机选择一部分桶(bucket),并对这些桶中的键进行过期检查。如果某个键的过期时间已经到达,Redis会立即将其删除。

  • 分批处理:为了避免一次性扫描过多的键导致性能下降,Redis采用分批处理的方式。每次定时任务只会检查一定数量的桶,并且每个桶中只会检查固定数量的键。这样可以确保定时任务不会占用过多的CPU资源,影响其他操作的性能。

  • 自适应调整:Redis会根据系统的负载情况动态调整定时任务的频率和扫描的键数。当系统负载较高时,Redis会减少扫描的频率和键数;当系统负载较低时,Redis会增加扫描的频率和键数,以确保过期键能够及时被删除。

(3)、定时删除的优点

  • 及时性:定时删除策略能够主动检查并删除过期键,确保过期键不会长期存在于内存中,从而减少了内存占用。

  • 防止内存泄漏:通过定期清理过期键,Redis可以有效防止内存泄漏,确保系统的稳定性和可靠性。

(4)、定时删除的缺点

  • CPU开销:虽然Redis采用了分批处理的方式,但定时删除仍然会占用一定的CPU资源,特别是在过期键较多的情况下,可能会对性能产生一定的影响。

2、惰性删除(Lazy Expiration)

(1)、概述

惰性删除是一种被动的过期策略,Redis不会主动检查过期键,而是在访问某个键时才检查其是否已经过期。如果该键已经过期,Redis会立即删除它,并返回相应的结果(如 nil 或 null)。

(2)、惰性删除的工作原理

  • 按需检查:当用户尝试访问某个键时(例如通过GET、HGET、ZSCORE等命令),Redis会首先检查该键是否存在于过期字典中。如果该键存在且已经过期,Redis会立即将其删除,并返回nil或null,表示该键不存在或已过期。

  • 只检查访问的键:惰性删除只会检查那些被访问的键,而不会主动扫描所有键。因此,对于那些从未被访问的过期键,Redis不会立即删除它们,而是等到它们被访问时才会删除。

  • 无CPU开销:由于惰性删除只在访问键时进行检查,因此它不会占用额外的CPU资源,也不会影响其他操作的性能。

(3)、惰性删除的优点

  • 无CPU开销:惰性删除不会主动扫描过期键,因此不会占用额外的CPU资源,适用于高并发场景。

  • 简单高效:惰性删除的实现非常简单,只需在访问键时进行一次检查,减少了代码复杂度和维护成本。

(4)、惰性删除的缺点

  • 延迟删除:惰性删除只会删除那些被访问的过期键,因此对于那些从未被访问的过期键,Redis不会立即删除它们。这可能导致内存占用较高,特别是在大量键过期但未被访问的情况下。

3、Redis实际用的过期策略

为了兼顾及时性和性能,Redis采用了(定时删除 + 惰性删除)的混合策略。

具体来说:

  • 定时删除:Redis会定期扫描并删除过期键,确保过期键不会长期存在于内存中。
  • 惰性删除:当用户访问某个键时,Redis会检查该键是否已经过期,如果是,则立即删除它。

通过这种混合策略,Redis既能够在高并发环境下保持良好的性能,又能够及时删除过期键,防止内存泄漏。

4、过期键的删除流程

前面说的是Redis的键过期的策略,那么发现过期后,Redis是怎么删除的呢?

当Redis决定删除一个过期键时,它会执行以下步骤:
(1)、检查过期时间:Redis首先检查该键是否存在于过期字典中。如果该键存在且已经过期,则进入下一步。

(2)、删除键:Redis会从数据库中删除该键,并更新相关的数据结构(如哈希表、跳跃表等)。如果该键是Hash、List、Set或Sorted Set类型,Redis还会递归删除该键下的所有子元素。

(3)、通知AOF和RDB:如果启用了AOF(Append Only File)持久化,Redis会将删除操作写入AOF文件。如果启用了RDB(Redis Database Backup)持久化,Redis会在下次生成快照时将该键排除在外。

(4)、触发事件:Redis会触发expired事件,通知其他模块或插件该键已被删除。例如,Redis可能会触发Pub/Sub事件,通知订阅者该键已过期。

5、配置参数

Redis 提供了一些配置参数,允许用户调整过期策略的行为:

  • hz:控制Redis的事件循环频率,默认值为10。hz参数决定了Redis每秒钟执行定时任务的次数。较高的hz值可以提高定时删除的及时性,但也可能增加CPU开销。

  • active-expire-effort:控制定时删除任务的强度,默认值为10。active-expire-effort参数决定了每次定时任务扫描的桶数和键数。较高的值可以提高定时删除的效率,但也可能增加CPU 开销。

  • maxmemory-policy:控制Redis在内存不足时的淘汰策略。
    常用的淘汰策略包括:

  • volatile-lru:仅淘汰设置了过期时间的键,使用 LRU(最近最少使用)算法。

  • allkeys-lru:淘汰所有键,使用 LRU 算法。

  • volatile-ttl:仅淘汰设置了过期时间的键,优先淘汰 TTL 较短的键。

  • volatile-random:仅淘汰设置了过期时间的键,随机选择键进行淘汰。

  • allkeys-random:淘汰所有键,随机选择键进行淘汰。

6、过期策略总结

Redis的过期策略通过(定时删除+惰性删除)的混合方式,确保了在高并发环境下既能及时删除过期键,又能避免对性能造成过大影响。定期扫描并删除过期键,确保过期键不会长期存在于内存中,防止内存泄漏。同时在访问键时会检查其是否过期,只删除那些被访问的过期键,避免不必要的CPU开销。通过结合定时删除和惰性删除,Redis既能够在高并发环境下保持良好的性能,又能够及时删除过期键,确保系统的稳定性和可靠性。

7、Redis过期事件监听及实现

在java中,可以通过Redis的Redis Keyspace Notifications来监听Redis键的过期事件。
Redis提供了__keyevent@__:expired通道,当某个键过期时,Redis会发布一条消息到该通道。我们可以通过订阅这个通道来监听键的过期事件。

(1)、Keyspace Notifications(键空间通知)

1、概述

在Redis中,NOTIFY_KEYSPACE_EVENTS是一个配置参数,用于启用和控制Keyspace Notifications(键空间通知)。通过这个参数,Redis可以发布特定类型的事件到Pub/Sub通道,允许客户端监听这些事件。
NOTIFY_KEYSPACE_EVENTS的值是一个字符串,由多个字符组成,每个字符代表一种类型的事件。你可以根据需要组合这些字符来启用或禁用特定的事件类型。

2、常用组合
  • Ex:启用所有过期事件(E表示键事件,x表示过期事件)。这是最常见的组合之一,适用于监听键的过期事件。(比较常用)

  • AKE:启用所有事件(A表示所有事件,K表示键空间事件,E表示键事件)。这个组合会启用所有的键空间和键事件,适用于需要监听所有类型的键变化场景。

  • g:启用通用命令事件。适用于监听对键进行增删改的操作,如DEL、EXPIRE等。

  • Kg:启用键空间事件和通用命令事件。适用于需要监听键的变化以及通用命令操作的场景。

  • Kx:启用键空间事件和过期事件。适用于需要监听键的变化以及键过期事件的场景。

3、解释下E和K区别

E(Keyevent Events)表示键事件
发布到__keyevent@__:通道,包含具体的事件类型和受影响的键名,适用于需要监听具体的命令操作的场景。

如果你需要记录Redis中的所有操作日志,包括每个命令的具体类型,E是一个合适的选择。你可以通过E监听到所有的命令操作,并将这些操作记录到日志文件中,方便后续审计或分析。

K(Keyspace Events)表示键空间事件
发布到__keyspace@__:通道,只包含键的变化信息,不知道到底是什么命令操作的键,适用于只需要监听键的变化的场景。

如,当某个缓存键过期时,你可以通过K监听到expired事件,不用关心具体怎么造成的(人为删除或自动过期等),此时可以立即从数据库中重新加载数据到缓存中。

(2)、java实现步骤

1、启用Redis Keyspace Notifications

要使用Redis的Keyspace Notifications功能,首先需要在Redis配置中启用它。你可以通过修改Redis配置文件(redis.conf)或在启动Redis时传递参数来启用该功能。

方法1:修改redis.conf文件
找到notify-keyspace-events配置项,并将其设置为Ex,表示启用键过期事件的通知:
notify-keyspace-events Ex

方法2:启动指定参数
如果你使用的是Docker或其他方式启动Redis,可以在启动命令中添加参数:

redis-server --notify-keyspace-events Ex

完整示例如:

docker run -d \--name my-redis \-p 6379:6379 \-e REDIS_REPLICATION_MODE=master \-e REDIS_PASSWORD=123456 \-e NOTIFY_KEYSPACE_EVENTS=Ex \-v /path/to/redis-data:/data \redis:latest \redis-server --requirepass 123456 --appendonly no --save "" --notify-keyspace-events Ex

命令参数解释:

  • -d:以守护进程模式(后台运行)启动容器。
  • –name my-redis:为容器指定名称my-redis,方便后续管理和操作。
  • -p 6379:6379:将主机的6379端口映射到容器的637 端口,使得外部可以访 Redis服务。
  • -e REDIS_PASSWORD=123456:设置Redis的密码为123456。Redis客户端在连接时需要提供此密码。
  • -e NOTIFY_KEYSPACE_EVENTS=Ex:启用Keyspace Notifications,允许监听键过期事件(E表示所有事件,x表示过期事件)。
  • -v /path/to/redis-data:/data:将主机的/path/to/redis-data目录挂载到容器的/data目录,用于持久化Redis数据。你可以根据需要更改路径。
  • redis:latest:使用最新的Redis官方镜像。
  • redis-server --requirepass 123456 --appendonly no --save “” --notify-keyspace-events Ex:启动 Redis 服务器,并通过命令行参数进一步配置:
    • –requirepass 123456:设置Redis的密码为 123456。
    • –appendonly no:禁用AOF持久化。
    • –save “”:禁用RDB持久化。
    • –notify-keyspace-events Ex:启用Keyspace Notifications,允许监听键过期事件。
2、Spring Boot实现-1

在Spring Boot项目中实现Redis Key过期事件的监听。
我们先创建RedisMessageListenerContainer,这是Redis的消息事件容器,用于管理Redis的相关事件。
在定义一个监听实现类MessageListener来接收监听,并针对监听做出业务处理。
最后将具体监听实现类添加到Redis事件容器中即可。

(1)、添加依赖
<dependencies><!-- Spring Boot Starter for Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Starter for Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Redis Java Client (Lettuce or Jedis) --><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></dependency>
</dependencies>
(2)、配置文件

在 application.yml 或 application.properties 中配置 Redis 连接信息

spring:redis:database: 0host: localhostport: 6379password: your_password   如果有密码timeout: 10slettuce:max-active: 200max-wait: -1msmax-idle: 10min-idle: 0
(3)、创建Redis配置类

创建一个配置类RedisConfig,用于配置RedisMessageListenerContainer和 MessageListenerAdapter,并订阅 Redis 的过期事件通道。

代码示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;@Configuration
public class RedisConfig {@BeanRedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);// 订阅 __keyevent@0__:expired 通道,监听数据库 0 中的键过期事件container.addMessageListener(listenerAdapter, new PatternTopic("__keyevent@0__:expired"));return container;}@BeanMessageListenerAdapter messageListenerAdapter(KeyExpiredEventReceiver receiver) {// 指定处理方法return new MessageListenerAdapter(receiver, "handleKeyExpiredEvent");}@BeanKeyExpiredEventReceiver keyExpiredEventReceiver() {return new KeyExpiredEventReceiver();   // 具体监听的类}
}
(4)、监听实现类

创建一个KeyExpiredEventReceiver类,用于处理 Redis 发布的键过期事件。我们将在这个类中定义handleKeyExpiredEvent方法,该方法会在接收到过期事件时被调用。

代码示例:

import org.springframework.stereotype.Component;
import org.springframework.messaging.simp.stomp.StompFrameHandler;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;@Component
public class KeyExpiredEventReceiver implements MessageListener {private static final Logger logger = LoggerFactory.getLogger(KeyExpiredEventReceiver.class);@Overridepublic void onMessage(Message message, byte[] pattern) {// 获取过期的键名String expiredKey = message.toString();handleKeyExpiredEvent(expiredKey);}public void handleKeyExpiredEvent(String expiredKey) {logger.info("Key '{}' has expired", expiredKey);// 在这里可以添加自定义逻辑,例如记录日志、触发其他业务操作等}
}
3、Spring Boot实现方式-2

除了上面的方式之外,还支持隐式的实现方式。第1,2步骤同上

(3)、配置类

配置类,只需要注入RedisMessageListenerContainer 管理即可,无需指定订阅的主题

/*** Redis 消息监听器容器.** @param redisConnectionFactory the redis connection factory* @return the redis message listener container*/@Beanpublic RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) {RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);return redisMessageListenerContainer;}/*** Redis Key失效监听器注册为Bean.** @param redisMessageListenerContainer the redis message listener container* @return the redis event message listener*/@Beanpublic RedisEventMessageListener redisEventMessageListener(RedisMessageListenerContainer redisMessageListenerContainer) {return new RedisEventMessageListener(redisMessageListenerContainer);    // 实现类加入到redis事件容器中}
(4)、实现类

通过实现KeyExpirationEventMessageListener ,直接实现了对过期key的监听,而无需在显示指定需要订阅的主题。

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import javax.annotation.Resource;/***  当redis中的key过期时,触发一次事件。*/
@Slf4j
public class RedisEventMessageListener extends KeyExpirationEventMessageListener {@Resourceprivate RedisLock redisLock;/*** Instantiates a new Redis event message listener.* @param listenerContainer the listener container*/public RedisEventMessageListener(RedisMessageListenerContainer listenerContainer) {super(listenerContainer);}@Overrideprotected void doHandleMessage(Message message) {String key = message.toString();      // 过期的keylog.info("开始处理redis过期键-->"+key);// 处理业务逻辑log.info("redis过期键处理完毕!");}
}
4、其他注意事项

(1)、Redis 版本:确保你使用的Redis版本支持Keyspace Notifications。Redis 2.8及以上版本都支持该功能。

(2)、性能影响:启用Keyspace Notifications会对Redis性能产生一定的影响,特别是在大量键过期的情况下。因此,建议在生产环境中谨慎使用,并根据实际需求调整配置。

(3)、多数据库支持:如果你使用了多个Redis数据库(如 db0、db1 等),你需要为每个数据库单独订阅相应的过期事件通道。例如, keyevent@1:expired 表示监听数据库 1 中的键过期事件。

(4)、消息格式:Redis发布的过期事件消息格式为键名本身,因此在onMessage方法中可以直接获取过期的键名。

学海无涯苦作舟!!!

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

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

相关文章

免费生成AI PPT产品推荐?

要完全免费几乎是没有的&#xff0c;要知道AI还是非常烧钱的。 不过免费蹭还是有很多方法的&#xff0c;这里收集了一些&#xff1a; 下面分享我自己免费蹭过的几款AI制作PPT的工具。 1 金山-WPS PPT对我们来说并不陌生&#xff0c;而微软的PowerPoint与金山的WPS也是我们最常…

LeetCode-Golang之【5. 最长回文子串】

给定一个字符串 s&#xff0c;找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1&#xff1a; 输入: “babad” 输出: “bab” 注意: “aba” 也是一个有效答案。 示例 2&#xff1a; 输入: “cbbd” 输出: “bb” 本算法采用 动态规划去解析 func longes…

音频数据采样入门详解 - 给Python初学者的简单解释

音频数据采样入门详解 - 给Python初学者的简单解释 声音是如何变成数字的&#xff1f;什么是采样率&#xff1f;为什么要懂这个&#xff1f;Python小例子总结 大家好&#xff01;今天我们来聊一个有趣的话题&#xff1a;音频数据是如何在计算机中处理的。让我用最简单的方式来解…

Python机器视觉的学习

一、二值化 1.1 二值化图 二值化图&#xff1a;就是将图像中的像素改成只有两种值&#xff0c;其操作的图像必须是灰度图。 1.2 阈值法 阈值法&#xff08;Thresholding&#xff09;是一种图像分割技术&#xff0c;旨在根据像素的灰度值或颜色值将图像分成不同的区域。该方法…

Cisco Packet Tarcer配置计网实验笔记

文章目录 概要整体架构流程网络设备互连基础拓扑图拓扑说明配置步骤 RIP/OSPF混合路由拓扑图拓扑说明配置步骤 BGP协议拓扑图拓扑说明配置步骤 ACL访问控制拓扑图拓扑说明配置步骤 HSRP冗余网关拓扑图拓扑说明配置步骤 小结 概要 一些环境配置笔记 整体架构流程 网络设备互连…

【优选算法】二分算法(在排序数组中查找元素的第一个和最后一个位置,寻找峰值,寻找排序数组中的最小值)

二分算法简介&#xff1a; 提到二分我们可能都会想起二分查找&#xff0c;二分查找要求待查找的数组是有序的&#xff0c;与我们今天讲的二分算法不同&#xff0c;并不是数组元素严格按照有序排列才可以使用二分算法&#xff0c;只要数组中有一个点可以将数组分为两个部分&…

下载与使用PCL启动器(2.8.12正式版)

一.下载PCL启动器 PCL启动器下载官网&#xff1a;爱发电 连接创作者与粉丝的会员制平台将创作的自由还给创作者&#xff01;爱发电是让创作者简单地获得稳定收入的粉丝赞助平台。无论你在创作什么&#xff0c;都能在这里获得持续的资金支持&#xff0c;让创作从此更自由。htt…

【系统思辨】分散注意

注意力在我们的日常生活和工作中扮演着至关重要的角色。注意力可以提高效率和准确性、减少错误和失误&#xff0c;提升学习效率&#xff0c;促进创造力。与此同时&#xff0c;各种各样的生活事件在分散我们的注意力&#xff0c;并且还有很多分散我们注意的手段&#xff0c;比如…

【ArcGIS】基于R语言、MaxEnt模型融合技术的物种分布模拟、参数优化方法、结果分析制图与论文写作

第一章、以问题导入的方式&#xff0c;深入掌握原理基础【理论篇】 1、R语言入门&#xff1a; &#xff08;1&#xff09;安装R及集成开发环境&#xff08;IDE&#xff09;&#xff1b;&#xff08;2&#xff09;R语言基础语法与数据结构&#xff0c;包括&#xff1a;程序包安…

泊松编辑 possion editing图像合成笔记

开源地址&#xff1a; GitHub - kono-dada/Reproduction-of-possion-image-editing 掩码必须是矩形框

江科大笔记—DMA数据转运DMA+AD多通道

1. DMA初始化结构体详解 标准库函数对每个外设都建立了一个初始化结构体xxx_InitTypeDef(xxx为外设名称)&#xff0c;结构体成员用于设置外设工作参数&#xff0c; 并由标准库函数xxx_Init()调用这些设定参数进入设置外设相应的寄存器&#xff0c;达到配置外设工作环境的目的。…

程序算术题-2

程序算术题-2 输出所有组合逻辑实例代码 输出所有排列逻辑实例代码 输出所有组合 计算一组数字按n位数组合的所有组合。 逻辑 /*** param stringBuilder 用于组合的拼接* param list 组合数序列* param level 目前位数* param exceptedLevel 组合期待位数*/…

第十四章:IO流 (java.io包中)

一、理解 1. 简单而言&#xff1a;流就是内存与存储设备之间传输数据的通道、管道。 2. 分类&#xff1a; (1) 按方向(以JVM虚拟机为参照物)【重点】 输入流&#xff1a;将<存储设备>中的内容读入到<内存>中。 输出流&#xff1a;将<内存>中的内容写入到…

MAC M3电脑在idea上搭建Spark环境并跑通第一个程序

我的电脑是Macbook Pro&#xff0c;最近在学习Spark&#xff0c;想要在idea里搭建Spark环境&#xff0c;为之后的Spark编程作准备。下面是在MAC版本的idea里配置Spark环境。 1. 准备工作 1.安装 JDK 确保Mac 上已经安装了 JDK 8 或更高版本。 可通过 java -version 查看是否…

Linux 安装NFS共享文件夹

程序默认使用2049端口&#xff0c;如果被占用需要修改端口104设置为服务端 122设置为客户端 一、在线安装&#xff08;服务端和客户端执行&#xff09; yum install nfs-utils rpcbind -y二、配置启动参数&#xff08;服务端执行&#xff09; 104服务器/mnt路径下创建shareda…

Maven常用插件清单

Maven 是一个强大的项目管理和构建工具&#xff0c;它使用插件来执行各种构建生命周期任务。以下是常用的一些 Maven 构建插件及其主要用途&#xff1a; 1. Maven Compiler Plugin 用途&#xff1a;编译Java源代码。配置示例&#xff1a;<build><plugins><plu…

大模型呼出机器人详解

大模型呼出机器人详解 原作者&#xff1a;开源呼叫中心FreeIPCC&#xff0c;其Github&#xff1a;https://github.com/lihaiya/freeipcc 大模型呼出机器人是基于大规模深度学习模型构建的智能化客服系统&#xff0c;它能够处理海量数据并学习其中的规律&#xff0c;从而实现高…

欧科云链研究院:AI时代,如何证明“我是我”?

OKG Research&#xff5c;编辑 近日&#xff0c;OpenAI 发布了新模型 Sora。这是一款高性能的文本到多模态生成工具&#xff0c;支持从文本生成精细的图像和动态视频。 相较早先发布的视频样例&#xff0c;该功能目前已经可以由用户真实上手体验&#xff0c;目前由于服务过载…

React 进阶深入理解核心概念与高阶实践

在上一节中&#xff0c;我们学习了 React 的基础知识&#xff0c;包括组件、状态管理和基本操作。接下来&#xff0c;我们将进一步探索 React 的高级功能和实战技巧&#xff0c;例如 组件间通信、高阶组件、Context API、React Router 等。这些内容将帮助你构建更复杂、功能更丰…

3.python运算符

Python 提供了多种运算符&#xff0c;用于执行算术、比较、逻辑等各种操作。以下是 Python 中常见的运算符类型及其用法&#xff1a; 文章目录 1. 算术运算符2. 比较运算符3. 逻辑运算符4. 赋值运算符5. 位运算符6. 成员运算符7. 身份运算符8. 运算符优先级 1. 算术运算符 算…