首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >2026Go面试宝典,万字总结和分享(一)

2026Go面试宝典,万字总结和分享(一)

作者头像
王中阳AI编程
发布2026-03-17 20:15:58
发布2026-03-17 20:15:58
1020
举报
文章被收录于专栏:Go语言学习专栏Go语言学习专栏

Hello,大家好!我是阳哥。

最近我们团队把过往的Go面试题都整理了一下,做成了一个2026年Go最新最全面试题pdf文档,因为篇幅有限,为了方便大家阅读和学习,我打算把这份文档里的精华内容,分几期文章分享出来。

这是第一篇,我们先来聊聊 Go 语言的基础对比和一些核心概念,精选了 20 道高频面试题,希望能助你一臂之力!


Go 与其他语言对比及基础

1、什么是面向对象

在了解 Go 语言是不是面向对象(简称:OOP) 之前,我们必须先知道 OOP 是啥,得先给他 “下定义”,根据 Wikipedia 的定义,我们梳理出 OOP 的几个基本认知:

  • 面向对象编程(OOP)是一种基于 “对象” 概念的编程范式,它可以包含数据和代码:数据以字段的形式存在(通常称为属性或属性),代码以程序的形式存在(通常称为方法)。
  • 对象自己的程序可以访问并经常修改自己的数据字段。
  • 对象经常被定义为类的一个实例。
  • 对象利用属性和方法的私有/受保护/公共可见性,对象的内部状态受到保护,不受外界影响(被封装)。

基于这几个基本认知进行一步延伸出,面向对象的三大基本特性:

  • 封装
  • 继承
  • 多态

2、Go 语言和 Java 有什么区别?

特性

Go

Java

函数重载

不允许(函数/方法名必须唯一)

允许

执行速度

编译型语言,速度通常更快

运行在 JVM 上,速度相对较慢

多态

默认不支持(需通过接口实现)

默认允许

路由配置

使用 HTTP 协议进行路由配置

使用 Akka.routing 等工具配置

扩展性

代码可自动扩展到多个核心

并不总是具有足够的可扩展性

继承方式

匿名组合(支持多重组合/伪继承)

extends 关键字(不支持多继承)

3、Go 是面向对象的语言吗?

是的,也不是。原因是:

  1. Go 有类型和方法,并且允许面向对象的编程风格,但没有类型层次。
  2. Go 中的 "接口 "概念提供了一种不同的方法,我们认为这种方法易于使用,而且在某些方面更加通用。还有一些方法可以将类型嵌入到其他类型中,以提供类似的东西,但不等同于子类。
  3. Go 中的方法比 C++ 或 Java 中的方法更通用:它们可以为任何类型的数据定义,甚至是内置类型,如普通的、"未装箱的 "整数。它们并不局限于结构(类)。
  4. Go 由于缺乏类型层次,Go 中的 "对象 "比 C++ 或 Java 等语言更轻巧。

4、Go 实现面向对象编程

封装

面向对象中的 “封装” 指的是可以隐藏对象的内部属性和实现细节,仅对外提供公开接口调用,这样子用户就不需要关注你内部是怎么实现的。

在 Go 语言中的属性访问权限,通过首字母大小写来控制:

  • 首字母大写,代表是公共的、可被外部访问的。
  • 首字母小写,代表是私有的,不可以被外部访问。
继承

面向对象中的 “继承” 指的是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

在 Go 语言中,是没有类似 extends 关键字的这种继承的方式,在语言设计上采取的是组合的方式

多态

面向对象中的 “多态” 指的同一个行为具有多种不同表现形式或形态的能力,具体是指一个类实例(对象)的相同方法在不同情形有不同表现形式。

在 Go 语言中,多态是通过接口来实现的。只要不同的类型实现了同一个接口,它们就可以作为该接口类型被调用,从而实现多态。

5、Go 语言和 Python 的区别

特性

Go

Python

范例

基于并发编程范式的过程编程语言

基于 OOP 的多范式,命令式和函数式

类型化

静态类型(编译时捕获错误)

动态类型

并发

内置并发机制 (Goroutine/Channel)

无内置并发机制 (需依赖库)

安全性

强类型,编译型,更安全

