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为 31 的社区信息,当用户在t2时刻继续获取分页的时候,返回的却是id为 14 那么这里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为31的社区信息,同时返回参数中也包含t1的值,那么在第二次访问的时候,需要携带count=2&time=t1,这样列表接口将会根据用户的时刻继续获取他的排行队列,那么返回的就应该是id为24的社区信息,同样包括t1的值。

其实也就是用户访问的时候,如果没有携带时刻参数,那么就默认返回距离当前时间最近的时刻。

缓存的过期和时刻参数t的失效设定

讨论一下极端情况:

  • 当时刻为t9的时候,时刻参数是t1的用户获取的将是很久以前的数据,可能这个数据对当前用户来说已经没有意义了。
  • 最理想的情景就是,用户发出请求的时候,刚好有一批新的社区排行缓存生成,这是拿到的数据也是最合理的数据。
  • 还有一种比较不合理的情景,就是用户发出请求的时候,刚好有一批新的社区排行榜将要生成,那么用户拿到的数据也就是间隔时间T之前的缓存。

所以这里就需要进行缓存过期和时刻参数失效的设定。

  • 设定时刻参数比当前时间小N×T的为无效时刻,将自动返回最新的缓存信息。
  • 缓存排行榜列表也会在任务执行的时候清除 N×T 前的缓存数据。

后端的实现

数据库中缓存表的构建

  • 该缓存表专门缓存各个时刻的排行信息,有定时任务进行插入和删除数据,任何用户均不能操作修改该表中数据。
  • 该表包含的基本字段有: 自身的id社区的id关注的人数生成的时刻(时间戳)

定时任务的调度

  • 社区排行榜生成任务,该任务是每T时间执行一次,完成对当前社区排行榜的计算、排序和入缓存库,任务执行时生成当前任务的唯一时刻值并一同存入缓存数据库中。
  • 缓存数据库清理任务,该任务的执行间隔可以是N×T,完成对N×T时刻前的排行榜数据进行清除。

列表接口的实现

  • 判断用户传入时刻值的有效性。如果用户没有传入时刻值或时刻值比当前时间小N×T则分配最新的时刻值。
  • 向缓存表中获取指定分页的社区id,并返回响应的社区信息列表和对应的时刻值。

客户端相关的任务

  • 用户首次进入列表界面时,请求不需要携带时刻值。
  • 用户下拉刷新的时候,请求不需要携带时刻值。
  • 用户上拉浏览列表的时候,请求需要携带时刻值。
  • 用户上拉浏览列表的时候,如果时刻值失效,需要清楚本地的部分缓存。

存在的问题

  • 用户浏览的数据不是最新的数据,在上面的极端情况中已经讨论
  • 客户端处理较为复杂
  • 用户在界面滞留时间越久,客户端的到的数据越不理想
  • 用户在当前列表的上的操作,比如关注某个社区,客户端需要将原本的关注人数+1,但是刷新界面之后,关注的人数又会变成原来的数字。
  • 由于是缓存的数据,当用户点击某个社区的详情时,看到的关注人数可能与列表中的人数不一致。

