【Redis-09】面试题之Redis数据结构与对象-RedisObject(下篇)

news2024/11/16 18:58:37

 承接上篇【Redis-08】面试题之Redis数据结构与对象-RedisObject(上篇)

8. type-字符串string

在这里插入图片描述

8.1 字符串的三种encoding编码(int + embstr + raw)

  • 如果保存的是整型,并且可以用long类型标识(-9223372036854775808到9223372036854775807),encoding取值为 int
  • 如果是浮点数 + 整型(long类型无法表达) + 字符串,且长度 ≤ 44个字节,encoding 取值为 embstr
  • 如果是浮点数 + 整型(long类型无法表达) + 字符串,且长度 > 44个字节,encoding 取值为 raw
    想知道为什么是44个字节吗?点击这里https://blog.csdn.net/u013099854/article/details/115399466
    在这里插入图片描述
    在这里插入图片描述

8.1.2 embstr 和 raw两种编码

 这两种编码内部封装的都是sds,站在使用者的角度而言,没什么区别;在底层内存分配及部分操作时,还是有一些不同的,主要体现在以下几点:

  1. embstr是用于保存短字符串的优化编码方式,且embstr编码的字符串对象是只读的,对此编码进行任何的写操作,都会导致字符串变为raw的编码方式;raw是用于保存长字符串的编码方式。
  2. embstr在内存分配和内存释放的时候,只需调用一次对应的函数;而raw需要调用两次内存分配和释放的函数来完成对应的过程;
  3. embstr编码的字符串对象所有的数据都是保存在一块连续的内存里,而raw不一定。

 embstr内存连续,如下图:
在这里插入图片描述
 raw内存不连续,如下图:
在这里插入图片描述

8.1.3 编码转换

  • 整数型经过某些操作,比如append、setrange; encoding: int -> raw
  • 整数型涉及到浮点数的操作,比如incrbyfloat; encoding:int -> embstr或raw
  • 短字符串经过某些写的操作,比如append、setrange; encoding : embstr -> raw
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

9 type-集合set

在这里插入图片描述
 redis中,set的类型是借助于intset和dict来实现的,与其他结构一样,在某些条件下,set的编码类型会发生变化。我们来看下,set在哪些情况下使用intset,哪些情况下使用dict。

9.1 类型转换

  • 我们创建一个set,写入 1、 3、 5、 7 这样的整数值时,set的encoding是intset,但是如果我们写入非整数 a,就会变成 dict 类型。
  • 我们创建一个set,写入 1、 3、 5、 7 这样的整数值时,set的encoding是intset,但是如果我们写入的整数 >264-1,就会变成 dict 类型。
  • 当set的元素超过 512 个时,编码类型会从 intset转为 dict,这个值也是在redis.conf的配置文件中定义的。
    在这里插入图片描述
     看下面的几个例子:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

9.2 两种类型比较

 我们看下set在不同编码下的数据结构,下图分别是intset 和 dict的实现:
在这里插入图片描述
在这里插入图片描述
 在set较小的时候,使用intset可以节省内存,因为dict要维护两个哈希表,链表指针及其他大量元数据,而intset是一整块连续的内存。但是dict的平均查找效率是高于intset的,dict可以支持O(1)的时间复杂度,而intset是有序的整数集合,可以做二分查找,时间复杂度是O(log n)。

 这里需要说明一点的是,如果set使用dict作为底层实现,key是set的元素值,而 value = null。

10 type-哈希hash

在这里插入图片描述
 hash是我们在redis中存储对象比较理想的数据结构,每个对象的属性正好可以对应hash的每个field。hash的底层数据结构就是基于压缩列表和字典这两种类型实现的。

10.1 encoding的编码转换

 当hash对象可以同时满足下面2个条件时,使用的是ziplist,否则就是dict。

  • 哈希对象保存的所有键值对的键和值字符串长度都 ≤ 64个字节;
  • 哈希对象保存的键值对的数量 ≤ 512个;
    在这里插入图片描述

10.2 举例说明

  • 下面这个案例,aa是64个字节,bb是65个字节

在这里插入图片描述

  • 下面这个案例,numbers1是512个键值对,numbers2是513个键值对
    在这里插入图片描述

11 type-有序列表 sorted set

在这里插入图片描述

  Redis中的sorted set,其实是在ziplist,skiplist和dict的基础上共同构建而来的,在不同的场景下,使用的数据结构是不一样的。决定使用哪种数据结构,涉及到redis.conf中的两个配置参数,分别是 zset-max-ziplist-entries 和 zset-max-ziplist-value。

在这里插入图片描述

  • 如果有序集合中的元素数量≤128(对应的ziplist中entry的个数就是128*2=256个),并且所有元素的长度都≤64个字节的时候,就会使用ziplist作为底层的结构实现。
  • 如果有序集合中的元素数量超过128个,或者某个元素成员对象的长度超过64个字节的时候,就会使用zset的数据结构,而zset的数据结构其实就是由1个dict + 1个 zskiplist结构组成的。
    在这里插入图片描述
    在这里插入图片描述

