Redis(七) zset有序集合类型

在这里插入图片描述

文章目录

  • 前言
  • 命令
    • ZADD
    • ZCARD
    • ZCOUNT
    • ZRANGE
    • ZREVRANGE
    • ZRANGEBYSCORE
    • ZPOPMAX
    • ZPOPMIN
    • 两个阻塞版本的POP命令
      • BZPOPMAX
    • BZPOPMIN
    • ZRANK
    • ZREVRANK
    • ZSCORE
    • ZREM
    • ZREMRANGEBYRANK
    • ZREMRANGEBYSCORE
    • ZINCRBY
    • 集合间操作
      • ZINTERSTORE
      • ZUNIONSTORE
    • 命令小结
  • 内部编码
  • 使用场景

前言

对于有序集合这个名词来说,大家可能会有一些陌生,对于前面的字符串、列表、哈希、集合类型大家肯定多多少少在其他方面都有一些了解。那么什么是有序集合呢?有序集合保留了集合可以去重的特性,但与集合不同的是,有序集合中每个都有一个唯一的浮点类型的分数与之关联,也正是因为这个唯一的浮点数使得有序集合中的元素是可以维护有序性的,但这个有序不是用下标作为排序依据而是用这个分数。

在这里插入图片描述

列表、集合、有序集合的异同点:

数据结构是否允许重复元素是否有序有序依据应用场景
列表索引下标时间轴、消息队列等
集合标签、社交等
有序集合分数排⾏榜系统、社交等

zset 中的有序指的是集合中的元素的大小顺序是一定的,默认是按照分数的升序排列的。zset 中的分数只是起到辅助排序的作用。

命令

ZADD

ZADD 命令添加或者更新指定的元素以及关联的分数到 zset 中,分数应该符合 double 类型,+inf/-inf 作为正负极限也是合法的。
ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member[score member...]

选项:

  • 默认不添加 NX 或者 XX 选项的情况下,如果要添加的元素不存在,则会将该元素添加到 zset 中,如果存在则会修改该元素
  • NX,当要添加的元素在 zset 中不存在时才添加成功,不存在时直接返回,也就是使用 NX 选项不会修改已存在的元素的值
  • XX,当要添加的元素不存在时,直接返回,之后当元素已经存在的时候才会修改已存在的元素的值,也就是说使用XX元素只会修改元素,而不会添加新的元素
  • LT/GT:LT(less than)选项只有当前已经存在的元素的值大于要修改的值的时候才会对元素的值进行修改,GT则相反
  • CH:默认情况下,ZADD 返回的值是本次操作添加的元素的个数,但指定这个选项之后,返回的值就还包括本次更新的元素的个数
  • INCR:此时命令类似 ZINCRBY 的效果,将元素的分数加上指定的分数。此时只能指定一个元素和分数

时间复杂度:O(logN)
返回值:本次添加成功的元素的个数

之前的 string、list、hash 和 set 类型添加元素的时间复杂度都是 O(1),而 zset 添加元素的时间复杂度之所以是 logN 是因为 zset 的内部编码是由跳表实现的,而为了保证 zset 的有序性,新添加进去的元素需要放到指定的位置,所以时间复杂度就是 O(logN)。

