Interface 面试题

1. Go 语言中 interface 的底层原理是怎样的?

Go 的 interface 底层实现主要依赖于两个结构体:efaceiface

  • eface:表示空接口(interface{}),包含两个指针:_type 指向类型信息,data指向实际数据。
  • iface:表示非空接口,包含两个指针:tab 指向接口方法表和类型信息,data 指向实际数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type eface struct {
_type *_type
data unsafe.Pointer
}

type iface struct {
tab *itab
data unsafe.Pointer
}

type itab struct {
inter *interfacetype // 接口类型
_type *_type // 具体类型
fun [N]uintptr // 方法地址表
}

2. iface 和 eface 的区别是什么?

核心区别在于是否包含方法信息

3. 类型转换和断言的区别是什么?

对比项 类型转换(conversion) 类型断言(assertion)
本质 把一种类型“转换”为另一种类型 从接口中“取出”真实类型
使用对象 普通类型之间 接口类型
是否改变数据 可能重新解释/拷贝数据 不改变数据,只检查动态类型
是否要求类型兼容 必须可转换 必须接口里真实存的就是该类型
语法 T(x) x.(T)
失败行为 编译期检查 运行期检查
常见场景 int→float64、[]byte→string any/interface{} 获取真实值

4. Go 语言 interface 有哪些应用场景?

Go 语言的 interface 主要有几个核心应用场景:

  1. 依赖注入和解耦。通过定义接口抽象,让高层模块不依赖具体实现,比如定义一个 UserRepo 接口,具体可以是 MySQL、Redis 或者 Mock 实现。这样代码更容易测试和维护,也符合 SOLID 原则。

  2. 多态实现。比如定义一个 Shape 接口包含 Area() 方法,不同的图形结构体实现这个接口,就能用统一的方式处理各种图形。这让代码更加灵活和可扩展。

  3. 标准库中大量使用 interface 来提供统一 API。像 io.Readerio.Writer 让文件、网络连接、字符串等都能用统一的方式操作;sort.Interface 让任意类型都能使用标准库的排序算法。

  4. 还有类型断言和反射的配合使用,比如 JSON 解析、ORM 映射等场景,先用 interface{} 接收任意类型,再通过类型断言或反射处理具体逻辑。

  5. 插件化架构也 heavily 依赖 interface。比如 Web 框架的中间件、数据库驱动、日志组件等,都通过接口定义规范,让第三方能够轻松扩展功能。

5. 接口之间可以相互比较吗?

接口值之间可以使用 ==!= 进行比较

接口值在与非接口值进行比较时,Go 会先将非接口值尝试转换为接口值再进行比较


参考资料: