当前位置: 首页 > news >正文

redis经典五种数据类型及底层实现

目录

  • 一、Redis源代码的核心部分
    • 1.redis源码在哪里
    • 2.src源码包下面该如何看?
  • 二、我们平时说redis是字典数据库KV键值对到底是什么
    • 1.6大类型说明(粗分)
    • 2.6大类型说明
    • 3.上帝视角
    • 4.Redis定义了redisObject结构体
      • 4.1 C语言struct结构体语法简介
      • 4.2 字典、KV是什么
      • 4.3 redisObject +Redis数据类型+Redis 所有编码方式(底层实现)三者之间的关系
  • 三、5大结构底层C语言源码分析
    • 1.从set hello world说起
    • 2.redisObjec结构的作用
      • 2.1 RedisObject各字段的含义
      • 2.2 案例
    • 3.数据类型以及数据结构的关系
      • 3.1 String数据结构介绍
        • 3.1.1 3大编码格式
        • 3.1.2 3大编码案例
          • 3.2.2.1 案例测试
          • 3.2.2.2 C语言中字符串的展现
          • 3.2.2.3 SDS简单动态字符串
          • 3.2.2.4 Redis为什么重新设计一个 SDS 数据结构?
          • 3.1.3 源码分析
        • 3.1.4 总结
      • 3.2 Hash数据结构介绍
        • 3.2.1 案例
        • 3.2.2 hash的两种编码格式
        • 3.2.3 源码分析
      • 3.3 List数据结构介绍
        • 3.3.1 案例
        • 3.3.2 List的一种编码格式
        • 3.3.3 源码分析
      • 3.4 Set数据结构介绍
        • 3.4.1 案例
        • 3.4.2 Set的两种编码格式
        • 3.4.3 源码分析
      • 3.5 ZSet数据结构介绍
        • 3.5.1 案例
        • 3.5.2 ZSet的两种编码格式
        • 3.5.3 源码分析
    • 4.小总结
  • 四、skiplist跳表面试题
    • 1.是什么
    • 2.说说链表和数组的优缺点?为什么引出跳表
    • 3.优缺点

一、Redis源代码的核心部分

1.redis源码在哪里

redis-6.0.8\redis-6.0.8\src
在这里插入图片描述
在这里插入图片描述

2.src源码包下面该如何看?

在这里插入图片描述

二、我们平时说redis是字典数据库KV键值对到底是什么

1.6大类型说明(粗分)

redis 是 key-value 存储系统,其中key类型一般为字符串, value 类型则为redis对象(redisObject)
在这里插入图片描述

2.6大类型说明

传统的5大类型
新介绍的3大类型
在这里插入图片描述
在这里插入图片描述

  • bitmap实质String
  • hyperLogLog实质String
  • GEO实质Zset

3.上帝视角

https://redissrc.readthedocs.io/en/latest/datastruct/dict.html
https://redissrc.readthedocs.io/en/latest/index.html
在这里插入图片描述

4.Redis定义了redisObject结构体

Redis定义了redisObject结构体来表示string、hash、list、set、zset等数据类型
Redis中每个对象都是一个 redisObject 结构

4.1 C语言struct结构体语法简介

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

4.2 字典、KV是什么

每个键值对都会有一个dictEntry
在这里插入图片描述
在这里插入图片描述

4.3 redisObject +Redis数据类型+Redis 所有编码方式(底层实现)三者之间的关系

在这里插入图片描述

三、5大结构底层C语言源码分析

1.从set hello world说起

set hello word为例,因为Redis是KV键值对的数据库,每个键值对都会有一个dictEntry(源码位置:dict.h),

里面指向了key和value的指针,next 指向下一个 dictEntry。
key 是字符串,但是 Redis 没有直接使用 C 的字符数组,而是存储在redis自定义的 SDS中。
value 既不是直接作为字符串存储,也不是直接存储在 SDS 中,而是存储在redisObject 中。
实际上五种常用的数据类型的任何一种,都是通过 redisObject 来存储的。

在这里插入图片描述

2.redisObjec结构的作用

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

2.1 RedisObject各字段的含义

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

在这里插入图片描述
3.lru字段表示当内存超限时采用LRU算法清除内存中的对象。
4.refcount表示对象的引用计数。
5.ptr指针指向真正的底层数据结构的指针。

2.2 案例

set age 17
在这里插入图片描述

type类型
encoding编码,此处是数字类型
lru最近被访问的时间
refcount等于1,表示当前对象被引用的次数
ptrvalue值是多少,当前就是17

3.数据类型以及数据结构的关系

在这里插入图片描述
程序员写代码时脑子底层思维
在这里插入图片描述

3.1 String数据结构介绍

3.1.1 3大编码格式

