企鹅想必是大部分开发者梦寐以求的归宿了,除了有丰富的福利之外,还有优厚的薪资待遇,以及大厂光环,即使干几年跳槽了,也能有很多选择。

这不,训练营的小伙伴在拿下字节跳动之后,又拿下一城,顺便把腾讯也给收了:

但弱水三千只取一瓢饮,去哪家公司变成了最大的苦恼了,果然,优秀的人从来都不缺机会。

好了,那咱们这些吃瓜群众来看看腾讯面试题的难度吧,看看咱们这些普通人是不是也能搞定这场面试呢?

1.自我介绍一下?

好的自我介绍要讲清楚以下问题:

  1. 你是谁? 我是张三,今年有N年工作经验/XXX大学毕业的24届学生。
  2. 你会啥? 技术栈 -> 招聘岗位的技术要求去说。
  3. 你最大的成就是啥? -> 程序设计大赛的名次/XXX个项目。

2.ThreadLocal什么情况内存泄漏?

ThreadLocal 内存泄漏的场景有以下两个:

  1. 使用完 ThreadLocal 之后没有进行 remove 操作。
  2. ThreadLocal 相关的线程未关闭(ThreadLocal 生命周期和线程相关)。

3.Spring AOP实现原理?

AOP 底层实现是:动态代理

动态代理的具体实现:

  1. JDK Proxy
  2. CGLib

4.单例模式的好处?

  1. 整个生命周期只有一个对象 -> 对象复用
  2. 性能比较好(对象在使用前初始化好了)。

5.Redis内存结构知道哪些?

内存结构=数据类型,总共有以下几种:

  • 字符 -> 简单动态字符。
  • Hash -> 哈希表。
  • List -> 双向链表。
  • Set -> 哈希表 + 数组。
  • ZSet -> 压缩列表(ziplist)/紧凑列表(listpack) + 跳跃表(skiplist)。

6.说说Redis过期键的删除策略?

Redis 过期删除策略包含以下两种:

  1. 惰性删除:查询时在检查 key 是否过期 -> 内存利用率比较低。
  2. 定期删除:每秒检查设置了过期键的键值对,把过期的数据进行删除 -> 不是检索所有的数据进行删除、定期删除有最大的执行时间。

7.缓存雪崩以及如何解决?

缓存雪崩是指有大量缓存同时失效,造成了大量请求发送到数据库。

缓存雪崩的常见解决方案:

  1. 设置随机的过期时间。
  2. 缓存预热:当缓存快要过期之前,先去预加载缓存。
  3. 使用多级缓存:分布式缓存(Redis)+本地缓存。
  4. 使用限流手段。

8.MySQL为什么要选用B+树?

使用排除法:Hash、链表(查询慢)、AVL(二叉树添加、删除、查询性能低)、黑红树(二叉树添加、删除、查询性能低),所以只剩下多叉树:B 树、B+ 树。

B+ 相比于 B 树的优势:

  1. B+ 树 IO 次数更少,查询效率高。
  2. B+ 树有冗余节点,写入(新增/删除)通常改动小,速度快。
  3. B+ 节点之间使用有序链表来连接,所以更适合范围查询。

9.如何优化MySQL查询效率?

MySQL 查询效率优化的手段有以下几个:

  1. 使用正确的索引进行查询。
  2. 尽量能够实现索引覆盖(无需回表查询效率高)。
  3. 不能使用 select *。
  4. 不能进行函数运算 。
  5. 数据量比较大的情况下,可以分库分表。
  6. 使用分布式数据库,例如 TiDB。

10.说说联合索引和覆盖索引?

联合索引是一种在数据库中对多个字段同时建立的索引,它包含这些字段的值,并且这些值在索引中有特定的顺序。

联合索引的特征是:

  1. 多字段组合:联合索引可以包含两个或更多的字段,这些字段的值一起构成了索引键。
  2. 有序性:组成联合索引的字段顺序是重要的,不同的顺序会创建不同的索引。例如,ABC 和 ACB 是两种不同的联合索引。
  3. 最左匹配原则:在使用联合索引进行查询时,SQL 语句中的条件应该涉及到联合索引的最左边的字段,这样才能充分利用索引的优势。如果不遵循最左匹配原则,索引可能不会被使用。

索引覆盖是数据库优化查询性能的重要手段之一,索引覆盖是指查询所需的所有列数据都可以从索引中直接获取,而不需要回表查询原始数据行。

例如,我们员工表中有一个联合索引 age,id,此时我们使用以下 SQL 查询时就是索引覆盖(无需进行回表查询):

select id from users where age>18

但如果是 select * 的话就需要回表查询了,因此索引覆盖是数据库优化查询性能的重要手段之一,能不使用 select * 就不要使用 select *。

11.JVM 永久代存的是什么内容?

永久代是 Hotspot JVM 在 JDK 7 之前的叫法,而 JDK 8 之后就更改为元空间了。

永久代包含的内容如下:

  • 类信息。
  • 常量池。
  • 静态变量(JDK 7 后移动到堆上)。
  • 字符串常量池(JDK 7 后移动到堆上)。

12.SpringBoot如何做到启动的时候注入一些Bean?

依靠的是自动装配机制 -> 自动装配的底层实现是反射机制

13.SpringBoot 默认的包扫描路径?

默认的包扫描路径是 Spring Boot 启动类(添加了 @SpringBootApplication 注解的类)的同级目录,为默认的包扫描路径。

14.TCP 为什么需要 4 次挥手?

  1. 第一次挥手原因(客户端发消息给服务器端):此请求一定需要,因为我要告诉对方要断开连接。
  2. 第二次挥手原因(服务器端消息应答):TCP 本身它有消息应答,我要告诉发送方我收到你的消息了。
  3. 第三次挥手原因(服务器端发消息给客户端):服务器端要将接收缓冲区的任务执行完之后,才能真正的断开连接。
  4. 第四次挥手原因(客户端消息应答):对第三次握手的确认应答,真正的断开连接的回应。

15.java.util.concurrent包下了解哪些?

JUC 下的四个著名类:

  1. ReentrantLock:加锁机制,保证线程安全。
  2. Semaphore:基于计数器实现的限流器。
  3. CountDownLatch:用于一个线程等待其他多个线程完成各自工作之后才能继续执行的场景。它像是一个倒计数器,当计数达到零时,等待的线程被唤醒继续执行。
  4. CyclicBarrier:允许一组线程相互等待,直到所有线程都准备好继续执行。与 CountDownLatch 不同的是,CyclicBarrier 可以重用,并且可以指定在释放等待之前每个线程必须完成的工作。

以上内容来自我的 《Java 面试突击训练营》,这门课程是 有着 14 年工作经验(前 360 开发工程师),9 年面试官经验的我,花费 4 年时间打磨完成的一门视频面试课

整个课程从 Java 基础到微服务 Spring Cloud、从实际开发问题到场景题应有尽有,如下图所示:

全程通过视频直播 + 录播的方式,把 Java 常见的面试题系统的过一遍,遇到一个问题,把这个问题相关的内容都给大家讲明白,并且视频支持永久更新和观看。

上完训练营的课程之后,基本可以应对目前市面上绝大部分公司的面试了,想要了解详情,加我微信:vipStone【备注:训练营】