让 BAT 的 Offer 不再难拿

什么是面试

有些人可能会把面试看的太重,觉得面试过了就能进入大厂,技术和财富兼得……

我倒是觉得,面试没有这么夸张(抱歉做了一回标题党),它其实是一次你和面试官互相了解的绝佳机会,借此机会你还可以对未来的工作有初步的了解。

面试本身并不能完全评价一个人的实力。面试通过的人,也许只是恰好在面试时遇到了自己熟悉的问题,面试不通过,也有可能是面试官自身的问题,并非每个面试官都具备客观评价别人的能力。

换句话说,面试没通过也许是面试官没有发现你的才华,面试通过了也并不代表你就能胜任工作,因为进入企业之后可不是每天负责回答面试题!

所以从这一点来看,面试有点像相亲。你满意我,我满意你,王八对绿豆——看上眼了,那就一拍即合,否则就分道扬镳。我本人非常希望能够多几轮面试(实际并不总是能做到),这样大家都有充足的时间互相了解,决定去留。

网上某些面经中,介绍了一些装逼的方法,还有所谓的面试技巧,我是不太认可的。技巧需要有,这是为了让你更好的展示自己,而非坑蒙拐骗,无理取闹,无中生有。我更想展现一个真实的自己,如果面试官不认可,说明我们没有缘分,或者说自己的能力还不够。

面试要准备什么

有一位小伙伴面试阿里被拒后,面试官给出了这样的评价:“……计算机基础,以及编程基础能力上都有所欠缺……”。但这种笼统的回答并非是我们希望的答案,所谓的基础到底指的是什么?

作为一名 iOS 开发者,我所理解的基础是 操作系统、网络和算法这三大块,不同的开发方向可能有不同的侧重,但基础总的来说就是这些。我不推荐通过去网上看教程来学习这些基础知识,因为能用短短几篇文章讲明白的事情不叫基础,至少我没见过写得这么深入浅出的文章。

不知道有多少读者和我一样有过这样的困扰:我知道某些东西很重要,所以去百度查了资料,但是查到的文章质量很差,正确率没有保证。这其实是正常的,优秀的文章一般都放在优秀的作者的个人博客上,这恰恰是搜索引擎的盲区,所以一般只能搜到 CSDN、博客园这种地方的文章。自然就无法保证文章质量。

出于这种考虑,我在文章最后的复习资料中,提供了用于学习相关基础知识的书籍,如果您恰好是 iOS 开发者,还可以阅读我收集的一些高质量文章,正确性比较有保证(我写的除外)。

除了准备通用的基础知识以外,简历也是一个很重要的环节。一直很仰慕唐巧老师的猿题库,无奈简历太差,都没有收到面试邀请。后来好好改了简历以后,就没有这种问题了。

最后,当然是准备好相关岗位的基础知识了。作为 iOS 开发者,虽然 Swift 已经发布了快两年,但是大公司转向 Swift 的动作还不明显,所以 Objective-C 几乎是必备项,Swift 都不一定能算是加分项。iOS 方面的知识也必不可少,虽然招聘信息上写着如果基础扎实,零 iOS 基础也可以,但是现实往往是比较残酷的。

我的面试经历

扯了这么多,终于进入正题了,分享一下我的面试经历。题目如下,破折线后面是简单的解决思路

百度

一面:约 1.5 小时

首先是四个算法题:

1. 不用临时变量怎么实现 swap(a, b)——用加法或者异或都可以

2. 二维有序数组查找数字——剑指 offer 3

3. 亿级日志中,查找登陆次数最多的十个用户——(不确定对不对,我的思路是)先用哈希表保存登陆次数和ID,然后用红黑树保存最大的十个数。剑指 offer 30

4. 简述排序算法——快排,partion 函数的原理,堆排(不稳定),归并排序,基数排序。

然后有一个智力题,没完整的答出来,好像影响不是很大。

最后是 iOS 相关,面试官问的很开放,都是谈谈自己的理解:

1. 说说你对 OC load 方法和 initialize 方法的异同。——主要说一下执行时间,各自用途,没实现子类的方法会不会调用父类的?

