🔥 原文地址:https://www.yundashi168.com/154.html 🔥 关注原文地址,可以获得最新最全的Android面试知识点更新情况,技术路上你不孤单。
🔥 个人归纳的中高级Android面试知识点全方面汇总+长期更新+QQ技术群交流(151909524)🔥
基础篇
Java基础
Java集合
- ArrayList
- HashMap (重点)
- LinkedList
- ConcurrentHashMap (重点)
- LinkedHashMap (重点)
- BlockingQueue
ArrayList和LinkedList的区别
Arraylist 底层是基于动态数组,根据下表随机访问数组元素的效率高,向数组尾部添加元素的效率高;但是,删除数组中的数据以及向数组中间添加数据效率低,因为需要移动数组。例如最坏的情况是删除第一个数组元素,则需要将第2至第n个数组元素各向前移动一位。而之所以称为动态数组,是因为Arraylist在数组元素超过其容量大,Arraylist可以进行扩容(针对JDK1.8? 数组扩容后的容量是扩容前的1.5倍) Linkedlist 基于链表的动态数组,数据添加删除效率高,只需要改变指针指向即可,但是访问数据的平均效率低,需要对链表进行遍历。基于链表的动态数组,数据添加删除效率高,只需要改变指针指向即可,但是访问数据的平均效率低,需要对链表进行遍历。
推荐阅读:
Java并发
Java反射
反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。
Java泛型
Java虚拟机
JVM常见面试题
- Java虚拟机(JVM)面试题(2020最新版)
- JVM 面试题汇总
- JVM方法区存储内容 是否会动态扩展 是否会出现内存溢出 出现的原因有哪些。
- 如何解决同时存在的对象创建和对象回收问题?
- JVM中最大堆大小有没有限制?
- Java运行时数据区域,导致内存溢出的原因。
- java中一个对象从创建到销毁的过程和 JVM类加载过程
https://blog.csdn.net/m0_37914467/article/details/106441824
JVM内存结构
双亲委派模型
Android基础
Activity知识点(必问)
- Activity启动过程全解析
- 启动模式以及使用场景
- onSaveInstanceState以及onRestoreInstanceState使用
- onConfigurationChanged使用以及问题解决
Fragment知识点
推荐阅读:
- Fragment全解析系列(一):那些年踩过的坑
- Google-Fragment概览
- Google-与其他Fragment通信
Service知识点
Handler知识点(必问)
Handler Looper Message 关系是什么? Messagequeue 的数据结构是什么?为什么要用这个数据结构? 如何在子线程中创建 Handler? Handler post方法原理? Handler消息机制,postDelayed会造成线程阻塞吗?对内存有什么影响? 当访问大量数据出现线程租塞用什么技术解决? Handler机制是如何进行线程切换的? 答:这里先大致解释下,当Looper的loop方法被调用的时候,Looper会从MessageQueue中取出单链表中第一个msg(Message对象),之后会执行msg.target.dispatchMessage(msg),这个msg中有个target对象,然后target对象里有个dispatchMessage方法,dispatchMessage方法又会调用handleMessage,这时候机智的你肯定意识到了这个target其实就是Handler对象,其实这还不是重点,线程切换的重点在于loop方法是在线程A中执行的,所以即便消息是在线程B产生的,由于loop方法执行在线程A中,所以handleMessage方法也就执行在了线程A中,如果A是主线程,handleMessage方法也就回调在主线程了。
推荐阅读:
Intent知识点
数据存储
文件和数据库哪个效率高?
UI控件篇
事件分发(重点)
自定义View
屏幕适配
- dp+自适应布局+weight比例布局直接适配
- 今日头条适配方式
- 宽高限定符适配方式
- smallestWidth适配
推荐阅读:
主要控件优化
RecyclerView优化
嵌套滚动
动态页面
电商类的APP使用居多
网络通信篇
网络协议
- http与https的区别
- 谈谈你对socket的理解和认识
- TCP和UDP的区别及应用场景
- 对称加密与非对称加密算法
- WebSocket协议原理
- 谈谈MQTT协议
推荐阅读:
网络安全
架构设计篇
MVP架构设计
组件化架构
业务大了代码多了会用到。 为什么要用组件化? 组件之间如何通信? 组件之间如何跳转?
设计模式
1.装饰者模式,代理模式,适配器,桥接模式有什么区别?
性能优化篇
【面试重点】性能优化:包括启动优化(主要是冷启动)、内存优化、绘制优化、稳定性优化、安装包体积优化等,优化是面试的重中之重。 你在开发中是如何做性能优化的?
启动优化
内存优化
常见的内存泄露有:
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也需要及时移除
而对于内存泄露的检测,常用的工具有LeakCanary、MAT(Memory Analyer Tools)、Android Studio自带的Profiler。
绘制优化
什么情况下使用 ViewStub、include、merge? 他们的原理是什么?
安装包优化
稳定性优化
源码流程篇
开源库源码分析
RxJava的实现原理,它是如何实现线程的控制? Retrofit的框架结构是什么?底层是怎么实现的? 网络框架是如何搭建?okhttp的底层实现是什么,和Retrofit有什么不同? 图片加载框架gilde、Picasso、fresco有什么不同,各自的实现原理是什么?如何搭建一个网络框架?
Glide源码分析
【面试题】 Glide的优点有哪些? Glide的缓存原理是什么?
Glide的优点主要包括:
- 多种图片格式的缓存,适用于更多的内容表现形式(如Gif、WebP、缩略图、Video)
- 生命周期集成(根据Activity或者Fragment的生命周期管理图片加载请求)Glide可以感知调用页面的生命周期,这就是优势
- 高效处理Bitmap(bitmap的复用和主动回收,减少系统回收压力)
- 高效的缓存策略,灵活(Picasso只会缓存原始尺寸的图片,Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式的不同,使得内存开销是Picasso的一半)
LeakCanary源码分析
OkHttp源码分析
【面试问题】
1.如何使用OkHttp进行异步网络请求,并根据请求结果刷新UI? 2.可否介绍一下OkHttp的整个异步请求流程? 3.OkHttp对于网络请求都有哪些优化,如何实现的? 4.OkHttp框架中都用到了哪些设计模式? 5.OKHttp有哪些拦截器,分别起什么作用? 6.OkHttp怎么实现连接池? 7.Okhttp 有哪些优势?
推荐阅读:
Okhttp优势:
1)支持http2,对一台机器的所有请求共享同一个socket 2)内置连接池,支持连接复用,减少延迟 3)支持透明的gzip压缩响应体 4)通过缓存避免重复的请求 5)请求失败时自动重试主机的其他ip,自动重定向 6)丰富的API,可扩展性好
Retrofit源码分析
RxJava源码分析
理解源码之前需要先了解一些RXJava基本知识
RxJava原理与源码分析
RxJava如何进行线程切换的?
Rxjava内存泄漏防止方案——RxLifecycle,AutoDispose,RxLife框架
Tinker源码分析
ARouter源码分析
[v_tips]
路由框架原理:ARouter 【官方文档】 【ARouter:现在模块化(组件化)算是比较常见的开发模式了,尤其是在大厂,所以有必要知道ARouter的实现原理,2个模块之间是怎样实现的页面跳转,以及ARouter为了优化性能做了哪些工作】 核心要点:将Route注解中的path地址和Activity.class文件的映射关系保存到它自己生成的java文件的map中 隐式跳转方案,但是一个项目中不可能所有的跳转都是隐式的,这样Manifest文件会有很多过滤配置,而且非常不利于后期维护。 反射跳转方案:需要拿到Activity的类文件,在组件开发的时候,想拿到其他module的类文件是很麻烦的,因为组件开发的时候组件module之间是没有相互引用的,你只能通过找到类的路径去反射拿到这个class。大量的使用反射跳转对性能会有影响。 APT是Annotation Processing Tool的简称,即注解处理工具。apt是在编译期对代码中指定的注解进行解析,然后做一些其他处理(如通过javapoet生成新的Java文件
[/v_tips]
Android框架层源码解析
Activity启动流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cdF5Tfo1-1629603357517)(https://i.loli.net/2021/04/13/6fFx4ehprUEHYD9.jpg)]
- 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
- system_server进程接收到请求后,向zygote进程发送创建进程的请求;
- Zygote进程fork出新的子进程,即App进程;
- App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
- system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
- App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
- 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。
推荐阅读:
Service启动流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T56Bnqyt-1629603357519)(https://i.loli.net/2021/04/13/RLAGa6ShBVYeQyW.jpg)]
启动流程:
- Process A进程采用Binder IPC向system_server进程发起startService请求;
- system_server进程接收到请求后,向zygote进程发送创建进程的请求;
- zygote进程fork出新的子进程Remote Service进程;
- Remote Service进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
- system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向remote Service进程发送scheduleCreateService请求;
- Remote Service进程的binder线程在收到请求后,通过handler向主线程发送CREATE_SERVICE消息;
- 主线程在收到Message后,通过发射机制创建目标Service,并回调Service.onCreate()方法。
推荐阅读:
事件分发机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n1YDap2E-1629603357522)(https://i.loli.net/2021/04/14/qHsYLBfCXx63SKW.jpg)]
onInterceptTouchEvent 返回值true表示事件拦截, onTouch/onTouchEvent 返回值true表示事件消费。- 触摸事件先交由
Activity.dispatchTouchEvent 。再一层层往下分发,当中间的ViewGroup都不拦截时,进入最底层的View 后,开始由最底层的OnTouchEvent 来处理,如果一直不消费,则最后返回到Activity.OnTouchEvent 。 ViewGroup 才有onInterceptTouchEvent 拦截方法。在分发过程中,中间任何一层ViewGroup都可以直接拦截,则不再往下分发,而是交由发生拦截操作的ViewGroup的OnTouchEvent来处理。- 子View可调用requestDisallowInterceptTouchEvent方法,来设置disallowIntercept=true,从而阻止父ViewGroup的onInterceptTouchEvent拦截操作。
- OnTouchEvent由下往上冒泡时,当中间任何一层的OnTouchEvent消费该事件,则不再往上传递,表示事件已处理。
- 如果View没有消费ACTION_DOWN事件,则之后的ACTION_MOVE等事件都不会再接收。
- 只要View.onTouchEvent是可点击或可长按,则消费该事件.
- onTouch优先于onTouchEvent执行,上面流程图中省略,onTouch的位置在onTouchEvent前面。当onTouch返回true,则不执行onTouchEvent,否则会执行onTouchEvent。onTouch只有View设置了OnTouchListener,且是enable的才执行该方法。
推荐阅读:
Java层源码解析
HashMap底层实现,它和LinkHashMap有什么区别?
算法设计
理论知识
数据结构
刷题资料
- hello-algorithm | 在线阅读:hello-algorithm | 「算法面试+算法知识」针对小白的算法训练。小浩算法是一套针对小白的完整的算法训练流程!
- 十大排序算法 | 在线阅读:bookstack.cn | 一本关于排序算法的 GitBook 在线书籍 《十大经典排序算法》,使用 JavaScript & Python & Go & Java 实现。 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。
- Leetcode 前 300 题算法题解析(Java) | bookstack.cn
新技术篇
Jetpack
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h7Tnq2C6-1629603357525)(https://i.loli.net/2021/08/03/scTDSQU3dZK1YFa.jpg)]
Jetpack架构组件
Android Architecture Components的核心是Lifecycle、LiveData、ViewModel 以及 Room,通过它可以非常优雅的让数据与界面进行交互,并做一些持久化的操作,高度解耦,自动管理生命周期,而且不用担心内存泄漏的问题。
- Room 一个强大的SQLite对象映射库。
- ViewModel 一类对象,它用于为UI组件提供数据,在设备配置发生变更时依旧可以存活。
- LiveData 一个可感知生命周期、可被观察的数据容器,它可以存储数据,还会在数据发生改变时进行提醒。
- Lifecycle 包含LifeCycleOwer和LifecycleObserver,分别是生命周期所有者和生命周期感知者。
Android Architecture Components的特点
- 数据驱动型编程 变化的永远是数据,界面无需更改。
- 感知生命周期,防止内存泄漏。
- 高度解耦 数据,界面高度分离。
- 数据持久化 数据、ViewModel不与UI的生命周期挂钩,不会因为界面的重建而销毁。
推荐阅读:
实战问题篇
权限处理
主题换肤
Socket粘包半包
面试篇
🔥
开源笔记
面试文献
Java基础
Android
个人面经
面试题目
跳槽攻略
社区网站篇
|