先说一下自己的情况, 本人今年大四, 双非一本学校, 计算机相关专业, 从大一开始加入学院创业团队的 Android 开发组.
去年过年后不久开始投简历, 前后投了腾讯, 阿里, 美团, CVTE 这几家公司, 拿到了腾讯, 阿里和 CVTE 的实习 offer, 最终选择了腾讯, 也算是给自己的第一次找工作之旅画上了圆满的句号.
这篇文章是去年春招之后的总结, 主要是分享我自己针对这次春招所做的准备工作以及在面试过程中的一些经验和思考, 因为今年的春招实习也要开始了, 所以分享出来, 希望能对大家找实习有些帮助.
一, 有计划的系统复习
各大互联网公司的春招的时间大概是 3 月到 5 月, 如果是通过内推途径的话, 甚至 2 月份就会开始电话面试, 也就意味着如果想拿到满意的 offer, 你必须在 2 月份之前就做好所有的复习工作.
先讲下我自己之前的规划, 为了准备这次春招, 我提前了半年开始准备复习, 复习阶段主要分为三部分:
学习「自己知道自己不会」的知识
全方位的学习, 构建自己的「知识体系」
学习「自己不知道自己不会」的知识
1.1 学习「自己知道自己不会」的知识
其实在开发过程中, 总有一些自己想学但是因为项目压力或者其他原因, 然后自己打算放在以后再学的东西, 也就是所谓「自己知道自己不会」的知识.
例如:
比较常用的一些框架, 比如客户端的网络请求, 图片加载框架
常用的一些类和集合的源码, 比如 ArrayList,LinkedList,HashMap(面试必问)
觉得自己无法清晰表达出来的概念, 如「内存泄露」,「Java 并发」
这个阶段是一个对自己当前知识体系查漏补缺的一个阶段, 你要做的, 就是把自己不会的东西完整的列出来, 然后逐个击破. 这个阶段最好通过博客的形式, 将自己学到的东西「用自己的语言」表达出来, 如果你能用自己的理解清晰, 完整地说出来, 甚至能让别人听懂你讲的东西, 那基本就没问题了. 但如果自己脑海里没法形成一个清晰的概念的话, 只能证明你对这个知识点还不够理解.
而且现在很多公司都将「写博客」作为一个加分点, 一份简历其实并不能反映多少东西, 但如果你有一个长期维护的博客的话, 面试官可以通过你的博客更加清楚地了解你, 而且坚持本身就是一件不容易的事情, 面试官对于能够坚持写博客的人也会更加有好感.
1.2 全方位的学习, 构建自己的「知识体系」
其实很多人在平时学习技术和日常开发过程中, 学了非常多的东西, 但很少有人会去系统地复习, 从而构建自己的知识体系, 导致自己学到的很多知识点没办法更好的产生联系, 而且可能会导致学了某个知识点没过多久就忘了.
那如何构建我们的「知识体系」呢?
Android 里面所谓的「知识体系」, 我认为主要包含这几个部分:
Java 和 Anroid 基础
计算机网络
操作系统
设计模式
数据结构和算法
也就是说我们需要将这几个部分逐步击破, 慢慢完善我们的知识体系, 这个阶段是最花时间和精力的, 但是坚持下来会让我们的基础变得更加扎实, 而且能最大限度的构建我们的知识体系.
在这里我推荐一份非常好的资料: Android 校招面试指南
1.3 学习「自己不知道自己不会」的知识
这个标题可能会让你们有点纳闷, 连自己都不知道自己不会的知识怎么学? 这时候面试题的作用就出来了,「面向面试题编程」其实是一个查漏补缺, 增强自己编程基础的非常好的方式. 在做面试题的时候, 你会遇到很多奇奇怪怪的问题, 很多都是你「之前没有接触过」或者「有接触过却没有往那方面想」的问题.
刚开始遇到这些面试题确实很让人很不舒服, 但是这些面试题也确实能够最大限度地提升我们对知识之间联系的理解以及引发我们对一些具体使用场景的思考. 当然更重要的是我们可以通过刷往年各大互联网公司的面试题, 让我们对于公司面试题有一个大致的认识而且也能提前了解到面试官面试时候的一些套路和做法.
在这里推荐一些我看过的, 觉得很不错的面试资料:
Android 面试指南 https://xiaozhuanlan.com/android-interview
Android LearningNotes https://github.com/francistao/LearningNotes
Android 面试 https://www.jianshu.com/nb/3450453
二, 面试的一些建议和套路
首先, 要强调一点, 想拿到自己满意的 offer, 最重要的就是提升自己的编程能力, 特别是计算机方面的基础, 这是每轮技术面试都必问的. 没有足够的实力, 再高的面试技巧也是没用的.
不过, 在面试中确实也有很多需要注意的地方, 甚至存在一些通用的经验和套路. 掌握一些必要的面试技巧才能在面试官面前最大程度的展示我们自己真正的水平, 甚至超常发挥, 从而拿到满意的 offer.
寻找自己的兴趣点, 并将其培养成自己的瑞士军刀
在学 Android 的过程中, 其实每个人都有着自己跟别人不一样的兴趣点, 例如我自己对「Android 网络」,「图片加载」这两方面的知识就有很大的兴趣. 如果想要在 Android 面试中脱颖而出, 拿到让自己满意的 offer, 拥有某个「能超过绝大部分人」的技能是非常必要的, 也就是所谓的你最出彩的地方.
在这次阿里技术二面的时候, 面试官一上来就说:"上一轮的面试官已经问了很多关于项目的东西了, 你给我讲一下你觉得自己在 Android 中学的最好的东西吧." 当时听到这个问题我心中一阵窃喜, 因为之前花了很多的时间和精力在学习「Android 网络」和「图片加载」这两方面, 对于这两方面我还是很有把握的, 最终也顺利通过了阿里的技术面试.
上面举的例子就是为了说明拥有某些技术特长的重要性, 在面试中很多时候面试官关心的是你会什么, 而不是纠结你不会什么. 而且技术的深度也比广度要重要的多, 如果你在某方面研究的比较深, 很有自己的心得和体会, 甚至连面试官在这方面都没办法问倒你的话, 通过这次面试的成功率就会大大增加.
将所有的知识点写成对应的逐字稿
在日常的 Android 开发和学习过程中, 相信很多人会觉得我们学过的东西自己都已经明白了, 但是真正在面试官面前, 被面试官问到问题的时候却不知道怎么「完整」,「清晰」地表达出来. 针对这个问题, 我自己的解决方法是将我们在面试中可能会遇到的所有的知识点「全部」都写成对应的逐字稿.
这里的逐字稿有三个要点:
必须是自己的总结和体会
结合你自己的开发和项目经历
能够流畅的朗读出来
写逐字稿的目的是让我们在面试官面前能够「完整」,「清晰」地表达出我们对知识的把握和理解, 所以必须用「自己的语言」将自己的总结和体会写出来, 只有这样我们才能记得更牢. 在写完逐字稿之后, 我们可以试着朗读一下, 看看能不能流畅的朗读出来, 如果中间有一些拗口或别扭的句子, 就把它逐渐改进.
在这里, 我用「讲讲你对进程和线程的理解」这个问题来详细讲一下, 如果我们在事先没有准备好相应的逐字稿的话, 我们可能就会直接讲:
线程是 CPU 调度的最小单元, 同时线程也是一种有限的资源. 而进程一般指一个执行单元, 在 PC 和移动设备上指一个程序或者一个应用. 一个进程可以包含多个线程.
然后就这么完了, 完了, 了. 20 秒解决问题, 接着面试官估计也会回你一句, 今天就这么结束吧. 在这里分享一下我自己对于「进程与线程」的部分逐字稿, 大家可以参考一下.
进程与线程
按照操作系统中的描述. 线程是 CPU 调度的最小单元, 同时线程也是一种有限的资源. 而进程一般指一个执行单元, 在 PC 和移动设备上指一个程序或者一个应用. 一个进程可以包含多个线程.
进程
当一个程序第一次启动的时候, Android 会启动一个 Linux 进程和一个主线程. 默认情况下, 同一应用的所有组件均在相同的进程中运行. 如果我们需要控制某个组件所属的进程, 则可在 AndroidManifest 文件中执行此操作.
组件运行在哪个进程中, 是在 AndroidManifest 文件中进行设置的, activity,service,receiver 和 provider 均支持 Android:process 属性, 此属性可以指定该组件应在哪个进程运行. 我们可以设置此属性, 使每个组件均在各自的进程中运行.
进程的优先级
Android 系统将尽量长时间地保持应用进程, 但为了新建进程或运行更重要的进程, 最终需要移除旧进程来回收内存. 为了确定保留或终止哪些进程, 系统会根据进程中正在运行的组件以及这些组件的状态, 将每个进程放入 "重要性层次结构" 中. 必要时, 系统会首先消除重要性最低的进程, 然后是重要性相对较高的进程, 以此类推, 以回收进程.
重要性层次结构一共有 5 级
1, 前台进程 - Foreground process
2, 可见进程 - Visible process
3, 服务进程 - Service process
4, 后台进程 - Background process
5, 空进程 - Empty process
线程
线程在 Android 中是一个很重要的概念, 从用途上来说, 线程分为主线程和子线程, 主线程的作用是「运行四大组件以及处理它们和用户的交互」, 而子线程的作用则是「执行耗时任务, 比如网络请求, I/O 操作等」, 由于 Android 的特性, 如果在主线程中执行耗时操作那么就会导致程序无法及时地响应. 因此耗时操作必须放在子线程中执行.
Android 中的线程形态
除了 Thread 本身以外, 在 Android 中可以扮演线程角色的还有很多, 比如 AsyncTask 和 IntentService, 同时 HandlerThread 也是一种特殊的线程. 尽管 AsyncTask,IntentService 以及 HandlerThread 的「表现形式」都有别于传统的线程, 但是它们的本质仍然是传统的线程.
我相信, 如果你能像我上面的逐字稿这样, 结合 Android 里面的知识点清晰地表达出你对进程和线程的理解的话, 面试官肯定会很满意的.
这里附上我自己的逐字稿目录, 大家也可以按照这样的分类, 来对自己的「知识体系」建立不同的逐字稿.
遇到不懂的面试题直接回答不懂, 但最好能将面试官的思路往我们会的东西带
在面试的时候, 切勿不懂装懂. 我们面试的是技术岗位, 有几斤几两, 面试官问几个问题就知道了, 如果面试官问到的某个知识点, 你只是有点印象或者没多少了解的话, 直接回答这个知识不是很熟就行了. 不然被面试官针对这个知识点追加几个问题的话, 分分钟打你脸.
当然, 在说对这个知识不是很熟之后, 可以试着将面试官的面试思路往我们会的东西带, 例如我在阿里二面的时候, 面试官问我有没有用过 B 树, 因为我对 B 树不是很熟, 所以我当时是这么讲的:"对于 B 树不是很熟悉, 但之前在看 HashMap 源码的时候, 有研究过红黑树, 对红黑树比较熟." 然后成功地将面试官的问题转向了我熟悉的红黑树和 HashMap 的源码上面.
有意识地锻炼自己的沟通和表达能力
如果想拿到满意的 offer, 除了自身的技术实力过硬之外, 拥有良好的沟通和表达能力也是非常重要的. 即使实力再强, 你不能很好的表达出来的话, 也是白费功夫. 沟通和表达能力需要长时间的「刻意练习」, 并没有什么捷径.
其实在大一的时候, 我的沟通和表达能力也是相当差的, 但后来自己开始慢慢明白了这项能力的重要性, 所以在很多场合都会「刻意练习」这项技能. 而且自己后来当上了团队的负责人, 有很多场合都需要我上台演讲或者进行一些内部的分享, 再加上自己后来很喜欢玩「狼人杀」, 表达能力便在这两年间有了很大的提升.
每一次面试完都要进行复盘, 详细记录面试问到的题目
在每一轮面试结束之后, 不要急着放松或者休息, 先拿出备忘录将面试中面试官问到的问题「全部」都详细地记录下来. 而且找个安静的地方慢慢的回忆自己在面试过程中有没有哪些环节表现的不是很好或者是需要改进的.
每一次的面试都是一个很宝贵的经验和财富, 在面试过后都要对面试进行复盘, 找出我们在面试中表现的不够好的地方, 然后针对性地进行改进, 以及收集在面试过程中我们答不出来的面试题, 有针对的进行复习, 指不定下一轮面试问的就是你上一轮面试不会的问题, 而且这个可能性是相当大的, 因为面试官之间也是会进行交流的, 你的面试表现也会传到下个面试官的手中.
总结
想要拿到满意的 offer,「坚持」是最重要的, 抛开了努力和坚持, 其他的一切方法论都毫无用处. 任何一个行业都是不容易的, 唯有持续的「有效」努力, 才能走得更远.
以上便是我这半年来对于面试的一些经验和体会, 希望能对大家有所帮助.
来源: https://juejin.im/entry/5c7f1ceee51d4541e0170c7f