基于go语言的云原生TodoList Demo 项目,验证云原生核心特性

以下是一个基于 Go 语言 的云原生 TodoList Demo 项目,涵盖 容器化、Kubernetes 编排、CI/CD、可观测性、弹性扩缩容 等核心云原生特性,代码简洁且附详细操作指南,适合入门学习。

在这里插入图片描述

项目概览

  • 目标:实现一个支持增删改查(CRUD)的 TodoList 后端服务,通过云原生技术栈部署,展示完整的云原生实践流程。
  • 技术栈
    • 后端:Go 1.21 + Gin(轻量高性能 Web 框架)
    • 数据库:PostgreSQL(云原生持久化存储)
    • 容器化:Docker(多阶段构建减小镜像体积)
    • 编排:Kubernetes(K8s,声明式管理)
    • CI/CD:GitHub Actions(自动化构建、测试、部署)
    • 可观测性:Prometheus(监控指标) + Grafana(可视化) + Loki(日志聚合)
    • 配置管理:K8s ConfigMap/Secret(外部化配置)

在这里插入图片描述

一、项目结构

todolist-cloudnative/
├── cmd/                    # 主程序入口
│   └── server/
│       └── main.go         # Gin 服务启动入口
├── internal/               # 内部业务逻辑
│   ├── api/                # HTTP 接口层
│   │   └── v1/
│   │       └── todo.go     # Todo 接口实现
│   ├── model/              # 数据库模型
│   │   └── todo.go         # Todo 结构体与数据库操作
│   └── config/             # 配置加载
│       └── config.go       # 读取环境变量/配置文件
├── pkg/                    # 公共工具库
│   └── prometheus/         # Prometheus 指标注册
│       └── metrics.go      # 自定义监控指标
├── docker/                  # Docker 配置
│   └── Dockerfile          # 多阶段构建脚本
├── k8s/                     # K8s 部署配置
│   ├── todo-deployment.yaml    # 应用 Deployment
│   ├── todo-service.yaml       # 应用 Service
│   ├── postgres-statefulset.yaml  # PostgreSQL StatefulSet
│   ├── postgres-service.yaml      # PostgreSQL Service
│   ├── configmap.yaml    # 非敏感配置(K8s 注入)
│   └── secret.yaml       # 敏感配置(数据库密码,K8s Secret)
├── prometheus/            # Prometheus 监控配置
│   └── todolist.yml      # 抓取规则
├── scripts/               # 辅助脚本(可选)
│   └── init-db.sh         # 初始化数据库表(可选)
├── go.mod                 # Go 模块依赖
├── go.sum                 # 依赖校验
└── README.md              # 操作指南

二、核心功能实现(Go 后端)

