iOS面试题(1)
2016-07-15 本文已影响793人
T_aa
问题来源:
http://www.zhihu.com/question/19604641/answer/56306604
网上的一些答案:
http://www.tuicool.com/articles/AVnMVj
以下答案是个人理解,如果有问题欢迎指正。
Model层:
- 数据持久化存储方案有哪些?
1.SQLite3
2.Preference(偏好设置)
3.Plist
4.Coredata
5.NSKeyedArchive(归档)
- 沙盒的目录结构是怎样的?各自一般用于什么场合?
参考:http://blog.csdn.net/iunion/article/details/46889073
1.应用程序包:只读,不会被iTurns同步,存放应用程序本身包括资源文件和可执行文件等
2.Document:会被iTurns同步,保存应用程序的数据文件,保存的是不可再生的数据
3.Documents/Inbox:会被iTurns同步,保存其他应用程序请求当前当前程序打开的文件
4.Library:会被iTurns同步,除了Caches,苹果建议用来存放默认设置和其他的状态信息
5.Library/Caches:不会被iTurns同步,主要是缓存文件,用户使用过程中缓存的都可以保存在这个目录中,保存可再生文件,比如网络请求的数据。删除缓存文件一般会把这个文件删除
6.Library/Preferences:会被iTurns同步,保存NSUserDefault的应用程序偏好配置信息文件,是一个plist文件
7.tmp:不会被iTurns同步,存放临时文件,保存的是应用程序再次启动的时候不需要的文件,系统内存不足的时候就会去自动去清理他
- SQL语句问题:inner join、left join、right join的区别是什么?
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
inner join(等值连接) 只返回两个表中联结字段相等的行
<这块不是很懂>
- sqlite的优化
SQLite数据库文件读写操作,频繁打开关闭是很耗时和浪费资源,一些sql执行语句可以先缓存到内存中,然后依次性执行。
数据排序
查询语句的形式
<这块不是很懂>
- 网络通信用过哪些方式(100%的人说了AFNetworking...)
TCP
HTTP
HTTPS
UDP
Socket
- 如何处理多个网络请求并发的情况
参考:http://www.cnblogs.com/yanhuaxuanlan/p/4683557.html
用信号量,dispatch_semaphore_t
- 在网络请求中如何提高性能
1.减少请求带宽-JSON和XML是常见的请求与响应提的编码方式。压缩模式的效率在很大程序上取决于待压缩的数据,通常情况下JSON更高效
2.降低请求延迟
3.避免网络请求-利用缓存机制,缓存的内容就不要再次请求了
<不是很懂>
- 在网络请求中如何保证安全性
参考:http://blog.csdn.net/jt521xlg/article/details/49717571
1.用户post请求,不直接暴露参数信息
2.重要的数据,要加密,常见的MD5(不可逆),AES(可逆)
3.非重要的数据,要签名
4.利用token校验时效性
语言与基础知识:
- 内存中的栈和堆的区别是什么?那些数据在栈上,哪些在堆上?
栈:编译器自动分配释放,存放函数的参数值,局部变量的值
堆:由程序猿管理释放,存放静态变量,字符常量,资源,编译运行时的数据
-
#define
和const
定义的变量,有什么区别
define:无类型校验、无分配内存、使用的话内存上多次拷贝、预处理的时候展开
const:有类型校验、有分配内存、使用的话内存上一次拷贝、编译运行阶段使用
- 什么情况下会出现内存的循环引用
1.NSTimer-他的target是self的时候,要手动停止定时器
2.Block-retain circle
3.delegate
- block中的weak self,是任何时候都需要加的么?
调用自身属性的时候或者方法的时候
- GCD的queue,main queue中执行的代码,一定是在main thread么?
看:http://www.tuicool.com/articles/AVnMVj
<不是很懂>
- NSThread中的Runloop的作用,如何使用?
<不知>
- .h文件中的变量,外部可以直接访问么?(注意是变量,不是property)
直接访问的话是没法访问到的,可以通过runtime的ivar去获取他的所有变量信息遍历就可以获取到
- 讲述一下runtime的概念,message send如果寻找不到相应的对象,会如何进行后续处理 ?
runtime是运行时语言,是系统运行时的机制,主要是消息机制。
message_send找不到对应的方法的时候会执行resolveInstanceMethod,在里面可动态添加方法实现
- TCP和UDP的区别是什么?
TCP:传输控制协议、 有链接的、可靠的、
UDP:用户数据报协议、无链接的、不可靠、
- MD5和Base64的区别是什么,各自场景是什么?
参考:http://www.cnblogs.com/XL-Sunny/p/5614012.html
MD5: 不可逆、消息完整性保护。用于:1、一次性验证。2.安全访问认证。3、数字证书
Base64: 可逆、是一种编码方式,主要作用不是加密,是用来避免‘字节’中不能转换成可显示字符的数值,将二进制数据转换成文本数据,方便使用HTTP协议等。使用场合:表示、传输、储存一些二进制数据。
- 二叉搜索树的概念,时间复杂度多少?
它获取是一个空树、或者是具有以下性质的二叉树:若他的左子树不空,则左子树上所有节点上的值均小于他根节点的值,若他的右子树不空,则右子树上所有节点的值均大于他根节点的值。
<时间复杂度不知>
架构:
- 哪些类不适合使用单例模式?即使他们在周期中只会出现一次。
单例是只有一个实例,并向整个系统提供这个实例。
哪些类不适合<不知>
- Notification的使用场景是什么?同步还是异步?
Notification是事件广播机制,默认情况下,广播一个通知会阻塞后面的代码、直到所有的监听者都执行完响应、从这个上看广播是同步的。如果希望广播事件异步处理,可以将它加到新的线程中执行
- 简单介绍一下KVC和KVO,他们都可以应用在哪些场景?
KVO:键值监听、监听某个属性值变化
KVC:键值编码、直接通过property的name(key)来访问这个property的属性。
APP相关:
- 如何添加一个自定义字体到工程中
1.将自定义的字体拖到工程中
2.在info的plsit文件中添加Fonts provided by application项,将新字体的名字添加进去,要带后缀.ttf
- 如何制作一个静态库/动态库,他们的区别是什么?
静态库:在编译的时候就会被链接到目标代码中,程序运行时候不再需要改静态库
动态库:动态库在程序编译时并不会被链接到目标代码中,只有在程序运行时载入,因为程序运行期间还需要动态库存在
我们封装的.a和.framework都是属于静态库。动态库苹果是不允许上商店。系统的framework基本上都是属于动态库。
- Configuration中,debug和release的区别是什么?
Debug:是调试版本,包含程序信息更多,只有debug程序才能断点、单步执行、调试语句输出
Release:是发行版本,比debug有了一些优化,文件比debug的小,跟debug调用两个不同的底层库
- 简单介绍下发送系统消息的机制(APNS)
和本地通知不同,推送通知是通过苹果APNS发送到客户端
1.应用设备向苹果APNS服务器注册推送服务
2.注册成功之后APNS服务器会返回一个device_token,拿到这个token之后保存下来,到应用服务器后台
3.需要推送服务的时候、应用服务器后台会将消息按指定的格式打包,然后结合device token一并发给APNS服务器
4.然后APNS通过注册时候的device token将消息发送到注册的设备上
UI:
- 系统如何寻找到需要响应用户操作的那个Responder
响应对象(Responder)-是具有响应和处理事件能力的对象,UIResponder是所有响应对象的基类。
用户点击屏幕-》检测到触摸的事件将其打包成UIEvent对象,并放入当前活动的UIApplication事件队列中-》取出该事件交给UIWindow来处理-》window首先使用hitTest:withEvent寻找此次touch操作的初始点所在的视图view-》次方法会调用pointInside:withEvent判断点击点是否在视图内以确定是不是点击了当前视图-》如果点击的是当前的视图以此类推遍历这个视图的子视图-》直到找到这个touch操作所在的位置
- 多屏幕尺寸的适配
自动布局,使用Masonry
- UIButton的父类是什么?UILabel呢?
UIButton:父类 UIControl,UIControl的父类是UIView,多了一层,在UIControl中多了一些交互事件的处理。
UILabel:父类 UIView
- push view controller 和 present view controller的区别
使用Push,必须要求当前的控制器在UINavigationController里面,present只要求当前是一个UIViewControler就行。
push是基于当前逻辑操作上叠加一个新的控制器
present一般是临时性的弹出一个界面
- 描述下tableview cell的重用机制
重用通过每个cell指定一个重用表示reuseIdentity,即指定单元格的种类,当cell滚出屏幕的时候,会将滚出屏幕的单元格放入重用的queue中,当某个未在屏幕上显示的单元格要显示的时候,就会从这个queue中取出进行重新,通过重用cell可以达到节省内存给的目的
- UIView的frame和bounds的区别是什么
frame是参照父视图的坐标系统
bounds是本身的坐标系统。原点是(0,0)
场景题
- 发送10个网络请求,然后再接收到所有回应之后执行后续操作,如何实现?
使用dispatch_group_t,开始一个任务enter,结束一个任务release,完成之后回调notify
dispatch_group_t queueGroup = dispatch_group_create();
dispatch_group_enter(queueGroup);
dispatch_group_leave(queueGroup);
dispatch_group_notify(queueGroup, dispatch_get_main_queue(), ^{
});
- 实现一个第三方控件,可以在任何时候出现在APP界面最上层
1.将这个视图添加在Window上
2.将这个控件做成一个新的window,显示在最上层
- 实现一个最简单的点击拖拽功能。上面那个拖拽之外,如果在手放开时,需要根据速度往前滑动呢?
给要拖拽的视图添加上UIPanGestureRecognizer手势,设置视图的center
停止之后的减速利用velocityInView来获取停止时候的速度。
代码:
CGPoint velocity = [panGestureRecognizer velocityInView:self.view];
CGFloat vMax = 3000;
CGFloat distanceMax = 60;
CGFloat finalDisX = (velocity.x * distanceMax)/vMax;
CGFloat finalDisY = (velocity.y * distanceMax)/vMax;
CGFloat finalDisXY = sqrtf((finalDisX * finalDisX) + (finalDisY* finalDisY));
CGPoint finalPoint = CGPointMake(panGestureRecognizer.view.center.x + finalDisX, panGestureRecognizer.view.center.y + finalDisY);
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
[UIView animateWithDuration:finalDisXY/distanceMax delay:0 options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction animations:^{
panGestureRecognizer.view.center = finalPoint;
} completion:nil];
- 如何减小一个应用程序的尺寸?
1.资源图片压缩
2.清理删除不必要的文件
3.压缩视频音频
4.解压ipa文件。查看哪个文件占用空间大,适当优化
- 如何提高一个性用程序的性能?
参考:http://blog.csdn.net/cuiweijie3/article/details/8987965
1.ARC进行内存管理
2.适当情况下使用reuseIdentity 重用
3.尽可能将view设置为不透明(Opaque)
4.避免臃肿的xib
5.不要阻塞主线程
6.让图片的大小UIimageview一样
7.选择正确的合集-使用适合的类和对象编写代码
8.使用GZip压缩-使用GZip对网络传输中的数据进行压缩,减小文件的大小,并加快下载的速度,压缩对文本的数据特别有用,文本具有很高的压缩比,NSURLConnection默认已经支持GZip压缩
9.重用和延迟加载view
10.缓存
11.考虑绘制
12.处理内存警告
13.重用花销很大的对象
14.使用Sprite Sheets-游戏
15.避免重新处理数据
16.选择正确的数据格式
17.设置适当的背景图片
18.降低web内容的影响
19.设置阴影路径
20.优化tableview
21.选择正确的数据储存方式
22.加速启动时间
23.使用Autorelease pool-临时对象不使用的时候,自动释放
24.缓存图片或不缓存-imageNamed加载图片的时候这个图片是有缓存下来,使用imageWithContentOfFile是没有缓存,如果经常使用到的则缓存下来比较合适
25.尽量避免Date格式化
- 不同版本的APP,数据库结构变化了,如何处理?
新建一个新的数据库,旧的数据库数据导出来,按新的数据库的结构存入新的数据库中。