面试宝典|Android基础(二)

本篇主要讲解数据库及IPC相关

数据存储相关

Q:Android中提供哪些数据持久存储的方法?

  • 技术点:数据持久化
  • 思路:分条解释每种数据持久存储的特点
  • 参考回答:Android平台实现数据存储的常见几种方式:
    • File 文件存储:写入和读取文件的方法和 Java中实现I/O的程序一样。
    • SharedPreferences存储:一种轻型的数据存储方式,常用来存储一些简单的配置信息,本质是基于XML文件存储key-value键值对数据。
    • SQLite数据库存储:一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,在存储大量复杂的关系型数据的时可以使用。
    • ContentProvider:四大组件之一,用于数据的存储和共享,不仅可以让不同应用程序之间进行数据共享,还可以选择只对哪一部分数据进行共享,可保证程序中的隐私数据不会有泄漏风险。

Q:Java中的I/O流读写怎么做?

  • 技术点:数据持久化(文件存储)
  • 思路:大致介绍核心类和核心方法
  • 参考回答:和 Java中实现I/O的程序是一样的,Context类中提供了openFileInput()和openFileOutput()方法来打开数据文件里的文件IO流

Q:SharePreferences适用情形?使用中需要注意什么?

  • 技术点:数据持久化(SharePreferences存储)
  • 参考回答:SharePreferences是一种轻型的数据存储方式,适用于存储一些简单的配置信息,如int、string、boolean、float和long。由于系统对SharedPreferences的读/写有一定的缓存策略,即在内存中有一份该文件的缓存,因此在多进程模式下,其读/写会变得不可靠,甚至丢失数据。
  • 引申:谈谈Android中多进程通信(Binder)

Q:了解SQLite中的事务处理吗?是如何做的?

  • 技术点:数据持久化(SQLite)
  • 参考回答:SQLite在做CRDU操作时都默认开启了事务,然后把SQL语句翻译成对应的SQLiteStatement并调用其相应的CRUD方法,此时整个操作还是在rollback journal这个临时文件上进行,只有操作顺利完成才会更新.db数据库,否则会被回滚。
  • 引申:谈谈如何模仿SQLite中事务的思想更高效进行批量操作

Q:使用SQLite做批量操作有什么好的方法吗?

  • 技术点:数据持久化(SQLite)
  • 思路:模仿SQLite的事务处理
  • 参考回答:使用SQLiteDatabase的beginTransaction()方法开启一个事务,将批量操作SQL语句转化成SQLiteStatement并进行批量操作,结束后endTransaction()

Q:如果现在要删除SQLite中表的一个字段如何做?

  • 技术点:数据持久化(SQLite)
  • 参考回答:SQLite数据库只允许增加表字段而不允许修改和删除表字段,只能采取复制表思想,即创建一个新表保留原表想要的字段、再将原表删除

Q:使用SQLite时会有哪些优化操作?

  • 技术点:数据持久化(SQLite)
  • 思路:列举可优化点
  • 参考回答:
    • 使用事务做批量操作:具体操作见上
    • 及时关闭Cursor,避免内存泄漏
    • 耗时操作异步化:数据库的操作属于本地IO,通常比较耗时,建议将这些耗时操作放入异步线程中处理
    • ContentValues的容量调整:ContentValues内部采用HashMap来存储Key-Value数据,ContentValues初始容量为8,扩容时翻倍。因此建议对ContentValues填入的内容进行估量,设置合理的初始化容量,减少不必要的内部扩容操作
    • 使用索引加快检索速度:对于查询操作量级较大、业务对要求查询要求较高的推荐使用索引

IPC相关

Q:Android中进程和线程的关系?

  • 技术点:进程、线程
  • 参考回答:
    • 形象理解:如果把安卓系统比喻成一片土壤,可以把App看做扎根在这片土壤上的工厂,每个APP一般对应一个进程,那么线程就像是工厂的生产线。其中,主线程好比是主生产线,只有一条,子线程就像是副生产线,可以有很多条。
    • 关系:一个APP一般对应一个进程和有限个线程
      • 一般对应一个进程,当然,可以在AndroidMenifest中给四大组件指定属性android:process开启多进程模式
      • 有限个线程:线程是一种受限的系统资源,不可无限制的产生且线程的创建和销毁都有一定的开销。

Q:为何需要进行IPC?多进程通信可能会出现什么问题?

  • 技术点:多进程通信
  • 思路:讨论多进程通信会出现的问题得出IPC的必要性
  • 参考回答:
  • (1)多进程造成的影响可总结为以下四方面:
    • 静态变量和单例模式失效:由独立的虚拟机造成
    • 线程同步机制失效:由独立的虚拟机造成
    • SharedPreference的不可靠下降:不支持两个进程同时进行读写操作,即不支持并发读写,有一定几率导致数据丢失
    • Application多次创建: Android系统会为新的进程分配独立虚拟机,相当于系统又把这个应用重新启动了一次。
  • (2)需要进程间通信的必要性:所有运行在不同进程的四大组件,只要它们之间需要通过内存在共享数据,都会共享失败。这是由于Android为每个应用分配了独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这会导致在不同的虚拟机中访问同一个类的对象会产生多份副本。
  • 引申: 谈谈IPC的使用场景

Q:什么是序列化?Serializable接口和Parcelable接口的区别?为何推荐使用后者?

  • 技术点:序列化
  • 参考回答:序列化表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
    • 应用场景:需要通过Intent和Binder等传输类对象就必须完成对象的序列化过程。
    • 两种方式:实现Serializable/Parcelable接口。不同点如图:


      Serializable与Parcelable图解

