iOS-面试题面试iOS精品文章-面试

iOS笔记-常见概念(二)

2016-10-30  本文已影响172人  树懒啊树懒

1、熟悉sql基本语法,和数据库使用

sqlite3 ,core data ,realm

2、数据结构和算法基础,熟悉各种基本算法


 不错的算法总结 :  十道海量数据处理面试题与十个方法大总结 - 结构之法 算法之道

教你如何迅速秒杀掉:99%的海量数据处理面试题

http://www.oschina.net/question/54100_28818

http://www.yangshebing.com/blog/2016/04/24/iosmian-shi-ti-xi-lie-zhi-chang-jian-suan-fa/

http://www.wtoutiao.com/p/df0EUr.html

3、熟悉html +CSS + JS 开发 , 跨平台开发

4、上传图片 :熟悉图片处理和编辑功能 ,大量用户推送原理。

coreImage系统图片处理:http://blog.csdn.net/lvmaker/article/details/38385823

OpenGL 的使用?

5、熟悉微信公众平台,微信小程序开发

6、熟悉http、https 、socket 等协议,蓝牙功能实现等等

socket : http://www.jianshu.com/p/9b589c880353

AsyncSocket 库 :  http://www.jianshu.com/search?q=asyncsocket+&page=1&type=notes 

7、单元测试、自动化测试

http://www.jianshu.com/p/8bbec078cabe

8、系统架构(高并发访问服务),后台服务设置原理要点,web前段,移动APP需要注意的?

移动APP : 多线程处理 + 数据缓存 

后台: SDN数据分发,重定向 等等:

http://mp.weixin.qq.com/s?__biz=MzA3MzYwNjQ3NA==&mid=401628413&idx=1&sn=91abfbad4c7dc882e94939042a8785a4&scene=23&srcid=121664TU0fDpPeR324qis7yL#rd

9、百度地图SDK , 微信支付SDK , 支付宝支付SDK 使用和常见问题?

10、MVC 和MVVM + RAC

http://www.jianshu.com/p/d56cb11ebc84

iOS MVVM+RAC 再不学你就OUT了 - 简书

MVVM : 

View绑定到ViewModel , ViewModel绑定到Model , Model 通知更新 View .

特点 : 解决 MVC 厚重的ViewController、遗失的网络逻辑(没有属于它的位置)、较差的可测试性等因此也就会有维护性较强、耦合性很低

11、生命周期的问题:UIview 、 VC、APP 启动到结束 等等

(1) : iOS应用程序生命周期(前后台切换,应用的各种状态)

状态如下: http://blog.csdn.net/totogo2010/article/details/8048652/

Not running  未运行  程序没启动

Inactive          未激活        程序在前台运行,不过没有接收到事件。在没有事件处理情况下程序通常停留在这个状态

Active             激活           程序在前台运行而且接收到了事件。这也是前台的一个正常的模式

Backgroud     后台           程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended)。有的程序经过特殊的请求后可以长期处于Backgroud状态

Suspended    挂起           程序在后台不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存

(2) 控制器生命周期

[学习笔记]_ios控制器的生命周期、各个方法的调用顺序及所做的操作 - 简书

1)、init函数(init;initWithFrame;initWithCoder;等)--初始化

2)、awakeFromNib--在loadView之前的工作放在这里

3)、viewDidLoad--注意,一个ViewController一个生命周期内这个函数只会调用一次

4)、viewWillAppear--view将要出现,每次View消失再出现都会调用

5)、viewWillLayoutSubviews--简要对子试图进行布局

6)、viewDidLayoutSubivews--完成对子试图布局

7)、viewDidAppear--视图将要出现在屏幕上

---上述代码不含部分

8)、viewWillDisappear--View将要消失

9)viewDidDisappear--View已经消失

(3)线程的生命周期

线程的生命周期 - - 博客频道 - CSDN.NET

新建(new Thread)、就绪(runnable)、运行(running)、死亡(dead)、堵塞(blocked)

12、缓存,内存,沙河,硬盘 等等的理解

先了解基本的计算机知识,看看百度的缓存介绍 :   缓存_百度百科

内存缓存:

http://blog.csdn.net/zhuqilin0/article/details/6647123

设计一个移动应用的本地缓存机制:

http://blog.csdn.net/zhuqilin0/article/details/6653532

13、对一些第三方库原理理解:比如SDWebImage  ,AFNetWork ,等等

SDWebImage : 

SDWebImage源码解析(一) - 简书 二 和 三

SDWebImage-源码分析与仿写(五)

PINCache-源码分析与仿写(四) [内存缓存, 磁盘缓存 的处理]

