面试总结

1.自我介绍

我是 16 年研究生毕业之后才转行做编程开发,在学校学的专业是机械,研究生时在实验室做了一点 C++,使用 MFC 编写一些 PC 的桌面程序,当时也没有学明白,临毕业时想走编程方向,但是并不好找相关工作。最后去了一家公司的一个新部门,做 VR 相关开发,实际上是研究,也主要是我自己搞研究。当时虽然做安卓开发,并不是做 App 应用开发,而是做 VR SDK 研究,更偏向于底层的 NDK 开发。经过 1 年多之后,编程水平也仅仅是学到了一些皮毛,甚至连一个简单的 App 都很难开发出来。在当时也感到很迷茫,觉得编程很难。后来自己利用周末时间去学习一些基础的知识,准备面试然后换一份工作,去做应用层开发。虽然当时技术很菜,但是面试了 2-3 家创业公司拿到了 2 个 offer,也是面试官给机会。最终选择了一家。不过还是『命挺苦的』,两家公司都是 996。开始时确实还是挺辛苦的,开始一周上班有点懵逼。。。开始 2-3 个月是一个小哥带我做安卓,做的产品属于实验性产品,这个产品做的不成功最后被撤掉了。刚刚对安卓开发有了一点领悟,但是部门产品方向发生了改变,不做移动端产品。所以也没办法,只能转前端或者后端,我这边选择了后端,因为之前对数据库有一点学习,并且语言都是使用 Java,难度相对小一些。公司后端使用 springboot + mybatis,边学边写业务差不多一周,也能完成一些简单的业务开发,主要还是数据库的增删改查。期间公司有些不景气进行了一波裁员,我这边要么离开,要么换部门,也是偶然机会换到一个新部门,又回到安卓开发,做一个直播产品,而且是自己开发。从入职到那时已经有 5 个月了,实际上安卓水平虽然有了一定的提高,但是因为没有实际项目历练,内心还是有点虚。当时项目也是比较紧急,第一版还有 10 天上线,直播和聊天室还没做,好在加班加点完成第一版上线。现在回想起来那段时间成长还是挺快的。这个产品产不多做了 2 个多月,因为不是赚钱的产品,属于免费赠送给 toB 用户的一个产品。后面部门没有换,但是产品又换了,我又回到后端开发,这个产品开发维护了 3-4 个月,因为卖的不好也是以失败告终。后面我又回到安卓开发,接下来的 3 个多月,主要是改版之前开发的直播 App,这其中对安卓开发算是增长了些信心,大部分功能都能完成,因为不完成也得完成,毕竟这个产品的安卓端只有我一个人。之后部门被拆散,公司试验中台模式,我去了移动中台,主要工作就是维护线上的 App,功能开发并不多,我负责维护 3 个 App,其中一个 App 采用了 Kotlin,所以也学习了一下 Kotlin。这个时候已经是快到 19 年的 9 月份了,原本打断到年底或者年后再准备换工作,目标还是想去大厂试试,因为感觉自己成长的速度变慢了,而且一直是自己做项目,也想参与团队开发。差不多到 10 月下旬,公司的境况很不好,陆陆续续技术开发与测试人员都离开了公司,我到 11 月中旬也离开了。

实际上我的情况也挺复杂的,这里并没有细说,这里的复杂不是说是上面所描述的产品换方向,转后端,更换部门,而且人际关系这块,总之,像我这样的在创业公司开发的同学,特别是刚毕业没多久的同学,因为公司的变化很快,还有可能因为人际关系影响,有时我们自己不能决定自己能在这家公司干多久,所以一定要多关注自己的成长,只有技术不断提升,才能因为这家不行不至于找不到工作。

