安卓进阶必知必会的问题(持续收集中)


安卓部分

1. 安卓跨进程通信(IPC)的几种方式

  1. Bundle:四大组件间的进程间通信方式,简单易用,但传输的数据类型受限。
  2. 文件共享: 不适合高并发场景,并且无法做到进程间的及时通信。
  3. Messenger: 数据通过Message传输,只能传输Bundle支持的类型。
  4. ContentProvider:android 系统提供的,简单易用,但使用受限,只能根据特定规则访问数据。
  5. AIDL:功能强大,支持实时通信,但使用稍微复杂。
  6. Socket:网络数据交换的常用方式。
    https://www.sohu.com/a/314677281_216613

2. View和SurfaceView的区别

  1. view只能在主线程中更新UI,不能在子线程中更新,而SurfaceView可以在任何线程中更新UI;
  2. SurfaceView可以控制帧数,执行动画效率View的高;
  3. SurfaceView是放在最底层,可以在它上边添加一些层,而且不能是透明的;
    https://www.jianshu.com/p/6d39ce9e4f9b

3. View的绘制原理

  • View的绘制过程就是从ViewRoot的performTraversals方法开始的,它经过measure、layout、draw三个过程才能最终将一个View绘制出来:
  1. measure用来测量View的宽和高。
  2. layout用来确定View在父容器中放置的位置。
  3. draw用来将view绘制在屏幕上。
    https://blog.csdn.net/u014316462/article/details/52054352

4. 简述JNI

  1. JNI翻译过来就是java本地接口,它相当于一个媒介,使得java代码能够和其它语言写的代码进行交互
  2. 把app一些重要的算法逻辑用c/c++来写,通过JNI来调用,可以加大被人反编译破解apk的难度
  3. 通过JNI可以移植一些其它语言写好的功能,比如:ffmpeg音视频解码库

5. 简述TCP/IP,HTTP,HTTPS,TCP,UDP,Socket

  1. TCP/IP 是互联网相关的各类协议族的总称,比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 族内的协议。像这样把与互联网相关联的协议集合起来总称为 TCP/IP。
  2. TCP/IP 参考模型:这一网络协议共分为四层:数据链路层、网络层、传输层和应用层。在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。在传输层中有TCP协议与UDP协议。在应用层有HTTP,FTP、TELNET、SMTP、DNS等协议。
  3. HTTP全称是HyperText Transfer Protocal,即:超文本传输协议,HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
  4. HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议。 它是一个安全通信通道HTTPS是HTTP over SSL/TLS,HTTP是应用层协议,TCP是传输层协议,在应用层和传输层之间,增加了一个安全套接层SSL/TLS:
  • SSL (Secure Socket Layer,安全套接字层)
  • TLS (Transport Layer Security,传输层安全协议)
  • SSL使用40 位关键字作为RC4流加密算法
  1. TCP(Transmission Control Protocol)协议全称是传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP 是面向连接的、可靠的流协议。
  2. UDP User Datagram Protocol)协议全称是用户数据报协议,在网络中它与 TCP 协议一样用于处理数据包,是一种无连接的协议,提供面向事务的简单不可靠信息传送服务。
  3. socket只是一种连接模式,不是协议,socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

https://blog.csdn.net/WHB20081815/article/details/67640804
https://blog.csdn.net/chaoshenzhaoxichao/article/details/79785318

6. Https和Http的区别

  1. https协议需要到CA申请证书。
  2. http是超文本传输协议,信息是明文传输;https 则是具有安全性的ssl加密传输协议。
  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4. http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
    https://www.cr173.com/Guide/302667_1.html

7. TCP和UDP的区别

  1. TCP 是面向连接的,UDP 是面向无连接的
  2. UDP程序结构较简单
  3. TCP 是面向字节流的,UDP 是基于数据报的
  4. TCP 保证数据正确性,UDP 可能丢包
  5. TCP 保证数据顺序,UDP 不保证
    https://blog.csdn.net/zhang6223284/article/details/81414149

8. android的消息机制

  1. android的消息机制指的是Handler的运行机制,主要通过四个类来完成,分别是:Handler,Message,MessegeQuque,Looper来完成
  2. 它的运行流程是这样的,首先在主线程中创建Handler,然后在分线程中使用handler.sendMessage()方法把消息发送到MessegeQuque中,MessegeQuque以队列的形式保存消息,Looper一直以轮询的方式一直监听着消息队列,一旦消息队列有消息,就把他提取出来,交给主线程的handler来处理,这样就完成了一次消息运转

