redis基础数据结构

news2024/11/25 9:29:28

文章目录

  • 前言
  • 字符串
    • 常见命令
    • 内部编码
    • 使用场景
      • 1、缓存(Cache)功能
      • 2、计数
      • 3、共享Session
      • 4、限速
  • 哈希
    • 命令
    • 内部编码
    • 使用场景
      • 存储结构化数据
  • 列表
    • 命令
    • 内部编码
    • 使用场景
      • 1.阻塞消息队列模型
      • 2.文章列表
      • 3.微博 Timeline
  • 集合
    • 命令
    • 内部编码
    • 使用场景
      • 1.给用户增加标签
      • 2.通过Set来计算用户之间的共同好友
      • 3.使用Set统计UV
  • 有序集合
    • 命令
    • 内部编码
    • 使用场景
      • 排行榜

前言

Redis提供了5种数据结构,理解每种数据结构的特点对于Redis开发运维非常重要,同时掌握Redis的单线程命令处理机制,会使数据结构和命令的选择事半功倍。

字符串

字符串类型是 Redis 最基础的数据类型,关于字符串需要特别注意:1)⾸先 Redis 中所有的键的类型都是字符串类型,⽽且其他⼏种数据结构也都是在字符串类似基础上构建的,例如列表和集合的元素类型是字符串类型,所以字符串类型能为其他 4 种数据结构的学习奠定基础。

常见命令

常用命令: set,get,decr,incr,mget 等。
大概得命令一览
在这里插入图片描述
在这里插入图片描述

内部编码

字符串类型的内部编码有 3 种:
• int:8 个字节的⻓整型。
• embstr:⼩于等于 39 个字节的字符串。
• raw:⼤于 39 个字节的字符串。
Redis 会根据当前值的类型和⻓度动态决定使⽤哪种内部编码实现。
当然这里的具体字节,大家不用强行记忆,因为都是根据具体的场景去规定使用哪种编码格式实现。

使用场景

1、缓存(Cache)功能

是比较典型的缓存使用场景,其中Redis作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。
在这里插入图片描述
具体的伪代码实现如下
在这里插入图片描述

2、计数

许多应用都会使用Redis作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。例如笔者所在团队的视频播放数系统就是使用Redis作为视频播放数计数的基础组件,用户每播放一次视频,相应的视频播放数就会自增1,如图所示:
在这里插入图片描述
具体的伪代码实现
在这里插入图片描述

3、共享Session

一个分布式Web服务将用户的Session信息(例如用户登录信息)保存在各自服务器中,这样会造成一个问题,出于负载均衡的考虑,分布式服务会将用户的访问均衡到不同服务器上,用户刷新一次访问可能会发现需要重新登录,这个问题是用户无法容忍的。
在这里插入图片描述

为了解决这个问题,可以使用Redis将用户的Session进行集中管理,如图所示,在这种模式下只要保证Redis是高可用和扩展性的,每次用户更新或者查询登录信息都直接从Redis中集中获取。
在这里插入图片描述

4、限速

很多应用出于安全的考虑,会在每次进行登录时,让用户输入手机验证码,从而确定是否是用户本人。但是为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次。
在这里插入图片描述

在这里插入图片描述
上述就是利用Redis实现了限速功能,例如一些网站限制一个IP地址不
能在一秒钟之内访问超过n次也可以采用类似的思路。


哈希

几乎所有的编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组。在Redis中,哈希类型是指键值本身又是一个键值对结构,形如value={{field1,value1},…{fieldN,valueN}},Redis键值对和哈希类型二者的关系可以用来表示。
在这里插入图片描述

命令

常用命令: hget,hset,hgetall 等。
具体的hash命令的时间复杂度:
在这里插入图片描述
Redis 的哈希(Hash)数据结构允许用户存储键值对的集合。哈希中的每个字段(field)都对应一个值(value),并且这些字段都是唯一的。下面是一些 Redis 哈希数据结构的常用命令及其解释:

