hash函数

hash

别等时光非礼了梦想. 提交于 2020-03-04 00:01:56
Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 Hash算法可以将一个数据转换为一个标志,这个标志和源数据的每一个字节都有十分紧密的关系。Hash算法还具有一个特点,就是很难找到逆向规律。 Hash算法是一个广义的算法,也可以认为是一种思想,使用Hash算法可以提高存储空间的利用率,可以提高数据的查询效率,也可以做数字签名来保障数据传递的安全性。所以Hash算法被广泛地应用在互联网应用中。 [1] Hash算法也被称为散列算法,Hash算法虽然被称为算法,但实际上它更像是一种思想。Hash算法没有一个固定的公式,只要符合散列思想的算法都可以被称为是Hash算法。 常用HASH函数 散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位。常用Hash函数有: 1.直接寻址法。取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数) 2. 数字分析法

HashMap分析

眉间皱痕 提交于 2020-03-03 16:51:36
目录 存储结构 初始化 put resize 树化 get 为什么HashMap中equals()和hashCode()要同时重写? 为何HashMap的数组长度一定是2的次幂? 线程安全 参考 存储结构 JDK1.8前是数组+链表,JDK1.8之后是数组+链表+红黑树。本文分析基于JDK1.8源代码。 HashMap的基础结构是Node ,它存着hash、键值对,Node类型的指针next。 主干是桶数组,链表bin用于解决hash冲突,当链表的Node超过阈值(8),执行树化操作,将该链表改造成红黑树。 图片来源:Java核心技术36讲 初始化 HashMap有4个构造器,其他构造器如果用户没有传入initialCapacity (容量)和loadFactor(负载因子)这两个参数, 会使用默认值 ,initialCapacity默认为16,loadFactory默认为0.75。 基于lazy-load原则,主干数组table的内存空间分配不在初始化中,而是在put中。 public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " +

HashMap O(1) 复杂度的分析

六月ゝ 毕业季﹏ 提交于 2020-03-02 11:38:27
**C++**在使用STL时,经常混淆的几个数据结构, map,hash Map,unordered_map 事实上,三个容器,有着比较大的区别. Map 内部数据的组织,基于红黑树实现,红黑树具有自动排序的功能,因此map内部所有的数据,在任何时候,都是有序的。 所以复杂度为 O(LogN) Hash map 基于哈希表,数据插入和查找的时间复杂度很低,几乎是常数时间,而代价是消耗比较多的内存。底层实现上,使用一个下标范围比较大的数组来存储元素,形成很多的桶,利用hash函数对key进行映射到不同区域(桶)进行保存。 插入 得到key, 通过hash函数得到hash值 根据hash值 找到对应的桶号(区域), hash值对(桶数)求模 存放key和value 在对应桶内 取值 分四步: 判断key,根据key算出索引。 根据索引获得索引位置所对应的键值对链表。 遍历键值对链表(当每个桶内只有一个元素时,查找时只进行一次比较),根据key找到对应的Entry键值对。 拿到value。 分析: 以上四步要保证HashMap的时间复杂度O(1),需要保证每一步都是O(1),现在看起来就第三步对链表的循环的时间复杂度影响最大,链表查找的时间复杂度为O(n),与链表长度有关。我们要保证那个链表长度为1,才可以说时间复杂度能满足O(1)。但这么说来只有那个hash算法尽量减少冲突

ConcurrentHashMap源码解析

北慕城南 提交于 2020-03-02 10:33:41
ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现 ConcurrentHashMap在并发编程的场景中使用频率非常之高,本文就来分析下ConcurrentHashMap的实现原理,并对其实现原理进行分析(JDK1.7). ConcurrentHashMap实现原理   众所周知,哈希表是中非常高效,复杂度为O(1)的数据结构,在Java开发中,我们最常见到最频繁使用的就是HashMap和HashTable,但是在线程竞争激烈的并发场景中使用都不够合理。    HashMap :先说HashMap,HashMap是 线程不安全 的,在并发环境下,可能会形成 环状链表 (扩容时可能造成,具体原因自行百度google或查看源码分析),导致get操作时,cpu空转,所以,在并发环境中使用HashMap是非常危险的。    HashTable : HashTable和HashMap的实现原理几乎一样,差别无非是 1.HashTable不允许key和value为null;2.HashTable是线程安全的。 但是HashTable线程安全的策略实现代价却太大了,简单粗暴,get/put所有相关操作都是synchronized的,这相当于给整个哈希表加了一把 大锁 ,多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞

HashTable源码解析

回眸只為那壹抹淺笑 提交于 2020-03-02 10:32:00
Hashtable 简介 和HashMap一样,Hashtable 也是一个 散列表 ,它存储的内容是 键值对(key-value)映射 。 Hashtable 继承于Dictionary ,实现了Map、Cloneable、java.io.Serializable接口。 Hashtable 的函数都是 同步的 ,这意味着它是线程安全的。它的key、value都不可以为null。此外,Hashtable中的映射不是有序的。 此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。 为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。 Hashtable 的实例有两个参数影响其性能: 初始容量 和 加载因子 。容量 是哈希表中桶 的数量,初始容量 就是哈希表创建时的容量。 注意,哈希表的状态为 open:在发生“哈希冲突”的情况下,单个桶会存储多个条目,这些条目必须按顺序搜索。 加载因子 是对哈希表在其容量自动增加之前可以达到多满的一个尺度。初始容量和加载因子这两个参数只是对该实现的提示。 关于何时以及是否调用 rehash 方法的具体细节则依赖于该实现。 通常, 默认加载因子是 0.75 , 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销, 但同时也增加了查找某个条目的时间

