粉丝1.2万获赞8.3万

radius 常用的五种数据类型都是基于不同的数据结构实现的,本期介绍实现 list 列表的数据结构, quick list 快速列表。实现 visit 有序集合的数据结构, skip list 跳表。 学习数据结构之前,我们先要知道什么是时间复杂度和空间复杂度。其实这两个是衡量算法效率的指标,用来描述时间和空间增长的趋势。通常我们会使用大 o 表示法来表示。 假设 a 大于 b, 那么 c 加加这行代码就会执行一次,它的时间复杂度就是 o e, 这是一个 for 循环。从 e 到 n 要循环 n 次,所以 c 加加会执行 n 次, 它的时间复杂度就是 o n。 那么一个两层循环,外层循环 n 次,内层也循环 n 次。 c 加加需要执行的次数就是 n 的二次方,所以它的时间复杂度就是 o n 的二次方。 o e o n o n 的二次方。三种是最常见的时间复杂度。与之类似的三种空间复杂度, int a 等于一,它声明了一个固定大小的变量,占用空间的大小不会发生变化,因此它的空间复杂度就是 o e a re 是一个长度为 n 的数组,占用空间的大小会随着 n 的大小改变,所以它的空间复杂度就是 o n。 那如果 array 是一个长度为 n 的二位数组,它的空间复杂度就是 o n 的二次方。除了以上 上三个,还有一些其他的复杂度,比如跳表数据结构,它的平均时间复杂度是 olog n, 这是一个初始化值 i 等于二的破循环, i 乘二的方式递增。如果 n 等于二, c 加加会执行一次,就是 log, 以二为底,二的对数等于一, 如果 n 等于四, c 加加会执行。两次就是 log, 腰为底,四的对数等于二。如果 n 等于八, c 加加会执行。三次就是 log, 腰为底,八的对数等于三, 以此类推,执行的次数就是 log, 以二为底 and 对数,所以它的时间复杂度就是 o log n。 理解了时间复杂度 o log n 的概念,我们趁热打铁开始介绍实现 visit 有序集合的 数据结构。跳表,这是一个有序列表,我们在添加、查询和删除的平均时间复杂度都是 o n, 因为 n 的元素我们使用负循环便利,最多需要执行 n 次才能找到这个元素。 而跳表在这个原始链表的基础上构建了多级锁影,目的就是提高查询效率,将它的添加、查询和删除的平均时间复杂度变成 olog n。 每一层锁影都是一个有序链表,包含了前面一层的部分元素,顶层的锁影元素最少,底层的锁影元素最多。 通常每个节点的元素是否能晋升到上一层有一个随机概率, p 决定。通常 p 的值可以设置为是零点五或者零点二五。在这个案例中,每一层的节点都只能一半,晋升到上一层意味着 p 为零点五。跳表会有一个 header 头结点,这个头结点存在于每一层缩影中。所有查询、删除、添加、操作都是从头结点开始。 我们在每一层都是从当前节点向右移动,遇到小于目标值的节点就将指针推进到下一个节点。遇到大于目标值的节点,就回到当前节点,并锁影向下推进一层。 我们来模拟一下跳表的执行原理。假如我们需要查询元素四,从 header 头节点出发,从二级锁引开始,向右移动,查看后记节点四,节点四等于四。查找结束了。整个过程一共执行了一次比较操作。 假如我们需要查询元素五,从黑的头结点出发,由二级缩音开始,向右移动,查看后 节点四,节点四小于五,将指针推进到节点四。从节点四出发,向右移动查看四的后期,节点是八,节点八大于五,于是回到节点四,所以向下推进一层, 来到四的一级锁影,向右移动,查看四的后记,节点为六,节点六大于五,于是回到节点四,所以又向下推进一层,来到四的原始节点,向右移动,查看四的后记,节点为五,节点五等于五。查找结束。 整个过程一共执行了四次比较操作。假如我们需要查询元素七,从 header 头结点出发,由二级缩音开始,向右移动,查看后极节点四,节点四小于五,将指针推进 到节点四。从节点四出发,向右移动,查看四的后记,节点是八,八大于七,于是回到节点四,所以向下推进一层, 来到四的一级缩影,向右移动,查看四的后极,节点为六,六小于七。指针推进到节点六的位置,从节点六出发,向右移动,查看六的后极节点八,八大于七,于是回到节点六。缩影,向下推进一层, 来到六的原始节点,向右移动,查看六的后期节点为七,节点七等于七。查找结束。整个过程一共执行了五次比较操作,添加和删除操作。查找节点的核心流程也是一样的,在这十个节点中,想要操作某一个节点,需要执行的平均次数是 log, 以二为底,十的对数等于三点三,也就是平均时间,复杂度为 o log n。 quick list 是实现 list 列表的数据结构,它将双向列表和 zip list 压缩列表结合。 zip list 是一种简单紧凑、连续存储的数据结构,由一系列特殊编码的连续内存快组成。 前面的三个是 zip list 的头部信息,最后一个 zealand 是整个 zip list 结束的标识,而中间的 entry 就是 zip list 存储的数据节点。 例如一个类似的列表, a b c, 存储为 h, e 等于 a h, 二等于 b h, 三等于 c, 但是它只适合小数据量场景,如果存 存储的数据量超出了 zip less 的最佳的上限,就会导致效率很低。既然一个 zip less 的放不下,那就多整几个 zip less 的来分片存储数据。看一下这边的演示图,每一个 zip less 的都作为一个节点, 再把它们串联起来,形成一个双向列表。 next 是指向列表中的后一个节点, our preview 是指向列表中的前一个节点。这就是一个 quick list 的基本结构,有多个节点组成,每一个节点就是 quick list node。 其中 next 和 preview 是 quick list node 节点的两个属性。 quick list 也是有两个属性, head 是指项链 表的头部节点, tail 指向链表的尾部节点。通过将链表和 zipless 的结合,既实现了链表的灵活操作,又具备了压缩列表的内存优势。那本期的内容就到这边结束了,我们下期再见。

