一道面试题

背景介绍

这里给大家分享一道很有趣的面试题。

面试过程

面试官:redis我看你有使用过,说一下redis的基本类型吧?
A:String,Hash,Set,List,Zset。
面试官:redis中string类型的实现有没有了解过?
A:(喵喵喵?)
面试官:回家等通知吧。

面试反思

作为一个爱学习的好孩子,遇到不会的当然要努力学习了,于是查阅了良多资料,算是把这个问题给搞明白了,下面且听我慢慢道来~

Redis的底层数据结构

经过查阅资料,发现Redis的底层数据结构分为八种

  • Long类型的整数
  • embstr 编码的简单动态字符串
  • 简单动态字符串
  • 字典
  • 双端链表
  • 压缩列表
  • 整数集合
  • 跳跃表和字典

简单动态字符串

Redis底层是用C语言写的,C语言中的字符串就是一个简单的字符数组,Redis中为了实现方便的扩展、安全和性能,自己定义了一个结构用来存储字符串。

我们叫它简单动态字符串(simple dynamic string)。

该数据结构中除了保存字符串,还保存了free(表示字符串剩余的空间)以及len(当前子字符串的长度)。

相比于C中的字符串,Redis这样做有几点好处:

  • 获取字符串长度的复杂度为O(1)
    由于sdshdr结构中定义了len用来保存当前字符串长度,因此不必像C中一样遍历字符串来得到长度。
  • 不会造成缓冲区溢出
    C中使用函数将一个字符串添加到另一个字符串默认是认为字符串剩余空间足够容纳添加的,但是事实可能并不够,会造成缓冲溢出。
    但是Redis在每一次执行字符串拼接的过程前都会判断当前剩余的free是否能够存下需要拼接的字符串,因此不会造成溢出。
  • 减少修改字符串带来的内存重分配次数
    Redis采用了内存预分配方法,每次扩容都会额外预留一些空间方便下次扩容来减少这些操作的出现频率。
  • 二进制安全
  • 兼容部分C字符串函数

后续

最近因为换工作的原因,耽误了更新,从这周起恢复每周至少一篇的博客更新,敬请期待~

公众号

原文地址:https://www.cnblogs.com/viyoung/p/11155178.html

时间: 2024-10-14 06:34:30

一道面试题的相关文章

一道面试题: C能申请的最大全局数组大小?

一道面试题: C能申请的最大全局数组大小?第一反应好像是4GB,但明显不对,代码和数据都要占空间,肯定到不了4GB.但是又想内存可以和硬盘数据交换,那到底是多少?应该是32位系统是理论上不能超过4GB(因为地址宽度4bytes,寻址的限制),实际中由于OS实现的细节会更少(比如Linux 1GB给了内核),而64位系统不超过2^64-1:内存大小最好大于数组长度,否则导致和磁盘交换数据,性能下降如果是局部变量,分配在栈上,空间会更小,取决于编译器 参考:http://stackoverflow.

华为的一道机试题--等式变换

华为的一道机试题 (http://blog.csdn.net/zombie_slicer/article/details/37346025) 第三题:等式变换 输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立. 1 2 3 4 5 6 7 8 9 = X 比如: 12-34+5-67+89 = 5 1+23+4-5+6-7-8-9 = 5 请编写程序,统计满足输入整数的所有整数个数. 输入:       正整数,等式右边的数字 输出:       使该等式成立的个数 样

Java中有关构造函数的一道笔试题解析

Java中有关构造函数的一道笔试题解析 1.具体题目如下 下列说法正确的有() A. class中的constructor不可省略 B. constructor必须与class同名,但方法不能与class同名 C. constructor在一个对象被new时执行 D.一个class只能定义一个constructor 2.解析说明 (1)class中的构造函数是可以省略的 /** * @Title:User.java * @Package:com.you.user.model * @Descrip

Android多线程研究(4)——从一道面试题说起

有一道这种面试题:开启一个子线程和主线程同一时候运行,子线程输出10次后接着主线程输出100次,如此重复50次.先看以下代码: package com.maso.test; /** * * @author Administrator * 两个线程,当中是一个主线程,第一个线程先运行输出10次,主线程接着运行输出100次,如此重复50次 */ public class ThreadTest3 implements Runnable{ private static Test test; @Overr

0810------笔试题----------腾讯2012年的一道笔试题

1.题目要求 a)b[i] = a[0] *a[1] *a[2]*….a[n-1]/ a[i],求出数组b: b)要求不能用除法,除循环控制变量以外,不许额外申请其余变量,时间复杂度为O(n),空间复杂度为O(1). 2.程序思路 a)假设 N = 5,那么 b[0] =      a[1]*a[2]*a[3]*a[4];            b[1] = a[0]*     a[2]*a[3]*a[4];            b[2] = a[0]*a[1]*     a[3]*a[4];

关于阿里的一道笔试题分析

其题目如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #pragma pack(2) class A { public:     int i;     union U     {         char buff[13];         int i;     }u;     void foo() {    }     typedef char* (*f)(void*);     enum{red, green, blue} color; }a; class A

关于Java类加载双亲委派机制的思考(附一道面试题)

预定义类加载器和双亲委派机制 JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar).由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作. 标准扩展(Extension)类加载器:是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)

好玩的一道笔试题

/*实现函数: void f(int a, int b, int c) 编码中不允许出现燃和if,switch,for,while之类的关键词以及"?:"表达式,并要求: a=1时,打印b+c的值: a=2时,打印b-c的值: a=3时,打印b*c的值: a=4时,打印b/c的值. */ 下面是我的解答,哈哈: #include <iostream> int cal(int a,int b, int c){ int res = 0; (!(a^1) && (

送上今年微软的一道笔试题

这里送上一道微软的笔试题,具体题目如下: Time Limit: 10000msCase Time Limit: 1000msMemory Limit: 256MB Description Consider a string set that each of them consists of {0, 1} only. All strings in the set have the same number of 0s and 1s. Write a program to find and outp

一道面试题让你与JS更近一步

这是一道面试题, 请先思考,在看讲解 :) var param = 1; function main() { console.log(param); var param = 2; console.log(this.param); this.param = 3; } //下面两条语句分别会在控制台打印什么? main(); var m = new main(); 讲解如下: 1. main() , 打印的结果为: undefined , 1 a. >  来看第一个打印的值为什么是 undefine