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

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

  •  
  •   kaigong · 20 天前 · 2718 次点击

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

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

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

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

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

    大学的时候我给我们学校李玉导演见面会做了一个抽奖活动,一共抽五个人,我做了个后门,后来发现奖品是一套护肤品就作罢
    qiayue
        6
    qiayue   20 天前
    三十万人编号,然后你生成 1~30 万的随机数,生成 30 次即可
    sweat89
        7
    sweat89   20 天前
    set spop
    SuperAllen
        8
    SuperAllen   20 天前 via Android   ❤️ 1
    1.前端,前端仅作展示和交互,接口提供几百个名字用作滚动,点抽奖后,请求抽奖接口,减慢滚动速度至展示结果停止
    2.后台设定奖池,对应奖品,数量,中奖人信息,这里你也可以指定谁中奖[狗头]
    3.抽奖逻辑一般都是随机数了,有其他规则的再具体设计算法
    justin2018
        9
    justin2018   20 天前
    随机撒 你写死了 都没有人晓得 你除外 😁
    wmhx
        10
    wmhx   20 天前
    30 万, 你选前 1000 个用户, 然后在取中间 100 ,然后想怎么随机就怎么随机,
    flowercoder
        11
    flowercoder   20 天前
    不能把事情想的太真实,老板又不可能为这事给你加服务器配置,从简,真心的,想简单些。
    kaigong
        12
    kaigong   20 天前
    我就知道我拐近坑里了,感谢各位大佬的提示。
    随机数对应人才是正道
    @Aliennnnnn @fancy111 @qiayue
    zjlletian
        13
    zjlletian   20 天前
    直接后端随机选 30 个人中奖的和 300 个不中奖的给前端,前端滚动显示这 300 个不中奖的,等停的时候显示 30 个中奖的
    jackchao7432
        14
    jackchao7432   20 天前
    随机数不就好了,这么简单的技术性问题.....
    loryyang
        15
    loryyang   20 天前
    有编号的话,其实可以通过编号来,给 30 个坑,每次随机每个坑的一位数字,直到结束,一般来说根本不需要去重,几乎没有重复的可能
    名字的话,页面打开时先随机粗选一波名字到前端,就在这波人里面抽 30 个好了。具体粗选选多少就看前端能顶住多少了
    loryyang
        16
    loryyang   20 天前
    @loryyang #15 想了下,第一个方案也不好搞,有点麻烦,毕竟有些号是没人的
    Tink
        17
    Tink   20 天前 via iPhone
    随机数
    wagjia
        18
    wagjia   20 天前
    import random
    alist = random.sample(range(1,200000),20)
    print(alist)
    violetlai
        19
    violetlai   20 天前
    随机整数,然后返回。
    建议先问问你们老大要不要真随机
    tz894305532
        20
    tz894305532   20 天前
    内定 30 人就完事了。
    jasamboro
        21
    jasamboro   20 天前
    小张啊,从单位找出 30 个电话号码给我一下
    saulshao
        22
    saulshao   20 天前
    直接读最近的 200 个名字给前端,让它拿去玩,中奖用户则随机...
    murmur
        23
    murmur   20 天前
    30 个用户都是随机的,反正姓名电话都是**,还真的去抽啊,傻才那么做
    Maboroshii
        24
    Maboroshii   20 天前
    提前选好结果,前端写死滚动的范围,最后显示你的结果就好了。。
    pmispig
        25
    pmispig   20 天前
    滚动还不随便,从 30W 里面取几百几千个,让前端循环滚动就行了
    gerrard000
        26
    gerrard000   20 天前
    srandmember key 30
    veike
        27
    veike   20 天前
    前提是你得报名,别没报名被抽中就搞笑了
    christin
        28
    christin   20 天前 via iPhone
    让我想到某个公司年会因为全是程序员中奖全体现场看代码,后门还是算了吧
    aguesuka
        29
    aguesuka   20 天前 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   20 天前 via Android
    @aguesuka 感谢您的答案,关于陪跑的概念我不是很懂,如果方便可以请您再仔细讲讲吗。
    gemini767
        31
    gemini767   20 天前
    给你一些思路,实现不是难题,问题是场景,一个是如何做后门如何去做,有可能现场临时加后门,另一个是 30w 人确定都来?如何保证抽中的肯定是现场观众而不是走的人,如果轮空 如何补位
    Junn
        32
    Junn   20 天前
    做个真的,直接展示的时候就从 30W 里随机取一些滚动,最后停到哪就是哪,不就完了么。
    相当于最后中奖者,抽了 2 次。
    致于随机取多少,看滚屏速度和每屏展示的数量决定了。
    另外每次循环时再随机重排一下顺序。

    做假的,就上面的,一开始就定了中奖者和陪跑的。前端自己玩,总能实现说停就停在中奖的地方的。
    aguesuka
        33
    aguesuka   19 天前 via Android
    @kaigong
    陪跑就是滚动但是没有中奖的用户。

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

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

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

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


    实际滚动多久,开始和结束间隔多久,和中奖没有任何关系,中奖是点结束那几毫秒里直接生成的。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1085 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:06 · PVG 06:06 · LAX 15:06 · JFK 18:06
    ♥ Do have faith in what you're doing.