【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本质上是基于有限离散值(如int、char),而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. 工具检测 :使用JVisualVM、MAT分析堆内存;
  2. 日志监控 :启用-XX:+HeapDumpOnOutOfMemoryError生成堆转储文件;
  3. 代码检查 :查找未释放的资源(如InputStream、Socket)。

最佳实践 :

启用内存转储:

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

相关推荐
她的男孩1 分钟前
页面已发布用户仍进不去:Forge Admin 门户入口与系统菜单挂载解耦
java·spring boot·低代码
不像程序员的程序媛5 分钟前
mybatisplus insert dto未指定id时会如何
java·开发语言
程序员梅雨22 分钟前
Hive面试总结
hive·hadoop·面试
我命由我1234524 分钟前
5-2.Python 编码进阶 - 字符串进阶(拼接、普通格式化、普通格式化数字精度控制、快速格式化、遍历、常用方法)
java·开发语言·后端·python·学习·java-ee·学习方法
yunwei3732 分钟前
eBPF 实例教程:使用内核跟踪点监控 GPU 驱动活动
linux·后端·性能优化
Pniubi8 小时前
HashMap的扩容和树化边界
java·开发语言
Mikko79 小时前
用 Java 复刻了高中时在塞班上玩的「熔岩矿车」:纯 Swing、零依赖、没有一张图片,一个 jar 双击就能玩
java·游戏开发·swing
知了学历孙老师9 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
Java爱好狂.9 小时前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
秋饼10 小时前
LLM API密钥动态轮换实战:Spring Vault + Spring AI + 多Provider路由
java·ai·技术分享·后端开发