https://blog.csdn.net/wsq_tomato/article/details/80301851

9. handler为什么出现内存泄漏?

  • 首先Handler使用是用来进行线程间通信的,所以新开启的线程是会持有Handler引用的,如果在Activity等中创建Handler,并且是非静态内部类的形式,就有可能造成内存泄漏。
  1. 首先,非静态内部类是会隐式持有外部类的引用,所以当其他线程持有了该Handler,线程没有被销毁,则意味着Activity会一直被Handler持有引用而无法导致回收。
  2. 同时,MessageQueue中如果存在未处理完的Message,Message的target也是对Activity等的持有引用,也会造成内存泄漏。
  • 解决的办法:
  1. 使用静态内部类+弱引用的方式:静态内部类不会持有外部类的的引用,当需要引用外部类相关操作时,可以通过弱引用还获取到外部类相关操作,弱引用是不会造成对象该回收回收不掉的问题.
  2. 在外部类对象被销毁时,将MessageQueue中的消息清空。例如,在Activity的onDestroy时将消息清空。
    https://blog.csdn.net/wsq_tomato/article/details/80301851

10. Activity的启动模式

  1. standard模式是Activity默认的启动模式, 在此模式下,每次启动新的Activity时,都会进入任务栈,并处于任务栈的栈顶。而且,在该模式下,系统不会判断该Activity在栈中是否真实存在,每次启动时都会选择创建一个新的实例。
  2. singleTop模式,大体上与standard模式类似,其中不同的是,如果启动的Activity已经位于任务栈的栈顶时,则直接使用它,不用再去创建一个新的实例。但是如果启动的Activity没有位于任务栈的栈顶,则要去创建一个新的实例位于任务栈的栈顶。
  3. singleTask模式可以使Activity在整个应用程序种只存在一个实例。当指定为该模式时,每次启动Activity时,系统首先会检查任务栈种是否存在该Activity的实例,若是存在则直接使用,并且会将当前Activity上的所有A
  4. ctivity出栈。若是没有发现存在,则会创建一个新的实例。
  5. singleInstance模式,Activity在整个系统中都只有一个实例.当指定为该模式时,Activity会启动一个新的任务栈来管理这个Activity。

11. Activity和Fragment数据交互

  1. 构造方法的参数传递
  2. bundle传递
  3. 广播
  4. 本地持久化存储
  5. evenbus
  6. 接口回调
  7. viewmodel
  8. 静态变量

12. okhttp的原理

https://blog.csdn.net/songzi1228/article/details/101050603

13. 事件的分发机制

事件的分发
上面的Log,是我手指按下去的时候打印出来的,这个时候我并没有移动和擡起手指

所以顺序是

1.进入activity的dispatchTouchEvent

2.事件传递进入viewgroup的dispatchTouchEvent

3.判断拦截器

4.拦截器返回数据,不拦截,进入view

5.进入view的dispatchTouchEvent

6.进入view的onTouchEvent

7.返回view的onTouchEvent

8.返回viewgroup的onTouchEvent

9.返回activity的dispatchTouchEvent

14. 自定义view

  • View的绘制流程
  • 自定义控件:
  • 1.组合控件。这种自定义控件不需要我们自己绘制,而是使用原生控件组合成的新控件。如标题栏。
  • 2、继承原有的控件。这种自定义控件在原生控件提供的方法外,可以自己添加一些方法。如制作圆角,圆形图片。
  • 3、完全自定义控件:这个View上所展现的内容全部都是我们自己绘制出来的。比如说制作水波纹进度条。
  • View的绘制流程:OnMeasure()——>OnLayout()——>OnDraw()
  • 第一步:OnMeasure():测量视图大小。从顶层父View到子View递归调用measure方法,measure方法又回调OnMeasure。
  • 第二步:OnLayout():确定View位置,进行页面布局。从顶层父View向子View的递归调用view.layout方法的过程,即父View根据上一步measure子View所得到的布局大小和布局参数,将子View放在合适的位置上。
  • 第三步:OnDraw():绘制视图。ViewRoot创建一个Canvas对象,然后调用OnDraw()。

