🔍 搜尋結果:資料庫

🔍 搜尋結果:資料庫

從 SDE1 到 SDE2,甚至更高! 🚀 實際需要什麼。

> ***「我擅長寫程式碼。就在這個月,我發了 11 個 PR!我甚至按時更新了我的大部分票。也沒有請那麼多假!而且我也比 Sam 工作了更多時間!為什麼沒有我沒有升職,但他們卻升職了?*** > *-- 一些不幸的人,這次沒有得到促銷。* 這聽起來有關聯嗎? 我以前見過這個。 很多。 有時原因是辦公室政治。 🤬 有時,這只是期望沒有得到良好的溝通。那可能很糟糕。 🥲 有時,你如何達到既定的期望與實際的標準之間**存在不匹配**。 🤔 您可能無法控製或改變您的辦公環境。但你當然可以控制自己,確保沒有任何事情可以阻止你**在職業階梯上的上升**。 ![你明白了,規劃辦公室](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6htoz012vjxxtc5po2hk.gif) > ### 涼爽的!你能快速引導我完成我需要做的事情嗎? 首先要知道身為軟體開發人員的職責是什麼。我不是指您在目前組織中的職責,而是指作為整體和個人開發人員的職責。 #### 目錄 我認為開發人員應該致力於涵蓋**5 個廣泛的領域**。 *點擊連結可跳轉至該部分。* 1. [技術](#1-technical-skills-)(程式碼品質、語言熟練度、測試、效能) 2. [生產力](#2-productivity-)(可靠性和效率) 3. [協作](#3-collaboration-)(溝通和評論) 4. [所有權](#4-ownership-)(責任和主動性) 5. [影響](#5-impact-)(系統/產品改進和創新) *“至此,我們製作 D&D 角色表的工作就完成了一半。滾動 Nat 20!🤣”* **我只會介紹您可以控制的事情。** 我特別提到這一點是因為我看到許多組織犯錯的一件事是,評估的各個領域最終都包括您可能無法控制的事情。 例如,您可能無法控制您的工作對公司的影響力。在大多數情況下,您只能完成直接要求您做的事情。 > ### 好吧!我們走吧!我已經準備好升職了! ![辦公室一百萬美元](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2q5npkuc8euhcnb2pvtm.gif) 我上面提到的 5 個領域並不是 SDE1 所特有的。這是每個開發人員都需要掌握的東西。但每個領域的標準和期望都會改變。 讓我們討論一下每個領域的基線期望是什麼,以及您需要做什麼才能達到下一個水平。 **稍安毋躁。這會很長。** **但請記住,下面只有 5 個部分...👇** ![這需要一段時間](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qaj5r04sxuc1fsfsaqtv.png) ### 1. 技術能力[\[🔝\]](#table-of-contents) 在 SDE1,沒有人指望您能引起轟動、改變世界、節省數十億美元! 他們希望您以最少或最多偶爾需要指導的方式完成工作,並且您交付的工作不需要重新審視或修復(只要合理)。 **太長了;博士** 編寫其他人可以閱讀的體面程式碼,並且不會每 2 秒就中斷一次。 有幾種方法可以做到這一點。 **寫愚蠢的程式碼。不是“智能”程式碼。** - 您可能是 Leetcode、Hackerrank 或類似事物的奇才。但不幸的是,這些網站鼓勵初級人員如此努力地追求效能,以至於常常以**犧牲可讀性為代價**。 - 如果您知道兩個循環僅針對`i`和`j`的較小值執行,那麼使用嵌套循環並不是一個壞主意。 - 如果保證陣列最多只有幾個專案,那麼不使用映射/字典而不是陣列並不是一個壞主意。 ![編寫與閱讀程式碼](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/amla8isarsp66etjd99v.png) **了解該語言為您提供的所有工具。** - 您可能習慣於對所有事情使用 for 循環,但箭頭/lambda 函數可以使您的程式碼更具可讀性。 - \[JS 範例\] 你可能習慣將事物儲存在物件`{}`中,每次尋找的時間複雜度為 O(1),但是`set.has(thing)`比`!!obj[thing]` (甚至`Boolean(obj[thing])` **了解為什麼測試有價值,然後編寫測試** - 人們常常只是在寫測試,因為這是「最佳實踐」。 - 如果不了解背後的原因,您可能會編寫無效或毫無意義的測試。 - 這個想法是,**做任何你需要做的事情,以增加對程式碼穩定性的信心**。您需要使用類型嗎?當然。您需要聘請 QA 人員嗎?有點低效,但很酷。**也許你需要寫...測試?**好吧,但是……我的目標是什麼? - 這可以是一個單獨的部落格。**但這裡有一個簡短的簡短介紹...** - 您是否需要編寫單元測試、整合測試、驗收測試,無論您如何稱呼它們,都沒關係。人們可能對此感到「宗教」。但只要你的測試做了一件基本的事情,這一切都不重要…提高你對程式碼不會破壞的信心。 - 有時您可能需要重構程式碼,使其更易於測試,但是一旦您這樣做了幾次,您就會開始從可測試性的角度考慮程式碼。 - 在實現任何東西之前,為您預期的實作編寫測試也是一個好主意!導致測試套件一開始就完全失敗,而當您實施一些東西時,它會逐漸保持通過!順便說一句,這基本上就是測試驅動開發(TDD)。 **關心表現** - 沒有人會期望您始終以 60 FPS 的速度執行所有內容,或者所有內容的延遲都低於 100 毫秒。 - 但請注意,您的程式碼何時可能會導致對資料庫發出過多請求,或載入過多資料。不要讓你的元件渲染 5 次,因為你無法弄清楚如何正確使用`useEffect`和`useState` 。在需要的地方尋求協助,但要夠小心,不要讓這些東西進入生產階段。 ![延遲紙飛機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57g9q3qria2u6k6s3of5.gif) **⏫ 進入 SDE2:** - 更深入地了解您使用的語言和框架的內部結構。 🧠 了解 React 如何實際渲染事物。了解瀏覽器如何處理從瀏覽器到伺服器的多個請求。了解 Postgres 如何選擇優化或不優化查詢。了解應用程式部署管道的配置方式。 - 詢問有關專案、元件、API 等是如何建構的問題。了解這些設計模式的名稱以及它們的優點和缺點。開始參與架構討論並提出改進建議。誰知道?您可能有更有經驗的人沒有考慮到的想法。 - 指導他人最佳編碼實務。團隊中常常會有比你資歷低的人。查看他們的程式碼。讓他們審查您的程式碼並分享他們應該關注的內容。像尤達一樣,你應該分享你的智慧。 🧠 ### 2. 生產力[\[🔝\]](#table-of-contents) 作為 SDE1,您的生產力是透過您按時可靠地完成任務、有效管理工作負載以及保持專案一致進度的能力來衡量的。您還應該能夠處理輕微的干擾和依賴性,而不會失去焦點或需要持續的指導。 您可能經常需要依靠工具或應用程式或腳本來更有效地完成某些事情。有時您可能需要自己製作這些工具。 如果感覺太多了也沒關係。它不會總是完美的。即使是更資深的開發人員也並不總是能確定這一點。 你會到達那裡的。重要的是,如果您無法履行承諾,請儘早溝通。 **太長了;博士** 目標是按時出色地完成任務。當您覺得自己做不到時,請盡快讓人們知道。 **知道什麼時候該做什麼,什麼時候該說「不」🙅** - 學會區分什麼是緊急的,什麼是重要的。使用艾森豪威爾矩陣等工具有效地確定優先順序。 - 專注於高影響力的任務,但不要忽略那些讓車輪轉動的小任務。 - **學會說不。**天哪,這是一個很大的。這非常重要,以至於它可以單獨成為一個部落格。我有故事。 - 如果你不善於拒絕,你偶爾會發現自己的工作負擔過重。如果你能簡單、清楚地解釋你正在做的事情,以及你何時能夠處理下一件事情,人們通常會認為這是可以接受的。 - 如果你發現自己被逼入絕境,你需要依靠你的經理來為你確定優先事項。只需詢問他們認為最重要的是什麼。 ![沒有上帝請不](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46j4r2r8b9oho91fduvw.gif) *你看到這個人來了,不是嗎?* **管理好你的時間,別讓自己精疲力竭** - 使用番茄鐘等技巧來保持工作效率而不至於精疲力竭。我有很多朋友使用某種數字或實體番茄計時器來管理他們的工作日。 - 追蹤您在不同任務上的時間,以了解您可能在哪些方面花費了過多或過少的時間。 ![番茄計時器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ktom06mrbpkg10u0vslo.png) *我的朋友以前常用的番茄計時器* **如果必須的話,可以透過製作自己的工具來自動化無聊的工作** - 自動執行重複性任務以節省時間。腳本和工具可以處理很多平凡的事情。我已經建立了一大堆腳本、用於內部偵錯的 Slack 命令等,這已經為我和團隊在[Middleware](https://github.com/middlewarehq/middleware)節省了無數的時間。 - 熟悉 IDE 快捷方式、插件和其他可以加快開發過程的工具。如果您的團隊中的大多數人都使用 VSCode 進行開發,您甚至可以就通用 IDE 配置達成一致,並透過將 .vscode 目錄提交到儲存庫來共享該程式碼庫! **⏫ 進入 SDE2:** - 開始更獨立地管理您的專案。建立現實的時間表並滿足它們。 SDE1 可能會不時錯過時間表。 SDE2,則不然。你走得越高,你就越有可能提前完成你的專案! - 主動辨識並解決工作流程中的瓶頸。向團隊提出流程改善建議。通常,您可能沒有時間或支援來實施此類改進。一個可靠的 SDE2+ 舉措就是在其他工作之間的零碎時間裡自己完成,突然有一天,團隊的一些關鍵工作流程痛點神奇地得到了解決!都是因為你。 - 平衡多個專案和任務,同時不忘記最後期限,並了解您並不總是透過每天工作 28 小時來滿足最後期限,您會找到更有效地完成同一件事的方法。因此,表明您可以以相同的生產力水平承擔更多的責任。像托尼史塔克管理他的套裝技術一樣升級你的多任務遊戲! 🦾 ### 3. 合作[\[🔝\]](#table-of-contents) 在 SDE1,您需要清晰溝通、分享您的進步並成為樂於助人的團隊成員。您與他人有效協作的能力對於團隊的成功至關重要。 有很多人依賴你按時交付東西。他們是您的工程經理、產品經理,也許還有他們報告的其他經理,還有等待您完成專案部分的同事。 人們通常可能會晚一點理解某些事情,特別是如果儘早得知的話。但真正導致問題的是: - 不到最後一刻才告訴你會遲到。 - 您的估計不清楚或非常不準確。 我仍然把其中的一些搞砸了。但總體而言,情況確實有所改善。 👌 **太長了;博士** 做一個好的隊友並進行良好的溝通。 ![團隊合作](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/385iu3jjbits6zfgq6zz.gif) **早說、常說,但最重要的是──傾聽** - 讓您的團隊了解您的最新進展。透過站立會議和 Jira 或 Trello 等專案管理工具進行定期更新可以幫助每個人保持一致。 (我知道,Jira 很糟糕,但你必須明白,對於你的經理和高層來說,這是一個相當不錯的工具,可以用來追蹤事情的運作情況。) - 在會議和討論期間積極傾聽。在做出回應之前先了解別人在說什麼。 - 成為一個好的傾聽者也會讓你更快找到女朋友/男朋友🤣。如果你不這樣做,我們希望你能通過規則 1 和 2。 **保護您的生產,檢查程式碼** - 積極參與程式碼審查。提供建設性的回饋並樂於接受。非常關心不要讓可讀性差或有潛在風險(效能、使用者體驗或安全性方面)的程式碼最終出現在產品中。 - 從您收到的回饋中學習並將其應用到您未來的工作中。 如果您需要令人信服地了解為什麼程式碼審查至關重要以及如何正確執行,也許這會有所幫助: {% 嵌入 https://dev.to/middleware/the-senior-engineers-guide-to-the-code-reviews-1p3b %} **讓您的團隊隨時了解您所學到的知識** - 與您的團隊分享您所學到的知識。無論是新工具、編碼技巧還是有趣的文章,讓您的團隊了解情況有助於每個人成長。如果您使用 Slack,#engineering 頻道是進行此類活動的好地方。 #memes 也是如此。 😄 - 為程式碼庫或流程的複雜部分撰寫文件並建立指南。這有助於其他人更有效地理解和使用您的工作。記住這個文件需要可搜尋是非常重要的。無法搜尋到的文件就不存在。 [Glean](https://www.glean.com)可能是一個很好的工具來幫助解決這個問題,但它是一個付費(而且昂貴)的東西。 **⏫ 進入 SDE2:** - 發揮指導作用。幫助初級開發人員應對任務和挑戰。幫助他們規劃、估算、記錄等。 - 領導小型專案或倡議。表明您可以協調努力並將團隊聚集在一起以實現共同目標。 - 促進團隊內部的溝通。幫助解決衝突並確保每個人的意見都得到傾聽。每個團隊都有內向的人,通常他們是最難溝通的,盡可能幫助他們。成為團隊中的美國隊長,團結一致,以身作則! 🛡️ ### 4. 所有權[\[🔝\]](#table-of-contents) 擁有所有權意味著對你的工作及其影響負責。作為 SDE1,這意味著您應該確保您的程式碼按預期工作,勤奮地處理您的任務,並履行您的承諾。 就像創始人或執行長必須盡一切努力確保公司生存、繁榮和盈利一樣,你也必須盡一切努力確保你的工作符合規定的時間表,並以以下方式交付:不僅滿足,而且超越標準。 可以理解的是,有時設定的時間表或期望可能根本不切實際。這就是你的溝通技巧需要發揮的地方。 **太長了;博士** 擁有你的工作及其品質。完成你開始的事情。 ![德懷特覆蓋](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hc5yu0726kgkxrws7xmy.gif) *也許不像……那樣。* **學會承諾** - 如果您致力於一項任務,請堅持到底直至完成。如果遇到障礙,請儘早溝通。 - 不要推卸責任。如果您的程式碼或任務有問題,請努力解決它,而不是責怪他人。 **積極主動:看到一些事情,做一些事情** - 不要等待問題被分配給您。如果您發現有問題需要修復,請主動解決。當然,您需要適當地確定優先順序。並非所有需要修復的東西都需要您先停放正在處理的任何東西並先修復它。 - 提前想好。預測潛在問題並在它們成為問題之前解決它們。對於技術或工程相關的工作,ERD(工程需求文件)可以大大幫助您制定工作計劃。 - 您的經理可能會從他們的角度關注您團隊的生產力,但作為積極主動的開發人員,您也可以這樣做。畢竟,您才是真正了解是什麼讓您有生產力的人。如果你能想出一種方法向你的經理進行生產力分析,向他們展示你的團隊實際上做得很好,或者在需要他們注意的事情上遇到了阻礙,這會讓你得到一些嚴肅的觀點。 DORA 指標是衡量開發團隊生產力的一種相當流行的方法。如果您不確定如何開始衡量這樣的事情,也許這個部落格會有所幫助: [什麼是 DORA 指標?](https://www.middlewarehq.com/blog/what-are-dora-metrics-how-they-can-help-your-software-delivery-process) **每一天,都要比前一天更好** - 反思你的工作。什麼進展順利?還有什麼可以更好的呢?利用這種反思來不斷改進。這將是您的經理將(或應該)進行的 Sprint 回顧的更個人化版本。 - 積極尋求回饋並應用它。努力讓您承擔的每個專案變得更好。對於提供回饋的人來說,共享回饋也是一項艱鉅的工作。如果您的組織沒有為此定義流程,那麼每季、每月等阻止一些時間可能是個好主意。 - 嘗試遵循童子軍規則,該規則基本上規定您應該留下比您發現時更好的程式碼庫。[在這裡閱讀更多內容](https://deviq.com/principles/boy-scout-rule)。 **⏫ 進入 SDE2:** - 從頭到尾推動專案。承擔需要您在最少監督的情況下規劃、執行和交付的任務。如果你證明自己有足夠的自我能力,你的經理可能會讓你監督更多的開發人員來執行這個專案。現在這是一些高級開發的東西。 💪 - 辨識並實施流程、工具或程式碼庫的改進。之前也提到過,但這裡的重點略有不同。表明您正在著眼於更大的前景並為組織的長期成功做出貢獻。 - 倡導最佳實踐並確保它們得到遵循。成為您專案中的蝙蝠俠—可靠、警惕並始終提供卓越服務。 🦇 ### 5.影響[\[🔝\]](#table-of-contents) 作為 SDE1,您的影響可能僅限於分配給您的任務和專案。然而,表現出更廣泛的理解並在你的直接職責之外做出貢獻可以讓你與眾不同。影響力不僅指你所做的事情,也指你的工作如何影響和造福你的團隊、你的專案和整個組織。 **太長了;博士** 做出改變。不只是做,而是改進。 ![往前想](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikxg6wmu8bnj72alus4c.png) **不要局限於“你的工作”** - 了解您所從事的業務和行業。 - 確定改進或創新的機會。建議可以使團隊或產品受益的增強功能。 - 關注產品的最終用戶。了解他們的需求和痛點可以引導您做出更有影響力的貢獻。不要只是建立你要求的任何東西,還要分析你的努力對使用者和組織有多成功。 **為社區做出貢獻** - 參與內部和外部開發者社群。參加聚會、為開源專案做出貢獻或撰寫技術部落格。 - 分享您的知識和專業知識,幫助他人成長和學習。組織技術講座、網路研討會或程式設計訓練營或在技術講座、網路研討會或程式設計訓練營中發表演講。 - 與組織內的其他團隊合作。為跨職能專案提供協助和協作,以擴大您的影響力。 ![瑞安社區服務](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zh2nexhrfd6azq4cz6qm.gif) *您可能不會被「要求」在工作中幫助您的社區🤣* **積極主動地解決問題** - 超越任務的直接要求。考慮一下您的解決方案如何使其他專案或未來的工作受益。 - 養成批判性思考您使用的工具和流程的習慣。提出並實施可以節省時間、減少錯誤或提高效能的改進措施。 - 不要等待有人給您分配有影響力的工作。尋找機會做出有意義的貢獻,即使這意味著走出你的舒適圈。 有時您可能必須依賴第三方工具來辨識流程中的問題。像[中間件](https://github.com/middlewarehq/middleware)這樣的工具可以讓您發現軟體交付中的問題。現在這是高級開發人員的舉動。 {% 嵌入 https://github.com/middlewarehq/middleware %} **創新與改進** - 隨時了解您所在領域的最新趨勢和技術。嘗試可以使您的專案受益的新工具和方法。 - 考慮工作中的可擴展性和可維護性。設計系統並編寫可以隨著業務需求而成長和發展的程式碼。 - 鼓勵團隊內部的創新文化。促進腦力激盪會議和黑客馬拉松,以產生新的想法和解決方案。 **⏫ 進入 SDE2:** - 開始戰略性思考。找出對團隊目標和公司成功產生重大影響的方法。尋找您和團隊的工作模式,並提出可以使每個人受益的改進建議。大多數人都不太擅長這一點,所以如果你能做到這一點,那絕對會讓你脫穎而出。 - 領導推動創新和改進的措施。表明您可以創造性地思考並提出有效的解決方案。這可能涉及提出新功能、優化現有系統或改進開發流程。 - 倡導可以提高生產力或品質的新技術或方法。 🚀 帶頭將這些技術整合到您的專案中並指導其他人使用它們。 --- 請記住,從 SDE1 升級到 SDE2 以及更高版本是一個旅程。專注於你可以控制的事情,尋求回饋,並不斷改進。作為開發人員,您的成長是技術技能、生產力、協作、所有權和影響力的結合。透過奉獻和努力,您不僅會升級,而且會享受成為更好的工程師和有價值的團隊成員的過程。遊戲開始! 🎮 **PS:資深工程師擅長辨識阻礙團隊準時交付的各種問題,同時又不影響輸出品質。** 其中一些使用[中間件](https://github.com/middlewarehq/middleware)等工具。 {% 嵌入 https://github.com/middlewarehq/middleware %} --- 原文出處:https://dev.to/middleware/going-from-sde1-to-sde2-and-beyond-what-it-actually-takes-1cld

給中級開發人員的建議