2. 说说你对 block 的理解。—— 三种 block,栈上的自动复制到堆上,block 的属性修饰符是 copy,循环引用的原理和解决方案。

3. 说说你对 runtime 的理解。——主要是方法调用时如何查找缓存,如何找到方法,找不到方法时怎么转发,对象的内存布局。

4. 说说你对 MVC MVVM 的理解。—— MVC C 太臃肿,可以和 V 合并,变成 MVVM 中的 V,而 VM 用来将 M 转化成 V 能用的数据。

5. 说说 UITableView 的调优。——一方面是通过 instruments 检查影响性能的地方,另一方面是估算高度并在 runloop 空闲时缓存。

6. 谈谈你对 ARC 的理解。ARC 是编译器完成的,依靠引用计数,谈谈几个属性修饰符的内存管理策略,什么情况下会内存泄露。

一面的问题非常基础,主要是算法和 Objective-C,因为准备比较充分,基本上答出来 80% 吧。大约一周后突然二面。

二面:约 0.5 小时

二面比较突然,显示简单的自我介绍,然后问了三个问题:

1. 野指针是什么,iOS 开发中什么情况下会有野指针?——野指针是不为 nil,但是指向已经被释放的内存的指针,不知道什么时候会有,如果有知道的读者还望提醒。

2. 介绍 block—— (接第一问) 我让面试官提示我一下什么时候会有野指针,他说用 block 时,我表示还是不知道,只知道 block 会有循环引用。于是就扯回了一面的问题。

3. 说说你是怎么优化 UITableView 的。——还是一面的问题。。。。。。。。。。。

虽然通过了,但是几乎又问了一遍一面的问题让我感觉对方不太认真。

三面:北京 onsite,约 2.5 小时

首先是给一个小时,手写算法两个算法题。接下来问了 TCP 握手相关的。最后问了 OC 的一些细节问题。

网易

笔试

主要是计算机方面的大杂烩,涉及操作系统,网络,移动开发,算法等。难度不大,目测是为了淘汰浑水摸鱼的人,就不列出题目了,算法有三题,直接在线写(木有 IDE 表示很忧伤):

1. 很长一道题,读了很久才读懂,目测是 DFS,但是最后没时间了,写了个思路。

2.  "www.zhidao.baidu.com" 这样的字符串改成 "com/baidu/zhidao/www"——老题目了,剑指 offer 的,两次逆序排列即可。

3. 求数组中和为某个值的所有子数组,比如数组是 [5,5,10,2,3] 一共有四个子数组的和是 15,比如 [5,10][5,10][10,2,3][5,5,2,3]。这个就是简单的递归了,分两种情况,当前位置的数字在子数组中,以及不在子数组中。

一面

全部是 iOS 题,可能是觉得算法已经面过了:

1. 介绍 block——我提到栈上的 block ARC 下会自动复制到堆上,面试官问我从 iOS 4 还是 5 开始支持这一特性,表示不知道,我又不是学 OC 历史的,后来想想可能是公司内部老项目有这个坑。

2. ARC 会对代码做什么优化?——比如 NSString *s2 = s1; s2 = nil 这样的语句,可能就不会有 retain  release 方法了。

3. 介绍一下 MVVM RAC——可能是我简历的某个角落写了用过 RAC,被挖出来了,大概谈了一下,结果面试官问我数据的双向绑定怎么做,bind 函数了解过么,果断说已经忘了

4. 介绍自己用过哪些开源库。——Masonry SnapKitAFNetWorkingMKNetworkKitAlamofireMantleSDWebImage

5. 如果让你写,你能实现么?——当然不能,不然还要实习?

6. 读过某个库的源码么?——扯了一点 SDWebImage,后来被告知这个库用了 runloop 来保证滑动是加载数据的流畅性,自己看了源码后表示没有发现,唯一用到 runloop 地方是保证后台线程一直跑,也有可能是我理解错了,如果错误欢迎指正。

7. SDWebImage 下载了图片后为什么要解码?——当时蒙住了,面试官很 nice 的解释了一下,说是要把 png 文件建立一个什么内存映射,目前还不太懂,有空研究一下。

