2020年已经过去了一大半了,仔细一看我的博客最后一次更新居然是去年的11月份……当然,在更新博客方面放鸽子对于现在每个博主来说应该都不算什么了吧,哈哈。这次我间隔这么久也算是事出有因吧,是的,我跳槽换工作了。我不是一个藏私的人,所以现在就把今年我作为一个Android开发在找工作方面的一些经验心得分享出来。
今天我不想说太多技术方面的东西,就说说这次面试之旅中一些比较有价值的信息吧,这样能让很多朋友在为面试做准备之前做到心里有数,别像无头苍蝇一样的乱撞,面试毕竟是一项技术活儿,要讲究策略,能做到有的放矢的话,就能做到事半功倍。
今年Android找工作的难度
一句话,难度又比以往增大了很多。
先从招聘职位的数量上来看,之前我在2019年Android开发找工作的分享中曾经记录过一个简单的数字,那就是在2019年1月的时候,我在51job里搜索北京地区的Android岗位,当时有2100多个,对比2015年的上万个已经减少了80%以上。而现如今又过去了一年半,在2020年8月这个时间段,51job的北京地区Android岗位是多少个呢?只有1100多个了,是的,又减少了50%,这形势有多么不友好,一目了然。当然,找工作和招聘也有一定的季节性规律,也许就是年中这段时间岗位更少一些吧,而且现在BOSS直聘、拉勾、脉脉等肯定分走了51job的很多互联网职位,等明年年后我再关注一下这个数字。但是现在全球的经济形势怎么样大家都心里有数,企业倒闭那是一片片的,而今年新冠带来的影响同样不可忽视,只能说这工作是真的难找了,因为需求量减少了很多。
再看面试难度方面,也是一年比一年高。想面高级职位,需要去阅读的源码必不可少,比如一些重要的官方库和三分库,不读源码你就无法了解这个库的实现思路和关键代码处,面试就很难通过了。同时对你的架构能力也会有要求,要能清晰的讲明白一个项目的架构并不是一件简单的事情。有的公司最后还会就一个具体的业务场景对你的系统设计能力进行考查,总之,难度越来越高了。
当前面试的主要流程和形式
在以前,面试一般都是通过各种途径把简历送到招聘公司的HR手里,然后又HR来安排面试。
送简历这一步,有可能是你直接在招聘网站/APP上搜索职位后主动投递,也有可能是相应公司的HR主动找到你来跟你要简历,也有可能是相应公司的开发人员直接跟你要简历——因为很多大厂对于成功的内推是会有奖励的,还有可能是你通过你认识的老同事/同学/朋友/老乡等直接内推简历,当然也可能是猎头帮你推的。总之,多个朋友就多个渠道,不会吃亏的。
之后的简历筛选就是人家公司内部的事情了,这里可能会通过HR、相应部门的开发、相应的Leader这么几个步骤,是否能通过筛选,就看你简历写得怎么样了,这个话题也不是三言两语就能说清楚的,以后咱们再说。
当你的简历通过了筛选,HR就会联系你,跟你约面试了。对于一个还在工作、没有离职的人来说,往往白天面试是不太方便的(被现任领导发现不就死定了),所以你可以考虑约在晚上,或者干脆自己休半天假来面试。
说到面试形式,以前的时候大部分公司会把候选人直接约到公司,当面进行面试。而现在技术发展了,工具进步了,再加上今年新冠的影响,在线面试就变得十分流行了。电话面试、微信视频面试、腾讯会议面试、阿里钉钉面试等,都已经是当下非常普及的面试方式了,而如果需要在面试中敲代码,那么牛客网可能是目前最主要的途径了。这些工具给面试双方都带来了很大的便利,反正现在技术面还需要现场面试的,我个人是不太喜欢的。
对于一些小厂来说,可能一轮面试就基本上尘埃落定,通过后就可以跟HR谈笑风生了。而对于大厂和一些在技术上还算讲究的中小厂来说,一般会有3轮左右的技术面,通常是一轮技术骨干面,二轮技术Leader面,三轮大Leader面(总监或者VP),全部通过后才是HR面。如果你的级别很高,或者面的公司/事业部要求很高,那么面试的轮数还会多,江湖传言腾讯的wxg有可能达到9-10轮面试。
面试要准备多久
这是一个没有什么标准答案的问题,取决于个人:如果你平时是一个注重总结、经常观看各种技术文章的人,那么所需要的准备时间就会短一些;如果你平时一心放在工作上,不太总结,那么可能就需要更长的准备时间了。我们必须得承认,面试跟平时的工作就是不一样,所谓“面试造火箭,入职拧螺丝”并不仅仅是一句玩笑,而是有相当可信度的。比如,同样一个开源库,对于绝大多数开发者来说,在工作中知道它该怎么用就足够了,但是你在面试中如果面试官问你这个库,那往往你需要比较深入的了解这个库的实现原理,这就需要你去阅读代码了。如果此时你还是憨憨的告诉面试官,我只知道这个库该怎么初始化,不了解其实现原理,那这次面试大概率已经凉了……
一般来说,至少要准备一个月的时间吧,对于一个Android开发人员来说,总得需要这么一个月的时间去熟悉那些你日常工作中用不上、但是面试中却有极大概率被问到的点。而且大部分人都是在职状态找工作,所谓一个月的准备时间,大部分还是在做平常的工作,真正能让你用来做面试准备的时间怕是不会太多。
强烈建议大家在日常的工作生活中养成好的习惯,把最常用的一些库(三方开源库和官方库)尽量从源码层面多了解一下,能自己从中总结其实现思路就更好了。同时一些重要的基础要经常温故知新,这样在跳槽的时候就能节省很多时间了。
是否需要刷算法题
哎,这又是一个大家很关心的问题吧,答案也会让大部分人失望吧——是的,有必要刷题!
当然这里面还是有一点点区分的:如果你的目标是找到一份还可以的工作,并没有一定要去大厂的执念,那么小厂在算法这方面要求并不高,不刷题也行;但如果你就是想去大厂,那么刷题还是很有必要的。
现在的大厂(百度、阿里、腾讯、头条、快手等等)一般至少有3轮技术面试,基本上前2轮都会出个题让你在线写代码。注意啦,这道算法题不一定很难,但很关键,因为绝大多数公司的面试,算法题都放在这一次面试的最后时间,所以它的权重会比较高。如果你之前的问题回答的都不错,但是这最后的算法题没做出来,那大概率就凉凉了;如果你之前的问题回答的很一般(当然不能是特别差),但是这最后的题做的还不错,那么通过此轮面试的概率还是比较高的。所以,你说是否要刷题呢。
Android面试要准备哪些知识点
相信这是大家最关注的问题了,答案内容也是会比较丰富。毕竟Android到今天已经有超过10年的历史了,在App开发方面也十分成熟了,面试官能从很多角度来提出问题,下面我把我这次面试中遇到的一些高频率的知识点说一下吧,因为这篇文章是概述性质的,所以不会详细的说,只说到知识点为止。
Java方面
即使现在Kotlin势头很猛,你也必须有相当的Java基础才行,这里所谓的基础,既包括语言特性,也包括一些数据结构,还有一些JVM层级的东西。
重要的数据结构:ArrayList、LinkedList、HashMap、ConcurrentHashMap,以及Android所独有的SparseArray、ArrayMap等,要做到源码级的理解,这里HashMap是最重要的(还要注意老版本和1.8之后的区别)。
内存方面:内存数据分区(就是程序计数器、堆、本地方法栈、Java栈、方法区)、内存模型。
GC:垃圾对象的判断、GC算法与策略,需要理解各种GC算法的区别。
多线程:Thread、Runnable、线程池、ThreadLocal,以及Android的AsyncTask(按理说现在狠少有人用了,但不知道为什么还是有人喜欢问)。
锁:volatile(姑且把它放在锁这个分类里吧)、synchronized、Lock、CAS、CountDownLatch等,知道每种锁的特性和使用场景,尤其是synchronized关键字锁与Lock锁的对比。
类加载:ClassLoader、双亲委托机制、父类子类各种代码的加载顺序等,还可能引申出热修复、插件化的一些技术。
内部类:普通内部类、静态内部类、匿名内部类,也会涉及到内存泄漏的问题。
设计模式:我面了这么多,还真没遇到几个考设计模式的,偶尔会让你写个单例模式,其他设计模式会穿插在实际的系统设计或者开源库原理分析里。
反射:好像没有被直接问到,但是实际上很多地方都涉及到了反射,如布局加载过程和一些开源库的实现。
Android方面
作为一个Android开发,本职的知识点那肯定是必须要掌握的,作为高级开发,需要理解的地方还是挺多的。
四大组件:四大组件现在被问到的机会很小了(很小的公司或者中低级岗位我不了解),不过偶尔会被问到启动Activity的流程,另外还有Activity的启动模式。Service被问到的很少,BroadcastReceiver和ContentProvider基本上不会被问到。
性能优化:包括启动优化(主要是冷启动)、内存优化、绘制优化、稳定性优化、安装包体积优化等,优化是面试的重中之重。
适配:主要是Android系统不同版本的适配(如6.0开始的动态权限、8.0的前台服务等),还有屏幕适配。
架构:MVC、MVP、MVVM,本来以为这是老生常谈,结果出乎意料,特别多的面试官喜欢问这一块,尤其是官方Jetpack里的ViewModel和LiveData,尽量做到源码级理解。
事件分发:说白了就是事件的分发、拦截、消费机制,这块说简单也简单,往细了说又挺麻烦,一般会给你个具体场景来进行分析。
消息机制:Handler、MessageQueue、Looper,也需要你去读一下相应的源码,尤其是Looper的loop方法,还可能问你loop里的死循环为啥不会导致ANR之类的问题。
布局:常用几种布居肯定都得了解,即LinearLayout、FrameLayout、RelativeLayout以及约束布局ConstraintLayout,要了解每种布居的特点和适用场景。
控件:常用的TextView、ImageView得非常熟悉,其他的也要熟悉。RecyclerView最好要做到源码级理解,尤其是缓存方面。
自定义控件:View(包括ViewGroup)的一些特性得了解,对于自定义控件有帮助。要熟悉View的测量、布局、绘制这3个关键步骤,如有可能,尽量了解从ViewRootImpl开始的绘制流程。
图片:主要是Bitmap的操作,如压缩、裁剪、缓存、回收与重用、超大图的处理等,一方面参考官方或者其他人写的指南,另一方面可以参考一些开源库(如Glide)里是如何处理Bitmap的。
跨进程:你得知道Linux系统里的几种进程间通信方式(共享内存、Socket、信号量、管道等),当然Android的Binder是最重要的,还要明白为什么Android没有使用Linux已有的跨进程方式,而是选择了Binder。
打包:熟悉整个打包的流程,了解打渠道包的方案和原理,清楚混淆和加固,Android对APK的签名和校验过程。
网络方面
对于Android开发来说,网络算是一块相对小众的知识,由于大部分人做的都是App,等于是仅仅在网络的应用层这一级活动。但作为一个程序员来说,网络本身就是一块很重要的基础知识,虽然被问到的机会不大,但如果问到了,你哑口无言,那场面就很尴尬了,所以还是有必要了解的。
由于我自己在网络方面的了解也不太成体系,所以就简单的说一下你需要了解的点吧:
了解TCP/IP协议与分层,知道一个TCP连接是什么,了解报文的格式,三次握手与四次挥手要知道其内容,TCP和UDP的区别,http1.0、1.1、2.0的区别,http与https,Socket和WebSocket等。
开源库
虽然网上各种三分开源库数之不尽,但作为一个Android开发人员,在面试中你需要深入了解的库并不用太多,加起来也不到10个。
Glide:这个是我此次面试中被考查频率最高的一个开源库了,因为Glide确实设计的非常经典,你需要深入了解的是它的缓存机制和BitmapPool,这2块是最重要的。另外你可以从中学习到很多对于Bitmap处理的方法。
LeakCanary:因为内存泄露的处理很重要,所以捎带着这个库也被很多面试官所重视。要理解它的原理,到底是怎么实现能够观察到一个Activity没有被顺利回收造成泄露的。
ARouter:现在模块化(组件化)算是比较常见的开发模式了,尤其是在大厂,所以有必要知道ARouter的实现原理,2个模块之间是怎样实现的页面跳转,以及ARouter为了优化性能做了哪些工作。
OkHttp:作为目前Android平台使用最广泛的网络库,不仅我们普通开发者在用,连Android自己都把HttpUrlConnection的底层实现换成了OkHttp。而且OkHttp的责任链模式非常经典,非常值得我们学习。
Retrofit:虽然Retrofit只是一个基于OkHttp的网络封装库,但合理使用设计模式使得这个库非常易用,基本上也成为App开发的标准库了。它使用动态代理的方式非常巧妙的把一个请求接口的注解参数最终转化成一个网络请求并执行,这种设计的方法我们在平时的开发中一般用不到,但的确能让人大开眼界,对于个人能力的成长是有帮助的。
EventBus:也许很多人可能用的是RxJava甚至LiveData实现的事件总线,但是EventBus作为Android领域最知名的事件库,本身非常轻量级(总共也就300个方法左右),使用起来也非常方便,有必要了解其实现原理,顺便还能复习一下反射。
Tinker:其实热修复的库还算挺多,为什么单拿出微信的Tinker来说呢?因为有的热修复框架并未开源(如阿里的Sophix在修复bug上更强大,然而并未开源),而且能深入理解Tinker的实现原理,也就等于同时对插件化技术有了了解。
总结
这次换工作,前前后后花费了我不少时间,算上准备时间,可能有3个月了,当然最后的结果也还算让我满意。因为距离我上次换工作时间太久,这个市场发生的变化实在是太大了,而今年的大环境又着实不好,谨在此希望各位有跳槽想法的朋友,都能得偿所愿吧。
评论