10年JAVA转GO,冲刺金九银十30K+,中间件深挖和拷打,踩坑分享

今天分享的内容是:最近和组织内部朋友进行的模拟面试的内容复盘,以后也会把这些通用的大家容易踩坑的地方总结分享出来,大家可以点赞、关注或者转发支持一波。

这位朋友有10年的工作经验,之前做的是Java开发,自己想转Go就找到了我们,想在9月份的时候跳槽。

面试内容聊的都是开发绕不开的 MySQL、Redis、Kafka 这些硬骨头。整体聊下来,发现他对基础概念有印象,但不少细节要么有点含糊其辞,要么理解有偏差。今天我就从对话中挑出 10 个有代表性的问题,好好拆解拆解。

这篇文章既是复盘,也是给各位朋友提个醒,这些坑可别踩。

1. 索引下推是什么

对话回放

我:那下面就请你先来讲一下,索引下推是什么,说一下。

他:就是在数据查询过程中,涉及到 MySQL 的 server 层和引擎层,一般走索引的话,返回后会在 server 层做过滤和组装;而索引下推的话,查询过程在引擎层就处理完了,返回给 server 层的就是最终结果。大概是这么个意思?

他回答的问题在哪?

解释少了核心:索引下推的本质是 “将本应在 server 层做的过滤逻辑,下放到引擎层利用索引完成”,目的是减少引擎层返回给 server 层的数据量。比如用联合索引查询时,引擎层可以根据索引中的字段直接过滤掉不符合条件的记录,不用把所有符合索引前缀的记录都返回给 server 层再过滤。

正确的打开方式

索引下推是 MySQL 的一种查询优化机制:当查询使用二级索引时,server 层会把本应在自身进行的 “where 条件过滤”,下放到引擎层;引擎层在遍历索引的同时,就会对索引中包含的字段做条件判断,只把符合条件的记录返回给 server 层。这样能减少引擎层和 server 层之间的数据传输,提高查询效率。

比如查询 “where name like ’ 张 %’ and age > 20”,若联合索引是(name, age),引擎层会直接过滤掉 age≤20 的记录,不用把所有 “name 以张开头” 的记录都返回给 server 层。

2. 什么是死锁

对话回放

我:再讲一下死锁的四个条件是什么?

他:死锁的四个条件,一个就是有资源竞争,然后循环依赖,不可剥夺,然后请求保持。

他回答的问题在哪?

名称记混了两个:“循环依赖” 应为 “循环等待”,“请求保持” 应为 “持有与等待”。这四个条件是死锁产生的必要条件,缺一不可,记准名称是基础。

正确的打开方式

死锁产生的四个必要条件:

  • 互斥条件:资源只能被一个进程占用,不能共享;
  • 持有与等待条件:进程已持有至少一个资源,又提出新的资源请求,而新资源被其他进程占用,此时进程会保持已持有的资源并等待新资源;
  • 不可剥夺条件:已分配的资源不能被强制收回,只能由持有进程主动释放;
  • 循环等待条件:多个进程形成环形等待链,每个进程都在等待下一个进程持有的资源。

3. 不设主键会怎么样

对话回放

我:在设计数据库表的时候不设置主键会怎么样?

他:不设置主键的话,MySQL 会自动加一个隐藏的主键。

他回答的问题在哪?

InnoDB 引擎下,若表没有显式主键,会优先选择非空唯一索引作为主键;若没有非空唯一索引,才会生成一个 6 字节的隐藏列row_id作为主键,这个row_id对外不可见,仅用于 InnoDB 内部组织数据(比如聚簇索引)。

正确的打开方式

MySQL 的 InnoDB 引擎表必须有主键(聚簇索引的基础),若未显式定义,会按以下规则自动生成:

  1. 优先选择表中第一个非空唯一索引作为主键;
  2. 若没有非空唯一索引,会自动创建一个隐藏的row_id列作为主键,row_id是自增的,但仅用于内部数据组织;
  3. 建议显式设置主键,因为隐藏的row_id可能导致聚簇索引页分裂(自增特性),且非空唯一索引作为主键的查询效率更高。

4. 索引建立的原则

对话回放

我:加索引不能乱加,在哪些情况下我们才会选择添加索引

他:根据实际的查询条件来加索引

我:具体有哪些条件?

他:比如多个字段的联合查询。

他回答的问题在哪?

“根据查询条件” 是大方向,但不够落地。索引是把双刃剑,加得好能加速查询,加得不好会拖慢写入(因为索引需要维护),得兼顾查询频率、字段特性和更新成本。

