一个自学Android 人的第三年的面经分享

474 阅读11分钟

一.前言

最近事情比较多,工作比较忙,同时在自学泰语和前端,精力比较分散。差点这份面经就跳票了,感谢同行的鼓励让我重新提笔。

数数这也正好是我入行的第三个年头了,侥幸当年在外包公司得到实习的机会,从此开始了IT生涯。回头看看这三年一步一步走来,真是吃了不少苦头。不知道你们有没有跟我同样的经历,刚毕业的时候什么都不懂,渴望一个机会,去面试当面被面试官批评太差劲。刚入行的时候,没有牛人带,总盼望着谁拉扯自己一把,什么都得自己摸索,一步一步自己踩坑。才工作一两年的时候,就感觉遭遇了瓶颈,未来一片迷茫,不知所措。这些我都经历过,我甚至还经历过比这更糟糕的情况。幸运的是,我坚持了下来。

二.个人背景

先介绍下个人履历,作为面试的参考,抛开背景谈面试都是耍流氓。

双非(非985,非211)一本电信专业毕业,半跨行从事IT行业,工作三年,跳槽前没有互联网履历,第一份工作在外包公司任职,第二份在公募基金公司任职。

如果你是专科毕业,我建议你至少要考个本科学历

现在很多公司简历审核的时候都会卡学历,我之前任职的基金公司甚至一度卡到985,211。虽然IT是靠能力吃饭的行当,但是随着从业人员的增多,市场的门槛也会随之调整。我有时候甚至觉得本科都有点不够看,建议专科毕业的同学至少要考个本科学历,不然很容易失去面试机会。即使面试通过了,在最终的HR面也很容易被刷。

三.面试准备

3.1养成日常学习的习惯,而不是依赖考前突击

我的面试准备周期很长,差不多从17年12月底开始有想出去看看的打算,一直到18年6月才最终拿到满意的offer,这个期间我一直在查漏补缺。但我的学习周期更长,从17年5月进入一个日常学习的状态,花了一年时间跟着网课完成了系统性的学习,中间还看过很多书。

我不建议大家只在面试前夕进行突击学习,背面试题,这种技巧可能会让你获得一个offer,但没办法提升你的个人能力。我建议养成一个日常学习的习惯,每天抽空学几个小时,在面试前把总结的知识点重温一遍即可。这种习惯日复一日所带来的复利会让你的技术在某一刻由量变产生质变。

3.2人不是神仙,不可能面面俱到

业内经常会调侃,面试造航母,工作拧螺丝。你不可能问什么都能答的上来,所以你要调整好心态坦然接受失败。不得不说准备面试真的是个很痛苦的事情,耗费精力不说,你可能突然会发现你原来这也不会,那也不懂,自以为拿手的本事被人两三下就问懵逼了,信心严重受挫。但你要相信自己,跌倒了不要紧,再爬起来就好。

关于面试具体要准备什么,聊这方面的文章很多,我简单梳理一下,后面也会有我部分公司面试题的总结。

  • 多线程、JVM

    这两块的知识点是让你能顺利通过大厂一面的保证,我所经历过的阿里、头条面试一面基本围绕这些知识点展开。

  • 开源框架

    我觉得多多少少需要看一些框架源码,了解其中的原理,掌握其中的核心,并且能用自己的语言,陈述出来。还有时下比较流行的东西面试官问的几率很高,比如组件化、hybrid。多读读源码也能培养自己读代码的能力,这样的本事能让你很快的了解一个新的项目或者一个新的框架。

  • 性能优化

    这一块也是很多公司喜欢问的,特别是当部门架构组团队招人的时候喜欢问。我不太擅长这方面,就不多谈了。

  • 数据结构及算法

    在我系统学习的过程中我是把数据结构和算法跟着课程学了一遍的,但是我面试期间是完全放弃复习算法的。这么说并不是说算法不重要,头条的面试上来就会考一道算法题,喜欢考算法的厂也越来越多。只是大家要根据自己的实际情况分配复习的比重。毕竟数学考试最后一道大题你做不来,你可以把前面的小题争取全部做对。

