• 笔试整理1


    1、对数组中的元素去重复

    例如:

    参考答案:

    • 第一种方法:开辟新的内存空间,然后判断是否存在,若不存在则添加到数组中,得到最终结果的顺序不发生变化。效率分析:时间复杂度为O ( n2 ):

    补充:原来集合操作可以通过valueForKeyPath来实现的,去重可以一行代码实现:

    但是返回的结果是无序的,与原来的顺序不同。大家可以阅读:Collection Operators

    • 第二种方法:利用NSDictionary去重,字典在设置key-value时,若已存在则更新值,若不存在则插入值,然后获取allValues。若不要求有序,则可以采用此种方法。若要求有序,还得进行排序。效率分析:只需要一个循环就可以完成放入字典,若不要求有序,时间复杂度为O(n)。若要求排序,则效率与排序算法有关:

    如果需要按照原来的升序排序,可以这样:

    • 第三种方法:利用集合NSSet的特性(确定性、无序性、互异性),放入集合就自动去重了。但是它与字典拥有同样的无序性,所得结果顺序不再与原来一样。如果不要求有序,使用此方法与字典的效率应该是差不多的。效率分析:时间复杂度为O (n):

    如果要求有序,那就得排序,比如这里要升序排序:

    补充:

    一直没有使用过有序集合,网友们反馈到可以直接使用有序集合,感谢大家:

    以上三种方法是笔者所能想到的办法。如果大家有更好的办法,欢迎在评论中指出。

    2、说说以下元素的特性和作用

    参考答案:

    特性:

    • NSArray表示不可变数组,是有序元素集,只能存储对象类型,可通过索引直接访问元素,而且元素类型可以不一样,但是不能进行增、删、改操作;NSMutableArray是可变数组,能进行增、删、改操作。通过索引查询值很快,但是插入、删除等效率很低。
    • NSSet表示不可变集合,具有确定性、互异性、无序性的特点,只能访问而不能修改集合;NSMutableSet表示可变集合,可以对集合进行增、删、改操作。集合通过值查询很快,插入、删除操作极快。
    • NSDictionary表示不可变字典,具有无序性的特点,每个key对应的值是唯一的,可通过key直接获取值;NSMutableDictionary表示可变字典,能对字典进行增、删、改操作。通过key查询值、插入、删除值都很快。

    作用:

    • 数组用于处理一组有序的数据集,比如常用的列表的dataSource要求有序,可通过索引直接访问,效率高。
    • 集合要求具有确定性、互异性、无序性,在iOS开发中是比较少使用到的,笔者也不清楚如何说明其作用
    • 字典是键值对数据集,操作字典效率极高,时间复杂度为常量,但是值是无序的。在ios中,常见的JSON转字典,字典转模型就是其中一种应用。

    3、简单描述一下XIB与Storyboards,说一下他们的优缺点。

    参考答案:

    笔者倾向于纯代码开发,所以所提供的参考答案可能具有一定的个人感情,不过还是给大家说说笔者的想法。

    优点:

    • XIB:在编译前就提供了可视化界面,可以直接拖控件,也可以直接给控件添加约束,更直观一些,而且类文件中就少了创建控件的代码,确实简化不少,通常每个XIB对应一个类。
    • Storyboard:在编译前提供了可视化界面,可拖控件,可加约束,在开发时比较直观,而且一个storyboard可以有很多的界面,每个界面对应一个类文件,通过storybard,可以直观地看出整个App的结构。

    缺点:

    • XIB:需求变动时,需要修改XIB很大,有时候甚至需要重新添加约束,导致开发周期变长。XIB载入相比纯代码自然要慢一些。对于比较复杂逻辑控制不同状态下显示不同内容时,使用XIB是比较困难的。当多人团队或者多团队开发时,如果XIB文件被发动,极易导致冲突,而且解决冲突相对要困难很多。
    • Storyboard:需求变动时,需要修改storyboard上对应的界面的约束,与XIB一样可能要重新添加约束,或者添加约束会造成大量的冲突,尤其是多团队开发。对于复杂逻辑控制不同显示内容时,比较困难。当多人团队或者多团队开发时,大家会同时修改一个storyboard,导致大量冲突,解决起来相当困难。

    4、请把字符串2015-04-10格式化日期转为NSDate类型

    参考答案:

    5、在App中混合HTML5开发App如何实现的。在App中使用HTML5的优缺点是什么?

    参考答案:

    在iOS中,通常是通常UIWebView来实现,当然在iOS8以后可以使用WKWebView来实现.有以下几种实现方法:

    • 通过实现UIWebView的代理方法来拦截,判断scheme是否是约定好的,然后iOS调用本地相关API来实现:

    优缺点:

    • iOS加入H5响应比原生要慢很多,体验不太好,这是缺点。
    • iOS加入H5可以实现嵌入别的功能入口,可随时更改,不用更新版本就可以上线,这是最大的优点

    6、请描述一下同步和异步,说说它们之间的区别。

    参考答案:

    首先,我们要明确一点,同步和异步都是在线程中使用的。在iOS开发中,比如网络请求数据时,若使用同步请求,则只有请求成功或者请求失败得到响应返回后,才能继续往下走,也就是才能访问其它资源(会阻塞了线程)。网络请求数据异步请求时,不会阻塞线程,在调用请求后,可以继续往下执行,而不用等请求有结果才能继续。

    区别:

    • 线程同步:是多个线程访问同一资源时,只有当前正在访问的线程访问结束之后,其他线程才能开始访问(被阻塞)。
    • 线程异步:是多个线程在访问竞争资源时,可以在空闲等待时去访问其它资源(不被阻塞)。

    7、请简单描述一下队列和多线程的使用原理。

    参考答案:

    在iOS中队列分为以下几种:

    • 串行队列:队列中的任务只会顺序执行
    • 并行队列: 队列中的任务通常会并发执行
    • 全局队列:是系统的,直接拿过来(GET)用就可以;与并行队列类似
    • 主队列:每一个应用程序对应唯一一个主队列,直接GET即可;在多线程开发中,使用主队列更新UI

    上面这四种是针对GCD来讲的,串行队列中的任务只能一个个地执行,在前一个没有执行完毕之前,下一个只能等待。并行队列可以并发地执行任务,因此多个任务之间执行的顺序不能确定,当添加一个新的任务时,交由GCD来判断是否要创建新的新的线程。

    大家可以阅读图片多线程,也许更明了:

    8、描述一下iOS的内存管理,在开发中对于内存的使用和优化包含哪些方面。我们在开发中应该注意哪些问题。

    参考答案:

    内存管理准则:谁强引用过,谁就在不再使用时使引用计数减一。

    对于内存的使用和优化常见的有以下方面:

    • 重用问题:如UITableViewCells、UICollectionViewCells、UITableViewHeaderFooterViews设置正确的reuseIdentifier,充分重用。
    • 尽量把views设置为不透明:当opque为NO的时候,图层的半透明取决于图片和其本身合成的图层为结果,可提高性能。
    • 不要使用太复杂的XIB/Storyboard:载入时就会将XIB/storyboard需要的所有资源,包括图片全部载入内存,即使未来很久才会使用。那些相比纯代码写的延迟加载,性能及内存就差了很多。
    • 选择正确的数据结构:学会选择对业务场景最合适的数组结构是写出高效代码的基础。比如,数组: 有序的一组值。使用索引来查询很快,使用值查询很慢,插入/删除很慢。字典: 存储键值对,用键来查找比较快。集合: 无序的一组值,用值来查找很快,插入/删除很快。
    • gzip/zip压缩:当从服务端下载相关附件时,可以通过gzip/zip压缩后再下载,使得内存更小,下载速度也更快。
    • 延迟加载:对于不应该使用的数据,使用延迟加载方式。对于不需要马上显示的视图,使用延迟加载方式。比如,网络请求失败时显示的提示界面,可能一直都不会使用到,因此应该使用延迟加载。
    • 数据缓存:对于cell的行高要缓存起来,使得reload数据时,效率也极高。而对于那些网络数据,不需要每次都请求的,应该缓存起来,可以写入数据库,也可以通过plist文件存储。
    • 处理内存警告:一般在基类统一处理内存警告,将相关不用资源立即释放掉
    • 重用大开销对象:一些objects的初始化很慢,比如NSDateFormatter和NSCalendar,但又不可避免地需要使用它们。通常是作为属性存储起来,防止反复创建。
    • 避免反复处理数据:许多应用需要从服务器加载功能所需的常为JSON或者XML格式的数据。在服务器端和客户端使用相同的数据结构很重要。
    • 使用Autorelease Pool:在某些循环创建临时变量处理数据时,自动释放池以保证能及时释放内存。
    • 正确选择图片加载方式:详情阅读细读UIImage加载方式

    9、plist文件是用来做什么的。一般用它来处理一些什么方面的问题。

    参考答案:

    plist是iOS系统中特有的文件格式。我们常用的NSUserDefaults偏好设置实质上就是plist文件操作。plist文件是用来持久化存储数据的。

    我们通常使用它来存储偏好设置,以及那些少量的、数组结构比较复杂的不适合存储数据库的数据。比如,我们要存储全国城市名称和id,那么我们要优先选择plist直接持久化存储,因为更简单。

    10、iOS中缓存一定量的数据以便下次可以快速执行,那么数据会存储在什么地方,有多少种存储方式?

    参考答案:

    • 偏好设置(NSUserDefaults)
    • plist文件存储
    • 归档
    • SQLite3
    • Core Data

    详情请阅读:iOS常用的持久化存储方式

    11、请简单写出增、删、改、查的SQL语句。

    参考答案:

    数据库的简单操作,还是会的,大学可没白学。

    增:

    删:

    改:

    查:

    12、在提交苹果审核时,遇到哪些问题被拒绝,对于被拒绝的问题是如何处理的。

    参考答案:

    对于笔者而言,所提交过的app还没有被拒绝过。不过在笔者所维护的几个群里经常有朋友们问到相关被拒绝的解决办法。幸好还懂一点点英文,还能帮助他们翻译翻译苹果反馈的被拒原因及所担的建议。

    这里只列出几种最常见的被拒原因:

    • 最常见到的就是app中有虚拟物品交易,但是不是走内购导致被拒。
    • 音频类App或者使用到音频相关的app,因为版权问题而被拒
    • App出现必闪退而被拒

    最后

    在这个夜晚,所有答案都是笔者花了大量的时间来整理出来的,且看且珍惜吧!如果所提供的参考答案与您的想法有所不同,欢迎到群里来交流,也可以直接在评论中反馈。

    ///////////////////////////////

    1.Difference between shallow copy and deep copy?
