java面试题--核心知识
一、HashMap和HashTable的区别?
二、HashMap有哪些线程安全的方式?
三、HashMap在扩容上有哪些优化? 难点
三、为什么ConcurrentHashMap是线程安全的?
- transitent volatile Node<K, V>[] tablle;
- table是数字+链表/红黑数的数据结构。当链表节点数达到阈值(默认是8)时,会由链表树化成红黑树。
- volatile关键字,指table是内存可见的。所有线程都是从主内存中读写数据,而不是在线程自己的工作内存中。
- table的初始化:
- 初始化方法中有个volatile sizeCtl变量。保证了线程初始化过程中sizeCtl一直是内存可见的,确保了线程安全。
- put 方法的线程安全:
- 使用了CAS锁更新value 。 CAS直接操作内存,保证了操作的原子性。
四、java锁机制?
- 无锁
- 偏向锁
- 轻量级锁
- 重量级锁
五、对AQS 抽象队列同步器的理解?
- 基石:volatile。共享资源的状态字段private volatile int state。该字段使用volatile修饰,代表是内存可见的。state=0:资源未被占用。state>0:资源被占用。
- CAS(Compare And Swap):使用CAS锁更新state的值。
- 独占方式EXCLUSIVE,可重入。state会累加。需要多次释放锁,一直到state=0.
- 公平锁:按照在CLH队列中的排队顺序,线程依次获得锁。
- 非公平锁:不管在CLH队列中的顺序如何。资源未被占用时,线程抢占锁。
- 共享方式SHARE。多个线程可以同时访问共享资源。
- CLH锁:这个是一种FIFO的虚拟双向队列。有头结点、尾结点。
六、对ReentrantLock, ReentrantReadWriteLock、CountDownLatch的理解?
- ReentrantLock可重入的互斥锁。
- ReentrantReadWriteLock可重入的读写锁:
- CountDownLatch:是一种共享锁组件。用作线程计数。只有当线程全部执行完成,n=0时,才唤醒主线程。
七、说说对线程池的理解?
https://pdai.tech/md/java/thread/java-thread-x-juc-executor-ThreadPoolExecutor.html
八、String、StringBuilder、StringBuffer的问题汇总。
- StringBuilder\StringBuffer的区别?
- 两者都继承自AbstractStringBuilder.
- StringBuilder不是线程安全的,所以效率更高。
- StringBuffer的方法使用了synchronized关键字修饰,是线程安全的,但是效率低。
- String和StringBuilder/StringBuffer的区别?
- String 的值是不可变的。每次对String 的操作,都会生成新的String对象。
- 什么情况下用“+”运算符进行字符串连接比调用StringBuffer/StringBuilder 对象的append方法连接字符串性能更好?
- 看下面这个例子。
反编译后的代码如下:
“+”号使用StringBuilder处理。如果连接字符串行表达式很简单(如上面的顺序结构),那么"+"和StringBuilder基本是一样的。但是如果是使用循环来连接字符串,性能会产生很大的差距。
反编译后的代码如下:
可以看到,循环体内,每次循环都会生成一个StringBuiler对象。这样会造成资源浪费,并且效率要低。优化的方法是在循环体外声明StringBuiler。
- 看下面这个例子。
九、线程安全集合类有哪些?
java.util.concurrent.*包下的。
例如:ConcurrentHashMap; CopyOnWriteArrayList; CopyOnWriteArraySet;
底层大都采用Lock锁(1.8的ConcurrentHashMap不使用Lock锁)保证线程安全的同时,效率也很高。
十、synchronized锁升级?
https://blog.csdn.net/qq_45593575/article/details/129315485
- 为什么需要synchronized锁升级?
- 用锁是数据安全的,但是抢锁失败后,线程会阻塞,交给操作系统处理,需要在用户态和内核态之间频繁切换,会消耗大量的系统资源,造成性能下降。
- 哪个java版本做出的锁升级?
- JDK1.5及之前的版本,synchronized锁都是重量级锁。JDK1.6 引入了偏向锁和轻量级锁。
- 锁升级的过程?
- 无锁--> 偏向锁--> 轻量级锁-->重量级锁
- 锁升级的原理?
十一、说一下对关键字final的理解?
十二、说一下对关键字volatile的理解?
1、被volatile修饰的关键字,是内存可见的,即多个线程可以看到最新的值。
2、可以禁止指令重排序。
3、但是不能保证原子性。
十三、说一下对关键字static的理解?
十四、Spring的AOP的底层实现原理?
AOP是IOC的一个扩展功能。先有的IOC,再有的AOP,只是在IOC的流程中增加的一个扩展点而已。BeanPostProcessor
总:AOP的概念、应用场景、动态代理
分:bean的创建过程中有一个步骤可以对bean进行扩展实现。AOP本身就是一个扩展功能,所以在BeanPostProcessor的后置处理方法中来进行实现。
1、代理对象的创建过程(advice,切面,切点)。
2、通过JDK或者Cglib的方式生成代理对象。
3、在执行方法调用的时候,会调用到生成的字节码文件中,直接找到DynamicAdvisedInterceptor类中的intercept方法,从此方法开始执行。
4、根据之前定义好的通知来生成拦截器链。
5、从拦截器链中依次获取每一个通知开始进行执行。在执行过程中,为了方便找到下一个通知是哪个,会有一个CglibMethodInvocation的对象,找的时候是从-1的位置依次查找并执行的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!