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

Go后端架构探索:从 MVC 到 DDD 的演进之路

Go语言 MVC 与 DDD 分层架构详细对比

MVCDDD是后台开发两种流行的分层架构思想,MVC(Model-View-Controller)是一种设计模式,主要用于分离用户界面、业务逻辑和数据模型,便于分层解耦,而DDD(领域驱动设计)则是一种架构方法论,旨在通过构建业务领域模型来解决复杂系统中的设计和维护难题。

在Java领域,很多系统逐渐由MVC逐渐转为DDD,但在Go、Python、NodeJS等语言,秉持简单高效的理念,MVC依然是主流架构。下面基于Go语言来具体探讨下MVCDDD两种目录结构的区别。

MVC 图形结构

+------------------+
|      View        | 用户界面层:负责数据展示和用户交互(如HTML页面、API响应)
+------------------+
|   Controller     | 控制层:处理用户请求,调用Service逻辑,协调Model与View
+------------------+
|      Model       | 模型层:包含数据对象(如数据库表结构)和部分业务逻辑(常分散在Service层)
+------------------+

DDD 图形结构

+--------------------+
|   用户界面层(UI)    | 负责用户交互和展示(如REST API、Web界面)
+--------------------+
| 应用层(Application)| 编排业务流程(如调用领域服务、事务管理),不包含核心业务规则
+--------------------+
|  领域层(Domain)    | 核心业务逻辑层:包含聚合根、实体、值对象、领域服务等,内聚业务规则
+--------------------+
|      基础设施层      | 提供技术实现(如数据库访问、消息队列、外部API)
|  (Infrastructure) | 
+--------------------+

MVCDDD 的主要区别:

1. 代码组织逻辑
MVC 按技术功能分层(Controller/Service/DAO),关注技术实现;DDD 按业务领域划分模块(如订单域、支付域),以限界上下文隔离核心业务逻辑。

2. 业务逻辑载体
MVC 通常采用贫血模型,数据(Model)与行为(Service)分离,逻辑分散导致维护成本高;DDD 通过聚合根、领域服务实现充血模型,业务逻辑内聚于领域层,增强可扩展性。

3. 适用性与成本
MVC 开发成本低,适合需求稳定的中小型系统;DDD 需前期领域建模和统一语言,适用于业务复杂、需长期演进的大型系统,但团队需具备领域抽象能力。例如,电商促销规则用 DDD 可避免逻辑散落在多个 Service 中。


Go语言 MVC 目录结构

MVC主要分为三层:视图、控制器、模型。

gin-order/
├── cmd
│   └── main.go                  # 应用入口,启动 Gin 引擎
├── internal
│   ├── controllers              # 控制器层(处理 HTTP 请求),也可以叫handlers
│   │   └── order
│   │       └── order_controller.go  # Order 模块的控制器
│   ├── services                 # 服务层(业务逻辑处理)
│   │   └── order
│   │       └── order_service.go       # Order 模块的服务实现
│   ├── repository               # 数据访问层(与数据库交互)
│   │   └── order
│   │       └── order_repository.go    # Order 模块的数据访问接口及实现
│   ├── models                   # 模型层(数据结构定义)
│   │   └── order
│   │       └── order.go               # Order 模块的数据模型
│   ├── middleware               # 中间件(如鉴权、日志、请求拦截)
│   │   ├── logging.go             # 日志中间件
│   │   └── auth.go                # 鉴权中间件
│   └── config                   # 配置模块(数据库、服务器等配置)
│       └── config.go                # 应用与环境配置
├── pkg                          # 公共工具包(如响应包装工具)
│   └── response.go              # 响应处理工具方法
├── web                          # 前端资源(模板与静态资源)
│   ├── static                   # 静态资源(CSS、JS、图片)
│   └── templates                # 模板文件(HTML模板)
│       └── order.tmpl           # Order 模块的视图模板(如果需要渲染HTML)
├── go.mod                       # Go 模块管理文件
└── go.sum                       # Go 模块依赖版本锁定

