iOS 面试

图片发自简书App

前一阵在趣直播平台上看了我就叫Sunny怎么了 大神的iOS 面试小灶直播,总结下直播的内容。

简历中的问题

1.项目描述过于简单宽泛

  • 项目规模?
  • 你在其中的职责
  • 详细介绍使用的技术
  • 遇到的问题、坑以及如何解决的?

2.专业技能前篇一律

  • 在列举技术名词时最好写出用这个技术干了什么?
    比如“熟练应用Objc runtime 技术,曾使用它做了ViewController 进入和退出时的AOP 埋点”

3.格式、拼写、细节

  • Object-C
  • Foudation
  • ios
  • xCode

4.提供更多的信息来体现你的特别

  • Blog
  • GitHub
  • 技术探索
  • 对技术的个人理解
  • 做过什么有意思的事儿

我就叫Sunny怎么了 的一般套路

  • 最近的工作,App,负责哪些模块(考察前一份工作的难度)
  • 找个最熟悉的业务,描述一下设计结构,UI层级,控件的使用,布局,交互效果等(考察基本业务能力,熟练程度,质量)
  • 考察几个基础的问题,如内存管理,多线程
  • 从简历里熟练或掌握的技术中找几个深聊
  • 找面试者研究过的,有心得或熟练的东西聊
  • 考虑更深度的问题
  • 沟通是否顺畅

几个面试题

property

  1. @property 能使用哪些关键字及作用是什么?

答:

属性 作用
strong 释放旧对象将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
weak weak不增加对对象的引用计数,也不持有对象,因此不能决定对象的释放。它比assign多了一个功能,当对象消失后自动把指针变成nil
assign 简单赋值,不更改索引计数,适用于基础数据类型(NSInteger CGFloat)和C数据类型(int float double char 等)简单数据类型
copy 对应mutableCopy。此属性只对那些实行了NSCopying协议的对象类型有效。根据调用类型不同,决定是深拷贝还是浅拷贝,一般都是浅拷贝,只复制了指针,内容还是同一份
atomic 和 nonatomic用来决定编译器生成的getter和setter是否为原子操作,atomic 设置成员变量的@property属性时 默认为是atomic 提供线程安全。在多线程环境下,原子操作是必要的否则会引起错误的结果。
nonatomic 非原子性访问对于属性赋值的时候不加锁,多线程并发访问会提高性能,如果不加此属性则默认是两个访问方法都为原子型事务访问。
readonly 此标记说明属性是只读的
readwrite 此标记说明属性会被当成读写的 这也是默认的属性
unsafe_unretained 跟weak类似,声明一个弱引用,但是当引用计数为0时,变量不会自动设置为nil
getter 指定 get 方法,并需要实现这个方法。必须返回与声明类型相同的变量,没有参数
setter 指定 set 方法,并需要实现这个方法。带一个与声明类型相同的参数,没有返回值(返回空值)
  1. 下面这4种写法的区别
@property (nonatomic, strong) NSArray *array0;
@property (nonatomic, copy) NSArray *array1;
@property (nonatomic, strong) NSMutableArray *array2;
@property (nonatomic, copy) NSMutableArray *array3;

答:
array0如果传进来的是mutableArray ,如果里面元素被改变的话,会可能出现问题;
array1标准写法,当传经来的是mutableArr时,会变成不可变版本,但里面元素不会复制一份,都是浅拷贝;
array2是标准写法;
array3当设置时,会被变成不可变版本,后续如果调用mutableArr的消息,会导致crash;

基本内存管理

下面对象分别在什么时候释放?

- (void)ARCProblem{
    id obj0 = @"sunny";
    __weak id obj1 = obj0;
    id obj2 = [NSObject new];
    __weak id obj3 = [NSObject new];
    {
        id obj4 = [NSObject new];
    }
    __autoreleasing id obj5 = [NSObject new];
    __unsafe_unretained id obj6 = self;
}
  • obj0 是一个字符串,分配在常量区,所以不会释放
  • obj1 是weak 指向obj0 会生成一个map 来映射对象和指针的关系,当对象释放时,会反向查找所有的指针,将指针置为nil。这里obj0 是个常量,不会被释放,所以obj1不会释放
  • obj2 当对象用完就会释放
  • obj3 这行语句结束就会释放
  • obj4 定义在一个scope里,scope结束就会释放
  • obj5 会加到自动释放池中,会在最近的AutoreleasePool pop被释放
  • obj6 可能随时都会被释放

UIViewController

这样写会发生什么?

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view = nil;
}

第一次self.view 时会调用loadView方法加载view ,当加载结束后会调用viewDidLoad。有可能递归调用,但是如果之后没有操作self.view 就不会递归,屏幕上会黑屏。

UITableView

UITableViewDataSourceUITableViewDelegate 中的主要方法有哪些,调用顺序和时机是怎样的?

block 内存管理

如何解决下面代码的问题

- (void)blockRetailCycleProblem{
    self.block = ^{
        NSLog(@"%@",@[self]);
    }
}

解决方案:

- (void)blockRetainCycleAnswer0{
    __weak typeof(self) weakSelf;
    self.block = ^{
        NSLog(@"%@",@[weakSelf]);
    }
}

- (void)blockRetainCycleAnswer1{
    __weak typeof(self) weakSelf;
    self.block = ^{
    __weak typeof(weakSelf) strongSelf = weakSelf;
        NSLog(@"%@",@[weakSelf]);
    }
}

- (void)blockRetainCycleAnswer2{
    __weak typeof(self) weakSelf;
    self.block = ^{
        __weak typeof(weakSelf) strongSelf = weakSelf;
        if(strongSelf){
            NSLog(@"%@",@[strongSelf]);
        }
    }
}

前两种都有weakself 都有提前被释放的可能,会导致crash,第三种比较全面

block 内存管理 Extension

下面的 self 用不用 weak ?

- (void)blockRetainCycleProblemExt{
    [UIView animateWithDuration:1 animations:^{
        self.view.frame = CGRectMake(1,2,3,4);
    }]
}

那这个呢?

[UIView animateWithDuration:1 delay:10000 options:0 animations:^{
   self.view.frame = CGRectMake(1,2,3,4);
}]

动画block 是瞬间执行的,不会持有self的

代码规范改错

typedef enum{
    UserSex_Man,
    UserSex_woman
}UserSex;

@interface UserModel : NSObject

@property(nonatomic, strong) NSString* name;
@property (assign, nonatomic) int age;
@property (nonatomic, assign) UserSex sex;

- (id)initUserModelWithUserName:(NSString*)name withAge:(int)age;
- (void)doLogin;

@end

修改如下:

typedef NS_ENUM(NSUInteger, XXUserGender){
    XXUserGenderUndefine,
    XXUserGenderMale,
    XXUserGenderFemale,
    XXUserGenderSark
};

@interface XXUserModel : NSObject

@property (nonatomic, copy) NSString* identifier;

@property (nonatomic, copy) NSString* name;
@property (nonatomic, assign) NSUInteger age;
@property (nonatomic, assign) XXUserGender sex;

+ (instancetype)modelWithIdentifier:(NSString *)identifier;

- (void)login;

@end

理解应用架构

  • MVCMVVM 的理解
  • StackHeap 分别的使用,如果管理?
  • ARC 是如何实现的?
  • Autorelease 对象何时释放?
  • AutoreleasePool 是如何实现的
  • 理解Class 与对象模型
  • 理解RunLoop

深入理解消息机制

问题:从写入[obj foo] 这行代码知道运行时foo 被调用,尽量详细描述中间都发生了什么?

掌握:objc_msgSend 的关键调用,后续如何通过selector 从isa 找到IMP ,若运行时没有找到foo 会如何?
精通:编译器如何编译成objc_msgSend、消息cache 机制、消息转发机制、objc_msgSend 的各个版本、objc_msgSend 的实现、跳板机制等

魔法数字

//64位,下面会输出什么,为什么?
- (void)magicNumberProblem{
    //Tagged Pointer
    NSLog(@"%@",11529223390768879413UL);
}

输出sunny,在64位下,指针的空间很大,比实际指向的值还大,所以采用Tagged Pointer 机制,直接在指针的地址里存放值。

另辟蹊径的block 调用

void (^block)(void) = ^{
    NSLog(@"block get called");
}
禁止调用block();

答:

[UIView animateWithDuration:1 animations:block];
//or
dispatch_async(dispatch_get_main_queue(), block);
[[NSBlockOperation blockOperationWithBlock:block] start];
[[NSInvocation invocationWithMethodSignature:[NSMethodSignatrue signatureWithObjCTypes:"v@?"]] invokeWithTarget:block];
//"v@?" 为block 的签名 v 表示返回值,@?表示第一个参数 为block 本身

//NSInvocation 一般用法
NSMethodSignature *signature = [self methodSignatureForSelector:@selector(description)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.target = self;
invocation.selector = @selector(description);
[invocation invoke];
//比较黑
[block invoke];

//block 是NSBlock 类型
//经查找NSBlock 里有这些实例方法
- (void)copy;
- (void)copyWithZone:({_NSZone=} *)arg0;
- (void)invoke;
- (void)performAfterDelay:(double)arg0;
//更黑
//Block内部结构
struct Block layout{
    void *isa;
    volatile int32_t flag;  
    int32_t reserved;      
    void (*invoke)(void *,...);
    struct Block_descriptor_1 *descriptor;
};

void *pBlock = (__bridge void*)block;//取到block的首地址
void (*invoke)(void *,...) = *((void **)pBlock + 2);//取到invoke函数的偏移量地址 32位加3
invoke(pBlock);
//节点
__strong void(^cleaner)(void) __attribute__((cleanup(blockCleanUp), unused)) = block;
asm("callq *0x10(%rax)");//汇编 真正调用方式

谈谈iOS 进阶

  • 要去联想、理解、有自己的思考、对技术的主见
  • 抽象、领悟、类比能力
  • 看书、看博客、实战总结、刨根问底
  • 进阶速度
    纯日常开发 < 纯看书、博客 < 自己试验、Demo < 写博客 < 系统性分享和讨论 < 提供完整的开源方案
  • 对技术保持好奇
  • 对原理刨根问底
  • 不甘于重复劳动
  • 多思考,多怀疑
  • 相信实践,不要轻信"大神"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,114评论 29 470
  • 多线程、特别是NSOperation 和 GCD 的内部原理。运行时机制的原理和运用场景。SDWebImage的原...
    LZM轮回阅读 1,999评论 0 12
  • iOS面试小贴士 ———————————————回答好下面的足够了------------------------...
    不言不爱阅读 1,950评论 0 7
  • 史上最全的iOS面试题及答案 iOS面试小贴士———————————————回答好下面的足够了----------...
    Style_伟阅读 2,341评论 0 35
  • 忆往昔 犹记学生时期坐在家中窗台上读《从你的全世界路过》,感受每个故事主角的喜怒哀乐,为他们的经历而欢笑、哭泣,渴...
    涵枫阅读 523评论 0 1