ios开发者谈谈技术面试那些坑
转眼又是秋季,是结束也是一场开始,离开了校园,我们中的大多数将要开始自己的职场生涯,我也是从大四开始漂泊北京,来来回回面试过几十次,经验丰富谈不上,但总是有可以说一说的东西。
首先,简历的制作,技术岗位求职要懂得HR看中你的地方,技术、人品,简历就是简单的陈述你的经历,不可做的太过于啰嗦,关键的地方要是你做过的项目,并介绍项目里的技术点和实现的功能,这里推荐智联的简历模板。有些同学刚刚毕业项目经验很少可以填写一些自己在校的编程比赛经历、实习项目等等。其次一些好的兴趣和活动经历是可以反应一个人的人品的,不要忽视一些小的细节,比如在上一家公司工作的时间,一般少于一年的就不要往上写了,这会令HR感到你的稳定性很差,招你进来会对公司造成损失的。好好过自己,牌已经发给你了,就看你如何打,我认识一个女生,是Dota世界女子组冠军,去摩根面试程员,前面的一堆技术问题回答的并不好,正觉无望的时候,面试官无意中看到她的玩游戏经历,后面半个小时竟然都在讲游戏,最后成功面上。并不是鼓励你们去玩游戏,只是想让你们懂的人生的每个节点都可以很精彩,要想精彩需要我们的思考乐观和努力,这也是面试官看中你的一点。
开始如果没有什么内推的机会的话,我还是推荐你们用智联来投递简历。收到面试通知的电话的后要把面试时间安排的近一些,我就有过因为多等了一天而错失机会的经历,不过也应该谨慎一些,去该公司官网查看一下他们的经营业务,一是为了防骗,二来可以在面试的时候有的放矢的针对该公司的需求技术侃侃而谈。面试路上,在北京的话转一圈真的挺费劲的,出行选择地铁避免堵车,带充电宝,纸质简历,吃好穿好,照顾好自己,时刻给自己鼓励,我们的技术不好可以学,可我们一直要做最好的自己。
提前半小时到,礼貌用语。基本的面试流程就是做一套题(根据具体公司而定),HR带你去一间小屋等候面试官的面试,开始面试官会看你的简历,这时候你要做一下简单的自我介绍,概括补充你简历上面的内容,后面是一些技术问题,所以应该提前多做准备,后面我会总结一些关于ios的面试题。面试官有的凶狠咄咄逼人,有的很和婉,都不要怕,如实回答,落落大方就好了,千万不要委屈了自己,将就了一个比自己预期很低的薪水,那样会后悔很久的。有一次竟然遇到群面,两个面试官,我们四个面试者坐对面长凳,有需要抢答的问题,有需要我们轮流来答的问题,放平心态,尽量扬长避短,发挥自己的长处。
面试后可以做一个表单,记录面试的公司、地址、面试情况、薪资情况等,方便自己对照查看,好记性不如烂笔头,良好的分类记录是很有帮助的,这也受用于你工作后。有几次面试后总是后悔,后悔没有要到面试官的微信,比如一次面试官是高我几届的同校学长,有一次是来自谷歌的工程师,要到微信后可以三天后问候一下,难免会有忘记通知的情况,再来这也是你的资源,毕竟都是大牛,我们的面试也是一次开阔自己的经历。
玄学,人都是需要一些运气的,面试也不能逃脱,有的公司可能只是为了解决一个技术问题并不真正的招聘,有的却是真正的急需招人,前者你技术再好也进不去,后者倒可以不是那么艰难,开始来北京的时候,我也是有这样的运气,很冷,从很远的地方匆匆赶来,差不多想要放弃了,却被录取了,有一定的运气,所以千万不要放弃任何的一次机会,所谓,柳暗花明又一村。
华丽的分割线
下面分享一些总结的面试题,希望能有帮助
1、viewWillAppear和viewDidLoad这两个方法谁会先被调用。
viewDidLoad先被调用,一个是load加载一个是appear呈现。
2、代理和block的区别。
block 和 delegate 都可以通知外面。block 更轻型,使用更简单,能够直接访问上下文,这样类中不需要存储临时数据,使用 block 的代码通常会在同一个地方,这样读代码也连贯。delegate 更重一些,需要实现接口,它的方法分离开来,很多时候需要存储一些临时数据,另外相关的代码会被分离到各处,没有 block 好读。
3、算是问题2的深入,单例里面的方法回调要用什么方法。
需要用block,因为用代理的话,如果多个对象同时调用单例的方法,那么只有最后一个对象能够得到响应。
4、TCP和UDP的区别。
TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂。
UDP(User Data Protocol,用户数据报协议)
(1) UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
(2) 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
(3) UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
(4) 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
(5)UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。
(6)UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。
5、什么时候用链表什么时候用数组。
从数据结构上来说,数组比较适合做查询,相对链表来说数组的查询效率高一些。链表的话因为他是指针指向下一个元素,在做插入一个元素或者删除一个元素只要改变指针指向就行(数组的话后面元素都要改)。
6、NSString为什么要用copy关键字,如果用strong会有什么问题?
使用strong关键字后创造出的对象和原对象的对象地址是一样的,指向同一个对象,而使用copy关键字对象地址是不一样的,是创建了一个新的对象。由此我们可以看到如果原对象的值有了改变使用copy关键字的就会跟随改变因为地址是一样的,而使用strong关键字的就不会跟随改变,因为是新创建的对象,地址是不一样的。
7、oc使用什么机制来管理对象内存?
mrc 手动内存管理
arc自动引用计数
garbage collection(垃圾回收) 但是ios不支持垃圾回收,arc作为llvm3.0编译器的一项特性,在ios5.0(xcode4.0)版本后推出。
arc的判断规则是,对象没有强指针指向对象,对象就会被释放。
8、为什么IBOutlet修饰的View也是用weak关键字?
因为当我们将控件拖到storyboard上就相当于新创建了一个对象,而这个对象加到视图控制器的View上的,View有一个subviews属性,这个属性是一个数组,而我们加的控件就在这个数组中,那么实际上我们的控件对象是属于View的,也就是说View对加到他上面的控件是强引用。当我们是用outlet属性的时候,我们是在viewcpntroller里面使用,而这个outlet属性是由View强引用的,在viwecontroller里面仅仅是对其使用,并没有必要拥有它,所以是weak。
9、可变集合类和不可变集合类的copy和mutablecopy有什么区别?如果集合是内容复制的话,集合里面的内容也是内容复制吗?
首先我们要明白一个概念,什么是倩复制,单层深复制,完全复制(每一层都深复制)浅复制就是指针复制并没有进行对象复制;
单层深复制就是我们常说的深层复制,我们这里说的单层深复制是针对集合类说的(NSArry, NSDictionary,NSSet),单层深复制值得是只复制了该集合类的最外层,里面的元素没有进行复制(即这两个集合类的地址不一样,但是两个集合里所存储的元素的地址是一样的);
完全复制指的是完全复制整个集合类,也就是说两个集合类地址不一样,里面所存储的元素地址也不一样。
[immutableObject copy]//浅复制
[immutableObject mutableCopy]//深复制
[mutableObject copy]//深复制
[mutableObject mutableCopy]//深复制
NSArray*copyArray = [[NSArrayalloc] initWithArray:array copyItems:YES];// 完全复制
10、如何令自己写的对象具备拷贝功能?
需要实现NSCopying协议,如果自定义的对象分为可变版本和不可变版本,那么就需要同时实现NSCopying和NSMUtableCopying协议。
11、属性的默认关键字是什么?
对于基本数据类型默认关键字是atomic,readwrite,assign
对于普通的oc对象是atomic,readwrite,strong。
12、用熟悉的语言实现n的阶乘。
//求阶乘
int factorial(int n){
if (n == 0 || n == 1) return 1;
return n*factorial(n - 1);
}
int main(){
int n;
int sum = 0;
for (int i = 1; i <= n; i++){
sum += factorial(i);
}
printf("结果为: %d\n", sum);
return 0;
}
13、为什么说Object-C是一门动态语言?
有三个名词容易混淆:
Dynamic Programming Language 动态语言或动态编程语言
Dynamically Typed Language 动态类型语言
Statically Typed Language 静态类型语言
(1)动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化。比如众所周知的ECMAScript(JavaScript)便是一个动态语言。除此之外如Ruby、Python也属于动态语言,而c、c++等语言则不属于动态语言。
(2)动态类型语言 意思就是类型的检查是在运行时做的。
(3)静态类型语言 类型判断是在运行前做的(如编译阶段),比如Java就是静态类型语言,静态类型语言为了达到多态会采取一些类型鉴别手段,如继承、接口,而动态类型语言却不需要,一般的动态语言都会采用dybamic typing,常出现在脚本语言中。是不是动态类型语言和这门语言是不是类型安全的完全没有联系。
(4)不同类型语言的优缺点 静态类型语言的优点在于其结构非常规范,便于调试,方便类型安全;缺点是为此要写很多的类型相关代码,导致不便于阅读、不清晰明了。动态类型语言的优点在于方便阅读,不需要写很多的类型相关的代码;缺点是不方便调试,命名不规范时会造成读不懂。
(5)Object-C的动态运行性 Object-C语言是C语言的子集,所以是静态类型语言,但是其特性之一多态让其拥有了动态性。oc的动态性让程序可以在运行时判断其该有的行为,而不是像c等静态语言在编译构建的时候就确定了下来。她的动态性主要体现在以下三个方面:
a、动态类型
b、动态绑定让代码在运行时判断调用什么方法,而不是编译时,和其他面向对象语言一样,方法调用和代码并没有在编译时绑定到一起,而是在消息发送时才进行连接。运行时决定调用哪个方法。
c、动态载入让程序在运行时添加代码模块和其他资源,用户可以根据需要加载一些可执行代码和资源,而不是再启动时就加载所有的组件。可执行代码中可以含有和程序运行时整合的新类。