安卓面试小结.
2017-03-23 00:00
246 查看
安卓面试小结:
1.Retrofit框架的结构是什么?底层是怎么实现的?简述:(这里可能理解不到位,链接里面比较详细)
Retrofit是对okhttp的进一步封装,它使用的是动态代理的技术,通过扫描注解构造请求体,底层使用okhttp进行网络请求,利用handler进行异步操作.
底层具体实现 : Retrofit2.0源码解析
2.网络框架是如何搭建的?Okhttp的底层实现是什么,和Retrofit有什么不同?
(1)Android学习之——自己搭建Http框架(1)
(2)Okhttp流处理底层使用了okio,具体实现推荐看看 OkHttp3源码分析[综述]
(3)Rtrofit就是对Okhttp进一步的封装,请求体通过注解的形式逐步传入,Rtrofit会自动封装,底层网络请求同样使用的是okhttp,它与Rxjava搭配更灵活.
以上是简单概括,给个鸿洋大神连接: Retrofit2
完全解析 探索与okhttp之间的关系
3.图片加载框架Glide,Picasso,Fresco有什么不同,各自的实现原理是什么?如何搭建一个网络框架?
Picasso:Square公司出品.
底层网络请求使用的是okhttp.
优点:体积小,使用简单.图片默认RGB_8888
尺寸大,不支持gif,对大图片加载不方便.它底层实现就是对Handler进行的高效封装。
Gilde:Google出品.
使用方法和picasso十分相像,支持gif,默认尺寸RGB_565.体积比Picasso大。
Fresco:Facebook出品
(1)使用的是android的匿名共享内存,不占用虚拟机内存,节约应用内存使用,避免oom,减少bitmap回收提高应用性能
(2)支持图片渐进加载
(3)可以设置图片任意一点为中心
(4)图片展示操作在native中,不在虚拟机避免oom
(5)支持gif
不足之处只能使用固定的控件SimpleDraweeView,体积太大
网络框架的搭建(讲道理我也没搞过)
若使用现有的api那就简单了(相当于二次封装)还是上连接吧 Android学习之——自己搭建Http框架(1)
4.冒泡 选择 插入 快速基本算法的实现,单链表,双链表,二叉树,队列数据结构的实现思路是什么?
冒泡:
选择:
插入:
快速:
(下面的是个人理解)
单链表,双链表,二叉树,不借助其它的工具类实现.由于java没有指针这个东西,我们可以搞一个对象:
单链表:p.next(p);
双链表:p.front(p); p.next(p);
二叉树:p.front(p); p.left(p); p.right(p);
类似上面这种形式,当然也可以借助LinkedhashMap这类的集合类
5.如何实现跨进程通信,什么事AIDL,IPC机制,Binder机制的实现的原理
语言表达不行直接上超链接:
(1)AIDL,广播,Content Provider,访问其他应用程序的Activity
(2)AIDL : Android:学习AIDL,这一篇文章就够了(上)
Android:学习AIDL,这一篇文章就够了(下)
小Demo : 安卓漫漫路之AIDL传递简单数据.
(3)IPC : Android开发艺术探索 第2章 IPC机制 读书笔记
(4)Binder : Binder 牌胶水
6.三级缓存的底层实现?
(1)内存缓存
内存大小为应用内存大小的1/8, 底层使用的是LruCache,最近最最少使用算法,使用的是双向链表的数据结构(LinkedHashMap). 即最常使用的和新插入的数据会保存在链表头部,不常使用的数据会在链表尾部.若链表存满则删除链表尾部最后的元素,在头部插入新元素.
(2)本地缓存
底层使用的是DiskLruCache同为最近最最少使用算,也是是双向链表的数据结构(LinkedHashMap)同上.
(3)网络缓存
在服务端进行的缓存,若客户端无内存缓存,本地缓存则请求网络,若服务器有缓存则直接返回缓存数据,未缓存,则直接返回请求数据并缓存.
三级缓存顺序:
内存缓存->本地缓存->网络缓存
l 发送网络请求前先验证内存缓存是否有缓存数据 , 有则直接从内存中取,否则验证本地缓存。
l 内存缓存无缓存数据,验证本地缓存,本地缓存有则取出本地缓存数据,并缓存进内存缓存。若无缓存则请求网络。
l 本地缓存无缓存数据则通过网络请求服务器,并将换回的数据缓存到内存和本地
7.通过开源框架的源码分析如ButterKnife,EventBus,GreenDao,Ormlite,Dragger2,实现原理是什么?
都是使用注解的形式来获取对象,但是不同于后端J2ee注解。它们不属于运行时注解,而是编译型注解,即他们在App编译时会通过扫描注解生成相关的代码。实际上就是通过注解帮我们自动生成了相关代码,例如ButterKnife我们通过向注解中传入控件id就可以获取到控件的实例,其实是ButterKnife帮我们做了findViewById的工作,这些代码会在编译时生成不会写入到class。而运行时注解则是在软件运行时通过反射拿到注解,这样的耗时操作会影响软件速度如xutils。
(这里是个人理解,不对请您指正 )
8.HashMap底层实现,它和LinkHashMap有什么区别?
hashMap底层是哈希表数据结构,允许存入null键null值,该集合是不同步的,将hashtable替代。
LinkhashMap继承 hashMap,它具有HashMap的特性,但是它底层是双向链表结构,插入移除元素更加的快速,灵活性比HashMap更强。
AsycTask机制,实现原理:
对Handler高度封装,避免了手动开辟子线程,实现异步操作。
下面是简单的AsycTask机制源码分析:
初始化AsyncTask对象时,内部会得到mWorker和mFuture两个对象,mWorker是一个callable对象,它里面主要是对传入的数据进行操作操作(内部会调用doInBackground(),onProgressUpdate()方法)。mFuture对象传入了mWorker,mFuture它是一个Runnable接口,这个对象最终会交给线程池,处理mWorker中数据的相关操作。
执行execute()方法时会调用内部的executeOnExecutor(Excutor exec,Params... params)方法,首先内部会先执行onPreExecute()方法。接着执行exec.execute(mFuture),exec是executeOnExecutor的第一个参数,见名知意它就是传入的线程池变量,它是在Executor类中初始化好的final型变量直接传入executeOnExecutor方法的,这一步就是将mFuture扔给线程池。接下来会执行mFuture(Runnable)中的run方法,run方法中会调用Sync内部类的innerRun()方法,里面会执行callable.call()就是mWorker的call方法,call方法中会调用postResult(doInBackground()),在进入这个方法就会发现它里面就是通过handler将doInBackground()的结果发送到主线程,由InternalHandler接收,若结果为MESSAGE_POST_RESULT执行onPostExecute()并关闭AsyncTask任务。若为MESSAGE_POST_PROGRESS则执行onProgressUpdate()方法,只有在doInBackground()方法中调用publishProgress()方法才会有MESSAGE_POST_PROGRESS这个结果,onProgressUpdate()方法才会接收到数据。
以上分析的是3.0版本以后的源码,和3.0之前区别是:
3.0之前:
只能同时执行5个线程,线程池大小为128,若达到5个线程,开启第6个线程则会进入等待队列,当线程数量超过128个时直接崩溃
3.0之后
默认的线程池,同时只能执行1个线程。但是这个线程池可自定义,就是说自定义可以同时执行n条线程,大小为m。n,m并不是越大越好。比3.0之前固定的线程池更灵活。
弊端:
容易内存泄漏,例如下载一个文件,有进度显示,在下载未下载完毕直接退出Activity的话AsyncTask并不会关闭任务,这样一来就会导致Activity得不到释放。就是它不方便关闭。
9.Handler消息机制,postDelayed会造成线程阻塞吗?对内存有什么影响?
上图:
不管在主线程还是在子线程想要通过handler发送消息必须要有Looper对象,在子线程中可通过Looper.prepare()获取,而在主线程中默认会被创建这个不用操心,为什么请百度Activity的源代码。
在条件都满足的情况下由handler发送消息,经过一系列的函数最终会进入到sendMessageAtTime()这个函数,说白了这个函数就是构建MssageQueue这个消息池,通过时间排序。之后就是我们的Looper对象了,它内部有一个死循环,在死循环内部有一个dispatchMessage()方法(属于handler的方法),这个方法就是根据时间顺序分发MssageQueue中的消息,也就是调用handleMessage()方法。
以上是粗略分析,详情还要看源代码。
10.Debug和Release状态的区别?
链接:Android签名详解(debug和release)
debug签名和release签名的区别:
1)debug签名的应用程序不能在Android Market上架销售,它会强制你使用自己的签名;Debug模式下签名用的证书(默认是Eclipse/ADT和Ant编译)自从它创建之日起,1年后就会失效。
2)debug.keystore在不同的机器上所生成的可能都不一样,就意味着如果你换了机器进行apk版本升级,那么将会出现上面那种程序不能覆盖安装的问题,相当于软件不具备升级功能!
如有问题请多指正,您的指正使我更正确的前行.
相关文章推荐
- 恒大信息化部实习生面试问题小结
- 魅族 安卓开发面试 问题整理(2017.12.13)
- 面试算法小结
- 2017年年末安卓面试
- 前端面试小结
- A8音乐集团面试小结.
- "Activity"-安卓面试必问技能点大总结"
- 索尼日本面试小结
- 【安卓面试】安卓面试经验之谈(十分实用)
- java面试小结
- 实习面试经验小结
- 安卓动画小结
- 阿里安卓面试分析: Android应用的闪退(crash)问题跟踪和解析
- 安卓 动画小结
- 面试小结-那些求职路上的经验分享与感受
- 安卓弹出框控件jjdxm-dialogui之日期选择小结
- 安卓面试必会题
- 数据库笔试和面试小结
- Java 面试题目小结(未完待续)
- java面试小结——MQ