资讯详情

看完这篇iOS面试题,一天3offer!!!

前言

不积小步,千里之外,不积小流,不成江海。学习就像逆水行舟,不进则退。我是一个在各种平台上游荡的搬运工。今天我给大家讲解很多关于面试题的知识点。如果你坚持看一点,读完就会有收获。即使你知道,你也会复习一遍,因此你会知道新的。废话不多说,希望对你有帮助。优秀的人赞不绝口

一C语言相关面试题

1.static用途是什么?

答:在C语言中,static主要定义全局静态变量、局部静态变量和静态函数。 static 它属于静态变量,用它修改的变量生命周期是整个源程序。 @1.在函数体内 static 变量的作用范围是函数体,该变量的内存只分配一次,因此其值在下次调用时仍保持上次值; @2.在模块中 static 全局变量可以被模块内所有函数访问,但不能被模块外其它函数访问; @3.在模块中 static 该函数仅被该模块中的其他函数调用,该函数的使用范围仅限于声明其模块;

2.说说冒泡排序的原理?

答:1.两两比较,质量大下沉,质量小上升; 2.外层循环用于控制排序次数,n个数需要n-1次; 3.内循环用于两两比较,每次找到最大沉到底部;

for(i=1; i<n; i  )  {     for(j=0; j<n-i; j  ){         if(ary[j] > ary[j 1]){             temp = ary[j];             ary[j] = ary[j 1];             ary[j 1] = temp;         }     }  }   

3.说说选择排序的原理?

答:1.每次获取一个关键字与其背后的数字逐一比较,找出最小数字与关键字交换; 2.外循环用于获取关键字,并控制循环次数(n个数需要n-1次); 3.内层循环用于将关键字与后面的数一一比较,找出与关键字交换的最小数;

        for(i=0; i<n-1; i  ){         for(j=i 1; j<n; j  ){             if(ary[i] > ary[j]){-->这里ary[i]就是关键字                 temp = ary[i];                 ary[i] = ary[j];                 ary[j] = temp;             }         }         }    

第一次选择排序:从n个数中找出最小数,与第一个数(即关键字)交换,最小数放在第一个元素位置; 第二次选择排序:从n-1个数中找出次小数,与第二个数(即关键字)交换,结果次小数放在第二个元素位置; 重复上述过程,共经过n-排次排序后,排序结束。

4.说说二分搜索的原则和先决条件?

答:1.先决条件:必须是一维顺序数组; 2.原理:取中,比较; 3.设置最小索引和最大索引,设置一个while循环语句的条件是最小索引<最大索引,首先判断要搜索的值等于这两个索引对应的值,等于搜索成功。这并不意味着重新定义一个中间索引,判断要找到的值等于中间索引对应的值,等于找到成功。这并不意味着判断要找到的值是否小于中间索引对应的值。如果小于,将中间索引减少到最大索引,否则将中间索引增加到最小索引。

设置数组r最小索引low,最大索引high,求数组中间索引mid=(low high)/2; //设置数组的最大和最小索引,求数组中间索引 若r[mid]==k,查找成功; //若中间索引的值等于要查找的数,则查找成功 若r[mid]>k,设置high=mid-1.继续搜索二分; //如果中间索引的值大于要找到的数量,则将最大索引设置为中间索引减1,并继续进行二分搜索 若r[mid]<k,设置low=mid 1.继续搜索二分。 //如果中间索引值小于要找到的数量,将最小索引设置为中间索引加1,并继续进行二分搜索

5.说说你对C语言指针的理解?

答:1.指针是C语言中广泛使用的数据类型的内存地址。使用指针编程是C语言的主要风格之一。 2.C语言允许用一个变量存储指针,称为指针变量。指针变量可以用来表示各种数据结构;数组和字符串可以很容易地使用;从而编制出精致高效的程序。

6.C如何实现语言中的顺序链表?

答:定义几个结构,每个结构包含两个成员,一个塑料变量,一个指针变量。让一个结构中的指针变量指向另一个结构的地址,而另一个结构中的指针变量指向另一个结构的地址。从而形成一个顺序链表。

7.C如何实现语言中的循环链表?

答:定义几个结构,每个结构包含两个成员,一个塑料变量,一个指针变量。让一个结构中的指针变量指向另一个结构的地址,而另一个结构中的指针变量指向另一个结构的地址。然后让最后一个结构中的指针变量指向开始结构的地址,从而形成一个循环链表。

8.说说你对C语言二叉树的理解?

答:在计算机科学中,二叉树是每个节点最多有两棵子树的树结构。子树通常被称为左子树(left subtree)和右子树和右子树(right subtree)。二叉树常用于实现二叉找树和二叉堆。

9.C语言里typedef与define有什么区别?

答案:#define 它是在预编译过程中处理的,只能用简单的字符串代替。 typedef 它是在编译过程中处理的,它给现有类型起别名。

10.写标准宏MIN,宏输入两个参数并返回较小的一个?

答案:#define MIN(X,Y) ((X)>(Y)?(Y):(X)) define只有纯替换功能,所以X,Y都需要加括号来防止括号X,Y表达式的情况

三目条件运算符,语法格式;x?y:z; 其中x为bool类型表达式,先计算x值,如果是true结果是表达式y的值,否则结果是表达式z的值。

