JavaRush /Java Blog /Random-TW /喝咖啡休息#64。如何編寫乾淨的程式碼。為什麼對於低延遲系統來說 Java 比 C++ 更好

喝咖啡休息#64。如何編寫乾淨的程式碼。為什麼對於低延遲系統來說 Java 比 C++ 更好

在 Random-TW 群組發布

如何寫乾淨的程式碼

來源:Dev.to 寫乾淨的程式碼就像寫詩。這首詩應該簡潔、易懂、易於改變。乾淨的程式碼意味著可擴展的組織。這意味著做出改變不會造成混亂。編寫此類程式碼的能力是經驗豐富的開發人員的關鍵品質之一。在幾個人推薦我讀《Clean Code》這本書後,我終於鼓起勇氣讀了它。事實證明,這是一本封面完全符合其炒作的書。書中的建議清晰、具體、實用,甚至帶有幽默感。今天我想與大家分享這本書的主要收穫。喝咖啡休息#64。 如何編寫乾淨的程式碼。 為什麼對於低延遲系統來說 Java 比 C++ 更好 - 1

1. 程式碼不僅要能工作,還要可讀

軟體的大部分成本與長期支援有關。因此,你寫的程式碼必須清楚表達你的意圖。它應該使得加入團隊的新開發人員能夠輕鬆理解程式碼中到底發生了什麼事以及為什麼。作者編寫的程式碼越容易理解,其他開發人員理解它所需的時間就越少。這減少了缺陷和維護成本。 如何實現這項目標?良好的命名+具有單一職責的類別和函數+編寫測試。

2. 後來意味著永遠不會

老實說:有時我們都向自己保證稍後會回來清理程式碼,但最終我們忘記了這一點。 不要留下不再需要的無用程式碼片段。它們會讓其他開發人員感到困惑並且沒有價值。因此,在更改功能時,請務必刪除舊程式碼。如果某個地方出現問題,測試仍然會立即顯示出來。 如何實現這項目標?刪除程式碼可能會很可怕,尤其是在大型架構中。所以測試是這裡的關鍵。它們使您可以放心地刪除程式碼。

3.特徵要小

編寫函數的第一條規則是它們應該很小,最多大約 20 行。函數越小,越專注於一項任務,就越容易為其找到一個好名字。至於函數參數,理想的數量是0。接下來是1、2,但你應該盡量不超過3個參數, 如何實現?函數的編寫應遵循單一責任、開放/封閉的原則。

4. 程式碼重複不好

重複是組織良好的系統的敵人。這是額外的工作、額外的風險和額外不必要的複雜性。 怎麼辦?確保你的程式碼是按照 DRY 原則編寫的,獨立且模組化。

5. 唯一好的評論是你找到了不寫的方法。

「沒有什麼比在正確的地方發表好評論更有用的了。但即使在最好的情況下,評論也是一種不可避免的罪。” 註釋旨在彌補我們無法用程式碼表達我們的想法的情況。也就是說,這最初是承認失敗。是的,我們必須使用它們,因為我們不能總是透過程式碼清楚地表達我們的意圖,但這並不是值得慶祝的理由。問題是,評論常常說謊。並不總是,也不是故意的,但太頻繁了。註釋越舊,離它所描述的程式碼越遠,它就越有可能是不正確的。原因很簡單:程式設計師無法很好地維護程式碼和所有註解。因此,註釋常常與它們引用的程式碼分離,並成為精確度最低的孤立註解。 怎麼辦?必須使用描述性命名方法。當你讀到變數的名稱時,你應該立即明白它是什麼。還需要進行測試,以便其他開發人員了解哪些功能最重要。

6. 對象揭示行為,但不揭示數據。

模組不應該知道它所操作的物件的內部結構。物件隱藏其資料並揭示其操作。這意味著物件不應透過存取器方法公開其內部結構。沒必要讓每個人都看到你的裸體。 怎麼辦?變數的範圍應盡可能是局部的,以免暴露超出必要的範圍。

7. 測試