强类型,解释型,运行时检查

内存管理

允许程序员一定程度管理内存

完全自动化,由 VM 管理

语法

基于括号 {}

使用缩进指示代码块

6、为什么选择 Golang

  1. 高性能-协程:golang 源码级别支持协程,实现简单;对比进程和线程,协程占用资源少,能够简洁高效地处理高并发问题。
  2. 学习曲线容易-代码极简:Go 语言语法简单,上手非常快。
  3. 效率:快速的编译时间,开发效率和运行效率高。
  4. 出身名门、血统纯正:Go 语言出自 Google 公司。
  5. 自由高效:组合的思想、无侵入式的接口。
  6. 强大的标准库-生态:背靠谷歌,生态丰富。
  7. 部署方便:二进制文件,Copy 部署。
  8. 简单的并发:Go 语言的 Goroutine 和 Channel 这两个神器简直就是并发和异步编程的巨大福音。
  9. 稳定性:Go 拥有强大的编译检查、严格的编码规范和完整的软件生命周期工具。

7、Golang 缺点

  1. 右大括号不允许换行,否则编译报错。
  2. 不允许有未使用的包或变量。
  3. 错误处理原始,基本依靠返回错误是否为空来判断函数是否执行成功,if err != nil 语句较多。
  4. []interface{} 不支持下标操作。
  5. struct 没有构造和析构,一些资源申请和释放动作不太方便。
  6. 仍然保留 C/C++ 的指针操作。

8、Golang 中 make 和 new 的区别?

共同点: 给变量分配内存

不同点对比:

特性

new

make

作用变量类型

任意类型

仅限 slice, map, channel

返回类型

指针 (*T)

变量本身 (T)

内存状态

分配空间并清零

分配空间并初始化

9、在 for range 循环中,变量的地址会发生变化吗?

这个问题的答案取决于使用的 Go 版本。

  • Go 1.21 及之前:循环变量(如 a, b)在内存中只有一份。每次迭代都会将新值覆盖写入这同一块内存,因此它们的地址在循环中始终不变。
  • Go 1.22 开始:语言语义得到了优化。现在,每次迭代都会创建全新的循环变量,拥有独立的地址。

10、Go defer,多个 defer 的顺序,defer 在什么时机会修改返回值?

作用:defer 延迟函数,释放资源,收尾工作;如释放锁,关闭文件,关闭链接;捕获 panic。

顺序:多个 defer 调用顺序是 LIFO(后入先出),defer 后的操作可以理解为压入栈中。

执行流程

修改返回值时机:defer 可以修改函数最终返回值,修改时机主要是在有名返回值或者函数返回指针的情况下。

11、uint 类型溢出问题

超过最大存储值如 uint8 最大是 255。

代码语言:javascript
复制
var a uint8 = 255
var b uint8 = 1
// a + b = 0

总之类型溢出会出现难以意料的事,需要注意。

12、能介绍下 rune 类型吗?

rune 相当 int32

Golang 中的字符串底层实现是通过 byte 数组的,中文字符在 unicode 下占 2 个字节,在 utf-8 编码下占 3 个字节,而 golang 默认编码正好是 utf-8。

类型

等同于

常用场景

byte

uint8

处理 ASCII 字符

rune

int32

处理 Unicode 或 UTF-8 字符

13、Golang 中解析 tag 是怎么实现的?反射原理是什么?

Go 中解析的 tag 是通过反射实现的。

反射原理:反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。反射将接口变量转换成反射对象 Type 和 Value;反射可以通过反射对象 Value 还原成原先的接口变量;反射可以用来修改一个变量的值。

常见的库如 gorm, json, yaml, gin.Bind() 等都是通过反射来实现 tag 解析的。

14、调用函数传入结构体时,应该传值还是指针?

Golang 都是传值。

传递方式

描述

建议场景

值传递

复制一份实参传递给函数。函数内修改不影响原数据。

结构体较小,且不需要修改原数据时。

引用传递 (指针)

复制指针。函数内修改可能影响原数据。

结构体较大(避免大内存拷贝),或需要修改原数据时。

15、Goroutine 什么情况下会阻塞?

