实习面经(十二)

来自网络,供学习,侵删 某猪 某皮

先完成再完美

1.jdk8和jdk17有什么区别,有哪些更新

  • 性能与底层
    • 垃圾回收器 :JDK 8 默认 Parallel GC,JDK 17 默认 G1 GC ,并引入了 ZGC(低延迟,亚毫秒级暂停)。
    • 启动速度:JDK 17 优化了类加载和 JIT 编译,启动速度更快,内存占用更低。

2.stream流场景题,List里面有person类,person里面有name,age,stream流把List里面变成map,其中键为name,值为person;

java8新特性

Map<String, Person> personMap = personList.stream() .collect(Collectors.toMap(Person::getName, person -> person)); // 或者使用方法引用 // .collect(Collectors.toMap(Person::getName, Function.identity()));

3.jdk17为了适应什么框架

JDK 17 的演进很大程度上是为了适应 云原生 (Cloud Native)微服务 架构,特别是为了配合 Spring Boot 3.xSpring Framework 6 的升级。

  • Spring Boot 3.0+ 强制要求最低 Java 版本为 17。
  • GraalVM 原生镜像:JDK 17 的改进(如分层编译、更强的封装)使得 Java 应用更容易被编译成原生镜像,实现秒级启动和极低内存占用,这对 Serverless 和容器化部署至关重要。

4.单例模式,策略模式和工厂模式解释下

单例模式的话,懒汉,饿汉,静态内部类,双重锁校验

  • 工厂模式 (Factory Pattern)

    • 定义 :1定义一个创建对象的接口,但让2子类决定实例化哪一个类。或者简单理解为一个"生产对象的车间"。3.调用工厂方法就能实例化
    • 作用:解耦对象的创建和使用。调用方不需要知道具体类的类名,只需要知道工厂和接口。
    • 例子Calendar.getInstance() 就是一个简单的工厂方法。
  • 策略模式 (Strategy Pattern)

    • 定义:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。
    • 作用 :消除大量的 if-elseswitch 判断。
    • 例子 :电商订单的支付方式(支付宝、微信、银联)。定义一个 PaymentStrategy 接口,不同支付方式实现该接口。根据用户选择,注入不同的策略实现类。通常配合工厂模式或 Map 容器来根据类型获取对应的策略。

5. Java 回收器了解吗?G1 和 ZGC 回收器

VM 垃圾回收器的核心目标是平衡 吞吐量 (Throughput)延迟 (Latency/Pause Time)

  • G1 (Garbage-First)
    • 特点:JDK 9+ 的默认回收器。将堆内存划分为多个独立的区域(Region),不再物理隔离新生代和老年代。
    • 优势:可预测的停顿时间模型。用户可以指定期望的停顿时间(如 200ms),G1 会尽力达成。适合大内存(6GB+)、多核 CPU 的服务器端应用。
  • ZGC (Z Garbage Collector)
    • 特点 :JDK 15+ 正式商用。基于 读屏障染色指针 技术。
    • 优势亚毫秒级的停顿时间(通常 < 1ms),且停顿时间不随堆内存大小增长而增长(支持 TB 级堆内存)。
    • 适用:对延迟极其敏感的系统,如高频交易、实时大数据处理。

6场景题:100w订单量问题进行表设计和库设计,订单分布式ID怎么设计,商家怎么通过你设计的表形成商家的订单列表,分库怎么查找

  • 分库分表 :100w 数据量在 MySQL 单表中其实不算大(通常 500w-1000w 是分界线)。如果预估会增长到千万级,需提前分表。
    • 策略 :通常按 user_id 取模分库分表,保证同一个用户的订单在同一个库/表中,方便查询。
  • 表结构
    • id (bigint, 主键)

    • order_no (varchar, 业务订单号,唯一索引)

    • user_id (bigint, 分片键)

    • merchant_id (bigint, 商家ID)

    • amount (decimal)

    • status (tinyint)

    • create_time (datetime)

    • 2. 分布式 ID 设计

    • 雪花算法 (Snowflake) :最常用。生成 64 位 Long 型 ID(时间戳 + 机器 ID + 序列号),趋势递增,性能好,不依赖数据库。

    • 数据库号段模式:美团 Leaf 等方案,依赖数据库生成号段,可靠性高。

    • 3. 商家订单列表与分库查找

    • 痛点 :订单表按 user_id 分片,但商家需要按 merchant_id 查询。这属于"非分片键查询"。

    • 解决方案

      • 方案 A (异构索引表) :建立一张专门的商家订单表(merchant_order),按 merchant_id 分片,异步同步数据。
      • 方案 B (Elasticsearch):将订单数据同步到 ES,商家查询走 ES,详情查询走 MySQL。
      • 方案 C (广播表/冗余字段) :如果商家数量少,可以在订单表中冗余 merchant_id,利用数据库中间件(如 ShardingSphere)的广播表功能或全表扫描(不推荐,性能差)。

7总体架构,传统三层架构和ddd架构有什么区别

  • 传统三层架构 (MVC/Service/Dao)

    • 核心贫血模型。实体类(Entity)只有 Getter/Setter,业务逻辑全部堆积在 Service 层(Transaction Script 模式)。
    • 缺点:随着业务复杂,Service 类会变得极其臃肿,难以维护,且容易违反单一职责原则。
    • 适用:简单的 CRUD 管理系统。
  • DDD (领域驱动设计)

    • 核心充血模型 。业务逻辑下沉到领域对象(Entity/Value Object)中,Service 层只负责协调。
    • 结构:通常分为接口层、应用层、领域层、基础设施层(六边形架构/整洁架构)。
    • 优点:代码结构与业务语言统一(通用语言),高内聚低耦合,适合复杂业务系统(如电商、金融核心)

8.项目里kafka里面有哪些注意点

  • 消息丢失
    • 生产者:开启 acks=all,重试次数设为最大值。
    • Broker:min.insync.replicas > 1
    • 消费者:关闭自动提交 offset,业务处理成功后再手动提交。
  • 消息重复消费
    • Kafka 只能保证"至少一次"。消费者必须实现 幂等性(如利用数据库唯一键、Redis 防重表)。
  • 消息积压
    • 排查消费者处理逻辑是否过慢。
    • 临时扩容:增加 Partition 数量,增加消费者实例。
  • 顺序消息
    • Kafka 只保证 Partition 内的顺序。如果需要全局顺序,只能用一个 Partition(性能差);通常只需要保证"同一订单/同一 Key"的顺序,发送时指定 Key 即可。

9.JMM了解吗

JMM 定义了 Java 虚拟机与计算机内存(主内存)之间的交互规则。

  • 核心概念
    • 主内存:所有变量存储的地方。
    • 工作内存:每个线程的私有内存,保存了该线程使用到的变量的主内存副本。
  • 三大特性
    • 原子性 :操作不可中断(如 synchronized)。
    • 可见性 :一个线程修改了变量,其他线程立即可见(如 volatile)。
    • 有序性 :禁止指令重排序(如 volatile)。
  • Happens-Before 原则:判断数据是否存在竞争、线程是否安全的依据。

10.垃圾回收了解吗

  • 判断对象存活 :引用计数法(已淘汰)、可达性分析算法(GC Roots)。
  • 分代收集理论
    • 新生代 :对象朝生夕死,使用 复制算法(Eden, Survivor)。
    • 老年代 :对象存活率高,使用 标记-整理标记-清除 算法。
  • STW (Stop-The-World):GC 发生时,用户线程暂停。优化的核心就是减少 STW 时间。

11.mysql有一个表,abc三列,b是索引,a是主键,where b =1,经过几次IO

  1. 查找索引 b :InnoDB 的二级索引(辅助索引)叶子节点存储的是 索引列的值 (b)主键值 (a)
    • 首先在 b 的 B+ 树中找到 b=1 的节点。假设树高为 h1(通常 2-3 层),需要 h1 次 IO。
  2. 回表 :因为查询需要所有列(或者非覆盖索引),拿到主键 a 后,需要回到 聚簇索引(主键索引) 树中查找完整的行数据。
    • 在主键 a 的 B+ 树中查找,假设树高为 h2(通常 2-3 层),需要 h2 次 IO。

12.分布式锁了解吗,redis怎么实现分布式锁

  • 基本实现
    • SET key value NX PX 30000 (Set If Not Exists + 过期时间)。
    • 利用 Redis 单线程特性保证原子性。
  • 关键点
    • 超时时间:防止死锁。
    • Value 值 :通常设为 UUID+ThreadID,用于释放锁时校验(只能删除自己的锁,防止误删别人的锁)。
    • 原子删除:使用 Lua 脚本判断 Value 并删除。
  • 进阶 (Redisson)
    • 看门狗机制:如果业务没执行完,后台线程自动给锁"续期"。
    • 红锁:在多个 Redis 主节点上尝试加锁,提高可靠性。

13JUC并发编程中用到哪些数据结构

  • ConcurrentHashMap
    • JDK 8:Node 数组 + 链表 + 红黑树。使用 CAS + synchronized 保证线程安全,锁粒度更细(只锁链表头节点)。
  • ThreadLocal
    • 线程本地变量,每个线程内部维护一个 ThreadLocalMap,实现线程隔离。
  • BlockingQueue (阻塞队列)
    • ArrayBlockingQueueLinkedBlockingQueue。用于线程池任务队列,生产消费解耦。
  • AQS (AbstractQueuedSynchronizer)
    • 底层核心,维护了一个 CLH 双向队列 来管理等待锁的线程。ReentrantLockCountDownLatch 都基于它。

14.有JVM调优经验吗

  1. 监控 :使用 Prometheus + Grafana 监控 JVM 的堆内存使用率和 GC 频率。
  2. 排查 OOM :当发生 OOM 时,通过启动参数 -XX:+HeapDumpOnOutOfMemoryError 生成 Dump 文件,使用 MATJProfiler 分析大对象和内存泄漏点(比如静态集合类无限增长)。
  3. 排查 CPU 飙高 :使用 top -H -p <pid> 找到占用 CPU 高的线程 ID,转换为 16 进制,再用 jstack 查看堆栈,定位是死循环还是频繁 GC 导致的。
  4. 参数调整 :根据业务场景调整堆内存大小(-Xmx, -Xms)以及选择合适的垃圾回收器(如将默认的 Parallel GC 换成 G1 以减少停顿)。"
相关推荐
编码忘我2 小时前
JVM 运行时数据区详解
java·后端·程序员
阿唯不困2 小时前
AI智能应用开发(Java)从起点到终点-面向对象
java·后端
m0_726965982 小时前
面面面(2)
java·开发语言
05大叔2 小时前
RAG开发
java·服务器·前端
迷藏4942 小时前
# 发散创新:用 Rust实现高性能测试框架的底层逻辑与实战演练
java·开发语言·后端·python·rust
XuDream2 小时前
idea中忽略idea文件不提交git和取消被 Git 追踪
java·git·intellij-idea
SadSunset2 小时前
第五章:Redis 的 Java 客户端
java·数据库·redis
毕设源码-钟学长2 小时前
【开题答辩全过程】以 基于Springboot的在线考试系统为例,包含答辩的问题和答案
java·spring boot·后端
星如雨グッ!(๑•̀ㅂ•́)و✧3 小时前
Webflux onErrorStop使用
java