測試程式碼與投入生產的程式碼同樣重要。因此,它必須隨著專案的發展而改變和成長。 測試可讓您的程式碼保持靈活、可維護和可重複使用。如果沒有它們,任何更改都可能會導致錯誤。測試使您可以清理程式碼,而不必擔心某些內容會損壞。因此,保持測試的純度非常重要。測試的簡潔性確保了它們的可讀性。測試是一個用簡單語言向其他開發人員解釋程式碼作者意圖的機會。因此,我們在每個測試函數中僅測試一個概念。這使得測試具有描述性,更易於閱讀,如果失敗,也更容易追蹤原因。 如何實現這項目標?必須遵循乾淨第一測試的原則。測試應該是:
  • 快速地。測試必須快速運行。如果您必須等待太長時間才能運行測試,則不太可能更頻繁地運行它。
  • 獨立/隔離(Independent)。測試應盡可能相互隔離和獨立。
  • 可重複。測試應該在任何環境(開發、登台和生產)中都是可重複的。
  • 自我驗證。測試結果必須是布林值。測試必須要么通過,要么失敗。
  • 徹底。我們應該努力透過測試來覆蓋所有邊緣情況、所有安全性問題、每個用例(use case)和happy path(對程式碼最有利的場景)。

8. 處理錯誤和異常

您拋出的每個異常都應該提供足夠的上下文來確定錯誤的來源和位置。通常,您有任何異常的堆疊跟踪,但堆疊跟踪不會告訴您失敗操作的目的。如果可能,請避免在程式碼中傳遞 null。如果您想從方法中傳回 null,請考慮拋出例外。將錯誤處理作為一項單獨的任務,可以獨立於主邏輯進行檢視。 如何實現這項目標?建立資訊豐富的錯誤訊息並將其與異常一起傳遞。指定失敗的操作和錯誤類型。

9. 課程

班級規模應該很小。但要計算的不是程式碼行數,而是責任。類別名稱是描述其職責的關鍵。我們的系統應該由許多小類組成,而不是幾個大類。每個這樣的小類必須封裝一個單一的職責。每個類別的存在必須只有一個特定的原因,並且每個類別必須與其他幾個類別「合作」以實現系統所需的行為。很少有充分的理由來創建公共變數。削弱封裝始終是最後的手段。此外,實例變數應該很少。良好的軟體設計允許在無需大量投資或返工的情況下進行更改。縮小變數範圍使這項任務變得更容易。 如何實現這項目標?關注點分離是最古老、最重要的設計技術之一。類別應該對擴展開放,但對修改關閉。在理想的系統中,我們透過擴展系統而不是更改現有程式碼來啟用新功能。

10. 格式化

每條空線都是一個視覺提示,有助於識別一個新的、獨立的概念已經開始。 局部變數必須出現在函數的頂部。 實例變數必須在類別的頂部聲明。 短線比長線更好。通常限制為 100-120 個字元;不應使其更長。 如何實現這項目標?大多數參數都可以傳遞給 CI 或文字編輯器中的 linter。使用這些工具使您的程式碼盡可能乾淨。

程式開發原則

使用以下技術,您的程式碼將始終保持乾淨: 命名變數。選擇適當的名稱(良好的命名)對於使程式碼可讀並因此可維護至關重要。 “你應該像為你的長子一樣負責任地為變數選擇一個名字。” 選擇好名字對於開發人員來說通常是一個挑戰。這需要良好的描述技巧和共同的文化背景。乾淨的程式碼是由完全不同的開發人員閱讀和改進的程式碼。變數、函數或類別的名稱應該回答所有基本問題:這個實體為什麼存在、它的用途和用途。如果一個名稱需要註釋,則表示它沒有充分揭示其所描述內容的本質。較長的名稱比較較短的名稱更重要,任何可搜尋的名稱都比常數更好。單字母名稱只能用作短方法內的局部變數:名稱的長度必須與範圍相符。方法名稱必須是動詞或動詞片語;類名不能是動詞。 依賴性應保持在最低限度。依賴你能控制的東西比依賴你無法控制的東西好。否則這些東西就會控制你。 準確性。每一段程式碼都應該位於讀者期望找到它的地方。程式碼庫的導航應該直觀,並且開發人員的意圖應該明確。 打掃。不要在程式碼庫中留下無用的程式碼(舊的且不再使用或創建的“以防萬一”)。減少重複並儘早創建簡單的抽象。 標準化。編寫程式碼時,您應該遵循為儲存庫建立的風格和實踐。 自律。隨著所用技術的發展和新技術的出現,開發人員通常希望更改和改進現有程式碼中的某些內容。不要太快屈服於炒作:徹底研究新堆疊,並且僅針對特定目的。保持程式碼庫清潔不僅僅是對當前和未來的同事有禮貌。這對於該程序的長期生存至關重要。你的程式碼越乾淨,開發人員就越高興,產品就越好,而且持續時間越長。

