Java中高级核心知识全面解析——Redis([数据类型、编码、底层数据结构]、5种数据类型的编码和数据结构、内存回收和共享)6

redis底层数据结构(一)-RedisObject 在看到refcount这个字段的时候,让我想到了jvm垃圾回收中的引用计数法和可达性分析算法,那么RedisObject中存在refcount字段,是否代表redis回收对象使用了引用计数法?它是 Redis 用来在内存中表示其支持的 5 种基本数据类型(字符串、列表、哈希、集合、有序集合)的底层统一结构。对于深入掌握 Redis 的内存管理、多态行为、内存优化机制至关重要。以下内容针对版本为redis7。 阅读详情

一、Redis数据类型、编码、底层数据结构

1.Redis构建的类型系统

Redis构建了自己的类型系统,主要包括

  • redisObject对象
  • 基于redisObject对象的类型检查
  • 基于redisObject对象的显示多态函数
  • 对redisObject进行分配、共享和销毁的机制

C语言不是面向对象语言,这里将redisObject称呼为对象是为了讲述方便,让里面的内容更容易被理解,redisObject其实是一个结构体。

1)redisObject对象

Redis内部使用一个redisObject对象来表示所有的key和value,每次在Redis数据块中创建一个键值对时,一个是键对象,一个是值对象,而Redis中的每个对象都是由redisObject结构来表示。

在Redis中,键总是一个字符串对象,而值可以是字符串、列表、集合等对象,所以我们通常说键为字符串键,表示这个键对应的值为字符串对象,我们说一个键为集合键时,表示这个键对应的值为集合对象

redisobject最主要的信息:

redisobject源码 
typedef struct redisObject{ 
	//类型 
	unsigned type:4; 
	//编码 
	unsigned encoding:4; 
	//指向底层数据结构的指针 
	void *ptr; 
	//引用计数 
	int refcount; 
	//记录最后一次被程序访问的时间 
	unsigned lru:22; 
}robj
  • type代表一个value对象具体是何种数据类型
    • type key :判断对象的数据类型
  • encoding属性和*prt指针
    • prt指针指向对象底层的数据结构,而数据结构由encoding属性来决定
    • 每种类型的对象至少使用了两种不同的编码,而这些编码对用户是完全透明的。
    • object encoding key命令可以查看值对象的编码

2)命令的类型检查和多态

①、Redis命令分类
  • 一种是只能用于对应数据类型的命令,例如LPUSH和LLEN只能用于列表键, SADD 和 SRANDMEMBER只能用于集合键。
  • 另一种是可以用于任何类型键的命令。比如TTL。

当执行一个处理数据类型的命令时,Redis执行以下步骤:

  • 根据给定 key ,在数据库字典中查找和它相对应的 redisObject ,如果没找到,就返回 NULL。
  • 检查 redisObject 的 type 属性和执行命令所需的类型是否相符,如果不相符,返回类型错误。
  • 根据 redisObject 的 encoding 属性所指定的编码,选择合适的操作函数来处理底层的数据结构。
  • 返回数据结构的操作结果作为命令的返回值。

小插曲:
更多阿里、腾讯、美团、京东等一线互联网大厂Java面试真题;包含:基础、并发、锁、JVM、设计模式、数据结构、反射/IO、数据库、Redis、Spring、消息队列、分布式、Zookeeper、Dubbo、Mybatis、Maven、面经等。
更多Java程序员技术进阶小技巧;例如高效学习(如何学习和阅读代码、面对枯燥和量大的知识)高效沟通(沟通方式及技巧、沟通技术)
更多Java大牛分享的一些职业生涯分享文档


请点击这里添加》》》》》》》》》社群,免费获取


比你优秀的对手在学习,你的仇人在磨刀,你的闺蜜在减肥,隔壁老王在练腰, 我们必须不断学习,否则我们将被学习者超越!
趁年轻,使劲拼,给未来的自己一个交代!

