程式語言的心智負擔
很多程式語言對比的文章,總喜歡比較各種程式語言的效能、語法、IO模型。本文將從心智負擔這個角度去比較下不同的程式語言和技術。
記憶體越界
C/C++
可以直接操作記憶體,但程式設計必須要面對記憶體越界問題。發生記憶體越界後,程式會直接core dump
,開發者需要使用gdb
工具分析記憶體錯誤的原因,如果記憶體越界是偶發的,比如由於資料同步問題造成,數億次中會出現一次,解決起來非常困難,甚至需要頂級專家才能找到問題原因。
心智負擔:10
現代C++
提供了STL
庫包含大量容器,另外C++
支援引用語法,不再需要直接操作指標,降低了記憶體錯誤讀寫的風險。使用現代C++
的程式設計風格可以避免此問題。但由於C++
沒有完全從語法層面移除指標,不夠徹底。
巨集
C/C++
程式中經常使用預定義巨集實現一些邏輯,導致可讀性變差。有些情況下會巢狀多次巨集的使用,展開後變得極其難讀。心智負擔:6
因此在C/C++
中建議使用enum
或static inline
函式代替巨集。
記憶體管理
如:C語言、C++
C/C++
語言,需要手工管理記憶體,malloc/new
申請的記憶體要與free/delete
成對使用。申請的記憶體忘記釋放,就會出現記憶體洩漏。心智負擔:8
Java/PHP/Go
等有GC
的程式語言,不需要手工管理記憶體,不會因為程式碼錯誤引起記憶體洩漏。心智負擔:0
數值型別
C/C++/GO
等程式語言,提供了有符號、無符號整型和浮點型,8/16/32/64
不同尺寸的整型。程式設計時需要額外處理,避免數值溢位。心智負擔:6
PHP/Java
等程式語言,預設整數為有符號int64
,降低了心智負擔。一般業務專案中很難有超過2^63
的數字,不會遇到問題。但如果是做科學計算,int64
就難以滿足需求了。在PHP
中超過2^63
底層會轉為浮點型,計算將丟失精度。心智負擔:1
而Python
整數是不限長度的,可以做任意位數的數值計算。心智負擔:0
型別約束
Java
是靜態強型別程式語言,因此在程式設計中存在型別約束,某些情況下可能不是特別方便。如JSON
序列化。不同型別的變數互相操作時可能需要進行顯式型別轉換。心智負擔:2
PHP/JS
是動態弱型別程式語言,底層自動進行隱式型別轉換。程式設計更方便。心智負擔:0
。
但在大型專案,或對專案進行程式碼重構,以及專案程式碼更換開發者時,弱型別帶來可維護性、可讀性的難題,反而與Java/Go/C++
這樣的靜態強型別程式語言,增加了大量心智負擔。心智負擔:5
多執行緒程式設計
Java/C++/Go
提供了多執行緒並行程式設計、無鎖程式設計,在程式設計中會存在資料同步問題。因此需要對臨界資源進行加鎖
。而錯誤的鎖操作又會帶來,死鎖和熱點爭搶問題。需要開發者具備極高的素質,否則難以做到正確無誤並效能良好,這可能需要耗費大量心智。心智負擔:10
記憶體洩漏
除PHP(php-fpm)
之外的其他程式語言和技術(包括PHP + Swoole
),在伺服器端程式中均為長生命週期。對全域性/靜態變數操作可能會導致記憶體或資源控制代碼洩漏。程式設計時需要注意。心智負擔:3
而PHP(php-fpm)
是短生命週期的,在請求結束後會立即釋放所有記憶體和控制代碼,無需擔心洩漏。心智負擔:0
IO 超時
同步阻塞IO
模型的程式語言和技術,在遇到某個慢IO
會導致整個程序或執行緒掛起。極端情況下會出現所有程序/執行緒掛起,引起線上服務不可用。開發者需要格外注意設定IO
操作的超時時間,避免慢請求帶來程序/執行緒阻塞。心智負擔:2
而且非同步IO
的Go/Node.js/Swoole
等無需擔心此問題。心智負擔:0