前言
续上2020上半年百度Android岗(初级到高级)面试真题全收录+解析,备战金九银十!(上篇)
本文是百度2020上半年网友分享以及我个人收录的面试真题大全。并且花了大量时间为大家寻找到了最佳的答案解析。希望可以收到资助到大家。喜好的朋友可以点个赞支持一下,谢谢。
BATJ大厂面试真题收录大全PDF电子书已上传在石墨文档:【BATJ面试大全】需要的小同伴自取就好了。别忘了给文章点个赞~
Android基础篇
1.Application
1.1、OnLowMemory 和 OnTrimMemory 的区别比力?
1、OnLowMemory 被回调时,已经没有配景历程;而 onTrimMemory 被回调时,另有配景
历程。
2、OnLowMemory 是在最后一个配景历程被杀时调用,一样寻常情况是 low memory killer 杀历程后触发;而 OnTrimMemory 的触发更频仍,每次盘算历程优先级时,只要满足条件,都会触发。
3、通过一键清算后,OnLowMemory 不会被触发,而 OnTrimMemory 会被触发一次。OnTrimMemory 的参数是一个 int 数值,代表不同的内存状态:
TRIM_MEMORY_COMPLETE:内存不足,并且该历程在配景历程列表最后一个,马上就要被
清算TRIM_MEMORY_MODERATE:内存不足,并且该历程在配景历程列表的中部。
TRIM_MEMORY_BACKGROUND:内存不足,并且该历程是配景历程。
TRIM_MEMORY_UI_HIDDEN:内存不足,并且该历程的 UI 已经不可见了。
1.2、Application 的生命周期
相比 Activity ,Application 的生命周期简直不要太简单。起首创建的时候会调用构造函数,然后系统准备好 ContextImpl 通过 attachBaseContext( Context ) 方法注入到 Application,接着调用我们最熟悉的 onCreate 方法。API 里另有一个 onTerminate 方法在历程被杀死的时候会回调,不过仅在模拟器生效,就不需要关注了。
1.3、说一下 Application 的初始化流程
Application 的初始化是在应用历程创建完成后:
ActivityThread 调用 AMS 的 Binder 对象( IActivityManager )的 attachApplication 方法
AMS 收到哀求后再去调用 ActivityThread 的 bindApplication 方法
ActivityThread 这边收到哀求再组装一个 AppBindData 对象,把所有参数封装进去,再通过 handler 发到主线程执行
主线程 loop 到这条消息,调用 handleBindApplication 来真正处置惩罚初始化 Application
handleBindApplication 和我们谈 “Context” 那次,Activity 的初始化差不多。回顾一下:
ClassLoader 加载 Application 类,实例化
初始化 Applicaction 用的 ContextImpl
通过 Application.attach( Context ) 方法,调用 attachBaseContext( Context ) 将 ContextImpl 注入到 Application
最后调用 Application.OnCreate()
如许 Application 就初始化完成了
2.Context
2.1、Context理解
1、Activity和Service以及Application的Context是不一样的,Activity继承自ContextThemeWraper.其他的继承自ContextWrapper。
2、每一个Activity和Service以及Application的Context是一个新的ContextImpl对象。
3、getApplication()用来获取Application实例的,但是这个方法只有在Activity和Service中才能调用的到。那也许在绝大多数情况下我们都是在Activity或者Servic中使用Application的,但是假如在一些其它的场景,比如BroadcastReceiver中也想得到Application的实例,这时就可以借助getApplicationContext()方法,getApplicationContext()比getApplication()方法的作用域会更广一些,任何一个Context的实例,只要调用getApplicationContext()方法都可以拿到我们的Application对象。
4、创建对话框时不可以用Application的context,只能用Activity的context。
5、Context的数目等于Activity的个数 + Service的个数 +1,这个1为Application。
2.2、ApplicationContext和ActivityContext的区别
这是两种不同的context,也是最常见的两种.第一种中context的生命周期与Application的生命周期相关的,context随着Application的销毁而销毁,陪同application的一生,与activity的生命周期无关.第二种中的context跟Activity的生命周期是相关的,但是对一个Application来说,Activity可以销毁几次,那么属于Activity的context就会销毁多次.至于用哪种context,得看应用场景。另有就是,在使用context的时候,小心内存泄漏,防止内存泄漏,留意一下几个方面:
- 不要让生命周期长的对象引用activity context,即包管引用activity的对象要与activity本身生命周期是一样的。
- 对于生命周期长的对象,可以使用application context。
- 制止非静态的内部类,尽量使用静态类,制止生命周期问题,留意内部类对外部对象引用导致的生命周期变化。
3.Activity
3.1、Activity和Fragment生命周期有哪些?
3.2、横竖屏切换时候Activity的生命周期
1)、Android 3.2 (API 13) 之前:
- 不设置 Activity 的 android:configChanges 时,切屏会重新调用生命周期,切横屏会调用一次,切竖屏>会调用两次。
- 设置 Activity 的 android:configChanges=“orientation” 时,切屏会重新调用生命周期,且横竖屏都是调>用一次生命周期。
- 设置 Activity 的 android:configChanges=“orientation|keyboardHidden” 时,切屏不会重新调用 Activity >的生命周期,但是会调用 onConfigurationChanges() 方法。
2)、从Android 3.2 (API 13) 开始
- 不设置 Activity 的 android:configChanges 时、设置 Activity 的 android:configChanges=“orientation”
- 设置 Activity 的 android:configChanges="orientaion|keyboardHidden"时切换横屏和竖屏都会重新调用>一次生命周期。
*设置 Activity 的 android:configChanges="orientation|screenSize"时不会重新调用 Activity 的生命周期,>但是会调用 onConfigurationChanges() 方法。
3.3、activity的startActivity和context的startActivity区别?
(1)、从Activity中启动新的Activity时可以直接mContext.startActivity(intent)就好
(2)、假如从其他Context中启动Activity则必须给intent设置Flag:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) ;
mContext.startActivity(intent);
3.4、怎么加速启动Activity?
1、onCreate() 中不执行耗时操纵 把页面显示的 View 细分一下,放在 AsyncTask 里逐步显示,用 Handler 更好。如许用户的看到的就是有层次有步调的一个个的 View 的展示,不会是先看到一个黑屏,然后一下显示所有 View。最好做成动画,效果更自然。
2、使用多线程的目的就是尽大概的减少 onCreate() 和 onReume() 的时间,使得用户能尽快看到页面,操纵页面。
3、减少主线程壅闭时间。
4、提高 Adapter 和 AdapterView 的效率。
5、优化结构文件。
3.5、直接在Activity中创建一个thread跟在service中创建一个thread之间的区别?
- 在Activity中被创建:该Thread的就是为这个Activity服务的,完成这个特定的Activity交接的任务,主动关照该Activity一些消息和事件,Activity销毁后,该Thread也没有存活的意义了。
- 在Service中被创建:这是包管最长生命周期的Thread的唯一方式,只要整个Service不退出,Thread就可以一直在配景执行,一样寻常在Service的onCreate()中创建,在onDestroy()中销毁。所以,在Service中创建的Thread,得当恒久执行一些独立于APP的配景任务,比力常见的就是:在Service中保持与服务器端的长连接。
3.6、Activity 与 Service 通讯的四种方式
1、Binder
2、Intent
3、接口 Interface
4、Broadcast 广播接收
3.7、Activity 之间的几种通讯方式
1、Intent
2、借助类的静态变量
3、借助全局变量/Application
4、借助外部工具
5、 借助 SharedPreference
6、使用 Android 数据库 SQLite
7、 赤裸裸的使用 File
8、Android 剪切板
9、借助 Service
4.Service
4.1、服务启动一样寻常有几种,服务和activty之间怎么通讯,服务和服务之间怎么通讯
方式:
1、startService:
onCreate()—>onStartCommand() —> onDestory()
假如服务已经开启,不会重复的执行onCreate(), 而是会调用onStartCommand()。一旦服务开启跟调用者(开启者)就没有任何关系了。 开启者退出了,开启者挂了,服务还在配景恒久的运行。 开启者不能调用服务内里的方法。
2、bindService:
onCreate() —>onBind()—>onunbind()—>onDestory()
bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。 绑定者可以调用服务内里的方法。
通讯:
1、通过Binder对象。
2、通过broadcast(广播)。
4.2、如何包管Service不被杀死?
Android 历程不死从3个层面入手:
A.提供历程优先级,降低历程被杀死的概率
方法一:监控手机锁屏解锁事件,在屏幕锁屏时启动1个像素的 Activity,在用户解锁时将 Activity 销毁掉。
方法二:启动前台service。
方法三:提升service优先级:
在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,假如数字越小则优先级越低,同时适用于广播。
B. 在历程被杀死后,进行拉活
方法一:注册高频率广播接收器,唤起历程。如网络变化,解锁屏幕,开机等
方法二:双历程相互唤起。
方法三:依赖系统唤起。
方法四:onDestroy方法里重启service:service + broadcast 方式,就是当service走ondestory的时候,发送一个自界说的广播,当收到广播的时候,重新启动service;
C. 依赖第三方
根据终端不同,在小米手机(包括 MIUI)接入小米推送、华为手机接入华为推送;其他手机可以思量接入腾讯信鸽或极光推送与小米推送做 A/B Test。
5.BroadcastReceiver
5.1、广播注册一样寻常有几种,各有什么优缺点?
第一种是常驻型(静态注册):当应用程序关闭后假如有信息广播来,程序也会被系统调用,本身运行。
第二种不常驻(动态注册):广播会跟随程序的生命周期。
动态注册
优点: 在android的广播机制中,动态注册优先级高于静态注册优先级,因此在必要情况下,是需要动态注册广播接收者的。
缺点: 当用来注册的 Activity 关掉后,广播也就失效了。
静态注册
优点: 无需担忧广播接收器是否被关闭,只要装备是开启状态,广播接收器就是打开着的。
6.Fragmengt
6.1、activty和Fragmengt之间怎么通讯,Fragmengt和Fragmengt怎么通讯?
(一)Handler
(二)广播
(三)事件总线:EventBus、RxBus、Otto
(四)接口回调
(五)Bundle和setArguments(bundle)
7.View
7.1、自界说view效率高于xml界说吗?阐明来由。
自界说view效率高于xml界说:
1、少了解析xml。
2.、自界说View 减少了ViewGroup与View之间的测量,包括父量子,子量自身,子在父中位置摆放,当子view变化时,父的某些属性都会跟着变化。
7.2、ListView卡顿原因
Adapter的getView方法内里convertView没有使用setTag和getTag方式;
在getView方法内里ViewHolder初始化后的赋值或者是多个控件的显示状态和配景的显示没有优化好,抑或是内里含有复杂的盘算和耗时操纵;
在getView方法内里 inflate的row 嵌套太深(结构过于复杂)或者是结构内里有大图片或者配景所致;
Adapter多余或者不公道的notifySetDataChanged;
listview 被多层嵌套,多次的onMessure导致卡顿,假如多层嵌套无法制止,建议把listview的高和宽设置为match_parent. 假如是代码继承的listview,那么也请你别忘记为你的继承类添加上LayoutPrams,留意高和宽都mactch_parent的;
7.3、LinearLayout、FrameLayout、RelativeLayout性能对比,为什么?
RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子 View 2次onMeasure
RelativeLayout的子View假如高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。假如可以,尽量使用padding代替margin。
在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout。
中场苏息
8.数据传输与序列化
8.1Bunder通报对象为什么需要序列化?Serialzable和Parcelable的区别?
因为bundle通报数据时只支持根本数据类型,所以在通报对象时需要序列化转换成可存储或可传输的本质状态(字节流)。序列化后的对象可以在网络、IPC(比如启动另一个历程的Activity、Service和Reciver)之间进行传输,也可以存储到本地。
Serializable(Java自带):
Serializable 是序列化的意思,表示将一个对象转换成存储或可传输的状态。序列化后的对象可以在网络上进传输,也可以存储到本地。
Parcelable(android专用):
除了Serializable之外,使用Parcelable也可以实现相同的效果,不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完备的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这也就实现通报对象的功能了。
8.2、android中有哪几种解析xml的类,官方保举哪种?以及它们的原理和区别?
DOM解析
优点:
1.XML树在内存中完备存储,因此可以直接修改其数据结构.
2.可以通过该解析器随时访问XML树中的任何一个节点.
3.DOM解析器的API在使用上也相对比力简单.
缺点:
假如XML文档体积比力大时,将文档读入内存是非斲丧系统资源的.
使用场景:
- DOM 是与平台和语言无关的方式表示 XML文档的官方 W3C 标准.
- DOM 是以层次结构组织的节点的集合.这个层次结构答应开人员在树中寻找特定信息.分析该结构通常需要加载整个文档和构造层次结构,然后才能进行任何工作.
- DOM 是基于对象层次结构的.
SAX解析
优点:
SAX 对内存的要求比力低,因为它让开发人员本身来决定所要处置惩罚的标签.特殊是当开发人员只需要处置惩罚文档中包罗的部分数据时,SAX 这种扩展能力得到了更好的表现.
缺点:
用SAX方式进行XML解析时,需要顺序执行,所以很难访问同一文档中的不同数据.此外,在基于该方式的解析编码程序也相对复杂.
使用场景:
对于含有数据量十分巨大,而又不消对文档的所有数据行遍历或者分析的时候,使用该方法十分有效.该方法不将整个文档读入内存,而只需读取到程序所需的文档标志处即可.
Xmlpull解析
android SDK提供了xmlpullapi,xmlpull和sax类似,是基于流(stream)操纵文件,后者根据节点事件回调开发者编写的处置惩罚程序.因为是基于流的处置惩罚,因此xmlpull和sax都比力节省内存资源,不会像dom那样要把所有节点以对象树的情势展如今内存中.xmpull比sax更简明,而且不需要扫描完备个流.
9.Android历程
9.1、android中历程的优先级?
1.前台历程:
即与用户正在交互的Activity或者Activity用到的Service等,假如系统内存不足时前台历程是最晚被杀死的
2.可见历程:
可以是处于暂停状态(onPause)的Activity或者绑定在其上的Service,即被用户可见,但由于失了焦点而不能与用户交互
3.服务历程:
其中运行着使用startService方法启动的Service,固然不被用户可见,但是却是用户关心的,例如用户正在非音乐界面听的音乐或者正在非下载页面下载的文件等;当系统要空间运行,前两者历程才会被终止
4.配景历程:
其中运行着执行onStop方法而停止的程序,但是却不是用户当前关心的,例如配景挂着的QQ,这时的历程系统一旦没了有内存就起首被杀死
5.空历程:
不包罗任何应用程序的历程,如许的历程系统是一样寻常不会让他存在的
9.2、Android中跨历程通讯的几种方式
1:访问其他应用程序的Activity 如调用系统通话应用
2:Content Provider 如访问系统相册
3:广播(Broadcast) 如显示系统时间
4:AIDL服务
9.3、为什么要用多历程?有哪些方式?怎么使用多历程
我们都知道,android 平台对应用都有内存限制,其实这个理解有点问题,应该是说 android
平台对每个历程有内存限制,比如某机型对对历程限制是 24m,假如应用有两个历程,则该
应该的总内存限制是 2*24m。使用多历程就可以使得我们一个 apk 所使用的内存限制加大
几倍。所以可以借此图片平台对应用的内存限制,比如一些要对图片、视频、大文件历程处置惩罚的好
内存的应用可以思量用多历程来解决应用操纵不流通问题。
开启多历程模式: 在 Android 中 使 用多 历程 只 有 一 种方 法,那 就是 在 AndroidManifest 中 给 四 大 组件(Activity,Service,Receiver,ContentProvider)指定 android:process 属性.除此之外没有其他的办法,也就是说我们无法给一个线程活一个实体类指定其运行时所在的历程.其实另有另一种非常规的多历程方法,那就是通过 JNI 在 native 层去 fork 一个新的历程,但这种方法属于特殊情况,并不是常用的创建多历程的方式,所以我们也暂不思量这种情况历程名以":“开头的历程属于当前应用的私有历程,其他应用的组件不可以和它跑在同一个历程中,而历程名不以”:"开头的历程属于全局历程,其他应用通过 ShareUID 方式可以和它跑在同一个历程中.用多历程的好处与坏处
好处
1)分担主历程的内存压力。
当应用越做越大,内存越来越多,将一些独立的组件放到不同的历程,它就不占用主历程的
内存空间了。当然另有其他好处,有心人会发现
2)使应用常驻配景,防止主历程被杀守护历程,守护历程和主历程之间相互监视,有一方
被杀就重新启动它。Android 配景历程里有很多应用是多个历程的,因为它们要常驻配景,特殊是即时通讯或者社交应用,不过如今多历程已经被用烂了。
典型用法是在启动一个不可见的轻量级私有历程,在配景收发消息,或者做一些耗时的事变,
或者开机启动这个历程,然后做监听等。
坏处:斲丧用户的电量。
多占用了系统的空间,若所有应用都如许占用,系统内存很轻易占满而导致卡顿。
应用程序架构会变得复杂,因为要处置惩罚多历程之间的通讯。这里又是另外一个问题了。
多历程的缺陷历程间的内存空间是不可见的。开启多历程后,会引发以下问题:
1)Application 的多次重修。
2)静态成员的失效。
3)文件共享问题。
4)断点调试问题。
10.Android各版本新特性
10.1、Android5.0新特性
1.MaterialDesign设计风格
2.支持64位ART假造机(5.0推出的ART假造机,在5.0之前都是Dalvik。他们的区别是:
Dalvik,每次运行,字节码都需要通过即时编译器转换成机器码(JIT)。
ART,第一次安装应用的时候,字节码就会预先编译成机器码(AOT))
3.关照详情可以用户本身设计
10.2、Android6.0新特性
1.动态权限管理
2.支持快速充电的切换
3.支持文件夹拖拽应用
4.相机新增专业模式
10.3、Android7.0新特性
1.多窗口支持
2.V2签名
3.加强的Java8语言模式
4.夜间模式
10.4、Android8.0(O)新特性
1.关照渠道 (Notification Channel)
关照标志
休眠
关照超时
关照设置
关照扫除
2.画中画模式:清单中Activity设置android:supportsPictureInPicture
3.配景限制
4.自动添补框架
5.系统优化
6.等等优化很多
10.5、Android9.0§新特性
1.室内WIFI定位
2.“刘海”屏幕支持
3.安全加强
10.6、Android10.0新特性
夜间模式:包括手机上的所有应用都可以为其设置暗黑模式。
桌面模式:提供类似于PC的体验,但是远远不能代替PC。
屏幕录制:通过长按“电源”菜单中的"屏幕快照"来开启。
11.Bitmap
11.1、Bitmap 使用时候留意什么?
1、要选择合适的图片规格(bitmap类型)
2、降低采样率。BitmapFactory.Options 参数inSampleSize的使用,先把options.inJustDecodeBounds设为true,只是去读取图片的巨细,在拿到图片的巨细之后和要显示的巨细做比力通过calculateInSampleSize()函数盘算inSampleSize的具体值,得到值之后。options.inJustDecodeBounds设为false读图片资源。
3、复用内存。即,通过软引用(内存不敷的时候才会采取掉),复用内存块,不需要再重新给这个bitmap申请一块新的内存,制止了一次内存的分配和采取,从而改善了运行效率。
4、使用recycle()方法实时采取内存。
BitmapFactory.Options 参数inSampleSize的使用,先把options.inJustDecodeBounds设为true,只是去读取图片的巨细,在拿到图片的巨细之后和要显示的巨细做比力通过calculateInSampleSize()函数盘算inSampleSize的具体值,得到值之后。options.inJustDecodeBounds设为false读图片资源。
3、复用内存。即,通过软引用(内存不敷的时候才会采取掉),复用内存块,不需要再重新给这个bitmap申请一块新的内存,制止了一次内存的分配和采取,从而改善了运行效率。
4、使用recycle()方法实时采取内存。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |