经纬恒润 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. 项目部署流程是怎样的?如何实现自动化部署?

答案:

传统部署流程:

  1. 本地打包:mvn clean package
  2. 上传jar包到服务器
  3. 备份旧版本
  4. 启动新版本:java -jar app.jar
  5. 检查日志和健康检查

Docker部署:

  1. 编写Dockerfile
  2. 构建镜像:docker build -t app:v1.0 .
  3. 推送到镜像仓库
  4. 服务器拉取镜像
  5. docker-compose up -d启动

CI/CD自动化:

Jenkins流程:

  1. Git提交代码触发Webhook
  2. Jenkins拉取代码
  3. Maven编译打包
  4. 执行单元测试
  5. SonarQube代码质量检查
  6. 构建Docker镜像
  7. 推送到Harbor镜像仓库
  8. 自动部署到测试环境
  9. 人工审核后部署生产环境

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圣经

全部评论

相关推荐

评论
1
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务