- 应用场景
- 类似于哈希操作,存储对象
incr && incrby<原子操作>
- incr对key对应的值进行加加操作,并返回新的值,incrby加指定的值
decr && decrby<原子操作>
- decr对key对应的值进行减减操做,并返回新的值,decrby减指定的值
setnx <小小体验一把分布式锁,真香>
- 设置Key对应的值为string类型的值,如果已经存在则返回0
setex
- 设置key对应的值为string类型的value,并设定有效期
setrange/getrange
- setrange从指定位置替换字符串
- getrange获取key对应value子字符串
其他命令
- msetnx 同mset,不存在就设置,不会覆盖已有的key
- getset 设置key的值,并返回key旧的值
- append 给指定的key的value追加字符串,并返回新字符串的长度
- strlen 返回key对应的value字符串的长度
应用场景
- 因为string类型是二进制安全的,可以用来存放图片,视频等内容。
- 由于redis的高性能的读写功能,而string类型的value也可以是数字,可以用做计数器(使用INCR,DECR指令)。比如分布式环境中统计系统的在线人数,秒杀等。
- 除了上面提到的,还有用于SpringSession实现分布式session
- 分布式系统全局序列号
2)list列表,它是简单的字符串列表,你可以添加一个元素到列表的头部,或者尾部。
编码
- 列表对象的编码可以是ziplist(压缩列表)和linkedlist(双端链表)。
- 编码转换
- 同时满足下面两个条件时使用压缩列表:
- 列表保存元素个数小于512个
- 每个元素长度小于64字节
- 不能满足上面两个条件使用linkedlist(双端列表)编码
- 同时满足下面两个条件时使用压缩列表:
- 常用命令
- lpush: 从头部加入元素
127.0.0.1:6379> lpush list1 hello
(integer) 1
127.0.0.1:637 9> lpush list1 world
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "world"
2) "hello"
- rpush:从尾部加入元素
127.0.0.1:6379> rpush list2 world
(integer) 1
127.0.0.1:6379> rpush list2 hello
(integer) 2
127.0.0.1:6379> lrange list2 0 -1
1) "world"
2) "hello"
- lpop: 从list的头部删除元素,并返回删除的元素
127.0.0.1:6379> lrange list1 0 -1
1) "world"
2) "hello"
127.0.0.1:6379> lpop list1
"world"
127.0.0.1:6379> lrange list1 0 -1
1) "hello"
- rpop:从list的尾部删除元素,并返回删除的元素
127.0.0.1:6379> lrange list2 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> rpop list2
"world"
127.0.0.1:6379> lrange list2 0 -1
1) "hello"
rpoplpush
: 第一步从尾部删除元素,第二步从首部插入元素 结合着使用linsert
:插入方法 linsert listname before [集合的元素] [插入的元素]
127.0.0.1:6379> lpush list3 hello
(integer) 1
127.0.0.1:6379> lpush list3 world
(integer) 2
127.0.0.1:6379> linsert list3 before hello start
(integer) 3
127.0.0.1:6379> lrange list3 0 -1
1) "world"
2) "start"
3) "hello"
- lset :替换指定下标的元素
127.0.0.1:6379> lrange list1 0 -1
1) "a"
2) "b"
127.0.0.1:6379> lset list1 0 v
OK
127.0.0.1:6379> lrange list1 0 -1
1) "v"
2) "b"
- lrm : 删除元素,返回删除的个数
127.0.0.1:6379> lrange list1 0 -1
1) "b"
2) "b"
3) "a"
4) "b"
127.0.0.1:6379> lrange list1 0 -1
1) "a"
2) "b"
- lindex: 返回list中指定位置的元素
- llen: 返回list中的元素的个数
实现数据结构
- Stack(栈)
- LPUSH+LPOP
- Queue(队列)
- LPUSH + RPOP
- Blocking MQ(阻塞队列)
- LPUSH+BRPOP
应用场景
- 实现简单的消息队列
- 利用LRANGE命令,实现基于Redis的分页功能
3)set
集合对象set是string类型(整数也会转成string类型进行存储)的无序集合。注意集合和列表的区别:集合中的元素是无序的,因此不能通过索引来操作元素;集合中的元素不能有重复。
编码
- 集合对象的编码可以是intset或者hashtable
- intset编码的集合对象使用整数集合作为底层实现,集合对象包含的所有元素都被保存在整数集合中。
- hashtable编码的集合对象使用字典作为底层实现,字典的每个键都是一个字符串对象,这里的每个字符串对象就是一个集合中的元素,而字典的值全部设置为null。当使用HT编码时,Redis中的集合SET相当于Java中的HashSet,内部的键值对是无序的,唯一的。内部实现相当于一个特殊的字典,字典中所有value都是NULL。
- 编码转换
- 当集合满足下列两个条件时,使用intset编码:
- 集合对象中的所有元素都是整数
- 集合对象所有元素数量不超过512
- 当集合满足下列两个条件时,使用intset编码:
常用命令
- sadd: 向集合中添加元素 (set不允许元素重复)
- smembers: 查看集合中的元素
127.0.0.1:6379> sadd set1 aaa
(integer) 1
127.0.0.1:6379> sadd set1 bbb
(integer) 1
127.0.0.1:6379> sadd set1 ccc
(integer) 1
127.0.0.1:6379> smembers set1
1) "aaa"
2) "ccc"
3) "bbb"
- srem: 删除集合元素
- spop: 随机返回删除的key
- sdiff :返回两个集合的不同元素 (哪个集合在前就以哪个集合为标准)
127.0.0.1:6379> smembers set1
1) "ccc"
2) "bbb"
127.0.0.1:6379> smembers set2
1) "fff"
2) "rrr"
3) "bbb"
127.0.0.1:6379> sdiff set1 set2
1) "ccc"
127.0.0.1:6379> sdiff set2 set1
1) "fff"
2) "rrr"
- sinter: 返回两个集合的交集
- sinterstore: 返回交集结果,存入目标集合
127.0.0.1:6379> sinterstore set3 set1 set2
(integer) 1
127.0.0.1:6379> smembers set3
1) "bbb"
- sunion: 取两个集合的并集
- sunionstore: 取两个集合的并集,并存入目标集合
- smove: 将一个集合中的元素移动到另一个集合中
- scard: 返回集合中的元素个数
- sismember: 判断某元素是否存在某集合中,0代表否 1代表是
- srandmember: 随机返回一个元素
127.0.0.1:6379> srandmember set1 1
1) "bbb"
127.0.0.1:6379> srandmember set1 2
1) "ccc"
2) "bbb"
应用场景
- 对于 set 数据类型,由于底层是字典实现的,查找元素特别快,另外set 数据类型不允许重复,利用这两个特性我们可以进行全局去重,比如在用户注册模块,判断用户名是否注册;微信点赞,微信抽奖小程序
- 另外就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好,可能认识的人等功能。
4)zset
和集合对象相比,有序集合对象是有序的。与列表使用索引下表作为排序依据不同,有序集合为每一个元素设置一个分数(score)作为排序依据。
编码
- 有序集合的编码可以使ziplist或者skiplist
- ziplist编码的有序集合对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员,第二个节点保存元素的分值。并且压缩列表内的集合元素按分值从小到大的顺序进行排列,小的放置在靠近表头的位置,大的放置在靠近表尾的位置。
- skiplist编码的依序集合对象使用zset结构作为底层实现,一个zset结构同时包含一个字典和一个跳跃表
typedef struct zset{
//跳跃表
zskiplist *zsl;
//字典
dict *dice;
}
zset
字典的键保存元素的值,字典的值保存元素的分值,跳跃表节点的object属性保存元素的成员,跳跃表节点的score属性保存元素的分值。这两种数据结构会通过指针来共享相同元素的成员和分值,所以不会产生重复成员和分值,造成内存的浪费。
- 编码转换
- 当有序结合对象同时满足以下两个条件时,对象使用ziplist编码,否则使用skiplist编码
- 保存的元素数量小于128
- 保存的所有元素长度都小于64字节
- 当有序结合对象同时满足以下两个条件时,对象使用ziplist编码,否则使用skiplist编码
常用命令
- zrem: 删除集合中名称为key的元素member
- zincrby: 以指定值去自动递增
- zcard: 查看元素集合的个数
- zcount: 返回score在给定区间中的数量
127.0.0.1:6379> zrange zset 0 -1
1) "one"
2) "three"
3) "two"
4) "four"
5) "five"
6) "six"
127.0.0.1:6379> zcard zset
# **读者福利**
**由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴**
**关注+点赞后,[点击这里获取](https://gitee.com/vip204888/java-p7)完整面试题(含答案)!**
![35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」](https://img-blog.csdnimg.cn/img_convert/12c1b3f07a15f1c5723bb7db0544c5dd.png)
![35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」](https://img-blog.csdnimg.cn/img_convert/a836a9cef573d48df44c616840bd4242.png)
![35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」](https://img-blog.csdnimg.cn/img_convert/e49b163a961b807a32da0fa15742c81a.png)
**更多笔记分享**
ard zset
# **读者福利**
**由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴**
**关注+点赞后,[点击这里获取](https://gitee.com/vip204888/java-p7)完整面试题(含答案)!**
[外链图片转存中...(img-OhwwwqZB-1628341245009)]
[外链图片转存中...(img-1QRtIy19-1628341245012)]
[外链图片转存中...(img-uF9U5T9n-1628341245014)]
**更多笔记分享**
![35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」](https://img-blog.csdnimg.cn/img_convert/aa974bf3287abac06cb9d9f2a3db992b.png)