@
xuanbg @
no1xsyzy 我这几天又思考了一下这个随机抽题的需求和实现思路,整理后的内容如下,欢迎指正:
前提:
1. 题库中一共有 N 道题。目前这个 N 为四位数,且在可以预期的未来,也不会有大量的增长。
2. 每道题目均为单选题、多选题、判断题中的一种。
3. 单选题、多选题、判断题的数量之比为 N1 : N2 : N3,且 N1 + N2 + N3 = N 。
需求:
1. 对每个用户来说,在每一轮游戏中,系统会将题库中的这 N 道题目,最多只有一次地、随机地呈现给用户,让用户回答。
2. 如果用户答对了题库中的所有题目,或者答错了 1 道题,则本轮游戏结束。
3. 为减轻系统负担,对于题库中的 N 道题,每次从中抽取 M 道题,全部抽完假设共需 L 次。对于每次抽取到的 M 道题,单选题、多选题、判断题的比例,尽量保持在 N1 : N2 : N3 这个比例上,也就是和这三类题目在总题库中的比例尽量相同。
4. 对同一个用户而言,各轮游戏的题目出现顺序应当不同,比如某一轮最开始拿到的题目是 1 、5 、9 、7,下一轮就不能也是这个顺序了。对于不同用户则没有要求。
大致实现思路:
1. 由于题目数量不多,可以在数据库中给题目增加一个序号字段,用自增的正整数来标记每一道题目的序号。
2. 在每个用户的每一轮游戏开始前,将所有题目的序号按题目类型进行分组,发给用户。例如用户收到的数组是
arr = [[1, 5, 7, 10, ...], [2, 3, 4, 8, ...], [6, 9, 11, 13, ...]],那么 arr[0]、arr[1] 、arr[2] 分别是所有单选题、多选题、判断题的序号。
3. 由于在一轮游戏中,每一次需要抽取 M 道题目,那么可知需要抽取单选题的数量为 Q1 = M * N1 / N,多选题为 Q2 = M * N2 / N,判断题为 Q3 = M * N3 / N 。
4. 前端在 arr[0] 中随机抽取 Q1 个元素为单选题的序号,在 arr[1] 中随机抽取 Q2 个元素为多选题的序号,在 arr[2] 中随机抽取 Q3 个为判断题的序号,并将这三组序号分别从 arr[0]、arr[1]、arr[2] 中移除。
5. 前端用这三组序号,从后端抽取 Q1 + Q2 + Q3 共 M 道题目并呈现给用户,让用户答题。
6. 如果这 M 道题用户全部回答正确,则重复第 4 、5 两步,继续抽取新的 M 道题给用户,直到用户答对所有题目,或者答错 1 道题目。
上面这个思路把抽题功能的主要部分交给了前端来做,感觉这样后端的负担可以小一些,也是对后端不够熟悉,就选择了这么一个相对比较取巧的办法。
PS:在整理这个需求和实现思路的时候,发现自己的表述的确不够清晰准确,就上面这段文字,来来回回修改了好几遍,用了两个多小时才完成,就这还是感觉表达得不够好,知易行难呐。