Redis的底层数据结构

2023-10-31

1、Redis的五种数据类型及七种底层结构

键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合

对于Redis来讲,对于键值对来说,键总是字符串,值就是五个中的一个,所以我们只用关心值的类型。**值有五种数据类型**

String Hash List Set ZSet

​​​​​​​

 

​​​​​​​

1、Redis的底层数据结构

Redis底层数据结构有⑦种:

1、简单动态字符串

2、链表

3、字典

4、跳跃表

5、整数集合

6、压缩列表

7、快速列表

2、Redis的底层数据结构

Redis底层数据结构之hash - 凡尘多遗梦 - 博客园讲的挺详细的

1、简单动态字符串(SDS)

(1)Redis默认字符串底层存储结构,比如set k1 v1,键k1是一个字符串,底层实现是保存着字符串k1的SDS,值v1也是一个字符串,底层实现是保存着字符串v1的SDS

(2)每个sds.h/sdshdr表示一个SDS,结构如下

struct sdshdr {
    //记录buf数组中已使用字节的数量,相当于保存的字符串的长度
    int len;
    //记录buf数组中未使用的字节数量
    int free;
    //字节数组,用于保存字符串
    char buf[];
}

底层是一个SDS,核心是字节数组 char buf[];注意是字节数组,因为Redis会使用SDS API以处理二进制的方式来处理SDS存在buf数组里的数据。

(3)优点:

1>获取字符串长度的复杂度为O(1)。

  • C字符串不记录自身长度,获取C字符串长度时必须遍历整个字符串计数得到,复杂度是O(N);

  • SDS字符串自身记录维护len长度属性,获得SDS字符串长度的复杂度是O(1);

2>杜绝缓存区溢出。因为其API会进行空间扩展,扩展之后未使用字节数量free和已使用字节数量len一样

和重分配的区别是:这是在修改之前,预先判断内存空间是否够用,不够用则进行拓展

C字符串不记录长度,由于两个C字符串在内存存储上紧邻,在执行字符串拼接strcat时,如果不提前分配足够空间,很可能发生修改s1的数据溢出到s2所在的空间中;(缓冲区溢出) SDS完全杜绝了缓冲区溢出问题,它记录了长度,当修改SDS字符串之前,API都会检查SDS的空间是否满足修改的要求,不满足API会自动进行空间扩展。

3>减少字符串修改时的内存重分配次数,因为有free(预分配),所有在最坏的情况下就是修改n次,重分配n次。

在修改之后,进行预分配(len<1mB,free=len,大于1MB,free=1MB)

C字符串每次修改增加或减少时,都会对保存这个C字符串的数组进行一次内存重分配; 拼接操作,在执行之前,程序需要先通过内存重分配来扩展底层数组的空间大小——如果忘了这一步就会产生缓冲区溢出。 截断操作,在执行之后,程序需要通过内存重分配来释放字符串不再使用的那部分空间——如果忘了这一步就会产生内存泄漏。 内存重分配算法复杂还需要执行系统调用,如果发生频繁修改可能对性能造成影响。

SDS通过free未使用空间,实现了空间预分配和惰性空间释放两种优化策略。 空间预分配 空间预分配:增长操作时,Redis可以减少连续执行字符串增长操作所需的内存重分配次数; 当SDS做增长操作,不仅会分配修改所必须要的空间,还会额外分配未使用空间,具体分配未使用空间如下2种方式: 一:如修改后长度len小于1MB,就分配和len属性相同大小的未使用空间;free=len; 二:如修改后长度len大于等于1MB,就分配1MD的未使用空间;free=1MB;

4、二进制安全。

C字符串的字符必须符合某种编码,除结尾空字符以外,字符串内部不允许有空字符串。存储有局限性; SDS存储的都是二进制安全的字符串,SDS API都会以处理二进制的方式来处理SDS存在buf数组里的数据。(这也是SDS的buf称之为字节数组的原因因——Redis不是用这个数组来保存字符,而是用它来保存一系列二进制数据)

