🔍 搜尋結果:bi

🔍 搜尋結果:bi

探索 JavaScript 中的解構

什麼是解構? ------ **解構**是 JavaScript 中一個非常酷的特殊語法功能,它允許我們從*陣列*、*物件*或其他可迭代結構中提取值並將它們指派給變數。 這是一種存取資料結構的屬性或元素的簡寫方式,而無需使用點表示法或陣列索引。 它對我們(用 JavaScript 寫程式的人)有什麼好處? ------------------------------ 解構有幾個好處,可以讓我們的程式碼更加簡潔、可讀和可維護! - ***提高可讀性***:解構透過減少複雜變數賦值和點符號的需要來簡化程式碼。 - ***更少的樣板程式碼***:您可以直接從資料結構中提取值,而無需建立中間變數。 - ***更簡潔的程式碼***:解構可以減少實現相同結果所需的程式碼行數。 - ***靈活性***:您可以解構任何類型的資料結構(物件、陣列、迭代),使其成為 JavaScript 工具包中的多功能工具。 有效的解構🚀使我們能夠編寫更具***表現力***、***可維護性***和***高效性的***程式碼,並且更容易理解和除錯。 基本範例 ---- ``` const person = { name: 'John', age: 30 }; const { name, age } = person; console.log(name); // "John" console.log(age); // 30 ``` 在這裡,我們解構了一個具有兩個屬性的物件`person` : `name`和`age` 。 解構 JavaScript 物件時,我們提取的值必須與物件中的鍵完全相同。您不能將`userName`取代該行中的`name` `const { name, age } = person;` 。這只是意味著 - `const { userName, age } = person;`行不通的。 但是,是的!我們可以在解構物件時套用別名。 EG- ``` const person = { name: 'John', age: 30 }; const { name:userName, age:userAge } = person; console.log(userName); // "John" console.log(userAge); // 30 ``` 您很可能在導入模組時第一次看到物件的解構。例如,當導入 exec 函數時 - ``` import { exec } from "node:child_process"; // ES Module syntax ``` ``` const { exec } = require("child_process"); // commonJS syntax ``` **同樣,我們也可以解構陣列**- ``` const numbers = [4, 5, 6]; const [x, y, z] = numbers; console.log(x); // 4 console.log(y); // 5 console.log(z); // 6 ``` 在這裡,當解構陣列時,您不需要使用別名將任何元素指派給自訂變數名稱。因為陣列元素只是值,所以它們不與某些鍵綁定。 預設值 --- 如果物件中不存在屬性,則解構允許您為變數指派預設值。 ``` const person = { name: 'John' }; const { name = 'Anonymous', age } = person; // age will be undefined console.log(name); // "John" console.log(age); // undefined ``` 這裡,字串值`'John'`沒有被變數`name`中的值`'Anonymous'`替換,因為它已經存在於物件中。 然而 - ``` const person = { name: 'John' }; const { name, age = 30 } = person; // age defaults to 30 if not present console.log(name); // "John" console.log(age); // 30 ``` 傳播文法 ---- **擴展**語法或**運算子**`(...)`可以與解構一起使用,以將陣列的剩餘元素或物件的屬性捕獲到新變數中。 - 使用陣列的擴充語法 - ``` const numbers = [1, 2, 3, 4, 5]; const [first, second, ...rest] = numbers; console.log(first); // 1 console.log(second); // 2 console.log(rest); // [3, 4, 5] (remaining elements) ``` - 物件的擴展語法 - ``` const person = { name: 'John', age: 30, city: 'New York' }; const { name, ...info } = person; console.log(name); // "John" console.log(info); // { age: 30, city: "New York"} (remaining properties) ``` 嵌套解構 ---- 解構可以嵌套以從深度嵌套的物件或陣列中提取值。 ``` const data = { user: { name: 'Alicia', origin: 'Romania', eyes: 'blue', address: { city: 'London', } } }; const { user: { name, address: { city } } } = data; console.log(name); // "Alicia" console.log(city); // "London" ``` 函數參數列表中的解構 ---------- 假設我們有一個名為`credentials`的JavaScript物件 - ``` const credentials = { name: 'Debajyati', age: 20, address: { city: 'Kolkata', state: 'West Bengal', country: 'India' }, phone: '', email: '', hobbies: ['reading', 'listening to music', 'coding', 'watching Anime'], skills: { programming: true, blogging: true, singing: false } } ``` 名為`showCredentials`的函數只接受 1 個參數值,該參數值是一個物件,而 Standard 會根據某些物件屬性輸出一個字串。 好吧,我們可以這樣寫函數定義 - ``` function showCredential(obj) { const hasSkill = (skill) => obj.skills[skill]; console.log( `${obj.name} is ${obj.age} years old.\n Lives in ${obj.address.city}, ${obj.address.country}.\n`, `He has the following hobbies: ${obj.hobbies.join(", ")}`, ); if (hasSkill("programming")) { console.log(`He is a programmer.`); } if (hasSkill("singing")) { console.log(`He is a singer.`); } if (hasSkill("blogging")) { console.log(`He is also a tech blogger.`); } } ``` 用 - 來呼叫它 ``` showCredential(credentials); ``` 得到這個輸出 - ``` Debajyati is 20 years old. Lives in Kolkata, India. He has the following hobbies: reading, listening to music, coding, watch ing Anime He is a programmer. He is also a tech blogger. ``` 相反,我們可以在定義函數時解構參數清單中的物件參數。像這樣 - ``` function showCredential({ name, age, address: { city, country}, hobbies, skills }) { const hasSkill = (skill) => skills[skill]; console.log( `${name} is ${age} years old.\n Lives in ${city}, ${country}.\n`, `He has the following hobbies: ${hobbies.join(", ")}`, ); if (hasSkill("programming")) { console.log(`He is a programmer.`); } if (hasSkill("singing")) { console.log(`He is a singer.`); } if (hasSkill("blogging")) { console.log(`He is also a tech blogger.`); } } ``` 給出相同的輸出。 > | :資訊來源: 注意| |----------------------------------------| 函數仍然只接受一個參數。解構不會增加函數參數清單中的參數數量。 此外,呼叫該函數也沒有改變。依然是—— ``` showCredential(credentials); ``` ### 那麼,為什麼要解構函數參數列表中的物件呢? 雖然函數參數清單中的解構一開始可能看起來很麻煩或乏味,但它有非常重要的好處。 #### 需要考慮的要點 - ***更安全的程式碼:*** 解構可以清楚地表明函數需要哪些屬性,有助於防止錯誤。如果傳遞的物件中缺少屬性,解構將導致函數執行期間出現錯誤,有助於及早發現潛在問題。 - ***減少冗長:*** 透過直接將屬性提取到參數清單中的變數中,可以避免使用點表示法重複存取物件屬性。這導致函數定義更清晰、更簡潔。 - ***注重功能:*** 透過在參數清單中進行解構,您可以將資料存取邏輯與函數的核心功能分開。這改進了程式碼組織並使函數的目的更加清晰。 解構字串 ---- 就像我們如何解構陣列一樣,我們也可以將字串解包為陣列元素。巧妙地運用我們的智慧。 ``` const fruit = 'grape'; const [first, second, ...rest] = fruit; const animal = rest.join(''); console.log(animal); // ape ``` > | :警告:記住! |------------------------| 當您使用展開運算子`(...)`捕獲字串中的剩餘字元時,您不會得到字串。您將會得到這些字元的陣列。 解構的一些方便的應用範例 ------------ - ***沒有第三個變數的交換解構***: JavaScript 傳統上需要一個臨時變數來交換兩個變數的值。解構提供了一種更簡潔、更易讀的方式來實現這一目標。 ``` - Before Destructuring: ``` ``` let a = 10; let b = 20; let temp = a; a = b; b = temp; console.log(a, b); // Output: 20 10 ``` ``` - After Destructuring: ``` ``` let a = 10; let b = 20; [a, b] = [b, a]; console.log(a, b); // Output: 20 10 ``` ``` So nifty & elegant✨! Isn't it? ``` - ***解構函數傳回值***:函數可以以陣列或物件的形式傳回多個值。解構允許您將這些返回值解包到單獨的變數中,從而提高程式碼清晰度。 假設您有一個從 API 取得資料並傳回回應物件的函數: ``` function getUserUpdates(id) { // Simulating some API call with a GET request return { data: { player: response.group.names[id], brain: "rotting", powerLevel: Number(response.group.power[id]), useAsDecoy: true, }, statusCode: Number(response.status), }; } ``` 在建立 API 或處理伺服器回應的上下文中,它提供了增強程式碼品質和可維護性的獨特優勢。 存取各個屬性將變得輕而易舉,因為您可以在函數呼叫本身期間直接將所需的屬性從函數的返回值提取到單獨的變數中。 ``` const { data: {player, useAsDecoy, powerLevel}, statusCode, } = getUserUpdates(1); ``` 每當函數傳回物件並且您對特定屬性值感興趣時,請始終立即套用解構。 如果您仍然認為返回值的解構不是一個好主意,那麼這另外兩個優點可能會說服您 - (A)***簡化的心智模型:***解構簡化了將使用您的函數的開發人員理解資料流所需的思考過程。開發人員可以專注於解構模式中使用的變數名稱所傳達的含義,而不是記住複雜的屬性存取鏈。這減少了認知負擔並促進更好的程式碼理解。 (B)***簡化複雜回傳物件的樣板程式碼:*** 當函數傳回具有大量或嵌套屬性的物件時,解構會顯著減少單獨存取它們所需的樣板程式碼。這使得程式碼庫更加簡潔、更簡潔,從而提高了整體程式碼品質。 - ***帶條件的解構***:解構可以與條件語句結合起來,根據物件的結構來處理不同的場景。如果您有一個接收具有可選屬性的物件的函數: ``` function greetUser(user) { const { name = "Anonymous" } = user || {}; // Destructuring with default value console.log(`Hello, ${name}!`); } greetUser({ name: "Bob" }); // Output: "Hello, Bob!" greetUser({}); // Output: "Hello, Anonymous!" (no name property) greetUser(undefined); // Output: "Hello, Anonymous!" (function receives no argument) ``` 結論 -- 在整篇文章中,我們了解到**「解構」**是 JavaScript 中一個強大且多功能的功能,可以顯著提高程式碼的可讀性、可維護性和效率。透過有效地使用解構技術,您可以編寫更乾淨、更簡潔且不易出錯的程式碼。因此,擁抱解構並將您的 JavaScript 技能提升到一個新的水平! 如果您發現這篇文章有幫助,如果這個部落格為您的時間和精力增加了一些價值,請透過給這篇文章點讚來表達一些愛,並與您的朋友分享。 請隨時透過[Twitter](https://twitter.com/ddebajyati) 、 [LinkedIn](https://www.linkedin.com/in/debajyati-dey)或[GitHub](https://github.com/Debajyati)與我聯繫:) 快樂編碼🧑🏽‍💻👩🏽‍💻!祝你有個美好的一天! 🚀 --- 原文出處:https://dev.to/ddebajyati/exploring-destructuring-in-javascript-5a24

Docker 在本地 Laravel 開發中的魅力

