[CareerCup] 10.2 Data Structures for Large Social Network 大型社交網站的資料結構

Grandyang發表於2015-10-03

 

10.2 How would you design the data structures for a very large social network like Facebook or Linkedln? Describe how you would design an algorithm to show the connection, or path, between two people (e.g., Me -> Bob -> Susan -> Jason -> You).

 

這道題讓我們實現大型社交網站的資料結構,首先使用者類Person需要包含好友和其他的一些資訊,而且大型網站一般可能會有上百萬的使用者,我們一般不可能把所有的資料都存在一臺機器上,所以我們在查詢好友時,需要先查詢好友所在的機器,再在機器上查詢好友,每個好友或機器都有自己的編號,為了快速查詢,均使用了雜湊表來建立對映,參見程式碼如下:

 

class Person {
public:
    Person(int id): _personID(id) {}
    int getID() { return _personID; }
    void addFriend(int id) { _friendIDs.push_back(id); }
    
private:
    vector<int> _friendIDs;
    int _personID;
};

class Machine {
public:
    unordered_map<int, Person*> _persons;
    int _machineID;
    Person* getPersonWithID(int personID) {
        if (_persons.find(personID) == _persons.end()) {
            return nullptr;
        }
        return _persons[personID];
    }
};

class Server {
public:
    unordered_map<int, Machine*> _machines;
    unordered_map<int, int> _personToMachineMap;
    Machine* getMatchineWithId(int machineID) {
        if (_machines.find(machineID) == _machines.end()) {
            return nullptr;
        }
        return _machines[machineID];
    }
    int getMachineIDForUser(int personID) {
        if (_personToMachineMap.find(personID) == _personToMachineMap.end()) {
            return -1;
        }
        return _personToMachineMap[personID];
    }
    Person* getPersonWithID(int personID) {
        if (_personToMachineMap.find(personID) == _personToMachineMap.end()) {
            return nullptr;
        }
        int machineID = _personToMachineMap[personID];
        Machine *machine = getMatchineWithId(machineID);
        if (machine == nullptr) return nullptr;
        return machine->getPersonWithID(personID);
    }
};

 

優化:減少機器跳躍

機器之間的跳躍花費大,我們一般不會在機器之間進行隨機跳躍,一般若我有好多個好友在同一個機器上,會將他們歸到一起訪問。

優化:智慧的分類人和機器

由於人們更有可能會新增和他們來自同一個國家的人,所以將同一個城市,州,國家的人都儘量存貯到同一臺機器上,這樣查詢時會減少機器跳躍

問題:BFS搜尋需要將點標記為已讀,這裡怎樣處理?

由於可能會有很多個搜尋同時進行,所以我們不會對資料進行直接標記,但我們會使用雜湊表來建立對映來標記資料是否訪問過。

還有一些其他的問題可以考慮:

1. 在現實中,如果伺服器崩潰了怎麼辦?

2. 你怎麼利用好快取功能?

3. 你會搜到圖的盡頭嗎,你怎麼決定什麼時候停止搜尋?

4. 實際中,每個人的朋友數都不同,有人想在你和別人之間產生一個好友鏈,你該怎麼用這資料確定在哪開始遍歷?

 

相關文章