lynpt字节SRE二面

根据口述整理,岗位方向偏 SRE。整体考察重点是 K8s、排障方法、学习能力、计算机基础和现场算法。

面试画像#

这场二面围绕“能否快速学习并解决线上问题”展开。面试官持续追问 K8s 的真实使用、学习路径、排障沉淀和遇到陌生问题时的探索方式,基础题覆盖操作系统、网络、数据结构与复杂度,最后用最长回文子串检查代码能力。

完整题目#

  1. 自我介绍。(两个小项目 + 一篇 CCF C 会议 + 一篇 EI 普会)
  2. 你最近在学习什么技术?(回答 K8s)
  3. 你 K8s 在学校或者什么场景下用过吗?
  4. 能不能介绍一下 K8s 的架构,申请 Pod 的一个执行流程?
  5. 一台 worker 挂掉了,这个信息如何发回数据平面?
  6. 你自己学 K8s 的时候遇到了什么问题,你是怎么解决的?
  7. 如果你不知道一个东西的最佳实践在哪里,你应该怎么做?你是怎么探索的?
  8. K8s 中,你想把某一个 Pod 的东西复制到宿主机中,你应该怎么做?
  9. 这个和 Docker 的 cp 命令有什么区别?
  10. 你在学习过程中碰到这些问题你是怎么解决的?你有哪些路径可以解决?
  11. 进程和线程的区别?
  12. 线程间通信有哪些?
  13. 死锁的四个条件是什么?
  14. 死锁避免?
  15. 你在学校的时候有没有做过这方面实践?或者写过什么代码吗?(回答 Go 协程等)
  16. TCP 三次握手和四次挥手,为什么不能多了少了?
  17. 挥手中的 TIME_WAIT 是做什么用的?
  18. 解释一下 O(1)、O(n)、O(log n)、O(n^2),并举例场景。
  19. 数组和链表的区别是什么?优缺点是什么?有什么使用场景?
  20. 数组和指针哪个更适合大规模的读取和写入?
  21. 服务器负载较高你会怎么排查?
  22. 我需要你在一周内学会 Flink(任意一个产品),你需要怎么学习?学习路径是什么样子的?
  23. 你自己记录的一些排错文档有几篇?是多长时间沉淀下来的?
  24. 算法:求一个字符串的最长回文子串。

参考答案(AI 生成)#

以下答案由 AI 生成,仅供面试复盘参考。

K8s 重点准备#

K8s 架构怎么讲#

可直接说: K8s 可以分成控制面和工作节点。控制面负责声明式状态管理,核心组件包括 kube-apiserver、etcd、scheduler、controller-manager;工作节点负责真正运行容器,核心组件包括 kubelet、容器运行时、kube-proxy、CNI 网络插件。

Pod 创建流程可以按这条链路讲:

  1. 用户通过 kubectl 或客户端提交 Pod / Deployment。
  2. 请求进入 kube-apiserver,经过认证、鉴权、准入控制。
  3. API Server 把对象写入 etcd。
  4. Scheduler 监听到未绑定节点的 Pod,按资源、亲和性、污点容忍等规则选择节点。
  5. Scheduler 写回 binding 结果。
  6. 目标节点上的 kubelet watch 到属于自己的 Pod。
  7. kubelet 调用 CRI 创建 sandbox 和容器。
  8. CNI 配置网络,挂载 volume,拉取镜像,启动容器。
  9. kubelet 持续上报 PodStatus 和 NodeStatus。

Worker 节点挂掉怎么感知#

可直接说: kubelet 会周期性向 API Server 上报 NodeStatus,并更新 Lease 心跳。节点异常后心跳停止,Node Controller 根据超时判断节点进入 NotReady,随后触发 Pod 驱逐、Endpoint 更新和重调度。

回答时可以补这几个关键词:

  1. kubelet 心跳和 Lease 是节点存活信号。
  2. API Server 是所有状态写入入口。
  3. Node Controller 负责节点健康判断。
  4. EndpointSlice / Service 会摘除异常节点上的不可用后端。
  5. Deployment / ReplicaSet 会把副本补到健康节点。

kubectl cp 怎么用#

可直接说: 使用 kubectl cp,格式是:

kubectl cp <namespace>/<pod>:<container-path> <local-path> -c <container-name>
kubectl cp <local-path> <namespace>/<pod>:<container-path> -c <container-name>

常见注意点:

  1. 多容器 Pod 需要指定 -c。
  2. 容器内需要有 tar,因为 kubectl cp 底层依赖 tar 流。
  3. 权限受 Pod 内用户和目标路径影响。
  4. 大文件可以用 kubectl exec + tar 管道处理。

kubectl cp 和 docker cp 的区别#

可直接说: docker cp 面向本机 Docker daemon 和单机容器文件系统;kubectl cp 面向 K8s 集群里的 Pod,路径里需要 namespace、Pod、container,数据通道经过 API Server、kubelet 和容器执行环境。

SRE 排障准备#

服务器负载较高怎么排查#

可直接说: 我会先看负载类型,再按 CPU、内存、磁盘、网络、应用日志和依赖服务逐层定位。

