【升級變成邀請-15人】還能邀請-2人??知乎的這麼明顯的BUG,貼上截圖,大家猜一下是啥原因造成的?

如圖所示,百思不得其解。

今天是11.12號,一看更加誇張:


謝@孤盡邀,我上半年讀過《阿里巴巴Java開發手冊》,裡面的強制和推薦很貼心,以前的好些習慣我細細思量和手冊對比確實有很多不妥之處,對我寫代碼的習慣有了潛移默化的修正,手冊對我們這些正在大量coding的人來說有很大幫助,在這裡表示感謝。也推薦新手可以邊學習便參考該手冊,因為最開始是形成coding好習慣的最好時機嘛。

說到這個話題,我說說自己的看法。

假如有一段執行邀請他人回答的代碼invite();那麼它肯定有個執行條件:

if(alreadyPersonNum&<=15){ invite(); }

那麼開始有兩個線程從資料庫或者緩存拿到alreadyPersonNum(已邀請人數)目前都是14,沒有加鎖的的情況下上面這一段代碼必然被執行兩次,會出現如圖的情況;但是圖上好像是alreadyPersonNum大於15的情況下還會執行invite();方法,我感覺可能就是簡單的業務邏輯問題,說不定是後端覺得前台肯定會校驗這個參數不調用後台api的,那前端妹紙還覺得這後台小哥肯定做了吧,我稍微給用戶一個友好的提示就可以了,所以前台妹紙拿到alreadyPersonNum一看大於15就拋出一個萌萌噠的「24小時最多邀請15次」!後台小哥說「哼,24小時才15次,你是在看不起誰?」所以可能傲嬌的多來了幾次。

我可沒在開車,各位坐穩了!


知乎是一個大網站,出現這種低級的錯誤不應該啊。阿里巴巴JAVA開發手冊中有一條:

【強制】在高並發場景中,避免使用「等於」判斷作為做中斷或退出的條件。

說明:如果並發控制沒有處理好,容易產生等值判斷被「擊穿」的情況,使用大於或小於的區間判斷條件來代替。

比如:庫存數=0退出,由於並發,成為-1,導致永遠無法退出。

這像《白夜追兇》一樣,大家分析一下案情。案情的奇怪之處是截圖中的-2,是在我明顯幾秒後點擊產生的,並發的錯誤不太可能,有可能是架構上的緩存問題,或者是故意而為之?

順便做個招聘的小廣告,如果想和我們一起奮鬥,享受編程的快樂,請發一句話,或者簡歷至:

guanbao.yanggb@alibaba-inc.com


我多麼希望把支付寶一直用到 》》餘額:-9999999元。


之前的答案只是舉了個沒加鎖突破限制的例子,但可能跟知乎的這個情況有所區別。下面再介紹一下更可能的猜測。

知乎的程序大概率應該是

1) a = 從資料庫中讀取該問題的邀請數

2) 判斷a是否小於15,如果大於15則結束程序,否則繼續執行3)

3) 將資料庫中該問題的邀請數+1

跟原回答中的情況類似,當邀請數已經達到14的情況下,多個請求都查詢到了a = 14,於是2)中判斷都認為可以繼續執行3),於是邀請數就超過了15。

當然還有一種可能就是這根本就跟並發沒有關係,而完全是前端邏輯混亂。比如每個用戶每天限制邀請15個用戶,然後前端以為是每個問題最多邀請15個用戶,結果第一天邀請了兩個,然後第二天再邀請15個就突破了單問題15個的限制了。

最後再解釋一下大家經常會問的其他問題:

1. 知乎這種級別的網站也會出這種bug?

你多邀請幾個人對知乎其實並沒有什麼損失。。。

2. 為什麼我覺得是記錄邀請數而不是剩餘可邀請數?

如果我哪天要把可邀請數改成20那豈不是資料庫里所有的欄位都要再更新一遍?

===== 原回答 ======

沒加鎖唄~

舉個例子,比如我要統計你這個問題邀請了幾個人了,那一般更新計數器的代碼會是這樣。

1) a = 從資料庫中讀取該問題的邀請數

2) a = a + 1

3) 把資料庫中該問題的邀請數更新為a

如果我同時邀請多個人,默認情況下程序不會一個一個邀請,而是同時邀請已提高處理效率,這意味著計算機會同時執行上面的程序。

那就有可能出現多個程序都執行到了1),並且都讀取到了一樣的數值,因為在執行3)之前其他任務讀取出來的數值是不會更新的。例如兩個任務在代碼1)中讀出來的都是3(之前已經邀請了三個了),然後最終在代碼4)中更新到資料庫的數值都是4。但實際邀請數已經到5了。


知乎好像不是用java的吧 以前據說是python。

應該有用分散式來提升並發,但是具體編程沒有考慮分散式的數據更新並發。


再送你一個同類bug

========================================

然後一不小心發現一個傻的bug

請看下面的系列圖。。

我邀請三人後顯示:已經邀請11人還可以邀請4人

當我邀請第四個人的時候,顯示已經邀請十人還可以邀請5人

我再邀請兩個人顯示已經邀請八人還可以邀請7人

知乎的計數方式很有趣啊~~~~~讓我思考思考

====================================

@孤盡 大佬看這裡。目前的結果是邀請數字到了8之後也無法繼續邀請了。。。。

