最近参与了一家知名游戏公司的后端开发岗位一面,面试官围绕技术栈和基础原理展开了深入提问。现将涉及的核心问题整理并稍作延伸,希望能为准备类似面试的后端开发者提供参考。
1. Go 的 channel 有缓冲与无缓冲的区别
在 Go 语言中,channel 是协程间通信的主要方式。无缓冲 channel 要求发送和接收操作必须同时就绪,否则会阻塞,确保了同步通信。而有缓冲 channel 则拥有一个固定大小的队列,发送方在队列未满时可以立即返回,接收方在队列非空时可以立即取数据,这提供了异步通信的能力,能一定程度解耦生产消费速度。
2. Go 的 defer 执行顺序,以及读写锁和互斥锁的区别
defer 语句的函数调用会被压入一个栈中,在当前函数返回前按照后进先出(LIFO)的顺序执行。关于锁,互斥锁(sync.Mutex)只允许一个 goroutine 访问共享资源,而读写锁(sync.RWMutex)允许多个读操作并发,但写操作是互斥的,这在读多写少的场景下能显著提升性能。
3. Go 的 map 是否线程安全?不安全,如何让多线程访问安全?
Go 内建的 map 不是线程安全的,并发读写会导致 panic。要让多个 goroutine 安全访问,常见的做法是加锁,比如使用 sync.Mutex 或 sync.RWMutex 来保护整个 map 或关键代码段。另一种方案是使用 sync.Map,它为一些特定场景(如键值对很少变化、大量读操作)提供了开箱即用的线程安全访问。
4. Go 协程的调度如何实现?GMP 模型
Go 的调度器采用 GMP 模型来实现协程的高效调度。G 代表 Goroutine(协程),M 代表 Machine(系统线程),P 代表 Processor(逻辑处理器)。P 维护一个本地 Goroutine 队列,M 需要绑定一个 P 来执行 G。调度器通过 work-stealing 等算法在 M 间均衡负载,并利用系统调用和非阻塞 I/O 来避免线程阻塞,从而实现高并发。
5. HTTP 请求的完整流程,以及 TCP 和 UDP 的区别
一次典型的 HTTP 请求涉及 DNS 解析、建立 TCP 连接、发送请求报文、接收响应报文、解析内容等步骤。TCP 和 UDP 都是传输层协议,但核心区别在于:TCP 是面向连接的、可靠的、提供流量控制和拥塞控制的流式协议;UDP 则是无连接的、不可靠的、尽最大努力交付的数据报协议,延迟更低但可能丢失或乱序。
6. MySQL 索引与索引覆盖
索引是帮助 MySQL 高效获取数据的数据结构,常见的有 B+Tree 索引。索引覆盖是指一个查询只需要通过索引就能获取所有需要的数据列,而无需回表查询数据行,这可以显著减少 I/O 操作,提升查询性能。例如,如果索引包含了 SELECT 语句中所有的列,就可以实现覆盖索引。
7. Redis 缓存“三剑客”与数据结构
常说的 Redis “三剑客”通常指其核心功能:作为缓存、消息队列(使用 List/PubSub)和分布式锁(使用 SETNX 等命令)。Redis 支持丰富的数据结构,如 String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Sorted Set(有序集合),以及 Bitmaps、HyperLogLogs 等,每种结构适用于不同的业务场景。
8. GIN 框架的优缺点
GIN 是 Go 语言中一个高性能的 Web 框架。优点包括:路由性能极高(基于 httprouter)、中间件支持灵活、易于学习和使用、拥有良好的社区生态。缺点可能是:相比一些全功能框架(如 Beego),内置的“电池”较少,需要更多依赖第三方库来构建完整应用;其极致性能的追求有时会牺牲一些语法糖或开发便利性。
9. Sync.WaitGroup 的使用方法
sync.WaitGroup 用于等待一组 goroutine 执行完毕。主要使用三个方法:Add(delta int) 设置等待的 goroutine 数量;Done() 表示一个 goroutine 完成,内部计数器减一;Wait() 会阻塞,直到内部计数器归零。它常用于主协程等待所有子任务完成后才继续执行的场景。
10. Linux 基本操作命令:如何查看内存与磁盘使用量
查看内存使用情况常用 free -h 命令,它以人类可读格式显示物理内存和交换空间的使用情况。查看磁盘用量则使用 df -h 命令,它能列出所有挂载点的磁盘空间使用情况。这两个命令是 Linux 系统管理和故障排查的基础。
11. SQL 注入与常见网络攻击
SQL 注入是一种通过将恶意 SQL 代码插入到输入参数中,从而欺骗服务器执行非预期命令的攻击方式。防御方法包括使用参数化查询(预编译语句)、对输入进行严格校验和过滤等。其他常见网络攻击还有跨站脚本(XSS)、跨站请求伪造(CSRF)、分布式拒绝服务(DDoS)等,了解其原理对构建安全的后端系统至关重要。
12. 反问环节
通常在面试结尾,面试官会留出时间让候选人提问。这是一个了解团队技术栈、项目挑战和职业发展机会的好时机。
以上问题覆盖了后端开发,特别是游戏服务端方向的核心知识面。在实际准备中,除了理解概念,最好能结合具体场景思考。如果想深入探讨某个技术点或查看更多实战分享,欢迎来 云栈社区 交流讨论。