今日头条java后端面试,redis编码及数据结构

本文介绍了Redis的客户端与服务器端,详细解释了其基本命令,包括5种数据结构(字符串、哈希、列表、集合、有序集合)的存储、获取和删除操作。还探讨了Redis的底层编码机制和对象类型实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis-cli.exe:redis的客户端

redis-server.exe:redis服务器端

1.3 基本命令


1.3.1 redis的数据结构

redis存储的是 key,value 格式的数据,其中key都是字符串,value有5种不同的数据结构

value的数据结构:

  • 字符串类型 string

  • 哈希类型 hash : map格式

  • 列表类型 list : linkedlist格式。支持重复元素

  • 集合类型 set : 不允许重复元素

  • 有序集合类型 sortedset:不允许重复元素,且元素有顺序

1.3.2 字符串类型 string

1. 存储: set key value

127.0.0.1:6379> set username zhangsan

OK

2. 获取: get key

127.0.0.1:6379> get username

“zhangsan”

3. 删除: del key

127.0.0.1:6379> del age

(integer) 1

1.3.3 哈希类型 hash

1. 存储: hset key field value

127.0.0.1:6379> hset myhash username lisi

(integer) 1

127.0.0.1:6379> hset myhash password 123

(integer) 1

2. 获取:

  • hget key field: 获取指定的field对应的值

127.0.0.1:6379> hget myhash username

“lisi”

  • hgetall key:获取所有的field和value

127.0.0.1:6379> hgetall myhash

  1. “username”
  1. “lisi”
  1. “password”
  1. “123”

3. 删除: hdel key field

127.0.0.1:6379> hdel myhash username

(integer) 1

1.3.4 列表类型 list

可以添加一个元素到列表的头部(左边)或者尾部(右边)

1. 添加:

  • lpush key value: 将元素加入列表左表

  • rpush key value:将元素加入列表右边

127.0.0.1:6379> lpush myList a

(integer) 1

127.0.0.1:6379> lpush myList b

(integer) 2

127.0.0.1:6379> rpush myList c

(integer) 3

2. 获取:

  • lrange key start end :范围获取

127.0.0.1:6379> lrange myList 0 -1

  1. “b”
  1. “a”
  1. “c”

3. 删除:

  • lpop key: 删除列表最左边的元素,并将元素返回

  • rpop key: 删除列表最右边的元素,并将元素返回

1.3.5 集合类型 set : 不允许重复元素

1. 存储:sadd key value

127.0.0.1:6379> sadd myset a

(integer) 1

127.0.0.1:6379> sadd myset a

(integer) 0

2. 获取:smembers key:获取set集合中所有元素

127.0.0.1:6379> smembers myset

  1. “a”

3. 删除:srem key value:删除set集合中的某个元素

127.0.0.1:6379> srem myset a

(integer) 1

1.3.6 有序集合类型 sortedset

不允许重复元素,且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

1. 存储:zadd key score value

127.0.0.1:6379> zadd mysort 60 zhangsan

(integer) 1

127.0.0.1:6379> zadd mysort 50 lisi

(integer) 1

127.0.0.1:6379> zadd mysort 80 wangwu

(integer) 1

2. 获取:zrange key start end [withscores]

127.0.0.1:6379> zrange mysort 0 -1

  1. “lisi”
  1. “zhangsan”
  1. “wangwu”

127.0.0.1:6379> zrange mysort 0 -1 withscores

  1. “zhangsan”
  1. “60”
  1. “wangwu”
  1. “80”
  1. “lisi”
  1. “500”

3. 删除:zrem key value

127.0.0.1:6379> zrem mysort lisi

(integer) 1

1.3.7 通用命令

1. keys * : 查询所有的键

2. type key : 获取键对应的value的类型

3. del key:删除指定的key value

2 redis编码及数据结构

==============

上面都是一些redis的基本入门级操作,接下来对于底层的分析是重点

2.1 redis支持的数据类型


2.2 Redis对象源码(3.0版)


redisObject类的属性有三个:

  • type:类型

  • encoding:对象的编码

  • int,embstr,raw,ht(哈希表),linkedlist,ziplist(连续空间),intset,skiplist(跳表)

  • ptr:指向底层实现数据结构的指针

type可以看做是第一层、encoding可以看做是第二层、ptr可以看做是第三层,他们之间有一些对应关系。

