🔍 搜尋結果:題

🔍 搜尋結果:題

網頁反應慢,怎麼辦?

看更多文章: 1. [使用 gRPC 和微服務建立可擴展的通知系統](https://dev.to/suprsend/building-a-scalable-notification-service-with-grpc-and-microservices-l6d) 2. [在 React 網站中新增通知來源](https://dev.to/suprsend/adding-a-notification-feed-in-react-websites-4oa0) 4. [2023 年現代應用通知基礎設施完整指南](https://dev.to/suprsend/a-complete-guide-on-notification-infrastruct-for-modern-applications-in-2023-13b9) --- 應用程式通常可以分為兩種類型的效能瓶頸: 1. **I/O 限制:** 這些應用程式將大部分時間花在處理輸入和輸出上。 2. **CPU 限制:** 這些應用程式將大部分時間花在運算任務上。 現在,這些分類如何轉化為前端應用程式的上下文,特別是 React 應用程式? **React 中的 I/O 效能挑戰** 當涉及到 React 應用程式時,經常會出現 I/O 效能方面的問題,主要與非同步 HTTP 呼叫相關。無效地管理這些網路請求可能會導致應用程式速度減慢。雖然這篇文章主要關注 CPU 效能,但有必要簡要介紹一下可以找到 I/O 限制問題解決方案的關鍵領域: - 盡可能實施延遲載入。 - 在初始載入資產和後端請求時請務必小心。 - 減少載入高度靜態元素的頻率(例如,選擇選項、配置)。 - 去抖特定請求的次數。 - 使用 Promise.all 等技術盡可能並行化請求。 - 透過優化資料庫存取等措施來提高關鍵後端端點的效率。 **React 中的 CPU 效能挑戰** 這篇文章的主旨是解決 React 中的 CPU 效能挑戰。在深入研究細節之前,讓我們先對效能建立一個具體的定義: - 瀏覽器應用程式主要作為單執行緒程式執行。 - 腳本任務,例如 JavaScript 執行、DOM 渲染和事件處理,都發生在同一個執行緒。 - 緩慢的 JavaScript 模組可能會阻塞主執行緒。 - 如果主執行緒被阻塞,使用者介面將變得無回應,導致每秒幀數 (fps) 下降。 - 響應式 UI 的目標是至少 30 fps,理想情況下達到 60 fps,這意味著每幀的計算時間應在 30 毫秒或更短的時間內。 在 React 的背景下,這個問題變得至關重要。當觸發 React 元件更新時,整個子樹必須在 30 毫秒內渲染完畢。對於複雜而冗長的元件結構(例如表、樹和列表),這變得尤其具有挑戰性,可能需要大規模重新渲染。 **反應渲染和提交階段** 從高層次來看,React 分為兩個不同的階段: **渲染階段:** - 當元件更新時啟動,由 props 或 hooks 的變更觸發。 - React 遍歷元件子樹,渲染每個子樹並計算虛擬 DOM (VDOM) 子樹。 - 只有受更新影響的「髒」子樹需要重新計算;更新元件的父元件可能不需要重新渲染。 - 此階段的效率與每個子元件的大小和計算成本成正比。 - React.memo 可用於提供更有效率渲染流程的提示。 **提交階段:** - 渲染階段產生整個 UI 的新虛擬 DOM。 - 在提交階段,React 將新樹與前一棵樹進行比較(VDOM 比較)。 - React 計算反映新 VDOM 樹所需的最小 DOM 突變。 - 套用 DOM 突變,更新 UI。 - 預設情況下,此階段本質上是高效的。 - 整個過程必須在 30 或 16 毫秒內完成(分別針對 30 fps 和 60 fps),UI 才會被視為回應。工作負載與應用程式的大小成正比。 後續探索將聚焦在提升Render階段的效率。在深入研究優化技術之前,了解如何測量和辨識應用程式中的緩慢元件至關重要。 **測量** 我經常依賴的工具包括: 1. **Chrome 開發工具的效能標籤** 2. **React Dev Tool 的效能標籤** **Chrome 開發工具的效能標籤** 該工具作為適用於任何瀏覽器應用程式的綜合資源而脫穎而出。它提供對每秒幀數的洞察、捕獲堆疊追蹤、辨識程式碼的慢速或熱點部分等等。主要使用者介面由火焰圖表示。 若要深入了解套用於 React 的 Chrome 效能選項卡,請參閱此[文件](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance)。 **React 開發工具的效能標籤** 若要利用此工具,您需要在瀏覽器中安裝 React Dev Tool 擴充功能。它專門針對 React 客製化了 Chrome 開發工具效能標籤中的資訊。透過火焰圖,您可以觀察不同的提交階段以及在對應渲染階段執行的 JavaScript 程式碼。 該工具有助於輕鬆確定: - 當元件進行重新渲染時。 - 哪些道具改變了。 - 哪些鉤子發生了變化,包括狀態、上下文等等。有關更多詳細訊息,請參閱[介紹性帖子](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html)。 **測量方法** 這是我在評估前端應用程式時更喜歡的方法: 1. **確定問題:** - 找出導致 UI 回應問題的頁面互動。 2. **建立一個假設:** - (可選)產生有關問題的潛在位置的想法。 3. **測量:** - 透過測量每秒幀數 (fps) 等基本指標來驗證問題。 4. **測量(第二部分):** - 辨識有問題的程式碼部分; (可選)驗證您的假設。 5. **建立解決方案:** - 根據收集到的見解實施解決方案。 6. **測量解決方案:** - 透過檢查關鍵指標來驗證實施的解決方案是否解決或緩解了問題。 在沒有適當衡量的情況下進行最佳化會使努力實際上變得無效。雖然有些問題可能很明顯,但大多數問題都需要徹底的測量,從而構成性能增強過程的基石。 此外,測量可讓您向上傳達成果,向使用者、利害關係人和您的領導層通報應用程式特定領域內實現的效能改進(以百分比增益表示)。 **React 應用程式中 CPU 限制問題的通用解決方案** 現在有了測量結果並了解了問題領域,讓我們深入研究潛在的解決方案。優化 React 效能圍繞著改進渲染的元件和渲染的元件。 許多效能問題也源自於反模式。消除這些反模式(例如避免渲染方法中的內聯函數定義)有助於提高渲染時間。事實上,解決不良模式可以降低複雜性並同時提高效能。 **🤔 改進元件渲染** 辨識 React 應用程式中的緩慢元件通常指的是難以渲染或單一頁面上實例數量過多的特定元件。多種原因可能導致他們行動遲緩: - 元件內的阻塞計算。 - 渲染大型元件樹。 - 使用昂貴或低效率的函式庫。 大多數這些問題都歸結為提高元件渲染的速度。有時,關鍵元件不能依賴過於複雜的函式庫,需要回歸基本原則並實施更簡單的替代方案。 例如,我在複雜表格中每行的多個單元格中過度使用 Formik 時遇到了此類挑戰。雖然提高單一元件的效率還有很長的路要走,但注意力最終必須轉移到正在渲染的元件上。 **🧙 改進哪些元件渲染** 這方面提供了兩大類改進: 1. **虛擬化:** - 僅渲染視窗中可見的元件。例如,僅呈現使用者可以看到的表格行或清單專案。事實證明,這種方法對於複雜的 UI 是有益的,雖然可以在不解決「內容」步驟的情況下應用它,但建議這樣做。現代函式庫通常為虛擬化表和清單提供強大的支持,例如“react-virtualized”。虛擬化減少了 React 需要在給定幀中渲染的元件數量。 2. **道具優化:** - React 的目標是使元件類似於純函數,但可能會嘗試渲染不必要的次數。 **反應.備忘錄:** - React 中的大多陣列件都可以被記憶,確保使用相同的 props,元件返回相同的樹(儘管鉤子、狀態和上下文仍然受到尊重)。如果它們的 props 保持不變,則利用 `React.memo` 通知 React 跳過重新渲染這些已記憶的元件。 ``` import React from 'react'; const MyComponent = React.memo((props) => { // Component logic here }); export default MyComponent; ``` **假道具更改:useCallback:** - 解決虛假道具更改問題涉及道具內容保持不變但引用發生變化的情況。一個典型的例子是事件處理程序。 ``` import React, { useCallback } from 'react'; const MyComponent = () => { const onChange = useCallback((e) => console.log(e), []); return <input onChange={onChange} />; }; export default MyComponent; ``` **假道具更改:useMemo:** - 在將複雜資料結構作為 props 傳遞之前,在沒有適當記憶的情況下建立複雜的資料結構時,也會出現類似的挑戰。利用「useMemo」可確保僅在依賴項發生變更時才重新計算行,從而提高效率。 ``` import React, { useMemo } from 'react'; const MyComponent = ({ data, deps }) => { const rows = useMemo(() => data.filter(bySearchCriteria).sort(bySortOrder), [deps]); return <Table data={rows} />; }; export default MyComponent; ``` 雖然您可以靈活地自訂「React.memo」如何比較目前與先前的道具,但保持快速運算至關重要,因為它是渲染階段不可或缺的一部分。避免在每次渲染期間過於複雜的深度比較。 ## 現在看起來怎麼樣? ### 道具已更改 它在 React 開發工具中的樣子: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k0wsxe16icfytqfamg3p.png) 他們真的嗎?它們是假的道具更改嗎?使用`useCallback`和`useMemo`。 ### 父渲染 它在 React 開發工具中的樣子: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ilqb2astlchzto603anc.png) 使用“React.memo”來記住您的純元件。 ### 掛鉤已更改(狀態、上下文) 它在 React 開發工具中的樣子: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8beosx4hh1n90ejts3h.png) 這裡沒有什麼太明顯的事情要做。嘗試驗證更改的鉤子是否有意義。也許一個糟糕的上下文提供者正在以與假道具更改可能出現的方式相同的方式偽造更改。 --- > 與此類似,我個人在 Slack 上經營著一個由開發人員主導的社群。我們在其中討論這些類型的實現、整合、一些真相炸彈、奇怪的聊天、虛擬會議以及一切有助於開發人員保持理智的事情;)畢竟,太多的知識也可能是危險的。 > 我邀請您加入我們的免費社區,參與討論,並分享您的驚人經驗和專業知識。您可以填寫此表格,Slack 邀請將在幾天後收到您的電子郵件。我們擁有來自一些偉大公司(Atlassian、Scaler、Cisco、IBM 等)的出色人員,您一定不想錯過與他們的互動。 [邀請表](https://forms.gle/VzA3ST8tCFrxt39U9) --- 您可能想要查看整合通知基礎架構的無縫方式。 https://github.com/suprsend/suprsend-go --- 原文出處:https://dev.to/nikl/react-is-slow-what-to-do-now-369g

Docker 絕對初學者

Docker 是一個工具,允許開發人員將他們的應用程式及其所有依賴項打包到一個容器中。然後,這個容器就可以輕鬆地在任何安裝了 Docker 的機器上傳輸和執行,而不必擔心環境的差異。這就像是打包和執行軟體的標準化方式。 **容器是什麼?** ![Docker 容器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imsgbstga86vnxjwgebr.png) 容器就像一個小包,其中包含程式執行所需的一切,可以輕鬆地在不同電腦上移動和執行,而不會造成任何麻煩。 最酷的部分是這個迷你電腦(容器)就像一個披著斗篷的超級英雄。它可以在任何電腦上執行,無論它們有多麼不同,因為它自帶特殊的環境。這是一種保持軟體井然有序的方式,並確保它無論在哪裡都能以相同的方式運作。 ![容器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1z5zcued8ya2onerpzwt.png) **為什麼我們需要 Docker?** 1. **一致性:** Docker 確保軟體在您的電腦、您朋友的電腦或任何電腦上以相同的方式運作。它使事情保持一致。 2. **可移植性:** 您可以將您的軟體及其朋友打包到 Docker 容器中,並且它可以移動到任何地方。這就像將您的遊戲及其所有規則放在手提箱中並在朋友家中玩。 3. **隔離:** Docker 容器就像小氣泡。氣泡內發生的事只會留在氣泡內。這意味著容器中的一個程式不會幹擾容器外的另一個程式。 4. **效率:** Docker有助於節省電腦資源。您可以讓許多容器在同一台電腦上執行,而不會相互妨礙,而不是讓一整台電腦只用於一個程式。 5. **速度:** Docker 讓啟動、停止和共享軟體變得快速、輕鬆。這就像打開和關閉遊戲機一樣 - 快速而簡單。 **什麼是 Docker 映像?** ![Docker 映像](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/817t1rsad728snnighkj.png) Docker 映像像是程式及其運作所需的所有內容的快照。它是一個打包版本,包括程式碼、工具和設置,就像包含所有成分的餅乾食譜的快照一樣。 **圖像是配方,容器是當您按照該配方實際製作和執行程序時所得到的。** **一些基本的 Docker 命令。** ![基本 Docker 指令](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xq1pwt8896lvster3ppl.png) 1. **`docker執行nginx`** - 此命令告訴 Docker 使用「nginx」映像執行容器。這就像告訴 Docker 啟動一個預製程式的新實例(nginx,它是一個 Web 伺服器)。 2. **`docker ps`** - 顯示正在執行的容器的清單。這就像檢查當前正在執行哪些程式。 3. **`docker ps -a`** - 顯示所有容器的列表,包括已停止的容器。這就像檢查您執行過的所有程式的歷史記錄。 4. **`docker stopsilly_sammet'** - 停止名為「silly_sammet」的正在運作的容器。這就像關閉當前正在執行的程式。 5. **`docker rmsilly_sammet'** - 刪除名為「silly_sammet」的已停止容器。這就像丟掉你不再需要的程式的指令一樣。 6. **`docker 映像`** - 列出您擁有的所有 Docker 映像。這就像查看您可以執行的所有不同程式的選單一樣。 7. **`docker rmi nginx`** - 刪除“nginx”圖像。這就像刪除您不想再使用的程式的配方。 8. **`docker拉nginx`** - 從網路下載「nginx」映像。這就像從食譜中獲取新食譜一樣。 9. **`docker 執行 ubuntu sleep 5`** - 使用「ubuntu」映像檔執行容器並使其休眠 5 秒。這就像啟動一個程序,只是等待一小會兒,然後就停止了。 10. **`docker exectracted_mcclintock cat /etc/hosts`** - 在名為「distracted_mcclintock」的正在執行的容器內執行命令。這就像在食譜書中偷看特定頁面一樣。 11. **`docker run -d kodekloud/simple-webapp`** - 從「kodekloud/simple-webapp」鏡像以分離模式執行容器。這就像啟動一個程式並讓它在背景執行。 12. **`docker Attach a043d`** - 將您的終端附加到 ID 為「a043d」的正在執行的容器。這就像跳入正在執行的程式來查看發生了什麼。 **一些 Docker 概念:** 1. **使用標籤執行:** - 標籤就像程式的版本。它指定您要執行哪個版本。 - 範例程式碼:`docker run nginx:latest` - 這將執行最新版本的 Nginx 程式。 2. **使用標準輸入執行:** - STDIN 就像在鍵盤上打字一樣。有些程式需要您的輸入。 - 範例程式碼:`docker run -i -t ubuntu` - 這會在 Ubuntu 容器內執行互動終端,讓您可以鍵入命令。 3. **使用連接埠映射執行:** - 連接埠就像門。程式使用它們與外界進行通訊。 - 範例程式碼:`docker run -p 8080:80 nginx` - 這將執行 Nginx,並打開電腦連接埠 8080 上的門,將其連接到容器的連接埠 80。 4. **使用磁碟區映射執行:** - 磁碟區就像共用資料夾。它們讓您可以將東西存放在容器之外。 - 範例程式碼:`docker run -v /your/local/folder:/container/folder nginx` - 這將執行 Nginx 並將電腦上的資料夾連接到容器內的資料夾。 5. **檢查容器:** - 檢查就像仔細檢查正在執行的程式。 - 範例程式碼:`docker檢查container_name` - 這為您提供有關正在執行或已停止的容器的詳細資訊。 6. **容器日誌:** - 日誌就像日記。他們記錄程式正在做什麼。 - 範例程式碼:“docker 日誌容器名稱” - 這會向您顯示特定容器的日誌或活動。 ##環境變數 環境變數就像程式用來尋找重要資訊的便利筆記,有點像是程式可以理解和更好工作的秘密訊息! 1. **Python腳本(app.py)中的環境變數:** - 假設您有一個用 Python 寫的程式 (app.py)。您可能想要在不更改程式碼的情況下自訂它。您可以使用環境變數。 - 範例程式碼(app.py): ``` import os app_color = os.getenv("APP_COLOR", "default_color") print(f"The app color is {app_color}") ``` - 正常運作腳本:`python app.py` - 以特定顏色執行:`export APP_COLOR=blue; python 應用程式.py` 2. **在 Docker 中使用 ENV 變數:** - Docker 容器也可以使用環境變數。這就像是向容器內的程式發出指令。 - 範例程式碼: - `docker run -e APP_COLOR=green simple-webapp-color` - 這會執行 Docker 容器(`simple-webapp-color`)並將環境變數 `APP_COLOR` 設為「綠色」。 3. **檢查環境變數:** - 有時,您會想要檢查正在執行的容器正在使用哪些環境變數。 - 範例程式碼:`docker檢查blissful_hopper` - 此命令提供有關名為“blissful_hopper”的容器的詳細訊息,包括其環境變數。 簡單來說,環境變數就像程式(或 Docker 容器)可以讀取以了解如何行為的小註釋。您可以在執行程式之前設定這些註釋,程式將使用它們來自訂自身。第二個範例中的「export」指令就像在執行程式之前寫一條註釋,告訴它如何運作。 “docker Inspect”指令就像是在容器內部查看它有什麼註解。 ## Docker 映像 **Docker 檔案:** Dockerfile 就像是 Docker 建立映像的一組指令。這就像是烤蛋糕的食譜。 ``` # Use the Ubuntu base image FROM Ubuntu # Update apt repository RUN apt-get update # Install dependencies using apt RUN apt-get install -y python # Install Python dependencies using pip RUN pip install flask RUN pip install flask-mysql # Copy source code to /opt folder COPY . /opt/source-code # Set the working directory WORKDIR /opt/source-code # Specify entry point to run the web server ENTRYPOINT ["flask", "run"] ``` **建立自己的圖像的步驟:** 1. 使用上述內容建立一個名為「Dockerfile」的檔案。 2. 將其保存在與原始碼相同的目錄中。 **建置 Docker 映像:** 在終端機中執行以下命令: ``` docker build -t your-image-name . ``` 此命令告訴 Docker 使用目前目錄中的 Dockerfile (`.`) 建置映像,並使用您選擇的名稱對其進行標記 (`-t your-image-name`)。 **分層架構:** ![分層架構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9i91e79dg61wnbbfp62m.png) - 將 Docker 映像視為一個分層蛋糕。 Dockerfile 中的每個指令都會在映像上新增一層。 - 圖層可重複使用。如果您變更程式碼中的某些內容,Docker 只會重建受影響的層,從而提高效率。 **Docker 建置輸出:** - 當您建置映像檔時,Docker 會顯示流程中的每個步驟。如果發生故障,它會給您錯誤訊息。 **你可以容器化什麼?** - 幾乎所有東西!應用程式、服務、資料庫、網站,基本上任何軟體都可以容器化。 - 這就像將您的軟體放入一個盒子中,以便它可以在任何地方執行而不會造成麻煩。 ## 什麼是 Docker CMD 與 ENTRYPOINT **Docker 中的`CMD`:** - 將 CMD 視為啟動容器時程式執行的預設操作。 - 這就像說,“嘿,當你執行這個容器時,默認執行此操作。” - 範例:`CMD ["flask", "run"]` 表示當容器啟動時,它會自動執行 Flask Web 伺服器。 **CMD 範例:** ``` FROM alpine CMD ["sleep", "5"] ``` 在此範例中,當您使用此映像執行容器時,它會自動休眠 5 秒。 **Docker 中的`ENTRYPOINT`:** - 將 ENTRYPOINT 視為容器所做的主要事情。就好像boss的命令一樣。 - 它設定一個預設應用程式在容器啟動時執行,但您仍然可以根據需要覆蓋它。 - 範例:`ENTRYPOINT ["flask", "run"]` 表示容器主要用於執行 Flask Web 伺服器,但如果需要,您仍可新增更多指令。 **入口點範例:** ``` FROM alpine ENTRYPOINT ["sleep"] CMD ["5"] ``` 在這裡,主要目的是睡眠,如果您願意,您仍然可以覆蓋睡眠持續時間。 在這兩種情況下,容器在啟動時只會休眠幾秒鐘。主要區別在於如何提供參數以及它們是否可以輕鬆覆蓋。 CMD 就像在說,“這是默認要做的事情”,而 ENTRYPOINT 就像在說,“這是主要要做的事情,但如果你願意,你可以稍微調整一下。”它們都有助於定義容器啟動時執行的操作。 ## Docker 中的網路: Docker 網路幫助容器(程式)相互通信,確保它們可以順利地協同工作。 **預設網路:** - Docker 建立預設網路供容器通訊。 - 範例程式碼:`docker run ubuntu --network=host` - 這使用主機網路執行 Ubuntu 容器,這意味著它與主機共享網路命名空間。 **使用者定義的網路:** - 您可以建立自己的網路以更好地組織和控制。 - 範例程式碼: ``` docker network create --driver=bridge --subnet=182.18.0.0/16 custom-isolated-network ``` - 這將建立一個名為「custom-isolated-network」的使用者定義的橋接網絡,具有特定的子網。 **上市網路:** - 您可以查看您擁有的所有網路。 - 範例程式碼:`docker network ls` **檢查網路:** - 您可以檢查特定網路的詳細資訊。 - 範例程式碼:`docker網路檢查blissful_hopper` - 這顯示有關名為「blissful_hopper」的網路的詳細資訊。 **嵌入式 DNS:** - Docker 有一個內建的 DNS 系統,供容器透過名稱相互查找。 - 範例程式碼:`mysql.connect(mysql)` - 這可能是程式碼中的一行,其中名為「mysql」的服務使用 Docker 的 DNS 連接到另一個名為「mysql」的服務。 ## Docker 儲存: ![Docker 儲存](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7i54a6m0o1tb0812xbjk.jpg) Docker 儲存就像使用容器時決定將資料保存在哪裡一樣。您可以將它們保留在容器內,使用磁碟區在容器之間共用它們,或將它們儲存在容器外部以妥善保管。 **Docker中的檔案系統:** - Docker 使用分層架構來建立映像。 Dockerfile 中的每個指令都會在檔案系統中新增一個新圖層。 ``` # Dockerfile FROM Ubuntu RUN apt-get update && apt-get install -y python RUN pip install flask flask-mysql COPY . /opt/source-code WORKDIR /opt/source-code ENTRYPOINT ["flask", "run"] ``` - Dockerfile 中的層: - 第 1 層:Ubuntu 基礎層 - 第 2 層:apt 軟體包的更改 - 第 3 層:pip 套件的變化 - 第 4 層:原始碼 - 第 5 層:使用「flask」指令更新入口點 - 第 6 層:容器層 **影像圖層:** - 當您建立 Docker 映像時,它由唯讀層組成。每一層代表影像的變化或加入。 - 第 1 層:Ubuntu 基礎層 - 第 2 層:apt 軟體包的更改 - 第 3 層:pip 套件的變化 - 第 4 層:原始碼 - 第 5 層:使用「flask」指令更新入口點 ``` # Build the Docker image docker build -t mmumshad/my-custom-app . ``` **容器層:** - 當您執行 Docker 容器時,會在唯讀映像層上方新增一個讀寫層。該層特定於正在執行的容器。 - 第 6 層. 容器層 ``` # Run the Docker container docker run mmumshad/my-custom-app ``` **數量:** - 卷是一種在容器外部保存資料的方法。它們就像外部記憶體。 ``` # Create a Docker volume docker volume create data_volume # Use the volume in a container docker run -v data_volume:/var/mysql mysql ``` - 您也可以使用「-v」將特定目錄從主機掛載到容器: ``` # Mount a host directory to a container directory docker run -v /path/on/host:/var/mysql/mysql -d mysql ``` - docker run --mount 指令用於將主機上的特定目錄或檔案掛載到正在執行的 Docker 容器中。 ``` docker run --mount type=bind,source=/mysql,target=/var/mysql mysql ``` **儲存驅動程式:** - Docker 使用儲存驅動程式來管理資料的儲存和存取方式。一些常見的儲存驅動程式包括 AUFS、ZFS、BTRFS、Device Mapper、Overlay 和 Overlay2。 [在 Docker 管理資料](https://docs.docker.com/storage/) [關於儲存驅動程式](https://docs.docker.com/storage/storagedriver/) [卷](https://docs.docker.com/storage/volumes/) ## Docker 組合 ![Docker Compose](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjyro6o2844s2or1b83c.jpeg) Docker Compose 是一個方便的工具,可幫助您輕鬆執行和連接不同的軟體服務,就好像它們都是同一事件的一部分一樣。 **Docker Compose 基礎:** 1. **執行單一容器:** - 通常,您可以像這樣執行單獨的 Docker 容器: ``` docker run mmumshad/simple-webapp docker run mongodb docker run redis:alpine docker run ansible ``` 2. **Docker 撰寫文件(`docker-compose.yml`):** - Docker Compose 允許您在一個簡單的檔案中定義所有這些服務: ``` # docker-compose.yml version: '3' services: web: image: 'mmumshad/simple-webapp' database: image: 'mongodb' messaging: image: 'redis:alpine' orchestration: image: 'ansible' ``` - 此檔案描述您要執行的服務(「web」、「database」、「messaging」、「orchestration」)、它們各自的映像以及任何其他配置。 3. **使用 Docker Compose 執行:** - 要一起啟動所有這些服務: ``` docker-compose up ``` - Docker Compose 負責啟動「docker-compose.yml」檔案中定義的所有容器。 4. **使用 Docker Compose 建置:** - 您也可以使用 Docker Compose 建置映像: ``` docker-compose build ``` - 此指令建置「docker-compose.yml」檔案中指定的映像。 **執行連結容器:** - 如果您要透過連結執行單一容器: ``` docker run -d --name redis redis docker run --name voting-app -p 5000:80 --link redis:redis voting-app docker run --name result-app -p 5001:80 --link db:db result-app docker run -d --name worker --link db:db --link redis:redis worker ``` - 在 Docker 中撰寫: ``` # docker-compose.yml version: '3' services: vote: image: 'voting-app' ports: - '5000:80' links: - 'redis:redis' result: image: 'result-app' ports: - '5001:80' links: - 'db:db' worker: image: 'worker' links: - 'db:db' - 'redis:redis' db: image: 'db' redis: image: 'redis' ``` Docker Compose 可讓您在單一檔案中描述整個應用程式堆疊,從而輕鬆管理、執行和連接不同的服務。這就像在一份計劃中寫下活動的所有任務,然後 Docker Compose 為您處理設定。 [Docker Compose 概述](https://docs.docker.com/compose/) [Docker 撰寫文件](https://docs.docker.com/engine/reference/commandline/compose/) ## Docker 註冊表 ![Docker 註冊表](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzflp82qyg36y8fcf8k8.png) Docker 註冊表是人們儲存和分享 Docker 映像的地方,使其他人可以輕鬆使用和執行他們的軟體。它就像一個大型線上程式庫,可以輕鬆下載並在不同電腦上使用。 **Docker 註冊表基礎知識:** 1. **公共登記處:** - Docker 映像可以在 Docker Hub 等公共註冊表中儲存和共用。 - 例: ``` docker pull nginx ``` 2. **私人登記處:** - 有時,您可能希望將圖像保存在您自己的私人註冊表中。 - 例: - 登入私人註冊表: ``` bash docker login private-registry.io ``` - 從私有註冊表中的映像執行容器: ``` docker run private-registry.io/apps/internal-app ``` 3. **部署您自己的私有註冊表:** - 您可以為您的團隊或公司部署自己的私人註冊表。 - 例: - 在您的電腦上執行私有註冊表: ``` docker run -d -p 5000:5000 --name registry registry:2 ``` - 為私人註冊表標記您的圖像: ``` bash docker image tag my-image localhost:5000/my-image ``` - 將映像推送到您的私人註冊表: ``` bash docker push localhost:5000/my-image ``` - 從您的私人註冊表中提取映像: ``` bash docker pull localhost:5000/my-image ``` 4. **從遠端私有註冊表中提取:** - 您也可以使用 IP 位址或網域從遠端私有註冊表中提取映像。 - 例: ``` docker pull 192.168.56.100:5000/my-image ``` Docker 註冊表就像一個儲存空間,人們在其中保存和共享 Docker 映像。您可以將公用註冊表用於廣泛使用的映像,也可以根據您的特定需求設定自己的私人註冊表。它就像一個用於共享和儲存軟體藍圖(圖像)的特殊庫。 ## Docker 引擎 ![Docker 引擎](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hc6r4dvo9kg9xqgwsrbb.jpg) 想像一下,你有一個魔盒(Docker Engine),可以為你執行和管理各種程式(容器)。 Docker Engine 就像是這個魔盒的大腦。 1. **Docker 守護程式:** - 守護程式就像魔法盒的看門人。它始終在那裡,隨時準備接受指示並確保一切順利進行。 2. **REST API:** - 將 REST API 視為一組允許您與魔盒對話的規則。它就像你和守護程式用來溝通的語言。你告訴守護程式要做什麼,它會理解,因為你們說的是同一種語言。 3. **Docker CLI(命令列介面):** - Docker CLI 就像是用來命令守護程式的魔杖。您輸入指令,守護程式就會按照您的指示進行操作。這就像說「Abracadabra」就能讓事情發生。 **連線到遠端 Docker 引擎:** 連接到遠端 Docker 引擎可讓您控制另一台機器上的容器,且設定約束可確保容器僅使用指定的資源。 1. **Docker主機IP:** - 您可以使用 IP 位址和連接埠連接到不同電腦上的 Docker 引擎。 - 例: ``` docker -H=remote-docker-engine:2375 run nginx ``` - 這告訴您的本機 Docker CLI 與遠端 Docker 引擎進行通訊。 2. **有約束地執行容器:** - Docker 允許您設定容器的資源限制,例如 CPU 和記憶體限制。 - 例: ``` docker run --cpus=0.5 ubuntu docker run --memory=100m ubuntu ``` - 這些指令限制容器僅使用半個 CPU 核心和 100 MB 記憶體。 當然,讓我們簡化一下PID命名空間的概念: **命名空間PID:** PID 命名空間可讓您為容器中的進程(如程式或任務)建立單獨的區域,因此它們有自己的一組「票號」(進程 ID),不會與容器外的進程發生衝突。 **範例程式碼:** 1. **使用主機 PID 命名空間執行容器:** - 這表示容器與主機共用相同的「票號」。 ``` docker run --pid=host ubuntu ``` 2. **執行具有隔離 PID 命名空間的容器:** - 這表示容器有自己的一組獨立於主機的「票號」。 ``` docker run --pid=container ubuntu ``` 在第一個範例中,容器與進程交互,就好像它與主機位於同一空間中一樣。在第二個範例中,容器有自己的進程隔離空間。這就像在大型活動中擁有一個私人區域,您的團隊有自己的一套票號,讓您可以獨立於活動的其餘部分進行操作。 **容器化概念:** 1. **進程 ID 命名空間:** - 容器有自己獨立的流程 ID (PID) 空間,因此容器內的流程與容器外的流程是分開的。 - 例: ``` docker run --pid=host ubuntu ``` - 此指令使用主機的 PID 命名空間來執行容器,因此它共用相同的程序。 2. **網路命名空間:** - 容器也有自己獨立的網路命名空間,這意味著它們可以有自己的網路配置。 - 例: ``` docker run --net=host nginx ``` - 此指令使用主機的網路命名空間來執行容器。 3. **Unix分時命名空間:** - 此命名空間允許容器擁有自己的時間視圖,與主機和其他容器分開。 - 例: ``` docker run --uts=host ubuntu ``` - 此指令使用主機的 Unix 時間共用命名空間來執行容器。 4. **進程間掛載命名空間:** - Mount命名空間隔離檔案系統,讓容器擁有自己的檔案系統視圖。 - 例: ``` docker run --mount=type=bind,source=/host/folder,target=/container/folder ubuntu ``` - 此指令將主機中的資料夾安裝到容器中。 當然!我們來簡化一下cgroup的概念: **C組:** cgroup(控制組的縮寫)可協助在不同進程或容器之間管理和分配系統資源,例如 CPU 和記憶體。它們確保沒有任何一個進程或容器耗盡所有可用資源,從而保持一切平衡。 **範例程式碼:** 1. **使用 Cgroup 設定 CPU 限制:** - 這就像說聚會上的每位客人只能吃一定數量的食物。 ``` docker run --cpus=0.5 ubuntu ``` - 這限制容器僅使用一半的 CPU 核心。 2. **使用 Cgroup 設定記憶體限制:** - 這就像說每位客人只能在舞池上佔據一定的空間。 ``` docker run --memory=100m ubuntu ``` - 這限制容器僅使用 100 MB 記憶體。 [Docker 引擎概述](https://docs.docker.com/engine/) [使用 Docker Engine API 進行開發](https://docs.docker.com/engine/api/) [執行時指標](https://docs.docker.com/config/containers/runmetrics/#control-groups) ## Linux容器與Windows容器的概念: **Linux 容器(預設):** Linux 容器是一種打包和執行軟體及其所需一切的方法,它們最適合執行 Linux 的電腦。 **Windows 容器:** Windows 容器是一種打包和執行軟體的方式,就像 Linux 容器一樣,但它們設計用於執行 Windows 的電腦。 **Windows 容器基礎:** 1. **集裝箱類型:** - Windows 容器有兩種主要類型:Windows Server Core 和 Nano Server。 - **Windows Server Core:** 將其視為功能更齊全的容器,適合各種應用程式。 - **Nano Server:** 將其視為一個輕量級容器,專為特定的、簡約的用例而設計。 2. **基礎鏡像:** - 基礎映像就像是建立容器時開始使用的空白畫布。 - 例: ``` docker pull mcr.microsoft.com/windows/servercore:ltsc2019 ``` - 此指令擷取 Windows Server Core 基礎映像。 - 例: ``` docker pull mcr.microsoft.com/windows/nanoserver:ltsc2019 ``` - 此命令提取 Nano Server 基礎映像。 3. **支援的環境:** - Windows 容器可以在特定版本的 Windows 作業系統上運作。 - 例: - 您可以在 Windows Server 2016 上執行 Windows 容器。 - 例: - 您可以在 Windows 10 專業版和企業版上執行 Windows 容器,並使用 Hyper-V 隔離容器進行額外隔離。 ## 容器編排 ![容器編排](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3lyleybojw3xmr2dgfep.png) 容器編排是一種管理和協調多個容器的方法,確保它們無縫協作來執行應用程式,就像一個超級智能的管理器確保所有機器人一起工作來建置完美的塔一樣。 **為什麼要編曲?** 1. **多項任務,一名經理:** - 想像一下您有許多機器人(容器)執行不同的工作。編排就像有一位超級聰明的經理(編排者),他告訴每個機器人該做什麼,並確保一切順利進行。 2. **一致性:** - 編排確保所有任務每次都以相同的方式完成。這就像為您的機器人提供了一套要遵循的指令,以確保其行為的一致性。 3. **效率:** - 編排有助於優化任務,確保資源(如時間和材料)有效利用。這就像經理確保所有機器人一起工作而不浪費能源。 4. **縮放比例:** - 當您需要完成更多工作時,編排可以輕鬆建立額外的機器人(容器)。這就像當有很多事情需要完成時神奇地召喚更多機器人來提供幫助。 5. **可靠性:** - 編排確保任務可靠地完成,即使機器人(容器)出現故障。這就像製定備份計劃來確保無論如何都能完成工作。 6. **協調:** - 編排協調任務,確保機器人無縫協作。這就像經理確保每個機器人都知道自己的角色並協作以實現總體目標。 **容器編排程式碼:** ``` # Create a Docker service with 100 replicas (instances) of a Node.js application docker service create --replicas 100 --name my-nodejs-app nodejs ``` 在這個例子中: - `docker service create`:該指令告訴 Docker 建立一個服務,該服務是一組正在執行的容器。 - `--replicas 100`:此標誌指定您需要 100 個服務實例(副本)。 - `--name my-nodejs-app`:此標誌為您的服務提供名稱,在本例中為「my-nodejs-app」。 - `nodejs`:這是 Node.js 應用程式的圖片或配方。這就像是烘焙紙杯蛋糕的藍圖。 因此,這段簡單的程式碼就像告訴您神奇的廚師助手 (Docker Swarm) 建立 Node.js 應用程式的 100 個副本,確保您有大量容器正在執行並準備好提供服務。 ## Docker 群 ![Docker Swarm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z5noonjo2ikyrp90kc38.png) Docker Swarm 是一個工具,可以幫助協調和管理一組電腦(節點)作為一個機器人團隊一起工作,使它們能夠以協調的方式部署和執行多個容器。這就像有一個首席機器人經理,確保所有單一機器人一起建造出偉大而令人驚嘆的東西。 **設定 Docker Swarm:** 1. **群組管理器:** - 想像你有一個首席機器人(Swarm Manager)來領導團隊。主機器人決定需要做什麼,並指導其他機器人(節點)如何協同工作。 ``` # Initiate Docker Swarm on the Swarm Manager docker swarm init ``` 2. **節點工作人員:** - 現在,您的工作機器人(節點工作人員)已準備好加入團隊。 Swarm Manager 共享一個特殊的程式碼(令牌)來邀請他們一起工作。 ``` # Join a Node Worker to the Docker Swarm docker swarm join --token <token> <Swarm Manager IP> ``` **Docker Swarm 服務:** 現在您已經有了一個協調的團隊,您想要建立一項服務,例如與您的機器人團隊一起建造塔: ``` # Create a Docker service (a group of containers) with 3 replicas (instances) docker service create --replicas 3 --network frontend --name my-web-server my-web-image ``` - `--replicas 3`:此標誌告訴 Docker 建立服務的三個實例(副本)。 - `--network frontend`:此標誌指定您的服務屬於名為「frontend」的網路。 - `--name my-web-server`:這會為您的服務命名,在本例中為「my-web-server」。 - `my-web-image`:這是您的網頁伺服器的圖片或藍圖。這就像建造塔樓的配方。 您建立了一個由隊長(Swarm Manager)和工作機器人(Node Workers)組成的機器人團隊。然後,您指示他們建立一個執行您的 Web 伺服器應用程式的服務(容器群組)。主機器人確保建立 Web 伺服器的三個副本並將其連接到「前端」網路。這就像有一個首席機器人經理在工作機器人的幫助下監督多個塔(貨櫃)的建造。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytitz2wt4jsufejox9yx.gif) **好的,這就是本文的內容。** 另外,如果您對此或其他任何問題有任何疑問,請隨時在下面的評論中或在 [Instagram](https://www.instagram.com/_abhixsh/) 、[Facebook](https://www.facebook.com/abhi.haththakage/) 或[Twitter](https://twitter.com/abhixsh)。 感謝您閱讀這篇文章,我們下一篇再見! ❤️ --- 原文出處:https://dev.to/abhixsh/docker-for-the-absolute-beginner-3h1p

JS 設計模式:綜合指南

![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vukjahraekzzsj9e6h3x.png) JavaScript 以其廣泛的採用和多功能性,已成為現代 Web 開發的基石。隨著您深入研究 JavaScript 開發,理解和利用模式變得至關重要。在本文中,我們將踏上揭開 JavaScript 模式神秘面紗的旅程,並探索它們如何增強您的程式設計實踐。 ## 先決條件 要理解本文中討論的概念和技術,您需要了解 JavaScript 的基礎知識。熟悉變數、函數、資料類型、物件導向程式設計等概念至關重要。 在繼續之前,讓我們花點時間了解 JavaScript 作為程式語言的重要性。 ### JavaScript 作為程式語言 JavaScript 通常被稱為“網路語言”,是一種動態的高階程式語言。它主要用於 Web 瀏覽器中的客戶端腳本編寫,但隨著 Node.js 的出現,它也在伺服器端獲得了關注。 JavaScript 的主要功能包括操作 DOM、處理事件、為網頁提供互動性等的能力。 話雖這麼說,讓我們簡單討論一下 JavaScript 中模式的重要性和用途。 ### JavaScript 開發中模式的重要性 JavaScript 中的模式可以作為軟體開發過程中遇到的重複問題的經過驗證的解決方案。它們提供結構、改進程式碼組織、增強可維護性並促進可重複使用性。透過理解和應用模式,開發人員可以編寫更清晰、更有效率的程式碼並有效應對複雜的挑戰。 ### 理解 JavaScript 模式的目的 理解 JavaScript 模式不僅僅是記住文法或遵循最佳實踐。它使開發人員能夠批判性地思考軟體設計、選擇適當的解決方案並建立可擴展的應用程式。透過掌握 JavaScript 模式,您可以深入了解該語言及其生態系統,從而能夠編寫健全且可維護的程式碼。 現在我們知道了 JavaScript 模式的重要性和用途,讓我們深入研究 JS 設計模式的基礎知識。 ## 設計模式的基礎知識 在本節中,我們為理解 JavaScript 開發背景下的設計模式奠定了基礎。 ###設計模式的定義與特點 設計模式是可重複使用的模板,封裝了解決重複出現的軟體設計問題的最佳實踐。它們提供了一種結構化的方法來設計軟體系統,並促進模組化、靈活和可維護的程式碼。設計模式的共同特徵包括其目的、結構、參與者和協作。 ###設計模式的類型 設計模式可分為三種主要類型: - 創意 - 結構性 - 行為的 了解這些類別有助於確定給定問題的適當模式。 - **創作模式** 建立模式專注於物件建立機制,提供以靈活且受控的方式實例化物件的方法。 JavaScript 中一些常用的建立模式包括: - 辛格頓 - 工廠 - 建構函數 - 原型 - 建造者 - 模組 **單例模式** 單例模式確保一個類別只有一個實例,並提供對其的全域存取點。當您想要限制類別的實例數量並確保在整個應用程式中可以存取單一共用實例時,此模式非常有用。 ``` // Implementation example of the Singleton Pattern class Singleton { constructor() { if (!Singleton.instance) { // Initialize the instance Singleton.instance = this; } return Singleton.instance; } } const instance1 = new Singleton(); const instance2 = new Singleton(); console.log(instance1 === instance2); // Output: true ``` 在此範例中,Singleton 類別有一個建構函數,用於檢查該類別的實例是否已存在。如果實例不存在(“!Singleton.instance”條件),它將透過將其指派給「Singleton.instance」來初始化該實例。這確保了對建構函數的後續呼叫將傳回相同的實例。 當使用新的 Singleton() 語法建立實例 1 和實例 2 時,這兩個變數都會引用 Singleton 類別的同一個實例。因此,當使用嚴格相等運算子比較實例 1 === 實例 2 時,其計算結果為 true。 **工廠模式** 工廠模式提供了一種建立物件而無需指定其特定類別的方法。它將物件建立邏輯封裝在一個單獨的工廠方法中,允許建立者和建立的物件之間的靈活性和解耦。 ``` // Implementation example of the Factory Pattern class Car { constructor(make, model) { this.make = make; this.model = model; } } class CarFactory { createCar(make, model) { return new Car(make, model); } } const factory = new CarFactory(); const myCar = factory.createCar("Tope", "Model 1"); ``` 在此範例中,使用 new CarFactory() 建立了一個 CarFactory 實例,然後使用參數「Tope」和「Model 1」在工廠上呼叫「createCar」方法。這將建立一個新的 Car 物件,其品牌為“Tope”,型號為“Model 1”,並分配給 `myCar` 變數。 **建構函式模式** 建構函式模式使用“new”關鍵字從建構函式建立物件。它允許您在建構函數中定義和初始化物件屬性。 ``` // Implementation example of the Constructor Pattern function Person(name, age) { this.name = name; this.age = age; } const tope = new Person("Tope", 24); ``` 上面的程式碼定義了一個名為 Person 的建構函數,它帶有兩個參數:姓名和年齡。在函數內部,使用 this 關鍵字將名稱和年齡值指派給新建立的物件的對應屬性。 稍後,透過使用參數“Tope”和 24 呼叫 Person 函數來建立 Person 物件的新實例。這將建立一個新物件,其 name 屬性設為“Tope”,age 屬性設為 24,然後指派給變數top。這段程式碼的輸出是 Tope 持有一個物件,代表一個名為「Tope」、年齡為 24 歲的人。 **原型模式** JavaScript 中的原型模式專注於透過複製或擴展現有物件作為原型來建立物件。它允許我們建立新實例而無需明確定義它們的類別。在此模式中,物件充當建立新物件的原型,從而實現繼承以及在多個物件之間共享屬性和方法。 ``` // Prototype object const carPrototype = { wheels: 4, startEngine() { console.log("Engine started."); }, stopEngine() { console.log("Engine stopped."); } }; // Create new car instance using the prototype const car1 = Object.create(carPrototype); car1.make = "Toyota"; car1.model = "Camry"; // Create another car instance using the same prototype const car2 = Object.create(carPrototype); car2.make = "Honda"; car2.model = "Accord"; car1.startEngine(); // Output: "Engine started." car2.stopEngine(); // Output: "Engine stopped." ``` 在此範例中,汽車實例 car1 和 car2 是使用原型物件 carPrototype 建立的。 car1 的品牌為“Toyota”,型號為“Camry”,而 car2 的品牌為“Honda”,型號為“Accord”。當呼叫 `car1.startEngine()` 時,輸出“Engine started.”,當呼叫 `car2.stopEngine()` 時,輸出“Engine waiting.”。這示範如何利用原型物件在多個實例之間共用屬性和方法。 **建造者模式** 在建構器模式中,建構器類別或物件負責建構最終物件。它提供了一組方法來配置和設定正在建置的物件的屬性。建置過程通常涉及按特定順序呼叫這些方法來逐步建立物件。 ``` class CarBuilder { constructor() { this.car = new Car(); } setMake(make) { this.car.make = make; return this; } setModel(model) { this.car.model = model; return this; } setEngine(engine) { this.car.engine = engine; return this; } setWheels(wheels) { this.car.wheels = wheels; return this; } build() { return this.car; } } class Car { constructor() { this.make = ""; this.model = ""; this.engine = ""; this.wheels = 0; } displayInfo() { console.log(`Make: ${this.make}, Model: ${this.model}, Engine: ${this.engine}, Wheels: ${this.wheels}`); } } // Usage const carBuilder = new CarBuilder(); const car = carBuilder.setMake("Toyota").setModel("Camry").setEngine("V6").setWheels(4).build(); car.displayInfo(); // Output: Make: Toyota, Model: Camry, Engine: V6, Wheels: 4 ``` 在此範例中,「CarBuilder」類別允許建構具有不同屬性的 Car 物件。透過呼叫`setMake`、`setModel`、`setEngine`、`setWheels`方法,設定Car物件的屬性。 build 方法完成建置並傳回完全建置的 Car 物件。 Car 類別代表一輛汽車,並包含一個「displayInfo」方法來記錄其詳細資訊。透過建立「carBuilder」實例並連結屬性設定方法,可以使用特定的品牌、型號、引擎和車輪值來建構汽車物件。呼叫“car.displayInfo()”顯示汽車的資訊。 **模組模式** 模組模式將相關的方法和屬性封裝到單一模組中,提供了一種乾淨的方式來組織和保護程式碼。它允許私有和公共成員,從而實現資訊隱藏並防止全域名稱空間污染。 ``` const MyModule = (function() { // Private members let privateVariable = "I am private"; function privateMethod() { console.log("This is a private method"); } // Public members return { publicVariable: "I am public", publicMethod() { console.log("This is a public method"); // Accessing private members within the module console.log(privateVariable); privateMethod(); } }; })(); // Usage console.log(MyModule.publicVariable); // Output: "I am public" MyModule.publicMethod(); // Output: "This is a public method" "I am private" "This is a private method" ``` 在此範例中,程式碼使用立即呼叫的函數表達式來封裝私人和公共成員。該模組具有私有變數和方法,以及公共變數和方法。存取時,公共成員提供預期的輸出。此模式允許對封裝的私有成員進行受控存取,同時公開選定的公共成員。 - **結構模式** 結構模式著重於組織和組合物件以形成更大的結構。它們促進物件的組合,定義物件之間的關係並提供靈活的方法來操縱其結構。 JavaScript 中一些常用的結構模式包括: - 裝飾模式 - 立面圖案 - 適配器 - 橋 - 合成的 **裝飾器模式** 裝飾器模式可讓您動態新增行為或修改物件的現有行為。它透過用一個或多個裝飾器包裝物件來增強物件的功能,而無需修改其結構。 ``` // Implementation example of the Decorator Pattern class Coffee { getCost() { return 1; } } class CoffeeDecorator { constructor(coffee) { this.coffee = coffee; } getCost() { return this.coffee.getCost() + 0.5; } } const myCoffee = new Coffee(); const coffeeWithMilk = new CoffeeDecorator(myCoffee); console.log(coffeeWithMilk.getCost()); // Output: 1.5 ``` 在此範例中,「CoffeeDecorator」類別包裝了基本「Coffee」物件並新增了附加功能。它有一個「getCost」方法,透過將基礎咖啡的成本與 0.5 的附加成本相結合來計算總成本。 在使用部分,建立了「Coffee」類別的「myCoffee」實例。然後,實例化「CoffeeDecorator」類別的「coffeeWithMilk」實例,並將「myCoffee」作為參數傳遞。當呼叫“coffeeWithMilk.getCost()”時,它會返回咖啡的總成本以及裝飾器加入的成本,從而得到 1.5 的輸出。此範例說明了裝飾器模式如何透過動態新增或修改物件的屬性或方法來擴展物件的功能。 **立面圖案** 外觀模式為複雜子系統提供了一個簡化的接口,充當隱藏底層實現細節的前端接口。它透過提供高級接口,提供了一種與複雜系統互動的便捷方式。 ``` // Implementation example of the Facade Pattern class SubsystemA { operationA() { console.log("Subsystem A operation."); } } class SubsystemB { operationB() { console.log("Subsystem B operation."); } } class Facade { constructor() { this.subsystemA = new SubsystemA(); this.subsystemB = new SubsystemB(); } operation() { this.subsystemA.operationA(); this.subsystemB.operationB(); } } const facade = new Facade(); facade.operation(); // Output: "Subsystem A operation." "Subsystem B operation." ``` 在此範例中,程式碼由三個類別組成:「SubsystemA」、「SubsystemB」和「Facade」。 `SubsystemA` 和 `SubsystemB` 類別代表獨立的子系統,並具有各自的 `operationA` 和 `operationB` 方法。 「Facade」類別作為一個簡化的接口,聚合了子系統的功能。 在使用部分,建立了“Facade”類別的“facade”實例。呼叫「facade.operation()」會觸發「SubsystemA」中的「operationA」和「SubsystemB」中的「operationB」的執行。結果,輸出顯示“子系統 A 操作”。接下來是「子系統 B 操作」。這展示了外觀模式如何提供統一且簡化的介面來與複雜的子系統交互,抽像出它們的複雜性並使它們更易於使用。 **適配器模式** 適配器模式是一種結構設計模式,它允許具有不相容介面的物件透過充當它們之間的橋樑來進行協作。它提供了一種將一個物件的介面轉換為客戶期望的另一個介面的方法。 ``` // Implementation class LegacyPrinter { printLegacy(text) { console.log(`Legacy Printing: ${text}`); } } // Target interface class Printer { print(text) {} } // Adapter class PrinterAdapter extends Printer { constructor() { super(); this.legacyPrinter = new LegacyPrinter(); } print(text) { this.legacyPrinter.printLegacy(text); } } // Usage const printer = new PrinterAdapter(); printer.print("Hello, World!"); // Output: "Legacy Printing: Hello, World!" ``` 在此程式碼中,適配器模式用於彌合「LegacyPrinter」類別和所需的「Printer」介面之間的差距。 `PrinterAdapter` 擴展了 `Printer` 類,並在內部利用 `LegacyPrinter` 來適配 `print` 方法。當呼叫 printer.print("Hello, World!")` 時,它會有效地觸發舊版列印功能,並輸出「Legacy Printing: Hello, World!」。這展示了適配器模式如何透過提供標準化介面來整合不相容的元件。 **橋樑圖案** 橋接模式是一種結構設計模式,它將系統的抽象和實現分開,允許系統獨立發展。它透過使用介面或抽象類別在兩者之間引入了橋樑。下面是一個範例程式碼片段來說明橋接模式: ``` // Example class Shape { constructor(color) { this.color = color; } draw() {} } // Concrete Abstractions class Circle extends Shape { draw() { console.log(`Drawing a ${this.color} circle`); } } class Square extends Shape { draw() { console.log(`Drawing a ${this.color} square`); } } // Implementor class Color { getColor() {} } // Concrete Implementors class RedColor extends Color { getColor() { return "red"; } } class BlueColor extends Color { getColor() { return "blue"; } } // Usage const redCircle = new Circle(new RedColor()); redCircle.draw(); // Output: "Drawing a red circle" const blueSquare = new Square(new BlueColor()); blueSquare.draw(); // Output: "Drawing a blue square" ``` 在此範例中,我們有由 Shape 類別表示的抽象,它具有顏色屬性和繪製方法。具體抽象(圓形和方形)繼承自 Shape 類別並實現其特定的繪製行為。 「Implementor」由 Color 類別表示,該類別聲明了「getColor」方法。具體的「Implementors」、「RedColor」和「BlueColor」繼承自 Color 類別並提供各自的顏色實作。 在使用部分,我們建立具體抽象的實例,傳遞適當的具體實現者物件。這允許抽象化將與顏色相關的功能委託給實現者。當我們呼叫draw方法時,它會從Implementor存取顏色並相應地執行繪圖操作。 **複合模式** 組合模式是一種結構設計模式,可讓您統一處理單一物件和物件組合。它使您能夠建立層次結構,其中每個元素都可以被視為單個物件或物件集合。此模式使用通用介面來表示單一物件(葉節點)和組合(複合節點),允許客戶端與它們統一互動。 ``` // Implementation class Employee { constructor(name) { this.name = name; } print() { console.log(`Employee: ${this.name}`); } } // Composite class Manager extends Employee { constructor(name) { super(name); this.employees = []; } add(employee) { this.employees.push(employee); } remove(employee) { const index = this.employees.indexOf(employee); if (index !== -1) { this.employees.splice(index, 1); } } print() { console.log(`Manager: ${this.name}`); for (const employee of this.employees) { employee.print(); } } } // Usage const john = new Employee("John Doe"); const jane = new Employee("Jane Smith"); const mary = new Manager("Mary Johnson"); mary.add(john); mary.add(jane); const peter = new Employee("Peter Brown"); const bob = new Manager("Bob Williams"); bob.add(peter); bob.add(mary); bob.print(); ``` 在此範例中,我們有 Component 類別 Employee,它代表個別員工。 Composite 類 Manager 擴展了 Employee 類,並且可以包含員工的集合。它提供了在集合中新增和刪除員工的方法,並重寫 print 方法以顯示經理的姓名及其下的員工。 在使用部分,我們建立一個複合層次結構,其中 Manager 物件可以包含單一員工 (Employee) 和其他經理 (Manager)。我們將員工加入經理中,建構了一個層次結構。最後,我們呼叫頂級經理的 print 方法,該方法遞歸地列印層次結構,顯示經理及其各自的員工。 - **行為模式** 行為模式關注物件之間的互動和職責分配。它們為物件之間的通訊、協調和協作提供解決方案。以下是行為模式的類型。 - 觀察者模式 - 策略模式 - 命令模式 - 迭代器模式 - 調解者模式 **觀察者模式** 觀察者模式在物件之間建立一對多關係,其中多個觀察者會收到主體狀態變化的通知。它支援物件之間的鬆散耦合並促進事件驅動的通訊。 ``` // Implementation example of the Observer Pattern class Subject { constructor() { this.observers = []; } addObserver(observer) { this.observers.push(observer); } removeObserver(observer) { const index = this.observers.indexOf(observer); if (index !== -1) { this.observers.splice(index, 1); } } notifyObservers() { this.observers.forEach((observer) => observer.update()); } } class Observer { update() { console.log("Observer is notified of changes."); } } const subject = new Subject(); const observer1 = new Observer(); const observer2 = new Observer(); subject.addObserver(observer1); subject.addObserver(observer2); subject.notifyObservers(); // Output: "Observer is notified of changes." "Observer is notified of changes." ``` 在此範例中,「Subject」類別表示一個主題,它維護觀察者清單並提供新增、刪除和通知觀察者的方法。 「Observer」類別透過其「update」方法定義觀察者的行為。在使用部分,建立了「Subject」類別的「subject」實例。也使用“addObserver”方法建立兩個“observer”實例並將其新增至主題。 當呼叫“subject.notifyObservers()”時,它會觸發每個觀察者的“update”方法。結果,輸出「觀察者收到更改通知」。被記錄兩次,顯示觀察者已被告知主題的變化。 **策略模式** 策略模式可讓您將可互換的演算法封裝在單獨的策略物件中。它支援在執行時動態選擇演算法,從而提高靈活性和可擴展性。 ``` // Implementation example of the Strategy Pattern class Context { constructor(strategy) { this.strategy = strategy; } executeStrategy() { this.strategy.execute(); } } class ConcreteStrategyA { execute() { console.log("Strategy A is executed."); } } class ConcreteStrategyB { execute() { console.log("Strategy B is executed."); } } const contextA = new Context(new ConcreteStrategyA()); contextA.executeStrategy(); // Output: "Strategy A is executed." const contextB = new Context(new ConcreteStrategyB()); contextB.executeStrategy(); // Output: "Strategy B is executed." ``` 在此範例中,「Context」類別表示封裝不同策略的上下文,具有「strategy」屬性和「executeStrategy」方法。有兩個特定策略類,“ConcreteStrategyA”和“ConcreteStrategyB”,每個類別都有自己的“execute”方法來輸出特定訊息。 在使用部分,使用“ConcreteStrategyA”作為策略來建立“Context”類別的“contextA”實例。呼叫 `contextA.executeStrategy()` 會呼叫 `ConcreteStrategyA` 的 `execute` 方法,導致輸出「策略 A 已執行」。類似地,以「ConcreteStrategyB」為策略建立「contextB」實例,呼叫「contextB.executeStrategy()」會觸發「ConcreteStrategyB」的「execute」方法,從而輸出「策略 B 已執行」。這演示了策略模式如何透過將行為封裝在不同的策略物件中來允許在執行時動態選擇行為。 **命令模式** 命令模式將請求封裝為物件,允許您使用不同的請求對客戶端進行參數化、對請求進行排隊或記錄請求,並支援撤銷操作。它將請求的發送者與接收者解耦,從而促進鬆散耦合和靈活性。 ``` // Implementation class Receiver { execute() { console.log("Receiver executes the command."); } } class Command { constructor(receiver) { this.receiver = receiver; } execute() { this.receiver.execute(); } } class Invoker { setCommand(command) { this.command = command; } executeCommand() { this.command.execute(); } } const receiver = new Receiver(); const command = new Command(receiver); const invoker = new Invoker(); invoker.setCommand(command); invoker.executeCommand(); // Output: "Receiver executes the command." ``` 在此範例中,「Receiver」類別在呼叫時執行命令,「Command」類別封裝命令並將執行委託給接收者。 `Invoker` 類別設定並執行命令。在使用部分,建立了接收者、命令和呼叫者。此指令是為呼叫者設定的,呼叫「invoker.executeCommand()」會執行該指令,從而產生輸出「接收者執行該指令」。 **迭代器模式** 迭代器模式是一種行為設計模式,它提供了一種順序存取聚合物件的元素而不暴露其底層表示的方法。它允許您以統一的方式遍歷物件集合,而不管集合的具體實現如何。該模式將遍歷邏輯與集合分開,從而促進了一種乾淨而靈活的方法來迭代元素。 ``` // Implementation class Collection { constructor() { this.items = []; } addItem(item) { this.items.push(item); } createIterator() {} } // Concrete Aggregate class ConcreteCollection extends Collection { createIterator() { return new ConcreteIterator(this); } } // Iterator class Iterator { constructor(collection) { this.collection = collection; this.index = 0; } hasNext() {} next() {} } // Concrete Iterator class ConcreteIterator extends Iterator { hasNext() { return this.index < this.collection.items.length; } next() { return this.collection.items[this.index++]; } } // Usage const collection = new ConcreteCollection(); collection.addItem("Item 1"); collection.addItem("Item 2"); collection.addItem("Item 3"); const iterator = collection.createIterator(); while (iterator.hasNext()) { console.log(iterator.next()); } ``` 在此程式碼中,我們有由 Collection 類別表示的 Aggregate,它定義了用於建立迭代器物件的介面。具體聚合「ConcreteCollection」擴展了 Collection 類別並提供了迭代器建立的具體實作。 Iterator 由 Iterator 類別表示,它定義了存取和遍歷元素的介面。具體迭代器“ConcreteIterator”擴展了迭代器類別並提供了迭代邏輯的具體實作。在使用部分,我們建立一個 Concrete Aggregate 的實例“ConcreteCollection”,並向其中新增專案。然後我們使用 createIterator 方法建立一個迭代器。透過使用迭代器的“hasNext”和 next 方法,我們迭代集合併列印每個專案。 **調解者模式** 中介者模式透過引入充當協調物件之間互動的中心樞紐的中介者物件來簡化物件溝通。它封裝了通訊邏輯,並為物件提供了註冊、發送和接收訊息的方法。 ``` // Implementation class Mediator { constructor() { this.colleague1 = null; this.colleague2 = null; } setColleague1(colleague) { this.colleague1 = colleague; } setColleague2(colleague) { this.colleague2 = colleague; } notifyColleague1(message) { this.colleague1.receive(message); } notifyColleague2(message) { this.colleague2.receive(message); } } class Colleague { constructor(mediator) { this.mediator = mediator; } send(message) { // Send a message to the mediator this.mediator.notifyColleague2(message); } receive(message) { console.log(`Received message: ${message}`); } } // Usage const mediator = new Mediator(); const colleague1 = new Colleague(mediator); const colleague2 = new Colleague(mediator); mediator.setColleague1(colleague1); mediator.setColleague2(colleague2); colleague1.send("Hello Colleague 2!"); // Output: "Received message: Hello Colleague 2!" ``` 在此範例中,我們有一個 Mediator 類,它充當兩個 Colleague 物件之間的中介。中介者保存對同事的引用並提供在他們之間發送訊息的方法。 每個Colleague物件都有一個對中介者的引用,並且可以透過通知中介者來發送訊息。調解員又將訊息轉發給適當的同事。在這種情況下,同事 1 會向同事 2 發送訊息,後者接收並記錄該訊息。 ### 結論 我們探索了 JavaScript 中的一系列基本設計模式,包括建立模式、結構模式和行為模式。建立模式使我們能夠以靈活且高效的方式建立物件。結構模式有助於器官的靈活性和可擴展性。行為模式支援 JavaScript 物件之間的有效溝通和互動。透過利用這些設計模式,JavaScript 開發人員可以提高程式碼的可重複使用性、可維護性和整體系統效能。有了這些知識,我們就可以建立健壯且高效的 JavaScript 應用程式,以滿足現代軟體開發的需求。 --- 原文出處:https://dev.to/topefasasi/js-design-patterns-a-comprehensive-guide-h3m

JavaScript 框架 - 邁向 2024 年

我不是第一個這麼說的人,但我還是要說,2023 年對 JavaScript 框架來說是個不平凡的一年。我們一直在關注的新技術最終顯示出它們可以交付,而舊框架正在復興,如果您不注意,您可能會錯過一個相當重大的轉變。 我預計 2024 年將繼續出現更大的全面變化。這次不是新技術,而是精細化。既然基礎已經存在,那麼還有很多事情要做。 -------------------- ## 伺服器優先 如果讓我為過去幾年選擇一個主題,那就是這個。這一直是爭論的焦點,但不可否認。幾年前,每個人都在談論漸進式 Web 應用程式和離線應用程式。但那個對話框幾乎消失了。 相反,我們會受到 HTMX 的敏銳智慧的影響,解釋為什麼 JavaScript 只是一個錯誤。 Astro 毫無歉意地接管了內容網站的開發。甚至 React Core 團隊也接受了 React Server Components 的伺服器簡單性,Dan Abramov 的演講令人信服地表達了這一點,該演講探討瞭如果 React 始終是伺服器優先會怎樣。 https://www.youtube.com/watch?v=zMf_xeGPn6s 那麼我們的單頁應用程式親愛的在這麼短的時間內發生了什麼?它是否仍然存在,還是我們生活在多頁面應用程式和僅伺服器渲染 HTML 的時代? ------------------ ## 回顧 2023 年 去年,我寫了一篇非常類似的文章,探討了新的一年 JavaScript 框架的趨勢,我認為這是一個很好的起點。 https://dev.to/this-is-learning/javascript-frameworks-heading-into-2023-nln 該文章中確定的三大技術趨勢成為去年討論的重要組成部分。 ### 訊號無所不在 從 2022 年底開始,Preact 和 Qwik 緊跟著 SolidJS 和 Vue 的腳步,採用這些 Reactive 原語,這種勢頭只會持續到 2023 年。 二月份,Angular 團隊宣布採用。這一訊息震驚了社群媒體。不僅。這是 Angular 的存在發生非常顯著變化的幾個因素之一。有人甚至稱之為「角度復興」。這是過去幾年我們第一次看到 React 團隊加入這場爭論,因為真正被問到的問題是「訊號什麼時候出現在 React 中?」。 我在下面的文章中寫了這個問題的更長的答案(以及在評論中與丹·阿布拉莫夫的討論)。 https://dev.to/this-is-learning/react-vs-signals-10-years-later-3k71 但簡短的回答是,訊號(至少作為 API)並不是他們感興趣的東西,而他們備受期待的「忘記」編譯器將扮演類似的角色。 但訊號傳播並沒有就此結束。 Lit 是 Google 的 Web 元件框架,推出了[Lit 3,具有第一方訊號支援](https://lit.dev/blog/2023-10-10-lit-3.0/#preact-signals-integration)。 Rich Harris 公佈了 Svelte 的未來,[他們新的基於訊號的「Runes」](https://svelte.dev/blog/runes),將成為即將推出的 Svelte 5 中反應性的主要來源。 2023 年結束訊號是大多數前端 JavaScript 框架的主要部分。 ### 混合路由 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdtlafe81eo4jchqx37w.png) 去年,基於伺服器的路由得到了加強並發揮了新的作用。從 2022 年底開始,到今年,我們看到人們已經習慣了這種範式轉變,例如 React Server Components 和 Astro 的 View Transition API 整合。 前提是初始頁面載入後的伺服器渲染不應阻止客戶端導航,且客戶端導航不應意味著我們需要發送所有 JavaScript 來渲染可以靜態伺服器渲染的頁面部分。 值得注意的是,並非所有解決方案都是等效的,而且這個領域仍在建設中。我們正在進入一個新的空間,它不完全是單頁應用程式,也不完全是傳統的多頁面網站。需要進行新的權衡和新的理解。我們還沒有完成對陷阱的探索。 ### 邊緣網路:最後的前沿 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bss8a8hwf3qbozvvq9a6.jpg) 邊緣功能似乎是那些明顯的勝利之一。將伺服器移至更靠近最終用戶的位置,可以大幅減少延遲。使用更輕的執行時間可以大幅減少冷啟動時間。我們終於可以提供我們一直夢想的網路體驗。以靜態的速度實現動態。 好吧,如果有什麼不同的話,2023 年是成長的陣痛和邊緣的一年。我們開始非常熱情。畢竟,Cloudflare 發布了邊緣資料庫,我們最喜歡的所有提供者都開始提供邊緣功能,而我們最喜歡的框架正在加入開箱即用的支援。提供者成立了一個 WinterCG 委員會來討論平台標準化問題。未來就在這裡。 我們最終認識到,即使在這些邊緣功能中,某些 Node API 也是必不可少的。您可以感謝或討厭 Next 和 Vercel 將“AsyncLocalStorage”推送到每個執行時,但我們需要它。 我們也意識到邊緣資料庫永遠無法滿足所有應用程式。即使使用串流媒體,伺服器瀑布也是真實且有影響力的。是的,即使使用 React Server 元件也是如此。 但這確實實現了我去年提出的目標,透過分散式部署進行整體創作。我們看到伺服器函數(`server$`、`use server`),甚至像 Worker Functions 這樣的變體在今年年初出現,表明我們可以分發我們部署 API 的方式,並被 Solid、Qwik 和 Next 採用。 到年底 [Next 14 發布了新的實驗性部分預渲染](https://nextjs.org/blog/next-14),它允許單一請求從邊緣提供靜態內容,同時代理到伺服器-less 靠近資料庫的函數全部被串流傳輸,以提供類似Edge 的體驗,而無需在那裡部署整個應用程式。看到一些獨創性提供了兩全其美的解決方案真是太棒了。 ---------------- ## 展望 2024 年 ### 訊號年 我知道我已經在一篇文章中充分討論了信號,但真正的回報還沒有發生。我們在 JavaScript 中使用細粒度的類似 Signal 的原語已有 15 年了,那麼為什麼現在呢? 這不僅僅是關於擁有它們,而是關於你如何使用它們。 Vue 多年來一直在隱藏這些原語,React 和 MobX 也是如此,但這幾乎沒有觸及事情的發展方向。那就是細粒度渲染。 SolidJS 所普及的內容,現在以 Vue Vapor 的形式進入 Vue,以及 Svelte 5 中的 Svelte。這些只是已經宣布的內容。 我希望其他採用訊號的人能夠更自然地將它們融入框架中,以便更好地從中受益。 這個領域的潛力令人興奮,致力於將 Signals 引入瀏覽器的 TC-39 提案的小組包括來自每個主要 JavaScript 框架的代表,而這個小組並不總是與標準密切相關。 ### 基礎設施主導的發展 既然伺服器端渲染框架已經打了一針強心劑,那麼下一個合乎邏輯的地方就是繼續考慮最大限度地利用這項新功能為我們提供的功能。標準的製定很慢,WinterCG 也需要一些時間,但這不會阻止這裡的發展。 為了實現差異化,我預期框架和基礎設施供應商都會面臨壓力,要求他們提供只能在特定平台上運作的獨特功能。雖然 2023 年各個提供者都在推動平等,以提供超出其基本靜態和功能託管的類似功能(例如鍵值存儲 Blob),但我只看到這裡提供獨特價值的競爭正在升溫。 框架在這方面的作用是保持一致的創作體驗和思考模型,同時找到利用呈現給我們的新能力的方法。這與 2000 年代末的瀏覽器戰爭沒有什麼不同,而且未來還會有很多事情發生。 ### 人工智慧 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sma4crnqjxbx89hhh7r3.jpg) 去年從框架的角度談論人工智慧還為時過早。明年也可能如此。但它就在眼前。程式碼遷移和生成工具都是很棒的想法,但它們遇到了我們多年來使用視覺化無程式碼或低程式碼編輯器所遇到的相同問題。人機界麵點仍然至關重要。畢竟,程式碼是有生命的東西。它會隨著時間的推移而增長和維持。 在過去的一年裡,與其他框架作者交談時,我們發現它吸引了我們周圍的人,但還沒有達到明確我們在其中的角色的程度。但這種情況正在改變。 是的,人工智慧正在回答一個永恆的問題:為什麼你的應用程式速度很慢。 對開發人員工具的影響是一回事。但我們也看到我們的框架中內建即時性的潛力越來越大。我也不僅僅指用於持久後端的 Websockets。元框架中的 API 已經從簡單的 JSON 發展到使用 SolidStart、Qwik 和 Next 中的「伺服器功能」完全流式跨網路 JavaScript 執行。不難想像生成技術即時建立使用者介面。 -------------------------- ## 結論 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pf0pc8fhlor9xnou9r8b.jpg) 2024 年可能會繼續我們過去幾年看到的成熟趨勢。從 2020-22 年,我們看到了許多新的 JavaScript(和 WASM)框架(Qwik、Million.js、Astro、Next 13、Remix、Hydrogen、SvelteKit、SolidStart、Leptos、Dioxus、HTMX),但這還不是去年的案例。我們已經找到了方法,現在我們需要充分發揮它們的潛力。 我不確定我們是否已經成功地解決了複雜性,這對像 Astro 或 HTMX 這樣的簡化解決方案給予了大力支持。但我仍然充滿希望。 期望每個人都就「單頁應用程式」到底是什麼或何時應該使用擺在我們面前的各種選項達成一致可能有點太過分了,但這些解決方案每天都在變得更有能力實現他們設定的目標出去做。 我們所知道的網頁開發是否會改變已經不再是一個問題。即使方向還不完全明確,革命已經來臨。期望在那裡見到你。 --- 原文出處:https://dev.to/this-is-learning/javascript-frameworks-heading-into-2024-i3l

iosbase的register_callback突然跳過一行

問題描述: 在testfn函數中,switch imbue的部分會被filestr.imbue(std::cout.getloc());觸發, 接下來理論上會cout, 接著LOG(我自己寫的輸出封裝函數), 但是cout後就離開switch, 觸發流刪除事件了,LOG沒有觸發。 如果先LOG再cout則沒問題, LOG和cout都會被輸出到console。 像這樣,提供出stream.imbue_event非常多的信息。 ``` LOG [enum std::ios_base::event] stream.imbue_event = 1At testfn ,line 00219 imbue_event erase_event ``` 出事代碼 C++ ``` #include <iostream> //std::ios, std::cout, std::cerr, std::clog, std::left #include <iomanip> #include <fstream> // ofstream #include <locale> // std::locale #include <typeinfo> #include <chrono> #include <thread> #include <ctime> #include <sstream> template <typename T> void Log(const char* varName, T var, int line, const char* functionName) { std::stringstream ss; ss << "[" << typeid(var).name() << "] " << varName << " = " << var; std::ios_base::fmtflags originalFlags = std::cout.flags();/*FORMAT FLAG*/\ /*auto now = std::chrono::system_clock::now();*//*TIME*/\ /*std::time_t timestamp = std::chrono::system_clock::to_time_t(now);*//*TIME*/\ /* std::cout << "\nTime taken at Total : " << duration.count() / 1000.0 << " millisecond" << std::endl;*//*TIME*/ std::cout.width(0); std::cout << std::setfill(' ') << std::left << "LOG "\ << std::setw(50) << ss.str()/*TYPE*//*VARIABLE*//*VALUE*/\ << "At " << std::setw(15) << functionName /*FUNCTION*/\ << std::dec << ",line " << std::setw(5) << std::setfill('0') << std::right << line /*LINE*/\ /*<< "File: " << __FILE__ */ /*FILE*/\ /*<< ", Thread ID: " << std::this_thread::get_id() << ", "*//*THREAD*/\ << std::endl; \ std::cout.flags(originalFlags); } //register_callback, imbue_event, erase_event void testfn(std::ios::event ev, std::ios_base& stream, int index) { switch (ev) { case stream.copyfmt_event: std::cout << "copyfmt_event\n"; break; case stream.imbue_event: std::cout << "imbue_event\n"; break; Log("stream.imbue_event", stream.imbue_event, 219, __FUNCTION__); case stream.erase_event: std::cout << "erase_event\n"; break; } } void funcPart6() { /*register_callback*/std::cout << "//---//\n"; std::ofstream filestr; filestr.register_callback(testfn, 0);/*imbue_event*//*erase_event*/ filestr.imbue(std::cout.getloc()); /* * 使用register_callback來設定事件 如 copyfmt_event imbue_event erase_event * filestr.register_callback(testfn, 0); * /* * 筆記: * 試圖複製或複製但是構造了一個 std::basic_ofstream 對象,該類的複製構造函數是被刪除的(deleted)。 * 這是因為 std::basic_ofstream 對象通常代表一個文件流,而文件流的複製構造函數不是允許的, * 因為一個檔案流在複製時可能會引起一些不可預測的行為。在這種情況下,應該避免直接複製 std::basic_ofstream 物件。 */ } ```

在沒有伺服器的情況下在視窗之間共享狀態

最近,社群網路上流行一張 gif 動圖,展示了一件 [Bjorn Staal 製作的令人驚嘆的藝術品](https://twitter.com/_nonfigurativ_/status/1727322594570027343)。 ![Bjorn Staal 藝術作品](https://cdn-images-1.medium.com/max/2000/1*vCKb_XLed3eD9y4h-yjdKQ.gif) 我想重新建立它,但缺乏球體、粒子和物理的 3D 技能,我的目標是了解如何讓一個視窗對另一個視窗的位置做出反應。 本質上,在多個視窗之間共享狀態,我發現這是 Bjorn 專案中最酷的方面之一! 由於無法找到有關該主題的好文章或教程,我決定與您分享我的發現。 > 讓我們嘗試根據 Bjorn 的工作建立一個簡化的概念驗證 (POC)! ![我們將嘗試創造什麼(ofc 它比 Bjorn 的作品沒那麼性感)](https://cdn-images-1.medium.com/max/2000/1*KJHO9DmEDcTISWuCcvDpMQ.gif) 我做的第一件事就是列出我所知道的在多個客戶端之間共享資訊的所有方法: ## 呃:伺服器 顯然,擁有伺服器(帶有輪詢或 Websocket)可以簡化問題。然而,由於 Bjorn 在沒有使用伺服器的情況下實現了他的結果,所以這是不可能的。 ## 本機存儲 本地存儲本質上是瀏覽器鍵值存儲,通常用於在瀏覽器會話之間保存資訊。雖然通常用於儲存身份驗證令牌或重定向 URL,但它可以儲存任何可序列化的內容。 [您可以在這裡了解更多](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)。 我最近發現了一些有趣的本地儲存 API,包括 *`storage`* 事件,每當同一網站的另一個會話更改本地儲存時就會觸發該事件。 ![儲存事件如何運作(當然是簡化的)](https://cdn-images-1.medium.com/max/4048/1*otw7fDvd-XFjj9yVBxn5zg.png) 我們可以透過將每個視窗的狀態儲存在本地儲存中來利用這一點。每當一個視窗改變其狀態時,其他視窗將透過儲存事件進行更新。 這是我最初的想法,這似乎是Bjorn 選擇的解決方案,因為他分享了他的LocalStorage 管理器程式碼以及與ThreeJs 一起使用的範例[此處](https://github.com/bgstaal/multipleWindow3dScene) 。 但是當我發現有程式碼可以解決這個問題時,我想看看是否有其他方法…劇透警告:是的,有! ## 共享工作者 這個華而不實的術語背後是一個令人著迷的概念——WebWorkers 的概念。 簡單來說,工作執行緒本質上是在另一個執行緒上執行的第二個腳本。雖然它們無法存取 DOM(因為它們存在於 HTML 文件之外),但它們仍然可以與您的主腳本進行通訊。 它們主要用於透過處理背景作業來卸載主腳本,例如預取資訊或處理不太關鍵的任務(例如流日誌和輪詢)。 ![腳本與worker之間通訊機制的簡單解釋](https://cdn-images-1.medium.com/max/3548/1*izcnWc_p13m8pZy5d49mVw.png) 共享工作線程是一種特殊類型的 WebWorkers,它可以與同一腳本的多個實例進行通信,這使得它們對我們的用例很有趣!好吧,讓我們直接進入程式碼! ![共享工作人員可以將資訊傳送到同一腳本的多個會話](https://cdn-images-1.medium.com/max/5428/1*A7ObCM2OjojgfFP57ankyw.png) ### 設定工人 如前所述,工作人員是具有自己的入口點的「第二腳本」。根據您的設定(TypeScript、捆綁程式、開發伺服器),您可能需要調整 tsconfig、新增指令或使用特定的匯入語法。 我無法涵蓋所有使用 Web Worker 的可能方法,但您可以在 MDN 或網路上找到資訊。 如果需要,我很樂意為本文撰寫前傳,詳細介紹設定它們的所有方法! 就我而言,我使用的是 Vite 和 TypeScript,因此我需要一個「worker.ts」檔案並將「@types/sharedworker」安裝為開發依賴項。我們可以使用以下語法在主腳本中建立連結: ``` new SharedWorker(new URL("worker.ts", import.meta.url)); ``` 基本上,我們需要: * 辨識每個視窗 * 追蹤所有視窗狀態 * 一旦視窗改變狀態,提醒其他視窗重繪 我們的狀態將非常簡單: ``` type WindowState = { screenX: number; // window.screenX screenY: number; // window.screenY width: number; // window.innerWidth height: number; // window.innerHeight }; ``` 當然,最重要的訊息是“window.screenX”和“window.screenY”,因為它們告訴我們視窗相對於顯示器左上角的位置。 我們將有兩種類型的訊息: * 每個窗口,無論何時改變其狀態,都會發布一個帶有新狀態的“windowStateChangedmessage”。 * 工作人員將向所有其他視窗發送更新,以提醒他們其中一個視窗已更改。工作人員將發送包含所有視窗狀態的「syncmessage」。 我們可以從一個看起來有點像這樣的普通工人開始: ``` // worker.ts let windows: { windowState: WindowState; id: number; port: MessagePort }[] = []; onconnect = ({ ports }) => { const port = ports[0]; port.onmessage = function (event: MessageEvent<WorkerMessage>) { console.log("We'll do something"); }; }; ``` 我們與 SharedWorker 的基本連結如下所示。我有一些基本函數可以產生 id,並計算當前視窗狀態,我還對我們可以使用的稱為 WorkerMessage 的訊息類型進行了一些輸入: ``` // main.ts import { WorkerMessage } from "./types"; import { generateId, getCurrentWindowState, } from "./windowState"; const sharedWorker = new SharedWorker(new URL("worker.ts", import.meta.url)); let currentWindow = getCurrentWindowState(); let id = generateId(); ``` 一旦我們啟動應用程式,我們應該提醒工作人員有一個新窗口,因此我們立即發送一條訊息: ``` // main.ts sharedWorker.port.postMessage({ action: "windowStateChanged", payload: { id, newWindow: currentWindow, }, } satisfies WorkerMessage); ``` 我們可以在工作端監聽此訊息並相應地更改 onmessage。基本上,一旦工作人員收到 windowStateChanged 訊息,要么它是一個新窗口,我們將其附加到狀態,要么它是一個已更改的舊窗口。然後我們應該提醒大家狀態已經改變: ``` // worker.ts port.onmessage = function (event: MessageEvent<WorkerMessage>) { const msg = event.data; switch (msg.action) { case "windowStateChanged": { const { id, newWindow } = msg.payload; const oldWindowIndex = windows.findIndex((w) => w.id === id); if (oldWindowIndex !== -1) { // old one changed windows[oldWindowIndex].windowState = newWindow; } else { // new window windows.push({ id, windowState: newWindow, port }); } windows.forEach((w) => // send sync here ); break; } } }; ``` 為了發送同步,我實際上需要一些技巧,因為“port”屬性無法序列化,所以我將其字串化並解析回來。因為我很懶,所以我不只是將視窗映射到更可序列化的陣列: ``` w.port.postMessage({ action: "sync", payload: { allWindows: JSON.parse(JSON.stringify(windows)) }, } satisfies WorkerMessage); ``` 現在是時候畫東西了! ## 有趣的部分:繪畫! 當然,我們不會做複雜的 3D 球體:我們只會在每個視窗的中心畫一個圓,並在球體之間畫一條線! 我將使用 HTML Canvas 的基本 2D 上下文進行繪製,但您可以使用任何您想要的內容。畫一個圓,非常簡單: ``` const drawCenterCircle = (ctx: CanvasRenderingContext2D, center: Coordinates) => { const { x, y } = center; ctx.strokeStyle = "#eeeeee"; ctx.lineWidth = 10; ctx.beginPath(); ctx.arc(x, y, 100, 0, Math.PI * 2, false); ctx.stroke(); ctx.closePath(); }; ``` 為了繪製線條,我們需要做一些數學運算(我保證,這不是很多🤓),並將另一個視窗中心的相對位置轉換為目前視窗上的座標。 基本上,我們正在改變基地。我用一點數學來做到這一點。首先,我們將更改底座以在顯示器上具有座標,並透過目前視窗 screenX/screenY 進行偏移 ![基本上我們正在尋找鹼基變化後的目標位置](https://cdn-images-1.medium.com/max/5056/1*Zg_z1aZxUE1WP-uOk1owdw.png) ``` const baseChange = ({ currentWindowOffset, targetWindowOffset, targetPosition, }: { currentWindowOffset: Coordinates; targetWindowOffset: Coordinates; targetPosition: Coordinates; }) => { const monitorCoordinate = { x: targetPosition.x + targetWindowOffset.x, y: targetPosition.y + targetWindowOffset.y, }; const currentWindowCoordinate = { x: monitorCoordinate.x - currentWindowOffset.x, y: monitorCoordinate.y - currentWindowOffset.y, }; return currentWindowCoordinate; }; ``` 如您所知,現在我們在同一相對座標系上有兩個點,我們現在可以畫線了! ``` const drawConnectingLine = ({ ctx, hostWindow, targetWindow, }: { ctx: CanvasRenderingContext2D; hostWindow: WindowState; targetWindow: WindowState; }) => { ctx.strokeStyle = "#ff0000"; ctx.lineCap = "round"; const currentWindowOffset: Coordinates = { x: hostWindow.screenX, y: hostWindow.screenY, }; const targetWindowOffset: Coordinates = { x: targetWindow.screenX, y: targetWindow.screenY, }; const origin = getWindowCenter(hostWindow); const target = getWindowCenter(targetWindow); const targetWithBaseChange = baseChange({ currentWindowOffset, targetWindowOffset, targetPosition: target, }); ctx.strokeStyle = "#ff0000"; ctx.lineCap = "round"; ctx.beginPath(); ctx.moveTo(origin.x, origin.y); ctx.lineTo(targetWithBaseChange.x, targetWithBaseChange.y); ctx.stroke(); ctx.closePath(); }; ``` 現在,我們只需要對狀態變化做出反應。 ``` // main.ts sharedWorker.port.onmessage = (event: MessageEvent<WorkerMessage>) => { const msg = event.data; switch (msg.action) { case "sync": { const windows = msg.payload.allWindows; ctx.reset(); drawMainCircle(ctx, center); windows .forEach(({ windowState: targetWindow }) => { drawConnectingLine({ ctx, hostWindow: currentWindow, targetWindow, }); }); } } }; ``` 最後一步,我們只需要定期檢查視窗是否發生變化,如果發生變化則發送訊息 ``` setInterval(() => { const newWindow = getCurrentWindowState(); if ( didWindowChange({ newWindow, oldWindow: currentWindow, }) ) { sharedWorker.port.postMessage({ action: "windowStateChanged", payload: { id, newWindow, }, } satisfies WorkerMessage); currentWindow = newWindow; } }, 100); ``` [您可以在此儲存庫中找到完整的程式碼](https://github.com/achrafl0/multi-window-article)。實際上,我用它做了很多實驗,使它變得更加抽象,但其要點是相同的。 如果您在多個視窗上執行它,希望您能得到與此相同的結果! ![完整結果](https://cdn-images-1.medium.com/max/2000/1*KJHO9DmEDcTISWuCcvDpMQ.gif) 謝謝閱讀 ! 如果您發現這篇文章有幫助、有趣或只是有趣,您可以將其分享給您的朋友/同事/社區 [您也可以訂閱我的電子報](https://notachraf.substack.com/)它是免費的! --- 原文出處:https://dev.to/notachraf/sharing-a-state-between-windows-without-a-serve-23an

幫助我成為技術主管的書籍

## 為什麼是書籍? 在發展我的技能時,我喜歡結合使用會議演講、視訊教學、書籍、論文、部落格文章、邊做邊學和教學/部落格。書籍是從別人所犯的錯誤中學習、從他們的成功中受到啟發以及間接體驗他們的成就的好方法。 在這篇文章中,我想分享我最喜歡的書籍,這些書籍在我從高級軟體工程師到成為技術主管的過程中對我幫助最大。他們幫助我拓寬並加深了對軟體工程、軟體架構以及建構和經營軟體業務的理解。他們教我挑戰和塑造我的行為和習慣。其中一些深深影響了我的個人和職業生活。 不用說,閱讀這些書不會自動讓你升職或讓你擔任新的技術主管職位。當然,你還是需要自己的經驗,自己的錯誤,還需要一點運氣。根據您所從事的特定領域不斷提高您的技術知識和技能也很重要。此清單中的書籍並不關注特定技術,而是適用於任何技術堆疊和業務的一般原則和概念。 對於清單中的每本書,我都會附上一個簡短的摘要,可以幫助您判斷這本書是否與您相關。為了賦予它個人風格,我還將包括我從這本書中學到的最有價值的教訓。這不一定是這本書的主要訊息,也不是唯一重要的訊息,而是最能引起我共鳴的訊息。 ## 列表 ### 設計它! [*Design It!: From Programmer to Software Architect*]((https://www.oreilly.com/library/view/design-it/9781680502923/)) Michael Keeling 是一本針對有志向的軟體開發人員的綜合指南轉變為軟體架構師的角色。本書提供了一種實用且易於理解的軟體架構方法,強調了設計在建立有效的軟體系統中的重要性。 Keeling 涵蓋了廣泛的主題,從軟體架構的基本原理到設計可擴展和可維護系統的實用技術。 在整本書中,基林提倡採用實踐、迭代的軟體設計方法,鼓勵讀者批判性地思考他們所做的架構選擇。他介紹了各種架構風格和模式,並討論如何評估權衡並做出符合專案目標和限制的決策。本書充滿了現實世界的範例、練習和實用技巧,對於那些希望發展軟體架構和設計技能的人來說是一個寶貴的資源。 **我從書中學到的最有價值的教訓:** 不存在「沒有設計」這樣的事情。 「無設計」通常意味著在工程師的腦海中存在多種、隱含的設計,這些設計彼此不一致。明確、協作、迭代地設計,並以書面記錄設計! ### 釋放它! Michael Nygard 的[*Release It!: Design and Deploy Production-Ready Software*](https://www.oreilly.com/library/view/release-it/9781680500264/) 是軟體開發人員和架構師的重要指南討論建立在生產環境中可靠運作的軟體所面臨的挑戰。本書深入探討了設計、部署和維護能夠承受現實世界操作嚴苛的軟體的複雜性。 Nygard 強調從設計過程一開始就考慮生產現實的重要性,並提倡從僅僅編寫程式碼到提供彈性、可擴展和可維護的系統的思維方式轉變。 Nygard 提供了對軟體系統在生產中遇到的各種陷阱的見解,例如網路問題、不可預測的負載模式和硬體故障。他介紹了穩定性模式和反模式等概念,說明如何建立能夠優雅地處理故障並在壓力下保持穩健的系統。這本書充滿了現實生活中的故事和案例研究,展示了生產環境中不良系統設計所造成的災難性後果。 “放開它!”對於軟體專業人士來說,這是一個寶貴的資源,他們希望確保他們的系統不僅能正常執行,而且在面對現實世界的挑戰時具有彈性和可靠性。 **我從書中學到的最有價值的教訓:** 每個軟體工程師都應該在建立他們的軟體時考慮到生產。生產中的軟體負責營運您的業務、影響您的客戶並決定成功或失敗。 ### 站點可靠度工程 [*站點可靠性工程:Google 如何執行生產系統*](https://www.oreilly.com/library/view/site-reliability-engineering/9781491929117/) 作者:Betsy Beyer、Chris Jones、Jennifer Petoff 和 Niall理查德·墨菲(Richard Murphy) 對Google 用於管理其大規模、高度可靠系統的實踐和原則進行了富有洞察力的探索。本書介紹了站點可靠性工程 (SRE) 的概念,這是一門將軟體工程與 IT 營運相結合的學科,重點是建立可擴展且可靠的軟體系統。 作者都是 Google 的 SRE 領域經驗豐富的從業者,他們分享瞭如何建置、部署、監控和維護強大且有彈性的系統的專業知識。他們深入研究了 Google 使用的具體策略和技術,例如設定服務等級目標 (SLO)、有效管理變更以及平衡發布速度與服務可靠性的需求。這本書涵蓋了一系列主題,從 SRE 團隊的組織方面到事件管理和事後分析文化等技術實踐。這本書提供了對世界上最熟練的工程組織之一的內部運作的罕見了解,對於參與大型系統的操作、維護和擴展的任何人來說都是寶貴的資源。 **我從書中學到的最有價值的教訓:** 不存在完美的系統。透過明確定義和衡量 SLO 和錯誤預算,您可以就可靠性和速度之間的權衡做出明智的決策。 ### 改變你的問題,改變你的生活 [*改變你的問題,改變你的生活:領導力、指導和生活的 12 種強大工具*](https://www.goodreads.com/en/book/show/6665149),作者 Marilee Adams 探討了我們提出的問題可能會對我們的生活和職業生涯產生影響。亞當斯引入了「問題思維」的概念,這是一種透過深思熟慮和用心提問來轉變思維、行動和結果的方法。這本書強調了我們問自己的問題類型,從限制性的、判斷性的「判斷者」問題到更開放的、建設性的「學習者」問題,如何能顯著影響我們的觀點和結果。 亞當斯透過引人入勝的敘述闡述了她的想法,講述了一個人與生活挑戰作鬥爭並學習應用問題思維原則的故事。這種方法為個人提供了實用的工具和技術,以提高他們的溝通、決策和解決問題的能力。透過培養學習者心態並提出更好、更有說服力的問題,讀者可以被引導建立更積極、更有生產力的個人和專業關係。這本書對於領導者、教練以及任何希望增強與他人聯繫並更有效地駕馭複雜情況的能力的人來說特別有價值。 **我從書中學到的最有價值的教訓:**我意識到我經常處於「評判者」心態中。更加留意這一點,並有意識地選擇轉變為「學習者」心態,對我來說幾乎就像一種超能力,可以解決我面臨的任何挑戰。 ### 思考,快與慢 Daniel Kahneman 的 [*思考,快與慢*](https://www.amazon.de/-/en/Designing-Data-Intective-Applications-Reliable-Maintainable/dp/1449373321) 是對心理學與經濟學,深入研究我們如何思考和做出決策。卡尼曼介紹了兩種主導我們心理過程的不同思維模式:「系統1」(快速、直覺和情緒)和「系統2」(較慢、更深思熟慮和更邏輯)。卡尼曼在整本書中探討了這兩個系統對我們的判斷、決策以及我們感知周圍世界的方式的影響。 這本書全面探討了影響我們日常思維的各種認知偏見和啟發法。卡尼曼展示了我們的直覺系統 1(通常對我們很有幫助)也可能導致嚴重的錯誤和偏見。他也探討了系統 2 的功能和局限性,強調系統 1 的快速判斷如何影響和推翻它。這本書綜合了數十年的研究,提供了對人類思想和行為的複雜性的深入見解。對於任何有興趣了解我們在個人和職業環境中的選擇和行為背後的心理過程的人來說,這是一本必讀的書。 **我從書中學到的最有價值的教訓:**我了解到這兩種模式都很有價值,但也有其缺點。我學會了更了解影響我思考的偏見和啟發法,並有意識地選擇何時依賴系統 1,何時使用系統 2。 ### 原子習慣 James Clear 的[*原子習慣:一種簡單且行之有效的建立好習慣和改掉壞習慣的方法*](https://jamesclear.com/atomic-habits) 是一本變革性的指南,深入研究了習慣的科學以及習慣的小習慣改變可以帶來顯著的結果。作者提出了一個理解習慣如何形成的全面框架,並提供了培養好習慣和改掉壞習慣的實用策略。這本書的核心理念是,隨著時間的推移,微小的改進或「原子習慣」可以累積成重大的、改變生活的結果。 克利爾強調系統比目標更重要,他認為專注於實現目標的流程和系統比專注於目標本身更有效。他介紹了行為改變四定律──一套簡單、可操作的原則來引導習慣的形成。其中包括使線索明顯、渴望有吸引力、反應簡單以及獎勵令人滿意。透過結合科學研究、個人故事和現實世界的例子,克利爾闡述如何將這些原則應用於生活的各個方面,從健身和財務管理到生產力和個人成長。 《原子習慣》為培養持久的習慣提供了一個易於理解且引人注目的藍圖,對於任何想要在生活中做出積極、持久改變的人來說都是有價值的。 **我從這本書中學到的最有價值的教訓:** 透過對我的日常生活進行許多小改變,這些改變單獨地只會對我的生產力產生很小的影響,所有這些習慣結合起來會產生巨大的影響。 ### 有意識的商業 Fred Kofman 的 [*Conscious Business: How to Build Value Through Values*](https://www.amazon.de/-/en/Fred-Kofman/dp/1622032020) 是一本發人深省的書,探討了個人誠信和職業成功。作者提出了這樣的觀點:建立成功且可持續發展的企業的關鍵在於有意識的管理實踐,其中個人價值觀和道德原則處於決策過程的最前沿。該書認為,商業上的成功不僅在於經濟收益,還在於實現個人和職業成就。 科夫曼討論了有意識的商業的各個方面,包括問責制、責任、情緒智商、溝通技巧以及建設性解決衝突的能力。他強調領導者能夠激發信任、培養開放和誠實的文化並以同理心領導的重要性。透過現實世界的例子、實用的建議和練習,科夫曼指導讀者如何發展這些技能並將其應用到他們的職業生活中。 **我從書中學到的最有價值的教訓:**無條件回應能力的概念。我現在不斷提醒自己,無論情況如何,我都有權力和責任選擇對任何情況的反應。 「響應能力」是「響應」和「能力」的雙關語,強調自覺、主動回應的能力。 ### 首先,打破所有規則 [*首先,打破所有規則:世界上最偉大的管理者的不同做法*](https://store.gallup.com/p/en-us/10286/first-break-all-the-rules) 作者:Marcus Buckingham柯特·科夫曼(Curt Coffman)根據蓋洛普組織的研究提出了一種激進的管理方法。本書挑戰了有關領導力和管理的傳統智慧,提出最有效的管理者往往會違反標準做法。 本書的核心訊息是,偉大的管理者不會遵循單一模式或嚴格遵守傳統的管理原則。相反,他們透過專注於員工的個人優勢而不是試圖糾正他們的弱點來打破規則。作者認為,這種方法可以提高敬業度、生產力和整體工作滿意度。 白金漢和科夫曼確定了使世界上最好的管理者脫穎而出的關鍵見解和策略。其中包括選擇人才而不是簡單地填補職位的重要性,定義正確的結果而不是規定正確的步驟,關注優勢而不是沉迷於劣勢,以及為員工找到合適的人選而不是簡單地將他們晉升到下一個梯級。梯子。 **我從書中學到的最有價值的教訓:** 專注於優勢而不是劣勢的重要性。我學會了接受自己的弱點,並使用工具和策略來彌補它們,而不是試圖「修復」它們。相反,我投入時間和精力來發展自己的優勢,並嘗試為我所領導的人做同樣的事情。 ## 榮譽獎 在我從高級軟體工程師到技術主管的旅程中,我發現還有很多有價值的書籍。它們更專注於特定技術,這就是為什麼我沒有將它們包含在主列表中。儘管如此,我想在這裡提及它們,因為它們可能與您相關,具體取決於您所從事的領域/行業。 - [*資料庫內部架構*](https://www.databass.dev/),作者:Alex Petrov。我讀過的「最好的」資料庫書籍。它以一種非常容易理解的方式涵蓋了資料庫的所有基礎知識。對於任何使用資料庫的人來說,這是一本必讀的書。 - [*設計資料密集型應用程式*](https://www.amazon.de/-/en/Designing-Data-Intential-Applications-Reliable-Maintainable/dp/1449373321) 作者:Martin Kleppmann。建立資料密集型應用程式的綜合指南。它涵蓋了廣泛的主題,從資料庫和資料處理到分散式系統和串流處理。 - [*Oracle JRockit:權威指南*](https://www.packtpub.com/product/oracle-jrockit-the-definitive-guide/9781847198068),作者:Marcus Hirt 和 Marcus Lagergren。對於任何對 JVM 內部結構感興趣的人來說,這是一個很好的資源。 - [*Linux 程式介面*](https://man7.org/tlpi/) 作者:Michael Kerrisk。這是一本關於 Linux 的非常詳細的書,涵蓋了廣泛的主題,從基本的系統呼叫到進程組、訊號和套接字等高級主題。 ## 最後的想法 雖然書籍是個很好的學習工具,但它們並不能取代第一手經驗。你仍然需要犯自己的錯誤並從中學習。與他人討論你讀過的書,了解他們的觀點並挑戰你自己的觀點也很有幫助。也許您可以加入讀書俱樂部,或與同事或朋友一起閱讀。 我希望這份清單對您的職業生涯有所幫助。如果有一本書啟發了您並且您認為應該在此列表中,請在下面的評論中告訴我。 --- 原文出處:https://dev.to/frosnerd/books-that-helped-me-become-a-tech-lead-3831

🎄24 個開源程式庫:供您假期休息時 Coding 一下使用🎅🏽🎁

這是開源的季節☃️ 假期編碼可以是一種幸福的經歷,沒有什麼比在休息時間建立一個很棒的專案更好的了。 我瀏覽了無數的儲存庫,找到了 24 個最適合聖誕節編碼的庫。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgcb0fm044iapyf30l34.gif) 不要忘記 STAR 🌟 這些儲存庫並保存本文以供日後使用。 --- #Web-Dev🌐: ### 1. [CopilotTextarea ](https://github.com/CopilotKit/CopilotKit) - React 應用程式中的 AI 驅動寫作 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7yb6ie1oeed9d1xwixt.png) 具有 Github CopilotX 功能的任何 React `<textarea>` 的直接替代品。 自動完成、插入、編輯。 可以即時或由開發人員提前提供任何上下文。   ###2.[React Joyride](https://github.com/gilbarbara/react-joyride) - 建立產品演練   ###3.[NextAuthJS](https://github.com/nextauthjs/next-auth) - 輕鬆設定驗證   ###4.[Trigger.dev](https://github.com/triggerdotdev/trigger.dev) - 可靠地執行長時間作業而不會逾時 ---   #UI/UX🦋: ### 5. [Flowbite](https://github.com/themesberg/flowbite) - 頂級 CSS 元件庫 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98dwqyrhf1pbiqkpko8g.png) 最好、最受尊敬的 UI 元件庫之一。 基於實用優先的 CSS 框架。 易於使用,充滿重要的支援和模板。   ###6.[MaterialUI](https://github.com/mui/material-ui) - 使用 Google 的 Material Design 實現的基礎 React 元件   ###7。 [SwiperUI](https://github.com/nolimits4web/swiper) - 用於實現行動滑動 UI 的受人尊敬的庫   ###8.[ReactSpring](https://github.com/pmndrs/react-spring) - 在 React 中實現具有真實物理效果的動畫 ---   #GenAI🤖: ## 9. [CopilotPortal](https://github.com/RecursivelyAI/CopilotKit):在您的應用程式中嵌入可操作的 LLM 聊天機器人。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szzmw5l8c9m4bce23bd3.png) 應用程式中的上下文感知 LLM 聊天機器人可以回答問題並採取行動。 只需幾行程式碼即可獲得一個可用的聊天機器人,然後根據需要進行自訂和嵌入。   ###10.[llamafile](https://github.com/Mozilla-Ocho/llamafile) - 將使用 LLM 的複雜性壓縮到單一檔案   ###11。 [Pezzo.ai](https://github.com/pezzolabs/pezzo) - 開發人員最喜歡的 LLM 操作和可觀察性   ###12.[Tavily](https://github.com/assafelovic/gpt-researcher) - 開發人員友善的自治 GPT 代理,可搜尋資料並撰寫報告 ---   #安全/隱私🔐: ### 13. [Wazuh](https://github.com/wazuh/wazuh) - 統一開源安全平台 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46eta4l6zxt2a8rf61ea.jpg) 適用於端點和雲端工作負載的統一開源安全平台。 威脅偵測、預防和回應。 保護本地、容器化和雲端環境。   ###14.[Zeek](https://github.com/zeek/zeek) - 深入分析網路流量   ###15。 [SuperTokens](https://github.com/supertokens/supertokens-core) - 開源身分驗證提供者   ###16.[Sniffnet](https://github.com/GyulyVGC/sniffnet) - 本地監控您的網路流量 ---   #移動📱: ### 17. [Tamagui ](https://github.com/tamagui/tamagui) - 受人尊敬的 React Native UI 與最佳化函式庫 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3kuenic5tr8kmtzksn59.jpg) Tamagui 旨在快速設計 React 應用程式。 它包含一個可選的 UI 套件和一個用於增強效能的最佳化編譯器。 允許在 Web 和本機平台之間實現無縫程式碼共享,為每個環境最佳化樣式元件。   ###18.[EarlGrey](https://github.com/google/EarlGrey) - Google 進行的 iOS UI 測試   ###19。 [ReactNativeMaps](https://github.com/react-native-maps/react-native-maps) - 高度可自訂的應用程式地圖元件   ###20.[ReactNativePaper](https://github.com/callstack/react-native-paper) - 適用於 iOS 和 Android 的設計庫 ---   #其他🎅: ### 21. [LangChain ](https://github.com/CopilotKit/CopilotKit) - 使用 LLM 建立自訂操作鏈 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdk6rxdz8i4o28ratj7n.png) 一個著名的庫,但仍然包含在內,因為它是我最喜歡的庫之一,並且建置起來很有趣。 模組化元件可協助您將 LLM 整合到與許多應用程式和 API 整合的操作中。 用於建立 LLM 代理的強大框架。   ###22.[ReactAgent](https://github.com/eylonmiz/react-agent) - 實驗專案。將提示轉變為有效的反應元件   ###23.[Awesome for Beginners](https://github.com/MunGell/awesome-for-beginners) - Github 初學者友好專案列表   ###24.[Appwrite](https://github.com/appwrite/appwrite) - 適用於網路和行動應用程式的強大後端平台 --- 而且……就是這樣,夥計們! 希望您喜歡這些庫,並且它們可以幫助/激勵您在假期期間建立一些很酷的東西。 ##如果您喜歡本文,請不要忘記對儲存庫加 STAR🌟 並透過回饋來支持本文。 #聖誕節快樂! 🎅🏽☃️ --- [PS:本文附有我用 [Suno.ai](https://www.suno.ai) 產生的伴奏歌曲。他們很搞笑,很棒,也很令人毛骨悚然。告訴我你最喜歡哪一個: 1. [開源聖誕老人](https://app.suno.ai/song/e5d415a5-2914-4fc4-b3e5-136ea0a8ef5a/) 2.【聖誕老人的程式設計師聖誕魔法】(https://app.suno.ai/song/5794dcf0-e9cc-4e0d-a80f-f70ef4b73150/)] --- 原文出處:https://dev.to/copilotkit/24-must-try-open-source-projects-for-your-christmas-coding-3603

免費託管全端應用程式的 5 種最佳方式🚀✨

## 你好呀! ![Heroku 標誌](https://blog.4linux.com.br/wp-content/uploads/2018/01/Heroku.png) 首先,讓我給你一些背景資訊。 [直到最近](https://help.heroku.com/RSBRUH58/removal-of-heroku-free-product-plans-faq),**Heroku** 有一個很好的免費層,可以讓您部署和測試東西與他們的馬力機。使用起來很輕鬆。但隨著這一免費層的取消,開發人員不得不尋找新的平台來部署他們的專案。 幸運的是,有許多新的託管提供者不斷湧現。但**實際上選擇部署位置**可能與為專案編碼一樣具有挑戰性。 ![如此多的選項 gif](https://media.giphy.com/media/McD0cTjsFuxc7tjseu/giphy.gif) 這就是為什麼在本文中,**我將展示其中一些** **選項**,用於免費在線託管您的應用程式。我們將快速了解每個提供者最擅長的領域,以便您可以做出明智的決定,並讓您的應用程式上線。 --- ### 快速提醒 在開始部署我們的應用程式之前,請務必閱讀您選擇的框架提供的部署指南。 [React](https://create-react-app.dev/docs/deployment/)、[NextJS](https://nextjs.org/docs/pages/building-your-application/deploying)、[Wasp](https://wasp-lang.dev/docs/advanced/deployment/overview),而且大多數目前框架都有非常好的部署指南(甚至是讓這些部署更容易的平台)。 因此,您的框架選擇可能會對您的託管提供者產生很大影響! ![辦公室 GIF](https://media.giphy.com/media/BpGWitbFZflfSUYuZ9/giphy.gif) ## 支持我們! 🙏⭐️ 順便說一句,我是 Wasp 團隊的一員,如果您能檢查我們的全端 React/NodeJS/Prisma 框架並[給我們一顆星](https://kdta.io/github-黃蜂-lang-wasp_14 )。 我們正在努力幫助開發人員盡可能快速、輕鬆地從想法到部署(例如,單一命令、全端部署),感謝所有幫助! 好的。現在,讓我們探索一些在免費託管應用程式時提供絕佳選擇的雲端平台。 ### 韋爾塞爾 ![Vercel 標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4nawjjv3zd1iea1rgfjw.png) 如果您正在部署前端應用程式,那麼這裡的體驗是難以比擬的。免費套餐**真的**很好。我有大約 20 個小型網站在 Hobby 計劃上執行,但無法減少使用量。 除此之外,部署的簡單性也令人驚訝。 ![Vercel 儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/61giw9nmi9y1d933y6hk.png) 您所要做的就是選擇一個 github 儲存庫,如果他們檢測到您正在使用主要框架之一,您可能甚至不需要配置任何內容!他們會處理好這一切,您的應用程式將在幾秒鐘內執行。 ![Vercel 部署](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xidcbvp9tpbeqr57d94.png) 不幸的是,對於後端和資料庫 [Vercel](https://vercel.com/) 仍然不是一個很好的選擇。如果你有一個非常小的後端(並且專注於NodeJS),你可以嘗試使用[Vercel 的函數](https://vercel.com/docs/functions/serverless-functions) 基礎設施在這裡部署,儘管它們在以下方面受到限制:執行時間和複雜性。 對於更複雜的後端,我們將不得不看看下面的一些提供者。 ### 鐵路 ![鐵路標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnxai4q81n8u5uxlcz4h.png) [Railway](https://railway.app/) 是一個可讓您輕鬆部署 Web 應用程式和 API 的平台。當您註冊時,它提供每月**價值 5 美元的免費使用**的免費套餐。 只需幾個命令,您就可以部署應用程式並立即啟動並執行。它有一個非常漂亮的 UI,整體部署體驗也很好! 順便說一句,我真的很喜歡他們決定展示物品和容器的方式。這是一種非常聰明的方式來概覽事物,而不是數百個小應用程式。有時,[簡單地將事物分組](https://lawsofux.com/law-of-common-region/) 會對使用者體驗產生重大影響,如下所示: ![分組專案](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3f4y84fkv7sa3rxd0yrf.png) 它還支援 React、Next.js 和 Node.js 等流行框架。此外,它還提供一鍵式資料庫設定和[社區建立的模板](https://railway.app/templates),可以顯著簡化為專案設定 Dockerfile 的過程。 ![鐵路計畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t5zsr0oghlpyej2p335u.png) 以下是它的基本當前價格,每月 5 美元(他們每月給你使用)實際上足以讓你擁有一些專案(如 2 - 3 個小型網站、後端和資料庫)和如果您知道如何正確設置它們(例如,將它們設定為在不使用時自動睡眠),請執行。 ![設定頁](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1nuvnb877w0zdb1kywt.png) 他們在應用程式設定頁面中有此選項。在那裡,您還可以找到其他可以更改的有趣的配置選項,例如網域、執行狀況檢查端點等。 ### 使成為 ![渲染標誌](https://images.g2crowd.com/uploads/product/image/large_detail/large_detail_477db83f729d63210139ec7cd29c1351/render-render.png) Render 是另一個用戶友好的雲端平台,提供**良好的免費套餐**並支援廣泛的應用程式。它簡化了部署和擴展應用程式的過程,並支援多種程式語言和框架。 Render 的免費套餐包括(每月): - 500 管道建設分鐘 - 100GB 頻寬 唯一的例外是他們的 **Cron Jobs 服務(您的情況可能不需要,特別是如果您正在利用 [Wasp 的內建作業](https://wasp-lang.dev/docs/advanced) /jobs),每月最低費用為1 美元。** ![渲染計畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbqb08789v4soij9gp0s.png) ![渲染計畫 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n54c1fapvolqgzszzaaz.png) 它的功能真的很強大!我能夠部署資料庫、NestJS 應用程式和 NextJS 前端,所有這些都可以與遷移、Prisma ORM 等一起使用!它有一些很好的事件追蹤(儘管它可以呈現得更好——有時,螢幕上有太多元素)。 ![事件範例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/essf0z1u1ows6snpswf6.png) 而且它還具有一些可觀察性功能!您可能認為這些不會在非常小的應用程式上使用,但是,當您在生產環境中偵錯事物時,您擁有的每個工具都可以產生有關問題的新見解。 ![可觀測範例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m3fs623gtv5gu4hnjr3g.png) ![可觀測範例 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wasik5y01zuh5a5za8gk.png) ### 飛 ![飛標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3v8jhqg988eorpcdn7hb.png) [Fly](https://fly.io/)是專注於全球邊緣運算的雲端平台。 Fly 專注於高效能託管,並提供全球邊緣站點網路。 Fly 以其可擴展性和性能優化而聞名。 ![飛行計畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/952omdoyh68fwq4lv4ik.png) 它支援各種程式語言和框架,讓您可以建立和部署功能強大的應用程式,並且在部署過程中,您只需下載[flyctl](https://fly.io/docs/hands-on/install-flyctl/)現在您就可以出發了! ![支援的架構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/almuttwim73338hy7ech.png) 順便說一句,Wasp 框架支援使用 Fly! 的單一命令部署!您可以在[此處](https://wasp-lang.dev/docs/advanced/deployment/manually#flyio)查看有關它的更多資訊! ![黃蜂部署飛行](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohqil6hslcacgnhr2128.jpeg) 它還可以容納一些小物品,但當我們查看實際價值時,成本會變得有點陡峭: ![飛行計畫定價](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f74v7dkf1p1i23jsckz3.png) 對於服務質量,它有一些不錯的監控儀表板和 Sentry 集成,這似乎非常有用。您也可以使用 SSH 輕鬆檢查應用程式日誌! ![飛行時記錄錯誤](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bcj1fzf6xc64fzyugpu.png) ### 網路化 ![Netlify 標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zm251qd0ow6ja1yhrot.png) Netlify 以其出色的免費套餐而聞名,並提供各種功能來建立和部署網站。話雖如此,它更像是 Vercel 的直接競爭對手,因為它專注於前端和靜態內容。 與 Vercel 一樣,它並不適用於強大的後端,但它也可以選擇託管無伺服器功能,您只需將資料庫託管在其他地方即可。 它使用為每個框架量身定制的特定建置器,為主要框架提供出色的支援。他們的[部署文件](https://docs.netlify.com/configure-builds/overview/?_gl=1%2a10z7npm%2a_gcl_au%2aMTcyNzA3MDU2My4xNzAyNjUxODAx#basic-build-settings)非常全面且有幫助。 ![Netlify 方案](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xv8o94y0dltcvr0u2n4a.png) 透過 Netlify,您可以利用其內容交付網路 (CDN) 為使用者提供快速的靜態內容交付。它們提供了一系列功能來幫助您建立和優化您的網站。 Netlify 的免費方案包括: - 每月 300 分鐘建置時間 - 每月 100GB 頻寬 Netlify 因其易用性和強大的功能而受到開發人員的歡迎。它是託管靜態網站或 [Jamstack](https://jamstack.org/) 應用程式的絕佳選擇。 ![NextJS辨識](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e80nn5uz0il95xtogrr3.png) 他們還有一些主要的框架建置執行時,可以簡化您的流程! ### 結論 如果您還沒有為 [Wasp 的儲存庫](https://www.github.com/wasp-lang/wasp) 加註星標,我建議您這樣做!它可以幫助我們每週為您帶來這樣的免費內容。另外,它是最好的、沒有廢話的全端框架,可以減少開發時間並完成專案。 在免費託管您的應用程式時,重要的是要考慮每個平台的特定功能和限制。每個平台都有自己的優勢,選擇最適合您的需求和要求的平台非常重要。 以下是您的視覺回顧: ![複習圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dd023j7tcv1cu23zedqm.png) 嘿!您想查看有關所有這些平台的更深入的文章嗎?留在評論區! --- 原文出處:https://dev.to/wasp/top-5-ways-to-host-your-full-stack-app-for-free-c2j

簡化複雜 - 深入探討 Kubernetes 元件

## 介紹 幾天前,我在我曾經就讀的大學舉辦了一場關於 Kubernetes 及其元件的演講。我媽媽說她喜歡這個演講,所以我把它變成了一篇部落格文章。 許多軟體工程師傾向於忽視與 Kubernetes 相關的任何東西,儘管他們可能每天都會使用它。乍一看,它似乎很複雜,就像一個需要潛入的全新世界。是的,確實如此,但在這篇文章中,我將介紹 Kubernetes 叢集的所有主要元件,並在範例中解釋它們的作用。 在這篇文章結束時,您不會成為 Kubernetes 專家,但您可能會很好地了解要尋找什麼以及如何建立 Kubernetes 最初看起來的混亂狀態。 *代表 Kubernetes 架構的圖片取自 [Kubernetes 網站](https://kubernetes.io/docs/concepts/overview/components/)* ### **向我們展示您的支持🙏🏻** ![Github 明星](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mab4sx5zugkc89ac7h4l.gif) 在我們開始之前,如果您為我們的儲存庫加註星標並幫助我們在其他開發人員面前獲得我們的工具,我們將非常高興。我們的 GitHub 儲存庫位於:https://github.com/cyclops-ui/cyclops ⭐ ## 成分 首先,我們可以將 Kubernetes 叢集分為兩部分:**控制平面**和**工作節點**。控制平面負責整個操作並控制集群的狀態。我們很快就會了解這意味著什麼。另一方面,我們的工作節點本質上只是監聽控制平面告訴它們要做什麼的電腦。它們是我們集群的運算能力。我們在叢集中執行的任何應用程式都將在這些節點上執行。 讓我們進一步分解。 ### 控制平面 ![控制平面](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gdy560pic4ae8ilelh58.png) 正如我們所說,控制平面確保我們的叢集能如預期運作。它透過與叢集用戶通訊、調度工作負載、管理叢集狀態等來實現這一點。 控制平面由四個關鍵元件組成。它們本身很簡單,但一起建立了一個複雜的系統。這些元件是: - **API** - **ETCD** - **調度程序** - **控制器經理** 控制平面元件可以在叢集中的任何機器上執行,但通常在一組單獨的機器上執行,通常稱為**主節點**。這些機器不用於執行任何其他容器或應用程式,而是為 Kubernetes 控制平面保留。 #### API Kubernetes API 充當叢集的前端接口,允許使用者與叢集互動、定義所需狀態以及執行建立、更新和刪除資源等操作。 這是我們與集群的**唯一聯繫點**。此外,沒有其他元件直接相互通信,但所有通信都是透過 API 進行的。 #### ETCD ETCD 是 API 的**資料庫**;就這麼簡單。當您告訴 Kubernetes 建立部署時,它會與所有其他建立的資源一起儲存在 ETCD 中。 ETCD 的一個特點是它的鍵值儲存被組織為檔案系統。 ETCD 的另一個出色功能是用戶可以**訂閱**事件並獲得有關更改的通知。例如,*建立新 Pod 時讓我知道*。 #### 調度程序 顧名思義,調度程式**決定 pod 將在哪個節點上執行**。它透過一組規則來實現這一點,您可以在 [Kubernetes 文件](https://kubernetes.io/docs/home/) 中閱讀。 *這就是我說你不會成為專家時的意思,但你會知道要谷歌什麼:)* 調度程序**訂閱**保存在 ETCD 中的所有新建立的 pod,但它**只能**與 API 通訊來取得此更新。 當它發現 Pod 已建立時,它會計算在哪個工作節點上執行它。一旦決定,**調度程序不會在任何機器上執行任何東西**;它只是告訴 API 在特定節點上執行 pod。 #### 控制器管理器 控制平面的最後一個元件是控制器管理器。我們可以把它當作我們集群的恆溫器。它的工作是將集群的當前狀態轉變為所需的狀態。 這意味著它將**在幕後建立所有需要的資源**來滿足我們的需求並使我們的應用程式啟動並執行。 它執行多個控制器進程,這些進程訂閱了 ETCD 上的更改,並編譯成相同的二進位檔案以便於部署。控制器管理員的角色以及這些控制器的作用將在部落格後面進行更詳細的定義。 ### 工作節點 ![工作節點](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gz5ocd4ito4o0n7fjzct.png) 現在我們已經了解了整個叢集的管理方式,接下來讓我們深入了解容器在哪裡運作以及如何實現這一點。 Kubernetes 叢集中的每個節點上執行 3 個元件。當然,您可以在叢集中擁有多個節點,但每個節點都需要這三個元件來託管您的應用程式。 那些是: - **容器運作時** - **kubelet** - **成為代理** #### 容器執行時 允許 Kubernetes 執行容器並管理節點上容器的生命週期的元件是容器執行時。 支援多個容器執行時,例如[conatinerd](https://containerd.io/)、[cri-o](https://cri-o.io/) 或其他[CRI 相容執行時](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md)。 #### 庫貝萊特 另一個訂閱 pod 事件的元件是 Kubelet。每次在節點上調度 pod 時,該節點上執行的 Kubelet 都會聽到該訊息並啟動所有定義的容器。最重要的是,Kubelet 還執行健康檢查,以確保一切能如預期運作。 #### 成為代理 Kubernetes 中的 KubeProxy 管理叢集中 pod 之間的網路連接,處理負載平衡和網路路由等任務。它透過維護網路規則並將服務抽象轉換為可操作的網路策略來確保 Pod 之間的無縫通訊。 ## 從部署到正在執行的容器 現在我們已經列出了 Kubernetes 叢集中的所有元件及其角色,接下來讓我們講述一個有關 Kubernetes 部署如何成為在叢集中的各種電腦上執行的一組容器的故事。 ### Pod、副本集和部署 快速提醒這三者的關係:Pod、Replicaset 和 Deployment。 ![部署元件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cs9u7fnhe3q096bkyp2l.png) 我們可以在 Kubernetes 叢集中部署的最小單元是 **pod**。有了它,我們將定義我們的容器。 最有可能的是,我們需要同一應用程式的幾個實例,並且我們可以定義如何使用 **Replicaset** 複製我們的 pod。它將透過啟動和終止來確保我們有所需數量的 Pod 執行。 太棒了,現在我們已經複製了我們的應用程式,但我們想推出新版本的應用程式。我們必須拆除現有的 Pod/Replicaset 並建立新的。部署將自動執行此流程,使我們能夠安全地推出我們的功能。 ## 威望 ![聲望](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yyxboeqedu4yvg0ceg29.gif) 現在我們已經了解了所有術語並觸及了所有 Kubernetes 元件及其角色,讓我們看看當我們將 Deployment「套用」到 Kubernetes 叢集時會發生什麼。 假設我們已經建立了一個定義應用程式的「deployment.yaml」檔案(您可以在[此處](https://imgur.com/7qKp189)了解如何執行此操作)並執行「kubectl apply -f deployment. yaml” 。 `kubectl` 現在將把我們的部署定義提交到叢集的**唯一的聯絡點** - Kubernetes API。 我們的簡單 API 將把我們的部署儲存在 ETCD 資料庫中。每次將 Deployment 物件儲存到 ETCD 時,它都會讓 API 知道 Deployments 發生了更改,並且它應該讓**每個訂閱此類事件的人**知道這一點。 控制平面中有一個元件想要知道何時產生新的部署,這就是**控制器管理器**。當它聽到新的 Deployment 時,它將根據 Deployment 配置建立一個新的 Replicaset。為了建立此 Replicaset,它將透過建立請求來呼叫 API。 建立 Replicaset 與建立 Deployment 非常相似。 API 將接收一個 Replicaset 來建立並儲存到 ETCD 中。這將使 ETCD 告訴 API 有人建立了一個 Replicaset 並將該資訊傳遞給所有訂閱的元件,這又是控制器管理器。 當 Controller Manager 聽到新的 Replicaset 時,它會透過呼叫 API 來建立使用該 Replicaset 定義的所有 Pod,您猜對了,該 API 會將所有這些 Pod 儲存到 ETCD 中。 ![k8s_deployment_gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6d97k6rggdrbbwes7d9.gif) *正如我們所說,發生了很多事情,因此我們決定建立一個 GIF 來幫助您了解整個過程。* 在這裡,我們包括了 Scheduler,它訂閱了 Pod 建立事件。每次聽到新的 Pod 時,它都會決定應該在哪個節點上執行。 Scheduler 並沒有執行 Pod,只是告訴 API** 它為其選擇了哪個節點。然後 API 將保存該資訊。 另一個監聽 Pod 事件的元件是 Kubelet,它是執行在 Kubernetes 叢集中每個工作節點上的元件。每次 API 告訴 Kubelet Scheduler 決定在其節點上執行 Pod 時,Kubelet **將啟動 Pod 定義的所有容器**。 最後,我們將配置變成了在機器上執行的應用程式!這是一個漫長的過程,有很多移動部分,但這可能是我最喜歡的部分。 每個元件只承擔部署應用程式的一小部分責任,但它們一起解決了一個相當複雜的問題。 ## 最後的想法 希望本文能幫助您掌握 Kubernetes 元件,並幫助您揭開最受歡迎的編排器的神秘面紗。我們鼓勵您自行挖掘,因為我們很高興了解這一點。 我們推薦學習 Kubernetes 的一本書是 Marko Lukša 的《Kubernetes in action》。它非常受歡迎,並且很好地概述了 Kubernetes 背後發生的事情以及如何使用它。 --- 原文出處:https://dev.to/cyclops-ui/complexity-by-simplicity-a-deep-dive-into-kubernetes-components-4l59

您必須在業餘專案中使用的 11 個免費且有趣的 API

開始一個新專案就像一次冒險起航——對開發人員來說充滿了興奮和挑戰。當您集思廣益並為您的下一件大事規劃功能時,有一個遊戲規則改變者可以讓您的旅程更加順利:API。 ![](https://media1.tenor.com/m/31nachzhSKQAAAAd/did-you-say-free.gif) 為了在不減少預算的情況下為您的專案提供所需的推動力,這裡精選了一系列最佳免費 API。它們就像您值得信賴的伙伴,可以無縫地融入您的工作中,讓您的編碼之旅更加愉快和高效。 ------------------- ### 開源API測試平台 [Firecamp](https://firecamp.dev) 是開源 API 測試工具,可協助您比以往更快地測試 API。 如果您能花 5 秒給我們一顆星,我將非常感激💜 ![octacat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5kjqmny5y0c4k4gyqcxs.png) ----- 讓我們深入探討一下: 1.[JSONPlaceholder API](https://jsonplaceholder.typicode.com/) - 幫助開發人員在使用真正的程式之前測試他們的程式。它允許您使用 HTTP 請求建立、變更和刪除虛假資料。 - 可以根據您的需求使用它可以是 JSON、CSV 和 YAML ![JSON 佔位](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x660agyk72r429p8kv2p.png) -------- 2.[OpenWeatherMap API](https://openweathermap.org/api) - 全球任何地點的即時天氣資料。 - 存取目前天氣狀況、預報和歷史資料。 - 非常適合涉及天氣預報、氣候分析或旅行計劃的應用。 -------- 3.[新聞API](https://newsapi.org/) - 總結來自世界各地各種來源的新聞文章。 - 提供即時和歷史資料,包括標題、來源和文章摘要。 - 非常適合需要即時新聞更新、內容聚合或情緒分析的應用程式。 -------- 4.[Unsplash API](https://unsplash.com/developers) - 用於應用程式和網站的高品質、免版稅圖像。 - 存取大量專業照片。 - 非常適合涉及視覺內容、設計或使用者參與的專案。 ------------ 5.[REST國家API](https://restcountries.com/) - 檢索有關國家的訊息,包括人口、面積等。 - 對於涉及地理、教育或文化探索的應用程式很有用。 ![國家 API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ghsa3b5eev6xnydsgo6s.png) ------------ 6.[Randomuser.me API](https://randomuser.me/) - 產生隨機用戶資料,包括姓名、地址和個人資料圖片。 - 非常適合在不使用真實用戶資料的情況下測試和原型應用程式。 ------------ 7.[JokeAPI](https://jokeapi.dev/) - 透過大量笑話將幽默融入您的專案中。 - 非常適合娛樂應用程式或為您的網站加入輕鬆的感覺。 ------------ 8.[匯率-API](https://www.exchangerate-api.com/) - 存取各種貨幣的即時和歷史匯率。 - 對於涉及電子商務、金融或旅遊的專案至關重要。 ------------ 9.【NASA開放API】(https://api.nasa.gov/) - 從 NASA 的大量收藏中檢索資料,包括圖像、影片和天文學資料。 - 非常適合教育計畫、太空愛好者或任何對宇宙探索感興趣的人。 ------------ 10.[COVID-19資料API](https://covid19api.com/) - 隨時了解全球 COVID-19 即時統計資料。 - 對於專注於健康、資料視覺化或流行病監測的應用程式很有用。 ------------ 11.[圖書API](https://openlibrary.org/developers/api) - 開放式庫提供了一套 API 來幫助開發人員啟動並執行我們的資料。其中包括 RESTful API,它使 Open Library 資料可以採用 JSON、YAML 和 RDF/XML 格式。 ------------ 這些 API 涵蓋了廣泛的功能,可讓您為專案加入不同的功能,而不會產生額外的成本。 請務必瀏覽他們的文件,以便無縫整合到您的開發工作流程中。 您還記得您為有趣的專案嘗試的第一個 API 嗎?在下面評論並與社區分享。 下週見!! 🙏 --- 原文出處:https://dev.to/firecampdev/11-free-and-fun-apis-you-must-use-in-your-side-project-219m

部署策略簡介:藍綠部署 vs 金絲雀部署 vs 其他部署

如今,軟體開發的最大變化是部署頻率。產品團隊更早(並且更頻繁)地將版本部署到生產中。長達數月或數年的發布週期變得越來越罕見,尤其是對於建立純軟體產品的人來說。 如今,使用服務導向的架構和微服務方法,開發人員可以將程式碼庫設計為模組化。這使他們能夠同時編寫程式碼庫的不同部分並將其部署到程式碼庫的不同部分。 縮短部署週期的商業優勢是顯而易見的: * 縮短上市時間 * 客戶在更短的時間內獲得產品價值 * 客戶回饋也更快回流到產品團隊,這意味著團隊可以更快地迭代功能並解決問題 * 開發人員整體士氣上升 然而,這種轉變也為營運或 DevOps 團隊帶來了新的挑戰。隨著部署更加頻繁,部署的程式碼更有可能對網站可靠性或客戶體驗產生負面影響。這就是為什麼制定程式碼部署策略以最大限度地降低產品和客戶的風險非常重要。 在本文中,我們將討論一些不同的部署策略、最佳實踐和工具,它們將使您的團隊更快*且*更可靠地工作。 --- ## 現代應用的挑戰 現代應用程式通常是分散式且基於雲端的。它們可以彈性擴展以滿足需求,並且由於高可用的架構,對故障的恢復能力更強。他們可以利用完全託管的服務,例如[AWS Lambda](https://aws.amazon.com/lambda/) 或[Elastic Container Service (ECS)](https://aws.amazon.com/ecs/) ,其中平台承擔一些營運責任。 這些應用程式幾乎總是有頻繁的部署。例如,行動應用程式或消費者 Web 應用程式可能在一個月內經歷多次變更。有些甚至每天多次部署到生產中。 他們經常使用微服務架構,其中多個元件協同工作以提供完整的功能。不同的元件可以有不同的發布週期,但它們都必須無縫地協同工作。 活動部件數量的增加意味著出現問題的可能性更大。由於多個開發團隊對整個程式碼庫進行更改,當問題不可避免地發生時,可能很難確定問題的根本原因。 另一個挑戰:基礎設施層的抽象,現在被視為程式碼。新應用程式的部署可能還需要部署新的基礎架構程式碼。 ## 流行的部署策略 為了應對這些挑戰,應用程式和基礎架構團隊應該設計並採用適合其用例的部署策略。 我們將回顧幾種不同的部署策略並討論幾種不同部署策略的優缺點,以便您可以選擇適合您的組織的策略。 ## “大爆炸”部署 顧名思義,「大爆炸」部署會一次更新應用程式的全部或大部分。這種策略可以追溯到軟體在實體媒體上發布並由客戶安裝的時代。 大爆炸部署要求企業在發布之前進行廣泛的開發和測試,通常與大型順序發布的[「瀑布模型」](https://en.wikipedia.org/wiki/Waterfall_model)相關。 現代應用程式的優點是可以在客戶端或伺服器端定期自動更新。對於現代團隊來說,這使得大爆炸方法變得更慢、更不靈活。 大爆炸部署的特點包括: * 所有主要部分都打包在一個部署中; * 用新版本很大程度上或完全取代現有軟體版本; * 部署通常會導致較長的開發和測試週期; * 假設失敗的可能性很小,因為回滾可能是不可能或不切實際的; * 完成時間通常很長,需要多個團隊的努力; * 要求客戶端採取行動更新客戶端安裝。 大爆炸部署不適合現代應用程式,因為對於面向公眾或關鍵業務應用程式來說,風險是不可接受的,因為中斷意味著巨大的財務損失。回滾通常成本高、耗時,甚至不可能。 大爆炸方法適用於非生產系統(例如,重新建立開發環境)或供應商打包的解決方案(例如桌面應用程式)。 ## 滾動部署 滾動、分階段或分步部署比大爆炸部署更好,因為它們最大限度地減少了許多相關風險,包括無法輕鬆回滾的用戶面臨的停機時間。 在滾動部署中,應用程式的新版本逐漸取代舊版本。實際部署需要一段時間。在此期間,新舊版本將共存,不會影響功能或使用者體驗。此過程可以更輕鬆地回滾與舊元件不相容的任何新元件。 下圖顯示了部署模式:叢集中每台伺服器的舊版本顯示為藍色,新版本顯示為綠色。 ![滾動部署](https://thepracticaldev.s3.amazonaws.com/i/divuxihkun2p186c9mye.png) 應用程式套件升級是滾動部署的一個範例。如果原始應用程式部署在容器中,則升級一次可以處理一個容器。每個容器都經過修改,可以從應用程式供應商的網站下載最新的映像。如果其中一個應用程式有相容性問題,舊映像可以重新建立容器。在這種情況下,套件應用程式的新舊版本會共存,直到每個應用程式都升級為止。 ## 藍綠、紅黑或 A/B 部署 這是另一個自動防故障過程。在這種方法中,兩個相同的生產環境並行工作。 一種是目前正在執行的生產環境,接收所有使用者流量(顯示為藍色)。另一個是它的克隆,但閒置(綠色)。兩者都使用相同的資料庫後端和應用程式配置: ![藍綠部署前](https://thepracticaldev.s3.amazonaws.com/i/78dk41w8qmuy9f9pvrf6.png) 新版本的應用程式部署在綠色環境中,並進行功能和效能測試。一旦測試結果成功,應用程式流量就會從藍色路由到綠色。綠色則成為新的產品。 ![藍綠部署後](https://thepracticaldev.s3.amazonaws.com/i/m664yyotixnqncprryf0.png) 如果綠色生效後出現問題,流量可以路由回藍色。 在藍綠部署中,兩個系統都使用相同的持久性層或資料庫後端。保持應用程式資料同步至關重要,但鏡像資料庫可以幫助實現這一目標。 您可以使用藍色的主資料庫進行寫入操作,並使用綠色的輔助資料庫進行讀取操作。從藍色切換到綠色期間,資料庫會從主資料庫故障轉移到輔助資料庫。如果測試時green也需要寫入資料,資料庫可以採用雙向複製。 一旦綠色變為可用,您可以關閉或回收舊的藍色實例。您可以在這些實例上部署較新的版本,並使它們成為下一個版本的新版本。 藍綠部署依賴流量路由。這可以透過更新主機的 DNS CNAMES 來完成。但是,長 TTL 值可能會延遲這些變更。或者,您可以變更負載平衡器設置,以便變更立即生效。 ELB 中的連線耗盡等功能可用於服務動態連線。 ## 金絲雀部署 金絲雀部署就像藍綠部署,但它更規避風險。您可以使用分階段的方法,而不是一步從藍色切換到綠色。 透過金絲雀部署,您可以在生產基礎架構的一小部分中部署新的應用程式程式碼。一旦應用程式被批准發布,只有少數用戶會被路由到它。這可以最大限度地減少任何影響。 如果沒有報告錯誤,新版本可以逐步推廣到基礎設施的其餘部分。下圖示範了金絲雀部署: ![金絲雀部署](https://thepracticaldev.s3.amazonaws.com/i/zvf9rbd1x38umph98zro.png) 金絲雀部署的主要挑戰是設計一種方法將某些使用者路由到新應用程式。此外,某些應用程式可能始終需要同一組使用者進行測試,而其他應用程式可能每次都需要不同的群組。 考慮透過探索多種技術來路由新用戶: * 在允許外部使用者存取之前,將內部使用者暴露給金絲雀部署; * 基於來源IP範圍的路由; * 在特定地理區域發布應用程式; * 使用應用程式邏輯為特定使用者和群組解鎖新功能。當應用程式對其他使用者上線時,此邏輯將被刪除。 ## 部署最佳實踐 現代應用程式團隊可以遵循許多最佳實踐,將部署風險降至最低: * **使用部署清單。** 例如,清單上的一項可能是「僅在應用程式服務停止後備份所有資料庫」以防止資料損壞。 * **採用持續整合 (CI)。** CI 確保簽入程式碼儲存庫功能分支的程式碼僅在*經過一系列相依性檢查、單元和整合測試以及成功建置。如果路徑中出現錯誤,建置將失敗並通知應用程式團隊。因此,使用 CI 意味著應用程式的每項變更都需要在部署之前進行測試。 CI 工具的範例包括:CircleCI、Jenkins。 * **採用持續交付 (CD)。** 透過 CD,CI 建置的程式碼工件被打包並隨時準備在一個或多個環境中部署。請閱讀我們的[低風險持續交付電子書](https://try.rollbar.com/low-risk-continuous-delivery-guide/) 以了解更多資訊。 * **使用標準作業環境 (SOE)** 以確保環境一致性。您可以使用 Vagrant 和 Packer 等工具來開發工作站和伺服器。 * **使用建置自動化工具來自動化環境建置。** 使用這些工具,通常只需單擊一個按鈕即可輕鬆拆除整個基礎架構堆疊並從頭開始重建。 CloudFormation 就是此類工具的一個範例。 * **在目標伺服器中使用 Puppet、Chef 或 Ansible 等組態管理工具**來自動套用作業系統設定、套用修補程式或安裝軟體 * **使用 Slack 等通訊管道**來自動通知不成功的建置和應用程式故障 * **建立一個流程,用於就部署失敗向負責團隊發出警報。** 理想情況下,您將在 CI 環境中捕獲這些情況,但如果部署了更改,您將需要一種方法來通知負責團隊 * **為執行狀況檢查失敗的部署啟用自動回滾**,無論是由於可用性還是錯誤率問題。 ## 部署後監控 即使您採用了所有這些最佳實踐,事情仍然可能失敗。因此,監控部署後立即發生的問題與規劃和執行完美部署同樣重要。 應用程式效能監控 (APM) 工具可以幫助您的團隊監控關鍵效能指標,包括部署後的伺服器回應時間。應用程式或系統架構的變化會極大地影響應用程式的效能。 像 [Rollbar](http://rollbar.com/) 這樣的錯誤監控解決方案同樣重要。它將快速通知您的團隊部署中的新錯誤或重新啟動的錯誤,這些錯誤可能會發現需要立即關注的重要錯誤。 如果沒有錯誤監控工具,這些錯誤可能永遠不會被發現。雖然少數遇到錯誤的用戶會花時間報告它們,但大多數其他用戶不會。隨著時間的推移,負面的客戶體驗可能會導致滿意度問題,或更糟的是,可能會導致業務交易無法進行。 錯誤監控工具還可以在營運/DevOps 團隊和開發人員之間建立所有部署後問題的共享可見性。這種共同的理解使團隊能夠更加協作和回應。 _原文發佈於 [rollbar.com](https://rollbar.com/blog/deployment-strategies/)_ --- 原文出處:https://dev.to/mostlyjason/intro-to-deployment-strategies-blue-green-canary-and-more-3a3

新增到 K8s 叢集的五個工具

‍ Kubernetes 已成為管理容器化應用程式的首選平台,提供可擴展性、靈活性和穩健性。然而,Kubernetes 的複雜性可能令人望而生畏,需要開發人員和 DevOps 團隊瀏覽複雜的設定檔和命令列互動。 一些強大的開發工具已經出現,以簡化 Kubernetes 叢集的管理並簡化部署流程。在本文中,我們將探討五種 Kubernetes 開發工具: - [**普羅米修斯**](https://prometheus.io/) - [**獨眼巨人**](https://cyclops-ui.com/) - [**科達**](https://keda.sh/) - [**卡本特**](https://karpenter.sh/) - [**帆船**](https://velero.io/) 這些工具提供直覺的使用者介面、自動擴展功能、災難復原解決方案並提高管理 Kubernetes 叢集的效率。 ### 向我們展示您的支持🙏🏻 在我們開始之前,如果您為我們的儲存庫加註星標並幫助我們在其他開發人員面前獲得我們的工具,我們將非常高興。我們的 GitHub 儲存庫在這裡:https://github.com/cyclops-ui/cyclops ⭐ ## 1. Prometheus:Kubernetes 監控與警報 ![普羅米修斯標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qbet4qg616cunly2gmll.png) **Prometheus** 是一款專為微服務和容器設計的開源監控和警報工具包。它提供靈活的查詢、即時通知以及對容器化工作負載、API 和分散式服務的可見性。 Prometheus 的功能之一是它能夠透過偵測可能升級為攻擊的不規則流量或活動來協助雲端原生安全。 它使用基於拉取的系統,發送稱為“scrapes”的 HTTP 請求,從應用程式和服務收集指標。這些指標儲存在記憶體和本機磁碟中,可以輕鬆檢索和分析。 Prometheus 可以直接從客戶端庫或透過匯出器(位於應用程式附近的軟體)存取資料。匯出器接受來自 Prometheus 的 HTTP 請求,確保資料格式相容性,並將請求的資料提供給 Prometheus 伺服器。 Prometheus 提供了四種主要類型的指標:計數器、儀表、直方圖和摘要。這些指標可以靈活地測量應用程式和服務的各個方面,例如事件啟動計數、記憶體使用情況、資料聚合和分位數範圍。 為了發現監控目標,Prometheus 利用 Kubernetes 叢集中的服務發現。它可以獨立於應用程式資訊存取機器級指標,從而實現全面監控。 資料收集完成後,Prometheus 提供了一種名為 PromQL 的查詢語言,使用戶能夠存取監控資料並將其匯出到 Grafana 等圖形介面,或使用 Alertmanager 發送警報。 ## 2. Cyclops:只需點擊幾下即可部署應用程式 ![獨眼巨人標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cd5wt4tqshun1o3eqeh.png) **Cyclops** 是一個簡化 Kubernetes 叢集中執行的應用程式管理的工具。它將複雜的設定檔抽象化為基於表單的 UI,從而無需手動配置和命令列互動。這使得具有不同技術專業知識水平的個人更容易存取部署過程。 有了 Cyclops,您就不再局限於一刀切的方法。您可以自訂模組以滿足您的獨特需求,讓您可以自由建立具有輸入驗證的模板,以便與您的團隊無縫協作。 這不僅加快了您的工作速度,還使每個團隊成員能夠獨立工作,從而促進更順暢、更有效率的工作流程。 在 Cyclops 中,每個模組都列出了它使用的資源的詳細清單——部署、服務、pod 等,所有這些都在簡單的視圖中。您可以輕鬆追蹤它們的狀態,幫助您快速發現並修復應用程式中的任何問題。這就像有一個清晰的路線圖來導航和解決出現的任何問題。 在 Cyclops 的架構中,核心元件是 [Helm](https://helm.sh/) 引擎,它允許動態產生配置。該引擎是有效管理 Cyclops 框架中的設定和參數的關鍵機制。 由於基於 Kubernetes 的系統通常使用 Helm 作為套件管理器,因此無縫整合 Cyclops 是一個簡單的流程。 Cyclops 促進部署實踐的一致性和標準化。透過提供預先定義的範本或設定預設,Cyclops 可確保部署遵循既定的最佳實務和指南。這種一致性不僅提高了部署的可靠性和穩定性,而且還促進了協作。 ## 3. Keda:Kubernetes 工作負載的事件驅動自動縮放 ![Keda 標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3tb1or82m7dt16jhcht5.png) Kubernetes Horizontal Pod Autoscaling (HPA) 和 Vertical Pod Autoscaling (VPA) 廣泛用於根據 CPU 和記憶體使用量自動縮放 Kubernetes 叢集。 然而,它們也有局限性,例如無法將 Pod 擴展到零或基於資源利用率以外的指標進行擴展。這就是 **Keda**(Kubernetes 事件驅動的自動縮放)發揮作用的地方。 Keda 是一個開源容器自動縮放器,它透過根據外部事件或觸發器縮放 Pod 來擴展本機 Kubernetes 自動縮放解決方案的功能。 Keda 監控 AWS SQS、Kafka 和 RabbitMQ 等事件來源,根據預定義規則有效觸發或停止部署。這種適應性強的解決方案還允許自訂指標,促進為訊息驅動的微服務量身定制的有效自動擴展,確保最佳效能和資源利用率。 Keda 的元件包括事件來源、縮放器、指標適配器和控制器。事件來源提供觸發擴展的外部事件,而擴展器則監視這些事件並取得指標。指標適配器轉換控制器的指標,然後相應地擴展部署。 透過利用 Keda,DevOps 團隊可以在沒有事件需要處理時縮小規模,從而釋放資源並降低雲端成本。 Keda 還提供與各種 DevOps 工具鏈的互通性,支援內建和外部縮放器。 借助 Keda,自動擴展變得更加靈活和高效,使團隊能夠優化資源利用率並適應不斷變化的工作負載需求。 ## 4. Karpenter:Kubernetes 的自動化節點配置 ![卡本特標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d6zjlri79rzrf9zq22vv.png) Kubernetes 叢集經常面臨在可用節點上調度 Pod 的挑戰。 **Karpenter** 是一個開源叢集自動縮放器,可自動配置新節點以回應不可調度的 Pod。它評估待處理 Pod 的聚合資源需求,並選擇最佳實例類型來滿足它們。 Karpenter 還支援整合功能,主動移動 Pod 並以更便宜的版本取代節點,以降低叢集成本。 一個突出的功能是引入“節點池”,允許用戶根據各種標準對節點進行分類。這種客製化確保了客製化的資源分配方法,卡彭特動態地將節點配置到最合適的池中。 Karpenter 的核心旨在無縫地自動擴展 Kubernetes 叢集。 Karpenter 利用 Kubernetes 中的自訂資源定義 (CRD),與現有工具和 API 無縫集成,為使用者提供熟悉的體驗。 Karpenter 的靈活性超出了 AWS 的範圍,使其成為適用於雲端和本地環境的多功能解決方案。 Karpenter 的適應性體現在它透過 Kubernetes 資源支援使用者定義的策略和策略。這種靈活性使組織能夠使 Karpenter 與其獨特的應用程式和工作負載需求保持一致,從而實現更好的自動化和最佳化的 Kubernetes 可擴展性。 ## 5. Velero:Kubernetes 的災難復原與備份 ![Velero 標誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ki3p8bkzdrl2lgpp53lr.png) **Velero** 是一款功能強大的工具,可為 Kubernetes 叢集提供災難復原和備份解決方案。它使用戶能夠輕鬆備份、還原和遷移應用程式及其持久性磁碟區。 Velero 拍攝叢集資源和資料的快照,並將它們儲存在 AWS S3、Google Cloud Storage 或 Azure Blob Storage 等物件儲存提供者中。 借助 Velero,使用者可以建立備份計劃,確保關鍵叢集資源的定期快照。這樣可以在資料遺失或叢集故障時實現高效的災難復原。 Velero 也支援叢集遷移,簡化了在 Kubernetes 叢集之間行動應用程式和資料的過程。 該工具提供資源過濾功能,允許使用者選擇性地備份和還原特定資源。 這種靈活性可確保備份中僅包含相關資料,從而節省儲存空間並減少備份和還原時間。 Velero 與 CSI(容器儲存介面)集成,提供備份磁碟區並將其恢復到原始狀態的支援。 除了災難復原和備份之外,Velero 還提供在任何命名空間中執行、使用掛鉤擴充功能以及支援自訂外掛程式以增強自訂等功能。它提供了診斷和解決常見問題的故障排除指南,確保管理 Kubernetes 叢集的流暢體驗。 ## 結論 這五種 Kubernetes 開發工具 - Prometheus、Cyclops、Keda、Karpenter 和 Velero - 在簡化 Kubernetes 叢集管理的複雜性方面發揮關鍵作用。 從使用Prometheus 進行監控和警報,到使用Keda 進行事件驅動的自動縮放,再到透過Karpenter 進行自動化節點配置,每個工具都可以解決特定的挑戰,從而有助於打造更有效率、更有彈性的Kubernetes環境。 Cyclops 因其用戶友好的方法而脫穎而出,將複雜的配置抽象化為直覺的 UI,而 Velero 則提供重要的災難復原和備份解決方案來保護關鍵資料和應用程式。 由於 Kubernetes 仍然是現代應用程式部署的基石,這些工具使開發人員和 DevOps 團隊能夠更輕鬆地駕馭複雜的容器化環境。 透過將這些工具整合到 Kubernetes 工作流程中,您可以增強可擴展性、簡化部署流程,並確保應用程式在當今動態且要求嚴苛的運算環境中的穩健性。 --- 原文出處:https://dev.to/cyclops-ui/five-tools-to-add-to-your-k8s-cluster-2j89

您需要了解的 42 個 🐍 Python 函式庫 🦾

## 簡介 透過這份備忘清單深入了解 Python,其中包含任何 Pythonista 都需要了解的唯一函式庫。 從資料操作到機器學習和建立 Web 應用程式,這些程式庫在您的 Python 編碼之旅中至關重要。 ![介紹 GIF](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6s1cu1kjpp4xae20gvpt.gif) --- ## 網路應用程式 ![Web 應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t532en00kn1s788ndnnt.png) ### 1. [太皮](https://github.com/Avaiga/taipy) Taipy 是這個街區的新來者。 它專為輕鬆開發前端 (GUI) 和 ML/資料管道而設計。 建立您夢想的應用程式得益於: - 完整的客製化和互動 - 多頁和多用戶應用程式 - 管道圖形編輯器 - 還有更多! --- ![QueenB](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovcc5kqd8xr9uihrggbb.gif) 您的支持意義重大🌱,並且在許多方面為我們帶來了很大的幫助,例如寫文章! 🙏 --- ### 2. [Streamlit](https://github.com/streamlit/streamlit) Streamlit 是一個完善的函式庫,可用於為飛行員快速建立 Web 應用程式。非常容易使用! --- ## 要點 ![要點](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f4ui7ramgta16rsnwm6s.png) ### 3. [熊貓](https://github.com/pandas-dev/pandas) 該庫帶來了兩個核心概念:資料幀和系列,使資料清理和準備成為一個輕鬆的過程。 ### 4. [Numpy](https://github.com/numpy/numpy) Pandas 有資料框,而 Numpy 有陣列。 它們以允許快速資料操作而聞名,使 Numpy 成為科學計算的重要工具。 ### 5. [請求](https://github.com/psf/requests) 該程式庫使處理 HTTPS 請求變得輕而易舉。 Requests 提供與 Web API 互動和管理 HTTP 回應的功能。 ### 6. [Scipy](https://github.com/scipy/scipy) Scipy 基於 Numpy,核心功能專注於數學計算,具有最佳化、訊號處理和插值等功能。 --- ## 約會時間 ![日期時間](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9k1rcy4cduac7r77zkmc.png) ### 7. [日期時間](https://docs.python.org/3/library/datetime.html) DateTime 是一個標準的 Python 函式庫,對於處理任何 DateTime 格式都是必不可少的。 ### 8. [擺](https://github.com/sdispater/pendulum) Pendulum 具有更高級的日期和時間處理所需的附加功能。 他們有更好的時區支援以及更好的格式選項。 --- ## 機器學習 ![機器學習](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o34j1iqk4hipnvtqc3l6.png) ### 9. [Scikit-Learn](https://github.com/scikit-learn/scikit-learn) 這個庫不再需要介紹了,這是理所當然的。 Scikit Learn 是機器學習的參考,包含從聚類到分類的演算法。 它還包括從資料驗證到資料選擇的所有功能。 ### 10. [XGboost](https://github.com/dmlc/xgboost) 該庫以其回歸和分類演算法的高效結果而聞名。 ### 11. [Catboost](https://github.com/catboost/catboost) Catboost 是一個機器學習庫,專門設計用於處理主要顯示分類資料的資料集。 --- ## 深度學習 ![深度學習](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oc0hnfiemtkc74lk981j.png) ### 12. [TensorFlow](https://github.com/tensorflow/tensorflow) TensorFlow 是一個成熟的深度學習庫,專門從事自然語言處理和影像分類。 ### 13. [PyTorch](https://github.com/pytorch/pytorch) Pytorch 還是 TensorFlow,這就是問題所在。 最終,您可以選擇自己的團隊,但 PyTorch 的與眾不同之處在於它更注重自然語言處理,並且更具 Python 風格,從而減少了眾所周知的 TensorFlow 陡峭的學習曲線。 ### 14. [Keras](https://github.com/keras-team/keras) Keras 是開始深度學習的好方法,因為它在 TensorFlow 之上執行,但實作過程得到簡化。 ### 15. [OpenCV](https://github.com/opencv/opencv) OpenCV 提供了各種圍繞即時電腦視覺的演算法。 您可以處理多種格式,包括物件、人類,甚至手寫體。 --- ## 自然語言處理 ![NLP](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i2vh6hm8ambihevofx3t.png) ### 16. [NLTK](https://github.com/nltk/nltk) NLTK 是自然語言處理的首選函式庫。 NLTK 的主要功能包括:處理和操作文本(標記化、詞幹提取等)以及使用 NLP 任務進行分類以進行情緒分析。 ### 17. [SpaCy](https://github.com/explosion/spaCy) 是這個領域的新人,專注於讓 NLP 更容易存取和用戶友好。 該圖書館優化了流程,以確保更高的速度和效率。 --- ## 測試 ![測試](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7711x9xwpfi249kgj1iy.png) ### 18. [Pytest](https://github.com/pytest-dev/pytest) Pytest 是一個簡化測試編寫和執行的框架。它的語法簡潔,使用者友善。 ### 19. [Unitest](https://docs.python.org/3/library/unittest.html) Unistest 是 Python 內建的測試框架。 其主要功能是:測試發現、夾具支援、輕鬆組織和測試套件管理。 --- ## 聲音的 ![音訊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrsy4w7kye7q71g7ugld.png) ### 20. [AudioFlux](https://github.com/libAudioFlux/audioFlux) Python 中用於音訊訊號處理的首選庫,但很簡單。 AudioFlux 具有大量功能,包括聲音分析,可用於深度學習訓練。 ### 21. [Librosa](https://github.com/librosa/librosa) 此 Python 程式庫允許從音訊來源中分析和提取特徵。 --- ## 程式碼分析 ![程式分析](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhbzed8w9wadmdptd4yd.png) ### 22.[黑色](https://github.com/psf/black) 它是一個自動程式碼格式化程式。 它將自動格式化您的程式碼,以在整個專案中保持一致的風格。 ### 23. [Pylint](https://github.com/pylint-dev/pylint) 顧名思義,Pylint 是一個 linter。 它是一個靜態程式碼分析工具,用於檢查程式碼品質和錯誤。 ### 24. [Flake8](https://github.com/PyCQA/flake8) 這是另一個 linting 函式庫,可以根據 PEP8 編碼約定檢查您的程式碼。 ### 25. [Ruff](https://github.com/astral-sh/ruff) Ruff 是等效 linter 的最快選擇。 它提高了效率和速度,使流程加快了十倍。 --- ## 分散式計算 ![分散式計算](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/foog7hfgk5r01vpfu7nl.png) ### 26. [Dask](https://github.com/dask/dask) Dask 是一個流行的分散式運算 Python 包,因為它在處理大型資料集時特別有用。 Dask 整合了 Pandas、Numpy 和 Scikit-learn API,因此易於使用。 ### 27. [PySpark](https://github.com/apache/spark/tree/master) 顧名思義,PySpark 是 Apache Spark 的 Python API,讓我們可以直接在 Python 中利用 Spark 的功能。 ### 28. [極地](https://github.com/pola-rs/polars) Polars 是一個為處理大型資料集而建立的 DataFrame 函式庫。 它的靈感來自蟒蛇皇室 - 熊貓,但有一個(快速)扭曲,它的速度快了 10 到 100 倍。 --- ## 文件 ![文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tmv4jhi7w8oo3hrr3adp.png) ### 29. [Mkdocs](https://github.com/mkdocs/mkdocs) Mkdocs 是產生簡單文件的最易於存取的庫。 適合較小的專案,幾乎沒有學習曲線。 ### 30. [獅身人面像](https://github.com/sphinx-doc/sphinx) Sphinx 通常是大型專案的首選。 它包括對多種格式的支援並允許特定的自訂。 ### 31. [Pydoc](https://docs.python.org/3/library/pydoc.html) Pydoc 已整合到 Python 生態系統中。它直接從您的模組產生文件。 --- ## 地理資料 ![地理資料](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zq7xis1kydzgxu7h1pm2.png) ### 32. [Geopy](https://github.com/geopy/geopy) Geopys 的主要功能是:距離計算、地理編碼和反向地理編碼。 ### 33. [表](https://github.com/python-visualization/sheet) 該庫允許您使用 Python 建立互動式地圖。改變遊戲規則的人。 ### 34. [Geopandas](https://github.com/geopandas/geopandas) 當您擁有地理空間資料時,您應該採取的方法。 如標題所述,Geopandas 是 Pandas,但用於地理空間資料。該庫具有輕鬆操作和分析地理資料的功能。 --- ## 遊戲 ![遊戲](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdsaapo3h5bo2dhcj8fs.png) ### 35. [Pygame](https://github.com/pygame/pygame) Pygame 是首選、簡單的函式庫,可以輕鬆使用 Python 建立 2D 和互動式視訊遊戲。 ### 36. [街機](https://github.com/pythonarcade/arcade) 就像 PyGame 一樣,Arcade 使 Python 中建立影片遊戲成為一個有趣的過程。 它們對經典 Pygame 進行了更現代的改造,因此選擇實際上取決於個人喜好。 --- ## 網頁抓取 ![網路搜尋](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kt6wd4ytgpdvuys1mytg.png) ### 37. [Scrapy](https://github.com/scrapy/scrapy) Scrapy 是一個成熟的函式庫,以網頁抓取而聞名。 一些關鍵功能包括:支援非同步/同步操作、HTTPS 請求處理等。 它具有廣泛的功能,這可能證明該庫具有陡峭的學習曲線。 ### 38. [美麗湯](https://www.crummy.com/software/BeautifulSoup/#Download) Beautiful Soup 是您處理從 XML 和 HTML 檔案中提取資料所需的一切。 由於其 Python 風格,它受到了開發人員的讚賞。 --- ## 視覺化 ![視覺化](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j8sawtir7wvwzmtns78i.png) ### 39. [Matplotlib](https://github.com/matplotlib/matplotlib) Matplotlib 是 Python 中主要的元件庫,這是有充分理由的。 Matplotlib 允許使用多種圖表類型繪製 2D 圖形,並且還允許進行大量自訂。 元素的細粒度控制是該庫的真正優勢。 ### 40. [散景](https://github.com/bokeh/bokeh) 與 Matplotlib 相反,Bokeh 專注於互動式圖表。 ### 41. [Seaborn](https://github.com/mwaskom/seaborn) Seaborn 建構在 Matplotlib 之上。 雖然 Matplolib 強調精確性和簡單性,但 Seaborn 在建立複雜的統計視覺化的同時,其時尚的視覺效果具有真正的附加價值。 ### 42. [Vizzu](https://github.com/vizzuhq/vizzu-lib) Vizzu 在視覺化領域找到了自己的定位,並且做得非常好。 他們將講故事和圖表與高度動畫的視覺化融為一體,這是一種獲得更多動態圖表的好方法。 --- ## 結論 無論您是高級 Python 專家還是正在嘗試 Python,有了這份不可或缺的函式庫列表,您將能夠應對任何挑戰。祝你編碼愉快! --- 我是一名新手作家,歡迎任何改進建議! ![新秀圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25oebh36ha622u74kpli.gif) 如果您有任何疑問,請隨時與我們聯繫。 --- 原文出處:https://dev.to/taipy/top-42-python-libraries-you-need-to-know-1omo

🎉像專業人士一樣監控您的 Javascript 應用程式🧙‍♂️💫

## **簡介** 在本教程中,您將學習如何使用**現代工具**和**最佳實踐**來監控您的Javascript應用程式。 探索分散式追蹤的力量,並了解如何無縫整合和利用 Odigos 和 Jaeger 等工具來增強您的監控能力。 **您將學到什麼:✨** - 如何在 Javascript 中建立微服務🐜。 - 為微服務設定 Docker 容器📦。 - 配置 Kubernetes ☸️ 以管理微服務。 - 整合追蹤後端以可視化追蹤🔍。 您準備好成為監控 JS 應用程式的**專家**了嗎? 😍 說**是的,先生!**。 我聽不到你說話。大聲點說。 🙉 ![大聲點 GIF](https://media.giphy.com/media/8m5dizh7ghyEPIWIx1/giphy.gif) *** ## **讓我們設定一下 🦄** > 🚨 在部落格的這一部分中,我們將建立一個虛擬的 JavaScript 微服務應用程式並將其部署在本地 Kubernetes 上。如果您已經有一個並且正在跟進,請隨意跳過這一部分。 為您的應用程式建立初始資料夾結構,如下所示。 👇🏻 ``` mkdir microservices-demo cd microservices-demo mkdir src cd src ``` ### **設定伺服器** 🖥️ > 👀 出於演示目的,我將建立兩個相互通信的微服務,最終我們可以使用它來視覺化分散式追蹤。 - **建置與 Dockerize 微服務 1** 在「/src」資料夾中,建立一個新資料夾「/microservice-1」。在資料夾內初始化 **NodeJS** 專案並安裝所需的依賴項。 ``` mkdir microservice-1 cd microservice-1 npm init -y npm install --save express node-fetch ``` 建立一個新檔案“index.js”並新增以下程式碼: ``` // 👇🏻/src/microservice-1/index.js const express = require("express"); const fetch = require("node-fetch") const app = express(); const PORT = 3001; app.use(express.json()); app.get("/", async (req, res) => { try { const response = await fetch("http://microservice2:8081/api/data"); const data = await response.json(); res.json({ data: "Microservice 2 data received in Microservice 1", microservice2Data: data, }); } catch (error) { console.error(error.message); res.status(500).json({ error: "Internal Server Error" }); } }); app.listen(PORT, () => { console.log(`Microservice 1 listening on port ${PORT}`); }); ``` 伺服器正在偵聽連接埠“3001”,並且在對“/”發出請求時,我們從“microservice2”請求資料並將回應作為 JSON 物件返回。 📦 現在,是時候對這個微服務進行 docker 化了。在“/microservice-1”資料夾中建立一個新的“Dockerfile”並新增以下程式碼: ``` // 👇🏻/src/microservice-1/Dockerfile FROM node:18 # Use /usr/src/app as the working directory WORKDIR /usr/src/app # Copy package files and install production dependencies COPY --chown=node:node package*.json /usr/src/app RUN npm install --production # Copy the rest of the files COPY --chown=node:node . /usr/src/app/ # Switch to the user node with limited permissions USER node # Expose the application port EXPOSE 3001 # Set the default command to run the application CMD ["node", "index.js"] ``` 將我們不想推送到容器的文件加入到“.dockerignore”總是很好。使用我們不想推送的檔案的名稱來建立一個“.dockerignore”檔案。 ``` // 👇🏻/src/microservice-1/.dockerignore node_modules Dockerfile ``` 最後,透過執行以下命令來建構 🏗️ docker 映像: ``` docker build -t microservice1-image:latest . ``` 現在,這就是我們第一個微服務的完整設定。 ✨ - **建置與 Dockerize 微服務 2** 我們將有一個類似於“microservice1”的設置,只是在這裡和那裡進行了一些更改。 在「/src」資料夾中,建立一個新資料夾「/microservice-2」。在該資料夾內,初始化 **NodeJS** 專案並安裝所需的依賴項。 ``` mkdir microservice-2 cd microservice-2 npm init -y npm install --save express node-fetch ``` 建立一個新檔案“index.js”並新增以下程式碼: ``` // 👇🏻/src/microservice-2/index.js const express = require("express"); const fetch = require("node-fetch") const app = express(); const PORT = 3002; app.use(express.json()); app.get("/api/data", async (req, res) => { const url = "https://jsonplaceholder.typicode.com/users"; try { const response = await fetch(url); const data = await response.json(); res.json(data); } catch (error) { console.error(error.message); res.status(500).json({ error: "Internal Server Error" }); } }); app.listen(PORT, () => { console.log(`Microservice 2 listening on port ${PORT}`); }); ``` 伺服器正在偵聽連接埠 3002,根據對“/api/data”的“GET 請求”,我們從“jsonplaceholder”獲取資料並將回應作為 JSON 物件傳回。 📦 現在,是時候對這個微服務進行 docker 化了。複製並貼上「microservice1」的整個「Dockerfile」內容,然後將連接埠從 3001 變更為 3002。 另外,新增一個「.dockerignore」檔案並包含我們在建立「microservice1」時新增的相同檔案。 最後,透過執行以下命令來建構 🏗️ Docker 映像: ``` docker build -t microservice2-image:latest . ``` 現在,這也是我們第二個微服務的完整設定。 ✨ - **設定 Kubernetes** > 確保已安裝 **[Minikube](https://github.com/kubernetes/minikube)** 透過執行以下命令建立新的本機 Kubernetes 叢集。我們在設定 Odigos 和 Jaeger 時將需要它。 **啟動 Minikube:🚀** ``` minikube start ``` 現在我們已經準備好並 Docker 化了兩個微服務,是時候設定 Kubernetes 來管理這些服務了。 在專案的根目錄下,建立一個新資料夾「/k8s/manifests」。在此資料夾中,我們將為兩個微服務新增部署和服務配置。 - **部署設定📜**:用於在 Kubernetes 叢集上實際部署容器。 - **服務配置📄**:將 Pod 暴露給叢集內部和叢集外部。 首先,我們為「microservice1」建立清單。建立一個新檔案「microservice1-deployment-service.yaml」並新增以下內容: ``` // 👇🏻/k8s/manifests/microservice1-deployment-service.yaml apiVersion: apps/v1 kind: Deployment metadata: name: microservice1 spec: selector: matchLabels: app: microservice1 template: metadata: labels: app: microservice1 spec: containers: - name: microservice1 image: microservice1-image # Make sure to set it to Never, or else it will pull from the docker hub and fail. imagePullPolicy: Never resources: limits: memory: "200Mi" cpu: "500m" ports: - containerPort: 3001 --- apiVersion: v1 kind: Service metadata: name: microservice1 labels: app: microservice1 spec: type: NodePort selector: app: microservice1 ports: - port: 8080 targetPort: 3001 nodePort: 30001 ``` 此配置部署了一個名為「microservice1」的微服務,其資源限制為 **200MB 記憶體** 🗃️ 和 **0.5 個 CPU 核心**。它透過部署在連接埠 3001 上公開微服務,並透過服務在 **NodePort** 30001 上公開微服務。 > 🤔 還記得我們用名稱「microservice1-image」建構的「Dockerfile」嗎?我們使用相同的映像來建立容器。 可透過集群內的連接埠 8080 存取它。我們假設「microservice1-image」透過「imagePullPolicy: Never」在本地可用。如果沒有到位,它將嘗試從 Docker Hub 🐋 中提取映像並失敗。 現在,讓我們為「microservice2」建立清單。建立一個名為「microservice2-deployment-service.yaml」的新檔案並新增以下內容: ``` // 👇🏻/k8s/manifests/microservice1-deployment-service.yaml apiVersion: apps/v1 kind: Deployment metadata: name: microservice2 spec: selector: matchLabels: app: microservice2 template: metadata: labels: app: microservice2 spec: containers: - name: microservice2 image: microservice2-image # Make sure to set it to Never, or else it will pull from the docker hub and fail. imagePullPolicy: Never resources: limits: memory: "200Mi" cpu: "500m" ports: - containerPort: 3002 --- apiVersion: v1 kind: Service metadata: name: microservice2 labels: app: microservice2 spec: type: NodePort selector: app: microservice2 ports: - port: 8081 targetPort: 3002 nodePort: 30002 ``` 它與“microservice1”的清單類似,只有一些更改。 👀 此配置部署一個名為「microservice2」的微服務,並透過部署在連接埠 3002 上將其內部公開,並透過服務在 **NodePort** 30002 上將其外部公開。 可透過叢集內的連接埠 8081 進行存取,假設「microservice2-image」可透過「imagePullPolicy: Never」在本地使用。 全部完成後,請確保套用這些設定並使用這些服務啟動 Kubernetes 叢集。將目錄更改為`/manifests`並執行以下命令:👇🏻 ``` kubectl apply -f microservice1-deployment-service.yaml kubectl apply -f microservice2-deployment-service.yaml ``` 執行以下命令檢查我們的兩個部署是否正在**執行**:👇🏻 ``` kubectl get pods ``` ![Kubernetes Pod](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ywsvodcqqbx1wv0kede1.png) 最後,我們的應用程式已準備就緒,並使用必要的部署配置部署在 Kubernetes 上。 🎉 *** ## **安裝 Odigos 😍** > 💡 [**Odigos**](https://odigos.io/) 是一個開源可觀察性控制平面,使組織能夠建立和維護其可觀察性管道。 ![Odigos - 監控工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7c6i7wth5l3ey9frk0cx.jpg) > ℹ️ 如果您在 Mac 上執行,請執行以下命令在本地安裝 Odigos。 ``` brew install keyval-dev/homebrew-odigos-cli/odigos ``` > ℹ️ 如果您使用的是 Linux 計算機,請考慮透過執行以下命令從 GitHub 版本安裝它。確保根據您的 Linux 發行版更改該檔案。 > ℹ️ 如果 Odigos 二進位檔案不可執行,請在執行安裝指令之前執行此指令 `chmod +x odigos` 使其可執行。 ``` curl -LJO https://github.com/keyval-dev/odigos/releases/download/v1.0.9/cli_1.0.9_linux_amd64.tar.gz tar -xvzf cli_1.0.9_linux_amd64.tar.gz ./odigos install ``` ![Odigos 安裝](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/145z2j9fusgnbp41whcw.png) > 如果您需要有關其安裝的更多簡短說明,請按照此[**連結**](https://docs.odigos.io/installation)操作。 現在,Odigos 已準備好執行 🎉。我們可以執行它的 UI,配置追蹤後端,並相應地發送追蹤。 *** ## **將 Odigos 連接到追蹤後端 💫** > 💡 [**Jaeger**](https://github.com/jaegertracing/jaeger) 是一個開源的端對端分散式追蹤系統。 ![Odigos - 分散式追蹤平台](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9bytdpf4wv1ncb0z52p.jpg) ### **設定 Jaeger!** ✨ 在本教程中,我們將使用 **Jaeger** 🕵️‍♂️,這是一個流行的開源平台,用於查看微服務應用程式中的分散式追蹤。我們將用它來查看 Odigos 生成的痕跡。 > 有關 Jaeger 安裝說明,請點選此 [**link**](https://www.jaegertracing.io/download/)。 👀 若要在 Kubernetes 叢集上部署 Jaeger,請執行下列命令:👇🏻 ``` kubectl create ns tracing kubectl apply -f https://raw.githubusercontent.com/keyval-dev/opentelemetry-go-instrumentation/master/docs/getting-started/jaeger.yaml -n tracing ``` 在這裡,我們建立一個「tracing」命名空間,並在該命名空間中為 Jaeger 應用部署配置📃。 此命令設定自託管 Jaeger 實例及其服務。 👀 執行以下命令來取得正在執行的 pod 的狀態:👇🏻 ``` kubectl get pods -A -w ``` 等待所有三個 Pod 都 **正在執行**,然後再繼續。 ![Kubernetes Pod](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n41rxtp8gcbe4cwsl6xx.png) 現在,要在本地查看 Jaeger Interface 💻,我們需要進行連接埠轉送。將流量從本機電腦上的連接埠 16686 轉送至 Kubernetes 叢集中選定 pod 上的連接埠 16686。 ``` kubectl port-forward -n tracing svc/jaeger 16686:16686 ``` 此命令在本機電腦和 Jaeger pod 之間建立一條隧道,公開 Jaeger UI,以便您可以與其互動。 最後,在瀏覽器上開啟「 http://localhost:16686 」並查看 Jaeger 實例正在執行。 ![Jaeger UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gr6bcqph7nyxa7v0u01t.png) ### **設定 Odigos 與 Jaeger 一起工作!** 🌟 > ℹ️ 對於 Linux 用戶,請前往從 GitHub 版本下載 Odigos 二進位檔案的資料夾,然後執行以下命令來啟動 Odigos UI。 ``` ./odigos ui ``` > ℹ️ 對於 Mac 用戶,只需執行: ``` odigos ui ``` 造訪“ http://localhost:3000 ”,您將看到 Odigos 介面,您將在“default”命名空間中看到您的部署。 ![Odigos 登陸頁](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14yqd2x41i9gqvwxdtsu.png) 選擇這兩個選項並點擊“下一步”。在下一頁上,選擇 Jaeger 作為後端,並在出現提示時加入以下詳細資訊: - **目的地名稱🛣️**:提供您想要的任何名稱,例如說**快速追蹤**。 - **端點🎯**:為端點加上`jaeger.tracing:4317`。 就是這樣 - Odigos 已準備好向我們的 Jaeger 後端發送痕跡。就是這麼簡單。 🤯 ![具有兩個微服務的 Odigos UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qqmo7div92zngnkdwwyu.png) *** ## **查看分散式追蹤 🧐** 設定 Odigos 後,在 Jaeger 主頁「 http://localhost:16686 」上,您將已經看到列出的兩個微服務。 ![Jaeger UI 列出了兩個微服務](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwb0qjdmxi4ydcvwjgr1.png) Odigos 已經開始向 Jaeger 發送我們的應用程式痕跡。 😉 請記住,這是我們的微服務應用程式。由於以「microservice1」為起點,因此再向「microservice1」發出一些請求,隨後它將向「microservice2」請求資料並傳回。最終,Jaeger 將開始填滿這些痕跡。 ![Jaeger 分散式追蹤](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4kwzh854bsh5wga1or3.png) 點擊任一請求,您應該能夠觀察請求如何流經您的應用程式以及完成每個請求所需的時間。 這一切都是在沒有更改一行程式碼的情況下完成的。 🤯 一切都感謝 **Odigos**! 🤩 ![令人震驚的 GIF](https://media.giphy.com/media/l0NwHXQy3kUSfFF60/giphy.gif) 想像一下,這只是一個很小的虛擬應用程式,但對於一個執行著大量微服務並相互交互的更大的應用程式來說,分散式追蹤將非常強大! 💪 透過分散式跟踪,您可以輕鬆辨識應用程式中的瓶頸,並確定哪個服務導致問題或花費更長的時間。 🕒 *** ## **讓我們總結一下! 🥱** 到目前為止,您已經學習如何使用 **Odigos** 作為應用程式和追蹤後端 **Jaeger** 之間的 **中間件**,透過分散式追蹤來密切監控 👀 Javascript 應用程式。 👏 如果您已經做到了這一步,請拍拍自己的背。 🥳你值得擁有! 😉 本教學的源程式碼可在此處取得: https://github.com/keyval-dev/blog/tree/main/odigos-monitor-JS-like-a-pro > 如果您對本文有任何疑問或建議,請在下面的評論部分分享。 👇🏻 那麼,這就是本文的內容。感謝您的閱讀! 🎉🫡 --- 原文出處:https://dev.to/odigos/monitor-your-javascript-application-like-a-pro-581p

初級開發人員需要掌握的 12 個資深開發人員特質 🔥

在任何領域,無論是藝術、體育還是軟體開發,達到頂峰的最快方法就是研究那些已經處於頂峰的人……並做他們正在做而你沒有做的事情。 如果您以編寫程式碼為生,這意味著要考慮一下高級開發人員。這意味著確定他們擁有哪些你不具備的技能、習慣和特質。 在過去 3 年裡與全球頂尖軟體工程師一起工作了數千個小時之後,我發現您現在就可以實施 12 種高級開發人員特質,以快速將您的成長提升到一個新的水平。 讓我們從第一開始… ## 1. 專注 專注意味著對某些事情說不,這樣我們就可以做其他事情。 理想情況下,對不重要的事情說不。並對那些能帶來改變的事情說「是」。使船移動得更快的東西。 這對許多開發人員來說確實很難,因為它違背了我們的本能。這意味著接受你無法完成所有事情。並不是每個機會都是平等的。 你不可能學習所有新的框架。您無法閱讀所有時事通訊。您不可能參加所有會議。而你不必這樣做。 你的時間有限。你的能量也是如此。 成為高級開發人員意味著選擇你的戰鬥。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wftnt9w68gjflh2yghs0.png) > 「人們認為專注意味著對你必須關注的事情說『是』。但這根本不是這個意思。這意味著對其他一百個好主意說不。” ——史蒂夫‧賈伯斯 有趣的是,你選擇的越好,你進步的速度就越快。高級開發人員每天都有 24 小時的時間。但他們做得更多。 如何? 透過少做事。 當新事物出現時,問問自己“這真的很重要嗎?”或者這只是另一個趨勢?很可能這只是另一個偽裝成機會的干擾。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgqenoavc69esm48yf06.png) 高級開發人員說的「不」多於「是」。他們完成的專案比開始的專案還要多。他們在學習新框架之前先掌握已經使用的框架。如果你想更快進入高級,你需要培養的第一個特質就是專注。 ## 2. 二階思維 讓「初級開發者」尖叫的一件事是「讓我們建造它,我們會找到結果」的態度。年輕人傾向於先編碼,後思考。 如果您剛開始,這可能是一個很好的態度,但是當您開發可用於生產的軟體時,您將無法更改一些技術決策。或者很容易改變。 例如,您選擇Vue作為前端框架。 然後,需求會改變。你開始認為 React 會是更好的選擇。當然,你可以切換到 React。但這既不容易,也不便宜。 資深開發人員知道,靠自己的供應很容易獲得快感。但是,如果您愛上了您最了解的框架和函式庫,您將開始做出糟糕的技術決策。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9eb6xwgv7jhmn4p7qcq1.png) 他們會三思而後行,考慮自己選擇的後果。這可能意味著在嘗試理解問題時詢問「五個為什麼」。 或考慮他們的解決方案可能存在的缺點。 例如,現在我們新增了 Redux,全域狀態可能更容易管理。但我們必須在 Redux 上招募新的開發人員。學習曲線很高。 而且,你猜怎麼著,我們的 JavaScript 套件會變得更大,這對效能不利。 考慮二階環境將使您成為更好的開發人員。它還將在技術面試中為您提供幫助。 🚨 PS您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/3GJuOjr) 🚨 ## 3.實用主義 當初級開發人員閱讀一本關於最佳實踐的書時,他們會跳起來並嘗試將它們應用到任何版本中的每一行程式碼。他們虔誠地追隨他們。 如果您無法自己做出技術決策,那麼遵守預先定義的規則會容易得多。但軟體開發不是一種宗教。 一個很好的例子是測試。 當初級開發人員閱讀 TDD(測試驅動開發)時,他們將開始嘗試測試所有內容。旨在實現完整的程式碼覆蓋率。事實上,完整的程式碼覆蓋率會帶來遞減的結果,並且最終會浪費時間。 ![每個發現 TDD 的初級開發人員](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/do0uxbjna2alz58b3mvg.png) 高級開發人員知道如何平衡最佳實踐和上市時間。何時走捷徑,何時不走捷徑。 快速破解會產生錯誤和技術債。當程式碼上下文發生變化時,始終遵守規則會導致錯誤的決策。 你需要一個平衡。 根據情況重新考慮您的技術選擇。 ## 4. 沒有什麼好證明的 由於缺乏自信,初級開發人員發現自己不斷地試圖向他人證明自己。與對自己的價值和技能缺乏安全感的高級開發人員一樣。 他們的信心是建立在他人的認可之上。 這是一場失敗的遊戲。 他們會嘗試在某個技術討論、與他人交談或在深夜或週末推送程式碼時展示自己了解多少。 事實上,所有這些行為都會造成有毒的團隊環境並適得其反。在最好的情況下,他們會讓你看起來比實際情況更高級。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1sfp7p24zru1r9zafd05.png) 獵豹不需要在比賽中證明自己,它只是為了狩獵而奔跑。 有兩種方法可以解決這個問題。 第一個是停止在外部驗證上花費太多。因為事實是你不需要向任何人證明自己。只對你自己。 第二是與頭腦中的負面聲音和平相處。 你可以成為你最嚴厲的批評者。完美主義、對失敗的恐懼以及對「真正的」開發人員的錯誤認知正在摧毀你的自尊。這就是為什麼無論你多努力,你總是感覺功虧一簣。 是時候擺脫你的頭腦了。 專注於掌握你的手藝,剩下的就會水到渠成。您將立即對自己和自己的技能更加自信。你將不再試圖向陌生人證明自己。 ## 5. 掌握基礎知識 每當我在 LinkedIn 上看到開發人員的個人資料,並且他們將自己描述為「React」開發人員或「Angular」開發人員時,我就知道他們不是高級開發人員。他們可能是該框架中的高級人員,但總體而言不是高級人員。 框架開發人員永遠不會成為高級開發人員。 框架不會讓你成為高級,因為框架只是錦上添花。不是蛋糕本身。冰山一角與其底部。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chomoxfdvoemx4m4n15o.png) 我甚至推測,目前軟體開發人員中冒充者症候群盛行的背後,甚至是高階開發人員的背後,並不是缺乏天賦,也不是缺乏努力。 這是基本面薄弱。 這也是為什麼除錯或效能優化等主題對於大多數開發人員來說是一個猜謎遊戲。他們不習慣深入挖掘他們正在使用的庫和工具的表面。 要成為高級開發人員,您不僅必須了解事物背後的“什麼”,還必須了解事物背後的“原因”。 例如,高級開發人員不僅能夠建立 React 應用程式。但他們也會理解為什麼 React 是以某種方式建構的。以及它如何與編寫的語言(JavaScript/TypeScript)和執行的平台(Web 瀏覽器)融合。 好訊息是,一旦你掌握了基本原理,一切的水平都會上升。 🚨 PS您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/3GJuOjr) 🚨 ## 6. 端對端交付 公司避開初級開發人員的第一大原因是他們需要大量外部協助才能完成工作。外部幫助意味著您將打擾高級開發人員來完成您的工作。 初級開發人員被認為“昂貴”,因為他們無法獨立交付。 相反,高級開發人員可以提供端到端的服務。給他們一堆要求,他們會解決剩下的問題。這並不意味著他們是獨狼,而且他們通常非常擅長團隊合作。 這並不意味著高級開發人員快速破解事物只是為了推動它們前進。 那不是「真正的」前輩。 這並不意味著他們深入了解軟體開發生命週期的每個部分。 但是,高級開發人員了解整個軟體開發生命週期的所有主要部分。並且可以為其中的每一個(前端、後端、部署)做出貢獻。 如果您是想要升級的初級/中級開發人員,那麼端對端交付是您需要關注的特徵。 ## 7. 心智模型 高級開發人員與初級開發人員的主要區別之一是他們可以處理的複雜性。 老年人可以理解更複雜的程式碼庫和需求。 他們可以理解二階環境。程式碼庫的變化將如何影響效能、成本甚至團隊。 他們這樣做並不是因為他們記住了每個實作細節。這是不可能的,因為人類的記憶非常有限。 他們這樣做是因為他們將程式碼的複雜度抽象化為心理模型。這些都是表示現實的簡單方法。 開發人員如何建構高品質的心理模型? 透過查看框架和庫的背後並學習它們背後的設計模式。根據您的技術堆棧,存在著許多噪音。諸如 SOLID 原則或 MVC 之類的東西... 但我認為最好的開始方法是選擇您正在使用的任何框架並嘗試超越程式碼。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hk2opgm1njc76p0a6k0n.png) 開始問自己,為什麼框架的建立者要這樣建構它?它是建立在新概念的基礎上還是只是古老原則的實現(通常是這種情況)? 透過回答這些問題,您將建立軟體開發的思維模型,並能夠處理更多的複雜性。這是快速成長為高級開發人員的最有效方法之一。 🚨 PS您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/3GJuOjr) 🚨 ## 8. 資深開發人員控制故事 高階開發人員可以做得非常好的一件事是領導技術討論並影響周圍的其他人。無論是業務利害關係人、產品經理或其他開發人員,資深開發人員都知道如何引導他們朝著正確的方向發展。 他們結合自信、技術專長和溝通技巧來做到這一點。 高級開發人員也能夠設定嚴格的界限。 他們可以不同意而不會情緒激動。他們可以在會議期間為自己(和他人)挺身而出。他們積極協商薪資。 他們講述自己的故事。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pd8vutmtz3wbxas13ey1.png) 高級開發人員知道如何以及何時在沙子上劃線並說“夠了”。 如果另一個開發人員在程式碼審查期間開始指責其他人,老年人知道如何阻止他們。如果高階主管試圖介入開發人員的工作並進行微觀管理,高階管理層知道如何在不破壞關係的情況下阻止他們。 沒有關於如何變得更加自信的開發人員的分步指南。 這需要重複和練習。第一步是停止一直說「是」。並開始嘗試在薪資談判中取得進展。 ## 9. 長期思考 初級開發人員考慮“現在”。他們的想法是短期的。當他們走捷徑時,他們的程式碼也是如此。初級開發人員會擴展一段程式碼,而不考慮正確重構它,或乾脆忽略測試和效能。 但青年人也會對自己的職業生涯進行短期思考。 這可能意味著跳槽過多或自毀前程。這可能意味著忽視。 就像不提高你的技能或推銷自己的方式一樣,因為現在你的工作很穩定。只是被解僱六個月後才後悔。 成為更高級的開發人員的一部分是開始進行長期思考。 第一個方法是改變你的心態。大多數初級開發人員的短期思維不是由懶惰引起的,而是由自我懷疑引起的。 他們內心深處仍在思考成為開發人員是否適合他們。或者他們是否選擇了正確的職業。 這些疑慮阻止他們做出長期承諾。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sw1r4ng1hoyigg3e0z6v.png) 好事需要時間,資深開發人員知道這一點並相應地調整他們的想法。 現在,隨著人工智慧威脅到軟體開發的終結,這種短期思維比以往任何時候都更加頻繁。如果某件事很快就會消失,為什麼還要承諾呢? 相信我,只有當我完全致力於我作為開發人員的職業生涯時,事情才開始起飛。 我說:「就是這樣」。 我不再向外張望。我告訴自己:這是我現在的工作,也是我未來十年的工作,所以讓我把它做好吧。 我開始投資我的技能,因為現在我知道它們會得到回報。 即使你未來 20 年不打算寫程式碼,擁有長遠的心態也會為你帶來巨大的好處。高級開發人員之所以能夠達到高級水平,是因為他們致力於自己的技術。如果您渴望實現這一目標,您也應該這樣做。 🚨 PS您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/3GJuOjr) 🚨 ## 10.卓越是一種習慣 我想正是 Kent Beck 說過那句名言:「我不是一個偉大的程式設計師,只是一個有著好習慣的好程式設計師」。習慣很重要,因為它們經得起時間的考驗。 因為您擁有的任何關於 JavaScript 框架的知識遲早都會過時。技術變革。但你的習慣將永遠伴隨你。 好訊息是人類是習慣的動物。 在我們的大腦中設定新的慣例並不容易。 但一旦我們將它們內化為習慣,我們就很容易堅持下去。利用這一點的最佳方法是實現您的任何目標並將其分解為日常行動。然後透過重複將這些行為變成習慣。 例如,如果您想更好地進行測試,請每天編寫一個單元測試。 如果您想在日常會議中做好更多準備並清晰思考,請寫日記。如果你想找到一份新的開發人員工作,並且你必須發送 100 份申請,那麼每天發送 10 份申請。 養成新的習慣,你向高級水準的進步將持續且穩定。 ## 11. 保護您最重要的資產 身為高階開發人員意味著不僅要長遠考慮您的程式碼和技術決策,還要考慮您的健康。 因為健康就是財富。 我在影片中一次又一次地談論這一點。 開發人員的工作需要久坐。您一天的大部分時間都坐在電腦前的椅子上。這對你的健康非常不利。 然後,辦公室裡到處都是垃圾食品,像是薯條、汽水和糖果。這意味著除非您有意識地努力,否則您將很難保持健康和體形。 但如果你想擁有一個長期而富有成效的軟體編寫職業,並且不想最終出現背部問題、糖尿病,甚至更糟糕的情況,那麼你需要開始照顧自己的健康。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fsdohne0ydvireyloigf.png) 欲得金蛋,勿殺鵝。如果你想提高工作效率,首先要照顧好自己。 這並不意味著您必須開始每週去健身房 5 次。 或進行一些瘋狂的節食。但每周至少2至3次運動。您可以去健身房、跑步或參加團隊運動。現在我正在做 在飲食方面,減少糖和精緻碳水化合物的攝取。肉也不要過量。 也要考慮您的心理健康。 忽略諸如「吃飯、睡覺、編碼、重複」之類的建議,在工作之外建立自己的生活。 開始一個新的嗜好。聯繫朋友。休息一下。 從短期來看,你的進步可能會慢一些。但從長遠來看,你將能夠在遊戲中停留更長時間。 🚨 PS您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/3GJuOjr) 🚨 ## 12. 閉合圓圈 最後,資深開發人員了解業力是如何運作的。他們知道,無論他們多麼努力,或者多麼聰明,在他們走向頂峰的道路上,都有數十個人的幫助。 這並沒有剝奪他們的優點,但也承認其他人。 所以他們關閉了這個圈子。 他們幫助其他開發人員。他們這樣做是沒有期望的。 不是因為它可能會讓你升職。或是地位,或是仰慕。他們這樣做是因為這是正確的事。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urp75psyn2lz8oah3cq7.png) 甚至科比·布萊恩也抽出時間來指導年幼的孩子並讓他們進入籃球領域。您也可以抽出時間來幫助新開發人員。 幫助剛起步的人會帶給你部分火花。初學者第一次看到事物時所感受到的熱情和好奇心是如此具有感染力。 另一件你可以變成日常習慣的事情! 好的,就是這樣。具備這 12 個特徵,您將快速成長到高級甚至更高級別。 --- 原文出處:https://dev.to/dragosnedelcu/12-senior-developer-traits-junior-developers-need-to-master-285m

2024 年您必須嘗試的 25 個 Web 開發專案

毫無疑問,掌握 Web 開發最有效的方法之一就是透過實作。雖然學習理論概念很重要,但將您的知識應用到現實世界的專案中才能真正鞏固您的技能。無論您是想要打下堅實基礎的初學者,還是尋求新挑戰的經驗豐富的開發人員,這裡有 25 個 Web 開發專案可以提高您的能力。 ### 學生成績管理系統 學生成績管理系統旨在為學生和大學提供一種快速且用戶友好的方式來存取和管理考試成績。學生可以登入查看他們的成績,新生可以選擇註冊。該系統旨在以易於理解的方式呈現結果。 **如何做:** 掌握前端、後端和資料庫程式設計的基礎知識後,從建立全端應用程式開始。利用HTML、CSS、JavaScript、PHP和MySQL實現使用者認證、結果顯示和註冊功能。 ![學生成績管理系統](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4y9a2bm1exqbu34lsxph.png) ### 線上程式碼編輯器(React) 該專案涉及使用 React 建立線上程式碼編輯器,允許使用者用各種程式語言編寫和執行程式碼。目標是建立一個用戶可以無縫編輯和測試原始程式碼的平台。 **如何做:** 先使用 HTML、CSS 和 React 進行前端工作。實現程式碼輸入、執行和結果顯示功能。專注於建立用戶友好的介面,以獲得流暢的程式碼編輯體驗。 ![線上程式碼編輯器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06jjz3v5sq7c6apc41d7.png) ### 使用 React 進行 Amazon 克隆 Amazon Clone 專案圍繞著使用 React 建立 Amazon 線上商店的工作副本。該專案將幫助您了解有效的電子商務網站所需的元件並將它們應用到您的應用程式中。 **如何做:** 從 HTML、CSS 和 JavaScript 開始。使用 React 建立電子商務網站的不同部分,例如產品清單、購物車和結帳流程。整合動態資料並增強使用者介面。 ![使用 React 的 Amazon 克隆](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pq55ml71nqntt4j07p1z.png) ### 客戶關係經理 客戶關係管理器專案涉及建立一個後端 Web 應用程式,該應用程式允許建立、讀取、更新和刪除 (CRUD) 客戶資料。這是了解後端 Web 開發的基礎專案。 **如何做:** 利用 Node.js、Express.js 和 MongoDB 等技術來建立後端基礎架構。實施 CRUD 操作來管理客戶資料。開發一個用戶友好的介面,用於與客戶資料庫互動。 ![顧客關係經理](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jfr25p8b2gzapen1l8ry.png) ### 排序展示台 排序可視化器專案旨在提供各種排序演算法的可視化表示。使用者可以觀察不同的演算法如何執行,並更深入地了解 JavaScript 的基本概念。 **具體操作方法:** 使用 HTML、CSS、Bootstrap 和 JavaScript 建立 Web 應用程式。實現冒泡排序、合併排序和快速排序等排序演算法的視覺化。允許用戶與視覺化進行交互,以增強他們的學習體驗。 ![排序視覺化工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51wpf82samc6k9ggftgc.png) ### 多人遊戲 – Connect4 多人遊戲 – Connect4 專案專注於建立具有多人遊戲功能的著名 Connect4 遊戲。它提供了學習一些重要的網路和遊戲設計基礎知識的機會。 **如何做:** 如果您想知道多人遊戲是如何開發的,或者您曾經想為週末製作一款遊戲,那麼這個專案適合您。使用 PyGame、Sockets 和遊戲編程為您和您的朋友建立多人 Connect4 遊戲。 ![多人遊戲 – Connect4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ktsz3ky4pj27b9q7mynm.png) ### YouTube 腳本摘要器 投入時間觀看可能比預期更長的電影變得相當具有挑戰性。有時,如果我們不能從他們那裡收集有用的訊息,我們的努力可能會徒勞無功。透過自動總結影片的文字記錄,我們可以輕鬆地發現這些影片中的關鍵主題,這節省了我們再次觀看整個影片的時間和精力。 **如何做到這一點:** 人們每天都會觀看 YouTube 影片,這些影片可以是指導性的、紀錄片的或任何其他持續時間較長的類型;考慮透過提供摘要資訊可以節省多少時間。該專案將是一個 chrome 擴展,它將向後端的 Rest API 發送請求,該 API 將向您發送 YouTube 腳本的摘要。 ![YouTube 腳本摘要](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4kw614tpyvyrumjc1g8.png) ### OurApp – NodeJS 中的社交媒體 Web 應用程式 現實應用程式 OurApp 的用戶可以進行交流、相互關注以及發布簡短的推文。掌握 HTML、CSS 和 JS 後,專案最適合想要使用 Nodejs 和 MongoDB 深入研究完整堆疊的人。 **怎麼做:** 你想成為能夠超越 HTML、CSS 和 JS 的全端開發人員嗎?建立這個完整的堆疊應用程式,以了解如何使用 NodeJS、MongoDB 和其他技術來建立現代、快速且可擴展的伺服器端 Web 應用程式。如果您想在磨練 NodeJS 技能的同時開發一些有趣的東西,那麼這個專案就是適合您的。您還可以免費註冊全端 Web 開發課程,這將幫助您成為您所在領域的傑出開發人員。 ![OurApp – NodeJS 中的社交媒體 Web 應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/02qifmojncuvx27k6hyu.png) ### Codechef 通知 CodeChef 經常遇到伺服器過載問題,導致評審難以快速提供提交結果。留給編碼人員的唯一選擇是在一段時間後不斷檢查站點,看看結果是否存在。透過這個專案,我們希望消除審查提交頁面以確定提交結果的額外步驟。我們將自動執行檢索結果的過程並在準備好後立即通知使用者。 **如何操作:** Codechef 是一個流行的編碼實踐平台,但伺服器過載可能會導致結果延遲。此附加元件旨在透過自動化獲取結果並及時通知用戶的流程來節省時間。使用網路抓取或 API 來收集結果資訊並實作通知系統。 ![Codechef 通知程序](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4k7ru3ff3h7tgne8qpoi.png) ### 使用 Dash 來視覺化和預測股票 該專案涉及使用 Dash(一種用於建立分析 Web 應用程式的 Python 框架)來視覺化和預測股票資料。它提供了將資料視覺化和機器學習概念應用於金融資料的機會。 **如何操作:** 如果您對股票市場感興趣,該專案將簡化股票資料的可視化。利用Python、Dash和相關函式庫進行資料視覺化。實施基於歷史資料預測股票趨勢的功能。 ![使用 Dash 視覺化和預測股票](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovs08g50etufj84gz6fd.png) ### 線上程式碼編輯器 (JQuery) 線上程式碼編輯器可透過瀏覽器存取,並位於遠端伺服器上。儘管一些線上程式碼編輯器更像是完整的 IDE,但其他編輯器更像是具有語法突出顯示或程式碼完成等基本功能的文字編輯器。 **如何操作:** 使用 HTML、CSS、JavaScript 和 JQuery 建立線上程式碼編輯器。專注於透過語法突出顯示和程式碼完成等功能來增強使用者體驗。確保程式碼輸入和執行順利。 ![線上程式碼編輯器 (JQuery)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1vxgxvbtf1rh578lauc.png) ### 模糊URL FuzzyURLs 涉及使用 Django(Python 的高級 Web 框架)建立 URL 縮短服務。它提供了建立 Web 應用程式的實務經驗,特別關注 URL 操作。 **如何做:** 從頭開始開發一個基於 Django 的 URL 縮短器。了解 URL 縮短服務的工作流程並實現建立、管理和重新導向短 URL 的功能。 ![FuzzyURLs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uouta53v2suc8m27i14.png) ### 使用 React 進行 Slack 克隆 該專案旨在使用 React 建立 Slack 克隆,提供即時訊息和協作的平台。這是一個中高階專案,強調React-Redux和Firebase。 **如何做:** 應用 React-Redux 原理來建立一個類似 Slack 的 Web 訊息服務。利用 Firebase 實現即時資料庫功能。專注於建立響應靈敏且功能豐富的訊息傳遞應用程式。 ![使用 React 的 Slack 克隆](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kugsfjeblq934ceomlhs.png) ### Web 應用程式的 Node.js 驗證 了解使用 Node.js 為 Web 應用程式建立驗證系統。探索各種身份驗證技術,評估其優點和缺點,並實施改進。 **如何做:** 對於那些想要深入研究 Node.js 並了解建立安全身份驗證系統的複雜性的人來說,這個專案非常適合。實施使用者身份驗證、會話管理並探索增強安全性的方法。 ![Web 應用程式的 Node.js 驗證](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fcet0kd7abf6xu57eh8.png) ### TinyMCE 同義詞插件 為 TinyMCE 富文本編輯器建立一個插件,用於搜尋單字的同義詞並允許使用者將它們插入編輯器中。 **如何做到這一點:** 為 TinyMCE 開發一個自訂插件,整合一項功能,使用戶能夠搜尋同義詞並輕鬆地將它們插入到富文本編輯器中。了解 TinyMCE API 以實現無縫整合。 ![TinyMCE 同義詞外掛](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nmr8y3x21l9g7vuwz5mi.png) ### 迷宮裡的老鼠 建立一個基本的 React Web 應用程式,顯示老鼠從帶有預設障礙的方形迷宮的左上角到右下角可以採取的所有可能路徑。 **具體操作方法:** 建立一個簡單的 React Web 應用程式來直觀地呈現經典的 Rat in the Maze 謎題。實施功能來展示老鼠穿過迷宮的所有潛在路徑。 ![迷宮中的老鼠](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdcwf4cioua8fogrsp96.png) ### 簡歷產生器 Web 應用程式 使用 ReactJS 和 NodeJS 建立一個用於建立履歷的 Web 應用程式。該專案將指導您完成建立簡歷產生器的步驟,並提供一種實用的方法來支援個人製作簡歷。 **如何做:** 深入研究 ReactJS 和 NodeJS 來開發一個用戶友好的簡歷產生器。實施加入個人詳細資訊、教育背景、工作經驗和技能的功能。專注於建立動態且可自訂的履歷模板。 ![簡歷產生器 Web 應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntwflc67s9kwi00plrti.png) ### Markdown 編輯器 建立一個 Markdown 編輯器,讓使用者編寫 Markdown 並預覽渲染的 HTML。 Markdown 是一種基於網路的文字格式化系統,廣泛用於部落格文章、文件等。 **如何做:** 使用 HTML、CSS 和 JavaScript 開發 Markdown 編輯器。使用戶能夠編寫 Markdown 程式碼並查看渲染的 HTML 的即時預覽。使用粗體文字、圖像和清單等功能增強編輯器。 ![Markdown 編輯器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppv6gl6pzq7uetmkax5b.png) ### 450 DSA 追蹤器 450 DSA Tracker 旨在協助使用者追蹤解決 450 道資料結構和演算法問題的進度。它利用 TypeScript、React.js 的 reducer 和 context API 以及即時瀏覽器 IndexedDB 來快取資訊。 **具體操作方法:** 使用 TypeScript 和 React.js 實作 Web 應用程式,以追蹤解決資料結構和演算法問題的進度。利用reducer 和context API 進行狀態管理,並利用IndexedDB 進行即時瀏覽器快取。 ![450 DSA 追蹤器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijhv2y4gx3f1l2ub7xnz.png) ### 待辦事項網頁應用程式 使用 Node.js 框架 Adonis.js 建立待辦事項 Web 應用程式。了解 HTTP、REST API 和 CRUD 操作,同時建立用於管理待辦事項清單的後端 API。 **如何操作:** 使用 Adonis.js 為待辦事項 Web 應用程式建立 CRUD API。使用 Postman 測試 API 並建立用於新增、更新和刪除任務的後端功能。獲得使用後端框架的經驗。 ![待辦事項 Web 應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rajw8titifncb6la3e6.png) ### 兩個真相和一個謊言遊戲 Slack 機器人 開發一個 Slack 機器人,用於在 Slack 工作區中玩「兩個真相和一個謊言」遊戲。該專案利用 JavaScript 和 Node.js 為工作區成員建立一個有趣的互動式遊戲。 **如何做:** 建立一個 Slack 機器人,以促進「兩個真相和一個謊言」遊戲。使用 JavaScript 和 Node.js 處理 Slack 工作區中的互動。實現用戶共享陳述並猜測哪一個是錯誤的功能。 ![兩個真相與一個謊言遊戲 Slack 機器人](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kwocawujfx0219s6ho5c.png) ### 使用 Chromakey(綠幕)效果進行即時視訊處理 探索視訊處理中使用的色度(綠幕)效果。使用 HTML、CSS 和 JavaScript 建立 Web 應用程式,以背景影片或圖像取代綠幕。 **具體操作方法:** 開發一個處理即時視訊並應用色鍵效果的 Web 應用程式。使用 HTML、CSS 和 JavaScript 操作影片幀並用背景影片或圖像替換綠幕。 ![使用 Chromakey(綠幕)效果進行即時視訊處理](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4yc5aauy13cthc6b2b3.png) ### WhatsApp 網頁克隆 使用 React 和 Firebase 開發具有即時訊息功能的 WhatsApp Web 克隆。 **如何操作:** 使用 React 建立使用者介面並使用 Firebase 實現即時資料庫功能,打造流暢的訊息體驗。 ![WhatsApp 網路克隆](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggf6mpl4bssvzjrr97b3.png) ### WhatsApp 上的電子郵件提醒 設定新電子郵件的 WhatsApp 提醒以簡化電子郵件管理和通知。 **如何操作:** 使用自動化平台 Twilio 建立一個工具,從收件匣中獲取詳細資訊並在 WhatsApp 上發送警報。 ![WhatsApp 上的電子郵件提醒](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2zxhacxpysrlx2d78sb5.png) ### 天氣預報應用程式 使用 Streamlit 函式庫和 OpenWeatherMap API 為天氣預報應用程式建立響應式前端。 **如何操作:** 利用 Python 和 Streamlit 可視化天氣資料並與 OpenWeatherMap API 互動以獲取即時天氣資訊。 ![天氣預報應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwm38a5vw8sj2iu17y57.png) ### 總結 這個 Web 開發專案的彙編提供了各種各樣的挑戰,使您能夠提高跨不同技術和概念的技能。無論您對全端開發、資料視覺化、遊戲設計還是自動化感興趣,這些專案都可以提供有價值的幫助 --- 原文出處:https://dev.to/mukeshkuiry/25-web-development-projects-you-must-work-on-2024-4onl

為什麼我不推薦 Robert C Martin 的《Clean Architecture》

*乾淨的架構*在許多方面都未能滿足我的期望。儘管 Martin 先生對這個主題表現出明顯的熱情,但「清潔架構」組織得很差,缺乏範例,並且對使用現有系統保持沉默。作者錯過了一個重要的機會來教導我們何時以及如何將這些經驗教訓應用到我們自己的系統中。讓我解釋。 ### *乾淨的架構*是一本組織得很差的書 這本書需要很長時間才能開始。關於設計範式(結構化、物件導向和函數式)的章節似乎特別不合時宜且不必要。 關於 SOLID 原則的章節很好。我很高興看到這些原則被分解並得到很好的解釋。我發現思考它們對系統架構的適用性很有趣。但鮑伯叔叔提出了諸如硬性規則之類的堅實原則,這讓我感到不舒服。事實上,我非常確定一個***從未***違反 SOLID 原則的系統將是一個巨大的混亂。 然而,第 137 頁的這一段很重要: >架構的主要目的是支援系統的生命週期。良好的架構使得系統易於理解、易於開發、易於維護、易於部署。最終目標是最小化系統的生命週期成本並最大化程式設計師的生產力。 這是一個很好的觀察。叔叔鮑伯為什麼不把它放在第一章呢? ### 例子不夠多 本書中幾乎沒有任何例子。第 33 章包含一個討論影片銷售電子商務應用程式的範例。沒關係。但我並沒有明確地知道如何將這些概念應用到我自己的系統中。 附錄講述了 Bob 叔叔如何提出 SOLID 原則和乾淨架構規則的故事。它載有過去專案的範例。我認為這是本書**最有趣的部分**。 ### 這本書沒有提到改進現有系統的架構 大多數開發人員將大部分時間花在現有系統上。因此,我期望 *[Clean Architecture](https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164/)* 充滿有關改進現有系統的建議。但這本書在這個問題上顯然隻字不提。 ### 如何建立一個乾淨的架構? 在本書的前半部分中,您將了解如何透過遵循 SOLID 原則將系統沿系統邊界分解為元件來建立一個乾淨的架構(我是這樣解釋的)。如果你停止閱讀那裡,你可能會有這樣的印象:叔叔鮑伯不會批准你為建築所做的一切,這是可以理解的。如果你認為他提出的幾個選項是「正確」的做事方式,這也是情有可原的。然而,在本書的最後,您將在第 228 頁讀到: >這個例子旨在顯示架構邊界無所不在。作為建築師,我們必須小心地辨識何時需要它們。我們也必須意識到,如果完全實施這些邊界,其成本是昂貴的。 >同時,我們必須認識到,當這些邊界被忽略時,即使存在全面的測試套件和重構規則,以後加入它們的成本也會非常昂貴。 >那我們建築師該怎麼辦?答案令人不滿意。一方面,多年來,一些非常聰明的人告訴我們,我們不應該預見抽象的需要。這就是 YAGNI 的哲學:“你不會需要它。”這句話充滿智慧,因為過度設計往往比設計不足更糟。另一方面,當您發現確實需要一個不存在的架構邊界時,加入這樣一個邊界的成本和風險可能會非常高。 >所以你已經得到它了。軟體架構師啊,你必須看見未來。你必須聰明地猜測。您必須權衡成本並確定架構邊界在哪裡,哪些應該完全實現,哪些應該部分實現,哪些應該被忽略。 因此,在本書的一半以上,他說應該由我們來決定我們的系統的邊界在哪裡。這種界限可能無所不在。令人困惑,對吧? ### 這本書缺少什麼 因此,如果軟體架構的最終目標是最小化系統的生命週期成本,那麼一本關於架構的書不應該幫助架構師做出這些決策嗎? #### 未解答的問題 這本書給我留下了很多未解答的問題。各種選擇的經濟學討論在哪裡?如何找到最適合我的系統的架構?研究在哪裡? ![未解答的問題](https://thepracticaldev.s3.amazonaws.com/i/fll25irsu1xbd0268kq2.jpg) 我該如何決定水平分層、垂直切片或其他方式是否可以最大限度地降低系統的生命週期成本?或者,如果我沒有明確定義的層,我該如何決定哪種分層策略(如果有)可以最大限度地降低我的生命週期成本? 我還有更多問題。如果您改進現有系統架構的時間有限,您應該把精力放在哪裡?將資料庫與業務邏輯分開總是一個好主意嗎?您應該始終遵循哪些建議?哪些建議取決於系統? #### 讓*乾淨的架構*更有價值的細節 在*[Code Complete](https://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/)*中,Steve McConnell 討論了不同非功能性需求(例如可靠性、可靠性)之間的權衡、正確性、可維護性、可讀性等。他解釋了一些需求如何協調一致而另一些需求如何衝突。我很樂意看到類似的東西用於本書中討論的架構決策。 在*清潔架構*中,專案規模、團隊規模、專案失敗的後果、預期程式碼生命週期和其他重要因素作為架構的驅動因素沒有得到足夠的重視。例如,Healthcare.gov 需要比您正在開發的個人待辦事項清單更多的架構,即使它們都是由資料庫支援的 Web 應用程式。 ### 這本書的真正內容是什麼 本書的大部分內容我都感到有些困惑。我有點明白叔叔鮑伯想說什麼。但直到讀了附錄才完全明白。那麼,讓我為您節省一些時間。 #### 一個例子 想像一下您正在為消費市場建立一台桌上型電腦(例如辦公室電腦)。您可以選擇硬件,然後為整個系統編寫軟體(韌體、作業系統、驅動程式、應用程式等)。 #### 你會寫一個整體嗎? 你會怎樣做呢?您會編寫一個巨大的程式(一個整體),其中電子表格的程式碼知道您為電腦選擇的磁碟類型嗎?您能否想像更新電子表格程式碼並在各處新增「if」語句,以便在您有 SATA 磁碟機時執行一件事,而在有 SCSI 磁碟機時執行另一件事?然後對 VGA、DVI 和 HDMI 視訊做同樣的事情? PS/2 與 USB 滑鼠輸入的不同路徑怎麼樣?然後對文字處理器和您打算與電腦捆綁的所有其他應用程式重複該過程? 維護這將是一場惡夢,對嗎?那麼解決方法是什麼呢?建築學!您的電子表格不應該知道您使用的是哪種滑鼠。也不知道你有什麼樣的顯示器。它應該完全忘記這些細節。 #### 計算機中的邊界 如果您查看計算機,您會發現這一點。您的滑鼠中有嵌入式軟體,可以與作業系統進行通訊。然而,詳細資訊對您的應用程式是隱藏的。您的電子表格接受標準化輸入,而無需知道或關心您使用的滑鼠類型。然後,當有人發明了新的輸入裝置(例如觸控板)時,它會自動與您的電子表格配合使用。 這只是計算機的邊界之一。您可能會想出數百個。您可以指派不同的團隊來處理系統的不同部分。您可以為不同元件互動的各種方式建立或採用不同的規格。 此時你可能會說「呃」。顯然,您不希望每次硬體發生變化時都更改並重新編譯電子表格。維護將是一場惡夢。並且我同意。 #### 邊界是你的朋友(如果你正確使用它們) 很容易看出硬體邊界。但使硬體邊界變得有價值的相同邏輯也適用於軟體邊界。軟體邊界更難看到。 因此,您可以從在螢幕上顯示電子表格的能力開始。但您可能還想將其儲存到磁碟、儲存為 PDF、儲存為 CSV 或列印。因此,電子表格程式的邊界之一可能是擁有代表每個電子表格的內部資料結構。然後將該結構傳遞給不同的程式碼,以所需的格式顯示、儲存或列印它。 如果您讓資料結構完全不知道它是如何顯示、保存或列印的,那麼您可以在以後加入「儲存到 XML」功能,而無需深入研究與電子表格資料結構相關的所有程式碼。如果電子表格資料結構有幾百萬行程式碼,您可以想像這會容易得多。 這就是鮑伯叔叔在本書中試圖告訴我們的全部。 **您可以使用 SOLID 原則在系統中建立邊界,隱藏實作細節、降低複雜度並幫助您降低系統的總生命週期成本**。 ### 一本更好的軟體架構書 在許多方面,Martin Fowler 的*[企業應用程式架構模式](https://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/)* 遠遠優於*清潔架構* 。 Fowler 描述了他在企業應用程式中反覆觀察到的模式。他給出了每個模式的簡單範例,描述了它的工作原理以及在何處使用它。我發現“企業應用程式架構模式”非常可讀並且適用於我的系統。 ### 要點 *乾淨的架構*中有有價值的訊息,但你必須努力找到它。 我發現有關嵌入式軟體的章節是最容易理解的章節之一。直觀上,避免在整個程式碼庫中分散低階呼叫是有意義的。在沒有硬體的情況下使邏輯可測試也是有意義的(特別是因為嵌入式軟體通常是在硬體可用之前開發的)。如果您只能閱讀本書的兩章,我建議您閱讀這一章和附錄,無論您以編寫哪種軟體為生。 總的來說,《乾淨的架構》是一本很難讀的書,鮑伯叔叔留給我的問題比答案還多。我絕對不會推薦這本書作為您關於軟體架構的第一本書(請查看*[企業應用程式架構模式](https://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/ )* 由馬丁·福勒取代)。 *同意還是不同意。我很想聽聽你的想法。* *喜歡這篇文章嗎?請在下面“喜歡”它。* --- 原文出處:https://dev.to/bosepchuk/why-i-cant-recommend-clean-architecture-by-robert-c-martin-ofd

我寫出易讀程式碼的 3 個原則

多年來圍繞著評論存在著許多爭論。許多人堅持認為“好的程式碼會自我註釋”,而其他人則贊成在程式碼中包含好的註釋,並認為應該需要它們。當我閱讀和聽到這些爭論時,我注意到他們經常關注程式碼的*什麼*和*如何*......即。程式碼*做什麼*,以及*如何*做到這一點。但「為什麼」的概念很少進入討論…即。 *為什麼*需要這段程式碼,或是*為什麼*要這樣寫。儘管雙方都有有效的論據,但很難知道該往哪個方向走。這促使我建立了 3 條規則,我相信這不僅有助於彌合兩者,而且還能鼓勵編寫更好的程式碼。我想與您分享我的 3 條規則,希望它們能像我一樣對您有所幫助。 ## 規則 1:名稱要解釋*什麼* ![一個抽象的人形機器人思考著頭上有問號的東西](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uj8crlt54k76jri1b0f7.png) 程式碼中的變數、參數、介面、函數、類別、方法或其他「事物」的名稱應提供足夠的訊息,以清楚地描述該事物的「什麼」功能或它所具有的「什麼」值。另一個開發人員應該能夠在幾週或幾個月後讀取該事物的名稱,並準確地知道它的功能或它所擁有的內容,而無需詢問、查看額外的程式碼或閱讀額外的文件。如果這樣做,則應更改名稱以使其更清晰。 為了在這裡澄清一點,重要的是要注意名稱不負責描述某些東西的“用途”。名稱僅負責描述該事物的“做什麼”,或該事物所具有的“什麼”價值。 讓我們來看一些我個人遇到的例子來幫助澄清這一點: ``` const derivatives = []; ``` 只知道這個名字,你就能知道這個陣列裡會保存什麼樣的資料嗎?顯然它包含了從其他東西複製或改編的東西......但是這些資訊足夠嗎?試著退一步思考,如果您在正在編寫的某些程式碼中遇到此問題,您會問自己或其他人甚麼樣的問題。 ``` function name(user) { // ... } ``` 這裡我們有一個函數正在執行與用戶名相關的操作...現在,無需閱讀其他程式碼或向某人詢問更多上下文,您能說出這個函數的作用嗎? 當我遇到這個問題時,我必須查看更多程式碼才能弄清楚它做了什麼......在我問“這是否返回名稱?”,“這是否會更新名稱?”或“這是否構造來自其他資料的名字?” 希望您能看到上面的範例不是好名稱,需要更改,因為它們不符合此規則的要求。您將不得不查看更多程式碼或詢問其他人來弄清楚他們做什麼或持有*什麼*。那什麼是更好的名字呢?顯然,我們可以使用很多不同的名稱,但這裡有幾個例子: ``` const derivativeUsers = []; ``` 透過這個更新後的名稱,我們現在可以知道該陣列將容納一定數量的從其他陣列複製或改編的用戶。無需閱讀額外的程式碼或詢問其他人。哈札! ``` function getFullName(user) { // ... } ``` 在這裡,我們更改了函數的名稱,以更清楚地說明該函數的*什麼*功能。透過這個簡單的更新,我們現在知道該函數傳回傳遞給它的使用者的全名。 因此,總結第一條規則,您在程式碼中命名的任何內容都應該清楚地描述該事物的*什麼*,或*什麼*值(如果成立)。這可能會讓你的名字變得更冗長一些,但在我個人看來,如果更冗長一點意味著程式碼對你和團隊來說更具可讀性和可維護性,那麼這是值得付出的代價。 ## 規則 2:程式碼應解釋*如何* ![一個人坐在辦公桌前寫下某件事是如何完成的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pomudgtas0bt8drlh3wc.png) 雖然事物的名稱告訴了它“做什麼”,但它內部的程式碼應該描述它“如何”做到這一點。現在,這可能聽起來有點明顯,但它帶來了一些您必須考慮的事情。 為了讓其他人理解程式碼「如何」執行某些操作,它必須具有可讀性和可理解性。如果沒有人能夠理解執行*操作*的程式碼,那麼它的好處就會少很多。其中一部分來自於組成程式碼的各個部分的命名。但有助於程式碼可讀和理解的其他因素包括簡單性、組織和結構、格式和樣式,僅舉幾例。 這是一個很大的話題,有很多關於它的文章、書籍和課程,所以我不會在這裡討論太多細節。只需要知道,編寫乾淨的程式碼是編寫可讀且可理解的程式碼的一個非常重要的部分,它可以讓團隊的其他成員知道「如何」某件事是如何做到的。 另一個難題是模組化。如果某個東西很小並且只做一件事,那麼理解它是如何做的就容易多了。您可能在您的職業生涯中以某種形式聽說過這個概念。也許您熟悉單一職責原則,即 [SOLID 原則] 中的「S」(https://www.goodreads.com/book/show/25936819-design-principles-and-design-patterns) 。如果您還不熟悉,我強烈建議您研究一下,因為它是軟體開發領域的重要概念。但回到正題。如果一個函數、類別、方法、元件或其他任何東西執行不只一件事,則程式碼的複雜性會急劇增加,並且不僅辨識*如何*它是如何做到的,而且隨著時間的推移,維護它也會變得更加困難。 因此,為了使您的程式碼符合第二條規則,您或團隊的其他成員必須在幾個月後能夠理解它。他們應該能夠查看某些“事物”的程式碼,並能夠輕鬆辨識它“如何”執行其功能。為了實現這一點,我們必須編寫乾淨、可讀、可理解的程式碼。 ## 規則 3:評論應該解釋*為什麼* 最後,當需要更多資訊時,當我們需要了解「什麼」和「如何*」之外的內容時,我們需要「為什麼」…這就是評論來拯救世界的地方。當我們編寫程式碼時,有時我們需要傳遞更多訊息,例如「為什麼」做出決定、「為什麼」需要一段程式碼或與之相關的一些其他上下文。這些都是應該評論的事情。 在編輯不是立即顯而易見的特定程式碼區塊時,可能需要考慮一些晦澀的用例。這應該被清楚地註釋,這樣當下一個開發人員下週、下個月甚至明年返回這段程式碼時,他們也會考慮到這些訊息,而不是重新引入一些錯誤,或破壞其他一些部分的功能。 也許由於某些第三方依賴項的工作方式,必須在程式碼的特定區域執行一些不「正常」的操作。與其期望團隊的其他成員遇到同樣的問題並必須自己解決,不如對情況進行評論,以節省他們以後的時間(可能是幾個小時甚至幾天)。 理解「為什麼」某件事以這種方式完成可以提供巨大的洞察力,特別是當有多種路徑可供選擇時,或者如果存在影響決策的間接背景。在我個人看來,評論“為什麼”不僅僅是程式碼中的“很好”,而且至關重要。它對於可維護性、知識共享至關重要,最重要的是對於幫助團隊其他成員成功至關重要。 知道何時應包含“為什麼”有時可能很困難。大多數人,包括我自己,都忘記了我們擁有別人所沒有的知識和理解。我們在生活中假設或期望其他人要么知道這些東西,要么很容易弄清楚……即使我們花了幾個月的時間收集不同的資訊來獲得這些知識。因此,當您編寫下一段程式碼時,請真正退一步思考一下,您認為下一個開發人員將擁有哪些資訊來理解它?然後,在評論中寫下這些內容。 ## 結論 嗯,就是這樣…保存程式碼的 3 個簡單規則。因此,下次當您在流程中編寫下一個重要功能時,請嘗試記住... 1. 命名應該解釋您的程式碼的*什麼*功能。 2. 程式碼本身應該是可讀且易於理解,以便您和其他人可以輕鬆辨識它*如何*執行它正在執行的操作。 3. 使用註解提供所有額外訊息,以便每個人都知道*為什麼*程式碼是這樣編寫的。 希望這3條規則對你的職涯有幫助!下次見,駭客快樂! --- 原文出處:https://dev.to/wraith/my-3-rules-for-documenting-code-2f54

使用 javascript 設定 CSS 樣式

假設你有一個段落。 ``` <p id="target">rainbow 🌈</p> ``` 你需要用JS改變它的顏色。你有什麼選擇? ## 1. 內聯樣式 最直接的路徑。從 DOM 查詢元素並變更其內聯樣式。 ``` document.getElementById('target').style.color = 'tomato'; ``` ![內聯樣式](https://thepracticaldev.s3.amazonaws.com/i/hd67z2je0m8u7zyf7231.jpg) 簡短而簡單。 ## 2. 全域樣式 另一種選擇是建立 `<style>` 標籤,用 CSS 規則填充它並將標籤附加到 DOM。 ``` var style = document.createElement('style'); style.innerHTML = ` #target { color: blueviolet; } `; document.head.appendChild(style); ``` ![全域樣式](https://thepracticaldev.s3.amazonaws.com/i/zhkm5phjflfick5xesu2.jpg) ## 3. CSSOM 插入規則 第三種選擇鮮為人知。我們將使用 [CSSStyleSheet](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet) `insertRule` 方法。 ``` var style = document.createElement('style'); document.head.appendChild(style); style.sheet.insertRule('#target {color: darkseagreen}'); ``` 雖然它可能看起來與第二個選項相似,但它絕對不同。 ![插入規則](https://thepracticaldev.s3.amazonaws.com/i/trjxmsf01o01w8c7u224.jpg) 正如您在 Chrome 開發工具中看到的那樣,“<style>”標籤為空,但樣式(深海綠顏色)已應用於該元素。此外,顏色無法透過開發工具更改,因為 Chrome 不允許[編輯動態 CSS 樣式](https://bugs.chromium.org/p/chromium/issues/detail?id=387952)。 其實這樣的行為才是寫這篇文章的動機。由於性能原因,流行的 CSS-in-JS 庫 [Styled Components](https://www.styled-components.com/) 使用此功能在生產模式下注入樣式。在特定專案或環境中,此功能可能不受歡迎,有些人在專案問題中抱怨它。 ## 4.可建構樣式表(2019 年 7 月更新) 現在可以從 JavaScript 建立 `CSSStyleSheet` 物件。 ``` // Create our shared stylesheet: const sheet = new CSSStyleSheet(); sheet.replaceSync('#target {color: darkseagreen}'); // Apply the stylesheet to a document: document.adoptedStyleSheets = [sheet]; ``` 更多詳細資訊請參閱[此處](https://developers.google.com/web/updates/2019/02/constructable-stylesheets)。 此選項僅對 Chrome 有效,因此請謹慎使用。 您知道使用 javascript 新增樣式的其他選項嗎?這些天你的首選選擇是什麼? 謝謝閱讀! --- 原文出處:https://dev.to/karataev/set-css-styles-with-javascript-3nl5