说说那些iOS笔试题
博主之前从事嵌入式开发,本科专业软件工程。毕业后一直从事嵌入式C语言。之所以进入嵌入式行业,完全是个人兴趣。不过,在从业两年之后发现不是自己喜欢的菜。毅然决然的转型到iOS行业。然,博主并非参加培训学校出来,完全利用工作之余时间自学,现在已经在ZAKER工作,从事ZAKER客户端的iPhone版本开发。这里,博主分享一下之前找工作时,总结的笔试题。
题目与答案
答案仅供参考,如有异议或者错误,请指正。
中文试题
#import 跟#include、@class有什么区别?#import<>跟 #import""又什么区别?
1 | 1) #import和#include都能完整地包含某个文件的内容,#import能防止同一个文件被包含多次 |
属性readwrite,readonly,assign,retain,copy,nonatomic各是什么作用,在那种情况下用?
1 | readwrite:同时生成get方法和set方法的声明和实现 |
写一个setter方法用于完成@property (nonatomic,retain)NSString *name,写一个setter方法用于完成@property(nonatomic,copy)NSString *name.
1 | @property (nonatomic, retain) NSString *name; |
1 | @property(nonatomic, copy) NSString *name; |
对于语句NSString*obj = [[NSData alloc] init]; ,编译时和运行时obj分别是什么类型?
1 | 编译时是NSString类型 |
常见的object-c的数据类型有那些,和C的基本数据类型有什么区别?
1 | 常用OC类型:NSString、NSArray、NSDictionary、NSData、NSNumber等 |
id 声明的变量有什么特性?
1 | id声明的变量能指向任何OC对象 |
Objective-C如何对内存管理的,说说你的看法和解决方法?
1 | 每个对象都有一个引用计数器,每个新对象的计数器是1,当对象的计数器减为0时,就会被销毁 |
内存管理的几条原则时什么?按照默认法则.哪些方法生成的对象需要手动释放?在和property结合的时候怎样有效的避免内存泄露?
1 | 只要调用了alloc、copy、new方法产生了一个新对象,都必须在最后调用一次release或者autorelease |
看下面的程序,三次NSLog会输出什么?为什么?
1 | NSMutableArray* ary = [[NSMutableArray array] retain]; |
结果:3、2、1
OC中创建线程的方法是什么?如果指定在主线程中执行代码?如何延时执行代码?
1 | 创建线程的方法 |
1 | 主线程中执行代码 |
1 | 延时执行 |
英文试题
提示: 一定要把英文题目过一遍,有些公司的题目故意弄成英文的。
Difference between shallow copy and deep copy?
1 | 浅拷贝:指针(地址)拷贝,不会产生新对象 |
What is advantage of categories? What is difference between implementing a category and inheritance?
1 | 分类可以在不修改原来类模型的基础上拓充方法 |
Difference between categories and extensions?
1 | 分类是有名称的,类扩展没有名称 |
Difference between protocol in objective c and interfaces in java?
1 | Java的接口中声明的方法必须都实现 |
What are KVO and KVC?
1 | KVC是键值编码,可以通过一个字符串的key(属性名)修改对象的属性值 |
What is purpose of delegates?
1 | 两个对象之间传递数据和消息 |
What are mutable and immutable types in Objective C?
1 | mutable是可变类型,比如NSMutableArray,可以动态往里面添加元素 |
When we call objective c is runtime language what does it mean?
1 | 动态绑定:对象类型在运行时才真正确定 |
what is difference between NSNotification and protocol?
1 | 通过NSNotification可以给多个对象传递数据和消息 |
What is push notification?
1 | 本地推送:程序内部弹出通知到用户设备 |
What is Polymorphism?
1 | 多态:父类指针指向子类对象 |
What is Singleton?
1 | 单例:保证程序运行过程中,永远只有一个对象实例 |
What is responder chain?
1 | 响应者链: |
Difference between frame and bounds?
1 | frame以父控件的左上角为坐标原点 |
Difference between method and selector?
1 | 通过一个selector可以找到方法地址,进而调用一个方法 |
Is there any garbage collection mechanism in Objective C.?
1 | OC 1.0没有垃圾回收 |
What is NSOperation queue?
1 | 用来存放NSOperation对象的队列,可以用来异步执行一些操作 |
Can we use one tableview with two different datasources? How you will achieve this?
1 | 从对象属性上分析,tableView只有一个dataSource属性。当然,真要使用两个不同的数据源,还是有其他办法解决的 |
Can we use two tableview controllers on one viewcontroller?
1 | 从技术角度上分析,一个控制器内部添加两个表格控制器是没有问题的 |
What is lazy loading?
1 | 延迟加载:比如控制器的view,在第一次用到view时才会调用loadView方法进行创建 |
- 链表不具备的特点是()
A. 可随机访问任何一个元素
B. 插入,删除操作不需要移动元素
C. 无需事先估计存储空间大小
D. 所欲存储空间可以是不连续的
参考答案: (A)
链表不同于数组。链表之所有叫链表,就是像一条链一样,要过到某个节点处,就得遍历着找;而数组才具备随机访问任何一个元素的能力,数组可以通过索引直接访问元素,时间复杂度为常量,效率非常高,因此在某些场合上,我们需要数组这样的数据结构。
B. 链表的插入、删除都不需要移动元素,只需要修改指针的指向就可以了,因为链表上的每个节点都是动态分配的,分配在堆上,通过指针来指向每个节点的内存区,要获取某个节点的值,是需要遍历一遍才能找到对应的节点的。
C. 因为链表上的每个节点是分配在堆上,需要开发人员手动申请内存空间的,因此不像数组在定义时就要指定存储空间大小。对于链表,需要增加一个节点时,直接在堆上申请。当需要删除某个节点时,可以直接将该节点的内存给释放掉。
D. 因为链接中的节点都是存储在堆上的,而每个节点之间都有一个指向前一个节点和后一个节点的指针,只要知道链表头指针,就可以通过遍历查找到任何一个节点。因此,链表不同于数组,数组是要连续的内存存储空间,才能保证以常量时间复杂度快速访问任意元素;而链表不要求每个节点是连接,在堆上申请的内存空间很难得到连续的,而且空间产生内存碎片。
- 关于多线程和多进程编程,下面描述正确的是()
A. 多进程里,子进程可获取父进程的所有堆和栈的数据;而线程会与同进程的其他线程共享数据,拥有自己的栈空间。
B. 线程因为有自己的独立栈空间且共享数据,所有执行的开销相对较大,同时不利于资源管理和保护。
C. 线程的通信速度更快,切换更快,因为他们在同一地址空间内。
D. 线程使用公共变量/内存时需要使用同步机制,因为他们在同一地址空间内。
- 设两个变量a=19;b=29;在不创建新实例的情况下使a、b的值互换?
参考答案:
这道题要求不创建新的实例,只有a、b两个变量,要交换这两个变量的值,通常的做法是使用临时变量来临时存储,但是现在要求不使用新的实例,那么有什么办法呢?
方法就是通过位运算来操作:
1 | a = a ^ b; |
对于题目中的a = 19,也就是对应二进制00010011;而b=29,也就是对应二进制00011101
第一步:a = 00010011 ^ 00011101 => 00001110,将a、b的值都记录下来了
第二步:b = 00001110 ^ 00011101 => 00010011(值为19,也就是b得到了原来的a的值)
第三步:a = 00001110 ^ 00010011 => 00011101 (值为29,也就是a得到了原来的b的值)
注意,符号表示按位异或。所谓按位异或是指对应位置上的二进制数值相同为0,不同为1。
- 使用block时什么情况会发生引用循环,如何解决?
参考答案:http://www.henishuo.com/ios-block-memory-cycle
- 为什么要序列化,对象序列化方式?
参考答案:
将对象JSON序列化:
1 | NSLog(@"%s", __FUNCTION__); |
将对象归档:需要遵守NSCoding协议,实现如下方法:
1 | - (void)encodeWithCoder:(NSCoder *)aCoder { |
- 简述如何处理UI与耗时操作的通信,有哪些方式及各自的优缺点?
参考答案:
1)将耗时的计算和IO操作放在子线程去处理,然后到主线程更新UI。优点是采用预加载方式,将耗时操作提前处理。优点是可让UI更流畅;缺点是内存会增多,控制加载逻辑比较复杂。
2)采用延迟加载方式,将耗时操作而不立刻使用时,采用延迟加载。优点是界面可提高流畅度;缺点是在需要显示时还需要加载才能显示,需要稍稍等待。
- 如何优化一个TableView?
参考答案:
1)若高度一定,直接使用rowHeight属性而不是使用heightForRowAtIndexPath方法,以减少调用的消耗。若高度是不固定的,heightForRowAtIndexPath所计算的高度应该缓存起来,每次数据源发生变化时,比如删除、插入、更新行都会重新请求所有的高度。若有100个行,就会有调用100次,因为将高度缓存起来是应该的。同理,heightForHeaderInSection、heightForFooterInSection也应该缓存起来。
2)不要在tableView:cellForRowAtIndexPath:中做太多的计算和IO操作,比如可以将需要的计算提前计算好、IO操作也提前计算好。它应该直接调用来显示就可以。
3)将计算行高的时间提前到从服务器获取数据的时候,计算完了高度一并写回数据库或者通过转型为model,将高度放到模型中。但是,最好将高度缓存起来。若一个model的数据有不同的状态,比如展开与收起状态,应该也将高度都缓存起来。注意使用异步去计算,计算完成后再回到主线程显示。
4)在设置显示图片时,不要直接设置UIImageView的contentMode属性自动适应,图片变形会计算transform,压缩时会乘以一个矩阵,消耗性能。对于要求性能较高的app,应该将得到的图片经过处理成UIImageView大小后再呈现。
5)不要将视图的opaque属性设置为NO,默认为YES,它表示不透明度。当opque为NO的时候,图层的半透明取决于图片和其本身合成的图层为结果。
6)layer添加圆角是比较耗时的,这样会离屏渲染,需要牺牲更多的性能。比如,图片显示有圆角时,可以通过core graphics来生成带圆角的图片等。
7)手动绘制cell。绘制cell不建议使用UIView,建议使用CALayer。 UIView的绘制是建立在CoreGraphic上的,其使用的是CPU。CALayer使用的是Core Animation,CPU、GPU都可以使用且由系统自动决定使用哪一个。UIView的绘制,使用的是自下向上的一层一层的绘制,而后渲染。Layer处理的是纹理,利用GPU的 Texture Cache和独立的浮点数计算单元可以加速纹理的处理。
8)重用cell。防止重复的绘制,减少渲染次数,可提高性能。
9)减少subviews的数量。尽量放在同一层view上显示。
10)尽量少动态给cell添加子view。用addView给Cell动态添加View,可以初始化时就添加,然后通过hide来控制是否显示。
更多参看:
http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/
简答题
- 假设类SomeClass中声明了一个委托属性delegate,该属性遵守自定义委托协议SomeDelegate,请写出该类和对应委托协议的定义?
1 | @protocol SomeDelegate<NSObject> |
- 简述UITableView的重用机制,并写出实现该机制的关键代码?
关键代码:
1 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellId"]; |
简述推送实现步骤?
定义一个带参宏,返回两个参数中较小的那个?
strong和weak分别起什么作用?有什么区别?
执行下面程序后NSLog的输出结果为( C )?
A.1,1 B.2,1 C.2,5 D.运行错误
1 | int a[5] = {1,2,3,4,5}; |
- 执行下面程序后NSLog的输出结果为( B )?
A.a,a1,a1 B.a1,a1,a1 C.a1,a,a D.a1,a1,a
1 | int main(int argc, char *argv[]){ |
Cocoa中所有的类都是( NSObject和NSProxy )的子类。
列举几个Cocoa Touch框架?
Foundation、UIKit、Core Data
- 下面机型屏幕分辨率分别是多少?
1 | iPhone4、4S:960X640 |
- Objective-C中的线程类是( NSThread ),常见方法有哪些( dispatch_async )、( dispatch_sync ),处理多线程同步有哪些类( )。
数据库
现有MySQL数据库,分别对下表写出要求的SQL语句,用到实例数据请自行给出即可。
表结构如下:
字段名 | 类型 |
---|---|
UserID | Integer |
UserName | varchar(20) |
Password | varchar(20) |
创建表:
1 | CREATE TABLE `test`.`table_a` ( |
增加记录:
1 | insert into `test`.`table_a` ( `UserName`, `UserID`, `Password`) values ( 'cd', '10', '123') |
删除记录:
1 | delete from `test`.`table_a` where `UserID`=’10' |
编程题
1.请通过接口“http://someurl/somefunc”获取数据,并在UI上显示。接口入参argu是一个字符串类型的变量,返回值是字典。
1)使用NSURL相关API实现网络加载类,其中:通过post方法发送请求,建立异步连接;
2)报文采用JSON格式;
3)多线程采用GCD或NSOperation实现;
4)以左边键右边值的格式在界面上显示结果。
2.传入数组*array和数组长度length,实现冒泡排序算法。
1 | int *BubbleSort(int *array, int length); |