1. 初始化项目(Go Modules)
mkdir todolist-cloudnative && cd todolist-cloudnative
go mod init github.com/your-username/todolist-cloudnative
go get -u github.com/gin-gonic/gin  # Web 框架
go get -u github.com/jmoiron/sqlx   # SQL 工具库
go get -u github.com/lib/pq         # PostgreSQL 驱动
go get -u github.com/prometheus/client_golang/prometheus  # 监控指标
2. 配置加载(internal/config/config.go
package configimport ("os""strconv"
)type Config struct {ServerPort     string `env:"SERVER_PORT" default:"8080"`PostgresHost   string `env:"POSTGRES_HOST" default:"postgres-service"`PostgresPort   int    `env:"POSTGRES_PORT" default:"5432"`PostgresDB     string `env:"POSTGRES_DB" default:"tododb"`PostgresUser   string `env:"POSTGRES_USER"`PostgresPass   string `env:"POSTGRES_PASSWORD"`
}func Load() (*Config, error) {port := os.Getenv("SERVER_PORT")if port == "" {port = "8080"}postgresPort, err := strconv.Atoi(os.Getenv("POSTGRES_PORT"))if err != nil {return nil, err}return &Config{ServerPort:   port,PostgresHost: os.Getenv("POSTGRES_HOST"),PostgresPort: postgresPort,PostgresDB:   os.Getenv("POSTGRES_DB"),PostgresUser: os.Getenv("POSTGRES_USER"),PostgresPass: os.Getenv("POSTGRES_PASSWORD"),}, nil
}
3. 数据库模型(internal/model/todo.go
package modelimport ("context""time""github.com/jmoiron/sqlx"_ "github.com/lib/pq"
)type Todo struct {ID        int64     `db:"id" json:"id"`Title     string    `db:"title" json:"title"`Content   string    `db:"content" json:"content"`IsDone    bool      `db:"is_done" json:"is_done"`CreatedAt time.Time `db:"created_at" json:"created_at"`UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}type TodoModel struct {db *sqlx.DB
}func NewTodoModel(db *sqlx.DB) *TodoModel {return &TodoModel{db: db}
}func (m *TodoModel) Create(ctx context.Context, todo *Todo) error {_, err := m.db.NamedExecContext(ctx,`INSERT INTO todos (title, content, is_done, created_at, updated_at)VALUES (:title, :content, :is_done, NOW(), NOW())`,todo)return err
}// 其他方法(查询、更新、删除)类似...
4. HTTP 接口(internal/api/v1/todo.go
package v1import ("net/http""time""github.com/gin-gonic/gin""github.com/google/uuid""github.com/prometheus/client_golang/prometheus/promauto""github.com/prometheus/client_golang/prometheus/promhttp""todolist-cloudnative/internal/config""todolist-cloudnative/internal/model"
)var (todoCounter = promauto.NewCounterVec(prometheus.CounterOpts{Name: "todo_operations_total",Help: "Total number of Todo operations",}, []string{"operation"})
)type TodoHandler struct {cfg    *config.Configmodel  *model.TodoModel
}func NewTodoHandler(cfg *config.Config, model *model.TodoModel) *TodoHandler {return &TodoHandler{cfg: cfg, model: model}
}// CreateTodo 创建待办事项
func (h *TodoHandler) CreateTodo(c *gin.Context) {var req struct {Title   string `json:"title" binding:"required"`Content string `json:"content"`}if err := c.ShouldBindJSON(&req); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}todo := &model.Todo{Title:   req.Title,Content: req.Content,IsDone:  false,}if err := h.model.Create(c, todo); err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "创建失败"})return}todoCounter.WithLabelValues("create").Inc()c.JSON(http.StatusCreated, todo)
}// 其他接口(GetTodo、UpdateTodo、DeleteTodo)类似...
5. 服务启动(cmd/server/main.go
package mainimport ("context""log""net/http""os""os/signal""syscall""time""github.com/gin-gonic/gin""github.com/jmoiron/sqlx"_ "github.com/lib/pq""todolist-cloudnative/internal/config""todolist-cloudnative/internal/model""todolist-cloudnative/internal/api/v1"
)func main() {// 加载配置cfg, err := config.Load()if err != nil {log.Fatalf("加载配置失败: %v", err)}// 连接数据库db, err := sqlx.Connect("postgres","host="+cfg.PostgresHost+" port="+strconv.Itoa(cfg.PostgresPort)+" dbname="+cfg.PostgresDB+" user="+cfg.PostgresUser+" password="+cfg.PostgresPass+" sslmode=disable")if err != nil {log.Fatalf("数据库连接失败: %v", err)}defer db.Close()// 初始化模型todoModel := model.NewTodoModel(db)// 初始化 Gin 路由router := gin.Default()v1Group := router.Group("/api/v1"){todoHandler := v1.NewTodoHandler(cfg, todoModel)v1Group.POST("/todos", todoHandler.CreateTodo)// 注册其他接口...}// 暴露 Prometheus 指标router.GET("/metrics", gin.WrapH(promhttp.Handler()))// 启动服务srv := &http.Server{Addr:    ":" + cfg.ServerPort,Handler: router,}go func() {if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {log.Fatalf("服务启动失败: %v", err)}}()// 等待终止信号quit := make(chan os.Signal, 1)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)<-quit// 优雅关闭ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()if err := srv.Shutdown(ctx); err != nil {log.Fatal("服务优雅关闭失败:", err)}log.Println("服务已退出")
}

三、容器化(Docker)

docker/Dockerfile(多阶段构建,最小化镜像体积)
# 阶段 1:构建 Go 二进制文件
FROM golang:1.21-alpine AS builder
WORKDIR /app# 缓存依赖(仅当 go.mod 或 go.sum 变化时重新下载)
COPY go.mod go.sum ./
RUN go mod download# 复制代码并构建
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o todo-server ./cmd/server# 阶段 2:运行轻量级镜像
FROM alpine:3.19
WORKDIR /app# 安装必要工具(如 CA 证书)
RUN apk add --no-cache ca-certificates# 从构建阶段复制二进制文件
COPY --from=builder /app/todo-server .# 暴露端口
EXPOSE 8080# 启动命令
CMD ["./todo-server"]

四、Kubernetes 编排(云原生核心)

1. 配置管理(k8s/configmap.yamlk8s/secret.yaml

非敏感配置(ConfigMap,注入数据库名、端口等)

apiVersion: v1
kind: ConfigMap
metadata:name: todo-config
data:SERVER_PORT: "8080"POSTGRES_DB: "tododb"POSTGRES_HOST: "postgres-service"  # K8s Service 名称(服务发现)

敏感配置(Secret,注入数据库用户、密码,需 base64 编码)

# 生成 base64 编码(实际生产建议用 HashiCorp Vault 等工具)
echo -n "admin" | base64   # 用户名
echo -n "mypassword" | base64  # 密码
echo -n "5432" | base64    # 端口
apiVersion: v1
kind: Secret
metadata:name: todo-secret
type: Opaque
data:POSTGRES_USER: "YWRtaW4="       # "admin" 的 base64POSTGRES_PASSWORD: "bXlwYXNzd29yZA=="  # "mypassword" 的 base64POSTGRES_PORT: "NTQzNg=="       # "5432" 的 base64

在这里插入图片描述

2. PostgreSQL 部署(k8s/postgres-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: postgres
spec:serviceName: postgres-servicereplicas: 1  # 生产环境建议 3 副本 + 主从复制(如 Patroni)selector:matchLabels:app: postgrestemplate:metadata:labels:app: postgresspec:containers:- name: postgresimage: postgres:15-alpineenv:- name: POSTGRES_USERvalueFrom:secretKeyRef:name: todo-secretkey: POSTGRES_USER- name: POSTGRES_PASSWORDvalueFrom:secretKeyRef:name: todo-secretkey: POSTGRES_PASSWORD- name: POSTGRES_DBvalueFrom:configMapKeyRef:name: todo-configkey: POSTGRES_DBports:- containerPort: 5432volumeMounts:- name: postgres-datamountPath: /var/lib/postgresql/datavolumeClaimTemplates:  # 持久化存储(云原生存储卷,如 AWS EBS、阿里云盘)- metadata:name: postgres-dataspec:accessModes: [ "ReadWriteOnce" ]resources:requests:storage: 1Gi
3. Todo 服务部署(k8s/todo-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: todo-deployment
spec:replicas: 2  # 初始副本数(弹性扩缩容基础)selector:matchLabels:app: todotemplate:metadata:labels:app: todospec:containers:- name: todoimage: your-docker-username/todolist:v1  # 替换为实际镜像地址ports:- containerPort: 8080env:- name: SERVER_PORTvalueFrom:configMapKeyRef:name: todo-configkey: SERVER_PORT- name: POSTGRES_USERvalueFrom:secretKeyRef:name: todo-secretkey: POSTGRES_USER- name: POSTGRES_PASSWORDvalueFrom:secretKeyRef:name: todo-secretkey: POSTGRES_PASSWORD- name: POSTGRES_HOSTvalueFrom:configMapKeyRef:name: todo-configkey: POSTGRES_HOST- name: POSTGRES_PORTvalueFrom:secretKeyRef:name: todo-secretkey: POSTGRES_PORTlivenessProbe:  # 存活探针(自动重启异常实例)httpGet:path: /metrics  # 或自定义健康检查接口port: 8080initialDelaySeconds: 30periodSeconds: 10readinessProbe:  # 就绪探针(流量路由前检查)httpGet:path: /health  # 需在接口中实现健康检查port: 8080initialDelaySeconds: 5periodSeconds: 5resources:  # 资源限制(K8s 调度依据)requests:cpu: "100m"memory: "256Mi"limits:cpu: "500m"memory: "512Mi"
4. 服务暴露(k8s/todo-service.yamlk8s/todo-ingress.yaml

ClusterIP Service(内部访问)

apiVersion: v1
kind: Service
metadata:name: todo-service
spec:type: ClusterIPselector:app: todoports:- protocol: TCPport: 80targetPort: 8080

Ingress(外部访问,需安装 NGINX Ingress Controller)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: todo-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target: /
spec:rules:- http:paths:- path: /todospathType: Prefixbackend:service:name: todo-serviceport:number: 80

五、CI/CD 自动化(GitHub Actions)

.github/workflows/deploy.yml
name: Deploy to Kuberneteson:push:branches: [ "main" ]jobs:build-and-push:runs-on: ubuntu-lateststeps:- name: Checkout codeuses: actions/checkout@v4- name: Set up Go 1.21uses: actions/setup-go@v5with:go-version: '1.21'- name: Build with Gorun: go build -o todo-server ./cmd/server- name: Set up Docker Buildxuses: docker/setup-buildx-action@v3- name: Login to Docker Hubuses: docker/login-action@v3with:username: ${{ secrets.DOCKERHUB_USERNAME }}password: ${{ secrets.DOCKERHUB_TOKEN }}- name: Build and push Docker imageuses: docker/build-push-action@v5with:context: .file: docker/Dockerfilepush: truetags: your-docker-username/todolist:latest,your-docker-username/todolist:${{ github.sha }}deploy-to-k8s:needs: build-and-pushruns-on: ubuntu-lateststeps:- name: Checkout codeuses: actions/checkout@v4- name: Set up kubectluses: azure/setup-kubectl@v3with:version: 'v1.28.0'- name: Deploy to Kubernetes clusterrun: |# 替换镜像标签为最新提交 SHAsed -i "s|your-docker-username/todolist:v1|your-docker-username/todolist:${{ github.sha }}|g" k8s/todo-deployment.yaml# 应用 K8s 配置kubectl apply -f k8s/env:KUBECONFIG: ${{ secrets.KUBECONFIG }}  # 从 GitHub Secrets 读取集群配置

六、可观测性配置

1. Prometheus 监控(prometheus/todolist.yml
scrape_configs:- job_name: "todo_service"scrape_interval: 15smetrics_path: "/metrics"static_configs:- targets: ["todo-service:80"]  # K8s Service 域名(集群内部可解析)

在这里插入图片描述

2. 日志集成(Loki)
  • 在接口中添加日志记录(使用 zaplogrus 等结构化日志库)。
  • 部署 Promtail 收集 Pod 日志并发送到 Loki(需额外配置)。
    在这里插入图片描述
3. Grafana 仪表盘(示例查询)
  • 请求速率rate(todo_operations_total{operation="create"}[5m])
  • Pod 内存使用container_memory_usage_bytes{container="todo-server"}

在这里插入图片描述

七、云原生特性验证

1. 容器化
  • 本地构建镜像:docker build -t todolist:v1 -f docker/Dockerfile .
  • 运行测试:docker run -p 8080:8080 todolist:v1,访问 http://localhost:8080/api/v1/todos 验证接口。
2. Kubernetes 部署
  • 本地搭建 K8s 集群(Minikube 或 Kind):minikube start
  • 应用配置:kubectl apply -f k8s/
  • 查看状态:kubectl get pods,svc,ingress
3. 弹性扩缩容
  • 手动扩缩容:kubectl scale deployment/todo-deployment --replicas=3
  • 自动扩缩容(HPA):
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:name: todo-hpa
    spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: todo-deploymentminReplicas: 2maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 70  # CPU 使用率超 70% 自动扩容
    
4. 故障自愈
  • 手动删除 Pod:kubectl delete pod <pod-name>,观察 K8s 自动重建新 Pod(状态变为 Running)。
5. 持续交付
  • 推送代码到 GitHub main 分支,触发 GitHub Actions 自动构建、测试、部署。

八、总结

通过这个 TodoList Demo,你可以完整体验云原生应用的核心流程:

  1. 容器化:用 Docker 封装应用,确保环境一致性。
  2. Kubernetes 编排:通过 Deployment、Service 等资源实现自动化管理。
  3. CI/CD:GitHub Actions 实现代码提交到生产的全自动化。
  4. 可观测性:Prometheus + Grafana 监控性能,Loki 收集日志。
  5. 弹性扩缩容:HPA 根据负载自动调整资源,保障高可用。

后续可扩展方向:

  • 微服务拆分(如用户服务、待办服务),用 Istio 实现服务网格。
  • 引入数据库读写分离(主从复制)。
  • 添加认证鉴权(OAuth2、JWT)。
  • 使用 Helm 打包 K8s 配置,简化多环境部署。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机能看、投屏 / 车机不能看与反向链接验证类似吗?

有一定关联&#xff0c;但两者的技术逻辑并非完全等同 ——“手机能看、投屏 / 车机不能看” 的核心原因更复杂&#xff0c;反向链接验证是其中一种可能的限制手段&#xff0c;但不是唯一甚至不是最主要的手段。要理清这个问题&#xff0c;需要先拆解 “投屏 / 车机播放受限” …

25年9月通信基础知识补充1:NTN-TDL信道建模matlab代码(satellite-communications toolbox学习)

看文献过程中不断发现有太多不懂的基础知识&#xff0c;故长期更新这类blog不断补充在这过程中学到的知识。由于这些内容与我的研究方向并不一定强相关&#xff0c;故记录不会很深入请见谅。 【通信基础知识补充10】25年9月通信基础知识补充1&#xff1a;NTN-TDL信道建模matlab…

洛谷P3370 【模板】字符串哈希 (哈希表)详解

题目如下&#xff1a;&#xff08;注&#xff1a;解此题我只需左手一根指头&#xff0c;哈哈哈哈哈哈哈&#xff09;注意&#xff0c;哈希表的好处是能大幅度减少寻找遍历的时间可能有人不理解哈希值&#xff0c; 这里哈希的模的值一般得是比较大的质数&#xff0c;如标准的100…

光子芯片驱动的胰腺癌早期检测:基于光学子空间神经网络的高效分割方法(未做完)

光子芯片驱动的胰腺癌早期检测:基于光学子空间神经网络的高效分割方法 1 论文核心概念 本文提出了一种基于集成光子芯片的光学子空间神经网络(Optical Subspace Neural Network, OSNN),用于胰腺癌的早期检测与图像分割。其核心思想是利用光子芯片的高并行性、低延迟和低能…

GraphRAG 工作原理逐步解析:从图创建到搜索的实战示例

本篇文章How GraphRAG Works Step-By-Step: From Graph Creation to Search with Real Examples | Towards AI详细介绍了GraphRAG的工作原理&#xff0c;适合对检索增强生成&#xff08;RAG&#xff09;和知识图谱感兴趣的读者。文章的技术亮点在于通过图结构提升信息检索效率&…

LAMPSecurity: CTF8靶场渗透

LAMPSecurity: CTF8 来自 <https://www.vulnhub.com/entry/lampsecurity-ctf8,87/> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.128&#xff0c;靶场IP192.168…

绿算技术闪耀智博会 赋能乡村振兴与产业升级

9月5日至7日&#xff0c;由宁波市人民政府、浙江省经济和信息化厅、中国信息通信研究院联合主办的第十五届智慧城市与智能经济博览会在宁波国际会展中心圆满落幕。绿算技术受邀参展&#xff0c;并发布与北京东方联鸣科技发展有限公司联合打造的《360数智牧业AI模型支撑底座》&a…

浅谈“SVMSPro视频切片”技术应用场景

技术定义视频切片是一项将连续不断的视频流&#xff0c;按特定规则&#xff08;如时间点、事件触发&#xff09;切割成一个个独立、完整的MP4等标准视频文件的技术。这些切片文件体积小、格式通用&#xff0c;易于管理、传输和播放。核心价值精准存档&#xff1a;从海量录像中精…

php 使用html 生成pdf word wkhtmltopdf 系列1

php 使用html 生成pdf word wkhtmltopdf 系列2 php 使用html 生成 pdf word 项目有个需求 想同时生成word 和pdf 并且对pdf要求比较高 为了一劳永逸 决定写成html 分别转成word 和pdf 系统环境 windows10 小皮面板&#xff08;php8&#xff09; linux centos 7.9 宝塔&…

Git常用命令大全:高效开发必备

目录 常用Git命令清单 1. 新建代码库 2. 配置 3. 增加/删除文件 4. 代码提交 5. 分支 6. 标签 7. 查看信息 8. 远程同步 9. 撤销 10. 常用操作组合 修改本地分支名和远程分支名 附录&#xff1a;Git命令思维导图 安装gitlab 常用Git命令清单 一般来说&#xff0…

AJAX入门-URL

本系列可作为前端学习系列的笔记&#xff0c;代码的运行环境是在VS code中&#xff0c;小编会将代码复制下来&#xff0c;大家复制下来就可以练习了&#xff0c;方便大家学习。 HTML、CSS、JavaScript系列文章 已经收录在前端专栏&#xff0c;有需要的宝宝们可以点击前端专栏查…

【深度学习新浪潮】什么是具身智能?

具身智能(Embodied AI)是人工智能与机器人技术深度融合的前沿领域,其核心是通过物理实体与环境的实时交互闭环,实现感知-认知-决策-行动的一体化自主进化。这类系统不仅能理解语言指令,更能通过高精度传感器(如触觉、视觉、力觉融合)感知物理世界,依托多模态大模型完成…

动画蓝图与动画状态机:从 Unity Mecanim 到 Unreal Animation Blueprint 的一把梭

动画蓝图与动画状态机&#xff1a;从 Unity Mecanim 到 Unreal Animation Blueprint 的一把梭这篇是系列的第一篇。目标很简单&#xff1a;把 Unreal 的 Animation Blueprint 和 Unity 的 Animator Controller&#xff08;Mecanim&#xff09; 放在同一张桌子上&#xff0c;系统…

实战案例:数字孪生+可视化大屏,如何高效管理智慧能源园区?

摘要&#xff1a; 当智慧遇上能源&#xff0c;一场管理革命正在悄然发生。想象一下&#xff1a;一个占地千亩的能源园区&#xff0c;光伏板、储能站、风力机组星罗棋布&#xff0c;传统管理模式下&#xff0c;数据分散、响应滞后、故障频发... 但某园区引入“数字孪生可视化大屏…

Django 从环境搭建到第一个项目

作为一名刚接触 Django 的开发者&#xff0c;我在学习过程中整理了这份入门笔记&#xff0c;涵盖 Django 框架基础、环境搭建、第一个项目创建以及核心配置&#xff0c;希望能为同样刚入门的小伙伴提供清晰的学习思路。 一、Django 框架基础认知 在开始实际操作前&#xff0c…

机器学习实操项目02——Pandas入门(基本操作、创建对象、查看数据、数据选择、处理缺失数据、数据合并、数据分组、时间序列、绘图、文件导出)

上一章&#xff1a;机器学习实操项目01——Numpy入门&#xff08;基本操作、数组形状操作、复制与试图、多种索引技巧、线性代数&#xff09; 下一章&#xff1a; 机器学习核心知识点目录&#xff1a;机器学习核心知识点目录 机器学习实战项目目录&#xff1a;【从 0 到 1 落地…

springboot超市货品信息管理系统

开发环境开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Mave…

c# .net中using的使用

using示例代码 示例代码1&#xff1a; using HttpContent httpContent new StringContent(postData, Encoding.UTF8);示例代码2&#xff1a; using (var process Process.Start(info)) {output process.StandardOutput.ReadToEnd(); }示例代码1写法&#xff1a; using HttpC…

STM32HAL 快速入门(二十):UART 中断改进 —— 环形缓冲区解决数据丢失

前言 大家好&#xff0c;这里是 Hello_Embed。上一篇我们用中断方式实现了 UART 收发&#xff0c;但发现一个关键问题&#xff1a;若 CPU 在处理其他任务时未及时重新使能接收中断&#xff0c;新数据会覆盖旧数据&#xff0c;导致丢失。本篇的核心改进方案是 ——“中断接收 环…

使用Docker搭建MaxKB智能体平台

1、系统要求 详见&#xff1a; https://maxkb.cn/docs/v2/quick_start https://maxkb.cn/docs/v2/installation/offline_installtion https://maxkb.cn/docs/v2/installation/online_installtion 2、安装Docker 合集&#xff1a;Docker安装与使用 3、安装MaxKB 详见&#xf…