2018 android中高级面试题总结

        最近在考虑着换工作的事情,面试了大概十几家吧,因为在职所以不着急,总结了一些长问的问题,都是些理论的问题,回答完这些就看面试官怎么问原理了,小伙伴们自由发挥吧,这些都回答不了,别人就没别的机会问的细一点了对吧!!!

oom
当前占用内存加上我们申请的内存资源超过虚拟机的最大内存限制,就会出现.
内存溢出:指程序申请内存时,没有足够的空间供其使用
内存泄漏:指程序分配出去的内存不再使用,无法回收
内存抖动:指短时间内大量创建对象,然后回收对象

解决oom
BitMap:
图片压缩 > 加载缩略图 > 在滚动时不加载图片 > 使用完回收BitMap >使用Inbitmap属性
避免Ondraw方法执行对象创建
LruCache 内部使用LinkhashMap实现

UI卡顿原因分析
在ui线程中做稍微耗时操作导致卡顿 > layout过于复杂,无法再16ms完成渲染 >同时间执行动画次数过多导致cpu负载过重 > view频繁的触发measure layout 导致累计耗时过多 > 频繁的触发Gc 到时线程暂停 > 多余资源及逻辑导致加载和执行缓慢
UI卡顿优化 >
布局优化 >
使用<include>,<merge>,<viewstub>标签
不要出现过于嵌套和多余的布局
使用自定义view取代复杂的view

内存泄漏引起的主要原因:
长生命周期对象持有短生命周期对象的引用就可能发生内存泄漏
java内存分配策略:
静态方法区:储存全局变量和静态变量,在整个程序运行间都存在
栈区:方法体的局部变量,在方法结束后释放空间和内存
堆区: 保存动态产生的数据,如new处理的对象数组,在不使用的时候由java回收器自动回收

andorid内存泄漏的例子
单例造成的内存泄漏,在单例中使用application的context
匿名内部类,由于非静态内部类持有匿名外部类的引用,必须将内部类设置成static
Handler造成的内存泄漏,使用static的handler内部类,在实现内部类中使用context的弱引用
少使用静态变量
资源未关闭
asyncTask造成的内存泄漏,使用activity的弱引用,使用静态内部类,在activity销毁时cancel

android内存管理机制
更少的占用内存
在合适的时候,合理的释放系统资源
在系统资源紧张的时候,能释放掉大部分不重要的资源
能合理的在特殊生命周期中,保存或还原重要数据

内存优化方法
service完成任务应该取消他,用intentservice(完成任务后自动停止)代替service
在ui不可见时 释放ui资源
在系统内存紧张的时候释放不重要的资源
避免滥用bitmap造成资源浪费
使用针对内存优化过的容器
使用多进程

冷启动热启动
冷启动:在系统启动前系统中没有应用的任何信息,创建application后再创建和初始化mainactivity
热启动:再已有的进程上启动应用,创建和初始化mainactivity即可
优化:
减少第一个界面oncreate方法的工作量
不要让application参与业务的操作,进行耗时操作,不再application中保存过多静态变量
减少布局的复杂性和深度
不要在主线程中加载资源
通过懒加载方式加载第三方sdk

android不适用静态变量保存数据
sharepreference安全问题,不能跨进程同步,文件不能过大
内存对象序列化serializeble是java对象序列化 serializeble在序列化是产生大量临时对象,从而引起频繁的GC
pracelable是android序列化方式,性能比serializeble高,precelable不能使用在将数据存储在硬盘上的情况

MVC模式
优点:
耦合性低>重用性高>生命周期成本低>部署快>可维护性高>
缺点:
视图与控制器过于紧密连接 >没有明确的定义 > 增加系统结构和实现的复杂性 > 视图对模型数据的低效率访问

