天天看點

int溢出 java_Java int溢出問題

最近在測試代碼時,發現一個bug,到測試的最後階段才發現,比較容易忽略。記錄下來,以自省。

簡單說一下代碼要實作的功能,一個函數,入參是一個整型數字lastTime,代表持續時間(機關是分鐘);函數功能是要計算以目前時間為起點,lastTime分鐘之後的時間點,封裝成一定的資料結構傳回出來。

private TimePeriod.Builder setTimePeriods(int lastTime) {

Date startDate = new Date();

Date endDate = new Date(startDate.getTime() + lastTime * 1000 * 60);

...

return timePeriodBuilder;

}

第一遍功能測試時,lastTime這個參數從配置檔案中随機讀取一個,校驗結果沒有問題,也就沒有關注;但是自動化執行後,發現很小的幾率有case失敗的情況,失敗的原因就是這個函數計算出來的結果和測試代碼自己計算出來的結果不比對,當時lastTime這個參數傳入的值為150000.

有問題,那就一步步執行來看,寫了個main函數,直接調用開發的函數,執行到Date endDate = new Date(startDate.getTime() + lastTime * 1000 * 60);這一步時,發現endDate的結果怎麼也對不上,初始一看目前的時間戳 + 持續時間(分鐘) * 60 * 1000,也就是結束時刻的時間戳,沒問題;後來自己手動計算lastTime * 1000 * 60的值才發現不對,才意識到lastTime這個參數是整型類型,這樣計算溢出了,導緻結果有問題。

Java語言裡整型數字占用4個位元組,表示的範圍為-2^31=-2147483648到2^31=2147483647,而150000 * 60 * 1000 = 9000000000,明顯溢出了。上報問題,開發把lastTime從int換成long,long類型的數字占用64個位元組,可表示的數字的範圍就很大了,至少目前人類能用到的時間應該不會溢出了。

過程就這樣。再啰嗦兩句,其實在開始測試前,我已經把開發寫的代碼通讀了一遍,這樣明顯的問題應該在代碼review的時候就發現。一個bug越早發現,修複它的代價就越小,向這樣的bug如果遺漏上線了,通過業務場景測試一般很難發現,即使發現了某些場景下持續時間有問題,線上的業務鍊路都比較長,定位起來也比較費勁,故review代碼很重要、單測很重要。做為一個QA,保持破壞性思維、發散性思維很重要,測得項目比較多,有些疲懶了,自省。