11天 -- Redis 中跳表的实现原理是什么?Redis 的 hash 是什么?Redis Zset 的实现原理是什么?
Redis 中跳表的实现原理是什么?
Redis 中的跳表(Skip List)是一种基于有序链表的高效数据结构,通过在链表上增加多级索引来提高数据的查找效率。以下是 Redis 中跳表的实现原理:
1. 基本概念
节点结构:跳表中的每个节点包含多个层,每层都有一个前进指针指向同一层级的下一个节点。每个节点还包含一个跨度属性,表示该节点到下一个节点的距离(在同一层级上)。底层包含所有元素,每上升一层,节点数量逐渐减少。
多级索引:跳表通过在不同层级上增加指针来加速查找。每一层都是一个有序链表,且高层链表的节点数量逐层减少。
2. 查找操作
查找过程:从最高层开始,通过前进指针逐层向下查找。如果当前节点的下一个节点的值小于要查找的值,则向右移动;如果大于要查找的值,则向下移动。重复上述过程,直到找到目标节点或确定目标节点不存在。
3. 插入操作
查找插入位置:首先进行查找操作,找到插入位置。
随机生成层数:根据预设的概率(如 0.5)随机生成一个层数,决定新节点的层数。
插入新节点:在每一层中插入新节点,并更新相关节点的前进指针。
4. 删除操作
查找要删除的节点:首先进行查找操作,找到要删除的节点。
更新指针:在每一层中删除该节点,并更新相关节点的前进指针。
5. 优势
高效性:跳表在平均情况下的时间复杂度为 O(log n),与红黑树相当,但实现起来更简单。支持动态操作(插入、删除、查找),并且在维护平衡性和有序性时的性能表现良好。
简洁性:跳表不需要复杂的平衡操作(如旋转),更容易实现和调试。在内存中的额外空间用于维护多级索引,但相对于整个数据集来说通常是可以接受的
并发友好:跳表的简单结构使得并发操作更为容易实现。在 Redis 中,跳表支持高效的并发访问和修改操作。
6. Redis 中的实现细节
节点定义:Redis 中的跳表节点由 zskiplistNode 结构定义,包含元素值、分值(用于排序)、多个层(每层包含前进指针和跨度)以及一个后退指针(指向前一个节点)。
跳表结构:Redis 中的跳表由 zskiplist 结构定义,保存了跳表节点的相关信息,如头节点、尾节点、节点数量和最大层数。
通过以上实现原理,Redis 中的跳表能够高效地支持插入、删除和查找操作,同时保持元素的有序性,非常适合实现如排行榜、范围查询等功能。
Redis 的 hash 是什么?
Redis 的 Hash 是一种非常灵活且高效的数据结构,用于存储键值对集合。它类似于其他编程语言中的字典或哈希表,能够以字段(field)和值(value)的形式存储数据。Redis 的 Hash 数据结构在实际应用中非常广泛,例如存储对象、缓存数据、统计信息等。
一、基本概念
Redis 的 Hash 是一个键值对集合,其中键(key)是唯一的,值(value)可以是任意类型的数据。Hash 的键和值都是字符串类型,但 Redis 提供了丰富的操作命令来处理这些数据。
二、数据结构
Redis 的 Hash 在底层使用哈希表实现,具有以下特点:
- 键值对存储:每个 Hash 包含多个字段(field)和对应的值(value)。
- 唯一性:字段名在同一个 Hash 中是唯一的,不能重复。
- 动态扩展:当 Hash 中的元素数量增加时,Redis 会自动扩展底层的哈希表,以保持高效的查找性能。
三、基本操作命令
Redis 提供了一系列命令来操作 Hash 数据结构,以下是一些常用的命令:
1. HSET
用于向 Hash 中添加一个字段及其对应的值。
HSET key field value
示例:
HSET user:1 name "Alice"
2. HGET
用于获取 Hash 中指定字段的值。
HGET key field
示例:
HGET user:1 name
3. HDEL
用于删除 Hash 中的一个或多个字段。
HDEL key field [field ...]
示例:
HDEL user:1 age
4. HKEYS
用于获取 Hash 中所有字段的名称。
HKEYS key
示例:
HKEYS user:1
5. HVALS
用于获取 Hash 中所有字段的值。
HVALS key
示例:
HVALS user:1
6. HLEN
用于获取 Hash 中字段的数量。
HLEN key
示例:
HLEN user:1
7. HMSET
用于同时设置 Hash 中多个字段的值。
HMSET key field value [field value ...]
示例:
HMSET user:1 name "Alice" age 25
8. HMGET
用于同时获取 Hash 中多个字段的值。
HMGET key field [field ...]
示例:
HMGET user:1 name age
9. HINCRBY
用于将 Hash 中指定字段的值增加一个整数。
HINCRBY key field increment
示例:
HINCRBY user:1 age 1
10. HSCAN
用于迭代 Hash 中的字段和值。
HSCAN key cursor [MATCH pattern] [COUNT count]
示例:
HSCAN user:1 0
四、应用场景
Redis 的 Hash 数据结构在实际应用中非常广泛,以下是一些常见的应用场景:
- 存储对象:可以将一个对象的所有属性存储在一个 Hash 中,例如用户信息、商品信息等。
- 缓存数据:可以将常用的数据缓存到 Redis 的 Hash 中,提高数据访问速度。
- 统计信息:可以使用 Hash 来统计各种信息,例如用户的行为统计、商品的销售统计等。
五、优点
- 高效性:Redis 的 Hash 数据结构具有高效的查找性能,能够快速获取和修改数据。
- 灵活性:可以存储任意数量的字段和值,字段名和值都可以是任意字符串。
- 丰富的操作命令:提供了丰富的操作命令,能够满足各种数据操作需求。
六、缺点
- 内存占用:相比于简单的字符串类型,Hash 数据结构可能会占用更多的内存。
- 数据一致性:在分布式环境下,需要考虑数据一致性的问题。
总的来说,Redis 的 Hash 数据结构是一种非常强大且灵活的数据结构,能够满足各种数据存储和操作需求。
Redis Zset 的实现原理是什么?
Redis 的 Zset(有序集合)是一种功能强大且应用广泛的数据结构,它结合了哈希表(Hash Table)和跳表(Skip List)的优势,实现了高效的元素插入、删除和范围查询操作。以下是 Redis Zset 的实现原理:
1. 基本概念
- 唯一性:Zset 中的每个元素都是唯一的,不能重复。
- 分数关联:每个元素都有一个与之关联的分数,分数为双精度浮点数。
- 有序性:Zset 中的元素按照分数从低到高进行排序;当多个元素的分数相同时,按照字典序升序排列。
2. 内部数据结构
Redis 的 Zset 使用两种主要的数据结构来实现:
- 哈希表(Hash Table):
- 用于存储元素与其分数的映射关系,支持 O(1) 的查找和更新。
- 跳表(Skip List):
- 用于维护元素的有序性,支持快速的范围查询和顺序访问。
3. 编码实现
Redis 在实现 Zset 时会根据元素数量和其他因素选择不同的编码方式,主要包括两种编码策略:
- ZIPLIST 编码:
- 当 Zset 中的元素数量较少,并且元素分数和字符串长度较小的时候,Redis 会选择使用
ziplist编码。这是一种内存紧凑的存储格式,通过连续的内存块存储多个元素,极大地节省了内存空间。
- 当 Zset 中的元素数量较少,并且元素分数和字符串长度较小的时候,Redis 会选择使用
特点:
- 内存紧凑,减少了额外的指针和元数据开销。
- 适用于小规模数据,性能和内存占用更优。
- 操作效率较高,但在元素较多时,操作效率会下降。
SKIPLIST + DICT 编码:
- 当 Zset 中的元素数量较多或分数和字符串长度较大时,Redis 会使用
skiplist + dict编码。这种编码方式结合了哈希表和跳表的优势,支持高效的查找、插入和范围查询。
特点:
- 哈希表用于快速查找和更新元素。
- 跳表用于维护元素的有序性,支持快速的范围查询。
4. 编码切换条件
Redis 会根据 Zset 的实际情况动态切换编码方式:
- 从 ZIPLIST 切换到 SKIPLIST + DICT:
- 当 Zset 中的元素数量超过
zset-max-ziplist-entries(默认为 128)时。 - 当 Zset 中的元素分数和长度超过
zset-max-ziplist-value(默认为 64 字节)的限制时。
- 当 Zset 中的元素数量超过
从 SKIPLIST + DICT 切换到 ZIPLIST:
- 当 Zset 中的元素数量和分数精度低于相应阈值时,Redis 可以选择将其重新编码为 ziplist,以节省内存。
5. 操作命令
Redis 提供了一系列命令来操作 Zset,以下是一些常用的命令:
- ZADD:向 Zset 中添加一个或多个元素。
- ZREM:从 Zset 中删除一个或多个元素。
- ZSCORE:获取 Zset 中某个元素的分数。
- ZRANGE 和 ZREVRANGE:按索引范围获取 Zset 中的元素,前者按分数升序排列,后者按分数降序排列。
- ZRANGEBYSCORE 和 ZREVRANGEBYSCORE:获取 Zset 中分数在指定范围内的元素,前者按分数升序排列,后者按分数降序排列。
6. 优势
- 高效性:Zset 在不同操作场景下都能够保持高效的性能,支持快速的查找、插入和范围查询。
- 灵活性:可以存储任意数量的元素,元素和分数都可以是任意字符串。
- 丰富的操作命令:提供了丰富的操作命令,能够满足各种数据操作需求。
总的来说,Redis 的 Zset 是一种非常强大且灵活的数据结构,能够满足各种数据存储和操作需求。
相关文章:
11天 -- Redis 中跳表的实现原理是什么?Redis 的 hash 是什么?Redis Zset 的实现原理是什么?
Redis 中跳表的实现原理是什么? Redis 中的跳表(Skip List)是一种基于有序链表的高效数据结构,通过在链表上增加多级索引来提高数据的查找效率。以下是 Redis 中跳表的实现原理: 1. 基本概念 节点结构:跳…...
单细胞分析(19)—— 单细胞转录组基因集评分方法
下面是每种基因集评分方法的原理介绍代码示例,适用于R语言和Python两种主流生信分析环境。可以直接应用于单细胞转录组(scRNA-seq)数据分析中。 🔬 单细胞转录组基因集评分方法(附代码示例) 在单细胞RNA测…...
010 rocketmq批量消息
文章目录 批量消息BatchProducer.javaBatchConsumer.java 批量消息 批量发送可以提⾼发送性能,但有⼀定的限制: topic 相同 waitStoreMsgOK 相同 (⾸先我们建设消息的iswaitstoremsgoktrue(默认为true), 如果没有异常,我们将始终收到"O…...
JavaWeb后端基础(3)
原打算把Mysql操作数据库的一些知识写进去,但是感觉没必要,要是现在会的都是简单的增删改查,所以,这一篇,我直接从java操作数据库开始写,所以这一篇大致就是记一下JDBC、MyBatis、以及SpringBoot的配置文件…...
Oracle数据库基础入门(三): DQL 深入解析与实践
在 Oracle 数据库的知识体系中,数据查询语言(DQL)无疑是最为常用且关键的部分之一。对于 Java 全栈开发者而言,熟练掌握 DQL 不仅能高效地从数据库中获取所需数据,更是构建强大后端应用的基石。通过 DQL,我…...
P9231 [蓝桥杯 2023 省 A] 平方差
P9231 [蓝桥杯 2023 省 A] 平方差 - 洛谷 题目描述 给定 L,R,问 L≤x≤R 中有多少个数 x 满足存在整数 y,z 使得 xy2−z2。 输入格式 输入一行包含两个整数 L,R,用一个空格分隔。 输出格式 输出一行包含一个整数满足题目给定条件的 x 的数量。 输…...
贪心算法 求解思路
贪心算法简介 贪心算法是通过做一系列的选择来给出某一问题的最优解。对算法中的每一个决策点,做一个当时(看起来是)最佳的选择。这种启发式策略并不是总能产生出最优解,但它常常能给出最优解。 在实际设计贪心算法时࿰…...
2025/2/25,字节跳动后端开发一面面经
一、双方简单自我介绍 面试官先自我介绍,之后属于面试官看简历过程,基本不听。 二、实习中遇到最难的事情,怎么解决的 主要问的还是实习中做过的项目,项目难点在哪里(自己参与的地方),面对困难是怎么思考,怎么实际操作解决的。 三、项目实现细节 掌握自己项目的实…...
Buildroot 添加自定义模块-内置文件到文件系统
目录 概述实现步骤1. 创建包目录和文件结构2. 配置 Config.in3. 定义 cp_bin_files.mk4. 添加源文件install.shmy.conf 5. 配置与编译 概述 Buildroot 是一个高度可定制和模块化的嵌入式 Linux 构建系统,适用于从简单到复杂的各种嵌入式项目. buildroot的源码中bui…...
SpringBoot新闻推荐系统设计与实现
随着信息时代的快速发展,新闻推荐系统成为用户获取个性化内容的重要工具。本文将介绍一个幽络源的基于SpringBoot开发的新闻推荐系统,该系统功能全面,操作简便,能够满足管理员和用户的多种需求。 管理员模块 管理员模块为系统管…...
领域驱动设计:事件溯源架构简介
概述 事件溯源架构通常由3种应用设计模式组成,分别是:事件驱动(Event Driven),事件溯源(Event Source)、CQRS(读写分离)。这三种应用设计模式常见于领域驱动设计(DDD)中,但它们本身是一种应用设计的思想,不仅仅局限于DDD,每一种模式都可以单独拿出来使用。 E…...
基于Java+Spring+Mybsita+mysql的汽租车辆共享平台的设计源码+设计文档
文末获取源码数据库文档 感兴趣的可以先收藏,有毕设问题,项目以及论文撰写等问题都可以和博主沟通,尽最大努力帮助更多的人! 目录 1软件需求 1.1引言 1.1.1编写目的 1.1.2背景 1.2 绪论 1.2.1-Internet与…...
深度学习的正则化深入探讨
文章目录 一、说明二、学习目标三、什么是机器学习中的正则化四、了解过拟合和欠拟合五、代价函数的意义六、什么是偏差和方差?七、机器学习中的正则化? 一、说明 在训练机器学习模型时,模型很容易过拟合或欠拟合。为了避免这种情况…...
Token相关设计
文章目录 1. 双Token 机制概述1.1 访问令牌(Access Token)1.2 刷新令牌(Refresh Token) 2. 双Token 认证流程3. Spring Boot 具体实现3.1 生成 Token(使用 JWT)3.2 解析 Token3.3 登录接口(返回…...
【时序预测】在线学习:算法选择(从线性模型到深度学习解析)
——如何为动态时序预测匹配最佳增量学习策略? 引言:在线学习的核心价值与挑战 在动态时序预测场景中(如实时交通预测、能源消耗监控),数据以流式(Streaming)形式持续生成,且潜在的…...
React antd的datePicker自定义,封装成组件
一、antd的datePicker自定义 需求:用户需要为日期选择器的每个日期单元格添加一个Tooltip,当鼠标悬停时显示日期、可兑换流量余额和本公会可兑流量。这些数据需要从接口获取。我需要结合之前的代码,确保Tooltip正确显示,并且数据…...
学生管理前端
文章目录 首页student.html查询功能 首页 SpringBoot前端html页面放在static文件夹下:/src/main/resources/static 默认首页为index.html,我们可以用两个超链接或者两个button跳转到对应的页面。这里只是单纯的跳转页面,不需要提交表单等其…...
深入理解并实现自定义 unordered_map 和 unordered_set
亲爱的读者朋友们😃,此文开启知识盛宴与思想碰撞🎉。 快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 在 C 的标准模板库(STL)中,unorder…...
顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-大模型电话机器人
语音流直接对接Realtime API 多模态大模型 直接把音频流输出给大模型,大模型返回音频流。 顶顶通CTI对Realtime API 的支持 提供了以下2个APP可对接任意 •cti_audio_stream 通过TCP推流和播放流,适合用于人机对话场景。 •cti_unicast_start 通过旁…...
kinova机械臂绿色灯一闪一闪及刷机方法
一、背景 实验室有两个kinova mico机械臂,但经常出现操纵杆上的绿色灯一闪一闪的,导致无法使用操纵杆或ROS进行控制,下面给出官方的教程以及所需要的FS 0CPP 0008_6.2.5_mico_6dof.hex文件。 重要的东西写在前面: a、如果出现操…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
