V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kaigong
V2EX  ›  程序员

从三十万观众中选出 30 个人作为中奖用户,还要在前端展示滚动抽奖的效果 ,后台的思路应该是怎样的呢?

  •  
  •   kaigong · 2020-03-19 13:18:41 +08:00 · 4690 次点击
    这是一个创建于 1706 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题 : 观众数量预计 30-40 万人 ,数据可以存储在 mysql/redis 中 需要前端页面点击抽奖,然后开始滚动观众数据 点击停止,返回给前端中奖的观众数据,展示

    问题一 : 前台滚动的全量观众数据如何返回给前端。我的方案是做一个大分页,前端分页调取,追加到他的滚动的那个数据 list 里面,如果网络延迟导致后面的分页没有及时加载,就回到开始重新滚动。

    问题二 : 中奖的逻辑该怎样实现? 业务方没有指定规则。我的方案是 从点击开始的那一刻开始,就按照一定的概率过滤每一个用户。遍历到该用户时,该用户的随机数如果在概率区间之内,就中奖。知道中奖用户数量足够为止。 需要注意的是,可能前端页面点击停止的时候,后台仍然没有足够的中奖人数,此时提高中奖概率,尽快返回结果 ?

    因为是第一次做这种抽奖 ,所以想不到太好的方案,请教有没有做过的大神,给说一下思路?

    36 条回复    2020-03-20 17:01:44 +08:00
    fancy111
        1
    fancy111  
       2020-03-19 13:22:53 +08:00
    你想多了,别说三十万,就算三万人选 30 个,也不会去用遍历。
    另外你系统里面有这三十万人的数据吗?如果都是登录的好说,直接生成 30 个 1-30W 的随机数,一一对应给他们就行了。
    前端展示就随便选几百个滚动就行了,你以为抽奖还搞什么全量数据。
    Aliennnnnn
        2
    Aliennnnnn  
       2020-03-19 13:23:59 +08:00
    为啥要这么麻烦,每个人给个序号(1-400000),然后从这里面随机取 30 个整数呗
    jangit
        3
    jangit  
       2020-03-19 13:24:40 +08:00 via iPhone
    先抽 n 个用户名给页面滚动去刷,然后再根据规则在所有人里面抽,抽完返回前端
    然后点停的时候显示这堆被抽中的人就好了
    dovme
        4
    dovme  
       2020-03-19 13:26:52 +08:00
    前端展示的话,提前取几百条用户名,然后以毫秒为间隔随机展示,
    中奖操作,直接数据库随机取 30 条数据就好了啊,
    dangyuluo
        5
    dangyuluo  
       2020-03-19 13:29:29 +08:00
    后台当然是加后门了😂

    大学的时候我给我们学校李玉导演见面会做了一个抽奖活动,一共抽五个人,我做了个后门,后来发现奖品是一套护肤品就作罢
    qiayue
        6
    qiayue  
       2020-03-19 13:38:19 +08:00
    三十万人编号,然后你生成 1~30 万的随机数,生成 30 次即可
    sweat89
        7
    sweat89  
       2020-03-19 13:43:28 +08:00
    set spop
    SuperAllen
        8
    SuperAllen  
       2020-03-19 13:43:49 +08:00 via Android   ❤️ 1
    1.前端,前端仅作展示和交互,接口提供几百个名字用作滚动,点抽奖后,请求抽奖接口,减慢滚动速度至展示结果停止
    2.后台设定奖池,对应奖品,数量,中奖人信息,这里你也可以指定谁中奖[狗头]
    3.抽奖逻辑一般都是随机数了,有其他规则的再具体设计算法
    justin2018
        9
    justin2018  
       2020-03-19 13:44:47 +08:00
    随机撒 你写死了 都没有人晓得 你除外 😁
    wmhx
        10
    wmhx  
       2020-03-19 13:51:31 +08:00
    30 万, 你选前 1000 个用户, 然后在取中间 100 ,然后想怎么随机就怎么随机,
    flowercoder
        11
    flowercoder  
       2020-03-19 13:54:20 +08:00
    不能把事情想的太真实,老板又不可能为这事给你加服务器配置,从简,真心的,想简单些。
    kaigong
        12
    kaigong  
    OP
       2020-03-19 13:56:51 +08:00
    我就知道我拐近坑里了,感谢各位大佬的提示。
    随机数对应人才是正道
    @Aliennnnnn @fancy111 @qiayue
    zjlletian
        13
    zjlletian  
       2020-03-19 14:06:47 +08:00
    直接后端随机选 30 个人中奖的和 300 个不中奖的给前端,前端滚动显示这 300 个不中奖的,等停的时候显示 30 个中奖的
    jackchao7432
        14
    jackchao7432  
       2020-03-19 14:17:46 +08:00
    随机数不就好了,这么简单的技术性问题.....
    loryyang
        15
    loryyang  
       2020-03-19 14:34:54 +08:00
    有编号的话,其实可以通过编号来,给 30 个坑,每次随机每个坑的一位数字,直到结束,一般来说根本不需要去重,几乎没有重复的可能
    名字的话,页面打开时先随机粗选一波名字到前端,就在这波人里面抽 30 个好了。具体粗选选多少就看前端能顶住多少了
    loryyang
        16
    loryyang  
       2020-03-19 14:35:34 +08:00
    @loryyang #15 想了下,第一个方案也不好搞,有点麻烦,毕竟有些号是没人的
    Tink
        17
    Tink  
       2020-03-19 14:37:17 +08:00 via iPhone
    随机数
    wagjia
        18
    wagjia  
       2020-03-19 15:00:11 +08:00
    import random
    alist = random.sample(range(1,200000),20)
    print(alist)
    violetlai
        19
    violetlai  
       2020-03-19 15:17:51 +08:00
    随机整数,然后返回。
    建议先问问你们老大要不要真随机
    tz894305532
        20
    tz894305532  
       2020-03-19 15:37:43 +08:00
    内定 30 人就完事了。
    jasamboro
        21
    jasamboro  
       2020-03-19 15:40:03 +08:00
    小张啊,从单位找出 30 个电话号码给我一下
    saulshao
        22
    saulshao  
       2020-03-19 15:59:11 +08:00
    直接读最近的 200 个名字给前端,让它拿去玩,中奖用户则随机...
    murmur
        23
    murmur  
       2020-03-19 16:01:28 +08:00
    30 个用户都是随机的,反正姓名电话都是**,还真的去抽啊,傻才那么做
    Maboroshii
        24
    Maboroshii  
       2020-03-19 16:05:07 +08:00
    提前选好结果,前端写死滚动的范围,最后显示你的结果就好了。。
    pmispig
        25
    pmispig  
       2020-03-19 17:55:52 +08:00
    滚动还不随便,从 30W 里面取几百几千个,让前端循环滚动就行了
    gerrard000
        26
    gerrard000  
       2020-03-19 18:09:09 +08:00
    srandmember key 30
    veike
        27
    veike  
       2020-03-19 18:26:58 +08:00
    前提是你得报名,别没报名被抽中就搞笑了
    christin
        28
    christin  
       2020-03-19 18:32:50 +08:00 via iPhone
    让我想到某个公司年会因为全是程序员中奖全体现场看代码,后门还是算了吧
    aguesuka
        29
    aguesuka  
       2020-03-19 18:35:51 +08:00 via Android
    只讨论真随机,也就是展示的所有中和不中的用户都是随机的,不会出现用户 aa 中奖,陪跑的全是 ab,ac,ad,据我所知 sql 必须遍历(欢迎打脸)。

    既然这样把所有用户取出来放到 list 里。list 的前 n 位保存已经取出来的用户,后 m 位保存没取的用户,每次取用户随机一个 n 到 m 的数 x,所指向的用户就是中将的用户,然后把 list[n]和 list[x]做交换,n++;m--。

    只要这样取,不管是取出的前 30 位,后 30 位中奖,都是随机的,都是公平的。而且中奖的用户和陪跑的用户没有关系。
    kaigong
        30
    kaigong  
    OP
       2020-03-19 18:58:08 +08:00 via Android
    @aguesuka 感谢您的答案,关于陪跑的概念我不是很懂,如果方便可以请您再仔细讲讲吗。
    gemini767
        31
    gemini767  
       2020-03-19 18:58:23 +08:00
    给你一些思路,实现不是难题,问题是场景,一个是如何做后门如何去做,有可能现场临时加后门,另一个是 30w 人确定都来?如何保证抽中的肯定是现场观众而不是走的人,如果轮空 如何补位
    Junn
        32
    Junn  
       2020-03-19 23:57:18 +08:00
    做个真的,直接展示的时候就从 30W 里随机取一些滚动,最后停到哪就是哪,不就完了么。
    相当于最后中奖者,抽了 2 次。
    致于随机取多少,看滚屏速度和每屏展示的数量决定了。
    另外每次循环时再随机重排一下顺序。

    做假的,就上面的,一开始就定了中奖者和陪跑的。前端自己玩,总能实现说停就停在中奖的地方的。
    aguesuka
        33
    aguesuka  
       2020-03-20 08:26:21 +08:00 via Android
    @kaigong
    陪跑就是滚动但是没有中奖的用户。

    抽奖最关键的是要实现一个接口 List<User> randomUser(int batch)。只要这个接口返回的每个用户是真随机的,那么前端只要一直显示,等到按停止按钮的时候,不管是当前的用户中奖,还是在请求一个后台中奖,每个用户中奖的概率是相等的。

    真随机和伪随机的区别是,伪随机需要一个种子,在种子相同的情况下,伪随机的每个随机数都是一样的。如果是随机分页的话,随机到的分页 offset 就是种子。(当然在这个抽奖里伪随机也可以)
    libook
        34
    libook  
       2020-03-20 11:47:12 +08:00
    一般有物理随机会比较让人信服,比如主持人嘉宾喊滚动和暂停。

    总的思路是最好放在内存数据库中,提升读数据的实时性;有条件的话可以先对数据库里的数据做随机排序;如果数据库有游标 Cursor 之类的功能的话,可以创建一个遍历所有数据的游标,前端下令开始滚动就从游标上遍历取数据,喊停就暂停,然后喊继续就再继续;前后端用 WebSocket 通信,比如 Socket.io ,前端与服务器一次连接就可以,持续到抽奖结束;前端以 WebSocket 事件的形式来控制后端,后端实时返回数据。
    windychen0
        35
    windychen0  
       2020-03-20 14:59:14 +08:00
    我寻思你想在前端显示的是名字还是 ID,如果是 ID 就好办了,数据库设置( id 主键自增,姓名,其他),然后前端页面显示 6 位数,3xxxxx,每一位随机上下滚动,第一位在 0-3 之间取值,其他在 0-9 之间取值,再给个停止按钮,你可以考虑一停一位还是一停全部,然后带着 ID 查询数据库出姓名部门数据不就好了?
    ajaxfunction
        36
    ajaxfunction  
       2020-03-20 17:01:44 +08:00
    我做过:
    前台滚动就是从数据库里拉出来几百个人的个头像或姓名, 这些信息仅仅做动画滚动用,给大家一种滚动抽奖视觉

    主持人喊开始:css 动画开始滚动这些的信息,主持人喊停止,然后 ajax 从数据库里随机 rand 几条中奖人员出来 ,并把中奖人信息展现到大屏幕上


    实际滚动多久,开始和结束间隔多久,和中奖没有任何关系,中奖是点结束那几毫秒里直接生成的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5392 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 08:49 · PVG 16:49 · LAX 00:49 · JFK 03:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.