Golang 基础与实战笔记:从语法到微服务的全面指南

Golang 基础与实战笔记:从语法到微服务的全面指南

本文基于作者多年的 Go 语言开发经验,系统整理了 Go 语言的基础语法、核心特性、并发编程模型、常用框架和微服务开发等方面的知识,适合有一定编程基础、想快速掌握 Go 语言的开发者阅读。


一、Go 语言简介与环境搭建

1.1 Go 语言概述

Go 语言(又称 Golang)是 Google 于 2009 年推出的一种静态强类型、编译型语言。它的设计目标是:在不损失应用程序性能的情况下降低代码的复杂性。Go 语言专门针对多处理器系统应用程序的编程进行了优化,使用 Go 编译的程序可以媲美 C 或 C++ 代码的速度,而且更加安全、支持并行进程。

Go 语言被广泛应用于以下场景:

  • Web 服务器和存储集群等巨型中央服务器的系统编程
  • 高性能分布式系统开发
  • 游戏服务端开发(天然支持海量并行)
  • 云原生和容器化技术(Docker、Kubernetes 均用 Go 编写)

1.2 Go 版本管理

推荐使用 goup 工具来管理本地的 Go 版本,方便在不同版本间切换:

bash 复制代码
# 安装 goup(Windows 平台)
# 从 https://github.com/owenthereal/goup/releases 下载最新版

# 初始化
goup init --skip-install --skip-prompt

# 安装指定版本(使用国内镜像)
GOUP_GO_HOST=golang.google.cn goup install 1.22.0

# 切换版本
goup default 1.22.0

# 验证
go version

1.3 第一个 Go 程序

go 复制代码
package main

import "fmt"

func main() {
    fmt.Println("Hello Golang")
}

程序结构说明:

组成部分 说明
package main 包声明,main 包表示一个可独立执行的程序
import "fmt" 引入 fmt 包,实现格式化 I/O
func main() 程序入口函数,每个可执行程序必须包含
fmt.Println(...) 输出字符串到控制台,自动添加换行符

编译与运行:

bash 复制代码
# 编译生成可执行文件
go build hello.go

# 直接运行(不生成可执行文件)
go run hello.go

可见性规则: 当标识符(常量、变量、类型、函数名、结构字段等)以大写字母开头时,可以被外部包的代码使用(类似 public);以小写字母开头则对包外不可见(类似 protected)。


二、基础语法

2.1 变量与常量

Go 语言提供三种变量声明方式:

go 复制代码
// 方式一:指定类型,声明后若不赋值使用默认值(零值)
var a int
a = 10

// 方式二:根据值自行判定类型
var b = 10

// 方式三:短变量声明(只能在函数内使用,左侧变量不能已声明过)
c := 10

多变量声明:

go 复制代码
var (
    err           error
    result, score int64
)

常量与 iota:

go 复制代码
const identifier [type] = value

// 枚举常量
const (
    Unknown = 0
    Female  = 1
    Male    = 2
)

// iota:特殊常量,每次 const 出现时重置为 0
const (
    a = iota // 0
    b        // 1
    c        // 2
)

_(下划线)是一个只写变量,常用于忽略函数返回值中不需要的部分:

go 复制代码
_, b = 5, 7  // 值 5 被抛弃

2.2 数据类型

Go 语言按类别有以下几种数据类型:

基本类型:

类型 描述
bool 布尔型,值只能是 truefalse
int/int8/int16/int32/int64 有符号整型
uint/uint8/uint16/uint32/uint64 无符号整型
float32/float64 浮点型
complex64/complex128 复数类型
byte 类似 uint8
rune 类似 int32,表示一个 Unicode 码点
string 字符串,字节使用 UTF-8 编码

派生类型: 指针类型、数组类型、结构体类型(struct)、Channel 类型、函数类型、切片类型、接口类型(interface)、Map 类型。

类型转换:

go 复制代码
// Go 不支持隐式类型转换,必须显式转换
var a = int(12.34)  // a = 12