2.5种数据类型对应的编码和数据结构

1)string

string 是最常用的一种数据类型,普通的key/value存储都可以归结为string类型,value不仅是string,也可以是数字。其他几种数据类型的构成元素也都是字符串,注意Redis规定字符串的长度不能超过512M

编码字符串对象的编码可以是int、raw、embstr

  • int编码
    • 保存的是可以用long类型表示的整数值
  • raw编码
    • 保存长度大于44字节的字符串
  • embstr编码
    • 保存长度小于44字节的字符串

int用来保存整数值,raw用来保存长字符串,embstr用来保存短字符串。embstr编码是用来专门保存短字符串的一种优化编码。

Redis中对于浮点型也是作为字符串保存的,在需要时再将其转换成浮点数类型

编码的转换

  • 当 int 编码保存的值不再是整数,或大小超过了long的范围时,自动转化为raw
  • 对于 embstr 编码,由于 Redis 没有对其编写任何的修改程序(embstr 是只读的),在对embstr对象进行修改时,都会先转化为raw再进行修改,因此,只要是修改embstr对象,修改后的对象一定是raw的,无论是否达到了44个字节。

常用命令

  • set/get
    • set:设置key对应的值为string类型的value (多次set name会覆盖)
    • get:获取key对应的值
  • mset /mget
    • mset 批量设置多个key的值,如果成功表示所有值都被设置,否则返回0表示没有任何值被设置
    • mget批量获取多个key的值,如果不存在则返回null
127.0.0.1:6379> mset user1:name redis user1:age 22 
OK
127.0.0.1:6379> mget user1:name user1:age 
1) "redis" 
2) "22"
  • 应用场景
    • 类似于哈希操作,存储对象

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

常用命令

  • 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字节

常用命令

  • 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 
(integer) 6 
127.0.0.1:6379> zcount zset 1 4 
(integer) 4
  • zrangebyscore: 找到指定区间范围的数据进行返回
127.0.0.1:6379> zrangebyscore zset 0 4 withscores 
1) "one" 
2) "1" 
3) "three" 
4) "2" 
5) "two" 
6) "2" 
7) "four" 
8) "4"
  • zremrangebyrank zset from to: 删除索引
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> zremrangebyrank zset 1 3 
(integer) 3 
127.0.0.1:6379> zrange zset 0 -1 
1) "one" 
2) "five" 
3) "six"
  • zremrangebyscore zset from to: 删除指定序号
127.0.0.1:6379> zrange zset 0 -1 withscores 
1) "one" 
2) "1" 
3) "five" 
4) "5" 
5) "six" 
6) "6" 
127.0.0.1:6379> zremrangebyscore zset 3 6 
(integer) 2 
127.0.0.1:6379> zrange zset 0 -1 withscores 
1) "one" 
2) "1"
  • zrank: 返回排序索引 (升序之后再找索引)
  • zrevrank: 返回排序索引 (降序之后再找索引)

应用场景

  • 对于 zset 数据类型,有序的集合,可以做范围查找,排行榜应用,取TOP N操作等。

5)hash

hash对象的键是一个字符串类型,值是一个键值对集合

编码

  • hash对象的编码可以是ziplist或者hashtable
    • 当使用ziplist,也就是压缩列表作为底层实现时,新增的键值是保存到压缩列表的表尾。
    • hashtable 编码的hash表对象底层使用字典数据结构,哈希对象中的每个键值对都使用一个字典键值对。Redis中的字典相当于Java里面HashMap,内部实现也差不多类似,都是通过“数组+链表”的链地址法来解决哈希冲突的,这样的结构吸收了两种不同数据结构的优点。
  • 编码转换
    • 当同时满足下面两个条件使用ziplist编码,否则使用hashtable编码
      • 列表保存元素个数小于512个
      • 每个元素长度小于64字节
  • hash是一个String类型的field和value之间的映射表
  • Hash特别适合存储对象
  • 所存储的成员较少时数据存储为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht
  • Hash命令详解
    • hset/hget
      • hset hashname hashkey hashvalue
      • hget hashname hashkey
