來自:碼農翻身(微訊號:coderising)
Linus Torvalds的“暴脾氣”是出了名的,看到令自己不爽的事情就會懟過去,比如:
-
他曾經說Intel提交的漏洞修複程式是徹底的垃圾!
-
當別人說Git沒用C++開發的時候, 他反擊說“C++是一種可怕的語言”
-
他噴別人的Pull Request : Your code is shit …..
-
他吐槽XML可能是有史以來最糟糕的格式……
-
甚至直接對著攝像機說了一句“So NVIDIA, Fxxk you.”同時給了一個中指。
有人說這是天才的個性,但是這種性格確實是得罪了不少人,去年9月份,他發郵件做了一個反省,說自己也許要照照鏡子,為自己的人身攻擊言論道歉。
我是有點好奇,領導著世界上最大的開源專案,Linus欣賞誰,尊重誰,喜歡和誰一起共事?
TED上對Linus 的一段訪談影片“The mind behind Linux” 給出了一點線索。
(ps. Linus 不喜歡在公眾面前演講,如果非要參加一些活動的話,他更喜歡和主持人一對一地對話,這會讓他感覺到舒服)
在這段訪談中展示了兩段完成同樣功能的程式碼(偽碼), 第一段是這樣的:
remove_list_entry(entry){
prev = NULL;
walk = head;
// Walk the list
while (walk != entry){
prev = walk;
walk = walk -> next;
}
// Remove the entry by updating the
// head or the previous entry
if (!prev)
head = entry->next;
else
prev->next = entry->next;
}
學過資料結構的同學(即使你沒學過C語言中的指標),估計也能明白這段程式碼的大致意思: 這是在刪除一個單向連結串列中的某個節點。
(這段程式碼沒有考慮待刪除的節點不在連結串列中的情況。)
由於是單向連結串列,在尋找某個節點的時候,需要不斷地記錄下這個節點前面的節點(prev)
另外,這段程式碼還考慮到了一個特殊情況, 待刪除的節點不是中間節點, 而是頭節點(head)。 即使有這個特殊的情況,這段程式碼還是相當容易理解的,絕大部分人都會寫出這樣的程式碼,學校的老師也會這麼教我們。
然後Linus給出了另外一段程式碼(偽碼),完成了同樣的功能。
remove_list_entry(entry){
// The "indirect" pointer points to the
// *address* of the thing we'll update
indirect = &head;
// Walk the list, looking for the thing that
// poins to the entry we want to remove_list_entry
while ((*indirect) != entry){
indirect = &((*indirect)->next);
}
// .. and just remove it
*indirect = entry -> next;
}
我看到這段程式碼的第一印象就是很簡潔, 根本沒有if else, 不管你刪除的是頭結點還是中間節點,都可以用同樣的邏輯來表達。
但是這段程式碼使用了指標的指標,我看了一會兒才明白到底是怎麼工作的。 一旦理解以後,就發現,這確實是個更優雅的方法。 消除了if else, 消除了previous。
我本來也想用圖來表達一下,但是發現畫出這個indirect的變化過程有點麻煩,大家充分發揮下想象力,自行腦補一下吧。
關鍵點就是indirect 這個指標第一次指向的是 head 的地址,第二次指向的是節點1.next的地址, 第三次指向的是節點2.next的地址。
Linus對比了這兩段程式碼以後說道:
第一段程式碼並不好, 它需要區別第一個節點和中間節點,有特例。
第二段程式碼展示了用一種不同的方式來看待一個問題,它可以把一個特例當成正常情況來處理,這就是好的程式碼。
我就喜歡和這樣的人一起工作,他們有著更好的程式碼的“品味”。
好的程式碼“品味” 能夠讓你從更大的範圍來看待問題,本能地知道怎麼才能把事情做對,做好。
這兩段程式碼只是很簡單的例子,它們甚至不完美, 但我理解Linus所說的意思,它給我們的啟示是:在寫程式碼的時候,要努力地從更高的層次去思考問題,找到更抽象,更通用的解決方案,而不是簡單地對各種情況寫滿if else, 那樣的程式碼,難以理解,難以維護。
優雅的程式碼不僅僅是格式規範,命名良好,更重要的是思維方式和抽象層次,以及由此帶來的良好的設計。