Redis(二十)五大经典类型源码

文章目录

  • 面试题
  • 源码核心
    • Redis基本的数据结构(骨架)
    • Redis数据库的实现
    • Redis服务端和客户端实现
    • 其他
  • K-V实现
    • 怎样实现键值对(key-value)数据库的
    • 传统五大基本数据类型和新五大数据类型
  • 5大数据结构底层C语言源码分析
    • 示例
    • redisObject
    • 五大数据结构解析
      • 定义
      • Debug Object key
      • String SDS数据结构
      • Hash数据结构
        • redis6:ziplist
        • 源码分析:t_hash.c
        • 源码分析:ziplist.c
        • redis7:packlist
      • List
      • Set
      • ZSet
      • 总结
        • redis6类型编码映射
        • 数据类型对应的底层数据结构
        • redis6数据类型以及数据结构的关系
        • redis7数据类型以及数据结构的关系
        • redis数据类型以及数据结构的时间复杂度
      • skiplist跳表
        • 时间复杂度
        • 空间复杂度
        • 优缺点

面试题

Redis数据类型的底层数据结构

  1. SDS动态字符串
  2. 双向链表
  3. 压缩列表ziplist
  4. 哈希表hashtable
  5. 跳表skiplist
  6. 整数集合intset
  7. 快速列表quicklist
  8. 紧凑列表listpack

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

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

内部redis重构使用

书籍

源码核心

Redis基本的数据结构(骨架)

  1. Redis对象object.d
  2. 字符串t_string.c
  3. 列表t_list.c
  4. 字典t hash.c
  5. 集合及有序集合t_set.c和t_zset.c
  6. 数据流t_stream.c:底层实现结构listpack.c和rax.c

  1. 简单动态字符串sds.c
  2. 整数集合intset.c
  3. 压缩列表ziplist.c
  4. 快速链表quicklist.c
  5. listpack
  6. 字典dict.c

Redis数据库的实现

  1. 数据库的底层实现db.c
  2. 持久化rdb.c和aof.c

Redis服务端和客户端实现

  1. 事件驱动ae.c和ae_epoll.c
  2. 网络连接anet.c和networking.c
  3. 服务端程序server.c
  4. 客户端程序redis-cli.c

其他

  1. 主从复制replication.c
  2. 哨兵sentinel.c
  3. 集群cluster.c
  4. 其他数据结构,如hyperloglog.c、geo.c等
  5. 其他功能,如pub/sub、Lua脚本

K-V实现

怎样实现键值对(key-value)数据库的

key一般为String类型的字符串对象
value类型则为redis对象(redisObject),可以是以下几种redis数据类型
在这里插入图片描述

传统五大基本数据类型和新五大数据类型

传统五大基本数据类型

  1. String
  2. List
  3. Hash
  4. Set
  5. ZSet

新五大基本数据类型

  1. bitmap实质String
  2. hyperLogLog实质String
  3. GEO实质Zset
  4. Stream实质Stream
  5. BITFIELD看具体key

在这里插入图片描述

每个Redis对象都是redisObject结构
在这里插入图片描述
在这里插入图片描述
redisObject
在这里插入图片描述在这里插入图片描述

5大数据结构底层C语言源码分析

  1. SDS动态字符串
  2. 双向链表
  3. 压缩列表ziplist
  4. 哈希表hashtable
  5. 跳表skiplist
  6. 整数集合intset
  7. 快速列表quicklist
  8. 紧凑列表listpack

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

示例

set hello word为例,因为Redis是KV键值对的数据库,每个键值对都会有一个dictEntry(源码位置:dict.h),里面指向了key和value的指针,next 指向下一个 dictEntry。

key 是字符串,但是 Redis 没有直接使用 C 的字符数组,而是存储在redis自定义的 SDS中。
value 既不是直接作为字符串存储,也不是直接存储在 SDS 中,而是存储在redisObject 中。
实际上五种常用的数据类型的任何一种,都是通过 redisObject 来存储的。
在这里插入图片描述
在这里插入图片描述

redisObject

