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