int
保存long 型(长整型)的64位(8个字节)有符号整数
9223372036854775807(数字最多19位)
在这里插入图片描述
补充
只有整数才会使用 int,如果是浮点数, Redis 内部其实先将浮点数转化为字符串值,然后再保存。
embstr
代表 embstr 格式的 SDS(Simple Dynamic String 简单动态字符串),保存长度小于44字节的字符串
EMBSTR 顾名思义即:embedded string,表示嵌入式的String
raw
保存长度大于44字节的字符串

3.1.2 3大编码案例

3.2.2.1 案例测试

在这里插入图片描述

3.2.2.2 C语言中字符串的展现

在这里插入图片描述
Redis没有直接复用C语言的字符串,而是新建了属于自己的结构-----SDS
在Redis数据库里,包含字符串值的键值对都是由SDS实现的(Redis中所有的键都是由字符串对象实现的即底层是由SDS实现,Redis中所有的值对象中包含的字符串对象底层也是由SDS实现)。

在这里插入图片描述

3.2.2.3 SDS简单动态字符串

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

Redis中字符串的实现,SDS有多种结构(sds.h):
sdshdr5、(2^5=32byte)
sdshdr8、(2 ^ 8=256byte)
sdshdr16、(2 ^ 16=65536byte=64KB)
sdshdr32、 (2 ^ 32byte=4GB)
sdshdr64,264次方byte=17179869184G用于存储不同的长度的字符串。len 表示 SDS 的长度,使我们在获取字符串长度的时候可以在 O(1)情况下拿到,而不是像 C 那样需要遍历一遍字符串。alloc 可以用来计算 free 就是字符串已经分配的未使用的空间,有了这个值就可以引入预分配空间的算法了,而不用去考虑内存分配的问题。buf 表示字符串数组,真存数据的。

在这里插入图片描述

3.2.2.4 Redis为什么重新设计一个 SDS 数据结构?

在这里插入图片描述
C语言没有Java里面的String类型,只能是靠自己的char[]来实现,字符串在 C 语言中的存储方式,想要获取 「Redis」的长度,需要从头开始遍历,直到遇到 ‘\0’ 为止。所以,Redis 没有直接使用 C 语言传统的字符串标识,而是自己构建了一种名为简单动态字符串 SDS(simple dynamic string)的抽象类型,并将 SDS 作为 Redis 的默认字符串。在这里插入图片描述

3.1.3 源码分析

用户API
set k1 v1底层发生了什么?调用关系
在这里插入图片描述
在这里插入图片描述
三大编码
在这里插入图片描述
INT 编码格式
命令示例: set k1 123
当字符串键值的内容可以用一个64位有符号整形来表示时,Redis会将键值转化为long型来进行存储,此时即对应 OBJ_ENCODING_INT 编码类型。内部的内存结构表示如下:

在这里插入图片描述
Redis 启动时会预先建立 10000 个分别存储 0~9999 的 redisObject 变量作为共享对象,这就意味着如果 set字符串的键值在 0~10000 之间的话,则可以 直接指向共享对象 而不需要再建立新对象,此时键值不占空间!
set k1 123
set k2 123
在这里插入图片描述
redis源代码:object.c

在这里插入图片描述
在这里插入图片描述
EMBSTR编码格式

redis源代码:object.c
在这里插入图片描述
对于长度小于 44的字符串,Redis 对键值采用OBJ_ENCODING_EMBSTR 方式,EMBSTR 顾名思义即:embedded string,表示嵌入式的String。从内存结构上来讲 即字符串 sds结构体与其对应的 redisObject 对象分配在同一块连续的内存空间,字符串sds嵌入在redisObject对象之中一样。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
RAW 编码格式
set k1 大于44长度的一个字符串,随便写
在这里插入图片描述
当字符串的键值为长度大于44的超长字符串时,Redis 则会将键值的内部编码方式改为OBJ_ENCODING_RAW格式,这与OBJ_ENCODING_EMBSTR编码方式的不同之处在于,此时动态字符串sds的内存与其依赖的redisObject的内存不再连续了
在这里插入图片描述
明明没有超过阈值,为什么变成 raw 了
在这里插入图片描述
转变逻辑图
在这里插入图片描述

3.1.4 总结

Redis内部会根据用户给的不同键值而使用不同的编码格式,自适应地选择较优化的内部编码格式,而这一切对用户完全透明!
流程图
在这里插入图片描述

3.2 Hash数据结构介绍

3.2.1 案例

结构
hash-max-ziplist-entries:使用压缩列表保存时哈希集合中的最大元素个数。
hash-max-ziplist-value:使用压缩列表保存时哈希集合中单个元素的最大长度。
结论
1.哈希对象保存的键值对数量小于 512 个;
2.所有的键值对的健和值的字符串长度都小于等于 64byte(一个英文字母一个字节) 时用ziplist,反之用hashtable
ziplist升级到hashtable可以,反过来降级不可以