// 类型别名 vs 类型定义
type MyInt1 = int   // 类型别名,MyInt1 和 int 完全相同
type MyInt2 int     // 类型定义,创建了一种新类型

fmt.Printf("%T %T\n", MyInt1(1), MyInt2(1))
// 输出:int main.MyInt2

2.3 运算符与控制流

运算符: Go 语言的运算符基本和 C 语言相同,但有以下区别:

  • 没有前置 ++ 和后置 ++ 的区别,++ 只是语句而非表达式
  • 关系运算符的结果是 bool

条件语句:

go 复制代码
// if-else
if a == b {
    handle()
}

// switch
switch x {
case 1:
    fmt.Println("one")
case 2:
    fmt.Println("two")
default:
    fmt.Println("other")
}

select 语句: 类似于用于通信的 switch 语句,每个 case 必须是一个通信操作(channel 发送或接收):

go 复制代码
select {
case msg := <-ch1:
    fmt.Println("received", msg)
case ch2 <- msg:
    fmt.Println("sent", msg)
default:
    fmt.Println("no activity")
}

循环语句: Go 只有 for 循环,但可以模拟 while 和无限循环:

go 复制代码
// 经典 for 循环
for i := 0; i < 10; i++ {
    fmt.Printf("i = %d\n", i)
}

// 模拟 while
for a < b {
    a++
}

// 无限循环
for {
    // ...
}

// range 迭代
nums := []int{2, 3, 4}
for i, num := range nums {
    fmt.Printf("index: %d, value: %d\n", i, num)
}

2.4 函数

go 复制代码
// 基本函数定义
func function_name(parameter_list) return_types {
    // 函数体
}

// 多返回值(Go 的特色功能)
func swap(a, b int) (int, int) {
    return b, a
}

// 命名返回值
func divide(a, b int) (result int, err error) {
    if b == 0 {
        err = errors.New("division by zero")
        return
    }
    result = a / b
    return
}

defer 关键字: defer 用于在函数返回前执行某些操作,常用于资源释放。执行顺序为先进后出(栈):

go 复制代码
func do() (ok bool) {
    file, _ := os.Open("a.txt")
    defer file.Close()  // 函数返回前自动关闭文件
    // doSomething
    return ok
}

// defer 的执行顺序是逆序的
for i := 0; i < 5; i++ {
    defer fmt.Printf("%d ", i)
}
// 输出:4 3 2 1 0

2.5 结构体与方法

go 复制代码
// 定义结构体
type Book struct {
    Title  string
    Author string
    Price  float64
}

// 创建实例
b := Book{Title: "Go Programming", Author: "John", Price: 59.9}

// 方法定义(值接收者 vs 指针接收者)
func (m Book) GetValue() int {
    return m.Price  // 不能修改调用者的值
}

func (m *Book) SetValue(price float64) {
    m.Price = price  // 可以修改调用者的值
}

注意: 与 C 语言不同,Go 中指针类型的结构体访问成员变量也使用 . 操作符,而不是 ->


三、核心数据结构深入

3.1 切片(Slice)

切片是 Go 中对数组的抽象,是"动态数组",长度不固定,可以追加元素。

go 复制代码
// 创建切片
s := []int{1, 2, 3}                    // 直接初始化
s := make([]int, 5, 10)                // make([]T, length, capacity)
s := arr[startIndex:endIndex]          // 从数组切片

// append 追加元素
s = append(s, 4)
s = append(s, 5, 6, 7)

// copy 复制切片
dst := make([]int, len(s), cap(s)*2)
copy(dst, s)

// copy 也可以将 string 复制给 byte 切片
buf := make([]byte, 10)
copy(buf, "hello")

切片技巧:

go 复制代码
// 允许对 nil 切片添加元素(但对 nil map 会 panic)
var s []int
s = append(s, 1)  // 这是合法的

