最后我想说
为什么很多程序员做不了架构师?
1、良好健康的职业规划很重要,但大多数人都忽略了
2、学习的习惯很重要,持之以恒才是正解。
3、编程思维没能提升一个台阶,局限在了编码,业务,没考虑过选型、扩展
4、身边没有好的架构师引导、培养。所处的圈子对程序员的成长影响巨大。
金九银十面试季,跳槽季,整理面试题已经成了我多年的习惯!在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
“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
第一种:在清单文件中声明,添加
第二种使用代码进行注册如
两种注册类型的区别是:
-
第一种不是常驻型广播,也就是说广播跟随程序的生命周期;
-
第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
================================================================================
搭建项目的主流框架集
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🗡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(); } });
如何快速理解项目进行二次开发
当我们进入一个新公司工作,有可能接手的不是一个新项目而是维护别人开发的项目,面对庞大的项目不知从何下手。在这里我要告诉大家的是,拿到项目的时候不要盲目的进行开发而是阅读项目源码。阅读源码首先浏览项目结构,
通过这张结构图可以了解项目用的是 MVP 架构,有两个 lib 一个和 service 有关 一个和图片处理有关。然后再阅读 build.gradle 文件,里面有项目中用到的第三方库的引用地址,知道项目中用到了哪些技术,如果有不熟悉的第三方库就可以根据这个地址去查找资源熟悉调用方式项目中用到的模块,日后逐渐研究库的源码以及实现原理。等这些了解的差不多了,再看一看需求文档和设计图,对着需求走一遍流程,主要记录 activity 之间的跳转,可以画一张类之间跳转的结构图,这样整个跳转的逻辑会更清晰。
还有两个值得阅读的是:项目中的工具类和封装的组件。相信不少人遇到过,在网上找了很久的一个处理数据的方法,过了很多天发现项目的工具类中有直接就可以拿来用。封装的组件也和工具类似可以直接拿来用的,在后面的开发也提倡大家将项目组件化。
=======================================================================
腾讯地图
-
算法:非递归实现二叉树前序遍历;
-
手写:双重检查单例类(其中volatile关键字作用)
-
GreenDao底层实现
-
binder用处和原理
-
messager用处和原理
-
Android中的内存泄露
-
oom原因及如何定位
-
如何降低程序崩溃率
-
okhttp源码理解,使用拦截器的用处和好处
-
项目中的难点
-
组件化、插件化
-
ExoPlayer源码
-
图片优化,如何压缩、如何缓存
阿里巴巴
-
LRUCache 原理
-
图片加载原理
-
模块化实现(好处,原因)
-
视频加密传输
-
统计启动时长,标准
-
如何保持应用的稳定性
-
ThreadLocal 原理
-
谈谈 classloader
-
动态布局
-
热修复、插件化
-
HashMap 源码, SpareArray 原理
-
性能优化,怎么保证应用启动不卡顿
-
SP 是进程同步的吗?有什么方法做到同步
-
介绍下 SurfView
-
HashMap 实现原理,ConcurrentHashMap 的实现原理
-
BroadcastReceiver,LocalBroadcastReceiver 区别
-
Bundle 机制
-
Handler 机制
-
android 事件传递机制
-
线程间 操作 List
-
App启动流程,从点击桌面开始
-
动态加载
-
类加载器
-
OSGI
-
Https 请求慢的解决办法,DNS,携带数据,直接访问 IP
-
GC 回收策略
-
画出 Android 的大体架构图
-
描述清点击 Android Studio 的 build 按钮后发生了什么
-
大体说清一个应用程序安装到手机上时发生了什么;
-
对 Dalvik、ART 虚拟机有基本的了解;
-
Android 上的 Inter-Process-Communication 跨进程通信时如何工作的;
-
App 是如何沙箱化,为什么要这么做;
-
权限管理系统(底层的权限是如何进行 grant 的);
-
进程和 Application 的生命周期;
-
系统启动流程 Zygote 进程 –> SystemServer 进程 –> 各种系统服务 –> 应用进程
美团
-
线程挂起,休眠,释放资源相关,唤醒,线程同步,数据传递,问了很多线程的问题,问了 20 分钟大概
-
static synchronized 方法的多线程访问和作用,同一个类里面两个 synchronized 方法,两个线程同时访问的问题
-
内部类和静态内部类和匿名内部类,以及项目中的应用
-
泛型是什么以及在项目中的应用
-
handler 发消息给子线程,looper 怎么启动
-
down、move、up 事件的传递
-
activity 栈
-
封装 view 的时候怎么知道 view 的大小
-
intent-filter
-
arraylist 和 linkedlist 的区别,以及应用场景
-
怎么启动 service,service 和 activity 怎么进行数据交互
-
下拉状态栏是不是影响 activity 的生命周期,如果在 onStop 的时候做了网络请求,onResume 的时候怎么恢复
-
view 渲染
爱奇艺
-
Android消息机制
-
Android View绘制流程,当一个TextView的实例调用setText()方法后执行了什么
-
Android dalvik虚拟机和Art虚拟机的优化升级点
-
Android屏幕渲染机制
-
热修复的原理,你都了解过哪几种热修复框架
-
OkHttp的原理
-
Android 线程池的实现原理
-
JavaGC机制
-
HashMap的实现机制,怎么样HashMap线程安全
-
可重入锁的实现,公平锁非公平锁都是什么定义?
尾声
最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
Android进阶学习资料库
一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
要,希望读者们能谨记这一点。
这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
[外链图片转存中…(img-UYz837E1-1715761808186)]
Android进阶学习资料库
一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!
[外链图片转存中…(img-olfEC0a7-1715761808187)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!