1. 笔试
1.1 请对比Exception和Error,另外运行时异常与一般异常有什么区别
特性 | Exception | Error | RuntimeException | 一般异常(Checked Exception) |
---|---|---|---|---|
继承关系 | Throwable -> Exception |
Throwable -> Error |
Exception -> RuntimeException |
Exception -> (非 RuntimeException) |
类型 | 被捕获并处理的异常 | 系统级错误,不需要捕获处理 | 运行时异常,通常由程序错误导致 | 需要捕获或抛出的异常 |
例子 | IOException , SQLException |
OutOfMemoryError , StackOverflowError |
NullPointerException , ArithmeticException |
IOException , SQLException |
处理方式 | 必须捕获或声明抛出 | 不需要捕获,一般不可恢复 | 可以选择捕获,也可以不处理 | 必须捕获或声明抛出 |
是否被强制处理 | 是 | 否 | 否 | 是 |
1.2 强引用、软引用、弱引用、幻象引用有什么区别?具体使用场景是什么?
引用类型 | 引用对象的生命周期 | 是否影响对象的回收 | 使用场景 |
---|---|---|---|
强引用 | 对象存在时不被回收 | 强烈影响,不会回收 | 核心业务对象,需要长期存活 |
软引用 | 内存不足时可能回收 | 内存不足时会被回收 | 缓存、内存敏感应用 |
弱引用 | 无论内存是否紧张都会回收 | 强烈影响,总是被回收 | 临时缓存、避免内存泄漏 |
幻象引用 | 无法直接访问,回收时处理 | 不影响对象回收,仅用于监控 | 对象销毁前的清理、堆外内存管理 |
1.3 谈谈Java反射机制,动态代理是基础什么原理
- 反射机制:允许在运行时访问和操作类、方法、字段等元数据,增加了程序的灵活性,但也带来性能开销和安全性问题。
- 动态代理:利用反射技术动态生成代理对象,并在方法调用时通过 InvocationHandler 执行自定义操作。JDK 动态代理需要接口,CGLIB 代理可以直接代理类,广泛应用于 AOP 和分布式系统中。
1.4 如何保证容器是线程安全的?ConcurrentHashMap如何实现搞笑地线程安全
保证容器线程安全:
- 使用同步机制(Synchronized)
- 使用显式锁(ReentrantLock)
- 使用并发容器
- 使用原子类(Atomic)
- 使用
volatile
关键字
ConcurrentHashMap 通过以下方式实现了高效的线程安全:
- 分段锁(Java 7及以前):将哈希表分成多个段,多个线程可以同时访问不同段,减少了锁竞争。
- 桶级锁(Java 8及以后):每个桶内独立加锁,减少了线程之间的阻塞。
- CAS 操作:在某些情况下,通过无锁的 CAS 操作确保数据的原子性。
- 优化锁和自旋:在某些场景下,避免了传统锁带来的性能损失。
1.5 synchronized底层如何实现?什么是锁的升级和降级
https://blog.csdn.net/qq_37756660/article/details/138859402
1.6 Java并发包提供了哪些并发工具类
- Executor Framework 框架简化了线程池的使用,允许你更方便地管理和调度线程。
- CountDownLatch 是一个同步工具类,它允许一个或多个线程等待其他线程完成任务。
- CyclicBarrier 允许一组线程互相等待,直到所有线程都达到某个公共屏障点。在线程到达屏障后,所有线程会被释放,并且计数器会重置,允许下一次的使用。
- Semaphore 是一个计数信号量,用于控制访问共享资源的线程数。信号量通常用于实现限制并发的场景。
- BlockingQueue 是一个线程安全的队列,它在队列为空时会阻塞等待数据,在队列满时也会阻塞等待空间。常用于生产者-消费者模式。
1.7 Java的并发类库提供的线程池有哪几种?分别用什么特点
线程池类型 | 特点 | 适用场景 |
---|---|---|
FixedThreadPool | 固定线程数,适用于负载稳定的任务 | 长期、稳定的后台任务,处理固定数量的线程池任务 |
CachedThreadPool | 线程数动态变化,适合短期任务,但容易导致大量线程创建和销毁 | 短期、大量的并发任务 |
SingleThreadExecutor | 只有一个线程,保证任务顺序执行 | 需要按顺序执行任务的场景 |
ScheduledThreadPool | 支持定时和周期性任务 | 定时任务、延迟任务、周期性任务 |
WorkStealingPool | 工作窃取算法,线程间相互窃取任务 | 适合大规模并行计算和小粒度任务的场景 |
ForkJoinPool | 使用工作窃取,适合递归任务和分治法任务 | 分治算法、大规模并行计算 |
1.8 请介绍类的加载过程,什么是双亲委派模型?
- 类加载过程:从加载、链接到初始化的整个过程,确保类被正确加载和执行。
- 双亲委派模型:通过将类加载请求委派给父加载器处理,避免了类的重复加载,并提高了系统的安全性和稳定性。
1.9 谈谈JVM内存区域的划分,哪些区域可能发生OutOfMemoryError?
区域划分为:方法区(Metaspace),堆(Heap),栈(Stack),程序计数器,本地方法栈,直接内存(Direct Memory)
可能发生OutOfMemoryError
:
- 堆内存和方法区是最容易导致
OutOfMemoryError
的区域,尤其是在程序创建大量对象或类加载过多时。 - 栈内存主要是因方法调用深度过大或递归导致的StackOverflowError。
- 直接内存不足时会抛出Direct buffer memory错误,这通常涉及到本地I/O操作。
1.10 Java常见的垃圾收集器有哪些
- SerialGC:适用于单核、内存小的环境。
- ParallelGC:适用于多核、吞吐量要求较高的环境。
- CMS:适用于对停顿时间要求较高的应用。
- G1:适用于大内存、高吞吐量并且需要精细控制GC停顿时间的应用。
- ZGC:适用于极低停顿时间和超大内存的应用。
- ShenandoahGC:类似ZGC,适用于低停顿、高并发、大内存应用。
- EpsilonGC:适用于不依赖JVM垃圾回收的特殊场景。
1.11 你了解Java应用开发中的注入攻击吗
- SQL注入
- LDAP注入
- XSS攻击
- 命令注入
- XML注入
1.12 谈谈MySQL支持的事物隔离级别,以及悲观锁和乐观锁的应用和原理
1.13 谈谈Spring Bean的生命周期和作用域?
Spring Bean 生命周期:从 Bean 的创建、依赖注入、初始化、使用到销毁的全过程。主要涉及实例化、依赖注入、初始化、销毁等步骤。
Spring Bean 作用域:决定了一个 Bean 在容器中的创建和生命周期。常见的作用域有:singleton(默认)、prototype、request、session、application、websocket 等。
2. 自我介绍
3. 简单自我介绍一下你这个低代码项目
4. 那你这个项目在生成的时候有没有做一些限制
5. 线程与线程之间怎么进行交互
6. 线程池在运行时能不能修改核心线程数
7. Spring Cloud和SpringBoot有什么区别
8. 什么是分布式
9. 你最近有在学习什么新技术嘛?
10. 你平时在通过什么方式学习新的技术
11. 从一个后端的考虑,你会如何开展一个项目
12. 反问
面试总结
这个面试官很好,对我的简历指出了一些问题,给了我一些实用性的建议。
标签:Java,信息技术,xxx,回收,任务,线程,内存,有限公司,加载 From: https://www.cnblogs.com/lymf/p/18613519