MVP模式
model:数据层,负责处理数据的加载和存储
view:视图层,负责界面的展示和用户交互
persenter:中间者,绑定model层和view层,是model和view的桥梁
优点:
模型与视图完全分离,修改视图不影响模型
更高效的使用模型,所有的交互都在persenter内部
可以将persenter用于多个视图,而不需要改变persenter的逻辑
如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)

JNI
Java调用C++
1在java中声明native方法
2编译java源文件javac(得到.class)文件,通过javah命令到处jni的头文件(.h文件)
3使用java需要交互的本地代码,实现java中声明的native方法
4编译.so库文件
5执行java程序,最终实现调用本地代码

webView优化
预加载webView
加载webView同时请求h5数据

pathClassLoader 只能加载安装到android系统里的apk文件,android默认的类加载器
dexClassLoader 可以加载任意目录下的dex,apk,jar,zip文件

android内存缓存和磁盘缓存
内存缓存基于Lrucache实现,磁盘缓存基于diskLruCache实现,都是基于LRU算法和linkHashMap实现
LruCache的原理是利用LinkHashMap持有对象的强引用,按照Lru算法进行淘汰,假设从表尾访问数据,在表头删除数据,当访问的数据项在链表中存在时,则将数据移动到表尾,否则在表尾创建一个数据项,当链表容量超过一定阈值,则移除表头数据

进程保活
提升进程的优先级,降低被杀死的概率
拉活已经被杀死的进程
监控手机锁屏事件,锁屏时启动一个1像素的activity,解锁时关闭,前台activity可以将进程变成前台进程,优先级最高
利用广播拉活activity

序列化
序列化就是将对象变成二进制流,便于传输和存储
serializable是java实现的一套序列化方式,会生成大量临时对象,频繁触发GC操作,效率低,适用于将对象存储在磁盘上
pracelable是android实现的序列化机制,将序列化的对象写入到一块共性内存中,其他对象可以从这块共性内存中读取字节流,并反序列化成对象,效率高,适合对象间或进程间传递信息

SQLite升级
将现有的表命名为临时表
创建新表
将临时表的数据导入到新表里
删除临时表

android中的几种进程
前台进程 :用户当前操作必须得进程
可见进程 :没有任何前台组件,但会影响用户在屏幕上所见内容
服务进程: 正在运行用户使用startService()方法启动的服务切不属于上两个最高级别进程
后台进程:包含对用户不可见的activity的进程
空进程:不含任何应用组件的进程,目的为了缓存

andorid Binder机制
是android实现进程通信的机制之一
client 用来获取服务
service 提供服务
serviceManager:servicemanager的作用是将字符形式的binder转化成client中对该binder的应用,使client端能通过binder名字获得service端binder实体的引用
binder驱动:负责进程间binder通信的建立,binder在进程间的传递,等一系列底层支持

handler机制
message:消息分为硬件产生的消息(触摸,按钮)和软件产生的消息
messagequeue:消息队列,用来向消息池存放和取走消息
looper:消息循环器,用来把消息发送给相应的处理者
hanlder:消息处理器,主要向消息队列发送以及处理各种消息

hanlder通过sendmessage()发送消息到消息队列
looper通过loop不断提取触发条件的消息,并将消息交给对应的target:hanlder处理
target hanlder通过hanldermessage()方法处理消息

view绘制过程
onMeasure()测量视图大小,从顶层父view到子view递归调用measure()方法,onmeasure()调用onMeasure(),onMeasure方法测量视图大小
onLayout() 确定视图位置,从顶层父view到子view递归调用layout()方法,父view根据上一步measure()得到的子view布局大小,将子view放到合适的位置上
onDraw()绘制最终的视图,viewRoot创建canvers()对象,调用ondraw()方法绘制,流程为
1.绘制视图背景,2.绘制画布图层;3.绘制view内容;4.绘制子view;5还原图层;,6绘制滚动条

