nodejs开发后端服务详细学习笔记

用nodejs开发一个后端服务的学习笔记,当初学完后才对很多后端概念有了一个清晰的认识,也算是自己的后端入门笔记,其中对npm、模块的讲解也很值得学习。

P14 http-理解http模块的概念及作用

2022年4月17日

http模块是node官方提供的核心模块:

  • 客户端:消费资源
  • 服务器:提供资源

普通电脑与服务器的区别:有没有安装 IIS、Apache 这些服务器软件,在node中,http模块就相当于上面那些第三方服务器软件。

P15 http-服务器相关的概念

2022年4月17日

IP地址:每台计算机的唯一地址,相当于电话号码,点分十进制,格式 a.b.c.d,每一个都是0-255之间的十进制整数。

  • ping:在终端中输入 ping cafe123.cn,就可以ping出域名对应的ip地址
  • 本地:localhost,对应IP地址 127.0.0.1
  • 域名:Domain Name,因为IP地址不好记而发明的
  • 域名服务器:提供IP地址和域名之间的转换服务的服务器,DNS全称Domain Name Server,用来映射IP地址和域名的对应关系
  • 端口:相当于门牌号,每个端口号不能同时被多个 web 服务占用,默认 80 可以省略,网络请求通过端口号,可以被准确地交给对应的 web 服务器处理

常见端口号:

  • 80: http超文本传输服务
  • 443: https加密的超文本传输服务
  • 3306: MySQL 数据库端口

P16 http-创建最基本的 web 服务器

2022年4月17日

js 复制代码
// 1、导入 http
const http = require('http')

// 2、创建服务器实例
const server = http.createServer()

// 3、绑定 request 事件,监听客户端请求
server.on('request', (req, res) => {
  console.log('someone visit our web server')
})

// 4、启动服务器
server.listen(8080, () => {
  console.log('server run at http://127.0.0.1:8080')
})
  • req 请求对象:req.url 请求路径,req.method 请求方式
  • res 响应对象:res.end 向客户端发送响应内容,注意不是 res.send

解决响应中文乱码问题:调用res.setHeader(),设置 Content-Type 响应头

js 复制代码
res.setHeader('Content-Type', 'text/html;charset=utf-8')

P17 http-根据不同的url响应不同的html内容

2022年4月17日

直接根据请求url来判断返回的内容就行了,如果想要能在手机上访问,本地启动的IP地址 127.0.0.1(或者localhost)要改成电脑实际的ip地址就可以访问了。

  • windows查看本机ip终端命令:ipconfig
  • mac查看本机ip终端命令:ifconfig,和Linux系统下一样

P18 http-实现 clock 时钟的 web 服务器

2022年4月17日

注意加上下面这句解决中文乱码的,css会不生效

js 复制代码
res.setHeader('Content-Type', 'text/html;charset=utf-8')

P19 模块化-模块化的概念

2022年4月18日

将一个大文件拆分成独立并互相依赖的多个小模块,如前面的拆分html文件,好处:复用、可维护、按需加载

P20 模块化-模块的分类&require的使用

2022年4月18日

三大分类:内置模块(fs、path、http)、自定义模块、第三方模块(npm),加载模块用 require,会执行加载模块中的代码。加载自定义模块时,可以省略文件后缀名 .js。

P21 模块化-模块作用域和module对象

2022年4月18日

模块作用域:跟函数作用域类似,在自定义模块中定义的变量、方法,只能在当前模块内访问,防止全局变量污染。

module对象:每一个自定义模块中都有一个 module 对象,里面储存了与当前模块相关 的信息,可以直接在js文件里console.log(module)查看具体信息(当然里面必须要包含 exports 或 module.exports才有用)

P22 模块化-module.exports对象的使用

2022年4月18日

在自定义模块中可以通过 module.exports 将模块内的成员共享出去,供外部使用 require导入自定义模块时,得到的就是 module.exports 所指向的对象(默认是一个空对象)

P23 模块化-exports对象

2022年4月18日

module.exports 单词太长,为了简化 node 又搞出了个 exports 对象,它和 module.exports 指向同一个对象,console.log(module.exports === exports) 结果为true(当然,这要在初始化默认的状态下才成立,如果后面改变了任意一个的指向,那肯定就不成立了)

P24 模块化-exports和module.exports的使用误区

2022年4月18日

最终共享出去的对象,永远都是以 module.exports 所指向的对象为准(就是module.exports可以覆盖exports,不管哪个写在前面,反之则不行,此处用覆盖有点不太准确,就是exports可以往里面添加属性,但是不可以直接赋值个新对象去改变module.exports的指向,反过来 module.exports 可以直接指向一个新对象让 exports 不管是添加属性还是赋值的新对象都无效

一开始 module.exports 和 exports 都指向同一个对象,但是如果 module.exports 重新赋值了一个新对象,exports 就被踢到一边凉拌了。

为了避免混乱,在同一个模块中尽量不要同时使用 module.exports 和 exports。

P25 模块化-CommonJS模块化规范

2022年4月18日

node遵循CommonJS模块规范:

  • 1、每个模块中,module变量即指当前模块
  • 2、module是一个对象,它的属性 exports是对外暴露的接口
  • 3、用require 加载某个模块,其实就是加载模块的 module.exports 属性

P26 包与npm-包的概念

2022年4月18日

第三方模块又叫做包

  • npm:全球最大的包共享平台,npm.Inc公司
  • 搜索包:npmjs.com
  • 供下载包的服务器:registry.npmjs.org
  • npm 包管理工具:Node Package Manager,安装node的时候会自动一块安装,输入终端命令 npm -v 可以查看版本

P27 包与npm-格式化时间的两种做法

2022年4月18日

  • 1、自己封装处理时间的方法,用模块导出导入方式使用
  • 2、直接安装第三方包,dayjs、momentjs,require 进来使用即可

P28 包与npm-使用npm的其他注意点

2022年4月18日

首次安装包后,目录下会多出 node_modules 和 package-lock.json,不要去改这两个文件下的东西,npm 包管理工具会自动维护。

要安装某个包的具体版本,在包名后面用 @版本号

bash 复制代码
npm install [email protected]

版本号遵循"点分十进制",a.b.c,第一位数字代表大版本,第二位数字代表小版本功能版本,第三位代表bug修复。

package.json里记录要安装的包信息,以 ^开头的就是匹配安装第一位大版本的最新版本包,以 ~ 开头的就是要匹配第二位功能版本的最新版本包,没有其他符号的就是直接安装具体版本的包。

P29 包与npm-包管理配置文件

2022年4月18日

package.json

bash 复制代码
npm init -y

文件夹里不能包含中文和空格,否则运行 npm init -y 会报错。

npm install 包名,简写 npm i ,直接用空格分割可以一次安装多个包。-g 全局安装,刚拉下来代码初始化项目时不用跟包名,直接 npm i 会自动根据 package.json 里的配置安装所有的包。

npm uninstall 包名,没有简写,会自动从配置文件里移除。

devDependencies 只在开发阶段用到的包,在安装命令包名前或后加 -D,不知道要安装到哪时,一般根据包的使用文档来安装就行了,规范的包都会直接提供安装命令。

P30 包与npm-解决下包慢的问题

2022年4月18日

默认是从npm官方registry.npmjs.org 下载服务器下载,国内访问国外的节点,需要网络传输需要通过海底光缆,所以慢的很。

淘宝 npm 镜像服务器,每隔一段时间自动同步国外npm官方服务器。

切换 npm 下包镜像源

nrm 小工具,切换镜像源更方便。

P31 包与npm-包的分类&规范的包结构

2022年4月18日

  • 项目包:开发依赖包 -D,核心依赖包
  • 全局包:-g,默认会被安装到c盘,卸载时和卸载普通包一样,不过要多加一个 -g,一般一些工具包才有全局安装的必要

P32 发布包-初始化基础的包结构

2022年4月18日

  • package.json:name、version、main 入口文件
  • index.js
  • README.md

P33 发布包-格式化时间&main属性

2022年4月18日

获取日的方法是 getDate(),getDay()是获取星期,星期日是0

P34 发布包-转义&还原HTML的方法

2022年4月18日

xml 复制代码
防止用户输入可以直接对标签的 <> 进行转义

P35 发布包-模块化拆分&编写包的使用说明

2022年4月18日

将使用步骤,示例写出来就可以了

P36 发布包-把包发布到npm

2022年4月18日

  • 要切换到npm官方源才能登录发布
  • npm unpublish 包名,可以删除发布72小时以内的包
  • 不要往npm 上发布没有意义的包

P37 模块的加载机制

2022年4月18日

不管内置模块还是第三方模块,会优先从缓存中加载,内置模块的加载优先级最高,路径里没有 ./ 或 ../,node就会当成内置模块或第三方模块来加载。

用require 加载模块时,如果省略了文件后缀名,node会遵循:

  • 1、确切的文件名加载
  • 2、自动补全 .js
  • 3、自动补全 .json
  • 4、自动补全 .node
  • 5、加载失败,终端报错

加载第三方模块,会从当前文件父目录下的 node_modules 开始,一级一级向上查找,直到文件根目录。

将文件目录用 require 加载遵循:

  • 1、寻找 package.json文件,从里面的main里找入口文件
  • 2、加载当前目录下的 index.js(在封装vue组件时经常用到,一个组件有多个文件时,直接放到一个目录下,然后新建一个 index.js 导入导出)
  • 3、终端报错,模块找不到

P38 express-认识express并创建基本的服务器

2022年4月19日

第三方npm包,web开发框架,和node内置的http模块类似。基于http内置模块封装出来的,功能更强大,开发效率更高。

js 复制代码
// 1、导入
const express = require('express')

// 2、创建
const app = express()

// 3、启动
app.listen(80, () => {
   console.log('success')
})

P39 express-监听get和post请求&处理参数

2022年4月19日

  • req.query 获取路由参数
  • req.params 获取动态参数

P40 express-静态资源处理

2022年4月19日

js 复制代码
app.use(express.static("public")

外部就可以直接访问public文件夹下的资源,public不会出现在url路径中。如果想要加上路径访问前缀:

js 复制代码
app.use('/public', express.static('public'))

要托管多个目录,重复调用上面的方法就可以了,但是查找文件的时候会有个先后顺序,如在第一个目录中找到了相应的文件就不会再去第二个文件夹了。

P41 express-安装并使用 nodemon

2022年4月19日

nodemon: 能够监听文件的变动,自动重启项目,方便开发

bash 复制代码
node xxx.js   =>  nodemon xxx.js

P42 路由-初识express中的路由

2022年4月19日

路由:就像移动客服的请按 1...,此处就是按键与服务之间的映射。在 express 中就是客户端的请求和服务器处理函数之间的映射关系,由3部分组成:

  • ① 请求类型
  • ② 请求的 URL 地址
  • ③ 处理函数
js 复制代码
app.METHOD(PATH, HANDLER)

P43 路由-路由的模块化

2022年4月19日

为了方便管理维护,不建议直接挂载到app上

js 复制代码
express.Router()

const router = require('./router.js')
app.use(router)
// 添加路由前缀
// app.use('/api', router)

P44 中间件-中间件的概念与格式

2022年4月20日

跟污水处理厂一样,上一级处理完再交给下一级继续处理。express的中间件,本质上就是一个function处理函数

js 复制代码
app.get('/', function(req, res, next) {
  next()
})

middleware,中间件函数形参中必须包含 next 参数,而路由处理函数中只包含 req 和 res。

P45 中间件-全局生效的中间件

2022年4月20日

全局生效中间件:客户端请求到达服务器之后,都会触发的中间件。通过调用 app.use(中间件函数),即可定义一个全局生效的中间件。

多个中间件之间,共享同一份 req 和 res,可以在上游的中间件中为 req 或 res 对象添加自定义属性,供下游的中间件或路由使用。

P46 中间件-局部生效的中间件

2022年4月20日

不用 app.use() 调用,直接加在路由处理中

js 复制代码
const mw = (req, res, next) => {
  next()
}
const mw2 = (req, res, next) => {
  next()
}
app.get('/', 中间件mw, 中间件mw2, (req, res)  => {

})

P47 中间件-中间件的5个注意事项

2022年4月20日

  • ① 一定要在路由之前注册中间件(从上到下匹配的)
  • ② 客户端发送过来的请求,可以连续调用多个中间件进行处理
  • ③ 执行完中间件的业务代码之后,不要忘记调用 next() 函数
  • ④ 为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码
  • ⑤ 连续调用多个中间件时,多个中间件之间,共享 req 和 res 对象

P48 中间件-中间件的分类

2022年4月20日

express官网把常见的中间件用法分成了5大类:

  • ① 应用级别的中间件:绑定到 app 实例上的,app.use、app.get、app.post
  • ② 路由级别的中间件:直接绑定到路由 router 上的
  • ③ 错误级别的中间件:捕获整个项目中发生的异常错误,(err, req, res, next),也是用 app.use() 调用,必须要注册在所有路由之后
  • ④ express 内置的中间件:express.static、express.json、express.urlencoded
  • ⑤ 第三方的中间件

P49 中间件-自定义中间件

2022年4月20日

P50 编写接口-创建基本的服务器&创建API路由模块

2022年4月20日

P51 编写接口-编写get接口

2022年4月20日

get请求参数通过 req.query 获取

P52 编写接口-编写post接口

2022年4月20日

post请求参数要通过 req.body 获取,要获取 URL-encoded 格式的请求体数据,必须配置中间件

js 复制代码
app.use(express.urlencoded({ extended: false }))

P53 跨域-基于cors解决接口跨域问题

2022年4月20日

跨域:cross-domain,浏览器同源(same-origin)安全机制:协议、域名、端口,浏览器其实已经拿到数据了,只是不会将拿到的数据转交给用户。

cors:主流解决方案 cross-origin resource sharing,由一系列http 响应头组成,这些响应头决定了浏览器是否阻止前端跨域获取资源,只支持 XMLHttpRequest Level2 的浏览器,如 IE 10+、Chrome4+、FireFox3.5+。

jsonp:只支持get 请求。

1、安装cors包

bash 复制代码
npm i cors

2、导入

js 复制代码
const cors = require('cors')

3、使用一下

js 复制代码
app.use(cors())

⚠️ 要在路由之前注册,注册的时候要调用一下

P54 跨域-cors相关的3个响应头

2022年4月22日

  • Access-Control-Allow-Origin:访问来源,可以用通配符 *
  • Access-Control-Allow-Header:请求头信息,默认只有9个,要用额外的需要设置
  • Access-Control-Allow-Methods:请求方式,默认允许 GET、POST、HEAD,也可以用通配符 * 设置

P55 跨域-cors的简单请求与预检请求

2022年4月22日

简单请求:需同时满足

  • 1、GET、POST、HEAD
  • 2、无额外请求头

预检请求:只要满足以下任一条件,浏览器会先发送 OPTION 请求进行预检,服务器响应成功后才会发送正式请求

  • 1、GET、POST、HEAD之外的请求方式
  • 2、有额外请求头
  • 3、向服务器发送了 application/json 格式的数据

P56 跨域-编写jsonp接口

2022年4月22日

只能发送get请求,利用 script 标签可以跨域获取资源的历史bug

P57 数据库-学习目标

2022年4月23日

  • MySQL基本使用
  • Express中操作MySQL
  • 前后端身份认证:Session、JWT

P58 数据库-数据库的基本概念

2022年4月23日

database,组织、储存和管理数据的仓库

常见数据库: 1、传统型数据库(关系型数据库、SQL数据库)

  • MySQL
  • Oracle:收费
  • SQL Server:收费 跟 excel 表格很像,数据组织结构分为:数据库 database、数据表 table、数据行 row、字段 field

2、型数据库(非关系型数据库、NoSQL数据库)

  • Mongodb

P59 数据库-安装MySQL数据库

2022年4月23日

  • MySQL Server
  • MySQL Workbench:可视化 MySQL管理工具

P60 数据库-MySQL Workbench的基本用法

2022年4月23日

P61 数据库-创建数据库和表

2022年4月23日

Mac 上 Navicat 连接报错,去系统偏好设置 - MySQL - Initialize Database - Use Legacy Password Encryption

P62 数据库-了解什么是SQL

2022年4月23日

Structured Query Language 结构化查询语言,是一门数据库编程语言,只能在关系型数据库中使用

  • 查询数据 select
  • 插入数据 insert into
  • 更新数据 update
  • 删除数据 delete

需要额外掌握的4种SQL语法:

  • where 条件
  • and 和 or 运算符
  • order by 排序
  • count(*) 函数

P63 SQL语句-select、insert、update、delete

2022年4月23日

sql 复制代码
SELECT * FROM 表名
SELECT 列名[, 列名2] FROM 表名

INSERT INTO 表名 (字段名[, 字段名2]) values (值[, 值2])

# 注意要加 where 条件,否则会更新整张表
UPDATE users SET 字段名 = 新值[, 字段名2 = 新值2] where id = 15

# 注意要加 where 条件,否则会删除整张表
DELETE FROM users where id = 17

P64 SQL语句-where子句、and和or运算符

2022年4月23日

P65 SQL语句-排序

2022年4月23日

  • 升序 asc,默认
  • 降序 desc
  • order by 字段名 desc/asc[, 字段名2 desc/asc]

P66 SQL语句-count函数和as关键字

2022年4月23日

sql 复制代码
SELECT count(*) FROM users
SELECT count(*) FROM users where status = 0

P67 SQL语句-保存和打开sql文件

2022年4月23日

P68 mysql模块-安装并配置mysql模块

2022年4月23日

安装依赖

bash 复制代码
npm i mysql

项目中使用mysql

js 复制代码
const mysql = require('mysql')
const db = mysql.createPool({
  host: '127.0.0.1',
  user: 'xxxx',
  password: 'xxxxx'
  database: 'tablename'
})

P69 mysql模块-查询和插入数据

2022年4月23日

js 复制代码
// ? 标识占位符
let insertSql = 'INSERT INTO users (username, password) VALUES (?, ?)'
db.query(insertSql, ['cafehaus', '123456'], (err, result) => {
  if (err) return console.log(err.message)

  if (result.affectedRows === 1) {
    consloe.log('插入成功')
})

// 插入数据便捷写法   SET ?
let info = { username: 'cafehaus', password: '123456' }
let insertSql = 'INSERT INTO users SET ?'
db.query(insertSql, info , (err, result) => {
  if (err) return console.log(err.message)

  if (result.affectedRows === 1) {
    consloe.log('插入成功')
  }
})

P70 mysql模块-更新和删除数据

2022年4月23日

如果只有一个占位符时,可以不用数组,直接写占位符的那个值就行

DELETE FROM 语句一般使用比较少,因为会把数据直接从表中删掉,一般使用标记删除,也就是用 update 去更新某个字段的值来做标记

P71 web开发模式

2022年4月23日

主流web开发模式:

  • ① 基于服务端渲染的传统开发模式
  • ② 前后端分离的开发模式

服务端渲染 SSR server side render

P72 身份认证的概念

2022年4月23日

身份认证:身份验证、鉴权,通过一定的手段,完成对用户身份的确认

  • 服务端渲染推荐 Session 认证机制
  • 前后端分离推荐 JWT 认证机制

P73 session的原理

2022年4月23日

HTTP 协议的无状态性:客户端的每次 http 请求都是独立的,服务器不会主动保留每次http请求的状态,想象超市的收银员能否记住当前客户是否为vip。

如何突破 HTTP 无状态的限制:超市会为vip客户发放会员卡。

Cookie:储存在用户浏览器中一段不超过4kb的字符串,不同域名下的各自独立,客户端请求时会自动把当前域名下所有未过期的cookie一同发送到服务器。

Cookie存在浏览器,不具安全性,就像客户可以伪造会员卡,所以不要用来存储用户的隐私信息。

Session认证:会员卡(客户端 Cookie) + 刷卡认证。

P74 express-session模块中间件的使用

2022年4月24日

js 复制代码
const session = require('express-session')

app.use({
   secret:'xxx',
   resave:false,
   saveUninitialized:true
})
  • 存储和获取 req.session
  • 清除 req.session.destroy()

P75 jwt-token的原理

2022年4月24日

session认证机制的不足:需要配合浏览器Cookie使用,Cookie默认不支持跨域访问,跨域需要做很多额外的配置。

最流行的跨域请求认证解决方案:JWT Json Web Token,用户信息通过加密的 Token 字符串的形式储存在客户端浏览器中,服务器通过解密还原 Token 字符串来确认用户信息。

JWT由3部分组成:

  • Header:头部
  • Payload:有效荷载,真正的用户信息,用户信息经过加密后生成的字符串
  • Signature:签名

P75 jwt-在express中生成token

2022年4月24日

bash 复制代码
npm i jsonwebtoken express-jwt
  • jsonwebtoken:生成jwt字符串
  • express-jwt:将jwt字符串解析还原成json对象

P76-96 express完整接口项目

2022年4月27日

windows 上 node 链接 mysql 报错:

bash 复制代码
Client does not support authentication protocol requested by server; consider upgrading MySQL client

原因:node中的mysql模块不支持 mysql 8 中的 caching_sha2_password 默认的严格加密模式加密方式,所以修改加密规则为普通模式就可以了。

解决方案:

  • ① 进到安装目录 mysql/bin,登录
bash 复制代码
mysql -u root -p 输入密码
  • ② 再输入命令:
bash 复制代码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
  • ③ 接着输入命令刷新权限:
bash 复制代码
FLUSH PRIVILEGES;

如果后面两条命令输入后显示:Query OK, 0 rows affected (0.01 sec),就是成功了,注意命令后面那个分号不能少。

用终端登录到数据后查看表命令最后的分号后面还要敲一个空格:

bash 复制代码
show databases;

2022年4月28日

客户端一次请求,服务端两次 res.send 会报错:

bash 复制代码
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

2022年4月29日

localtunnel 可以将内网服务器暴露到外网,供其他人访问

  • ① 安装依赖
bash 复制代码
npm i -g localtunnel
  • ② --subdomain 不配置自定义域名会默认给你返回一个,自定义的容易和别人的冲突,然后也可能报错打不开,命令最前面那个是小写的L:
bash 复制代码
lt --port <要映射的端口> --subdomain <自定义域名前缀>

如果打开网址报错:Invalid Host header,在 vue.config.js 里的开发服务器 devServer 里添加:disableHostCheck: true(是否关闭用于 DNS 重绑定的 HTTP 请求的 HOST 检查,devServer 默认只接受来自本地的请求,关闭后可以接受来自任何 HOST 的请求)。

类似的工具还有:ngrok、frp、nps、nat123。

内网穿透:NAT 穿透,内网也称为局域网,就是路由器搭建的网络,比如需要访问别的站点,就要是公网,我们的普通电脑只有一个局域网ip,没有公网ip,同一局域网内的设备可以通过局域网ip找到你,但是不在这个局域网内的设备则找不到你,最多只能找到你的路由器,但进不了你的局域网,局域网外的设备要访问你就需要内网穿透

JWT认证:在 OAuth2 体系中认证通过后返回的令牌信息分为两大类:不透明令牌(opaque tokens)和透明令牌(not opaque tokens)。

不透明令牌:是一种无可读性的令牌,一般来说就是一段普通的 UUID 字符串。使用不透明令牌时资源服务不知道这个令牌是什么,代表谁,需要调用认证服务器校验、获取用户信息。使用不透明令牌采用的是 中心化 的架构。

透明令牌:一般指的是我们常说的JWT Token,用户信息保存在 JWT 字符串中,资源服务器自己可以解析令牌不再需要去认证服务器校验令牌。使用JWT是属于 无状态、去中心化 的架构。

一旦我们选择了使用JWT,就需要明确一点:在不借助外力的情况下,让JWT失效的唯一途径就是等token自己过期,无法做到主动让JWT失效。非要让JWT有主动失效的功能只能借助外力,即在服务端存储JWT的状态,在请求时添加判断逻辑,这个与JWT的无状态化、去中心化特性是矛盾的。

人人都是码农:AI时代,零基础也能学会编程!关于作者:从美工、前端开发一路成功转型Java后端的野生码农 ‍,分享UI转前端、前端转Java、全栈开发、AI人工智能和码农搞钱副业...

相关推荐
风象南31 分钟前
SpringBoot中6种自定义starter开发方法
java·spring boot·后端
Asthenia041210 小时前
Spring AOP 和 Aware:在Bean实例化后-调用BeanPostProcessor开始工作!在初始化方法执行之前!
后端
Asthenia041210 小时前
什么是消除直接左递归 - 编译原理解析
后端
Asthenia041210 小时前
什么是自上而下分析 - 编译原理剖析
后端
Asthenia041211 小时前
什么是语法分析 - 编译原理基础
后端
Asthenia041211 小时前
理解词法分析与LEX:编译器的守门人
后端
uhakadotcom11 小时前
视频直播与视频点播:基础知识与应用场景
后端·面试·架构
Asthenia041212 小时前
Spring扩展点与工具类获取容器Bean-基于ApplicationContextAware实现非IOC容器中调用IOC的Bean
后端
bobz96512 小时前
ovs patch port 对比 veth pair
后端