如何对百条/百万条答题数据进行排行榜排序?

请尝试在评论区里写下答案(如不能清楚表述,那么你可能没真正理解)。欢迎参与,为下一次求职做准备。

某厂面试题

有类似如下的数组,开始是100条

[
        [
            'id' => 1,
            'grade' => 100,
            'time' => 50
        ],
        [
            'id' => 2,
            'grade' => 90,
            'time' => 60
        ],
]

分数越高排名越高,分数相同时间越低排名越高
在不使用redis zset的情况下得出前十排行榜


而后延伸题,如果数据量达到了十万/百万或者更甚该如何处理得到排行榜

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 9
chowjiawei

数据插入到mysql的时候 插入redis bigmap bigmap资源可省了 然后根据bigmap的id去mysql直接查询

2年前 评论
laisxn

数量少,函数array_multisort()结合array_column(),排序完,取前十个

延申题,看使用场景,可以第一次可以使用简单yield,循环计算出符合排序的前二十个,并缓存,下一次产生新数据,只需要和这二十个比较,为什么是二十个,避免分数相同的情况要从源数据从新对比

简单回答,不保证对 :joy:

2年前 评论

100w 条的数组?

2年前 评论
Aroad (楼主) 2年前

用redis的string和list,手动维护一个有序的list

    $time = $redis->get('key:' . $grade)

    if ($time && $time < $new_time) {
        $redis->rPush('list:' . $grade, $id)
    } else {
        $redis->lPush('list:' . $grade, $id)
        // 记录更新当前分数时间
        $redis->set('key:' . $grade, $new_time)
    }

最后把100个list合并成一个list就好了。

2年前 评论

mysql 排序后期肯定会慢,如果可以的话用MongoDB 简单排序应该也是支持的,查出id 在去mysql 查也是一种方案呢

2年前 评论

laravel有个collect方法很好用 这个是并列排名的实现方法 可以参考一下

collect($data)
    ->groupBy('grade')
    ->sortKeysDesc(SORT_NUMERIC)
    ->values()
    ->each(function ($data, $key) {
        foreach ($data as $datum) {
            $datum['rank'] = $key + 1;
        }
    })
    ->toArray();
1年前 评论

目的是得出前十的排行榜,不是去排序这一百万数据,所以创建一个前十的数组,然后遍历一百万数据,大于数组中的最小值就插入到数组中

7个月前 评论

我觉得可以使用类似插入排序的方式,比如只需要前10,那么超出第10的就放弃插入就可以。

4个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!