面试问题:大型社交网络的数据结构

时间:2010-11-09 01:27:00

标签: algorithm data-structures

我偶然发现了另一个有趣的访谈问题 -

为非常大的社交网络(Facebook,LinkedIn等)设计数据结构?

另外,设计一种算法来显示两个人之间的连接或路径(例如me-> foo-> bar-> rob-> ron)

6 个答案:

答案 0 :(得分:5)

我可能会考虑某种多样的无向图,可能存储为稀疏邻接矩阵。至于找到两个人之间的最短路径,由于边缘成本是一致的,我会考虑进行双向搜索。

基本上,以每个人为中心的同心圆出去,其中每个圆圈都是他自己,然后是他的朋友,然后是朋友的朋友等,每一步测试两个圆圈中是否有人。沿着从你发现的第一个人到每个人的中心的路径,你找到了最短的路径。

你可以尝试其他最短路径算法,但一般来说,大多数最短路径算法只给你距离而不是实际路径。

答案 1 :(得分:1)

关于算法:

我喜欢@sxeraverx的答案,除了稀疏矩阵部分。在这里,附件列表或简单对象图将是更好的选择。矩阵必须为每个可能的连接分配内存,即O(n ^ 2),其中n是用户数。列表或对象图将仅在O(e)上分配内存,其中e是稀疏的连接数。

我会使用带标记的深度优先搜索来找到朋友。标记已经遍历的节点是必不可少的,因为朋友的周期将存在。使用DFS,路径的查找几乎是微不足道的,因为您用于执行DFS的堆栈是路径。所以,当你找到朋友时,你只需弹出整个堆栈,就可以了。

呼吸优先搜索没有这个不错的属性,因为用于遍历图的队列将具有未探测的节点,因此您需要使用其他结构跟踪路径。如果我们期望该功能针对朋友的同一“邻居”中的人并且真正关注性能,那么广度优先搜索可能是合适的。

DFS的另一个不错的特性是它可以并行化。当遇到新节点时,可以创建生成新的DFS进程/线程/以及处理节点子节点的任何内容。新线程必须能够通过某种消息传递系统共享标记信息。这可能是一些过早的优化现在,我想更多。如果有人感兴趣的话,这里有一个paper

答案 2 :(得分:1)

您可以使用neo4j

等图表数据库

答案 3 :(得分:0)

当我们拥有大量数据时,我们无法将所有数据保存在一台计算机上。这意味着我们需要存储一个机器ID。我们需要注意以下几个方面 -

  1. 对于每个朋友ID:machine_id = lookupMachineForUserID(id);
  2. 转到machine machine_id
  3. friend = lookupFriend(machine_id);
  4. 这里可以做很多优化。其中之一是减少从一台机器到另一台机器的跳跃次数,因为这很昂贵。我们可以通过将属于同一个国家/城市的人聚集在一起来做到这一点。在同一个城市寻找朋友的机会很高。同样,可以采用其他方式进行优化。

    我将尝试对数据结构的外观进行非常基本的实现。当然,在现实中我们必须考虑很多因素,比如如果机器发生故障,缓存数据等等。

    public class Server 
    {
     ArrayList<Machine> machines = new ArrayList<Machine>();
    }
    
    public class Machine 
    {
     public ArrayList<Person> persons = new ArrayList<Person>();
     public int machineID;
    }
    
    public class Person 
    {
     private ArrayList<Integer> friends;
     private int ID;
     private int machineID;
     private String info;
     private Server server = new Server();
    }
    

    我会尝试发布解决方案,以便稍后跟踪朋友之间的路径。

答案 4 :(得分:-3)

我担心数据结构无法实现 - 您可能会在这里谈论数据库结构。非常大的是xxx百万(100+),我不认为这可以在内存中有效处理。

答案 5 :(得分:-3)

复合模式?我们可能不需要将他所有的“朋友的朋友”拉到记忆中 数据库表设计是一个不同的问题