四.简历

简历是敲门砖,也可能是面试的引线

大家一定要重视简历。对于学校不优秀,工作背景不突出的同学,简历是你的敲门砖。简历写的不好,你可能直接会错过一次展示自己的机会。

在面试中很多面试官会根据简历来提问,所以你擅长的东西,一定要写在突出的地方让面试官看到,主动引导面试官问你你擅长的问题。在回答问题的时候,千万不要只言片语草草结束。每次被提问,都是一次展示自己的机会。尽可能的说全,说详细。接着面试官可能围绕你说的内容进行深挖去考察你,所以你的知识点不能浮于表面,不然两三个回合可能就被问的哑口无言。如果你实在有些知识点不懂,尽量的在回答中规避这些细节,免得面试官一时兴起问你一下。

那么简历到底该怎么写,有些同学可能会觉得,我平时工作都在堆业务,项目上没有什么可以写的怎么办。首先再回头看一看项目里是不是真的没有什么闪光点,日活、品控、性能这些都能作为你的谈资。如果实在没有那就去研究两三个主流开源框架,读读Android SDK源码,写点开源项目放到github上。你也可以搞明白自己项目的业务架构,钻研一下组件化、热修复、插件化、hybrid等热门技术,深究一下性能优化比如卡顿监测、APK瘦身、DEX加密、过渡绘制等。每一个点它都可能成为你成功的钥匙。

五.面试题

生活是场修行,认真对待每场面试

这里写了部分大厂面试题作为大家复习的参考,平安系的面试主要问的项目,包括个别小厂面试没什么参考性,这里就不写了。

头条的面试质量很高,复盘的时候有种醍醐灌顶的感觉。

携程的面试很不走心,大老远跑一趟最后面试官都不给我提问的机会面完直接走出去了,我也没差到这种地步吧。

阿里的面试比较随机,两次下午上班的时候来电面试,一次是晚上来电面试。

5.1东方财富

笔试
  • 简述类加载机制
  • 写三种单例的实现方式
  • Activity生命周期
一面
  • Handler机制
  • 事件分发机制
  • 乐观锁与悲观锁
二面
  • Android 7.0 8.0 p 兼容性问题
  • 嵌套滑动
  • 营销工具比如列表第三位展示广告,如何设计接口

5.2蚂蚁金服

一面
  • 内存泄漏
    • 具体场景
  • 大图加载
    • 大图加载的缓存
    • Bitmap优化
  • Handler机制
    • 子线程能不能创建Handler
    • 线程间通信其他方式
  • 线程的创建与退出
    • 乐观锁与悲观锁
    • volatile原理
    • 读写锁的应用
  • RecyclerView与ListView的区别
    • RecyclerView为什么这么设计
    • 应用
  • 自定义控件
    • 事件分发机制
    • 动画
  • okhttp支不支持优先级
    • ssl握手谁实现的
    • websocket应用
  • 简述日志系统
二面
  • 介绍项目架构等,围绕项目进行提问
  • 序列化的作用
  • 子线程轮询阻塞队列如何安全回收线程
5.3Musical.ly(头条)

一面

算法:数组中的数据前半部分递增,后半部分递减,排序并去重

Java虚拟机

  • 虚拟机内存结构
    • 哪些是线程私有,哪些线程公有
    • 静态常量的存储位置
    • 无穷递归方法引发的问题
  • GC机制
    • GC roots是什么
    • Handler造成内存泄漏的整个引用链
  • 什么情况会产生ANR
  • 广播
    • onReceive方法调用线程
    • 静态广播接收流程
    • 动态广播接收流程
    • 动态广播能不能重复注册
  • SurfaceView原理及使用注意事项
  • ButterKnife工作原理
  • 仿微信朋友圈图片展示设计思路

