軟體開發的常見認知規律和原則 - Reflectoring

banq發表於2021-11-08

本文列舉了一些可以應用於軟體開發的最流行的規則和原則。對於每條定律,我們將快速討論其主要命題,然後探討如何將其應用於軟體開發。
 

帕累託原則(80/20 規則)
帕累託原則指出,通常80% 的結果來自 20% 的原因。數字 80 和 20 無論如何都不是精確的,但該原則的總體思路是結果通常分佈不均。
我們可以在生活的許多領域遵守這條規則,例如:

  • 世界上最富有的 20% 的人創造了世界 80% 的收入,
  • 80%的犯罪是由20%的罪犯所為
  • 自 2020 年以來,我們知道 80% 的病毒傳播來自 20% 的受感染人群。

我們可以從帕累託原則中獲得的主要好處是專注。它可以幫助我們專注於重要的事情(20%),而不是在不重要的事情(其他 80%)上浪費時間和精力。不重要的事情對我們來說往往很重要,因為有太多(而且看起來很緊急)。但是最好的結果往往是透過關注重要的少數來實現的。
在軟體開發中,我們可以使用它來專注於構建正確的功能,例如:
  • 專注於構成產品價值 80% 的產品功能的 20%,
  • 專注於導致 80% 使用者沮喪的 20% 錯誤,
  • 專注於 80% 的產品功能需要 20% 的總時間來構建,

關注“現在最重要的事情是什麼?” 可以幫助建立下一個最重要的事情,而不是下一個最緊急的事情。
順便說一下,敏捷和 DevOps 等現代開發方法有助於獲得這種關注!具有定期使用者反饋的快速迭代允許對重要事項進行資料驅動的決策。像基於主幹的開發與功能標記這樣的實踐可以幫助軟體團隊實現目標。
 

破窗定理
破碎的窗戶會招致故意破壞,因此很快就會損壞所有窗戶。
一般來說:混亂會招致更多的混亂。
如果我們的環境是原始的,我們就會有動力保持這種狀態。環境中的混亂越多,我們新增混亂的門檻就越低。畢竟已經混亂了……誰在乎我們是否再新增一點呢?
我們可以從這條規則中獲得的主要好處是我們應該意識到我們周圍的混亂。如果它達到人們習慣於不再關心它的程度,那麼最好給混亂帶來一些秩序。
在軟體開發中,我們可以將其應用於程式碼質量:我們引入程式碼庫的每一種程式碼味道都會降低我們新增更多程式碼味道的門檻。我們應該 [[Start clean]] 並保持程式碼庫乾淨以避免這種情況發生。許多程式碼庫如此難以理解和維護的原因是,破窗已經悄然出現並且沒有足夠快地修復。
我們也可以將這個原則應用到測試覆蓋率上:一旦有一定數量的程式碼進入了未被測試覆蓋的程式碼庫,就會新增更多未被覆蓋的程式碼。這是保持100% 程式碼覆蓋率(應該覆蓋的程式碼的)的論據,因此我們可以在視窗破裂之前看到裂縫。
 

奧卡姆剃刀
哲學剃刀是一種透過消除(或“削除”)不太可能的解釋來幫助解釋某些事情的原則。
奧卡姆剃刀說,如果有多個假設,我們應該選擇假設最少的假設(這很可能是解釋最簡單的假設)。
我們可以在事件分析中應用奧卡姆剃刀。您可能遇到過這樣的情況:使用者報告了您的應用程式存在問題,但您不知道導致問題的原因。因此,您正在搜尋日誌和指標,試圖找到根本原因。
下次使用者報告錯誤時,請維護事件調查文件。寫下您對導致問題的原因的假設。然後,對於每個假設,列出事實和假設。如果一個假設被證明是正確的,則將其標記為事實。如果一個假設被證明是錯誤的,請將其從文件中刪除或將其標記為錯誤。在任何時候,您現在都可以將時間集中在最可能的假設上,而不是浪費時間追逐紅鯡魚。
 

