【81-90期】Java核心面试问题深度解析:性能优化与高并发设计

🚀 作者 :"码上有前"

🚀 文章简介 :Java

🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬

文章题目:Java核心面试问题深度解析:性能优化与高并发设计

摘要

本文聚焦于第81-90期Java面试的高频问题,从数据库连接池设计、Nginx压缩、多线程事务处理,到Java内存泄漏排查和Spring IOC解耦,全面剖析了关键技术点,并提供详细的代码实例和实践方法,助力开发者深入理解核心Java技术,在面试和实际开发中游刃有余。


1. 为什么数据库连接池不采用IO多路复用?

回答

数据库连接池主要用于管理与数据库之间的TCP连接,而不是直接操作Socket的IO。IO多路复用如epoll主要用于高并发场景下的非阻塞IO处理,适合处理成千上万的短连接。

  • 数据库连接池:重在复用数据库的长连接,减少频繁创建和销毁连接的成本。
  • IO多路复用:适合大量并发但轻量的网络请求,而数据库操作通常较重。

最佳实践

使用HikariCP连接池:

java 复制代码
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/db");
config.setUsername("user");
config.setPassword("password");
HikariDataSource dataSource = new HikariDataSource(config);

2. 说一下Nginx静态压缩和代码压缩

回答

  • 静态压缩 :在文件生成时提前压缩,如生成.gz文件,由Nginx直接返回压缩后的静态资源;
  • 动态压缩:实时对响应内容进行压缩,常用算法如Gzip。

最佳实践

在Nginx中启用Gzip动态压缩:

nginx 复制代码
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1024;
gzip_comp_level 5;

3. 多线程事务怎么回滚?

回答

多线程环境下事务的回滚需要保证跨线程的一致性,可以通过以下方式实现:

  1. 独立事务:每个线程独立控制事务,彼此隔离;
  2. 分布式事务 :通过分布式事务协调器(如Seata)实现全局事务管理;
  3. 手动管理:线程执行结果汇总后决定是否回滚。

最佳实践

使用Seata管理分布式事务:

java 复制代码
@GlobalTransactional
public void execute() {
    // 分布式事务逻辑
}

4. Java Switch是如何支持String的?为什么不支持long?

回答

  • String支持 :Java 7通过将String转换为hashCode实现支持。
  • long不支持Switch本质上是基于有限离散值(如intchar),而long值范围过大,无法高效实现。

最佳实践

避免过多case,保持代码简洁:

java 复制代码
switch (input) {
    case "A": System.out.println("Option A"); break;
    case "B": System.out.println("Option B"); break;
    default: System.out.println("Default option");
}

5. 公司规定所有接口都用POST请求,这是为什么?

回答

  1. 安全性POST请求参数不会暴露在URL中,更适合传递敏感信息;
  2. 灵活性POST支持更大的请求体;
  3. 幂等性 :限制为POST可以防止错误修改数据。

最佳实践

通过Spring Boot限制接口方法:

java 复制代码
@PostMapping("/create")
public ResponseEntity<String> create(@RequestBody Data data) {
    // 业务逻辑
}

6. Redis的keys命令到底有多慢?

回答
keys命令会遍历Redis中的所有键,时间复杂度为O(n),在键数量很大时会导致严重的性能问题,甚至阻塞Redis服务。
替代方案 :使用SCAN命令进行分批迭代。

最佳实践

bash 复制代码
SCAN 0 MATCH user:* COUNT 100

7. 为什么MySQL单表行数不要超过2000万?

回答

  1. 查询性能下降:超过一定规模,查询需要扫描更多行;
  2. 索引维护开销大:索引操作效率降低;
  3. 备份与恢复:表数据过大会影响备份和恢复速度。

优化方案

  • 垂直拆分:将字段分布到不同表;
  • 水平分片:按主键或时间拆分表。

最佳实践

使用分区表:

sql 复制代码
CREATE TABLE orders (
    id INT NOT NULL,
    order_date DATE NOT NULL
) PARTITION BY RANGE (YEAR(order_date)) (
    PARTITION p2021 VALUES LESS THAN (2022),
    PARTITION p2022 VALUES LESS THAN (2023)
);

8. Java内存泄漏了,怎么排查?

回答

  1. 工具检测 :使用JVisualVMMAT分析堆内存;
  2. 日志监控 :启用-XX:+HeapDumpOnOutOfMemoryError生成堆转储文件;
  3. 代码检查 :查找未释放的资源(如InputStreamSocket)。

最佳实践

启用内存转储:

bash 复制代码
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump

9. Spring IOC为什么能降低耦合?

回答

Spring IOC(控制反转)通过依赖注入(DI)管理对象的创建和依赖关系,使对象之间通过接口而不是实现类耦合。

  • 解耦的原理:依赖通过容器注入,而非在类中硬编码。
  • 优点:降低了模块之间的依赖,提高可测试性。

最佳实践

通过注解实现依赖注入:

java 复制代码
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

10. 布隆过滤器和谷鸟过滤器的区别及应用场景?

回答

  1. 布隆过滤器:通过位图和多个哈希函数快速判断元素是否存在,但可能存在误判;
  2. 谷鸟过滤器(Cuckoo Filter):支持删除操作,并且误判率更低。

应用场景

  • 布隆过滤器:适用于黑名单校验、大量数据快速查重。
  • 谷鸟过滤器:更适合频繁动态增删场景。

最佳实践

使用Guava实现布隆过滤器:

java 复制代码
BloomFilter<String> filter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), 1000, 0.01);
filter.put("element");
System.out.println(filter.mightContain("element"));

总结

通过解析第81-90期Java面试问题,本文系统讲解了从数据库设计、内存优化到高并发工具使用的关键技术点,并结合代码实例提供了清晰的解决方案,帮助开发者在性能优化和面试中脱颖而出。

相关推荐
mo477614 分钟前
JS中的类与对象
java·开发语言·javascript
T.O.P1116 分钟前
数据结构和算法
java·开发语言·数据结构
重生之绝世牛码19 分钟前
Java设计模式 —— 【创建型模式】工厂模式(简单工厂、工厂方法模式、抽象工厂)详解
java·大数据·开发语言·设计模式·工厂方法模式·设计原则·工厂模式
北漂编程小王子1 小时前
maven 工具 clean、compile、package、install、deploy 常用命令使用区别
java·maven·maven常用命令·clean package
binqian1 小时前
【maven】配置下载私有仓库的快照版本
java·maven
five小点心1 小时前
尚硅谷学习笔记——Java设计模式(一)设计模式七大原则
java·开发语言·设计模式
豆 腐1 小时前
Spring Boot【二】
java·spring boot·后端
潜洋1 小时前
Spring Boot教程之十一:获取Request 请求 和 Put请求
java·开发语言·python
AskHarries1 小时前
一个高效的Java对象映射库Orika
java·开发语言·python
浩浩学编程2 小时前
JAVA项目-------医院挂号系统
java·开发语言