首页
友链
Search
1
本网站搭建
24 阅读
2
原神!启动!0v0
22 阅读
3
25/26大模型面试经典题
13 阅读
4
常用代码模板4——数学知识
6 阅读
5
LLM
5 阅读
经验贴
从零开始系列
学生时代
工作
claude code
C++
登录
/
注册
Search
标签搜索
0-1
web
justu
Wxb
累计撰写
40
篇文章
累计收到
0
条评论
首页
栏目
经验贴
从零开始系列
学生时代
工作
claude code
C++
页面
友链
搜索到
14
篇与
的结果
26实习面试经历
幂达量化笔试题做了一坨 没过就直接挂了字节电商后端开发c++手撕不理想 自我介绍很乱 沟通很差阿里电商ai agent面试面试官评价:AI相关的能力比较薄弱,没有Agent建设的实践和经验,后训练也不够深入,不太符合我们这个岗位的要求。但是技术能力很扎实,做的网站也能看出来能力不错,可以考虑投其他岗位或者补全下AI基础能力
2026年04月02日
5 阅读
0 评论
0 点赞
code——虚拟环境
写代码第一步 环境刚开始接触各种语言的时候c++ c python的时候或者是直接复现一个简单的项目最头疼的莫过于配置环境 很多代码都是因为环境冲突 环境互相依赖冲突导致跑不起来这时候就会了解到虚拟环境会有各种各样的教程告诉你如何配置虚拟环境巴拉巴拉的但我还是经历了很长时间才真正的理解我刚接触的时候觉得真的好麻烦啊 ::(泪) 为什么不能直接在我的电脑上都能跑通 我还要一遍一遍的配置各种各样的虚拟环境{dotted startColor="#ff6c6c" endColor="#1989fa"/}现在我的理解就是不同的项目依赖的东西就是不同的圈子项目A可能是植物类的 项目B可能是动物类他们直接会有交集 但有些东西又是不一样的 比如植物可以光合作用 动物可以随意运动等等我们不可能做到一个环境统筹所有内容 所以方便起见有了虚拟环境根据管理内容的不同 就有了主要的三种环境虚拟环境 (venv)Conda 环境Docker工具一句话定位隔离对象venvPython 项目的轻量级虚拟环境仅 Python 解释器 + 第三方包conda跨语言的包管理与环境工具Python 解释器 + 第三方包 + 非 Python 依赖(如 CUDA、OpenSSL)Docker操作系统级容器整个文件系统、网络、进程、用户空间{dotted startColor="#ff6c6c" endColor="#1989fa"/}对比维度venvcondaDocker所属生态Python 内置(3.3+)Anaconda / MinicondaDocker Inc.(容器生态)隔离级别进程级(环境变量)进程级(环境变量)操作系统级(namespace + cgroups)隔离对象Python 解释器 + 第三方包Python + 第三方包 + 非 Python 依赖(如 CUDA)整个文件系统、网络、进程、用户空间能否管理 Python 版本❌ 不能(用宿主机 Python)✅ 能(python=3.10)✅ 能(通过不同基础镜像)能否管理非 Python 依赖❌ 不能✅ 能(conda 包可含二进制)✅ 能(任意系统库,如 libssl、ffmpeg)跨平台一致性⚠️ 弱(依赖宿主机 OS)⚠️ 中等(与 OS 绑定,但 conda 预编译)✅ 强(镜像包含完整 OS,行为一致)启动速度极快(毫秒级)快(毫秒级)中等(秒级,需启动容器进程)磁盘占用极小(几 MB,仅存包列表)中等(每环境几百 MB)较大(镜像几百 MB 到几 GB)打包与分发requirements.txtenvironment.ymlDockerfile → 镜像仓库适用场景简单 Python 项目,仅需隔离包版本数据科学、机器学习(需复杂二进制依赖)微服务部署、统一开发/生产环境、系统级隔离生产环境推荐度低中(镜像较大)高(标准部署方式)典型命令python -m venv envconda create -n env python=3.10docker build -t myapp .激活方式source env/bin/activateconda activate envdocker run -it myapp那么就很好理解了 这个venv就是可以把不同python包改善一下版本 conda就是可以把python版本都改了 docker就是可以把你操作系统给改了docker快速安装{dotted startColor="#ff6c6c" endColor="#1989fa"/}通过 Ubuntu 官方仓库安装 (docker.io)这是最简单的方法,但软件版本可能不是最新的。# 1. 更新软件包列表 sudo apt update # 2. 直接通过 apt 安装 docker.io 包 sudo apt install docker.io🧑💻 安装后配置(重要)避免重复输入sudo:默认情况下,运行 Docker 命令需要 sudo 权限。将你的用户添加到 docker 用户组后,重新登录,之后就可以直接使用 docker 命令了。sudo usermod -aG docker $USER⚠️ 安全提示:docker 组的权限等同于 root 用户,请谨慎添加。验证安装是否成功:运行一个简单的测试镜像来验证。docker run hello-world如果安装成功,你会看到一条欢迎消息,说明 Docker 引擎正在运行。{dotted startColor="#ff6c6c" endColor="#1989fa"/}Windows 系统 Docker 安装在Windows上,Docker Desktop是官方推荐的安装方式。建议优先选择使用WSL 2作为后端,其性能更好、资源占用更低。第一步:启用WSL 2功能以管理员身份打开 PowerShell,执行以下命令即可自动安装WSL 2并设置为默认版本:wsl --install如果你的系统不支持此命令,可以手动在“控制面板” -> “程序” -> “启用或关闭 Windows 功能”中,勾选“适用于Linux的Windows子系统”和“虚拟机平台”,然后重启电脑。第二步:下载并安装Docker Desktop下载:访问 Docker 官网下载页面,下载适用于 Windows 的安装包。安装:运行下载的 Docker Desktop Installer.exe,建议在安装过程中勾选 "Use WSL 2 instead of Hyper-V"(使用 WSL 2 代替 Hyper-V)选项。第三步:启动与验证安装完成后,从开始菜单启动 Docker Desktop。Docker 图标会在系统托盘中显示,等待其状态变为 "Docker Desktop is running"。打开 PowerShell 或 命令提示符,输入以下命令验证:docker --version如果输出版本号信息,就说明安装成功了。
2026年04月02日
2 阅读
0 评论
0 点赞
Node.js—Express使用
前言 前端也是可以编写接口的噢,我们一步一步学下去吧。Express 安装首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录。代码语言:javascriptAI代码解释$ mkdir myapp$ cd myapp通过 npm init 命令为你的应用创建一个 package.json 文件。代码语言:javascriptAI代码解释$ npm init此命令将要求你输入几个参数,例如此应用的名称和版本。 你可以直接按“回车”键接受大部分默认设置即可,下面这个除外:entry point: (index.js)键入 app.js 或者你所希望的名称,这是当前应用的入口文件。如果你希望采用默认的 index.js 文件名,只需按“回车”键即可。接下来在 myapp 目录下安装 Express 并将其保存到依赖列表中。如下:代码语言:javascriptAI代码解释$ npm install express --save如果只是临时安装 Express,不想将它添加到依赖列表中,可执行如下命令:代码语言:javascriptAI代码解释$ npm install express --no-save安装nodemon工具为什么要使用nodemon在编写调试 Node.js项目的时候,如果修改了项目的代码,则需要频繁的手动close掉,然后再重新启动,非常繁琐.。现在,我们可以使用nodemon (https/www.npmjs.com/package/nodemon)这个工具,它能够监听项目文件的变动,当代码被修改后,nodemon 会自动帮我们重启项目。极大方便了开发和调试。安装代码语言:javascriptAI代码解释npm i -g nodemon使用nodemon第一个案例体验代码语言:javascriptAI代码解释const express = require('express') // => 引入 express 模块const app = express() // => 实例化模块const port = 8080 // => 定义端口变量app.get('/', (req, res) => { res.send('Hello World!')})app.listen(port, () => { console.log(Example app listening on port ${port})})如上就是一个使用 express 创建的最基本的web服务器第五行中 '/',指的是根目录,可以理解为什么都没带,就比如我是8080端口打开,那么此时的地址栏为 http://localhost:8080/。req指的是请求,res指的是响应。现在站在服务端的视角来看:req是前端传过来的,res是响应返回给前端的。第九行中调用app.listen方法,启动服务器,是监听了port这个端口号,监听成功后执行回调。Express基本使用之监听请求监听get请求通过 app.get() 方法,可以监听客户端的GET请求,具体语法格式如下:监听post请求将内容响应给客户端通过res.send()方法,可以把处理好的内容,发送给客户端:基础代码示例代码语言:javascriptAI代码解释/*res.send()send 方法内部会检测响应内容的类型send 方法会自动设置 http 状态码send 方法还会帮我们自动设置响应的内容类型以及编码*/// => 引入 express 框架const express = require('express')// => 创建网站服务器const app = express();app.get('/', (req, res) => {res.send('Hello Express');})app.get('/list', (req, res)=> {// => 调用express提供的res.send()方法,向客户端响应一个JSON对象 res.send({name: 'zhangsan', age: 20});})app.post('/list',(req,res) => {// => 调用express提供的res.send()方法,向客户端响应一个文本字符串})// => 监听端口app.listen(3000);console.log('网站服务器启动成功');Express之获取URL中的参数获取 URL 中携带的查询参数代码语言:javascriptAI代码解释// => 引入 express 框架const express = require('express')// => 创建网站服务器const app = express();app.get('/', (req, res) => {// => 通过 req.query 可以获取到客户端发送过来的查询参数 // => 注意:默认情况下,req.query是一个空对象 console.log(req.query) res.send(req.query)})// 监听端口app.listen(3000);console.log('网站服务器启动成功');如上,我们服务器站点已经打开为 http://localhost:3000,处理的是地址为’/'的get请求现在我们使用postman工具模拟客户端来发起get请求,并带query参数我们可以看到在模拟客户端的工具内确实是响应了JSON对象(res.send(req.query))同时我们也可以看到服务端的打印情况获取 URL 中的动态参数代码语言:javascriptAI代码解释// => 引入 express 框架const express = require('express')// => 创建网站服务器const app = express();// => :id 是一个动态的参数app.get('/user/:id',(req,res) => {// => res.params 是动态匹配到的 URL 参数,默认也是一个空对象 console.log(req.params) res.send(req.params)})// 监听端口app.listen(3000);console.log('网站服务器启动成功');同样我们来看客户端和服务端的响应情况客户端服务端当然,,也是可以有多个动态参数的,如:/user/:name/:ageExpress之托管静态资源express提供了一个非常好用的函数,叫做express.static(),通过它,我们可以非常方便地创建一个静态资源服务器,例如,通过如下代码就可以将public目录下的图片、CSS文件、JavaScript 文件对外开放访问了:代码语言:javascriptAI代码解释app.use(express.static('public'))现在,你就可以访问public目录中的所有文件了:http://localhost:3000/images/bg.jpghttp://localhost:3000/css/style.csshttp://localhost:3000/js/login.js注意:Express在指定的静态目录中查找文件,并对外提供资源的访问路径。因此,存放静态文件的目录名不会出现在URL中,就比如寻找静态资源时,就没有带上public文件目录名。代码示例代码语言:javascriptAI代码解释const express = require('express')const app = express()// => 在这里,调用 express.static() 方法,快速地对外提供静态资源app.use(express.static('./public'))app.listen(8080,() => {console.log('express server runing at http://locallhost:8080')})托管多个静态资源目录访问静态资源文件时,express.static()函数会根据目录的添加顺序查找所需的文件。如上,在访问静态资源时,比如要找的时index.html,此时,public和files中都有index.html文件夹,这样在public中找到后,便不会继续往下找了。挂载路径前缀如果希望在托管的静态资源访问路径之前,挂载路径前缀,则可以使用如下的方式:代码语言:javascriptAI代码解释app.use("/public", express.static("public"))现在,就可以通过带有/public前缀地址来访问public目录中的文件了:http://localhost3000/public/images/kitten.jpghttp://localhost:300d7public/css/style.csshttp://localhost:3000/publicljs/app.jsExpress之路由现实生活的路由在这里,路由是按健与服务之问的映射关系Express中的路由在 Express 中,路由指的是客户端的请求与服务器处理函数之间的映射关系。Express中的路由分三部分组成,分别是请求的类型,请求的URL地址,处理函数,格式如下:代码语言:javascriptAI代码解释app.METHOD(PATH,HANDLER)Express中的路由例子代码语言:javascriptAI代码解释const express = require('express')const app = express()// => 匹配 GET 请求,且请求 URL 为 /app.get('/',function(req,res) {res.send('Hello')})// => 匹配 POST 请求,且请求 URL 为 /app.post('/',function(req,res) {res.send('Got a POST request')})理解路由的匹配过程每当一个请求到达服务器之后,需要先经过路由的匹配,只有匹配成功之后,才会调用对应的处理函数。在匹配时,会按照路由的顺序进行匹配,如果请求类型和请求的URL同时匹配成功,则 Express 会将这次请求,转交给对应的function函数进行处理。路由的使用最简单的路由用法在Express中使用路由最简单的方式,就是把路由挂载到app上,如下代码语言:javascriptAI代码解释const express = require('express ')// => 创建web服务器,命名为appconst app = express()// => 挂载路由app.get('/',(req,res) => { res.send('hell World') })// => 启动 Web 服务器app.listen(8080,()=>{console.log('启动')})路由的模块化为了方便对路由进行模块化的管理,Express 不建议将路由直接挂载到app上,而是推荐将路由抽离为单独的模块。将路由抽离为单独模块的步骤如下:① 创建路由模块对应的 .js 文件② 调用 express.Router() 函数创建路由对象③ 向路由对象上挂载具体的路由④ 使用 Module.exports 向外共享路由对象⑤ 使用 app.use() 函数注册路由模块① —> ④,如下代码语言:javascriptAI代码解释/*这是路由模块*/// => 1. 导入expressconst express = require('express')// => 2. 创建路由对象const router = express.Router()// => 3. 挂载具体路由router.get('/user/list',(req,res) => {res.send('Get user List.')})router.post('/user/add',(req,res) => {res.send('Add new user.')})// => 4. 向外导出路由对象module.exports = router⑤,如下代码语言:javascriptAI代码解释const express = require('express')const app = express()// => 导入路由模块const router = require('./08-router')// => 注册路由模块app.use(router)app.listen(8080,() => {console.log('http:127.0.0.1')})为路由模块添加前缀类似于托管静态资源时,为静态资源统一挂载访问前缀一样,路由模块添加前缀的方式也非常简单:Express之中间件生活当中的例子在处理污水的时候,一般要经过三个处理环节,从而保证处理过的废水,达到排放标准。处理污水的这三个中间处理环节,就可以叫做中间件。Expres中间件的调用流程当一个请求到达 Express 的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。Express 中间件的格式注意:中间件函数的形参列表中,必须包含 next 参数,而路由处理函数中只包含 req 和 res。因此区分是中间件处理函数还是路由处理函数的区别就是看参数列表是否包含next参数。next 函数的作用next函数是实现多个中间件连续调用的关键。它表示把流转关系转交给下一个中间件或路由。定义中间件函数可以通过如下的方式,定义一个最简单的中间件函数:代码语言:javascriptAI代码解释const express = require('express')const app = express()// => 定义一个最简单的中间件函数const mw = function(req,res,next) {console.log('这是最简单的中间件函数') // => 把流转关系,转交给下一个中间件或路由 next()}app.listen(8080,() => {console.log('Web服务启动');})全局生效的中间件客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。通过调用app.use(中间件函数),即可定义一个全局生效的中间件,示例代码如下:代码语言:javascriptAI代码解释const express = require('express')const app = express()// => 定义一个最简单的中间件函数const mw = function(req,res,next) {console.log('这是最简单的中间件函数') // => 把流转关系,转交给下一个中间件或路由 next()}// => 全局生效的中间件app.use(mw)app.get('/',(req,res) => {console.log('这次流转到我 / 这里了') res.send('Home page')})app.get('/user',(req,res) => {res.send('User page.')})app.listen(8080,() => {console.log('Web服务启动');})接着我们使用 postman 给我们这个开启的 Web 服务器发起请求客户端:服务器:定义中间件的简化形式中间件在实际开发中的作用多个中间件之间,共享同一份req和res。基于这样的特性,我们可以在上游的中间件中,统一为req或res对象添加自定义的属性或方法,供下游的中间件或路由进行使用。代码示例代码语言:javascriptAI代码解释/*捕获请求到达到达服务器的时间*/const express = require('express')const app = express()app.use((req,res,next) => {// => 获取请求到达服务器的时间 const time = Date.now() // => 为 req 对象,挂载自定义属性,从而把时间共享给后面的所有路由 req.startTime = time next()})app.get('/',(req,res) => {console.log('这次流转到我 / 这里了' + ' 请求时间是' + req.startTime) res.send('Home page')})app.get('/user',(req,res) => {console.log('这次流转到我 /user 这里了' + ' 请求时间是' + req.startTime) res.send('User page.')})app.listen(8080,() => {console.log('Web服务启动');})定义多个全局中间件可以使用app.use()连续定义多个全局中间件。客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行调用,示例代码如下:代码语言:javascriptAI代码解释const express = require('express')const app = express()// => 定义一个全局中间件app.use((req,res,next) => {console.log('调用了第1个全局中间件') next()})// => 定义第二个全局中间件app.use((req,res,next) => {console.log('调用了第二个全局中间件') next()})// => 定义一个路由app.get('/user',(req,res) => {res.send('User page')})app.listen(8080,() => {console.log('启动')})局部生效的中间件不使用app.use0定义的中间件,叫做局部生效的中间件,示例代码如下:代码语言:javascriptAI代码解释const express = require('express')const app = express()// 1. 定义中间件函数const mw1 = (req,res,next) => {console.log('调用了局部生效的中间件') next()}// 2. 创建路由// mw1 就是局部的中间件了app.get('/',mw1,(req,res) => {res.send('Home page')})app.get('/user',(req,res) => {res.send('User page')})// => 指定端口号,并启动web服务器app.listen(8080,function(){console.log('启动');})定义多个局部中间件代码语言:javascriptAI代码解释const express = require('express')const app = express()// 1. 定义中间件函数const mw1 = (req,res,next) => {console.log('调用了第一个局部生效的中间件') next()}const mw2 = (req,res,next) => {console.log('调用了第二个局部生效的中间件') next()}// 2. 创建路由app.get('/',mw1,mw2,(req,res) => {res.send('Home page')})app.get('/user',(req,res) => {res.send('User page')})// => 指定端口号,并启动web服务器app.listen(8080,function(){console.log('启动');})中间件的注意事项一定要在路由之前注册中间件客户端发送过来的请求,可以连续调用多个中间件进行处理执行完中间件的业务代码之后,不要忘记调用next()函数为了防止代码逻辑混乱,调用next()函数后不要再写额外的代码连续调用多个中间件时,多个中间件之间,共享req和res 对象监听 req 的 data 事件在中间件中,需要监听req对象的data事件,来获取客户端发送到服务器的数据。如果数据量比较大,无法一次性发送完毕,则客户端会把数据切割后,分批发送到服务器。所以data事件可能会触发多次,每一次触发data事件时,获取到数据只是完整数据的一部分,需要手动对接收到的数据进行拼接。代码语言:javascriptAI代码解释// 定义变量,用来储存客户端发送过来的请求体数据let str = ''// 监听 req 对象的 data 事件(客户端发送过来的新的请求体数据)req.on('data',(chunk) => { // 拼接请求体数据,隐式转换为字符串 str += chunk})监听 req 的 end 事件当请求体数据接收完毕之后,会自动触发req的end 事件。因此,我们可以在req的end 事件中,拿到并处理完整的请求体数据。示例代码如下:代码语言:javascriptAI代码解释// 监听 req 对象的 end 事件(请求体发送完毕后自动触发)req.on('end',() => { // => 打印完整的请求体数据 console.log(str) // TODO: 业务逻辑 // .......})Express中间件的分类为了方便理解和记忆中间件的使用,Express 官方把常见的中间件用法,分成了5大类,分别是:应用级别的中间件通过app.use()或app.get()或 app.post(),绑定到app实例上的中间件,叫做应用级别的中间件,代码示例如下:路由级别的中间件绑定到express.Router()实例上的中间件,叫做路由级别的中间件。它的用法和应用级别中间件没有任何区别。只不过,应用级别中间件是绑定到 app实例上,路由级别中绚件摸定到router 实例上,代码示例如下:错误极别的中间件错误级别中间件的作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。格式:错误级别的中间件的 function 处理函数中,必须有 4 个形参,形参顺序从前到后,分别是(err,req,res,next)。代码示例注意:错误级别的中间件必须注册在所有路由之后。代码语言:javascriptAI代码解释// 引入 express 框架const express = require('express')// 创建网站服务器const app = express();// 1. 定义路由app.get('/',(req,res) => { // 1.1 人为的制造错误 throw new Error('服务器内部发生错误')})// 2. 定义错误级别的中间件,捕获整个项目的异常错误,从而防止程序的崩溃app.use((err,req,res,next) => {console.log('发生了错误!' + err.message) res.send('Error:' + err.message)}) // 监听端口app.listen(8080,function() {console.log('Express server is running')})Express内置的中间件自Express 4.16.0版本开始,Express 内置了3个常用的中间件,极大的提高了Express 项目的开发效率和体验:express.static快速托管静态资源的内置中间件,例如:HTML文件、图片、CSS样式等(无兼容性)express.json解析JSON格式的请求体数据(有兼容性,仅在4.16.0+版本中可用)代码语言:javascriptAI代码解释// => 配置解析 application / json 格式数据的内置中间件app.use(express.json())express.urlencoded解析URL-encoded格式的请求体数据(有兼容性,仅在4.16.0+版本中可用)代码语言:javascriptAI代码解释// => 配置解析 application / x-www-from-urlencoded 格式数据的内置中间件app.use(express.urlencoded({ extended: false }))代码示例代码语言:javascriptAI代码解释// 引入 express 框架const express = require('express')// 创建网站服务器const app = express();// 注意:除了错误级别的中间件,其他中间件,必须在路由之前进行配置// 通过 express.json 这个内置中间件,解析表单中 json 格式的数据app.use(express.json())// 通过 express.ulencoded() 这个中间件,解析表单中 url-encoded 格式的数据app.use(express.urlencoded({ extended: false }))app.post('/user',(req,res) => {// 在服务器,可以使用req.body这个属性,来接受客户端发送过来的请求体数据 // 默认情况下,如果不配置解析表单数据的中间件,则 req.body 默认等于 undefined console.log(req.body) res.send('ok')})app.post('/book',(req,res) => {console.log(req.body) res.send('ok')})app.listen(3000,function() {console.log('网站服务器启动成功');})第三方的中间件非Express官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,大家可以按需下载并配置第三方中间件,从而提高项目的开发效率。例如:在express@4.16.0之前的版本中,经常使用body-parser这个第三方中间件,来解析请求体数据。使用步骤如下:运行npm install body-parser安装中间件使用require导入中间件调用app.use()注册并使用中间件自定义中间件需求描述与实现步骤自己手动模拟一个类似于express.urlencoded这样的中间件,来解析POST提交到服务器的表单数据。实现步骤定义中间件监听req的data事件监听req的end 事件使用querystring模块解析请求体数据将解析出来的数据对象挂载为req.body将自定义中间件封装为模块代码示例代码语言:javascriptAI代码解释// => 引入 express 框架const express = require('express')// => 创建网站服务器const app = express()// 1. 导入自己封装的中间件模块const custonBodyParser = require('./21-封装')// 2. 将自定义的中间件函数注册为全局可用的中间件app.use(custonBodyParser)app.post('/user',(req,res) => {res.send('ok') res.send(req.body)})// => 监听端口app.listen(3000,function() {console.log('网站服务器启动成功')})封装的模块代码语言:javascriptAI代码解释// => 导入 Node.js内置的 querystring 模板const bodyParser = require('body-parser')const qs = require('querystring')app.use((req,res,next) => {// => 定义中间件具体的业务逻辑 let str = '' req.on('data',(chunk) => { str += chunk }) req.on('end',() => { console.log(str) // => 在 str 中存放的是完整的请求体数据 // => 业务:把字符串格式的请求体数据,解析成对象格式 const body = qs.parse(str) console.log(body) req.body = body next() })})modules.exports = bodyParser使用Express编写接口编写 GET 接口核心代码代码语言:javascriptAI代码解释apiRouter.get('/get',(req,res) => {// 1. 获取到客户端通过查询字符串,发送到服务器的数据 const query = req.query // 2. 调用 res.send() 方法,把数据响应给客户端 res.send({ status: 0, // 状态,0 表示成功 msg: 'GET请求成功!', // 状态描述 data: query // 需要响应给客户端的具体数据 })})编写 POST 接口核心代码代码语言:javascriptAI代码解释apiRouter.post('/post',(req,res) => {// 1. 获取客户端通过请求体,发送到服务器的 URL-encoded 数据 const body = req.body // 2. 调用 res.send() 方法,把数据响应给客户端 res.send({ status: 0, // 状态,0 表示成功,1 表示失败 msg: 'POST请求成功!', // 状态描述信息 data: body // 需要响应给客户端的具体数据 })})注意:如果要获取URL-encoded格式的请求体数据,必须配置中间件 app.use(express.urlencoded(extended:false))创建服务器及编写简单接口首先创建基本的服务器,提供接口的导入口代码语言:javascriptAI代码解释const express = require('express') // => 导入 expressconst app = express() // => 创建服务器实例app.use(express.urlencoded({extended:false})) // => 配置解析表单的数据中间件// => 本来路由写在这里的,现在模块化管理了,导入注册即可// => 导入并注册路由模块,这样客户端到达的请求就会到对应封装好的接口中去匹配对应的路由const router = require('./23-接口')app.use('/api',router)// => 启动服务器app.listen(3000,() => {console.log('Web服务器已经创建');})封装API接口并暴露链接代码语言:javascriptAI代码解释const express = require('express')const router = express.Router()// => 在这里挂载对应的路由// 如下, 编写一个 GET 接口router.get('/get',(req,res) => {// 通过req.query获取客户端通过查询字符串,发送到服务器的数据 const query = req.query // 调用res.send()方法,向客户端响应处理的结果 res.send({ status:0, // => 0表示处理成功,1表示处理失败 msg:'GET 请求成功', // => 状态的描述 data: query // => 需要响应给客户端的数据 })})// 如下,编写一个 POST 接口router.post('/post',(req,res) => {// 通过 req.body 获取请求体中包含的 url-encoded 格式的数据 const body = req.body // 调用 res.send 方法,向客户端响应数据 res.send({ status:0, msg:'POST请求成功', data: body })})module.exports = router使用Express框架链接sQlite3数据库一. 安装sqlite3,运行如下命令代码语言:javascriptAI代码解释yarn add sqlite3 --ignore-scripts二. 实现链接文件夹目录代码语言:javascriptAI代码解释▽ Message ▸ node_modules ▸ public ▸ hello.html▸ db ▸ db.sqlite3 ▸ dbutils.js▸ router ▸ MessageRouter.js▸ app.js ▸ package-lock.json ▸ package.json ▸ yarn.lock1、创建数据库创建数据库文件:注意 ③,数据文件配置的路径是要和我们项目调用数据文件保持一致新建一个表:添加字段:添加数据2、使用NODE开始链接数据库首先,我们希望的是,使用我们搭建的服务器来连接数据库,那么创建服务器app.js代码语言:javascriptAI代码解释const express = require("express")const path = require("path")const app = express()let port = 3000// => 为前端开放跨域请求app.use(function (req,res,next) {// => 设置允许跨域的域名,* 代表允许任意域名跨域 res.header("Access-Control-Allow-Origin","*"); // => 允许的header类型 res.header("Access-Control-Allow-Headers","content-type"); // => 跨域允许的请求方式 res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS"); if(req.method == "OPTIONS") res.sendStatus(200) // => 让options尝试请求快速结束 else next()})// => 导入路由app.use("/message",require("./router/MessageRouter.js"))// => 导入静态资源app.use(express.static(path.join(__dirname,"./public")))app.get("/",(req,res) => {res.send("hello")})app.listen(port,(req,res) => {console.log(`启动成功`)})然后我们配置相关路由router / MessageRouter.js代码语言:javascriptAI代码解释const express = require("express")const {db} = require("../db/dbutils")var router = express.Router()router.get("/test",(req,res) => {// => 查询数据库 db.all("select * from `message`",(err,rows) => { res.send(rows) })})module.exports = router为了使得数据库导出及复用性更高,我们将其单独封装成一个链接db / dbutils.js代码语言:javascriptAI代码解释const path = require("path") // => 导入 path 模块const sqlite3 = require("sqlite3").verbose() // => 导入依赖const db = new sqlite3.Database(path.join(__dirname,"./db.sqlite3")) // => 实例化// => 暴露module.exports = {db}启动查看是否链接成功接口的跨域问题咱们刚才编写的 GET 和 POST 接口,存在一个很严重的问题,不支持跨域请求(跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制)。我们仍然使用刚才所打开的服务器,现在测试发起请求代码语言:javascriptAI代码解释<!DOCTYPE html><meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.staticfile.org/jquery/3.7.0/jquery.slim.js"></script><button id="btnGET">GET</button> <button id="btnPOST">POST</button> <script> // => 1. 测试GET接口 $('#btnGET').on('click',function() { $.ajax({ type: 'GET', url: 'http://localhost:3000/api/get', data: {name:'hv',age:20}, success: function(res) { console.log(res) } }) }) // => 2. 测试POST接口 $('#btnPOST').on('click',function() { $.ajax({ type: 'POST', url: 'http://localhost:3000/api/get', data: {bookname:'水浒传',author:'施耐庵'}, success: function(res) { console.log(res) } }) }) </script>如下,可以看见违反了同源策略( 同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域)。如下的协议名是 file以前我们使用 postman 发起请求的时候,是没有违反同源策略的,用的就是服务器的域名。使用 cors 中间件解决跨域问题(主流的解决方案,推荐使用)cors 是 Express的一个第三方中间件。通过安装和配置cors中间件,可以很方便地解决跨域问题。使用步骤分为如下3步:运行 npm install cors 安装中间件使用 const cors = require('cors') 导入中间件在路由之前 调用app.use(cors()) 配置中间件代码语言:javascriptAI代码解释const express = require('express') // => 导入 expressconst app = express() // => 创建服务器实例app.use(express.urlencoded({extended:false})) // => 配置解析表单的数据中间件// => 一定要在路由之前,配置 cors 这个中间件,从而解决接口跨域的问题const cors = require('cors')app.use(cors())// => 本来路由写在这里的,现在模块化管理了,导入注册即可// => 导入并注册路由模块,这样客户端到达的请求就会到对应封装好的接口中去匹配对应的路由const router = require('./23-接口')app.use('/api',router)// => 启动服务器app.listen(3000,() => {console.log('Web服务器已经创建');})注意:CORS主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了CORS的接口。CORS在浏览器中有兼容性。只有支持XMLHttpRequest Level2的浏览器,才能正常访问开启了CORS的服务端接口。结语 保持热爱,永远都在前进的路上❤️
2026年04月01日
2 阅读
0 评论
0 点赞
LLM
1.前置知识 微调的模型集中在以下模型:DeepSeek、GLM、Llama、Qwen,其中在初步微调中,DeepSeek和Qwen表现较好,于是选择加入DeepSeek和Qwen较大参数量的模型进行微调测试 2.在微调过程中,主要关注以下因素的调整对模型表现的影响,包括但不限于:训练集数据量、训练集不同类型数据的配比、训练集单条数据长度、cutoff_len(截断长度)、Qlora、lora_dropout(丢弃部分神经元防止过拟合)、learning_rate(学习率)、Epochs(训练轮次)、模型参数规模等3.训练可用GPU:A800,微调方法:lora,集成平台:llama-factory2.微调平台使用 部署llama-factory,详见:https://llamafactory.readthedocs.io/en/latest/getting_started/installation.html 部署完成之后熟悉各项微调参数: 3.以微调材料大模型的经验,以下微调参数比较重要:训练集数据量、训练集不同类型数据的配比、训练集单条数据长度、cutoff_len(截断长度)、Qlora(参数精度:16、8、4)、lora_dropout(丢弃部分神经元防止过拟合)、learning_rate(学习率)、Epochs(训练轮次)、模型参数规模注意:(1)部分微调参数调整需要补充环境,比如qlora(2)模型参数规模受限于gpu,要选择合适的模型和相应的参数规模(3)可以在微调前后使用llama-factory的评估来测试模型在测试集上各个指标的提升,所以在准备数据集的时候既需要准备训练集也需要测试集
2026年04月01日
5 阅读
0 评论
0 点赞
2026-03-31
实现tool.epoch42.cn
开源才是最难的xd
2026年03月31日
3 阅读
0 评论
0 点赞
本网站搭建
😁 太难啦 😁 最开始打算本地mysql+ghost/or各种博客框架+nginx 本地环境是多用户ubuntu服务器 端口环境异常恶劣hh nginx启动很困难 网络环境为内网环境 为了实现网站梦 遂开始从0构建 基本路线是本地frpc——阿里云ecs的frps+nginx上面 域名解析到ecs的公网ip上面 一切的原因都是因为太对了出此下策 (气笑了) ::(乖) 现在就是简单的使用pm2托管了typecho架构的网站 使用sqlite 使用了一些大佬的开源主题+插件这里给下他们的链接苏晓晴 Joe little-gt why not nginx? 😊 openresty LISTEN 80 因为环境下太多用户 改用openresty也很困难 配置文件如果在root下直接启动过于危险 so passwhy not mysql? 😆 有服务跑在了3306 而大部分默认配置都直接要跑3306 一旦要修改端口不知道要改多少内容 而本人是mysql菜鸡 所以选择了最简单的方式(已被mysql权限狠狠折磨了)why not ...? 😭 最开始把框架想的很大 最后发现自己不行 甚至尝试自己写前后端+数据库架构搭建 也能搭出来 但是你懂的 异常简陋 所以砍掉成现在这个样子了我深深感受到了什么叫做 如无必要勿增实体typecho:轻量级博客框架——>基于php下载:从 typecho 官网 下载压缩包。解压:放到你想要启动网站的目录下(可以新建一个文件夹比如 typecho_site)(文件夹名字随便你)。安装:访问域名,填入站点信息,30秒就能装好。cd /跳转到你放typecho的文件夹 # 启动 PHP 内置服务器 # -S 指定监听地址和端口 # -t 指定网站根目录php -S 0.0.0.0:8888 -t /你放typecho的根目录文件夹 (8888改成你喜欢的端口就行了)php不是后台托管命令 我习惯用pm2了 比较方便管理pm2 start "php -S 0.0.0.0:8888 -t /你放typecho的根目录文件夹" --name "typecho-blog" 上述命令其实就是让系统找到pm2这个服务/软件 start:启动 双引号里为具体命令 --name:自定义一下改进程名字查看状态:pm2 list(你会看到 typecho-blog 在列表中显示 online)。 如下│ id │ name │ mode │ ↺ │ status │ cpu │ memory │├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤│ 7 │ epoch42_blog │ fork │ 0 │ online │ 0% │ 76.0mb │你可以使用 pm2 restart epoch42_blog 或者 pm2 restart 7 (7是服务的id) 来重启typecho (如果你对typecho系统文件进行更改了的话)映射经过上述命令 你其实已经完成一大半了 typecho会显示在你本地服务器端口8888上面(你命令中的端口)如果你是直接在公网ecs上面使用 那么你只需要把端口绑到你的域名就好了当然 如何申请域名并拥有一个属于自己的域名(在国内)也是很麻烦主题/插件 typecho默认的主题和后台内容并不友好 我也在探索阶段 我在前面提到的开源大佬中 分别有后台和主题的代码 可以很快弄出一个像我这样的网站(你也试试吧xd 只需要把他们的压缩文件夹解压并且放到typecho的相应目录下即可 /usr/plugins (插件 /usr/themes (主题
2026年03月30日
24 阅读
0 评论
0 点赞
1
2