🔍 搜尋結果:go

🔍 搜尋結果:go

後端 JS 訓練二:第1課 ── 回應 http get request

## 課程目標 - 使用 node 與 express 回應 http get request ## 課程內容 在 node 中開發後端程式,通常會使用一款叫做 express 的套件 雖然不用 express 也能夠開發後端應用,但 express 提供很多現成好用功能 所以先來安裝 express 吧! ``` npm install express ``` 建立一個資料夾,放我們每課的練習內容,這一課就叫 lesson1 吧 然後建立一個 index.js 檔案 此時資料夾會長類似這樣 ``` repo ├── package.json ├── package-lock.json ├── node_modules └── lesson1    └── index.js ``` 在 index.js 檔案放入以下內容 ``` const express = require('express'); const app = express(); app.get('/', function(req, res){ res.send('<h1>恭喜您,成功囉!</h1>'); }); app.listen(3000); ``` 然後去終端機輸入 ``` node lesson1/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/ ``` 你會看到一段大大的打招呼訊息! --- 讓我們逐行說明一下 前面兩句是載入 express 套件,然後建立主程式物件 `app.get()` 是註冊登記一個處理 `HTTP GET 請求` 第一個參數是 `要處理的網址` 第二個參數是放進一段「函式定義」代表要如何處理 函式定義通常會用 `(req, res)` 當參數,有人會寫 `(request, response)`,都可以,分別是代表 `請求` 與` 回應` 的物件 這段看不太懂沒關係,需要稍微研究一下「HTTP 協定」才會知道定義 反正就先用 `res.send` 來回應一段 html 就對了! 最後用 `app.listen(3000);` 來在 port 3000 跑這段後端程式 --- 在一台電腦上,多個程式之間彼此溝通,通常會在電腦上各自使用一個 port 號碼 在瀏覽器中,通常只會輸入網址,例如 `https://www.google.com.tw` 之類的 只輸入網址,代表使用 443 當作 port,舉例來說,你可以在網址輸入 `https://www.google.com.tw:443` 看看,結果一模一樣 一個 port 只能同時給一個程式使用,為了避免用到別的程式在用的 port,我們請 node 在這邊使用 3000 這個冷門的 port,方便我們測試 然後 `localhost` 不是真的網址,是請瀏覽器直接在本機電腦上尋找網站開啟的意思! 以上通通看不懂沒關係,需要對 `網際網路協定` 稍微研讀才比較懂,先照做即可! ## 課後作業 這次的系列作業,要練習開發一個「個人日記 APP」 首先來練習如何用 node 回應 http get request 請開發一個 app,打開首頁 `http://localhost:3000/` 會顯示 `<h1>我的個人日記 APP</h1>`,先做到這樣就好 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 請建立一個 repo 上傳到 github 這個 repo 的檔案結構應該會是這樣: ``` repo ├── package.json ├── package-lock.json ├── node_modules └── hw1    └── index.js ``` 接下來的每次作業,都新開一個小資料夾 然後把 github 專案連結,貼到留言區即可

用Github Page整理作品集

