是的,阿里P7,腾讯T4,字节跳动总监都是你家亲戚!!!都在帮你们整理资料

58 阅读13分钟

Android 方面需要掌握的有:APP 启动原理,想要详细了解的可以看我的另一篇 chat (APP 启动原理及启动优化详解 )、图片压缩与性能优化、自定义 view 、事件分发流程、屏幕适配、组件化和插件化、Glide 的缓存与复用、OkHttp 的责任链与连接池、序列化与反序列化、分析一个你最熟练框架的源码等等。可以看到,对于两到三年的程序员来说不仅掌握的知识点更多,而且还需要对原理有一定的了解。

二.面试经历分享,大厂和小厂的区别

大厂面试经历

本人刚出来找工作的时候面试了很多家,那时候是移动开发的爆发时期,其中有腾讯等中大型公司也有一些刚创业的小公司,当然大厂最终面试失败了。记得去腾讯面试的时候,去面试的人特别的多,需要在大厅等待,一批一批的去面试,先是群面,了解基本情况过后,就是单独面谈等待面试,总共三轮面试,面试官会通知面试结果出来的时间。

面试官提到的问题有:为什么从上一家离职、如何看待我们公司、自己以后的职业规划是什么、技术方面问了启动优化怎么优化?跨进程传递大内存数据如何做?主线程等待所有线程执行完毕,再执行某个特定任务怎么实现?原理和源码看过没?你写的 rxpay 和 rxlogin 具体怎么实现的?

大小厂考察点的区别

  • 大厂:

流程比较多,一般会有三面以上,首先会有一套面试题等着你,当然不是所有公司都有面试题,只不过大厂有面试题的概率会高些,其次技术主管面试,然后技术经理面试,人事会跟你介绍公司的发展业务公司福利工作时间等等。大厂的开发一般是分模块开发,每个人单独负责某一个模块,所以要求你要有自己的优势点,比如你会写自定义组件,视频模块,对 NDK 深有研究等等。

  • 小厂:

流程少,有可能一面过了就叫你来上班了。小公司面试一定要问清楚工资什么时候发,月初发说明公司资金充足,月中旬发是正常的,如果月末才发的话公司资金紧张很可能出现财务危机。还有五险一金有没有,有的话试用期有没有,目前还有一部分公司没有五险一金的,而且大部分公司试用期不交五险一金。关于五险一金的重要性大家可以去百度搜一搜,限购令出来后这个更加重要了。

关于技术方面的区别就是,小公司一般都是一个人开发,要求你知道整个项目的开发流程,但是对于技术深度要求不高(仅仅对于初级程序员来说,高级架构师就另说了)。面试之前多准备些项目去演示,有些人说懂技术的都不看作品的,但是对于小公司就不同了,有可能面试你的是产品经理、后台人员等等,对安卓了解的也不是很深,这时候有几个好的作品演示一定会给你的面试加不少分。

三.安卓面试常问的知识点解析

以下五个问题本人面试的时候都被问到过,也作为面试官考察过别人,算是比较有代表性的题目。

Activity之间的通信方式

1)通过Intent方式传递参数跳转

2)通过广播方式

3)通过接口回调方式

4)借助类的静态变量或全局变量

5)借助SharedPreference或是外部存储,如数据库或本地文件

请介绍下 Android 的数据存储方式

使用 SharedPreferences 存储数据;文件存储数据;SQLite 数据库存储数据;使用 ContentProvider 存储数据;网络存储数据。

Preference,File, DataBase 这三种方式分别对应的目录是 /data/data/Package Name/Shared_Pref, /data/data/Package Name/files, /data/data/Package Name/database 。

  • 使用 SharedPreferences 存储数据

首先说明 SharedPreferences 存储方式,它是 Android 提供的用来存储一些简单配置信息的一种机制,例如:登录用户的用户名与密码。其采用了 Map 数据结构来存储数据,以键值的方式存储,可以简单的读取与写入,具体实例如下:

void ReadSharedPreferences(){String strName,strPassword;SharedPreferences user = getSharedPreferences(“user_info”,0);strName = user.getString(“NAME”,””);strPassword = user getString(“PASSWORD”,””);}void WriteSharedPreferences(String strName,String strPassword){SharedPreferences user = getSharedPreferences(“user_info”,0);uer.edit();user.putString(“NAME”, strName);user.putString(“PASSWORD” ,strPassword);user.commit();}

数据读取与写入的方法都非常简单,只是在写入的时候有些区别:先调用 edit() 使其处于编辑状态,然后才能修改数据,最后使用 commit() 提交修改的数据。实际上 SharedPreferences 是采用了 XML 格式将数据存储到设备中,在 DDMS 中的 File Explorer 中的 /data/data//shares_prefs 下。使用 SharedPreferences 是有些限制的:只能在同一个包内使用,不能在不同的包之间使用。

  • 文件存储数据

