黑马程序员----银行业务调度系统面试题
?
這種程序就是模擬一個去取票系統,大家平時都有移動營業廳或者銀行,都知道進去之后需要在門口的取票取一張票,那張票上面記錄你的號碼和需要等待的人樓,然后窗口會有顯示當前服務的號碼,如果輪到相應的數字就到對應的窗臺。
---------------------- android培訓、java培訓、期待與您交流! ----------------------
圖:程序運行時狀態
模擬實現銀行業務調度系統邏輯,具體需求如下:
? 銀行內有6個業務窗口,1 - 4號窗口為普通窗口,5號窗口為快速窗口,6號窗口為VIP窗口。
? 有三種對應類型的客戶:VIP客戶,普通客戶,快速客戶(辦理如交水電費、電話費之類業務的客戶)。
? 異步隨機生成各種類型的客戶,生成各類型用戶的概率比例為
VIP客戶 :普通客戶 :快速客戶 = 1 :6 :3。
? 客戶辦理業務所需時間有最大值和最小值,在該范圍內隨機設定每個VIP客戶以及普通客戶辦理業務所需的時間,快速客戶辦理業務所需時間為最小值(提示:辦理業務的過程可通過線程Sleep的方式模擬)。
? 各類型客戶在其對應窗口按順序依次辦理業務。
? 當VIP(6號)窗口和快速業務(5號)窗口沒有客戶等待辦理業務的時候,這兩個窗口可以處理普通客戶的業務,而一旦有對應的客戶等待辦理業務的時候,則優先處理對應客戶的業務。
隨機生成客戶時間間隔以及業務辦理時間最大值和最小值自定,可以設置。
? 不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。
通過老師的分析,可是知道有三種類型的客戶,VIP:普通客戶:快速客戶,然后1-4專為普通客戶辦理的窗臺,5號為快速窗口,6號為VIP那么我們在進入程序的時候創建六個窗口用于處理客戶,辦理的時間是通過sleep來模擬。
Constants類:用于控制用戶等待的時間和產生用戶的時間 ,采用靜態變態來向其他程序提供s
Constants 1 package cn.itcast.bank;2
3 public class Constants {
4 public static int MAX_SERVICE_TIME = 10000; //10秒!
5 public static int MIN_SERVICE_TIME = 1000; //1秒!
6
7 /*每個普通窗口服務一個客戶的平均時間為5秒,一共有4個這樣的窗口,也就是說銀行的所有普通窗口合起來
8 * 平均1.25秒內可以服務完一個普通客戶,再加上快速窗口和VIP窗口也可以服務普通客戶,所以,
9 * 1秒鐘產生一個普通客戶比較合理,*/
10 public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
11 }
CustomerType類:模擬三種 不同的用戶
CustomerType 1 package cn.itcast.bank;2 public enum CustomerType{
3 COMMON,EXPRESS,VIP;
4 public String toString(){
5 switch(this)
6 {
7 case COMMON:
8 return "普通";
9 case EXPRESS:
10 return "快速";
11 case VIP:
12 return name();
13 }
14
15 return null;
16 }
17 }
MainClass類:這個類用于產生6個窗口,然后模擬用戶的拿號到享受服務的過程,相當整個程序的司令用于整合整個程序。
MainClass 1 package cn.itcast.bank;2
3
4 import java.util.concurrent.Executors;
5 import java.util.concurrent.TimeUnit;
6 import java.util.logging.Logger;
7
8
9 public class MainClass {
10
11 private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");
12
13
14 public static void main(String[] args) {
15 //產生4個普通窗口
16 for(int i=1;i<5;i++){
17 ServiceWindow window = new ServiceWindow();
18 window.setNumber(i);
19 window.start();
20 }
21
22 //產生1個快速窗口
23 ServiceWindow expressWindow = new ServiceWindow();
24 expressWindow.setType(CustomerType.EXPRESS);
25 expressWindow.start();
26
27 //產生1個VIP窗口
28 ServiceWindow vipWindow = new ServiceWindow();
29 vipWindow.setType(CustomerType.VIP);
30 vipWindow.start();
31
32 //普通客戶拿號
33 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
34 new Runnable(){
35 public void run(){
36 Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
37 /**
38 * 采用logger方式,無法看到直觀的運行效果,因為logger.log方法內部并不是直接把內容打印出出來,
39 * 而是交給內部的一個線程去處理,所以,打印出來的結果在時間順序上看起來很混亂。
40 */
41 //logger.info("第" + serviceNumber + "號普通客戶正在等待服務!");
42 System.out.println("第" + serviceNumber + "號普通客戶正在等待服務!");
43 }
44 },
45 0,
46 Constants.COMMON_CUSTOMER_INTERVAL_TIME,
47 TimeUnit.SECONDS);
48
49 //快速客戶拿號
50 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
51 new Runnable(){
52 public void run(){
53 Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();
54 System.out.println("第" + serviceNumber + "號快速客戶正在等待服務!");
55 }
56 },
57 0,
58 Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,
59 TimeUnit.SECONDS);
60
61 //VIP客戶拿號
62 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
63 new Runnable(){
64 public void run(){
65 Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();
66 System.out.println("第" + serviceNumber + "號VIP客戶正在等待服務!");
67 }
68 },
69 0,
70 Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,
71 TimeUnit.SECONDS);
72 }
73
74 }
NumberManager類:用于存在辦業務的用戶
NumberManager 1 package cn.itcast.bank;2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 public class NumberManager {
7 private int lastNumber = 0;
8 private List queueNumbers = new ArrayList();
9
10 public synchronized Integer generateNewNumber(){
11 queueNumbers.add(++lastNumber);
12 return lastNumber;
13 }
14
15 public synchronized Integer fetchNumber(){
16 if(queueNumbers.size()>0){
17 return (Integer)queueNumbers.remove(0);
18 }else{
19 return null;
20 }
21 }
22 }
NumberMachine類:老師采用的是單例的模式,單例模式(也叫單件模式)的作用就是保證在整個應用程序的生命周期中,任何一個時刻,單例類的實例都只存在一個(當然也可以不存在)。
NumberMachine 1 package cn.itcast.bank;2
3 public class NumberMachine {
4
5 private NumberMachine(){}
6 private static NumberMachine instance = new NumberMachine();
7 public static NumberMachine getInstance(){
8 return instance;
9 }
10
11 private NumberManager commonManager = new NumberManager();
12 private NumberManager expressManager = new NumberManager();
13 private NumberManager vipManager = new NumberManager();
14 public NumberManager getCommonManager() {
15 return commonManager;
16 }
17 public NumberManager getExpressManager() {
18 return expressManager;
19 }
20 public NumberManager getVipManager() {
21 return vipManager;
22 }
23
24 }
ServiceWindow類:這個類是這個程序的關鍵主要是用于模擬模擬三個窗臺的運行情況再輸出給用戶。
ServiceWindow 1 package cn.itcast.bankqueue;2
3 import java.util.Random;
4 import java.util.concurrent.Executors;
5 import java.util.logging.Logger;
6
7 /**
8 * 沒有把VIP窗口和快速窗口做成子類,是因為實際業務中的普通窗口可以隨時被設置為VIP窗口和快速窗口。
9 * */
10 public class ServiceWindow {
11 private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");
12 private CustomerType type = CustomerType.COMMON;
13 private int number = 1;
14
15 public CustomerType getType() {
16 return type;
17 }
18
19 public void setType(CustomerType type) {
20 this.type = type;
21 }
22
23 public void setNumber(int number){
24 this.number = number;
25 }
26
27 public void start(){
28 Executors.newSingleThreadExecutor().execute(
29 new Runnable(){
30 public void run(){
31 //下面這種寫法的運行效率低,最好是把while放在case下面
32 while(true){
33 switch(type){
34 case COMMON:
35 commonService();
36 break;
37 case EXPRESS:
38 expressService();
39 break;
40 case VIP:
41 vipService();
42 break;
43 }
44 }
45 }
46 }
47 );
48 }
49
50 private void commonService(){
51 String windowName = "第" + number + "號" + type + "窗口";
52 System.out.println(windowName + "開始獲取普通任務!");
53 Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();
54 if(serviceNumber != null ){
55 System.out.println(windowName + "開始為第" + serviceNumber + "號普通客戶服務");
56 int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
57 int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
58
59 try {
60 Thread.sleep(serviceTime);
61 } catch (InterruptedException e) {
62 e.printStackTrace();
63 }
64 System.out.println(windowName + "完成為第" + serviceNumber + "號普通客戶服務,總共耗時" + serviceTime/1000 + "秒");
65 }else{
66 System.out.println(windowName + "沒有取到普通任務,正在空閑一秒");
67 try {
68 Thread.sleep(1000);
69 } catch (InterruptedException e) {
70 e.printStackTrace();
71 }
72 }
73 }
74
75 private void expressService(){
76 Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();
77 String windowName = "第" + number + "號" + type + "窗口";
78 System.out.println(windowName + "開始獲取快速任務!");
79 if(serviceNumber !=null){
80 System.out.println(windowName + "開始為第" + serviceNumber + "號快速客戶服務");
81 int serviceTime = Constants.MIN_SERVICE_TIME;
82 try {
83 Thread.sleep(serviceTime);
84 } catch (InterruptedException e) {
85 e.printStackTrace();
86 }
87 System.out.println(windowName + "完成為第" + serviceNumber + "號快速客戶服務,總共耗時" + serviceTime/1000 + "秒");
88 }else{
89 System.out.println(windowName + "沒有取到快速任務!");
90 commonService();
91 }
92 }
93
94 private void vipService(){
95
96 Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber();
97 String windowName = "第" + number + "號" + type + "窗口";
98 System.out.println(windowName + "開始獲取VIP任務!");
99 if(serviceNumber !=null){
100 System.out.println(windowName + "開始為第" + serviceNumber + "號VIP客戶服務");
101 int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
102 int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
103 try {
104 Thread.sleep(serviceTime);
105 } catch (InterruptedException e) {
106 e.printStackTrace();
107 }
108 System.out.println(windowName + "完成為第" + serviceNumber + "號VIP客戶服務,總共耗時" + serviceTime/1000 + "秒");
109 }else{
110 System.out.println(windowName + "沒有取到VIP任務!");
111 commonService();
112 }
113 }
114 }
---------------------- android培訓、java培訓、期待與您交流! ---------------------- 詳細請查看:http://edu.csdn.net/heima
轉載于:https://www.cnblogs.com/tianyake/archive/2012/02/22/2363967.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的黑马程序员----银行业务调度系统面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android下发布正式包注意事项
- 下一篇: 【转载】C ++ 基础 指针 引用