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 用于处理 JSONRawTextURL中的请求数据
  • cookie-parser 用于处理Cookie
  • multer 用于处理**enctyoe=“multipart/form-data””**的表单数据

基本使用

基本使用步骤:

  1. 导入 express 模块
  2. 创建 express 实例
  3. 创建并启动HTTP服务
  4. 绑定请求事件
// 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处理请求中回调函数的参数:requestresponse对象来处理请求和响应。

request 对象

request对象表示 HTTP请求,包含了请求查询的字符串参数内容HTTP头部等属性。常见属性:

  • request.appcallback为外部文件时,用其访问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-TypeMIME类型
// 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 获取请求 IP
  console.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 获取请求 IP
  console.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.appcallback为外部文件时,用其访问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-TypeMIME类型
  • 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)指业务流程的中间处理环节。其是一个函数,包含了requestrespoonsenext三个参数,其中 next() 把流转交给下一个中间件或路由。

Express 中间件调用流程
在这里插入图片描述
注意:

  1. 在注册路由之前注册中间件(错误中间件除外)
  2. 多个中间件共享requestresponse对象
  3. 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实例上的中间件即为应用级别中间件。(其中methodgetpostputdelete等请求方法)

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 最大失效时间(指从当前时间开始多久后失效),单位毫秒
    • securetrue时,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获取不签名cookiereq.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)是由三部分组成:HeaderPayload(真正的用户信息,加密后的字符串)、Signature
JWT工作原理:用户的信息以Token的字符串的形式,保存在客户端中。用户每次请求,将Token存放在请求头Authorization上,服务器拿到该值后进行解析处理。
在这里插入图片描述
Expressjsonwebtoken模块用于生成JWT字符串,express-jwt用于将JWT字符串还原成JSON对象。

