想要进入大厂,首先得明白:成功离不开毅力和决心。无论学历、资历如何,只要你有决心并愿意付出时间,总会看到成果。

但除了这些,学习还需要注重效率。互联网上的免费资料虽多,但筛选、整合和实际应用却需要花费大量时间。而且,自己摸索很容易走弯路、踩坑,而且学习内容也可能不够系统。

对于想要进入大厂的开发者来说,基础知识尤为关键。大厂通常深入考察候选人的基础知识,不仅要求了解,还需要深入掌握。因此,仅仅依靠表面的了解很难在面试中脱颖而出。


1. Activity
启动流程
  1. 当启动一个新的Activity时,系统会首先调用onCreate()方法。
  2. 接着调用onStart()onResume()方法,使Activity对用户可见。
onSaveInstanceState() 和 onRestoreInstanceState()
  • onSaveInstanceState(): 当Activity可能不再存在时(如屏幕旋转、用户导航离开等)被调用,用于保存Activity的状态。
  • onRestoreInstanceState(): 在Activity的onCreate()之后被调用,用于恢复之前保存的状态。
启动模式和使用场景
  • Standard: 默认模式,每次启动都会创建新的实例。
  • SingleTop: 如果Activity实例已经在任务栈的顶部,则不会创建新的实例。
  • SingleTask: 创建一个新的任务栈,并在其中启动Activity实例。
  • SingleInstance: 创建一个新的任务栈,且只包含一个Activity实例。
生命周期执行顺序

Activity A -> Activity B: A的onPause()onStop()被调用,B的onCreate()onStart()onResume()被调用。
按返回键:B的onPause()onStop()被调用,A的onRestart()onStart()onResume()被调用。

其他生命周期场景
  • 横竖屏切换:当前Activity会被销毁并重新创建。
  • 按Home键:onPause()onStop()被调用。
  • 锁屏与解锁屏幕:取决于设备实现,可能仅调用onPause()
  • 透明Activity:onCreate()onStart()onResume()正常调用。
  • Dialog Theme的Activity:与普通Activity相同。
  • 弹出Dialog:不影响Activity的生命周期。
onStart() 和 onResume()、onPause() 和 onStop() 的区别
  • onStart(): Activity对用户不可见,但已加载。
  • onResume(): Activity对用户可见,且可以与用户交互。
  • onPause(): Activity对用户仍可见,但即将变为不可见。
  • onStop(): Activity不再对用户可见。
传递数据
  • Intent: 用于在Activity之间传递数据,大小有限制(约1MB)。
  • 解决方案:使用Bundle、Serializable、Parcelable或数据库、文件存储等方式。
onNewIntent()
  • 当Activity已存在,并且再次接收到与其相同的Intent时调用。
显示启动和隐式启动
  • 显示启动:明确指定要启动的Activity。
  • 隐式启动:基于Intent中的action和category来匹配要启动的Activity。
Scheme使用场景
  • 用于定义自定义的URI格式,如myapp://path/data
ANR
  • 应用程序无响应,通常由于主线程长时间运行导致。
onCreate和onRestoreInstance
  • onCreate(): 在Activity首次创建时调用。
  • onRestoreInstance(): 在Activity重新创建后用于恢复状态。
跨App启动Activity
  • 使用Intent并设置相应的flag。
Activity任务栈
  • 存放Activity实例的栈结构。
Flags
  • FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TOP等。
数据保存与恢复
  • 使用Bundle保存和恢复数据。
  • 进程被Kill后,数据从Bundle中恢复。
2. Service
生命周期
  • 创建、启动、绑定、销毁。
两种启动方式
  • startService(): 启动Service,即使客户端解绑,Service仍运行。
  • bindService(): 绑定Service到客户端,当客户端解绑时,Service可能销毁。
通信
  • 使用Messenger、AIDL、LocalBinder等方式。
IntentService
  • 用于在后台执行异步任务,处理完所有Intent后自动结束。
onStartCommand返回值
  • START_NOT_STICKYSTART_STICKYSTART_REDELIVER_INTENT
bindService和startService混合使用
  • 可以同时使用,但需要注意生命周期和绑定状态。
3. BroadcastReceiver
分类和使用场景
  • 粘性广播、非粘性广播。
  • 用于接收系统或其他应用发送的广播。
注册方式
  • 动态注册:在代码中注册和注销。
  • 静态注册:在AndroidManifest.xml中注册。
原理
  • BroadcastReceiver接收来自Intent的广播。
4. ContentProvider

ContentProvider 是 Android 中用于实现数据共享的一种组件,它可以让不同的应用程序之间共享数据。数据通常以表格的形式组织,类似于数据库的表。其他应用程序可以通过 ContentResolver 来查询或修改这些数据。

ContentProvider、ContentResolver、ContentObserver 的关系:

  • ContentProvider:提供数据访问的接口。
  • ContentResolver:用于从 ContentProvider 中获取和修改数据,它是应用程序与 ContentProvider 之间的桥梁。
  • ContentObserver:用于监听ContentProvider中的数据变化,当数据发生变化时,会通知注册的观察者。

ContentProvider 的实现原理:

ContentProvider 的实现主要基于数据库,如 SQLite,来存储和管理数据。当其他应用通过 ContentResolver 访问数据时,ContentProvider 会处理这些请求,如查询、插入、更新和删除数据。