正确的打开方式

索引建立的核心原则:

  • 高频查询字段优先:where、order by、group by 中频繁出现的字段,比如用户表的 “手机号”(登录查询);
  • 高基数字段优先:字段值重复少(比如身份证号,基数接近记录数),低基数字段(如性别,只有 2 个值)加索引意义不大;
  • 联合索引看顺序:遵循 “最左前缀原则”,把过滤性强的字段放前面(比如 “手机号 + 验证码” 比 “验证码 + 手机号” 更合理);
  • 避免更新频繁字段:索引会随数据更新而同步维护,更新频繁的字段(如订单状态)加索引会导致写入变慢;
  • 控制数量:单表索引建议不超过 5 个,太多会让 MySQL 优化器在选择索引时 “犯迷糊”,还会占用额外存储空间。

5. redo log 和 binlog 的刷盘机制

对话回放

我:下面再讲一下,redo log 和 binlog 的刷盘机制是什么?

他:刷盘有三种配置,一种是每次事务提交,写到 page cache 里,但不强制操作系统落盘,由系统自己触发;一种是写到 page cache,事务提交时强制操作系统落盘;还有一种是不写 page cache,由后台定时任务刷到 page cache 再落盘。binlog 和 redo log 类似,但 binlog 是基于写了多少个日志后刷盘,redo log 是定时的。

我:其实可以更具体,比如 binlog 的 sync_binlog 参数,设为 0 是系统自动刷盘,设为 1 是每次提交都刷盘…

他回答的问题在哪?

逻辑大致对,但没提具体参数,等于没说透。redo log 和 binlog 的刷盘机制直接影响数据安全性和性能,参数是必须记牢的核心细节。

正确的打开方式

  • redo log(由 innodb_flush_log_at_trx_commit 控制)
    • 0:事务提交时,日志只写到 redo log buffer,由后台线程每秒刷盘(可能丢失 1 秒内数据);
    • 1(默认):事务提交时,直接刷盘(最安全,性能略低);
    • 2:事务提交时写到操作系统缓存(page cache),由系统决定刷盘(可能丢失操作系统崩溃前的数据)。
  • binlog(由 sync_binlog 控制)
    • 0:事务提交时写到 binlog cache,由系统不定时刷盘(风险高,可能丢失大量数据);
    • 1(建议):每次事务提交都刷盘(安全,性能有损耗);
    • N(N>1):每 N 次事务提交刷盘一次(折中方案,最多丢失 N 个事务数据)。

6. Redis 默认的持久化机制

对话回放

我:持久化除了 AOF 和 RDB,还有混合持久化,讲一下。

他:混合持久化就是两者的结合,文件上半部分是 RDB,下半部分是 AOF。

我:那Redis 默认采用哪种持久化方式?

他:我记得默认是 AOF 开启吧?

我:你可以去了解一下,默认应该是 RDB。

他回答的问题在哪?

这是个典型的易混点。Redis 默认只开启RDB,不开启 AOF。AOF 需要手动配置appendonly yes才会生效,而混合持久化(RDB+AOF)更是需要额外开启aof-use-rdb-preamble yes

正确的打开方式

Redis 的三种持久化方式及默认配置:

  • RDB:默认开启,通过快照方式保存某一时刻的内存数据,触发条件由save指令定义(如save 900 1表示 900 秒内有 1 次修改就触发);
  • AOF:默认关闭,需配置appendonly yes,记录所有写操作,刷盘策略由appendfsync控制(默认everysec,每秒刷盘一次);
  • 混合持久化:Redis 4.0 + 支持,默认关闭,需配置aof-use-rdb-preamble yes,文件前半部分是 RDB 快照,后半部分是 AOF 增量日志,兼顾恢复速度和数据完整性。

7. Redis 定期删除策略

对话回放

我:那定期删除的详细流程是怎么样的?

他:随机取 20 个 key,若过期的超过 25%,就再取 20 个,直到过期的少于 25%,或者循环时间大于 25 秒就退出。

他回答的问题在哪?

时间限制说错了。Redis 是单线程,定期删除是 “快速检测”,每次循环耗时不能超过500ms(避免阻塞主线程),否则会暂停,等下次再执行。25 秒的话那服务早就卡死了。

正确的打开方式

Redis 定期删除流程(针对过期 key):

  1. 从过期字典中随机抽取 20 个 key;
  2. 删除其中已过期的 key;
  3. 若过期 key 占比≥25%,重复步骤 1-2;
  4. 若循环次数过多,总耗时超过 500ms 则停止,避免影响正常请求处理。这个机制既能减少过期 key 堆积,又不会因删除操作阻塞主线程。