二.6个内存管理面试题

1.说说你对内存管理的理解?

答:1.在非ARC在这种情况下,谁创建谁释放,当对象进行时alloc,new,retain,copy需要调用时间release或autorelease释放。当引用计数为0时,会调用dealloc销毁当前对象的方法。 2.在ARC在任何强指针的情况下,(label,retain)指向对象将被销毁;任何弱指针(assign)指向对象不会被销毁;默认情况下,对象为强指针类型。 3.自动释放池是OC内存自动回收机制可通过自动释放池回收和统一释放一些临时变量;内存池autoreleasepool用于管理被声明的人autorelease对象,系统中有成千上万的内存池,当系统内存不足时,系统会从栈中取出顶层的池子,释放引用计数为0的对象,当前应用程序使用回收内存。 当自动释放池本身被销毁时,池中的所有对象都会一次完成release操作。 在使用block一定要注意不要在block内部直接对象操作,但如果使用__block或__weak修改,避免循环引用,造成内存泄漏。

2.ARC环境中有内存泄漏吗?如有,请举例说明。

答案:是的。例如:两个用途label相互引用或修改的对象 在控制器中循环引用会导致内存泄漏。

3.说说深拷贝和浅拷贝的区别?

答:浅拷贝是指只复制对象的指针,而不复制对象属性的地址。 深度复制是指即将复制对象的指针也属性的地址。

4.什么是自动释放池?它的底层是如何实现的?

答:1.自动释放池是OC内存自动回收机制。当对象调用时autorelease当物体被放入自动释放池时。当自动释放池被回收时,它将从堆栈中删除,池中的所有物体将被一次完成release操作。

答案:自动释放池是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来回收统一释放; 内存池autoreleasepool是用于管理那些被声明为autorelease的对象,系统中有成千上万个内存池,系统内存不足时,系统会从栈中取最顶层的池子把引用计数为0的对象释放掉,收回的内存給当前应用程序使用。 自动释放池本身销毁的时候,池子里面所有的对象都会做一次release操作。

5.程序出现内存泄漏,该如何解决?

答案: 1.单步断点调试,找出内存泄漏的地方, 2.使用全局断点,定程序闪退的地方,找出内存泄漏的原因 3.使用僵尸变量,根据打印日志,然后分析原因,找出内存泄漏的地方 4.分段调试,找出内存泄漏的地方 5.使用Instrument当中的Leak检测工具

6.实际开发中,如何对内存进行优化呢?

答案:1.用ARC管理内存,它能保证释放掉不再需要的对象内存 2.尽量把VIew设置成透明 3.避免反复处理数据 4.优化tableVIew 5.当对视图控制器进行pop或dismiss操作的时候,把该视图控制器的视图对象等于nil或者直接remove掉。 6.在使用block的时候,一定要注意不能在block里面直接对对象进行操作,而是要是要使用__block或__weak进行修饰,避免循环引用,造成内存泄漏。 7. 使用Instrument当中的Leak检测工具 8. 使用Autorelease Pool

三.Objective-C语言相关面试题16个

1.描述一下你对OC堆和栈的理解?

答案:堆由开发人员控制,比如:alloc的对象,要手工释放或交由系统释放; 栈是由编译器自动管理,无需我们手动控制。

2.什么是单例呢?

答案:单例模式的意思就是只有一个实例对象。而且自行实例化并向整个系统提供这个实例。

答案:单例就是使得一个类的对象成为系统中唯一的实例对象,需要用static创建这个全局对象。

3.ARC环境下创建单例有哪两种方式,请举例说明?

答案:1.创建一个全局静态实例并设置成nil;实现一个实例构造方法并进行同步处理,再判断上面声明的静态实例是否为nil,如果是则新建并返回这个实例对象; 2.使用GCD线程中的只执行一次的方法来创建单例。

4.MRC下怎么创建单例模式呢?

答案:必须重写allocWithZone,copyWithZone,release和autorelease方法,用来保证其他人直接使用alloc和init试图获得一个新实例时不产生新实例。

5.说下KVC与KVO的区别?

答案:1.KVC是键值编码,即通过字符串的名字(key)来访问类属性。而不是通过调用Setter、Getter方法来访问。即使这个属性它没有Set和Get方法,我们也能访问;注意:当这个属性有Set方法系统会优先调用Set方法,通过KVC设值对象,此对象会被retain。 2.KVO是键值监听,即指定观察的对象属性被修改后,KVO就会自动通知相应的观察者,用完后需要在dealloc方法中移除观察者。如果开启了ARC机制后也可以调用dealloc方法,只不过不能调用[super dealloc],然后在dealloc方法中移除观察者。

6.描述下synthesize与dynamic的作用?

答案:1.@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = _var; 2.@synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。 3.@dynamic告诉编译器,属性的setter与getter方法由用户自己实现,不自动生成。(当然对于readonly的属性只需提供getter即可)。假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。

7.类与类之间的消息传递,有哪几种方式呢?

答案:委托代理delegate,消息通知,KVO键值监听,block块。

8.描述下你对消息通知的理解?

