1、图片的三级缓存中,图片加载到内存中,如果内存快爆了,会发生什么?怎么处理?
参考回答:首先我们要清楚图片的三级缓存是如何的:
如果内存足够时不回收。内存不够时就回收软引用对象
2、内存中如果加载一张 500 * 500 的 png 高清图片。应该是占用多少的内存?
3、WebView 的性能优化?
参考回答:一个加载网页的过程中,native、网络、后端处理、CPU 都会参与,各自都有必要的工作和依赖关系;让他们相互并行处理而不是相互阻塞才可以让网页加载更快:
推荐文章:WebView 性能、体验分析与优化(https://tech.meituan.com/2017/06/09/webviewperf.html)
4、Bitmap 如何处理大图,如一张 30M 的大图,如何预防 OOM?
参考回答:避免 OOM 的问题就需要对大图片的加载进行管理,主要通过缩放来减小图片的内存占用。
BitmapFactory 提供的加载图片的四类方法(decodeFile、decodeResource、decodeStream、decodeByteArray)都支持 BitmapFactory.Options 参数,通过 inSampleSize 参数就可以很方便地对一个图片进行采样缩放
比如一张 10241024 的高清图片来说。那么它占有的内存为 102410244,即 4MB,如果 inSampleSize 为 2,那么采样后的图片占用内存只有 512512*4, 即 1MB( 注意:根据最新的官方文档指出,inSampleSize 的取值应该总是为 2 的指数,即 1、2、4、8 等等,如果外界输入不足为 2 的指数,系统也会默认选择最接近 2 的指数代替,比如 2)
综合考虑。通过采样率即可有效加载图片,流程如下:
推荐文章:Android 高效加载大图、多图解决方案,有效避免程序OOM
(https://blog.csdn.net/guolin_blog/article/details/9316683)
5、内存回收机制与 GC 算法 (各种算法的优缺点以及应用场景);GC 原理时机以及 GC 对象?
内存判定对象可回收有两种机制:
引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加 1;当引用失效时,计数器值就减 1;任何时刻计数器为 0 的对象就是不可能再被使用的。然而在主流的 Java 虚拟机里未选用引用计数算法来管理内存,主要原因是它难以解决对象之间相互循环引用的问题,所以出现了另一种对象存活判定算法。
可达性分析法:通过一系列被称为『GCRoots』的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。其中可作为 GC Roots 的对象:虚拟机栈中引用的对象,主要是指栈帧中的本地变量 *、本地方法栈中 Native 方法引用的对象、方法区中 类静态属性引用的对象、方法区中常量引用的对象
GC 回收算法有以下四种:
分代收集算法:是当前商业虚拟机都采用的一种算法,根据对象存活周期的不同,将 Java 堆划分为新生代和老年代,并根据各个年代的特点采用最适当的收集算法。
新生代:大批对象死去,只有少量存活。使用『复制算法』,只需复制少量存活对象即可。
复制算法:把可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用尽后,把还存活着的对象『复制』到另外一块上面,再将这一块内存空间一次清理掉。实现简单,运行高效。在对象存活率较高时就要进行较多的复制操作,效率将会变低
老年代:对象存活率高。使用『标记 — 清理算法』或者『标记 — 整理算法』,只需标记较少的回收对象即可。
标记 - 清除算法:首先『标记』出所有需要回收的对象,然后统一『清除』所有被标记的对象。标记和清除两个过程的效率都不高,清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。 标记 - 整理算法:首先『标记』出所有需要回收的对象,然后进行『整理』,使得存活的对象都向一端移动,最后直接清理掉端边界以外的内存。标记整理算法会将所有的存活对象移动到一端,并对不存活对象进行处理,因此其不会产生内存碎片
推荐文章:图解 Java 垃圾回收机制(https://blog.csdn.net/justloveyou_/article/details/71216049)
6、内存泄露和内存溢出的区别 ?AS 有什么工具可以检测内存泄露
7、性能优化,怎么保证应用启动不卡顿?黑白屏怎么处理?
应用启动速度:取决于你在 application 里面时候做了什么事情,比如你集成了很多 sdk,并且 sdk 的 init 操作都需要在主线程里实现所以会有卡顿的感觉。在非必要的情况下可以把加载延后或则开启子线程处理
另外,影响界面卡顿的两大因素,分别是界面绘制和数据处理:
推荐文章:Android 性能优化之内存检测、卡顿优化、耗电优化、APK 瘦身
(https://blog.csdn.net/csdn_aiyang/article/details/74989318)
黑白屏产生原因:当我们在启动一个应用时,系统会去检查是否已经存在这样一个进程,如果不存在,系统的服务会先检查 startActivity 中的 intent 的信息,然后在去创建进程,最后启动 Acitivy,即冷启动。而启动出现白黑屏的问题,就是在这段时间内产生的。系统在绘制页面加载布局之前,首先会初始化窗口(Window),而在进行这一步操作时,系统会根据我们设置的 Theme 来指定它的 Theme 主题颜色,我们在 Style 中的设置就决定了显示的是白屏还是黑屏。
推荐文章:Android 启动页解决攻略
(https://blog.csdn.net/zivensonice/article/details/51691136)
8、强引用置为 null,会不会被回收?
参考回答:不会立即释放对象占用的内存。如果对象的引用被置为 null,只是断开了当前线程栈帧中对该对象的引用关系,而 垃圾收集器是运行在后台的线程,只有当用户线程运行到安全点 (safe point) 或者安全区域才会扫描对象引用关系,扫描到对象没有被引用则会标记对象,这时候仍然不会立即释放该对象内存,因为有些对象是可恢复的(在 finalize 方法中恢复引用 )。只有确定了对象无法恢复引用的时候才会清除对象内存。
9、ListView 跟 RecyclerView 的区别:
动画区别:
刷新区别:
缓存区别:
推荐文章:
10、ListView 的 adapter 是什么 adapter?
11、LinearLayout、FrameLayout、RelativeLayout 性能对比,为什么?
1、对 JNI 是否了解?
参考回答:Java 的优点是跨平台,但也因为其跨平台的的特性导致其本地交互的能力不够强大,一些和操作系统相关的的特性 Java 无法完成,于是 Java 提供 JNI 专门用于和本地代码交互,通过 JNI,用户可以调用 C、C++ 编写的本地代码
NDK 是 Android 所提供的一个工具集合,通过 NDK 可以在 Android 中更加方便地通过 JNI 访问本地代码,其优点在于:
2、如何加载 NDK 库 ?如何在 JNI 中注册 Native 函数,有几种注册方法 ?
public class JniTest{
//加载NDK库
static{
System.loadLirary("jni-test");
}
}
注册 JNI 函数的两种方法:
推荐文章:
3、你用 JNI 来实现过什么功能 ?怎么实现的 ?(加密处理、影音方面、图形图像处理)
参考回答:推荐文章:Android JNI 篇 - ffmpeg 获取音视频缩略图(https://www.jianshu.com/p/411761bd5f5b)
1、你所知道的设计模式有哪些?
2、谈谈 MVC、MVP 和 MVVM,好在哪里,不好在哪里 ?
MVC:
总结:具有一定的分层,model 彻底解耦,controller 和 view 并没有解耦层与层之间的交互尽量使用回调或者去使用消息机制去完成,尽量避免直接持有 controller 和 view 在 android 中无法做到彻底分离,但在代码逻辑层面一定要分清业务逻辑被放置在 model 层,能够更好的复用和修改增加业务。
MVP:通过引入接口 BaseView,让相应的视图组件如 Activity,Fragment 去实现 BaseView,实现了视图层的独立,通过中间层 Preseter 实现了 Model 和 View 的完全解耦。MVP 彻底解决了 MVC 中 View 和 Controller 傻傻分不清楚的问题,但是随着业务逻辑的增加,一个页面可能会非常复杂,UI 的改变是非常多,会有非常多的 case,这样就会造成 View 的接口会很庞大。
MVVM:MVP 中我们说过随着业务逻辑的增加,UI 的改变多的情况下,会有非常多的跟 UI 相关的 case,这样就会造成 View 的接口会很庞大。而 MVVM 就解决了这个问题,通过双向绑定的机制,实现数据和 UI 内容,只要想改其中一方,另一方都能够及时更新的一种设计理念,这样就省去了很多在 View 层中写很多 case 的情况,只需要改变数据就行。
三者如何选择?
推荐文章:MVC、MVP、MVVM,我到底该怎么选?(https://juejin.im/post/5b3a3a44f265da630e27a7e6)
3、封装 p 层之后。如果 p 层数据过大,如何解决?
参考回答:对于 MVP 模式来说,P 层如果数据逻辑过于臃肿,建议引入 RxJava 或则 Dagger,越是复杂的逻辑,越能体现 RxJava 的优越性。
推荐文章:RxJava+OkHttp+Retrofit+Dagger2+MVP 框架 (kotlin 版本)(https://juejin.im/post/5c6e601cf265da2dc675b69e#comment)
4、是否能从 Android 中举几个例子说说用到了什么设计模式 ?
5、装饰模式和代理模式有哪些区别 ?
参考回答:装饰器模式与代理模式的区别就在于:
6、实现单例模式有几种方法 ?懒汉式中双层锁的目的是什么 ?两次判空的目的又是什么 ?
参考回答:单例模式实现方法有多种:饿汉,懒汉 (线程安全,线程非安全),双重检查 (DCL), 内部类,以及枚举。
所谓双层检验锁(在加锁前后对实例对象进行两次判空的检验):加锁是为了第一次对象实例化的线程同步,而锁内还要有第二层判空是因为可能会有多个线程进入第一层 if 判断内部,而在加锁代码块外排队等候,如果锁内不进行第二次检验,仍然会出现实例化多个对象的情况。
推荐文章:单例模式的总结(https://xxxblank.github.io/2017/09/14/singleTon/)
7、用到的一些开源框架,介绍一个看过源码的,内部实现过程。
参考回答:面试常客:Okhttp,Retrofit,Glide,RxJava,GreenDao,Dagger 等。
【Android进阶学习视频】、【全套Android面试秘籍】关注我【主页简介】查看免费领取方式
推荐文章:
Android OkHttp 源码解析入门教程(一)(https://juejin.im/post/5c46822c6fb9a049ea394510)
Android OkHttp 源码解析入门教程(二)(https://juejin.im/post/5c4682d2f265da6130752a1d)
8、Fragment 如果在 Adapter 中使用应该如何解耦?
参考回答:接口回调和广播
今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。