Redis(设计与实现):03---数据结构之字典(hashtable、struct dictht、struct dictEntry、struct dict)

78 篇文章 28 订阅
订阅专栏

一、字典介绍

  • 字典,又称为符号表(symbol table)、关联数组(associative array)或映射(map), 是一种用于保存键值对(key-value pair)的抽象数据结构
  • 在字典中,一个键(key)可以和一个值(value)进行关联(或者说将键映射为值), 这些关联的键和值就称为键值对
  • 字典中的每个键都是独一无二的,程序可以在字典中根据键查找与之关联的值,或者通过键来更新值,又或者根据键来删除整个键值对,等等

二、字典在Redis中的应用场景

  • ①Redis的数据库就是使用字典来作为底层实现的, 对数据库的增、删、查、改操作也是构建在对字典的操作之上的
    • 举个例子,当我们执行下面命令,在数据库中创建一个键为"msg",值为"hello world"的键值对时,这个键值对就是保存在 代表数据库的字典里面的:
redis> SET msg "hello world"
OK
  • ②字典还是哈希键的底层实现之一,当一个哈希键包含的键值对比较多,又或者键值对中的元素都是比较长的字符串时,Redis就会使用字典作为哈希键的 底层实现

例如:

  • website是一个包含10086个键值对的哈希键,这个哈希键的键都是一些数据 库的名字,而键的值就是数据库的主页网址:

  • website键的底层实现就是一个字典,字典中包含了10086个键值对,例如:
    • 键值对的键为"Redis",值为"Redis.io"
    • 键值对的键为"MariaDB",值为"MariaDB.org"
    • 键值对的键为"MongoDB",值为"MongoDB.org"
  • ③除了用来实现数据库和哈希键之外,Redis的不少功能也用到了字典,我们将在后面介绍

三、字典的底层实现

  • Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个 哈希表节点就保存了字典中的一个键值对

哈希表(struct dictht)

  • Redis字典所使用的哈希表由dict.h/dictht结构定义:
typedef struct dictht {
    //哈希表数组
    dictEntry **table;
    //哈希表大小
    unsigned long size;
    //哈希表大小掩码,用于计算索引值。总是等于size-1
    unsigned long sizemask;
    //该哈希表已有节点的数量
    unsigned long used;
} dictht;
  • 成员介绍:
    • table属性:是一个数组,数组中的每个元素都是一个指向dict.h/dictEntry结构的指针,每个 dictEntry结构保存着一个键值对
    • size属性:记录了哈希表的大小,也即是table数组的大小
    • used属性:则记录了哈希表目前已有节点(键值对)的数量
    • sizemask属性:的值总是等于size-1,这个属性和哈希值一起决定一个键应该被放到table数组的哪个索引上面
  • 例如:下图展示了一个大小为4的空哈希表(没有包含任何键值对)

哈希表节点(struct dictEntry)

  • 哈希表节点使用dictEntry结构表示,每个dictEntry结构都保存着一个键值对:
typedef struct dictEntry {
    //键
    void *key;
    //值
    union{
        void *val;
        uint64_tu64;
        int64_ts64;
    } v;
    //指向下个哈希表节点,形成链表
    struct dictEntry *next;
} dictEntry;
  • 成员如下:
    • key属性保存着键值对中的键,而v属性则保存着键值对中的值,其中键值对的值可以是 一个指针,或者是一个uint64_t整数,又或者是一个int64_t整数
    • next属性是指向另一个哈希表节点的指针,这个指针可以将多个哈希值相同的键值对连 接在一次,以此来解决键冲突(collision)的问题
  • 例如:下图就展示了如何通过next指针,将两个索引值相同的键k1和k0连接在一 起

字典(struct dict)

  • Redis中的字典由dict.h/dict结构表示:
typedef struct dict {
    //类型特定函数
    dictType *type;
    //私有数据
    void *privdata;
    //哈希表
    dictht ht[2];
    //rehash 索引。当rehash 不在进行时,值为-1
    in trehashidx; /* rehashing not in progress if rehashidx == -1 */
} dict;