127.0.0.1:6379> zadd key 92 zhangsan 93.5 lisi 95 wangwu
3
127.0.0.1:6379> zrange key 0 -1 withscores #该命令获取zset中的元素,后面为大家详细讲
zhangsan
92
lisi
93.5
wangwu
95
127.0.0.1:6379> ZADD key nx 100 zhangsan #使用了nx选项因为zhangsan已经存在了,所以修改数据失败
0
127.0.0.1:6379> zrange key 0 -1 withscores
zhangsan
92
lisi
93.5
wangwu
95
127.0.0.1:6379> ZADD key nx 100 zhaoliu #zhaoliu不存在,所以添加成功
1
127.0.0.1:6379> zrange key 0 -1 withscores
zhangsan
92
lisi
93.5
wangwu
95
zhaoliu
100
127.0.0.1:6379> ZADD key xx 95 xiaoming #使用xx选项意味着就是修改zset中元素的值,但是xiaoming不存在与zset中,所以修改失败
0
127.0.0.1:6379> zrange key 0 -1 withscores
zhangsan
92
lisi
93.5
wangwu
95
zhaoliu
100
127.0.0.1:6379> ZADD key xx 95 zhangsan #zhangsan存在于zset中,所以修改成功,但是这里返回的值是0,为了能够体现出来修改成功,我们再加上CH选项
0
127.0.0.1:6379> zrange key 0 -1 withscores
lisi
93.5
wangwu
95
zhangsan
95
zhaoliu
100
127.0.0.1:6379> ZADD key xx ch 93.5 zhangsan #添加选项ch使得返回的值包括了更新的元素的个数
1
127.0.0.1:6379> zrange key 0 -1 withscores
lisi
93.5
zhangsan
93.5
wangwu
95
zhaoliu
100
redis> zadd key lt 90 zhangsan #使用lt选项之后添加的元素的值小于已经存在的元素的值,修改成功
(integer) 0
redis> zrange key 0 -1 withscores
1) "zhangsan"
2) "90"
3) "lisi"
4) "93.5"
5) "wnagwu"
6) "95"
7) "zhaoliu"
8) "100"
redis> zadd key lt 95 zhangsan #要修改的值大于已经存在的元素的值,添加失败
(integer) 0
redis> zrange key 0 -1 withscores
1) "zhangsan"
2) "90"
3) "lisi"
4) "93.5"
5) "wnagwu"
6) "95"
7) "zhaoliu"
8) "100"
redis> zadd key gt 96 wangwu #使用gt选项,要添加的值小于已经存在的元素的值,修改元素失败
(integer) 0
redis> zrange key 0 -1 withscores
1) "zhangsan"
2) "90"
3) "lisi"
4) "93.5"
5) "wangwu"
6) "98"
7) "zhaoliu"
8) "100"
redis> zadd key gt 99 wangwu #添加成功
(integer) 0
1) "zhangsan"
2) "90"
3) "lisi"
4) "93.5"
5) "wangwu"
6) "99"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZADD key xx incr 5 zhangsan #使用incr选项可以不必知道需要修改的元素的值,然后直接讲zset中元素的值加上指定元素
98.5
127.0.0.1:6379> zrange key 0 -1 withscores
lisi
93.5
wangwu
95
zhangsan
98.5
zhaoliu
100

如果 zset 中存在分数相同的元素,那么会以 member 的字典序进行排序。

ZCARD

ZCARD 命令获取一个 zset 的基数,即 zset 中元素的个数。ZCARD key

时间复杂度:O(1),这里之所以是O(1)是因为用了一个变量来维护元素个数
返回值:zset 内元素的个数

127.0.0.1:6379> zrange key 0 -1 withscores
1) "lisi"
2) "93.5"
3) "wangwu"
4) "95"
5) "zhangsan"
6) "98.5"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZCARD key
(integer) 4

ZCOUNT