答案:通知(NSNotificationCenter)是一对多的关系,当一个类需要跟多个类进行信息传递的时候,我们一般都是用消息通知, ①通知时同步的,使用时必须先注册并绑定接收通知的方法, ②消息中心创建消息内容,然后发送通知 ③不在监听时调用dealloc方法移除通知对象!

答案:用于通知多个对象某个事件,在对象中实现对象监听及监听的方法;是一对多的模式,只要接收通知都能响应方法。

9.主线程注册通知事件,子线程发通知事件,那响应方法在哪个线程完成呢?

答案:子线程完成,在哪个线程发送通知就在哪个线程响应

10.描述一下你对委托代理的理解,它支持一对多吗?如果支持,如何实现?

答案:委托代理是类与类之间信息传递的一种方式,使用委托代理的时候,必须先声明协议,确认协议并实现协议中声明的方法,添加要委托的对象,最后才能使用, 它支持一对多吗?:可以!即可以把委托delegate改成数组保存多个委托对象,调用时取出每一个委托对象进行信息传递。

答案:委托代理是类与类之间信息传递的一种方式,协议只声明了方法,不具体实现,接受协议的对象负责实现;

11.什么是类别?什么是延展?详细描述一下你的理解。

答案:类别是给已有类添加新的方法且对外界公开,不能添加实例变量; 延展是给类添加私有变量,属性及方法。对外界不公开。

12.详细描述一下你对block的理解,它的作用有哪些呢?

答案:block 是IOS4.0之后新增一种语法结构,也称闭包 SDK4.0,新增的API大量使用了block block类似一个匿名的函数代码块,此代码块可以作为参数传递对象或方法,也可以作为方法的返回值; block可以实现两个类之间的信息传递, 并且block对局部变量是只读的,如果要修改可以加__block进行修饰。 block是获取其他函数局部变量的匿名函数功能是保存代码片段, 预先准备好代码, 并在需要的时候执行. 作用:在两个类之间的信息传递 或者对代码封装作为参数进行传递 或者作为方法的返回值 利用block实现代理委托delegate

13.ARC环境下使用block会产生内存泄漏吗?如果会,该如何解决呢?

答案:当在block里面直接调用局部对象或者当前对象self的属性或方法的时候,局部对像或当前对象,就会block隐性的retain一次,导致相互引用,内存泄漏! 可以加__block,或使用完之后立即释放block,防止内存泄漏 1.使用__block修饰当前对象 2.block使用完后立即释放,即self.block=nil

14.类别和继承有什么区别呢?

答案:类别:是给已有的类添加新的方法,向对象添加非正式协议 ,使原有类的功能更加强大,但是不能添加实例变量! 继承:子类继承父类,子类就拥有了父类的成员、属性及方法,这样可以节省代码量,使程序更加简洁,也可以添加新的属性及方法,使功能更加强大! 成员也可以使用权限控制,@private私有的,@protected受保护的,@public公共的

答案:继承修改的方法不会对父类原方法产生影响; 类别修改的方法相当于替换了原有方法。

15.NSPredicate即谓词逻辑,可以用来做什么呢?

答案:redicate即谓词逻辑,用于从数据堆中根据条件进行筛选,大多用于数组对象的筛选。 (1). 可用于数组中数字对象和字符串对象的比较; (2). 可用于筛选符合条件的数组元素;

16.描述下__block和__weak修饰符的区别?

答案:__block不管在ARC模式下还是MRC模式下,都可以使用,可以修饰对象,还可以修饰修饰基本数据类型 __weak只能在ARC的模式下使用,只能修饰对象,不能修饰基本的数据类型 __block对像可以在block中重新被赋值,__weak不可以

四.UI界面相关9个题

1.什么是MVC模式?什么是MVVM模式?详细说明一下。

答案:MVC模式 Model是数据层;View是用于显示界面;Controller将model和view绑定在一起,也是model和view通信的桥梁。 MVVM框架与传统的MVC框架极为相似,是MVC框架的延伸。 M:即Model层,数据模型,用来定制数据的。 创建的实体类都是放在这个文件夹里; V: 即ViewController层,即视图控制器。 用来显示界面以及与用户交互; 它又可以细分成View层和Controller层,其中View层保存纯视图类,Controller层保存控制器; VM: 即ViewModel层,即业务逻辑层。用来处理ViewController层的业务逻辑和界面逻辑, 比如:网络数据请求, json解析,本地数据存储,用户登录密码校验,图片上传与下载等。说明了,就是把原来的ViewContrller 层的业务逻辑和页面逻辑等剥离出来放到ViewModel层。


2.描述一下UITableView的重用机制?

答案:tableview有个可重用队列,滑出去的会放到可重用队列里面,滑进来的会从可重用队列里面获取,如果没有,会创建一个cell,cell的可重用标示是用static静态变量声明的。

3.如果想让scrollview实现重用,有什么好的思路呢?

答案:可以把UITableView逆时针转90度,tableview里的cell顺时针转90度,使用它们的属性transform来实现。同时修改tableview的frame以及当前的cell的高度,即可实现。

4.视图控制器从创建到销毁分别经历哪些方法呢?

答案:alloc—init—loadview(创建并加载一个属于自己的根视图)—viewdidload(视图加载完成)—viewwillappear(视图将要显示)—viewdidappear(视图已经显示)—viewWillDisapper(视图将要消失)—viewDiddisappear(视图已经消失)—dealloc

