黑马程序员 Java自学总结二十二 张老师7K面试题之银行业务调度系统

来源:互联网 发布:oracle sql语句别名 编辑:程序博客网 时间:2024/05/19 12:16

------ ASP.Net+Android+IO开发.Net培训期待与您交流! ------

总结内容来源于张孝祥老师的7K面试题之银行业务调度系统 

这次又把张老师的银行业务调度系统看完了 , 看完后 , 第一感觉就是要比交通灯管理系统复杂很多 , 代码量也是交通灯的两倍 , 反复的看了3遍才勉强看明白 , 感觉现阶段自己完全不可能独立做出这种系统 , 不过就像张老师说的 , 每个人最初都是模仿 , 借鉴 , 使用别人的代码 , 用的多了 , 自己的经验多了 , 以后自己就会渐渐的产生这种编程思想 , 看来最重要的还是要多敲代码 !

银行业务调度系统

系统的需求:

1.银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。

2. 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。

3. 异步随机生成各种类型的客户,生成各类型用户的概率比例为:

        VIP客户 :普通客户 :快速客户  =  1 3

4. 客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。

5.各类型客户在其对应窗口按顺序依次办理业务。 

6.当VIP6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。

7.随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。

8.不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。


系统的分析:

借用一下张老师画的类图

1 . 取号机(NumberMachine)

     取号机是唯一的 , 所以设计为单例模式 , 取号机中定义3个号码管理器(NumberManager) , 普通 , 快速, VIP

2. 号码管理器(NumberManager)

    号码管理器里有2个方法 , 一个方法generateNewNumber()负责产生号码 , 并存入集合 , 另一个方法fetchServiceNumber()负责取号.

3 . 服务窗口(ServiceWindow)

     服务窗口中创建了窗口类型的标记type , 因窗口类型只有三种 , 是固定的 , 所以就想到了创建枚举Enum , 里面3个元素分别对应3个窗口

     一个start()方法 , 用于启动窗口 , 创建线程 , 使每次启动start()方法都是独立的一个线程 , 用switch方法判断type类型 , 调用与之对应的窗口服务方法

     为每个窗口创建不同实现的方法  .

4 . main方法中, 创建4个普通窗口 , 1个快速窗口 , 1个VIP窗口 , 然后再分别创建3个定时器线程 , 来取3种类型的客户 , 客户的比例在定时器中设置 .

下面是代码: 

