7K月薪面試題____銀行業務調度系統

---------------------------------------- android培訓java培訓、期待與您交流! ------------------------------------

題目要求:

銀行業務調度系統 模擬實現銀行業務調度系統邏輯,具體需求如下: *銀行內有6個業務窗口,1 - 4號窗口爲普通窗口,5號窗口爲快速窗口,6號窗口爲VIP窗口。 *有三種對應類型的客戶:VIP客戶,普通客戶,快速客戶(辦理如交水電費、電話費之類業務的客戶)。 *異步隨機生成各種類型的客戶,生成各類型用戶的概率比例爲: VIP客戶 :普通客戶 :快速客戶  =  1 :6 :3。 *客戶辦理業務所需時間有最大值和最小值,在該範圍內隨機設定每個VIP客戶以及普通客戶辦理業務所需的時間, 快速客戶辦理業務所需時間爲最小值(提示:辦理業務的過程可通過線程Sleep的方式模擬)。 *各類型客戶在其對應窗口按順序依次辦理業務。 當VIP(6號)窗口和快速業務(5號)窗口沒有客戶等待辦理業務的時候,這兩個窗口可以處理普通客戶的業務, 而一旦有對應的客戶等待辦理業務的時候,則優先處理對應客戶的業務。 隨機生成客戶時間間隔以及業務辦理時間最大值和最小值自定,可以設置。 不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。

問題分析:

*有三種對應類型的客戶:VIP客戶,普通客戶,快速客戶 ,異步隨機生成各種類型的客戶, 各類型客戶在其對應窗口按順序依次辦理業務 。   *首先,經常在銀行辦理業務的人更有利於理解本系統,每一個客戶其實就是由銀行的一個取號機器產生號碼的方式來表示的。      所以,我想到要有一個號碼管理器對象,讓這個對象不斷地產生號碼,就等於隨機生成了客戶。   *由於有三類客戶,每類客戶的號碼編排都是完全獨立的,所以,我想到本系統一共要產生三個號碼管理器對象,      各自管理一類用戶的排隊號碼。這三個號碼管理器對象統一由一個號碼機器進行管理,      這個號碼機器在整個系統中始終只能有一個,所以,它要被設計成單例。   *各類型客戶在其對應窗口按順序依次辦理業務 ,準確地說,應該是窗口依次叫號。     *各個窗口怎麼知道該叫哪一個號了呢?       它一定是問的相應的號碼管理器,即服務窗口每次找號碼管理器獲取當前要被服務的號碼。

關係結構分析圖:

"NumberManager"類	-->排號
	定義一個用於存儲上一個客戶號碼的成員變量和用於存儲所有等待服務的客戶號碼的隊列集合。
	定義一個產生新號碼的方法和獲取馬上要爲之服務的號碼的方法,
		這兩個方法被不同的線程操作了相同的數據,所以,要進行同步。

"NumberMachine"類	-->號碼管理器,取號
	定義三個成員變量分別指向三個NumberManager對象,分別表示普通、快速和VIP客戶的號碼管理器,
	定義三個對應的方法來返回這三個NumberManager對象。
	將NumberMachine類設計成單例。

"CustomerType"枚舉類
	系統中有三種類型的客戶,所以用定義一個枚舉類,其中定義三個成員分別表示三種類型的客戶。
	重寫toString方法,返回類型的中文名稱。這是在後面編碼時重構出來的,剛開始不用考慮。

"ServiceWindow"類	-->業務窗口
	定義一個start方法,內部啓動一個線程,根據服務窗口的類別分別循環調用三個不同的方法。 
	定義三個方法分別對三種客戶進行服務,爲了觀察運行效果,應詳細打印出其中的細節信息。

"MainClass"類
	用for循環創建出4個普通窗口,再創建出1個快速窗口和一個VIP窗口。
	接着再創建三個定時器,分別定時去創建新的普通客戶號碼、新的快速客戶號碼、新的VIP客戶號碼。

"Constants"類	
	定義三個常量:MAX_SERVICE_TIME、MIN_SERVICE_TIME、COMMON_CUSTOMER_INTERVAL_TIME


package com.liujie.bank;

import java.util.ArrayList;
import java.util.List;

/**
 * 生成票
 * @author lWX207643
 *
 */
public class NumberManager {
	private List<Integer> queueList = new ArrayList<Integer>();
	private Integer lastNumber = 0;

	// 生成用戶排隊號碼
	public synchronized Integer generateNumber() {
		queueList.add(++lastNumber);
		return lastNumber;
	}

	// 櫃檯取出排隊號碼
	public synchronized Integer feachNumber() {
		if (queueList.size() > 0) {
			return queueList.remove(0);
		} else {
			return null;
		}
	}
}



NumberMechine類:

package com.liujie.bank;

/*
 * 號碼生成器:
 * 設置爲單列
 * 生成普通用戶號碼,快速用戶號碼,VIP用戶號碼
 */
public class NumberMechine {
	private NumberMechine() {

	}

	private static NumberMechine instance = new NumberMechine();

	public static NumberMechine getInstance() {
		return instance;
	}

	private NumberManager commonManager = new NumberManager();
	private NumberManager expreeManager = new NumberManager();
	private NumberManager vipManager = new NumberManager();

	public NumberManager getCommonManager() {
		return commonManager;
	}

	public NumberManager getExpreeManager() {
		return expreeManager;
	}

	public NumberManager getVipManager() {
		return vipManager;
	}
}


CustomerType枚舉類

package com.liujie.bank;

/**
 * 枚舉類:用戶類型
 * 
 * @author lWX207643
 * 
 */
public enum CustomerType {
	COMMON, EXPRESS, VIP;

