2025年5月9日 滴滴求储Java一面

自我介绍:

面试官好,我是北华大学 27 届本科生,来自计算机科学技术学院。

从大一开始我就进入了 我们学校的实验室进行学习 Java,我在大一上学完了 Java 基础 , 大一下学习了 Javaweb 开发和 spring 框架以及 springboot 的使用.

我在大一暑假速成学习了前端 vue

在大二上学期进行一段 三个月的小厂实习,

大二寒假我参加了字节青训,完成了前后端两个项目,并且写了自己的开源项目

大二下学期参加了 acm 算法竞赛获得了三块铜牌,

完成了学校的实验室的博客论坛项目部署上线并且系统学习了阿里体系的电商项目。

实习:

实习项目中遇到的挑战是什么?(todo)

这个问题需要提前准备一下 。实习主要干的事 react+ts 的全栈开发

八股

1.ArrayList和LinkedList区别

底层数据结构不同

一个是动态数组 一个是双向链表

ArrayList 在内存中声明的是一段连续的空间

LinkedList 在内存中声明的是一段不连续的空间

ArrayList 随机根据索引访问平均时间复杂度是 O1 而 LinkedList 是 ON

但是 LinkedList 的增删平均时间复杂度为 ON

ArrayList 是一直在扩容的数组

每次都会扩容为原来的 1.5 倍

如果要追求线程安全 可以使用 CopyOnWriteArrayList

LinkedList 实现了 Deque 接口 可以当做双端队列使用

2.了解的同步并发容器有哪些

CopyOnWriteArrayList

HashTable

ConcurrentHashMap

ConcurrentSkipListMap

ConcurrentLinkedQueue

BlockingQueue

BlockingDeque

3.线程池的参数、线程数量设定

七个核心参数

public ThreadPoolExecutor(
    
    int corePoolSize,                    // 核心线程数
    
    int maximumPoolSize,                 // 最大线程数
    
    long keepAliveTime,                  // 线程空闲时间
    
    TimeUnit unit,                       // 时间单位
    
    BlockingQueue<Runnable> workQueue,   // 任务队列
    
    ThreadFactory threadFactory,         // 线程工厂
    
    RejectedExecutionHandler handler     // 拒绝策略

)

线程数量的合理配置取决于任务类型(CPU 密集型、IO 密集型)和系统资源(CPU 核心数、内存)。

  1. CPU 密集型任务定义:任务主要消耗 CPU 资源(如计算、加密、解码)。最佳线程数:线程数 = CPU 核心数 + 1(额外 1 个线程用于处理可能的页缺失等异常情况)
int cores = Runtime.getRuntime().availableProcessors(); // 获取 CPU 核心数
  1. IO 密集型任务定义:任务主要等待 IO 操作(如数据库查询、网络请求、文件读写)。最佳线程数:线程数 = CPU 核心数 × (1 + 平均等待时间 / 平均处理时间)或简化为 线程数 = CPU 核心数 × 2(经验值)示例:若平均等待时间是处理时间的 3 倍,CPU 核心数为 8,则线程数 = 8 × (1 + 3) = 32。
  2. 混合型任务策略:若可拆分,将任务拆分为 CPU 密集型和 IO 密集型子任务,分别使用不同线程池;否则按 IO 密集型任务处理。

4.JVM内存区域

主要分为七个部分

  1. 程序计数器
  2. Java 虚拟机栈
  3. 本地方法栈
  4. 方法区
  5. 运行时常量池
  6. 直接内存

5.递归爆异常是属于哪个区域的溢出?

递归爆栈属于是栈溢出

因为递归是不断执行方法

函数调用会进栈 过多导致栈溢出

最终抛出 StackOverflowError 异常

JVM 栈 通常为 1mb 我们可以通过-Xss 参数调整

Java 线程执行时会为每一个线程分配独立的栈空间

用于存储一系列数据 例如方法的局部变量表,方法的返回地址

每个方法调用会创建一个栈帧 我们在递归调用时会不断压入新栈帧 直到内存耗尽

6.Java异常处理机制

Java 的异常处理机制基于 Throwable 类

大体分为两类

Error 错误 由 JVM 处理

Expection 异常 分为可检查异常 运行时异常

异常很重要 在我第一次实习的时候 因为每次都不写异常 还被批了

try - catch - finally

catch 作为捕获异常 我们需要按照子类在前 父类在后的顺序排列

在方法后加上 throws 表示可能抛出的异常 由调用者处理

也可以在 catch 的语句体里面用 throw 手动抛出

自定义异常可以继承 Expection 和 RuntimeExpection 并且在构造方法里将信息通过 super() 向上传

finally 里优先保证 try-with-resources 语法 保证资源正常退出 避免内存泄漏

7.AOP的实现原理

8.Spring循环依赖怎么解决?

循环依赖是我们从 ioc 容器注入 bean 的时候

造成的一种类似于死锁的情况

如果是构造器注入

我们可以使用@ Lazy 注解

9.Redis数据结构有哪些?

10.Redis缓存击穿和缓存雪崩

11.热Key问题怎么解决?

12.讲讲 redis 热点数据保存 方案,过期策略

13.索引数据结构是什么,为什么使用B+?

14.索引都有哪些?

15.索引失效有哪些?

16.查看是否走索引的方法

在MySQL中,要查看查询是否使用了索引,可以借助EXPLAIN语句来分析查询执行计划。下面为你介绍具体的操作方法和示例:

1. 使用EXPLAIN语句

EXPLAIN SELECT * FROM users WHERE age = 30;

执行上述语句后,MySQL会返回一个结果集,其中包含了查询执行的详细信息。我们重点关注以下几个字段:

  • type:该字段表示连接类型。若值为indexrangeconst等,就意味着查询使用了索引;若值为ALL,则表示查询进行的是全表扫描,没有使用索引。
  • key:此为MySQL实际选用的索引。若该字段值为NULL,则表明查询未使用索引。
  • Extra:该字段会显示一些额外信息,像Using index就表示查询使用了覆盖索引。

2. 示例分析

下面通过一个具体例子来进行说明:

-- 假设有如下表结构
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    age INT,
    INDEX idx_age (age)
);

-- 执行EXPLAIN查看是否使用索引
EXPLAIN SELECT * FROM users WHERE age = 30;

假设执行上述查询后,EXPLAIN的输出如下:

+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered |         Extra         |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------------+
| 1  | SIMPLE      | users | NULL       | range | idx_age       | idx_age | 5       | NULL  | 10   | 100.00   | Using index condition |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------------+

从这个输出结果我们可以得出以下结论:

  • type = range:这表明查询使用了索引来确定扫描范围。
  • key = idx_age:说明实际使用的索引是idx_age
  • Extra = Using index condition:意味着查询使用了索引条件下推(ICP)优化。

3. 注意事项

  • 覆盖索引:当查询的字段全部包含在索引中时,Extra字段会显示Using index,这种情况属于覆盖索引查询,能够极大地提高查询效率。
  • 索引失效:如果查询条件中使用了函数、表达式或者不恰当的类型转换,可能会导致索引失效。例如:
-- 索引失效示例
SELECT * FROM users WHERE YEAR(create_time) = 2023;
  • 执行计划缓存:在某些情况下,MySQL会缓存查询的执行计划。如果想要获取最新的执行计划,可以使用ANALYZE TABLE命令重新分析表。

4. 查看索引使用情况的其他方法

除了EXPLAIN语句,还可以通过以下方式来查看索引的使用情况:

  • SHOW STATUS LIKE 'Handler_read%':通过查看这个命令的返回结果,可以了解索引和表的读取次数。
  • pt-query-digest:这是一个第三方工具,能够分析慢查询日志并统计索引的使用情况。

通过上述方法,你就可以有效地判断MySQL查询是否使用了索引,进而对查询性能进行优化。

17.讲一下什么是分布式 session 讲讲 jwt

18. 讲讲 redis 的 aof 和 rof

#面试问题记录##牛客创作赏金赛#
27双非 Java后端开发面经 文章被收录于专栏

来源于自己的记录但是并不都是自己的面试经历 所有解答均是主观看法一个字一个字的敲的...

全部评论

相关推荐

评论
4
12
分享

创作者周榜

更多
牛客网
牛客企业服务