经纬恒润 Java开发 一面 面经
1. 说说你对Java反射机制的理解,实际项目中在哪些场景使用?
答案:
核心概念:
- 运行时获取类的信息(字段、方法、构造器)
- 动态创建对象、调用方法
- 突破访问权限限制
主要API:
Class.forName():加载类getDeclaredFields():获取字段getDeclaredMethods():获取方法newInstance():创建对象invoke():调用方法
应用场景:
- Spring IoC容器:根据配置创建Bean
- MyBatis:ResultSet映射到对象
- JSON序列化/反序列化(Jackson、Gson)
- 动态代理:AOP实现
- 注解处理:扫描和解析注解
- JDBC:加载数据库驱动
优缺点:
- 优点:灵活、解耦、支持动态扩展
- 缺点:性能开销、破坏封装、编译期无法检查
2. Stream流式操作有哪些常用方法?相比传统集合操作有什么优势?
答案:
中间操作(返回Stream):
filter():过滤map():转换flatMap():扁平化distinct():去重sorted():排序limit():限制数量skip():跳过元素
终止操作(返回结果):
collect():收集到集合forEach():遍历reduce():归约count():计数anyMatch()/allMatch():匹配findFirst()/findAny():查找
示例:
list.stream()
.filter(x -> x > 10)
.map(x -> x * 2)
.sorted()
.collect(Collectors.toList());
优势:
- 代码简洁,链式调用
- 惰性求值,提升性能
- 支持并行流(parallelStream)
- 函数式编程风格
- 内部迭代,优化空间大
3. 消息队列RabbitMQ、RocketMQ、Kafka有什么区别?如何选型?
答案:
性能对比:
- Kafka:吞吐量最高(百万级/秒),适合大数据
- RocketMQ:吞吐量高(十万级/秒),功能丰富
- RabbitMQ:吞吐量较低(万级/秒),延迟最低
功能特性:
RabbitMQ:
- 支持多种协议(AMQP、MQTT)
- 灵活的路由(Exchange类型丰富)
- 消息优先级
- 延迟队列(插件)
- 社区成熟,文档完善
RocketMQ:
- 顺序消息(全局/分区)
- 事务消息(分布式事务)
- 延迟消息(18个级别)
- 消息回溯
- 阿里开源,中文文档好
Kafka:
- 高吞吐、低延迟
- 分区机制,水平扩展
- 消息持久化,可回溯
- 适合日志收集、流处理
- 生态丰富(Kafka Streams)
选型建议:
- 日志收集、大数据场景 → Kafka
- 业务解耦、可靠性要求高 → RocketMQ
- 复杂路由、小规模 → RabbitMQ
4. 数据库分页查询如何优化?深分页问题怎么解决?
答案:
传统分页问题:
SELECT * FROM table LIMIT 1000000, 20
- 需要扫描前1000020行
- 偏移量越大越慢
优化方案:
1. 子查询优化(覆盖索引)
SELECT * FROM table t
INNER JOIN (
SELECT id FROM table
WHERE conditions
ORDER BY id
LIMIT 1000000, 20
) tmp ON t.id = tmp.id
2. 延迟关联
SELECT t.* FROM table t, (SELECT id FROM table ORDER BY id LIMIT 1000000, 20) a WHERE t.id = a.id
3. 记录上次位置(推荐)
SELECT * FROM table
WHERE id > #{lastId}
ORDER BY id
LIMIT 20
- 适合只有下一页的场景
- 性能最优
4. 使用ES等搜索引擎
- 适合全文检索场景
- 支持深分页
5. 业务优化
- 限制最大页数(如只显示前100页)
- 使用搜索代替翻页
- 缓存热点页
5. 项目部署流程是怎样的?如何实现自动化部署?
答案:
传统部署流程:
- 本地打包:
mvn clean package - 上传jar包到服务器
- 备份旧版本
- 启动新版本:
java -jar app.jar - 检查日志和健康检查
Docker部署:
- 编写Dockerfile
- 构建镜像:
docker build -t app:v1.0 . - 推送到镜像仓库
- 服务器拉取镜像
docker-compose up -d启动
CI/CD自动化:
Jenkins流程:
- Git提交代码触发Webhook
- Jenkins拉取代码
- Maven编译打包
- 执行单元测试
- SonarQube代码质量检查
- 构建Docker镜像
- 推送到Harbor镜像仓库
- 自动部署到测试环境
- 人工审核后部署生产环境
K8s部署:
- 编写Deployment、Service配置
- 滚动更新,零停机
- 自动扩缩容
- 健康检查和自愈
监控告警:
- Prometheus + Grafana监控
- ELK日志收集
- 钉钉/企业微信告警
6. Java中创建线程有哪些方式?各有什么特点?
答案:
1. 继承Thread类
class MyThread extends Thread {
public void run() { }
}
new MyThread().start();
- 简单直接
- 无法继承其他类
2. 实现Runnable接口
new Thread(new Runnable() {
public void run() { }
}).start();
- 可以继承其他类
- 代码解耦
3. 实现Callable接口
Futur
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java面试圣经 文章被收录于专栏
Java面试圣经,带你练透java圣经
