面試官:群聊消息的已讀未讀功能,你來(lái)設(shè)計(jì)一個(gè)?
時(shí)間:2021-11-11 13:53:34
手機(jī)看文章
掃描二維碼
隨時(shí)隨地手機(jī)看文章
[導(dǎo)讀]一朋友和我討論他前段時(shí)間面試某大公司的一題目:企業(yè)IM比如企業(yè)微信、釘釘里面的群消息的有個(gè)已讀未讀的功能,發(fā)送者剛發(fā)出消息時(shí),當(dāng)前群里其他群成員都是未讀狀態(tài),陸陸續(xù)續(xù)有人看了這個(gè)消息,這時(shí)候消息的詳情變成x人已讀,y人未讀,如下圖所示,有具體的已讀未讀列表(萬(wàn)惡的功能,看到同事o...
一朋友和我討論他前段時(shí)間面試某大公司的一題目 :
我第一時(shí)間給出一個(gè)很簡(jiǎn)單粗暴的方案:
{
uint64_t userid;
uint32_t mapid;
};
struct GroupMetaInfo
{
vectormembers;
string name;
uint32_t maxid;
// other info
};
這樣群成員每加入一個(gè)群里,就有mapidusreid的雙向映射了,假如群里有5個(gè)成員ABCDE, 那就對(duì)應(yīng)mapid 1-5,messageid對(duì)應(yīng)的消息詳情存儲(chǔ)就可以設(shè)計(jì)成
如上面的案例就是{5, readbit[0] =bin(0000 0000)}; 就占用了5B(4 1),A發(fā)消息,D已讀消息時(shí),就更新成{5,readbit[0]= bin(0000 1000)},其余4人都已讀消息時(shí) 更新為{5, readbit[0]=bin(0001 1110)}
企業(yè)IM比如企業(yè)微信、釘釘里面的群消息的有個(gè)已讀未讀的功能,發(fā)送者剛發(fā)出消息時(shí),當(dāng)前群里其他群成員都是未讀狀態(tài),陸陸續(xù)續(xù)有人看了這個(gè)消息,這時(shí)候消息的詳情變成x人已讀,y人未讀,如下圖所示,有具體的已讀未讀列表(萬(wàn)惡的功能,看到同事or老板的消息不能假裝沒(méi)看到了),每條消息對(duì)應(yīng)一個(gè)唯一的messageid(uint64_t),每個(gè)用戶對(duì)應(yīng)一個(gè)唯一的userid(uint64_t),應(yīng)該如何保存這個(gè)消息對(duì)應(yīng)的已讀未讀詳情呢?

對(duì)于每一個(gè)messageid,存當(dāng)前readids unreadids,當(dāng)群成員A已讀某一條消息時(shí),把A userid從unreadids移除寫到readids上就好了,客戶端更新到messageid對(duì)應(yīng)的詳情列表,就可以展示m人已讀,n人未讀顯然這么簡(jiǎn)單粗暴的方案面試官是不會(huì)滿意的,追問(wèn)有沒(méi)有更好的方案呢?
{
uint64_t userid;
uint32_t mapid;
};
struct GroupMetaInfo
{
vectormembers;
string name;
uint32_t maxid;
// other info
};
這樣群成員每加入一個(gè)群里,就有mapidusreid的雙向映射了,假如群里有5個(gè)成員ABCDE, 那就對(duì)應(yīng)mapid 1-5,messageid對(duì)應(yīng)的消息詳情存儲(chǔ)就可以設(shè)計(jì)成
如上面的案例就是{5, readbit[0] =bin(0000 0000)}; 就占用了5B(4 1),A發(fā)消息,D已讀消息時(shí),就更新成{5,readbit[0]= bin(0000 1000)},其余4人都已讀消息時(shí) 更新為{5, readbit[0]=bin(0001 1110)}
-
退出的成員呢?比如C退出群,發(fā)消息時(shí)maxid還是5,已讀 未讀總?cè)藬?shù)應(yīng)該是3(不包括發(fā)消息者本人),目前信息只有5個(gè)bit(0/1),識(shí)別不出來(lái)誰(shuí)已經(jīng)退出群聊了
-
退出群聊的成員如何處理?從GruopMetaInfo里面刪除么?退出群聊成員重新加入又如何分配id呢?
-
增加自增mapid字段,一個(gè)群聊維護(hù)一份,成本幾乎可以忽略不計(jì)
-
每個(gè)成員已讀未讀由8B(64bit)優(yōu)化成2bit,減少62/64, 200人已讀未讀舊的方案1600B, 現(xiàn)在只需要(200/8) * 2 4 = 54 , 每條消息節(jié)約95%