银行业务调度系统的项目
2015-10-09 19:26
399 查看
这是我第一个博客,这个是从其他网站上找来的资料,并用自己的理解来写的,有很多不对的地方请包涵,最后我会附上 张孝祥-7K月薪面试题破解之二_银行业务调度系统视频教程 原文件。
银行业务调度系统的项目需求
模拟实现银行业务调度系统逻辑,具体需求如下:
*银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)
各类型客户在其对应窗口按顺序依次办理业务。
当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。*
分析该需求,java是面向对象,我们需要从该需求中找到相关的对象,然后在从其中找属性和方法。
结合实际,我们可以找到客户类,窗口类,机器类(该类是从实际情况中分析出来的)。
客户类属性:姓名
窗口类属性:窗口编号,窗口姓名。
机器类属性:该机器中有三个管理类,一个是普通号管理类,一个是快速管理类,一个是VIP管理类,管理类中包涵了来的客户的编号,和需要维护的客户队列。
这个分析是慢慢的积累出来的,也有一些课程来,比如UML中类的课程就讲了怎样找类和类的属性、方法。而且找类后在实际编写代码时都有可能在分出类来,这些类是实际需要。
客户类:由于该程序很小,客户类中没有其他的东西,只有一个名字属性,并且不需要客户该对象。这里我们可以创建一个enum,该类中有三个COMMON,FAST,VIP分别表示普通客户,快速客户,vip客户。
该类中我没有进行优化。所有每个窗口进行叫号,这样,因为有三个窗口,这样我们进行一下区分,进行start()方法,进入start()中后,会进行判断那一个窗口,并进行相应的方法。
普通窗口叫号时,先取出号码,并判断是否有该号码,没有则等待一分钟在叫,有那么就行该客户服务。该客户服务有一个时间,根据需求,需要在最小时间和最大时间之间的随机值。随后就结束服务。
快速窗口叫号时,先取出号码,并判断是否有该号码,没有,这时需要去询问是否有普通客户,此时直接调用普通窗口叫号服务,有那么就行该客户服务。该客户服务有一个时间,根据需求,直接是最小时间。
快速窗口叫号时,先取出号码,并判断是否有该号码,没有,这时需要去询问是否有普通客户,此时直接调用普通窗口叫号服务,有那么就行该客户服务。该客户服务有一个时间,根据需求,需要在最小时间和最大时间之间的随机值。随后就结束服务。
此时该服务类就可以完成。其中会发现如何去得到一个号码呢。该号码是有机器产生的,这时就需要创建机器类,机器类中来创建一个号码管理器,该号码管理器是管理每个到来客户的一个信息的,比如普通客户到时机器到了几号了,同时要维护每次到来客户的队列。该号码管理器能够产生两个方法,取号,产生号码方法。如下:
机器管理类只需维护三个号码管理器就可以了,在实际中机器只有一台,那么该处用到单例,单例的方法如下:
private Class(){}
private static Class mInstance;
public static Class getInstance(){
if(mInstance == null){//Class为类名
mInstance = new Class();
}
return mInstance;
}
机器管理类如下:
这里有个常量类:
那么这时完成大部分功能了,有一个功能没有完成,那是怎样随机产生客户,这个会在主方法中完成:
主方法要完成两个功能:
分别创建6个窗口;
按要求产生客户;
按比例产生号码,我想到了使用scheduleAtFixedRate,该方法是周期性的完成任务。其中调用时,有四个参数,一个参数是Runnable,是要完成需要执行的方法,initialDelay 初始延迟时间,period周期,TimeUnit周期的时间单位。
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
}
}, 0, 1, TimeUnit.SECONDS);
这是该方法的调用。
总结:
第一结合实际我们要找到有哪几个类,并且确定该类要完成的那个属性和方法。那个接下来的工作就很简单了。
那面我就是找到几个类,最后在主方法中进行创建相关的对象。这里还需要有一些经验的地方是scheduleAtFixedRate,该方法的使用。
大家可以下在下列视屏看
参考:
张孝祥-7K月薪面试题破解之二_银行业务调度系统视频教程
银行业务调度系统的项目需求
模拟实现银行业务调度系统逻辑,具体需求如下:
*银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)
各类型客户在其对应窗口按顺序依次办理业务。
当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。*
分析该需求,java是面向对象,我们需要从该需求中找到相关的对象,然后在从其中找属性和方法。
结合实际,我们可以找到客户类,窗口类,机器类(该类是从实际情况中分析出来的)。
客户类属性:姓名
窗口类属性:窗口编号,窗口姓名。
机器类属性:该机器中有三个管理类,一个是普通号管理类,一个是快速管理类,一个是VIP管理类,管理类中包涵了来的客户的编号,和需要维护的客户队列。
这个分析是慢慢的积累出来的,也有一些课程来,比如UML中类的课程就讲了怎样找类和类的属性、方法。而且找类后在实际编写代码时都有可能在分出类来,这些类是实际需要。
客户类:由于该程序很小,客户类中没有其他的东西,只有一个名字属性,并且不需要客户该对象。这里我们可以创建一个enum,该类中有三个COMMON,FAST,VIP分别表示普通客户,快速客户,vip客户。
public enum Customer { COMMON, FAST, VIP; public String toString() { String name = null; switch (this) { case COMMON: name = "普通"; case FAST: name = "快速"; case VIP: name = name(); } return name; } } 该enum中重写了toString()方法,这是用户返回一组汉字。 这样客户类创建好了 窗口类中属性窗口编号,窗口名称 方法:叫号方法 从实际中,我们可以发现银行的窗口叫号,然后客户才来 public class WindonService { private Customer name = Customer.COMMON; //窗口名称 private int number = 1; //窗口编号 /** * 要完成的任务 */ public void start(){ //开启线程来完成 Executors.newSingleThreadExecutor().execute(new Runnable() { @Override public void run() { while(true){ switch (name) { case COMMON: commonService(); break; case FAST: fastService(); break; case VIP: vipService(); break; } } } }); } /** *vip窗口叫号服务 */ protected void vipService() { String windonservice = "第" + number + "号" + name + "窗口"; System.out.println(windonservice + ",开始获取vip服务!"); //取号 Integer serviceNumber = NumberMachine.getIntance().getVipManager().fetchNumber(); //判断号码是否为空,如果为空,就等待一段时间 if (serviceNumber != null) { System.out.println(windonservice+ "正在为第" + serviceNumber+"vip客户服务"); //计算服务时间 //服务时间 int randomTime = Constans.MAX_TIME - Constans.MIN_TIME; int ServiceTime = new Random().nextInt(randomTime)+1 + Constans.MIN_TIME; try { Thread.sleep(ServiceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(windonservice + "为第" + serviceNumber + "vip客户服务" + ServiceTime/1000 +"时间"); }else { System.out.println("没有取到vip任务,等待一秒钟"); //取到普通号码,则服务普通号码 commonService(); } } /** * 快速窗口叫号服务 */ protected void fastService() { String windonservice = "第" + number + "号" + name + "窗口"; System.out.println(windonservice + ",开始获取快速服务!"); //取号 Integer serviceNumber = NumberMachine.getIntance().getFastManager().fetchNumber(); //判断号码是否为空,如果为空,就等待一段时间 if (serviceNumber != null) { System.out.println(windonservice+ "正在为第" + serviceNumber+"快速客户服务"); //快速服务时间为最小时间 int serviceTime = Constans.MIN_TIME; try { Thread.sleep(serviceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(windonservice + "为第" + serviceNumber + "快速客户服务" + serviceTime/1000 +"时间"); }else { System.out.println("没有取到快速任务,等待一秒钟"); //快速窗口没有取到快速客户的号码,则试着去取普通号码 //取到普通号码,则服务普通号码 commonService(); } } /** * 普通窗口的服务 */ protected void commonService() { String windonservice = "第" + number + "号" + name + "窗口"; System.out.println(windonservice + ",开始获取普通服务!"); //取号 Integer serviceNumber = NumberMachine.getIntance().getCommonManager().fetchNumber(); //判断号码是否为空,如果为空,就等待一段时间 if (serviceNumber != null) { System.out.println(windonservice+ "正在为第" + serviceNumber+"普通客户服务"); //计算服务时间 //服务时间 int randomTime = Constans.MAX_TIME - Constans.MIN_TIME; int ServiceTime = new Random().nextInt(randomTime)+1 + Constans.MIN_TIME; try { Thread.sleep(ServiceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(windonservice + "为第" + serviceNumber + "普通客户服务" + ServiceTime/1000 +"时间"); }else { System.out.println("没有取到普通任务,等待一秒钟"); try { Thread.sleep(1000); //等待一秒钟 } catch (InterruptedException e) { e.printStackTrace(); } } } // --------------------------------------------- public Customer getName() { return name; } public void setName(Customer name) { this.name = name; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } }
该类中我没有进行优化。所有每个窗口进行叫号,这样,因为有三个窗口,这样我们进行一下区分,进行start()方法,进入start()中后,会进行判断那一个窗口,并进行相应的方法。
普通窗口叫号时,先取出号码,并判断是否有该号码,没有则等待一分钟在叫,有那么就行该客户服务。该客户服务有一个时间,根据需求,需要在最小时间和最大时间之间的随机值。随后就结束服务。
快速窗口叫号时,先取出号码,并判断是否有该号码,没有,这时需要去询问是否有普通客户,此时直接调用普通窗口叫号服务,有那么就行该客户服务。该客户服务有一个时间,根据需求,直接是最小时间。
快速窗口叫号时,先取出号码,并判断是否有该号码,没有,这时需要去询问是否有普通客户,此时直接调用普通窗口叫号服务,有那么就行该客户服务。该客户服务有一个时间,根据需求,需要在最小时间和最大时间之间的随机值。随后就结束服务。
此时该服务类就可以完成。其中会发现如何去得到一个号码呢。该号码是有机器产生的,这时就需要创建机器类,机器类中来创建一个号码管理器,该号码管理器是管理每个到来客户的一个信息的,比如普通客户到时机器到了几号了,同时要维护每次到来客户的队列。该号码管理器能够产生两个方法,取号,产生号码方法。如下:
public class NumberManager { private Integer lastNumber = 0; private List<Integer> queueNumber = new ArrayList<Integer>(); /** * 生成号码 */ public synchronized Integer generateNumber(){ queueNumber.add(++lastNumber); return lastNumber; } /** * 取号码 * @return */ public synchronized Integer fetchNumber(){ if (queueNumber.size() > 0) { return queueNumber.remove(0); }else { return null; } } }
机器管理类只需维护三个号码管理器就可以了,在实际中机器只有一台,那么该处用到单例,单例的方法如下:
private Class(){}
private static Class mInstance;
public static Class getInstance(){
if(mInstance == null){//Class为类名
mInstance = new Class();
}
return mInstance;
}
机器管理类如下:
public class NumberMachine { /** * 由于叫号机器只有一台,必须给其创建单利 * 机器可以生成三种不同号码,普通号码,快速号码,vip号码 */ private NumberMachine(){} private static NumberMachine mInstance; public static NumberMachine getIntance(){ if (mInstance== null) { mInstance = new NumberMachine(); } return mInstance; } private NumberManager commonManager = new NumberManager(); private NumberManager fastManager = new NumberManager(); private NumberManager vipManager = new NumberManager(); public NumberManager getCommonManager() { return commonManager; } public NumberManager getFastManager() { return fastManager; } public NumberManager getVipManager() { return vipManager; } }
这里有个常量类:
public class Constans { public static final int MAX_TIME = 10000; //最大服务时间是10秒 public static final int MIN_TIME = 1000; //最小服务时间是1秒 }
那么这时完成大部分功能了,有一个功能没有完成,那是怎样随机产生客户,这个会在主方法中完成:
主方法要完成两个功能:
分别创建6个窗口;
按要求产生客户;
按比例产生号码,我想到了使用scheduleAtFixedRate,该方法是周期性的完成任务。其中调用时,有四个参数,一个参数是Runnable,是要完成需要执行的方法,initialDelay 初始延迟时间,period周期,TimeUnit周期的时间单位。
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
}
}, 0, 1, TimeUnit.SECONDS);
这是该方法的调用。
public static void main(String[] args) { /** * 创建出6个窗口来 * 然后机器运行起来,生成号码 */ for (int i = 1; i < 5; i++) { //创建4个普通窗口 WindonService commonService = new WindonService(); commonService.setName(Customer.FAST); commonService.start(); } WindonService fastService = new WindonService(); //创建1个快速窗口 fastService.setName(Customer.VIP); fastService.start(); WindonService vipService = new WindonService(); //创建1个vip窗口 vipService.setNumber(1); vipService.start(); Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { @Override public void run() { Integer serviceNumber = NumberMachine.getIntance().getCommonManager().generateNumber(); System.out.println("第" + serviceNumber + "号普通客户正在等待服务!"); } }, 0, 1, TimeUnit.SECONDS); Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { @Override public void run() { Integer serviceNumber = NumberMachine.getIntance().getFastManager().generateNumber(); System.out.println("第" + serviceNumber + "号快速客户正在等待服务!"); } }, 0, 3, TimeUnit.SECONDS); Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { @Override public void run() { Integer serviceNumber = NumberMachine.getIntance().getVipManager().generateNumber(); System.out.println("第" + serviceNumber + "号vip客户正在等待服务!"); } }, 0, 6, TimeUnit.SECONDS); }
总结:
第一结合实际我们要找到有哪几个类,并且确定该类要完成的那个属性和方法。那个接下来的工作就很简单了。
那面我就是找到几个类,最后在主方法中进行创建相关的对象。这里还需要有一些经验的地方是scheduleAtFixedRate,该方法的使用。
大家可以下在下列视屏看
参考:
张孝祥-7K月薪面试题破解之二_银行业务调度系统视频教程
相关文章推荐
- 新注册
- 四大漏洞入侵博客
- 在Ubuntu系统上安装Ghost博客平台的教程
- PHP多用户博客系统分析[想做多用户博客的朋友,需要了解]第1/3页
- 基于CakePHP实现的简单博客系统实例
- 基于jsp+servlet实现的简单博客系统实例(附源码)
- csdn 博客的css样式 v3
- 如何使用Gitblog和Markdown建自己的博客
- Flask入门教程实例:搭建一个静态博客
- 让写博客成为一种习惯
- 使用微信快捷登录Wordpress博客
- 博客之前在网易安家,现在迁移到了自己开发的blog http://blog.tongbor.com
- OpenAPI 之 开源软件信息预览 ProjectTips
- 自己对博客的计划
- 做一份30字的简历
- 从主流到边缘,博客为什么不行了?
- 里程碑:博客文章阅读数突破1000万
- 博客恢复访问通知!
- 博客更新主题通知!