view,viewGroup事件分发
1.touch事件分发只有两个猪脚:viewgroup和view,viewGroup包含onInterceptTouchEvent,dispatchTouchEvent,onTouchEvent三个相关事件,View包含dispatchTouchEvent和onTouchEvent两个,其中ViewGroup继承View.
2.ViewGroup和View组成了一个树状结构,根节点为Activity内部包含的Viewgroup
3.触摸事件有ACTION_DOWN,ACTOIN_MOVE,ACTION_UP组成,一次完整的触摸事件中,DOWN,UP只会执行一次,MOVE会执行多次,也可以为0.
4.当activity接收到Touch事件时将遍历子view进行DOWN事件分发,ViewGroup的遍历可以看成递归的,分发的目的是为了找到真正要处理本次完整触摸事件的view,这个view会在onTouchEvent中返回true
5.当某个子view返回true时会终止DOWN事件分发,同时在viewGroup中记录该子view,接下来的UP,MOVE事件将有该子view直接处理,由于子view时保存在ViewGroup中的,多层ViewGroup节点结构时,上级ViewGroup保存的会是真实处理事件的View所在的Viewgroup对象,:如ViewGroup0-ViewGroup1-TextView的结构中,TextView返回了true,它将被保存在ViewGroup1中,而ViewGroup1也会返回true,被保存在ViewGroup0中。当Move和UP事件来时,会先从ViewGroup0传递至ViewGroup1,再由ViewGroup1传递至TextView。
6.当ViewGroup中所有子View都不捕获DOWN事件时,将触发ViewGroup自身的onTouch事件,触发的方式是调用super.dispatchTouchEvent(),在所有子View都不处理的情况下,触发activity的onTouchEvent方法;
7.OnInterceptTouchEvent有两个作用:1.拦截DOWN事件分发,2.终止UP和MOVE事件向目标View传递,使得view所在的ViewGroup捕获UP和DOWN事件

android动画
帧动画:通过指定每一帧的图片和播放时间,有序的进行播放而形成的动画效果
补间动画:通过指定View的初始状态,变化时间,方式,经过算法进行图形变换从而形成的动画效果,有Alpha,Translate,Rotate,Scale.只是在视图层实现了动画效果,并没有改变view的属性,比如滑动列表,改变标题栏透明度
属性动画:3.0后才支持,通过不断的改变view的属性,不断的重绘而形成的动画效果,相比于视图动画,View的属性是真的改变了,比如view的放大,缩小,旋转.

跨进程通信的几种方式
android跨进程通信,intent,contentprovider,广播,service都可以跨进程
intent: 这种跨进程方式不是访问内存的形式,需要传递一个uri比如打电话
contentProvider:这种方式是使用数据共享的形式进行数据共享
service: 远程服务,AIDL

binder机制理解
在android系统中,有client,service,serviceManager,和Binder驱动四部分组成,其中client,service,serviceManager运行在用户空间中,binder驱动运行在内核空间中,而binder就是把这四种组件粘合在一起的粘合剂,核心组件就是binder驱动,serviceManager提供辅助管理功能,client和service正是在binder驱动和serviceManager提供的基础设施上完成C/S通信的.

http和https的区别
1,https需要ca证书,需要一定费用
2,http是超文本传输协议,信息是明文传输,https是具有安全性的ssl加密传输协议
3,http和https用的完全不同的连接方式,用的端口也不一样,前者是80,后者是443
4,http连接是无状态的,https是由ssl+http协议构建的可进行加密传输,身份认证的网络协议,比http协议更安全
http协议的特点:客户端每次发送求情都需要服务器回送响应,在请求结束后,主动释放连接,从建立连接到关闭连接的过程叫"一次连接"

TCP和UDP的区别
tcp是面向连接的,由于tcp需要三次握手,所以能够最低层度降低风险保证连接的可靠
udp不是面向连接的,连接前不需要于对象建立连接,无论发送还是接收,都没有发送信号,udp是不可靠的,传输速率高



阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页