// 只循环不取值的高效写法
slice := make([]struct{}, 100)
for range slice {
    // 执行 100 次
}

3.2 Map(集合/哈希表)

go 复制代码
// 创建 Map
m := make(map[string]string)
m["key"] = "value"

// 遍历 Map
for k, v := range m {
    fmt.Printf("%s -> %s\n", k, v)
}

// 删除元素
delete(m, "key")

// 判断 key 是否存在
value, ok := m["key"]
if ok {
    fmt.Println("found:", value)
}

注意事项:

  • 在创建 map 时可以指定容量,但不能像 slice 一样使用 cap() 检测分配空间大小
  • 对值为 nil 的 map 添加元素会引发运行时 panic

3.3 Channel(通道)

Channel 是 Go 语言并发编程的核心,用于在 goroutine 之间安全地传递数据。

go 复制代码
// 创建通道
ch := make(chan int, 10)  // 带缓冲的通道,容量为 10

// 发送和接收
ch <- 42          // 发送
value := <-ch     // 接收

// 关闭通道后,缓冲中的数据还可以读出
close(ch)

// 判断通道是否关闭
v, ok := <-ch
if !ok {
    fmt.Println("channel closed")
}

// 使用 for + range 读取通道(通道关闭后自动退出循环)
for v := range ch {
    fmt.Println(v)
}

Channel 使用技巧:

go 复制代码
// 单向通道(通常作为函数参数)
func producer(ch chan<- int) {   // 只写通道
    ch <- 42
}

func consumer(ch <-chan int) {   // 只读通道
    v := <-ch
    fmt.Println(v)
}

// len(ch) 返回已写入但未消费的元素个数
// cap(ch) 返回通道的容量

Channel 规则总结:

操作 nil 通道 已关闭通道 正常通道
发送 永久阻塞 panic 阻塞或成功
接收 永久阻塞 返回零值 阻塞或成功
关闭 panic panic 成功

3.4 内存对齐

Go 默认采用类似 C/C++ 的内存对齐机制。内存对齐的原因:

  1. 平台移植性: 不是所有硬件平台都能访问任意地址上的任意数据
  2. 性能提升: 对齐的内存只需一次访问即可完成读取,空间换时间

对齐原则: 一个结构体内的对齐系数取决于最大的成员字节数,但不超过平台系数(64 位平台为 8)。

go 复制代码
type T struct {
    a byte
    b uint16  // unsafe.Sizeof(*new(T)) == 4
}

// 32 位下访问 int64 结构体成员的注意事项
type T1 struct {
    a int32
    _ int32   // 占位符,使结构体按 8 字节对齐
    b int64
}

使用 unsafe.Alignof(v) 查看对齐系数,使用 unsafe.Sizeof(v) 查看实际占用大小。


四、并发编程

4.1 GMP 调度模型

GMP 是 Go 语言运行时的核心调度模型,理解它对编写高效并发程序至关重要:

  • G(Goroutine): 用户态协程,轻量级线程
  • M(Machine/Thread): 操作系统线程(内核态),最大 10000 个
  • P(Processor): 逻辑处理器,最大 256 个(可通过 runtime.GOMAXPROCS 设置)

调度流程:

  1. 每个 Go 程序有全局队列和每个 P 维护的本地队列
  2. Goroutine 创建时加入 P 的本地队列,满了后放入全局队列
  3. P 将本地队列的 G 放到 M 中运行,每个 G 有时间片
  4. 当 G 遇到阻塞任务时,P 会分离当前 M,创建新 M 执行队列中的 G
  5. P 先从本地队列找 G,没有则从全局队列找,再去其他 P 中"偷"
go 复制代码
// 设置使用的 CPU 核心数
runtime.GOMAXPROCS(runtime.NumCPU())

// 让出时间片
runtime.Gosched()

4.2 Goroutine 与 Channel 实战

go 复制代码
// 启动 goroutine
go func() {
    fmt.Println("hello from goroutine")
}()

