前言
你应该看过很多人分享的成功面经。你觉得也许可以吗?
这里有一个理论:幸存者偏差。当获取信息的渠道仅来自幸存者(因为死者不会说话)时,信息可能与实际情况有不同的偏差。
所以,今天要分享的是凉经。
一.Android中高级面试题
1、Activity生命周期?
onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDetroy()
2、Service生命周期?
service 有两种启动方式,一种是通过startService()另一种方式是通过bindService()启动方式。不同的启动方式有不同的生命周期.
通过startService()这样开始service,生命周期是这样的:调用startService() --> onCreate()–> onStartConmon()–> onDestroy()。如果这样开始,需要注意几个问题, 第一:当我们通过时startService调用后,多次调用startService(),onCreate()方法只调用一次,onStartConmon()我们将多次调用它stopService()的时候,onDestroy()它将被调用来销毁服务。 第二:当我们通过时startService启动时,通过intent传值,在onStartConmon()在方法中获得值时,必须先判断intent是否为null。
通过bindService()这样绑定,这样绑定service,生命周期:bindService–>onCreate()–>onBind()–>unBind()–>onDestroy()bingservice 这样开始service优点是更方便activity中操作service,比如加入service有几种方法,a,b ,如果要在activity需要在中调用activity获取ServiceConnection对象,通过ServiceConnection来获取service内部类对象,然后通过这个类对象可以调用类中的方法,当然,这个类需要继承Binder对象
3、Activity启动过程(不要回答生命周期)
app有两种情况可以启动,第一种是从桌面launcher点击相应的应用图标,第二个是activity中通过调用startActivity启动新的activity。
默认创建新项目的根源activity都是MainActivity,而所有的activity都保存在堆栈里,我们开始新的activity会放在最后一个activity当我们从桌面上点击应用图标时,因为launcher它也是一个应用程序。当我们点击图标时,系统会调用它startActivitySately(),一般来说,我们开始了activity保存相关信息intent中,比如action,category等等。当我们安装这个应用程序时,系统也会启动一个PackaManagerService这项管理服务将是对的AndroidManifest.xml分析文件,以获取应用程序中的相关信息,如service,activity,Broadcast等等,然后获取相关组件的信息。
当我们点击应用,会调用startActivitySately()该方法内部调用startActivty(),而startActivity()方法最终会调用startActivityForResult()这个方法startActivityForResult()这个方法startActivityForResult()该方法有返回结果,因此系统直接给出-1,表示不需要返回结果。
而startActivityForResult()这种方法实际上是通过的Instrumentation类中的execStartActivity()方法来启动activity,Instrumentation这一类的主要功能是监控程序与系统之间的交互。而在这领域execStartActivity()获取方法ActivityManagerService代理对象通过该代理对象启动activity。启动会调用一个checkStartActivityResult()方法,如果配置清单中没有配置此组件,则该方法中会出现异常。当然,最后一个调用是Application.scheduleLaunchActivity()进行启动activity,而这个方法中通过获取得到一个ActivityClientRecord对象,而这个ActivityClientRecord通过handler来进行消息的发送,系统内部会将每一个activity组件使用ActivityClientRecord描述对象ActivityClientRecord在对象中保存一个LoaderApk对象对象调用对象handleLaunchActivity来启动activity组件,页面的生命周期方法也在此方法中调用。
4、Broadcast注册方式与差异
5、HttpClient与HttpUrlConnection的区别
:Volley哪种请求方式(2).3前HttpClient,2.3后HttpUrlConnection)
首先HttpClient和HttpUrlConnection 支持这两种方法Https协议以流的形式上传或下载数据,或以流的形式传输数据,以及ipv六、连接池等功能。HttpClient这个有很多API,因此,如果要扩展而不破坏其兼容性,就很难扩展,这就是为什么,Google在Android6.0的时候直接放弃了这个HttpClient.
而HttpUrlConnection比较轻量级,API少,容易扩展,能满足Android大部分的数据传输。比较经典的一个框架volley,在2.3版本以前都是使用HttpClient,在2.以后用HttpUrlConnection。
6、java虚拟机和Dalvik虚拟机的区别
- java基于栈的虚拟机。基于栈的机器必须使用指令来输入和操作栈上的数据,需要更多的指令。
- java虚拟机运行java字节码。(java类别将被编译成一个或多个字节.class文件)
- dalvik虚拟机是基于寄存器的
- Dalvik自定义操作.dex字节码格式。(java类被编译成.class文件结束后,将通过一个dx所有的工具.class将文件转换成一个.dex文件,然后dalvik虚拟机会读取指令和数据
- 为了 简化解释器。
- 一个应用程序,一个虚拟机实例,一个过程(所有)android应用程序的线程对应于一个linux线程在自己的沙箱中运行,不同的应用在不同的过程中运行。android dalvik所有的应用程序都被赋予了独立性linux PID(app_*))
7.过程保存(不死过程)
8、讲解一下Context
Cotext是一个抽象基类。在翻译为上下文,也可以理解为环境,是提供一些程序的运行环境基础信息。Context下有两个子类,ContextWrapper是上下文功能的封装类,而ContextImpl则是上下文功能的实现类。
而ContextWrapper又有三个直接的子类, ContextThemeWrapper、Service和Application。其中,ContextThemeWrapper是一个带主题的封装类,而它有一个直接子类就是Activity,所以Activity和Service以及Application的Context是不一样的,只有Activity需要主题,Service不需要主题。Context一共有三种类型,分别是Application、Activity和Service。这三个类虽然分别各种承担着不同的作用,但它们都属于Context的一种,而它们具体Context的功能则是由ContextImpl类去实现的,因此在绝大多数场景下,Activity、Service和Application这三种类型的Context都是可以通用的。不过有几种场景比较特殊,比如启动Activity,还有弹出Dialog。
出于安全原因的考虑,Android是不允许Activity或Dialog凭空出现的,一个Activity的启动必须要建立在另一个Activity的基础之上,也就是以此形成的返回栈。而Dialog则必须在一个Activity上面弹出(除非是System Alert类型的Dialog),因此在这种场景下,我们只能使用Activity类型的Context,否则将会出错。
getApplicationContext()和getApplication()方法得到的对象都是同一个application对象,只是对象的类型不一样。
Context数量 = Activity数量 + Service数量 + 1 (1为Application)
9、理解Activity,View,Window三者关系
这个问题真的很不好回答。所以这里先来个算是比较恰当的比喻来形容下它们的关系吧。Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图)LayoutInflater像剪刀,Xml配置像窗花图纸。
Activity构造的时候会初始化一个Window,准确的说是
PhoneWindow。 这个PhoneWindow有一个“ViewRoot”,这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。 “ViewRoot”通过addView方法来一个个的添加View。比如TextView,Button等 这些View的事件监听,是由WindowManagerService来接受消息,并且回调Activity函数。比如onClickListener,onKeyDown等。
10、四种LaunchMode及其使用场景
:栈(First In Last Out)与队列(First In First Out)的区别
1. 队列先进先出,栈先进后出 2. 对插入和删除操作的"限定"。 栈是限定只能在表的一端进行插入和删除操作的线性表。 队列是限定只能在表的一端进行插入和在另一端进行删除操作的线性表。 3. 遍历数据速度不同
这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中。使用场景:大多数Activity。
如果在任务的栈顶正好存在该Activity的实例,就重用该实例( 会调用实例的 onNewIntent() ),否则就会创建新的实例并放入栈顶,即使栈中已经存在该Activity的实例,只要不在栈顶,都会创建新的实例。使用场景如新闻类或者阅读类App的内容页面。
如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的 onNewIntent() )。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。使用场景如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。
在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。使用场景如闹铃提醒,将闹铃提醒与闹铃设置分离。singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,在此启动,首先打开的是B。
11、View的绘制流程
12、View,ViewGroup事件分发
13、保存Activity状态
14、Android中的几种动画
:指通过指定每一帧的图片和播放时间,有序的进行播放而形成动画效果,比如想听的律动条。
:指通过指定View的初始状态、变化时间、方式,通过一系列的算法去进行图形变换,从而形成动画效果,主要有Alpha、Scale、Translate、Rotate四种效果。注意:只是在视图层实现了动画效果,并没有真正改变View的属性,比如滑动列表,改变标题栏的透明度。
:在Android3.0的时候才支持,通过不断的改变View的属性,不断的重绘而形成动画效果。相比于视图动画,View的属性是真正改变了。比如view的旋转,放大,缩小。
15、Android中跨进程通讯的几种方式
16、AIDL理解
: 每一个进程都有自己的Dalvik VM实例,都有自己的一块独立的内存,都在自己的内存上存储自己的数据,执行着自己的操作,都在自己的那片狭小的空间里过完自己的一生。而aidl就类似与两个进程之间的桥梁,使得两个进程之间可以进行数据的传输,跨进程通信有多种选择,比如 BroadcastReceiver, Messenger 等,但是 BroadcastReceiver 占用的系统资源比较多,如果是频繁的跨进程通信的话显然是不可取的;Messenger 进行跨进程通信时请求队列是同步进行的,无法并发执行。
:
在Android系统的Binder机制中,是有Client,Service,ServiceManager,Binder驱动程序组成的,其中Client,service,Service Manager运行在用户空间,Binder驱动程序是运行在内核空间的。而Binder就是把这4种组件粘合在一块的粘合剂,其中核心的组件就是Binder驱动程序,Service Manager提供辅助管理的功能,而Client和Service正是在Binder驱动程序和Service Manager提供的基础设施上实现C/S 之间的通信。其中Binder驱动程序提供设备文件/dev/binder与用户控件进行交互,
Client、Service,Service Manager通过open和ioctl文件操作相应的方法与Binder驱动程序进行通信。而Client和Service之间的进程间通信是通过Binder驱动程序间接实现的。而Binder Manager是一个守护进程,用来管理Service,并向Client提供查询Service接口的能力。
17、Handler的原理
Android中主线程是不能进行耗时操作的,子线程是不能进行更新UI的。所以就有了handler,它的作用就是实现线程之间的通信。
handler整个流程中,主要有四个对象,handler,Message,MessageQueue,Looper。当应用创建的时候,就会在主线程中创建handler对象,
我们通过要传送的消息保存到Message中,handler通过调用sendMessage方法将Message发送到MessageQueue中,Looper对象就会不断的调用loop()方法
不断的从MessageQueue中取出Message交给handler进行处理。从而实现线程之间的通信。
18、Binder机制原理
在Android系统的Binder机制中,是有Client,Service,ServiceManager,Binder驱动程序组成的,其中Client,service,Service Manager运行在用户空间,Binder驱动程序是运行在内核空间的。而Binder就是把这4种组件粘合在一块的粘合剂,其中核心的组件就是Binder驱动程序,Service Manager提供辅助管理的功能,而Client和Service正是在Binder驱动程序和Service Manager提供的基础设施上实现C/S 之间的通信。其中Binder驱动程序提供设备文件/dev/binder与用户控件进行交互,Client、Service,Service Manager通过open和ioctl文件操作相应的方法与Binder驱动程序进行通信。而Client和Service之间的进程间通信是通过Binder驱动程序间接实现的。而Binder Manager是一个守护进程,用来管理Service,并向Client提供查询Service接口的能力。
19、热修复的原理
我们知道Java虚拟机 —— JVM 是加载类的class文件的,而Android虚拟机——Dalvik/ART VM 是加载类的dex文件,
而他们加载类的时候都需要ClassLoader,ClassLoader有一个子类BaseDexClassLoader,而BaseDexClassLoader下有一个
数组——DexPathList,是用来存放dex文件,当BaseDexClassLoader通过调用findClass方法时,实际上就是遍历数组,
找到相应的dex文件,找到,则直接将它return。而热修复的解决方法就是将新的dex添加到该集合中,并且是在旧的dex的前面,
所以就会优先被取出来并且return返回。
20、Android内存泄露及管理
21、Fragment与Fragment、Activity通信的方式
22、Android UI适配
23、app优化
24、图片优化
对图片本身进行操作。尽量不要使用
setImageBitmap、setImageResource、BitmapFactory.decodeResource来设置一张大图,因为这些方法在完成decode后, 最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 图片进行缩放的比例,SDK中建议其值是2的指数值,值越大会导致图片不清晰。 不用的图片记得调用图片的recycle()方法
25、HybridApp WebView和JS交互
26、JAVA GC原理
27、ANR
28、设计模式
29、RxJava
30、MVP,MVC,MVVM
:手写mvp例子,与mvc之间的区别,mvp的优势
MVP模式,对应着Model–业务逻辑和实体模型,view–对应着activity,负责View的绘制以及与用户交互,Presenter–负责View和Model之间的交互,MVP模式是在MVC模式的基础上,将Model与View彻底分离使得项目的耦合性更低,在Mvc中项目中的activity对应着mvc中的C--Controllor,而项目中的逻辑处理都是在这个C中处理,同时View与Model之间的交互,也是也就是说,mvc中所有的逻辑交互和用户交互,都是放在Controllor中,也就是activity中。
View和model是可以直接通信的。而MVP模式则是分离的更加彻底,分工更加明确Model–业务逻辑和实体模型,view–负责与用户交互,Presenter 负责完成View于Model间的交互,MVP和MVC最大的区别是MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。还有一点就是Presenter与View之间的交互是通过接口的
31、手写算法(选择冒泡必须要会)
32、JNI
安装和下载Cygwin,下载 Android NDK 在ndk项目中JNI接口的设计 使用C/C++实现本地方法 JNI生成动态链接库.so文件 将动态链接库复制到java工程,在java工程中调用,运行java工程即可
33、RecyclerView和ListView的区别
RecyclerView可以完成ListView,GridView的效果,还可以完成瀑布流的效果。同时还可以设置列表的滚动方向(垂直或者水平);
RecyclerView中view的复用不需要开发者自己写代码,系统已经帮封装完成了 RecyclerView可以进行局部刷新。
RecyclerView提供了API来实现item的动画效果。
如果需要频繁的刷新数据,需要添加动画,则RecyclerView有较大的优势。
如果只是作为列表展示,则两者区别并不是很大。
34、Universal-ImageLoader,Picasso,Fresco,Glide对比
35、Xutils, OKhttp, Volley, Retrofit对比
最后
我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了5、6年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。
其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。
不断奔跑,你就知道学习的意义所在!

给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。
其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。
不断奔跑,你就知道学习的意义所在!
[外链图片转存中…(img-cP6v82RK-1648220950033)]
[外链图片转存中…(img-IKJS399F-1648220950034)]