浅复制和深复制的区别?

    答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。
深层复制:复制引用对象本身。
意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源
还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了
两份独立对象本身。
用网上一哥们通俗的话将就是:
浅复制好比你和你的影子,你完蛋,你的影子也完蛋
深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。


    2.What is advantage of categories? What is difference between implementing a category and inheritance?
类别的作用?继承和类别在实现中有何区别?
    答案:category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。
并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。
类别主要有3个作用:
(1)将类的实现分散到多个不同文件或多个不同框架中。
(2)创建对私有方法的前向引用。
(3)向对象添加非正式协议。
 继承可以增加,修改或者删除方法,并且可以增加属性。


    3.Difference between categories and extensions?
类别和类扩展的区别。
    答案:category和extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。
extensions可以认为是一个私有的Category。


    4.Difference between protocol in objective c and interfaces in java?
obc中的协议和java中的接口概念有何不同?

    答案:OBC中的代理有2层含义,官方定义为 formal和informal protocol。前者和Java接口一样。
informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,但是如果有实现,就会改变类的属性。
其实关于正式协议,类别和非正式协议我很早前学习的时候大致看过,也写在了学习教程里
“非正式协议概念其实就是类别的另一种表达方式“这里有一些你可能希望实现的方法,你可以使用他们更好的完成工作”。
这个意思是,这些是可选的。比如我门要一个更好的方法,我们就会申明一个这样的类别去实现。然后你在后期可以直接使用这些更好的方法。
这么看,总觉得类别这玩意儿有点像协议的可选协议。"
现在来看,其实protocal已经开始对两者都统一和规范起来操作,因为资料中说“非正式协议使用interface修饰“,
现在我们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。


    5.What are KVO and KVC?

    答案:KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。

    KVO这种编码方式使用起来很简单,很适用与datamodel修改后,引发的UIVIew的变化这种情况,就像上边的例子那样,当更改属性的值后,监听对象会立即得到通知。

     KVC是KeyValueCoding的简称,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。

     当使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。


    6.What is purpose of delegates?