月底时制止的常见数据类型有哪些?时讯支付站存储支付账或数字,可以用来做指针。阿西是一个建筑队,集合适合存储对象 历史的列表。数据可以重复,按照插入的顺序排序,头尾都可以插入,可以用来做消息队列, stat 即可。数据不重复但是无序,可以做序程和求共同好友等。 acca 有序即可,数据不重复且有序。每个数据给定一个分数,自动按照分数排序,可以做排行和榜单。每日一问, ready 时还支持哪些数据类型?

哈喽,大家好,我是专注加瓦干货分享的灰灰,昨天晚上收到一个粉丝的私信,他说自己在某些二面的时候问到了这个问题,也根据自己的理解回答了。当面试官明显觉得不满意,希望能听听我的回答,那我就和大家分享一下这道题。另外,我还准备了一份加瓦程序员学习路线图, 从技能提升、代码实战到架构思维构建都有详细的学习规划,有需要的小伙伴可以在评论区置顶领取。哈西是用来去保存结构化数据的, 虽然 steam 也可以通过节省的方式来保存结构化数据,但是相比于 steam 来讲,有以下几个优势。 第一个,可以更加高效的查询单个字段,比如想查询里面的某个字段,不需要经过阶层解析,直接可以基于字段去查询,并且能够进行操作。第二,基于单个字段的更改更加方便,并且能够 保证某个字段更改操作的一个原则性。所以啊,如果业务场景有很多基于单个字段去进行变更的场景,哈西数据类型比思韵类型更加的合适。相反,如果要查询对象的大部分字段,并且不需要对里面的单个字段进行变更的词骏类型比哈西类型更加的合适, 因为他能够去减少跟 redis 服务的一个交互次数。以上呢,就是我对这个问题的理解,如果对你有帮助的话,记得帮我一键三连,我是灰灰,我们下期再见!