C字符串只能存储文本数据,SDS可以存储二进制数据

5)兼容部分C字符串函数。

  • 虽然SDS是二进制安全的,但是还秉承C字符串以空字符结尾的特性。很多函数是可以共用C字符串的不需要重写;

img

用处:

1、String通常用于保存单个字符串或JSON字符串数据 2、因为String是二进制安全的,所以可以把保密要求高的图片文件内容作为字符串来存储 3、计数器常规Key-Value缓存应用,如微博数、粉丝数。INCR本身就具有原子性特性,所以不会有线程安全问题

是String字符串的底层数据结构

2、字典(dictht)(比如将键设计为对象的名称?)

Redis hash是一个string类型的field和value的映射表,hash特别适用于存储对象

可以通过字典(dictht)这种结构实现,类似于HashMap(结构是数组+链表)

数组叫做哈希表数组(table),链表节点为dictEntry,每个Entry包含键和值,并且Entry连接到哈希表的索引下标处

1)字典又称为符号表、关联数组或映射,是一种用于保存键值对的抽象数据结构,如果了解java7的HashMap的底层实现,那么这个自然就懂了。

(2)使用哈希表由dict.h/dictht结构定义

struct dictht{
    //哈希表数组 
    dictEntry **table;
    //哈希表大小 
    unsigned long size;
    //大小掩码,用于计算索引值,总是等于size-1
    unsigned long sizemask;
    //已有节点的数量  
    unsigned long used;
}dictht;

table是一个数组,类型是指向dict.h/dictEntry结构的指针。每个dictEntry保存着一个键对值,结构如下

struct dictEntry{
    //键
    void *key;
    //值,下面三个的其中一个
    union{
        //指针
        void *val;
        //uint64_t整数
        uint64_tu64;
        //int64_t整数
        int64_ts64;
    }v;
    //指向下一个节点的指针
    struct dictEntry *next;
}dictEntry;

如果此时表中有一个entry的键为k0,插入键为k1的entry的时候,k1、k0它俩的hash值都一样,这时候就发生了哈希冲突,那么此时k1就会放在table中对应的索引下,k1的next就会指向k0,这个就是解决hash冲突的实现。

img

总结:由哈希表数组+字典Entry构成,其中哈希表数组定义了存储数组的大小,已有Entry的个数对于相同key的字典Entry存储到相同的数组索引下标处,并且以链表的形式连接。采用的存储结构是数组+链表

解决哈希冲突的方法:拉链法

用处:

存储对象的属性信息

应该是一个对象对应着一个table,一个属性对应着一个dictEntry,每个Entry是由键值对构成的

根据以上字典的特性,我们知道,字典和 HashMap 的特性是差不多的,也是基于数组和链表的组合,所以一般都是用来存储键值对的。不过在实际运用场景中,我们会经常用来存储一个对象的信息。例如:一个对象的属性如 name ,age ,weight 等属性,可以直接当做一个个键值对存储在这个字典下,这样做的好处是,在需要用到这个对象的属性时,不用把这个对象全部序列化,只需要取出特定的就可以,而在传统的需要全部序列化,相比来讲就比较消耗资源。

这里用处写的很模糊

是哈希(Hash)和集合的底层数据结构

怎么解决属性值为Object类型?

redis hash每一个hashEntry只能存储key(String)->value(string)字符串类型数据

讲了redisTemplate的hash数据类型存储{key(String)->value(string)}的方法; 但是实际清楚我们存储对象应该是{key(string)->value(object)}类型的。 开始测试的时候,报错为 object can not cast to object,发现redis的hash类型只能存储string类型的数据。后经翻阅资料,找到存储序列化对象的方法解决。 实现serializable接口的作用就是可以把对象转化为字节流,并且可以反序列化恢复,对象实现序列化可以进行网络传输,在分布式应用中,就需要进行序列化对象的操作。

3、LinkedList(链表)