鄧寧-克魯格效應
鄧寧-克魯格效應表明,沒有經驗的人往往會高估自己的能力,而有經驗的人往往會低估自己的能力。
如果你不擅長某件事,你會認為你擅長它。如果你擅長某事,你會認為你不擅長 - 這可能導致冒名頂替綜合症,這讓你非常懷疑自己的能力,以至於你在其他具有相似技能的人中感到不舒服 - 不必要地害怕被暴露詐騙。
意識到這種認知偏差已經是朝著正確方向邁出的重要一步。它將幫助您更好地評估自己的技能,以便您可以尋求幫助,或者克服自我懷疑並自己動手。
有助於消除鄧寧-克魯格效應和冒名頂替綜合症的一種做法是結對或群體程式設計。你不是獨自工作,沉浸在自我懷疑或優越感中,而是與他人密切合作,在工作的同時交流思想、學習和教學。
不過,這隻適用於安全的環境。在個人主義被美化的環境中,結對或群體程式設計會導致更多的自我懷疑或更多的優越感妄想。
 

彼得原理
彼得原理指出,只要你成功,你就會得到晉升,直到你最終得到一份你不稱職的工作。
既然你不再成功,你就不會再得到提升,這意味著你將生活在一份不會給你帶來滿足感或成功的工作中,貫穿你的一生中。
在軟體開發中,當您將角色從開發人員職業轉換為管理職業時,彼得原則通常適用。然而,成為一名優秀的開發人員並不一定意味著你是一名優秀的經理。或者,您可能是一名優秀的經理,但只是不要從開發人員工作中獲得的經理工作中獲得滿足感,這意味著您沒有全力以赴(這就是我的情況)。在任何情況下,你都很痛苦,在你的職業道路上看不到任何未來的發展。
在這種情況下,退後一步,決定你希望你的職業是什麼樣子。然後,轉換角色(或公司,如果需要)以獲得您想要的角色。
 

帕金森定律
帕金森定律指出,工作總是會填滿分配給它的時間。如果您的專案在兩週內有截止日期,則該專案將不會在此之前完成。可能需要更長的時間,是的,但絕不會少於我們為它分配的時間,因為我們正在用不必要的工作或拖延來填補時間。
帕金森定律的主要驅動因素是:

  • 拖延症(“截止日期太遠了,所以我現在不需要匆忙……”),以及
  • 範圍蔓延(“當然,我們可以新增這個小功能,它不會花費我們太多時間......”)。

為了對抗拖延,我們可以在幾天而不是幾周或幾個月內設定最後期限。在接下來的 2-3 天內需要做什麼才能朝著目標前進?一個(健康的!)截止日期可以給我們足夠的動力,不要陷入拖延症的低谷。
為了防止範圍蔓延,我們應該非常清楚地瞭解我們試圖透過專案實現的目標。成功的衡量標準是什麼?這個新功能是否會增加這些指標?那麼如果每個人都明白這項工作需要更長的時間,我們應該新增它。如果新功能與使命宣言不符,就讓它不存在。
 

霍夫施塔特定律
霍夫施塔特定律指出**“它總是比您預期的要長,即使您考慮了霍夫施塔特定律”。
即使您瞭解了這條規則,並增加了專案的時間分配,它仍然會比您預期的要長。這與帕金森定律密切相關,即工作總是會填滿分配給它的時間。只有霍夫施塔特定律說它填充的時間超過了分配的時間。
這條定律得到了心理學的支援。我們容易出現所謂的“規劃謬誤”,即在估算工作時,我們通常不會考慮所有可用資訊,即使我們認為我們已經考慮了。我們的估計幾乎總是主觀的,很少是正確的。
在軟體開發中(以及任何其他基於專案的工作,真的),我們人類的樂觀主義佔了上風。估計幾乎總是過於樂觀。
為了減少霍夫施塔特定律的影響,我們可以嘗試儘可能客觀地進行估計。
寫下關於專案的假設和事實。將每個專案標記為假設或事實,以使資料質量可見並管理預期。
不要依賴直覺,因為每個人的感受都不一樣。寫下估算值,讓你的大腦思考它們。將它們與其他人的估計進行比較,然後討論差異。
即便如此,它仍然只是一個估計,很可能不能反映現實。如果估算不是基於統計資料或其他歷史資料,那麼它的價值就非常低,因此與要求您估算的人一起管理預期總是好的 - 總是會出錯。如果你讓它儘可能客觀,它就會減少錯誤。
 

