zoukankan      html  css  js  c++  java
  • Hash

    HASH http://baike.baidu.com/view/20089.htm

    有些时候,先计算Key的值,比如Objet中的hashcode返回的是一个Key.  得到这个key值然后可以利用hash算法H(Key)会形成一个散列表(类似于hashmap里面的列表).每个H(Key)的值对应一个散列地址. 一个散列地址指向内存中一段连续的地址集(类似于hashmap里面的链表). 如果H(Key1)与H(Key2)得到相同的散列地址,那么具有相同函数值的关键字对该散列函数来说称做同义词。Key1,Key2对于H(Key)就是同义词.当为同义词时,Key1,Key2会放到用同一个散列地址标识的"桶"里. Key1,Key2会分别存储到地址集中(hashmap中,table[index]表示已经找到的元素需要存储的位置。先判断该位置上有没有元素(这个元素是HashMap内部定义的一个类Entity,基本结构它包含三个类,key,value和指向下一个Entity的next),没有的话就创建一个Entity<K,V>对象,在 table[index]位置上插入,这样插入结束;如果有的话,通过链表的遍历方式去逐个遍历,看看有没有已经存在的key,有的话用新的value替换老的value;如果没有,则在table[index]插入该Entity,把原来在table[index]位置上的Entity赋值给新的 Entity的next,这样插入结束).

    Hash常用算法
    1)hash算法最常用的是%.
    H(key) = key MOD p, p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词(负载均衡还故意用到同义词)。
    2)hashmap里面使用了Key & (length-1)得到一个小于length的值做为数组的index.


    Hash的应用:
    1)数据库的水平分区,分表使用的最多的也是基于%的hash. Key是userid或者accountid, 这样可以保证一个user或account的所有操作的数据都可以从一个分区中取出. 对于%算法,动态扩展的例子:
    userid为0~20W的数据使用userid % 4;
    userid为20~40W的数据可以使用userid % 4+4, 散列函数改变,并不会导致之前0~20W的数据重新计算. 新的数据也不会散列到最初的db server上. 而是到了新加的4台db server上.  不会增加旧的server的负担.
    2)缓存
    最常用的仍然是%做为散列函数.但是当server发生增减,根据新的p值,之前缓存的内容就会失效,而从对后端服务器产生冲击.
    此时的解决办法就是一致性hash. key与cache采用[一致的hash算法],然后按照[顺时针]去找相应的cache节点,按照顺时针去划分.

    3)hash就是找到一种数据内容和数据存放地址之间的映射关系
    4)java中数据量太大,不推荐使用list,因为遍历list此时比较耗时, 替换的方案就是使用hashmap. 此时通过key的hashcode去定位value要比遍历快得多.

  • 相关阅读:
    使用 requests 维持会话
    使用 requests 发送 POST 请求
    使用 requests 发送 GET 请求
    requests 安装
    使用 urllib 分析 Robots 协议
    使用 urllib 解析 URL 链接
    使用 urllib 处理 HTTP 异常
    使用 urllib 处理 Cookies 信息
    使用 urllib 设置代理服务
    按单生产程序发布
  • 原文地址:https://www.cnblogs.com/highriver/p/2140411.html
Copyright © 2011-2022 走看看