hash

HashMap底层源码剖析

十年热恋 提交于 2020-03-17 19:17:23
HashMap底层源码剖析 数组+单向链表+红黑树 数组:    数组每一项都是一个链表,其实就是数组和链表的结合体 单向链表:    当法神hash碰撞时,首先会找到数组对应位置,然后1.8采用尾插入法(1.7采用头插入法),形成一个单项链表结构 红黑树:   当数组中每项的链表长度大于8时,会转换为红黑树 什么是hash碰撞?解决方案 hash碰撞:    不同的key可能会产生相同的hash值; 方案:    链表发,再哈希法; hashMap中采用链表发,在ConcurrentHashMap中采用哈希法; 为什么采用红黑树,比如二叉查找树,并且为什么临界值为8    二叉查找树在特殊情况下也会变为线性结构,和原来链表有共同的问题,节点太深,查找性能慢 使用红黑树主要用于提升查询速度,红黑树是平衡二叉树的一种,插入新的数据都会通过左旋,右旋,变色等操作来保持平衡,解决节点的深度问题   当数据较少时,采用链表要比红黑树效率高,因为平衡二叉树保持平衡需要耗费资源,那么前期数据较少时采用链表,当数据到达一定的界限后,再采用 红黑树,可以加快数据查询速度,官方测试8为性能最优 put()底层源码剖析 public V put(K key, V value) { return putVal(hash(key), key, value, false, true);     } /**

HashMap底层源码与实现逻辑

依然范特西╮ 提交于 2020-03-17 19:02:20
ConcurrentHashMap性能高于HashTable,都能够完成线程安全操作, Hashtable中线程安全使用synchronized同步方法进行加锁操作,如果当前一个线程正在访问该集合,其他线程是无法进行访问的,需要进行等待 反之ConcurrentHashMap当中采用分段锁机制 JDK1.7和JDK1.8底层实现的区别 JDK1.8版本之前,ConcurrentHashMap使用分段锁技术,将数据分成一段一段的进行村粗,每一个数据段配置一把锁Segment(继承ReentrantLock) 底层采用:Segment+HashEntry 当数据添加时,根据key值找到Segment对应的数据段,然后匹配数据块,采用链表方式进行存储 1.1JDK1.7底层实现 在JDK1.7版本中,ConcurrentHashMap的数据结构是由一个Segment数组和多个HashEntry组成: Segment数组的意义就是将一个大的table分割成多个小的table来进行加锁,也就是上面的提到的锁分离技术,而每一个Segment元素存储的是HashEntry数组+链表,这个和HashMap的数据存储结构一样 1.2JDK1.8底层实现 JDK1.8的实现已经摒弃了Segment的概念,而是直接用Node数组+链表+红黑树的数据结构来实现

What pool of characters do MD5 and SHA have?

时光怂恿深爱的人放手 提交于 2020-03-17 10:02:20
问题 Does MD5 and SHA only contain alphanumeric characters? (i.e., from A to Z and 0 to 9, or do they exclude some characters?) 回答1: MD5 and SHA hashes in raw form are binary, however their common representation is a hex-encoded string, which contains characters [a-fA-F0-9] . So if this is what you meant, then characters G-Z, g-z are "excluded". Another, less common, representation is Base64 encoding [0-9a-zA-Z+/]. 来源: https://stackoverflow.com/questions/12618321/what-pool-of-characters-do-md5-and

vue-router 结合源码分析原理

末鹿安然 提交于 2020-03-17 04:08:20
路由响应过程: 浏览器发出请求 服务器监听到num端口(或443)有请求过来,并解析url路径 根据服务器的路由配置,返回相应信息(可以是 html 字串,也可以是 json 数据,图片等) 浏览器根据数据包的 Content-Type 来决定如何解析数据 一般的vueRouter的代码模式是这样的: let router = new Router({ mode: 'history|hash|abstract', routes: [ { // 默认页 path: '*', redirect: to => { return '/' }, meta: { status: *** } }, { path: '/', name: '****', component: ****, meta: { status: *** } }, ], beforeEnter: (to, from, next) => {}), scrollBehavior: fun() }) 可以看到的是使用Router这个类进行实例化【new Router(options)】 在使用vueRouter的时候,我们会在项目中使用 Vue.use(Router) 安装,它会加载VueRouter中的 install 方法使得所有组件都可以使用router的实例( this.$router/this.$route )

加密学详细介绍

孤街醉人 提交于 2020-03-17 01:15:06
加密学介绍  密码锁:是对里面贵重东西进行加密  钥匙:对加密的锁进行解密  计算机只能识别0和1两个数字 将现在世界中的东西映射为比特序列的操作称为编码 m -> 01101101 i -> 01101001 d -> 01100100 n -> 01101110 i -> 01101001 g -> 01100111 h -> 01101000 t -> 01110100  异或运算 异或运算的举例 0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 1 = 0 结论:可以根据B和C推到出A 0 1 0 0 1 1 0 0 A 1 0 1 0 1 0 1 0 B 1 1 1 0 0 1 1 0 C  加密和解密的初始模型 对称加密  对称加密 又称为共享密钥加密,它使用同一个密钥对数据进行加密和解密  适合于加密大数据  算法:DES(56bit) 3DES(168bit) AES(比较多) 工作原理  发送方: 明文数据 ------------对称算法(DES-56bit)-----------得到密文数据 得到56bit的密钥  接收方: 提前获知56bit密钥-------解密密文数据--------明文数据 优点  速度快 适合对大数据进行加密  安全  紧凑 加密1G的数据 加密出来之后 密文数据大概1G左右

哈希表结构 笔记

ⅰ亾dé卋堺 提交于 2020-03-16 19:50:33
Hash-Table (空间换时间) 利用哈希函数生成对应的index(o(1); 利用生成的index(O(1)) 来操作指定位置的元素 O(1) 时间复杂度 Hash 冲突: 两个不同的key ,经过哈希函数计算出相同的结果解决办法: 1) 开放定址法:按照一定规则向其他地址探测,直到遇到空桶 2) 再Hash法 :利用另一个Hash函数再次计算,看是否与第一个相 3) 链地址法:通过链表将同一index的元素串起来 JDK 1.8 解决Hash冲突: 默认单向链表将元素串起来 在添加元素时有可能将单向链表转为红黑树(当哈希表容量大于64 或者链表节点数大于8) 当红黑树的节点少于一定数量后,也会转成单向链表 表为什么使用单链表? 1.挨个比较key 相同就覆盖掉 不同就尾插 2. 每次从头开始比较 3. 节省空间 比双链表少一个指针 Hash 函数: 先生成key 的哈希值 再让key 的哈希值与数组的大小进行相关的计算 生成索引值(Hash(key)要小于数组) Hash(key)%table.length 为了提高效率 ,可以将 % 更换为 & (前提是将数组的长度设计为2En) Hash(key)&(table.length-1) ——》 按照此方法得出的数字必然小于table.length (2En -1 保证数字全部是1) 良好的哈希函数: 算出的索引分布比较均匀

深入python的set和dict

て烟熏妆下的殇ゞ 提交于 2020-03-16 07:56:57
一. collections中的abc    和list(Sequence)相似,都继承于Collection,添加了一些方法 二. dict的常见用法    (setdefault,defaultdict,__missing__方法)   1.copy():        from collections.abc import MutableMapping a = {'LYQ1':{'SWPU':'软件工程'}, 'LYQ2':{'SWPU2':'软件工程2'}} #这是浅拷贝,指向的是同一值,修改一个,另一个也会修改 b=a.copy() b['LYQ1']['SWPU']='我是浅拷贝' print(b) print(a) 注:copy方法是浅拷贝:深拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用 a = {'LYQ1':{'SWPU':'软件工程'}, 'LYQ2':{'SWPU2':'软件工程2'}} import copy #深拷贝,指向不同的对象 deep_b=copy.deepcopy(a) deep_b['LYQ1']['SWPU']='我是深拷贝' print(deep_b) print(a)   2.fromkeys(): #把一个可迭代对象转换为dict,{'SWPU':'软件工程'}为默认值 my_list=['Stu1','Stu2'] my

HashMap实现原理分析

三世轮回 提交于 2020-03-16 04:07:43
1 HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找 时间复杂度小,为O(1); 数组的特点是: 寻址容易,插入和删除困难; 链表 链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。 链表 的特点是: 寻址困难,插入和删除容易。 哈希表 那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表。哈希表( (Hash table ) 既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。 从上图我们可以发现哈希表是由 数组+链表 组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。那么这些元素是按照什么样的规则存储到数组中呢。一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。   HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。这可能让我们很不解,一个线性的数组怎么实现按键值对来存取数据呢

Map-HashMap

[亡魂溺海] 提交于 2020-03-15 18:03:04
一、HashMap数据结构   JDK 1.7 采用数组 + 链表实现。   JDK 1.8 采用数组 + 链表 + 红黑树实现。链表采用内部类Node节点实现。红黑树采用内部类TreeNode节点实现。 二、重要参数  // 1. 容量(capacity): 必须是2的幂 & <最大容量(2的30次方),默认是16 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;  // 最大容量 = 2的30次方(若传入的容量过大,将被最大值替换) static final int MAXIMUM_CAPACITY = 1 << 30; // 2. 加载因子(Load factor):HashMap在其容量自动增加前可达到多满的一种尺度 // 加载因子过大则容器内可添加更多元素,空间效率高,但是容易导致哈希冲突。反之反之 final float loadFactor; // 实际加载因子 static final float DEFAULT_LOAD_FACTOR = 0.75f; // 默认加载因子 = 0.75 h // 3. 扩容阈值 = 容量 x 加载因子,哈希表的大小 ≥ 扩容阈值时,就会扩容哈希表 int threshold; // 4. 其他 transient Node<K,V>[] table; //

Redis 基础数据结构

僤鯓⒐⒋嵵緔 提交于 2020-03-15 01:03:50
string (字符串) 是一种键值对的数据结构,定义一个唯一的key值来获取相应的value数据。 > set name codehole OK > get name "codehole" > exists name (integer) 1 > del name (integer) 1 > get name (nil) 批量操作 > set name1 codehole OK > set name2 holycoder OK > mget name1 name2 name3 # 返回一个列表 1) "codehole" 2) "holycoder" 3) (nil) > mset name1 boy name2 girl name3 unknown > mget name1 name2 name3 1) "boy" 2) "girl" 3) "unknown" 可以对 key 设置过期时间,到点自动删除,这个功能常用来控制缓存的失效时间。 > set name codehole > get name "codehole" > expire name 5 # 5s 后过期 ... # wait for 5s > get name (nil) > setex name 5 codehole # 5s 后过期,等价于 set+expire > get name "codehole" .