上面啰嗦了很多,主要写了写自己过往的一些经历,特别是在创业公司这段时间,很多经历仍旧历历在目。我再说下我平时的学习吧,因为这部分可能会对像我一样,转行做编程的同学有一定启发。在第一家公司时,那时学习真的很迷茫,因为很多东西都不懂,也不懂得怎么补,自然学习效率就非常低,不知道大家有没有同样的经历。到了第二家时,开始的学习氛围还是不错的,带我的小哥开始给了我很多指导,也帮我解答开发时遇到的难题。虽然 996,下班后在地铁上也看一些博客和书籍,记得但是看得最久的一本书『Java 编程思想』,这本书还是挺有难度的,花了好几个月才看完,里面也有很多没有理解的。后面又把一些关键章节看了一遍。上班时主要写代码,开始时会遇到很多问题,一个是问同事,一个是搜索。我的做法是先尝试自己搞定,不过开始因为自己的知识有限,有些问题自己是搞不定的,结果浪费了不少时间,我的 Leader 和那个小哥还专门批评了我=。=,后来给自己设定时间,超过一个小时搞不定,就去请教那个小哥。对于自己搜索这块,强烈建议使用 Google,这块不用多说。这需要一个过程,慢慢自己解决问题的水平就提上来了。平时也会看一些 Android 官方文档,这部分最好还是看英文的,不理解的地方可以翻译一下,或者看看别人的博客对这部分的解释。对于开始的业务开发,需要熟悉组件,布局,动画,网络请求,一些三方库等等,总之需要哪块,自己不会就先迅速掌握这部分知识。另外我们使用三方库一般都会在 GitHub 上搜索,搜索可以看下这个库的 Star 数量以及作者的维护情况,自己 clone 下来先试试效果,同时觉得好的库可以收藏起来,后面用到就可以直接使用不用再浪费搜索的时间,后面有时间可以再仔细研究研究源码,毕竟好的开源库我们需要学习。平时我也会针对 Android 中的一些点深入学习,并写一些博客,比如 Handler,View 的测量、布局和绘制过程,动画,开源库 greenDAO、Retrofit,OkHttp,AsyncTask等,先自己读源码,看一些博客,之后理解差不多之后开始写文章,加深理解。期间一直感觉自己项目经历还差很多,所以自己也找了一些开源项目,跟着写了写,这个过程也提升了不少。差不多到 18 年底,开始学习数据结构与算法,开始看的是『大话数据结构』还有极客时间上的课程,自己练习基本上都是些常见数据结构的实现,像 List、链表(单向、双向、循环)、队列、栈、二叉树、二叉查找树、堆,这些基本的结构使用 Java 和 C 各写了写。后面中间一段时间停了,到 19 年 9 月份,开始刷了刷 LeetCode 上的题目,大约 200 多道题,差不多一般面试的算法题够用了。对于 Android 这块的学习我当时给自己列了一个简单的大纲,然后按照这个大纲来复习,其实很多不是复习而是学习。虽然并没有严格按照计划走,因为有些东西也仅仅能够在理论上学习一下,像热修复、性能优化之类的,这些并不能很快就能提升的。但总体上对于 Android 的学习还是提升了不少。对于网络这块,看了廖雪峰的博客,以及一些其他的博客,书籍主要推荐《图解 Http》、《图解 TCP/IP》这两本,开始看的是『计算机网络自顶向下』,看的有点蒙。计算机基础这部分可以看看『深入理解计算机系统』,挑主要章节看就行,再看些博客。Java 这块基础部分看了看『Java 核心技术』、『Java 编程思想』、『Effective Java』、『Java 并发编程的艺术』、『深入理解 Java 虚拟机』,Android 部分主要是『Android 开发技术探索』。东西还是很多的,很多东西我反反复复看看很多遍。总之,零零散散的写了很多,希望有些点能够对大家有用,这就我平时学习的一些过程。个人觉得还是平时多积累才是最好的学习方式,面试时那种突击的方式类似于学校里考前突击,过后大部分还是会忘。只有理解透了,才能真正和跟面试官聊的来。

2.面试过程

我这次找工作准备的也不是很充分,心里也没底,特别是一些高级部分,性能优化之类的,因为平时没怎么做这块的优化,也就看了一些文章了解而已。我从十一回家准备,回来开始面试,第一周面试 3 家公司,只有第一家通过了,后面陆陆续续开始面试大公司,前后包括新浪、百度、小米、阅文集团、快手、头条、阿里。这次出来找工作也算是很幸运了,拿到了一些 offer,其中新浪、百度、小米、快手、头条和 阿里通过了,当然这里并不是说我的技术有多好,自己知道目前的水平还差很多的,我投递的这些岗位主要比较缺人,另外也是面试官觉得我还是做事踏实肯学的那种,所以给了机会。

面试过程就不具体叙述了,这里主要说一些关键的点吧,也是投递简历到面试再到等待入职过程的坑。

