【Android面试】SDK相关面试题

1、请简要谈谈Android系统的架构组成?

android系统分为四部分,从高到低分别是:

  • Android应用层:

Android会同一系列核心应用程序包一起发布,该应用程序包括email客户端,SMS短消息程序,日历,地图,浏览 器, 联系人管理程序等。所有的应用程序都是使用JAVA语 言编写的。

  • Android应用框架层:

开发人员也可以完全访问核心应用程序所使用的API框架。该应用程序的架构设计简化了组件的重用;任何一个应用程 序都可以发布它的功能块并且任何其它的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性限制)。同 样,该应用程序重用机制也使用户可以方便的替换程序组件。

  • Android系统运行层:

Android 包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过 Android 应用程序框架为开发者 提供服务。

  • Linux内核层:

Android 的核心系统服务依赖于 Linux 2.6 内核,如安全性,内存管理,进程管理, 网络协议栈和驱动模型。 Linux 内核也同时作为硬件和软件栈之间的抽象层

2、SharedPreferences 是线程安全的吗?它的 commit 和 apply 方法有什么区别?

context.getSharedPreferences()开始追踪的话,可以去到ContextImpl的getSharedPreferences(),最终发现 SharedPreferencesImpl这个SharedPreferences的实现 类,在代码中可以看到读写操作时都有大量的synchronized,因此它是线程安全的

3、Serializable和Parcelable的区别?

Android中序列化有两种方式:Serializable以及Parcelable。其中Serializable是Java自带的,而 Parcelable是安卓专有的。Seralizable相对Parcelable而言,好处就是非常简单,只 需对需要序列化的类class执行就可以,不需要手动去处理 序列化和反序列化的过程,所以常常用于网络请求数据处理,Activity之间传递值的使用。 Parcelable是android特有的序列化API,它的出现是为了解决Serializable在序列化的过程中消耗资源严重的问题, 但是因为本身使用需要手动处理序列化和反序列化过程, 会与具体的代码绑定,使用较为繁琐,一般只获取内存数据的时候使用。

4、谈谈ArrayMap和HashMap的区别?

  • 查找效率

HashMap因为其根据hashcode的值直接算出index,所以其 查找效率是随着数组长度增大而增加的。ArrayMap使用的是二分法查找,所以当数组长度每增加一 倍时,就需要多进行一次判断,效率下降

  • 扩容数量

HashMap初始值16个长度,每次扩容的时候,直接申请双倍的数组空间。ArrayMap每次扩容的时候,如果size长度大于8时申请size*1.5个长度,大于4小于8时申请8个,小于4时申请4 个。这样比较ArrayMap其实是申请了更少的内存空间,但 是扩容的频率会更高。因此,如果数据量比较大的时候,但是使用HashMap更合适,因为其扩容的次数要比 ArrayMap少很多。

  • 扩 容 效 率

HashMap每次扩容的时候重新计算每个数组成员的位置, 然后 放 到 新 的 位 置 。ArrayMap则是直接使用System.arraycopy,所以效率上 肯定是ArrayMap更占优势。

  • 内存消耗

以ArrayMap采用了一种独特的方式,能够重复的利用因为 数据扩容而遗留下来的数组空间,方便下一个ArrayMap的 使用。而HashMap没有这种设计。 由于ArrayMap之缓存了长度是4和8的时候,所以如果频繁的使用到Map,而且数据量都比较小的时候,ArrayMap无疑是相当的是节省内存的。

5、简要说说 LruCache 的原理?

androidx.collection.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 就很巧妙的利用了这个特点, 完成了 LeastRecently Used 的需求;

6、为什么推荐用SparseArray代替HashMap?

并不能替换所有的HashMap。只能替换以int类型为key的HashMap。HashMap中如果以int为key,会强制使用Integer这个包装类型,当我们使用int类型作为key的时候系统会自用装箱成为Integer,这个过程会创建对象一想效率。SparseArray内部是一个int数组和一个object数组。可以直 接使用int减少了自动装箱操作。

#android面试#
全部评论
感恩!给大佬递茶
点赞 回复 分享
发布于 2023-02-22 15:12 甘肃
看见干货 收藏√
点赞 回复 分享
发布于 2023-02-22 14:39 浙江

相关推荐

上周组里招人,我面了六个候选人,回来跟同事吃饭的时候聊起一个让我挺感慨的现象。前三个候选人,算法题写得都不错。第一道二分查找,五分钟之内给出解法,边界条件也处理得干净。第二道动态规划,状态转移方程写对了,空间复杂度也优化了一版。我翻他们的简历,力扣刷题量都在300以上。后三个呢,就有点参差不齐了。有的边界条件没处理好,有的直接说这道题没刷过能不能换个思路讲讲。其中有一个女生,我印象特别深——她拿到题之后没有马上写,而是先问我:“面试官,我能先跟你确认一下我对题目的理解吗?”然后她把自己的思路讲了一遍,虽然最后代码写得不是最优解,但整个沟通过程非常顺畅。这个女生的代码不是最优的,但当我问她“如果这里是线上环境,你会怎么设计’的时候,她给我讲了一套完整的方案——异常怎么处理、日志怎么打、怎么平滑发布。她对这是之前在实习的时候踩过的坑。”我在想LeetCode到底在筛选什么?我自己的经历可能有点代表性。我当年校招的时候,也是刷了三百多道题才敢去面试。那时候大家都刷,你不刷就过不了笔试关。后来工作了,前三年基本没再打开过力扣。真正干活的时候,没人让你写反转链表,也没人让你手撕红黑树。更多的是:这个接口为什么慢了、那个服务为什么OOM了、线上数据对不上了得排查一下。所以后来我当面试官,慢慢调整了自己的评判标准。算法题我还会出,但目的变了。我出算法题,不是想看你能不能背出最优解。而是想看你拿到一个陌生问题的时候,是怎么思考的。你会先理清题意吗?你会主动问边界条件吗?你想不出来的时候会怎么办?你写出来的代码,变量命名乱不乱、结构清不清楚?这些才是工作中真正用得到的能力。LeetCode是一个工具,不是目的。它帮你熟悉数据结构和常见算法思路,这没问题。但如果你刷了三百道题,却说不清楚自己的项目解决了什么问题、遇到了什么困难、你是怎么解决的,那这三百道题可能真的白刷了。所以还要不要刷LeetCode?要刷,但别只刷题。刷题的时候,多问自己几个为什么:为什么用这个数据结构?为什么这个解法比那个好?如果换个条件,解法还成立吗?把刷题当成锻炼思维的方式,而不是背答案的任务。毕竟面试官想看到的,从来不是一台背题机器,而是一个能解决问题的人。
国企上岸了的向宇同桌...:最害怕答非所问了,但是频繁反问确定意思又害怕面试官觉得我笨
AI时代还有必要刷lee...
点赞 评论 收藏
分享
评论
4
24
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务