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

Go 基础解析

涵盖基础语法、并发、内存管理、接口设计、标准库与工具、性能优化以及实战场景

一、基础语法与类型

1. Go 与 C/Java 的主要区别

  • 内存管理:Go 有垃圾回收(GC),不需要手动管理内存。
  • 并发模型:Go 内置 goroutine 和 channel,而 C/Java 需要线程库或 Executor。
  • 面向对象:Go 不支持继承,用组合 + 接口实现多态。
  • 错误处理:Go 通过返回值 error 处理,而不是异常。
  • 编译与部署:Go 生成静态二进制,部署简单;Java 需要 JVM。

2. Go 的数据类型

基础类型

布尔类型:bool
数值类型
整型:int8, int16, int32, int64, uint8, uint16, uint32, uint64, int, uint, uintptr
浮点型:float32, float64
复数型:complex64, complex128
字符类型
byte:uint8 的别名
rune:int32 的别名,表示一个 Unicode 码点
字符串类型:string

复合类型

数组类型:[n]T,长度固定的元素序列
切片类型:[]T,动态长度的元素序列
结构体类型:struct,字段集合,支持方法和接口
指针类型:*T,指向类型 T 的指针
函数类型:func,函数签名
接口类型:interface,定义方法集的类型
映射类型:map[K]V,键值对集合
通道类型:chan T,用于 goroutine 之间通信的管道

3. new 与 make 区别

关键点newmake
用途分配内存初始化 slice、map、chan
返回值指针对象本身
例子p := new(int) // *ints := make([]int,5) // []int

4. defer 执行时机

  • 在函数返回前执行,遵循 后进先出(LIFO)
  • 常用于释放资源、解锁、打印日志
func f() {defer fmt.Println("first")defer fmt.Println("second")fmt.Println("function body")
}
// 输出:
// function body
// second
// first

5. 指针使用限制

  • Go 不允许指针算术运算
  • 避免野指针和内存越界
  • 只能通过 new/make 或取地址 &var 获取指针

二、控制流与函数

1. 可变参数函数

func sum(nums ...int) int {total := 0for _, n := range nums {total += n}return total
}

2. 闭包(closure)

  • 函数可以引用外部变量并返回函数,保持状态
func adder() func(int) int {sum := 0return func(x int) int {sum += xreturn sum}
}

3. panic、recover 与 error

  • panic:运行时错误,触发堆栈展开
  • recover:捕获 panic,防止程序崩溃
  • error:函数返回错误,不影响堆栈
func safeDiv(a,b int) {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()fmt.Println(a/b) // b=0 会 panic
}

4. 方法与函数区别

  • 方法绑定在 receiver 上
  • 值接收者 vs 指针接收者影响是否能修改对象状态
type Point struct { x, y int }
func (p Point) Move(dx, dy int) { p.x += dx; p.y += dy } // 值接收
func (p *Point) MovePtr(dx, dy int) { p.x += dx; p.y += dy } // 指针接收

三、并发与调度

1. Goroutine

  • 轻量级线程,使用 go func() {} 创建

2. runtime.Gosched()

  • 让出当前 goroutine 的 CPU 时间片
  • 不保证其他 goroutine 立即执行
  • 不保证严格交替输出
go func() { for i:=0;i<10;i+=2{ fmt.Println(i); runtime.Gosched() } }()
go func() { for i:=1;i<10;i+=2{ fmt.Println(i); runtime.Gosched() } }()

3. Channel

  • 无缓冲 channel(同步)
  • 有缓冲 channel(异步,满时阻塞)
  • select 多路复用
ch := make(chan int, 2)
ch <- 1
ch <- 2
select {
case v := <- ch:fmt.Println(v)
default:fmt.Println("no value")
}

4. sync.Mutex 与 sync.RWMutex

  • Mutex:互斥锁
  • RWMutex:读写锁,多个读不阻塞,写独占

5. WaitGroup

var wg sync.WaitGroup
wg.Add(1)
go func() {defer wg.Done()// do something
}()
wg.Wait()

6. Goroutine 泄漏排查

  • channel 阻塞未关闭
  • 无限循环或 select 默认分支未退出
  • 使用 pprof/goroutine dump 检查堆栈

四、内存管理

1. 栈 vs 堆

  • 栈:局部变量,函数返回自动释放
  • 堆:逃逸分析判断需跨函数使用的变量分配到堆,GC 回收

2. slice 扩容原理

  • slice 底层结构:ptr, len, cap
  • append 超出 cap,会分配新数组并复制原数据
s := make([]int,0,2)
s = append(s,1,2,3) // cap 扩容

3. map 底层实现

  • 哈希表 + 链表/红黑树冲突处理
  • 随机 hash 减少碰撞