本来以为面的这么差肯定是挂了,没想到还是过了一面。过了不到一个小时,HR 电话打过来,约了两天后二面。

二面

纯数学和算法:

1. 

下面这段代码的输出结果是:

2. 

 int main() {

     int a[5]={1,2,3,4,5};

     int *ptr=(int *)(&a+1);  

     printf(“%d,%d”,*(a+1),*(ptr-1));

  }

3. 

答案是 2 5是指向数组开头元素的指针,a + 1 就是指向下一个元素的指针,所以星号求值以后是 2&a 相当于是数组的指针,&a + 1 是数组后面一个数组的指针,然后转换成int *类型是 5 这个数字后面的一个数字的指针。再减一就是指向 5 的指针,所以星号求值以后是 5

4. 

5. 

某个地方天气有如下规律:如果第一天和第二天都不下雨,则第三天下雨的概率为30%;如果第一天和第二天中有任 意一天下雨,则第三天下雨的概率为60%。问如果周一周二都没下雨,那么周四下雨的概率为_

6. 

简单的概率题,答案是:30% * 60% + 70% * 30% = 39%

7. 

8. 

某痴迷扑克的小团体喜欢用23456789TJQKA来计数,A后面是22,23,...,2A,32,...,AA,222,... 依次类推。
请用C/C++Java写个程序,将用字符串表示这种计数法转换成字符串表示的10进制整数。其中,该计数法的2就对应于十进制的2,之后依次递增。C/C++函数接口: char pokToDec(char )

9. 

我的解决思路是进制转换,类似于 16 进制转换 10 进制这种,最后再把数字转成 char * 类型。

10. 

然后好像没结果了,可能是编程实现太渣了?

其他我知道的面试题

阿里一面:

1. MVC 具有什么样的优势,各个模块之间怎么通信,比如点击 Button 后 怎么通知 Model

2. 两个无限长度链表(也就是可能有环) 判断有没有交点

3. UITableView 的相关优化

4. KVONotificationdelegate 各自的优缺点,效率还有使用场景

5. 如何手动通知 KVO 

6. Objective-C 中的 copy 方法

7. runtime 中,SEL  IMP 的区别

8. autoreleasepool 的使用场景和原理

9. RunLoop 的实现原理和数据结构,什么时候会用到

10. block 为什么会有循环引用

11. 使用 GCD 如何实现这个需求:ABC 三个任务并发,完成后执行任务 D

12. NSOperation  GCD 的区别

13. CoreData 的使用,如何处理多线程问题

14. 如何设计图片缓存?

15. 有没有自己设计过网络控件?

阿里二面:

1. 怎么判断某个 cell 是否显示在屏幕上

2. 进程和线程的区别

3. TCP  UDP 区别

4. TCP 流量控制

5. 数组和链表的区别

6. UIView 生命周期

7. 如果页面 A 跳转到 页面 BA viewDidDisappear 方法和 B viewDidAppear 方法哪个先调用?

8. block 循环引用问题

9. ARC 的本质

10. RunLoop 的基本概念,它是怎么休眠的?

11. Autoreleasepool 什么时候释放,在什么场景下使用?

12. 如何找到字符串中第一个不重复的字符

13. 哈希表如何处理冲突

面试收获

1. 算法题怎么答

面试官可能会问到你闻所未闻的算法,这时候你不应该自己瞎想,而是先和面试官把问题讨论清楚。要知道,通过沟通弄明白复杂的问题也是一种能力,在和面试官交流的过程中,不仅仅可以搞清楚题目真正的意思是什么,还可以展现自己良好的交流沟通能力。所以千万不要因为紧张或者害羞而浪费这次大好的机会。

有些题目似曾相识,但是暂时没有思路。这时候不妨告诉面试官,给我一些时间思考这个题。然后不要急,不要慌,就当他不存在,拿出纸和笔慢慢算(这充分说明了面试戴耳机的重要性)。你一定要坚定一个信念:任何一道稍微有难度的算法题,除非做过,否则一定是需要时间想的。所以,合理的安排思考时间吧。如果十几分钟都想不出来,可以直接放弃。