11.1 使用 ziplist 的数据结构

 前面我们了解到ziplist是占用了一大块连续的内存,他的数据项都是相邻的。在数据项较少的时候,我们向有序集合中插入一条数据,ziplist上面就会插入两个entry节点,成员对象ele在前,分数score在后面,而且这些元素都是按照分值从小到大进行排序保存的。它的优势就是节省内存开销,支持从前往后或者从后往前的顺序查找。

 如果我们执行了这样一条命令,向学生有序集合中插入分数和姓名,他的类型就是ziplist:

在这里插入图片描述

 那么数据结构就是这样的
在这里插入图片描述

11.2 使用 dict + zskiplist 的数据结构

 在数据量比较多的时候,有序集合使用了 dict + zskiplist两种结构共同来实现。dict用于保存数据与分值之间的对应关系,key=成员对象,value=分值,这也是为什么数据值如果相同,后者会覆盖前者的原因。 而zskiplist用于使用分数来查找数据,也支持范围内的查找。虽然zset同时使用了字段和跳跃表,但是这两种数据结构都会通过指针来共享相同的元素和分值,所以不会产生重复的数据,也不会额外占用内存。

 如果我们执行了这样一条命令,向学生有序集合中插入分数和姓名,他的类型就是skiplist(zset):
在这里插入图片描述

11.3 编码的转换

 我现在分别写入128个元素和129个元素、长度为64和长度为65的元素,看一下他们的encoding的编码类型是什么。

在这里插入图片描述

在这里插入图片描述

 可以看到,上面两种情况的encoding编码值确实发生了变化。

 理论上,有序集合可以单独使用dict或者zskiplist来实现,但是为什么要使用两者结合呢,是因为无论单独使用哪一种,在性能上对比起同时使用两者时性能都会有所下降。下面我们看个例子:

在这里插入图片描述

 如果仅使用zskiplist,现在查找dd的排序:首先我们现在知道的是成员对象,而不是分值,所以就没有办法在O(log n)的时间复杂度下找到对应的节点,只能循环遍历,从头开始找,每循环一个对比一下 ele ?= dd,直到命中为止,时间复杂度就是O(n);

 而现在zset借助了dict,首先根据key=dd找到对应的value,这一步在哈希值冲突较小的前提下时间复杂度是O(1),而找到分值score后,借助于zskiplist的特性在O(log n)的时间复杂度下找到dd这个节点,然后再把沿途的跨度数值加起来,就是dd的排位。

在这里插入图片描述

12 type-列表list

在这里插入图片描述

12.1 编码类型

 redis中列表list就是借助于quicklist来实现的,而且只有这一种编码类型。
在这里插入图片描述

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

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

相关文章

《InnoDB引擎七》InnoDB关键特性-插入缓存

InnoDB 关键特性 InnoDB存储引擎的关键特性包括: Insert Buffer (插入缓冲)Double Write (两次写)Adaptive Hash Index (自适应哈希索引)Async IO (异步IO)Flush Neighbor Page (刷新领接页) 这些特性为InnoDB存储引擎带来了更好的性能以及更高的可靠性。 插入缓冲…

2023年湖北监理工程师考试时间、报名时间、报考条件是什么?

2023年湖北监理工程师考试时间、报名时间、报考条件是什么? 一、2023年湖北监理工程师考试时间: 参考往年的监理工程师考试时间,预计考试时间为5月份。 二、2023年湖北监理工程师报名时间: 2023年湖北监理工程师报名时间预计3月份…

单例模式【JavaEE初阶】

一、单例模式的概念 单例模式是一种常见的设计模式 。单例模式希望:有些对象,在一个程序中应该只有唯一一个实例,就可以使用单例模式 。换句话说,在单例模式下,对象的实例化被限制了,只能创建一个&#xff…

Mybatis源码解析(七):Mapper代理原理

Mybatis源码系列文章 手写源码(了解源码整体流程及重要组件) Mybatis源码解析(一):环境搭建 Mybatis源码解析(二):全局配置文件的解析 Mybatis源码解析(三):映射配置文件的解析 Mybatis源码解析(四):s…

使用R语言对S&P500股票指数进行ARIMA + GARCH交易策略

在本文中,我想向您展示如何应用S&P500股票市场指数的交易策略。最近我们被客户要求撰写关于交易策略的研究报告,包括一些图形和统计输出。 通过组合ARIMA GARCH模型,从长期来看,我们可以超过“买入并持有”方法。 相…

【MySQL基础】常用指令详解

如果看不清未来,就走好当下的路,做你此刻该去做的事。——《冰雪奇缘2》 目录 1、进入和退出mysql 1.1进入mysql 1.2退出mysql 2、查看mysql中有哪些数据库 2.2.创建数据库 3、使用数据库 3.1开始使用数据库 3.2展示数据库中的表 4、查看表中的…

跨境电商面临“寒冬”考验,如何转型升级入局新赛道(Starday)

