缘起
有很多Android 开发人员筹备面试,却不晓得如何筹备?于是纷纷上网发帖求助。
甚至很多人网上轻易找找面试题什么的,其后果就是[字节惨挂在三面],挥泪整顿面筋。等诸多文章火了,究其原因就是这些文章戳中了大部分面试者的痛点,面试被刷了。
想到还有很多android程序员没有找到Android面试纲要。不晓得如何筹备Android面试。
于是,我就想罗唆我本人做这个事吧,就算没人看,也当我本人的年终总结了。
如何筹备android面试
纯技术方面的筹备,如果是的话,我就提供一些高见,大部分算是一些开发常识死角或者tips吧,权当抛砖引玉了:)
明天就总结下2020年搜集整理的面试题,难度不大,大佬能够间接路过,当然发发善心点个赞也是能够的❤️。
Activity面试题
1、Activity是什么
Activity是四大组件之一,它提供一个界面让用户点击和各种滑动操作,这就是Activity
2、Activity四种状态
- runing
- paused
- stopped
- killed
3、Activity生命周期
- onCreate()
- onStart()
- onResume()
- onPause()
- onStop()
- onDestroy()
- onRestart()
4、Activity切换横屏时生命周期
- onSaveInstanceState()
- onPause()
- onStop()
- onDestroy()
- onCreate()
- onStart()
- onRestoreInstanceState()
- onResume()
5、过程的优先级
oom_adj
是linux内核调配给每个零碎过程的一个值,代表过程的优先级,过程回收机制就是依据这个优先级来决定是否进行回收。过程的oom_adj
越大,示意此过程优先级越低,越容易被杀回收;越小,示意过程优先级越高,越不容易被杀回收。一般app过程的oom_adj
>=0,零碎过程的oom_adj
才可能小于0。过程优先级从小到大如下
- 空过程
- 后盾过程
- 服务过程
- 可见过程
- 前台过程
6、Activity工作栈
- 先进后出
7、Activity启动模式
- standard
- singletop
- singletask
- singleinstance
8、scheme跳转协定
android中的scheme是一种页面内跳转协定,通过定义本人的scheme协定,能够跳转到app中的各个页面
- 服务器能够定制化通知app跳转哪个页面
- App能够通过跳转到另一个App页面
- 能够通过H5页面跳转页面
9、Context、Activity、Application之间有什么区别
Activity和Application都是Context的子类。Context从字面上了解就是上下文的意思,在理论利用中它也的确是起到了治理上下文环境中各个参数和变量的总用,不便咱们能够简略的拜访到各种资源。尽管Activity和Application都是Context的子类,然而他们保护的生命周期不一样。前者保护一个Acitivity的生命周期,所以其对应的Context也只能拜访该activity内的各种资源。后者则是保护一个Application的生命周期
10、Activity启动过程
- 在装置利用的时候,零碎会启动PackaManagerService治理服务,这个治理服务会对AndroidManifest进行解析,从而失去应用程序中的相干信息,比方service,activity,Broadcast等等,而后取得相干组件的信息
- 当用户点击利用图标时,就会调用
startActivitySately()
,而这个办法外部则是调用startActivty()
,startActivity()
最终还是会调用startActivityForResult()
。因为startActivityForResult()
是有返回后果的,零碎间接返回-1,示意不须要返回后果 startActivityForResult()
通过Instrumentation类中的execStartActivity()
来启动activity,Instrumentation这个类次要作用是监控程序和零碎之间的交互。在这个execStartActivity()
中会获取ActivityManagerService的代理对象,通过这个代理对象进行启动activity- 在ActivityManagerService的代理对象中,通过Binder通信,调用到
ApplicationThread.scheduleLaunchActivity()
进行启动activity,在这个办法中创立一个ActivityClientRecord对象,用来记录启动Activity组件的信息,而后通过handler将ActivityClientRecord发送进来 - 在handler收到音讯后,调用
ActivityThread.handleLaunchActivity()
启动Activity
11、简述Activity,View,Window三者关系
- Activity实质是上下文,View实质是视图,Window实质是窗口
- Activity结构的时候会初始化一个Window,其具体实现是PhoneWindow
- PhoneWindow中有一个ViewRoot(View或ViewGroup),是最初始的根视图
- ViewRoot通过addView()将View增加到根视图上,实际上是将View交给了PhoneWindow解决
- View的事件监听是由WindowManagerService来承受音讯,并且回调Activity函数
Fragment面试题
1、Fragment为什么被称为第五大组件
Fragment比Activity更节俭内存,其切换模式也更加舒服,应用频率不低于四大组件,且有本人的生命周期,而且必须依附于Activity
2、Activity创立Fragment的形式
- 动态创立
- 动态创建
3、FragmentPageAdapter和FragmentPageStateAdapter的区别
- FragmentPageAdapter在每次切换页面的的时候,是将Fragment进行拆散,适宜页面较少的Fragment应用以保留一些内存,对系统内存不会多大影响
- FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适宜页面较多的Fragment应用,这样就不会耗费更多的内存
4、Fragment生命周期
- onAttach()
- onCreate()
- onCreateView()
- onActivityCreated()
- onStart()
- onResume()
- onPause()
- onStop()
- onDestroyView()
- onDestroy()
- onDetach()
5、Fragment的通信
- Fragment调用Activity中的办法:getActivity
- Activity调用Fragment中的办法:接口回调
- Fragment调用Fragment中的办法:FragmentManager.findFragmentById
6、Fragment的replace、add、remove办法
- replace:代替Fragment的栈顶页面
- add:增加Fragment到栈顶页面
- remove:移除Fragment栈顶页面
Service面试题
1、Service是什么
Service是四大组件之一,它能够在后盾执行长时间运行操作而没有用户界面的利用组件
2、Service和Thread的区别
- Service是安卓中零碎的组件,它运行在独立过程的主线程中,不能够执行耗时操作。Thread是程序执行的最小单元,调配CPU的根本单位,能够开启子线程执行耗时操作
- Service在不同Activity中能够获取本身实例,能够不便的对Service进行操作。Thread在不同的Activity中难以获取本身实例,如果Activity被销毁,Thread实例就很难再获取失去
3、Service启动形式
- startService
- bindService
4、Service生命周期
- startService
- onCreate()
- onStartCommand()
- onDestroy()
- bindService
- onCreate()
- onBind()
- onUnbind()
- onDestroy()
Broadcast Receiver面试题
1、Broadcast Receiver是什么
Broadcast是四大组件之一,是一种宽泛使用在应用程序之间传输信息的机制,通过发送Intent来传送咱们的数据
2、Broadcast Receiver的应用场景
- 同一App具备多个过程的不同组件之间的音讯通信
- 不同App之间的组件之间的音讯通信
3、Broadcast Receiver的品种
- 一般播送
- 有序播送
- 本地播送
- Sticky播送
4、Broadcast Receiver的实现
- 动态注册:注册后始终运行,只管Activity、过程、App被杀死还是能够接管到播送
- 动静注册:追随Activity的生命周期
5、Broadcast Receiver实现机制
- 自定义播送类继承BroadcastReceiver,复写onReceiver()
- 通过Binder机制向AMS进行注册播送
- 播送发送者通过Binder机制向AMS发送播送
- AMS查找合乎相应条件的播送发送到BroadcastReceiver相应的循环队列中
- 音讯队列执行拿到播送,回调BroadcastReceiver的onReceiver()
6、LocalBroadcastManager特点
- 本地播送只能在本身App内流传,不用放心透露隐衷数据
- 本地播送不容许其余App对你的App发送该播送,不用放心安全漏洞被利用
- 本地播送比全局播送更高效
- 以上三点都是源于其外部是用Handler实现的
WebView面试题
1、WebView安全漏洞
- API16之前存在近程代码执行安全漏洞,该破绽源于程序没有正确限度应用WebView.addJavascriptInterface办法,近程攻击者可通过应用Java反射机制利用该破绽执行任意Java对象的办法
2、WebView销毁步骤
- WebView在其余容器上时(如:LinearLayout),当销毁Activity时,须要在onDestroy()中先移除容器上的WebView,而后再将WebView.destroy(),这样就不会导致内存透露
3、WebView的jsbridge
- 客户端和服务端之间能够通过Javascript来相互调用各自的办法
4、WebViewClient的onPageFinished
- WebViewClient的onPageFinished在每次实现页面的时候调用,然而遇到未加载实现的页面跳转其余页面时,就会始终调用,应用WebChromeClient.onProgressChanged能够代替
5、WebView后盾耗电
- 在WebView加载页面的时候,会主动开启线程去加载,如果不很好的敞开这些线程,就会导致电量耗费加大,能够采纳暴力的办法,间接在onDestroy办法中System.exit(0)完结以后正在运行中的java虚拟机
6、WebView硬件加速
Android3.0引入硬件加速,默认会开启,WebView在硬件加速的状况下滑动更加平滑,性能更加好,然而会呈现白块或者页面闪动的副作用,倡议WebView临时敞开硬件加速
7、WebView内存透露
因为WebView是依附于Activity的,Activity的生命周期和WebView启动的线程的生命周期是不统一的,这会导致WebView始终持有对这个Activity的援用而无奈开释,解决方案如下
- 独立过程,简略暴力,不过可能波及到过程间通信(举荐)
- 动静增加WebView,对传入WebView中应用的Context应用弱援用
Binder面试题
1、Linux内核的基本知识
- 过程隔离/虚拟地址空间:过程间是不能够共享数据的,相当于被隔离,每个过程被调配到不同的虚拟地址中
- 零碎调用:Linux内核对利用有拜访权限,用户只能在应用层通过零碎调用,调用内核的某些程序
- binder驱动:它负责各个用户的过程,通过binder通信内核来进行交互的模块
2、为什么应用Binder
- 性能上,相比传统的Socket更加高效
- 安全性高,反对协定单方相互校验
3、Binder通信原理
- Service端通过Binder驱动在ServiceManager的查找表中注册Object对象的add办法
- Client端通过Binder驱动在ServiceManager的查找表中找到Object对象的add办法,并返回proxy对象的add办法,add办法是个空实现,proxy对象也不是真正的Object对象,是通过Binder驱动封装好的代理类的add办法
- 当Client端调用add办法时,Client端会调用proxy对象的add办法,通过Binder驱动去申请ServiceManager来找到Service端真正对象,而后调用Service端的add办法
4、AIDL
- 客户端通过aidl文件的Stub.asInterface()办法,拿到Proxy代理类
- 通过调用Proxy代理类的办法,将参数进行封包后,调用底层的transact()办法
- transact()办法会回调onTransact()办法,进行参数的解封
- 在onTransact()办法中调用服务端对应的办法,并将后果返回
5、BpBinder和BBinder
BpBinder(客户端)对象和BBinder(服务端)对象,它们都从IBinder类中派生而来,BpBinder(客户端)对象是BBinder(服务端)对象的代理对象,关系图如下
- client端:BpBinder.transact()来发送事务申请
- server端:BBinder.onTransact()会接管到相应事务
Handler面试题
1、Handler是什么
Handler通过发送和解决Message和Runnable对象来关联绝对应线程的MessageQueue
2、Handler应用办法
- post(runnable)
- sendMessage(message)
3、Handler工作原理
- Android进阶——Android音讯机制之Looper、Handler、MessageQueen
4、Handler引起的内存透露
- 起因:非动态外部类持有外部类的匿名援用,导致Activity无奈开释
解决:
- Handler外部持有内部Activity的弱援用
- Handler改为动态外部类
- Handler.removeCallback()
AsyncTask面试题
1、AsyncTask是什么
它实质上就是一个封装了线程池和Handler的异步框架
2、AsyncTask应用办法
三个参数
- Params:示意后台任务执行时的参数类型,该参数会传给AysncTask的doInBackground()办法
- Progress:示意后台任务的执行进度的参数类型,该参数会作为onProgressUpdate()办法的参数
- Result:示意后台任务的返回后果的参数类型,该参数会作为onPostExecute()办法的参数
五个办法
- onPreExecute():异步工作开启之前回调,在主线程中执行
- doInBackground():执行异步工作,在线程池中执行
- onProgressUpdate():当doInBackground中调用publishProgress时回调,在主线程中执行
- onPostExecute():在异步工作执行之后回调,在主线程中执行
- onCancelled():在异步工作被勾销时回调
3、AsyncTask工作原理
- Android进阶——多线程系列之异步工作AsyncTask的应用与源码剖析
4、AsyncTask引起的内存透露
- 起因:非动态外部类持有外部类的匿名援用,导致Activity无奈开释
解决:
- AsyncTask外部持有内部Activity的弱援用
- AsyncTask改为动态外部类
- AsyncTask.cancel()
5、AsyncTask生命周期
在Activity销毁之前,勾销AsyncTask的运行,以此来保障程序的稳固
6、AsyncTask后果失落
因为屏幕旋转、Activity在内存缓和时被回收等状况下,Activity会被从新创立,此时,旧的AsyncTask持有旧的Activity援用,这个时候会导致AsyncTask的onPostExecute()对UI更新有效
7、AsyncTask并行or串行
- AsyncTask在Android 2.3之前默认采纳并行执行工作,AsyncTask在Android 2.3之后默认采纳串行执行工作
- 如果须要在Android 2.3之后采纳并行执行工作,能够调用AsyncTask的executeOnExecutor()
HandlerThread面试题
1、HandlerThread产生背景
当零碎有多个耗时工作须要执行时,每个工作都会开启一个新线程去执行耗时工作,这样会导致系统屡次创立和销毁线程,从而影响性能。为了解决这一问题,Google提供了HandlerThread,HandlerThread是在线程中创立一个Looper循环器,让Looper轮询音讯队列,当有耗时工作进入队列时,则不须要开启新线程,在原有的线程中执行耗时工作即可,否则线程阻塞
2、HanlderThread的特点、
- HandlerThread实质上是一个线程,继承自Thread
- HandlerThread有本人的Looper对象,能够进行Looper循环,能够创立Handler
- HandlerThread能够在Handler的handlerMessage中执行异步办法
- HandlerThread长处是异步不会梗塞,缩小对性能的耗费
- HandlerThread毛病是不能同时持续进行多任务处理,须要期待进行解决,解决效率较低
- HandlerThread与线程池不同,HandlerThread是一个串行队列,背地只有一个线程
IntentService面试题
1、IntentService是什么
IntentService是继承自Service并解决异步申请的一个类,其外部采纳HandlerThread和Handler实现的,在IntentService内有一个工作线程来解决耗时操作,其优先级比一般Service高。当工作实现后,IntentService会主动进行,而不须要手动调用stopSelf()。另外,能够屡次启动IntentService,每个耗时操作都会以工作队列的形式在IntentService中onHandlerIntent()回调办法中执行,并且每次只会执行一个工作线程
2、IntentService应用办法
- 创立Service继承自IntentService
- 覆写构造方法和onHandlerIntent()办法
- 在onHandlerIntent()中执行耗时操作
视图工作机制面试题
- Android进阶——Android视图工作机制之measure、layout、draw
事件散发机制面试题
- Android事件散发机制之dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
Android我的项目构建面试题
1、Android构建流程
[图片上传失败…(image-ccd96b-1606878198554)]
2、jenkins继续集成构建
- 这里可参考蒲公英文档
3、git常用命令
- git init:仓库的初始化
- git status:查看以后仓库的状态
- git diff:查看仓库与上次批改的内容
- git add:将文件放进暂存区
- git commit:提交代码
- git clone:克隆代码
- git bransh:查看以后分支
- git checkout:切换以后分支
4、git工作流
fork/clone(支流)
- fork:将他人的仓库代码fork到本人的仓库上
- clone:克隆下本人仓库的代码
- update、commit:批改代码并提交到本人的仓库
- push:提交到本人的仓库
- pull request:申请增加到他人的仓库
- clone
5、proguard是什么
ProGuard工具是用于压缩、优化和混同咱们的代码,其主作用是移除或混同代码中无用类、字段、办法和属性
6、proguard技术性能
- 压缩
- 优化
- 混同
- 预检测
7、proguard工作原理
将无用的字段或办法存入到EntryPoint中,将非EntryPoint的字段和办法进行替换
8、为什么要混同
因为Java是一门跨平台的解释性语言,其源代码被编译成class字节码来适应其余平台,而class文件蕴含了Java源代码信息,很容易被反编译
9、annotationProcessor与compileOnly的区别
annotationProcessor与compileOnly都是只编译并不打入apk中
- annotationProcessor:编译时生成代码,编译完就不须要了
- compileOnly:有反复的库时,能够剃除反复库,只保留一个库
ANR面试题
1、什么是ANR
Application Not Responding,页面无响应的对话框
2、产生ANR的条件
应用程序的响应性是由ActivityManager和WindowManager零碎服务监督的,当ANR产生条件满足时,就会弹出ANR的对话框
- Activity超过5秒无响应
- BroadcastReceiver超过10秒无响应
- Service超过20秒无响应
3、造成ANR的次要起因
主线程被IO操作阻塞
- Activity的所有生命周期回调都是执行在主线程的
- Service默认执行在主线程中
- BoardcastReceiver的回调onReceive()执行在主线程中
- AsyncTask的回调除了doInBackground,其余都是在主线程中
- 没有应用子线程Looper的Handler的handlerMessage,post(Runnable)都是执行在主线程中
4、如何解决ANR
- 应用AsyncTask解决耗时IO操作
- 应用Thread或HandlerThread进步优先级
- 应用Handler解决工作线程的耗时操作
- Activity的onCreate和onResume回调尽量避免耗时操作
OOM面试题
1、什么是OOM
OOM指Out of memory(内存溢出),以后占用内存加上咱们申请的内存资源超过了Dalvik虚拟机的最大内存限度就会抛出Out of memory异样
2、OOM相干概念
- 内存溢出:指程序在申请内存时,没有足够的空间供其应用
- 内存透露:指程序调配进来的内存不再应用,无奈进行回收
- 内存抖动:指程序短时间内大量创建对象,而后回收的景象
3、解决OOM
Bitmap相干
- 图片压缩
- 加载缩略图
- 在滚动时不加载图片
- 回收Bitmap
- 应用inBitmap属性
- 捕捉异样
其余相干
- listview重用convertView、应用lru
- 防止onDraw办法执行对象的创立
- 审慎应用多过程
Bitmap面试题
1、recycle
- 在安卓3.0以前Bitmap是寄存在堆中的,咱们只有回收堆内存即可
- 在安卓3.0当前Bitmap是寄存在内存中的,咱们须要回收native层和Java层的内存
- 官网倡议咱们3.0当前应用recycle办法进行回收,该办法也能够不被动调用,因为垃圾回收器会主动收集不可用的Bitmap对象进行回收
- recycle办法会判断Bitmap在不可用的状况下,将发送指令到垃圾回收器,让其回收native层和Java层的内存,则Bitmap进入dead状态
- recycle办法是不可逆的,如果再次调用getPixels()等办法,则获取不到想要的后果
2、LruCache原理
LruCache是个泛型类,外部采纳LinkedHashMap来实现缓存机制,它提供get办法和put办法来获取缓存和增加缓存,其最重要的办法trimToSize是用来移除起码应用的缓存和应用最久的缓存,并增加最新的缓存到队列中
3、计算采样率
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float)height / (float)reqHeight); } else { inSampleSize = Math.round((float)width / (float)reqWidth); } } return inSampleSize;}
4、采样率压缩(缩略图)
public static Bitmap thumbnail(String path,int maxWidth, int maxHeight) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(path, options); options.inJustDecodeBounds = false; int sampleSize = calculateInSampleSize(options, maxWidth, maxHeight); options.inSampleSize = sampleSize; options.inPreferredConfig = Bitmap.Config.RGB_565; options.inPurgeable = true; options.inInputShareable = true; if (bitmap != null && !bitmap.isRecycled()) { bitmap.recycle(); } bitmap = BitmapFactory.decodeFile(path, options); return bitmap;}
5、品质压缩
public static String save(Bitmap bitmap,Bitmap.CompressFormat format, int quality, File destFile) { try { FileOutputStream out = new FileOutputStream(destFile); if (bitmap.compress(format, quality, out)) { out.flush(); out.close(); } if (bitmap != null && !bitmap.isRecycled()) { bitmap.recycle(); } return destFile.getAbsolutePath(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null;}
6、尺寸压缩
public static void reSize(Bitmap bmp,File file,int ratio){ Bitmap result = Bitmap.createBitmap(bmp.getWidth()/ratio, bmp.getHeight()/ratio,Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(result); RectF rect = new RectF(0, 0, bmp.getWidth()/ratio, bmp.getHeight()/ratio); canvas.drawBitmap(bmp, null, rect , null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); result.compress(Bitmap.CompressFormat.JPEG, 100, baos); try { FileOutputStream fos = new FileOutputStream(file); fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); }}
7、保留到SD卡
public static String save(Bitmap bitmap,Bitmap.CompressFormat format, int quality, Context context) { if (!Environment.getExternalStorageState() .equals(Environment.MEDIA_MOUNTED)) { return null; } File dir = new File(Environment.getExternalStorageDirectory() + "/" + context.getPackageName() + "/save/"); if (!dir.exists()) { dir.mkdirs(); } File destFile = new File(dir, UUID.randomUUID().toString()); return save(bitmap, format, quality, destFile);}
8、三级缓存
- 网络缓存
- 本地缓存
- 内存缓存
9、NDK压缩
Android进阶——图片优化之品质压缩、尺寸压缩、采样率压缩、LibJpeg压缩
10、webp压缩
Android Webp 齐全解析 快来放大apk的大小吧-鸿洋的博客
UI卡顿面试题
1、UI卡顿原理
View的绘制帧数放弃60fps是最佳,这要求每帧的绘制工夫不超过16ms(1000/60),如果安卓不能在16ms内实现界面的渲染,那么就会呈现卡顿景象
2、UI卡顿的起因剖析
- 在UI线程中做轻微的耗时操作,导致UI线程卡顿
- 布局Layout过于简单,无奈在16ms内实现渲染
- 同一时间动画执行的次数过多,导致CPU和GPU负载过重
- overDraw,导致像素在同一帧的工夫内被绘制屡次,使CPU和GPU负载过重
- View频繁的触发measure、layout,导致measure、layout累计耗时过多和整个View频繁的从新渲染
- 频繁的触发GC操作导致线程暂停,会使得安卓零碎在16ms内无奈实现绘制
- 冗余资源及逻辑等导致加载和执行迟缓
- ANR
3、UI卡顿的优化
布局优化
- 应用include、ViewStub、merge
- 不要呈现过于嵌套和冗余的布局
- 应用自定义View取代简单的View
ListView优化
- 复用convertView
- 滑动不加载
背景和图片优化
- 缩略图
- 图片压缩
防止ANR
- 不要在UI线程中做耗时操作
内存透露面试题
1、Java内存透露引起的次要起因
长生命周期的对象持有短生命周期对象的援用就很可能产生内存透露
2、Java内存调配策略
- 动态存储区:又称办法区,次要存储全局变量和动态变量,在整个程序运行期间都存在
- 栈区:办法体的局部变量会在栈区创立空间,并在办法执行完结后会主动开释变量的空间和内存
- 堆区:保留动静产生的数据,如:new进去的对象和数组,在不应用的时候由Java回收器主动回收
3、Android解决内存透露的例子
- 单例造成的内存透露:在单例中,应用context.getApplicationContext()作为单例的context
- 匿名外部类造成的内存透露:因为非动态外部类持有匿名外部类的援用,必须将外部类设置为static
- Handler造成的内存透露:应用static的Handler外部类,同时在实现外部类中持有Context的弱援用
- 防止应用static变量:因为static变量会跟Activity生命周期统一,当Activity退出后盾被后盾回收时,static变量是不平安,所以也要治理好static变量的生命周期
- 资源未敞开造成的内存透露:比方Socket、Broadcast、Cursor、Bitmap、ListView等,应用完后要敞开
- AsyncTask造成的内存透露:因为非动态外部类持有匿名外部类的援用而造成内存透露,能够通过AsyncTask外部持有内部Activity的弱援用同时改为动态外部类或在onDestroy()中执行AsyncTask.cancel()进行修复
内存治理面试题
1、Android内存管理机制
- 分配机制
- 管理机制
2、内存管理机制的特点
- 更少的占用内存
- 在适合的时候,正当的开释系统资源
- 在零碎内存缓和的时候,能开释掉大部分不重要的资源
- 能正当的在非凡生命周期中,保留或还原重要数据
3、内存优化办法
- Service实现工作后应进行它,或用IntentService(因为能够主动进行服务)代替Service
- 在UI不可见的时候,开释其UI资源
- 在零碎内存缓和的时候,尽可能多的开释非重要资源
- 防止滥用Bitmap导致内存节约
- 防止应用依赖注入框架
- 应用针对内存优化过的数据容器
- 应用ZIP对齐的APK
- 应用多过程
冷启动和热启动面试题
1、什么是冷启动和热启动
- 冷启动:在启动利用前,零碎中没有该利用的任何过程信息
- 热启动:在启动利用时,在已有的过程上启动利用(用户应用返回键退出利用,而后马上又重新启动利用)
2、冷启动和热启动的区别
- 冷启动:创立Application后再创立和初始化MainActivity
- 热启动:创立和初始化MainActivity即可
3、冷启动工夫的计算
这个工夫值从利用启动(创立过程)开始计算,到实现视图的第一次绘制为止
4、冷启动流程
- Zygote过程中fork创立出一个新的过程
- 创立和初始化Application类、创立MainActivity
- inflate布局、当onCreate/onStart/onResume办法都走完
- contentView的measure/layout/draw显示在界面上
总结:点击App->IPC->Process.start->ActivityThread->Application生命周期->Activity生命周期->ViewRootImpl测量布局绘制显示在界面上
5、冷启动优化
- 缩小第一个界面onCreate()办法的工作量
- 不要让Application参加业务的操作
- 不要在Application进行耗时操作
- 不要以动态变量的形式在Application中保留数据
- 缩小布局的复杂性和深度
- 不要在mainThread中加载资源
- 通过懒加载形式初始化第三方SDK
6、adb命令获取启动工夫
adb shell am start -W packagename/MainActivity
- ThisTime:最初一个Activity启动耗时
- TotalTime:所有Activity启动耗时
- WaitTime:AMS启动Activity的总耗时
其余优化面试题
1、Android不必动态变量存储数据
- 动态变量等数据因为过程曾经被杀死而被初始化
- 应用其余数据传输方式:文件/sp/contentProvider
2、SharePreference平安问题
- 不能跨进程同步
- 文件不宜过大
3、内存对象序列化
- Serializeble:是java的序列化形式,Serializeble在序列化的时候会产生大量的长期对象,从而引起频繁的GC
- Parcelable:是Android的序列化形式,且性能比Serializeble高,Parcelable不能应用在要将数据存储在硬盘上的状况
4、防止在UI线程中做沉重的操作
架构模式面试题
- Android根底——框架模式MVC在安卓中的实际
- Android根底——框架模式MVP在安卓中的实际
- Android根底——框架模式MVVM之DataBinding的实际
插件化面试题
1、插件化解决的问题
- 动静加载APK(反射、类加载器)
- 资源加载(反射、AssetManager、独立资源、分段资源)
- 代码加载(反射获取生命周期)
2、类加载器(Java中字节码增加到虚拟机中)
- DexClassLoader:可能加载未装置的jar/apk/dex,次要用于动静加载和代码热更新
- PathClassLoader:加载/data/app目录下的apk文件,只有用来加载零碎中曾经装置过的apk
热更新面试题
1、热更新次要流程
- 线上查看到Crash
- 拉出Bugfix分支修复Crash问题
- jenkins构建和补丁生成
- app通过推送或被动拉取补丁文件
- 将Bugfix代码合到master上
2、热更新支流框架
- Dexposed
- AndFix
- Nuwa
3、热更新的原理
- 在ClassLoader创立一个dexElements数组
- 将修复好的dex文件寄存在dexElements数组的最后面
- ClassLoader会遍历dexElements数组,找到最后面的dex文件优先加载
过程保活面试题
1、过程的优先级
- 空过程
- 后盾过程
- 服务过程
- 可见过程
- 前台过程
2、Android过程回收策略
- Low memory Killer(定时执行):通过一些比较复杂的评分机制,对过程进行打分,而后将分数高的过程断定为bad过程,杀死并开释内存
- OOM_ODJ:判断过程的优先级
3、Android保活计划
- 利用零碎播送拉活
- 利用零碎Service机制拉活
- 利用Native过程拉活
- 利用JobScheduler机制拉活
- 利用账号同步机制拉活
Lint面试题
1、什么是Android Lint
Android Lint是一个动态代码剖析工具,它可能对你的Android我的项目中潜在的Bug、可优化的代码、安全性、性能、可用性、可拜访性、国际化等进行查看
2、Lint工作流程
[图片上传失败…(image-d5f5ab-1606878198551)]
3、配置Lint
- 创立Lint.xml到根目录下,自定义Lint安全等级等
- 在Java文件中能够应用@suppressLint(“NewApi”)来漠视Lint的报错
- 在xml文件中能够应用tool:ignore(“UnusedResources”)来漠视Lint的报错
- 自定义Lint查看,能够创立类,继承Detector和实现JavaPsiScanner
Kotlin面试题
1、什么是Kotlin
- Kotlin是一种基于JVM的编程语言
- 对Java的一种拓展,比Java更简洁
- Kotlin反对函数式编程
- Kotlin类和Java类能够互相调用
2、Kotlin环境搭建
- 间接在Plugin中下载Kotlin插件即可
- 零碎会主动配置到Kotlin环境
虚拟机面试题
1、Dalvik与JIT
Dalvik是Android虚拟机,JIT则是Dalvik采纳的技术策略
在编译打包APK文件时,会通过以下流程Java->Class->Dalvik字节码(dex)->每次执行代码都要编译成机器码->交给底层解决
,这样解决起来效率低下,通过引入JIT(即时编译技术),当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行即时编译,通过编译后的代码,会被优化成相当精简的原生型指令码,这样在下次执行到雷同逻辑的时候,速度就会更快。但因为每次启动App都须要即时编译,导致运行时耗电量大
2、ART与AOT
ART是Android虚拟机,AOT则是ART采纳的技术策略
在ART环境中,利用在第一次装置的时候,字节码就会事后编译成机器码,使其成为真正的本地利用,这一技术称为AOT。之后关上App的时候,不须要额定的翻译工作,间接应用本地机器码运行,因而运行速度进步。但因为会事后编译,安装时间难免会缩短,而且会耗费更多的存储空间,但消耗掉空间的增幅通常不会超过利用代码包大小的20%
3、发展史
- 2.2 ~ 4.4:Dalvik虚拟机应用JIT技术
- 4.4 ~ 5.0:Dalvik虚拟机和ART虚拟机共存
- 5.0 ~ x.0:ART虚拟机应用AOT技术代替Dalvik虚拟机
4、JVM与Dalvik不同
- 类加载零碎区别比拟大
- JVM是基于栈,Dalvik是基于寄存器
- JVM执行的是java字节码文件,Dalvik执行的是dex字节码文件
- Dalvik能够同时存在多个,即便一个退出了也不会影响其余程序
5、Dalvik与ART不同
- Dalvik应用JIT(Just In Time 运行时编译)来将字节码转换成机器码,效率低
- ART采纳AOT(Ahead Of Time 运行前编译或装置时编译)预编译技术,利用运行速度更快
- ART会占用更多的利用安装时间和存储空间
注解面试题
1、什么是Annotation
Java提供的一种元程序中的元素关联任何信息和任何元数据(metadata)的路径和办法
2、什么是metadata
- 元数据以标签的模式存在于Java代码中
- 元数据形容的信息是类型平安的
- 元数据须要编译器之外的工具额定的解决用来生成其余的程序部件
- 元数据能够只存在于Java源代码级别,也能够存在于编译之后的Class文件外部
3、注解分类
零碎内置规范注解
- @Override:示意重写
- @Deprecated:示意已过期
- @SuppressWarnnings:示意克制正告
元注解
- @Target:示意注解的润饰范畴
- @Retention:示意注解的代码生存期
- @Documented:示意注解为程序员的API
- @Inherited:示意注解能够继承
@Target
- ElementType.CONSTRUCTOR:结构器申明
- ElementType.FIELD:成员变量、对象、属性(包含enum实例)
- ElementType.LOCAL_VARIABLE:局部变量申明
- ElementType.METHOD:办法申明
- ElementType.PACKAGE:包申明
- ElementType.PARAMETER:参数申明
- ElementType.TYPE:类、接口(包含注解类型)或enum申明
@Retention
- RetentionPolicy.SOURCE:在源文件中无效,当Java文件编译成class文件的时候,注解被遗弃
- RetentionPolicy.CLASS:在class文件中无效,当jvm加载class文件时候被遗弃
- RetentionPolicy.RUNTIME:在运行时无效,当jvm加载class文件之后,依然存在
生命周期
- RUNTIME > CLASS > SOURCE
- .java文件 --> .class文件 --> 内存中的字节码
4、注解申明
注解反对填写数组,同时反对多种范畴
@Target({ElementType.TYPE,ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ModuleWrapper {}
5、Android Support Annotation
- Nullness注解(@NonNull、@Nullable):示意指定的空类型或非空类型
- ResourceType注解(@StringRes、@IntegerRes、@ColorRes等):示意指定的变量类型
- Threading注解(@WorkerThread、@UIThread、@MainThread等):示意指定的线程类型
- Range注解(@IntRange、@FloatRange等):示意容许传值的范畴
- OverridingMethods注解(@CallSuper等):示意调用父类的办法
6、注解的用处
- 束缚类
- 束缚变量
- 束缚入参
- 束缚返回值
网络面试题
1.网页中输出url,到渲染整个界面的整个过程,以及两头用了什么协定?
1)过程剖析:次要分为三步
DNS解析
。用户输出url后,须要通过DNS解析找到域名对应的ip地址,有了ip地址能力找到服务器端。首先会查找浏览器缓存,是否有对应的dns记录。再持续依照操作系统缓存—路由缓存—isp的dns服务器—根服务器的程序进行DNS解析,直到找到对应的ip地址。客户端(浏览器)和服务器交互
。浏览器依据解析到的ip地址和端口号发动HTTP申请,申请达到传输层,这里也就是TCP层,开始三次握手建设连贯。服务器收到申请后,发送相应报文给客户端(浏览器),客户端收到相应报文并进行解析,失去html页面数据,包含html,js,css等。客户端(浏览器)解析html数据
,构建DOM树,再结构出现树(render树),最终绘制到浏览器页面上。
2)其中波及到TCP/IP协定簇,包含DNS,TCP,IP,HTTP协定等等。
2.具体介绍下TCP/IP
TCP/IP个别指的是TCP/IP协定簇,次要包含了多个不同网络间实现信息传输波及到的各种协定
次要包含以下几层:
应用层
:次要提供数据和服务。比方HTTP,FTP,DNS等传输层
:负责数据的组装,分块。比方TCP,UDP等网络层
:负责通知通信的目的地,比方IP等数据链路层
:负责连贯网络的硬件局部,比方以太网,WIFI等
3.TCP的三次握手和四次挥手,为什么不是两次握手?为什么挥手多一次呢?
客户端简称A,服务器端简称B
1)TCP建设连贯须要三次握手
- A向B示意想跟B进行连贯(A发送
syn
包,A进入SYN_SENT
状态) - B收到音讯,示意我也筹备好和你连贯了(B收到
syn
包,须要确认syn
包,并且本人也发送一个syn
包,即发送了syn+ack
包,B进入SYN_RECV
状态) - A收到音讯,并通知B示意我收到你也筹备连贯的信号了(A收到
syn+ack
包,向服务器发送确认包ack
,AB进入established
状态)开始连贯。
2)TCP断开连接须要四次挥手
- A向B示意想跟B断开连接(A发送
fin
,进入FIN_WAIT_1
状态) - B收到音讯,然而B音讯没发送完,只能通知A我收到你的断开连接音讯(B收到fin,发送ack,进入
CLOSE_WAIT
状态) - 过一会,B数据发送结束,通知A,我能够跟你断开了(B发送fin,进入
LAST_ACK
状态) - A收到音讯,通知B,能够他断开(A收到fin,发送ack,B进入
close
d状态)
3)为什么挥手多一次
其实失常的断开和连贯都是须要四次
:
- A发消息给B
- B反馈给A示意正确收到音讯
- B发送音讯给A
- A反馈给B示意正确收到音讯。
然而连贯中,第二步和第三步是能够合并
的,因为连贯之前A和B是无分割的,所以没有其余状况须要解决。而断开的话,因为之前两端是失常连贯状态,所以第二步的时候不能保障B之前的音讯曾经发送结束,所以不能马上通知A要断开的音讯。这就是连贯为什么能够少一步的起因。
4)为什么连贯须要三次,而不是两次。
失常来说,我给你发消息,你通知我能收到,不就代表咱们之前通信是失常的吗?
- 简略答复就是,
TCP是双向通信协定
,如果两次握手,不能保障B发给A的音讯正确达到。
TCP 协定为了实现牢靠传输, 通信单方须要判断本人曾经发送的数据包是否都被接管方收到, 如果没收到, 就须要重发。
TCP是怎么保障牢靠传输的?
序列号和确认号
。比方连贯的一方发送一段80byte数据,会带上一个序列号,比方101。接管方收到数据,回复确认号181(180+1),这样下一次发送音讯就会从181开始发送了。
所以握手过程中,比方A发送syn信号给B,初始序列号为120,那么B收到音讯,回复ack
音讯,序列号为120+1。同时B发送syn
信号给A,初始序列号为256,如果收不到A的回复音讯,就会重发,否则失落这个序列号,就无奈失常实现前面的通信了。
这就是三次握手的起因。
4.TCP和UDP的区别?
TCP
提供的是面向连贯,牢靠的字节流服务。即客户和服务器替换数据前,必须当初单方之间建设一个TCP连贯(三次握手),之后能力传输数据。并且提供超时重发,抛弃反复数据,测验数据,流量管制等性能,保证数据能从一端传到另一端。
UDP
是一个简略的面向数据报的运输层协定。它不提供可靠性,只是把应用程序传给IP层的数据报发送进来,然而不能保障它们能达到目的地。因为UDP
在传输数据报前不必再客户和服务器之间建设一个连贯,且没有超时重发等机制,所以传输速度很快。
所以总结下来就是:
- TCP 是面向连贯的,UDP 是面向无连贯的
- TCP数据报头包含序列号,确认号,等等。相比之下UDP程序结构较简略。
- TCP 是面向字节流的,UDP 是基于数据报的
- TCP 保证数据正确性,UDP 可能丢包
- TCP 保证数据程序,UDP 不保障
能够看到TCP
实用于稳固的利用场景,他会保证数据的正确性和程序,所以个别的浏览网页,接口拜访都应用的是TCP
传输,所以才会有三次握手
保障连贯的稳定性。
而UDP是一种构造简略的协定,不会思考丢包啊,建设连贯等。长处在于数据传输很快,所以实用于直播,游戏等场景。
5.HTTP的几种申请办法具体介绍
常见的有四种:
GET
获取资源,没有body,幂等性POST
减少或者批改资源,有bodyPUT
批改资源,有body,幂等性DELETE
删除资源,幂等性
6.HTTP申请和响应报文的格局,以及罕用状态码
1)申请报文:
//申请行(包含method、path、HTTP版本) GET /s HTTP/1.1 //Headers Host: www.baidu.com Content-Type: text/plain //Body 搜寻****
2)响应报文
//状态行 (包含HTTP版本、状态码,状态信息) HTTP/1.1 200 OK //Headers Content-Type: application/json; charset=utf-8 //Body [{"info":"xixi"}]
3)罕用状态码
次要分为五种类型:
1结尾
, 代表临时性音讯,比方100(持续发送)2结尾
, 代表申请胜利,比方200(OK)3结尾
, 代表重定向,比方304(内容无扭转)4结尾
, 代表客户端的一些谬误,比方403(禁止拜访)5结尾
, 代表服务器的一些谬误,比方500
出于篇幅的考量,本文不可能对Android面试纲要所有面试模块作出阐明。即便如此,沿着本文提供的思路,参考相干章节内容,剖析相干知识点和源码,你会很快、很容易地拿到一线互联网企业的offer。
文档支付形式:点赞+关注,而后私信关键词 【1】即可取得收费支付形式!