🔍 搜尋結果:CD

🔍 搜尋結果:CD

✨ 用您的文件訓練 ChatGPT 🪄 ✨

# 簡介 ChatGPT 訓練至 2022 年。 但是,如果您希望它專門為您提供有關您網站的資訊怎麼辦?最有可能的是,這是不可能的,**但不再是了!** OpenAI 推出了他們的新功能 - [助手](https://platform.openai.com/docs/assistants/how-it-works)。 現在您可以輕鬆地為您的網站建立索引,然後向 ChatGPT 詢問有關該網站的問題。在本教程中,我們將建立一個系統來索引您的網站並讓您查詢它。我們將: - 抓取文件網站地圖。 - 從網站上的所有頁面中提取資訊。 - 使用新資訊建立新助理。 - 建立一個簡單的ChatGPT前端介面並查詢助手。 ![助手](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ekre38der95twom33tqb.gif) --- ## 你的後台工作平台🔌 [Trigger.dev](https://trigger.dev/) 是一個開源程式庫,可讓您使用 NextJS、Remix、Astro 等為您的應用程式建立和監控長時間執行的作業!   [![GiveUsStars](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bm9mrmovmn26izyik95z.gif)](https://github.com/triggerdotdev/trigger.dev) 請幫我們一顆星🥹。 這將幫助我們建立更多這樣的文章💖 --- ## 讓我們開始吧🔥 讓我們建立一個新的 NextJS 專案。 ``` npx create-next-app@latest ``` >💡 我們使用 NextJS 新的應用程式路由器。安裝專案之前請確保您的節點版本為 18+ 讓我們建立一個新的資料庫來保存助手和抓取的頁面。 對於我們的範例,我們將使用 [Prisma](https://www.prisma.io/) 和 SQLite。 安裝非常簡單,只需執行: ``` npm install prisma @prisma/client --save ``` 然後加入架構和資料庫 ``` npx prisma init --datasource-provider sqlite ``` 轉到“prisma/schema.prisma”並將其替換為以下架構: ``` // This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = env("DATABASE_URL") } model Docs { id Int @id @default(autoincrement()) content String url String @unique identifier String @@index([identifier]) } model Assistant { id Int @id @default(autoincrement()) aId String url String @unique } ``` 然後執行 ``` npx prisma db push ``` 這將建立一個新的 SQLite 資料庫(本機檔案),其中包含兩個主表:“Docs”和“Assistant” - 「Docs」包含所有抓取的頁面 - `Assistant` 包含文件的 URL 和內部 ChatGPT 助理 ID。 讓我們新增 Prisma 客戶端。 建立一個名為「helper」的新資料夾,並新增一個名為「prisma.ts」的新文件,並在其中新增以下程式碼: ``` import {PrismaClient} from '@prisma/client'; export const prisma = new PrismaClient(); ``` 我們稍後可以使用“prisma”變數來查詢我們的資料庫。 --- ![ScrapeAndIndex](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fc05wtlc4peosr62ydnx.png) ## 刮擦和索引 ### 建立 Trigger.dev 帳戶 抓取頁面並為其建立索引是一項長期執行的任務。 **我們需要:** - 抓取網站地圖的主網站元 URL。 - 擷取網站地圖內的所有頁面。 - 前往每個頁面並提取內容。 - 將所有內容儲存到 ChatGPT 助手中。 為此,我們使用 Trigger.dev! 註冊 [Trigger.dev 帳號](https://trigger.dev/)。 註冊後,建立一個組織並為您的工作選擇一個專案名稱。 ![pic1](https://res.cloudinary.com/practicaldev/image/fetch/s--B2jtIoA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdnxq8o7el7t4utvgf1u.jpeg) 選擇 Next.js 作為您的框架,並按照將 Trigger.dev 新增至現有 Next.js 專案的流程進行操作。 ![pic2](https://res.cloudinary.com/practicaldev/image/fetch/s--K4k6T6mi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4kt7e5r1mwg60atqfka.jpeg) 否則,請點選專案儀表板側邊欄選單上的「環境和 API 金鑰」。 ![pic3](https://res.cloudinary.com/practicaldev/image/fetch/s--Ysm1Dd0r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ser7a2j5qft9vw8rfk0m.png) 複製您的 DEV 伺服器 API 金鑰並執行下面的程式碼片段來安裝 Trigger.dev。 仔細按照說明進行操作。 ``` npx @trigger.dev/cli@latest init ``` 在另一個終端中執行以下程式碼片段,在 Trigger.dev 和您的 Next.js 專案之間建立隧道。 ``` npx @trigger.dev/cli@latest dev ``` ### 安裝 ChatGPT (OpenAI) 我們將使用OpenAI助手,因此我們必須將其安裝到我們的專案中。 [建立新的 OpenAI 帳戶](https://platform.openai.com/) 並產生 API 金鑰。 ![pic4](https://res.cloudinary.com/practicaldev/image/fetch/s--uV1LwOH---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ashau6i2sxcpd0qcxuwq.png) 點擊下拉清單中的「檢視 API 金鑰」以建立 API 金鑰。 ![pic5](https://res.cloudinary.com/practicaldev/image/fetch/s--Tp8aLqSa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bzc6e7f7avemeuuaygr.png) 接下來,透過執行下面的程式碼片段來安裝 OpenAI 套件。 ``` npm install @trigger.dev/openai ``` 將您的 OpenAI API 金鑰新增至「.env.local」檔案。 ``` OPENAI_API_KEY=<your_api_key> ``` 建立一個新目錄“helper”並新增一個新檔案“open.ai.tsx”,其中包含以下內容: ``` import {OpenAI} from "@trigger.dev/openai"; export const openai = new OpenAI({ id: "openai", apiKey: process.env.OPENAI_API_KEY!, }); ``` 這是我們透過 Trigger.dev 整合封裝的 OpenAI 用戶端。 ### 建立後台作業 讓我們繼續建立一個新的後台作業! 前往“jobs”並建立一個名為“process.documentation.ts”的新檔案。 **新增以下程式碼:** ``` import { eventTrigger } from "@trigger.dev/sdk"; import { client } from "@openai-assistant/trigger"; import {object, string} from "zod"; import {JSDOM} from "jsdom"; import {openai} from "@openai-assistant/helper/open.ai"; client.defineJob({ // This is the unique identifier for your Job; it must be unique across all Jobs in your project. id: "process-documentation", name: "Process Documentation", version: "0.0.1", // This is triggered by an event using eventTrigger. You can also trigger Jobs with webhooks, on schedules, and more: https://trigger.dev/docs/documentation/concepts/triggers/introduction trigger: eventTrigger({ name: "process.documentation.event", schema: object({ url: string(), }) }), integrations: { openai }, run: async (payload, io, ctx) => { } }); ``` 我們定義了一個名為「process.documentation.event」的新作業,並新增了一個名為 URL 的必要參數 - 這是我們稍後要傳送的文件 URL。 正如您所看到的,該作業是空的,所以讓我們向其中加入第一個任務。 我們需要獲取網站網站地圖並將其返回。 抓取網站將返回我們需要解析的 HTML。 為此,我們需要安裝 JSDOM。 ``` npm install jsdom --save ``` 並將其導入到我們文件的頂部: ``` import {JSDOM} from "jsdom"; ``` 現在,我們可以新增第一個任務。 用「runTask」包裝我們的程式碼很重要,這可以讓 Trigger.dev 將其與其他任務分開。觸發特殊架構將任務拆分為不同的進程,因此 Vercel 無伺服器逾時不會影響它們。 **這是第一個任務的程式碼:** ``` const getSiteMap = await io.runTask("grab-sitemap", async () => { const data = await (await fetch(payload.url)).text(); const dom = new JSDOM(data); const sitemap = dom.window.document.querySelector('[rel="sitemap"]')?.getAttribute('href'); return new URL(sitemap!, payload.url).toString(); }); ``` - 我們透過 HTTP 請求從 URL 取得整個 HTML。 - 我們將其轉換為 JS 物件。 - 我們找到網站地圖 URL。 - 我們解析它並返回它。 接下來,我們需要抓取網站地圖,提取所有 URL 並返回它們。 讓我們安裝“Lodash”——陣列結構的特殊函數。 ``` npm install lodash @types/lodash --save ``` 這是任務的程式碼: ``` export const makeId = (length: number) => { let text = ''; const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; for (let i = 0; i < length; i += 1) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; }; const {identifier, list} = await io.runTask("load-and-parse-sitemap", async () => { const urls = /(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])/g; const identifier = makeId(5); const data = await (await fetch(getSiteMap)).text(); // @ts-ignore return {identifier, list: chunk(([...new Set(data.match(urls))] as string[]).filter(f => f.includes(payload.url)).map(p => ({identifier, url: p})), 25)}; }); ``` - 我們建立一個名為 makeId 的新函數來為所有頁面產生隨機辨識碼。 - 我們建立一個新任務並加入正規表示式來提取每個可能的 URL - 我們發送一個 HTTP 請求來載入網站地圖並提取其所有 URL。 - 我們將 URL「分塊」為 25 個元素的陣列(如果有 100 個元素,則會有四個 25 個元素的陣列) 接下來,讓我們建立一個新作業來處理每個 URL。 **這是完整的程式碼:** ``` function getElementsBetween(startElement: Element, endElement: Element) { let currentElement = startElement; const elements = []; // Traverse the DOM until the endElement is reached while (currentElement && currentElement !== endElement) { currentElement = currentElement.nextElementSibling!; // If there's no next sibling, go up a level and continue if (!currentElement) { // @ts-ignore currentElement = startElement.parentNode!; startElement = currentElement; if (currentElement === endElement) break; continue; } // Add the current element to the list if (currentElement && currentElement !== endElement) { elements.push(currentElement); } } return elements; } const processContent = client.defineJob({ // This is the unique identifier for your Job; it must be unique across all Jobs in your project. id: "process-content", name: "Process Content", version: "0.0.1", // This is triggered by an event using eventTrigger. You can also trigger Jobs with webhooks, on schedules, and more: https://trigger.dev/docs/documentation/concepts/triggers/introduction trigger: eventTrigger({ name: "process.content.event", schema: object({ url: string(), identifier: string(), }) }), run: async (payload, io, ctx) => { return io.runTask('grab-content', async () => { // We first grab a raw html of the content from the website const data = await (await fetch(payload.url)).text(); // We load it with JSDOM so we can manipulate it const dom = new JSDOM(data); // We remove all the scripts and styles from the page dom.window.document.querySelectorAll('script, style').forEach((el) => el.remove()); // We grab all the titles from the page const content = Array.from(dom.window.document.querySelectorAll('h1, h2, h3, h4, h5, h6')); // We grab the last element so we can get the content between the last element and the next element const lastElement = content[content.length - 1]?.parentElement?.nextElementSibling!; const elements = []; // We loop through all the elements and grab the content between each title for (let i = 0; i < content.length; i++) { const element = content[i]; const nextElement = content?.[i + 1] || lastElement; const elementsBetween = getElementsBetween(element, nextElement); elements.push({ title: element.textContent, content: elementsBetween.map((el) => el.textContent).join('\n') }); } // We create a raw text format of all the content const page = ` ---------------------------------- url: ${payload.url}\n ${elements.map((el) => `${el.title}\n${el.content}`).join('\n')} ---------------------------------- `; // We save it to our database await prisma.docs.upsert({ where: { url: payload.url }, update: { content: page, identifier: payload.identifier }, create: { url: payload.url, content: page, identifier: payload.identifier } }); }); }, }); ``` - 我們從 URL 中獲取內容(之前從網站地圖中提取) - 我們用`JSDOM`解析它 - 我們刪除頁面上存在的所有可能的“<script>”或“<style>”。 - 我們抓取頁面上的所有標題(`h1`、`h2`、`h3`、`h4`、`h5`、`h6`) - 我們迭代標題並獲取它們之間的內容。我們不想取得整個頁面內容,因為它可能包含不相關的內容。 - 我們建立頁面原始文字的版本並將其保存到我們的資料庫中。 現在,讓我們為每個網站地圖 URL 執行此任務。 觸發器引入了名為“batchInvokeAndWaitForCompletion”的東西。 它允許我們批量發送 25 個專案進行處理,並且它將同時處理所有這些專案。下面是接下來的幾行程式碼: ``` let i = 0; for (const item of list) { await processContent.batchInvokeAndWaitForCompletion( 'process-list-' + i, item.map( payload => ({ payload, }), 86_400), ); i++; } ``` 我們以 25 個為一組[手動觸發](https://trigger.dev/docs/documentation/concepts/triggers/invoke)之前建立的作業。 完成後,讓我們將保存到資料庫的所有內容並連接它: ``` const data = await io.runTask("get-extracted-data", async () => { return (await prisma.docs.findMany({ where: { identifier }, select: { content: true } })).map((d) => d.content).join('\n\n'); }); ``` 我們使用之前指定的標識符。 現在,讓我們在 ChatGPT 中使用新資料建立一個新檔案: ``` const file = await io.openai.files.createAndWaitForProcessing("upload-file", { purpose: "assistants", file: data }); ``` `createAndWaitForProcessing` 是 Trigger.dev 建立的任務,用於將檔案上傳到助手。如果您在沒有整合的情況下手動使用“openai”,則必須串流傳輸檔案。 現在讓我們建立或更新我們的助手: ``` const assistant = await io.openai.runTask("create-or-update-assistant", async (openai) => { const currentAssistant = await prisma.assistant.findFirst({ where: { url: payload.url } }); if (currentAssistant) { return openai.beta.assistants.update(currentAssistant.aId, { file_ids: [file.id] }); } return openai.beta.assistants.create({ name: identifier, description: 'Documentation', instructions: 'You are a documentation assistant, you have been loaded with documentation from ' + payload.url + ', return everything in an MD format.', model: 'gpt-4-1106-preview', tools: [{ type: "code_interpreter" }, {type: 'retrieval'}], file_ids: [file.id], }); }); ``` - 我們首先檢查是否有針對該特定 URL 的助手。 - 如果我們有的話,讓我們用新文件更新助手。 - 如果沒有,讓我們建立一個新的助手。 - 我們傳遞「你是文件助理」的指令,需要注意的是,我們希望最終輸出為「MD」格式,以便稍後更好地顯示。 對於拼圖的最後一塊,讓我們將新助手儲存到我們的資料庫中。 **這是程式碼:** ``` await io.runTask("save-assistant", async () => { await prisma.assistant.upsert({ where: { url: payload.url }, update: { aId: assistant.id, }, create: { aId: assistant.id, url: payload.url, } }); }); ``` 如果該 URL 已經存在,我們可以嘗試使用新的助手 ID 來更新它。 這是該頁面的完整程式碼: ``` import { eventTrigger } from "@trigger.dev/sdk"; import { client } from "@openai-assistant/trigger"; import {object, string} from "zod"; import {JSDOM} from "jsdom"; import {chunk} from "lodash"; import {prisma} from "@openai-assistant/helper/prisma.client"; import {openai} from "@openai-assistant/helper/open.ai"; const makeId = (length: number) => { let text = ''; const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; for (let i = 0; i < length; i += 1) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; }; client.defineJob({ // This is the unique identifier for your Job; it must be unique across all Jobs in your project. id: "process-documentation", name: "Process Documentation", version: "0.0.1", // This is triggered by an event using eventTrigger. You can also trigger Jobs with webhooks, on schedules, and more: https://trigger.dev/docs/documentation/concepts/triggers/introduction trigger: eventTrigger({ name: "process.documentation.event", schema: object({ url: string(), }) }), integrations: { openai }, run: async (payload, io, ctx) => { // The first task to get the sitemap URL from the website const getSiteMap = await io.runTask("grab-sitemap", async () => { const data = await (await fetch(payload.url)).text(); const dom = new JSDOM(data); const sitemap = dom.window.document.querySelector('[rel="sitemap"]')?.getAttribute('href'); return new URL(sitemap!, payload.url).toString(); }); // We parse the sitemap; instead of using some XML parser, we just use regex to get the URLs and we return it in chunks of 25 const {identifier, list} = await io.runTask("load-and-parse-sitemap", async () => { const urls = /(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])/g; const identifier = makeId(5); const data = await (await fetch(getSiteMap)).text(); // @ts-ignore return {identifier, list: chunk(([...new Set(data.match(urls))] as string[]).filter(f => f.includes(payload.url)).map(p => ({identifier, url: p})), 25)}; }); // We go into each page and grab the content; we do this in batches of 25 and save it to the DB let i = 0; for (const item of list) { await processContent.batchInvokeAndWaitForCompletion( 'process-list-' + i, item.map( payload => ({ payload, }), 86_400), ); i++; } // We get the data that we saved in batches from the DB const data = await io.runTask("get-extracted-data", async () => { return (await prisma.docs.findMany({ where: { identifier }, select: { content: true } })).map((d) => d.content).join('\n\n'); }); // We upload the data to OpenAI with all the content const file = await io.openai.files.createAndWaitForProcessing("upload-file", { purpose: "assistants", file: data }); // We create a new assistant or update the old one with the new file const assistant = await io.openai.runTask("create-or-update-assistant", async (openai) => { const currentAssistant = await prisma.assistant.findFirst({ where: { url: payload.url } }); if (currentAssistant) { return openai.beta.assistants.update(currentAssistant.aId, { file_ids: [file.id] }); } return openai.beta.assistants.create({ name: identifier, description: 'Documentation', instructions: 'You are a documentation assistant, you have been loaded with documentation from ' + payload.url + ', return everything in an MD format.', model: 'gpt-4-1106-preview', tools: [{ type: "code_interpreter" }, {type: 'retrieval'}], file_ids: [file.id], }); }); // We update our internal database with the assistant await io.runTask("save-assistant", async () => { await prisma.assistant.upsert({ where: { url: payload.url }, update: { aId: assistant.id, }, create: { aId: assistant.id, url: payload.url, } }); }); }, }); export function getElementsBetween(startElement: Element, endElement: Element) { let currentElement = startElement; const elements = []; // Traverse the DOM until the endElement is reached while (currentElement && currentElement !== endElement) { currentElement = currentElement.nextElementSibling!; // If there's no next sibling, go up a level and continue if (!currentElement) { // @ts-ignore currentElement = startElement.parentNode!; startElement = currentElement; if (currentElement === endElement) break; continue; } // Add the current element to the list if (currentElement && currentElement !== endElement) { elements.push(currentElement); } } return elements; } // This job will grab the content from the website const processContent = client.defineJob({ // This is the unique identifier for your Job; it must be unique across all Jobs in your project. id: "process-content", name: "Process Content", version: "0.0.1", // This is triggered by an event using eventTrigger. You can also trigger Jobs with webhooks, on schedules, and more: https://trigger.dev/docs/documentation/concepts/triggers/introduction trigger: eventTrigger({ name: "process.content.event", schema: object({ url: string(), identifier: string(), }) }), run: async (payload, io, ctx) => { return io.runTask('grab-content', async () => { try { // We first grab a raw HTML of the content from the website const data = await (await fetch(payload.url)).text(); // We load it with JSDOM so we can manipulate it const dom = new JSDOM(data); // We remove all the scripts and styles from the page dom.window.document.querySelectorAll('script, style').forEach((el) => el.remove()); // We grab all the titles from the page const content = Array.from(dom.window.document.querySelectorAll('h1, h2, h3, h4, h5, h6')); // We grab the last element so we can get the content between the last element and the next element const lastElement = content[content.length - 1]?.parentElement?.nextElementSibling!; const elements = []; // We loop through all the elements and grab the content between each title for (let i = 0; i < content.length; i++) { const element = content[i]; const nextElement = content?.[i + 1] || lastElement; const elementsBetween = getElementsBetween(element, nextElement); elements.push({ title: element.textContent, content: elementsBetween.map((el) => el.textContent).join('\n') }); } // We create a raw text format of all the content const page = ` ---------------------------------- url: ${payload.url}\n ${elements.map((el) => `${el.title}\n${el.content}`).join('\n')} ---------------------------------- `; // We save it to our database await prisma.docs.upsert({ where: { url: payload.url }, update: { content: page, identifier: payload.identifier }, create: { url: payload.url, content: page, identifier: payload.identifier } }); } catch (e) { console.log(e); } }); }, }); ``` 我們已經完成建立後台作業來抓取和索引文件🎉 ### 詢問助理 現在,讓我們建立一個任務來詢問我們的助手。 前往“jobs”並建立一個新檔案“question.assistant.ts”。 **新增以下程式碼:** ``` import {eventTrigger} from "@trigger.dev/sdk"; import {client} from "@openai-assistant/trigger"; import {object, string} from "zod"; import {openai} from "@openai-assistant/helper/open.ai"; client.defineJob({ // This is the unique identifier for your Job; it must be unique across all Jobs in your project. id: "question-assistant", name: "Question Assistant", version: "0.0.1", // This is triggered by an event using eventTrigger. You can also trigger Jobs with webhooks, on schedules, and more: https://trigger.dev/docs/documentation/concepts/triggers/introduction trigger: eventTrigger({ name: "question.assistant.event", schema: object({ content: string(), aId: string(), threadId: string().optional(), }) }), integrations: { openai }, run: async (payload, io, ctx) => { // Create or use an existing thread const thread = payload.threadId ? await io.openai.beta.threads.retrieve('get-thread', payload.threadId) : await io.openai.beta.threads.create('create-thread'); // Create a message in the thread await io.openai.beta.threads.messages.create('create-message', thread.id, { content: payload.content, role: 'user', }); // Run the thread const run = await io.openai.beta.threads.runs.createAndWaitForCompletion('run-thread', thread.id, { model: 'gpt-4-1106-preview', assistant_id: payload.aId, }); // Check the status of the thread if (run.status !== "completed") { console.log('not completed'); throw new Error(`Run finished with status ${run.status}: ${JSON.stringify(run.last_error)}`); } // Get the messages from the thread const messages = await io.openai.beta.threads.messages.list("list-messages", run.thread_id, { query: { limit: "1" } }); const content = messages[0].content[0]; if (content.type === 'text') { return {content: content.text.value, threadId: thread.id}; } } }); ``` - 該事件需要三個參數 - `content` - 我們想要傳送給助理的訊息。 - `aId` - 我們先前建立的助手的內部 ID。 - `threadId` - 對話的執行緒 ID。正如您所看到的,這是一個可選參數,因為在第一個訊息中,我們還沒有線程 ID。 - 然後,我們建立或取得前一個執行緒的執行緒。 - 我們在助理提出的問題的線索中加入一條新訊息。 - 我們執行線程並等待它完成。 - 我們取得訊息清單(並將其限制為 1),因為第一則訊息是對話中的最後一則訊息。 - 我們返回訊息內容和我們剛剛建立的線程ID。 ### 新增路由 我們需要為我們的應用程式建立 3 個 API 路由: 1、派新助理進行處理。 2. 透過URL獲取特定助手。 3. 新增訊息給助手。 在「app/api」中建立一個名為assistant的新資料夾,並在其中建立一個名為「route.ts」的新檔案。裡面加入如下程式碼: ``` import {client} from "@openai-assistant/trigger"; import {prisma} from "@openai-assistant/helper/prisma.client"; export async function POST(request: Request) { const body = await request.json(); if (!body.url) { return new Response(JSON.stringify({error: 'URL is required'}), {status: 400}); } // We send an event to the trigger to process the documentation const {id: eventId} = await client.sendEvent({ name: "process.documentation.event", payload: {url: body.url}, }); return new Response(JSON.stringify({eventId}), {status: 200}); } export async function GET(request: Request) { const url = new URL(request.url).searchParams.get('url'); if (!url) { return new Response(JSON.stringify({error: 'URL is required'}), {status: 400}); } const assistant = await prisma.assistant.findFirst({ where: { url: url } }); return new Response(JSON.stringify(assistant), {status: 200}); } ``` 第一個「POST」方法取得一個 URL,並使用用戶端傳送的 URL 觸發「process.documentation.event」作業。 第二個「GET」方法從我們的資料庫中透過客戶端發送的 URL 取得助手。 現在,讓我們建立向助手新增訊息的路由。 在「app/api」內部建立一個新資料夾「message」並新增一個名為「route.ts」的新文件,然後新增以下程式碼: ``` import {prisma} from "@openai-assistant/helper/prisma.client"; import {client} from "@openai-assistant/trigger"; export async function POST(request: Request) { const body = await request.json(); // Check that we have the assistant id and the message if (!body.id || !body.message) { return new Response(JSON.stringify({error: 'Id and Message are required'}), {status: 400}); } // get the assistant id in OpenAI from the id in the database const assistant = await prisma.assistant.findUnique({ where: { id: +body.id } }); // We send an event to the trigger to process the documentation const {id: eventId} = await client.sendEvent({ name: "question.assistant.event", payload: { content: body.message, aId: assistant?.aId, threadId: body.threadId }, }); return new Response(JSON.stringify({eventId}), {status: 200}); } ``` 這是一個非常基本的程式碼。我們從客戶端獲取訊息、助手 ID 和線程 ID,並將其發送到我們之前建立的「question.assistant.event」。 最後要做的事情是建立一個函數來獲取我們所有的助手。 在「helpers」內部建立一個名為「get.list.ts」的新函數並新增以下程式碼: ``` import {prisma} from "@openai-assistant/helper/prisma.client"; // Get the list of all the available assistants export const getList = () => { return prisma.assistant.findMany({ }); } ``` 非常簡單的程式碼即可獲得所有助手。 我們已經完成了後端🥳 讓我們轉到前面。 --- ![前端](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k3s5gks1j0ojoz11b93i.png) ## 建立前端 我們將建立一個基本介面來新增 URL 並顯示已新增 URL 的清單: ![ss1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ihvx4yn6uee6gritr9nh.png) ### 首頁 將 `app/page.tsx` 的內容替換為以下程式碼: ``` import {getList} from "@openai-assistant/helper/get.list"; import Main from "@openai-assistant/components/main"; export default async function Home() { const list = await getList(); return ( <Main list={list} /> ) } ``` 這是一個簡單的程式碼,它從資料庫中取得清單並將其傳遞給我們的 Main 元件。 接下來,讓我們建立“Main”元件。 在「app」內建立一個新資料夾「components」並新增一個名為「main.tsx」的新檔案。 **新增以下程式碼:** ``` "use client"; import {Assistant} from '@prisma/client'; import {useCallback, useState} from "react"; import {FieldValues, SubmitHandler, useForm} from "react-hook-form"; import {ChatgptComponent} from "@openai-assistant/components/chatgpt.component"; import {AssistantList} from "@openai-assistant/components/assistant.list"; import {TriggerProvider} from "@trigger.dev/react"; export interface ExtendedAssistant extends Assistant { pending?: boolean; eventId?: string; } export default function Main({list}: {list: ExtendedAssistant[]}) { const [assistantState, setAssistantState] = useState(list); const {register, handleSubmit} = useForm(); const submit: SubmitHandler<FieldValues> = useCallback(async (data) => { const assistantResponse = await (await fetch('/api/assistant', { body: JSON.stringify({url: data.url}), method: 'POST', headers: { 'Content-Type': 'application/json' } })).json(); setAssistantState([...assistantState, {...assistantResponse, url: data.url, pending: true}]); }, [assistantState]) const changeStatus = useCallback((val: ExtendedAssistant) => async () => { const assistantResponse = await (await fetch(`/api/assistant?url=${val.url}`, { method: 'GET', headers: { 'Content-Type': 'application/json' } })).json(); setAssistantState([...assistantState.filter((v) => v.id), assistantResponse]); }, [assistantState]) return ( <TriggerProvider publicApiKey={process.env.NEXT_PUBLIC_TRIGGER_PUBLIC_API_KEY!}> <div className="w-full max-w-2xl mx-auto p-6 flex flex-col gap-4"> <form className="flex items-center space-x-4" onSubmit={handleSubmit(submit)}> <input className="flex-grow p-3 border border-black/20 rounded-xl" placeholder="Add documentation link" type="text" {...register('url', {required: 'true'})} /> <button className="flex-shrink p-3 border border-black/20 rounded-xl" type="submit"> Add </button> </form> <div className="divide-y-2 divide-gray-300 flex gap-2 flex-wrap"> {assistantState.map(val => ( <AssistantList key={val.url} val={val} onFinish={changeStatus(val)} /> ))} </div> {assistantState.filter(f => !f.pending).length > 0 && <ChatgptComponent list={assistantState} />} </div> </TriggerProvider> ) } ``` 讓我們看看這裡發生了什麼: - 我們建立了一個名為「ExtendedAssistant」的新接口,其中包含兩個參數「pending」和「eventId」。當我們建立一個新的助理時,我們沒有最終的值,我們將只儲存`eventId`並監聽作業處理直到完成。 - 我們從伺服器元件取得清單並將其設定為新狀態(以便我們稍後可以修改它) - 我們新增了「TriggerProvider」來幫助我們監聽事件完成並用資料更新它。 - 我們使用「react-hook-form」建立一個新表單來新增助手。 - 我們新增了一個帶有一個輸入「URL」的表單來提交新的助理進行處理。 - 我們迭代並顯示所有現有的助手。 - 在提交表單時,我們將資訊傳送到先前建立的「路由」以新增助理。 - 事件完成後,我們觸發「changeStatus」以從資料庫載入助手。 - 最後,我們有了 ChatGPT 元件,只有在沒有等待處理的助手時才會顯示(`!f.pending`) 讓我們建立 `AssistantList` 元件。 在「components」內,建立一個新檔案「assistant.list.tsx」並在其中加入以下內容: ``` "use client"; import {FC, useEffect} from "react"; import {ExtendedAssistant} from "@openai-assistant/components/main"; import {useEventRunDetails} from "@trigger.dev/react"; export const Loading: FC<{eventId: string, onFinish: () => void}> = (props) => { const {eventId} = props; const { data, error } = useEventRunDetails(eventId); useEffect(() => { if (!data || error) { return ; } if (data.status === 'SUCCESS') { props.onFinish(); } }, [data]); return <div className="pointer bg-yellow-300 border-yellow-500 p-1 px-3 text-yellow-950 border rounded-2xl">Loading</div> }; export const AssistantList: FC<{val: ExtendedAssistant, onFinish: () => void}> = (props) => { const {val, onFinish} = props; if (val.pending) { return <Loading eventId={val.eventId!} onFinish={onFinish} /> } return ( <div key={val.url} className="pointer relative bg-green-300 border-green-500 p-1 px-3 text-green-950 border rounded-2xl hover:bg-red-300 hover:border-red-500 hover:text-red-950 before:content-[attr(data-content)]" data-content={val.url} /> ) } ``` 我們迭代我們建立的所有助手。如果助手已經建立,我們只顯示名稱。如果沒有,我們渲染`<Loading />`元件。 載入元件在螢幕上顯示“正在載入”,並長時間輪詢伺服器直到事件完成。 我們使用 Trigger.dev 建立的 useEventRunDetails 函數來了解事件何時完成。 事件完成後,它會觸發「onFinish」函數,用新建立的助手更新我們的客戶端。 ### 聊天介面 ![聊天介面](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0u7db3qwz03d6jkk965a.png) 現在,讓我們加入 ChatGPT 元件並向我們的助手提問! - 選擇我們想要使用的助手 - 顯示訊息列表 - 新增我們要傳送的訊息的輸入和提交按鈕。 在「components」內部新增一個名為「chatgpt.component.tsx」的新文件 讓我們繪製 ChatGPT 聊天框: ``` "use client"; import {FC, useCallback, useEffect, useRef, useState} from "react"; import {ExtendedAssistant} from "@openai-assistant/components/main"; import Markdown from 'react-markdown' import {useEventRunDetails} from "@trigger.dev/react"; interface Messages { message?: string eventId?: string } export const ChatgptComponent = ({list}: {list: ExtendedAssistant[]}) => { const url = useRef<HTMLSelectElement>(null); const [message, setMessage] = useState(''); const [messagesList, setMessagesList] = useState([] as Messages[]); const [threadId, setThreadId] = useState<string>('' as string); const submitForm = useCallback(async (e: any) => { e.preventDefault(); setMessagesList((messages) => [...messages, {message: `**[ME]** ${message}`}]); setMessage(''); const messageResponse = await (await fetch('/api/message', { method: 'POST', body: JSON.stringify({message, id: url.current?.value, threadId}), })).json(); if (!threadId) { setThreadId(messageResponse.threadId); } setMessagesList((messages) => [...messages, {eventId: messageResponse.eventId}]); }, [message, messagesList, url, threadId]); return ( <div className="border border-black/50 rounded-2xl flex flex-col"> <div className="border-b border-b-black/50 h-[60px] gap-3 px-3 flex items-center"> <div>Assistant:</div> <div> <select ref={url} className="border border-black/20 rounded-xl p-2"> {list.filter(f => !f.pending).map(val => ( <option key={val.id} value={val.id}>{val.url}</option> ))} </select> </div> </div> <div className="flex-1 flex flex-col gap-3 py-3 w-full min-h-[500px] max-h-[1000px] overflow-y-auto overflow-x-hidden messages-list"> {messagesList.map((val, index) => ( <div key={index} className={`flex border-b border-b-black/20 pb-3 px-3`}> <div className="w-full"> {val.message ? <Markdown>{val.message}</Markdown> : <MessageComponent eventId={val.eventId!} onFinish={setThreadId} />} </div> </div> ))} </div> <form onSubmit={submitForm}> <div className="border-t border-t-black/50 h-[60px] gap-3 px-3 flex items-center"> <div className="flex-1"> <input value={message} onChange={(e) => setMessage(e.target.value)} className="read-only:opacity-20 outline-none border border-black/20 rounded-xl p-2 w-full" placeholder="Type your message here" /> </div> <div> <button className="border border-black/20 rounded-xl p-2 disabled:opacity-20" disabled={message.length < 3}>Send</button> </div> </div> </form> </div> ) } export const MessageComponent: FC<{eventId: string, onFinish: (threadId: string) => void}> = (props) => { const {eventId} = props; const { data, error } = useEventRunDetails(eventId); useEffect(() => { if (!data || error) { return ; } if (data.status === 'SUCCESS') { props.onFinish(data.output.threadId); } }, [data]); if (!data || error || data.status !== 'SUCCESS') { return ( <div className="flex justify-end items-center pb-3 px-3"> <div className="animate-spin rounded-full h-3 w-3 border-t-2 border-b-2 border-blue-500" /> </div> } return <Markdown>{data.output.content}</Markdown>; }; ``` 這裡正在發生一些令人興奮的事情: - 當我們建立新訊息時,我們會自動將其呈現在螢幕上作為「我們的」訊息,但是當我們將其發送到伺服器時,我們需要推送事件 ID,因為我們還沒有訊息。這就是我們使用 `{val.message ? <Markdown>{val.message}</Markdown> : <MessageComponent eventId={val.eventId!} onFinish={setThreadId} />}` - 我們用「Markdown」元件包裝訊息。如果您還記得,我們在前面的步驟中告訴 ChatGPT 以 MD 格式輸出所有內容,以便我們可以正確渲染它。 - 事件處理完成後,我們會更新線程 ID,以便我們從以下訊息中獲得相同對話的上下文。 我們就完成了🎉 --- ![完成](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0half2g6r5zfn7asq084.png) ## 讓我們聯絡吧! 🔌 作為開源開發者,您可以加入我們的[社群](https://discord.gg/nkqV9xBYWy) 做出貢獻並與維護者互動。請隨時造訪我們的 [GitHub 儲存庫](https://github.com/triggerdotdev/trigger.dev),貢獻並建立與 Trigger.dev 相關的問題。 本教學的源程式碼可在此處取得: [https://github.com/triggerdotdev/blog/tree/main/openai-assistant](https://github.com/triggerdotdev/blog/tree/main/openai-assistant) 感謝您的閱讀! --- 原文出處:https://dev.to/triggerdotdev/train-chatgpt-on-your-documentation-1a9g