127.0.0.1:6379> hset user id 1 
(integer) 1 
127.0.0.1:6379> hset user name z3 
(integer) 1 
127.0.0.1:6379> hset user add shanxi 
(integer) 1 
127.0.0.1:6379> hget user id "1" 
127.0.0.1:6379> hget user name "z3" 
127.0.0.1:6379> hget user add "shanxi"
  • hmset/hmget
    • hmset hashname hashkey1hashvalue1 hashkey2 hashvalue2 hashkey3 hashvalue3
    • hget hashname hashkey1 hashkey2 hashkey3
127.0.0.1:6379> hmset user id 1 name z3 add shanxi 
OK
127.0.0.1:6379> hmget user id name add 
1) "1" 
2) "z3" 
3) "shanxi"
  • hsetnx/hgetnx
  • hincrby/hdecrby
127.0.0.1:6379> hincrby user2 id 3 
(integer) 6 
127.0.0.1:6379> hget user2 id 
"6"
  • hexist 判断是否存在key,不存在返回0
127.0.0.1:6379> hget user2 id 
"6"
  • hlen 返回hash集合里所有的键值数
127.0.0.1:6379> hmset user3 id 3 name w5 
OK
127.0.0.1:6379> hlen user3 
(integer) 2
  • hdel :删除指定的hash的key
  • hkeys 返回hash里所有的字段
  • hvals 返回hash里所有的value
  • hgetall:返回hash集合里所有的key和value
127.0.0.1:6379> hgetall user3 
1) "id" 
2) "3" 
3) "name" 
4) "w3" 
5) "add" 
6) "beijing"

优点

  • 同类数据归类整合存储,方便数据管理,比如单个用户的所有商品都放在一个hash表里面。
  • 相比string操作消耗内存cpu更小

缺点

  • hash结构的存储消耗要高于单个字符串
  • 过期功能不能使用在field上,只能用在key上
  • redis集群架构不适合大规模使用

应用场景

  1. 对于 hash 数据类型,value 存放的是键值对,比如可以做单点登录存放用户信息。
  2. 存放商品信息,实现购物车

小插曲:
更多阿里、腾讯、美团、京东等一线互联网大厂Java面试真题;包含:基础、并发、锁、JVM、设计模式、数据结构、反射/IO、数据库、Redis、Spring、消息队列、分布式、Zookeeper、Dubbo、Mybatis、Maven、面经等。
更多Java程序员技术进阶小技巧;例如高效学习(如何学习和阅读代码、面对枯燥和量大的知识)高效沟通(沟通方式及技巧、沟通技术)
更多Java大牛分享的一些职业生涯分享文档


请点击这里添加》》》》》》》》》社群,免费获取


比你优秀的对手在学习,你的仇人在磨刀,你的闺蜜在减肥,隔壁老王在练腰, 我们必须不断学习,否则我们将被学习者超越!
趁年轻,使劲拼,给未来的自己一个交代!

3. 内存回收和内存共享

typedef struct redisObject{ 
	//类型 
	unsigned type:4; 
	//编码 
	unsigned encoding:4; 
	//指向底层数据结构的指针 
	void *ptr; 
	//引用计数 
	int refcount; 
	//记录最后一次被程序访问的时间 
	unsigned lru:22; 
}robj

内存回收:因为c语言不具备自动内存回收功能,当将redisObject对象作为数据库的键或值而不是作为参数存储时其生命周期是非常长的,为了解决这个问题,Redis自己构建了一个内存回收机制,通过redisobject结构中的refcount实现.这个属性会随着对象的使用状态而不断变化。

  1. 创建一个新对象,属性初始化为1
  2. 对象被一个新程序使用,属性refcount加1
  3. 对象不再被一个程序使用,属性refcount减1
  4. 当对象的引用计数值变为0时,对象所占用的内存就会被释放

