記一次判斷值是否存在遇到的神奇問題

linyb極客之路發表於2022-04-26

前言

最近朋友說遇到一個無解的bug,他有個業務需求是VIP使用者才能參與活動的業務場景。他判斷vip的虛擬碼形如下

private boolean isVip(UserDTO userDTO){
        List<Integer> vipUserIds = userService.vipUserIds();
        for (Integer vipUserId : vipUserIds) {
            if(vipUserId.equals(userDTO.getUserId())){
                return true;
            }
        }


        return false;
    }

他傳了一個userId為10000(注:10000為示例資料)的vip使用者,結果發現這個判斷一直是false。於是就找到我幫他看下,這程式碼看著沒啥問題,我就讓他先確認一下資料庫是否存在這個vip使用者,朋友非常肯定的說存在的。

排查

因為朋友確定資料庫存在這條記錄,後面我就讓他判斷vip的邏輯上加下日誌,改後的虛擬碼如下

private boolean isVip(UserDTO userDTO){
        List<Integer> vipUserIds = userService.vipUserIds();
        for (Integer vipUserId : vipUserIds) {
            if(vipUserId.equals(userDTO.getUserId())){
                return true;
            }
        }

        log.warn("userId-->{} is not in vipList-->{}",userDTO.getUserId(),vipUserIds);

        return false;
    }

然後日誌神奇的出現

當看到這條日誌,我就有點懵逼了。後面朋友跟我說他懷疑是JDK版本有問題,但我的第六感告訴這不至於。

多年寫bug經驗告訴我,啥都會騙人,只有原始碼不會騙人。因為判斷是否vip的程式碼就一句equal,直接點進去了事。這equal的原始碼如下

   public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

看到這個程式碼後,我想有些老司機應該有點感覺。後面我就跟朋友說你有沒有可能型別寫錯了,你的userId型別是Integer嗎?於是他翻一下程式碼,果然他userId的型別寫成String

修復

後面朋友把userId的型別也改成Integer,問題圓滿解決。

總結

有時候有些bug難以解決,並不是因為遇到技術難題,而是因為一些我們平時沒注意的小細節引起

相關文章