Android 体系化进阶学习图谱,扔物线五期
形成自己的面试知识体系
面试,简单地说就是回答出更多的问题。而准备面试,自然就要掌握更多面试中可能问到的知识。为了方便系统地对知识点进行学习和复习,我觉得在准备阶段形成一个自己的面试知识体系非常重要。并且,在学习过程中,你的体系要不断地完善。各种零散的知识点是不方便系统地学习和复习的。
具体来说,大致过程如下:
整理面试需要掌握的知识点。可以通过 Github 和 博客上别人整理的面试总结或者知识脑图,结合自己的项目经历和面试经验整理出一个面试涉及的知识体系。
结合自己的情况确定学习计划。可以看着自己整理的知识体系,思考一下这两个问题:“我掌握了哪些知识、掌握程度如何”、“需要学习哪些知识、优先级如何”。
学习新的知识和巩固自己擅长的知识。同时,不断完善自己的知识体系。
在自己心中形成一个知识体系之后,不仅学习的时候更有针对性和计划性,面试时心态也会好很多。另外写简历和面试时也可以用一些技巧,比如在对自己有一个明确的认识的前提下可以避开自己不擅长的知识点,突出自己擅长的知识点。
下面,我详细分享一下我自己的面试知识体系。我的面试知识体系包括以下几个部分:
知识点
项目
算法
亮点
3.2.1 知识点
这里说的知识点,指的是面试中基本不用思考,只需要知道就能回答的东西。下面是我自己的面试知识点体系,大家觉得不错的话,可以参考一下:
Android
四大组件、Fragment、Context
概述、生命周期、启动
通信方式以及一些细节,比如 Fragment 的 commitAllowingStateLoss 等
进程间通信
Binder
Binder 结合 AMS、WMS 等系统服务
四大组件的启动过程
Window 的理解
View
事件体系、滑动冲突
测量布局绘制流程
ListView、RecyclerView 对比和缓存机制
invalidate、requestLayout 等刷新方式
SurfaceView 的原理
图形显示原理
Choreographer 结合 View 刷新
VSYNC、双缓冲、三缓冲
SurfaceFlinger
消息机制
Handler、Looper、MessageQueue
ThreadLocal
线程形态
AsyncTask
HandlerThread
IntentService
内存泄漏
情况
分析
性能优化
常见的一些套路,比如布局优化、内存泄漏优化、ListView/RecyclerView 优化、LruCache 等
可以结合图形显示原理和 Handler 机制扩展
大图显示
开源库,这部分通常会考察源码的设计和实现
EventBus
Retrofit
OkHttp
其他项目中用到的流行开源库
其他
Android 版本变更
APK 打包、安装过程
Android 类加载,结合 Java 类加载
Dalvik/ART,结合 Java 虚拟机
进程保活、进程优先级
JNI,这块不用掌握很深,大致原理知道就行
SharePreferences 的原理和注意点
Parcelable 与 Serializable
WebView
MultiDex
Java
语言
动态代理
类型信息、反射
泛型
异常
容器,HashMap 一定要看,其他的各种常见容器也都建议了解一下实现
常用容器:HashMap、LinkedHashMap、ArrayList、LinkedList 等
Android 容器:SparseArray 等
并发容器:ConcurrentHashMap、CopyOnWriteArrayList、阻塞队列
并发
线程状态
内置/显式的锁、条件队列
死锁
线程池
volatile、原子变量、CAS、ABA
内存模型和 happens-before
虚拟机
内存区域
对象内存分配
引用计数和可达性分析
垃圾收集算法和垃圾收集器
设计模式
常用设计模式,常考单例、模板、观察者
源码中的设计模式
MVC/MVP/MVVM
计算机基础
计算机网络
HTTP:请求、响应、缓存、版本变化
TCP/IP:握手挥手、流量控制、拥塞控制、广播/组播等。
操作系统
进程和线程
虚拟内存、分页和分段
数据库
索引
事务和 ACID
关系型和非关系型
ORM 和 SQL
上面比较详细地罗列了我准备的知识点。除了这些常见知识点外,还有些知识点是结合项目的,与项目相关的知识点也要看一下。
计算机基础部分知识量很大,在短时间内很难深入学习,主要还是靠平时积累。但是这方面内容,对校招来说是很重要的,而且越是大厂越重视。比如我的面试中,阿里相比于美团和头条,我能感觉到对计算机基础的考察更加重视。非科班出身的我在研究生期间花了好多时间补计算机基础,但依然没有学得很深入,这块我准备的点也不多。
知识点部分在面试中会占到很大的比例。有时会直接问知识点,更多的情况是根据简历和项目引出一些问题考察知识点,然后基于当前问题不断扩展。知识点的准备虽然范围比较清晰,但是准备过程需要花费大量时间,死记硬背而不理解是不够的。只有在深刻的理解之后,才能在面试中流畅地表达出来。
我自己的学习材料主要是书、源码和博客。我一般先对某一块知识找一两本有名的书看,看书过程中要结合源码,对有疑问的或者书上没讲清楚的内容 Google 一些文章看。有了一两本书的底子后,再将剩余的知识点通过博客查漏补缺。在这个过程中,一定会发现新的知识,知识点也会随之增加。
针对知识点的学习,在明确了学习内容后,我推荐一些我看过或正在用的学习资源:
综合,下面两个整理是我面试前看的比较多的,非常不错的资料。
Android
《Android 开发艺术探索》:只要看这本即可,剩下的就看博客和源码了。其他的书我还看过《第一行代码》、《Android 编程权威指南》、《Android 群英传》,但都没任主席这本书写得好。这本书会穿插一些源码片段,讲解了 Android 开发中各种最基本的问题,这些问题也是面试中的热点。建议看的时候结合源码。另外书中内容基于 Android 5.0,有点久了,要注意版本问题。
AndroidXRef:这个网站可以查各个版本的源码,养成看源码的习惯很重要。
Java
《深入理解 Java 虚拟机》:面试常考这本书的前三章。
《Java 并发编程实战》:我非常喜欢的书,全面介绍了 Java 并发框架的使用方式和实现思想。代码不多,重在阐述思想。本书内容到 JDK1.6,不过对面试来说够了。
JDK 源码:可以看 src.zip、编译好的 OpenJDK 源码或者 GitHub 上的源码仓库。需要注意版本区别。
计算机网络,下面两本书都比较薄,看了之后再看一些网上的整理,面试基本上没问题了。
《图解 TCP/IP》
《图解 HTTP》
操作系统
《深入理解计算机系统》:这本书很厚,但是真的非常好,讲得非常底层。掌握这本书的内容在校招面试中我觉得是很有竞争力的。在平时看比较适合。
设计模式部分,我没有系统地看过书,只在网上学过,就不给大家推荐资源了。我觉得设计模式主要是理解常用设计模式的思想,知道他们在源码中有哪些应用。
另外,学习知识点的时候要兼顾深度和广度,广度我觉得基本覆盖主要的知识点就行,但深度是越深越好。理解得越深、越底层,越能在面试中更胜一筹。同时也能展现出自己的学习能力,学习能力是校招面试非常重视的。
3.2.2 项目
项目部分,我会先理一下项目整体架构,然后看一遍项目源码中自己的部分,最后整理出如下内容:
项目背景
架构
技术点
疑难问题
优化点
用到的设计模式
上述内容除了项目背景外,都是面试中经常会问到的内容。整理过程中,我的方式是将内容写在纸上。这种方式有助于方便地进行日常复习和面试前快速复习。头两次面试前,我都看了自己整理的项目内容。后面面试多了以后,对自己的项目中可以说的内容自然也会非常熟悉了。
另外,建议边整理项目,边考虑一下相关的知识点。非常有必要对相关的知识点做一下准备,特别是用到的主流开源库。面试中,网络库是最常被问到的。
3.2.3 算法
不管哪个公司,算法都是面试中必考的一部分。我在美团和头条的面试过程中,每一轮技术面都考了我一到两道手写算法题。难度上,都挺简单的,但是一定要注意写的对不对、规不规范。我一般会先跟面试官说一下我的思路再写。
我在算法准备过程中,主要完成了下面几部分准备:
理论学习:这块我是看了一遍《数据结构与算法分析:C 语言描述》,这本书虽然薄,但是讲得不大好理解,所以看起来非常慢。我还是建议看《算法》或者在刷题时边刷边学。
数据结构:对面试来说,只要理解数组、链表、二叉树、散列表、图这几种数据结构就够了。而且这些结构中一般不会问跳跃表、伸展树、红黑树等稍微复杂点的数据结构。
算法思想:DP、BFS、DFS、回溯、贪婪、分治。其中,DP 考的概率应该是最大的。
查找:二分查找。
排序:各种排序算法的思想、实现、复杂度、稳定性都是面试中常考的内容。
背包问题:除 0/1 背包问题外有很多变种,面试和测评时我碰到过两次背包问题,可以看一下。
刷题:我的方式是刷 LeetCode 各种类型的流行题,推荐一个清单。《剑指 Offer》我刷了两遍,面试前还会拿出来看看,很多题都很可能被问到。
整理常见算法题:我自己整理了背包、各种排序以及链表和二叉树的常见问题的 Java 实现,并且在不断扩充,在面试前也可以用来快速复习。
除了正常的算法题之外,我和一些同学都被问过智力题。智力题也是面试官可能会问的一种题型。比如,过河问题在我们实验室同学的面试中,出现了不止一次。然后,阿里的算法题问的比较灵活,经常会通过一个场景来考,不是 LeetCode 或《剑指 Offer》上常见的那种题目。比如,我阿里一面中的一个问题:“老板有 2000 元给我和同学分钱,首先由我提出分钱方案。如果同学不同意,则总额变为 1000 元,并由同学提出分钱方案。如果这时我不同意,则俩人各拿 100 元。请问一开始我应该怎么给出分钱方案?”。还有我阿里三面中的一个问题:“在一个手机屏幕上有两列(类似于瀑布流),给你一些高度不同的 item,怎么摆放才能让这两列的整体高度最小?”。
3.2.4 亮点
亮点通常是一些可以深入的点或者比较底层的知识点,面试中亮出来经常会有很好的效果。可以有意准备一些点。比如,我在美团和头条的面试中面试官都因为我对图形显示原理、SurfaceFlinger 这块内容的理解而表扬了我,认可了我的学习能力。
另外,从我和我同学的面试经验看,如果对 C++ 很了解或者有项目经验的话,是很加分的。一方面 C++ 是比 Java 更接近底层的语言,另一方面 NDK 开发现在也越来越重要。
4. 面试技巧
4.1 引导面试官
在对自己的知识体系很清楚的前提下,可以适当地引导面试官以达到扬长避短的目的。
最直接的方法就是简历。面试官一般都会从简历开始问起,所以简历上的内容直接影响了面试走向。所以在写简历时,最好在对自己的知识体系有一个清晰的认识之后,扬长避短地写。
主动深入和扩展是我在面试中引导面试官的常用方式。一般面试官问一个问题,我会由浅入深地回答,然后尽量讲得深、讲得底层,讲得差不多了就主动将话题切换到一个自己擅长的相关的话题上。比如 Android 中 应用与 AMS 间的通信、屏幕刷新等很多内容都能引到 Handler 上。这时候,之前准备的“亮点”就可以排上用场了。
4.2 表现出自己的好学
除了学习能力,对学习的热情感觉面试官也很看重。不管是在技术面还是 HR 面中,表现自己对技术的追求都是不会错的。当然,这个还是要建立在自己真的喜欢某种技术的基础上。
可以通过以下几种方式表现出自己的好学:
表现出自己对知识点的钻研。这就需要引导面试官了。
表现自己对新技术的关注。可以主动提一些新技术和自己对某一技术未来发展趋势的理解。比如我在阿里二面时讲到 Google 新的开发框架 Flutter。
说明自己看过哪些书、对哪些东西深入研究过。
4.3 遇到不会的问题
这种情况我也不能说我做的很好,不过我在这里分享一下我遇到不会的问题时是怎么做的。
首先,我一般会主动说:“这方面内容我没有深入研究过,我只能说一些比较浅显的或者使用上的东西”。因为一开始就跟面试官说明自己的理解程度可以让面试官心中有数,一般就不会再刻意刁难了,比起后面回答不上来,这是更好的方式。也表现出了自己的诚实。
然后,我会继续说:“如果让我来做的话,我会……”。因为说出自己的方案肯定比什么都不说好,甚至可以借题发挥,讲到自己擅长的知识点上去。
最后
感觉现在好多人都在说什么安卓快凉了,工作越来越难找了。又是说什么程序员中年危机啥的,为啥我这年近 30 的老农根本没有这种感觉,反倒觉得那些贩卖焦虑的都是瞎 j8 扯谈。当然,职业危机意识确实是要有的,但根本没到那种草木皆兵的地步好吗?
Android 凉了都是弱者的借口和说辞。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
所以,最后这里放上我耗时两个月,将自己 8 年 Android 开发的知识笔记整理成的 Android 开发者必知必会系统学习资料笔记,上述知识点在笔记中都有详细的解读,里面还包含了腾讯、字节跳动、阿里、百度 2019-2021 面试真题解析,并且把每个技术点整理成了视频和 PDF(知识脉络 + 诸多细节)。
以上全套学习笔记面试宝典,吃透一半保你可以吊打面试官,只有自己真正强大了,有核心竞争力,你才有拒绝 offer 的权力,所以,奋斗吧!骚年们!千里之行,始于足下。种下一颗树最好的时间是十年前,其次,就是现在。
最后,赠与大家一句诗,共勉!
不驰于空想,不骛于虚声。不忘初心,方得始终。
评论