首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

老弟想自己做个微信,被我一个问题劝退了。。

编程知识
2024年08月14日 10:34

大家好,我是程序员鱼皮。最近老弟小阿巴放暑假,想找点事情做,于是就来问我:老鲏,我想做个练手项目,有没有什么好的建议?

我说:练手项目的话,就做个自己感兴趣的呗,想加什么功能就加什么,做起来会更舒服~

小阿巴:Emm,我感兴趣的太多了,有没有推荐啊?

我说:那就想想自己经常使用的网站或 APP,选个对业务流程相对熟悉的。

小阿巴思考片刻,一拍脑袋:对啊,我天天用微信,那我就做个微信吧!说不定之后大家都在用我做的软件聊天呢?

我一听,不禁暗自惊叹,没想到小伙子年纪轻轻,野心很大啊!

我说:想法不错,但想做个微信这样的 IM(即时通讯)项目,可没有那么简单,你有什么实现思路么?说来听听?

小阿巴:微信的核心功能是收发消息,我可以把用户 A 发送的消息保存到数据库中,用户 B 进入聊天界面时,从数据库查询出发给他的消息就行。

我一听这个回答,就知道以小阿巴目前的水平,想做出微信是不太可能了。。。

我问:Emm,暂且不考虑用户体验和性能,我们就先实现基础功能吧,你会怎么让用户查看自己的历史消息呢?

小阿巴思考片刻,然后嘴角微微上扬,露出狡黠的笑容:你是不是以为我会说一次性把所有历史消息全部查出来?可惜啊老鲏,你把我想的太天真了,用户可能有成百上千条历史消息,全量加载会很慢,所以我必然会使用 分页 来查询!

我说:行,那你打算怎么分页呢?

小阿巴:这还真难不倒我,这几年我苦练增删改查,分页写得很溜的!纸笔呈上来,看我给你手写 SQL:

select from message
where user '鱼皮'
limit 020;

我说:Emm,老弟啊,听我一句劝,咱先别想着做微信了,先实现一个消息管理系统吧。

小阿巴:怎么说?吾 SQL 不亦精乎?

其实这也是一道经典的场景题:即时通讯项目中怎么实现历史消息的下拉分页加载?

下面鱼皮给大家讲解一下。

 

如何实现下拉分页加载?

业务场景

一般在即时通讯项目(比如聊天室)中,我们会采用下拉分页的方式让用户加载历史消息记录。

区别于标准分页每次只展示当前页面的数据,下拉分页加载是 增量加载 的模式,每次下拉时会请求加载一小部分新数据,并放到已加载的数据列表中,从而形成无限滚动的效果,确保用户体验流畅。

比如用户有 10 条消息记录,以 5 条为单位进行分页,刚进入房间时只会加载最新的 5 条消息:

下拉后,会加载历史的第 6 - 10 条消息:

理解了业务场景后,再看下实现方案,为什么不建议使用传统分页实现下拉加载。

 

传统分页的问题

在传统分页中,数据通常是 基于页码或偏移量 进行加载的。如果数据在分页过程发生了变化,比如插入新数据、删除老数据,用户看到的分页数据可能会出现不一致,导致用户错过或重复某些数据。

举个例子,对于即时通讯项目,用户可能会持续收到新的消息。如果按照传统分页基于偏移量加载,第一页已经加载了第 1 - 5 行的数据,本来要查询的第二页数据是第 6 - 10 行(对应的 SQL 语句为 limit 5, 5),数据库记录如下:

结果在查询第二页前,突然用户又收到了 5 条新消息,数据库记录就变成了下面这样。原本的第一页,变成了当前的第二页!

这样就导致查询出的第二页数据,正好是之前已经查询出的第一页的数据,造成了消息重复加载。所以不建议采用这种方法。

 

推荐方案 - 游标分页

为了解决这种问题,可以使用游标分页。使用一个游标来跟踪分页位置,而不是基于页码,每次请求从上一次请求的游标开始加载数据。

一般我们会选择数据记录的唯一标识符(主键)、时间戳、或者具有排序能力的字段作为游标。比如即时通讯系统中的每个消息,通常都有一个唯一自增的 id,就可以作为游标。每次查询完当前页面的数据后,可以将最后一条消息记录的 id 作为游标值传递给前端(客户端)。

当要加载下一页时,前端携带游标值发起查询,后端操作数据库从 id 小于当前游标值的数据开始查询,这样查询结果就不会受到新增数据的影响。

对应的 SQL 语句为:

SELECT FROM messages
WHERE id :cursorId
ORDER BY id DESC
LIMIT 5;

 

扩展知识

其实游标分页是一种经典方案,它的应用场景很多,特别适用于增量数据加载、大数据量的高性能查询和处理。除了 IM 系统获取历史消息记录之外,常见场景还有社交媒体信息流、内容推荐系统、数据迁移备份等等。

游标分页还有很多扩展知识,篇幅原因就不在这里展开了,感兴趣的同学可以在我们的 程序员面试刷题工具 - 面试鸭 上阅读。

 

最后

小阿巴听完,长叹道:唉,没想到光是这么一个小功能,就把我难住了。

我说:你可别这么想。。。难住你的,可不止这一个小功能啊!想做一个成熟的 IM 系统,除了最基础的消息发送和获取功能外,你得去学习 WebSocket 实时通讯、得考虑到消息收发的性能、得考虑到消息的顺序和一致性、得考虑到消息的存储成本和安全,等等等等。可没那么容易。

小阿巴:得,那我先去做消息管理系统了!🐶

 

更多

💻 编程学习交流:编程导航:https://www.code-nav.cn

📃 简历快速制作:老鱼简历:https://laoyujianli.com

✏️ 面试刷题神器:面试鸭:https://mianshiya.com  

From:https://www.cnblogs.com/yupi/p/18358557
本文地址: http://www.shuzixingkong.net/article/1087
0评论
提交 加载更多评论
其他文章 面试官:说说volatile应用和实现原理?
volatile 是并发编程中的重要关键字,它的名气甚至是可以与 synchronized、ReentrantLock 等齐名,也是属于并发编程五杰之一。 需要注意的是 volatile 并不能保证原子性,因此使用 volatile 并没有办法保证线程安全。 并发编程五杰: PS:“并发编程五杰”是
面试官:说说volatile应用和实现原理? 面试官:说说volatile应用和实现原理?
Sy.ExpressionBuilder 动态查询新体验
省流模式,看下对比 //常规查询 var query = users .WhereIf(m => m.UserName.Contains(input.UserName), !string.IsNullOrEmpty(input.UserName)) .WhereIf(m => input
Sy.ExpressionBuilder 动态查询新体验 Sy.ExpressionBuilder 动态查询新体验 Sy.ExpressionBuilder 动态查询新体验
.NET 8 中利用 MediatR 实现高效消息传递
前言 MediatR 是 .NET 下的一个实现消息传递的库,轻量级、简洁高效,用于实现进程内的消息传递机制。它基于中介者设计模式,支持请求/响应、命令、查询、通知和事件等多种消息传递模式。通过泛型支持,MediatR 可以智能地调度不同类型的消息,非常适合用于领域事件处理。 在本文中,将通过一个简
.NET 8 中利用 MediatR 实现高效消息传递 .NET 8 中利用 MediatR 实现高效消息传递 .NET 8 中利用 MediatR 实现高效消息传递
聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现
本文基于 Netty 4.1.56.Final 版本进行讨论 时光芿苒,岁月如梭,好久没有给大家更新 Netty 相关的文章了,在断更 Netty 的这段日子里,笔者一直在持续更新 Linux 内存管理相关的文章 ,目前为止,算是将 Linux 内存管理子系统相关的主干源码较为完整的给大家呈现了出来
聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现 聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现 聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现
将 Rust 代码编译为 WASM
前言 在现代 Web 开发中,WebAssembly (WASM) 已成为一种强大的工具。它使得开发者可以在浏览器中运行高性能的代码,跨越传统的 JavaScript 性能限制。Rust 语言因其高效性和内存安全性,成为了编写 WASM 模块的热门选择。本文将介绍如何将 Rust 代码编译为 Web
附038.Kubernetes_v1.30.3高可用部署架构二
部署组件 该 Kubernetes 部署过程中,对于部署环节,涉及多个组件,主要有 kubeadm 、kubelet 、kubectl。 kubeadm介绍 Kubeadm 为构建 Kubernetes 提供了便捷、高效的“最佳实践” ,该工具提供了初始化完整 Kubernetes 过程所需的组件,
附038.Kubernetes_v1.30.3高可用部署架构二 附038.Kubernetes_v1.30.3高可用部署架构二 附038.Kubernetes_v1.30.3高可用部署架构二
线上问题排查指南
前言 最近经常有小伙伴问我,遇到了线上问题要如何快速排查。 这非常考验工作经验了。 有些问题你以前遇到,如果再遇到类似的问题,就能很快排查出导致问题的原因。 但如果某个问题你是第一次遇到,心中可能会有点无从下手的感觉。 这篇文章总结了,我之前遇到过的一些线上问题排查思路,希望对你会有所帮助。 1 O
线上问题排查指南 线上问题排查指南 线上问题排查指南
C#数据结构与算法实战入门指南
前言 在编程领域,数据结构与算法是构建高效、可靠和可扩展软件系统的基石。它们对于提升程序性能、优化资源利用以及解决复杂问题具有至关重要的作用。今天大姚分享一些非常不错的C#数据结构与算法实战教程,希望可以帮助到有需要的小伙伴。 C#经典十大排序算法 主要讲解C#经典十大排序算法的实现,部分包含图解!
C#数据结构与算法实战入门指南 C#数据结构与算法实战入门指南 C#数据结构与算法实战入门指南