5.描述一下事件的响应者链。

答案:当前触发事件--根视图上的子视图--视图控制器上的根视图--视图控制器--窗口--UIApplication对象--丢弃

6.didMoveToSuperView,layoutSubviews,drawRect都在什么时候调用呢?实际编码中用来做什么呢?

答案:didMoveToSuperView:当继承自UIView的子视图被贴到父视图时调用,可以在此方法中设置子视图自身的属性; layoutsubviews:当添加到父视图或自己添加子视图时调用,当修改自己的frame或子视图的frame时也会调用,当自己调用setNeedsLayout方法时也会调用,父视图UIScrollView滚动时或屏幕旋转时也会调用(待求证)。可以在此方法对子视图进行重新布局; drawRect:贴到父视图的时候调用,设置它的contentMode属性值为UIViewContentModeRedraw时,每次更改frame的时候调用,直接调用setNeedsDisplay或者setNeedsDisplayInRect:方法的时候调用。可以在此方法中绘制自己的内容。

7.CALayer和UIView的区别是什么呢?

答案:两者最大的区别是:图层不会直接渲染到屏幕上,UIView是IOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全由CoreAnimation 来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器。一个UIView上可以有n个CALayer,每个layer显示一种东西,增强UIView的展现能力。

8.UIScrollview如何做垂直方向的约束呢?

答案:storyboard里设置scrollview的小技巧: (1).首先托一个scrollview到故事板里(可以全屏也可以任意大小),给scrollview添加左,右,上,下四个约束; (2).然后在scrollview上托一个UIView,大小与scrollview一样大,给UIView添加左,右,上,下,固定高,垂直居中对齐几个约束;(固定高,垂直居中对齐两个约束一定要加,否则滚动失效!!) (3).以后所有的子控件都可以放到这个UIView上显示了;

9.说一下UIScrollerView实现原理。

答案:在滚动过程当中,其实是在修改原点坐标。当手指触摸后, scrollview会暂时拦截触摸事件,使用一个计时器。假如在计时器到点后没有发生手指移动事件,那么 scrollview 发送 tracking events 到被点击的 subview。假如在计时器到点前发生了移动事件,那么 scrollview 取消 tracking 自己发生滚动。

五.多线程相关面试题8个

1.描述一下线程与进程的区别?

答案:1.进程有独立的地址空间,一个进程崩溃后,在其保护模式下不会对其他进程产生影响,而线程只是一个进程中的执行路径。 2.线程有自己的堆栈,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程程序比多线程程序健壮。 3.但在进程切换时耗费资源较大,效率要差一些。对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。

2.你所掌握的多线程有哪些呢?它们的特点是什么?

答案:NSThread:NSThread是轻量级的,需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销; Cocoa operation:Cocoa operation不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。相关的类是NSOperation,NSOpertionQueue.它是一个抽象类,使用时必须用它的子类NSInvocationOpertion.创建子类的对象并把它添加到NSOperationQueue队列里执行。 GCD:是Apple开发的一个多核编程的解决方法,是一个替代诸如NSThread,NSOperationQueue,NSInvocationOperation等高效.强大的技术;GCD本身非常简单,易用,对于不复杂的多线程操作,会节省代码量,而block参数的使用,会使代码更为易读。

3.描述一下线程同步与异步的区别?

答案: 线程同步是指当前有多个线程的话,必须等一个线程执行完了才能执行下一个线程。使用加锁处理。线程异步就不需要等待了,可以同时进行。

答案:线程同步指一个线程要等待上一个线程执行完之后才开始执行下一个线程; 线程异步指一个线程去执行,他的下一个线程不用等待他执行完就开始执行。 同步需要用@synchronized 或加锁解锁处理 异步主要使效率提高 同步线程主要解决线程安全问题,异步主要使效率提高

4.多线程在实际代码中有哪些应用场景呢?

答案: 当我们进行网络请求的时候,网络请求就使用了多线程处理, 当我们进行JSON解析的时候,也使用了多线程进行处理, 当我们进行本地缓存的时候,也会使用多线程进行处理,主线程用于界面刷新,子线程用于数据处理。

5.使用GCD加载多张图片之后,如何把加载的图片融合到一张图片里呢?

答案: 在GCD线程里创建一个组,在组里添加几个异步线程加载图片,这些图片加载完之后就汇总通知,然后调用主线程,在主线程里开启图形上下文,在drawinrect方法中绘制加载的图片,获取合成图片,关闭图形上下文,这就把加载的图片融合到一张图片里了。

6.使用GCD的时候,如何在一个group里添加几个任务的依赖呢?

答案: 1、dispatch_group_async(group, queue, ^{ /* 任务A */ });
 dispatch_group_async(group, queue, ^{ /* 任务B */ });
 dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    dispatch_group_async(group, queue, ^{ /* 任务C */ });
    dispatch_group_async(group, queue, ^{ /* 任务D */ });
});

创建一个组,然后在组里面添加异步线程,有几个任务就添加几次,当这些线程任务执行完之后就汇总结果,然后再调用主线程刷新。

7.多线程共享同一数据,如何防止错乱呢?

