vlambda博客
学习文章列表

2年大厂经验Java面试,题目和答案!

1、垃圾收集算法

标记清除(碎片化)

复制算法(浪费空间)

标记整理算法(效率比前两者差)

分代收集算法(老年代一般使用“标记-清除”、“标记-整理”算法,年轻代一般用复制算法)


2、垃圾收集器




3、ZGC收集器中的染色指针有什么用?

具体可以看这篇:

https://blog.csdn.net/qq_32165517/article/details/106403870


1)染色指针可以使得一旦某个Region的存活对象被移走之后,这个Region立即就能够被释放和重用掉,而不必等待整个堆中所有指向该Region的引用都被修正后才能清理。使得理论上只要还有一个空闲Region,ZGC就能完成收集。


2)染色指针可以大幅减少在垃圾收集过程中内存屏障的使用数量,设置内存屏障,尤其是写屏障的目的通常是为了记录对象引用的变动情况,如果将这些信息直接维护在指针中,显然就可以省去一些专门的记录操作。实际上,到目前为止ZGC都并未使用任何写屏障,只使用了读屏障(一部分是染色

指针的功劳,一部分是ZGC现在还不支持分代收集,天然就没有跨代引用的问题)。能够省去一部分的内存屏障,显然对程序运行效率是大有裨益的,所以ZGC对吞吐量的影响也相对较低。


内存屏障(Memory Barrier)的目的是为了指令不因编译优化、CPU执行优化等原因而导致乱序执行,它也是可以细分为仅确保读操作顺序正确性和仅确保写操作顺序正确性的内存屏障的。


3)染色指针可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程相关的数据,以便日后进一步提高性能。现在Linux下的64位指针还有前18位并未使用,它们虽然不能用来寻址,却可以通过其他手段用于信息记录。如果开发了这18位,既可以腾出已用的4个标志位,将ZGC可支持的最大堆内存从4TB拓展到64TB,也可以利用其余位置再存储更多的标志,譬如存储一些追踪信息来让垃圾收集器在移动对象时能将低频次使用的对象移动到不常访问的内存区域。



4、SPI机制



5、类加载过程

加载

验证

准备(为一些类变量分配内存,并将其初始化为默认值)

解析(将符号引用替换为直接引用。类和接口、类方法、接口方法、字段等解析)

初始化


6、违背双亲委派机制的例子



7、作为注册中心,Zookeeper和Eureka有什么区别?


8、Zookeeper的Zab协议


9、Redis集群数据一致性算法——Gossip协议



10、Redis中的String有哪些编码方式


11、Redis缓存穿透



12、布隆过滤器原理



13、InnoDB索引原理


14、InnoDB的MVCC机制


15、Kafka消息是有序的吗

在同一个partition里的消息是有序的,不同partition之间的消息是没法保证全局有序的。


16、Kafka如何解决消息重复消费

在消费的时候做好幂等性处理,常见的方案如下:

在发送消息时,给每条消息指定一个全局唯一的 ID。消费时,先根据这个 ID 检查这条消息是否有被消费过,如果没有消费过,才更新数据,然后将消费状态置为已消费。


17、TCP time_wait状态



18、time_wait状态是主动断开方才有还是被动断开方才有,还是两者都有?

主动断开方才有time_wait状态。


18、Nagle算法



19、Java中如何禁用Nagle算法

Java Socket编程里,有个TcpNoDelay选项可以设置。当这个选项设置为true时,即表示禁用Nagle算法。


20、synchronized实现原理



21、Java对象内存布局


22、ReentrantLock与synchronized的区别

可重入性:

从名字上理解,ReenTrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的锁也是可重入的,两者关于这个的区别不大。两者都是同一个线程没进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。


锁的实现:

Synchronized是依赖于JVM实现的,而ReenTrantLock是JDK实现的,有什么区别,说白了就类似于操作系统来控制实现和用户自己敲代码实现的区别。前者的实现是比较难见到的,后者有直接的源码可供阅读。


性能的区别:

在Synchronized优化以前,synchronized的性能是比ReenTrantLock差很多的,但是自从Synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用synchronized,其实synchronized的优化我感觉就借鉴了ReenTrantLock中的CAS技术。都是试图在用户态就把加锁问题解决,避免进入内核态的线程阻塞。


功能区别:

便利性:很明显Synchronized的使用比较方便简洁,并且由编译器去保证锁的加锁和释放,而ReenTrantLock需要手工声明来加锁和释放锁,为了避免忘记手工释放锁造成死锁,所以最好在finally中声明释放锁。

锁的细粒度和灵活度:很明显ReenTrantLock优于Synchronized


ReenTrantLock独有的能力:

1.ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。

2.ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。

3.ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。


23、ReentrantLock公平锁实现原理



24、原子类原理



25、线程池原理



2年大厂经验Java面试,题目和答案!



求关注



求转发