ZCOUNT 命令返回分数在 min 和 max 之间的元素的个数,默认情况下 min 和 max 都是包含的,可以通过 ( 排除。ZCOUNT key min max

时间复杂度:O(logN)
返回值:min 到 max 之间元素的个数

这里的时间复杂度为什么不是O(logN + M),M为区间大小呢?这是因为 zcount 在找 min 和 max 之间元素的个数的时候,会先去找到 min 和 max 所对应的元素的“下标”,然后用 max 的下标减去 min 的下标就得到 min 和 max 之间元素的个数了,而不是找到 min 元素之后继续向后找,遍历一个元素 count++,直到找到 max 元素所在的位置。

127.0.0.1:6379> zrange key 0 -1 withscores
1) "lisi"
2) "93.5"
3) "wangwu"
4) "95"
5) "zhangsan"
6) "98.5"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> zcount key 95 100 #范围值包括95100
(integer) 3
127.0.0.1:6379> zcount key (95 100 #范围内的值不包括95
(integer) 2
127.0.0.1:6379> zcount key -inf inf #获取负无穷到正无穷之间的元素的个数,也可以理解为zset中所有元素的个数
(integer) 4

ZRANGE

ZRANGE 命令返回指定区间之间的元素,分数按照升序。带上 WITHSCORES 可以将对应的分数也返回。ZRANGE key start end [WITHSCORES]

这里有人可能会问了,这不是集合吗,集合为什么会有下标这样的说法呢?是的,这里虽然是集合,但是这个集合是有序集合,元素之间是有先后顺序的,谁在前,谁在后都是由明确的顺序的,所以这个有序集合也就可以有下标这样的概念了。同样这里的下标也是支持负数的。

时间复杂度:O(logN+M),N为zset中元素个数,M为区间范围
返回值:区间之内的元素

127.0.0.1:6379> zrange key 1 2
wangwu
zhangsan
127.0.0.1:6379> zrange key 1 2 withscores
wangwu
95
zhangsan
98.5
127.0.0.1:6379> zrange key 0 -1 withscores
lisi
93.5
wangwu
95
zhangsan
98.5
zhaoliu
100

ZREVRANGE

ZREVRANGE 命令获取指定区间的元素,但是结果是按照分数的降序显示的,同样的带上 WITHSCORES 也可将对应的分数返回。备注:这个命令可能在6.2.0之后废弃,并且功能合并到RANGE中。ZREVRANGE key start end [WITHSCORES]

时间复杂度:O(logN+M),N为zset中元素个数,M为区间范围
返回值:区间内的元素

127.0.0.1:6379> zrange key 0 -1 withscores
1) "lisi"
2) "93.5"
3) "wangwu"
4) "95"
5) "zhangsan"
6) "98.5"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZREVRANGE key 0 -1 withscores
1) "zhaoliu"
2) "100"
3) "zhangsan"
4) "98.5"
5) "wangwu"
6) "95"
7) "lisi"
8) "93.5"
127.0.0.1:6379> ZREVRANGE key 1 3 withscores
1) "zhangsan"
2) "98.5"
3) "wangwu"
4) "95"
5) "lisi"
6) "93.5"

ZRANGEBYSCORE

ZRANGEBYSCORE 命令返回分数在 min 到 max 之间的元素,默认情况下 min 和 max 都是包含的。可以通过 ( 排除。备注:这个命令可能在6.2.0之后废弃,并且功能合并到RANGE中。

时间复杂度:O(logN + M),N为zset中元素的个数,M为区间范围
返回值:区间内的元素

127.0.0.1:6379> zrange key 0 -1 withscores
1) "lisi"
2) "93.5"
3) "wangwu"
4) "95"
5) "zhangsan"
6) "98.5"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZRANGEBYSCORE key 95 100 withscores
1) "wangwu"
2) "95"
3) "zhangsan"
4) "98.5"
5) "zhaoliu"
6) "100"
127.0.0.1:6379> ZRANGEBYSCORE key (95 (100 withscores #通过加上(可以排除掉min或者max的值
1) "zhangsan"
2) "98.5"

ZPOPMAX

ZPOPMAX 命令删除并返回分数最高的 count 个元素。ZPOPMAX key [count]

时间复杂度:O(logN * M),M为要删除的元素的个数
返回值:分数和元素列表

127.0.0.1:6379> ZPOPMAX key
1) "zhaoliu"
2) "100"
127.0.0.1:6379> ZPOPMAX key 2
1) "zhangsan"
2) "98.5"
3) "wangwu"
4) "95"

因为 zset 的有序性,默认将分数最大的元素放在最后面,那么这个 ZPOPMAX 每次删除最大的元素,也就是最末尾的元素,这属于是一个特殊的位置,为什么不使用一个特殊的变量来存储这个位置呢?这样不就可以使得么每次删除一个最大值的时间复杂度都是 O(1)呢?其实 redis 底层使用了一个特殊的变量来标记末尾的位置,但是具体为啥 redis 没有这样用,我们也不知道,换句话说,ZPOPMAX 命令是可以优化的。