为了便于操作,Redis采用redisObjec结构来统一五种不同的数据类型,这样所有的数据类型就都可以以相同的形式在函数间传递而不用使用特定的类型结构。同时,为了识别不同的数据类型,redisObjec中定义了type和encoding字段对不同的数据类型加以区别。简单地说,redisObjec就是string、hash、list、set、zset的父类,可以在函数间传递时隐藏具体的类型信息,所以作者抽象了redisObjec结构来到达同样的目的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 类型:4位的type表示具体的数据类型

  2. 编码,此处是数字类型:4位的encoding表示该类型的物理编码方式见下表,同一种数据类型可能有不同的编码方式。(比如String就提供了3种:int embstr raw)
    在这里插入图片描述

  3. 最近被访问的时间:lru字段表示当内存超限时采用LRU算法清除内存中的对象。

  4. 表示当前对象被引用的次数:refcount表示对象的引用计数。

  5. ptr指针指向真正的底层数据结构的指针。

五大数据结构解析

定义

在这里插入图片描述

Debug Object key

前提:开启该命令
在这里插入图片描述
Value at: 内存地址
refcount: 引用次数
encoding: 物理编码类型
serializedlength: 序列化后的长度(注意这里的长度是序列化后的长度,保存为rdb文件时使用了该算法,不是真正存贮在内存的大小),会对字串做一些可能的压缩以便底层优化
lru:记录最近使用时间戳
lru_seconds_idle:空闲时间
在这里插入图片描述
在这里插入图片描述

String SDS数据结构

动态字符串

  1. int:保存long 型(长整型)的64位(8个字节)有符号整数,上面数字最多19位只有整数才会使用 int,如果是浮点数, Redis内部其实先将浮点数转化为字符串值,然后再保存。
  2. embstr(嵌入式的String):代表 embstr 格式的 SDS(Simple Dynamic String简单动态字符串),保存长度小于44字节的字符串
  3. raw:保存长度大于44字节的字符串

SDS数据结构
在这里插入图片描述

Redis中字符串的实现,SDS有多种结构(sds.h):
sdshdr5、(2^5=32byte)
sdshdr8、(2 ^ 8=256byte)
sdshdr16、(2 ^ 16=65536byte=64KB)
sdshdr32、 (2 ^ 32byte=4GB)
sdshdr64,2的64次方byte=17179869184G用于存储不同的长度的字符串。

len 表示 SDS 的长度,使我们在获取字符串长度的时候可以在 O(1)情况下拿到,而不是像 C 那样需要遍历一遍字符串。

alloc 可以用来计算 free 就是字符串已经分配的未使用的空间,有了这个值就可以引入预分配空间的算法了,而不用去考虑内存分配的问题。

buf 表示字符串数组,真存数据的。

在这里插入图片描述
官网:https://github.com/antirez/sds

C语言SDS
字符串长度处理需要从头开始遍历,直到遇到 ‘\0’ 为止,时间复杂度O(N)记录当前字符串的长度,直接读取即可,时间复杂度 O(1)
内存重新分配分配内存空间超过后,会导致数组下标越级或者内存分配溢出空间预分配 SDS 修改后,len 长度小于 1M,那么将会额外分配与 len 相同长度的未使用空间。如果修改后长度大于 1M,那么将分配1M的使用空间。惰性空间释放有空间分配对应的就有空间释放。SDS 缩短时并不会回收多余的内存空间,而是使用 free 字段将多出来的空间记录下来。如果后续有变更操作,直接使用 free 中记录的空间,减少了内存的分配。
二进制安全二进制数据并不是规则的字符串格式,可能会包含一些特殊的字符,比如 ‘\0’ 等。前面提到过,C中字符串遇到 ‘\0’ 会结束,那 ‘\0’ 之后的数据就读取不上了根据 len 长度来判断字符串结束的,二进制安全的问题就解决了

int
命令示例:

set k1 123

当字符串键值的内容可以用一个64位有符号整形来表示时,Redis会将键值转化为long型来进行存储,此时即对应 OBJ_ENCODING_INT 编码类型。内部的内存结构表示如下:
在这里插入图片描述

Redis 启动时会预先建立 10000 个分别存储 0~9999 的 redisObject 变量作为共享对象,这就意味着如果 set字符串的键值在 0~10000 之间的话,则可以 直接指向共享对象 而不需要再建立新对象,此时键值不占空间!

set k1 123
set k2 123

server.h
在这里插入图片描述
object.c
在这里插入图片描述

redis7源代码:object.c
在这里插入图片描述
在这里插入图片描述
流程图
在这里插入图片描述
结论
只有整数才会使用 int,如果是浮点数, Redis 内部其实先将浮点数转化为字符串值,然后再保存。

embstr 与 raw 类型两者的区别见下图:

