一周CP笔试问答题记录

一周CP笔试问答题记录

多线程

1. 有哪些情况会破坏Collections.synchronizedMap() 和 ConcurrentHashMap线程安全?

- Collections.synchronizedMap()和ConcurrentHashMap只能保证单个方法的线程安全即原子性

- 在进行组合操作的情况会产生问题例如

if(map.contains(key)){

    map.put(key, map.get(key) + 1)

} else {

    map.put(key, 1)

}

2. 为什么调用Object.wait()方法经常需要外面包着while()循环?

- 因为在多个线程抢占锁的时候竞态条件可能会改变,所以在获取到锁之后需要再次判断条件是否改变

- 例如在生产消费者模型中,多个消费者wait阻塞, 生产出一个产品之后进行notifyAll(), 一个消费者竞争到锁消耗掉产品,之后进行notifyAll()通知其他消费者,此时如果是简单的if,消费者获得锁之后会直接进行消费会产生空指针因为此时没有产品,所以需要进行while循环判断是否有产品,无产品继续进行wait,有产品才跳出循环进行消费。

或者举个有界阻塞队列的列子

3. 同样是持有外部activity的引用, 为什么AsyncTask会导致内存泄漏,而View就不会?

- 首先抛开这个问题,Android中内存泄漏指的是本来要被回收的资源却没有被回收

- 而判断一个对象能否被回收,要看这个对象能否通过直接或间接的引用到达GC root,如果这条引用链上没有gcroot,就说明这个对象不再被使用,等待回收。

- 所以这样来说AsyncTask会导致内存泄漏是因为内部线程持有activity的引用,而线程的生命周期比Activity更长,所以在acitivity销毁的时候,线程还活着并且有activity的引用,所以导致activity无法回收导致内存泄漏。view不会导致activity内存泄漏是因为其生命周期比activity短,如果把view声明为static 一样会导致activity内存泄漏。

- 非静态内部类会持有外部类的this引用, 因为内部类访问外部类的成员变量和方法就是通过初始化传入的this

View

1. 简单描述下View绘制流程。如果绘制一个宽高均为50dp的view, 且大小不受使用者自定义, 你会怎么做?

2. 聊聊你对子线程不能更新ui的看法

这个说法是正确的,但不是绝对的。activity在执行到onResume周期,创建viewrootimpl, 对mThread = Thread.currentThread(),由于ActivityThread是运行在主线程的所以此时mThread就是主线程, 更新ui会执行requestLayout(), 这个方法中会对线程进行判断,不是主线程就抛出异常。 所以在onResume生命周期之前是可以在子线程更新ui的,但是时间很短而且不确定,所以很不安全。

3. view.post传入的Runnable一定会被执行吗? 为什么?

不一定会执行, 在view被attach之前,在子线程执行view.post,runnable就不会被执行,在attach之后才可以。 因为在view被attach之前post,runnable会被加入到等待列表RunQueue里,而RunQueue是ThreadLocal变量, 等到view被attach之后,会从拿到RunQueue从中取出runnable执行,但是此时是在主线程。所以拿不到子线程的RunQueue

Lifecycle

1. 在默认的启动模式下:从activityA打开activityB,两个activity的生命周期回调如何?

 AonPause ->  BonCreat -> BonStart -> BonResume  ->  AonStop

按返回键返回activityA    BonPause -> AonRestart -> AonStart -> AonResume -> BonStop -> BonDestory

2. 在ActivityB为singleInstance的启动模式下,从activityA打开activityB,两个activity的生命周期回调如何?

当任务栈中不存在ActivityB实例的话 生命周期与题一相同

如果存在 会走 BonPause -> AonNewIntent - > AonStart -> AonResume -> BonStop

3. 在ActivityB为singleInstance的启动模式下, intent中添加Flag 为Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP: 从activityA打开activityB,两个activity的生命周期回调如何?

singleInstance意味着ActivityB,会在新的任务栈中,并且任务栈中只会有它自己,所以添加的flag并不会影响生命周期

与题二相同

4. Activity中的界面会在那个生命周期之后才能显示出来? 为什么?

onResume, 因为resume的时候创建ViewRoot, 进行requestLayout(), 其中进行performMeasure()、performLayout()、performDraw()测量布局绘制,之后才能显示到屏幕上。

你可能感兴趣的:(一周CP笔试问答题记录)