Go语言 DDD 目录结构

DD主要分为四层:界面、应用、领域、基础。

go-web/
│── cmd/
│   └── main.go               # 应用入口
│── internal/
│   ├── application/          # 应用层(协调领域逻辑,处理业务用例)
│   │   ├── services/         # 服务层,业务逻辑目录
│   │   │   └── order_service.go # 订单应用服务,调用领域层业务逻辑
│   ├── domain/               # 领域层(核心业务逻辑和接口定义)
│   │   ├── order/            # 订单聚合
│   │   │   ├── order.go      # 订单实体(聚合根),包含核心业务逻辑
│   │   ├── repository/       # 通用仓库接口
│   │   │   ├── repository.go # 通用仓库接口(通用 CRUD 操作)
│   │   │   └── order_repository.go # 订单仓储接口,定义对订单数据的操作
│   ├── infrastructure/       # 基础设施层(实现领域层定义的接口)
│   │   ├── repository/       # 仓储实现
│   │   │   └── order_repository_impl.go  # 订单仓储实现,具体的订单数据存储
│   └── interfaces/           # 接口层(处理外部请求,如HTTP接口)
│   │   ├── handlers/         # HTTP 处理器
│   │   │  └── order_handler.go # 订单相关的HTTP处理器
│   │   └── routes/
│   │   │   ├── router.go     # 基础路由工具设置
│   │   │   └── order-routes.go # 订单路由地址配置
│   │   │   └── order-routes-test.go # 订单路由测试
│   └── middleware/           # 中间件(例如:鉴权、拦截、认证等)
│   │   └── logging.go        # 日志中间件
│   ├── config/               # 服务相关配置
│   │   └── server_config.go  # 服务器配置(如端口、超时设置等)
│── pkg/                      # 可复用的公共库
│   └── utils/                # 工具类(例如:日志、日期处理等)

Go语言 MVC 代码实现

源码:https://github.com/microwind/design-patterns/tree/main/mvx/mvc/gin-mvc

Controller(接口层) → Service(业务逻辑层) → Repository(数据访问层) → Model(数据模型)

分层代码

  • 控制器层(Controller)
// internal/controller/order/order.go
package orderimport ("net/http""strconv""github.com/gin-gonic/gin""github.com/gin-order/internal/model""github.com/gin-order/internal/service/order""github.com/gin-order/internal/pkg/response"
)type OrderController struct {service *order.OrderService
}func NewOrderController(service *order.OrderService) *OrderController {return &OrderController{service: service}
}func (c *OrderController) GetOrder(ctx *gin.Context) {idStr := ctx.Param("id")id, _ := strconv.ParseUint(idStr, 10, 64)order, err := c.service.GetOrderByID(uint(id))if err != nil {response.Error(ctx, http.StatusNotFound, "Order not found")return}response.Success(ctx, order)
}func (c *OrderController) CreateOrder(ctx *gin.Context) {var req model.Orderif err := ctx.ShouldBindJSON(&req); err != nil {response.Error(ctx, http.StatusBadRequest, "Invalid request")return}if err := c.service.CreateOrder(&req); err != nil {response.Error(ctx, http.StatusInternalServerError, "Create failed")return}response.Success(ctx, req)
}
  • 路由配置
// cmd/server/main.go
package mainimport ("github.com/gin-gonic/gin""github.com/gin-order/internal/controller/order""github.com/gin-order/internal/pkg/database""github.com/gin-order/internal/repository/order""github.com/gin-order/internal/service/order"
)func main() {// 初始化数据库db := database.NewGORM()// 依赖注入orderRepo := order_repo.NewMySQLOrderRepository(db)orderService := order_service.NewOrderService(orderRepo)orderController := order_controller.NewOrderController(orderService)// 创建路由r := gin.Default()// 注册中间件r.Use(middleware.Logger())// 路由分组apiGroup := r.Group("/api"){orderGroup := apiGroup.Group("/orders"){orderGroup.GET("/:id", orderController.GetOrder)orderGroup.POST("", orderController.CreateOrder)}}// 启动服务r.Run(":8080")
}
  • 服务层(Service)