ContentProvider 的优点:

  • 数据共享:允许不同的应用程序共享数据。
  • 安全性:提供了一套权限控制机制,确保只有具有相应权限的应用程序才能访问数据。
  • 统一接口:所有 ContentProvider 都遵循相同的接口规范,使得应用程序能够以一种统一的方式访问不同来源的数据。

Uri (统一资源标识符):

Uri 是用于唯一标识资源(如文件、网页、数据库记录等)的字符串。在 Android 中,Uri 常用于标识 ContentProvider 中的数据。例如,一个 Uri 可能表示一个特定的数据库记录或一组记录。

5. Handler

Handler 的实现原理:

Handler 的工作原理基于 Looper 和 MessageQueue。当一个消息(Message)被发送到 Handler 时,Handler 会将这个消息放入与当前线程关联的 MessageQueue 中。Looper 是一个无限循环,它会不断从 MessageQueue 中取出消息并分发给相应的 Handler 进行处理。

子线程中能否直接创建 Handler:

在子线程中不能直接创建 Handler,因为子线程默认没有 Looper。只有主线程(UI线程)在启动时会自动创建 Looper。如果需要在子线程中使用 Handler,需要先手动为子线程创建 Looper。

主线程的 Looper 第一次调用 loop 方法的时间和类:

主线程的 Looper 在 Android 应用程序启动时由 ActivityThread 类创建,并在主线程的 run 方法中调用 Looper.loop() 方法开始运行。

Handler 导致的内存泄露原因及其解决方案:

Handler 导致的内存泄露通常是因为 Handler 持有 Activity 或其他 Context 的引用,而这个 Handler 又被其他长生命周期的对象(如静态变量、线程等)持有。当 Activity 被销毁时,由于 Handler 仍然持有其引用,导致 Activity 无法被垃圾回收器回收,从而造成内存泄露。

解决方案通常包括:

  • 使用静态内部类 + 弱引用(WeakReference):将 Handler 放在一个静态内部类中,并使用弱引用持有 Context,这样即使 Handler 被其他对象持有,也不会阻止 Context 被回收。
  • 及时移除回调和消息:确保在 Activity 销毁时,移除所有与 Handler 相关的回调和消息,避免在 Activity 销毁后还尝试访问它。

一个线程可以有几个 Handler、Looper、MessageQueue 对象:

一个线程只能有一个 Looper 和一个 MessageQueue。但是一个线程可以有多个 Handler,因为每个 Handler 都有自己的 Message 队列和回调接口,但它们都共享同一个 Looper 和 MessageQueue。

Message 对象的创建方式及区别:

Message 对象可以通过两种方式创建:直接 new 一个 Message 对象,或者调用 Message.obtain() 方法。直接使用 new 创建 Message 会导致频繁的对象分配和垃圾回收,影响性能。而 Message.obtain() 方法会从 MessagePool(消息池)中复用 Message 对象,减少内存分配和垃圾回收的开销。

Message.obtain() 如何维护消息池:

Message.obtain() 方法会首先从 MessagePool 中获取一个已经被回收的 Message 对象(如果存在的话)。如果没有可用的对象,它会创建一个新的 Message。当一个 Message 被处理完毕后,它的 recycle() 方法会被调用,将 Message 返回到 MessagePool 中供下次使用。

Handler 的发送消息方法:

Handler 有多种发送消息的方法,包括 sendMessage()、sendMessageDelayed()、sendEmptyMessage()、sendEmptyMessageDelayed() 等。这些方法的主要区别在于是否延迟发送消息以及是否携带数据。

post 与 sendMessage 的区别和应用场景:

post() 方法用于在主线程中执行 Runnable 对象,而 sendMessage() 方法用于发送一个 Message 对象到 MessageQueue 中。post() 方法通常用于执行简单的任务,而 sendMessage() 方法更适合于需要传递数据和延迟执行的任务。

handler postDelayed 后消息队列的变化:

当使用 postDelayed() 方法发送一个消息时,这个消息会被放入 MessageQueue 中,并根据指定的延迟时间排序。


目录

金三银四Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!_android

第一章 Java方面
  • Java基础部分
  • Java集合
  • Java多线程
  • Java虚拟机

金三银四Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!_面试_02

第二章 Android方面
  • Android四大组件相关
  • Android异步任务和消息机制
  • Android UI绘制相关
  • Android性能调优相关
  • Android中的IPC
  • Android系统SDK相关
  • 第三方框架分析
  • 综合技术
  • 数据结构方面
  • 设计模式
  • 计算机网络方面
  • Kotlin方面

金三银四Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!_ide_03

第三章 音视频开发高频面试题
  • 为什么巨大的原始视频可以编码成很小的视频呢?这其中的技术是什么呢?
  • 怎么做到直播秒开优化?
  • 直方图在图像处理里面最重要的作用是什么?
  • 数字图像滤波有哪些方法?
  • 图像可以提取的特征有哪些?
  • 衡量图像重建好坏的标准有哪些?怎样计算?

金三银四Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!_ide_04

第四章 Flutter高频面试题
  • Dart部分
  • Flutter部分

金三银四Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!_android_05

第五章 算法高频面试题
  • 如何高效寻找素数
  • 如何运用二分查找算法
  • 如何高效解决雨水问题
  • 如何去除有序数组的重复元素
  • 如何高效进行模幂运算
  • 如何寻找最长回文子串

金三银四Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!_Android_06

第六章 Andrio Framework方面
  • 系统启动流程面试题解析
  • Binder面试题解析
  • Handler面试题解析
  • AMS面试题解析

金三银四Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!_职场和发展_07