	@Override
	public String toString() {
		switch (this) {
		case COMMON:

			return "普通用戶";
		case EXPRESS:

			return "快速用戶";
		case VIP:

			return name();
		}
		return null;
	}
}

Constants常量類:

package com.liujie.bank;

/**
 * 服務時間常量類
 * 
 * @author lWX207643
 * 
 */
public class Constants {
	public final static int MAX_SERVICE_TIME = 10000;
	public final static int MIX_SERVICE_TIME = 1000;
	// 普通客戶間隔時間
	public final static int COMMON_CUSTOMER_Interval_TIME = 1;
}

ServiceWindow服務窗口類:

package com.liujie.bank;

import java.util.Random;
import java.util.concurrent.Executors;

/**
 * 服務窗口類,就是銀行櫃檯
 * 
 * @author lWX207643
 * 
 */
public class ServiceWindow {
	// 默認爲普通用戶
	private CustomerType type = CustomerType.COMMON;
	private int windowsId = 1;

	public CustomerType getType() {
		return type;
	}

	public void setType(CustomerType type) {
		this.type = type;
	}

	public int getWindowsId() {
		return windowsId;
	}

	public void setWindowsId(int windowsId) {
		this.windowsId = windowsId;
	}

	public void start() {
		// 單例線程池
		Executors.newSingleThreadExecutor().execute(new Runnable() {

			@Override
			public void run() {
				while (true) {
					// switch只能接受int和枚舉類型
					switch (type) {
					case COMMON:
						commonService();
						break;
					case EXPRESS:
						expressService();
						break;
					case VIP:
						vipService();
						break;
					}
				}

			}

		});
	}

	private void commonService() {
		String windowName = "第" + windowsId + "號" + type + "窗口";
		Integer number = NumberMechine.getInstance().getCommonManager()
				.feachNumber();
		System.out.println(windowName + "正在獲取任務");
		if (number != null) {
			System.out.println(windowName + "爲" + number + "號普通客戶服務");
			int maxRandom = Constants.MAX_SERVICE_TIME
					- Constants.MIX_SERVICE_TIME;
			long serviceTime = new Random().nextInt(maxRandom) + 1
					+ Constants.MIX_SERVICE_TIME;

			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(windowName + "完成對第" + number + "號普通客戶服務;耗時:"
					+ serviceTime + "Millis");
		} else {
			System.out.println(windowName + "沒有任務....休息一分鐘");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void expressService() {
		String windowName = "第" + windowsId + "號" + type + "窗口";
		Integer number = NumberMechine.getInstance().getExpreeManager()
				.feachNumber();
		System.out.println(windowName + "正在獲取任務");
		if (number != null) {
			System.out.println(windowName + "爲" + number + "號" + type + "客戶服務");

			long serviceTime = Constants.MIX_SERVICE_TIME;

			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(windowName + "完成對第" + number + "號" + type
					+ "客戶服務;耗時:" + serviceTime + "Millis");
		} else {
			System.out.println(windowName + "沒有快速任務...爲普通客戶服務");
			commonService();
		}
	}

	private void vipService() {
		String windowName = "第" + windowsId + "號" + type + "窗口";
		Integer number = NumberMechine.getInstance().getVipManager()
				.feachNumber();
		System.out.println(windowName + "正在獲取任務");
		if (number != null) {
			System.out.println(windowName + "正在爲第" + number + "號" + type
					+ "客戶服務");
			int maxRandom = Constants.MAX_SERVICE_TIME
					- Constants.MIX_SERVICE_TIME;
			long serviceTime = new Random().nextInt(maxRandom) + 1
					+ Constants.MIX_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(windowName + "完成對第" + number + "號" + type
					+ "用戶服務;耗時:" + serviceTime + "Millis");
		} else {
			System.out.println(windowName + "沒有VIP任務...爲普通客戶服務");
			commonService();
		}
	}
}


MainClass類:

package com.liujie.bank;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 客戶排號類
 * 
 * @author lWX207643
 * 
 */
public class MainClass {
	public static void main(String[] args) {
		for (int i = 1; i < 5; i++) {
			ServiceWindow commonWindow = new ServiceWindow();
			commonWindow.setWindowsId(i);
			commonWindow.setType(CustomerType.COMMON);
			commonWindow.start();
		}
		ServiceWindow expressWindow = new ServiceWindow();
		expressWindow.setType(CustomerType.EXPRESS);
		expressWindow.start();

		ServiceWindow vipWindow = new ServiceWindow();
		vipWindow.setType(CustomerType.VIP);
		vipWindow.start();
		// 0表示馬上來第一個客戶,
		// Constants.COMMON_CUSTOMER_Interval_TIME,過多久再來一個客戶,
		// TimeUnit.SECONDS表示時間單位
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				// 生成普通用戶
				Integer number = NumberMechine.getInstance().getCommonManager()
						.generateNumber();
				System.out.println(number + "號普通客戶正在等待服務");
			}
		}, 0, Constants.COMMON_CUSTOMER_Interval_TIME, TimeUnit.SECONDS);

		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Integer number = NumberMechine.getInstance().getExpreeManager()
						.generateNumber();
				System.out.println(number + "號快速客戶正在等待服務");
			}
		}, 0, Constants.COMMON_CUSTOMER_Interval_TIME * 2, TimeUnit.SECONDS);

		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Integer number = NumberMechine.getInstance().getVipManager()
						.generateNumber();
				System.out.println(number + "號VIP客戶正在等待服務");
			}
		}, 0, Constants.COMMON_CUSTOMER_Interval_TIME * 6, TimeUnit.SECONDS);

	}
}


運行結果:

 

---------------------------------------- android培訓java培訓、期待與您交流! ------------------------------------

發佈了31 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章