第 6 课:全栈项目性能 & 安全双进阶 ——Redis 缓存 + JWT 认证(打造高并发高安全后端)

✅ 课程衔接:已掌握「Python 后端工程化 4 层架构 + Vue 前端组件化 + 前后端联动」,此前项目存在两大核心短板:① 数据全靠 MySQL 支撑,高并发下查询缓慢;② 登录认证用 Session,存在分布式兼容、安全风险等问题。本课直击痛点,完成性能升级(Redis 缓存)+ 安全升级(JWT 认证) 双重改造;

✅ 核心定位:Redis 和 JWT 是企业级全栈项目必配技术,前者解决「性能瓶颈」,后者解决「认证安全」,二者结合可让项目从「能用」升级为「好用、耐用、安全」;

✅ 学习价值:掌握高并发项目的缓存设计思想、分布式认证核心方案,适配企业生产环境要求,解决全栈项目线上部署的性能与安全难题。

✅ 今日学习目标

✅ 吃透 Redis 核心原理与应用场景,掌握 Python 操作 Redis 的两种方式,实现「热点数据缓存」,将项目查询性能提升 10 倍;

✅ 理解传统 Session 认证的致命缺陷,精通 JWT 认证的核心原理、生成 / 校验流程,实现「无状态分布式认证」;

✅ 完成企业级整合落地:用JWT 替换 Session 实现登录认证,用Redis 缓存 token + 热点数据,解决认证安全与数据库压力问题;

✅ 掌握「token 有效期控制、注销登录、刷新 token」企业级方案,规避 JWT 原生短板;

✅ 实现「Vue 前端 + Python 后端」的 JWT 全链路联动,打造高安全、高并发的全栈项目雏形。

✅ 课前认知:为什么必须学 Redis+JWT?(项目痛点直击)

经过前 5 课的开发,我们的全栈项目已实现核心功能,但在性能安全两个维度,完全达不到企业生产标准,存在 2 个致命问题:

❌ 痛点 1:性能瓶颈 ------MySQL 扛不住高并发,查询效率低下

所有数据操作均直接访问 MySQL(磁盘型数据库),当项目用户量增加、请求频率变高时,会出现 3 个问题:① 数据库查询缓慢,接口响应超时;② 数据库连接池耗尽,服务崩溃;③ 重复查询相同数据(如用户信息、商品列表),造成资源浪费。

✅ 解决方案:引入Redis 内存数据库,缓存高频访问的「热点数据」,让请求优先访问 Redis,大幅降低 MySQL 压力,提升接口响应速度。

❌ 痛点 2:安全短板 ------Session 认证不适配企业分布式部署

此前用 Session 保存用户登录状态,存在 3 个致命缺陷:① Session 存储在服务器内存,分布式部署时多台服务器无法共享,用户登录后切换服务器需重新登录;② Session 依赖 Cookie 传递,存在 CSRF 跨站请求伪造风险;③ 服务器内存有限,大量用户登录会导致内存溢出。

✅ 解决方案:用JWT(JSON Web Token) 替换 Session,实现「无状态认证」------ 用户信息加密存储在 token 中,服务器无需存储,任意服务器均可校验,完美适配分布式部署,且安全性更高。

💡 核心结论:Redis 是性能刚需,JWT 是安全刚需,二者是企业级全栈项目的标配技术,缺一不可。

✅ 一、核心知识点精讲(模块 1):性能基石 ------Redis 缓存核心 + Python 实战

✅ 1. Redis 核心认知(快速吃透,必懂)

✔️ 什么是 Redis?

Redis 是一款高性能的开源内存型数据库,数据直接存储在服务器内存中,同时支持数据持久化到磁盘。对比我们常用的 MySQL,二者核心差异决定了各自的适用场景:

特性 MySQL(磁盘数据库) Redis(内存数据库)
存储位置 磁盘 内存(核心)
读写速度 慢(毫秒级) 极快(微秒级)
数据结构 仅支持二维表 支持字符串、哈希、列表等多种结构
核心优势 海量数据存储、事务支持 高并发读写、缓存、分布式锁
适用场景 核心业务数据持久化存储 热点数据缓存、限流、计数器
✔️ Redis 核心应用场景(全栈项目必用 3 个)

