ART是安装的时候就编译好了,执行的时候直接就可以运行的,安装慢,开启应用快,占用空间大
用个比喻来说就是,骑自行车
dalvik 是已经折叠起来的自行车,每次骑都要先组装自行车才能骑
ART 是已经组装好的自行车,每次骑直接上车就能走人
详情:http://www.jb51.net/article/88708.htm
虚拟机原理,如何自己设计一个虚拟机(内存管理,类加载,双亲委派):
在加载阶段,java虚拟机需要完成以下3件事:
a.通过一个类的全限定名来获取定义此类的二进制字节流。
b.将定义类的二进制字节流所代表的静态存储结构转换为方法区的运行时数据结构。
c.在java堆中生成一个代表该类的java.lang.Class对象,作为方法区数据的访问入口。
类加载:
从类被加载到虚拟机内存中开始,到卸载出内存为止,类的生命周期包括加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段
双亲委派:
系统提供的类加载器主要有下面3个:
.启动类加载器(Bootstarp ClassLoader)
.扩展类加载器(Extension ClassLoader)
.应用程序类加载器(Application ClassLoader)
注意:上述三个JDK提供的类加载器虽然是父子类加载器关系,但是没有使用继承,而是使用了组合关系。
详情:http://blog.csdn.net/ochangwen/article/details/51473120
http://blog.csdn.net/ochangwen/article/details/51472311
JVM内存模型及类加载机制:
JVM要想执行class文件,首先会将文件载入虚拟机的方法区内,根据类文件的格式相应的存放数据。在需要产生对象时,从方法区中获取对应的类信息,在堆中建立对象。
详情:http://blog.csdn.net/dragon_cat_han/article/details/52150955
内存对象的循环引用及避免:
如果有两个或者以上的对象,它们彼此引用,就会造成循环引用。
避免:引用计数GC处理,引用遍历GC处理。
详情:http://www.wtoutiao.com/p/11elsk6.html
######3.内存回收机制与GC算法(各种算法的优缺点以及应用场景);GC原理时机以及GC对象;内存泄露场景及解决方法;OOM的避免及解决方法
内存回收机制与GC算法(各种算法的优缺点以及应用场景):
GC是通过对象是否存活来决定是否进行回收,最常用的判定算法是引用计数算法以及Java中使用的判定算法为根搜索算法(GC Roots Tracing)
常用的垃圾收集算法
a、标记——清除算法(Mark——Sweep)
首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。
缺点:效率问题,标记和清除过程的效率不高;
b、复制算法(Copying)
为了解决标记清除算法的效率问题,复制算法将可用的内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活的对象复制到另一块上,然后再把已使用过的内存空间一次清理掉。
优点:实现简单,运行高效
缺点:对内存空间的利用不高,可用内存变成一半,这代价过高
c、标记——整理算法(Mark——Compact)
与标记清除算法的标记阶段相同,但标记后会将所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。这种算法一般用于老年代的内存回收上,因为老年代中对象的存活时间都比较长,可能存在100%存活的极端情况,因此不能选择Copying算法来进行回收。
d、分代收集算法(Generational Collection)
这种算法只是根据对象的存活周期的不同将内存划分为几块,一般都划分为新生代和老年代,这样可以根据各个年代的特点采用最适当的收集算法。新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,因此选取复制算法,只需要付出少量存活对象的复制成本就可以完成收集;老年代中因为对象存活率高,没有额外的空间对它进行分配担保,就必须使用“标记——清除”或是“标记——整理”算法来进行回收。在之前的三种算法中已经有所描述。
详情:http://www.open-open.com/lib/view/open1380593930103.html
GC原理时机以及GC对象:
JVM 分别对新生代和旧生代采用不同的垃圾回收机制
Java中那些不可达的对象就会变成垃圾。那么什么叫做不可达?其实就是没有办法再引用到该对象了。主要有以下情况使对象变为垃圾:
1.对非线程的对象来说,所有的活动线程都不能访问该对象,那么该对象就会变为垃圾。
2.对线程对象来说,满足上面的条件,且线程未启动或者已停止。
GC将负责回收所有“不可达”对象的内存空间。
详情:https://segmentfault.com/a/1190000002579346
内存泄露场景及解决方法:
因为静态变量造成的内存泄漏;
Handler 的错误使用;
非静态内部类的静态实例的错误使用;
不正确使用线程,造成内存泄漏;
资源没有及时关闭;
详情例子解决方案参见:http://blog.csdn.net/adrian24/article/details/53248255
或者http://www.jianshu.com/p/51072faadf51
OOM的避免及解决方法:
高效加载大图片:
在展示高分辨率图片的时候,最好先将图片进行压缩。压缩后的图片大小应该和用来展示它的控件大小相近,在一个很小的ImageView上显示一张超大的图片不会带来任何视觉上的好处,但却会占用我们相当多宝贵的内存,而且在性能上还可能会带来负面影响。下面我们就来看一看,如何对一张大图片进行适当的压缩,让它能够以最佳大小显示的同时,还能防止OOM的出现。
使用图片缓存技术:
内存缓存技术对那些大量占用应用程序宝贵内存的图片提供了快速访问的方法。其中最核心的类是LruCache (此类在android-support-v4的包中提供) 。这个类非常适合用来缓存图片,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。
详情:http://blog.csdn.net/guolin_blog/article/details/9316683
######4.四大组件及生命周期;ContentProvider的权限管理(读写分离,权限控制-精确到表级,URL控制);Activity的四种启动模式对比;Activity状态保存于恢复
都是一些基础知识,详情归类下:
Activity:详细知识:http://blog.csdn.net/amazing7/article/details/51244219
Service:详细知识:http://blog.csdn.net/amazing7/article/details/51305911
ContentProvider:详细知识:http://blog.csdn.net/amazing7/article/details/51324022
BroadcastReceiver:详细知识:http://blog.csdn.net/amazing7/article/details/51352139
ContentProvider的权限管理:http://blog.csdn.net/robertcpp/article/details/51337891
Activity的四种启动模式对比:http://blog.csdn.net/knlnzhao/article/details/8005277
Activity状态保存于恢复:http://blog.csdn.net/js331455217/article/details/40930157
######5.Fragment生命周期;Fragment状态保存
生命周期及相关:http://blog.csdn.net/amazing7/article/details/51282082
状态保存:http://www.jianshu.com/p/75dc2f51cd63
######6.startActivityForResult是哪个类的方法,在什么情况下使用,如果在Adapter中使用应该如何解耦
startActivityForResult是Activity类里的方法,在原Activity里通过Intent跳转到其他类再跳回到原Activity里时候,回传数据所用
详情:http://blog.csdn.net/sunchaoenter/article/details/6612039
在Adapter以及其他非Activity类使用的时候,可以将由原Activity类传入的Context强转为Activity类,再在原Activity里重写onActivityResult方法接受到返回值。
######7.AsyncTask原理及不足;IntentService原理
AsyncTask是一个轻量级的异步类,继承时候有三个泛型参数:
-
Params,在执行AsyncTask时需要传入的参数,可用于在后台任务中使用;
-
Progress,后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位;
-
Result,当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
需要重写四个方法(至少是2个,2和4):
-
onPreExecute(),这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。
-
doInBackground(Params…),这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果进行返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress…)方法来完成。
-
onProgressUpdate(Progress…),当在后台任务中调用了publishProgress(Progress…)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应的更新。
-
onPostExecute(Result),当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如说提醒任务执行的结果,以及关闭掉进度条对话框等。
AnsycTask执行任务时,内部会创建一个进程作用域的线程池来管理要运行的任务,也就就是说当你调用了AsyncTask.execute()后,AsyncTask会把任务交给线程池,由线程池来管理创建Thread和运行Therad,本质上是对Thread+Handler的良好封装,减少了开发者处理问题的复杂度,提高了开发效率。
AsyncTask缺陷:
最大的缺点:在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来。
其他的参考下面的文章。
详情:http://blog.csdn.net/liuhe688/article/details/6532519
http://blog.csdn.net/boyupeng/article/details/49001215
分享读者
作者2013年java转到Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。
被人面试过,也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!
我们整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。
主要包括腾讯,以及字节跳动,阿里,华为,小米,等一线互联网公司主流架构技术。如果你有需要,尽管拿走好了。
如果你觉得自己学习效率低,缺乏正确的指导,可以点击加入资源丰富,学习氛围浓厚的技术圈一起学习交流吧!
群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。
%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)!**
群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。