iOS工程师面试题.docx
《iOS工程师面试题.docx》由会员分享,可在线阅读,更多相关《iOS工程师面试题.docx(8页珍藏版)》请在冰豆网上搜索。
iOS工程师面试题
iOS工程师面试题
1.谈谈你对多线程开发的理解?
iOS中有几种实现多线程的方法?
好处:
1、使用线程能够把程序中占据时间长的任务放到后台去处理,如图片、视频的下载2、发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好缺点:
1、大量的线程降低代码的可读性,2、更多的线程需要更多的内存空间3、当多个线程对同一个资源出现争夺的时候要注意线程安全的问题。
iOS有三种多线程编程的技术:
1、NSThread(两种创立方式)[NSThreaddetachNewThreadSelector:
@selector(doSomething:
)toTarget:
selfwithObject:
nil];NSThread*myThread=[[NSThreadalloc]initWithTarget:
selfselector:
@selector(doSomething:
)object:
nil];
[myThreadstart];2、NSOperationQueue
NSOperationQueue*oprationQueue=[[NSOperationQueuealloc]init];
oprationQueueaddOperationWithBlock:
^{
//这个block语句块在子线程中执行
}
3、GrandCentralDispatch(GCD)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
//耗时的操作
dispatch_async(dispatch_get_main_queue(),^{
//更新界面
});
});
PS:
不显示的创立线程的方法:
用NSObject的类方法 performSelectorInBackground:
withObject:
创立一个线程:
[ObjperformSelectorInBackground:
@selector(doSomething)withObject:
nil];
1.线程同步和异步的区别?
IOS中如何实现多线程的同步?
同步:
一个线程要等待上一个线程执行完之后才能执行当前的线程,生活中的例子(上厕所)。
异步:
同时去做两件或者多件事。
比如边听歌边看报。
原子操作(atomic)、加锁(NSLock、NSRecursive、NSConditionLock)、@synchronizedGCD串行队列,GCD当中的屏障,NSOperationQueue设置最大并发数为1
参考()
1.iOS类是否能够多继承?
如果没有,那能够用其它方法实现吗?
简述实现过程。
不能够,能够经过消息转发、delegate和protocol和类别来实现类似多继承。
1.iOS本地数据存储都有哪几种方式?
iOS如何实现复杂对象的存储?
NSKeyedArchiver(归档)采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,而且该对象对应的类必须提供encodeWithCoder:
和initWithCoder:
方法。
1.NSUserDefaults:
用来保存应用程序设置和属性、用户保存的数据。
用户再次打开程序或开机后这些数据依然存在。
NSUserDefaults能够存储的数据类型包括:
NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。
2.Write写入方式:
永久保存在磁盘中。
3.SQLite(FMDB、CoreData)
NSCoding+NSKeyedArchiver实现复杂对象的存储。
1.深拷贝和浅拷贝的理解?
深拷贝拷贝的是内容,浅拷贝拷贝的是指针。
深拷贝和浅拷贝最大的区别就是子类对象的地址是否改变,如果子类对象的地址改变那么就是深拷贝。
1.怎样实现一个singleton的类。
staticLOSingleton*shareInstance;
+(LOSingleton*)sharedInstance{
@synchronized(self){//这个东西其实就是一个加锁。
如果self其它线程访问,则会阻塞。
这样做一般是用来对单例进行一个死锁的保护
if(shareInstance==nil){
shareInstance=[[superallocWithZone:
NULL]init];
}
}
returnshareInstance;
}
//第二种方式
+(LOSingleton*)sharedInstance
{
staticLOSingleton*sharedInstance=nil;
staticdispatch_once_tonceToken;//锁
dispatch_once(&onceToken,^{//最多调用一次
sharedInstance=[[selfalloc]init];
});
returnsharedInstance;
}
1.什么是安全释放?
在对象release之后把指针置为nil
1.RunLoop是什么?
一个RunLoop就是一个时间处理的循环,用来不停的调度工作以及处理输入时间。
使用runloop的目的是让你的线程在有工作的时候忙于工作,而没工作的时候处于休眠状态。
runloop的设计是为了减少cpu无谓的空转。
1.什么是序列化和反序列化,能够用来做什么?
如何在OC中实现复杂对象的存储?
如果你需要存储一个复杂的对象的话,经常要以二进制的方法序列化这个对象,这个过程叫Archiving。
如果一个对象需要进行序列化,那么需要遵循NScoding协议,主要有两个方法:
-(id)initWithCoder:
(NSCoder*)coder;//从coder中读取数据,保存到相应变量中,即反序列化数据。
-(void)encodeWithCoder:
(NSCoder*)coder;//读取实例变量,并把这些数据写到coder中去,即序列化数据。
1.简述应用程序按Home键进入后台时的生命周期,以及从后台回到前台时的生命周期?
应用程序的状态:
Notrunning未运行,程序没启动
Inactive未激活,程序在前台运行,不过没接受到事件,没有事件处理的状态下一般处于这个状态。
Active激活程序在前台而且接收到了事件Backgound后台程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。
Suspended挂起程序在后台不能执行代码。
-(BOOL)application:
(UIApplication*)applicationwillFinishLaunchingWithOptions:
(NSDictionary*)launchOptions//告诉代理进程启动但还没进入状态保存-(BOOL)application:
(UIApplication*)applicationdidFinishLaunchingWithOptions:
(NSDictionary*)launchOptions// 告诉代理启动基本完成程序准备开始运行-(void)applicationWillResignActive:
(UIApplication*)application// 当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话了-(void)applicationDidBecomeActive:
(UIApplication*)application // 当应用程序入活动状态执行,这个刚好跟上面那个方法相反-(void)applicationDidEnterBackground:
(UIApplication*)application// 当程序被推送到后台的时候调用。
因此要设置后台继续运行,则在这个函数里面设置即可-(void)applicationWillEnterForeground:
(UIApplication*)application//当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。
-(void)applicationWillTerminate:
(UIApplication*)application//当程序将要退出是被调用,一般是用来保存数据和一些退出前的清理工作。
这个需要要设置UIApplicationExitsOnSuspend的键值。
-(void)applicationDidFinishLaunching:
(UIApplication*)applicatio//当程序载入后执行
1.描述应用程序的启动顺序。
1、程序入口main函数创立UIApplication实例和UIApplication代理实例2、在UIApplication代理实例中重写启动方法,设置第一ViewController3、在第一ViewController中添加控件,实现对应的程序界面。
1.UIImage初始化一张图片有几种方法?
简述各自的优缺点。
1、从资源读取UIImage*image=[UIImageimageNamed:
@”1.png”];2、从网络读取NSURL*url=[NSURLURLWithString:
@""];3.从手机本地读取//读取本地图片非resourceNSString *aPath3=[NSString stringWithFormat:
@"%@/Documents/%@.jpg",NSHomeDirectory(),@"test"];UIImage *imgFromUrl3=[[UIImage alloc]initWithContentsOfFile:
aPath3]; 4.从现有的context中获得图像
//addImageIO.frameworkand#import
CGImageSourceRefsource=CGImageSourceCreateWithURL((CFURLRef)url,NULL);
CGImageRefimg=CGImageSourceCreateImageAtIndex(source,0,NULL);
CGContextRefctx=UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
//transformCTM的2种方式
//CGContextConcatCTM(ctx,CGAffineTransformMakeScale(.2,-0.2));
//CGContextScaleCTM(ctx,1,-1);
//注意坐标要反下,用ctx来作为图片源
CGImageRefcapture=CGBitmapContextCreateImage(ctx);
CGContextDrawImage(ctx,CGRectMake(160,0,160,230),[imageCGImage]);
CGContextDrawImage(ctx,CGRectMake(160,230,160,230),img);
CGImageRefcapture2=CGBitmapContextCreateImage(ctx);
5、用Quartz的CGImageSourceRef来读取图片
CGImageSourceRefsource=CGImageSourceCreateWithURL((CFURLRef)url,NULL);
CGImageRefimg=CGImageSourceCreateImageAtIndex(source,0,NULL);
参考()
1.这段代码有什么问题吗:
@implementationPerson
-(void)setAge:
(int)newAge{
self.age=newAge;
}
@end死循环
1.这段代码有什么问题,如何修改
for(inti=0;iNSString*string=@”Abc”;
string=[stringlowercaseString];
string=[stringstringByAppendingString:
@"xyz"];
NSLog(@“%@”,string);
}
如果数字很大的话会造成内存一直增加(因为一直经过便利构造器方法创立autorelease对象),直到循环结束才减少,在循环内加一个自动释放池,更改后代码如下:
for(inti=0;iNSString*string=@”Abc”;@autoreleasepool{
string=[stringlowercaseString];
string=[stringstringByAppendingString:
@"xyz"];
NSLog(@“%@”,string);
}
}
1.截取字符串”20|”中,”|”字符前面和后面的数据,分别输出它们。
NSString*string=@”20|”;[stringcomponentsSeparatedByString:
@”|”];
2.简述你对UIView、UIWindow和CALayer的理解
UIView继承于UIResponder,UIResponder继承于NSObject,UIView能够响应用户事件。
CALayer继承于NSObject,因此CALayer不能响应事件。
UIView构建界面,UIView侧重于对内容的管理,CALayer侧重于对内容的绘制。
UIView是用来显示内容的,能够处理用户事件;CALayer是用来绘制内容的,对内容进行动画处理,依赖与UIView来进行显示,不能处理用户事件。
1.Whatislazyloading?
在使用的时候才去初始化,比如UITableViewCell的imageView属性,懒加载对象的创立是在getter方法里面进行创立的。
1.什么是Protocol?
什么是代理?
写一个委托的interface?
委托的property声明用什么属性?
为什么?
协议提供了一组方法,可是并不负责实现,如果一个类遵循了某个协议,而且实现了协议里面的方法,那么我们称这个类就是遵循了某个协议的代理。
属性的声明使用assign,防止出现循环引用的问题。
1.分别描述类别(categories)和延展(extensions)是什么?
以及两者的区别?
继承和类别在实现中有何区别?
为什么Category只能为对象添加方法,却不能添加成员变量?
category类目:
在不知道源码的情况下为一个类扩展方法,extension:
为一个类声明私有方法和变量。
继承是创立了一个新的类,而类别只是对类的一个扩展,还是之前的类。
类目的作用就是为已知的类添加方法。
1.Objective-C有私有方法么?
私有变量呢?
如多没有的话,有没有什么代替的方法?
objective-c – 类里面的方法只有两种, 静态方法和实例方法. @private来修饰私有变量OC中所有的实例变量默认都是私有的,所有的实例方法默认都是公有的。
吗
1.如何监测系统键盘的弹出[[NSNotificationCenterdefaultCenter]addObserver:
selfselector:
@selector()name:
UIKeyboardWillShowNotificationobject:
nil];
2.举出5个以上你所熟悉的iOSSDK库有哪些和第三方库有哪些?
Foundation,CoreFraphics,UIKit,MapKit,CoreLocation,CFNetWork,MessageUI,ImageIO,CoreData,AFNetWorking,MKNetWorkKit,ASIHttpRequest,FMDB,ZXing,ZBar,SDWebImage
1.如何将产品进行多语言发布?
程序的国际化
1.如何将敏感字变成**字符串替换stringByReplacingOccurrencesOfString:
withString:
1.objc中的减号与加号代表什么?
+静态方法,也叫类方法,-实例方法
1.给定的一个字符串,判断字符串中是否还有png,有就删除它?
[stringstringByReplacingOccurrencesOfString:
@"png"withString:
@“"]
1.对于语句NSString*testObject=[[NSDataalloc]init];testObject在编译时和运行时分别是什么类型的对象?
编译的时候是NSString类型,运行的时候是NSData类型
1.OC中是所有对象间的交互是如何实现的?
函数指针实现
1.目标-动作机制目标是动作消息的接收者。
动作是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动作而实现的方法。
常见的UIButton添加方法
1.NSArray和NSMutableArray的区别,多线程操作哪个更安全?
NSArray不可变数组,NSMutableArray可变数组,NSArray更安全,多线程操作的时候记得加锁。
1.当前有一个数组,里面有若干重复的数据,如何去除重复的数据?
(会几个写几个)最简单的方式,把数组里面的元素放到集合里面。
也能够对数组进行排序,排序之后把数组里相同的元素删除掉
1.isKindOfClass、isMemberOfClass作用分别是什么?
-(BOOL)isKindOfClass:
classObj判断是否是这个类或者是这个类子类的实例-(BOOL)isMemberOfClass:
classObj判断是否是这个类的实例
1.iPhone上,不能被应用程序直接调用的系统程序是什么?
时钟、视频、指南针、天气、计算器、备忘录、提醒事件、股市
1.以.mm为拓展名的文件里,能够包含的代码有哪些?
c和obj-c如何混用
obj-c的编译器处理后缀为m的文件时,能够识别obj-c和c的代码,处理mm文件能够识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj-c的代码,因为cpp只是cpp
2)在mm文件中混用cpp直接使用即可,因此obj-c混cpp不是问题
3)在cpp中混用obj-c其实就是使用obj-c编写的模块是我们想要的。
如果模块以类实现,那么要按照cppclass的标准写类的定义,头文件中不能出现obj-c的东西,包括#importcocoa的。
实现文件中,即类的实现代码中能够使用obj-c的东西,能够import,只是后缀是mm。
如果模块以函数实现,那么头文件要按c的格式声明函数,实现文件中,c++函数内部能够用obj-c,但后缀还是mm或m
1.sizeof和strlen的区别和联系
sizeof是运算符,strlen是函数charstr[20]="";inta=strlen(str);//a=10;>>>>strlen计算字符串的长度,以结束符0x00为字符串结束。
intb=sizeof(str);//而b=20;>>>>sizeof计算的则是分配的数组str[20]所占的内存空间的大小,不受里面存储的内容改变。
1.sprintf,strcpy,memcpy的功能?
使用上要有哪些要注意的地方char*strcpy(char*dest,constchar*src);
其对字符串进行操作,完成从源字符串到目的字符串的拷贝,当源字符串的大小大于目的字符串的最大存储空间后,执行该操作会出现段错误。
intsprintf(char*str,constchar*format,...)
函数操作的源对象不限于字符串:
源对象能够是字符串、也能够是任意基本类型的数据。
主要是实现将其它数据类型转换为字符串
void*memcpy(void*dest,constvoid*src,size_tn)
实现内存的拷贝,实现将一块内存拷贝到另一块内存。
该函数对源对象与目的对象没有类型现在,只是对内存的拷贝
1.写一个代码片段输入一个字符串“”,输出一个NSDate类型的对象,打印该对象输出-03-2215:
28:
32NSDateFormatter@“yyyy-MM-ddHH:
mm:
ss”
1.用变量a写出以下定义
a、一个整型数inta;
b、一个指向整型数的指针int*a;
c、一个指向指针的指针,它指向的指针是指向一个整型数int**a;
d、一个有10个整型数的数组inta[10];
e、一个有10个指针的数组,该指针是指向一个整型数的int*a[10];
f、一个指向有10个整型数数组的指针int(*a)[10];
g、一个指向函数的指针,该函数有一个整型参数,并返回一个整型数int(*a)(int);