内存共享:refcount属性除了能实现内存回收以外,还能实现内存共享

  1. 将数据块的键的值指针指向一个现有值的对象
  2. 将被共享的值对象引用refcount加1Redis的共享对象目前只支持整数值的字符串对象。之所以如此,实际上是对内存和CPU(时间)的平衡:共享对象虽然会降低内存消耗,但是判断两个对象是否相等却需要消耗额外的时间。对于整数值,判断操作复杂度为o(1),对于普通字符串,判断复杂度为o(n);而对于哈希,列表,集合和有序集合,判断的复杂度为o(n^2).虽然共享的对象只能是整数值的字符串对象,但是5种类型都可能使用共享对象。

参考资料:《Java中高级核心知识全面解析》限量100份,有一些人已经通过我之前的文章获取了哦!
名额有限先到先得!!!
有想要获取这份学习资料的同学可以点击这里免费获取》》》》》》》

海康工业相机BayerRG8转BGR8实战:手把手教你用OpenCV实现高效图像转换 本文详细解析了海康工业相机BayerRG8格式到BGR8格式的高效转换实战。针对工业视觉项目中高帧率、大分辨率场景下的性能瓶颈,文章对比了海康SDK原生方案与OpenCV多种转换方法的优劣,并提供了从基础实现到高级优化(如多线程流水线、内存管理、SIMD指令集应用)的完整代码示例与性能调优策略,帮助开发者构建稳定、高效的图像处理系统。 阅读详情

相关推荐

SAP S/4HANA BP主数据-CVI模型

SAP BP主数据介绍 ECC系统中的客户、供应商主数据的限制: •一个客户或供应商仅能有一个地址 •客户和供应商没有关联关系(同一个实体公司) •如果一家公司既是供应商也是客户需建立两个主数据(数据冗余) •属性无时间相关性 S4系统中BP优点: •一个BP可以扮演多个角色(个人,客户,供应商)且角色之间数据共享 •时间相关的属性 •统一的数据架构,无数据冗余 •CVI模型可以确保BP和客户/供应商数据同步 SAP BP主数据配置 •配置BP角色/角色类别 •配置BP角.

qq_37785505的博客 1551

Redis如何把字符集的编码格式设置为UTF-8

该篇文章主要用来实现怎么让redis客户端显示中文

qq_57492774的博客 4070

C# 【WebService编写调用】

😹 觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!!

只有登上山顶,才能看到那边的风光 1175

Redis 中的 集合(Set) SRANDMEMBER:随机获取集合中的元素 返回指定数量的元素

这里写目录标题5.7 SRANDMEMBER:随机获取集合中的元素5.7.1 返回指定数量的元素5.7.2 其他信息参考目录 5.7 SRANDMEMBER:随机获取集合中的元素         通过使用SRANDMEMBER命令,用户可以从集合中随机地获取指定数量的元素。         SRANDMEMBER命令接受一个可选的count参数,用于

norang的博客 5395

STM32CubeMX + HAL库避坑指南:为什么你的代码总在SystemClock_Config卡住?

本文深入剖析了STM32开发者在使用STM32CubeMX和HAL库时,代码在SystemClock_Config函数中卡死的根本原因。文章不仅指出硬件时序、Flash延迟配置等常见陷阱,更提供了从硬件设计、软件容错到深度调试的系统性解决方案,帮助开发者构建鲁棒的时钟初始化策略,彻底告别启动卡顿问题。

bb456的博客 929

Oracle19c-集群节点重新添加

Oracle RAC集群在极端情况下,如硬件、主机,集群软件损坏,导致集群节点永久无法使用,需要对集群节点进行修复,删除节点集群信息并重新加入集群,以恢复集群原有的架构。 本文主要讲述一套两节点的Oracle19c RAC集群,节点一orcl01由于主机异常无法正常启动,在对主机进行重装之后,需要将orcl01节点重新加入集群的操作步骤。环境信息: 操作系统:Linux 7 RAC集群:19C 主机节点:orcl0...

