提示
不要用传统开发的思维来理解 智能 Agent 的开发,也不要用传统框架的思想来理解 Agent 框架。
1. 前言
想要看明白 Eino 的源码,需要三个前置工作:
- 有一定的 LLM 项目开发经验,对于常见的关键词有一定的了解。
- 十分熟悉 Go 语言,对于泛型、接口、并发等有深刻的认识。
- 对于软件工程、代码架构等有一定的了解。
提示
不要用传统开发的思维来理解 智能 Agent 的开发,也不要用传统框架的思想来理解 Agent 框架。
想要看明白 Eino 的源码,需要三个前置工作:
go 1.24版本之后,对于路由这一块进行了升级改造,但是本质没有大的变化,大家可以搜索看下。
正如我们之前学过的,Go语言搭建一个服务器非常简单,只需要用到几个方法:
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
_, _ = fmt.Fprintf(writer, "关注 香香编程喵喵喵,关注香香编程谢谢喵喵喵!")
})
panic(http.ListenAndServe(":8080", nil))
什么是面向切面编程AOP? - 知乎
AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,用于将横切关注点(Cross-cutting Concerns)与主要业务逻辑分离。横切关注点是指那些存在于应用程序中多个不同部分的功能,例如日志,鉴权等,它们跨越多个模块和对象。
go1.7是一个变动非常大的版本。一方面官方引入了Context来管理多个具有明显父级关系的GoRoutine,一方面对原有的代码包进行了大量的修改,让他们都能够支持Context。
我们之前已经讲过一个用来管理,编排多个GoRoutine的包sync.WaitGroup。它能够解决部分场景,但仍然有一些问题未能解决:
如果你学过软件工程的话,应该会了解设计模式是什么,用来干什么。简单的讲,设计模式是经验总结,是针对某些特定场景的解决方案。1995年,GOF提出了23种设计模式,在实际开发中使用到的种类非常少。设计模式有一个严肃的问题:增加代码量,降低代码可读性。当然了,这也是为了实现高内聚,低耦合付出的代价,想要得到一些,就得失去一些呗。
真正的灾难往往不是灾难本身,设计模式的灾难百分之九十九是开发人员的滥用。很多初学者,总是想把刚学会的设计模式用到自己的代码中,完全不考虑当前业务场景是否合适。于是,灾难悄无声息的酝酿起来了。
本文为极客时间《Go语言核心36讲》的学习笔记,梳理了相关的知识点。
当我们需要对一个程序进行性能分析的时,通常只有两种情况:
第一种,这个程序是个重要模块,上线后要迎接大流量场景者是支持核心业务线。不能出问题,出了问题就是大问题,今年的绩效就要玩砸了。第二种,程序已经出了性能问题。
第一种情况,需要我们大范围的进行压测,通过循序渐进的方式获取程序的性能瓶颈,为后续的技术优化和应急方案提供详细的指标和场景。比如:把QPS压到1W时,CPU、内存、响应耗时和协程数等指标具体是多少。后续,以此为参考制定优化指标和方案。
第二种情况,需要我们能够快速定位问题原因,尽快修复,减少损失。但,这是理论上。正常线上出现性能问题,应该先执行上文提到的应急方案,减小损失,保留现场。等危机解除,服务稳定后再分析程序的性能问题。
我们常常会遇到一些业务场景,需要我们每隔一段时间执行以下代码。比如:
这种业务场景,就需要我们用到定时器。最常用的定时器是linux下的crontab,之前使用PHP或者Python的时候,就是通过定义crontab,定时执行一条脚本语句实现定时任务。
提示
引申,熟悉下crontab。它仍然是常用的定时任务方案,绝大多数的自用小工具,都会使用。
本文为极客时间《Go语言核心36讲》的学习笔记,梳理了相关的知识点。
Go语言做网络开发是非常容易的一件事,它已经为我们封装好了Http包,开箱即用。除此之外,我们也可以用Gin框架或者使用fasthttp等三方包,快速搭建一个Web服务。但是,越是封装的方便,我们越是容易忽略底层的一些知识点。
我们这里先补充两个必要的知识:网络分层和进程通信。
这块知识属于计算机网络,可以直接去看书。
本文为极客时间《Go语言核心36讲》的学习笔记,梳理了相关的知识点。
通常情况下,我们是肯定不会直接起一个协程开始写逻辑代码的。Go语言已经帮我们写好了各种常用的并发工具,基本都在 sync(同步) 包中,可以开箱即用。
//正常情况下,是不会这样子直接起一个协程做并发业务的。
go func(){
....
}
这一块内容我们只简单提一下,不会展开。相关问题可以直接在网上找资料,非常全面。
在讨论并发之前,必须得先讲清楚并发和并行,以及他们两个之间的区别,还有各自会有哪些常见的问题。这两个名词都是操作系统里的概念:
相关信息
本文为极客时间《Go语言核心36讲》的学习笔记,梳理了相关的知识点。
通常 panic 和 recover 是用来处理异常问题的。我们来综述下,他们各自的特点:
本文为极客时间《Go语言核心36讲》的学习笔记,梳理了相关的知识点。
接口(硬件类接口)是指同一计算机不同功能层之间的通信规则称为接口。
接口(软件类接口)是指对协定进行定义的引用类型。其他类型实现接口,以保证它们支持某些操作。接口指定必须由类提供的成员或实现它的其他接口。与类相似,接口可以包含方法、属性、 索引器和事件作为成员。
从根本上讲:接口是一个中间层,使得调用和实现完全分离,解除了上下游的耦合,调用方不再依赖于某一个具体的模块,而是依赖于一个接口。举个例子:
本文为极客时间《Go语言核心36讲》的学习笔记,梳理了相关的知识点。
我们看下面向对象的定义:
面向对象程序设计(Object Oriented Programming,OOP)是一种计算机编程架构。OOP的一条基本原则是计算机程序由单个能够起到子程序作用的单元或对象组合而成。OOP达到了软件工程的三个主要目标:重用性、灵活性和扩展性。OOP=对象+类+继承+多态+消息,其中核心概念是类和对象。
本质上讲,它是一种对于世界的认知,是一种思想,它认为世间万物都有具体的属性组成,把拥有相同属性的事务抽象为一个集体,就是这一类事务的对象。举个例子:一只狗,它应该有四条腿,它有鼻子,它的叫声是“汪汪汪”。
源码地址: https://github.com/golang/time
在我看来,这块代码写的非常好,至少有三点非常值得我们学习:
本文为极客时间《Go语言核心36讲》的学习笔记,梳理了相关的知识点。
Map数据结构有多种多样的名称:哈希表,散列,字典,Map,键值对,这些都是广义上的Map数据类型。Map类型的数据结构在大多数的编程语言中都有支持,日常使用最多,面试最经常问到的是GO语言中的Map和Redis中的字典。
这是GO语言官方文档的描述:
Maps are a convenient and powerful built-in data structure that associate values of one type (the key) with values of another type (the element or value).
本文为极客时间《Go语言核心36讲》的学习笔记,并结合源码,梳理了相关的知识点。
Go 语言的切片类型属于引用类型,同属引用类型的还有字典类型、通道类型、函数类型等;而 Go 语言的数组类型则属于值类型,同属值类型的有基础数据类型以及结构体类型。简单的说,数组类型的长度是固定的,而切片类型是可变长的。数组的容量永远等于其长度,都是不可变的。
项目地址 https://github.com/patrickmn/go-cache
假如,我们正在请求一个接口,获取用户的个人信息,这个接口需要1秒钟的时间进行数据查询,回溯,拼接等逻辑,然后再返回给我们。在这一秒钟内,服务因为某些原因,出BUG了,Panic了,那么服务可能会爆出500的错误。如果是被人为的关闭了,会发生什么?应该发生什么?
相关信息
这是架构领域的一道经典面试题。解决方案就是:优雅关闭。