1.常见提问:
(1)有什么擅长?
这个要好好想想
(2)技术上研究的最深入的是那一块?
这个要好好想想,会问的很细.
(3)缺点?优点?为什么来我公司?面试最后会问对公司有什么想了解的吗?
举例确定然后怎么改的或者这个缺点不影响工作;
公司发展前景怎么好等等
公司发展,职位细节,薪资等等
(4)最近看什么类型的书?经常浏览什么网站?
书:举例一本技术类和非技术类的
网站: stackoverflow ,github , cocoa China , V2EX , SegmentFault ,CSDN , 简书 ,博客园 等等
(5)http 和 https的区别?https怎么实现更安全的?
>>http有明显的缺陷,它是明文传送,同时对消息完整性检测不足,这种缺陷很容易被人窃取传输中的信息,尤其是当前网站交易和支付相当普遍,个人越来越重视隐私信息的情况下。
>>https于就应此而生,网景Netscape公司提出了HTTPS协议,用以增强网上数据传输的安全性,作用原理是在TCP和HTTP之间增加了用以保障数据通信安全性的SSL(Secure Sockets Layer) 协议;基于SSL的HTTP信息传输协议就是HTTPS (HyperText Transfer Protocol over Secure Socket Layer).
>>HTTP采用80数据端口,而HTTPS则443端口。https://zhidao.baidu.com/question/1539092189748973467.html
>> 解释SSL(Secure Sockets Layer) 协议?
SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
SSL协议提供的服务主要有:
1》认证用户和服务器,确保数据发送到正确的客户机和服务器;
2》加密数据以防止数据中途被窃取;
3》维护数据的完整性,确保数据在传输过程中不被改变。
http://blog.csdn.net/ysdaniel/article/details/6782469
(6)自己手动实现KVO功能?
(7)runtime 中method swizzling 和IMP(VIMP)的区别?
前者是运行时方法交换,直接调用方法,后者是以直接调用方法的IMP指针,来避免方法调用死循环的问题,比如:_objc_msgForward是一个函数指针(和 IMP 的类型一样),是用于消息转发的,通过函数指针的形式去调用其他或者父类该方法。
http://blog.csdn.net/u014466582/article/details/47108563
(8)自己实现日志收集和分析(不用第三方比如Bugly)?
http://mobile.51cto.com/hot-436334.htm
http://www.jianshu.com/p/7f584e5c4376
http://blog.sina.com.cn/s/blog_a573f7990102uzt9.html
(9)说说常用加密技术 如MD5 、对称和RSA非对称等等技术
* iOS RSA加解密签名和验证 代码地址https://github.com/HustBroventure/iOSRSAHandler
* iOS,一行代码进行RSA、DES 、AES加密、解密及MD5加密
百度知道基本概念:
MD5:http://baike.baidu.com/item/MD5
对称和非对称加密概念:http://baike.baidu.com/view/444169.htm
RSA非对称加密:http://baike.baidu.com/item/RSA算法
2.RAC:对不同的编码方式,如: action、delegate、KVO、回调等。ReactiveCocoa为事件定义了标准的接口,从而可以使用一些基本工具来更容易的连接、过滤和组合。
FRP: 函数响应式编程, RAC它是Objective-C语言下FRP思想的一个优秀实例,后续版本也支持了Swift语言。
zip : 信号合并 combineLatest
3.block:
__weak :block外面修饰防止被强引用
__block :block外面修饰需要在block里修改的变量
^(){
_strong : block 修饰外面通过__weak修饰过的对象(一般self),防止被提前释放
}
(2)Block可以定义在方法内部,也可以定义在方法外部;
(3)只有调用Block时候,才会执行其{}体内的代码
3(1).block:
(A) block(块)的本质是什么?
block定义
structBlock_descriptor{
unsignedlongintreserved;unsignedlongintsize;void(*copy)(void*dst,void*src);void(*dispose)(void*);};
structBlock_layout{void*isa;intflags;intreserved;void(*invoke)(void*,...);structBlock_descriptor*descriptor;/* Imported variables. */};
你定义完block之后,其实是创建了一个函数,在创建结构体的时候把函数的指针一起传给了block,所以之后可以拿出来调用。
定义block的时候,变量a的值就传递到了block结构体中,仅仅是值传递,所以在block中修改a是不会影响到外面的a变量的。
而加了__block前缀,并不是直接传递a的值了,而是把a的地址传过去了,所以在block内部便可以修改到外面的变量了。
(B)函数指针? 理解block需要
函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。
(C)指针函数:
指针函数是指返回值是指针的函数,即本质是一个函数。
(D)生成一百个单例对象,如何作内存管理?
单例对象地址不都是静态吗?所以其实就一个内存地址。
Objective-C中的深拷贝和浅拷贝 (推荐)
4.封装(封装哪些?)
1.时间选择器自定义封装
2.图片选择器
3.富文本编辑器
4.图形柱状
5.runtime 是 OC底层的一套C语言的API ,
·动态交换两个方法的实现(特别是交换系统自带的方法)
·动态添加对象的成员变量和成员方法
·获得某个类的所有成员方法、所有成员变量
6. KVO 给对象的属性添加监听,改变改属性值,会自动调用方法然后进行操作
7.网络处理 :
应用层:HTTP,FTP 等等
传输层:TCP,UDP
网络层:IP
TCP/IP 即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准
ip地址+协议+端口号唯一标示网络中的一个进程
socket是一种 ”打开—读/写—关闭"模式,[服务器socket监听端口-客户端创建socket-连接服务器-连接成功-客户端数据写入-服务器读取-客户端关闭-服务器关闭]
8.多线程 :
同步 - 异步 - 并发 - 串行:
·同步和异步 -函数 -主要影响: 能不能开启新线程
·并发和串行- 队列 -主要影响: 任务的执行方式
·1.同步并发,同步串行效果相同:只有主线程(没有子线程 = 0)
·2.异步并发:多线程同时执行(可能有多个子线程 >=1)
·3.异步串行:主线程 和 一个子线程(只有一个子线程 = 1)
常用:
1.延时dispatch_after
2.once :dispatch_once
3.GCD迭代: dispatch_apply(相对于for循环耗时减少一半左右)
4.队列组 -- 先将分组内的任务完成,再继续完成别的任务
创建组队列:dispatch_group_t -> 添加任务到组队列中执行dispatch_group_async -> 队列中的任务执行完后,执行这段代码: dispatch_group_notify
5.执行子线程后回到主线程:dispatch_get_main
9.数据存储:
Realm 是一个跨平台的移动数据库引擎
特点:跨平台,简单易用,可视化
Object:模型 -
关系(Relationships):“一对多”“多对一”和“多对多”的关系
写操作事务:数据库中的所有操作,比如创建、编辑,或者删除对象,都必须在事务中完成。“事务”是指位于write闭包内的代码段。
查询(Queries):要在数据库中检索信息
Results:这个类是执行任何查询请求后所返回的类
10.Swift
1.混编:点击项目-->TARGETS-->Build Settings中找到Swift Compiler,里面有一项:Objective-C Bridging Header
链接到项目头文件,然后#import "AwesomeMenu.h"就可以了
2.5种修饰符访问权限排序: open > public > interal > fileprivate > private
1,private : private访问级别所修饰的属性或者方法只能在当前类里访问。
2,fileprivate: fileprivate访问级别所修饰的属性或者方法在当前的Swift源文件里可以访问。(比如上门样例把private改成fileprivate就不会报错了)
3,internal(默认访问级别,internal修饰符可写可不写)
internal访问级别所修饰的属性或方法在源代码所在的整个模块都可以访问。
如果是框架或者库代码,则在整个框架内部都可以访问,框架由外部代码所引用时,则不可以访问。
如果是App代码,也是在整个App代码,也是在整个App内部可以访问。
4,public : 可以被任何人访问。但其他module中不可以被override和继承,而在module内可以被override和继承。
5,open : 可以被任何人使用,包括override和继承。
-------------20161027---------------------
面试笔记2:
1.有什么擅长?
(1)封装一些常用的小功能Utils
(2)解决一些常见和不常见的bug
(3)快速学习新知识和功能
2.Bug日志收集 :腾讯bugly , 性能调优 leak 和unused XXX(shift+ common + B)视图层次:reveal [ri’vi:l]
3.自定义控件 : pickview ,图片选择器,多选,alertView
常用动画 :
(1)UIView动画setAnimation
(2)CATransition(转场动画):淡入淡出 , 翻页
(3)popview
4.SVN、Git代码管理命令和工具
Git工具:sourceTree
SVN工具:Cornerstone
5.常用第三方
MJex ,MJref , masonry ,AF , SDweb, BlocksKit , RACetc.
6.
多媒体视频播:
(1)常用格式:AVPlayer
(2) 视频播放器
https://github.com/Bilibili/ijkplayer
iOS video player based on FFmpeg n3.1, with MediaCodec, VideoToolbox support.
https://github.com/kolyvan/kxmovie
https://github.com/0xced/XCDYouTubeKit
YouTube video player for iOS, tvOS and OS X
不常用格式视频:视频编码解码FFmpeg:是一个跨平台的开源视频框架,能实现如视频编码,解码,转码,串流,播放等丰富的功能。其支持的视频格式以及播放协议非常丰富,几乎包含了所有音视频编解码、封装格式以及播放协议
(3)直播流程:
目录
如何快速的开发一个完整的iOS直播app:
1.七牛云(熊猫TV,龙珠TV等直播平台都是用的七牛云
)
http://cocoadocs.org/docsets/PLCameraStreamingKit/1.7.2/
2.网易视频云:基于专业的跨平台视频编解码技术和大规模视频内容分发网络,提供稳定流畅、低延时、高并发的实时音视频服务,可将视频直播无缝对接到自身App
http://vcloud.163.com/docs/index.html
直播
点播
(4)音频:
豆瓣音频流:
https://github.com/douban/DOUAudioStreamer
3.多线程下载,后台下载
(1) NSURLSessionDataTask :断点续传
(2) NSURLSessionDownloadTask :唯一可以实现后台下载 和 断点续传:
@property (nonatomic, strong) NSData *data;
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
//下载
_task = [_session downloadTaskWithURL:url];
[_task resume];
//取消下载并调用回调与恢复数据供以后使用
[_task cancelByProducingResumeData:^(NSData *resumeData) {
_data = resumeData;
}];
//恢复下载
_task = [_session downloadTaskWithResumeData:_data];
http://www.cocoachina.com/ios/20160503/16053.html
4.文件压缩和解压缩
第三方框架github网址:https://github.com/ZipArchive/ZipArchive
5.即时通讯
环信 . 融云 .等第三方
6.开发问题
(1) APP里接入第三方晚报接口,对方返回数据不稳定导致客户端数据有问题: 通过自己公司服务器过滤一遍
(2)审核问题:对于不能App中包含谈论Android系统的内容:不仅仅是名称,也有图片包含类似安卓手机的图片
(3)复杂的角色关系:多个角色对一个页面功能,很好的锻炼了逻辑能力
(4)频繁的框架改版:前期设计没有很好的考虑到,后期进行大量改版,工作量多余
线程锁
@synchronized
面试笔记3:
一常用动画:
1.左旋转45°缩小到最小,然后再从小到大推出.
* animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0.50, -0.50, 0.50)];
[animation setSubtype: kCATransitionFromBottom];
kCATransition (Fade淡出MoveIn覆盖原图Push推出Reveal底部显出来..)
2.
[yourView.layer addAnimation:theAnimation forKey:@"animateTransform"];
//中心点
[yourView.layer setAnchorPoint:CGPointMake(0.5, 0.5)];
//左上角
[yourView.layer setAnchorPoint:CGPointMake(0, 0)];
//右下角
[yourView.layer setAnchorPoint:CGPointMake(1, 1)];
2.NSTimer
(1) 举例:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(timerFired:) userInfo:nil repeats:NO];
或
NSTimer *myTimer = [NSTimertimerWithTimeInterval:3.0 target:selfselector:@selector(timerFired:)userInfo:nilrepeats:NO];
[[NSRunLoopcurrentRunLoop]addTimer:myTimerforMode:NSDefaultRunLoopMode];
//当定时器创建完(不用scheduled的,添加到runloop中后,该定时器将在初始化时指定的timeInterval秒后自动触发。
(2)、触发(启动)
-(void)fire;//方法来立即触发该定时器;
(3)、停止
- (void)invalidate;//这个是唯一一个可以将计时器从runloop中移出的方法。
3 . runloop使用场景
(1) NSTimer实例是被加到当前runloop中的,模式是NSDefaultRunLoopMode。而“当前runloop”就是应用程序的main runloop,此main runloop负责了所有的主线程事件,这其中包括了UI界面的各种事件。当主线程中进行复杂的运算,或者进行UI界面操作时,由于在main runloop中NSTimer是同步交付的被“阻塞”,而模式也有可能会改变。因此,就会导致NSTimer计时出现延误。
使用实例 :
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
}
self.timer = [NSTimer timerWithTimeInterval:0.01 target:self selector:@selector(addTime) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timerforMode:NSRunLoopCommonModes];
解释:[NSRunLoop currentRunLoop]获取的就是“main runloop”,使用NSRunLoopCommonModes模式,将NSTimer加入其中。
(2) 开辟子线程:使用子线程的runloop,使用场景: TableView滚动时中cell同步更新计时器数据)
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread) object:nil];
[thread start];
- (void)newThread{
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(addTime) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run];
[默认NSDefaultRunLoopMode,TableView滚动时timer休眠,停止运行]
或者:
NSTimer* timer1 = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(addTimer) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer1 forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
}
(3)使用GCD,同样也是多线程方式:
声明全局成员变量
1 dispatch_source_t _timers;
实现代码:
1uint64_t interval = 0.01 * NSEC_PER_SEC;
2dispatch_queue_t queue = dispatch_queue_create("my queue", 0);
3_timers = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
4dispatch_source_set_timer(_timers, dispatch_time(DISPATCH_TIME_NOW, 0), interval, 0);
5__weak ViewController *blockSelf = self;
6dispatch_source_set_event_handler(_timers, ^()
7{
8NSLog(@"Timer %@", [NSThread currentThread]);
9[blockSelf addTime];
10});
11dispatch_resume(_timers);
然后在主线程中修改UI界面:
1 dispatch_async(dispatch_get_main_queue(), ^{
2self.label.text = [NSString stringWithFormat:@"%.2f", self.timeCount/100];
3});
(4)滑动与图片刷新
当tableview的cell上有需要从网络获取的图片的时候,滚动tableView,异步线程会去加载图片,加载完成后主线程就会设置cell的图片,但是会造成卡顿。可以让设置图片的任务在CFRunLoopDefaultMode下进行,当滚动tableView的时候,RunLoop是在UITrackingRunLoopMode下进行,不去设置图片,而是当停止的时候,再去设置图片。
- (void)viewDidLoad {
[superviewDidLoad];
//只在NSDefaultRunLoopMode下执行(刷新图片)
[self.myImageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@""] afterDelay:ti inModes:@[NSDefaultRunLoopMode]];
}
(5)常驻子线程,保持子线程一直处理事件
http://blog.csdn.net/pengyuan_d/article/details/50994166
为了保证线程长期运转,可以在子线程中加入RunLoop,并且给Runloop设置item,防止Runloop自动退出。
1+ (void)networkRequestThreadEntryPoint:(id)__unused object {
2@autoreleasepool{
3[[NSThread currentThread] setName:@"AFNetworking"];
4NSRunLoop*runLoop = [NSRunLoop currentRunLoop];
5[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
6[runLoop run];
7}
8}
4.音视频
(1)封装格式(MP4,RMVB,TS,FLV,AVI)
编解码工具:ffmpeg库—H.264软编解码以及常用IPB帧压缩算法
(2)音频:格式:常用新格式AAC (mp3旧):
AAC码流解析的步骤就是首先从码流中搜索0x0FFF,分离出ADTS frame;
然后再分析ADTS frame的首部各个字段。这就是AAC码流解码时的主要逻辑.
(3)视频像素数据:
像素数据主要有两种,RGB个式和YUV格式
RGB原理:把一幅图片的每个点上的颜色记录下来(三原色)
YUV原理:亮度和色度信息数据,YUV420P格式居多
(4)音频采样数据(PCM)
5. FFmpeg相关函数方法库
(1) FFmpeg的8个库
.avcodec :编解码(最重要)
.avformat :封装格式处理
.avutil :工具库
.swscale :视频像素数据格式转换
.avfilter :滤镜特效处理
.avdevice :各种设备的输入输出
.postproc :后加工
.swresample :音频采样数据格式转换
6.FFmpeg解码流程
FFmpeg所有的初始化都要用到"av_register_all()"这个函数来注册所有的组件
接下来"avformat_open_input()"是打开视频流
"avformat_find_stream_info()"打开视频文件,查看视频流信息(例如这个视频是多宽多高,解码器类型)
"avcodec_find_decoder()"找出视频的解码器
"avcodec_open2()"将它打开
接下来进入一个循环
"av_read_frame()"调用时它会读取一帧的压缩数据(h.264码流)
读取完后它会执行"Get Packet",若为true则说明读取到了数据,则进行下一步,若没读取到则说明视频流已经读取完毕就退出了
"AVPacket"是一个结构体,里面装的是h.264
"avcodec_decode_video2()"这是解码中最重要的函数,他负责将AVPacket->AVFream
"AVFream"里面装的是yuv数据
"show on screen"这一步我们后边会使用SDL将它展示在我们的屏幕上,然后再重新读取数据,进入循环
这就是FFmpeg解码的一个基本流程
7.block
(1) 引用循环
__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
__typeof__(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
} );
8.正则表达式
http://www.admin10000.com/document/5944.html
9.IOS使用Asyncsocket进行socket编程:
https://my.oschina.net/u/2448717/blog/499784
10 .oc中结构体和枚举
(1) .推荐的定义枚举类型的方式
typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) {
RWTLeftMenuTopItemMain,
RWTLeftMenuTopItemShows,
RWTLeftMenuTopItemSchedule
};
(2) .定义一个Sample结构体
struct Sample{
int a;
int b;
int c;
}sampleStruct;
typedef struct Sample MySampleStruct;
//以后用这个结构体,就可以直接用MySampleStruct去定义了
MySampleStruct samDefineStructVarible = {1,2,1};
samDefineStructVarible.a = 1;
samDefineStructVarible.b =2;
samDefineStructVarible.c = 3;
11 .iOS: webView与html的交互
`pod 'WebViewJavascriptBridge', '~> 5.0'`
12. gcd总结:
为什么使用gcd:
GCD可用于多核的并行运算
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
同步执行(sync):只能在当前线程中执行任务,不具备开启新线程的能力
异步执行(async):可以在新的线程中执行任务,具备开启新线程的能力
并发队列(Concurrent Dispatch Queue):可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效
串行队列(Serial Dispatch Queue):让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
//串行队列的创建方法
dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL);
//并发队列的创建方法
dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);
gcd其他方法:
栅栏方法: dispatch_barrier_async
GCD的队列组:dispatch_group
//多线程
//多线程技术:
/*
1:pthread
2:nsthread
3:gcd
4:nsoperation
*/
//gcd相关面试
//串行并行:并行,就是几个任务一起完成。串行,就是几个任务一个接着一个完成。
//同步异步:同步执行线程,等待新线程执行完以后,再继续执行当前线程,很少用到。异步执行线程,在执行新线程的同时,继续执行当前线程,常用。
//gcd使用步骤:
//1:创建线程队列
//2:选择执行方式
//3;添加执行任务
//4:任务被执行
//创建串行队列
//serial:串行
dispatch_queue_tserial =dispatch_queue_create("serial",DISPATCH_QUEUE_SERIAL);
//创建并行队列
//concurrent:并行
dispatch_queue_tconcurrent =dispatch_queue_create("concurrent",DISPATCH_QUEUE_CONCURRENT);
//同步串行
dispatch_sync(serial, ^{
for(inti =0; i <10; i++) {
NSLog(@"同步串行执行一:%d",i);
}
});
dispatch_sync(serial, ^{
for(inti =0; i <10; i++) {
NSLog(@"同步串行执行二:%d",i);
}
});
**********************************************************************
面试笔记4:
1 .runloop
使用场景:
NSTimer , performSelecter , UIEvent ,UIView动画, Transition动画
dispatch_get_mian_queue() ,dispatch_background
AF ,
tableView中runloop实例:
(1)延迟加载图片
uiimage * downloadImage = … ;
[self.imageView performSelector:@selector(setImage:) with object:downloadImage afterDelay:0 inModels:@[NSDefaultRunLoopMode]];
-(void)setImage:(UIImage *)downIamge {
self.imageView.image =downIamge;
}
解释:设置image操作方法放在runloop的NSDefaultRunLoopMode模式下,当操作UITableView滚动时,设置Image暂时休眠,等待DidEndScroll被唤醒.
同理,如果是耗时操作都是同样的思路.
(2) NSTimer
runtime
(1)iOS runtime实战应用:成员变量和属性
http://www.jianshu.com/p/d361f169423b
(2)[iOS] runtime的使用场景--实战篇
http://www.jianshu.com/p/07b6c4a40a90
描述一个你遇到过的retain cycle例子。(别撒谎,你肯定遇到过)
答:比如说block里引用self的属性
+(void)load; +(void)initialize;有什么用处?
答:比如说runtime的method swizzling方法调换功能可以写在load类方法中(一定会调用),initialize在该类被使用时才被调用.
为什么其他语言里叫函数调用,objective c里则是给对象发消息(或者谈下对runtime的理解)
这题考查的是objective c这门语言的dynamic特性,需要对比c++这类传统静态方法调用才能理解。最好能说出一个对象收到message之后的完整的流程是如何的。对runtime有完整理解的候选人还能说出oc的对象模型。
什么是method swizzling?
答:动态交换方法。
UIView和CALayer是啥关系?
能答出UIView是CALayer的delegate就及格了,能说出UIView主要处理事件,CALayer负责绘制就更好,再聊下二者在使用过程中对动画流畅性影响的注意点就superb。UI流畅性是个大话题,推荐看下这两篇文章。中餐,西餐。
如何高性能的给UIImageView加个圆角?(不准说layer.cornerRadius!)
https://github.com/panghaijiao/HJCornerRadius
这题讨论的最多,还有说美工切图就搞定的。答主在项目里做过圆角头像的处理,里面的坑还真不少。cornerRadius会导致offscreen drawing有性能问题,美工切图无法适用有背景图的场景,即使加上shouldRasterize也有cache实效问题。正确的做法是切换到工作线程利用CoreGraphic API生成一个offscreen UIImage,再切换到main thread赋值给UIImageView。这里还涉及到UIImageView复用,圆角头像cache缓存(不能每次都去绘制),新旧头像替换等等逻辑。还有其他的实现方式,但思路离不开工作线程与主线程切换。
使用drawRect有什么影响?(这个可深可浅,你至少得用过。。)
不少同学都用过drawRect或者看别人用过,但不知道这个api存在的含义。这不仅仅是另一种做UI的方式。drawRect会利用CPU生成offscreen bitmap,从而减轻GPU的绘制压力,用这种方式最UI可以将动画流畅性优化到极致,但缺点是绘制api复杂,offscreen cache增加内存开销。UI动画流畅性的优化主要平衡CPU和GPU的工作压力。推荐一篇文章:西餐
ASIHttpRequest或者SDWebImage里面给UIImageView加载图片的逻辑是什么样的?(把UIImageView放到UITableViewCell里面问更赞)
很多同学没有读源码的习惯,别人的轮子拿来只是用用却不知道真正的营养都在源代码里面。这两个经典的framework代码并不复杂,很值得一读。能对一个UIImageView怎么通过url展示一张图片有完整的理解。涉及到的知识点也非常多,UITableViewCell的复用,memory cache, disk cache,多线程切换,甚至http协议本身都需要有一定的涉及。
麻烦你设计个简单的图片内存缓存器(移除策略是一定要说的)
内存缓存是个通用话题,每个平台都会涉及到。cache算法会影响到整个app的表现。候选人最好能谈下自己都了解哪些cache策略及各自的特点。常见的有FIFO,LRU,LRU-2,2Q等等。由于NSCache的缓存策略不透明,一些app开发者会选择自己做一套cache机制,其实并不难。
讲讲你用Instrument优化动画性能的经历吧(别问我什么是Instrument)
Apple的instrument为开发者提供了各种template去优化app性能和定位问题。很多公司都在赶feature,并没有充足的时间来做优化,导致不少开发者对instrument不怎么熟悉。但这里面其实涵盖了非常完整的计算机基础理论知识体系,memory,disk,network,thread,cpu,gpu等等,顺藤摸瓜去学习,是一笔巨大的知识财富。动画性能只是其中一个template,重点还是理解上面问题当中CPU GPU如何配合工作的知识。
loadView是干嘛用的?
不要就简单的告诉我没用过,至少问下我有什么用。。这里是apple给开发者自己设置custom view的位置。说UI熟悉的一定要知道。
viewWillLayoutSubView你总是知道的。。
controller layout触发的时候,开发者有机会去重新layout自己的各个subview。说UI熟悉的一定要知道。
GCD里面有哪几种Queue?你自己建立过串行queue吗?背后的线程模型是什么样的?
两种queue,串行和并行。main queue是串行,global queue是并行。有些开发者为了在工作线程串行的处理任务会自己建立一个serial queue。背后是苹果维护的线程池,各种queue要用线程都是这个池子里取的。GCD大家都用过,但很多关键的概念不少人都理解的模凌两可。串行,并行,同步,异步是GCD的核心概念。
用过coredata或者sqlite吗?读写是分线程的吗?遇到过死锁没?咋解决的?
没用过sqlite是说不过去的。用过CoreData的肯定有很多血泪史要说。多谢线程模型你肯定做过比较选择。死锁是啥肯定也是要知道的,没遇到过至少能举个简单的例子来说明。单个线程可以死锁(main thread里dispatch_sync到main queue),多个线程直接也可以死锁(A,B线程互相持有对方需要的资源且互相等待)。
http的post和get啥区别?(区别挺多的,麻烦多说点)
这个可以说很多。不希望听到的答案有
两个差不多,随便用一个。
post比get安全(其实两个都不安全)
能说下两个http格式有什么不同,各自应用的场景就合格了。更多可以阅读下这个答案。
我知道你大学毕业过后就没接触过算法数据结构了,但是请你一定告诉我什么是Binary search tree? search的时间复杂度是多少?我很想知道!
很多人都很排斥数据结构和算法题,我个人意见是复杂的可以不知道,基础的一定要了解。时间复杂度是什么得知道,list,queue,stack,table,tree这些都要明白是啥。连hash表的概念都不知道怎么能保证在写代码的时候注意性能呢。
如何自己高效实现NSUserDefault?
NSUserDefaults *mySettingData = [NSUserDefaults standardUserDefaults];
创建NSUserDefaults对象之后即可往里面添加数据,它支持的数据类型有NSString、NSNumber、NSDate、NSArray、NSDictionary、BOOL、NSInteger、NSFloat等系统定义的数据类型,如果要存放自定义的对象(如自定义的类对象),则必须将其转换成NSData存储:
NSArray *arr = [[NSArray alloc] initWithObjects:@"arr1", @"arr2", nil]
[mySettingData setObject:arr forKey:@"arrItem"];
[mySettingData setObject:@"admin" forKey:@"user_name"];
[mySettingData setBOOL:@YES forKey:@"auto_login"];
[mySettingData setInteger:1 forKey:@"count"];
[mySettingData synchronize];//同步到plist文件中
如何用HTTP实现长连接?
如果浏览器或者服务器在其头信息加入了这行代码
Connection:keep-alive
谈下Objective C都有哪些锁机制,你一般用哪个?
http://blog.csdn.net/roger_jin/article/details/45307951
常用:@synchronized代码块
如何终止正在运行的工作线程?
NSthread 有 cancel方法
NSOperation:队列的取消,暂停和恢复
(1)取消队列的所有操作
- (void)cancelAllOperations;
提⽰:也可以调用NSOperation的- (void)cancel⽅法取消单个操作
(2)暂停和恢复队列
- (void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列
- (BOOL)isSuspended; //当前状态
(3)暂停和恢复的适用场合:在tableview界面,开线程下载远程的网络界面,对UI会有影响,使用户体验变差。那么这种情况,就可以设置在用户操作UI(如滚动屏幕)的时候,暂停队列(不是取消队列),停止滚动的时候,恢复队列。
列举iOS下的几种本地持久化方案
plist文件(属性列表)
preference(偏好设置)
NSKeyedArchiver(归档)
SQLite 3
CoreData
Realm