🔥5 個必須在 Kubernetes 叢集上安裝的工具 ✨️🚀

本文列出了開發人員在 Kubernetes 叢集上安裝的五個必備工具。 🎉 請隨意探索這些專案,為儲存庫加註星標,並為您最喜歡的專案做出貢獻。 😉 事不宜遲,讓我們開始吧。 🏃‍♂️💨 ![讓我們開始吧](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1p4nkxc6qnkbcpo59q9c.gif) ** ** ## **1\. [Odigos](https://odigos.io)** > 💡 分散式跟踪,無需更改程式碼。 ![Odigos - 可觀測控制平面](https://res.cloudinary.com/practicaldev/image/fetch/s--vrtvOUOw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/najz95vmowa4uv1jlecq.jpg) Odigos 是一個開源可觀測性控制平面,使組織能夠建立和維護其可觀測性管道。 Odigos 自動產生 OpenTelemetry 格式的遙測資料到任何 Observability 後端,無需更改任何程式碼。 😻。 它會自動檢測我們的應用程式,從而無需我們自己設定 OpenTelemetry 或任何其他內容。奧迪戈斯處理這一切。 🤯 這一切之所以成為可能,是因為: * **自動化檢測👾:** Odigos 支援使用 OpenTelemetry 和 eBPF 對應用程式進行自動化檢測,無需修改程式碼。 * **通用觀測工具相容性🤝:** 與各種觀測工具平滑集成,提供全面的支援和高效的收集器管理。 ** ** ## **2\. [Argo CD](https://argoproj.github.io/cd/)** ![Argo CD ](https://res.cloudinary.com/practicaldev/image/fetch/s--Q6PXSe2d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oawy0bzp0hok5jvwq1l3.jpg) Argo CD 是一款功能強大的 GitOps CD 工具,可協助自動化和簡化 Kubernetes 應用程式的部署和管理🚀。 Argo CD 主要功能包括 Web UI 💻、CLI、回滾功能和簡化的監控。 > **為什麼要使用 Argo CD 而不是傳統的 CD 工具?** 🤔 * **Git 作為單一事實來源 🤫:** Argo CD 使用 Git 作為應用程式和基礎設施配置的單一事實來源。如果出現問題,它可以輕鬆追蹤變更並回滾部署。 * **友善的 Web UI 💻:** Argo CD 提供了一個儀表板來管理和取得所有已部署應用程式的狀態。 * **輕鬆回滾 🔄:** 叢集與單獨的 git 儲存庫同步,因此我們只需要恢復 git 中的更改,叢集就會自動與 git 儲存庫同步。 * **災難復原 🌋:** 如果發生災難,只需將 git 儲存庫指向新建立的集群,它將擁有先前集群的所有配置。 這些功能使初學者和經驗豐富的 Kubernetes 用戶都可以使用它。 > 簡而言之,Argo CD 是 Kubernetes ☸️ 的 GitOps CD 工具,它使用 Git 作為應用程式和基礎設施配置的單一來源,並提供輕鬆的回滾、儀表板和災難復原功能。 ** ** ## **3\. [Nginx 入口控制器](https://docs.nginx.com/nginx-ingress-controller/)** > 💡 適用於 Kubernetes 環境的專用負載平衡器。 它是 Kubernetes 使用最廣泛的入口控制器。 ☸️ 它使用 Nginx 作為反向代理和負載平衡器。 它在具有 Nginx Plus 或 Nginx 開源實例的 Kubernetes 環境中執行 🏃‍♂️。 Nginx Ingress Controller 的主要職責是👇: * 負載平衡 Kubernetes 叢集中容器📦的流量。它監視 Kubernetes 入口資源並將流量路由到適當的 Kubernetes 服務和 Pod。 * 處理網路、流量管理👮‍♂️、通訊和安全性🔒。 * 根據其配置部署資源並根據入口資源定義自動更新規則。 > 簡而言之,它管理流量、安全性並根據 Kubernetes 入口資源和配置動態調整路由。 ** ** ## **4\. [適用於 Kubernetes 的 AWS 控制器](https://aws-controllers-k8s.github.io/community/)** > 💡 使用 Kubernetes 管理 AWS 服務。 **ACK** 是 AWS Controllers for Kubernetes 的縮寫,是一組自訂控制器,可實現 AWS 服務和 Kubernetes 叢集之間的集成,讓您可以直接從 Kubernetes 管理 AWS 服務。 ACK 讓您可以輕鬆建立利用 AWS 服務的可擴充且高度可用的 Kubernetes 應用程式。它提供了一種統一的方式來管理我們的應用程式及其相依性✨️。 適用於 Kubernetes 的 AWS 控制器的一些主要功能包括: * 直接從 Kubernetes 定義和使用 AWS 服務資源。 * 利用 AWS 託管服務來管理 Kubernetes 應用程式,無需在叢集外部定義資源或執行提供資料庫或訊息佇列等支援功能的服務。 > 簡而言之,ACK 使我們能夠直接從 Kubernetes 管理 AWS 服務,並提供一種在 Kubernetes 叢集內定義和使用 AWS 服務的統一方法。 ** ** ## **5\. [Kyverno](https://kyverno.io)** > 💡 為 Kubernetes 設計的策略引擎。 在 Kubernetes 中部署事物(例如 Pod 或 ConfigMap)時,設定規則/策略非常重要。 一個關鍵的做法是避免在生產中使用容器鏡像的“最新”標籤,因為它通常是正在進行的開發建置。 > **Kyverno 實際上做了什麼?** 🧐 在 Kubernetes 中,安全性問題是一個大問題,主要原因之一是**配置錯誤**。當沒有良好的規則(政策)時,就會出現這些安全問題。 這就是像 **Kyverno** 這樣的策略管理器發揮作用的地方。 😎 > 🚨 **注意:** Kyverno 不適用於 Kubernetes 以外的任何其他環境。如果您正在尋找與供應商無關的策略管理,您可以考慮使用諸如[開放策略代理程式](https://www.openpolicyagent.org/)之類的東西。 Kyverno 在我們的 Kubernetes 設定中管理策略,無論它們是關於安全還是只是良好實踐。 我們可以為前面提到的「最新」標籤問題等建立規則,或專注於安全性,例如確保您的容器映像在軟體供應鏈中是安全的。 > 簡而言之,Kyverno 是一個策略引擎,它允許使用者管理部署策略、解決錯誤配置等問題並推廣良好實踐,從而幫助管理安全性和最佳實踐。 ** ** > 如果您認為本文中未提及的任何其他有用的專案,請在下面的評論部分分享。 👇🏻 那麼,這就是本文的內容。非常感謝您的閱讀! 🎉 --- 原文出處:https://dev.to/odigos/5-must-have-tools-to-install-on-your-kubernetes-cluster-489k

🚀 Kubernetes 上的 GITLAB:終極部署指南! 🌟

## TL;DR 🔍 探索在 Kubernetes 上部署 GitLab 的逐步指南,並專注於 Omnibus 套件配置。了解如何設定 PostgreSQL、SMTP、Container Registry、Sidekiq、Prometheus 指標和備份。使用 Glasskube GitLab Kubernetes Operator 探索替代方案,簡化流程並將設定時間縮短至僅 5 分鐘。 --- ## 我們需要您的回饋! 🫶 在下面的評論中分享您的想法!讓我們知道您想要更多內容的主題。如果本指南有幫助,請點擊貓並留下一顆星,以支持我們建立更多以開發人員為中心的內容。您的回饋很重要! [![Glasskube Github](https://cms.glasskube.eu/uploads/CTA_51bbe3bb2a.png) ](https://github.com/glasskube/operator) --- ## 讓我們開始吧🏌️ [GitLab](https://glasskube.eu/en/s/kubernetes-operator/gitlab/) 是一個以軟體工程團隊為導向的開源 DevSecOps 平台。 有兩種方式可用於在 Kubernetes 叢集上部署 GitLab: 1.GitLab雲端原生混合 2.GitLab包(綜合) ## GitLab 雲端原生混合 部署 GitLab Cloud 原生混合架構僅在查詢特定用例中才有意義。例如 - 如 [GitLab 決策樹](https://docs.gitlab.com/ee/administration/reference_architectures/#decision-tree) 所示 - 如果 GitLab 實例需要為至少 3,000 個使用者提供服務。對於這種部署,GitLab 元件將單獨安裝在不同的 docker 容器中。最低要求為 10 個節點,總共 19 個 vCPU 和 60 GB 內存,這將導致每月數千美元的雲端成本。 <img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExbHl6eXltNWw0ZDNjbnNqbDdicXBpbzNpdX6e nlfaWQmY 3Q9Zw/2aIZfQdC2V7bBvU5t2/giphy.gif"> 因此,在大多數情況下,GitLab 雲端原生是不需要的,而且過於複雜。 **那麼,如何在 Kubernetes 上部署 GitLab Omnibus?** ## Kubernetes 上的 GitLab Omnibus 使用「omnibus」這個名稱,GitLab 也發布了一體化軟體包,這些軟體包可以作為docker 映像[`hub.docker.com/r/gitlab/gitlab-ce`](https://hub.docker. com /r/gitlab/gitlab-ce),可以透過環境變數輕鬆配置。正確進行設定可以輕鬆在 Kubernetes 上部署 GitLab。 應正確配置以下重要元件,以便歸檔合理的 Kubernetes 設定: 1.PostgreSQL資料庫 2. SMTP配置 3. Kubernetes 上的 GitLab 容器註冊表 4. Sidekiq、Gitaly 和 Puma 配置 5. 普羅米修斯指標 6. Kubernetes 上的 GitLab 備份 ### Kubernetes 上的 GitLab:設定外部 PostgreSQL 資料庫 建立 PostgreSQL 資料庫可以使用 [CloudNativePG PostgreSQL Operator](https://cloudnative-pg.io/) 來完成。安裝完 Operator 後,可以透過套用 Kubernetes CR 來部署新的 Postgres 叢集: ``` kind: Cluster apiVersion: postgresql.cnpg.io/v1 metadata: name: gitlab spec: enableSuperuserAccess: false instances: 2 bootstrap: initdb: database: gitlabhq_production owner: gitlab storage: size: 20Gi ``` 重要的是,資料庫名稱為“gitlabhq_product”,而配置的“gitlab”資料庫使用者是資料庫的擁有者。在本例中,我們建立了一個由兩個 PostgreSQL 副本組成的集群,以確保資料庫保持可用,即使執行主副本的節點發生故障也是如此。這稱為高可用性 (HA)。 現在,我們建立了自己的 PostgreSQL 集群,必須在「gitlab.rb」檔案中停用綜合映像中包含的資料庫。 ``` postgresql['enable'] = false gitlab_rails['db_adapter'] = 'postgresql' gitlab_rails['db_encoding'] = 'unicode' gitlab_rails['db_host'] = 'gitlab-pg-rw' gitlab_rails['db_password'] = '<your-password>' ``` 很好,我們已經為 GitLab 安裝提供了雲端原生資料庫。 <img width="25%" style="width:25%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExc2VydjJoN3BsN2RycDY5N3prZHhoaW8xdTYxenJoN3BsN2RycDY5N3prZHhoaW8xdTYxenhkbHdtBlcMpm30FmDFt0Fyg n;ipPlcmDMlcM40M400005450000200020025400000 mY3 Q9Zw/SVH9y2LQUVVCRcqD7o/giphy.gif"> #### Kubernetes 上的 GitLab:設定 SMTP 憑證 為了確保您的 GitLab 實例能夠傳送電子郵件,您需要設定 SMTP 伺服器。這也可以在 `gitlab.rb` 檔案中完成。 ``` gitlab_rails['smtp_enable'] = ... gitlab_rails['smtp_address'] = ... gitlab_rails['smtp_port'] = ... gitlab_rails['smtp_user_name'] = ... gitlab_rails['smtp_password'] = ... gitlab_rails['smtp_tls'] = ... gitlab_rails['gitlab_email_from'] = ... ``` 例如,可以在 Brevo 平台上建立用於交易電子郵件的免費 smtp 伺服器。 <img width="25%" style="width:25%" src="https://media.giphy.com/media/0IR3vO2bWY1AQPAsAn/giphy.gif"> #### Kubernetes 上的 GitLab:容器註冊表 在眾多功能中,GitLab 支援充當容器註冊表。這是透過捆綁 docker 容器註冊表的參考實作來實現的,但預設情況下它是禁用的,因為正確設定它相當麻煩。 > **重要** > 重要的是要了解 GitLab 綜合容器中的所有請求將首先由內部 nginx 伺服器處理,然後分發到元件。 容器註冊表僅適用於 TLS 加密連接,因此我們需要透過入口負載平衡器停用 TLS 終止,並將加密流量直接傳送到 GitLab 容器。如果使用 NGINX 入口控制器,可以透過在入口中新增以下註解來完成:「nginx.ingress.kubernetes.io/ssl-passthrough: true」。 之後,必須套用以下`gitlab.rb`配置: ``` registry['enable'] = true gitlab_rails['registry_enabled'] = true registry['token_realm'] = "https://" + ENV['GITLAB_HOST'] gitlab_rails['registry_enabled'] = true gitlab_rails['registry_host'] = ENV['GITLAB_REGISTRY_HOST'] gitlab_rails['registry_api_url'] = "http://localhost:5000" registry_external_url 'https://' + ENV['GITLAB_REGISTRY_HOST'] registry_nginx['redirect_http_to_https'] = true registry_nginx['listen_port'] = 5443 registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/tls.crt" registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/tls.key" registry_nginx['real_ip_trusted_addresses'] = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'] registry_nginx['server_names_hash_bucket_size'] = 128 ``` 此外,可以配置 S3 儲存桶(或相容的雲端儲存端點),以便所有影像層不會儲存在磁碟區內,而是儲存在可擴充的 S3 中 ### Kubernetes 上的 GitLab:Sidekiq、Gitaly 和 Puma 配置 Puma(Ruby 的 HTTP 伺服器)、Sidekiq(作業排程器)和 Gitaly(GitLabs Git 橋接器)都可以使用自訂數量的工作執行緒/執行緒來啟動。最佳配置在很大程度上取決於您的用例和需要支援的使用者數量。合理的最小配置是: ``` puma['worker_processes'] = 2 sidekiq['max_concurrency'] = 9 ``` ### Kubernetes 上的 GitLab:Prometheus 指標 GitLab 綜合包在鏡像中附帶了自己的 prometheus 實例。由於大多數 Kubernetes 叢集中已經存在 Prometheus 實例,因此可以安全地停用包含的 Prometheus。 ``` prometheus_monitoring['enable'] = false ``` ServiceMonitor 可以用來告訴正在執行的 Prometheus 實例在下列連接埠上監視 GitLabs 元件所公開的指標端點: - 8082(sidekiq) - 9168(gitlab) - 9236(義大利) ### Kubernetes 上的 GitLab:備份 嗯,在 Kubernetes 上備份 GitLab 本身就是一個技術指南。最簡單的方法是使用 [Velero](https://velero.io/) 等備份解決方案備份完整的命名空間。 ## 玻璃立方體 GitLab Kubernetes Operator 了解Glasskube GitLab [Kubernetes Operator](https://glasskube.eu/en/r/glossary/kubernetes-operator/) - 我們的開發團隊對繁瑣的配置過程、耗時的設定和不斷的故障排除感到沮喪的產物與 GitLab 部署相關。為了應對這些挑戰,我們精心設計了一個簡化整個體驗的解決方案。 Glasskube GitLab Kubernetes Operator 部署一個完全配置的 GitLab 實例,其所有功能均透過自訂資源定義 (CRD) 巧妙抽象化。感謝操作員,花費過多時間進行設定和更新的日子已經結束。現在,您可以在短短 5 分鐘內輕鬆啟動新的 GitLab 實例。嘗試一下並向我們提供反饋! ### 安裝 Glasskube 運算符 第一步是透過 Helm Chart 安裝 Glasskube: ``` helm repo add glasskube https://charts.glasskube.eu/ helm repo update helm install my-glasskube-operator glasskube/glasskube-operator ``` 完整的文件可以在我們的[入門](https://glasskube.eu/docs/getting-started/install/)文件中找到。 ### 部署 GitLab > **重要** > 必須在「LoadBalancer」或「Ingress Host」上設定 DNS 專案。 SSL 憑證是 > 如果配置了“ClusterIssuer”,則由“LoadBalancer”或“cert-manager”自動產生。 **gitlab.yaml** ``` apiVersion: "v1" kind: "Secret" metadata: name: "gitlab-smtp" stringData: username: "..." password: "..." --- apiVersion: v1 kind: Secret metadata: name: gitlab-registry-secret stringData: accessKey: "..." secretKey: "..." --- apiVersion: "glasskube.eu/v1alpha1" kind: "Gitlab" metadata: name: "gitlab" spec: host: "gitlab.mycompany.eu" sshEnabled: true sshHost: "ssh.gitlab.mycompany.eu" smtp: host: "..." port: 465 fromAddress: "[email protected]" authSecret: name: "gitlab-smtp" tlsEnabled: true registry: host: "registry.gitlab.mycompany.eu" storage: s3: bucket: gitlab-registry accessKeySecret: name: gitlab-registry-secret key: accessKey secretKeySecret: name: gitlab-registry-secret key: secretKey region: ... ``` ``` kubectl apply -f gitlab.yaml ``` <img width="25%" style="width:25%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExa2RldHpiYnMzOWdlZTgwdWtqOHN3N3eG9I0NjVyd2l4m Y3Q9Zw/YRhUem7n2UaF9EK2PH/giphy.gif"> 就是這樣! 完整的自訂資源文件可以在 Glasskube 文件中找到 關於 [GitLab](https://glasskube.eu/docs/crd-reference/gitlab/) ### 在 Kubernetes 上部署 GitLab Runner <img width="25%" style="width:25%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZDJsN2x6NTI0dWdhZW55MjBzMjFobHdtbDRtaHEycXlidWdhZW55MjBzMjFobHdtbDRtaHEycXlidWdhZW55MjBzMjFobHdtbDRtaHEycXlidGt. WQmY 3Q9Zw/945jGDodvZCDe/giphy.gif"> GitLab 上的運作程序是為持續整合和持續交付 (CI/CD) 管道提供支援的執行代理。 他們負責執行作業,即管道中的各個步驟或任務。 Glasskube Gitlab Kubernetes Operator 讓在 Gitlab 中新增執行器變得如此簡單。首先,需要透過「https://{{host}}/admin/runners/new」建立一個新的執行程式。之後,這些執行器令牌只需加入到「gitlab.yaml」規格中,Glasskube Kubernetes Operator 將自動產生並將這些執行器與 Gitlab 實例連接起來。 ``` runners: - token: glrt-xxxxXX-xxxxxXXXXX # can be generated at https://{{host}}/admin/runners/new ``` 完整的自訂資源文件可以在關於 [GitLab runner] 的 Glasskube 文件中找到(https://glasskube.eu/docs/crd-reference/gitlab/runner/) 現在安裝完成了。 Kubernetes Operator 的更新將自動更新 GitLab。 ## 結論 在 Kubernetes 上為少於 1000 個使用者部署 GitLab 實例不應該使用 GitLabs 雲端原生混合 Helm Charts 來完成,而應該使用專門安裝的 GitLab Omnibus 套件與雲端原生基礎架構結合來完成。 Glasskube Kubernetes 操作員負責處理這個問題。 --- [![玻璃立方體Github]( https://cms.glasskube.eu/uploads/CTA_51bbe3bb2a.png) ](https://github.com/glasskube/operator) --- 星星冰塊: # [`glasskube/operator`](https://github.com/glasskube/operator) --- 原文出處:https://dev.to/glasskube/gitlab-on-kubernetes-the-ultimate-deployment-guide-188b

使用 Markdown 與 React 在 Github 文件中顯示淺色模式、深色模式