// 使用 channel 通信
func producer(ch chan<- int) {
    for i := 0; i < 10; i++ {
        ch <- i
    }
    close(ch)
}

func consumer(ch <-chan int, done chan<- bool) {
    for v := range ch {
        fmt.Println("received:", v)
    }
    done <- true
}

func main() {
    ch := make(chan int, 5)
    done := make(chan bool)

    go producer(ch)
    go consumer(ch, done)

    <-done  // 等待消费者完成
}

4.3 sync 同步工具

Go 的 sync 包提供了多种实用的同步工具:

go 复制代码
// 1. Mutex - 普通互斥锁
var mu sync.Mutex
mu.Lock()
// 临界区
mu.Unlock()

// 2. RWMutex - 读写锁
var rw sync.RWMutex
rw.RLock()   // 读锁,多个 goroutine 可同时持有
rw.RUnlock()
rw.Lock()    // 写锁,独占
rw.Unlock()

// 3. Once - 只执行一次(常用于单例模式)
var once sync.Once
once.Do(func() {
    // 初始化操作,只会执行一次
})

// 4. WaitGroup - 等待一组 goroutine 完成
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
    wg.Add(1)
    go func() {
        defer wg.Done()
        // do work
    }()
}
wg.Wait()

// 5. Map - 线程安全的 Map
var m sync.Map
m.Store("key", "value")
v, ok := m.Load("key")

// 6. Pool - 对象池
var pool = sync.Pool{
    New: func() interface{} {
        return new(MyObject)
    },
}
obj := pool.Get().(*MyObject)
pool.Put(obj)

// 7. Cond - 条件变量
cond := sync.NewCond(&mu)
cond.Wait()      // 等待信号
cond.Signal()    // 唤醒一个等待者
cond.Broadcast() // 唤醒所有等待者

4.4 Atomic 原子操作

go 复制代码
// 基本类型的原子操作
var counter int64
atomic.AddInt64(&counter, 1)
atomic.LoadInt64(&counter)
atomic.StoreInt64(&counter, 100)

// 任意类型的原子操作
var value atomic.Value
value.Store("hello")
v := value.Load().(string)

4.5 Context 上下文

Context 是处理慢请求时管理多个 goroutine 生命周期的重要手段:

go 复制代码
// 创建可取消的 context
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

// 创建超时 context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

// 在 goroutine 中使用
go func(ctx context.Context) {
    select {
    case <-ctx.Done():
        fmt.Println("cancelled:", ctx.Err())
    case <-time.After(3 * time.Second):
        fmt.Println("work done")
    }
}(ctx)

通过派生方式生成子 context,父 context 调用 cancel 函数时,各子 context 都能收到信号。


五、包管理与依赖

5.1 Go Modules(推荐)

Go Module 是 Go 1.11 之后官方推荐的包管理方式,是 Go 最终的包管理工具。

bash 复制代码
# 初始化模块
go mod init github.com/yourname/project

# 下载依赖
go mod tidy

# 指定版本下载
go get github.com/some/package@v2.0.0

# 设置国内代理
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOSUMDB=sum.golang.google.cn

go.mod 文件示例:

复制代码
module github.com/yourname/project

go 1.22

require (
    github.com/gin-gonic/gin v1.9.1
    gorm.io/gorm v1.25.0
)

大版本约定: 当模块版本 >= v2.0.0 时,模块路径必须添加版本后缀:

复制代码
module github.com/panicthis/modfile/v2

5.2 Vendor 模式

Vendor 模式将工程中所有第三方依赖打包进 vendor 目录,适合不能访问外网的生产环境:

bash 复制代码
# Go Module 项目使用 vendor
go mod vendor              # 创建 vendor 目录
go build -mod=vendor       # 编译时指定使用 vendor

5.3 导入包的几种形式

go 复制代码
import "github.com/zhouwy1994/library"             // 正常导入
import lib "github.com/zhouwy1994/library"          // 别名导入
import . "github.com/zhouwy1994/library"            // 直接使用(不推荐)
import _ "github.com/zhouwy1994/library"            // 仅执行 init()

