【问题标题】:How to decide which collection will best suited for your requirement如何决定哪个系列最适合您的要求
【发布时间】:2016-06-28 22:43:57
【问题描述】:

最近在一次采访中,被问到一个问题——

让我们在一个文件系统中拥有数十亿个数据[假设数据已经被现有代码获取]我的任务是使用电子邮件 ID 作为搜索条件以最佳情况复杂度来查找人员姓名。 另外,什么系列最适合这个?

public class Person
 {
     public string Name {get;set;}
     public string Email {get;set;}
 }

【问题讨论】:

  • 您是否考虑过使用Dictionary<string, string>?其中keyEmailName 是值。然后,您可以使用一个简单的检查来查看该字典是否包含电子邮件地址作为键 - if (dict.ContainsKey("email@domain.com")) { var match = dict["email@domain.com"].Value; }
  • 这听起来有点像一个技巧问题。有两个赠品。 1)他们指定数据在文件系统中。 2)有数十亿。他们故意描述您无法实时直接查询的内容。如果多个用户尝试同时执行查询,那么找到一条记录需要很长时间,甚至更长。答案不是查询文件,而是将数据转换为您可以查询的内容。

标签: c# .net


【解决方案1】:

绝对是Dictionary,以电子邮件为密钥
按键查找是 O(1)
并且电子邮件会很好地散列

对于值,您可以使用名称或人员

还有 KeyedCollection 是 O(1) 但那几乎是在炫耀。

【讨论】:

    【解决方案2】:

    Dictionary<string,string> 将是我的答案。

    争论类的开销是无关紧要的。在引擎盖下,键被实现为哈希表。按键检索接近 O(1) 复杂度。

    在您的情况下,唯一键是电子邮件地址,人名是值。

    【讨论】:

    • 我认为我们的选民不喜欢字典。
    • @Paparazzi 这可能是一个简单的巧合。斯科特也没有那么错,指出没有办法实时查询是正确的。顺便说一句,如果它能让你的一天变得更好,那就去吧。 :P
    【解决方案3】:

    您不能(或者真的,真的不应该)计划搜索数十亿个文件以找到一个具有匹配电子邮件地址的文件。这就像阅读图书馆里的每一本书,以找出哪些是某个作者写的。你需要的(就像他们在图书馆里一样)是一个索引。您可能必须完成所有工作来读取和解析所有内容一次以构建索引,但是当您需要一个或多个特定文件时,您会搜索索引,而不是文件。

    您可以读取每个文件并将记录保存到数据库中,其中包含诸如电子邮件地址等元素以及有关该文档的其他详细信息,然后使用该记录存储指向文件本身的指针(路径)。

    这样,当您需要执行搜索时,您是在执行 SQL 查询,而不是扫描数十亿个文件。

    我不同意使用Dictionary。那本词典从哪里来?如果您使用的是索引(如一个或多个 SQL 表),那么您将对其进行查询。没有理由查询这些表并构建一个巨大的内存字典。如果您还希望文件可以通过其他属性进行查询,该怎么办。然后怎么 - 创建另一个字典?

    还有一个很大的漏洞——它假设每个电子邮件地址都有一个文件。如果两个包含相同的电子邮件地址怎么办?那么你就会有重复的键。

    如果您出于某种原因(例如极快的性能)想要将大量数据存储在内存中,它仍然不会改变解决方案。较新版本的 SQL Server 将数据加载到内存中。但它仍然在 SQL 服务器上,可以更有效地处理查询。

    关于使用哪个集合的问题以“also”开头,表明它不是问题的核心。这很好,因为我认为这根本不相关。如果查询返回对多个文档的引用,您可以在 IEnumerable<T> 中返回结果 - 基础类型(List<T>、数组等)并不重要。

    【讨论】:

    • 你没有得到这份工作。 Dictionary 将来自哪里“假设数据已经被现有代码获取]”。人名单数。什么 COLLECTION(db 不是一个集合)。即使在表上有索引,字典上的键查找也比到数据库的往返速度快 100 倍。最佳复杂性是集合使用的术语 - 而不是 db。字典不是 T - 它是键、值。你投了我的票吗?
    • 重复的电子邮件?这将使电子邮件传递变得困难。
    • @Paparazzi - 正确指出字典不可能在内存中保存十亿个条目,没有集合会这样做。另一方面,如果数据已经包含一个电子邮件地址,为什么还要推动人工索引。 还有一个很大的漏洞——它假设每个电子邮件地址都有一个文件。如果两个包含相同的电子邮件地址怎么办?那么你就会有重复的键。我们只是对这个问题的理解不同,Scott 正在回答面试官,而我们正在考虑示例课程。
    • @pijemcolu 所陈述的问题是集合和复杂性——他们询问的是集合。 “文件系统中的数十亿数据”并不意味着数十亿的电子邮件。他们解析了几百万。 “假设数据已经被现有代码获取”公平假设它们适合内存。
    • “我的任务是使用电子邮件 ID 作为搜索条件,以最佳案例复杂性来查找人名”对我来说非常清楚。人名是单数。 “还有,什么收藏品最适合这个?”我将把它当作“集合”而不是数据库。获取数据(姓名、电子邮件)的系统是否无关紧要?所以你会忽略现有的代码来获取数据并从头开始?很确定你没有得到这份工作。
    猜你喜欢
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 2022-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多