高级java每日一道面试题-2024年10月1日-服务器篇[Redis篇]-Redis数据结构压缩列表和跳跃表的区别?
如果有遗漏,评论区告诉我进行补充
面试官: Redis数据结构压缩列表和跳跃表的区别?
我回答:
关于Redis数据结构的理解是一个重要的考察点,特别是压缩列表(ziplist)和跳跃表(skiplist)这两种数据结构,它们在内部实现和使用场景上有一些重要的区别。下面是对这两种数据结构的详细解释:
一、定义与基本原理
压缩列表(ziplist)
定义:
- 压缩列表是Redis为了节约内存而设计的一种线性数据结构,它本质上是一个字节数组,可以包含多个元素,每个元素可以是一个字节数组或一个整数。
结构:
- 压缩列表由多个字段组成,包括列表的总字节数(zlbytes)、列表尾元素的偏移量(zltail)、列表的元素数目(zllen),以及若干个元素(entry)和列表的结尾标志(zlend)。每个元素又由前一个元素的长度(previous_entry_length)、元素的类型和长度(encoding)以及元素的值(content)三部分组成。
- 紧凑存储:压缩列表是一种非常紧凑的数据结构,它将多个元素存储在一个连续的内存块中,减少了内存碎片。
- 无指针:压缩列表不使用指针,而是通过偏移量来访问元素,这样可以节省内存空间。
- 变长编码:压缩列表中的每个元素都使用变长编码,根据元素的实际大小来分配空间。
应用场景:
- 压缩列表适用于元素数量少且长度小的场景,如有序集合或哈希。当数据长度或列表长度超过一定阈值时,Redis会考虑使用其他数据结构。
- 小数据集:适用于存储少量的小型数据,如字符串、整数等。
- 有序集合:在 Redis 3.2 及之前的版本中,当有序集合的元素较少且元素长度较短时,Redis 会使用压缩列表来存储有序集合。
操作性能:
- 插入和删除:在压缩列表中插入或删除元素可能需要移动大量数据,因此在大数据集下性能较差。
- 查找:由于没有索引,查找操作需要遍历整个列表,时间复杂度为 O(n)。
内存效率:
- 高效:压缩列表在内存使用上非常高效,因为它避免了指针和额外的空间开销。
跳跃表(skiplist)
定义:
- 跳跃表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。
结构:
- 跳跃表由节点(Node)组成,每个节点包含一个有序元素以及多个层(Level)。每个层都包含一个指向下一个节点的指针,这些指针按照升序排列。节点的层数越多,表示该节点在搜索路径中被访问的可能性越大。此外,跳跃表还包含头节点(Header Node)、长度(Length)和最大层数(Max Level)等字段。
- 多层索引:跳跃表是一种多层索引的数据结构,每一层都包含一个指向下一节点的指针。最底层是一个完整的链表,而上层则是一些稀疏的索引。
- 平衡性:跳跃表通过随机化的方式保持平衡,使得查找、插入和删除操作的时间复杂度平均为 O(log n)。
- 动态调整:跳跃表可以在运行时动态调整层数,以保持高效的查询性能。
搜索操作:
- 在跳跃表中搜索一个元素时,从头节点的最高层开始,沿着指针向下搜索,直到找到目标元素或确定目标元素不存在。这种搜索方式使得跳跃表能够在平均情况下保持较高的搜索效率。
应用场景:
- 跳跃表主要用于实现Redis中的有序集合数据类型,通过跳跃表可以高效地支持元素的按照分数(score)进行排序和检索。
-
- 大数据集:适用于存储大量数据,特别是需要频繁进行查找、插入和删除操作的场景。
- 有序集合:在 Redis 3.2 及之后的版本中,当有序集合的元素较多或元素长度较长时,Redis 会使用跳跃表来存储有序集合。
操作性能:
- 插入和删除:跳跃表的插入和删除操作平均时间复杂度为 O(log n),并且可以通过调整层数来保持高效的性能。
- 查找:跳跃表的查找操作也具有 O(log n) 的平均时间复杂度,比压缩列表的 O(n) 更高效。
内存效率:
- 相对较低:跳跃表在内存使用上不如压缩列表高效,因为它需要维护多层索引和指针。
二、性能对比
查找效率
- 压缩列表的查找操作是顺序查找,时间复杂度为O(n)。
- 跳跃表的查找操作具有平均时间复杂度O(log N),其中N是有序集合的元素数量。这使得跳跃表在查找大量数据时具有显著优势。
内存占用
- 压缩列表:压缩列表是一种内存紧凑型的数据结构,它通过连续的内存空间存储数据,以达到节省内存的目的。然而,当元素数量增多或元素长度增大时,内存占用也会相应增加。
- 跳跃表:跳跃表的空间复杂度为O(n),其中n是节点的数量。虽然跳跃表的每个节点可能包含多个指向其他节点的指针(即所谓的“层”),但整体来看,这些额外的指针并不会显著增加整体的空间占用。
更新操作
- 压缩列表:压缩列表的更新操作可能会导致内存重分配和连锁更新,影响性能。特别是当需要插入或删除元素时,可能需要移动大量数据以保持列表的连续性。
- 跳跃表:跳跃表的插入和删除操作同样可以在平均情况下保持较高的效率。这是因为跳跃表在插入或删除节点时,会根据一定的规则更新节点的位置和数量,以保持整个结构的平衡和稀疏性。
三、选择与应用
选择依据
* 在选择使用压缩列表还是跳跃表时,需要根据具体的应用场景和需求进行权衡。如果元素数量少且长度小,且对内存占用有较高要求,可以考虑使用压缩列表。如果元素数量多且需要快速查找、插入和删除操作,可以选择跳跃表。
Redis中的应用
* 在Redis中,压缩列表被用于实现短小的列表或集合。当数据长度或列表长度超过一定阈值时,Redis会自动将其转换为其他数据结构(如链表或哈希表)。
* 跳跃表则被用于实现有序集合数据类型(如Sorted Set)。通过跳跃表,Redis可以高效地支持元素的按照分数进行排序和检索操作。
总结
-
压缩列表:
- 优点:内存占用少,适合小数据集。
- 缺点:插入和删除操作在大数据集下性能差,查找操作时间复杂度为 O(n)。
- 适用场景:小数据集,少量小型数据。
-
跳跃表:
- 优点:高效的查找、插入和删除操作,适合大数据集。
- 缺点:内存占用相对较高。
- 适用场景:大数据集,频繁的查找、插入和删除操作。
在 Redis 中,选择使用哪种数据结构取决于具体的应用场景和数据规模。对于小数据集,压缩列表是一个更优的选择;而对于大数据集,跳跃表则更为合适。Redis 会根据数据集的大小和配置自动选择合适的数据结构。
相关文章:
高级java每日一道面试题-2024年10月1日-服务器篇[Redis篇]-Redis数据结构压缩列表和跳跃表的区别?
如果有遗漏,评论区告诉我进行补充 面试官: Redis数据结构压缩列表和跳跃表的区别? 我回答: 关于Redis数据结构的理解是一个重要的考察点,特别是压缩列表(ziplist)和跳跃表(skiplist)这两种数据结构&…...
使用 ElLoading 组件来实现加载(loading)功能
在 Element Plus 中,你可以使用 ElLoading 组件来实现加载(loading)功能。ElLoading 通常用于在数据加载或某些异步操作进行时,向用户展示一个覆盖整个页面的加载提示。 以下是如何在你的 Vite Vue 3 JavaScript 项目中使用 El…...
Win10 IDEA连接虚拟机中的Hadoop(HDFS)
获取虚拟机的ip 虚拟机终端输入 ip a关闭虚拟机防火墙 sudo ufw disable修改Hadoop的core-site.xml文件 将localhost修改为虚拟机局域网IP # 位置可能不一样,和Hadoop安装位置有关 cd /usr/local/hadoop/etc/hadoop vim core-site.xmlIDEA 连接 创建Maven项目…...
tp8自带的文件缓存如何配置
TP8自带的缓存是文件缓存。 ThinkPHP6默认的缓存驱动是文件缓存,它将缓存数据存储在应用的runtime目录下的cache目录中。文件缓存适用于单机环境下的应用,对于数据量较小且读写频率较低的应用场景,是一种简单有效的缓存方案。 ThinkPHP8…...
【环境搭建】MAC M1安装ElasticSearch
STEP1 官网下载ES Download Elasticsearch | Elastic,下载mac m1对应版本的es STEP2 进入bin文件夹,执行./elasticSearch 浏览器输入 127.0.0.1:9200 STEP 3 下载对应Kibana版本,Download Kibana Free | Get Started Now | Elastic 出现报错…...
[linux 驱动]网络设备驱动详解
目录 1 描述 2 结构体 2.1 net_device 2.2 sk_buff 2.3 net_device_ops 2.4 ethtool_ops 3 相关函数 3.1 网络协议接口层 3.1.1 dev_queue_xmit 3.1.2 netif_rx 3.1.3 alloc_skb 3.1.4 kfree_skb 3.1.5 skb_put 3.1.6 skb_push 3.1.7 skb_reserve 3.2 网络设备驱…...
【ShuQiHere】 重新定义搜索:本体搜索引擎的时代
🌐 【ShuQiHere】 什么是本体搜索引擎?🤖 本体搜索引擎(Ontological Search Engine, OSE) 是一种基于语义理解和本体结构的智能搜索工具。与传统的关键词搜索不同,本体搜索引擎能够理解搜索背后的深层语义…...
Ruby脚本:自动化网页图像下载的实践案例
随着互联网的快速发展,网页上的内容变得越来越丰富,尤其是图像资源。对于需要大量图像资源的设计师、内容创作者或数据分析师来说,手动下载这些图片不仅耗时耗力,而且效率低下。因此,自动化网页图像下载成为了一个迫切…...
ArcGIS中分区统计栅格值前需要进行投影吗(在投影坐标系下进行吗),为什么?
最近,我接到了一个分区统计栅格数值前需要进行投影,或者说是必须需要在投影坐标系下进行吗的咨询。 答案是不需要刻意去变。 但是他又说他把地理坐标系下分区统计结果与投影坐标系下的分区统计结果分别做了一遍,并进行了对比,两个…...
怎么将视频原声提出来?视频原声提取,让创作更自由
在数字媒体时代,视频已成为我们日常生活和工作中不可或缺的一部分。有时,我们可能想要提取视频中的音频部分,无论是为了制作音频素材、学习语言,还是为了其他创意用途。那么,怎么将视频原声提出来呢?本文将…...
在IDEA里用XDebug调试PHP,断点....
做程序开发,调试必不可少,这里最近用到了PHP,顺便写个关于PHP的调试安装使用: 1、首先是PHP先安装xdebug扩展(还有zend的),这个我的工具是IDEA,所以安装方法也相对简单,如果你是用VSCode等应该也是一样,如下图,找到这个PHP->DEBUG 2、直接点上面的Install XDebug 就可以帮你…...
如何设置 GitLab 密码过期时间?
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料: 极狐GitLab 60天专业…...
重学SpringBoot3-集成Redis(十二)之点赞功能实现
更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(十二)之点赞功能实现 1. 点赞功能的场景分析2. 项目环境配置2.1. 依赖引入2.2. Redis 配置 3. 点赞功能的实现3.1. 点…...
Django-rest-framework(DRF)怎么实现Excel文件导出
目录 一、安装openpyxl库 二、openpyxl库介绍 1、工作簿 a、创建工作簿 b、加载工作簿 c、保存工作簿 2、工作表 a、获取工作表 b、创建和删除工作表 c、工作表属性设置 3、单元格 a、获取单元格 b、合并单元格 C、设置单元格样式 三、django集成openpyxl库 一、…...
零基础MySQL数据库入门一天学完
目录 课程介绍数据库的存在意义数据库历史及MySQL简介MySQL安装指南MySQL客户端工具介绍库操作详解表操作指南单表查询技巧多表查询实践MySQL函数速览新增、修改、删除操作索引优化策略视图应用实例事务处理机制数据备份与恢复日常维护与安全建议 1. 课程介绍 本指南旨在为初…...
【CSS Tricks】鼠标滚轮驱动css动画播放,使用js还是css?
目录 引言一、js实现1. 实现思路2. 实现案例3. 看下效果 二、css实现1. 代码修改2. 属性介绍2.1 看下浏览器支持性2.2 常用属性值2.2.1 scroll()2.2.2 view() 三、总结 引言 本篇为css的一个小技巧 页面中的动画效果随着滚轮的转动…...
《Electron 基础知识》设置 Vue 中引用的文件路径别名
vite.renderer.config.mjs 文件中配置 代码第1行,引入 resolve ;代码第 6 - 10 行,设置路径别名,注意没有后缀 /; import { resolve } from pathexport default defineConfig((env) > {return {resolve: {alias: …...
day 20 二叉树 part05
654.最大二叉树 注意类似用数组构造二叉树的题目,每次分隔尽量不要定义新的数组,而是通过下标索引直接在原数组上操作,这样可以节约时间和空间上的开销。 题目链接/文章讲解:代码随想录 lass Solution { private:// 在左闭右开…...
003 Springboot操作RabbitMQ
Springboot整合RabbitMQ 文章目录 Springboot整合RabbitMQ1.pom依赖2.yml配置3.配置队列、交换机方式一:直接通过配置类配置bean方式二:消息监听通过注解配置 4.编写消息监听发送测试5.其他类型交换机配置1.FanoutExchange2.TopicExchange3.HeadersExcha…...
小猿口算脚本
实现原理:安卓adb截图传到电脑,然后用python裁剪获得两张数字图片,使用ddddocr识别数字,比较大小,再用adb命令模拟安卓手势实现>< import os import ddddocr from time import sleep from PIL import Imagedef …...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
