十个iOS面试问题

来源:互联网 发布:iphone图片加密软件 编辑:程序博客网 时间:2024/05/22 21:23
          不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘者技能和积累的考察,也是一个开发者自我检验的好机会。对于iOS和Mac开发来说,因为本事还算比较新,企业对于这方面的开发者需求也比较大,所以面试时的要求可能并不是很高,一般能知道一些Cocoa和OC的基本知识也就认为可以了。但是对于一个希望拥有技术力基础的企业的iOS或者Mac开发来说,两到三个顶尖的熟练技术人员,带领一些还较为初级的开发者,共同完成项目应该是比较常见的构成。

         Cocoa特别是CocoaTouch的开发,上手可以说十分容易,但是背后隐藏的细节和原理却很丰富。一方面对于基础不够熟练和清晰(比如从一个AppDelegate开始用代码构建ViewController,或者清晰地说明栈和堆之类的概念),另一方面对于更进阶的开发知之甚少(比如多线程、网络异步处理或者Core开头的各种框架等等)。这些内容十分重要,但是可能现在一般的iOS开发者或多或少都在这些问题上存在薄弱。在这里我整理了一份面向于较高层级的iOS开发者的面试题目的问题清单,列出了十个应聘Leader级别的高级Cocoa/CocoaTouch开发工程师所应该掌握和理解的技术。这份列表没有提供标准答案,因为这些问题本身就没有标准答案。随每个人对这些内容的认识的不同和理解的差异,可以有不一样的答案。但是最基本地,如果面对的是一名资深的Cocoa开发者,至少期望能得到的答案都是“接触过”,并且能结合自己的经验说个七七八八,达到互相能明白意图和方法的地步。能够在其中两三个领域有不错的见解和具体的阐述的话,那是更好。这种对于知识覆盖面和深度的考察很能真实反映出开发者的技术水平。如果清单里的很大部分内容都是完全没接触过和没听过的话,那可能距离资深Cocoa开发这样一个阶段还尚有距离了。

那么,面试开始。

  1.你使用过Objective-C的运行时编程(Runtime Programming)么?如果使用过,你用它做了什么?你还能记得你所使用的相关的头文件或者某些方法的名称吗?

答:整个OC都是运行在一套Runtime基础之上的。不过大部分我们不直接接触它的Runtime Programming.
我们使用下面这些方法时,动态判断一个对象的类型,是否能对某个方法进行响应等等,都用到了OC的运行时特点。
- (BOOL)isKindOfClass:(Class)aClass;
- (BOOL)isMemberOfClass:(Class)aClass;
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
- (BOOL)respondsToSelector:(SEL)aSelector;
运行时的一个头文件是objc/runtime.h。
我们可以利用里面的一些方法直接发送消息,如objc_msgSend().
也可以动态的给某个类添加方法,如class_addMethod().
甚至还可以动添添加一个类,如objc_addClass()。
objc_getAssociatedObjectobjc_setAssociatedObject设置属性

+ (NSArray *)findAllOf:(Class)defaultClass利用objc_getClassListclass_getSuperclass等获取当前Bundle下的所以defaultClass的子类.

// 将对象序列化到文件
    unsigned int outCount;
    NSMutableDictionary *finalDic = [[NSMutableDictionary alloc] init];
    objc_property_t *propList = class_copyPropertyList([self class], &outCount);
    for (int i = 0; i < outCount; i ++) {
        objc_property_t oneProp = propList[i];
        NSString *propName = [NSString stringWithUTF8String:property_getName(oneProp)];
        id value = [self valueForKey:propName];
        if (value) {
            [finalDic setObject:value forKey:propName];
        }
    }
    free( propList );


  2.你实现过多线程的Core Data么?NSPersistentStoreCoordinator,NSManagedObjectContext和NSManagedObject中的哪些需要在线程中创建或者传递?你是用什么样的策略来实现的?

UI框架内部还是由CA和CG实现的。
CA做过一些view的描边操作,还有淡入淡出的转场动画。
用CG做过一个画图程序,可以记录画笔的位置及线条颜色,可以合成一个UIImage.

  3.Core开头的系列的内容。是否使用过CoreAnimation和CoreGraphics。UI框架和CA,CG框架的联系是什么?分别用CA和CG做过些什么动画或者图像上的内容。(有需要的话还可以涉及Quartz的一些内容)

  4.是否使用过CoreText或者CoreImage等?如果使用过,请谈谈你使用CoreText或者CoreImage的体验。


  5.NSNotification和KVO的区别和用法是什么?什么时候应该使用通知,什么时候应该使用KVO,它们的实现上有什么区别吗?如果用protocol和delegate(或者delegate的Array)来实现类似的功能可能吗?如果可能,会有什么潜在的问题?如果不能,为什么?(虽然protocol和delegate这种东西面试已经面烂了…)