那麼說明判斷與15這個數字關係不是太大哦。。

並且請求有發出返回403~~~~~~~~

我過了十二點後的再次請求會變成反向遞增。

目前掌握的條件是:

1,請求不會判斷已經邀請人數中斷訪問,因為滿了之後會繼續請求並返回403。滿人數之後不中斷請求不符合常規做法。

2,根據1與實際觀察,已經邀請人數對判斷幾乎沒有影響。

3,根據bug2可以看出。已經邀請人數與可邀請人數並非單純的i++或者i--的累加模式,故並發情況下不存在同時出現兩個已邀請人為14的請求同時到達知乎伺服器。

4,知乎伺服器大概率會統計同一用戶請求數作為判斷依據,而並非某個request參數。

5,知乎的設計上看第二天可以繼續增加邀請人數,所以超過15是必然。

6,根據以上所述,判斷值與已經邀請人數無關。

大佬您的判斷個人感覺有些輕視了。這個bug還是有點意思的。。。。


謝邀,題目中出現了我頭像,我也是嚇一跳。

這個應該是後台邏輯判斷不嚴謹

1. 24小時內,只能邀請15個人,很明顯超過15個還能邀請,所以資料庫里寫進去數據了,但是前台算的時候還是用15減的。至於為什麼寫進去數據了,難道是因為沒有進行人數判斷?

2.另外24個小時過去了,邀請人數應該重新計算,後台也沒有重置?

3.應該是測試沒到位?

4.也有可能只是前端錯了,一直用15減邀請人數,應該是n天后用 n*15-邀請人數


一堆熱心人幫人家試BUG……


我覺得是前端問題。我也遇到過這個情況。因為知乎好像在用戶操作之後會在前端立刻顯示更新,前端判斷不嚴謹造成了數字成為負數。但是實際上刷新一下又變成正常的了,是因為後端數據同步過來了。


謝大佬。被大佬邀請。

大佬的Java手冊看了好幾遍。

我也不是知乎程序員,我也不知道什麼原因。

可能是兩邊數據統計的不一致,少個判斷吧。

比如15人是個常量,你邀請過的人是前面那個值,-15,就直接是後面的還能邀請。這裡少個判斷。

兩邊數據,這條我只能想出來可能原因,但是解釋不出來。


前端…… 編輯器也是極其垃圾 粘貼文字亂加換行,沒法粘貼圖片,只能一個一個上傳……


應該是判斷條件寫成「==」了。並發處理不好的話 就會出問題。


請求在被執行的時候沒有做好並發處理,最後三個請求同時被執行結束了。

另外我查看問題日誌,會自動跳轉到網頁端登錄頁面...

ios10,難道只有我有這個bug,這個bug我就百思不得其解了,難道是查看問題日誌token丟失了?


驚奇的發現Tencent大大騰訊新聞也有這個問題


之前沒仔細看題,我覺得我又一次高估了知乎的技術人員的水平!

………………以下是原答案………………

如果只憑感覺說的話,可能是資料庫讀寫分離,數據沒有及時同步造成的。

類似的,新增加到某個話題的問題,是不會馬上就能通過話題找到的。這些現象可以看出讀寫分離的痕迹。

————————————

說一下我的分析吧。

1:服務端做了檢查,但是因為讀寫不同步,造成了在某個時間段實際上超過15的時候沒有檢查到。所以產生了實際上超過15的邀請。

2:同步以後,因為超過了15,服務端的檢查不會通過。但是web客戶端判斷寫的是==15,所以依然可以提交請求。請求提交以後,返回200,客戶端接著根據服務端的信息執行業務邏輯,彈出了那條紅色信息。

這個如果以mysql為例的話,應該是使用mysql proxy造成的。改用mysql cluster,並且保證服務端的[檢查和發起邀請]是同一個事務,就能徹底解決了。


已邀請xx人,還能邀請xx-15人 的這句是前端自己計數的吧,然後沒有加判斷條件。

那個紅色的句子則是寫死的。

中間應該是有2個請求沒發到後端,所以前端以為自己發了17次,就記了17,後端這時才夠15個,剛剛返回了達到上限的標記,前端就把那2句話都顯示出來了。


3條邀請同時到了,然後他們幾乎同時進入了檢查剩餘邀請數的代碼段,獲取了資料庫剩餘邀請數,都發現剩餘1人,都通過了檢查。然後創建邀請。然後更新資料庫邀請人數減1?


並發沒有處理好


感覺還是不一致,提示語和頁面顯示的數據源不一致?


我覺得是判斷條件不夠嚴格造成的,不能小於零


就是沒加鎖,並發沒控好


只能說明這個邀請功能比較容易,是讓新人寫的,每家公司都會有幾個萌新,只能做一些偏門的功能,領導看到你做出來了,實現效果了,也就不管具體業務下會不會出現bug了。


@知乎小管家 希望能夠修正這個BUG?謝謝


推薦閱讀:

賦能遊戲產業鏈!這或許是阿里遊戲第一次真正展示自己的野心
財報解讀|阿里一季度超預期增長60%,股價為什麼沒大漲?
管理變陣,戰略落地——阿里再造阿里
阿里28.8億美元入股高鑫,新零售「未來已來,正在加速流行」

TAG:知乎 | 測試 | 阿里巴巴集團 | Java | 邀請回答知乎功能 |