康威定律
康威定律指出,組織建立的任何系統都將類似於該組織的團隊和溝通結構。
系統將有介面,構建系統的團隊有介面。如果您有 10 個團隊在一個系統上工作,您很可能會得到 10 個相互通訊的子系統。
我們可以應用所謂的逆康威機動:建立最能支援我們想要構建的系統架構的組織結構。(banq注:業務決定架構,還是架構決定業務,康威定律是業務決定架構,逆康威其實就是想實現架構決定業務,蒸汽機的工業機器決定了大批工人的生存方式。)
沒有固定的團隊結構,而是要有足夠的靈活性來建立和解散團隊,這對系統的當前狀態是最好的。
 

墨菲定律
墨菲著名的定律說,任何可能出錯的事情,都會出錯。它經常在意外發生後被引用。
軟體開發是一個很多事情都會出錯的職業。出錯的主要來源是錯誤。沒有任何軟體不存在測試使用者耐心的錯誤或事件。
我們可以透過在日常軟體開發實踐中養成習慣來減少錯誤的影響,從而抵禦墨菲定律。我們不能完全避免錯誤,但我們可以而且應該減少它們對使用者的影響。
對抗墨菲定律最有用的做法是特徵標記。如果我們使用功能標記平臺,我們可以在功能標記後面將更改部署到生產中。然後,我們可以使用有針對性的推出來啟用內部 dogfooding 的標誌,然後為少量友好的 Beta 使用者啟用它,最後將其釋出給所有使用者。透過這種方式,我們可以從越來越關鍵的使用者群體那裡獲得關於變化的反饋。如果更改出錯(並且在某些時候會出錯),影響很小,因為只有一小部分使用者組會受到它的影響。而且,該標誌可以快速關閉。
 

布魯克定律
在經典著作《人月神話》中,弗雷德·布魯克 (Fred Brook) 有句名言:為遲到的專案增加人力會使其更晚。
儘管本書討論的是軟體專案,但它適用於大多數型別的專案,甚至是軟體開發之外的專案。
新增人員不會提高專案速度的原因是專案的通訊開銷隨著新增到專案中的每個人呈指數增長。2個人有1條通訊路徑,5個人已經有5條了!= 120 條可能的通訊路徑。新人安頓下來並確定他們需要的溝通路徑需要時間,這就是為什麼在專案中新增新人時,遲到的專案會更晚。
解決辦法很簡單:更改截止日期,而不是將人員新增到已經遲到的專案中。
對在軟體專案中增加新人的期望要切合實際。將人員新增到專案中可能會在某個時候提高速度,但並非總是如此,當然也不是立即。人員和團隊需要時間來適應工作程式,而在某些時候,工作無法充分並行化,因此增加更多人是沒有意義的。仔細考慮一個新人應該做哪些任務,以及在將該人新增到專案中時您期望什麼。
 

波斯特定律
Postel 定律也被稱為穩健性原則,它規定你應該“在你所做的事情上保守,在你接受別人的事情上自由”。
換句話說,您可以接受多種不同形式的資料,以使您的軟體儘可能靈活,但在處理這些資料時應非常小心,以免因無效或惡意資料而損害您的軟體。
該定律源於軟體開發,因此非常直接適用。
您的軟體與其他軟體或人類之間的介面應允許不同形式的輸入以實現穩健性:

  • 為了向後相容,新版本的介面應該接受舊版本和新版本的資料,
  • 為了更好的使用者體驗,UI 中的表單應該接受不同格式的資料,這樣使用者就不必擔心格式。