社区列表根据关注人数排序(排行榜)的实现思路整理相关推荐

  1. SAP UI5 初学者教程之二十三 - 列表控件的排序 Sort 和分组 Group 试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 初学者教程之一:Hello World SAP UI5 初学者教程之二:SAP UI5 ...

  2. 斗鱼关注人数爬取 | 字体反爬的攻与防

    作者:CJ Ting 原文:https://cjting.me/2020/07/01/douyu-crawler-and-font-anti-crawling/ 之前因为业务原因需要爬取一批斗鱼主播的 ...

  3. html列表拖拽排序插件,可对列表自由拖拽排序的jQuery插件

    dragslot.js是一款可以对列表自由拖拽排序的jQuery插件.该插件主要的功能是实现了列表项可以在各个列表中相互拖拽. 对于像todo list, 分配任务列表都可以应用这个效果. 使用方法 ...

  4. python列表中字典排序_python中字典排序,列表中的字典排序

    python中字典排序,列表中的字典排序 一.使用python模块:operator import operator #首先要导入模块operator x = {1:2, 3:4, 4:3, 2:1, ...

  5. java和node.js 2018_2018,Node.js社区最值得关注的三个话题

    原标题:2018,Node.js社区最值得关注的三个话题 [ ] [IT168 资讯]我们与IBM Node.js社区主管Michael Dawson进行了一次访谈,本次访谈所涉及的几个Node.js ...

  6. Python 基础详解-列表的反转与排序!跬步千里

    引言 学习python中有什么不懂的地方,小编这里推荐加小编的python学习群:895,817, 687 有任何不懂的都可以在里面交流,还有很好的视频教程pdf学习资料,大家一起学习交流! 列表是按 ...

  7. python之itemgetter函数:对字典列表进行多键排序

    itemgetter函数:对字典列表进行多键排序 1 from operator import itemgetter 2 3 list_people = [ 4 {'name': 'Mike', 'a ...

  8. python 多个列表合并_Python对两个有序列表进行合并和排序的例子

    Python对两个有序列表进行合并和排序的例子 这篇文章主要介绍了Python对两个有序列表进行合并和排序的例子,最终代码经过不断优化,小编非常满意,需要的朋友可以参考下 假设有2个有序列表l1.l2 ...

  9. pythonfor循环列表排序_Python使用for循环对列表内元素进行排序方法

    这篇文章介绍Python使用for循环对列表内元素进行排序方法list = [13, 22, 6, 99, 11] for m in range(len(list)-1): for n in rang ...

  10. 字典排序什么意思_列表及字典的排序

    一.列表嵌套元组的排序 1.列表的内置方法s.sort() sort(...) L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN ...

最新文章

  1. PowerDesigner教程系列(三)概念数据模型
  2. 讨论下直博和读完硕士再读博,在能力上的差距
  3. python 为何要学16进制,从十六进制Python中的补
  4. DCMTK:DSRDocumentTree,DSRDocumentSubTree,DSRDocumentTreeNode和DSRContentItem类的测试程序
  5. iOS开发之控制器创建与加载(生命周期)
  6. 软考网络工程师--数据通信基础
  7. 传智播客Java 一维数组
  8. linux opencl安装方法,如何在Ubuntu上安装libOpenCL.so
  9. 获取HG526超级密码
  10. 大象装企营销:装饰公司如何通过差异化营销传播口碑
  11. iOS xcode中生成和打包ipa文件的方法和步骤
  12. 知识服务才是为用户创造价值的体现
  13. 用PHP查看微信撤回的消息,[笔记]使用itchat监听微信撤回消息
  14. js + jquery 两栏Tab鼠标移入显示/隐藏的效果(详)
  15. ToDoList 案例完整 尚硅谷
  16. 常见的关系型数据库有哪些
  17. 输入一个有大写和小写的字符串,把其中的大写转化为小写,小写转化为大写。
  18. 认知空间是什么意思_为什么很多女生都是“路痴”| 男女的空间认知有什么差异...
  19. 大数据技术之_11_HBase学习_03_HBase 实战之谷粒微博(练习API) + 扩展知识(布隆过滤器+HBase2.0 新特性)
  20. [转]数学之美-【算法】 - 用来流方式计算UV的基数算法

热门文章

  1. Redhat6.8安装docker环境
  2. 虚拟光驱安装服务器无法运行,Win7新装虚拟光驱无法打开的解决方法
  3. python小说爬虫练习
  4. C# 实现对三维点数据的 显示
  5. win7原版镜像_封装二:Win7 预装软件 Setup 包集成方法
  6. setup factory的命令行打包
  7. 最新要饭网源码1.6终极版
  8. STM32F4UCOSII移植
  9. 「运维有小邓」AD域管理软件——ADManager Plus介绍
  10. 小米手机解锁、线刷、开启root权限详细教程