2.3 Redis对象类型——type(第一层)& encoding(第二层)


redis对象的key都是String的,value就是其支持的5种数据类型。我们可以用TYPE命令查看value的类型:

5个数据类型与源码中的8个encoding(编码)类型的对照关系(第一层和第二层对照):

之所以有这么多的对照关系是因为redis支持了针对不同应用场景来采用不同的数据结构,具有更大的灵活性。

我们可以用OBJECT encoding命令来查看相应的encoding类型:

2.4 字符串内部实现——int & raw & embstr


int编码很简单,ptr指向一个int型数据

raw的内部实现是ptr指向一个sds(可以简单的理解为redis中实现的字符串)。

free属性表示预留的空闲空间,len表示实际字符串的长度,buf是指向一个字符数组的指针。

预留空间:当申请的空间较小时,C语言在申请len这么多的空间时会申请一份同样大小的预留空间。

惰性空间释放:删除数据时,free的值会增加,而不是真正的把数据给释放掉

embstr结构和raw的类似,只不过ptr不是指向sds的指针了,而是一个连续空间,ptr后面紧跟着sds对象,所以查询会非常快,但这种方式并不适合存储大量数据。

选择编码格式的规则:

  • 如果设置的数字是一个long类型的,那么其encoding就是int

  • 如果不是long类型表示的整形数字,那么用raw或者embstr

  • 长度小于等于39则是embstr

  • 长度大于40则是raw

  • embstr是一个只读的,如果要修改这样类型的数据,修改之后的结果会变为raw

2.5 列表的内部实现——ziplist & linkedlist编码


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

一线互联网大厂Java核心面试题库

image

正逢面试跳槽季,给大家整理了大厂问到的一些面试真题,由于文章长度限制,只给大家展示了部分题目,更多Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等已整理上传,感兴趣的朋友可以看看支持一波!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

一线互联网大厂Java核心面试题库

[外链图片转存中…(img-CsCd4feF-1713465388805)]

正逢面试跳槽季,给大家整理了大厂问到的一些面试真题,由于文章长度限制,只给大家展示了部分题目,更多Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等已整理上传,感兴趣的朋友可以看看支持一波!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

### Java 后端开发工程师面试 Redis 常见问题及答案 #### 什么是 RedisRedis 是一种开源的键值存储系统,支持多种数据结构如字符串、哈希、列表、集合和有序集合。它不仅可以用作内存中的数据结构存储器,还可以作为数据库、缓存和消息中间件使用[^2]。 #### Redis 的持久化机制有哪些? Redis 提供两种主要的持久化方式:RDB 和 AOF。 - **RDB (Redis Database Backup)**:通过快照的方式,在指定的时间间隔内保存数据集的时间点副本。 - **AOF (Append Only File)**:记录服务器执行的所有写操作命令,并在服务器启动时重新执行这些命令来恢复数据。 #### 如何解决 Redis 中的数据过期策略? Redis 支持设置键的有效时间(TTL),当 TTL 到达时,该键会被自动删除。对于大量即将到期的 key,可以采用惰性删除加定期主动删除相结合的方式来处理。前者是在访问某个 key 时才检查其是否已过期并清理;后者则是后台定时扫描一部分 keyspace 来查找并清除已经过期但还未被访问到的 key。 #### Redis 实现分布式锁的方法是什么? 实现分布式锁可以通过 SETNX 指令配合 EXPIRE 设置超时期限完成。具体来说就是尝试给一个特定名称的 key 赋予唯一 value 并设定有效期限,如果返回结果为 true 表明成功获取到了锁,反之则说明已被其他客户端占用需等待重试机会。为了防止死锁情况发生还需要考虑异常情况下如何释放锁等问题。 ```java public class DistributedLock { private final Jedis jedis; public boolean tryAcquire(String lockKey, String requestId, int expireTime){ Long result = jedis.setnx(lockKey, requestId); if(result != null && result.equals(1L)){ // 成功获得锁 jedis.expire(lockKey, expireTime); return true; } return false; } public void release(String lockKey, String requestId){ String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then " + "return redis.call('del', KEYS[1]) " + "else return 0 end"; Object result = jedis.eval(luaScript, Collections.singletonList(lockKey), Collections.singletonList(requestId)); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值