序幕 == 我五年前寫了[這個博客](https://dev.to/rampa2510/3-tips-for-new-developers-49hj),當時我還是一名初級開發人員。我當時分享的技巧至今仍然是我遵循的規則,並且已經成為我不可或缺的一部分。作為一名開發人員,我已經成長了很多,所以現在我想作為中級開發人員回饋社區。 這裡提到的建議是針對那些熱愛自己的手藝並希望做得更好的人,不是為了更好的報酬,而是為了享受程式設計的樂趣。 1)熱愛你的工作 -------- 我看過人們把程式設計當作只是一份工作,只是為了錢。他們透過程式設計謀生並過上日常生活。這種生活方式很好,這是你的選擇。但如果你的技能沒有提高並且你變得停滯不前,請不要感到驚訝。要擅長編程,你必須熱愛你的工作。你一天的大部分時間都花在日常工作上編程,如果你不喜歡它,你就不會在工作的同時主動提高你的技能。 我有一個個人故事可以分享。我曾經在一家我討厭的公司工作過。我沒有主動改進程式碼庫或學習新東西來增強應用程式架構。現在,我從事著自己熱愛的工作,並將其視為自己的產品。這通常會引導我學習新事物並以結構良好的方式開發程式碼庫,因為我不想破壞它。如果你做你不喜歡的事,弊大於利。你可以在下班後學習,但你一天會浪費大約六個小時,但收效甚微。 2)成為多面手 ------- 永遠不要把自己放在一個盒子裡。不要認為自己只是前端開發人員或後端開發人員。將自己視為軟體開發人員。優秀的開發人員不會將自己局限於特定的技術,他們專注於解決問題,而不僅僅是問題的一部分。如果你將自己限制在某個堆疊上,你就不會成為一個偉大的問題解決者。軟體開發就是解決問題,如果你不了解如何建立端到端產品,你就不會成為一個好的問題解決者。 在職業生涯開始時,您可能必須選擇特定的堆疊來證明自己是一名出色的軟體開發人員。但不要讓它限制你。如果您在一家優秀的公司工作,請與資深或其他開發人員交談,以深入了解不同的團隊並學習新事物。開始負責公司程式碼庫的其他部分,以轉變為更全端的開發人員角色。這樣,您將開始更多地考慮解決整個問題,而不僅僅是解決部分問題。如果不歡迎您與其他堆疊一起工作,我建議您從事另一份工作。公司永遠不應該限制工程師的學習。 所以,做個多面手。不要將自己限制在堆疊的某一部分。學習作為軟體開發人員解決問題。通才發現更容易擅長解決特定問題,因為他們已經有了廣泛的理解,因此可以更快地掌握新技術。 3)永遠不要停止學習新技術(當修補匠) ------------------- 這是許多開發人員忽略的關鍵點。要成為優秀的問題解決者,您必須隨時了解科技的最新進展。我在嗜好專案中找到了很多樂趣,這幫助我發展了許多技能。當你修補新東西時,你會學到很多東西,而且你永遠不知道它什麼時候會變得有用。 例如,假設您的任務是為您的公司建立一個部落格應用程式。他們想要一個客製化的解決方案,而不是使用 Webflow 和其他類似服務的解決方案。如果您跟上了最新的進步,您可以使用 Supabase 或 Pocketbase 等現代 CMS 工具來快速開發後端。為您的部落格網站設定 CMS 可能只需要 30 分鐘,使您無需建立和管理資料庫和後端程式碼。然後你就可以根據你公司的需求專注於前端。 這是一個個人例子:我已經業餘學習了一個月的 Go。最近,我必須寫一個 cron 作業來每 30 分鐘更新一次使用者指標。我知道 Go 對於此類任務來說非常出色且速度非常快,因此我在 Go 中建立了 cron 作業,建置了二進位文件,並每 30 分鐘安排一個帶有計時器的系統守護程序任務。它工作效率高,消耗的資源更少。如果我沒有在業餘時間修修補補,只在日常工作中編寫程式碼,我就不會在合理的時間內想出最好的解決方案。 cron 作業將以 Node 編寫,隨著使用者群的成長,這將需要更多時間。 因此,永遠不要停止學習和創造。最好的學習方法是創造和修補。我一直在業餘學習 Ruby on Rails 和 Go,並且開始欣賞各種生態系統提供的不同功能。這幫助我將新想法融入我的工作流程中。 4)取得所有權 ------- 我最近觀看了 ThePrimagen 的一段[影片](https://www.youtube.com/watch?v=5i_O6NLXYsM&t=1586s),這激發了我寫這個博客的靈感。他提到解決問題或成為優秀軟體開發人員的最佳方法是擁有產品。他談到《毀滅戰士》是如何由四個人創造出來的,他們因為擁有所有權而交付瞭如此好的產品。他們知道自己沒有其他人可以依賴,因此他們將開發最好的軟體作為自己的責任。沒有備用計劃。 他們從未感到倦怠或放棄,因為他們擁有產品,而不僅僅是任務。 為了提高軟體開發人員的技能,您需要開始掌控您正在建立的產品,而不僅僅是功能或任務。當您將任何功能或錯誤視為您要解決的問題,而不僅僅是其他人的另一項任務時,您會發現開發產品會更加有趣。這是戰勝倦怠的最好方法。當您擁有所有權時,您會發現改進產品並使產品更有效率的樂趣。 如果你正在開發一個產品,當使用者發現它們時,你不能將出現的任何錯誤歸咎於其他人。如果出現問題,你就是問題的一部分,所以你必須承擔起解決問題的責任並創造出出色的產品。好的、可擴展的產品是由團隊建立的,如果你不承擔責任,你就不是一個好的團隊成員。當您擁有所有權時,您可以編寫最好的程式碼來建立最好的軟體,而不僅僅是另一個軟體產品。 就像製作《毀滅戰士》的四個人一樣,他們投入了大量的時間來創造屬於他們的東西,他們從不滿足於只是另一款遊戲,他們創造了一款定義時代的遊戲。其餘的,正如他們所說,是歷史。這同樣適用於你,如果你想製作最好的軟體,你必須開始擁有所有權並將該產品視為你自己的產品。 結語 == 寫完這個部落格並與社區分享我的想法後,我感覺很好。我們可能會爭論框架、語言和工具,但這些爭論有助於我們改進。他們推動技術進步,使我們的社區極具競爭力。讓我們保持激情! --- 原文出處:https://dev.to/rampa2510/advice-for-intermediate-developers-4777

建構強大的 CI/CD 管道:綜合指南

歡迎參加 DevSecOps in 5 的第 2 週:您獲得安全開發超級大國的門票! \_嘿,安全冠軍和編碼戰士! 您是否渴望提升 DevSecOps 水平並成為堅如磐石的軟體架構師?好吧,您來對地方了!這個為期 5 週的部落格系列是您掌握安全開發和部署的快速通道。 準備好拋棄開發戲劇,對您的安全實踐建立不可動搖的信心。我們同舟共濟,所以係好安全帶,讓我們踏上這段史詩般的旅程! --- 軟體開發環境處於不斷變化的狀態。更快的發布週期、不斷發展的技術以及不斷增長的品質需求正在推動團隊採用敏捷方法並擁抱自動化。進入 CI/CD 管道—簡化軟體交付背後的主力。這篇部落格深入探討了 CI/CD 的世界,提供了從入門到探索先進技術的全面指南。 為什麼 CI/CD 管道是您的秘密武器 ------------------- 在深入研究之前,讓我們先了解 CI/CD 管道無可否認的優勢: #### 更快的上市時間: 漫長的發布週期的日子已經一去不復返了。 CI/CD 可自動執行建置、測試和部署流程,從而實現頻繁且更快的部署。新功能可以更快地觸及用戶,保持他們的參與度並培養競爭優勢。 例:想像一家公司正在開發一個新的電子商務平台。透過實施 CI/CD 管道,他們可以自動部署新功能,例如改進的搜尋功能或更快的結帳流程。這使他們能夠快速響應用戶反饋和市場趨勢,在競爭中保持領先地位。 #### 提升軟體品質: 想像一下,儘早發現錯誤並在影響生產之前防止回歸。 CI/CD 在整個管道中整合了自動化測試。單元測試、集成測試,甚至端到端測試都可以無縫集成,確保每個階段的程式碼品質。 範例:開發金融服務應用程式的公司可以利用具有強大單元和整合測試的 CI/CD 管道。這確保帳戶管理和交易處理等關鍵功能在投入生產之前經過徹底測試,從而最大限度地減少錯誤和財務損失的風險。 #### 提高協作和效率: CI/CD 透過打破開發和營運團隊之間的孤島來促進協作。開發人員可以充滿信心地編寫程式碼,因為他們知道自動化測試提供了安全網。營運團隊受益於可預測和簡化的部署。這培育了一種共同所有權和責任的文化。 範例:在傳統的開發過程中,開發人員可能會將程式碼「越過牆」扔給操作,導致相互指責和延遲。透過 CI/CD 管道,兩個團隊都參與整個過程。開發人員可以看到他們的程式碼在自動化測試中的執行情況,而操作人員可以更了解即將進行的部署。這可以促進更順暢的協作和更快的問題解決。 設定您的第一個 CI/CD 管道(不僅僅是 Jenkins) ------------------------------ 雖然 Jenkins 仍然是一個流行的選擇,但 CI/CD 環境提供了大量工具來滿足您的特定需求。以下是一些受歡迎的競爭者,以及他們的優勢的簡要概述: #### GitLab CI/CD: 與 GitLab 緊密整合,實現無縫版本控制和 DevOps 工作流程。非常適合已經使用 GitLab 進行程式碼管理的團隊。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1masi4ldtu7fm6bz5kva.png) #### Circle CI: 基於雲端的平台以其易用性、可擴展性和注重開發人員體驗而聞名。對於尋求用戶友好且可擴展解決方案的團隊來說,這是一個不錯的選擇。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3sozor0d4vf3iik92n6.png) #### Azure DevOps: Microsoft 提供全面的 DevOps 工具鏈,提供 CI/CD 管道以及建置管理和工件儲存庫等其他功能。非常適合大量投資於 Microsoft 生態系統的組織。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hxmg0lxkoduvbopjhtll.png) #### Travis CI: 開源平台以其簡單性和專注於持續整合而聞名。對於小型團隊或從 CI/CD 開始的團隊來說,這是一個不錯的選擇。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hd6fr17cr7ckgfn5isyl.png) 現在,讓我們探討 CI/CD 管道的常見階段及其用途: #### 程式碼提交: 將變更推送到版本控制系統 (VCS)(如 Git)的觸發點。 #### 建造: 程式碼被編譯成可部署的工件(例如,可執行檔、WAR 檔)。 #### 測試: 針對建置的工件執行自動化測試,以辨識任何錯誤或回歸。 #### 部署: 測試成功後,工件將部署到目標環境(暫存、生產)。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kr66y6ycum7sd9suxpdd.png) #### CI/CD 工作流程設定範例(使用 GitLab CI/CD): ``` stages: - build - test - deploy build: stage: build script: - npm install - npm run build test: stage: test script: - npm run test deploy: stage: deploy script: - scp -r dist/ user@server_ip:/var/www/html/my_app only: - master ``` 將版本控制與 CI/CD 整合:自動化的力量 ---------------------- VCS 在 CI/CD 管道中發揮著至關重要的作用。這就是它的工作原理: #### 版本控制系統 (VCS): Git 等工具追蹤程式碼更改,允許開發人員協作並在需要時恢復到先前的版本。 CI/CD 管道利用此功能來確保可追溯性並在部署失敗時促進回溯。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mikn0zfpeydo5oiv2mno.png) #### 管道執行的觸發器: CI/CD 管道可以設定為自動觸發 VCS 內的特定事件。常見的觸發因素包括: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t3t78w8ex3pzkjpnwkg2.png) #### 程式碼提交: 每當開發人員將程式碼變更推送到特定分支時,管道就會啟動。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxx9bnifs1go7mw4frhx.png) #### 合併到特定分支: 僅當程式碼合併到特定分支(例如 master 或 staging)時才能觸發管道。這允許對部署進行更多控制。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vwx42no4pb94b3xxovzw.png) #### 被推送的標籤: 將標籤推送到儲存庫可以觸發管道,通常用於與版本相關的部署。 #### 分支策略: CI/CD 管道可以客製化以適應不同的分支策略。以下是兩種常見的方法: #### 功能分支工作流程: 開發人員為開發工作建立功能分支。完成並進行程式碼審查後,程式碼將合併到主分支(例如 master),觸發 CI/CD 管道進行部署。這種方法允許單獨開發和測試新功能。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8hmkjpemri80yjn2h9m.png) #### Git 流程工作流程: 此策略利用專用的開發分支進行持續開發。功能從開發中分支出來,並在測試後合併回來。合併以開發觸發 CI/CD 管道以部署到臨時環境。最後,從開發部署到生產需要手動升級。這種方法在開發、登台和生產環境之間提供了明確的分離。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6l6zc5zq47nljqjs17w4.png) #### 選擇分支策略: 最佳策略取決於您的團隊規模、專案複雜性以及所需的部署控制等級。功能分支工作流程適合專案較簡單的小型團隊。 Git Flow 為大型團隊或複雜專案提供了更多的環境控制和分離。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tsvx28v0iigzvwfobfng.png) 持續交付與持續部署: ---------- 了解差異 這些術語經常互換使用,但有一個關鍵區別: #### 持續部署: 成功完成管道後,變更將自動部署到生產中。這種方法需要強大的測試和對程式碼品質的高度信心。它非常適合風險承受能力低且注重快速迭代的應用程式。 範例:開發社交媒體應用程式的公司可能會利用持續部署來實現不影響核心功能的功能。自動化測試可確保品質,快速部署可實現快速實驗和功能推出。 #### 持續交付: 該管道自動建置、測試並部署到臨時環境。在部署到生產之前需要手動批准。這種方法為關鍵應用程式提供了一個安全網,並允許在實施變更之前進行手動監督。 例如:開發金融交易平台的公司可能會從持續交付中受益。管道成功執行後,部署將在投入生產之前進行分階段和審查。這確保了關鍵功能在影響現實世界的交易之前經過徹底的測試和批准。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7rlprqoto2rihmk28xu3.png) #### 選擇正確的策略: 持續部署和持續交付之間的選擇取決於以下因素: #### 風險承受能力: 對於具有高風險或影響的應用程式,可能首選透過手動批准進行持續交付。 #### 應用關鍵性: 關鍵任務應用程式可能會受益於生產部署之前手動批准的額外安全網。 #### 測試覆蓋範圍: 強大而全面的測試對於持續部署至關重要。如果測試範圍較小,則透過手動審核進行持續交付可能是更安全的選擇。 #### 回滾策略:總是有一個 B 計劃 無論您的 CI/CD 管道多麼細緻,都可能會出現不可預見的問題。制定回滾策略可確保您可以快速恢復到穩定狀態: ### 版本控制的救援: 如果部署出現問題,VCS 允許您輕鬆恢復到先前的程式碼提交。這是一種快速可靠的回滾部署方法。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/doul01tn1rf1bn51cs95.png) #### 回滾腳本: 在 CI/CD 管道中定義腳本,以便在發生故障時自動回滾部署。這可能涉及恢復基礎架構變更或降級配置。這些腳本提供了一種更自動化的回滾方法。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4swhforiux7h7sxnykkn.png) #### 藍/綠部署: 此策略涉及將新版本部署到單獨的環境(綠色),同時保持現有版本運作(藍色)。如果新版本正常執行,流量將切換到綠色環境。如果出現問題,可以無縫切換回藍色。藍/綠部署可最大限度地減少回滾期間的停機時間。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rhcwn0cwttal0yfymgk.png) #### 選擇回滾策略: 最佳方法取決於您的特定需求。 VCS 回滾簡單可靠,但需要手動介入。回滾腳本提供自動化,但需要仔細的設計和測試。藍/綠部署提供了更強大的回滾方法,但可能需要額外的基礎設施設定。 將您的 CI/CD 管道提升到新的水平 ------------------- #### CI/CD 管道安全: 安全性在任何軟體開發過程中都是至關重要的,CI/CD 管道也不例外。以下是保護管道安全的一些最佳實踐: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2hl4xwf0krot2nlx54p0.png) #### 管理秘密: 使用機密管理工具安全地儲存密碼、API 金鑰和資料庫憑證等敏感資訊。這些工具對機密進行加密並限制對 CI/CD 管道內授權使用者和應用程式的存取。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ieww0aoauvexapf9dkq.png) #### 限制存取控制: 在 CI/CD 工具中定義明確的存取控制,以限制誰可以修改或觸發管道。實施基於角色的存取控制 (RBAC) 以根據使用者角色和職責授予權限。這確保只有授權的個人才能更改管道配置。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wxvwarjo75beumbr0swk.png) #### 定期安全審核: 對 CI/CD 管道進行定期安全審核,以辨識和解決潛在漏洞。這種主動方法可以最大限度地降低未經授權的存取或安全漏洞的風險。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p0gobpx2nw8b0u9e867h.png) #### 監控和記錄: 密切監控 CI/CD 管道的性能和錯誤檢測。實施日誌記錄解決方案來追蹤管道執行並辨識潛在的瓶頸或故障。用於監控和記錄的常用工具包括: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzg4r2y894s742wbxd04.png) #### 格拉法納: 一個開源平台,用於視覺化來自各種來源(包括 CI/CD 管道)的指標和日誌。這允許您建立儀表板來監控管道執行狀況、建置時間和部署成功率。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vrob5ut2ipkrq6iz6y4.png) #### ELK 堆疊(Elasticsearch、Logstash、Kibana): 用於收集、儲存、分析和視覺化日誌的強大工具組合。您可以使用 ELK Stack 集中來自 CI/CD 管道和其他系統的日誌,以進行全面監控和故障排除。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gg5aqvi50jyoyd0rh81q.png) #### 內建監控工具: 許多 CI/CD 平台提供內建的監控和日誌記錄功能。利用這些工具深入了解管道執行並辨識潛在問題。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djrjfa9uk1if4jux25zg.png) #### 不同程式語言的 CI/CD: CI/CD 管道與語言無關。特定於您的程式語言的建置工具和測試框架可以無縫整合在管道中。這裡有些例子: #### 爪哇: Maven 或 Gradle 等建置工具可用於自動化 Java 應用程式的建置流程。可以整合 JUnit 等測試框架以進行單元測試和整合測試。 #### JavaScript: 對於 JavaScript 專案,npm 或yarn 等工具可以管理依賴項。 Jest 或 Mocha 等測試框架可用於自動化測試。 #### Python: Python 專案經常利用 setuptools 或 Poetry 等建置工具。像unittest或pytest這樣的測試框架是自動化測試的流行選擇。 請記住:雖然 CI/CD 管道的核心概念在不同語言中保持一致,但特定工具和配置可能會有所不同。研究適合您選擇的程式語言的最佳實踐和工具,以優化您的 CI/CD 管道。 加深您的 CI/CD 專業知識:進階主題 -------------------- CI/CD 是一個不斷發展的領域。讓我們探索一些進階概念,將您的管道推向極限: #### 先進的 CI/CD 技術: #### 基礎設施即程式碼 (IaC): Terraform 或 Ansible 等工具可讓您將基礎架構配置定義為程式碼。這些配置可以整合到您的 CI/CD 管道中,以自動化基礎設施配置和管理。 IaC 促進基礎設施的一致性、可重複性,並減少手動配置錯誤。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rpivmcb9c1792csuhjdo.png) #### 與遺留系統的持續整合: 將遺留系統整合到 CI/CD 管道中可能具有挑戰性。策略包括使用包裝器或適配器透過 API 公開遺留功能。這允許遺留系統與管道互動以進行自動化測試和部署。 #### 藍/綠部署: 前面討論過,藍/綠部署可最大限度地減少應用程式更新期間的停機時間。透過先部署到單獨的環境,您可以確保在出現問題時無縫回滾。 #### 金絲雀部署: 此策略涉及將應用程式的新版本部署到一小部分使用者(金絲雀),以便在全面部署之前辨識並修復問題。金絲雀部署可讓您在將新版本公開給所有使用者之前在有限的範圍內測試新版本,從而最大限度地降低風險。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g5df1jw6f9ckmtop4t7y.png) #### 不同專案類型的 CI/CD: #### 微服務架構: 基於微服務的應用程式可以受益於旨在處理單一微服務的獨立建置、測試和部署的 CI/CD 管道。這允許更快地部署和更輕鬆地管理複雜的應用程式。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uqrrbc30qetaklxuvmn.png) #### 使用 Docker 進行容器化: Docker 容器提供了一種打包和部署應用程式的標準化方法。 CI/CD 管道可用於跨環境自動建置和部署 Docker 映像。容器化簡化了部署並確保跨環境的應用程式行為一致。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xakuitegoux6baihwdb4.png) #### 用於機器學習 (ML) 專案的 CI/CD: 機器學習專案通常需要管理大型資料集和複雜模型。 CI/CD 管道可以客製化為: #### 自動化資料版本控制和管理: 確保用於培訓和測試的資料與程式碼變更一起進行追蹤和版本控制。這樣可以實現可重複性並更輕鬆地進行故障排除。 #### 整合模型訓練與測試: 在管道中利用 TensorFlow 或 PyTorch 等工具來自動化模型訓練和測試過程。這確保了模型在部署之前經過嚴格評估。 #### 管理模型部署: CI/CD 管道可用於將經過訓練的模型部署到生產環境。這簡化了流程並確保開發和生產模型之間的一致性。 持續改進與優化: -------- #### 效能優化: CI/CD 管道可能會遇到效能瓶頸,尤其是隨著專案的成長。以下是一些優化策略: #### 快取依賴: 快取經常使用的依賴項(例如,庫、套件)以減少建置期間的下載時間。這可以顯著提高建置速度,尤其是對於大型專案。 #### 並行化: 分解可以同時執行的管道階段(例如,不同模組的單元測試)並並行執行它們。這減少了整體管道執行時間。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tb4qguz8vmi4vb6anaiw.png) #### 資源優化: 根據管道階段的要求分配適當的資源(CPU、記憶體)。這確保了資源的有效利用並避免了瓶頸。 #### 指標和監控: 不要只是建立管道,還要積極監控其效能和運作狀況。就是這樣: #### 定義關鍵績效指標 (KPI): 確定代表管道有效性的指標,例如建置時間、部署頻率和回滾率。隨著時間的推移追蹤這些 KPI,以確定需要改進的領域。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8quogqkfkkjbkul4ype8.png) #### 利用監控工具: 實施 Grafana 或 Prometheus 等監控工具來視覺化管道指標並辨識潛在問題。這使您能夠主動解決瓶頸和效能下降。 #### 追蹤管道日誌: 日誌提供了有關管道執行的寶貴見解。利用 ELK Stack 等日誌分析工具來分析日誌並辨識可能表明潛在問題的錯誤或警告。 #### CI/CD 版本控制: 就像程式碼一樣對 CI/CD 管道配置進行版本控制。原因如下: #### 追蹤變化: 版本控制允許您追蹤對管道配置所做的更改,類似於追蹤程式碼更改的方式。這有助於在必要時進行回滾,並確保您可以恢復到先前的工作配置。 #### 協作與評審: 透過版本控制,多個團隊成員可以協作處理管道配置並在部署之前檢查變更。這可以促進最佳實踐並降低錯誤風險。 #### 災難復原: 如果您的 CI/CD 管道出現重大問題,版本控制可以讓您快速恢復到已知的良好狀態。這可以最大限度地減少停機時間並確保您可以從意外問題中恢復。 CI/CD 的未來:展望未來 -------------- CI/CD 格局不斷發展。以下是一些值得關注的令人興奮的趨勢: #### CI/CD 中的人工智慧和機器學習: 人工智慧可以自動化管道內的任務、優化資源分配並預測潛在問題。機器學習可用於分析歷史資料並提出管道的改進建議。這裡有些例子: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/frk52c5r06hdj3dvhc6r.png) #### 自動測試用例產生: AI可用於分析程式碼並自動產生測試案例,提高測試覆蓋率並減少手動工作。 #### 預測管道分析: 機器學習演算法可以分析管道資料,以在潛在瓶頸或故障發生之前預測它們。這允許主動幹預並確保管道平穩執行。 #### 自癒管道: 想像一下可以自動偵測故障並從故障中恢復的管道。這可能涉及重新啟動失敗的階段或回滾部署。人工智慧和機器學習在開發自我修復管道方面可以發揮至關重要的作用。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9uf4xg8jl4yvtcy4fqyd.png) #### 無伺服器應用程式的 CI/CD: 無伺服器功能變得越來越流行。 CI/CD 管道可用於自動部署和管理無伺服器功能。就是這樣: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7lflsufhkb84dsqk7dk.png) #### 建置與打包無伺服器功能: CI/CD 管道可用於建置無伺服器函數並將其打包到特定於雲端提供者的部署工件中(例如,AWS Lambda 套件、Azure Functions)。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9mnbn81w0w66yw39aq3x.png) #### 部署和管理無伺服器功能: 此管道可以自動將無伺服器功能部署到目標雲端平台。此外,它還可以根據流量模式管理配置更新和擴充。 #### 監控和優化無伺服器功能: CI/CD 管道可以與監控工具集成,以追蹤無伺服器功能的效能和成本。這允許持續優化和成本管理。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qv998kwcpr7cbo3fug4.png) 透過採用這些進步並不斷改進您的 CI/CD 實踐,您可以確保您的軟體交付快速、高效且可靠。以下是一些鞏固您的 CI/CD 知識的結論: CI/CD 是一段旅程,而不是目的地 建立防彈 CI/CD 管道是一個持續的過程。隨著專案的發展,調整和完善您的管道以滿足不斷變化的需求。隨時了解最新趨勢和工具,以持續優化您的 CI/CD 工作流程。 溝通和協作是關鍵成功的 CI/CD 管道需要開發、營運和安全團隊之間的密切協作。促進開放式溝通並鼓勵回饋,以確保管道符合每個人的需求。 測量和分析 不要只是建造管道並設置它就忘記它了。定期監控管道性能、分析指標並確定需要改進的領域。使用資料驅動的見解來優化您的 CI/CD 流程並確保其提供最大價值。 結論 -- CI/CD 管道是現代軟體開發的主力。透過了解本綜合指南中探討的核心概念、最佳實踐和先進技術,您可以幫助您的團隊更快、更有效率地交付高品質的軟體。擁抱 CI/CD,不斷改進您的管道,並見證您的軟體交付飆升至新的高度。 --- 我很高興有機會與您一起深入研究《建立防彈 CI/CD 管道:綜合指南》。這是一個令人著迷的領域,具有改善安全狀況的巨大潛力。 感謝您與我一起探索《建立防彈 CI/CD 管道:綜合指南》。您持續的興趣和參與推動了這趟旅程! 如果您發現有關建立防彈 CI/CD 管道:綜合指南的討論有幫助,請考慮與您的網路分享!知識就是力量,尤其是在安全方面。 讓我們繼續談話吧!在下面的評論中分享您的想法、問題或經驗《建立防彈 CI/CD 管道:綜合指南》。 渴望了解有關 DevSecOps 最佳實踐的更多資訊?請繼續關注下一篇文章! 透過共同努力並採用安全的開發實踐,我們可以建立一個更具彈性和值得信賴的軟體生態系統。 請記住,安全開發之旅是一個持續學習的過程。這是為了持續改進! --- 原文出處:https://dev.to/gauri1504/building-a-bulletproof-cicd-pipeline-a-comprehensive-guide-3jg3

使用 NextJS 建立電子商務商店

在本教程中,您將學習如何建立電子商務商店,客戶可以在其中透過 Stripe 購買產品並付款。成功付款後,將向客戶發送電子郵件通知,並向管理員用戶發送應用程式內通知。管理員用戶也可以在應用程式中建立和刪除產品。 為了建立這個應用程式,我們將使用以下工具: - [Appwrite](https://appwrite.io/) - 用於驗證使用者身份,以及保存和檢索產品詳細資訊。 - [Next.js](https://nextjs.org/) - 用於建立應用程式的使用者介面和後端。 - [Novu](https://docs.novu.co/getting-started/introduction) - 用於發送電子郵件和應用程式內通知。 - [React Email](https://react.email/docs/introduction) - 用於建立電子郵件範本。 - [Stripe](https://docs.stripe.com/) - 用於將付款結帳整合到應用程式中。 ![應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t02iyysrqjfqw8imuqxn.png) --- 使用 Next.js 建立應用程式介面 ------------------- 應用程式頁面根據指派給使用者的角色分為兩部分。客戶可以在付款前存取主頁並登入應用程式。管理員使用者可以存取所有頁面,包括登入頁面和儀表板頁面,他們可以在其中新增和刪除產品。 現在,讓我們建立應用程式。 ![https://media1.giphy.com/media/iopxsZtW2QVRs4poEC/giphy.gif?cid=7941fdc6aot3qt7vvq4voh5c1iagyusdpuga713m8ljqcqmd&ep=v1_gifs_searchiagyusdpuga713m8ljqcqmd&ep=v1_gifs_searchiagyusdpugagif&ct](https://media1.giphy.com/media/iopxsZtW2QVRs4poEC/giphy.gif?cid=7941fdc6aot3qt7vvq4voh5c1iagyusdpuga713m8ljqcqmd&ep=v1_gifs_search&rid=giphy.gif&ct=g) 透過執行以下程式碼片段來建立一個新的 Next.js Typescript 專案: ``` npx create-next-app novu-store ``` 接下來,安裝[React Icons](https://react-icons.github.io/react-icons)和[Headless UI](https://headlessui.com/)包。 React Icons 允許我們在應用程式中使用各種圖標,而 Headless UI 則提供易於使用的現代 UI 元件。 ``` npm install react-icons @headlessui/react ``` 將此程式碼片段從[GitHub 儲存庫](https://github.com/dha-stix/ecom-store-with-nextjs-appwrite-novu-and-stripe/blob/main/src/app/page.tsx)複製到`app/page.tsx`檔案中。它在螢幕上呈現產品列表,並允許用戶選擇購物車中的商品,類似於下圖。 ![1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dj69givzhqfapgsg12rk.gif) 建立登入路由,使用戶能夠使用其 GitHub 帳戶進行簽署。將下面的程式碼片段複製到`app/login/page.tsx`檔案中。 ``` //👉🏻 create a login folder containing a page.tsx file export default function Home() { const handleGoogleSignIn = async () => {}; return ( <main className='w-full min-h-screen flex flex-col items-center justify-center'> <h2 className='font-semibold text-3xl mb-2'>Customer Sign in</h2> <p className='mb-4 text-sm text-red-500'> You need to sign in before you can make a purchase </p> <button className='p-4 border-[2px] border-gray-500 rounded-md hover:bg-black hover:text-white w-2/3' onClick={() => handleGoogleSignIn()} > Sign in with GitHub </button> </main> ); } ``` ![客戶登入](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nh2rowpfg4hgksj5diy.png) 當使用者點擊「登入」按鈕時,會將他們重新導向到 GitHub 驗證頁面並提示他們登入應用程式。您很快就會了解如何使用[Appwrite](https://appwrite.io/)執行此操作。 接下來,讓我們建立管理頁面。在`app`資料夾中新增包含`login`和`dashboard`路由的`admin`資料夾。 ``` cd app mkdir admin && cd admin mkdir dashboard login ``` 在`dashboard`和`login`資料夾中新增`page.tsx`文件,並將下面的程式碼片段複製到`login/page.tsx`檔案中。 ``` "use client"; import Link from "next/link"; import { useState } from "react"; export default function Login() { const [email, setEmail] = useState<string>(""); const [password, setPassword] = useState<string>(""); const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); console.log({ email, password }); }; return ( <main className='w-full min-h-screen flex flex-col items-center justify-center'> <h2 className='font-semibold text-3xl mb-4'> Admin Sign in</h2> <form className='w-2/3' onSubmit={handleLogin}> <label htmlFor='email' className='block'> Email </label> <input type='email' id='email' className='w-full px-4 py-3 border border-gray-400 rounded-sm mb-4' required value={email} placeholder='[email protected]' onChange={(e) => setEmail(e.target.value)} /> <label htmlFor='password' className='block'> Password </label> <input type='password' id='password' className='w-full px-4 py-3 border border-gray-400 rounded-sm mb-4' required value={password} placeholder='admin123' onChange={(e) => setPassword(e.target.value)} /> <button className='p-4 text-lg mb-3 bg-blue-600 text-white w-full rounded-md'> Sign in </button> <p className='text-sm text-center'> Not an Admin?{" "} <Link href='/login' className='text-blue-500'> Sign in as a Customer </Link> </p> </form> </main> ); } ``` 上面的程式碼片段呈現一個表單,該表單接受管理員的電子郵件和密碼,驗證憑證,然後將使用者登入應用程式中。 ![管理員登入](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gjd9wsi63t96d5cls9om.png) 管理儀表板頁面呈現可用的產品,並允許管理員使用者在應用程式中新增和刪除產品。將此[程式碼片段複製](https://github.com/dha-stix/ecom-store-with-nextjs-appwrite-novu-and-stripe/blob/main/src/app/admin/dashboard/page.tsx)到`dashboard/page.tsx`檔案中以建立使用者介面。 ![2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1gd1uq1eq6n76fesjxu.gif) 恭喜!您已經建立了應用程式介面。在接下來的部分中,您將了解如何將應用程式連接到 Appwrite 後端並在客戶端和伺服器之間發送資料。 --- 如何將 Appwrite 新增到 Next.js 應用程式 ----------------------------- Appwrite 是一項開源後端服務,可讓您建立安全且可擴展的軟體應用程式。它提供多種身份驗證方法、安全性資料庫、文件儲存、雲端訊息傳遞等功能,這些對於建立全端應用程式至關重要。 在本部分中,您將了解如何設定 Appwrite 專案,包括身份驗證、資料庫和檔案儲存等功能。 首先,請造訪[Appwrite Cloud](https://cloud.appwrite.io/register) ,並為您的專案建立一個帳戶和組織。 接下來,建立一個新專案並選擇您的首選區域來託管該專案。 ![應用程式寫入1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/as6302olk60oklfo70x5.png) 選擇`Web`作為應用程式的平台 SDK。 ![應用程式編寫2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bb5ae82i9fyoyrowsy96.png) 請依照螢幕上顯示的步驟進行操作。由於您目前正在開發模式下建置,因此您可以使用通配符 ( `*` ) 作為主機名,並在部署應用程式後將其變更為您的網域名稱。 ![應用程式寫入3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y5ccs0hzgs9ujf5lzh83.png) 在 Next.js 專案中安裝 Appwrite 用戶端 SDK。 ``` npm install appwrite ``` 最後,在 Next.js 應用程式資料夾中建立一個`appwrite.ts`文件,並將下面的程式碼片段複製到該文件中以初始化 Appwrite。 ``` import { Client, Account, Databases, Storage } from "appwrite"; const client = new Client(); client .setEndpoint("https://cloud.appwrite.io/v1") .setProject(<YOUR_PROJECT_ID>); export const account = new Account(client); export const db = new Databases(client); export const storage = new Storage(client); ``` ### 使用 Appwrite 設定 GitHub 身份驗證 在這裡,您將了解如何使用 Appwrite 設定 GitHub 和電子郵件/密碼驗證。預設已配置電子郵件/密碼身份驗證,因此我們專注於設定 GitHub 身份驗證。 在繼續之前,您需要使用您的 GitHub 帳戶建立[GitHub OAuth 應用程式](https://github.com/settings/developers)。 Appwrite 將需要客戶端 ID 和金鑰來設定 GitHub 身份驗證。 ![GitHub 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9znk1yr7tffus7soitq2.png) 透過從側邊欄選單中選擇`Auth`並導覽至`Settings`選項卡,啟用 Appwrite 的 GitHub 驗證方法。 ![應用程式編寫4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43uo6nho1bz9su14zsno.png) 將您的 GitHub 用戶端 ID 和金鑰複製到 Appwrite 的 GitHub OAuth 設定中。 最後,確保將 Appwrite 產生的 URI 複製到 GitHub 應用程式設定中。 ![GitHub 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g75q5r5hc6l5pi09k88m.png) ### 設定 Appwrite 資料庫 從側邊欄選單中選擇資料庫並建立新資料庫。您可以將其命名為`novu store` 。 ![應用程式寫入5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y7kn1llmu7olqirfcrpa.png) 接下來,建立`products`集合。它將包含應用程式中的產品清單。 ![應用程式寫入 6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7p8laty6z37x0q1g6az4.png) 將名稱、價格和圖像屬性新增至集合。 ![應用程式寫入 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzom3ptlz8t1rh9dtt1k.png) 在「設定」標籤下,更新權限以允許每個使用者執行 CRUD 操作。但是,您可以在部署應用程式後變更此設置,以確保只有經過身份驗證的使用者才能執行各種操作。 ![應用程式寫入 8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/37cqr8s0crtcttocjagk.png) 最後,將專案、資料庫和集合 ID 複製到**`.env.local`**檔案中。這可以確保您的憑證安全,並允許您引用其環境變數中的每個值。 ``` NEXT_PUBLIC_PROJECT_ID=<YOUR_PROJECT_ID> NEXT_PUBLIC_DB_ID=<YOUR_DATABASE_ID> NEXT_PUBLIC_PRODUCTS_COLLECTION_ID=<YOUR_DB_COLLECTION_ID> ``` ### 設定應用程式寫入存儲 從側邊欄選單中選擇`Storage` ,然後建立新儲存桶來儲存所有產品影像。 ![應用程式編寫 9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b84t9mk3k0wrkgiy4uca.png) 在`Settings`標籤下,更新「權限」以暫時允許任何使用者。 ![應用程式寫入 10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zi3iozkaera7fohkwanm.png) 設定可接受的文件格式。由於我們上傳的是圖像,因此您可以選擇**`.jpg`**和**`.png`**檔案格式。 ![應用寫入 11](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzxqpoq5dcpokkvdcsce.png) 最後,將您的儲存桶 ID 複製到`.env.local`檔案中。 ``` NEXT_PUBLIC_BUCKET_ID=<YOUR_BUCKET_ID> ``` 恭喜!您已成功配置 Appwrite。我們現在可以開始與其各種功能進行互動。 --- 如何使用Appwrite執行CRUD操作 -------------------- 在本部分中,您將了解如何從 Appwrite 建立、檢索和刪除產品。用戶需要能夠在購買前查看現有產品,而管理員用戶應有權在應用程式中新增和刪除產品。 首先,在 Next.js **`app`**資料夾中建立一個**`utils.ts`**檔案。該文件將包含所有 Appwrite 資料庫交互,然後您可以將其導入到必要的頁面中。 ``` cd app touch utils.ts ``` ### 將產品儲存到 Appwrite 回想一下, `products`集合有三個屬性:名稱、圖像和價格。因此,在將產品新增至資料庫時,您需要先上傳產品的圖像,從回應中檢索其 URL 和 ID,然後將 URL 作為產品的圖像屬性上傳,使用圖像的儲存 ID 作為產品資料。 這是解釋這一點的程式碼片段: ``` import { db, storage } from "@/app/appwrite"; import { ID } from "appwrite"; export const createProduct = async ( productTitle: string, productPrice: number, productImage: any ) => { try { //👇🏻 upload the image const response = await storage.createFile( process.env.NEXT_PUBLIC_BUCKET_ID!, ID.unique(), productImage ); //👇🏻 get the image's URL const file_url = `https://cloud.appwrite.io/v1/storage/buckets/${process.env.NEXT_PUBLIC_BUCKET_ID}/files/${response.$id}/view?project=${process.env.NEXT_PUBLIC_PROJECT_ID}&mode=admin`; //👇🏻 add the product to the database await db.createDocument( process.env.NEXT_PUBLIC_DB_ID!, process.env.NEXT_PUBLIC_PRODUCTS_COLLECTION_ID!, response.$id, //👉🏻 use the image's ID { name: productTitle, price: productPrice, image: file_url, } ); alert("Product created successfully"); } catch (err) { console.error(err); } }; ``` 上面的程式碼片段將圖像上傳到 Appwrite 的雲端存儲,並使用儲存桶 ID、圖像 ID 和專案 ID 檢索準確的圖像 URL。圖片成功上傳後,其 ID 將用於產品資料中,以便輕鬆檢索和參考。 ### 從 Appwrite 檢索產品 若要從 Appwrite 取得產品,您可以在頁面載入時在 React **`useEffect`**掛鉤中執行下列函數。 ``` export const fetchProducts = async () => { try { const products = await db.listDocuments( process.env.NEXT_PUBLIC_DB_ID!, process.env.NEXT_PUBLIC_PRODUCTS_COLLECTION_ID! ); if (products.documents) { return products.documents; } } catch (err) { console.error(err); } }; ``` `fetchProducts`函數傳回`products`集合中的所有資料。 ### 從 Appwrite 中刪除產品 管理員使用者也可以透過產品 ID 刪除產品。 **`deleteProduct`**函數接受產品的 ID 作為參數,並從資料庫中刪除所選產品(包括其圖像),因為它們使用相同的 ID 屬性。 ``` export const deleteProduct = async (id: string) => { try { await db.deleteDocument( process.env.NEXT_PUBLIC_DB_ID!, process.env.NEXT_PUBLIC_PRODUCTS_COLLECTION_ID!, id ); await storage.deleteFile(process.env.NEXT_PUBLIC_BUCKET_ID!, id); alert("Product deleted successfully"); } catch (err) { console.error(err); } }; ``` --- 如何使用 Appwrite 驗證使用者身份 --------------------- 在前面的部分中,我們已經設定了 GitHub 身份驗證方法。在這裡,您將了解如何處理使用者登入應用程式。 若要使客戶能夠使用其 GitHub 帳戶登入應用程式,請在按一下`Sign in`按鈕時執行以下功能。該函數將使用者重定向到 GitHub,在那裡他們可以向應用程式授權或授予權限,然後登入應用程式: ``` import { account } from "../appwrite"; import { OAuthProvider } from "appwrite"; const handleGoogleSignIn = async () => { try { account.createOAuth2Session( OAuthProvider.Github, "http://localhost:3000", "http://localhost:3000/login" ); } catch (err) { console.error(err); } }; ``` 管理員使用者可以使用電子郵件和密碼登入應用程式。 Appwrite 在授予對應用程式儀表板的存取權之前會驗證憑證。 ``` import { account } from "@/app/appwrite"; const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); try { await account.createEmailPasswordSession(email, password); alert(`Welcome back 🎉`); router.push("/admin/dashboard"); } catch (err) { console.error(err); alert("Invalid credentials ❌"); } }; ``` Appwrite 還允許您取得目前使用者的資料。例如,如果只有經過身份驗證的使用者才能付款,您可以透過執行下面的程式碼片段來完成此操作。它會檢索目前使用者的資料,如果使用者未登錄,則傳回 null。 ``` import { account } from "@/app/appwrite"; useEffect(() => { const checkAuthStatus = async () => { try { const request = await account.get(); setUser(request); } catch (err) { console.log(err); } }; checkAuthStatus(); }, []); ``` --- 如何將 Stripe 付款結帳新增至 Next.js -------------------------- 在本節中,您將了解如何在應用程式中實現 Stripe 付款結帳。 Stripe 是一種流行的線上支付處理平台,可讓您建立產品並將一次性和定期支付方式整合到您的應用程式中。 首先,您需要[建立一個 Stripe 帳戶](https://dashboard.stripe.com/login)。您可以在本教學中使用測試模式帳戶。 ![條紋1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nibs7bxb09i167mxm918.png) 點擊頂部選單中的`Developers` ,然後從 API 金鑰選單中複製您的金鑰。 ![條紋2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/up8757knbquc3k0577ps.png) 將您的 Stripe 金鑰貼到`.env.local`檔案中。 ``` STRIPE_SECRET_KEY=<your_secret_key> ``` 安裝[Stripe Node.js SDK](https://docs.stripe.com/libraries) 。 ``` npm install stripe ``` 接下來,在 Next.js `app`資料夾中建立一個`api`資料夾。 `api`資料夾將包含應用程式的所有 API 路由和端點。 ``` cd app mkdir api ``` 透過在`api`資料夾中新增`checkout`資料夾來建立`checkout`端點。 ``` cd api mkdir checkout && cd checkout touch route.ts ``` 將下面的程式碼片段複製到`route.ts`檔中。 ``` import { NextRequest, NextResponse } from "next/server"; import Stripe from "stripe"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); export async function POST(req: NextRequest) { //👇🏻 accepts the customer's cart const cart = await req.json(); try { //👇🏻 creates a checkout session const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: cart.map((product: Product) => ({ price_data: { currency: "usd", product_data: { name: product.name, }, unit_amount: product.price * 100, }, quantity: 1, })), mode: "payment", cancel_url: `http://localhost:3000/?canceled=true`, success_url: `http://localhost:3000?success=true&session_id={CHECKOUT_SESSION_ID}`, }); //👇🏻 return the session URL return NextResponse.json({ session: session.url }, { status: 200 }); } catch (err) { return NextResponse.json({ err }, { status: 500 }); } } ``` 上面的程式碼片段建立了一個接受 POST 請求的結帳端點。它為客戶建立結帳會話並傳回會話 URL。 **`cancel_url`**和**`success_url`**確定完成或取消付款後將用戶重新導向到何處。 最後,當用戶決定為產品付款時,您可以透過執行以下程式碼片段將客戶的購物車發送到`/checkout`端點: ``` const processPayment = async (cart: Product[]) => { try { if (user !== null) { //👇🏻 saves cart to local storage localStorage.setItem("cart", JSON.stringify(cart)); //👇🏻 sends cart to /checkout route const request = await fetch("/api/checkout", { method: "POST", body: JSON.stringify(cart), headers: { "Content-Type": "application/json" }, }); //👇🏻 retrieves the session URL const { session } = await request.json(); //👇🏻 redirects the user to the checkout page window.location.assign(session); } else { //👇🏻 redirects unauthenticated users router.push("/login"); } } catch (err) { console.error(err); } }; ``` 上面的程式碼片段將購物車儲存到瀏覽器的本機儲存體並將其傳送到 API 端點,然後從後端伺服器檢索回應(會話 URL)並將使用者重新導向至 Stripe 結帳頁面。 ![條紋3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5hokf2qyqyey3kwsg9x.gif) --- 使用 Novu 發送應用程式內通知和電子郵件通知 ------------------------ [Novu](https://github.com/novuhq/novu)是第一個提供統一 API 的通知基礎架構,用於透過多種管道(包括應用程式內、推播、電子郵件、簡訊和聊天)發送通知。 在本部分中,您將了解如何將 Novu 加入到您的應用程式,以便您能夠發送電子郵件和應用程式內訊息。 首先,安裝所需的 Novu 軟體包: ``` npm install @novu/node @novu/echo @novu/notification-center ``` 當用戶進行購買時,他們將收到一封付款確認電子郵件,管理員用戶也會收到一條應用程式內通知。 為此,您需要[在 Novu 上建立帳戶](https://web.novu.co/auth/login)並設定主要電子郵件提供者。在本教程中,我們將使用[“重新發送”](https://resend.com/docs/introduction) 。 在 Novu 上建立帳戶後,建立一個[重新傳送帳戶](https://resend.com/docs/introduction),然後從儀表板上的側邊欄選單中選擇`API Keys`來建立帳戶。 ![重新發送 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhehx7s45x180zpir1ti.png) 接下來,回到 Novu 儀表板,從側邊欄選單中選擇`Integrations Store` ,然後新增 Resend 作為電子郵件提供者。您需要將重新傳送 API 金鑰和電子郵件地址貼到必填欄位中。 ![新 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f03vb6nftyi8g790vg7m.png) 從側邊欄選單中選擇**「設定」** ,然後將您的`Novu API`金鑰和`App ID`複製到**`.env.local`**檔案中,如下所示。另外,將您的`subscriber ID`複製到其欄位中 - 您可以從`Subscribers`部分獲取此資訊。 ``` NOVU_API_KEY=<YOUR_API_FOR_NEXT_SERVER> NEXT_PUBLIC_NOVU_API_KEY=<YOUR_API_FOR_NEXT_CLIENT> NEXT_PUBLIC_NOVU_APP_ID=<YOUR_API_ID> NOVU_SUBSCRIBER_ID=<YOUR_API_FOR_NEXT_SERVER> NEXT_PUBLIC_NOVU_SUBSCRIBER_ID=<YOUR_API_FOR_CLIENT> ``` ![新2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/voeofvvtv88pex9rpr1s.png) 最後,將 Novu 通知鈴新增至管理儀表板,以使管理員使用者能夠在應用程式內接收通知。 ``` import { NovuProvider, PopoverNotificationCenter, NotificationBell, } from "@novu/notification-center"; export default function AdminNav() { return ( <NovuProvider subscriberId={process.env.NEXT_PUBLIC_NOVU_SUBSCRIBER_ID!} applicationIdentifier={process.env.NEXT_PUBLIC_NOVU_APP_ID!} > <PopoverNotificationCenter colorScheme='light'> {({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />} </PopoverNotificationCenter> </NovuProvider> ); } ``` ![儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m62ft87ue9orse2yww9z.png) --- 如何使用 Novu Echo 建立通知工作流程 ----------------------- [Novu](https://docs.novu.co/echo/quickstart)提供程式碼優先的工作流程引擎,讓您能夠在程式碼庫中建立通知工作流程。它允許您將電子郵件、簡訊、聊天範本和內容產生器(例如[React Email](https://react.email/docs/introduction)和[MJML](https://mjml.io/) )整合到 Novu 中,以建立高級且強大的通知。 在本部分中,您將了解如何在應用程式中建立通知工作流程、如何使用 Novu 的電子郵件通知範本以及如何使用 Novu 發送應用程式內通知和電子郵件通知。 透過執行以下命令安裝[React Email](https://react.email/docs/introduction) : ``` npm install react-email @react-email/components -E ``` 將以下腳本包含在您的 package.json 檔案中。 `--dir`標誌使 React Email 能夠存取位於專案內的電子郵件範本。在本例中,電子郵件範本位於`src/emails`資料夾中。 ``` { "scripts": { "email": "email dev --dir src/emails" } } ``` 接下來,在 Next.js `app`資料夾中建立一個包含`email.tsx`的`emails`資料夾,並將以下程式碼片段複製到該檔案中: ``` import { Body, Column, Container, Head, Heading, Hr, Html, Link, Preview, Section, Text, Row, render, } from "@react-email/components"; import * as React from "react"; const EmailTemplate = ({ message, subject, name, }: { message: string; subject: string; name: string; }) => ( <Html> <Head /> <Preview>{subject}</Preview> <Body style={main}> <Container style={container}> <Section style={header}> <Row> <Column style={headerContent}> <Heading style={headerContentTitle}>{subject}</Heading> </Column> </Row> </Section> <Section style={content}> <Text style={paragraph}>Hey {name},</Text> <Text style={paragraph}>{message}</Text> </Section> </Container> <Section style={footer}> <Text style={footerText}> You&apos;re receiving this email because your subscribed to Newsletter App </Text> <Hr style={footerDivider} /> <Text style={footerAddress}> <strong>Novu Store</strong>, &copy;{" "} <Link href='https://novu.co'>Novu</Link> </Text> </Section> </Body> </Html> ); export function renderEmail(inputs: { message: string; subject: string; name: string; }) { return render(<EmailTemplate {...inputs} />); } const main = { backgroundColor: "#f3f3f5", fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif", }; const headerContent = { padding: "20px 30px 15px" }; const headerContentTitle = { color: "#fff", fontSize: "27px", fontWeight: "bold", lineHeight: "27px", }; const paragraph = { fontSize: "15px", lineHeight: "21px", color: "#3c3f44", }; const divider = { margin: "30px 0", }; const container = { width: "680px", maxWidth: "100%", margin: "0 auto", backgroundColor: "#ffffff", }; const footer = { width: "680px", maxWidth: "100%", margin: "32px auto 0 auto", padding: "0 30px", }; const content = { padding: "30px 30px 40px 30px", }; const header = { borderRadius: "5px 5px 0 0", display: "flex", flexDireciont: "column", backgroundColor: "#2b2d6e", }; const footerDivider = { ...divider, borderColor: "#d6d8db", }; const footerText = { fontSize: "12px", lineHeight: "15px", color: "#9199a1", margin: "0", }; const footerLink = { display: "inline-block", color: "#9199a1", textDecoration: "underline", fontSize: "12px", marginRight: "10px", marginBottom: "0", marginTop: "8px", }; const footerAddress = { margin: "4px 0", fontSize: "12px", lineHeight: "15px", color: "#9199a1", }; ``` 上面的程式碼片段使用 React Email 建立了一個可自訂的電子郵件範本。您可以找到更多[易於編輯的靈感或模板](https://demo.react.email/preview/notifications/vercel-invite-user)。該元件還接受訊息、主題和名稱作為屬性,並將它們填入元素中。 最後,您可以在終端機中執行`npm run email`來預覽範本。 接下來,讓我們將電子郵件範本整合到 Novu Echo 中。首先,關閉 React Email 伺服器,然後執行下面的程式碼片段。它會在瀏覽器中開啟[Novu Dev Studio](https://docs.novu.co/echo/concepts/studio) 。 ``` npx novu-labs@latest echo ``` 在 Next.js 應用程式資料夾中建立一個包含`client.ts`檔案的`echo`資料夾,並將此程式碼片段複製到該檔案中。 ``` import { Echo } from "@novu/echo"; import { renderEmail } from "@/app/emails/email"; interface EchoProps { step: any; payload: { subject: string; message: string; name: string; totalAmount: string; }; } export const echo = new Echo({ apiKey: process.env.NEXT_PUBLIC_NOVU_API_KEY!, devModeBypassAuthentication: process.env.NODE_ENV === "development", }); echo.workflow( "novu-store", async ({ step, payload }: EchoProps) => { //👇🏻 in-app notification step await step.inApp("notify-admin", async () => { return { body: `${payload.name} just made a new purchase of ${payload.totalAmount} 🎉`, }; }); //👇🏻 email notification step await step.email( "email-customer", async () => { return { subject: `${payload ? payload?.subject : "No Subject"}`, body: renderEmail(payload), }; }, { inputSchema: { type: "object", properties: {}, }, } ); }, { payloadSchema: { type: "object", properties: { message: { type: "string", default: "Congratulations! Your purchase was successful! 🎉", }, subject: { type: "string", default: "Message from Novu Store" }, name: { type: "string", default: "User" }, totalAmount: { type: "string", default: "0" }, }, required: ["message", "subject", "name", "totalAmount"], additionalProperties: false, }, } ); ``` 此程式碼片段定義了一個名為`novu-store` Novu 通知工作流程,該工作流程接受包含電子郵件主題、訊息、客戶姓名和總金額的有效負載。 此工作流程有兩個步驟:應用程式內通知和電子郵件通知。應用程式內通知使用通知鈴聲向管理員發送訊息,而電子郵件則向客戶的電子郵件發送訊息。 接下來,您需要為 Novu Echo 建立 API 路由。在`api`資料夾中,建立一個包含`route.ts`檔案的`email`資料夾,並將下面提供的程式碼片段複製到該檔案中。 ``` import { serve } from "@novu/echo/next"; import { echo } from "@/app/echo/client"; export const { GET, POST, PUT } = serve({ client: echo }); ``` 在終端機中執行`npx novu-labs@latest echo` 。它將自動開啟 Novu Dev Studio,您可以在其中預覽工作流程並將其與雲端同步。 ![新3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ed2sl38m7zrlgjoj4a6y.gif) `Sync to Cloud`按鈕會觸發一個彈出窗口,其中提供有關如何將工作流程推送到 Novu 雲端的說明。 ![新4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ch8ba7y9klyudmmv9jz.png) 若要繼續,請在終端機中執行以下程式碼片段。這將產生一個唯一的 URL,表示您的開發環境和雲端環境之間的本機隧道。 ``` npx localtunnel --port 3000 ``` 將產生的連結與 Echo API 端點一起複製到 Echo Endpoint 欄位中,按一下`Create Diff`按鈕,然後部署變更。 ``` https://<LOCAL_TUNNEL_URL>/<ECHO_API_ENDPOINT (/api/email)> ``` 恭喜!您剛剛從程式碼庫建立了 Novu 工作流程。 ![新5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bdugs6g15y1e7xeixux.png) 最後,讓我們建立在用戶付款時發送電子郵件和應用程式內通知的端點。建立一個`api/send`路由並將下面的程式碼片段複製到檔案中: ``` import { NextRequest, NextResponse } from "next/server"; import { Novu } from "@novu/node"; const novu = new Novu(process.env.NOVU_API_KEY!); export async function POST(req: NextRequest) { const { email, name, totalAmount } = await req.json(); const { data } = await novu.trigger("novu-store", { to: { subscriberId: process.env.NOVU_SUBSCRIBER_ID!, email, firstName: name, }, payload: { name, totalAmount, subject: `Purchase Notification from Novu Store`, message: `Your purchase of ${totalAmount} was successful! 🎉`, }, }); console.log(data.data); return NextResponse.json( { message: "Purchase Completed!", data: { novu: data.data }, success: true, }, { status: 200 } ); } ``` 端點接受客戶的電子郵件、姓名和支付總額,並在付款成功後觸發 Novu 通知工作流程發送所需的通知。 --- 結論 -- 到目前為止,您已經學會如何執行以下操作: - 實施多種身份驗證方法,從 Appwrite 儲存和檢索資料和檔案。 - 使用 React Email 建立電子郵件模板,並使用 Novu 發送應用程式內和電子郵件通知。 如果您希望在應用程式中發送通知,Novu 是您的最佳選擇。使用 Novu,您可以為應用程式加入多個通知管道,包括聊天、簡訊、電子郵件、推播和應用程式內通知。 本教學的源程式碼可在此處取得: <https://github.com/novuhq/ecom-store-with-nextjs-appwrite-novu-and-stripe> 感謝您的閱讀! --- 原文出處:https://dev.to/novu/building-an-e-commerce-store-with-nextjs-49m

系統設計面試的資料庫分片

*揭露:這篇文章包含附屬連結;如果您透過本文中提供的不同連結購買產品或服務,我可能會獲得補償。* [![資料庫分片的類型](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/42ob2tziqrlt820gdsy7.jpg)](https://bit.ly/3pMiO8g) image\_credit -[設計大師](https://bit.ly/3pMiO8g) 朋友們大家好,在這個資料驅動的世界中,有效處理大量資料的能力對於企業和組織來說至關重要。 傳統的整體資料庫往往難以跟上現代應用程式和服務的需求,並成為效能瓶頸。 這就是**資料庫分片發揮**作用的地方,它為**水平擴展資料提供了強大的解決方案。** 如果你不知道什麼是Sharding?分片是一種資料庫架構技術,它將大型資料庫劃分為更小、更易於管理的部分,稱為“分片”,分佈在多個伺服器上。 每個分片都包含資料的子集,它們一起形成完整的資料集。這種方法透過分配工作負載、減少延遲和啟用並行處理來增強效能和可擴展性。 分片對於處理大規模應用程式和高流量系統特別有用,確保沒有單一伺服器成為瓶頸,並提高資料庫系統的整體效率和可靠性。 過去,我討論過常見的系統設計問題,例如[API 網關與負載平衡器](https://dev.to/somadevtoo/difference-between-api-gateway-and-load-balancer-in-system-design-54dd)、[水平與垂直擴展](https://dev.to/somadevtoo/horizontal-scaling-vs-vertical-scaling-in-system-design-3n09)、 [正向代理與反向代理](https://dev.to/somadevtoo/difference-between-forward-proxy-and-reverse-proxy-in-system-design-54g5),在這份全面的**資料庫分片指南**中,您將了解資料庫分片,探索其概念、優點、實施策略和實際用例。 分片也是系統設計面試的重要議題,因為 因為它展示了對如何處理大規模資料並提高系統效能和可擴展性的理解,這是開發人員的關鍵技能和經驗。 在這些面試中,通常會評估候選人設計能夠有效管理高流量和大量資料的系統的能力。分片展示了分散式系統、資料庫管理的知識以及解決潛在瓶頸和故障點的能力。 它反映了候選人設計彈性、高效能和可擴展架構的能力,這是在現實場景中建立強大且高效的軟體系統的關鍵技能。 順便說一句,如果您正在準備系統設計面試並想深入學習系統設計,那麼您還可以查看[**ByteByteGo**](https://bit.ly/3P3eqMN) 、 [**Design Guru**](https://bit.ly/3pMiO8g) 、 [**Exponent**](https://bit.ly/3cNF0vw) 、 [**Educative**](https://bit.ly/3Mnh6UR)和[**Udemy**](https://bit.ly/3vFNPid)等網站,這些網站有許多很棒的系統設計課程,這裡有一個很好的系統設計 Exponent 的面試備忘單,以快速修改面試的基本系統設計概念。 [![軟體設計面試備忘錄](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k3i7ytpm4lzhad3dclk5.png)](https://bit.ly/3cNF0vw) ***PS 繼續閱讀直到最後。我有一份獎金給你。*** 用於系統設計的資料庫分片 ------------ 現在,我們來了解一下什麼是資料庫分片?為什麼需要它以及它如何幫助擴展您的應用程式。我們還看到不同類型的資料庫分片,例如基於哈希和基於範圍的分片。 目錄 1. 介紹 2. 什麼是資料庫分片? 3. 為什麼要分片?對可擴展性的需求 4. 資料庫分片如何運作? 5. 分片策略 6. 挑戰和考慮因素 7. 現實世界的用例 8. 實施資料庫分片 9. 最佳實踐 10. 結論 一、簡介 ---- 在當今資料驅動的世界中,企業和組織被大量資訊淹沒。有效管理和處理這些資料是傳統整體資料庫難以應對的挑戰。 隨著用戶群的成長、應用程式工作負載的增加以及對即時分析的需求的飆升,對可擴展資料庫解決方案的需求變得至關重要。 > 這就是資料庫分片作為實現水平可擴展性的強大工具的作用。 [![資料庫分片概述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gx9climi3dpc0fpgie24.png)](https://bit.ly/3Mnh6UR) --- 2.什麼是資料庫分片? ----------- **資料庫分片是一種資料庫架構策略,用於跨多個資料庫執行個體或伺服器分割和分佈資料。**術語“分片”是指整個資料集的分區或子集。 每個分片獨立運作並包含一部分資料。透過將資料分佈在多個分片上,系統可以實現水平可擴展性,從而能夠處理更大的資料量和更高的工作負載。 分片對於資料集快速成長或高吞吐量要求的應用程式尤其有利,例如社交媒體平台、電子商務網站和遊戲應用程式。 它使這些應用程式能夠跨多個伺服器或叢集分配資料庫負載,從而防止任何單一資料庫伺服器成為瓶頸。 這是一個**簡單的圖表,將資料庫分片解釋為水平擴展:** [![什麼是資料庫分片](https://miro.medium.com/v2/resize:fit:609/1*Dmb3LCxTWjyGj_uYjEGnHA.png)](https://bit.ly/3P3eqMN) --- 3. 為什麼要進行資料庫分片?對可擴展性的需求 ----------------------- 現在,讓我們看看為什麼需要資料庫分片 ### 3.1.單體資料庫中的可擴展性挑戰 傳統的整體資料庫在可擴展性方面有其限制。在整體架構中,所有資料都儲存在單一資料庫執行個體中。 隨著資料量和使用者負載的增加,單體資料庫可能面臨幾個挑戰: - **效能瓶頸:**單一資料庫伺服器可能成為效能瓶頸,導致查詢回應時間緩慢且應用程式停機。 - **儲存有限:**單一伺服器的儲存容量有限,難以處理超大資料集。 - **垂直擴展成本**:透過升級硬體進行垂直擴展可能成本高昂,而且回報遞減。 - **複雜性:**管理大型整體資料庫可能很複雜且容易出錯,需要大量維護和最佳化。 ### 3.2.解決方案:透過分片實現水平可擴展性 資料庫分片透過將資料分佈在多個分片上(每個分片駐留在單獨的資料庫伺服器或叢集上)來解決這些可擴展性挑戰。這種方法有幾個優點: - **提高效能:**分片將資料庫負載均勻分佈在多個伺服器上,從而提高查詢效能和回應能力。 - **無限的可擴展性:**隨著資料的成長,可以加入新的分片,從而實現近乎無限的可擴展性。 - **成本效益:**與不斷升級單一伺服器相比,分片是一種經濟高效的解決方案。 - **高可用性**:分片可以提高容錯性和可用性,因為一個分片的故障不會影響整個系統。 這是資料庫的水平分片和垂直分片的樣子 [![如何使用分片擴充資料庫](https://miro.medium.com/v2/resize:fit:609/1*0j0DLUHN8EeykY-XxVSzJA.png)](https://medium.com/javarevisited/top-3-system-design-cheat-sheets-templates-and-roadmap-for-software-engineering-interviews-53012952db28) --- ### 4. 資料庫分片如何運作? 資料庫分片背後的核心思想是將資料分成更小的、可管理的部分,稱為分片。每個分片都是一個獨立的資料庫子集,用於儲存整個資料集的一部分。 分片可以分佈在多個資料庫伺服器或叢集\*\*,從而實現並行處理並提高效能。 以下是資料庫分片工作原理的進階概述: ![資料庫分片如何運作?](https://miro.medium.com/v2/resize:fit:609/1*1FCBTWUliqTM-VYNcd_YHA.png) 您可以看到資料庫分片提供了一種邏輯方法來將資料等級分割到多個伺服器和叢集上。 ### 4.1.資料分割區 分片的第一步是決定如何對資料進行分區。有幾種常見的分區策略,我們將在下一節中詳細探討。 分區策略的選擇取決於應用程式的要求和資料分佈。 ![資料分割區](https://miro.medium.com/v2/resize:fit:375/1*jsHUuhNxK-goazpSQUfAMg.png) ### 4.2.片鍵 **分片鍵**是用來決定特定資料屬於哪個分片的欄位或屬性。選擇合適的分片鍵至關重要,該鍵可以在分片之間均勻分佈資料,以防止熱點(分片接收的流量明顯多於其他分片)。 ### 4.3.資料分佈 一旦對資料進行了分區並選擇了分片鍵,資料就會分佈在可用的分片中。分發過程可以自動化,通常涉及分片機製或服務,根據分片鍵將資料路由到正確的分片。 ### 4.4.查詢路由 當對資料庫進行查詢或請求時,查詢路由器或協調器會根據分片鍵決定要查詢的分片。涉及多個分片的查詢可能需要結果的協調和聚合。 ### 4.5.聚合 在某些情況下,可能需要聚合多個分片的查詢結果才能產生最終結果。這種聚合可以發生在應用程式層級或透過專用聚合層。 ### 4.6.資料一致性 確保分片之間的資料一致性是分片的關鍵方面。兩階段提交或最終一致性等技術用於維護資料完整性。 [![資料庫分片完整指南](https://miro.medium.com/v2/resize:fit:497/1*ZVrIULaZsBFrzfEeoO63IQ.png)](https://www.java67.com/2019/09/top-5-courses-to-learn-system-design.html) --- 5. 分片策略 ------- 選擇正確的分片策略對於分片資料庫系統的成功至關重要。選擇取決於資料的性質、存取模式和可擴展性要求。以下是一些常見的分片策略: ### 5.1.基於範圍的分片 基於範圍的分片涉及根據分片鍵中特定值範圍對資料進行分區。例如,如果您要對客戶資料進行分片,則可以使用基於範圍的策略,其中每個分片包含姓氏以特定字母開頭或屬於特定範圍的客戶。 當資料分佈不均勻且您希望將相關資料保留在一個分片中時,基於範圍的分片非常有用。 以下是[DesignGuru.io](https://bit.ly/3pMiO8g)基於範圍的分片範例: [![基於範圍的資料庫分片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3j4ttcmk6e1oifbd4sr6.png)](https://bit.ly/3pMiO8g) --- ### 5.2.基於哈希的分片 基於雜湊的分片使用雜湊函數將分片鍵映射到特定分片。這種方法在分片之間均勻分佈資料,有助於避免熱點。 當資料存取模式不可預測或您想要確保資料均勻分佈時,基於雜湊的分片特別有效。 以下是[DesignGuru.io](https://bit.ly/3pMiO8g)在資料庫上基於哈希的分片範例: [![基於哈希的分片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hoks5uj5825fjwo9zd6m.png)](https://bit.ly/3pMiO8g) --- ### 5.3.基於目錄的分片 基於目錄的分片維護一個中央目錄,將分片鍵對應到對應的分片。此目錄有助於將查詢有效地路由到適當的分片。但是,它可能會引入單點故障。 基於目錄的分片適用於需要對分片分配保持高度控制的場景。 這是[DesignGuru.io](https://bit.ly/3pMiO8g)的基於目錄的分片範例 [![基於目錄的分片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s8691g3i2seemih5in0p.png)](https://bit.ly/3pMiO8g) --- ### 5.4.地理分片 在處理基於位置的資料(例如使用者位置)時,地理分片是相關的。資料根據與分片鍵關聯的地理區域進行分區。 此策略對於具有地理分佈的使用者或資料的應用程式很有價值。 正如他們所說,一張圖片勝過 1000 個單詞,這是來自[**Architecture Notes**](https://architecturenotes.co/database-sharding-explained/)的漂亮圖表,它解釋了不同類型的資料庫分片 ![資料庫分片策略](https://miro.medium.com/v2/resize:fit:609/1*_X8CwmkPPT1JLyiwSN6ZlQ.jpeg) 信用 --- <https://architecturenotes.co/database-sharding-explained/> --- 6. 挑戰和考慮 -------- 雖然資料庫分片提供了顯著的好處,但它也帶來了一系列挑戰和考慮因素: 6.1.資料遷移 在分片之間遷移資料可能非常複雜且耗時。正確的規劃和工具對於確保遷移過程順利進行至關重要。 6.2.備份與復原 管理備份並確保跨多個分片的資料復原需要仔細的規劃和強大的備份解決方案。 6.3.查詢複雜度 涉及來自多個分片的資料的查詢的實施和最佳化可能很複雜。應用程式程式碼可能需要處理查詢路由和結果聚合。 6.4.資料一致性 在分片環境中維護資料一致性可能具有挑戰性。開發人員需要考慮分散式事務、衝突解決和最終一致性等因素。 6.5.監控和擴展 有效的監控和擴展策略對於確保分片資料庫的健康和效能至關重要。辨識效能瓶頸並根據需要加入新分片至關重要。 ![資料庫分片的挑戰與注意事項](https://miro.medium.com/v2/resize:fit:609/1*GXRq3DgwsPpvG72EDUkX2Q.png) --- 7. 資料庫分片的實際用例 ------------- 資料庫分片適用於可擴展性和效能至關重要的各種現實場景。讓我們探討一些值得注意的例子: 7.1.社群媒體平台 Facebook、Twitter 和 Instagram 等社群媒體平台處理大量用戶生成的內容,包括貼文、圖像和影片。分片使這些平台能夠有效地分發和管理用戶資料。 7.2.電子商務網站 電子商務網站面臨著劇烈的流量波動,尤其是在促銷活動期間。分片幫助他們處理增加的負載並提供無縫的購物體驗。 7.3.遊戲應用 線上遊戲應用程式通常需要即時互動和低延遲回應時間。分片可確保遊戲資料的分佈以獲得最佳效能。 7.4.金融服務 金融機構每天處理大量的交易資料。分片允許他們擴展資料庫以處理負載,同時保持資料完整性。 ![MongoDB 中的資料庫分片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5rwxxozvp46xalmhu8r.png) --- 8. 如何實現資料庫分片? ------------- 實施資料庫分片需要仔細的規劃和執行。以下是涉及的步驟: 8.1.評估與規劃 首先評估應用程式的可擴展性要求和資料分佈模式。選擇合適的分片策略和分片鍵。 8.2.資料庫設計 設計資料庫架構以適應分片。定義資料如何跨分片分區和分佈。 8.3.分片實施 實施分片機製或使用適合您選擇的策略的分片資料庫系統。跨分片分佈現有資料。 8.4.查詢路由 發展一種查詢路由機制,根據分片鍵將查詢定向到適當的分片。如有必要,處理查詢聚合。 8.5。資料一致性 實施資料一致性機制,例如分散式交易或最終一致性,以維護資料完整性。 8.6。測試與優化 徹底測試分片資料庫系統,優化查詢並監控效能。根據需要擴展系統。 讓我告訴你一個秘密,分片還可以讓你的資料庫更快: ![分片如何使資料庫更快](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a4xuebb3yiyfkg4bebaz.png) --- ### 9. 資料庫分片最佳實踐 若要充分利用資料庫分片,請考慮遵循以下最佳實務: - **選出正確的分片鍵:** 選擇能夠均勻分佈資料並避免熱點的分片鍵。 - **監控和規模**: 持續監控分片資料庫的運作狀況和效能。隨著資料的成長加入新的分片。 - **備份和災難復原:** 實施強大的備份和復原程序來保護您的資料。 - **資料遷移:** 仔細規劃資料遷移並使用高效率的工具和流程。 - **查詢最佳化:** 優化分片環境中的查詢效能。 - **資料一致性:** 了解並實施適合您的應用程式的資料一致性模型。 而且,如果您需要備忘單,這裡有[**ByteByteGo**](https://bit.ly/3P3eqMN)提供的一份不錯的資料庫分片備忘單,可幫助您快速修改關鍵分片概念 [![資料庫分片備忘單](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgf23bifr1mvth1hol9j.jpg)](https://bit.ly/3P3eqMN) --- ### 系統設計訪談資源: 而且,這裡列出了最佳系統設計書籍、線上課程和練習網站,您可以查看這些內容,以便更好地為系統設計面試做好準備。這些課程中的大多數也回答了我在這裡分享的問題。 1. [**DesignGuru 的 Grokking 系統設計課程**](https://bit.ly/3pMiO8g):一個互動式學習平台,提供實作練習和真實場景,以增強您的系統設計技能。 2. [**《系統設計面試》作者:Alex Xu**](https://amzn.to/3nU2Mbp) :這本書深入探討了系統設計概念、策略和麵試準備技巧。 3. Martin Kleppmann 的[**「設計資料密集型應用程式」**](https://amzn.to/3nXKaas) :綜合指南,涵蓋了設計可擴展且可靠的系統的原則和實踐。 4. [LeetCode 系統設計 標籤](https://leetcode.com/explore/learn/card/system-design):LeetCode 是一個受歡迎的技術面試準備平台。 LeetCode 上的系統設計標籤包含各種練習問題。 5. GitHub 上的[**「系統設計入門」**](https://bit.ly/3bSaBfC) :精選的資源列表,包括文章、書籍和影片,可幫助您準備系統設計面試。 6. [**Educative 的系統設計課程**](https://bit.ly/3Mnh6UR):一個互動式學習平台,提供實作練習和真實場景,以增強您的系統設計技能。 7. **高可擴展性部落格**:該部落格包含有關高流量網站和可擴展系統架構的文章和案例研究。 8. **[YouTube 頻道](https://medium.com/javarevisited/top-8-youtube-channels-for-system-design-interview-preparation-970d103ea18d)**:請參閱「Gaurav Sen」和「Tech Dummies」等頻道,以取得有關係統設計概念和麵試準備的富有洞察力的影片。 9. [**ByteByteGo**](https://bit.ly/3P3eqMN) :Alex Xu 的一本現場書籍和課程,用於系統設計面試準備。它包含《系統設計訪談》第一捲和第二卷的所有內容,並將隨即將推出的第三卷進行更新。 10. [**Exponent**](https://bit.ly/3cNF0vw) :一個專為面試準備的網站,特別是針對亞馬遜和谷歌等 FAANG 公司,他們還有很棒的系統設計課程和許多其他材料,可以幫助您破解 FAAN 面試。 [![如何為系統設計做準備](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqv3p46jmw5qc0newuiu.jpg)](https://bit.ly/3P3eqMN) image\_credit - [ByteByteGo](https://bit.ly/3P3eqMN) 請記住透過參與實際專案和參加模擬面試將理論知識與實際應用結合。不斷的練習和學習無疑會提高你在系統設計面試中的熟練程度。 --- ### 10. 結論 這就是關於**資料庫分片及其工作原理的**全部內容。資料庫分片是實現水平可擴展性以及處理大量資料和高工作負載的強大策略。 透過跨多個分片分佈資料,組織可以提高效能、確保高可用性並滿足現代應用程式的需求。 然而,**分片並不是萬能的解決方案**,並且有其自身的一系列挑戰和考慮因素。正確的規劃、仔細的實施和遵守最佳實踐是成功分片的關鍵。 隨著資料量和複雜性不斷增長,掌握資料庫分片技術對於企業和開發人員來說變得越來越重要。 獎金 --- 正如承諾的,這是給你的獎金,一本免費的書。我剛剛找到一本新的免費書籍來學習分散式系統設計,您也可以在 Microsoft 上閱讀它 --- [https://info.microsoft.com/rs/157-GQE-382/images/EN-CNTNT -eBook-設計分散式系統.pdf](https://info.microsoft.com/rs/157-GQE-382/images/EN-CNTNT-eBook-DesigningDistributedSystems.pdf) ![學習分散式系統的免費書籍](https://miro.medium.com/v2/resize:fit:317/0*ICrIesz1fT-KtmUZ.png) --- 原文出處:https://dev.to/somadevtoo/database-sharding-for-system-design-interview-1k6b

Node.js 中的高階錯誤處理

錯誤處理是軟體開發的重要方面,可確保應用程式的行為可預測,並在出現問題時提供有意義的回饋。在 Node.js 中,由於其非同步特性,有效的錯誤處理可能特別具有挑戰性。本文深入探討了管理 Node.js 應用程式中的錯誤的先進技術和最佳實踐。 了解錯誤類型 ------ 在深入研究錯誤處理策略之前,了解可能遇到的錯誤類型非常重要: 1. 同步錯誤: 同步程式碼執行期間發生的錯誤可以使用 try-catch 區塊擷取。 2. 非同步錯誤: 錯誤發生在非同步程式碼執行期間,例如回呼、promise 和 async/await 函數。 3. 操作錯誤: 表示程式需要處理的執行時間問題(例如,無法連線到資料庫)的錯誤。 4. 程式設計師錯誤: 程式中的錯誤(例如,型別錯誤、斷言失敗)。通常不應以與操作錯誤相同的方式捕獲和處理這些錯誤。 **同步錯誤處理** ---------- 對於同步程式碼,錯誤處理使用 try-catch 區塊: ``` try { // Synchronous code that might throw an error let result = dafaultFunction(); } catch (error) { console.error('An error occurred:', error.message); // Handle the error appropriately } ``` **非同步錯誤處理** ----------- - *callback* 在基於回調的非同步程式碼中,錯誤通常是回呼函數中的第一個參數: ``` const fs = require('fs'); fs.readFile('/path/to/file', (err, data) => { if (err) { console.error('An error occurred:', err.message); // Handle the error return; } // Process the data }); ``` - *promise* Promise 提供了一種更簡潔的方法來使用 .catch() 處理非同步錯誤: ``` const fs = require('fs').promises; fs.readFile('/path/to/file') .then(data => { // Process the data }) .catch(err => { console.error('An error occurred:', err.message); // Handle the error }); ``` - *async/await* Async/await 語法允許在非同步程式碼中進行更同步的錯誤處理: ``` const fs = require('fs').promises; async function readFile() { try { const data = await fs.readFile('/path/to/file'); // Process the data } catch (err) { console.error('An error occurred:', err.message); // Handle the error } } readFile(); ``` 集中錯誤處理 ------ 對於較大的應用程式,集中錯誤處理可以幫助更有效地管理錯誤。這通常涉及 Express.js 應用程式中的中間件。 - *Express.js 中介軟體* Express.js 提供了一種透過中間件處理錯誤的機制。這個中間件應該是堆疊中的最後一個: ``` const express = require('express'); const app = express(); // Define routes and other middleware app.get('/', (req, res) => { throw new Error('Something went wrong!'); }); // Error-handling middleware app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ message: 'Internal Server Error' }); }); app.listen(3000, () => { console.log('Server is running on port 3000'); }); ``` 先進技術 ---- - *自訂錯誤類別* 建立自訂錯誤類別可以幫助區分不同類型的錯誤並使錯誤處理更加精細: ``` class AppError extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode; Error.captureStackTrace(this, this.constructor); } } // Usage try { throw new AppError('Custom error message', 400); } catch (error) { if (error instanceof AppError) { console.error(`AppError: ${error.message} (status: ${error.statusCode})`); } else { console.error('An unexpected error occurred:', error); } } ``` - *錯誤記錄* 實施強大的錯誤日誌記錄以監視和診斷問題。 Winston 或 Bunyan 等工具可以幫助記錄日誌: ``` const winston = require('winston'); const logger = winston.createLogger({ level: 'error', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'error.log' }) ] }); // Usage try { // Code that might throw an error throw new Error('Something went wrong'); } catch (error) { logger.error(error.message, { stack: error.stack }); } ``` - *全域錯誤處理* 處理未捕獲的異常和未處理的承諾拒絕可確保不會漏掉任何錯誤: ``` process.on('uncaughtException', (error) => { console.error('Uncaught Exception:', error); // Perform cleanup and exit process if necessary }); process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection at:', promise, 'reason:', reason); // Perform cleanup and exit process if necessary }); ``` 最佳實踐 ---- - 快速失敗:儘早偵測並處理錯誤。 - 正常關閉:確保您的應用程式在發生嚴重錯誤時可以正常關閉。 - 有意義的錯誤訊息:提供清晰且可操作的錯誤訊息。 - 避免靜默故障:始終記錄或處理錯誤以避免靜默故障。 - 測試錯誤場景:編寫測試來覆蓋潛在的錯誤場景並確保錯誤處理按預期工作。 結論 -- 為了有效地處理 Node.js 中的錯誤,您需要結合使用同步和非同步技術、集中管理以及進階策略,例如自訂錯誤類別和強大的日誌記錄。透過結合這些最佳實踐和先進技術,您可以建立強大的 Node.js 應用程式,優雅地處理錯誤並為用戶提供改進的體驗。 --- 原文出處:https://dev.to/amritak27/advanced-error-handling-in-nodejs-1ep8

資深工程師程式碼審查指南

程式碼審查。 ----- 你知道它們有多重要。 它們是獲得可靠程式碼的支柱之一。 然而,這是您在超級忙碌的日子裡需要**擠出**時間做的事情之一。 如果您不審查程式碼,那麼您可能會向用戶發送地雷,因為您永遠不知道它什麼時候會爆炸。 🤷 顯然,你知道這一點。你來這裡不是為了被告知「嘿!你應該進行程式碼審查!這是一件至關重要的事情! 我的團隊已經做了評論。我為什麼要在乎? ------------------- 如果不小心和勤勉地處理程式碼審查流程,可能會產生嚴重後果。 在我之前的一個組織中,程式碼審查通常沒有徹底完成,因此需要多次審查。它們也是由地球兩端的審查者完成的! 🌏 因此,處理任何評論幾乎花了一整天的時間。再說一次,因為評論通常不全面,所以 PR 的返工時間可能會因為一些瑣碎的事情而花費幾天的時間。 ![團隊週期時間分解](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvws8nxa2kjdvx6034n1.png) “如果不衡量,就無法改進” *通常被認為是彼得·德魯克(Peter Drucker)的作品,但我還沒有找到真正的證據。* 但我發現這句話對我的經驗來說意義深遠。 我過去曾向我的領導階層提出必要的組織變革,使所有團隊能夠減少跨時區的相互依賴,從而使人們能夠更快地協作。 我知道這樣做有多麼困難,但如果沒有可靠的資料支持理由來解釋為什麼需要改變,就更難實現任何改變。 *PS:這就是 Dhruv 和我創辦[Middleware 的](https://www.middlewarehq.com/)部分原因。 🚀* {% 嵌入 https://github.com/middlewarehq/middleware %} 好的,我聽到了。我有什麼選擇? --------------- 您理想的情況是進行徹底的程式碼審查,也就是說,明顯的危險訊號、效能或安全缺陷或其他難以閱讀的程式碼不應被忽視。 但您也希望所有這一切都在合理的時間內發生。 在合理的時間內合併經過嚴格審查的程式碼,這意味著您的團隊的交付可預測且具有高可靠性。 除非有一種經過充分研究、結構化的方法來掌握這一點。 🤔 …… 您聽過…DORA 指標嗎? 好吧,這不是另一部《DORA GOOD!文章。 這些是我過去專注於四鍵(正如出色的[Nathen Harvey](https://www.linkedin.com/in/nathen/)所[解釋的](https://dora.dev/guides/dora-metrics-four-keys/))如何幫助我改善我自己和我的團隊的程式碼交付體驗的經驗。 ![朵拉指標](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b49lb17w68bs5fojske7.png) *在中介軟體開源中看到的 DORA 指標* 使用 DORA 探索程式碼審查 --------------- ### 評論會延長交貨時間多久 審核週期長直接影響變更的前置時間。 交貨時間基本上由 5 個部分組成。 1. 從第一次提交到 PR 開放的時間 2. 然後 PR 收到第一次審核(可能是評論、更改、批准) 3. 更改 PR 直至最終獲得批准所花費的時間 4. 批准和 PR 合併之間的時間 5. PR最終部署的時間 當然,任何需要花費時間的部分都會增加您團隊的時間。但有兩個部分是造成延誤的特別嚴重的因素。這是#2 和#3。 **\#2. PR 收到第一次審核的時間(首次回應時間)** PR 公開後,開發人員實際上無法對其做太多事情。公關可能完全可以順利進行!它可能需要切實的改變。在這一點上,只有評論才能告訴我們答案。這也是開發人員可能無法承擔更多任務的時候,因為從技術上講,審查可能隨時發生,並且他們會遭受上下文切換的困擾。 **上下文切換是開發人員最大的生產力殺手之一。** ### 對「每次審核時間」的誤導性關注 這討論了提前期指標的第三個子部分。 **#3。更改 PR 所花費的時間(返工時間)** 這裡真正的問題不在於在這裡花了多少時間,而是來回發生了多少次。我們稱之為「返工週期」。 因為如果因為PR被批准而只有1個返工週期,那麼在批准之前可能仍然需要很長時間,但這是實際的實施時間,而不是空閒時間。可以透過更好的培訓、程式碼庫入門、上下文共享等來減輕這種返工。 但是…如果您要來回很多次,那麼每個週期都有一些與之相關的空閒時間,就像第一次回應時間一樣。 在此期間,開發人員無法接受新的工作,因為這將不可避免地導致快速的上下文切換。 這種情況很可能發生在PR太大而無法一次審完,或是審查者因為其他原因沒有審透徹底的情況下。當作者和審稿人位於相距甚遠的時區時,情況尤其嚴重。由於每次審核和返工都可能發生在各自時區的工作時間內,因此返工更改之前的時間可能會被誇大到很多小時。 **這就是滾雪球效應** 像這樣被屏蔽的 PR 越多,團隊交付的速度就越慢。通常新工作不會停止出現,這使得開發人員準確管理和評估他們的工作變得更具挑戰性。 如果這種情況持續發生,也會對團隊士氣造成打擊。 **博士** 僅僅專注於減少「每次審查的時間」可能會適得其反。 目標應該是在不犧牲徹底性的情況下優化審核流程,確保每次審核都能增加真正的價值。 ### 低於標準的審查和變更失敗率 團隊始終在壓力和緊迫的期限下運作。期望這種情況會神奇地改變是不合理的。但認為不會偷工減料以確保貨物不能按時發貨也是不切實際的。 由於我們談論的是程式碼審查,因此經常被削減的角落之一是: 1. 建立的大型 PR 包含某個功能的所有程式碼,而不是包含良好的較小且更易於審查的 PR。 2. PR 的審核只需略讀即可,因為審核者目前可能沒有足夠的心理能力或時間來正確處理它。 這兩件事時常發生。開發人員也是人。你不能僅僅把責任歸咎於他們或強迫他們「正確地」複習來解決這個問題。 最重要的是你首先要知道它正在發生。因為這樣你就可以做點什麼。你問,你怎麼知道這件事? 1. 您的交貨時間應該會縮短。因為審核速度更快(通常比應有的速度快) 2. 您的變更失敗率可能會上升。當然,如果評論低於標準,您可能會帶來更多錯誤。 ``` 1. But, even if your CFR isn’t going noticeably down, your team might still be shipping low performance or quality code that would bite you back later, and will likely show up as higher Lead Time down the line. But by then it’ll be too difficult to correlate with the reviews of today. ``` **現在是時候提一下《朵拉》是一位很棒的嚮導,但它並不完美。** 不要將其視為明確的規則手冊。不要用它來衡量個人。 為您的團隊全面使用它,但也要參與其中,以確保它真正幫助您的團隊。畢竟這就是目標,不是嗎? 偉大的!如何? 👉 更快、更有效的審核策略 --------------------- ### 這是一個快速**預審清單** 1. 測試:確保所有相關測試都已編寫並通過✅。 ``` 1. This can be done by a CI bot (or Github Actions) ``` 2. 文件:更新相關文件,包括內嵌註解和自述文件。 3. 清晰的提交訊息:編寫描述性提交訊息,解釋更改背後的「原因」。 ``` 2. This could also be enforced via [commit-lint](https://commitlint.js.org/) ``` ``` 3. You could also use [aicommit](https://github.com/Nutlope/aicommits) to help write good and detailed commit messages! ``` ``` 4. My team often uses GH Copilot to create commit messages that actually end up being totally satisfactory to me! ``` 提交訊息範例: ``` feat: add user authentication - Implemented OAuth2 for secure login - Added unit tests for authentication flows - Updated API documentation with new endpoints ``` ### 正確的審稿人,正確的時間 將審閱者與其專業知識和當前工作量相匹配,以避免超負荷。複雜的變更交給高階開發人員,簡單的變更交給同業。 但您還需要了解開發人員對特定程式碼庫有多少上下文。 這裡有一些挑戰: - 如果您的開發人員在單一特定儲存庫中高度專業化,那麼由於需要時間來加入和共享上下文,因此在單獨的程式碼庫上使用他們的技能將非常困難。 - 如果您的開發人員對所有程式碼庫過於籠統,那麼由於缺乏特定程式碼庫的深層上下文,他們可能很難更快地解決某些問題。 - 如果團隊中的一位開發人員對事物有很多背景知識,那麼很容易讓他們負擔過重。您需要儘早騰出時間來分發上下文,這樣您的工作就不會在最關鍵的時候受到阻礙。 您希望確保將兩者結合起來,並且只需與您合作的 2-3 名開發人員即可實現這一目標。 ![視覺化團隊中的瓶頸](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/va7uc3ajyb17kiamhq0h.png) *了解誰被阻止對誰進行程式碼審查至關重要。您不希望您的團隊因為有人需要休假而根本無法交付。* ### 貿易工具 使用靜態分析、程式碼檢查和自動檢查在人工審查之前捕獲簡單的問題。這讓審閱者可以專注於更複雜的回饋。 範例工具: - [ESLint](https://eslint.org/) :JavaScript linting。 - [Husky](https://typicode.github.io/husky/) :用於執行預提交檢查和靜態分析。 - CI/CD 管道:自動化測試和建置流程。 **超重要提示:** 爭論空格和製表符、分號與否、尾隨換行符很容易浪費大量時間。 但這一切並不重要。 決定並同意團隊最終確定的任何程式碼風格,並將它們作為 linter 規則的一部分強制執行。 這些東西不值得你花時間。 👍 ### 回饋的藝術 給予可操作的、具體的評論,重點是改進,而不是吹毛求疵。避免模糊的陳述並提供明確的指導。 分享如何將一個文件重組為多個文件,以及為什麼這樣做是個好主意。 分享為什麼在循環中多次呼叫資料庫可能是一個壞主意,因為我確信我不需要在這裡解釋。 😆 如果挑剔的問題主要是可以由 linter 處理的事情,那麼就使用其中之一。 人們討厭那些大多只有蝨子的評論。但同樣,糟糕的變數名稱、拼字錯誤等不能只是去生產! 😁 例子: ``` # Ineffective comment "Fix this." # Effective comment "Consider using a map here to improve lookup efficiency. This will reduce the time complexity from O(n) to O(1)." ``` 使用中介軟體簡化流程 ---------- ### 中介軟體如何提供協助 我能夠具體了解我的團隊在哪裡陷入困境、原因以及如何解除困境。 這就是我工作的一半,現在我能夠比以前更快地完成這些工作! ![團隊流程概述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yl0k380fegaussrrckyd.png) ### 我重點關注以下幾點: - 審核指標:追蹤審核所需的時間並確定發生延遲的位置。 - 流程洞察:了解整個審核流程並找到需要最佳化的領域。 我不會對此進行太多討論,因為那樣聽起來就像是推銷! 😂 超越技術細節:人的因素 ----------- ### 培養建設性回饋文化 倡導一種將回饋視為成長機會的文化。建設性的、相互尊重的溝通有助於提高程式碼品質和團隊士氣💬。 ### 平衡速度與徹底性 平衡速度與徹底性。快速審查不應影響審查,徹底審查不應拖延。 ### 心理安全 確保審稿人和作者的心理安全。鼓勵公開討論不加指責地解決錯誤,營造持續改進的環境🌱。 請記住,當您分享改進回饋時,人們常常會保持警惕。考慮周到,思路清晰。 結論 -- 有效的程式碼審查對於保持程式碼品質和交付速度至關重要。透過與 DORA 指標保持一致、使用正確的工具並培養建設性的回饋文化,團隊可以簡化其審核流程。採用這些實踐可以使您的程式碼審查既高效又具有影響力。 *嘗試使用[中間件](https://www.middlewarehq.com/)來更深入地了解您的程式碼審查流程並確定需要進一步改進的領域。 🚀* 同樣,這些只是指導方針以及我們如何看待程式碼審查。請分享您的組織中如何進行程式碼審查! 程式碼審查對於整體產品可靠性起著至關重要的作用。有些情況下,糟糕的程式碼審查(不是糟糕的程式碼!)會造成負面的品牌影響。總而言之,更好的程式碼審查流程有助於降低故障率。 像[DORA](https://github.com/middlewarehq/middleware)這樣的框架被設計為輕量級的,可以幫助工程團隊提高工作效率,而無需工程師甚至領導者付出太多的努力。 Middleware 的使命是幫助工程團隊交付高效率的程式碼。請查看我們的[開源中間件](https://github.com/middlewarehq/middleware),我們的開源 DORA 指標解決方案,它是本地託管的。如果您喜歡,請考慮給我們一顆星! --- 原文出處:https://dev.to/middleware/the-senior-engineers-guide-to-the-code-reviews-1p3b

Web 開發人員的頂級工具

**嘿,網頁開發者們!** 如果您是在廣闊的 Web 開發世界中揚帆起航的新手,擁有正確的工具可以決定您的旅程的成敗,有時很難選擇正確的工具。有太多可供選擇! 🤯 在本文中,我們將深入探討一些必備工具,這些工具不僅流行,而且能夠改變遊戲規則,提高您的工作效率,簡化複雜的任務,並使您的編碼生活變得更加輕鬆(也更有趣! ) 。 *PS 本文適合初學者,但歡迎更多經驗豐富的開發人員閱讀並加入他們的技巧。* --- ### 1. 程式碼編輯器和 IDE 程式碼編輯器是專門為編輯程式碼而設計的程式。它提供語法突出顯示、自動完成和除錯工具等功能,使編碼更有效率、更不易出錯。 **Visual Studio 程式碼(VS 程式碼)** VS Code 是一個輕量級但功能強大的原始程式碼編輯器,可以在桌面上執行。它支援 JavaScript、TypeScript、Node.js,並擁有豐富的其他語言擴充生態系統(包括 C++、C#、Python、PHP 等)。其內建的 Git 支援、強大的除錯和智慧程式碼完成 (IntelliSense) 使其成為開發人員的最愛。 **崇高的文字** Sublime Text 以其速度和效率而聞名,是一款多功能編輯器,可處理多個專案並在多個專案之間切換。其大量的鍵盤快捷鍵提高了工作效率,並允許開發人員更快地編寫和編輯程式碼。 **JetBrains WebStorm** WebStorm 專為 JavaScript 開發人員量身打造。它為 JavaScript、HTML 和 CSS 提供高級編碼幫助,包括自動完成、自動重構和強大的導航工具。 WebStorm 與流行的版本控制系統集成,並為建立 Web、伺服器和行動應用程式提供流暢的開發人員體驗。 --- ### 2.版本控制系統 版本控制系統是幫助軟體團隊管理原始碼隨時間變化的軟體工具。他們在一種特殊的資料庫中追蹤對程式碼的每次修改。如果發生錯誤,開發人員可以倒轉並比較早期版本的程式碼,以幫助修復錯誤,同時最大限度地減少對所有團隊成員的干擾。 **git** Git 是當今世界上使用最廣泛的現代版本控制系統。它允許多個開發人員在複雜的專案上一起工作,而不必擔心發生衝突的變更。 GitHub 和 GitLab 等平台也在 Git 功能之上提供了視覺化介面,讓管理專案變得更容易。 **水銀** 作為 Git 的替代方案,Mercurial 的設計考慮了簡單性和效能。它是一個分散式版本控制系統,允許開發人員有效管理大型程式碼庫。 --- **想要探索 Web 開發的未來嗎?** {% cta https://www.webcrumbs.org/waitlist %} 透過 Webcrumbs 了解更多 {% endcta %} --- ### 3. 前端框架 前端框架是允許開發人員建立使用者介面的標準結構。它提供了一種組織和建構程式碼的方法,並提供可重複使用的元件,從而使 Web 開發更快、更容易且更具可擴展性。使用框架可以大幅簡化開發過程,特別是對於需要快速建置的複雜專案。 **反應** React 是一個聲明式、高效且靈活的 JavaScript 程式庫,用於建立使用者介面。它允許開發人員從稱為“元件”的小型且獨立的程式碼片段組成複雜的 UI。 **視圖.js** Vue.js 因其簡單性而受到讚賞,並且對於初學者來說很容易上手。它的核心庫僅專注於視圖層,因此可以輕鬆選擇並與其他庫或現有專案整合。 **角** Angular 是一個使用 HTML 和 TypeScript 建立用戶端應用程式的平台和框架。它非常適合開發大型企業應用程式,並支援廣泛的功能,例如雙向資料綁定、模組化、模板化、AJAX 處理、依賴項注入等。 --- ### 4. CSS 框架與預處理器 CSS 框架是預先準備好的軟體框架,旨在允許使用級聯樣式表語言更輕鬆、更符合標準的網頁樣式。另一方面,預處理器為 CSS 加入了額外的功能,以保持樣式表組織良好,並允許我們更快地編寫程式碼。 **引導程式** Bootstrap 是世界上最受歡迎的框架,用於建立響應式、行動優先的網站。它包括用於排版、表單、按鈕、導航和其他介面元件的基於 HTML 和 CSS 的設計模板,以及可選的 JavaScript 擴充功能。 **順風 CSS** Tailwind CSS 是一個實用程式優先的 CSS 框架,用於快速建立自訂設計。與其他 CSS 框架不同,Tailwind 不附帶預定義元件,而是提供實用程式類別來直接在標籤中建立獨特的設計。 **薩斯** Sass 是一種成熟、穩定、強大的專業級 CSS 擴展語言。它有助於讓 CSS 再次變得有趣,並包含變數、巢狀和混合等功能,允許更靈活和可重複使用的程式碼。 --- ### 5. 建置工具和任務執行器 建置工具和任務執行程式是在軟體開發過程中自動執行重複任務的軟體,例如縮小程式碼、將原始程式碼編譯為二進位程式碼、打包二進位程式碼以及執行自動化測試。這種自動化使開發過程更加一致,並為開發人員節省了大量時間。 **網頁包** Webpack 是現代 JavaScript 應用程式的靜態模組捆綁器。當 Webpack 處理您的應用程式時,它會在內部建立一個依賴關係圖,該圖會對應您的專案所需的每個模組並產生一個或多個捆綁包。 **咕嚕咕嚕** Gulp 是一個工具包,可協助開發人員自動執行開發工作流程中痛苦或耗時的任務。它用於常見任務的任務自動化,例如 CSS 縮小、圖像優化、程式碼檢查和建立網頁。 ### 您使用哪些工具? 我們希望本指南可以幫助您選擇合適的工具來增強您的 Web 開發專案。嘗試將其中一些工具整合到您的工作流程中,並親自看看有何不同。 與我們分享您的經驗或推薦其他值得一提的工具! 在 WebCrumbs,我們正在發展一個供開發人員相處和共同學習的社群! {% cta [https://discord.gg/4PWXpPd8HQ](https://discord.gg/4PWXpPd8HQ "https://discord.gg/4PWXpPd8HQ") %} 在這裡加入我們{% endcta %} --- 原文出處:https://dev.to/buildwebcrumbs/top-tools-for-modern-web-developers-1ba3

17 個讓我保持高效率的開發者工具

許多開發人員喜歡從頭開始建立東西,但有時工作量太大,使用這些工具可以讓工作變得更容易。 這裡包含一系列工具,因此我相信您會找到適合您需求的工具。 我無法涵蓋所有內容,但如果您知道其他很棒的工具,請隨時在評論中告訴我! 我們開始做吧。 --- 1. [Taipy](https://github.com/Avaiga/taipy) - 資料和人工智慧演算法融入生產級網路應用程式。 -------------------------------------------------------------------- ![打字](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wd10iiofzmt4or4db6ej.png) 通常,當我需要 Python 介面時,我會使用 Streamlit。然而,它的效率不是很高,並且存在許多基於效能的問題。 另一方面,Taipy(開源)是用於輕鬆、端到端應用程式開發的完美 Python 程式庫,具有假設分析、智慧管道執行、內建調度和部署工具。 需要明確的是,Taipy 用於為基於 Python 的應用程式建立 GUI 介面並改進資料流管理。 關鍵是性能,而 Taipy 是最佳選擇。 雖然 Streamlit 是一種流行的工具,但正如我之前告訴您的那樣,它的性能可能會顯著下降,尤其是在處理大型資料集時,這使得它對於生產級使用來說不切實際。 另一方面,Taipy 在不犧牲性能的情況下提供了簡單性和易用性。 ![大資料支持](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnvk0tozn0lgj083rzcb.gif) Taipy 有許多整合選項,可以輕鬆地與領先的資料平台連接。 ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7yv31uir3erina587zp8.png) 開始使用以下命令。 ``` pip install taipy ``` 最好的部分是 Taipy,它的所有依賴項現在都與 Python 3.12 完全相容,因此您可以在使用 Taipy 進行專案的同時使用最新的工具和程式庫。 您可以閱讀[文件](https://docs.taipy.io/en/latest/)。 ![用例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdvnbejf9aivxmqsd3hx.png) 另一個有用的事情是,Taipy 團隊提供了一個名為[Taipy Studio](https://docs.taipy.io/en/latest/manuals/studio/)的 VSCode 擴充功能來加速 Taipy 應用程式的建置。 ![太皮工作室](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kc1umm5hcxes0ydbuspb.png) 如果您想閱讀部落格來了解程式碼庫結構,您可以閱讀 HuggingFace[的使用 Taipy 在 Python 中為您的 LLM 建立 Web 介面](https://huggingface.co/blog/Alex1337/create-a-web-interface-for-your-llm-in-python)。 嘗試新技術通常很困難,但 Taipy 提供了[10 多個演示教程,](https://docs.taipy.io/en/release-3.1/gallery/)其中包含程式碼和適當的文件供您遵循。我將詳細討論其中一些專案! ![示範](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wigid2aokt6spkkoivr.png) 這些用例令人驚嘆,因此請務必查看一些演示應用程式。 Taipy 還在其企業版中提供了 Designer 應用程式(拖放低程式碼編輯器)。它非常有用,您可以觀看下面的演示來了解它是如何工作的! {% 嵌入 https://www.youtube.com/watch?v=y3VPT6IPvC4 %} Taipy 在 GitHub 上有 9.2k+ 顆星,並且處於`v3.1`版本,因此它們正在不斷改進。 {% cta https://github.com/Avaiga/taipy %} 明星 Taipy ⭐️ {% endcta %} --- 2. [Jam](https://jam.dev/) - 一鍵錯誤報告。 ------------------------------------ ![果醬](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tn2c6djsj5hej0gj07xs.png) 幾個月前我發現了 Jam,並且用過它好幾次。 Jam 是一款免費的 Chrome 擴充功能(非開源),您可以使用它來有效地報告錯誤。當然,您還可以做更多的事情。 報告錯誤是一個漫長的過程,您最終可能會錯過解決該錯誤所需的基本資料。這就是開發人員更喜歡使用 Jam 的原因。 觀看此影片,了解 Jam 的工作原理! {% 嵌入 https://www.youtube.com/watch?v=iXjmUwZLzVs&amp;embeds\_referring\_euri=https%3A%2F%2Fchromewebstore.google.com%2F&amp;source\_ve\_path=OTY3MTQ&amp;feature=emb\_imp\_woyt %} 正如您所看到的,最好的部分是它捕獲控制台和網頁日誌訊息,這使得其他開發人員可以方便地查看它。 您還將獲得人工智慧除錯器、後端追蹤、重現步驟和瀏覽器資訊。您還需要什麼? ![即興開發](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2tpffk9h60skslw8i0b.png) 我已經使用 Jam 很長時間了,因此您還將獲得一個儀表板來查看您迄今為止建立的所有 Jam。它非常高效並且效果非常好。 ![儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t01buvno1r7pfrolfu6k.png) 它還可以與許多流行的工具一起使用,因此您根本不必改變您的環境。 ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gr566uwdcmors2yvkfcb.png) 不要使用傳統的方式,您可以簡單地對 Jam 進行評論並改進整個流程來輕鬆處理它。 --- 3. [DevGPT](https://www.getdevkit.com/devgpt) - 開發者的人工智慧助理。 ----------------------------------------------------------- ![開發組](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8k8a8jyeo9qkj2hqmc4n.png) 我已經使用 DevGPT 很久了,尤其是當 ChatGPT 還很新的時候。我曾經反覆核對訊息,看看它是否正確。我不相信 ChatGPT 和用於它的訓練資料。 您會驚訝地發現,在某些情況下 DevGPT 比 ChatGPT 更好。但這並不是 DevGPT 的唯一用例。 他們提供了一系列可以直接使用的提示。您可以修改它們的結構並使用斜線命令來使用它。 ![提示結構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fc74vge21d65nbpauig.png) ![提示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yhl7o1grjvcg9q1fee5.png) 範例提示 ![提示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0y51yi3t4s0a54tw0jrs.png) 範例提示 DevGPT 與其他人工智慧助理的獨特之處在於它提供了許多有用的迷你工具。 ![迷你工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il3qcaykt4k9x612251n.png) 我使用最多的是響應式設計,它有助於同時在所有螢幕上查看任何網站預覽。 ![響應式設計](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nodp7fbhagwqavd5ud5h.png) 響應式設計 每個工具本身都是完整的,因此您不會得到任何不完整的東西。我相信這實際上可以改善您的工作流程條件。 ![日期檢查員](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1q5bau21dd8dqaqbu4c.png) 日期檢查員 --- 4. [DevToys](https://github.com/DevToys-app/DevToys) - 開發者的瑞士軍刀。 ---------------------------------------------------------------- ![開發玩具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7zfl1wjr01fdvca6wxbi.png) DevToys 協助完成日常開發任務,例如格式化 JSON、比較文字和測試 RegExp。 用例是相同的,但 DevToys 提供了更多選項,而且它是一個離線工具,這是一個優點。 這樣,就無需使用不可信的網站來處理您的資料執行簡單的任務。透過智慧型偵測,DevToys 可以偵測用於複製到 Windows 剪貼簿的資料的最佳工具。 緊湊的覆蓋範圍讓您可以保持應用程式較小並位於其他視窗之上。最好的部分是可以同時使用該應用程式的多個實例。 我可以肯定地說,很多開發人員從來不知道這件事。 我很高興地說它是專為 Windows 生態系統設計的軟體。哈哈! ![工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7wd60jsgdb5tx2t2adi.png) 他們提供的一些工具是: > 轉換器 - JSON &lt;&gt; YAML - 時間戳 - 數基數 - 規劃任務解析器 ![轉換器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g8x784fx53x6ia02zal0.png) > 編碼器/解碼器 - 超文本標記語言 - 網址 - Base64 文字與圖片 - 壓縮包 - 智威湯遜解碼器 ![編碼器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73ts4x1vtcy4yswsmytw.png) > 格式化程式 - JSON - SQL - XML ![XML](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5dc8ko2baywta82ymq5.png) > 發電機 - 哈希(MD5、SHA1、SHA256、SHA512) - UUID 1 和 4 - 洛雷姆·伊普蘇姆 - 校驗和 ![發電機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwsq8xig6jf69wr99iuv.png) > 文字 - 逃脫/逃脫 - 檢驗員和箱子轉換器 - 正規表示式測試器 - 文字比較 - XML驗證器 - 降價預覽 ![MD預覽](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vcbkse1i5324qg3xu1yd.png) ![文字差異](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hlqqib4fcjimc03pdrwr.png) > 形象的 - 色盲模擬器 - 顏色選擇器和對比度 - PNG / JPEG 壓縮器 - 影像轉換器 ![圖形工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/631upekcqzh62xyrdjwt.png) 我不了解你,但我不會錯過這個! 您可以閱讀[如何執行 DevToys](https://github.com/DevToys-app/DevToys?tab=readme-ov-file#how-to-run-devtoys) 。 > 關於許可證的註解。 DevToys 使用的授權允許將應用程式作為試用軟體或共享軟體重新分發而無需進行任何更改。然而,作者 Etienne BAUDOUX 和 BenjaminT 不希望你這樣做。如果您認為自己有充分的理由這樣做,請先與我們聯絡討論。 他們在 GitHub 上擁有超過 23,500 顆星,並使用 C#。 {% cta https://github.com/DevToys-app/DevToys %} 明星 DevToys ⭐️ {% endcta %} --- 5. [Linear-](https://github.com/linear)任務管理工具。 ---------------------------------------------- ![線性](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zlvr12b9untwos846i2.png) 我之前嘗試過使用 Trello 或 Jira 等工具,我想說線性絕對值得。 Jira 似乎有點複雜,適合大型團隊。 Linear 是開源的,是簡化問題、專案和產品路線圖的最佳方法之一。它是一種管理工具,我們都需要它來了解正在發生的事情以及未來的計劃。 ![工作管理](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gbno2672e69ofqonsob3.png) 您還可以獲得一個全域命令選單,可以幫助您更快地完成操作。作為開發人員,我們都喜歡這一點! 它們提供了一系列很酷的功能,例如自動跟踪,這可確保將啟動的問題加入到當前週期中。您還將收到有關有風險週期的警告,這可以幫助預測延誤。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o3bi4fgk4vp0nfc75jlc.png) ![線性](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pfl0onb6rmiepiu1ibns.png) ![循環](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eb7tpqvlbxyhkwzkroyj.png) 您可以看到[25+ 個完整功能](https://linear.app/features)的清單。您還可以了解[他們的整個旅程](https://linear.app/readme)。 如果您喜歡觀看影片,可以觀看此影片,其中涵蓋了有關線性的大部分基本內容。 {% 嵌入 https://youtu.be/oh2AfSFe0H0 %} 它有一個針對 2 個團隊的免費套餐計劃,這足以讓您嘗試一下並看看它們是否合適。 Linear 在主儲存庫上有 650 顆星,是使用 TypeScript 建構的。 {% cta https://github.com/linear %} 星線性 ⭐️ {% endcta %} --- 6. [Pieces](https://github.com/pieces-app) - 您的工作流程副駕駛。 ------------------------------------------------------- ![件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qf2qgqtpv78fxw5guqm5.png) Pieces 是一款 AI 生產力工具,旨在透過智慧程式碼片段管理、情境化副駕駛互動和主動呈現有用材料來幫助開發人員管理混亂的工作流程。 它改善了您的工作流程和整體開發體驗,同時透過完全離線的 AI 方法保持工作的隱私和安全。 實時上下文的最新概念使其更上一層樓。您可以觀看引起熱議的演示! {% 嵌入 https://www.youtube.com/watch?v=aP8u95RTCGE %} 有了這個,Pieces Copilot+ 現在可以提供高度感知的幫助,引導您回到上次離開的地方。 - 問它, `What was I working on an hour ago?`並讓它幫助你重新進入心流狀態。 - 問一下, `How can I resolve the issue I got with Cocoa Pods in the terminal in IntelliJ?` - 或者`What did Mack say I should test in the latest release?` 。 Copilot 可以顯示您知道自己擁有但不記得在哪裡的資訊。 ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2ro3rcwnqp4qrmv5e8s.png) 它與您最喜歡的工具無縫集成,以簡化、理解和提升您的編碼流程。 它具有比表面上看到的更令人興奮的功能。 ✅ 它可以透過閃電般的搜尋體驗找到您需要的資料,讓您可以根據您的喜好透過自然語言、程式碼、標籤和其他語義進行查詢。可以放心地說“您的個人離線谷歌”。 ✅ Pieces 使用 OCR 和 Edge-ML 升級螢幕截圖,以提取程式碼並修復無效字元。因此,您可以獲得極其準確的程式碼提取和深度元資料豐富。 您可以查看 Pieces 可用[功能的完整清單](https://pieces.app/features/?utm_source=anmol&utm_medium=cpc&utm_campaign=anmol-article)。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysluzx8qtyaqrtnp4fld.png) ![分享程式碼片段](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wz4xtesz5empxatxju1l.png) 您可以閱讀[文件](https://docs.pieces.app/?utm_source=anmol&utm_medium=cpc&utm_campaign=anmol-article)並存取[網站](https://pieces.app/)。 它還允許您捕獲程式碼片段,您可以在編輯現有程式碼或處理新專案時將其用作參考。這對於開源開發人員來說非常方便。 ✅ 在應用程式中保存部分程式碼。 ✅ 輕鬆存取已儲存的程式碼片段。 ✅ 從網路貼上程式碼。 ✅ 與您的團隊分享您的程式碼。 他們為 Pieces OS 用戶端提供了一系列 SDK 選項,包括[TypeScript](https://github.com/pieces-app/pieces-os-client-sdk-for-typescript) 、 [Kotlin](https://github.com/pieces-app/pieces-os-client-sdk-for-kotlin) 、 [Python](https://github.com/pieces-app/pieces-os-client-sdk-for-python)和[Dart](https://github.com/pieces-app/pieces-os-client-sdk-for-dart) 。 就開源流行度而言,他們仍然是新的,但他們的社群是迄今為止我見過的最好的社群之一。加入他們,成為 Pieces 的一部分! {% cta https://github.com/pieces-app/ %} 星星碎片 ⭐️ {% endcta %} --- 7.[螢幕截圖到程式碼](https://github.com/abi/screenshot-to-code)- 放入螢幕截圖並將其轉換為乾淨的程式碼。 --------------------------------------------------------------------------- ![截圖到程式碼](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5akiyz5telxqqsj32ftu.png) 這個開源專案廣泛流行,但許多開發人員仍然不了解它。這可以幫助您以 10 倍的速度建立使用者介面。 這是一個簡單的工具,可以使用 AI 將螢幕截圖、模型和 Figma 設計轉換為乾淨、實用的程式碼。 該應用程式有一個 React/Vite 前端和一個 FastAPI 後端。如果您想使用 Claude Sonnet 或獲得實驗視訊支持,您將需要一個能夠存取 GPT-4 Vision API 的 OpenAI API 金鑰或一個 Anthropic 金鑰。您可以閱讀[指南](https://github.com/abi/screenshot-to-code?tab=readme-ov-file#-getting-started)來開始。 您可以在託管版本上[即時試用](https://screenshottocode.com/),並觀看 wiki 上提供的[一系列演示影片](https://github.com/abi/screenshot-to-code/wiki/Screen-Recording-to-Code)。 他們在 GitHub 上擁有超過 52k 顆星,並支援許多技術堆疊,例如 React 和 Vue,以及不錯的 AI 模型,例如 GPT-4 Vision、Claude 3 Sonnet 和 DALL-E 3。 {% cta https://github.com/abi/screenshot-to-code %} 將螢幕截圖轉為程式碼 ⭐️ {% endcta %} --- 8. [Silver Searcher](https://github.com/ggreer/the_silver_searcher) - 超快速的程式碼庫搜尋工具。 ----------------------------------------------------------------------------------- ![銀色搜尋者](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/41z8goks4ag2opm0ynvp.png) 許多開源專案都有開發人員多年來建立的大型程式碼庫。顯然,有人無法一次理解所有內容,這就是這個工具的用武之地。 Silver Searcher(開源),通常縮寫為 Ag,是一種快速且有效率的程式碼搜尋工具,專為使用大型程式碼庫的開發人員而設計。 Ag 是作為傳統 grep 命令的替代品而建置的,它利用平行性和智慧過濾來提供超快速的搜尋結果。 它最初是[Ack](https://github.com/beyondgrep/ack3)的克隆,但速度快了 5 到 10 倍。您可以閱讀[為什麼它這麼快](https://github.com/ggreer/the_silver_searcher?tab=readme-ov-file#how-is-it-so-fast)。 它有很多很酷的功能,例如: ✅ 多執行緒可加快程式碼錯誤搜尋速度。 ✅ 忽略 .gitignore、.ignore 和 .hgignore 中的檔案模式以避免不必要的搜尋。 ✅ 可透過命令列選項和可下載的設定檔進行自訂。 好處是它可以與文字編輯器和 IDE 集成,以在您首選的工作流程中增強搜尋功能。 它可以根據您的開發環境在 Windows、macOS 和 Linux 上無縫執行。 您可以閱讀[安裝指南](https://github.com/ggreer/the_silver_searcher?tab=readme-ov-file#installing)。 它在 GitHub 上擁有超過 25,500 顆星,擁有 200 多名貢獻者。 唯一的問題是它不再被維護,因為最後一次提交是 4 年前的事情,並且有 400 多個活躍問題。 {% cta https://github.com/ggreer/the\_silver\_searcher %} 星銀搜尋者 ⭐️ {% endcta %} --- 9. [Obsidian](https://github.com/obsidianmd) - 根據您的風格編寫應用程式。 ------------------------------------------------------------ ![黑曜石](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/26r33zlctwpny1f7hf96.png) Obsidian 是一款私密且靈活的寫作應用程式,可適應您的思維方式。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mz0eig3tzezhm32i314m.png) ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z983u116nummmo8n16b7.png) 您也可以查看插件清單\](https://obsidian.md/plugins),它們可以幫助您塑造 Obsidian 以適應您的思維方式。我已經檢查了那裡存在的瘋狂數量的選項! ![外掛](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/voyny8k3zbh6a92u3qy4.png) 您甚至可以協作並輕鬆追蹤修訂之間的更改,每個註釋都有一年的版本歷史記錄。 ![版本歷史](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqj3sxbwh1y5t9rbwb4l.png) 您可以發布這些(我從未嘗試過)並透過主題、自訂網域、密碼保護等控制網站的外觀和風格。這是一項付費功能,但您可以閱讀有關[使用 Obsidian 發布的](https://obsidian.md/publish)所有內容。 您可以閱讀詳細[文件](https://docs.obsidian.md/Home)並查看[即時網站](https://obsidian.md/)。您也可以使用本[指南](https://docs.obsidian.md/Plugins/Getting+started/Build+a+plugin)建立自訂插件,並使用 React 或 Svelte。 根據您使用的平台下載[Obsidian](https://obsidian.md/download) 。 他們提供永久免費的套餐,並且不根據功能或使用情況收費。只有當您將 Obsidian 用於商業用途時才需要付費。 您可以嘗試的最佳替代方案之一是[Capacities](https://capacities.io/) 。在某些方面它甚至可能比黑曜石更好。我將在以後的一篇文章中介紹它。 主儲存庫在 GitHub 上有 8k+ 顆星,有 1400 多名貢獻者。開源社群的另一個很棒的專案。 {% cta https://github.com/obsidianmd/obsidian-releases %} 星黑曜石 ⭐️ {% endcta %} --- 10.[自動完成](https://github.com/withfig/autocomplete)- IDE 風格的自動完成功能適用於您現有的終端和 shell。 ---------------------------------------------------------------------------------- ![自動完成](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8i8vcidsa023jf8r9382.png) [Fig](https://fig.io/?ref=github_autocomplete)讓命令列對個人來說更容易,對團隊來說更具協作性。 他們最受歡迎的產品是自動完成。當您鍵入時,Fig 會在現有終端機中彈出子命令、選項和上下文相關的參數。 作為開發人員,我們確實需要它來最大限度地提高我們的日常生產力。 最好的部分是您也可以將 Fig 的自動完成功能用於您自己的工具。以下是建立私人完成的方法: ``` import { ai } from "@fig/autocomplete-generators" ... generators: [ ai({ // the prompt prompt: "Generate a git commit message", // Send any relevant local context. message: async ({ executeShellCommand }) => { return executeShellCommand("git diff") }, //Turn each newline into a suggestion (can specify instead a `postProcess1 function if more flexibility is required) splitOn: "\n", }) ] ``` 您可以閱讀[Fig.io/docs](https://fig.io/docs/getting-started)了解如何開始。 您可以觀看下面的演示來了解它是如何工作的! ![影像](https://camo.githubusercontent.com/c477525cab041ce8177323e8140aa872341e3b8130d61454b89ccae87d00d87b/68747470733a2f2f646f63732e6177732e616d617a6f6e2e636f6d2f696d616765732f616d617a6f6e712f6c61746573742f71646576656c6f7065722d75672f696d616765732f636f6d6d616e642d6c696e652d636f6d706c6574696f6e732e676966) 它們在 GitHub 上有 24k+ 顆星,對於經常使用 shell 或終端機的開發人員很有用。 {% cta https://github.com/withfig/autocomplete %} 星狀自動完成 ⭐️ {% endcta %} --- 11. [Excalidraw](https://github.com/excalidraw/excalidraw) - 線上白板,讓您的想法得以實現。 ---------------------------------------------------------------------------- ![外畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u691s86xjinjvehmun51.png) 向遠距工作的過渡讓我懷念使用記號筆和白板進行腦力激盪的簡單性。 我們知道,當語言無法表達時,視覺效果可以彌補理解複雜想法的差距。 Excalidraw(開源)以數位方式重新建立白板體驗,對於補充無聊文字的快速圖表或插圖來說具有無價的價值。您可以建立漂亮的手繪圖表、線框圖或任何您喜歡的內容。 ![外畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ki8wave2sgy3mikv4nec.png) 作為開發人員,對我來說最好的部分是您可以安裝 Excalidraw npm 套件以將 Excalidraw 整合到我自己的應用程式中。哇! ``` npm install react react-dom @excalidraw/excalidraw ``` 一些很棒的功能是: ✅ 本地化 (i18n) 支援。 ✅ 匯出到 PNG、SVG 和剪貼簿。 ✅ 多種工具 - 長方形、圓形、菱形、箭頭、線條、自由繪製、橡皮擦... ✅ 撤銷/重做。 ✅ PWA 支援(離線工作)。 ✅ 即時協作。 ✅ 本機優先支援(自動儲存至瀏覽器)。 ✅ 可分享連結(匯出至可與他人分享的唯讀連結)。 ![exalidraw 具有大螢幕功能](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru356oc83ll9mo4dhjd5.png) Google Cloud、Meta、CodeSandbox、Notion 和 Replit 等產品整合了 Excalidraw,賦予其巨大的可信度。 您可以閱讀[文件](https://docs.excalidraw.com/docs/introduction/development)並檢查[excalidraw 編輯器](https://excalidraw.com/)。 他們甚至有一套迷你的人工智慧功能,並支援從美人魚轉換,這非常有幫助。 ![人工智慧特點](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ihl90jf222ahtymec8ui.png) 團隊提供了一個[即時編輯器](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/customizing-styles),如果您不想在本地執行,您可以直接檢查任何類型的變更。讓我著迷的是,有些團隊工作非常努力,因此開發人員的體驗是一流的。 ![即時編輯器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob848loog24milg0h2uv.png) 儘管它是免費使用的,但他們提供了增強版本,因此您可以檢查[付費計劃和免費計劃之間的差異](https://plus.excalidraw.com/excalidraw-plus-vs-excalidraw/)。 說實話,我從來沒有真正想過這會是開源的。但它非常受歡迎,GitHub 上有超過 74,000 顆星,有 1,300 多個活躍問題。 {% cta https://github.com/excalidraw/excalidraw %} 明星 Excalidraw ⭐️ {% endcta %} --- 12. [Mintlify](https://github.com/mintlify/writer) - 在建置時出現的文件。 --------------------------------------------------------------- ![精簡](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvk07kmn8p48cpssogov.png) 我們都知道在程式碼中建立文件非常重要,這樣我們就可以了解稍後發生的情況。但這是一個漫長的過程,而且大多數時候我們都懶得這麼做。 這就是 Mintlify 作為人工智慧文件編寫者可以幫助您在短短 1 秒內記錄程式碼的地方。哇! 幾個月前我發現了 Mintlify,從那時起我就一直是它的粉絲。 正如我們在該公司的大多數網站上看到的那樣,他們還為任何專案提供完整的文件。我見過很多公司使用它,甚至我使用我的商務電子郵件產生了完整的文件,結果證明這是非常簡單和體面的。如果您想要這些文件,Mintlify 就是解決方案。 ![副駕駛套件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7obg1a3hilqx47h6nw3o.png) copilotkit 文件也由 Mintlify 提供支持 我們在這裡要討論的主要用例是根據程式碼產生文件。當您編寫程式碼時,它會自動記錄程式碼,以便其他人更容易跟上。 您可以安裝[VSCode 擴充功能](https://marketplace.visualstudio.com/items?itemName=mintlify.document)或將其安裝在[IntelliJ](https://plugins.jetbrains.com/plugin/18606-mintlify-doc-writer)上。 您只需突出顯示程式碼或將遊標放在要記錄的行上。然後點選「編寫文件」按鈕(或按 ⌘ + 。) 您可以閱讀[文件](https://github.com/mintlify/writer?tab=readme-ov-file#%EF%B8%8F-mintlify-writer)和[安全指南](https://writer.mintlify.com/security)。 如果您更喜歡教程,那麼您可以觀看[Mintlify 的工作原理](https://www.loom.com/embed/3dbfcd7e0e1b47519d957746e05bf0f4)。它支援 10 多種程式語言,並支援許多文件字串格式,例如 JSDoc、reST、NumPy 等。 順便說一句,他們的網站連結是[writer.mintlify.com](https://writer.mintlify.com/) ;回購協議中目前的似乎是錯誤的。 Mintlify 是一個方便的工具,用於記錄程式碼,這是每個開發人員都應該做的事情。它使其他人更容易有效地理解您的程式碼。 它在 GitHub 上有大約 2.5k 顆星,基於 TypeScript 建置,受到許多開發人員的喜愛。 {% cta https://github.com/mintlify/writer %} Star Mintlify ⭐️ {% endcta %} --- 13. [Focusmate](https://www.focusmate.com/) - 虛擬協同辦公,可以完成任何事情。 -------------------------------------------------------------- ![焦點伴侶](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bwxmwxio6jq7bw2mw10j.png) 儘管我們盡量不拖延,但在編碼期間我們總是擔心拖延。對於這些情況,Focusmate 是完美的解決方案! 這是一個共同工作的虛擬社區,您會在其中分配一位合作夥伴,確保您專注於自己的任務。 您需要與其他 Focusmate 用戶預訂會議。確定何時預訂課程後,您可以存取 Focusmate 儀表板。在那裡,您將看到一個日曆,其中包含其他使用者的可用會話時間。 ![怎麼運作的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bqjf66nrzrdjyccc6gl.png) 要與其他人預訂會議,您只需點擊日曆中的個人資料圖片,然後選擇與他們預訂會議。 ![儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/21pudw9jdj90uup92k4j.png) 一旦您這樣做,Focusmate 就會推薦幾個可用使用者供您選擇。 重點是它允許[安靜模式](https://support.focusmate.com/en/articles/8060080-session-settings-my-task-quiet-mode-and-partner),在這種模式下,人們沒有麥克風或無法說話(想想圖書館和共享空間)。 ![靜音模式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vav48ckhnn2dhikx19ju.png) 就我個人而言,我沒有嘗試過很多次,但它有一個很大的社區,所以值得一試。 --- 14. [Spark Mail](https://sparkmailapp.com/) - 優化您的電子郵件管理。 --------------------------------------------------------- ![火花郵件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/824r33nf4lc8p28fkoyp.png) Spark(非開源)不僅僅是一個電子郵件用戶端。這是關於人們應該如何溝通和組織工作的哲學。 Spark 的目標是幫助您專注於重要的事情並實現收件匣之外的目標。 他們首先使電子郵件變得智能,然後改進了團隊協作,現在他們已經解決了資訊過載問題,使電子郵件變得聚焦。 觀看快速演示,了解 Spark 的工作原理! {% 嵌入 https://www.youtube.com/watch?v=l2QpqNw3zXU&amp;t=3s %} 我喜歡 Spark 的一些很酷的功能: ✅ 您可以設定電子郵件稍後返回收件匣的時間。 ✅ 您可以新增提醒來提示您跟進。 ✅ 您可以安排電子郵件的發送時間。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czr3jmfmkhmqj7yd264k.png) ✅ 您也可以與您的團隊合作: - 在同一地址下管理電子郵件和團隊角色。 - 即時一起撰寫電子郵件草稿。 - 將任務分配給同事並追蹤他們的狀態。 ✅ 您甚至可以將電子郵件變成帶有私人評論的聊天。 ![合作](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v7p0vdhd7vh5s72qjgub.png) 我知道你想知道人工智慧,所以它有很多功能,你可以讓人工智慧為你起草電子郵件或獲得一堆回覆選項。 ![你有回覆](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vyux9mn1wc0h5bde3w9l.png) 更好的是,您可以校對、調整語氣、改寫、擴展或縮短文本,等等。 ![已編輯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yxs7vejau2h96ell5dr.png) 但我最喜歡的是建立電子郵件簽名的選項,因為簡單的選項並不那麼有效。 ![電子郵件簽名](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rhq44742us4lity50jig.png) 您可以查看[定價計劃](https://sparkmailapp.com/plans-comparison),其中包括足夠好的免費套餐,然後下載[Spark for Windows](https://sparkmailapp.com/windows) 。也請查看他們的[部落格](https://sparkmailapp.com/blog)和[電子郵件指南](https://sparkmailapp.com/how-to)以了解更多資訊。 儘管我喜歡人工智慧,但我不喜歡人工智慧為我建立電子郵件草稿。我比較喜歡自己做,哈哈! 不管怎樣,Spark 絕對是一種有趣的電子郵件管理方式。嘗試一下並讓我知道效果如何。 如果您正在尋找替代方案,我推薦[Inbox Zero](https://github.com/elie222/inbox-zero) ,它是開源的,我已經在我的一篇文章中介紹過,以及 SaneBox (https://www.sanebox.com/),我沒有介紹它因為它沒有免費套餐。 --- 15. [n8n](https://github.com/n8n-io/n8n) - 工作流程自動化工具。 ----------------------------------------------------- ![n8n](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4pqsc84nhgj0b9dhfaxo.png) n8n 是一個可擴展的工作流程自動化工具。透過公平程式碼分發模型,n8n 將始終擁有可見的原始程式碼,可用於自託管,並允許您加入自訂函數、邏輯和應用程式。 每個開發人員都想使用的工具。畢竟,自動化是生產力和簡單性的關鍵。 ![n8n](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rxnp57kw5szbpj6mfs1p.png) n8n 基於節點的方法使其具有高度通用性,使您能夠將任何事物連接到任何事物。 有[400 多個集成選項](https://n8n.io/integrations),這幾乎是瘋狂的! 您可以看到所有[安裝](https://docs.n8n.io/choose-n8n/)選項,包括 Docker、npm 和自架。 開始使用以下命令。 ``` npx n8n ``` 此命令將下載啟動 n8n 所需的所有內容。然後,您可以透過開啟`http://localhost:5678`來存取 n8n 並開始建置工作流程。 在 YouTube 上觀看此[快速入門影片](https://www.youtube.com/watch?v=1MwSoB0gnM4)! {% 嵌入 https://www.youtube.com/watch?v=1MwSoB0gnM4 %} 您可以閱讀[文件](https://docs.n8n.io/)並閱讀本[指南](https://docs.n8n.io/try-it-out/),根據您的需求快速開始。 他們還提供初學者和中級[課程,](https://docs.n8n.io/courses/)以便輕鬆學習。 他們在 GitHub 上有 41k+ 顆星,並提供兩個包供整體使用。 {% cta https://github.com/n8n-io/n8n %} 明星 n8n ⭐️ {% endcta %} --- 16. [Infisical](https://github.com/Infisical/infisical) - 秘密管理平台。 ----------------------------------------------------------------- ![內部的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrolzjdnkky1r694h9av.png) Infisical 是一個開源秘密管理平台,團隊可以用它來集中 API 金鑰、資料庫憑證和設定等秘密。 他們讓每個人(而不僅僅是安全團隊)都可以更輕鬆地進行秘密管理,這意味著從頭開始重新設計整個開發人員體驗。 就我個人而言,我不介意使用 .env 文件,因為我並不特別謹慎。不過,您可以閱讀[立即停止使用 .env 檔案!](https://dev.to/gregorygaines/stop-using-env-files-now-kp0)由格雷戈里來理解。 他們提供了四種 SDK,分別用於<a href="">Node.js</a> 、 <a href="">Python</a> 、 <a href="">Java</a>和<a href="">.Net</a> 。您可以自行託管或使用他們的雲端。 開始使用以下 npm 指令。 ``` npm install @infisical/sdk ``` 這是使用入門 (Node.js SDK) 的方法。 ``` import { InfisicalClient, LogLevel } from "@infisical/sdk"; const client = new InfisicalClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", logLevel: LogLevel.Error }); const secrets = await client.listSecrets({ environment: "dev", projectId: "PROJECT_ID", path: "/foo/bar/", includeImports: false }); ``` ![內部](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h3eu288l470du91b66pd.png) Infisical 還提供了一組工具來自動防止 git 歷史記錄的秘密洩露。可以使用預提交掛鉤或透過與 GitHub 等平台直接整合在 Infisical CLI 層級上設定此功能。 您可以閱讀[文件](https://infisical.com/docs/documentation/getting-started/introduction)並檢查如何[安裝 CLI](https://infisical.com/docs/cli/overview) ,這是使用它的最佳方式。 Infisical 還可用於將機密注入 Kubernetes 叢集和自動部署,以便應用程式使用最新的機密。有很多整合選項可用。 ![內部](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5x0tvt5ycaiqhggv6wml.png) 在使用整個原始程式碼之前一定要檢查他們的[許可證](https://github.com/Infisical/infisical/blob/main/LICENSE),因為他們有一些受 MIT Expat 保護的企業級程式碼,但不用擔心,大部分程式碼都是免費使用的。 他們在 GitHub 上擁有超過 11k 顆星,並發布了超過 125 個版本,因此他們正在不斷發展。另外,Infiscial CLI 的安裝次數超過 540 萬次,因此非常值得信賴。 {% cta https://github.com/Infisical/infisical %} 明星 Infisical ⭐️ {% endcta %} --- 17. [Gitinfluence](https://github.com/geovanesantana/gitfluence) - 尋找正確 git 指令的 AI 工具。 -------------------------------------------------------------------------------------- ![影響力](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8mr459i8l2lwa892nkae.png) 如您所知,學習每一個 git 指令是很困難的。如果用例很複雜,它就會變得複雜。 這就是為什麼 Gitinfluence 是人工智慧驅動的解決方案,可以幫助您快速找到正確的命令。借助這個出色的工具,您可以節省大量時間。 例如,這是我輸入我需要的內容後得到的回應。 ![回覆](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqylmd1mim7smgc78cby.png) 它就像聽起來一樣簡單而且非常有效率。 ![怎麼運作的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfmsm5cazm7sdnbvbmqe.png) 這是一個非常早期的開源專案 (next.js),擁有 55 顆星,但我確信它有很大的發展潛力。 {% cta https://github.com/geovanesantana/gitfluence %} 明星 Gitinfluence ⭐️ {% endcta %} --- 其中許多工具可以幫助您提高日常工作效率。 不管怎樣,如果您知道其他很棒的工具,請在評論中告訴我們。 祝你有美好的一天!直到下一次。 |如果你喜歡這類東西, 請關注我以了解更多:) | [![用戶名 Anmol_Codes 的 Twitter 個人資料](https://img.shields.io/badge/Twitter-d5d5d5?style=for-the-badge&logo=x&logoColor=0A0209)](https://twitter.com/Anmol_Codes) [![用戶名 Anmol-Baranwal 的 GitHub 個人資料](https://img.shields.io/badge/github-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/Anmol-Baranwal) [![用戶名 Anmol-Baranwal 的 LinkedIn 個人資料](https://img.shields.io/badge/LinkedIn-0A66C2?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/Anmol-Baranwal/) | |------------|----------| 關注 Taipy 以了解更多此類內容。 {% 嵌入 https://dev.to/taipy %} --- 原文出處:https://dev.to/taipy/17-developer-tools-that-keep-me-productive-37e2

TypeScript 專案的自訂實用程式類型

在我們探索 TypeScript 開發的第二部分中,我們引入了另外十種自訂實用程式類型,這些類型可以擴展程式碼的功能,提供更多工具來更有效地管理類型。這些實用程式類型有助於保持您的程式碼庫乾淨、高效和健壯。 第一部分: [TypeScript 專案的 1-10 個自訂實用程式類型](https://dev.to/antonzo/10-sustom-utility-types-for-typescript-projects-48pe) 總有機碳 ---- - [不可空深](#NonNullableDeep) - [合併](#Merge) - [元組到物件](#TupleToObject) - [獨佔元組](#ExclusiveTuple) - [Promise類型](#PromiseType) - [省略方法](#OmitMethods) - [函數參數](#FunctionArguments) - [承諾](#Promisify) - [約束函數](#ConstrainedFunction) - [聯合解析器](#UnionResolver) <a name="NonNullableDeep"></a> `NonNullableDeep` ----------------- `NonNullableDeep`類型是一個實用程序,可從給定類型`T`的所有屬性中深度刪除`null`和`undefined` 。這意味著不僅物件的頂級屬性不可為空,而且所有嵌套屬性也遞歸地標記為不可為空。在必須確保物件的屬性(包括深度嵌套的屬性)不為`null`或`undefined`情況下(例如在處理必須完全填充的資料時),此類型特別有用。 ``` type NonNullableDeep<T> = { [P in keyof T]: NonNullable<T[P]> extends object ? NonNullableDeep<NonNullable<T[P]>> : NonNullable<T[P]>; }; ``` **例子** 以下範例示範如何套用`NonNullableDeep`類型來確保`Person`物件本身及其任何巢狀屬性都無法為`null`或`undefined` ,從而確保整個物件已完全填入。 ``` interface Address { street: string | null; city: string | null; } interface Person { name: string | null; age: number | null; address: Address | null; } const person: NonNullableDeep<Person> = { name: "Anton Zamay", age: 26, address: { street: "Secret Street 123", city: "Berlin", }, }; // Error: Type 'null' is not assignable to type 'string'. person.name = null; // Error: Type 'undefined' is not assignable to type 'number'. person.age = undefined; // Error: Type 'null' is not assignable to type 'Address'. person.address = null; // Error: Type 'null' is not assignable to type 'string'. person.address.city = null; ``` <a name="Merge"></a> `Merge` ------- `Merge<O1, O2>`類型對於透過組合兩個物件類型`O1`和`O2`的屬性來建立新類型非常有用。當屬性重疊時, `O2`中的屬性將覆寫`O1`中的屬性。當您需要擴展或自訂現有類型以確保特定屬性優先時,這特別有用。 ``` type Merge<O1, O2> = O2 & Omit<O1, keyof O2>; ``` **例子** 在此範例中,我們定義了兩種物件類型,分別表示預設設定和使用者設定。使用`Merge`類型,我們組合這些設定來建立最終配置,其中`userSettings`會覆蓋`defaultSettings` 。 ``` type DefaultSettings = { theme: string; notifications: boolean; autoSave: boolean; }; type UserSettings = { theme: string; notifications: string[]; debugMode?: boolean; }; const defaultSettings: DefaultSettings = { theme: "light", notifications: true, autoSave: true, }; const userSettings: UserSettings = { theme: "dark", notifications: ["Warning 1", "Error 1", "Warning 2"], debugMode: true, }; type FinalSettings = Merge<DefaultSettings, UserSettings>; const finalSettings: FinalSettings = { ...defaultSettings, ...userSettings }; ``` <a name="TupleToObject"></a> `TupleToObject` --------------- `TupleToObject`類型是將元組類型轉換為物件類型的實用程序,其中元組的元素成為物件的鍵,並根據這些元素在元組中的位置提取關聯的值。這種類型在需要將元組轉換為更結構化的物件形式的情況下特別有用,允許透過元素的名稱而不是位置更直接地存取元素。 ``` type TupleToObject<T extends [string, any][]> = { [P in T[number][0]]: Extract<T[number], [P, any]>[1]; }; ``` **例子** 考慮這樣一個場景,您正在使用將表架構資訊儲存為元組的資料庫。每個元組包含一個欄位名稱及其對應的資料類型。這種格式通常用於資料庫元資料 API 或架構遷移工具。元組格式緊湊且易於處理,但對於應用程式開發來說,使用物件更方便。 ``` type SchemaTuple = [ ['id', 'number'], ['name', 'string'], ['email', 'string'], ['isActive', 'boolean'] ]; const tableSchema: SchemaTuple = [ ['id', 'number'], ['name', 'string'], ['email', 'string'], ['isActive', 'boolean'], ]; // Define the type of the transformed schema object type TupleToObject<T extends [string, string | number | boolean][]> = { [P in T[number][0]]: Extract< T[number], [P, any] >[1]; }; type SchemaObject = TupleToObject<SchemaTuple>; const schema: SchemaObject = tableSchema.reduce( (obj, [key, value]) => { obj[key] = value; return obj; }, {} as SchemaObject ); // Now you can use the schema object console.log(schema.id); // Output: number console.log(schema.name); // Output: string console.log(schema.email); // Output: string console.log(schema.isActive); // Output: boolean ``` <a name="ExclusiveTuple"></a> `ExclusiveTuple` ---------------- `ExclusiveTuple`類型是一個實用程序,它產生包含來自給定聯合類型`T`的唯一元素的元組。此類型確保聯合的每個元素僅在結果元組中包含一次,從而有效地將聯合類型轉換為具有聯合元素的所有可能的唯一排列的元組類型。這在您需要枚舉聯合成員的所有唯一組合的情況下特別有用。 ``` type ExclusiveTuple<T, U extends any[] = []> = T extends any ? Exclude<T, U[number]> extends infer V ? [V, ...ExclusiveTuple<Exclude<T, V>, [V, ...U]>] : [] : []; ``` **例子** 考慮這樣一個場景:您正在開發一個旅行應用程式的功能,該功能可以為遊覽某個城市的遊客產生獨特的行程。該市有三個主要景點:博物館、公園和劇院。 ``` type Attraction = 'Museum' | 'Park' | 'Theater'; type Itineraries = ExclusiveTuple<Attraction>; // The Itineraries type will be equivalent to: // type Itineraries = // ['Museum', 'Park', 'Theater'] | // ['Museum', 'Theater', 'Park'] | // ['Park', 'Museum', 'Theater'] | // ['Park', 'Theater', 'Museum'] | // ['Theater', 'Museum', 'Park'] | // ['Theater', 'Park', 'Museum']; ``` <a name="PromiseType"></a> `PromiseType` ------------- `PromiseType`類型是一個實用程序,用於提取給定 Promise 解析為的值的類型。這在使用非同步程式碼時非常有用,因為它允許開發人員輕鬆推斷結果的類型,而無需明確指定它。 ``` type PromiseType<T> = T extends Promise<infer U> ? U : never; ``` 此類型使用 TypeScript 的條件類型和`infer`關鍵字來決定`Promise`的解析類型。如果`T`擴展`Promise<U>` ,則表示`T`是解析為類型`U` `Promise` ,而`U`是推斷的類型。如果`T`不是`Promise` ,則型別解析為`never` 。 **例子** 以下範例示範如何使用 PromiseType 類型從 Promise 中提取已解析的類型。透過使用此實用程式類型,您可以推斷 Promise 將解析為的值的類型,這有助於在處理非同步操作時進行類型檢查並避免錯誤。 ``` type PromiseType<T> = T extends Promise<infer U> ? U : never; interface User { id: number; name: string; } interface Post { id: number; title: string; content: string; userId: number; } async function fetchUser(userId: number): Promise<User> { return { id: userId, name: "Anton Zamay" }; } async function fetchPostsByUser(userId: number): Promise<Post[]> { return [ { id: 1, title: "Using the Singleton Pattern in React", content: "Content 1", userId }, { id: 2, title: "Hoisting of Variables, Functions, Classes, Types, " + "Interfaces in JavaScript/TypeScript", content: "Content 2", userId }, ]; } async function getUserWithPosts( userId: number ): Promise<{ user: User; posts: Post[] }> { const user = await fetchUser(userId); const posts = await fetchPostsByUser(userId); return { user, posts }; } // Using PromiseType to infer the resolved types type UserType = PromiseType<ReturnType<typeof fetchUser>>; type PostsType = PromiseType<ReturnType<typeof fetchPostsByUser>>; type UserWithPostsType = PromiseType<ReturnType<typeof getUserWithPosts>>; async function exampleUsage() { const userWithPosts: UserWithPostsType = await getUserWithPosts(1); // The following will be type-checked to ensure correctness const userName: UserType["name"] = userWithPosts.user.name; const firstPostTitle: PostsType[0]["title"] = userWithPosts.posts[0].title; console.log(userName); // Anton Zamay console.log(firstPostTitle); // Using the Singleton Pattern in React } exampleUsage(); ``` **為什麼我們需要`UserType`而不僅僅是使用`User` ?** 這是個好問題!使用`UserType`而不是直接使用`User`主要原因是為了確保從非同步函數的回傳類型準確推斷出類型。這種方法有幾個優點: 1. **類型一致性:**透過使用`UserType` ,您可以確保類型始終與`fetchUser`函數的實際回傳類型一致。如果`fetchUser`的回傳類型發生更改, `UserType`將自動反映該更改,而無需手動更新。 2. **自動類型推斷**:在處理複雜類型和巢狀承諾時,手動確定和追蹤解析的類型可能具有挑戰性。使用 PromiseType 允許 TypeScript 為您推斷這些類型,從而降低錯誤風險。 <a name="OmitMethods"></a> `OmitMethods` ------------- `OmitMethods`型別是個實用程序,可從給定型別`T`中刪除所有方法屬性。這意味著作為函數的類型`T`的任何屬性都將被省略,從而產生僅包含非函數屬性的新類型。 ``` type OmitMethods<T> = Pick<T, { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]>; ``` **例子** 此類型在您想要從物件類型中排除方法的情況下特別有用,例如將物件序列化為 JSON 或透過 API 發送物件時,其中方法不相關且不應包含在內。以下範例示範如何將`OmitMethods`套用至物件類型以刪除所有方法,確保產生的類型僅包含非函數的屬性。 ``` interface User { id: number; name: string; age: number; greet(): void; updateAge(newAge: number): void; } const user: OmitMethods<User> = { id: 1, name: "Alice", age: 30, // greet and updateAge methods are omitted from this type }; function sendUserData(userData: OmitMethods<User>) { // API call to send user data console.log("Sending user data:", JSON.stringify(userData)); } sendUserData(user); ``` <a name="FunctionArguments"></a> `FunctionArguments` ------------------- `FunctionArguments`類型是一個實用程序,用於提取給定函數類型`T`的參數類型。這意味著對於傳遞給它的任何函數類型,該類型將傳回一個表示函數參數類型的元組。此類型在需要捕獲或操作函數的參數類型的情況下特別有用,例如在高階函數中或建立類型安全的事件處理程序時。 ``` type FunctionArguments<T> = T extends (...args: infer A) => any ? A : never; ``` **例子** 假設您有一個高階函數包裝,它接受一個函數及其參數,然後使用這些參數來呼叫該函數。使用 FunctionArguments,您可以確保包裝函數參數的類型安全。 ``` function wrap<T extends (...args: any[]) => any>(fn: T, ...args: FunctionArguments<T>): ReturnType<T> { return fn(...args); } function add(a: number, b: number): number { return a + b; } type AddArgs = FunctionArguments<typeof add>; // AddArgs will be of type [number, number] const result = wrap(add, 5, 10); // result is 15, and types are checked ``` <a name="Promisify"></a> `Promisify` ----------- `Promisify`類型是一個實用程序,它將給定類型`T`的所有屬性轉換為各自類型的 Promise。這意味著結果類型中的每個屬性都將是該屬性的原始類型的`Promise` 。這種類型在處理非同步操作時特別有用,您希望確保整個結構符合基於`Promise`的方法,從而更輕鬆地處理和管理非同步資料。 ``` type Promisify<T> = { [P in keyof T]: Promise<T[P]> }; ``` **例子** 考慮一個顯示使用者個人資料、最近活動和設定的儀表板。這些資訊可能是從不同的服務獲取的。透過承諾單獨的屬性,我們確保使用者資料的每個部分都可以獨立取得、解析和處理,從而在處理非同步操作時提供靈活性和效率。 ``` interface Profile { name: string; age: number; email: string; } interface Activity { lastLogin: Date; recentActions: string[]; } interface Settings { theme: string; notifications: boolean; } interface UserData { profile: Profile; activity: Activity; settings: Settings; } // Promisify Utility Type type Promisify<T> = { [P in keyof T]: Promise<T[P]>; }; // Simulated Fetch Functions const fetchProfile = (): Promise<Profile> => Promise.resolve({ name: "Anton Zamay", age: 26, email: "[email protected]" }); const fetchActivity = (): Promise<Activity> => Promise.resolve({ lastLogin: new Date(), recentActions: ["logged in", "viewed dashboard"], }); const fetchSettings = (): Promise<Settings> => Promise.resolve({ theme: "dark", notifications: true }); // Fetching User Data const fetchUserData = async (): Promise<Promisify<UserData>> => { return { profile: fetchProfile(), activity: fetchActivity(), settings: fetchSettings(), }; }; // Using Promisified User Data const displayUserData = async () => { const user = await fetchUserData(); // Handling promises for each property (might be in different places) const profile = await user.profile; const activity = await user.activity; const settings = await user.settings; console.log(`Name: ${profile.name}`); console.log(`Last Login: ${activity.lastLogin}`); console.log(`Theme: ${settings.theme}`); }; displayUserData(); ``` <a name="ConstrainedFunction"></a> `ConstrainedFunction` --------------------- `ConstrainedFunction`類型是一個實用程序,它約束給定的函數類型 T 以確保保留其參數和傳回類型。它本質上捕獲函數的參數類型和返回類型,並強制結果函數類型必須遵守這些推斷類型。當您需要對高階函數實施嚴格的類型約束或建立必須符合原始函數簽署的包裝函數時,此類型非常有用。 ``` type ConstrainedFunction<T extends (...args: any) => any> = T extends (...args: infer A) => infer R ? (args: A extends any[] ? A : never) => R : never; ``` **例子** 在事先未知函數簽署且必須動態推斷的情況下, `ConstrainedFunction`可確保根據推斷的類型正確應用約束。想像一個實用程序,它包裝任何函數以記憶其結果: ``` function memoize<T extends (...args: any) => any>(fn: T): ConstrainedFunction<T> { const cache = new Map<string, ReturnType<T>>(); return ((...args: Parameters<T>) => { const key = JSON.stringify(args); if (!cache.has(key)) { cache.set(key, fn(...args)); } return cache.get(key)!; }) as ConstrainedFunction<T>; } const greet: Greet = (name, age) => { return `Hello, my name is ${name} and I am ${age} years old.`; }; const memoizedGreet = memoize(greet); const message1 = memoizedGreet("Anton Zamay", 26); // Calculates and caches const message2 = memoizedGreet("Anton Zamay", 26); // Retrieves from cache ``` 在這裡, `memoize`使用`ConstrainedFunction`來確保記憶函數保持與原始函數`fn`相同的簽名,而不需要明確定義函數類型。 <a name="UnionResolver"></a> `UnionResolver` --------------- `UnionResolver`類型是將聯合型別轉換為可區分聯合的實用程式。具體來說,對於給定的聯合類型`T` ,它會產生一個物件陣列,其中每個物件都包含一個屬性類型,該屬性類型保存聯合中的類型之一。在需要明確處理聯合的每個成員的情況下使用聯合類型時,此類型特別有用,例如在類型安全的 Redux 操作或 TypeScript 中的可區分聯合模式中。 ``` type UnionResolver<T> = T extends infer U ? { type: U }[] : never; ``` **例子** 以下範例示範如何應用`UnionResolver`類型將聯合類型轉換為物件陣列,每個物件都具有`type`屬性。這允許對聯合內的每個操作進行類型安全處理,確保考慮到所有情況並降低使用聯合類型時發生錯誤的風險。 ``` type ActionType = "ADD_TODO" | "REMOVE_TODO" | "UPDATE_TODO"; type ResolvedActions = UnionResolver<ActionType>; // The resulting type will be: // { // type: "ADD_TODO"; // }[] | { // type: "REMOVE_TODO"; // }[] | { // type: "UPDATE_TODO"; // }[] const actions: ResolvedActions = [ { type: "ADD_TODO" }, { type: "REMOVE_TODO" }, { type: "UPDATE_TODO" }, ]; // Now you can handle each action type distinctly actions.forEach(action => { switch (action.type) { case "ADD_TODO": console.log("Adding a todo"); break; case "REMOVE_TODO": console.log("Removing a todo"); break; case "UPDATE_TODO": console.log("Updating a todo"); break; } }); ``` --- 原文出處:https://dev.to/antonzo/11-20-sustom-utility-types-for-typescript-projects-2bg5

適用於 React 和 NodeJS 的最佳免費開源 SaaS 模板

展示開放 SaaS 🎉 ----------- 我們非常高興推出[Open SaaS](https://opensaas.sh) ,這是適用於 React、NodeJS 和 Prisma 的完全免費、開源、生產級 SaaS 樣板。 在這裡查看它的實際效果: https://www.youtube.com/watch?v=rfO5SbLfyFE Open SaaS 擁有您最近看到的那些付費 SaaS 入門者的所有功能,除了它完全**免費**且**開源**。 **我們覺得為一些需要自己管理的樣板程式碼支付 300-2,000 美元是瘋狂的**。最重要的是,許多樣板文件嚴重依賴第三方服務。再加上託管和其他費用,您需要花費大量資金才能將您的想法推向世界。 **這就是為什麼透過開放 SaaS,我們有意識地決定盡可能嘗試使用開源和免費服務。**例如,我們在[OpenSaaS.sh](http://OpenSaaS.sh)上託管的演示應用程式及其管理儀表板由 Plausible 分析的自架版本提供支援。希望您的 SaaS 具有相同的功能嗎?那麼,Open SaaS 已為您預先配置好! 此外,Open SaaS 使用的[Wasp 框架](https://wasp.sh)可以為您建立許多功能,例如 Auth 和 Cron 作業,這樣您就不必支付第三方服務費用或完全自己編寫程式碼(我們稍後會更詳細地解釋這一點)。 人們已經在使用開放 SaaS 建置什麼... ---------------------- 自正式發布以來,已有大量人員使用 Open SaaS 建立了令人驚嘆的應用程式並推出了超級創意業務。因此,我們首先要強調其中的一些內容。 以下是我們社區中一些應用程式的精選清單: 1. [Solon](https://trysolon.co) :Instagram/whatsapp 賣家的人工智慧銷售代理,幫助客戶探索產品。 ![梭倫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j32pl4a078c587jffsin.png) 2. [Captn.ai](https://captn.ai) :人工智慧代理團隊協作,自動建立、監控和優化 Google Ads 廣告活動。 ![船長](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzygxmy4iu1yi9r758nc.png) 3. [Bleepify](https://bleepify.me) :在人工智慧的幫助下,自動配音或立即從影片中刪除某些單字。對於快速使 YouTube 影片符合其行為準則非常有幫助。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eqdqbvjwvfpv2rmmaypn.png) 4. [取得 AI 部落格文章](https://getaiblogarticles.com/):以 Markdown 格式提供的高品質、專注於 SEO 的部落格文章產生器 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qyzpg3gbipgyuy7g6lh.png) 如果上面的這些範例還沒有激發您的建造靈感,請繼續閱讀下面的內容,我們將討論為什麼建立開源 SaaS 模板、我們使用的堆疊以及它的工作原理。 為什麼我們要建造它......然後免費贈送它 ---------------------- 自從我們正式發布以來,反饋非常積極。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/subbtpb2syehdtuuof0r.png) 很多人對它讚不絕口,並且已經用它建置了許多 SaaS 應用程式,但我們也收到了一些問題,例如: - “它會保持免費嗎?” - “您開源這個的動機是什麼?” 所以我們認為我們應該先回答這些問題。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rac9o1rxgrwfx51mc50.png) 首先,是的,它是 100% 免費和開源的,並將保持這種狀態。 其次,我們相信,開發者、獨立駭客和個人企業家社群的集體知識將比個人或小團體產生更好的樣板。當您從某些開發人員那裡購買SaaS 入門版時,您已經獲得了一個固執己見的堆棧,然後除此之外,您還獲得了按照他們認為最好的方式建置的應用程式- 但這可能並不總是最適合*您。* 第三, [Open SaaS](https://opensaas.sh)是[Wasp](https://wasp.sh)的一個專案,一個超強的開源React + NodeJS + Prisma全端框架。我們 Wasp 團隊相信 Wasp 非常適合快速且有效率地建立 SaaS 應用程式,我們希望這個模板能夠證明這一點。另外,身為開發人員,我們從其他開源專案中學到了很多東西,而 Wasp 本身就是一個開源專案。 基本上,我們熱愛開源理念,並且希望將其發揚光大。 🙏 因此,我們希望能夠為開發者社群提供非常有價值的資產,同時宣傳我們的開源全端框架。我們很高興看到社區為其做出貢獻,以便它不斷發展並成為最好的 SaaS 樣板。 開放 SaaS 是由什麼組成的 --------------- 我們在 Open SaaS 上投入了大量的精力,包括[文件](https://docs.opensaas.sh),以便開發人員可以自信、輕鬆地啟動 SaaS 應用程式。 我們還花了一些時間檢查其他免費的開源 SaaS 啟動器,並希望確保 Open SaaS 具有可立即投入生產的啟動器的所有正確功能,而不顯得臃腫。我們認為我們已經在很大程度上實現了這一點,儘管我們將繼續加入功能並隨著時間的推移進行改進。 目前的主要特點如下: - 🔐 身份驗證(電子郵件驗證、Google、github) - 📩 電子郵件(sendgrid、emailgun、SMTP) - 📈 管理儀表板(合理或谷歌分析) - 🤑 Stripe 付款(只需加入您的訂閱產品 ID) - ⌨️ 端對端類型安全性(無需配置) - 🤖 OpenAI 整合(AI 驅動的範例應用程式) - 📖 Astro 博客 - 🧪 與劇作家進行端到端測試 - 🚀 部署在任何地方 - 📄 完整的文件和社群支持 值得深入了解其中每個功能的細節,所以讓我們開始吧。 ### 授權 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wbistoghxrxft9zxxra1.png)](https://www.producthunt.com/posts/open-saas) 感謝 Wasp,Open SaaS 附帶了許多可能的身份驗證方法: - 使用者名稱和密碼(最簡單/最容易進行開發測試) - 已驗證電子郵件並重設密碼 - Google 和/或 Github 社群登入 這就是 Wasp 真正發揮作用的地方,因為設定全端 Auth 並取得預先配置的 UI 元件所需要做的就是: ``` //main.wasp app SaaSTemplate { auth: { userEntity: User, methods: { usernameAndPassword: {}, google: {}, gitHub: {}, } } } ``` 嚴重地。就是這樣! 只需確保您已設定社交身份驗證並擁有 API 金鑰以及定義的`User`和`ExternalAuth`實體,就可以開始了。不用擔心,這部分內容已在[Open SaaS Docs](https://docs.opensaas.sh)中詳細記錄和解釋。 最重要的是,Open SaaS 預先配置了一些範例,說明如何自訂和建立一些真正強大的身份驗證流程。 ### 管理儀表板和分析 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4mm6s1c3txxgm49e2k7w.png)](https://www.producthunt.com/posts/open-saas) 透過利用[Wasp 的工作功能](https://wasp-lang.dev/docs/advanced/jobs),Open SaaS 每小時從 Plausible 或 Google 的網站分析(您的選擇!)和 Stripe 的資料 API 中提取資料,並將其保存到我們的資料庫中。然後,該資料將顯示在我們的管理儀表板上(前往[OpenSaaS.sh](https://OpenSaaS.sh)查看其實際情況)。好的部分是,要為您自己的應用程式存取這些資料,您所要做的就是按照我們的指南獲取分析 API 金鑰,插入提供的腳本,然後就可以開始了! 再次強調,Wasp 讓整個過程變得非常簡單。透過已經為您定義的查詢 API 和取得我們需要的資料的功能,Open SaaS 然後在`main.wasp`設定檔中使用 Wasp 作業: ``` job dailyStatsJob { executor: PgBoss, perform: { fn: import { calculateDailyStats } from "@server/workers/calculateDailyStats.js" }, schedule: { cron: "0 * * * *" }, entities: [User, DailyStats, Logs, PageViewSource] } ``` 就是這樣! Wasp 負責為您設定和執行 cron 作業。 ### 條紋支付 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugy3mx9xo1d9i9vfysr7.png)](https://www.producthunt.com/posts/open-saas) 如果您是以前從未建立過自己的 SaaS 的開發人員,那麼與 Stripe 這樣的支付處理器整合可能是您將面臨的少數挑戰之一。 當我建立第一個 SaaS [CoverLetterGPT.xyz](https://coverlettergpt.xyz)時,我的情況就是如此。這實際上是我建造它的主要動機之一;了解如何將 Stripe 支付整合到應用程式以及 OpenAI API 中。 儘管 Stripe 因擁有豐富的文件而聞名,但這個過程仍然令人畏懼。你必須: - 建立正確的產品類型 - 設定 webhook 端點 - 告訴 Stripe 將正確的 Webhook 事件傳送給您 - 正確使用事件 - 處理重複付款和失敗付款 - 在上線之前透過 CLI 進行正確測試 這就是為什麼為您設定 Stripe 訂閱付款是一個巨大的勝利。 但比這更重要的是,為您方便地記錄整個過程!這就是為什麼 Open SaaS[在我們的文件中為您提供方便的 Stripe 指南](https://docs.opensaas.sh)🙂 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uehwot350u3dl02s4w7r.png)](https://www.producthunt.com/posts/open-saas) ### 端對端類型安全 Open SaaS 是使用 Typescript 建置的,因為它是一個全棧應用程式,所以從後端到前端的類型安全可以成為真正的救星。我的意思是,一些[固執己見的堆疊](https://create.t3.gg/)在此基礎上變得非常流行。 幸運的是,Wasp 為您提供開箱即用的端到端類型安全性(無需配置!),因此 Open SaaS 可以輕鬆利用它。 這是一個例子: 1. 讓 Wasp 了解您的伺服器操作: ``` // main.wasp action getResponse { fn: import { getResponse } from "@server/actions.js", entities: [Response] } ``` 2. 輸入並實施您的伺服器操作。 ``` // src/srever/actions.ts type RespArgs = { hours: string; }; const getResponse: GetResponse<RespArgs, string> = async ({ hours }) => { } ``` 3. 導入並在客戶端呼叫。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fah81r1g4bg3vdqapju.png) 客戶端類型將被正確推斷! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7n04yh6de9slhhnjrgf3.png) ### AI 驅動的範例應用程式(附有 OpenAI API) [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zbbc2gkxbxjl3q2y01a3.png)](https://www.producthunt.com/posts/open-saas) 人工智慧正在使新的應用程式創意成為可能,這也是我們看到開發人員對建立 SaaS 應用程式的興趣重新抬頭的部分原因。正如我上面提到的,我建造的第一個 SaaS 應用程式[CoverLetterGPT](https://coverlettergpt.xyz)是「GPT 包裝器」之一,我很自豪地說它帶來了約350 美元MRR(每月經常性收入)的可觀被動收入。 我個人認為,我們在軟體開發方面處於最佳狀態,開發新的、有利可圖的人工智慧應用程式有很大的潛力,尤其是「獨立駭客」和「個人企業家」。 這就是 Open SaaS 推出 AI 調度助手演示應用程式的原因。您輸入任務及其分配的時間,AI Scheduler 會為您的一天建立詳細的計劃。 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j4suf7g9jm5w93ri3bqx.png)](https://www.producthunt.com/posts/open-saas) 在幕後,這是使用 OpenAI 的 API 為每個任務分配優先級,並將它們分解為詳細的子任務,包括喝咖啡休息時間!它還利用 OpenAI 的函數呼叫功能以使用者定義的 JSON 物件回傳回應,以便客戶端每次都能正確使用它。此外,我們計劃在未來加入開源法學碩士,敬請期待! 示範版 AI Scheduler 可協助開發人員學習如何有效使用 OpenAI API,並激發一些 SaaS 應用程式創意! ### 隨處部署。容易地。 許多流行的 SaaS 新創公司都使用依賴託管的框架,這意味著您只能依賴一個提供者進行部署。雖然這些都是簡單的選擇,但它可能並不總是最適合您的應用程式。 Wasp 為您提供了部署全端應用程式的無限可能性: - 使用`wasp deploy`一鍵部署到[Fly.io](http://Fly.io) - 使用`wasp build`並部署 Dockerfiles 和客戶端,無論您喜歡什麼! `wasp deploy`的優點在於它會自動產生和部署您的資料庫、伺服器和用戶端,並為您設定環境變數。 Open SaaS 還內建了環境變數和常數驗證器,以確保您已正確設定部署所需的所有內容,以及文件中的部署指南 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fihbij250xtbdtjbjoks.png)](https://www.producthunt.com/posts/open-saas) 最後,您擁有自己的程式碼,並且可以自由地將其部署到任何地方,而無需受供應商鎖定。 幫助我們,幫助你 -------- 想支持我們的免費開源計畫嗎?然後[在 GitHub 上為我們加註星標以向](https://github.com/wasp-lang/open-saas/)我們表示支持🙏 ![https://media1.giphy.com/media/ZfK4cXKJTTay1Ava29/giphy.gif?cid=7941fdc6pmqo30ll0e4rzdiisbtagx97sx5t0znx4lk0auju&ep=v1_gifs_searchx97sx5t0znx4lk0auju&ep=v1_gifs_search}&ridgi.](https://media1.giphy.com/media/ZfK4cXKJTTay1Ava29/giphy.gif?cid=7941fdc6pmqo30ll0e4rzdiisbtagx97sx5t0znx4lk0auju&ep=v1_gifs_search&rid=giphy.gif&ct=g) <https://www.github.com/wasp-lang/wasp> ⭐️ 給 Open SaaS 一顆星 🙏 現在就開始建立您的 SaaS! --------------- 我們希望 Open SaaS 能夠讓更多的開發人員能夠發布他們的想法和副專案。我們也希望從開發人員那裡獲得一些回饋和意見,以便我們能夠使其成為最好的 SaaS 樣板啟動器。 因此,如果您有任何意見或發現任何錯誤,請[在此處提交問題](https://github.com/wasp-lang/open-saas/issues)。 如果您發現 Open SaaS 和/或 Wasp 很有用,最簡單的支援方法就是給我們一顆星: - 為[Open SaaS 儲存庫](https://github.com/wasp-lang/open-saas)加註星標 - 給[黃蜂倉庫](https://github.com/wasp-lang/wasp)加註星標 --- 原文出處:https://dev.to/wasp/the-best-free-open-source-saas-template-for-react-nodejs-263

REST API 設計規則

為什麼編寫乾淨的 REST-API 設計很重要 ----------------------- 在當今互聯的世界中,精心設計的 REST API 是高效且可擴展的應用程式的支柱。 編寫乾淨的 REST API 設計至關重要,原因如下: - **增強的可用性:**精心設計的 API 直覺且易於使用,適合各種技能水平的開發人員使用。這簡化了整合並縮短了學習曲線。 - **提高可維護性:**乾淨的程式碼可以更輕鬆地辨識和修復錯誤、加入功能和擴展 API,從而提高可維護性。這確保了長期穩定性並降低了開發成本。 - **提高安全性:**結構良好的 API 具有適當的身份驗證和授權機制,有助於防止未經授權的存取、資料外洩和其他安全漏洞。 - **增強的效能:**簡潔的設計透過使用高效的資料結構、避免不必要的呼叫並最大限度地減少延遲來優化效能。這提供了無縫的用戶體驗並提高了整體應用程式效能。 - **縮短開發時間:**明確定義的 API 規格和清晰的文件可消除猜測並減少大量測試的需要,從而加快開發速度。這節省了寶貴的開發時間和資源。 - **改進的可擴展性:**簡潔的設計透過提供模組化架構來實現輕鬆的可擴展性,該架構可以輕鬆擴展以處理增加的流量或新功能。這確保了 API 可以隨著應用程式的需求而成長。 - **提高可重複使用性:**設計良好的 API 可以在多個應用程式中重複使用,從而減少重複並提高一致性。這簡化了開發並節省了時間和精力。 - **改進的文件:**簡潔的設計更容易記錄,讓開發人員清楚 API 的工作原理以及如何有效地使用它。這可以減少混亂並提高採用率。 URI規則 ----- **一個url的結構如下** **`scheme :// authority / path [?query][#fragment]`** 例如 `https://soccer.api.org/teams/dortmund/players?name=Rona#2` 有兩種類型的資源 1. 集合資源:包含資源的集合。它可以比喻為資料庫關係 2. 單例資源:包含單一資源。它可以比喻為資料庫記錄。 --- 設計 Rest-Api 時 1 集合資源應該是複數 ``` + soccer.api.org/teams/dortmond - soccer.api.org/team/dortmond ``` 2 Singleton資源應該是單一的,可以用api後面資料庫系統中代表資源的唯一id來代替 ``` +soccer.api.org/teams/dortmond/players/58c1aaae-205a-11ef-aeea-a64c74618950 ``` 3 URI 中沒有**尾隨正斜杠** ``` +soccer.api.org/teams/dortmond/players -soccer.api.org/teams/dortmond/players/ ``` 4 使用**連字號**取代**底線**以提高 API 的可讀性 ``` + api.blog.com/blogs/this-is-my-blog - api.blog.com/blogs/this_is_my_blog ``` 5 URI 路徑**中小寫字母**優先於**大寫字母** ``` + api.example.com/my-api/my-resource - api.example.com/My-Api/My-Resource ``` 6 URI 中沒有**檔案副檔名** ``` + api.example.com/api/resource - api.example.com/api/resource.json ``` 7 CRUD 函數名稱**不應**在 URI 中使用 ``` + DELETE api.example.com/api/resource - GET api.example.com/api.resource/delete ``` 8 URI 的查詢元件只能在集合資源中使用 ``` + GET /users?role=admin ``` 9 URI 的查詢元件應用於對集合結果分頁 ``` + GET /users?pageSize=25&pageStartIndex=50 ``` HTTP 方法規則 --------- | HTTP 方法 |用途 | | ----------- | -------------------------------------------------- -------------------------------------------------- ------------- | |POST |建立新資源。類似於建立 | |GET |獲取資源的表示。類似閱讀 | |PUT|透過替換**整個**資源來更新資源 | |DELETE |刪除資源 | |PATCH|透過更改所需資源的一部分來更新資源,而不取代整個資源。 | |HEAD|僅獲取響應頭而不是響應體 | |OPTION |獲取特定資源的所有可用選項 | > PUT 可用於建立和更新資源。但是,根據最佳實踐,通常建議使用 POST 來建立新資源,並使用 PUT 來完全取代現有資源。 --- 版本控制 ---- 對 api 進行版本控制對於以下方面可能很重要: **保持向後相容性:**版本控制可讓您引入新功能,而不會破壞依賴舊 API 版本的現有整合。使用者可以繼續使用熟悉的端點,而尋求新功能的使用者可以採用版本化的 API。 **確保一致且設計良好的 API:**跨版本的一致命名約定有助於提供使用者友善的體驗。更改端點會破壞這種體驗,而版本控制有助於避免這種情況。 --- 結論 == 現在您已經掌握了這些 REST API 設計規則,是時候將它們付諸實現了!在下面的評論中分享您的 API 創作,讓我們一起建立一個設計良好且對開發人員友好的 API 世界。 --- 原文出處:https://dev.to/ezekiel_77/rest-api-design-rules-2c4j

21 個可提高您工作效率的 VS Code 擴展

開發者們大家好👋 身為開發人員,我們大部分時間都花在 VS Code 上。在這篇文章中,我將分享一些 VS Code 擴展,它們可以幫助提高您的工作效率並節省您的寶貴時間。 讓我們開始吧🚀 Codiumate -- ![鈉鹽](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tmm61xovmha09i9us1fl.png) > ✨ Codiumate 使用 AI 產生測試、檢視測試結果、修復用 Python、JavaScript、TypeScript 和 Java 等各種程式語言編寫的程式碼的錯誤和錯誤。它在您的 IDE 中充當您的私人代理或助手。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=Codium.codium) Partial Diff ---- ![部分差異](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8uqlcq8e60lkthg7dosx.png) > ✨ Partial Diff 擴充功能可讓您比較同一文件內或不同文件中的不同文字選擇,從而更容易發現變更和差異。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=ryu1kn.partial-diff) Git Graph ---- ![git圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ww8j9qvrsr66wmn0mosw.png) > ✨ Git Graph 擴充功能為您提供了 Git 儲存庫的視覺化表示,讓您更容易理解和管理分支、提交和合併,您還可以從圖表中執行 Git 操作。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph) Path Intellisense ------ ![路徑智能](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v22b2kyhxwwfpzpnwtc4.png) > ✨ Path Intellisense 擴充擴展了 VS Code 中的預設路徑完成,以包含工作區中的所有可用路徑,即使它們尚未匯入。 🔹連結 [👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense) Error Lens ---- ![誤差透鏡](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ui3i6k3zm1b64r1ga7xb.png) > ✨ Error Lens 擴充功能透過直接在程式碼中顯示錯誤訊息來增強 VS Code 中的錯誤突出顯示。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) SQL工具 ----- ![SQL工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ceg4gtsb96fme1in7z2.png) > ✨ SQLTools 是 VS Code 的輕量級 SQL 用戶端,它為您提供資料庫管理、查詢執行,並直接在編輯器中提供視覺化結果。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=mtxr.sqltools) Markdown 多合一 ------------ ![Markdown 多合一](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3k7dpy89w65i30ggq8ih.png) > ✨ Markdown All in One 擴展為 Markdown 編輯提供全面支持,包括快捷方式、目錄生成等。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) Turbo 控制台日誌 ----------- ![Turbo 控制台日誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ycisuti1dsz1z632olq.png) > ✨ Turbo Console Log 擴充功能會自動將有意義的 console.log 語句新增到您的程式碼中,這可以在偵錯過程中節省大量時間。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=ChakrounAnas.turbo-console-log) Quokka.js --------- ![Quokka.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bko1yy8akuwm36ny4j4u.png) > ✨ Quokka.js 是一款用於快速 JavaScript / TypeScript 原型設計的開發人員生產力工具。當您鍵入時,執行時間值會更新並顯示在 IDE 中程式碼旁邊。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=WallabyJs.quokka-vscode) 專案經理 ---- ![專案經理](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drvs445isps5ydysl58v.png) > ✨ 專案管理器可讓您在 VS Code 中的不同專案之間輕鬆切換,使其成為管理和導航多個專案的捷徑。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager) Todo Tree --- ![所有樹](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xr5zknvtyuujeipsmbh0.png) > ✨ Todo Tree 擴充功能掃描您的程式碼中的註解標籤,例如 TODO 和 FIXME,並將它們顯示在活動欄中的樹狀視圖中。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree) TabNine ---- ![選項卡九](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bycu1zglpkloehx8yq1d.png) > ✨ TabNine 是一款支援多種程式語言的人工智慧程式碼補全擴展,它為您提供智慧程式碼建議、即時程式碼補全、聊天和程式碼生成。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=TabNine.tabnine-vscode) Better Comments ----- ![更好的評論](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkjarirc3nsaeqg509zr.png) > ✨ Better Comments 擴充功能可協助您在程式碼中建立或編寫更人性化的註解。它允許您使用不同的顏色將註釋分類為警報、查詢、待辦事項等。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments) Polacode --- ![波拉碼](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0shnpzcdku2prtrafvl.png) > ✨ Polacode 是一款時尚的程式碼螢幕截圖工具,可讓您直接從 VS Code 建立漂亮的程式碼螢幕截圖。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=pnp.polacode) REST Client ----- ![休息客戶端](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s54cm9rrjwllxjipi9y0.png) > ✨ REST 用戶端可讓您直接在 VS Code 中發送 HTTP 請求並查看回應,從而更輕鬆地測試和偵錯 API。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) HTML CSS 支持 ----------- ![HTML CSS 支持](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tk68l0ra0jjpy07ebe0t.png) > ✨ HTML CSS 支援根據工作區中的 CSS 檔案為 HTML 類別屬性提供 CSS 類別和 ID 名稱補全。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=ecmel.vscode-html-css) Git Lens ---- ![吉特透鏡](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iyhhk9m4xezrl6gqrrh9.png) > ✨ GitLens 擴充功能增強了 VS Code 的內建 Git 功能。它可以幫助您視覺化程式碼作者、無縫導航和探索 Git 儲存庫,並深入了解您的程式碼。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) Wakatime ---- ![瓦卡時間](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pfs2ux1njyipa8cdc88n.png) > ✨ WakaTime 擴充功能為您的編碼活動提供自動時間追蹤。它可以讓您深入了解自己的編碼習慣,並幫助您更有效地管理時間。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=WakaTime.vscode-wakatime) Bookmarks -- ![書籤](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jn88xn94pg001feiazq.png) > ✨ 書籤擴充功能可協助您在程式碼中導航,輕鬆快速地在重要位置之間移動。不再需要搜尋程式碼。它還支援一組選擇命令,允許您選擇已加入書籤的行以及已加入書籤的行之間的區域。它對於日誌檔案分析非常有用。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks) PlantUML ----- ![植物UML](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvlanhdp5yx61xteaen1.png) > ✨ PlantUML 擴充功能可讓您從純文字描述建立 UML 圖,從而輕鬆視覺化和記錄您的系統設計。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml) 尾隨空格 ---- ![尾隨空格](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/55wyje0me31nchvmkk6k.png) > ✨ 尾隨空格擴充會自動反白並刪除程式碼中的尾隨空格,它有助於保持程式碼整潔且一致。 🔹連結[👉marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces) 這就是這篇文章的內容。感謝您的閱讀💖 > 請在評論中告訴我您最常使用哪一個或任何其他有用的擴充功能👇 在 👉 https://x.com/kiran\_\_a\_\_n X https://github.com/Kiran1689 GitHub 上找到我 https://dev.to/dev\_kiran --- 原文出處:https://dev.to/dev_kiran/21-vs-code-extensions-to-boost-your-productivity-1fil

