1. 程式人生 > >筆試:天貓魔盒下單邏輯及資料瓶頸問題

筆試:天貓魔盒下單邏輯及資料瓶頸問題

天貓雙十一有個積分換墨盒的活動,總共有50萬臺天貓魔盒(box),每個使用者(user)可以用99個天貓積分(point)兌換一臺魔盒,且每人限換一臺。

請設計一套java介面並實現下單(order)邏輯。

0參考(但不侷限於)下面的下單邏輯:

1、建立訂單

2、扣減使用者積分

3、扣減魔盒庫存

4、下單成功

同時請回答:

1、資料庫表結構如何設計,有哪些表,分別有什麼作用?

2、下單過程中哪些地方可能成為瓶頸?如何解決或改善?

3、是否會用到資料庫事務,哪些地方會用到?如果不用資料庫事務,如何保證資料的一致性?

/**
 * 使用者類
 * @author
 *
 */
public class User {
	private int id;
	/**
	 * 使用者積分
	 */
	private int credit;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getCredit() {
		return credit;
	}
	public void setCredit(int credit) {
		this.credit = credit;
	}
}

public interface OrderOperation {
	/**
	 * 建立訂單
	 * @param user 使用者
	 * @return 建立是否成功
	 */
	public boolean createOrder(User user);
	
	/**
	 * 扣除使用者積分
	 * @param user 使用者
	 * @return 積分扣減是否成功
	 */
	public boolean minusCredit(User user);
	
	/**
	 * 扣除天貓盒子
	 * @return 扣除是否成功
	 */
	public boolean minusBoxStock();
	
	/**
	 * 下單
	 * @param user 下單的使用者
	 * @return 下單是否成功
	 */
	public boolean OrderTemplet(User user);
}

/**
 * 魔盒庫存類
 * @author 
 *
 */
public class BoxStock {
	
	private volatile static BoxStock boxStock; 
	private int currentNumOfBox = 500000;
    private BoxStock (){}  
    /**
     * 獲取BoxStock的例項
     * @return BoxStock例項
     */
    public static BoxStock getBoxStock() {  
	    if (boxStock == null) {  
	        synchronized (BoxStock.class) {  
		        if (boxStock == null) {  
		        	boxStock = new BoxStock();  
		        }  
	        }  
	    }  
	    return boxStock;  
    }
    
    /**
     * 獲取當前剩餘的魔盒數
     * @return 剩餘的魔盒數
     */
    public int getCurrentNumOfBox() {
		return currentNumOfBox;
	}
    
    /**
     * 設定魔盒數
     * @param currentNumOfBox 新的魔盒數
     */
	public void setCurrentNumOfBox(int currentNumOfBox) {
		this.currentNumOfBox = currentNumOfBox;
	}
}
public class OrderOperationImpl implements OrderOperation {
	BoxStock stock = BoxStock.getBoxStock();
	@Override
	public boolean createOrder(User user) {
		// TODO Auto-generated method stub
		
		if(stock.getCurrentNumOfBox() > 0 && user.getCredit() >= 99) {
			return true; 
		}
		return false;
	}

	@Override
	public boolean minusCredit(User user) {
		
		if(user.getCredit() >= 99) {
			user.setCredit(user.getCredit() - 99);
			return true;
		}
		
		return false;
	}

	@Override
	public boolean minusBoxStock() {
		// TODO Auto-generated method stub
		if(stock.getCurrentNumOfBox() > 0) {
			stock.setCurrentNumOfBox(stock.getCurrentNumOfBox() - 1);
			return true;
		}
		return false;
	}
	
	public boolean OrderTemplet(User user) {
		if(this.createOrder(user)) {
			if(this.minusCredit(user)) {
				if(this.minusBoxStock()) {
					return true;
				}
			}
		}
		
		return false;
	}
}


public class test {
	public static void main(String[] args) {
		OrderOperation op = new OrderOperationImpl();
		User user = new User();
		if(op.OrderTemplet(user)) {
			System.out.println("下單成功");
		}
	}
}

1、資料庫表結構如何設計,有哪些表,分別有什麼作用?

魔盒表:box,作用:儲存魔盒數量及附屬屬性

使用者表:user,作用:儲存使用者資訊及天貓積分等使用者屬性

訂單表:order,作用:關聯使用者及魔盒訂單相關屬性資訊

2、下單過程中哪些地方可能成為瓶頸?如何解決或改善?

瓶頸主要會存在寫資料庫的過程中,例如:

1)魔盒數量修改

2)使用者天貓積分修改

3)使用者兌換魔盒記錄次數修改

改善方法:

1)程式邏輯上。在程式設計過程中,合理安排下單關聯的方法順序,比如先查詢使用者是否兌換過魔盒。

2)資料表設計上。儘量減少表的冗餘,尤其是涉及數值敏感欄位。

3、是否會用到資料庫事務,哪些地方會用到?如果不用資料庫事務,如何保證資料的一致性?

需要資料庫事物。

事物主要會用在寫資料庫的過程中,例如:

1)魔盒數量修改

2)使用者天貓積分修改

3)使用者兌換魔盒記錄次數修改

用資料庫事物是做安全的保證資料一致性的方法。

不用事務的話需要在程式碼中體現,程式碼必須確保邏輯正確。