文件存储方式是一种较常用的方法,在 Android 中读取/写入文件的方法,与 Java 中实现 I/O 的程序是完全一样的,提供了 openFileInput() 和openFileOutput() 方法来读取设备上的文件。具体实例如下:

String fn = “moandroid.log”;FileInputStream fis = openFileInput(fn);FileOutputStream fos = openFileOutput(fn,Context.MODE_PRIVATE);

  • 网络存储数据

网络存储方式,需要与 Android 网络数据包打交道,关于 Android 网络数据包的详细说明,请阅读 Android SDK 引用了 Java SDK 的哪些package?。

activity的启动模式有哪些?是什么含义?

在 Android 里,有 4 种 activity 的启动模式,分别为:

“standard” (默认)

“singleTop”

“singleTask”

“singleInstance”

它们主要有如下不同:

  • 如何决定所属 task

“standard” 和 ”singleTop” 的 activity 的目标 task,和收到的 Intent 的发送者在同一个 task 内,除非 intent 包括参数 FLAG_ACTIVITY_NEW_TASK。

如果提供了 FLAG_ACTIVITY_NEW_TASK 参数,会启动到别的 task 里。

“singleTask” 和 ”singleInstance” 总是把 activity 作为一个 task 的根元素,他们不会被启动到一个其他 task 里。

  • 是否允许多个实例

“standard” 和 ”singleTop” 可以被实例化多次,并且存在于不同的 task 中,且一个 task 可以包括一个 activity 的多个实例。

“singleTask” 和 ”singleInstance” 则限制只生成一个实例,并且是 task 的根元素。 singleTop 要求如果创建 intent 的时候栈顶已经有要创建的 Activity的实例,则将 intent 发送给该实例,而不发送给新的实例。

  • 是否允许其它 activity 存在于本 task 内

“singleInstance” 独占一个 task,其它 activity 不能存在那个 task 里;如果它启动了一个新的 activity,不管新的 activity 的 launch mode 如何,新的activity 都将会到别的 task 里运行(如同加了 FLAG_ACTIVITY_NEW_TASK参数)。

而另外三种模式,则可以和其它 activity 共存。

  • 是否每次都生成新实例

“standard” 对于没一个启动 Intent 都会生成一个 activity 的新实例。

“singleTop” 的 activity 如果在 task 的栈顶的话,则不生成新的该 activity 的实例,直接使用栈顶的实例,否则,生成该 activity 的实例。

比如现在 task 栈元素为 A-B-C-D(D在栈顶),这时候给 D 发一个启动 intent,如果 D 是 “standard” 的,则生成 D 的一个新实例,栈变为 A-B-C-D-D。

如果 D 是 singleTop 的话,则不会生产 D 的新实例,栈状态仍为 A-B-C-D。

如果这时候给 B 发 Intent 的话,不管 B 的 launchmode 是 ”standard” 还是 “singleTop” ,都会生成 B 的新实例,栈状态变为 A-B-C-D-B。

“singleInstance” 是其所在栈的唯一 activity,它会每次都被重用。

“singleTask” 如果在栈顶,则接受 intent,否则,该 intent 会被丢弃,但是该 task 仍会回到前台。

当已经存在的 activity 实例处理新的 intent 时候,会调用 onNewIntent() 方法 如果收到 intent 生成一个 activity 实例,那么用户可以通过 back 键回到上一个状态;如果是已经存在的一个 activity 来处理这个 intent 的话,用户不能通过按 back 键返回到这之前的状态。

说说ContentProvider、ContentResolver、ContentObserver 之间的关系

ContentProvider实现各个应用程序间数据共享,用来提供内容给别的应用操作。如联系人应用中就使用了ContentProvider,可以在自己应用中读取和修改联系人信息,不过需要获取相应的权限。它也只是一个中间件,真正的数据源是文件或SQLite等。 ContentResolver内容解析者,用于获取内容提供者提供的数据,通过ContentResolver.notifyChange(uri)发出消息 ContentObserver内容监听者,可以监听数据的改变状态,观察特定Uri引起的数据库变化,继而做一些相应的处理,类似于数据库中的触发器,当ContentObserver所观察的Uri发生变化时,便会触发它。

注册广播有几种方式,这些方式有何优缺点?请谈谈 Android 引入广播机制的用意。

首先写一个类要继承 BroadcastReceiver

第一种:在清单文件中声明,添加

第二种使用代码进行注册如

两种注册类型的区别是:

  1. 第一种不是常驻型广播,也就是说广播跟随程序的生命周期;

  2. 第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

目前主流框架的分享,如何快速上手项目

================================================================================

搭建项目的主流框架集

