Node.js教程-express框架
概述
Express是基于Node.js平台(建立在Node.js内置的http模块上),快速、开放、极简的Web开发框架。
中文官网 http://www.expressjs.com.cn/。
Github地址:https://github.com/orgs/expressjs。
Express核心特性:
- 可设置中间件来响应 HTTP 请求
- 定义了路由表用于执行不同的 HTTP 请求
- 可通过向模板传递参数来动态渲染 HTML 页面
安装
npm i express
以上命令会将express安装在当前目录下的node_modules文件夹下,并且将其依赖的包也一并下载下来
以下几个和express搭配使用的包:
- body-parser 用于处理 JSON、Raw、Text和URL中的请求数据
- cookie-parser 用于处理Cookie
- multer 用于处理**enctyoe=“multipart/form-data””**的表单数据
基本使用
基本使用步骤:
- 导入 express 模块
- 创建 express 实例
- 创建并启动HTTP服务
- 绑定请求事件
// 1. 导入 express 包
const express = require('express')// 2. 创建 express 实例
const app = express()// 3. 启动服务
app.listen(80, () => {console.log("Express server is starting ...")
})// 4. 绑定请求事件
app.get("/", (req, res) => {console.log("请求进来了 >>> " + req.url)res.end("Hello Node.js")
})
set 方法
set方法用于指定变量的值
// 设置 端口
app.set("port", process.env.PORT)// 设定views变量,意为视图存放的目录
app.set('views', path.join(__dirname, 'views'));// 设定view engine变量,意为网页模板引擎
app.set('view engine', 'jade');
请求和响应
Express处理请求中回调函数的参数:request和response对象来处理请求和响应。
request 对象
request对象表示 HTTP请求,包含了请求查询的字符串,参数、内容、HTTP头部等属性。常见属性:
- request.app 当callback为外部文件时,用其访问express实例
- request.baseUrl 获取当前的 URL 路径
- request.method 获取请求方法
- request.body 获取请求体内容
- request.cookie 获取 Cookie 内容
- request.hostname 获取主机名
- request.ip 获取IP
- request.originalUrl 获取原始请求 URL
- request.params 获取请求参数(动态匹配的参数)
- request.path 获取请求路径
- request.protocol 获取请求协议
- request.query 获取URL的查询参数
- request.route 获取请求匹配的路由
- request.get() 获取指定的请求头
- request.is() 判断请求头Content-Type的MIME类型
// http://domain:port/x1/x2/wz?age=18
request.path // /x1/x2/wz
request.params // wz
request.query // age
// 引入express 模块
const express = require('express')// 创建 实例
const app = express()// 启动服务
app.listen(80, () => {console.log("Server is starting ...")
})// 绑定 get 请求事件
app.get('/user', (req, res) => {// req.protocol 获取请求协议console.log("protocol >>> ", req.protocol)// req.method 获取请求方法console.log("method >>> ", req.method)// req.hostname 获取主机名console.log("hostname >>> ", req.hostname)// req.ip 获取请求 IPconsole.log("ip >>> ", req.ip)// req.originalUrl 获取请求原始路径console.log("originalUrl >>> ", req.originalUrl)// req.path 获取请求路径console.log("path >>> ", req.path)// req.route 获取请求路由console.log("route >>> ", req.route)// req.params 获取请求参数console.log("params >>> ", req.params)// req.query 获取请求查询参数console.log("query >>> ", req.query)// req.body 获取请求体console.log("body >>> ", req.body)res.end("GET")
})// 绑定 post 请求事件
app.post('/user', (req, res) => {// req.protocol 获取请求协议console.log("protocol >>> ", req.protocol)// req.method 获取请求方法console.log("method >>> ", req.method)// req.hostname 获取主机名console.log("hostname >>> ", req.hostname)// req.ip 获取请求 IPconsole.log("ip >>> ", req.ip)// req.originalUrl 获取请求原始路径console.log("originalUrl >>> ", req.originalUrl)// req.path 获取请求路径console.log("path >>> ", req.path)// req.route 获取请求路由console.log("route >>> ", req.route)// req.params 获取请求参数console.log("params >>> ", req.params)// req.query 获取请求查询参数console.log("query >>> ", req.query)// req.body 获取请求体console.log("body >>> ", req.body)res.end("POST")
})
response 对象
response 对象表示 HTTP响应,即在接受到请求时向客户端发送的数据。常见属性:
- response.app 当callback为外部文件时,用其访问express实例
- response.cookie(name, value[, options]) 设置Cookie信息
- response.clearCookie() 清空Cookie
- response.download() 传送指定的文件
- response.get() 获取指定的HTTP头信息
- response.set(name, value) 设置响应头(Header)
- response.json() 响应JSON格式的数据
- response.render(view[, locals], callback) 渲染网页模版
- response.send() 发送响应
- response.sendFile(path[, options][, fn]) 传送文件
- response.status() 设置 HTTP 状态码
- response.type() 设置 Content-Type的 MIME类型
- response.redirect() 设置重定向
路由
路由即路径映射。在Express中,路由指客户端的请求与服务器处理函数的映射。
Express中路由是一个单独的组件Express.Router。
Express中路由由三部分组成,分别为请求类型、请求URL、处理函数。其格式如下:
app.method(path, handler())
路由匹配过程
- 请求到达服务器时,先经过路由的匹配,匹配成功了,才会调用对应的处理函数
- 在匹配时,按照定义的顺序依次匹配,仅当请求类型和请求URL同时匹配成功了,才会调用对应的处理函数