使用ListNode链表作为底层是一个双向链表,并且有头指针和尾指针。

双向链表!!!!!

(1)redis的list数据类型的底层实现之一,类似于java集合类LinkedArrayList。

(2)每个链表节点用一个adlist.h/listNode结构来表示

struct listNode{
    //前置节点
    struct listNode *prev;
    //后置节点
    struct listNode *next;
    //节点的值
    void *value;     
}listNode;

多个listNode可以通过prev和next指针组层双端链表

(3)链表通过结构adlist.h/list来构建

struct list{
    //表头节点
    listNode *head;
    //表尾节点
    listNode *tail;
    //链表节点数量
    unsigned long len;
    //节点值复制函数
    void *(*dup)(void *ptr);
    //节点值释放函数
    void (*free)(void *ptr);
    //节点值对比函数
    int (*match)(void *ptr,void *key);
}list;

结构如下: img

用处:

阻塞队列和文章列表或者数据分页展示的应用

redis的链表结构可以在左边和右边插入数据

消息队列:Redis 的链表结构,可以轻松实现阻塞队列,可以使用左进右出的命令组成来完成队列的设计。比如:数据的生产者可以通过 Lpush 命令从左边插入数据,多个数据消费者,可以使用 BRpop 命令阻塞的“抢”列表尾部的数据。不过这种消息队列没有办法和专业的消息队列相比

常用命令:lpush:在头部插入元素,rpush在尾部插入元素,blpop在头部取出元素,brpop在尾部取出元素

文章列表或者数据分页展示的应用。比如,我们常用的博客网站的文章列表,当用户量越来越多时,而且每一个用户都有自己的文章列表,而且当文章多时,都需要分页展示,这时可以考虑使用 Redis 的列表,列表不但有序同时还支持按照范围内获取元素可以完美解决分页查询功能。大大提高查询效率。

是列表的底层数据结构

4、整数集合

全部是整数值,无重复, 有序,这里的有序是指取出的顺序和放入的顺序一致,而不是会对元素大小自动排序

当一个集合中的*元素都是整数值,且元素不多的时候,*整数集合就会作为集合 Set 的底层实现。

Redis 中的整数集合 intset 是用来保存多个不重复的整数值且有序的集合抽象数据结构,可以保存类型为 int16-t 、int32-t 或者 int64-t 的整数值。它是实现集合键底层之一。

并且保证集合中不会出现重复元素

typedef struct intset {
​
    // 编码方式
    uint32_t encoding;
​
    // 集合包含的元素数量
    uint32_t length;
​
    // 保存元素的数组
    int8_t contents[];
​
} intset;

encoding是整个整数数组的存储类型,假设添加一个新元素比原来数组的encoding要大,比如int64, 原数组会进行升级,将encoding变为int64

升级操作步骤:时间复杂度为O(N) 根据新元素的类型,扩展整数集合底层数组的空间大小,并为新元素分配空间。 将底层数组现有的所有元素都转换成与新元素相同的类型,并将类型转换后的元素放置到正确的位上,而且在放置元素的过程中,需要继续维持底层数组的有序性质不变。 将新元素添加到底层数组里面。 将enconding改为当前类型,长度加一。

所有的元素都变为新的encoding类型

升级的好处

整数集合的升级策略有两个好处,一个是提升整数集合的灵活性,另一个是尽可能地节约内存。

(1)提升灵活性

因为整数集合可以通过自动升级底层数组来添加元素,所以可以任意添加不同类型的数值(int16_t,int32_t,int64_t),不必担心类型错误。

(2)尽可能的节约内存

不必上来就定义int64_t类型(或者更长的类型)的数组,而是在需要的时候在扩展为int64_t(或者更长的类型);

特点:

全部元素为整数,无重复,有序,可以升级不能降级

是集合(Set)的底层数据结构

5、跳跃表

跳跃表()

(1)跳跃表是一种有序的数据结构,通过每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。这种数据结构可以在小于等于O(n)的情况下找到相应的数据。

1>由很多层组成

2>每一层都是一个有序的链表

3>最底层的链表包含了所有的元素;

4>如果一个元素出现在某一层的链表中,那么在该层之下的链表也全都会出现(上一层的元素是当前层的元素的子集);

5>链表中的每个节点都包含两个指针,一个指向同一层的下一个链表节点,另一个指向下一层的同一个链表节点;

img

简单的理解就是当前层节点之间的间隔都比下一层更大,但是每一层都必须是有头结点和尾节点。

特点:

有序,多层,去重,构成有序集合的底层结构(ZSET)

是有序列表的底层结构

跳跃表查询:

从上层链表开始查询,遇到比查询值小的节点向后查询,遇到比查询值大的节点返回前一个结点并向下查询

6、压缩列表

Redis数据结构——压缩列表 - Mr于 - 博客园

传统的数组存储元素的时候,每个元素占用的内存大小都是一样的,比如Int64,这样就会造成内存的浪费,但是好处是因为数组元素的内存地址都是连续的,所以好计算元素的位置,比如比较小的数。因此这是redis为了节省内存自己设计的一种数据结构,它是对于数组的每一个元素,都带有前一元素占用内存的大小,这样,元素就不需要全部占用一样的内存了,从而减少内存开销

数组:

Redis压缩列表的机构示意图:

每个压缩列表节点可以保存一个字节数组或者一个整数值。

上面的图只是形象的表示,实际上是存储的前一个节点的内存大小

节点的结构:

分别定义了前一节点占用内存大小,此节点的编码方式,此节点的内容

对于前一节点的占用内存大小:

前一节点长度小于254字节,则该字段长度为一字节保存其长度大小

前一节点长度大于254字节,该字段长度使用5个字节记录前一节点长度

对于此节点的内容:可以是字节数组或者整数

特点:

  • 压缩列表是Redis为节约内存自己设计的一种顺序型数据结构。

  • 压缩列表被用作列表键和哈希键的底层实现之一。

  • 压缩列表可以包含多个节点,每个节点可以保存一个字节数组或者整数值。

  • 添加新节点到压缩列表,或者从压缩列表中删除节点,可能会引发连锁更新操作,但这种操作出现的几率并不高。

7、快速列表

