模拟银行某一时段的服务流程 ---- IBM面试题
2013-06-04 20:23
525 查看
注:本博客内容没有通过面试,呵呵...请不要盲信博客内容!!!
这段时间一直在找工作,说实话现在行情真不是太好,叫我去面试的大都是外包公司,而我又不很喜欢做外包,所以很郁闷,也挺焦急...这是背景。
今天下午又接到一外包公司的面试电话,是外包到IBM的,不知什么原因没有推掉,于是负责招聘的MM发来一道IBM的试题,说是做完让那边看完之后才能安排面试。于是乎,忙活了好大一会子,终于将其解决。
由于以前没做银行项目,对于并发这块也不是很熟悉,所以解决方式很别扭,也不知道是否对题目理解正确,现将解决方案发表于此,请大家指正。
银行有4个服务窗口,其中有三个是普通窗口,一个是VIP窗口。VIP窗口在没有VIP用户时也可以当作普通服务窗口办理业务。银行的服务流程描述如下:
首先到达的客户需要在门口领取一张号码纸,号码纸上写明了前面排队的人数和你的号码。
客户等待自己被服务。如果号码纸的的号码过期,即当前的号码大于号码纸的号码,则号码纸就过期了
如果VIP用户到达后,VIP用户进入VIP窗口办理,如果VIP窗口前面有其他的VIP用户,则排在其他VIP用户之后,如果有普通会员在办理,则服务完成后立刻服务VIP用户。
银行的业务员在服务完一个客户后,会根据号码纸依次通知下一个客户进行服务
用户的数据放在一个文本文件中
类似于如下所示(各列依次为:次序、客户类型、到达时间、服务时间):
接着给出两个窗口类(VIP窗口和普通窗口),业务窗口类实现了Runnable接口,表示这是一个任务;在窗口中循环从客户端获取下一个客户(VIP窗口获取下一个VIP客户,如果接下来没有VIP客户了,则获取普通客户),如果客户存在则打印服务列表,然后休眠客户服务时长,如果接下来再没有客户了,则该窗口关闭(线程结束)。
VIP窗口:
普通窗口:
最后是客户端代码,用一个LinkedList类存储解析得到的所有客户(可将其作为队列使用),然后在static代码块中解析客户信息文件并填充LinkedList,最后在main方法中创建了三个普通窗口线程和一个VIP窗口线程,丢进执行器ExecutorService 中:
这段时间一直在找工作,说实话现在行情真不是太好,叫我去面试的大都是外包公司,而我又不很喜欢做外包,所以很郁闷,也挺焦急...这是背景。
今天下午又接到一外包公司的面试电话,是外包到IBM的,不知什么原因没有推掉,于是负责招聘的MM发来一道IBM的试题,说是做完让那边看完之后才能安排面试。于是乎,忙活了好大一会子,终于将其解决。
由于以前没做银行项目,对于并发这块也不是很熟悉,所以解决方式很别扭,也不知道是否对题目理解正确,现将解决方案发表于此,请大家指正。
试题信息
要求
请在一个小时内完成。问题描述
请模拟银行某一时段的服务流程银行有4个服务窗口,其中有三个是普通窗口,一个是VIP窗口。VIP窗口在没有VIP用户时也可以当作普通服务窗口办理业务。银行的服务流程描述如下:
首先到达的客户需要在门口领取一张号码纸,号码纸上写明了前面排队的人数和你的号码。
客户等待自己被服务。如果号码纸的的号码过期,即当前的号码大于号码纸的号码,则号码纸就过期了
如果VIP用户到达后,VIP用户进入VIP窗口办理,如果VIP窗口前面有其他的VIP用户,则排在其他VIP用户之后,如果有普通会员在办理,则服务完成后立刻服务VIP用户。
银行的业务员在服务完一个客户后,会根据号码纸依次通知下一个客户进行服务
用户的数据放在一个文本文件中
类似于如下所示(各列依次为:次序、客户类型、到达时间、服务时间):
1 普通 09:00 5 2 普通 09:00 6 3 普通 09:00 5 4 普通 09:02 9 5 普通 09:04 5 6 VIP 09:05 7 7 普通 09:10 5 8 普通 09:12 10 9 普通 09:15 5 10 VIP 09:18 5 11 普通 09:18 8 12 普通 09:19 5
输出
请输出每一个窗口的服务客户列表,以及每一个客户的等待时间解决方案
首先定义客户类,客户类型以枚举表示,个人觉得题目不算复杂,因此并没有好好设计,没有将客户类抽象出父类,而是VIP客户和普通客户都由此类表示:package com.ibm.bank; import java.util.Date; /** * 客户类, 例子比较简单, 没有再提取父类, VIP和普通客户都用此类代表, 以customType区分. * @author zyh */ public class Custom implements Comparable<Custom>{ private Long order; // 客户次序 private CustomType customType; // 客户类型 private Date arrivalDate; // 到达时间 private int serviceTime; // 服务时长 public long getOrder() { return order; } public void setOrder(long order) { this.order = order; } public CustomType getCustomType() { return customType; } public void setCustomType(CustomType customType) { this.customType = customType; } public Date getArrivalDate() { return arrivalDate; } public void setArrivalDate(Date arrivalDate) { this.arrivalDate = arrivalDate; } public int getServiceTime() { return serviceTime; } public void setServiceTime(int serviceTime) { this.serviceTime = serviceTime; } @Override public int compareTo(Custom o) { return this.order.compareTo(o.order); } } /** * 客户类型枚举类 * @author zyh */ enum CustomType { VIP("the VIP custom."), COMMON("the COMMON custom."); private String description; private CustomType(String desc) { this.description = desc; } public String getDescription() { return this.description; } @Override public String toString() { return this.description; } }
接着给出两个窗口类(VIP窗口和普通窗口),业务窗口类实现了Runnable接口,表示这是一个任务;在窗口中循环从客户端获取下一个客户(VIP窗口获取下一个VIP客户,如果接下来没有VIP客户了,则获取普通客户),如果客户存在则打印服务列表,然后休眠客户服务时长,如果接下来再没有客户了,则该窗口关闭(线程结束)。
VIP窗口:
package com.ibm.bank; import java.util.concurrent.TimeUnit; /** * VIP窗口, 办理VIP用户业务, 如果没有VIP用户在等待, 也可以办理普通用户业务. * @author zyh */ public class VIPWindow implements Runnable { private Client client; public VIPWindow(Client client) { this.client = client; } @Override public void run() { Custom cs = null; while ((cs = client.nextCustom(CustomType.VIP)) != null) { long waitedTime = System.currentTimeMillis() - client.getServiceStartTime(); try { System.out.println("VIP Window is Servicing for Custom " + cs.getOrder() + ", Custom Type: " + cs.getCustomType().name() + ", arrival time: " + String.format("%1$tF %1$tR", cs.getArrivalDate()) + ", waited time: " + waitedTime/1000 + "S"); // 服务时间 TimeUnit.MINUTES.sleep(cs.getServiceTime()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
普通窗口:
package com.ibm.bank; import java.util.concurrent.TimeUnit; /** * 普通用户窗口 * @author zyh */ public class GeneralWindow implements Runnable { private String windowName; private Client client; public GeneralWindow(Client client, String winName) { this.client = client; this.windowName = winName; } public void run() { Custom cs = null; while((cs = client.nextCustom(CustomType.COMMON)) != null) { long waitedTime = System.currentTimeMillis() - client.getServiceStartTime(); try { System.out.println("General Window(" + this.windowName + ") is Servicing for Custom " + cs.getOrder() + ", Custom Type: " + cs.getCustomType().name() + ", arrival time: " + String.format("%1$tF %1$tR", cs.getArrivalDate()) + ", waited time: " + waitedTime/1000 + "S"); TimeUnit.MINUTES.sleep(cs.getServiceTime()); } catch (InterruptedException e) { e.printStackTrace(); } } } public String getWindowName() { return windowName; } public void setWindowName(String windowName) { this.windowName = windowName; } }
最后是客户端代码,用一个LinkedList类存储解析得到的所有客户(可将其作为队列使用),然后在static代码块中解析客户信息文件并填充LinkedList,最后在main方法中创建了三个普通窗口线程和一个VIP窗口线程,丢进执行器ExecutorService 中:
package com.ibm.bank; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Calendar; import java.util.LinkedList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Client { private static LinkedList<Custom> customList = new LinkedList<Custom>(); private Long serviceStartTime; public Long getServiceStartTime() { return serviceStartTime; } public Client() { serviceStartTime = System.currentTimeMillis(); } static { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/ibm/bank/customs.txt"); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); try { String line = reader.readLine(); String regex = "^\\d{1,2} [\\u4E00-\\u9FFF|\\w]{2,3} \\d{2}:\\d{2} \\d{1,}$"; Calendar calendar = Calendar.getInstance(); while(null != line && line.matches(regex)) { String [] customInfo = line.split(" "); Custom custom = new Custom(); custom.setOrder(Long.parseLong(customInfo[0])); custom.setServiceTime(Integer.parseInt(customInfo[3])); if (customInfo[1].equals("VIP")) { custom.setCustomType(CustomType.VIP); } else { custom.setCustomType(CustomType.COMMON); } String [] time = customInfo[2].split(":"); calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0])); calendar.set(Calendar.MINUTE, Integer.parseInt(time[1])); custom.setArrivalDate(calendar.getTime()); customList.offer(custom); line = reader.readLine(); } } catch (IOException e) { e.printStackTrace(); } finally { if (null != reader) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void main(String[] args) { Client client = new Client(); ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new GeneralWindow(client, "第1普通窗口")); executorService.execute(new GeneralWindow(client, "第2普通窗口")); executorService.execute(new GeneralWindow(client, "第3普通窗口")); executorService.execute(new VIPWindow(client)); executorService.shutdown(); } /** * 获取下一个客户 * @param customType 客户类型 * @return VIP窗口或者普通窗口要服务的下一个客户 */ public synchronized Custom nextCustom(CustomType customType) { if (customType == CustomType.VIP) { Custom cs; int index = 0; while (index < customList.size() && (cs = customList.get(index++)) != null) { if (customType == cs.getCustomType()) { customList.remove(cs); return cs; } } } return customList.poll(); } }
相关文章推荐
- 银行ATM机工作流程模拟编程(代码)
- 向Web Service进军--Axis Tomcat模拟一个银行存取款服务
- 迅雷面试题: 模拟银行一天的工作, 统计vip客户和普通客户的办理业务的平均等待时间.
- 银行流程:招商银行、建设银行、中国银行服务流程的差别
- 银行ATM机工作流程模拟编程
- 某银行IT运维流程管理体系建设之服务目录参考
- 转载:C++ 实现银行排队服务模拟
- 某银行IT运维流程管理体系建设之服务目录参考
- 某银行IT运维流程管理体系建设之服务目录参考
- PTA 银行排队问题之单队列多窗口加VIP服务 队列+模拟
- PTA 7-1 银行排队问题之单队列多窗口服务(25 分)25分代码 (小模拟)
- 向Web Service进军--Axis+Tomcat模拟一个银行存取款服务(zz学习)
- C++ 实现银行排队服务模拟
- C++ 实现银行排队服务模拟
- C#模拟键盘鼠标之三:windows服务配合改善模拟流程
- 项目实战笔记 | C++ 实现银行排队服务模拟1 数据结构设计 |实验楼项目
- 微服务架构之基于容器编排的Dev/Ops流程
- android通过jni控制wifi service服务的流程分析
- 通过jersey-client客户端调用Jersey的Web服务模拟CURD
- 探究服务(一)---异步消息处理流程