intLong类型整数时,RedisObject中的ptr指针直接赋值为整数数据,不再额外的指针再指向整数了,节省了指针的空间开销。
embstr当保存的是字符串数据且字符串小于等于44字节时,embstr类型将会调用内存分配函数,只分配一块连续的内存空间,空间中依次包含 redisObject 与 sdshdr 两个数据结构,让元数据、指针和SDS是一块连续的内存区域,这样就可以避免内存碎片
raw当字符串大于44字节时,SDS的数据量变多变大了,SDS和RedisObject布局分家各自过,会给SDS分配多的空间并用指针指向SDS结构,raw 类型将会调用两次内存分配函数,分配两块内存空间,一块用于包含 redisObject结构,而另一块用于包含 sdshdr 结构

在这里插入图片描述

Hash数据结构

redis6:ziplist

结构
hash-max-ziplist-entries:使用压缩列表保存时哈希集合中的最大元素个数。
hash-max-ziplist-value:使用压缩列表保存时哈希集合中单个元素的最大长度。

Hash类型键的字段个数 小于 hash-max-ziplist-entries 并且每个字段名和字段值的长度 小于 hash-max-ziplist-value 时,

Redis才会使用 OBJ_ENCODING_ZIPLIST来存储该键,前述条件任意一个不满足则会转换为 OBJ_ENCODING_HT的编码方式
在这里插入图片描述
在这里插入图片描述
结论

  1. 哈希对象保存的键值对数量小于 512 个;
  2. 所有的键值对的健和值的字符串长度都小于等于 64byte(一个英文字母一个字节)时用ziplist,反之用hashtable

ziplist升级到hashtable可以,反过来降级不可以:一旦从压缩列表转为了哈希表,Hash类型就会一直用哈希表进行保存而不会再转回压缩列表了。在节省内存空间方面哈希表就没有压缩列表高效了。

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

源码分析:t_hash.c

在 Redis 中,hashtable 被称为字典(dictionary),它是一个数组+链表的结构

OBJENCODING HT 编码分析:每个键值对都会有一个dictEntry

  1. OBJ_ENCODING_HT 这种编码方式内部才是真正的哈希表结构,或称为字典结构,其可以实现O(1)复杂度的读写操作,因此效率很高。
  2. 在 Redis内部,从 OBJ_ENCODING_HT类型到底层真正的散列表数据结构是一层层嵌套下去的
    在这里插入图片描述
    在这里插入图片描述
    dict.h
    在这里插入图片描述
源码分析:ziplist.c

为了节约内存而开发的,它是由连续内存块组成的顺序型数据结构,有点类似于数组

ziplist是一个经过特殊编码的双向链表它不存储指向前一个链表节点prev和指向下一个链表节点的指针next而是存储上一个节点长度和当前节点长度,通过牺牲部分读写性能,来换取高效的内存空间利用率,节约内存,是一种时间换空间的思想。只用在字段个数少,字段值小的场景里面
在这里插入图片描述
在这里插入图片描述

redis7:packlist
  1. 哈希对象保存的键值对数量小于 512 个;
  2. 所有的键值对的健和值的字符串长度都小于等于 64byte(一个英文字母一个字节)时用listpack,反之用hashtable
  3. listpack升级到hashtable,反过来降级不可以
    在这里插入图片描述
    在这里插入图片描述

有ziplist为什么出现listpack

ziplist连锁更新问题

压缩列表新增某个元素或修改某个元素时,如果空间不不够,压缩列表占用的内存空间就需要重新分配。而当新插入的元素较大时,可能会导致后续元素的 prevlen 占用空间都发生变化,从而引起「连锁更新」问题,导致每个元素的空间都要重新分配,造成访问压缩列表性能的下降。

案例:压缩列表每个节点正因为需要保存前一个节点的长度字段,就会有连锁更新的隐患
第一步:现在假设一个压缩列表中有多个连续的、长度在 250~253 之间的节点,如下图:
在这里插入图片描述
因为这些节点长度值小于 254 字节,所以 prevlen 属性需要用 1 字节的空间来保存这个长度值
第二步:这时,如果将一个长度大于等于 254 字节的新节点加入到压缩列表的表头节点,即新节点将成为entry1的前置节点,如下图:
在这里插入图片描述
因为entry1节点的prevlen属性只有1个字节大小,无法保存新节点的长度,此时就需要对压缩列表的空间重分配操作并将entry1节点的prevlen 属性从原来的 1 字节大小扩展为 5 字节大小。