HSET

命令:HSET key field value
解释:将哈希表 key 中的字段 field 的值设为 value。如果 key 不存在,一个空哈希表会被创建并执行 HSET 操作。如果字段已经存在于哈希表中,该操作会覆盖旧值。
HGET

命令:HGET key field
解释:获取存储在哈希表 key 中给定字段 field 的值。
HGETALL

命令:HGETALL key
解释:返回哈希表 key 中,所有的字段和值。
HMSET

命令:HMSET key field1 value1 field2 value2 … fieldN valueN
解释:同时设置哈希表 key 中的多个字段值。
HMGET

命令:HMGET key field1 field2 … fieldN
解释:获取哈希表 key 中多个字段的值。
HINCRBY

命令:HINCRBY key field increment
解释:将哈希表 key 中指定字段 field 的值增加 increment。
HINCRBYFLOAT

命令:HINCRBYFLOAT key field increment
解释:将哈希表 key 中指定字段 field 的值增加 increment,increment 可以是浮点数。
HDEL

命令:HDEL key field1 field2 … fieldN
解释:删除哈希表 key 中的一个或多个字段,不存在的字段将被忽略。
HEXISTS

命令:HEXISTS key field
解释:检查哈希表 key 中,指定的字段 field 是否存在。
HLEN

命令:HLEN key
解释:返回哈希表 key 中字段的数量。
HKEYS
命令:HKEYS key
解释:获取哈希表 key 中的所有字段。
HVALS
命令:HVALS key
解释:获取哈希表 key 中的所有值。
这些命令提供了对 Redis 哈希数据结构的基本操作,使得用户能够轻松地存储、检索和修改哈希表中的字段和值。
在这里插入图片描述

内部编码

哈希类型的内部编码有两种:

  • ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。
  • hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

使用场景

存储结构化数据

关系型数据表记录的两条用户信息,用户的属性作为表的列,每条用户信息作为行。
在这里插入图片描述
相比于使用字符串序列化缓存用户信息,哈希类型变得更加直观,并且在更新操作上会更加便捷。可以将每个用户定义的id定义为后缀,对file-value对应的每个用户的属性。
另外还有一个原因就是,如果使用String(json)的格式来存储UserInfo。万一我们想修改field,或者修改某个field,就需要吧整个json都读取出来,解析成对象,操作filed,再重写json字符串,再写回去。
如果使用hash的方式来表示UserInfo,就可以使用field表示对象的每个属性,此时就可以非常方便的修改、获取任何一个属性的值了。具体的伪代码如下。
在这里插入图片描述

但是需要注意的是哈希类型和关系型数据库有两点不同之处:
• 哈希类型是稀疏的,⽽关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的 field,而关系型数据库⼀旦添加新的列,所有⾏都要为其设置值,即使为 null,如图 所示 。

• 关系数据库可以做复杂的关系查询,而Redis 去模拟关系型复杂查询,例如联表查询、聚合查询等基本不可能,维护成本高。
在这里插入图片描述
开发人员需要将两者的特点搞清楚,才能在适合的场景使用适合的技术。到目前为止,我们已经能够用三种方法缓存用户信息,下面给出三种方案的实现方法和优缺点分析。

  • 1)原生字符串类型:每个属性一个键。
set user:1:name tom
set user:1:age 23
set user:1:city beijing

优点:简单直观,每个属性都支持更新操作。
缺点:占用过多的键,内存占用量较大,同时用户信息内聚性比较差,
所以此种方案一般不会在生产环境使用。

  • 2)序列化字符串类型:将用户信息序列化后用一个键保存。
set user:1 serialize(userInfo)

优点:简化编程,如果合理的使用序列化可以提高内存的使用效率。
缺点:序列化和反序列化有一定的开销,同时每次更新属性都需要把全部数据取出进行反序列化,更新后再序列化到Redis中。

  • 3)哈希类型:每个用户属性使用一对field-value,但是只用一个键保存.
