本人面试遇到的多线程笔试题,主要考察的多线程编程和面向对象思想。主要关注:多个窗口办理业务,有VIP窗口和普通窗口。VIP窗口可以办理普通业务,普通业务窗口只能办理普通业务,VIP用户在VIP窗口可以优先办理。一般核心业务实现出来就可以了。
题目
1、银行内有6个业务窗口,1-4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口;
2、有三种对应类型的客户:VIP客户,普通客户,快速客户
3、异步随机生成各种类型客户,生成各类型用户的概率比例为:VIP客户:快速客户:普通客户 = 1:3:6
4、客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值
5、各类型客户在其对应窗口按顺序依次办理业务;
6、VIP窗口和快速窗口优先处理对应客户的业务,这两个窗口也可以处理普通客户的业务。
分析
- 对象:窗口、银行顾客、取号机
- 窗口类型:普通窗口、VIP窗口、快速窗口。
- 业务类型:普通业务、VIP业务、快速业务。
- 多线程:每一个窗口为一个线程,顾客生成一个线程。
代码
顾客实体
public class Consumer {
//取号号码
public Integer id;
//类型:普通、快速、VIP
public ConsumerType consumerType;
public Consumer(Integer id, ConsumerType consumerType) {
this.id = id;
this.consumerType = consumerType;
}
//省略set、get
/**
* 模拟业务执行时间
*/
public void execute() {
Random random = new Random();
try {
switch (consumerType) {
case NORMAL:
TimeUnit.SECONDS.sleep(random.nextInt(10) + 1);
break;
case QUICK:
TimeUnit.SECONDS.sleep(1);
break;
case VIP:
TimeUnit.SECONDS.sleep(random.nextInt(10) + 1);
break;
}
} catch (Exception exception) {
exception.printStackTrace();
System.out.println("业务异常");
}
}
}
//顾客枚举类
public enum ConsumerType {
NORMAL, QUICK, VIP;
@Override
public String toString() {
String name = null;
switch (this) {
case NORMAL:
name = "普通";
break;
case QUICK:
name = "快速";
break;
case VIP:
name = name();
break;
}
return name;
}
}
取号机(用户和号码管理器)
使用线程安全的阻塞队列BlockingQueue和原子类AtomicInteger实现用户取号排队。
public class ConsumerManager {
/**
* 用户号码(原子类线程安全)
*/
public AtomicInteger norNumber = new AtomicInteger(1);
public AtomicInteger vipNumber = new AtomicInteger(1);
public AtomicInteger quickNumber = new AtomicInteger(1);
/**
* 用户队列(线程安全)
*/
public ArrayBlockingQueue<Consumer> norQueue = new ArrayBlockingQueue<>(10);
public ArrayBlockingQueue<Consumer> vipQueue = new ArrayBlockingQueue<>(10);
public ArrayBlockingQueue