1. 前言 接触 Golang 有一段时间了,发现 Golang 同样需要类似 Java 中 Spring 一样的依赖注入框架。如果项目规模比较小,是否有依赖注入框架问题不大,但当项目变大之后,有一个合适的依赖注入框架是十分必要的。通过调研,了解到 Golang 中常用的依赖注入工具主要有 Inject 、Dig 等。但是今天主要介绍的是 Go 团队开发的 Wire,一个编译期实现依赖注入的工具。 什么是依赖注入 说起就要引出另一个名词( IoC )。IoC 是一种设计思想,其核心作用是降低代码的耦合度。是一种实现且用于解决依赖性问题的设计模式。 在go中,依赖注入是指组件创建的时候,就应该获取该组件所依赖的其他关系,如下代码,要创建一个App示例则需要Config和service结构体。 go type App struct { conf *Config httpServer *Server } // 构建 Config func InitConfig() *Config { return &Config{} } // 构建 Server func NewHttpServer.... Go的依赖注入-wire Technology
在 Go 语言的并发编程世界里,sync.Mutex(互斥锁)通常是我们解决数据竞争(Data Race)的首选武器。然而,在某些追求极致性能的场景下,锁的开销(上下文切换、内核态用户态切换)可能会成为瓶颈。 这时,sync/atomic 包就闪亮登场了。它提供了底层的原子级内存操作,让我们能够以“无锁(Lock-Free)”的方式处理并发数据。 本文将带你深入了解 Atomic 的核心概念、使用场景以及它背后的黑科技。 🔍 什么是“原子操作”? 原子操作(Atomic Operation)是指不会被线程调度机制打断的操作。即使在多核 CPU 上,原子操作一旦开始,就会一直运行到结束,中间不会有任何 Context Switch(上下文切换)。 通俗理解: 如果 Mutex 是在厕所门口挂一把锁,同一时间只能进一个人; 那么 Atomic 就是厕所里只有一个超光速马桶,你还没来得及眨眼,操作就已经完成了,根本不需要锁门。 🛠️ 核心操作详解 sync/atomic 包主要提供了五类核心操作,支持的数据类型包括 int32, int64, uint32, uint64, uintpt.... Go 并发编程进阶:深入理解 sync/atomic 包 Technology
1. 概念梳理 1.1 线程 通常指内核级线程,具有以下特点:· 是操作系统的做小调度单元; 创建,销毁,调度交由内核完成,cup需要完成用户态与内核态的切换; 可充分利用多核,实现并行。 1.2 协程 协程:又称为用户级别线程,核心如下: 与线程存在映射关系:M:1 创建,销毁,调度在用户态完成,对内核透明 从属同一个内核级线程,无法并行;一个协程阻塞会导致从属同一个线程的所有协程无法执行。 1.3 Goroutine Goroutine,经Golang优化后的特殊协程,核心点如下: 与线程存在映射关系:M:N 创建,销毁,调度在用户态完成,对内核透明 可利用多个线程,实现并行。 通过调度器的调度,实现和线程间的动态绑定和灵活调度; 栈空间大小可动态扩缩,因地制宜。 实际上,“灵活调度” 一词概括得实在过于简要,Golang 在调度 goroutine 时,针对“如何减少加锁行为”,“如何避免资源不均”等问题都给出了精彩的解决方案,这一切都得益于经典的 “gmp” 模型。 2. GMP模型 GMP = goroutine+machine+processor+(一套有机组合的机制.... Golang GMP原理 Technology
Go Context 源码深度解析与最佳实践 目录 Context 核心接口设计 源码结构解析 四大核心实现 取消机制的实现原理 值传递的设计 最佳实践与业务场景 1. Context 核心接口设计 go // context.go - 核心接口定义 type Context interface { // 返回 context 被取消的时间点 Deadline() (deadline time.Time, ok bool) // 返回一个 channel,当 context 被取消时会被关闭 // 这是实现取消通知的核心机制 Done() <-chan struct{} // 返回 context 被取消的原因 Err() error // 根据 key 获取值 Value(key interface{}) interface{} } 设计思想: 返回只读 channel,利用 "关闭 channel 会通知所有接收者" 的特性实现广播 接口最小化,只有 4 个方法,符合 Go 的简洁哲学 不可变性:Context 是不可修改的,只能通过衍生创建新的 Context 2. 源码.... Context源码学习和最佳实践 Technology
Go Time 包完全指南 目录 核心类型概览 时间点操作 (Time) 时间间隔 (Duration) 定时器 (Timer) 周期触发器 (Ticker) 时间格式化 实战场景 常见陷阱 1. 核心类型概览 time 包的核心是 4 个类型: go // Time - 表示一个时间点 var t time.Time = time.Now() // Duration - 表示时间间隔(纳秒精度) var d time.Duration = 5 * time.Second // Timer - 一次性定时器 var timer *time.Timer = time.NewTimer(5 * time.Second) // Ticker - 周期性触发器 var ticker *time.Ticker = time.NewTicker(1 * time.Second) 关系图: plain text Time (时间点) ├── Now() - 获取当前时间 ├── Add(Duration) - 加上时间间隔 └── Sub(Time) - 两个时间点相减 → Duration Du.... Go标准库-Time Technology
数据结构 双层存储架构(read vs dirty) 我们要掌握的第一个核心概念就是:sync.Map 为什么会有两个 Map? 在标准的 Go map 中,为了防止并发冲突,我们在读写时都需要加锁(Mutex)。但在高并发场景下,如果读操作很多,锁的竞争就会导致性能下降。 sync.Map 解决这个问题的策略是**“读写分离”**。它内部维护了两个字段: read (只读/快路径) 特点:访问不需要加锁(使用原子操作 atomic)。 内容:存放的是“稳定”的数据,通常是那些已经存在且主要被用于读取的 key。 比喻:就像你办公桌上的便利贴。你需要找电话号码时,第一眼先看桌上(read),因为这最快,不用起身。 dirty (脏/慢路径) 特点:访问需要加锁(mu Mutex)。 内容:存放所有的数据,包括最新写入且还没同步到 read 中的 key。 比喻:就像档案室里的文件柜。如果桌上(read)找不到,你就不得不拿钥匙(加锁),走到档案室(dirty)去翻找,这比较慢。 Entry 的三种状态(nil, expunged, 指针) 为了高效地处理读写操作,sync.Map 在底.... GO中sync.Map的底层原理 Technology
Eino框架 是由字节开发的Go的大模型应用框架,为go开发者提供类似LangChain的能力。 核心特性 组件化设计:提供chatModel、Embedding、Retrivcer、Tool等丰富的原子组件 灵活编排:支持Chain和Grapher两张编排模式。 生态集成:支持OpenAI,ARK、Allama,Qwen等多种大模型。 高性能:基于Go,天然支持高并发场景。 易扩展:清晰的接口设计,方便自定义组件。 简单使用 go package main import ( "context" "fmt" "log" "os" "github.com/cloudwego/eino-ext/components/model/deepseek" "github.com/cloudwego/eino/schema" ) func main() { ctx := context.Background() //创建模型 model, err := deepseek.NewChatModel(ctx, &deepseek.ChatModelConfig{ APIKey: os.Geten.... Eino简单学习 Technology