卡码笔记-最强八股文
首页
计算机基础
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
简历专栏
代码随想录 (opens new window)
首页
计算机基础
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
简历专栏
代码随想录 (opens new window)
  • Java面经

    • 阿里面经
    • 11.23阿里面经
    • 26.4.21阿里Java后端开发
    • 26.4.21阿里Java实习
    • 12.4美团面经
    • 美团日常实习一面
    • 26.2.1美团Java日常实习
    • 26.2.2美团一二面
    • 26.2.5美团Java实习
    • 26.2.8美团一二面
    • 26.2.20美团Java后端实习
    • 26.2.22美团后端面经
    • 26.3.1美团Java后端技术
    • 12.27腾讯面经
    • 腾讯日常实习Java技术
    • 26.3.7腾讯Java秋招
    • 26.4.4腾讯天美后台开发
    • 腾讯云面经
    • 26.1.1字节跳动二面
    • 26.1.10字节跳动后端一面
    • 26.1.10字节跳动后端二面
    • 26.1.25字节电商后端
    • 26.4.3小红书Java面经
    • 26.4.12小红书后端一面
    • 26.4.13小红书研发一面
    • 26.4.28百度面经
      • 12.10京东面经
      • 26.1.22海康威视面经
      • 快手一面面经
      • 盒马面经
      • 众安后端一面面经

    # 百度面经

    # ThreadLocal 的实现原理?

    1. ThreadLocal 是 Java 提供的线程本地变量工具,核心作用是让每个线程都持有一份自己的变量副本,避免多个线程直接竞争同一份共享变量。
    2. ThreadLocal 本身不直接保存数据,真正的数据保存在当前线程对象的 ThreadLocalMap 中。结构可以理解为:Thread -> ThreadLocalMap -> Entry(ThreadLocal, value)。
    3. 调用 set() 时,会先拿到当前线程,再拿到线程内部的 ThreadLocalMap,然后以当前 ThreadLocal 对象作为 key,把业务值作为 value 放进去。调用 get() 时,也是先找到当前线程的 map,再通过当前 ThreadLocal 找到对应 value。
    4. 在线程池场景中,工作线程会被复用,所以使用完 ThreadLocal 后最好在 finally 中调用 remove(),避免内存泄漏和上下文串用。

    # ThreadLocalMap 中的 key 和 value 是什么类型的引用?

    1. ThreadLocalMap 里的每个元素是一个 Entry,它继承了 WeakReference<ThreadLocal<?>>,所以 key 是 ThreadLocal 对象的弱引用。
    2. value 是真正存储的线程本地变量,类型是 Object,并且是 Entry 对 value 的强引用。
    3. 可以简单理解为:key 只是当前 ThreadLocal 的弱引用入口,value 才是业务真正放进去的数据。

    # 为什么 key 能被 GC 自动回收,但 value 不能被 GC 自动回收?

    1. key 是弱引用,当外部没有强引用再指向这个 ThreadLocal 对象时,下一次 GC 就可以把 key 回收掉,ThreadLocalMap 里的 key 会变成 null。
    2. value 不一样,它仍然被 ThreadLocalMap.Entry 强引用着。只要线程还存活,Thread -> ThreadLocalMap -> Entry -> value 这条引用链还在,value 就仍然是可达对象,GC 不会主动回收。
    3. ThreadLocalMap 会在部分 get()、set()、remove() 操作中顺带清理 key 为 null 的陈旧 Entry,但这个清理不是实时保证的。所以在线程池这种长生命周期线程里,必须主动调用 remove()。

    # value 主要是什么?

    1. value 就是调用 ThreadLocal.set(value) 放进去的业务对象,也就是当前线程独享的变量副本。
    2. 常见 value 有用户上下文、租户 ID、权限信息、traceId、请求上下文、事务上下文、数据库连接资源、线程私有工具对象等。
    3. 实际开发中不建议把大对象长期放进 ThreadLocal,尤其在线程池里,如果忘记清理,会让内存压力和排查难度都变大。

    # 垃圾回收器有哪些?

    1. 新生代常见收集器有 Serial、ParNew、Parallel Scavenge。Serial 是单线程收集器,ParNew 是 Serial 的多线程版本,Parallel Scavenge 更关注吞吐量。
    2. 老年代常见收集器有 Serial Old、Parallel Old、CMS。Serial Old 是单线程标记整理,Parallel Old 关注吞吐量,CMS 追求低停顿,但会有内存碎片和浮动垃圾问题。
    3. 整堆收集器常见的是 G1,它把堆划分成多个 Region,优先回收价值高的区域,兼顾吞吐和停顿控制。更新一些的低延迟收集器还有 ZGC、Shenandoah,更适合超大堆和低停顿场景。
    4. 面试里可以按场景总结:后台计算更偏向吞吐量,可以考虑 Parallel;在线服务更关注响应时间,常见选择是 G1;CMS 现在更多作为历史方案理解。

    # 可达性分析法的 GC Roots 有哪些?

    1. 可达性分析会从一组 GC Roots 出发向下搜索,如果一个对象到 GC Roots 没有任何引用链相连,就认为这个对象不可达,可以被回收。
    2. 常见 GC Roots 包括:
      • 虚拟机栈中局部变量表引用的对象
      • 本地方法栈中 JNI 引用的对象
      • 方法区中类静态属性引用的对象
      • 方法区中常量引用的对象
      • 被 synchronized 锁持有的对象
      • 活跃线程、系统类加载器等 JVM 运行时自身持有的对象

    链可达性判断

    # 为什么选这些对象作为 GC Root?

    1. 这些对象本质上代表了程序当前还能直接访问到的入口,比如正在执行的方法栈、全局静态变量、JNI 句柄、锁对象和 JVM 运行时结构。
    2. 只要从这些入口还能访问到某个对象,就说明这个对象后续仍可能被程序使用,不能被垃圾回收器误删。
    3. GC Root 不是说对象永远不会被回收,而是说它在当前这次可达性分析中作为根节点存在。等方法执行结束、线程结束、静态引用置空或 JNI 引用释放后,它就可能不再是 GC Root。

    # 平时使用 MySQL 是怎么用的?

    1. 项目里一般把 MySQL 作为核心关系型存储,用来保存用户、订单、文件、权限、配置这类需要持久化和事务一致性的数据。
    2. 开发时会通过 MyBatis、JPA 或 JDBC 访问 MySQL,围绕表结构设计、主键设计、索引设计、SQL 编写、事务控制和连接池配置来使用。
    3. 日常优化上会关注 SQL 是否走索引、是否有慢查询、是否需要分页优化、是否出现锁等待或死锁。常用 explain 看执行计划,结合慢 SQL 日志和监控定位问题。

    # MySQL 的存储引擎?

    1. 存储引擎负责表数据的存储、索引组织、事务、锁和崩溃恢复等底层能力。MySQL 支持多种存储引擎,可以通过 show engines 查看。
    2. 常见的有 InnoDB、MyISAM、Memory、Archive、CSV 等。InnoDB 是现在最常用的默认引擎,支持事务、行锁、MVCC、外键和崩溃恢复。
    3. MyISAM 不支持事务,主要是表锁,读性能较好但并发写能力和一致性能力弱。Memory 把数据放在内存里,适合临时数据。Archive 更偏向归档存储,适合大量写入、很少更新的历史数据。

    # 为什么用 InnoDB 做默认存储引擎?

    1. InnoDB 支持 ACID 事务,通过 redo log 保证持久性,通过 undo log 支持回滚和 MVCC,更适合业务系统对一致性的要求。
    2. InnoDB 支持行级锁和 MVCC,读写并发能力比表锁模型更好。普通快照读不会阻塞写,写操作也能尽量缩小锁范围。
    3. InnoDB 使用 B+ 树索引,主键索引是聚簇索引,查询、范围扫描和排序都比较稳定。再加上崩溃恢复、外键等能力,所以通用业务场景默认选择 InnoDB 更稳。

    # 事务隔离级别有哪些?

    1. MySQL 常见四种隔离级别是:读未提交、读已提交、可重复读、串行化。InnoDB 默认使用的是可重复读。
    2. 读未提交可以读到其他事务未提交的数据,会出现脏读、不可重复读和幻读。
    3. 读已提交只能读到其他事务已经提交的数据,解决了脏读,但仍可能出现不可重复读和幻读。
    4. 可重复读保证同一个事务内多次读取同一数据结果一致,解决脏读和不可重复读。InnoDB 在可重复读下通过 MVCC 和 Next-Key Lock 尽量解决幻读问题。
    5. 串行化隔离级别最高,会让事务串行执行,可以解决脏读、不可重复读和幻读,但并发性能最差。

    # update b = b + 1 where b = 5 在可重复读隔离级别下,5 个线程并发执行,最后 b 的值是多少?

    1. 如果假设只有一行数据,初始 b = 5,实际 SQL 是 update t set b = b + 1 where b = 5,5 个事务并发执行后,最后通常是 6。
    2. 原因是 update 属于当前读,不是普通 select 那种快照读。第一个事务拿到行锁后把 b 从 5 改成 6,其他事务会等待这个行锁释放。
    3. 等第一个事务提交后,后面的事务会读取最新版本并重新判断 where b = 5,这时条件已经不满足了,所以后续事务影响行数是 0,不会继续把 6 改成 7。
    4. 如果条件不是 where b = 5,而是按主键更新同一行,比如 where id = ?,那 5 个事务依次加锁并执行累加,最终就可能从 5 变成 10。关键区别在于更新后是否还满足 where 条件。

    # OSI 网络模型?

    1. OSI 七层模型从上到下分别是:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
    2. 应用层直接面向应用程序,常见协议有 HTTP、HTTPS、DNS、FTP。表示层负责数据格式转换、加密解密、压缩解压。会话层负责会话建立、管理和释放。
    3. 传输层负责端到端通信,典型协议是 TCP 和 UDP。网络层负责 IP 寻址和路由转发,典型协议是 IP、ICMP。数据链路层负责把网络层数据封装成帧,处理 MAC 地址、差错检测和链路访问控制。物理层负责比特流在网线、光纤、无线信号上的传输。
    4. 实际工程里更常用的是 TCP/IP 四层模型:应用层、传输层、网络层、网络接口层。

    # 数据链路层有哪些协议?

    1. 数据链路层的核心职责是成帧、MAC 地址寻址、差错检测、链路访问控制,保证相邻节点之间可以传输数据帧。
    2. 常见协议或标准有 以太网 Ethernet / IEEE 802.3、Wi-Fi / IEEE 802.11、PPP、HDLC、Frame Relay、VLAN / IEEE 802.1Q、STP / IEEE 802.1D。
    3. 面试里也经常会把 ARP 放到链路层相关内容里讨论,因为它负责把 IP 地址解析成 MAC 地址,帮助网络层数据包在局域网内找到下一跳的链路层地址。
    Last Updated: 4/30/2026, 11:54:17 AM

    ← 26.4.13小红书研发一面 12.10京东面经 →

    评论

    验证登录状态...

    侧边栏
    夜间
    卡码简历
    代码随想录
    卡码投递表🔥
    2026群
    添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
    支持卡码笔记
    鼓励/支持/赞赏Carl
    1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
    2. 希望大家都能梦想成真,有好的前程,加油💪