http://www.jianshu.com/search?q=SDWebImage&page=1&type=notes 

http://www.jianshu.com/p/2b79b520d61c

SDWebImage是一个开源的第三方库,它提供了UIImageView的一个分类,以支持从远程服务器下载并缓存图片的功能。它具有以下功能:

>>提供UIImageView的一个分类,以支持网络图片的加载与缓存管理

>>一个异步的图片加载器

>>一个异步的内存+磁盘图片缓存,并具有自动缓存过期处理功能

>>支持GIF图片

>>支持WebP图片

>>后台图片解压缩处理

>>确保同一个URL的图片不被下载多次

>>确保虚假的URL不会被反复加载

>>确保下载及缓存时,主线程不被阻塞

>>优良的性能

>>使用GCD和ARC

>>支持Arm64

14、对项目健全性能的保障和测试:性能、内存weak、UnitTest,AutoTest 、UITest 等等

(1)UnitTest 单元测试  分为3种:

>>逻辑测试:测试逻辑方法. iOS 单元测试--逻辑测试 - 简书

>>异步测试:测试耗时方法(用来测试包含多线程的方法): 

iOS 单元测试--异步测试 - 简书

简单iOS单元测试-异步测试(XCTestExpectation) - 简书

分析:

1.该测试中,创建了一个XCTestExpectation对象,名为expect

2.通过GCD在全局队列中开始一个异步动作,并添加超时监听:

[expectation fulfill];

3.通过waitForExpectationsWithTimeout:handler:做了两件事

设置异步测试的时间长度,当超过时间时,报测试错误,并打印预设的超时错误信息

超时发生时执行block中的方法

>>性能测试:测试某一方法运行所消耗的时间 iOS 单元测试--性能测试 - 简书

( 2 ) UI 自动化测试 :

iOS 自动化测试 UI Automation - 简书 【xcode 8 找不到 Automation ?】

15、对数据存储深入了解,常用的数据库框架和问题解决方案,比如realm 和 core data 对比,各种坑。。

16、混编开发:oc & c & c++  和 oc 混编 swift  常见设置和使用要点,注意要点?

> 1 : swift 中 桥接 oc  :OC和Swift的桥接

创建swift工程 -> 新建oc文件,提示是否创建桥接头Handle-Bridging-Header.h文件,点击是 ->添加oc的.h文件到桥接头文件中 -> 在oc文件用oc语法编写方法 -> 然后直接在swift 文件中用swif方法直接调用oc方法名,会自动转换,不需要管.

>2 : oc 中 桥接 swift :在oc项目中添加swift文件,并设置oc-swift混编 - 简书

步骤 : 新建一个swift文件 -> 提示是否创建桥接头TestProject-Bridging-Header.h文件,点击是 ->添加oc的.h文件到桥接头文件中,这样新增的swift文件中就可以调用这些oc文件了 -> 然后在oc的.m文件中,导入#import"TestProject-Swift.h" (系统已经关联好的), -> 最后可以在oc中任意调用所有的swift文件,不需要导入操作(也没有.h可以导入).

17、代码版本管理 : 持续集成工具

例如 CruiseControL,hudson ,jenkins,还有apache的Continuum 等 开源的持续集成工具

jenkins 配置 : http://www.jianshu.com/p/8d4452c6f17e

18, 项目中什么情况下经常使用的多线程?

iOS中的多线程一般使用场景

>1 :延迟操作 dispatch_after