下划线的三个用途:

  1. import _ --- 仅初始化包,不使用其中的方法
  2. file, _ := os.Open(...) --- 忽略返回值
  3. var _ Interface = &Struct{} --- 接口断言,确保结构体实现了接口

六、Protobuf 与 gRPC

6.1 Protobuf

Protobuf 是一种跨语言的数据序列化工具,支持 boolintdoublefloatstringbytesmaprepeated 等类型。

6.2 gRPC 四种服务接口

protobuf 复制代码
syntax = "proto3";

service RouteGuide {
    // 1. 简单 RPC(一问一答,最常用)
    rpc GetFeature(Point) returns (Feature) {}

    // 2. 服务器端流式 RPC
    rpc ListFeatures(Rectangle) returns (stream Feature) {}

    // 3. 客户端流式 RPC
    rpc RecordRoute(stream Point) returns (RouteSummary) {}

    // 4. 双向流式 RPC
    rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}

message Point {
    int32 latitude = 1;
    int32 longitude = 2;
}

编译与使用:

bash 复制代码
# 编译 proto 文件
protoc -I proto/ proto/route_guide.proto \
    --go_out=plugins=grpc:../routeguide

服务端实现:

go 复制代码
type routeGuideServer struct{}

func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
    // 实现业务逻辑
    return &pb.Feature{}, nil
}

// 启动 gRPC 服务
lis, _ := net.Listen("tcp4", ":3456")
grpcServer := grpc.NewServer()
pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})
grpcServer.Serve(lis)

客户端调用:

go 复制代码
conn, _ := grpc.Dial("127.0.0.1:3456", grpc.WithInsecure())
client := pb.NewRouteGuideClient(conn)
feature, _ := client.GetFeature(context.Background(), &pb.Point{Latitude: 409146138})

七、HTTP 服务器与 Web 框架

7.1 Go 原生 HTTP 服务器

go 复制代码
// 简单的文件服务器(仅需两行代码)
http.Handle("/", http.FileServer(http.Dir("./")))
http.ListenAndServe(":8888", nil)

核心概念:

  • 处理器(Handler): 实现了 Handler 接口的 ServeHTTP 方法
  • 处理器函数: 签名为 func(ResponseWriter, *Request) 的函数
  • ServeMux: 多路复用器,负责 URL 路由分发

7.2 Web 框架对比与选型

框架 定位 特点 适用场景
Echo 轻量级 高性能、可扩展、极简 小型业务
Gin 中量级 高性能、中间件丰富、社区活跃 中型业务
Beego 重量级 完整 MVC、自带 ORM/Session 大型业务
Fiber 轻量级 类 Express 风格、基于 fasthttp 高性能 API

7.3 Gin 框架实战

go 复制代码
package main

import "github.com/gin-gonic/gin"

type Request struct {
    Name      string `form:"name" json:"name" binding:"required"`
    Timestamp string `form:"timestamp" json:"timestamp" binding:"required"`
}

func main() {
    r := gin.Default()

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "pong"})
    })

    r.POST("/submit", func(c *gin.Context) {
        var req Request
        if err := c.ShouldBindJSON(&req); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }
        c.JSON(200, gin.H{"status": "ok"})
    })

    r.Run(":8080")
}

Gin 的参数绑定(binding)标签: 支持丰富的验证规则,如 requiredlen=64gt=10oneof=red greenemailurl 等。

7.4 中间件原理

中间件的本质是"处理器串联",通过层层包裹实现横切关注点:

go 复制代码
// 计时中间件
func TimingMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now()
        c.Next()  // 调用下一个处理器
        elapsed := time.Since(start)
        fmt.Printf("Request took %v\n", elapsed)
    }
}

八、日志框架

8.1 Zap(高性能,推荐)