想要快速入門並跳過下面的詳細教學嗎?為您的作業系統安裝[Docker](https://docs.docker.com/docker-for-mac/install/) ,複製[此儲存庫](https://github.com/aschmelyun/docker-compose-laravel),將 Laravel 應用程式檔案新增至**src**目錄,然後從您剛剛複製的根專案目錄執行: `docker-compose build && docker-compose up -d` 。 簡介 -- 在開始之前,我們應該知道,本文並不是關於 Docker 的完整教程,也不是對該工具集複雜性的解釋。它更像是使用 Docker 和 docker-compose 快速設定本地開發環境的簡化演練,而不是直接在電腦上安裝 LAMP 堆疊。雖然有一些注意事項,但我發現下面的方法在開發 Laravel 應用程式時最適合我。 對於那些不知道 Docker 是什麼的人,讓我們先簡單了解一下。根據 opensource.com 報告: > [Docker](https://github.com/docker/docker)是一種工具,旨在讓使用容器更輕鬆地建立、部署和執行應用程式。容器允許開發人員將應用程式及其所需的所有部分(例如庫和其他依賴項)打包在一起,並將其全部作為一個套件發布。 您可以將 Docker 視為一個淡化的虛擬機器。 為什麼這有幫助或有用?如果您有多個執行不同版本的 Linux、PHP 或任何其他 Web 軟體的生產伺服器,那麼這些變數可以複製到您的容器中,並且可以保證應用程式將按照其預期在生產電腦上準確執行。 更符合本文的基調,如果您的本地計算機上有多個跨越不同版本的Laravel 專案,您可以為每個應用程式指定特定的Docker 配置,而無需實現PHP 版本切換器之類的東西並修改實際計算機的配置。您甚至可以同時存取這兩個專案,每個容器都彼此隔離執行。 聽起來令人興奮嗎?**讓我們深入了解一下吧!** 安裝 Docker --------- 在本文中,螢幕截圖和參考資料將與 MacOS 用戶相關。但是,Windows 上的安裝和使用說明應該非常相似(即使不是幾乎完全相同)。 首先,取得安裝程式: <https://docs.docker.com/docker-for-mac/install/> 。 執行典型的應用程式安裝過程,完成後打開應用程式。第一次開啟 Docker 時,系統會要求您透過系統密碼對 Docker 進行授權,之後您會看到頂部狀態列中出現小鯨魚圖示。 專案結構 ---- 以下是我在 Laravel + Docker 專案中使用的結構。儘管本文的其餘部分將假設您的專案是使用相同的佈局設定的,但您不必明確遵循這一點。 ``` my-project.com/ ├── nginx/ │ └── default.conf ├── src/ │ └── (Laravel app files) ├── docker-compose.yml └── Dockerfile ``` 在接下來的幾個部分中,我將介紹每個檔案的用途,但現在只需使用上面的佈局將它們建立為空白佔位符。此外,在**src/**目錄下新增(或建立)整個 Laravel 應用程式的檔案。 建立我們的堆疊 ------- 使用 Docker 時的一個重要經驗法則是每個容器都應該提供單一服務。由於我們正在建立一個典型的 LEMP 堆疊,這意味著我們需要一個用於 Web 伺服器 ( **Nginx** )、 **PHP**和**MySQL 的**堆疊。雖然理論上我們可以為每個服務建立單獨的容器,然後嘗試將它們連結在一起,但 Docker 有一個漂亮的內建工具,稱為**[docker-compose](https://docs.docker.com/compose/)** 。 我們所做的就是定義將要使用的服務,並在執行時 Docker 將每個服務提供為一個容器並將它們全部包裝在虛擬網路中。這意味著每個服務都可以從每個容器存取。 首先,打開**docker-compose.yml**檔案並將以下內容新增至其頂部: ![docker-compose.yml 截圖開始](https://cdn-images-1.medium.com/max/800/1*xNYoBOhF9G-TQFz3wVsYfg.png) 對我們剛剛加入的內容的一些快速解釋: - **版本:3** ,最新最推薦的docker-compose引擎版本 - **網路:**我們只使用一個網路**laravel** ,除了名稱之外我們沒有加入任何選項 - **服務:**我們將在其中指定構成堆疊的映像 新增 Nginx -------- 在我們在上面**docker-compose.yml**檔案底部指定的服務標題的正下方,您將加入以下內容: ![nginx 服務的 docker-compose.yml 截圖](https://cdn-images-1.medium.com/max/800/1*ioySVPvb1iSlIv7ev501VQ.png) 上面我們所做的就是告訴 Docker 我們想要一個名為**nginx**的容器,它是從 nginx:stable-alpine 映像建置的(您可以[在此處](https://github.com/nginxinc/docker-nginx/blob/14c1b938737cf4399a6bb039bc506957dce562ae/stable/alpine/Dockerfile)查看其完整原始程式碼)。我們使用 alpine linux 作為基礎作業系統,因為它輕巧且響應靈敏。 接下來,我們將容器命名為**nginx**並將其`:80`連接埠在本機電腦上公開為`:8080` 。我們最終將使用此連接埠號碼來存取我們的網站,您可以將其調整為您喜歡的任何非保留連接埠號碼。 對於 Web 伺服器的捲,我們新增以下兩項: - 我們的本地**/src**資料夾綁定到容器的**/var/www**路徑。與符號連結不同,我們在 /src 中修改的任何內容都將立即可供 /var/www 下的伺服器使用。 - 我們建立的**/nginx/default.conf**檔案連結到**/etc/nginx/conf.d/default.conf**容器文件,並且使我們能夠修改本地電腦上的 nginx Web 伺服器。 您可以在此標題下指定任意數量的目錄或文件,以將它們從本機電腦符號連結到 nginx 容器。 透過在**depends\_on**專案下加入php和mysql(我們接下來將建立的服務),我們告訴Docker在初始化時php和mysql容器需要在nginx之前執行。此外,如果我們嘗試只啟動 nginx 容器,它也會啟動這兩個依賴容器。 最後,我們明確指定容器位於我們在 docker-compose.yml 檔案開頭所建立的**laravel**網路下。 新增MySQL ------- 我們要加入**docker-compose.yml**檔案中的下一個服務是 MySQL。這個相對簡單。 ![docker-compose.yml 截圖新增mysql服務](https://cdn-images-1.medium.com/max/800/1*0rXBlDAOOWxUQnDPy7lvMQ.png) 最初,我們指定映像和容器名稱,以及設定一些我認為有助於維護 MySQL 在容器中的穩定性的其他設定。 預設的 MySQL 端口`:3306`是我們向本地計算機公開的端口,然後使用**環境**物件,我們可以設定初始化期間使用的一些變數來修改建立的資料庫。由於我們正在為 Laravel 應用程式配置 Docker,因此我使用典型 Laravel .env 檔案中的預設資料庫名稱/使用者名稱/密碼。 就像 nginx 一樣,我們將此服務附加到**laravel**網路。 ✨ 簡單! 新增 PHP ------ 與 Nginx 和 MySQL 不同,新增**PHP**容器將採取不同的、*稍微*複雜的路徑。透過前兩個服務,我們能夠直接引用映像來建置我們的容器,但是由於 Laravel 需要依賴項,我們實際上將基於本機 Dockerfile 建置我們自己的映像。 在我們開始這部分之前,將以下內容作為下一個(也是最後一個)服務加入到我們的**docker-compose.yml**檔案中。 ![新增php服務的docker-compose.yml截圖](https://cdn-images-1.medium.com/max/800/1*N8S_9gJheDvwcXIpuphk2Q.png) 您已經可以發現差異,我們正在用**建置**標題替換之前使用的**圖像**標題。在它下面,我們將上下文指定為當前專案目錄,並將 dockerfile 指定為 Dockerfile(我們之前已經建立了)。 與我們的 nginx 容器一樣,我們為根目錄指定相同的捲,然後為容器公開連接埠`:9000`並將網路設定為**laravel** 。 現在我們已經加入了該服務,是時候將以下內容加入到我們的**Dockerfile**中了: ![用於建立 PHP 映像的 Dockerfile 螢幕截圖](https://cdn-images-1.medium.com/max/800/1*eCT3BxPVZ2w7redLrfHpKA.png) 是的,就是這樣。 我們在這裡所做的就是: - 指定我們希望從`7.2-fpm-alpine` PHP 映像建置 php 容器。 - 安裝 Laravel 的 ORM 與其資料庫方法一起使用的`pdo`和`pdo_mysql` PHP 擴充。 `docker-php-ext-install`指令是 Docker 內建的(並且[沒有詳細記錄](https://docs.docker.com/samples/library/php/#how-to-install-more-php-extensions))。您可以傳遞任何 PHP 擴展,它將在我們新建立的容器中處理安裝和配置。 配置nginx ------- 還記得我們建立的**/nginx/default.conf**檔案嗎?打開它並加入以下內容: ![預設 nginx 設定的螢幕截圖](https://cdn-images-1.medium.com/max/800/1*GhwmexAjEEbdags1CQOowg.png) 老實說,這裡沒有太多可討論的,因為它主要是與大多數基本 Laravel 應用程式一起使用的樣板 nginx 配置。請注意,根路徑設定為我們將 Laravel 應用程式連結到的**/var/www** nginx 目錄的公共資料夾。 啟動 Docker --------- 我們已經將所有單獨的部分都準備好了,現在終於可以組裝我們的 Docker 網路了!開啟終端機視窗並導航到該專案的根目錄。由於我們的一個容器( **php** )使用 Dockerfile 作為其映像,並且這是我們第一次啟動這些容器,因此我們需要做的第一件事是執行**建置**命令來產生映像資料: `docker-compose build` 這需要一些時間才能完成,並且可能看起來有一段時間沒有發生任何事情。大約 1-2 分鐘後,您應該會在終端機中看到**「已成功建置」**和**「已成功標記」**訊息。然後,您可以使用以下命令繼續實際啟動容器: `docker-compose up -d` Docker 將建立我們的 laravel 網絡,然後建立我們在 docker-compose.yml 檔案的 services 部分中指定的三個容器。如果您對**-d**標誌感到好奇,它代表**分離**並在處理完所有命令後保持容器執行。否則,一旦完成初始化,Docker 就會停止它們。對於網頁伺服器來說毫無意義! 配置 Laravel ---------- 在我們第一次存取我們的應用程式之前,我們需要對 Laravel .env 檔案進行一些小的調整。特別是關於資料庫連接和應用程式域。在**src**目錄中開啟專案的`.env`檔案並修改以下行: - `DB_HOST=mysql` - 這個名稱來自我們在 docker-compose.yml 檔案中建立的 MySQL 服務,並在 Docker 網路中用於引用其他容器中的服務。 - `APP_URL=http://localhost:8080` - 新增您在 nginx 容器中公開的連接埠號,以使其指向可解析的位址。 存取您的應用程式 -------- 假設上述步驟中的所有內容都已成功啟動,我們現在可以使用公開的連接埠存取我們的容器並查看我們應用程式的登陸頁面! 在瀏覽器中,導覽至<http://localhost:8080> ,其中**8080**是您在 docker-compose.yml 檔案中的 nginx 服務下指定的**第一個**連接埠。 ![顯示 Laravel 登陸畫面的瀏覽器螢幕截圖](https://cdn-images-1.medium.com/max/800/1*p3yulsFx0g_Szh_2hqfkPg.png) 💥 繁榮!我們的 Laravel 應用程式在 Docker 網路中執行! 當然,如果您可能還想使用[TablePlus](https://tableplus.io/)之類的工具存取 MySQL 資料庫,那麼連接到該資料庫也同樣簡單。您要做的就是使用`127.0.0.1`作為主機,以及您在 docker-compose.yml 檔案中的 MySQL 服務下公開的連接埠(在本範例中,我們將其保留為預設值**3306** ) 。 我們在環境變數中指定的使用者名稱和密碼分別為`MYSQL_USER`和`MYSQL_PASSWORD` 、 **homestead**和**Secret** 。 ![TablePlus 設定的螢幕截圖](https://cdn-images-1.medium.com/max/2000/1*oupY3mehpHd2bItaf_tNzw.png) **注意:**如果您打算為不同的專案同時執行多個網絡,則必須指定不同的連接埠以在本機電腦上公開(例如,一個為 8080,另一個為 8081)。否則,在容器初始化期間,您將收到`port is already allocated`錯誤。 執行命令 ---- Laravel 經常使用命令列來進行遷移、佇列和測試等操作。使用 docker-compose 的`exec`指令在我們的 Docker 網路上執行這些指令非常簡單。 **Docker 不是透過 ssh 進入系統並直接在作業系統上執行命令的虛擬機,而是偏好將命令傳遞到容器,**然後將這些命令的輸出回顯到終端。例如,讓我們透過在專案根目錄的終端機中執行以下命令來執行 Laravel 附帶的預設遷移: `docker-compose exec php php /var/www/artisan migrate` 讓我們稍微分解一下: - **docker-compose exec**告訴 Docker 我們要在容器網路上執行指令。 - **php**我們要執行指令的容器名稱。由於我們要執行 PHP 命令,因此它需要位於執行 PHP 的容器上。 - **php /var/www/artisan 遷移**我們正在執行的指令的實際名稱。我們使用 artisan 的絕對路徑,該路徑通過 ./src 的本地捲進行符號連結,並執行標準的 Laravel 遷移。 ![執行 docker-compose migrate 指令後的終端螢幕截圖](https://cdn-images-1.medium.com/max/800/1*HUKD-2efKCz8jM1G0Eg_eQ.png) 執行我們的命令後,您應該會看到遷移輸出,並且您的資料庫現在將填充兩個表! 可以從本機終端將任意數量的命令執行到我們選擇的 Docker 容器。只需注意要在其上執行命令的容器中安裝和可用的服務即可。 **提示:**如果您堅持要直接透過 ssh 進入容器來執行命令,有一個非常簡單的解決方法。跑步 `docker-compose exec {container_name} /bin/sh`將開啟與 {container\_name} 參數中指定的容器的持久連線。 隊伍的盡頭 ----- 好吧,我們就有了!我們已經安裝了 Docker,設定並配置了 docker-compose 檔案來建立包含在單一網路中的三個容器的 LEMP 堆疊,在該網路上公開了允許我們存取應用程式和資料庫的端口,甚至執行了 cli 命令透過docker-compose的exec方法。 展望未來,如果您想關閉容器和網絡,只需導航到專案的根資料夾並執行即可 `docker-compose down` 。這將關閉並銷毀容器以及儲存在其中的**任何關聯的非磁碟區資料**。 當我處理跨越不同 Laravel 版本的多個專案時,Docker 為我開啟了一個充滿開發可能性的世界。我可以使用`7.1`輕鬆地在具有 PHP 容器的 Docker 網路上執行一個專案,如果我想了解當前專案在 PHP `7.3`中的執行情況,只需更改 Dockerfile 中的**單個字符**,重新建置容器即可,並恢復docker -compose 網路。 我不會否認,與直接在機器硬體上執行堆疊相比,您不會獲得更好的本地開發效能。但對我來說,**性能**與**多功能性、易用性、並行環境和客製化的**權衡遠遠超過了這些。 如果您有任何問題、意見或想進一步討論 PHP 和 Laravel,請隨時在[Twitter](https://twitter.com/aschmelyun)上與我聯絡!如果您正在尋找**專門針對 Laravel 應用程式的超級簡單錯誤和日誌監控服務**,我已經建立了[Larahawk](https://larahawk.com) 。它目前處於內測階段,很快就會推出,每個應用程式每月只需 5 美元。 --- 原文出處:https://dev.to/aschmelyun/the-beauty-of-docker-for-local-laravel-development-13c0

您可以在開源中貢獻這 25 個專案

受資助計畫的聲譽非常好,因為它們獲得了大量資金並得到了風險投資的支持。 有很多開源專案,你絕對應該為這些專案做出貢獻,特別是因為它們的可信度要高得多。 也許你有機會獲得直接的工作機會,畢竟你真的不知道誰在開源中關注你! 我只保留了活躍的專案(最後一次提交不到 2 個月),所以它會很有用。讓我們保持簡短和直接。 --- 1. [Taipy](https://github.com/Avaiga/taipy) - 資料和人工智慧演算法融入生產級網路應用程式。 -------------------------------------------------------------------- ![打字](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wd10iiofzmt4or4db6ej.png) Taipy 是用於輕鬆、端到端應用程式開發的完美 Python 程式庫,具有假設分析、智慧型管道執行、內建調度和部署工具。 它用於為基於 Python 的資料和人工智慧應用程式建立 GUI 介面並改進資料流管理。 關鍵是性能,而 Taipy 是完美的選擇,尤其是與 Streamlit 相比。您可以閱讀 Marktechpost 發表的[Taipy 與 Streamlit](https://www.marktechpost.com/2024/03/15/taipy-vs-streamlit-navigating-the-best-path-to-build-python-data-ai-web-applications-with-multi-user-capability-large-data-support-and-ui-design-flexibility/)的詳細比較。 - 💰 獲得總資金 500 萬美元。 - 🚀 使用的主要語言是Python。 Taipy 在 GitHub 上有近 10k 顆星,並且正在發布`v3.1`版本。 https://github.com/Avaiga/taipy Star Taipy ⭐️ --- 2. [Hoppscotch](https://github.com/hoppscotch/hoppscotch) - API 開發生態系統。 ----------------------------------------------------------------------- ![跳房子](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75cjol6454uvrnth524y.png) Hoppscotch 是一個輕量級、基於 Web 的 API 開發套件。它是從頭開始建置的,考慮到了易用性和可存取性。 Hoppscotch 與 Postman 非常相似,但提供了一些不同的功能。這就是儀表板的樣子,您可以在[hoppscotch.io](https://hoppscotch.io/)上進行即時測試。 ![跳房子](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2f6ck92qdpd99in6wav.png) 即使測試本機 API,Postman 也要求您保持線上狀態。使用 Hoppscotch,您可以在沒有網路連線的情況下使用 API。 甚至 Web 應用程式也可以透過本機快取離線執行並充當 PWA,讓您可以隨時隨地測試 API! Hoppscotch 也提供私人工作空間。請參閱[完整功能清單](https://github.com/hoppscotch/hoppscotch?tab=readme-ov-file#features)。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d36kmr72z11h71nnvhf5.png) 最好的部分也是必要的部分是他們提供完整的[文件](https://docs.hoppscotch.io/),其中包括指南、文章、支援和變更日誌,以便您可以在這裡看到所有內容。 ![2023年已結束](https://hoppscotch.com/images/blog-hoppscotch-wrapped-2023.png) - 💰 獲得總資金 300 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Hoppscotch 在 GitHub 上擁有超過 60k 顆星,有 300 多個活躍問題和 200 多個貢獻者。 https://github.com/hoppscotch/hoppscotch 明星跳房子 ⭐️ --- 3. [Daily](https://github.com/dailydotdev/daily) - 每個開發者都值得擁有的首頁。 ----------------------------------------------------------------- ![日常的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qvzd1auk8wet7vv5ev37.png) 這是一個專業網絡,您可以在其中閱讀與開發者生態系統相關的文章和個人化動態訊息。 他們匯總了來自許多組織(例如 Hacker News、Dev、Hashnode 等)的各種主題的有價值的帖子。您可以投票、加書籤,甚至建立自己的小隊。 ![小隊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqqkl42pja53ssywltyl.png) 我是其中一些功能的粉絲,如果我解釋所有內容,我會花費幾個小時,所以最好檢查一下。 這是我個人最喜歡的開源專案之一。你可以查看我的[每日個人資料](https://app.daily.dev/anmolbaranwal)。 - 💰 獲得總資金 1100 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Dailydotdev 在 GitHub 上擁有 17k+ 顆星。 https://github.com/dailydotdev/daily 明星日報 ⭐️ --- 4. [Requestly](https://github.com/requestly/requestly) - 瀏覽器的 HTTP 攔截器。 ----------------------------------------------------------------------- ![請求地](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1jnfzpqe827qxm11a1tm.png) Requestly 的建置是為了透過攔截和修改 HTTP 請求來節省開發人員的時間。 Requestly 為前端開發人員提供必要的工具和整合協助,幫助他們以 10 倍的速度編寫、測試和偵錯程式碼。 Requestly 減少了對後端開發人員和開發和測試需求環境的依賴。 使用 Requestly,開發人員可以建立模擬、測試、驗證和覆蓋 API 回應,修改請求和回應標頭,設定重定向(映射本機、映射遠端),並使用 Requestly 會話進行更快的偵錯。 您可以看到[完整功能](https://github.com/requestly/requestly?tab=readme-ov-file#-features)的清單。 - 💰 獲得 50 萬美元的種子資金。 - 🚀 使用的主要語言是 TypeScript。 Requestly 在 GitHub 上擁有超過 1,800 顆星,並且正在快速成長。 https://github.com/requestly/requestly 為請求加星號 ⭐️ --- 5.[重新發送](https://github.com/resend)- 給開發人員的電子郵件。 ------------------------------------------------ ![重發](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a7diqqs4n4yrshxf22l3.png) 電子郵件可能是人們溝通的最重要的媒介。然而,我們需要停止像 2010 年那樣開發電子郵件,並重新思考 2022 年及以後如何開發電子郵件。它應該針對我們今天建立網頁應用程式的方式進行現代化。 他們提供了許多與我們正在使用的技術堆疊相對應的不同儲存庫。請隨意探索其中每一個。 ![重新發送集成](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4jmx7q5i4wrsnwgcuvwk.png) - 💰 獲得 350 萬美元種子資金。 - 🚀 使用的主要語言是 TypeScript(React 電子郵件)。 Resend(React email)在 GitHub 上擁有超過 12,500 顆星,並被超過 7,500 名開發者使用。 https://github.com/resend 星標重新發送 ⭐️ --- 6. [Buildship](https://github.com/rowyio/buildship/) - 由人工智慧驅動的低程式碼視覺後端建構器。 --------------------------------------------------------------------------- ![建造船](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzlrynz5xephv4t9layd.png) 對於您正在使用無程式碼應用程式建構器(FlutterFlow、Webflow、Framer、Adalo、Bubble、BravoStudio...)或前端框架(Next.js、React、Vue...)建立的應用程式,您需要一個後端來支援可擴展的 API、安全工作流程、自動化等。 BuildShip 為您提供了一種完全視覺化的方式,可以在易於使用的完全託管體驗中可擴展地建立這些後端任務。 這意味著您無需在雲端平台上爭論或部署事物或執行 DevOps。只需立即建造和發貨 🚀 他們甚至與 TypeSense 合作並且發展得非常快! ![建造船](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6oc3rc713mjg9cwqj7d4.png) 我嘗試過Buildship,它很強大。 - 💰 私人資金(由 Google、Vercel、Figma 等支持)。 - 🚀 使用的主要語言是 TypeScript。 它在 GitHub 上有 260 多顆星,使用 Rowy 完成,有 5800 顆星。 https://github.com/rowyio/buildship/ 明星 BuildShip ⭐️ --- 7. [Cal](https://github.com/calcom/cal.com) - 為所有人安排基礎設施。 --------------------------------------------------------- ![卡爾](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ccagnexb805xzpewfy5.png) 這是有史以來最活躍的專案之一。我也透過 Cal 的 Algora 看過很多付費演出。 早些時候,我使用 Calendly,但我將其切換到 Cal,特別是因為它們在您可以建立的連結方面提供了更大的靈活性。 例如,我有一個協作連結,人們可以在其中選擇會議的持續時間並修復其他連結中的時間安排。您可以將其附加到幾乎所有應用程式,例如 GMeet、Zoom,如果您想參加付費會議,甚至可以同步付款。應用程式整合的[總選項](https://cal.com/apps)幾乎令人難以置信:) ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anesuu0ux6ejz886irnt.png) 您可以做很多事情,包括自動化工作流程,所以只需檢查一下即可。 ![工作流程儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kc0x5vq54joov98wwq9h.png) - 💰 獲得總資金(A 輪)3240 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Cal 在 GitHub 上擁有超過 29,000 顆星,並擁有超過 600 名貢獻者。 https://github.com/calcom/cal.com Star Cal ⭐️ --- 8. [Penpot](https://github.com/penpot/penpot) - 完美協作的設計工具。 ---------------------------------------------------------- ![筆筒](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mooryn8zodod2mkpzefn.png) Penpot 是第一個用於設計和程式碼協作的開源設計工具。設計師可以大規模建立令人驚嘆的設計、互動式原型和設計系統,而開發人員則可以享受現成的程式碼,並使他們的工作流程變得簡單、快速。所有這一切都沒有任何切換戲劇性的情況。 完全免費並符合開放標準(SVG、CSS 和 HTML)。 一次性查看[庫、模板](https://penpot.app/libraries-templates)和[功能](https://penpot.app/features)的清單。 觀看以下影片體驗`Penpot 2.0` 。 - 💰 獲得總資金 800 萬美元。 - 🚀 使用的主要語言是 Clojure。 Penpot 在 GitHub 上擁有超過 28,500 顆星,目前已發布`v2.0`版本。 https://github.com/penpot/penpot 星星筆罐 ⭐️ --- 9. [Appsmith](https://github.com/appsmithorg/appsmith) - 建立管理面板、內部工具和儀表板的平台。 ---------------------------------------------------------------------------- ![應用史密斯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rt7s0r3wz2leec83cl17.png) 管理面板和儀表板是任何軟體創意(在大多數情況下)的一些常見部分,我嘗試從頭開始建立它,這會帶來很多痛苦和不必要的辛苦工作。 您可能已經看到組織建立了內部應用程式,例如儀表板、資料庫 GUI、管理面板、批准應用程式、客戶支援儀表板等,以幫助其團隊執行日常操作。正如我所說,Appsmith 是一個開源工具,可以實現這些內部應用程式的快速開發。 首先,請觀看這個 YouTube 影片,該影片在 100 秒內解釋了 Appsmith。 嵌入 https://www.youtube.com/watch?v=NnaJdA1A11s 他們提供拖放小部件來建立 UI。 您可以使用 45 多個可自訂的小工具在幾分鐘內建立漂亮的響應式 UI,而無需編寫一行 HTML/CSS。尋找[小部件的完整清單](https://www.appsmith.com/widgets)。 ![按鈕點擊小工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kqpnnslvsvjl4gifseon.png) ![驗證](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/489fly7tvknz2uv2mgei.png) 您可以閱讀[文件](https://docs.appsmith.com/)並使用這[20 多個範本](https://www.appsmith.com/templates)中的任何一個,以便您可以快速入門。 - 💰 獲得 500 萬美元種子資金。 - 🚀 使用的主要語言是 TypeScript。 Appsmith 在 GitHub 上擁有超過 32k 顆星,發布了 200 多個版本。 https://github.com/appsmithorg/appsmith Star Appsmith ⭐️ --- 10.[二十](https://github.com/twentyhq/twenty)- Salesforce 的現代替代品。 --------------------------------------------------------------- ![二十](https://framerusercontent.com/images/oclg8rdRgBnzeLnSJOfettLFjI.webp) 我們花了數千個小時來研究Pipedrive 和Salesforce 等傳統CRM,以使它們與我們的業務需求保持一致,但最終卻感到沮喪——定制非常複雜,而且這些平台的封閉生態系統可能會讓人感到受到限制。 Twenty 是一個現代化、功能強大、價格實惠的平台,用於管理您的客戶關係。您可以閱讀[使用者指南](https://twenty.com/user-guide)。 ![二十](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tucrt5pk9piyswnt9q77.png) - 💰 獲得 75.9 萬美元的種子資金。 - 🚀 使用的主要語言是 TypeScript。 Twenty 在 GitHub 上擁有超過 14,500 顆星,擁有 200 多名貢獻者。 https://github.com/twentyhq/twenty 二十星 ⭐️ --- 11.[繼續](https://github.com/continuedev/continue)-AI程式碼助手。 -------------------------------------------------------- ![繼續 gif](https://github.com/continuedev/continue/raw/main/docs/static/img/understand.gif) Continue 是領先的開源 AI 程式碼助理。您可以連接任何模型和任何上下文,以在[VS Code](https://marketplace.visualstudio.com/items?itemName=Continue.continue)和[JetBrains](https://plugins.jetbrains.com/plugin/22707-continue-extension)內建立自訂自動完成和聊天體驗。 > 選項卡可自動完成程式碼建議。 ![自動完成 gif](https://github.com/continuedev/continue/raw/main/docs/static/img/autocomplete.gif) > 重構您正在編碼的函數。 ![重構影像](https://github.com/continuedev/continue/raw/main/docs/static/img/inline.gif) > 詢問有關您的程式碼庫的問題。 ![程式碼庫](https://github.com/continuedev/continue/raw/main/docs/static/img/codebase.gif) > 快速使用文件作為上下文 ![文件上下文 gif](https://github.com/continuedev/continue/raw/main/docs/static/img/docs.gif) 閱讀[快速入門指南](https://docs.continue.dev/quickstart)。 - 💰 獲得 210 萬美元種子資金。 - 🚀 使用的主要語言是 TypeScript。 Continue 在 GitHub 上有 12k+ 顆星,並且發布了`v0.8`版本。 https://github.com/continuedev/continue 星繼續 ⭐️ --- [12.Refine](https://github.com/refinedev/refine) - 面向企業的開源 Retool。 ------------------------------------------------------------------ ![精煉](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wsti2yfikrhc9nggov5.png) Refine 是一個元 React 框架,可以快速開發各種 Web 應用程式。 從內部工具到管理面板、B2B 應用程式和儀表板,它可作為建立任何類型的 CRUD 應用程式(例如 DevOps 儀表板、電子商務平台或 CRM 解決方案)的全面解決方案。 ![電子商務](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xry9381y4s36emgb9psr.png) 您可以在一分鐘內使用單一 CLI 命令進行設定。 它具有適用於 15 多個後端服務的連接器,包括 Hasura、Appwrite 等。 但最好的部分是,Refine `headless by design` ,從而提供無限的樣式和自訂選項。 你可以看到[模板](https://refine.dev/templates/)。 ![範本](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87vbx5tqyicb9gmgirka.png) - 💰 獲得總資金 380 萬美元。 - 🚀 使用的主要語言是 TypeScript。 它們在 GitHub 上擁有大約 25,000 顆星,並被超過 3,000 名開發人員使用。 https://github.com/refinedev/refine 星際精煉 ⭐️ --- 13. [Revideo](https://github.com/redotvideo/revideo) - 使用程式碼建立影片。 ----------------------------------------------------------------- ![審查](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttwzahj6kfgllj0aknt1.png) Revideo 是一個用於程式化影片編輯的開源框架。它是從令人驚嘆的 Motion Canvas 編輯器分叉出來的,將其從獨立的應用程式轉變為開發人員可以用來建立整個影片編輯應用程式的庫。 Revideo 可讓您在 Typescript 中建立視訊範本並部署 API 端點以使用動態輸入呈現它們。它還提供了一個React播放器元件來即時預覽瀏覽器中的變化。 - 💰 獲得總資金 500 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Revideo 在 GitHub 上有 1.2k 顆星,活躍問題非常少。簡而言之,這是一個完美的、不那麼擁擠的貢獻專案。 https://github.com/redotvideo/revideo 明星重錄 ⭐️ --- 14.[百萬](https://github.com/aidenybai/million)- 讓你的 React 速度提高 70%。 ------------------------------------------------------------------ ![百萬](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afs9dm1eujmajxn0rng9.png) Million.js 是一個極其快速且輕量級的最佳化編譯器,可將元件速度提高 70%。自己探索吧! ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vozcs5gd57rwlp3jjmr4.png) - 💰 獲得總計 50 萬美元的資金。 - 🚀 使用的主要語言是 TypeScript。 Million 在 GitHub 上擁有超過 15,500 顆星,並被超過 3000 名開發者使用。 https://github.com/aidenybai/million 明星百萬⭐️ --- 15. [FlowiseAI](https://github.com/FlowiseAI/Flowise) - 拖放 UI 來建立您的客製化 LLM 流程。 ------------------------------------------------------------------------------ ![弗洛伊薩伊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5bp43nil764fhe4a05z.png) Flowise 是一款開源 UI 視覺化工具,用於建立客製化的 LLM 編排流程和 AI 代理程式。 ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ahk2ovjrpq1qk3r5pfot.png) 您可以閱讀[文件](https://docs.flowiseai.com/)。 ![流程化人工智慧](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/trkltpn5lk1y1pte0smd.png) - 💰 從 YCombinator 獲得資金(不知道多少)。 - 🚀 使用的主要語言是 TypeScript。 FlowiseAI 在 GitHub 上擁有超過 26,500 個 Star,並擁有超過 13,000 個分叉,因此具有良好的整體比率。 https://github.com/FlowiseAI/Flowise 明星 FlowiseAI ⭐️ --- 16.[觸發器](https://github.com/triggerdotdev/trigger.dev)——後台作業平台。 --------------------------------------------------------------- ![扳機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iaoox3qwmc397x9ckmw4.png) Trigger.dev v3 可以輕鬆編寫可靠的長時間執行任務而不會逾時。 在它們所屬的地方建立作業:在您的程式碼庫中。像您已經習慣的那樣進行版本控制、本地主機、測試、審查和部署。 您可以選擇在自己的基礎架構上使用觸發器雲端或自架觸發器。 閱讀文件中的[快速入門指南](https://trigger.dev/docs/v3/quick-start)。 - 💰 獲得總資金 300 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Trigger 在 GitHub 上有 7,500 顆星,目前已發布`v3.1`版本。 https://github.com/triggerdotdev/trigger.dev 星觸發器 ⭐️ --- 17. [Tiptap](https://github.com/ueberdosis/tiptap) - 無頭富文本編輯器框架。 ---------------------------------------------------------------- ![尖擊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gdtmi7do65ks6f2mpsjd.png) Tiptap 編輯器是一個無頭、與框架無關的富文本編輯器,可以透過擴充功能進行自訂和擴充。它的無頭性質意味著它沒有固定的使用者介面,提供完全的設計自由(要快速入門,請參閱下面連結的 UI 模板)。 Tiptap 是基於高度可靠的 ProseMirror 庫。 Tiptap Editor 得到協作開源後端 Hocuspocus 的補充。 Editor 和 Hocuspocus 構成了 Tiptap Suite 的基礎。 我建議閱讀包含[範例](https://tiptap.dev/docs/editor/examples/default)和詳細程式碼的[文件](https://tiptap.dev/docs/editor/introduction)。 - 💰 獲得總資金 260 萬美元。 - 🚀 使用的主要語言是 TypeScript。 ![尖擊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/20c83ios6ugr1q6blqfq.png) Tiptap 在 GitHub 上擁有超過 24k 顆星,擁有 300 多名貢獻者。 https://github.com/ueberdosis/tiptap 明星 Tiptap ⭐️ --- 18. [Infisical](https://github.com/Infisical/infisical) - 秘密管理平台。 ----------------------------------------------------------------- ![內部的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrolzjdnkky1r694h9av.png) Infisical 是一個開源秘密管理平台,團隊可以用它來集中 API 金鑰、資料庫憑證和設定等秘密。 他們讓每個人(而不僅僅是安全團隊)都可以更輕鬆地進行秘密管理,這意味著從頭開始重新設計整個開發人員體驗。 ![內部](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h3eu288l470du91b66pd.png) Infisical 還提供了一組工具來自動防止 git 歷史記錄的秘密洩露。可以使用預提交掛鉤或透過與 GitHub 等平台直接整合在 Infisical CLI 層級上設定此功能。 您可以閱讀[文件](https://infisical.com/docs/documentation/getting-started/introduction)並檢查如何[安裝 CLI](https://infisical.com/docs/cli/overview) ,這是使用它的最佳方式。 在使用整個原始程式碼之前一定要檢查他們的[許可證](https://github.com/Infisical/infisical/blob/main/LICENSE),因為他們有一些受 MIT Expat 保護的企業級程式碼,但不用擔心,大部分程式碼都是免費使用的。 - 💰 獲得總資金 290 萬美元。 - 🚀 使用的主要語言是 TypeScript。 他們在 GitHub 上擁有超過 12,500 顆星,發布了 130 多個版本。另外,Infiscial CLI 的安裝次數超過 540 萬次,因此非常值得信賴。 https://github.com/Infisical/infisical 明星 Infisical ⭐️ --- 19. [HyperDX](https://github.com/hyperdxio/hyperdx) - 統一會話重播、日誌、指標、追蹤和錯誤的可觀察平台。 ------------------------------------------------------------------------------- ![超DX](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6r38lckflg0wmwlq6i4.png) HyperDX 透過將日誌、指標、追蹤、異常和會話重播集中並關聯到一處,幫助工程師快速找出生產中斷的原因。 Datadog 和 New Relic 的開源且開發人員友善的替代方案。閱讀[文件](https://www.hyperdx.io/docs)。 ![超DX](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9g83r7408vr2oawc8s8p.png) - 💰 獲得總計 50 萬美元的資金。 - 🚀 使用的主要語言是 TypeScript。 HyperDX 在 GitHub 上擁有超過 6k 顆星。 https://github.com/hyperdxio/hyperdx 明星 HyperDX ⭐️ --- 20.[亮點](https://github.com/highlight/highlight)-全端監控平台。 ------------------------------------------------------- ![強調](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3p2ecjnrwbtskuqrkjv7.png) highlight.io 是為下一代開發人員(像您一樣!)提供的監控工具。與現有的古老、過時的工具不同,它們的目標是建立一個有凝聚力的、現代的、功能齊全的監控解決方案。 ![支援框架](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afaoao8954hobs7d2igw.png) - 💰 獲得總資金 850 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Highlight 在 GitHub 上有超過 7k 顆星。 https://github.com/highlight/highlight 星標亮點 ⭐️ --- 21. [Panora](https://github.com/panoratech/Panora) - 在幾分鐘內將整合目錄新增至您的 SaaS 產品。 ----------------------------------------------------------------------------- ![全景](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzhhyl8t0xy2ueln8d4t.png) Panora 協助您將產品置於客戶日常工作流程的核心。 您的客戶希望他們的所有工具都能很好地協同工作。 Panora 避免您的團隊花費數百小時來建立和維護集成,而不是核心產品。 查看[快速入門指南](https://docs.panora.dev/quick-start)。 - 💰 獲得了 50 萬美元的總資金(可能更多)。 - 🚀 使用的主要語言是 TypeScript。 Panora 在 GitHub 上擁有 300 多個 star,並且處於非常早期的階段。 https://github.com/panoratech/Panora 明星 Panora ⭐️ --- 22. [Fleet](https://github.com/fleetdm/fleet) - IT、安全和基礎設施團隊的平台。 ---------------------------------------------------------------- ![艦隊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d47vi9uyn2hq3kx6s2h6.png) 針對擁有數千台電腦的 IT 和安全團隊的開源平台。專為 API、GitOps、webhooks、YAML 和人類而設計。 Fastly 和 Gusto 等組織使用 Fleet 進行漏洞報告、偵測工程、裝置管理 (MDM)、裝置運作狀況監控、基於狀態的存取控制、管理未使用的軟體授權等。 ![艦隊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vfn75mjk5rfhb4bfjwp8.png) - 💰 獲得總資金 2500 萬美元。 - 🚀 使用的主要語言是 Go。 Fleet 在 GitHub 上擁有 2,500 顆星。 https://github.com/fleetdm/fleet 星際艦隊 ⭐️ --- 23. [Ballerine](https://github.com/ballerine-io/ballerine) - 用於風險決策的基礎設施和資料編排平台。 -------------------------------------------------------------------------------- ![舞者](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tnnrhyf6oj3dexdeyyuf.png) Ballerine 是一種開源風險管理基礎設施,可協助全球支付公司、市場和金融科技公司在整個客戶生命週期中自動為商家、賣家和使用者做出決策。 從開戶(KYC、KYB)、承銷和交易監控,使用靈活的規則和工作流程引擎、第 3 方插件系統、手動審核後台以及文件和資訊收集前端流程。 - 💰 獲得總資金 550 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Ballerine 在 GitHub 上擁有 2000 顆星,發布了 700 多個版本。 https://github.com/ballerine-io/ballerine 明星芭蕾舞者 ⭐️ --- 24. [Tooljet](https://github.com/ToolJet/ToolJet) - 用於建立業務應用程式的低程式碼平台。 ---------------------------------------------------------------------- ![工具噴射器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhipvjl2wnthjccgrpij.png) 我們都建立前端,但它通常非常複雜,並且涉及許多因素。這樣可以省去很多麻煩。 ToolJet 是一個開源低程式碼框架,可以用最少的工程工作來建置和部署內部工具。 ToolJet 的拖放式前端建構器可讓您在幾分鐘內建立複雜的響應式前端。 您可以整合各種資料來源,包括PostgreSQL、MongoDB、Elasticsearch等資料庫;具有 OpenAPI 規範和 OAuth2 支援的 API 端點; SaaS 工具,例如 Stripe、Slack、Google Sheets、Airtable 和 Notion;以及 S3、GCS 和 Minio 等物件儲存服務來取得和寫入資料。一切 :) 這就是 Tooljet 的工作原理。 ![工具噴射器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6vv09z7ioma1ce2ttei.png) 您可以在 ToolJet 中開發多步驟工作流程以自動化業務流程。除了建置和自動化工作流程之外,ToolJet 還可以在您的應用程式中輕鬆整合這些工作流程。 ![工作流程](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eh2vk3kih9fhck6okf67.png) 您可以閱讀[文件](https://docs.tooljet.com/docs/)並查看[操作指南](https://docs.tooljet.com/docs/how-to/use-url-params-on-load)。 - 💰 獲得總融資 620 萬美元(GitHub 是其中一名投資者)。 - 🚀 使用的主要語言是 JavaScript。 Tooljet 在 GitHub 上擁有超過 27,800 顆星和 500 多名貢獻者。 https://github.com/ToolJet/ToolJet Star Tooljet ⭐️ --- 25. [Mattermost-](https://github.com/mattermost/mattermost)整個軟體開發生命週期的安全協作。 --------------------------------------------------------------------------- ![最重要的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43p8f052h71ryhavrkms.png) Mattermost 是一個開源平台,用於在整個軟體開發生命週期中進行安全協作。 該儲存庫是 Mattermost 平台上核心開發的主要來源;它是用 Go 和 React 編寫的,並作為單一 Linux 二進位與 MySQL 或 PostgreSQL 一起執行。每個月 16 日都會在 MIT 許可下發布新的編譯版本。 - 💰 獲得總資金 7350 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Mattermost 在 GitHub 上擁有超過 28,400 顆星,有 600 多個活躍問題和 900 多個貢獻者。 https://github.com/mattermost/mattermost Star Mattermost ⭐️ --- 我很驚訝這麼多受資助的專案使用 TypeScript 而不是 JavaScript。你是? 如果您知道任何其他資助專案或希望我製作第二部分。 請在評論中告訴我您最喜歡的清單。 祝你有美好的一天!直到下一次。 您可以加入我的開發者和技術作家社區,網址為[dub.sh/opensouls](https://dub.sh/opensouls) 。 關注 Taipy 以了解更多此類內容。 嵌入 https://dev.to/taipy --- 原文出處:https://dev.to/taipy/25-funded-projects-you-can-contribute-in-open-source-40lh

你的 side project 無法賺錢的 5 個原因以及如何避免它們

介紹 -- ![](https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExcjA0MGM0NjN0YjR3aGRicHM3YzUyc254ZmxxNjkxdzlnZWZ0NHRjbCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ljtfkyTD3PIUZaKWRi/giphy.webp) 你好呀!如果您像許多有抱負的企業家(包括我)一樣,您可能已經有不少聰明的想法,但很難將它們轉化為有利可圖的副業專案。你不是一個人。許多副業專案都無法賺錢,了解原因是邁向成功的第一步。因此,讓我們深入探討個人創業家/獨立駭客之旅中的常見陷阱,並學習如何避免它們。 開始這段旅程時,重要的是要記住失敗不是敵人。事實上,這是這個過程的關鍵部分。是的,這是殘酷的事實:沒有人是第一次嘗試就成功的。 擁抱失敗並從中學習可以幫助我們避免在未來犯下同樣的錯誤。所以請繫好安全帶,因為我們即將探討業餘專案失敗的常見原因以及如何解決這些問題。 錯誤#1——沒有嘗試 ---------- ![來自levelsio的推文](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bcwyxlln68kmzv853oc.png) 這是來自[@levelsio](https://twitter.com/levelsio)的一條推文,他是一位成功的個體企業家,每月收入超過 15 萬美元,這是一個值得一看的好例子。對失敗的恐懼常常阻礙我們踏出第一步。不要讓這種恐懼阻止你!**嘗試但失敗比根本不嘗試好。** 此外,請記住,完全不嘗試意味著您會錯過寶貴的經驗和成長機會。即使您的專案沒有盈利,您獲得的技能和經驗確實是重點。無論是提高您解決問題的能力,請多了解新市場,還是了解其動態,這些技能都對您未來的專案和麵試非常有益。 所以,下次當你有一個業餘專案的想法時,就去做吧!讓你的好奇心和熱情驅動你,不要讓失敗的恐懼阻礙你。一次又一次地失敗並從錯誤中學習——這是成長的最佳方式,如[@levelsio](https://twitter.com/levelsio)所示。 錯誤#2-失敗的創意 ---------- ![](https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExMzZ5ejdzZWFhbHl6anF1NXNtN2ZwdXJvbmE5NDBxdjZjY2J1Mm84cSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/PbzwVUojP4d8RcRgK0/giphy.webp) 你有這個想法。但它是透過有效的腦力激盪和解決問題形成的嗎?業餘專案的一個常見陷阱是倉促的構思過程。徹底的腦力激盪過程對於確保您的想法的可行性至關重要。 試著用你自己的視角來過濾掉那些與你沒有太多共同點的想法。問題對你來說越是原生,解決方案看起來就越明顯可行。 - 驗證你的想法:僅僅認為它是好的還不夠。您至少需要保證它有市場。進行調查,詢問您信任的人,並收集盡可能多的初始資料。 - 確保你的想法能夠解決問題:一個好的商業想法是能夠填補市場空白或解決人們遇到的問題的想法。 - 評估您的資源:您是否有技能、時間和金錢將您的想法轉化為業務?不要自欺欺人。永遠記住,你可以做一個 MVP(最小可行產品),但是,如果 MVP 不能為用戶帶來真正的價值,那麼它是不夠的。 想要一個例子嗎?查看對[amicus.work](https://www.amicus.work/)的建立者 Erlis 的[訪談](https://wasp-lang.dev/blog/2023/02/14/amicus-indiehacker-interview)。它準確地表明了接近問題如何使解決方案變得直觀。如果您發現自己陷入困境,您可以快速閱讀另一篇[文章](https://dev.to/llxd/creating-a-more-than-minor-side-project-from-planning-to-release-3be8),或者,如果您希望更深入地了解, [Make Book](https://makebook.io/)或[The Lean Startup](https://www.amazon.com/Lean-Startup-Entrepreneurs-Continuous-Innovation/dp/0307887898)也是很好的參考資料,因為它們提供了寶貴的見解,幫助您避免在創業過程中出現常見錯誤。 錯誤 #3 - 無限建置 ------------ ![](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNmoxdm1nN2I4dml0OXNibTg5a2N3bGxhbGprZG10eHR4MmllNzJ0dSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/UAHZijO91QCl2/200.webp) 現在,您的腦海中浮現出技術選擇,您實際上正在考慮學習一種全新的程式語言,只是為了解決這個新問題。來吧,你已經讀過一篇[關於學習的文章](https://dev.to/wasp/the-art-of-self-learning-how-to-teach-yourself-any-programming-concept-5de4)了!沒有什麼可以阻止你! 可是等等!想一想。現在你必須同時處理兩個問題: 1. 學習一門新語言, 2. **並為您的問題建立解決方案。** 將一個奇妙的想法變成一項蓬勃發展的業務已經足夠具有挑戰性了。而且您已經知道許多副專案**在建置階段**都會失敗,那麼為什麼要對自己這樣做呢? 這裡的秘密?創新,但要謹慎! 嘗試那些總是能讓你加速的事情,而不是給你帶來負擔和減慢你的速度的事情。一個例子?已經了解 React 了?嘗試[Wasp](https://wasp-lang.dev/) ,這是一個全端框架,它可以為您處理 Boilerplate(例如 Auth),並使用 AI 生成功能來幫助您更快地建立產品。 當嘗試建立和測試一個想法時,我們不會過度專注於學習新東西,而是**更專注於建立想法本身。**因此,在選擇工具時,請選擇基於您已知的技術並能幫助您快速前進的工具! --- 順便一提: [Wasp](https://wasp-lang.dev/)使本文成為可能,最近,我們發布了 Open SaaS — 一種出色的、100% 免費的開源方式,可用於快速啟動新的 SaaS。一探究竟! https://github.com/wasp-lang/open-saas ⭐️ 使用 Open SaaS 建立您的 SaaS 🙏 [![打開 SaaS 橫幅](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9t2q03c6a86dd4oi1xt.png)](https://opensaas.sh) --- 其他真正常見的錯誤是追求完美,這通常會導致無休止的調整和延誤。請記住,「完成比完美更好」。完成您的專案並將其推向世界至關重要。如果你的專案沒有人看到,那麼它只是一個想法。 錯誤#4 - 從未到達的回饋 -------------- 延誤並不是此階段的唯一障礙。有時,我們過於專注於創造完美的產品,以至於我們忘記了與實際用戶一起驗證它。定期回饋至關重要 - 它可以幫助您做出必要的更改並確保您的產品滿足用戶的需求。 沒有回饋,您永遠不會知道自己是否中了大獎,或者是否正在為無人解決的問題建立解決方案。 ![](https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExM294bHQyaGN3NHVsaWFncW1lNWc3aGIzaG50YWR3c3d2bThxMHdkNyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/4LsN0YwgIsvaU/giphy.webp) 那麼,如何確保獲得必要的回饋呢?首先與一小群用戶測試您的產品。這可以是一群朋友、家人,甚至是一個專門的焦點團體。他們的回饋對於辨識任何問題或需要改進的領域非常有價值。 我們也面臨著收到負面回饋的恐懼,這很常見,這通常會導致產品被拒絕進入市場,直到它「完美」為止。然而,這種方法可能是有害的。儘早發布您的產品至關重要,即使它缺少您計劃加入的一些很酷的功能。用戶的早期回饋可以引導您加入以前沒有想到的功能,但這是實際用戶想要的功能。 請記住,回饋是一份禮物。它可以讓您改進您的產品,使其成為人們不僅使用而且喜歡的東西。所以,不要迴避它,擁抱它! 錯誤#5——羞澀的發布 ----------- 並談論害羞:所以,你已經建立了它,現在怎麼辦?是時候向世界展示它了。然而,請記住,時機就是一切。如果你的發布是羞澀的、計劃不周的,你就不會獲得你需要的用戶(也不會是收入)。 第一步是了解您的受眾並選擇合適的平台。 [Reddit](https://www.reddit.com/)非常適合開源或主要不是由利潤驅動的專案,而[Dev Hunt](https://devhunt.org/) 、 [Product Hunt](https://www.producthunt.com/)和[Hacker News (YC) 則](https://news.ycombinator.com/)非常適合更廣泛的專案。選擇正確的啟動地點可能意味著企業與空無一物之間的差異。 此外,制定策略發布計劃至關重要。儘管有可能發生,但僅發布您的專案並希望獲得最好的結果是不夠的。您需要規劃您的發布,考慮合適的發佈時間、平台的習慣等因素,並調整與目標受眾的溝通。 深思熟慮的啟動計劃不僅可以幫助您吸引更廣泛的受眾,還可以增加專案成功的機會。您應該使用[Screen Studio](https://www.screen.studio/)和[Canva](https://canva.com)等工具來幫助您建立精美的螢幕錄製和宣傳圖像/橫幅。 作為獎勵,這裡有一個啟動計劃範例,可以幫助您入門: - 第一周:準備所有宣傳材料,例如圖像和影片 - 第 2 週:在[Dev Hunt](https://devhunt.org/)上啟動 + 在社群媒體上進行推廣 - 第 3 週:推出[Product Hunt](https://www.producthunt.com/) + [Show HN](https://news.ycombinator.com/show) - 第 4 週及以後:大聲點!繼續在 Reddit、HN 和其他社交媒體平台上進行推廣(不被禁止)。 ![](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNmFzZG14azQ1cjJrc25mY3hoNnk1aWI3bHpnNW45MHkxOWJ6ejd6ciZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/P0ZRTYaCmPsJPNd3r0/giphy.webp) 嘿,你在網路上,所以,儘管你可能會得到很好的回饋,但有些用戶只會對你進行人身攻擊。這很正常,所以不要理會那些生氣的人。如果你的想法被一些隨機的 Reddit 用戶消滅,這絕對不是一種很好的感覺,但時不時地,你實際上也會從誠實的用戶那裡得到一些很棒的見解。這並不容易,但試著辨識哪些回饋應該認真對待,哪些回饋應該忽略:) --- 尋找更多? ----- ![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNWNraHJwazF1cGtxZWI5YmZmaXc1YzZwZms3djJ0eXY4NDhkMGZjZyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/IwAZ6dvvvaTtdI8SD5/giphy.gif) 對更多這樣的內容有興趣嗎?關注我們在[Wasp - DEV Community 的](https://dev.to/wasp)博客,並在 github 上給我們一個星星。這是支持我們的最簡單的方式! https://www.github.com/wasp-lang/wasp ⭐️ GitHub 上的 Star Wasp 🙏 --- 結論 -- 總之,將業餘專案轉變為成功的企業是一個充滿挑戰和勝利的旅程。一路走來,每一步,無論是坎坷或勝利,都是一次寶貴的學習和成長的機會。 每一次失敗都不是終點,而是邁向更大成功的墊腳石,是推動我們前進的教訓。每一次挫折都是重新評估、完善並變得更強大的機會。擁抱這個過程的迭代本質:繼續完善你的想法,堅持不懈地努力改進,最重要的是,永遠不要停止嘗試和學習。 --- 原文出處:https://dev.to/wasp/5-reasons-why-your-side-projects-fail-to-make-money-and-how-to-avoid-them-4l5m

🙅 為什麼我不使用 AI 作為我的副駕駛 🤖

\*\*耶穌,掌管方向盤。 🚗 還有 Github Copilot,使用 IDE。 💻\*\* **[Github 表示](https://github.blog/2023-06-13-survey-reveals-ais-impact-on-the-developer-experience/)**,92% 的美國開發者都在使用 Copilot。 什麼。嚴重地? 什麼時候聽過 92% 的人口使用單一事物? 當然,除非…你說全世界**100%**的人都消耗過一氧化二氫。 *(這條線只有一種變黑的方式。不要去那裡。👀)* 和我一起快速旅行,我將談論: - [我真正擔心的是什麼。](#what-im-actually-worried-about) - [其他經驗豐富的開發人員對此有何看法?](#from-the-experienced-devs-point-of-view) - [也許我什麼都不擔心?](#lets-take-a-step-back-for-a-moment) - [以及我們如何對我們如何使用LLMs負責!](#where-the-heck-does-llmai-fit-in) ### 🔥 當機器在 2024 年佔領世界時 經過谷歌快速搜尋後,似乎大多數開發人員都在使用人工智慧輔助來編寫程式碼。如果我說我根本沒有使用人工智慧來編寫程式碼,**那我就是在撒謊**。當然,我有。我並不住在岩石下。 我發現開發人員對與第三方雲端服務共享程式碼相關資料的想法感到奇怪,這些第三方雲端服務通常沒有 SOC2(或類似的東西)認證,並且充其量只能做出模糊且無法證明的隱私聲明。 Github Copilot(和 Copilot 聊天)、Bito.ai 以及 VS Code 市場上的其他幾個 AI 程式碼擴充的安裝量已超過 3000 萬。瘋狂的! 🤯 然後是我。**我還沒有將人工智慧輔助**納入我的常規程式碼工作流程中。當然,我有幾次在 GPT 的幫助下編寫了一些樣板檔案。但那些時候是個例外。像 Github Copilot 這樣的東西,或任何類型的程式碼審查、程式碼產生工具、PR 建立或提交協助,都不屬於我的 IDE 或 CLI 流程的一部分。 也許它會隨著時間而改變。我們拭目以待。 > ## “但為什麼?” ![但為什麼](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bpc1fc4t5a10j0i5r3wj.gif) ### 😟我真正擔心的是 答案很簡單。 👇 #### 1.我擔心我的程式設計技能會生疏 我擔心如果我太習慣人工智慧的幫助,我編寫和閱讀程式碼的方式將會受到影響。 - 我擔心我會開始**忽略**程式碼中的缺陷,否則我可以發現這些缺陷。 - 我將開始認為人工智慧產生的程式碼是**理所當然的**。 - 尋找 API、內建方法或其他文件將開始變得像一件**苦差事**。 我擔心……我會開始滑倒。 #### 2. 我不願意與第三方服務分享我的所有程式碼 公司可以非常聰明地從你提供的資料中推斷出一些事情。有時他們會知道[你的家人不知道的](https://www.forbes.com/sites/kashmirhill/2012/02/16/how-target-figured-out-a-teen-girl-was-pregnant-before-her-father-did/)事。 敏感的業務邏輯可能會洩漏給第三方服務,最終可能會被用來做出我不滿意的推論,或者只是…直接洩漏?我的意思是,軟體總是被駭客攻擊。 我認為我很合理地認為我不想以不受限制的方式向第三方公司公開像程式碼這樣敏感的東西。即使那家公司是微軟,[因為即使他們也搞砸了](https://www.wired.com/story/total-recall-windows-recall-ai/)。 ### 👀 從經驗豐富的開發人員的角度來看 這也不是我獨有的想法! #### 1. 經驗豐富的開發人員往往**不想依賴**「拐杖」來寫程式碼。 我甚至很高興與不想在 IDE 上使用彩色主題的高級開發人員合作,因為他們認為這會損害他們掃描、閱讀或偵錯程式碼的能力! (這對我來說也有點太多了) 畢竟,「程式設計技能」**不僅僅是編寫程式碼**。 #### 2. 老開發者看過各種**軟體被駭**、資料外洩等。 我的意思是,十多年來, [haveibeenpwned.com](https://haveibeenpwned.com/)每年都會向您發送有關您的憑證、電子郵件和其他資料外洩的電子郵件…很多時候來自[價值數十億](https://en.wikipedia.org/wiki/2017_Equifax_data_breach)[美元的](https://www.news18.com/india/indias-biggest-data-leak-so-far-covid-19-test-info-of-81-5cr-citizens-with-icmr-up-for-sale-exclusive-8637743.html)[公司](https://www.nytimes.com/2017/10/03/technology/yahoo-hack-3-billion-users.html)… 當你無數次聽到**「當你不為產品付費時,你就是產品」** ,然後又得到另一家將資料出售給第三方的公司的支持... 是啊……會很累。 只需斷開盡可能多的電線即可輕鬆回到石器時代。 > ![老馬特達蒙](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/03pmbpqix6e199ewey5t.gif) > “老開發人員”?我是……我變老了嗎? > 不,我才 22 歲,現在已經是 2016 年了……對吧?正確的? **順便說一句,標題中問題的答案是👆這個。**恭喜!貼文結束了!轉到下一個… Buuuuut…如果你想繼續閱讀… ![喬伊還有更多](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jk0ywd7yjqukeokd0t2d.gif) ### 🚶 讓我們退後一步...... #### 我認為我的擔心可能被誇大了。 > *現在讓我們把整個資料隱私的角度放在一邊,因為這本身就是一個我非常熱衷的另一個主題。* 我個人沒有足夠的資料來經驗說使用人工智慧輔助會帶來我擔心的厄運……它會將我從今天的樣子降級為[SDE1](https://dev.to/middleware/going-from-sde1-to-sde2-and-beyond-what-it-actually-takes-1cld) 。 但我已經看到了模式。 - 我見過人工智慧生成的低於標準品質的程式碼經過程式碼審查並最終出現在`main`分支上。 - 我見過一些函式庫函數在沒有正確理解存在什麼或存在什麼替代方案的情況下被使用,只是因為LLMs產生了它。 - 我什至見過為解決某個問題而生成的程式碼,對於該問題,程式碼庫中已經存在一個實用程式函數,但沒有使用它,因為知道這個實用程式的存在比要求GPT 為您生成它要多得多的工作。 ### 💎 ~~鑽石是~~ 糟糕的程式碼是永遠的 **“等一下……我以前看過這部電影!”** ![似曾相識](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvun4635neb2dflv5yto.gif) - LLM 是一個相當新的事物…但是💩程式碼是**永恆的!** - 每一個。單身的。開發。曾經。在沒有完全**理解**或尋找替代方案的情況下使用了函式庫函數。你和我都對此有罪。 (什麼?您認為`Array.prototype.sort`是對任何內容進行排序的最佳方式?在大多數情況下它就足夠了!) - 一段邏輯總是被重新發明(重新複製貼上)!只是之前它來自**StackOverflow** ,現在它來自 ChatGPT 。 ### 🤷 那麼,有什麼好大驚小怪的呢? > “使用 ChatGPT 會讓我成為一個糟糕的程式設計師嗎?” 我想不是。 重點是您只需要關心您建立的內容。 為您所**建造的**東西感到**自豪**。 ### 🤖 LLM/AI 到底適合什麼? **LLM 本身並不是邪惡的。** 事實上,如果負責任地使用它們,它們會非常有用: - **品質程式碼:**LLMs可能會處理不太勤奮的開發人員不會考慮的邊緣情況。 - **綜合測試:**LLMs可能會編寫比某些開發人員編寫的測試更全面的測試。 - **綜合類型:**它甚至可能比普通開發人員自己編寫的類型或可能具有編寫技能的類型更「完整」地編寫類型。 然而,開發人員有責任確保程式碼輸出受到保護和良好監控。一個不在乎的人在歷史上的任何時候都會做得很糟糕。LLMs的存在並沒有改變這一點。 ### 😎 真正給予 a\*ck 的藝術 有很多開發者對此並不關心。 但你不是這樣的開發者。**你確實關心。** 否則你就不會在這裡開發並學習人們的經驗。 我最近寫了一篇關於新開發人員在職涯中應該關心什麼成長的文章。它不僅僅是程式碼。 https://dev.to/middleware/going-from-sde1-to-sde2-and-beyond-what-it-actually-takes-1cld **也許我會在 VSCode 中引入一些 AI。** 我認為這只是時間問題,而不是**是否有問題**。 更重要的是……只要我關心確保我的程式輸出**可讀、高效能、高品質且易於審查**,我想我會沒事的,你也一樣。 --- ### 👇 PS 如果您想要一個我非常關心的範例,並且具有出色的程式碼 💪 和…不太出色的程式碼 🤣,請查看我們的**開源**儲存庫! 它可以讓您了解交付程式碼需要多長時間、PR 陷入審查循環的次數以及您的團隊交付程式碼的整體情況。 https://github.com/middlewarehq/middleware --- 原文出處:https://dev.to/middleware/why-i-dont-use-ai-as-my-copilot-47k3

如何在行動裝置上測試本地網站

在建立網站時,開發人員通常需要測試他們的網站是否響應靈敏、經過優化並且在行動裝置上運作良好。如果他們不知道一種簡單且正確的方法來進行測試,那麼測試可能會令人沮喪。 在這篇文章中,我將向您展示如何透過三個簡單的步驟在行動裝置上測試本地網站。儘管瀏覽器開發工具可以提供幫助,但有時您可能需要更好的視覺化、清晰度和與專案的觸控互動。在這種情況下,在實際手機上進行測試可能比使用瀏覽器的行動螢幕更好。 要在手機上查看本地網站的即時預覽,請確保您的手機和桌面連接到相同 WiFi 網路。如果尚未安裝,請安裝[VS Code](https://code.visualstudio.com/)編輯器和[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)擴充功能。 在電話上測試本地網站的步驟 ------------- 下載 VS Code 編輯器及其 Liver Server 擴充功能後,現在請按照給定的 3 個步驟逐行查看手機上的本機專案: ### 1. 執行實時伺服器 首先,在 VS Code 中開啟專案資料夾。然後,點擊右下角的「上線」按鈕。這將為您的專案啟動本機開發伺服器,通常在連接埠`5500`上執行。 您的專案現在應該在預設的 Web 瀏覽器中執行。記下連接埠號碼(5500 或其他數字,如果不同)。 ![執行實時伺服器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5bxampc1npsnupyvfwrf.jpg) ### 2. 尋找您的本地 IPv4 位址 接下來,您需要本機 IPv4 位址。開啟命令提示字元 (CMD),鍵入 ipconfig,然後按 Enter。在「無線 LAN 適配器 Wi-Fi」部分下尋找您的 IPv4 位址。它看起來像`192.168.1.68` 。 請記住,如果新設備連接或斷開與您的 WiFi 網路的連接,您的本地 IP 位址可能會發生變化。 ![尋找您的本機 IPv4 位址](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggaldbbpfdf26cbbqebk.jpg) ### 3. 在手機上查看您的專案 開啟手機上的瀏覽器並輸入您的 IPv4 位址,然後輸入連接埠號碼。 URL 應如下所示: `192.168.1.68:5500` 。 如果您的主 HTML 檔案未命名為 index.html,則需要在 URL 中包含檔案名,如下所示: `192.168.1.68:5500/filename.html` 。 ![在手機上查看您的專案](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qoy2k744fqngq9bsz35.jpg) 現在您應該在手機上看到專案的即時預覽。您在桌面上的 VS Code 中所做的任何更改都會立即反映在您的手機上,無需手動刷新。 常見錯誤故障排除 -------- 如果您遇到「無法存取網站」或類似內容的錯誤,請嘗試以下故障排除步驟: - **仔細檢查 IPv4 位址和連接埠號碼:**確保您在手機瀏覽器中輸入了正確的 IPv4 位址和連接埠號碼。 - **檢查網路連線:**確保您的手機和桌面連接到相同 WiFi 網路。 - **檢查檔案路徑:**如果您的主 HTML 檔案不是`index.html` ,請確保 URL 中包含正確的檔案路徑。 - **防火牆設定:**您電腦的防火牆可能阻止連線。調整設定以允許 Live Server 使用的連接埠號碼上的流量。 結論 -- 在這篇文章中,您學習如何在手機上查看專案的即時預覽。此方法適用於使用[HTML、CSS](https://www.codingnepalweb.com/category/html-and-css/)和[JavaScript](https://www.codingnepalweb.com/category/javascript/)以及其他框架專案建立的靜態專案。 如果您想提高編碼的準確性、速度和效能,請查看我的部落格文章《[面向 Web 開發人員的十大有用 VS 程式碼擴充》](https://www.codingnepalweb.com/top-vs-code-extensions-for-web-developers/) 。 如果您發現本指南有幫助,請與其他人分享! --- 原文出處:https://dev.to/codingnepal/how-to-test-local-website-on-mobile-devices-2p69

掌握整潔程式碼:開發人員的基本實踐

乾淨的程式碼是每個成功的軟體專案的基石。作為開發人員,編寫乾淨、可維護的程式碼的能力對於應用程式的效率和壽命至關重要。在本文中,我們將深入研究 JavaScript 中好的和壞的編碼實踐的十個範例,強調編寫乾淨程式碼並提供可操作的見解以幫助您提高開發技能的重要性。 例子 -- - 描述性變數名稱: ``` // Good: const totalPrice = calculateTotalPrice(quantity, unitPrice); ``` ``` // Bad: const t = calcPrice(q, uP); ``` 在一個很好的例子中,變數名稱具有描述性並清楚地表達了它們的目的,從而增強了程式碼的可讀性。相反,糟糕的範例使用神秘的縮寫,使其他人難以理解程式碼的意圖。 - 一致的格式: ``` // Good: function greet(name) { return `Hello, ${name}!`; } ``` ``` // Bad: function greet(name){ return `Hello, ${name}!` } ``` 一致的格式提高了程式碼的可讀性和可維護性。在一個很好的例子中,採用了適當的縮排和間距,並增強了程式碼結構。相反,壞例子缺乏一致性,使得程式碼更難遵循。 - 避免魔法數字: ``` // Good: const TAX_RATE = 0.1; const totalPrice = subtotal + (subtotal * TAX_RATE); ``` ``` // Bad: const totalPrice = subtotal + (subtotal * 0.1); ``` 幻數掩蓋了值的含義,並使程式碼更難維護。在很好的例子中,常數用於表示幻數,提高了程式碼的清晰度和可維護性。 - 單一責任原則: ``` // Good: function calculateTotalPrice(quantity, unitPrice) { return quantity * unitPrice; } function formatPrice(price) { return `$${price.toFixed(2)}`; } ``` ``` // Bad: function calculateAndFormatTotalPrice(quantity, unitPrice) { const totalPrice = quantity * unitPrice; return `$${totalPrice.toFixed(2)}`; } ``` 函數應該有單一的責任來提高程式碼的可重複使用性和可維護性。在這個很好的例子中,每個函數都執行特定的任務,並遵循單一職責原則。相反,壞例子將多個職責組合到一個函數中,違反了這個原則。 - 錯誤處理: ``` // Good: function fetchData(url) { return fetch(url) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .catch(error => { console.error('Error fetching data:', error); throw error; }); } ``` ``` // Bad: function fetchData(url) { return fetch(url) .then(response => response.json()) .catch(error => console.error(error)); } ``` 正確的錯誤處理可以提高程式碼的穩健性,並有助於更有效地辨識和解決問題。在好的範例中,錯誤得到了妥善處理,為開發人員提供了有意義的回饋。相反,壞範例缺乏全面的錯誤處理,可能導致靜默故障。 - 評論和文件: ``` // Good: // Calculate the total price based on quantity and unit price function calculateTotalPrice(quantity, unitPrice) { return quantity * unitPrice; } ``` ``` // Bad: function calculateTotalPrice(quantity, unitPrice) { // calculate total price return quantity * unitPrice; } ``` 註釋和文件增強了程式碼的可理解性並促進了開發人員之間的協作。在一個很好的範例中,清晰的註解描述了函數的用途,有助於程式碼理解。相反,壞例子提供的模糊評論幾乎沒有什麼價值。 - 適當的模組化: ``` // Good: export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; } ``` ``` // Bad: function add(a, b) { return a + b; } function subtract(a, b) { return a - b; } ``` 模組化程式碼透過將功能組織成內聚的單元來提高可重複使用性和可維護性。在好的例子中,函數被正確地封裝和匯出,促進程式碼重用。相反,壞例子缺乏模組化,使其更難以管理和擴展。 - DRY 原則(不要重複): ``` // Good: const greeting = 'Hello'; function greet(name) { return `${greeting}, ${name}!`; } ``` ``` // Bad: function greet(name) { const greeting = 'Hello'; return `${greeting}, ${name}!`; } ``` 重複的程式碼會增加錯誤的風險並使維護變得困難。一個很好的例子是,將重複的字串提取為常數,遵循DRY原則並提高程式碼的可維護性。相反,壞範例在函數內冗餘地定義了問候語。 - 有意義的函數名稱: ``` // Good: function calculateArea(radius) { return Math.PI * radius ** 2; } ``` ``` // Bad: function calc(r) { return Math.PI * r ** 2; } ``` 函數名稱應準確反映其用途,以增強程式碼可讀性。在這個很好的例子中,函數名稱“calculateArea”清楚地表明了它的功能。相反,糟糕的例子使用了神秘的縮寫(“calc”),讓人不清楚函數的作用。 - 可測試性: ``` // Good: function sum(a, b) { return a + b; } module.exports = sum; ``` ``` // Bad: function sum(a, b) { console.log(a + b); } ``` 編寫可測試的程式碼有利於自動化測試,確保程式碼的可靠性和穩定性。在很好的範例中,函數被匯出用於測試目的,從而可以輕鬆設定和執行測試。相反,壞範例包含副作用(console.log),使得測試函數的行為變得具有挑戰性。 - 正確使用資料結構: ``` // Good: const studentGrades = [90, 85, 95, 88]; const averageGrade = studentGrades.reduce((total, grade) => total + grade, 0) / studentGrades.length; ``` ``` // Bad: const grade1 = 90; const grade2 = 85; const grade3 = 95; const grade4 = 88; const averageGrade = (grade1 + grade2 + grade3 + grade4) / 4; ``` 使用適當的資料結構可以增強程式碼的可讀性和可維護性。在很好的例子中,陣列用於儲存學生成績,以便於操作和計算。相反,壞範例依賴單一變數,導致重複且容易出錯的程式碼。 - 處理非同步操作: ``` // Good: async function fetchData(url) { try { const response = await fetch(url); if (!response.ok) { throw new Error('Network response was not ok'); } return await response.json(); } catch (error) { console.error('Error fetching data:', error); throw error; } } ``` ``` // Bad: function fetchData(url) { return fetch(url) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .catch(error => { console.error('Error fetching data:', error); throw error; }); } ``` 正確處理非同步操作可確保程式碼的可靠性和健全性。在一個很好的例子中,async/await 語法用於簡化非同步程式碼並優雅地處理錯誤。相反,壞範例使用嵌套的 Promise,導致回調地獄並降低程式碼可讀性。 - 依賴管理: ``` // Good: import { format } from 'date-fns'; ``` ``` // Bad: const dateFns = require('date-fns'); ``` 有效的依賴管理可以促進程式碼模組化和可擴展性。在一個很好的範例中,ES6 導入語法用於僅從“date-fns”庫導入所需的功能,從而減少不必要的導入並提高效能。相反,糟糕的範例使用 CommonJS require 語法,該語法導入整個“date-fns”模組,可能會使應用程式套件膨脹。 - 效能優化: ``` // Good: const sortedNumbers = [5, 2, 8, 1, 9]; sortedNumbers.sort((a, b) => a - b); ``` ``` // Bad: const unsortedNumbers = [5, 2, 8, 1, 9]; const sortedNumbers = unsortedNumbers.sort(); ``` 優化程式碼效能可確保高效執行並增強使用者體驗。在一個很好的範例中,使用自訂比較函數呼叫 sort() 方法來按升序對數字進行排序,與預設排序演算法相比,可以獲得更好的效能。相反,壞範例依賴於預設排序演算法,這對於數值陣列可能不是最有效的。 - Node.js API 中的正確錯誤處理: ``` // Good: app.get('/user/:id', async (req, res) => { try { const user = await getUserById(req.params.id); if (!user) { return res.status(404).json({ error: 'User not found' }); } res.json(user); } catch (error) { console.error('Error fetching user:', error); res.status(500).json({ error: 'Internal server error' }); } }); ``` ``` // Bad: app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); if (!user) { res.status(404).json({ error: 'User not found' }); } res.json(user); }); ``` 在 Node.js API 中,正確的錯誤處理對於確保穩健性和可靠性至關重要。在好的範例中,錯誤被捕獲並記錄,並且適當的 HTTP 狀態程式碼被返回到客戶端。相反,壞範例無法處理錯誤,可能導致未處理的承諾拒絕和不一致的錯誤回應。 - 高效率的檔案系統操作: ``` // Good: const fs = require('fs').promises; async function readFile(filePath) { try { const data = await fs.readFile(filePath, 'utf-8'); console.log(data); } catch (error) { console.error('Error reading file:', error); } } ``` ``` // Bad: const fs = require('fs'); function readFile(filePath) { fs.readFile(filePath, 'utf-8', (error, data) => { if (error) { console.error('Error reading file:', error); return; } console.log(data); }); } ``` 在檔案系統操作中使用 Promise 可以增強程式碼可讀性並簡化錯誤處理。在一個很好的範例中,fs.promises.readFile() 用於非同步讀取文件,並使用 try-catch 處理錯誤。相反,壞範例使用基於回調的方法,這可能導致回調地獄和可讀性較差的程式碼。 - 高效率的記憶體管理: ``` // Good: const stream = fs.createReadStream('bigfile.txt'); stream.pipe(response); ``` // 壞的: ``` fs.readFile('bigfile.txt', (error, data) => { if (error) { console.error('Error reading file:', error); return; } response.write(data); }); ``` 在 Node.js 中使用流進行大檔案處理可以節省記憶體並提高效能。在一個很好的例子中,fs.createReadStream() 和stream.pipe() 用於有效地將資料從檔案串流傳輸到HTTP 回應。相反,壞示例在將整個文件寫入響應之前將其讀入內存,這可能會導致大文件出現內存問題。 - 正確的模組導出和導入: ``` // Good: module.exports = { add: (a, b) => a + b, subtract: (a, b) => a - b }; ``` ``` // Bad: exports.add = (a, b) => a + b; exports.subtract = (a, b) => a - b; ``` 一致的模組導出和導入實踐提高了程式碼的可讀性和可維護性。在好的例子中, module.exports 用來匯出包含函數的物件,而在壞的例子中,直接使用exports。儘管這兩種方法都有效,但堅持一種約定可以增強程式碼的一致性。 - 非同步控制流程: ``` // Good: async function processItems(items) { for (const item of items) { await processItem(item); } } ``` ``` // Bad: function processItems(items) { items.forEach(item => { processItem(item); }); } ``` 適當的非同步控制流程可確保操作依需求順序或併發執行。在一個很好的範例中,非同步函數與 for...of 迴圈一起使用來順序處理專案,等待每個操作。相反,壞的例子使用了 forEach,它不能很好地處理非同步操作,並且可能會導致意外的行為。 --- 原文出處:https://dev.to/mahabubr/mastering-clean-code-essential-practices-for-developers-1287

如何在NodeJS中實現授權

**介紹:** ------- 身份驗證和授權是 Web 應用程式安全性中的兩個基本概念。當我們建立 Web 應用程式時,確保只有正確的使用者才能存取我們網站的某些部分對於安全性至關重要。這就是身份驗證和授權發揮作用的地方。 在本文中,我們將討論身份驗證和授權,以及如何在 Nodejs 應用程式中實作它們。 那麼事不宜遲,讓我們開始吧! **了解授權** -------- ![顯示 HTML 程式碼的電腦螢幕特寫,並顯示錯誤訊息「驗證失敗。請聯絡管理員」。](https://images.unsplash.com/photo-1618044619888-009e412ff12a?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D) ### **什麼是授權?** 授權是授予使用者執行特定工作/操作的權限的過程。它決定允許經過身份驗證的使用者在應用程式內執行哪些操作。經過驗證後,授權可確保使用者僅執行允許執行的操作,並遵循特定的規則和權限。 一些常見的身份驗證方式是: - 基於角色的存取控制 (RBAC) - 基於屬性的存取控制 (ABAC) - 基於策略的存取控制(PBAC) ### **授權如何運作?** 授權過程如下: - 經過身份驗證的使用者向伺服器發出請求。 - 伺服器驗證使用者並取得其指派的角色和權限。 - 伺服器評估使用者是否有權執行所請求的操作。 - 如果使用者獲得授權,伺服器將允許使用者執行請求的操作。 - 否則,它會拒絕存取並返回適當的回應。 ### **什麼是基於角色的存取控制 (RBAC)?** ![說明基於角色的存取控制 (RBAC) 的圖表。客戶端將帶有使用者憑證的管理服務請求傳送到管理節點管理器。管理節點管理器定義權限層級的角色,與服務 1、服務 2 和服務 3 互動以執行身份驗證並確保用戶端有權存取。然後客戶端接收並處理回應。](https://lh7-us.googleusercontent.com/mpwrmZ13hD2p5SL6s64A4USQOMGxvUT46zMXkyjcHC0nKGRfF_JHIdrkOR6FWZrpmNf35a8mLMGYRow84v--hZUNjNOkxTQj3I1Yi-KCtB4O8dfHqOK3N8Ejv1Xa6-J5-rY8YQNutGpzk_jXT9-pjvg) 基於角色的存取控制是一種存取控制方法,它根據使用者在應用程式中分配的角色向使用者授予權限。簡而言之,它控制用戶在應用程式中可以執行的操作。 RBAC 不是將權限指派給單一用戶,而是將使用者分組為角色,然後將權限指派給這些角色。這使得管理存取控制變得更加容易,因為我們只需要更新角色的權限,而不是每個單獨使用者的權限。 RBAC 的關鍵元件是: - 角色:定義應用程式內的一組職責、任務或功能 - 權限:代表使用者可以執行的特定操作。 - 角色分配:使用者被指派給一個或多個角色,每個角色都與一組權限相關聯。 - 存取控制策略:規定哪些角色可以存取特定資源以及他們可以採取哪些操作。 **在 NodeJS 中實作授權** ------------------ 到目前為止,我們已經了解了身份驗證和授權。讓我們探索如何在 NodeJS 應用程式中實現它們。 在本節中,我們將建立一個簡單的 NodeJs 應用程式並整合身份驗證和授權功能。 ### 基本專案設定和身份驗證 要設定基本的 Node.js 專案並新增 JWT 身份驗證,您可以查看以下文章,其中我詳細解釋了每個步驟: [設定基本 Node.js 專案並新增 JWT Auth](https://arindam1729.hashnode.dev/jwt-authentication-in-nodejs#heading-project-setup) ### **實施授權** 在本節中,我們將在 Nodejs 應用程式中實作授權。 #### 1. 更新用戶架構: 我們將更新使用者架構並新增一個「角色」字段,我們將在其中定義使用者的角色/範圍。我們將在後面的部分中使用這些角色進行授權。 ``` const mongoose = require("mongoose"); const userSchema = new mongoose.Schema({ username: { type: String, required: true, unique: true, }, password: { type: String, required: true, }, role:{ type: String, required: true, default: "user", } }); module.exports = mongoose.model("User", userSchema); ``` #### 2. 更新認證路由: 接下來,我們將更新`/signup`和`/login`路由。我們將從註冊路由的請求正文中獲取新新增的角色。 ``` // updated sign up router.post("/signup", async (req, res) => { try { const { username, password, role } = req.body; const user = new User({ username, password,role }); await user.save(); res.status(201).json({ message: "New user registered successfully" }); } catch (error) { res.status(500).json({ message: "Internal server error" }); } }); ``` 在登入路徑中,就像使用者名稱和密碼驗證一樣,我們也會驗證使用者的角色。 ``` // Updated Login route router.post("/login", async (req, res) => { const { username, password, role } = req.body; try { const user = await User.findOne({ username }); if (!user) { return res.status(401).json({ message: "Invalid username or password" }); } if (user.password !== password) { return res.status(401).json({ message: 'Invalid username or password' }); } if (user.role !== role) { return res.status(401).json({ message: 'Invalid role' }); } // Generate JWT token const token = jwt.sign( { id: user._id, username: user.username, role: user.role}, process.env.JWT_SECRET ); res.json({ token }); } catch (error) { res.status(500).json({ message: "Internal server error" }); } }); ``` #### 3. 建立管理驗證中間件: 現在,我們將建立一個中間件來驗證使用者是否是管理員。 ``` function verifyAdmin(req, res, next) { if (req.user.role !== "admin") { return res.status(401).json({ message: "Access denied. You need an Admin role to get access." }); } next(); } module.exports = verifyAdmin; ``` #### 4. 建立管理路由: 之後,我們將在主`index.js`中建立一個管理路由來驗證使用者是否具有管理員存取權限。 ``` // index.js const adminMiddleware = require("./middleware/admin"); app.get("/admin", userMiddleware, adminMiddleware, (req, res) => { const { username } = req.user; res.send(`This is an Admin Route. Welcome ${username}`); }); ``` #### 5. 測試端點: 在註冊路徑中,我們將建立一個具有管理員角色的新使用者。 為此,我們將使用以下正文向[`http://localhost:3000/auth/signup`](http://localhost:3000/auth/signup)發出 POST 請求: ``` {     "username": "Arindam Majumder",     "password": "071204",     "role": "admin" } ``` ![Postman 介面的螢幕截圖,顯示了「http://localhost:3000/auth/signup」的 POST 要求,其中包含包含使用者名稱、密碼和角色的 JSON 正文。回應正文顯示一則訊息:“新用戶註冊成功”,狀態為 201 Created。](https://lh7-us.googleusercontent.com/4AsIcyQYmEgP38jlExZ0JJk_nnzCLvbn6Vflg2w_fHMgnGv39JenYDBhd5W0OgOT516USD-RoPIVWqYPXBCmxMRfhUSOXcEjizs3ZELeAps6AqcB6PX7rM6Tpd1XJt2kgm0UVQ_xYmgNQTc2Cm1tKC4) 新用戶已註冊。我們更新後的註冊報價正常運作。 同樣,在登入路由中,我們將取得新使用者的令牌。 為此,我們將使用類似的正文向[`http://localhost:3000/auth/login`](http://localhost:3000/auth/login)發出 GET 請求: ``` { "username": "Arindam Majumder", "password": "071204", "role": "admin" } ``` 我們將得到一個像這樣的令牌: ![Postman 介面的螢幕截圖顯示了對「http://localhost:3000/auth/login」的 POST 要求。請求內文包含 JSON 資料,其中包含「使用者名稱」、「密碼」和「角色」欄位。回應正文顯示帶有「令牌」欄位的 JSON 物件。請求的狀態為 200 OK。](https://lh7-us.googleusercontent.com/H76nwPmFj-vCvnULTn0dmo2ABKjuHBx-aemMNYo9DCGTsSaKj_RpxrvdyQuENgGFN-TDefoN_-78fAenWQ3UjSeHkCpq1EIAceTWqTdbaKkvvbiTXYlrovVmYzmALcmYMakMyXw_xx7MYAm1NNWBoM8) 現在,我們將測試我們的管理路由。為此,我們將使用以下正文向[`http://localhost:3000/admin`](http://localhost:3000/admin)發出 GET 請求: ``` { "username": "Arindam Majumder", "password": "071204", "role": "admin" } ``` 這次我們還必須加入一個授權標頭並在其中加入令牌來驗證我們的用戶。 ``` Authorization = USERS_JWT_TOKEN ``` 我們將得到以下回應: ![Postman 介面的螢幕截圖,顯示了「http://localhost:3000/admin」的 GET 要求,其中包含 JSON 正文參數,包括「使用者名稱」、「密碼」和「角色」。回應部分顯示一條訊息:“這是一條管理路線。歡迎 Arindam Majumder。”狀態為 200 OK。](https://lh7-us.googleusercontent.com/hXtX9n0Bb0fJl50zJRbA50XGLPGwpKsgffdkQa_-w58p_Oo9fillBPy9f6k0jH2SOz2FOh5xwdKPLXqCcqerrrMgUpQkA2AKdqnZGN_tGjEYIiUJCqcCuibc-7Z-W-j7hlfXUOTtwf4oQQC5NvuetNA) 這意味著我們的端點正在按預期工作。 至此,我們已經在 NodeJs 應用程式中成功實現了授權。 **結論** ------ 總的來說,身份驗證和授權在現代 Web 應用程式中非常重要。 在本文中,我們介紹了身份驗證和授權的基礎知識以及如何將它們整合到 NodeJs 應用程式中。 希望您覺得這有幫助。不要忘記分享您對評論的回饋。 如需付費合作,請發送電子郵件至: <[email protected]> 在[Twitter](https://twitter.com/intent/follow?screen_name=Arindam_1729) 、 [LinkedIn](https://www.linkedin.com/in/arindam2004/) 、 [Youtube](https://www.youtube.com/channel/@Arindam_1729)和[GitHub](https://github.com/Arindam200)上與我聯絡。 快樂編碼! ![謝謝 :)](https://cdn.hashnode.com/res/hashnode/image/upload/v1713555130149/625f8664-4caa-4318-bfe7-97bec77085bb.png) --- 原文出處:https://dev.to/arindam_1729/how-to-implement-authorization-in-nodejs-31hk

同步引擎是 Web 應用程式的未來嗎?

請看下面的 GIF — 它顯示了一個即時[Todo-MVC 演示](https://todo-replicache-sveltekit.onrender.com/),跨視窗同步並平滑地進出離線模式。雖然它只是一個簡單的演示應用程式,但它展示了每個 Web 開發人員都應該了解的重要的前沿概念。這是一個[Replicache](https://replicache.dev/)演示應用程式,我將其從 Express 後端和 Web 元件前端移植到 SvelteKit,以了解背後的技術和概念。我想與您分享我的學習成果。原始碼可[在 Github 上](https://github.com/isaacHagoel/todo-replicache-sveltekit)取得。 ![sveltekit-replicache-演示](https://github.com/isaacHagoel/todo-replicache-sveltekit/assets/20507787/11b5ae10-049d-4cc7-82bf-45d8287701f0) 背景和動機 ----- Web 應用程式面臨一些根本性的難題,而大多數 Web 框架似乎都忽略了這些問題。這些問題非常困難,以至於只有很少的應用程式能夠真正很好地解決它們,並且這些應用程式在各自的領域中遙遙領先於其他應用程式。 以下是我在實際開發的商業應用程式中必須處理的一些此類問題: 1. 讓應用程式感覺敏捷,即使它與伺服器通信,即使在緩慢或不穩定的網路上。這不僅適用於初始載入時間,也適用於應用程式載入後的互動。 [SPA](https://developer.mozilla.org/en-US/docs/Glossary/SPA)是解決這個問題的早期嘗試,但最終還不夠。 2. 為使用者產生的內容(例如網站建立、電子商務、線上課程建構器)實施撤銷/重做和版本歷史記錄。 3. 當同一用戶在多個分頁/裝置上同時開啟應用程式時,請讓應用程式正常運作。 4. 處理執行舊版本前端的長期會話,使用者可能不想刷新以避免丟失工作。 5. 使協作功能/多人遊戲功能正確且近乎即時地工作,包括解決衝突。 我在開發完全正常的 Web 應用程式時遇到了這些問題,沒有什麼太瘋狂的,而且我相信大多數 Web 應用程式在獲得吸引力時都會遇到部分或全部問題。 我在開始開發新產品的開發團隊中註意到的一個模式是完全忽略這些問題,即使團隊已經意識到這些問題。推理通常是這樣的:“當我們真正開始遇到這些問題時,我們會處理它。”然後,團隊將繼續選擇一些完善的框架(選擇您最喜歡的),認為這些工具肯定能為可能出現的任何常見問題提供解決方案。幾個月後,當應用程式達到一萬名活躍用戶時,現實就浮出水面:團隊必須引入部分的、不完整的解決方案,這些解決方案會增加複雜性,使系統更加緩慢和錯誤,或者重寫核心部分(之後沒有人立即這樣做)發射)。哎喲。 我感受到了這種痛苦。痛苦是真實的。 輸入“同步引擎”。 同步引擎到底是什麼? ---------- 還記得我說過有些應用程式比其他應用程式更好地解決這些問題嗎?最近著名的例子是[Linear](https://linear.app/isaach)和[Figma](https://www.figma.com/) 。兩者都透過技術優勢擾亂了競爭異常激烈的市場。其他例子有[Super human](https://superhuman.com/)和十年前的[Trello](https://trello.com/) 。當您研究他們所做的事情時,您會發現它們都集中在非常相似的模式上,並且它們都在內部開發了各自的實現。您可以在以下連結中了解他們是如何做到的(強烈推薦): [Figma](https://www.figma.com/blog/how-figmas-multiplayer-technology-works/) 、 [Linear](https://www.youtube.com/live/WxK11RsLqp4?feature=share&t=2175) 、 [Super human](https://blog.superhuman.com/superhuman-is-built-for-speed/) 、 [Trello(系列)](https://www.atlassian.com/engineering/sync-architecture) 。 在系統的核心,始終有一個同步引擎,可作為前端和後端之間的持久緩衝區。從高層次來看,它是這樣運作的: - 客戶端始終讀取和寫入引擎提供的本地儲存。就應用程式程式碼而言,它在記憶體中本地執行。 - 該儲存負責樂觀地更新狀態,將資料本地保存在瀏覽器的儲存中,並與後端來回同步,包括處理潛在的複雜情況和邊緣情況。 - 後端實作引擎的另一半,以允許拉取和推播資料、在資料變更時通知客戶端、將資料保存在資料庫中等。 同步引擎的不同實作會做出不同的權衡,但基本概念始終是相同的。 這不是一個新想法,但... ------------- If you've been following trends in the web-dev world, you'd know that sync engines have been a centrepiece in several of them, namely: [progressive web apps](https://web.dev/articles/what-are-pwas) , [offline-first apps](https://offlinefirst.org/) , and the lately trending term: [local-first軟體](https://www.inkandswitch.com/local-first/).您甚至可能研究過一些提供內建同步引擎的資料庫,例如[PouchDb](https://pouchdb.com/)或具有相同功能的線上服務(例如[Firestore](https://firebase.google.com/docs/firestore) )。我也有,但過去幾年我的整體感覺是,這些都不是切中要害的。漸進式網頁應用程式是關於用戶在主螢幕上「安裝」網站的快捷方式,就好像它們是本機應用程式一樣,儘管不需要安裝可能是網路的「好處」。 「離線優先」聽起來離線模式比線上模式更重要,但對於 99% 的網路應用程式來說,情況並非如此。 「本地優先」無疑是迄今為止最好的名字,但官方的[本地優先宣言](https://www.inkandswitch.com/local-first/)談論了點對點通信和[CRDT](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) (一個超級酷的想法,但除了協作文本編輯之外很少用於任何其他用途)。客戶端-伺服器Web 應用程式的世界正在嘗試解決像我上面描述的那樣的實際問題。諷刺的是,許多屬於當前「本地優先」浪潮一部分的工具都採用了這個名稱,但沒有採用所有原則。 最引起我注意和興趣的是「Replicache」。具體來說,我對它很感興趣,因為它不是一個自我複製的資料庫,也不是一個你必須圍繞它來建立整個應用程式的黑盒 SaaS 服務。相反,與我在這個領域遇到的任何現成解決方案相比,它提供了更多的控制、靈活性和關注點分離。 什麼是複製快取? -------- Replicache 是一個函式庫。在前端,它只需要很少的佈線,並且可以有效地充當普通的全局商店(想想 Zustand 或 Svelte 商店)。它有一個狀態區塊(在我們的範例中,每個清單都有自己的儲存)。它可以使用一組稱為“mutators”(認為是reducers)的用戶定義函數進行變異,例如“addItem”、“deleteItem”或任何您想要的東西,並公開一個訂閱函數(我[在這裡](https://doc.replicache.dev/api/classes/Replicache)簡化了完整的API)。 在這個熟悉的介面背後是一個強大且高效能的客戶端同步引擎,它可以處理: 1. 初步將相關資料完整下載到客戶端。 2. 從後端拉動和推送“突變”。突變是一個事件,指定應用哪個突變器以及哪些參數(加上一些元資料)。 ``` - When pushing, these changes are applied optimistically on the client, and rolled back if they fail on the server. Any other pending changes would be applied on top (rebase). ``` ``` - The sync mechanism also includes queuing changes if the connection is lost, retry mechanisms, applying changes in the right order, and de-duping. ``` 3. 將所有內容快取在記憶體中(效能)並將其保存到瀏覽器儲存(特別是 IndexedDB)以進行備份。 4. 由於可以從同一應用程式的所有選項卡存取相同的存儲,因此引擎會處理其中的所有含義,例如當架構發生更改但某些選項卡已刷新而某些選項卡尚未刷新且仍在使用時該怎麼辦舊模式。 5. 使用廣播通道立即保持所有選項卡同步(因為依賴共用儲存不夠快)。 6. 處理瀏覽器決定清除本地儲存的情況。 您可能已經注意到,這裡解決了我在本文頂部列出的大部分問題。基於突變也適合撤銷/重做等功能。 為了讓所有這些都能發揮作用,後端的工作就是實作 Replicache 定義的協定。具體來說: 1. 您需要實作[推送](https://doc.replicache.dev/reference/server-push)和[拉取](https://doc.replicache.dev/reference/server-pull)API。這些端點需要能夠像前端一樣啟動變異器(儘管它們不必執行相同的邏輯)。後端是權威的,衝突解決是由您的 mutator 實作中的程式碼完成的。 2. 您的資料庫需要支援快照隔離並在事務內執行操作。 3. Replicache 用戶端定期輪詢伺服器以檢查更改,但如果您希望用戶端之間接近即時同步,則需要實作「poke」機制,即通知客戶端某些內容已更改並且需要進行更改的方法。拉。這可以透過[伺服器發送的事件](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)或[websockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)來完成。這是一個有趣的 API 設計選擇——更改永遠不會推送到客戶端;客戶總是拉他們。我相信這樣做是為了簡單且易於對系統進行推理。有一點可以肯定:他們沒有強制使用Websocket,這是件好事,因為這會使協議與HTTP(伺服器透過正常HTTP 連接發送的事件流)不相容,這將需要額外的基礎設施並帶來額外的集成挑戰。 4. 根據[版本控制策略](https://doc.replicache.dev/strategies/overview),您可能需要實作其他操作(例如,createSpace)。 如果這對您來說並不平凡,那麼您是對的。我認為我還沒有完全理解它如何與資料庫一起操作的所有細節。我需要做一個後續專案,在其中完全重構資料庫結構和/或向範例加入有意義的功能(例如版本歷史記錄),以便更接近完全理解它。問題是,我知道在建立和維護實際生產應用程式時這種控制層級有多麼有價值。在我的書中,花一兩週的時間深入思考和設定應用程式的核心部分,如果它為建立和擴展奠定了堅實的基礎,那麼它就是一筆巨大的投資。 移植一個重要的範例 --------- 學習新事物的最好(也可以說是唯一)方法就是親自動手,親自體驗一些會影響真正應用程式的權衡和影響。當我查看[Replicache 網站上的範例](https://doc.replicache.dev/examples/todo)時,我注意到沒有 Sveltekit 的範例。自從 Svelte 3 發布以來,我一直是 Svelte 的忠實粉絲,但最近才開始使用 Sveltekit。我認為這將是一個透過實踐學習並同時建立有用的參考來實現的絕佳機會。 將現有程式碼庫移植到不同的技術具有教育意義,因為在翻譯程式碼時,您被迫理解並質疑它。在整個過程中,我經歷了多次靈光一現的時刻,因為一些起初看起來很奇怪的事情都發生了。 學習內容 ---- #### 斯維爾特基特 1. Sveltekit[本身並不支援 WebSockets](https://github.com/sveltejs/kit/issues/1491) ,即使它確實支援伺服器發送事件,但它的[方式也很笨拙](https://stackoverflow.com/questions/74879852/how-can-i-implement-server-sent-events-sse-in-sveltekit)。 Express 很好地支援兩者。因此,我使用[svelte-sse](https://github.com/razshare/sveltekit-sse)來處理伺服器發送的事件。我遇到的一個有點煩人的怪癖是,由於 svelte-sse 返回一個 Svelte 商店,而我的應用程式沒有訂閱該商店(應用程式不需要讀取該值,只需觸發如上所述的拉取),整件事情只是被編譯器優化掉了。起初我很困惑為什麼訊息沒有通過。我最終不得不針對這種行為實施解決方法。我不怪圖書館的作者;我只是怪罪圖書館的作者。他們假設一個有意義的值將發送給客戶端,但「poke」的情況並非如此。 2. 與原始 Express 後端相比,SvelteKit 基於檔案系統的路由、載入函數、佈局和其他功能可以實現更好組織的程式碼庫和更少的樣板程式碼。不用說,在前端,Svelte 遠遠領先於 Web 元件,導致前端程式碼庫更小、更易讀,儘管它具有更多功能(原始示例 TodoMVC 缺少諸如“將所有內容標記為完成”等功能) “刪除完成”)。 3. 總的來說,我喜歡 Sveltekit 並計劃在未來繼續使用它。如果您還沒有嘗試過,[官方教學](https://learn.svelte.dev/tutorial/introducing-sveltekit)是一個很棒的介紹。 ### 複製快取 總的來說,Replicache 給我留下了非常深刻的印象,並建議嘗試一下。在基本層面上(這是我目前要做的所有嘗試),它運作良好並兌現了所有承諾。話雖如此,以下是我的一些普遍擔憂(與待辦事項應用程式無關)以及與之相關的想法: - **性能相關:** ``` - **Initial load time** (first time, before any data was ever pulled to the client) might be long when there is a lot of data to download (think tens of MBs). Productivity apps in which the user spends a lot of time after the initial load are less sensitive to this, but it is still something to watch for. Potential mitigation: partial sync (e.g., Linear only sends open issues or ones that were closed over the last week instead of sending all issues). ``` ``` - **Chatty network (?)** - Initially, it seemed to me that there was a lot of chatter going back and forth between the client and the server with all the push, pull, and poke calls flying around. On deeper inspection, I realized my intuition was wrong. There is frequent communication, yes, but since the mutations are very compact and the poke calls are tiny (no payload), it amounts to much less than your normal REST/GraphQL app. Also, a browser full reload (refresh button or opening the page again in a new tab/window after it was closed) loads most of the data from the browser's storage and only needs to pull the diffs from the server, which leads me to the next point. ``` ``` - **Coming back after a long period of time offline**: I haven't tested this one, but it seems like a real concern. What happens if I was working offline for a few days making updates while my team was online and also making changes? When I come back online, I could have a huge amount of diffs to push and pull. Additionally, conflict resolution could become super difficult to get right. This is a problem for every collaborative app that has an offline mode and is not unique to Replicache. The Replicache docs [warn about this situation](https://doc.replicache.dev/concepts/offline) and propose implementing "the concept of history" as a potential mitigation. ``` ``` - What about **bundle size**? Replicache is [34kb gzipped](https://bundlephobia.com/package/[email protected]), and for what you get in return, it's easily worth it. ``` ``` - [This page](https://doc.replicache.dev/concepts/performance) on the Replicache website makes me think that, in the general case, performance should be very good. ``` - **功能相關:** ``` - Unlike native mobile or desktop apps, it is possible for users to **lose the local copy of their work** because the browser's storage doesn't provide the same guarantees as the device's file system. Browsers can just decide to delete all the app's data under certain conditions. If the user has been online and has work that didn't have a chance to get pushed to the server, that work would be lost in such a case. Again, this problem is not unique to Replicache and affects all web apps that support offline mode, and based on what I read, it is unlikely to affect most users. It's just something to keep in mind. ``` ``` - I was surprised to see that the **schema in the backend database** in the Todo example I ported doesn't have the "proper" relational definitions I would expect from a SQL database. There is no "items" table with fields for "id", "text", or "completed". The reason I would want that to exist is the same reason I want a relational database in the first place—to be able to easily slice and dice the data in my system (which I always missed down the line when I didn't have). I don't think it is a major concern since Replicache is supposed to be backend-agnostic as long as the protocol is implemented according to spec. I might try to refactor the database as a follow-up exercise to see what that means in terms of complexity and ergonomics. ``` ``` - I find **version history and undo/redo** super useful and desirable in apps with user-editable content. With regards to undo/redo there is an [official package](https://github.com/rocicorp/undo) but it seems to [lack support for the multiplayer usecase](https://github.com/rocicorp/replicache/issues/1008) (which is where the problems come from). As for version-history, the Replicache documentation mentions "the concept of history" but [suggests talking to them](https://doc.replicache.dev/concepts/offline) if the need arises. That makes me think it might not be straightforward to achieve. Another idea for a follow-up task. ``` ``` - **Collaborative text editing** - the existing conflict resolution approach won't work well for collaborative text editing, which requires [CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) or [OT](https://en.wikipedia.org/wiki/Operational_transformation). I wonder how easy it would be to integrate Replicache with something like [Yjs](https://yjs.dev/). There is an [official example repo](https://github.com/rocicorp/replicache-yjs), but I haven't looked into it yet. ``` - **縮放相關:** ``` - Since the server is stateful (holds open HTTP connections for server-sent events), I wonder how well it would scale. I've worked on production systems with >100k users that used WebSockets before, so I know it is not that big of a deal, but still something to think about. ``` - **其他:** ``` - - In theory, Replicache can be **added into existing apps** without rewriting the frontend (as long as the app already uses a similar store). The backend might be trickier. If your database doesn't support snapshot isolation, you are out of luck, and even if it does, the existing schema and your existing endpoints might need some serious rework. If you're going to use it, do it from day one (if you can). ``` ``` - Replicache is **not open source** (yet! see the point below) and is [free only as long as you're small or non-commercial](https://replicache.dev/#pricing). Given the amount of work (>2 years) that went into developing it and the quality of engineering on display, it seems fair. With that said, it makes adopting Replicache more of a commitment compared to picking up a free, open library. If you are a tier 2 and up paying customer, you get a [source license](https://doc.replicache.dev/howto/source-access) so that if Replicache shuts down for some reason, your app is safe. Another option is to roll out your own sync engine, like the big boys (Linear, Figma) have done, but getting to the quality and performance that Replicache offers would be anything but easy or quick. ``` ``` - **Crazy plot twist** (last minute edit): As I was about to publish this post I discovered that Replicache is going to be opened sourced in the near future and that its parent company is planning to launch a new sync-engine called "Zero". [Here is the official announcement](https://zerosync.dev/). It reads: "We will be open sourcing [Replicache](https://replicache.dev/) and [Reflect](https://reflect.net/). Once Zero is ready, we will encourage users to move." ``` ``` Ironically, Zero seems to be yet another solution that automagically syncs the backend database with the frontend database, which at least for me personally seems less attractive (because I want separation of concerns and control). With that said, these guys are experts in this domain and I am just a dude on the internet so we'll have to wait and see. In the meanwhile, I plan on playing with Replicache some more. ``` 同步引擎應該用於所有事情嗎? -------------- 不,同步引擎不應該用於所有事情。好訊息是,您可以讓應用程式的某些部分使用它,而其他部分仍然以傳統方式提交表單並等待伺服器的回應。 SvelteKit 和其他全端框架使這種整合變得容易。 使用同步引擎的明顯情況是一個壞主意: 1. 只有當客戶端更改很可能成功(回滾很少)並且客戶端擁有足夠的資訊來預測結果時,樂觀更新才有意義。例如,在線上測驗中,學生的答案必須傳送到伺服器進行評分,樂觀更新(因此同步引擎)是不可行的。這同樣適用於下訂單或交易股票等關鍵操作。一個好的經驗法則是,任何依賴伺服器且無法離線運作的操作都不應該依賴同步引擎。 2. 任何處理無法安裝在使用者電腦上的龐大資料集的應用程式。例如,建立本地優先版本的 Google 或處理千兆位元組資料以產生結果的分析工具是不切實際的。然而,在部分同步就足夠的情況下,同步引擎仍然是有益的。例如,Google地圖可以在客戶端裝置上下載和快取地圖以進行離線操作,而無需始終提供全球每個位置的高解析度地圖。 關於開發人員生產力和 DX 的一句話 ------------------ 我的印像是,擁有同步引擎可以讓 DX(開發人員體驗)變得更好。前端工程師只需與普通商店合作即可訂閱更新,並且 UI 始終保持最新狀態。無需考慮為同步引擎控制的應用程式部分取得任何內容、呼叫 API 或伺服器操作。至於後端,我還不能說太多。看起來它不會比傳統後端難,但我不能肯定。 ### 結束語 令人興奮的是,將網路應用程式的未來想像為全球範圍內的即時多人協作工具,無論網路條件如何,都可以可靠地工作,同時解決這些令人討厭的問題,我以過去的事情開始這篇文章。 我強烈建議網頁開發人員熟悉這些新概念,嘗試它們,甚至做出貢獻。 謝謝閱讀。如果您有任何問題或想法,請發表評論。和平。 。 **聚苯乙烯** 建立 Replicache 公司的創辦人 Aaron Boodman 的[訪談](https://youtu.be/cgTIsTWoNkM?si=Sssrbj09Z936QxEf)非常棒。觀看並稍後感謝我。 --- 原文出處:https://dev.to/isaachagoel/are-sync-engines-the-future-of-web-applications-1bbi

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

![被燒壞的工程師](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

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

系統設計面試中 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

程式設計師必須具備的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

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

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

使用 Langchain 為您的文件建立 QA 機器人 😻

--- 標題:使用 Langchain 為您的文件建立 QA 機器人 😻 描述:使用 Wing Framework、NextJS 和 Langchain 建立的 ChatGPT 用戶端應用程式 canonical\_url:https://www.winglang.io/blog/2024/05/29/qa-bot-for-your-docs-with-langchain 發表:真實 --- 長話短說 ---- 在本教學中,我們將為您的網站文件建立一個人工智慧驅動的問答機器人。 - 🌐 建立一個用戶友好的 Next.js 應用程式來接受問題和 URL - 🔧 設定一個 Wing 後端來處理所有請求 - 💡 透過使用 RAG 抓取和分析文件,將 @langchain 納入 AI 驅動的答案 - 🔄 前端輸入和人工智慧處理的回應之間的完整連接。 ![問題](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykw5f2sos4fdhj8akowt.gif) 什麼是翼? ----- [Wing](https://wing.cloud/redirect?utm_source=qa-bot-reddit&redirect=https%3A%2F%2Fwww.winglang.io%2Fblog%2F2024%2F05%2F29%2Fqa-bot-for-your-docs-with-langchain)是一個雲端開源框架。 它允許您將應用程式的基礎架構和程式碼組合為一個單元,並將它們安全地部署到您首選的雲端提供者。 Wing 讓您可以完全控制應用程式基礎架構的配置方式。除了其易於學習的[程式語言](https://www.winglang.io/docs/language-reference)之外,Wing 還支援 Typescript。 在本教學中,我們將使用 TypeScript。所以,別擔心,您的 JavaScript 和 React 知識足以理解本教學。 ![翼登陸頁面](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u366v255drbwqmcoagrz.png) {% cta https://wingla.ng/github %} 看 Wing ⭐️ {% endcta %} --- 使用 Next.js 建立前端 --------------- 在這裡,您將建立一個簡單的表單,它接受文件 URL 和使用者的問題,然後根據網站的資料回傳回應。 首先,建立一個包含兩個子資料夾的資料夾 - `frontend`和`backend` 。 `frontend`資料夾包含 Next.js 應用程式, `backend`資料夾用於 Wing。 ``` mkdir qa-bot && cd qa-bot mkdir frontend backend ``` 在**`frontend`**資料夾中,透過執行以下程式碼片段來建立 Next.js 專案: ``` cd frontend npx create-next-app ./ ``` ![下一個應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyq8dnmmmplvzl7g41ir.png) 將下面的程式碼片段複製到`app/page.tsx`檔案中,以建立接受使用者問題和文件 URL 的表單: ``` "use client"; import { useState } from "react"; export default function Home() { const [documentationURL, setDocumentationURL] = useState<string>(""); const [question, setQuestion] = useState<string>(""); const [disable, setDisable] = useState<boolean>(false); const [response, setResponse] = useState<string | null>(null); const handleUserQuery = async (e: React.FormEvent) => { e.preventDefault(); setDisable(true); console.log({ question, documentationURL }); }; return ( <main className='w-full md:px-8 px-3 py-8'> <h2 className='font-bold text-2xl mb-8 text-center text-blue-600'> Documentation Bot with Wing & LangChain </h2> <form onSubmit={handleUserQuery} className='mb-8'> <label className='block mb-2 text-sm text-gray-500'>Webpage URL</label> <input type='url' className='w-full mb-4 p-4 rounded-md border text-sm border-gray-300' placeholder='https://www.winglang.io/docs/concepts/why-wing' required value={documentationURL} onChange={(e) => setDocumentationURL(e.target.value)} /> <label className='block mb-2 text-sm text-gray-500'> Ask any questions related to the page URL above </label> <textarea rows={5} className='w-full mb-4 p-4 text-sm rounded-md border border-gray-300' placeholder='What is Winglang? OR Why should I use Winglang? OR How does Winglang work?' required value={question} onChange={(e) => setQuestion(e.target.value)} /> <button type='submit' disabled={disable} className='bg-blue-500 text-white px-8 py-3 rounded' > {disable ? "Loading..." : "Ask Question"} </button> </form> {response && ( <div className='bg-gray-100 w-full p-8 rounded-sm shadow-md'> <p className='text-gray-600'>{response}</p> </div> )} </main> ); } ``` 上面的程式碼片段顯示了一個表單,該表單接受使用者的問題和文件 URL 並將它們暫時記錄到控制台。 ![QA 機器人表單](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7b4w3tq0srua93gnk73n.png) 完美的! 🎉您已經完成了應用程式的使用者介面。接下來,讓我們設定 Wing 後端。 --- 如何在電腦上設定 Wing ------------- Wing 提供了一個 CLI,使您能夠在專案中執行各種 Wing 操作。 它還提供[VSCode](https://marketplace.visualstudio.com/items?itemName=Monada.vscode-wing)和[IntelliJ](https://plugins.jetbrains.com/plugin/22353-wing)擴展,透過語法突出顯示、編譯器診斷、程式碼完成和片段等功能增強開發人員體驗。 在繼續之前,請停止 Next.js 開發伺服器並透過在終端機中執行下面的程式碼片段來安裝 Wing CLI。 ``` npm install -g winglang@latest ``` 執行以下程式碼片段以確保 Winglang CLI 已安裝並按預期工作: ``` wing -V ``` 接下來,導航到`backend`資料夾並建立一個空的 Wing Typescript 專案。確保選擇`empty`模板並選擇 Typescript 作為語言。 ``` wing new ``` ![永新](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezy04zqvz9lura0d25dj.png) 將下面的程式碼片段複製到`backend/main.ts`檔案中。 ``` import { cloud, inflight, lift, main } from "@wingcloud/framework"; main((root, test) => { const fn = new cloud.Function( root, "Function", inflight(async () => { return "hello, world"; }) ); }); ``` **`main()`**函數充當 Wing 的入口點。 它建立一個雲端函數並在編譯時執行。另一方面, **`inflight`**函數在執行時執行並返回`Hello, world!`文字. 透過執行下面的程式碼片段啟動 Wing 開發伺服器。它會自動在瀏覽器中開啟 Wing 控制台,網址為`http://localhost:3000` 。 ``` wing it ``` ![Wing TS 最小控制台](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1ejobkm0dq5akhut732.png) 您已在電腦上成功安裝 Wing。 --- 如何將 Wing 連接到 Next.js 應用程式 ------------------------- 在前面的部分中,您已在`frontend`資料夾中建立了 Next.js 前端應用程式,並在`backend`資料夾中建立了 Wing 後端。 在本部分中,您將了解如何在 Next.js 應用程式和 Wing 後端之間通訊和發送資料。 首先,透過執行以下程式碼在後端資料夾中安裝[Wing React](https://github.com/winglang/winglibs/tree/main/react)函式庫: ``` npm install @winglibs/react ``` 接下來,更新`main.ts`文件,如下所示: ``` import { main, cloud, inflight, lift } from "@wingcloud/framework"; import React from "@winglibs/react"; main((root, test) => { const api = new cloud.Api(root, "api", { cors: true }) ; //👇🏻 create an API route api.get( "/test", inflight(async () => { return { status: 200, body: "Hello world", }; }) ); //👉🏻 placeholder for the POST request endpoint //👇🏻 connects to the Next.js project const react = new React.App(root, "react", { projectPath: "../frontend" }); //👇🏻 an environment variable react.addEnvironment("api_url", api.url); }); ``` 上面的程式碼片段建立了一個 API 端點 ( `/test` ),它接受 GET 請求並傳回`Hello world`文字。 `main`函數也連接到 Next.js 專案並將`api_url`新增為環境變數。 環境變數中包含的 API URL 使我們能夠將請求傳送到 Wing API 路由。我們如何在 Next.js 應用程式中檢索 API URL 並發出這些請求? 更新 Next.js `app/layout.tsx`檔案中的`RootLayout`元件,如下所示: ``` export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang='en'> <head> {/** ---👇🏻 Adds this script tag 👇🏻 ---*/} <script src='./wing.js' defer /> </head> <body className={inter.className}>{children}</body> </html> ); } ``` 透過執行`npm run build`重新建置 Next.js 專案。 最後,啟動Wing開發伺服器。它會自動啟動 Next.js 伺服器,可以在瀏覽器中透過**`http://localhost:3001`**存取該伺服器。 ![控制台到 URL](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7rkxw9bds97a0qzg5vh.gif) 您已成功將 Next.js 連接到 Wing。您也可以使用`window.wingEnv.<attribute_name>`存取環境變數中的資料。 ![視窗.wingEnv](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0up5430jmxufmyeb9e4h.gif) 使用LangChain和Wing處理用戶請求 ---------------------- 在本節中,您將學習如何向 Wing 發送請求,使用[LangChain 和 OpenA](https://js.langchain.com/docs/get_started/quickstart#llm-chain) I 處理這些請求,並在 Next.js 前端顯示結果。 首先,我們更新 Next.js **`app/page.tsx`**檔案以檢索 API URL 並將使用者資料傳送到 Wing API 端點。 為此,請透過在**`page.tsx`**檔案頂部新增以下程式碼片段來擴充 JavaScript **`window`**物件。 ``` "use client"; import { useState } from "react"; interface WingEnv { api_url: string; } declare global { interface Window { wingEnv: WingEnv; } } ``` 接下來,更新`handleUserQuery`函數以將包含使用者問題和網站URL 的POST 請求傳送到Wing API 端點。 ``` //👇🏻 sends data to the api url const [response, setResponse] = useState<string | null>(null); const handleUserQuery = async (e: React.FormEvent) => { e.preventDefault(); setDisable(true); try { const request = await fetch(`${window.wingEnv.api_url}/api`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ question, pageURL: documentationURL }), }); const response = await request.text(); setResponse(response); setDisable(false); } catch (err) { console.error(err); setDisable(false); } }; ``` 在建立接受 POST 請求的 Wing 端點之前,請在`backend`資料夾中安裝下列套件: ``` npm install @langchain/community @langchain/openai langchain cheerio ``` [Cheerio](https://js.langchain.com/v0.2/docs/integrations/document_loaders/web_loaders/web_cheerio/)使我們能夠抓取軟體文件網頁,而[LangChain 軟體包](https://js.langchain.com/v0.1/docs/get_started/quickstart/)使我們能夠存取其各種功能。 LangChain OpenAI整合包使用OpenAI語言模型;因此,您需要一個有效的 API 金鑰。您可以從[OpenAI 開發者平台](https://platform.openai.com/api-keys)取得。 ![朗查恩](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omg4o524oklrssso5rqc.png) 接下來,讓我們建立處理傳入請求的`/api`端點。 端點將: - 接受來自 Next.js 應用程式的問題和文件 URL, - 使用[LangChain 文件載入器](https://js.langchain.com/v0.1/docs/modules/data_connection/document_loaders/)載入文件頁面, - 將檢索到的文件分成區塊, - 轉換分塊文件並將它們保存在[LangChain 向量儲存](https://js.langchain.com/v0.1/docs/modules/data_connection/vectorstores/)中, - 並建立一個[檢索器函數](https://js.langchain.com/v0.1/docs/modules/data_connection/),從向量儲存中檢索文件。 首先,將以下內容匯入`main.ts`檔案: ``` import { main, cloud, inflight, lift } from "@wingcloud/framework"; import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai"; import { ChatPromptTemplate } from "@langchain/core/prompts"; import { createStuffDocumentsChain } from "langchain/chains/combine_documents"; import { CheerioWebBaseLoader } from "@langchain/community/document_loaders/web/cheerio"; import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; import { MemoryVectorStore } from "langchain/vectorstores/memory"; import { createRetrievalChain } from "langchain/chains/retrieval"; import React from "@winglibs/react"; ``` 在`main()`函數中加入以下程式碼片段以建立`/api`端點: ``` api.post( "/api", inflight(async (ctx, request) => { //👇🏻 accept user inputs from Next.js const { question, pageURL } = JSON.parse(request.body!); //👇🏻 initialize OpenAI Chat for LLM interactions const chatModel = new ChatOpenAI({ apiKey: "<YOUR_OPENAI_API_KEY>", model: "gpt-3.5-turbo-1106", }); //👇🏻 initialize OpenAI Embeddings for Vector Store data transformation const embeddings = new OpenAIEmbeddings({ apiKey: "<YOUR_OPENAI_API_KEY>", }); //👇🏻 creates a text splitter function that splits the OpenAI result chunk size const splitter = new RecursiveCharacterTextSplitter({ chunkSize: 200, //👉🏻 characters per chunk chunkOverlap: 20, }); //👇🏻 creates a document loader, loads, and scraps the page const loader = new CheerioWebBaseLoader(pageURL); const docs = await loader.load(); //👇🏻 splits the document into chunks const splitDocs = await splitter.splitDocuments(docs); //👇🏻 creates a Vector store containing the split documents const vectorStore = await MemoryVectorStore.fromDocuments( splitDocs, embeddings //👉🏻 transforms the data to the Vector Store format ); //👇🏻 creates a document retriever that retrieves results that answers the user's questions const retriever = vectorStore.asRetriever({ k: 1, //👉🏻 number of documents to retrieve (default is 2) }); //👇🏻 creates a prompt template for the request const prompt = ChatPromptTemplate.fromTemplate(` Answer this question. Context: {context} Question: {input} `); //👇🏻 creates a chain containing the OpenAI chatModel and prompt const chain = await createStuffDocumentsChain({ llm: chatModel, prompt: prompt, }); //👇🏻 creates a retrieval chain that combines the documents and the retriever function const retrievalChain = await createRetrievalChain({ combineDocsChain: chain, retriever, }); //👇🏻 invokes the retrieval Chain and returns the user's answer const response = await retrievalChain.invoke({ input: `${question}`, }); if (response) { return { status: 200, body: response.answer, }; } return undefined; }) ); ``` API 端點接受使用者的問題和來自 Next.js 應用程式的頁面 URL,初始化[`ChatOpenAI`](https://js.langchain.com/v0.2/docs/integrations/chat/openai/)和[`OpenAIEmbeddings`](https://js.langchain.com/v0.2/docs/integrations/text_embedding/openai/) ,載入文件頁面,並以文件的形式檢索使用者查詢的答案。 然後,將文件分割成區塊,將區塊保存在`MemoryVectorStore`中,並使我們能夠使用[LangChain 檢索器](https://js.langchain.com/v0.1/docs/modules/data_connection/)來取得問題的答案。 從上面的程式碼片段來看,OpenAI API金鑰直接輸入到程式碼中;這可能會導致安全漏洞,使 API 金鑰可供攻擊者存取。為了防止這種資料洩露,Wing 允許您將私鑰和憑證保存在名為`secrets`的變數中。 當您建立機密時,Wing 會將此資料保存在`.env`檔案中,確保其安全且可存取。 更新`main()`函數以從 Wing Secret 取得 OpenAI API 金鑰。 ``` main((root, test) => { const api = new cloud.Api(root, "api", { cors: true }); //👇🏻 creates the secret variable const secret = new cloud.Secret(root, "OpenAPISecret", { name: "open-ai-key", }); api.post( "/api", lift({ secret }) .grant({ secret: ["value"] }) .inflight(async (ctx, request) => { const apiKey = await ctx.secret.value(); const chatModel = new ChatOpenAI({ apiKey, model: "gpt-3.5-turbo-1106", }); const embeddings = new OpenAIEmbeddings({ apiKey, }); //👉🏻 other code snippets & configurations ); const react = new React.App(root, "react", { projectPath: "../frontend" }); react.addEnvironment("api_url", api.url); }); ``` - 從上面的程式碼片段來看, ``` - The `secret` variable declares a name for the secret (OpenAI API key). ``` ``` - The [`lift().grant()`](https://www.winglang.io/docs/typescript/inflights#permissions) grants the API endpoint access to the secret value stored in the Wing Secret. ``` ``` - The [`inflight()`](https://www.winglang.io/docs/typescript/inflights) function accepts the context and request object as parameters, makes a request to LangChain, and returns the result. ``` ``` - Then, you can access the `apiKey` using the `ctx.secret.value()` function. ``` 最後,透過在終端機中執行此命令將 OpenAI API 金鑰儲存為機密。 ![翅膀的秘密](https://www.winglang.io/assets/images/qa-bot-wing-secrets-883db5e81515894ae280d77b7f72bb25.gif) 恭喜!您已成功完成本教學的專案。 以下是該應用程式的簡短演示: ![QA 機器人演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ropklqge2xzpibl29vye.gif) --- 讓我們更深入地研究 Wing 文件,看看我們的 AI 機器人可以提取哪些資料。 ![QA 機器人演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnmf6n6mszc6go0uiw1v.gif) --- 總結一下 ---- 到目前為止,我們已經討論了以下內容: - 什麼是翼? - 如何使用Wing並使用Langchain查詢資料, - 如何將 Wing 連接到 Next.js 應用程式, - 如何在 Next.js 前端和 Wing 後端之間發送資料。 > [Wing](https://github.com/winglang/wing)旨在恢復您的創意流並縮小想像力與創造之間的差距。 Wing 的另一個巨大優勢是它是開源的。因此,如果您希望建立利用雲端服務的分散式系統或為雲端開發的未來做出貢獻, [Wing](https://github.com/winglang/wing)是您的最佳選擇。 請隨意為[GitHub 儲存庫做出貢獻,](https://github.com/winglang/wing)並與團隊和大型開發人員社群[分享您的想法](https://t.winglang.io/discord)。 本教學的源程式碼可[在此處](https://github.com/NathanTarbert/wing-langchain-nextjs)取得。 感謝您的閱讀! 🎉 --- 原文出處:https://dev.to/winglang/build-a-qa-bot-for-your-documentation-with-langchain-27i4

恭喜前端挑戰:六月版得獎者!

等待已經結束!我們很高興地宣布[前端挑戰賽:六月版](https://dev.to/devteam/join-us-for-the-next-frontend-challenge-june-edition-3ngl)的獲獎者。 從[海灘上昏昏欲睡的皮卡丘](https://dev.to/dhrutisubham03/sleepy-pikachu-4iha)到慶祝[世界自行車日](https://dev.to/israebenboujema/world-bicycle-day-css-art-frontend-challenge-june-edition-31oc),我們的 DEV 評審團隊在審查每個人提交的創意作品並了解世界各地的海灘時獲得了很多樂趣! 無論您剛完成第一個挑戰還是正在連續完成挑戰,我們都希望您為自己提交的內容和學到的知識感到自豪! 一如既往,只能有幾個贏家。 恭喜… --- ### CSS藝術 恭喜 @tanveermahendra 的**CSS 藝術**讓我們驚嘆不已! 這個提交是美麗而感人的。它擴展了 CSS 的功能,並且沒有犧牲一絲藝術完整性。 有很多很棒的作品,我們認為這個作品確實解決了這個挑戰。 {% 嵌入 https://dev.to/tanveermahendra/css-art-june-was-made-for-happiness-5acm %} ### 讓我的標記更加迷人 恭喜 @rith1x 在**Glam Up My Markup**提示中建立了一個漂亮的響應式網站! 此提交散發出個性和專業精神,並創造了令人愉快且易於存取的用戶體驗。這讓我們想去參觀這些海灘之一! {% 內嵌 https://dev.to/rith1x/glam-up-my-markup-beaches-4fn8 %} --- 我們的兩位獲獎者將獲得專屬 DEV 徽章和[DEV 商店](https://shop.forem.com)贈送的禮物。所有參與者都將獲得完成徽章以迎接挑戰! 下一步是什麼? ------- 明天(6 月 12 日),我們將發起一項新的合作挑戰,即[Twilio 挑戰](https://dev.to/challenges/twilio),以及我們的首個[電腦科學挑戰](https://dev.to/challenges/twilio)。 {% 嵌入 https://dev.to/t/twiliochallenge %} {% 嵌入 https://dev.to/t/cschallenge %} 6 月 26 日,我們將啟動[Wix Studio 挑戰賽](https://dev.to/challenges/wix): {% 嵌入 https://dev.to/t/wixstudiochallenge %} 請務必關注每個挑戰標籤,這樣您就不會錯過公告! 感謝所有參加前端挑戰賽:六月版的人!我們希望您玩得開心,感受到挑戰,並可能為您的職業檔案加入一兩件事。下次見! --- 原文出處:https://dev.to/devteam/congrats-to-the-frontend-challenge-june-edition-winners-26kd

  近期留言