受 android-interview-questions 项目启发,这里想发挥众多 Android **开发者的力量,整理一份高质量、范围全的 Android 面试指南,旨在帮助更多的 Android 开发者提升技术,找到工作。
现在还是项目初期,项目背景见这里:想跟大家一起做件小事,也欢迎关注微信公众号 stormzhang,后续有任何进展我都会在公号进行通知的。
目前该项目有如下初步的计划:
-
翻译 android-interview-questions 项目,不过翻译仅是我们的第一步而已,这个比较简单,目前第一步翻译工作已经被认领完毕;
-
因为原项目很多只是列了一些问题,但是都没有答案的,所以第二步我们就是认领问题,整理答案,务必保证高质量、易理解,因为问题很多,所以这一步需要花费不少精力,也需要更多的同学参与进来,目前还在第一步阶段;
-
第三步是补充与完善,原项目虽然列了不少领域,但是总归有些遗漏的,比如 Android 安全、插件化、Kotlin 等等,第三步是找在某一领域研究比较深的同学加入进来,对一些领域进行补充、完善,甚至会推出一些专题等;
数据结构与算法问题的难度完全取决于你所申请的公司
-
数组
-
数组由一组相同的数据类型组成。它存储在连续的内存空间内,使用索引可以找到元素的地址。数组包括一维数组和多维数组,一维数组是最简单的数据结构,也是最常用的。
算法 平均 最坏 空间(Space) O(n) O(n) 查找(Search) O(n) O(n) 插入(Insert) O(n) O(n) 删除(Delete) O(n) O(n)
-
-
链表
-
链表看起来更像树,而不是数组,它使用一组结点来表示一个序列。每一个结点都包含数据和一个指针。在链表中,结点中的数据可以为任意类型,而指针则是指向下一结点的引用。链表包含一个头结点和一个尾结点。头结点是链表中的第一个结点,尾结点是最后一个结点。链表不是一个循环数据结构,所以尾结点没有指向头结点的指针,指针为空。一些基础方法的时间复杂度如下:
算法 平均 最坏 空间 (Space) O(n) O(n) 查找 (Search) O(n) O(n) 插入 (Insert) O(1) O(1) 删除 (Delete) O(1) O(1)
-
-
双向链表
-
栈
-
栈是一个有着「后进先出」特性的基础数据结构,这就意味着最后一个入栈的元素,也是第一个出栈的。栈就像是一堆书,想要得到书堆中的第一本书(最下面一本),必须把其他的书都先拿走。向栈中添加一个元素的操作被称为 Push(入栈),删除一个元素的操作被称为 Pop(出栈),查看且不删除最后一个入栈的元素的操作被称为 Top 。实现栈的常用方法是使用链表(LinkedList),也可以使用不允许空值的 StackArray(使用数组实现),还有允许空值的 Vector
算法 平均 最坏 图形表示 空间 (Space) O(n) O(n) 查找 (Search) O(n) O(n) 入栈 (Push) O(1) O(1) 出栈 (Pop) O(1) O(1) 查看栈顶 (Top) O(1) O(1)
-
-
队列
-
优先队列
-
动态编程
-
字符串操作
-
二叉树
-
二叉搜索树
-
排序算法
-
哈希表与哈希图
-
广度优先搜索
-
深度优先搜索
-
贪心算法
-
解释一下 OOP 的概念
-
抽象类和接口的区别?Link
- 抽象类是一个可同时包含具体方法和抽象方法(方法未被实现)的类。抽象方法必须被该抽象类的子类实现。抽象类是可以继承的。
- 接口像是描述类的一张蓝图或者说是类的一种契约,它包含了许多空方法,这代表着它的所有的子类都应该拥有共同点。它的子类应该提供这些空方法的具体实现。一 个类需要用
implements
来实现接口,接口可以用extends
来继承其他接口。
-
序列化是什么?如何实现它?
- 序列化是一种将对象转换为字节流的过程,目的是为了将该对象存储到内存中,等后面再次构建该对象时可以获取到该对象先前的状态及数据信息。Java中,有两种方式可以实现序列化,既可以实现Serializable接口,也可以实现Parcelable接口。然而,在Android中,我们不应该使用Serializable接口。因为Serializable接口使用了反射机制,这个过程相对缓慢,而且往往会产生出很多临时对象,这样可能会触发垃圾回收器频繁地进行垃圾回收。相比而言,Parcelable接口比Serializable接口效率更高,性能方面要高出10x多倍。
-
什么是单例?
- 单例模式指的是一个类只能被初始化一次,即只有一个实例。单例模式限定一个类只能拥有一个实例。这在系统中只需要一个实例来和其他模块协调工作时是很实用的。单例普遍使用在只需要一个或是限制一定数量实例的系统中。
-
什么是匿名内部类?
-
对字符串进行
==
和equals()
操作时有什么区别? -
hashCode()
和equals()
何时使用? -
Java 中的
final
,finally
和finalize
? -
什么是内存泄露,Java 是如何处理它的?
-
垃圾收集器是什么?它是如何工作的
-
所有的对象实例都在JVM管理的堆区域分配内存
只要对象被引用,JVM就会认为它还存活于进程中。
一旦对象不再被引用,就不能被应用程序所访问,
垃圾收集器将删除它并重新声明未使用的内存。
-
-
比较
Arrays
和ArrayLists
。 -
比较
HashSet
和TreeSet
。 -
Java 中的类型转换。
-
方法重载和重写的区别
- 重载发生在编译时,重写发生在运行时。重载方法调用与其定义的绑定发生在编译时,但是重写方法调用与其定义的绑定在运行时发生。
- 静态方法可以重载,意味着一个类可以有多个同名的静态方法。静态方法不能被重写,即使在子类中声明了一个相同的静态方法,它与父类的相同方法无关。
- 最基本的区别是重载是在同一个类中完成的,重写父类需要有子类。重写是给父类的继承方法一个具体的实现。
- 静态绑定用于方法重载,动态绑定用于方法重写。性能:重载比重写更有效率,原因是方法重写的绑定是在运行时完成的。
- 私有方法和用
final
修饰的方法可以重载但不可重写。这意味着一个类可以有多个同名的private/final
方法,子类不能重写父类的private/final
方法。 - 方法重载的情况下不关心返回值类型, 它可以相同,也可以不同。但是方法重写的情况下可以有多个具体的返回值类型。
- 方法重载时参数列表必须不同,方法重写时参数列表必须相同。
-
什么是访问修饰符?它们能做什么?
-
接口可以继承另一个接口吗?
-
Java 中
static
关键字是什么意思? -
Java 中静态方法可以被重写吗?
-
什么是多态?什么是继承?
-
Integer
和int
之间的区别 -
Java 中的对象是否会以引用传递或者值传递?详细说明。
-
什么是 ThreadPoolExecutor? Link
-
本地变量、实例变量以及类变量之间的区别?
-
什么是反射? Link
-
在 Java 中什么是强引用、软引用、弱引用以及虚引用?
-
什么是依赖注入?能说几个依赖注入的库么?你使用过哪些?
-
关键字
synchronized
的作用是什么? -
为什么说
String
不可变的? -
修饰符
transient
和volatile
的作用是什么? -
finalize()
方法的作用是什么? -
异常捕获中的
try{}finally{}
块儿是如何工作的? -
对象的实例化和初始化之间的区别是什么?
-
静态块何时运行?
-
解释一下 Java 中的泛型?
-
StringBuffer
和StringBuilder
的区别在哪里? -
StringBuilder
是怎么避免不可变字符串分配的问题? -
什么是自动装箱和拆箱?
-
枚举和迭代器有什么区别?
-
Java 中 fail-fast 和 fail-safe 的区别?
-
什么是 Java 优先级队列?
-
什么是设计模式 Link
-
阐述一下 Activity 的生命周期。
-
谈谈 Android 的四大组件。
-
Service 与 IntentService 的区别。Link
-
Android 应用的结构是什么?
-
Android 应用中如何保存数据。
-
如何在 Android 应用中执行耗时操作。
-
两个 Fragment 之间如何通信。
-
阐述一下 Android 的通知系统。
-
两个不同的 app 之间如何交互。
-
什么是 Fragment?
-
为什么建议只使用默认的构造方法来创建 Fragment?Link
-
为什么 Bundle 被用来传递数据,为什么不能使用简单的 Map 数据结构?
-
阐述一下 Fragment 的生命周期。Link
-
如何理解 Android 的 Dialog ?
-
解释下 Android 的 View 。
-
你能创建自定义 View 吗?具体是如何创建的?
-
什么是 ViewGroup ,它与 View 的区别在哪里?
-
Fragment 和 Activity 有什么区别?它们之间又有什么关系?
-
谈谈 Serializable 接口和 Parcelable 接口的区别。在 Android 中最好使用哪种接口?
-
Activity 的启动模式有哪些?Link
-
解释一下 Android 中的 Intent 。Link
-
什么是隐式 Intent ?
-
什么是显式 Intent ?
-
解释一下 AsyncTask 。
-
如何理解 Android 中的广播。Link
-
如何理解 Android 的 LocalBroadcastManager 。Link
-
什么是 JobScheduler ?Link
-
什么是 DDMS ?你可以用它来做什么?
-
解释一下什么是 support libary ,以及为什么要引入 support library ?Link
-
如何理解 Android 中的 ContentProvider 。它通常用来干什么?
-
什么是 Data Binding ?Link
-
Android 的核心组件具体都有什么?Link
-
什么是 ADB ?
-
什么是 ANR ?如何避免发生 ANR ?
-
AndroidManifest.xml 是什么?
-
解释一下 broadcast 和 intent 在 app 内传递消息的工作流程。
-
当 Bitmap 占用较多内存时,你是怎么处理的?
-
Android 应用有哪些不同的存储数据的方式?
-
什么是 Dalvik 虚拟机?
-
AsyncTask 的生命周期和(它所属的) Activity 的生命周期有什么关系?这种关系可能会导致什么样的问题? 如何避免这些问题发生?
-
Intent filter 是用来做什么的?
-
什么是 Sticky Intent?Link
-
什么是 AIDL ?列举一下通过 AIDL 创建被绑定的服务(bounded service)的步骤。
-
Android 的权限有多少个不同的保护等级?
-
在转屏时你如何保存 Activity 的状态?Link
-
相对布局和线性布局的区别。
-
如何实现 XML 命名空间?
-
View.GONE 和 View.INVISIBLE 之间的区别。
-
Bitmap 和 .9(nine-patch)图片之间有什么区别?
-
谈谈位图池。Link
-
在 Android 中如何避免内存泄漏?
-
Android 桌面的小部件是什么?
-
什么是 AAPT ?
-
你是如何在 Android 应用程序中发现内存泄漏的?
-
你如何排查应用崩溃的原因?
-
为什么你应该避免在主线程上运行非用户界面相关的代码?
-
你是如何适配不同分辨率的手机的?
-
如何理解 Doze 模式。如何理解应用程序待机模式(App Standby)。
-
在 Android 中,你可以使用什么来进行后台操作?
-
什么是 ORM ?它是如何工作的?
-
什么是 Loader ?
-
什么是 NDK ,为什么它是有用的?
-
如何理解严格模式(StrictMode)。 Link
-
什么是 Lint ?它的用途是什么?
-
什么是 SurfaceView ?
-
ListView 和 RecyclerView 有什么区别?
-
什么是 ViewHolder 模式?为什么我们应该使用它?
-
什么是 PendingIntent ?
-
你能手动调用垃圾回收吗?
-
周期地更新页面的最好方式是什么?
-
有哪些类型的广播?
-
你开发过组件吗?请描述一下。Link
-
如何理解上下文(Context)。怎么使用它?Link
-
你知道什么是视图树(View Tree)吗?怎样优化它的深度?
-
onTrimMemory() 方法是什么?
-
Android 应用可以使用多进程吗?怎样使用?
-
内存溢出(OutOfMemory)是怎么发生的?
-
文本样式接口(Spannable)是什么?
-
什么是过度绘制(overdraw)?
-
什么是渲染脚本(renderscript)?Link
-
Dalvik 虚拟机模式和 ART(Android Runtime)虚拟机模式的区别。
-
FlatBuffers 和 JSON 的区别。Link
-
描述一下约束布局(Constraint Layout)。Link
-
阐述一下 Android 中的 HashMap , ArrayMap 和 SparseArray 。Link
-
阐述一下 Looper, Handler 和 HandlerThread 。Link
-
如何降低 Android 应用的耗电量?Link
-
SnapHelper 是什么?Link
-
在 Android 中怎么处理多点触控?link
-
请介绍一下你做的上一个 App 的架构。
-
请介绍一下 MVP。 Link
-
Presenter 是什么?
-
什么是模型?
-
请介绍一下 MVC。
-
Controller 是什么?
-
请介绍一下 MVVM。 Link
-
谈谈你对代码整洁之道(clean code)的理解。Link
-
请设计 Uber App。
-
请设计 Facebook App。
-
请设计 Facebook Near-By Friends App。
-
请设计 WhatsApp。
-
请设计 SnapChat。
-
基于地理位置 App 的设计问题。
-
Espresso 是什么? Link
-
Robolectric 是什么? Link
-
UI-Automator 是什么? Link
-
请解释一下单元测试。
-
请解释一下设备化测试。
-
你是否做过单元测试或者自动测试?
-
为什么要使用 Mockito? Link
-
请描述一下 JUnit 测试。
-
描述一下 REST APIs 如何工作 ?
-
描述一下 SQLite 。
-
描述一下 数据库 。
-
项目管理工具 - trello ,basecamp ,kanban ,jira ,asana 。
-
关于构建系统 - gradle , ant , buck 。
-
APK 逆向工程 。
-
混淆器用于什么 ?
-
什么是混淆? 用于什么? 如何压缩 ?
-
如何构建你的发布版本的 APP ?
-
如何面向特定用户群体更新应用程序版本 ?
-
可以识别卸载我们的应用程序的用户吗 ?
-
缩小 APK 的体积 。Link
-
Android 开发最佳实践 。Link
-
Android 代码风格和指南 。Link
-
你尝试使用过 Kotlin 吗 ?Link
-
开发 Android 应用程序时应该连续测量哪些指标 ?Link
感谢这些无私的贡献者,排名不分先后。
mengxn、innovatorCL、SmartNJ、Zhiw、lanyuanxiaoyao、934079371、cdevelopr、smartbeng、ikook、mrfanr、androidZzT、qiaojialin、maokai1229、renxuelong、dzx1994
Copyright (C) 2017 stormzhang
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.