Java 搜索的性能调整
我对DS和算法相当陌生,最近在一次工作面试中,我被问到一个关于性能调优和代码的问题。我们有一个包含数十亿条目的数据结构,我们需要在该数据结构中搜索特定的单词。那么,我们可以使用哪种Java特性/库在尽可能快的时间内进行搜索呢 当时我想不出确切的答案,所以我写道:Java 搜索的性能调整,java,performance,data-structures,Java,Performance,Data Structures,我对DS和算法相当陌生,最近在一次工作面试中,我被问到一个关于性能调优和代码的问题。我们有一个包含数十亿条目的数据结构,我们需要在该数据结构中搜索特定的单词。那么,我们可以使用哪种Java特性/库在尽可能快的时间内进行搜索呢 当时我想不出确切的答案,所以我写道: 我们可以将值存储在地图中,并在地图中搜索单词(但遇到了如何确定地图中的键值对的问题) 我如何理解这个问题的确切答案以及最佳解决方案是什么?假设内存需求不是问题,并且数据结构已经填充,那么有两种数据结构可以实现高效搜索 关于时间复杂度,S
我如何理解这个问题的确切答案以及最佳解决方案是什么?假设内存需求不是问题,并且数据结构已经填充,那么有两种数据结构可以实现高效搜索 关于时间复杂度,
Set#contains
和Map#containsKey
都是O(1)
,假设哈希函数并不昂贵并且没有太多冲突
因为数据结构存储单词(假设您指的是String
s),所以使用(基数树、前缀树等)也可能相对有效,这将允许您按字符进行搜索(我认为是O(logn)
)。如果哈希函数很昂贵或者有很多冲突,这可能是一个很好的选择
你给面试官的答案应该足够了,因为散列是一种有效的搜索方法,即使是对于数十亿条目的搜索也是如此。数十亿条目的边缘可能会存储在主内存中(例如,以每个条目的100字节存储100亿条目的内容需要1000 GB的主内存) 虽然将数据存储在主内存中可以提供非常高的吞吐量(每秒数千到数百万个请求),但您可能需要特殊的硬件(典型的刀片服务器仅提供16 GB,但有些商品服务器允许安装高达3000 GB的主内存)。此外,将这么多数据保留在Java堆中可能会导致垃圾收集器暂停数秒或数分钟,除非特别小心 因此,除非数据的结构允许在主内存中进行非常紧凑的表示(例如,您只需要在int之间进行成员身份检查,这在512 MB位集中是可能的),否则您不会希望将其存储在主内存中,而是存储在磁盘上 因此,你需要坚持。任何关系数据库或NoSQL数据库都允许按键进行高效搜索,并且可以轻松地处理此类数据量。要与关系数据库通信,请使用或。要与非关系数据库对话,您可以使用它们专有的JavaAPI或抽象层,例如
如果您愿意,您也可以从头开始实施持久性(即面试官要求的)。为在外部内存中高效查找而优化的数据结构是,这是许多数据库内部使用的:-)您没有提到条目是单词还是文档(多个单词)。在这两种情况下,a都是合适的 搜索索引从十亿个文档条目中提取单词,并管理这些单词到它们所用文档的映射。像Lucene这样的框架(例如作为SOLR或ElasticSearch的一部分)为您管理内存和持久性
如果它只是数千个条目的倍数,那么一个简单的HashMap就足够了,因为那时不需要内存管理。如果所有十亿个条目都是单个单词,那么数据库可能是一个更好的选择。正如其他人所说,hashmap解决方案是合理的,但在可伸缩性方面存在疑问 下面是一个可能的解决方案,在下面的帖子中讨论
参考-在阅读了问题并在评论中得到澄清后,我认为对我来说显而易见的是:你需要提出后续问题 我会尝试将其分解,并提供一些我希望会有所帮助的评论,因为我也知道“当下”是什么感觉,以及在你最不需要的时候神经会如何刺伤你的背部 我们有一个包含数十亿条目的数据结构,我们需要在该数据结构中搜索特定的单词 我认为一个很好的后续问题是: Q:使用什么特定的数据结构来包含所有这些数据 我会一直按,直到他们给我一个实际的名字,并解释为什么不能命名Java算法/库。据您所知,数据结构可能是
String[]
、一个集
,甚至是磁盘上文件的一个别致的名称(如果他们想甩掉您的话)。他们也可以澄清并说DS不相关,你可以选择你认为最好的DS
措辞还暗示他们实施了该结构,并且该结构已经完成