go 复制代码
func NewZapLogger(path, baseFile string, saveDays int, level string) *zap.SugaredLogger {
    // 日志分割器
    lumberJackLogger := &lumberjack.Logger{
        Filename:   fmt.Sprintf("%s/%s", path, baseFile),
        MaxSize:    64,        // MB
        MaxBackups: saveDays,  // 最大保留个数
        MaxAge:     saveDays,  // 最大保留天数
        Compress:   false,
    }

    // 日志编码器
    encoderConfig := zapcore.EncoderConfig{
        TimeKey:        "time",
        LevelKey:       "level",
        CallerKey:      "file",
        FunctionKey:    zapcore.OmitKey,
        MessageKey:     "msg",
        StacktraceKey:  "stacktrace",
        LineEnding:     zapcore.DefaultLineEnding,
        EncodeLevel:    zapcore.CapitalLevelEncoder,
        EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
            enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
        },
        EncodeDuration: zapcore.MillisDurationEncoder,
        EncodeCaller:   zapcore.ShortCallerEncoder,
    }

    // 设置日志级别
    atomicLevel := zap.NewAtomicLevel()
    switch level {
    case "debug":
        atomicLevel.SetLevel(zap.DebugLevel)
    case "release":
        atomicLevel.SetLevel(zap.InfoLevel)
    }

    // 构建日志记录器
    jsonEncoder := zapcore.NewJSONEncoder(encoderConfig)
    writeSyncer := zapcore.NewMultiWriteSyncer(
        zapcore.AddSync(os.Stdout),
        zapcore.AddSync(lumberJackLogger),
    )
    core := zapcore.NewCore(jsonEncoder, writeSyncer, atomicLevel)
    logger := zap.New(core, zap.AddCaller(), zap.Development())

    return logger.Sugar()
}

8.2 Logrus(高度可定制化)

Logrus 通过 Hook 机制实现高度定制:

go 复制代码
import "github.com/sirupsen/logrus"

log := logrus.New()
log.SetFormatter(&logrus.JSONFormatter{
    TimestampFormat: "2006-01-02 15:04:05",
})
log.SetReportCaller(true)
log.Info("application started")

8.3 日志记录通用步骤

  1. 创建日志分割器(Hook),如 lumberjackfile-rotatelogs
  2. 设置日志编码器格式(JSON/TEXT)、通用字段(time, level, file, line, msg)
  3. 设置日志等级(debug, info, warn, error)
  4. 将分割器和编码器绑定到日志记录器
  5. 封装日志接口(Info, Infof, InfoWithFields 等)

九、DLL/SO 调用(CGO 与 syscall)

Go 调用 C 库是所有语言中最方便的之一:

9.1 使用 syscall 调用 DLL

go 复制代码
dllHandle, err := syscall.LoadLibrary("WaveApi.dll")
if err != nil {
    log.Fatal(err)
}
defer syscall.FreeLibrary(dllHandle)

proc, err := syscall.GetProcAddress(dllHandle, "waveInInit")
if err != nil {
    log.Fatal(err)
}

// 调用带回调的 DLL 函数
callback := syscall.NewCallback(func(data unsafe.Pointer, length int, user unsafe.Pointer) int {
    // 处理回调数据
    return 0
})

syscall.Syscall6(proc, 5,
    uintptr(channels),
    uintptr(samplesPerSec),
    uintptr(bitPerSec),
    callback,
    uintptr(0), 0)

9.2 使用 CGO 直接调用 C 代码

go 复制代码
/*
#include <stdio.h>
#include <stdlib.h>

char* hello() {
    return "Hello from C!";
}
*/
import "C"
import "unsafe"

func main() {
    // 调用 C 函数
    cStr := C.hello()
    goStr := C.GoString(cStr)  // C 字符串转 Go 字符串
    fmt.Println(goStr)

    // Go 字符串转 C 字符串(需手动释放)
    goStr := "Hello from Go"
    cStr := C.CString(goStr)
    defer C.free(unsafe.Pointer(cStr))
}

