最近我试图找到一份工作,我被分配了一个测试任务,除了搜索 O(1) 的复杂性之外,我什么都做了。HR 表示,该解决方案基于构建内存索引。你能用一个例子解释一下这意味着什么。在此先感谢!)链接到带有项目的git:(https://github.com/venoman9867/testTask)
最近我试图找到一份工作,我被分配了一个测试任务,除了搜索 O(1) 的复杂性之外,我什么都做了。HR 表示,该解决方案基于构建内存索引。你能用一个例子解释一下这意味着什么。在此先感谢!)链接到带有项目的git:(https://github.com/venoman9867/testTask)
没有索引给出复杂性
O(1)
。您的解决方案仍然不符合要求。您正在阅读整个文件,尽管工作明确禁止这样做,但您需要熟悉数据库的运行原理以及索引在其中的排列方式。但无论如何,我认为你并没有失去太多:接受“家庭作业”面试的雇主往往马马虎虎。然而,更详细一点,我将描述移动的方向。看,
FileChannel.map()
这是一种处理memory-mapped
文件的方法。一般方案如下——首先你需要在内存中建立一个表,对于文件中的行,CSV
将记录它们所在文件中的偏移量。表查找需要O(log(N)
) 并且不需要磁盘读取。之后,通过偏移量从 mmap 读取条目就足够了。这个答案并不能解决面试中提出的问题。特别是,它不能解决问题:
答案回答了作者提出的问题,并描述了创建此类索引的原理,并在上面列出的几点上进行了修改,可以使用。我认为这将是有用的。
想法是立即在内存中存储一个HashMap,其中键是搜索字符串,值是表中行的链接。由于您的字符串表示为
String[]
,它看起来像这样(如果可以创建一组数组):但由于 Set<String[]> 不起作用,您需要以不同的方式存储字符串,例如将数组转换为
List<String>
. 或者,仅在文件中按顺序存储行号。在这种情况下,索引将如下所示:您需要为每一列存储这样一个索引,即 需要此类结构的列表。
从文件中读取一行时,您需要对其进行索引,即 为每一列添加一个指向集合中这样一行的链接:
在此过程之后,您可以搜索完全匹配:它将返回列具有“搜索字符串”值
indices.get(columnNumber).get("строка поиска")
的所有行的索引。这样的查找使用索引查找和查找- 都在 O(1) 中。allLines
columnNumber
ArrayList
HashMap
要按前缀搜索,您需要更改
indexLine
,即在索引中添加一个值,而不仅仅是 forline.get(i)
,即 列中的值,以及所有前缀:要解决将数据加载到内存中的问题,您需要更改索引的结构。您需要存储该行相对于文件开头的偏移量,而不是内存中数组中的行号。
至于索引的大小,很有可能会太大,你需要使用不同的数据结构来优化大小,但查找时间不是 O(1),而是 O(log (n))。