(1)投递简历最好事先了解这个岗位的需求情况,工作地点,面试技术要求等,面试通过的难度和岗位需求紧急度成反比的。我这块就没太注意,面试地点和岗位,包括应试的部门都没了解就投了简历,发现有些并不是特别想去的部门和想做的业务,如果有同学在里面最好提前了解清楚。

(2)有些很多想去的公司不要急着先投递,一旦约了面试,如果面试失败,再想投递同一个公司其他部门,可能会有一个锁定期,浪费了机会。可以先面试其他公司,把心仪的公司放到后面。

(3)能够内推的最好选择内推,我因为没有啥认识的同学在大厂,基本上都是在 Boss 上投递的=。=

(4)面试我是一般安排到下午 2 点,如果顺利的话,最好一次面完。但是事实我面试的公司基本上都至少跑了 2 次,有的跑了 3 次=。=

(5)面试后记得整理自己不会的知识点,下次面试的时候不至于一点不会,也是自己查缺补漏的机会。

(6)面试时做到知之为知之,不知为不知吧,面试官的能力基本上都是比我们厉害的,但是不会的题目最好还是能过动脑思考和分析一下,面试官也是会看我们思考的过程。另外面试出题时,特别是一些设计题,一定要问清楚一些条件等等。

(7)面试这块我一般把大公司往后约,给自己多留出时间来准备,这个就看自己的时间安排和请假的情况了。

(8)和 HR 谈薪资最好还是不要说具体的数字,这部分大家应该都知道,还有要表现去的意愿,可以说一下其他公司的待遇情况,如果想清楚,到最后给何 HR 商量出一个能够接受的薪资待遇。

(9)Offer 等待,最好还是能有一个保底的 Offer,有些公司的 Offer 审批流程很长很长,所以拿到的 Offer 还是尽量拖一拖,虽然这样不太好=。=,还有就是最好能提前了解通过面试的公司发 Offer 以及后面入职流程,协调好时间。

(10)心态很重要,尽自己努力吧,其他的就随缘了。开始面试也有受到打击,期望是大公司,但是自己也没信心,想着最后自己能去一个大一点稳定一点公司也可以,最后能拿到大公司的 Offer,也是对自己努力的一种肯定和鼓励!

3.面试题目

面试题目这部分主要还是常见的知识点,我也参考了一些知识点大纲,在后面参考文章中也列了出来,下面两部分主要是我在面试过程中记录的 Java 和 Android 的知识点。

3.1 java基础

1、对多态的理解 2、abstract 关键字能否和 synchronized、static、native 一起使用,abstract 能否用在内部类上 3、抽象类和接口的区别 4、final 、finally、finalize 区别,这几个实际上没啥关系,主要考啥这几个关键字 5、HashMap 和 HashTable 以及 CurrentHashMap 的区别 6、ArrayMap 和 SparseArray 7、LinkedHashMap 8、Fast fail 机制 9、java 反射效率不高的原因 10、静态内部类和非静态内部类区别,他们的加载时机 11、Java 的四大引用的区别以及使用场景 12、BIO、NIO、AIO 的了解 13、四大引用的区别 14、Equals 重写的原则,手写实现一个 15、设计模式的 UML 图 16、常见设计模式,使用场景和意义

Kotlin

1、Kotlin 高阶函数、lamda、属性委托、协程 2、与java对比,优缺点 3、扩展函数、顶级函数 4、懒加载:lazy 和 initlate 5、Kotlin 与 java 区别以及优缺点

算法部分

其实算法这部分主要还是来自于 LeetCode,把简单和中等难度的题刷一刷,基本就差不多了

1、三个线程交替打印 A - Z,结果 1A、2B、3C、1D、2E、3F … 2、层次遍历、Z 字型遍历 3、两个矩形区域,已知每个矩形的left、right、top、bottom,求新的相交矩形,需要考虑不想交的情况 4、求两个链表相交的节点(包括不相交的情况) - LeetCode 160 链表反转 5、两数相加 I - LeetCode 2 6、两数相加 II - LeetCode 445 7、给定链表的头指针和一个结点指针,在O(1)时间删除该结点,需要考虑头节点和尾结点情况 8、合并两个有序数组 - LeetCode 88 9、缺失的第一个正数 - LeetCode 41 10、堆排序 11、一个整形数组中,找出右边减左边的最大值,即交易一次股票使得收益最大问题 - LeetCode 121 12、交易两次次股票使得收益最大 - LeetCode 123 13、二叉树路径总和 - LeetCode 112 14、二叉搜索树的中序遍历 15、输出二叉树中最大的路径,从根节点开始的路径