hmset user:1 name tomage 23 city beijing

优点:简单直观,如果使用合理可以减少内存空间的使用。
缺点:要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable会消耗更多内存


列表

列表(list)类型是用来存储多个有序的字符串,如图所示,a、b、c、d、e五个元素从左到右组成了一个有序的列表,列表中的每个字符串称为元素(element),一个列表最多可以存储2^32-1 个元素。在Redis中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景.
在这里插入图片描述
列表类型的特点:
第⼀、列表中的元素是有序的,这意味着可以通过索引下标获取某个元素或者某个范围的元素列表,
例如要获取图中 的第 5 个元素,可以执行 lindex user:1:messages 4 或者倒数第 1 个元素,lindex
user:1:messages -1 就可以得到元素 e。
第⼆、区分获取和删除的区别,例如图 2-20 中的 lrem 1 b 是从列表中把从左数遇到的前 1 个 b 元素删
除,这个操作会导致列表的⻓度从 5 变成 4;但是执⾏ lindex 4 只会获取元素,但列表⻓度是不会变化
的。
第三、列表中的元素是允许重复的,例如图 2-21 中的列表中是包含了两个 a 元素的。

命令

常用命令: lpush,rpush,lpop,rpop,lrange等
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Redis 的列表(List)数据结构是一个简单的字符串列表,按照插入顺序排序。你可以从列表的两端推入或者弹出元素。下面是一些 Redis 列表数据结构的常用命令及其解释:

LPUSH

命令:LPUSH key value1 value2 … valueN
解释:将一个或多个值插入到列表头部。如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。当 key 存在但不是列表类型时,会返回一个错误。
RPUSH

命令:RPUSH key value1 value2 … valueN
解释:将一个或多个值插入到列表尾部。如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。当 key 存在但不是列表类型时,会返回一个错误。
LPOP

命令:LPOP key
解释:移除并获取列表的第一个元素。如果列表没有元素会返回 nil。
RPOP

命令:RPOP key
解释:移除并获取列表的最后一个元素。如果列表没有元素会返回 nil。
LINDEX

命令:LINDEX key index
解释:获取列表在指定索引上的元素。索引是从 0 开始的。如果索引超出范围,返回 nil。
LRANGE

命令:LRANGE key start stop
解释:获取列表指定范围内的元素。start 和 stop 是索引,其中 0 表示列表的第一个元素,-1 表示最后一个元素,-2 表示倒数第二个元素,以此类推。
LLEN

命令:LLEN key
解释:获取列表的长度。
LINSERT

命令:LINSERT key BEFORE|AFTER pivot value
解释:在列表中找到指定元素 pivot,并在其前(BEFORE)或后(AFTER)插入 value。如果列表不存在,或者 pivot 不在列表中,该命令不做任何操作。
LREM

命令:LREM key count value
解释:移除列表中等于 value 的元素。count 的值决定了移除操作的执行方式:
count > 0:从头向尾移除最多 count 个等于 value 的元素。
count < 0:从尾向头移除最多 abs(count) 个等于 value 的元素。
count = 0:移除所有等于 value 的元素。
LSET

命令:LSET key index value
解释:将列表 key 下标为 index 的元素的值设置为 value。
LTRIM

命令:LTRIM key start stop
解释:对一个已存在的列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间内的元素都将被删除。
BLPOPBRPOP

命令:BLPOP key1 key2 … keyN timeout 和 BRPOP key1 key2 … keyN timeout
解释:它们是阻塞版本的 LPOP 和 RPOP,当给定列表内没有任何元素可供弹出的时候,将阻塞连接直到等待超时或发现可弹出元素为止。
这些命令为 Redis 列表数据结构提供了丰富的操作选项,使得用户能够轻松地管理列表中的元素。

内部编码

列表类型的内部编码有两种。

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。
  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。

使用场景

1.阻塞消息队列模型