// internal/service/order/service.go
package orderimport ("github.com/gin-order/internal/model""github.com/gin-order/internal/repository/order"
)type OrderService struct {repo order.OrderRepository
}func NewOrderService(repo order.OrderRepository) *OrderService {return &OrderService{repo: repo}
}func (s *OrderService) GetOrderByID(id uint) (*model.Order, error) {return s.repo.FindByID(id)
}func (s *OrderService) CreateOrder(order *model.Order) error {return s.repo.Create(order)
}
  • 数据访问层(Repository)
// internal/repository/order/interface.go
package orderimport "github.com/gin-order/internal/model"type OrderRepository interface {FindByID(id uint) (*model.Order, error)Create(order *model.Order) errorFindByStatus(status string) ([]model.Order, error)
}
// internal/repository/order/mysql.go
package orderimport ("gorm.io/gorm""github.com/gin-order/internal/model"
)type MySQLOrderRepository struct {db *gorm.DB
}func NewMySQLOrderRepository(db *gorm.DB) OrderRepository {return &MySQLOrderRepository{db: db}
}func (r *MySQLOrderRepository) FindByID(id uint) (*model.Order, error) {var order model.Orderif err := r.db.First(&order, id).Error; err != nil {return nil, err}return &order, nil
}func (r *MySQLOrderRepository) Create(order *model.Order) error {return r.db.Create(order).Error
}func (r *MySQLOrderRepository) FindByStatus(status string) ([]model.Order, error) {var orders []model.Orderif err := r.db.Where("status = ?", status).Find(&orders).Error; err != nil {return nil, err}return orders, nil
}
  • 模型层(Model)
// internal/model/order.go
package modelimport "time"type Order struct {OrderID     uint      `gorm:"primaryKey;column:order_id"`OrderNo     string    `gorm:"uniqueIndex;column:order_no"`UserID      uint      `gorm:"index;column:user_id"`OrderName   string    `gorm:"column:order_name"`Amount      float64   `gorm:"type:decimal(10,2);column:amount"`Status      string    `gorm:"column:status"`CreatedAt   time.Time `gorm:"column:created_at"`UpdatedAt   time.Time `gorm:"column:updated_at"`
}func (Order) TableName() string {return "orders"
}

Go语言 MVC 最佳实践

接口隔离原则

Repository 层通过接口定义,支持多种数据库实现

// 可轻松切换为 Mock 实现
type MockOrderRepository struct {}
func (m *MockOrderRepository) FindByID(id uint) (*model.Order, error) {return &model.Order{OrderNo: "mock-123"}, nil
}

统一响应格式

// pkg/response/response.go
func Success(c *gin.Context, data interface{}) {c.JSON(http.StatusOK, gin.H{"code":    0,"message": "success","data":    data,})
}

中间件链

// 全局中间件
r.Use(gin.Logger(), gin.Recovery())// 路由组中间件
adminGroup := r.Group("/admin", middleware.AuthJWT())

数据库迁移

使用 GORM AutoMigrate:

db.AutoMigrate(&model.Order{})

Go语言 DDD 代码实现与最佳实践

源码:https://github.com/microwind/design-patterns/tree/main/domain-driven-design/go-web

1. 关注领域模型

DDD 强调领域模型的构建,使用 聚合(Aggregate)实体(Entity)值对象(Value Object) 组织业务逻辑。

在 Go 语言中,通常使用 struct 定义实体和值对象:

// 实体(Entity)
type User struct {ID   intName string
}

2. 分层架构

DDD 通常采用 分层架构,Go 语言项目可以遵循如下结构:

  • 领域层(Domain Layer):核心业务逻辑,如 domain 目录下的实体和聚合。
  • 应用层(Application Layer):用例(Use Cases)和业务流程编排。
  • 基础设施层(Infrastructure Layer):数据库、缓存、外部 API 适配等。
  • 接口层(Interface Layer):提供 HTTP、gRPC 或 CLI 接口。