因為一直找不到工作(...汗)所以來整理作品 [成果展示](https://superyngo.github.io/to_do_list/) 基本上是參考[Let's Write](https://www.letswrite.tw/)做的[Demo](https://letswritetw.github.io/letswrite-food-check/) 在頁面下方有作品導覽以及Github連結 使用工具: 1.Github Page 2.[Google Tag Manager](https://tagmanager.google.com/#/home) 步驟: 1.申請GTM並取得GTM代碼 2.將GTM代碼插入所有專案的index.html中,並將所有專案上傳github,開啟page頁面 3.另外做一個myNavbat的github page,將所有專案連結放進去,可參考[我做的](https://github.com/superyngo/myNavbar) 4.用GTM的「自訂HTML」功能將myNavbar和github連結塞進所有專案中,參考代碼如下: ``` <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> <div class="myNav"></div> <div class="github"> <a class="githubHerf"> <i class="fa fa-github" aria-hidden="true"></i> </a> </div> <script> var githubHerf=document.querySelector(".githubHerf") githubHerf.setAttribute("href","https://github.com/superyngo"+{{Page Path}}) var myNav2 = document.querySelector(".myNav"); var iframe2 = document.createElement("iframe"); iframe2.setAttribute("src", "https://superyngo.github.io/myNavbar/"); iframe2.setAttribute("width", "100%"); iframe2.setAttribute("frameborder", "0"); myNav2.appendChild(iframe2) </script> <style> body{ background-color: #fff0df; } .github { position: fixed; left: 0; bottom: 0; display: flex; width: 100px; height: 100px; cursor: pointer; z-index: 2; :hover { position: absolute; left: 10px; bottom: 5px; font-size: 3rem; color: #fff; scale: 0.9; } } .github::before { content: ""; width: 0; height: 0; border-style: solid; border-width: 100px 0 0 100px; border-color: transparent transparent transparent #6e5494; } .github .fa { position: absolute; left: 10px; bottom: 5px; font-size: 3rem; color: #fff; } @media screen and (max-width: 600px) { :root { font-size: 12px; } .github { width: 70px; height: 70px; } .github::before { border-width: 70px 0 0 70px; } .github .fa { left: 8px; bottom: 4px; font-size: 2rem; } } </style> ``` 注意事項; 1.不知為何我GTM塞iframe一直不給過,所以用append的。 2.iframe內的超連結預設會在iframe內開啟,要避免只要在myNavbar的head裡加上<base target="_parent" />就可以了。 3當初做這些作業時完全沒考慮theme和RWD,花了一些時間但又不想花太多時間結果就勉勉強強用手機也都能開。 閒聊: 前陣子都在codeSignal上刷題,看別人解法真的很神,學很多... 有沒有北部公司缺人啊...投履歷都沒人回..中年轉行真的不行嗎...

Pair Programming:實務技巧與工具推薦

合作對於開發高質量程式碼至關重要。在本文中,我們將探討結對編程的概念,揭示其優點並推薦有用的工具。我們還將打破一些關於結對編程的常見誤解。 原文出處:https://dev.to/documatic/pair-programming-best-practices-and-tools-154j ## 什麼是結對編程? [結對編程](https://en.wikipedia.org/wiki/Pair_programming) 是一種讓兩個開發人員一起完成同一任務的技術。在這個過程中,一個人編寫程式碼(驅動程序),另一個人檢查每一行並提供反饋(導航器)。這種方法不同於傳統的單獨編程,並具有多種優點。 驅動程序的職責是專注於操作計算機和輸入程式碼的機制。導航員的責任是思考需要做什麼以及我們要去哪裡。兩人會不斷地溝通並頻繁地轉換角色,可能每隔幾分鐘。 ![結對編程](https://martinfowler.com/articles/on-pair-programming/driver_navigator.png) ## 結對編程的好處 ### 提高程式碼質量 當兩個軟體工程師一起工作時,他們可以快速發現彼此的錯誤,從而產生高質量的程式碼,從而顯著減少遺漏錯誤的機會。編程合作夥伴可以提供寶貴的見解、提出改進建議,並在做出承諾之前獲得有關其想法的反饋。 例如,在處理編碼問題時,一個軟體工程師可以專注於實現解決方案,而另一個軟體工程師則監視任何錯誤或語法錯誤。這樣,團隊就可以建立更清晰、更實用、更優化的程式碼。 ### 加強協作和溝通 結對編程還增強了兩個開發人員之間的協作。它幫助他們在相同的程式碼庫上工作並分享他們的知識和技能,從而更好地解決問題。它還解決了同事之間的溝通鴻溝,因為它促進了溝通,實現了快速、輕鬆的訊息共享。 例如,在開發新功能時,一名軟體工程師可以解釋他們的思維過程和想法,而另一名軟體工程師可以提供反饋並提出問題以澄清需要做什麼。這樣,團隊就可以共同尋找最佳解決方案並避免誤解。 ### 提高生產力 結對編程可以提高開發團隊的生產力。當兩個軟體工程師一起工作時,他們可以通過分擔責任更快地完成任務。一個可以解決問題,另一個可以搜尋潛在的錯誤。這樣,團隊就能比單獨工作更高效地解決問題、更有效地工作。這也取決於個人,一些軟體工程師在單獨工作時效率更高。 例如,在一個專案上的兩人合作中,一個人可能需要一兩個小時才能完成一項單獨開發人員需要三四個小時才能完成的任務。第二對可以專注於查找程式碼中的錯誤或其他問題。這意味著團隊可以用更少的時間和更少的精力完成任務,從而提高整體生產力。 ## 關於結對編程的誤解 在討論結對編程的最佳實踐之前,讓我們先澄清一些關於結對編程的誤解。 ### 誤區#1:結對編程很昂貴 這是關於結對編程的一個常見誤區。但實際上,這是對團隊生產力、程式碼質量和創新的投資。從長遠來看,通過及早發現錯誤可以節省時間並降低成本。所以,這不是真的。 ### 誤區#2:結對編程很慢 結對編程比其他編碼方法更快,因為它允許快速更正。當兩個開發人員協作時,他們可以避免許多錯誤和錯誤並加快問題解決速度。因此,除非開發人員只是為了好玩而不是高效地工作,否則這是不正確的。 ### 誤區#3:結對編程導致緊張 一些人認為結對編程會給開發人員帶來太大壓力,導致工作場所發生衝突。然而,這種情況只發生在該技術實施不佳的情況下。這取決於您與編程夥伴的關係如何。如果它很好,那麼這不適用於你。 ## 結對編程的最佳實踐 為了充分利用結對編程課程,請考慮遵循以下最佳實踐: ### 明確定義角色 明確界定駕駛員和領航員的角色。駕駛員編寫程式碼,而導航員檢查程式碼並提供反饋。經常切換角色以保持兩位開發人員的參與並避免一個人主導整個會話。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/govzbp92oczw6yx7259t.png) ### 有效溝通 結對編程期間,溝通至關重要。雙方開發人員都應該積極參與,表達自己的想法,並認真傾聽。分享想法、提出問題並公開討論程式碼。使用螢幕共享和程式碼審查平台等協作工具來促進溝通。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y46bjmfoivparjdb5lu2.png) ### 尊重和同理心 相互尊重和同理心對於成功的結對編程至關重要。重視彼此的意見、想法和專業知識。對建設性批評持開放態度,避免人身攻擊。建立一個鼓勵協作和學習的支持性和非評判性環境。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e34ughpeje20bxfbuekt.png) ### 休息一下 結對編程可能對智力要求很高。定期休息對於防止疲勞和保持工作效率非常重要。利用這些休息時間反思進展、討論挑戰併計劃下一步。請記住考慮彼此的精力水平並相應地安排休息時間。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/au3xmal7cftl1xtx5tub.png) ### 擁抱學習機會 結對編程是學習和技能發展的絕佳機會。與您的合作夥伴分享知識、技術和最佳實踐。對新想法和方法持開放態度。鼓勵參與的開發人員不斷學習和成長。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k1myouifacd659tc2ox6.png) ### 練習主動程式碼審查 利用結對編程的力量來持續審查和驗證程式碼。討論潛在的改進、及早發現缺陷並解決設計缺陷。利用兩位開發人員的專業知識來確保程式碼具有最高質量。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chmhnulefghzk17ulmy9.png) ### 計劃並設定目標 在開始結對編程課程之前,討論並調整手頭任務的目的和目標。將工作分解為更小的、可管理的部分。設定明確的里程碑並確定任務的優先順序,以保持重點和進展。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7hse6ayo7sggjfrico6y.png) ### 記錄和分享知識 在結對編程會議期間做筆記,以記錄重要的討論、決策和見解。建立可以與團隊共享的文件,有助於傳播知識並確保整個專案的一致性。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfqcuoqdpv2dq9bxigiz.png) ### 反思和改進 完成結對編程課程後,花時間反思這次經歷。討論哪些方面進展順利,哪些方面可以改進。根據反饋和經驗教訓不斷完善您的結對編程實踐。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3dlrw737qbsij0i3fvb8.png) *通過遵循這些最佳實踐,您可以最大限度地發揮結對編程的優勢。協作和程式碼質量將得到改善,開發人員將有機會增長他們的技能和知識。* ## 結對編程工具 為了充分利用結對編程,開發人員可以依靠各種工具來簡化流程。以下是一些可用的最佳工具: ### 實時分享(VS Code) [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare) 是 VS Code 的擴展。它包含在最新版本的 VS Code 中。該工具使使用 VS Code 的開發人員能夠實時協作。 ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686383031679/a2336e60-fe72-477b-ada7-978c113961ef.png) ### Replit [Replit](https://replit.com/) 是一個在線工具,可讓您與其他開發人員協作,而無需下載或安裝任何額外的軟體。您所要做的就是打開網絡瀏覽器,然後就可以開始了。如果您只是需要與其他人一起實時編輯程式碼,那麼它是完美的。 Replit 的一大優點是它支持 50 多種編程語言,使其具有多功能性並適合廣泛的專案。 ![](https://replit.com/public/images/IDE2/hero-image.svg) ### CodeSandbox Live [CodeSandbox](https://codesandbox.io/blog/introducing-codesandbox-live-real-time-code-collaboration-in-the-browser) Live 是一項實時協作功能,使開發人員能夠在同一平台上工作實時專案。借助 CodeSandbox Live,多個開發人員可以同時處理同一個程式碼庫,從而更輕鬆地協作處理複雜的專案。 ![](https://codesandbox.io/_next/image?url=%2Fnew%2Fblog%2Fintroducing-codesandbox-live-real-time-code-collaboration-in-the-browser%2F0.gif&w=1920&q=75) ### Codeanywhere [Codeanywhere](https://codeanywhere.com/) 是一個基於雲的集成開發環境 (IDE),允許開發人員使用任何具有網路連接的設備從任何地方編碼、協作和管理他們的專案。它提供了一套全面的工具和功能來促進編碼和簡化開發工作流程。 ![](https://i.imgur.com/jIr0IqV.png) ### [CodeTogether](https://www.codetogether.com/) CodeTogether **允許您通過 Eclipse、IntelliJ 或 VS Code 主持和加入協作編碼會話**。來賓可以從安裝了 CodeTogether 的自己的 IDE 加入會話,即使它與主機的 IDE 不同。訪客還可以通過任何現代瀏覽器加入會話,無需進行任何設置。 ![](https://i.imgur.com/8KDJzAv.png) ## 結論 最後,結對編程對於軟體開發人員來說是一種非常有效的技術。它增強了協作、程式碼質量、團隊生產力和許多其他方面。遵循最佳實踐並使用適當的工具是成功結對編程的關鍵。

改善重用性:Vue Composables 的推薦技巧&Design Patterns

本文將分為三個部分: 1. 通用設計模式 2. 我的建議 3. 進一步閱讀 享受並且讓我知道您在專案中使用的模式和實踐🚀 原文出處:https://dev.to/jacobandrewsky/good-practices-and-design-patterns-for-vue-composables-24lk ## 通用設計模式 我認為了解建置可組合項模式的最佳來源實際上是 Vue.js 文件,您可以在[此處](https://vuejs.org/guide/reusability/composables.html)查看 ### 基本可組合項 Vue 文件顯示了以下 useMouse 可組合項的示例: ``` // mouse.js import { ref, onMounted, onUnmounted } from 'vue' // by convention, composable function names start with "use" export function useMouse() { // state encapsulated and managed by the composable const x = ref(0) const y = ref(0) // a composable can update its managed state over time. function update(event) { x.value = event.pageX y.value = event.pageY } // a composable can also hook into its owner component's // lifecycle to setup and teardown side effects. onMounted(() => window.addEventListener('mousemove', update)) onUnmounted(() => window.removeEventListener('mousemove', update)) // expose managed state as return value return { x, y } } ``` 稍後可以在元件中使用它,如下所示: ``` <script setup> import { useMouse } from './mouse.js' const { x, y } = useMouse() </script> <template>Mouse position is at: {{ x }}, {{ y }}</template> ``` ### 異步可組合項 為了獲取資料,Vue 建議使用以下可組合結構: ``` import { ref, watchEffect, toValue } from 'vue' export function useFetch(url) { const data = ref(null) const error = ref(null) watchEffect(() => { // reset state before fetching.. data.value = null error.value = null // toValue() unwraps potential refs or getters fetch(toValue(url)) .then((res) => res.json()) .then((json) => (data.value = json)) .catch((err) => (error.value = err)) }) return { data, error } } ``` 然後可以在元件中使用它,如下所示: ``` <script setup> import { useFetch } from './fetch.js' const { data, error } = useFetch('...') </script> ``` ### 可組合合約 根據上面的示例,以下是所有可組合項都應遵循的約定: 1. 可組合文件名應以 use 開頭,例如 `useSomeAmazingFeature.ts` 2. 它可以接受輸入參數,這些參數可以是字串等基本類型,也可以接受 refs 和 getter,但需要使用 toValue 幫助器 3. Composable 應該返回一個 ref 值,該值可以在解構可組合項後存取,例如 `const { x, y } = useMouse()` 4. 可組合項可以保存可以在整個應用程式中存取和修改的全局狀態。 5. 可組合性可能會產生副作用,例如加入窗口事件偵聽器,但在卸載元件時應清除它們。 6. 可組合項只能在 `<script setup>` 或 `setup()` 掛鉤中呼叫。它們也應該在這些上下文中同步呼叫。在某些情況下,您還可以在生命週期掛鉤中呼叫它們,例如“onMounted()”。 7. 可組合項可以呼叫內部的其他可組合項。 8. 可組合項應在內部包裝某些邏輯,當過於復雜時,應將它們提取到單獨的可組合項中以便於測試。 ## 我的建議 我已經為我的工作專案和開源專案建置了多個可組合項 - NuxtAlgolia、NuxtCloudinary、NuxtMedusa,因此基於這些,我想根據我的經驗在上面的合同中加入一些要點。 ### 有狀態或/和純函數可組合項 在程式碼標準化的某個時刻,您可能會得出這樣的結論:您希望對可組合項中的狀態保留做出決定。 最容易測試的函數是那些不存儲任何狀態的函數(即它們是簡單的輸入/輸出函數),例如負責將字節轉換為人類可讀值的可組合函數。它接受一個值並返回一個不同的值 - 它不存儲任何狀態。 不要誤會我的意思,你不必做出“或”的決定。您可以完全保留有狀態和無狀態可組合項。但這應該是一個書面決定,以便以後更容易與他們合作 🙂 ### 可組合項的單元測試 我們希望使用 Vitest 為我們的前端應用程式實施單元測試。在後端工作時,進行單元測試程式碼覆蓋率非常有用,因為您主要關注邏輯。然而,在前端,您通常使用視覺效果。 因此,我們認為對整個元件進行單元測試可能不是最好的主意,因為我們基本上將對框架本身進行單元測試(如果按下按鈕,檢查狀態是否更改或模式是否打開)。 由於我們已將所有業務邏輯移至可組合項(基本上是 TypeScript 函數)內,因此它們很容易使用 Vitest 進行測試,並且允許我們擁有更穩定的系統。 ### 可組合項的範圍 不久前,在 VueStorefront 中,我們開發了自己的可組合方法(早在它們實際上像這樣被呼叫之前)。在我們的方法中,我們使用可組合項來映射電子商務的業務領域,如下所示: ``` const { cart, load, addItem, removeItem, remove, ... } = useCart() ``` 這種方法絕對有用,因為它允許將域包裝在一個函數中。在“useProduct”或“useCategory”等更簡單的示例中,實現和維護相對簡單。然而,正如您在此處的“useCart”示例中看到的那樣,當包裝一個包含更多邏輯而不僅僅是資料獲取的域時,這個可組合項正在發展成為一種非常難以開發和維護的形狀。 此時,我開始為 Nuxt 生態系統做出貢獻,其中引入了不同的方法。在這種新方法中,每個可組合項僅負責一件事。因此,我們的想法不是建置一個巨大的“useCart”可組合項,而是為每個功能建置可組合項,即“useAddToCart”、“useFetchCart”、“useRemovefromCart”等。 因此,維護和測試這些可組合項應該更容易 🙂 ## 進一步閱讀 這將是我的研究的全部內容。如果您想了解有關此主題的更多訊息,請務必查看以下文章: * https://vuejs.org/guide/reusability/composables.html * https://www.youtube.com/watch?v=bcZM3EogPJE * https://vueschool.io/articles/vuejs-tutorials/what-is-a-vue-js-composable/ * https://blog.logrocket.com/getting-started-vue-composables/ * https://macopedia.com/blog/news/how-can-vue-3-composables-make-your-life-easier

AI 咒語工程簡介:什麼是 AI 咒語工程?如何利用各種 AI 得到理想產出?

人工智能遍地開花,隨處可見一些新的人工智能工具。在 [ChatGPT](https://openai.com/blog/chatgpt)、[AutoGPT](https://autogpt.net/)、[Midjourney](https://www.midjourney.com/home/) 之間, [Dall-E](https://openai.com/dall-e-2) 和 [GitHub Copilot](https://github.com/features/copilot),您可以建置、編碼、獲取答案,以及創造美麗的藝術品……至少我們中的一些人可以。 為什麼有些人在使用生成式 AI 時比其他人獲得更好的結果?為什麼有些人製作的藝術品配得上盧浮宮,而另一些人卻得到了接近狗屁的東西? 這一切都取決於您使用的輸入。此輸入稱為“提示”。提示是您提出的問題,或者您用來建立內容的詞語。那些“製作”提示或對輸入有策略的人將其稱為“提示工程”。 原文出處:https://dev.to/github/prompt-engineering-for-ai-what-is-prompt-engineering-and-how-to-get-good-results-from-ai-engines-5ch6 ## 什麼是提示工程? 提示工程是指專門設計提示,以便從 AI 獲得更好的結果。 [OpenAI](https://openai.com/)、[Google](https://bard.google.com/) 等人工智能係統的建立者甚至聘請“快速工程師”來幫助訓練他們的模型。一些“創作者”甚至在 Etsy 等平台上出售他們的 Midjourney 提示。 簡而言之,人工智能系統就像資料:輸入垃圾,輸出垃圾。如果輸入錯誤,可能會得到錯誤的結果。提示工程在很大程度上受上下文影響。 ## 人工智能的背景 當涉及到我們得到的結果時,上下文是最大的問題之一。例如,如果我用谷歌搜尋“donut”(或“doughnut”:doughnut:),我可以獲得一整套結果;從甜甜圈食譜到甜甜圈圖片,或者在哪裡可以買到這種美味的甜點。這是因為我沒有給搜尋引擎任何其他上下文。當然,Google 會使用我之前的搜尋歷史記錄和我的位置等訊息來幫助確定結果,但僅此而已。 ![GitHub 甜甜圈](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rp4pnnp89sr7u1nkqnli.jpg) _搜尋引擎中的術語“甜甜圈”可以指任何形狀、Slack 插件、應用程式,或者 GitHub Universe 2022 上提供的這些美味的 GitHub 甜甜圈_ 例如,如果我想找到一個關於在 Blender 中建立甜甜圈 3D 模型的教程,那麼如果我只輸入“甜甜圈”,搜尋結果可能不會顯示。我需要更具體。諸如“甜甜圈 Blender3D 教程”之類的東西會為我提供更準確的結果。 人工智能也是如此。您需要為 AI 提供足夠的上下文,以便根據您的需要獲得更好的結果。 ## 聊天應用的提示工程 許多人向我們展示了來自 ChatGPT 的一些瘋狂結果。雖然它們並不總是準確的,但 ChatGPT 確實擅長一件事:散文。寫出優美、結構合理、流暢的句子真是令人難以置信。結果很容易閱讀,聽起來真的很棒。但獲得準確的回應完全是另一回事。例如,人們厭倦了使用 ChatGPT 撰寫歷史文章,雖然文章可能讀起來不錯,但在歷史上可能並不准確。比如你讓ChatGPT“寫一篇關於中國的淪陷的2000字的文章”,它就會給你寫一篇關於中國的淪陷的2000字的文章。但它不一定是事實正確的。 ![ChatGPT 生物響應](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jc4mphrlgsmfw3yobfo.png) _雖然某些內容可能讀起來不錯,但實際上可能不正確。提示:我沒有博士學位_ :wink: 這是因為 ChatGPT 從各種來源獲取訊息並將它們融合在一起。這些來源本身可能並不准確。 ChatGPT 也不知道您指的是中國的_哪個_秋天。因此它很容易錯誤地交叉引用日期。通過以對話方式向 ChatGPT 提供訊息,然後要求它寫一篇 2000 字的文章,您將獲得更好的結果。 那到底是什麼意思?有些人認為 ChatGPT 是一種單向的、對話式的、單一輸入的獲取訊息的方法。但事實並非如此。它被稱為“聊天”是有原因的。進行對話,完善您的問題,為您的回答提供背景訊息。 例如,如果我想要一段關於“NDC 會議”的旅行報告,我不會以“給我寫一段 NDC 旅行報告”來開始我的 ChatGPT。相反,我會首先弄清楚 ChatGPT 對 NDC 了解多少,並在此過程中提供上下文。您提供的輸入在很大程度上決定了輸出。這就是為什麼有些人能夠獲得非常好的結果,而其他人則不能。 ![ChatGPT 響應](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eks1e166pqqu0jh9hpll.png) _沒有任何上下文,ChatGPT 不知道我指的是什麼 NDC_ 另一個例子:如果你要去參加工作面試,你想要一些提示,讓 ChatGPT“給我一些準備工作面試的提示”,會給你一些很好的回應,但它遠非具體。相反,諸如“我要去一家 AI 初創公司面試軟體開發人員的職位。你能給我一些準備面試的提示嗎?”將為您提供更加量身定制的個性化結果。這就好比你讓台上的專家給觀眾中的 1000 個人一個答案,他們可能會提供一些通用的東西,這樣每個人都有一個外賣訊息。但如果你一對一地問同一個人,他們可能會問你一些後續問題以了解你的情況,因此會提供更個性化、更具體的答案。 ## 藝術應用的提示工程 您可能已經看到一些人使用穩定的傳播應用程式創作的一些精美藝術品。然後是看起來“錯誤”的藝術品。其中很多都歸結為上下文。例如,如果我使用 [Night Café](https://nightcafe.studio/)(我最喜歡的生成器之一),然後輸入“dog”這個詞,這就是我得到的: ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/61ibs1fd5j3ht37e4epn.jpg) _使用 Night Café 生成的圖像,以及提示符“dog”_ 有一些隨機的“狗”字寫成一個標誌,前景中有一隻看起來很奇怪的狗,而且它的顏色非常奇怪。現在,如果我想像成年德國牧羊犬在陽光明媚的日子裡在公園裡的照片般的圖像,那可能不是我要得到的。人工智能沒有那種背景。它無法讀懂我的想法(還沒有!)。當你想創作藝術品時,你需要描述你在腦海中想像的圖像。您提供的細節越多,輸出就越好。這就是它變得棘手的地方。許多穩定的擴散應用程式都有有限的字符數。因此,您需要對如何製作提示具有意義和戰略性。 與 ChatGPT 類似,您需要不斷地重新製作提示並完善它們。然而,基於聊天的 AI 的優勢在於,您可以繼續對話並不斷向 AI 提供更多訊息和不同的問題,以獲得良好的回應。雖然一些藝術生成器允許您“重新混合”您的輸出,但它仍然依賴於新的提示。因此,您一直在等待輸出,查看未加入的內容,然後發送經過調整的新提示。一些用戶在 Midjourney 上花費數小時,接收輸出並重新製作他們的提示以產生一些驚人的作品。這都是練習的問題。這就是為什麼一些創作者在 Etsy 上出售他們的提示! ![AI生成戰鬥兔](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z0411o5c2fgbz7oikzwz.jpg) _我的朋友 Jean 使用 Midjourney 製作的藝術品_ 有一件事是肯定的,如果你想製作一些高質量的藝術品,不要指望花幾秒鐘寫一個提示,點擊“建立”按鈕然後看到莫內。沒有!相反,您需要投入時間(和金錢)來創作數百件藝術品,在每次迭代中重新處理您的提示以製作您的傑作。 ## 提示工程程式碼 我不會花大量時間談論如何為 [GitHub Copilot](https://github.com/features/copilot) 之類的東西製作好的提示。我的同事 [Rizel](https://twitter.com/blackgirlbytes/) 寫了一篇精彩的博文,深入探討了 GitHub Copilot 的提示工程: https://dev.to/github/a-beginners-guide-to-prompt-engineering-with-github-copilot-3ibp 我要說的是——類似於 ChatGPT——GitHub Copilot 依賴於上下文。存儲庫中還編寫了哪些其他程式碼?文件的擴展名(以及語言)是什麼? GitHub Copilot 還為您打造了什麼?您在程式碼中加入了哪些註釋?所有這些都將幫助 GitHub Copilot 為您合成更準確的程式碼。 可以這樣想:如果您寫了一條評論,說明您想要建立一個使用後端資料並解決特定問題的複雜函數,那麼您可能不會僅僅通過一條評論就得到很好的回應。就像你的程式碼——至少它應該是——被分解成許多函數,(希望)有很多有用的評論,當你分解東西時,GitHub Copilot 工作得更好。 而不是要求 GitHub Copilot: `//反轉句子`(使用 JavaScript) 想想如何從邏輯上分解問題。例如,如果有人給我一張紙,上面寫著一句話,讓我把它倒過來,我會怎麼做?像這樣寫評論會更有益。如果您這樣做,GitHub Copilot 將擁有更多的上下文並更好地理解您想要什麼。 與 ChatGPT 之類的東西相比,GitHub Copilot 的另一個區別是 GitHub Copilot 考慮了你擁有的_所有_上下文。我上面提到的所有事情: - 什麼是文件擴展名 - 專案中還有哪些其他文件 - 你是怎麼寫其他評論的 - 其他程式碼是如何建置的 - 您輸入的評論是什麼 - 您輸入的程式碼是什麼 ChatGPT 和其他聊天應用程式會更加重視您對聊天所做的最後評論; 也就是,您加入到對話中的最後一條訊息。但是,GitHub Copilot 始終會考慮上下文以生成更好的程式碼結果。 ## 更好的提示工程 歸根結底,從任何類型的生成式 AI 中獲得好的結果都在你身上——你提供輸入的人。正如我一開始所說:垃圾進,垃圾出。因此,在製作提示時請考慮以下重要提示: - 提供良好的**上下文**;提供有關您要實現的目標的示例和訊息 - 請明確點**;如果它是針對特定觀眾的,那麼就說 - **分解**問題 - **清楚**你如何提問。如果返回的內容聽起來不對,請澄清 - 根據您的提示**改寫**和**精煉** 最後,始終,始終驗證您從 AI 收到的訊息。對於藝術品生成器而言,這不太重要,但如果您查看程式碼和訊息,它就很重要。檢查您收到的程式碼是否按照您的預期工作。驗證提供給您的書面訊息的準確性。 請記住,無論發生什麼,您仍然是飛行員。您仍然是負責人,您對使用和共享哪些藝術作品、哪些程式碼片段以及哪些訊息有最終決定權。

Github 範本專案推薦:學習 React 技術的幾個 Repo

開源對很多事情都非常有用。其中之一是學習新技能。在本文中,我們將介紹 GitHub 上一些最好的開源 React 專案,您可以使用它們來快速提升您的 React 技能。 原文出處:https://dev.to/livecycle/top-github-repositories-to-learn-modern-react-development-5d3h ## 你可以學習的開源 React 專案 ![提升](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/app52pnsi0e6rey24kp1.gif) ## Cal.com ![Cal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jnra9gxpgh0y04ereq7.png) [https://github.com/calcom/cal.com](https://github.com/calcom/cal.com) Cal.com 將自己標榜為“絕對適合所有人的日程安排基礎設施”。他們是 Calendly 等預約安排服務的競爭對手。他們同時提供託管和自託管產品。它是一個全棧 Next.js 應用程式,它依賴 tRPC 進行類型安全的客戶端到伺服器通信。該存儲庫具有相當廣泛的 Monorepo 設置(使用 Turborepo),可將應用程式拆分為多個包。在樣式方面,Cal.com 使用 TailwindCSS 和無頭 Radix 元件。存儲庫非常活躍,他們積極鼓勵貢獻者。許多問題被標記為“良好的第一期”和“需要幫助”。 ## Taxonomy ![分類法](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfjhtw3tccnosgf5n0rn.png) [https://github.com/shadcn/taxonomy](https://github.com/shadcn/taxonomy) 這個有點不同。它由單個開發人員建置,作為探索新的 Next.js 13 App Router 功能的演示。但是不要讓那個愚弄你。它可以說是使用新 App Router 的最全面的開源應用程式之一。因此,即使對於想要學習如何在生產中使用 App Router 的經驗豐富的 React 開發人員來說,這也是一個很好的資源。 除了用於前端和後端的 Next.js 之外,Taxonomy 使用 NextAuth 進行身份驗證,使用 Prisma 作為 ORM,使用帶有 Radix 的 TailwindCSS 進行樣式設置。特別有趣的是 Stripe 訂閱集成。因此,如果您想了解如何將訂閱集成到您的應用程式中,這就是適合您的存儲庫。 ## Highstorm ![高塔](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/40cy6gokdozqqihlqgxr.png) [https://github.com/chronark/highstorm](https://github.com/chronark/highstorm) Highstorm 是這個街區的新玩家。它是一種監視應用程式中發生的事件的服務。您通過他們的 API 提交事件,然後將其輸入 Highstorm 儀表板。再次重申,這是一個基於 Next.js 的專案。它使用 Tinybird 作為分析資料的資料庫,並使用 Clerk 進行身份驗證。如果您想學習如何處理大量分析資料並將它們顯示在精美的圖表中,那麼這個專案很棒。 ## Dub.sh ![配音](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g90d1imz9110lv1uxb5l.png) [https://github.com/steven-tey/dub](https://github.com/steven-tey/dub) Dub.sh 大約在一年前作為開源連結縮短器推出。它是 Bitly 等服務的替代品。它也是基於 Next.js 並結合使用舊頁面和新 App 路由器。它通常是最早採用 Next.js 新功能(例如元資料 API)的專案之一。 該存儲庫是了解多租戶 Next 應用程式的好地方。這些是為不同域下的不同用戶提供服務的應用程式。在 Dub.sh 的情況下,用戶可以加入自己的域以在其下建立縮短的連結。該應用程式的設計也很精美,整個網站上都有許多令人愉悅的動畫。 Framer Motion 庫用於幫助解決此問題。 ## Bulletproof React ![防彈](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cndmw6tii88v9puz154.png) [https://github.com/alan2207/bulletproof-react](https://github.com/alan2207/bulletproof-react) Bulletproof React 與我們目前介紹的其他專案不同。該存儲庫確實包含一個功能齊全的演示 React 應用程式。但最大的價值來自閱讀此應用程式附帶的綜合文件。本文件列出了設計大型 React 應用程式各個方面的最佳實踐。這是一個很好的資源,可以定期參考以刷新您對最佳實踐的記憶。 ## 總結和開始 正如我們所見,上述每個存儲庫都提供了一個獨特的視角來了解大型 React 應用程式是如何建置的。每個人都可以從研究存儲庫的程式碼中獲益,無論您有多有經驗。 開始從存儲庫中學習的一個很好的實用技巧是提出一個特定的問題。例如,您可能會問“Taxonomy 如何處理 Stripe 訂閱?”之類的問題。然後挖掘程式碼層以找到問題的答案。 最後一點——探索開源存儲庫是提升 React 技能的好方法,但這不是您唯一應該做的事情。將您新獲得的知識應用到您自己的專案中也很重要。這就是您鞏固新技能和保留訊息的方式。 最主要的是享受這個過程,並認識到開源是培養新技能的友好場所,無論您目前的經驗水平如何。

增加開發者生產力:19 個簡單好用的 VScode 外掛

[VS Code](https://code.visualstudio.com/) 是一款免費、跨平台、開源的程式碼編輯器,近年來成為開發者最熱門的選擇。 在本文中,我整理了一些最有用的外掛,您可以使用它們來提高工作效率。 原文出處:https://dev.to/madza/19-vs-code-extensions-to-boost-your-productivity-4npo --- ### 1\. [Swimm](https://go.swimm.io/ide-plugin?utm_source=Hashnode&utm_medium=paid_influencer&utm_campaign=launch_may&utm_content=madza_dev) 使用 Swimm 的富文本編輯器建立文件。記錄跨越多個文件和存儲庫的複雜流程,其中包含與程式碼交互並在您進行更改時自動更新的豐富內容。 在本地驗證和更新文件,並將其作為 CI 工作流的一部分,自動修復簡單的錯誤,並且僅在發生重大更改時提醒您。 在正確的時間找到正確的文件——就在相關程式碼旁邊。當您看到一個 wave 時,這意味著存在與該特定程式碼部分相關的文件。 ![使用 Swimm 建立內部文件](https://storage.googleapis.com/swimmio-ide/assets/doc%20creation.png) ### 2\. [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) 借助 GitLens,開發人員可以通過提供有關 Git 存儲庫的高級可視化和訊息,更好地了解其程式碼庫的歷史、作者身份和更改。 GitLens 還提供了一組豐富的自定義選項,以及內聯責備註釋、提交和差異詳細訊息,甚至無需離開編輯器即可查看和編輯提交訊息的能力。 ![提交圖](https://raw.githubusercontent.com/gitkraken/vscode-gitlens/main/images/docs/commit-graph-illustrated.png) ### 3\. [Thunder Client](https://marketplace.visualstudio.com/items?itemName=rangav.vscode-thunder-client) Thunder Client 是用於 Visual Studio Code 的輕量級 Rest API 客戶端擴展,具有簡單易用的 UI。 支持集合和環境變數和 GraphQL 查詢,以及使用基於 GUI 的界面進行無腳本測試。 所有請求的資料都本地保存在您的設備上。 ![迅雷客戶端](https://github.com/rangav/thunder-client-support/blob/master/images/thunder-client-v2.png?raw=true) ### 4\. [Tabnine](https://marketplace.visualstudio.com/items?itemName=TabNine.tabnine-vscode) Tabnine 是一個 AI 程式碼助手,可以通過在所有最流行的編碼語言和 IDE 中實時完成程式碼來提高您的開發速度。 Tabnine 由多種語言專用的機器學習模型提供支持,這些模型是在程式碼上從頭開始進行預訓練的。 ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683725176305/71c6f916-5dd6-475a-ac87-066bc301d3e3.gif) ### 5\. [Remote-SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) Remote - SSH 擴展允許您使用任何帶有 SSH 伺服器的遠程機器作為您的開發環境。 無需在本地計算機上安裝源程式碼即可獲得這些好處,因為該擴展程序直接在遠程計算機上執行命令和其他擴展程序。 您可以打開遠程計算機上的任何文件夾並使用它,就像文件夾在您的計算機上一樣。 ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/psfddazji4zk1nfgcbrg.png) ### 6\. [Docker](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker) Docker 擴展使從 Visual Studio Code 建置、管理和部署容器化應用程式變得容易。 它還提供了對容器內 Node.js、Python 和 .NET 的一鍵式除錯。 ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kifgjwnunn9ynmr2odcf.png) ### 7\. [Git History](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory) 使用此擴展,用戶可以輕鬆瀏覽提交歷史記錄、檢查文件更改並比較程式碼的不同版本。 該擴展提供了一個 GUI,可以在時間軸中顯示提交歷史記錄。每個提交都與其提交訊息、作者、日期和時間一起顯示。 用戶還可以查看與每個提交關聯的分支和標籤名稱。 ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y7us7mebno5di3f7lp1l.png) ### 8\. [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) 對於在 VS Code 中使用大量 Markdown 的任何人來說,這是一個有用的工具。它使建立和編輯 Markdown 文件變得更加容易和快速,幫助您提高生產力和效率。 這些功能包括語法突出顯示、程式碼塊格式化、目錄、預覽模式、表情符號支持、鍵盤快捷鍵等等。 ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8f1ygmrmzd1ifz2q2pfq.png) ### 9\. [Regex Previewer](https://marketplace.visualstudio.com/items?itemName=chrmarti.regex) 該擴展在並排文件中顯示當前正則表達式的匹配項。這可以使用 Ctrl+Alt+M 打開/關閉。 可以通過狀態欄條目加入全局選項和多行選項,以便使用並排文件進行評估。當並排文件有多個匹配示例時,這會很有用。 ![執行中的正則表達式預覽器](https://github.com/chrmarti/vscode-regex/raw/main/images/in_action.gif) ### 10\. [Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments) 使用此擴展,您將能夠將註釋分類為提醒、查詢、TODO、突出顯示等。 註釋掉的程式碼也可以設置樣式以明確程式碼不應該存在。您可以在設置中指定您想要的任何其他評論樣式。 ![無法為 Python 使用 vs 程式碼“更好的評論擴展”- 堆棧溢出](https://i.stack.imgur.com/MFQJN.png) ### 11\. [Bookmarks](https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks) 書籤擴展可幫助您導航程式碼,輕鬆快速地在重要位置之間移動。 不再需要搜尋程式碼。它還支持一組選擇命令,允許您選擇書籤行和書籤行之間的區域。它對日誌文件分析非常有用。 ![切換](https://github.com/alefragnani/vscode-bookmarks/raw/HEAD/images/printscreen-toggle.png) ### 12\. [Project Manager](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager) 專案管理器可幫助您輕鬆存取您的專案,無論它們位於何處。不要再錯過那些重要的專案了。 您可以定義您的專案(也稱為收藏夾),或選擇自動檢測 Git、Mercurial 或 SVN 存儲庫、VS 程式碼文件夾或任何其他文件夾。 此外,您還可以使用標籤來組織您的專案。 ![側欄](https://github.com/alefragnani/vscode-project-manager/raw/HEAD/images/vscode-project-manager-side-bar-tags.gif) ### 13\. [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) 一個基本的拼寫檢查器,適用於程式碼和文件。 這個拼寫檢查器的目標是幫助捕獲常見的拼寫錯誤,同時保持較低的誤報率。 ![示例](https://raw.githubusercontent.com/streetsidesoftware/vscode-spell-checker/main/images/example.gif) ### 14\. [Image Optimizer](https://marketplace.visualstudio.com/items?itemName=MadsKristensen.ImageOptimizer) 向解決方案資源管理器中的任何文件夾和圖像加入右鍵單擊菜單,使您可以自動優化該文件夾中的所有 PNG、GIF 和 JPEG 文件。 只需右鍵單擊任何包含圖像的文件或文件夾,然後單擊其中一個圖像優化按鈕。 ![輸出窗口](https://github.com/madskristensen/ImageOptimizer/raw/master/art/output-window.png) ### 15\. [CSS Peek](https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek) 該擴展支持符號定義跟踪的所有正常功能,但它適用於 CSS 選擇器(類、ID 和 HTML 標記)。 您可以內聯加載 CSS 文件並在此處進行快速編輯,直接跳轉到 CSS 文件或在新編輯器中打開它或在懸停時顯示定義。 ![工作](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/working.gif) ### 16\. [Placeholder Images](https://marketplace.visualstudio.com/items?itemName=JakeWilson.vscode-placeholder-images) 使用各種第 3 方服務(如 Unsplash、LoremFlickr 等)在 Visual Studio Code 中生成佔位符圖像並將其插入到 HTML 中。 您可以選擇圖像寬度、高度、文本和顏色,將生成的 IMG 標籤插入到您的 HTML 中或將其複製到剪貼板,或者將圖像 URL 插入到您的 HTML 中,複製到剪貼板,或在您的瀏覽器中打開它。 ![使用 placehold.it 生成佔位符圖像](https://github.com/Jakobud/vscode-placeholder-images/raw/master/images/example.gif) ### 17\. [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) 具有實時瀏覽器重新加載功能的快速開發實時伺服器。從狀態欄單擊即可啟動或停止伺服器。 允許用戶建立可自定義的端口號,設置伺服器根目錄,並在設置中提供默認的瀏覽器配置選項。 ![實時伺服器演示 VSCode](https://github.com/ritwickdey/vscode-live-server/raw/HEAD/images/Screenshot/vscode-live-server-animated-demo.gif) ### 18\. [Peacock](https://marketplace.visualstudio.com/items?itemName=johnpapa.vscode-peacock) 使用 Peacock,您可以巧妙地更改 VS Code 工作區的顏色。 當你有多個 VS Code 實例、使用 VS Live Share 或使用 VS Code 的遠程功能,並且你想快速辨識你的編輯器時,這是理想選擇。 ![孔雀窗](https://raw.githubusercontent.com/johnpapa/vscode-peacock/main/resources/hero.png) ### 19\. [Polacode](https://marketplace.visualstudio.com/items?itemName=pnp.polacode) Polacode 是 VS Code 的擴展,它可以對你的程式碼進行截圖。 該擴展生成一個與源具有相同風格和主題的螢幕截圖。 ![用法](https://github.com/octref/polacode/raw/master/demo/usage.gif) --- 以上簡單分享,希望對您有幫助~

7 個進階、好用的 TypeScript 技巧用法分享

**TypeScript** 是一種出色的工具,可以讓我們的生活更輕鬆並避免 **bug**,但有時使用起來感覺不知所措。 本文概述了專業人士使用的 7 個 **TypeScript** 技巧,它們將使您的生活更輕鬆。 原文出處:https://dev.to/ruppysuppy/7-secret-typescript-tricks-pros-use-3ckg ## 1. 型別推理 **Typescript** 足夠聰明,可以在您幫助縮小資料類型時**推斷資料類型**。 ``` enum CounterActionType { Increment = "INCREMENT", IncrementBy = "INCREMENT_BY", } interface IncrementAction { type: CounterActionType.Increment; } interface IncrementByAction { type: CounterActionType.IncrementBy; payload: number; } type CounterAction = | IncrementAction | IncrementByAction; function reducer(state: number, action: CounterAction) { switch (action.type) { case CounterActionType.Increment: // TS infers that the action is IncrementAction // & has no payload return state + 1; case CounterActionType.IncrementBy: // TS infers that the action is IncrementByAction // & has a number as a payload return state + action.payload; default: return state; } } ``` 如上所示,**TypeScript** 根據 `type` 屬性推斷操作的類型,因此您無需檢查 `payload` 是否存在。 ## 2. 字串類型 通常你需要一個變數的特定值,這就是**文字類型**派上用場的地方。 ``` type Status = "idle" | "loading" | "success" | "error"; ``` 它也適用於數字: ``` type Review = 1 | 2 | 3 | 4 | 5; // or better yet: const reviewMap = { terrible: 1, average: 2, good: 3, great: 4, incredible: 5, } as const; // This will generate the same type as above, // but it's much more maintainable type Review = typeof reviewMap[keyof typeof reviewMap]; ``` ## 3.類型守衛 **類型保護** 是另一種縮小變數類型的方法: ``` function isNumber(value: any): value is number { return typeof value === "number"; } const validateAge = (age: any) => { if (isNumber(age)) { // validation logic // ... } else { console.error("The age must be a number"); } }; ``` 注意:在上面的示例中,最好使用: ``` const validateAge = (age: number) => { // ... }; ``` 這個例子是為了展示 **type guards** 是如何工作的一個簡化。 ## 4.索引簽名 當對像中有**動態鍵**時,可以使用**索引簽名**來定義其類型: ``` enum PaticipationStatus { Joined = "JOINED", Left = "LEFT", Pending = "PENDING", } interface ParticipantData { [id: string]: PaticipationStatus; } const participants: ParticipantData = { id1: PaticipationStatus.Joined, id2: PaticipationStatus.Left, id3: PaticipationStatus.Pending, // ... }; ``` ## 5.泛型 **泛型** 是一個強大的工具,可以讓您的程式碼更易於重用。它允許您**定義一個類型,該類型將由您的函數的使用決定**。 在以下示例中,`T` 是通用類型: ``` const clone = <T>(object: T) => { const clonedObject: T = JSON.parse(JSON.stringify(object)); return clonedObject; }; const obj = { a: 1, b: { c: 3, }, }; const obj2 = clone(obj); ``` ## 6. 不可變類型 您可以通過加入 `as const` 使您的類型**不可變**。這確保您不會意外更改值。 ``` const ErrorMessages = { InvalidEmail: "Invalid email", InvalidPassword: "Invalid password", // ... } as const; // This will throw an error ErrorMessages.InvalidEmail = "New error message"; ``` ## 7. 部分、選擇、省略和必需類型 通常在使用 **server** 和 **local data** 時,您需要將一些屬性設置為 **optional** 或 **required**。 而不是使用相同資料的略微更改版本定義數百個接口。您可以使用 `Partial`、`Pick`、`Omit` 和 `Required` 類型來做到這一點。 ``` interface User { name: string; age?: number; email: string; } type PartialUser = Partial<User>; type PickUser = Pick<User, "name" | "age">; type OmitUser = Omit<User, "age">; type RequiredUser = Required<User>; // PartialUser is equivalent to: // interface PartialUser { // name?: string; // age?: number; // email?: string; // } // PickUser is equivalent to: // interface PickUser { // name: string; // age?: number; // } // OmitUser is equivalent to: // interface OmitUser { // name: string; // email: string; // } // RequiredUser is equivalent to: // interface RequiredUser { // name: string; // age: number; // email: string; // } ``` 當然,你可以使用 **intersection** 來組合它們: ``` type A = B & C; ``` 其中 `B` 和 `C` 是任何類型。 --- 謝謝閱讀,希望對您有幫助!

給軟體工程師:50 個好用的 ChatGPT 咒語指令

下列 ChatGPT-4 咒語,對開發者很有幫助。附上原文與中文指令,供您參考。 原文出處:https://dev.to/hackertab_org/50-chat-gpt-prompts-every-software-developer-should-know-tested-9al ### **程式碼生成** - Generate a boilerplate `[language]` code for a `[class/module/component]` named [name] with the following functionality: `[functionality description].` - 為名為 [name] 的 `[class/module/component]` 生成樣板 `[language]` 程式碼,具有以下功能:`[functionality description]。 - Create a [language] function to perform `[operation]` on `[data structure]` with the following inputs: [input variables] and expected output: `[output description]`. - 建立一個 [語言] 函數以使用以下輸入對 `[資料結構]` 執行 `[操作]`:[輸入變數] 和預期輸出:`[輸出描述]`。 - Generate a `[language]` class for a `[domain]` application that includes methods for `[methods list]` and properties `[properties list]`. - 為包含“[方法列表]”的方法和屬性“[屬性列表]”的“[域]”應用程式生成一個“[語言]”類。 - Based on the [design pattern], create a code snippet in [language] that demonstrates its implementation for a [use case]. - 基於[設計模式],用[語言]建立一個程式碼片段,演示其對[用例]的實現。 **例子:** ``` Generate a boilerplate Python code for a shopping cart module named "ShoppingCart" with the following functionality: - A constructor that initializes an empty list to store cart items. - A method called "add_item" that takes in an item object and adds it to the cart. - A method called "remove_item" that takes in an item object and removes it from the cart if it exists. - A method called "get_items" that returns the list of items in the cart. - A method called "get_total" that calculates and returns the total price of all items in the cart. ``` ### **程式碼完成** - In `[language]`, complete the following code snippet that initializes a [data structure] with `[values]`: `[code snippet]`. - 在“[語言]”中,完成以下使用“[值]”初始化[資料結構]的程式碼片段:“[程式碼片段]”。 - Finish the `[language]` function that calculates [desired output] given the following input parameters: `[function signature]`. - 在給定以下輸入參數的情況下完成計算[期望輸出]的[語言]函數:[函數簽名]。 - Complete the `[language]` code to make an API call to `[API endpoint]` with [parameters] and process the response: `[code snippet]`. - 完成“[語言]”程式碼以使用[參數]對“[API 端點]”進行 API 呼叫並處理響應:“[程式碼片段]”。 **Example** : Finish the Python function that calculates the average of a list of numbers given the following input parameters: **示例**:完成計算給定以下輸入參數的數字列表的平均值的 Python 函數: ``` def calculate_average(num_list) ``` ### **錯誤檢測** - Identify any potential bugs in the following [language] code snippet: `[code snippet]`. - 確定以下 [語言] 程式碼片段中的任何潛在錯誤:`[程式碼片段]`。 - Analyze the given [language] code and suggest improvements to prevent [error type]: `[code snippet]`. - 分析給定的[語言]程式碼並提出改進建議以防止[錯誤類型]:`[程式碼片段]`。 - Find any memory leaks in the following [language] code and suggest fixes: `[code snippet]`. - 在以下 [語言] 程式碼中查找任何內存洩漏並提出修復建議:`[程式碼片段]`。 **Example** : Identify any potential bugs in the following Python code snippet: **示例**:辨識以下 Python 程式碼片段中的任何潛在錯誤: ``` def calculate_sum(num_list): sum = 0 for i in range(len(num_list)): sum += num_list[i] return sum ``` ### **程式碼審查** - Review the following `[language]` code for best practices and suggest improvements: `[code snippet]`. - 查看以下“[語言]”程式碼以獲得最佳實踐並提出改進建議:“[程式碼片段]”。 - Analyze the given `[language]` code for adherence to `[coding style guidelines]`: `[code snippet]`. - 分析給定的“[語言]”程式碼是否符合“[編碼風格指南]”:“[程式碼片段]”。 - Check the following [language] code for proper error handling and suggest enhancements: `[code snippet]`. - 檢查以下 [語言] 程式碼以正確處理錯誤並提出改進建議:`[程式碼片段]`。 - Evaluate the modularity and maintainability of the given `[language]` code: `[code snippet]`. - 評估給定“[語言]”程式碼的模塊化和可維護性:“[程式碼片段]”。 **Example** : Review the following Python code for best practices and suggest improvements: **示例**:查看以下 Python 程式碼以獲得最佳實踐並提出改進建議: ``` def multiply_list(lst): result = 1 for num in lst: result *= num return result ``` ### **API 文件生成** - Generate API documentation for the following `[language]` code: `[code snippet]`. - 為以下“[語言]”程式碼生成 API 文件:“[程式碼片段]”。 - Create a concise API reference for the given `[language]` class: `[code snippet]`. - 為給定的“[語言]”類建立簡明的 API 參考:“[程式碼片段]”。 - Generate usage examples for the following `[language]` API: `[code snippet]`. - 為以下“[語言]”API 生成用法示例:“[程式碼片段]”。 **Example** : Generate API documentation for the following JavaScript code: **示例**:為以下 JavaScript 程式碼生成 API 文件: ``` /** * Returns the sum of two numbers. * @param {number} a - The first number to add. * @param {number} b - The second number to add. * @returns {number} The sum of a and b. */ function sum(a, b) { return a + b; } ``` ### **查詢優化** - Optimize the following SQL query for better performance: `[SQL query]`. - 優化以下 SQL 查詢以獲得更好的性能:`[SQL 查詢]`。 - Analyze the given SQL query for any potential bottlenecks: `[SQL query]`. - 分析給定的 SQL 查詢是否存在任何潛在瓶頸:`[SQL 查詢]`。 - Suggest indexing strategies for the following SQL query: `[SQL query]`. - 為以下 SQL 查詢建議索引策略:`[SQL 查詢]`。 - Optimize the following NoSQL query for better performance and resource usage: `[NoSQL query]`. - 優化以下 NoSQL 查詢以獲得更好的性能和資源使用:`[NoSQL 查詢]`。 **Example** : Optimize the following SQL query for better performance: **示例**:優化以下 SQL 查詢以獲得更好的性能: ``` SELECT * FROM orders WHERE order_date BETWEEN '2022-01-01' AND '2022-12-31' ORDER BY order_date DESC LIMIT 100; ``` ### **用戶界面設計** - Generate a UI mockup for a `[web/mobile]` application that focuses on [`user goal or task]`. - 為專注於 [`用戶目標或任務]` 的`[web/mobile]` 應用程式生成 UI 模型。 - Suggest improvements to the existing user interface of `[app or website]` to enhance `[usability, accessibility, or aesthetics]`. - 建議改進“[應用程式或網站]”的現有用戶界面,以增強“[可用性、可存取性或美學]”。 - Design a responsive user interface for a `[web/mobile]` app that adapts to different screen sizes and orientations. - 為適應不同螢幕尺寸和方向的“[web/mobile]”應用程式設計響應式用戶界面。 **Example** : Generate a UI mockup for a mobile application that focuses on managing personal finances. **示例**:為專注於管理個人財務的移動應用程式生成 UI 模型。 ### **自動化測試** - Generate test cases for the following [language] function based on the input parameters and expected output: `[function signature]`. - 根據輸入參數和預期輸出為以下 [語言] 函數生成測試用例:`[函數簽名]`。 - Create a test script for the given [language] code that covers [unit/integration/system] testing: `[code snippet]`. - 為涵蓋[單元/集成/系統]測試的給定[語言]程式碼建立測試腳本:`[程式碼片段]`。 - Generate test data for the following [language] function that tests various edge cases: `[function signature]`. - 為以下測試各種邊緣情況的[語言]函數生成測試資料:`[函數簽名]`。 - Design a testing strategy for a [web/mobile] app that includes [unit, integration, system, and/or performance] testing. - 為 [網絡/移動] 應用程式設計測試策略,包括 [單元、集成、系統和/或性能] 測試。 **Example:** Generate test cases for the following Python function based on the input parameters and expected output: **示例:** 根據輸入參數和預期輸出為以下 Python 函數生成測試用例: ``` def divide(a: float, b: float) -> float: if b == 0: raise ZeroDivisionError('division by zero') return a / b ``` ### **程式碼重構** - Suggest refactoring improvements for the following [language] code to enhance readability and maintainability: `[code snippet]`. - 建議對以下 [語言] 程式碼進行重構改進,以增強可讀性和可維護性:`[程式碼片段]`。 - Identify opportunities to apply [design pattern] in the given [language] code: `[code snippet]`. - 確定在給定的[語言]程式碼中應用[設計模式]的機會:`[程式碼片段]`。 - Optimize the following [language] code for better performance: `[code snippet]`. - 優化以下 [語言] 程式碼以獲得更好的性能:`[程式碼片段]`。 **Example** : Optimize the following Python code for better performance: **示例**:優化以下 Python 程式碼以獲得更好的性能: ``` def find_max(numbers): max_num = numbers[0] for num in numbers: if num > max_num: max_num = num return max_num ``` ### **設計模式建議** - Based on the given [language] code, recommend a suitable design pattern to improve its structure: `[code snippet]`. - 根據給定的[語言]程式碼,推薦合適的設計模式來改進其結構:`[程式碼片段]`。 - Identify opportunities to apply the [design pattern] in the following [language] codebase: `[repository URL or codebase description]`. - 確定在以下 [語言] 程式碼庫中應用 [設計模式] 的機會:`[存儲庫 URL 或程式碼庫描述]`。 - Suggest an alternative design pattern for the given [language] code that may provide additional benefits: `[code snippet]`. - 為可能提供額外好處的給定 [語言] 程式碼建議替代設計模式:`[程式碼片段]`。 **Example:** Based on the given Python code, recommend a suitable design pattern to improve its structure: **例子:** 根據給定的Python程式碼,推薦合適的設計模式來改進其結構: ``` class TotalPriceCalculator: def calculate_total(self, items): pass class NormalTotalPriceCalculator(TotalPriceCalculator): def calculate_total(self, items): total = 0 for item in items: total += item.price * item.quantity return total class DiscountedTotalPriceCalculator(TotalPriceCalculator): def calculate_total(self, items): total = 0 for item in items: total += item.price * item.quantity * 0.9 # apply 10% discount return total class Order: def __init__ (self, items, total_price_calculator): self.items = items self.total_price_calculator = total_price_calculator def calculate_total(self): return self.total_price_calculator.calculate_total(self.items) class Item: def __init__ (self, name, price, quantity): self.name = name self.price = price self.quantity = quantity ``` ### **算法開發** - Suggest an optimal algorithm to solve the following problem: `[problem description]`. - 建議解決以下問題的最佳算法:`[問題描述]`。 - Improve the efficiency of the given algorithm for `[specific use case]`: `[algorithm or pseudocode]`. - 為“[特定用例]”提高給定算法的效率:“[算法或偽程式碼]”。 - Design an algorithm that can handle `[large-scale data or high-throughput]` for `[specific task or operation]`. - 為“[特定任務或操作]”設計一種可以處理“[大規模資料或高吞吐量]”的算法。 - Propose a parallel or distributed version of the following algorithm to improve performance: `[algorithm or pseudocode]`. - 提出以下算法的並行或分佈式版本以提高性能:`[算法或偽程式碼]`。 ### **程式碼翻譯** - Translate the following `[source language]` code to `[target language]`: `[code snippet]`. - 將以下“[源語言]”程式碼翻譯成“[目標語言]”:“[程式碼片段]”。 - Convert the given `[source language]` class or module to `[target language]` while preserving its functionality and structure: `[code snippet]`. - 將給定的“[源語言]”類或模塊轉換為“[目標語言]”,同時保留其功能和結構:“[程式碼片段]”。 - Migrate the following `[source language]` code that uses `[library or framework]` to [target language] with a similar library or framework: `[code snippet]`. - 將以下使用“[庫或框架]”的“[源語言]”程式碼遷移到具有類似庫或框架的“目標語言”:“[程式碼片段]”。 **Example:** Translate the following Python code to JavaScript: **示例:**將以下 Python 程式碼轉換為 JavaScript: ``` def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) ``` ### **個性化學習** - Curate a list of resources to learn `[programming language or technology]` based on my current skill level: `[beginner/intermediate/advanced]`. - 根據我目前的技能水平,策劃學習`[編程語言或技術]`的資源列表:`[初學者/中級/高級]`。 - Recommend a learning path to become proficient in `[specific programming domain or technology]` considering my background in `[existing skills or experience]`. - 考慮到我在“[現有技能或經驗]”方面的背景,推薦精通“[特定編程領域或技術]”的學習路徑。 - Suggest project ideas or coding exercises to practice and improve my skills in `[programming language or technology]`. - 建議專案想法或編碼練習,以練習和提高我在“[編程語言或技術]”方面的技能。 ### **程式碼可視化** - Generate a UML diagram for the following `[language]` code: `[code snippet]`. - 為以下“[語言]”程式碼生成一個 UML 圖:“[程式碼片段]”。 - Create a flowchart or visual representation of the given `[language]` algorithm: `[algorithm or pseudocode]`. - 建立給定“[語言]”算法的流程圖或可視化表示:“[算法或偽程式碼]”。 - Visualize the call graph or dependencies of the following `[language]` code: `[code snippet]`. - 可視化以下“[語言]”程式碼的呼叫圖或依賴關係:“[程式碼片段]”。 **Example** : Generate a UML diagram for the following Java code: **示例**:為以下 Java 程式碼生成 UML 圖: ``` public abstract class Vehicle { private String model; public Vehicle(String model) { this.model = model; } public String getModel() { return model; } public abstract void start(); public abstract void stop(); } public class Car extends Vehicle { public Car(String model) { super(model); } @Override public void start() { System.out.println("Starting car engine"); } @Override public void stop() { System.out.println("Stopping car engine"); } } public class Motorcycle extends Vehicle { public Motorcycle(String model) { super(model); } @Override public void start() { System.out.println("Starting motorcycle engine"); } @Override public void stop() { System.out.println("Stopping motorcycle engine"); } } ``` ### **資料可視化** - Generate a bar chart that represents the following data: `[data or dataset description]`. - 生成代表以下資料的條形圖:`[資料或資料集描述]`。 - Create a line chart that visualizes the trend in the following time series data: `[data or dataset description]`. - 建立一個折線圖,將以下時間序列資料的趨勢可視化:`[資料或資料集描述]`。 - Design a heatmap that represents the correlation between the following variables: `[variable list]`. - 設計一個表示以下變數之間相關性的熱圖:`[變數列表]`。 --- 以上,簡單分享,希望對您有幫助!

給新手工程師的建議:每天工作都在查 ChatGPT 會不會很糟?

給新手工程師的建議:每天工作都在查 ChatGPT 會不會很糟? 看到滿多年輕工程師提問:工作時經常查 ChatGPT,感覺不太踏實,沒關係嗎? 讓我簡單談論一下這件事 --- 首先,讓我們把時間倒回 2000 年代 google 剛出來的時候 當時一定也是這樣,年輕工程師遇到問題狂查 google 資深工程師則覺得 google 可有可無,真的有問題,桌上的工具書大概要翻到第幾頁他也都知道,翻一下不用 10 秒就有答案 時間快轉到今天,年輕工程師遇到問題狂問 ChatGPT 資深工程師則覺得 ChatGPT 可有可無,真的有問題,google 關鍵字怎麼組合、stackoverflow or reddit or 某某技術論壇,找一下不用 10 秒就有答案 --- 新科技的出現,讓一些「死背類型」的任務變得「毫無意義」 比方說現在沒人會去背歷史事件的年份了,因為要用時 google 一下就有 同理,現在的工程師,所用程式語言的某些語法、函式名稱、API 用法,沒背起來,根本沒關係 (不信的話,問問看用 Linux 的工程師,怎麼解壓縮檔案,看看有幾個人可以不查 google 打出指令) ``` tar -xzvf 壓縮檔名稱.tar.gz ``` 所以 AI 的出現,如果讓很多以往工程師視為 knowhow、design pattern、convention 的東西,降格為「死背類型」 那麼這些東西當然不用靠肌肉記憶去記住了,每次遇到就去問 AI 即可 --- 我認為工程師這行業的重點在於,你知道「某些問題在技術上可不可能被解決」、「解決方案的大方向是什麼」、「不同解決方案的成本跟考量分別是什麼」 如果你都知道大方向,但是細節語法常常忘記,那習慣性問 AI 當然沒問題 但如果每次查完,你都是把一大堆你自己根本不知道在幹嘛的程式碼複製貼上,那就很有問題 簡單講,這些新科技「可以減少打字的時間、減少查詢的時間、減少翻閱的時間」 但是「無法減少你學習的時間」 # 結論 所以,用 ChatGPT 沒問題,但是你要知道自己拿到的程式碼,到底實際上在做什麼 這樣用了之後,出問題才能除錯、必要時才能擴充、才能加功能 以上,簡單分享,大家有什麼問題,可以多多提問,我盡量回答

COMPOSER 設計原理與基本用法

相信有在用PHP的朋友近年來常聽到composer這個套件管理工具。 它到底是做什麼用的?又是為了解決什麼問題而存在呢? 要瞭解這個,得先從歷史開始說起...。 # PHP最早讀取套件的方法 初學PHP時,最早會面對的問題之一就是require與include差別何在? require_once與include_once又是什麼? 弄懂這些問題之後,如果不使用framework,直接開發,便常出現類似這樣的code: ``` // whatever.php // 這檔案需要用到幾個類別 require 'xxx_class.php'; require 'yyy_class.php'; require 'zzz_class.php'; // ... ``` 然後在其他檔案會出現: ``` // another.php // 這檔案需要用到幾個類別 require 'yyy_class.php'; require 'zzz_class.php'; // ... ``` 這樣的結果,會產生至少兩個問題: 1. 許多檔案用到同樣幾個class,於是在不同地方都需要載入一次。 2. 當類別多了起來,會顯得很亂、忘記載入時還會出現error。 那麼,不如試試一種懶惰的作法? 寫一個php,負責載入所有類別: ``` // load_everything.php require 'xxx_class.php'; require 'yyy_class.php'; require 'zzz_class.php'; require 'aaa_class.php'; require 'bbb_class.php'; require 'ccc_class.php'; ``` 然後在其他檔案都載入這支檔案即可: ``` require 'load_everything.php' ``` 結果新問題又來了:當類別很多的時候,隨便一個web page都會載入一堆code,吃爆記憶體,怎麼辦呢? # __autoload 為了解決這個問題,PHP 5開始提供__autoload這種俗稱「magic method」的函式。 當你要使用的類別PHP找不到時,它會將類別名稱當成字串丟進這個函式,在PHP噴error投降之前,做最後的嘗試: ```// autoload.php function __autoload($classname) { if ($classname === 'xxx.php'){ $filename = "./". $classname .".php"; include_once($filename); } else if ($classname === 'yyy.php'){ $filename = "./other_library/". $classname .".php"; include_once($filename); } else if ($classname === 'zzz.php'){ $filename = "./my_library/". $classname .".php"; include_once($filename); } // blah } ``` 也因為PHP這種「投降前最後一次嘗試」的行為,有時會讓沒注意到的人困惑「奇怪我的code怎麼跑得動?我根本沒有require啊..」,所以被稱為「magic method」。 如此一來,問題似乎解決了? 可惜還是有小缺點..,就是這個__autoload函式內容會變得很巨大。以上面的例子來說,一下會去根目錄找、一下會去other_library資料夾、一下會去my_library資料夾尋找。在整理檔案的時候,顯得有些混亂。 # spl_autoload_register 於是PHP從5.1.2開始,多提供了一個函式。 可以多寫幾個autoload函式,然後註冊起來,效果跟直接使用__autoload相同。 現在可以針對不同用途的類別,分批autoload了。 ```spl_autoload_register('my_library_loader'); spl_autoload_register('other_library_loader'); spl_autoload_register('basic_loader'); function my_library_loader($classname) { $filename = "./my_library/". $classname .".php"; include_once($filename); } function other_library_loader($classname) { $filename = "./other_library/". $classname .".php"; include_once($filename); } function basic_loader($classname) { $filename = "./". $classname .".php"; include_once($filename); } ``` 每個loader內容可以做很多變化。可以多寫判斷式讓它更智慧、可以進行字串處理...。 自動載入類別的問題終於解決了...。 *但是光上面的code也有15行,而且在每個project一定都會寫類似的東西。有沒有辦法自動產生這15行呢? 我的願望很簡單,我告訴你,反正我有my_library資料夾跟other_library資料夾,你自己進去看到什麼類別就全部載入好不好...?* *阿不對,全部載入剛又說效能不好,那你進去看到什麼就全部想辦法用spl_autoload_register記起來好不好...?* *我懶得打15行了,我只想打這幾個字:* ``` $please_autoload = array( 'my_library', 'other_library'); ``` *可不可以發明一個工具,去吃$please_autoload這個變數,然後自己想辦法載入一切啊...?* *ㄟ等等,我連php程式碼都懶得打了,在web領域JSON格式更簡潔。允許我這樣打,好嗎?* ``` { "autoload": [ "my_library", "other_library" ] } ``` *然後誰來個工具幫我產生一大串autoload相關的php程式碼吧...,可以嗎?* **可以。** # Composer登場 首先,裝好composer(本文不介紹如何安裝。) 再來,建立一個composer.json檔,裏面輸入這些: ``` { "autoload": { "classmap": [ "my_library", "other_library" ] } } ``` 比原本希望的多打了一些字,不過差不多。 再來,在terminal輸入 ``` composer install ``` 執行成功之後,你會看到一個vendor資料夾,內含一個autoload.php。 沒錯,跟你夢想的一樣。你只要載入這個檔案: ``` require 'vendor/autoload.php'; ``` 你需要的所有類別,都會在適當的時候、以適當的方式自動載入。 php再也不會噴error說你「類別尚未定義」了! 這vendor資料夾裏面的一切,都只是php code而已,並沒有特別神奇的地方。只要去看autoload.php的原始碼,就能知道composer到底寫了哪些php code給你。 *ㄟ等等,我寫的類別都放在my_library裏面了,other_library都是網路上copy下來的現成類別。我想要用Google API的Client類別、Doctrine資料庫管理抽象層類別、還有guzzlehttp的發送request類別。* *我連去下載這些檔案、然後丟進這個資料夾都懶得做了,我根本不想手動建立other_library這個資料夾。composer真那麼神...不如連下載都幫我自動下載?可以嗎?* **可以。** 查詢一下那幾個套件在 https://packagist.org/ 的名稱、還有你需要的版本號。 把剛剛的composer.json改成這樣: ``` { "require": { "google/apiclient": "1.0.*@beta", "guzzlehttp/guzzle": "~4.0", "doctrine/dbal": "~2.4" }, "autoload": { "classmap": [ "my_library" ] } } ``` 然後'composer install'指令除了自動載入你的類別之外、還會自動下載你需要的類別、然後自動載入它們。 一樣require 'vendor/autoload.php'就可以了。composer實在是太棒了。 其實composer解決的問題不只這樣。 類別多了起來之後,各種程式語言都提供namespace功能協助分類。 在有namespace的情況下,PHP社群與composer是如何解決自動載入的問題呢? 這些比較進階的內容,下回分曉。

西元 2023 年了,還值得花時間學 Dreamweaver 嗎?簡單分享幾個觀點

首先我們來看 google trend ![](https://i.imgur.com/GwTUmvo.png) https://trends.google.com.tw/trends/explore?date=all&geo=TW&q=dreamweaver&hl=zh-TW 如你所見 這是一個過時的技術、正在被人們拋棄 接著請到 google 搜尋 `dreamweaver 職缺` 會發現其實 還是有些職缺要求要會 dreamweaver 這些職缺的待遇、工作內容 都在各大人力資源網站 你可以自行判斷:這些是不是你求職的目標職缺、理想職缺 --- 再來是我個人經驗,我這十年職場所見所聞,沒有遇過公司在用 Dreamweaver 我在社群認識各類工程師,也沒聽過有人在用這工具 不得不說 這實在是一個很老派的工具 唯一有次在業界遇到 好像有人在用的情境 是一間接案公司 以快速、便宜為主打 他們當時需要有人能用低價、快速的方式 把大量網頁切出來 後來找到的配合的人 好像就是用 Dreamweaver 在切版 --- 如果對 Dreamweaver 有興趣、好奇 我覺得多學一個工具 也不是壞事 對於之後再學其它工具 也是會有幫助 但是 應該沒必要花時間「專精」或者「鑽研」這樣一個老舊的工具 如果課程要求 或是有證照需求 那評估一下需要花費的時間 如果證照沒那麼難考 那花點時間 拿個證照 也滿好的 還能培養一些自信 如果履歷表還沒什麼東西能放 那放個證照也不錯 但如果考那證照很花錢、很花時間 那請審慎思考一下這投資值不值得 我是不推薦 我感覺只是培養快速、低成本切版網頁的能力 這能力頂多在接案公司會有幫助 而且還不會是很精緻的接案公司 不如花時間深入研究 JavaScript 基本功,對前端職涯更有幫助,而不只是專精於切版而已 --- 以上 簡單個人觀點分享

後端 JS 訓練一:第3課 ── 用 node 寫入檔案內容

## 課程目標 - 用 node 寫入檔案內容 ## 課程內容 來學習一下用 node 寫入檔案的方法 學會這方法,可以用 node 寫腳本處理工作上的文書瑣事 --- 建立 `write-my-name.js` 程式,裡面輸入 ``` var fs = require('fs'); const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout }); readline.question('請問您的大名?\n', function (answer) { fs.writeFile('my-name.txt', answer, function (err) { console.log('儲存成功。'); process.exit(0); }); }); ``` 然後去終端機輸入 ``` node write-my-name.js ``` 你會看到終端機要求你輸入內容,接著會去更新文字檔內容! --- 第一段的 `readline` 模組,是處理 `輸入/輸出` 資訊的模組,後面要呼叫 `createInterface` 並且用全域變數 `process` 來設定輸入、輸出來源 照做就好,背後意義不用細究,能用就好,有興趣自行 google `readline.question` 從終端機請求用戶輸入內容,`\n` 是換行字元,讓畫面更好看而已 注意 `readline.question` 後面還是把函式當參數傳,也就是依然採用「非同步程式設計」 很怪、很醜,對嗎?我同意,這語法設計實在意義不明 又不是在等待 AJAX 回應的同時,用戶可以先做別的事情 這邊就是要等用戶輸入完內容,程式往下走才有意義呀! 後面會教你如何改寫成「同步程式設計」,先照做就好 ## 課後作業 接續前一課的作業,現在來寫「新增」功能 請建立一個 `create.js` 檔案 使用者輸入 `node create.js` 之後,終端機會詢問 ``` 您要新增什麼待辦事項? ``` 使用者可以輸入內容,接著終端機會顯示 ``` 新增事項:XXXXXX ``` 打開 `todos.json` 查看,會看到剛剛輸入的項目出現在裡面 完成以上任務,你就完成這次的課程目標了!

寫程式不需要天份,也不需要熱情

這是我 2015 年寫的文章,當時在學界、業界評價兩極,也引起很多人痛罵 多年後回頭看,我的觀點不變。文章滿適合這個論壇的,我順手轉發一下 --- 從來沒有一個技能,曾經被神化到這個程度: 「你不但要有天份,還要有熱情,才適合寫程式。」 那些寫程式的人,好像「從小就立定志向,決定未來要寫程式了」。 缺乏其一的話,你要嘛是個假貨,要嘛走不遠,總之就是不適合。 這種深植人心的刻板印象不但大錯特錯,同時還是有害的。 隨便找幾個工程師都能證明這點。 # Jacob Kaplan-Moss(Django創造者) Jacob Kaplan-Moss的這份簡報提到: [一個平庸工程師的自白](http://www.inside.com.tw/2015/06/12/i-am-a-mediocre-programmer) > 這種關於「程式天才」的神話非常有害,一方面它把行業門檻設置得特別高,令很多人望而卻步,另一方面它也在折磨產業內的人,因為你如果不能 rocks ,就會變成 sucks ,所以不得不用一切時間來努力學習和工作,導致影響生活。…(略)…我們應該改變這種態度,寫程式只是一些技能,並不需要太多天分,它是可以學習的,而且做一個平庸的工程師不丟人, 他本人在[Twitter的自介](https://twitter.com/jacobian)直接寫「不是真的程式設計師(not a real programmer)」, 透漏著他對這種迷思的不耐煩。 # Jacob Thornton(Bootstrap作者) 在Github擁有八萬顆星的Bootstrap作者, 前Twitter、現任Medium工程師Jacob Thornton的一篇採訪也是這種迷思的反例: [Jacob Thornton痛恨電腦(Jacob Thornton Hates Computers)](https://medium.com/@verbagetruck/jacob-thornton-hates-computers-5c64f164ee07) > 當他說「我痛恨電腦」的時候,並不完全在開玩笑。…(略)…他說「我本來要去唸社會學的」 接著描述了他第一份工作的情況: > 我拿到了一個遠超我能力的工作。每一天都可能被開除。所以我非常努力工作,想搞懂JavaScript,因為我不懂它到底在幹嘛。 > 我一生中最現實的一刻到了。整間公司的人圍在我身邊,要我做一個XHR request。我根本沒做過,我只稍微聽過而已。於是我開始打字、重新整理瀏覽器,然後什麼都沒出來。我反覆做了幾次,知道自己完蛋了,他們發現我是假貨了。接著我突然發現自己忘記加「.send()」。我加了之後再次重新整理瀏覽器,畫面成功顯示。整個團隊感覺像在說「喔,酷。」然後就各自回辦公桌了。 > 我在那裡坐了15分鐘。心想,就這樣。我搞定了。我不會被開除了。 這段描述一點也不像「程式天才」在職場的表現。 至於支持他一路走來的動機是什麼呢?他說: > 我是一個高度在乎同儕的人,我做前端的朋友總是會告訴我哪個地方做很醜或是在哪個瀏覽器上壞掉。感覺真的很棒。我真的只想跟朋友一起寫程式,一起工作。 [他本人的Twitter](https://twitter.com/fat)自介寫「computer loser」, 置頂推文是「公司裡第一爛的工程師,但是第三酷」。 這種態度跟刻板印象完全相反。 # Rasmus Lerdorf(PHP之父) Rasmus Lerdorf的[言論](https://en.wikiquote.org/wiki/Rasmus_Lerdorf)常常引起廣泛爭議: - 我其實很討厭寫程式,不過我喜歡解決問題。 - 有些人熱愛寫程式。我不懂他們為何會這樣。 - 我不是一個真的工程師。我把東西弄一弄,弄到能跑之後就不管了。真的工程師會說「這段程式能跑,但記憶體沒管理好,我們來修好它」。我只會說,一直重新開機不就好了。 從他的言論,很難看出他對電腦本身有多少熱情。 他也跟Jacob Kaplan-Moss以及Jacob Thornton一樣,懶得對寫程式的迷思多做解釋, 乾脆直接說自己是loser、假工程師了。 # David Heinemeier Hansson(Rails之父) DHH在接受[Big Think訪問](http://bigthink.com/videos/big-think-interview-with-david-heinemeier-hansson)時提到: > 說來有點好笑。我以前寫PHP跟Java的時候,常常花時間去摸其他程式語言。到處摸看看其他程式語言…隨便什麼都好。寫PHP跟Java實在太悶了,我需要用這種方式讓自己暫時抽離。 > 我以前寫PHP跟Java的時候,完全不覺得自己之後會當程式設計師。 整段看起來都不像是一個「電腦天才」的自我介紹。 最後讓他愛上的不是電腦本身,而是Ruby程式語言的優雅性。 如果Ruby沒有被發明,DHH現在也許會做完全不同的事情。 --- 這一類可以說明刻板印象大錯特錯的文章實在太多了, 看看工程師們最愛的幾個玩笑:[關於工程師 59 條搞笑但卻真實無比的語錄](http://www.inside.com.tw/2013/12/20/59-hilarious-but-true-programming-quotes-for-software-developers) - 一個人寫的爛軟體將會給另一個人帶來一份全職工作。 - 傻瓜都能寫出電腦能理解的程式,優秀的工程師寫出的是人類能讀懂的程式。 - 開發軟體和建造教堂非常相似——完工之後我們就開始祈禱。 如果工程師都很有天份跟熱情,這些笑話又怎會受歡迎呢。 再看看Medium上很受歡迎的學習系列文章:[資深開發者給後輩的七個 Coding 學習心得](http://buzzorange.com/techorange/2013/11/29/wish-someone-had-told-me-when-learn-coding/) 其中的幾個建議 - 也許常常有人說你是錯的 - 也許常常會有人跟你說「你並不是個 Coder」 - 不要在意外表,能力才是一切 無非就是想打破這類寫程式的迷思、無意義的資格論神話。 下次又有人學到一半,開始反省自己適不適合、夠不夠資格的時候, 我只想跟他說:你就多找幾種方式學學看吧,不要抱持那種奇怪的資格論。 很多時候其實只是[搞錯方法](http://blog.turn.tw/?p=1283)、[搞錯心態](http://blog.turn.tw/?p=2568)而已。 真的完全學不懂再放棄吧。 寫程式不需要天份,也不需要熱情。 (Photo via Sano Rin, CC licensed.)

未來 ChatGPT 會取代軟體工程師嗎?你完全不需要擔心這個

最近看到滿多年輕學生、考慮轉職者提問:未來 ChatGPT 會取代軟體工程師嗎? 看來這個議題已經造成不少 IT 領域學生的焦慮,我非常驚訝,讓我簡單談論一下這件事 # 個人經驗回顧 我在畢業前全心學習 web 前端與後端開發,2012 年畢業時,正逢智慧型手機快速發展,所有公司都在思考如何開發手機 app 來創造新機會,當時媒體的主要論述是:「web 已死!web 工程師都將失業,未來是 mobile app 的世界!」 當時年輕的我,看到這些媒體這樣分析,也是有點焦慮,但同時又有點不服氣,所以依然 100% 心思在研究 web 開發,不管媒體怎麼看衰。現在,10 年過去了,請問 web 職缺消失了嗎? # 媒體的習慣、網紅 YTer 的習慣 想像你住在一個非常小的島嶼國家上,往外走一下就看到海,國家全年365天基本沒什麼大事,每天就是太陽升起、太陽落下。如果你是島上的「新聞從業人員」,請問你每天能做什麼?你當然只能誇大你看到的每件事情。 看到海水漲潮,發新聞:「海水異常上漲!恐有釀禍危機!全國一半人口恐有水災、死亡風險!」 看到海水退潮,發新聞:「近三年最低點!海水不斷消退、國家水資源流失、重大警訊!我國恐成大型沙漠!」 世界上大多數事情本就「帶有波動性」,一下狀況好一下狀況壞,潮起又潮落,正如月有陰晴圓缺,這相當正常。 媒體、網紅,基本上需要吸引人們關注來過活,他總不能每天發新聞:「今天海水正常漲潮,沒什麼特別的。」、「今天海水退潮了,這很自然,不太重要。」 身為現代公民,你要有能力透過媒體吸收新知,但同時也要有能力保持冷靜、自行判斷,不要隨意被影響。你要能看出各種觀點背後相關的利益。 # AI 對職缺的影響 AI 當然對各行各業會有重大衝擊,但是目前也僅止於改善工作效率、優化流程而已。 AI 因為可以加強專業人員的生產力,所以會造成職缺變少一點,但要到「軟體工程師通通失業」、「就靠機器人寫完所有程式」這種程度,實在太誇大了 最後,程式設計已經是各種工作領域之中,最難被機器取代的職缺之一,如果真的被高階人工智能取代,那社會上已經沒有多少工作適合人做,大概會是「無條件基本收入」制度之類的社會 --- # 結論 太廢的技能、感覺問 google 或問 ChatGPT 就有的東西,可以不用學了,像死背課文一樣的任務再也不用做了 除此之外,該學什麼學什麼,不用想太多 上個時代,懂得善用 google 與網際網路的專業人士 vs 不懂得善用的專業人士,生產力有巨大差別 下個時代,懂得善用 AI 的專業人士 vs 不懂得善用的專業人士,生產力有巨大差別 除此之外,跟案主溝通、釐清功能規格、分析各種技術選擇、認識領域知識並設計軟體,是極度複雜的工作,你真的覺得一個機器人放在面前聊天幾分鐘,它就能通通做完給你? --- 以上,簡單看法分享