Redis 可以使⽤ lpush + brpop 命令组合实现经典的阻塞式⽣产者-消费者模型队列,
⽣产者客⼾端使⽤ lpush 从列表左侧插⼊元素,多个消费者客⼾端使⽤ brpop 命令阻塞式地从队列中"争抢" 队⾸元素。通过多个客⼾端来保证消费的负载均衡和⾼可⽤性。
在这里插入图片描述

2.文章列表

每个用户有属于自己的文章列表,现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。
1)每篇文章使用哈希结构存储,例如每篇文章有3个属性title、

hmset acticle:1 title xx timestamp 1476536196 content xxxx

2)向用户文章列表添加文章,user:{id}:articles作为用户文章列表的键

lpush user:1:acticles article:1 article3
...
lpush user:k:acticles article:5

3)分页获取用户文章列表,例如下面伪代码获取用户id=1的前10篇文章:

articles = lrange user:1:articles 0 9
for article in {articles}
hgetall {article}

使用列表类型保存和获取文章列表会存在两个问题。
第一,如果每次分页获取的文章个数较多,需要执行多次hgetall操作。
第二,分页获取文章列表时,lrange命令在列表两端性能较好,但是如果列表较大,获取列表中间范围的元素性能会变差。

3.微博 Timeline

每个⽤⼾都有属于⾃⼰的 Timeline(微博列表),现需要分⻚展⽰⽂章列表。此时可以考虑使⽤列表,因为列表不但是有序的,同时⽀持按照索引范围获取元素。
1)每篇微博使⽤哈希结构存储,例如微博中 3 个属性:title、timestamp、content

hmset mblog:1 title xx timestamp 1476536196 content xxxxx
...
hmset mblog:n title xx timestamp 1476536196 content xxxxx

2)向用户 Timeline 添加微博,user::mblogs 作为微博的键:

lpush user:1:mblogs mblog:1 mblog:3
...
lpush user:k:mblogs mblog:9

3)分页获取用户的 Timeline,例如获取⽤⼾ 1 的前 10 篇微博

keylist = lrange user:1:mblogs 0 9
for key in keylist {
 hgetall key
}

实际上列表的使用场景很多,在选择时可以参考以下口诀:
在这里插入图片描述


集合

集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。如图所示,集合user:1:follow包含着"it"、“music”、“his”、"sports"四个元素,一个集合最多可以存储2^32-1个元素。Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,能在实际开发中解决很多实际问题。

在这里插入图片描述

命令

常用命令: sadd,spop,smembers,sunion 等
在这里插入图片描述

内部编码

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

  • intset(整数集合):当集合中的元素都是整数且元素个数小于set-maxintset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。
  • hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使
    用hashtable作为集合的内部实现。

使用场景

集合类型比较典型的使用场景是标签(tag)。例如一个用户可能对娱乐、体育比较感兴趣,另一个用户可能对历史、新闻比较感兴趣,这些兴趣点就是标签。有了这些数据就可以得到喜欢同一个标签的人,以及用户的共同喜好的标签,这些数据对于用户体验以及增强用户黏度比较重要。例如一个电子商务的网站会对不同标签的用户做不同类型的推荐,比如对数码产品比较感兴趣的人,在各个页面或者通过邮件的形式给他们推荐最新的数码产品,通常会为网站带来更多的利益。

1.给用户增加标签

下面使用集合类型实现标签功能的若干功能。
(1)给用户添加标签

sadd user:1:tags tag1 tag2 tag5
sadd user:2:tags tag2 tag3 tag5
...
sadd user:k:tags tag1 tag2 tag4

(2)给标签添加用户

sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2 user:3
sadd tagk:users user:1 user:2

(3)删除用户下的标签

srem user:1:tags tag1 tag5

(4)删除标签下的用户

srem tag1:users user:1
srem tag5:users user:1