Q:Android中为何新增Binder来作为主要的IPC方式?

  • 技术点:Binder机制
  • 思路:回答Binder优点
  • 参考回答:Binder机制有什么几条优点:
    • 传输效率高、可操作性强:传输效率主要影响因素是内存拷贝的次数,拷贝次数越少,传输速率越高。从Android进程架构角度分析:对于消息队列、Socket和管道来说,数据先从发送方的缓存区拷贝到内核开辟的缓存区中,再从内核缓存区拷贝到接收方的缓存区,一共两次拷贝,如图:



      而对于Binder来说,数据从发送方的缓存区拷贝到内核的缓存区,而接收方的缓存区与内核的缓存区是映射到同一块物理地址的,节省了一次数据拷贝的过程,如图:



      由于共享内存操作复杂,综合来看,Binder的传输效率是最好的。
    • 实现C/S架构方便:Linux的众IPC方式除了Socket以外都不是基于C/S架构,而Socket主要用于网络间的通信且传输效率较低。Binder基于C/S架构 ,Server端与Client端相对独立,稳定性较好。
    • 安全性高:传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Binder机制为每个进程分配了UID/PID且在Binder通信时会根据UID/PID进行有效性检测。

Q:使用Binder进行数据传输的具体过程?

  • 技术点:Binder机制
  • 思路:通过AIDL实现方式解释Binder数据传输的具体过程
  • 参考回答:服务端中的Service给与其绑定的客户端提供Binder对象,客户端通过AIDL接口中的asInterface()将这个Binder对象转换为代理Proxy,并通过它发起RPC请求。客户端发起请求时会挂起当前线程,并将参数写入data然后调用transact(),RPC请求会通过系统底层封装后由服务端的onTransact()处理,并将结果写入reply,最后返回调用结果并唤醒客户端线程。


Q:Binder框架中ServiceManager的作用?

  • 技术点:Binder机制
  • 思路:从Binder框架出发讨论每个元素的作用
  • 参考回答:在Binder框架定义了四个角色:Server,Client,ServiceManager和Binder驱动。其中Server、Client、ServiceManager运行于用户空间,Binder驱动运行于内核空间。关系如图:


    • Server&Client:服务器&客户端。在Binder驱动和Service Manager提供的基础设施上,进行Client-Server之间的通信。
    • ServiceManager服务的管理者,将Binder名字转换为Client中对该Binder的引用,使得Client可以通过Binder名字获得Server中Binder实体的引用。流程如图:


  • Binder驱动:
    • 与硬件设备没有关系,其工作方式与设备驱动程序是一样的,工作于内核态。
    • 提供open()、mmap()、poll()、ioctl() 等标准文件操作。
    • 以字符驱动设备中的misc设备注册在设备目录/dev下,用户通过/dev/binder访问该它。
    • 负责进程之间binder通信的建立,传递,计数管理以及数据的传递交互等底层支持。
    • 驱动和应用程序之间定义了一套接口协议,主要功能由ioctl() 接口实现,由于ioctl()灵活、方便且能够一次调用实现先写后读以满足同步交互,因此不必分别调用write()和read()接口。
    • 其代码位于linux目录的drivers/misc/binder.c中。

Q:Android中有哪些基于Binder的IPC方式?简单对比下?

  • 技术点:IPC方式
  • 思路:分析每种IPC方式的优缺点和使用场景的差异
  • 参考回答:


    image.png

Q:是否了解AIDL?原理是什么?如何优化多模块都使用AIDL的情况?

  • 技术点:AIDL
  • 思路:
  • 参考回答:
    • AIDL(Android Interface Definition Language,Android接口定义语言):如果在一个进程中要调用另一个进程中对象的方法,可使用AIDL生成可序列化的参数,AIDL会生成一个服务端对象的代理类,通过它客户端实现间接调用服务端对象的方法。
    • AIDL的本质是系统提供了一套可快速实现Binder的工具。关键类和方法:
      • AIDL接口:继承Interface。
      • Stub类:Binder的实现类,服务端通过这个类来提供服务。
      • Proxy类:服务器的本地代理,客户端通过这个类调用服务器的方法。
      • asInterface():客户端调用,将服务端的返回的Binder对象,转换成客户端所需要的AIDL接口类型对象。返回对象:
        • 若客户端和服务端位于同一进程,则直接返回Stub对象本身;
        • 否则,返回的是系统封装后的Stub.proxy对象。
      • asBinder():根据当前调用情况返回代理Proxy的Binder对象。
      • onTransact():运行服务端的Binder线程池中,当客户端发起跨进程请求时,远程请求会通过系统底层封装后交由此方法来处理。
      • transact():运行在客户端,当客户端发起远程请求的同时将当前线程挂起。之后调用服务端的onTransact()直到远程请求返回,当前线程才继续执行。
    • 当有多个业务模块都需要AIDL来进行IPC,此时需要为每个模块创建特定的aidl文件,那么相应的Service就会很多。必然会出现系统资源耗费严重、应用过度重量级的问题。解决办法是建立Binder连接池,即将每个业务模块的Binder请求统一转发到一个远程Service中去执行,从而避免重复创建Service。
    • 工作原理:每个业务模块创建自己的AIDL接口并实现此接口,然后向服务端提供自己的唯一标识和其对应的Binder对象。服务端只需要一个Service,服务器提供一个queryBinder接口,它会根据业务模块的特征来返回相应的Binder对像,不同的业务模块拿到所需的Binder对象后就可进行远程方法的调用了。流程如图:


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341