為什麼對於低延遲系統來說 Java 比 C++ 更好

資料來源:StackOverflow 身為開發人員,我們都知道有兩種方法可以做:手動、緩慢且煩人,或自動、困難但快速。我可以使用人工智慧為我寫這篇文章。這可以節省我很多時間——人工智慧每秒可以產生數千篇文章,但我的編輯可能會不高興得知生成第一篇文章需要兩年的時間。喝咖啡休息#64。 如何編寫乾淨的程式碼。 為什麼對於低延遲系統來說 Java 比 C++ 更好 - 2開發低延遲的軟體系統時也會出現類似的情況。傳統觀點認為,使用 C++ 以外的任何語言都是瘋狂的,因為其他語言都有太多的延遲。但我來這裡是為了讓您相信相反的、反直覺的、近乎異端的觀念:當談到在軟體系統中實現低延遲時,Java 更好。在這篇文章中,我想舉一個重視低延遲的軟體的具體例子:交易系統。然而,這裡提出的論點可以應用於幾乎任何需要或期望低延遲的情況。只是針對我有經驗的開發領域進行討論會比較容易。事實上,延遲是很難測量的。這一切都取決於你所說的低延遲是什麼意思。現在讓我們弄清楚這一點。

後天智慧

由於 C++ 更接近硬件,因此大多數開發人員會告訴您用這種語言進行編碼具有速度優勢。在低延遲情況下,例如高速交易,幾毫秒就可以區分出可行的軟體和遺留的磁碟空間浪費,C++ 被認為是黃金標準。至少過去是這樣。但現實情況是,許多大型銀行和經紀商現在都使用用 Java 寫的系統。我的意思是用 Java 原生編寫,而不是用 Java 編寫然後用 C++ 解釋以減少延遲。這些系統甚至正在成為一級投資銀行的標準,儘管它們(據稱)速度較慢。發生什麼事了?是的,C++ 在執行程式碼時可能具有“低延遲”,但在部署新功能甚至尋找可以編寫程式碼的開發人員時絕對不是低延遲。

Java 與 C++ 之間的(真實)差異

當談到現實系統中 Java 和 C++ 之間的差異時,開發時間問題只是一個開始。為了了解每種語言在這種情況下的真正價值,讓我們更深入地研究一下。首先,重要的是要記住在大多數情況下 C++ 比 Java 更快的真正原因:C++ 指標是記憶體中變數的位址。這意味著軟體可以直接存取各個變量,而不必爬行計算密集型表來查找它們。或者至少可以透過指定它們的位置來解決,因為使用 C++,您通常必須明確管理物件的生命週期和所有權。因此,除非您真的擅長編寫程式碼(這種技能可能需要數十年才能掌握),否則 C++ 將需要數小時(或數週)的調試。任何嘗試過調試蒙特卡羅引擎或 PDE 測試工具的人都會告訴您,嘗試從根本上調試內存訪問可能非常耗時。僅僅一個錯誤的指標就可以輕鬆地導致整個系統癱瘓,因此發布用 C++ 編寫的新版本確實是一件可怕的事情。當然,這還不是全部。喜歡用 C++ 程式設計的人會指出 Java 的垃圾收集器遭受非線性延遲峰值的困擾。在使用遺留系統時尤其如此,因此在不破壞客戶端系統的情況下發送 Java 程式碼更新可能會使它們變得如此緩慢以至於無法使用。作為回應,我想指出,在過去十年中,為了減少 Java GC 造成的延遲,我們做了很多工作。LMAX幹擾器例如,是一個用 Java 編寫的低延遲交易平台,也是作為一個框架構建的,與其運行的硬體具有“機械交互”並且不需要鎖定。如果您建立一個使用持續整合和交付 (CI/CD) 流程的系統,則可以進一步緩解問題,因為 CI/CD 允許自動部署經過測試的程式碼變更。這是因為 CI/CD 提供了一種迭代方法來減少垃圾收集延遲,Java 可以逐步改進並適應特定的硬體環境,而無需在交付之前為不同的硬體規格準備程式碼的資源密集型流程。由於 IDE 的 Java 支援比 C++ 廣泛得多,因此大多數框架(Eclipse、IntelliJ IDEA)都允許您重構 Java。這意味著 IDE 可以優化程式碼以實現低延遲效能,儘管這種能力在使用 C++ 時仍然受到限制。即使 Java 程式碼在速度上與 C++ 不太匹配,大多數開發人員仍然發現在 Java 中比在 C++ 中更容易實現可接受的效能。

