Android 高级面试题大全(持续更新中),字节跳动厂内部超高质量 Flutter+Kotlin 笔记
6. 线程池的实现机制
向线程池提交任务,会依次启动核心线程,如果提交的任务数超过了核心线程数,会将任务保存到阻塞队列中,如果阻塞队列也满了,且继续提交任务,则会创建新线程执行任务,直到任务数达到最大线程数。此时如果再提交任务的话会抛出异常或者直接丢弃任务。通过 Executor.execute()无法得到返回值,通过 ExecutorService.submit()可以得到返回值。
7. RxJava 中 map 和 flatmap 操作符的区别及底层实现
Map 返回的是结果集,flatmap 返
回的是包含结果集的 Observable。Map 只能一对一,flatmap 可以一对多、多对多。
RxJava 是通过观察者模式实现的。
8. 对消息机制中 Looper 的理解
Looper 在消息机制中扮演的角色是创造无限循环从 Messagequeue 中取得消息然后分发。
9. 单例模式有哪些实现方式
饿汉模式(线程安全,调用效率高,但是不能延时加载)
懒汉模式(线程安全,调用效率不高,但是能延时加载)
双重检测锁模式(由于 JVM 底层模型原因,偶尔会出问题,不建议使用)
静态内部类式(线程安全,调用效率高,可以延时加载)
枚举类(线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用)
10. 通过静态内部类实现单例模式有哪些优点
线程安全,调用效率高,可以延时加载
11. synchronized volatile 关键字有什么区别?以及还有哪些同样功能的关键字
(1) volatile 是变量修饰符,而 synchronized 则作用于一段代码或者方法。
(2) volatile 只是在线程内存和 main memory(主内存)间同步某个变量的值;而 synchronized 通过锁定和解锁某个监视器同步所有变量的值。显然 synchronized 要比 volatile 消耗更多资源。
const、final、lock
12. 界面卡顿的原因有哪些?
UI 线程(main)有耗时操作
视图渲染时间过长,导致卡顿
13. 造成 OOM/ANR 的原因?
OOM: (1)不恰当地使用 static 关键字 (2)内部类对 Activity 的引用 (3)大量 Bitmap 的使用会导致程序包运行时的内存消耗变大 (4)游标 Cursor 对象用完应该及时关闭 (5)加载对象过大 (6)相应资源过多,来不及释放。
ANR: (1)在 5 秒内没有响应输入的事件(IO 操作耗时、数据库操作复杂耗时、主线程非主线程产生死锁等待、网络加载/图片操作耗时、硬件操作耗时) (2)BroadcastReceiver 在 10 秒内没有执行完毕(Service binder 数量达到上限、Service 忙导致超时无响应)
14. Activity 与 Fragment 生命周期有何联系
在创建的过程中,是 Activity 带领着 Fragment,在销毁的过程中,是 Fragment 带领着 Activity。
15. Glide 三级缓存
内存缓存,磁盘缓存、网络缓存(由于网络缓存严格来说不算是缓存的一种,故也称为二级缓存)。缓存的资源分为两种:原图(SOURCE)、处理图(RESULT)(默认)。
内存缓存:默认开启的,可以通过调用 skipMemoryCache(true)来设置跳过内存缓存,缓存最大空间:每个进程可用的最大内存*0.4。(低配手机 0.33)
磁盘缓存:分为四种:ALL(缓存原图)、NONE(什么都不缓存)、SOURCE(只缓存原图)、RESULT(之后处理图),通过 diskCacheStrategy(DiskCacheStrategy.ALL)来设置,缓存大小 250M。
16. MVC、MVP、MVVM 的原理
(1) MVC,Model View Controller,是软件架构中最常见的一种框架,简单来说就是通过 controller 的控制去操作 model 层的数据,并且返回给 view 层展示。当用户发出事件的时候,view 层会发送指令到 controller 层,接着 controller 去通知 model 层更新数据,model 层更新完数据以后直接显示在 view 层上,这就是 MVC 的工作原理。
(2) MVP 是 MVC 的演化。MVP 的 model 层相对于 MVC 是一样的,而 activity 和 fragment 不再是 controller 层,而是纯粹的 view 层,所有关于用户事件的转发全部交由 presenter 层处理。presenter 层充当了桥梁的作用,用于操作 view 层发出的事件传递到 presenter 层中,presenter 层去操作 model 层,并且将数据返回给 view 层。
(3) MVVM 和 MVP 的区别貌似不大,只不过是 presenter 层换成了 viewmodel 层,还有一点就是 view 层和 viewmodel 层是相互绑定的关系,这意味着当你更新 viewmodel 层的数据的时候,view 层会相应的变动 ui。
17. 数据库的操作类型有哪些,如何导入外部数据库?
(1) 增删改查
(2) 将外部数据库放在项目的 res/raw 目录下。因为安卓系统下数据库要放在 data/data/packagename/databases 的目录下,然后要做的就是将外部数据库导入到该目录下,操作方法是通过 FileInputStream 读取外部数据库,再用 FileOutputStrean 把读取到的东西写入到该目录下。
18. 是否使用过 IntentService,作用是什么, AIDL 解决了什么问题?
(1) IntentService 继承自 Service。由于 Service 运行在主线程,无法进行耗时操作。所以你需要在 Service 中开启一个子线程,并且在子线程中运行。为了简化这一操作,Android 中提供了 IntentService 来进行这一处理。通过查看 IntentService 的源码可以看到,在 onCreate 中,我们开启了一个 HandlerThread 线程,之后获取 HandlerThread 线程中的 Looper,并通过这个 Looper 创建了一个 Handler。然后在 onStart 方法中通过这个 Handler 将 intent 与 startId 作为 Message 的参数进行发送到消息队列中,然后交由 Handler 中的 handleMessage 中进行处理。由于在 onStart 方法是在主线程内运行的,而 Handler 是通过工作者线程 HandlerThread 中的 Looper 创建的。所以也就是在主线程中发送消息,在工作者接收到消息后便可以进行一些耗时的操作。
(2) 进程间通信
19. 是否使用过本地广播,和全局广播有什么差别?
本地广播的数据在本应用范围内传播,不用担心隐私数据泄露的问题。不用担心别的应用伪造广播,造成安全隐患。相比在系统内发送全局广播,它更高效。
20. Activity、 Window、 View 三者的差别, fragment 的特点?
(1) Activity 像一个工匠(控制单元),Window 像窗户(承载模型),View 像窗花(显示视图) LayoutInflater 像剪刀,Xml 配置像窗花图纸。
(2) a. Fragment 可以作为 Activity 界面的一部分组成出现;
b. 可以在一个 Activity 中同时出现多个 Fragment,并且一个 Fragment 也可以在多个 Activity 中使用;
c. 在 Activity 运行过程中,可以添加、移除或者替换 Fragment;
d. Fragment 可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主 Activity 的生命周期影响。
21. Handler、 Thread 和 HandlerThread 的差别
从 Android 中 Thread(java.lang.Thread -> java.lang.Object)描述可以看出,Android 的 Thread 没有对 Java 的 Thread 做任何封装,但是 Android 提供了一个继承自 Thread 的类 HandlerThread(android.os.HandlerThread -> java.lang.Thread),这个类对 Java 的 Thread 做了很多便利 Android 系统的封装。
android.os.Handler 可以通过 Looper 对象实例化,并运行于另外的线程中,Android 提供了让 Handler 运行于其它线程的线程实现,也是就 HandlerThread。HandlerThread 对象 start 后可以获得其 Looper 对象,并且使用这个 Looper 对象实例 Handler。
22. 低版本 SDK 实现高版本 api
自己实现或使用注解 @TargetApi annotation
23. launch mode 应用场景
(1) standard:标准的启动模式。
(2) singleTop:单一顶部模式
如果 Activity 已经被开启,并且处于任务栈的栈顶,就不会创建新的 Activity,而是复用这个已经开启的 Activity。
为了防止出现一些奇怪的用户体验,推荐使用单一顶部模式,整个任务栈可以有多个实例存在.
应用场景:短信发送界面.
(3)singletask:单一任务栈
在整个任务栈里面只允许有一个当前 Activity 的实例存在
如果要开启的 Activity 在任务栈中已经存在,直接复用这个已经存在的 Activity,并且把这个 Activity 上面的所有的其他 Activity 给清空
应用场景:如果一个 Activity 非常消耗内存和 cpu 资源,建议把这个 Activity 做成 singletask 的模式。浏览器的 browserActivity
(4)singleinstance:单一实例.
整个手机操作系统只有一个实例存在,并且是运行在自己单独的任务栈里面.
应用场景:通话界面的 Activity
评论