作者:魔都_大白
链接:https://www.jianshu.com/p/7afb776a1ea3
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

15. Binder机制

1、首先 Binder 驱动在内核空间创建一个数据接收缓存区;

2、接着在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系;

3、发送方进程通过系统调用 copy_from_user() 将数据 copy 到内核中的内核缓存区(通过序列化,反序列化拷贝),由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。

作者:吴小博Toby
链接:https://www.jianshu.com/p/ab1cc84b0192
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

16. 插件化、组件化、热修复的原理

  1. 组件化:组件化开发就是将一个app分成多个模块,每个模块都是一个组件(Module),开发的过程中我们可以让这些组件相互依赖或者单独调试部分组件等,但是最终发布的时候是将这些组件合并统一成一个apk,这就是组件化开发。
  2. 插件化:插件化架构下,每个业务模块都是一个独立可运行的APP,插件化顾名思义,更多是想把需要实现的模块或功能当做一个独立的提取出来,减少宿主的规模,当需要使用到相应的功能时再去加载相应的模块。
  3. 热修复:热修复和插件化有一定的相同之处,他们都是从系统加载器的角度出发,无论是采用hook方式,亦或是代理方式或者是其他底层实现,都是通过“欺骗”Android 系统的方式来让宿主正常的加载和运行插件(补丁)中的内容。插件化强调的是按需加载,动态更新。热修复则是从修复bug的角度出发,强调的是在不需要二次安装应用的前提下修复已知的bug。

作者:八分半
链接:https://www.jianshu.com/p/cdfba36245e8
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

17. ARouter原理

  1. ARouter 是通过注解的方式结合android提供的启动Activity的API实现页面的跳转及参数的传递的。
  2. 路由框架会在项目的编译期通过注解处理器apt扫描所有添加@Route注解的Activity类,然后将Route注解中的path地址和Activity.class文件映射关系保存到它自己生成的java文件中,只要拿到了映射关系便能拿到Activity.class。、
  3. 最后通过Android提供的启动Activity的api来进行启动activity
    http://www.pianshen.com/article/8521186521/

18. HTTPS工作原理

采用对称加密对数据进行加密,然后将加密后的数据data和密钥key一起传给服务器,服务器根据key对数据进行解密。

19. Android 中的线程有那些,原理与各自特点

https://blog.csdn.net/merbn/article/details/88609668

20. Rxjava

21. 常见的设计模式

  1. 单例模式
  2. Builder模式
  3. 策略方法模式
  4. 工厂方法模式
  5. 观察者模式
  6. 组合模式
  7. 适配模式
  8. 模板方法模式
  9. 代理模式
    https://www.cnblogs.com/kma-3/p/7096057.html

22. AsyncTask是串行还是并行执行?

串行执行

23. AMS,WMS,PMS 创建过程

24. LruCache使用极其原理

LruCache算法就是Least Recently Used,也就是最近最少使用算法。

他的算法就是当缓存空间满了的时候,将最近最少使用的数据从缓存空间中删除以增加可用的缓存空间来缓存新内容。

这个算分的内部有一个缓存列表。每当一个缓存数据被访问的时候,这个数据就会被提到列表头部,每次都这样的话,列表的尾部数据就是最近最不常使用的了,当缓存空间不足时,就会删除列表尾部的缓存数据。
————————————————
版权声明:本文为CSDN博主「喵了个呜s」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_25806863/article/details/77548468

25. 如何避免OOM?(安卓的内存优化)

  • 从三个方面来讲,第一,减少对象的内存占用,第二,内存对象的重复利用,第三,避免对象的内存泄漏
  1. 减少对象的内存占用
    1. 使用更加轻量的数据结构
    2. 避免在android里面使用Enum
    3. 减少Bitmap对象的内存占用
    4. 使用更小的图片
  2. 内存对象的重复利用
    1. 复用系统自带的资源
    2. 注意在ListView/GridView等出现大量重复子组件的视图里对ConvertView的复用
    3. Bitmap对象的复用
    4. 避免在自定义view的onDraw方法里面执行对象的创建
    5. 使用StringBuilder来对字符串频繁的拼接
  3. 避免对象的内存泄漏
    1. 注意Activity的泄露,内部类引用导致Activity的泄漏
    2. Activity Context被传递到其他实例中,这可能导致自身被引用而发生泄漏。
    3. 注意临时Bitmap对象的及时回收
    4. 注意监听器的注销
    5. 注意缓存容器中的对象泄漏
    6. 注意WebView的泄露
    7. 注意Cursor对象是否及时关闭
      https://www.jianshu.com/p/6cbd5bc49464