Dagger2+RxJava+Retrofit+MVP 是本人目前用的框架集,目前使用的很广泛, 四个相结合,组成项目的优美整体架构。 需要导入的包

dependencies { // 网络请求 compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:adapter-rxJava:2.0.1' compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4' compile 'com.squareup.retrofit2:converter-scalars:2.0.0-beta4' compile 'com.squareup.okhttp3:okhttp:3.2.0' // 注解 compile 'com.google.dagger:dagger:2.0.2' apt 'com.google.dagger:dagger-compiler:2.0.2' provided 'org.glassfish:Javax.annotation:10.0-b28' compile 'com.jakewharton:butterknife:7.0.1' // Rx compile 'io.reactivex:rxandroid:1.1.0' compile 'io.reactivex:rxJava:1.1.5' }

下面是 MVP 的架构图

如上图所示

View 与 Model 并不直接交互,而是使用 Presenter 作为 View 与 Model 之间的桥梁。

其中 Presenter 中同时持有 view 层以及 Model 层的 Interface 的引用,View 层持有 Presenter 层 Interface 的引用。当 View 层某个界面需要展示某些数据的时候,首先会调用 Presenter 层的某个接口,然后 Presenter 层会调用 Model 层请求数据。

当 Model 层数据加载成功之后会调用 Presenter 层的回调方法通知 Presenter 层数据加载完毕。

最后 Presenter 层再调用 View 层的接口将加载后的数据展示给用户。这就是 MVP 模式的整个核心过程,如果你是面试初级安卓开发,面试官应该只会让你阐述下整个调用过程,只要你能流畅的说完整个过程应该差不多了。

Dagger2 的流程图

什么是 Dagger2

Dagger2 是一个依赖注入框架,butterknife 也是一个依赖注入框架。不过 butterknife,最多叫奶油刀,Dagger2 被叫做利器啊,他的主要作用,就是对象的管理,其目的是为了降低程序耦合。

Dagger2 的优点

  • 全局对象实例的简单访问方式

和 ButterKnife 库定义了view,事件处理以及资源的引用一样,Dagger2 提供全局对象引用的简易访问方式。声明了单例的实例都可以使用 @inject 进行访问。比如下面的 MyTwitterApiClient 和SharedPreferences 的实例:

public class MainActivity extends Activity { @Inject MyTwitterApiClient mTwitterApiClient; @Inject SharedPreferences sharedPreferences; public void onCreate(Bundle savedInstance) { // assign singleton instances to fields InjectorClass.inject(this); }

  • 复杂的依赖关系只需要简单的配置

Dagger2 会通过依赖关系并且生成易懂易分析的代码。以前通过手写的大量模板代码中的对象引用将会由它给你创建并传递到相应对象中。因此你可以更多的关注模块中构建的内容而不是模块中的对象实例的创建顺序。

  • 让单元测试和集成测试更加方便

因为依赖关系已经为我们独立出来,所以我们可以轻松的抽取出不同的模块进行测试。依赖的注入和配置独立于组件之外。因为对象是在一个独立、不耦合的地方初始化,所以当注入抽象方法的时候,我们只需要修改对象的实现方法,而不用大改代码库。依赖可以注入到一个组件中:我们可以注入这些依赖的模拟实现,这样使得测试更加简单。

  • 作用域实例(Scoped instances)

我们不仅可以轻松的管理全局实例对象,也可以使用 Dagger2 中的 scope 定义不同的作用域。(比如根据 user session、activity 的生命周期)

  • 什么是 Retrofit

Retrofit 是 Square 开发的一个 Android 和 Java 的 REST 客户端库。这个库非常简单并且具有很多特性,相比其他的网络库,更容易让初学者快速掌握。

  • 怎样创建 Retrofit 实例

创建 Retrofit 实例时需要通过 Retrofit.Builder,并调用 baseUrl 方法设置 URL。

接口定义

以获取时间列表为例

public interface TimeService {> @GET("getTimes?") Call< ResponseBody > getTimes (@Query("month") String month);}

注意,这里是 interface 不是 class,所以我们是无法直接调用该方法,我们需要用 Retrofit 创建一个 TimeService 的代理对象。

TimeService timeService= createRetrofit().create(TimeService .class);

接口调用

Call mService= timeService.getTimes ("1"); mService.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { try { Log(response.body().string()); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); } });

如何快速理解项目进行二次开发

当我们进入一个新公司工作,有可能接手的不是一个新项目而是维护别人开发的项目,面对庞大的项目不知从何下手。在这里我要告诉大家的是,拿到项目的时候不要盲目的进行开发而是阅读项目源码。阅读源码首先浏览项目结构,

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

上面分享的腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

Android学习PDF+学习视频+面试文档+知识点笔记

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

【Android高级架构视频学习资源】