ZPOPMIN

ZPOPMIN 命令删除并返回 count 个分数最低的元素。ZPOPMIN key [count]

时间复杂度:O(logN * M),M为要删除的元素的个数
返回值:分数和列表元素

127.0.0.1:6379> zadd key 93 zhangsan 95 lisi 97.5 wangwu 100 zhaoliu
(integer) 4
127.0.0.1:6379> zrange key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "95"
5) "wangwu"
6) "97.5"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZPOPMIN key
1) "zhangsan"
2) "93"
127.0.0.1:6379> ZPOPMIN key 2
1) "lisi"
2) "95"
3) "wangwu"
4) "97.5"
127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhaoliu"
2) "100"

两个阻塞版本的POP命令

对于 zset 来说存在两个阻塞版本的 POP 操作,分别是 BZPOPMAX 和 BZPOPMIN。

BZPOPMAX

BZPOPMAX 命令是 ZPOPMAX 的阻塞版本。BZPOPMAX key[key...] timeout

时间复杂度:O(logN)
返回值:元素列表

在这里插入图片描述
在这里插入图片描述

BZPOPMIN

BZPOPMIN 命令是 ZPOPMIN 的阻塞版本。BZPOPMIN key [key...] timeout

<font color = “CC0000”.时间复杂度:O(logN )
返回值:元素列表

在这里插入图片描述

ZRANK

ZRANK 命令返回指定元素的排名(升序),排名从0开始。ZRANK key member

时间复杂度:O(logN)
返回值:排名

127.0.0.1:6379> zadd key 93 zhangsan 94.5 lisi 97 wnagwu 100 zhaoliu
(integer) 4
127.0.0.1:6379> ZRANK key zhaoliu
(integer) 3

ZREVRANK

ZREVRANK 命令返回指定元素的排名(降序),排名从0开始。ZREVRANK key member

时间复杂度:O(logN)
返回值:排名

127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "94.5"
5) "wnagwu"
6) "97"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZREVRANK key lisi
(integer) 2
127.0.0.1:6379> 

ZSCORE

ZSCORE 命令返回指定元素的分数。ZSCORE key member

时间复杂度:O(logN)
返回值:分数

127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "94.5"
5) "wnagwu"
6) "97"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZSCORE key lisi
"94.5"

ZREM

ZREM 命令删除指定元素。ZREM key member[member...]

时间复杂度:O(logN)
返回值:本次操作删除的元素的个数

127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "94.5"
5) "wnagwu"
6) "97"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZREM key zhangsan lisi
(integer) 2
127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "wnagwu"
2) "97"
3) "zhaoliu"
4) "100"

ZREMRANGEBYRANK

ZREMRANGEBYRANK 命令按照排序,升序删除指定排名范围的元素。ZREMRANGEBYRANK key start end

时间复杂度:O(logN + M),M为区间范围
返回值:本次操作删除的元素的个数

127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "94.5"
5) "wangwu"
6) "97"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZREMRANGEBYRANK key 1 2
(integer) 2
127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "zhaoliu"
4) "100"

ZREMRANGEBYSCORE

ZREMRANGEBYSCORE 命令按照顺序,按照分数删除指定范围的元素。ZREMRANGEBYSCORE key start end

时间复杂度:O(logN + M),M为区间范围
返回值:本次操作删除的元素的个数

127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "94.5"
5) "wangwu"
6) "97"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZREMRANGEBYSCORE key 95 100
(integer) 2
127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "94.5"

ZINCRBY

ZINCRBY 命令为指定的元素的关联分数添加指定的分数。ZINCRBY key increment member

时间复杂度:O(logN)
返回值:增加后元素的分数

127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "94.5"
5) "wangwu"
6) "97"
7) "zhaoliu"
8) "100"
127.0.0.1:6379> ZINCRBY key 10 zhaoliu
"110"
127.0.0.1:6379> ZRANGE key 0 -1 withscores
1) "zhangsan"
2) "93"
3) "lisi"
4) "94.5"
5) "wangwu"
6) "97"
7) "zhaoliu"
8) "110"

