当前位置: 首页 > news >正文

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 获取请求 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.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 

项目结构

在这里插入图片描述

相关文章:

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实现二分查找

引言 在计算机科学领域&#xff0c;查找是一项基本操作&#xff0c;而二分查找是一种高效的查找算法。本博客将详细解释一个简单的C语言程序&#xff0c;演示如何使用标准库函数qsort和bsearch来对一个整数数组进行排序和二分查找。 代码解析 包含头文件 #include <stdi…...

MySQL的替换函数及补全函数的使用

前提&#xff1a; mysql的版本是8.0以下的。不支持树形结构递归查询的。但是&#xff0c;又想实现树形结构的一种思路 提示&#xff1a;如果使用的是MySQL8.0及其以上的&#xff0c;想要实现树形结构&#xff0c;请参考&#xff1a;MySQL数据库中&#xff0c;如何实现递归查询…...

2022第十二届PostgreSQL中国技术大会-核心PPT资料下载

一、峰会简介 本次大会以“突破•进化•共赢 —— 安全可靠&#xff0c;共建与机遇”为主题&#xff0c;助力中国数据库基础软件可掌控、可研究、可发展、可生产&#xff0c;并推动数据库生态的繁荣与发展。大会为数据库从业者、数据库相关企业、数据库行业及整个IT产业带来崭…...

2024 年 10大 AI 趋势

2025 年&#xff0c;全球人工智能市场预计将达到惊人的 1906.1 亿美元&#xff0c;年复合增长率高达 36.62%。 人工智能软件正在迅速改变我们的世界&#xff0c;而且这种趋势在未来几年只会加速。 我们分析了未来有望彻底改变 2024 年的 10 个AI趋势。从生成式人工智能的兴起到…...

Uboot

什么是Bootloader? Linux系统要启动就必须需要一个 bootloader程序&#xff0c;也就说芯片上电以后先运行一段bootloader程序。 这段 **bootloader程序会先初始化时钟&#xff0c;看门狗&#xff0c;中断&#xff0c;SDRAM&#xff0c;等外设&#xff0c;然后将 Linux内核从f…...

ECMAScript 的未来:预测 JavaScript 创新的下一个浪潮

以下是简单概括关于JavaScript知识点以及一些目前比较流行的比如&#xff1a;es6 想要系统学习&#xff1a; 大家有关于JavaScript知识点不知道可以去 &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&…...

代码随想录算法训练营第十三天 | 239. 滑动窗口最大值、347.前 K 个高频元素

239. 滑动窗口最大值 题目链接&#xff1a;239. 滑动窗口最大值 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 文章讲解…...

推荐五个免费的网络安全工具

导读&#xff1a; 在一个完美的世界里&#xff0c;信息安全从业人员有无限的安全预算去做排除故障和修复安全漏洞的工作。但是&#xff0c;正如你将要学到的那样&#xff0c;你不需要无限的预算取得到高质量的产品。这里有SearchSecurity.com网站专家Michael Cobb推荐的五个免费…...

Cross-Drone Transformer Network for Robust Single Object Tracking论文阅读笔记

Cross-Drone Transformer Network for Robust Single Object Tracking论文阅读笔记 Abstract 无人机在各种应用中得到了广泛使用&#xff0c;例如航拍和军事安全&#xff0c;这得益于它们与固定摄像机相比的高机动性和广阔视野。多无人机追踪系统可以通过从不同视角收集互补的…...

【LeetCode刷题笔记】动态规划(二)

647. 回文子串 解题思路: 1. 暴力穷举 , i 遍历 [0, N) , j 遍历 [i+1, N] ,判断每一个子串 s[i, j) 是否是回文串,判断是否是回文串可以采用 对撞指针 的方法。如果是回文串就计数 +1...

(十七)Flask之大型项目目录结构示例【二扣蓝图】

大型项目目录结构&#xff1a; 问题引入&#xff1a; 在上篇文章讲蓝图的时候我给了一个demo项目&#xff0c;其中templates和static都各自只有一个&#xff0c;这就意味着所有app的模板和静态文件都放在了一起&#xff0c;如果项目比较大的话&#xff0c;这就非常乱&#xf…...

蓝牙技术在物联网中的应用

随着蓝牙技术的不断演进和发展&#xff0c;蓝牙已经从单一的传统蓝牙技术发展成集传统蓝牙。高速蓝牙和低耗能蓝牙于一体的综合技术&#xff0c;不同的应用标准更是超过40个越来越广的技术领域和越来越多的应用场景&#xff0c;使得目前的蓝牙技术成为包含传感器技术、识别技术…...

宝塔面板Linux服务器CentOS 7数据库mysql5.6升级至5.7版本教程

近段时间很多会员问系统更新较慢&#xff0c;也打算上几个好的系统&#xff0c;但几个系统系统只支持MYSQL5.7版本&#xff0c;服务器一直使用较低的MYSQL5.6版本&#xff0c;为了测试几个最新的系统打算让5.6和5.7并存使用&#xff0c;参考了多个文档感觉这种并存问题会很多。…...

掌握常用Docker命令,轻松管理容器化应用

Docker是一个开源的应用容器引擎&#xff0c;它可以让开发者将应用程序及其依赖打包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的Linux机器或Windows机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。下面介…...

【数据结构1-2】P5076 普通二叉树(简化版)(c++,multiset做法)

文章目录 一、题目【深基16.例7】普通二叉树&#xff08;简化版&#xff09;题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1基本思路&#xff1a; 一、题目 【深基16.例7】普通二叉树&#xff08;简化版&#xff09; 题目描述 您需要写一种数据结构&#xff0c;来维…...

Linux系统安装及管理

目录 一、Linux应用程序基础 1.1应用程序与系统命令的关系 1.2典型应用程序的目录结构 1.3常见的软件包装类型 二、RPM软件包管理 1.RPM是什么&#xff1f; 2.RPM命令的格式 2,1查看已安装的软件包格式 2.2查看未安装的软件包 3.RPM安装包从哪里来&#xff1f; 4.挂…...

MySQL学生向笔记以及使用过程问题记录(内含8.0.34安装教程

MySQL 只会写代码 基本码农 要学好数据库&#xff0c;操作系统&#xff0c;数据结构与算法 不错的程序员 离散数学、数字电路、体系结构、编译原理。实战经验&#xff0c; 高级程序员 去IOE&#xff1a;去掉IBM的小型机、Oracle数据库、EMC存储设备&#xff0c;代之以自己在开源…...

obs video-io.c

video_frame_init 讲解 /* messy code alarm video_frame_init 函数用于初始化视频帧。它接受一个指向 struct video_frame 结构体的指针 frame&#xff0c; 视频格式 format&#xff0c;以及宽度 width 和高度 height。该函数根据视频格式的不同&#xff0c;计算出每个视频帧…...

简述 tcp 和 udp的区别?

简述 tcp 和 udp的区别&#xff1f; TCP&#xff08;Transmission Control Protocol&#xff09;和UDP&#xff08;User Datagram Protocol&#xff09;是两种不同的传输层协议&#xff0c;用于在计算机网络中进行数据传输。以下是它们的主要区别&#xff1a; 区别&#xff1…...

信息收集 - 谷歌hack

搜索引擎 FOFA网络空间测绘:https://fofa.info/ FOFA(FOcus on Assets)是一个网络空间搜索引擎,可以帮助用户快速定位和收集特定目标的信息。 ZoomEye:https://www.zoomeye.org ZoomEye 是一个网络空间搜索引擎,可以用于发现和收集特定目标的网络设备、Web应用程序、开放…...

英飞凌TC3xx之一起认识DSADC系列(七)应用实战项目二(实现旋变软解码)

英飞凌TC3xx之一起认识DSADC系列(七) 1 项目要求2 项目实现2.1 内部时钟配置2.2 输入信号配置2.3 调制器配置2.4 滤波器链路配置2.5 整流器配置3 总结本文写一篇关于DSADC的resover的载波信号生成的应用,刚刚接触DSADC的开发者很容易被手册中简短的文字描述弄的迷惑,它到底…...

【浏览器】同源策略和跨域

1. 什么是跨域 在说跨域之前,先说说同源策略,什么是同源策略呢?同源策略是浏览器的一种安全机制,减少跨站点脚本攻击(XSS,Cross Site Scripting)、跨站点请求伪造(CSRF,Cross Site Request Forgery)攻击等,因为非同源的请求会被浏览器拦截掉。 同源就是协议、域名(…...

云计算与大数据之间的羁绊(期末不挂科版):云计算 | 大数据 | Hadoop | HDFS | MapReduce | Hive | Spark

文章目录 前言&#xff1a;一、云计算1.1 云计算的基本思想1.2 云计算概述——什么是云计算&#xff1f;1.3 云计算的基本特征1.4 云计算的部署模式1.5 云服务1.6 云计算的关键技术——虚拟化技术1.6.1 虚拟化的好处1.6.2 虚拟化技术的应用——12306使用阿里云避免了高峰期的崩…...

基于jdk11和基于apache-httpclient的http请求工具类

1.基于apache-httpclient 需要引入依赖 <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.3.5</version></dependency> 工具类如下&#xff1a; package com.bw.e…...

Node.js(二)-模块化

1. 模块化的基本概念 1.1 什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层将系统拆分成若干模块的过程。对于整个系统来说&#xff0c;模块是可组合、分解和更换的单元。 1.2 编程领域中的模块化 编程领域中的模块化&#xff0c;就是遵守固定的规则&…...

ARM AArch64的TrustZone架构详解(上)

目录 一、概述 1.1 在开始之前 二、什么是TrustZone? 2.1 Armv8-M的TrustZone 2.2 Armv9-A Realm Management Extension(RME)...

从源PC上一次性p2v(qcow2)的构想

磁盘分区表&#xff0c;虚拟硬盘文件&#xff0c;操作系统引导 1. 基本概念和术语 源硬盘&#xff1a;一般就是客户的PC机的硬盘&#xff0c;硬盘里面包含了Windows分区。 源Windows&#xff1a;以源硬盘启动的Windows环境。 虚拟磁盘文件&#xff1a;文件格式有qcow2、vhd…...

数据结构:KMP算法

1.何为KMP算法 KMP算法是由Knuth、Morris和Pratt三位学者发明的&#xff0c;所以取了三位学者名字的首字母&#xff0c;叫作KMP算法。 2.KMP的用处 KMP主要用于字符串匹配的问题&#xff0c;主要思想是当出现字符串不匹配时&#xff0c;我们可以知道一部分之前已经匹配过的的文…...

小程序真机如何清除订阅数据

在做小程序订阅消息开发的过程中发现&#xff0c;真机上如果是选择了‘总是保持以上选择’&#xff0c;一旦用户授权后&#xff0c;后面就不会再弹出申请改订阅消息的授权弹窗&#xff0c;这对于开发过程中是很不方便的。 曾试过清除缓存&#xff0c;重进小程序也不能清除掉 解…...

基于ssm出租车管理系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本出租车管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…...

音视频转码

音视频转码是指&#xff1a; 容器中音视频数据编码方式转换&#xff0c;如由H.264编码转成mpeg-4编码&#xff0c;mp3转成AAC&#xff1b;音视频码率的转换&#xff0c;如4Mb视频码率降为2Mb&#xff0c;视频分辨率的转换&#xff0c;如1080P转换为720P&#xff0c;音频重采样…...

编解码异常分析

前言 最近在做的项目&#xff0c;有H264解码的需求。部分H264文件解码播放后&#xff0c;显示为绿屏或者花屏。 分析 如何确认是否是高通硬解码的问题 adb 指令 adb root adb remount adb shell setenforce 0 adb shell setprop vendor.gralloc.disable_ubwc 1 adb shell c…...

APISpace 热门好用的API推荐,含免费次数

短信验证码&#xff1a;可用于登录、注册、找回密码、支付认证等等应用场景。支持三大运营商&#xff0c;3秒可达&#xff0c;99.99&#xff05;到达率&#xff0c;支持大容量高并发。通知短信&#xff1a;短信通知支持三大运营商以及虚拟运营商&#xff0c;我们提供电信级运维…...

Qt/QML编程学习之心得:一个.qml文件调用另一个.qml文件(十七)

在c++中,一个文件调用另外一个文件最直接最快捷的方式就是#incldue<头文件>的使用,那么在元数据描述性语言QML中,如何从一个界面描述调用另外一个界面描述,一个.qml文件调用另外一个.qml呢?QML虽然有个import,但是用法可以说完全不同于#include。 引用方法1:直接…...

C++_单列模式介绍

介绍 (1)…什么是单例 1.只能有一个实例化的对象的类(2).单例有什么用 1.多线程的线程池的设计 2.系统中只需要一个窗口时才使用单例(无法重复创建) 3.一个操作系统只能有一个文件系统(3).单例怎么用 1.隐藏所有构造函数 2.静态成员内部调用构造函数实例化 3.提供一个静态函数来…...

油烟净化器如何做到高效净化?科技力量,清新餐饮生活

我最近分析了餐饮市场的油烟净化器等产品报告&#xff0c;解决了餐饮业厨房油腻的难题&#xff0c;更加方便了在餐饮业和商业场所有需求的小伙伴们。 油烟净化器的出现&#xff0c;为我们的餐饮生活注入了一抹清新的色彩。然而&#xff0c;它究竟是如何工作的&#xff1f;为何能…...

【HTML5】HTML5 语音合成

一、前言 前一段时间在项目中需要用到播报文字语音。找到了 HTML 5 有这样的功能。 现在有时间进行总结下。 二、SpeechSynthesis SpeechSynthesis 接口是语音服务的控制接口。它可以用于获取设备上关于可用的合成声音的信息&#xff0c; 开始、暂停语音&#xff0c;或者别…...

顺序表的实现

目录 一. 数据结构相关概念​ 二、线性表 三、顺序表概念及结构 3.1顺序表一般可以分为&#xff1a; 3.2 接口实现&#xff1a; 四、基本操作实现 4.1顺序表初始化 4.2检查空间&#xff0c;如果满了&#xff0c;进行增容​编辑 4.3顺序表打印 4.4顺序表销毁 4.5顺…...

深度学习中的池化

1 深度学习池化概述 1.1 什么是池化 池化层是卷积神经网络中常用的一个组件&#xff0c;池化层经常用在卷积层后边&#xff0c;通过池化来降低卷积层输出的特征向量&#xff0c;避免出现过拟合的情况。池化的基本思想就是对不同位置的特征进行聚合统计。池化层主要是模仿人的…...