网络部分

1、Http 1.0、SPDY、2.0 2、什么是滑动窗口、作用 3、Https 的 TSL/SSL 的握手过程 4、TCP 的三次握手和四次挥手过程,为什么要三次握手 5、Http 常见请求码 6、Http 请求中数据类型

并发部分

1、产生线程安全性问题的原因 2、实现线程安全的方式有哪些? 3、synchronized 中使用 Class 对象和实例对象的区别,能否达到同步的效果? 4、sleep 、wait、yield 的区别,wait 的使用 5、synchronized 和 volatile 的区别 6、双重检验锁的单例模式手写,加 volatile 关键的作用,以及这种单例的分析 7、生产者和消费者实现的几种方式,会手写 8、线程异常的种类、线程池的优势、线程池的原理 9、CAS 原理 10、线程安全的集合有哪些?以及他们的原理和源码分析 11、Collections.synchronized 12、CopyOnWriteArrayList 13、HashTable 以及 CurrentHashMap 的区别

虚拟机部分

1、Class.forname 和 classloder 加载的区别 2、JVM 内存结构 3、JVM 类加载机制 4、垃圾回收算法 5、内存泄漏原因,以及可达性分析中的根对象有哪些 6、什么时候发生垃圾回收 7、jni 的使用方式,动态注册和静态注册,加载过程的了解

这部分主要看《深入理解Java虚拟机》这本书就够了

android 部分

1、Android 有哪些存储数据的方式 2、SharedPrefrence 源码和使用注意点 3、属性动画、补间动画、帧动画的区别和使用场景 4、Fragment 采用 new 实例方式的问题 5、Fragment 怎么进行状态保存 6、Fragment 生命周期 7、Activity a 跳转 b 后的生命周期 8、Service 的生命周期,两种开启方式的过程,包括 rebind 的调用时机 9、IntentService 和 Service 的区别 10、Service 保活 11、Context 几种的区别 12、安卓源码中的设计模式 13、本地广播和全局广播的区别,源码层面的分析 14、Activity 的热启动和冷启动过程 15、ARouter navigation 方法中 NavigationCallback 的作用 16、进程间通讯的方式有哪些? 17、一个 view 在界面上超出父 view 的范围如何处理:clipchildren 使用,以及和 clipchildtopadding 的区别 18、view 的 measure、layout、draw 过程,measurespec 的作用 19、viewgroup 的绘制顺序,默认情况下能够直接绘制,setWillNotDraw 的设置 20、自定义 View 和自定义 ViewGroup 需要注意什么? 21、view 层次遍历、递归和非递归、手写 22、getLocationOnScreen 和 getLocationInWindow 的区别 23、CoordinatorLayout 的使用 24、ConstraintLayout 使用,用来优化层级嵌套过深的问题 25、include、merge、viewstub 的使用,viewstub 的原理 26、requestLayout、invalidate 的区别 27、invalidate 和 postInvalidate 的区别 28、handler.post 中更新 view 和 view.post 的区别,需要知道 view.post 执行的过程 29、View 和 viewgroup 采用的设计模式 30、Webview 原理、h5 中的 java 对象是否是 native 的对象? 31、如何实现原生和 h5 的通讯,即互相调用 32、surfaceView 和 textureview 33、如何实现 Fragment 的滑动 34、Viewpager 无限滑动实现 35、如何实现圆形头像 36、ViewTreeObserver 中的各种监听,常用的 OnGlobalLayoutListener 的使用,用来获得 view 的尺寸 37、富文本的实现,SpannableString 38、两种序列化的区别 39、Intent 传递数据 40、Binder 的好处以及原理、AIDL 的使用、如何实现客户端进程和服务端进程互相通讯 41、如何进行手势识别 42、高清大图加载处理 43、Handler 机制,这块虽然大家都很熟悉,但是结合内存泄漏,分析引用链,找到 gc root 是否能够说清楚 44、EventBus 原理以及使用的优缺点,postSticker 的分析 45、OkHttp 的优势、源码分析、责任链过程、参数设置,包括请求数量,线程池设置等; 46、如何添加 header、token 等,自定义拦截器和 NetworkInterceptor 的区别,如何监听网络请求时间,如何防止运行商 DNS 劫持,网络优化方式有哪些? 47、如何实现网络请求安全,在 okhttp 中如何做证书认证 48、对 okio 的了解 49、Glide 缓存原理,如何设计一个大图加载框架。 50、LRUCache 原理,自己设计一个 LRU 的数据结构 51、Retrofit 原理,以及使用到的设计模式 52、动态代理的原理 53、注解解析器原理 54、事件分发流程,一般都是从 Activity 开始,从 ViewRootImpl 分发到 Activity 的过程分析 56、嵌套时手指移出 View 的范围后发生什么? Cancel 事件发生的时机 57、如何使得点击事件 onClick 不被执行 58、事件滑动冲突情况的处理:竖直滑动嵌套水平滑动、水平滑动嵌套水平滑动、竖直滑动嵌套水平滑动,水平滑动中还有竖直滑动(recyclerview + viewpager + recyclerview) 59、Rxjava 线程切换原理 60、响应式编程的理解,优缺点 61、Rxjava 操作符,map、flatMap、concatMap

