2015年8月3日

Null 造成了數十億的損失 Null Reference is the Billion Dollar Mistake

Tony Hoare 是 Quick Sort 的發明者、發明 Hoare logic 用來驗證程式的正確性,同時也是 Null Reference 的發明者,1980 ACM Turing Award 的得主。

在 2009 年的 conference 中,他主講了一個主題Null References: The Billion Dollar Mistake, 8/25 2009,Null Reference 造成了系統一些不可預期的錯誤,間接就等於是大量的金錢損失。

Null 的問題是語意不清,字面上的意思是「空」、「無」、「沒有」、「不存在」,Java 開發者常常會在 method 不需要傳送任何東西時傳回 return null。

然而吊詭的是,明明在那個 method 的定義上,就要回傳一個物件,使用這個 method 的開發者,並不一定會知道,這個 method 回傳的物件有可能會是 null,這就造成了 NullPointerException 問題,而這個 Exception 沒辦法在編譯時期就被發現,只能在運作時期產生出來,並在 JVM 直接造成系統停止運作。

這常會造成一種開發的循環,開發者說程式寫好了,上線測試了一段時間,怎麼系統突然掛掉了,然後找開發者去問,第一時間會回答不知道為什麼,然後去伺服器上取 log,找了半天,才發現出了 NullPointerException,然後就修改程式,判斷一下是不是 null,又重演一次上面的循環。

回頭來看看作者對 Null Reference 的看法:1965年時,我正在設計程式語言 ALGOL W ,這是第一個 comprehensive type system for reference in OO language,目標是確保每一個 object reference 都是安全可用的,而且可以由 compiler 自動檢查。

但是他卻沒辦法抗拒將 Null Reference 放進實作中,因為它實在是太容易實作出來了,而 Null 造成了 innerable errors, vulnerabilities 與 system crash,間接等於近四十年來造成了數億元的損失。

要避免遇到 NullPointerException,唯一的解決方法就是完全不使用 null,不過,剛說完不使用 null 可能馬上就會被打臉,因為 RDBMS 的資料欄位中,設計時為了節省儲存實體的硬碟空間,通常預設值都是 null。

Java 8 提出要用 Optional 處理 null,scala 也建議要使用 Option/Some/None Pattern,當語言的設計本身難免都會有一些誤區,也就是 Anti-Pattern,建議開發者要多深入了解語法的意義,並以「正確」的方式使用他們。

說避免不使用 null 還是夢想,還是得回頭提醒開發者,隨時都得要注意,除非確定該變數不是 null,否則一定要針對 null reference 進行處理,多寫一些檢查的程式碼,不會讓你的生命多浪費幾秒鐘,反而會讓系統更加穩定,不會發生不可預期的錯誤。

Refernces

補救null的策略

圖靈獎得主Tony Hoare:我的錯誤造成了十億美元損失