>2 :只执行一次,如单例模式中 : dispatch_once(&onceToken,^{} 

>3 :管理任务队列中的任务

dispatch_group_t group = dispatch_group_create();

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_async(group, queue, ^{});

>4 :下载图片 和 大文件  :多线程 和 background 模式下载

NSURLSession的常规使用:

```NSURLSession:

{

NSURLSessionTask(抽象类)NSURLSessionDataTaskNSURLSessionUploadTaskNSURLSessionDownloadTask

}

请求代理:

NSURLSessionDataDelegate

断点下载:

NSURLSessionDownloadTask 方法返回 resumeData,用来记录下载位置

session的配置信息:

NSURLSessionConfiguration

{

(NSURLSessionConfiguration *)defaultSessionConfiguration;默认的配置会将缓存存储在磁盘上

(NSURLSessionConfiguration *)ephemeralSessionConfiguration;瞬时会话模式不会创建持久性存储的缓存

(NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier后台会话模式允许程序在后台进行上传下载工作

config.timeoutIntervalForRequest  超时时间

timeoutIntervalForRequest = 10;// 是否允许使用蜂窝网络(后台传输不适用)

}```

>5 :线程的通信

[queue addOperationWithBlock:^{ // 异步下载图片}

// 回到主线程,显示图片

// [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];

// dispatch_async(dispatch_get_main_queue(), ^{

>6 : 设置依赖

[operationB addDependency:operationA];

[operationC addDependency:operationB];

// 添加操作到队列中(自动异步执行任务)

[queue addOperation:operationC];

[queue addOperation:operationA];

[queue addOperation:operationB];

通过GCD中的dispatch_barrier_(a)sync加强对sync中所谓等待的理解 (有时候比队列组更好用,SDWebImage也使用到)

>7 :优化app性能的需求

// A :设置最大并发(最多同时并发执行3个任务) : queue.maxConcurrentOperationCount = 3;

// B: -(void)didReceiveMemoryWarning 里面[queue cancelAllOperations]; // 取消队列中的所有任务

>8  通过Runtime机制检测子线程操作UI

moshuqi.github.io/ios/2016/05/02/iOS通过runtime机制检测子线程操作UI.html

存在滥用子线程的问题,很多没有必要的地方都新开了线程去做处理操作,导致操作完的回调UI处理也可能是在子线程中,导致了各种隐蔽的坑问题。因为我们绝大多数的UI操作对象都为UIView或其子类,所以方法的替换针对UIView进行。

load 方法的实现

18.2 iOS多线程---锁-并行开发解决 [一般不是必要时不轻易加锁]

http://www.jianshu.com/p/ad2a0f53eb8d

多线程操作过程中往往多个线程是并发执行的,同一个资源可能被多个线程同时访问,造成资源抢夺,这个过程中如果没有锁机制往往会造成重大问题。

(1)NSLock同步锁

```[_lock lock];//加锁

[_imageNames removeObject:name];

[_lock unlock];//使用完解锁```

(2)@synchronized代码块 (常用,简单)

```@synchronized(self){

[_imageNames removeObject:name];

}```

(3)GCD中信号量机制:信号量是dispatch_semaphore_t类型

```dispatch_semaphore_t _semaphore;//定义一个信号量

/*初始化信号量参数是信号量初始值*/

_semaphore=dispatch_semaphore_create(1);```

执行代码:

```//信号等待第二个参数:等待时间

dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);

[_imageNames removeObject:name];

dispatch_semaphore_signal(_semaphore);//信号通知```

(4) NSCondition来控制线程通信(同前面GCD的信号机制类似)

(5) NSRecursiveLock :递归锁,有时候“加锁代码”中存在递归调用,递归开始前加锁,递归调用开始后会重复执行此方法以至于反复执行加锁代码最终造成死锁,这个时候可以使用递归锁来解决。使用递归锁可以在一个线程中反复获取锁而不造成死锁,这个过程中会记录获取锁和释放锁的次数,只有最后两者平衡锁才被最终释放。

(6) NSDistributedLock:分布锁,它本身是一个互斥锁,基于文件方式实现锁机制,可以跨进程访问。

(7) pthread_mutex_t:同步锁,基于C语言的同步锁机制,使用方法与其他同步锁机制类似。

(8)使用atomic(原子性)一定是线程安全的吗?

atomic原子操作,系统会为setter方法加锁,并不能保证绝对的线程安全,还需要使用更高级的方式来处理,比如@syncronized等

19 , ios runtime 的理解 ?

yulingtianxia.com/blog/2014/11/05/objective-c-runtime/

当某个对象使用语法[receiver message]来调用某个方法时,其实[receiver message]被编译器转化为:

idobjc_msgSend (idself, SEL op, ... );

也就是说,我们平时编写的oc代码,方法调用的本质,就是在编译阶段,编译器转化为向对象发送消息。

Runtime的几个小例子 - 简书

>获取person类的所有变量;

>2.获取person类的所有方法;

>3.改变person类的私有变量name的值;

>4.为person的category类增加一个新属性;

>5.为person类添加一个方法;

>6.交换person类的2个方法的功能;

20 , ios 消息机制的理解?

>1 消息队列 : http://blog.csdn.net/topurce/article/details/7344360 :

intmain(){

 while(要求退出){

响应各种消息

}

return0;

}

这就是我们消息队列的原型,系统的启动的时候创建一个线程,然后等待该线程结束,在等待的过程中响应各种消息,如鼠标,键盘等。 这里所创建的线程就是程序的主线程,它自动的创建一个消息队列,然后等待它完成。这里的消息队列就是RunLoop, 我们查阅Foundation会发现有两个相关的对象NSRunLoop和CFRunLoop, 其实这两个东西是一样的,NSRunLoop主要是用于Objective-C程序,而CFRunLoop主要用于C/C++程序,这是因为C/C++程序无法使用objective-c对象而创建的一个类。

 >2  设计模式消息机制 :  iOS学习笔记(三) 消息机制 - 简书

>3 .iOS  runtime消息机制 :

http://www.cnblogs.com/zhaoyunboy/p/objc_msgsend-and-msg-forwarding.html

>4 .iOS  runtime消息转发机制 :

iOS消息转发机制详解 - 简书

深入理解Object-C消息转发机制  待学习?

总结:

在一个函数找不到时,OC提供了三种方式去补救:

1、调用resolveInstanceMethod给个机会让类添加这个实现这个函数

2、调用forwardingTargetForSelector让别的对象去执行这个函数

3、调用forwardInvocation(函数执行器)灵活的将目标函数以其他形式执行。

如果都不中,调用doesNotRecognizeSelector抛出异常

21 , KVO 实现原理

iOS--KVO的实现原理与具体应用 - 简书

KVO机制 : 

>>1 动态创建一个对象A当前类的子类NSKVONotifying_A. 对象的isa 实际上 是指向这个新子类了.

>>2 为这个新的子类重写了被观察属性keyPath的setter 方法。setter 方法随后负责通知观察对象属性的改变状况。

>>3 isa指针的作用:每个对象都有isa 指针,指向该对象的类,它告诉 Runtime 系统这个对象的类是什么。所以对象注册为观察者时,isa指针指向新子类,那么这个被观察的对象就神奇地变成新子类的对象(或实例)了。) 因而在该对象上对 setter 的调用就会调用已重写的 setter,从而激活键值通知机制。

>>4 .执行方法顺序:

-(void)setName:(NSString*)newName{

[selfwillChangeValueForKey:@"name"];//KVO在调用存取方法之前总调用

[supersetValue:newName forKey:@"name"];//调用父类的存取方法didChangeValueForKey

[selfdidChangeValueForKey:@"name"];//KVO在调用存取方法之后总调用

}

>>5 .KVO 实现的监听成功的必要条件

如果赋值没有通过setter方法或者KVC,而是直接修改属性对应的成员变量,例如:仅调用_name = @"newName",这时是不会触发kvo机制,更加不会调用回调方法的。

所以使用KVO机制的前提是遵循 KVO 的属性设置方式来变更属性值。

>>6 .手动实现需要的API

21、KVO 手动实现

如何自己动手实现 KVO

(1)PG_addObserver:forKey:withBlock: 方法:

1>检查对象的类有没有相应的 setter 方法。如果没有抛出异常;

2>检查对象 isa 指向的类是不是一个 KVO 类。如果不是,新建一个继承原来类的子类,并把 isa 指向这个新建的子类;

3>检查对象的 KVO 类重写过没有这个 setter 方法。如果没有,添加重写的 setter 方法;

4>添加这个观察者

demo 下载 :GitHub - okcomp/ImplementKVO: Implement KVO

22 , KVC与KVO 和 Notification 之间区别?

KVC(键值编码) : 一个非正式的Protocol,使用字符串(键)访问一个对象实例变量的机制。而不是通过调用Setter、Getter方法等显式的存取方式去访问。

KVO(键值监听) : 一对多 , 类与类之间 ,发送通知,无返回值 , 实例无观察者不工作 , 它提供一种机制,当指定的对象的属性被修改后,对象就会接受到通知,前提是执行了setter方法、或者使用了KVC赋值。

Notification(通知) : 一对多 , 类与类之间 ,发送通知,无返回值 , 实例无观察者要工作 , 监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,例如键盘、前后台等系统通知的使用也更显灵活方便。iOS 趣谈设计模式Notification.

delegate (代理) : 一对一(一般),类与类之间 ,对象通过变量(代理) ,实例无观察者要工作 ,

23 ,  block 的本质 和 实现原理

block使用:   一篇文章看懂iOS代码块Block - 简书

block使用比如BlockKit 和 Masonry 封装使用可以学习一下。

循环引用解析weak ,strong 及 __block修饰原理:     深入分析 Objective-C block、weakself、strongself 实现原理 - 简书

block的原理 :  Block源码解析和深入理解 - 简书

24 , ARC - MRC 下怎么管理内存的?

>> MRC :  

 iOS笔记:内存管理

 1.你拥有你创建的对象:也就是说创建的对象(使用alloc,new,copy或者mutalbeCopy等方法)的初始引用计数是1。

2.给对象发送retain消息后,你拥有了这个对象

3.当你不需要使用该对象时,发送release或者autorelease消息放弃这个对象

4.不要对你不拥有的对象发送“放弃”的消息

5.设置为ARC环境  : -fobjc-arc

>> ARC :

iOS开发ARC内存管理技术要点 - 不忘初“辛” - 博客园

iOS内存管理: ARC MRC 引用计数器 autorelease - 简书

iOS arc 内存管理 - 简书

1.不可以再显示调用dealloc、或实现调用retain、release、retainCount、autorelease这些方法。也不能使用@selector(retain), @selector(release),等等。

当自动释放池被销毁时,会对池子里的所有对象做一次release,如果手动retaincount 加1的话,会导致释放失败.

对于太耗性能的方法,不用的情况下,最好能手动释放.手动添加 @autoreleasepool {  };

2.设置非ARC文件 : -fno-objc-arc

3.ARC 中内存泄漏: 

[ A import B, 同时 B import A ] - 

[ deleget 设置了strong ,应该是assign ] - 

[ block 里直接用了self及其属性,应该weak ] -

 [ 动画animation 设置HUGE_VALL 一直重复,应该viewWillDisappear中 removeAllAnimations] 

 [   ]

25 , 来电话时 如何保存需要的数据? 

来电:

后台模式1:   IOS的后台任务-四种常见模式

26 、 NSTimer的使用

IOS中关于NSTimer使用知多少 - 集结号 - 博客频道 - CSDN.NET

简单注意比如滚动时定时器暂停的问题,熟悉runloop。

27 、 oc 和 swift 的区别?

Swift新特性介绍(一) 语言基础中的新特性

28、IOS 野指针的产生及危害 及空指针说明_harry_water_新浪博客

29、如何增强iOS应用程序的性能。

初级

1、使用ARC进行内存管理、2.在适当的情况下使用reuseIdentifier

3.尽可能将View设置为不透明(Opaque)4.避免臃肿的XIBs 5.不要阻塞主线程6.让图片的大小跟UIImageView一样7.选择正确的集合8.使用GZIP压缩

中级:

9.重用和延迟加载View 10.缓存、缓存、缓存11.考虑绘制12.处理内存警告13.重用花销很大的对象14.使用Sprite

Sheets 15.避免重新处理数据16.选择正确的数据格式17.设置适当的背景图片18.降低Web内容的影响19.设置阴影路径20.优化TableView 21.选择正确的数据存储方式

高级

22.加速启动时间23.使用Autorelease

Pool 24.缓存图片—或者不缓存25.尽量避免Date格式化

30、队列和栈有什么区别?堆和栈的区别?

栈(Stack):是限定只能在表的一端进行插入和删除操作的线性表

队列(Queue)是限定只能在表的一段进行插入和在另一端进行删除操作的的线性表

1)、队列是先进先出,栈是先进后出

2)、遍历数据速度不同,队列遍历速度要快得多