typedef struct dictType {
    //计算哈希值的函数
    unsigned int (*hashFunction)(const void *key);
    //复制键的函数
    void *(*keyDup)(void *privdata, const void *key);
    //复制值的函数
    void *(*valDup)(void *privdata, const void *obj);
    //对比键的函数
    int (*keyCompare)
    (void *privdata, const void *key1, const void *key2);
    //销毁键的函数
    void (*keyDestructor)(void *privdata, void *key);
    //销毁值的函数
    void (*valDestructor)(void *privdata, void *obj);
} dictType;

  • 成员如下:
    • type属性和privdata属性是针对不同类型的键值对,为创建多态字典而设置的
    • type属性是一个指向dictType结构的指针,每个dictType结构保存了一簇用于操作特定 类型键值对的函数,Redis会为用途不同的字典设置不同的类型特定函数
    • 而privdata属性则保存了需要传给那些类型特定函数的可选参数
    • ht属性是一个包含两个项的数组,数组中的每个项都是一个dictht哈希表,一般情况下, 字典只使用ht[0]哈希表,ht[1]哈希表只会在对ht[0]哈希表进行rehash时使用
    • 除了ht[1]之外,另一个和rehash有关的属性就是rehashidx,它记录了rehash目前的进度,如果目前没有在进行rehash,那么它的值为-1
  • 下图展示了一个普通状态下(没有进行rehash)的字典

四、哈希算法

  • 当要将一个新的键值对添加到字典里面时,程序需要先根据键值对的键计算出哈希值和索引值,然后再根据索引值,将包含新键值对的哈希表节点放到哈希表数组的指定索引上 面
  • Redis计算哈希值和索引值的方法如下:
#使用字典设置的哈希函数,计算键key 的哈希值hash = dict->type->hashFunction(key);

#使用哈希表的sizemask 属性和哈希值,计算出索引值
#根据情况不同,ht[x] 可以是ht[0] 或者ht[1]
index = hash & dict->ht[x].sizemask;
  • MurmurHash2算 法:
    • 当字典被用作数据库的底层实现,或者哈希键的底层实现时,Redis使用MurmurHash2算 法来计算键的哈希值
    • MurmurHash算法最初由Austin Appleby于2008年发明,这种算法的优点在于,即使输入 的键是有规律的,算法仍能给出一个很好的随机分布性,并且算法的计算速度也非常快
    • MurmurHash算法目前的最新版本为MurmurHash3,而Redis使用的是MurmurHash2,关 于MurmurHash算法的更多信息可以参考该算法的主页:http://code.google.com/p/smhasher/

演示案例

  • 对于下图所示的字典来说,如果我们要将一个键值对k0和v0添加到字典里 面,那么程序会先使用语句计算键k0的哈希值:
hash = dict->type->hashFunction(k0);

  • 假设计算得出的哈希值为8,那么程序会继续使用语句计算出键k0的索引值0,这表示包含键值对k0和v0的节点应该被放置到哈希表数组的索引0位置上,如下图所示:
index = hash&dict->ht[0].sizemask = 8 & 3 = 0;

五、解决键冲突

  • 当有两个或以上数量的键被分配到了哈希表数组的同一个索引上面时,我们称这些键发生了冲突(collision)
  • Redis的哈希表使用链地址法(separate chaining)来解决键冲突,每个哈希表节点都有 一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上 的多个节点可以用这个单向链表连接起来,这就解决了键冲突的问题

演示案例

  • 假设程序要将键值对k2和v2添加到下图所示的哈希表里面

  • 并且计算得出k2 的索引值为2,那么键k1和k2将产生冲突,而解决冲突的办法就是使用next指针将键k2和k1所在的节点连接起来,如下图所示

  • 因为dictEntry节点组成的链表没有指向链表表尾的指针,所以为了速度考虑,程序总是 将新节点添加到链表的表头位置(复杂度为O(1)),排在其他已有节点的前面。