sinat_36757755的博客 2352

Redis:集合SADD、SISMEMBER、SPOP、SRANDMEMBER、SREM、SMOVE、SCARD、SMEMBERS、SSCAN命令介绍

Redis学习(十二) - 集合SADD、SISMEMBER、SPOP、SRANDMEMBER、SREM、SMOVE、SCARD、SMEMBERS、SSCAN命令介绍 SADD SADD key member [member …] 可用版本: >= 1.0.0 时间复杂度: O(N), N 是被添加的元素的数量。 将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略(集合中的元素各不相同)。 演示 当key不存在时,会先创建一个空集合,再执行SADD命令将这些

kaven 6139

树莓派5新手必看:保姆级ibus中文输入法安装与配置全流程(含.bashrc设置避坑)

本文详细介绍了在树莓派5上安装和配置ibus中文输入法的完整流程,包括系统环境准备、ibus框架安装、图形界面配置及常见问题解决方案。通过清晰的步骤说明和避坑指南,帮助新手快速实现中文输入功能,提升开发效率。

weixin_29159441的博客 536

二、redis对象类型及编码

redis对象

u010342147的博客 560

YOLO26改进 - SPPF模块 | 发论文神器!LSKA注意力改进SPPF,增强多尺度特征提取能力,高效涨点!!!

本文介绍了Large Separable Kernel Attention (LSKA)模块及其在YOLO26中的结合应用。LSKA旨在解决Visual Attention Networks (VAN)使用大内核卷积时的计算效率问题,通过将2D深度卷积层的卷积核分解为级联的水平和垂直1-D卷积核,降低了计算复杂度和内存占用,且使VAN更关注物体形状。我们将集成LSKA的SPPF_LSKA模块引入YOLO26,大量实验表明,改进后的模型在对象识别、检测、分割和稳健性测试上表现出色。

魔改工程师的博客 255

6.4 直流无刷电机(BLDC):测试与性能评估

本文系统阐述了直流无刷电机(BLDC)的测试与性能评估方法,涵盖参数测量、性能测试、测试平台设计及可靠性评估。详细介绍了绕组电阻、电感和反电动势的测量原理与修正方法,以及转矩-转速特性、效率分析和动态响应测试的技术要点。通过搭建高精度测功机系统,结合自动化数据处理,实现对电机性能的全面评估。最后讨论了温升、振动、EMC等特殊测试方法,为BLDC电机的设计验证和质量控制提供了完整的技术路径。

技术工作者 446

【redis】set和zset常用命令

