阿里面试官问我:“Redis 的 String 底层是怎么设计的?”,我画完 SDS,他点了点头……

今天分享一道高频面试题:

Redis 中的 String 底层是怎么设计的?

平时使用 SET 和 GET 时,我们很少关心 Redis 是怎么保存字符串的。看起来只是存进去一个值,再原样取出来,没什么特别的。

但 Redis 的 String 不只可以保存普通文本。比如数字、JSON、序列化对象,甚至图片的二进制内容,都可以作为 String 保存。

这一切都和 Redis 自己实现的字符串结构 SDS 有关。

Redis 的 String 类型最基本的数据类型,它能够存储任何二进制数据。

Redis 的 String 类型底层实现是基于一个名为 SDS(Simple Dynamic String,简单动态字符串) 的数据结构。SDS 提供了对动态字符串的操作,它的设计目标是能够高效地处理字符串,同时尽可能地降低内存重新分配的次数。

下面是 SDS 的头部结构源代码:

c 复制代码
typedef char *sds;

struct sdshdr {

    // 已用长度
    int len;

    // 可用长度
    int free;

    // 保存字符串的字节数组
    char buf[];
};

SDS 的数据结构如下:

包含以下几个部分:

  • free: 表示字符串的可用长度,也就是字符串中可以增加的字符数量,而不需要进行内存重新分配。
  • len: 表示字符串的占用长度,也就是字符串中实际字符的数量。
  • buf: 是一个字节数组,用于存储实际的字符串。这个数组的长度是 len + free + 1,多出来的 1 是为了存储字符串的结束符 '\0',用于兼容部分 C 语言标准库的函数。

和普通的 C 字符串相比,SDS 有一个很直接的优势:获取长度时不用从头遍历。

因为长度已经记录在 len 字段中,所以读取字符串长度的时间复杂度是 O(1)。即使字符串很长,也可以直接拿到结果。

另外,free 字段则给字符串预留了一部分可用空间。一般在追加内容时,只要预留空间足够,Redis 就可以直接写入,不必每次都申请一块新内存,再复制原有数据。

所以,Redis 的 String 看起来简单,底层实现却很讲究。

SDS 通过保存长度、记录可用空间和使用字节数组,解决了普通 C 字符串在长度计算、二进制数据处理和内存扩容方面的问题。

相关推荐
rannn_1111 小时前
JVM 面试题:类加载过程详解(附高频考点)
java·jvm·后端
程序猿乐锅5 小时前
从0-1一文详解RabbitMQ
java·分布式·后端·中间件·rabbitmq·ruby
考虑考虑8 小时前
JDK26中的List.ofLazy()
java·后端·java ee
小蒜学长8 小时前
基于SpringBoot的公寓报修管理系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·公寓报修管理系统·多角色协同
云浪9 小时前
Go源码分析:搞懂 Go 是如何实现堆的
后端·go·源码阅读
调试人生的显微镜12 小时前
iOS开发入门:Interface Builder、基础控件及UITextField详解
后端·ios
泡海椒12 小时前
巡检照片与工单附件:jquick-pdf 图片嵌入的业务实战
后端
蜗牛互联网12 小时前
Python消费Responses SSE事件:增量文本、超时与取消
java·开发语言·人工智能·后端·python
AI持续学习12 小时前
文档权限变更如何回归测试?账号、空间、文件和分享链接用例清单
后端
谢亮_vipxieliang13 小时前
Go Worker Pool 设计——从原理到生产级实现
开发语言·后端·golang