哈希表

编程面试之前你应该知晓的八大数据结构

一曲冷凌霜 提交于 2019-11-26 12:10:35
https://baijiahao.baidu.com/s?id=1609200503642486098&wfr=spider&for=pc https://www.cnblogs.com/wanghuaijun/p/7302303.html 什么是数据结构? 简单地说,数据结构是以某种特定的布局方式存储数据的容器。这种“布局方式”决定了数据结构对于某些操作是高效的,而对于其他操作则是低效的。首先我们需要理解各种数据结构,才能在处理实际问题时选取最合适的数据结构。 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。 为什么我们需要数据结构? 数据是计算机科学当中最关键的实体,而数据结构则可以将数据以某种组织形式存储,因此,数据结构的价值不言而喻。 无论你以何种方式解决何种问题,你都需要处理数据——无论是涉及员工薪水、股票价格、购物清单,还是只是简单的电话簿问题。 数据需要根据不同的场景,按照特定的格式进行存储。有很多数据结构能够满足以不同格式存储数据的需求。 常见的数据结构 首先列出一些最常见的数据结构,我们将逐一说明: ============================ 八大数据结构简单描述 ===========================================

HashMap解析

僤鯓⒐⒋嵵緔 提交于 2019-11-26 10:01:55
HashMap的底层是哈希表,关于哈希表的存储原理可以看我博客《哈希表的存储原理》。 关于HashMap存储 自定义对象 的知识可以看我博客《HashSet解析》,方式是相同的。 HashMap常用方法的运用与 遍历map集合 的三种方式: public class TestHashMap { public static void main(String[] args) { HashMap hm = new HashMap(); hm.put("hello",250); hm.put("hello",350);//键重复时,将进行值得覆盖 hm.put("java", 360); hm.put(null, null); //HashMap集合只允许有一个空键,可以有多个空值 System.out.println(hm); System.out.println("集合中元素的个数:"+hm.size()); System.out.println("集合是否为空:"+hm.isEmpty()); System.out.println(hm.remove("java"));//这里会先输出值再进行移除 //判断 System.out.println(hm.containsKey("hello")+"\t"+hm.containsValue(100)); System.out

HashMap之get()剖析

流过昼夜 提交于 2019-11-26 09:53:51
上次我们已经剖析了get()方法,这次来看看put()方法。 1.HashMap的get()方法剖析: public V get(Object key) { Node<K,V> e; return (e = getNode(hash(key), key)) == null ? null : e.value; } 可见,也是将key值进行hash()之后,找到对应的桶数组,再调用getNode()进行查找。 final Node<K,V> getNode(int hash, Object key) { Node<K,V>[] tab; Node<K,V> first, e; int n; K k; //若哈希表不为空,并且当前索引位置有元素 if ((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) { //若在一个桶中,并且当前索引位置的key值与要查找的key值相等 //说明找到了,返回该值 if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k)))) return first; //若key值不相同,且还有元素 if ((e = first

Java中的常用类

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-26 09:23:34
1、Object 1.1、 java.lang.Object 1.1.1、Object类 Class Object is the root of the class hierarchy . Every class has Object as a superclass . All objects , including arrays , implement the methods of this class . 1.1.2、构造方法 public Object ( ) { } 1.1.3、实例方法 1.1.3.1、 equals 指示其他某个对象(由参数指定)是否与此对象(当前对象)“相等”。 在 java.lang.Object 类中的 equals 方法的实现过程: public boolean equals ( Object obj ) { return ( this == obj ) ; // 比较 当前对象(this) 和 其它某个对象(obj) 的 地址 } 1.1.3.2、 toString 返回该对象的字符串表示。 在 java.lang.Object 类中的 toString 方法的实现过程: public String toString ( ) { return getClass ( ) . getName ( ) + "@" + Integer .

海量数据处理面试题

江枫思渺然 提交于 2019-11-26 07:39:56
何谓海量数据处理? 所谓海量数据处理,无非就是基于海量数据上的存储、处理、操作。何谓海量,就是数据量太大,所以导致要么是无法在较短时间内迅速解决,要么是数据太大,导致无法一次性装入内存。 那解决办法呢?针对时间,我们可以采用巧妙的算法搭配合适的数据结构,如布隆过滤器/Hash/bit-map/堆/数据库或倒排索引/trie树,针对空间,无非就一个办法:大而化小,分而治之(hash映射),你不是说规模太大嘛,那简单啊,就把规模大化为规模小的,各个击破不就完了嘛。 海量数据处理主要方法: 分而治之-hash映射 + hash统计 + 堆排序/外排序 布隆过滤器 布隆过滤器+分层 哈希函数的性质: 典型的哈希函数都有无限的输入值域。 当给哈希函数传入相同的输入值时,返回值一样,即哈希值一样。 当给哈希函数传入不同的值时,返回值可能一样,也可能不一样。 很多不同的输入之所得到的返回值会均匀的分布在S上,S为输出域–范围固定。这条性质是评判一个哈希函数优劣的关键。 堆排序的注意点: 要找出最大的TopK,要建立最小堆,堆顶元素为最小的,先拿K个数建立最小堆,接下来每拿一个数都和堆顶元素比较,如果比堆顶元素大,则代替堆顶元素,然后对该堆进行凋整,使之成为最小堆。重复操作直到遍历所有数据。 要找出最小的TopK,要建立最大堆,每次与最大堆的堆顶元素比较,小于堆顶元素则代替堆顶元素,然后进行调整

Redis数据结构

拜拜、爱过 提交于 2019-11-26 06:54:39
redisObject Redis存储的数据都使用redisObject来封装,包括string,hash,list,set,zset在内的所有数据类型。 简单来说,就是将key-value封装成对象,key是一个对象,value也是一个对象 typedef struct redisObject { // 对象的类型 unsigned type 4 : ; // 对象的编码格式 unsigned encoding : 4 ; // 指向底层实现数据结构的指针 void * ptr ; //LRU计时时钟 lru:REDIS_LRU_BITS //引用计数器 int refcount ; } robj ; String Redis 的字符串是动态字符串,是可以修改的字符串 SDS struct sdshdr { //记录buf数组中已使用字节的数量 //等于 SDS 保存字符串的长度 int len ; //记录 buf 数组中未使用字节的数量 int free ; //字节数组,用于保存字符串 char buf [ ] ; } 常数复杂度获取字符串长度 对于C语言求字符串长度,需要遍历字符串,对于sds已经记录了当前字符串长度,时间复杂度为O(1) 杜绝缓冲区溢出 C 语言中使用 strcat 函数来进行两个字符串的拼接,一旦没有分配足够长度的内存空间,就会造成缓冲区溢出。对于

找到出现次数最多的数

时光怂恿深爱的人放手 提交于 2019-11-26 05:56:10
题目说明 有一个包含20亿个全是32位整数的大文件,在其中找到出现次数最多的数。 题目要求 内存限制为2GB。 实现思路 想要在很多整数中找到出现次数最多的数,通常的做法是使用哈希表对出现的每 一个数做词频统计,哈希表的key是某一个整数,value是这个数出现的次数。就本题来说,一共有20亿个数,哪怕只是一个数出现了20亿次,用32位的整数也可以表示其出现的次数而不会产生溢出,所以哈希表的key需要占用4B,value也是4B。那么哈希表的一条记录(key,value)需要占用8B。最极端的情况是20亿个数都不同,那么在哈希表中可能需要产生20亿条记录,大约为16GB内存。这样内存会不够用,所以一次性用哈希表统计20亿个数的办法是有很大风险的。 解决办法是把包含20亿个数的大文件用哈希函数分成很多个小文件,根据哈希函数的性质,同一种数不可能被哈希到不同的小文件上。 假设哈希函数设计的足够好,可以将数字近乎平均的散列到每个小文件上。假设散列到8个小文件上,理论上每个文件占用的内存正好是2GB。当然为了更稳妥起见,我们可以分成更多的小文件,比如16个,20个,40个甚至更多。假设我们这里选择散列到 16 个小文件上。 接下来,我们计算得到16个小文件中各自出现次数最多的数,还有各自的次数统计。接下来只要选出这 16 个小文件各自的第一名中谁出现的次数最多即可。

nf_conntrack

ぐ巨炮叔叔 提交于 2019-11-26 03:27:43
(服务器用的阿里云主机,CentOS 7.3,似乎不管内存多少阿里云都把 conntrack_max 设成 65536) 症状 CentOS服务器,负载正常,但请求大量超时,服务器/应用访问日志看不到相关请求记录。 在dmesg或/var/log/messages看到大量以下记录: kernel: nf_conntrack: table full, dropping packet. 原因 服务器访问量大,内核netfilter模块conntrack相关参数配置不合理,导致新连接被drop掉。 详细 nf_conntrack模块在kernel 2.6.15(2006-01-03发布) 被引入,支持ipv4和ipv6,取代只支持ipv4的ip_connktrack,用于跟踪连接的状态,供其他模块使用。 最常见的使用场景是 iptables 的 nat 和 state 模块: nat 根据转发规则修改IP包的源/目标地址,靠nf_conntrack的记录才能让返回的包能路由到发请求的机器。 state 直接用 nf_conntrack 记录的连接状态(NEW/ESTABLISHED/RELATED/INVALID)来匹配防火墙过滤规则。 iptables nf_conntrack用1个哈希表记录已建立的连接,包括其他机器到本机、本机到其他机器、本机到本机(例如 ping 127.0.0

解密比特币的那些核心技术原理

一笑奈何 提交于 2019-11-26 02:04:32
作者:李艳鹏,现任蚂蚁金服高级技术专家,著有《分布式服务架构:原理、设计与实战》和《可伸缩服务架构:框架与中间件》,曾经在易宝支付、花旗银行、甲骨文、新浪微博、路透社等大型IT互联网公司担任技术负责人和首席架构师的工作,现专注于区块链平台的研发与推广,擅长大规模高并发的线上与线下相结合的第三方支付平台的架构规划与实施。 1 背景 对于当下流行的电子货币-比特币系统,朋友圈里有很多介绍性的文章,也有人试图通过漫画来生动的解释比特币的特性,但是始终不得要领,总是有些问题想不清楚,为了弄清楚这些问题,最近深入的研读了几本比特币的书籍以及中本聪本人发表的比特币论文,感觉茅塞顿开,迫不及待的与大家分享我的理解,希望与大家共同探讨、共同进步。 2 比特币 比特币是一种利用点对点技术实现的电子现金系统,它允许一个组织直接与另外一个组织进行在线支付,而不需要中间的权威的清算机构。 在比特币的世界里,如果你想拥有比特币,你需要申请一个比特币地址,就像你到银行存款,需要开立一个账户,然后,你就拥有这个账号,有了自己的账号,你可以向你的账号存款,别人也可以给你的账号转账,当你需要提款的时候或者给别人转账的时候,你需要出示一个能够打开这个地址的钥匙,也就是你的私钥,就像你在ATM上取款的时候需要提供密码一样。 与银行发行的法定货币不同,法定货币的发行是由各国央行来统一管理的,大家都相信央行是靠谱的

PoW挖矿算法原理及其在比特币、以太坊中的实现

夙愿已清 提交于 2019-11-25 22:49:51
  PoW,全称Proof of Work,即工作量证明,又称挖矿。大部分公有链或虚拟货币,如比特币、以太坊,均基于PoW算法,来实现其共识机制。即根据挖矿贡献的有效工作,来决定货币的分配。 比特币区块   比特币区块由区块头和该区块所包含的交易列表组成。区块头大小为80字节,其构成包括:    4字节:版本号   32字节:上一个区块的哈希值   32字节:交易列表的Merkle根哈希值    4字节:当前时间戳    4字节:当前难度值    4字节:随机数Nonce值   此80字节长度的区块头,即为比特币Pow算法的输入字符串。   交易列表附加在区块头之后,其中第一笔交易为矿工获得奖励和手续费的特殊交易。   bitcoin-0.15.1源码中区块头和区块定义: class CBlockHeader { public: //版本号 int32_t nVersion; //上一个区块的哈希值 uint256 hashPrevBlock; //交易列表的Merkle根哈希值 uint256 hashMerkleRoot; //当前时间戳 uint32_t nTime; //当前挖矿难度,nBits越小难度越大 uint32_t nBits; //随机数Nonce值 uint32_t nNonce; //其它代码略 }; class CBlock : public