0
点赞
收藏
分享

微信扫一扫

Android相关面试题

八卦城的酒 2022-04-02 阅读 137
android

一.SharedPreferences是线程安全的吗?它的commit()方法和apply()方法有什么区别?它有什么缺点?有没有类似更好的方案?

1.SharePreferences是线程安全的 里面的方法有大量的synchronized来保障。
2.SharePreferences不是进程安全的 即使你用了MODE_MULTI_PROCESS 。
3.第一次getSharePreference会读取磁盘文件,异步读取,写入到内存中,后续的getSharePreference都是从内存中拿了。
4.第一次读取完毕之前,所有的get/set请求都会被卡住,等待读取完毕后再执行,所以第一次读取会有ANR风险。
5.所有的get都是从内存中读取。
6.提交都是写入到内存和磁盘中 。apply跟commit的区别在于apply 是内存同步,然后磁盘异步写入任务放到一个单线程队列中 等待调用。方法无返回,即void,commit 内存同步 只不过要等待磁盘写入结束才返回,直接返回写入成功状态 true or false
7.从 Android N 开始, 不再支持 MODE_WORLD_READABLE & MODE_WORLD_WRITEABLE. 一旦指定, 会抛异常 。也不建议使用MODE_MULTI_PROCESS 。
8.每次commit/apply都会把全部数据一次性写入到磁盘,即没有增量写入的概念 。 所以单个文件千万不要太大 否则会严重影响性能。

9.不能保证类型安全,调用 getXXX() 方法的时候,可能会出现 ClassCastException 异常,因为使用相同的 key 进行操作的时候,putXXX() 方法可以使用不同类型的数据覆盖掉相同的 key。

SharePreferencesDataStoreMMKV
是否线程安全
是否线程阻塞否(通过协程+Flow异步写入)
是否支持跨进程是(基于mmap+进程锁)
读取方式完整的 I/O 操作,需要经过用户态、内核态、文件系统通过 mmap 写入虚拟内存,0 拷贝和操作内存一样快
数据格式xml(键值对)xml或者ProtobufProtobuf
写入方式全量写入增量写入增量写入
是否类型安全
是否能监听数据变化

参考:再见 SharedPreferences,拥抱 Jetpack DataStore

[实践—卡顿优化] 替换 SharePreferences 为 MMKV_大圣代的博客-CSDN博客 

 再见 SharedPreferences ,Jetpack DataStore 第二种实现方式

 官方也无力回天?SharedPreferences的设计与实现

 详解DataStore,SharedPreferences终结者

二.Serializable和Parcelable的区别?

  1. 都是用于对象序列化的。
  2. Serializable是Java提供的,Parcelable是android专用的。
  3. Serializable序列化会调用反射的一些逻辑,产生大量的临时变量,因此效率较低,而Parcelable是通过native方法(Parcel.cpp)来将对象通过JNI写到内存中,一般情况下效率较高
  4. Parcelable实现过程较为复杂,并实现序列化、反序列化、内容描述的过程,不过AS有快捷方式,Serializable实现过程较为简单,类继承Serializable接口,添加常量serialVersionUID,此类就可以进行序列化和反序列化操作了。
  5. Parcelable适用于内存序列化,Serializable适用于存储设备和网络传输序列化。

三.LruCache底层原理?

  • 初始化的时候, 会限制缓存占据内存空间的总容量 maxSize;
  • 底层维护的是 LinkedHashMap, 使用 LruCache 最好要重写 sizeOf 方法, 用于计算每个被缓存的对象, 在内存中存储时, 占用多少空间;
  • 在 put 操作时, 首先计算新的缓存对象, 占多少空间, 再根据 key, 移除老的对象,
  • 占用内存大小 = 之前占用的内存大小 + 新对象的大小 - 老对象的大小;
  • put 操作最后总会根据 maxSize, 在拿到 LinkedHashMap.EntrySet 中链表的头节点, 循环判断, 只要当前缓存对象占据内存超出 maxSize, 就移除一个头节点, 一直到符合要求;
  • lruCache 和 LinkedHashMap 的关系:
  • LinkedHashMap 中维护一个双向链表, 并维护 head 和 tail 指针, lruCache 使用了 LinkedHashMap accessOrder 为 true 的属性, 只要访问了某个 key,
  • 包括 get 和 put, 就把当前这个 entry 放在链表的位节点, 所以链表的头节点, 是最老访问的节点, 尾节点是最新访问的节点,
  • 所以, lruCache 就很巧妙的利用了这个特点, 完成了 Least Recently Used 的需求;

四.android 5.0、android 6.0、android 7.0、android 8.0、android 9.0、android 10、android 11、android12 新特性?

android 5.0

1.默认开启art虚拟机

2.全新的Material Design 风格

3.添加了悬挂式通知栏

android 6.0

1.运行时权限

2.Doze电量管理

3.删除了HttpClient类库,只保留了HttpURLConnection,也可以自己导入HttpClient类库

android 7.0

1.多窗口模式

2.分享私有文件内容的推荐方法是使用FileProvider,使用content://协议,直接使用file://协议会报错

3.支持Java 8

4.后台省电

5.在启动activity的SystemServer进程过程中添加了ActivityStarter类,他是加载Activity的控制类,会收集所有的逻辑来将Intent和Flag转化成Activity。

6.art中添加了JIT即时编译器

android 8.0

1.添加了android中的一个InMemoryDexClassLoader,用于加载内存中的dex文件。

2.修改了IActivityManager从代理模式编程AIDL实现RPC。

3.系统绝大多数隐式广播不能静态注册,自定义隐式广播不能静态注册,个别系统广播可以静态注册,具体查看https://developer.android.google.cn/guide/components/broadcast-exceptions.html

4.引入通知渠道

5.只有前台service不容易被杀死,一旦进入后台,service随时会被回收

android 9.0

1.使用前台service必须声明权限(是普通权限)

2.默认只允许https类型的网络请求

android 10

1.引入深色主题特性

2.支持5g手机

3.通知栏智能回复

android 11

1.新增ControlsProviderService API,可用于提供连接外部设备的控件,这些控件显示于 Android 电源菜单中的设备控制器下。

2.无线调试,同一局域网可以直接进行无线调试手机

3.adb增量安装,命令adb install --incremental

4.聊天气泡

android 12

1.增加了Material You,可帮助您构建更具个性化、更精美的应用。

2.音频焦点,如果某个应用请求获得音频焦点,而另一个应用具有焦点并正在播放,则系统会淡出正在播放的应用。

3.微件改进,改进了现有的 Widgets API,以改善平台和启动器中的用户和开发者体验。

4.新增应用启动动画

参考:Android 5.0 行为变更  |  Android 开发者  |  Android Developers

5. 

举报

相关推荐

0 条评论