第三步:连续更新问题出现
在这里插入图片描述

entry1节点原本的长度在250~253之间,因为刚才的扩展空间,此时entry1节点的长度就大于等于254,因此原本entry2节点保存entry1节点的 prevlen属性也必须从1字节扩展至5字节大小。entry1节点影响entry2节点,entry2节点影响entry3节点…一直持续到结尾。这种在特殊情况下产生的连续多次空间扩展操作就叫做「连锁更新」

结论:listpack 是 Redis 设计用来取代掉 ziplist 的数据结构,它通过每个节点记录自己的长度且放在节点的尾部,来彻底解决掉了 ziplist 存在的连锁更新的问题

listpack结构

https://github.com/antirez/listpack/blob/master/listpack.md
Total Bytes:为整个listpack的空间大小,占用4个字节,每个listpack最多占用4294967295Bytes。
num-elements:为listpack中的元素个数,即Entry的个数占用2个字节
element-1~element-N:为每个具体的元素
listpack-end-byte:为listpack结束标志,占用1个字节,内容为0xFF。
在这里插入图片描述
listpack如何解决连锁更新问题
在这里插入图片描述
和ziplist 列表项类似,listpack 列表项也包含了元数据信息和数据本身。不过,为了避免ziplist引起的连锁更新问题,listpack 中的每个列表项不再像ziplist列表项那样保存其前一个列表项的长度
在这里插入图片描述

List

Redis6、7都是quicklist差异在于:
redis6:实际是ziplist
redis7:实际是listpack

listpack紧凑列表是用来替代 ziplist 的新数据结构,在 7.0 版本已经没有 ziplist 的配置了(6.0版本仅部分数据类型作为过渡阶段在使用)

quicklist
实际上是 zipList 和 linkedList 的混合体,它将 linkedList按段切分,每一段使用 zipList 来紧凑存储,多个 zipList 之间使用双向指针串接起来。
在这里插入图片描述
在这里插入图片描述
redis6
在这里插入图片描述

Redis7的List的编码格式
list用quicklist来存储,quicklist存储了一个双向链表,每个节点都是一个listpack
quicklist是listpack和linkedlist的结合体

Set

两种编码方式:
intset
hashset

  1. Redis用intset或hashtable存储set。如果元素都是整数类型,就用intset存储
  2. 如果不是整数类型,就用hashtable(数组+链表的存来储结构)。key就是元素的值,value为null。
  3. 集合元素都是longlong类型并且元素个数<=set-max-intset-entries编码就是intset,反之就是hashtable

ZSet

两种编码格式

  1. ziplist+skiplist(redis6)
  2. listpack+skiplist(redis7)

redis6
当有序集合中包含的元素数量超过服务器属性 server.zset_max_ziplist_entries 的值(默认值为 128 ),或者有序集合中新添加元素的 member 的长度大于服务器属性 server.zset_max_ziplist_value 的值(默认值为 64 )时,redis会使用跳表作为有序集合的底层实现。否则会使用ziplist作为有序集合的底层实现

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

总结

redis6类型编码映射

在这里插入图片描述

数据类型对应的底层数据结构
  1. 字符串

int:8个字节的长整型。

embstr:小于等于44个字节的字符串。

raw:大于44个字节的字符串。

Redis会根据当前值的类型和长度决定使用哪种内部编码实现。

  1. 哈希

ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries 配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64 字节)时,

Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的 结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。

hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使 用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

  1. 列表

ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置 (默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时 (默认64字节),

Redis会选用ziplist来作为列表的内部实现来减少内存的使 用。

linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用 linkedlist作为列表的内部实现。quicklist ziplist和linkedlist的结合以ziplist为节点的链表(linkedlist)

  1. 集合

intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,Redis会用intset来作为集合的内部实现,从而减少内存的使用。

hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。

  1. 有序集合

ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist- entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配 置(默认64字节)时,

Redis会用ziplist来作为有序集合的内部实现,ziplist 可以有效减少内存的使用。

skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作 为内部实现,因为此时ziplist的读写效率会下降。

redis6数据类型以及数据结构的关系

在这里插入图片描述

redis7数据类型以及数据结构的关系

在这里插入图片描述

redis数据类型以及数据结构的时间复杂度

在这里插入图片描述

skiplist跳表

从单链表优化:索引升级
优化1
在这里插入图片描述
从这个例子里,我们看出,加来一层索引之后,查找一个结点需要遍历的结点个数减少了,也就是说查找效率提高了。
优化2
在这里插入图片描述

跳表是什么

skiplist是一种以空间换取时间的结构

优点:由于链表,无法进行二分查找,因此借鉴数据库索引的思想,提取出链表中关键节点(索引),先在关键节点上查找,再进入下层链表查找,提取多层关键节点,就形成了跳跃表
缺点:由于索引也要占据一定空间的,所以,索引添加的越多,空间占用的越多

时间复杂度

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

空间复杂度

比起单纯的单链表,跳表需要存储多级索引,肯定要消耗更多的存储空间

  1. 首先原始链表长度为n,
  2. 两两取首,每层索引的结点数:n/2, n/4, n/8 … , 8, 4, 2 每上升一级就减少一半,直到剩下2个结点,以此类推;如果我们把每层索引的结点数写出来,就是一个等比数列。

在这里插入图片描述
这几级索引的结点总和就是n/2+n/4+n/8…+8+4+2=n-2。所以,是O(n)

三三取首同理是等比数列…

优缺点

优点:
跳表是一个最典型的空间换时间解决方案,而且只有在数据量较大的情况下才能体现出来优势。而且应该是读多写少的情况下才能使用,所以它的适用范围应该还是比较有限的

缺点:
维护成本相对要高,在单链表中,一旦定位好要插入的位置,插入结点的时间复杂度是很低的,就是O(1)
新增或者删除时需要把所有索引都更新一遍,为了保证原始链表中数据的有序性,我们需要先找到要动作的位置,这个查找操作就会比较耗时最后在新增和删除的过程中的更新,时间复杂度也是O(log n)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用Python接单,一单800块虽然不多,但真的能够挣!

当今收入低于5000的人至少占到40%&#xff0c;完全不够养活一家人&#xff0c;而且很多小伙伴其实空余时间比较多&#xff0c;特别是大学生&#xff0c;零花钱又不够花&#xff0c;都想靠业余时间找点轻松的活增加收入。但是缺没门路&#xff0c;为此结合我多年编程开发经验&am…

【React】Ant Design社区扩展库之分割面板:react-resizable-panels

主角&#xff1a;react-resizable-panels 简介&#xff1a;来之Ant Design官方文档社区精选组件 1、效果 2、环境 react-resizable-panels: ^2.0.16next: 14.1.3react: ^18 3、安装 # npm npm install react-resizable-panels# yarn yarn add react-resizable-panels# pnpm …

python 如何向上取整

python向上取整 方法&#xff1a; Python match.ceil函数 ceil(x)函数是向上取整&#xff0c;即取大于等于x的最接近整数。 import math math.ceil(float(1)/2)

品牌软文怎么写?媒介盒子分享

品牌软文是品牌传播的主要方式。高质量的品牌软文能够帮助企业塑造正面的品牌形象&#xff0c;提高品牌知名度和影响力&#xff0c;扩大目标消费者范围。接下来媒介盒子就和大家聊聊&#xff1a;如何写好品牌软文。 一、 确立品牌独特点 品牌独特性是品牌能够与行业内其他品牌…

Offline RL : Efficient Planning in a Compact Latent Action Space

ICLR 2023 paper Intro 采用Transformer架构的Planning方法对马尔可夫序列重构,(et. TT)在面对高维状态动作空间&#xff0c;容易面对计算复杂度高的问题。本文提出TAP算法&#xff0c;基于Transformer的VQ-VAE&#xff0c;利用提取的状态动作在隐空间的低微特征进行Planning…

【LAMMPS学习】八、基础知识(2.4)恒温器

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

【JavaWeb】Day38.MySQL概述——数据库设计-DQL(一)

数据库设计——DQL 介绍 DQL英文全称是Data Query Language(数据查询语言)&#xff0c;用来查询数据库表中的记录。 查询关键字&#xff1a;SELECT 查询操作是所有SQL语句当中最为常见&#xff0c;也是最为重要的操作。在一个正常的业务系统中&#xff0c;查询操作的使用频次…

2024妈妈杯Mathorcup数学建模竞赛选题建议

关于十四届妈妈杯题目点击链接加入群聊【2024年第十四届MathorCup数学建模】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&kNol416eFZyg4AFPHCZsYfGkLnEnZ8H36&authKeyo9lIFgRfnk2U%2FfYYg1AlFJd5I456CSA2M6nlvJX2qcUockIKuMHj%2BhKMP6RnPeo1&noverify0&a…

在Ubuntu上搭建Prometheus + Grafana监控系统

1.Prometheus 部署 从官网下载页面找到最新的二进制文件下载 cd ~ curl -LO https://github.com/prometheus/prometheus/releases/download/v2.51.1/prometheus-2.51.1.linux-amd64.tar.gz将文件解压到指定目录 tar xf prometheus-2.51.1.linux-amd64.tar.gz -C /usr/local为…

每天学点儿Python(5) -- 序列索引和切片

Python中&#xff0c;序列是指一块可存放多个值的连续内存空间&#xff0c;这些值按一定顺序排列&#xff0c;可通过每个值所在位置的编号&#xff08;称为索引&#xff09;访问它们。它类似于C/C中的数组或字符串&#xff0c;但又比数组或字符串强大很多 序列类型包括字符串、…

挖掘未来:私有LTE/5G网络驱动智慧矿山的自动化

私有LTE/5G网络为世界上一些最偏远的角落提供无线连接。如果没有无线通信网络&#xff0c;各行业就无法满足增加产量、降低运营成本和减少环境破坏的需求。 在本案例研究中&#xff0c;我们着眼于自动化如何改变无线网络的动态。智慧矿山要求运营商无缝集成多个系统和应用程序…

Keil #include “stm32f10x.h“报错

给我的提示 我看到懵逼了&#xff0c;我就一直在网上找各种方法&#xff0c;发现都不行&#xff0c;我就想没有找到&#xff0c;我挨个挨个去找它想要的&#xff0c;发现是有的 我就想这不是有吗&#xff0c;怎么会找不到呢 我就又想是我路径写错了&#xff1f;我就看了一下路…

【深度学习】Fine-Grained Face Swapping via Regional GAN Inversion高保真换脸范式

文章目录 代码介绍实践效果 帮助、问询 代码 https://github.com/e4s2022/e4s 介绍 Fine-Grained Face Swapping via Regional GAN Inversion 提出一种新的高保真换脸范式&#xff0c;能够保留期望的微妙几何和纹理细节。从微观面部编辑的角度重新思考换脸任务&#xff0c;基…

npm创建Vue3项目

npm创建Vue3项目 1 创建Vue项目说明 2 安装3 运行 1 创建Vue项目 创建最新版的Vue项目&#xff0c;已经不推荐使用CLI构建方式了。参考如下即可。 npm create vuelatest如果发现一直动不了&#xff0c;切换网络试一下&#xff0c;个人热点尝试一下。 按下图的选项按需引入自…

[STM32+HAL]DengFOC移植之闭环位置控制

一、源码来源 DengFOC官方文档 二、HAL库配置 1、开启硬件IIC低速模式 低速更稳定 2、PWM波开启 三、keil填写代码 1、AS5600读取编码器数值 #include "AS5600.h" #include "math.h"float angle_prev0; int full_rotations0; // full rotation trac…

OSCP靶场--Hawat

OSCP靶场–Hawat 考点(目录扫描zip文件下载java代码审计web1的sql注入写到web2的webshel) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.158.147 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-11 07:18 EDT …

性能优化-01

当看到性能指标时&#xff0c;你会首先想到什么呢&#xff1f;我相信 “高并发” 和 “响应快” 一定是最先出现在你脑海里的两个词&#xff0c;而它们也正对应着性能优化的两个核心指标—— “吞吐” 和 “延时” 。这两个指标是从应用负载的视角来考察性能&#xff0c;直接影…

python爬虫----BeautifulSoup(第二十天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

组合数学<1>——组合数学基础

今天我们聊聊组合数学。(本期是给刚刚学习组合数学的同学看的&#xff0c;dalao们可以自行忽略) 建议:不会求逆元的出门左转数论<2>&#xff0c;不会数论的出门右转数论<1>。 加乘原理 加乘原理小学奥数就有。 总的来说:加法原理:分类;乘法原理:分步 比如说&a…

景芯2.5GHz A72训练营dummy添加(一)

景芯A72做完布局布线之后导出GDS&#xff0c;然后进行GDS merge&#xff0c;然后用Calibre对Layout添加Dummy。在28nm以及之前的工艺中&#xff0c;Dummy metal对Timing的影响不是很大&#xff0c;当然Star RC也提供了相应的解决方案&#xff0c;可以考虑Dummy metal来抽取RC。…