如何建立基本的 RAG 應用程式

生成式人工智慧的出現使我們建構的應用程式具有新的功能成為可能。法學碩士可以以令人難以置信的技巧回答使用者的問題。那麼,為什麼不將它們用作我們系統的一部分呢?如果用戶需要協助使用該應用程式,我們可以加入聊天功能,法學碩士將回答用戶的所有問題。如果我們的應用程式有解釋重要概念的部落格文章,而不是讓用戶閱讀所有內容來獲取所需的知識,它可以只詢問並立即得到回應。 為什麼是拉格? ------- 我們決定將法學碩士整合到我們的應用程式中,為我們的用戶帶來這些功能。然而,我們很快就發現該模型無法回答使用者的問題。它沒有任何關於我們的應用程式的資訊!如果需要回答的資訊不在LLM的訓練資料中,則無法回答。更糟的是,如果它不知道答案,它可能會產生一個完全錯誤的事實的幻覺!這很糟糕,那麼我們該如何解決這個問題呢?採用 Transformer 架構的法學碩士已展現出優異的情境學習能力。因此,我們只需在提示中傳遞它所需的所有事實以及問題即可!呃哦,每次提示都塞滿所有資料肯定會很貴。那麼,我們該怎麼做呢? 什麼是RAG? ------- RAG 代表**檢索增強產生**。 RAG與變形金剛一起誕生。最初,它被用來用額外的事實來增強法學碩士的預訓練資料。一旦 Transformers 的情境學習能力變得明顯,在推理過程中增強提示也成為一種常見做法。 基本的 RAG 管道由三個步驟組成:索引、檢索和產生。法學碩士需要回答的所有資訊都在向量資料庫中建立了索引。當使用者提出問題時,我們可以從該向量資料庫中檢索資訊的相關部分。最後,結合相關資訊和使用者的問題,我們可以提示法學碩士根據我們作為上下文提供的資訊給出答案。讓我們更詳細地看看如何實現這一目標。 ### 索引 首先,我們從任何地方提取模型所需的資訊。生成模型使用純文字(某些模型也可以使用圖像或其他格式,這些格式也可以被索引,但這是另一個主題)。如果訊息已經是純文字形式,那麼我們很幸運。但它也可能存在於 PDF 文件、Word 文件、Excel、Markdown 等。 ![索引過程](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9rbz60uizoiswi8lng0k.png) 一旦資訊採用文字格式,我們就可以將其儲存在向量資料庫中。向量資料庫將儲存該文字的嵌入表示。這將使我們能夠搜尋與另一個文本具有相似嵌入表示的文本部分,因此它們涉及相似的概念。我們將整個文字分成更小的部分或區塊,計算每個部分的嵌入表示,最後將它們儲存在向量資料庫中。 ### 恢復 當使用者問我們一個問題時,我們可以使用我們用於索引資料的相同嵌入模型將該問題轉換為向量表示。利用該向量表示,我們將計算問題與向量資料庫中儲存的每個區塊之間的相似度因子。我們將選擇與查詢最相似的前 K 個區塊,因此它們的內容與問題的概念相同(因此它們可能包含答案)。 ![檢索流程](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/isms443c1ytjcazo5t17.png) ### 世代 系統會建立一個提示,將使用者的問題和相關上下文放在一起,以幫助 LLM 回答。我們也可能包含用戶和人工智慧助理之間對話的先前訊息。 LLM 根據上下文而不是之前學習的預訓練資料為使用者產生答案。 ![檢索流程](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9ih4417ubpht7kyskav.png) 例子 -- 對於這個例子,我們將收錄一篇名為「蘭格語言模型的檢索增強生成:調查」的論文。我們將使用本文中包含的資訊查詢LLM,以便它可以回答使用者對其內容的疑問。您可以在[本文提供的 Google Colab 筆記本](https://colab.research.google.com/drive/1mFmPN0GBHpS-kMDMuU8EDrWu1KENy69e?usp=sharing)中遵循此範例。 首先,我們將載入 PDF 文件並使用 LangChain 的 PyPDF 連接器對其進行解析。 ![使用 pypdf 載入文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mggsh8vxc1i6aknze50x.png) 一旦我們從文件中獲得文本,我們就必須將其分割成更小的區塊。我們可以使用 LangChain 的可用分割器,例如本例中的 RecursiveCharacterSplitter: ![將文件分割成區塊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92h7gf78bv699oup9xfc.png) 我們將使用 BGE-small,一種開源嵌入模型。我們將從 HuggingFace Hub 下載它並在所有區塊上執行它以計算它們的向量表示。 ![計算嵌入](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g9qoe5p4b0t37gooh4ix.png) 一旦我們有了所有區塊的向量表示,我們就可以建立一個記憶體向量資料庫並將所有向量儲存在其中。對於此範例,我們將使用 FAISS 資料庫。 ![將嵌入載入到向量資料庫中](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kvw8o3f9hwtafr3olord.png) 資料庫現已建立。現在,我們將接受用戶對此資訊的查詢。在這種情況下,用戶詢問 Naive RAG 的缺點是什麼。我們使用與先前相同的嵌入模型對該查詢進行編碼。然後,我們檢索與該查詢最相似的前 5 個區塊。 ![從向量資料庫中檢索與查詢類似的文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3euuftp1j1edlvj8oau.png) 檢索相關上下文後,我們使用此資訊和使用者的原始查詢來建立提示。在這個例子中,我們將使用克勞德的俳句作為法學碩士: ![使用上下文和查詢來產生答案](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdl7s7gownp37psg9084.png) 常見問題和陷阱 ------- 正如標題所暗示的,該解決方案是一個基本的或簡單的 RAG 實作。它將幫助您的申請充分利用其所使用的法學碩士和您的資料。但它並不適用於所有情況。這些只是 RAG 最常見的問題: - **檢索不相關的資訊。**如果檢索器從向量資料庫中獲取與問題無關的資料,它將混淆試圖回答問題的模型。這可能會導致不使用上下文來回答問題,或回答與所問內容不同的問題。 - **錯過重要資訊。**也許回答問題所需的資訊不在資料庫中。也許檢索機制無法找到相關的區塊。我們必須找到方法來幫助檢索器輕鬆、更可靠地找到所需的資訊。 - **產生上下文不支援的回應。**如果上下文有模型需要的訊息,但它不使用它而是依賴自己的預訓練資料,那麼這一切都是徒勞的。預訓練資料中的資訊可能已過時或錯誤。我們必須支持模型始終使用上下文來回答,或者如果它無法從上下文中回答,則回答「我不知道」。 - **對查詢的回應不相關。** LLM 可能會使用您提供的所有資訊來產生回應,但這並不意味著它回答了使用者的問題。重要的是,模型必須堅持使用者的原始問題,而不是迷失在大量資訊中。 - **相似上下文導致的冗餘響應。**當我們攝取具有相似資訊的多個文件時,檢索器有可能會獲得多個幾乎相同的資訊區塊。這可能會導致法學碩士在其回復中多次重複相同的訊息。 如何避免這些問題呢? ---------- 為了避免這些問題,簡單的 RAG 管道可能還不夠。我們需要建立一個更先進、更複雜的RAG系統。存在經過測試的技術來解決我們提出的問題。我們可以將它們合併到 RAG 管道中,以提高 RAG 應用程式的效能。 另一個需要解決的重要問題是,為了改進您的 RAG 應用程式,您需要能夠測量和評估整個過程。你無法改進你無法衡量的東西。另外,當您進行評估時,您可能會發現基本的 RAG 設定足以滿足您的用例,並且不需要使其過於複雜。畢竟,即使是非常基本的 RAG 實施也可以極大地改進您的 LLM 支援的應用程式。 在以後的文章中,我將更詳細地解釋先進的 RAG 技術,這將幫助我們避免常見問題並將我們的 RAG 應用程式提升到新的水平。 --- 原文出處:https://dev.to/rogiia/how-to-build-a-basic-rag-app-h9p

