社区列表根据关注人数排序(排行榜)的实现思路整理
title: 社区列表根据关注人数排序(排行榜)的实现思路整理
date: 2018-09-08
tags: [工作笔记]
场景说明
客户端有一个社区列表的展示界面,该列表的排序方式是按照关注人数进行反向排序(从大到小),类似:
社区id | 社区名称 | 社区关注人数 |
---|---|---|
1 | AAA | 4 |
3 | CCC | 3 |
2 | BBB | 2 |
4 | DDD | 1 |
但是社区的 关注人数是动态变化的 ,当社区数量较多时也要考虑分页的情况,那么该列表的排序和分页有了很大的难度。
这里简单整理当前的实现思路,并指出明显的缺陷和暂时解决不了的问题,待以后有能力解决。
实现思路
这里首先要解决的第一个问题就是将动态转换成静态,然后才能排序。
如果做到根据实时的关注人数进行排序,对于后端是容易实现的,但是要考虑的客户端的处理方式:客户端会缓存已经获取的列表信息,同一个用户分页获取数据的时候,由于关注人数的动态变化,会导致数据出现重复或缺漏的问题。
举个例子说明
某时刻社区的关注人数如下(这里是举个例子说明,所以数据仅列出了4条):
社区id | 社区名称 | 社区关注人数 |
---|---|---|
1 | AAA | 3 |
3 | CCC | 4 |
2 | BBB | 3 |
4 | DDD | 1 |
当前时刻为t1,那么此时的社区排序结果如下:
社区id | 社区名称 | 社区关注人数 | 生成时刻 |
---|---|---|---|
3 | CCC | 4 | t1 |
1 | AAA | 3 | t1 |
2 | BBB | 3 | t1 |
4 | DDD | 1 | t1 |
一段时间之后,时刻为t2,那么此时社区的关注人数发生了变化:
社区id | 社区名称 | 社区关注人数 |
---|---|---|
1 | AAA | 5 |
3 | CCC | 7 |
2 | BBB | 9 |
4 | DDD | 4 |
那么此时的排序结果相对与t1时刻已经发生了明显的变化:
社区id | 社区名称 | 社区关注人数 | 生成时刻 |
---|---|---|---|
2 | BBB | 9 | t2 |
3 | CCC | 7 | t2 |
1 | AAA | 5 | t2 |
4 | DDD | 4 | t2 |
数据重复或漏缺的复现
这里出现的数据重复漏缺是有前提的:数据条数有点多,不能够一次全部返回给客户端,需要分页获取。
根据上面的那个例子,在t1时刻,用户当前的分页参数 count=2
,那么返回的是id为 3
和 1
的社区信息,当用户在t2时刻继续获取分页的时候,返回的却是id为 1
和4
那么这里id为1的社区就出现重复的问题了,缺漏的原理也类似。
缓存生成的关注排行榜
这里的实现思路是每隔一段时间将当前的关注排行榜进行缓存:
排行榜id | 社区id | 社区名称 | 社区关注人数 | 生成时刻 |
---|---|---|---|---|
1 | 3 | CCC | 4 | t1 |
2 | 1 | AAA | 3 | t1 |
3 | 2 | BBB | 3 | t1 |
4 | 4 | DDD | 1 | t1 |
5 | 2 | BBB | 9 | t2 |
6 | 3 | CCC | 7 | t2 |
7 | 1 | AAA | 5 | t2 |
8 | 4 | DDD | 4 | t2 |
这个时间间隔就是每次任务的时间间隔T,在T间隔内获取的数据都将通过该缓存排行榜中获取。用户在第一次访问的时候,仅携带分页的count
即可,返回的数据中,不仅包含社区的相关信息,还包括最新的时刻tn
,在以后的分页获取数据过程中,需要携带该时刻。
比如用户在t1
时刻传入参数count=2
,那么返回的是id为3
和1
的社区信息,同时返回参数中也包含t1
的值,那么在第二次访问的时候,需要携带count=2&time=t1
,这样列表接口将会根据用户的时刻继续获取他的排行队列,那么返回的就应该是id为2
和4
的社区信息,同样包括t1
的值。
其实也就是用户访问的时候,如果没有携带时刻参数,那么就默认返回距离当前时间最近的时刻。
缓存的过期和时刻参数t的失效设定
讨论一下极端情况:
- 当时刻为t9的时候,时刻参数是t1的用户获取的将是很久以前的数据,可能这个数据对当前用户来说已经没有意义了。
- 最理想的情景就是,用户发出请求的时候,刚好有一批新的社区排行缓存生成,这是拿到的数据也是最合理的数据。
- 还有一种比较不合理的情景,就是用户发出请求的时候,刚好有一批新的社区排行榜将要生成,那么用户拿到的数据也就是间隔时间T之前的缓存。
所以这里就需要进行缓存过期和时刻参数失效的设定。
- 设定时刻参数比当前时间小N×T的为无效时刻,将自动返回最新的缓存信息。
- 缓存排行榜列表也会在任务执行的时候清除 N×T 前的缓存数据。
后端的实现
数据库中缓存表的构建
- 该缓存表专门缓存各个时刻的排行信息,有定时任务进行插入和删除数据,任何用户均不能操作修改该表中数据。
- 该表包含的基本字段有:
自身的id
、社区的id
、关注的人数
、生成的时刻(时间戳)
。
定时任务的调度
- 社区排行榜生成任务,该任务是每T时间执行一次,完成对当前社区排行榜的计算、排序和入缓存库,任务执行时生成当前任务的唯一时刻值并一同存入缓存数据库中。
- 缓存数据库清理任务,该任务的执行间隔可以是N×T,完成对N×T时刻前的排行榜数据进行清除。
列表接口的实现
- 判断用户传入时刻值的有效性。如果用户没有传入时刻值或时刻值比当前时间小N×T则分配最新的时刻值。
- 向缓存表中获取指定分页的社区id,并返回响应的社区信息列表和对应的时刻值。
客户端相关的任务
- 用户首次进入列表界面时,请求不需要携带时刻值。
- 用户下拉刷新的时候,请求不需要携带时刻值。
- 用户上拉浏览列表的时候,请求需要携带时刻值。
- 用户上拉浏览列表的时候,如果时刻值失效,需要清楚本地的部分缓存。
存在的问题
- 用户浏览的数据不是最新的数据,在上面的极端情况中已经讨论
- 客户端处理较为复杂
- 用户在界面滞留时间越久,客户端的到的数据越不理想
- 用户在当前列表的上的操作,比如关注某个社区,客户端需要将原本的关注人数+1,但是刷新界面之后,关注的人数又会变成原来的数字。
- 由于是缓存的数据,当用户点击某个社区的详情时,看到的关注人数可能与列表中的人数不一致。
社区列表根据关注人数排序(排行榜)的实现思路整理相关推荐
- SAP UI5 初学者教程之二十三 - 列表控件的排序 Sort 和分组 Group 试读版
一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 初学者教程之一:Hello World SAP UI5 初学者教程之二:SAP UI5 ...
- 斗鱼关注人数爬取 | 字体反爬的攻与防
作者:CJ Ting 原文:https://cjting.me/2020/07/01/douyu-crawler-and-font-anti-crawling/ 之前因为业务原因需要爬取一批斗鱼主播的 ...
- html列表拖拽排序插件,可对列表自由拖拽排序的jQuery插件
dragslot.js是一款可以对列表自由拖拽排序的jQuery插件.该插件主要的功能是实现了列表项可以在各个列表中相互拖拽. 对于像todo list, 分配任务列表都可以应用这个效果. 使用方法 ...
- python列表中字典排序_python中字典排序,列表中的字典排序
python中字典排序,列表中的字典排序 一.使用python模块:operator import operator #首先要导入模块operator x = {1:2, 3:4, 4:3, 2:1, ...
- java和node.js 2018_2018,Node.js社区最值得关注的三个话题
原标题:2018,Node.js社区最值得关注的三个话题 [ ] [IT168 资讯]我们与IBM Node.js社区主管Michael Dawson进行了一次访谈,本次访谈所涉及的几个Node.js ...
- Python 基础详解-列表的反转与排序!跬步千里
引言 学习python中有什么不懂的地方,小编这里推荐加小编的python学习群:895,817, 687 有任何不懂的都可以在里面交流,还有很好的视频教程pdf学习资料,大家一起学习交流! 列表是按 ...
- python之itemgetter函数:对字典列表进行多键排序
itemgetter函数:对字典列表进行多键排序 1 from operator import itemgetter 2 3 list_people = [ 4 {'name': 'Mike', 'a ...
- python 多个列表合并_Python对两个有序列表进行合并和排序的例子
Python对两个有序列表进行合并和排序的例子 这篇文章主要介绍了Python对两个有序列表进行合并和排序的例子,最终代码经过不断优化,小编非常满意,需要的朋友可以参考下 假设有2个有序列表l1.l2 ...
- pythonfor循环列表排序_Python使用for循环对列表内元素进行排序方法
这篇文章介绍Python使用for循环对列表内元素进行排序方法list = [13, 22, 6, 99, 11] for m in range(len(list)-1): for n in rang ...
- 字典排序什么意思_列表及字典的排序
一.列表嵌套元组的排序 1.列表的内置方法s.sort() sort(...) L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN ...
最新文章
- PowerDesigner教程系列(三)概念数据模型
- 讨论下直博和读完硕士再读博,在能力上的差距
- python 为何要学16进制,从十六进制Python中的补
- DCMTK:DSRDocumentTree,DSRDocumentSubTree,DSRDocumentTreeNode和DSRContentItem类的测试程序
- iOS开发之控制器创建与加载(生命周期)
- 软考网络工程师--数据通信基础
- 传智播客Java 一维数组
- linux opencl安装方法,如何在Ubuntu上安装libOpenCL.so
- 获取HG526超级密码
- 大象装企营销:装饰公司如何通过差异化营销传播口碑
- iOS xcode中生成和打包ipa文件的方法和步骤
- 知识服务才是为用户创造价值的体现
- 用PHP查看微信撤回的消息,[笔记]使用itchat监听微信撤回消息
- js + jquery 两栏Tab鼠标移入显示/隐藏的效果(详)
- ToDoList 案例完整 尚硅谷
- 常见的关系型数据库有哪些
- 输入一个有大写和小写的字符串,把其中的大写转化为小写,小写转化为大写。
- 认知空间是什么意思_为什么很多女生都是“路痴”| 男女的空间认知有什么差异...
- 大数据技术之_11_HBase学习_03_HBase 实战之谷粒微博(练习API) + 扩展知识(布隆过滤器+HBase2.0 新特性)
- [转]数学之美-【算法】 - 用来流方式计算UV的基数算法