(5)计算用户共同感兴趣的标签
可以使用sinter命令,来计算用户共同感兴趣的标签,如下代码所示:

sinter user:1:tags user:2:tags

2.通过Set来计算用户之间的共同好友

基于集合求交集
在这里插入图片描述

3.使用Set统计UV

使用Redis的Set集合来统计UV(Unique Visitors,独立访客)是一个常见且高效的做法。UV通常用于衡量网站的独立访问用户数量,即不同用户访问的次数。下面是一个使用Redis Set集合来统计UV的基本思路:

设计Key:
首先,你需要为UV统计设计一个Redis的key。这个key通常与统计的时间范围相关,比如按天统计的UV,你可以使用uv:2023-10-23这样的key。

添加用户ID:
每当有用户访问网站时,你需要将用户的唯一标识(比如用户ID)添加到Redis的Set集合中。这个操作可以通过SADD命令来实现。例如:

SADD uv:2023-10-23 user_id_123

如果user_id_123已经存在于集合中,SADD命令不会有任何效果,也不会报错。这确保了每个用户ID在集合中只会出现一次。

获取UV数量
要获取某个时间范围内的UV数量,你可以使用SCARD命令来获取Set集合的元素数量。例如:

SCARD uv:2023-10-23

这个命令会返回uv:2023-10-23这个集合中的元素数量,也就是那一天的独立访客数量。

定期清理:
由于UV统计通常是按时间范围进行的(如按天、按小时等),你需要定期清理旧的UV数据,以释放Redis的内存空间。这可以通过删除旧的key来实现,比如使用DEL命令:

DEL uv:2023-10-22

你也可以使用Redis的过期键功能,为key设置一个TTL(Time To Live),让Redis自动在一段时间后删除这些key。

并发控制:
在高并发的场景下,多个请求可能同时尝试向同一个Set集合添加同一个用户ID。由于Redis的SADD命令是原子性的,你不需要额外的并发控制机制来确保数据的准确性。

通过以上步骤,你可以利用Redis的Set集合高效地统计网站的UV数据。需要注意的是,这种方法只适用于统计UV数量,如果你需要更详细的用户行为数据或更复杂的分析功能,可能需要结合其他数据库或分析工具来实现。


有序集合

有序集合相对于哈希、列表、集合来说会有一点点陌生,但既然叫有序集合,那么它和集合必然有着联系,它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据。如图所示,该有序集合包含kris、mike、frank、tim、martin、tom,它们的分数分别是1、91、200、220、250、251,有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助我们在实际开发中解决很多问题。
在这里插入图片描述

命令

常用命令: zadd,zrange,zrem,zcard等
在这里插入图片描述

内部编码

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

  • ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用。
  • skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降。

使用场景

排行榜

有序集合比较典型的使⽤场景就是排行榜系统。例如常见的网站上的热榜信息,榜单的维度可能是多方面的:按照时间、按照阅读量、按照点赞量。本例中我们使用点赞数这个维度,维护每天的热榜:

例如用户mike上传了一个视频,并获得了3个赞,可以使用有序集合的
zadd和zincrby功能:
(1)添加用户赞数

zadd user:ranking:2016_03_15 mike 3

如果之后再获得一个赞,可以使用zincrby:

zincrby user:ranking:2016_03_15 mike 1

(2)取消用户赞数
由于各种原因(例如用户注销、用户作弊)需要将用户删除,此时需要
将用户从榜单中删除掉,可以使用zrem。例如删除成员tom:

zrem user:ranking:2016_03_15 mike

(3)展示获取赞数最多的十个用户
此功能使用zrevrange命令实现:

zrevrangebyrank user:ranking:2016_03_15 0 9

(4)展示用户信息以及用户分数
此功能将用户名作为键后缀,将用户信息保存在哈希类型中,至于用户
的分数和排名可以使用zscore和zrank两个功能:

hgetall user:info:tom
zscore user:ranking:2016_03_15 mike
zrank user:ranking:2016_03_15 mike

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

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

