黑马程序员_7k面试之银行调度

------- 物联云培训java培训、期待与您交流! ----------  

项目名称:银行业务调度系统

项目内容要求:

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

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

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

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

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

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

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

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

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

用面向对象的方法分析:题目设计到的对象有窗口、出号码器、号码管理器他们之间的联系如图:


分析号码管理器:号码管理器主要用于产生号码和取出号码,因为号码是保持先进先出的原则,所以定义一个List集合用于存储号码。然后把最前面的号码取出。

代码如下:

importjava.util.ArrayList;
importjava.util.List;
publicclass NumberCollect {
   private int number=0;
   private List<Integer> number_list=new ArrayList<Integer>();
//产生号码
   public synchronizedInteger conmuctionNumber(){
      number_list.add(++number);//把号码添加到集合中。
      return number;
   }
//获取号码
   public synchronizedInteger bankNumber(){
      IntegernewNumber=null;
      if(number_list.size()>0)
         newNumber=(Integer)number_list.remove(0);//获取最前面的号码
      return newNumber;
   }
}

分析出号器:从名字就可以看出他的主要用途就是用户让客户取号排队,取号之前首先要有号,所以该类内部封装了号码管理器的对象。按题目有三种客户,那么就要有三个号码管理器的对象,分开管理。有利于管理维护。出号器只有一个,所以不能自主创建对象,且对象固定,想到用单例模式可以解决。

代码如下:

publicclass NumberMachion {
   private NumberCollect common=new NumberCollect();//定义普通号码
   private NumberCollect qucly=new NumberCollect();//定义快速号码
   private NumberCollect VIP=new NumberCollect();//定义VIP号码
   public NumberCollect getCommon() {
      return common;
   }
   public NumberCollect getQucly() {
      return qucly;
   }
   public NumberCollect getVIP() {
      return VIP;
   }
   private NumberMachion(){}//私有构造函数,不让外界创建
   private static NumberMachion numbermachion=newNumberMachion();                //自己创建
   public static NumberMachion getNumberMachion(){//获取本类对象
      return numbermachion;
   }
}

分析窗口类:因为有三种不同的窗口,分别为:普通窗口、快速窗口、VIP窗口。他们都是固定的,把他们封装成了一个枚举类,定义窗口的服务对象及服务事件。

窗口类代码如下:

importjava.util.Random;
importjava.util.concurrent.Executors;
 
publicclass ServerWindow {
   private int number=1;
   private ConmuctionType type=ConmuctionType.common;
   public void setNumber(intnumber) {
      this.number = number;
   }
   public void setType(ConmuctionType type) {
      this.type = type;
   }
   public void start(){
      Executors.newSingleThreadExecutor().execute(
      new Runnable(){
         public void run(){
                while(true){
                switch(type){
                case common:
                   commonServer();
                   break;
                case qucly:
                   quclyServer();
                   break;
                case VIP:
                   VIPServer();
                   break;
                }
            }
         }       
      });
   }
   //为普通用户服务
   private void commonServer() {
            // TODOAuto-generated method stub
      System.out.println("第"+number+"号"+type+"窗口正在为普通客户服务");
      Integerconmuction=NumberMachion.getNumberMachion().getCommon().bankNumber();
      if(conmuction!=null){
         System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号普通客户服务");
         long servertime=(new Random().nextInt(StaticTime.LONG_TIME-StaticTime.SHRIT_TIME))+1+StaticTime.SHRIT_TIME;
         try {
            Thread.sleep(servertime);
         } catch (InterruptedException e) {
            // TODOAuto-generated catch block
            e.printStackTrace();
         }
         System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号普通客户服务...............结束");
      }
      else{
         System.out.println("第"+number+"号"+type+"窗口没有取到普通任务........休息一秒");
         try {
            Thread.sleep(10000);
         } catch (InterruptedException e) {
            // TODOAuto-generated catch block
            e.printStackTrace();
         }
      }    
         }
//为快速用户服务
   private void quclyServer() {
            // TODOAuto-generated method stub
      System.out.println("第"+number+"号"+type+"窗口正在为快速客户服务");
      Integerconmuction=NumberMachion.getNumberMachion().getQucly().bankNumber();
      if(conmuction!=null){
         System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号快速客户服务");
         //long servertime=(new Random().nextInt())*StaticTime.SHRIT_TIME+1+(StaticTime.LONG_TIME-StaticTime.SHRIT_TIME);
         try {
            Thread.sleep(StaticTime.SHRIT_TIME);
         } catch (InterruptedException e) {
            // TODOAuto-generated catch block
            e.printStackTrace();
         }
         System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号快速客户服务...............结束");
      }
      else{
        
         System.out.println("第"+number+"号"+type+"窗口没有取到快速任务........休息一秒");
         try {
            Thread.sleep(1000);
         } catch (InterruptedException e) {
            // TODOAuto-generated catch block
            e.printStackTrace();
         }
         commonServer();
      }    
         }
//为VIP窗口用户服务
   private void VIPServer() {
            // TODOAuto-generated method stub
      System.out.println("第"+number+"号"+type+"窗口正在为VIP客户服务");
      Integer conmuction=NumberMachion.getNumberMachion().getVIP().bankNumber();
      if(conmuction!=null){
         System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号VIP客户服务");
         long servertime=(new Random().nextInt(StaticTime.LONG_TIME-StaticTime.SHRIT_TIME))+1+StaticTime.SHRIT_TIME;
         try {
            Thread.sleep(servertime);
         } catch (InterruptedException e) {
            // TODOAuto-generated catch block
            e.printStackTrace();
         }
         System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号VIP客户服务...............结束");
      }
      else{
        
         System.out.println("第"+number+"号"+type+"窗口没有取到VIP任务........休息一秒");
         try {
            Thread.sleep(1000);
         } catch (InterruptedException e) {
            // TODOAuto-generated catch block
            e.printStackTrace();
         }
         commonServer();
      }    
         }
}