排查路径:

  1. uptime / top 看 load average 和 CPU 使用情况。
  2. pidstat / top -H 定位高 CPU 进程和线程。
  3. free / vmstat 看内存、swap、上下文切换。
  4. iostat / iotop 看磁盘 I/O。
  5. ss / netstat / sar -n 看连接数、重传、网络吞吐。
  6. 查看应用日志、错误率、慢请求、GC、依赖超时。
  7. 结合监控曲线确认故障开始时间和变更记录。

可直接说: 我会先建立产品地图,再做最小 Demo,然后补核心机制,最后输出排障文档和面试表达。

7 天路径:

  1. Day 1:看官网快速开始,理解 Flink 解决什么问题。
  2. Day 2:跑通本地 WordCount、Kafka 输入、窗口聚合 Demo。
  3. Day 3:学习 JobManager、TaskManager、Slot、Checkpoint、State。
  4. Day 4:整理常见场景:实时 ETL、实时统计、告警、流批一体。
  5. Day 5:排查一次失败任务,记录日志、Web UI、Checkpoint、反压。
  6. Day 6:读一篇生产实践文章,提炼最佳实践。
  7. Day 7:产出一页架构图、一份 Demo、一份排障清单、一套面试回答。

最佳实践怎么探索#

可直接说: 我的路径是官方文档优先,其次看成熟云厂商文档、社区 issue、生产实践文章和源码注释,最后用小实验验证结论。

可展开为:

  1. 官方文档确认概念和推荐配置。
  2. 云厂商文档确认生产落地方式。
  3. GitHub issue / PR 看真实问题和维护者解释。
  4. 技术博客和会议分享补充经验。
  5. 本地 Demo 或压测复现关键点。
  6. 写成排错文档,记录现象、定位路径、结论和后续动作。

基础题复盘#

进程和线程#

可直接说: 进程是资源分配单位,拥有独立地址空间;线程是 CPU 调度单位,同一进程内线程共享地址空间、文件描述符等资源。线程切换成本更低,进程隔离性更强。

线程间通信可以说:

  1. 共享内存 + 锁。
  2. 条件变量。
  3. 信号量。
  4. 管道。
  5. 消息队列。
  6. Go 里可以补充 channel。

死锁#

死锁四个条件:

  1. 互斥。
  2. 占有且等待。
  3. 不可抢占。
  4. 循环等待。

死锁避免可以从破坏条件入手:

  1. 固定加锁顺序,破坏循环等待。
  2. 一次性申请资源,减少占有且等待。
  3. 加锁超时和失败回滚。
  4. 用资源分级、锁粒度控制和代码审查降低风险。

TCP#

三次握手重点:

  1. 客户端发 SYN,证明客户端发送能力。
  2. 服务端回 SYN + ACK,证明服务端收发能力。
  3. 客户端回 ACK,证明客户端接收能力,并确认双方初始序列号。

四次挥手重点:

  1. TCP 是全双工连接,两个方向分别关闭。
  2. 主动关闭方发 FIN 表示自己发送方向关闭。
  3. 被动关闭方先回 ACK,处理完剩余数据后再发 FIN。
  4. 主动关闭方回 ACK 后进入 TIME_WAIT。

TIME_WAIT 的作用:

  1. 保证最后一个 ACK 可以重传。
  2. 等待旧连接中的报文自然消失。
  3. 避免新连接复用同一四元组时受到旧报文影响。

复杂度、数组和链表#

复杂度例子:

  1. O(1):数组按下标访问、哈希表平均查询。
  2. O(n):遍历数组、查找链表中的某个值。
  3. O(log n):二分查找、平衡树查询。
  4. O(n^2):双重循环比较、朴素冒泡排序。

数组和链表:

  1. 数组内存连续,随机访问快,缓存友好。
  2. 链表节点分散,插入删除时调整指针更方便。
  3. 大规模顺序读写通常数组更占优势,因为 CPU 缓存命中率更高。
  4. 频繁中间插入删除、已持有节点指针的场景可以考虑链表。

算法:最长回文子串#

推荐面试写中心扩展法,思路清晰,代码量小。

func longestPalindrome(s string) string {
	if len(s) < 2 {
		return s
	}
	start, end := 0, 0
	expand := func(l, r int) (int, int) {
		for l >= 0 && r < len(s) && s[l] == s[r] {
			l--
			r++
		}
		return l + 1, r - 1
	}
	for i := 0; i < len(s); i++ {
		l1, r1 := expand(i, i)
		l2, r2 := expand(i, i+1)
		if r1-l1 > end-start {
			start, end = l1, r1
		}
		if r2-l2 > end-start {
			start, end = l2, r2
		}
	}
	return s[start : end+1]
}

复杂度:

  1. 时间复杂度:O(n^2)。
  2. 空间复杂度:O(1)。

复盘重点#

这场面试的核心准备方向:

  1. K8s 架构和 Pod 创建流程要能白板讲出来。
  2. SRE 排障要形成固定方法论,并能说出真实文档沉淀。
  3. 学习能力题要给出“文档 -> Demo -> 实验 -> 排错 -> 输出”的路径。
  4. OS、TCP、复杂度和数据结构要用短答案稳定命中关键点。
  5. 算法优先准备中心扩展法和动态规划两种口径。
内容反馈

发现错误或想补充内容?

GoClub 是静态知识库,评论功能不再加载第三方脚本。你可以在 GitHub 仓库提交 Issue,反馈会直接进入项目协作流程。

提交 GitHub 反馈