我們所說的「更快」是什麼意思?

事實上,我們有充分的理由懷疑 C++ 是否真的比 Java“更快”,甚至具有“更低的延遲”。我意識到我正陷入一些相當黑暗的水域,許多開發人員會開始質疑我的理智。但請聽我說完。讓我們想像一下這樣的情況:您有兩個開發人員 - 一個用 C++ 編寫,另一個用 Java 編寫,您要求他們從頭開始編寫一個高速交易平台。因此,用 Java 編寫的系統比用 C++ 編寫的系統需要更長的時間才能完成交易。然而,Java 中未定義行為的實例比 C++ 少得多。舉一個例子,在陣列外部建立索引在 Java 和 C++ 中都是一個錯誤。如果您不小心在 C++ 中執行此操作,則可能會出現段錯誤,或者(更常見的是)您最終只會得到一些隨機數。在 Java 中,越界總是會拋出ArrayIndexOutOfBoundsException錯誤。這意味著 Java 中的偵錯要容易得多,因為錯誤通常會立即被識別出來,錯誤的位置也更容易被追蹤。此外,至少根據我的經驗,Java 更擅長識別哪些程式碼不需要運行,哪些對於軟體的運行至關重要。當然,您可以花幾天時間調整 C++ 程式碼,使其絕對不包含無關程式碼,但在現實世界中,每個軟體都包含一些臃腫的內容,而 Java 更擅長自動識別它。這意味著在現實世界中,即使按照標準延遲指標,Java 通常也比 C++ 更快。即使情況並非如此,語言之間的延遲差異也常常被其他因素所掩蓋,即使在高速交易中,這些因素也不足以產生影響。

Java 對低延遲系統的好處

在我看來,所有這些因素都為使用 Java 編寫高速交易平台(以及一般的低延遲系統,稍後會詳細介紹)提供了非常令人信服的論點。不過,為了稍微影響 C++ 愛好者,讓我們來看看使用 Java 的一些其他原因:
  • 首先,Java 在軟體中引入的任何額外延遲可能會比影響延遲的其他因素(例如網路問題)少得多。這意味著任何(編寫良好的)Java 程式碼在大多數交易情況下都可以輕鬆地與 C++ 一樣執行。

  • Java 較短的開發時間也意味著,在現實世界中,用 Java 編寫的軟體可以比 C++ 更快適應硬體變化(甚至新的交易策略)。

  • 如果您深入研究這一點,您會發現即使優化 Java 軟體也比 C++ 中的類似任務更快(考慮到整個軟體時)。

換句話說,您可以很好地編寫Java程式碼來減少延遲。您只需將其編寫為 C++,並在開發的每個階段牢記記憶體管理即可。不用C++編寫的好處是,用Java調試、敏捷開發、適應多種環境更容易、更快。

結論

除非您正在開發低延遲交易系統,否則您可能想知道上述任何內容是否適用於您。除了極少數例外,答案是肯定的。關於如何實現低延遲的爭論對於金融界來說既不新鮮也不獨特。因此,對於其他情況,可以從中學到寶貴的教訓。特別是,上面關於 Java「更好」的論點是因為它更靈活、更容錯、最終開發和維護速度更快,可以應用於軟體開發的許多領域。我(個人)更喜歡用 Java 編寫低延遲系統的原因與該語言在過去 25 年中如此成功的原因相同。Java 易於編寫、編譯、調試和學習。這意味著您可以花更少的時間編寫程式碼,而花更多的時間優化程式碼。在實踐中,這會帶來更可靠、更快速的交易系統。這對於高速交易來說是最重要的。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION