Redis(七) zset有序集合类型

news2025/2/24 17:27:44

在这里插入图片描述

文章目录

  • 前言
  • 命令
    • 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.coloradmin.cn/o/1628501.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

航片水体空洞修补

水体空洞情况如下图所示&#xff1a; 水体空洞修补结果如下图所示&#xff1a; 操作视频教程&#xff1a; MCM智拼图软件V8.5-漏洞空洞修补-水体修补_哔哩哔哩_bilibili

【SDC时序约束】1.主时钟创建

一、时钟 DC工具在进行综合时&#xff0c;需要根据一个时钟进行时序分析。   因此我们需要通过SDC给DC提供一个时钟。   时钟创建是必须的&#xff0c;在创建时钟的同时对时钟进行约束&#xff0c;从而确定整个设计的性能和限制外部时钟。 二、时钟创建 时钟约束通过creat…

详解centos8 搭建使用Tor 创建匿名服务和匿名网站(.onion)

1 Tor运行原理&#xff1a; 请求方需要使用&#xff1a;洋葱浏览器&#xff08;Tor Browser&#xff09;或者Google浏览器来对暗&#xff0c;网网站进行访问 响应放需要使用&#xff1a;Tor协议的的Hidden_service 2 好戏来了 搭建步骤&#xff1a; 1.更新yum源 rpm -Uvh h…

React复习笔记

基础语法 创建项目 借助脚手架&#xff0c;新建一个React项目(可以使用vite或者cra&#xff0c;这里使用cra) npx create-react-app 项目名 create-react-app是React脚手架的名称 启动项目 npm start 或者 yarn start src是源文件index.js相当于Vue的main.js文件。整个…

C++—DAY4

在Complex类的基础上&#xff0c;完成^&#xff0c;<<&#xff0c;>>&#xff0c;~运算符的重载 #include <iostream>using namespace std; class Complex {int rel;int vir; public:Complex(){}Complex(int rel,int vir):rel(rel),vir(vir){}void show(){c…

力扣每日一题-总行驶距离-2024.4.25

力扣题目&#xff1a;总行驶距离 题目链接: 2739.总行驶距离 题目描述 代码思路 直接用数学模拟计算即可 代码纯享版 class Solution {public int distanceTraveled(int mainTank, int additionalTank) {int sum 0;while(additionalTank > 0){if(mainTank > 5){mai…

动静态库以及动态链接

文章目录 静态库制作静态库如何使用静态库 动态库动态库的制作动态库的使用动态链接 库是给别人用的&#xff0c;所以库中一定不存在main函数。库一般会有lib前缀和后缀&#xff0c;去掉前缀和后缀才是库名。 静态库 静态库&#xff08;.a&#xff09;&#xff1a;程序在编译…

OpenHarmony实战开发-使用SmartPerf-Host分析应用性能

简介 SmartPerf-Host是一款深入挖掘数据、细粒度展示数据的性能功耗调优工具&#xff0c;可采集CPU调度、频点、进程线程时间片、堆内存、帧率等数据&#xff0c;采集的数据通过泳道图清晰地呈现给开发者&#xff0c;同时通过GUI以可视化的方式进行分析。该工具当前为开发者提…

C#技巧之窗体去鼠标化

简介 在窗体程序中不用鼠标&#xff0c;直接使用键盘完成想要的操作。 实现的方法有两种&#xff0c;一种是使用键盘上的Tab键使控件获得焦点&#xff0c;然后用enter键触发该控件上的事件&#xff08;一般为click事件&#xff09;。另一种是&#xff0c;为控件添加快捷键&am…

优维全新力作:统一采控平台

在本月&#xff0c;优维新一代核心系统「EasyOps」7.0大版本重磅上线&#xff0c;为广大用户带来了“更核心、更智能、更开放、更客制”的产品能力。&#xff08;点击回看&#xff1a;重磅&#xff01;优维科技发布EasyOps7.0大版本&#xff09;在本次版本能力分享上&#xff0…

