面试题答案
一键面试获取字符串长度
- Redis SDS:Redis的SDS(Simple Dynamic String)结构在获取字符串长度时,时间复杂度为O(1)。因为SDS结构体中专门有一个字段来记录字符串的长度,通过直接读取该字段就能获取长度信息。例如,SDS的结构体可能类似如下:
struct sdshdr {
int len;
int free;
char buf[];
};
获取长度时,直接访问len
字段即可。
- 传统C字符串:传统C字符串获取长度的时间复杂度为O(n)。C字符串以空字符
'\0'
作为结束标志,要获取其长度,需要从字符串的起始位置开始逐个字符遍历,直到遇到'\0'
,统计遍历过的字符个数。例如:
char str[] = "hello";
int len = 0;
while (str[len] != '\0') {
len++;
}
所以在获取字符串长度场景下,Redis SDS明显优于传统C字符串,主要原因是SDS采用了额外的字段记录长度,避免了遍历操作。
遍历操作
- Redis SDS:在遍历操作方面,SDS由于有明确的长度记录,不用担心越界问题。开发人员可以在已知长度范围内安全地进行遍历操作。例如,在对SDS字符串进行逐个字符处理时,可以直接通过循环从0到
len - 1
进行操作,代码如下:
struct sdshdr *sds_str; // 假设已初始化
for (int i = 0; i < sds_str->len; i++) {
// 处理sds_str->buf[i]
}
- 传统C字符串:遍历传统C字符串时,需要时刻注意
'\0'
结束标志,以防止越界访问。如果不小心在遍历过程中超过了字符串实际长度(未考虑'\0'
),可能会访问到无效内存,导致程序崩溃。例如:
char c_str[] = "world";
for (int i = 0; ; i++) {
if (c_str[i] == '\0') break;
// 处理c_str[i]
}
Redis SDS在遍历操作时更简单和安全,原因在于它明确记录了长度,减少了开发人员处理边界条件的负担,而传统C字符串依赖隐式的结束标志,增加了越界风险。