使用
  1. 安装模块
    npm install jsonwebtoken express-jwt
    
  2. 引入模块
    const jwt = requre('jsonwebtoken')
    const expressJWT = require('express-jwt')
    
  3. 生成 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'})
    })
    
  4. 还原 JWT 字符串
    // 此处的 secret 值必须和jwt 生成时所使用的秘钥相同
    // unless 指定了哪些接口无须携带Token访问
    app.use(expressJWT({secret: '^123456$'}).unless({path:[/^\/api\//]}))
    
  5. 获取 JWT 信息

    在访问权限的接口中,可通过req.user对象即可访问 JWT 字符串中解析的内容

  6. 捕获 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对象和一个filefiles对象。body对应表单中提交的文本字段,filefiles包含了表单上传的文件。
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中具有DiskStorageMemoryStorage和第三方等引擎。

DiskStorage

DiskStorage为磁盘存储引擎,其有两个选项可用:destinationfilename
destination 用来确定上传的文件存放的位置。可提供一个 stringfunction。若没有设置则使用操作系统默认的临时文件夹。
注意: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

自定义中间件

自定义中间件流程:

  1. 定义中间件
  2. 监听request对象的 data 事件
  3. 监听 request 对象的 end 事件
  4. 解析请求参数
  5. 封装模块

自定义中间件解析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模板是用于渲染视图的文件,可以包含HTMLCSSJavaScript等内容,用于构建 Web应用程序的图形界面。
使用Express模板可以快速、方便地创建Web应用程序,并可轻松地将动态数据注入到模板中,以便呈现动态效果。常见的模版引擎有:EJS、Pug、Handlebars 等。

分类

Express模板可分静态模板动态模板两类:

  1. 静态模板 预先定义好的 HTML 文件,可通过路由直接呈现
  2. 动态模板 通过模版引擎加载动态数据来生成动态内容

Express中常用的模板引擎:

  • 基于HTML的模版引擎:MustacheHandlebars
  • 基于JavaScript的模版引擎:EJSUnderscore.js
  • 基于CSS的模版引擎:LESSSASS

使用

模版使用步骤

  1. 下载模板包
  2. 配置模版引擎 app.set("view engine", "xxx")
  3. 配置模板路径 app.set("views", path.resolve(__dirname, "views")) (表示模板存放在当前目录下views文件夹中)
  4. 在请求响应中设置渲染 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 

项目结构

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/268588.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能优化算法应用:基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.法医调查算法4.实验参数设定5.算法结果6.…

基于阿里云服务网格流量泳道的全链路流量管理(二):宽松模式流量泳道

作者:尹航 在前文基于阿里云服务网格流量泳道的全链路流量管理(一):严格模式流量泳道中,我们介绍了使用服务网格 ASM 的严格模式流量泳道进行全链路灰度管理的使用场景。该模式对于应用程序无任何要求,只需…

4. java——多态(java巅峰设计,超越了C++的理解,取其精华,去其糟粕)

多态指的是同—个行为具有多个不同表现形式 。是指—个类实例(对象)的相同方法在不同情形下具有 不同表现形式。封装和继承是多态的基础,也就是说,多态只是—种表现形式而已。一个对象,同一个方法不同形态,方法必须重…

Redis源码精读:准备工作

文章目录 前言拉取源码项目结构源码阅读技巧最后 前言 我是醉墨居士,未来的一段时间里面我准备写一些关于Redis源码的文章,来帮助大家深入浅出Redis,希望大家多多支持🫠 拉取源码 git clone https://github.com/redis/redis项目…

大数据----基于sogou.500w.utf8数据的MapReduce编程

目录 一、前言二、准备数据三、编程实现3.1、统计出搜索过包含有“仙剑奇侠传”内容的UID及搜索关键字记录3.2、统计rank<3并且order>2的所有UID及数量3.3、上午7-9点之间&#xff0c;搜索过“赶集网”的用户UID3.4、通过Rank&#xff1a;点击排名 对数据进行排序 四、参…

爬虫响应cookie阿里系案例:某财经

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、响应cookie阿里系特点 cookie中一定有acw_sc__v2清除所有cookie刷新页面时&#xff0c;会自动debugger到设置cookie的文件…

YOLOv8改进 | 主干篇 | 利用SENetV2改进网络结构 (全网首发改进)

一、本文介绍 本文给大家带来的改进机制是SENetV2&#xff0c;其是2023.11月的最新机制(所以大家想要发论文的可以在上面下点功夫)&#xff0c;其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型&#xff0c;而是一个可以和现有的任何…

Spark集群部署与架构

在大数据时代&#xff0c;处理海量数据需要分布式计算框架。Apache Spark作为一种强大的大数据处理工具&#xff0c;可以在集群中高效运行&#xff0c;处理数十TB甚至PB级别的数据。本文将介绍如何构建和管理Spark集群&#xff0c;以满足大规模数据处理的需求。 Spark集群架构…

微服务实战系列之Dubbo(上)

前言 随着一年一度冬至的到来&#xff0c;2023的步伐也将远去。而博主的系列文章&#xff0c;也将从今天起&#xff0c;越来越聚焦如何构建微服务“内核”上。前序系列文章几乎囊括了微服务的方方面面&#xff0c;无论使用什么框架、组件或工具&#xff0c;皆可拿来用之。 那么…

数据处理系列课程 02:数据处理的科学性之初识NumPy

前面我们才提到数据处理是一件非常重要的事情&#xff0c;数据处理的是否得当直接关系到最终的成果&#xff0c;所以针对数据要做缺失值处理、离群点处理、重复值处理、噪声处理、规范化处理、离散化处理、稀疏化处理等处理&#xff0c;这些处理操作的基础都是建立在数学的基础…

[论文阅读笔记28] 对比学习在多目标跟踪中的应用

这次做一篇2D多目标跟踪中使用对比学习的一些方法. 对比学习通过以最大化正负样本特征距离, 最小化正样本特征距离的方式来实现半监督或无监督训练. 这可以给训练MOT的外观特征网络提供一些启示. 使用对比学习做MOT的鼻祖应该是QDTrack, 本篇博客对QDTrack及其后续工作做一个总…

Mac电脑如何彻底删除清除数据?CleanMyMac X软件更专业

虽然不用杀毒&#xff0c;但是日常的清理还是有必要的&#xff0c;特别是卸载一些软件会有残留&#xff0c;可以用命令mdfind来找&#xff0c;然后删&#xff0c;这里给新手用户推荐一款应用clean my mac x&#xff0c;定期清理一下&#xff0c;不用的时候关掉就可以。 CleanM…

JS常用事件大全

事件 事件通常与函数配合使用&#xff0c;这样就可以通过发生的事件来驱动函数执行。 注意&#xff1a;事件名称大小写敏感。若是事件监听方式&#xff0c;则在事件名的前面取消on。 1. 鼠标事件 给btn按钮添加点击事件&#xff0c;点击弹出 你好&#xff01; 2. 键盘事件…

智能优化算法应用:基于沙猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于沙猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于沙猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.沙猫群算法4.实验参数设定5.算法结果6.参考文…

YOLOv8改进 | 2023注意力篇 | MSDA多尺度空洞注意力(附多位置添加教程)

一、本文介绍 本文给大家带来的改进机制是MSDA&#xff08;多尺度空洞注意力&#xff09;发表于今年的中科院一区(算是国内计算机领域的最高期刊了)&#xff0c;其全称是"DilateFormer: Multi-Scale Dilated Transformer for Visual Recognition"。MSDA的主要思想是…

变量的存储类型(storage class)

变量的存储类型(storage class) 对于变量的存储类型&#xff0c;前面遇到过一些疑惑&#xff0c;再简单的在这里说一下。存储类型是指存储变量值的内存类型&#xff0c;它用来决定存储空间的大小。变量的存储类型决定着变量的存储器和作用域。有三个地方可以用于存储变量&#…

netstat的使用

netstat命令查看系统中网络连接状态&#xff0c;可以从显示的Linux网络系统状态信息得知整个Linux系统的网络情况&#xff0c;包括网络连接、路由表、接口状态、伪装连接、网络链路和组播成员组等信息。 语法&#xff1a;netstat [-acCeFghilMnNoprstuvVwx][-A<网络类型>…

算法学习系列(十):用数组模拟链表、双链表、栈、队列、单调栈、单调队列

目录 引言一、数组模拟链表1.模板2.例题3.测试 二、数组模拟双链表1.模板2.例题3.测试 三、数组模拟栈1.模板2.例题3.测试 四、数组模拟队列1.模板2.例题3.测试 五、数组模拟单调栈1.例题模板2.测试 六、数组模拟单调队列1.例题模板2.测试 引言 首先说一下为什么要拿数组来模拟…

DshanMCU-R128s2 SDK 架构与目录结构

R128 S2 是全志提供的一款 M33(ARM)C906(RISCV-64)HIFI5(Xtensa) 三核异构 SoC&#xff0c;同时芯片内部 SIP 有 1M SRAM、8M LSPSRAM、8M HSPSRAM 以及 16M NORFLASH。 本文档作为 R128 FreeRTOS SDK 开发指南&#xff0c;旨在帮助软件开发工程师、技术支持工程师快速上手&am…

[机器人-3]:开源MIT Min cheetah机械狗设计(三):嵌入式硬件设计

目录 概述&#xff1a; 1、硬件组成 2、通信速率 3、通信协议 4、mbedOS 概述&#xff1a; 以1条腿进行设计&#xff0c;其它腿也一样&#xff1a; 腿部硬件组成 1、硬件组成 1&#xff09;UP board计算机板卡&#xff08;Linux OS&#xff09;&#xff1a; 腿部控制器…