性能优化

1、IdleHandler 的使用 2、内存泄漏,如何找出内存泄漏,leakcanary 原理 3、项目中内存优化做了哪些? 4、bitmap 优化 5、recyclerview 缓存、滑动优化 6、启动优化做了哪些? 7、包体积优化做了哪些?只用 armabi-v7a 是否有问题 8、ANR 原理以及分析 9、art dalvik 区别,垃圾回收机制的区别 10、安卓各个版本特性

框架

1、MVC、MCP、MVVP 区别、优缺点,如何选择、选择框架的意义 2、组件化架构思路,你在项目中如何做模块划分的 3、ARouter 原理,如何实现组件间通信,组件化平级间通讯

设计题目

1、埋点设计,设计一个埋点 SDK 2、图片加载框架设计 3、自己设计一个简单的 LRU 缓存,存储 int 类型,具有get 和 put 功能即可。 4、设计网络请求封装给应用层使用,网络框架选择,缓存处理(先读取缓存还是先请求、缓存时间),请求重试 5、设计一个网络下载框架,具有开始,暂停,停止功能,有进度通知,可以参照 AsyncTask

其他

1、项目中比较有挑战的地方 2、你认为是自己项目中设计的地方 3、个人规划、离职原因、薪资期望

4.参考

这部分主要平时看到的一些好的文章和书籍,当然还有很多好的文章,这里仅仅是一部分,所以还是注重平时的学习和整理。

2019大厂Android高级工程师面试题整理+进阶资料

BAT大厂Android面试知识点

Android 高级面试-5:四大组件、系统源码等

19年3月移动端大厂面试题分享

面试官:今日头条启动很快,你觉得可能是做了哪些优化?

RecyclerView问题汇总

郭神的抽丝剥茧心法修炼: 深剖RecyclerView

Android匿名共享内存(Ashmem)原理

Android性能优化(七)之你真的理解ANR吗?

Android性能优化(六)之卡顿那些事

学习大神的思路,动手实现字节码插桩功能

讲一讲 Android 内存优化的小秘密

查内存泄漏神器,LeakCanray原来是这样工作的

Android - 彻底消灭OOM的实战经验分享(千分之1.5 -> 万分之0.2

Android高级面试题

Android性能优化全方面解析

【凯子哥带你学Framework】Activity启动过程全解析

Activity中的那些小秘密

Android v1、v2、v3签名详解

APK签名机制之——V2签名机制详解

HTTP 的架构设计和一些优化的技巧

如何优化Androd App启动速度

启动优化方案的“第三板斧”终于齐了!

Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复

Android的UI显示原理总结

2019.07 Android 面试真题集锦

Binder学习指南

深入理解Java并发之synchronized实现原理

Glide 系列(四) Glide缓存机制

JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比

Android中高效的显示图片 - Bitmap的内存模型

Android原生H5混合开发之JsBridge

让你彻底理解Synchronized

Android 插件化和热修复知识梳理

《Android 开发艺术探索》 《深入理解 Java 虚拟机》 《Java 并发编程的艺术》 《图解 Http》 《图解 TCP/IP》

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