Android高级岗面试实战04——某二手交易平台Android电话一面

一开始我做了一下简单的自我介绍,然后开始大致说了一下自己的技术情况,面试小哥沿着我的技术栈问了几个很好的问题:

1.LRUCache污染问题如何避免?

我也不知道!

2.双检锁单例为什么线程不安全?

https://blog.csdn.net/zy13608089849/article/details/82703192?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.nonecase

简单来说,就是JVM的指令重排!

public class DoubleCheckLock {
    private static DoubleCheckLock instance;

    private DoubleCheckLock() {
    	// TODO
    }

    public static DoubleCheckLock getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckLock.class) {
                if (instance == null) {
                    instance = new DoubleCheckLock();
                }
            }
        }
        return instance;
    }
}

再回过头看我们的双检锁内部,对于"instance = new DoubleCheckLock();"这一行代码,它分为三个步骤执行:

1.分配一块内存空间
2.在这块内存上初始化一个DoubleCheckLock的实例
3.将声明的引用instance指向这块内存
第2和第3个步骤都依赖于第1个步骤,但是2和3之间没有依赖关系,那么如果编译器将2和3调换顺序,变成了:

1.分配一块内存空间
2.将声明的引用instance指向这块内存
3.在这块内存上初始化一个DoubleCheckLock的实例
当线程A执行到第2步时,instance已经不为null了,因为它指向了这块内存,此时如果线程B走到了"if (instance == null)",那么线程B其实拿到的还是一个null,因为这块内存还没有初始化,这就出现了问题。
解决方案:volatile关键字

public class DoubleCheckLock {
    private static volatile DoubleCheckLock instance;

    private DoubleCheckLock() {
    	// TODO
    }

    public static DoubleCheckLock getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckLock.class) {
                if (instance == null) {
                    instance = new DoubleCheckLock();
                }
            }
        }
        return instance;
    }
}

3.OkHttp请求流程是什么?

https://www.jianshu.com/p/230e2e2988e0/

4.HashMap原理。

https://blog.csdn.net/vking_wang/article/details/14166593

5.EventBus如何做到进程间通信。

不清楚!~

6.详细讲一讲Http和Https。

7.数组和链表有什么区别?

数组存储区间是连续的,占用内存严重,故空间复杂度很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;

链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。

 

 

你可能感兴趣的:(Android高级岗面试实战)