展开全部 ↓

Go语言GORM的介绍和常见用法

GORM 是 Go 语言里常用的 ORM 框架,可以把数据库表映射成 Go 结构体,让我们用面向对象的方式操作 MySQL、PostgreSQL、SQLite 等数据库。 什么是 GORM ORM 的全称是 Object Relational Mapping,也就是对象关系映射。 在 Go 项目里,如果不用 ORM,通常需要手写 SQL: 1 rows, err := db.Query("select id, name, age from users where id = ?", id) 使用 GORM 后,可以用结构体和方法调用来操作数据库: 1 2 var user User db.First(&user, id) GORM 会根据结构体、字段、方法调用生成对应 SQL。 GORM 常见特点: 支持 MySQL、PostgreSQL、SQLite、SQL Server 等数据库。 支持结构体和表的自动映射。 支持增删改查、事务、关联关系、预加载。 支持自动迁移表结构。 支持 Hook、软删除、日志、连接池等功能。 安装 GORM 以 MySQL 为例: 1 2 go get gorm.io/gorm go get gorm.io/driver/mysql 如果使用 SQLite: ...

April 22, 2026 · 5 min

Go语言Reflect包的使用

reflect 是 Go 标准库里的反射包,可以在运行时查看变量的类型和值,也可以动态读取和修改对象。它常用于 JSON 序列化、ORM、配置解析、参数校验、依赖注入等框架代码中。 什么是反射 正常写 Go 代码时,变量类型在编译期就已经确定: 1 2 name := "Tom" age := 18 编译器知道 name 是 string,age 是 int,所以可以做类型检查。 反射解决的是另一个问题:如果代码在编译期不知道具体类型,运行时才拿到一个 interface{} 或 any,还能不能知道它到底是什么类型、有什么字段、能不能调用方法? 答案就是使用 reflect。 简单来说: 1 2 普通代码:编译期知道类型 反射代码:运行时检查类型和值 reflect 的两个核心类型 reflect 包最重要的是两个类型: reflect.Type:表示变量的类型信息。 reflect.Value:表示变量的值信息。 获取方式: 1 2 reflect.TypeOf(x) reflect.ValueOf(x) 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package main import ( "fmt" "reflect" ) func main() { var age int = 18 t := reflect.TypeOf(age) v := reflect.ValueOf(age) fmt.Println(t) // int fmt.Println(v) // 18 fmt.Println(t.Kind()) // int fmt.Println(v.Kind()) // int } Type 更关注“它是什么类型”,Value 更关注“它的值是什么”。 ...

April 22, 2026 · 4 min

Go语言Map的使用和底层原理

map 是 Go 语言内置的哈希表,用来保存键值对。它查询、插入、删除都很方便,平均时间复杂度接近 O(1),但普通 map 不是并发安全的。 什么是 map map 是一种键值对集合: key:用来查找数据的键,必须是可比较类型,比如 string、int、bool、指针、数组、结构体等。 value:键对应的值,可以是任意类型。 常见定义方式: 1 2 3 4 5 6 7 8 9 10 11 // 声明但未初始化,值为 nil,不能直接写入 var m map[string]int // 使用 make 初始化 scores := make(map[string]int) // 字面量初始化 ages := map[string]int{ "Tom": 18, "Jack": 20, } 需要注意,nil map 可以读取,但不能写入: 1 2 3 4 5 6 var m map[string]int fmt.Println(m["Tom"]) // 0 // panic: assignment to entry in nil map m["Tom"] = 18 所以实际使用时,一般用 make 或字面量初始化。 ...

April 22, 2026 · 6 min

Docker的使用

Docker 是一种容器化技术,它可以把应用程序、运行环境、依赖库和配置文件一起打包成镜像,再通过容器运行起来。相比直接部署在服务器上,Docker 更容易做到环境一致、快速发布、快速回滚和服务隔离。 Docker 是什么 在没有 Docker 之前,我们部署一个服务通常需要在服务器上安装语言环境、依赖包、配置数据库连接、开放端口等。不同服务器的系统版本、依赖版本、环境变量只要有一点不同,就可能出现“本地能跑,线上不能跑”的问题。 Docker 解决的核心问题就是:把应用和运行环境一起打包,让应用在不同机器上尽量保持一致的运行结果。 Docker 中有几个重要概念: 镜像(Image):应用的只读模板,里面包含代码、依赖、运行环境等。 容器(Container):镜像运行起来之后的实例,可以理解成一个轻量级的独立运行环境。 Dockerfile:用于描述如何构建镜像的脚本文件。 仓库(Registry):存放镜像的地方,比如 Docker Hub、Harbor、阿里云镜像仓库。 数据卷(Volume):用于持久化容器数据,避免容器删除后数据丢失。 网络(Network):用于容器之间或容器与宿主机之间通信。 Docker 的基本命令 查看版本和运行状态 1 2 docker version docker info 拉取镜像 1 2 3 docker pull nginx docker pull mysql:8.0 docker pull redis:7 镜像名后面的 :8.0、:7 是标签(tag),通常用来区分版本。如果不写 tag,默认使用 latest,但生产环境不建议依赖 latest,最好固定明确版本。 查看本地镜像 1 docker images 运行容器 1 docker run -d --name my-nginx -p 8080:80 nginx 参数说明: -d:后台运行。 --name my-nginx:给容器起名。 -p 8080:80:把宿主机的 8080 端口映射到容器内的 80 端口。 nginx:使用的镜像名。 访问 http://localhost:8080 就能看到 nginx 页面。 ...

April 20, 2026 · 5 min

Gin的使用及优缺点

Gin 是一个轻量级 HTTP Web 框架,封装了路由、参数绑定、中间件等功能,性能较高,适合开发 RESTful API。 优点 性能高 基于 httprouter 零内存分配路由(zero allocation) 比较接近原生 net/http 中间件机制完善 支持全局 / 路由级 / 分组中间件 支持参数绑定和验证 JSON / form / query 自动解析 缺点 不适合复杂大型项目 没有Java Spring 那样的规范 Context过于强劲 不利于分层 基础用法 最小demo示例:引入库+启动一个监听接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import ( "net/http" "github.com/gin-gonic/gin" ) func main() { // 用默认中间件创建路由 r := gin.Default() // 定义一个简单的get请求接口 r.GET("/ping", func(c *gin.Context) { // 返回JSON响应 c.JSON(http.StatusOK, gin.H{ "message": "pong", }) }) // 默认启动在8080端口 r.Run() } 最基本用法 ...

April 15, 2026 · 2 min

Go语言的GC机制

什么是 GC GC(Garbage Collection,垃圾回收)是一种自动内存管理机制,用于自动识别并回收程序中不再使用的内存(即“垃圾”)。程序员无需手动 free 或 delete,GC 会在运行时找到这些不可达的对象并释放其占用的内存,避免内存泄漏和悬空指针。 Go 的 GC 机制 Go 的 GC 经历了多次演进,从最初的简单标记清除,到现在的 并发、三色标记、混合写屏障 的算法。当前版本(Go 1.20+)的核心特点如下: 1. 三色标记法(Tri-color Marking) 将内存中的对象分为三种颜色: 白色:尚未被扫描的对象,可能是垃圾。回收结束后,所有白色对象都会被清除。 灰色:已被标记但尚未扫描其引用的对象(即已经访问到,但它的子对象还没处理)。 黑色:已被扫描且其引用的所有子对象都已被标记(即该对象是存活且已完全处理)。 过程: 初始:所有对象都是白色。 根对象扫描:从根对象(栈、全局变量、寄存器等)出发,将其引用的对象标记为灰色,放入工作队列。 并发标记:不断从工作队列取出灰色对象,扫描其引用,将引用的白色对象标记为灰色,并将当前对象变为黑色。 重复直到没有灰色对象。 清除:所有白色对象即为不可达的垃圾,回收内存。 2. 并发执行(Concurrent GC) Go 的 GC 是并发的,即大部分标记工作与用户程序(mutator)同时运行,避免了长时间的 “Stop-The-World”(STW)停顿。 标记准备阶段(短暂 STW):开启写屏障,启动后台标记 worker。 并发标记阶段:标记工作与用户代码并发执行,通过后台 goroutine 和调度器协作。 标记终止阶段(短暂 STW):关闭写屏障,完成最终标记。 并发清除阶段:释放白色对象的内存,可以边分配边清除,不需要 STW。 3. 写屏障(Write Barrier) 为了保证并发标记的正确性(避免漏标),Go 使用 混合写屏障(hybrid write barrier,结合了 Dijkstra 插入屏障和 Yuasa 删除屏障)。其核心作用是:当用户程序修改指针时,在写操作前或后插入一个屏障,确保新的指针关系被正确处理,不会出现“白色对象被黑色对象引用”的漏标情况。 Go 的混合写屏障简化了屏障逻辑,仅在标记期间启用,且对性能影响较小。 4. 并发清除与内存分配 清除阶段是并发的,在分配内存时逐步回收。Go 采用 span 管理,内存分配器(mcache、mcentral、mheap)与 GC 紧密配合,使得清除工作与分配工作可以交错进行,进一步降低停顿。 ...

April 1, 2026 · 1 min

什么是Channel,怎么实现的?

“Channel 在 Go 运行时里是一个叫 hchan 的结构体,核心是一个环形队列 + 两个等待队列(发送方和接收方),再加上一把互斥锁保证并发安全。”

March 31, 2026 · 1 min

什么是GMP模型,它为什么快?

GMP 模型 是 Go 语言实现高并发的核心,也是它“快”的根本原因。下面将拆解模型本身,再说明为什么这种设计能让 Go 在处理大量并发任务时既高效又轻量。 一、GMP 模型是什么 GMP 是 Goroutine、Machine、Processor 三个组件的缩写: G (Goroutine) Go 的“协程”,可以理解为用户态的轻量级线程。 一个 Goroutine 只占 2KB 左右的栈空间(可动态伸缩),创建、销毁、切换的成本远低于操作系统线程(通常线程栈 1~8MB)。 M (Machine) 操作系统线程的抽象,由内核管理。 一个 M 对应一个真实的内核线程,负责执行 Goroutine 的代码。 P (Processor) 处理器,是 G 和 M 之间的“调度器”。 每个 P 维护一个本地的 Goroutine 队列,并持有执行 Go 代码所需的资源(如内存分配缓存等)。 P 的数量通常等于 CPU 核心数(由 GOMAXPROCS 控制)。 核心关系: 一个 M 必须绑定一个 P 才能执行 G。 一个 P 可以绑定多个 M,但同一时刻只能有一个 M 与其绑定并执行 G。 G 被调度到 P 的本地队列或全局队列,M 通过 P 获取 G 并执行。 二、调度流程(如何工作) 初始化 启动时,会创建与 GOMAXPROCS 数量相等的 P,并启动一个初始 M。 ...

March 31, 2026 · 2 min
留言