【翻译/介绍】jump Consistent hash:零内存消耗,均匀快速简洁,来自Google

百般思念 提交于 2020-03-02 02:11:28
简介 jump consistent hash是一种一致性哈希算法, 此算法 零内存消耗 , 均匀分配 , 快速 ,并且 只有5行代码 。 此算法适合使用在分shard的分布式存储系统中 。 此算法的作者是 Google 的 John Lamping 和 Eric Veach,论文原文在 http://arxiv.org/ftp/arxiv/papers/1406/1406.2294.pdf 完整代码: JumpConsistentHash 1 2 3 4 5 6 7 8 9 int32_t JumpConsistentHash ( uint64_t key , int32_t num_buckets ) { int64_t b = - 1 , j = 0 ; while ( j < num_buckets ) { b = j ; key = key * 2862933555777941757ULL + 1 ; j = ( b + 1 ) * ( double ( 1LL << 31 ) / double (( key >> 33 ) + 1 )); } return b ; } 输入是一个64位的key,和桶的数量(一般对应服务器的数量),输出是一个桶的编号。 原理解释: 下面byron根据论文的推导过程,做个翻译: jump consistent hash的设计目标是: 平衡性

PHP_框架储备资料

自古美人都是妖i 提交于 2020-03-01 14:33:29
spl_object_hash($this); //返回指定对象的hash id,字符串,对于每个对象它都是唯一的,并且对同一个对象它总是相同。 debug_print_backtrace() debug_backtrace() //只是前者直接打印出来了而已。查看整个程序的调用栈,用来查看瞬间函数调用栈,方便查错。 is_callable() 验证变量的内容能否作为函数调用。 这可以检查包含有效函数名的变量,或者一个数组,包含了正确编码的对象以及函数名。 is_callable($object, true, $method_name) is_callable('parent::__construct') is_callable(array('User', 'showAge')) 来源: oschina 链接: https://my.oschina.net/u/1425152/blog/637223

海量数据处理:十道面试题与十个海量数据处理方法总结

谁说我不能喝 提交于 2020-02-29 16:44:19
1、海量日志数据,提取出某日访问百度次数最多的那个IP。 首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。同样可以采用映射的方法,比如模1000,把整个大文件映射为1000个小文件,再找出每个小文中出现频率最大的IP(可以采用hash_map进行频率统计,然后再找出频率最大的几个)及相应的频率。然后再在这1000个最大的IP中,找出那个频率最大的IP,即为所求。 或者如下阐述(雪域之鹰): 算法思想:分而治之+Hash 1.IP地址最多有2^32=4G种取值情况,所以不能完全加载到内存中处理; 2.可以考虑采用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址; 3.对于每一个小文件,可以构建一个IP为key,出现次数为value的Hash map,同时记录当前出现次数最多的那个IP地址; 4.可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的IP; 2、搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。 假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个

[转]海量数据处理的面试题的方法总结

喜你入骨 提交于 2020-02-29 16:36:20
处理海量数据问题,无非就是: 分而治之/hash映射 + hash统计 + 堆/快速/归并排序; Bloom filter/Bitmap; Trie树/数据库/倒排索引; 外排序; 分布式处理之hadoop/mapreduce。 本文接下来的部分,便针对这5种方法模式结合对应的海量数据处理面试题分别具体阐述。 密匙一、分而治之/hash映射 + hash统计 + 堆/快速/归并排序 1、海量日志数据,提取出某日访问百度次数最多的那个IP。 既然是海量数据处理,那么可想而知,给我们的数据那就一定是海量的。针对这个数据的海量,我们如何着手呢?对的,无非就是分而治之/hash映射 + hash统计 + 堆/快速/归并排序,说白了,就是先映射,而后统计,最后排序: 分而治之/hash映射:针对数据太大,内存受限,智能是:把大文件化成(取模映射)小文件,即16字方针:大而化小,各个击破,缩小规模,逐个解决 hash统计:当大文件转化了小文件,那么我们便可以采用常规的hashmap(ip,value)来进行频率统计。 堆/快速排序:统计完了之后,便进行排序(可采取堆排序),得到次数最多的IP。 具体而论,则是: “首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。同样可以采用映射的方法,比如模1000

MySQL AHI 实现解析

瘦欲@ 提交于 2020-02-29 13:00:08
版权声明:本文由 musazhang 原创文章,转载请注明出处: 文章原文链接: https://www.qcloud.com/community/article/904925001482373849 来源:腾云阁 https://www.qcloud.com/community 前言     MySQL 定位用户记录的过程可以描述为:打开索引 -> 根据索引键值逐层查找 B+ 树 branch 结点 -> 定位到叶子结点,将 cursor 定位到满足条件的 rec 上;如果树高为 N, 则需要读取索引树上的 N 个结点并进行比较,如果 buffer_pool 较小,则大量的操作都会在 pread 上,用户响应时间变长;另外,MySQL中 Server 层与 Engine 之间的是以 row 为单位进行交互的,engine 将记录返回给 server 层,server 层对 engine 的行数据进行相应的计算,然后缓存或发送至客户端,为了减少交互过程所需要的时间,MySQL 做了两个优化: 如果同一个查询语句连续取出了 MYSQL_FETCH_CACHE_THRESHOLD(4) 条记录,则会调用函数 row_sel_enqueue_cache_row_for_mysql 将 MYSQL_FETCH_CACHE_SIZE(8) 记录缓存至 prebuilt->fetch