------以下问题都是面试官根据简历问的------

  • 热修复
    • 热修复原理
    • 假如某个类A有个bug,热修复的整个流程
    • 该修复方案是否能避免oat导致的一些问题
  • LeakCanary原理
  • Groovy插件
    • APK瘦身如何实现的
    • 自定义任务在某个任务之前或之后执行怎么写
    • Gradle打包的整个过程
  • 看过哪些Android源码
    • 拦截Activity跳转有哪些Hook点
  • Groovy和Java的比较

二面

  • 类加载过程
    • 触发类初始化的时机
    • 被动引用
  • Activity启动模式及几个模式的应用场景
  • onSavedInstanceState相关
    • 灭屏会不会触发onSavedInstance
    • onRestoreInstanceState和onSavedInstanceState是否成对出现
  • Service生命周期的理解
    • bindService整个代码怎么写
    • 与service通信是否会阻塞当前线程
    • 如果是耗时方法,为什么会阻塞
    • 如果不是耗时方法,为什么不会阻塞
    • 如果远端是耗时操作,怎么不等待结果让主线程先运行
    • startService和bindSerivce对service生命周期的影响
    • aidl传递Bitmap需要注意的事项

5.4携程

一面

  • EventBus原理
  • Java中有哪几种注解
    • 具体注解名称
    • 如何自定义注解
  • EventBus是什么注解
    • 能不能用编译时注解实现EventBus
    • 注解处理器怎么工作
    • 注解处理器有哪些API
  • Glide原理
  • Lrucache原理
  • LinkedHashpMap原理
  • HashMap原理
    • 解决Hash冲突的方法
    • equals和hashcode作用
    • hashcode如何实现
  • Object类下有什么方法
  • 使用过哪些热修复
    • 热启动热修复原理
    • 冷启动热修复原理
  • Android中的类加载器
    • 类加载器之间的区别
    • Dex融合用的哪种类加载器
    • 父类是什么及三者之间的关系
  • 双亲委派模型
  • APK瘦身
  • Android中的动画及区别
  • Handler原理
  • Android中序列化方式
    • 两者区别
    • 为什么Parcelable性能更好
    • 序列化UID作用
  • ThreadLocal原理
  • Java中有哪些锁
    • 悲观锁与乐观锁的区别
    • 自旋锁的作用
    • 锁一般是怎么实现的
    • 让你自己实现,怎么实现一个锁
  • 内存优化有哪几种方式
  • 布局优化有哪几种方式
  • 线性布局在onLayout里面做了哪些工作
  • 谷歌为什么给Activity设计这么多生命周期

5.5招行信用卡中心

(招行是架构组招人,问的问题主要是架构方面和安全方面,比较开放,简单总结一下)

  • 工程结构纵向横向如何拆分(项目架构)
    • 如果解决代码依赖
    • 两个隔离模块的数据交互
  • 开发过程中遇到的问题
    • 内存泄漏
  • 项目中首页的实现
    • VLayout实现原理
    • 为什么不用RecyclerView实现多Item
  • 热修复差分文件的验证(安全性)
  • 公钥私钥体系
    • 应用场景
    • HTTPS连接过程
  • 应用构建过程
  • 应用签名校验过程
  • V1签名和V2签名区别
  • Dex加固原理
  • APK瘦身

六.展望

干这行三年了,自己恐慌过,也看到过别人恐慌。担心行业日落西山,担心Android被大前端统一。这样的担心也不算没有道理。但其实真正让我恐慌的是我没在进步,而行业在不断进步,担心跟不上行业的脚步。作为程序员,还是要保持一颗学习的心态,不断前进。但也希望大家在繁忙的工作、学习之余抽身出来多培养些兴趣爱好,多陪陪家人朋友。多打磨一下自己的软技能,提高谈吐、情商、表达能力。这些也是一个优秀的程序员所需要具备的条件。

我不算是一个优秀的程序员,也只是努力的在这条路上前行,希望能做一些自己喜欢的事情。

如果有机会,会在博客上跟大家分享一些安卓以外的内容。

愿每个人都有梦想,也愿每个人都能坚持自己的梦想