pursue wind pursue wind
首页
Java
Python
数据库
框架
Linux
中间件
前端
计算机基础
DevOps
项目
面试
书
关于
归档
MacOS🤣 (opens new window)
GitHub (opens new window)
首页
Java
Python
数据库
框架
Linux
中间件
前端
计算机基础
DevOps
项目
面试
书
关于
归档
MacOS🤣 (opens new window)
GitHub (opens new window)
  • 技术面试题篇

  • 面试准备篇

  • 技术面试题自测篇

  • 练级攻略篇

  • 工作篇

  • 面经篇

  • 笑傲Java面试

    • 2-1 导学-Java编程技巧部分
    • 2-2 IDEA Java配置补充
    • 2-4 Java8 Stream 接口:流和并发计算实例
    • 2-5 和面试官聊聊实现管道和流计算的基石:函数式的Monad
    • 2-6 Buffer的原理和使用场景+面试题解读
    • 2-7 补充提问:同步和阻塞、异步和非阻塞等不等价?
    • 2-8 阿里面试题:中文乱码处理和大文件计算词频
    • 2-9 实战场景Coding训练:解读反射+代理+AOP 并结合业务逻辑实现
    • 2-10 注解部分答案
    • 2-11 反射-元编程面试题目合集
    • 2-12 面试必备:Java8-11的新特性和理解的误区
    • 2-13 白板篇-Java编程总结(以及面试题)
    • 3-1 算法和数据结构导学
    • 3-2 教你面试时不会忘记的5种手写排序
    • 3-3 手写链表算法
    • 3-4 手写栈和队列面试专项
    • 3-5 课后习题+面试题:用栈和队列实现表达式解析
    • 3-6 迷宫伪代码和8皇后问题源代码
    • 3-7 3-7 树部分源代码
    • 3-8 8皇后问题
    • 3-10 动态规划的课前题目
    • 3-11 总结和课后习题:白板篇-数据结构和算法
    • 4-1 解读:并发编程知识体系
    • 4-2 看看你的基础:Java线程状态之间如何转换?
    • 4-3 CAS和原子操作
    • 4-4 同步器(上篇)——面试官问synchronized本质是什么?
    • 4-5 同步器(中)——AbstractQueuedSynchronizer
    • 4-6 面试官:说6个Java的同步器?
    • 4-7 面试官出难题:并发环境下单例怎么写性能最高
    • 4-8 面试官:LinkedBlockingDeque和SynchronousQueue工作原理一样吗?
    • 4-9 面试要点:volatile的简短补充
    • 4-10 给面试官讲讲无锁编程(Lock-Free Programming)
    • 4-11 高阶并发编程Coding训练:N种优化哲学家就餐问题的方法
    • 4-12 并发基础篇:总结和思考题
    • 4-13 并发部分的通关Boss: 生成、发放大量红包并控制资金流速
  • LeetCode

  • 面试
  • 笑傲Java面试
pursuewind
2021-12-13

4-13 并发部分的通关Boss: 生成、发放大量红包并控制资金流速

# 并发部分的通关Boss: 生成、发放大量红包并控制资金流速

大Boss来啦!

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

题目内容

Hi,到了年底了,Wo信公司决定发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;
    }
}

因为生成红包、发送红包都有一定的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. 用户并发抢红包不用真的模拟万级QPS的并发,但请画出服务器如何解决这种并发情况的架构图。

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

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

  5. 请实现你的算法

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

Last Updated: 2023/01/30, 11:01:00
4-12 并发基础篇:总结和思考题
xxx

← 4-12 并发基础篇:总结和思考题 xxx→

Theme by Vdoing | Copyright © 2019-2023 pursue-wind | 粤ICP备2022093130号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
  • 飙升榜
  • 新歌榜
  • 云音乐民谣榜
  • 美国Billboard榜
  • UK排行榜周榜
  • 网络DJ