一旦从压缩列表转为了哈希表,Hash类型就会一直用哈希表进行保存而不会再转回压缩列表了。
在节省内存空间方面哈希表就没有压缩列表高效了。

在这里插入图片描述

3.2.2 hash的两种编码格式

ziplist
hashtable

3.2.3 源码分析

ziplist.c
Ziplist 压缩列表是一种紧凑编码格式,总体思想是多花时间来换取节约空间,即以部分读写性能为代价,来换取极高的内存空间利用率,
因此只会用于 字段个数少,且字段值也较小 的场景。压缩列表内存利用率极高的原因与其连续内存的特性是分不开的。
在这里插入图片描述
想想我们的学过的一种GC垃圾回收机制:标记–压缩算法
当一个 hash对象 只包含少量键值对且每个键值对的键和值要么就是小整数要么就是长度比较短的字符串,那么它用 ziplist 作为底层实现
ziplist什么样
ziplist是一个经过特殊编码的双向链表,它不存储指向上一个链表节点和指向下一个链表节点的指针,而是存储上一个节点长度和当前节点长度,通过牺牲部分读写性能,来换取高效的内存空间利用率,节约内存,是一种时间换空间的思想。只用在字段个数少,字段值小的场景里面
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ziplist各个组成单元什么意思
在这里插入图片描述
明明有链表了,为什么出来一个压缩链表?

  • 1 普通的双向链表会有两个指针,在存储数据很小的情况下,我们存储的实际数据的大小可能还没有指针占用的内存大,得不偿失。ziplist 是一个特殊的双向链表没有维护双向指针:prev next;而是存储上一个 entry的长度和 当前entry的长度,通过长度推算下一个元素在什么地方。牺牲读取的性能,获得高效的存储空间,因为(简短字符串的情况)存储指针比存储entry长度更费内存。这是典型的“时间换空间”。

  • 2 链表在内存中一般是不连续的,遍历相对比较慢,而ziplist可以很好的解决这个问题,普通数组的遍历是根据数组里存储的数据类型找到下一个元素的(例如int类型的数组访问下一个元素时每次只需要移动一个sizeof(int)就行),但是ziplist的每个节点的长度是可以不一样的,而我们面对不同长度的节点又不可能直接sizeof(entry),所以ziplist只好将一些必要的偏移量信息记录在了每一个节点里,使之能跳到上一个节点或下一个节点。

  • 3 头节点里有头节点里同时还有一个参数 len,和string类型提到的 SDS 类似,这里是用来记录链表长度的。因此获取链表长度时不用再遍历整个链表,直接拿到len值就可以了,这个时间复杂度是 O(1)

在这里插入图片描述
压缩列表节点的构成
压缩列表是 Redis 为节约空间而实现的一系列特殊编码的连续内存块组成的顺序型数据结构,本质上是字节数组
在模型上将这些连续的数组分为3大部分,分别是header+entry集合+end,
其中header由zlbytes+zltail+zllen组成,
entry是节点,
zlend是一个单字节255(1111 1111),用做ZipList的结尾标识符。见下: 压缩列表结构:由zlbytes、zltail、zllen、entry、zlend这五部分组成
在这里插入图片描述
zlbytes 4字节,记录整个压缩列表占用的内存字节数。
zltail 4字节,记录压缩列表表尾节点的位置。
zllen 2字节,记录压缩列表节点个数。
zlentry 列表节点,长度不定,由内容决定。
zlend 1字节,0xFF 标记压缩的结束。

在这里插入图片描述
zlentry实体结构解析
官网源码
在这里插入图片描述解析
压缩列表zlentry节点结构:每个zlentry由前一个节点的长度、encoding和entry-data三部分组成
在这里插入图片描述
前节点:(前节点占用的内存字节数)表示前1个zlentry的长度,prev_len有两种取值情况:1字节或5字节。取值1字节时,表示上一个entry的长度小于254字节。虽然1字节的值能表示的数值范围是0到255,但是压缩列表中zlend的取值默认是255,因此,就默认用255表示整个压缩列表的结束,其他表示长度的地方就不能再用255这个值了。所以,当上一个entry长度小于254字节时,prev_len取值为1字节,否则,就取值为5字节。
enncoding:记录节点的content保存数据的类型和长度。
content:保存实际数据内容
在这里插入图片描述

typedef struct zlentry {    // 压缩列表节点// prevrawlen是前一个节点的长度unsigned int prevrawlensize, prevrawlen;  //prevrawlensize是指prevrawlen的大小,有1字节和5字节两种unsigned int prevrawlensize, prevrawlen;    // len为当前节点长度 lensize为编码len所需的字节大小unsigned int lensize, len;  // 当前节点的header大小unsigned int headersize;   // 节点的编码方式unsigned char encoding; // 指向节点的指针unsigned char *p;   
} zlentry;