答案:方法一:@synchronized(xin ke nai zi)会对参数对象同步处理,保证临界区内的代码线程安全; 方法二:使用NSLock进行加锁处理,等线程执行结束再进行解锁处理。

8.多线程之间如何进行数据传递的?应注意哪些事项。

答案: -(void) perfromSelectOnMainThread: withObject: waitUntilDone: 注意事项: waitUntilDone:是YES的话,子线程结束后会阻塞主线程,然后走要执行的方法 如果是NO的话,就不会阻塞主线程, 或者使用:本地存储的方式,或者使用block,使用block的时候需要用__block修饰 __block, __weak, 子线程里嵌套主线程进行传值; 子线程下载数据后直接丢给主线程刷新; 本地储存; 注意的事项:多线程共享同一数据,要防止错乱。

六.本地存储8个题

1.你所掌握的本地存储有哪些呢,描述下它们各自的特点?

答案:文件写入;归档;NSUserDefauls;FMDatabase(第三方数据库),core data,系统数据库sqlite 特点: 文件写入:只能存储系统的数据类型,永久保存在磁盘中; 归档(NSKeyedArchiver):采用归档的形式保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供2个方法,对象进行编码的方法encodeWithCoder:,对象进行解码的方法initWithCoder:然后创建沙盒,设置归档路径,,使用NSKeyedArchiver序列化进行编码,使用NSKeyedUnarchiver反序列化进行解码。 NSUserDefaults:主要用来保存应用程序的设置和属性,用户再次打开程序或开机后这些数据仍然存在; 数据库FMDB(FMDatabase第三方数据库):FMDB是基于SQLite封装过来的,它能很方便的对数据进行增删改查。 CoreData:是一个模型层的技术,也是一种持久化技术,它能将模型对象的状态持久化到磁盘里,它可以对数据进行增删改查; sqlite:是轻量级的嵌入式数据库,系统中内置了sqlite,它可以对数据进行增删改查;

2.如何对自定义的对象进行本地归档呢?

答案:采用归档的形式保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供2个方法,对象进行编码的方法encodeWithCoder:,对象进行解码的方法initWithCoder:。然后创建沙盒,设置归档路径,使用NSKeyedArchiver序列化进行编码,使用NSKeyedUnarchiver反序列化进行解码。

3.说出数据库中表的创建,以及对表进行增、删、改、查的SQL语句。

答案:创建表:executeUpdate create table 表的名称(表里面数据的类型) 增 :executeUpdate insert into 表的名称(要增加的对象) 删: executeUpdate delete from 表的名称 where 改: executeUpdate update 表的名称 set ……where …… 查: executeQuery select from 表的名称 ,用while循环进行查询。

4.详细描述一下你对CoreData的理解?

答案:CoreData是一个模型层的技术,也是一种持久化技术,它能将模型对象的状态持久化到磁盘里,它可以对数据进行增删改查; 创建工程时,需要勾选CoreData选项,创建模型文件,可以在模型文件里进行添加实体对象; 然后新建一个NSManagedObject cubclass文件; 工程创建完之后,它会在AppDelegate.h里自动生成了3个属性; 然后在需要使用的类里面添加CoreData头文件,再使用它的属性,就可以对数据进行增删改查操作了;

5.详细描述一下你对系统数据库sqlite的理解?

答案: sqlite是轻量级的嵌入式数据库,系统中内置了sqlite,现在的版本是sqilte3; 使用SQLite,只需要加入libsqlite3.0.tbd,以及引入sqlite3.h头文件即可 然后就可以打开数据库, 创建表, 执行SQL语句,进行增删改查等操作 然后关闭数据库

6.如何对自定义的对象进行CoreData保存呢?

答案:①引入CoreData框架 ②创建数据模型文件.xcdatamodel ③初始化NSManagedObjectModel对象,加载数据模型文件,读取app中所有实体信息。 ④初始化NSPersistentStoreCoordinator 对象,添加持久化库 ⑤初始化NSManagedObjectContext对象,拿到上下文对象操作实体。

7.CoreData是用什么筛选数据的?说出查询age字段在18岁到28岁的筛选条件.

答案: 使用NSPredicate逻辑谓词筛选, NSPredicate *predicate = [NSPredicate predicateWithFormat:@“SELF.age BETWEEN {18, 28}”]; 或者 NSPredicate *predicate = [NSPredicate predicateWithFormat:@“SELF.age >= 18 && SELF.age <=28”];

8.ios 10下集成coredata发生了哪些变化呢?

答案:IOS10中,系统默认只生成一个CoreData存储容器; 创建CoreData时,先创建DataModel; 在创建好的数据模型里添加实体; 再创建NSManagedObject cubclass文件,它创建的地方不同, 然后在需要使用的类里面添加CoreData头文件,再使用它的属性,就可以对数据进行增删改查操作了; IOS9之前,数据是存储在Documents 中; ios10,数据库文件存储在Library->Application Support中。

七.网络请求5个题

1.实际开发项目中,经常用到的网络请求有哪些呢?

答案:ASIHTTPRequest、AFNetWorking、NSURLConnection、NSURLSession(功能更强大,更稳定); AFNetWorking2.0和3.0的区别:底层封装不同(3.0底层是封装NSURLSession来实现的); ios9以后,NSURLConnection被弃用;

