【阿里真题思考】 生成、发放大量红包并控制资金流速
2.1k
等8人参与

大家好!大Boss来啦!

这是一道阿里让求职者带回家做的面试题。要求求职者将代码在面试前发送到面试官的邮箱。这样的题目设计的目的是为了检查求职者的思考和Coding能力。。

题目内容

Hi,到了年底了,公司决定发1亿元红包给1000W个用户:

  • 红包金额平均在1元左右(随机)
  • 用户会抢红包,红包:用户是1:n的关系。(假设所有红包都会被领取)
  • 红包发送要控制速率,这是为了持续发酵用户的感情,举个例子:若要求在1000s内发完,那么平均每秒发出去的金额在10W元。
  • 时间不一定是1000s,时间是随时可以改变的输入

对红包和用户的抽象如下:


public class RedPacket {

    private int id; // 请实现自增逻辑
    private int money; // 单位分
    private byte state; // 0-未发送  1-已发送

    // 增加难度无意义字段,让红包不要太小
    // 水平不够可以删除字段简化题目
    // transient 的意思就是不用持久化,但是内存中得存在
    transient byte[] padding = new byte[1024];

    private RedPacket(int money){
        this.money = money;
    }

    public static RedPacket create(int money) throws InterruptedException {
        Thread.sleep((long) (1000 + (Math.random() * 1000)));
        // 创建红包的逻辑
    }
    
    static class FailToSendException extends Exception {
    }

    public static void sendTo(User user) throws InterruptedException, FailToSendException {
        // 模拟发送,什么都不做
        Thread.sleep((long) (1000 + (Math.random() * 1000)));
        if(Math.random() > 0.99) {
            throw new FailToSendException();
        }
    }

}


public class User {
    private int id; // 请实现自增逻辑
    private String name; // 请Mock一个名字

    // 增加难度无意义字段,让红包不要太小
    // 水平不够可以删除字段简化题目
    // transient 的意思就是不用持久化,但是内存中得存在
    transient byte[] padding = new byte[1024];

    public User(String name){
        this.name = name;
    }
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
代码块
复制 预览
复制成功!
代码块
复制 预览
复制成功!

因为生成红包、发送红包都有一定的I/O成本,这里用Thread.sleep替代。生成红包的I/O成本是1~2秒/个,见RedPacket.create方法,请补全实现。

发送红包的RedPacket.send方法成本是1-2秒发送1个,但是有1%的概率失败,如果失败就需要重新发送。

public static void sendTo(User user) throws InterruptedException, FailToSendException {

    Thread.sleep((long) (1000 + (Math.random() * 1000)));
    if(Math.random() > 0.99) {
        throw new FailToSendException();
    }
    // 记录用户的红包(别忘记排名)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
代码块
复制 预览
复制成功!
代码块
复制 预览
复制成功!

要做的事情:

  1. 生成用户、红包,并保存到磁盘上(自己设计格式)。

  2. 用户并发抢红包不用真的模拟万级QPS的并发,但请画出服务器如何解决这种并发情况的架构图

  3. 红包发送程序是通过读取磁盘程序工作

  4. 请你画出你红包发送部分的架构图

  5. 请实现你的算法

  6. 统计出获得红包最多的100个用户姓名和金额

本题答案将以视频方式公布,欢迎大家到答疑区讨论,我会及时回复和支招。

我的作业
去发布

登录后即可发布作业,立即

全部作业
0
评论
提交于  2022-04-15 09:09:34

登录后即可查看更多作业,立即

微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号