压缩列表的遍历:
通过指向表尾节点的位置指针p1, 减去节点的previous_entry_length,得到前一个节点起始地址的指针。如此循环,从表尾遍历到表头节点。从表尾向表头遍历操作就是使用这一原理实现的,只要我们拥有了一个指向某个节点起始地址的指针,那么通过这个指针以及这个节点的previous_entry_length属性程序就可以一直向前一个节点回溯,最终到达压缩列表的表头节点。

ziplist存取情况
在这里插入图片描述

在这里插入图片描述
t_hash.c
在这里插入图片描述
在 Redis 中,hashtable 被称为字典(dictionary),它是一个数组+链表的结构
OBJ_ENCODING_HT 编码分析
OBJ_ENCODING_HT 这种编码方式内部才是真正的哈希表结构,或称为字典结构,其可以实现O(1)复杂度的读写操作,因此效率很高。
在 Redis内部,从 OBJ_ENCODING_HT类型到底层真正的散列表数据结构是一层层嵌套下去的,组织关系见面图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 List数据结构介绍

3.3.1 案例

在这里插入图片描述

(1) ziplist压缩配置:list-compress-depth 0
表示一个quicklist两端不被压缩的节点个数。这里的节点是指quicklist双向链表的节点,而不是指ziplist里面的数据项个数
参数list-compress-depth的取值含义如下:
0: 是个特殊值,表示都不压缩。这是Redis的默认值。
1: 表示quicklist两端各有1个节点不压缩,中间的节点压缩。
2: 表示quicklist两端各有2个节点不压缩,中间的节点压缩。
3: 表示quicklist两端各有3个节点不压缩,中间的节点压缩。
依此类推…

(2) ziplist中entry配置:list-max-ziplist-size -2
当取正值的时候,表示按照数据项个数来限定每个quicklist节点上的ziplist长度。比如,当这个参数配置成5的时候,表示每个quicklist节点的ziplist最多包含5个数据项。当取负值的时候,表示按照占用字节数来限定每个quicklist节点上的ziplist长度。这时,它只能取-1到-5这五个值,
每个值含义如下:
-5: 每个quicklist节点上的ziplist大小不能超过64 Kb。(注:1kb => 1024 bytes)
-4: 每个quicklist节点上的ziplist大小不能超过32 Kb。
-3: 每个quicklist节点上的ziplist大小不能超过16 Kb。
-2: 每个quicklist节点上的ziplist大小不能超过8 Kb。(-2是Redis给出的默认值)
-1: 每个quicklist节点上的ziplist大小不能超过4 Kb。

3.3.2 List的一种编码格式

list用quicklist来存储,quicklist存储了一个双向链表,每个节点都是一个ziplist
在这里插入图片描述
在低版本的Redis中,list采用的底层数据结构是ziplist+linkedList;

高版本的Redis中底层数据结构是quicklist(它替换了ziplist+linkedList),而quicklist也用到了ziplist
quicklist
在低版本的Redis中,list采用的底层数据结构是ziplist+linkedList;
高版本的Redis中底层数据结构是quicklist(它替换了ziplist+linkedList),而quicklist也用到了ziplist。

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

3.3.3 源码分析

quicklist.h,head和tail指向双向列表的表头和表尾
在这里插入图片描述

在这里插入图片描述
quicklistNode中的*zl指向一个ziplist,一个ziplist可以存放多个元素
在这里插入图片描述
在这里插入图片描述

3.4 Set数据结构介绍

3.4.1 案例

Redis用intset或hashtable存储set。如果元素都是整数类型,就用intset存储。
如果不是整数类型,就用hashtable(数组+链表的存来储结构)。key就是元素的值,value为null。
在这里插入图片描述

3.4.2 Set的两种编码格式

intset
hashtable

3.4.3 源码分析

t_set.c
在这里插入图片描述
在这里插入图片描述

3.5 ZSet数据结构介绍

3.5.1 案例

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

3.5.2 ZSet的两种编码格式

ziplist
skiplist

3.5.3 源码分析

t_zset.c
在这里插入图片描述
在这里插入图片描述

4.小总结

在这里插入图片描述

redis数据类型以及数据结构的关系
在这里插入图片描述

不同数据类型对应的底层数据结构

  1. 字符串
    int:8个字节的长整型。
    embstr:小于等于44个字节的字符串。
    raw:大于44个字节的字符串。
    Redis会根据当前值的类型和长度决定使用哪种内部编码实现。

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

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

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

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

redis数据类型以及数据结构的时间复杂度
在这里插入图片描述

四、skiplist跳表面试题

1.是什么

