三面

1、照例自我介绍和项目介绍;

2、上来就让我手撕一个单例模式。。。答:

public class SingleInstanceDemo {
    private SingleInstanceDemo(){}
    private static volatile SingleInstanceDemo singleInstance;
    public static SingleInstanceDemo getInstance(){
        if (singleInstance == null){
            synchronized (SingleInstanceDemo.class){
                if (singleInstance == null){
                    singleInstance = new SingleInstanceDemo();
                }
            }
        }
       return singleInstance;
   }
}

3、让我讲了讲代码是啥啥意思?

答:STEP 1. 线程A访问getInstance()方法,因为单例还没有实例化,所以进入了锁定块。STEP 2. 线程B访问getInstance()方法,因为单例还没有实例化,得以访问接下来代码块,而接下来代码块已经被线程1锁定。STEP 3. 线程A进入下一判断,因为单例还没有实例化,所以进行单例实例化,成功实例化后退出代码块,解除锁定。STEP 4. 线程B进入接下来代码块,锁定线程,进入下一判断,因为已经实例化,退出代码块,解除锁定。STEP 5. 线程A初始化并获取到了单例实例并返回,线程B获取了在线程A中初始化的单例。大体是这么回事。

4、由于我的项目中提及到JVM,所以给我出了一个场景题,垃圾会收器中,标记清除多次后,由于采用的是标记清除算法,那么你觉得可能会出现什么问题?

答:由于标记清除算法清理垃圾对象的同时产生了内存碎片(虽然释放内存但不是连续的),所以当分配一个大对象的时候,由于内存不连续,那么会产生full GC。

5、这里提及到了full gc,问我,哪些情况会产生full GC,哪些情况产生minor GC?

答:minor会产生在eden区满了,fullGC产生在老年代的剩余空间不足,以及永久代内存不足也会发生fullGC。

6、除了你项目中的内存溢出问题,你还知道哪些关于内存溢出内存泄漏的?

答:这里之前了解过ThreadLocal,ThreadLocal中的键值对中的键是一个弱引用,那么在内存回收的时候,这个键很可能会被回收掉,然后键没了,就无法引用value的值,造成了内存泄漏;