六、rehash(重新排列)

  • 随着操作的不断执行,哈希表保存的键值对会逐渐地增多或者减少,为了让哈希表的负载因子(load factor)维持在一个合理的范围之内,当哈希表保存的键值对数量太多或者太少时,程序需要对哈希表的大小进行相应的扩展或者收缩
  • 扩展和收缩哈希表的工作可以通过执行rehash(重新散列)操作来完成,Redis对字典的哈希表执行rehash的步骤如下:
    • ①为字典的ht[1]哈希表分配空间,这个哈希表的空间大小取决于要执行的操作,以及 ht[0]当前包含的键值对数量(也即是ht[0].used属性的值)
      • 如果执行的是扩展操作,那么ht[1]的大小为第一个大于等于ht[0].used*2的2^{n}(2的n次方幂); ·如果执行的是收缩操作,那么ht[1]的大小为第一个大于等于ht[0].used的2^{n}
    • ②将保存在ht[0]中的所有键值对rehash到ht[1]上面:rehash指的是重新计算键的哈希值 和索引值,然后将键值对放置到ht[1]哈希表的指定位置上
    • ③当ht[0]包含的所有键值对都迁移到了ht[1]之后(ht[0]变为空表),释放ht[0],将 ht[1]设置为ht[0],并在ht[1]新创建一个空白哈希表,为下一次rehash做准备

演示案例

  • 假设程序要对下图所示字典的ht[0]进行扩展操作,那么程序将执行以下步骤:

  • ht[0].used当前的值为4,4*2=8,而8(2^{3})恰好是第一个大于等于4的2的n次方,所 以程序会将ht[1]哈希表的大小设置为8。下图展示了ht[1]在分配空间之后,字典的样子

  • 将ht[0]包含的四个键值对都rehash到ht[1],如下图

  • 释放ht[0],并将ht[1]设置为ht[0],然后为ht[1]分配一个空白哈希表,如下图所示。 至此,对哈希表的扩展操作执行完毕,程序成功将哈希表的大小从原来的4改为了现在的8

哈希表的自动扩展与收缩

  • 当以下条件中的任意一个被满足时,程序会自动开始对哈希表执行扩展操作:
    • ①服务器目前没有在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载因子大于等于1
    • ②服务器目前正在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载因子大于等于5
  • 其中哈希表的负载因子可以通过下列公式得出:
#负载因子= 哈希表已保存节点数量/哈希表大小
load_factor = ht[0].used/ht[0].size
  • 例如,对于一个大小为4,包含4个键值对的哈希表来说,这个哈希表的负载因子为:
load_factor = 4/4 = 1
  • 又例如,对于一个大小为512,包含256个键值对的哈希表来说,这个哈希表的负载因子为:
load_factor = 256/512=0.5
  • 根据BGSAVE命令或BGREWRITEAOF命令是否正在执行,服务器执行扩展操作所需的负载因子并不相同,这是因为在执行BGSAVE命令或BGREWRITEAOF命令的过程中,Redis 需要创建当前服务器进程的子进程,而大多数操作系统都采用写时复制(copy-on-write)技 术来优化子进程的使用效率,所以在子进程存在期间,服务器会提高执行扩展操作所需的负 载因子,从而尽可能地避免在子进程存在期间进行哈希表扩展操作,这可以避免不必要的内 存写入操作,最大限度地节约内存
  • 另一方面,当哈希表的负载因子小于0.1时,程序自动开始对哈希表执行收缩操作

