关于java:头条面试官如何设计群聊消息的已读未读功能懵了

起源:https://www.toutiao.com/i6686…

一敌人和我探讨他前段时间面试某大公司的一题目 :

企业IM比方企业微信、钉钉外面的群音讯的有个已读未读的性能,发送者刚收回音讯时,以后群里其余群成员都是未读状态,陆陆续续有人看了这个音讯,这时候音讯的详情变成x人已读,y人未读,如下图所示,有具体的已读未读列表(万恶的性能,看到共事or老板的音讯不能伪装没看到了),每条音讯对应一个惟一的messageid(uint64_t),每个用户对应一个惟一的userid(uint64_t),应该如何保留这个音讯对应的已读未读详情呢?

我第一工夫给出一个很简略粗犷的计划:

对于每一个messageid,存以后readids + unreadids,当群成员A已读某一条音讯时,把A userid从unreadids移除写到readids上就好了,客户端更新到messageid对应的详情列表,就能够展现m人已读,n人未读

显然这么简略粗犷的计划面试官是不会称心的,诘问有没有更好的计划呢?

仔细分析,依照目前的设计,每一条音讯,已读未读详情就要占用8B * 群成员数的内存,如果一个沉闷的200人大群,每发一条音讯,已读未读就要1600B,如果均匀每天音讯量是1k,那每个这样的群,每天就要1.6MB磁盘空间,对于客户端来说,特地是手机端,占用磁盘空间是用户不能承受的,又不能把工作音讯删了,对于服务器端来说,用户群体如果特地大,那数据库存储这个老本也不小

其实未读已读就是一个0/1的标记而已,能够保护一个bitmap来实现呢?具体应该怎么做呢?

群元信息保留userid到自增mapid的映射

struct UserInfo
{
 uint64_t userid;
 uint32_t mapid;
};

struct GroupMetaInfo
{
 vector <UserInfo> members;
 string name;
 uint32_t maxid;
 // other info
};

这样群成员每退出一个群里,就有mapid<->usreid的双向映射了,如果群里有5个成员ABCDE, 那就对应mapid 1-5,messageid对应的音讯详情存储就能够设计成

{ uint32_t maxid, uint8_t readbit[]}

如下面的案例就是{5, readbit[0] =bin(0000 0000)}; 就占用了5B(4+1),A发消息,D已读音讯时,就更新成{5,readbit[0]= bin(0000 1000)},其余4人都已读音讯时 更新为{5, readbit[0]=bin(0001 1110)}

这是个粗略的计划,外面还有一些细节值得思考:

  1. 退出的成员呢?比方C退出群,发消息时maxid还是5,已读+未读总人数应该是3(不包含发消息者自己),目前信息只有5个bit(0/1),辨认不进去谁曾经退出群聊了
  2. 退出群聊的成员如何解决?从GruopMetaInfo外面删除么?退出群聊成员重新加入又如何调配id呢?

首先2这个点,退出群聊的成员只能标记删除,不能物理删除,不然客户端展现已读未读详情时,通过mapid找不到对应的userid,退出的成员又重新加入群聊这个就好办了,把标记删除改成非标记删除,还是用旧的mapid

至于1呢? 我目前想到比拟好的形式就是再加多一个bitmap,记录成员在音讯发送时是否曾经退出群聊了,退出群聊就置为1, 所以最终计划就是

群信息减少userid,自增mapid双向映射,退出群聊成员标记删除,messageid 已读未读详情存储 {maxid, readbit[], quitbit[]}

新的计划带来怎么的收益呢?

  1. 减少自增mapid字段,一个群聊保护一份,老本简直能够忽略不计
  2. 每个成员已读未读由8B(64bit)优化成2bit,缩小62/64, 200人已读未读旧的计划1600B, 当初只须要(200/8) * 2 + 4 = 54 , 每条音讯节约95%+

如果maxid如果到百万甚至千万级别,那岂不是劫难?个别理论场景,群聊是会限度人数的,就算一直踢人加新人,那maxid最多也只能到企业人数。 如果maxid达到一个特地大数字,已读未读对应的存储能够减少多一个flag,如果bitmap存储老本远超过最后的计划,能够用最后的计划来实现,客户端提前埋好兼容逻辑就能够了

近期热文举荐:

1.1,000+ 道 Java面试题及答案整顿(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.Spring Boot 2.6 正式公布,一大波新个性。。

5.《Java开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞+转发哦!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理