iOS面试题小结
通过自己的工作经验和面试经历小结了一份iOS面试题 分享出来 欢迎指正和补充!
如果你懒得看文字, 可以直接浏览前面的思维导图(本人使用的是MindNode)
ios-interview-questions-01-basic.png ios-interview-questions-02-grammar.png ios-interview-questions-03-memory.png ios-interview-questions-04-development.png ios-interview-questions-05-design.png ios-interview-questions-06-advanced.png ios-interview-questions-07-product.png基础
1: @class的作用?
(1) @class告诉编译器某个类的声明 当执行时 才去查看类的实现文件 可以解决头文件的相互包含
(2) @class能提高编译效率 由于在h文件中 使用#import的话 是将其内容全部拷贝过来 会影响编译效率 而且对应的h文件只有有任何改动 又要重新编译
2: @synthesize和@dynamic分别有什么作用?
@synthesize的语义是如果你没有手动实现setter方法和getter方法 那么编译器会自动为你加上这两个方法
@dynamic告诉编译器属性的setter与getter方法由用户自己实现 不自动生成 如果没有实现的话 那么运行时会发生崩溃
3: #import和#include的区别?
(1) #import是O-C导入头文件的关键字 #include是C/C++导入头文件的关键字
(2) #import比起#include的好处就是不会引起重复包含
4: nil和NULL的区别?
(1) nil表示为空的O-C对象
(2) NULL表示空指针(不指向任何内存地址)
5: id、instanceType和void *的区别?
(1) id是指针 指向任何一个继承自NSObject的对象
(2) instanceType只能作为返回值 返回和方法所在类相同类型的对象
(3) void *则为"无类型指针" 可以指向任何数据类型
更多请参考Objective-C小结
语法
1: 什么是block?
类似匿名函数 (实质是对象)
什么时候使用block?
通常在异步请求时使用 (尤其注意view controller间通信推荐使用delegate 而不是block)
使用block有什么需要注意的地方?
防止循环引用
2: Objective-C中category的特点?
(1) 在不获悉不改变原来代码的情况下往里面添加新的方法
(2) 将类的实现分散到多个不同文件或多个不同框架中
(3) 可以访问原始类的实例变量 但不能添加变量 (其实可以用过runtime的assosiated object来实现)
(4) 不能重载primary class的方法(这个算是category相比继承的劣势吧)
继承相比category相比有何劣势?
(1) 成本高: 必须要熟悉父类 (而category不需要了解primary class就可以进行扩展)
(2) 耦合高: 子类依赖父类
(3) 复杂度高: 当继承体系较复杂时
3: Objective-C相比其他语言有哪些”缺点”?
(1) 没有命名空间机制: 为了区分不同的类 在类名前加前缀
(2) 不支持多重继承: 但可以通过protocol和delegate pattern来代替
(3) 不支持抽象基类(abstract class): 要想达成类似效果 可以在子类必须覆写的父类方法里抛出异常
4: 是否使用过Swift?
Swift相比Objective-C有哪些更友好的特性? (可选类型, 异常处理, 函数式编程)
Objective-C和Swift混编, 详细请参考iOS开发 之 Objective-C和Swift混合编程
内存
1: 什么是ARC? (auto reference count)
ARC属性修饰符有哪些? (strong weak copy assign readonly readwrite)
它们分别在什么时候使用? (strong保持该对象不被销毁 weak主要应用于delegate和block copy主要应用于string asking主要应用于内置数据类型如NSInteger BOOL等)
weak和assign有何区别? (weak = assign + 引用对象销毁时自动置nil 所以使用weak引用对象更安全)
view controller中的sub view成员一般使用哪一种修饰符? (weak 因为view controller强引用了root view root view又强引用了subview 因为sub view的owner是root view而非view controller 所以使用weak相比于strong可以避免过度使用强引用)
2: 什么是循环引用? (对象相互强引用彼此)
如何解决强引用? 思路是打破相互强引用形成的循环引用
(1) 使用弱引用 例如delegate和block中使用weak
(2) 不使用强引用对象时及时将引用置为nil
举个你遇到过的循环引用的例子?
(1) block里面应用了self.property
(2) http request在block中应用了self, 但是没有在vc销毁后cancel task
(3) NSTimer没有正确销毁, 详细请参考iOS开发 之 不要告诉我你会用NSTimer
3: 是否使用过对象拷贝?
深拷贝(shallow copy)和浅拷贝(deep copy)的区别?
(1) 浅复制: 复制指向对象的指针
(2) 深复制: 复制引用对象本身
Objective-C中的对象拷贝要实现什么protocol? (NSCopying)
更多请参考Objective-C学习 之 对象拷贝
开发
1: UIViewController生命周期有哪些?
load(在加载该类时调用) -> initialize(在该类第一次创建对象时调用) -> init
-> loadView(代码创建) or initWithNib(nib创建)
-> viewDidLoad (不要在这里设置frame!!!)
-> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews -> viewDidAppear
-> viewWillDisappear -> viewDidDisappear
-> dealloc
2: UIApplication生命周期有哪些?
willFinishLaunchingWithOptions -> didFinishLaunchingWithOptions
-> (applicationWillEnterForeground) -> applicationDidBecomeActive
-> applicationWillResignActive -> applicationDidEnterBackground
-> applicationWillTerminate
3: iOS中多线程有哪些方式? (pthread NSThread GCD NSOperation)
各有何优缺点? (pthread是Unix, Linux, MacOS下的一套多线程APIs NSThread功能较简单但需要自己管理线程 GCD简单高效但当过度使用会造成线程调用混乱 NSoperation功能强大且接口一致推荐使用)
详细请参考iOS开发 之 Queue和Thread
4: 本地持久化可以采取哪些方案?
NSUserDefaults储存基本数据类型的简单数据
NSKeyedArchiver存储对象
sqlite(使用第三方库FMDB, 数据加密请参考iOS工具 之 FMDB+SQLCipher)
core data(Apple官方替代db的方案 使用第三方库MagicalRecord)
realm(新兴的本地持久化方案)
6: 如何做屏幕适配?
(1) 代码方式的第三方库: masonry, pure layout等
(2) storyboard/xib布局
在屏幕适配过程中遇到了哪些问题?
代码布局以及storyboard/xib在开发中的优劣势?
设计
1: 写一个单例设计模式? (允许答题者上网查找)
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[super allocWithZone:NULL] init];
});
return sharedInstance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [self sharedInstance];
}
+ (id)copyWithZone:(struct _NSZone *)zone {
return [self sharedInstance];
}
- (id)copy {
return self;
}
2: Delegate和Proxy模式的区别?
Delegate是委托, 即两者之间的通信
Proxy是代理, 即第三者起到保护和控制的作用
详细请参考设计模式 之 Proxy
3: MVC MVP MVVM
iOS开发中MVP架构较少, MVVM的第三方库有ReactiveCocoa, RxSwfit
4: notification和delegate以及KVO的区分和用途?
notification是广播 即1对多的通信方式(广播方不知道接收方)
delegate是委托 即1对1的通信方式(是iOS中常见且推荐的通信方式)
KVO是观察者模式的应用 也是1对多的通信方式(被观察者是知道有哪些观察者的)
5: 如何优化UITableView性能?
(1) 压缩图片(缩略图 ImageOptim Webp)
(2) UITableViewCell复用
(3) 耗时操作和计算放置异步线程
(4) facebook的方案: AsyncDisplayKit
6: 一些常用的设计原则
(1) 一元: 统一使用delegate进行模块解耦; 数据格式统一为JSON且key统一为String
(2) 接口: 接口功能单一, 简单, 参数少, 易理解; 接口面向接口编程而非实现; 进行单元测试
(3) 分层: 避免横向依赖; 没有跨层访问
(4) 网络层和本地持久化: 隔离数据的处理和表示; 串行化
高阶
1: 什么是事件响应链?
Touch Event发生时, iOS将其封装成UIEvent对象, 放在当前App的的Event Queue中
UIApplication Runloop从Event Queue中取出该Event进行disptach for handling
Dispatch for hanlding该event的view的过程, 就叫hit-testing
而最终handling该event的view, 就叫hit-test view
详细请参考iOS开发 之 Touch事件处理机制
举出使用事件响应链的例子?
(1) 使用第三方库DAСontextMenuCell, 让上层的OverLay View的事件响应透传至下层View
- hitTest:withEvent:
(2) 划出侧边栏和cell侧滑响应事件的处理, 使用了
- gestureRecognizer:shouldReceiveTouch:
2: 什么是反射? (运行时获取或改变程序信息)
Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime
3: Runtime有哪些引用场景?
(1) 要在按钮点击时全局加上统计信息, 使用了Method Swizzling(使用第三方库Aspects)
(2) 要在category里添加新的属性, 使用了Associated Object(只有assign没有weak属性修饰符, 所以需要在销毁时手动置nil)
load和initialize的区别?
(1) load会在第一次加载该类时调用, 且包含category
(2) initialize只在该类第一次创建对象时调用, 对category无效
4: Runloop及其应用?
详细请参考
以及
产品
1: 代码规范
详细请参考Objective-C编程规范
2: 常用的第三库有哪些?
AFNetworking YYkit MJExtension
FMDB Realm
SDWebImage
Masonry TPKeyboardAvoiding
fastlane
3: 有哪些安全措施?
(1) 编码
Base64使用64个字符来对任意数据进行编码 过程是可逆的 目的是把含有不可见字符串的信息用可见字符串表示出来
MD5生成的是固定的128bit 过程不可逆 常用来保存密码信息
SHA-256生成的是固定的256bit 加强版的MD5安全性更高
DES对称加密算法 密钥既能加密也能解密
AES加强版的DES 安全性更高 加密速度更快
RSA非对称加密算法 更安全 但加密速度不如对称加密算法
(2) HTTPS(证书)
(3) 数据库加密, 参考iOS工具 之 FMDB+SQLCipher
4: 持续集成和自动化发布
Jenkins
或者
TravisCI, 详细请参考TravisDemo + fir
更多文章, 请支持我的个人博客