一個與運算引發的事故
今天發生了一起事故,追查下去,找到了一段陳年老程式碼。
程式碼邏輯很簡單:
<?php
$a = 1;
$b = 8;
if ($a & $b) {
var_dump('same');
} else {
var_dump('not same');
}
這個程式碼的作用是什麼呢?判斷a與b是否相等。
為什麼能判斷呢?或者說什麼條件下這個邏輯是生效的?
聰明的你可能有了答案,當a和b都是2^n的時候。
在位與運算的時候,只有完全一樣a&b才能大於零,否則,每一位必然會有一個0,最終結果為0,表示不相等。
這個算是比較巧的寫法(這麼寫的人少),另外理論上這個操作比直接判斷相等是要快一些的。
但是卻隱藏了兩個極大的問題
- 數值增長會很快,迅速達到越界的範圍,畢竟指數增長啊
- 如果這個邏輯一直是由同一個人維護還好,知道賦值必須為2^n,如果程式碼交接給別的組或者換了一個新人,極有可能不知道這點,賦值的時候沒有遵循指數規則,然後就悲劇了
墨菲定律說的是個概率問題,感覺世上的事情沒啥能逃脫統計,然後果然就悲劇了。對於系統來說,一個&值多少錢,可能一文不值,也可能是天價。
後來我想了想,在程式碼層面至少有兩個問題
- 如果接手別人的程式碼,一定要看一遍,另外對裡面不符合常理的地方一定要跟進,這些地方往往是定律的藏身之所
- 寫程式碼的時候,通俗易懂是最重要的,不要去炫技,也不要為了炫技而埋了坑。就對上面舉例的程式碼而言,即沒有充分利用每一個數字,而且很可能引發錯誤,另外其實也提升不了多少效能,優化優化邏輯、改改演算法,效能不會比這個提升的多?
最後說一句:
<?php
$a = 1;
$b = 8;
if ($a == $b) {
var_dump('same');
} else {
var_dump('not same');
}
這個寫法不香嗎?
最後
大家如果喜歡我的文章,可以關注我的公眾號(程式設計師麻辣燙)
我的個人部落格為:https://shidawuhen.github.io/
往期文章回顧:
技術
- 秒殺系統
- 分散式系統與一致性協議
- 微服務之服務框架和註冊中心
- Beego框架使用
- 淺談微服務
- TCP效能優化
- 限流實現1
- Redis實現分散式鎖
- Golang原始碼BUG追查
- 事務原子性、一致性、永續性的實現原理
- CDN請求過程詳解
- 常用快取技巧
- 如何高效對接第三方支付
- Gin框架簡潔版
- InnoDB鎖與事務簡析
- 演算法總結
讀書筆記
思考
相關文章
- 事故現場:MySQL 中一個雙引號的錯位引發的血案MySql
- Redis Cluster 當機引發的事故Redis
- 記一次 Redis Cluster 當機引發的事故Redis
- git stash 引發得事故Git
- 一個不讓用加號的需求而引發的Java位運算詳解Java
- 一次依賴注入不慎引發的一連串事故依賴注入
- 記go中一次http超時引發的事故GoHTTP
- Redis分散式鎖引發的工作事故Redis分散式
- 記一次自定義starter引發的線上事故覆盤
- 一次mongo查詢不存在欄位引發的事故Go
- 一個由line-height引發的血案與思考
- 「生產事故」MongoDB複合索引引發的災難MongoDB索引
- 一個commit引發的思考MIT
- 一個排序引發的BUG排序
- 一個 List.of 引發的“血案”
- 由一個emoji引發的思考
- shell (3)指令碼引數傳遞與數學運算指令碼
- 一個單引號引發的 MySQL 效能損失MySql
- 3、前置運算(++a)與後置運算(a++)的區別
- 一個map函式引發的血案函式
- 一個UPDATE語句引發的血案
- MySQL 中一個雙引號的錯位引發的血案MySql
- 記一次JVM FullGC引發嚴重線上事故的定位、分析、解決過程!JVMGC
- 1的個數 【位運算】
- 執行緒池運用不當的一次線上事故執行緒
- 一個ES設定操作引發的“血案”
- 實戰|一個表白牆引發的“血案”
- 一個系統BUG引發的血案 -- FKDownloader
- 一個 Handler 面試題引發的血案!!!面試題
- 記一個面試題引發的思考面試題
- 模運算與逆元
- 區塊鏈應用|CryptoKitties效應:一個與區塊鏈有關的事故區塊鏈
- 一次因生產事故與chatGpt的對話ChatGPT
- 兩個double之間的運算
- 一個圖片偶爾載入不出來的事故
- 一道面試題引發的思考:理解 new 運算子面試題
- 一個由public關鍵字引發的bug
- Vue一個案例引發的遞迴元件的使用Vue遞迴元件