author:魏静崎
2025年3月12日
面试题
后端核心基础(必答)
- TCP 与 UDP 的核心差异是什么?HTTP 为何选择基于 TCP 协议?
TCP是面向连接的,是可靠连接;UDP是面向报文的,是无连接协议,是尽最大努力交付的。
HTTP选择TCP是因为可靠性需求和序列化传输的必要性。 - HTTPS 的实现原理
HTTPS结合HTTP和SSL来提供安全的数据传输。 - 设计一个 RESTful API 时需遵循哪些核心原则?
以资源为中心、无状态、可扩展性、可缓存性等。 - 数据库索引的实现机制是什么?B+ 树相比 B 树的优势是什么?
索引是通过B+树实现的。
B+树同时支持顺序索引和随机索引,其查询效率更高。 - 什么是事务的 ACID 特性?如何保证事务的原子性?
原子性、一致性、隔离性、持久性。
保证同时成功或失败。 - 进程和线程的区别是什么?Linux 中如何查看进程信息?
进程是操作系统进行资源分配的基本单位,线程是操作系统进行运算调度的最小单元。
使用ps 或 top命令 - 分库分表的策略有哪些?如何解决分表后的跨表查询问题?
水平分库,水平分表, 垂直分库,垂直分表。
通过搜索后回答:应用层聚合、中间件代理等
Golang核心基础****(除必答外可不答)
并发安全性****(必答)
- 问题:解释并发安全性,如何通过互斥锁、通道、原子操作实现?
并发安全是指多个goroutine同时访问共享资源时,确保数据的一致性和正确性。
可以通过在访问共享资源前加锁,访问完成后解锁。
通过通道的发送和接收操作来同步goroutine。
atomic包提供的原子操作来保证操作是原子的。 - 延伸:读写锁(RWMutex)适用场景?sync.Map与普通Map的线程安全差异?
读写锁适用于读多写少的场景,sync.Map是并发安全的
- 问题:解释并发安全性,如何通过互斥锁、通道、原子操作实现?
值类型与引用类型
- 问题:Go中哪些类型是值类型(如数组、结构体)?哪些是引用类型(如切片、map、channel)?内存分配差异?
基本数据、数组、结构体类型是值类型,切片、map、channel是引用类型
- 问题:Go中哪些类型是值类型(如数组、结构体)?哪些是引用类型(如切片、map、channel)?内存分配差异?
defer机制****(必答)
- 问题:defer的执行顺序?如何用defer实现资源释放和panic捕获?延迟函数的参数求值时机?
defer是放入栈中因此是先入后出。
在defer中进行资源的关闭和结合recover捕获panic。
因为会入栈,所以是在入栈时就会传参
- 问题:defer的执行顺序?如何用defer实现资源释放和panic捕获?延迟函数的参数求值时机?
接口与反射
- 问题:接口的动态类型如何比较?反射获取结构体Tag的原理?
接口的动态类型比较可以通过 类型断言 或 反射 实现。
interface类型有个(value,type)对,而反射就是检查interface的这个(value, type)对的。
- 问题:接口的动态类型如何比较?反射获取结构体Tag的原理?
Context (必答)
- 问题:设计的目的是什么?常用的 context 的应用场景?
context用于管理 goroutine 生命周期,传递上下文
常用于取消goroutine或者超时控制
- 问题:设计的目的是什么?常用的 context 的应用场景?
中间件与系统设计****(除必答外可不答)
MySQL 应用题(必答)
用户分数统计
有一个用户科目分数表 id/user_id/course_id/score,每个人均有2门课程,请写出以下sql
总分数最高的人
SELECT user_id, SUM(score) AS total_score
FROM scores
GROUP BY user_id
ORDER BY total_score DESC
LIMIT 1;总分大于150分,平均分小于90分的人数有几个
通过搜索后回答:
SELECT COUNT(*) AS user_count
FROM (
SELECT user_id
FROM scores
GROUP BY user_id
HAVING SUM(score) > 150 AND AVG(score) < 90
) AS subquery;每科满分 100 分,统计每科优/良/及格/未及格的人数
SELECT
course_id,
SUM(CASE WHEN score >= 90 THEN 1 ELSE 0 END) AS excellent_count,
SUM(CASE WHEN score >= 80 AND score < 90 THEN 1 ELSE 0 END) AS good_count,
SUM(CASE WHEN score >= 60 AND score < 80 THEN 1 ELSE 0 END) AS pass_count,
SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS fail_count
FROM scores
GROUP BY course_id;
相似收藏夹
在一个内容推荐平台中,用户创建并管理自己的收藏夹(可多个)。平台需要设计一个算法,能够衡量不同收藏夹之间的相似度,从而为用户推荐相关的收藏夹。
问题描述
给定一个目标收藏夹 A 和平台上的其他收藏夫 B,设计一个相似度算法,能够量化这些收藏夹的相似程度。
算法要求
相似度计算需要考虑以下因素:
两个收藏夹的共同作品数量
共同作品在总作品中的比例
对不同层级的收藏夹进行区分
相似度分数计算公式为:
1
2
3
4
5相似度 = (y + (y/x)) / (2n)
其中:
x = 目标收藏夹 B 的总作品数
y = 目标收藏夹 A 和 B 的共同作品数
n = 目标收藏夹 A 的作品总数实现要求:
- 建表语句以及取某个收藏夹相似的收藏夹 top 10 的 sql
Redis高频场景
- 常见的数据类型以及应用场景(必答)
常见数据类型包括:String(普通信息、计数器)、Hash(对象信息)、List(消息队列)、Set(去重数据-标签、用户)、Zset(排行榜) - 缓存穿透/雪崩/击穿的解决方案
缓存穿透:对不存在的数据缓存空值(null
),并设置较短的过期时间。使用布隆过滤器(Bloom Filter)过滤无效请求。
缓存雪崩:使用高可用redis集群
缓存击穿:使用分布式锁加载数据、设置数据不过期
- 常见的数据类型以及应用场景(必答)
- 分布式锁实现
在golang的redis包中有SetNX(context.Background(), key, 1, expiration) 方法
- 分布式锁实现
- 注册发送验证码的场景,实现每个自然日最多发送 5 条(必答)
设置过期的截止时间为当天24点的缓存,value为当天发送次数,每次发送判断是否达到五次,不到的话使用incr自增。
- 注册发送验证码的场景,实现每个自然日最多发送 5 条(必答)
- 注册发送验证码的场景,实现任意 24h的时间滑块最多发送 5 条(必答)
通过搜索后回答:使用 Redis 的List
和Lua
脚本实现滑动窗口限流。
- 注册发送验证码的场景,实现任意 24h的时间滑块最多发送 5 条(必答)
Kafka核心机制
如何保证消息顺序性?(必答)
Kafka只能保证分区顺序性,无法保证全局顺序性,因此可以使用相同的Key确保消息进入同一个分区消费者组Rebalance触发场景?
零拷贝技术如何提升吞吐?
Elasticsearch优化
- 倒排索引原理?(必答)
把文件ID对应到关键词的映射转换为关键词到文件ID的映射,每个关键词都对应着一系列的文件,这些文件中都出现这个关键词。 - 深分页性能问题如何解决(Search After vs Scroll)?
通过搜索后回答:
Search After: 基于上一页的排序值进行分页,避免全局扫描。
Scroll: 创建快照,基于游标分页,适合大数据量导出场景。
- 倒排索引原理?(必答)
系统设计实战
- 设计千级QPS的秒杀系统,需包含库存扣减(Redis+Lua)、限流熔断(令牌桶)、异步削峰(Kafka)
使用Redis存储库存,通过Lua脚本保证原子性。- 使用令牌桶算法限制请求速率。将秒杀请求写入 Kafka,由消费者异步处理。
- 设计千级QPS的秒杀系统,需包含库存扣减(Redis+Lua)、限流熔断(令牌桶)、异步削峰(Kafka)
编码与算法****(可只选择一个题目回答)
并发安全LRU缓存
- 要求:基于sync.Mutex实现,支持Get/Put操作,时间复杂度O(1)
链表环检测
- 题目:快慢指针法判断链表是否有环,并找到环入口节点
归并排序大文件
- 场景:10GB文件内存仅1GB,如何分治排序?考察外部排序与IO优化
数组去重
- 有个 int 类型的数组,想实现数组内去重,并保留原有排序
func removeChongfuNums(nums []int) []int {
seen := make(map[int]bool)
result := []int{}
for _, num := range nums {
if !seen[num] {
seen[num] = true
result = append(result, num)
}
}
return result
}
- 有个 int 类型的数组,想实现数组内去重,并保留原有排序
进阶原理与调优****(可只选择一个题目回答)
GC机制
- 问题:三色标记法流程?如何通过sync.Pool减少GC压力?
Goroutine调度
- 问题:GMP模型中的工作窃取机制?阻塞操作(如系统调用)如何触发调度?
- work stealing机制:当本线程无可运行的G时,尝试从其他线程绑定的P偷取G,而不是销毁线程。
- hand off机制:当本线程因为G进行系统调用阻塞时,线程释放绑定的P,把P转移给其他空闲的线程执行。
- 问题:GMP模型中的工作窃取机制?阻塞操作(如系统调用)如何触发调度?
内存逃逸分析
- 案例:局部变量何时会逃逸到堆?如何通过
go build -gcflags="-m"
检测?
- 案例:局部变量何时会逃逸到堆?如何通过
性格与软技能评估****(可只选择一个题目回答)
项目深度复盘
- 问题:描述一个你解决过的复杂BUG,如何定位根本原因?如何验证修复效果?
背景:预算数据(分为实际数据和预测数据,实际存在于一张表中)需要临时复制一份进行每月数据的导入。
我负责进行预测数据的导入,因为会出现新的预算包因此需要根据导入数据进行创建,导入完成后当前端点击确认,两部分数据需要同时写回原始表。发现写回的预测数据只存在部分,之后通过接口返回数据查询以及在写回方法的多个断点查询数据阶段正确性发现,写回部分对年度数据的汇总(更新年度数据后需要重新更新月度数据)在写回后需要二次更新才能保证正确性。
效果的验证来自于数据库中的数据累加相同。
- 问题:描述一个你解决过的复杂BUG,如何定位根本原因?如何验证修复效果?
技术决策说服力
- 场景:团队计划采用新技术(如Kafka),你如何评估风险并推动落地?
抗压能力验证
- 案例:线上服务突发CPU飙升,如何快速定位Goroutine泄漏(pprof+火焰图)?
思维题(可只选择一个题目回答)
一头牛800 kg,桥承重 700 kg ,怎么让牛过桥?
实际上是压力的问题,因此可以减小压力或者分摊压力或增大承受力,最不好的方法就是分割整个牛(bushi)。可以考虑使用气球等减少压力,其次可以考虑使用一个比桥长的物体承受牛的压力,然后通过多出的长度将压力分摊到地面上,或者加固桥梁增大支撑力。将3×4的方格纸用四种不同方法分割成完全相同的两部分,要求保持方格完整。
红墨水瓶含5毫升蓝墨水,蓝墨水瓶含5毫升红墨水。哪个瓶子中“外来墨水”占比更高?
- 本文作者: 魏静崎
- 本文链接: https://slightwjq.github.io/2025/03/12/新片场面试题/
- 版权声明: 该文章来源及最终解释权归作者所有