堆和栈的区别?

栈完全是由系统管理的,堆是由程序员自己控制管理的,包括内存空间的开辟和释放.栈是先进后出.并且是连续的内存地址。堆是充分利用零散的内存地址,

31、常用git命令?如何解决代码冲突的?

32、iOS10新特性

iOS10新特性(What's New in iOS) - 简书

苹果官方文档:

iOS10新增框架 :  iOS 9.3 to iOS 10.0 API Differences

iOS10功能简介 :  iOS 10.0

callKit 电话框架 :iOS10新特性之CallKit开发详解:锁屏接听和来电识别-爱编程

33、 UITableViewCell的重用机制:

关于UITableViewCell重用机制的理解 - 简书

(UITableViewCell)dequeueReusableCellWithIdentifier:(NSString)identifier这个方法中,他的基本意思就是在创建cell的时候为每一个cell都绑定一个identifier的标识。当cell从我们的视觉范围中消失的时候,这个绑定了cell的标识就会被放到缓存池中。当tableView需要新的cell的时候,直接先去缓存池中寻找有没有携带identifier的cell,若有的话直接复用;没有的话,才去创建新的cell,并绑定标识identifier。所以从理论上讲,倘若一屏最多显示的cell个数为n个,那么需要携带identifier表示的cell最少只需n+1个。

当然在某些情况下,我们不需要复用cell,因为cell的复用在当cell的个数比较少的情况下,对于性能的提升几乎没有作用,反而有可能会造成数据的错乱,这时候我们不想再使用cell的重用机制,这时候该怎么办呢?可以利用以下几种方式来解决:

UITableViewCellcell = [tableView cellForRowAtIndexPath:indexPath]; //根据indexPath准确地取出一行,而不是从cell重用队列中取出

if (cell == nil) {

cell = [[UITableViewCellalloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier];

}

34、ios webrtc 音视频通话

上一篇下一篇

猜你喜欢

热点阅读