但是,如果我們願意接受不同格式的資料,我們在處理這些資料時就必須保守。我們必須審查無效值,並確保我們不會因為允許太多不同的格式而損害系統的安全性。SQL 注入是一種可能的攻擊,它是透過對使用者輸入過於寬鬆而啟用的。
 

克奇霍夫原理
Kerchkhoff 的原則指出,加密系統應該是安全的,即使它的方法是公知的。只有您用來解密某些東西的金鑰才需要是私有的。
永遠不要相信要求一種方法是私有的加密系統。這被稱為“默默無聞的安全”。這樣的系統本質上是不安全的。一旦該方法向公眾公開,它就容易受到攻擊。
相反,依靠公開審查和信任的對稱和非對稱加密系統,在可以公開審查的開源包中實施。每個想知道他們內部如何工作的人都可以檢視程式碼並驗證它們是否安全。
 

萊納斯定律
據報導,萊納斯·託瓦茲 (Linus Torvalds) 說“如果有足夠的眼球,所有錯誤都是淺薄的”。
這意味著如果很多人看程式碼比很少人看程式碼可以更好地暴露程式碼中的錯誤。
如果您想擺脫錯誤,請讓其他人檢視您的程式碼。
源自開源社群的一種常見做法是讓開發人員提出包含程式碼更改的拉取請求,然後讓其他開發人員在將拉取請求合併到主分支之前審查該拉取請求。這種做法也進入了閉源開發,但根據 Linus 萊納斯定律,拉取請求在閉源環境(只有少數人檢視它)中的作用不如在開源環境中(其中可能很多貢獻者都在看它)。
為程式碼新增更多眼球的其他做法是結對程式設計和 mob 程式設計。至少在閉源環境中,這些在避免錯誤方面比拉取請求審查更有效,因為每個人都參與了程式碼的初始階段,這為每個人提供了更好的上下文來理解程式碼和潛在的錯誤。
 

沃斯定律
沃斯定律指出,軟體變慢的速度比硬體變快的速度要快。
不要依賴強大的硬體來執行效能不佳的程式碼。相反,編寫經過最佳化以表現良好的程式碼。
這必須與 [[軟體開發定律Knuth 的最佳化原則]] 的格言相平衡,該格言說“過早的最佳化是萬惡之源”。與為使用者構建新功能所花費的精力相比,不要在使程式碼執行得更快上花費更多的精力。
通常,這是一種平衡行為。( 演算法信仰的力量:改進演算法能提升多少效能?
 

Knuth 的最佳化原則
Donald Knuth 在他的一部作品中寫了“過早最佳化是萬惡之源”這句話,這句話經常斷章取意,被用作根本不關心最佳化程式碼的藉口。
根據 Knuth 定律,我們不應該浪費精力過早地最佳化程式碼。然而,根據沃斯定律,我們也不應該依賴硬體足夠快來執行最佳化不當的程式碼。
最後,這就是我從這些原則中得出的結論:

  • 最佳化可以輕鬆完成的程式碼,無需太多努力:例如,編寫幾行額外程式碼以避免經歷可能包含大量專案的迴圈
  • 最佳化一直執行的程式碼路徑中的程式碼
  • 除此之外,不要在最佳化程式碼上花費太多精力,除非您已經確定了效能瓶頸。

 

最後:保持懷疑
規則和原則是好的。這使我們能夠從某個角度評估某些情況,如果沒有它們,我們可能不會擁有這些情況。
然而,盲目地將規則和原則應用於每種情況是行不通的。每一種情況都會帶來微妙之處,這可能意味著某個原則不能或不應該被應用。
對你遇到的原則和規則保持懷疑。世界不是非黑即白的。

 

相關文章