4. 指针逃逸分析

  • 如果变量被返回或闭包引用,会分配到堆
  • go build -gcflags '-m' 可查看逃逸信息

五、接口与面向对象

1. 接口

  • 定义行为,不定义实现
  • 空接口 interface{} 可接收任意类型
  • 类型断言/类型开关提取具体类型
var i interface{} = "hello"
s := i.(string)
switch v := i.(type) {
case string:fmt.Println("string:", v)
}

2. 多态实现

  • 通过接口实现
type Shape interface { Area() float64 }
type Circle struct { r float64 }
func (c Circle) Area() float64 { return 3.14*c.r*c.r }
func PrintArea(s Shape) { fmt.Println(s.Area()) }

六、标准库与工具

1. Go module 与 GOPATH

  • Module 是推荐方式,支持版本管理
  • GOPATH 已逐渐弱化

2. context.Context

  • 用于控制 goroutine 生命周期、超时、取消和传递请求范围值

3. net/http 与 fasthttp

  • fasthttp 性能更高,但 API 不兼容 http

4. reflect 包

  • 用于运行时类型信息
  • 使用过度可能影响性能

5. log 包

  • 简单日志打印
  • 支持自定义输出、前缀和标志位

七、性能与优化

1. 性能分析工具

  • pprof CPU / memory / goroutine profiling
  • trace 分析并发阻塞、调度

2. 常见优化点

  • 减少对象频繁分配
  • 减少锁竞争
  • 使用池(sync.Pool)复用对象
  • 控制 goroutine 数量,避免泄漏

八、实战类场景题

1. 限流器(Token Bucket)

type TokenBucket struct {tokens intcapacity intmu sync.Mutex
}
func (tb *TokenBucket) Allow() bool {tb.mu.Lock()defer tb.mu.Unlock()if tb.tokens > 0 {tb.tokens--return true}return false
}

2. 生产者-消费者

ch := make(chan int, 10)
go func() {for i:=0;i<10;i++ { ch <- i }close(ch)
}()
go func() {for v := range ch { fmt.Println(v) }
}()

3. 协程池示例

tasks := make(chan func(), 100)
for i:=0;i<5;i++ {go func() {for task := range tasks { task() }}()
}
tasks <- func() { fmt.Println("task") }

4. 奇偶交替输出

odd := make(chan struct{})
even := make(chan struct{})
go func() {for i:=1;i<=10;i+=2 {<- oddfmt.Println(i)even <- struct{}{}}
}()
go func() {for i:=2;i<=10;i+=2 {<- evenfmt.Println(i)odd <- struct{}{}}
}()
odd <- struct{}{} // 启动奇数

http://www.dtcms.com/a/344714.html

相关文章:

  • 逛越南本地菜市场学英语
  • 异质结3.0时代的降本提效革命:捷造科技设备技术创新与产业拐点分析
  • DSPy框架:从提示工程到声明式编程的革命性转变
  • go 常见面试题
  • 番茄(西红柿)叶片病害检测数据集:12k+图像,10类,yolo标注
  • RAG中稠密向量和稀疏向量
  • 基于抗辐照性能的ASP4644S电源芯片特性分析与多领域应用验证
  • show-overflow-tooltip使用当内容过多不展示...
  • 国密双证书双向认证实践
  • 浅拷贝,深拷贝
  • SkyWalking高效线程上下文管理机制:确保调用链中traceId来自同一个请求
  • 图像指针:高效处理像素数据的核心工具
  • 贪吃蛇--C++实战项目(零基础)
  • 直播间聊天室直播录播消息发送自动对话点赞H5开源
  • Datawhale AI夏令营---coze空间共学
  • RoboTwin--CVPR2025--港大--2025.4.17--开源
  • NLP 场景下的强化学习
  • 数据分析编程第二步: 最简单的数据分析尝试
  • 总线之间的关系,64位32位与DB数据总线CB控制总线与AB地址总线的关系
  • Spring 中 @Import 注解:Bean 注入的灵活利器
  • Java面试-自动装箱与拆箱机制解析
  • Springboot项目的各层级详细总结
  • 腾讯云COS SDK签名有效期设置为10分钟到期会自动刷新
  • 2721. 【SDOI2010】外星千足虫
  • ArduPilot plane 俯仰姿态稳定器源码逐行解析:从期望角度到升降舵 PWM_角度环角速度环
  • day24
  • Nginx(一)认识Nginx
  • 一级指针遍历二维数组
  • 3-2〔OSCP ◈ 研记〕❘ WEB应用攻击▸WEB安全防护体系
  • Python Flask快速实现163邮箱发送验证码