KVO只能监测属性的变化,通过NSString类型的属性名来实现。但是实现了自动监测,当属性值变化时,会自动通知观察者,不用再添加代码了。
NSNotification比较灵活,可以监测的内容较多,但是需要被观察者手动发送通知,观察者才能响频。
protocol通过添加一个NSArray也能实现类似的功能,但是实现上需要自己处理delegate的添加与删除,自己在属性变化时手动通知,较繁琐,易出错。

  6.你用过NSOperationQueue么?如果用过或者了解的话,你为什么要使用NSOperationQueue,实现了什么?请描述它和GCD的区别和类似的地方(提示:可以从两者的实现机制和适用范围来描述)。

我们已经知道iOS还提供了一种叫做NSOperationQueue的队列机制。就像分派队列一样,它也接受块作为参数并加入队列。你可能会问:什么时候应该用GCD,什么时候又应该用NSOperationQueue呢?

下面是NSOperationQueue和GCD之间的一些相同点和不同点。

  • NSOpertaionQueue用GCD构建,是GCD的高级抽象。
  • GCD只支持FIFO队列,而加入NSOperationQueue队列的操作可以被重新排序(重新设置优先级)。
  • NSOperationQueue支持在操作之间设置依赖关系,而GCD不支持。如果某个操作需要另一个操作生成的数据,可以让这个操作依赖另外的一个,NSOperationQueue会自动按照正确的顺序执行操作。而GCD没有内建的依赖关系支持。
  • NSOperationQueue兼容KVO。这意味着你可以观察任务的状态。那我们应该只用NSOperationQueue而不用GCD吗?答案是否定的。NSOperationQueue的执行速度比GCD慢。如果用Instruments查看代码性能并且觉得需要提升性能的话,那就用GCD。通常在底层代码中,任务之间可能不会相互依赖,或者没有必要用KVO来观察状态。别忘了高德纳的教诲:“在大概97%的时间里,我们应该忘记微小的性能提升。过早优化是万恶之源。”只有Instruments显示有真正的性能提升时才有必要用低级的GCD。

  7.既然提到GCD,那么问一下在使用GCD以及block时要注意些什么?它们两是一回事儿么?block在ARC中和传统的MRC中的行为和用法有没有什么区别,需要注意些什么?
Block是一个C级别的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持,从ios4.0开始就很好的支持Block。
Block 闭包就是能够读取其它函数内部变量的函数,一个函数里定义了个block,这个block可以访问该函数的内部变量。通常用来做并发任务、遍历、以及回调。
在ARC中,__block会自动进行retain
在非ARC中,__block不会自动进行retain
ARC 在使用block过程中,会有retain cycle的问题,需要使用__weak代替。
在block中用到了self,self会被block retain,而_observer会copy一份该block,就是说_observer间接持有self,同时当前的self也会retain _observer,最终导致self持有_observer,_observer持有self,形成retain cycle

注:iOS5以下没有__weak,则需使用__unsafe_unretained

  8.您是否做过异步的网络处理和通讯方面的工作?如果有,能具体介绍一些实现策略么?

  9.对于Objective-C,你认为它最大的优点和最大的不足是什么?对于不足之处,现在有没有可用的方法绕过这些不足来实现需求。如果可以的话,你有没有考虑或者实践过重新实现OC的一些功能,如果有,具体会如何做?

优点: 与C,C++兼容,很多以前的类库可以不用修改直接使用。动态识别,比较灵活。加入类别,扩展方便。
缺点: 不支持重载和多继承,运行时导致效率稍低。

   10.你实现过一个框架或者库以供别人使用么?如果有,请谈一谈构建框架或者库时候的经验;如果没有,请设想和设计框架的public的API,并指出大概需要如何做、需要注意一些什么方面,来使别人容易地使用你的框架。

答:曾经移植过一个框架,把C++的一套类库移植到OC上面,主要工作就是做一个oc++的接口层。做的过程中,遇到的问题就是在原来框架中,很多头文件中用结构体或者类的地方,没有用指针,导致不能用声明的方式来使用类和结构体,必须在头文件中把其它头文件导入,这样导致整个接口需要提供的头文件太多了。
还封装过供他人调用的接口。建议就是调用方法尽可能简单,做好传入参数的安全检查及错误提醒。因为你无法确定你的调用者给你传什么样的数据进来。如果实现方法中耗时较长,需要用异步的方式进行结果返回,可以选用delegate或者block的方式。

      以上10个问题对于初级或者刚接触iOS的开发者来说,肯定是过于难了。想要答出全部问题,可能需要至少两到三年的Cocoa/CocoaTouch开发经验。而如果想要有所见地的回答,可能需要更长的时间和经验。这些问题对于技术的积累会是一个很好的考察,因为如果没有对这些问题中涉及的内容有过实际使用和体会的话,是很难较完整和全面回答这些问题的。同时,因为这些问题并不像ABCD的客观题有标准答案,表现的是应聘者的理解,所以提问者也必须具备必要的材料或者知识,以应对可能的讨论。

      在为团队寻求高级别的开发工程师或者Leader类的职位时,这些问题的回答会是对应聘者技术深度和广度的一个有效的考察。同样地,如果你的团队在Cocoa/CocoaTouch上比较偏重,但是技术团队的No.1的工程师却不能很好地回答这些问题的话,可能也会是需要检讨技术层的一个信号。


原创粉丝点击