筆試:天貓魔盒下單邏輯及資料瓶頸問題
阿新 • • 發佈:2019-01-28
天貓雙十一有個積分換墨盒的活動,總共有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)使用者兌換魔盒記錄次數修改
用資料庫事物是做安全的保證資料一致性的方法。
不用事務的話需要在程式碼中體現,程式碼必須確保邏輯正確。