[java] view plaincopy
  1. package com.study.bank;  
  2. //取号机,设计为单例模式  
  3. public class NumberMachine {  
  4.     private static NumberMachine instance =new NumberMachine();  
  5.     private NumberMachine(){}     
  6.     public static NumberMachine getInstance(){  
  7.         return instance;  
  8.     }  
  9.     //定义3个号码管理器  
  10.     private NumberManager commonManager = new NumberManager();  
  11.     private NumberManager expressManager = new NumberManager();  
  12.     private NumberManager vipManager = new NumberManager();  
  13.     public NumberManager getCommonManager() {  
  14.         return commonManager;  
  15.     }  
  16.     public NumberManager getExpressManager() {  
  17.         return expressManager;  
  18.     }  
  19.     public NumberManager getVipManager() {  
  20.         return vipManager;  
  21.     }  
  22.       
  23. }  
  24. package com.study.bank;  
  25.   
  26. import java.util.ArrayList;  
  27. import java.util.List;  
  28. //号码管理器  
  29. public class NumberManager {  
  30.       
  31.     private int lastNumber = 1;  
  32.     private List<Integer> queueNumber = new ArrayList<Integer>();  
  33.     //产生号码并存入集合  
  34.     public synchronized Integer generateNewNumber(){  
  35.         queueNumber.add(lastNumber);  
  36.         return lastNumber++;  
  37.     }  
  38.     //取号,返回值类型定义成Integer的目的,防止集合中没有元素,返回null,null和int会产生NullPointException  
  39.     public synchronized Integer fetchServiceNumber(){  
  40.         if(queueNumber.size() > 0)  
  41.             return queueNumber.remove(0);  
  42.         return null;  
  43.     }  
  44. }  
  45. package com.study.bank;  
  46. //枚举,3种类型的客户  
  47. public enum CustomerType {  
  48.     COMMON,EXPRESS,VIP;  
  49.     public String toString(){  
  50.         switch(this){  
  51.         case COMMON:  
  52.             return "普通";  
  53.         case EXPRESS:  
  54.             return "快速";  
  55.         case VIP:  
  56.             return "VIP";  
  57.         }  
  58.         return null;  
  59.     }  
  60. }  
  61. package com.study.bank;  
  62. //常量值  
  63. public class Constans {  
  64.     public static int MAX_SERVICE_TIME = 10000;  
  65.     public static int MIN_SERVICE_TIME = 1000;  
  66.     public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;  
  67. }  
  68. package com.study.bank;  
  69.   
  70. import java.util.Random;  
  71. import java.util.concurrent.Executors;  
  72. //服务窗口  
  73. public class ServiceWindow {  
  74.     //区分窗口类型的变量  
  75.     private CustomerType type = CustomerType.COMMON;  
  76.     //某窗口的窗口号  
  77.     private int windowId = 1;  
  78.       
  79.     public void setType(CustomerType type) {  
  80.         this.type = type;  
  81.     }  
  82.   
  83.     public void setWindowId(int windowId) {  
  84.         this.windowId = windowId;  
  85.     }  
  86.     //窗口开始启动叫号方法,根据上面的type标记判断窗口类型,执行对应的窗口服务  
  87.     public void start(){  
  88.         Executors.newSingleThreadExecutor().execute(new Runnable(){  
  89.             public void run(){  
  90.                 while(true){  
  91.                     switch(type){  
  92.                         case COMMON:  
  93.                             commonService();  
  94.                             break;  
  95.                         case EXPRESS:  
  96.                             expressService();  
  97.                             break;  
  98.                         case VIP:  
  99.                             vipService();  
  100.                             break;  
  101.                     }                     
  102.                 }  
  103.   
  104.             }  
  105.         });  
  106.     }  
  107.     //普通窗口服务方法  
  108.     private void commonService() {  
  109.         String windowName = "第"+windowId+"号"+type+"窗口";  
  110.         Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();  
  111.         System.out.println(windowName+"正在获取任务");  
  112.         if(number != null){  
  113.             System.out.println(windowName + "正在为第" + number+ "个普通客户服务");  
  114.             long beginTime = System.currentTimeMillis();  
  115.             int maxRand = Constans.MAX_SERVICE_TIME - Constans.MIN_SERVICE_TIME;  
  116.             long serviceTime = new Random().nextInt(maxRand)+1+Constans.MIN_SERVICE_TIME;  
  117.             try {  
  118.                 Thread.sleep(serviceTime);  
  119.             } catch (InterruptedException e) {  
  120.                 e.printStackTrace();  
  121.             }  
  122.             long endTime = System.currentTimeMillis();  
  123.             long time = endTime - beginTime;  
  124.             System.out  
  125.                     .println(windowName +"为第"+number+"个普通客户完成服务,耗时"+time/1000+"秒");  
  126.         }  
  127.         else{  
  128.             System.out.println(windowName+"没有取到任务,先休息1秒钟");  
  129.             try {  
  130.                 Thread.sleep(1000);  
  131.             } catch (InterruptedException e) {  
  132.                 e.printStackTrace();  
  133.             }  
  134.         }  
  135.     }  
  136.     //快速窗口服务方法  
  137.     private void expressService() {  
  138.         String windowName = "第"+windowId+"号"+type+"窗口";  
  139.         Integer number = NumberMachine.getInstance().getExpressManager().fetchServiceNumber();  
  140.         System.out.println(windowName+"正在获取任务");  
  141.         if(number != null){  
  142.             System.out.println(windowName + "正在为第" + number+ "个" + type + "客户服务");  
  143.             long beginTime = System.currentTimeMillis();  
  144.             //int maxRand = Constans.MAX_SERVICE_TIME - Constans.MIN_SERVICE_TIME;  
  145.             //long serviceTime = new Random().nextInt(maxRand)+1+Constans.MIN_SERVICE_TIME;  
  146.             try {  
  147.                 Thread.sleep(Constans.MIN_SERVICE_TIME);  
  148.             } catch (InterruptedException e) {  
  149.                 e.printStackTrace();  
  150.             }  
  151.             long endTime = System.currentTimeMillis();  
  152.             long time = endTime - beginTime;  
  153.             System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+time/1000+"秒");  
  154.         }  
  155.         else{  
  156.             System.out.println(windowName+"没有取到任务");  
  157.             commonService();  
  158.             try {  
  159.                 Thread.sleep(1000);  
  160.             } catch (InterruptedException e) {  
  161.                 e.printStackTrace();  
  162.             }  
  163.         }  
  164.     }  
  165.     //VIP窗口服务方法  
  166.     private void vipService() {  
  167.         String windowName = "第"+windowId+"号"+type+"窗口";  
  168.         Integer number = NumberMachine.getInstance().getVipManager().fetchServiceNumber();  
  169.         System.out.println(windowName+"正在获取任务");  
  170.         if(number != null){  
  171.             System.out.println(windowName + "正在为第" + number+ "个" + type + "客户服务");  
  172.             long beginTime = System.currentTimeMillis();  
  173.             int maxRand = Constans.MAX_SERVICE_TIME - Constans.MIN_SERVICE_TIME;  
  174.             long serviceTime = new Random().nextInt(maxRand)+1+Constans.MIN_SERVICE_TIME;  
  175.             try {  
  176.                 Thread.sleep(serviceTime);  
  177.             } catch (InterruptedException e) {  
  178.                 e.printStackTrace();  
  179.             }  
  180.             long endTime = System.currentTimeMillis();  
  181.             long time = endTime - beginTime;  
  182.             System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+time/1000+"秒");  
  183.         }  
  184.         else{  
  185.             System.out.println(windowName+"没有取到任务");  
  186.             commonService();  
  187.             try {  
  188.                 Thread.sleep(1000);  
  189.             } catch (InterruptedException e) {  
  190.                 e.printStackTrace();  
  191.             }  
  192.         }  
  193.     }  
  194. }  
  195. package com.study.bank;  
  196.   
  197. import java.util.concurrent.Executors;  
  198. import java.util.concurrent.TimeUnit;  
  199.   
  200. public class MainClass {  
  201.   
  202.     public static void main(String[] args) {  
  203.         for(int i=1; i<5; i++){  
  204.             ServiceWindow commonWindow = new ServiceWindow();  
  205.             commonWindow.setType(CustomerType.COMMON);  
  206.             commonWindow.setWindowId(i);  
  207.             commonWindow.start();  
  208.         }  
  209.           
  210.         ServiceWindow expressWindow = new ServiceWindow();  
  211.         expressWindow.setType(CustomerType.EXPRESS);  
  212.         expressWindow.setWindowId(5);  
  213.         expressWindow.start();  
  214.           
  215.         ServiceWindow vipWindow = new ServiceWindow();  
  216.         vipWindow.setType(CustomerType.VIP);  
  217.         vipWindow.setWindowId(6);  
  218.         vipWindow.start();  
  219.           
  220.         Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
  221.                 new Runnable(){  
  222.                     public void run(){  
  223.                         Integer number = NumberMachine.getInstance().getCommonManager().generateNewNumber();  
  224.                         System.out.println(number + "号普通客户等待服务");  
  225.                     }  
  226.                 },  
  227.                 0,  
  228.                 Constans.COMMON_CUSTOMER_INTERVAL_TIME,  
  229.                 TimeUnit.SECONDS);  
  230.           
  231.         Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
  232.                 new Runnable(){  
  233.                     public void run(){  
  234.                         Integer number = NumberMachine.getInstance().getExpressManager().generateNewNumber();  
  235.                         System.out.println(number + "号快速客户等待服务");  
  236.                     }  
  237.                 },  
  238.                 0,  
  239.                 Constans.COMMON_CUSTOMER_INTERVAL_TIME*2,  
  240.                 TimeUnit.SECONDS);  
  241.           
  242.         Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
  243.                 new Runnable(){  
  244.                     public void run(){  
  245.                         Integer number = NumberMachine.getInstance().getVipManager().generateNewNumber();  
  246.                         System.out.println(number + "号VIP客户等待服务");  
  247.                     }  
  248.                 },  
  249.                 0,  
  250.                 Constans.COMMON_CUSTOMER_INTERVAL_TIME*6,  
  251.                 TimeUnit.SECONDS);  
  252.           
  253.           
  254.     }  
  255. }  



------ ASP.Net+Android+IO开发.Net培训期待与您交流! ------

原创粉丝点击