1. 笔试题
1.1 冒泡排序
Objective-C 实现如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14- (void)bubbleSort:(NSMutableArray *)array {
for (int i = 0; i < array.count; i++)
{
for (int j = 0; j < array.count-1-i; j++)
{
NSInteger left = [array[j] integerValue];
NSInteger right = [array[j+1] integerValue];
if (left < right) {
[array exchangeObjectAtIndex:j withObjectAtIndex:j+1];
}
}
}
NSLog(@"%@",array);
}
参考链接:【算法】冒泡排序
1.2 二分查找
Swift实现如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15func binarySearch<T: comparable>(_a: [T], key: T) -> Int? {
var lowerBound = 0
var upperBound = a.count
while lowerBound < upperBound {
let midIndex = lowerBound + (upperBound - lowerBound) / 2
if a[midIndex] == key {
return midIndex
} else if a[midIndex] < key {
lowerBound = midIndex + 1
} else {
upperBound = midIndex
}
}
return nil
}
参考链接:【算法】二分查找
1.3 合并两个数组去重
参考链接:【算法】合并两个数组并去重
1.4 两个大数相加
参考链接:大数相加算法
2. 一面
2.1 SDWebImage 的缓存机制?LRU 说一下。
SDWebImage加载图片拿到url会先把url的MD5值作为key从内存中查找,如果内存中有,则直接取图片显示;如果内存中没有,会从磁盘中查找。磁盘中没有,会走下载流程。
LRU 最近最少使用。缓存容量满时,会先清理最近最少的缓存。
2.2 数据库升级,比如从 1.0 升级到 2.0,增加了字段。
做好兼容处理。
2.3 性能优化
2.3.1 优化启动时间
- 将一些耗时操作延迟执行。比如SDK的初始化,界面的创建。
- 不能延迟执行的,尽量放到后台执行。比如数据读取,原始 JSON 数据转对象,日志发送。
- 减少动态库、合并动态库,定期清理不必要的动态库。
- 减少类、分类的数量,合并Category和功能类似的类。删除不必要的方法和类、分类。
- 将不必须在+load中做的事延时到+initialize中。
2.3.2 减少CPU、GPU资源消耗
- cell复用,header、footer复用。
- 尽量把view设置不透明。
- 减少视图的层级。
- 尽量避免调整视图层次、添加和移除视图。
- 合理选择加载图片的方式,UIImage imageNamed: ImageAssets 用于多个地方重复使用,UIImage imageWithContentsOfFile 一般用在图片数据很大,一般不需要多次使用的情况。
- 图片大小最好和UIImageView的大小相同。
- 不要阻塞主线程,耗时操作放在子线程进行。
- 懒加载。
- 缓存,缓存图片SDWebImage,缓存行高,NSCache缓存。
- 复用高开销对象NSDateFormatter和NSCalendar。
- 减少离屏渲染,优化圆角、阴影。
- 使用正确的数据存储。
2.3.3 内存优化
- 减少内存泄漏。
- 降低内存使用峰值。
- 懒加载。
- 灵活运用图片和文件加载。
- 拉长文件处理机制,逐步处理文件。
2.3.4 耗电优化
耗电功率是个比较综合的指标,影响因素很多。密集的网络请求,长链接,密集的CPU操作(比如大量的复杂计算)都会使耗电功率增加。网络状况(流畅的Wi-Fi还是信号不好的3G)都会影响。
- 优化网络。
- 减少、压缩网络数据。
- 若多次网络请求结果相同,尽量使用缓存。
- 网络不可用时,不进行网络请求。
- 优化CPU、GPU消耗。
- 优化I/O操作,使用dispatch_io。
- 定位优化
- 尽量降低定位精度,如不要使用精度最高的KCLLocationAccuracyBest。
- 如果只是需要快速确定用户位置,用 CLLocationManager 的 requestLocation 方法定位,定位完成后,定位硬件会自动断电。
2.4 Git 开发流程。
- master
- develop
- dev-xx 具体开发人员分支
开发完成后发起PR。项目提审打Tag
2.5 微信登录流程。
注册微信的AppKey与AppSecret。使用微信SDK方法调起微信,回调拿到一些参数,把包含openId等协定好的参数传给服务器,由服务器判断该用户是否注册过,如果注册过,返回登录成功后的用户相关信息。
2.6 WebView 与 JS 交互。
H5调用原生采用拦截协议的方式。
执行JS方法:evaluateScript
也可以使用JSBridge等方式。
2.7 说一下Runloop,苹果设计 Runloop 的初衷是什么?
Runloop 运行循环。
让线程在有任务的时候忙任务,没任务的时候休眠。
参考链接:【iOS 开发】RunLoop 总结
2.8 Delegate
代理用assign修饰。
2.9 GCD
参考链接:GCD 的 API
2.10 深拷贝与浅拷贝
深拷贝是拷贝整个对象。
浅拷贝只拷贝对象的指针。
copy用于修饰NSArray、NSDictionary、NSString。如果=右边赋值的对象是可变的,copy是深拷贝,拷贝对象的本身。如果赋值的对象是不可变的,copy是浅拷贝,只拷贝对象的指针。
用copy和用strong的区别?
用copy更安全,避免赋的值是可变的。如果能确保赋的值是不可变的,那么用strong和用copy都是浅拷贝,copy只是多了一个判断,判断可变还是不可变,其他是一样的。
NSMutableArray、NSMutableDictionary用Strong修饰,如果用copy,就会拷贝一份,变成不可变的,如果增删数据,就会发生错误。
2.11 进程间通信
URL Schemes
2.12 线程间通信,两个线程怎么切换?
performSelectorOnThread
2.13 多态
多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。
子类继承父类后,子类重写父类的方法,实现多态。