提升你的技能

介紹 -- 學習如何成為更好的開發人員需要不斷提升自己的技能。一個人如何學習成長並成為更好的開發人員?讓我們探討幾個總體上適用於大多數開發人員的想法。程式碼範例全部採用 C# 語言,之所以選擇它們是因為它們對於大多數開發人員來說並不常見,並且是在內部完成的。 腳步 -- - [Pluralsight](https://www.pluralsight.com/)是一個付費網站,提供數百門 C# 課程。首先使用他們的人工智慧評估,這將引導您走上正確的道路。許多課程也有自己的評估。 Pluralsight 讓您輕鬆地向高評價作者學習,並透過任何裝置(例如筆記型電腦、手機或平板電腦)存取課程。 Pluralsite 提供免費試用,有時還會在購買訂閱時提供折扣。 - 使用[微軟學習](https://learn.microsoft.com/en-us/training/)。無論您是剛開始職業生涯,還是經驗豐富的專業人士,我們的自我導向方法都可以幫助您更快、更有信心地按照自己的步調實現目標。透過互動式模組和路徑培養技能或向講師學習。以您的方式學習和成長。 - 花時間閱讀 Microsoft 文件,例如,閱讀[C# 程式的一般結構、類型運算子和表達式語句、](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/)各種[類別](https://learn.microsoft.com/en-us/dotnet/api/system.string?view=net-6.0)[、物件導向程式設計](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/tutorials/oop)等等。 - 在學習過程中,嘗試使用控制台或單元測試專案使事情變得簡單,換句話說,將後端學習與前端使用者介面學習分開。 - 在您感覺舒服的某個時間點,確定一個簡單的專案,在編碼之前寫出任務,然後編寫程式碼,而不是同時思考和編碼。新手等級的思考和編碼簡直就是一場即將發生的災難。 - 在網路上尋找資訊並找到解決方案時,不要簡單地複製和貼上,檢查程式碼,在使用所述程式碼之前先嘗試弄清楚它在做什麼。 - 了解如何在 Visual Studio 中使用 GitHub 來備份和版本程式碼。假設您編寫了程式碼並破壞了它,透過 GitHub 儲存庫中的正確版本控制,您可以還原變更並還原程式碼。 - 使用 .NET Framework Core 6 或 .NET Core Framework 8 而不是 .NET Framework classic,因為使用 .NET Core 有更多好處 - 如果學習使用資料,請從 SQL-Server Express 開始並安裝 SSMS (SQL-Server Management Studio),同時學習使用 Entity Framework Core。 - 充分了解學習任何語言時慢速學習比快速學習好,而且沒有人知道這一切。 ![了解如何使用除錯器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xp3uj4nuhzx7sple8tad.png) 加速學習的工具 ------- Microsoft Visual Studio 絕對是最好的 IDE(整合開發環境),它具有以下專案可以增加學習並節省編碼時間。 - 適用於 Visual Studio 和 SSMS 的 Red Gate [SQL 提示符](https://www.red-gate.com/products/sql-prompt/) - 高級 IntelliSense 風格的程式碼完成 - 重構 SQL 程式碼 - SSMS SQL 歷史記錄 - 以及更多 - Jetbrains [ReSharper](https://www.jetbrains.com/resharper/)這是一個非常寶貴的 Visual Studio 擴充功能。 - [EF Power Tools](https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools)可輕鬆對 EF Core 的 SQL-Server 資料庫進行逆向工程 深入了解程式碼基礎知識 ----------- 掌握基礎知識後,尋找有助於成長為更好的開發人員的程式碼範例。 一個可能的途徑是使用[Microsoft Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/) (EF Core) 或使用[Dapper](https://www.learndapper.com/)等資料提供者來處理資料庫。 還有其他處理資料的方法,但 EF Core 和 Dapper 在效能和易於學習方面是最好的。 在 Web 上尋找程式碼範例時,請確保它們適用於您的專案的 .NET Framework,因為 .NET Framework 4.8 程式碼範例與 .NET Core 8 Framework 有很大不同。 Microsoft 每年都會為 EF Core 建立程式碼範例,但在許多情況下,其結構可能不適合缺乏經驗的開發人員學習,因此 Karen Payne 採用 EF Core 8 程式碼範例並建立了以下[文章](https://dev.to/karenpayneoregon/microsoft-entity-framework-core-8-samples-3dj8)/[儲存庫,在大多數情況下,這些文章/儲存庫](https://github.com/karenpayneoregon/ef-code-8-samples)很容易學習。 第 1 課 - SQL-Server 計算列 ---------------------- ### EF 核心版本 {% cta https://github.com/karenpayneoregon/sql-basics/tree/master/EF\_CoreBirthdaysCompulatedColumns %} 範例專案 {% endcta %} [計算列](https://learn.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-ver16)是虛擬列,除非該列被標記為 PERSISTED,否則不會實際儲存在表中。計算列表達式可以使用其他欄位中的資料來計算其所屬列的值。您可以使用 SQL Server Management Studio (SSMS) 或 Transact-SQL (T-SQL) 為 SQL Server 中的計算列指定運算式。 完整文章,請參閱[SQL-Server:使用 Ef Core 計算列](https://dev.to/karenpayneoregon/sql-server-computed-columns-with-ef-core-3h8d) 但在這裡,我們將使用 EF Core 和 Dapper 從開始和演練使用情況建立一個計算列。 原文來自以下 Stackoverflow貼[文](https://stackoverflow.com/questions/9/how-do-i-calculate-someones-age-based-on-a-datetime-type-birthday?page=2&tab=modifieddesc#tab-top)。取得出生日期和目前日期,用出生日期減去目前日期,然後除以 10,000。 在 SSMS(SQL Server Management Studio)中 請注意,在程式碼範例中,完整資料庫存在於腳本資料夾下的專案 EF\_CoreBirthdaysCompulatedColumns 中。在執行腳本之前,請在 SSMS 中建立資料庫,然後執行腳本來建立表格並填入資料。 另請注意,在程式碼範例中,連接字串使用 NuGet 套件[ConsoleConfigurationLibrary](https://www.nuget.org/packages/ConsoleConfigurationLibrary/)駐留在 appsettings.json 中。 **表結構** ![表結構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06sfbbb9i4ru5203l1nx.png) **SQL** ![選擇語句](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bqiabe7j0a4nvez1yqa.png) 將聲明分開。 - 使用日期分隔符號格式化兩個日期並將每個日期轉換為整數。 - 從目前日期減去出生日期,括號很重要。 - 將以上除以 10,000 即可得到年齡。 **結果** ![SELECT 的結果](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvzc25dc1ojr4arurnqy.png) 現在為名為 YearsOld 的表建立一個 nvarchar 類型的新欄位,並將此語句放入計算列屬性中,然後儲存變更。 ``` (CAST(FORMAT(GETDATE(), 'yyyyMMdd') AS INTEGER) - CAST(FORMAT(BirthDate, 'yyyyMMdd') AS INTEGER)) / 10000 ``` ![ssms中的表設計](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvwq73hel66uumzbixh5.png) - 建立一個新的 C# 控制台專案。 - 新增[Microsoft.EntityFrameworkCore.SqlServer](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.SqlServer/8.0.0?_src=template)的依賴項 - 安裝 Visual Studio 擴充[EF Power Tools](https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools) 。若要了解如何使用 EF Power Tools,請觀看作者提供的以下[影片](https://www.youtube.com/watch?v=uph-AGyOd8c)。新增[完整文件](https://github.com/ErikEJ/EFCorePowerTools/wiki/Reverse-Engineering)。 使用 EF Power Tools 後,將產生以下類別。 代表 SQL-Server 資料庫表的模型。 ``` public partial class BirthDays { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateOnly? BirthDate { get; set; } public int? YearsOld { get; set; } } ``` 所謂的[DbContext](https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.dbcontext?view=entity-framework-6.2.0)和與資料庫互動的配置。 注意 YearsOld 上的[HasCompulatedColumnSql](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.relationalpropertybuilderextensions.hascomputedcolumnsql?view=efcore-8.0) ,這是我們的計算列。 ``` public partial class Context : DbContext { public Context() { } public Context(DbContextOptions<Context> options) : base(options) { } public virtual DbSet<BirthDays> BirthDays { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) #warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263. => optionsBuilder.UseSqlServer(DataConnections.Instance.MainConnection); protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<BirthDays>(entity => { entity.Property(e => e.YearsOld).HasComputedColumnSql("((CONVERT([int],format(getdate(),'yyyyMMdd'))-CONVERT([int],format([BirthDate],'yyyyMMdd')))/(10000))", false); }); OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); } ``` > **筆記** > 執行上述工作有兩個陣營:資料庫優先或程式碼優先。對於剛開始使用 EF Core 的人來說,資料庫優先是最好的路徑。 要查看資料, [Spectre.Console](https://spectreconsole.net/)用於建立一個漂亮的表格。 ``` internal partial class Program { static async Task Main(string[] args) { await Setup(); var table = CreateTable(); await using (var context = new Context()) { var list = await context.BirthDays.ToListAsync(); foreach (var bd in list) { table.AddRow( bd.Id.ToString(), bd.FirstName, bd.LastName, bd.BirthDate.ToString(), bd.YearsOld.ToString()); } AnsiConsole.Write(table); } ExitPrompt(); } public static Table CreateTable() { var table = new Table() .AddColumn("[b]Id[/]") .AddColumn("[b]First[/]") .AddColumn("[b]Last[/]") .AddColumn("[b]Birth date[/]") .AddColumn("[b]Age[/]") .Alignment(Justify.Left) .BorderColor(Color.LightSlateGrey); return table; } } ``` ![上述程式碼的截圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i60dye7au7fve08y1wfu.png) 為了獲取我們的資料,一行程式碼用於實例化 EF Core,一行程式碼用於讀取資料。 EF Core 也非常適合關聯式資料庫,請參閱以下[儲存庫](https://github.com/karenpayneoregon/ef-code-8-samples)。 有關記錄 EF Core 產生的 SQL,請參閱下列[專案](https://github.com/karenpayneoregon/ef-code-8-samples/tree/master/DualContextsApp),該專案也展示如何使用兩個不同的 SQL-Server 實例。 ### 短小精悍的版本 {% cta https://github.com/karenpayneoregon/sql-basics/tree/master/DapperBirthdaysCompulatedColumns %} 範例專案 {% endcta %} 與 EF Core 不同,使用 Dapper,開發人員在 SSMS 中編寫 SQL 語句並將有效語句新增到程式碼中。有關 Dapper 的更多訊息,請參閱我的[系列](https://dev.to/karenpayneoregon/series/25270)。 這裡 SQL 儲存在唯讀字串中,替代方法是將 SQL(或任何語句)儲存在預存程序中。 ![學習編寫正確的 SQL](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uyn1awyunv0pvbhtgzy1.png) ``` internal class SqlStatements { public static string GetBirthdays => """ SELECT Id ,FirstName ,LastName ,BirthDate ,YearsOld FROM BirthDaysDatabase.dbo.BirthDays """; } ``` 讀取資料的程式碼。 ``` internal class DapperOperations { private IDbConnection _cn; public DapperOperations() { _cn = new SqlConnection(DataConnections.Instance.MainConnection); SqlMapper.AddTypeHandler(new SqlDateOnlyTypeHandler()); SqlMapper.AddTypeHandler(new SqlTimeOnlyTypeHandler()); } public async Task<List<BirthDays>> GetBirthdaysAsync() { return (await _cn.QueryAsync<BirthDays>(SqlStatements.GetBirthdays)).AsList(); } } ``` 在類別構造函數中 1. 使用[Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient/5.2.1?_src=template) NuGet 套件建立連線。 1. 使用[kp.Dapper.Handlers](https://www.nuget.org/packages/kp.Dapper.Handlers/1.0.0?_src=template) NuGet 套件為 Dapper 新增理解 DateOnly 類型的功能。 讀取資料是一個單行資料,表示我們需要非同步生日列表。 ``` public async Task<List<BirthDays>> GetBirthdaysAsync() { return (await _cn.QueryAsync<BirthDays>(SqlStatements.GetBirthdays)).AsList(); } ``` 回到 Program.cs,除了建立 Dapper 類別的實例並呼叫方法之外,程式碼與 EF Core 相同。 ``` internal partial class Program { static async Task Main(string[] args) { await Setup(); var table = CreateTable(); var operations = new DapperOperations(); var list = await operations.GetBirthdaysAsync(); foreach (var bd in list) { table.AddRow( bd.Id.ToString(), bd.FirstName, bd.LastName, bd.BirthDate.ToString(), bd.YearsOld.ToString()); } AnsiConsole.Write(table); ExitPrompt(); } public static Table CreateTable() { var table = new Table() .AddColumn("[b]Id[/]") .AddColumn("[b]First[/]") .AddColumn("[b]Last[/]") .AddColumn("[b]Birth date[/]") .AddColumn("[b]Age[/]") .Alignment(Justify.Left) .BorderColor(Color.LightSlateGrey); return table; } } ``` ### 計算列的摘要 並未詳細介紹程式碼的每個方面,這意味著在專案中採用技術之前需要花時間剖析程式碼以及使用了哪些 NuGet 套件。也可以考慮透過[Visual Studio 偵錯器](https://learn.microsoft.com/en-us/visualstudio/get-started/csharp/tutorial-debugger?view=vs-2022)執行程式碼。 偵錯是許多新手開發人員忽略的事情,也是 Visual Studio 的最佳功能之一。學習如何除錯並不需要花費大量時間。 第 2 課 - 重構程式碼 ------------- 許多人認為編碼的主要任務是讓程式碼正常工作,然後返回並重構程式碼。從個人經驗來看,這種情況一般不會發生。這就是開發人員需要在工作專案之外磨練技能的原因。 ![從未停止學習](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ju4889uewhkpfrfmp0w5.png) ### 實施例1 開發人員被要求將字串拆分為大寫字符,並將字串放在前面。 例如,給定 ThisIsATest,輸出將是 This Is A Test。開發者在網路上搜尋並找到以下內容。 ``` public static class StringExtensions { private static readonly Regex CamelCaseRegex = new(@"([A-Z][a-z]+)"); /// <summary> /// KarenPayne => Karen Payne /// </summary> [DebuggerStepThrough] public static string SplitCamelCase(this string sender) => string.Join(" ", CamelCaseRegex.Matches(sender) .Select(m => m.Value)); } ``` 這是可行的,但有一個更好的版本,在下面的範例中是由GitHub Copilot 編寫的,並且是第二次迭代,這意味著第一次copilot 被問到時,它提供了一個未經優化的解決方案,因為問題是如何提出的。 ``` [DebuggerStepThrough] public static string SplitCamelCase(this string input) { if (string.IsNullOrEmpty(input)) { return input; } Span<char> result = stackalloc char[input.Length * 2]; var resultIndex = 0; for (var index = 0; index < input.Length; index++) { var currentChar = input[index]; if (index > 0 && char.IsUpper(currentChar)) { result[resultIndex++] = ' '; } result[resultIndex++] = currentChar; } return result[..resultIndex].ToString(); } ``` ![更少的程式碼並不總是最好的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i8u0zjrr2qjgot6tmav8.png) 等一下,第二個版本的程式碼多了很多,這個版本怎麼會更好呢?新手和經驗豐富的開發人員都有一種心態,就是程式碼行數越少越好,也許是為了提高可讀性。當然,開發人員應該始終努力編寫可讀的程式碼,但多行程式碼也可以輕鬆閱讀。 如何編寫可讀的程式碼。 - 使用有意義的變數名稱,例如在 for 語句中使用索引而不是 i 或使用firstName 而不是fName。 - 折疊程式碼而不是一行,如下所示 ``` public static class CheckedListBoxExtensions { public static List<T> CheckedList<T>(this CheckedListBox sender) => sender.Items.Cast<T>() .Where((_, index) => sender.GetItemChecked(index)) .Select(item => item) .ToList(); } ``` 而不是 ``` public static class CheckedListBoxExtensions { public static List<T> CheckedList<T>(this CheckedListBox sender) => sender.Items.Cast<T>().Where((_, index) => sender.GetItemChecked(index)).Select(item => item).ToList(); } ``` 下一步 --- 這裡有一些想法,即使是許多經驗豐富的開發人員也會避免,而不是你! - [泛型](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics) - [介面](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface) - 建立公共庫 - [JSON 序列化與反序列化](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/overview) 概括 -- 這些是成為更好的開發人員的更多技巧中的一些。實現這一目標的唯一方法是在專案之外不斷學習。 如果您的老闆或團隊領導者沒有提供時間來學習新技能,您可以每週花一兩個小時來學習和成長。 --- 原文出處:https://dev.to/karenpayneoregon/push-your-skills-2pho