2.详细描述一下AFNetworking与ASIHttpRequest的区别?

问题: 1.底层实现不同,AFN的底层基于OC的NSURLConnection和NSURLSession;ASI的底层基于纯C语言的CFNetwork框架;ASI的运行性能高于AFN。 2.对服务器返回的数据处理不同,ASI没有直接提供对服务器数据处理的方式,直接返回data\string;AFN提供了多种对服务器数据处理的方式,JSON处理,XML处理 3.监听请求的过程不同 ,AFN只提供了成功和失败两个block来监听请求的过程 ,ASI提供了3套方案,每一套方案都能监听请求的完整过程 4.文件下载和文件上传的使用难易度不同,afn不容易监听下载进度和上传进度,不容易实现断点续传,而且一般只用来下载不大的文件,而asi则相反。 5.ASI提供了更多的实用功能,比如监听文件的上传和下载过程,暂停/恢复/取消所有的网络请求等; 答案:

1.底层实现

(1) AFN的底层基于OC的NSURLConnection和NSURLSession (2) ASI的底层基于纯C语言的CFNetwork框架 (3) ASI的运行性能高于AFN

2.对服务器返回的数据处理

(1) ASI没有直接提供对服务器数据处理的方式,直接返回data\string (2) AFN提供了多种对服务器数据处理的方式 ▪ JSON处理 ▪ XML处理

3.监听请求的过程

(1) AFN提供了success和failure两个block来监听请求的过程(只能监听成功和失败) ▪ success : 请求成功后调用 ▪ failure : 请求失败后调用 (2) ASI提供了3套方案,每一套方案都能监听请求的完整过程 (监听请求开始、接收到响应头信息、接受到具体数据、接受完毕、请求失败) ▪ 成为代理,遵守协议,实现协议中的代理方法 ▪ 成为代理,不遵守协议,自定义代理方法 ▪ 设置block

4.在文件下载和文件上传的使用难易度

(1) AFN ▪ 不容易监听下载进度和上传进度 ▪ 不容易实现断点续传 ▪ 一般只用来下载不大的文件 (2) ASI ▪ 非常容易实现下载和上传 ▪ 非常容易监听下载进度和上传进度 ▪ 非常容易实现断点续传 ▪ 下载或大或小的文件都行

5.ASI提供了更多的实用功能

(1) 控制圈圈要不要在请求过程中转 (2) 可以轻松地设置请求之间的依赖:每一个请求都是一个NSOperation对象 (3) 可以统一管理所有请求(还专门提供了一个叫做ASINetworkQueue来管理所有的请求对象) ▪ 暂停\恢复\取消所有的请求 ▪ 监听整个队列中所有请求的下载进度和上传进度

3.详细描述一下你对get请求与post请求的理解?

答案:get是向服务器发送,索取数据的一种请求,get请求的参数会跟在url后进行传递,请求数据会附在url之后,以?分割url和传输数据,参数之间以&相连;这样的安全性不高,get请求的数据有大小限制,一般不超过255个字节; post是向服务器提交数据的,post请求会把消息放到消息体body里,安全性高且post没有限制提交的数据。

4.实际开发中如何处理多个网络请求的并发呢?

答案:可以使用GCD线程,创建一个组,然后在组里面添加异步线程,有几个任务就添加几次,当这些线程任务执行完之后就汇总结果,然后再调用主线程刷新。

5.实际开发中AFNetworking发送出去的请求,如何主动取消呢?

答案:通过类别来动态管理请求队列,避免VC直接持有请求队列。 通过runtime来自动触发取消请求操作。

八.自动布局4个题

1.如何让一款应用兼容不同的屏幕,有哪几种方案呢?

答案:有2种方式进行适配。 第一种是在实际代码里写一个宏判断当前设备的高度,根据屏幕高度动态调整图片及视图的尺寸; 第二种是使用main.storboard里的属性size class对不同屏幕尺寸进行分类处理,使用autolayout对不同屏幕下的尺寸进行自动布局,包括自动拉伸和自动贴边。 第三种是使用masonry布局框架。

2.实际开发中添加约束时,如果产生了警告和冲突,该如何解决呢?

答案:一种是非运行时的约束冲突,在InterfaceBuilder里面就能看到的,比如同一个高度给了两个约束,这两个约束是无法同时满足的,然后就冲突了,解决办法就是去掉其中的一个约束; 另一种是在运行时的约束冲突,可以通过阅读打印的日志,就能知道是哪里有冲突,解决办法就是在运行的时候动态修改约束冲突。

3.描述一下你对masonry的理解?

答案:masonry是一个轻量级的布局框架,采用链式语法封装自动布局,使程序代码更为易读,只声明了方法,没有声明相应的属性,通过添加约束条件来确定视图的位置,而不是通过手动修改frame来进行布局,主要包含点语法、小括号调用、连续访问 三部分

4.详细描一下Xib与StoryBoard的区别?

答案: Xib是轻量级的,用来描述局部的UI界面,一个工程中可以有多个xib文件,主要用于视图,一个xib可以在不同的视图控制器中使用。 storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系,主要用于视图控制器。 然后多个storyboard之间可以关联使用。