26. 如何实现进程保活

这个有点不太了解,以前有做过,不知道现在还能不能用,就是启动两三个进程在后台两两监听,其中一个挂了,其余的进程知道了就再重启那个进程,大概是这样

27. 说下冷启动和热启动

  1. app冷启动: 当应用启动时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用, 这个启动方式就叫做冷启动(后台不存在该应用进程)
  2. app热启动: 当应用已经被打开, 但是被按下返回键、Home键等按键时回到桌面或者是其他程序的时候,再重新打开该app时, 这个方式叫做热启动(后台已经存在该应用进程)

28. ANR的原因

https://www.125la.com/955.html

29. 图片的3级缓存原理

  1. 首先先从内存获取图片,如果内存有图片那就直接显示图片
  2. 如果内存没有图片,那就从磁盘获取图片,并且把图片加载到内存,并显示出来
  3. 如果磁盘没有图片,那就从网络获取图片,然后把图片保存到磁盘,并且把图片加载到内存,最后把图片显示出来

30. 说下AIDL的使用与原理

  • 使用
  1. 服务端首先要创建一个Service用来监听客户端的链接请求,然后创建一个AIDL文件,将暴露给客户端的接口在这个AIDL文件中声明,最后在Service中实现这个AIDL接口即可。
  2. 客户端做的事情比较简单,首先需要绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转成AIDL接口所属的类型,接着就可以调用AIDL中的方法了
  • 原理

31. 内存泄漏的场景和解决办法

  1. 非静态内部类的静态实例
    非静态内部类会持有外部类的引用,如果非静态内部类的实例是静态的,就会长期的维持着外部类的引用,组织被系统回收,解决办法是使用静态内部类

  2. 多线程相关的匿名内部类和非静态内部类
    匿名内部类同样会持有外部类的引用,如果在线程中执行耗时操作就有可能发生内存泄漏,导致外部类无法被回收,直到耗时任务结束,解决办法是在页面退出时结束线程中的任务

  3. Handler内存泄漏
    Handler导致的内存泄漏也可以被归纳为非静态内部类导致的,Handler内部message是被存储在MessageQueue中的,有些message不能马上被处理,存在的时间会很长,导致handler无法被回收,如果handler是非静态的,就会导致它的外部类无法被回收,解决办法是1.使用静态handler,外部类引用使用弱引用处理2.在退出页面时移除消息队列中的消息

  4. Context导致内存泄漏
    根据场景确定使用Activity的Context还是Application的Context,因为二者生命周期不同,对于不必须使用Activity的Context的场景(Dialog),一律采用Application的Context,单例模式是最常见的发生此泄漏的场景,比如传入一个Activity的Context被静态类引用,导致无法回收

  5. 静态View导致泄漏
    使用静态View可以避免每次启动Activity都去读取并渲染View,但是静态View会持有Activity的引用,导致无法回收,解决办法是在Activity销毁的时候将静态View设置为null(View一旦被加载到界面中将会持有一个Context对象的引用,在这个例子中,这个context对象是我们的Activity,声明一个静态变量引用这个View,也就引用了activity)

  6. WebView导致的内存泄漏
    WebView只要使用一次,内存就不会被释放,所以WebView都存在内存泄漏的问题,通常的解决办法是为WebView单开一个进程,使用AIDL进行通信,根据业务需求在合适的时机释放掉

  7. 资源对象未关闭导致
    如Cursor,File等,内部往往都使用了缓冲,会造成内存泄漏,一定要确保关闭它并将引用置为null

  8. 集合中的对象未清理
    集合用于保存对象,如果集合越来越大,不进行合理的清理,尤其是入股集合是静态的

  9. Bitmap导致内存泄漏
    bitmap是比较占内存的,所以一定要在不使用的时候及时进行清理,避免静态变量持有大的bitmap对象

  10. 监听器未关闭
    很多需要register和unregister的系统服务要在合适的时候进行unregister,手动添加的listener也需要及时移除

查找内存泄漏可以使用Android Profiler工具或者利用LeakCanary工具。
————————————————
版权声明:本文为CSDN博主「csbhwy」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wcsbhwy/article/details/89360469