Kubernetes 編譯失敗:然後正式機掛掉的情況!

我從來都不是一個大賭徒。過去我可能會下一個小賭注來為超級盃增添趣味,但我並沒有那麼投入,但這並不是什麼瘋狂的事情。真正投入資金需要一定程度的確定性,而我在任何體育賽事、選舉結果或未來預測中都很少有這種確定性。科技領域的確定性非常少。工作保障並不是既定的,產業趨勢潮起潮落,你每天使用的[工具](https://glasskube.dev/guides/kubectl/)和技術堆疊很可能會隨著時間的推移而不斷發展。儘管充滿了不確定性,但還是有一些東西你可以安全地押注,但在某些時候,**你會遭遇中斷。** ![賭場](https://media1.giphy.com/media/26tneF8wxg0H4NrC8/200.webp?cid=ecf05e4725b5vpix4vj3x0ajz06gb8rehvx96kjva729y9nu&ep=v1_gifs_search&rid=200.webp&ct=g) 從事任何時間的 Kubernetes 工程師都可以證明這個現實。在這種情況下,害怕失敗或執行艱鉅的任務來確保[100% 可用性](https://andrewmatveychuk.com/why-99-99-uptime-or-sla-is-bad/)是沒有意義的,如果有任何[錯誤](https://www.amazon.com/Black-Box-Thinking-People-Mistakes-But/dp/1591848229)和中斷應該被視為學習機會,這對於任何渴望成熟並提供高品質的環境來說都是必要的邪惡以可靠的方式提供服務。 有效處理和消化中斷的最佳方法是系統地進行[事後分析](https://www.atlassian.com/incident-management/postmortem/reports)。事實證明,這些是我們尋找模式並綜合中斷所提供的經驗教訓的最敏銳的工具。關於 Kubernetes 叢集故障中常見的模式主題,出現了一些模式。 ![reddit-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xml8lmgs8g9e36624td5.png) DNS、網路和預設資源分配是一些關鍵的罪魁禍首。 ![reddit-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ijimseogd4nn43k5sni.png) 在這篇文章中,我們將分析其中的一些事後分析,並盡力吸收其他人經過艱苦的努力才學到的東西。 故障嚴重程度等級 -------- 並非每次中斷都會產生相同的影響,因此我建立了一個非常科學的分類系統來了解每次 Kubernetes 中斷的影響: **🤷 - 有點糟糕:**微不足道的 Kubernetes 故障 **😅 - 非正式機,但仍然令人煩惱:**我們沒有影響任何客戶,但我們學到了教訓 **🤬 - 休士頓,我們在生產中遇到了問題:**客戶受到影響,職業選擇受到質疑。 ![你被開除了](https://media1.giphy.com/media/xT4uQ7N8UNsoeFAjVS/200.webp?cid=790b76115lk6lg7hzua5e4qexoocj2f0sltdsw5l4ggfcsln&ep=v1_gifs_search&rid=200.webp&ct=g) --- 在我忘記之前,讓我感謝[Glasskube](https://github.com/glasskube/glasskube)讓我花時間建立這樣的內容。如果這是您第一次聽說我們,我們正在努力`Package Manager for Kubernetes` 。 如果您願意支持我們完成這項任務,我們將不勝感激 [⭐️ GitHub 上的 Star Glasskube 🙏](https://github.com/glasskube/glasskube) [![感謝您的支持](https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHZxc3Nxbjdyem9kY24xd3k5M3EwY2Q1dmQ3OTA0aTh4c3cycmpkdyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/l3q2wJsC23ikJg9xe/200.webp)](https://github.com/glasskube/glasskube) --- 有點糟糕🤷 ----- 如果你不能笑自己,你還能笑誰? ### 叢集和節點群組 第一個故事來自您謙虛的記者,他最近使用 AWS 控制台啟動了一個測試 Kubernetes 集群,以快速驗證概念。我已經有一段時間沒有使用 EKSCTL 或某種形式的基礎設施即程式碼定義檔來建立叢集了。 因此,我登入並存取 EKS 控制台,命名我的 Kubernetes 集群,然後點擊「建立」。然後,我按照 CLI 說明配置 kubeconfig 檔案並透過終端連接到我新建立的叢集。 由於渴望測試最新版本的 Glasskube,我將其安裝在叢集中。然而,令我驚訝的是 Pod 的安排時間如此之長。現在回想起來,我很尷尬地承認我花了多長時間才意識到我沒有配置節點組,難怪 Pod 沒有被調度。 ![不為所動](https://media4.giphy.com/media/v1.Y2lkPTc5MGI3NjExNm9mdzVweWc1cDljdjM3MWpmeTRqcm1sejltZXhzZmZlYzFtMmNtMSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/c5FhF1waAJ5wk/giphy.webp) ### 打電話給消防隊,我忘了加入資源限制。 另一個真實的故事來自另一位Glasskube 成員,由於在本地Minikube 集群中安裝了許多元件(GitLab),他的本地筆記型電腦超載了,筆記型電腦幾乎在他的辦公桌上燒了一個洞,這是一個很好的提醒,要使用資源限制和請求 ![筆記型電腦起火](https://media0.giphy.com/media/dbtDDSvWErdf2/200.webp?cid=ecf05e4775sy7d66ores8c10w1hrw77311mm7m323lkkkqym&ep=v1_gifs_search&rid=200.webp&ct=g) 非正式機,但仍然很煩人😅 ----------- 轉向一些真實的事件,幸運的是這些事件僅限於不會影響付費客戶的叢集。 ### 事件#1:Venafi 的 Webhooks 無回應 [Venafi](https://venafi.com/)是機器身分的控制平面,最近被[Cyberark](https://www.cyberark.com/)收購,Cyberark 在 OPA 方面存在一些問題。完整的屍檢[在這裡](https://venafi.com/blog/gke-webhook-outage/)。 ![快點](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5mnqgz5998ynmk3rpipg.png) > **影響:**間歇性 API 伺服器逾時導致節點不健康。 > **涉及:**開放策略代理、節點準備 **逐場比賽** 在計劃的叢集升級期間,儘管有警告並且之前升級成功,但主升級失敗,導致 API 伺服器逾時和節點不穩定。**根本原因是 ConfigMap 更新期間逾時**,由無回應的[OPA](https://www.openpolicyagent.org/) Webhook 觸發。刪除 webhook 恢復了服務,此後他們將其限制在特定的命名空間,加入了 OPA 的活性探針,並更新了文件。 他們強調需要 API 回應時間警報、工作負載探測,並可能使用 Helm 圖表進行部署,以避免將來出現類似問題。他們繼續監控功能的改進並透過 Flightdeck 服務提供見解。 **學習內容:** - 需要對 API 伺服器回應時間發出警報。 - 增加所有工作負載所需的`livenessProbes` 。 - 使用套件管理進行更精細的配置。 > 💡 這事件凸顯了[Glasskube](https://github.com/glasskube/glasskube)旨在解決的用例之一。雖然 Glasskube 尚不支援 OPA 運算符,但我們相信透過強大的 Kubernetes 套件管理器可以避免這個問題。 Glasskube 可輕鬆配置關鍵功能,協助升級,並將 GitOps 方法應用於套件操作員管理,包括回溯和特定命名空間分配。[在這裡](https://github.com/glasskube/glasskube)嘗試一下。 ### 事件#2:當加密貨幣礦工潛入時 [JW Player](https://jwplayer.com/)成為比特幣挖礦惡意軟體的目標,請[在此處](https://medium.com/jw-player-engineering/how-a-cryptocurrency-miner-made-its-way-onto-our-internal-kubernetes-clusters-9b09c4704205)查看完整的事後分析。 ![JW-玩家](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/do39mgvqt5e01ndnk9aw.png) > **影響:**非生產集群被比特幣礦工滲透 > **涉及:** Root存取利用 **逐場比賽** 在 Datadog 向 JW Player 的 DevOps 團隊發出其臨時和開發環境中的平均負載較高的警報後,JW Player 的 DevOps 團隊在其 Kubernetes 叢集上發現了一個加密貨幣挖礦程式。**初步調查發現,有一個gcc進程佔用了100%的CPU,經檢查發現該進程是監控工具Weave Scope發起的礦機**。該礦工利用了面向公眾的 Weave Scope 負載平衡器,允許在容器中執行命令。 立即採取的行動包括停止 Weave Scope、隔離受影響的節點並將其輪換出去。該事件導致 CPU 使用率較高,但沒有服務中斷或資料外洩。該團隊將 Kubernetes 覆蓋的手動安全群組編輯確定為關鍵問題,並強調需要採取適當的配置實踐來防止此類漏洞。 **學習內容:** - 監控負載並不是檢測叢集問題的最佳方法。 - 可能需要`falcon`或`sysdig`等工具 - 需要更強大的 Docker 映像和容器掃描。 - 架構的某些區域需要重新檢視。 - 需要更多的跨團隊資料共享和溝通。 ### 事件 #3:GKE 耗盡 IP 位址 ![愛情假期](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2e5fh4u5u8hxwse1az0s.png) > **影響:**高節點數叢集耗盡了 IP 位址,無法調度新的 Pod。 > **涉及:**子網路、每個節點的預設 IP 分配 **逐場比賽** 當一名團隊成員報告其應用程式的部署時間異常長時,就發生了一起事件。他們很快就發現,雖然一些新部署的 Pod 正在提供流量,但其餘的 Pod 仍處於`pending`狀態。**分析顯示`FailedScheduling`警告顯示資源不足。**儘管部署了叢集自動縮放器,但問題仍然存在,因為他們看到了令人震驚的**「0/256 個節點可用」**訊息。進一步檢查發現,GKE為每個節點預先分配了110個IP,導致IP消耗意外高。了解這一點後,他們調整了每個節點的 Pod 分配,將整體 IP 使用量減少了 30%。此外,他們還探索了子網擴展和增加節點大小等選項以緩解 IP 耗盡,最終優化節點池實例大小以更好地利用資源。 **學習內容:** - 了解 GKE 設定的預設值的重要性。 - [子網路擴充功能](https://cloud.google.com/vpc/docs/create-modify-vpc-networks#expand-subnet)是一個可供您使用的實用工具(儘管關於次要範圍的文件不多)。 - 增加節點池執行個體大小也可以完成這項工作(每個節點執行更多 Pod,然後需要更少的節點)。 休士頓,我們的生產遇到問題了🤬 --------------- 這些類型的中斷**會讓 SRE 徹夜難眠**,當客戶受到影響並且業務價值岌岌可危時,這些都是最重要的經驗教訓和英雄的誕生地。 ### 事件 #1 Skyscanner 只需要幾個字元就可以關閉他們的網站 在這裡我們看到,針對彈性進行了最佳化的架構仍然容易因為一行程式碼而故障。完整的屍檢[在這裡](https://medium.com/@SkyscannerEng/how-a-couple-of-characters-brought-down-our-site-356ccaf1fbc3)。 ![天巡](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zma05ic4v2m88e05y797.png) > **影響:**全球 Skyscanner 網站和行動應用程式無法存取 > **涉及:** IaC清單 **逐場比賽** 2021 年 8 月,由於無意中更改了基礎設施配置系統中的根文件,Skyscanner 面臨持續四個多小時的全球中斷。**由於缺少`{{ }}` ,這項變更意外地觸發了全球範圍內關鍵微服務的刪除**,導致網站和行動應用程式無法存取。 ![致命線](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ohytkjb4v3p1c0ekvno.png) 他們迅速解決了這個問題,利用 GitOps 恢復配置並確定關鍵服務的優先順序。 **學習內容:** - 不要進行全域配置部署。 - 需要更徹底的「最壞情況」規劃。 - 驗證備份/復原過程。 - 保持操作手冊最新。 - 超越自動化的潛力。 ### 事件#2 Monzo Bank 的 linkerd 慘敗 英國數位[銀行](https://monzo.com/)艱難地發現了 Kubernetes 的一個嚴重錯誤。完整的屍檢[在這裡](https://community.monzo.com/t/resolved-current-account-payments-may-fail-major-outage-27-10-2017/26296/95)。 ![蒙佐銀行](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tjblle4py5mifmv1s1e.png) > **影響:**預付卡和新活期帳戶下降約1.5小時 > **涉及:** Linkerd、kube-apiserver、etcd **逐場比賽:** 此事件始於例行部署導致支付處理失敗。嘗試回滾變更未成功,導致內部中斷聲明。工程師發現並重新啟動了不健康的`linkerd`實例,但`kube-apiserver`的配置問題導致新的`linkerd`實例無法啟動,從而將中斷升級為整個平台故障。**根本原因可追溯到 Kubernetes 和 etcd 中的錯誤,該錯誤是由最近的叢集重新配置觸發的。**這導致`linkerd`無法接收網路更新,再加上 Kubernetes 和 linkerd 之間的相容性問題。該事件已透過更新 linkerd 並刪除空的 Kubernetes 服務得到解決。 **學習內容:** - 需要新版本的 Linkerd。 - k8s bug 需要修復(現已[修復](https://github.com/kubernetes/kubernetes/issues/47131))。 - 改進執行狀況檢查、儀表板和警報。 - 改進程序以改善停電期間的內部溝通。 ### 事件 #3 Redis 操作員丟了一個曲線球 Palark 是一家 DevOps 服務供應商,曾試圖保護其 Redis 集群,但最終卻後悔了。[這](https://blog.palark.com/failure-with-redis-operator-and-redis-data-analysis-tools/)是完整的移植剖析 ![帕拉克](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09fk9z0exq8006orscwm.png) > **影響:**加入副本後的生產 Redis 資料 > **涉及:** Redis算子 **逐場比賽** 他們遇到了一個涉及眾所周知的記憶體鍵值儲存 Redis 的事件,他們透過[Redis Operator](https://github.com/spotahome/redis-operator)安裝該儲存來執行 Redis 故障轉移。最初部署了一個 Redis 副本,後來擴展到兩個副本以增強資料庫可靠性。**然而,這個看似微小的變化在部署過程中被證明是災難性的,導致資料遺失。**該事件揭露了 Redis Operator 中的缺陷,主要是其`readiness probe` ,引發了意外的主升級和隨後的資料破壞。使用`Redis-memory-analyzer`等工具進行進一步分析,揭示了對資料庫大小和元素的洞察,從而幫助開發人員優化資料庫和應用程式程式碼,以防止未來發生事件。 **學習內容:** - 使用 Kubernetes Operator 時要非常小心(確保它們成熟且經過充分測試)。 - 他們發現了與 Redis Operators 就緒性探測相關的關鍵錯誤,該錯誤使副本橫向擴展容易導致資料遺失(已[修復](https://github.com/spotahome/redis-operator/releases/tag/v1.0.0-rc.3))。 - `Redis-memory-analyzer`是Redis資料庫故障排除的最佳工具。 事件 #4 Datadog 的多區域噩夢 -------------------- 多個[Datadog](https://www.datadoghq.com/)區域宕機`systemd-networkd`強制刪除了容器網路介面 (CNI) 插件管理的路由。完整的屍檢 [在這裡](https://www.datadoghq.com/blog/2023-03-08-multiregion-infrastructure-connectivity-issue/)。 ![資料狗](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcobaticca62tpuk7nwq.png) > **影響:**多個地區的使用者無法存取 API 和平台。 > **涉及:** systemd更新、Cilium **逐場比賽** 從 2023 年 3 月 8 日開始,Datadog 經歷了一次影響多個區域的重大中斷,導致用戶無法存取平台、API 和監視器,並影響資料提取。這個問題是由眾多虛擬機器上的 systemd 自動安全性更新觸發的,導致網路中斷,導致數萬個節點離線。恢復涉及恢復運算能力、解決特定於服務的問題以及為客戶提供持續更新。**根本原因被確定為允許自動更新的錯誤配置,該更新已停用。** **學習內容:** - 更強大的混沌測試。 - 需要在停電期間改善與客戶的溝通 - 停電期間狀態頁面不充分。 - 自動更新本身就有風險,應謹慎使用。 ### 事件#5 Reddit 的圓周率日中斷 Reddit 遭受了快速有機成長的後果,他們面臨著殘酷的現實,即許多關鍵的 Kubernetes 叢集不標準化,很容易出現中斷,[這裡是](https://www.reddit.com/r/RedditEng/comments/11xx5o0/you_broke_reddit_the_piday_outage/)完整的 Pi-Day 中斷事後分析。 ![紅迪網](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5s1vi0fdjwzps01hgnpj.png) > **影響:**嚴重的跨平台中斷持續 314 分鐘 > **涉及:** Calico、Kubernetes版本更新 **逐場比賽** 2023 年 3 月,Reddit 經歷了一次持續 314 分鐘的嚴重中斷,巧合的是,這發生在圓周率日。嘗試存取網站的用戶要么遇到不堪重負的 Snoo 吉祥物、錯誤訊息,要么看到空的主頁。這次中斷是由 Kubernetes 1.23 升級到 1.24 引發的,這引入了一個以前從未見過的微妙問題。工程團隊近年來一直強調可用性的改進,但發現自己處於一個充滿挑戰的境地,回滾雖然有風險,但卻成為了最佳選擇。 在復原過程中,由於 TLS 憑證和 AWS 容量限制不匹配,因此出現了一些複雜情況,但團隊設法克服了這些挑戰並重新建立了高可用性控制平面。 **進一步調查顯示,根本原因與 Calico 過時的路由反射器配置有關**,由於刪除了「master」節點標籤,此配置與 Kubernetes 1.24 不相容。 **學習內容:** - 出於測試目的改進預生產集群的重要性。 - 需要改進 Kubernetes 元件生命週期管理工具。 - 需要更同質的環境。 - 此外,還需要增加他們的 IaC 和內部技術文件。 結論 -- 正如您所看到的,熵定律很容易適用於 Kubernetes 叢集——破壞它們比讓它們滿意要容易得多。升級、部署、擴展和部署等變更通常會引發中斷,因此您可能傾向於盡量減少中斷。但對於那些努力引領細分市場並滿足不斷變化的客戶需求的組織來說,這不是一個選擇。我們所能期望的最好的結果就是從實踐中學習,並從失敗中學習。從好的方面來說,科技業普遍樂於學習,並能坦然面對失敗( [在大多數情況下](https://apnews.com/article/cellular-att-verizon-tmobile-outage-02d8dfd93019e79e5e2edbeed08ee450))。事實上,許多大型企業公開分享事後總結供更大的社區學習,這是一種最佳實踐,其基礎是這樣的假設:故障和中斷是「何時」而不是「是否」的問題。保護我們自己的最好方法就是在他們過去後向他們學習。 > 🫵 那你呢?您是否經歷過任何特別困難的停電並從另一邊講述了這個故事?如果是這樣,請在下面的評論中分享您的經驗。我相信我們很多人都想聽聽這個。 --- 幫助我們製作更多這樣的內容! -------------- 在[Glasskube,](https://github.com/glasskube/glasskube)我們在此類內容上投入了大量精力,並`next generation package manager for Kubernetes` 。 如果您從我們所做的工作中獲得價值,我們將不勝感激 [⭐️ GitHub 上的 Star Glasskube 🙏](https://github.com/glasskube/glasskube) [![github 上的明星](https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExdnhibjU3MnRqeDVydm83ZXNiMHF1YXQ3NW9iMTEwcjFuZmhqcG8ydSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/XaFhFM2lVRoVa/giphy.gif)](https://github.com/glasskube/glasskube) --- 原文出處:https://dev.to/glasskube/kubernetes-fail-compilation-but-they-keep-getting-worse-12n2

進階 SQL:掌握查詢最佳化和複雜連接

大家好,願神的平安、憐憫、祝福臨到你們 SQL(結構化查詢語言)是管理和操作關係資料庫的重要工具。雖然基本的 SQL 技能可以幫助您入門,但高級 SQL 技術可以大大增強您處理複雜查詢和優化資料庫效能的能力。本文深入探討高階 SQL 主題,重點在於複雜的查詢最佳化策略、高階聯結類型以及`SELECT`語句的複雜性。 ### 進階查詢最佳化技術 最佳化 SQL 查詢是資料庫管理員和開發人員的關鍵技能。進階查詢最佳化超越了基本索引和查詢重構,還包括一系列複雜的技術。 #### 1. 查詢執行計劃 了解查詢的執行計劃對於最佳化至關重要。執行計劃顯示 SQL 引擎如何執行查詢,揭示潛在的瓶頸。 - **EXPLAIN** : `EXPLAIN`語句提供對查詢執行方式的深入了解,使您能夠辨識效率低下的情況。 ``` EXPLAIN SELECT column1, column2 FROM table_name WHERE condition; ``` - **ANALYZE** : `ANALYZE`語句與`EXPLAIN`結合使用,執行查詢並提供執行時統計訊息,從而更深入地了解查詢性能。 ``` EXPLAIN ANALYZE SELECT column1, column2 FROM table_name WHERE condition; ``` #### 2. 子查詢最佳化 子查詢有時可以替換為更有效率的聯結或`WITH`子句(通用表表達式)。 - **用連接替換子查詢**: ``` -- Subquery SELECT * FROM table1 WHERE column1 IN (SELECT column1 FROM table2); -- Equivalent Join SELECT table1.* FROM table1 INNER JOIN table2 ON table1.column1 = table2.column1; ``` - **使用通用表格表達式 (CTE)** : ``` WITH CTE AS ( SELECT column1, column2 FROM table_name WHERE condition ) SELECT * FROM CTE WHERE another_condition; ``` #### 3. 索引策略 進階索引策略包括使用複合索引和覆蓋索引。 - **複合索引**:包含多個欄位的索引可以加快對這些欄位進行篩選的查詢速度。 ``` CREATE INDEX idx_composite ON table_name (column1, column2); ``` - **覆蓋索引**:包含查詢檢索到的所有列的索引可以顯著提高效能。 ``` CREATE INDEX idx_covering ON table_name (column1, column2, column3); ``` #### 4. 分區 將大表劃分為更小、更易於管理的部分可以透過限制掃描的資料量來提高查詢效能。 - **範圍劃分**: ``` CREATE TABLE orders ( order_id INT, order_date DATE, ... ) PARTITION BY RANGE (order_date) ( PARTITION p0 VALUES LESS THAN ('2024-01-01'), PARTITION p1 VALUES LESS THAN ('2025-01-01'), ... ); ``` - **哈希分區**:根據雜湊函數將資料分佈在指定數量的分區上,提供均勻分佈。 ``` CREATE TABLE users ( user_id INT, username VARCHAR(255), ... ) PARTITION BY HASH(user_id) PARTITIONS 4; ``` - **清單分區**:根據值清單將資料劃分為多個分區。 ``` CREATE TABLE sales ( sale_id INT, region VARCHAR(255), ... ) PARTITION BY LIST (region) ( PARTITION p0 VALUES IN ('North', 'South'), PARTITION p1 VALUES IN ('East', 'West') ); ``` #### 5. 物化視圖 物化視圖實體儲存查詢結果,並且可以定期刷新,從而提高頻繁執行的複雜查詢的效能。 - **建立物化視圖**: ``` CREATE MATERIALIZED VIEW sales_summary AS SELECT region, SUM(sales_amount) AS total_sales FROM sales GROUP BY region; ``` - **刷新物化視圖**: ``` REFRESH MATERIALIZED VIEW sales_summary; ``` 筆記: --- 在 MySQL 中,存在視圖,但物化視圖本身並不存在。 MySQL支援標準視圖,這些視圖是儲存查詢定義並在查詢時動態產生結果集的虛擬表。但是,它沒有對物化視圖的內建支持,物化視圖物理儲存結果集。 ### MySQL 中的視圖 #### 建立視圖 您可以使用`CREATE VIEW`語句在 MySQL 中建立視圖。這是一個例子: ``` CREATE VIEW ActiveCustomers AS SELECT CustomerID, CustomerName, ContactName, Country FROM Customers WHERE Status = 'Active'; ``` 這將建立一個名為`ActiveCustomers`的視圖,其中僅包含`Customers`表中的活動客戶。查詢此視圖如下所示: ``` SELECT * FROM ActiveCustomers; ``` #### 更新視圖 可以使用`CREATE OR REPLACE VIEW`語句更新檢視: ``` CREATE OR REPLACE VIEW ActiveCustomers AS SELECT CustomerID, CustomerName, ContactName, Country FROM Customers WHERE Status = 'Active' AND Country = 'USA'; ``` 這會將`ActiveCustomers`檢視修改為僅包含來自美國的活躍客戶。 #### 刪除視圖 您可以使用`DROP VIEW`語句刪除檢視: ``` DROP VIEW ActiveCustomers; ``` #### MySQL 中的物化視圖 MySQL 本身不支援物化視圖,但有一些變通方法可以實現類似的功能。這裡有幾種方法: ##### 1. 使用表格和計劃更新 一種常見的方法是建立一個表來儲存查詢結果並使用計劃事件(cron 作業)或觸發器定期更新它。 ##### 建立表 首先,建立一個表格來儲存結果: ``` CREATE TABLE MaterializedActiveCustomers AS SELECT CustomerID, CustomerName, ContactName, Country FROM Customers WHERE Status = 'Active'; ``` ##### 更新表格 使用計劃事件定期更新表。此範例使用 MySQL 事件每小時更新一次表格: ``` CREATE EVENT UpdateMaterializedActiveCustomers ON SCHEDULE EVERY 1 HOUR DO BEGIN DELETE FROM MaterializedActiveCustomers; INSERT INTO MaterializedActiveCustomers SELECT CustomerID, CustomerName, ContactName, Country FROM Customers WHERE Status = 'Active'; END; ``` 此事件每小時都會清除`MaterializedActiveCustomers`表並使用最新的活躍客戶重新填充。 ##### 2. 使用觸發器 另一種方法是使用觸發器使表與基底表保持同步。然而,這可能會變得複雜,對於大型資料集可能效率不高。 #### 使用觸發器的範例 ##### 建立表 首先,建立表: ``` CREATE TABLE MaterializedActiveCustomers AS SELECT CustomerID, CustomerName, ContactName, Country FROM Customers WHERE Status = 'Active'; ``` ##### 建立觸發器 建立觸發器以保持物化表更新: ``` DELIMITER // CREATE TRIGGER after_customer_insert AFTER INSERT ON Customers FOR EACH ROW BEGIN IF NEW.Status = 'Active' THEN INSERT INTO MaterializedActiveCustomers (CustomerID, CustomerName, ContactName, Country) VALUES (NEW.CustomerID, NEW.CustomerName, NEW.ContactName, NEW.Country); END IF; END // CREATE TRIGGER after_customer_update AFTER UPDATE ON Customers FOR EACH ROW BEGIN IF OLD.Status = 'Active' AND NEW.Status != 'Active' THEN DELETE FROM MaterializedActiveCustomers WHERE CustomerID = OLD.CustomerID; ELSEIF NEW.Status = 'Active' THEN REPLACE INTO MaterializedActiveCustomers (CustomerID, CustomerName, ContactName, Country) VALUES (NEW.CustomerID, NEW.CustomerName, NEW.ContactName, NEW.Country); END IF; END // CREATE TRIGGER after_customer_delete AFTER DELETE ON Customers FOR EACH ROW BEGIN DELETE FROM MaterializedActiveCustomers WHERE CustomerID = OLD.CustomerID; END // DELIMITER ; ``` 這些觸發器將確保`MaterializedActiveCustomers`表隨著`Customers`表的變更而保持更新。 #### 結論 雖然 MySQL 支援視圖,但它本身不支援物化視圖。但是,您可以使用具有計劃更新或觸發器的表來實現類似的功能。透過使用這些解決方法,您可以維護可以快速查詢的預先計算的結果,類似於其他資料庫系統中的物化視圖。 ### 高級連接類型和技術 連接是 SQL 的基礎,它允許您組合多個表中的資料。除了基本連接之外,高級連接技術還可以處理更複雜的需求。 #### 1. 自加入 自連接是一種常規連接,但表與自身連接。它對於比較同一表中的行很有用。 ``` SELECT a.employee_id, a.name, b.name AS manager_name FROM employees a INNER JOIN employees b ON a.manager_id = b.employee_id; ``` #### 2. 橫向連接 `LATERAL`連線允許子查詢在`FROM`子句中引用前面表格中的欄位。這對於更複雜的查詢很有用。 ``` SELECT a.*, b.* FROM table1 a LEFT JOIN LATERAL ( SELECT * FROM table2 b WHERE b.column1 = a.column1 ORDER BY b.column2 DESC LIMIT 1 ) b ON TRUE; ``` #### 3. 使用 COALESCE 進行完全外部連接 處理需要完整外連接但希望避免結果中出現`NULL`值的情況。 ``` SELECT COALESCE(a.column1, b.column1) AS column1, a.column2, b.column2 FROM table1 a FULL OUTER JOIN table2 b ON a.column1 = b.column1; ``` #### 4. 進階連接過濾器 在連接中應用複雜的條件以更精確地過濾結果。 ``` SELECT a.column1, b.column2 FROM table1 a INNER JOIN table2 b ON a.column1 = b.column1 AND a.date_column BETWEEN '2023-01-01' AND '2023-12-31'; ``` #### 5. 反連接和半連接 這些連接分別對於排除和包含查詢很有用。 - **反連接**:從左表中檢索右表中沒有匹配行的行。 ``` SELECT a.* FROM table1 a LEFT JOIN table2 b ON a.column1 = b.column1 WHERE b.column1 IS NULL; ``` - **半連接**:從左表中檢索右表中存在一個或多個匹配項的行。 ``` SELECT a.* FROM table1 a WHERE EXISTS (SELECT 1 FROM table2 b WHERE a.column1 = b.column1); ``` ### 高級`SELECT`語句 `SELECT`語句可以透過進階功能進行擴展,以滿足複雜的資料檢索要求。 #### 1. 視窗函數 視窗函數對與目前行相關的一組表行執行計算,提供強大的分析功能。 - **行號**: ``` SELECT column1, column2, ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column2) AS row_num FROM table_name; ``` - **執行總計**: ``` SELECT column1, column2, SUM(column2) OVER (ORDER BY column1) AS running_total FROM table_name; ``` - **排行**: ``` SELECT column1, column2, RANK() OVER (PARTITION BY column1 ORDER BY column2) AS rank FROM table_name; ``` - **移動平均線**: ``` SELECT column1, column2, AVG(column2) OVER (PARTITION BY column1 ORDER BY column2 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_avg FROM table_name; ``` #### 2. 遞迴 CTE 遞歸 CTE 可讓您執行遞歸查詢,這對於分層資料很有用。 ``` WITH RECURSIVE cte AS ( SELECT column1, column2 FROM table_name WHERE condition UNION ALL SELECT t.column1, t.column2 FROM table_name t INNER JOIN cte ON t.column1 = cte.column1 ) SELECT * FROM cte; ``` #### 3.JSON函數 現代 SQL 資料庫通常包含處理 JSON 資料的函數,可讓您儲存和查詢 JSON 文件。 - **提取 JSON 值**: ``` SELECT json_column->>'key' AS value FROM table_name; ``` - **聚合成 JSON** : ``` SELECT json_agg(row_to_json(t)) FROM (SELECT column1, column2 FROM table_name) t; ``` - **更新 JSON 資料**: ``` UPDATE table_name SET json_column = jsonb_set(json_column, '{key}', '"new_value"', true) WHERE condition; ``` #### 4. 資料透視 透視將行轉換為列,提供了一種重新組織和匯總資料以用於報告目的的方法。 - **使用 CASE 語句進行透視**: ``` SELECT category, SUM(CASE WHEN year = 2021 THEN sales ELSE 0 END) AS sales_2021, SUM(CASE WHEN year = 2022 THEN sales ELSE 0 END) AS sales_2022 FROM sales_data GROUP BY category; ``` #### 5.動態SQL 動態 SQL 允許在執行時間建立和執行 SQL 語句,為需要動態產生的複雜查詢提供靈活性。 - **執行動態SQL** : ``` EXECUTE 'SELECT * FROM ' || table_name || ' WHERE ' || condition; ``` - **使用準備好的語句**: ``` PREPARE stmt AS SELECT * FROM table_name WHERE column1 = $1; EXECUTE stmt('value'); ``` ### 結論 掌握進階 SQL 技術可以讓您最佳化資料庫效能並輕鬆處理複雜查詢。了解執行計劃、利用高階聯結、利用複雜的`SELECT`語句、實作進階索引策略是精通 SQL 的關鍵。透過將這些技術整合到您的工作流程中,您可以顯著提高資料庫驅動應用程式的效率和可擴展性。 進階 SQL 技能可讓您處理複雜的資料操作和檢索任務,確保您的應用程式能夠有效率且有效地處理大量資料。無論您是資料庫管理員、開發人員還是資料分析師,這些進階 SQL 技術都將使您能夠充分利用關聯式資料庫,從而獲得更好的效能、更深入的見解和更強大的應用程式。 --- 原文出處:https://dev.to/bilelsalemdev/advanced-sql-mastering-query-optimization-and-complex-joins-4gph

使用 ToolJet + Gemini API 建構 SQL 查詢產生器

介紹 -- 本教學將引導您完成使用[ToolJet](https://github.com/ToolJet/ToolJet) (一種低程式碼視覺化應用程式建構器)和 Gemini API(一種強大的自然語言處理 API)來建立 AI 驅動的 SQL 查詢產生器的過程。由此產生的應用程式將使用戶能夠以簡單的英語輸入提示,然後將其轉換為可執行的 SQL 查詢。我們將使用 ToolJet 的視覺化應用程式建構器來建立使用者友善的 UI,並使用 ToolJet 的低程式碼查詢建構器將其連接到 Gemini API 端點。 --- 先決條件: ----- - [**ToolJet**](https://github.com/ToolJet/ToolJet):一個開源、低程式碼的商業應用程式建構器。[註冊](https://www.tooljet.com/signup)免費的 ToolJet 雲端帳號或使用 Docker[在本機上執行 ToolJet](https://docs.tooljet.com/docs/setup/try-tooljet/) 。 - **Gemini API 金鑰**:使用您現有的 Google 憑證登入[Google AI Studio](https://aistudio.google.com/app/apikey) 。在 AI Studio 介面中,您將能夠找到並複製您的 API 金鑰。 以下是我們最終應用程式的快速預覽: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/amxvh44ue5inhf9cyoh8.png) --- 製作我們的使用者介面 ---------- - 登入您的[ToolJet 帳號](https://app.tooljet.com/)。導覽至 ToolJet 儀表板,然後按一下左上角的**「建立新應用程式」**按鈕。 ToolJet 隨附 45 多個內建元件。這將讓我們立即設定我們的用戶界面。 - 將右側元件庫中的**Container**元件拖曳到畫布上。適當調整**Container**元件的高度和寬度。 - 同樣,將**圖示**和兩個**文字**元件拖曳到容器內。我們將使用這兩個**文字**元件作為標題和署名文字。 - 選擇**Icon**元件,導覽至右側的屬性面板,然後選擇其**Icon**屬性下的資料庫圖示。 - 根據您的喜好變更**圖示**和**文字**元件的顏色。在這裡,我們將使用藍色陰影(十六進位程式碼:#4A7EE2)。 - 適當地變更**文字**元件的字體大小和內容。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tezdxuu2q9zq5fpazaj.png) - 將**Dropdown**元件拖曳到容器中。我們將使用此元件在**Gemini** API 提供的模型之間進行選擇。 - 將此元件重新命名為*modelDropdown* 。重新命名元件將有助於在開發過程中快速存取其資料。 - 同樣,將三個**Textarea**元件拖曳到容器中。我們將使用這些元件作為資料模式輸入、文字查詢輸入以及第三個元件來顯示產生的 SQL 查詢。 - 將三個**Textarea**元件分別重新命名為*databaseSchemaInput* 、 *textPrompt*和*generatedQuery* 。 - 適當調整**Textarea**元件的高度和寬度。 - 在**「屬性」**部分下,清除預設值輸入並輸入適當的佔位符文字。 - 拖放另一個**文字**元件。我們將使用它作為產生的查詢**Textarea**元件的標籤。適當變更顏色、字體大小和內容。 - 讓我們加入最後一個元件,拖放一個**Button**元件。我們將使用它來觸發 SQL 查詢產生。適當改變顏色、大小和內容。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l1p7ggxevjpxwgviumtc.png) --- 建立查詢 ---- ToolJet 允許使用其 REST API 查詢功能連接到第三方 API。我們將使用它來將我們的 UI 與 Gemini API 端點整合。我們將建立兩個單獨的 REST API 查詢: 1. 第一個查詢將取得**Gemini** API 提供的所有 AI 模型的清單。 2. 第二個查詢是將使用者輸入傳送到**Gemini** API 端點的 POST 請求。它將傳回基於這些輸入產生的 SQL 查詢。 我們也將利用 ToolJet 的**工作空間常數**來安全地儲存我們的**Gemini** API 金鑰。工作區常數在伺服器端解析。這確保了常數的實際值不會與網路有效負載一起發送;相反,伺服器解析這些值,從而確保它們免受客戶端暴露。 - 若要建立**工作空間常數**,請點選左上角的 ToolJet 標誌。從下拉清單中,選擇**工作空間常數**。 - 點選**建立新常數**按鈕。將名稱設為*GEMINI\_API\_KEY*並在值輸入中輸入您的**Gemini** API 金鑰。 - 點選**新增常數**按鈕。現在,該常數將在我們的工作區中可用,並且可以使用`{{constants.GEMINI_API_KEY}}`進行存取。 - 導航回您的應用程式並開啟查詢管理器。 - 點擊**+ 新增**按鈕並選擇**REST API**選項。 - 將查詢重新命名為*getModels* 。 - 將請求方法保留為**GET**並將以下 URL 貼到 URL 輸入中。這是 Gemini API 端點,它將傳回我們可用的模型。 ``` https://generativelanguage.googleapis.com/v1beta/models?key={{constants.GEMINI_API_KEY}} ``` - 若要確保每次載入應用程式時都執行查詢,請啟用**“在應用程式載入時執行此查詢?”**切換。 - 同樣,建立另一個查詢並將其命名為*getSqlQuery* 。 - 在**請求**參數中,從下拉清單中選擇**POST**作為方法,然後貼上以下 URL。 ``` https://generativelanguage.googleapis.com/v1beta/{{components.modelDropdown.value}}:generateContent?key={{constants.GEMINI_API_KEY}} ``` - 導航到*getSqlQuery*的 Body 部分。切換到**原始 JSON**並輸入以下程式碼: ``` {{ `{  "contents": [{    "parts": [{      "text": "Data Schema: ${components.databaseSchemaInput.value.replaceAll("\n"," ")}, Text Prompt: Write a standard SQL query that will ${components.textPrompt.value.replaceAll("\n"," ")}. Return with correct formatting but without any code highlighting and any backticks"     },],   },], }` }} ``` --- 將 UI 與查詢集成 ---------- 現在我們已經成功建立了 UI 和查詢,下一步就是整合它們。 - 選擇**“屬性”**部分下的**“按鈕”**元件,然後按一下**“新事件處理程序”**按鈕以建立新事件。 - 選擇**On click**作為**事件**,**執行查詢**作為**操作**,然後選擇*getSqlQuery*作為**查詢**。 - 選擇**「屬性」**部分下的**下拉**元件,然後為選項值和標籤輸入以下程式碼。 **選項值**: ``` {{queries.getModels.data.models.map(item => item.name)}} ``` **選項標籤**: ``` {{queries.getModels.data.models.map(item => item.displayName)}} ``` - 選擇**Properties**部分下的*generatedQuery* **Textarea**元件,然後為預設值輸入輸入以下程式碼。 **預設值**: ``` {{queries.getSqlQuery.data.candidates[0].content.parts[0].text}} ``` 我們的人工智慧驅動的 SQL 查詢產生器已經完成。讓我們提供一些範例資料來測試一下。 資料庫結構定義: ``` Orders (id, product_id, address, customer_name, is_paid) Products (id, quantity, moq) Customers (id, name, email, phone, addresses) ``` 文字提示/查詢: ``` find all the prepaid orders from a customer named Alex JR ``` **預期輸出:** ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1rjpn413n42hejyu2ofc.png) --- 結論 -- 恭喜您使用 ToolJet 和 Gemini API 成功建置了人工智慧驅動的 SQL 查詢產生器。現在您可以用簡單的英文輸入提示,然後將其準確地轉換為可執行的 SQL 語句。 要了解和探索有關 ToolJet 的更多訊息,請查看[ToolJet 文件](https://docs.tooljet.com/docs/)或聯絡我們並在[Slack](https://join.slack.com/t/tooljet/shared_invite/zt-2ij7t3rzo-qV7WTUTyDVQkwVxTlpxQqw)上發布您的問題。 --- 原文出處:https://dev.to/tooljet/building-a-sql-query-generator-using-tooljet-gemini-api-4lo9

系統設計面試的 10 個微服務架構挑戰

*揭露:這篇文章包含附屬連結;如果您透過本文中提供的不同連結購買產品或服務,我可能會獲得補償。* [![微服務架構最佳實踐](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rkibz6xn6xqibepgu9cz.png)](https://bit.ly/3P3eqMN) image\_credit - [ByteByteGo](https://bit.ly/3P3eqMN) 朋友們大家好,如果您正在準備系統設計面試,那麼您也必須準備微服務架構。這是許多面試官最喜歡的架構,它提供了大量的材料來拷問你。 毫無疑問,微服務架構透過將單體應用程式分解為更小的、鬆散耦合的服務,徹底改變了軟體開發。 過去,我分享過幾篇系統設計面試文章,例如[API 網關與負載平衡器](https://medium.com/javarevisited/difference-between-api-gateway-and-load-balancer-in-microservices-8c8b552a024)、 [正向代理與反向代理](https://medium.com/javarevisited/difference-between-forward-proxy-and-reverse-proxy-in-system-design-da05c1f5f6ad)以及[常見的系統設計問題](https://medium.com/javarevisited/7-system-design-problems-to-crack-software-engineering-interviews-in-2023-13a518467c3e),在本文中我們將討論微服務架構的挑戰。 它也是程式設計師必須了解的[基本系統設計主題或概念](https://medium.com/javarevisited/top-10-system-design-concepts-every-programmer-should-learn-54375d8557a6)之一。 雖然微服務方法承諾提高可擴展性、靈活性和更快的開發週期,但它也帶來了一系列挑戰,這對開發人員來說非常重要,不僅要了解這些挑戰,還要有效地解決這些挑戰。 雖然有很多文章討論微服務最佳實踐,但很少有文章闡述它們提供的好處以及它們解決的挑戰。 在本文中,我們將探討開發人員在使用微服務時所面臨的十大主要挑戰,並學習克服這些挑戰的有效策略。 順便說一句,如果您正在準備系統設計面試並想深入學習系統設計,那麼您還可以查看[ByteByteGo](https://bit.ly/3P3eqMN) 、 [Design Guru](https://bit.ly/3pMiO8g) 、 [Exponent](https://bit.ly/3cNF0vw) 、 [Educative](https://bit.ly/3Mnh6UR)和[Udemy](https://bit.ly/3vFNPid)等網站,它們有許多很棒的系統設計課程 此外,對各種微服務模式(例如服務發現、CQRS 和 Saga)的紮實了解對於解決我們將在本文中討論的許多挑戰大有幫助,就此而言,這裡有一個來自[DesignGuru.io](https://designgurus.org/link/84Y9hP)的漂亮圖表,說明如何微服務中的服務發現工作,我們將在本文後面使用此模式 [![微服務中的服務發現](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e0ke14if9uyunsszj0lu.png)](https://www.designgurus.io/course/grokking-microservices-design-patterns?aff=84Y9hP) --- 微服務開發的10大挑戰及解決方案 ---------------- 以下列出了使用微服務架構建立應用程式時可能面臨的主要挑戰 ### 1. 服務溝通挑戰 如果您在現實世界的微服務架構中工作過,那麼您可能知道微服務嚴重依賴服務間通信,隨著服務數量的增長,這可能會成為一個挑戰。 由於每個服務都有自己的 API 和協議,管理通訊變得複雜。 為了解決這個問題,請採用 REST、訊息佇列和事件驅動架構等通訊模式。此外,請考慮使用[**API 閘道**](https://medium.com/javarevisited/difference-between-api-gateway-and-load-balancer-in-microservices-8c8b552a024)來集中通訊邏輯並處理橫切問題。 ![微服務架構挑戰](https://miro.medium.com/v2/resize:fit:609/1*I4tv-pLx4ccaaBTFzquzsA.png) --- ### 2. 資料管理挑戰 由於架構的分散性,跨微服務的資料管理可能會很複雜。不一致的資料模型和維護資料一致性帶來了困難。 為了解決這個問題,您可以實施多語言持久性策略,使用適合每個服務特定需求的資料庫。 您還應該利用事件來源和[**CQRS(命令查詢職責分離)**](https://javarevisited.substack.com/p/how-cqrs-pattern-works-in-microservices)等技術來維護資料完整性以及讀寫操作的分離。 [![微服務的資料管理挑戰](https://miro.medium.com/v2/resize:fit:609/1*XKdhM77EN6isbz5eeH2K9A.jpeg)](https://medium.com/javarevisited/what-is-cqrs-command-and-query-responsibility-segregation-pattern-7b1b38514edd) --- ### 3. 分散式追蹤與監控挑戰 由於請求跨越多個服務,監控和除錯微服務應用程式變得非常具有挑戰性。傳統的監控工具可能無法提供所需的可見度。 為了解決這個問題,您應該整合 Jaeger 或 Zipkin 等分散式追蹤系統來追蹤跨服務的請求。 您還可以使用集中式日誌記錄和監控解決方案來聚合和分析來自各種服務的日誌和指標,有助於早期發現問題。 對於開發人員來說,微服務中的偵錯問題是處理和了解 Zipkin 等追蹤系統真正運作的最大挑戰之一。 ![微服務架構中的分散式追蹤與監控挑戰](https://miro.medium.com/v2/resize:fit:609/1*MRyM0qiMBljjsfnoemCAeg.png) --- ### 4. 服務編排與編排挑戰 微服務可以集中編排,也可以以分散的方式編排。這兩種方法都有其挑戰。 編排服務可能會導致單點故障,而編排可能會導致追蹤流程的複雜性和難度增加。 在這種情況下,您應該努力尋求平衡,對關鍵工作流程採用編排,並對可以獨立運作的服務進行編排。 ![微服務中的服務編排與編排挑戰](https://miro.medium.com/v2/resize:fit:609/1*O_AFZvulWl5ZZYE1BG7hYQ.png) --- ### 5. 部署與 DevOps 挑戰 微服務的部署涉及管理多個服務實例並確保不同環境之間的相容性。使用傳統方式部署微服務幾乎是不可能的。 使用 Docker 等工具的容器化和使用[Kubernetes 的](https://medium.com/javarevisited/top-15-online-courses-to-learn-docker-kubernetes-and-aws-for-fullstack-developers-and-devops-d8cc4f16e773)編排可以幫助標準化部署流程,事實上,如果您想要穩健的話,它們是必須的。 您還應該採用**DevOps 實踐**並自動化部署管道,以確保微服務的一致性和快速部署。 ![微服務中的部署與 DevOps 挑戰](https://miro.medium.com/v2/resize:fit:609/1*Bxoxd1eCCtPyJzMtLeFVYw.jpeg) --- ### 6. 跨服務挑戰的測試 測試微服務一點也不容易,由於其互動的複雜性,它需要一個全面的策略。 傳統的單元測試可能還不夠。 為了解決這個問題,您可以結合整合測試、合約測試和端到端測試來驗證服務互動和資料流。 您還應該實施一個強大的[CI/CD 管道](https://javarevisited.blogspot.com/2018/09/top-5-jenkins-courses-for-java-and-DevOps-Programmers.html),以在整個微服務生態系統中自動進行測試。 ![應對微服務中的服務挑戰](https://miro.medium.com/v2/resize:fit:609/1*fKlBw13XQ5RyazLXl2MIIQ.png) --- ### 7. 安全和存取控制挑戰 微服務可能會暴露大量端點,從而增加潛在的攻擊面。大多數時候,您甚至不會意識到這一點,但不用擔心,幾乎所有大型組織都有龐大的安全團隊,高薪來騷擾您。 就您而言,您應該確保跨服務的安全性,管理身分驗證和授權以及保護傳輸中的資料會帶來重大挑戰。 採用零信任安全模型,實作[OAuth2](https://medium.com/javarevisited/5-best-online-courses-to-learn-oauth-2-0-and-jwt-in-2023-719fd63c834)和[JWT(JSON Web Tokens)](https://medium.com/javarevisited/difference-between-jwt-oauth-and-saml-for-authentication-and-authorization-in-web-apps-75b412754127)等 API 安全標準,並採用具有強大存取控制機制的 API 閘道。 ![微服務中的安全性和存取控制挑戰](https://miro.medium.com/v2/resize:fit:609/1*GP0lglBapQS929e3Paf1ng.png) 積分 --- superTokens --- ### 8. 可擴展性和資源分配 可擴展性是微服務的核心承諾,也是許多公司放棄單體應用而轉向微服務的主要驅動力之一,但它需要仔細規劃。 某些服務可能會遇到比其他服務更重的負載,導致資源分配挑戰。 您應該利用容器**編排平台**和工具(例如 K8)根據需求動態分配資源。 您也可以根據 CPU 使用率或請求率等指標實施自動擴展,以確保最佳的資源使用率。 [![微服務中的可擴展性和資源分配挑戰](https://miro.medium.com/v2/resize:fit:609/1*JH4N7C199Gl3dhc2sh3xHQ.png)](https://medium.com/javarevisited/difference-between-horizontal-scalability-vs-vertical-scalability-67455efc91c) --- ### 9. 版本控制和相容性挑戰 隨著微服務的獨立發展,保持向後和向前相容性變得至關重要。 不相容的更改可能會破壞整個系統。 作為經驗豐富的開發人員或技術主管,您應該在程式碼層級和通訊協定中實作 API 的版本控制。 您也可以利用語意版本控制來清楚傳達相容性期望。逐步淘汰舊版本,同時為遷移提供足夠的支援和文件。 ![微服務中的版本控制和相容性挑戰](https://miro.medium.com/v2/resize:fit:609/1*xezI58bd7nSSjW35u2XfGQ.jpeg) --- ### 10.組織複雜性和溝通挑戰 微服務架構可以反映組織的結構,從而導致溝通和協作方面的挑戰,例如不同的團隊管理不同的微服務。 從事不同服務的跨職能團隊需要協調他們的工作,這一點很重要。 作為經驗豐富的專家,您應該透過定期會議、分享文件和促進資訊交換的工具來培養溝通和協作的文化。 ![組織複雜性與溝通挑戰](https://miro.medium.com/v2/resize:fit:609/1*6-rMCG_PZDnt1Z1RWvPWyg.jpeg) --- ### 系統設計訪談資源: 而且,這裡列出了最佳系統設計書籍、線上課程和練習網站,您可以查看這些內容,以便更好地為系統設計面試做好準備。這些課程中的大多數也回答了我在這裡分享的問題。 1. [**DesignGuru 的 Grokking 系統設計課程**](https://bit.ly/3pMiO8g):一個互動式學習平台,提供實作練習和真實場景,以增強您的系統設計技能。 2. [**《系統設計面試》作者:Alex Xu**](https://amzn.to/3nU2Mbp) :這本書深入探討了系統設計概念、策略和麵試準備技巧。 3. Martin Kleppmann 的[**「設計資料密集型應用程式」**](https://amzn.to/3nXKaas) :綜合指南,涵蓋了設計可擴展且可靠的系統的原則和實踐。 4. [LeetCode 系統設計 標籤](https://leetcode.com/explore/learn/card/system-design):LeetCode 是一個受歡迎的技術面試準備平台。 LeetCode 上的系統設計標籤包含各種練習問題。 5. GitHub 上的[**「系統設計入門」**](https://bit.ly/3bSaBfC) :精選的資源列表,包括文章、書籍和影片,可幫助您準備系統設計面試。 6. [**Educative 的系統設計課程**](https://bit.ly/3Mnh6UR):一個互動式學習平台,提供實作練習和真實場景,以增強您的系統設計技能。 7. **高可擴展性部落格**:該部落格包含有關高流量網站和可擴展系統架構的文章和案例研究。 8. **[YouTube 頻道](https://medium.com/javarevisited/top-8-youtube-channels-for-system-design-interview-preparation-970d103ea18d)**:請參閱「Gaurav Sen」和「Tech Dummies」等頻道,以取得有關係統設計概念和麵試準備的富有洞察力的影片。 9. [**ByteByteGo**](https://bit.ly/3P3eqMN) :Alex Xu 的一本現場書籍和課程,用於系統設計面試準備。它包含《系統設計訪談》第一捲和第二卷的所有內容,並將隨即將推出的第三卷進行更新。 10. [**Exponent**](https://bit.ly/3cNF0vw) :一個專為面試準備的網站,特別是針對亞馬遜和谷歌等 FAANG 公司,他們還有很棒的系統設計課程和許多其他材料,可以幫助您破解 FAANG 面試。 而且,這是一個很好的系統設計面試備忘錄,可以快速修改基本的系統設計概念: [![系統設計面試備忘錄](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ooidxg5v3bopt7a6uf4.png)](https://bit.ly/3cNF0vw) image\_credit - [tryExponent](https://bit.ly/3cNF0vw) ### 結論 這就是關於微服務架構挑戰以及如何應對這些挑戰的全部內容。微服務架構在可擴展性、靈活性和更快的開發方面提供了顯著的優勢。 然而,這些優勢也伴隨著開發人員必須有效應對的一系列獨特挑戰。 透過在服務通訊、資料管理、監控、測試、安全性等方面採用最佳實踐,團隊可以克服這些挑戰並釋放微服務的全部潛力。 隨著軟體開發環境的不斷發展,解決這些挑戰對於成功實施微服務仍然至關重要 雖然我寫這篇文章是為了準備系統設計面試,但對於使用微服務並希望獲得更多控制和更好組織的經驗豐富的開發人員來說,它同樣有價值。 微服務開發一切順利! **獎金**\\ 正如承諾的,這是給你的獎金,一本免費的書。我剛剛找到一本新的免費書籍來學習分散式系統設計,您也可以在 Microsoft 上閱讀它 --- [https://info.microsoft.com/rs/157-GQE-382/images/EN-CNTNT -eBook-設計分散式系統.pdf](https://info.microsoft.com/rs/157-GQE-382/images/EN-CNTNT-eBook-DesigningDistributedSystems.pdf) [![關於分散式系統的免費書籍](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fso5r1wv8x95i74nz6p89.png)](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fso5r1wv8x95i74nz6p89.png) --- 原文出處:https://dev.to/somadevtoo/10-microservices-architecture-challenges-for-system-design-interviews-6g0

您把 Git commit 訊息寫對了嗎?

當涉及版本控制時,Git 是一個非常有效的工具。然而,像任何其他工具一樣,您必須以正確的方式使用它才能充分利用它。您需要考慮不同的方面。本文重點介紹如何按照常規提交規範編寫有效的 Git 提交訊息。它概述了幫助您建立清晰、資訊豐富且標準化的提交訊息的基礎知識。 好的提交訊息是什麼樣的? ------------ 發送訊息的目的是為了溝通。為了使溝通有效,接收者必須清楚地了解訊息發送者試圖告訴他們什麼。因此,您需要提供上下文和足夠的資訊。基於此,一個好的提交訊息應該傳達以下內容: **1. 類型(必填)** - `fix:` – 適用於修復錯誤的操作。 - `feat:` – 當您新增功能時適用。 - `BREAKING CHANGE:` - 當您引入以下變更時適用 可能需要更新程式的某些方面或 升級以避免中斷。例如,替換已棄用的 如果有的話,新資源可能會破壞功能 沒有向後相容性。您也可以指示中斷 使用符號“!”進行更改緊接在類型(或範圍,如果 可用的)。 例子; '壯舉(身份驗證)! - `docs:` – 適用於文件。 其他包括*test:、chore:、refactor:、build:、style:*等。因此,提前了解詳細資訊很重要。 **2.範圍(可選)** 儘管提供範圍是可選的,但為了清晰起見,最好將其包含在內。範圍指定了受變更影響的程式碼庫部分,從而幫助讀者了解變更的上下文。這對於有許多貢獻者的大型專案尤其有用。它使協作變得更加容易。 **3. 說明(必填)** 這是您描述您所做的事情的部分。保持簡潔、開門見山。確保以命令式形式編寫。例如,不應編寫“新增身份驗證機制”,而應編寫“新增身份驗證機制”。這將提高自動產生的變更日誌和發行說明的可讀性。 **4. 本體(可選)** 您可以在此處提供有關您已實施的內容的更多資訊。使用空白行將正文與描述分開。 **5.頁尾(可選)** 如果您想在頁腳中包含任何元資料,請執行此操作。例如,如果您所做的變更解決了先前提出的問題,您可以透過引用參考號在此指出。例子; '**修復#003** ' 您也可以在頁腳中包含審閱者的姓名。 請記住,在給出描述之前,範圍後面應該跟有冒號和空格。您還應該記住,BREAKING CHANGE 在包含在頁腳中時區分大小寫,因此應以大寫形式書寫。 例子 -- - Chore(Art\_func):將變數“Empty”更改為“empty” 將變數名稱從“Empty”更改為“empty”以保持一致 命名約定。 - 修復(資料庫)! 修改架構以僅容納結構化資料。關閉所有 其他類型的資料。 - 壯舉:增加對黑暗模式的支援。 對於長訊息,請使用文字編輯器執行 ``` git commit ``` 沒有 -m 標誌。這將打開一個編輯器,您可以在其中編寫詳細的提交訊息。對於較短的訊息,您可以僅包含 -m 標誌並使用終端機而不是編輯器。 ``` git commit -m "subject" -m "body" ``` 使用多個 -m 標誌可以透過分隔主題、正文和頁腳來幫助您正確格式化訊息。 結論 -- 編寫提交訊息應該達到預期目的。為了使其清晰且資訊豐富,建議您至少包含所做更改的類型和描述。按照傳統方法維護一個良好的程式碼庫,可以支援各種流程的協作和自動化。有關詳細訊息,請務必閱讀[常規提交](https://www.conventionalcommits.org/en/v1.0.0/)指南。 --- 原文出處:https://dev.to/otienorabin/are-you-writing-your-git-commit-messages-properly-54cl