热点数据缓存:将用户信息、商品列表、首页数据等高频查询数据存入 Redis,请求优先读取缓存,缓存失效再查数据库(全栈项目最核心用法);

Token 存储 :存储 JWT 令牌、验证码等临时数据,利用 Redis 的过期策略实现自动失效;✅ 计数器 / 限流:实现接口请求次数统计、用户点赞数统计、接口限流等功能(进阶用法)。

✔️ Redis 核心数据类型(聚焦全栈高频 4 种,够用即可)

Redis 支持丰富的数据结构,无需全部掌握,以下 4 种覆盖 90% 的全栈项目场景,重点掌握:

  1. String(字符串):最基础类型,存储文本、数字,适用于存储 token、验证码、单值数据(如用户昵称);
  2. Hash(哈希) :键值对的集合,适用于存储对象型数据(如用户信息、商品信息),可单独操作某个字段,无需整体修改;
  3. List(列表):有序的字符串集合,适用于存储有序数据(如商品排行榜、消息队列);
  4. Set(集合):无序且唯一的字符串集合,适用于去重、交集 / 并集计算(如用户关注列表、商品标签)。

✅ 2. Python 操作 Redis(2 种方式,企业全覆盖)

Python 操作 Redis 有两种主流方式,原生库 适合理解底层原理,框架封装库适合工程化开发,二者均需先安装 Redis 服务(本地 / 服务器),并启动 Redis。

⚠️ 前置准备:本地安装 Redis(Windows 下载 Redis 安装包,Mac 执行brew install redis),启动命令:redis-server

✔️ 方式 1:原生 redis 库(入门首选,理解底层)

python

运行

复制代码
# 1. 安装依赖
# pip install redis

# 2. 核心操作代码(直接复制使用)
import redis

# 建立Redis连接(核心配置)
r = redis.Redis(
    host="localhost",  # Redis地址(本地填localhost)
    port=6379,         # 默认端口
    db=0,              # 数据库编号(Redis默认16个库,从0开始)
    decode_responses=True  # 自动解码为字符串,避免返回字节流
)

