勤與懶
「Just In Case」和「Just In Time」,前者是「以防萬一」,而後者是「正好及時」。寫這篇日誌不是爲了給大家解釋這兩個詞組的字面意思,我更想談一談它們字面意思以下的含義,以及它們在程序設計中的意義。
初看之下,這兩個詞組只是長得很像,似乎並沒有什麼聯繫。而事實上我覺得它們間是一種反義的聯繫。「Just In Case」的做法是在處理問題時把所有可預料的情況處理放在前面處理;「Just In Time」則相對應,總是只處理當前需要處理的問題,處理是放在當下的。所以打個形象的比喻就是前者是勤勤懇懇的人,而後者是懶惰精明的人。
看到這裏,或許你會認爲前者是好的,後者是壞的。但是這也正是我想澄清的,它們並沒有好壞之分,應該說它們各有各的優勢也各有各的劣勢。此話怎講?我們來用我們學過的知識來打個比方好了。曾经我和很多人一样都有一种困惑,或者说失落感,因为大学本科课程太浅,觉得学得泛而浅;而真正开始工作了又要开始学各种更加深入而专项的知识。为什么不在本科就学呢?其实这样的教育体系是有它存在的意义的。泛而浅的知识是必要的,因为如果你从未开始探索某一领域的知识的话,在将来如果要用到的时候就很难往这一领域的知识想。比如《数学之美》的作者吴军博士就曾经是学信号处理的,而这些知识恰好在他后来的信息和语音处理领域可以得到应用。如果他之前学的,比方说,会计學,他或许最终会用一样的知识体系去解决问题,但很显然,他很有可能得走更多的弯路。所以这些在本科学到的泛而浅的知识其实就是「Just In Case」的知识。相對應的,那些到了工作中学到的专项深入的知识大多是「Just In Time」的知识。这两种不同类型的知识我們都需要,自然可以看出 JIC 和 JIT 是各有千秋的了。
現在我們再把這兩個概念放到編程語言和程序設計這裏領域來說說吧。可能對編譯有所瞭解的同學會一眼認出JIT,那是一種編譯方式沒錯,不過我想說的是一個更廣一點的概念,就是「lazy」。lazy 是計算機科學裏一個處理問題的策略,說白了就是讓程序避免執行不必要的指令,從而達到提升效能的目的。lazy 這個詞跟我們平時生活中用來形容人的用法其實是一樣的,只是這裏我們似乎因爲它帶來了額外的利益,反而對 lazy 跪舔了。(再次表現出了人類的醜陋本性,嫉妒別人能夠省事,同時又無節操地喜歡對自己有利的東西。)那在程序世界裏跟 JIT 相對的概念跑哪兒去了?其實我們平時正常的、無 laziness 的編程方式就是跟 JIT 相對的編程方式了。
這時候可能有人會覺得,既然 lazy 式的編程方式可以幫我們節省資源,我們爲什麼不全都用這種方式?這就引出了我想說的,不同應用場景這兩種編程風格的利弊了。lazy 也不是徹底的好東西。我們拿分佈式計算裏的一個案例來舉例,Hadoop(MapReduce),如果全都採用 lazy 式的設計方案,那很有可能有些數據就總不會被算,直到被需要的那一刻,這帶來的後果就是本來能夠並行分佈式運算的,但卻因爲 lazy 變成了低效的半並行半流水線的分佈式運算。
聊完了編程,我們來聊聊人生好了。其實「勤奮」與「懶惰」,還真的是個哲學問題呢。有人看起來勤奮,但其實他懶惰;有人看起來懶惰,但其實他勤奮。第一類人,我們通常會用「庸庸碌碌」來形容他,而第二類人更像是「精明能幹」的。第一類人不想走出自己的 confident zone,所以即便知道自己在做的是重複勞動,他也會「勤勤懇懇」地做下去,「懶」到不願去想有沒有更好的辦法。第二類人合理地避開不需要處理的事物,創造性地產生出可以取代現有方案的新方案,他們可能看起來做的事情並不多,但其實「勤」于思考。