2018年iOS面试总结
从今年8月初开始找工作到现在,历时一个半月,终于进入了收尾的时候。这一个半月经历了很多,学习了很多,也成长了很多,所以做个总结。总结既是对这一个半月学到的东西,进行一个梳理,也是对未来的一个展望:公司需要的是什么样的人才,看中你的什么?自己需要培养什么技能,需要哪些习惯?本文按照三部分来做总结:第一部分,公司需要什么样的人才;第二部分,自己需要培养什么;第三部分,应聘iOS需要掌握些什么。第三部分,思路是按照第一部分和第二部分的总结,针对iOS需要的一个梳理。本文是从面试iOS的角度出发的,接下来的博文中的一些表达和思考可能会与计算机专业和iOS相关性比较大。
公司需要什么样的人才
有哪些公司(目标)
根据我面试的经历,我这边把公司分为四类,A类、B类、C类、D类,知名度和难度都是依次递减。A类是属于技术行业领先、知名度行业领先、公司业务发展行业领先,就我们行业论,BAT自是无话可说(这边不考虑巨头如Google、Facebook),还有已经被人熟知的京东,网易等,以及近几年崛起的如今日头条、滴滴、美团、饿了么等等。B类是,近两年发展很迅速,前景还不错的公司,如拼多多、爱奇艺。C类是已经稳定发展的创业公司,业务和各方面都还不错,资金都很充足。最后一类D类,可能是属于一些创业公司比较初期,或者是一些大公司旗下的子公司,也有可能是一些海外公司在国内拓展业务的子公司,这一类相对来说,人员不是很充足,团队也还需要壮大,一般比较冒险。
公司是怎么样的要求
这边,都是根据我自己面试经验的总结和推敲,不同类的公司,一般是怎么样的要求,如果有不对或不合理的地方,恳请指正。
由于有些要求是类似的,或者必须的,如果自上而下(A类->D类)介绍可能会有重复累赘,所以这边自下而上介绍。
首先是D类,这类公司一般会有一个明确的,需要的业务,比方说我面过的一家,是想自己包装一个浏览器,针对用户流量做一些事情。所以它可能会需要至少它业务相关方面的知识储备是有的,比方说对网络协议比较清楚,DNS比较了解。然后你去了,可能也不仅仅是做一个方向的事情,比方说你做APP客户端,如果会后台,也需要帮衬一下,可能相对会有一些杂事。然后,一些框架,前后端的架构,很有可能是用一些比较现成的。总的来说,要求不高,但还是可能会考你一些很基础的东西,简单的算法题,网络和操作系统的一些知识。
接下来是C类,这类公司业务比较成熟,技术团队规模不会太大,但一般都是相对有经验的人。它们的要求,除了你拥有基础以外,更多的可能是,实际经验,业务能力。我觉得,这方面短时间,比较难以补出来,所以还是有一定难度的。它们一般对基础不会问的太深入,但是会给你一个业务场景,需要你去实现这种业务场景。可能更需要的是,你平常对技术有研究,比方说热更新,平常业务可能很少用到,但是你如果去研究这种技术,看相关源码和实现,甚至动手写Demo,做实验,有这样的积累也是不错的。总之,要么你之前的公司很多业务,技术都是比较丰富的,要么自己研究的比较多。
然后再来看B类,这类公司发展和前景都不错,而且处于扩张期,粗放增长。它们对人才的需求量比较大,既有一定的基础,又有大量的业务。所以,对人才一般来说,基础会多看重些,经验可以相对少一些。它们的面试一般,会偏向计算机基础,但是会比较深入,算法要求会比较高。当然,对你所从事的方向的知识,考察的也会比较多。
最后是A类,这一类基本算是TOP了,既然是Top,要求也是Top了。不但对你的计算机基础,算法功底要求很高;对你从事方向的知识掌握也要比较全面;还有对你解决问题的能力要求都比较高。当然,经验充足,基础扎实,技术栈丰富。这些,都是作为一个技术人员,不断追求的目标。基础,是解决问题的能力和思路来源;经验,是解决问题的能力体现和积累;技术栈或知识储备,是未来发展方向和Idea的来源。
自己需要培养什么
总结,上文的公司要求,自己需要培养的能力和积累的东西,主要有: 基础,从事方向基础和原理,经验+及时更新自己的知识库,跟上最新的技术潮流。
首先是基础,计算机基础无非是:操作系统(编译链接),网络,算法和数据结构。
操作系统
主要考察最多的是:线程、进程。
线程
考察线程的东西最多
- 线程和进程的区别和联系
- 多线程的实现方法
- 如何保证线程安全?加锁有哪几种方式/锁的实现方式有哪些?
- 死锁是什么?发生的条件?
编译连接
- C程序是如何一步一步变为可执行文件的?
- 虚拟内存是什么,一个程序的内存分配是怎么样的?
- 编译器做的什么?链接期又做的什么?
- 静态库和动态库的区别?为什么要有动态库?
- main函数是什么,为什么C程序的入口默认是main函数?
网络
基础的五层网络模型,TCP三次握手(四次挥手),上层的应用层(比较常见的有HTTP)
TCP/UDP
- TCP和UDP的区别,哪些场景适合用UDP?
- TCP如何进行拥塞避免?
- 滑动窗口是什么?具体是怎么样的?
HTTP
详细列举一下HTTP的关键知识: HTTP是一种无状态和无连接的协议(原因?)
- HTTP发送和接收的消息是如何包装的:头部+主体
- HTTP头部有哪些组成成分(最主要的是哪些)?
- HTTPS和HTTP的区别,HTTPS具体是怎么样实现请求的?
算法和数据结构
数据结构都是一些常用的,算法是需要不断练,也就是刷题的,这里推荐一些书籍。’
如果你对基础算法还不是很了解,《数据结构与算法分析》,有C语言版和Java版,简单易懂,看完就会对基本的数据结构比较了解,还有一些不太常用的数据结构也有介绍,希尔排序、不相交集、B树等。
如果想要进阶,肯定是《算法导论》,相对比较深奥,难以理解,可以挑自己感兴趣的,比方说,算法导论里的快排,简短精妙,短短几行代码就写完了,而且对复杂度的分析、改版都很透彻。
还有就是一些刷题的OJ,找工作本人比较推荐LeetCode。LeetCode的题分三个等级,Easy\Medium\Hard。如果你很久没写算法题,推荐先从Easy刷起,Easy和Medium的题一般考察的是对基本的算法和数据结构的掌握,所以一般基础相对薄弱的,就刷Easy和Medium就行了;Hard级别的偶尔想要挑战一下的时候,可以试一下。
然后刷题有几点建议:1. 推荐C++刷题:C++既需要你对算法有一定的思考(不那么方便),C++又有STL,有一些基本数据结构和算法可以拿来直接用,是锻炼算法的最佳(我认为)语言。 2. 不要用IDE,直接用LeetCode的编辑器:不借助IDE,有助于记住基本的API,忘记了就去cplusplus(C++)查询 ,培养手写代码的能力 3. 尽量自己写出来,实在写不出来,先看Hint;还不行,再看Discuss, 可以找Votes比较高的;最后写完了,或者写不出来,再看Solution。
LeetCode还有一个功能就是Tag, 按数据结构分: Tree、Stack、Graph等;所以还有一种思路,你可以先看完《数据结构与算法分析》的某一章,比方说“树”,然后专门刷Tree的题,巩固和提高对它的掌握。
应聘iOS需要掌握些什么
上面部分主要是作为计算机(IT)面试都需要掌握的知识,只是不同方向,不同公司可能深浅不一,我也只是从我的面试经历总结,可能会有偏颇和遗漏。接下来的部分,是我作为一个iOS开发,面试iOS岗位的一些知识的总结。
我按三个部分来讲,原理,架构和其他,其他部分比较杂,但是是一些做iOS都会用到的知识和技能。
原理
- Objective-C Runtime
- iOS Runloop
- 事件响应链
- 内存管理:MRC,ARC,autorelease
- Block
- GCD
- JSCore(Exception)
Objective-C Runtime
最基本的,要对Runtime有一定了解,OC的Runtime是什么?消息是如何转发的?
会问到的一些问题:
- 你怎么理解OC的动态性?
- 系统有哪些利用Runtime的应用?(KVO, Category)
- KVO是怎么实现的?
- Category可以添加方法吗?可以添加属性吗?为什么?
- Runtime有哪些应用?
- NSProxy了解吗?
- RunTime中涉及到的结构体是怎么样的?
iOS Runloop
基本的,要对Runloop了解?Runloop是什么?它的结构是怎么样的?Runloop的内部逻辑(流程)?
会问到的一些问题:
- 如何把一个任务放到下一个Runloop执行?
- 为什么Tableview下拉刷新的时候,timer会失效?解决方法?
- Timer放在主线程和子线程一样吗?如果不一样,有什么区别?
- 为什么Timer必须要invalidate?
事件响应链
基本的,描述iOS事件传递的整个过程?
会问到的一些问题:
- 有这样一个应用场景。一个应用的Tabbar上,有几个按钮,但是按钮的一部分在Tabbar范围外,如何做到点击按钮Tabbar范围外的地方,也能响应?
- 给一个Tableview的Cell添加手势,事件响应链会有怎么样的变化?会先响应手势呢,还是Cell会先响应?
- UIControl在事件响应链中的作用,以及它的优先级?
内存管理:MRC,ARC,autorelease
内存管理,基本的,iOS的内存管理是怎么样的?然后比较多问的,是问OC属性相关引发的问题
会问到的一些问题:
- OC的属性中,哪些和内存相关?
- 哪些类型需要用copy属性?
- assign一般修饰什么?它可以修饰对象吗?
- strong和weak的区别?weak是如何实现的?
- 如何避免循环引用?
- weak和unsafe_unretained有什么区别?什么情况下会用到unsafe_unretained?
- autoreleasepool了解吗?什么情况下会需要用到?
Block
基本的,Block是什么,为什么要有Block?Block是如何实现的?它放在内存的哪个区域?
会问到的一些问题:
- 什么情况下需要用block,block是如何实现的,对应的对象是放在堆上还是栈上?
- block会造成循环引用吗?什么情况下会造成?有哪些方法解决循环引用?
- block为何一般需要copy属性?
GCD
GCD和多线程相关,所以会问一些线程相关的东西引入。比方说iOS有哪几种多线程的方式?OperationQueue和GCD的区别?GCD的优势和劣势?
会问到的一些问题:
- 如何理解dispatch_async和dispatch_sync?
- 什么情况下会用到dispatch_group?
- 如何理解串行队列和并行队列?它是怎么实现的?
- main_queue和global_queue是什么?分别是串行的,还是并行的?
- 如果一个通知在global_queue中添加observer,然后又再main_queue中发送通知,那么这个通知的任务最后在主线程,还是子线程执行?
- dispatch_once是如何保证原子性的?
- 每创建一个新的队列就会产生一个新的线程吗?线程数量是有限的吗?如果要你定一个线程池的大小,你会选择多大?理由?
JSCore
JSCore相比于前面的原理不是那么重要,但是很多与JS打交道的东西都和它有关,比方说热更新的一些方案,JS_bridge的实现方案,RN、Weekx,都是基于它的;还有,最基本的,iOS的浏览器内核,主要是WebKit,主要的组成就是JSCore。主要是要搞清楚Webkit的组成,JSCore在其中扮演的角色,它是干什么的?
架构
iOS主要架构有MVC、MVP、MVVM,还有VIPER。可以找一些相关的博文深入理解和分析一下。关于MVVM,推荐Limboy的博客,介绍MVVM和使用RAC实现MVVM讲得很详细。
可能会问的问题:
- 你怎么理解MVC和MVVM?
- 我们知道RxSwift可以很容易实现数据的绑定,那么你知道它的原理吗?它是基于RAC的,对RAC的实现了解吗?
其他
- 组件化
- 热更新
- 持续化集成(CI)
- 设计模式
- 第三方库
组件化
组件化是17年比较火的一个概念,最早是由蘑菇街的Limboy提出组件化的方案和思路,然后Casa针对Limboy的方案提出一些改进和建议的思路,并给出了简单的Demo, 然后Bang在前三篇文章基础之上做了清晰的总结;然后,就掀起了一片讨论和热潮。我这边就不详细讨论了,研究得也还不是很透彻,所以,就简单贴几个链接。如果作者觉得侵权了,可以随时联系我删除。
热更新
热更新,是利用Objective-C的动态性,加上JSCore,实现对已有代码的更新和修复。所以,主要利用了OC的runtime和JSCore实现。使用最广泛第三方库实现是JSPatch,作者有对它实现整个库的过程和原理,有详细的博文说明。通过阅读它的源码和分析,基本上可以对热更新这一技术有一个比较全面的了解。
持续化集成(continue integrate)
持续化集成,是一个能够极大提高生产效率的一个思路。由于,很多公司的项目庞大,编译一次可能耗时几小时,甚至几天的时间。所以,能够在合适的时间自动编译,自动部署可以大幅度的减少一些重复和不必要的工作。目前iOS用的比较多的,有Jenkins和Fastlane。本人研究还不够深入,所以暂时不详细阐述。
设计模式
设计模式,其实面是向对象开发过程中,为了提高代码的复用性、可读性和可靠性,一套被反复使用的、许多程序猿验证使用、并梳理分类过的总结。苹果在iOS系统上,自己本身就应用了很多常见的设计模式。关于设计模式,网上介绍的有一大堆,但真实能否用起来,理解可能光看这些还不够。
我这边推荐一本书,《设计模式:可复用面向对象软件的基础(英文版)》,它囊括了基本所有常见的设计模式,而且每个设计模式,都是按目的、动机、结构、应用场景、优缺点和实际例子,还有常见的具体应用来讲述的。稍稍有点比较晦涩难懂,是因为它需要一定的抽象能力,但是你一旦理解了,对这个设计模式掌握得也就比较透彻了。书中的例子都是用C++写的,想必程序员对C++都应该不会陌生。
第三方库
第三方库,平常开发过程中经常会用到第三方库,由于它们的各种优点:易用、安全、高效等。其实,一些优秀的第三方库有很多值得我们学习和借鉴的地方,平常如果经常阅读它们的源代码可以学到很多东西。它们实现某个功能的思路,和解决问题的方法,还有一些良好的代码习惯,甚至是应对一些小点的一些Trick。有些第三方库的作者,不仅开源它们的代码,还自己写博客分析它们的库和写库的经历。作为一个程序员,学习和模仿是必备技能,而阅读第三方库,是一个相对比较高效和受益颇多的方法。
扯完淡,讲点实在的,简单介绍一下iOS常用的第三方库。
AFNetwork,客户端与后台、或固件的交互都是基于网络请求的,苹果系统自带就有网络请求库,URLConnection、URLSession,那么既然系统自带,为什么不用系统的呢?通过阅读AFNetwork,你能知道一个HTTP请求构成,需要哪些步骤,消息如何封装,还能看到它使如何处理和安排上层的多个请求的,还能够大致了解和掌握HTTPS的一个过程。
YYCache,YYCache的作者,自己就有分享它写这个库的过程和考量,以及自己解决问题的思路和最后的方案。通过学习YYCache,你可以对缓存设计有一定的思路和了解。
JSPatch,热更新的一个广泛备用的开源库。这个库的作者,也详细介绍了它写这个库的初衷,想法,初始设计和存在问题、解决问题的过程。通过他的介绍,你会对这种热更新有个全面的认识,也会对JS和客户端交互的一些方法有些了解,还有更加体会到OC Runtime的好处和精髓。
然后,还有很多很多,优秀的库值得我们学习。。。
写在最后
最后,写一些这一趟面试下来,觉得作为一个程序员需要培养注意的东西和养成的一些习惯,主要是用来提醒自己,和同样需要在这个方向不断前行的小伙伴。
- 多逛社区,阅读博客,跟上最新的技术潮流,学习新的技术
- 多看开源库,学习优秀代码
- 多写代码实践和验证一些理论,积攒经验和掌握理论
- 多做题,锻炼自己解决问题和巩固算法数据结构
- 多写博客,总结、分享自己的工作和研究
- 多和其他技术人员交流,分享自己的学习和知识(多写PPT演讲)
最后的最后,感谢你看到这儿,有什么问题,欢迎指出和纠正;有什么建议,欢迎提出和讨论。
我的Email地址: huanjianjiang@gmail.com