3. 依赖倒置(Dependency Inversion)

领域层不应直接依赖基础设施,而是通过 接口(Interface) 进行依赖倒置。

注:DDD架构核心就是依赖倒置(DIP),Domain是最核心的内层,仅定义业务规则和接口抽象,其他层级依赖Domain实现,Domain不依赖任何外部实现。在六边形架构(Hexagonal Architecture)中,领域层位于核心,其他层级(如应用层、基础设施层)通过实现领域层定义的接口来提供具体技术细节(如数据库操作、API 调用),从而达成领域与技术实现的解耦。

// 领域层:定义接口
type UserRepository interface {GetByID(id int) (*User, error)
}
// 基础设施层:数据库实现
type userRepositoryImpl struct {db *sql.DB
}func (r *userRepositoryImpl) GetByID(id int) (*User, error) {// 数据库查询逻辑
}

4. 聚合(Aggregate)管理

聚合根(Aggregate Root)管理整个聚合的生命周期:

type Order struct {ID      intItems   []OrderItemStatus  string
}func (o *Order) AddItem(item OrderItem) {o.Items = append(o.Items, item)
}

5. 应用服务(Application Service)

应用服务封装领域逻辑,避免外部直接操作领域对象:

type OrderService struct {repo OrderRepository
}func (s *OrderService) CreateOrder(userID int, items []OrderItem) (*Order, error) {order := Order{UserID: userID, Items: items, Status: "Pending"}return s.repo.Save(order)
}

6. 事件驱动(Event-Driven)

使用 领域事件(Domain Events) 进行解耦,在 Go 语言中可通过 ChannelPub/Sub 实现:

type OrderCreatedEvent struct {OrderID int
}def publishEvent(event OrderCreatedEvent) {go func() {eventChannel <- event}()
}

7. 结合 CQRS(命令查询职责分离)

DDD 可结合 CQRS(Command Query Responsibility Segregation),在 Go 语言中可用 命令(Command) 处理变更操作,用 查询(Query) 处理数据读取:

type CreateOrderCommand struct {UserID intItems  []OrderItem
}func (h *OrderHandler) Handle(cmd CreateOrderCommand) (*Order, error) {return h.service.CreateOrder(cmd.UserID, cmd.Items)
}

MVC与DDD架构总结

1. 架构核心区别

维度MVC 架构DDD 架构
层级三层:Controller/Service/DAO四层:接口层/应用层/领域层/基础设施层
职责- Controller 处理请求,Service 承载逻辑
- DAO 直接操作数据库
- 应用层编排流程(如调用领域服务)
- 领域层内聚业务原子操作(如订单创建规则)
- 基础设施层实现技术细节(如数据库访问)
痛点Service 层臃肿,业务逻辑与数据操作耦合领域层独立于技术实现,逻辑与层级强对应

2. 模块化与扩展性

MVC

  • 高耦合:缺乏明确的业务边界,跨模块调用(如订单服务直接依赖账户表)导致代码难以维护。
  • 扩展性差:新增功能需全局修改(如添加风控规则需侵入订单服务),易引发连锁问题。

DDD

  • 限界上下文:按业务能力划分模块(如支付域、风控域),通过事件驱动(如订单支付完成事件)解耦协作。
  • 独立演进:各领域模块可独立升级(如支付逻辑优化不影响订单服务),降低系统级风险。

3. 适用场景区别

  • 中小系统优先 MVC:业务简单(如博客、CMS、管理后台),需快速开发且业务规则清晰,无后续反复变更。
  • 复杂业务转向 DDD:规则密集(如金融交易、供应链)、多领域协作(如电商订单与库存联动),后续变更频繁。

更多架构设计源码

  • https://github.com/microwind/design-patterns
  • https://github.com/microwind/algorithms

相关文章:

Go后端架构探索:从 MVC 到 DDD 的演进之路

