《八股文》20道Redis面试题

1、什么是Redis,Redis有哪些特点?

Redis全称为:Remote Dictionary Server(远程数据服务),Redis是一种支持key-value等多种数据结构的存储系统。可用于缓存,事件发布或订阅,高速队列等场景。支持网络,提供字符串,哈希,列表,队列,集合结构直接存取,基于内存,可持久化。

特点1:丰富的数据类型

我们知道很多数据库只能处理一种数据结构:

  • 传统SQL数据库处理二维关系数据;

  • MemCached数据库,键和值都是字符串;

  • 文档数据库(MongoDB)是由Json/Bson组成的文档。

当然不是他们这些数据库不好,而是一旦数据库提供数据结构不适合去做某件事情的话,程序写起来就非常麻烦和不自然。

Redis虽然也是键值对数据库,但是和Memcached不同的是:Redis的值不仅可以是字符串,它还可以是其他五中数据机构中的任意一种。通过选用不同的数据结构,用户可以使用Redis解决各种各样的问题,使用Redis,你碰到一个问题,首先会想到是选用那种数据结构把哪些功能问题解决掉,有了多样的数据结构,方便你解决问题。

特点2:内存存储

数据库有两种:一种是硬盘数据库,一种是内存数据库。

硬盘数据库是把值存储在硬盘上,在内存中就存储一下索引,当硬盘数据库想访问硬盘的值时,它先在内存里找到索引,然后再找值。问题在于,在读取和写入硬盘的时候,如果读写比较多的时候,它会把硬盘的IO功能堵死。

内存存储是讲所有的数据都存储在内存里面,数据读取和写入速度非常快。

特点3:持久化功能

将数据存储在内存里面的数据保存到硬盘中,保证数据安全,方便进行数据备份和恢复。

2、Redis有哪些数据结构?

Redis是key-value数据库,key的类型只能是String,但是value的数据类型就比较丰富了,主要包括五种:

  • String

  • Hash

  • List

  • Set

  • Sorted Set

 

(1)String字符串

语法

SET KEY_NAME VALUE

string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象。string类型是Redis最基本的数据类型,一个键最大能存储512MB。

(2)Hash哈希

语法

HSET KEY_NAME FIELD VALUE

Redis hash 是一个键值(key=>value)对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

(3)List列表

语法

//在 key 对应 list 的头部添加字符串元素
LPUSH KEY_NAME VALUE1.. VALUEN
//在 key 对应 list 的尾部添加字符串元素
RPUSH KEY_NAME VALUE1..VALUEN
//对应 list 中删除 count 个和 value 相同的元素
LREM KEY_NAME COUNT VALUE
//返回 key 对应 list 的长度
LLEN KEY_NAME

Redis 列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)

(4)Set集合

语法

SADD KEY_NAME VALUE1...VALUEn

Redis的Set是string类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

(5)Sorted Set有序集合

语法

ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。

redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

3、一个字符串类型的值能存储最大容量是多少?

查询官方文档(https://redis.io/topics/data-types)可以看到String类型的value值最多支持的长度为512M,所以正确的答案是512M。

 

4、能说一下Redis每种数据结构的使用场景吗?

(1)String的使用场景

字符串类型的使用场景:信息缓存、计数器、分布式锁等等。

常用命令:get/set/del/incr/decr/incrby/decrby

实战场景1:记录每一个用户的访问次数,或者记录每一个商品的浏览次数

方案:

常用键名:userid:pageview 或者 pageview:userid,如果一个用户的id为123,那对应的redis key就为pageview:123,value就为用户的访问次数,增加次数可以使用命令:incr。

使用理由:每一个用户访问次数或者商品浏览次数的修改是很频繁的,如果使用mysql这种文件系统频繁修改会造成mysql压力,效率也低。而使用redis的好处有二:使用内存,很快;单线程,所以无竞争,数据不会被改乱。

实战场景2:缓存频繁读取,但是不常修改的信息,如用户信息,视频信息

方案:

业务逻辑上:先从redis读取,有值就从redis读取,没有则从mysql读取,并写一份到redis中作为缓存,注意要设置过期时间。

键值设计上:

直接将用户一条mysql记录做序列化(通常序列化为json)作为值,userInfo:userid 作为key,键名如:userInfo:123,value存储对应用户信息的json串。如 key为:"user:id:name:1",  value为"{"name":"leijia","age":18}"。

实战场景3:限定某个ip特定时间内的访问次数

方案:

用key记录IP,value记录访问次数,同时key的过期时间设置为60秒,如果key过期了则重新设置,否则进行判断,当一分钟内访问超过100次,则禁止访问。

实战场景4:分布式session

我们知道session是以文件的形式保存在服务器中的;如果你的应用做了负载均衡,将网站的项目放在多个服务器上,当用户在服务器A上进行登陆,session文件会写在A服务器;当用户跳转页面时,请求被分配到B服务器上的时候,就找不到这个session文件,用户就要重新登陆。

如果想要多个服务器共享一个session,可以将session存放在redis中,redis可以独立于所有负载均衡服务器,也可以放在其中一台负载均衡服务器上;但是所有应用所在的服务器连接的都是同一个redis服务器。

(2)Hash的使用场景

以购物车为例子,用户id设置为key,那么购物车里所有的商品就是用户key对应的值了,每个商品有id和购买数量,对应hash的结构就是商品id为field,商品数量为value。如图所示:

 

如果将商品id和商品数量序列化成json字符串,那么也可以用上面讲的string类型存储。下面对比一下这两种数据结构:

对比项 string(json) hash
效率 很高
容量
灵活性
序列化 简单 复杂

总结一下:

当对象的某个属性需要频繁修改时,不适合用string+json,因为它不够灵活,每次修改都需要重新将整个对象序列化并赋值;如果使用hash类型,则可以针对某个属性单独修改,没有序列化,也不需要修改整个对象。比如,商品的价格、销量、关注数、评价数等可能经常发生变化的属性,就适合存储在hash类型里。

(3)List的使用场景

列表本质是一个有序的,元素可重复的队列。

实战场景:定时排行榜

list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如QQ音乐内地排行榜,每周计算一次存储再list类型中,访问接口时通过page和size分页转化成lrange命令获取排行榜数据。

 

但是,并不是所有的排行榜都能用list类型实现,只有定时计算的排行榜才适合使用list类型存储,与定时计算的排行榜相对应的是实时计算的排行榜,list类型不能支持实时计算的排行榜,下面介绍有序集合sorted set的应用场景时会详细介绍实时计算的排行榜的实现。

(4)Set的使用场景

集合的特点是无序性和确定性(不重复)。

实战场景:收藏夹

例如QQ音乐中如果你喜欢一首歌,点个『喜欢』就会将歌曲放到个人收藏夹中,每一个用户做一个收藏的集合,每个收藏的集合存放用户收藏过的歌曲id。

key为用户id,value为歌曲id的集合。

 

(5)Sorted Set的使用场景

有序集合的特点是有序,无重复值。与set不同的是sorted set每个元素都会关联一个score属性,redis正是通过score来为集合中的成员进行从小到大的排序。

实战场景:实时排行榜

QQ音乐中有多种实时榜单,比如飙升榜、热歌榜、新歌榜,可以

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值