将截断字符串或二进制数据_「常见面试题」如何设计一个扩容方便且二进制安全的字符串...

hello,大家好。欢迎坐客老张的读书圈,这里专注于好书内容分享。

上一期我们介绍了本书的引言部分 redis为何性能如此强悍。其中也提到了专门设计的数据结构。这期一起来看第二章redis 字符串的结构《简单动态字符串》 大家也知道这个名称是根据英文 Simple Dynamic String 直译过来的。

作者在本章开头就提出了一个问题让大家思考: 如何实现一个扩容方便且二进制安全的字符串?不知道这个问题你有没有被面试官问到过,反正老张是被问到过。

3cd04c37dc43ff31eda043dd06490b9b.png

女面试官

大家知道在C语言中,用"0" 表示字符串的结束,如果字符串中本身就包含 "0" 字符,那么字符串就会被截断,即非二进制安全;假如使用某种机制,保证读写字符串时不损害其内容,则是二进制安全。

由这个问题引入sds的设计。

struct sds {    int len;        // buf中已占用的字节数    int free;       // buf中剩余可用的字节数    char buf[];     // 真正存放字符串的数据空间}

这样就可以通过len字段,知道该取多少个字节的字符。就算中间有0也都取出来。而且

早起的redis3.2之前的sds就是这样设计的。

那么redis为什么要这么设计呢?主要有以下几点原因

  1. 有单独的统计变量len 和 free 可以很方便地得到字符串已使用 和 空闲长度。
  2. 字符串内容放在柔性数组buf中(如果有需要,可以留言 咱单独介绍下柔性数组),sds对上层暴露的指针不是指向结构体sds的指针,而是指向柔性数组buf的指针。上层可以像读取C字符串一样读取sds的内容,这样兼容C语言处理字符串的各种函数。
  3. 由于有长度统计变量len的存在,读写字符串时就可以不依赖"0"结束符,保证了二进制安全。这样就算字符串中间有"0"也会继续读取后面的内容。

这里引入了柔性数组的概念。

之所以用柔性数组存放字符串,是因为柔性数组的地址和结构体是连续的,这样查找内存更快(因为不需要额外通过指针找到字符串的位置);可以很方便的通过柔性数组的首地址,这样就可以通过移动指针获得其他的变量了。

那么这样设计有没有什么问题呢?欢迎留言讨论。下期我们继续交流沟通。

大家如果喜欢老张的分享,欢迎点赞,转发,关注三连。

您的支持也是老张坚持原创的动力。希望老张能和你们一起成长。

#读书# #Redis# #程序员# #编程# #缓存#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值