【问题标题】:Google Interview Question [closed]谷歌面试问题[关闭]
【发布时间】:2011-11-11 01:27:35
【问题描述】:

这是 Google 面试问题之一。

如果 Hash Table 增长超过 30 GB,可能会出现什么问题 (忽略哈希函数不好等问题)

我不知道。有什么满意的答案?

谢谢

【问题讨论】:

  • 这取决于。你有 30GB 的内存吗?那将是我问他们的第一个问题
  • 投票重新打开:虽然问题标题不具体,但关于哈希表如何扩展和合适的替代方案的讨论与编程非常相关。也许海报可以重述这个问题,以关注海量哈希表会发生什么?
  • 为了记录,我投票决定将其移至programmers.stackexchange.com,但我不希望它被关闭。投票决定重新开放。
  • 你问为什么是30?如果我理解正确,它不会在 32 位系统上工作,因为你需要至少 2^36 的 hashmap 标头:)

标签: java c++ hashtable


【解决方案1】:

答案部分取决于他们是在谈论经典的哈希表实现(如 Java 中的 HashTable / HashMap)还是更复杂的东西。最后,按照今天的标准,30 GB 的内存对于单机/VM 来说仍然是相当大的。

所以想想下面发生了什么:

  1. 它必须在某个海量数组中的任意位置读写。
  2. 如果填满超过一定程度,它就必须增长;请参阅 Java 实现中的“负载因子”。
  3. 在垃圾收集语言/实现中,存储在哈希表中的所有对象都需要由垃圾收集器检查

这会导致以下问题:

  1. 目前尚不清楚即使是今天的操作系统也能很好地分配数十 GB 的内存块
  2. 为简单起见,假设表的一半实际上由表本身使用(而不是键和值对象)。所以里面有一个 15 GB 的数组。所以每次表增长时,你至少需要分配另一个 15 gb
  3. 即使分配了数十 GB 的数组,操作系统也会分页其中的一些内存。由于我们假设一个好的散列函数,如果我们使用数组中的大部分数据,我们将破坏页面缓存。会有很多页面错误。
  4. 假设我们使用所有数据。有些键经常使用,有些则不常用。为了说明,假设每个键值都很小—— 128 字节。为简单起见,假设我们将哈希表中的所有内容都存储为值。所以 30G/128 = ~ 250M 条目。但是说25k常用键。 (25k / 250M = 0.01%)。但是如果有一个好的散列函数,它们会均匀地分布在庞大的数组中。即使页面大小很小——比如 4kb,25K(条目)* 128 字节(条目大小)= ~3.5Mb 的常用数据价值我们需要 25K(条目)* 4K(页面大小)= ~ 100Mb 的内存需要以高达 3.5% 的效率保持寻呼!
  5. 在 Java 世界中,从业者不建议堆大小大于 4 - 8Gb。当然有像 Azul 这样的东西,但这只是证明了这一点——典型的垃圾收集器不能很好地扩展到这些大小。

我同意 Google 正在寻找作为解决方案分发的其他海报。但我认为,一个简单的哈希表会停止扩展超过一个点。在上面,

  1. 如果所有条目的访问相对均匀,则必须进行分配
  2. 如果大部分时间都在访问某些地图,则使用两张地图(一张用于最常用的地图)可以为您带来很多好处。
  3. 在 Java 世界中,使用在堆外存储数据的专用映射也可以提高性能;例如,请参阅Peter Lawrey's work
  4. 当您必须扩大哈希表时,即使只是简单地对哈希表中的底层数组进行条带化(如 Java 的 ConcurrentHashMap 所做的那样),也可以为您带来重大改进。

【讨论】:

    【解决方案2】:

    我认为面试官期待Distributed Hash table 的行,因为一个 30GB 的哈希表不能存储在单台机器上(至少在当前的 64 位世界中);从我个人的经验来看,相当多的 google Qs 都是围绕分布式计算、map-reduce 等展开的,

    【讨论】:

    【解决方案3】:

    一些问题:

    1. Hash Collision 可能是主要问题之一。
    2. 当数据以哈希表形式存储在磁盘中时,频繁读取磁盘也会效率低下。

    【讨论】:

    • 为什么哈希冲突一定会导致额外的内存?
    • 我也没有得到第二个。这怎么会花费额外的内存?
    • 为什么哈希冲突会成为问题?通常,频繁的哈希冲突是哈希函数不佳的结果,问题明确表示要忽略它。想象一下,30 GiB 哈希表中这组特定对象的哈希函数分别被哈希到不同的值。 30 GiB 可通过 35 位整数寻址,因此强加的要求只是每个对象的 5 个字节是唯一的。这似乎是合理的。
    • 我认为#1 不是答案,#2 更有可能回答这个问题,因为:除非你实际上有 30Gb 的 RAM,否则数据存储在磁盘(HDD)上,它具有很高的吞吐量,但随机访问的高延迟(这是哈希表的全部内容)。 IDK 如果 SSD 可以改善这一点。
    猜你喜欢
    • 1970-01-01
    • 2011-07-27
    • 2021-11-24
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    相关资源
    最近更新 更多