十、go-micro 微服务开发

10.1 Micro 与 go-micro 的关系

  • go-micro 是一套编写微服务的框架,让编写微服务变得更加简单
  • Micro 是一个完整的微服务生态,包含框架(go-micro)、运行时管理、网络共享等

Micro 自带的运行时服务替代了常用的中间件:

  • api --- 替代 API 网关
  • broker --- 替代 Kafka、RabbitMQ 等消息队列
  • config --- 替代 Nacos、Etcd 等配置中心
  • registry --- 替代 Nacos、Etcd 等注册中心
  • store --- 替代 Redis、Memcache 等缓存

10.2 创建微服务

bash 复制代码
# 使用脚手架创建项目
micro new helloworld

生成的目录结构:

复制代码
.
├── main.go
├── handler/
│   └── hello.go
├── proto/
│   └── hello.proto
├── Dockerfile
├── Makefile
├── go.mod
└── micro.mu

注意事项: 使用 go-micro 时要注意版本匹配(v1/v2/v3/v4),protoc-gen-micro 工具也要使用对应版本编译。

10.3 常用第三方库清单

库名 用途
GORM 数据库 ORM 操作
Gin 高性能 Web 框架
go-redis Redis 客户端
Viper 配置文件读写(支持 JSON/TOML/YAML 等)
Swagger API 文档自动生成
go-simplejson JSON 解析库
goquery HTML 解析(爬虫利器)
excelize Excel 文件处理
go-qrcode 二维码生成
pigo 人脸检测(不依赖 OpenCV)
progressbar 进度条显示

总结

Go 语言凭借其简洁的语法、强大的并发模型和丰富的生态,已成为后端开发的热门选择。本文涵盖了以下核心知识点:

  1. 基础语法: 变量、常量、数据类型、控制流、函数、结构体
  2. 核心数据结构: Slice、Map、Channel 的深入理解和使用技巧
  3. 内存对齐: 理解 Go 的内存布局和对齐规则
  4. 并发编程: GMP 调度模型、goroutine/channel/sync 包的实战使用
  5. 包管理: Go Modules 和 Vendor 模式的使用
  6. Web 开发: 原生 HTTP、Gin/Echo/Beego 框架对比与实战
  7. 日志框架: Zap 和 Logrus 的配置与使用
  8. 跨语言调用: CGO 和 syscall 调用 DLL/SO
  9. 微服务: go-micro 框架和 Protobuf/gRPC 的使用

Go 语言的学习曲线平缓,但要写出高效、优雅的 Go 代码需要深入理解其并发模型和设计哲学。希望本文能帮助你在 Go 语言的学习和实践中少走弯路。


原始笔记来源:

  • jdah/study on golang.go
  • zyh/LearnGolang.go
  • zyh/gomicro.go
相关推荐
灰子学技术1 小时前
Envoy TCP 层面的 Metric 指标分析
开发语言·网络·网络协议·tcp/ip·php
清水白石0082 小时前
生成器不是性能银弹:什么时候该用 `yield` 省内存,什么时候它会拖慢 Python 数据处理吞吐?
开发语言·python·原型模式
不甘先生2 小时前
Go context 实战指南:从入门到生产级并发控制(架构师避坑手册)
开发语言·后端·golang
AI进化营-智能译站2 小时前
ROS2 C++开发系列18-STL容器实战:deque缓存激光雷达数据|priority_queue调度任务
开发语言·c++·缓存·ai
初心未改HD2 小时前
Go 泛型完全指南:从入门到实战
开发语言·golang
西红柿炒番茄312 小时前
【Python】一个自动切换壁纸的python程序
开发语言·python
ShiJiuD6668889992 小时前
JSP Cookie和Session
java·开发语言
FQNmxDG4S10 小时前
Java多线程编程:Thread与Runnable的并发控制
java·开发语言
前端老石人11 小时前
HTML 字符引用完全指南
开发语言·前端·html