- 键值对的值就有所不同之前了,这里是一个列表对象,列表对象里面包含了三个字符串对象,这三个字符串底层都是由SDS实现的
除了用来保存数据库中的字符串值之外,SDS有时还会被应用在缓冲区(buffer),比如AOF模块中的AOF缓冲区,以及客户端状态中的输入缓冲区,这些都是由SDS来实现的。
SDS的定义
SDS是一个结构体,每一个sdshdr结构表示一个sds值,如下所示
struct sdshdr{
//len记录buf数组中已使用字节的数量
//也可以理解成SDS所保存字符串的长度
int len;
//free记录buf数组中剩余未使用字节的数量
int free;
//字节数组,用于保存字符串
char buf[]
};
举个栗子
-
free属性的值为0,表示这个SDS没有分配任何未使用的空间,即buf数组的空间已经用完了
-
len属性的值为5,代表这个SDS储存了一个五字节长的字符串
-
buf属性是一个char类型的数组(记住是一个字节数组),数组的前5个字节分别为’R’,‘E’,‘D’,‘I’,‘S’,最后一个字符则保存了空字符’\0’。
SDS遵循传统字符串的以空字符结尾,保存空字符的一个字节空间是不计算在SDS的len属性里面的,并且为空字符分配额外的1字节空间,以及添加空字符到字符串末尾等操作,都是由SDS函数自动完成的,所以这个空字符相对于使用者来说是完全透明的。遵循这个,可以让SDS重用一部分C字符串函数库里面的函数
SDS与C字符串的区别
C语言使用长度为N+1的字符数组来表示长度为N的字符串,并且字符数组的最后一个元素总是空字符"\0"。
常数复杂度获取字符串长度
C语言的字符串是没有记录自身长度的信息的(只有整个字符数组的长度),所以为了获取一个C字符串的长度,程序是需要进行遍历的(直到遇到空字符,代表结束),所以时间复杂度为 O ( N ) O(N) O(N)。
SDS与C不同,它有一个len属性,里面记录了自身长度信息,所以获取字符串长度只需直接访问len属性就好了,时间复杂度为 O ( 1 ) O(1) O(1) 。
更新和维护len属性都是由SDS的API在执行时自动完成的,使用者在使用SDS时,无需进行任何手动修改长度的工作。
好处
通过使用SDS而不是C字符串,Redis将获取字符串长度所需的时间复杂度从 O ( N ) O(N) O(N)降为了 O ( 1 ) O(1) O(1),这确保了获取字符串长度的工作不会成为Redis的性能瓶颈,例如,对一个非常长的字符串使用STRLEN命令,即如下
strlen key名字 //用来获取字符串长度
这是不会对系统性能造成任何影响的,因为STRLEN命令的时间复杂度仅为 O ( 1 ) O(1) O(1)。
杜绝缓冲区的溢出
不记录自身长度还会带来一个问题就是很容易造成缓冲区溢出,比如实现两个字符串拼接,如果没有为dest(目标)分配足够多的空间,就会产生缓冲区溢出,举个栗子
比如这里往REDIS后面进行添加字符串"CLUSTER",那么就会变成下面这个样子
由于没有分配足够的空间,拼接的内容就会溢出到后面的内存中,让MONGODB被修改了。
SDS的空间分配策略
SDS的空间分配策略完全杜绝了发生缓冲区溢出的可能性;当SDS API需要对SDS进行修改时,API会先检查SDS的空间是否满足修改的条件要求,如果不满足的话,API会自动将SDS的空间扩展至执行修改所需的大小,这样就不会出现缓冲区溢出的问题了。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
分享
1、算法大厂——字节跳动面试题
2、2000页互联网Java面试题大全
3、高阶必备,算法学习
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**