有了ChatGPT編程我們還需要使用那么多庫嗎
瀑布流展示圖片的新需求
我已經(jīng)可以生成一些圖片了,但是光看圖片我能看出什么來?我需要展示出圖片和圖片的信息。這可能就要專門開發(fā)一下了。
我當時想,這個可能有點難,他是個前后端都有的程序。所以我就本能的想到,要不要找找有個庫沒有,先找個瀑布流展示圖片的現(xiàn)成的庫,在上面稍微改改可能是比較簡單的做法。害怕ChatGPT不行,我還去問了new bing,我想著,newbing的知識更新一點,于是我問:
指定一個path直接啟動一個nodejs server,通過localhost訪問,以瀑布流形式展示path下所有圖片的npm工具
結果他建議我使用node-static的庫,于是我就追問了一些怎么用node-static庫的方式去寫代碼,得到的代碼可能由于知識過時,反正是不能用的,我就不貼在這里了。
有點沮喪,這稍微用點庫你就給我撂挑子,你這果然也不行啊,一用庫就出錯,你這果然勝任不了復雜開發(fā)。new bing不靠譜,我就又去問ChatGPT,一開始我問得有問題,我直接問:
用node-static庫怎么實現(xiàn):指定一個path直接啟動一個nodejs server,通過localhost訪問,以瀑布流形式展示path下所有圖片
結果顯示的代碼果然是不能用的,我心想對啊,new bing都沒有新數(shù)據(jù),你這個數(shù)據(jù)豈不是更糟糕?但是靈機一動之下,我也沒退出,我就問
上面的代碼不能運行,有沒有別的辦法?
然后我得到了下面的回答:
可以使用Node.js的http和fs模塊來啟動一個HTTP服務器,并且使用path模塊來獲取文件路徑,以及使用mime模塊來獲取文件的MIME類型,然后通過HTML和CSS來創(chuàng)建一個簡單的瀑布流布局。
以下是一個示例代碼:
const http = require('http'); const fs = require('fs'); const path = require('path'); const mime = require('mime'); const PORT = 3000; const PATH = './path'; // 設置圖片目錄的路徑 http.createServer((req, res) => { console.log(`Request for ${req.url}`); // 如果請求的是根路徑,返回圖片列表頁面 if (req.url === '/') { res.writeHead(200, { 'Content-Type': 'text/html' }); // 讀取圖片目錄下的所有文件 fs.readdir(PATH, (err, files) => { if (err) { console.error(err); res.end('Error reading directory'); return; } // 使用HTML和CSS創(chuàng)建瀑布流布局 res.write(` <html> <head> <title>Image Gallery</title> <style> .container { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-gap: 10px; } .item { position: relative; } .item img { width: 100%; height: auto; } .item .caption { position: absolute; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.5); color: #fff; padding: 5px; } </style> </head> <body> <div class="container"> `); // 遍歷所有文件,并在瀑布流布局中展示圖片和文件名 files.forEach((file) => { const filePath = path.join(PATH, file); const mimeType = mime.getType(filePath); if (mimeType && mimeType.startsWith('image/')) { res.write(` <div class="item"> <img src="${filePath}" alt="${file}"> <div class="caption">${file}</div> </div> `); } }); res.write(` </div> </body> </html> `); res.end(); }); } else { // 否則,返回請求的文件 const filePath = path.join(PATH, req.url); const mimeType = mime.getType(filePath); if (mimeType && mimeType.startsWith('image/')) { // 如果請求的是圖片文件,則返回圖片數(shù)據(jù) fs.readFile(filePath, (err, data) => { if (err) { console.error(err); res.writeHead(404); res.end('Not found'); return; } res.writeHead(200, { 'Content-Type': mimeType }); res.end(data); }); } else { // 否則,返回404錯誤 res.writeHead(404); res.end('Not found'); } } }).listen(PORT); console.log(`Server running at http://localhost:${PORT}`);
將上述代碼保存為app.js文件,然后在終端中進入該文件所在的目錄,并運行以下命令: node app.js 運行該命令后,服務器將會在本地3000端口上啟動。您可以在瀏覽器中輸入
http://localhost:3000/來查看圖片列表,其中/表示根路徑,這將會顯示圖片列表頁面,瀑布流形式展示path下所有圖片。如果您想直接訪問某張圖片,可以通過輸入其文件名來訪問,例如http://localhost:3000/example.jpg。
請注意,在上述示例中,我們假設所有圖片文件的MIME類型都以image/開頭,這通常是正確的,但如果您的圖片文件類型不同,則可能需要修改相關代碼。
咦?可以用原生寫法啊,我立刻修改了自己的提問:
我需要用nodejs寫一個后端服務,可以指定一個文件夾,按瀑布流顯示下面所有的png圖片。 要求:
可以通過傳參指定任意基于index.js的相對文件夾及子文件夾
要并排顯示png圖片和png圖片文件中的文本信息
頁面要用BootStrap布局
我有一個模塊:'./util/png_info/index'。 該模塊導出的對象上有一個異步函數(shù) readPng 可以讀取 PNG 圖像文件中的文本信息。不用實現(xiàn),其簽名為:
async function readPng(filePath) { //.... }
指定index.js所在文件夾為靜態(tài)文件夾
我得到了可以執(zhí)行的代碼:
const express = require('express'); const path = require('path'); const fs = require('fs'); const { readPng } = require('./util/png_info'); const app = express(); // 設置靜態(tài)文件夾 app.use(express.static(path.join(__dirname))); app.get('/images', async (req, res) => { try { const folderPath = req.query.folder; const images = await getImages(folderPath); const imagesHTML = await Promise.all( images.map(async (image) => { const info = await readPng(image.path); return ` <div class="col-md-3"> <img src="${image.url}" class="img-thumbnail" alt="${image.name}"> <div class="text-muted">${info}</div> </div> `; }) ); const html = ` <html> <head> <title>Image Gallery</title> <link rel="external nofollow" rel="stylesheet"> </head> <body> <div class="container"> <div class="row"> ${imagesHTML.join('')} </div> </div> </body> </html> `; res.send(html); } catch (error) { console.error(error); res.status(500).send('Internal Server Error'); } }); async function getImages(folderPath) { const images = []; const files = await fs.promises.readdir(folderPath, { withFileTypes: true }); for (const file of files) { if (file.isDirectory()) { const subfolderPath = path.join(folderPath, file.name); const subfolderImages = await getImages(subfolderPath); images.push(...subfolderImages); } else if (file.name.endsWith('.png')) { const url = path.join('/', path.relative(__dirname, folderPath), file.name).replace(/\\/g, '/'); images.push({ name: file.name, path: path.join(folderPath, file.name), url }); } } return images; } const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`Server listening on port ${port}`); });
開悟時刻
這一刻,我開悟了,對啊,要什么庫啊!我需要重新反思我的工作習慣,以前之所以要搞那么多的庫為的是什么?現(xiàn)在這些庫還有沒有存在的必要要重新思考一下。
比如這里,我覺得寫一個瀑布流很麻煩,于是我想到搞個庫,這個是一個舊時代的思維定式。這是因為自己開發(fā)很花成本,我自己寫有可能會相關技術不熟有可能會寫錯,所以我的生產效率比較低。比如寫一個例子里這樣的東西,它涉及到非常多的知識點:nodejs的、css的、HTML的;還有很多集成點:前端后端你把它們連起來,可能會連錯。太多的點要考慮了。這個每一個點上我可能我的知識儲備不夠,或者我忘了,我還要重新去學習,重新去查找;又或者我在集成的時候,個人會犯太多的錯,完了就要重新調試,都是成本。所以我選擇了使用一個庫。
但是使用一個庫就沒有成本嗎?查找是個成本,學習是個成本,然后呢你查的資料和現(xiàn)在的庫有可能對不上,還會產生浪費,也是成本。但是在以前我們就忍了,因為自己開發(fā)的成本遠遠大于使用庫的成本。但是今天,對于ChatGPT來說,前面提到的自己開發(fā)的那些問題,它還是問題嗎?它不是問題啊。
然后我又想到前面的node-static庫為什么不行?而你看在這個里面他也用了庫,他用了express,用了fs,用了path。為什么后面這幾個庫就沒有問題,前面那個node-static庫就有問題?因為前面?zhèn)€庫接口不穩(wěn)定,ChatGPT學習到了舊版接口的使用方法,而那個庫更新了。這么專用的一個庫為什么要更新接口?還不是為了讓人用的方便。因為可能會有人反饋說你這個接口不好理解,不容易理解。這個你能不能換一個接口?他這一換接口對于用新接口的人可能是舒服的,但是對于像我這樣只是想簡單用一下的人就很郁悶了,因為資料都變了。很有可能會出現(xiàn)我查了資料,照著寫了代碼,然后用不起來的情況。在軟件開發(fā)的世界里面,這種事情不要太多。
對于 ChatGPT 來說,這種變化是好還是壞?人在使用上那一點點微小的\心理上的爽感對于 ChatGPT 來說是沒有任何好處的,反而是有害的。那么在今天這個時代,我們?yōu)槭裁催€要使用那些繁重的庫?我們是不是應該直接回歸本源?就用最基礎、最簡單封裝的庫。這些都有一個特點。接口穩(wěn)定。從誕生之初到現(xiàn)在沒有太大變化。這個對于ChatGPT才是最友好的。
推而廣之
讓我們暢想一下,比如Java企業(yè)開發(fā)領域,是不是像是spring data這種東西。它的價值可能就不如SQL了,spring data這個東西一年不看都能有一大堆的變化,而sql這么多年了都沒什么變化。這才是最好的。除非我們能找到。SQL不能滿足的場景。在那里封裝一個簡單的框架。比如說就是MyBatis。
所以在基于 ChatGPT 進行編程為前提,我們進行技術棧選型時,依賴庫接口的穩(wěn)定性就變得格外重要了。不客氣的說,在今天這個時代,接口的穩(wěn)定性壓倒一切。這就像在蒸汽機時代,鐵軌的間距是不能隨心隨意的。只有穩(wěn)定的鐵軌間距。才會有高效的運輸效率。同理,只有穩(wěn)定的接口才能最大限度的發(fā)揮 ChatGPT 的能力,得到極高的開發(fā)效率。那些僅僅是因為幫助人少寫幾行代碼而開發(fā)的。變化在今天這個時代,能不引入還是不要引入。畢竟你在上面包一層的成本已經(jīng)開始無限趨近于0了。你為什么還要讓下面的接口遷就你呢?下層接口只要穩(wěn)定的干好自己該干的事情,并且提供穩(wěn)定的接口就夠了。
這個變化對于今天非常多的企業(yè)中臺都是一個重大利好。我們知道很多企業(yè)中臺這么多年都疲于奔命。淪為給前臺的“大客戶”打工。通常對于企業(yè)來說,前臺分為幾種?
一種是類似企業(yè)的“大客戶”,就是企業(yè)里最賺錢的前臺部門,那么我們就要配很大的人力去服務好他,“大客戶”自己呢,通常就任性一點,所以會把他們的需求直接扔給我。那我們不得不改以適配“大客戶”。
還有一些是小客戶,但是因為都在企業(yè)里,你不能像在市場里一樣說,小客戶我就不管了,我們是專做高端服務的。小客戶你也要管,成年人全都要嘛。這中間的矛盾呢,就使得很多設計上本來已經(jīng)說的很清楚的原則,根本落了地。
其實想想挺可笑的,過去那么多年,我們都說,下層要穩(wěn)定下層要穩(wěn)定,結果下層總也穩(wěn)定不了。為什么呢?不就是上層的新需求來了,非要讓我們下層的搞嘛。該我們搞的,我們搞,你們用著不方便也讓我們搞這是不是有點過分了,方便這個東西哪是有止境的呀?最方便的就是你們什么都不做,都讓我們做了,才最方便不是嗎?這么搞它接口能穩(wěn)定嗎?
但是話又說回來了,以前沒有辦法呀。中臺有很強的開發(fā)力量,前臺有嗎?通常前臺是沒有的。而前臺一句你不好用,中臺就政治不正確了,所以不得已我們就要配很多的開發(fā)力量來解決這些非技術的所謂技術問題。畢竟大家都要為效率低頭嘛,前中后臺端到端全局效率最高才是我們追求的方向。你不能說我中臺設計的好了,我效率高了,你整體效率上不去。你這個單點效率高又有什么用?
所以這就是個死局。以前大家都裝作努力在解,其實本質上都是非常原始的解法,解得所有人都痛苦。但是在今天我們迎來了新的生產工具。讓我們看到了這個矛盾可以被消解的可能,因為穩(wěn)定。不僅僅可以讓中臺的開發(fā)效率提升,也可以讓前臺開發(fā)效率提升。一個變動的接口,對前臺也是不友好的,畢竟隨著 ChatGPT 這類大語言模型的推廣,前臺的開發(fā)能力被史詩級加強,我們可以看到,微軟在Power Platform上已經(jīng)推出Copilot功能來實踐這種模式了。
總結一下
開篇我們引入了一個以瀑布流形式展示圖片需求,一開始,我們采用習慣的思路,嘗試使用一個庫來解決這個問題。但馬上就遇到了問題,這并不是ChatGPT擅長的事情,然而當我問 ChatGPT 有沒有其他方法的時候,我得到了原生寫法的解決方案。
這讓我們意識到在基于 ChatGPT 編程的背景下,重新審視庫。過往的很多庫都是會為了人們好用而不停地提供一些新的接口,這些接口讓人們用著很舒服,但是其實帶來了學習成本,以及學習資料的過時。很多人都不喜歡學習新技術,就是覺得亂,看起來也不是沒有道理。
所以那些古老的但是依然在用的庫是更能發(fā)揮出 ChatGPT 的效力的。依然在使用表示沒有過時,依然有價值,古老表示接口穩(wěn)定,資料最全。所以我們是不是要反思一下,發(fā)明那么多庫有沒有可能一定程度上走錯了路。這讓我想起三體里面,人類建了那么多的星際艦隊,三體就搞了一個水滴,只用撞擊這一個動作就把那些花里花哨的攻擊方式給比下去了。這層頓悟導致我之后一段時間在技術群里看到有人問什么功能有沒有現(xiàn)成的庫的時候,不自覺的會在腦子里蹦出一個吐槽:“哼,原始人”。這心態(tài)很不好,但是確實很貼切,興許隨著此類大語言模型AI的發(fā)展,我們以前的很多花里胡哨的做法真的看起來就很像傳統(tǒng)武術里的很多招數(shù),在熱武器面前不再具有普遍的價值。
那么推而廣之,穩(wěn)定的接口對于發(fā)揮ChatGPT的能力以提高開發(fā)效率至關重要。在技術棧選型時,穩(wěn)定性應該成為優(yōu)先考慮的因素。甚至于對于中臺建設都有很大利好,在企業(yè)中臺的建設中,前臺和中臺之間的矛盾導致中臺的接口和功能都無法穩(wěn)定。然而,隨著ChatGPT這類大語言模型的普及,前臺的開發(fā)能力得到了極大的提升,讓中臺穩(wěn)定成為可能,微軟的Power Platform已經(jīng)在摸索類似的模式了。
這一篇我們講了一個思路上轉變,使用 ChatGPT 的過程中,經(jīng)常會遇到這種思路轉變的情況,每次轉變都會覺得上一刻的自己是多么的愚蠢。所以建議大家盡快用起來,認知的轉變可能會帶來完全不同的風景。下一篇我們講講另一個引起我思路轉變的手法,這也是很多人用ChatGPT處理長內容時的一個思維盲區(qū)。
以上就是有了ChatGPT編程我們還需要那么多庫嗎的詳細內容,更多關于ChatGPT編程的資料請關注腳本之家其它相關文章!
相關文章
NPM 安裝cordova時警告:npm WARN deprecated minimatch@2.0.10: Pleas
這篇文章主要介紹了NPM 安裝cordova時警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to的相關資料,需要的朋友可以參考下2016-12-12詳解如何優(yōu)雅在webpack項目實現(xiàn)mock服務器
這篇文章主要為大家介紹了詳解如何優(yōu)雅在webpack項目實現(xiàn)mock服務器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02Windows環(huán)境下npm install 報錯: operation not permitted, rename的解決
這篇文章主要介紹了Windows環(huán)境下npm install 報錯: operation not permitted, rename的解決方法,文中對解決的方法介紹的很詳細,有需要的朋友們可以參考借鑒。2016-09-09阿里大于短信驗證碼node koa2的實現(xiàn)代碼(最新)
本文給大家分享一個最新版阿里大于短信驗證碼node koa2的實現(xiàn)代碼及注意事項,需要的朋友參考下吧2017-09-09