集合间操作

同样的 zset 也是支持集合间操作的,但是与 set 不同的是,zset 只支持交集和并集的操作,并且对于这些交集和并集的操作,也只支持 store 版本的操作,也就是 ZINTERSTORE 和 ZUNIONSTORE 操作。

ZINTERSTORE

ZINTERSTORE 将给定几个的交集存放在一个指定集合中。ZINTERSTORE destination numkeys key[key...] [WEIGHTS weight[weight...]] [AGGREGATE <SUM | MIN | MAX>]

  • numkeys:表示集合的数量,这里为什么需要指定集合的数量呢?这是因为我们后面的 weight 的数量也是不确定的,为了区分出集合名和 weight,所以需要指定出集合的数量 numkeys
  • weights:这是集合所占的权重,在进行交集操作的时候,每个集合中的每个元素的分数都需要乘上对应的权重
  • aggregate:指明,对于不同集合中求交集的操作,每个元素的分数该怎么计算,sum 表示相同元素分数之和,max 表示取分数最大的,min表示取分数最小的

时间复杂度:O(N*K) + O(M*logM),N是输入的有序集合中,最小的有序集合的个数,k是集合的数量,M是最终结果的有序集合的元素个数
返回值:目标集合元素个数

127.0.0.1:6379> zadd key 90 zhangsan 93 lisi 97.5 wangwu 96 zhaoliu
(integer) 4
127.0.0.1:6379> zadd key2 89 xiaoming 91 xiaoli 95 wangwu 94 zhangsan
(integer) 4
127.0.0.1:6379> ZINTERSTORE key3 2 key key2
(integer) 2
127.0.0.1:6379> zrange key3 0 -1 withscores #没指定aggregate选项的时候,默认是sum求和
1) "zhangsan"
2) "184"
3) "wangwu"
4) "192.5"
127.0.0.1:6379> ZINTERSTORE key4 2 key key2 weights 4 6 #指定权重之后,对于交集元素key的每个元素会乘上4,key2中的交集元素会乘上6
(integer) 2
127.0.0.1:6379> zrange key4 0 -1 withscores
1) "zhangsan"
2) "924"
3) "wangwu"
4) "960"
127.0.0.1:6379> ZINTERSTORE key5 2 key key2 aggregate max #交集元素的分数取最大值
(integer) 2
127.0.0.1:6379> zrange key5 0 -1 withscores
1) "zhangsan"
2) "94"
3) "wangwu"
4) "97.5"
127.0.0.1:6379> ZINTERSTORE key6 2 key key2 aggregate min #交集元素的分数取最小值
(integer) 2
127.0.0.1:6379> zrange key6 0 -1 withscores
1) "zhangsan"
2) "90"
3) "wangwu"
4) "95"

ZUNIONSTORE

ZUNIONSTORE 命令将给定集合的并集放在指定的集合中。ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

这个命令中各个选项的含义和 ZINTERSTORE 是一样的,这里就不为大家过多展示了。

时间复杂度:O(N) + O(M*logM),N是输入的结合的所有元素的个数,M是最终集合的元素的个数
返回值:目标集合的元素的个数

命令小结

