有了ChatGPT編程我們還需要使用那么多庫嗎
瀑布流展示圖片的新需求
我已經(jīng)可以生成一些圖片了,但是光看圖片我能看出什么來?我需要展示出圖片和圖片的信息。這可能就要專門開發(fā)一下了。
我當(dāng)時(shí)想,這個(gè)可能有點(diǎn)難,他是個(gè)前后端都有的程序。所以我就本能的想到,要不要找找有個(gè)庫沒有,先找個(gè)瀑布流展示圖片的現(xiàn)成的庫,在上面稍微改改可能是比較簡單的做法。害怕ChatGPT不行,我還去問了new bing,我想著,newbing的知識(shí)更新一點(diǎn),于是我問:
指定一個(gè)path直接啟動(dòng)一個(gè)nodejs server,通過localhost訪問,以瀑布流形式展示path下所有圖片的npm工具
結(jié)果他建議我使用node-static的庫,于是我就追問了一些怎么用node-static庫的方式去寫代碼,得到的代碼可能由于知識(shí)過時(shí),反正是不能用的,我就不貼在這里了。
有點(diǎn)沮喪,這稍微用點(diǎn)庫你就給我撂挑子,你這果然也不行啊,一用庫就出錯(cuò),你這果然勝任不了復(fù)雜開發(fā)。new bing不靠譜,我就又去問ChatGPT,一開始我問得有問題,我直接問:
用node-static庫怎么實(shí)現(xiàn):指定一個(gè)path直接啟動(dòng)一個(gè)nodejs server,通過localhost訪問,以瀑布流形式展示path下所有圖片
結(jié)果顯示的代碼果然是不能用的,我心想對啊,new bing都沒有新數(shù)據(jù),你這個(gè)數(shù)據(jù)豈不是更糟糕?但是靈機(jī)一動(dòng)之下,我也沒退出,我就問
上面的代碼不能運(yùn)行,有沒有別的辦法?
然后我得到了下面的回答:
可以使用Node.js的http和fs模塊來啟動(dòng)一個(gè)HTTP服務(wù)器,并且使用path模塊來獲取文件路徑,以及使用mime模塊來獲取文件的MIME類型,然后通過HTML和CSS來創(chuàng)建一個(gè)簡單的瀑布流布局。
以下是一個(gè)示例代碼:
const http = require('http'); const fs = require('fs'); const path = require('path'); const mime = require('mime'); const PORT = 3000; const PATH = './path'; // 設(shè)置圖片目錄的路徑 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錯(cuò)誤 res.writeHead(404); res.end('Not found'); } } }).listen(PORT); console.log(`Server running at http://localhost:${PORT}`);
將上述代碼保存為app.js文件,然后在終端中進(jìn)入該文件所在的目錄,并運(yùn)行以下命令: node app.js 運(yùn)行該命令后,服務(wù)器將會(huì)在本地3000端口上啟動(dòng)。您可以在瀏覽器中輸入
http://localhost:3000/來查看圖片列表,其中/表示根路徑,這將會(huì)顯示圖片列表頁面,瀑布流形式展示path下所有圖片。如果您想直接訪問某張圖片,可以通過輸入其文件名來訪問,例如http://localhost:3000/example.jpg。
請注意,在上述示例中,我們假設(shè)所有圖片文件的MIME類型都以image/開頭,這通常是正確的,但如果您的圖片文件類型不同,則可能需要修改相關(guān)代碼。
咦?可以用原生寫法啊,我立刻修改了自己的提問:
我需要用nodejs寫一個(gè)后端服務(wù),可以指定一個(gè)文件夾,按瀑布流顯示下面所有的png圖片。 要求:
可以通過傳參指定任意基于index.js的相對文件夾及子文件夾
要并排顯示png圖片和png圖片文件中的文本信息
頁面要用BootStrap布局
我有一個(gè)模塊:'./util/png_info/index'。 該模塊導(dǎo)出的對象上有一個(gè)異步函數(shù) readPng 可以讀取 PNG 圖像文件中的文本信息。不用實(shí)現(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(); // 設(shè)置靜態(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}`); });
開悟時(shí)刻
這一刻,我開悟了,對啊,要什么庫啊!我需要重新反思我的工作習(xí)慣,以前之所以要搞那么多的庫為的是什么?現(xiàn)在這些庫還有沒有存在的必要要重新思考一下。
比如這里,我覺得寫一個(gè)瀑布流很麻煩,于是我想到搞個(gè)庫,這個(gè)是一個(gè)舊時(shí)代的思維定式。這是因?yàn)樽约洪_發(fā)很花成本,我自己寫有可能會(huì)相關(guān)技術(shù)不熟有可能會(huì)寫錯(cuò),所以我的生產(chǎn)效率比較低。比如寫一個(gè)例子里這樣的東西,它涉及到非常多的知識(shí)點(diǎn):nodejs的、css的、HTML的;還有很多集成點(diǎn):前端后端你把它們連起來,可能會(huì)連錯(cuò)。太多的點(diǎn)要考慮了。這個(gè)每一個(gè)點(diǎn)上我可能我的知識(shí)儲(chǔ)備不夠,或者我忘了,我還要重新去學(xué)習(xí),重新去查找;又或者我在集成的時(shí)候,個(gè)人會(huì)犯太多的錯(cuò),完了就要重新調(diào)試,都是成本。所以我選擇了使用一個(gè)庫。
但是使用一個(gè)庫就沒有成本嗎?查找是個(gè)成本,學(xué)習(xí)是個(gè)成本,然后呢你查的資料和現(xiàn)在的庫有可能對不上,還會(huì)產(chǎn)生浪費(fèi),也是成本。但是在以前我們就忍了,因?yàn)樽约洪_發(fā)的成本遠(yuǎn)遠(yuǎn)大于使用庫的成本。但是今天,對于ChatGPT來說,前面提到的自己開發(fā)的那些問題,它還是問題嗎?它不是問題啊。
然后我又想到前面的node-static庫為什么不行?而你看在這個(gè)里面他也用了庫,他用了express,用了fs,用了path。為什么后面這幾個(gè)庫就沒有問題,前面那個(gè)node-static庫就有問題?因?yàn)榍懊鎮(zhèn)€庫接口不穩(wěn)定,ChatGPT學(xué)習(xí)到了舊版接口的使用方法,而那個(gè)庫更新了。這么專用的一個(gè)庫為什么要更新接口?還不是為了讓人用的方便。因?yàn)榭赡軙?huì)有人反饋說你這個(gè)接口不好理解,不容易理解。這個(gè)你能不能換一個(gè)接口?他這一換接口對于用新接口的人可能是舒服的,但是對于像我這樣只是想簡單用一下的人就很郁悶了,因?yàn)橘Y料都變了。很有可能會(huì)出現(xiàn)我查了資料,照著寫了代碼,然后用不起來的情況。在軟件開發(fā)的世界里面,這種事情不要太多。
對于 ChatGPT 來說,這種變化是好還是壞?人在使用上那一點(diǎn)點(diǎn)微小的\心理上的爽感對于 ChatGPT 來說是沒有任何好處的,反而是有害的。那么在今天這個(gè)時(shí)代,我們?yōu)槭裁催€要使用那些繁重的庫?我們是不是應(yīng)該直接回歸本源?就用最基礎(chǔ)、最簡單封裝的庫。這些都有一個(gè)特點(diǎn)。接口穩(wěn)定。從誕生之初到現(xiàn)在沒有太大變化。這個(gè)對于ChatGPT才是最友好的。
推而廣之
讓我們暢想一下,比如Java企業(yè)開發(fā)領(lǐng)域,是不是像是spring data這種東西。它的價(jià)值可能就不如SQL了,spring data這個(gè)東西一年不看都能有一大堆的變化,而sql這么多年了都沒什么變化。這才是最好的。除非我們能找到。SQL不能滿足的場景。在那里封裝一個(gè)簡單的框架。比如說就是MyBatis。
所以在基于 ChatGPT 進(jìn)行編程為前提,我們進(jìn)行技術(shù)棧選型時(shí),依賴庫接口的穩(wěn)定性就變得格外重要了。不客氣的說,在今天這個(gè)時(shí)代,接口的穩(wěn)定性壓倒一切。這就像在蒸汽機(jī)時(shí)代,鐵軌的間距是不能隨心隨意的。只有穩(wěn)定的鐵軌間距。才會(huì)有高效的運(yùn)輸效率。同理,只有穩(wěn)定的接口才能最大限度的發(fā)揮 ChatGPT 的能力,得到極高的開發(fā)效率。那些僅僅是因?yàn)閹椭松賹憥仔写a而開發(fā)的。變化在今天這個(gè)時(shí)代,能不引入還是不要引入。畢竟你在上面包一層的成本已經(jīng)開始無限趨近于0了。你為什么還要讓下面的接口遷就你呢?下層接口只要穩(wěn)定的干好自己該干的事情,并且提供穩(wěn)定的接口就夠了。
這個(gè)變化對于今天非常多的企業(yè)中臺(tái)都是一個(gè)重大利好。我們知道很多企業(yè)中臺(tái)這么多年都疲于奔命。淪為給前臺(tái)的“大客戶”打工。通常對于企業(yè)來說,前臺(tái)分為幾種?
一種是類似企業(yè)的“大客戶”,就是企業(yè)里最賺錢的前臺(tái)部門,那么我們就要配很大的人力去服務(wù)好他,“大客戶”自己呢,通常就任性一點(diǎn),所以會(huì)把他們的需求直接扔給我。那我們不得不改以適配“大客戶”。
還有一些是小客戶,但是因?yàn)槎荚谄髽I(yè)里,你不能像在市場里一樣說,小客戶我就不管了,我們是專做高端服務(wù)的。小客戶你也要管,成年人全都要嘛。這中間的矛盾呢,就使得很多設(shè)計(jì)上本來已經(jīng)說的很清楚的原則,根本落了地。
其實(shí)想想挺可笑的,過去那么多年,我們都說,下層要穩(wěn)定下層要穩(wěn)定,結(jié)果下層總也穩(wěn)定不了。為什么呢?不就是上層的新需求來了,非要讓我們下層的搞嘛。該我們搞的,我們搞,你們用著不方便也讓我們搞這是不是有點(diǎn)過分了,方便這個(gè)東西哪是有止境的呀?最方便的就是你們什么都不做,都讓我們做了,才最方便不是嗎?這么搞它接口能穩(wěn)定嗎?
但是話又說回來了,以前沒有辦法呀。中臺(tái)有很強(qiáng)的開發(fā)力量,前臺(tái)有嗎?通常前臺(tái)是沒有的。而前臺(tái)一句你不好用,中臺(tái)就政治不正確了,所以不得已我們就要配很多的開發(fā)力量來解決這些非技術(shù)的所謂技術(shù)問題。畢竟大家都要為效率低頭嘛,前中后臺(tái)端到端全局效率最高才是我們追求的方向。你不能說我中臺(tái)設(shè)計(jì)的好了,我效率高了,你整體效率上不去。你這個(gè)單點(diǎn)效率高又有什么用?
所以這就是個(gè)死局。以前大家都裝作努力在解,其實(shí)本質(zhì)上都是非常原始的解法,解得所有人都痛苦。但是在今天我們迎來了新的生產(chǎn)工具。讓我們看到了這個(gè)矛盾可以被消解的可能,因?yàn)榉€(wěn)定。不僅僅可以讓中臺(tái)的開發(fā)效率提升,也可以讓前臺(tái)開發(fā)效率提升。一個(gè)變動(dòng)的接口,對前臺(tái)也是不友好的,畢竟隨著 ChatGPT 這類大語言模型的推廣,前臺(tái)的開發(fā)能力被史詩級(jí)加強(qiáng),我們可以看到,微軟在Power Platform上已經(jīng)推出Copilot功能來實(shí)踐這種模式了。
總結(jié)一下
開篇我們引入了一個(gè)以瀑布流形式展示圖片需求,一開始,我們采用習(xí)慣的思路,嘗試使用一個(gè)庫來解決這個(gè)問題。但馬上就遇到了問題,這并不是ChatGPT擅長的事情,然而當(dāng)我問 ChatGPT 有沒有其他方法的時(shí)候,我得到了原生寫法的解決方案。
這讓我們意識(shí)到在基于 ChatGPT 編程的背景下,重新審視庫。過往的很多庫都是會(huì)為了人們好用而不停地提供一些新的接口,這些接口讓人們用著很舒服,但是其實(shí)帶來了學(xué)習(xí)成本,以及學(xué)習(xí)資料的過時(shí)。很多人都不喜歡學(xué)習(xí)新技術(shù),就是覺得亂,看起來也不是沒有道理。
所以那些古老的但是依然在用的庫是更能發(fā)揮出 ChatGPT 的效力的。依然在使用表示沒有過時(shí),依然有價(jià)值,古老表示接口穩(wěn)定,資料最全。所以我們是不是要反思一下,發(fā)明那么多庫有沒有可能一定程度上走錯(cuò)了路。這讓我想起三體里面,人類建了那么多的星際艦隊(duì),三體就搞了一個(gè)水滴,只用撞擊這一個(gè)動(dòng)作就把那些花里花哨的攻擊方式給比下去了。這層頓悟?qū)е挛抑笠欢螘r(shí)間在技術(shù)群里看到有人問什么功能有沒有現(xiàn)成的庫的時(shí)候,不自覺的會(huì)在腦子里蹦出一個(gè)吐槽:“哼,原始人”。這心態(tài)很不好,但是確實(shí)很貼切,興許隨著此類大語言模型AI的發(fā)展,我們以前的很多花里胡哨的做法真的看起來就很像傳統(tǒng)武術(shù)里的很多招數(shù),在熱武器面前不再具有普遍的價(jià)值。
那么推而廣之,穩(wěn)定的接口對于發(fā)揮ChatGPT的能力以提高開發(fā)效率至關(guān)重要。在技術(shù)棧選型時(shí),穩(wěn)定性應(yīng)該成為優(yōu)先考慮的因素。甚至于對于中臺(tái)建設(shè)都有很大利好,在企業(yè)中臺(tái)的建設(shè)中,前臺(tái)和中臺(tái)之間的矛盾導(dǎo)致中臺(tái)的接口和功能都無法穩(wěn)定。然而,隨著ChatGPT這類大語言模型的普及,前臺(tái)的開發(fā)能力得到了極大的提升,讓中臺(tái)穩(wěn)定成為可能,微軟的Power Platform已經(jīng)在摸索類似的模式了。
這一篇我們講了一個(gè)思路上轉(zhuǎn)變,使用 ChatGPT 的過程中,經(jīng)常會(huì)遇到這種思路轉(zhuǎn)變的情況,每次轉(zhuǎn)變都會(huì)覺得上一刻的自己是多么的愚蠢。所以建議大家盡快用起來,認(rèn)知的轉(zhuǎn)變可能會(huì)帶來完全不同的風(fēng)景。下一篇我們講講另一個(gè)引起我思路轉(zhuǎn)變的手法,這也是很多人用ChatGPT處理長內(nèi)容時(shí)的一個(gè)思維盲區(qū)。
以上就是有了ChatGPT編程我們還需要那么多庫嗎的詳細(xì)內(nèi)容,更多關(guān)于ChatGPT編程的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
NPM 安裝cordova時(shí)警告:npm WARN deprecated minimatch@2.0.10: Pleas
這篇文章主要介紹了NPM 安裝cordova時(shí)警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to的相關(guān)資料,需要的朋友可以參考下2016-12-12node學(xué)習(xí)記錄之搭建web服務(wù)器教程
本篇文章主要介紹了詳解node學(xué)習(xí)記錄——搭建web服務(wù)器,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02搭建基于express框架運(yùn)行環(huán)境的方法步驟
Express提供了一個(gè)輕量級(jí)模塊,把Node.js的http模塊功能封裝在一個(gè)簡單易用的接口中,這篇文章主要介紹了搭建基于express框架運(yùn)行環(huán)境的方法步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11Node.js基礎(chǔ)入門之緩存區(qū)與文件操作詳解
Node.js是一個(gè)基于Chrome?V8引擎的JavaScript運(yùn)行時(shí)。類似于Java中的JRE,.Net中的CLR。本文將詳細(xì)為大家介紹Node.js中的緩存區(qū)與文件操作,感興趣的可以了解一下2022-03-03詳解如何優(yōu)雅在webpack項(xiàng)目實(shí)現(xiàn)mock服務(wù)器
這篇文章主要為大家介紹了詳解如何優(yōu)雅在webpack項(xiàng)目實(shí)現(xiàn)mock服務(wù)器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Windows環(huán)境下npm install 報(bào)錯(cuò): operation not permitted, rename的解決
這篇文章主要介紹了Windows環(huán)境下npm install 報(bào)錯(cuò): operation not permitted, rename的解決方法,文中對解決的方法介紹的很詳細(xì),有需要的朋友們可以參考借鑒。2016-09-09阿里大于短信驗(yàn)證碼node koa2的實(shí)現(xiàn)代碼(最新)
本文給大家分享一個(gè)最新版阿里大于短信驗(yàn)證碼node koa2的實(shí)現(xiàn)代碼及注意事項(xiàng),需要的朋友參考下吧2017-09-09