8. 数据库与缓存的数据一致性如何保证

对话回放

我:数据库和缓存的数据一致性如何保证?

他:常用的是 Cache Aside,写的时候先写库,再删缓存;读的时候先读缓存,没命中就读库,再更新缓存。
我:除了这个还有吗?

他:还有读穿或者写穿,但感觉它们的一致性没 Cache Aside 高。具体内容不太清楚

他回答的问题在哪?

“读穿”“写穿” 的一致性并不比 Cache Aside 低,只是适用场景不同。这几种策略没有绝对优劣,得结合业务选。

正确的打开方式

四种主流的缓存更新策略:

  • Cache Aside(旁路缓存):应用直接操作数据库和缓存,写流程 “写库→删缓存”,读流程 “读缓存→未命中读库→更新缓存”,适合读写分离场景,需注意 “删缓存” 而非 “更新缓存”(避免脏数据);
  • Read Through(读穿):缓存代理负责读操作,未命中时自动查库并更新缓存,应用只与缓存交互,适合不想手动处理缓存更新的场景;
  • Write Through(写穿):缓存代理负责写操作,写流程 “更新缓存→更新数据库”,同步更新,一致性高,但写性能略低;
  • Write Back(回写):写操作只更新缓存,缓存异步批量更新数据库,写性能好,但可能丢数据(如缓存宕机),适合非核心数据(如浏览量)。

9. Kafka 的 ISR 机制

对话回放

我:什么是 Kafka 的 ISR 机制?

他:ISR 就是同步副本的列表,里面的副本会同步主副本的数据。

我:ISR 指的是与 leader 副本保持同步状态的所有副本的集合,“同步” 是有标准的。

他回答的问题在哪?

只说了 “同步副本列表”,没说清 “同步” 的标准和作用。ISR 是 Kafka 保证数据可靠性的核心,“同步” 不是指实时一致,而是有明确的滞后阈值。

正确的打开方式

ISR(In-Sync Replicas)机制:

  • 定义:ISR 是与 leader 副本保持同步的所有副本(包括 leader 自身)的集合;
  • 同步标准:副本需满足两个条件 ——① 能定期向 leader 发送心跳(默认每 3 秒);② 滞后 leader 的消息量不超过replica.lag.time.max.ms(默认 30 秒),超过则被移出 ISR;
  • 作用:leader 宕机时,新 leader 只会从 ISR 中选举,确保新 leader 有尽可能新的数据,避免数据丢失;若 ISR 为空,会从 OSR(Out-of-Sync Replicas)中选,但可能丢数据。

10. Kafka 消息丢失怎么解决

对话回放

我:Kafka 发生消息丢失怎么办?有哪些方式可以避免?

他:生产者有重试机制,acks 设为 all 的话,ISR 所有副本确认才算成功;broker 端异步刷盘可能丢数据;消费者自动提交 offset 可能丢数据。

他回答的问题在哪?

方向对,但不够具体。消息丢失可能发生在生产者、broker、消费者任一环节,每个环节的防丢失配置都有细节。

正确的打开方式

全链路防消息丢失配置:

  • 生产者
    • acks=all:消息需被 ISR 中所有副本确认才算发送成功;
    • retries>0:失败自动重试,配合retry.backoff.ms控制间隔;
    • 开启回调函数,确认发送结果,失败后人工介入。
  • broker
    • unclean.leader.election.enable=false:禁止从非 ISR 副本中选 leader,避免数据丢失;
    • replica.lag.time.max.ms:合理设置副本同步超时时间(默认 30 秒),确保 ISR 中的副本数据足够新。
  • 消费者
    • enable.auto.commit=false:关闭自动提交,改为处理完消息后手动提交 offset;
    • 若用自动提交,需确保auto.commit.interval.ms合理,避免 “处理中提交” 导致的丢失(处理失败后,offset 已提交,消息不会再被消费)。

总结

整场面试下来,能看出他对基础概念有框架性了解,但有些细节问题要么记混了,要么没说透,很多朋友都有这样的问题,后端技术面试,一定是 “细节见真章”。

建议各位朋友 复习时,别只记 “大概意思”,多抠抠具体细节、流程、适用场景,毕竟实际工作中,出问题的往往就是这些地方。

欢迎关注 ❤

我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。

没准能让你能刷到自己意向公司的最新面试题呢。

感兴趣的朋友们可以私信我,备注:面试群。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值