警告:所表達的觀點可能不適合所有受眾! 😂 ## 簡介 在本文結束時,您將了解並能夠根據使用者偏好 - **深色**或**淺色**模式展示您的 Markdown 影像。 1. 我將介紹如何在 GitHub README.md 中加入兩個圖像 - 根據所選的“主題”,您的圖像將正確回應。 2. 我將引導您在 Markdown 中合併影像的過程,並示範如何使用 React 使它們回應。 😎 ___ ## 你使用淺色還是深色? 我不了解你的情況,但無論平台如何,如果他們可以選擇在淺色和深色模式之間切換,那就沒有競爭了。 淺色主題正在切換為深色,事實上,當然在我寫這篇文章的時候! ![深色主題](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s0yfjc2yv5pfyacu74go.png) 話雖如此,在軟體開發的快速發展中,創造無縫的使用者體驗至關重要。 這種體驗的一部分涉及適應使用者偏好,例如淺色和深色模式。 我還記得幾年前,Github 宣布了用戶可以切換到「深色模式」的選項,這是一件非常大的事情。 ![GitHub 深色主題](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qi10urco3o6fdojm6ipf.png) 【Github揭曉黑暗主題的重要時刻】(https://t.co/HEotvXVJ7R) 🤩 2020 年 12 月 8 日🎆 近年來,使用者介面中深色和淺色模式選項的出現已成為一種流行趨勢。 我絕對不是唯一一個喜歡使用深色主題選項的人,根據 Android 用戶的說法,[91.8% 的用戶更喜歡深色模式](https://www.androidauthority.com/dark-mode-poll-results-1090716/) 所以我們可以猜測這個數字在所有作業系統中都相當高。 這當然可能會引起激烈的爭論,所以我會盡力將自己的觀點降到最低。 ![輕模式迷因](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m3yiepj8a46rwhu69fgw.png) ## 改善使用者體驗 主要目標是透過在應用程式中提供選項來改善用戶體驗。 有多種方法可以建立每個圖像的多個版本,在本教程中我們不會深入討論細節。 只要確保您的圖像在兩個主題中脫穎而出並具有透明背景,您就會獲得成功。 **_讓我們開始派對吧!_** ## GitHub 自述文件中的響應式圖像 您有一個專案並想讓您的 GitHub 專案 README.md 真正流行嗎? 無論使用者使用什麼淺色主題,我們都需要一種方法來指定圖像應在 Markdown 中顯示哪種主題(淺色或深色)。 當您想要根據使用者選擇的配色方案優化圖片的顯示時,這特別有用,並且它涉及將 **HTML `<picture>`** 元素與 `prefers-color-scheme` 媒體功能結合使用如下所示。 繼續將圖片檔案直接拖曳到 GitHub 中並放在“srcset=”後面。 ``` <picture> <source media="(prefers-color-scheme: dark)" srcset="https://github.com/boxyhq/.github/assets/66887028/df1c9904-df2f-4515-b403-58b14a0e9093"> <source media="(prefers-color-scheme: light)" srcset="https://github.com/boxyhq/.github/assets/66887028/e093a466-72ea-41c6-a292-4c39a150facd"> <img alt="BoxyHQ Banner" src="https://github.com/boxyhq/jackson/assets/66887028/b40520b7-dbce-400b-88d3-400d1c215ea1"> </picture> ``` 瞧! ![SAML Jackson 暗模式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q51g41fjfqnposn50una.png) ![SAML Jackson 燈光模式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0xzs88txjylnixilaqu.png) 太好了,你有 5 秒嗎? https://github.com/boxyhq/jackson --- ## 使用 React 在 Markdown 中回應影像 假設今天我將像平常一樣用 Markdown 編寫博客,並將其發佈到我的網站上。 我使用的圖像需要根據使用者偏好做出回應,但在 Markdown 中不可能偵聽本地儲存和設定狀態中的「主題」變更。 ![本機儲存](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vrjz4to8x17h63dtybxn.png) 值得慶幸的是,如果我們將 React 匯入到 Markdown 檔案中,但先建立一個元件,就有一種方法可以解決這個困境。 ## 反應文件 ``` src/components/LightDarkToggle.js import React, { useEffect, useState } from 'react'; function ToggleImages() { // Define a state variable to track the user's login status const [currentTheme, setcurrentTheme] = useState(localStorage.getItem('theme')); // Add an event listener for the 'storage' event inside a useEffect useEffect(() => { const handleStorageChange = (event) => { console.log('Storage event detected:', event); // Check the changed key and update the state accordingly console.log("event", event.key) if (event.key === 'theme') { setcurrentTheme(event.newValue); } }; window.addEventListener('storage', handleStorageChange); // Clean up the event listener when the component unmounts return () => { window.removeEventListener('storage', handleStorageChange); }; }, []); // The empty dependency array ensures that this effect runs once when the component mounts return ( <div className="image-container"> {currentTheme == 'light'? ( <img id="light-mode-image" src="/img/blog/boxyhq-banner-light-bg.png" alt="Light Mode Image" ></img> ):( <img id="dark-mode-image" src="/img/blog/boxyhq-banner-dark-bg.png" alt="Dark Mode Image" ></img> )} </div> ); } export default ToggleImages; ``` 我在程式碼中加入了註釋和一些控制台日誌,以幫助了解正在發生的事情,但讓我們快速分解它。 - React useState 鉤子管理 `currentTheme` 的狀態,它代表使用者選擇的儲存在本機儲存中的主題。 - useEffect 掛鉤用於為「儲存」事件新增事件偵聽器。當儲存事件發生時(表示本機儲存發生變化),元件會檢查變更的鍵是否為“theme”,並相應地更新“currentTheme”狀態。 - 此元件根據使用者選擇的主題呈現不同的影像,如果主題是“淺色”,則顯示淺色模式影像;如果主題是其他主題,則顯示深色模式影像。 酷,讓我們繼續吧! ## 降價文件 讓我們為新部落格建立一個 .md 檔案。 ``` --- slug: light-and-dark-mode-responsive-images title: 'Light and Dark Mode Responsive Images' tags_disabled: [ developer, react, javascript, open-source, ] image: /img/blog/light-dark.png author: Nathan Tarbert author_title: Community Engineer @BoxyHQ author_url: https://github.com/NathanTarbert author_image_url: https://boxyhq.com/img/team/nathan.jpg --- import ToggleImages from '../src/components/LightDarkToggle.js'; ## 🤩 Let's start this blog off with a bang! Our business logo is now responsive with each user's preference, whether it's **light** or **dark** mode! <div> <ToggleImages /> </div> More blog words... ``` 此時,我們只需匯入 React 元件並將其呈現在 Markdown 檔案中。 由於這是一個 Next.js 應用程式,讓我們啟動伺服器“npm run dev”並查看結果。 ![貓鼓滾](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lyjzjqgcwaubyj5ve1o3.gif) ![網站深色模式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qraltb34mrl9y8j9jppq.png) 並切換到淺色主題 ![網站燈光模式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u33jgzha5fbfy6tlb4hs.png) 讓我們打開控制台來查看我們的事件 ![console.log](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpxz5gbhwt308vatsnkp.png) 你有它! 這些是在 Markdown 中展示響應式映像的幾種方法,其中一個範例使用 React 來幫助我們在本地儲存中設定狀態。 我希望您喜歡這篇文章,如果您喜歡開發,請在 [X (Twitter)](https://twitter.com/nathan_tarbert) 上關注我,我們下次再見! --- 原文出處:https://dev.to/nathan_tarbert/the-zebras-guide-to-showcase-your-images-in-light-dark-17f5

工程師就業市場也太慘了🤯 分享 5 個生存技巧

你有沒有想過... **如果軟體開發人員的需求如此之大,為什麼現在找到開發人員的工作這麼難?** 為什麼面試過程這麼長?為什麼會有數百次拒絕? 為什麼提供的工資低? 今天,您將了解混亂背後的原因。 我們是如何來到這裡的。以及為什麼。 我還將向您展示為什麼事情並不像大多數開發人員想像的那麼糟糕。以及您需要採取的 5 個步驟來利用這種情況為您帶來優勢。 因此,當大多數開發人員都在倒退時,您可以快速發展您的職業生涯。 如果您是一位雄心勃勃的開發人員,想要更上一層樓並增加薪水,那麼這就是適合您的。 **因為有一件事是真的,我們所知道的軟體開發在 2023 年已經發生了永遠的變化。**‍ 「美好的舊時光」已經一去不復返了。 知道如何建立 React 應用程式將不再讓你獲得這份工作。我們不會很快回到那個狀態。 我們走吧。 這一切都要追溯到 2022 年,當時從谷歌到 Meta 和微軟等大型科技公司開始宣布裁員。不是各種裁員,是裁員開發者。 起初,大多數開發人員都很有信心。 他們說,_「軟體開發總是在成長並且需求旺盛,我們將會復甦」_。 現在,12 個多月過去了,許多程式設計師已經失去了樂觀情緒(免責聲明:我仍然對開發人員的未來非常樂觀,稍後會詳細介紹)。 許多開發者正在失去耐心等待就業市場的復甦。如果它永遠不會發生怎麼辦? 一些開發人員正在懷疑他們的職業選擇。正在考慮 B 計劃或已經轉向做其他事情。 其他人則被迫回到編寫程式碼之前的低薪工作。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ws0oxry69oxhjkbyiydf.png) 最初的樂觀很快就變成了悲觀,許多開發者都在尋找 B 計畫。 **最好的情況是資料輸入或客戶服務工作。在最壞的情況下,它會回到咖啡店或倉庫。** 我認為這是一件非常悲傷的事情。僅僅因為你找不到擺脫困境的有效策略,就拋棄了你的夢想和多年的努力。 我相信,如果你進入軟體開發,那是有原因的。您可能工作勤奮、雄心勃勃且富有創造力。你至少應該有機會證明自己的價值。 在這篇文章中,我將向您展示該怎麼做。具體來說,無論市場表現如何,如何使用經過驗證的軟體工程原理來度過這場風暴,並將您的開發人員職業生涯提升到一個新的水平。 我是誰可以給你這方面的建議? 我叫 Dragos,在過去 3 年裡,我幫助超過 230 多名軟體開發人員提升了技能,快速晉升到高級級別,並獲得了他們應得的認可和報酬。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsbpn3yvyq1zcvn44mu5.jpeg) 我不是大師或技術影響者。我並不打算成為其中之一。 但是,在作為自學成才的開發人員編寫程式碼期間,我一直在戰壕里工作,現在幫助其他開發人員升級,這使我很有資格為您提供這方面的建議。 首先,讓我們先了解一下軟體開發行業目前正在發生什麼… **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** ## 現在的情況 像任何好醫生一樣,為了治療症狀,我們必須了解背後的問題。 開發人員就業市場就像任何市場一樣,受簡單的供需機制控制。對開發者的需求越大,開發者的議價能力就越大。 對開發者的需求越少,我們的談判能力就越小。 如果你不斷地感覺自己與其他開發者比較,無法要求高薪,並且很難找到工作,這意味著你在市場上的力量很小。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ew79c0vwwkmkb6fkgg5j.jpeg) 供需關係決定開發者就業市場。 傳統上,開發者在市場上擁有大部分權力,公司會不遺餘力地獲得最好的工程人才。 這就是為什麼開發人員的薪水不斷增長以及每個人都想學習如何編碼的原因。 **但是,在過去 12 個月裡,權力已經從開發者轉移到了公司(除了頂層的開發者,稍後會詳細介紹)。** 為什麼? 很多原因。讓我們一一回顧一下… ## 1.“效率時代” 戰爭、通貨膨脹和經濟衰退迫使世界各地的公司最大限度地利用資金。包括軟體公司。 企業需要找到更有效的做事方式——如果您正在建立軟體,這意味著擺脫一些開發人員並自動化盡可能多的任務。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qtjm4nj6cilxu1nri3e.jpeg) 糟糕的經濟狀況迫使科技公司的執行長提高公司的效率。 正如馬克·祖克柏在他關於 Meta 的「效率年」的文章中提到的那樣,公司希望提高開發人員的生產力和工具並減少員工人數。 **一言以蔽之:科技公司希望盡可能精簡。** 這意味著軟體開發團隊不能再龐大了。他們需要一些高技能的開發人員以及大量的自動化設備。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xazs5u5i90cy86ryxhux.png) 這意味著縮小團隊規模(即:解僱表現不佳的員工)、取消優先順序較低的專案並降低招募率。用更少的軟體開發人員完成更多的工作。 對於開發人員就業市場來說,這可不是好訊息… **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** ## 2.人才海嘯 開發人員就業市場變得非常非常擁擠,有數百名候選人瞄準同一職位。 這是因為編碼技能變得越來越普遍。 在過去的十年中,訓練營和電腦科學學位一直在將軟體開發人員吸引到一個已經擁擠的市場中。尤其是訓練營,經過六週的編碼後,他們實現了六位數薪資的夢想。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ak3kyp3ivrnaf2oomgcc.jpeg) 這引發了一場「人才海嘯」。開發人員的工作被當作中產階級的金票出售。成千上萬的人放棄了學習編碼的希望。 然而,正如許多初級開發人員所看到的那樣,這主要是一種行銷承諾。 事實上,開發人員職位的競爭非常激烈,你在 3 個月的 Bootcamp 中學到的技能已經不足以脫穎而出。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ho072lld5gyddr0vq1ee.jpeg) 由於大量開發者在尋找黃金,就業市場很快就飽和了。 2020 年的情況就已經如此,但後來情況變得更糟… ## 3.遠距工作 Covid-19 大流行推動全世界轉向遠距工作。鑑於編碼基本上可以在任何地方完成,開發人員的工作是適應速度最快的工作之一。 對許多開發人員來說,在家工作聽起來像是個夢想。 無需通勤,擁有更多屬於自己的時間,並以相同的薪水在舒適的家中進行編碼,這是大多數人在任何給定時間都需要的交易。 但事實證明,遠距工作是一把雙面刃。 因為最終,公司透過增加招募人數而受益最多。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sctir1mrkya6tophrl30.png) 遠距工作意味著軟體公司現在可以僱用來自世界各地的開發人員。 本地職缺吸引了數十名遠距求職者,他們願意以少得多的錢做同樣的工作。正如《紐約時報》所說: **“遠距工作者普遍面臨更多競爭,並且更加依賴運氣。” - 紐約時報** 如果您想知道為什麼現在有數百甚至數千名求職者,那麼答案就是:遠端候選人。 大多數職缺現在都在收到來自世界各地的申請。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pq3697d8plsobcs7ipu3.png) 隨著遠距工作的興起,本地工作現在面臨國際競爭。 當我可以在中西部找到具有相同技能且至少少兩倍的錢的人時,為什麼還要雇用矽谷的開發人員呢? 在歐洲也一樣。 一家位於柏林的公司可以聘請一位位於德國中部小村莊的開發者。讓他們每個月來辦公室兩次。並少付給他們幾十萬歐元。 當然,一些公司採取了重返辦公室政策。 但從長遠來看,我們將看到越來越多的公司採用完全遠端的思維方式。從經濟學的角度來看,遠距工作很有意義。 **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** ## 4. 人工智慧與自動化 人工智慧已經存在很多年了,但從未像現在這樣出現在我們的生活中。 2023 年 10 月,OpenAI 發布了 ChatGPT。 近年來人工智慧創新的巔峰和迄今為止最好的人工智慧模型。它可以與您談論您的一天,也可以為您撰寫論文。 更糟的是,它可以編碼。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8p43t4w3jo3dy7itcwcf.png) 隨著人工智慧能夠編寫功能齊全的程式碼,許多開發人員都會問自己:“現在怎麼辦?” 如果有足夠好的提示,它可以比大多數人類開發人員更好、更快、更便宜地編寫程式碼。 當然,ChatGPT 無法自行思考。 這是一個巨大的統計機器。它會犯很多錯誤並且陷入循環。但是,這足以讓事情順利進行。而且情況只會變得更好。 GitHub 很快就做出了調整,將其整合到 GitHub Copilot 中,後者已直接在 VS Code 中可用。 從長遠來看,沒有人知道人工智慧將對就業市場產生什麼影響。 它會像某些人聲稱的那樣導致我們所知的編碼的終結嗎?或者它只是人類開發人員完成工作的工具? 我們所知道的是,在短期內,人工智慧透過自動化任務或完全取代一些工作,給就業市場帶來了更大的壓力。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/knbz25n83y18knp9sl27.png) 高盛估計,大約 29% 的電腦相關任務可以透過人工智慧自動化。 結果? **找到一份體面的開發人員工作變得越來越難。** 回到報價和供應曲線,開發者數量增加,但就業機會數量保持不變。 隨著市場上數百名開發人員尋找職位,軟體開發產業正遭受「Tinder 效應」的困擾。類似網路約會的現象。 就像約會應用程式中的熱門個人資料一樣,軟體公司現在面臨著數百種不同的選擇。數百名候選人和簡歷。 整理噪音並不容易。 你必須更快地放棄候選人。即使你拒絕了一個合適的開發者,總會有其他人在門口等著。 好吧,現在對於開發者來說情況並不好。 忍住眼淚,因為我會告訴你為什麼事情並不像大多數開發人員想像的那麼糟糕... # 好訊息 這場「完美風暴」讓大多數開發者感到驚訝。許多人覺得薪水過低,但同時又沒有勇氣去市場。 這創造了一個“技能差距”,你可以利用它來跑得更快。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2rip84pxxnjmom5twd5e.png) 「在陽光明媚的天氣裡你無法超越 15 輛汽車…但在下雨天你可以。」- Ayrton Senna **風雨飄搖的就業市場實際上可能是您將開發人員職業提升到全新水平的完美時刻。** 首先,不要像其他人一樣屈服於恐懼。恐懼會讓你癱瘓,擾亂你的思考。不要驚慌失措,而是要超越噪音。 裁員開始一年後,公司意識到消除成本實際上會阻礙他們的成長。 在資本主義中,一家不成長的公司就是一家正在消亡的公司。 公司需要重新開始創造價值。緊急。 更多價值,因為我們正處於經濟衰退之中,消費者只想要最優惠的價格。而且速度更快,因為競爭是全球性的。 **在軟體開發中,價值意味著功能。這意味著高品質的程式碼。** 那麼人工智慧呢? AI實際上刺激了市場。軟體公司別無選擇,只能將人工智慧模型整合到現有的軟體中。否則就有倒閉的風險。 你需要什麼? 開發者、開發者、開發者… 好吧,這就是為什麼這可能是您作為一個雄心勃勃的開發人員超越競爭對手的最佳時機: ## 1. 質量重於數量 是的,市場上的開發者總數有所增加。但他們的技術技能品質卻沒有。 經濟衰退可能在一夜之間發生,但技術掌握需要時間。 即使在這樣的市場條件下,大多數公司仍然抱怨很難找到符合其工作要求的合格開發人員。 企業的要求是否過高? 或許。 但是,這正是您可以利用的差距來保持競爭優勢。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vhlaajmxwuvmcj8j3hl.png) 市場上有如此多的噪音,這與您發送的申請數量無關。追求數量只會產生更多垃圾郵件。 重要的是您的簡歷和申請的品質。 這並不意味著您應該成為完美主義者。數字仍然很重要。在開始找工作之前,只需在[您的簡歷和LinkedIn 個人資料上做更多工作](https://dev.to/dragosnedelcu/how-to-find-a-developer-job-in-2023-with-little-or-no-experience-27h7)。 並專注於技術掌握而不是數字! ## 2. 人工智慧作為補充 正如我所提到的,人工智慧模型無法思考,至少目前還不能。事實證明,它們更多的是對開發人員工作的補充,而不是替代品。 人工智慧帶來的是更多透過人工智慧整合進行的軟體開發。對正在開發的軟體的需求不斷增加。 這似乎有悖常理,但事實證明,人工智慧和自動化對軟體產業的影響與 70 年代修建高速公路對汽車交通的影響類似。 更多的高速公路意味著更多的汽車空間,因此更多的人使用汽車。導致汽車流量增加,而不是減少! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6apqk9jlfffpi8ud11n5.png) 更多的高速公路,更多的汽車。更多人工智慧,更多程式碼。 人工智慧編碼工具將使產生的程式碼量倍增。 最終,這意味著更多的程式碼需要由人類檢查、驗證和維護。整體而言,需要更多的開發人員。 **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** ## 3. 現金仍為王 $$$ 有趣的是,開發人員的薪資仍在增加。但它們的成長並不相同。 事實上,大多數開發者都無法跟上通貨膨脹的腳步。許多人根本沒有加薪,儘管在市場上待了很久卻找不到職位。 其他人則獲得小幅加薪,例如 3%。由於去年通膨率約為 10%,這並不是加薪。又是減薪! 但是,一小群幸運的程式設計師的薪酬正在打破記錄。 事實上,我們在 theSeniorDev.com 上看到了這一點。許多高級開發人員的薪資創下歷史新高,即使在歐盟市場也超過 6 位數。 幾年前,如此高的報價是非常不尋常的。 但是,如果你仔細想想,更高的薪水是有道理的。 一家公司面臨著交付一款可以為他們帶來數百萬美元收入的軟體的壓力,他們不會介意為能夠交付該軟體的開發人員額外花費數千美元。 這樣想吧,熟練勞力不是商品。 公司不會購買一雙一模一樣的鞋子並尋求優惠。有些鞋子會讓他們走得更快。為他們支付更多費用是有道理的。 **無論是矽谷或歐洲科技中心,趨勢都很明顯:熟練的開發人員需求量很大,公司願意為他們支付大量資金。** 正如您所看到的,事情並不像大多數開發人員想像的那麼糟糕。 至少不適合所有開發人員... 因為如果你和你的資深朋友交談過,你可能會發現有一群開發者做得併不差…。 ## 僅限資深開發人員的就業市場 儘管發生了一切,但高階開發人員的需求仍然非常大。您可以在招聘板上看到它,其中指定:僅限高級。 或查看誰正在被雇用並立即簽署工作合約。 Hired.com 的一份報告顯示,目前簽署工作合約的軟體開發人員中有超過 73% 擁有 7 到 5 年(或更長)的經驗。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0axdi46s6kfnph2ek2x.png) 高級開發人員受最近科技業裁員的影響最小。 感覺無論經濟如何發展,成為高級開發人員都會有回報。或多少程式碼 A.I.可以生成。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8iwtihn2647c81nv2gvn.png) 如果就業市場是動物農場。所有開發人員都是平等的,但高級開發人員比其他人更平等。 如果市場如此糟糕,為什麼高級開發人員仍然受歡迎? 從公司的角度來看,高階開發人員從第一天起就可以創造價值。 公司知道,他們比以往任何時候都更需要快速、優質的交付,才能在當前經濟狀況下保持競爭力。通貨膨脹,記住。 所有這些因素意味著整個軟體開發團隊將崩潰為少數開發人員利用兩個要素: 1. **高級開發人員** 2. **人工智慧工具和自動化** 儘管發生了這一切,但也不全然是壞訊息。堅持幾秒鐘,我會告訴你原因。 **事實是,您可以利用當前的情況來發揮自己的優勢。** **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** # 真相 為了在這個充滿活力的就業市場中取得成功,您將需要比與您競爭的其他數千名開發人員更可靠的策略和更有效率的流程。 您需要立即採取行動,因為… 提供高薪、酷炫技術堆疊、良好福利和遠距工作的開發人員工作每天都變得越來越有競爭力。 這並不意味著他們不可能到達。簡而言之,獲得開發人員工作的舊方法不再有效。 如果您需要其他 5 名開發人員的幫助才能將程式碼投入生產,那麼您的日子就很寶貴了。還有另一個開發人員可以提供端到端的服務,他們將取代您的位置。 所以你會怎麼做? 正如我的一位招募人員朋友所說: **「你最好的選擇是盡快成為高級開發人員」。** 盡快達到高級水平是目前在軟體開發市場中生存的唯一途徑。 成為高級開發人員將使您從眾多編碼人員中脫穎而出,提供端到端的價值,並被視為對公司的投資,而不僅僅是另一個昂貴的開發人員。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/882onhgzj1btfpvppdvu.png) 聰明的開發人員正在尋找提供更多服務並脫穎而出的方法。他們正在尋找快速實現這一目標的方法。 他們首先需要解決的是如何提升自己的技術能力。 好訊息是,您不需要在周末花費無數時間或編碼來實現這一目標。您不需要啟動數百個線上課程和副專案。 而且您不需要等待數年才能做到這一點。因為有更好的方法可以做到這一點。 你只需要專注在那些不會改變的事情上。 **那麼,如何獲得對自己技能的完全信心、端到端交付並釋放高級信心?** 您遵循基於經過驗證的軟體開發原則的逐步過程。就像高級開發人員每天使用的那樣。我們稱之為技術掌握藍圖。 在接下來的幾行中,我將更深入地討論具體步驟,但這不是本文的目標。 如果您有興趣了解更多訊息,可以單擊下面的連結並觀看我為您準備的免費培訓。 [這是免費培訓的連結。](https://bit.ly/3udWD0m) **免責聲明**:您必須加入您最好的電子郵件才能存取它。別擔心我不會寄垃圾郵件給你。我只會與您分享有關如何快速晉升高級開發人員並讓您的開發人員職業生涯提升到一個全新水平的相關資訊。您可以隨時取消訂閱。 **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** ### 1. 首先,你要採取資深開發人員的心態🧠 成為高級開發人員的第一步是改變您對軟體開發職業和整個生活的看法。 這意味著要以更高的標準要求自己。對您目前的開發者職業生涯承擔全部責任。並掌控你的職涯道路。 你也必須擺脫限制性信念或任何內在的關於自己的負面情緒。你必須養成新的習慣並培養紀律技能。 這意味著設定明確的重點目標,為自己定義一個在情感上令人信服的願景,並在執行這些目標時對自己負責。 **🚀[行動專案]**:準確定義您想要在未來 12 個月內實現的目標。為什麼想實現它?到達那裡需要採取哪些步驟?你是否缺乏任何知識和技能?你需要做一些與現在不同的事情才能到達那裡嗎?寫下來。 當你走向高級開發的旅程時,這將是讓你的火焰保持活力的燃料。大多數開發人員從未到達那裡,因為他們退出得太早。他們忘記了過程就是目標。 ### 2. 其次,你掌握了「基礎知識」📚 大多數開發人員,特別是 JavaScript 開發人員已經習慣相信軟體開發中的資歷就像一個購物袋。 新增的庫和框架越多,其等級就越高。 事實上,情況完全相反。高級開發人員平均編寫的程式碼比初級開發人員少。他們使用不太閃亮的庫和框架來解決問題。 沉迷於框架和庫會讓你成為炒作列車的受害者。當一個圖書館失寵時,另一個圖書館就會出現,需要您投入時間和注意力。這是一場你無法獲勝的遊戲。 如何才能逃脫炒作機器? 透過專注於**「不會改變的事情」**。我們所說的基礎知識。 模式和原則是大多數框架和函式庫的核心。對基礎知識的深入理解將確保您無論情況如何變化都能掌握最新資訊。 它還可以保護您免受人工智慧和自動化的影響。在程式碼在幾秒鐘內產生的世界中,清晰的思維變得越來越有價值。雙贏。 基礎知識取決於您的技術堆疊。 如果您是 JavaScript 開發人員,您主要需要掌握 2 組基礎知識。電腦科學基礎知識和 JavaScript 基礎知識。 這不是本文的範圍,但我整理了一個路線圖,供您準確了解這些內容,請參見下文。 🚨 PS有關“計算機科學基礎知識”的詳細列表,請查看[計算機科學基礎知識掌握路線圖](https://mm.tt/app/map/2980765378?t=LsjjpEBYky)。🚨 🚨附言有關「JavaScript 基礎知識」的詳細列表,請查看我們的 2023 年 [JavaScript 基礎知識掌握路線圖](https://mm.tt/app/map/2962635113?t=ILeYm71vU3)。🚨 順便說一句,我們免費社群的開發人員可以存取獨家內容和針對基礎知識的客製化練習。請在下面註冊! **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** ### 3. 第三,您學習如何端到端交付🎯 任何科技公司執行長現在最不想做的就是僱用更多的開發人員。但他們確實想解決問題。很多問題。 但是,你無法真正解決問題,我的意思是,當你只建構孤立的功能時,會出現有價值的問題。或者當您需要另外 5 名開發人員的幫助才能將您的東西投入生產時。 **高級開發人員之所以需求如此巨大,是因為他們可以提供端到端的服務。** 他們可以與產品經理或其他利害關係人獨立工作,並從第一天起就交付價值。掌握了這一點,你的價值就會增加10倍。 端到端交付並不意味著您必須了解一切。 這意味著您需要了解後端以及基礎設施方面的情況。目前無需深入研究各個元件。但從大局來看是的。 **[進階開發提示]**:學習如何端到端交付的最快方法不是 100 小時的雲端憑證課程(這些課程的重點是向您推銷品牌,而不是教您東西) )。 相反,請嘗試規劃您公司的 CI/CD 流程。 找出他們擁有的任何架構圖,然後自己參與其中。如果他們沒有,請自己建造一些。這已經可以給你一個良好的開始,並在你的下一次技術面試中談論很多事情。 🚨附言要確切了解您需要掌握哪些端對端交付心理模型,請查看我們的[JavaScript 開發人員的「端對端交付」路線圖](https://mm.tt/app/map/2974013323?t=pqAIdWZ7W2 ).🚨 **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** ### 4.第四,成為「AI驅動」🚀 當我接到想要加入我們專案的開發人員的電話時,最令我驚訝的事情之一是他們每天很少使用人工智慧。 有些人多次使用 ChatGPT 來執行日常任務(樣板檔案、測試)。真正使用過 GitHub Copilot 的人就更少了。 他們告訴我他們不相信它的未來。或者他們的公司並沒有真正使用它。 如果你在飛機上,氧氣會耗盡,我敢打賭,即使機組人員沒有給你,你也會尋找氧氣面罩。 ChatGPT 和 GitHub Copilot 不只是更好的自動完成工具。自動完成無法重構、尋找程式碼中的錯誤或擴充功能。 人工智慧模型可以優化、重構,甚至可以比許多開發人員提出更好的程式碼。事實上,到 2023 年,在人工智慧工具的幫助下,初級開發人員可以完成與沒有人工智慧工具的高級開發人員一樣多的工作。 重點很明確:如果您是願意轉為高級的 JavaScript 開發人員,您需要成為「人工智慧驅動」。 如果您已經是大四學生並希望在未來幾年保持相關性,情況也是如此。潮流正在改變。透過升級這些技能來確保您處於正確的位置。 您是否必須學習 Python、Numpy、深度學習以及 AI 堆疊中的十幾種工具?並不真地。這是一項完全不同的工作。 **這意味著你應該將人工智慧工具整合到你所做的一切中。** 從建置功能到程式碼審查,再到測試和效能優化。如果您希望我寫一篇有關如何做到這一點的文章,請在評論中告訴我。 **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** ### 5.第五,有效推銷自己🏆 如果你找不到一家公司來支付你的技能費用,那麼無論你是多麼優秀的開發人員,也沒有用。由於開發人員就業市場已經過度飽和,這一點更加正確。 為了脫穎而出並獲得頂級軟體開發人員的職位,您必須以盡可能最好的方式將自己推向市場。 作為一名員工,這一點更為重要,因為您應該始終擔心的一件事是您的就業能力。 **如果你明天被解僱,你找到另一個職位有多容易?** 你越有就業能力就越好。 您的就業能力取決於兩件事。您的產品(在這種情況下,您的開發技能和支持這些技能的過去經驗)。 其次,你如何推銷自己和你的人脈。有多少人認識你?如果你現在被解僱,明天有人可以提供你工作嗎? 要改進您的產品,請提高您的開發技能。我們在前面的幾點中討論過這一點。但如何改進自我推銷的方式呢? **好吧,如果你想要高級開發人員的薪水,你首先必須看起來像高級開發人員。** 這意味著建立一份相關的履歷,以最好的方式量化以展示您為市場帶來的東西。 如果您想讓我寫一篇關於如何打造一流開發人員履歷表的文章,請在評論中告訴我! ## 總結與後續步驟 好吧,現在你知道了。 下次當你問自己為什麼現在找到開發人員的工作如此困難時,請考慮這些原因。您還了解如何透過盡快成為高級開發人員來解決這個問題。 能夠落實這 5 個支柱並以最快的速度適應這個新市場範式的開發人員將獲得工作保障、對自己的技能充滿信心並獲得最高的薪水。 無法適應的開發者將慢慢被淘汰,並面臨被完全擠出市場的風險。 按照我在本文中概述的步驟操作,您不僅可以輕鬆找到開發人員工作,而且可以「快速」晉升到高級開發人員級別,並將您的開發人員職業生涯提升到一個全新的水平。 他們為我和世界各地 230 多名其他開發人員工作,他們也將為您工作! 我們下一篇再見 德拉戈斯 **🚨附:您是否希望快速晉升為擁有優質資源、回饋和責任的高階開發人員? [點擊此處加入我們的免費社區 - 高級開發學院。](https://bit.ly/46hbx3h)🚨** --- 原文出處:https://dev.to/dragosnedelcu/why-is-it-so-hard-to-find-a-developer-job-in-2023-and-how-to-fix-it-2d13