命令执行效果时间复杂度
zadd key score member [score member …]向zset中添加元素O(k * log(n)),k 是添加成员的个数,n 是当前有有序集合的元素个数
zcard key获取zset中元素个数O(1)
zscore key member获取指定元素的分数O(logN)
zrank key member获取指定元素的排名(升序)O(logN)
zrevrank key member获取指定元素的排名(降序)O(logN)
zrem key member [member …]删除指定的元素O(k * log(n)),k 是删除成员的个数,n 是当前有序集合的元素个数
zincrby key increment member使得zset中指定元素的分数加上指定值O(log(n)),n 是当前有序集合的元素个数
zrange key start end [withscores]获取指定下标范围内的元素(升序形式返回)O(k + log(n)),k 是获区间范围,n 是当前有序集合的元素个数
zrevrange key start end [withscores]获取指定下标范围内的元素(降序形式返回)O(k + log(n)),k 是获区间范围,n 是当前有序集合的元素个数
zrangebyscore key min max [withscores]获取指定分数范围内的元素(升序形式返回)O(k + log(n)),k 是获区间范围,n 是当前有序集合的元素个数
zrevrangebyscore key max min [withscores]获取指定分数范围内的元素(降序形式返回)O(k + log(n)),k 是获区间范围,n 是当前有序集合的元素个数
ZCOUNT key min max获取min到max分数之间的元素个数O(log(n)),n 是当前有序集合的元素个数
zremrangebyrank key start end删除start到end排名之间的元素O(logN + M),M为区间范围
zremrangebyscore key min max删除min到max分数之间的元素O(logN + M),M为区间范围
zinterstore destination numkeys key [key …]将给定集合的交集元素放在指定集合中O(N*K) + O(M*logM),N是输入的有序集合中,最小的有序集合的个数,k是集合的数量,M是最终结果的有序集合的元素个数
zunionstore destination numkeys key [key…]将给定集合的并集元素放在指定集合中O(N) + O(M*logM),N是输入的结合的所有元素的个数,M是最终集合的元素的个数

内部编码

有序集合类型的内部编码有两种:

  • ziplist:当zset中的元素个数和每个元素的长度较小的时候,redis 底层会用 ziplist 来作为 zset 的颞部实现
  • skiplist(跳表):当 zset 中元素不满足 ziplist 的条件的时候,就会选择 skiplist 来作为 zset 的内部实现
127.0.0.1:6379> zadd key7 1 zhangsan 2 lisi 3 wangwu
(integer) 3
127.0.0.1:6379> OBJECT encoding key7
"ziplist"
127.0.0.1:6379> zadd key7 4 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
(integer) 1
127.0.0.1:6379> OBJECT encoding key7
"skiplist"

使用场景

  1. 排行榜系统:zset非常适合用于实现各种排行榜,如游戏排行榜、文章阅读排行榜、电商网站的销售排行榜等。你可以将用户的得分作为分数(score)存储,用户ID作为元素(member)存储。这样,你就可以通过zset的排序特性快速获取排名靠前的用户。
  2. 延时队列:zset可以用来实现一个简单且高效的延时队列。你可以将任务作为元素存储,任务的执行时间作为分数存储。当任务到达执行时间时,就可以从zset中取出并执行。这种方式比使用Redis的列表(List)实现延时队列更加灵活和高效。
  3. 按时间排序的数据:对于需要按照时间顺序排列的数据,如日志、事件等,zset也是一个很好的选择。你可以将时间戳作为分数存储,数据内容作为元素存储。这样,你就可以按照时间顺序快速地获取数据。
  4. 唯一性约束且需要排序的场景:在某些情况下,你可能需要存储一组唯一的数据,并且这些数据还需要按照某种顺序进行排序。例如,你可能需要存储一组唯一的用户名,并且按照用户的注册时间进行排序。这时,你可以使用zset来实现这个需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/660119.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

下一代云原生应用引擎OpenNJet体验

文章目录 前言OpenNJet 介绍OpenNJet VS NGINXOpenNJet 安装OpenNJet 动态配置体验动态location动态黑名单动态灰度发布 体验感受 前言 作为一名技术人员&#xff0c;我们应时刻保持对行业动态的关注&#xff0c;今天我们就来体验一下号称下一代云原生应用引擎OpenNJet。 Ope…

Python urllib 爬虫入门(2)

本文为Python urllib类库爬虫更入门的一些操作和爬虫实例及源码。 目录 模拟浏览器请求 简单模拟 设置随机user-agent 请求超时 HTTP请求类型 Get请求 Post请求 抓取网页动态请求 封装ajax请求 调用 循环调用 抓取小说 封装请求函数 把html写入本地分析 调用 正…

JWT是什么?如何使用?