代理的作用?
    答案:代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。
另外一点,代理可以理解为java中的回调监听机制的一种类似。


    7.What are mutable and immutable types in Objective C?
obc中可修改和不可以修改类型。

    答案:可修改不可修改的集合类。这个我个人简单理解就是可动态添加修改和不可动态添加修改一样。
比如NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间。

    9.what is difference between NSNotification and protocol?
通知和协议的不同之处?

    答案:协议有控制链(has-a)的关系,通知没有。
首先我一开始也不太明白,什么叫控制链(专业术语了~)。但是简单分析下通知和代理的行为模式,我们大致可以有自己的理解
简单来说,通知的话,它可以一对多,一条消息可以发送给多个消息接受者。
代理按我们的理解,到不是直接说不能一对多,比如我们知道的明星经济代理人,很多时候一个经济人负责好几个明星的事务。
只是对于不同明星间,代理的事物对象都是不一样的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的
发布会了。但是通知就不一样,他只关心发出通知,而不关心多少接收到感兴趣要处理。
因此控制链(has-a从英语单词大致可以看出,单一拥有和可控制的对应关系。


    10.What is push notification?
什么是推送消息?

    答案:

                1、              [Client App]注册消息推送;

                2、              [Client App]跟[APNS Service]要deviceToken, Client App接收deviceToken;

                3、              [Client App]将deviceToken发送给[Provider]Push服务端程序;

                4、              当Push服务端程序满足发送消息条件了,[Provider]向[APNS Service]发送消息;

                5、              [APNS Service]将消息发送给[Client App].

    12.Singleton?
对于单例的理解


    答案:单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
    显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

    13.What is responder chain?
说说响应链

    答案:

    首先要明确的是:在IOS中,有响应者链对事件进行响应,所有的响应类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象将依次获得响应事件消息的机会。

    响应链的过程:当事件发生的时候,响应链首先被发送给第一个响应者(往往是事件发生的视图,也就是用户触摸屏幕的地方)。事件将沿着响应者链一直向下传递,知道被接受并作出处理。一般来说,第一响应这是个视图对象或者其子类,当其被触摸后事件就交由它处理,如果他不处理,事件就会被传递给视图控制器对象UIViewController(如果存在),然后是它的父视图对象(superview),以此类推知道顶层视图。接下来会沿着顶层视图(top view)到窗口(UIwindow 对象) 再到程序的(UIApplication对象),如果整个过程都没有响应这个事件,则该事件被丢弃,一般情况下,在响应链中只要有对象处理事件,事件就会被传递。

    典型的响应路线图如:

    First  Responser --> The Window -->The Applicationn --> App Delegate

    正常的响应者链流程经常被委托打断,一个对象可能将响应工作委托给另一个对象来完成(通常是视图控制器viewcontroller)。


    14.Difference between frame and bounds?
frame和bounds有什么不同?

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


    15.Difference between method and selector?
方法和选择器有何不同?

    答案:selector是一个方法的名字,method是一个组合体,包含了名字和实现.
详情可以看apple文档。


    16.Is there any garbage collection mechanism in Objective C.?
OBC的垃圾回收机制?

    答案: OBC2.0有Garbage collection,但是iOS平台不提供。
一般我们了解的objective-c对于内存管理都是手动操作的,但是也有自动释放池。
但是差了大部分资料,貌似不要和arc机制搞混就好了。
求更多~~


    17.NSOperation queue?

    答案:存放NSOperation的集合类。
操作和操作队列,基本可以看成java中的线程和线程池的概念。用于处理ios多线程开发的问题。
网上部分资料提到一点是,虽然是queue,但是却并不是带有队列的概念,放入的操作并非是按照严格的先进现出。
这边又有个疑点是,对于队列来说,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,
但是Bfunc是等Afunc完全操作完以后,B才开始启动并且执行,因此队列的概念离乱上有点违背了多线程处理这个概念。
但是转念一想其实可以参考银行的取票和叫号系统。
因此对于A比B先排队取票但是B率先执行完操作,我们亦然可以感性认为这还是一个队列。
但是后来看到一票关于这操作队列话题的文章,其中有一句提到
“因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”
瞬间觉得这个queue名字有点忽悠人了,还不如pool~
综合一点,我们知道他可以比较大的用处在于可以帮组多线程编程就好了。


    18.What is lazy loading?

    答案:懒汉模式,只在用到的时候才去初始化。
也可以理解成延时加载。
我觉得最好也最简单的一个列子就是tableView中图片的加载显示了。
一个延时载,避免内存过高,一个异步加载,避免线程堵塞。

    22.#import 跟#include 又什么区别 #import<> 跟 #import""又什么区别?
    答案:@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文 件中还是需要使用#import而#import比起#include的好处就是不会引起交叉编译。

    24.id 声明的对象有什么特性?
    答案:id是个很重要的类型,是个可以指向任何类型的指针或者可以理解为指向任何未知类型的指针。


    25.MVC是什么?有什么特性?为什么在iPhone上被广泛运用?
    答案:MVC设计模式考虑三种对象:模型对象、视图对象、和控制器对象。模型对象代表 特别的知识和专业技能,它们负责保有应用程序的数据和定义操作数据的逻辑。视图对象知道如何显示应用程序的模型数据,而且可能允许用户对其进行编辑。控制 器对象是应用程序的视图对象和模型对象之间的协调者。


    26.对于语句NSString* testObject = [[NSData alloc] init];testObject 在编译时和运行时分别是什么类型的对象?

    答案:编译时是NSString对象,运行时是NSData对象

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

               readwrite 是可读可写特性;需要生成getter方法和setter方法时

              readonly 是只读特性  只会生成getter方法 不会生成setter方法 ;不希望属性在类外改变

              assign 是赋值特性,setter方法将传入参数赋值给实例变量;简单赋值,不更改索引计数,对基础数据类型 (NSInteger)和C数据类型

             retain 表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;对其他NSObject和其子类

             copy 表示赋值特性,setter方法将传入对象复制一份;需要完全一份新的变量时。对NSString

             nonatomic 非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic

    38.在一个对象释放前.如果他被加到了notificationCenter 中.不在notificationcenter中remove这个对象可能会出现什么问题?

    答:对象被release,出现野指针。

    41. 线程与进程的区别和联系?

    答案: 进程和线程都是由操作系统所体会的程序运行的基本 单元,系统利用该基本单元实现系统对应用的并发性。
    程和线程的主要差别在于它们是不同的操作系统资源 管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变 量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一 些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。


    42.在iphone上有两件事情要做,请问是在一个线程里按顺序做效率高还是两个线程里做效率高?为什么?

    答:在两个线程里高,程序可以并发执行。

    43,单例写法

    复制代码
    static Singleton *singleton = nil;//将对象定义为全局变量 已备在本类其他方法中方便使用
    +(Singleton *)sharedSingleton{
    //同步锁写法
        @synchronized(self){
            if (!singleton) {
                singleton = [[Singleton alloc]init];
            }
        }
        return singleton;
    }
    + (Singleton *)sharedSingleton{
        //GCD写法 (执行效率高)
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            singleton = [[Singleton alloc]init];
        });
        return singleton;
    }
    复制代码

    为了完全的实现实例的单态性,必须通过一定手段来避免实例多次被创建。+(id)sharedInstance控制了单例的创建和访问,但是并不能控制其它地方的代码通过alloc方法来创建更多的实例,因此我们还要重载任何一个涉及到allocation的方法,这些方法包括   +new, +alloc,+allocWithZone:, -copyWithZone:, 以及 -mutableCopyWithZone: 另外,+(id)sharedInstance也需要稍作修改。

    复制代码
    + (id)alloc  
    {  
        NSLog(@"%@: use +sharedInstance instead of +alloc", [[self class] name]);  
        return nil;  
    }  
      
      
    + (id)new  
    {  
        return [self alloc];  
    }  
      
    +(id)allocWithZone:(NSZone*)zone  
    {  
        return [self alloc];  
    }  
      
    -   (id)copyWithZone:(NSZone *)zone  
    {   // -copy inherited from NSObject calls -copyWithZone:  
        NSLog(@"MySingletonClass: attempt to -copy may be a bug.");  
        [self retain];  
        return self;  
    }  
      
    - (id)mutableCopyWithZone:(NSZone *)zone  
    {  
        // -mutableCopy inherited from NSObject calls -mutableCopyWithZone:  
        return [self copyWithZone:zone];  
    }  
    复制代码
  • 相关阅读:
    Github注册过程以及对管理软件的了解
    进度总结
    总体心得
    学车后的领悟
    打工心得
    关于传统文化的对话实践计划书
    软件工程-课程总结
    结对编程项目---四则运算
    作业三
    目前流行的源程序版本管理软件和项目管理软件都有哪些?各有什么优缺点
  • 原文地址:https://www.cnblogs.com/yulang314/p/5232627.html
Copyright © 2020-2023  润新知