九.swift语言相关

1.详细描述一下你对苹果语言Swift的理解?

答案:swift是苹果WWDC2014大会上发布的一种编程语言。它继承了C语言以及Objective-C的特性,使用var命名变量,使用let命名常量,创建类时只有一个后缀为.swift的文件。支持playground,允许程序员写一段swift代码并立即看到结果。无需导入单独的库,无需编写main()函数,无需在每个语句后写分号。

十.协议相关4个题

1.详细描述一下对你TCP,UDP,HTTP的理解?

答案:HTTP协议,对应于应用层 TCP协议,对应于传输层; UDP协议,对应于传输; IP协议,对应于网络层; HTTP协议基于TCP连接的,TCP/IP是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议。 scoket是对TCP/IP协议的封装,scoket本身并不是协议,而是一个调用接口(API),我们才能用TCP/IP协议。

2.详细描述一下HTTP与HTTPS之间的区别?

答案:http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议; http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全; 如果使用http进行网络请求时,需要在info.plist文件设置允许任意加载,禁用ATS。 https需要申请数据证书,公钥,私钥;

3.详细描述下UDP和TCP的区别?

答案:TCP—传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

UDP—用户数据协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

4.简单描述一下TCP/IP建立连接通信的过程?

答案:在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。 第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND(发送)状态,等待服务器确认; 第二次握手:服务器收到客户端连接请求,向客户端发送允许连接应答,此时服务器进入SYN_RECV(接收)状态; 第三次握手:客户端收到服务器的允许连接应答,向服务器发送确认,客户端和服务器进入通信状态,完成三次握手。

十一.4个题

1.ios 10的新特性有哪些呢,举例说明一下?

答案:它的语音识别api对外开放,提供了一套从语音识别到代码处理,最后向用户展示结果的流程; 它还封装了新的通知中心,可以在推送通知中添加音频,视频,图片等功能; 它还对外开放新的iMessage api,它可以对现有 App 延伸扩展,比如添加了贴纸表情包的功能,也可以发送图片,链接,音频,视频内容。

2.实际开发中,程序出现了闪退,该如何解决?

答案: 1.单步断点调试,找出内存泄漏的地方, 2.使用全局断点,锁定程序闪退的地方,找出内存泄漏的原因 3.使用僵尸变量,根据打印日志,然后分析原因,找出内存泄漏的地方 4.分段调试,找出内存泄漏的地方 5.使用Instrument 当中的Leak检测工具

3.详细描述一下你对ATS的理解?

答案:一种网络安全机制,这项机制确保 app 在进行网络访问时,使用业界标准的,没有已知重大安全隐患的协议和加密方式,以此确保用户的隐私和数据完整性。从而培养用户对 app 的信任。

4.详细描述一下你对ipv4与ipv6的理解。

答案:IP是TCP/IP协议族中网络层的协议,是TCP/IP协议族的核心协议。目前IP协议的版本号是4(简称为IPv4)地址位数为32位。IPv6是下一版本的互联网协议,IPv6采用128位地址长度,几乎可以不受限制地提供地址。解决了地址短缺,有端到无端IP连接、服务质量(QoS)、安全性、多播、移动性、即插即用等。IPv6与IPv4相比更大的地址空间。更小的路由表。

5.解决tableview滑动卡顿问题

之所以会造成这个问题,主要是因为cell赋值内容时,会根据内容设置布局,也就可以知道cell的高度,若有1000行,就会调用1000次 heightForRow方法,意味着每次回调这个方法时都要计算高度,而计算是要花时间了,在用户体验上的体现就是卡顿。 为了避免重复且无意义的计算cell高度,我们可以需要一个可变数组缓存高度,每当回调heightForRow这个方法时,我们先去这个数组里去取,如果有,就直接拿出来,如果没有,就计算高度,并且放进数组,,这样就可以解决卡顿问题。

十二、常问面试题

1.设计模式是什么? 你知道哪些设计模式,并简要叙述?

设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型的事情。 1). MVC模式:Model View Control,把模型 视图 控制器 层进行解耦合编写。 2). MVVM模式:Model View ViewModel 把模型 视图 业务逻辑 层进行解耦和编写。 3). 单例模式:通过static关键词,声明全局变量。在整个进程运行期间只会被赋值一次。 4). 观察者模式:KVO是典型的通知模式,观察某个属性的状态,状态发生变化时通知观察者。 5). 委托模式:代理+协议的组合。实现1对1的反向传值操作。 6). 工厂模式:通过一个类方法,批量的根据已有模板生产对象。

2.MVC 和 MVVM 的区别

1). MVVM是对胖模型进行的拆分,其本质是给控制器减负,将一些弱业务逻辑放到VM中去处理。 2). MVC是一切设计的基础,所有新的设计模式都是基于MVC进行的改进。

3.#import跟 #include 有什么区别,@class呢,#import<> 跟 #import””有什么区别?

1). #import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入。 2). @class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含。 3). #import<>用来包含系统的头文件,#import””用来包含用户头文件。

4.frame 和 bounds 有什么不同?

frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父view的坐标系统) bounds指的是:该view在本身坐标系统中的位置和大小。(参照点是本身坐标系统)

5.Objective-C的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?