定义窗口类型及客户类型的类

代码如下:

publicenum ConmuctionType {
   common,qucly,VIP;
   public String toString(){
      String name=null;
      switch(this){
      case common:
         name="普通";
         break;
      case qucly:
         name="快速";
         break;
      case VIP:
         name="VIP";
         break;
      }
      return name;
   }
 
}

定义常量类:

代码如下:

publicclass StaticTime {
   public static intLONG_TIME=10000;
   public static intSHRIT_TIME=1000;
   public static intconmuction_time=1;
 
}
测试类:

importjava.util.concurrent.Executors;
importjava.util.concurrent.TimeUnit;
 
publicclass MainClassDemo {
 
   /**
    * @param args
    */
   public static voidmain(String[] args) {
      // TODOAuto-generated method stub
      for(int i = 1;i<5;i++){
         ServerWindowsw=new ServerWindow(); //产生普通窗口
         sw.setNumber(i);
         sw.start();
      }
      //产生快速窗口
      ServerWindowqucly=new ServerWindow();
      qucly.setType(ConmuctionType.qucly);
      qucly.start();
      //产生VIP窗口
ServerWindow vip=newServerWindow();
      vip.setType(ConmuctionType.VIP);
      vip.start();
 //模拟普通用户取票
      Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
            new Runnable(){
                public void run(){
                   Integernumber=NumberMachion.getNumberMachion().getCommon().conmuctionNumber();
                   System.out.println("第"+number+"号普通客户等待服务..");
                }
            },
            0,
            StaticTime.conmuction_time,
            TimeUnit.SECONDS);
//模拟快速用户取票
      Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
            new Runnable(){
                public void run(){
                   Integernumber=NumberMachion.getNumberMachion().getQucly().conmuctionNumber();
                   System.out.println("第"+number+"号快速客户等待服务..");
                }
            },
            0,
            StaticTime.conmuction_time*2,
            TimeUnit.SECONDS);
//模拟VIP用户取票
      Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
            new Runnable(){
                public void run(){
                   Integernumber=NumberMachion.getNumberMachion().getVIP().conmuctionNumber();
                   System.out.println("第"+number+"号VIP客户等待服务..");
                }
            },
            0,
            StaticTime.conmuction_time*6,
            TimeUnit.SECONDS);
   }
}

运行结果:


不足之处:号码管理器类,它是用来产生号码和取出号码,当他对外暴露时,会引起系统的安全隐患,如果有非法人员(或操作错误)可能会导致银行系统错乱,所以这个类应当进行隐藏。隐藏方法有:将其抽象化,将其变为接口,封装成出号器的内部类。我在这里将其抽象化。

号码管理器代码:

import java.util.ArrayList;
import java.util.List;
public abstract class NumberCollect {
    private  int number=0;
    private  List<Integer> number_list=new ArrayList<Integer>();
    public  synchronized Integer conmuctionNumber(){
       number_list.add(++number);
       return number;
    }
    public  synchronized Integer bankNumber(){
       Integer newNumber=null;
       if(number_list.size()>0)
           newNumber=(Integer)number_list.remove(0);
       return newNumber;
    }
}

出号器代码:

publicclass NumberMachion {
   private NumberCollect common=new NumberCollect(){};
   private NumberCollect qucly=new NumberCollect(){};
   private NumberCollect VIP=new NumberCollect(){};
   public NumberCollect getCommon() {
      return common;
   }
   public NumberCollect getQucly() {
      return qucly;
   }
   public NumberCollect getVIP() {
      return VIP;
   }
   private NumberMachion(){}
   private static NumberMachion numbermachion=newNumberMachion();
   public static NumberMachion getNumberMachion(){
      return numbermachion;
   }
}
运行结果:


总结:因为想到有三种不同的号码,并且只有一个取号的机子,所以想到了一个号码管理器来管理这三种号码。并且把号码管理器定义成单例。因为有三种不同的固定窗口,所以想到了枚举。

通过银行调度系统是我更加明白了“谁拥有数据就把方法定义在谁身上”。

自我思考与总结:当接到项目是不应急于编写代码,代码是次要的,思想才是主要的。思想决定着代码的好坏、系统的优略。充分的认识项目的目的也是提到编码效率的手段。要充分的认识事物的本质。项目的主要用途也是我们考虑在内的的,有的用于网络视屏,这样的我们可以适当的降低安全性,而主要提高数据传输速度;有的用于银行,这样的系统我们就要着重的考虑系统的安全性。具体情况还需具体分析。


------- 物联云培训java培训、期待与您交流! ----------  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值