From 60331be22825bec6e375451fb969fae4a80ed2b7 Mon Sep 17 00:00:00 2001 From: wonder Date: Sun, 7 Jun 2026 22:13:27 +0800 Subject: [PATCH] vault backup: 2026-06-07 22:13:27 --- hzh/Resume.md | 62 +++ hzh/TEST/GMP调度原理.md | 226 ++++++++++ hzh/TEST/简历 QA 100.md | 944 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1232 insertions(+) create mode 100644 hzh/Resume.md create mode 100644 hzh/TEST/GMP调度原理.md create mode 100644 hzh/TEST/简历 QA 100.md diff --git a/hzh/Resume.md b/hzh/Resume.md new file mode 100644 index 0000000..b1ed70d --- /dev/null +++ b/hzh/Resume.md @@ -0,0 +1,62 @@ +# 何朝晖 + +📞 15671623703 | 📧 [hezhaohui0807@163.com](mailto:hezhaohui0807@163.com) +全栈开发(Go/Java 后端) +🌐 [http://47.121.181.112:8080/resume/](http://47.121.181.112:8080/resume/) + +## 教育经历 + +**武汉科技大学** | 计算机科学与技术(国家级一流专业) | 本科 | 2023-09 ~ 2027-06 + +- 2026-03 ~ 2026-05 **金山办公 WPS 菁英工程师训练营** | 全栈方向 Go/React +- 2025-01 ~ 2025-03 **字节跳动 MarsCode 青训营** | 后端方向 Go + +## 荣誉奖项 + +- "金山杯"华中地区高校第十八届程序设计邀请赛 | **三等奖** | 2024-04 +- 国际大学生程序设计竞赛(ICPC)湖北省赛 | **优秀奖** | 2024-06 + +## 实习经历 + +**国家网络安全人才与创新基地 | 武汉金银湖实验室** | 平台技术部 后端开发 | 2025-11 ~ 2026-03 + +- 参与设计 **SaaS 多租户架构** 的 Tcode 平台,设计租户隔离策略、用户绑定解绑、RBAC 权限模型和树状组织架构。 +- 参与数据中台开发,基于 Go 并发模型重构面向**多源异构数据**的采集服务,引入流量控制机制提升数据处理效率。 +- 完善安全检测模块的 RAG 模块,基于**金银湖安全大模型**,实现结构化输出生成元数据,构建组件漏洞知识图谱。 + +**武汉市知无涯教育科技有限公司** | 2025-06 ~ 2025-08 + +- 基于 Gitea Actions 搭建 CI/CD 流水线,实现代码提交后触发 Lint 检查、单元测试与镜像构建,全流程自动化部署。 +- 采用 Docker 多阶段构建 Dockerfile 压缩镜像体积,集成 Lark SDK 实现流水线状态飞书推送,提升研发交付效率。 + +## 项目经历 + +**Gen2D 游戏素材生成工具** | 全栈开发 【七牛云 XEngineer 开源项目】 | 2026-05 ~ 至今 + +- **项目链接**: [https://gitee.com/hezhaohui123/gen2d](https://gitee.com/hezhaohui123/gen2d) +- **项目介绍**: 基于 Go(Gin) + Eino Agent Graph + GORM + 七牛云 Kodo + React + Zustand 的 AI 2D 游戏素材生成平台。用户输入文本提示词,自动生成风格一致的 Sprite、背景、UI 元素与动画帧,可直接导入 Unity 等主流 2D 游戏引擎。 +- **主要工作**: + 1. 基于 **Eino Graph** 构建四阶段 **DAG 管线**,编排 Prompt 优化、素材生成、质量校验、格式适配四节点有序执行。 + 2. 为提升生成质量稳定性,引入 **Reflect 自省机制**,自动质检不通过时将拒绝理由回注提示词,同时支持注入用户反馈。 + 3. 在限流方案的选择上,对比计数器、漏桶、窗口等多种限流机制,选用 **go-redis** 实现分布式的**令牌桶算法限流**。 + 4. 针对 LLM 请求耗时长特性,设计自定义 **IO 密集型协程池** 和 **RabbitMQ 消息队列**,实现模型调用并发化和异步化。 + +**ThumbUP 高并发点赞系统** | 后端开发 【哔哩哔哩技术团队文章复现】 | 2025-10 ~ 2025-11 + +- **项目链接**: [http://47.121.181.112:3000/wonder/thumb-up](http://47.121.181.112:3000/wonder/thumb-up) +- **项目介绍**: 基于 Spring Boot 3 + Redis + Caffeine + HeavyKeeper + MyBatis-Plus 的高并发点赞系统。采用 Write-Behind 异步写回架构,写入由 Redis 承接后定时批量落库;读取走 Caffeine、Redis 二级缓存加速。 +- **主要工作**: + 1. 基于 **Caffeine + Redis** 构建**二级缓存**,热点 Key 提升至本地缓存,避免冷数据污染,降低 Redis 访问压力。 + 2. **Lua 脚本**保证点赞原子性,10 秒时间片分桶暂存增量,**定时任务**批量落库,**补偿任务**每日兜底,保障最终一致性。 + 3. 复现 **HeavyKeeper 算法**实现 Top-K 热点探测,最小堆维护热点集,概率衰减淘汰冷 Key,周期 fading 适配流量变化。 + 4. 利用字符串常量池特性,以**业务前缀+用户ID**为锁对象,实现同用户串行,不同用户并行,减少锁竞争,提升吞吐量。 + +## 专业技能 + +- 熟练掌握 Java 与 Go 语言核心,熟悉常用集合与数据结构、面向对象设计、并发模型及内存管理机制。 +- 熟悉 Java (Spring/MyBatis/Cloud) 与 Go (Gin/GORM/gRPC) 技术栈,能熟练运用框架进行模块化开发与接口设计。 +- 了解 React Hooks 与组件生命周期,熟悉前端状态管理方案,熟练使用 Vite 构建工具及 Tailwind CSS。 +- 熟练掌握 MySQL 数据库,深刻理解事务隔离、存储引擎原理、B+树索引优化及 MVCC 并发控制机制。 +- 熟练掌握 Redis 缓存技术,理解 RDB/AOF 持久化策略、网络 IO 模型、哨兵集群机制及高性能架构原理。 +- 熟悉 Context Engineer,理解主流 Agent 架构,包括 ReAct、reflect、Plan-Exec 等,高效使用 Coding Agent 编码。 +- 熟悉 Docker、Git、web-hook,能够搭建 CI/CD 工作流,具备良好的编码习惯,以及良好的 commit 和 PR 风格。 \ No newline at end of file diff --git a/hzh/TEST/GMP调度原理.md b/hzh/TEST/GMP调度原理.md new file mode 100644 index 0000000..190ddc6 --- /dev/null +++ b/hzh/TEST/GMP调度原理.md @@ -0,0 +1,226 @@ +--- +tags: [go, golang, go-principle, gmp-scheduler, test, mcq] +create time: 2026-06-07 +title: GMP 调度原理 — 选择题测试 +questions: 20 +--- + +# GMP 调度原理 — 选择题测试 + +共 20 题,涵盖 GMP 概览、数据结构、生命周期和抢占式调度四大模块。每题仅有一个正确答案,答案以折叠块形式位于每题之后,点击展开查看。 + +--- + +## 一、GMP 架构概览(第 1~5 题) + +**1. Go 为什么没有直接使用操作系统内核线程来承载 goroutine?** + +A. 操作系统不支持多线程 +B. 内核线程上下文切换成本高,goroutine 是用户态轻量级执行流,切换仅需修改栈指针,开销极小 +C. Go 语言规范禁止使用系统线程 +D. 内核线程无法执行并行计算 + +> [!info]- 答案 +> **B** — 内核线程上下文切换需陷入内核态(保存寄存器、切换页表等),开销大;goroutine 在用户态运行,切换仅需改栈指针,成本极低。(§1.1) + +**2. GMP 模型中,P(Processor)的角色最接近以下哪个类比?** + +A. 工作任务 +B. 工人 +C. 车间主管 +D. 工厂仓库 + +> [!info]- 答案 +> **C** — G = 工作任务、M = 工人、P = 车间主管。P 管理本地队列,协调 M 与 G 的关系。(§1.3 表格) + +**3. LRQ(Local Run Queue)与 GRQ(Global Run Queue)的主要区别是什么?** + +A. LRQ 需要加锁,GRQ 无锁 +B. LRQ 是每个 P 私有的无锁队列,GRQ 是所有 P 共享的全局队列需加锁 +C. LRQ 容量无限,GRQ 最多 256 个 G +D. LRQ 用于存放阻塞的 G,GRQ 用于存放运行的 G + +> [!info]- 答案 +> **B** — LRQ per-P 私有,无锁 CAS 操作,容量 256;GRQ 全局共享,需 `sched.lock`,容量理论上无限。(§1.3 两种队列) + +**4. 当 M 上的 P 本地队列和全局队列都为空时,findRunnable 接下来会做什么?** + +A. 直接让 M 进入永久休眠 +B. 向操作系统申请更多 CPU 核心 +C. 通过 netpoll 检查 IO 就绪事件,若仍无则进行 work-stealing +D. 强制杀死所有当前正在运行的 G + +> [!info]- 答案 +> **C** — findRunnable 优先级:LRQ → GRQ → netpoll IO 就绪 → work-stealing → 失败才休眠。(§1.3 / §3.4 流程图) + +**5. Go 防止 GRQ 中的 G 长期饥饿的策略是什么?** + +A. 每 10ms 强制清空 LRQ +B. 每 61 次调度循环强制检查一次 GRQ +C. 每个 P 固定分配 50% 时间处理 GRQ +D. GRQ 中的 G 拥有最高优先级 + +> [!info]- 答案 +> **B** — 每 61 次调度循环(`schedtick % 61 == 0`)强制检查 GRQ,保证公平性防饥饿。(§1.3 note / §2.3 表格) + +--- + +## 二、数据结构(第 6~10 题) + +**6. G 结构体中 `stackguard0` 字段的用途是什么?** + +A. 记录 goroutine 的创建时间 +B. 作为栈保护区边界值,用于触发栈扩容或传递抢占标记 +C. 存储 goroutine 的优先级 +D. 指向下一个 goroutine 的指针 + +> [!info]- 答案 +> **B** — `stackguard0` 用于函数调用前比较,等于 `stackPreempt` 表示被抢占,接近 `stack.lo` 触发栈扩容。(§2.1 G 结构) + +**7. M(Machine)结构体中 `g0` 的特殊作用是什么?** + +A. 它是第一个被创建的普通用户协程 +B. 它是调度协程,M 用它来执行调度逻辑(如 schedule、newproc) +C. 它负责处理所有的网络 IO +D. 它是垃圾回收专用的协程 + +> [!info]- 答案 +> **B** — `g0` 是调度协程,每个 M 独有。M 执行 `g0` 时是调度者,执行 `curg` 时是执行者。(§2.2 M 结构) + +**8. P 结构体中 `runnext` 字段的作用是什么?** + +A. 记录 P 的编号 +B. 作为 VIP 位置,新创建或高优先级的 G 优先放入,下次调度直接跳过队列执行 +C. 指向下一个可用的空闲 P +D. 记录 P 已经运行了多久 + +> [!info]- 答案 +> **B** — `runnext` 是 VIP 位,新创建的高优先级 G 优先放此处,跳过队列开销直接执行。(§2.3 P 结构) + +**9. `schedt`(全局调度器)中的 `midle` 和 `pidle` 两个空闲队列的设计意图是什么?** + +A. 用于调试时统计空闲资源数量 +B. 实现资源的休眠与复用——不忙时释放回池中,有新任务时快速唤醒 +C. 为系统崩溃时恢复资源提供备份 +D. 用于将资源转移给其他进程的运行时 + +> [!info]- 答案 +> **B** — `midle` 和 `pidle` 实现资源休眠与复用——不忙释放回池,有新任务快速唤醒。(§2.4 schedt note) + +**10. G 的状态 `_Gwaiting` 有什么特点?** + +A. G 被放置在 LRQ 中等待再次调度 +B. G 不入任何就绪队列,由上层调用者(channel/mutex 等)自行保管 +C. G 被立即终止并回收 +D. G 被提升为最高优先级 + +> [!info]- 答案 +> **B** — `_Gwaiting` 的 G 不入任何就绪队列,由上层(channel/mutex/Timer 等)保管,等待上层唤醒。(§4.4 gopark 流程) + +--- + +## 三、Goroutine 生命周期(第 11~16 题) + +**11. `go func(){...}` 语句最终被编译器转换为何种 runtime 函数调用?** + +A. `runtime.new()` +B. `runtime.schedule()` +C. `runtime.newproc()` +D. `runtime.gopark()` + +> [!info]- 答案 +> **C** — `go func(){...}` 被编译器转换为 `runtime.newproc(fn)` 调用。(§3.2 创建流程) + +**12. 创建新 G 时,为什么需要通过 `systemstack` 从用户 G 栈切换到 `g0` 栈?** + +A. 因为用户栈空间不够 +B. 因为创建 G 是调度层面的工作,必须交由调度栈 `g0` 处理 +C. 因为 `g0` 栈有更高的优先级 +D. 因为用户栈不支持函数调用 + +> [!info]- 答案 +> **B** — 创建 G 涉及分配 struct、初始化入口地址等调度层面工作,必须在 `g0` 调度栈上执行。(§3.2 核心步骤①) + +**13. `findRunnable()` 查找可运行 G 的正确优先级顺序是什么?** + +A. GRQ → LRQ → netpoll → work-stealing +B. LRQ → GRQ → netpoll → work-stealing +C. netpoll → LRQ → GRQ → work-stealing +D. work-stealing → netpoll → LRQ → GRQ + +> [!info]- 答案 +> **B** — 严格顺序:LRQ 无锁 CAS → GRQ 加锁 → netpoll IO → work-stealing。源码路径 `runtime/proc.go`。(§3.4 流程图) + +**14. Work-Stealing 机制中,P 从其他繁忙 P 那里窃取的比例是多少?** + +A. 全部 G +B. 一半 G +C. 最后一个 G +D. 随机数量 G + +> [!info]- 答案 +> **B** — `runqsteal` 窃取目标 P LRQ 中的一半而非全部,减少反复争夺。(§3.7 Work-Stealing) + +**15. Goroutine 主动让出的三种方式中,`Gosched` 和 `goexit` 的关键区别是什么?** + +A. `Gosched` 将 G 放回 gfree 链表,`goexit` 将 G 放回 GRQ +B. 两者没有区别,完全等价 +C. `Gosched` 将 G 放回 GRQ 等待再次调度,`goexit` 将 G 放回 gfree 彻底回收 +D. `Gosched` 直接将 G 发送给另一个 M,`goexit` 将 G 放入 LRQ + +> [!info]- 答案 +> **C** — `Gosched` → `_Grunnable` → globrunqput(GRQ),等待再调度;`goexit` → `_Gdead` → gfput(gfree),彻底回收复用。(§4.2 vs §4.3 note) + +**16. `goready()` 唤醒一个处于 `_Gwaiting` 状态的 G 时,以下操作的正确顺序是?** + +A. 改为 `_Grunning` → runqput → wakep() +B. 改为 `_Grunnable` → runqput(LRQ 或 GRQ) → wakep() +C. runqput → 改为 `_Grunning` → wakep() +D. wakep() → 改为 `_Grunnable` → runqput + +> [!info]- 答案 +> **B** — `ready()` 三步:casgstatus(`_Gwaiting`→`_Grunnable`) → runqput(入 LRQ 或 GRQ) → wakep() 唤醒空闲 P。(§4.4 goready 源码) + +--- + +## 四、抢占式调度(第 17~20 题) + +**17. sysmon 线程三次巡检的核心职责分别是?** + +A. netpoll(IO 轮询)、retake(抢占检查)、GC 触发 +B. schedule(调度)、netpoll(IO 轮询)、memory alloc(内存分配) +C. retake(抢占检查)、lock(加锁)、unlock(解锁)、stack resize(栈扩容) +D. GC 触发、wakeup(唤醒 G)、stopm(停止 M) + +> [!info]- 答案 +> **A** — sysmon 三板斧:① netpoll 取 epoll 就绪事件 → injectglist;② retake 抢占超时/syall P;③ GC 触发检查。(§5.1 三次巡检表格) + +**18. 当一个 G 发起系统调用时,`reentersyscall` 做了什么?(单选)** + +A. 将该 G 直接放入 GRQ 并停止 M +B. 将 G 状态改为 `_Gsyscall`,解除 P 与 M 的绑定,并将 P 状态设为 `_Psyscall` +C. 复制一个新的 P 来继续调度 +D. 暂停整个程序直到 syscall 返回 + +> [!info]- 答案 +> **B** — `reentersyscall`: G→`_Gsyscall`, pp.m=0 (解绑 P→M), _g_.m.p=0, atomic.Store(&pp.status, _Psyscall)。(§5.2 源码) + +**19. Go ≥ 1.14 引入的非协作式抢占是如何工作的?** + +A. 通过设置 `stackPreempt` 标记在下次函数调用时生效 +B. 通过 POSIX 信号 (`sigPreempt`) 发送到目标线程,在安全中断点注入 `asyncPreempt` 强行接管执行流 +C. 通过 kill 信号终止该 G 所在的 OS 线程 +D. 通过降低该 G 所属 P 的优先级来间接实现 + +> [!info]- 答案 +> **B** — Go ≥ 1.14: preemptone 发送 `sigPreempt` 信号 → sighandler → doSigPreempt → pushCall(asyncPreempt) 劫持 PC。(§5.3.2 源码 + 流程图) + +**20. 为什么 Go 在引入了非协作式抢占后仍然保留协作式抢占作为兜底方案?** + +A. 因为协作式抢占的性能更好 +B. 因为信号机制存在平台限制(如 Windows 不支持),协作式兜底;且对有 IO/channel 的 G 协作式已足够及时 +C. 因为开发者可以手动选择使用哪种抢占方式 +D. 因为非协作式抢占只在 Linux 上有效 + +> [!info]- 答案 +> **B** — 信号机制有平台限制(Windows 不支持),协作式兜底;对有 IO/channel 的 G 协作式已足够及时。(§5.4 note) diff --git a/hzh/TEST/简历 QA 100.md b/hzh/TEST/简历 QA 100.md new file mode 100644 index 0000000..4ed1f11 --- /dev/null +++ b/hzh/TEST/简历 QA 100.md @@ -0,0 +1,944 @@ +--- +tags: ["测试", "选择题", "面试", "Go", "Java", "Redis", "MySQL", "系统架构"] +create time: 2026-06-07 14:30 +--- + +# 简历技术选择题 100 题 + +## 概述 + +基于个人简历中涉及的技术栈(Go、Java、Redis、MySQL、React、Docker/CI/CD、并发模型、缓存策略等)生成的 100 道选择题,每题附答案与解析,用于自测与技术复盘。 + +## 正文 + +### 一、Go 语言核心(第 1-13 题) + +**Q1. Go 中 goroutine 与操作系统的线程有什么区别?** +A) goroutine 是用户态线程,由 Go runtime 调度 +B) goroutine 是内核线程,由操作系统调度 +C) goroutine 和线程完全等价 +D) goroutine 只能在 main 函数中运行 + +> [!summary]- Q1 答案与解析 +> **答案:A** — goroutine 是 Go runtime 管理的用户态轻量级协程,初始栈仅 2KB,可动态伸缩。 + +**Q2. Go 的 channel 在关闭后发送数据会发生什么?** +A) 静默丢弃 +B) panic: send on closed channel +C) 返回 nil +D) 阻塞等待 + +> [!summary]- Q2 答案与解析 +> **答案:B** — 向已关闭的 channel 发送数据会触发 panic。 + +**Q3. sync.WaitGroup 的 Add、Done、Wait 方法调用顺序正确的是?** +A) Wait() → Add() → Done() +B) Add() → 启动 goroutine 调用 Done() → Wait() +C) Done() → Add() → Wait() +D) 任意顺序均可 + +> [!summary]- Q3 答案与解析 +> **答案:B** — Add() 必须在 Wait() 之前调用,且 Add(n) 中的 n 应大于 0。 + +**Q4. Go Context 的主要用途是什么?** +A) 管理内存分配 +B) 传递取消信号、截止时间与请求作用域值 +C) 实现 HTTP 路由 +D) 替代 struct field + +> [!summary]- Q4 答案与解析 +> **答案:B** — Context 用于控制 goroutine 生命周期(取消/超时)和传递跨 API 边界的请求级数据。 + +**Q5. Go 的 GC(垃圾回收)使用的是什么算法?** +A) 引用计数 +B) Mark-Sweep +C) Mark-Compact +D) 三色标记 + 混合写屏障(Concurrent Mark & Sweep) + +> [!summary]- Q5 答案与解析 +> **答案:D** — Go 采用并发三色标记清除算法,配合混洗写屏障保证性能。 + +**Q6. 在 Go 中,make([]int, 0, 10) 创建的切片其 len 和 cap 分别为?** +A) len=0, cap=10 +B) len=10, cap=10 +C) len=0, cap=0 +D) len=10, cap=0 + +> [!summary]- Q6 答案与解析 +> **答案:A** — make 第三个参数为容量,长度默认为第一个参数。 + +**Q7. Go 的 select 语句在没有 case 可选时会怎样?** +A) 返回 nil +B) 编译报错 +C) 永久阻塞 +D) panic + +> [!summary]- Q7 答案与解析 +> **答案:C** — 没有 default case 的 select 在所有 channel 不可操作时永久阻塞。 + +**Q8. go 的 defer 语句执行时机是什么?** +A) 函数结束时按声明顺序执行 +B) 函数结束时逆序(LIFO)执行 +C) goroutine 退出时执行 +D) return 之后立即执行 + +> [!summary]- Q8 答案与解析 +> **答案:B** — defer 压入栈,函数返回时以 LIFO 顺序弹出执行。 + +**Q9. Go 接口类型的底层结构包括几个部分?** +A) 1 个:指向数据的指针 +B) 2 个:类型信息和数据指针 +C) 3 个:类型、数据、虚表 +D) 4 个 + +> [!summary]- Q9 答案与解析 +> **答案:B** — 接口由 iface 组成:type(类型信息)和 data(数据指针)。 + +**Q10. Go 的 reflect.TypeOf 返回的是什么?** +A) 变量的运行时值 +B) 变量编译时的静态类型 +C) 变量的动态类型信息(interface{} 的具体类型) +D) 变量的内存地址 + +> [!summary]- Q10 答案与解析 +> **答案:C** — TypeOf 在运行时获取 interface{} 所持有值的实际类型。 + +**Q11. Go 的 race detector 通过什么实现?** +A) 静态分析编译器标志 +B) -race 编译标志,在源码级别插入探测代码 +C) 运行时 GC 监控 +D) pprof profile + +> [!summary]- Q11 答案与解析 +> **答案:B** — go build -race 会在源码级别插入读写探测代码来检测数据竞争。 + +**Q12. Go 的 map 在并发读写时会怎样?** +A) 自动加锁 +B) panic: concurrent map reads and writes +C) 只读安全,只写不安全 +D) 取决于 Go 版本 + +> [!summary]- Q12 答案与解析 +> **答案:B** — 原生 map 不是并发安全的,需用 sync.Map 或加 mutex。 + +**Q13. Go 标准库中 net/http 默认是否有连接池?** +A) 没有,每次请求新建 TCP 连接 +B) 有,Transport 内置 Keep-Alive 连接复用 +C) 需要手动配置才能启用 +D) 仅在 HTTP/2 下才有 + +> [!summary]- Q13 答案与解析 +> **答案:B** — http.Transport 默认支持 HTTP Keep-Alive 连接复用。 + +### 二、Go Web 开发 & Gin/GORM(第 14-23 题) + +**Q14. Gin 框架中 Middleware 的执行顺序是怎样的?** +A) 随机 +B) 注册顺序,先注册先执行、后返回 +C) 先注册的后执行 +D) 只在出错时执行 + +> [!summary]- Q14 答案与解析 +> **答案:B** — Gin 中间件按注册顺序依次执行,类似洋葱模型。 + +**Q15. GORM 中 Preload 和 Joins 的区别是?** +A) 无区别,都是 N+1 查询 +B) Preload 用额外 SELECT 加载关联,Joins 用 SQL JOIN +C) Preload 只能用于一对多关系 +D) Joins 总是比 Preload 快 + +> [!summary]- Q15 答案与解析 +> **答案:B** — Preload 执行两次查询(主表 + 关联表),Joins 合并为一次 LEFT JOIN。 + +**Q16. Gin 中 c.ShouldBindJSON() 失败时会怎样?** +A) 返回 nil +B) 自动调用 c.AbortWithError() 返回 400 +C) 忽略错误继续执行 +D) panic + +> [!summary]- Q16 答案与解析 +> **答案:B** — 绑定失败会自动返回 400 Bad Request 并终止后续 handler 执行。 + +**Q17. GORM 的 First() 和 Take() 的区别是?** +A) First() 按主键排序,Take() 随机取一条 +B) First() 必须 WHERE id=...,Take() 无条件取第一条 +C) 两者完全一样 +D) Take() 返回多条记录 + +> [!summary]- Q17 答案与解析 +> **答案:A** — First() 隐含 Order("primary_key"),Take() 不做排序直接 LIMIT 1。 + +**Q18. Gin 中使用 c.Query() 和 c.Param() 分别对应什么 URL 元素?** +A) Query → path param, Param → query string +B) Query → query string, Param → path parameter +C) 两者都从 body 读取 +D) Query → header, Param → query string + +> [!summary]- Q18 答案与解析 +> **答案:B** — Query 解析 URL ?key=value,Param 解析 :param 路径参数。 + +**Q19. GORM AutoMigrate 的功能是什么?** +A) 迁移数据库版本号 +B) 自动创建/alter 表结构以匹配 struct tag +C) 备份数据库数据 +D) 加密字段 + +> [!summary]- Q19 答案与解析 +> **答案:B** — AutoMigrate 根据 struct 定义自动建表或调整列(不删列)。 + +**Q20. Gin 中 ResponseWriter 的 Flush() 方法实现什么功能?** +A) 刷新 buffer,支持 Server-Sent Events +B) 关闭连接 +C) 重置 header +D) 打印日志 + +> [!summary]- Q20 答案与解析 +> **答案:A** — 实现 SSE (Server-Sent Events) 推送。 + +**Q21. GORM 中 scope.Searchable() 的作用是什么?** +A) 条件链式搜索查询 +B) 全文搜索引擎集成 +C) 删除记录 +D) 事务管理 + +> [!summary]- Q21 答案与解析 +> **答案:A** — Searchable 简化链式条件查询构建。 + +**Q22. Gin 中 c.Bind() 和 c.ShouldBind() 的差异是?** +A) c.Bind() 出错时 panic,c.ShouldBind() 返回 error +B) c.ShouldBind() 出错时 panic +C) 两者相同 +D) c.Bind() 更快 + +> [!summary]- Q22 答案与解析 +> **答案:A** — Bind 内部若出错会 abort+panic(被 recover 捕获返回 400),ShouldBind 显式返回 error。 + +**Q23. Gin Router 的 LoadHTMLGlob() 和 LoadHTMLFiles() 有何区别?** +A) Glob 加载目录所有模板,Files 加载指定文件列表 +B) Glob 只能加载 HTML,Files 可以加载任何文件 +C) 无实质区别 +D) Files 支持通配符 + +> [!summary]- Q23 答案与解析 +> **答案:A** — Glob 接受路径模式(如 "templates/*"),Files 需逐个指定文件名。 + +### 三、Go 高级特性 & RabbitMQ(第 24-30 题) + +**Q24. Go 的 pool(协程池)主要解决的问题是?** +A) 减少 goroutine 频繁创建销毁开销 +B) 避免死锁 +C) 代替 channel +D) 提升 GC 速度 + +> [!summary]- Q24 答案与解析 +> **答案:A** — 协程池复用 goroutine 避免大量短命协程的创建/销毁成本,尤其对 IO 密集型任务有价值。 + +**Q25. RabbitMQ 中 Exchange 的类型不包括?** +A) direct +B) topic +C) random +D) headers + +> [!summary]- Q25 答案与解析 +> **答案:C** — RabbitMQ 四种 Exchange:direct、topic、headers、fanout。 + +**Q26. RabbitMQ 消息持久化需要哪三个步骤?** +A) Queue durable + Message persistent + Confirm +B) Queue auto-delete + Message transient +C) 仅需 Queue durable +D) 只需 Message delivery_mode=2 + +> [!summary]- Q26 答案与解析 +> **答案:A** — 队列需 declare_durable=true,消息 delivery_mode=2,且开启 publisher confirm。 + +**Q27. Go 中 context.WithTimeout 和 context.WithDeadline 的区别是?** +A) 无区别,完全等价 +B) WithTimeout = Now + duration,WithDeadline = 绝对时间戳 +C) WithDeadline 只能用于 HTTP +D) WithTimeout 不支持 cancel + +> [!summary]- Q27 答案与解析 +> **答案:B** — 一个是相对时长,一个是绝对 Time。 + +**Q28. RabbitMQ 中 Consumer Ack 的目的是?** +A) 告诉 Broker 消息已处理成功,可从队列移除 +B) 增加消息延迟 +C) 触发重试 +D) 改变消息优先级 + +> [!summary]- Q28 答案与解析 +> **答案:A** — Ack 确认消费成功;Nack 可重新入队或丢弃。 + +**Q29. Go 泛型中 type constraint 使用 interface 而不是 class,原因是?** +A) Go 没有 class +B) Go 的 interface 支持结构化子类型(隐式满足) +C) class 太复杂 +D) 语法限制 + +> [!summary]- Q29 答案与解析 +> **答案:B** — Go interface 是 duck-typing,任何实现了对应方法的类型自动满足约束。 + +**Q30. Go 的 unsafe.Pointer 能做什么?** +A) 绕过类型安全进行内存操作 +B) 替代 malloc +C) 创建新 thread +D) 优化 GC + +> [!summary]- Q30 答案与解析 +> **答案:A** — unsafe 包允许直接操作内存(转换、偏移、指针算术),但会破坏类型安全。 + +### 四、Java 语言核心(第 31-42 题) + +**Q31. Java 中 HashMap 的默认负载因子和初始容量是?** +A) 0.5, 8 +B) 0.75, 16 +C) 0.75, 8 +D) 0.8, 16 + +> [!summary]- Q31 答案与解析 +> **答案:B** — load factor 0.75,initial capacity 16。 + +**Q32. Java ConcurrentHashMap 在 JDK 8+ 使用什么结构?** +A) 单纯链表 +B) Array + LinkedList +C) Array + LinkedList + Red-Black Tree(树化阈值 8) +D) Hash Table + +> [!summary]- Q32 答案与解析 +> **答案:C** — 桶内链表节点数 ≥8 且数组长度 ≥64 时转为红黑树,降低查找复杂度。 + +**Q33. Java synchronized 和 ReentrantLock 的核心区别是?** +A) synchronized 是 JVM 层面,ReentrantLock 是 API 层面 +B) 两者完全等价 +C) ReentrantLock 不能中断等待 +D) synchronized 支持 condition + +> [!summary]- Q33 答案与解析 +> **答案:A** — synchronized 由 JVM 内置实现,ReentrantLock 是 java.util.concurrent 层面的显式锁。 + +**Q34. Java Callable 和 Runnable 的区别是?** +A) Callable 可返回值并能抛出 checked exception +B) Runnable 更快 +C) Callable 不能异步执行 +D) Runnable 是 Java 8 引入 + +> [!summary]- Q34 答案与解析 +> **答案:A** — Callable.call() 返回 V 并可 throw Exception,Runnable.run() 无返回值。 + +**Q35. Java Spring Bean 的作用域不包括?** +A) singleton +B) prototype +C) request +D) coroutine + +> [!summary]- Q35 答案与解析 +> **答案:D** — Spring 五大作用域:singleton、prototype、request、session、application。 + +**Q36. Spring 中 @Autowired 默认是按什么注入?** +A) 按 name +B) 按 type(byType) +C) 按 constructor +D) 按 index + +> [!summary]- Q36 答案与解析 +> **答案:B** — 默认按 byType 匹配;同名多个 bean 时才按 byName。 + +**Q37. MyBatis 中 #{ } 和 ${ } 的区别是?** +A) #{} 是预编译占位符防 SQL 注入,${} 是直接字符串拼接 +B) 两者完全一样 +C) ${} 更安全 +D) #{} 只用于字符串 + +> [!summary]- Q37 答案与解析 +> **答案:A** — #{ } 使用 PreparedStatement 的参数绑定,${ } 是原始文本替换。 + +**Q38. Java 中 volatile 关键字保证哪些属性?** +A) 可见性 + 原子性 +B) 可见性 + 有序性,不保证原子性 +C) 只有原子性 +D) 没有保证 + +> [!summary]- Q38 答案与解析 +> **答案:B** — volatile 保证可见性和禁止指令重排,但不保证复合操作的原子性。 + +**Q39. Java 线程池中 corePoolSize 和 maximumPoolSize 的关系是?** +A) corePoolSize ≤ maximumPoolSize +B) 可以任意大小 +C) 必须相等 +D) core > max + +> [!summary]- Q39 答案与解析 +> **答案:A** — 核心线程数不能超过最大线程数。 + +**Q40. Java 8 Stream 中 flatMap() 和 map() 的区别是?** +A) flatMap 将嵌套集合展平为一层,map 是一对一转换 +B) 两者完全一样 +C) flatMap 更慢 +D) map 可以展平 + +> [!summary]- Q40 答案与解析 +> **答案:A** — map(Stream) 得到 Stream>,flatMap 直接将 Stream 展平为一个 Stream。 + +**Q41. Java Optional.ofNullable(null) 的行为是?** +A) 返回 Optional.empty() +B) 返回 null +C) panic +D) NullPointerException + +> [!summary]- Q41 答案与解析 +> **答案:A** — Optional.ofNullable 允许 null 值,null 时返回 empty();Optional.of(null) 才会抛 NPE。 + +**Q42. Java Spring 中 @Controller 和 @RestController 的区别是?** +A) @RestController = @Controller + @ResponseBody +B) 完全一样 +C) @Controller 不能返回 JSON +D) @RestController 不能做视图渲染 + +> [!summary]- Q42 答案与解析 +> **答案:A** — @RestController 在每个方法上隐式添加 @ResponseBody,直接写响应体而非视图名。 + +### 五、Spring Boot & MyBatis-Plus(第 43-49 题) + +**Q43. Spring Boot Starter 的作用是?** +A) 自动化配置依赖组合 +B) 编译加速 +C) 单元测试框架 +D) 部署工具 + +> [!summary]- Q43 答案与解析 +> **答案:A** — Starter 通过 spring.factories 或 AutoConfiguration 自动装配相关配置类。 + +**Q44. MyBatis-Plus 中 IService 和 BaseMapper 的区别是?** +A) IService 提供 CRUD 通用方法,BaseMapper 只做单表 Mapper 操作 +B) 无区别 +C) BaseService 包含 BaseMapper +D) BaseMapper 是 MyBatis 原生的 + +> [!summary]- Q44 答案与解析 +> **答案:A** — IService 封装了常用的增删改查、分页等方法,BaseMapper 是对应实体表的 Mapper 接口。 + +**Q45. Spring Boot 的自动装配原理核心注解是?** +A) @EnableAutoConfiguration +B) @ComponentScan +C) @Configuration +D) @Import + +> [!summary]- Q45 答案与解析 +> **答案:A** — @EnableAutoConfiguration 通过 @Import(AutoConfigurationImportSelector.class) 加载 META-INF/spring.factories 中配置的自动装配类。 + +**Q46. MyBatis-Plus 的 @TableId(type = IdType.AUTO) 含义是?** +A) 主键由数据库自增 +B) 使用雪花算法 +C) UUID +D) 雪花+本地 Snowflake + +> [!summary]- Q46 答案与解析 +> **答案:A** — AUTO 依赖数据库自增序列;ASSIGN_ID 才是雪花算法。 + +**Q47. Spring Cloud Gateway 与传统 Zuul 1.x 的区别是?** +A) Gateway 基于 Reactor 非阻塞,Zuul 1.x 是 Servlet 阻塞式 +B) 无区别 +C) Zuul 更快 +D) Gateway 不支持负载均衡 + +> [!summary]- Q47 答案与解析 +> **答案:A** — Spring Cloud Gateway 基于 Spring WebFlux (Netty),非阻塞响应式模型。 + +**Q48. MyBatis 一级缓存和二级缓存的区别是?** +A) 一级是 SqlSession 级别,二级是 Namespace/Mapper 级别 +B) 一级是全局的 +C) 二级默认开启 +D) 一级可跨 Session + +> [!summary]- Q48 答案与解析 +> **答案:A** — 一级缓存默认开启且无法关闭;二级缓存需手动配置 enableCache=true,跨同 namespace 的 Session 共享。 + +**Q49. Spring Boot Actuator 主要用于?** +A) 监控和管理应用(健康检查、指标暴露等) +B) 热修复代码 +C) 前端打包 +D) 自动生成 UI + +> [!summary]- Q49 答案与解析 +> **答案:A** — 提供 /actuator/health、/metrics、/info 等端点供外部监控系统采集。 + +### 六、Redis(第 50-62 题) + +**Q50. Redis 的 RDB 和 AOF 两种持久化方式的比较中,正确的是?** +A) RDB 基于快照,恢复快但可能丢数据;AOF 逐条记录追加,更安全但文件更大 +B) AOF 基于快照 +C) RDB 实时性更好 +D) AOF 不可能丢数据 + +> [!summary]- Q50 答案与解析 +> **答案:A** — RDB 定期 fork 子进程写快照;AOF 每条写入命令追加到 .aof 文件。 + +**Q51. Redis 哨兵模式的自动故障转移流程是?** +A) Master fail → Sentinel 投票选 New Master → 提升 Slave → 通知 clients +B) Master fail → 直接切换 +C) Master fail → Slave 自动提升(无需投票) +D) 需要人工介入 + +> [!summary]- Q51 答案与解析 +> **答案:A** — 哨兵通过 is-master-down-by-addr 探测失败,quorum 确认后 election 选出 new master。 + +**Q52. Redis 的持久化策略 appendfsync 三种模式安全性从高到低排列是?** +A) always > everysec > no +B) no > everysec > always +C) everysec > always > no +D) always = everysec + +> [!summary]- Q52 答案与解析 +> **答案:A** — always 每条 fsync(最安全,性能最低);everysec 每秒 fsync(折中);no 交由 OS 决定。 + +**Q53. Redis Set 数据类型不支持的操作是?** +A) union +B) intersection +C) difference +D) range by index(范围索引查询) + +> [!summary]- Q53 答案与解析 +> **答案:D** — Set 是无序的哈希集合,不支持按位置索引;List 才支持 LRANGE。 + +**Q54. Redis 发布订阅模式中,客户端断线后会怎样?** +A) 收不到断线期间发布的消息 +B) 断线重连后可收到历史消息 +C) 自动 rejoin 上次 channel +D) Redis 会自动缓存消息 + +> [!summary]- Q54 答案与解析 +> **答案:A** — Pub/Sub 是 fire-and-forget,不持久化消息;需要持久化可用 Redis Streams。 + +**Q55. Redis Pipeline 的优势是?** +A) 减少 RTT(往返延迟),批量命令一次网络往返 +B) 增加数据一致性 +C) 替代事务 +D) 提高单个命令吞吐量 + +> [!summary]- Q55 答案与解析 +> **答案:A** — 管道将多个命令打包在一次网络往返中,显著降低网络开销。 + +**Q56. Redis Cluster 分片是基于?** +A) 哈希槽(Hash Slot),共 16384 个 +B) 按 key 字母排序 +C) 随机分配 +D) 按 value 大小 + +> [!summary]- Q56 答案与解析 +> **答案:A** — CRC16(key) % 16384 定位 slot,每个 slot 映射到一个主节点。 + +**Q57. Redis 的 Keyspace Notification 功能可以用于?** +A) 监听 key 过期事件,触发业务逻辑 +B) 替代 pub/sub +C) 替代 Lua +D) 压缩内存 + +> [!summary]- Q57 答案与解析 +> **答案:A** — 可通过 CONFIG SET notify-keyspace-events KEA 开启 key 过期通知。 + +**Q58. Redis 的 HGETALL 在高版本优化后的行为是?** +A) 不再一次性全部返回,需改用 HSCAN 避免阻塞 +B) 变得更慢了 +C) 改为异步输出 +D) 返回压缩格式 + +> [!summary]- Q58 答案与解析 +> **答案:A** — HGETALL 对小 hash 仍一次性返回,大 hash 推荐使用 HSCAN 游标迭代。 + +**Q59. Redis 的 ZSET(Sorted Set)分数相同时如何排序?** +A) 按 member 字典序 +B) 随机 +C) 插入顺序 +D) 按 value 大小 + +> [!summary]- Q59 答案与解析 +> **答案:A** — 分数相同情况下,Redis 按 member 字符串的字典序排序。 + +**Q60. Redis 中 DEL 命令删除一个不存在的 key 会怎样?** +A) 返回 false / 0(无效操作) +B) panic +C) 阻塞 +D) 自动重建 key + +> [!summary]- Q60 答案与解析 +> **答案:A** — DEL key 对于不存在 key 返回整数 0。 + +**Q61. Redis 的 Maxmemory-policy 设置 allkeys-lru 的含义是?** +A) 所有 key 遵循 LRU 淘汰策略 +B) 仅 expired keys +C) 永不淘汰 +D) 随机淘汰 + +> [!summary]- Q61 答案与解析 +> **答案:A** — 对所有 key 近似 LRU 淘汰,直到内存低于 maxmemory。 + +**Q62. Redis String 类型的 max size 是多少?** +A) 512 MB +B) 1 GB +C) 256 MB +D) 1 TB + +> [!summary]- Q62 答案与解析 +> **答案:B** — Redis String 最大 512MB(Redis 6.0+ 之前),理论上可达 1GB。 + +### 七、MySQL(第 63-74 题) + +**Q63. MySQL InnoDB 默认的隔离级别是?** +A) READ COMMITTED +B) REPEATABLE READ +C) READ UNCOMMITTED +D) SERIALIZABLE + +> [!summary]- Q63 答案与解析 +> **答案:B** — 默认 RR(Repeatable Read),通过 MVCC + Next-Key Lock 防止幻读。 + +**Q64. MySQL 的 B+ 树索引相比 B 树的优势是?** +A) 范围查询更高效,所有数据都在叶子节点 +B) 查询更快 +C) 存储空间更小 +D) 不支持前缀索引 + +> [!summary]- Q64 答案与解析 +> **答案:A** — B+ 树的非叶子节点只存 key,叶子节点通过链表串联,适合范围扫描。 + +**Q65. MySQL 中 EXPLAIN 的 type 字段值 best→worst 排列正确的是?** +A) system > const > eq_ref > ref > range > index > ALL +B) ALL > index > range > ref > eq_ref > const > system +C) const > system > ref > range > index > ALL > eq_ref +D) 无固定顺序 + +> [!summary]- Q65 答案与解析 +> **答案:A** — 从左到右扫描效率递减,system/const 最优,ALL 是全表扫描最差。 + +**Q66. MySQL 的 MVCC 通过什么实现?** +A) Undo Log + Read View +B) Redo Log +C) Binlog +D) Buffer Pool + +> [!summary]- Q66 答案与解析 +> **答案:A** — 每行隐藏 rollback pointer 指向 undo log 版本链,当前事务通过 read view 决定可见性。 + +**Q67. MySQL 的 binlog 三种格式 ROW/STATEMENT/MIXED 中,哪种记录最多数据量但最安全?** +A) ROW 格式,记录每一行的变更前后值 +B) STATEMENT,记录原始 SQL +C) MIXED +D) 都一样 + +> [!summary]- Q67 答案与解析 +> **答案:A** — ROW 格式记录每行变更前后的完整值,精确可还原且不受 SQL 语义影响。 + +**Q68. MySQL 中唯一索引和普通索引在存储上的差异是?** +A) 唯一索引强制要求列值不重复 +B) 普通索引更快 +C) 唯一索引不能用 Covering Index +D) 无差异 + +> [!summary]- Q68 答案与解析 +> **答案:A** — 唯一索引维护唯一约束,插入重复 key 时抛 Duplicate Key Error。 + +**Q69. MySQL 联合索引 (a, b, c) 可以用到索引的最长连续前缀是?** +A) (a), (a,b), (a,b,c) +B) (b), (c) +C) (a, c) +D) (b, c) + +> [!summary]- Q69 答案与解析 +> **答案:A** — 最左前缀原则:必须从左边第一个列开始连续匹配。 + +**Q70. MySQL 中 DELETE 和 TRUNCATE 的区别是?** +A) DELETE 逐行删除可回滚,TRUNCATE 释放页面不可回滚 +B) 无区别 +C) TRUNCATE 更慢 +D) DELETE 不能带 WHERE + +> [!summary]- Q70 答案与解析 +> **答案:A** — DELETE 是 DML 语句走事务日志;TRUNCATE 是 DDL 直接重置表空间。 + +**Q71. MySQL 的事务 ACID 中,Atomicity 由什么保证?** +A) Undo Log +B) Redo Log +C) Buffer Pool +D) Binlog + +> [!summary]- Q71 答案与解析 +> **答案:A** — Undo Log 记录事务修改前的旧值,支持回滚以实现原子性。 + +**Q72. MySQL 缓冲池(Buffer Pool)命中率接近 100% 意味着?** +A) 几乎都在内存中访问,磁盘 IO 极少 +B) 物理内存不足 +C) 磁盘性能差 +D) 查询效率低 + +> [!summary]- Q72 答案与解析 +> **答案:A** — 高命中率说明绝大部分数据已在内存中,减少磁盘 I/O。 + +**Q73. MySQL 中 GROUP BY 默认会对结果集进行什么操作?** +A) 排序 +B) 过滤 +C) 更新 +D) 分片 + +> [!summary]- Q73 答案与解析 +> **答案:A** — 未开启 ONLY_FULL_GROUP_BY 时,GROUP BY 隐式 ORDER BY,会产生 extra filesort。 + +**Q74. MySQL 中 PRIMARY KEY 和 UNIQUE KEY 能否共存?** +A) 能,一个表可以有多个 UNIQUE 但只有一个 PRIMARY KEY +B) 不能,二选一 +C) 可以互为别名 +D) PRIMARY KEY 也是 UNIQUE KEY 的一种 + +> [!summary]- Q74 答案与解析 +> **答案:A** — 一张表可有多个 UNIQUE 索引,但只能有一个 PRIMARY KEY(NOT NULL + 聚簇索引)。 + +### 八、高并发设计 & 缓存策略(第 75-84 题) + +**Q75. Write-Behind 缓存策略的特点是什么?** +A) 先写缓存再异步落库,提升写入吞吐 +B) 先落库再写缓存 +C) 同步写双写 +D) 只写不存 + +> [!summary]- Q75 答案与解析 +> **答案:A** — 写入先命中缓存层即刻返回,后台定时批量刷盘,牺牲强一致性换取高性能。 + +**Q76. 二级缓存的设计目的通常是?** +A) 热点数据在本地减少远程调用,冷数据不落 L1 减少污染 +B) 替代单级缓存 +C) 加快 GC +D) 减少 CPU 消耗 + +> [!summary]- Q76 答案与解析 +> **答案:A** — L1 本地缓存存极热点数据(零网络开销),L2 远端缓存作为后备,兼顾速度与资源消耗。 + +**Q77. HeavyKeeper 算法主要用于解决什么问题?** +A) Top-K 热点 Key 探测 +B) 数据加密 +C) 网络拥塞控制 +D) 分布式事务 + +> [!summary]- Q77 答案与解析 +> **答案:A** — HeavyKeeper 通过最小堆 + 概率衰减机制,自适应流量变化持续追踪高频热点。 + +**Q78. 令牌桶限流相比漏桶的区别在于?** +A) 令牌桶允许突发流量,漏桶是匀速输出 +B) 令牌桶更简单 +C) 漏桶不允许峰值 +D) 两者完全一样 + +> [!summary]- Q78 答案与解析 +> **答案:A** — 令牌桶积累令牌允许短时间内突发消费;漏桶以固定速率出水,不突发。 + +**Q79. 点赞系统中 Lua 脚本保证原子性的目的是?** +A) 原子地读取-判断-递增,防止并发冲突 +B) 减少网络 IO +C) 替代 Redis +D) 持久化 + +> [!summary]- Q79 答案与解析 +> **答案:A** — Lua 脚本在 Redis 中串行执行,确保 incr + TTL 逻辑不被中间状态打断。 + +**Q80. 补偿任务的目的是?** +A) 兜底修复因异常导致的数据不一致(如未落库记录) +B) 加速写入 +C) 替代定时任务 +D) 清除过期数据 + +> [!summary]- Q80 答案与解析 +> **答案:A** — 定时批量写回可能失败或遗漏,补偿任务定期对账补齐丢失数据。 + +**Q81. Redis 中利用字符串常量池作为锁对象的好处是?** +A) 同用户串行执行,不同用户并行,减少不必要的互斥 +B) 节省内存 +C) 加快 GC +D) 替代数据库锁 + +> [!summary]- Q81 答案与解析 +> **答案:A** — 以 user_id 为粒度实现细粒度并行,避免一把大锁导致的瓶颈。 + +**Q82. Redis 时间片分桶暂存增量的好处是?** +A) 将分散的单次请求聚合为批处理请求 +B) 减少 Redis 压力 +C) 替代 MQ +D) 实现秒级 TPS + +> [!summary]- Q82 答案与解析 +> **答案:A** — 在 10s 窗口内攒一批后再统一落库,减少 DB 写入次数。 + +**Q83. Caffeine 本地缓存相比 Guava Cache 的优势之一是?** +A) W-TinyLFU 淘汰算法更接近 LRU 但更轻量 +B) 支持远程复制 +C) 更大内存上限 +D) 内置集群功能 + +> [!summary]- Q83 答案与解析 +> **答案:A** — Caffeine 采用 W-TinyLFU(滑动窗口 Tiny-Filter LFU),命中率接近 LRU 但代价更低。 + +**Q84. Redis 的 watch 命令实现了什么功能?** +A) 乐观锁——监视 key 并在 multi/exec 时校验是否被修改 +B) 悲观锁 +C) 分区 +D) 复制 + +> [!summary]- Q84 答案与解析 +> **答案:A** — WATCH key… 后 MULTI,EXEC 时如果 key 被他人改动则整个事务失败。 + +### 九、Docker & CI/CD(第 85-90 题) + +**Q85. Docker 多阶段构建的主要优势是?** +A) 最终镜像体积更小(只保留产物不含构建工具) +B) 自动部署 +C) 更快的网络 +D) 取代 K8s + +> [!summary]- Q85 答案与解析 +> **答案:A** — 在不同 stage 中分别完成编译和打包,拷贝产物到新镜像,剔除编译环境。 + +**Q86. Dockerfile 中 RUN、CMD、ENTRYPOINT 的区别是?** +A) RUN 构建时执行,CMD 和 ENTRYPOINT 运行时执行(CMD 可被 docker run 覆盖) +B) 三者完全相同 +C) CMD 在构建时执行 +D) ENTRYPOINT 可以被覆盖 + +> [!summary]- Q86 答案与解析 +> **答案:A** — RUN 在镜像构建阶段执行;ENTRYPOINT 为主命令不易变,CMD 是默认参数可覆盖。 + +**Q87. GitHub Actions 中 workflow_dispatch 触发器用于?** +A) 手动触发工作流 +B) Git push 自动触发 +C) PR 合并后触发 +D) cron 定时触发 + +> [!summary]- Q87 答案与解析 +> **答案:A** — 通过 UI 点击手动触发,常用于测试或紧急发布。 + +**Q88. CI/CD 流水线中 Lint 检查的阶段通常在?** +A) 代码提交后、单元测试前 +B) 部署之后 +C) 构建镜像之后 +D) 不需要这个环节 + +> [!summary]- Q88 答案与解析 +> **答案:A** — Lint 是最快发现规范问题的步骤,放在测试和构建之前以减少无效流水线运行。 + +**Q89. Docker Compose 中 depends_on 的作用局限性是?** +A) 仅表示服务间依赖顺序,不等待容器内进程就绪 +B) 自动重启失败的容器 +C) 管理环境变量 +D) 自动拉取镜像 + +> [!summary]- Q89 答案与解析 +> **答案:A** — depends_on 只保证启动顺序,需要配合 healthcheck 或 wait-for-it 脚本才能确保服务可用。 + +**Q90. Lark(飞书)OpenAPI 回调 Webhook 常用于?** +A) 接收事件通知(如审批、机器人消息) +B) 发送邮件 +C) 构建 Docker 镜像 +D) 监控 CPU + +> [!summary]- Q90 答案与解析 +> **答案:A** — 飞书 webhook 可将审批、聊天等事件实时推送到业务服务端。 + +### 十、微服务 & 架构(第 91-96 题) + +**Q91. 微服务架构中最核心的挑战之一是?** +A) 分布式一致性/跨服务通信 +B) 代码编写难度 +C) 内存占用 +D) CPU 使用率 + +> [!summary]- Q91 答案与解析 +> **答案:A** — 服务间调用带来延迟、幂等、Saga/TCC 事务一致性等难题。 + +**Q92. gRPC 默认使用的序列化协议是?** +A) Protobuf +B) JSON +C) XML +D) MessagePack + +> [!summary]- Q92 答案与解析 +> **答案:A** — Protobuf 二进制编码,体积小、解析快,优于 JSON。 + +**Q93. gRPC 和 RESTful API 的比较中不正确的是?** +A) gRPC 基于 HTTP/2,RESTful 通常 HTTP/1.1 +B) gRPC 契约驱动,适合强 typed 场景 +C) gRPC 不适合跨语言 +D) RESTful 更易被浏览器调试 + +> [!summary]- Q93 答案与解析 +> **答案:C** — gRPC 跨语言能力强(官方 SDK 支持 Go/Java/Python/Node…),Protobuf 天然多语言。 + +**Q94. SaaS 多租户架构中常见的数据隔离方案有几种?** +A) 三种:独立数据库、独立 Schema、共享 Schema 加 tenant_id +B) 一种:共享表 +C) 五种 +D) 两种 + +> [!summary]- Q94 答案与解析 +> **答案:A** — Level 1 独立库(最强隔离)、Level 2 独立 Schema、Level 3 共用表 tenant_id 列。 + +**Q95. RBAC(Role-Based Access Control)的核心实体有哪些?** +A) User–Role–Permission +B) User–Department +C) Project–Team +D) Tenant–Service + +> [!summary]- Q95 答案与解析 +> **答案:A** — 用户绑定角色,角色赋予权限,通过角色间接授权。 + +**Q96. 树状组织架构在 SaaS 平台中通常需要支持的操作是?** +A) 增删改查子节点 + 移动节点到不同父节点 +B) 仅查询 +C) 只支持扁平化 +D) 不需要支持树 + +> [!summary]- Q96 答案与解析 +> **答案:A** — 树状组织需要灵活维护层级关系,常见实现用 adjacency list 或 materialized path。 + +### 十一、AI & RAG(第 97-100 题) + +**Q97. RAG(Retrieval-Augmented Generation)的核心思想是?** +A) 从外部知识库检索相关信息,再让 LLM 基于这些资料生成回答 +B) 训练更大的模型 +C) 替换 Transformer 架构 +D) 直接微调全模型 + +> [!summary]- Q97 答案与解析 +> **答案:A** — RAG 将检索与生成解耦,避免全量微调,实时更新知识库成本低。 + +**Q98. Eino Agent Graph 编排 Prompt 优化→素材生成→质量校验→格式适配管线,本质上是?** +A) DAG 有向无环图工作流,保证节点按拓扑顺序执行 +B) 简单的 for-loop +C) 随机采样 +D) 并行随机组合 + +> [!summary]- Q98 答案与解析 +> **答案:A** — DAG 确保依赖关系正确:只有前置节点完成才可进入下一阶段。 + +**Q99. Reflect 自省机制在 AI Agent 中的作用是?** +A) 让 Agent 自我评估输出质量,不达标时自动回注提示词修正 +B) 加密数据 +C) 加速推理 +D) 替代向量数据库 + +> [!summary]- Q99 答案与解析 +> **答案:A** — Self-reflection 使 Agent 形成闭环:生成→评判→修正→再生成,逐步提升质量。 + +**Q100. 构建组件漏洞知识图谱的典型流程是?** +A) 抽取组件三元组(组件-漏洞-CVE)→ 存入图数据库 → 关联风险传播路径 +B) 写入 MySQL +C) 纯 NLP 模型生成 +D) 人工标注 + +> [!summary]- Q100 答案与解析 +> **答案:A** — 知识图谱用图结构表达实体关系,利于漏洞影响面分析与传播链路追踪。 + +## 关联笔记 + +- [[hzh/GO/Go 语言基础.md]] +- [[hzh/GO/并发模型.md]] +- [[hzh/Java/Spring 系列.md]] +- [[hzh/Redis/Redis 核心概念.md]] +- [[hzh/MySQL/MySQL 索引与事务.md]] +- [[hzh/项目经验/Gen2D 游戏素材生成.md]] +- [[hzh/项目经验/ThumbUP 高并发点赞系统.md]]