常见基础性题目
面试不能紧张,尽量要主动讲解自己懂得的知识点或者了解的知识点,最好不要漏讲解中的步骤
java的设计模式
java中的集合hashmap实现及concurrentHashMap的原理及优势
java中的异常处理及常用的异常
线程池的理解
java的反射机制
java回收机制
Android四大组件
activity的生命周期
fragment的生命周期
service的生命周期
handler的原理(为什么主线程死循环不会ANR)
Android触摸事件分发机制
Android的启动流程
Android使用过的框架及原理(okhttp,glide,rxjava)
JNI和NDK的使用
Android性能优化 (leakcanary的原理)
Android屏幕适配
Android的进程间通信IPC及AIDL的理解
Android动画的理解
Android自定义View(页面是怎么绘制到屏幕的)
Android项目中遇到过的bug,怎么解决的
Android和js的相互调用(JSbridge原理)
AIDL的使用及原理
ContentProvider的接口
视图是怎么在Activity上渲染的
Handler原理,为啥主线程不会被阻塞
动画有几种模式,区别在哪
MVC和MVP 的区别
线程有几种同步方式
讲项目,需要讲项目背景,有什么用,解决了什么问题
http和https的区别,及https连接请求过程,tcp和udp的区别.
Stringbuffer和StringBuilder的区别
常用的请求数据返回码(200,404,500)
okhttp的原理,及http有几个拦截器,拦截器调用的流程
Glide的原理,缓存图片机制和原理
Arouter的原理
JsBridge的原理
性能优化,内存泄漏,AndroidStudio的profiler的使用
Handler的原理
eventbus原理
Android屏幕适配
事件分发机制
类加载过程(双亲委派机制)
Android垃圾回收算法
加密算法RSA等算法原理
View绘制流程
jetpack工具包的详解
MVC和MVP和MVVM的理解
你开发中擅长哪点
软件设计与软件工程有什么理解
为什么使用设计模式
面向对象及理解
继承:继承是从已有类得到继承信息创建新类的过程.
封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。
多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。
java的集合有哪些及特点
使用Collections工具类进行排序
Collections.sort(List, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
//o2-o1为倒序 o1-o2为顺序
return o2.getXXX()-o1.getXXX();//Object.getXXX()返回的是int值
}
});
ConcurrentHashMap相比HashMap而言,是多线程安全的,其底层数据与HashMap的数据结构相同,(数组+链表+红黑树),桶中的结构可能是链表,也可能是红黑树,红黑树是为了提高查找效率。多线程效率加快是因为put时只会锁数组中的表头,不是每次put加锁
java线程
创建方法:
1:class MyThread extend Thread{ public void run(){//执行的代码} } | new MyThread().start();
2:new Thread(new Runnable(){ public void run(){//执行的代码} }).start();
Activity的生命周期
onCreate : Activity开始创建 (最好笔试中可以使用英文写出来而不出错)
onResatrt() : Activity执行了onStop并没有执行onDestroy重新回到自身执行
onStart : Activity可见未获取焦点(不可与用户交互)
onResume : Activity可见并获取焦点(可以与用户交互)
onPause : Activity可见失去焦点(不可与用户交互)
onStop : Activity失去焦点并不可见
onDestroy : Activity销毁
Fragment声明周期
1. onAttach->onCreat->onCreateView->onAttachActivity
2. ->onStart->onResume
3. ->onPause->onStop
4. ->onDestroyView->onDestroy->onDetach
Activity的四种启动模式
1.standard:标准模式(默认),每次启动就会创建一个新的实例
2.singleTop:栈顶复用模式,只有启动栈顶activity才会复用并调用onNewIntent方法
3.singleTask:栈内复用模式,只要启动的activity存在会复用activity(清除该activity栈上的别的activity,使自己位于栈顶)并回调onNewIntent方法,不存在创建一个新的实例
4.singleInstance:单实例模式,启动该activity会单独位于一个activity栈,且该栈只有唯一的该activity实例
https请求过程图
Stringbuffer和StringBuilder的区别
1.StringBuilder是线程不安全的,效率高,StringBuffer方法加了synchronized关键字,线程安全 底层都是使用了char数组实现
开发过程中后端常用返回码有哪些
1XX 信息性状态码(Informational) 服务器正在处理请求
2XX 成功状态码(Success) 请求已正常处理完毕
3XX 重定向状态码(Redirection) 需要进行额外操作以完成请求
4XX 客户端错误状态码(Client Error) 客户端原因导致服务器无法处理请求
5XX 服务器错误状态码(Server Error) 服务器原因导致处理请求出错
常用的请求数据返回码(200,301,404,500)
类加载过程
顺序是:加载->验证->准备->解析->初始化->使用->卸载
双亲委派机制:启动类加载器->扩展类加载器->应用程序加载器
双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类(这个父类不是指继承,是应用程序类往上找是扩展类,扩展类往上找是启动类)加载器。每个类加载器都是如此,只有在父类加载器在自己的搜索范围内找不到指定类时,子类加载器才会尝试自己去加载(比如应用程序类加载会先去扩展类加载,扩展类加载会去启动类加载,如果启动类里面找不到,就去扩展类加载,扩展类找不到就去应用程序类加载)
okhttp的原理,及http有几个拦截器,拦截器调用的流程
okhttp优点:支持HTTP2.HTTP1和SPDY,缓存socket连接,支持自动重连,减少握手次数.
okhttp有两个重要角色:分发器和拦截器.分发器作用(里面维护了线程池和任务队列).对同步请求仅做记录,不做别的操作,主要对异步请求会判断是否达到请求饱和条件,达到饱和条件(有64个请求和同Host请求大于5)会把请求任务缓存下来,等不饱和时会从缓存下来的任务队列中取出请求任务执行,如果是不饱和条件就是直接加入线程池中执行请求任务.走完分发器去请求时就会来到拦截器,okhttp有5个主要实现的拦截器,使用了责任链模式,这些拦截器会对request和response进行一个自身处理
重试重定向拦截器–>桥接拦截器–>缓存拦截器–>连接拦截器–>请求服务器拦截器
Glide的原理,缓存图片机制和原理
Glide.with(Application).load(url).into(view);
Glide通过with传入的参数绑定生命周期,如果是Activity或者Fragment它会创建一个隐藏的Fragment对象来监听Activity或者Fragment的生命周期,当执行onStop时自动暂停一些任务,onStart自动开始一些任务(例如git图片的播放,图片下载等),onDestroy清除任务
注意的是当子线程中运行Glide传入Activity或者Fragment会默认使用Application的生命周期.
缓存机制: 活动缓存–>内存缓存–>磁盘缓存 BitmapPool缓存
Glide(参考郭霖博客Glide系列)
图片加载流程:Glide.with(this).load(url).into(imageView)
根据你传入的是对象监听生命周期,Application不用监听,如果是Activity或者Fragment会添加一个隐藏的Fragment对象来实现监听对应的Activity和Fragment生命周期,如果该页面被销毁,Glide也会对应的销毁下载图片任务
根据你传入的url和Imageview的宽高,作为缓存key去缓存中获取是否有缓存图片,有就直接返回该图片并显示,没有会进行一个网络下载,下载成功会根据传来的ImageView宽高做对应的转换该图,然后缓存该图片,显示该图片
优势:
使用简单,一行代码搞定,支持图片和GIF动图显示
自动监听页面生命周期,防止内存泄漏或占用多问题
默认自动转换相对应图片,减少占用内存,或自定义圆形等转换效果图 (可以关闭转换功能,也可以引用转换开源库glide-transformations)
自带两种缓存(内存和硬盘缓存),硬盘默认缓存转换后的图片,还可以自己设置硬盘缓存图片占用空间大小
图片格式默认使用RGB_565,一像素占用2个字节无透明度信息,比ARGB_8888占用内存少一半,ARGB_8888一像素占用4个字节
网络通讯组件可以替换为okhttp,glide官方也提供了对应库
缓存:四种模式,一种不缓存,一种只缓存原图,一种只缓存转换过后图片(该模式为默认模式),一种是原图和转换图都缓存
有预加载: 使用要注意预加载和显示时都指定缓存原图diskCacheStrategy(DiskCacheStrategy.SOURCE),确保走原图缓存,否则可能重新再去下载图片 Glide.with(this).load(url).diskCacheStrategy(DiskCacheStrategy.SOURCE).preload();
glide怎么实现带下载进度功能 使用okhttp网络组件,在okhttp网络组件中添加进度拦截器,在进度拦截器计算下载进度
Arouter的原理
触摸事件分发机制
触摸事件中一般分发事件是从Activity->ViewGroup->View中,事件分发有三个重要方法,
dispatchTouchEvent:直接返回true为消费,直接返回false为不分发,会调用上层容器onTouchEvent方法,返回super是往下分发事件
onInterceptTouchEvent:这个方法是ViewGroup独有的,用来拦截事件的,返回true未拦截事件,不会向子容器分发事件,直接调用本容器的onTouchEvent方法. 返回false和Super会往子容器分发事件
onTouchEvent:返回true为消费,返回false和super会调用上层容器的onTouchEvent事件
以上为Action_DOWN事件分发,如果有某个容器或者View中的的onTouchEvent方法被记录到消费事件,move和up事件直接会分发到消费事件的容器里,不会再经过onTouchEvent事件层层传递过来了
okhttp原理,支持HTTP和HTTPS协议,以及HTTP2和SPDY协议,使用了Socket连接池进行复用Socket,减少Socket重复创建及和服务器握手连接,增加了责任链模式的拦截器,有重试重定向拦截器,桥接拦截器,Cache拦截器,连接拦截器,callServer拦截器,最后一层真正实现去请求服务器数据
glide原理,使用了多层缓存进行一个图片加载,先去活动缓存里去寻找图片资源,没有就去内存缓存里寻找图片,没有再看磁盘缓存是否拥有图片,没有进行一个网络请求或者去外存路径去拿图片. 重要的是Glide支持了绑定Activity和Fragment的生命周期方法,通过给Activity和Fragment增加一个隐藏的Fragment绑定对应的Activity和Fragment的生命周期上,在onStart时进行任务执行,onStop时进行任务暂停,onDestroy时清除任务. 需要注意的时在子线程去执行Glide加载图片会默认绑定Application生命周期,有可能不注意会造成内存泄漏.
https的请求过程:客户端请求服务器,服务器返回数字证书,客户端验证数字证书,验证不上提示用户是否继续访问,验证正确的话,客户端随机生成一个key,使用证书的公钥进行加密,把加密后的key发送给服务器,服务器通过私钥解密key,得到key后,把要返回的数据使用该key进行一个对称加密发送给客户端,客户端得到数据后使用key解密得到数据了
线程有6中同步方式:1.synchronize关键字,synchronize修饰方法,变量,或者同步代码块,2.volatile关键字修饰变量3.使用阻塞队列,4使用ReentrantLock重入锁5.atomic包下的AtomicInteger等工具类5.使用ThreadLocal(感觉不行)
动画类型:帧动画,补间动画,属性动画. 帧动画为一张一张图片连贯播放形成动画效果. 补间动画:表面上view会进行一个动画效果,但是view的实际属性大小,焦点都没有改变位置 属性动画:随着动画进行,真正的属性也会随之改变,位置及焦点改变,
binder机制原理:c/s架构,有两个进程分为客户端和服务端,客户端发送数据给服务端时,首先把客户端数据复制到内核空间,内核空间是可以进程间共享的,数据到了内核空间后会把数据映射地址给服务端,服务端可以拿到该地址访问该数据
MVC和MVP及MVVM 的区别
MVC:M是数据封装处理,V是视图显示,xml文件,C为Activity可以控制逻辑处理及视图显示,activity复杂的话会比较复杂和臃肿
MVP:在MVC基础进化而来,Activity把数据处理逻辑等抽出一个presenter层,Activity作为一个View层,只控制UI的变化,不再控制逻辑处理,屏蔽对数据的处理
MVVM:VM是ViewModel,view和数据绑定,数据改变后UI跟着改变
https://www.kancloud.cn/s1657292627/android_ios/621895
HashMap(JDK1.8之后)
数组+链表+红黑树 结构组成,链表节点超过8个变成红黑树,少于6个会变回链表,链表使用尾插法插入元素
SparseArray(有限制的是key为int)
两个数组 一个int[] 和object数组,使用二分查找法查询插入位置,对应的位置上为空直接赋值,位置有值然后会把数组进行复制挪动排序,删除元素是只会把对应的数组赋值为Delete指向Object()对象,不会进行数组有别的移动操作,查询使用二分法查询,速度快
volatile关键字作用
1.保证修饰的变量对线程的可见性(A线程对变量改动后,B线程可以即时能拿到新值)
2.禁止指令重排序[例如:创建对象时,1.在堆内存创建对象,给对象内变量赋值初始化(默认值0等)2.在栈中创建对象指针3.给对象成员变量赋值,4.栈中对象指针指向堆中对象] 对象半初始化:由于cpu优化先执行了124,还没有执行3会导致别的线程执行的时候拿到对象使用成员变量带来跟预想中结果不一致的问题