七、渐进式rehash

  • 上一节说过,扩展或收缩哈希表需要将ht[0]里面的所有键值对rehash到ht[1]里面,但 是,这个rehash动作并不是一次性、集中式地完成的,而是分多次、渐进式地完成的
  • 这样做的原因在于:如果ht[0]里只保存着四个键值对,那么服务器可以在瞬间就将这些 键值对全部rehash到ht[1];但是,如果哈希表里保存的键值对数量不是四个,而是四百万、 四千万甚至四亿个键值对,那么要一次性将这些键值对全部rehash到ht[1]的话,庞大的计算 量可能会导致服务器在一段时间内停止服务
  • 因此,为了避免rehash对服务器性能造成影响,服务器不是一次性将ht[0]里面的所有键 值对全部rehash到ht[1],而是分多次、渐进式地将ht[0]里面的键值对慢慢地rehash到ht[1]
  • 以下是哈希表渐进式rehash的详细步骤:
    • ①为ht[1]分配空间,让字典同时持有ht[0]和ht[1]两个哈希表
    • ②在字典中维持一个索引计数器变量rehashidx,并将它的值设置为0,表示rehash工作 正式开始
    • ③在rehash进行期间,每次对字典执行添加、删除、查找或者更新操作时,程序除了执 行指定的操作以外,还会顺带将ht[0]哈希表在rehashidx索引上的所有键值对rehash到ht[1], 当rehash工作完成之后,程序将rehashidx属性的值增一
    • ④随着字典操作的不断执行,最终在某个时间点上,ht[0]的所有键值对都会被rehash至 ht[1],这时程序将rehashidx属性的值设为-1,表示rehash操作已完成
  • 渐进式rehash的好处在于它采取分而治之的方式,将rehash键值对所需的计算工作均摊 到对字典的每个添加、删除、查找和更新操作上,从而避免了集中式rehash而带来的庞大计 算量

演示案例

  • 下面展示了一次完整的渐进式rehash过程,注意观察在整个rehash过程中,字 典的rehashidx属性是如何变化的

渐进式rehash执行期间的哈希表操作

  • 因为在进行渐进式rehash的过程中,字典会同时使用ht[0]和ht[1]两个哈希表,所以在渐 进式rehash进行期间,字典的删除(delete)、查找(find)、更新(update)等操作会在两 个哈希表上进行。例如,要在字典里面查找一个键的话,程序会先在ht[0]里面进行查找,如 果没找到的话,就会继续到ht[1]里面进行查找,诸如此类
  • 另外,在渐进式rehash执行期间,新添加到字典的键值对一律会被保存到ht[1]里面,而 ht[0]则不再进行任何添加操作,这一措施保证了ht[0]包含的键值对数量会只减不增,并随着 rehash操作的执行而最终变成空表

八、字典API