相关文章

图像处理环境配置opencv-python

下载python&#xff0c;配置pip使用清华源下载镜像&#xff1a; pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 切换到python目录下&#xff0c;右击cmd&#xff0c;执行pip升级指令: python -m pip install --upgrade pip 下载opencv&#x…

Linux(CentOS7) 安装 Nginx

目录 下载 上传 解压 生成 Makefile 编译与安装 启动 nginx 创建软链接 常用命令 下载 官网地址&#xff1a; nginx: downloadhttps://nginx.org/en/download.html选择稳定版本&#xff0c;也可以指定需要的版本下载 上传 将下载好的 tar 包上传到 Linux 服务器…

第14届蓝桥杯C++B组省赛:串的熵|枚举、浮点数相等比较、log函数

题目链接&#xff1a; 2.01串的熵 - 蓝桥云课 (lanqiao.cn) 注意点&#xff1a; 1.C的log函数&#xff1a;有2&#xff0c;e&#xff08;log()以e为底&#xff09;&#xff0c;10为底的&#xff0c;没有现成的用换底公式&#xff1a; C 标准库 <cmath> 数学函数大全 - …

SpringMvc项目创建过程

1、新建空项目 名字和路径自定义&#xff0c;Maven项目&#xff0c;不建议勾选Add sample code 2、创建web模块 选中当前项目 修改路径&#xff0c;注意是在main包下 选择当前项目 3、编写pom.xml文件 在文件中加入以下内容&#xff0c;packaging标签表明了maven打包类型。 &…

【网站项目】贫困生管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

文献速递:机器学习 + 分子动力学 + 第一性原理计算 + 热力学性质(熔化温度 热导率 热膨胀系数)

分享一篇关于机器学习 分子动力学 第一性原理 热力学性质&#xff08;熔化温度 & 热导率 & 热膨胀系数&#xff09;的文章。 感谢论文的原作者&#xff01; 关键词&#xff1a; 1. Al−Li alloy 2. Neural network potential 3. Molecular dynamics 4. Thermal …

C语言 键盘输入与屏幕输出——数据的格式化屏幕输出

目录 顺序结构 C语言如何实现数据的输入和输出&#xff1f; 数据的格式化屏幕输出 printf&#xff08;&#xff09;格式字符 printf&#xff08;&#xff09;的格式修饰符 顺序结构 一般而言&#xff0c;顺序结构程序涉及如下三个基本操作&#xff1a; *输入数据 *处理数…

Linux_地址空间_进程控制_进程创建_进程终止_进程等待_进程替换_简易shell_4

文章目录 一、程序地址空间1.地址空间验证2.验证堆和栈的增长方向3.感知地址空间4.什么是地址空间 二、进程控制1.进程创建2.进程终止1、**关于终止的正确认识&#xff1a;**2、**关于终止常见做法**3、**关于终止&#xff0c;内核做了什么&#xff1f;** 3.进程等待1、为什么要…

【DETR系列目标检测算法代码精讲】01 DETR算法02 DETR算法数据预处理+图像增强+dataset代码精讲

今天这一节主要对DETR算法的数据预处理和数据增强部分的代码做逐行的精讲。 这一部分的代码主要的功能就是将COCO数据集中的原始图像和原始标注处理成能够输入到DETR网络中的图像和标注。 我首先采取任务流程逐行讲解的办法&#xff0c;然后再debug演示一下 准备 这个读取数…

<Linux> Linux环境开发工具

一、Linux软件包管理器 - yum 什么是软件包&#xff1a; 在Linux 下安装软件 , 一个通常的办法是下载到程序的源代码 , 并进行编译 , 得到可执行程序 . 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好 , 做成软件包 ( 可以理解成 windows 上的安装程序) 放在一…

Transformer的前世今生 day12(Transformer的三个问题)