Go语言 MVC 与 DDD 分层架构详细对比 MVC和DDD是后台开发两种流行的分层架构思想&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;是一种设计模式&#xff0c;主要用于分离用户界面、业务逻辑和数据模型&#xff0c;便于分层解耦&#xff0c;而DDD&#xff08;领…...

【力扣hot100题】(017)矩阵置零

还是挺简单的&#xff0c;使用哈希表记录需要置换的行列即可&#xff0c;这样就可以避免重复节省时间。 class Solution { public:void setZeroes(vector<vector<int>>& matrix) {unordered_set<int> row;unordered_set<int> line;for(int i0;i&l…...

One Commander 3,文件管理新体验

One Commander 3 是一款集多功能于一体 Windows 10/11的文件管理工具&#xff0c;其设计目的在于为用户带来多元化的操作体验。这款工具通过支持多栏界面布局&#xff0c;让用户能够迅速且高效地组织和管理文件。此外&#xff0c;它还提供了多主题选项和多种图标集&#xff0c;…...

Ubuntu 下 nginx-1.24.0 源码分析

main 函数在 src\core\nginx.c int ngx_cdecl main(int argc, char *const *argv) {ngx_buf_t *b;ngx_log_t *log;ngx_uint_t i;ngx_cycle_t *cycle, init_cycle;ngx_conf_dump_t *cd;ngx_core_conf_t *ccf;ngx_debug_init();if (ngx_strerror_in…...

c# ftp上传下载 帮助类

工作中FTP的上传和下载还是很常用的。如下载打标数据,上传打标结果等。 这个类常用方法都有了:上传,下载,判断文件夹是否存在,创建文件夹,获取当前目录下文件列表(不包括文件夹) ,获取当前目录下文件列表(不包括文件夹) ,获取FTP文件列表(包括文件夹), 获取当前目…...

Java进阶——静态代理与动态代理

代理模式是一种常用的设计模式&#xff0c;为其他对象提供一种代理以控制对这个对象的访问。代理模式就像是一个中间人&#xff0c;客户端通过代理来间接访问目标对象&#xff0c;可以在不修改目标对象的基础上&#xff0c;对目标对象的功能进行增强或扩展。代理模式主要分为静…...

VS Code 中 .history`文件的来源与 .gitignore`的正确使用

引言 在使用 VS Code 进行 Git 版本控制时&#xff0c;有时会发现项目中多出一个 .history 目录&#xff0c;并被 Git 识别为未跟踪文件。本文将解释 .history 的来源&#xff0c;并提供 .gitignore 的正确配置方法&#xff0c;确保开发环境的整洁性。 1. .history 文件的来源…...

非手性分子发光有妙招:借液晶之力,实现高不对称圆偏振发光

*本文只做阅读笔记分享* 一、圆偏振发光研究背景与挑战 圆偏振发光&#xff08;CPL&#xff09;材料在3D显示、光电器件等领域大有用处&#xff0c;衡量它的一个重要指标是不对称发光因子&#xff08;glum&#xff09;。早期CPL材料的glum值低&#xff0c;限制了实际应用。为…...

解释器模式_行为型_GOF23

解释器模式 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;核心思想是定义语言的文法规则&#xff0c;并构建一个解释器来解析和执行该语言中的表达式。它类似于“翻译器”——将符合特定语法规则的文本&#xff08;如数学公式、脚本…...

OTN(Optical Transport Network)详解

OTN&#xff08;光传送网&#xff09;是一种基于**波分复用&#xff08;WDM&#xff09;**的大容量光传输技术&#xff0c;结合了SDH的运维管理优势和WDM的高带宽特性&#xff0c;广泛应用于骨干网、城域核心层及数据中心互联&#xff08;DCI&#xff09;。 1. OTN 的基本概念 …...

YOLOv8+ Deepsort+Pyqt5车速检测系统

该系统通过YOLOv8进行高效的目标检测与分割&#xff0c;结合DeepSORT算法完成目标的实时跟踪&#xff0c;并利用GPU加速技术提升处理速度。系统支持模块化设计&#xff0c;可导入其他权重文件以适应不同场景需求&#xff0c;同时提供自定义配置选项&#xff0c;如显示标签和保存…...

【干货】前端实现文件保存总结

⚠️⚠️文前推荐一下&#x1f449; 前端必备工具推荐网站(图床、API和ChatAI、智能AI简历、AI思维导图神器等实用工具): 站点入口&#xff1a;http://luckycola.com.cn/ 前端实现文件保存实现总结 在Web开发中&#xff0c;文件下载是常见的交互需求。本文将系统总结前端实现文…...

并发编程之FutureTask.get()阻塞陷阱:深度解析线程池CPU飚高问题排查与解决方案

FutureTask.get方法阻塞陷阱&#xff1a;深度解析线程池CPU飚高问题排查与解决方法 FutureTask.get()方法阻塞陷阱&#xff1a;深度解析线程池CPU飚高问题排查与解决方法1、情景复现1.1 线程池工作原理1.2 业务场景模拟1.3 运行结果1.4 发现问题&#xff1a;线程池没有被关闭1.…...

DGNN-YOLO:面向遮挡小目标的动态图神经网络检测与追踪方法解析

一、算法结构与核心贡献 1.1 文章结构 采用经典五段式结构: ​引言:分析智能交通系统(ITS)中小目标检测与追踪的挑战,提出研究动机。​相关工作:综述小目标检测(YOLO系列、Faster R-CNN)、目标追踪(SORT、Transformer)和图神经网络(GNN)的进展。​方法论:提出DG…...

在Ubuntu中固定USB设备的串口号

获取设备信息 lsusb # 记录设备的Vendor ID和Product ID&#xff08;例如&#xff1a;ID 0403:6001&#xff09;# 获取详细属性&#xff08;替换X和Y为实际设备号&#xff09; udevadm info -a /dev/ttyUSBX 结果一般如下 创建udev规则文件 sudo gedit /etc/udev/rules.d/us…...

javaSE————文件IO(2)、

文件内容的读写——数据流 我们对于文件操作使用流对象Stream来操作&#xff0c;什么是流对象呢&#xff0c;水流是什么样的&#xff0c;想象一下&#xff0c;水流的流量是多种的&#xff0c;可以流100ml&#xff0c;也可以流1ml&#xff0c;流对象就和水流很像&#xff0c;我…...

前端常问的宏观“大”问题详解(二)

JS与TS选型 一、为什么选择 TypeScript 而不是 JavaScript&#xff1f; 1. 静态类型系统&#xff1a;核心优势 TypeScript 的静态类型检查能在 编译阶段 捕获类型错误&#xff08;如变量类型不匹配、未定义属性等&#xff09;&#xff0c;显著减少运行时错误风险。例如&…...

[创业之路-343]:创业:一场认知重构与组织进化的双向奔赴

目录 前言&#xff1a;关键词&#xff1a; 一、重构企业认知框架&#xff1a; 1、认知框架的顶层设计——六大维度生态模型 2、认知重构的精密设计——五层结构化模型 第一层&#xff1a;战略层&#xff08;脑&#xff09; 第二层&#xff1a;运营层&#xff08;躯干&…...

智慧电力:点亮未来能源世界的钥匙

在科技日新月异的今天&#xff0c;电力行业正经历着前所未有的变革。智慧电力&#xff0c;作为这一变革的核心驱动力&#xff0c;正逐步改变着我们对电力的认知和使用方式。它不仅是电力行业的一次技术革新&#xff0c;更是推动社会可持续发展、实现能源高效利用的重要途径。 智…...

架构师面试(二十三):负载均衡

问题 今天我们聊微服务相关的话题。 大中型微服务系统中&#xff0c;【负载均衡】是一个非常核心的组件&#xff1b;在微服务系统的不同位置对【负载均衡】进行了实现&#xff0c;下面说法正确的有哪几项&#xff1f; A. LVS 的负载均衡一般通过前置 F5 或是通过 VIP keepa…...

CSS3学习教程,从入门到精通, CSS3 列表控制详解语法知识点及案例代码(24)

CSS3 列表控制详解 CSS 列表控制的语法知识点及案例代码的详细说明&#xff0c;包括 list-style-type、list-style-image、list-style-position 和 list-style 的用法。 1. list-style-type 属性 list-style-type 属性用于设置列表项标记的类型。 语法 list-style-type: v…...

NSSCTF(MISC)—[justCTF 2020]pdf

相应的做题地址&#xff1a;https://www.nssctf.cn/problem/920 binwalk分离 解压文件2AE59A.zip mutool 得到一张图片 B5F31内容 B5FFD内容 转换成图片 justCTF{BytesAreNotRealWakeUpSheeple}...

坚持“大客户战略”,昂瑞微深耕全球射频市场

北京昂瑞微电子技术股份有限公司&#xff08;简称“昂瑞微”&#xff09;是一家聚焦射频与模拟芯片设计的高新技术企业。随着5G时代的全面到来&#xff0c;智能手机、智能汽车等终端设备对射频前端器件在通信频率、多频段支持、信道带宽及载波聚合等方面提出了更高需求&#xf…...

LiteDB 数据库优缺点分析与C#代码示例

LiteDB 是一个轻量级的 .NET NoSQL 嵌入式数据库,完全用 C# 开发,支持跨平台(Windows、Linux、MacOS),并提供类似于 MongoDB 的简单 API。它以单文件形式存储数据,类似于 SQLite,支持事务和 ACID 特性,确保数据的一致性和可靠性。 优缺点分析 优点: 轻量级与嵌入式:…...

上海SMT贴片技术解析与行业趋势

内容概要 随着长三角地区电子制造产业集群的快速发展&#xff0c;上海作为核心城市正引领着SMT贴片技术的革新浪潮。本文聚焦表面组装技术在高密度互连、微间距贴装等领域的突破性进展&#xff0c;通过解析焊膏印刷精度控制、元件定位算法优化等核心工艺&#xff0c;展现上海企…...

HTML5和CSS3的一些特性

HTML5 和 CSS3 是现代网页设计的基础技术&#xff0c;它们引入了许多新特性和功能&#xff0c;极大地丰富了网页的表现力和交互能力。 HTML5 的一些重要特性包括&#xff1a; 新的语义化标签: HTML5 引入了一些重要的语义化标签如 <header>, <footer>, <articl…...

Linux系统中快速安装docker

1 查看是否安装docker 要检查Ubuntu是否安装了Docker&#xff0c;可以使用以下几种方法&#xff1a; 方法1&#xff1a;使用 docker --version 命令 docker --version如果Docker已安装&#xff0c;输出会显示Docker的版本信息&#xff0c;例如&#xff1a; Docker version …...

每日c/c++题 备战蓝桥杯(最长上升子序列)

点击题目链接 题目描述 给出一个由 n(n≤5000) 个不超过 1e6 的正整数组成的序列。请输出这个序列的最长上升子序列的长度。 最长上升子序列是指&#xff0c;从原序列中按顺序取出一些数字排在一起&#xff0c;这些数字是逐渐增大的。 输入格式 第一行&#xff0c;一个整数…...

蓝桥杯—质数

质数 质数是一个只有1和它本身2个因数 代码实现 //求质数 #include<bits/stdc.h> using namespace std; bool zhishu(int n) {if(n1){cout<<"1不是质数";return false;}else if(n>1){for(int i2;i<sqrt(n);i){if(n%i0){cout<<n<<&q…...

CP15 协处理器

ARMv7-A 一共支持 16 个协处理器&#xff0c;编号从 CP0~CP15。这里仅对CP15进行描述。 1、ARMv7-A 协处理器 ARMv7-A 处理器除了标准的 R0~R15&#xff0c;CPSR&#xff0c;SPSR 以外&#xff0c;由于引入了 MMU、TLB、Cache 等内容&#xff0c;ARMv7-A 使用协处理器来对这些…...