// 导入 express 模块
const express = require('express')// 创建 express 实例
const app = express()// 创建路由实例
const router = express.Router()// 挂载路由
router.get('/user', (req, res) => {res.send("express router")
})// 注册路由
app.use('/api', router)// 启动服务
app.listen(80, () => {console.log("Server is starting ...")
})// 访问路径 http://domain:port/api/user
中间件
中间件(Middleware)指业务流程的中间处理环节。其是一个函数,包含了request、respoonse、next三个参数,其中 next() 把流转交给下一个中间件或路由。
Express 中间件调用流程

注意:
- 在注册路由之前注册中间件(错误中间件除外)
- 多个中间件共享request和response对象
- next() 函数后不能再写逻辑代码
全局中间件
通过app.use()注册的中间件为全局中间件
const express = require('express')const app = express()// 注册全局中间件
app.use((req, res, next) => {console.log("中间件A")
})// 注册全局中间件
app.use((req, res, next) => {console.log("中间件B")
})app.get('/user', (req, res) => {res.send("ok")
})app.listen(8888)
局部中间件
const express = require('express')const app = express()// 定义中间件
const mw1 = (req, res, next) => {console.log("中间件A")
}// 注册全局中间件
const mw2 = (req, res, next) => {console.log("中间件B")
}app.get('/user', mw1, mw2, (req, res) => {res.send("ok")
})app.post('/user', [mw1, mw2], (req, res) => {res.send("ok")
})app.listen(8888)
中间件分类
中间件按照作用可划分为三类:应用级别中间件、路由级别中间件、错误级别中间件。
应用级别中间件
通过app.use()或app.method()注册,即绑定到app实例上的中间件即为应用级别中间件。(其中method为get、post、put、delete等请求方法)
const express = require('express')const app = express()// 注册路由
app.use('/', (req, res, next) => {next()
})
路由级别中间件
通过router.use()注册,即绑定到router实例上的中间件即为路由级别中间件。
const express = require('express')const app = express()
const router = express.Router()// 路由上注册中间件
router.use((req, res, next) => {next()
})// 注册路由
app.use('/', router)
错误级别中间件
错误级别中间件用来捕获整个项目中发生的异常,从而防止项目异常崩溃。
错误级别中间件的处理函数中必须有4个形参,即(error, request, response, next)
错误级别中间件必须注册在所有路由之后
const express = require('express')const app = express()// 请求处理 ...// 注册错误中间件
app.use((err, req, res, next) => {next()
})
内置中间件
Express中内置了多个中间件,极大的提高了 Express 项目的开发效率。常见内置中间件:
-
express.static 快速托管静态资源
express.static(root[, options])
-
express.json 解析JSON格式的请求体数据
-
express.urlencoded 解析 url-encoded 格式的请求体数据
// 快速托管静态资源
app.use(express.static(path))// 通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据
app.use(express.json())// 通过 express.urlencoded() 这个中间件,来解析表单中的 url-encoded 格式的数据
app.use(express.urlencoded({ extended: false }))
第三方中间件
cookie-parser
cookie-parser 用于处理请求中的Cookie。
https://github.com/expressjs/cookie-parser
设置Cookie
res.cookie(name, value[, options])
参数说明
- name cookie名称
- value cookie值
- options 配置参数
- domain 域名。默认为当前域名
- expires 失效时间。未设置或0,表示浏览器关闭后即失效
- maxAge 最大失效时间(指从当前时间开始多久后失效),单位毫秒
- secure 为 true时,cookie 在 http 失效,https 生效
- path cookie在什么路径下有效。默认为**/**
- httpOnly 只能被访问,防止 XSS攻击
- signed 是否签名。默认指为false
不签名实例
const express = require('express')
const cookieParser = require('cookie-parser')// 创建 app 实例
const app = express()// 注册 Cookie中间件
app.use(cookieParse())app.get('/setCookie', (req, res) => {res.cookie('name', '张三', {maxAge: 10000})res.send('cookie set success!')
})app.listen(8888)
签名实例
const express = require('express')
const cookieParser = require('cookie-parser')const app = express()app.use(cookieParser('^123$')) // ^123$ 为签名秘钥app.get('setCookie', (req, res) => {// 将cookie的name 进行签名res.cookie("name", "张三", {maxAge: 100000, signed: true})
})
获取Cookie
注意:Cookie签名与不签名获取的方式不一样。req.cookies获取不签名的cookie;req.signedCookies获取签名的cookie。
不签名实例
const express = require('express')
const cookieParser = require('cookie-parser')// 创建 app 实例
const app = express()// 注册 Cookie中间件
app.use(cookieParser()) //app.get('/getCookie', (req, res) => {console.log(req.cookies)res.send("cookie got")
})app.listen(8888)
签名实例
const express = require('express')
const cookieParser = require('cookie-parser')// 创建 app 实例
const app = express()// 注册 Cookie中间件
app.use(cookieParser('^123$')) // ^123$ 为签名秘钥app.get('/getCookie', (req, res) => {console.log(req.signedCookies)res.send("cookie got")
})app.listen(8888)
删除Cookie
res.clearCookie(name[, options])
express-session
express-session用于处理请求中的会话。
https://github.com/expressjs/session
配置 session
session(options)
参数说明:
- options 配置参数
- cookie cookie设置
- genid sessionid算法。默认为uid-safe库自动生成id
- name 会话名称。默认为 connect.sid
- secret 会话签名秘钥
- store 会话存储方式。默认为内存
- resave 是否强制保存会话,及时未被修改也被保存。默认为true
- saveUninitialized 强制将未初始化的会话保存至存储中。(会话是新的且未被修改即为未初始化)
- unset 是否保存会话。默认为keep,不保存可设置为destory
const express = require('express')
const session = require('express-session')const app = express()app.use(session({name: "session-cookie",secret: "^123456$", // 会话签名秘钥cookie: {maxAge: 2 * 60 * 60 * 1000}
}))
req.session
req.session可用于存储或访问会话数据,以JSON的形式序列化。
const express = require('express')
const session = require('express-session')// 创建服务实例
const app = express()// 配置session,并注册session中间件
app.use(session({name: "express",secret: "^123456$",resave: false,saveUninitialized: true
}))app.get('/setSession', (req, res) => {// 存储会话req.session.name = "李四"res.send("set session success")
})app.get('/getSession', (req, res) => {// 获取会话console.log(req.session)res.send("session got")
})// 启动服务
app.listen(8888)
属性
| 属性 | 说明 |
|---|---|
req.session.id | 会话ID |
req.session.sessionID | 会话ID |
req.session.cookie | 获取会话中的 cookie 对象, 而后可对其修改 |
req.session.cookie.maxAge | 会话有效剩余时长 |
req.session.cookie.originalMaxAge | 返回会话 cookie 的原始 maxAge, 以毫秒为单位 |
方法
| 方法 | 说明 |
|---|---|
req.session.regenerate(callback) | 重新生成会话 |
req.session.destroy(callback) | 销毁会话并取消设置 req.session 属性 |
req.session.reload(callback) | 从存储重新加载会话数据并重新填充 req.session 对象 |
req.session.save(callback) | 讲会话保存至 store,用内存中的内容替换 store上的内容 |
req.session.touch() | 更新 .maxAge属性 |
JWT
JWT(JSON Web Token)是由三部分组成:Header、Payload(真正的用户信息,加密后的字符串)、Signature。
JWT工作原理:用户的信息以Token的字符串的形式,保存在客户端中。用户每次请求,将Token存放在请求头Authorization上,服务器拿到该值后进行解析处理。

Express中jsonwebtoken模块用于生成JWT字符串,express-jwt用于将JWT字符串还原成JSON对象。
使用
- 安装模块
npm install jsonwebtoken express-jwt - 引入模块
const jwt = requre('jsonwebtoken') const expressJWT = require('express-jwt') - 生成 JWT 字符串
jwt.sign(payload, secret[, options[, callback]])
payload 存储的对象
secret 签名秘钥
options 配置参数。常见有 expiresIn(过期时间)、algorithm(签名算法)
callback 回调函数app.post('/api/login', (req, res) => {let token = jwt.sign({username: username}, '^123456$', {expireIn: '2h'}) }) - 还原 JWT 字符串
// 此处的 secret 值必须和jwt 生成时所使用的秘钥相同 // unless 指定了哪些接口无须携带Token访问 app.use(expressJWT({secret: '^123456$'}).unless({path:[/^\/api\//]})) - 获取 JWT 信息
在访问权限的接口中,可通过req.user对象即可访问 JWT 字符串中解析的内容
- 捕获 JWT 异常
// 通过异常中间件来处理JWT解析失败 app.use((err, req, res, next) => {if(err.name === 'UnauthorizedError') {// TODO}next() })
multer
multer是用于处理multipart/form-data类型的表单数据,主要用于上传文件。(不会处理任何非 multipart/form-data 的数据 )
multer在解析完请求体后,会向request对象上添加一个body对象和一个file或files对象。body对应表单中提交的文本字段,file或files包含了表单上传的文件。
https://github.com/expressjs/multer
multer(options)
参数说明:
- options 参数配置
- dest / storage 上传文件存放目录。
- fileFilter 文件过滤器
- limits 限制上传文件 (可有效防止Dos攻击)
- fieldNameSize field名字最大长度。默认为 100 bytes
- fieldSize field指最大长度。默认为1MB
- fields 非文件field的最大数量。默认为无限
- fileSize 文件最大长度,单位字节。默认为无限
- files 文件最大数量。默认为无限
- parts part传输的最大数量(field + file)。默认为无限
- headerPairs 键值对最大组数。默认为2000
- preservePath 保存包含文件名的完整路径
storage
storage为存储引擎,multer中具有DiskStorage、MemoryStorage和第三方等引擎。
DiskStorage
DiskStorage为磁盘存储引擎,其有两个选项可用:destination和filename。
destination 用来确定上传的文件存放的位置。可提供一个 string或function。若没有设置则使用操作系统默认的临时文件夹。
注意:若destination 是一个function,则需用手动创建文件夹;若destination 是一个string,multer 会自动创建。
filename用来确定文件夹中文件名。若未设置该参数,则文件将设置一个随机文件名且没有后缀名。
const storage = multer.DiskStorage({distination: function(req, file, cb) {cb(null, '/xxx/xxx')}filename: function(req, file, cb) {cb(null, file.fieldname + "_" + Date.now())}
})const upload = multer({storage: storage})
MemoryStorage
MemoryStorage 为内层存储引擎(将内容存储在Buffer中)
const storage = multer.memoryStorage()
const upload = multer({storage: storage})
注意:当使用内层存储,上传文件非常大,或上传文件非常多时,可能会导致内层溢出。
方法
multer.single(fieldname)
multer.signle()接受一个以filename命名的文件,文件保存至request.file中
multer.array(fieldname[, maxCount])
multer.array() 接受一个以fieldname命名的文件数组,可配置maxCount来限制上传文件数量,文件保存至request.files中
multer.fields(fields)
multer.fields()接受fileds的混合文件,文件保存至request.files中
multer.none()
multer.none() 只接受文本域,和multer.fields([])效果一样。若该模式有文件上传,则抛出LIMIT_UNEXPECTED_FILE
multer.any()
multer.any() 接受一切上传的文件。文件保存至request.files中
const multer = require('multer')// 存储设置
const storage = multer.DiskStorage({distination: function(req, file, cp) {cp(null, '/xxx/xx')}filename: function(req, file, cp)
})const upload = multer({storage:storage})app.post('/upload/photo', upload.single('avatar'), function (req, res) {// req.file 是 `avatar` 文件的信息// req.body 将具有文本域数据,如果存在的话
})app.post('/upload/file', upload.array('file', 3), function (req, res) {// req.files 是 `file` 文件组的信息// req.body 将具有文本域数据,如果存在的话
})app.post('/upload', upload.fields([{name: 'avatar', maxCount: 1},{name: 'file', maxCount: 3}]), function (req, res) {// req.files 是一个对象 (String -> Array) 键是文件名,值是文件数组// req.files['avatar'][0] -> File// req.files['file'] -> Array// req.body 将具有文本域数据,如果存在的话
})
文件属性
| 属性 | 说明 |
|---|---|
fieldname | 表单定义的名称 |
originalname | 文件原始名称 |
encoding | 文件编码 |
mimetype | 文件的 MIME 类型 |
size | 文件大小 |
distination | 文件保存路径 |
filename | 保存至 distination 中的文件名 |
path | 已上传文件的完整路径 |
buffer | 存放整个文件的 Buffer |
自定义中间件
自定义中间件流程:
- 定义中间件
- 监听request对象的 data 事件
- 监听 request 对象的 end 事件
- 解析请求参数
- 封装模块
自定义中间件解析POST提交的数据
// querything 是 Node.js的内置模块
const qs = require('querything')// 定义中间件
const bodyParser = (req, res, next) => {let str = ''// 监听 req 的 data 事件req.on('data', (chunk) => {str += chunk})req.on('end', () => {// 解析数据,并将数据放在 req 的 body 中,供下游访问req.body = qs.parse(str)next()})
}module.exports = bodyParser
模板
Express模板是用于渲染视图的文件,可以包含HTML、CSS、JavaScript等内容,用于构建 Web应用程序的图形界面。
使用Express模板可以快速、方便地创建Web应用程序,并可轻松地将动态数据注入到模板中,以便呈现动态效果。常见的模版引擎有:EJS、Pug、Handlebars 等。
分类
Express模板可分静态模板和动态模板两类:
- 静态模板 预先定义好的 HTML 文件,可通过路由直接呈现
- 动态模板 通过模版引擎加载动态数据来生成动态内容
Express中常用的模板引擎:
- 基于
HTML的模版引擎:Mustache、Handlebars - 基于
JavaScript的模版引擎:EJS、Underscore.js - 基于
CSS的模版引擎:LESS、SASS
使用
模版使用步骤
- 下载模板包
- 配置模版引擎
app.set("view engine", "xxx") - 配置模板路径
app.set("views", path.resolve(__dirname, "views"))(表示模板存放在当前目录下views文件夹中) - 在请求响应中设置渲染
res.render('xx',renderDataObj)
express-generator
express-generator 是 快速创建 express 项目生成器工具。
使用
## 1. 全局安装 express-generator
npm i -g express-generator## 2. 创建项目
#### 快速创建 [project_name[ 的项目,并且使用默认的 jade 模板引擎
express [project_name] #### 快速创建 [project_name[ 的项目,并且使用指定的 ejs 模板引擎
express [project_name] --view=ejs## 3.进入到项目根目录下执行 npm install
npm install## 4. 启动项目
#### npm 命令
npm run start 或 npm start#### node 命令
node ./bin/www## 5.访问 express-generator生成的项目服务默认端口为 3000
项目结构

相关文章:
Node.js教程-express框架
概述 Express是基于Node.js平台(建立在Node.js内置的http模块上),快速、开放、极简的Web开发框架。 中文官网 http://www.expressjs.com.cn/。 Github地址:https://github.com/orgs/expressjs。 Express核心特性: 可设置中间件来响应 HTTP…...
location.origin兼容
if (!window.location.origin) {window.location.origin window.location.protocol "//" window.location.hostname (window.location.port ? : window.location.port: );}...
spring boot集成mybatis和springsecurity实现权限控制功能
上一篇已经实现了登录认证功能,这一篇继续实现权限控制功能,文中代码只贴出来和上一篇不一样的修改的地方,完整代码可结合上一篇一起整理spring boot集成mybatis和springsecurity实现登录认证功能-CSDN博客 数据库建表 权限控制的意思就是根…...
按键修饰符
在键盘监听事件时,我们经常需要判断详细的按键,此时,可以为键盘相关的事件添加按键修饰符,例如: 键盘修饰符案例:...
新版IDEA中Git的使用(一)
说明:本文介绍如何在新版IDEA中使用Git 创建项目 首先,在GitLab里面创建一个项目(git_demo),克隆到桌面上。 然后在IDEA中创建一个项目,项目路径放在这个Git文件夹里面。 Git界面 当前分支&Commit …...
【性能测试】真实企业,性能测试流程总结分析(一)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 性能测试什么时候…...
20231224解决outcommit_id.xml1 parser error Document is empty的问题
20231224解决outcommit_id.xml1 parser error Document is empty的问题 2023/12/24 18:13 在开发RK3399的Android10的时候,出现:rootrootrootroot-X99-Turbo:~/3TB/Rockchip_Android10.0_SDK_Release$ make installclean PLATFORM_VERSION_CODENAMEREL…...
电子电器架构刷写方案——General Flash Bootloader
电子电器架构刷写方案——General Flash Bootloader 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 注:文章1万字左右,深度思考者入!!! 老规矩,分享一段喜欢的文字,避免…...
【Linux】僵尸与孤儿 进程等待
目录 一,僵尸进程 1,僵尸进程 2,僵尸进程的危害 二,孤儿进程 1,孤儿进程 三,进程等待 1,进程等待的必要性 2,wait 方法 3,waitpid 方法 4,回收小结…...
Java小案例-Sentinel的实现原理
前言 Sentinel是阿里开源的一款面向分布式、多语言异构化服务架构的流量治理组件。 主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 核心概念 要想理解一个新的技…...
【Leetcode Sheet】Weekly Practice 21
Leetcode Test 1901 寻找峰值Ⅱ(12.19) 一个 2D 网格中的 峰值 是指那些 严格大于 其相邻格子(上、下、左、右)的元素。 给你一个 从 0 开始编号 的 m x n 矩阵 mat ,其中任意两个相邻格子的值都 不相同 。找出 任意一个 峰值 mat[i][j] 并 返回其位置 [i,j] 。 …...
C语言使用qsort和bsearch实现二分查找
引言 在计算机科学领域,查找是一项基本操作,而二分查找是一种高效的查找算法。本博客将详细解释一个简单的C语言程序,演示如何使用标准库函数qsort和bsearch来对一个整数数组进行排序和二分查找。 代码解析 包含头文件 #include <stdi…...
MySQL的替换函数及补全函数的使用
前提: mysql的版本是8.0以下的。不支持树形结构递归查询的。但是,又想实现树形结构的一种思路 提示:如果使用的是MySQL8.0及其以上的,想要实现树形结构,请参考:MySQL数据库中,如何实现递归查询…...
2022第十二届PostgreSQL中国技术大会-核心PPT资料下载
一、峰会简介 本次大会以“突破•进化•共赢 —— 安全可靠,共建与机遇”为主题,助力中国数据库基础软件可掌控、可研究、可发展、可生产,并推动数据库生态的繁荣与发展。大会为数据库从业者、数据库相关企业、数据库行业及整个IT产业带来崭…...
2024 年 10大 AI 趋势
2025 年,全球人工智能市场预计将达到惊人的 1906.1 亿美元,年复合增长率高达 36.62%。 人工智能软件正在迅速改变我们的世界,而且这种趋势在未来几年只会加速。 我们分析了未来有望彻底改变 2024 年的 10 个AI趋势。从生成式人工智能的兴起到…...
Uboot
什么是Bootloader? Linux系统要启动就必须需要一个 bootloader程序,也就说芯片上电以后先运行一段bootloader程序。 这段 **bootloader程序会先初始化时钟,看门狗,中断,SDRAM,等外设,然后将 Linux内核从f…...
ECMAScript 的未来:预测 JavaScript 创新的下一个浪潮
以下是简单概括关于JavaScript知识点以及一些目前比较流行的比如:es6 想要系统学习: 大家有关于JavaScript知识点不知道可以去 🎉博客主页:阿猫的故乡 🎉系列专栏:JavaScript专题栏 🎉ajax专栏&…...
代码随想录算法训练营第十三天 | 239. 滑动窗口最大值、347.前 K 个高频元素
239. 滑动窗口最大值 题目链接:239. 滑动窗口最大值 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 文章讲解…...
推荐五个免费的网络安全工具
导读: 在一个完美的世界里,信息安全从业人员有无限的安全预算去做排除故障和修复安全漏洞的工作。但是,正如你将要学到的那样,你不需要无限的预算取得到高质量的产品。这里有SearchSecurity.com网站专家Michael Cobb推荐的五个免费…...
Cross-Drone Transformer Network for Robust Single Object Tracking论文阅读笔记
Cross-Drone Transformer Network for Robust Single Object Tracking论文阅读笔记 Abstract 无人机在各种应用中得到了广泛使用,例如航拍和军事安全,这得益于它们与固定摄像机相比的高机动性和广阔视野。多无人机追踪系统可以通过从不同视角收集互补的…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
