程式常用的設計技巧

程式設計一生發表於2019-02-26

一、背景

程式的定義:程式=資料+演算法+介面

 

二、常用技巧

技巧1 - 按目標設計介面做冪等設計

場景

背景:做任務賺積分。前端發出增加積分請求,如果收不到響應會重試。

 

後臺開發人員:怎麼判斷是重試還是另一次請求?

 

解決方案:介面定義中需要傳入原來積分是多少,增加到多少。開發人員直接將目標結果入庫。

 

疑問:那實際生產環境發現了原來積分一樣,增加到多少不一樣的結果怎麼辦?

 

答疑:這說明上線的產品中肯定有漏洞或bug。怎麼辦?改bug唄!

 

- 解析

冪等性設計的定義:一次和多次請求某一個資源應該具有相同的副作用。直白點講就是多次重試可以多次查詢,但是修改更新應該只進行一次。

 

作為開發正確的觀念應該是外部呼叫失敗是常態,並且失敗之後必然有重試。

不要靠巧合程式設計  --《程式設計師修煉之道》

 

技巧2 - 多版本併發控制解決併發問題

- 場景

背景:上文中的做任務賺積分,後臺收到了增加積分請求。

 

開發人員:為了避免重試,我該怎麼寫程式碼呢?

 

解決方案:update XXX set score=XX where score=X

 

- 解析

多版本併發控制MVCC(MultiVersion Concurrency Control)的定義:該策略主要使用update with condition(更新帶條件來防止)來保證多次外部請求呼叫對系統的影響是一致的。這也是「樂觀鎖」的主要思想。

 

樂觀鎖的定義:假設最好的情況,資料在變更的時候不會被別人更新,如果更新了,某個值就會改變。所以就用這個值來作為判斷條件,只有條件為真才更新成功。

 

總是為併發進行設計  --《程式設計師修煉之道》

 

技巧3 - 預判斷准入控制避免「箭頭型」程式碼

- 場景

背景:上文中後臺收到了增加積分請求,傳入了一個負數的積分。

 

開發人員:我就if 正數 才往下執行就好了呀?

 

結果:一層層的判斷下來,程式碼變成這個樣子。

 

疑問:怎麼解決這種複雜的「箭頭型」程式碼問題呢?

 

答疑:「衛語句」在預判斷時做准入控制。

 

- 解析

衛語句(guard clause)的定義:先對異常情況做檢查,異常則直接返回。

最終一個請求被完美的分成預判斷檢查和正式執行兩個部分,邏輯清晰,簡單明瞭。

 

早重構,常重構  --《程式設計師修煉之道》

 

技巧4 - 非同步設計分離響應和執行

- 場景

背景:上文的增加積分,併發量太大,因此採用了佇列設計,大量請求排隊等待資料庫變更。

 

開發人員:這樣後臺介面部分很容易都在等著響應,服務被拖死。

 

解決方案:准入校驗做充分,請求放到佇列裡後直接給使用者返回操作成功。

 

疑問:萬一最後失敗了呢?

 

答疑:知道失敗了還不修資料嗎?資料補償保證最終與對使用者承諾一致撒。

 

- 解析

1/3/5秒原則:在1s以內得到響應,使用者會覺得系統響應很快,體驗非常好;1-3秒得到響應,使用者可以接受,體驗還不錯;3-5秒才響應,使用者就感覺慢了,體驗有點糟糕;一旦響應超過5秒,使用者就會認為是個失敗的體驗,選擇離開或重新發起請求。

 

三、總結

思考!你的工作!  --《程式設計師修煉之道》

 

相關閱讀:

 

相關閱讀:

 

《程式設計師修煉之道》解讀

 

到底多大才算高併發?

 

美團分散式服務通訊框架及服務治理系統OCTO

 

相關文章