主要分为以下 4 种场景:

  1. 同步/通信阻塞:由于原子、互斥量或通道操作调用导致 Goroutine 阻塞。
  2. 网络/IO 阻塞:由于网络请求和 IO 操作导致 Goroutine 阻塞(Go 提供了 NetPoller 来处理)。
  3. 系统调用阻塞:当调用一些系统方法的时候(如文件 I/O),如果系统方法调用的时候发生阻塞。
  4. Sleep 操作:如果在 Goroutine 去执行一个 sleep 操作。

16、讲讲 Go 的 select 底层数据结构和一些特性?

Go 的 select 为 golang 提供了多路 IO 复用机制。

Select 执行流程:

Select 的特性:

  1. select 语句允许不包含任意 case 语句(即空 select)。
  2. select 仅支持管道,而且是单协程操作。
  3. 每个 case 语句仅能处理一个管道,要么读要么写。
  4. 多个 case 语句的执行顺序是随机的。
  5. 存在 default 语句,select 将不会阻塞,但是存在 default 会影响性能。
  6. 出现读写 nil 的 channel 该分支会忽略,在 nil 的 channel 上操作则会报错。

17、讲讲 Go 的 defer 底层数据结构和一些特性?

每个 defer 语句都对应一个 _defer 实例,多个实例使用指针连接起来形成一个单连表,保存在 goroutine 数据结构中。每次插入 _defer 实例,均插入到链表的头部,函数结束再一次从头部取出,从而形成后进先出的效果。

Defer 的规则总结

  1. 延迟函数的参数是 defer 语句出现的时候就已经确定了的。
  2. 延迟函数执行按照后进先出的顺序执行。
  3. 延迟函数可能操作主函数的返回值。
  4. 申请资源后立即使用 defer 关闭资源是个好习惯。

18、单引号,双引号,反引号的区别?

符号

类型

含义

是否支持转义

单引号'

rune / byte

表示字符 (int32/uint8)

支持

双引号"

string

字符串 (字符数组)

支持

反引号`

string

字符串字面量 (Raw String)

不支持 (所见即所得)

19、Go 出现 panic 的场景

  • 数组/切片越界
  • 空指针调用
  • 过早关闭 HTTP 响应体
  • 除以 0
  • 向已经关闭的 channel 发送消息
  • 重复关闭 channel
  • 关闭未初始化的 channel
  • 未初始化 map(赋值时)
  • 跨协程的 panic 处理
  • sync 计数为负数
  • 类型断言不匹配

20、Go 里面如何实现 Set?

Go 中是不提供 Set 类型的。

我们可以利用 map 类型来实现一个 set。因为 map 的 key 是不能重复的。 Value 我们可以用一个常量来代替,比如一个空结构体 struct{}。实际上空结构体不占任何内存,使用空结构体,能够帮我们节省内存空间,提高性能。


结语

好了,今天的分享就先到这里。

这 20 道题只是《Go 最新最全面试题》中的冰山一角。因为篇幅原因,剩下的内容我会在后面的文章中继续分享。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-12-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 王中阳 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Go 与其他语言对比及基础
    • 1、什么是面向对象
    • 2、Go 语言和 Java 有什么区别?
    • 3、Go 是面向对象的语言吗?
    • 4、Go 实现面向对象编程
      • 封装
      • 继承
      • 多态
    • 5、Go 语言和 Python 的区别
    • 6、为什么选择 Golang
    • 7、Golang 缺点
    • 8、Golang 中 make 和 new 的区别?
    • 9、在 for range 循环中,变量的地址会发生变化吗?
    • 10、Go defer,多个 defer 的顺序,defer 在什么时机会修改返回值?
    • 11、uint 类型溢出问题
    • 12、能介绍下 rune 类型吗?
    • 13、Golang 中解析 tag 是怎么实现的?反射原理是什么?
    • 14、调用函数传入结构体时,应该传值还是指针?
    • 15、Goroutine 什么情况下会阻塞?
    • 16、讲讲 Go 的 select 底层数据结构和一些特性?
    • 17、讲讲 Go 的 defer 底层数据结构和一些特性?
    • 18、单引号,双引号,反引号的区别?
    • 19、Go 出现 panic 的场景
    • 20、Go 里面如何实现 Set?
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档