跳表是可以实现二分查找的有序链表

  • skiplist是一种以空间换取时间的结构。
  • 由于链表,无法进行二分查找,因此借鉴数据库索引的思想,提取出链表中关键节点(索引),先在关键节点上查找,再进入下层链表查找。
  • 提取多层关键节点,就形成了跳跃表

总结来讲 跳表 = 链表 + 多级索引

2.说说链表和数组的优缺点?为什么引出跳表

痛点
在这里插入图片描述
解决方法:升维,也叫空间换时间。

优化
在这里插入图片描述
在这里插入图片描述
跳表的时间复杂度
时间复杂度是O(logN)
跳表查询的时间复杂度分析
首先每一级索引我们提升了2倍的跨度,那就是减少了2倍的步数,所以是n/2、n/4、n/8以此类推;
第 k 级索引结点的个数就是 n/(2^k);
假设索引有 h 级, 最高的索引有2个结点;n/(2^h) = 2, 从这个公式我们可以求得 h = log2(N)-1;
所以最后得出跳表的时间复杂度是O(logN)
在这里插入图片描述
跳表的空间复杂度
所以空间复杂度是O(N)
跳表查询的空间复杂度分析
首先原始链表长度为n
如果索引是每2个结点有一个索引结点,每层索引的结点数:n/2, n/4, n/8 … , 8, 4, 2 以此类推;
或者所以是每3个结点有一个索引结点,每层索引的结点数:n/3, n/9, n/27 … , 9, 3, 1 以此类推;
所以空间复杂度是O(n);

3.优缺点

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

维护成本相对要高 - 新增或者删除时需要把所有索引都更新一遍;
最后在新增和删除的过程中的更新,时间复杂度也是O(log n)

相关文章:

redis经典五种数据类型及底层实现

目录一、Redis源代码的核心部分1.redis源码在哪里2.src源码包下面该如何看?二、我们平时说redis是字典数据库KV键值对到底是什么1.6大类型说明(粗分)2.6大类型说明3.上帝视角4.Redis定义了redisObject结构体4.1 C语言struct结构体语法简介4.2 字典、KV是什么4.3 red…...

三十而立却被裁,打工人要如何应对职场危机?

又到金三银四就业季,对于部分职场人来说,年龄成为了他们找工作的最大限制。 因为绝大部分企业招聘中层干部以下岗位的时候,都会要求年龄不超过35周岁,再加上每年千万毕业生涌入社会,竞争程度相当激烈,这就导…...

java面试-java基础

char 变量能不能存贮一个中文汉字?为什么? char 变量可以存贮一个汉字,因为 Java 中使用的默认编码是 Unicode ,一个 char 类型占 2 个字节(16 bit),一个汉字是2个字节,所以放一个中…...

Kafka 消息不丢失

Kafka 消息不丢失生产者丢失消费者丢失不丢失配置Kafka 保证消息不丢失:只对已提交的消息 (committed message) 做有限度的持久化保证 已提交的消息:当 n 个 Broker 成功接收到该消息并写入到日志文件后,就告诉生产者该消息已成功提交有限度…...

ASEMI高压MOS管10N65参数,10N65规格,10N65封装

编辑-Z ASEMI高压MOS管10N65参数: 型号:10N65 漏极-源极电压(VDS):650V 栅源电压(VGS):30V 漏极电流(ID):10A 功耗(PD&#xff…...

LeetCode-416. 分割等和子集

目录题目分析回溯法动态规划动态规划(压缩)题目来源 416. 分割等和子集 题目分析 这道题目是要找是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 那么只要找到集合里能够出现 sum / 2 的子集总和,就算是可以分割成两个相同元素和子集了…...

2021年 第12届 蓝桥杯 Java B组 省赛真题详解及小结【第2场省赛 2021.05.09】

一、试题A:求余(本题总分:5 分) 得:5分 本题总分:5 分 【问题描述】 在 C/C/Java/Python 等语言中,使用 % 表示求余,请问 2021%20 的值是多少? 【答案提交】 这是一道结果…...

elasticSearch写入原理

elasticSearch写入原理 最近学习完了es相关的课程整理除了es的核心内容,学习这东西知其然知其所以然,自己按照自己的理解整理了es相关的面试题。先热个身,整理一下es的写入原理,有不对的地方请大家指正。 这些原理的东西我觉得还是…...

第十四届蓝桥杯模拟赛(第三期)Python

1 进制转换 问题描述   请找到一个大于 2022 的最小数,这个数转换成十六进制之后,所有的数位(不含前导 0)都为字母(A 到 F)。   请将这个数的十进制形式作为答案提交。 答案:2730 def ch…...

Pytorch模型参数的保存和加载

目录 一、前言 二、参数保存 三、参数的加载 四、保存和加载整个模型 五、总结 一、前言 在模型训练完成后,我们需要保存模型参数值用于后续的测试过程。由于保存整个模型将耗费大量的存储,故推荐的做法是只保存参数,使用时只需在建好模…...

面试热点题:回溯算法之组合 组合与组合总和 III

什么是回溯算法? 回溯算法也可以叫回溯搜索算法,回溯是递归的"副产品",回溯的本质是穷举,然后选出我们需要的数据,回溯本身不是特别高效的算法,但我们可以通过"剪枝"来优化它。 理解回溯算法 回溯…...

java面试-jvm

JVM JVM 是 java 虚拟机,简单来说就是能执行标准 java 字节码的虚拟计算机 JVM 是如何工作的 首先程序在执行之前先要把 Java 代码(.java)转换成字节码(.class),JVM 通过类加载器(ClassLoade…...

vscode下载与使用

1.vscode下载 官网下载地址:Download Visual Studio Code - Mac, Linux, Windows下载太慢,推荐文章:解决VsCode下载慢问题_vscode下载太慢_迷小圈的博客-CSDN博客下载太慢,推荐下载链接:https://vscode.cdn.azure.cn/s…...

人员摔倒识别预警算法 opencv

人员摔倒识别预警算法通过opencv网络模型技术,人员摔倒识别预警算法能够智能检测现场画面中人员有没有摔倒,无需人为干预可以立刻抓拍告警。OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉处理开源软件库&…...

华为OD机试题 - 火星文计算(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:火星文计算题目输入输出示例一输入输出说明Code解题思路版权说明…...

AI人工智能 - 初探

1.应用场景 主要用于了解和系统学习AI,从而可以在工作生活中利用AI做一些事。 2.学习/操作 1.文档阅读 下面的内容来自于与chatGPT的对话 2.整理输出 介绍AI 人工智能(Artificial Intelligence,简称AI)是计算机科学中的一个分支&…...

Spring-AOP工作流程

Spring-AOP工作流程 3,AOP工作流程 3.1 AOP工作流程 由于AOP是基于Spring容器管理的bean做的增强,所以整个工作过程需要从Spring加载bean说起: 流程1:Spring容器启动 容器启动就需要去加载bean,哪些类需要被加载呢?需要被增强的类,如:B…...

C51---串口发送指令,控制LED灯亮灭

1.Code: #include "reg52.h" #include "intrins.h" sfr AUXR 0x8E; sbit D5 P3^7; void UartInit(void) //9600bps11.0592MHz { //PCON & 0x7F; //波特率不倍速 AUXR 0x01; SCON 0x50; //8位数据,可变波…...

【Wiki】XWiki数据备份

XWiki为主题使用java开发的开源wiki,官网地址如下: https://www.xwiki.org/xwiki/bin/view/Main/ 目录1、 XWiki升级数据备份1.1、 获取XWiki配置的数据库与持久化目录信息1.2 备份数据库信息1.3 备份持久化目录2、XWiki数据迁移如果一个知识库不能确保数…...

ctk框架开发Qt插件应用示例工程

目录 前言 约定 插件工程pluginApp: 主启动工程StartApp: 效果演示 结语...

spring5源码篇(4)——beanFactoryPostProcessor执行/注解bean的装配

spring-framework 版本:v5.3.19 前面研究了beanDefinition的注册,但也仅仅是注册这一动作。那么在spring容器启动的过程中,是何时/如何装配的?以及装配的bean是如何注入的? (考虑到xml方式基本不用了以及篇…...

masstransit的message几个高级用法

1)问题,Class MessageA 基类,Class MessageB继承自MessageA; 用bus.Publish方法本想把有些消息只发给B队列,结果由于其继承关系A队列也获得了消息; 解决方法用send, Uri uri new Uri(RabbitM…...

漏洞分析丨cve-2012-0003

作者:黑蛋一、漏洞简介这次漏洞属于堆溢出漏洞,他是MIDI文件中存在的堆溢出漏洞。在IE6,IE7,IE8中都存在这个漏洞。而这个漏洞是Winmm.dll中产生的。二、漏洞环境虚拟机调试工具目标软件辅助工具XP-SP3、KaliOD、IDAIE6Windbg组件gflags.exe三…...

rm命令——删除文件或目录

rm命令是英文单词remove的缩写,主要功能是删除文件或目录。 因为删除文件是一个破坏性动作,因此,在使用时需要格外小心,在执行之前一定要再三确认删除的是哪个目录中的什么文件。 rm命令的语法格式如下: rm [选项] …...

【零基础入门学习Python---Python的基本语法使用】

一.Python基本语法使用 Python是一种易学且功能强大的编程语言,具有简洁的语法和广泛的应用领域。在本文中,我们将介绍Python的基本语法使用,以帮助初学者快速入门Python编程。 1.1 注释 Python 支持两种类型的注释:单行注释和多行注释。 单行注释:以 # 符号开头,从 # …...

数据仓库相关概念的解释

数据仓库相关概念的解释 文章目录数据仓库相关概念的解释1 ETL是什么?ETL体系结构2 数据流向何为数仓DW3 ODS 是什么?4 数据仓库层DWDWD 明细层DWD 轻度汇总层(MID或DWB,data warehouse basis)DWS 主题层(D…...

1/4车、1/2车、整车悬架模糊PID控制仿真合集

目录 前言 1. 1/4悬架系统 1.1数学模型 1.2仿真分析 2. 1/2悬架系统 2.1数学模型 2.2仿真模型 2.3仿真分析 3. 整车悬架系统 3.1数学模型 3.2仿真分析 4.总结 前言 前面几篇文章介绍了LQR、SkyHook、H2/H∞、PID控制,接下来会继续介绍滑模、反步法、M…...

Linux性能补丁升级,避免不必要的跨核Wake-Up

导读一个由英特尔发起的、旨在改进Linux内核公平调度程序代码的补丁系列,也看到了来自AMD工程师和其他利益相关者的测试/反馈,并继续进行改进。这个补丁系列的重点是避免在不必要的情况下发生过多的跨核唤醒(Cross-CPU Wake-up)。这样一来,这…...

Spring Cloud Alibaba全家桶(六)——微服务组件Sentinel介绍与使用

前言 本文小新为大家带来 微服务组件Sentinel介绍与使用 相关知识,具体内容包括分布式系统存在的问题,分布式系统问题的解决方案,Sentinel介绍,Sentinel快速开始(包括:API实现Sentinel资源保护,…...

拼多多2021笔试真题集 -- 3. 多多的求和计算

多多的求和计算 多多路上从左到右有N棵树(编号1~N),其中第i个颗树有和谐值Ai。 多多鸡认为,如果一段连续的树,它们的和谐值之和可以被M整除,那么这个区间整体看起来就是和谐的。 现在多多鸡想请…...

DP算法:动态规划算法

步骤(1)确定初始状态(2)确定转移矩阵,得到每个阶段的状态,由上一阶段推到出来(3)确定边界条件。例题蓝桥杯——印章(python实现)使用dp记录状态,d…...

一三四——一六七

一三四、JavaScript——_DOM简介 MDNq前端参考文档&#xff1a;DOM 概述 - Web API 接口参考 | MDN (mozilla.org) 一三五、JavaScript——HelloWorld <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta h…...

day29_JS

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、事件 二、DOM操作 三、案例 零、 复习昨日 js 脚本语言,弱类型 引入方案: 3种 js的内容: 语法dombom 语法 变量 var 数据类型 引用类型 - 对象,J…...

【HTTP协议与Web服务器】

HTTP协议与Web服务器浏览器与服务器通信过程HTTP的请求报头HTTP请求报头结构HTTP的请求方法HTTP应答报头HTTP应答报头结构应答状态web服务器的c语言实现浏览器与服务器通信过程 浏览器与Web服务器再应用层通信使用的是HTTP协议&#xff0c;而HTTP协议在传输层使用的是TCP协议。…...

Idea+maven+spring-cloud项目搭建系列--12 整合grpc

前言&#xff1a; grpc 是geogle 开源的rpc 通信框架&#xff0c;通过定义proto生成通信存根&#xff0c;像本地调用服务一样&#xff0c;进行远程服务的调用&#xff1b; 1 消费端服务提供&#xff1a; 1.1 引入grpc 和 protobuf <!-- RPC --> <!-- RPC 服务调用 …...

Revit开洞问题:结构专业开洞口剖面显示及一键开洞

一、Revit中关于结构专业开洞口剖面显示问题 Revit作业的时候&#xff0c;我们不仅只为了一个最后的三维立体模型,我们需要的是一个符合国家以及本院制图标准的一个出图样式,这时候就会出现各种各样的显示问题&#xff0c;本期就一个结构专业开洞显示问题&#xff0c;跟大家一起…...

0107连通分量-无向图-数据结构和算法(Java)

文章目录1 API2 代码实现和分析测试后记1 API 深度优先搜索下一个直接应用就是找出一幅图中的连通分量,定义如下API。 public class CCCC(Graph g)预处理构造函数booleanconnected(int v, int w)v和w连通吗intcount()连通分量数intid(int v)v所在的连通分量标识符(0~count()-…...

[学习笔记]黑马程序员python教程

文章目录思维导图Python基础知识图谱面向对象SQL入门和实战Python高阶技巧第一阶段第九章&#xff1a;Python异常、模块与包1.9.1异常的捕获1.9.1.1 为什么要捕获异常1.9.1.2 捕获常规的异常1.9.1.3 捕获指定的异常1.9.1.4 捕获多个异常1.9.1.5 捕获全部异常1.9.1.6 异常的else…...

如何配置用于构建 FastReport Online Designer 的 API ?

FastReport Online Designer 是一个跨平台的报表设计器&#xff0c;允许通过任何平台的移动设备创建和编辑报表。今天我们就一起来看看在2023版中新增和改进的功能有哪些&#xff0c;点击下方可以获取最新版免费试用哦&#xff01; FastReport Onlin Designe最新版试用https:/…...

【嵌入式Linux内核驱动】02_字符设备驱动

字符设备驱动 〇、基本知识 设备驱动分类 &#xff08;按共性分类方便管理&#xff09; 1.字符设备驱动 字符设备指那些必须按字节流传输&#xff0c;以串行顺序依次进行访问的设备。它们是我们日常最常见的驱动了&#xff0c;像鼠标、键盘、打印机、触摸屏&#xff0c;还有…...

【零散整理】

1-1 git查看代码的项目总行数 git log --prettytformat: --numstat | awk ‘{ add $1; subs $2; loc $1 - $2 } END { printf “added lines: %s, removed lines: %s, total lines: %s\n”, add, subs, loc }’ - 1-2 cookie const cookies document.cookie.split(; )for…...

RocketMQ重复消费的症状以及解决方案

RocketMQ重复消费的症状以及解决方案 生产消息时重复 症状 当一条消息已被成功发送到 消费者 并完成持久化&#xff0c;此时出现了网络闪断或者客户端宕机&#xff0c;导致服务端对客户端应答失败。 如果此时 生产者 意识到消息发送失败并尝试再次发送消息&#xff0c;消费者…...

数字化时代,企业的商业模式建设

随着新一代信息化、数字化技术的应用&#xff0c;众多领域通过科技革命和产业革命实现了深度化的数字改造&#xff0c;进入到以数据为核心驱动力的&#xff0c;全新的数据处理时代&#xff0c;并通过业务系统、商业智能BI等数字化技术和应用实现了数据价值&#xff0c;从数字经…...

项目实战典型案例23——-注册上nacos上的部分服务总是出现频繁掉线的情况

注册上nacos上的部分服务总是出现频繁掉线的情况一&#xff1a;背景介绍二&#xff1a;思路&方案解决问题过程涉及到的知识nacos服务注册和服务发现一&#xff1a;背景介绍 spring cloud项目通过nacos作为服务中心和配置中心&#xff0c;出现的问题是其中几个服务总是出现…...

玩转金山文档 3分钟让你的文档智能化

在上个月底&#xff0c;我们给大家推荐了金山轻维表的几个使用场景&#xff0c;社群中不少用户反响很好&#xff0c;对其中一些场景的解决方案十分感兴趣。但也有一些人表示&#xff0c;有些场景不知道如何实现&#xff0c;希望我们能提供模版/教程。这次我们将做一期热门模板盘…...

安装了nodejs怎么安装nvm

第一步&#xff0c;从控制面板卸载已经安装的node 第二步&#xff0c;删除C盘program开头文件夹下的node文件 第三步&#xff0c;去C/user/用户名 文件夹下&#xff0c;删除.npmrc文件 第四步&#xff0c;打开隐藏文件&#xff0c;第三步文件夹下有一个Appdata文件&#xff…...

java安全编码规范考试

java安全编码规范考试 整理不易&#xff0c;收点币&#xff01;&#xff01; 安全编码规范考试.md 下面对zip文件的安全解压缩描述&#xff0c;错误的是 A.zip文件解压时&#xff0c;可以使用entry.getSize(&#xff09;对解压缩文件进行文件大小判断 B.zip文件解压时&…...

表格检测识别技术的发展历程

近年来&#xff0c;随着计算机技术的飞速发展&#xff0c;越来越多的研究者开始关注表格检测识别技术。表格检测识别技术是一种利用计算机自动处理表格的技术&#xff0c;它可以实现从文本中检测出表格&#xff0c;并进行识别和提取。这种技术有助于提高文本处理的效率&#xf…...

设计UI - Adobe xd对象介绍

矩形工具 新建矩形 操作步骤&#xff1a;选择矩形工具&#xff0c;快捷键R&#xff0c;鼠标在画板上拖出矩形即可。 拖动定界框周围圆形手柄&#xff0c;可快速调整矩形大小&#xff0c;也可以输入宽和高的参数对矩形大小进行改变。 移动矩形 操作步骤&#xff1a;选择选择工具…...

优思学院|精益生产中的“单件流”真的能够做到吗?

精益生产中提到的“一个流”&#xff08;One Piece Flow&#xff09;是一种生产方式&#xff0c;它的核心理念是通过合理配置作业场地、人员和设备&#xff0c;使产品从投入到成品产出的整个制造加工过程中始终处于不停滞、不堆积、不超越&#xff0c;按节拍一个一个地流动。 …...