答:Objective-C的类不可以多重继承;可以实现多个接口(协议);Category是类别;一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。

6.@property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的

@property 的本质是什么? @property = ivar + getter + setter; “属性” (property)有两大概念:ivar(实例变量)、getter+setter(存取方法) “属性” (property)作为 Objective-C 的一项特性,主要的作用就在于封装对象中的数据。 Objective-C 对象通常会把其所需要的数据保存为各种实例变量。实例变量一般通过“存取方法”(access method)来访问。其中,“获取方法” (getter)用于读取变量值,而“设置方法” (setter)用于写入变量值。

7.@property中有哪些属性关键字?/ @property 后面可以有哪些修饰符?

  • 属性可以拥有的特质分为四类:
  • 1.原子性— nonatomic 特质
  • 2.读/写权限—readwrite(读写)、readonly (只读)
  • 3.内存管理语义—assign、label、 weak、unsafe_unretained、copy
  • 4.方法名—getter= 、setter=
  • 5.不常用的:nonnull,null_resettable,nullable

8.属性关键字 readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用?

  • 1). readwrite 是可读可写特性。需要生成getter方法和setter方法。
  • 2). readonly 是只读特性。只会生成getter方法,不会生成setter方法,不希望属性在类外改变。
  • 3). assign 是赋值特性。setter方法将传入参数赋值给实例变量;仅设置变量时,assign用于基本数据类型。
  • 4). retain(MRC)/label(ARC) 表示持有特性。setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1。
  • 5). copy 表示拷贝特性。setter方法将传入对象复制一份,需要完全一份新的变量时。
  • 6). nonatomic 非原子操作。决定编译器生成的setter和getter方法是否是原子操作,atomic表示多线程安全,一般使用nonatomic,效率高。

9.什么情况使用 weak 关键字,相比 assign 有什么不同?

  • 1.在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决,比如: delegate 代理属性。
  • 2.自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用 weak,自定义 IBOutlet 控件属性一般也使用 weak;当然,也可以使用label。

10.IBOutlet连出来的视图属性为什么可以被设置成weak?

  • 因为父控件的subViews数组已经对它有一个强引用。
  • 不同点:
  • assign 可以用非 OC 对象,而 weak 必须用于 OC 对象。
  • weak 表明该属性定义了一种“非拥有关系”。在属性所指的对象销毁时,属性值会自动清空(nil)。

11.怎么用 copy 关键字?

  • 用途:
  1. NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;
  2. block 也经常使用 copy 关键字。
  • 说明:

block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.在 ARC 中写不写都行:对于 block 使用 copy 还是 label 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效。

12.用@property声明的 NSString / NSArray / NSDictionary 经常使用 copy 关键字,为什么?如果改用label关键字,可能造成什么问题?

用 @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作(就是把可变的赋值给不可变的),为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份

  1. 因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本。
  2. 如果我们使用是 label ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。 //总结:使用copy的目的是,防止把可变类型的对象赋值给不可变类型的对象时,可变类型对象的值发送变化会无意间篡改不可变类型对象原来的值。

13.浅拷贝和深拷贝的区别?

答: 浅拷贝:只复制指向对象的指针,而不复制引用对象本身。 深拷贝:复制引用对象本身。内存中存在了两份独立对象本身,当修改A时,A_copy不变。

14.系统对象的 copy 与 mutableCopy 方法

不管是集合类对象(NSArray、NSDictionary、NSSet … 之类的对象),还是非集合类对象(NSString, NSNumber … 之类的对象),接收到copy和mutableCopy消息时,都遵循以下准则:

  1. copy 返回的是不可变对象(immutableObject);如果用copy返回值调用mutable对象的方法就会crash。
  2. mutableCopy 返回的是可变对象(mutableObject)。

一、非集合类对象的copy与mutableCopy 在非集合类对象中,对不可变对象进行copy操作,是指针复制,mutableCopy操作是内容复制; 对可变对象进行copy和mutableCopy都是内容复制。用代码简单表示如下:

NSString *str = @"hello word!";
NSString *strCopy = [str copy] // 指针复制,strCopy与str的地址一样
NSMutableString *strMCopy = [str mutableCopy] // 内容复制,strMCopy与str的地址不一样
NSMutableString *mutableStr = [NSMutableString stringWithString: @"hello word!"];
NSString *strCopy = [mutableStr copy] // 内容复制
NSMutableString *strMCopy = [mutableStr mutableCopy] // 内容复制

二、集合类对象的copy与mutableCopy (同上) 在集合类对象中,对不可变对象进行copy操作,是指针复制,mutableCopy操作是内容复制; 对可变对象进行copy和mutableCopy都是内容复制。但是:集合对象的内容复制仅限于对象本身,对集合内的对象元素仍然是指针复制。(即单层内容复制)

NSArray *arr = @[@[@"a", @"b"], @[@"c", @"d"];
NSArray *copyArr = [arr copy]; // 指针复制
NSMutableArray *mCopyArr = [arr mutableCopy]; //单层内容复制
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *copyArr = [mutableArr copy]; // 单层内容复制
NSMutableArray *mCopyArr = [mutableArr mutableCopy]; // 单层内容复制

【总结一

标签: 1500vc重量变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台