iOS跳槽宝典-面试技术基础篇

序言

又是一年金三银四时,相信很多人会选择这个时机考虑跳槽,但又对轮轮面试望而生畏。其实面试只是对个人技术及应变能力的一次考验,通常面试第一轮为技术面试,二面一般是跟HR交流,进一步了解你(严格的大公司还会有三面、四面)。第一轮技术面试中遇到的问题通常都是一些基础性的知识,平时可能忙于夜以继日的工作而疏于整理和总结,匆忙去面试可能被面试官层层紧逼的提问问的晕头转向,或者笔试题答的一塌糊涂。技术过关后忠厚老实的你在二面时察觉不到HR问题的意图,答非所问最终败下阵来或者被HR硬生生的往下压了千元预期薪资。

跳槽不是简单的找工作或换一家公司,是一个双向选择的机会。如何将自己完美的呈现出来从而获得一个自己满意的offer?整理一些自己经历的、看到的问题,与君共勉。

技术基础篇

1、为什么说Objective-C是一门动态的语言?

静态、动态是相对的,这里引用一下网上的定义:

①动态类型语言:动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。

②静态类型语言:静态类型语言与动态类型语言刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++是静态类型语言的典型代表

Objective-C是C的超集,在C语言的基础上添加了面向对象的特性,可以通过Runtime运行时机制在运行时动态的添加变量、方法、类等,所以说OC是一门动态语言。

延伸

编译时与运行时

编译时:即编译器对语言的编译阶段,编译时只是对语言进行最基本的检查报错,包括词法分析、语法分析等。将程序代码翻译成计算机能够识别的语言,编译通过并不意味程序就可以运行成功。

运行时:即程序通过了编译这一关之后编译好的代码被装载到内存中跑起来的阶段。这个时候会具体对类型进行检查,而不是仅仅对代码进行简单的扫描分析,此时如果出错的话程序就会崩溃。

可以说编译时是一个静态的阶段,类型错误很明显的可以直接检查出来,可读性好;而运行时则是动态的阶段,开始具体与运行环境结合起来。

Objective-C语言的动态性

OC语言的动态性主要体现在三个方面:动态类型(Dynamic typing)、动态绑定(Dynamic binding)、动态加载(Dynamic loading)。

<一>、动态类型

动态类型指的是对象指针类型的动态性。具体是指使用id任意类型将对象的类型确定推迟到运行时,由赋给它的对象类型来决定对象指针类型。另外类型确定推迟到运行时之后,可以通过NSObject的isKindOfClass方法动态的判断对象最后的类型(动态类型识别)。也就是说id任意类型修饰的对象为动态类型对象,其他在编译器指明类型的对象为静态对象。

示例:

对于语句 NSString* testObject = [[NSData alloc] init];  testObject在编译时和运行时分别是什么类型的对象?

首先,testObject是一个指向某个对象的指针,不论何时指针的空间大小都是固定的
编译时:指针的类型为NSString,即编译时会被当成一个NSString实例来处理,编译器在类型检查时如果发现类型不匹配就会给出黄色警告。该语句给指针赋值用的是一个NSData对象,则编译时编译器会给出类型不匹配警告。但是编译时如果testObject调用NSString的方法,编译器会认为是正确的,既不会警告也不会报错

运行时:运行时指针指向的实际是一个NSData对象,因此如果指针调用了NSString的方法,虽然编译时通过额,但运行时也会崩溃,因为NSData对象没有该方法。另外虽然运行时指针实际指向的是NSData,但编译时编译器并不知道,因此如果试图用这个指针调用NSData的方法会直接编译不通过,给出红色报错程序也运行不起来。

下面给出测试示例:

 // 1.编译时编译器认为testObject是一个NSString对象,这里赋给它一个NSData对象编译器给出黄色类型错误警告,但运行时却是指向一个NSData对象
    NSString* testObject = [[NSData alloc] init];
 // 2.编译器认为testObject是NSString对象,所以允许其调用NSString的方法,这里编译通过无警告和错误
    [testObject stringByAppendingString:@"string"];
  // 3.但不允许其调用NSData的方法,下面这里编译不通过给出红色报错
    [testObject base64EncodedDataWithOptions:NSDataBase64Encoding64CharacterLineLength];

将上面第三句编译不通过的注释掉,然后在第二句打断点,编译后跑程序到断点后会看到testObject指针类型是_NSZeroData对象。继续运行程序会崩溃,因为NSData对象没有NSString的stringByAppendingString这个方法。

动态类型测试

如果我们假设testObject是id类型会怎么样呢?

 // 1.id任意类型,编译器就不会把testObject在当成NSString对象了
    id testObject = [[NSData alloc] init];
    // 2.调用NSData的方法编译通过
    [testObject base64EncodedDataWithOptions:NSDataBase64Encoding64CharacterLineLength];
    // 3.调用NSString的方法编译也通过
    [testObject stringByAppendingString:@"string"];

