???? 作者 :“码上有前”
???? 文章简介 :Java
???? 欢迎小伙伴们 点赞????、收藏⭐、留言????
文章题目:Java核心面试问题41-50期深度解析:从数据库优化到并发场景解决方案
摘要:
本篇文章详细解答了Java面试中第41-50期的高频技术问题,涵盖接口安全性设计、MySQL优化与索引应用、类加载原理、线程池异常处理、海量数据导入导出的方案及高并发接口解决方案。通过理论分析与实战代码结合,帮助开发者快速掌握这些关键知识点,在面试和实际开发中脱颖而出。
1. 业务开发时,接口不能对外暴露怎么办?
回答:
可通过鉴权机制限制接口访问,如采用IP白名单、访问令牌(token)或网关进行管理。
最佳实践:
通过Spring Security实现鉴权:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/internal/**").hasIpAddress("192.168.1.0/24")
.anyRequest().authenticated();
}
}
2. 为什么不建议在MySQL中使用UTF-8?
回答:
MySQL的utf8
编码实际上不支持4字节字符(如emoji),推荐使用utf8mb4
以全面支持多字节字符。
最佳实践:
修改表字符集:
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
3. MySQL上亿大表如何优化?
回答:
- 分库分表:将数据拆分到多个库或表中;
- 创建合适的索引;
- 水平分区或垂直分区;
- 限制查询范围,如使用分页。
最佳实践:
按时间分区:
ALTER TABLE orders PARTITION BY RANGE (YEAR(order_date)) (
PARTITION p2021 VALUES LESS THAN (2022),
PARTITION p2022 VALUES LESS THAN (2023)
);
4. MySQL索引失效有哪些场景?
回答:
- 使用
%
开头的模糊查询; - 数据类型不匹配;
- 使用函数操作字段;
- OR条件未覆盖索引。
最佳实践:
避免索引失效:
SELECT * FROM users WHERE name LIKE 'John%'; -- 索引生效
5. Java类加载过程是怎么样的?
回答:
-
加载:通过类加载器加载
.class
文件; - 验证:校验字节码;
- 准备:为静态字段分配内存;
- 解析:符号引用转为直接引用;
-
初始化:执行类的
<clinit>
方法。
最佳实践:
自定义类加载器:
public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) {
// 自定义加载逻辑
}
}
6. 线程池执行的用户任务抛出异常会怎样?
回答:
任务抛出异常不会影响线程池运行,但可能导致任务丢失。
最佳实践:
捕获异常或自定义线程池:
public class LoggingThreadPool extends ThreadPoolExecutor {
@Override
protected void afterExecute(Runnable r, Throwable t) {
if (t != null) {
System.err.println("任务抛出异常:" + t.getMessage());
}
}
}
7. 线上MySQL的自增ID用尽怎么办?
回答:
- 更换ID生成策略(如UUID或雪花算法);
- 增加ID步长;
- 使用分布式ID生成器。
最佳实践:
配置自增步长:
SET @@auto_increment_increment=10;
8. 为什么HashMap使用的时候注意容量?
回答:
当HashMap容量超过阈值时,会触发扩容,导致性能下降。扩容过程包括重新计算哈希和数据迁移。
最佳实践:
预估容量,避免频繁扩容:
Map<String, String> map = new HashMap<>(128);
9. 百万数据导入导出方案,怎么设计?
回答:
- 导入:批量插入+分片处理;
- 导出:流式读取+分段处理。
最佳实践:
使用JDBC批量插入:
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO users (name) VALUES (?)");
for (int i = 0; i < data.size(); i++) {
pstmt.setString(1, data.get(i));
pstmt.addBatch();
if (i % 1000 == 0) pstmt.executeBatch();
}
10. 海量请求下的接口并发解决方案
回答:
- 限流:如漏桶算法或令牌桶算法;
- 缓存:减少数据库查询;
- 异步处理:将请求写入队列异步执行;
- 分布式锁:控制并发更新。
最佳实践:
结合Redis限流:
String key = "rate_limit:" + userId;
if (redis.incr(key) > MAX_REQUESTS) {
throw new RuntimeException("请求过多");
}
redis.expire(key, 1, TimeUnit.SECONDS);
总结:
本文通过对41-50期面试问题的解析,从接口安全、数据库优化到并发控制,涵盖了Java开发中的多个技术点。通过实战代码与理论的结合,帮助开发者轻松应对高难度面试,同时提升实际开发技能。