JWT是什么&#xff1f;如何使用&#xff1f; 前言什么是JWT&#xff1f;概念工作方式JWT的组成HeaderPayloadSignatrue 实战引入依赖自定义注解定义实体类定义一个JWT工具类业务校验并生成token定义拦截器配置拦截器定义接口方法并添加注解开始验证 使用场景注意事项 JWT与传统…

2024最新的,免费的 ChatGPT 网站AI(八个)

ChatGPT是美国人工智能研究实验室OpenAI在2022年11月推出的一款人工智能技术驱动的语言模型应用。它基于GPT-3.5架构&#xff08;后续还有GPT-4架构的升级版&#xff09;构建&#xff0c;拥有强大的自然语言处理能力和上下文理解能力&#xff0c;能够参与多轮对话&#xff0c;为…

【RAG 博客】Haystack 中的 DiversityRanker 与 LostInMiddleRanker 用来增强 RAG pipelines

Blog&#xff1a;Enhancing RAG Pipelines in Haystack: Introducing DiversityRanker and LostInTheMiddleRanker ⭐⭐⭐⭐ 文章目录 Haystack 是什么1. DiversityRanker2. LostInTheMiddleRanker使用示例 这篇 blog 介绍了什么是 Haystack&#xff0c;以及如何在 Haystack 框…

上位机图像处理和嵌入式模块部署(树莓派4b开机界面程序自启动)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们学习了如何在树莓派4b上面开发qt&#xff0c;也学习了如何用/etc/rc.local启动控制台程序&#xff0c;那今天我们继续学习一下如何利用树莓…

PotatoPie 4.0 实验教程(35) —— FPGA实现摄像头图像二值化膨胀效果

手机扫码 链接直达 https://item.taobao.com/item.htm?ftt&id776516984361 什么是图像二值化膨胀&#xff0c;有什么作用&#xff1f; 图像二值化膨胀是图像处理中的一种基本操作&#xff0c;它用于扩展和增强二值图像中的白色区域。具体而言&#xff0c;二值化膨胀操作…

【VSCode调试技巧】Pytorch分布式训练调试

最近遇到个头疼的问题&#xff0c;对于单机多卡的训练脚本&#xff0c;不知道如何使用VSCode进行Debug。 解决方案&#xff1a; 1、找到控制分布式训练的启动脚本&#xff0c;在自己的虚拟环境的/lib/python3.9/site-packages/torch/distributed/launch.py中 2、配置launch.…

微视网媒:引领新媒体时代的视觉先锋

在信息爆炸的时代&#xff0c;内容消费的方式日新月异&#xff0c;而“微视网媒”正是这场媒体变革中的佼佼者。凭借其独特的视角、精湛的制作和广泛的传播渠道&#xff0c;微视网媒不仅改变了人们获取信息的方式&#xff0c;更在不断地塑造着未来的媒体生态。 一、创新内容&am…

Hotcoin Research | 市场洞察:2024年4月22日-28日

加密货币市场表现 本周内加密大盘整体呈现出复苏状态&#xff0c;在BTC减半后进入到震荡上行周期。BTC在$62000-66000徘徊&#xff0c;ETH在$3100-3300徘徊&#xff0c;随着港交所将于 4 月 30 日开始交易嘉实基金的比特币和以太坊现货 ETF&#xff0c;周末行情有一波小的拉升…

【Qt】QtCreator忽然变得很卡

1. 问题 Qt Creator忽然变得很卡。电脑里两个版本的Qt Creator&#xff0c;老版本的开启就卡死&#xff0c;新版本好一点&#xff0c;但是相比于之前也非常卡&#xff0c;最明显的是在 ctrl鼠标滚轮 放大缩小的时候&#xff0c;要卡好几秒才反应。 2. 解决方案 2.1 方法1 关…

2000.1-2023.8中国经济政策不确定性指数数据(月度)

2000.1-2023.8中国经济政策不确定性指数数据&#xff08;月度&#xff09; 1、时间&#xff1a;2000.1-2023.8 2、指标&#xff1a;CNEPU&#xff08;经济政策不确定性指数&#xff09; 3、来源&#xff1a;China Economic Policy Uncertainty Index 4、用途&#xff1a;可…