# ✅ String类型操作(token、验证码存储)
r.set("token:admin", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", ex=3600)  # ex=过期时间(秒),1小时过期
token = r.get("token:admin")  # 查询
r.delete("token:admin")       # 删除
print("String查询结果:", token)

# ✅ Hash类型操作(用户信息、商品信息存储,最常用)
# 存储用户信息(key=user:admin,值为多个字段)
r.hmset("user:admin", {"username": "admin", "nickname": "超级管理员", "age": 20})
# 查询单个字段
nickname = r.hget("user:admin", "nickname")
# 查询所有字段(返回字典)
user_info = r.hgetall("user:admin")
print("Hash查询结果:", user_info)

# ✅ 通用操作
r.expire("user:admin", 7200)  # 设置过期时间(2小时)
r.exists("user:admin")        # 判断key是否存在
r.keys("*")                   # 查询所有key
✔️ 方式 2:Flask-Redis 封装(工程化首选,适配 4 层架构)

在 Flask 项目中使用封装库,可将 Redis 连接全局初始化,适配分层架构,无需重复创建连接,企业项目标配。

python

运行

复制代码
# 1. 安装依赖
# pip install flask-redis

# 2. 在config.py中添加Redis配置
class DevConfig:
    REDIS_URL = "redis://localhost:6379/0"  # Redis连接地址

# 3. 在run.py中全局初始化Redis
from flask import Flask
from flask_redis import FlaskRedis
app = Flask(__name__)
app.config.from_object("config.DevConfig")
redis_client = FlaskRedis(app)  # 全局Redis客户端,全项目可调用

# 4. 在业务层/数据层使用(示例:app/service/user_service.py)
from app.common.redis_client import redis_client
def get_user_info_service(username):
    # 先查Redis缓存
    user_cache = redis_client.hgetall(f"user:{username}")
    if user_cache:
        return user_cache  # 缓存存在,直接返回
    # 缓存不存在,查数据库,再写入缓存
    user = get_user_by_username(username)
    redis_client.hmset(f"user:{username}", {"username": user.username, "nickname": user.nickname})
    redis_client.expire(f"user:{username}", 3600)  # 1小时过期
    return user

✅ 3. Redis 缓存核心设计思想(企业必背)

缓存的核心不是「无脑存储」,而是「按需缓存、合理失效」,否则会出现缓存击穿、缓存雪崩、缓存一致性问题,掌握以下 3 个原则,可避开 99% 的缓存坑:

原则 1:缓存热点数据:只缓存「查询频率高、修改频率低」的数据(如用户信息、商品详情),修改频繁的数据(如订单、库存)不适合缓存;

原则 2:缓存失效策略 :为所有缓存设置过期时间(ex),避免缓存永久存在,同时过期时间错开,防止大量缓存同时失效导致数据库压力骤增;

原则 3:缓存更新机制 :数据修改后(如用户昵称修改),先更新数据库,再删除缓存,保证缓存与数据库数据一致。

✅ 二、核心知识点精讲(模块 2):安全基石 ------JWT 认证核心 + Python 实战

✅ 1. 传统 Session VS JWT(核心对比,吃透为什么替换)

先彻底理解 Session 的缺陷,才能掌握 JWT 的核心价值,二者的本质差异是「有状态认证 」和「无状态认证」:

❌ Session 认证(有状态)核心流程 & 缺陷

plaintext

复制代码
1. 用户登录 → 服务器生成SessionID,存储用户信息到内存 → 返回SessionID到前端(存入Cookie);
2. 用户后续请求 → 前端携带Cookie中的SessionID → 服务器根据SessionID查询内存中的用户信息 → 验证通过。

✅ 致命缺陷:① 服务器存储用户信息,占用内存;② 分布式部署时,多服务器无法共享 Session;③ 依赖 Cookie,存在 CSRF 风险。

✅ JWT 认证(无状态)核心流程 & 优势

plaintext

复制代码
1. 用户登录 → 服务器校验账号密码成功 → 生成JWT令牌(加密存储用户信息)→ 返回令牌到前端;
2. 用户后续请求 → 前端在请求头中携带JWT令牌 → 服务器校验令牌合法性(无需查询存储)→ 验证通过。

✅ 核心优势:① 服务器不存储任何用户信息,无内存压力;② 令牌自带用户信息,任意服务器均可校验,完美适配分布式部署;③ 基于请求头传递,不依赖 Cookie,无 CSRF 风险;④ 支持跨域、跨端(PC / 移动端)认证。

✅ 2. JWT 核心原理(3 部分组成,一眼看懂)

JWT 令牌本质是一段加密的字符串 ,由「.」分隔为 3 个部分,每部分各司其职,缺一不可,格式示例:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzM1NzE1NjAwfQ.Sf982x0X7e9s8jK5tG7a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0

✔️ JWT 三部分组成(Header + Payload + Signature)
  1. Header(头部) :固定格式,声明加密算法(如 HS256)和令牌类型(JWT),Base64 编码(可解码,不加密);示例:{"alg": "HS256", "typ": "JWT"}
  2. Payload(载荷) :存储非敏感用户信息 (如用户名、用户 ID),可自定义字段,Base64 编码(可解码,严禁存储密码等敏感数据);示例:{"username": "admin", "exp": 1735715600}(exp = 令牌过期时间)
  3. Signature(签名) :核心安全层,用「Header 指定的算法 + 服务器密钥」对 Header 和 Payload 加密生成,无法篡改------ 一旦令牌内容被修改,签名校验失败。

💡 安全核心:Signature 的加密密钥仅保存在服务器,前端无法获取,保证令牌无法伪造、篡改。

✅ 3. Python 实现 JWT 完整流程(PyJWT 库,企业实战)

使用 Python 最主流的 PyJWT 库,实现 JWT 的「生成令牌、校验令牌、刷新令牌」全套功能,直接整合到后端 4 层架构中。

✔️ 步骤 1:安装依赖 + 全局配置密钥

bash

运行

复制代码
# 安装PyJWT库
pip install pyjwt

python

运行

复制代码
# 在config.py中添加JWT配置(密钥必须保密,线上存储在环境变量)
class DevConfig:
    JWT_SECRET_KEY = "python_full_stack_jwt_secret_2026"  # 服务器密钥(自定义)
    JWT_EXPIRE_TIME = 3600  # JWT过期时间(秒),1小时
✔️ 步骤 2:封装 JWT 工具类(公共工具层,全项目复用)

app/common/jwt_utils.py中封装核心方法,适配分层架构,API 层、服务层可直接调用,企业级规范。

python

运行

复制代码
import jwt
import time
from config import DevConfig
from app.common.exceptions import TokenExpiredException, InvalidTokenException

# JWT配置
SECRET_KEY = DevConfig.JWT_SECRET_KEY
EXPIRE_TIME = DevConfig.JWT_EXPIRE_TIME

def generate_jwt(username):
    """生成JWT令牌:传入用户名,返回令牌"""
    # 1. 构造Payload载荷(包含用户信息+过期时间)
    payload = {
        "username": username,
        "iat": int(time.time()),  # 签发时间
        "exp": int(time.time()) + EXPIRE_TIME  # 过期时间
    }
    # 2. 生成令牌(HS256算法加密)
    token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")
    return token

def verify_jwt(token):
    """校验JWT令牌:传入令牌,返回用户信息/抛出异常"""
    try:
        # 校验令牌合法性+过期时间
        payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        return payload  # 校验成功,返回载荷中的用户信息
    except jwt.ExpiredSignatureError:
        # 令牌过期,抛出自定义异常
        raise TokenExpiredException(code=4011, msg="令牌已过期,请重新登录")
    except jwt.InvalidTokenError:
        # 令牌无效,抛出自定义异常
        raise InvalidTokenException(code=4012, msg="令牌无效,请重新登录")

def refresh_jwt(token):
    """刷新令牌:令牌即将过期时,生成新令牌(延长有效期)"""
    payload = verify_jwt(token)
    payload["exp"] = int(time.time()) + EXPIRE_TIME  # 刷新过期时间
    new_token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")
    return new_token
✔️ 步骤 3:自定义 JWT 异常类(对接全局异常处理)

app/common/exceptions.py中新增异常,与上一课的全局异常中间件联动,实现标准化响应。

python

运行

复制代码
# JWT专属异常(继承基础异常类)
class TokenExpiredException(BaseException):
    pass

class InvalidTokenException(BaseException):
    pass

class TokenMissingException(BaseException):
    def __init__(self):
        super().__init__(code=4013, msg="请求头中未携带令牌")

✅ 三、核心知识点精讲(模块 3):企业级整合实战 ------Redis+JWT 落地 4 层架构(重中之重)

本课最终目标是将 Redis 和 JWT 无缝整合到前序的 4 层架构项目中,完全替换「Session + 纯 MySQL」的旧方案,实现「性能 + 安全」双升级,同时保证前端无感知,无需修改代码。

✅ 1. 核心改造 1:JWT 替换 Session,实现登录认证全流程

改造「用户登录接口」,登录成功后生成 JWT 令牌,返回给前端;新增「JWT 全局校验中间件」,拦截所有需授权的接口,校验令牌合法性。

✔️ 改造 1:登录接口(API 层,app/api/user_api.py)

python

运行

复制代码
from app.common.jwt_utils import generate_jwt
from app.common.redis_client import redis_client

@user_bp.post("/login")
def login():
    data = request.json
    username = data.get("username")
    password = data.get("password")
    # 调用业务层校验账号密码
    user = login_service(username, password)
    # 生成JWT令牌
    token = generate_jwt(username)
    # ✅ 关键:将token存入Redis,实现注销功能(JWT原生不支持注销)
    redis_client.set(f"token:{username}", token, ex=DevConfig.JWT_EXPIRE_TIME)
    # 返回令牌给前端
    return jsonify({
        "code":200,
        "msg":"登录成功",
        "data":{"username":user.username, "nickname":user.nickname, "token":token}
    })
✔️ 改造 2:JWT 全局校验中间件(run.py,拦截所有需授权接口)

python

运行

复制代码
from flask import request
from app.common.jwt_utils import verify_jwt
from app.common.exceptions import TokenMissingException
from app.common.redis_client import redis_client

@app.before_request
def jwt_auth_middleware():
    """JWT全局校验中间件:白名单接口不校验,其余接口必须携带令牌"""
    # 接口白名单(无需登录的接口)
    white_list = ["/api/user/login", "/api/user/register"]
    if request.path in white_list:
        return None
    # 从请求头获取令牌(前端需在请求头中携带:Authorization: Bearer <token>)
    token = request.headers.get("Authorization")
    if not token or not token.startswith("Bearer "):
        raise TokenMissingException()
    token = token.split(" ")[1]  # 提取纯令牌
    # 1. 校验令牌合法性
    payload = verify_jwt(token)
    username = payload.get("username")
    # 2. 校验令牌是否在Redis中(实现注销功能:注销时删除Redis中的token)
    redis_token = redis_client.get(f"token:{username}")
    if not redis_token or redis_token != token:
        raise InvalidTokenException(msg="令牌已失效,请重新登录")
    # 3. 将用户信息存入request,供后续接口使用
    request.username = username
    return None

✅ 2. 核心改造 2:Redis 缓存落地,实现性能升级

在「用户信息查询、商品列表查询」等高频接口中,加入 Redis 缓存逻辑,先查缓存,再查数据库,大幅提升接口响应速度。

✔️ 改造示例:用户信息查询(服务层,app/service/user_service.py)

python

运行

复制代码
def get_user_info_service(username):
    """查询用户信息:缓存优先,数据库兜底"""
    # 1. 先查Redis缓存
    cache_key = f"user:{username}"
    user_cache = redis_client.hgetall(cache_key)
    if user_cache:
        logger.info(f"业务层:从Redis缓存获取用户信息,用户名={username}")
        return user_cache
    # 2. 缓存不存在,查数据库
    user = get_user_by_username(username)
    if not user:
        raise UserNotExistException()
    # 3. 将数据库数据写入Redis缓存,设置过期时间
    redis_client.hmset(cache_key, {
        "username": user.username,
        "nickname": user.nickname
    })
    redis_client.expire(cache_key, 3600)  # 1小时过期
    logger.info(f"业务层:从数据库获取用户信息,已写入缓存,用户名={username}")
    return {"username": user.username, "nickname": user.nickname}

✅ 3. 核心改造 3:实现注销登录 + 令牌刷新(企业级必备)

解决 JWT 原生短板,实现「注销登录」和「令牌刷新」功能,适配企业生产需求。

✔️ 功能 1:注销登录接口(删除 Redis 中的 token,令牌失效)

python

运行

复制代码
@user_bp.get("/logout")
def logout():
    username = request.username  # 从中间件获取当前登录用户
    # 删除Redis中的token,令牌失效
    redis_client.delete(f"token:{username}")
    return jsonify({"code":200, "msg":"退出登录成功"})
✔️ 功能 2:令牌刷新接口(延长令牌有效期,避免用户频繁登录)

python

运行

复制代码
@user_bp.get("/refresh_token")
def refresh_token():
    token = request.headers.get("Authorization").split(" ")[1]
    new_token = refresh_jwt(token)
    username = verify_jwt(token).get("username")
    # 更新Redis中的token
    redis_client.set(f"token:{username}", new_token, ex=DevConfig.JWT_EXPIRE_TIME)
    return jsonify({"code":200, "msg":"令牌刷新成功", "data":{"token":new_token}})

✅ 4. 前端联动适配(Vue 端,无缝对接 JWT)

前端只需在请求头中携带 JWT 令牌,即可实现接口访问,无需修改业务逻辑,适配所有 Vue 开发方式(CDN / 脚手架)。

✔️ Vue 中 Axios 全局携带令牌(示例)

javascript

运行

复制代码
// 1. CDN版Vue(入门)
axios.interceptors.request.use(config => {
    // 从localStorage中获取token,请求头中携带
    const token = localStorage.getItem("token");
    if (token) {
        config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
});

// 2. Vue脚手架版(工程化)
// 在src/utils/request.js中配置拦截器
import axios from "axios";
const request = axios.create({ baseURL: "http://127.0.0.1:5000" });
request.interceptors.request.use(config => {
    const token = localStorage.getItem("token");
    token && (config.headers.Authorization = `Bearer ${token}`);
    return config;
});
export default request;

✅ 四、今日核心实战(必做,性能 + 安全双验收)

✅ 实战需求:全栈项目「性能 + 安全」升级改造

✔️ 实战目标

基于前 5 课的 4 层架构项目,完成全套改造:① 用 JWT 替换 Session 实现登录认证,新增令牌校验、注销、刷新功能;② 用 Redis 缓存用户信息、商品列表等热点数据;③ 整合全局异常处理,保证所有接口返回标准化格式;④ 前端适配 JWT 令牌携带,实现全链路联动。

✔️ 核心验收标准(企业级)

✅ 登录成功返回 JWT 令牌,前端存储后,所有请求自动携带令牌;

✅ 未携带令牌 / 令牌过期 / 令牌无效,均返回 401 系列标准化错误;

✅ 注销登录后,原令牌失效,无法访问需授权接口;

✅ 高频接口(用户信息、商品列表)优先读取 Redis,缓存命中率≥90%;

✅ 分布式部署时(启动多台后端服务),JWT 认证正常生效,无登录态丢失问题;

✅ 接口响应速度提升:缓存命中时,响应时间≤10ms;缓存未命中时,响应时间≤50ms。

✔️ 实战价值

本次改造后的项目,完全达到企业生产环境的性能与安全标准,可直接作为你的全栈项目模板,用于后续的上线部署。

✅ 五、课后作业(分层练习,对标企业招聘要求)

📌 基础作业(必做,巩固核心)

  1. 按本课规范,为「商品模块」添加 Redis 缓存,实现商品列表、商品详情的缓存功能,设置不同的过期时间;
  2. 实现「商品库存修改」接口,保证「修改数据库后,删除对应缓存」,避免缓存不一致;
  3. 为 JWT 令牌添加「用户权限」字段(如 admin/normal),在中间件中校验权限,实现「管理员专属接口」拦截。

📌 进阶作业(选做,企业级能力拓展)

  1. 实现「接口限流」功能:基于 Redis 实现 IP 限流,限制单个 IP 每分钟最多请求 100 次,超出则返回 429 错误;
  2. 优化 JWT 令牌,实现「双令牌机制」(access_token+refresh_token),access_token 短期有效(1 小时),refresh_token 长期有效(7 天),提升用户体验;
  3. 搭建 Redis 集群(主从复制),实现缓存高可用,避免 Redis 单点故障导致项目崩溃。

✅ 课程小结

  1. 全栈项目的性能升级核心是 Redis 缓存,利用内存读写的高性能,缓存热点数据,降低数据库压力,核心原则是「缓存热点、合理失效、及时更新」;
  2. 全栈项目的安全升级核心是 JWT 认证,实现无状态分布式认证,解决 Session 的分布式缺陷,核心是「令牌加密、签名校验、Redis 辅助实现注销」;
  3. Redis+JWT 的整合,需适配后端 4 层架构,封装为工具类 / 中间件,实现「一次开发、全局生效」;
  4. 企业级开发的核心:不仅要实现功能,更要保证性能、安全、高可用,这是区别于 demo 开发的关键;
  5. 本次改造后的项目,已具备企业级全栈项目的核心能力,后续可直接对接上线部署、性能优化。
相关推荐
困知勉行1985几秒前
Redis数据结构及其底层实现
数据库·redis·缓存
悟能不能悟3 分钟前
java HttpServletRequest 设置header
java·开发语言
云栖梦泽7 分钟前
易语言运维自动化:中小微企业的「数字化运维瑞士军刀」
开发语言
一直在追8 分钟前
告别 WHERE id=1!大数据工程师的 AI 觉醒:手把手带你拆解向量数据库 (RAG 核心)
大数据·数据库
刘975310 分钟前
【第23天】23c#今日小结
开发语言·c#
Gofarlic_OMS12 分钟前
协同设计平台中PTC许可证的高效调度策略
网络·数据库·安全·oracle·aigc
敢敢のwings13 分钟前
VGGT-Long:极简主义驱动的公里级单目三维重建系统深度解析(Pytorch安装手册版)
人工智能·pytorch·python
刘一说15 分钟前
Windows 与 Linux 跨平台自动化 MySQL 8 备份:专业级脚本设计与实战指南
linux·数据库·windows·mysql·自动化
aiguangyuan16 分钟前
CART算法简介
人工智能·python·机器学习
郝学胜-神的一滴20 分钟前
线程同步:并行世界的秩序守护者
java·linux·开发语言·c++·程序人生