遍历

因为不会Redis的scan命令,我被开除了

。_饼干妹妹 提交于 2020-03-04 19:50:28
那个深夜,我登上了公司的服务器,在Redis 命令行里敲入 keys* 后,线上开始报警,服务瞬间被卡死,我只能举起双手,焦急地等待几千万key被慢慢扫描,束手无策万念俱灰的时候,我收到了leader的短信:你明天不用来上班了。 虽然上面是我的臆想,事实上很多公司的运维也会禁用这些命令,来防止开发出错。但我在群里依然看到有同学在问“为什么Redis不能用 keys?我觉得挺好的呀”时,为了不让上面的情况发生,我决定写下这篇文章。 如何才能优雅地遍历Redis?作为一种可以称为数据库的组件,这是多么理所因当的要求。终于,Redis在2.8.0版本新增了众望所归的 scan操作,从此再也不用担心敲入了keys*, 然后等着定时炸弹的引爆。 学会使用 scan并不困难,那么问题又来了,它是如何遍历的?当遍历过程中加入了新的key,当遍历过程中发生了扩容,Redis是如何解决的?抱着深入学习的态度,以及为了能够将来在面试官面前谈笑风生,让我们一起来借此探索Redis的设计原理。 引言 开门见山,首先让我们来总结一下 scan的优缺点。 优点: 提供键空间的遍历操作,支持游标,复杂度O(1), 整体遍历一遍只需要O(N) 提供结果模式匹配 支持一次返回的数据条数设置,但仅仅是个hints,有时候返回更多 弱状态,所有状态只需要客户端需要维护一个游标 缺点: 无法提供完整的快照遍历

每天AC系列(十二):K个一组翻转链表

我的未来我决定 提交于 2020-03-04 19:09:26
1 题目 LeetCode第25题 ,每K个节点一组进行翻转,剩下不足K个的保留原状. 2 直接翻转 将链表分成三部分,已翻转,待翻转,未翻转三部分: 首先,用一个指针t表示要插入的位置的前驱,一边把head移动k遍,一边插入在t后面(下图假设k=3): int i=0; for(;i<k && head != null;++i) { temp = head.next; head.next = t.next; t.next = head; head = temp; } 直接插在t的后面,一轮循环之后,移动t与head. t的新位置为未插入head之前的head的位置,因此在插入之前把head的位置保存下来,直接使t移动到该位置,head的位置为自然移动到的位置,不需改变。 ListNode nextTPosition = head; ListNode temp; int i=0; for(;i<k && head != null;++i) { temp = head.next; head.next = t.next; t.next = head; head = temp; } if(i == k) t = nextTPosition; 接着再翻转,到达7后,7不需要翻转,因为剩下的节点数不足: 这时就需要i发挥作用了,i表示已翻转的节点的值,因为只是一次遍历,每遍历k次便翻转k次

秒懂闭包

你说的曾经没有我的故事 提交于 2020-03-04 18:38:47
闭包是针对嵌套函提出的概念。 闭包=函数+引用环境 闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。 闭包的作用是加强模块化,让相同的逻辑可以加入到各种逻辑环境中。 比如我们要计算一个数组中所有数字的和,这只需要循环遍历数组,把遍历到的数字加起来就行了。如果现在要计算所有元素的积呢?要打印所有的元素呢?解决这些问题都要对数组进行遍历,如果是在不支持闭包的语言中,我们不得不一次又一次重复写循环语句。而在支持闭包的语言中识是不必要的。 来源: CSDN 作者: llwgl 链接: https://blog.csdn.net/llwgl/article/details/104652740

Python——一些特殊的变量

爷,独闯天下 提交于 2020-03-04 16:28:57
如果你学习过java编程,那么这里你非常容易理解 知识点回顾 Python 中数据类型可以分为 数字型 和 非数字型 数字型 整型 ( int ) 浮点型( float ) 布尔型( bool ) 真 True 非 0 数 —— 非零即真 假 False 0 复数型 ( complex ) 主要用于科学计算,例如:平面场问题、波动问题、电感电容等问题 非数字型 字符串 列表 元组 字典 在 Python 中,所有 非数字型变量 都支持以下特点: 都是一个 序列 sequence ,也可以理解为 容器 取值 [] 遍历 for in 计算长度 、 最大/最小值 、 比较 、 删除 链接 + 和 重复 * 切片 01. 列表 1.1 列表的定义 List (列表) 是 Python 中使用 最频繁 的数据类型,在其他语言中通常叫做 数组 专门用于存储 一串 信息 列表用 [] 定义, 数据 之间使用 , 分隔 列表的 索引 从 0 开始 索引 就是数据在 列表 中的位置编号, 索引 又可以被称为 下标 注意:从列表中取值时,如果 超出索引范围 ,程序会报错 name_list = ["zhangsan", "lisi", "wangwu"] 1.2 列表常用操作 在 ipython3 中定义一个 列表 ,例如: name_list = [] 输入 name_list. 按下 TAB 键

链表的创建、遍历、删除、插入和清空

十年热恋 提交于 2020-03-04 16:19:25
一、链表的概念   链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 二、链表和数组的区别: 1、数组静态分配内存,链表动态分配内存。 2、数组在内存中是连续的,链表是不连续的。 3、数组利用下标定位,查找的时间复杂度是O(1),链表通过遍历定位元素,查找的时间复杂度是O(N)。 4、数组插入和删除需要移动其他元素,时间复杂度是O(N),链表的插入或删除不需要移动其他元素,时间复杂度是O(1)。 数组的优点 1、随机访问性比较强,可以通过下标进行快速定位。 2、查找速度快 数组的缺点 1、插入和删除的效率低,需要移动其他元素。 2、会造成内存的浪费,因为内存是连续的,所以在申请数组的时候就必须规定七内存的大小,如果不合适,就会造成内存的浪费。 3、内存空间要求高,创建一个数组,必须要有足够的连续内存空间。 4、数组的大小是固定的,在创建数组的时候就已经规定好,不能动态拓展。 链表的优点 1、插入和删除的效率高,只需要改变指针的指向就可以进行插入和删除。 2、内存利用率高,不会浪费内存,可以使用内存中细小的不连续的空间,只有在需要的时候才去创建空间。大小不固定,拓展很灵活。 链表的缺点 查找的效率低,因为链表是从第一个节点向后遍历查找。 单链表和双链表 三、链表环问题 判断是否有环    定义一个快指针和一个慢指针