🙌 像專業人士一樣建立 GitHub 個人資料的 7 個技巧🚀

嘿朋友們👋 曾經造訪過某人的 Github 個人資料並思考過: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7abcd75k05wkjwjpdmdp.gif) 在本文中,我將嘗試向您展示建立專業的 GitHub 個人資料比您想像的要容易得多。 沒錯,即使您不是經驗豐富的專家,您也可以讓您的個人資料看起來可靠。 這是我的 GitHub 個人資料的範例。讓我們深入探討如何在接下來的 10 分鐘內讓您的個人資料看起來同樣完美。 😉** [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcvypyr17rtl23wz96j1.png)](https://github.com/fernandezbaptiste) 準備好了,出發吧⏰ --- # 1. 建立您的 GitHub 設定檔:新增 `README` 如果您還沒有這樣做,則必須建立自己的 GitHub「自述文件」來建立您的個人資料頁面。 為此,請轉到您的個人資料並點擊“您的儲存庫”。 之後,建立一個「New」儲存庫: - 儲存庫的名稱需要與您的使用者名稱相同。 - 確保將儲存庫設為“公開” - 點擊“新增自述文件” ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4esiem3zolcfqpcawoq.png) --- # 2. 為您的儲存庫建立一個開源儲存庫 🤫 不久前我發現了這個[repo](https://github.com/rahuldkjain/github-profile-readme-generator),我愛上了它。❤️ 這個很酷的專案可以幫助您立即建立自己的 GitHub 個人資料! 前往 [GitHub Profile README Generator](https://rahuldkjain.github.io/gh-profile-readme-generator/) 並填寫您的資料。 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kgzoys92q078jfwoy2eu.png)](https://rahuldkjain.github.io/gh-profile-readme-generator/) **注意:** 您不需要完成每個部分;僅相關的。 完成後: - 點擊“生成自述文件” - 然後點選“複製markdown” - 前往您新建立的 GitHub 個人資料並將程式碼貼到您的「自述文件」中 💪 --- # 3. 使用小工具提升您的個人資料設計水平 您現在應該擁有一個看起來非常漂亮的個人資料! 為了提高您的遊戲水平,您可以加入一些優雅的小部件,這些小部件提供有價值的統計資料來展示您的技能和成就。 🚀⭐️ 就我而言,我已將這些加入到我的[個人資料](https://github.com/fernandezbaptiste): [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96bqxqtbpbl9mi7nki7k.png)](www.quine.sh/?utm_source=devto&utm_campaign=beautify_github_profile) 您也可以加入一些小工具來展示您的 _Web3_ 或 _StackOverflow_ 體驗: [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1d4ewrrl0ukqz28kcag.png)](www.quine.sh/?utm_source=devto&utm_campaign=beautify_github_profile) 這些小工具_完全免費_,您可以透過註冊 [quine.sh](www.quine.sh/?utm_source=devto&utm_campaign=beautify_github_profile) 來取得它們。 只需前往您的 Quine 個人資料上的_“Widgets”_,然後將複製的 Wiget 程式碼貼到您的「自述文件」頁面中即可。 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xksq52zpha8lxeocfo4c.png)](www.quine.sh/?utm_source=devto&utm_campaign=beautify_github_profile) --- # 4.「美化」你的聯絡資訊💄 您可能不喜歡 GitHub README 產生器中的某些設計。 🙃 有些人喜歡不同的風格,尤其是與他們的_社交連結/連結輸出相關的風格。_ 您可以使用以下替代樣式: [![github](https://img.shields.io/badge/GitHub-000000?style=for-the-badge&logo=GitHub&logoColor=white)](https://github.com/fernandezbaptiste) 如果您喜歡這種風格,您可以使用此合成器建立自己的徽章: ``` ![<Badge Name>](https://img.shields.io/badge/<Badge Text>-<Background Color>?style=for-the-badge&logo=<Icon Name>&logoColor=<Logo Color>) ``` 例如,如果您想新增 **GitHub 徽章**,則為: ``` ![github](https://img.shields.io/badge/GitHub-000000?style=for-the-badge&logo=GitHub&logoColor=white)] ``` 根據您想要顯示的橫幅圖示的類型,您可以在此清單中找到許多簡潔的圖示[此處](https://simpleicons.org)。 🙌 --- # 5.利用 PIN 儲存庫功能 如果您已經建立了幾個專案,那麼這是展示您最引以為傲的專案的好機會! 在您的個人資料上,只需點擊“自訂您的 pin”,然後選擇最多 6 個您想要固定的專案。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ct3s69ar9qn41zc721a.png) --- # 6. 貢獻並升級你的遊戲! 在您的 PIN 儲存庫之後,您的個人資料將顯示以下網格。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lnqhh19a3ceuicoq56tn.png) 這代表您**在 GitHub 上的貢獻和活動水平。** 需要強調的是,儘管您應該嘗試透過經常貢獻來展示您的一致性,但此欄上的「綠色度」百分比並不是最重要的方面。 👀 許多人專注於試圖建立完美的連勝,但實際上,他們的工作沒有影響力,他們的貢獻也沒有什麼價值。 在我看來(我相信很多人都有同樣的看法),貢獻應該集中在: **品質 > 數量** ❤️ 話雖如此,定期建立幾個專案或為其他人的專案做出貢獻符合您的利益。 現在,為了嘗試為專案做出貢獻,您可以使用多種工具。 🔎 這裡有 3 個免費網站,可以幫助您找到下一個要從事的專案: - [GitHub 探索](https://github.com/explore) - [UpForGrabs](https://up-for-grabs.net/#/filters?tags=python&date=1month) - [Quine.sh](https://quine.sh/?&utm_source=devto&utm_campaign=beautify_github_profile) 或者,如果這是您第一次貢獻,我已經建立了這篇逐步[文章](https://dev.to/quine/contribute-to-open-source-in-the-next-10-min-step-by-step-beginner-edition-4aia)適合初學者。您將學習在 GitHub 上做出貢獻的機制,並能夠在接下來的 10 分鐘內做出貢獻! --- # 7. 新增個人簡介 我們已準備好進行最後的潤色... 現在你的個人資料看起來應該會很火。 🔥 我建議您做的最後一件事就是完成您的“簡歷”。 當您進入個人資料頁面時,請轉到照片下方的左側,然後按一下「編輯個人資料」。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d81dlk34hdigvmzgo5c1.png) 加入您自己的簡短描述,然後您就可以開始了! --- 現在就這樣。 😄 我希望您對**您精美的 GitHub 個人資料**感到滿意! 💅 我必須強調,我的個人資料還遠遠不是世界上最好的... 然而,有了這些免費工具,您將能夠自訂一個奇妙的新設定檔! 這就是為什麼我想先睹為快,並從您將建立的酷炫設定檔中獲得靈感! 👀 `在評論部分分享您全新的個人資料! 🙌` 下週見。 你的開發夥伴, 巴巴💚 --- 如果您想加入開源中自稱「最酷」的伺服器😝,您應該加入我們的[discord伺服器](https://discord.com/invite/ChAuP3SC5H/?utm_source=devto&utm_campaign=beautify_github_profile)。我們隨時為您的開源之旅提供協助。 🫶 [https://dev.to/quine](https://dev.to/quine) --- 原文出處:https://dev.to/quine/7-tips-to-build-your-github-profile-like-a-pro-38bg

10 個給 Web 開發者的好用 Chrome 外掛

## 介紹 Web 開發人員社群致力於建立能夠吸引目標受眾注意力的網站。成員總是在學習新的東西並創造有影響力的東西。這意味著生產力在他們的成功之路上發揮著重要作用。 網路上有許多我們可以遵循的技術來提高我們的生產力。 Chrome 擴充功能就是這樣一種技術,它使我們能夠提高我們致力於技術的辛勤工作的成果。 在本文中,我們將發現 10 個有用的 Chrome 擴充程序,它們可以提高 Web 開發人員的工作效率並讓我們的生活變得更美好。 ## Loom ![Loom](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qfklh8cwrpcev4t9anhu.jpg) [Loom](https://chromewebstore.google.com/detail/loom-%E2%80%93-screen-recorder-sc/liecbddmkiiihnedobmlmillhodjkdmb) 是 Chrome 線上應用程式商店中最常用的螢幕錄製擴充功能之一。它使我們能夠記錄螢幕、以圖形方式分享我們的想法並提供即時回應。 ## Window Resizer ![視窗大小調整器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjy8xcsa2jih0gr8z27z.jpg) [Window Resizer](https://chromewebstore.google.com/detail/window-resizer/kkelicaakdanhinjdeammmilcgefonfh) 調整瀏覽器視窗的大小以複製不同的解析度。它給我們一種個性化的感覺,因為它允許我們加入、刪除和重新排序我們想要測試的解析度清單。 ## 檢查我的連結 ![檢查我的連結](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzrr7hl03dhk1j2tu2tv.jpg) [檢查我的連結](https://chromewebstore.google.com/detail/check-my-links/ojkcdipcgfaekbeaelaapakgnjflfglf) 是一個連結分析器,用於掃描我們的網站是否有損壞的連結。此擴充功能專為網頁開發人員量身定制,因為他們始終致力於使網站內容完美無缺。 ## Wappalyzer ![Wappalyzer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uh8nfny8e3h914zxosnf.jpg) [Wappalyzer](https://chromewebstore.google.com/detail/wappalyzer-technology-pro/gppongmhjkpfnbhagpmjfkannfbllamg) 是一個技術堆疊評估器,列出了用於建立網站的工具和技術。它使我們能夠了解 CMS(內容管理系統)、框架、JavaScript 庫等。 ## Session Buddy ![會話好友](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sxhi33bxt0cs2m313uzy.jpg) [Session Buddy](https://chromewebstore.google.com/detail/session-buddy/edacconmaakjimmfgnblocblbcdccpbko) 是一個擴展,使我們能夠方便地管理瀏覽器選項卡和書籤。它將打開的選項卡保存為集合,我們可以稍後在任何給定時間點恢復。 ## Lighthouse ![燈塔](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wijphg7u3a1htt3oavdd.jpg) [Lighthouse](https://chromewebstore.google.com/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk) 是開源自主工具,用於提高網路應用程式的品質、效率和準確性。它透過在頁面上執行一系列測試來審核頁面,然後產生總結頁面效能的報表。 ## Requestly ![請求](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0qa3uoc7g2qsguucri9n.jpg) [Requestly](https://chromewebstore.google.com/detail/requestly-open-source-htt/mdnleldcmiljblolnjhpnblkcekpdkpa) 讓我們可以使用攔截和修改HTTP 請求、模擬伺服器、API 用戶端和會話記錄來建置、測試和會話記錄來建置、測試和除錯Web 應用程式。它將 Fiddler、Charles Proxy 和更多此類工具的功能引入瀏覽器,並具有有吸引力的現代 UI。 ## Grepper ![Grepper](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1o5sf4arl30ass61xpgf.jpg) [Grepper](https://chromewebstore.google.com/detail/grepper/amaaokahonnfjjemodnpmeenfpnnbkco) 是一個回答開發人員社群查詢的擴充。它使我們能夠從網路上快速提取程式碼片段,然後將其用於我們的專案中,以在我們的旅程中取得進展。 ## BrowserStack ![BrowserStack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c2xzz5en8vux6k9oijkb.jpg) [BrowserStack](https://chromewebstore.google.com/detail/browserstack/nkihdmlheodkdfojglpcjjmioefjahjb) 使我們能夠在桌面或行動瀏覽器上測試我們的網站。對於希望將跨瀏覽器測試作為其開發工作流程不可或缺的一部分的 Web 開發人員來說,這是一個有用的擴充功能。 ## Octotree ![Octotree](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9fly17l9cn4m6jztewe.jpg) [Octotree](https://chromewebstore.google.com/detail/octotree-github-code-tree/bkhaagjahfmjljalopjnoealnfndnagc) 是一個擴展,可以幫助我們在 GitHub 上進行程式碼審查和探索。使用此工具,我們可以為儲存庫、問題、拉取請求和文件加入書籤,執行快速搜尋並輕鬆導航拉取請求。 ## 結論 我們已經到達終點了!我們上面討論的擴充功能非常有幫助,並且能夠大幅提高工作量。因此,讓我們使用它們,並在各自作為 Web 開發人員的旅程中不斷取得進展。 **快速說明:** > 感謝您花時間閱讀我的文章。這對我來說意義重大,並促使我創作更多這樣的內容。 **我的社交:** - [LinkedIn](https://www.linkedin.com/in/sriparnooy/) - [推特](https://twitter.com/Sriparno08) - [GitHub](https://github.com/Sriparno08) - [CodePen](https://codepen.io/Sriparno08) **我的部落格:** - [展示案例](https://www.showwcase.com/sriparno08) - [DEV](https://dev.to/sriparno08) - [哈希節點](https://hashnode.com/@sriparno08) --- 原文出處:https://dev.to/this-is-learning/10-useful-chrome-extensions-for-web-developers-meg

在 JS 應用程式中載入環境變數

#### 如何儲存並使用本機開發的環境變數 API 和第三方整合要求開發人員使用稱為**環境或配置變數**的配置資料。這些變數通常儲存在受密碼保護的地方,例如 CI 工具或部署管道,但是當我們在本地開發應用程式時如何使用它們? ![](https://cdn-images-1.medium.com/max/1024/1*iTLvajtJ6tN3DnHArGKkDA.png) #### 簡介 - 不要在原始碼管理中儲存環境變數 - 使用 [dotenv](https://github.com/motdotla/dotenv) 從 .env 檔案讀取資料 - create-react-app 在環境變數上強制命名空間 這個簡短的教程將解釋在本地開發時將環境變數載入到程式碼中的一種方法。主要好處是 API 金鑰等秘密不會提交給原始碼控制,以確保您的應用程式更安全。 #### 要求: - 一個 JavaScript 應用程式 - 套件管理器(yarn 和 npm 都很棒) - Node 7+ ### 設定變數 在儲存庫的根目錄中建立一個名為「.env」的檔案。該文件稱為“點文件”,與常規文件不同,它通常隱藏在文件瀏覽器中。 大多數 IDE 允許使用者建立沒有名稱的文件,但如果情況並非如此,請轉到終端並 cd 進入應用程式的根資料夾。 ``` touch .env ``` 接下來,使用格式 key=value 設定變數,並以換行符號分隔: ``` API_KEY=abcde API_URL=https://my-api.com/api ``` 最後,確保 .env 檔案未提交到您的儲存庫。這可以透過開啟(或建立).gitignore 檔案並新增以下行來實現: ``` .env # This contains secrets, don't store in source control ``` ### 使用變數 前往終端使用您首選的套件管理器安裝 [dotenv](https://github.com/motdotla/dotenv): ``` # Using npm: npm i dotenv # Using yarn: yarn add dotenv ``` 現在您已準備好讀取 .env 檔案。儘早在您的應用程式中加入這行程式碼。對於 React 應用程式,通常是 index.js 或 App.js,但這完全取決於您的設定: ``` require('dotenv').config(); ``` 就是這樣!您的應用程式應該可以透過 process.env 物件存取環境變數。您可以透過撥打以下電話進行雙重檢查: ``` console.log(process.env); ``` 如果一切順利,您應該會看到類似以下內容: ``` { NODE_ENV: "development", API_KEY: "abcde", API_URL: "https://my-api.com/api" } ``` 🎉 現在您可以在應用程式中使用環境變數了! 現在,對於我們這些使用 create-react-app 的人來說,有一個問題,我希望它能被更好地記錄下來。 ### 使用 create-react-app Facebook 的 [create-react-app](https://github.com/facebook/create-react-app) 的工作方式略有不同。如果您按照上述步驟操作但沒有彈出應用程式,那麼您應該看到的只是 NODE\_ENV 變數。這是因為 **create-react-app 只允許應用程式讀取帶有** **REACT\_APP\_ 前綴的變數。** 因此,為了使我們的變數起作用,我們需要像這樣更新我們的 .env 檔案: ``` REACT_APP_API_KEY=abcde REACT_APP_API_URL=https://my-api.com/api ``` 再次透過將 process.env 記錄到控制台來驗證您的設定: ``` { NODE_ENV: "development", REACT_APP_API_KEY: "abcde", REACT_APP_API_URL: "https://my-api.com/api" } ``` 你就完成了😎 ### 小技巧 .env 檔案中的變數不需要引號,除非值中有空格。 ``` NO_QUOTES=thisisokay QUOTES="this contains spaces" ``` 最好建立一個 .env.sample 檔案來追蹤應用程式應該期望的變數。這是我目前專案中的範例文件的樣子。請注意,它解釋了人們可以在哪裡找到這些金鑰和 URL。 ``` CONTENTFUL_SPACE_TOKEN="see Contentful dashboard" CONTENTFUL_API_KEY="see Contentful dashboard" S3_BUCKET_URL="check AWS" SHOW_DEBUG_SIDEBAR="if true, show debug sidebar" ``` ### 進一步閱讀: - [在 12-Factor App 方法中讀取環境中的設定](https://12factor.net/config) 感謝您的閱讀!您是否喜歡另一種在本地載入環境變數的方法?我很想在下面的評論中聽到它! --- 原文出處:https://dev.to/deammer/loading-environment-variables-in-js-apps-1p7p

使用 Python 和 Pytest 自動化 API 測試

您是否想過如何使用 python 測試您的 API?在本文中,我們將學習如何使用 Python 和 pytest 框架來測試我們的 API。 對於本教程,您需要安裝 python,您可以在[此處](https://www.python.org/downloads/)下載它 --- ### 簡介: - [什麼是 Python 和 Pytest 框架](#what-is-python-and-pytest-framework) - [我們專案的設定](#configuration-of-our-project) - [使用python建立虛擬環境](#creation-of-virtual-environment-with-python) - [測試的依賴關係設定](#setup-of-dependency-for-the-tests) - [建立我們的第一個測試](#creating-our-first-test) - [將被測試的 API 的定義](#definition-of-the-api-that-will-be-tested) - [建立我們的測試](#creating-our-test) - [重建我們的測試](#refactoring-our-tests) - [產生 html 報告結果](#generate-html-report-result) - [結論](#conclusion) --- ## 什麼是 Python 和 Pytest 框架 「Python」是一種高級通用程式語言,以其簡單性和可讀性而聞名。它由 Guido van Rossum 建立,於 1991 年首次發布。 Python 的設計易於學習,並且具有乾淨簡潔的語法,這使其成為初學者和經驗豐富的程式設計師的流行選擇。 「pytest」框架可以輕鬆編寫小型、可讀的測試,並且可以擴展以支援應用程式和程式庫的複雜功能測試。 --- ## 我們專案的配置 ### 用python建立虛擬環境 在開始建立之前,我們先來了解一下什麼是Python上的虛擬環境。 Python 中的虛擬環境是一個獨立的目錄或資料夾,可讓您為專案建立和管理隔離的 Python 環境。透過環境,您可以輕鬆管理依賴項,避免與不同版本的 python 發生衝突。 虛擬環境(除其他外)是: - 用於包含支援專案(庫或應用程式)所需的特定 Python 解釋器以及軟體庫和二進位檔案。預設情況下,它們與其他虛擬環境中的軟體以及作業系統中安裝的 Python 解釋器和庫隔離。 - 包含在專案目錄中的目錄中,通常名為“venv”或“.venv”,或在許多虛擬環境的容器目錄下,例如“~/.virtualenvs”。 - 未簽入原始碼控制系統(例如 Git)。 - 被認為是一次性的 - 應該很容易刪除並從頭開始重新建立它。您沒有在環境中放置任何專案程式碼 - 不被視為可移動或可複製 - 您只需在目標位置重新建立相同的環境。 您可以在[此處](https://docs.python.org/3/library/venv.html#venv-def)閱讀有關 python 環境的更多資訊。 #### 視窗 首先,為您的專案建立一個資料夾,然後打開 cmd 並使用命令 cd 導航到該資料夾: ``` cd tests_with_python ``` 如果您不知道資料夾在哪裡,可以執行命令“ls”,您將看到資料夾列表,並且可以瀏覽它們。在我們的專案資料夾中,執行以下命令: ``` python -m venv name_of_environment ``` 您的環境名稱可以是任何人,只需記住python 區分大小寫,請查看[PEP 8 風格指南](https://peps.python.org/pep-0008/) 以了解有關Python 約定的更多資訊. 要啟動我們的環境,我們使用以下命令: ``` name_of_environment\Scripts\Activate ``` 如果一切正確,您的環境將被激活,並且在 cmd 上您將看到如下所示: ``` (name_of_environment) C:\User\tests ``` 要停用您的環境,只需執行: ``` deactivate ``` #### Linux 或 MacOS 為您的專案建立一個資料夾,然後打開 cmd 並使用命令 cd 導航到該資料夾: ``` cd tests_with_python ``` 要啟動我們的環境,我們使用以下命令: ``` source name_of_environment/bin/activate ``` 如果一切正確,您的環境將被激活,並且在 cmd 上您將看到如下所示: ``` (name_of_environment) your_user_name tests % ``` 要停用您的環境,只需執行: ``` deactivate ``` ### 設定測試的依賴關係 當我們要測試 API 時,我們需要安裝依賴項來幫助我們進行測試,首先我們將安裝「requests」函式庫來幫助我們發出請求: PS:在執行此命令之前請確保您的環境已激活 ``` pip install requests ``` 為了進行測試,我們將安裝「pytests」框架: ``` pip install pytest ``` --- ## 建立我們的第一個測試 ### 將要測試的 API 的定義 在本教程中,我們將使用返回小行星列表的 Nasa API:[Asteroids - NeoWs](https://api.nasa.gov/#donkiGST),我們將測試檢索基於小行星列表的端點在他們最接近地球的日期。 關於API: - 基本網址:`https://api.nasa.gov/neo/rest/v1/feed` - 查詢參數: |參數|類型|預設|描述| | --------|---------|--------|--------------------| |start_date|YYYY-MM-DD|無|小行星搜尋的開始日期| |end_date|YYYY-MM-DD|start_date後7天|小行星搜尋的結束日期| |api_key|字串|DEMO_KEY|用於擴展用途的 api.nasa.gov 密鑰| 在本教程中,我們將重點放在三種類型的測試: - 合約:如果 API 能夠驗證傳送的查詢參數 - 狀態:狀態程式碼是否正確 - 身份驗證:即使這個API不需要令牌,我們也可以用它來做測試 我們的場景: |方法|測試|預期結果 | | --------|--------|--------------------| |獲取 |搜尋成功 | - 傳回狀態程式碼 200<br/> 正文回應包含小行星清單| |獲取 |無需任何查詢參數即可搜尋 | - 返回狀態碼403<br/>| |獲取 |僅搜尋開始日期| - 傳回狀態程式碼 200 <br/> 主體回應包含小行星清單| |獲取 |僅搜尋結束日期| - 傳回狀態程式碼 200 <br/> 主體回應包含小行星清單| |獲取 |在有效日期範圍內搜尋| - 傳回狀態碼 200<br/> - 正文回應包含所有非空白欄位| |獲取 |當開始日期大於結束日期時進行搜尋| - 傳回狀態程式碼 400 <br/>| |獲取 |使用無效的 API 令牌進行搜尋| - 傳回狀態程式碼 403 <br/> 主體回應包含小行星清單| ### 建立我們的測試 首先,我們將建立一個名為「tests.py」的文件,我們將在該文件中編寫測試。為了幫助我們使用良好的實踐並編寫良好的自動化測試,讓我們使用 [TDD(測試驅動開發)](https://www.browserstack.com/guide/what-is-test-driven-development?psafe_param=1?keyword=&campaignid=&adgroupid=&adid=8784011037660164696&utm_source=google&utm_medium=cpc&utm_platform=paidads&utm_content=602353912717&utm_campapaidads&utm_content=602353912717&utm_campa.utm_term=+&gad_source=1&gclid=CjwKCAiAxreqBhAxEiwAfGfndN8P705lwnkvEFnCz_lueR2hnhmZXgboBQEtKTaCIRbhcb1SXOxBYhoC-WoQAD_BwwE)技術。 該技術包括: - 紅色 - 進行失敗的測試 - 綠色 - 使此測試通過 - 重構 - 重構所做的事情,刪除重複的內容 為了編寫一套好的測試,我們將使用 3A 技術: - 安排:準備上下文。 - 行動:執行我們想要示範的行動。 - 斷言:表明我們預期的結果確實發生了。 從紅色開始,使用 3A 技術,我們將編寫第一個測試「成功搜尋小行星」: ``` import pytest def test_search_asteroids_with_sucess(): # Arrange: api_key = "DEMO_KEY" #Act: response = make_request(api_key) #Assertion: assert response.status_code == 200 # Validation of status code data = response.json() # Assertion of body response content: assert len(data) > 0 assert data["element_count"] > 0 ``` - 安排:我們建立一個變數來插入 api_key,在此步驟中,您可以插入執行測試所需的任何資料。通常,在這一步驟我們會建立模擬資料。 - Act:在這一步驟中我們呼叫了負責發出請求的方法 - 斷言:我們驗證回應 `方法或類別的名稱應以 test 開頭` 若要執行我們的測試,請在命令提示字元中執行: ``` pytest test.py ``` 我們將收到一個錯誤,因為我們沒有建立執行請求的方法: ``` test.py F [100%] ====================================================================== FAILURES ====================================================================== _________________________________________________________ test_search_asteroids_with_sucess __________________________________________________________ def test_search_asteroids_with_sucess(): > response = make_request() E NameError: name 'make_request' is not defined test.py:5: NameError ============================================================== short test summary info =============================================================== FAILED test.py::test_search_asteroids_with_sucess - NameError: name 'make_request' is not defined ================================================================= 1 failed in 0.01s ================================================================== ``` 現在,讓我們建立方法來執行請求: ``` import requests def make_request(api_key): base_url = "https://api.nasa.gov/neo/rest/v1/feed/" response = requests.get(f'{base_url}?api_key={api_key}') return response ``` 現在,再次執行我們的測試: ``` ================================================================ test session starts ================================================================= platform darwin -- Python 3.11.5, pytest-7.4.3, pluggy-1.3.0 rootdir: /Users/Documents/tests_python collected 1 item test.py . [100%] ================================================================= 1 passed in 20.22s ================================================================= ``` --- ## 重構我們的測試 現在我們已經了解如何使用 pytest 建立測試以及如何建立請求,我們可以編寫其他測試並開始重構測試。我們要做的第一個重構是從測試文件中刪除請求方法。我們將建立一個名為「make_requests.py」的新文件,其中將包含我們的請求,並將我們所做的請求移至此文件: ``` import requests def make_request(api_key): base_url = "https://api.nasa.gov/neo/rest/v1/feed/" response = requests.get(f'{base_url}?api_key={api_key}') return response ``` 現在,我們需要考慮在其他測試中重複使用此方法,因為我們需要為不同的測試傳遞不同的參數。我們可以透過很多方法來做到這一點,在本教程中,我們將參數的名稱從“api_key”更改為“query_parameters”。我們這樣做是為了讓我們的方法更加靈活,我們可以一次傳遞參數進行測試: ``` import requests def make_request(query_parameters): base_url = "https://api.nasa.gov/neo/rest/v1/feed/" response = requests.get(f'{base_url}?{query_parameters}') return response ``` 之後,我們需要更改我們的測試文件。我們將導入我們建立的這個方法: ``` from make_requests import make_request ``` 為了以更好的方式組織我們的測試,並遵循 pytest 文件的建議,我們將測試移至類別「TestClass」: 再次執行我們的測試: ``` ============================= test session starts ============================== collecting ... collected 7 items test.py::TestClass::test_search_asteroids_with_sucess test.py::TestClass::test_search_asteroids_with_query_parameters_empty test.py::TestClass::test_search_asteroids_with_start_date test.py::TestClass::test_search_asteroids_with_end_date test.py::TestClass::test_search_asteroids_in_valid_range test.py::TestClass::test_search_asteroids_in_invalid_range test.py::TestClass::test_search_asteroids_in_invalid_token ============================== 7 passed in 5.85s =============================== PASSED [ 14%]PASSED [ 28%]PASSED [ 42%]PASSED [ 57%]PASSED [ 71%]PASSED [ 85%]PASSED [100%] Process finished with exit code 0 ``` ### 產生 html 報告結果 為了更好地視覺化您的測試結果,我們可以使用 pytest-html-reporter 庫產生報告 html,為此,我們首先需要安裝該套件: ``` pip install pytest-html ``` 若要產生報告,請在執行測試時新增: ``` pytest test.py --html-report=./report/report.html ``` 將產生一個包含測試結果的 .html 文件,如下所示: ![report_example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eol3v7iex84t7prmyb9c.png) ## 結論 本文是一篇教程,介紹如何開始使用 python 和 pytest 框架為 API 編寫自動化測試以及如何產生一個報告 html。 您可以在[此處](https://github.com/aliciamarianne1507/tests_python)存取本教學中使用的專案。 我希望這些內容對您有用。 如果您有任何疑問,請隨時與我聯繫! 親親,下週見💅🏼 --- 原文出處:https://dev.to/m4rri4nne/automating-your-api-tests-using-python-and-pytest-23cc

Giskard 如何獲得第一批 1,200 顆星!

要將其作為影片觀看,請查看此 **YouTube**: https://www.youtube.com/watch?v=uEiWbR7wai0 --- 網紅和權威 =========================== 如果說世界上有什麼比任何行銷都更強大的話,那就是影響力。伊隆馬斯克被認為是有史以來最會貼廢文的人之一,但他發布的所有內容仍然引起了大量的迴響。 很多人傾向於相信我,因為我也在 GitHub 領域建立了一些權威。 這就是為什麼影響者是如此強大的管道。他們的權威和追隨者的意圖可以為公司帶來巨大的轉變。 Giskard 購買了[Santiago's](https://twitter.com/svpino?utm_source=nevo.github20k.com&utm_medium=referral&utm_campaign=how-giskard-got-their-first-1-200-starsign=how-giskard-got-their-first-1-200-stars) 服務來推廣他們的套件,並將其數量增加了一倍星星。 雖然星星是很好的指標,但正如你所知,我從有影響力的人那裡得到了很多星星,這些星星不一定會給我帶來合適的受眾,但會讓我在 GitHub 上成為趨勢。像聖地亞哥這樣的影響者是專注於雷射的影響者,他們實際上可以帶來客戶和良好的用戶(有購買力),**通常更少的明星。** 他們向優秀的影響者支付約 **700-1200 美元**。 ![](https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,format=auto,onerror=redirect,quality=80/uploads/asset/file/75633df4-1274-46e2-b1b4-a179cb45a4fb/image.png) --- 錯誤的副產品? ---------------------- Giskard 製作了一個名為 **SafeGPT** 的小產品 - 拼字檢查器。 他們在 [Super human newsletter](https://www.joinsuperhuman.ai/?utm_source=nevo.github20k.com&utm_medium=referral&utm_campaign=how-giskard-got-their-first-1-200-newsstarHacker) 以及[Showhower](https://news.ycombinator.com/show?utm_source=nevo.github20k.com&utm_medium=referral&utm_campaign=how-giskard-got-their-first-1-200-stars) 並獲得**2,000** 1週內註冊🔥 主要問題是 SafeGPT 是面向最終用戶的最終產品 **(不一定是開發人員),** 當他們嘗試將這些使用者轉換為 Giskard 時,他們沒有轉換,因為這是一個不同的市場。 實際上,我認為這並不是失敗。仍有一些方法可以利用非觀眾來幫助您完成不同的事情。 **你可以:** * 取得不同文章/Youtube 的反應 * 獲得一些社會證明(在社群媒體上關注) * 透過獎勵獲得星星。 --- 原文出處:https://dev.to/github20k/how-giskard-got-their-first-1200-stars-b8k

React 設計模式 Design Patterns

![](https://refine.ams3.cdn.digitaloceanspaces.com/blog-banners/retool-alternative.png) ## 介紹: React 開發人員可以透過使用設計模式來節省時間和精力,設計模式提供了一種使用經過測試且可信賴的解決方案來解決問題的快速方法。它們支援低耦合的內聚模組,從而幫助 React 開發人員建立可維護、可擴展且高效的應用程式。在本文中,我們將探索 React 設計模式並研究它們如何改進 React 應用程式的開發。 ## 容器和表示模式 容器和表示模式是一種旨在將反應程式碼中的表示邏輯與業務邏輯分離的模式,從而使其模組化、可測試並遵循關注點分離原則。 大多數情況下,在 React 應用程式中,我們需要從後端/儲存取得資料或計算邏輯並在 React 元件上表示該計算的結果。在這些情況下,容器和表示模式大放異彩,因為它可用於將元件分為兩類,即: * 容器元件,充當負責資料取得或計算的元件。 * 表示元件,其工作是將獲取的資料或計算值呈現在 UI(使用者介面)上。 容器和表示模式的範例如下所示: ``` import React, { useEffect } from 'react'; import CharacterList from './CharacterList'; const StarWarsCharactersContainer:React.FC = () => { const [characters, setCharacters] = useState<Character>([]) const [isLoading, setIsLoading] = useState<boolean>(false); const [error, setError] = useState<boolean>(false); const getCharacters = async () => { setIsLoading(true); try { const response = await fetch("https://akabab.github.io/starwars-api/api/all.json"); const data = await response.json(); setIsLoading(false); if (!data) return; setCharacters(data); } catch(err) { setError(true); } finally { setIsLoading(true); } }; useEffect(() => { getCharacters(); }, []); return <CharacterList loading={loading} error={error} characters={characters} />; }; export default StarWarsCharactersContainer; ``` ``` // the component is responsible for displaying the characters import React from 'react'; import { Character } from './types'; interface CharacterListProps { loading: boolean; error: boolean; users: Character[]; } const CharacterList: React.FC<CharacterListProps> = ({ loading, error, characters }) => { if (loading && !error) return <div>Loading...</div>; if (!loading && error) return <div>error occured.unable to load characters</div>; if (!characters) return null; return ( <ul> {characters.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }; export default CharacterList; ``` ## 有 Hooks 的元件組合 Hooks 是 React 16.8 中首次推出的全新功能。從那時起,他們在開發 React 應用程式中發揮了至關重要的作用。掛鉤是基本函數,可授予功能元件存取狀態和生命週期方法(以前僅可用於類別元件)的功能。另一方面,掛鉤可以專門設計來滿足元件要求並具有其他用例。 我們現在可以隔離所有狀態邏輯(一種需要反應性狀態變數的邏輯),並使用自訂掛鉤在元件中組合或使用它。因此,程式碼更加模組化和可測試,因為鉤子鬆散地綁定到元件,因此可以單獨測試。 帶有鉤子的元件組合示例如下所示: ``` // creating a custom hook that fetches star wars characters export const useFetchStarWarsCharacters = () => { const [characters, setCharacters] = useState<Character>([]) const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(false); const controller = new AbortController() const getCharacters = async () => { setIsLoading(true); try { const response = await fetch( "https://akabab.github.io/starwars-api/api/all.json", { method: "GET", credentials: "include", mode: "cors", headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, signal: controller.signal } ); const data = await response.json(); setIsLoading(false); if (!data) return; setCharacters(data); } catch(err) { setError(true); } finally { setIsLoading(true); } }; useEffect(() => { getCharacters(); return () => { controller.abort(); } }, []); return [ characters, isLoading, error ]; }; ``` 建立自訂鉤子後,我們將其導入到我們的 **StarWarsCharactersContainer** 元件中並使用它; ``` // importing the custom hook to a component and fetch the characters import React from 'react'; import { Character } from './types'; import { useFetchStarWarsCharacters } from './useFetchStarWarsCharacters'; const StarWarsCharactersContainer:React.FC = () => { const [ characters, isLoading, error ] = useFetchStarWarsCharacters(); return <CharacterList loading={loading} error={error} characters={characters} />; }; export default StarWarsCharactersContainer; ``` --- <橫幅隨機/> --- ## 使用Reducers進行狀態管理 大多數情況下,處理元件中的許多狀態會導致許多未分組狀態的問題,這可能是處理起來很麻煩且具有挑戰性的。在這種情況下,減速器模式可能是有用的選擇。我們可以使用減速器將狀態分類為某些操作,這些操作在執行時可以變更分組的狀態。 此模式允許使用它的開發人員控制元件和/或掛鉤的狀態管理,讓他們在發送事件時管理狀態變更。 使用減速器模式的範例如下所示: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbob3gmfxws8k4ti0cyx.png) 在上面的程式碼中,元件調度兩個操作: * “**login**”操作類型會觸發狀態更改,影響三個狀態值,即 **loggedIn**、**user**、**token**。 *“**註銷**”操作只是將狀態重設為其初始值。 ## 提供者的資料管理 提供者模式對於資料管理非常有用,因為它利用上下文 API 透過應用程式的元件樹傳遞資料。這種模式是一種有效的解決支柱鑽井問題的方法,這一直是 React 開發中普遍關注的問題。 為了實現提供者模式,我們首先建立一個提供者元件。 Provider 是 Context 物件提供給我們的一個高階元件。我們可以利用React提供的createContext方法來建構一個Context物件。 ``` export const ThemeContext = React.createContext(null); export function ThemeProvider({ children }) { const [theme, setTheme] = React.useState("light"); return ( <ThemeContext.Provider value={{ theme, setTheme }}> {children} </ThemeContext.Provider> ); } ``` 建立提供者後,我們將使用建立的提供者元件封裝依賴上下文 API 中的資料的元件。 為了從上下文 API 取得資料,我們呼叫 useContext 鉤子,它接受上下文作為參數(在本例中為 **ThemeContext**)。 ``` import { useContext } from 'react'; import { ThemeProvider, ThemeContext } from "../context"; const HeaderSection = () => { <ThemeProvider> <TopNav /> </ThemeProvider>; }; const TopNav = () => { const { theme, setTheme } = useContext(ThemeContext); return ( <div style={{ backgroundColor: theme === "light" ? "#fff" : "#000 " }}> ... </div> ); }; ``` ## 使用 HOC(高階元件)增強元件 高階元件接受一個元件作為參數,並傳回一個注入了附加資料或功能的增壓元件。 React 中 HOC 的可能性是由於 React 更喜歡組合而不是繼承。 高階元件 (HOC) 模式提供了一種增加或修改元件功能的機制,促進元件重複使用和程式碼共用。 HOC 模式的範例如下所示: ``` import React from 'react' const higherOrderComponent = Component => { return class HOC extends React.Component { state = { name: 'John Doe' } render() { return <Component name={this.state.name {...this.props} /> } } const AvatarComponent = (props) => { return ( <div class="flex items-center justify-between"> <div class="rounded-full bg-red p-4"> {props.name} </div> <div> <p>I am a {props.description}.</p> </div> </div> ) } const SampleHOC = higherOrderComponent(AvatarComponent); const App = () => { return ( <div> <SampleHOC description="Frontend Engineer" /> </div> ) } export default App; ``` 在上面的程式碼中, **<AvatarComponent/>** 由 **higherOrderComponent** 提供 props,它將在內部使用。 ## 複合元件 複合元件模式是一種 React 設計模式,用於管理由子元件組成的父元件。 這種模式背後的原理是將父元件分解為更小的元件,然後使用 props、上下文或其他反應資料管理技術來管理這些較小元件之間的互動。 當需要建立由較小元件組成的可重複使用、多功能元件時,這種模式會派上用場。它使開發人員能夠建立複雜的 UI 元件,這些元件可以輕鬆自訂和擴展,同時保持清晰簡單的程式碼結構。 複合元件模式的用例範例如下所示: ``` import React, { createContext, useState } from 'react'; const ToggleContext = createContext(); function Toggle({ children }) { const [on, setOn] = useState(false); const toggle = () => setOn(!on); return ( <ToggleContext.Provider value={{ on, toggle }}> {children} </ToggleContext.Provider> ); } Toggle.On = function ToggleOn({ children }) { const { on } = useContext(ToggleContext); return on ? children : null; } Toggle.Off = function ToggleOff({ children }) { const { on } = useContext(ToggleContext); return on ? null : children; } Toggle.Button = function ToggleButton(props) { const { on, toggle } = useContext(ToggleContext); return <button onClick={toggle} {...props} />; } function App() { return ( <Toggle> <Toggle.On>The button is on</Toggle.On> <Toggle.Off>The button is off</Toggle.Off> <Toggle.Button>Toggle</Toggle.Button> </Toggle> ); } ``` ## 道具組合 這需要從幾個相關的 props 建立一個物件,並將其作為單個 props 傳遞給元件。 這種模式允許我們清理程式碼並使管理 props 變得更簡單,當我們想要將大量相關屬性傳遞給元件時,它特別有用。 ``` import React from 'react'; function P(props) { const { color, size, children, ...rest } = props; return ( <p style={{ color, fontSize: size }} {...rest}> { children } </p> ); } function App() { const paragraphProps = { color: "red", size: "20px", lineHeight: "22px" }; return <P {...paragraphProps}>This is a P</P>; } ``` ## 受控輸入 受控輸入模式可用於處理輸入欄位。此模式涉及使用事件處理程序在輸入欄位的值發生變更時更新元件狀態,以及將輸入欄位的目前值儲存在元件狀態中。 由於React 控制元件的狀態和行為,因此該模式使程式碼比不受控制的輸入模式更具可預測性和可讀性,後者不使用元件的狀態,而是直接透過DOM(文件物件模型)對其進行控制。 受控輸入模式的用例範例如下所示: ``` import React, { useState } from 'react'; function ControlledInput() { const [inputValue, setInputValue] = useState(''); const handleChange = (event) => { setInputValue(event.target.value); }; return ( <input type="text" value={inputValue} onChange={handleChange} /> ); } ``` ## 使用forwardRefs 管理自訂元件 稱為 ForwardRef 的高階元件將另一個元件作為輸入並輸出一個傳遞原始元件引用的新元件。透過這樣做,子元件的 ref(可用於檢索底層 DOM 節點或元件實例)可供父元件存取。 當建立與第三方程式庫或應用程式中的另一個自訂元件互動的自訂元件時,在工作流程中包含 ForwardRef 模式非常有幫助。透過授予對庫的 DOM 節點或另一個元件的 DOM 實例的存取權限,它有助於將此類元件的控制權轉移給您。 forwardRef 模式的用例範例如下所示: ``` import React from "react"; const CustomInput = React.forwardRef((props, ref) => ( <input type="text" {...props} ref={ref} /> )); const ParentComponent = () => { const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); }, []); return <CustomInput ref={inputRef} />; }; ``` 在上面的程式碼中,我們使用「forwardRefs」從元件「<ParentComponent/>」觸發了另一個元件「<CustomInput/>」的焦點。 # 結論 我們在本文中討論了 React 設計模式,包括高階元件、容器呈現元件模式、複合元件、受控元件等等。透過將這些設計模式和最佳實踐合併到您的 React 專案中,您可以提高程式碼質量,促進團隊協作,並使您的應用程式更具可擴展性、靈活性和可維護性。 --- 原文出處:https://dev.to/refine/react-design-patterns-230o

最受軟體開發人員推薦的 20 本書

> _“信任,但驗證”_(“信任,但驗證”) > -- [俄羅斯諺語](https://en.wikipedia.org/wiki/Trust,_but_verify) --- 我整理了數十位程式設計師、經理、職業教練和其他行業專業人士的建議,為您帶來一份__軟體開發人員最推薦的20 本書__的清單,並附有一些簡短的摘要(亞馬遜提供)。我用於編制此清單的所有資料都可以作為 [GitHub 上的單一 Excel 工作簿](https://github.com/awwsmm/2020books) 免費提供。截至 __2019 年 10 月 19 日星期六__,我的元列表引用了 36 個來源,並包括 297 本獨特書籍的推薦。 我這樣做主要是為了幫助自己整理我在不久的將來想讀的書籍,同時也是為了幫助其他想要打下良好基礎,但可能會因網路上提出不同建議的不同列表而感到沮喪的人。當你可以綜合考慮_每個人的意見_時,為什麼要相信他們中的_一個_?不客氣,網路。 以下是我用來撰寫此清單的__經驗法則__: 1. 盡可能_不_包括_尋求_推薦的文章。 1. 對一本書的不同版本的推薦視為對同一本書的推薦,但對一篇文章內的多個版本的推薦不會重複計算。 1. 作者只_列出_他們已讀過或正在閱讀的書籍的文章_不_包括在內。文章必須以_推薦_書籍清單的形式呈現。 1. 包含針對特定_等級_開發人員(即 CTO、初級開發人員、新手)的清單。 1. 我嘗試跳過針對特定技術(即 PHP、CSS、Java)的列表,但有些列表中散佈著這些類型的書籍;關於所包含文章的每一本書都包含在我的書籍清單中,即使它是一本小說、特定於技術的或與程式設計無關的。 1. 儘管某些人的解釋可能略有不同,但就本列表而言,「軟體開發人員」、「軟體工程師」、「開發人員」、「程式設計師」和「編碼員」都是等效的。除非第 (5) 點也適用,否則包括針對上述任何內容的文章。 就我所知,這是__網路上最完整的軟體開發書籍推薦元列表__。我查看了 Google 返回的“圖書軟體開發人員”的“每一個結果”以及 Dev.To 上標題中包含“圖書”的每篇文章,這就是結果。如果您發現通用軟體開發的書籍推薦清單未包含在我在 GitHub 上的來源電子表格中,請告訴我。如果它符合我上面列出的標準,我很樂意將其加入到列表中。 言歸正傳,列表如下: --- ![Martin Fowler 的企業應用程式架構模式](https://thepracticaldev.s3.amazonaws.com/i/lee3yr9dzmevpfz8r6p3.jpg) ## \#20。 [企業應用架構模式](https://amzn.to/2jSqwQ5) ### 作者:Martin Fowler(_3 路並列 #19 和 #18_) #### 推薦 13.0% > 這本書其實是兩本書合而為一。第一部分是有關開發企業應用程式的簡短教程,您可以從頭到尾閱讀該教程以了解本書課程的範圍。下一部分,即本書的大部分內容,是對模式本身的詳細參考。每個模式都提供使用和實現訊息,以及詳細的 Java 或 C# 程式碼範例。整本書還配有豐富的UML圖來進一步解釋概念。 > > 有了這本書,您將擁有做出有關建立企業應用程式的重要架構決策所需的知識,以及建立它們時使用的經過驗證的模式。 > > -- [Amazon.com](https://amzn.to/2jSqwQ5) --- ![《清潔架構:軟體結構與設計工匠指南》,作者:Robert C.「Uncle Bob」Martin](https://thepracticaldev.s3.amazonaws.com/i/jeoyr1agokp3k43qtrzx.jpg) ## \#19。 [清潔架構:軟體結構與設計工匠指南](https://amzn.to/2jTxLHt) ### 作者:羅伯特·C·「鮑伯叔叔」·馬丁 #### 建議 13.0%(_3 路與 #20 和 #18 平手_) > - 了解軟體架構師需要實現什麼目標,以及實現它的核心規則和實踐 > - 掌握尋址功能、元件分離和資料管理的基本軟體設計原則 > - 了解程式設計範式如何透過限制開發人員可以執行的操作來施加紀律 > - 了解什麼是至關重要的,什麼只是“細節” > - 為 Web、資料庫、胖客戶端、控制台和嵌入式應用程式實施最佳的高級結構 > - 定義適當的邊界和層,並組織元件和服務 > - 了解設計和架構為何出錯,以及如何預防(或修復)這些故障 > > -- [Amazon.com](https://amzn.to/2jTxLHt) --- ![Donald Knuth 的電腦程式設計藝術](https://thepracticaldev.s3.amazonaws.com/i/26n7ggpj2vnte6s7s7b9.jpg) ## \#18。 [電腦程式設計的藝術](https://amzn.to/2XKk8Ik) ### 作者:唐納德高德納 #### 建議 13.0%(_3 路與 #20 和 #19 平手_) > 這部宏偉的傑作全面概述了各種演算法及其分析。現在,《電腦程式設計的藝術》已經是第三版了,其中包含作者的大量修訂,並包括許多新練習。 > > 儘管這本書是幾十年前構思的,但它仍然是一部永恆的經典。本書最大的優點之一是每一章都包含大量問題。作者精心挑選問題,並根據難度進行索引。解決大量此類問題將幫助您深入了解圍繞給定主題的問題。此外,練習還包含各種經典問題。 > > -- [Amazon.com](https://amzn.to/2XKk8Ik) --- ![程式碼:Charles Petzold 的電腦硬體和軟體的隱藏語言](https://thepracticaldev.s3.amazonaws.com/i/36uenl4hsq1v4n9o4olc.jpg) ## \#17。 [程式碼:電腦硬體與軟體的隱藏語言](https://amzn.to/2XYXZKA) ### 查爾斯·佩措爾德 #### 15.9% 推薦(_與 #16_ 並列) > 手電筒、英國入侵、黑貓和蹺蹺板與電腦有什麼關係?在《程式碼》中,他們向我們展示了操縱語言和發明新的相互交流方式的巧妙方式。透過 _CODE_,我們看到這種獨創性和我們人類的溝通衝動是如何推動過去兩個世紀的技術創新的。 > > 作者 Charles Petzold 使用日常物品和熟悉的語言系統(例如點字和莫爾斯電碼),為任何想了解電腦和其他智慧機器的秘密內部生活的人編織了一個富有啟發性的敘述。 > > 這是一個插圖巧妙且非常易於理解的故事,在整個過程中,您會發現自己獲得了理解當今 PC、數位媒體和網路世界的真實背景。無論您的技術水平如何,CODE 都會讓您著迷,甚至可能喚醒您內心的技術愛好者。 > > -- [Amazon.com](https://amzn.to/2XYXZKA) --- ![敏捷軟體開發:原則、模式與實踐,作者:Robert C.「Bob 叔叔」Martin](https://thepracticaldev.s3.amazonaws.com/i/qvta7nticfmwig5x68f7.jpg) ## \#16。 [敏捷軟體開發:原則、模式與實踐](https://amzn.to/2XT4fj3) ### 作者:羅伯特·C·「鮑伯叔叔」·馬丁 #### 15.9% 推薦(_與 #17_ 並列) > 本書由軟體開發人員為軟體開發人員撰寫,是最新軟體開發方法的獨特集合。作者包括 OOD、UML、設計模式、敏捷和 XP 方法,並詳細描述了 C++ 和 Java 中可重複使用程式的完整軟體設計。它使用實用的解決問題的方法,展示瞭如何開發物件導向的應用程式——從分析的早期階段,到底層設計,再到實現。引導讀者了解設計師的想法—展示整個軟體設計過程中出現的錯誤、死胡同和創意見解。本書涵蓋:靜力學和動力學;類設計原則;複雜性管理;包裝設計原理;分析與設計;模式和範式交叉。一一解釋 OOD 的原理,然後透過大量範例、完整的設計和案例研究來示範它們。涵蓋 C++ 和 OOD 應用程式中的陷阱、缺陷和解決方法,然後展示如何使用敏捷方法。詳細討論了大型軟體的設計和開發方法。對建築安全系統進行了三章深入的單一案例研究。適合想要了解如何使用最先進的方法設計物件導向軟體的軟體工程師、程式設計師和分析師。 > > -- [Amazon.com](https://amzn.to/2XT4fj3) --- ![Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest 和 Clifford Stein 的演算法簡介](https://thepracticaldev.s3.amazonaws.com/i/3avr69imz4gk8t8osbqc.jpg) ## \#15。 [演算法介紹](https://amzn.to/2XRR81s) ### 作者:Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest 與 Clifford Stein #### 建議 17.4%(_3 路與 #14 和 #13 平手_) > 有些演算法書籍嚴謹但不完整;其他的涵蓋大量材料但缺乏嚴謹性。 《演算法導論》獨特地結合了嚴謹性和全面性。本書深入涵蓋了廣泛的演算法,同時使各個層級的讀者都可以理解它們的設計和分析。每一章都相對獨立,可以作為學習單元。這些演算法以英語和偽程式碼進行描述,任何稍微編程過的人都可以閱讀。這些解釋保持基本,但沒有犧牲覆蓋深度或數學嚴謹性。 > > 第一版成為全球大學廣泛使用的教材以及專業人士的標準參考書。第二版新增了關於演算法的作用、機率分析和隨機演算法以及線性規劃的章節。第三版進行了全面修訂和更新。它包括關於 van Emde Boas 樹和多線程演算法的兩個全新章節,對遞歸章節(現在稱為“分而治之”)的大量補充,以及關於矩陣的附錄。它改進了動態規劃和貪婪演算法的處理,以及流網路材料中基於邊緣的流的新概念。此版本加入了許多練習和問題 > > -- [Amazon.com](https://amzn.to/2XRR81s) --- ![Head First 設計模式:Eric Freeman、Elizabeth Robson、Kathy Sierra 和 Bert Bales 編寫的大腦友善指南](https://thepracticaldev.s3.amazonaws.com/i/2k33el50lr3gnihj6zqo.jpg) ## \#14。 [Head First 設計模式:大腦友善指南](https://amzn.to/2XNEdxz) ### 作者:Eric Freeman、Elizabeth Robson、Kathy Sierra 和 Bert Bales #### 建議 17.4%(_3 路與 #15 和 #13 平手_) > 在任何特定時刻,都會有人遇到與您相同的軟體設計問題。而且,很可能其他人已經解決了您的問題。這一版的《Head First Design Patterns》(現已針對 Java 8 進行了更新)向您展示了開發人員用來建立實用、優雅、可重用且靈活的軟體的可靠、經過實際檢驗的模式。當你讀完本書時,你將能夠利用那些與軟體設計的野獸戰鬥並取得勝利的人的最佳設計實踐和經驗。 > > -- [Amazon.com](https://amzn.to/2XNEdxz) --- ![破解編碼面試:189 個程式設計問題和解決方案,作者:Gayle Laakmann McDowell](https://thepracticaldev.s3.amazonaws.com/i/glfijew89yb3sxnxiznu.jpg) ## \#13。 [破解程式設計面試:189題程式設計題及解答](https://amzn.to/2XPSwlg) ### 作者:蓋爾‧拉克曼‧麥克道威爾 #### 建議 17.4%(_3 路與 #15 和 #14 並列_) > - 189 道程式設計面試問題,從基礎知識到最棘手的演算法問題。 > - 如何匯出每個解決方案的演練,以便您可以學習如何自己實現。 > - 有關如何解決 189 個問題的提示,就像您在真實面試中得到的一樣。 > - 五種經過驗證的解決演算法問題的策略,讓你可以解決你沒見過的問題。 > - 廣泛涵蓋基本主題,例如大 O 時間、資料結構和核心演算法。 > - 深入了解 Google 和 Facebook 等頂尖公司如何聘用開發人員。 > - 準備和應對面試軟性方面的技巧:行為問題。 > - 對於面試官和公司:關於什麼是好的面試問題和招募流程的詳細資訊。 > > -- [Amazon.com](https://amzn.to/2XPSwlg) --- ![別讓我思考:Web 可用性的常識方法,作者:Steve Krug](https://thepracticaldev.s3.amazonaws.com/i/8d63yx8mnivrer5d08v6.jpg) ## \#12. [不要讓我思考:網路可用性的常識性方法](https://amzn.to/2XPjDwF) ### 史蒂夫·克魯格 #### 18.8% 推薦(_與#11_並列) > _Don't Make Me Think_ 是 Steve Krug 寫的一本關於人機互動和網路可用性的書。本書的前提是,一個好的軟體程式或網站應該讓使用者盡可能輕鬆、直接地完成他們的預期任務。克魯格指出,人們善於滿足問題,或採用第一個可用的解決方案來解決問題,因此設計應該利用這一點。他經常引用 Amazon.com 作為精心設計的網站的例子,該網站能夠實現高品質的交互,儘管該網站每天都變得越來越大、越來越複雜。 > > 這本書本身旨在成為簡潔(簡潔)和重點突出的寫作範例。根據該書的介紹,其目標是製作一篇可供高管在兩個小時的飛機飛行中閱讀的文本。 > > -- [維基百科](http://bit.ly/2XSAhLY) --- ![The Clean Coder: A Code of Conduct for Professional Programmers by Robert C. “Uncle Bob” Martin](https://thepracticaldev.s3.amazonaws.com/i/8etf99rgjqkmvl0n12b8.jpg) ## \#11。 [The Clean Coder:專業程式設計師行為準則](https://amzn.to/2XMluCs) ### 作者:羅伯特·C·「鮑伯叔叔」·馬丁 #### 18.8% 推薦(_與 #12_ 並列) > 在不斷的不確定性和不間斷的壓力中忍受並取得成功的程式設計師有一個共同的屬性:他們非常關心建立軟體的實踐。他們把它當作一門手藝。他們是專業人士。 > > 在《乾淨的編碼器:專業程式設計師的行為準則》中,傳奇軟體專家 Robert C. Martin 介紹了真正的軟體工藝的學科、技術、工具和實踐。本書充滿了實用的建議——從估計和編碼到重構和測試。它涵蓋的不僅僅是技術:它是關於態度。馬丁展示瞭如何以榮譽、自尊和自豪的態度進行軟體開發;工作良好,工作乾淨;忠實地溝通和評估;清晰而誠實地面對困難的決定;並理解深刻的知識伴隨著採取行動的責任。 > > -- [Amazon.com](https://amzn.to/2XMluCs) --- ![軟技能:John Sonmez 的軟體開發人員生活手冊](https://thepracticaldev.s3.amazonaws.com/i/3cjtbj9vse8xzxa35po2.jpg) ## \#10. [軟體技能:軟體開發人員的生活手冊](https://amzn.to/2XR9u2y) ### 約翰‧桑梅茲 #### 23.2% 推薦(_與#11_並列) > _軟技能:軟體開發人員生活手冊_ 是作為技術專業人員全面、令人滿意的生活的指南。在其中,開發人員兼生活教練 John Sonmez 就重要的「軟」主題向開發人員提供建議,例如職業和生產力、個人理財和投資,甚至健身和人際關係。這本有趣的書由 71 個短章組成,邀請您隨心所欲地閱讀。每章末尾的「採取行動」部分向您展示如何快速獲得結果。軟技能將幫助您成為更好的程式設計師、更有價值的員工以及更快樂、更健康的人。 > > -- [Amazon.com](https://amzn.to/2XR9u2y) --- ![Peopleware:富有成效的專案和團隊,作者:Tom DeMarco 和 Timothy Lister](https://thepracticaldev.s3.amazonaws.com/i/pplphoinwajolqw6pdf9.jpg) ## \#9。 [Peopleware:高效率的專案與團隊](https://amzn.to/2XR6keY) ### 湯姆·德馬科和提摩西·利斯特 #### 23.2% 推薦(_與 #12_ 並列) > _Peopleware_ 是一本有關軟體組織管理的熱門書籍。書的第一章聲稱,「我們工作的主要問題本質上與其說是技術問題,不如說是社會學問題」。這本書探討了社會學或「政治」議題,例如團隊化學反應和團隊凝聚力、工作環境中的「流動時間」和安靜以及高流動成本。其他主題包括個人工作觀點與企業意識形態之間的衝突、企業熵、「團隊滅絕」和工作空間理論。 > > 作者將大多數主題呈現為由一些具體故事或其他資訊支持的原則。例如,「義大利麵晚餐」一章介紹了一個虛構的例子,一位經理邀請一個新團隊來吃晚飯,然後讓他們作為一個團隊購買和準備飯菜,以便讓一線團隊取得成功。其他章節使用現實生活中的故事或引用各種研究來說明所提出的原則 > > -- [維基百科](http://bit.ly/2XMFrJf) --- ![Jon Bentley 的程式設計珍珠](https://thepracticaldev.s3.amazonaws.com/i/fa7x5erzt1qryzis8784.jpg) ## \#8。 [程式珍珠](https://amzn.to/2XNxWlf) ### 喬恩‧本特利 #### 26.1% 推薦 > 電腦程式設計有很多面貌。弗雷德布魯克斯 (Fred Brooks) 在《人月神話》中描繪了一幅宏偉的圖畫。他的文章強調了管理在大型軟體專案中的關鍵作用。 Steve McConnell 在 Code Complete 中更詳細地教授了良好的程式設計風格。這些書中的主題是優秀軟體的關鍵,也是專業程式設計師的標誌。然而不幸的是,這些合理的工程原理的熟練應用並不總是令人興奮——直到軟體按時完成並且不出意外地工作。 > > 本書中的專欄介紹了該行業更迷人的方面:編程珍珠,其起源超出了紮實的工程,而是在洞察力和創造力的領域。正如天然珍珠是從激怒牡蠣的沙粒中生長出來的一樣,這些編程珍珠也是從激怒真正程式設計師的實際問題中生長出來的。這些程式很有趣,並且教授重要的程式技術和基本設計原理。 > > -- [Amazon.com](https://amzn.to/2XNxWlf) --- ![有效處理 Michael Feathers 的遺留程式碼](https://thepracticaldev.s3.amazonaws.com/i/4bls25qdhatgaz2vvmz5.jpg) ## \#7。 [有效處理遺留程式碼](https://amzn.to/2Y5hNvR) ### 麥可費瑟斯 #### 27.5% 推薦(_與#6_並列) > 你的程式碼容易修改嗎?當你改變它時,你能得到幾乎即時的回饋嗎?你到底懂不懂呢?如果這些問題中任何一個的答案是否定的,那麼您就有遺留程式碼,並且它會消耗您的開發工作的時間和金錢。 > > 在本書中,Michael Feathers 提供了從頭到尾的策略,以便更有效地處理大型、未經測試的遺留程式碼庫。本書借鑒了邁克爾為其著名的物件導師研討會建立的材料:邁克爾在指導中使用的技術,幫助數百名開發人員、技術經理和測試人員控制他們的遺留系統。涵蓋的主題包括: > > - 了解軟體變更的機制:新增功能、修復錯誤、改進設計、優化效能 > - 將遺留程式碼放入測試工具中 > - 編寫測試來防止引入新問題 > - 可用於任何語言或平台的技術 - 包含 Java、C++、C 和 C# 範例 > - 準確地辨識需要更改程式碼的位置 > - 處理非物件導向的遺留系統 > - 處理看起來沒有任何結構的應用程式 > > -- [Amazon.com](https://amzn.to/2Y5hNvR) --- ![人月神話:Frederick P. Brooks 的軟體工程論文](https://thepracticaldev.s3.amazonaws.com/i/wd3l2w6s5mzbu1gwf7b8.jpg) ## \#6。 [人月神話:軟體工程論文](https://amzn.to/2XMoXAY) ### 作者:弗雷德里克·P·布魯克斯 #### 27.5% 推薦(_與 #7_ 並列) > 很少有關於軟體專案管理的書籍能像《人月神話》一樣具有影響力和永恆性。 Fred Brooks 融合了軟體工程事實和發人深省的觀點,為任何管理複雜專案的人提供了見解。這些文章借鑒了他作為 IBM System/360 電腦系列以及其大型軟體系統 OS/360 專案經理的經驗。現在,在他的書首次出版 20 年後,布魯克斯重新審視了他最初的想法,並加入了新的想法和建議,無論是對於已經熟悉他的作品的讀者還是第一次發現它的讀者。 > > -- [Amazon.com](https://amzn.to/2XMoXAY) #### 在 Dev.To 上閱讀[我對《人月神話》的評論](https://dev.to/awwsmm/book-review-the-mythical-man-month-1995-1hpn) --- ![重構:改進現有程式碼的設計,作者:Martin Fowler](https://thepracticaldev.s3.amazonaws.com/i/3iai8x9pod62ge1f38su.jpg) ## \#5。 [重構:改進現有程式碼的設計](https://amzn.to/2XQ2KlF) ### 馬丁·福勒 #### 33.3% 推薦(_與#4_並列) > 二十多年來,全世界經驗豐富的程式設計師一直依靠 Martin Fowler 的_重構_來改進現有程式碼的設計並增強軟體的可維護性,並使現有程式碼更易於理解。 > > 這個備受期待的新版本已經全面更新,以反映程式設計領域的重大變化。 _Refactoring_,第二版,提供更新的重構目錄,包括 JavaScript 程式碼範例,以及演示無需類別的重構的新功能範例。 > > 與原版一樣,此版本解釋了什麼是重構;為什麼你應該重構;如何辨識需要重構的程式碼;以及如何真正成功地做到這一點,無論您使用什麼語言。 > > - 了解重構的流程和一般原則 > - 快速應用有用的重構,使程式更易於理解和更改 > - 辨識程式碼中預示重構機會的“難聞氣味” > - 探索重構,每個重構都有解釋、動機、機制和簡單的範例 > - 為您的重建置立可靠的測試 > - 認識重構的權衡與障礙 > > -- [Amazon.com](https://amzn.to/2XQ2KlF) --- ![設計模式:可重複使用物件導向軟體的元素,作者:Erich Gamma、Richard Helm 和 Ralph Johnson](https://thepracticaldev.s3.amazonaws.com/i/8orec0j061cf2ypavhqt.jpg) ## \#4。 [設計模式:可重複使用物件導向軟體的要素](https://amzn.to/2jY1a37) ### 作者:Erich Gamma、Richard Helm 與 Ralph Johnson #### 33.3% 推薦(_與 #5_ 並列) > 本書不是物件導向技術或設計的介紹。許多書已經在這方面做得很好......這也不是一篇高級論文。這是一本關於設計模式的書,描述了物件導向軟體設計中特定問題的簡單而優雅的解決方案...一旦您理解了設計模式並有一個「啊哈!」的感覺。 (不僅僅是與它們的「嗯?」體驗,您將永遠不會以相同的方式思考物件導向的設計。您將擁有可以使您自己的設計更加靈活、模組化、可重用和易於理解的見解- -這就是您首先對物件導向技術感興趣的原因,對吧? > > -- [Amazon.com](https://amzn.to/2jY1a37) --- ![程式碼完整:軟體建立實用手冊,作者:Steve McConnell](https://thepracticaldev.s3.amazonaws.com/i/sf7gm1y7ld56iytxpzbb.jpg) ## \#3。 [程式碼大全:軟體建置實用手冊](https://amzn.to/2jY2PWp) ### 史蒂夫麥康奈爾 #### 44.9% 推薦 > Steve McConnell 的原始《Code Complete》被廣泛認為是最好的實用程式指南之一,十多年來一直在幫助開發人員編寫更好的軟體。現在,這本經典書籍已通過前沿實踐和數百個新程式碼示例進行了全面更新和修訂,闡釋了軟體建置的藝術和科學。麥康奈爾從研究、學術界和日常商業實踐中獲得了豐富的知識體系,將最有效的技術和必須了解的原則綜合成清晰、務實的指導。無論您的經驗水平、開發環境或專案規模如何,本書都會啟發並激發您的思考,並幫助您建立最高品質的程式碼。 > > - 發現永恆的技術和策略,幫助您: > - 最小複雜度、最大創造力的設計 > - 獲得協作開發的好處 > - 應用防禦性程式設計技術來減少和清除錯誤 > - 利用機會重構或改進程式碼,並安全地進行 > - 使用適合您專案的施工實踐 > - 快速有效地除錯問題 > - 及早正確解決關鍵施工問題 > - 將品質貫穿專案的開始、中期和結束階段 > > -- [Amazon.com](https://amzn.to/2jY2PWp) --- ![《實用程式設計師:從熟練工到大師》,作者:Andrew Hunt 和 Dave Thomas](https://thepracticaldev.s3.amazonaws.com/i/9ckxzwb9a5vc6lpl3fhq.jpg) ## \#2。 [務實的程式設計師:從新手到大師](https://amzn.to/2jY48Vh) ### 安德魯·亨特和戴夫·托馬斯 #### 47.8% 推薦 > 程式設計師是經過訓練的工匠,可以使用一組特定的工具(編輯器、物件管理器、版本追蹤器)來產生將在某些環境(硬體元件上的作業系統)中執行的特定類型的產品(程式).與其他工藝一樣,電腦程式設計催生了一系列智慧,其中大部分不是在大學或認證課程中教授的。隨著時間的推移,大多數程式設計師透過獨立實驗掌握了所謂的技巧。在《務實的程式設計師》中,安德魯·亨特和大衛·托馬斯將他們在各自作為軟體設計師和程式碼編寫者的職業生涯中發現的許多真理編入了法律。 > > 作者的一些實用主義要點是具體的,其實施路徑也很明確。例如,他們建議讀者學習一種文字編輯器,並將其用於所有用途。他們還建議即使是最小的專案也使用版本追蹤軟體,並宣傳學習正規表示式語法和文字操作語言的優點。其他(也許更有價值)的建議則更加輕鬆。在除錯部分,有人指出,“如果您看到蹄印,請想到馬,而不是斑馬。”也就是說,懷疑一切,但開始在最明顯的地方尋找問題。有一些關於估算時間和費用以及將測試整合到開發過程中的建議。你需要一本《務實的程式設計師》有兩個原因:它比你費心去表達的更清晰地展示了你自己累積的智慧,它向你介紹了你可能還沒有考慮過的工作方法。正在工作的程式設計師會喜歡這本書。 > > -- [大衛沃爾來自 Amazon.com](https://amzn.to/2jY48Vh) --- ## 最後,最受軟體開發人員推薦的一本書: --- ![《乾淨的程式碼:敏捷軟體工藝手冊》,作者:Robert C.「Bob 叔叔」Martin](https://thepracticaldev.s3.amazonaws.com/i/jlpbbbl4ity80ottuins.jpg) ## \#1。 [整潔程式碼:敏捷軟體流程手冊](https://amzn.to/2k1ogG7) ### 作者:羅伯特·C·「鮑伯叔叔」·馬丁 #### 52.2% 推薦 > 即使是糟糕的程式碼也能運作。但如果程式碼不乾淨,它可能會讓開發組織陷入困境。每年,都會因為程式碼編寫不當而浪費無數的時間和大量資源。但事實並非一定如此。 > > 著名軟體專家 Robert C. Martin 在《乾淨程式碼:敏捷軟體工藝手冊》中提出了革命性範例。 Martin 與Object Mentor 的同事合作,將他們「即時」清理程式碼的最佳敏捷實踐提煉成一本書,這本書將向您灌輸軟體工匠的價值觀,並使您成為更好的程式設計師——但前提是您工作在它。 > > 您將從事什麼類型的工作?你將閱讀程式碼——大量的程式碼。你將面臨著思考該程式碼哪些是正確的、哪些是錯誤的挑戰。更重要的是,您將面臨重新評估您的專業價值觀和對您的技能的承諾的挑戰。 > > _Clean Code_ 分為三個部分。第一部分描述了編寫簡潔程式碼的原則、模式和實踐。第二部分由幾個日益複雜的案例研究組成。每個案例研究都是一次清理程式碼的練習,即將存在一些問題的程式碼庫轉變為健全且高效的程式碼庫。第三部分是回報:一章包含一系列啟發式方法和建立案例研究時收集的「氣味」。結果是一個知識庫,描述了我們編寫、閱讀和清理程式碼時的思維方式。 > > 讀者將從本書中解脫出來 > - 如何區分好程式碼和壞程式碼 > - 如何寫好程式碼以及如何將壞程式碼轉換為好程式碼 > - 如何建立好名字、好函數、好物件、好類 > - 如何格式化程式碼以獲得最大的可讀性 > - 如何在不模糊程式碼邏輯的情況下實現完整的錯誤處理 > - 如何進行單元測試並實踐測試驅動開發 > - 對於任何有興趣產生更好程式碼的開發人員、軟體工程師、專案經理、團隊領導或系統分析師來說,這本書都是必讀的。 > > -- [Amazon.com](https://amzn.to/2k1ogG7) --- 上述「建議百分比」是包含該書的所有調查清單的比例。因此,即使一本書只有“12.5% 的推薦度”,也意味著平均每 8 個開發人員中就有 1 個已經閱讀過該書並推薦給其他開發人員。上述所有書籍都通過了八分之一的門檻。 更令人驚訝的是前 10 名的書籍。平均每 4 個開發人員中有 __1 人推薦 10 到 6 本書。每 3 人中就有 1 人推薦書籍#5 和#4。排名前三的書籍《__Code Complete__》、《The Pragmatic Programmer__》和《__Clean Code__》受到大約__其他軟體開發人員__的推薦。這對現代社會最關鍵的行業之一產生了巨大影響。如果您想加強您的軟體開發知識,但您尚未閱讀這三本書,那麼您的同事很可能會建議您這樣做。 --- --- 如果您喜歡上面的文章,也許您想關注我在 [Dev.To](https://dev.to/awwsmm) 上的工作?或在 [The Tweeter](https://twitter.com/_awwsmm) 上閱讀我的愚蠢推文?或[請我喝杯咖啡](https://ko-fi.com/awwsmm)? (我有令人衰弱的咖啡因成癮。) 不管怎樣,感謝您的光臨! --- 原文出處:https://dev.to/awwsmm/20-most-recommended-books-for-software-developers-5578

我使用了幾款文字編輯器的心得:sublime、vim、emacs、vscode

我將談論我使用每個文字編輯器的經驗,也許這對於評估文字編輯器的人花時間學習可能有用。 ## Sublime Text 我在高中時開始學習編程,編寫一些程式碼並在瀏覽器上查看結果非常有趣。我使用 Sublime Text 是因為我正在透過部落格文章和影片進行學習,而且大部分內容都提到了 Sublime Text。而且,它速度很快,而且我安裝了一些外掛程式來處理 php、html、javascript 和 css。我在工作中也使用了它幾年,直到有一天我加入了一家擁有 vim 和 emacs 用戶的公司。 ## vim vim 使用者從事的專案與我自己的專案更接近,所以我開始檢查他們是如何做事的,然後我開始學習 vim。這並不酷,學習如何使用它太難了,要加載新的配置文件我每次都必須重新啟動 vim 以及許多其他問題,但既然他們這樣做了,我說服自己我也可以學習它,所以我做過。 我使用 vim 幾個月了,我最喜歡 vim 的是它針對編輯檔案而不是建立新檔案進行了最佳化。大多數時候,我們都在編輯檔案並在程式碼行之間移動,這樣才有意義。最後,我對 vim 的使用感到高興並且富有成效。 ## neovim 有一天,我聽說了 neovim,但不確定為什麼我轉而使用它,但請查看這兩個專案的 github 專案: ![](https://thepracticaldev.s3.amazonaws.com/i/mr475vfxouxinfcgxeaa.png) ![](https://thepracticaldev.s3.amazonaws.com/i/oogdvczt4j9mt5v49jxu.png) 等等什麼? vim 儲存庫上只有一位貢獻者?怎麼只有一個人就能做到這一點?檢查拉取請求列表,我發現作者應用了其他人的更改,因為這是他的更改。好吧,我不喜歡這樣,所以我改用 neovim,當人們做出貢獻時,它會給他們帶來榮譽。 更新:我同意我的調查太淺薄。我看到[此評論](https://dev.to/heast/comment/4gk4)。但我還是不喜歡這樣。 ## nvim + tmux 當時人們正在談論“tmux”,它是一個終端多路復用器,因此您可以拆分終端並擁有選項卡並自定義所有內容,從快捷方式到tmux 的外觀,例如向狀態欄加入有用的訊息。我嘗試過並且喜歡。由於我在終端中使用 nvim,它執行得非常好,我甚至找到了一些插件來順利整合它們。它是這樣的: ![](https://thepracticaldev.s3.amazonaws.com/i/u4ncf7ir9rfeb0lx700j.gif) 我不再使用 nvim,但你仍然可以找到我的 [vim](https://github.com/lucasprag/vimlociraptor) 和 [tmux](https://github.com/lucasprag/dotfiles/blob) 設定/ master/tmux.conf)。 我使用這個堆疊三年了,我很高興。 然後我看到自己管理 nvim、tmux、zsh 的配置和插件,以便在工作中的 Debian 上的 terminator 和家裡的 macOS 上的 iTerm 上執行良好。插件之間也不是一切都工作得很好,例如,我在nvim 上有自動完成功能,它工作得很好,除非我使用多個遊標,這是另一個插件的功能,自動完成功能僅適用於第一個遊標,因為它們沒有彼此融為一體。我還遇到了類似的其他令人沮喪的問題,而且我發現自己花了太多時間除錯或嘗試替代插件,所以我傾向於嘗試一些不同的東西,這就是 emacs 引起我注意的地方。 ## emacs Emacs 有一個 GUI 應用程式,它讓我不再需要 terminator 或 iTerm,它有自己的 shell,用 elist 編寫,稱為 eshell,所以我對所有事情都有一個配置和插件。我嘗試像使用 vim 一樣從頭開始寫下每個配置,但要學的東西太多了,而且我必須完成一些工作,所以我嘗試了 spacemacs,在一些幫助下我很快就能提高工作效率。 Spacemacs 有 vim 鍵綁定,所以我在家裡,我只需要學習處理 spacemacs 的不同方面,例如佈局和工作區。做事情更容易,因為它會即時顯示可用的鍵綁定,所以當您鍵入時,您可以看到您的選項,它也是助記符,所以如果您想要佈局,您可以使用“SPC + l” ,如果需要的話要切換某些內容,請使用“SPC + t”,如果需要緩衝區,請使用“SPC + b”,對於專案,請使用“SPC + p”,對於文件,請使用“SPC + f”,並儲存您需要的檔案組合“SPC + fs”(意指“spacemacs -> 檔案 -> save”)和“SPC + pt”等指令來檢視檔案的專案樹。非常簡單吧? 我花了大約一個月的時間才理解一切並順利工作。我對一切都不滿意,我遇到了一些錯誤,這沒關係,我報告了並嘗試修復它們,但我必須再學習一種語言(elisp)才能做到這一點。這是一次很棒的經歷,因為我學習了很多 elisp,在我看來這是一門很棒的語言,所以我玩得很開心,這讓我使用了 spacemacs 6 個月。 然後我看到了這個影片: https://www.youtube.com/watch?v=8kCd4w4kc68 等等什麼?一週的 VSCode 就毀了對 Emacs 10 年的熱愛?我有一些朋友也對 vscode 很滿意,他們強烈推薦它。好吧,讓我們試試看。 ## vscode 我必須在周末做一些編碼,所以我切換到 vscode,總的來說,體驗很棒,但一開始我不得不經常使用滑鼠。 我安裝了vim 鍵綁定,令我驚訝的是,它還支援常見的vim 插件,例如「vim-easymotion」、「vim-surround」、「vim-commentary」以及其他我從未聽說過的插件。 我在 vscode 中發現的殺手級功能: - `cmd + p` 使用模糊搜尋開啟檔案更快、更聰明(它將最近的檔案放在頂部) - 快捷方式與瀏覽器快捷方式更相似,這讓我作為網頁開發人員的生活更輕鬆 - 設定檔是「JSON」文件,不需要太多自訂(我的設定檔有 22 行,僅此而已) - 整合的多終端運作得非常好,並且像 tmux 一樣有分割功能 - vscode 由 Microsoft 維護,我認為有一個團隊致力於它並加入彼此集成良好的功能真是太好了 - 我不需要除錯 vscode 並且到目前為止我沒有發現任何錯誤 - 我不需要安裝太多插件 - 跳到 React 的定義 我安裝的VScode外掛: - [Vim 鍵綁定](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) - [專案管理器](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager) - 使用「ALT + CMD + p」更輕鬆地在專案之間切換 - [書籤](https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks) - `ALT + CMD + k` 加書籤,`ALT + CMD + l` 跳到下一個書籤 - [檔案實用程式](https://marketplace.visualstudio.com/items?itemName=sleistner.vscode-fileutils) - 無需使用滑鼠即可輕鬆複製或重新命名文件 - [對 Ruby 的支持](https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby) - [對 Ruby Haml 的支持](https://marketplace.visualstudio.com/items?itemName=vayan.haml) - [Ruby 自動補全](https://marketplace.visualstudio.com/items?itemName=castwide.solargraph) - [Ruby 的 Linting](https://marketplace.visualstudio.com/items?itemName=misogi.ruby-rubocop) - [Python 支援](https://marketplace.visualstudio.com/items?itemName=ms-python.python) - [Elixir 支援](https://marketplace.visualstudio.com/items?itemName=mjmcloug.vscode-elixir) - [React 支援](https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets) - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - [One Dark Pro Monokai Darker 主題](https://marketplace.visualstudio.com/items?itemName=eserozvataf.one-dark-pro-monokai-darker) - 我最喜歡的配色方案 ![](https://thepracticaldev.s3.amazonaws.com/i/thtlo6h65n8hmfksan23.gif) 這是我使用文字編輯器的經驗。今天,我不必除錯我的編輯器來使簡單的事情發生,而且我仍然可以根據我的需要對其進行自訂。是的,我對 vscode 非常滿意,也許你也應該嘗試一下。我希望它對某人有用。 我也期待聽到您對這些文字編輯器的意見和經驗。謝謝。 --- 原文出處:https://dev.to/lucasprag/my-editor-journey-sublime-vim-emacs-vscode-19k0

在 Ubuntu 18.04 LTS 上安裝 Z-shell (Oh My Zsh)

![Ubuntu 的 Z-shell](https://thepracticaldev.s3.amazonaws.com/i/qmdocrps1ngl6v1ox29n.png) - 更新軟體包 ``` sudo apt-get update sudo apt upgrade ``` - 安裝必備包(ZSH、powerline 和 powerline 字型) ``` sudo apt install zsh sudo apt-get install powerline fonts-powerline ``` - 克隆 Oh My Zsh Respo ``` git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh ``` - 建立一個新的ZSH設定檔 ``` cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc ``` - 為您的終端設定一個精美的主題 - 使用 Nano 編輯器開啟 `.zshrc` 文件 ``` nano .zshrc ``` - 找到行“ZSH_THEME =“robbyrussell””,將“robbyrussell”替換為“.zshrc”檔案中的“agnoster”主題(CTRL + X並輸入儲存) ``` ZSH_THEME="agnoster" ``` - 更改您的預設外殼 ``` chsh -s /bin/zsh ``` - 更新和卸載 oh-my-zsh 存取 - https://github.com/robbyrussell/oh-my-zsh#manual-updates ``` cd .oh-my-zsh upgrade_oh_my_zsh ``` ### 想要語法突出顯示嗎?為 Oh My Zsh 安裝 ZSH 語法突出顯示 - 克隆 ZSH 語法加亮顯示 ``` git clone https://github.com/zsh-users/zsh-syntax-highlighting.git "$HOME/.zsh-syntax-highlighting" --depth 1 ``` - 在`.zshrc`配置中加入語法高亮 ``` echo "source $HOME/.zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> "$HOME/.zshrc" ``` #### 恢復到預設外殼 ``` chsh -s /bin/bash ``` --- 原文出處:https://dev.to/mskian/install-z-shell-oh-my-zsh-on-ubuntu-1804-lts-4cm4

如何在 git 撤銷上一個 commit

在這篇文章中,我將展示有時如何在命令列上使用 git 恢復編碼專案中的錯誤變更(提交)。 ### 我為什麼要這樣做? 在我的論文中,我正在研究一個在一個環境中開發的專案,然後在另一個由多個虛擬機器組成的環境中進行測試。所以我所做的每一個重要的改變都可能對專案的功能產生重大影響。有時候,我所做的改變可能沒有達到我預期的結果。然後我必須查看更改並分析上次提交前後專案的行為。 ### 你如何看待最後一次提交? 要測試特定提交,您需要哈希值。要取得哈希值,您可以執行“git log”,然後您將獲得以下輸出: ``` root@debian:/home/debian/test-project# git log commit <last commit hash> Author: Isabel Costa <[email protected]> Date: Sun Feb 4 21:57:40 2018 +0000 <commit message> commit <before last commit hash> Author: Isabel Costa <[email protected]> Date: Sun Feb 4 21:42:26 2018 +0000 <commit message> (...) ``` 您也可以執行“git log --oneline”來簡化輸出: ``` root@debian:/home/debian/test-project# git log --oneline <last commit hash> <commit message> cdb76bf Added another feature d425161 Added one feature (...) ``` 若要測試您認為具有最後工作版本的特定提交(例如:「<before last commit hash>」),您可以輸入以下內容: ``` git checkout <commit hash> ``` 這將使工作儲存庫與此確切提交的狀態相符。 執行此操作後,您將得到以下輸出: ``` root@debian:/home/debian/test-project# git checkout <commit hash> Note: checking out '<commit hash>'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at <commit hash>... <commit message> ``` 分析特定提交後,如果您決定保持該提交狀態,則可以撤銷上次提交。 ### 如何撤銷此提交? 如果您希望[撤銷/復原上次提交](https://git-scm.com/docs/git-revert),您可以使用從「git log」指令取得的提交雜湊執行下列操作: ``` git revert <commit hash> ``` 此命令將建立一個新的提交,並在訊息開頭包含“Revert”一詞。之後,如果您檢查儲存庫狀態,您會發現 HEAD 在先前測試的提交處已分離。 ``` root@debian:/home/debian/test-project# git status HEAD detached at 69d885e (...) ``` [您不想看到此訊息](https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit),因此要修復此問題並附回 HEAD到您的工作儲存庫,您應該簽出您正在處理的分支: ``` git checkout <current branch> ``` 在撰寫這篇文章的過程中,我發現了Atlassian 的教程 —[ 撤消提交和更改](https://www.atlassian.com/git/tutorials/undoing-changes) — ,它很好地描述了這個問題。 ### 概括 - 如果你想測試之前的提交,只需執行`git checkout <test commit hash>`;然後您可以測試專案的最後一個工作版本。 - 如果你想恢復最後一次提交,只需執行「git revert <unwanted commit hash>」;然後你可以推送這個新的提交,這會撤銷你先前的提交。 - 若要修復分離的頭,請執行「git checkout <目前分支>」。 --- 您可以在[Twitter](https://twitter.com/isabelcmdcosta)、[LinkedIn](https://www.linkedin.com/in/isabelcmdcosta)、[Github](https://github.com) 上找到我/isabelcosta)、[Medium](https://medium.com/@isabelcmdcosta) 和[我的個人網站](https://isabelcosta.github.io)。 --- 原文出處:https://dev.to/isabelcmdcosta/how-to-undo-the-last-commit--31mg

初級到資深 Web 開發人員:技能樹說明

原文出處:https://dev.to/aswin2001barath/junior-to-senior-web-developer-roadmap-breakdown-1525 您是初級開發人員,正在努力爬上公司的階梯並成為高級開發人員嗎? 您是一名感到迷茫、不知道從哪裡開始的全端開發人員嗎? 🤔 嗯,您來對地方了! 😎 這是初級開發人員成為受人尊敬的高級開發人員的逐步路線圖👨‍💻 ### 先決條件 - 基本的 HTML、CSS 和 JavaScript 知識。 - **MERN**(MongoDB、ExpressJS、ReactJS、NodeJS)或 **PERN**(PostgreSQL、ExpressJS、ReactJS、NodeJS)堆疊知識很有幫助,但不是必要的。 以下是路線圖中基本技術的細分,您可以在成為高級開發人員的過程中逐步遵循這些技術👨‍💻 ### SSH SSH 在安全遠端通訊中發揮著重要作用。透過熟悉 SSH 基礎知識、其命令、加密方法、SSH 金鑰管理以及將 SSH 應用於實際應用程式,您就可以順利成為高級開發人員。 - **到底什麼是 SSH?** - SSH 是 **S**ecure **Sh**ell 的縮寫,是一種旨在在兩台電腦之間建立安全通訊的協定。 (不用擔心這些花哨的術語——協議只是一堆規則,而 SSH 是一種特定類型的協議。) - **SSH 指令**:SSH 的主要用途之一是在遠端電腦上執行指令。這意味著您可以建立與伺服器的連接並使用 SSH 命令與其互動。 - **加密**:要真正掌握 SSH,了解加密等關鍵概念非常重要,其中涉及對稱和非對稱加密技術以及雜湊。這些概念為更深入地理解 SSH 的安全機制奠定了基礎。 - **SSH 金鑰**:SSH 的一個組成部分是使用 SSH 金鑰。這些密鑰由公鑰和私鑰組成。了解如何在伺服器上產生、管理和安全地儲存這些金鑰對於有效使用 SSH 至關重要。 - 練習並測試您的 SSH 技能: - 練習 SSH 技能的一個好方法是將本地電腦連接到 **GitHub** 等平台或 **DigitalOcean** 等雲端供應商。這種實務經驗將有助於鞏固您對 SSH 概念的理解。 - 想像這樣的場景:“您的 Web 應用程式一夜之間神秘地從伺服器上消失。您的任務是使用 SSH 將所有專案檔案恢復到伺服器上。”成功完成此任務可以展示您的 SSH 技能和解決問題的能力。基本上,如果你能做到這一點,那你就太棒了! ### 表現: 效能優化是您成為高級開發人員的關鍵技能。以下技術將幫助您確保應用程式平穩且有效率地執行。透過掌握它們,您將成為性能大師。 **I) 網路優化:** - **最小化檔案**:最小化檔案至關重要,因為較小的檔案會導致更快的載入時間。這不僅可以增強使用者體驗,還可以降低專案的頻寬成本。在網路速度不同的行動裝置造訪網站的時代,這一點尤其重要。 - 1. **檔案壓縮**:較小的檔案意味著使用者的下載速度更快。了解如何使用 GZIP 等檔案壓縮技術來最小化檔案大小,以減少 HTML、CSS 和 JavaScript 等基於文字的檔案的大小。 - 2. **影像最佳化**:透過調整大小、壓縮和選擇正確的影像格式來優化影像可以顯著減小檔案大小。 ImageMagick 等工具或 TinyPNG 等線上服務可以幫助您完成此過程。 - **改善應用程式的交付**:改進的交付可以加快頁面載入時間,這可以直接影響用戶的參與度和保留率。這對於全球可存取性和確保全球用戶獲得一致的體驗也至關重要。 - 1. **內容交付網絡(CDN)**:CDN 是一種分散式伺服器網絡,策略性地位於全球範圍內,用於從地理位置更靠近用戶的伺服器交付Web 內容,例如圖像、腳本和影片,從而更快的加載時間並減少延遲。作為初級開發人員,了解如何利用 CDN 來增強交付。 - 2. **HTTP/2 協定**:HTTP/2 是萬維網使用的 HTTP 網路協定的主要修訂版。它透過同時發送多個檔案並透過多路復用、壓縮和標頭優化等功能實現更快的載入時間來增強網站效能。實作 HTTP/2 協定可以顯著改善交付。 - 練習並測試您的網路優化技能: - 效能測試:初級開發人員可以透過使用 Google 的 PageSpeed Insights、GTmetrix 或 WebPageTest 等工具進行效能測試來進行練習。這些工具評估網站的效能並提供改進建議。 - 真實世界專案:初級開發人員可以透過參與真實世界專案進行練習。從頭開始建立和優化網站或 Web 應用程式可以提供實施網路優化的實務經驗。 **II) 前端優化:** - **關鍵渲染路徑以及如何改進它:** - 了解和優化關鍵渲染路徑對於使您的網站快速加載至關重要。它涉及優化從用戶請求網頁到視覺上完整的事件順序。關鍵面向包括最大限度地減少 CSS 和 JavaScript 等渲染阻塞資源、利用瀏覽器快取以及利用非同步載入技術。 - **漸進式 Web 應用程式 (PWA) 與程式碼最佳化:** - 開發漸進式 Web 應用程式涉及最佳化程式碼以獲得卓越的使用者體驗。 PWA 是一種 Web 應用程式,可提供類似本機應用程式的體驗,具有離線功能、推播通知和快速載入時間等功能。程式碼優化實踐包括高效的快取策略和最大限度地減少 JavaScript 執行,同時確保互動順暢。 - **建立離線就緒的漸進式 Web 應用程式 (PWA):** - 了解如何開發離線工作的 PWA,甚至使用 JavaScript、HTML 和 CSS 將其提交到應用程式商店。離線功能、快取和響應式設計是確保 PWA 無縫運作(無論使用者的網路連線為何)的重要組成部分。 - **程式碼分割:** - 程式碼分割是一種透過將 JavaScript 分成按需載入的較小套件來增強網站效能的策略。這種做法減少了初始載入時間並改善了整體使用者體驗,尤其是在較慢的網路連線上。 - **React 和 Redux 應用程式的智慧渲染:** - 透過智慧渲染技術提高 React 和 Redux 應用程式的速度。這涉及優化元件渲染和狀態管理,減少不必要的重新渲染,並確保您的應用程式快速響應用戶互動。 - 練習並測試您的知識: - 透過實際改善網站(例如公司登陸頁面)來提升您的技能。實施您在實際專案中學到的效能最佳化,然後測試結果。這種實務經驗對於鞏固您在前端優化方面的專業知識非常寶貴。 **III) 後端優化** 後端優化以及實踐和測試是確保您的應用程式能夠處理不斷增長的用戶群並提供高效、可靠的服務的基礎。 - **內容交付網路 (CDN):** - 內容交付網絡是分散式伺服器網絡,用於儲存網站內容的快取副本。這些伺服器策略性地分佈在全球各地,允許用戶從地理位置較近的伺服器存取資料。這可以減少延遲、加速內容交付並增強用戶體驗。 - **擴充資料庫:** - 擴展資料庫涉及擴展資料庫的容量和效能以處理增加的資料和流量。技術包括垂直擴展(向單一伺服器加入更多資源)或水平擴展(加入更多伺服器來分配負載),確保您的應用程式在成長時保持回應靈敏且可靠。 - **壓縮來自後端的回應:** - 壓縮來自後端的回應意味著減少從伺服器發送到客戶端的資料大小。 GZIP 壓縮等技術可以顯著減小響應大小,從而縮短載入時間並減少頻寬消耗。 - **快取:** - 快取涉及將經常存取的資料或內容儲存在記憶體或磁碟上,以便更快地檢索。實施快取策略可以縮短回應時間、減少伺服器負載並增強應用程式的整體效能。 - **負載平衡和負載測試:** - 實作負載平衡器對於在多個伺服器之間分配傳入網路流量至關重要。負載平衡可確保沒有任何一台伺服器不堪負荷,從而提高資源利用率並提高可靠性。 - 負載測試模擬現實條件,以辨識效能瓶頸、確保可擴充性並最佳化您的基礎架構。 - 練習並測試您的知識: - 實作負載平衡器。 - 對專案實際執行負載測試。 ### 前端框架與概念 前端開發是您成為資深開發人員的基石。熟悉這些概念將為網路開發事業的蓬勃發展鋪路。 - **React 和 Redux**:React 和 Redux 是建立動態單頁應用程式的首選函式庫。首先掌握 React 基礎知識並建立一個專案。然後,深入研究 Redux,了解狀態管理並建立應用程式以實現可擴展性。 - **Webpack4 + Parcel**:Webpack4 和 Parcel 是用於捆綁專案文件和優化生產包的最新工具。獲得使用 Webpack 設定專案的實務經驗。 - 練習並測試你的技能: - 透過使用 React 和 Redux 建立專案來測試您的知識。 - 了解使用 Webpack 設定專案的細節。 ### 測試: 測試是一個重要的主題,但也經常被初學者和初級開發人員忘記。 公司喜歡測試。因此,如果您知道如何編寫單元測試和整合測試,您將編寫更好的軟體。 - **軟體測試 101:** 了解什麼是測試、測試類型、目前 Web 開發世界中的測試環境、測試工具和函式庫的類型是什麼、如何使用它們以及如何設定一切。 - **Jest**:用於測試的頂級庫之一。學習編寫同步和非同步測試、編寫模擬並產生覆蓋率報告 - **React 測試**:然後深入為您的 React 應用程式編寫測試。學習使用快照測試和酵素來編寫智慧測試,以避免應用程式中出現錯誤。 到此結束時,您應該了解整個測試環境,並可以輕鬆地編寫您遇到的任何測試。 ### 打字稿: TypeScript 是目前 Web 開發環境中最熱門的話題之一。 - **靜態類型**:了解靜態類型的基礎知識。了解為什麼 JavaScript 沒有靜態型別而是動態型別。 - **Typescript 101**:了解什麼是 TypeScript、如何使用 TypeScript、有哪些不同類型以及如何將它們新增到您的專案中。 - **React 中的 Typescript**:最終學習如何將 TypeScript 新增到您自己的 React 專案中。 再次確保您掌握這些主題。 ### SPA + 伺服器端 - **伺服器端渲染 (SSR)**:透過伺服器端渲染深入研究 Web 渲染的起源。了解為什麼 SSR 在 Web 開發中曾經並且仍然有用。了解為什麼有些公司繼續依賴 SSR 來滿足特定需求。探索 React 中伺服器端渲染的實現,並權衡這種方法的優缺點。 - **客戶端渲染 (CSR)**:深入了解單頁應用程式 (SPA) 中的客戶端渲染。了解企業社會責任的優點和缺點。了解何時選擇客戶端渲染而不是伺服器端渲染。了解如何實作客戶端渲染並評估兩種渲染方法的優缺點。 - **Next.js**:探索 Next.js,這是一個簡化伺服器端動態應用程式所建立的函式庫。了解 Next.js 如何促進伺服器端渲染和互動式資料驅動 Web 應用程式的開發。 在本節結束時,您將準備好決定是否需要為您的專案使用單頁應用程式或伺服器端呈現的應用程式。 ### 安全: - **前端安全性最佳化**:學習跨網站腳本和 SQL 注入等註入攻擊。練習這些以了解它們是如何工作的。 - **後端安全優化**:了解有關後端安全的更多資訊以及管理敏感資料的最佳實踐。 - **道德駭客 101**:學習基本的道德駭客技術,以便我們在建立應用程式時能夠學習如何保護自己。 因此,在學習這些概念後,當您使用最新的提示和技巧以及實施最新的工具和技術來建立安全應用程式時,您必須充滿信心。 ### 碼頭工人: **Docker** 是一個容器化平台,可讓您將應用程式及其相依性打包到可移植、隔離的容器中。這些容器可以在從開發到生產的不同環境中一致運作。 Docker 是一個絕對會讓你驚嘆不已的工具。 - **容器**: - 首先深入了解容器及其對公司建立和管理應用程式的方式的深遠影響。 - 容器支援輕量級、一致且易於複製的環境,徹底改變了軟體開發和部署。 - **Docker 101**:製作容器 - 透過了解如何建立 Docker 檔案和建立自己的容器來了解 Docker 的基礎知識。 - 這些基礎知識構成了使用 Docker 輕鬆封裝和分發應用程式的基礎。 - **Docker-compose**:編排容器 - 探索 Docker-compose,一個用於編排多容器 Docker 應用程式的工具。 - 了解如何將多個容器作為單一服務進行定義、配置和管理,從而簡化複雜應用程式的部署。 - **微服務與單體架構**: - 在整體架構中,單一大型程式碼庫處理所有應用程式功能,這使得更新和擴展具有挑戰性。 - 容器支援微服務方法,其中應用程式被分為更小的、獨立的服務,可以單獨開發、部署和擴展。這種轉變提供了靈活性、可擴展性並提高了資源利用率。 - 容器(如 Docker)有助於從整體架構轉向微服務。因此,請詳細了解每種架構的優缺點。 - 練習並測試您的 Docker 技能: - 了解如何將 Redis 伺服器、Postgres 資料庫和 API 伺服器全部組合到一個 docker 容器中,以便它們都透過一個命令執行。 在本節和操作專案之後,每當我們部署應用程式時,我們都會對 Docker 感到非常滿意。 ### Redis: Redis 是最受歡迎、最常用的資料庫之一,是一種鍵值儲存。 - **資料庫 101**:深入研究資料庫主題,深入了解各種類型的資料庫以及它們如何適應資料儲存解決方案的前景。 - **什麼是 Redis?:** - Redis 是一個開源的記憶體鍵值儲存資料庫。 - 它在資料儲存和檢索方面表現出色,使其成為需要高速資料存取的應用程式的多功能選擇。 - **Redis 101**:學習如何使用 Redis。了解如何使用 Redis 進行快取以使我們的網站更快並進行會話管理。 - **Redis CLI**:了解如何使用 Redis CLI。 - **練習您的 Redis 技能**:啟動我們自己的 Redis 伺服器。 - **鍵值資料庫及其作用:** - 像 Redis 這樣的鍵值資料庫提供了一種簡單而有效的資料儲存方式。 - 它們將資料儲存為鍵和對應值對,從而實現快速資料檢索。 - 這些資料庫在快速資料存取至關重要的場景中尤其有價值,例如快取、會話管理和即時應用程式。 - **何時使用 Redis 等資料庫:** - Redis 非常適合速度和資料一致性至關重要的用例。 - 考慮使用 Redis 來快取經常存取的資料、管理使用者會話、為即時應用程式提供支援以及確保對關鍵資訊的低延遲存取。 ### 會話 + JWT 使用您的 React 專案,了解如何建立網站的整個動態部分:即使用以下技術的使用者管理。 - **會話驗證**:了解如何建立新的個人資料頁面。了解如何使用基於會話的身份驗證(其中將使用 cookie)並了解如何實現它。 - **令牌身份驗證**:了解有關令牌身份驗證(例如 JWT 令牌)的更多資訊。了解每種身份驗證類型的優缺點。 - **安全性身分驗證流程**:了解如何實施可以在您選擇的任何應用程式中實施的安全性身分驗證流程。 - 練習您的 Redis 技能:學習如何使用和實施 Redis 進行會話管理 - 這樣我們就有受保護的路線 - 此外,這樣,只要我們有登入功能,我們就可以使用該系統,因為我們知道它是安全的並且遵循最佳實踐。 ### 亞馬遜網路服務(「AWS」): Amazon Web Services,通常稱為 **AWS**,是一個強大的雲端平台,它改變了公司的營運方式,提供了無與倫比的可擴展性和效率。 #### AWS 101: - **什麼是 AWS(亞馬遜網路服務)?:** - AWS 是一個雲端運算平台,提供廣泛的服務,包括運算能力、儲存、資料庫、機器學習等。 - 它提供可擴展的按需資源,使企業能夠創新和發展,而無需管理實體基礎設施的負擔。 - **基礎設施即服務 (IaaS):** - AWS 提供基礎架構即服務,讓使用者透過網際網路配置和管理虛擬化運算資源。 - 這種方法消除了對本地硬體的需求,並提供了靈活性和可擴展性。 - **平台即服務 (PaaS):** - AWS 將其服務擴展到平台即服務,使開發人員能夠建置、部署和管理應用程式,而無需擔心底層基礎設施。 - 這使開發人員能夠專注於編寫程式碼和交付價值。 - **使用 AWS 進行擴充:** - AWS 使公司能夠有效擴展,並根據需要提供對資源的存取。 - 它允許企業將其能力與需求相匹配,類似於Google、亞馬遜和微軟等科技巨頭,確保他們能夠無縫地為客戶提供服務。 - **AWS Lambda** 是一種無伺服器運算服務,使開發人員能夠執行程式碼來回應事件,而無需管理伺服器。它提供了一種經濟高效、可擴展且簡單的方式來執行雲端中的功能。 - **Serverless 101**:了解如何使用 Serverless 框架。 - 練習您的 AWS 技能:了解如何將 AWS Lambda 實施到您的 React 應用程式中。 最後,您將充滿信心地使用 AWS 並建立雲端中的功能。 ###CI/CD 當我們將所有內容聯繫在一起並建立瞭如何編寫優秀軟體和優秀應用程式的整體圖景之後;了解如何實際建立良好的流程以及如何實際將應用程式部署到生產中。 - **持續整合**:了解有關良好持續整合實踐以及如何實施這些良好實踐和良好工具的更多資訊。 - **持續交付**:了解有關良好持續交付實踐以及如何實施這些良好實踐和良好工具的更多資訊。 - **持續部署**:了解有關良好持續部署實踐以及如何實施這些良好實踐和良好工具的更多資訊。 - 練習 CI/CD 技能:了解如何在專案中實施 Circle CI (CI/CD) 工具 - 確保您的開發團隊從一開始就擁有正確的工具和正確的流程 - 成功編寫錯誤更少、程式碼更簡潔的應用程式。 ### 額外位 - **程式碼分析**:了解當您第一次開始一個有大量文件並且不是您自己編寫程式碼的專案時該怎麼做!了解真正優化的提示和技巧。 - **建立高品質應用程式的一般最佳實踐**。 ### 軟技能 - 在本部落格中,我主要關注成為高級開發人員過程中的技術方面。然而,有效溝通和情緒智商等軟技能也發揮著至關重要的作用。 - [開發人員的七大軟技能及其學習方法](https://academy.zerotomastery.io/a/aff_pp6yfnkw/external?affcode=441520_dcwk-s8s):要更深入地探索各種軟技能,請考慮請參閱資深開發人員兼程式講師Andrei Neagoie 撰寫的部落格。 ### 筆記 - 不同的公司可能對高級 Web 開發人員有不同的期望,因此請務必進行一些額外的研究來客製化您的開發路徑。 最後,在學習了上述所有主題之後,所有這些事情對您來說都會有意義。您將能夠將所有這些事情實施到您自己的專案、您自己的公司。您將了解它們中的每一個是如何連接的。 最重要的是,與其他需要數年時間學習這些技能的初級開發人員相比,借助本路線圖可以快速學習這些內容。 ### 最佳資源 - [初級到高級 Web 開發人員路線圖部落格系列](https://dev.to/aswin2001barath/series/24357):一個部落格系列,我將學習並分享上述每個主題的知識。 - [不要成為初級開發人員:從初級到高級的路線圖](https://academy.zerotomastery.io/a/aff_5s8ff6y7/external?affcode=441520_dcwk-s8s):Andrei Neagoie 的詳細路線圖部落格(a高級開發人員)提供免費資源的連結。 - **零到精通課程**:[完整的初級到高級Web 開發人員路線圖課程](https://academy.zerotomastery.io/a/aff_hpwn5xy9/external?affcode=441520_dcwk-s8s):Andrei 的綜合課程Neagoie(同一高級開發人員)涵蓋了上述所有主題。 **我是誰?** - 我是 Aswin Barath,軟體工程迷,喜歡建立 Web 應用程式,現在在我自由職業生涯的繁忙時間透過[部落格](https://medium.com/techsoftware) 分享我的知識。 - 我也是像您一樣的初級開發人員,學習如何成為高級開發人員並在過程中分享我的知識。 - 這是我所有社交活動的連結,按平台分類在一個位置:https://linktr.ee/AswinBarath **謝謝** 非常感謝您閱讀我的部落格🙂。

為什麼我們需要數學來程式設計(10 個數學概念)

原文出處:https://dev.to/codewithshahan/10-math-concepts-for-every-programmer-31n9 許多人認為,成為電腦程式設計師不需要了解任何數學。雖然這可能部分正確,但了解一些基本的數學概念可以使程式設計變得更容易,並幫助您解開數位世界的秘密。 現在,讓我們探討每個程式設計師都應該熟悉的 10 個數學概念。 ![shahan 的 10 個數學概念封面圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4e5s7z6ee8vm1z1hpujs.png) ## 1. 布林代數 布林代數是程式設計中的基本概念。它處理只能有兩個值的二元變數:true 或 false。我們使用三個運算子來處理布林值:**AND**、**OR** 和 **NOT**。 將它們想像為決策工具。例如,如果你想知道某人是否既**有錢**又**帥**才能得到**女孩**,布爾變量可以幫助你做出決定。如果這兩個條件都滿足,他就會得到一個女孩。如果沒有,他可能還有其他選擇。您可以使用if 語句、[維恩圖](https://en.wikipedia.org/wiki/Venn_diagram) 或[真值表](https://en.wikipedia.org/wiki/Truth_table) 來表示此邏輯。 ![shahan chowdhury 的布林代數圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1ju0l69sc4hlzual24c.png) ## 2. 數位系統 電腦使用以 2 為基數(二進位)的數字系統,與人類使用以 10 為基數(十進位)的系統不同。在基數2 中,數字僅使用兩個符號表示:0 和1。了解二進位有助於我們使用其他數字系統,例如十六進位(基數16) 和基數64,這在程式設計中至關重要,特別是對於編碼和表示資料。 ![由 shahan chowdhury 拍攝的二進位 base-2 與二進位 base-10 的圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/legbrmu97n7rb0sytaw6.png) ## 3. 浮點數 浮點數是計算機表示實數的方式。它們並不總是精確的,這可能會導致計算中出現微小的錯誤。這些數字使用科學記數法來有效地處理大值和小值。了解浮點數的限制對於避免程式碼中出現這些錯誤至關重要。 ``` print(1.00000000005) # A positive float print(-85.6701) # A negative float ``` ## 4. 對數函數 對數幫助我們理解一些自然現像是如何運作的。將對數視為一種測量需要切割原木多少次才能達到特定長度的方法。在程式設計中,對數函數用於二分搜尋等演算法。這些功能在從演算法到科學研究的各種應用中發揮著至關重要的作用。 ## 5.集合論 集合論處理唯一值的集合。在程式設計中,這個概念被廣泛使用,特別是在資料庫中,其中表是唯一行的集合。連接集合、尋找交集、並集和差異是這種情況下的常見操作。理解集合論對於使用資料庫和資料操作非常重要。 ![圖片由集合論的 shahan chowdhury 提供](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5724rsklcbc3qanr9wma.png) ## 6. 組合學 組合學就是對事物和組合進行計數。無論您是為新聞應用程式開發演算法還是設計全球分散式資料庫,組合數學都可以幫助您有效地計算所有可能的組合或排列。這是一項寶貴的程式設計技能。 ![圖片由組合器的 shahan chowdhury 提供](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ic3tza0tm8gih9afnpq.png) ## 7.圖論 圖論涉及由邊連接的節點(頂點)。這個概念用於對關係和連接進行建模。理解圖論對於解決網路路由等問題和優化各種場景至關重要。 ![SHAHAN CHOWDHURY 的圖論圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c2nwhgr17213l3puo8nd.png) ## 8. 複雜性理論(大 O 表示法) 複雜性理論可以幫助您分析演算法的效率。 Big O 表示法是表達演算法時間和記憶體複雜度的工具。它可以幫助您為您的程式設計任務選擇最有效的解決方案,這是面試和編寫高效程式碼的寶貴技能。 ![SHAHAN CHOWDHURY 的 BIG O 符號圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tsy1vtrbbp0z11peyo0.png) ## 9. 統計 統計對於各個程式設計領域都至關重要,尤其是在人工智慧和機器學習領域。了解平均值、中位數、眾數和標準差等基本統計概念可以讓您最擅長做出預測。它是在[數據驅動的應用程式](https://try.sanebox.com/kxz8nr6vzzwl)中進行預測和決策的基礎。 ![SHAHAN CHOWDHURY 的統計圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oh3ef03m8muoujujhrif.png) ## 10.線性代數 [線性代數](https://en.wikipedia.org/wiki/Linear_algebra) 在電腦圖形學、深度神經網路和許多其他程式設計領域中至關重要。它涉及標量、向量和矩陣來表示和操作資料。如果您想使用 3D 圖形、密碼學和機器學習,那麼線性代數就可以發揮作用。您需要掌握線性代數才能解決這些問題。 ![SHAHAN CHOWHDURY 上傳線性代數](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vgi0514spu0fkbqv1lq1.png) _**使用 Notion 最大限度地提高您的生產力**_ [Notion](https://affiliate.notion.so/ow0zcr8xfey4) 對於開發者來說是一個很棒的工具!它支援 60 多種程式語言的語法突出顯示,使編碼更輕鬆、更有效率。不僅如此,它還提供了一些方便的筆記功能。此外,它與多個平台相容,允許您公開分享您的筆記,並促進私人協作。 ## 結論 數學是程式設計世界中的強大工具,這 10 個概念只是一個開始。它們可以幫助您開發更有效率的程式碼、解決複雜的問題並揭開數位世界背後的魔力。這些數學概念將使您成為更好的程式設計師,並且您將有能力克服不斷發展的技術領域中的各種挑戰。 **相關文章:** [6個月內前端開發人員路線圖](https://dev.to/codewithshahan/must-have-frontend-development-skills-roadmap-2024-28jc) **贊助商:** [Sanebox - 專注於重要的電子郵件!](https://try.sanebox.com/kxz8nr6vzzwl) ![Sanebox 註冊圖片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k3q0jw42zodbwjiihb2a.png) _Sanebox 是一個很棒的工具,可以幫助您控制您的電子郵件。它透過將不重要的電子郵件從收件匣中分類出來來組織您的電子郵件。它透過在您的電子郵件帳戶上建立一個名為「SaneLater」的資料夾來實現此目的。所有被認為不重要的電子郵件都會自動過濾到此資料夾。_ **我的社交:** [Linkedin](https://www.linkedin.com/in/codewithshahan) | [X](https://twitter.com/shahancd) 請繼續關注更多有價值的內容,如果您覺得有幫助,您可能也會喜歡我的[YouTube 頻道](https://www.youtube.com/programmingwithshahan?sub_confirmation=1)。下次見,祝您編碼愉快! **[請我喝杯咖啡](https://www.buymeacoffee.com/codewithshahan)**

使用 API Platform 來寫出優質的 API

原文出處:https://dev.to/juststevemcd/making-apis-the-right-way-with-api-platform-565p https://www.youtube.com/watch?v=NpfnnXi1CHI 我要坦白:直到最近有一個獨特的機會與 API Platform 的建立者進行直播,我才意識到我已經錯誤地建立了 API 太久了!最重要的是,這次經驗讓我希望自己多年前就曾使用 API Platform。現在,為什麼要猶豫使用它呢?答案在於一個潛在的誤解。 ## 打破誤解:PHP 與 Symfony 關於 API Platform 最常見的誤解通常源自於您需要深入了解 Symfony 才能開始的信念。這與事實相差甚遠。事實上,API 平台基本上是基於 PHP 的。它是如何交付的?現在這就是 Symfony 的用武之地。所以方向性很重要,API 平台不是 Symfony 的擴展,而是 Symfony 促進了 API Platform 的交付。 ## API Platform 專案剖析 如果您查看 API 來源實體,您會發現該平台提供了開箱即用的完整建立、讀取、更新和刪除 (CRUD) 功能。不需要額外的段。 ## 制勝因素:易於使用 簡單性和效率最終讓我選擇了 API 平台。只需三到四個命令,您就可以啟動、執行並準備啟動您的 API。結合更多命令,您就可以獲得一些強大的端點。只要一點點努力,一切就準備好了。無需採取進一步行動。 ## 癥結點:記住指令 作為 Laravel 開發人員,我習慣於“PHP artisan this”和“PHP artisan that”,因此 API 平台的挑戰來自於記住其不同的命令格式。在 API 平台中,任務是使用 Symfony 控制台在 Docker 中執行的,類似於 Laravel 中的完成方式 - 我們呼叫不同的東西。差別在於命令的用法。 ## 你為何還不試試看 API Platform? 那麼,回到我們最初的問題──你們為什麼還不使用 API Platform?是因為你跟我一樣,曾經錯誤地認為它需要紮實的 Symfony 知識才能開始? > 如果是這樣的話,我告訴你:事實並非如此。 API Platform 是一個強大的、使用者友善的環境,使用 PHP 建立 API 變得輕而易舉。因此,讓我們嘗試更多地使用 API 平台,因為如果您在 PHP 中建立 API,那麼您沒有理由不使用 API Platform。

從開源專案複製程式碼,算是偷竊嗎?

原文出處:https://dev.to/rjwignar/are-you-stealing-from-other-projects-4f0n ### 優秀的程式設計師抄襲;更優秀的程式設計師會偷竊嗎? > 優秀的藝術家臨摹;偉大的藝術家偷竊 > \- 巴勃羅·畢卡索 巴勃羅·畢卡索經常因說出上述引言而受到讚譽。我不會提供我自己對這句話的解釋,因為有興趣的人可以在網路上找到大量的解釋。然而,我經常想知道這句話如何應用於程式設計和開源開發。 ### 我們的程式設計知識真的是我們自己的嗎? 網路上有很多資源可以教您幾乎所有與程式設計相關的知識。我自己和我的許多同學幾乎所有的程式設計知識都是從教科書、線上資源/文件和 YouTube 教學中學到的。這些資源教會了我們今天擁有並應用的程式設計知識,但是所有這些知識都被盜了嗎?如果您從數千人觀看的 YouTube 教程中學會了編寫第一個“Hello World”程序,您是否在竊取程式碼?影片上傳者也學會使用外部資源編寫「Hello World」程式的可能性有多大?上傳者的知識被偷了嗎? 我不能說這些知識是否被盜,但我相信這種知識對於我們建立和擴展我們的技能是必要的。沒有人能夠知道每一個完美的實現,或是為每個專案編寫每一行程式碼。 ### 開源軟體是為使用而生的! 開源軟體的存在不應該被忽視,開源軟體是用來使用的!如果開源專案提供了您需要的功能,那麼當其他人為您精心完成這些功能時,為什麼還要自己實現這些功能呢?只要該庫得到積極維護並滿足您的需要,您就應該使用和研究開源庫。如果您發現任何錯誤、問題或缺少的功能,請嘗試建立自己的解決方案並為該專案做出貢獻,使其對每個人都更好!同樣,如果開源程式庫提供了您需要的功能,但您無法整合該程式庫,請以開源專案為靈感,在您自己的專案中實現該功能。 ### 從其他專案中獲取靈感 在我之前的[關於程式碼閱讀的部落格文章](https://dev.to/rjwignar/code-reading-i7h)中,我閱讀了Docusaurus 的程式碼庫來研究該專案如何為受保護的程式碼區塊實現語法突出顯示。我的研究告訴我,Docusaurus 實際上使用第三方函式庫 [Prism-React-Renderer](https://github.com/FormidableLabs/prism-react-renderer) 來提供語法突出顯示。這些知識很有用,因為我想在我的 Markdown 到 HTML 轉換器 [ctil](https://github.com/rjwignar/ctil) 新增語法突出顯示,但不想從頭開始實現該功能。雖然我無法在自己的專案中使用 Prism React Renderer,但研究 Docusaurus 給了我找到一個我可以使用的開源程式庫的想法。 ### 使用highlight.js 進行語法高亮顯示 在搜尋第三方語法螢光筆時,我找到了 [highlight.js](https://highlightjs.org/)。 ctil 將文字(`.txt`)和 Markdown (`.md`)轉換為生成的 HTML(`.html`)文件,因此我希望生成的 HTML 文件支援語法突出顯示。透過使用內容分發網路(CDN),highlight.js 可以用作 HTML 標籤,因此我可以透過將以下行新增至產生的 HTML 檔案來新增highlight.js: ``` <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script> <script>hljs.highlightAll();</script> ``` 透過這些行,我能夠[加入語法突出顯示](https://github.com/rjwignar/ctil/commit/c597f05724b60731e129aead33f1c3017a99ec17): ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k74q82mbi46fbbqupbri.png) ### 與 Docusaurus 方法的比較 在我的[上一篇部落格文章](https://dev.to/rjwignar/code-reading-i7h)中,我描述了 Docusaurus 如何使用 Prism React Renderer 新增語法突出顯示。與 Docusaurus 一樣,我使用了第三方函式庫highlight.js 來加入語法突出顯示。然而,在 Docusaurus 中新增和修改了設定檔以設定 Prism React Renderer,並透過使用「<Highlight />」元件加入了語法突出顯示。 Prism React Renderer 還提供了使用者可以在其專案中配置的突出顯示主題。對於我的專案,只需將highlight.js 加入到生成的 HTML 文件中,作為要透過 CDN 傳送的 HTML 標籤。現在我對基本的語法突出顯示感到滿意,所以我不關心有一個特定的突出顯示主題。透過 CDN 使用highlight.js 的一個缺點是,如果使用者在線,語法突出顯示可能無法運作。將來我可能會將highlight.js加入到專案本身中,這樣語法突出顯示就可以離線工作。 ### 下一步。 此功能仍在開發中。在目前迭代中,html 用作 `<code>...</code>` 區塊的預設語言類別。目前這是可以接受的,但此解決方案將忽略原始 Markdown 文件中的任何語言類設定。我希望 ctil 解析 Markdown 文件中的語言標籤,以確定使用哪種語言進行突出顯示。這將是未來需要解決的問題。有興趣的人可以在[此處](https://github.com/rjwignar/ctil/issues/11)找到問題。 ### 那麼從開源專案複製程式碼算不算偷竊? 只要專案許可證允許複製,並且您遵循專案許可證的要求,您就不會竊取。同樣,我認為從開源專案中尋找靈感並不是偷竊。

2023 年開發者的 24 個開源專案🔥👍

原文出處:https://dev.to/madza/24-open-source-projects-for-developers-in-2023-391l --- 標題:2023 年開發人員的 24 個開源專案 🔥👍 發表:真實 描述: 標籤: 開源、 github、 程式設計、 Web 開發 封面圖:https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74998ffdt3doqvxtxumz.png canonical_url:https://madza.hashnode.dev/24-open-source-projects-for-developers-in-2023 --- 開源專案是創新、協作和創造力的遊樂場。它是來自世界各地的開發人員聚集在一起分享他們的想法、技能和熱情的中心。 在本文中,我精心挑選了 24 個涵蓋廣泛興趣和技術的開源專案。 從尖端的人工智慧框架到漂亮的生產力工具以及介於兩者之間的一切,每個開發人員都能找到適合自己的東西。 我提供了直接連結、描述和視覺效果,以便您可以立即獲得每個工具的初步印象。 --- ## 1\. [集算器SPL](https://github.com/SPLWare/esProc)(贊助) 集算器SPL是一種基於腳本的資料操作語言,與SQL資料庫集成,支援進階分析和高效能並行處理。 它適合處理大型資料集,與各種工具集成,提供資料視覺化,並跨多個平台工作。一些主要功能包括: **💪 強大的資料處理能力:** 集算器SPL是一種腳本語言,具有豐富的函數庫和強大的語法。 **✨ 預存程序等效項:** 它允許透過 JDBC 介面執行 SPL 腳本。 **📈 多功能視覺化:** 它提供了成熟的報告工具,具有廣泛的視覺化配置,用於建立各種類型的報告。 **⚡ 自動化工作流程:** 它支援軟體工作流程的自動化,包括用於程式碼建置、測試和部署的 CI/CD 流程。 **🔥 相比SQL更具彈性:** 與SQL語法不同,集算器SPL允許將資料處理程式碼寫在多條語句中。 ![esProc_SPL](https://cdn.hashnode.com/res/hashnode/image/upload/v1679824673641/82f843e0-72a1-44a4-bd99-68616f322534.pw?m=1600,4cro format =網頁) ⭐ 支援他們的 GitHub 倉庫:[https://github.com/SPLWare/esProc](https://github.com/SPLWare/esProc) ## 2\. [跳房子](https://github.com/hoppscotch/hoppscotch) 一種多功能開源 API 開發和測試工具,提供使用者友善的介面,用於發出 HTTP 請求來測試 API 並與 API 互動。 它簡化了製作和發送請求的過程,使其成為使用 API 的開發人員和測試人員的必備工具。 ![Hoppscotch](https://github.com/hoppscotch/hoppscotch/raw/main/packages/hoppscotch-common/public/images/banner-dark.png) ## 3\. [Supabase](https://github.com/supabase/supabase) Firebase 的開源替代方案,為開發人員提供了一組用於建立可擴展的即時應用程式的工具。 它提供了強大的後端即服務 (BaaS) 平台,具有身份驗證、資料庫管理和即時功能等功能,使其成為創建現代 Web 和行動應用程式的強大選擇。 ![Supabase](https://supabase.com/_next/image?url=%2Fimages%2Fproduct%2Fstorage%2Fheader--dark.png&w=1920&q=75) ## 4\. [超級代幣](https://github.com/supertokens/supertokens-core) 一種開源身份驗證解決方案,提供強大的安全功能和輕鬆集成,以增強 Web 和行動應用程式中的使用者身份驗證和授權。 它為開發人員提供了一個全面的工具包,用於保護用戶資料並確保無縫登入體驗。 ![Supertokens](https://supertokens.com/docs/static/assets/arch.png) ## 5\. [Git](https://github.com/git/git) Git 版本控制系統的官方開源程式庫,最初由 Linus Torvalds 建立。 Git 廣泛用於追蹤原始程式碼的更改,並透過提供強大的分支和合併功能來實現協作軟體開發。 ![Git](https://www.lumis.com.br/data/files/FC/F4/E3/0A/098EA7108FA5E7A7C808A8A8/Gitflow__-_blog___interna.png) ## 6\. [VS 代碼](https://github.com/microsoft/vscode) 由 Microsoft 開發的免費開源程式碼編輯器。 它提供了高度可自訂且高效的程式設計環境,具有 IntelliSense、調試支援和龐大的擴充庫等功能,可增強您的開發工作流程。 ![VS代碼](https://user-images.githubusercontent.com/35271042/118224532-3842c400-b438-11eb-923d-a5f66fa6785a.png) ## 7\. [OhMyZsh](https://github.com/ohmyzsh/ohmyzsh) 一個流行且高度可自訂的框架,用於在類 Unix 作業系統中管理 Zsh 配置。 它簡化了 shell 自訂,提供了大量插件和主題來增強您的命令列體驗。 ![OhMyZsh](https://cloud.githubusercontent.com/assets/2618447/6316862/70f58fb6-ba03-11e4-82c9-c083bf9a6574.png) ## 8\. [包子](https://github.com/oven-sh/bun) 一個開源 JavaScript 工具包,旨在簡化和優化為 Web 應用程式捆綁 JavaScript 程式碼的過程。 它提供了一種現代且快速的方法來建立捆綁包,從而增強了使用 JavaScript 專案時的效能和開發人員體驗。 ![Bun](https://cdn.hashnode.com/res/hashnode/image/upload/v1696318057709/5a1125cf-eb78-4e9d-9632-faebd228abe5.png) ## 9\. [SWR](https://github.com/vercel/swr) SWR(Stale-While-Revalidate)是一個用於在 React 應用程式中取得資料的 JavaScript 函式庫。 它可以在客戶端和伺服器之間實現高效、自動的資料同步,提供無縫的即時更新,同時確保資料保持新鮮和最新。 ![SWR](https://cdn.hashnode.com/res/hashnode/image/upload/v1696318453842/d9ab3384-becc-4040-93f7-8a9e064100b1.png) ## 10\. [Prisma](https://github.com/prisma/prisma) 用於現代應用程式開發的開源資料庫工具包,透過強大的查詢產生器和類型安全的 ORM(物件關聯映射)層簡化資料庫存取和操作。 它允許開發人員使用聲明性和直觀的方法管理資料庫並與之交互,從而使資料庫操作在各種資料庫系統中無縫且安全。 ![Prisma](https://i.imgur.com/O1lwo0v.png) ## 11\. [ElasticSearch](https://github.com/elastic/elasticsearch) 由 Elastic 開發的強大且可擴展的開源搜尋和分析引擎。 它旨在幫助用戶快速有效地搜尋、分析和視覺化大量數據,使其成為從全文搜尋引擎到日誌分析等應用程式的熱門選擇。 ![ElasticSearch](https://cdn.hashnode.com/res/hashnode/image/upload/v1696315923559/58c2db03-9a6c-4b98-9b48-a91025c507a2.png) ## 12\. [哈蘇拉](https://github.com/hasura/graphql-engine) 一款功能強大的開源工具,可簡化應用程式的 GraphQL API 開發。 借助 Hasura,您可以輕鬆建立、管理和保護 GraphQL API,從而更輕鬆地與資料來源互動並建立現代的資料驅動應用程式。 ![Hasura](https://assets.website-files.com/63e3d6905bacd6855fa38c1c/63e3d6905bacd64f08a38f95_Hasura.jpg) ## 13\. [BioDrop](https://github.com/EddieHubCommunity/BioDrop) 透過單一連結與您的受眾建立聯繫。在一處展示您創建的內容和項目。 讓人們更容易找到、關注和訂閱。 ![BioDrop](https://user-images.githubusercontent.com/624760/230707268-1f8f1487-6524-4c89-aae2-ab45f0e17f39.png) ## 14\. [Powertoys](https://github.com/microsoft/PowerToys) 適用於 Windows 的開源實用程序,可提高工作效率和自訂功能。 它提供了一系列方便的工具和實用程序,包括快速啟動器、文件預覽和視窗管理等功能,旨在簡化您的 Windows 體驗。 ![Powertoys](https://cdn.hashnode.com/res/hashnode/image/upload/v1696280333258/279d3728-4731-46eb-9836-c8300d3a9f75.png) ## 15\. [Strapi](https://github.com/strapi/strapi) 開源無頭內容管理系統 (CMS),使開發人員能夠快速建立強大且可自訂的 API。 它使團隊能夠輕鬆創建和管理內容豐富的網站和應用程序,為各種專案提供靈活性和可擴展性。 ![Strapi](https://cdn.hashnode.com/res/hashnode/image/upload/v1696316645227/6122feae-4b38-4c00-a8a1-30da5346568c.png) ## 16\. [看似合理](https://github.com/plausible/analytics) 一種開源網路分析工具,旨在為網站所有者提供對其網站效能的簡單且注重隱私的見解。 它提供用戶友好、輕量級的跟踪,且不會損害訪問者的隱私,使其成為那些重視數據分析而無需侵入性跟踪方法的人的理想選擇。 ![看似](https://cdn.hashnode.com/res/hashnode/image/upload/v1696280734881/0cc0aa58-46e1-49ac-a920-65f7eaad6e33.png) ## 17\. [Astro](https://github.com/withastro/astro) 現代靜態網站產生器,透過僅傳送頁面所需的 JavaScript 來提供閃電般的效能,從而實現近乎即時的載入時間。 它將傳統伺服器渲染框架的靈活性與靜態網站產生器的速度相結合,使其成為建立高效動態網站的絕佳選擇。 ![Astro](https://deegloo.com/wp-content/uploads/2022/11/blogblog-cover-1024x614.png) ## 18\. [混音](https://github.com/remix-run/remix) 用於建立現代 JavaScript 應用程式的 Web 框架,注重速度和開發人員體驗。 它使開發人員能夠透過無縫組合伺服器渲染和客戶端渲染的內容來創建高效能的 Web 應用程式。 ![混音](https://cdn.shopify.com/s/files/1/0779/4361/files/RemixRun_bcc7b8fd-ca3a-4385-b279-91a0606706e7.jpg?v=1666895610) ## 19\. [張量流](https://github.com/tensorflow/tensorflow) 由Google開發的開源機器學習框架。 它為建立和部署機器學習模型提供了靈活且全面的生態系統,使其成為人工智慧領域研究人員和開發人員的熱門選擇。 ![Tensorflow](https://m-alcu.github.io/assets/tensorflow-playground.png) ## 20\. [顫動](https://github.com/flutter/flutter) 由 Google 創建的開源 UI 軟體開發工具包,以其從單一程式碼庫建立適用於行動、Web 和桌面的本機編譯應用程式的能力而聞名。 它使開發人員能夠使用單一程式語言 Dart 跨多個平台創建美觀、快速且高度可自訂的使用者介面。 ![Flutter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696281232879/35493958-0397-40c4-9c30-ca0faead9f39.png) ## 21\. [Kubernetes](https://github.com/kubernetes/kubernetes) 一個開源容器編排平台,可自動執行容器化應用程式的部署、擴充和管理。 它為編排容器提供了強大而靈活的基礎架構,使在雲端原生環境中大規模管理複雜的分散式系統變得更加容易。 ![Kubernetes](https://d33wubrfki0l68.cloud.net/2475489eaf20163ec0f54ddc1d92aa8d4c87c96b/e7c81/imaimages/docofs/components-d4c87c96b/e7c81/images/docofs/components-vv-uberknetes.svvv) ## 22\. [Docker](https://www.docker.com/community/open-source/) 一個開源工具,可簡化多容器 Docker 應用程式的管理。 它允許開發人員使用簡單的 YAML 檔案定義和運行多容器應用程序,從而更輕鬆地編排和部署複雜的服務。 ![Docker](https://cdn.hashnode.com/res/hashnode/image/upload/v1696316908120/7e01fe2b-a438-4882-8cd6-863b7f5effb0.png) ## 23\. [鉻](https://github.com/chromium/chromium) Google 的一個開源瀏覽器項目,旨在為所有使用者建立更安全、更快、更穩定的網路體驗方式。 它是開發人員在網路瀏覽技術領域做出貢獻和創新的平台。 ![Chromium](https://cdn.hashnode.com/res/hashnode/image/upload/v1696319343433/61d13e7f-512b-40b7-a127-b127a944cf9d.png) ## 24\. [Linux 核心](https://github.com/torvalds/linux) 由 Linus Torvalds 和全球貢獻者社群開發的開源、類別 Unix 作業系統核心。 它作為各種基於 Linux 的作業系統的核心組件,提供硬體互動和系統管理的基本功能。 ![Linux 核心](https://upload.wikimedia.org/wikipedia/commons/2/2e/Linux_Mint_21_%22Vanessa%22_%28Cinnamon%29.png) --- 寫作一直是我的熱情,幫助和激勵人們讓我感到很高興。如果您有任何疑問,請隨時與我們聯繫! 透過[Twitter](https://twitter.com/madzadev)、[LinkedIn](https://www.linkedin.com/in/madzadev/) 和[GitHub](https://github.com) 與我聯繫/madzadev)! 請訪問我的[部落格](https://madza.dev/blog)以獲取更多此類文章。