Transformer的Decoder为什么要用掩码&#xff08;Masked Self-Attention&#xff09; 机器翻译中&#xff1a;源语句&#xff08;我爱中国&#xff09;&#xff0c;目标语句&#xff08;I love China&#xff09; 为了解决训练阶段和测试阶段不匹配的问题&#xff1a; 在训练阶…

多传感器标定——概述

文章目录 一、前言二、内容记录 一、前言 是对自动驾驶之心多传感器标定课程内容的记录&#xff0c;也是对一些被老师简单略过问题的自主学习。第一章是概述&#xff0c;将内容以问题的形式记录&#xff0c;并结合课上内容以及自己的项目经验给出回答 二、内容记录 车上会安装…

如何使用route-detect在Web应用程序路由中扫描身份认证和授权漏洞

关于route-detect route-detect是一款功能强大的Web应用程序路由安全扫描工具&#xff0c;该工具可以帮助广大研究人员在Web应用程序路由中轻松识别和检测身份认证漏洞和授权漏洞。 Web应用程序HTTP路由中的身份认证&#xff08;authn&#xff09;和授权&#xff08;authz&…

实验04_OSPF&RIP选路实验

实验拓扑 IP地址规划 拓扑中的 IP 地址段采用&#xff1a;172.16.AB.X/24。其中 AB 为两台路由器编号组合&#xff0c;例如&#xff1a;R3-R6 之间的 AB 为 36&#xff0c;X 为路由器编号&#xff0c;例如R3 的 X3所有路由器都有一个 loopback 0 接口&#xff0c;地址格式为&…

代码随想录算法训练营第二十七天| LeetCode 39. 组合总和、40.组合总和II、131.分割回文串

一、39. 组合总和 题目链接/文章讲解/视频讲解&#xff1a; https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html 状态&#xff1a;已解决 1.思路 这道题跟216. 组合总和 III - 力扣&#xff08;LeetCode&#xff09;题思路差不多&#xff0c;区别在于…

为什么感觉张宇 25 版没 24版讲得好?

很多同学反映&#xff1a;25版&#xff0c;讲得太散了, 知识点太多&#xff0c;脱离了基础班。 三个原因&#xff1a; 1. 25版改动很大&#xff0c;课程没有经过打磨&#xff1b; 2. 因为24考试难度增加&#xff0c;所以改动的总体思路是“拓宽基础”&#xff1a;即把部分强…

redis中bitmap的使用及场景,如何操作

一、概念 在Redis数据库中&#xff0c;Bitmap&#xff08;位图&#xff09;是一种特殊的数据结构&#xff0c;它不是一个独立的数据类型&#xff0c;而是基于String类型实现的。Bitmap主要用于存储大量二进制位&#xff08;0或1&#xff09;的数据&#xff0c;这些位可以代表不…

支付接口和数据库断言及封装

支付下单接口 请求方法&#xff1a; post 请求地址&#xff1a;http://shop.lemonban.com:8107/p/order/pay 请求参数&#xff1a;{“payType”:3,“orderNumbers”:“1733308182027309056”} 请求头部&#xff1a; {“Content-Type”:“application/json”,“Authorization…

HDMI 2.1b 规范解读

HDMI 规范 HDMI 2.1b 是最新版 HDMI 规范&#xff0c;支持一系列更高的视频分辨率和刷新频率&#xff0c;包括 8K60 和 4K120 以及高达 10K 的分辨率。同时支持动态 HDR 格式&#xff0c;带宽能力增加到 48Gbps HDMI。 新的超高速 HDMI 线缆支持 48Gbps 带宽。该线缆可确保提供…

在单通道彩图上踩的坑

使用labelme后&#xff0c;生成如图所示文件夹&#xff0c;其中JPEGImages是原图&#xff0c;SegmentationClassPNG是标签。 此时SegmentationClassPNG中的标签&#xff08;masks&#xff09;是只包含0和1的二进制文件&#xff0c;0表示背景,1表示要识别的物体类型。&#xff…