有时候面试官会要求在线编程,相信我,他不会无聊到盯着你的代码看的,面试官一般都很忙,他也有自己的工作要完成,所以你就当是用自己的 IDE 就好。在线编程往往是一个中等难度的问题,所以不要自己吓唬自己。同时要注意代码格式的规范,适当的注释,提前编写好测试用例等,即使没有解决问题,也至少要把自己良好的编程习惯展示给面试官。

2. 遇到不会的问题怎么处理

这个问题有可能是面试官故意说得含糊不清,考察你的交流能力,也有可能是无意的,或者是你的理解方式出现了偏差。不管是以上哪种问题,你都应该先和面试官交流,直到你搞懂了面试官要问你什么,而不是按照自己的理解说了一堆无用的东西。

举个例子,面试官可能会问了一道算法题:如何判断两个无限长度的链表是否有交点?。对于无限长度可以有不同的理解,如果真的是有无穷多个节点,那显然这个问题是无法解决的。但如果链表仅仅是有环,那么还是可以解决的。如果面试官的本意是链表有环,但你错误的理解成了无穷多个节点,那么必然会导致无法回答这个问题。而且这并非能力不足,而是属于交流沟通方面的失误,这也正是我想分享的技巧

还有一些问题,虽然你没有接触过,但是由于对类似的问题或者情况有过思考,所以可以合理假设。比如面试官问 “ARC 会对代码做什么样的优化?。我们知道 ARC 的本质就是在合适的地方插入 retain  release 等方法,那么就应该从这个角度出发去思考问题。

显然分别执行 retain  release 操作是没有必要的,那么就可以构造出相应的例子:

NSString *s1 = @"hello";

NSString *s2 = s1;

NSString *s2 = nil;

由于这种问题我们没有真正实践过,所以可以委婉的告诉面试官:根据我的推理,可能会有……”

3. 遇到真的不会的问题怎么处理

遇到不会的问题果断承认啊。如果是基本问题,比如问你哈希表怎么实现,你说不会,那么这次面试可能就悬了。如果是有一定难度的问题,那么你承认不会,也是一种明智之举,毕竟人无完人,一个问题不会并不能全盘否定一个人的能力。

但是比较糟糕的一种情况是,面试者由于过分紧张,担心答不上面试官的问题会有严重后果,所以尝试着去敷衍面试官。比如:我猜是 xxx 我觉得可能是 ……”,更有甚者直接装逼:这个我试过,不就是 xxx 。要知道,此时的你,由于紧张,在心态上已经输给了面试官,更何况面试官问你的问题一定是他有把握的,你觉得这时候你负隅顽抗会有几成胜算呢?

所以,面试官问我堆排序的细节时,由于我当时忘了堆排序是怎么实现的,所以我直接告诉他我记不清了。另一个主动认输的例子是面试官问我 RAC 如何实现双向绑定,我告诉他这个是我当时学习的时候写过的 demo,因为不常用,已经只记得一些简单的概念了。

最后,还需要保持一个平稳的心态:面试时尽力就好,遇到自己不会的问题也是正常情况。如果面试者顺利答对了所有问题,难免会让面试官感到一丝尴尬,面试者也有可能会产生一些别的情绪。所以,我们要做的只是把自己的能力展示给面试官,做到不骄不躁。

4. 准备杀手锏

除了能够回答上面试官的问题以外,我建议自己准备一两个杀手锏级别的话题。所谓的杀手锏,至少具备以下几个特征:

· 你亲自动手试验过。所谓实践是检验真理的唯一标准,数据是不会说谎的。

· 问题有足够的深度。一面的面试官可能是你的直接上司,二面一般就是更改级别的。你的深度一定要远超其他面试者,让一面面试官觉得自己没有十足把握,让二面面试官觉得这是一个好话题,自己的手下都不一定能有这么独到深刻的见解。

· 你对这个问题理解的足够深入,无论是广度还是深度都达到一定水平。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值