🔍 搜尋結果:1

🔍 搜尋結果:1

使用 Gemini AI + ToolJet 建置 SQL 報表產生器

介紹 -- 本教學將引導您完成使用[ToolJet](https://github.com/ToolJet/ToolJet) (一種低程式碼視覺化應用程式產生器)和 Gemini API(一種強大的自然語言處理 API)建立 AI 驅動的 SQL 自訂報告產生器的過程。由此產生的應用程式將使用戶能夠以簡單的英語輸入請求,然後將其翻譯成自訂報告。我們將使用 ToolJet 的視覺化應用程式建構器來建立使用者友善的 UI,並使用 ToolJet 的低程式碼查詢建構器將其連接到 Gemini API 端點和我們的資料來源。最終產品將使用戶能夠預覽生成的報告並以 PDF、Excel 或 CSV 格式下載。 --- 先決條件: ----- - **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 金鑰。 以下是我們最終應用程式的快速預覽: ![SQL 報表產生器預覽](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xb7brsesfnu9t6ny61h1.png) --- 登入您的[ToolJet 帳號](https://app.tooljet.com/)。導覽至 ToolJet 儀表板,然後按一下左上角的「建立新應用程式」按鈕。 ToolJet 隨附 45 多個內建元件。這將讓我們立即設定我們的用戶界面。 建立我們的使用者介面 ---------- - 將右側元件庫中的**Container**元件拖曳到畫布上。適當調整**Container**元件的高度和寬度。 - 同樣,將**圖示**和三個**文字**元件拖曳到容器內。我們將使用這些**文字**元件作為標題和標籤文字。 - 對於**「圖示」**元件,導航到右側的屬性面板,然後在**「圖示」**屬性下選擇適當的圖示。 - 根據您的喜好變更**圖示**和**文字**元件的顏色。 - 適當地變更**文字**元件的字體大小和內容。 - 將**Textarea**元件拖曳到容器內。我們將使用此元件作為文字查詢的輸入。 - 將**Textarea**元件重新命名為*textPrompt* 。 - 接下來,將**表格**元件拖曳到容器上。我們將使用此元件來顯示報告的預覽。**表**元件內建了下載顯示資料的功能。這將使我們能夠下載產生的 PDF、Excel 或 CSV 格式的報告。 - 現在讓我們新增一個啟動報告產生過程的**Button**元件。適當改變顏色、大小和內容。 ![SQL 報表產生器 UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5b1r1pifxlt1kj74xe0e.png) --- 設定查詢 ---- 除了內建的資料庫和資料來源之外,ToolJet 還允許您連接到各種外部資料來源,包括資料庫、外部 API 和服務。在本教程中,我們將使用 ToolJet 的內建 PostgreSQL 範例資料來源。我們將設定的查詢也適用於外部 PostgreSQL 資料來源。 我們也將使用 REST API 查詢功能來連接**Gemini** API 端點。 - 在查詢面板中,按一下 + 新增按鈕並選擇範例資料來源選項。 - 將查詢重新命名為 getDatabaseSchema。 - 在下拉清單中,選擇 SQL 模式並輸入以下程式碼。這將獲取資料庫中的所有表名及其列名。 ``` SELECT table_name, string_agg(column_name, ', ') AS columns FROM information_schema.columns WHERE table_schema = 'public' GROUP BY table_name ``` - 若要確保每次載入應用程式時都執行查詢,請啟用**“在應用程式載入時執行此查詢?”**切換。 現在,讓我們建立另一個查詢,該查詢將連接到 Gemini AI API 並產生自訂 SQL 報表查詢。 - 使用 ToolJet 的[工作空間常數](https://docs.tooljet.com/docs/org-management/workspaces/workspace_constants/)功能,使用您的 Gemini API 金鑰建立一個名為**GEMINI\_API\_KEY 的**新常數。 - 在查詢面板中,按一下**+ 新增**按鈕並選擇**REST API**選項。 - 將查詢重新命名為*getSqlQuery* 。 - 在請求參數中,從下拉清單中選擇 POST 作為方法,然後貼上以下 URL。 ``` https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent?key={{constants.GEMINI_API_KEY}} ``` - 導航到*getSqlQuery*的 Body 部分。切換到原始 JSON 並輸入以下程式碼: ``` {{ `{ "contents": [{ "parts": [{ "text": "Data Schema: ${JSON.stringify(queries.getTablesWithColumns.data.map(item => ({ ...item, table_name: "public." + item.table_name }))).replace(/"([^"]+)":/g, '$1:').replace(/"/g, '\\"')}, Text Prompt: Write a standard SQL query for a custom SQL report that will ${components.textPrompt.value.replaceAll("\n"," ")}. Return without formatting and without any code highlighting and any backticks" },], },], }` }} ``` 讓我們新增最終查詢,該查詢將從自訂報表所需的範例資料來源中檢索資料。 - 同樣,建立另一個**Sample 資料來源**查詢,將其重新命名為*getReportData*並輸入以下程式碼: ``` {{queries.getSqlQuery.data.candidates[0].content.parts[0].text}} ``` --- 將查詢綁定到 UI 元件 ------------ 現在我們已經成功建立了 UI 和查詢,下一步就是整合它們。 - 選擇**Button**元件並導航到右側的屬性面板。點選**“+ 新事件處理程序”**按鈕。將**操作**變更為**執行查詢**並選擇*getSqlQuery*查詢。 - 接下來,導覽至*getSqlQuery*查詢並點擊**+ New event handler**按鈕。將**操作**變更為**執行查詢**並選擇*getReportData*查詢。 - 接下來,選擇**表格**元件。在右側的屬性面板中,在資料欄位中輸入以下程式碼。 ``` {{queries.getReportData.data}} ``` 我們已經成功地將查詢整合到我們的 UI 中。現在讓我們使用以下提示來測試應用程式: *列出客戶姓名以及他們訂購的產品,包括訂購日期和每種產品的訂購總數。* ![SQL 報表範例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pbdvss1cd8b7mjucowym.png) 您可以點選**表格**頁腳上的**+**按鈕下載 PDF、Excel 或 CSV 格式的報表。 --- 結論 -- 恭喜您使用 ToolJet 和 Gemini API 成功建置了人工智慧驅動的 SQL 報表產生器。現在您可以用簡單的英文輸入提示並跨 PostgreSQL 實例中的多個表產生報表。 要了解和探索有關 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-report-generator-using-gemini-ai-tooljet-424p

少寫,永不修復:高度可靠程式碼的藝術

![被燒壞的工程師](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aygtgwad96xzq2pr944q.gif) 如果您是開發人員,不知疲倦地推出新的更改,卻被過去工作中的錯誤拖了回來,那麼這篇文章對您來說非常重要。 在過去的十年裡,在軟體開發中,我犯過並且看到其他人反覆犯過的關鍵錯誤之一是專注於做更多的工作,而不是確保完成的工作(無論多小)是穩健的並且將繼續正常工作。這些重複出現的錯誤會嚴重影響生產力和積極性。 從我自己的錯誤中,我學到了寶貴的教訓。在這裡,我想分享一些策略,它們不僅可以幫助您**交付強大的軟體**,還可以**讓您擺脫過去工作的束縛**。 ![告訴我更多](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a85h4md8p9xwd1ooq7zc.gif) 我們將討論對我最有效的 5 個策略: 1. [計劃 10 倍](#1-plan-for-10x) 2. [附註:您的舊工作出現錯誤,正在召回您](#2-psst-your-old-work-got-a-bug-and-is-calling-you-back) 3. [讓系統為您服務,而不是相反](#3-make-the-systems-work-for-you-not-the-other-way-around) 4. [始終用連結回答](#4-always-answer-with-a-link) 5. [了解軟體建置是一項團隊運動](#5-understand-software-building-is-a-team-sport)。 1. 10 次計劃 --------- 恕我直言,工程師有兩種:為今天而奮鬥的工程師和為遙遠的未來而設計的工程師。這兩種方法本身都不可持續。 您的程式碼應該能夠應對您的業務即將經歷的成長。然而,針對未來挑戰的過度設計可能會導致不必要的複雜性。有一個專門的術語 -[自行車脫落](https://thedecisionlab.com/biases/bikeshedding) ![擴大](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/edi9uv0o8bxjg58qr0wm.gif) 這是我的實用經驗法則:規劃目前規模的 10 倍,或考慮您的業務在未來 2-3 年內預計會成長多少。確保您的計劃與您的業務目標保持一致。 例如,如果您是一家設計預訂模組的計程車公司,現在您的公司每天處理 10,000 次乘車,並預計在 2 年內達到每天 100,000 次乘車,請以此作為基準。當您只進行 10,000 次騎行時,設計一個每天可進行 1000 萬次騎行的系統可能會導致解決方案過於複雜和昂貴。 2. 噓:您的舊工作出現了錯誤,正在召回您 --------------------- ![系統損壞](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/csf7rulcx55smffdqyyi.gif) 「幾天甚至幾週的除錯可以節省你編寫測試的幾個小時」——明智的人。 在不測試所有邊緣情況的情況下發布程式碼就像噴霧和祈禱策略。確保程式碼按預期工作的最簡單方法是新增單元測試。這聽起來似乎是顯而易見的,但徹底測試的重要性怎麼強調也不為過。 單元測試不僅充當針對明顯錯誤的第一道防線,而且還可以作為程式碼的保險,防止可能違反業務需求的意外更改。因此,減少每個衝刺分配給您的臨時錯誤 😉 **懶人(像我)的一個技巧**:在寫程式之前: - 編寫涵蓋您能想到的每個極端情況的測試。 - 假裝你正試圖破壞別人的系統。 - 在所有測試中編寫斷言 False 並執行它們。 - 當然,所有測試都會失敗。 現在,只需努力讓每個測試通過即可。這種方法總體上花費的時間較少,每次都會產生健壯的程式碼! 3. 讓系統為你服務,而不是相反 ---------------- ![監控系統](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8teb74yr1dgfq2tpolxf.gif) 我的一位經理曾經給了我最有影響力的建議:“採取行動,不要做出反應。”當我不斷在不同的 Slack 頻道上因問題、客戶投訴和付款失敗而被標記時,我提出了這個建議。我只是對每個請求做出反應,不知道接下來會發生什麼。 從那時起,我開始對我建造的每個功能提出三個問題: - 我怎麼知道它正在工作? - 我怎麼知道它失敗了? - 我怎麼知道它成功了? 然後,我透過將指標傳送到我們的 APM 工具(例如 Datadog 或 NewRelic)來回答各個層級(功能、螢幕、應用程式)的這些問題。 ![APM樣本](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8werj18bl8p6zhwc61d.png) 設定完畢後,我配置了警報,以便在出現任何問題時通知我。 透過這樣做,我在錯誤升級為重大問題之前就意識到了它們,從而防止了反應性措施、糟糕的客戶體驗以及我自己對接下來可能發生的事情的不確定性。 每次建造一些東西時,就開始回答這三個基本問題,以確保您始終採取行動而不是做出反應。 4. 總是用連結來回答 ----------- ![回覆文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8utxvlj2pt1ojjq7kk8.gif) 就像糟糕的工作會讓你在各種 Slack 頻道上進行修復一樣,出色的工作會讓你在你所從事的領域中被貼上上下文標籤。 這可能會在你最意想不到的時候耗盡你的精力,或者更糟的是,它可能會讓你成為執行相同任務的首選人選,因為你了解完整的情況。 **請保留這個秘密技巧:** 記錄一切。包括您在建立功能時所做的上下文、架構和特定於業務的決策。當有人詢問某個區域的上下文(功能、螢幕、應用程式)時,只需向他們發送更新文件的連結即可。這每次都會為您節省幾個小時。 此外,完整的文件使新團隊成員的入職變得更加容易,並確保您的工作隨著時間的推移仍然可以存取和理解。 5. 了解軟體建置是一項團隊運動。 ----------------- ![特德·拉索欣賞](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/witndxix4fs05xy3fjie.gif) 軟體工程通常強調個人貢獻者路徑。然而,單獨實現最終目標是不可能的——你只能與你的團隊一起實現它(反之亦然)。 理解並採用流程卓越的思維方式可以幫助您充分利用團隊的集體生產力。 ![使困惑](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwk1ubf1tcuq8wio2v7x.gif) 對於這樣的措詞表示抱歉😄 簡而言之,確保審查、部署和任何涉及程式碼的協作活動不會有很長的等待時間,這可以大大提高您的工作效率! 辨識團隊中長時間等待或阻塞時間的最佳方法是衡量 DORA 指標。您可以使用像[Middleware](https://github.com/middlewarehq/middleware)這樣的開源工具,它提供開箱即用的[DORA 指標](https://www.middlewarehq.com/blog/what-are-dora-metrics-how-they-can-help-your-software-delivery-process)。 {% 嵌入 https://github.com/middlewarehq/middleware %} PS:我也是[Middleware](https://middlewarehq.com)的共同創辦人,我們的使命是讓工程師的工程變得順暢。如果您喜歡我們所建造的內容,請考慮給我們一顆星星! 像老闆一樣發布程式碼! ----------- ![老闆人](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2qrf8s8gmb9cx5f8b6f.gif) 透過採用這些建議,您可以大幅減少重新審視和修復過去工作所花費的時間。這不僅可以提高您的工作效率,還可以確保您始終專注於創新和提供新功能。 保持高效,而不是忙碌!祝一切順利😊 --- 原文出處:https://dev.to/middleware/write-less-fix-never-the-art-of-highly-reliable-code-5a0i

我學習了 JavaScript 並製作了一款火爆網頁應用程式 🤯

隆重介紹**[Fakedin](https://fakedin-app.netlify.app/)** - 一款可以快速為社交媒體、簡報、迷因等建立令人驚嘆的假 LinkedIn 貼文的工具 🔥 請觀看下面的小演示影片,了解其工作原理,並存取該網站親自嘗試一下 🌟 --- https://www.youtube.com/watch?v=sikfunHdhRk --- 我必須承認,該應用程式還不完美,您可能會遇到一些錯誤,但不用擔心,我會在繼續進行時修復它們。目前,我正在尋求您的寶貴回饋,以使其變得更好。 🤝 **Fakedin 連結🔗** :https://fakedin-app.netlify.app/ 請務必檢查並分享您的回饋😇 感謝您的寶貴時間🙌 --- 另外,由於我每天發布的精彩內容,我最近在**[Linkedin](https://Linkedin.com/in/rammcodes)**上擁有了**14 萬**粉絲 ✌ 𝗙𝗼𝗹𝗹𝗼𝘄 我在**[Linkedin](https://Linkedin.com/in/rammcodes)**上取得與程式設計和 Web 開發相關的最精彩內容 💎 [![拉姆‧馬赫什瓦里 (Ram Maheshwari) (@rammcodes) Linkedin](https://i.postimg.cc/fL6k3xyT/www-linkedin-com-in-rammcodes-6.png)](https://Linkedin.com/in/rammcodes) --- 請用❤️🦄🤯🙌🔥 回覆這篇文章 & 保存起來供以後使用🔖 --- 再一次感謝你 :) --- 原文出處:https://dev.to/rammcodes/i-learned-javascript-made-a-web-app-that-went-viral-3no0

使用 Gemini API 和 ToolJet 在 10 分鐘內建立人工智慧商業提案編寫器 🚀

在本教學中,我們將引導您完成使用 ToolJet 和 Gemini API 建立 AI 商業提案編寫器的流程。我們將利用 ToolJet 的預先建置元件和簡單的整合流程來快速建立一個可以與 Gemini API 互動的應用程式。該應用程式將允許用戶輸入業務詳細資訊並產生專業的業務提案。 以下是最終應用程式的預覽: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rghughfkz183bzjtqpou.png) ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewcpalt0obyfkvdh68xr.png) --- 先決條件 ---- **Gemini API 金鑰**:Gemini API 是[Google AI Studio](https://aistudio.google.com/app/apikey)提供的進階 AI 服務。它使開發人員能夠將強大的內容生成功能整合到他們的應用程式中。 **ToolJet** (https://github.com/ToolJet/ToolJet):一個開源、低程式碼的商業應用程式建構器。[註冊](https://www.tooljet.com/signup)免費的 ToolJet 雲端帳號或使用 Docker[在本機上執行 ToolJet](https://docs.tooljet.com/docs/setup/try-tooljet/) 。 首先建立一個名為*Business Proposal Writer 的*應用程式。 --- 1. 建立一個新應用程式 ------------ - 打開 ToolJet 並點擊**“建立新應用程式”** 。 - 將您的應用程式命名為*Business Proposal Writer* 。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5faoqkb5ab9ydfpbjt0n.png) 建立新應用程式後,您將看到一個空白畫布,右側有一個元件庫,底部有一個查詢面板。 --- 2. 設計使用者介面 ---------- 將以下元件拖曳到畫布上: - **容器**:組織標題、輸入欄位和輸出部分。 - **文字和文字輸入**:用於公司名稱、服務描述、預算、截止日期和公司專業知識。 - **按鈕**:產生提案。 - **文字**:以 HTML 格式顯示產生的提案。 - **圖示**:用於徽標並使 UI 更具吸引力。 為了清楚起見,重新命名輸入欄位: - `companyNameInput` - `serviceDescriptionInput` - `budgetInput` - `deadlineInput` - `companyExpertiseInput` 將按鈕命名為`createButton` 。 命名將把產生的提案顯示為`output`的文字元件。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dki3r05jwejzr62mlbws.png) *ToolJet 的預先建置[元件](https://docs.tooljet.com/docs/tooljet-concepts/what-are-components)在功能和樣式自訂方面提供了完全的靈活性。* --- 3. 透過查詢與Gemini API集成 -------------------- - 建立一個[工作區常數](https://docs.tooljet.com/docs/tooljet-concepts/workspace-constants/)來保存您的 Gemini API 金鑰。將其命名為`GEMINI_API_KEY` 。 - 展開查詢面板,建立一個新查詢,並命名為`generateProposal` 。 - 將請求方法變更為`POST`並將以下 URL 貼到 URL 輸入下: `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent?key={{constants.GEMINI\_API\_KEY}} ` - 導航到`getContent`查詢的正文部分。切換到原始 JSON 並輸入以下程式碼: ``` { "contents": [ { "parts": [ { "text": " 1. **Client/Company Name:** {{components.companyNameInput.value}} 2. **Project/Service Description:** {{components.serviceDescriptionInput.value}} 3. **Budget Range (if applicable):** {{components.budgetInput.value}} 4. **Deadline:** {{components.deadlineInput.value}} 5. **Company Expertise:** {{components.companyExpertiseInput.value}} Based on these inputs, generate a well-structured and comprehensive business proposal document in HTML format. The generated proposal should include the following sections, each with ample padding and spacing: 1. **Executive Summary** 2. **Company Overview and Qualifications** 3. **Project Understanding and Approach** 4. **Proposed Solution and Methodology** 5. **Timeline and Deliverables** 6. **Team Structure and Bios** 7. **Cost Breakdown and Budget** (Include charts as needed) 8. **Terms and Conditions** 9. **Conclusion and Call to Action** Ensure that the HTML output is properly formatted and visually appealing." } ] } ] } ``` ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71f02ensa53tr3g6ponl.png) *ToolJet 中的[查詢](https://docs.tooljet.com/docs/tooljet-concepts/what-are-queries)提供了一種連接[資料庫、API 和雲端儲存服務的](https://docs.tooljet.com/docs/tooljet-concepts/what-are-datasources)簡單方法。* --- 4. 將 UI 元件與查詢連接 --------------- - 選擇`createButton`元件。 - 新增事件處理程序以在點擊按鈕時觸發`generateProposal`查詢。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cuayj8aq73tdg0zbhrc.png) *事件用於執行查詢、顯示警報以及基於觸發器(例如按鈕單擊或查詢完成)的其他功能。* - 選擇為顯示查詢輸出而建立的文字元件。 - 在其 Data 屬性下,輸入以下程式碼: `{{queries.generateProposal.data.candidates[0].content.parts[0].text}}` 現在,在輸入欄位中輸入所需的詳細訊息,然後按一下按鈕。您應該在輸出元件中看到產生的業務提案。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jjzuk15d30x9036nyhki.png) ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyfbp9ltgyn1zqmsezsu.png) --- 結論 -- 您已在短短 10 分鐘內使用 Gemini API 和 ToolJet 成功建立了一個商業提案編寫器。該工具將簡化專業商業提案的建立,節省您的時間和精力。如有任何問題或支持,請加入[ToolJet Slack 社群](https://join.slack.com/t/tooljet/shared_invite/zt-2l2i9tuls-NNCZPBlPAi2flYIhrjBqHA)。您也可以查看[ToolJet 文件](https://docs.tooljet.com/docs/)以了解更多資訊。 --- 原文出處:https://dev.to/tooljet/build-an-ai-business-proposal-writer-using-gemini-api-and-tooljet-in-10-minutes-4j3j

DNS 基礎:了解 Internet 的目錄服務

了解 DNS:網際網路的目錄服務 ---------------- 網域名稱系統 (DNS) 是您每天與之互動的網路的重要組成部分,您甚至常常沒有意識到這一點。該系統將`www.example.com`等人類友善的網域轉換為`192.0.2.1`等電腦用來相互通訊的 IP 位址。將 DNS 視為網際網路的電話簿,可協助您輕鬆連線至網站和服務。在本部落格中,我們將探討 DNS 是什麼、它如何運作以及為什麼它如此重要。我們也將透過範例和配置深入探討一些技術細節。 目錄 -- 1. [什麼是 DNS?](#1-what-is-dns) 2. [DNS 的工作原理](#2-how-dns-works) - [DNS解析過程](#dns-resolution-process) - [DNS 伺服器的類型](#types-of-dns-servers) 3. [DNS 記錄](#3-dns-records) 4. [設定 DNS](#4-setting-up-dns) - [DNS 設定檔](#dns-configuration-files) - [DNS 查詢範例](#dns-query-example) 5. [安全考慮](#5-security-considerations) 6. [結論](#6-conclusion) 1.什麼是DNS? --------- DNS 代表網域名稱系統。它是一個分層、分散的系統,用於將網域轉換為 IP 位址。 DNS 允許您使用易於記憶的網域名稱而不是複雜的數位 IP 位址,從而使網路變得用戶友好。 ### DNS 的結構如何 DNS 依層級結構組織: 1. **根級**:最頂層,包含儲存有關頂級域 (TLD) 資訊的根伺服器。 2. **頂級網域名稱 (TLD)** :包括熟悉的擴展名,如`.com` 、 `.org`和`.net` ,以及特定國家/地區的 TLD,如`.uk`和`.jp` 。 3. **二級域名**:直接位於 TLD 下的域名,例如`example.com`中的`example` 。 4. **子網域**:其他細分,例如`www.example.com`中的`www` 。 2. DNS 的工作原理 ------------ 當您在瀏覽器中輸入 URL 時,DNS 會將該 URL 轉換為 IP 位址,以便您的電腦可以存取網站。此過程涉及多個步驟和不同類型的 DNS 伺服器。 ### DNS解析過程 1. **DNS 查詢啟動**:您在瀏覽器中輸入 URL,瀏覽器會將 DNS 查詢傳送至本機 DNS 解析器。 2. **查詢遞歸解析器**:本機 DNS 解析器(通常由 ISP 提供)檢查其快取中的 IP 位址。如果沒有找到,它會查詢遞歸解析器。 3. **遞歸查詢**:遞歸解析器依序查詢根伺服器、TLD 伺服器和權威 DNS 伺服器來尋找 IP 位址。 4. **回應**:找到 IP 位址後,它會返回本機 DNS 解析器,然後解析器將其發送到您的瀏覽器,從而允許存取該網站。 ### DNS 伺服器的類型 - **根名稱伺服器**:DNS 轉換過程的第一站,處理 TLD 請求。 - **TLD 名稱伺服器**:儲存有關特定 TLD 內的網域的資訊。 - **權威名稱伺服器**:對其管理的網域的查詢提供回應。 3.DNS記錄 ------- DNS 記錄儲存有關網域名稱及其對應 IP 位址的資訊。以下是一些常見的 DNS 記錄類型: - **A 記錄**:將網域名稱對應到 IPv4 位址。 - **AAAA 記錄**:將網域名稱對應到 IPv6 位址。 - **CNAME記錄**:將一個網域對應到另一個網域(規範名稱)。 - **MX 記錄**:指定網域的郵件伺服器。 - **TXT 記錄**:儲存文字訊息,通常用於驗證和電子郵件安全(例如 SPF、DKIM)。 例如,以下是`example.com`的一些 DNS 記錄: ``` example.com. 3600 IN A 93.184.216.34 example.com. 3600 IN AAAA 2606:2800:220:1:248:1893:25c8:1946 www.example.com. 3600 IN CNAME example.com. example.com. 3600 IN MX 10 mail.example.com. example.com. 3600 IN TXT "v=spf1 include:_spf.example.com ~all" ``` 4. 設定 DNS --------- 為您的網域設定 DNS 涉及配置 DNS 記錄並確保您的 DNS 伺服器可以正確處理查詢。 ### DNS 設定檔 在類別 Unix 系統上,DNS 配置通常可以在`/etc/named.conf`中找到(對於 BIND,一種流行的 DNS 伺服器軟體)。這是一個基本範例: ``` options { directory "/var/named"; forwarders { 8.8.8.8; // Google DNS 8.8.4.4; // Google DNS }; }; zone "example.com" IN { type master; file "example.com.zone"; }; zone "." IN { type hint; file "named.ca"; }; ``` `example.com.zone`檔案可能如下所示: ``` $TTL 86400 @ IN SOA ns1.example.com. admin.example.com. ( 2024010101 ; Serial 3600 ; Refresh 1800 ; Retry 1209600 ; Expire 86400 ) ; Minimum TTL @ IN NS ns1.example.com. @ IN NS ns2.example.com. @ IN A 93.184.216.34 @ IN AAAA 2606:2800:220:1:248:1893:25c8:1946 www IN CNAME example.com. mail IN MX 10 mail.example.com. ``` ### DNS 查詢範例 若要查詢 DNS 記錄,您可以使用`dig`或`nslookup`等工具。這是使用`dig`範例: ``` dig example.com ``` 此命令輸出如下內容: ``` ; <<>> DiG 9.16.1-Ubuntu <<>> example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 3600 IN A 93.184.216.34 ;; AUTHORITY SECTION: example.com. 3600 IN NS ns1.example.com. example.com. 3600 IN NS ns2.example.com. ;; ADDITIONAL SECTION: ns1.example.com. 3600 IN A 192.0.2.1 ns2.example.com. 3600 IN A 192.0.2.2 ;; Query time: 54 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Wed Jun 15 16:20:55 UTC 2024 ;; MSG SIZE rcvd: 117 ``` 5. 安全考慮 ------- DNS 對於網路功能至關重要,因此成為各種攻擊的目標。主要安全考量包括: - **DNS 快取中毒**:攻擊者將損壞的 DNS 資料引入解析器的快取中,將流量重新導向到惡意網站。 - **DNSSEC** :DNS 安全性擴充功能會向 DNS 資料新增加密簽名,確保資料完整性和真實性。 - **DDoS 攻擊**:分散式阻斷服務攻擊可能會導致 DNS 伺服器的流量不堪重負,導致 DNS 解析緩慢或無法解析。 六,結論 ---- 域名系統是一項重要的技術,它使網路變得易於存取且用戶友好。透過將網域轉換為 IP 位址,DNS 可以實現無縫瀏覽和通訊。了解 DNS 的工作原理、結構和配置對於 Web 開發人員、網路管理員和網路安全專業人員至關重要。 我們已經介紹了 DNS 的基礎知識,包括其層次結構、解析過程和各種記錄類型。我們也研究了 DNS 的設定和一些重要的安全注意事項。有了這些知識,您就可以更深入地研究 DNS 並將其應用到您的專案和網路中。 --- 原文出處:https://dev.to/iaadidev/the-basics-of-dns-understanding-the-internets-directory-service-34l2

只需 2GB 記憶體即可將後端擴展到 1M 請求 ⚡️

本部落格介紹了我如何解鎖效能,使我能夠在最少的資源(2 GB RAM 1v CPU 和最小網路頻寬 50-100 Mbps)上將後端從 50K 請求擴展到 1M 請求(~16K 請求/分鐘)。 ![迷因](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b0m1kiuyq575f2qzyweu.png) 它將帶你踏上一段與過去的自己的旅程。這可能是一段漫長的旅程,所以請繫緊安全帶,享受這段旅程! 🎢 *它假設您熟悉後端和編寫 API。如果你了解一點 Go,這也是一個優勢。如果你不這樣做,也沒關係。您仍然可以按照我提供的資源來幫助您理解每個主題。 (如果您不知道 GO,這裡有一個*[*快速介紹*](https://www.youtube.com/watch?v=446E-r0rXHI)*)* 長話短說;博士, 首先,我們建立一個[可觀察性管道](https://www.observo.ai/post/what-is-an-observability-pipeline),幫助我們監控後端的所有面向。然後,我們開始對後端進行壓力測試,直到斷點測試(當一切最終崩潰時)。 →[連接輪詢以避免達到最大連接閾值](#optimization-1-connection-pooling-️) →[實施資源限制以避免非關鍵服務佔用資源](#optimization-2-unblocking-resources-from-alloy-open-telemetry-collector) →[新增索引](#optimization-3-adding-indexes-🏎️) →[禁用隱式事務](#optimization-4-ensure-while-testing-there-is-no-blocking-transaction) →[增加 Linux 的最大檔案描述符限制](#optimization-6-increasing-the-max-file-descriptor-limit) →[限制 Goroutines](#optimization-7-avoid-overloading-goroutines) →[未來計劃](#next-steps) 後端簡介🤝 ----- 讓我簡單介紹一下後端, - 它是一個用 Golang 寫的整體 RESTful API。 - 使用[GIN](https://github.com/gin-gonic/gin)框架編寫,並使用[GORM](https://gorm.io/)作為[ORM](https://www.theserverside.com/definition/object-relational-mapping-ORM) 。 - 使用 Aurora Postgres 作為託管在 AWS RDS 上的唯一主資料庫。 - 後端是[Docker 化的](https://dev.to/documatic/how-to-dockerize-your-application-536i#:~:text=Dockerizing%20an%20application%20is%20the,for%20developers%20and%20organizations%20alike.),我們在 AWS 上的`t2.small`實例中執行它。它具有 2GB RAM、50-100mb/s 網路頻寬、1 個 vCPU。 - 後端提供身份驗證、CRUD 操作、推播通知和即時更新。 - 對於即時更新,我們打開一個非常輕量級的[Web 套接字連接](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API),通知設備實體已更新。 我們的應用程式主要是讀取密集型,具有下降的寫入活動,如果我必須給它一個比率,它將是 65% 讀取/35% 寫入。 我可以寫一篇單獨的部落格來解釋我們為什麼選擇 - 整體架構、golang 或 postgress,但為了向您介紹[MsquareLabs 的](www.msquarelabs.com)tl;dr,我們相信「保持簡單,並建立允許我們以驚人的快節奏前進的程式碼。 資料資料資料🙊 ------- 在進行任何模擬負載生成之前,我首先將可觀察性建置到我們的後端中。其中包括追蹤、指標、分析和日誌。這使得找到問題並準確地找出造成疼痛的原因變得非常容易。當您對後端擁有如此強大的監控能力時,您也可以更輕鬆地更快地追蹤生產問題。 在我們繼續之前,讓我先簡單介紹一下指標、分析、日誌和追蹤: - 日誌:我們都知道日誌是什麼,它只是我們在事件發生時建立的大量文字訊息。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/94b2970c-34fc-4135-bed0-bf763ef098c8) - 追蹤:這是高度可見性的結構化日誌,有助於我們以正確的順序和時間封裝事件。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/9ee944e8-0637-4aa9-b076-5ff35990a8e2) - 指標:所有數字攪動資料,例如 CPU 使用率、活動請求和活動 goroutine。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/ec9a493d-6344-4c10-80e6-0db8c5c1d219) - 分析:為我們提供程式碼的即時指標及其對機器的影響,幫助我們了解正在發生的情況。 (WIP,下一篇部落格會詳細講) 要了解有關我如何將可觀察性建置到後端的更多訊息,您可以研究下一個博客(WIP),我將此部分移至另一個博客,因為我想避免讀者不知所措並只關註一件事 -**優化**) 這就是追蹤、日誌和指標的視覺化的樣子, ![截圖 2024-05-30 下午 4.53.29.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/20883b44-6f0f-42a1-b4f0-ae6ac2c04642) 所以現在我們有一個強大的監控管道+一個像樣的儀表板作為開始🚀 嘲笑高級用戶 x 100,000 🤺 ------------------ 現在真正的樂趣開始了,我們開始嘲笑愛上該應用程式的用戶。 「只有當你把你的愛(後端)置於極大的壓力時,你才會發現它的真正本質✨」 - 某個偉大的人,哈哈,idk Grafana 還提供了一個負載測試工具,因此我決定使用它,因為它只需要幾行程式碼的最少設置,因此您已經準備好了模擬服務。 我沒有觸及所有 API 路線,而是專注於最關鍵的路線,這些路線負責我們 90% 的流量。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/e42d706f-fc61-4cdd-8b0e-35113761f09c) 關於[k6](https://k6.io)的簡單介紹,它是一個基於 javascript 和 golang 的測試工具,您可以在其中快速定義要模擬的行為,它負責對其進行負載測試。無論您在主函數中定義什麼,都稱為*迭代*,k6 會啟動多個虛擬使用者單元(VU)來處理此迭代,直到達到給定的週期或迭代計數。 每次迭代構成4個請求,建立任務→更新任務→取得任務→刪除任務 ![iLoveIMG 下載 (1).jpg](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/32cb71fb-d549-48c9-88a0-ecaf48296593/c7dcc3cb-4128-44d4-b3ad-e736c96e377b) 慢慢開始,讓我們看看大約 10K 請求 → 100 VU 和 30 iter → 3000 iters x 4reqs → 12K 請求情況如何 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/84f31eec-79d5-49f9-915f-bb97b6d5f517) 這是輕而易舉的事情,沒有任何記憶體洩漏、CPU 過載或任何類型瓶頸的跡象,萬歲! 這是 k6 的摘要,發送了 13MB 資料,接收了 89MB,平均超過 52 req/s,平均延遲為 278ms,考慮到所有這些都在單台機器上執行,這還不錯。 ``` checks.........................: 100.00% ✓ 12001 ✗ 0 data_received..................: 89 MB 193 kB/s data_sent......................: 13 MB 27 kB/s http_req_blocked...............: avg=6.38ms min=0s med=6µs max=1.54s p(90)=11µs p(95)=14µs http_req_connecting............: avg=2.99ms min=0s med=0s max=536.44ms p(90)=0s p(95)=0s ✗ http_req_duration..............: avg=1.74s min=201.48ms med=278.15ms max=16.76s p(90)=9.05s p(95)=13.76s { expected_response:true }...: avg=1.74s min=201.48ms med=278.15ms max=16.76s p(90)=9.05s p(95)=13.76s ✓ http_req_failed................: 0.00% ✓ 0 ✗ 24001 http_req_receiving.............: avg=11.21ms min=10µs med=94µs max=2.18s p(90)=294µs p(95)=2.04ms http_req_sending...............: avg=43.3µs min=3µs med=32µs max=13.16ms p(90)=67µs p(95)=78µs http_req_tls_handshaking.......: avg=3.32ms min=0s med=0s max=678.69ms p(90)=0s p(95)=0s http_req_waiting...............: avg=1.73s min=201.36ms med=278.04ms max=15.74s p(90)=8.99s p(95)=13.7s http_reqs......................: 24001 52.095672/s iteration_duration.............: avg=14.48s min=1.77s med=16.04s max=21.39s p(90)=17.31s p(95)=18.88s iterations.....................: 3000 6.511688/s vus............................: 1 min=0 max=100 vus_max........................: 100 min=100 max=100 running (07m40.7s), 000/100 VUs, 3000 complete and 0 interrupted iterations _10k_v_hits ✓ [======================================] 100 VUs 07m38.9s/20m0s 3000/3000 iters, 30 per VU ``` 讓我們增加 12K → 100K 請求,發送 66MB,接收 462MB,CPU 使用率峰值達到 60%,記憶體使用率達到 50%,執行需要 40 分鐘(平均 2500 個請求/分鐘) ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/838e351e-ac9e-47a1-af51-4f69f75f5de0) 一切看起來都很好,直到我在日誌中看到一些奇怪的東西,“::gorm: 連接太多::”,快速檢查RDS 指標,確認打開的連接已達到410,即最大打開連接的限制。它是由 Aurora Postgres 本身[根據實例的可用記憶體](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Managing.html#AuroraPostgreSQL.Managing.MaxConnections)設定的。 您可以透過以下方法檢查, `select * from pg_settings where name='max_connections';` ⇒ 410 Postgres 為每個連接產生一個進程,考慮到它會在新請求到來時打開一個新連接並且之前的查詢仍在執行,因此這是極其昂貴的。因此 postgress 對可以開啟的並發連線數進行了限制。一旦達到限制,它會阻止任何進一步連接資料庫的嘗試,以避免實例崩潰(這可能會導致資料遺失) ### 優化一:連接池⚡️ 連接池是一種管理資料庫連接的技術,它重用打開的連接並確保它不會超過閾值,如果客戶端請求連接並且超過最大連接限制,它會等待直到連接被釋放或拒絕該請求。 這裡有兩個選項,要么執行客戶端池,要么使用單獨的服務,例如[pgBouncer](pgbouncer.org) (充當代理)。當我們規模較大且我們有連接到相同資料庫的分散式架構時,pgBouncer 確實是一個更好的選擇。因此,為了簡單性和我們的核心價值觀,我們選擇繼續進行客戶端池化。 幸運的是,我們使用的 ORM GORM 支援連接池,但[在幕後使用資料庫/SQL](https://gorm.io/docs/connecting_to_the_database.html#Connection-Pool) (golang 標準套件)來處理它。 有一些非常簡單的方法可以處理這個問題, ``` configSQLDriver, err := db.DB() if err != nil { log.Fatal(err) } configSQLDriver.SetMaxIdleConns(300) configSQLDriver.SetMaxOpenConns(380) // kept a few connections as buffer for developers configSQLDriver.SetConnMaxIdleTime(30 * time.Minute) configSQLDriver.SetConnMaxLifetime(time.Hour) ``` - `SetMaxIdleConns` → 保留在記憶體中的最大空閒連接,以便我們可以重複使用它(有助於減少開啟連接的延遲和成本) - `SetConnMaxIdleTime` → 我們應該在記憶體中保留空閒連接的最長時間。 - `SetMaxOpenConns` → 與資料庫的最大開啟連接,因為我們在同一個 RDS 實例上執行兩個環境 - `SetConnMaxLifetime` → 任何連線保持開啟的最長時間 現在更進一步,500K 請求(4000 個請求/分鐘)和 20 分鐘伺服器崩潰💥,最後讓我們調查一下🔎 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/39787835-b83d-441a-a3aa-a3b9fb03fc26) 快速查看指標,然後砰! CPU 和記憶體使用量激增。 Alloy(開放遙測收集器)佔用了所有 CPU 和內存,而不是我們的 API 容器。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/e8e764e4-31ea-44fa-b930-1bd1746d131b) ### 優化二:合金資源解鎖(開放式遙測收集器) 我們在小型 t2 實例中執行三個容器, - API開發 - API 分期 - 合金 當我們將大量負載轉儲到 DEV 伺服器時,它開始以相同的速率產生日誌和跟踪,從而呈指數級增加 CPU 使用率和網路出口。 因此,確保合金容器不會超出資源限制並妨礙關鍵服務非常重要。 由於合金在 docker 容器內執行,因此更容易強制執行此約束, ``` resources: limits: cpus: '0.5' memory: 400M ``` 此外,這次日誌不為空,存在多個上下文取消錯誤 - 原因是請求逾時,並且連接突然關閉。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/ace0ce7e-990e-43ea-a871-dc18888e3968) 然後我檢查了延遲,這太瘋狂了 😲 經過一段時間後,平均延遲為 30 - 40 秒。多虧了跟踪,我現在可以準確地找出是什麼導致瞭如此巨大的延遲。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/04be9892-5791-4834-b418-e9f417c0781d) 我們在 GET 操作中的查詢非常慢,讓我們對查詢執行[`EXPLAIN ANALYZE`](https://www.postgresql.org/docs/current/sql-explain.html) , ![截圖 2024-06-11 9.55.10 PM.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/3cf82d23-53c5-4976-aacc-2fa0d6ab2353) LEFT JOIN 花了 14.6 秒,而 LIMIT 又花了 14.6 秒,我們如何優化它 - INDEXING ### 優化3:新增索引🏎️ 為`where`或`ordering`子句中常用的欄位新增索引可以將查詢效能提高五倍。在新增 LEFT JOIN 表和 ORDER 欄位的索引後,相同查詢花費了 50 毫秒。你能從**14.6 秒 ⇒ 50 毫秒**開始思考嗎? (但要注意盲目加入索引,會導致CREATE/UPDATE/DELETE慢死) 它還可以更快地釋放連接,並有助於提高處理巨大並發負載的整體能力。 ### 最佳化 4:確保測試時沒有阻塞 TRANSACTION 🤡 從技術上講不是優化而是修復,您應該記住這一點。當您進行壓力測試時,您的程式碼不會嘗試同時更新/刪除相同實體。 在檢查程式碼時,我發現了一個錯誤,該錯誤導致每次請求時都會對用戶實體進行更新,並且當在事務內執行每個更新呼叫時,這會建立一個鎖,幾乎所有更新呼叫都被以前的更新呼叫阻止。 僅此一項修復就將吞吐量提高至 2 倍。 ### 最佳化5:跳過 GORM 的隱式 TRANSACTION 🎭 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/ab40af5b-c0fd-4c18-9067-859df56c4ec0) 預設情況下,GORM 在事務中執行每個查詢,這會降低效能,因為我們擁有極其強大的事務機制,在關鍵區域丟失事務的機會幾乎是不可能的(除非他們是實習生🤣)。 我們有一個中間件可以在到達模型層之前建立事務,並且有一個集中函數來確保控制器層中該事務的提交/回滾。 透過停用此功能,我們可以獲得[至少約 30% 的效能提升](https://gorm.io/docs/transactions.html#Disable-Default-Transaction)。 “我們卡在每分鐘 4-5K 請求的原因是這個,我認為這是我的筆記型電腦網路頻寬的問題。” - 愚蠢的我 所有這些優化帶來了 5 倍的吞吐量增益 💪,現在光是我的筆記型電腦就可以每分鐘產生 12K-18K 請求的流量。 ![截圖 2024-06-12 7.20.27 PM.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/fd440164-255f-4a4d-8389-c14365472372) ### 百萬點次數🐉 最後,每分鐘 10k-13K 請求達到 100 萬次,大約需要 2 小時,本來應該早點完成,但隨著合金重新啟動(由於資源限制),所有指標都會隨之丟失。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/6561ab09-1eb6-4b6f-92f2-92b5b2818590) 令我驚訝的是,該時間段內的最大 CPU 使用率為 60%,而記憶體使用量僅為 150MB。 Golang 的效能如此之高且處理負載的能力如此出色,這真是太瘋狂了。它具有最小的記憶體佔用。就是愛上了 golang 💖 每個查詢需要 200-400 毫秒才能完成,下一步是找出為什麼需要這麼多時間,我的猜測是連接池和 IO 阻塞減慢了查詢速度。 平均延遲降至約 2 秒,但仍有很大改進空間。 隱式優化🕊️ ------ ### 優化6:增加最大檔案描述子限制🔋 當我們在 Linux 作業系統中執行後端時,我們打開的每個網路連線都會建立一個檔案描述符,預設為 Linux 將每個進程限制為 1024 個,這阻礙了它達到峰值效能。 當我們開啟多個 Web 套接字連線時,如果有大量並發流量,我們很容易就會達到此限制。 Docker compose 提供了一個很好的抽象, ``` ulimits: core: soft: -1 hard: -1 ``` ### 優化 7:避免 goroutine 過載 🤹 作為一個 Go 開發者,我們經常認為 Goroutine 是理所當然的,只是盲目地在 Goroutine 中執行許多非關鍵任務,我們在函數之前加入`go` ,然後忘記它的執行,但在極端情況下它可能會成為瓶頸。 為了確保它永遠不會成為我的瓶頸,對於經常在 goroutine 中執行的服務,我使用帶有 n-worker 的記憶體佇列來執行任務。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/b00e6636-6b3f-472e-99fc-f6c66ee87186) 後續步驟🏃‍♀️ -------- ### 改進:從 t2 移動到 t3 或 t3a t2是老一代的AWS通用機器,而t3和t3a、t4g是新一代。它們是可突發的實例,與 t2 相比,它們為長時間的 CPU 使用提供更好的網路頻寬和更好的效能 了解突發實例, [AWS 引入了可突發執行個體](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances.html)類型,主要針對大多數時間不需要 100% CPU 的工作負載。因此,這些實例以基準效能 (20% - 30%) 運作。當您的實例不需要 CPU 時,他們會維護一個積分系統,它會累積積分。當 CPU 峰值發生時,它會使用該積分。這可以降低您的 AWS 運算成本和浪費。 t3a 將是一個值得堅持的好系列,因為它們的成本/效率比在可突發實例係列中好得多。 這是一個比較[t2 和 t3 的](https://www.cloudzero.com/advisor/t2-vs-t3/)不錯的部落格。 ### 改進:查詢 我們可以對查詢/模式進行許多改進來提高速度,其中一些是: - 在插入重型表中批量插入。 - 透過非規範化避免 LEFT JOIN - 快取層 - 著色和分區,但這要晚得多。 ### 改進:分析 釋放效能的下一步是啟用分析並弄清楚執行時到底發生了什麼。 ### 改進:斷點測試 為了發現我的伺服器的限制和容量,下一步是斷點測試。 ### 尾註👋 如果你讀到最後,你已經破解了,恭喜你🍻 這是我的第一篇博客,如果有不清楚的地方,或者您想更深入地了解該主題,請告訴我。在我的下一篇部落格中,我將深入研究分析,敬請關注。 您可以在[X](x.com/_rikenshah)上關注我,以獲取最新資訊:) --- 原文出處:https://dev.to/rikenshah/scaling-backend-to-1m-requests-with-just-2gb-ram-4m0c

如何使用 Ollama 和打開 WebUI 在本地執行 Llama 3

https://youtu.be/GT-Fwg124-I 我是 Llama 的忠實粉絲。 Meta 發布其 LLM 開源程式碼對整個科技界來說是一項淨收益,其寬鬆的許可證允許大多數中小型企業在幾乎沒有任何限制的情況下使用其 LLM(當然,在法律範圍內)。他們的最新版本是備受期待的 Llama 3。 Llama 3 有兩種大小:80 億和 700 億參數。這種模型經過大量文字資料的訓練,可用於各種任務,包括生成文字、翻譯語言、編寫不同類型的創意內容以及以資訊豐富的方式回答您的問題。 Meta 宣稱 Llama 3 是最好的開放模型之一,但它仍在開發中。這是與 Mistral 和 Gemma 相比的 8B 模型基準(根據 Meta)。 ![基準測試](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ax9r9z2w2zghv81grbh7.png) 這就引出了一個問題:作為一個普通人,我如何在我的電腦上本地執行這些模型? 開始使用 Ollama ----------- 這就是[奧拉瑪](https://ollama.com/)登場的地方! Ollama 是一款免費的開源應用程式,可讓您在自己的電腦上執行各種大型語言模型,包括 Llama 3,即使資源有限。 Ollama 利用了 llama.cpp 的效能提升,llama.cpp 是一個開源程式庫,旨在允許您以相對較低的硬體要求在本地執行 LLM。它還包括一種套件管理器,使您只需一個命令即可快速有效地下載和使用 LLM。 第一步是[安裝 Ollama](https://ollama.com/download) 。它支援所有 3 個主要作業系統,其中[Windows 是「預覽版」](https://ollama.com/blog/windows-preview) (更好的說法是「測試版」)。 安裝完成後,打開您的終端。在所有平台上,命令都是相同的。 ``` ollama run llama3 ``` 等待幾分鐘,它會下載並載入模型,然後開始聊天!它應該會帶您進入與此類似的聊天提示。 ``` ollama run llama3 >>> Who was the second president of the united states? The second President of the United States was John Adams. He served from 1797 to 1801, succeeding George Washington and being succeeded by Thomas Jefferson. >>> Who was the 30th? The 30th President of the United States was Calvin Coolidge! He served from August 2, 1923, to March 4, 1929. >>> /bye ``` 您可以在這個終端聊天中整天聊天,但是如果您想要更像 ChatGPT 的東西怎麼辦? 打開網頁介面 ------ Open WebUI 是一個可擴充的、自架的 UI,完全在[Docker](https://docs.docker.com/desktop/)內部運作。它可以與 Ollama 或其他 OpenAI 相容的 LLM 一起使用,例如 LiteLLM 或我自己的[Cloudflare Workers OpenAI API](https://github.com/chand1012/openai-cf-workers-ai) 。 假設您的電腦上已經執行了[Docker](https://docs.docker.com/desktop/)和 Ollama,[安裝](https://docs.openwebui.com/getting-started/#quick-start-with-docker-)非常簡單。 ``` docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main ``` 只要造訪 http://localhost:3000,建立帳戶,然後開始聊天! ![OpenWebUI 範例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdi1d35zh09s78o8vqvb.png) 如果您之前沒有執行過 Llama 3,則必須先關閉一些模型才能開始聊天。最簡單的方法是點擊左下角您的名字後點擊設定圖示。 ![設定](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqyetksyn0y4a0p12ylu.png) 然後點擊模式左側的“模型”,然後貼上[Ollama 註冊表](https://ollama.com/models)中的模型名稱。以下是我推薦用於一般用途的一些模型。 - `llama3` - `mistral` - `llama2` ![機型設定頁面](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txc581jf4w3xszymjfbg.png) 奧拉馬 API ------- 如果您想將 Ollama 整合到您自己的專案中,Ollama 提供自己的 API 以及 OpenAI 相容 API。 API 會自動將本機儲存的 LLM 載入到記憶體中,執行推理,然後在一定的逾時後卸載。您必須先拉取您想要使用的任何模型,然後才能透過 API 執行模型,這可以透過命令列輕鬆完成。 ``` ollama pull mistral ``` ### 奧拉馬 API Ollama 有自己的 API,其中還有[一些用於 Javascript 和 Python 的 SDK](https://github.com/ollama/ollama?tab=readme-ov-file#libraries) 。 以下是如何使用 API 進行簡單的文字產生推理。 ``` curl http://localhost:11434/api/generate -d '{ "model": "mistral", "prompt":"Why is the sky blue?" }' ``` 以下是如何使用 API 進行聊天產生推論。 ``` curl http://localhost:11434/api/chat -d '{ "model": "mistral", "messages": [ { "role": "user", "content": "why is the sky blue?" } ] }' ``` 將`model`參數替換為您要使用的任何模型。請參閱[官方 API 文件](https://github.com/ollama/ollama/blob/main/docs/api.md)以取得更多資訊。 ### OpenAI 相容 API 您也可以使用 Ollama 作為 OpenAI 庫的替代品(取決於用例)。這是[他們文件](https://github.com/ollama/ollama/blob/main/docs/openai.md)中的一個範例。 ``` # Python from openai import OpenAI client = OpenAI( base_url='http://localhost:11434/v1/', # required but ignored api_key='ollama', ) chat_completion = client.chat.completions.create( messages=[ { 'role': 'user', 'content': 'Say this is a test', } ], model='mistral', ) ``` 這也適用於 JavaScript。 ``` // Javascript import OpenAI from 'openai' const openai = new OpenAI({ baseURL: 'http://localhost:11434/v1/', // required but ignored apiKey: 'ollama', }) const chatCompletion = await openai.chat.completions.create({ messages: [{ role: 'user', content: 'Say this is a test' }], model: 'llama2', }) ``` 結論 -- Meta 的 Llama 3 的發布及其大型語言模型 (LLM) 技術的開源標誌著技術社群的一個重要里程碑。現在,透過 Ollama 和 Open WebUI 等本地工具可以存取這些先進的模型,普通個人可以挖掘其巨大潛力來生成文字、翻譯語言、創作創意寫作等。此外,API 的可用性使開發人員能夠將 LLM 無縫整合到新專案或增強現有專案。最終,LLM 技術透過 Llama 3 等開源專案實現民主化,釋放了廣泛的創新可能性,並激發了科技業的創造力。 --- 原文出處:https://dev.to/timesurgelabs/how-to-run-llama-3-locally-with-ollama-and-open-webui-297d

系統設計面試中 Docker、Kubernetes 和 Podman 有何不同?

*揭露:這篇文章包含附屬連結;如果您透過本文中提供的不同連結購買產品或服務,我可能會獲得補償。* ![Docker、Kubernetes 和 Podman 之間的差異?](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7lmxnjetsoayumogkorw.png) 朋友們大家好,如果您正在準備技術面試,那麼您必須為 Docker 和 Kubernetes 等容器技術做好準備,因為容器現在用於部署大多數應用程式,包括微服務和單體應用。 如今,系統設計和軟體開發人員面試中最常見的問題之一是**Docker、Kubernetes 和 Podman 之間的差異?它們是什麼以及何時使用它們**。 過去我討論過[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)等系統設計問題,今天我將回答Docker、Kubernetes和Podman之間的差異。 Docker、Kubernetes 和 Podman 都是受歡迎的容器化工具,讓開發人員和 DevOps 以一致且高效的方式打包和部署應用程式。 **Docker**是流行的容器化平台,允許開發人員在容器中建立、部署和執行應用程式。 Docker 提供了一組工具和 API,使開發人員能夠建置和管理容器化應用程式,包括 Docker Engine、Docker Hub 和 Docker Compose。 另一方面, **Kubernetes**是一個開源容器編排平台,可以自動化容器化應用程式的部署、擴展和管理。 Kubernetes 還提供了一組 API 和工具,使開發人員能夠在多個主機和環境中大規模部署和管理容器化應用程式。 而\*\*,Podman\*\*是一個相對較新的容器化工具,與Docker類似,但架構不同。 Podman 不需要守護程序來執行容器,並且它與 Docker 映像和註冊表相容。 Podman 提供了一個簡單的命令列介面來建立和管理容器,在許多情況下它可以用作 Docker 的直接替代品。 現在我們已經基本了解它們是什麼以及它們的作用,讓我們深入研究它們以了解它們是如何工作的。 順便說一句,如果您正在準備系統設計面試並想深入學習系統設計,那麼您還可以查看[**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)等網站,它們有許多很棒的系統設計課程 [![如何回答系統設計問題](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%2Fxd9nfio7kl57gyevndql.jpg)](https://bit.ly/3pMiO8g) PS 繼續閱讀直到最後。我有一份免費獎金給你。 --- 什麼是 Docker?它是如何運作的? ------------------- 正如我所說,Docker 是一個開源平台,使開發人員能夠在容器內自動部署和管理應用程式。 它提供了*一種將應用程式及其相依性打包到稱為容器的標準化單元中的方法,*該單元可以在任何相容的系統上執行,而無需擔心作業系統或底層基礎設施的差異。 身為開發人員或 DevOps 工程師,您應該了解以下幾個重要的 Docker 概念: **1. 容器化** Docker 利用容器化技術建立隔離的環境(稱為容器)來執行應用程式。容器是輕量級的,封裝了執行應用程式所需的應用程式程式碼、執行時間、系統工具、程式庫和相依性。 這使得應用程式能夠在不同的環境中一致地執行,確保無論底層系統如何,它們的行為都是相同的。 **2. Docker 映像** Docker 映像可作為建立容器的範本。它是一個只讀快照,包含應用程式程式碼和所有必要的依賴項。 Docker 映像是使用`Docker file`建立的,該文件是一個文字文件,指定建置映像的步驟。 `Dockerfile`中的每個步驟代表映像中的一個層,從而實現映像的高效儲存和共用。 **3.Docker引擎** Docker Engine是Docker的核心元件。它負責建置和執行基於Docker映像的容器。 Docker 引擎包括管理容器的伺服器和允許使用者與 Docker 互動的命令列介面 (CLI)。 **4. Docker 註冊表** Docker 映像可以儲存在登錄中,例如 Docker Hub 或私有註冊表。註冊表是`Docker`映像的集中儲存庫,可輕鬆地在不同系統之間共用和分發映像。開發人員可以從登錄中提取預先建置的映像,或推送自己的自訂映像供其他人使用。 **5. 容器生命週期** 為了執行應用程式, [Docker](https://medium.com/javarevisited/5-best-docker-courses-for-java-and-spring-boot-developers-bbf01c5e6542)從映像建立容器。容器是隔離的,有自己的檔案系統、流程和網路介面。 它們可以根據需要啟動、停止、暫停和刪除。 Docker 提供了一組命令和 API 來管理容器的生命週期,從而可以輕鬆擴展、更新和監控。 **6. 容器編排** 雖然[Docker](https://medium.com/javarevisited/why-every-developer-should-learn-docker-in-2023-ac27fac5fd6f)本身提供了容器管理功能,但它還可以與 Kubernetes 等容器編排平台無縫協作。 這些平台支援管理大型容器集群,處理負載平衡、擴展和跨多個主機的自動部署等任務。 總體而言, **Docker 利用容器化技術簡化了應用程式的打包、分發和執行過程。**它幫助開發人員實現應用程式的一致性、可移植性和可擴展性,使其成為現代軟體開發和部署工作流程中的熱門選擇。 這也是[ByteByteGo](https://bit.ly/3P3eqMN)的一個很好的圖表,它突出顯示了 Docker 的關鍵元件及其工作原理: [ ![Docker 是如何運作的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i8jbisa4dxd0k9tju7va.jpg)](https://bit.ly/3P3eqMN) --- 什麼是 Kubernetes?它是如何運作的? ----------------------- Docker 和 Kubernetes 就像兄弟一樣,經常被一起提及,但它們卻有很大不同。 [Kubernetes](https://medium.com/javarevisited/10-best-kubernetes-courses-for-developers-and-devops-engineers-94c35cd3a2fd)是一個開源容器編排平台,可自動執行容器化應用程式的部署、擴充和管理。 它**提供了一個框架,用於跨機器叢集執行和協調多個容器**,從而更輕鬆地管理複雜的分散式系統。 以下是我認為每個開發人員或 DevOps 都應該學習和了解的重要 Kubernetes 或 K8 概念: **1. 集群架構** Kubernetes 以叢集架構執行,由一個主節點和多個工作節點組成。主節點管理叢集並協調整體操作,而工作節點負責執行容器。 **2. Pod** Kubernetes 中的基本部署單元是 Pod。 Pod 是一個或多個容器的邏輯群組,這些容器位於同一位置並共享相同的資源,例如網路命名空間和儲存。 Pod 內的容器可以使用 localhost 相互通訊。 Pod 被視為臨時單元,可輕鬆建立、更新或終止。 **3. 副本集和部署** 副本集定義了在任何給定時間執行的相同 Pod 副本的所需數量。 它們透過自動管理和維護所需數量的 Pod 執行個體來確保高可用性和可擴充性。 部署是一種更高層次的抽象,可讓您以聲明方式管理和更新副本集,從而實現應用程式版本的無縫滾動更新和回滾。 **4. 服務** Kubernetes 服務提供穩定的網路端點來連接到一組 Pod。它們支援負載平衡並將 Pod 內的容器公開給其他服務或外部用戶端。 服務抽象化了底層的 Pod 實例,允許應用程式與其他元件進行通信,而無需擔心它們的動態特性。 **5. 標籤和選擇器** Kubernetes 使用標籤和選擇器來實現靈活、動態的物件分組和選擇。標籤是附加到 Pod、部署、服務和其他 Kubernetes 物件的鍵值對。 選擇器用於根據物件的標籤過濾和匹配物件,從而可以進行有針對性的操作並對相關資源進行分組。 **6. 縮放和自動縮放** Kubernetes 可讓您透過調整 pod 副本的數量來擴展應用程式。 Pod 水平自動擴展 (HPA) 是一項根據資源利用率指標(例如 CPU 或記憶體使用情況)自動擴展 Pod 副本數量的功能。 **7. 容器網絡** Kubernetes 也管理 Pod 和節點之間的網路。每個 Pod 都有自己的 IP 位址,Pod 內的容器可以使用`localhost`相互通訊。 Kubernetes 提供了**網路插件**,可以促進容器網路並實現跨 Pod 和叢集的通訊。 **8. 集群管理** Kubernetes 還提供廣泛的叢集管理功能,包括捲動更新、機密管理、設定管理和執行狀況監控。 它提供了一種聲明式方法來定義系統的所需狀態,使 Kubernetes 能夠持續監控實際狀態並將其與所需狀態進行協調。 **9. 貨櫃存放** Kubernetes 支援各種儲存選項,包括持久磁碟區和儲存類別。持久卷提供了一種將儲存與 Pod 生命週期分離的方法,從而實現跨 Pod 和容器重新啟動的資料持久化和共享。 透過抽象化*大規模管理容器的複雜性,Kubernetes 使開發人員能夠專注於應用程式邏輯*而不是基礎架構管理。 它提供了一個強大且可擴展的平台,用於部署和管理容器化應用程式,使其成為建置現代雲端原生系統的流行選擇。 這是一個很好的圖表,顯示了 K8 或 Kubernetes 的不同元件以及它們如何協同工作: ![什麼是 Kubernetes](https://miro.medium.com/v2/resize:fit:609/0*pRm7KUB_3307GXS2.png) --- Podman 是什麼?它是如何運作的? --------------- 現在您已經知道什麼是 Docker 和 Kubernetes,是時候看看另一個流行的工具 Podman,它通常被視為 Docker 的替代品。 Podman 是一個開源容器執行時間和管理工具,提供用於管理容器的命令列介面 (CLI)。 它旨在成為 Docker 的兼容替代方案,提供與 Docker 相容的 API,並允許熟悉 Docker 的用戶輕鬆過渡\*。 Podman 設計提供安全且輕量的容器體驗。 以下概述了 Podman 的工作原理以及您應該了解的重要 Podman 概念: **1. 容器運作時** Podman 作為容器執行時,這意味著它可以建立和執行容器。它使用相容於開放容器計劃 (OCI) 的容器格式,確保與其他容器執行時的兼容性,並允許 Podman 執行符合 OCI 的容器。 **2. CLI 相容性** Podman 的 CLI 旨在讓 Docker 用戶熟悉。它提供類似於 Docker CLI 的命令,讓使用者可以輕鬆管理容器、映像、磁碟區和網路。 這種相容性使開發人員和系統管理員可以更輕鬆地從 Docker 過渡到 Podman,而無需對其工作流程進行重大更改。 **3.無根容器** Podman 的一項顯著功能是它對無根容器的支援。它允許非 root 用戶無需特權存取即可執行容器。 這透過將容器與主機系統隔離並降低容器逃逸的風險來增強安全性。 **4. 容器管理** Podman 提供一系列管理功能,例如建立、啟動、停止和刪除容器。它支援網路配置,允許容器之間以及主機系統之間進行通訊。 Podman 還提供了管理容器磁碟區、環境變數和資源限制的選項。 **5. 容器鏡像** 與 Docker 一樣,Podman 依賴容器映像作為建立容器的基礎。它可以從各種容器註冊表(包括 Docker Hub)中提取和推送容器映像。 Podman 也可以使用 Dockerfile 在本機建置映像或從其他容器執行時匯入映像。 **6. Pod 支持** Podman 超越了單一容器,支援 Pod 的概念,類似 Kubernetes。 Pod 是一組共享相同網路命名空間和資源的容器。 Podman 讓使用者可以建立和管理 Pod,從而實現容器之間更複雜的部署和通訊模式。 **7. 與編排平台集成** 雖然 Podman 可以用作獨立的容器執行時,但它也可以與 Kubernetes 等容器編排平台整合。它可以充當 Kubernetes Pod 的容器執行時,允許使用者在 Kubernetes 叢集中利用 Podman 的功能和相容性。 **8. 安全焦點** Podman 非常重視安全性。它支援使用者命名空間映射等功能,將容器使用者ID映射到主機上的非root使用者ID,從而增強容器隔離。 Podman 還整合了 SELinux 和 seccomp 設定檔等安全增強技術,以提供額外的保護層。 Podman 旨在為 Docker 用戶提供無縫過渡,同時強調安全性和輕量級容器管理。 它提供相容性、靈活性和用戶友好的 CLI,對於尋求替代容器執行時的人來說是一個引人注目的選擇。 ![什麼是 Podman](https://miro.medium.com/v2/resize:fit:609/1*bFTJH7TCRebunX4CXhr7Uw.png) --- Docker、Kubernetes 和 Podman 之間有什麼區別? ----------------------------------- 以下是 Docker、Kubernetes 和 Podman 之間的主要區別,我對它們的不同點進行了比較,主要是這些工具提供的功能和功能,例如容器化和容器管理等。 **1. 容器引擎** Docker 主要是用於建置、執行和分發容器的容器執行時和引擎。另一方面,Kubernetes 是一個編排平台,旨在管理跨機器叢集的容器化應用程式。 Podman 是一個容器執行時間和管理工具,提供與 Docker 相容的 CLI 和容器執行時間。 **2. 容器格式** Docker 使用自己的容器格式,稱為 Docker 容器。 [Kubernetes](https://medium.com/javarevisited/7-free-online-courses-to-learn-kubernetes-in-2020-3b8a68ec7abc)可以使用多種容器格式,但 Docker 容器是最常見的選擇。 另一方面,Podman 使用相容於開放容器計劃 (OCI) 的容器格式,並且可以執行符合 OCI 的容器。 **3. 編排** Docker 擁有內建的編排工具 Docker Swarm,它允許管理一組用於執行容器的 Docker 節點。 另一方面,Kubernetes 提供了用於管理容器化應用程式的高級編排功能,包括擴充功能、負載平衡、自動化部署和自我修復。 Podman 沒有像 Docker Swarm 或 Kubernetes 這樣的內建編排功能,但它可以與 Kubernetes 或其他編排平台一起工作。 **4. 集群管理** Docker 本身不支援管理容器叢集。另一方面,Kubernetes 是專門為管理容器叢集而設計的,並提供擴展、升級、監控和管理容器化應用程式的功能。 Podman 本身不支援管理容器集群,但可以與 Kubernetes 或其他容器編排框架等外部工具一起使用。 **5. 安全** 對於安全性比較,Docker 提供了基本的隔離和安全功能,但其主要重點是執行單一容器。 Kubernetes 提供進階安全功能,例如網路策略、秘密管理和 RBAC。 另一方面, **Podman**專注於安全性,並提供使用者命名空間映射、seccomp 設定檔和 SELinux 整合等功能,以增強容器安全性。 **6. 使用者介面** 相較於 UI, [Docker](https://medium.com/javarevisited/10-free-courses-to-learn-docker-and-devops-for-frontend-developers-691ac7652cee)提供了使用者友善的 CLI 和基於 Web 的圖形介面(Docker Desktop)來管理容器。 Kubernetes 有一個名為`"kubectl"`的 CLI 工具和一個基於 Web 的儀表板(Kubernetes Dashboard),用於管理容器和叢集。 同時,Podman 提供了類似 Docker CLI 的 CLI,可以與`Cockpit`等第三方工具一起使用,進行基於 Web 的管理。 而且,如果您喜歡表格,這裡有一個很好的表格,我以表格格式列出了*Docker、Kubernetes 和 Podman 之間的所有差異*: ![docker、kubernetes 和 podman 之間的區別](https://miro.medium.com/v2/resize:fit:609/1*Q4wN6VE6C_0LoWc1PqgTzg.png) 這些是*Docker、Kubernetes 和 Podman 之間的根本區別*,它們在容器化生態系統中服務於不同的目的。 --- ### 系統設計訪談資源: 而且,這裡列出了最佳系統設計書籍、線上課程和練習網站,您可以查看這些內容,以便更好地為系統設計面試做好準備。這些課程中的大多數也回答了我在這裡分享的問題。 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) 這就是**Docker、Kubernetes 和 Podman 之間的差異。**總之,Docker 是一個用於建立和管理容器的流行容器化平台,Kubernetes 是一個用於大規模管理容器化應用程式的容器編排平台,而`Podman`是一個具有不同架構的容器化工具,可以用作Docker的直接替代品在很多情況下。 這些工具都有不同的用途,它們都可以一起使用,為開發人員提供全面的容器化解決方案,但更重要的是每個開發人員和 DevOps 都應該了解這些工具。 ### 獎金 正如承諾的,這是給你的獎金,一本免費的書。我剛剛找到一本新的免費書籍來學習分散式系統設計,您也可以在 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%2Fhrc1jn751mzs4ru91zt3.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%2Fhrc1jn751mzs4ru91zt3.png) 謝謝 --- 原文出處:https://dev.to/somadevtoo/difference-between-docker-kubernetes-and-podman-for-system-design-interview-3an6

不要沒事就「重構」程式碼

這是很久以前有人給我的建議。不幸的是,我不太記得是誰,所以我無法正確歸因(儘管他們很可能也在某個地方聽到)。但我決定重新分享這件事。 **什麼是重構?**我確信我們可以找到多種定義。但在現代軟體開發過程中,它通常成為任何不加入、修改或刪除功能的程式碼變更的代名詞。換句話說,這是一部非產品作品。實際上,它常常成為一個模糊的術語,並導致產品利益相關者和開發團隊之間關係緊張。 我們當中誰沒有在狀態會議上聽過這樣的話:「昨天我花了大部分時間圍繞 X 重構程式碼」?我知道我做到了。至少,我可能不只一次說過這樣的話。這是什麼意思?你到底做了什麼?這隱藏在「我重構」一詞背後。 「我做了你無法理解的重要技術工作」是另一種表達方式。 而這正是「重構程式碼」的問題所在。在許多情況下,這意味著做一項非常重要的工作,但這與幾乎偷懶沒有區別,例如無緣無故地重命名變數。 這就是我所說的「不要重構程式碼」的意思:在談論你所做的、正在做的或計劃做的事情時使用不同的字詞。不要“重構”。相反,嘗試這些: - 我讓程式碼效能更高(辨識了N+1,發現處理大量資料效率低) - 我使程式碼更加開放以進行更改(主要應該透過預測我們現在將更頻繁地更改此區域來證明是合理的) - 我使程式碼更具防禦性(如果使用不正確的參數執行,則會提前失敗並發出明確的訊息 - 因為其他團隊錯誤地使用它並導致微妙的錯誤) - 我加入了針對未經測試區域的測試(好的理由:因為它最近失敗了幾次;壞的理由:增加我們的任意程式碼覆蓋率指標) - 我加入了更多的日誌記錄/儀器(這樣我們可以更好地了解正在發生的事情) - 我更改程式碼以滿足我們新的樣式指南(因為我們會經常更改它) 這樣的溝通不僅可以讓其他人更容易理解更改的內容,還可以幫助您確定您計劃進行的更改是否真的會產生影響。無法隱藏在「重構」術語後面也有助於使變更更加集中,並且更容易為同事審查。 --- 原文出處:https://dev.to/katafrakt/dont-refactor-the-code-igk

我發現的很酷的 VSCode 擴展

最近,我重新審視了去年放棄的 React 副專案。在此過程中,我發現了一些重要的 VSCode 擴展,這些擴展顯著提高了我作為 React 開發人員的工作效率。此清單的唯一規則是所有這些擴充都是**React 特定的**。雖然它們可能對其他目的有用,但它們的主要焦點是 React。 那麼,讓我們深入了解一下。 ![我們走吧](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/opxot6h4u0sxgm9zp3yq.gif) --- 這些擴充功能將透過為您提供片段來提供幫助。***程式碼片段***是預先定義的程式碼片段,只需一次按鍵(*大多數情況下按 Tab 鍵*)即可擴充為完整的程式碼區塊。這些片段的範圍可以從單行到整個文件。透過使用片段,您可以將整個檔案壓縮為簡短的縮寫,使您的編碼體驗更加順暢。 ### **1.ES7 React/Redux/GraphQL/React-Native 片段** ![ES7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqxpf64yy8a7zpfcpgcg.png) 此擴充功能提供了 React、Redux、GraphQL 和 React Native 的全面片段集合。這些片段可讓您快速產生常用的程式碼結構,從而顯著加快您的開發流程。例如: - `rcc`建立一個 React 類別元件骨架。 - `rfc`產生一個 React 功能元件。 - `rnfce`片段可協助您快速設定具有預設匯出的 React Native 元件。 - *這個清單是無窮無盡的*。[在這裡](https://github.com/r5n-dev/vscode-react-javascript-snippets/blob/HEAD/docs/Snippets.md)探索 這些片段是高度可自訂的,涵蓋廣泛的用例,使您的開發更加高效。 ### **2.React Hooks 片段** ![鉤子](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ulwbak9qamtc3846llm.png) React Hooks 程式碼片段擴充功能透過提供特定的縮寫來簡化在 React 中加入鉤子: - `ush` for `useState`初始化一個狀態變數。 - `ueh` for `useEffect`設定副作用。 - `uch` for `useContext`存取上下文。 這個擴充特別有用,因為它專注於 React 的 hooks API,這是功能元件的核心功能。它可以幫助您快速實現鉤子,而不必每次都記住確切的語法。 ### **3.VSCode React 重構** ![重構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tucj03fncc4btoltsxm4.png) VSCode React Refactor 可讓您透過將部分程式碼提取到單獨的元件中來重構程式碼。當您的元件變得太大並且您希望將其分解為更小、更易於管理的部分時,這尤其有用。例如: - 選擇一段 JSX 程式碼。 - 右鍵單擊並選擇“重構”。 - 將其提取到新元件中。 此擴充功能支援 TypeScript 並確保正確導入和使用提取的元件,從而簡化您的重構過程。 ### **4. 將 JSON 貼為程式碼** ![json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cflc9kcid3tvfitmlzg8.png) 將 JSON 貼上為程式碼可讓您將 JSON 物件轉換為程式碼。這在處理傳回 JSON 回應的 API 時特別有用。例如: - 複製 JSON 物件。 - 使用命令選項板選擇“將 JSON 貼上為程式碼”。 - 將 JSON 轉換為具有類型定義的 JavaScript 或 TypeScript 程式碼。 此擴充功能有助於快速將 JSON 資料轉換為可用的程式碼結構,從而節省時間並減少錯誤。 ### **5.SVG圖庫** ![svg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ioelbe4mk13mk7y2ld0.png) SVG Gallery 是用於管理專案中的 SVG 檔案的絕佳工具。它允許您直接在 VSCode 中預覽 SVG 文件,這在處理多個 SVG 資源時特別方便。特點包括: - 在編輯器中預覽 SVG。 - 將 SVG 內容複製為 React 元件。 - 有效地組織和管理您的 SVG 資源。 此擴充簡化了使用 SVG 檔案的流程,讓您更輕鬆地在 React 專案中整合和管理向量圖形。 --- 雖然上述建議來自我的主觀觀點和個人對這些擴充功能的體驗,但我強烈建議您親自安裝和體驗它們。每個開發人員都有獨特的需求和工作流程,這些擴充功能可能會以不同的方式適合您的專案。 我鼓勵您分享一些可以提高您的工作效率的很酷的擴充功能。請記住,這些並不是唯一的擴展,我一直在尋找新工具來改善我的工作流程。 *這給我們帶來了一個發人深省的問題:**我們是否透過嚴重依賴這些擴充功能而創造了懶惰的程式設計師,或者我們是否真正提高了生產力和效率?**分享您的想法和經驗。讓我們討論一下這些工具是更好發展的拐杖還是催化劑。* 直到下次! ![乾杯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ruau6ij81iaqqoyjlzm1.jpeg) --- 原文出處:https://dev.to/mitchiemt11/cool-vscode-extensions-that-that-ive-discovered-12mg

給中級開發人員的建議

序幕 == 我五年前寫了[這個博客](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

程式設計師必須具備的7個習慣!

介紹 -- 作為一名程式設計師,您知道您的工作需要高度專注,因此往往會佔用您大量的時間。是的,這也發生在我身上,我花了很多時間做任務,但有時結果並沒有達到預期。我意識到我從工作經驗和同事的見解中獲得了一些東西,並且有一本書很有趣並且對改善我的習慣非常有幫助。 您是否知道我們每天都遵循模式和習慣來生活,這些習慣會影響我們目標的結果。所以如果你想改變你的生活並實現你想要的,你要做的第一件事就是改變你的習慣。史蒂芬‧柯維在他的***《高效能人士的七個習慣》一***書中說:「*我們看待世界的方式完全基於我們自己的看法。* 」 讓我們先看看與我們日常活動相關的較小事物,而不是著眼於如此之大的世界。是的,沒錯,我想從我作為一個程式設計師的角度來分享。作為程式設計師,您應該了解一些提高生產力的習慣。其中一些內容也是基於我的經驗,所以結果可能會有所不同,但相信我,如果你練習得好,這將會很有用。好的,讓我們開始吧! **1. 積極主動** 柯維在他的書中描述了我們生活中存在的兩類人。**關注圈**是一個包含我們無法控制的事物的圈。同時,較小的圓圈是**影響圈**,其中包含我們可以控制的東西。 ![主動式和被動式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p50j7r9vgw6hhipidjz2.png) 基於這兩個圈子,**反應型的**人會更多地考慮**關注圈**,而**主動型的**人會更多地考慮**影響圈**。程式設計師也是一樣,我們中間一定有兩類人。 有**一些反應型程式設計師**忙於處理辦公室條件、公司財務等無法控制的事情,他們甚至認為自己的職業生涯可以透過影片《*如何在三個月內成為最好的程式設計師*》來決定。另一方面,也有一些**積極主動的程式設計師**選擇練習,嘗試幾次面試和比賽,以打開成為程式設計師或任何他們夢想的工作的機會。 積極主動的人知道他們需要了解外在事物,但他們才是對自己的職業負責的人。換句話說,要積極主動,你可以更專注於從自己內部尋找靈感,並且可以控制它,而不會忽視自己之外的重要事物,而不是僅僅期望別人給你一個「*神奇食譜*」。 **2.以終為始** 我們中的許多人一生都在隨波逐流,甚至不知道自己的目的。因此,我們所擁有的只是希望,這無論如何都不是一個好的策略。史蒂芬·柯維說「以終為始」換句話說,在做任何事情時,包括啟動一個專案,你必須確定明確的成功衡量標準以及實現這些目標的計劃。 ![開始就要考慮如何結束](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1bbrkhtnd78rarqcfd8.png) 如果您將其應用於編程,那麼每當您開始一個新專案時,您都會花時間了解最終產品。要建構的功能的功能和非功能要求是什麼? 我記得有人說過軟體工程是做出權衡的藝術。很少有正確和錯誤的答案,而是確定不同類型的設計以及特定情況下的優點和缺點的問題。不管你相信與否,我的經驗是,花 30 分鐘仔細規劃可以為你節省 10 多個小時的程式設計時間。 > 「人們比以往任何時候都更加努力工作,但由於缺乏清晰度和遠見,他們並沒有取得多大進展。本質上,他們是在用盡全力推一根繩子。史蒂芬‧柯維博士 當然,這並不容易,因為每個計劃都可能出錯,我也陷入過幾次。但這仍然比根本不計劃任何事情要好得多。 **3、要事第一** 能夠選擇什麼是重要的、什麼是不重要的也是一種有效的習慣。透過根據您的需求對您的興趣進行排序,您將能夠確定首先完成的工作的優先順序。 這個習慣與時間管理密切相關。柯維建議我們根據他建立的四個像限(他稱之為艾森豪威爾矩陣)來做主要事情。 ![艾森豪威爾矩陣](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hv4j1roh5p3f4gaw52uc.png) 以前我認為這個象限對於我的任務來說並不那麼重要。事實證明,這一點常常被大多數程式設計師所忽略。當我擔任軟體工程師時,我不斷受到需要解決的錯誤的轟炸。另一方面,我也有長期的專案需要完成。 當你承受如此大的壓力時,你就會忘記學習。因此,如果你的程式碼有問題,你只想去谷歌或使用人工智慧並複製貼上解決方案,而無需真正理解它。是的,真正了解問題的原因對學習來說很重要,但並不迫切。對許多程式設計師來說,隨著職業的進步,學習就會停止。這就是為什麼你需要專注於屬於這個象限的任務,並為你的長期成功安排特定的時間。換句話說,優先考慮並實現最重要的目標,而不是不斷地對緊急情況做出反應。 **4.雙贏思維** 一個人的**收穫**就是另一個人的**損失**——這個想法在我們的大腦中非常熟悉,可能是因為我們經常觀看的各種比賽和體育賽事。在這本書中,柯維博士認為培養「豐富心態」很重要。也就是說,相信有足夠的資源和機會讓每個人都獲得成功。這種心態對於軟體工程師的職業生涯成功至關重要。我們與其他工程師和其他工作職能人員(例如資料科學和產品管理)一起工作。 ![雙贏協議](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1thqzuw744a9usc2ezo.png) 能夠有效協作是您需要具備的主要技能之一。因此,能夠超越個人職業目標並為團隊擁有雙贏的心態非常重要。不只是透過讓別人輸來贏得自己,或是屈服於別人讓他們贏,甚至讓別人輸,因為我們也輸了。 習慣了總是想著能夠贏得多方的支持,會讓我們總是努力取得最好的結果。不僅如此,從長遠來看,這也極大地影響了我們與他人的關係。 為了建立長期良好的關係,我們需要與許多人建立關係。透過**雙贏思維**,這將有助於我們在未來建立良好的聲譽或形象,並使我們的工作從長遠來看更加有效。 **5. 首先尋求理解,然後被理解** 你是那種在給別人機會之前就忙著徵求自己回饋的人嗎?這不是史蒂芬·柯維所推薦的。 ![先尋求理解,再尋求被理解](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bg3uigm6p7xm7h9stc7v.png) 為了被別人理解,我們首先要做的就是**先理解別人**。高效能的人能夠具有極大的同理心,並透過理解他人來尊重他人。 但這如何適用於程式設計師呢?除了口頭交流之外,工程師還使用程式碼來相互交流。高效率的程式設計師了解**同理心**在編碼中的重要性。他們優先考慮程式碼的清晰度,以確保其他人(包括將來的自己)可以輕鬆理解和維護程式碼。 除了其他工程師之外,程式設計師還透過他們的產品與最終用戶進行交流。高效率的程式設計師會設身處地為最終使用者著想,優先考慮使用者體驗。他們預測用戶需求,設計可交付的介面,並建立錯誤訊息來引導用戶而不是讓他們感到困惑。 **6. 協同增效** 能夠與他人很好地協同工作的人將是高效的人。透過良好的關係和協作,您可以建立比僅依靠自己更好的解決方案。數學上1 + 1 = 2。 ![協同作用](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lb8uq52jfzpkl28kyp32.png) 柯維博士在他的書中強調了欣賞差異並利用差異創造一個大於各個部分總和的整體的重要性。因此,關鍵在於充分發揮每個團隊成員的作用,創造出使用者喜愛的產品。高效的程式設計師採用**協作**編碼實踐,例如程式碼審查、配對程式設計和其他知識共享。透過結合個人技能和見解,團隊可以建立更強大、更有效率和創新的產品。 儘管這並不容易,尤其是對於程式設計師來說,他們大多數都是單獨工作,但透過習慣這一點,我們不僅可以成為獨立的人物,而且可以成為可以與任何人一起工作和良好協作的人。 **7.磨利鋸子** 高效率的人會在生活中不斷實踐事物,從而不斷進步、良好發展。科維說,我們在生活中必須磨練四件主要的事情:***身體、心靈、精神和精神***。是的,總的來說,這對於任何領域的生活來說都是非常重要的。但讓我們試著專注在更具體的事情上。 ![敏銳的發現](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2tj8no1yezmseadugi4.png) 對程式設計師來說,這是最重要的習慣。為了理解這個習慣,我們假設有兩個工人正在嘗試砍柴。第一個工人是個年輕人,整個8小時的輪班時間裡,他一直不停地砍柴。第二位工人是一位年紀較大的男子,每小時需要休息 10 分鐘,在休息期間他會花時間磨鋸子。如果你認為年長的人會砍更多的木頭,那麼你就已經理解了這個習慣。 作為一名程式設計師,你將面臨如此多的新技術。高效率的程式設計師了解**持續學習**的重要性。磨礪鋸子需要投入時間來獲取新技能、了解產業趨勢以及探索新技術。高效率的程式設計師必須透過練習、參加會議、參加程式設計社群等方式騰出時間進行專業發展。這種習慣可以幫助我們適應科技進步。 **結論** 有時候,在我們不知不覺中,壞習慣或多或少影響我們的生活,讓我們的生活變得低效。然而,一個習慣如果持續太久,就很難打破。 如果我們想要改善我們的生活,從改變我們的觀點到改變我們的習慣,這就是我們需要理解的。實踐史蒂芬‧柯維所說的這七個習慣將幫助我們更有效、更有意義地改變我們的生活。 僅僅了解這些習慣是不夠的,我們還必須全部應用它們,因為每一點都同樣重要且相互關聯。因為只有過有效的生活,我們才能走上更大成功的道路。 **參考** [富蘭克林科維](https://www.franklincovey.com/the-7-habits/) [高效能人士的七個習慣](https://books.google.co.id/books?id=36V_PAAACAAJ&hl=id&source=gbs_book_other_versions_r&cad=1) --- 原文出處:https://dev.to/tentanganak/7-habits-that-programmers-must-have-1dfj

介紹我們的第一個電腦科學挑戰!

為了慶祝驕傲月,我們很高興推出我們的首個[電腦科學挑戰賽](https://dev.to/challenges/cs),以紀念艾倫·圖靈,這位傑出的同性戀英國數學家和密碼分析師,被廣泛認為是「電腦科學之父」。他的生日是 6 月 22 日,就在我們挑戰的中間!那麼就讓我們慶祝一下吧。 本次挑戰只有一個簡單的寫作提示和一位獲勝者。我們的獲勝者將獲得 DEV 專屬榮譽徽章和[DEV 商店](https://shop.forem.com)贈送的禮物。有效提交的參與者將獲得完成徽章。 我們的提示 ----- 我們將帶回**一位元組解釋器**! 您的挑戰是**用 256 個或更少的字元解釋電腦科學概念。** 您可以選擇任何概念(即“大 O 表示法”、“遞歸”、“P 與 NP 問題”)並簡潔地解釋它是什麼以及為什麼它相關。您有 256 個字元(比一條推文還少)來表達您的觀點,因此挑戰在於保持簡單。 256 個字元對於其中一些概念來說少得可笑,這就是它的挑戰! ***您願意一邊編碼一邊有機會贏得現金獎勵嗎?**那就來看看獎金池為 5,000 美元的[Twilio 挑戰賽](https://dev.to/devteam/join-us-for-the-twilio-challenge-5000-in-prizes-4fdi)吧!* {% 卡 %} 如何參與 ---- 為了參加電腦科學挑戰賽,您需要使用以下提交範本發布貼文: {% cta hhttps://dev.to/new?prefill=---%0Atitle%3A%20%0Apublished%3A%20%0Atags%3A%20devchallenge%2C%20challenge%2C%20computerscience%2C%20beginners%0Acschallenge%2C%20computerscience%2C%20beginners%0Acschallenge%2C%20computerscience%2C%20beginners%0Acschallenge%2C%20computerscience%2C%20beginners%0Acschallenge%2C%20computerscience%2C%20beginners%0Acschallenge%2C%20computerscience%2C%20beginners%0Acschallenge%2C%20computerscience%2C%20beginners。 ---%0A%0A*這%20是%20a%20submission%20for%20%5BDEV%20Computer%20Science%20Challenge%20v24.06.12%3A%20One%20Byte%20Explainer%5D(%3A. to %2F挑戰%2Fcs)。* %0A%0A%23%23%20解釋%0A%0A%3C!--%20解釋%20a%20計算機%20科學%20概念%20in%20256%20字元%20或%20less。 -%3E%0A%0A %23%23%20Additional%20Context%0A%0A%3C!--%20Please%20share%20any%20additional%20context%20you%20think%20the%20judges%203% %20as%20it%20relates% 20至%20您的%20One%20Byte%20解釋者。 %20one%20member%20至%20發表%20the%20submission%20and% 20credit%20teammates%20by%20listing%20their%20DEV%20usernames%20directly%20in%20the%20DEV%20usernames%20directly%20in%20the%20the%20post%. 3E%0A%0A%3C!--%20Don%27t%20forget% 20to%20add%20a%20cover%20image%20to%20your%20post%20(如果%20you%20)。 %0A%0A%3C! 一字節解釋提交模板 {% 結束%} {% 結束卡 %} 請在提交之前查看我們的[評審標準、規則、指南和常見問題解答頁面,](https://dev.to/challenges/cs)以便您了解我們的參與指南和[官方競賽規則](https://dev.to/page/cs-challenge-v24-06-12-contest-rules)(例如資格要求)。 重要的日子 ----- - 6 月 12 日:電腦科學挑戰賽開始! - 6 月 23 日:提交截止時間為太平洋夏令時間晚上 11:59 - 6 月 25 日:得獎者公佈 “計算機科學之父” --------- 有興趣了解更多關於阿蘭·圖靈的資訊嗎?查看這些帖子,了解他對電腦科學的成就和貢獻: {% 嵌入 https://dev.to/devteam/celebating-dev-pride-alan-turing-52eh %} {% 嵌入 https://dev.to/devteam/dev-pride-alan-turing-the-father-of-modern-computing-39in %} {% 嵌入 https://dev.to/devteam/happy-110th-birthday-alan-turing-3m6o %} {% 嵌入 https://dev.to/devteam/happy-111th-birthday-alan-turing-5271 %} 我們希望您喜歡這個寫作挑戰!有疑問嗎?請在下面詢問他們。 祝你好運,編碼愉快! --- 原文出處:https://dev.to/devteam/introducing-our-first-computer-science-challenge-hp2

從 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&amp;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

Git 分支策略指南

自 2008 年以來,作為一名開發人員,我親眼目睹了版本控制系統的演變。從 SVN 開始,最終過渡到 Git,我已經看到這些工具如何在我們的日常工作流程中變得不可或缺。讓我分享一個詳細的分支策略,該策略已被證明在管理程式碼庫、確保穩定性和促進協作方面非常有效。 #### 主要分行 - **`main` (或`master` )分支:** - 生產就緒的程式碼。 - 僅包含經過徹底測試且穩定的程式碼。 - 直接提交受到限制;僅允許在程式碼審查和批准後透過拉取請求 (PR)。 - **`develop`分支:** - 反映當前開發狀態的最新程式碼庫。 - 所有功能和修復都在合併到`main`之前整合到此分支中。 - 作為所有新功能分支的基礎。 #### 支持分行 - **特色分支:** - **命名約定:** `feature/<feature-name>` - **建立自:** `develop` - **目的:**用於開發新功能或增強功能。 - **合併:**完成並測試後,合併回`develop` 。 - **錯誤修復分支:** - **命名約定:** `bugfix/<issue-id>` - **建立自:** `develop` (或`release` ,如果修復是針對即將發布的版本) - **目的:**修復開發過程中發現的錯誤。 - **合併:**修復後合併回`develop` (或`release` ,如果適用)。 - **發布分支:** - **命名約定:** `release/<version-number>` - **建立自:** `develop` - **目的:**為新的生產版本做好準備。 - **活動:**最終測試、錯誤修復和準備發行說明。 - **合併:**準備好後合併到`main`並`develop` 。 - **修補程式分支:** - **命名約定:** `hotfix/<issue-id>` - **建立自:** `main` - **目的:**用於需要直接投入生產的緊急修復。 - **合併:**一旦應用,就合併到`main`和`develop` 。 #### 分行工作流程 1. **功能開發:** - 使用`feature/<feature-name>`從`develop`建立分支。 - 實現該功能,提交變更並將分支推送到儲存庫。 - 開啟拉取請求以將功能分支合併到`develop`中。 - 進行程式碼審查,執行必要的測試,並將變更合併到`develop`中。 2. **錯誤修復:** - 使用`bugfix/<issue-id>`從`develop`建立一個分支。 - 修復錯誤、提交變更並推送分支。 - 開啟拉取請求以將 bugfix 分支合併到`develop`中。 - 經過審查和測試後,將變更合併到`develop`中。 3. **發布準備:** - 使用`release/<version-number>`從`develop`建立一個分支。 - 執行最終測試,修復所有最後一刻的錯誤並更新文件。 - 準備好後,將發布分支合併到`main`分支和`develop` 。 4. **修補程式:** - 使用`hotfix/<issue-id>`從`main`建立一個分支。 - 應用修復、提交變更並推送分支。 - 開啟拉取請求以將修補程式分支合併到`main`中。 - 將變更合併到`develop`中,以將修復包含在正在進行的開發中。 #### 最佳實踐 - **定期合併:**定期`develop`合併到功能分支中,以保持更新並避免整合問題。 - **程式碼審查:**在合併任何分支之前進行強制性程式碼審查,以確保品質和遵守標準。 - **自動化測試:**實施與自動化測試的持續集成,以儘早發現問題並保持程式碼品質。 - **文件:**記錄所有更改,包括程式碼中的註釋、更新日誌和全面的提交訊息。 [揭秘高級 Git 指令:簡單指南](https://dev.to/amit_k_812b560fb293c72152/demystifying-advanced-git-commands-a-simple-guide-1lpj) --- ### SVN 與 Git 比較 #### SVN(顛覆) - **集中版本控制:** SVN依賴中央伺服器來儲存專案文件的所有版本。 - **提交結構:**更改直接提交到中央儲存庫。 - **分支:**分支通常在伺服器上建立,分支操作可能很慢並且佔用資源。 - **合併:**與 Git 相比,合併可能更複雜且效率更低。 #### git - **分散式版本控制:** Git 允許每個開發人員擁有整個專案歷史記錄的本機副本。 - **提交結構:**更改首先在本地提交,然後可以推送到遠端儲存庫。 - **分支:**分支輕量且快速,鼓勵使用功能分支。 - **合併:** Git 的合併功能更先進,可以更輕鬆地整合來自不同分支的變更。 --- 我希望本指南對您有所幫助,就像自從 Git 成為我的日常夥伴以來它對我的幫助一樣。快樂編碼! --- --- 原文出處:https://dev.to/ak_23/branching-strategy-guide-24d6

JavaScript 去抖動綜合指南:提高程式碼效率

透過實際範例和技巧了解如何在 JavaScript 中實現去抖動。掌握去抖功能並提升您的網路效能。 在這份綜合指南中,我們將探索 JavaScript 中的去抖動,了解其重要性,並學習如何有效地實現它。無論您是初學者還是經驗豐富的開發人員,掌握去抖動都可以顯著提高您的網路效能。 去抖動是一種程式設計實踐,用於確保耗時的任務不會頻繁觸發,從而提高效能和使用者體驗。它在視窗大小調整、按鈕單擊或表單輸入事件等需要控制多個快速事件的場景中特別有用。 請訂閱我的 [YouTube 頻道](https://www.youtube.com/@DevDivewithDipak?sub\_confirmation=1)來支援我的頻道並獲取更多 Web 開發教學。 ### 什麼是去抖動? 去抖是一種限制函數執行速率的技術。當多個事件快速連續觸發時,去抖動功能將確保只有係列中的最後一個事件在指定的延遲後觸發函數執行。 ### 為什麼要使用去抖動? - **效能最佳化**:透過減少呼叫函數的次數來防止效能問題。 - **增強的使用者體驗**:避免重複操作的混亂,提供更流暢的體驗。 - **網路效率**:與即時搜尋輸入欄位等事件處理程序一起使用時,減少不必要的網路請求。 ### 去抖動如何運作 想像一下,使用者在搜尋框中輸入內容,每次按鍵都會觸發 API 呼叫。如果沒有去抖,每次擊鍵都會導致新的 API 呼叫,從而使網路充滿請求。透過去抖動,只有使用者停止輸入指定持續時間後的最終輸入才會觸發 API 呼叫。 ### 在 JavaScript 中實作去抖動 這是去抖函數的簡單實作: ``` function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } ``` ### 使用範例 讓我們看看如何在現實場景中使用`debounce`函數: ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Debouncing Example</title> </head> <body> <input type="text" id="searchBox" placeholder="Type to search..."> <script> const searchBox = document.getElementById('searchBox'); function fetchSuggestions(query) { console.log('Fetching suggestions for:', query); // Simulate an API call } const debouncedFetchSuggestions = debounce(fetchSuggestions, 300); searchBox.addEventListener('input', (event) => { debouncedFetchSuggestions(event.target.value); }); function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } </script> </body> </html> ``` 在這個例子中: - 輸入欄位捕獲使用者的輸入。 - `fetchSuggestions`函數的去抖延遲為 300 毫秒。 - 當使用者鍵入時,將呼叫`debouncedFetchSuggestions`函數,確保僅在使用者停止鍵入 300 毫秒後才執行`fetchSuggestions` 。 ### 結論 去抖動是一種簡單但強大的技術,可優化 Web 應用程式的效能。透過控制函數執行的速率,它有助於減少不必要的計算並改善整體用戶體驗。無論您是處理搜尋輸入、調整視窗大小還是處理其他快速事件,去抖動都是 JavaScript 武器庫中的一個有價值的工具。 *追蹤我,以獲得更多有關 Web 開發的教學課程和技巧。歡迎在下面留下評論或問題!* ### 關注並訂閱: - **網址**:\[Dipak Ahirav\] (https://www.dipakahirav.com) - **電子郵件**:[email protected] - **Instagram** : [devdivewithdipak](https://www.instagram.com/devdivewithdipak) - **YouTube** :\[devDive 與 Dipak\](https://www.youtube.com/@DevDivewithDipak?sub\_confirmation=1) - **領英**:[迪帕克·阿希拉夫](https://www.linkedin.com/in/dipak-ahirav-606bba128) --- 原文出處:https://dev.to/dipakahirav/understanding-debouncing-in-javascript-5g30

僅使用 HTML 和 CSS 建立側邊欄選單

如果您是 Web 開發新手,您可能在不同網站上看過[側邊欄](https://www.codingnepalweb.com/category/sidebar-menu/)。您是否想知道它們是如何僅使用 HTML 和 CSS 建立的?僅使用 HTML 和 CSS 製作側邊欄是學習網頁設計基礎知識和獲得實務經驗的好方法。 在這篇文章中,我將指導您僅使用[HTML](https://www.codingnepalweb.com/?s=html)和[CSS](https://www.codingnepalweb.com/category/html-and-css/)建立響應式側邊欄。最初,側邊欄將被隱藏,僅顯示每個連結的圖示。但是,將滑鼠懸停在側邊欄上將平滑展開以顯示與每個圖示關聯的連結。 為了建立這個側邊欄,我們將使用基本的 HTML 語意元素,例如`<aside>` 、 `<ul>` 、 `<li>`和`<a>`以及常見的 CSS 屬性來設定其樣式。這是一個簡單的專案,因此您應該毫無困難地遵循這些步驟或理解程式碼。 HTML 和 CSS 中的響應式側邊欄選單影片教學 ------------------------- https://www.youtube.com/watch?v=VU74s-XAn7M 如果您喜歡從影片教學中學習,上面的 YouTube 影片是一個很好的資源。在本影片中,我解釋了每一行程式碼並提供了資訊豐富的註釋,以使建立 HTML 側邊欄的過程易於遵循,尤其是對於初學者而言。 但是,如果您喜歡閱讀部落格文章或需要此專案的逐步指南,您可以繼續閱讀這篇文章。 在 HTML 和 CSS 中建立響應式側邊欄的步驟 ------------------------- 若要僅使用 HTML 和 CSS 建立響應式側邊欄,請按照以下簡單的逐步說明進行操作: - 首先,建立一個具有任何您喜歡的名稱的資料夾。然後,在其中建立必要的文件。 - 建立一個名為`index.html`的檔案作為主檔案。 - 為 CSS 程式碼建立一個名為`style.css`檔案。 - 最後,下載[Images](https://www.codingnepalweb.com/custom-projects/simple-sidebar-menu-html-css-only-images.zip)資料夾並將其放置在您的專案目錄中。該資料夾包含該側邊欄專案所需的所有圖像。 首先,將以下 HTML 程式碼新增至您的`index.html`檔案: 此程式碼包含具有不同語意標籤(如`<aside>` 、 `<ul>` 、 `<li>`和`<a>`的基本HTML 標記,用於建立我們的側邊欄佈局。 ``` <!DOCTYPE html> <!-- Coding By CodingNepal - www.codingnepalweb.com --> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Sidebar Menu HTML and CSS | CodingNepal</title> <!-- Linking Google Font Link For Icons --> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" /> <link rel="stylesheet" href="style.css" /> </head> <body> <aside class="sidebar"> <div class="sidebar-header"> <img src="images/logo.png" alt="logo" /> <h2>CodingLab</h2> </div> <ul class="sidebar-links"> <h4> <span>Main Menu</span> <div class="menu-separator"></div> </h4> <li> <a href="#"> <span class="material-symbols-outlined"> dashboard </span >Dashboard</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> overview </span >Overview</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> monitoring </span >Analytic</a > </li> <h4> <span>General</span> <div class="menu-separator"></div> </h4> <li> <a href="#" ><span class="material-symbols-outlined"> folder </span>Projects</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> groups </span>Groups</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> move_up </span>Transfer</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> flag </span>All Reports</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> notifications_active </span >Notifications</a > </li> <h4> <span>Account</span> <div class="menu-separator"></div> </h4> <li> <a href="#" ><span class="material-symbols-outlined"> account_circle </span >Profile</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> settings </span >Settings</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> logout </span>Logout</a > </li> </ul> <div class="user-account"> <div class="user-profile"> <img src="images/profile-img.jpg" alt="Profile Image" /> <div class="user-detail"> <h3>Eva Murphy</h3> <span>Web Developer</span> </div> </div> </div> </aside> </body> </html> ``` 接下來,將以下 CSS 程式碼新增至您的`style.css`檔案中,以使您的側邊欄實用且具有視覺吸引力。請隨意嘗試不同的 CSS 屬性,例如顏色、字體、背景等,以使您的側邊欄更具吸引力。 ``` /* Importing Google font - Poppins */ @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"); * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body { min-height: 100vh; background: #F0F4FF; } .sidebar { position: fixed; top: 0; left: 0; height: 100%; width: 85px; display: flex; overflow-x: hidden; flex-direction: column; background: #161a2d; padding: 25px 20px; transition: all 0.4s ease; } .sidebar:hover { width: 260px; } .sidebar .sidebar-header { display: flex; align-items: center; } .sidebar .sidebar-header img { width: 42px; border-radius: 50%; } .sidebar .sidebar-header h2 { color: #fff; font-size: 1.25rem; font-weight: 600; white-space: nowrap; margin-left: 23px; } .sidebar-links h4 { color: #fff; font-weight: 500; white-space: nowrap; margin: 10px 0; position: relative; } .sidebar-links h4 span { opacity: 0; } .sidebar:hover .sidebar-links h4 span { opacity: 1; } .sidebar-links .menu-separator { position: absolute; left: 0; top: 50%; width: 100%; height: 1px; transform: scaleX(1); transform: translateY(-50%); background: #4f52ba; transform-origin: right; transition-delay: 0.2s; } .sidebar:hover .sidebar-links .menu-separator { transition-delay: 0s; transform: scaleX(0); } .sidebar-links { list-style: none; margin-top: 20px; height: 80%; overflow-y: auto; scrollbar-width: none; } .sidebar-links::-webkit-scrollbar { display: none; } .sidebar-links li a { display: flex; align-items: center; gap: 0 20px; color: #fff; font-weight: 500; white-space: nowrap; padding: 15px 10px; text-decoration: none; transition: 0.2s ease; } .sidebar-links li a:hover { color: #161a2d; background: #fff; border-radius: 4px; } .user-account { margin-top: auto; padding: 12px 10px; margin-left: -10px; } .user-profile { display: flex; align-items: center; color: #161a2d; } .user-profile img { width: 42px; border-radius: 50%; border: 2px solid #fff; } .user-profile h3 { font-size: 1rem; font-weight: 600; } .user-profile span { font-size: 0.775rem; font-weight: 600; } .user-detail { margin-left: 23px; white-space: nowrap; } .sidebar:hover .user-account { background: #fff; border-radius: 4px; } ``` 結論和最後的話 ------- 對於 Web 開發初學者來說,使用 HTML 和 CSS 建立響應式側邊欄是一項可以完成的任務。透過遵循本文中提供的步驟和程式碼,您應該能夠成功建立自己的響應式和功能性側邊欄。 為了進一步提高您的網頁開發技能,我建議您嘗試重新建立本網站上提供的其他[漂亮的側邊欄](https://www.codingnepalweb.com/category/sidebar-menu/)。其中一些側邊欄使用 JavaScript 來增強其功能,例如加入[深色模式](https://www.codingnepalweb.com/sidebar-menu-in-html-css-javascript-dark-light-mode/)、[下拉式選單](https://www.codingnepalweb.com/dropdown-sidebar-menu-html-css/)等。 如果您在建立側邊欄時遇到任何問題,可以透過點擊「下載」按鈕免費下載專案的原始碼檔案。您也可以透過點擊“查看即時”按鈕來查看它的即時演示。 [查看現場演示](https://www.codingnepalweb.com/demos/create-sidebar-menu-html-css-only/) [下載程式碼文件](https://www.codingnepalweb.com/create-sidebar-menu-html-css-only/) --- 原文出處:https://dev.to/codingnepal/create-a-sidebar-menu-using-html-and-css-only-2e79

建構強大的 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

✨ 6 個您應該造訪的學習寶石網站!

介紹 -- 那麼您是軟體開發人員?太棒了。您可以建立應用程式並製作💸💸💸,但是您是否考慮過長期場景或您是否真正意識到這一點? 在五年的軟體開發生涯中,建立應用程式並不是為了完成工作或為啟動活動提供軟體。這不是🙅‍♂️。 如果您是優秀的開發人員,您應該了解軟體的後期開發階段... 🤨:來吧,我的「學習寶石」在哪裡?標題不是關於工程職位的! 好吧,我知道這跟工程職位無關。美好的! 但... ![阿塞爾瓦斯格爾](https://i.pinimg.com/564x/5c/89/b7/5c89b75128a05063ddfccbf36be74e75.jpg) 讓我們透過這些精彩的學習材料來增強我們的知識!從如何建立應用程式、編寫可維護的程式碼,甚至了解 CPU 的實際運作原理! 順便說一句,讓我們向所有製作這些優秀學習材料的作者致敬🙇‍♂️! [模式.dev](https://www.patterns.dev/) ----------------------------------- ![圖案縮圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2sca89gm5igy58byojn.png) Patterns.dev 由 Addy Osmani 和 Lydia Hallie 建立,旨在幫助您將網站架構提升到新的水平。 Patterns.dev 將幫助您設計、渲染和效能模式,以便使用普通 JavaScript 或現代框架建立強大的 Web 應用程式。 [將“你”放入CPU](https://cpu.land/) ------------------------------ ![CPU 區域縮圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xqdzvm4uaub99aop9g70.png) 接下來,我們有CPU Land! 你有沒有想過CPU在幕後到底是如何運作的? 🤨:如果它已經在幕後工作了,為什麼我還要考慮它? 阿喲,兄弟。來吧,你是認真的嗎?你不會被人工智慧取代吧? 這就是為什麼你應該知道 CPU 如何執行你的程式! 幸運的是,這個網站為您提供了幫助。在這裡,您可以了解多處理的工作原理、系統呼叫的真正含義、電腦如何透過硬體中斷管理記憶體以及 Linux 如何載入可執行檔。 感謝 Lexi Mattick 建立了這個網站! [重構大師](https://refactoring.guru/) --------------------------------- ![重構大師縮圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j2fubawobhmqkyogab86.png) 🤨:啊,我不想碰這個程式碼庫。很脆弱! 嘿,你兩年前寫了這段程式碼... 🤨:啊,對不起。我的意思是是的...為什麼你不給我一些解決方案,阿克巴? 我?沒有人,但是 Refactoring Guru 可以幫助你! Alexander Shvets 已經建立了很酷的網站來重構您的 💩 程式碼庫。這個網站將改變您對如何建立可長期維護的東西的看法。 [元件庫](https://component.gallery/) --------------------------------- ![元件庫縮圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqsl23fpudyj78pn8k2f.png) 對 UI 元件的命名及其外觀感到困惑嗎?不用擔心,我經常遇到這個問題。但幸運的是,Iain Bean 建立了 Component Gallery 網站! 在這裡,我們沒有看到預先建置的 UI 元件,而是為您提供了元件應該是什麼樣子以及它的具體用途。 [學習 Git 支撐](https://learngitbranching.js.org/) ---------------------------------------------- ![學習 Git 支撐縮圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbqvf9qc0jszns878xwk.png) 我有一個表情包給你,你去看看吧… ![凱伊瑟爾](https://miro.medium.com/v2/resize:fit:600/0*VcMPr1unIjAIHw2j.jpg) 但是,除非你知道如何正確使用 Git,否則它只是模因。如果你不這樣做,不用擔心。只需學習 Git 分支即可! Peter Cottle 建立此網站是為了幫助您以互動方式學習 Git。你知道,因為如果你能將某件事形象化,就更容易理解它。 [十二要素應用程式](https://www.12factor.net/) ------------------------------------- ![十二要素應用程式縮圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojf6okkbrng5meghecwe.png) 最後一個是十二要素應用程式! 您將學習如何在微服務叢集中建置 SaaS 或簡單的服務。在這裡,您不是了解使用了什麼技術,而是了解使您的應用程式可移植且易於在任何地方部署的意識形態或概念! 讓我們感謝亞當·威金斯的奉獻精神。 結論 -- 好吧,現在你已經知道了。不要放棄並保持學習精神。歸根結底,這只是某人的寫作,但它的價值在於當你應用它並且它起作用時。 如果您有任何建議,請隨時在下面的評論部分寫下來! 再見! ![烹飪霍馬特](https://i.pinimg.com/564x/2e/84/89/2e84892562d68742930e7641520beb38.jpg) --- 原文出處:https://dev.to/thexdev/5-website-learning-gems-you-should-visit-2pn5

使用 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

  近期留言