考虑到链表的附加空间相对太高,prev 和 next 指针就要占去 16 个字节 (64bit 系统的指针是 8 个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理效率。

后续版本对列表数据结构进行了改造,使用 quicklist 代替了 ziplist 和 linkedlist

quickList 是 zipList 和 linkedList 的混合体,它将 linkedList 按段切分,每一段使用 zipList 来紧凑存储,多个 zipList 之间使用双向指针串接起来。

这样就减少了双向链表的前后指针,并且中间是使用的是zipList,其内部是连续的,也减少了内存的碎片化

传统链表的缺点:前后指针占用内存大,并且内存空间不连续,容易产生内存碎片

快速列表使用了双向链表,并且每个节点就是一个zipList,这样减少了前后指针,也减少了内存碎片化

优点是:节省内存以及较少内存碎片化

3、Redis的数据类型以及使用场景

1、String类型

一种实现方法

底层使用简单动态字符串(SDS)

使用场景

1、String通常用于保存单个字符串或JSON字符串数据 2、因为String是二进制安全的,所以可以把保密要求高的图片文件内容作为字符串来存储 3、计数器常规Key-Value缓存应用,如微博数、粉丝数。可以快速实现计数和查询的功能。INCR本身就具有原子性特性,所以不会有线程安全问题

4、缓存功能:String 字符串是最常用的数据类型,不仅仅是 Redis,各个语言都是最基本类型,因此,利用 Redis 作为缓存,配合其它数据库作为存储层,利用 Redis 支持高并发的特点,可以大大加快系统的读写速度、以及降低后端数据库的压力。

2、列表(List)

三种实现方式

可以通过链表或者压缩列表或者快速列表实现

用处:

阻塞队列和文章列表或者数据分页展示的应用

redis的链表结构可以在左边和右边插入数据

消息队列:Redis 的链表结构,可以轻松实现阻塞队列,可以使用左进右出的命令组成来完成队列的设计。比如:数据的生产者可以通过 Lpush 命令从左边插入数据,多个数据消费者,可以使用 BRpop 命令阻塞的“抢”列表尾部的数据。(应该是新加入的元素为头部?) 文章列表或者数据分页展示的应用。比如,我们常用的博客网站的文章列表,当用户量越来越多时,而且每一个用户都有自己的文章列表,而且当文章多时,都需要分页展示,这时可以考虑使用 Redis 的列表,列表不但有序同时还支持按照范围内获取元素,可以完美解决分页查询功能。大大提高查询效率。

快速列表也可以作为列表的一种实现方式

3、Hash

两种实现方式

底层由字典或者压缩列表实现

用处:

存储对象属性信息

zipList怎么实现hash

ziplist 编码的哈希对象使用压缩列表作为底层实现, 每当有新的键值对要加入到哈希对象时, 程序会先将保存了键的压缩列表节点推入到压缩列表表尾, 然后再将保存了值的压缩列表节点推入到压缩列表表尾, 因此:

保存了同一键值对的两个节点总是紧挨在一起, 保存键的节点在前, 保存值的节点在后; 先添加到哈希对象中的键值对会被放在压缩列表的表头方向, 而后来添加到哈希对象中的键值对会被放在压缩列表的表尾方向。

4、Set

两种实现方式

底层由整数集合或者字典实现

一种去重无序的集合(这里的无序是说没有对其中的元素自动排序,而不是存取的顺序不同)

用处:

对数据进行自动去重或者进行交集并集差集的操作

Set 是会自动去重的无序集合。直接基于 Set 将系统里需要去重的数据扔进去,自动就给去重了,如果需要对一些数据进行快速的全局去重,当然也可以基于 JVM 内存里的 HashSet 进行去重,但是如果某个系统部署在多台机器上呢?得基于 Redis 进行全局的 Set 去重。

可以基于 Set 玩交集、并集、差集的操作,比如交集吧,我们可以把两个人的好友列表整一个交集,看看俩人的共同好友是谁。

dict字典为什么能作为set的一种实现方式

set对外与list类似,都是提供列表功能,即单键多值,唯独多了一个自动去重功能。

在这里插入图片描述

5、Sorted Set

底层使用跳跃表实现

用处:

Sorted set 是排序的 Set去重但可以排序,写进去的时候给一个分数,自动根据分数排序。

排行榜:有序集合经典使用场景。例如视频网站需要对用户上传的视频做排行榜,榜单维护可能是多方面:按照时间、按照播放量、按照获得的赞数等。 用 Sorted Sets 来做带权重的队列,比如普通消息的 score 为1,重要消息的 score 为2,然后工作线程可以选择按 score 的倒序来获取工作任务。让重要的任务优先执行。

4、Redis常用的命令?

4、Redis的数据对象类型是什么?

redisObject

redisObject是Redis类型系统的核心,数据库中的每个键、值,以及Redis本身处理的参数,都表示为这种数据类型。

//Redis 对象
typedef struct redisObject {
    // 类型,记录了对象所保存的值的类型
    unsigned type:4
    // 对齐位
    unsigned notused:2;
    // 编码方式,记录了对象所保存的值的编码
    unsigned encoding:4;
    // LRU 时间(相对于 server.lruclock)
    unsigned lru:22;
    // 引用计数
    int refcount;
    // 指向对象的值,指向实际保存值的数据结构, 这个数据结构由type属性和encoding属性决定
    void *ptr;
} robj;

type:有五种分别代表Redis的五种数据类型

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis的底层数据结构 的相关文章

  • “JSONArray 文本必须在 null 的第 1 个字符处以 '[' 开头”

    只是想知道这个错误可能意味着什么 我从下面的代码中得到它 try JSONArray jArray new JSONArray result for int i 0 i
  • 无论线程如何,对象是否总是能看到其最新的内部状态?

    假设我有一个带有简单整数计数变量的可运行对象 每次可运行对象运行时该变量都会递增 该对象的一个 实例被提交以在计划的执行程序服务中定期运行 class Counter implements Runnable private int coun
  • 了解 netty 通道缓冲区和水印

    我正在尝试了解网络缓冲区和水印 作为一个测试用例 我有一个 netty 服务器 它向客户端写入数据 客户端被阻止 基本上每次读取之间有 10 秒的睡眠时间 在正常 I O 下 如果接收方被阻塞 TCP 发送方将受到限制 由于流量控制 发送速
  • java 中的梵文 i18n

    我正在尝试使用来自互联网的示例 ttf 文件在 java 中使用 i18n 进行梵文 印地文 我可以加载资源包条目 还可以加载 ttf 并设置字体 但它不会根据需要呈现 jlabel 它显示块代替字符 如果我在 Eclipse 中调试 我可
  • Java 小程序在 Mac 上闪烁

    这个问题很奇怪 问题并非在每个平台上都会发生 我在使用 MacOSX 的 Google Chrome 中出现了这种情况 但在 Safari 中却没有出现这种情况 对于使用 Windows 的朋友来说 在 Google Chrome 上运行得
  • Apache Thrift Java-Javascript 通信

    我正在编写一个基于 Apache Thrift 的 Java 服务器 它将从 Javascript 客户端接收数据 我已经完成了 Java 服务器 但问题是我可以获得 Javascript 客户端的工作示例 我无法找到一个好的示例 构建文档
  • 在 Eclipse 3.5 上安装旧版 TestNG 插件时出现问题

    我正在尝试在 eclipse 3 5 上安装 TestNG 5 11 并获得以下信息 eclipse buildId unknown java version 1 6 0 19 java vendor Sun Microsystems In
  • 如何将本机数据库运算符 (postgres ~) 与 JPA 标准生成器一起使用?

    我使用 JPA 2 0 标准构建以下查询 简化 select n from notif n where n message b la 我正在使用 postgresql 数据库 我真的需要 运算符 而不是像 我可以使用与 CriteriaBu
  • 对对象集合进行排序[重复]

    这个问题在这里已经有答案了 如果我有一个简单的字符串列表 List
  • FileObserver 不适用于 Android 6.0 Marshmallow (API 23) 中的外部存储

    我有一个应用程序可以观察外部存储上的公共目录FileObserver 它运行良好Lollipop设备 我想添加对Marshmallow 所以我用它设置了一台 Nexus 9 平板电脑 在 Marshmallow 设备上 它失败 在 Loll
  • Java 中如何验证字符串的格式是否正确

    我目前正在用 Java 编写一个验证方法来检查字符串是否是要更改为日期的几种不同格式之一 我希望它接受的格式如下 MM DD YY M DD YY MM D YY 和 M D YY 我正在测试第一种格式 每次它都告诉我它无效 即使我输入了有
  • 超出 Redis 连接/缓冲区大小限制

    在对我们的应用程序服务器进行压力测试时 我们从 Redis 中得到以下异常 ServiceStack Redis RedisException 无法连接到 redis host 6379 处的 redis 实例 gt System Net
  • 使用 Guava Ordering 对对象列表进行多条件排序

    我有一个类无法实现可比较 但需要根据 2 个字段进行排序 我怎样才能用番石榴实现这一目标 假设班级是 class X String stringValue java util Date dateValue 我有一个清单 List
  • 了解Kafka流groupBy和window

    我无法理解 kafka 流中的 groupBy groupById 和窗口的概念 我的目标是聚合一段时间内 例如 5 秒 的流数据 我的流数据看起来像 value 0 time 1533875665509 value 10 time 153
  • Java HashSet 是线程安全的只读吗?

    如果我通过 Collections unmodifyingSet 运行 HashSet 实例后 它是线程安全的吗 我问这个是因为 Set 文档声明它不是 但我只是执行读取操作 来自 Javadoc 请注意 此实现不是同步的 如果多个线程同时
  • 如何在 spring-data 中强制使用 CrudRepository 进行预加载?

    我有一个实体 其中包含List就是这样lazy默认加载 interface MyEntityRepository extends CrudRepository
  • 获取 Future 对象的进度的能力

    参考 java util concurrent 包和 Future 接口 我注意到 除非我弄错了 只有 SwingWorker 实现类才能启动冗长的任务并能够查询进度 这就引出了以下问题 有没有办法在非 GUI 非 Swing 应用程序 映
  • 在java中执行匿名pl/sql块并获取结果集

    我想执行匿名 PL SQL 并需要获取结果集对象 我得到了可以通过在 PL SQL 块内使用游标来完成的代码 但 PL SQL 块本身将以文本形式来自数据库 所以我无法编辑该 PL SQL 块 并且它只会返回两个值 其列名始终相同 它将返回
  • Firebase:用户注册后如何进行电话号码验证?

    所以我知道我可以使用电子邮件验证或电话号码验证 但我想做的是在用户注册或登录后进行电话号码验证 如何连接这两种身份验证方法 最后 Firebase中是否有一个函数可以检查用户是否通过电话号码验证 谢谢 即使用户已通过身份验证 您仍然可以使用
  • 我怎样才能限定我不“拥有”的自动装配设置器

    要点是 Spring Batch v2 测试框架具有JobLauncherTestUtils setJob与 Autowired注解 我们的测试套件有多个Job类提供者 由于这个类不是我可以修改的东西 我不确定如何限定它自动连接的作业 每个

随机推荐

  • VMware Workstation 不可恢复错误: (vcpu-0),Exception 0xc0000005 (access violation) has occurred.

    在使用VMware虚拟机的时候可能会出现VMware Workstation 不可恢复错误 vcpu 0 Exception 0xc0000005 access violation has occurred 的报错情况 经常出现在启动 挂起
  • 【游戏音效】Unity集成Wwise并进行开发的全流程教程(一)准备工作

    集成教程 游戏音效 Unity集成Wwise并进行开发的全流程教程 二 Wwise项目 游戏音效 Unity集成Wwise并进行开发的全流程教程 三 脚本接入Unity 前言 Unity有自己的原生音乐功能 AduioSound 但是这个功
  • C++ 泛型算法 std::find() ,用于在数组或标准库容器中查找指定元素

    find 函数是一个 泛型算法 可以用于操作所有STL容器 它用于在数组或标准库容器 如vector map 中查找指定元素 查找成功则返回一个指向指定元素的迭代器 查找失败则返回end迭代器 注意不是返回 true or false 代码
  • java科学计数法转换为普通数字_Java BigDecimal toString() 的转换和输出

    BigDecimal 的 toString 方法将会把 BigDecimal 通过字符串的方式输出 这个方法将会在必要的时候使用指数进行输出 具体的转换步骤是按照下面的步骤进行转换的 BigDecimal的非标度值的绝对值用字符 0 到 9
  • linxu/torch/pytorch会自动安装 cuda

    如下图所示
  • Android 是否可支持 exFAT 格式 U 盘?如何使 Android 设备支持 exFAT

    Android 是否可支持 exFAT 格式 U 盘 如何使 Android 设备支持 exFAT exFAT 文件系统是一种适用于移动设备和嵌入式系统的文件系统 它具有更好的兼容性和更高的性能 然而 并非所有的 Android 设备都原生
  • 华为OD机试真题-完美走位/滑动窗口【2023Q1】

    输入一个长度为4的倍数的字符串 字符串中仅包含WASD四个字母 将这个字符串中的连续子串用同等长度的仅包含WASD的字符串替换 如果替换后整个字符串中WASD四个字母出现的频数相同 那么我们称替换后的字符串是 完美走位 求子串的最小长度 如
  • 2023华为OD机试真题【严格递增字符串】【2023.Q2】

    题目描述 定义字符串完全由 A 和 B 组成 当然也可以全是A 或全是 B 如果字符串从前往后都是以字典序排列的 那么我们称之为严格递增字符串 给出一个字符串s 允许修改字符串中的任意字符 即可以将任何的 A 修改成 B 也可以将任何的 B
  • dll signing issue

    1 Verify if a dll has been signed sn exe v module dll Scenario sometimes for security reasons a Net program requires all
  • 命令行_第二篇 Anaconda Prompt 命令提示符

    Anaconda 安装外接库过程 1 打开Anaconda Prompt 输入conda list 就会显示已经安装好的库 2 如果已安装库中没有所需的库 则需要手动进行安装 3 pip install 外接库 更新所需要的外接库 Anac
  • 用 h2 替换 hsql

    开发时用hsql做数据库 没什么问题 部署的时候 碰到数据量比较大的情况 就有点感觉慢了 这个时候 想替换方案时 考虑了几个可能的替代 一个是mysql 肯定没问题 但是部署麻烦 被否定了 其他的java数据库 可选的包括 mocki 这个
  • C语言学习

    为了更好的理解数据结构 开始重温C语言 以前学习过C语言 所以此笔记可能有些天马行空 不系统 挂个学习链接 C语言实例说明 解剖C语言 C语言教程 C语言网 dotcpp com 1B 1byte 字节 8bit 一字节存两位16进制数 以
  • 数据科学猫:强化学习的定义

    进击的橘子猫正式改名上线啦 我的CSDN主页 https blog csdn net Orange Spotty Cat 也欢迎大家搜索微信公众号 进击的橘子猫 我也会定期分享数据科学 Python 大数据 项目管理与PPT的相关知识 让我
  • DUT处理延迟 对Monitor采数和验证环境结束机制的影响分析

    1 问题背景 一句话描述 验证环境中 当激励完成发送时 由于DUT存在处理延迟 monitor在延迟一段时间后才能采集到DUT完整的输出 如何设计验证环境的结束机制 此处的验证环境结束机制 可以认为是main phase的结束控制 但并不单
  • 21. Merge Two Sorted Lists

    题目描述 将两个升序链表合并为一个新的 升序 链表并返回 新链表是通过拼接给定的两个链表的所有节点组成的 示例 1 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img 0VfjZ6Ct 1686493063120 i
  • STM32CubeMX工程配置说明

    一 STM32CubeMX配置 1 1 设置时钟 单片机的时钟 相当于人的心跳 只要单片机工作 必须要开启时钟 STM32单片机共有4个时钟来源 名称 缩写 频率 外部连接 功能 用途 特性 外部高速晶体振荡器 HSE 4 16MHz 4
  • Android手把手实战APP首页 下拉刷新 自动加载

    一 概述 作为一名三年Android开发经验的程序员 今天和大家一起实战一款APP的首页功能 这个首页在我们平时接触中还是很常见的 虽然页面简单 但是里面涉及的功能点还是挺多的 代码如有不足的还望各路同仁指点一二 页面中使用的开发库 整个首
  • 国家税务总局全国增值税发票查验平台网站js逆向分析及全逆向算法还原

    本文教程针对的是2021年7月2日时国税查验平台的js分析 其中版本号为V2 0 06 009 主要分析内容为key9和flwq39以及fplx这3个参数的算法 其中key9分为获取验证码阶段和查验阶段 算法有所区别 flwq39同理 教程
  • js-倒计时

    p p
  • Redis的底层数据结构

    1 Redis的五种数据类型及七种底层结构 键的类型只能为字符串 值支持五种数据类型 字符串 列表 集合 散列表 有序集合 对于Redis来讲 对于键值对来说 键总是字符串 值就是五个中的一个 所以我们只用关心值的类型 值有五种数据类型 S