基于springboot实现中药实验管理系统设计项目【项目源码+论文说明】计算机毕业设计

基于springboot实现中药实验管理系统设计演示 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了中药实验管理系统的开发全过程。通过分析中药实验管理系统管理的不足&#xff0c;创建了一个计算机管理中药实验管…

基于WOA鲸鱼优化的购售电收益与风险评估算法matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于WOA鲸鱼优化的购售电收益与风险评估算法.WOA优化算法是一种基于鲸鱼捕食过程的仿生优化算法&#xff0c;其包括鲸鱼行走觅食、鲸鱼包围以及鲸鱼螺旋捕食三个步骤。在WOA优…

用 Python 创建 Voronoi 图

概述 最常见的空间问题之一是找到距离我们当前位置最近的兴趣点 (POI)。假设有人很快就会耗尽汽油&#xff0c;他/她需要在为时已晚之前找到最近的加油站&#xff0c;解决这个问题的最佳解决方案是什么&#xff1f;当然&#xff0c;驾驶员可以检查地图来找到最近的加油站&…

C++从入门到精通——string类

string类 前言一、为什么学习string类C语言中的字符串示例 二、标准库中的string类string类string类的常用接口说明string类对象的常见构造string类对象的容量操作string的接口测试及使用string类对象的访问及遍历操作下标和方括号遍历范围for遍历迭代器遍历相同的代码&#xf…

6.模板初阶

目录 1.泛型编程 2. 函数模板 2.1 函数模板概念 2.2函数模板格式 2.3 模板的实现 2.4函数模板的原理 2.5 函数模板的实例化 3.类模板 1.泛型编程 我们如何实现一个 交换函数呢&#xff1f; 使用函数重载虽然可以实现&#xff0c;但是有一下几个不好的地方&#xff1a; …

iOS - 多线程-读写安全

文章目录 iOS - 多线程-读写安全1. 多读单写1.1 场景1.2 实现方案1.2.1 pthread_rwlock&#xff1a;读写锁1.2.1.1 示例 1.2.2 dispatch_barrier_async&#xff1a;异步栅栏调用1.2.2.1 示例 iOS - 多线程-读写安全 假设有一个文件&#xff0c;A线程进行读取操作&#xff0c;B…

刷题日记 ---- 顺序表与链表相关经典算法题(C语言版)

目录 1. 移除元素2. 合并两个有序数组3. 移除链表元素4. 反转链表5. 合并两个有序链表6. 链表的中间结点7. 环形链表的约瑟夫问题8. 分割链表总结 正文开始 1. 移除元素 题目链接: 移除元素 题目描述: 思路历程: 题目明确要求, 不能使用额外的数组空间, 也就是说不可以创建…

linux系统-FTP服务配置

目录 一、FTP简介 1.什么是FTP&#xff1f;&#xff1f;&#xff1f; 2.FTP的两种模式 二、安装配置FTP服务 1.关闭防火墙和核心防护 2.安装VSFTPD 3.修改配置文件 4.黑白名单设置 一、FTP简介 1.什么是FTP&#xff1f;&…

【Node.js工程师养成计划】之打造自己的脚手架工具

一、创建全局的自定义命令 1、打开一个空文件夹&#xff0c;新建一个bin文件夹&#xff0c;在bin文件夹下新建cli.js文件&#xff0c;js文件可以命名为cli.js&#xff08;您随意&#xff09; 2、在cli.js文件中的开头&#xff08;&#xff01;&#xff01;&#xff09;写下面这…

Prometheus Metrics指标类型 Gauge(仪表盘)

指标是用来衡量性能、消耗、效率和许多其他软件属性随时间的变化趋势。它们允许工程师通过警报和仪表盘来监控一系列测量值的演变&#xff08;如CPU或内存或磁盘使用量、请求持续时间、延迟等&#xff09;。指标在IT监控领域有着悠久的历史&#xff0c;并被工程师广泛使用&…