结果是编译完全通过,编译时编译器把testObject指针当做任意类型,运行时才确定testObject为NSData对象,因此执行NSData的方法正常。但是执行NSString的方法时还是崩溃了。通过这个例子我们就可以很清楚的知道id类型的作用了,将类型的确定推迟到运行时,这就提现了OC的一种动态性:动态类型。

延伸

动态类型的识别方法(面向对象语言的内省Introspeciton特性)

1.Class类型:

  • Class class = [NSObject class];//通过类名得到对应的Class动态类型
  • Class class = [obj class];//通过实例对象得到对应的Class动态类型
  • if([obj1 class] == [obj2 class])//判断是不是相同类型的实例

2.Class动态类型和类名字符串的相互转换:

  • NSClassFromString(@"NSObject");//由类名字符串得到Class动态类型
  • NSStringFromClass([NSObject class]);//由类名的动态类型得到类名字符串
  • NSStringFromClass([obj class]);//由对象的动态类型得到类名字符串

3.判断对象是否属于某种动态类型:

  • -(BOOL)isKindOfClass:class//判断某个对象是否是动态类型class的实例或其子类的实例
  • -(BOOL)isMemberOfClass:Class//只判断某个对象是否是class类型的实例,不考虑其子类

4.判断类中是否有对应的方法:

  • -(BOOL)respondsToSelector:(SEL)selector//类中是否有这个类方法
  • -(BOOL)instancesRespondToSelector:(SEL)selector // 类中是否有这个实例方法

5.方法名字符串和SEL类型的转换

在编译时,编译器会根据方法的名字和参数序列生成唯一标识方法的ID,这个ID为SEL类型。到了运行时编译器通过SEL类型的ID来查找对应的方法,放法的名字和参数序列相同,那么它们的ID就都是相同的。另外可以通过@select()指示符获得方法的ID。常用方法如下:

SEL funcID = @select(func);// 这个注册事件回调时常用,将方法转成SEL类型
SEL funcID = NSSelectorFromString(@"func"); // 根据方法名得到方法标识
NSString *funcName = NSStringFromSelector(funcID); // 根据SEL类型得到方法名字符串


<二>、动态绑定

动态绑定指的是方法确定的动态性。具体指的是利用OC的消息传递机制将要执行的方法的确定推迟到运行时,可以动态添加方法。也就是说一个OC对象是否调用某个方法不是由编译器决定的,而是由运行时决定的。另外,关于动态绑定的关键一点是基于消息传递机制的消息转发机制,主要处理应对一些接受者无法处理的消息,此时有机会将消息转发给其他接收者处理。

动态绑定是基于动态类型的,在运行时对象的类型确定后,那么对象的属性和方法也就确定了(包括类中原来的属性和方法以及运行时动态新加入的属性和方法),这也就是所谓的动态绑定了。动态绑定的核心就是在运行时动态的为类添加属性和方法,以及方法的最后处理和转发,主要用法C语言语法,因为涉及到运行时,因此要引入运行时头文件#include <objc/runtime.h>

延伸

消息传递机制

在OC中,方法的调用不再理解为对象调用起方法,而是要理解成对象接受消息,消息的发送采用动态绑定机制,具体会调用哪个方法直到运行时才能确定。确定之后才回去执行绑定的代码。方法的调用实际就是告诉对象要干什么,给对象传送一个消息,对象为接收者(receiver),调用的方法及其参数即消息(message),给一个对象传消息表达为:[receiver message];接收者的类型可以通过动态类型识别,于运行时确定。

在消息传递机制中,当开发者编写[receiver message];语句发送消息后,编译器都会将其转换成对应的一条objc_msgSend C语言消息发送原语,具体格式为:void objc_msgSend (id self, SEL cmd, ...)

这个原语函数参数可变,第一个参数是消息的接收者,第二个参数是消息的选择子,后面跟着可选的消息的参数。有了这些参数,objc_msgSend就可以通过接收者的isa指针,到其类对象中的方法列表中以选择子的名称为寻找对应的方法,找到则转发哦其实现代码执行,找不到则继续根据继承关系从父类中寻找。如果找到了跟类还是无法找到对应的方法,说明该接收者对象无法响应该消息,则会出发消息转发机制,给开发者最后一次挽救程序的机会

<三>、动态加载

动态加载主要包括两个方面,一个是动态加载资源,一个是一些可执行代码模块的加载。这些资源在运行时根据需要动态的选择性的加入到程序中,是一种代码和资源的“懒加载“模式,可以降低内存需求,提高整个程序的性能。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,690评论 0 9
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,599评论 18 399
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,135评论 30 470
  • 作者:青雘 在“猫儿湾”我们一个囫囵觉都没睡,天还没亮明白,就忙不迭地赶到别的地方去。因为有风声说日本人发现了我们...
    静静的静静想静静地静静阅读 392评论 0 7
  • 爱写日记,不知道是从什么时候沾染上这一个习惯。年少轻狂的日子里,全靠一本本日记去回忆,每一本日记里都记录着某个...
    BB艺的大柚子阅读 280评论 0 0