热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

2019年Android岗位BAT等大厂面试题知识点小结,2021年Android开发学习路线

内存回收机制与GC算法(各种算法的优缺点以及应用场景):GC是通过对象是否存活来决定是否进行回收,最常用的判定算法是引用计数算法以及Java中使用的判定算法为根搜索算法(GCRo

内存回收机制与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是一个轻量级的异步类,继承时候有三个泛型参数:


  1. Params,在执行AsyncTask时需要传入的参数,可用于在后台任务中使用;

  2. Progress,后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位;

  3. Result,当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。

需要重写四个方法(至少是2个,2和4):


  1. onPreExecute(),这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。

  2. doInBackground(Params…),这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果进行返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress…)方法来完成。

  3. onProgressUpdate(Progress…),当在后台任务中调用了publishProgress(Progress…)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应的更新。

  4. 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

IntentService原理

IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。

详情:http://blog.csdn.net/qq_18402085/article/details/50753005

http://blog.csdn.net/ryantang03/article/details/8146154/

######8.AstncTask+HttpClient与AsyncHttpClient有什么区别

AsyncHttpClient来自android-async-http库是在Apache的HttpClient库的基础上开发构建而成的,这里的异步,是指它所有的网络请求都是在app的UI线程之外的独立工作线程中执行。而开发者通过利用Android的消息处理机制,把我们所需要编写的回调函数放在这个回调函数的创建线程中执行(一般就是UI线程),所以使用起来非常方便除了能应用在开发普通App上,还可以用来开发Service或后台线程,async-http-client库可以自已分辨是被用在哪一种应用下,不需要额外的设置。

详情:https://my.oschina.net/u/725054/blog/494494

http://blog.csdn.net/wangpeng047/article/details/19624529

######9.如何保证一个后台服务不被杀死;比较省电的方式是什么

服务不被杀死分3种来讨论

1.系统根据资源分配情况杀死服务

2.用户通过 settings -> Apps -> Running -> Stop 方式杀死服务

3.用户通过 settings -> Apps -> Downloaded -> Force Stop 方式杀死服务

第一种情况:

用户不干预,完全靠系统来控制,办法有很多。比如 onStartCommand() 方法的返回值设为 START_STICKY ,服务就会在资源紧张的时候被杀掉,然后在资源足够的时候再恢复。当然也可设置为前台服务,使其有高的优先级,在资源紧张的时候也不会被杀掉。

第二种情况:

用户干预,主动杀掉运行中的服务。这个过程杀死服务会通过服务的生命周期,也就是会调用 onDestory() 方法,这时候一个方案就是在 onDestory() 中发送广播开启自己。这样杀死服务后会立即启动。

当然,从理论上来讲这个方案是可行的,实验一下也可以。但有些情况下,发送的广播在消息队列中排的靠后,就有可能服务还没接收到广播就销毁了(这是我对实验结果的猜想,具体执行步骤暂时还不了解)。所以为了能让这个机制完美运行,可以开启两个服务,相互监听,相互启动。服务A监听B的广播来启动B,服务B监听A的广播来启动A。经过实验,这个方案可行,并且用360杀掉后几秒后服务也还是能自启的。到这里再说一句,如果不是某些功能需要的服务,不建议这么做,会降低用户体验。

第三种情况:

强制关闭就没有办法。这个好像是从包的level去关的,并不走完整的生命周期。所以在服务里加代码是无法被调用的。处理这个情况的唯一方法是屏蔽掉 force stop和 uninstall 按钮,让其不可用。方法自己去找吧。当然有些手机自带的清理功能就是从这个地方清理的,比如华为的清理。所以第三种情况我也没有什么更好的办法了。

详情:http://www.tuicool.com/articles/iu22QnF

######10.如何通过广播拦截和abort一条短信;广播是否可以请求网络;广播引起anr的时间限制

目前找到方法都是适用于Android4.4默认短信应用以前的方法:

第一步:新建一个类继承BroadcastReceiver,并重写onReceive()方法.

第二步:订阅短信的广播Intent,订阅方法有两种:

1:使用代码进行订阅

2:在AndroidManifest.xml文件中的节点中进行订阅

在Android中,每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法,

onReceive() 方法执行完后,BroadcastReceiver 的实例就会被销毁。拦截短信的方法就写在onReceive() 方法里即可。

详情:http://blog.csdn.net/jason0539/article/details/11720419


最后:学习总结——Android框架体系架构知识脑图(纯手绘xmind文档)

学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。

下方即为我手绘的Android框架体系架构知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的Android框架体系架构知识脑图原件(包括上方的面试解析xmind文档)

除此之外,前文所提及的Alibaba珍藏版 Android框架体系架构 手写文档以及一本 《大话数据结构》 书籍等等相关的学习笔记文档,也皆可分享给认可的朋友!

——感谢大家伙的认可支持,Free Download请注意:点赞+点赞+点赞!!!
节方面不是特别清晰。但可给感兴趣的朋友提供完整的Android框架体系架构知识脑图原件(包括上方的面试解析xmind文档)
[外链图片转存中…(img-cPyXDdGA-1643772218773)]

除此之外,前文所提及的Alibaba珍藏版 Android框架体系架构 手写文档以及一本 《大话数据结构》 书籍等等相关的学习笔记文档,也皆可分享给认可的朋友!

——感谢大家伙的认可支持,Free Download请注意:点赞+点赞+点赞!!!
自行下载领取链接:【Git】


推荐阅读
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
author-avatar
金豪情圣
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有