32. ART和Dalvik区别

  1. 在Dalvik下,应用每次运行都需要通过即时编译器(JIT)将字节码转换为机器码,即每次都要编译加运行,这虽然会使安装过程比较快,但是会拖慢应用以后每次启动的效率。而在ART 环境中,应用在第一次安装的时候,字节码就会预编译(AOT)成机器码,这样的话,虽然设备和应用的首次启动(安装慢了)会变慢,但是以后每次启动执行的时候,都可以直接运行,因此运行效率会提高。
  2. ART占用空间比Dalvik大(字节码变为机器码之后,可能会增加10%-20%),这也是著名的“空间换时间大法"。
  3. 预编译也可以明显改善电池续航,因为应用程序每次运行时不用重复编译了,从而减少了 CPU 的使用频率,降低了能耗。 
    ————————————————
    版权声明:本文为CSDN博主「SEU_Calvin」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/SEU_Calvin/article/details/52354964

33. 屏幕适配

  1. smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。
  2. smallestWidth的适配机制由系统保证,我们只需要针对这套规则生成对应的资源文件即可,不会出现什么难以解决的问题,也根本不会影响我们的业务逻辑代码,而且只要我们生成的资源文件分布合理,,即使对应的smallestWidth值没有找到完全对应的资源文件,它也能向下兼容,寻找最接近的资源文件。
  3. 这是比较成熟的方案了,也是我比较常用的屏幕适配方案

34. 安卓的性能优化

  1. 卡顿优化
  2. 内存优化
  3. 稳定性优化
  4. 耗电优化
  5. 安装包大小优化
  6. 数据库的优化
  7. 网络优化
    https://my.oschina.net/nicksong/blog/3043796

35. Serializable 和 Parcelable区别

  1. Serializable是java中的序列化接口,其使用起来简单但是开销很大,序列化和反序列化过程需要大量I/O操作。一般在保存数据到 SD 卡或者网络传输时建议使用 Serializable 即可
  2. 而Parcelable是Android中序列化方式,一般在运行时数据传递时建议使用 Parcelable。,他的缺点就是使用起来稍微麻烦点,但是他的效率很高。

36. MVC、MVP、MVVM

  1. MVC:用户的对View操作以后,View捕获到这个操作,会把处理的权利交移给Controller(Pass calls);Controller接着会执行相关的业务逻辑,这些业务逻辑可能需要对Model进行相应的操作;当Model变更了以后,会通过观察者模式(Observer Pattern)通知View;View通过观察者模式收到Model变更的消息以后,会向Model请求最新的数据,然后重新更新界面。
  2. MVP:和MVC模式一样,用户对View的操作都会从View交移给Presenter。Presenter同样的会执行相应的业务逻辑,并且对Model进行相应的操作;而这时候Model也是通过观察者模式把自己变更的消息传递出去,但是是传给Presenter而不是View。Presenter获取到Model变更的消息以后,通过View提供的接口更新界面。
  3. MVVM:MVVM的调用关系和MVP一样。但是,在ViewModel当中会有一个叫Binder,或者是Data-binding engine的东西。以前全部由Presenter负责的View和Model之间数据同步操作交由给Binder处理。你只需要在View的模版语法当中,指令式地声明View上的显示的内容是和Model的哪一块数据绑定的。当ViewModel对进行Model更新的时候,Binder会自动把数据更新到View上去,当用户对View进行操作(例如表单输入),Binder也会自动把数据更新到Model上去。这种方式称为:Two-way data-binding,双向数据绑定。
    ————————————————
    版权声明:本文为CSDN博主「万能程序者」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/SUPERIT1/article/details/83794598

java部分

1. ClassLoader的过程,ClassLoader的好处

2. ArrayList和Vector扩容的区别

3. 锁的种类,什么是自旋锁,ReentrantLock?

4. 说下你对 Collection 这个类的理解。

5. 如何理解Java的多态?其中,重载和重写有什么区别?

6. Java的类加载过程

7. String、StringBuilder、StringBuffer

8. JVM内存结构

9. 泛型

10. 项目中Socket是怎么分包、编码的?

11. HashMap的rehash扩容是怎么操作的

12. 数据怎么压缩,数据的安全

13. HashMap的哈希散列实现,线程安全吗,为什么?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章