由于zset是有序结构,要求新增的元素,要放到合适的位置上(找位置)。如果存在多个元素,分数相同,同时为最大值,zpopmax删的时候,仍然只删除其中一个元素。log(M))N是输入的有序集合中,最小的有序集合的元素个数;zcount:返回分数在min和max之间的元素个数,默认情况下,min[max都是包含的,可以通过(排除。虽然redis的有序集合记录了开头的元素,但是删除的时候使用的是通用的删除函数。zcard :获取一个zset的基数(cardinality),即zset中的元素个数。

weixin_66409969的博客 1600

基于STFT和卷积神经网络的时序数据分类

我们提供了相应的代码和数据,读者可以直接运行并尝试在自己的数据集上进行分类实验。在本文中,我们将介绍一种基于短时傅里叶变换(STFT)和卷积神经网络(CNN)的时序数据分类方法。我们将提供可直接运行的代码和数据,以帮助读者理解和实现这一方法。STFT可以提取信号的频谱信息,有助于捕捉时序数据中的关键特征。在这个例子中,我们将使用一个简化的手势识别数据集作为示例。在这段代码中,我们使用Adam优化器和稀疏分类交叉熵损失函数进行模型的编译。然后,我们使用训练集进行模型的训练,同时使用测试集进行模型性能的验证。

CodeWOW的博客 694

【JAVA核心知识】23-F.1 Redis数据底层存储原理

Redis具有五种数据类型:String,List,Hash,Set,ZSet,底层使用了多种数据结构,同种数据类型在不同的状态也会使用不同的数据结构。 RedisObject Redis中的值都是一个个键值对,其中键总是字符串对象,值则可以是字符串,整数,列表,集合等。Redis的值对象都通过RedisObject来表示。 typedef struct redisObject{ //表示类型:string,list,hash,set,zset unsigned type:4;

积 1526

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Redis底层数据结构

题记: 文章内容输出来源:拉勾教育Java高薪训练营。 本篇文章是 Redis 学习课程中的一部分笔记。 Redis底层数据结构 Redis作为Key-Value存储系统,数据结构如下: Redis没有表的概念,Redis实例所对应的db以编号区分,db本身就是key的命名空间。比如:user:1000作为key值,表示在user这个命名空间下id为1000的元素,类似于user表的id=1000的行。 一、RedisDB结构 Redis中存在“数据库”的概念,该结构由redis.h中的redisDb定义

weixin_41018580的博客 1948

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Redis五大常用数据类型全解析

Redis作为主流NoSQL数据库,提供了五种核心数据结构:String(字符串)、List(链表)、Hash(哈希)、Set(集合)、Zset(有序集合)。每种结构都有特定应用场景:String适合缓存和计数器,List可实现消息队列,Hash适合存储对象,Set用于去重集合,Zset则适用于排行榜。底层采用不同编码方式(如ziplist、skiplist等)优化存储与性能,根据数据量自动切换。虽然Redis功能强大,但重要消息队列建议使用专业MQ工具。合理选择数据结构能显著提升Redis性能。

2501_93873871的博客 958

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Redis对象机制详解

Redis 并没有直接使用传统的数据结构(如链表、哈希表等)来存储键值对,而是在这些数据结构之上封装了一层统一的抽象——。是 Redis 内部定义的一个核心数据结构,它使得 Redis 能够以统一的方式管理不同类型的数据,并实现类型检查、多态性以及内存管理等高级功能。理解的结构是理解 Redis 对象机制的关键。Redis 的对象机制是其高性能和灵活性的基石。通过引入这一统一的抽象层,Redis 巧妙地实现了数据类型的封装、动态编码切换、对象共享以及基于引用计数的内存管理。

weixin_56018532的博客 1415

Redis7底层数据结构深度解析:从源码透视高性能设计精髓

Redis采用两层数据结构设计,通过智能编码选择优化性能。String类型根据长度使用int/embstr/raw编码;Hash和ZSet在listpack与hashtable/skiplist间自动切换;List采用quicklist+listpack结构。Redis7用listpack全面替代ziplist,解决连锁更新问题。性能优化包括:内存局部性、渐进式rehash、小整数共享等。监控工具可分析数据结构使用,配置参数需根据业务调整。未来趋势包括更多压缩算法和硬件加速。

alonewolf_99的博客 1003

Java八股文——Redis「数据结构篇」

面试官您好,listpack是Redis在5.0版本中引入、并在7.0版本中正式全面取代ziplist的一种新的紧凑型列表数据结构。在保留ziplist极高空间利用率这一核心优点的同时,彻底解决ziplist最致命的“连锁更新”(Cascading Update)问题。我们可以把listpack看作是ziplist的一次“青出于蓝而胜于蓝”的进化。1. 回顾ziplist的“阿喀琉斯之踵”——连锁更新要理解listpack的精妙之处,我们必须先回顾ziplist为什么会被取代。ziplist。

最短的捷径就是绕远路,绕远路才是我的最短捷径。 1653

Redis核心知识解析:RedisObject、编码方式、数据结构及skiplist与sortedset详解

特别是skiplist这种高效的数据结构和Redis中有序集合的巧妙结合,为处理有序数据和范围查询提供了强大的支持。本文将深入探讨RedisObject、Redis的编码方式、五种数据结构(string、list、hash、set、zset),以及重点介绍skiplist和sortedset的简介、特点和底层结构。当存储的是可以表示为整数的字符串时,Redis会采用int编码,将其转换为实际的整数类型进行存储。- 简介:Redis中最基本的类型,它可以包含任意类型的字符串,如文本、数字、二进制数据等。

2301_76867627的博客 705

Redis 面试核心知识点总结,一文读懂 Redis!

不同的数据类型适用于不同的应用场景,如 String 常用于存储简单的键值对,List 适用于实现队列和栈,Hash 适合存储对象等。这种方式主要用于解决在更新数据库后,缓存中的旧数据可能导致的数据不一致问题。通过数据分片将数据存储在不同的节点上,节点间通过 Gossip 协议进行通信和数据同步,实现了集群的水平扩展和高可用性。Redis 事务是一组命令的集合,它可以保证这组命令在执行过程中不会被其他客户端的命令打断,即这些命令要么全部执行,要么全部不执行。(本文大部分内容也总结于这篇文章)

2403_85207115的博客 1270

Java 实习生必须掌握的 Redis 核心知识点(工程向)

Redis 是基于内存的 Key–Value 数据结构服务器,Java 应用通过 TCP 上的 RESP 协议与 Redis 通信。Redis 提供多种数据结构以支持高性能缓存、计数、排行榜和简单消息队列等场景,在系统中主要用于提升性能和解耦。

m0_58809631的博客 1092

Redis数据结构底层编码原理与性能优化实战

在分布式缓存与数据存储领域,数据结构是系统性能与效率的核心基础。其底层编码实现原理直接决定了内存使用效率与操作性能,是进行系统调优和问题排查的关键。Redis作为高性能键值数据库,其核心价值在于通过智能的编码转换机制,在内存占用与操作复杂度之间取得最佳平衡,从而支撑高并发、低延迟的应用场景。例如,对于Hash结构,当字段较少且值较短时,会采用内存紧凑的ziplist编码;而当数据规模增长时,则会自动转换为查询更快的hashtable编码。理解这些编码的转换阈值与行为,例如通过调整hash-max-zipli

weixin_33812433的博客 392

redis 核心数据结构

redis是一个开源的使用C语言编写的一个kv存储系统,是一个速度非常快的非关系远程内存数据库。它支持包括String、List、Set、Zset、hash五种数据结构。除此之外,通过复制、持久化和客户端分片等特性,用户可以很方便地将redis扩展成一个能够包含数百GB数据和每秒处理上百万次的请求的系统。目前支持多种语言的api,方便用户使用。

天天新知 658

Redis 知识点总结

某个 key 访问量极大导致单节点压力过高。解决:本地缓存(Caffeine)、key 拆分为多份(key_1, key_2…)、读写分离、Redis Proxy 层缓存。

mmsyyxkmnew的博客 565

redis-2-数据结构内部编码-单线程-String命令

type 命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、list(列表)、hash(哈希)、set(集合)、zset(有序集合),但这些只是 Redis 对外的数据结构集合就是SetZset就是除了存元素之外,还要存储score就是权重,对权重进行优先级排序raw就是最基本的字符串,int是用来计数的,当value就是一个整数的时候,可能就会使用redis直接使用int来保存,embstr其实就是存储短字符串的,raw是存储长字符串的,这个是redis自动处理的。

ck的博客 1084
上一篇: Java中高级核心知识全面解析——Redis(集群【概述{主从复制、哨兵、集群化}、数据分区方案、节点通信机制、数据结构简析】)5
下一篇: 炸裂!这份阿里P8大佬手写“Java核心技能精选”惨遭疯抢!
JavaCaiy
博客等级 码龄6年 1万+粉丝 95原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值