Redis内部数据结构详解(1)——dict
u013938578的博客
04-06 293
如果你使用过Redis,一定会像我一样对它的内部实现产生兴趣。《Redis内部数据结构详解》是我准备写的一个系列,也是我个人对于之前研究Redis的一个阶段性总结,着重讲解Redis在内存中的数据结构实现(暂不涉及持久化的话题)。Redis本质上是一个数据结构服务器(data structures server),以高效的方式实现了多种现成的数据结构,研究它的数据结构和基于其上的算法,对于我们自己...
redis系列之一:数据结构&关联
HK_KIKY的博客
01-11 612
r深入edis数据结构
Redis内部数据结构详解之字典(dict)
fmt.Println(
12-22 9614
本文所引用的源码全部来自Redis2.8.2版本。 Redis字典dict数据结构与API相关文件是:dict.h, dict.c。 本文讲解的不是很详细,可以同时参考Redis实现设计一书中字典部分,本文关于字典的核心代码的注释可以参考。 字典,简单说就是存储key-value键值数据,当然value=NULL那么就是集合了。字典通俗来说就是C++ STL中的m
redis源码阅读—dict(字典结构)_字典规则源
最新发布
2401_87361386的博客
09-22 988
因为在进行渐进式 rehash 的过程中, 字典会同时使用 ht[0] 和 ht[1] 两个哈希表, 所以在渐进式 rehash 进行期间, 字典的删除(delete)、查找(find)、更新(update)等操作会在两个哈希表上进行: 比如说, 要在字典里面查找一个键的话, 程序会先在 ht[0] 里面进行查找, 如果没找到的话, 就会继续到 ht[1] 里面进行查找, 诸如此类。扩展和收缩都需要将ht[0]里面的所有键值对散列到ht[1]中,但是这个动作并不是一次性完成的,而是分多次,渐进式完成的。
Redis数据结构-dict
qq_35901181的博客
10-05 286
Redis底层是采用哈希加链表实现的,了解Redis内部数据结构,对学习Redis有很大的帮助。 先来看几个关键词 dictEntry:表示一个key-value节点。 dictht:表示一个dict哈希表,里面有一个数组,数组里面的每个元素都是指向dictEntry的指针。 dict:表示redis字典结构,里面有2个哈希表,一个用来存储键值对,一个用来rehash。 dictType:保存了一些用于操作特定类型键值对的函数 附上源码: dictEntry typedef struct
dictEntry
TuxedoLinux的博客
02-19 1613
typedef struct dictEntry { // 键 void *key; // 值 union { void *val; uint64_t u64; int64_t s64; } v; // 指向下个哈希表节点,形成链表 struct dictEntry *next; } d...
Redis基础数据结构篇之dict
火焰柠檬
09-20 403
Redis源码学习 本系列文章基于redis6.0.6版本,详见官网https://redis.io。 根据前人分享,结合源码,本系列将分为11个部分, 详见Redis源码学习,文章为记录个人理解,能力受限,如有偏颇之处请指正。 前言 Redis基础数据结构篇之dict: The implementsin-memoryhashtableswithinsert/del/replace/find/ get-random-elementoperations.Hashtablesw...
Redis 数据结构 hashtable
格物致知,知行合一。
05-09 859
和大家分享 Redis数据结构 hashtable(哈希表),欢迎阅读斧正。
Redis设计核心-1-Redis底层数据结构总结1
yqxz045000的博客
06-09 690
前言 最近看了相关的Redis设计核心相关的书籍,对Redis有了一些小的认识,然后自己也做一些产出加深映象,我会从几个方面去总结Redis设计的核心内容:Redis底层数据结构总结、Redis高性能由哪些基础支撑、Redis应用场景、那些有趣的功能。 概述 本篇主要内容是Redis底层数据结构总结。Redis供用户直接使用的数据结构有String、List、Set、Zset、Hash等结...
Redis底层数据结构---hash表
chenmengyuanCSDN的博客
03-26 1209
Redis的哈希表—rehash详细讲解   Redis的性能优越,应用普遍,可以存储的键值个数大到上亿条记录,依然保持较高的效率。作为一个内存数据库,Redis内部采用了字典(哈希表)的数据结构实现了键值对的存储。随着数据量的不断增加,数据必然会产生hash碰撞,而Redis采用链地址法解决hash冲突。我们知道如果哈希表数据量达到了一个很大的量级,那么冲突的链的元素数量就会很大,这时查询效率就...
Redis底层核心数据结构Redis6.0新特性
qq_44027353的博客
03-27 572
在移动数据过程中如果客户端进行了更新操作,Redis会操作两个dictht,先去老数组ht[0]中找,如果没有找到就直接去新数组ht[1]中操作,如果老数组找到了就是在老数组中去操作,同时会把这个hash桶中的数据全都移动到新数组中去。中的level记录的是最高的层高数,因为索引遍历时是从最高的那一层开始往下找的,这个层高是通过一个随机函数生成的,越高的层数出现的概率越低。Redis中所有的key都是String类型的,底层是使用的SDS类型,没有使用c语言的字符数组去实现字符串。
redis源码解析 hash字典- dict (6.2.3版本)
qazwsxwtc的专栏
08-04 275
hash字典,kv存储,用于快速查询,redis中的源码为 dict.h和dict.c, redis hash字典采用渐进式hash实现,具体渐进式hash,请搜索相关博文阅读。 redishash字典的结构体声明 typedef struct dictEntry {//字典实体节点 void *key; //字典实体节点key union { void *val; uint64_t u64; int64_t s64; .
python dict hashtable_Dict(hashtable, Map) implementation in python
weixin_39752880的博客
12-18 175
__author__ = 'bozeng'## this code implements a hashtable.class Item:def __init__(self, key, value):self.key=keyself.value=value## do it using linear probing and two lists (for easier retrieval of keys...
Redis 6.0 源码阅读笔记(3)-概述 Redis 重要数据结构及其 6 种数据类型
谈谈1974
08-27 1499
文章目录1. 重要数据结构1.1 redisServer1.2 redisDb1.3 dict1.4 dictht1.5 dictEntry2. 数据类型2.1 Redis 数据对象结构2.2 Redis 数据类型及其存储结构2.2.1 字符串对象 String 1. 重要数据结构 Redis 有许多重要的数据结构,其存储结构从外层往内层依次是 redisDb、dictdicthtdictEntry redisDb 默认情况下有16个,每个 redisDb 内部包含一个 dict数据结构dict
java中的hashtable_java之HashTable
weixin_30127995的博客
02-12 269
一、HashTable1.1基本数据结构首先根据上图,并结合代码,来看一下HashTable的基本数据结构:根据代码,可以看出HashTable是一个Entry<>的数组,那Entry又是什么呢?HashTable中的EntryHashTable.class的一个内部类,来看一下源代码:这里,我们关注它的四个字段,hash、key、value、next。这里的hash也就是之所以叫H...
Redis存储结构之dictht字典
java那些事儿
09-06 532
属性是个数组, 数组的每个元素都是个指向dictEntry结构的指针。每个dictEntry都保存着一个键值对, 以及一个指向另一个dictEntry属性指向另一个dictEntry结构, 多个dictEntry可以通过next指针串连成链表, 从这里可以看出,dictht使用链式寻址法来解决hash冲突: 当多个不同的键拥有相同的哈希值时,哈希表用一个链表将这些键连接起来。
Redis底层数据结构Dict
xiong_tai的博客
04-23 2926
RedisDict 是一个高效的键值对映射数据结构,采用双哈希表实现以支持无锁的渐进式 Rehash,确保扩容或缩容时的高效性能。它通过哈希表节点以链表形式解决哈希冲突,允许快速的查找、插入和删除操作,是实现 Redis 各种数据类型和高级功能的基础架构之一。
leetcode-哈希表
SunYutong_1234的博客
02-24 1676
哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构。哈希表通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做哈希函数,存放记录的数组称做哈希表。
Leetcode算法(两数之和)
weixin_44059948的博客
07-27 620
//给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 // // 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 // // 你可以按任意顺序返回答案。 // // // // 示例 1: //输入:nums = [2,7,11,15], target = 9 //输出:[0,1] //解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 解法.
Redis字典实现解析:dict数据结构与哈希策略
Redis是一个高性能的键值数据库,其内部数据结构之一是字典dict),用于存储键值对。在Redis 2.8.2版本中,字典实现主要依赖于哈希表,这是一种高效的数据结构,允许快速查找、插入和删除操作。本文将探讨字典的...
写文章

热门文章

  • C++:19---sizeof运算符 506915
  • Linux磁盘格式化(mkfs、mkfs.xfs、mkfs.ext4)、Linux文件系统的校验(xfs_repair、fsck_ext4) 112030
  • 全方面讲解OpenWrt的DNS配置与DHCP,并介绍dnsmasq DNS缓存工具、nslookup/dig DNS测试工具 38145
  • OPKG包管理系统详解!带你管理OpenWrt系统软件 37254
  • 两种高效的事件处理模式(reactor模式、proactor模式),C/C++编码实现 36986

分类专栏

  • UNP编程 47篇
  • APUE编程 119篇
  • Linux(入门基础) 34篇
  • Linux(程序设计) 57篇
  • Linux(内核剖析) 38篇
  • Nginx 15篇
  • Kafka
  • Docker 20篇
  • ZeroMQ 19篇
  • ZooKeeper
  • Kubernetes
  • Prometheus
  • 项目(百万并发网络通信架构) 26篇
  • 后端开发杂记 3篇
  • 服务/软件管理 54篇
  • muduo网络库 21篇
  • Lua 10篇
  • Go
  • Go(标准库)
  • Go(第三方库)
  • Go(Gin框架)
  • C 26篇
  • C++ 90篇
  • C++(标准库) 51篇
  • C++ STL源码剖析 22篇
  • C++(对象模型) 9篇
  • C++(数据结构与算法) 63篇
  • Effective STL 7篇
  • Effective C++ 51篇
  • Memcached
  • Redis(开发与运维) 29篇
  • Redis(设计与实现) 78篇
  • MySQL 49篇
  • MySQL(InnoDB剖析) 55篇
  • 高性能MySQL
  • Kali 22篇
  • 堆漏洞挖掘 27篇
  • Qt 82篇
  • OpenWrt开发 21篇
  • HTTP
  • TCP/IP卷一 92篇
  • 计算机网络 17篇

最新评论

  • APUE编程:108---进程管理(进程组与会话:getpgrp、getpgid、setsid、getsid)

    玟林禹: 您好,第六章节上面那个例子,子进程的pid不应该是固定为0吗,为什么getpid得到的数是3114

  • 超详细!手把手演示编译OpenWrt内核驱动模块

    espalternatives: 楼主没有给出(从无到有的)正确的编译命令。它这命令只适合已经编译过的。

  • 堆的调用流程、堆漏洞挖掘中的malloc_chunk结构体分析

    youthdou: fd(forward pointer to next chunk in list),不应该是下一个chunk指针吗?

  • 堆的调用流程、堆漏洞挖掘中的malloc_chunk结构体分析

    youthdou: fd(forward pointer to next chunk in list),不应该是下一个chunk指针吗?

  • MySQL(InnoDB剖析):26---B+树索引之Cardinality值

    开发工程师_卢刚: 针对性别这样的字段加索引的话,会有多少页呢? 只有一页还是很多页? 如果有很多页的话那个cardinality统计也是不准的,可能是叶子节点个数的两倍. 而实际结果应该是2

最新文章

  • 面试冲刺:54---MTU是什么?IP分片是什么?MSS是什么?TCP和UDP会分片吗?它们的关系是什么?
  • 系统可用性:SRE口中的3个9,4个9...到底是个什么东西?
  • MySQL与Redis数据库连接池介绍(图示+源码+代码演示)
2022年2篇
2021年12篇
2020年497篇
2019年752篇
2018年9篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家衡阳玻璃钢雕塑公司哪家好舟山商场美陈公司上饶特色玻璃钢雕塑供应商衢州定制玻璃钢雕塑设计玻璃钢红旗浮雕雕塑兴化玻璃钢雕塑加工营口实惠的沈阳玻璃钢花盆韶关楼盘玻璃钢人物雕塑扬州蛋形玻璃钢花盆楚雄市玻璃钢雕塑哪家好武威玻璃钢雕塑生产厂家浮雕学校玻璃钢雕塑南京家居商场美陈新郑玻璃钢雕塑寒亭玻璃钢花盆花器安庆元旦商场美陈佛山玻璃钢植物卡通雕塑陕西定制玻璃钢雕塑方法玻璃钢古钟雕塑玻璃钢雕塑小品现货江苏多彩玻璃钢雕塑雅安玻璃钢雕塑制作厂家信阳铸铜校园玻璃钢景观雕塑开原玻璃钢仿铜雕塑滁州市玻璃钢雕塑广西动物玻璃钢雕塑厂家西山区玻璃钢雕塑造型厂家美陈创意商场专业的玻璃钢新娘雕塑商场农家小木屋美陈香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化