近几年随着互联网和高新技术的飞速发展,加之疫情下各国海外贸易政策的管理,跨境贸易模式不断地创新升级,现今的跨境贸易模式已经从线下交易上升为线上交易,各种基于互联网商务网站的电子商务业务和网络公司开始不断地涌现&#xf…

WebDAV之葫芦儿•派盘+FolderSync

FolderSync 支持WebDAV方式连接葫芦儿派盘。 随着业务发展,文件数据增长,如文档更新、资料下载、拍照录像等。如何更好的管理这些资料,不出现丢失的问题就成为了一个很大的问题。也正是有了类似的需求,现在网络上出现了很多的文件同步备份软件。那么,文件同步备份软件哪…

Thread类的start()方法创建线程的底层分析

在Java中通过如下简单代码就可以创建一个新线程 Thread thread new Thread(new Runnable() {Overridepublic void run() {//do something} }); thread.start(); 在start()中又调用了start0(),它才是真正创建线程的方法。 public synchronized void start() {gro…

安全机制(security) - 加解密算法 - 对称加密 - 加解密模式

说明 大部分对称加密算法支持多种加密模式,每种模式的运算结果也不相同。加解密模式是分组加密算法通用的机制,不同算法可能支持相同的加密模式,不同算法支持的加密模式也可能不同。加密和解密需要使用相同的模式才能得到正确的结果。不同的…

CANOE功能介绍

1.CANoe主界面 当计算机安装完CANoe后,用户只需选择“开始”→“所有程序 ”→Vector CANoe 11.0→CANoe 11.0 系 统 菜 单 命 令 即 可 启 动CANoe。 为了快速熟悉CANoe的常用功能,我们可以打开Vector官方的自带例程,一边学习一边实践相关功…

超算/先进计算如何改变现如今对的生活

算力作为新一代的“石油”,与超算/先进计算有着不可分割的紧密联系。 通俗而言,算力泛指计算能力,即数据处理能力。算力大小代表数据处理能力的强弱。从远古的结绳计算到近代的机械式计算,再到现代的数字电子计算,特别…

Ajax学习:设置CROS响应头实现跨域(跨域资源共享)

CROS:跨域资源共享、是官方的跨域解决方案&#xff0c;特点不需要在客户端做任何特殊的操作&#xff0c;完全在服务器中处理&#xff08;支持get post 等&#xff09; 客户端做ajax请求&#xff0c;服务端做相应头设置就可以实现跨域&#xff1a; <!DOCTYPE html> <h…

如何快速构建研发效能度量的指标体系?

本月初&#xff0c;没毛病软件公司的研发总监 Kevin 在参加完公司管理层月度例会后&#xff0c;心情非常糟糕...... 刚才会议中&#xff0c;老板很严肃地问研发总监 Kevin&#xff1a;“我在会议前接到了客户的投诉电话&#xff0c;说产品出现了 Bug&#xff0c;这已经不是第一…

.net-----Windows 窗体应用程序包括控件,对话框,多重窗体,绘制图形,菜单和工具栏

目录前言Windows窗体应用程序概述&#xff1b;窗体和大部分控件常用的事件创建Windows窗体应用程序使用Visual Studio集成开发环境实现Hello World程序使用常用Windows窗体控件&#xff1b;Label、TextBox、RichTextBox、Button应用示例单选按钮、复选框和分组【例】RadioButto…

(附源码)springboot物流配货管理系统 毕业设计 250858

基于springboot物流配货管理系统的设计与实现 摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题.针对物流配货等问题,对物流配货进行研究分析,然后…

电力系统机组组合优化调度(IEEE14节点、IEEE30节点、IEEE118节点)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f4dd;目前更新&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;电力系统相关知识&#xff0c;期刊论文&…

数云融合丨知识图谱在烟草零售数字化转型中的应用

一、知识图谱的趋势 随着互联网、云计算、大数据、人工智能等信息数据技术的快速发展&#xff0c;计算机的智能化程度也越来越高&#xff0c;知识图谱作为人工智能的核心技术&#xff0c;其在数据集成、语义表示和逻辑推理等方面存在着得天独厚的优势。 2021年&#xf…

Java并发-交替打印的四种方法。

1 前言 如下图所示&#xff0c;现在有两个线程A,B&#xff1b;A打印12345&#xff0c;B打印abcde&#xff0c;结果为1a2b3c4d5e交替输出。 1.1 采用wait和notify 【分析】我们要求线程A始终先打印&#xff0c;因此在线程B先获得CPU使用时间时也应该阻塞。 细节 线程A应该打印…

【人工智能/算法】搜索求解(Solving Problemsby Searching)

文章目录一、求解与搜索二、盲目式搜索1. 深度优先搜索&#xff08;Depth First Search, DFS&#xff09;回溯搜索&#xff08;Backtracking Search&#xff09;2. 广度优先搜索&#xff08;Breadth First Search, BFS&#xff09;一致代价搜索&#xff08;Uniform-cost Search…