04-字符串序列的转换

瘦欲@ 提交于 2020-03-04 14:38:19
2020年2月 TapTap × 心动网络的一个笔试题,原题记不太清了,只能回忆一下了。 题目回忆 给定两个字符串str1和str2,拿str1 = “asd”, str2 = “dsa” 举例。 把 str1的末尾字符 取下,放到栈中,这个操作记为 E ; 判断栈顶元素是否与 str2 的首字符 相同,如果相同,那么栈顶元素出栈,这个操作记为 D 。 现在给定任意的两个字符串,需要判断字符串1能否通过合理的E、D操作得到字符串2,并将E、D操作序列输出。 规定每个字符串中 没有相同的字符 ,每个字符都是唯一的。 样例 1 input : asd dsa output : EDEDED 样例 2 : input : qwert twerq output : EDEEEDDDED 解题思路 设置遍历下标index用于顺序遍历字符串2,以便进行判等操作; 逆序遍历字符串1进行入栈操作,每次入栈后,在结果字符串中追加 E 操作; 每次入栈之后,借助while循环,对栈顶元素和字符串2当前的首字符进行判断,如果两者相等,那么栈顶元素出栈,index后移,同时在结果字符串中追加 D 操作,这里必须用while循环一直判断到 栈空 或者 栈顶元素和字符串2首字符不相等 为止,单纯的if判断一次是不能解决问题的; 当字符串1遍历结束之后, 若栈不空 ,对栈内元素进行遍历,思路与步骤3大致相同

Elastic-Job原理

廉价感情. 提交于 2020-03-04 12:33:09
概述 Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。 Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。 功能列表 分布式调度协调 弹性扩容缩容 失效转移 错过执行作业重触发 作业分片一致性,保证同一分片在分布式环境中仅一个执行实例 自诊断并修复分布式不稳定造成的问题 支持并行调度 支持作业生命周期操作 丰富的作业类型 Spring整合以及命名空间提供 运维平台 基本概念 1. 分片概念 任务的分布式执行,需要将一个任务拆分为多个独立的任务项,然后由分布式的服务器分别执行某一个或几个分片项。 例如:有一个遍历数据库某张表的作业,现有2台服务器。为了快速的执行作业,那么每台服务器应执行作业的50%。 为满足此需求,可将作业分成2片,每台服务器执行1片。作业遍历数据的逻辑应为:服务器A遍历ID以奇数结尾的数据;服务器B遍历ID以偶数结尾的数据。 如果分成10片,则作业遍历数据的逻辑应为:每片分到的分片项应为ID%10,而服务器A被分配到分片项0,1,2,3,4;服务器B被分配到分片项5,6,7,8,9,直接的结果就是服务器A遍历ID以0-4结尾的数据;服务器B遍历ID以5-9结尾的数据。 2. 分片项与业务处理解耦 Elastic

排序算法之冒泡排序

回眸只為那壹抹淺笑 提交于 2020-03-04 11:38:12
排序算法之冒泡排序 分析思路 :冒泡排序,顾名思义就是像冒气泡一样,可以从前冒到后,也可以从后冒到前。这里以从后冒到前,从小到大排序举例:从最后一个值开始,不断将其与前一个值进行比较,如果后面的值比前面的值要小,那就进行交换,这样遍历一次之后,序列第一个位置就已经是最小的值了,如此循环,O(n2)之后就可以全部排好序。 编程思路 : 顺序存储:如果序列为数组,我们可以采用两重for循环。第一重for循环用于记录未排好序序列的起点,第二重for循环用于遍历、比较和交换。 链式存储:如果序列为链表,我们可以采用双指针。第一个指针用于记录未排好序子链的起点,第二个指针用于遍历、比较和交换。(链式存储只能从前冒到后) 具体代码 : 顺序存储 void Emit_Bubble_Sort(int array[],int n) { for (int i = 0; i < n; i++) { for (int j = n-1; j > 0; j--) { if (array[j] < array[j - 1]) { int temp = array[j]; array[j] = array[j - 1]; array[j - 1] = temp; } } } } 链式存储 void Emit_Bubble_Sort(Node *Head) { Node *p=Head->next,*q=Head-

java中遍历Map的方法

女生的网名这么多〃 提交于 2020-03-04 11:18:43
//第一种:普遍使用,二次取值 System.out.println("通过Map.keySet遍历key和value:"); for (String key : map.keySet()) { System.out.println("key= "+ key + " and value= " + map.get(key)); } //第二种 System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //第三种:推荐,尤其是容量大时 System.out.println("通过Map.entrySet遍历key和value"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key=

遍历map几种方式及应用

谁说我不能喝 提交于 2020-03-04 11:18:22
Map<String, String> map = new HashMap<String, String>(); map.put("1", "value1"); map.put("2", "value2"); map.put("3", "value3"); //第一种:普遍使用,二次取值 System.out.println("通过Map.keySet遍历key和value:"); for (String key : map.keySet()) { System.out.println("key= "+ key + " and value= " + map.get(key)); } //第二种 System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //第三种:推荐,尤其是容量大时