🔍 搜尋結果:第一

🔍 搜尋結果:第一

工程師就業市場也太慘了🤯 分享 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

用 React 和 Node.js 建立 GPT Web 應用程式產生器 - 在 4 個月內,從點子到 25,000 個應用程式

我們正在開發 [Wasp](https://github.com/wasp-lang/wasp) - 一個基於 React、Node.js 和 Prisma 建置的全端 Web 框架。自從 GPT 出現以來,我們想知道是否可以使用它來更快地建立 Web 應用程式。這讓我們想到了 [MAGE - 一個由 GPT 驅動的 Web 應用程式產生器](https://usemage.ai/),它可以根據簡短的描述建立完整的堆疊程式碼庫。 我們已經寫過[MAGE 可以(和不能)做什麼](https://dev.to/wasp/gpt-web-app-generator-let-ai-create-a-full-stack-react-nodejs-codebase-based-on-your-description-2g39)和[它在幕後的工作原理](https://wasp-lang.dev/blog/2023/07/17/how-we-built-gpt-web-app-generator)。這是關於它的起源和採用的故事 - 為什麼我們決定建立它,開發人員如何發現它,以及他們實際上用它做什麼。 ## 為什麼要建構另一個 AI 編碼代理? 我們很晚才進入整個 GPT 編碼代理遊戲。在我們開始考慮建立自己的工具之前,Smol AI、GPT Engineer 和 MetaGPT 等工具就已經受到了廣泛的關注,我們對此也很清楚。 ![編碼代理景觀](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zw6vyjt79bxrsyvdhl78.png) 那為什麼還要麻煩呢?事實是,這些代理程式都不是專門為建立 Web 應用程式而設計的,而這正是我們看到機會的地方。 儘管使用 GPT 代理進行編碼可以讓人感覺超級強大,但它們通常會很慢並且沒有抓住要點,需要多次迭代,最終使該過程相當麻煩且昂貴。 有了這些經驗,我們想知道,*「如果我們為特定堆疊中的 Web 應用程式製作一個高度專業化的編碼代理,而不做其他事情會怎麼樣?它能變得更容易、更快、更便宜嗎?」* 儘管我們對此很感興趣,但作為一個兼顧多個優先事項的小團隊,我們仍然相當懷疑,幾乎放棄了整個專案。事實證明,它的效果比我們預期的還要好。 ## 第 1 步:建造它🛠️ ![運作方式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lkqk1i0p311u9zd9ouk6.png) 在決定 MAGE(*Magic App Generator*)的 v0 版本時,我們考慮了多種選擇。第一個也是最直接的一個是將其與 Wasp CLI 集成,因為我們已經擁有了圍繞它的所有工具。然後,開發人員將執行“wasp new myProject -ai”,而不是執行“wasp new myProject -ai”,CLI 會要求他們提供應用程式描述和其他所需的輸入,然後在終端中完成所有工作。 另一方面,我們知道在開始描述您的應用程式之前下載並安裝 Wasp 是一個很大的要求。最重要的是,CLI 中的使用者介面功能非常有限。這就是我們選擇網路介面的原因 - 零摩擦開始,我們可以讓應用程式建立流程變得非常簡單且美觀。 花了幾週的時間來建構它,最終的結果是一個[用Wasp 製作的完全開源的Web 應用程式](https://github.com/wasp-lang/wasp/tree/wasp-ai/wasp-ai)可以在 https://usemage.ai/ 上免費使用,或在本地託管以獲得更多控制和靈活性(例如,使用您自己的 OpenAI API 金鑰)。 ### 超級具體(僅限網頁應用程式)得到了回報! ![法師計畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xqkrqj8b3we67ufxl8gm.png) 如上所述,我們的主要賭注是建立一個專門的編碼代理來建立全端 Web 應用程式,而不是其他任何東西,這得到了回報。它使我們能夠預先為代理提供大量上下文和結構,並引入專門的啟發式方法來修復錯誤。此外,由於 Wasp 的高級抽象(例如身份驗證、專案結構、查詢和作業系統等),我們顯著減少了錯誤的表面積。 另一個結果是執行時間顯著減少,甚至更重要的是成本減少。典型的MAGE 建立的Web 應用程式成本在0.10 至0.20 美元之間,而一般編碼代理[同一應用程式的花費可能高達10 美元](https://wasp-lang.dev/blog/2023/08/01/smol-ai-vs-wasp-ai#thoughts--further-considerations)(所有價格均在 OpenAI 23 年 11 月 7 日定價更新公告之前)。 您可以閱讀有關Wasp 內部工作原理的更多資訊[此處](https://wasp-lang.dev/blog/2023/07/17/how-we-built-gpt-web-app-generator),以及它的比較其他編碼代理[此處](https://wasp-lang.dev/blog/2023/07/17/how-we-built-gpt-web-app-generator)。 ## 第 2 步:啟動它🚀 ![圖表](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/icff70qgd5ozu23ghgw7.png) 開發產品是一回事,但傳播產品並讓人們使用它則完全是另一回事。在我們建立了 MAGE 並在團隊內對其進行了測試之後,問題是下一步該做什麼?我們如何真正聯繫開發人員並開始接收回饋? ### 社區啟動 - 生命的證明 ![waspularity](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwcmspqyer7hxjysjyjo.png) 由於當時我們已經擁有一個[擁有大約 1,000 名成員的 Wasp 社區](https://discord.gg/rzdnErX),因此我們[發布了 MAGE 作為我們發布週 #3 的一部分](https://wasp-lang.dev/blog/2023/06/22/wasp-launch-week-third#gpt-web-app-generator--friday-waspularity---tutorial-o-thon)。這是一個很好的測試平台,我們可以看到第一個應用程式正在建置。儘管如此,更多的開發人員本可以從更簡單的方式來啟動他們的 React 和 Node.js 專案中受益,但他們卻無法找到 MAGE。 ### 啟動 Product Hunt — 首次「真正」使用 ![mage-ph](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3z5dkjuxn8502699s5a.png) 這就是為什麼我們決定在內部社群啟動後將 MAGE 放在 Product Hunt 上。儘管Product Hunt 不是一個特定於開發工具的平台,並且吸引了來自不同背景的人群,但仍然有很多開發人員在使用它,而且我們[之前有很好的經驗](https://www.producthunt.com/products/wasp-lang-alpha/launches) 與它。 Product Hunt 對於[獲得Wasp 的第一批用戶並在GitHub 上獲得1,000 顆星](https://wasp-lang.dev/blog/2022/09/29/journey-to-1000-gh-stars) 至關重要,因此我們想再試一次。 有些人在發布準備工作上投入了大量精力,需要提前幾個月才能準備好,但我們沒有那個時間,只是想盡快完成。我們要求我們的朋友和社區查看 [MAGE on Product Hunt](https://www.producthunt.com/products/wasp-lang-alpha#gpt-webapp-generator-for-react-node-js) 並提供支持我們在發布當天就進入了當天的前十名產品,後來又躋身本週排名第二的開發者工具! 這就是我們的目標,因為排名前十的產品最終會出現在第二天的電子報中,有超過 100 萬訂閱者閱讀。很快,我們看到建立的應用程式數量顯著增加,新的人開始加入我們的 Discord 社群! ### 有機成長(又稱「無所事事」)階段 在 Product Hunt 推出後,我們放鬆了行銷工作,因為其他與 Wasp 相關的任務趕上了團隊。我們必須為即將到來的[發布週#4](https://wasp-lang.dev/blog/2023/10/13/wasp-launch-week-four)做準備,所以 MAGE 最終被擱置了。在我們決定投入更多資源之前,我們也想看看社區如何接受它。 我們發布了更多後續文章,「[它是如何在後台工作的](https://wasp-lang.dev/blog/2023/07/17/how-we-built-gpt-web-app-generator)”和“[MAGE vs. 一般編碼代理](https://wasp-lang.dev/blog/2023/08/01/smol-ai-vs-wasp-ai)”,獲得平均數量牽引力,但沒有爆炸。我們在 Reddit 和 Hackernews 上也沒有什麼成功,感覺社群已經厭倦了所有的人工智慧內容。 儘管如此,使用 MAGE 建立的應用程式數量持續增長(約 200 個應用程式/天),偶爾會出現小規模爆炸。我們無法真正追蹤用戶來自哪裡 - MAGE 似乎是透過封閉社區和時事通訊中的口碑傳播的。 ### YouTube 和 TikTok 影片 - 病毒式傳播(每天 1,300 個應用程式!) 在我們的第 4 週發布週結束後,我們意識到,在近 2 個月的時間裡,在我們付出最小努力的情況下,MAGE 一直在不斷成長。這向我們表明它具有一定的實際價值,因此我們決定對其進行更多投資。 ![matt_yt_video](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sztjfowul34w6uqwzb56.png) 我們決定與該領域的影響者碰碰運氣。我們不想簡單地支付廣告費用,而是希望與真正對我們正在建立的產品感興趣並且想要客觀地審查 MAGE 的人合作。我們發現 [Matthew Berman](https://www.youtube.com/watch?v=KQrGu8cnwvA&t=2s&ab_channel=MatthewBerman) 涵蓋了 LLM 領域從最新模型到工具的所有內容,他將 MAGE 視為非常適合他的觀眾。 該影片在幾週內就準備好了,當它發佈時,觀看次數很快就達到了約 25,000 次。許多觀眾對透過 Web 介面從單一提示中獲取全端程式碼庫的可能性感到興奮,我們看到使用率和開發人員再次嘗試。 ![tiktok_video](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cnfmgt026dvf5yn0a9sm.png) 大約一周後,我們看到建立的應用程式數量再次大幅增加,但無法弄清楚它來自哪裡。我們做了一些搜尋,在TikTok 上找到了一位開發者@techfren,他製作了[一個關於它的短影片](https://www.tiktok.com/@techfren/video/7288306291733269778)(MAGE 甚至最終無法在就是那個!),一天之內瀏覽量猛增至 20 萬次,並迅速走紅。如今,它的瀏覽量已接近 100 萬。 ## 現實 - 所有這些應用程式會發生什麼? 儘管 25,000 個建立的應用程式聽起來令人印象深刻,但退後一步並進一步細分是很好的。 與大多數人工智慧驅動的編碼工具一樣,想要建立自己產品的開發人員和非開發人員都對該領域抱持極大的興趣和好奇心。許多人甚至沒有想要建立的具體專案,但他們熱衷於嘗試一下,看看它是如何運作的。此外,由於法學碩士不是確定性的,因此還沒有任何工具能夠完美執行,並且經常會出現需要手動幹預和編碼知識的小錯誤。 雖然我們對此非常明確(https://wasp-lang.dev/blog/2023/07/10/gpt-web-app-generator#what-kind-of-apps-can-i-build-with-it )和其他[挑戰](https://wasp-lang.dev/blog/2023/07/10/gpt-web-app-generator#challenges)GPT驅動的工具面臨,MAGE仍然吸引了一部分的用戶對建置自己的產品感到興奮,但不精通編碼,需要幫助下載、執行和修復應用程式。另一方面,它是一種非常友好且易於參與 Web 開發和編碼的方式。我們不會阻止非編碼人員嘗試,而是盡可能透明地管理期望。 因此,大約 40% 的所有建立的應用程式都會下載並在本地執行。 ## 結論 事實證明,我們對 MAGE 的實驗非常成功,甚至超越了我們最初的預期。除了許多現有的通用編碼代理之外,高度專業化和結構化的方法可以以低廉的價格產生更好、更一致的結果。 此外,開發人員對啟動全端應用程式的簡單方法(其中包含最佳實踐)感到興奮,並且正在積極尋找這樣的解決方案並在彼此之間共享。 我預計人工智慧輔助的 SaaS 新創公司將成為 Web 開發的未來。如果有人可以使用已經為其應用程式定制的資料模型和 CRUD 邏輯來建立他們的應用程式,那麼為什麼有人會使用通用樣板啟動器呢?另一個問題是誰以及如何具體實現這一點,但我預計未來每個主流框架都會有一個。 ## 祝你好運! 我希望這篇概述對您有所幫助,並讓您了解建立和行銷新的(人工智慧驅動的)開發工具時幕後的情況。請記住,這是我們獨特的經歷,每個故事都是不同的,因此對一切都持保留態度,只選擇對您和您的產品有意義的內容。 我們祝您好運,如果您有任何疑問或想了解 [MAGE](https://usemage.ai/) 和 [Wasp](https://github.com/wasp-lang/wasp)! --- 原文出處:https://dev.to/wasp/how-we-built-a-gpt-web-app-generator-for-react-nodejs-from-idea-to-25000-apps-in-4-months-1aol

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

如何寫文章:與世界分享您的知識!

分享書面知識是掌握特定主題的好方法,也是改善社區中思想組織、溝通和明顯自我推銷的好方法。這種技術和社會文章的製作對於寫作者和閱讀者來說都非常重要,永遠記住:「你今天比那些昨天開始的人知道的更多」。 ## 費曼方法以及為什麼要製作內容 首先,我們需要討論為什麼我們應該分享內容,無論是文字格式(本文的重點)還是任何其他格式。為了開始這個討論,重要的是要了解費曼的方法是什麼,以及它如何幫助我們自信和掌握該學科,從而將學習效果提高 10 倍。 費曼方法是由一位非常重要的物理學家理查德·費曼建立的,目的是開發一種新的學習方法,這個新提議假設了一個核心事實:「如果你不能清楚、簡單地解釋某件事,那麼你就還不算搞懂這件事」 這句話有助於我們思考我們的學習應該如何建置,因為從我們開始考慮教授我們正在學習的內容的那一刻起,我們就更加專注於掌握該學科的基本基礎,並為迫使你學習的疑慮做好準備。另一方面,看起來問題完全不同。 當為此類情況做準備時,明顯的結果是對所研究的主題有極大的信心和掌握。 我特別喜歡這種方法,唯一的問題是,當我們離開學術環境時,很難找到對你現在正在學習的同一學科感興趣的人,要么因為你的學校裡沒有IT人。友誼週期或僅僅因為對特定主題有興趣。 對於這個問題我們有一個非常不可思議的解決方案,叫做「公共學習」!這種做法包括在技術社群線上分享您的學習內容,無論是製作影片、進行直播還是本文的目標:寫作! 像 dev.to 這樣的平台(您現在正在使用它閱讀:D)旨在使「公共學習」的想法變得越來越簡單,並且更接近那些正在消費的人,因為現在可以製作能夠達到的文章與我們有相同興趣的人可以:學習、回答問題甚至提出改變和正確的想法。難以置信,對吧? ## 收集想法並激勵自己寫作 ![寫迷因](https://github.com/cherryramatisdev/public_zet/assets/86631177/66b243e4-5d12-4901-929f-d458db2b6fe0) 靈感過程可能是在線撰寫文章之前最煩人的階段之一,我們經常陷入瘋狂技術的無限循環中以提出令人難以置信的想法,而事實上,解決方案最終非常簡單:接受你的想法並消費它們,盡可能多的內容。 尋找想法並建立自己的語言的最實用方法是閱讀其他人已經就您感興趣的主題發表的文章,無論是程式語言還是特定的 IT 主題等;這種內容消費來自許多不同的來源,例如技術文章、YouTube 影片、科技泡沫推文、Github 討論和許多其他可能的地方。 嗯,我知道這樣說似乎簡化了一些不簡單的事情,我同意你的觀點!不僅僅是閱讀或觀看網路上存在的所有內容才能使我們有能力製作相同的內容,使這些人脫穎而出的最重要技能是**組織到達大腦的想法**。 ### 維護第二個大腦 我們的大腦是一個優秀的資訊吸收機器,實際上是一塊儲存我們周圍所有資訊的海綿。這台機器的一個大問題是,隨著時間的推移,它在組織方面變得很糟糕,這主要是為了節省能源,因為我們不需要一直記住一切,但知道我們可以做什麼來將我們想要的資訊儲存在一個機器中。組織方式?好吧,好吧,年輕的蚱蜢,我們當然需要停止相信我們的大腦! 維護「第二個大腦」是作家和研究人員中非常著名的做法,它由一個物理或虛擬位置組成,您可以在其中複製您所消耗的小塊內容以及使用您自己的話對該主題進行的觀察。這堆筆記將構成您的“第二個大腦”,並使您能夠快速找到任何內容並參考其作者,而不會忘記任何內容! 長話短說,消耗盡可能多的內容,將其儲存在可以儲存和搜尋的第二個大腦中,最後挑戰自己寫作!無論是您想學習的主題、您最近學到的特定內容,還是您已經掌握多年的內容。 ## 了解平台並找到自己的語言 了解我們透過撰寫內容要接觸的平台和受眾非常重要,這樣我們就可以過濾我們將如何建立文章的整體結構,對嗎?在*我看來*,[dev.to](https://dev.to) 是一個非常非正式的平台,它重視大量以教程形式呈現的內容,具有對話風格並且開門見山,以此通過這些訊息,我們可以推斷出一些建立文章的方法,以便我們可以用讀者已知的模型來說明我們的想法。 這是否意味著您將製作的所有內容都是簡單、非正式的教學?決不!這只是意味著你可以塑造你的內容來包含這種更非正式、對話和直接的語言,即使所涵蓋的主題非常複雜,這甚至成為簡化複雜性的一個非常有趣的挑戰。 > 簡化複雜問題的能力將伴隨您的餘生,建立類比和範例以促進理解和辨識所提出的問題和建議的解決方案非常重要。 ## 學習 Markdown 和良好格式設定的一般技巧 我們在dev.to 上製作文章的方式是使用一種稱為[Markdown](https://www.markdownguide.org) 的標記語言(與HTML 完全相同),雖然它非常簡單,但重要的是要有一個當我們談論組織並使文字美觀時,我們可以做很多事情,類似於我們如何在 Microsoft Word 中產生複雜的結構,我們應該能夠使用 Markdown 程式碼產生相同的結構。 強調結構良好的教育材料的重要性始終很重要(畢竟,您正在閱讀這篇文章正是因為這個原因,對吧?),當談到卓越和品質時,我不能不推薦 [4noobs](https://github.com/he4rt/4noobs),它在一個存儲庫中匯集了有關各種IT 主題的多個免費課程和文本格式,對於本文的主題,我建議使用[markdown4noobs](https://github.com/jpaulohe4rt/markdown4noobs )學習 Markdown 標記語言。 ### 文字操作和程式碼區塊的基礎知識 Markdown 讓我們可以使用超級基本和必要的結構來標記文字的各個部分,例如粗體、斜體、突出顯示、標題層級等。下面我們將快速了解如何使用正確的語法執行每個操作。 ``` # Primeiro titulo equivalente a um h1 ## Segundo titulo equivalente a um h2 ### Terceiro titulo equivalente a um h3 #### Quarto titulo equivalente a um h4 `Texto em highlight` **Texto em negrito** *Texto em itálico* ``` Markdown 語言的這些技巧使我們能夠以自己喜歡的方式控制敘述並使閱讀更容易理解,在文本中間使用**粗體**來吸引註意力,使用突出顯示甚至使用突出顯示來明確“技術術語”說明性圖像介紹了段落的要點,同時使文字的整體氛圍更易於閱讀。 另一個值得一提的重要事情是我上面使用的特定區塊,它在編寫技術文章時非常有用,因為它允許更多地突出顯示文字區塊,並且它允許您在編寫程式碼區塊時啟用語法突出顯示,它的使用方式如下: > 免責聲明:由於 markdown 不允許區塊內有區塊,所以我選擇用截圖來展示: ![程式碼區塊](https://github.com/cherryramatisdev/public_zet/assets/86631177/61de98aa-e7bb-4baa-91c4-afca9db2991f) 在「反引號」符號之後,我們可以包含語言的名稱(在我的例子中為 ruby),以便 dev.to 可以啟用特定於該程式語言的語法突出顯示。 ### 目錄 如果您的文章超過兩千字邊距或至少有 4 個主要標題,我強烈建議您定義一個「目錄」或「目錄」。目錄用於指導閱讀本文將要介紹的要點。要建立一個目錄,我將在下面示範一些技巧: #### 在 dev.to 平台上,使用無序列表而不是編號列表 Markdown 中的清單使用起來非常簡單,它們有兩種**主要**類型:無序和編號。 ``` - Uma lista - Não - Ordenada 1. Uma lista 2. Numerada 3. Aqui ``` 在 dev.to 中使用編號列表的問題是它們沒有對齊,正如我們在下面的範例中看到的那樣,所以我通常不建議使用它們,我總是嘗試使用無序列表,如果有必要應用一些順序,在手動未排序的列表符號後使用數字。 ![清單沒有 dev.to](https://github.com/cherryramatisdev/public_zet/assets/86631177/0ab1a9c1-efb3-40d5-b90f-7cacb7d20f77) #### 如何組織標題的連結 假設您已經了解如何在 Markdown 中建立連結(因為您閱讀了 markdown4noobs,對吧?),讓我們學習在標題中指示連結的簡單技巧以及如何建立目錄。 目錄範例如下: ``` ## Table of contents - [What is metaprogramming anyway?](#what-is-metaprogramming-anyway) - [In ruby everything is an object, what does that mean?](#in-ruby-everything-is-an-object-what-does-that-mean) - [But what about rails? How this framework applies that concept for maximum developer experience](#but-what-about-rails-how-this-framework-applies-that-concept-for-maximum-developer-experience) - [How to define methods dynamically](#how-to-define-methods-dynamically) - [Using hooks to detect moments on the instantiation of the class](#using-hooks-to-detect-moments-on-the-instantiation-of-the-class) - [Conclusion](#conclusion) ``` 正如您所看到的,定義連結第二部分的總體思路是在標題旁邊以特定格式包含一個主題標籤“#”,遵循以下規則: - 用連字號「-」取代所有空格 - 將整個標題保留為小寫 就是這樣!帶有重音符號的標題可以保持不變,沒有任何問題,Markdown 理解相同的標準文本,如下所示: ``` - [Um título com muitos acentos e çedilha](#um-título-com-muitos-acentos-e-çedilha) ``` ## 技術文章的基本結構 現在我們對如何標記文字以使其清晰易讀有了一個有趣的想法,讓我們了解文章的結構。需要強調的是,模型並不適用於所有可能的文本類型,其想法是提供一個必須根據上下文進行調整和更改的整體想法。 首先,定義開頭段落以吸引讀者了解您將在整篇文章中剖析的問題或情況非常重要,這樣做很重要,因為第一段將由 dev.to 用於 e-行銷傳播、電子郵件或社交媒體。開頭段落的範例可以在您正在閱讀的同一篇文章或我在下面留下的其他文章中找到: ![段落初始範例 1](https://github.com/cherryramatisdev/public_zet/assets/86631177/a76e0a72-60a7-4864-b2e9-f43922a8e0fb) ![段落初始範例 2](https://github.com/cherryramatisdev/public_zet/assets/86631177/64fc0d55-eed4-4c81-b4cf-193cf0d594a6) 我們的想法是始終在文本中使用問題和停頓,以便我們能夠實現直接的對話式交流,並始終嘗試以最普遍的方式呈現情況,以便任何閱讀者都非常好奇並願意閱讀。 在第一段演示之後,定義[目錄](#table-of-content) 來引導使用者了解文章的主要標題非常重要,在這方面我個人不建議列出副標題標題旁邊,因為它們使目錄變得非常大,對於閱讀者來說不是很有用,顯然,如果您認為列出字幕非常重要,那麼完全值得包括在內。 轉到文章的正文,我們進入一個非常主觀的領域,因為它在很大程度上取決於所涵蓋的主題以理解其標題和段落的結構。我將假設簡單教程模型中的一篇文章能夠從某個地方開始。 我總是建議使用三個“附屬標題”來指導您的文章並提供靈感以通過更多細節擴展內容。這些衛星標題如下: -「技術或問題簡介」:這段將幫助我們詳細說明文章開頭所說的內容,回答我們為激發好奇心而建立的問題,並更深入地研究將與特定主題一起討論的主題。 - `優點與缺點`:此時我們將明確本文將介紹的解決方案的優點和缺點,無論是架構、程式碼標準、語言、框架等。根據您的主題,此段落的存在可能非常具體,但如果您以教程的形式呈現解決方案,它通常非常有用! - `結論`:這一點更多的是一種意見,而不是一般規則,但我認為有一個段落將表明閱讀過程的結束是非常重要的,這樣我們就可以留下最終的論點,謝謝,聯繫方式以及任何其他有趣的訊息。 圍繞著這三個主要標題,我們可以用說明性的寫作來發展我們的文章,提供實際的例子或類比,使讀者更容易想像問題和解決方案。同樣重要的是要強調在過於深入地進行類比時要小心,它們非常有用,但是當你濫用它們並且永遠不會帶著明確的解決方案和解釋回到現實世界時,它們可能會成為一劑強心針。 關於文章結構的一般提示是保持閱讀光線的總體感覺,因此強烈建議使用圖像(無論是放鬆的表情包還是更好地說明所要表達的觀點的圖形),因為開發人員.to平台支持更多非正式技術人員的文章,濫用這種更接近的語言是一個非常準確的策略。 ## 如何複習並提升寫作水平 ![程式碼審查迷因](https://github.com/cherryramatisdev/public_zet/assets/86631177/ba71cb93-5734-423f-ab32-7718bf5bca5d) 好吧,現在我們已經很好地了解瞭如何建立我們的文章、如何使用 Markdown 保持文章美觀以及如何考慮我們的語言針對特定平台的情況,還缺少什麼嗎?好吧,現在剩下的就是要明白我們並不完美,我們會犯錯誤,因此,我們需要一個好的策略來回顧我們剛剛用我們學到的技術製作的文章。 為了幫助寫作,我強烈建議使用提供即時 Markdown 預覽的編輯器,例如 [VSCode](https://code.visualstudio.com/Docs/languages/markdown) 或社群最喜歡的 [Obsidian](https://obsidian.md)。這篇文章甚至是用黑曜石寫的! 在複習方面,我們有一些非常有趣的工具可以幫助我們進行寫作的不同方面: - [LanguageTool](https://languagetool.org):這個工具是我最喜歡的,它可以處理所有拼字更正,最酷的部分是,在這個工具中,您可以提供上下文提示,可以改進句子並更正特定的程式設計術語,例如語言名稱,因為他們的資料庫是超級更新的。 - [Deepl](https://www.deepl.com/translator):進入人工智慧世界,Deepl 使用深度學習提供令人難以置信的翻譯介面,但不僅如此!有了它,我們可以獲得第二意見,以一種非常簡單的方式重新表述我們的段落,您只需將文本翻譯成英語,然後再次將英語文本翻譯成葡萄牙語;通常在Google翻譯中,這會破壞上下文,但該工具保留了上下文並改進了表達方式,以便您對同一段落有第二個感知。 - [ChatGPT](http://chat.openai.com) 或 [Bard](https://bard.google.com): 好吧,在這裡我承認我沒有太多知識,而且我不使用很多,但是這些介面人工智慧聊天可以幫助我們提出不同的觀點,重新措詞現有的段落,甚至開始寫一個段落。 **重要提示:我需要強調的是,您應該只使用這些工具來獲取想法或幫助改寫您已經編寫的文本,請不要使用人工智慧生成整篇文章** - [社群](https://heartdevs.com):在 He4rt 開發者社群中,我們嘗試為在 dev.to 平台上撰寫技術文章提供盡可能多的幫助。我們透過提供一個論壇來做到這一點,您可以在文章仍在進行中時發布您的文章,並在發表之前獲得社區的反饋。發表後,我們還為活躍的人做宣傳工作! **免責聲明:顯然我提到的是 He4rt,因為我們有一個專注於此的專案,但一般的教訓是與整個社區分享您的進展。** ## 結論和致謝 這是我在[100 天的程式碼](https://www.100diasdecodigo.dev) 挑戰之後發布的最後一篇文章,這是一個非常激烈的挑戰,需要大量的學習,我發現了一種新的熱情:寫作和分享知識!我甚至無法感謝 He4rt 社區在這段漫長的旅程中對我 100% 的支持。我希望這篇文章對任何閱讀它的人都有用,並激勵任何人在線上分享知識,以便我們可以建立一個更安全、資訊更豐富的網路。 我還要特別感謝本文的審稿人: - [阿尼巴爾‧索倫](https://github.com/anibalsolon) - [艾莉西亞瑪麗安](https://github.com/m4rri4nne) - [米格爾·S·巴博薩](https://github.com/m1guelsb) - [克林頓·羅查](https://github.com/Clintonrocha98) - [塞繆爾·羅德里格斯](https://github.com/SamucaDev) 願原力與你同在! 🍒 --- 原文出處:https://dev.to/he4rt/compartilhando-seu-conhecimento-com-o-mundo-como-escrever-artigos-5ghc

💨 將 Javascript 應用部署到 Kubernetes 的最快方法 🌬️ ✨

## 簡介 在本教程中,您將學習如何在 Kubernetes(容器編排平台)上部署您的第一個 JavaScript 應用程式☸️。 我們將部署一個簡單的 **express** 伺服器,該伺服器使用 **Minikube** ✨ 在本機 Kubernetes 上傳回範例 JSON 物件。 **先決條件📜:** - **Docker**:用於容器化應用程式。 🐋 - **Minikube**:用於在本地執行 Kubernetes。 ☸️ ![GetADeploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mn162frk9shm0d76z99n.gif) *** ## Odigos - 開源分散式追蹤 **無需編寫任何程式碼即可同時監控所有應用程式!** 利用唯一可以在所有應用程式中產生分散式追蹤的平台來簡化 OpenTelemetry 的複雜性。 我們真的才剛開始。 可以幫我們加個星星嗎?請問? 😽 https://github.com/keyval-dev/odigos [![貓咪](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84twzafd93w3a4ktqflm.png)](https://github.com/keyval-dev/odigos) --- ### 讓我們設定一下🚀 我們將首先初始化我們的專案: ``` npm init -y ``` 這會使用 `package.json` 📝 檔案初始化 **NodeJS** 專案,該檔案追蹤我們安裝的依賴項。 安裝 Express.js 框架 ``` npm install express ``` 現在,在 `package.json` 中,依賴項物件應該如下所示。 ✅ ``` "dependencies": { "express": "^4.18.2" } ``` 現在,在專案的根目錄中建立一個「index.js」檔案並新增以下程式碼行。 🚀 ``` // 👇🏻 Initialize express. const express = require("express"); const app = express(); const port = 3000; // 👇🏻 Return a sample JSON object with a message property on the root path. app.get("/", (req, res) => { res.json({ message: "Hello from Odigos!", }); }); // 👇🏻 Listen on port 3000. app.listen(port, () => { console.log(`Server is listening on port ${port}`); }); ``` 我們需要在「package.json」中新增一個腳本來執行應用程式。將其新增至 `package.json` 的腳本物件中。 ``` "scripts": { "dev": "node index.js" }, ``` 現在,要檢查我們的應用程式是否正常執行,請使用「npm run dev」執行伺服器,並透過 CLI 或在瀏覽器中向「localhost:3000」發出 get 請求。 ✨ 如果您使用 CLI,請確保已安裝了 [cURL](https://curl.se/)。 ✅ ``` curl http://localhost:3000 ``` 你應該看到這樣的東西。 👇🏻 ![cURL 回應](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxs2uu8u0aa7kw6k9ta4.png) 現在,您可以使用「Ctrl + C」簡單地停止正在執行的 Express 伺服器🚫 我們的範例應用程式已準備就緒! 🎉 現在,讓我們將其容器化並推送到 Kubernetes。 🐳☸️ *** ### 將應用程式容器化📦 我們將使用 **Docker** 來容器化我們的應用程式。 在專案的根目錄中,建立一個名為「Dockerfile」的新檔案。 > 💡 確保名稱完全相同。否則,您將需要明確傳遞“-f”標誌來指定“Dockerfile”路徑。 ``` # Uses node as the base image FROM node:21-alpine # Sets up our working directory as /app inside the container. WORKDIR /app # Copyies package json files. COPY package.json package-lock.json ./ # Installs the dependencies from the package.json RUN npm install --production # Copies current directory files into the docker environment COPY . . # Expose port 3000 as our server uses it. EXPOSE 3000 # Finally runs the server. CMD ["node", "index.js"] ``` 現在,我們需要建置 ⚒️ 這個容器才能實際使用它並將其推送到 Kubernetes。 執行此命令來建置“Dockerfile”。 > 🚨 如果您在 Windows 上執行它,請確保 Docker Desktop 正在執行。 ``` // 👇🏻 We are tagging our image name to express-server docker build -t express-server . ``` 現在,是時候執行容器了。 🏃🏻‍♂️💨 ``` docker run -dp 127.0.0.1:3000:3000 express-server ``` > 💡 我們正在後台執行容器,容器連接埠 3000 對應到我們的電腦連接埠 3000。 再次執行以下命令,您應該會看到與之前相同的結果。 ✅ ``` curl http://localhost:3000 ``` > **注意**:這次應用程式沒有像以前一樣在我們的電腦上執行。相反,它在容器內運作。 🤯 *** ### 在 Kubernetes 中部署 ## 如前所述,我們將使用 Minikube 在本機電腦上建立編排環境,並使用 kubectl 命令與 Kubernetes 互動。 😄 **啟動 Minikube:🚀** ``` minikube start ``` 由於我們將使用本機容器而不是從 docker hub 中提取它們,因此請執行這些命令。 ✨ ``` eval $(minikube docker-env) docker build -t express-server . ``` `eval $(minikube docker-env)`:用於將終端機的 `docker-cli` 指向 minikube 內的 Docker 引擎。 > 🚨 注意,我們很多人都使用 Fish 作為 shell,因此對於 Fish 來說,相應的命令是 `eval (minikube docker-env)` 現在,在專案根目錄中,建立一個嵌套資料夾“k8/deployment”,並在部署資料夾中建立一個名為“deployment.yaml”的新文件,其中包含以下內容。 在此文件中,我們將管理容器的部署。 👇🏻 ``` # 👇🏻 /k8/deployment/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: express-deployment spec: selector: matchLabels: app: express-svr template: metadata: labels: app: express-svr spec: containers: - name: express-svr image: express-server imagePullPolicy: Never # Make sure to set it to Never, or else it will pull from the docker hub and fail. resources: limits: memory: "128Mi" cpu: "500m" ports: - containerPort: 3000 ``` 最後,執行此命令以應用我們剛剛建立的部署配置「deployment.yaml」。 ✨ ``` kubectl apply -f .\k8\deployment\deployment.yaml ``` 現在,如果我們查看正在執行的 Pod,我們可以看到 Pod 已成功建立。 🎉 ![執行 kubernetes pod](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83ijo09xpd9ccv30h6ug.png) 要查看我們建立的 Pod 的日誌,請執行“kubectl messages <pod_name>”,我們應該會看到以下內容。 ![正在執行的 kubernetes pod 的日誌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f97aap8qioqsjr45rafw.png) 至此,我們的「express-server」就成功部署在本地 Kubernetes 上了。 😎 *** 這就是本文的內容,我們成功地將應用程式容器化並將其部署到 Kubernetes。 本文的原始碼可以在這裡找到 https://github.com/keyval-dev/blog/tree/main/js-on-k8s 非常感謝您的閱讀! 🎉🫡 --- 原文出處:https://dev.to/odigos/the-fastest-way-to-deploy-your-javascript-app-to-kubernetes-2j33

【Python 🐍精通】Python Linked List 及基本 Linked List 操作🛠️

在上一篇文章中,我們了解了物件導向程式設計並對 Python 的 Magic/Dunder 方法進行了全面概述。 **Python 中的物件導向程式設計 (OOP)**:Python 中的這種範例圍繞著建立可重複使用程式碼。它涉及使用類別作為物件的藍圖。這些物件可以具有定義其行為和交互的屬性(資料)和方法(函數)。 **Python 的 Magic/Dunder 方法**:Python 中的 Magic 或 Dunder(雙底線)方法是名稱以雙底線開頭和結尾的特殊方法(例如,`__init__`、`__str__`、`__repr__`)。 您可以在這裡閱讀相關內容。 👇 https://dev.to/swirl/python-mastery-pythons-object-oriented-programming-overview-and-fundamentals-22m1 今天,我們將對其進行擴展,並使用物件導向程式設計的知識來理解和建立 Python 中的鍊錶。並會對其執行一些操作。 ## 開源 Python 專案:[Swirl](https://github.com/swirlai/swirl-search) [![旋流搜尋](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9icq3q8vmtzrse1cbqcj.gif)](https://github.com/swirlai/swirl-search) 如果您對 Python 感興趣,您將會💖 [**Swirl**](https://github.com/swirlai/swirl-search)。 Swirl 是一個開源搜尋平台,它將為您提供以下知識: - Python - 人工智慧 - 在任何產品中整合大型語言模型 - 了解如何開發搜尋平台。 檢查我們的 GitHub 儲存庫: https://github.com/swirlai/swirl-search 如果您能夠:我們將非常高興: https://github.com/swirlai/swirl-search ## Linked List 連結列表是物件有序的集合。它是一種資料結構,旨在將資料保存在不連續的記憶體區塊中。 與使用連續記憶體區塊的陣列或傳統列表不同,鍊錶儲存在非連續記憶體位置。這種設計允許高效的插入和刪除,而無需重新排列整個資料結構。 這種設計允許高效的插入和刪除,而不需要重新排列整個資料結構。 ### 基本鍊錶 基本鍊錶是一種線性資料結構,其中每個元素(稱為節點)包含兩部分:資料和對清單中下一個節點的引用。這種結構允許有效地插入和刪除元素,因為它不需要移動元素,這與陣列不同。 典型的節點設計: **資料**:包含資料,可以是數字、地址、文字等。 **Next**:指向下一個資料節點或儲存下一個資料節點的位址。 ![Python 中鍊錶的節點](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cus930t03hko9x0xeac2.png) 第一個節點稱為列表的頭,最後一個節點指向 None(在 Python 中)(或在其他語言中為 Null),稱為尾節點。 當你把很多節點收集在一起時,它就變成了一個鍊錶。 ![Python 中的鍊錶](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndkxz3274ylfqva4y2kh.png) ### 鍊錶的好處和操作的時間複雜度 連結清單有很多好處,特別是在動態資料操作場景中。以下是一些主要優勢: 1. **動態大小**:與陣列不同,鍊錶可以動態增長或縮小大小,這對於記憶體使用來說是高效的。 2. **易於插入/刪除**:插入或刪除節點相對簡單,因為它通常只涉及更改一些引用,而不需要像陣列中那樣移動元素。 3. **靈活性**:它們可以實現其他資料結構,如堆疊、佇列和圖鄰接表。 |運營|時間複雜度| |----------------|-----------------| |存取 | O(n) | |搜尋 | O(n) | |插入| O(1) | O(1) | |刪除 | O(1) | O(1) | _注意_:我們考慮的是單鍊錶。 ## 在 Python 中實作鍊錶。 這是將在 Python 中建立節點的程式碼。如果您對 `__repr__` 方法感到困惑,請注意。請查看本系列中的[上一篇文章](https://dev.to/swirl/python-mastery-pythons-object-oriented-programming-overview-and-fundamentals-22m1)。 ``` class Node: def __init__(self, data): self.data = data self.next = None def __repr__(self): return f"Node({self.data})" ``` 連結列表類別的程式碼。這利用了 Node 類別來建立資料並將它們連接在一起。 ``` class LinkedList: def __init__(self): self.head = None def append(self, data): new_node = Node(data) if self.head is None: self.head = new_node return last_node = self.head while last_node.next: last_node = last_node.next last_node.next = new_node def __repr__(self): nodes = [] current = self.head while current: nodes.append(repr(current)) current = current.next return "->".join(nodes) ``` 這段程式碼做了兩件事: 1. **追加**:在鍊錶末端追加一個節點。 2. `__repr__` :此方法遍歷鍊錶並以Pythonic方式列印它。 1. 這也可以使用稱為 traverse 的方法來完成。 _這是呼叫「__repr__」方法的「print(llist)」的輸出: ![在 Python 中列印連結清單](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8krtl50nkifa5nhvsh4j.png) ### 遍歷鍊錶。 遍歷鍊錶就是遍歷每個節點並列印它的過程。 ``` def traverse(linked_list): current = linked_list.head while current: print(current.data) current = current.next llist = LinkedList() llist.append(1) llist.append(2) llist.append(3) print("Traversing the linked list:") traverse(llist) ``` ![Python中遍歷鍊錶](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzzy5pwzixnwpgmfqynw.png) ## 反轉鍊錶 這個想法是迭代鍊錶,並且對於每個節點,將其“下一個”指標切換為指向前一個節點而不是下一個節點。這將幫助我們反轉鍊錶。 ``` def reverse_linked_list(head): previous = None current = head while current: next_node = current.next current.next = previous previous = current current = next_node return previous llist = LinkedList() llist.append(1) llist.append(2) llist.append(3) print("Original List:", llist) new_head = reverse_linked_list(llist.head) llist.head = new_head print("Reversed List:", llist) ``` ![反轉連結清單](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s05ouz9eegzukkkuofw8.png) ## 在連結清單中插入值 我們已經有一個追加函數,可以將值加到鍊錶的末尾。但是,如果我們想要一個在特定位置加入的方法,並且如果該位置不存在,則將值附加到末尾,該怎麼辦? ``` class LinkedList: def insert_after_value(self, data_after, data_to_insert): if self.head is None: return current = self.head while current: if current.data == data_after: new_node = Node(data_to_insert) new_node.next = current.next current.next = new_node return current = current.next self.append(data_to_insert) ``` ## 刪除鍊錶中的節點 若要從鍊錶中刪除節點,請建立一個函數,該函數將鍊錶的頭和要刪除的節點的資料作為參數。並遍歷鍊錶,直到找到資料,然後將其刪除。 ``` class LinkedList: def delete_node(self, data): current = self.head if current is None or current.data == data: self.head = current.next if current else None return while current.next: if current.next.data == data: current.next = current.next.next return current = current.next ``` ![刪除連結清單中的節點](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12hjdfchdy0ofrjyyt10.png) 感謝您閱讀本文。在本系列的後續文章中,我們將討論 Python 和 Python 資料結構的更複雜的細節。 ## 為 [Swirl] 做出貢獻(https://github.com/swirlai/swirl-search) [![為 Swirl 做出貢獻](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/itecirhtu5lghtlr6m2a.jpg)](https://github.com/swirlai/swirl-search) [Swirl](https://github.com/swirlai/swirl-search) 是一個開源 Python 專案。為 Swirl 做出貢獻可以幫助您獲得生產級的 Python 知識並提高您的技能。 檢查我們的 GitHub 儲存庫: https://github.com/swirlai/swirl-search 如果您能夠:我們將非常高興: https://github.com/swirlai/swirl-search 謝謝閱讀, 你們都令人嘆為觀止。 ![你太棒了](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kqhf5vqr2lj4z5kq4gdr.gif) --- 原文出處:https://dev.to/swirl/python-mastery-overview-of-linked-list-in-python-essential-linked-list-operations-hn3

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

🚀使用 NextJS、Trigger.dev 和 GPT4 做一個履歷表產生器🔥✨

## 簡介 在本文中,您將學習如何使用 NextJS、Trigger.dev、Resend 和 OpenAI 建立簡歷產生器。 😲 - 加入基本詳細訊息,例如名字、姓氏和最後工作地點。 - 產生詳細訊息,例如個人資料摘要、工作經歷和工作職責。 - 建立包含所有資訊的 PDF。 - 將所有內容傳送到您的電子郵件 ![猴子手錶](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/23k6hee187s62k8y1dmd.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) 請幫我們一顆星🥹。 這將幫助我們建立更多這樣的文章💖 https://github.com/triggerdotdev/trigger.dev --- ## 讓我們來設定一下吧🔥 使用 NextJS 設定一個新專案 ``` npx create-next-app@latest ``` 我們將建立一個包含基本資訊的簡單表單,例如: - 名 - 姓 - 電子郵件地址 - 你的頭像 - 以及你今天為止的經驗! ![輸入](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01mmvn0lvw1p1i4knoa8.png) 我們將使用 NextJS 的新應用程式路由器。 開啟`layout.tsx`並加入以下程式碼 ``` import { GeistSans } from "geist/font"; import "./globals.css"; const defaultUrl = process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "http://localhost:3000"; export const metadata = { metadataBase: new URL(defaultUrl), title: "Resume Builder with GPT4", description: "The fastest way to build a resume with GPT4", }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en" className={GeistSans.className}> <body className="bg-background text-foreground"> <main className="min-h-screen flex flex-col items-center"> {children} </main> </body> </html> ); } ``` 我們基本上是為所有頁面設定佈局(即使我們只有一頁。) 我們設定基本的頁面元資料、背景和全域 CSS 元素。 接下來,讓我們打開“page.tsx”並加入以下程式碼: ``` <div className="flex-1 w-full flex flex-col items-center"> <nav className="w-full flex justify-center border-b border-b-foreground/10 h-16"> <div className="w-full max-w-6xl flex justify-between items-center p-3 text-sm"> <span className="font-bold select-none">resumeGPT.</span> </div> </nav> <div className="animate-in flex-1 flex flex-col opacity-0 max-w-6xl px-3"> <Home /> </div> </div> ``` 這設定了我們的resumeGPT 的標題和主要的家庭元件。 <小時/> ## 建立表單的最簡單方法 保存表單資訊並驗證欄位最簡單的方法是使用react-hook-form。 我們將上傳個人資料照片。 為此,我們不能使用基於 JSON 的請求。 我們需要將 JSON 轉換為有效的表單資料。 那麼就讓我們把它們全部安裝吧! ``` npm install react-hook-form object-to-formdata axios --save ``` 建立一個名為 Components 的新資料夾,新增一個名為「Home.tsx」的新文件,並新增以下程式碼: ``` "use client"; import React, { useState } from "react"; import {FormProvider, useForm} from "react-hook-form"; import Companies from "@/components/Companies"; import axios from "axios"; import {serialize} from "object-to-formdata"; export type TUserDetails = { firstName: string; lastName: string; photo: string; email: string; companies: TCompany[]; }; export type TCompany = { companyName: string; position: string; workedYears: string; technologies: string; }; const Home = () => { const [finished, setFinished] = useState<boolean>(false); const methods = useForm<TUserDetails>() const { register, handleSubmit, formState: { errors }, } = methods; const handleFormSubmit = async (values: TUserDetails) => { axios.post('/api/create', serialize(values)); setFinished(true); }; if (finished) { return ( <div className="mt-10">Sent to the queue! Check your email</div> ) } return ( <div className="flex flex-col items-center justify-center p-7"> <div className="w-full py-3 bg-slate-500 items-center justify-center flex flex-col rounded-t-lg text-white"> <h1 className="font-bold text-white text-3xl">Resume Builder</h1> <p className="text-gray-300"> Generate a resume with GPT in seconds 🚀 </p> </div> <FormProvider {...methods}> <form onSubmit={handleSubmit(handleFormSubmit)} className="p-4 w-full flex flex-col" > <div className="flex flex-col lg:flex-row gap-4"> <div className="flex flex-col w-full"> <label htmlFor="firstName">First name</label> <input type="text" required id="firstName" placeholder="e.g. John" className="p-3 rounded-md outline-none border border-gray-500 text-white bg-transparent" {...register('firstName')} /> </div> <div className="flex flex-col w-full"> <label htmlFor="lastName">Last name</label> <input type="text" required id="lastName" placeholder="e.g. Doe" className="p-3 rounded-md outline-none border border-gray-500 text-white bg-transparent" {...register('lastName')} /> </div> </div> <hr className="w-full h-1 mt-3" /> <label htmlFor="email">Email Address</label> <input type="email" required id="email" placeholder="e.g. [email protected]" className="p-3 rounded-md outline-none border border-gray-500 text-white bg-transparent" {...register('email', {required: true, pattern: /^\S+@\S+$/i})} /> <hr className="w-full h-1 mt-3" /> <label htmlFor="photo">Upload your image 😎</label> <input type="file" id="photo" accept="image/x-png" className="p-3 rounded-md outline-none border border-gray-500 mb-3" {...register('photo', {required: true})} /> <Companies /> <button className="p-4 pointer outline-none bg-blue-500 border-none text-white text-base font-semibold rounded-lg"> CREATE RESUME </button> </form> </FormProvider> </div> ); }; export default Home; ``` 您可以看到我們從「使用客戶端」開始,它基本上告訴我們的元件它應該只在客戶端上執行。 為什麼我們只需要客戶端? React 狀態(輸入變更)僅在用戶端可用。 我們設定兩個接口,「TUserDetails」和「TCompany」。它們代表了我們正在使用的資料的結構。 我們將“useForm”與“react-hook-form”一起使用。它為我們的輸入建立了本地狀態管理,並允許我們輕鬆更新和驗證我們的欄位。您可以看到,在每個「輸入」中,都有一個簡單的「註冊」函數,用於指定輸入名稱和驗證並將其註冊到託管狀態。 這很酷,因為我們不需要使用像“onChange”這樣的東西 您還可以看到我們使用了“FormProvider”,這很重要,因為我們希望在子元件中擁有“react-hook-form”的上下文。 我們還有一個名為「handleFormSubmit」的方法。這是我們提交表單後呼叫的方法。您可以看到我們使用“serialize”函數將 javascript 物件轉換為 FormData,並向伺服器發送請求以使用“axios”啟動作業。 您可以看到另一個名為“Companies”的元件。該元件將讓我們指定我們工作過的所有公司。 那麼讓我們努力吧。 建立一個名為「Companies.tsx」的新文件 並加入以下程式碼: ``` import React, {useCallback, useEffect} from "react"; import { TCompany } from "./Home"; import {useFieldArray, useFormContext} from "react-hook-form"; const Companies = () => { const {control, register} = We(); const {fields: companies, append} = useFieldArray({ control, name: "companies", }); const addCompany = useCallback(() => { append({ companyName: '', position: '', workedYears: '', technologies: '' }) }, [companies]); useEffect(() => { addCompany(); }, []); return ( <div className="mb-4"> {companies.length > 1 ? ( <h3 className="font-bold text-white text-3xl my-3"> Your list of Companies: </h3> ) : null} {companies.length > 1 && companies.slice(1).map((company, index) => ( <div key={index} className="mb-4 p-4 border bg-gray-800 rounded-lg shadow-md" > <div className="mb-2"> <label htmlFor={`companyName-${index}`} className="text-white"> Company Name </label> <input type="text" id={`companyName-${index}`} className="p-2 border border-gray-300 rounded-md w-full bg-transparent" {...register(`companies.${index}.companyName`, {required: true})} /> </div> <div className="mb-2"> <label htmlFor={`position-${index}`} className="text-white"> Position </label> <input type="text" id={`position-${index}`} className="p-2 border border-gray-300 rounded-md w-full bg-transparent" {...register(`companies.${index}.position`, {required: true})} /> </div> <div className="mb-2"> <label htmlFor={`workedYears-${index}`} className="text-white"> Worked Years </label> <input type="number" id={`workedYears-${index}`} className="p-2 border border-gray-300 rounded-md w-full bg-transparent" {...register(`companies.${index}.workedYears`, {required: true})} /> </div> <div className="mb-2"> <label htmlFor={`workedYears-${index}`} className="text-white"> Technologies </label> <input type="text" id={`technologies-${index}`} className="p-2 border border-gray-300 rounded-md w-full bg-transparent" {...register(`companies.${index}.technologies`, {required: true})} /> </div> </div> ))} <button type="button" onClick={addCompany} className="mb-4 p-2 pointer outline-none bg-blue-900 w-full border-none text-white text-base font-semibold rounded-lg"> Add Company </button> </div> ); }; export default Companies; ``` 我們從 useFormContext 開始,它允許我們取得父元件的上下文。 接下來,我們使用 useFieldArray 建立一個名為 Companies 的新狀態。這是我們擁有的所有公司的一個陣列。 在「useEffect」中,我們新增陣列的第一項以對其進行迭代。 當點擊“addCompany”時,它會將另一個元素推送到陣列中。 我們已經和客戶完成了🥳 --- ## 解析HTTP請求 還記得我們向“/api/create”發送了一個“POST”請求嗎? 讓我們轉到 app/api 資料夾並在該資料夾中建立一個名為「create」的新資料夾,建立一個名為「route.tsx」的新檔案並貼上以下程式碼: ``` import {NextRequest, NextResponse} from "next/server"; import {client} from "@/trigger"; export async function POST(req: NextRequest) { const data = await req.formData(); const allArr = { name: data.getAll('companies[][companyName]'), position: data.getAll('companies[][position]'), workedYears: data.getAll('companies[][workedYears]'), technologies: data.getAll('companies[][technologies]'), }; const payload = { firstName: data.get('firstName'), lastName: data.get('lastName'), photo: Buffer.from((await (data.get('photo[0]') as File).arrayBuffer())).toString('base64'), email: data.get('email'), companies: allArr.name.map((name, index) => ({ companyName: allArr.name[index], position: allArr.position[index], workedYears: allArr.workedYears[index], technologies: allArr.technologies[index], })).filter((company) => company.companyName && company.position && company.workedYears && company.technologies) } await client.sendEvent({ name: 'create.resume', payload }); return NextResponse.json({ }) } ``` > 此程式碼只能在 NodeJS 版本 20+ 上運作。如果版本較低,將無法解析FormData。 該程式碼非常簡單。 - 我們使用 `req.formData` 將請求解析為 FormData - 我們將基於 FormData 的請求轉換為 JSON 檔案。 - 我們提取圖像並將其轉換為“base64” - 我們將所有內容傳送給 TriggerDev --- ## 製作履歷並將其發送到您的電子郵件📨 建立履歷是我們需要的長期任務 - 使用 ChatGPT 產生內容。 - 建立 PDF - 發送到您的電子郵件 由於某些原因,我們不想發出長時間執行的 HTTP 請求來執行所有這些操作。 1. 部署到 Vercel 時,無伺服器功能有 10 秒的限制。我們永遠不會準時到達。 2.我們希望讓用戶不會長時間掛起。這是一個糟糕的使用者體驗。如果用戶關閉窗口,整個過程將失敗。 ### 介紹 Trigger.dev! 使用 Trigger.dev,您可以在 NextJS 應用程式內執行後台進程!您不需要建立新伺服器。 他們也知道如何透過將長時間執行的作業無縫地分解為短期任務來處理它們。 註冊 [Trigger.dev 帳號](https://trigger.dev/)。註冊後,建立一個組織並為您的工作選擇一個專案名稱。 ![CreateOrg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shf1jsb4gio1zrjtz91d.jpeg) 選擇 Next.js 作為您的框架,並按照將 Trigger.dev 新增至現有 Next.js 專案的流程進行操作。 ![下一頁](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5guppb6rot13myu6th5c.jpeg) 否則,請點選專案儀表板側邊欄選單上的「環境和 API 金鑰」。 ![複製](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5gh527u7sthp6clkcfa.png) 複製您的 DEV 伺服器 API 金鑰並執行下面的程式碼片段以安裝 Trigger.dev。仔細按照說明進行操作。 ``` npx @trigger.dev/cli@latest init ``` 在另一個終端中,執行以下程式碼片段以在 Trigger.dev 和 Next.js 專案之間建立隧道。 ``` npx @trigger.dev/cli@latest dev ``` 讓我們建立 TriggerDev 作業! 前往新建立的資料夾 jobs 並建立一個名為「create.resume.ts」的新檔案。 新增以下程式碼: ``` client.defineJob({ id: "create-resume", name: "Create Resume", version: "0.0.1", trigger: eventTrigger({ name: "create.resume", schema: z.object({ firstName: z.string(), lastName: z.string(), photo: z.string(), email: z.string().email(), companies: z.array(z.object({ companyName: z.string(), position: z.string(), workedYears: z.string(), technologies: z.string() })) }), }), run: async (payload, io, ctx) => { } }); ``` 這將為我們建立一個名為「create-resume」的新工作。 如您所見,我們先前從「route.tsx」發送的請求進行了架構驗證。這將為我們提供驗證和“自動完成”。 我們將在這裡執行三項工作 - 聊天GPT - PDF建立 - 電子郵件發送 讓我們從 ChatGPT 開始。 [建立 OpenAI 帳戶](https://platform.openai.com/) 並產生 API 金鑰。 ![ChatGPT](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ashau6i2sxcpd0qcxuwq.png) 從下拉清單中按一下「檢視 API 金鑰」以建立 API 金鑰。 ![ApiKey](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> ``` 在根目錄中建立一個名為「utils」的新資料夾。 在該目錄中,建立一個名為「openai.ts」的新文件 新增以下程式碼: ``` import { OpenAI } from "openai"; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY!, }); export async function generateResumeText(prompt: string) { const response = await openai.completions.create({ model: "text-davinci-003", prompt, max_tokens: 250, temperature: 0.7, top_p: 1, frequency_penalty: 1, presence_penalty: 1, }); return response.choices[0].text.trim(); } export const prompts = { profileSummary: (fullName: string, currentPosition: string, workingExperience: string, knownTechnologies: string) => `I am writing a resume, my details are \n name: ${fullName} \n role: ${currentPosition} (${workingExperience} years). \n I write in the technologies: ${knownTechnologies}. Can you write a 100 words description for the top of the resume(first person writing)?`, jobResponsibilities: (fullName: string, currentPosition: string, workingExperience: string, knownTechnologies: string) => `I am writing a resume, my details are \n name: ${fullName} \n role: ${currentPosition} (${workingExperience} years). \n I write in the technolegies: ${knownTechnologies}. Can you write 3 points for a resume on what I am good at?`, workHistory: (fullName: string, currentPosition: string, workingExperience: string, details: TCompany[]) => `I am writing a resume, my details are \n name: ${fullName} \n role: ${currentPosition} (${workingExperience} years). ${companyDetails(details)} \n Can you write me 50 words for each company seperated in numbers of my succession in the company (in first person)?`, }; ``` 這段程式碼基本上建立了使用 ChatGPT 的基礎設施以及 3 個函數:「profileSummary」、「workingExperience」和「workHistory」。我們將使用它們來建立各部分的內容。 返回我們的「create.resume.ts」並新增作業: ``` import { client } from "@/trigger"; import { eventTrigger } from "@trigger.dev/sdk"; import { z } from "zod"; import { prompts } from "@/utils/openai"; import { TCompany, TUserDetails } from "@/components/Home"; const companyDetails = (companies: TCompany[]) => { let stringText = ""; for (let i = 1; i < companies.length; i++) { stringText += ` ${companies[i].companyName} as a ${companies[i].position} on technologies ${companies[i].technologies} for ${companies[i].workedYears} years.`; } return stringText; }; client.defineJob({ id: "create-resume", name: "Create Resume", version: "0.0.1", integrations: { resend }, trigger: eventTrigger({ name: "create.resume", schema: z.object({ firstName: z.string(), lastName: z.string(), photo: z.string(), email: z.string().email(), companies: z.array(z.object({ companyName: z.string(), position: z.string(), workedYears: z.string(), technologies: z.string() })) }), }), run: async (payload, io, ctx) => { const texts = await io.runTask("openai-task", async () => { return Promise.all([ await generateResumeText(prompts.profileSummary(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies[0].technologies)), await generateResumeText(prompts.jobResponsibilities(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies[0].technologies)), await generateResumeText(prompts.workHistory(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies)) ]); }); }, }); ``` 我們建立了一個名為「openai-task」的新任務。 在該任務中,我們使用 ChatGPT 同時執行三個提示,並返回它們。 --- ## 建立 PDF 建立 PDF 的方法有很多種 - 您可以使用 HTML2CANVAS 等工具並將 HTML 程式碼轉換為映像,然後轉換為 PDF。 - 您可以使用「puppeteer」之類的工具來抓取網頁並將其轉換為 PDF。 - 您可以使用不同的庫在後端建立 PDF。 在我們的例子中,我們將使用一個名為「jsPdf」的簡單函式庫,它是在後端建立 PDF 的非常簡單的函式庫。我鼓勵您使用 Puppeteer 和更多 HTML 來建立一些更強大的 PDF 檔案。 那我們來安裝它 ``` npm install jspdf @typs/jspdf --save ``` 讓我們回到「utils」並建立一個名為「resume.ts」的新檔案。該文件基本上會建立一個 PDF 文件,我們可以將其發送到使用者的電子郵件中。 加入以下內容: ``` import {TUserDetails} from "@/components/Home"; import {jsPDF} from "jspdf"; type ResumeProps = { userDetails: TUserDetails; picture: string; profileSummary: string; workHistory: string; jobResponsibilities: string; }; export function createResume({ userDetails, picture, workHistory, jobResponsibilities, profileSummary }: ResumeProps) { const doc = new jsPDF(); // Title block doc.setFontSize(24); doc.setFont('helvetica', 'bold'); doc.text(userDetails.firstName + ' ' + userDetails.lastName, 45, 27); doc.setLineWidth(0.5); doc.rect(20, 15, 170, 20); // x, y, width, height doc.addImage({ imageData: picture, x: 25, y: 17, width: 15, height: 15 }); // Reset font for the rest doc.setFontSize(12); doc.setFont('helvetica', 'normal'); // Personal Information block doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text('Summary', 20, 50); doc.setFontSize(10); doc.setFont('helvetica', 'normal'); const splitText = doc.splitTextToSize(profileSummary, 170); doc.text(splitText, 20, 60); const newY = splitText.length * 5; // Work history block doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text('Work History', 20, newY + 65); doc.setFontSize(10); doc.setFont('helvetica', 'normal'); const splitWork = doc.splitTextToSize(workHistory, 170); doc.text(splitWork, 20, newY + 75); const newNewY = splitWork.length * 5; // Job Responsibilities block doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text('Job Responsibilities', 20, newY + newNewY + 75); doc.setFontSize(10); doc.setFont('helvetica', 'normal'); const splitJob = doc.splitTextToSize(jobResponsibilities, 170); doc.text(splitJob, 20, newY + newNewY + 85); return doc.output("datauristring"); } ``` 該文件包含三個部分:「個人資訊」、「工作歷史」和「工作職責」區塊。 我們計算每個區塊的位置和內容。 一切都是以“絕對”的方式設置的。 值得注意的是“splitTextToSize”將文字分成多行,因此它不會超出螢幕。 ![恢復](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hdolng9e5ojev895x8i5.png) 現在,讓我們建立下一個任務:再次開啟 `resume.ts` 並新增以下程式碼: ``` import { client } from "@/trigger"; import { eventTrigger } from "@trigger.dev/sdk"; import { z } from "zod"; import { prompts } from "@/utils/openai"; import { TCompany, TUserDetails } from "@/components/Home"; import { createResume } from "@/utils/resume"; const companyDetails = (companies: TCompany[]) => { let stringText = ""; for (let i = 1; i < companies.length; i++) { stringText += ` ${companies[i].companyName} as a ${companies[i].position} on technologies ${companies[i].technologies} for ${companies[i].workedYears} years.`; } return stringText; }; client.defineJob({ id: "create-resume", name: "Create Resume", version: "0.0.1", integrations: { resend }, trigger: eventTrigger({ name: "create.resume", schema: z.object({ firstName: z.string(), lastName: z.string(), photo: z.string(), email: z.string().email(), companies: z.array(z.object({ companyName: z.string(), position: z.string(), workedYears: z.string(), technologies: z.string() })) }), }), run: async (payload, io, ctx) => { const texts = await io.runTask("openai-task", async () => { return Promise.all([ await generateResumeText(prompts.profileSummary(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies[0].technologies)), await generateResumeText(prompts.jobResponsibilities(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies[0].technologies)), await generateResumeText(prompts.workHistory(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies)) ]); }); console.log('passed chatgpt'); const pdf = await io.runTask('convert-to-html', async () => { const resume = createResume({ userDetails: payload, picture: payload.photo, profileSummary: texts[0], jobResponsibilities: texts[1], workHistory: texts[2], }); return {final: resume.split(',')[1]} }); console.log('converted to pdf'); }, }); ``` 您可以看到我們新增了一個名為「convert-to-html」的新任務。這將為我們建立 PDF,將其轉換為 base64 並返回。 --- ## 讓他們知道🎤 我們即將到達終點! 剩下的唯一一件事就是與用戶分享。 您可以使用任何您想要的電子郵件服務。 我們將使用 Resend.com 造訪[註冊頁面](https://resend.com/signup),建立帳戶和 API 金鑰,並將其儲存到 `.env.local` 檔案中。 ``` RESEND_API_KEY=<place_your_API_key> ``` ![密鑰](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yncrarbwcs65j44fs91y.png) 將 [Trigger.dev Resend 整合套件](https://trigger.dev/docs/integrations/apis/resend) 安裝到您的 Next.js 專案。 ``` npm install @trigger.dev/resend ``` 剩下要做的就是加入我們的最後一項工作! 幸運的是,Trigger 直接與 Resend 集成,因此我們不需要建立新的「正常」任務。 這是最終的程式碼: ``` import { client } from "@/trigger"; import { eventTrigger } from "@trigger.dev/sdk"; import { z } from "zod"; import { prompt } from "@/utils/openai"; import { TCompany, TUserDetails } from "@/components/Home"; import { createResume } from "@/utils/resume"; import { Resend } from "@trigger.dev/resend"; const resend = new Resend({ id: "resend", apiKey: process.env.RESEND_API_KEY!, }); const companyDetails = (companies: TCompany[]) => { let stringText = ""; for (let i = 1; i < companies.length; i++) { stringText += ` ${companies[i].companyName} as a ${companies[i].position} on technologies ${companies[i].technologies} for ${companies[i].workedYears} years.`; } return stringText; }; client.defineJob({ id: "create-resume", name: "Create Resume", version: "0.0.1", integrations: { resend }, trigger: eventTrigger({ name: "create.resume", schema: z.object({ firstName: z.string(), lastName: z.string(), photo: z.string(), email: z.string().email(), companies: z.array(z.object({ companyName: z.string(), position: z.string(), workedYears: z.string(), technologies: z.string() })) }), }), run: async (payload, io, ctx) => { const texts = await io.runTask("openai-task", async () => { return Promise.all([ await generateResumeText(prompts.profileSummary(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies[0].technologies)), await generateResumeText(prompts.jobResponsibilities(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies[0].technologies)), await generateResumeText(prompts.workHistory(payload.firstName, payload.companies[0].position, payload.companies[0].workedYears, payload.companies)) ]); }); console.log('passed chatgpt'); const pdf = await io.runTask('convert-to-html', async () => { const resume = createResume({ userDetails: payload, picture: payload.photo, profileSummary: texts[0], jobResponsibilities: texts[1], workHistory: texts[2], }); return {final: resume.split(',')[1]} }); console.log('converted to pdf'); await io.resend.sendEmail('send-email', { to: payload.email, subject: 'Resume', html: 'Your resume is attached!', attachments: [ { filename: 'resume.pdf', content: Buffer.from(pdf.final, 'base64'), contentType: 'application/pdf', } ], from: "Nevo David <[email protected]>", }); console.log('Sent email'); }, }); ``` 我們在檔案頂部的「Resend」實例載入了儀表板中的 API 金鑰。 我們有 ``` integrations: { resend }, ``` 我們將其加入到我們的作業中,以便稍後在“io”內部使用。 最後,我們的工作是發送 PDF `io.resend.sendEmail` 值得注意的是其中的附件,其中包含我們在上一步中產生的 PDF 文件。 我們就完成了🎉 ![我們完成了](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/esfhlds2qv1013c6x2h3.png) 您可以在此處檢查並執行完整的源程式碼: https://github.com/triggerdotdev/blog --- ## 讓我們聯絡吧! 🔌 作為開源開發者,我們邀請您加入我們的[社群](https://discord.gg/nkqV9xBYWy),以做出貢獻並與維護者互動。請隨時造訪我們的 [GitHub 儲存庫](https://github.com/triggerdotdev/trigger.dev),貢獻並建立與 Trigger.dev 相關的問題。 本教學的源程式碼可在此處取得: https://github.com/triggerdotdev/blog/tree/main/blog-resume-builder 感謝您的閱讀! --- 原文出處:https://dev.to/triggerdotdev/creating-a-resume-builder-with-nextjs-triggerdev-and-gpt4-4gmf

🧠 自己用 JavaScript 手寫:人工智慧/神經網路......! 😱 不使用任何套件!🤯

您是否嘗試過實際建立神經網路?不,我也沒有……直到今天! 在這篇文章中,我們將介紹我學到的一些東西,以及一些用 vanilla JS 編寫的非常簡單的神經網路的 2 個演示。 ## 介紹 今天早些時候,我正在閱讀 @supabase_io [“AI 內容風暴”](https://supabase.com/blog/supabase-ai-content-storm) 文章。 我突然意識到一件事。我得到了神經網路......但我實際上根本沒有得到它們! 就像,我得到了神經元的概念。但數學是如何運作的呢? 特別是如何使用「反向傳播」來訓練神經網路?偏差和權重如何發揮作用?什麼或誰是 sigmoid? ETC。 現在,明智的做法是閱讀大量文章,獲取一個庫並使用它。 **但我不懂事。** 因此,我閱讀了大量文章……然後決定建立我的第一個神經網路。 但這還不夠難,所以我決定用 JavaScript 來做(因為每個人似乎都使用 Python...)。哦,我決定在沒有任何庫的情況下完成它。哦,我也想在其中建立一個視覺化工具。 我有些不對勁……我似乎在痛苦中茁壯成長。 無論如何,我做到了,這就是我學到的東西。 ## 注意:這不是教學課程 聽著,我想澄清一下,這不是教學! 這只是我分享一些我在學習和我的**第一個**神經網路時發現有趣的事情。 請注意,這裡強調**第一**,所以請不要將其視為除了有趣的東西之外的任何東西。 我也盡力解釋每個部分及其作用,但與所有事情一樣,你對某些東西越熟練,你就越能更好地解釋它......所以我的一些解釋可能有點“偏離” ! 無論如何,既然所有這些都已經解決了,讓我們繼續吧! 如果您想直接跳到[最終演示](#the-demo),請繼續! ## 第一步 好的,首先,我可以建立的最基本的神經網路是什麼? 經過一番閱讀後,我發現神經網路可以像一些輸入神經元和一些輸出神經元一樣簡單。 每個輸入神經元都連接到一個輸出神經元,然後我們可以為每個連接加入權重。 考慮到這一點,我必須想出一個易於理解的問題來解決,但又足夠複雜以確保我的網路正常運作。 我決定建立一個神經網絡,它獲取圖表上某個點的 X 和 Y 座標,然後根據它們是正還是負為它們分配一個「團隊」(顏色)。 這樣我們就有了 2 個輸入(X 和 Y 位置),然後有 4 個輸出: 1. X > 0 且 Y > 0 2. X < 0 且 Y > 0 3. X > 0 且 Y < 0 4. X < 0 且 Y < 0 由於這裡的要求非常簡單,我們可以擺脫一些「隱藏」神經元(這是我稍後將介紹的內容)並讓事情變得超級簡單! 所以本質上我們必須建構一個看起來像這樣的神經網路: ![左側 2 個圓圈透過線連接到右側 4 個圓圈。深色背景上的霓虹燈風格。](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9rh1tbxrndmjsz5b7oo.png) 左邊的圓圈是我們的輸入(X 和 Y 位置),右邊的圓圈是我們之前討論的輸出。 ### 我們的第一個神經元 好的,現在我們可以真正開始了。 現在我實際上並沒有先建置神經元。事實上,我實際上首先建立了一個視覺化工具,因為這是查看事情是否正常運作的最簡單方法,但我稍後會介紹這一點。 因此,讓我們建立一個神經元(或更具體地說,一些神經元及其連接)。 幸運的是,神經元其實非常簡單! (或者我應該說,它們*可以*非常簡單......它們在大型語言模型(LLM)等中變得更加複雜。) 簡單神經元具有偏差(將其視為內部權重,我們將加入到最終計算中以對每個神經元進行加權的數字),並透過每個連接之間的權重連接到其他神經元。 現在回想起來,單獨加入到每個神經元的連接可能是一個更好的主意,但我決定將每層神經元和每層連接作為單獨的專案加入,因為這樣更容易理解。 所以建構我的第一個神經網路的程式碼如下所示: ``` class NeuralNetwork { constructor(inputLen, outputLen) { this.inputLen = inputLen; this.outputLen = outputLen; this.weights = Array.from({ length: this.outputLen }, () => Array.from({ length: this.inputLen }, () => Math.random()) ); this.bias = Array(this.outputLen).fill(0); } } const neuralNetwork = new NeuralNetwork(2, 4); ``` 好的,我跳過了一些步驟,所以讓我們簡要介紹一下每個部分。 `this.inputLen = inputLen;` 和 `this.outputLen = outputLen;` 只是為了讓我們可以引用輸入和輸出的數量。 `this.weights = [...]` 是連線。現在看起來可能有點嚇人,但這就是我們正在做的事情: - 建立輸出神經元陣列(`outputLen`) - 將長度為“inputLen”的陣列加入到每個陣列條目,並用 0 到 1 之間的一些隨機值填充它以開始我們的工作。 該程式碼的輸出範例如下所示: ``` this.weights = [ [0.7583747881712366,0.4306037998314902], [0.40553698492617807,0.4419651593960727], [0.852978801662627,0.9762509253699836], [0.8701610553353811,0.5583309725764114] ] ``` 它們本質上代表以下內容: ``` [input 1 to output 1, input 2 to output 1], [input 1 to output 2, input 2 to output 2], [input 1 to output 3, input 2 to output 3], [input 1 to output 4, input 2 to output 4], ``` 然後我們還有「this.bias」。 這適用於輸出層中的每個神經元。我們稍後用它來加入輸出值,使一些神經元更強,一些神經元更弱。 它只是一個由 4 個 0 組成的陣列來讓我們開始,因為我們不想要初始偏差! 現在,雖然這是一個神經網絡,但它完全沒有用。 我們無法實際使用它......如果我們確實使用它,它產生的結果將是完全隨機的! 所以我們需要解決這些問題! ### 使用我們的網路! 我們需要做的第一件事是實際獲取一些輸入,透過我們的網路執行它們並收集輸出。 這是我想出來的: ``` propagate(inputs) { const output = new Array(this.outputLen); for (let i = 0; i < this.outputLen; i++) { output[i] = 0; for (let j = 0; j < this.inputLen; j++) { output[i] += this.weights[i][j] * inputs[j]; } output[i] += this.bias[i]; output[i] = this.sigmoid(output[i]); } return output; } sigmoid(x) { return 1 / (1 + Math.exp(-x)); } ``` 現在這裡有兩件有趣的事情。 ####乙狀結腸 首先,一件有趣的事情是我們的“sigmoid”函數。它所做的只是沿著「S 形」曲線將我們輸入的值(例如 12)轉換為 0 到 1 之間的值。 這是我們將價值觀從極端標準化為更統一的**且始終為正值的方式。** 進一步閱讀後,這裡還有其他關於如何將值更改為 0 到 1 之間的選項,但我還沒有完全探索它們(例如 [ReLU](https://en.wikipedia.org/wiki/Rectifier_(neural_networks)) 如果你想閱讀相關內容)。 我確信有一些很好的解釋為什麼需要這樣做,但在我的猴腦中,這只是將值保持在 0 和 1 之間的方法,以便乘法保持在一定範圍內並且值被「展平」。 這樣你就不會在過於強大的神經元之間出現「失控」的路徑。 例如,假設您有一個權重為 16 的連接和一個權重為 1 的連接,使用我們的 sigmoid 函數,我們可以將其從 16 倍的差異減少到大約 35% 的差異(「sigmoid(1)」為0.73 ,執行我們的函數後,`sigmoid(16)` 為0.99)。 這也意味著負值變成正值。 因此,透過 sigmoid 函數執行值意味著負數會轉換為 0 到 0.5 之間的值,0 的值恰好變成 0.5,大於 0 的值變成 0.5 到 1 之間的值。 ![描繪兩條虛線之間的 S 型曲線的圖形。中間有一條虛線表示0.5。深色背景上的霓虹燈發光造型。](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dr3460emdf5m77nc0rn2.png) 如果你考慮一下,這是有道理的,因為當我們開始將負數和正數相乘時,我們可以極大地改變我們的輸出。 例如,如果我們在 100 的路徑中有一個負神經元,而其餘的都是正神經元,這會將強值更改為弱值,並且可能會導致問題。 不管怎樣,隨著我閱讀更多和實驗更多,我相信我會更好地理解這一部分! #### 我需要偏見嗎? 第二個有趣的是「output[i] += this.bias[i];」。 好吧,在這個神經網路中,所有 4 個輸出都同樣重要,而且我們沒有隱藏神經元,所以我後來刪除了它以簡化程式碼! 但諷刺的是,在我們更複雜的神經網路上,由於網路反向傳播的工作方式,我需要重新加入輸出神經元的偏差。否則,一個輸出神經元會一直啟動。 我無法弄清楚這是否是必要的步驟,或者我的神經網路是否犯了一個錯誤,而這是為了彌補它。 再次提醒大家,我還在學習中,只是掌握了基礎知識,所以我不知道它是什麼! 🤣 #### 我們快到了 上面的其餘程式碼相當簡單。我們只是將每個輸入乘以與每個輸出相關的權重(並加入不必要的偏差!)。 事實上,我們現在就可以執行它,但結果會很糟糕!讓我們來解決這個問題! ### 訓練時間到了! 好吧,神經網路的最後一個重要部分是訓練它! 現在,隨著這篇文章越來越長,我將只介紹以下訓練程式碼的要點(順便說一下,我花了將近一個小時來編寫......我告訴過你我對此是個菜鳥! ) ``` train(inputs, target) { const output = this.propagate(inputs); const errors = new Array(this.outputLen); for (let i = 0; i < this.outputLen; i++) { errors[i] = target[i] - output[i]; for (let j = 0; j < this.inputLen; j++) { this.weights[i][j] += this.learningRate * errors[i] * output[i] * (1 - output[i]) * inputs[j]; } this.bias[i] += this.learningRate * errors[i]; } } ``` “為什麼花了這麼長時間?”我聽到你問了!好吧,它讓我思考了所有需要相乘才能更新每個權重的位元。 另外 `this.learningRate` 也需要一點時間來適應。這只是降低我們改變權重的速率,這樣我們就不會“超過”每個權重的目標值,但是將其調整到合理的值需要經驗......我沒有經驗並且設置得太低,所以我的程式碼看起來被破壞了! 經過一番擺弄後,我將數值定為 0.1(而不是 0.01 🤦🏼‍♂️),突然間事情開始變得更好了! 是的,所以我們有一個訓練函數。但請記住,此訓練功能僅進行一次訓練。 我們需要對我們的網路進行多次訓練,希望每次訓練都能使其更加準確。 我們將在一秒鐘內討論這一點,但我想分享一個快速的側面/我學到的東西。 #### 訓練資料調整 我知道我們甚至還沒有涵蓋最終的訓練資料,但這是我學到的一個有趣的觀點,適合這裡(因為它解釋了為什麼我花了這麼長時間來編寫這個訓練函數)。 最初我產生了數百個不同的訓練 X 和 Y 座標,全部都是隨機的。 但經過進一步閱讀後,我只產生 4 個靜態訓練點,得到了更好的結果: ``` const trainingData = [ { x: -0.5, y: -0.5, label: "blue" }, { x: 0.5, y: -0.5, label: "red" }, { x: -0.5, y: 0.5, label: "green" }, { x: 0.5, y: 0.5, label: "purple" } ]; ``` 一旦你明白了,就很有意義了! 我們希望「拉」值更接近目標,上述值是我們每個區域的確切「中心點」。 因此,對於給定的距離,我們的錯誤率將始終保持一致。 這意味著我們的神經網路學習得更快,因為我們的錯誤率更大,這取決於它們距離 X 更遠還是距離 Y 更遠。 我可以更好地解釋這一點,但這超出了本文的範圍。希望如果您仔細考慮一下,那麼它也會像對我一樣為您「點擊」! 諷刺的是,我回到了更大模型的更隨機的資料集,因為我想真正測試我對學習率、過度訓練等的理解。 ## 我們有一個有效且有用的神經網路! 實際上,這就是我們的整個神經網路。 不過,我們需要做一件事。 我們的訓練函數需要執行很多次! 因此,我們需要最後一個函數來做到這一點,它獲取我們的訓練資料並執行我們的訓練函數數百次: ``` function train() { for (let i = 0; i < 10000; i++) { const data = trainingData[Math.floor(Math.random() * trainingData.length)]; neuralNetwork.train([data.x, data.y], encode(data.label)); } console.log("Training complete"); } ``` ### 金髮女孩迭代 請注意,我們在「for」循環中訓練網路 10,000 次。 10,000 次迭代足以訓練這個特定的神經網路。但對於我們稍後將介紹的更複雜的問題,我需要更多的迭代(並降低學習率)。 這是機器學習有趣的部分之一,您需要足夠地訓練神經網路(這很難做到正確),但如果訓練太多,就會發生“過度擬合”,並且實際上開始得到更糟糕的結果。因此,為了獲得最佳結果,需要完美平衡! 不管怎樣,已經很多了,我們終於迎來了第一個示範! ## 簡單的普通 JS 神經網路演示 雖然有點亂,但我們的神經網路和所有訓練部分都在下面 CodePen 的前 67 行。 其餘程式碼行實際上執行我們的網路(“neuralNetwork.propagate([x, y]);”大約第 85 行),然後將點及其預測顏色輸出到“<canvas>”上。 「encode」和「decode」純粹是為了獲取我們的輸出神經元,找到哪個神經元具有最高的激活,然後將其映射到我們可視化的顏色。 這是最後要理解的事。我們的輸出神經元都會有一個值。神經網路不僅僅輸出 1, 0, 0, 0。 相反,它會輸出每個輸出神經元的「確定性」或猜測。因此我們將得到類似「0.92,0.76,0.55,0.87」的輸出。 這就是為什麼我們有“解碼”函數,它找到最高輸出的神經元並將其作為我們的最終猜測! ``` // this line finds the max value of all of our output neurons and then returns its index so we can use that to classify our X and Y coordinates. const maxIndex = output.indexOf(Math.max(...output)); ``` ### 用法和實際演示 要使用該範例,您有 3 個按鈕: - **訓練** - 在我們的神經網路開始未經訓練和隨機化時對其進行訓練。 - **分類點** - 這是為了執行我們的神經網路。它將在圖表上繪製點並為它們分配顏色。我建議在訓練之前和之後執行這個。 - **重設** - 這將建立一個未經訓練的新神經網路。非常適合在訓練前後測試點的分類。 另請注意,每個區域都根據該區域應顯示的顏色進行著色。它真的可以讓您看到隨機且未經訓練的神經網路距離成功還有多遠(重置然後對測試點進行分類)! 玩吧! https://codepen.io/GrahamTheDev/pen/abPxoqb ### 我們最基本的神經網路結束 這樣我們就有了最基本的神經網路! 它可以很好地滿足我們的需求,並且我們設法了解了一些關於反向傳播(我們在主類別中的“train”函數)以及權重和偏差的知識。 但這是非常有限的。如果我們將來想做更高級的事情,我們需要加入一些隱藏神經元! ## 版本 2 - 隱藏神經元 好的,那為什麼要隱藏神經元呢?他們的目的是什麼? 在更複雜的範例中,它們充當獲取輸入並為它們的分類方式加入更多維度的方式。 我們仍然使用 2 個輸入神經元和 4 個輸出神經元,但這次我們在中間加入了一個附加層(我們可以更改和調整其中神經元的數量)。 所以我們的神經網路看起來像這樣: ![左側 2 個圓圈透過線連接到中間的 6 個圓圈,然後透過線連接到右側的 4 個圓圈。深色背景上的霓虹燈風格。](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z0f1204y2d96wucq6fzv.png) 由於神經網路需要處理更多的輸入並進行更複雜的計算,隱藏層中的額外神經元使它們能夠更好地對輸入進行分類並提供更好的結果。 隱藏層也可以是不同的「深度」。 假設我們有 2 個輸入神經元。我們可以將它們連接到 6 個「隱藏」神經元,然後將它們連接到 4 個輸出神經元。 但我們也可以將第一層的 6 個神經元連結到第二層隱藏神經元。第二層可能有 8 個神經元,然後連接到我們的 4 個輸出神經元。 但要遵循的內容還有很多,這是為了讓我學習基礎知識,所以我選擇加入一個隱藏層。這也意味著我可以將每個連接層保留為單獨的陣列,這在現階段更容易理解! ### 那麼有什麼新內容呢? 沒有太大變化,只是我們有了更多的連結和更多的神經元! 您可以將其視為串聯加入 2 個原始神經網絡,只是第一個神經網路的輸出現在充當第二個神經網路的輸入。 雖然程式碼可能更加複雜,但我們的神經網路遵循相同的原則。 這是程式碼: ``` class NeuralNetwork { constructor(inputSize, hiddenSize, outputSize) { this.inputSize = inputSize; this.hiddenSize = hiddenSize; this.outputSize = outputSize; this.weightsInputToHidden = Array.from({ length: hiddenSize }, () => Array.from({ length: inputSize }, () => Math.random() * 2 - 1) ); this.biasHidden = Array(hiddenSize).fill(0); this.weightsHiddenToOutput = Array.from({ length: outputSize }, () => Array.from({ length: hiddenSize }, () => Math.random() * 2 - 1) ); this.biasOutput = Array(outputSize).fill(0); this.learningRate = document.querySelector('#learningRate').value; // Adjusted learning rate this.hiddenLayer = new Array(this.hiddenSize); } feedForward(inputs) { for (let i = 0; i < this.hiddenSize; i++) { this.hiddenLayer[i] = 0; for (let j = 0; j < this.inputSize; j++) { this.hiddenLayer[i] += this.weightsInputToHidden[i][j] * inputs[j]; } this.hiddenLayer[i] += this.biasHidden[i]; this.hiddenLayer[i] = sigmoid(this.hiddenLayer[i]); } const output = new Array(this.outputSize); for (let i = 0; i < this.outputSize; i++) { output[i] = 0; for (let j = 0; j < this.hiddenSize; j++) { output[i] += this.weightsHiddenToOutput[i][j] * this.hiddenLayer[j]; } output[i] += this.biasOutput[i]; output[i] = sigmoid(output[i]); } return output; } train(inputs, target) { for (let i = 0; i < this.hiddenSize; i++) { this.hiddenLayer[i] = 0; for (let j = 0; j < this.inputSize; j++) { this.hiddenLayer[i] += this.weightsInputToHidden[i][j] * inputs[j]; } this.hiddenLayer[i] += this.biasHidden[i]; this.hiddenLayer[i] = sigmoid(this.hiddenLayer[i]); } const output = new Array(this.outputSize); for (let i = 0; i < this.outputSize; i++) { output[i] = 0; for (let j = 0; j < this.hiddenSize; j++) { output[i] += this.weightsHiddenToOutput[i][j] * this.hiddenLayer[j]; } output[i] += this.biasOutput[i]; output[i] = sigmoid(output[i]); } const errorsOutput = new Array(this.outputSize); const errorsHidden = new Array(this.hiddenSize); for (let i = 0; i < this.outputSize; i++) { errorsOutput[i] = target[i] - output[i]; for (let j = 0; j < this.hiddenSize; j++) { this.weightsHiddenToOutput[i][j] += this.learningRate * errorsOutput[i] * output[i] * (1 - output[i]) * this.hiddenLayer[j]; } this.biasOutput[i] += this.learningRate * errorsOutput[i]; } for (let i = 0; i < this.hiddenSize; i++) { errorsHidden[i] = 0; for (let j = 0; j < this.outputSize; j++) { errorsHidden[i] += this.weightsHiddenToOutput[j][i] * errorsOutput[j]; } this.biasHidden[i] += this.learningRate * errorsHidden[i]; for (let j = 0; j < this.inputSize; j++) { this.weightsInputToHidden[i][j] += this.learningRate * errorsHidden[i] * this.hiddenLayer[i] * (1 - this.hiddenLayer[i]) * inputs[j]; } } } } ``` 現在,不要被嚇倒,我剛剛複製了幾個循環,其中要操作的目標資料集略有不同。 我們加入了一組額外的偏差(對於我們的隱藏層)和一組額外的連接:我們的輸入層到我們的隱藏層,然後我們的隱藏層現在連接到我們的輸出層。 最後,我們的「train」函數有一些額外的循環,只是為了透過每個步驟進行反向傳播。 唯一值得一提的其他變化是我們現在有第三個輸入參數(中間),用於隱藏神經元的數量。 ### 醜陋,但似乎有用 看,我想再說一遍,這是我一邊學習一邊學習,所以程式碼反映了這一點。 這裡有很多重複,可擴展性不太好。 然而,據我所知,它是有效的。 話雖如此,雖然它有效,但它的性能似乎比我們原來的、簡單得多的神經網路要差。 這要么意味著我犯了一個錯誤(可能),要么是我沒有「撥入」正確的訓練設定。 說到這裡... ### 加入一些變數來玩 由於這更複雜,我在一些快速設定中「迴避」了。 現在我們可以更新: - **訓練資料大小** - 我們產生的不同隨機點的數量 - **訓練迭代** - 我們從訓練集中選擇隨機資料點並將其輸入神經網路上的「訓練」函數的次數。 - **學習率** - 我們根據錯誤調整速度的乘數。 - **隱藏節點(超過2個!)** - 調整第二層有多少個隱藏節點(需要您再次初始化網絡,否則會損壞!) - **要分類的點** - 傳遞給我們訓練過的神經網路並繪製在圖表上的點數。 這意味著我們可以更快地處理這些值,看看它們對我們的神經網路及其準確性有什麼影響! ### 最後一件事 哦,我加入了一個按鈕來視覺化神經網路的樣子。 無論如何按“可視化神經元和權重”,但它還沒有完成。我也沒有立即完成它的打算,因為我想完全重新設計建構神經網路的方法,使其更具可擴展性。 不過,按鈕就在那裡,請隨意按下。更好的是,請隨時為我修復它! 🤣💗 ## 演示 控制項與以前相同,加上前面 2 個小節中提到的輸入。 試試一下,看看是否可以微調學習率、神經元數量和訓練設定以獲得真正準確的結果! https://codepen.io/GrahamTheDev/pen/qBLwBxP 請務必更新一些值,重新初始化神經網絡,嘗試使用不同數量的隱藏神經元等。 如果您像我一樣是初學者,希望您能開始理解一些事情! ## 結論 用 vanilla JS 建立神經網路真的很有趣。 我沒有見過很多人這樣做,所以我希望它對你或至少對某人有用! 我學到了很多關於偏差、反向傳播(神經網路的關鍵)等的知識。 顯然這個例子和這裡學到的東西只是機器學習的1%。但對於像我這樣的微小的、未優化的神經網路和巨大的數十億參數模型來說,核心原理是相同的。 這個例子就像機器學習 (ML) 和神經網路的「hello world」。 接下來,我真的想嘗試建立一個更大的、結構更好、更容易擴展的神經網絡,看看我們是否可以進行一些光學字元辨識(OCR)。您可以將其視為機器學習和神經網路的“待辦事項清單”! ### 發表評論。 您是神經網路專家嗎?告訴我我哪裡錯了! 你是像我一樣的初學者嗎?那麼請告訴我這是否有助於您理解,至少一點點!或者,如果這實際上讓事情變得更加混亂! 😱 最重要的是,如果這篇文章激發了您對我糟糕的編碼做鬼臉,或者想要建置您自己的神經網絡......那麼我很高興它對您產生了一些影響,並且很樂意聽到它! 💗 --- 原文出處:https://dev.to/grahamthedev/a-noob-learns-ai-my-first-neural-networkin-vanilla-jswith-no-libraries-1f92

最受軟體開發人員推薦的 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

如何將 async/await 與 map 和 Promise.all 一起使用

原文出處:https://dev.to/jamesliudotcc/how-to-use-async-await-with-map-and-promise-all-1gb5 我發現自己一直在使用帶有 async 和 await 的 map 函數。我需要重新學習如何使用 Promise 來解決這個問題,但是一旦我解決了這個問題,語法就變得非常漂亮且可讀。 JavaScript 的 async 和 wait 語法是 ES2017 中的新語法。我認為語法非常簡潔,因為它允許我編寫比承諾金字塔更短、更容易理解的程式碼,類似於承諾是回調地獄的改進。 但是當你想從一堆請求中取回一堆資料時會發生什麼? JavaScript 中沒有「await all」。這就是 `Promises.all()` 的用武之地。Promises.all() 收集一堆 Promise,並將它們匯總成一個 Promise。一旦所有內部承諾成功解決,Promise.all() 將返回已解決的承諾,其中所有內部承諾都已解決。為了讓事情變得更快,一旦任何內部 Promise 被拒絕,Promise.all() 就會拒絕。 重點是 Promise.all() 將一系列 Promise 轉換為單一 Promise,如果正常的話,它會解析為您想要的陣列。其他一切都只是細節。 不知何故,我花了很長時間才擺脫困境。這是我最終開始工作的程式碼,希望這有助於解釋。 假設您點擊一個 REST 端點並取得 REST 端點的 URL 陣列,其中包含您最終想要的內容。例如,您想從 Star Wars API 中找到有關電影 R2-D2 的一些資訊。無論出於何種原因,您都不能使用 SWAPI GraphQL。我們知道從網路取得是一個非同步操作,因此我們必須使用回呼、promise 或 async 和await 關鍵字。由於 R2-D2 出現在多部電影中,因此需要多次網路呼叫才能獲取所有電影。 首先,讓我們進行設定。讓我們只專注於我們正在開發的最小功能,因此我們將在命令列上使用 Node.js。 Node.js 沒有附帶 fetch,所以讓我們使用 npm 或 YARN 來安裝它。 ``` npm install node-fetch --save-dev ``` 或者 ``` yarn add node-fetch --dev ``` async/await 的一個問題是,await 關鍵字只允許在 async 函數內部使用。在真實的程式中,您可能已經進行了足夠的封裝,以便您可以在使用await關鍵字的函數上新增async關鍵字,但在臨時檔案中,我們希望從封閉的上下文中抽像出來。但作為 Javascript 程式設計師,我們知道如何透過將我們想要的內容包裝在即時呼叫的函數表達式中來解決這個問題。 ``` // prettier-ignore const fetch = require('node-fetch') // prettier-ignore (async () => { try { let characterResponse = await fetch('http://swapi.co/api/people/2/') let characterResponseJson = await characterResponse.json() console.log(characterResponseJson) } catch (err) { console.log(err) } } )() ``` 現在我們已經有了基本的 async/await 語法,我們可以檢查回應以查看我們想要的電影欄位。它是一個 URL 陣列。 ``` let films = characterResponseJson.films.map(async filmUrl => { let filmResponse = await fetch(filmUrl) let filmResponseJSON = filmResponse.json() return filmResponseJSON }) console.log(films) ``` 當您執行此程式碼時,您會得到一組待處理的承諾。您需要新的“async”,否則箭頭函數內的等待將無法工作。如果你不「等待」獲取,你會得到一堆被拒絕的承諾,並且錯誤告訴你處理你的承諾拒絕。 但回想一下,「Promise.all()」接受一組 Promise 並將它們包裝成一個 Promise。所以我們包裝我們的“map”函數。我們已經知道一些處理單一 Promise 的好語法。我們可以‘等待’。 ``` let characterResponse = await fetch('http://swapi.co/api/people/2/') let characterResponseJson = await characterResponse.json() let films = await Promise.all( characterResponseJson.films.map(async filmUrl => { let filmResponse = await fetch(filmUrl) return filmResponse.json() }) ) console.log(films) ``` 為了進行比較,promise 中的等效程式碼如下所示: ``` fetch('http://swapi.co/api/people/2/') .then(characterResponse => characterResponse.json()) .then(characterResponseJson => { Promise.all( characterResponseJson.films.map(filmUrl => fetch(filmUrl).then(filmResponse => filmResponse.json()) ) ).then(films => { console.log(films) }) }) ``` 對我來說,第一組 `.then().then()` 非常語意化,我幾乎可以遵循 async/await 文法。但是一旦我們進入“Promise.all()”,僅使用 Promise 語法事情就開始變得難以遵循。無論我們要對影片執行什麼操作,都將取代“console.log”,並且在“.then”連結語法中,它已經埋藏了 3 級縮排。淺層程式碼是易於理解的程式碼。

40 個免費 HTML 登陸頁面模板

原文出處:https://dev.to/davidepacilio/40-free-html-landing-page-templates-3gfp 這樣你的產品就已經準備好了。您花了幾週的時間尋找要解決的正確問題,幾個月甚至幾年的時間開發出一個出色的解決方案來減輕客戶的痛苦,現在只缺少一件事:您幾乎準備好啟動- 您需要一個登陸頁。 即使您想銷售線上服務、電子書或數位課程,登陸頁面對於幫助您根據特定目標實現預期結果也至關重要,因此值得花一些時間找出您真正需要的東西來把它做好。 不幸的是,建立登陸頁面既困難又耗時:結構、設計、圖像、副本等等。這是極其艱難的。 好訊息是 - 您不必從頭開始設計著陸頁,並且有這麼多**免費著陸頁模板**,您可以立即輕鬆建立一個漂亮的著陸頁,從而節省開發時間您可以投資為您的企業創造正確的資訊. 我花了幾個小時研究並找到最好的免費 HTML 登陸頁面模板,結果,我列出了 **40 個漂亮的模板**,您可以將它們用於多種目的、工具和專案。例如: - 開源專案 - 數位服務、電子書和線上課程 - 時事通訊 - SaaS產品 - 行動應用程式 以下列表中的所有模板都是 100% 免費,由不同團隊和作者精心製作,並使用 HTML5 和 Bootstrap 建立。享受閱讀的樂趣,並隨意將它們用於您想要的任何用途。 ###1。 **Solid** ![實體範本](https://dev-to-uploads.s3.amazonaws.com/i/bqh7szmq6e917xfa1lod.jpg) **[現場示範與下載](https://cruip.com/demos/solid/)** Solid 是一款單頁登陸頁面模板,專為線上工具、SaaS 產品和數位服務而設計。它採用 HTML5 建置,具有現代時尚的深色外觀、明亮的互補調色板、3D 圖標/插圖,並且經過明智的編碼和記錄,因此您不必擔心根據您的特定需求自訂模板,目的。 **附加功能:** - 易於調整的英雄佔位符 - 多功能和多用途的圖像 - 即用型定價選項卡 --- ###2。 **Switch** ![切換模板](https://dev-to-uploads.s3.amazonaws.com/i/019rgq3i9ml7i9uye9kn.jpg) **[現場示範及下載](https://cruip.com/demos/switch/)** Switch 是一款免費的 HTML 登陸頁面模板,以高設計標準和回應效能為理念建置。之所以稱為Switch,是因為它配備了頂級英雄切換開關,可讓您輕鬆在深色和淺色佈局之間切換,因此您可以透過展示真正原創的外觀和感覺來給用戶留下深刻印象,靈感來自於一天中變化的天空。 **附加功能:** - 基於向量的多色形狀 - 透視應用程式設計模型 - 行動優先的內容 --- ###3。 **SaaS 應用程式** ![SaaS 範本](https://dev-to-uploads.s3.amazonaws.com/i/y90d0mmoao3f3r5ooo46.jpg) **[現場示範及下載](https://grayic.com/preview/?demo=saas-app)** SaaS 應用程式是一個免費的 Bootstrap 4 登陸頁面模板,具有有趣且友善的配色方案。它旨在為多種 SaaS 相關軟體和服務提供服務,如果您需要一套現代的現成人類插圖、現代圖像、定價元件和用於捕獲電子郵件地址的文本表單,那麼特別推薦它。 **附加功能:** - 現代與當代繪畫 - 大量現成的部分 - 專為不同用途和產品設計 --- ###4。 **April** ![四月範本](https://dev-to-uploads.s3.amazonaws.com/i/qf0s75h00guuuq0v8w42.jpg) **[現場示範及下載](https://cruip.com/demos/april/)** April 擁有簡單的佈局和強大的自訂選項,適合每個需要美觀、響應式元件用於其專案或時事通訊服務的人。透過流暢的導航和一組有價值的編碼元素,如果您需要顯示應用程式功能、客戶評價以及頂部英雄部分的真實產品預覽,則該模板可以滿足您的需求。 **附加功能:** - 現代與當代繪畫 - 大量現成的部分 - 專為不同用途和產品設計 --- ###5。 **數位服務** ![數位服務範本](https://dev-to-uploads.s3.amazonaws.com/i/0uybxsxod2mrynn8hlfw.jpg) **[現場演示和下載](https://grayic.com/preview/?demo=digital-service)** 數位服務是一種響應式登陸頁面模板,旨在幫助您快速輕鬆地展示您的行動應用程式或線上狀態。它基於 Bootstrap 4,並附帶大量預先設計的部分,例如砌體推薦、定價表、輸入表單、三列功能部分等等。最後但並非最不重要的一點是,其設計的多功能性使該模板成為支援多個利基市場的完美選擇。 **附加功能:** - 測試應用程式原型的理想選擇 - 優雅且開源的圖像 - 適用於產品和線上服務 --- ###6。 **Venus** ![維納斯範本](https://dev-to-uploads.s3.amazonaws.com/i/d56saxazri538scb53y8.jpg) **[現場示範與下載](https://cruip.com/demos/venus/)** Venus 是一個免費的單頁登陸頁面模板,基於預先建置的設計部分和 HTML5。它遵循響應式設計的最新最佳實踐,並且由於存在多個可編輯的行動應用程式佔位符、手工製作的向量插圖、Google 字體、社交媒體圖標和完全可編輯的顏色產品調色板,因此非常容易定制。 **附加功能:** - 頁面恆星動畫 - 靈活的佈局和內容設計 - 在任何裝置上都能完美執行 --- ###7。 **艾莉** ![艾莉模板](https://dev-to-uploads.s3.amazonaws.com/i/jnfdnoel1gbg4qnnkdux.jpg) **[現場示範及下載](https://cruip.com/demos/ellie/)** 使用這個深色、明亮且緊湊的免費模板建立漂亮的登陸頁面並開始收集時事通訊訂閱者。有了 Ellie,只需不到 5 個步驟就可以讓您的產品脫穎而出,並且憑藉頂級英雄動畫和像素完美形狀的組合,您將永遠不會讓存取者在再次滾動到正文部分之前跳動。 **附加功能:** - 動態英雄過渡 - 內建示範功能 - 技術和廣泛的調色板 --- ###8。 **軟體** ![軟體範本](https://dev-to-uploads.s3.amazonaws.com/i/qn4taou9lhy4ona0583l.jpg) **[現場示範及下載](https://grayic.com/preview/?demo=software)** 使用Berlin 輕鬆建立自訂且高度適應性的應用程式網站,這是一個免費的Bootstrap 4 登陸頁面模板,專為SaaS 專案建置,並且希望將更多潛在客戶轉化為客戶,並相信精心設計的登陸頁面可以在一個普通的產品和一個公認的國際軟體品牌。 **附加功能:** - 動態隨機產生的內容 - 智慧餐桌選項 - 影片示範部分 --- ###9。 **勞雷爾** ![月桂模板](https://dev-to-uploads.s3.amazonaws.com/i/42ox85g1o989no5tnkum.jpg) **[現場示範與下載](https://cruip.com/demos/laurel/)** Laurel 是一個基於最新版本 HTML5 的大膽而美麗的登陸模板,它將幫助您美麗而優雅地展示您的行動應用程式。功能方面,此範本附帶了 Sass 檔案、作為建置工具的 NPM 腳本以及 package.json 範例檔案。在設計方面,所有資產都是為了提供無盡而甜蜜的客製化選項而建造的。 **附加功能:** - 記錄良好的程式碼文件 - 即將推出的功能更新 - 完整的利基應用程式模板 --- ###10。 **棱鏡** ![棱鏡模板](https://dev-to-uploads.s3.amazonaws.com/i/0wrh4kf9zyeipjujmlro.jpg) **[現場示範](https://webresourcesdepot.com/demo/prism/)** / **[下載](https://webresourcesdepot.com/freebie/prism/)** Prism 是一款輕量級、現代的免費模板,專為使用 Bootstrap 4、CSS、HTML 和 JavaScript 的開源專案而建置。使用者喜歡 Prism,因為它使用起來非常簡單,修改起來非常直觀,並且它涵蓋了任何人都可以從具有此類設計和功能特徵的登陸頁面中期望的大多數元素。 **附加功能:** - SEO專用設計 - 評論良好的程式碼 - 創意一頁版面 --- ###11。 **Web應用程式** ![Web 應用程式範本](https://dev-to-uploads.s3.amazonaws.com/i/rzuf0mbk2sm0s790as2n.jpg) **[現場示範及下載](https://grayic.com/preview/?demo=web-app)** Web 應用程式是建立簡單HTML 登入頁面的最佳方式,可以幫助您吸引使用者使用下一個出色的Web 應用程式或桌面應用程式- 得益於詳細列出的功能部分、功能性幻燈片客戶以及引人入勝的號召性用語,Web 應用程式應用程式可以輕鬆快速地設定一個有吸引力的獨立頁面,以滿足不同的需求、範圍。 **附加功能:** - 有吸引力的按鈕和表格 - 終極 HTML 功能 - 不同的演示版本 --- ###12。 **騎士** ![騎士模板](https://dev-to-uploads.s3.amazonaws.com/i/ulo57e43t9f6d4uidrgc.jpg) **[現場示範](https://webresourcesdepot.com/demo/knight/)** / **[下載](https://webresourcesdepot.com/freebie/knight/)** 身為黑夜中的勇敢騎士,Knight是一款專為產品登陸頁面設計的深色、現代、優雅的Bootstrap 4登陸頁面模板。它配備了 Feather & Font Awesome 圖示、光滑的滑桿、常見問題清單等福利。 Knight 使用 HTML5、CSS3、jQuery 和 Sass 建置,保證了令人難以置信的響應性能和流暢的自訂選項。 **附加功能:** - 出色的 UI/UX 和資產文件 - 自動調整影像大小 - 免費無限支持 --- ###13。 **開發手冊** ![DevBook 範本](https://dev-to-uploads.s3.amazonaws.com/i/rzp0mc2lqavn08v3bzf7.jpg) **[現場示範](https://themes.3rdwavemedia.com/demo/devbook/)** / **[下載](https://themes.3rdwavemedia.com/bootstrap-templates/product/devbook-free-bootstrap-4-book-ebook-landing-page-template-for-developers/)** DevBook 是一個免費的 Bootstrap 4 書籍登陸頁面模板,專為想要在線上推廣或銷售書籍/電子書的開發人員和程式設計師而設計。它包含吸引好奇的訪客成為潛在讀者的所有基本元素,並且由於它是完全客製化開發的,因此您可以輕鬆地將其與 Gumroad 等平台集成,它將代表您處理購買和付款。 **附加功能:** - 與現代瀏覽器相容 - 免費書籍模型 - 多個可用許可證 --- ###14。 **有** ![Tivo 範本](https://dev-to-uploads.s3.amazonaws.com/i/gojb4bkb00vdk73kjmu3.jpg) **[現場示範](https://inovatik.com/tivo-landing-page/index.html)** / **[下載](https://inovatik.com/tivo-free-saas-app-登陸頁模板.html)** Tivo 是一款使用 HTML5 製作的免費應用程式登陸頁面模板,經過精確建立,可支援建立有吸引力的軟體即服務 (SaaS) 網站和 B2C 應用程式頁面。對於任何尋求簡單下拉導航、文章詳細資訊、視訊框、文字滑桿推薦以及允許製作無限數量的個人和商業專案的易於使用的許可證的人來說,Tivo 是一個智慧解決方案。 **附加功能:** - 功能聯繫表 - 谷歌字體和 Font Awesome - 在每個瀏覽器中經過全面測試 --- ###15。 **光滑** ![光滑模板](https://dev-to-uploads.s3.amazonaws.com/i/vmig768208lulvcgwoxf.jpg) **[現場示範](https://preview.uideck.com/items/slick/business/index.html)** / **[下載](https://uideck.com/templates/slick-free-引導模板/)** Slick 是一個基於 Bootstrap 4 和 HTML5 的免費原創多用途網頁模板。 Slick 提供卓越的設計技術和最佳的 UI/UX 實踐,可在任何類型的數位裝置(例如桌上型電腦、平板電腦和行動裝置)上提供出色的體驗。它為基於網路的軟體產品和行動應用程式提供了兩種不同的主頁變體。 **附加功能:** - CSS 庫和線條圖標 - 超豐富的排版 - 條紋設計靈感 --- ###16。 **線上課程** ![線上課程範本](https://dev-to-uploads.s3.amazonaws.com/i/g0qev01qthm9vxzt9ybn.jpg) **[現場示範及下載](https://grayic.com/preview/?demo=online-course)** 線上課程是一個免費的 HTML 登陸頁面模板,它為您提供建立業務和透過建立和銷售線上課程創造收入所需的一切。使用線上課程模板,您可以快速設定市場上排名第一的使用者體驗設計課程,並且由於有用元素的巨大變體,您可以支援隨時存取線上課程、視訊課程和複習系統。 **附加功能:** - 功能課程課程 - 常見問題部分 - 多種內容呈現 --- ###17。 **聯盟** ![聯合模板](https://dev-to-uploads.s3.amazonaws.com/i/egjsxv0o22v8mmvkgujt.jpg) **[現場示範](https://webresourcesdepot.com/demo/union/)** / **[下載](https://webresourcesdepot.com/freebie/union/)** Union 是一個免費的登陸頁面,可以幫助您更快、更輕鬆地建立漂亮的響應式 HTML 網站。 Union 受到數千名滿意用戶的信賴,提供10 多種不同的配色方案、有序的Sass 檔案(用於快速自訂)、有吸引力的圖像,對於尋求具有多個可編輯元件的高效能一頁的創意團隊來說,它是理想的選擇。 **附加功能:** - 有效且手寫的程式碼 - 漂亮流暢的滾動 - 預先整合和功能形式 --- ###18。 **行動應用2.0** ![行動應用程式 2.0 範本](https://dev-to-uploads.s3.amazonaws.com/i/y9op3tx00u09iiutd2c3.jpg) **[現場示範及下載](https://grayic.com/preview/?demo=mobile-app-2-0)** Mobile App 2.0 是一款免費的行動應用模板,專為行動應用程式、新創公司、產品開發公司和特別注重用戶獲取的企業而設計。行動應用程式 2.0 為您提供了詳細記錄的設置,可讓您在 3 分鐘內完成設置並執行,並且不會影響輕鬆頁面佈局的可能性。 **附加功能:** - 基於向量的氣泡形狀 - 帶有畫廊截圖的滑塊 - 不同的演示類型 --- ###19。 **阿特拉斯** ![圖集範本](https://dev-to-uploads.s3.amazonaws.com/i/wayb6z44rhjris7xo79v.jpg) **[現場示範](https://www.lapa.ninja/lab/atlas/)** / **[下載](https://www.lapa.ninja/freebies/atlas/)** Atlas 是一個響應靈敏且高度可自訂的啟動登陸頁面,提供許多出色的功能,例如推廣 SaaS、聯繫我們部分、優雅的英雄、定價標籤、手工製作的圖標和產品功能。借助 Atlas,您只需點擊幾下即可快速建立任何登陸頁面,並且使用 Bootstrap Framework,您還可以匯入自己喜歡的元件。 **附加功能:** - 版面安全可靠 - 最多 15 個文件 - 清新的佈置配色方案 --- ###20。 **簡單的** ![簡單範本](https://dev-to-uploads.s3.amazonaws.com/i/3el75t5hah5e6uv3oar8.jpg) **[現場示範](https://www.bootstrapdash.com/demo/simple/)** / **[下載](https://www.bootstrapdash.com/product/simple-landing-page/) ** Simple 是一款乾淨友善的單頁登陸頁面模板,旨在以現代且豐富多彩的外觀為您的用戶留下深刻印象。簡單的登陸頁面具有美觀整潔的設計,是展示您的早期新創公司、線上服務和數位產品的理想選擇。此範本具有創意和獨特的設計、人體插圖、像素完美的圖標以及一組預先建立的元素,可輕鬆呈現主要應用程式功能和優點。 **附加功能:** - 定期更新和改進 - 麻省理工學院許可 - 快速和友好的支持 --- ###21。 **幻影** ![幻像範本](https://dev-to-uploads.s3.amazonaws.com/i/c56b1ycw4i87isqaz16e.jpg) **[現場示範](https://webresourcesdepot.com/demo/phantom/)** / **[下載](https://webresourcesdepot.com/freebie/phantom/)** Phantom 是一款富有創意且現代的 Bootstrap 4 登陸頁面模板,專為想要為其副專案和開源工具建立快速、新穎的登陸頁面的開發人員而建置。此範本提供了獨特且利基的佈局,您可以立即適應自己的需求,並提供大量精心製作和組織的高品質編碼元素。 **附加功能:** - 響應靈敏並與現代設備相容 - 設計中包含螢幕截圖 - 可重複使用的元件 --- ###22。 **新的** ![Nova 範本](https://dev-to-uploads.s3.amazonaws.com/i/5hm4f3hxb7bwchtcg7p7.jpg) **[現場示範](https://demo.bootstraptemple.com/app-landing/)** / **[下載](https://bootstrapious.com/p/app-landing-page)** Nova 是由 HTML5 和 Bootstrap 4 提供支援的響應式專業行動應用程式登陸頁面。Nova 是一款功能強大且超級靈活的產品,非常適合各種應用程式登陸頁面。對於每個尋求新鮮的線上形像以及與通常的網站演示不同的東西的人來說,該模板是一個完美的解決方案。 **附加功能:** - 龐大且可變的元素庫 - 無需歸屬 - 可用於個人和商業專案 --- ###23。 **紗羅** ![Leno 範本](https://dev-to-uploads.s3.amazonaws.com/i/s8rmxzr5044hu6d2okm1.jpg) **[現場示範](https://inovatik.com/leno-landing-page/index.html)** / **[下載](https://inovatik.com/leno-free-mobile-app-登陸頁模板.html)** Leno 是一款免費的深色行動應用程式 HTML 登陸頁面,使用 HTML、CSS 和 Javascript 建置。這個引人注目的模板具有一個帶有佔位符大預覽的圖像滑塊、一個用於客戶推薦的動態輪播以及一組附加頁面,其中包括聯繫表單部分,潛在客戶可以在其中輕鬆聯繫您詢問或提出問題。 **附加功能:** - 經過 W3C 有效程式碼測試 - 動畫統計資料和數字 - GDPR 友善設計 --- ###24。 **折斷** ![快照範本](https://dev-to-uploads.s3.amazonaws.com/i/00qaht3st5sdfahj83e7.jpg) **[現場示範](https://webresourcesdepot.com/demo/snap/)** / **[下載](https://webresourcesdepot.com/freebie/snap/)** Snap 是建立展示實用程式應用程式的美觀登陸頁面的最快方法。透過 Snap,您將獲得現代網站以正確方式展示其功能所需的所有必要頁面和部分。其中一些功能包括定價標籤、支援部分、桌面佔位符、福利圖塊以及用於顯示用戶評論的輪播。 **附加功能:** - 企業數位化解決方案 - 靈活的主頁變化 - 在不同的行動裝置上進行測試 --- ###25。 **埃沃洛** ![Evolo 範本](https://dev-to-uploads.s3.amazonaws.com/i/dgkev9n9d0jiu0kri0ha.jpg) **[現場示範](https://inovatik.com/evolo-landing-page/index.html)** / **[下載](https://inovatik.com/evolo-free-startup-landing-頁面模板.html)** Evolo 是一個清新迷人的登陸頁面模板,專為各種線上服務和數位產品而設計。由於 Evolo 建立在靈活的元件之上,因此如果您希望輕鬆建立無限數量的附加頁面,Evolo 是一個很好的伴侶。該模板還提供了一系列支援元素,可以整合這些元素以方便地建立一個全新的網站。 **附加功能:** - 合作夥伴螢幕截圖滑桿 - 支援的專案數量不受限制 - 圖像檔案和文字標誌選項 --- ###26。 **基本的** ![基本範本](https://dev-to-uploads.s3.amazonaws.com/i/h9f4dfaztpi44njq48ek.jpg) **[現場示範](https://preview.uideck.com/items/basic/)** / **[下載](https://uideck.com/templates/basic/)** Basic 是在 Bootstrap 4 和 HTML5 之上開發的軟體和 SaaS 登陸頁面範本。此範本包含新創公司快速展示數位產品所需的所有基本元素。基本它是完全響應式的,透過多個區塊進行編碼,而且它非常靈活,以至於增加 Bootstrap 4 的基本元件變得前所未有的容易。 **附加功能:** - 提供免費和專業功能 - 刪除頁腳積分 - 包含文件 --- ###27。 **快的** ![快速範本](https://dev-to-uploads.s3.amazonaws.com/i/ymv9q8a18jnp2fl2gcaj.jpg) **[現場示範](http://themehunt.com/item/1527640-quick-free-bootstrap-4-theme/preview)** / **[下載](https://themehunt.com/item/1527640-quick-free-bootstrap-4-theme)** Quick 是一個免費的 HTML 登陸頁面,專為行動優先專案、新創公司和數位服務而建置。此範本包含 50 多個預先建置元件、2 個有用的外掛程式和 4 個設計精美的響應式頁面。 Quick 是一個不斷改進的模板,每次新更新都會獲得額外的功能和 UI 元件,以取悅使用者。 **附加功能:** - 提供影片示範 - 智慧程式碼標記 - 包括 NPM 和 Gulp 等熟悉的工具。 --- ###28。 **開發援助** ![devAid 範本](https://dev-to-uploads.s3.amazonaws.com/i/3m3v5mwf9vd3jx0ptfny.jpg) **[現場示範](https://themes.3rdwavemedia.com/demo/devaid/)** / **[下載](https://themes.3rdwavemedia.com/bootstrap-templates/startup/devaid-free-bootstrap-theme-for-developers-side-projects/)** devAid 是一個乾淨的 Bootstrap 模板,非常適合幫助程式設計師展示他們的個人專案和開源產品。此範本配有 4 種不同的配色方案、來源 SCSS 文件,可輕鬆執行樣式自訂,並提供大量額外元素,可根據登陸所包含的工具立即調整內容。 **附加功能:** - 經典的標題版面 - 超快載 - 基於流行的前端框架 --- ###29。 **棉花糖** ![棉花糖模板](https://dev-to-uploads.s3.amazonaws.com/i/it03dy8e17dnco3ya9lo.jpg) **[現場示範](https://www.bootstrapdash.com/demo/marshmallow/)** / **[下載](https://www.bootstrapdash.com/product/marshmallow/)** Marshmallow 是一個 HTML 登陸頁面模板,專為各種類型的 SaaS 產品、新創公司和應用程式展示而設計。該模板 100% 響應,在所有類型的設備上看起來都令人驚嘆。 Marshmallow 具有設計精美的元素和內頁,讓您的網站看起來安全且專業。 **附加功能:** - 提供功能輪播 - 動態網站統計和數字 - 獨立的圖像和插圖 --- ###30。 **阿普蘭** ![Appland 範本](https://dev-to-uploads.s3.amazonaws.com/i/kz7x1n3i7zvlp9jrw3bs.jpg) **[現場示範](https://preview.uideck.com/items/appland/)** / **[下載](https://uideck.com/templates/appland/)** Appland 是一款免費、優雅的登陸頁面模板,專為應用程式登陸、軟體和線上工具而建立。 Appland 功能強大,具有原始設計和新創公司從頭開始建立引人注目的登陸頁面所需的所有必要元素,具有預先建立的佈局視圖和無限的創意可能性。 **附加功能:** - 專為不同目的而設計 - 包括所有基本功能和元素 - 令人驚嘆的動畫英雄部分 --- ###31。 **SEO公司** ![SEO 公司範本](https://dev-to-uploads.s3.amazonaws.com/i/l900p6nf3650bqke632j.jpg) **[現場示範](https://demos.onepagelove.com/html/seo-company/)** / **[下載](https://onepagelove.com/seo-company)** SEO Company 是一款免費且優雅的單頁 HTML 模板,專為數位團隊設計,旨在建立乾淨且令人驚嘆的登陸頁面來展示其線上服務。在功能方面,此模板呈現出獨特的設計、有吸引力的平滑過渡、移動觸控滑桿以及一組充分混合的高級元素,以最大限度地提高轉換率。 **附加功能:** - 包含 PSD 範本和文件 - 直接下載 - 乾淨的鋸齒形特徵 --- ###32。 **炫** ![Dazzle 範本](https://dev-to-uploads.s3.amazonaws.com/i/874afgq81sb9nqmh2p6w.jpg) **[現場示範](https://demos.onepagelove.com/html/dazzle/)** / **[下載](https://onepagelove.com/dazzle)** Dazzle 是一款響應式單頁模板,具有視差滾動佈局,旨在提供平滑的外觀和無限的自訂可能性。 Dazzle 的設計和開發考慮了最新的設計趨勢,並經過最佳化以包含所有基本元素,為幾乎所有可能的場合建立具有視覺吸引力的頁面。 **附加功能:** - 平滑滾動到各個部分 - 應用程式概述部分 - 推薦滑桿和下載按鈕 --- ###33。 **新時代** ![新時代模板](https://dev-to-uploads.s3.amazonaws.com/i/hmdc6gzpcai262bgx65z.jpg) **[現場示範](https://startbootstrap.com/previews/new-age/)** / **[下載](https://startbootstrap.com/themes/new-age/)** New Age 是一個應用程式登陸頁面模板,它將幫助您以絕對的快樂和平靜的心態精美地展示您的新行動應用程式或其他任何內容。該模板具有不同的免費使用 HTML/CSS 設備佔位符、帶有滾動動畫的定制導航以及帶有導航、部分和旁白的語義標記。由於其大膽、多彩且時尚的外觀,New 是您下一個基於應用程式的專案的優秀樣板! **附加功能:** - 帶有滾動過渡的菜單 - 不同的按鈕樣式 - CSS 漸層與紋理和覆蓋 --- ###34。 **登陸頁** ![登陸頁範本](https://dev-to-uploads.s3.amazonaws.com/i/ikvoesq8mv52mxagi37h.jpg) **[現場示範](https://startbootstrap.com/previews/landing-page/)** / **[下載](https://startbootstrap.com/themes/landing-page/)** 登陸頁面是適用於HTML5 和Bootstrap 4 的響應式登陸頁面模板。即使對於非技術用戶來說,登陸頁面也可以輕鬆建立引人注目的網路形象,並且透過其詳細的修飾,您會發現可以更改任何模板部分或元素小菜一碟。在功能方面,此範本包括一個帶有響應式背景圖像的輸入表單選擇標題,以及展示應用程式功能和優點的豐富內容部分。 **附加功能:** - 包括簡單的線條圖標 - 動態內容部分 - 響應式背景圖片 --- ###35。 **即將推出** ![即將推出範本](https://dev-to-uploads.s3.amazonaws.com/i/agexcg1run49mcy1fxum.jpg) **[現場示範](https://startbootstrap.com/previews/coming-soon/)** / **[下載](https://startbootstrap.com/themes/coming-soon/)** 如果您正在開發令人興奮的新產品,並且需要開始圍繞它建立受眾群體,「即將推出」範本將幫助您在幾分鐘內輕鬆建立令人驚嘆的發布前登陸頁面。即將推出是透過優雅的即用型產品吸引早期客戶的理想解決方案,並且由於它是為多種目的而設計的,因此您不需要進行大量的客製化工作來根據您的特定目的和需求調整內容。 **附加功能:** - 移動後備影像 - 電子郵件訂閱者選擇加入輸入 - 實用的影片背景 --- ###36。 **SaaS 訂閱** ![SaaS 訂閱](https://dev-to-uploads.s3.amazonaws.com/i/4m892kjw7iaq57xnq3xv.jpg) **[現場示範及下載](https://grayic.com/preview/?demo=saas-sub)** 您的 SaaS 模型應基於您的產品提供的價值,不同的價值類型需要不同類型的訂閱。 SaaS 訂閱是完美的 HTML 登陸頁面模板,可協助您取得新使用者並將早期訪客轉化為潛在客戶。該模板具有幾個漂亮的圖形和預先建立的部分,並且只需較低的程式碼技能即可輕鬆編輯。 **附加功能:** - 可切換的定價選項 - 工作聯絡表 - 無限的定制可能性 --- ###37。 **開發空間** ![開發空間](https://dev-to-uploads.s3.amazonaws.com/i/yy2bsudpfbor7nlf4xsi.jpg) **[現場示範與下載](https://www.lapa.ninja/lab/dev-space)** Dev Space 是一款非常實用且設計精美的登陸頁面模板,專為應用程式開發顧問服務而製作。此範本建立在可靠的基礎設施之上,其中包括全面的內部工具、幾個免費的流線型圖示、豐富的插圖包以及高效且易於維護的記錄良好的程式碼。 **附加功能:** - 預先設計的標誌雲 - 認識我們的團隊部分 - 互動的現代運用 --- ###38。 **降落** ![登陸](https://dev-to-uploads.s3.amazonaws.com/i/qrtbv9hzuebkbrymw7cl.jpg) **[現場示範](https://www.tailwindtoolbox.com/templates/landing-page-demo.php) / [下載](https://www.tailwindtoolbox.com/templates/landing-page)** Landing 是一個獨特且現代的 SaaS 登陸頁面模板,主要專注於流暢的使用者體驗,使您的網站脫穎而出。 Landing 中的所有圖像均可用於個人或商業專案,並且具有廣泛的預建置內容塊和元件,該模板為您提供了無限數量的自訂可能性。 **附加功能:** - 交易和卡片內容元件 - 多欄英雄部分 - 入門範本已準備好 --- ###39。 **凱羅斯** ![Kairos 範本](https://dev-to-uploads.s3.amazonaws.com/i/o8m08uga9xc4u58wsobz.jpg) **[現場示範](https://templatemag.com/demo/templates/CleanLanding/index.html) / [下載](https://templatemag.com/cleanlanding-bootstrap-landing-template/)** Kairos 是一個很棒的應用程式模板,可讓您以簡單且時尚的方式展示您的應用程式。此範本將讓您的客戶更了解您的應用程式提供的功能,首先是優點部分,然後是聯絡表單,您將獲得他們的興趣和信任,因此他們會嘗試您的應用程式。 Kairos 還使用平滑過渡來為您的著陸提供更自然的外觀和感覺。 **附加功能:** - 持續更新和錯誤修復 - 支援無限網站 - PHP 和 AJAX 聯絡表 --- ###40。 **蝴蝶** ![蝴蝶模](https://dev-to-uploads.s3.amazonaws.com/i/bpyehblbxhdabeupg1ft.jpg) **[現場示範](https://bootstrapmade.com/demo/Butterfly/) / [下載](https://bootstrapmade.com/butterfly-free-bootstrap-theme/)** Butterfly 是一個乾淨且有吸引力的單頁 Bootstrap 模板,專為希望展示與容器元素功能相關的號召性用語的特色部分的公司新創公司而建立。總體而言,此模板是用 HTML 5 開發的,所有支援的元素均支援視網膜,適用於較大的顯示器和小型行動裝置。 Butterfly 將幫助您建立令人驚嘆的登陸頁面,讓您的用戶停下來思考。 **附加功能:** - 透過電子郵件提供高級支援 - 整頁版面 - 以生產品質打造 --- ##結論 登陸頁面將佔您的用戶的大部分,因此他們需要您的全力關注和關注。有了這個免費的 HTML 登陸頁面模板列表,您就沒有理由不能擁有一個能夠正確展示您的產品並且轉換良好的登陸頁面。

我使用了幾款文字編輯器的心得: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

如何從頭開始為基本網站設定 Webpack 4 或 5

原文出處:https://dev.to/antonmelnyk/how-to-configure-webpack-from-scratch-for-a-basic-website-46a5 #簡介 你好,讀者! 如您所知,設定 [Webpack](https://webpack.js.org/) 可能是一項令人沮喪的任務。儘管有很好的文件,但由於一些原因,這個捆綁器並不是一匹舒服的馬。 Webpack 團隊正在非常努力且相對快速地開發它,這是一件好事。然而,對於新開發人員來說,一次性學習所有內容是難以承受的。教程已經過時,一些插件損壞,發現的範例可能會令人困惑。有時,您可能會陷入一些瑣碎的事情,並透過 Google 進行大量搜尋,以在 GitHub issues 中找到一些最終有幫助的簡訊。 缺乏關於 Webpack 及其工作原理的介紹性文章,人們直接奔向 *create-react-app* 或 *vue-cli* 等工具,但有時需要編寫一些簡單的純 JavaScript 和 SASS,無需框架或任何奇特的東西。 本指南將逐步介紹 ES6、SASS 和圖片/字體的 Webpack 配置,無需任何框架。對於大多數簡單的網站開始使用 Webpack 或將其用作進一步學習的平台應該足夠了。儘管本指南需要一些有關 Web 開發和 JavaScript 的先驗知識,但它可能對某些人有用。至少當我開始使用 Webpack 時,我會很高興遇到這樣的事情! #我們的目標 我們將使用 Webpack 將 JavaScript、樣式、圖像和字體檔案捆綁到一個 *dist* 資料夾中。 ![](https://thepracticaldev.s3.amazonaws.com/i/9n9g3yr1v6lhjfg8roqc.png) Webpack 將產生 1 個捆綁的 JavaScript 檔案和 1 個捆綁的 CSS 檔案。您可以像這樣簡單地將它們加入到 HTML 文件中(當然,如果需要,您應該更改 dist 資料夾的路徑): ``` <link rel="stylesheet" href="dist/bundle.css"> <script src="dist/bundle.js"></script> ``` 你就可以走了:tropical_drink: 您可以查看本指南中完成的範例::link:[link](https://github.com/heyanton/simple_webpack_boilerplate)。 注意:我最近更新了依賴項。本指南適用於最新的 Webpack 5,但設定仍適用於 Webpack 4,以防您需要! #開始 ####1。安裝Webpack 我們使用 [npm](https://www.npmjs.com/): `$ npm init` 命令在專案資料夾中建立一個 *package.json* 文件,我們將在其中放置 JavaScript 依賴項。然後我們可以使用 $ npm i --save-dev webpack webpack-cli 來安裝 Webpack 本身。 ####2。建立入口點文件 Webpack 從單一 JavaScript 檔案開始運作,該檔案稱為入口點。在 *javascript* 資料夾中建立 *index.js*。您可以在這裡編寫一些簡單的程式碼,例如 `console.log('Hi')` 以確保其正常運作。 ![](https://thepracticaldev.s3.amazonaws.com/i/tlt38mn2u385i06y4vzn.png) ####3。建立 webpack.config.js ....在專案資料夾中。這裡是所有:sparkles:魔法發生的地方。 ``` // Webpack uses this to work with directories const path = require('path'); // This is the main configuration object. // Here, you write different options and tell Webpack what to do module.exports = { // Path to your entry point. From this file Webpack will begin its work entry: './src/javascript/index.js', // Path and filename of your result bundle. // Webpack will bundle all JavaScript into this file output: { path: path.resolve(__dirname, 'dist'), publicPath: '', filename: 'bundle.js' }, // Default mode for Webpack is production. // Depending on mode Webpack will apply different things // on the final bundle. For now, we don't need production's JavaScript // minifying and other things, so let's set mode to development mode: 'development' }; ``` ####4。在 *package.json* 中新增 npm 腳本來執行 Webpack 要執行 Webpack,我們必須使用 npm 腳本和簡單的命令「webpack」以及我們的設定檔作為 *config* 選項。我們的 *package.json* 現在應該如下所示: ``` { "scripts": { "build": "webpack --config webpack.config.js" }, "devDependencies": { "webpack": "^4.29.6", "webpack-cli": "^3.2.3" } } ``` ####5。執行Webpack 透過基本設置,您可以執行“$ npm run build”命令。 Webpack 將尋找我們的入口文件,解析其中的所有[*import*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) 模組相依性並將其捆綁到*dist* 資料夾中的單一 *.js* 檔案。在控制台中,您應該看到如下內容: ![](https://thepracticaldev.s3.amazonaws.com/i/8j9rn72esbfbvn27duz6.png) 如果您將 `<script src="dist/bundle.js"></script>` 加入到 HTML 檔案中,您應該在瀏覽器控制台中看到「Hi」! #:顯微鏡:裝載機 偉大的!我們捆綁了標準 JavaScript。但是,如果我們想使用 ES6(及更高版本)的所有酷炫功能並保持瀏覽器相容性怎麼辦?我們應該如何告訴 Webpack 將我們的 ES6 程式碼轉換(*transpile*)相容於瀏覽器的程式碼? 這就是 Webpack **loaders** 發揮作用的地方。 Loader 是 Webpack 的主要功能之一。他們對我們的程式碼進行某些轉換。 讓我們在 *webpack.config.js* 檔案中新增選項 *module.rules*。在此選項中,我們將介紹 Webpack 如何準確地轉換不同類型的檔案。 ``` entry: /* ... */, output: /* ... */, module: { rules: [ ] } ``` 對於 JavaScript 文件,我們將使用: ###1。 [babel-loader](https://github.com/babel/babel-loader) [Babel](https://babeljs.io/) 是目前最好的 JavaScript 轉譯器。我們將告訴 Webpack 在捆綁之前使用它將現代 JavaScript 程式碼轉換為與瀏覽器相容的 JavaScript 程式碼。 Babel-loader 正是這樣做的。讓我們安裝它: `$ npm i --save-dev babel-loader @babel/core @babel/preset-env` 現在我們要新增有關 JavaScript 檔案的規則: ``` rules: [ { test: /\.js$/, exclude: /(node_modules)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] ``` * `test` 是我們要轉換的檔案副檔名的[正規表示式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)。在我們的例子中,它是 JavaScript 檔案。 * `exclude` 是一個正規表示式,它告訴 Webpack 在轉換模組時應該忽略哪個路徑。這意味著如果我們將來導入它們,我們將不會轉換從 npm 匯入的供應商庫。 * `use` 是主要規則的選項。這裡我們設定 loader,它將應用於與「test」正規表示式相對應的檔案(在本例中為 JavaScript 檔案) * “選項”可能因載入程式而異。在這種情況下,我們為 Babel 設定預設預設,以考慮應該轉換哪些 ES6 功能,哪些不應該轉換。它本身是一個單獨的主題,如果您感興趣,可以深入研究它,但目前保持這樣是安全的。 現在您可以將 ES6 程式碼安全地放置在 JavaScript 模組中! ###2。 [sass-loader](https://github.com/webpack-contrib/sass-loader) 是時候處理樣式了。通常,我們不想寫純 CSS。我們經常使用 [SASS](https://sass-lang.com/) 預處理器。我們將 SASS 轉換為 CSS,然後應用自動前綴和縮小。這是 CSS 的一種「預設」方法。讓我們告訴 Webpack 要這樣做。 假設我們在 *javascripts/index.js* 入口點導入主 SASS 檔案 *sass/styles.scss*。 ``` import '../sass/styles.scss'; ``` 但目前,Webpack 不知道如何處理 *.scss* 檔案或除 *.js* 之外的任何檔案。我們需要新增適當的載入器,以便 Webpack 可以解析這些檔案: `$ npm i --save-dev sass sass-loader postcss-loader css-loader` 我們可以為 SASS 檔案新增規則並告訴 Webpack 如何處理它們: ``` rules: [ { test: /\.js$/, /* ... */ }, { // Apply rule for .sass, .scss or .css files test: /\.(sa|sc|c)ss$/, // Set loaders to transform files. // Loaders are applying from right to left(!) // The first loader will be applied after others use: [ { // This loader resolves url() and @imports inside CSS loader: "css-loader", }, { // Then we apply postCSS fixes like autoprefixer and minifying loader: "postcss-loader" }, { // First we transform SASS to standard CSS loader: "sass-loader" options: { implementation: require("sass") } } ] } ] ``` 請注意此處有關 Webpack 的重要事項。可連結多個裝載機;它們將從“use”陣列中的最後一個到第一個逐個應用。 現在,當 Webpack 在程式碼中遇到“import 'file.scss';”時,它知道該怎麼做! ####PostCSS 我們應該如何告訴 *postcss-loader* 它必須應用哪些轉換?我們建立一個單獨的設定檔 `postcss.config.js` 並使用我們的樣式所需的 postcss 外掛程式。您可能會發現對最基本和有用的插件進行縮小和自動加入前綴,以確保 CSS 為您的真實網站做好準備。 首先,安裝這些 postcss 外掛:`$ npm i --save-dev autoprefixer cssnano`。 其次,將它們加入到 *postcss.config.js* 檔案中,如下所示: ``` module.exports = { plugins: [ require('autoprefixer'), require('cssnano'), // More postCSS modules here if needed ] } ``` 您可以更深入地研究 [PostCSS](https://github.com/postcss/postcss),找到更多適合您的工作流程或專案需求的插件。 在完成所有 CSS 設定之後,只剩下一件事了。 Webpack 將解析您的 *.scss* 導入,對其進行轉換,然後...下一步是什麼?它不會神奇地建立一個與您的樣式捆綁在一起的單一 *.css* 檔案;我們必須告訴 Webpack 要這樣做。但這個任務超出了裝載機的能力範圍。為此,我們必須使用 Webpack 的 **插件**。 #:electric_plug: 插件 他們的目的是做裝載機做不到的任何事。如果我們需要將所有轉換後的 CSS 提取到一個單獨的「捆綁」檔案中,我們必須使用插件。我們的案例有一個特殊的插件:*MiniCssExtractPlugin*: `$ npm i --save-dev mini-css-extract-plugin` 我們可以在 *webpack.config.js* 檔案的開頭單獨導入外掛: ``` const MiniCssExtractPlugin = require("mini-css-extract-plugin"); ``` 在我們設定載入器的“module.rules”陣列之後加入新的“plugins”程式碼,我們用選項啟動我們的插件: ``` module: { rules: [ /* ... */ ] }, plugins: [ new MiniCssExtractPlugin({ filename: "bundle.css" }) ] ``` 現在我們可以將此插件連結到我們的 CSS 載入器中: ``` { test: /\.(sa|sc|c)ss$/, use: [ { // After all CSS loaders, we use a plugin to do its work. // It gets all transformed CSS and extracts it into separate // single bundled file loader: MiniCssExtractPlugin.loader }, { loader: "css-loader", }, /* ... Other loaders ... */ ] } ``` 完畢!如果您按照步驟操作,則可以執行「$ npm run build」命令並在 *dist* 資料夾中找到 *bundle.css* 檔案。現在的一般設定應如下所示: ![](https://thepracticaldev.s3.amazonaws.com/i/ye1wwk5r7rvxcu9n0ylm.png) Webpack 有大量用於不同目的的插件。您可以根據需要在[官方文件](https://webpack.js.org/plugins/)中探索它們。 # 更多載入器:圖像和字體 此時,您應該了解 Webpack 工作原理的基礎知識。但我們還沒完成。大多數網站都需要一些資源:我們透過 CSS 設定的圖像和字體。由於 *css-loader*,Webpack 可以解析 `background-image: url(...)` 行,但它不知道如果將 URL 設為 *.png* 或 *jpg* 檔案該怎麼辦。 我們需要一個新的載入器來處理 CSS 內的檔案或能夠直接在 JavaScript 中匯入它們。這是: ### [檔案載入器](https://github.com/webpack-contrib/file-loader) 使用 `$ npm i --save-dev file-loader` 安裝它,並在我們的 *webpack.config.js* 新增規則: ``` rules: [ { test: /\.js$/, /* ... */ }, { test: /\.(sa|sc|c)ss$/, /* ... */ }, { // Now we apply rule for images test: /\.(png|jpe?g|gif|svg)$/, use: [ { // Using file-loader for these files loader: "file-loader", // In options we can set different things like format // and directory to save options: { outputPath: 'images' } } ] } ] ``` 現在,如果你在 CSS 中使用一些像這樣的圖像: ``` body { background-image: url('../images/cat.jpg'); } ``` Webpack 將成功解決它。您將在 *dist/images* 資料夾中找到帶有雜湊名稱的圖像。在 *bundle.css* 會發現類似這樣的內容: ``` body { background-image: url(images/e1d5874c81ec7d690e1de0cadb0d3b8b.jpg); } ``` 正如你所看到的,Webpack 非常聰明——它正確解析了你的 url 相對於 *dist* 資料夾的路徑! 您也可以為字體加入規則並以與圖像類似的方式解析它們;將 outputPath 變更為 *fonts* 資料夾以保持一致性: ``` rules: [ { test: /\.js$/, /* ... */ }, { test: /\.(sa|sc|c)ss$/, /* ... */ }, { test: /\.(png|jpe?g|gif|svg)$/, /* ... */ }, { // Apply rule for fonts files test: /\.(woff|woff2|ttf|otf|eot)$/, use: [ { // Using file-loader too loader: "file-loader", options: { outputPath: 'fonts' } } ] } ] ``` #總結 就是這樣!經典網站的簡單 Webpack 設定。我們介紹了 **入口點**、**載入器** 和 **插件** 的概念以及 Webpack 如何轉換和捆綁檔案。 當然,這是一個非常簡單的配置,旨在了解 Webpack 的一般概念。如果您需要的話,還有很多事情可以加入:來源映射、熱重載、設定 JavaScript 框架以及 Webpack 可以做的所有其他事情,但我覺得這些事情超出了本指南的範圍。 如果您遇到困難或想了解更多訊息,我鼓勵您查看 Webpack [官方文件](https://webpack.js.org/concepts)。快樂捆綁!

Git 和 GitHub:如何復原單一檔案

原文出處:https://dev.to/lofiandcode/git-and-github-how-to-revert-a-single-file-dha ##介紹 一旦您開始與其他開發人員合作,了解如何將單一檔案還原到某個提交就變得很重要。出現這種需求是因為您有時需要更改與拉取請求無關的文件以測試您正在開發的功能。但是,手動將這些文件中的每一行程式碼變更回原始狀態並進行新的提交可能會導致提交歷史記錄混亂。恢復檔案是一種更清晰的處理方式。 ##找到提交ID 首先,您需要前往 GitHub 上的共用儲存庫並找到要復原的檔案。導航到該文件後,您應該在文件上方看到以下內容: ![替代文本](https://dev-to-uploads.s3.amazonaws.com/i/6muovwvd0kukchcrur91.png) 在右側,您可以看到 7 位數的提交 ID 和日期。這是修改該文件的最近一次提交的提交 ID。記下此提交 ID,或將其複製到剪貼簿。 ##找到檔案路徑 接下來您需要的是工作目錄中的檔案路徑。這部分很簡單,因為文件的路徑位於您找到文件的提交 ID 的相同 GitHub 畫面上。 ![替代文本](https://dev-to-uploads.s3.amazonaws.com/i/xl83nfi5q3h3bnzmjzm7.png) 在上面您可以看到與之前相同的螢幕截圖,但這次我在文件路徑下劃線了。請注意,我只在路徑的一部分下劃線了。列出的第一個目錄是工作目錄名稱,並且將是您使用此檔案路徑時所在的目錄。因此,您只需要下劃線部分。 ##恢復檔案。 剩下的就是恢復檔案了。打開終端並變更為工作目錄後,您可以使用“git checkout”來還原檔案。 git 指令的格式如下圖所示: `git checkout [提交 ID] -- 路徑/到/檔案` 如果我要恢復上面螢幕截圖中的文件,則將如下所示: ![替代文](https://dev-to-uploads.s3.amazonaws.com/i/dfby4ccbqcii9uwsptma.png) ##提交更改 我知道你在想什麼,“等一下,我認為重點是不建立新的提交?”嗯,這說對了一半。我們不想對我們恢復的文件進行新的提交。但是一旦我們恢復文件,我們就需要提交該更改。在這種情況下,更改是單一檔案的恢復。這是使用標準提交命令完成的: `git commit -m '提交訊息'` 然後,您可以將該提交推送到遠端,以便 GitHub 上的分支版本與您的本機版本相符。 ##總結 若要將單一檔案還原至特定版本,請執行下列操作: * 尋找要還原到的檔案版本的提交 ID。 * 找到要從工作目錄復原的檔案的路徑。 * 在終端機中,將目錄變更為工作目錄。 * 輸入 `git checkout [commit ID] -- path/to/file` 並按 Enter 鍵。 * 將更改提交到恢復的文件。 ##參考 [封面圖片](https://ih0.redbubble.net/image.591029586.5228/flat,550x550,075,f.jpg) [如何將檔案重設或還原到特定版本? - Stackoverflow](https://stackoverflow.com/questions/215718/how-can-i-reset-or-revert-a-file-to-a-specific-revision)

初級到資深 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/bigsondev/10-projects-to-skyrocket-your-coding-skills-19hl ## 介紹 每當您考慮提高編碼水平時,都有很多選擇可以實現。您可以閱讀開發文章或無限循環地閱讀教程、課程、影片和書籍,但真正的關鍵是從學習過渡到動手編碼,相信我,沒有比應用您所掌握的所有概念更好的方法了。到目前為止,我們已經透過**基於專案的學習**學習了。 我自己是一名擁有 [8 年以上經驗](https://www.linkedin.com/in/adrian-bigaj-282277130/) 的軟體工程師,我發送了大量的履歷,進行了數十次面試,尤其是現在,當獲得前端/Web 開發人員的工作比以往任何時候都更加棘手時,我強烈建議您建立自己的專案。 為了在人群中脫穎而出,我將描述 10 個專案,每個專案都有獨特的設計、要求和技能,您可以掌握這些來建立您的作品集,並實際建立可以影響您作為開發人員進步的東西! 此外,每個專案都附帶預先定義的實施卡,可以幫助您感覺自己像在敏捷環境中工作的真正開發人員,具有使用者故事和驗收標準,同時也支援專案本身的規劃。 ## [名片](https://app.bigdevsoon.me/projects/business-card) 深入 Web 開發的良好介紹暖身。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/naebo2g2thxvabzqyu0h.png) 您將了解基本的 HTML 和 CSS、響應式設計原則以及線上個人品牌介紹。 ### 卡牌 1.UI容器 2. 用戶聯繫部分 3. 用戶形象 4. 使用者資訊部分 5. 絕對定位的形狀 6. 動畫 ### 其他資源 - [附有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-business-card) - [附有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-business-card) ## [素食王](https://app.bigdevsoon.me/projects/the-veggie-king) 經典的CSS RWD Landing Page樣式,感受媒體質疑! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/am4hk4p1it0apjyb41sd.png) 您將學習進階 CSS 技術、CSS Flexbox/Grid,以及如何建立回應靈敏且有吸引力的登陸頁面。 ### 卡牌 1. 導航 2.英雄區 3. 關於我們部分 4. 菜單部分 5. 畫廊部分 6. 聯繫部分 7. 頁尾 8. 懸停效果 9. 行動選單 10.響應式網頁設計 11. 優化 ### 其他資源 - [帶有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-the-veggie-king) - [帶有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-the-veggie-king) ## [計算機](https://app.bigdevsoon.me/projects/calculator) 讓我們進一步了解 JS、邏輯、純函數和一些數學運算。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdmrz3n0g5h49buvu7id.png) 您將學習 JavaScript 基礎知識、DOM 操作和事件處理來建立互動式 Web 應用程式。 ### 卡牌 1.UI容器 2. 輸入數字 3. 數學運算 4. 清除和重置 5. 之前的操作 6. 明暗模式 7. 邊緣情況處理 ### 其他資源 - [帶有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-calculator) - [帶有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-calculator) ## [Just Weather](https://app.bigdevsoon.me/projects/just-weather) **此專案類型已多次用於面試帶回家**挑戰,值得至少做一次! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dyhh9offr1n7qlbi3372.png) 您將學習如何從外部 API、非同步 JavaScript(Promises、async/await)獲取資料,並在 Web 上顯示動態資料。 ### 卡牌 1.API配置 2. 搜尋欄 3. 地點和溫度 4. 每小時預報 5. 天氣詳情 6. 位置存取 7. 溫度單位切換 8. 最近的搜尋 9. 骨骼動畫 10. 錯誤處理 ### 其他資源 - [有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-just-weather) - [帶有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-just-weather) ## [GifTok](https://app.bigdevsoon.me/projects/giftok) 更多 API、分頁、無限滾動。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqfo7txkf37mj1393tiy.png) 您將學習如何使用富媒體 API、實作分頁並確保適合行動裝置的 UI。 ### 卡牌 1.API配置 2.顯示第一個GIF 3. 滑動下一步 4. 向後滑動 5.無限滑動 6. 用戶詳細訊息 7. 骨架加載 8. 桌面版 9. 邊緣情況 ### 其他資源 - [附有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-giftok) - [帶有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-giftok) ## [注意](https://app.bigdevsoon.me/projects/notely) 另一種經典的待辦事項應用程式風格,如果您還沒有建立一個,現在可能是個好時機! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xqxbj0wc699ysm9kauyx.png) 您將學習現代 JavaScript 框架中的 CRUD 操作、狀態管理以及不可變程式設計的原理。 ### 卡牌 1. 導航佔位符 2. 新筆記 3. 列出註釋 4. 編輯註釋 5. 刪除註釋 6. 填寫註釋 7. 搜尋筆記 8. 過濾筆記 9. 完成筆記 10. 空狀態 11. 字段驗證 12. 持久性存儲 ### 其他資源 - [附有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-notely) - [附有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-notely) ## [顏色記憶](https://app.bigdevsoon.me/projects/color-memory) 建立遊戲並擁有元件化和結構的高級圖片總是好的。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1doqmzxyqetppk47fgb.png) 您將學習軟體開發中的邏輯建置、維護應用程式狀態和使用者互動處理。 ### 卡牌 1. 圓形元件 2. 首頁 3. 遊戲玩法 4. 遊戲結束模式 5. 最佳成績 6. 遊戲規則模態 7. 聲音通知 8.響應式網頁設計 9. 邊緣情況 ### 其他資源 - [附有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-color-memory) - [附有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-color-memory) ## [AI 貼文產生器](https://app.bigdevsoon.me/projects/ai-post-generator) 人工智慧的現代趨勢很奇特,對吧?了解最受歡迎的可用 API 之一的絕佳機會。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9k8amzzo0f32idkb3ymd.png) 您將學習透過 API 與 AI 交互,了解提示的工作原理,並根據實際用例建立工具。 ### 卡牌 1.API配置 2.UI容器 3. 社交平台選擇器 4. 訊息文字區域 5. 音調和風格選擇器 6. 產生貼文按鈕 7. 生成階段 8. 按鈕邏輯 ### 其他資源 - [附有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-ai-post-generator) - [帶有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-ai-post-generator) ## [關卡編輯器](https://app.bigdevsoon.me/projects/level-editor) 這就像您的第一個「迷你 Photoshop 工具」😁 如今有很多類似風格的「無程式碼」應用程式。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5kqkhjhpwyc6h2jc10ug.png) 您將學習如何實現拖放功能、資產管理以及遊戲級設計和 UX/UI 考量的基礎知識。 ### 卡牌 1.UI容器 2. 資產提現機制 3、快速資產 4. 撤銷功能 5. 橡皮擦工具 6. 變焦能力 7. 設定與匯出 8. 調整網格大小 9. 等級的持續性 ### 其他資源 - [帶有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-level-editor) - [附有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-level-editor) ## [任何聊天](https://app.bigdevsoon.me/projects/any-chat) 掌握前端和後端、套接字和事件廣播的完整流程是一項非常有用的技能。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qkuenw2ya3y3q5apgyoa.png) 您將學習全端開發,包括伺服器端程式設計、即時資料處理和資料庫管理。 ### 卡牌 1. 入職頁面 2. 進入聊天頁面 3.Node.js伺服器 4. 聊天頁標題 5. 聊天視窗 6. 聊天頁頁腳 7. 訊息發送 8.表情符號支持 9. 連接和斷開 10. 邊緣情況 ### 其他資源 - [有專案文件的故障範本](https://glitch.com/edit/#!/big-dev-soon-any-chat) - [帶有專案文件的 GitHub 範本](https://github.com/elise-bigdevsoon/big-dev-soon-any-chat) ## 結論 嘗試技術、框架和函式庫,建立您自己的創意變體,看看什麼最適合您。我絕對建議您擴展HTML/CSS 之外的技能,加入更多JS 和邏輯,同時使用API、React/Vue/Svelte 等一些流行框架,並深入研究Node.js/Express 以了解完整的前端是如何運作的。<-> 後端流程有效。 建立出色的專案,我祈禱面試成功,繼續編碼。 長期以來,我的目標是透過社區傳播基於專案的學習方法,並啟動並執行 [BigDevSoon](https://bigdevsoon.me/),這是我們過去 2 年一直在開發的應用程式年對我們來說是一項偉大的成就。 **如果您喜歡本文,請隨意傳播!** ❤️

身為開發者,我的 8 個讓生活更美好的秘訣

原文出處:https://dev.to/wraith/my-8-tips-for-a-better-life-as-a-developer-1hfg 我擔任軟體開發人員和工程師已經有 8 年多一點了,從我自己的經驗以及從一些非常有才華的人那裡學到了很多東西。在這篇文章中,我想分享一些真正讓我的體驗變得更好、更愉快的事情。有些是技術性的,有些只是一般生活技巧。但所有這些都改善了我在軟體開發方面的生活和經驗,希望透過分享這些課程和技巧,我可以幫助您避免一些我為了弄清楚它們而必須經歷的不愉快的時光。 ## 1. 找一個您喜歡工作的地方 ![三個人坐在咖啡店裡用電腦工作,微笑。](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shosztzzfmpjuf7ksr5c.jpg) 您的環境對您的生活貢獻很大。它可以增加或減輕壓力,幫助您集中註意力或分散注意力,讓您感到安全或不安全等等。因為它在我們每個人的生活中都扮演著不可或缺的角色,所以我認為從這裡開始是合適的。 無論您是在辦公室還是遠端工作,您很可能可以採取一些措施來找到一個讓您感覺「合適」的地方。我說「對」是因為這裡每個人都會有所不同。有些人想要感到舒適和「賓至如歸」。其他人想要一個不太舒適的區域,而是真正讓他們「進入狀態」並集中註意力的區域。 多年來,我嘗試了很多不同的地點,只是為了看看什麼對我有用。我坐在陽台上,享受早晨涼爽的空氣,喝著一杯熱咖啡。我確實坐在桌子底下,身上蓋著毯子。我坐在壁櫥、角落、咖啡店、餐廳、酒吧、汽車、公園、餐桌和樓梯井裡。透過所有這些實驗,我已經能夠找到在我需要時為我提供所需的地方。如果我需要集中註意力,我就需要獨處。某處有一扇可以關閉的門,但沒有窗戶讓我注意到有人走過。當我太舒適時,就像依偎在柔軟的沙發上的毯子裡時,我的工作效果就不太好。如果我需要改變節奏,或者只是需要和人們在一起,我發現我真的很喜歡坐在不太擁擠的小酒吧或餐廳裡。我可以在某個地方點一杯飲料和一份開胃菜然後工作,但周圍仍然有幾個人。 所以我鼓勵你嘗試幾個地方。找出什麼對你有用,同樣重要的是,找出什麼對你沒用。如果你找不到地方,你總是可以花一點力氣去打造你想要的地方! 「正確」對你來說意味著什麼? ## 2. 投資硬件 ![黑暗房間裡一張配有高科技設備的桌子,LED 照亮空間](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7knnfnk29bpe02gibac4.png) 作為軟體開發人員,我們使用的硬體數量非常多。可以說,我們使用鍵盤和辦公椅之類的東西比生活中任何其他物品都多。當然,我們可以使用任何舊鍵盤來完成工作,我們可以坐在任何椅子上。但我發現,對「更好」的硬體進行一點投資會對我的工作體驗產生很大的影響。 ### 椅子 如果您在工作時坐著,並且您只想投資一件東西,那麼它絕對應該是您的椅子。一張既提供舒適又提供支撐的椅子確實可以大有幫助。從您可以坐多久並集中註意力而不會感到不舒服,到日常生活中背部、頸部和肩膀的感覺,您的椅子對您的整體健康和福祉有很大影響。因此,一定要找到一款好的產品,而不要只滿足於會導致不良姿勢的產品。 我個人使用 [Secretlab Titan Evo(蝙蝠俠主題)](https://secretlabchairs.ca/products/titan-evo-2022-series?sku=R22PU-Batman),幾年來我對它非常滿意。與許多高端桌椅相比,價格還不錯。 ### 鍵盤 僅次於椅子(但相差不多)的是鍵盤。輕鬆地成為我們每天工作中互動最多的工具。那裡也有很多選擇,因此無論您的個人喜好如何,很可能有一些東西可以滿足您的需求。 每個人選擇合適的鍵盤都有很大不同。有些人喜歡低調的鑰匙而不是機械鑰匙。有些人需要整合 USB 連接埠。成本、人體工學、有線或無線、可自訂的按鍵和開關、背光、可配置的 LED、支援配置按鍵佈局、高度和大小、按鍵數量,這樣的例子不勝枚舉。尋找適合您的鍵盤無疑是一段旅程,但我強烈建議您繼續下去。當然,我們可以使用任何鍵盤來完成我們的工作......但我保證,如果您嘗試一下,找到「正確的」鍵盤將使您作為開發人員的一天和體驗更加愉快。 我使用 [Moonlander Mark 1](https://www.zsa.io/moonlander/),絕對💙它!分離式設計確實幫助我不再那麼無精打采,也幫助消除了我長期以來的肩膀和手腕疼痛。再加上那些櫻桃棕色的開關聽起來很漂亮😍! ### 老鼠 談論鍵盤就不能不談論它們的助手——滑鼠。就像鍵盤一樣,市面上有許多不同類型的鍵盤,每個人都會有自己的偏好。幸運的是,即使是半像樣的滑鼠也有相當低的價格,因此嘗試一些滑鼠來找到適合您的滑鼠相對容易。但與此處的所有其他項目一樣,投入一點時間和金錢即可對您的體驗產生積極影響。 我的老鼠是 [ZLOT 垂直遊戲滑鼠](https://www.amazon.com/gp/product/B07T3PFWCB?th=1)。它是一款較輕(重量)的滑鼠,但具有良好的人體工學感覺和響應能力,我已經喜歡了很長一段時間了。 ### 監視器 這絕對是一個可選項目,但我發現它讓我的工作更加愉快。並非每個人都需要外接顯示器。有些人實際上更喜歡直接使用筆記型電腦工作。但如果您確實喜歡使用外部顯示器,這是一項可以產生巨大影響的投資。 遺憾的是,由於多台 4k 顯示器在 Mac 上工作出現問題,我放棄了多顯示器設置,現在使用 [Sceptre 35" 曲面顯示器](https://www.sceptre.com/Monitors/2K-4K -Series /C355W-3440UN-35-Curved-Monitor-product1176category12category98.html)。它有很多空間,所以我仍然可以在一個螢幕上打開大量視窗。 ### 耳機 耳機也是可選的(有些人可能會反對這一點😝),但它們的好處怎麼強調都不為過。從減少干擾到幫助您集中註意力,一副好的耳機可以大有幫助。就像我列出的大多數項目一樣,每個人的偏好都會有所不同。但是,投入一點時間和金錢來尋找一雙適合您的好鞋,確實可以將您的遊戲提升到一個新的水平。我認識的許多人都尋求良好的降噪效果,而且它們必須輕盈舒適,這樣才能一次佩戴幾個小時。 我個人喜歡使用 Beats。我曾經使用[Studio3](https://www.bestbuy.ca/en-ca/product/beats-by-dr-dre-studio3-over-ear-noise-cancelling-bluetooth-headphones-black/11534527 )但是當我必須開始戴眼鏡時,我不喜歡這些耳機給我的鏡框帶來的壓力,所以我改用了[Beats Fit Pro](https://www.beatsbydre.com/earbuds/beats- fit- pro?sku=MK2F3) 並且對它們非常滿意。我已經連續戴了 8 個小時,效果非常好。它們輕巧、舒適、音質好,並且在我慢跑和運動時表現良好且穩定。 您使用什麼硬體?您夢想的硬體是什麼? ## 3. 找到您*喜歡*使用的工具 ![應用程式牆的螢幕截圖,應用程式圖示上有有趣的表情符號臉孔](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/clgqlfokffwpu57wnkr9.png) 除了硬體之外,作為開發人員,我們還使用許多軟體工具來完成我們的工作。有些我們別無選擇,但也有很多我們可以選擇,找到您真正喜歡使用的工具確實可以讓您的日常體驗變得更好。即使只是擁有一個可以配置為您喜歡的外觀的工具也可以產生積極的影響。 我在這裡想強調的不是找到每個人都使用的工具,因為他們可以做各種各樣的事情。更多的是尋找您真正「喜歡」和「期待」使用的工具來完成工作。即使它們不能完成其他工具可以完成的所有奇特的事情,如果您確實希望使用其他工具,那就使用它!擁有我們積極喜歡的工具確實會為我們的生活增添很多積極性。 多年來,類似的工具有很多,但這裡有一些工具為我的日常生活帶來了很多樂趣: - Giphy 桌面應用程式 - 用 gif 回覆取代無聊的文字,讓 Slack 訊息變得生動起來。 - 光線投射 - 這已經取代了我 Mac 上的 Spotlight。透過專業版,我可以存取 ChatGPT 4...因此,只需一個快速鍵盤快捷鍵,我就能輕鬆掌握 AI。對我來說遊戲規則改變者! - 黑曜石 - 雖然這已經是一個流行的筆記應用程序,但我花了一些時間編寫了一些腳本來為我自動化工作,它完全改變了我記下所有筆記並跟踪我需要做的所有事情的方式。 - 弧形瀏覽器 - Arc 花了整整 1 天的時間才成為我的主要瀏覽器。現在,當我測試瀏覽器對我正在建立的某些功能的支援時,我只使用其他瀏覽器(在我的桌面上)。 - 習慣性的 - 獲得徽章、成就和一般遊戲化讓我非常有動力,所以這個待辦事項應用程式讓我管理和執行任務變得更加有趣! 有哪些工具可以為您的日常開發生活帶來樂趣? ## 4. 設定目標 ![一台打字機,上面印有一張伸出的紙上的「目標」](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vcsabk75mtb2o8dlwbt3.jpg) 我知道這聽起來很明顯,而且我相信我們都從無數其他來源聽到這一點。但您可能會驚訝地發現有多少人沒有為自己設定目標。不相信我?向你的任意 2 到 3 個鄰居詢問他們目前正在努力實現什麼目標。當我問這個問題時,經常得到的只是聳聳肩,然後回答「沒什麼」。 僅僅設定目標也是不夠的。你也必須定期考慮它們。有些方法建議將它們寫下來並放在鏡子上或您經常看到它們的地方。這個方法對我個人來說沒有效果,但也許對你有用?對我來說有效的方法是每天早上開始工作前坐下來15 分鐘,並重點思考我的目標、我所有的待辦事項以及日曆上的所有事情(是的,我實際上在日曆上留出15分鐘的時間)這個,並強迫自己堅持這個時間)。在這段時間裡,我思考我的目標,並找出我今天可以做的一件小事,讓我離實現每個目標更近一步。 例如,如果我的目標是在家人來過感恩節之前清理車庫,我會想,「我今天可以做哪一件小事來實現這個目標?」。有時答案特別小…「掃到工作台下面」。其他時候我可能會更有動力,或者我有更多的可用時間,這可能是更大的事情。無論如何,請花一些時間考慮您今天可以採取的一項行動來實現該目標。 當我這樣做時,我的大腦中會發生一些事情。我發現自己感覺更有成就感和更樂觀。當然,完成目標可能是一條漫長的道路(如果它是一個大目標),但是知道我離我想要完成的事情更近了,這對我的日常生活產生了積極的影響,並讓我能夠完成的事情比我想像的還要多。 無論大小,給自己設定目標。然後定期思考它們,並採取許多微小的行動,以朝著前進邁出一步。我保證這會為您的生活帶來美好的事物! 現在您正在努力實現哪些目標? ## 5. 保持好奇心並了解*為什麼* ![視窗上有一個標誌,上面寫著「#becurious」](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/42zs3m4tlzbcilh338nd.png) 很多人對編碼專案中的完成方式感到沮喪或評判。我肯定去過那裡! - “為什麼有人選擇這項技術?!對於這個用例來說,其他技術要好得多...” - “為什麼有人會寫這樣的程式碼?!” - “如果我們不做 X 而只是做…,事情會好得多” 這些聽起來很熟悉嗎? 儘管事情有時會令人沮喪,但在軟體開發中,做出的每個決定背後幾乎總是有一個「原因」。這是最好的選擇嗎?也許不是……但做出這樣的選擇還是有原因的。 我曾經對事情的現狀感到沮喪,然後在嘗試解決問題時感到沮喪,然後在遇到障礙時感到沮喪。但最終,事情突然發生了,我沒有感到沮喪,而是開始尋找這些事情發生的原因。背後的*原因*是什麼。當我養成「尋找原因」而不是「想知道為什麼不」的習慣時,我的好奇心變得更強。我發現我正在尋找更多的信息,更徹底地學習和理解事物,更多地同情與我一起工作的人,最終,沮喪的感覺減少了很多。 現在,我的經歷更加積極了。無論我是重構一段複雜的程式碼,試圖找到解決惱人問題的方法,還是為新工作學習全新的程式碼庫,我實際上更喜歡這個過程,因為我只是好奇並想知道「為什麼」。 最近一次讓您真正感到沮喪的編碼*事情*是什麼?您知道*為什麼*會是這樣嗎? ## 6. 為重點工作劃出日曆 ![一週中每天 2 小時的日曆條目顯示「焦點時間」](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13x844h65h98y6c78bsk.png) 這說起來容易做起來難,具體取決於您的工作地點,但它會對您的開發人員生活產生驚人的影響! 您是否曾經在該區域中,只是編寫程式碼來建立該新功能,然後「*叮!*」有人向您發送了一條緊急的 Slack 訊息?或是有人拍拍你的肩膀問你問題?您解決了乾擾問題,然後返回螢幕,然後您就失去了所有註意力?如果沒有……我願意賭很多錢,你會在職業生涯的某個時刻這麼做。 「在區域中」或進入「心流」的概念是一個已經被研究和寫了很多的主題。我強烈建議您查看一些有關該主題的文章和書籍,因為這是一個非常有趣的主題(至少對我來說是😃)!其中許多研究都表明,處於心流狀態是多麼有益,而且在中斷後可能需要 20 分鐘以上才能恢復到那種精神狀態!因此,找到讓自己進入這種心態並保持這種狀態的方法非常重要! 我發現讓自己進入這種狀態的最佳方法之一就是在日曆上劃出大量時間專門用於「專注工作」。一開始這可能是一個挑戰,讓人們在嘗試聯繫之前檢查您的日曆或 Slack 狀態,並幫助每個人了解您將在焦點時間結束後立即回覆他們。但最終人們會明白過來,並且回報是巨大的!別忘了在這段時間關閉通知! 不過這裡有一些提示...... - 接受有時會出現緊急事務並需要更高優先順序的事實。這就是生活,我們只能隨波逐流……但這不該成為「常態」。 - 拍攝 2-3 小時的片段。少於這個數量會讓人覺得不夠,但超過這個數量,人們就會被迫更頻繁地打斷你。請記住,其他人也有重要、緊急的事務,在當今的工作環境下,讓他們等待半天以上才能獲得地址確實不公平或不合理。 - 在你最有生產力的時間安排這些時間段。對我來說,早上 6 點到 10:30 左右我的工作效率最高。所以我通常會嘗試將我的專注時間安排在這些時間裡。 您發現一天中的什麼時段您的工作效率最高? ## 7. 保持 PR 較小 ![GitHub 審核標題的螢幕截圖,顯示 3 個檔案已更改,總共進行了 35 項更改](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf7cy31tmzjjfz9wz2cn.png) 我喜歡這個,並且在過去一年左右的時間裡它已經成為我的首要任務。 事實證明,保持 Pull 請求(或 GitLab 人員的合併請求)較小有很多積極的好處。發布的錯誤更少,我們審查程式碼的時間更少,功能的推出速度更快,僅舉幾例。所有這些不僅使我們的產品變得更好,而且我發現它也極大地改善了我作為開發人員的體驗! 透過專注於較小的變化,我發現我可以更徹底地思考問題,考慮到在較大變化的混亂中可能被忽視的用例。我能夠更快地將變更納入審查,我的團隊成員能夠更快地審查我的程式碼,因為我只佔用了他們5 分鐘而不是2 小時的時間,並且在審查期間,我收到的程式碼要少得多變更請求。因此,更好的程式碼將會出現,我可以繼續花更多的時間來建立新的東西,而不是必須解決一堆被遺漏的錯誤。 另一方面,審查小型 PR|MR 比大型 PR|MR 更令人愉悅。您是否曾經需要審查某人的 PR|MR,其中包含數千個更改、跨越 20 多個檔案以及應用程式的多個區域?當你這樣做時,你的第一個反應是什麼?您是否對參與並開始審核感到過於興奮?或者,也許您感到“呃”,於是推遲了會議,因為距離下一次會議只有 30 分鐘,而您可以在這段時間內完成其他事情? 當審查大型 PR|MR 時,通常會失去很多細節(或至少受到較少的關注),最終,大多數人會達到「審查盲目性」或「審查疲勞」的地步,事情開始被忽視,或者審稿人必須離開一段時間,稍後再回來。這一切都會導致審核過程花費更長的時間、效率更低,並導致提交更多的變更請求。更不用說所有團隊成員都有的不滿情緒了。 自從我開始將此作為自己的優先事項,並與團隊成員一起努力讓他們也這樣做時,我注意到我在 PR|MR 方面的經驗明顯改善了。我更願意在會議之間跳出一些評論,我不得不要求更少的改變,而且我不會在需要離開並重新振作起來之後感到精疲力盡。就連我的計劃也變得更準確了! 總而言之,我強烈向大家推薦這個。如果您想了解更多關於這樣做的好處,我建議您查看 [LinearB 部落格](https://linearb.io/blog) 以及 [Dev Interrupted 播客](https://linearb .io/dev-interrupted/ podcast).他們談到了一些很棒的觀點,我發現這些觀點確實對工程領導者和團隊有幫助! 你曾經審查過的最糟糕的公關是什麼? ## 8. 寫下一切! ![有人在筆記本上寫筆記](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yeqff10xv6ej22xk22w8.jpg) 我的最後一個建議是我在去年開始做的事情,在閱讀了[如何做智慧筆記](https://www.amazon.ca/How-Take-Smart-Notes-Technique/dp/3982438802)和[把事情做好](https://www.amazon.ca/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280)它對我的生活產生了驚人的影響。 當我學到新東西時,我會把它寫下來。即使只是一小段描述我學到的東西。當出現新任務時,無論大小,我都會把它寫下來。在會議期間,如果分享想法、給予回饋、提出問題,所有這些都會被記錄下來。如果我對某事有一個隨意的想法,或者一個頭腦發熱的想法……你猜對了……它會被寫下來。然後,每當我有幾分鐘空閒時間時,我都會先看筆記,而不是瀏覽社群媒體。我盡可能回顧它們,這強化了我腦海中的信息,但也幫助我將不同的想法聯繫在一起,這往往會產生一個全新的想法。 透過這樣做,我發現我對事情的記憶更加徹底。如果我不能,我有記錄並且可以將其調出!它使我能夠完成更多的工作文檔,而且我甚至在任何給定時間都有 4 或 5 篇部落格文章正在編寫中!遺漏的事情少了很多,而且我能夠完成更多的事情。 我最近開始了一份新工作,透過使用這種方法,人們已經來找我詢問我是如何做到這麼多的!秘密醬汁?全部寫下來並將其添加到系統中。 這對我來說改變了遊戲規則,我只需要鼓勵其他人也這樣做,因為我真的相信這可以使他們的生活受益匪淺! 你用什麼方法來記住和分享你學到的東西? ## 結論 在過去 8 年多的軟體開發人員和工程師工作中,我學到了很多。我經歷過好時光和壞時光,並一路走來學到了一些非常有用的人生課程。透過找到我喜歡工作的地方,在我的硬體上投入更多的時間和金錢,找到我「喜歡」使用的工具,設定目標,保持好奇心並專注於“為什麼”,定義專注工作的時間,專注於保持PR 較小,並寫下我能寫下的一切,我可以誠實地說,我的開發者體驗得到了極大的改善。 我非常希望這些技巧中至少一兩個也能改善您的體驗。 感謝您讓我與您分享這些技巧。下次見,駭客快樂!

JSON 效能比較慢。這邊介紹 4 個更快的替代方案

原文出處:https://dev.to/nikl/json-is-slower-here-are-its-4-faster-alternatives-2g30 --- ## 介紹 在快節奏的 Web 開發世界中,速度和反應能力是不容妥協的。您的用戶希望即時存取資訊、快速互動和無縫體驗。 JSON 是 JavaScript 物件表示法的縮寫,一直是 Web 開發中資料交換的忠實夥伴,但它會減慢您的應用程式速度嗎?讓我們深入探討 JSON 的世界,探索其潛在瓶頸,並發現更快的替代方案和優化技術,讓您的應用程式像獵豹一樣衝刺。 --- 您可能還想查看本教學:[使用 Golang 建立即時通知系統 - 逐步通知系統設計指南](https://dev.to/nikl/using-golang-to-build -即時通知系統逐步通知系統設計指南-50l7) --- ### 什麼是 JSON 以及為什麼您應該關心? 在開始 JSON 優化之旅之前,讓我們先了解 JSON 是什麼以及它為何重要。 JSON 是將應用程式中的資料黏合在一起的黏合劑。它是伺服器和客戶端之間通訊資料的語言,也是資料儲存在資料庫和設定檔中的格式。從本質上講,JSON 在現代 Web 開發中發揮關鍵作用。 了解 JSON 及其細微差別不僅是任何 Web 開發人員的基本技能,而且對於優化應用程式也至關重要。隨著我們深入研究此博客,您將發現為什麼 JSON 在性能方面可以成為一把雙刃劍,以及這些知識如何對您的開發之旅產生重大影響。 ## JSON 的受歡迎程度以及人們使用它的原因 JSON 在 Web 開發領域的受歡迎程度怎麼強調都不為過。由於以下幾個令人信服的原因,它已成為資料交換的事實上的標準: 1. **人類可讀格式**:JSON 使用簡單的、基於文字的結構,開發人員和非開發人員都可以輕鬆閱讀和理解。這種人類可讀的格式增強了協作並簡化了調試。 ``` // Inefficient { "customer_name_with_spaces": "John Doe" } // Efficient { "customerName": "John Doe" } ``` 2. **與語言無關**:JSON 不依賴任何特定的程式語言。它是一種通用資料格式,幾乎可以由所有現代程式語言解析和生成,因此具有高度通用性。 3. **資料結構一致性**:JSON 使用鍵值對、陣列和巢狀物件強制資料結構一致。這種一致性使其在各種程式設計場景中都可預測且易於使用。 ``` // Inefficient { "order": { "items": { "item1": "Product A", "item2": "Product B" } } } // Efficient { "orderItems": ["Product A", "Product B"] } ``` 4. **瀏覽器支援**:Web 瀏覽器原生支援 JSON,允許 Web 應用程式與伺服器無縫通訊。這種原生支援對其在 Web 開發中的採用做出了重大貢獻。 5. **JSON API**:許多Web服務和API預設提供JSON格式的資料。這進一步鞏固了 JSON 作為 Web 開發中資料交換首選的角色。 6. **JSON Schema**:開發人員可以使用 JSON Schema 來定義和驗證 JSON 資料的結構,為其應用程式添加額外的清晰度和可靠性。 有鑑於這些優勢,全球開發人員依賴 JSON 來滿足資料交換需求也就不足為奇了。然而,當我們更深入地探索部落格時,我們將發現與 JSON 相關的潛在性能挑戰以及如何有效解決這些挑戰。 ## 對速度的極品 在當今快節奏的數位環境中,應用程式速度和回應能力是不容談判的。用戶期望跨網路和行動應用程式即時存取資訊、快速互動以及無縫體驗。這種對速度的需求是由以下幾個因素所驅動的: ### 用戶期望 使用者已經習慣了數位互動中閃電般的快速回應。他們不想等待網頁加載或應用程式回應。即使是幾秒鐘的延遲也會導致沮喪和放棄。 ### 競爭優勢 速度可以成為顯著的競爭優勢。快速回應的應用程式往往比反應遲緩的應用程式更有效地吸引和留住用戶。 ### 搜尋引擎排名 像 Google 這樣的搜尋引擎將頁面速度視為排名因素。載入速度更快的網站往往在搜尋結果中排名更高,從而提高可見度和流量。 ### 轉換率 尤其是電子商務網站,他們敏銳地意識到速度對轉換率的影響。更快的網站可以帶來更高的轉換率,從而增加收入。 ### 移動效能 隨著行動裝置的普及,對速度的需求變得更加重要。行動用戶的頻寬和處理能力通常有限,因此需要快速的應用程式效能。 ### JSON 會減慢我們的應用程式速度嗎? 現在,讓我們解決核心問題:JSON 是否會減慢我們的應用程式速度? 如同前面提到的,JSON 是一種非常流行的資料交換格式。它靈活、易於使用且廣受支援。然而,這種廣泛的採用並不能使其免受性能挑戰。 在某些情況下,JSON 可能是降低應用程式速度的罪魁禍首。解析 JSON 資料的過程,尤其是在處理大型或複雜結構時,可能會消耗寶貴的毫秒時間。此外,低效率的序列化和反序列化可能會影響應用程式的整體效能。 ### 解析開銷 當 JSON 資料到達您的應用程式時,它必須經過解析過程才能將其轉換為可用的資料結構。解析可能相對較慢,尤其是在處理大量或深層巢狀的 JSON 資料時。 ``` // JavaScript example using JSON.parse for parsing const jsonData = '{"key": "value"}'; const parsedData = JSON.parse(jsonData); ``` ### 序列化與反序列化 JSON 要求資料從用戶端傳送到伺服器時進行序列化(將物件編碼為字串),並在接收時進行反序列化(將字串轉換回可用物件)。這些步驟可能會帶來開銷並影響應用程式的整體速度。 ``` // Node.js example using JSON.stringify for serialization const data = { key: 'value' }; const jsonString = JSON.stringify(data); ``` ### 字串操作 JSON 是基於文字的,嚴重依賴字串操作來進行連接和解析等操作。與處理二進位資料相比,字串處理可能會慢一些。 ### 缺乏資料類型 JSON 具有一組有限的資料類型(例如字串、數字、布林值)。複雜的資料結構可能需要效率較低的表示,導致記憶體使用量增加和處理速度變慢。 ``` { "quantity": 1.0 } ``` ### 冗長 JSON 的人類可讀設計可能會導致冗長。冗餘金鑰和重複結構會增加有效負載大小,導致資料傳輸時間更長。 ``` // Inefficient { "product1": { "name": "Product A", "price": 10 }, "product2": { "name": "Product A", "price": 10 } } ``` ### 沒有二進位支持 JSON 缺乏對二進位資料的本機支援。在處理二進位資料時,開發人員通常需要將其編碼和解碼為文本,這可能會降低效率。 ### 深度嵌套 在某些場景下,JSON資料可能會深度嵌套,需要遞歸解析和遍歷。這種計算複雜性可能會減慢您的應用程式的速度,尤其是在沒有最佳化的情況下。 --- > **與此類似,我與其他熱愛開源的開發人員一起在 Slack 上運行一個以開發人員為中心的社群。我們討論這些類型的主題、實現、整合、一些真相炸彈、奇怪的聊天、虛擬會議、為開源做出貢獻以及一切有助於開發人員保持理智的事情;)畢竟,太多的知識也可能是危險的。* * > **我邀請您加入我們的免費社區(_沒有廣告,我保證,並且我打算保持這種方式_),參與討論,並分享您的經驗和專業知識。您可以填寫此表格,Slack 邀請將在幾天後收到您的電子郵件。我們有來自一些偉大公司(Atlassian、Gong、Scaler)的優秀人員,您一定不想錯過與他們的互動。 [邀請表](https://forms.gle/VzA3ST8tCFrxt39U9)** 讓我們繼續... --- ## JSON 的替代方案 雖然 JSON 是一種通用的資料交換格式,但其在某些場景下的效能限制導致人們探索更快的替代方案。讓我們深入研究其中一些替代方案,並了解您何時以及為何選擇它們: ### 協定緩衝區 Protocol Buffers,也稱為 protobuf,是 Google 開發的二元序列化格式。它在速度和效率方面表現出色。這就是您可能考慮使用 Protocol Buffer 的原因: 1. **二進位編碼**:Protocol Buffers 使用二進位編碼,與 JSON 基於文字的編碼相比,它更緊湊,編碼和解碼速度更快。 2. **高效的資料結構**:Protocol Buffers 可讓您透過精確的類型定義高效的資料結構,從而實現更快的序列化和反序列化。 3. **架構演化**:Protocol Buffers 支援架構演化,這表示您可以在不破壞向後相容性的情況下更新資料結構。 ``` syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` ### 訊息包 MessagePack 是另一種專為提高效率和速度而設計的二元序列化格式。以下是您可能考慮使用 MessagePack 的原因: 1. **緊湊性**:MessagePack 產生高度緊湊的資料表示形式,從而減少資料傳輸大小。 2. **二進位資料**:MessagePack 提供了對二進位資料的原生支持,非常適合涉及二進位資訊的場景。 3. **速度**:MessagePack 的二進位性質允許快速編碼和解碼。 ``` // JavaScript example using MessagePack for serialization const msgpack = require('msgpack-lite'); const data = { key: 'value' }; const packedData = msgpack.encode(data); ``` ### BSON(二進位 JSON) BSON,通常發音為“bee-son”或“bi-son”,是一種二進位序列化格式,主要用於 MongoDB 等資料庫。以下是您可能考慮使用 BSON 的原因: 1. **類似 JSON 的結構**:BSON 維護了類似 JSON 的結構,並添加了二進位資料類型,在效率和可讀性之間提供了平衡。 2. **二進位資料支援**:BSON 提供對二進位資料類型的原生支持,這有利於處理映像或多媒體等資料。 3. **資料庫集成**:BSON 與 MongoDB 等資料庫無縫集成,使其成為此類環境的自然選擇。 ``` { "_id": ObjectId("60c06fe9479e1a1280e6bfa7"), "name": "John Doe", "age": 30 } ``` ### 歐元 Avro 是在 Apache Hadoop 專案中開發的資料序列化框架。它強調模式相容性和效能。以下是您可能考慮使用 Avro 的原因: 1. **架構相容性**:Avro 優先考慮架構相容性,讓您在不破壞相容性的情況下發展資料結構。 2. **二進位資料**:Avro 使用緊湊的二進位編碼格式進行資料傳輸,從而產生更小的有效負載。 3. **語言中立**:Avro 支援多種程式語言,使其適合不同的應用程式生態系統。 ``` { "type": "record", "name": "Person", "fields": [ { "name": "name", "type": "string" }, { "name": "age", "type": "int" } ] } ``` JSON 及其替代方案之間的選擇取決於您的特定用例和要求。如果架構相容性至關重要,Avro 可能是最佳選擇。如果您需要緊湊性和效率,MessagePack 和 Protocol Buffers 是強有力的競爭者。在處理二進位資料時,MessagePack 和 BSON 可以滿足您的需求。每種格式都有其優點和缺點,因此請選擇適合您專案需求的格式。 ### 最佳化 JSON 效能 但是,如果您決心使用 JSON,儘管它有潛在的速度障礙,該怎麼辦?如何讓 JSON 運作得更快、更有效率?好消息是,有一些實用的策略和最佳化可以幫助您實現這一目標。讓我們透過程式碼範例和最佳實踐來探索這些策略。 **1.最小化資料大小** A。 **使用簡短的描述性鍵**:選擇簡潔但有意義的鍵名稱以減少 JSON 物件的大小。 ``` // Inefficient { "customer_name_with_spaces": "John Doe" } // Efficient { "customerName": "John Doe" } ``` b. **盡可能縮寫**:在不犧牲清晰度的情況下,考慮使用鍵或值的縮寫。 ``` // Inefficient { "transaction_type": "purchase" } // Efficient { "txnType": "purchase" } ``` **2.明智地使用數組** A。 **最小化巢狀**:避免深度巢狀數組,因為它們會增加解析和遍歷 JSON 的複雜度。 ``` // Inefficient { "order": { "items": { "item1": "Product A", "item2": "Product B" } } } // Efficient { "orderItems": ["Product A", "Product B"] } ``` **3.優化數位表示** A。 **盡可能使用整數**:如果一個值可以表示為整數,請使用它而不是浮點數。 ``` // Inefficient { "quantity": 1.0 } // Efficient { "quantity": 1 } ``` **4.刪除冗餘** A。 **避免重複資料**:透過引用共享值來消除冗餘資料。 ``` // Inefficient { "product1": { "name": "Product A", "price": 10 }, "product2": { "name": "Product A", "price": 10 } } // Efficient { "products": [ { "name": "Product A", "price": 10 }, { "name": "Product B", "price": 15 } ] } ``` **5.使用壓縮** A。 **套用壓縮演算法**:如果適用,請使用 Gzip 或 Brotli 等壓縮演算法來減少傳輸過程中 JSON 有效負載的大小。 ``` // Node.js example using zlib for Gzip compression const zlib = require('zlib'); const jsonData = { // Your JSON data here }; zlib.gzip(JSON.stringify(jsonData), (err, compressedData) => { if (!err) { // Send compressedData over the network } }); ``` 根據塞繆爾的評論,我添加了一個編輯。 {% devcomment 2adn4 %} ``` As Samuel rightly observes, the adoption of HTTP/2 has brought significant advancements, particularly in optimizing data interchange formats like JSON. HTTP/2's multiplexing capabilities efficiently manage multiple requests over a single connection, enhancing responsiveness and reducing overhead. In practical terms, a comprehensive optimization strategy may involve both embracing HTTP/2 and utilizing compression techniques per your use-case, recognizing that each approach addresses specific aspects of network efficiency and performance. HTTP/2 excels in network-level optimization, while compression strategies enhance application-level efficiency, and the synergy between them can lead to substantial gains in data handling speed and resource utilization. ``` **6。使用伺服器端快取** A。 **快取 JSON 回應**:實作伺服器端快取以有效儲存和提供 JSON 回應,減少重複資料處理的需要。 **7.設定檔和優化** A。 **分析效能**:使用分析工具來識別 JSON 處理程式碼中的瓶頸,然後最佳化這些部分。 請記住,您實施的具體優化應符合應用程式的要求和約束。 ### 實際最佳化:在實作中加速 JSON 現在您已經探索了優化 JSON 的理論方面,現在是時候深入研究遇到 JSON 效能瓶頸並巧妙克服它們的實際應用程式和專案了。這些範例提供了有關用於提高速度和回應能力的策略的寶貴見解,同時仍利用 JSON 的多功能性。 **1. LinkedIn 的協定緩衝區整合** *挑戰:LinkedIn 與 JSON 冗長和網路頻寬使用的鬥爭* 全球最大的職業社交平台LinkedIn面臨嚴峻的挑戰。他們對 JSON 進行微服務通訊的依賴導致了冗長和網路頻寬使用量的增加,最終導致更高的延遲。在每一毫秒都至關重要的數位世界中,這是一個需要解決方案的挑戰。 **解決方案:協定緩衝區的力量** LinkedIn 轉向了 [Protocol Buffers](https://engineering.linkedin.com/blog/2023/linkedin-integrates-protocol-buffers-with-rest-li-for-improved-m),通常稱為 protobuf,由Google開發的二進位序列化格式。 Protocol Buffers 的主要優勢在於其效率、緊湊性和速度,使其在序列化和反序列化方面比 JSON 快得多。 **影響:延遲減少高達 60%** Protocol Buffers 的採用顯著降低了延遲,報告顯示延遲可提高高達 60%。此次優化顯著提高了 LinkedIn 服務的速度和回應能力,為全球數百萬用戶提供了更流暢的體驗。 **2. Uber 的 H3 地理索引** *挑戰:Uber 在地理空間資料方面的 JSON 困境* 叫車巨頭優步的營運嚴重依賴地理空間數據。 JSON 是表示地理空間資料的預設選擇,但解析大型資料集的 JSON 被證明是一個瓶頸,減慢了演算法的速度。 **解決方案:引入 H3 地理索引** Uber 推出了 [H3 Geo-Index](https://www.uber.com/en-IN/blog/h3/),這是一種用於地理空間資料的高效能六邊形網格系統。透過從 JSON 轉向這種創新解決方案,他們成功地大幅減少了 JSON 解析開銷。 **影響:加速地理空間操作** 這種優化大大加速了地理空間操作,提高了 Uber 乘車服務和地圖系統的效率。使用者體驗到更快的回應時間和更可靠的服務。 **3. Slack 的訊息格式最佳化** *挑戰:Slack 與即時訊息渲染的戰鬥* Slack 是團隊的訊息平台,需要在即時聊天中傳輸和呈現大量 JSON 格式的訊息。然而,這導致了效能瓶頸和訊息渲染緩慢。 **解決方案:簡化 JSON 結構** Slack 優化了 JSON 結構以減少不必要的資料。他們開始在每個訊息中只包含基本訊息,從而減少有效負載的大小。 **影響:更快的訊息渲染和增強的聊天效能** 此優化顯著提高了訊息渲染速度。 Slack 用戶享受到更靈敏、更有效率的聊天體驗,尤其是在繁忙的群組聊天中。 **4. Auth0 的協定緩衝區實作** *挑戰:Auth0的身份驗證和授權資料效能* Auth0 是一個著名的身份和存取管理平台,在處理身份驗證和授權資料時面臨 JSON 的效能挑戰。這些數據需要在不影響安全性的情況下有效處理。 **解決方案:採用協定緩衝區進行資料序列化** [Auth0 也轉向Protocol Buffers](https://auth0.com/blog/beating-json-performance-with-protobuf/#How-Do-We-Use-Protobuf),利用其高效的資料序列化和反序列化功能。此交換器顯著提高了資料處理速度,使身份驗證過程更快並增強了整體效能。 **影響:加速身份驗證和授權** Protocol Buffers 的採用增強了身分驗證和授權流程,確保 Auth0 的服務提供一流的效能,同時保持最高的安全標準。 這些現實世界的例子強調了優化在克服 JSON 相關的速度下降方面的力量。這些案例中採用的策略證明了 JSON 和替代格式在滿足現代數位環境的需求方面的適應性和多功能性。 請繼續關注結論部分,我們總結了關鍵要點,並為您提供了在您自己的專案中優化 JSON 效能的路線圖。 ## 結束語 在開發領域,JSON 是一種多功能且不可或缺的資料交換工具。其人類可讀的結構和跨語言適應性使其成為當代應用程式的基石。然而,正如我們在本指南中的探索所揭示的那樣,JSON 的普遍使用並不能使其免受性能挑戰。 我們在增強 JSON 效能的過程中獲得的重要收穫是顯而易見的: - 1. **效能至關重要:** 速度和反應能力在當今的數位環境中至關重要。用戶要求應用程式以閃電般的速度運行,即使是輕微的延遲也會導致不滿意並錯失機會。 - 2. **大小很重要:** 資料有效負載的大小直接影響網路頻寬使用和回應時間。減少資料大小通常是優化 JSON 效能的第一步。 - 3. **探索替代格式:** 當效率和速度至關重要時,探索替代資料序列化格式(如 Protocol Buffers、MessagePack、BSON 或 Avro)是有益的。 - 4. **真實世界範例:** 從組織有效解決 JSON 相關減速問題的真實實例中學習,表明最佳化工作可以顯著提高應用程式效能。 當您繼續開發和增強 Web 應用程式時,請務必牢記 JSON 對效能的影響。精心設計資料結構,選擇有意義的鍵名稱,並在情況需要時開放探索替代序列化格式。透過這樣做,您可以確保您的應用程式在速度和效率方面不僅滿足而且超越用戶的期望。 在不斷發展的 Web 開發環境中,優化 JSON 效能成為一項寶貴的資產,使您的專案與眾不同,並確保您的應用程式在即時數位體驗時代蓬勃發展。 --- > **與此類似,我與其他熱愛開源的開發人員一起在 Slack 上運行一個以開發人員為中心的社群。我們討論這些類型的主題、實現、整合、一些真相炸彈、奇怪的聊天、虛擬會議、為開源做出貢獻以及一切有助於開發人員保持理智的事情;)畢竟,太多的知識也可能是危險的。* * > **我邀請您加入我們的免費社區(_沒有廣告,我保證,並且我打算保持這種方式_),參與討論,並分享您的經驗和專業知識。您可以填寫此表格,Slack 邀請將在幾天後收到您的電子郵件。我們有來自一些偉大公司(Atlassian、Gong、Scaler)的優秀人員,您一定不想錯過與他們的互動。 [邀請表](https://forms.gle/VzA3ST8tCFrxt39U9)** > _如果您能與您的開發朋友(他們是奉獻者)分享該表格,我將不勝感激。_