iOS基础笔试题 - 集锦二

来源:互联网 发布:三维动画制作软件apk 编辑:程序博客网 时间:2024/05/22 08:23

                     



前言

以下部分题目来源于网络,笔者在此处收集起来,既是要巩固自我,也希望能够帮助到同样需要的人!参考答案均为笔者所写,其有疑问或者出错之处,请在评论中提出,谢谢!不喜勿喷!


1、即时聊天App不会采用的网络传输方式

A. UDP

B. TCP 

C. HTTP 

D. FTP


FTP:是文件传输协议,是File Transfer Protocol的简称,它的作用是用于控制互联网上文件的双向传输,因此一定不会是即时聊天使用的;

UDP:是面向无连接的传输层协议,数据传输是不可靠的,它只管发,不管收不收得到;

TCP:是面向连接的,可靠的传输层协议;

HTTP:是超文本传输协议,对应于应用层,而HTTP是基于TCP的。

关于socket理论基础知识,更详细可阅读下面的文章:Socket理论知识

参考答案:D

-----------------可爱的分割线------------------


2、下列技术不属于多线程的是

A Block 

B NSThread 

C NSOperation

D GCD


苹果提供了NSThread、NSOperation、GCD这三种技术用于处理多线程。

对于NSThread是需要自己管理其生命周期的;

对于NSOpeartion也是常用的技术之一,通常与NSOperationQueue一起配合使用;

对于GCD是平时见到最多的,使用起来很方便,而它与block配合起来使用,简单而且简洁。

Block不是一项技术,只是代码段,但是具备自动捕获上下文信息的功能,与函数指针有点类似,其实全局函数就是特殊的block。

关于NSOperation/NSOperationQueue,可阅读笔者的文章:多线程之NSOperatoin/NSOperationQueue;

参考答案:A

-----------------可爱的分割线------------------


3、线程和进程的区别不正确的是

A 进程和线程都是由操作系统所提供的程序运行的基本单元

B 线程之间有单独的地址空间

C 进程和线程的主要差别在于它们是不同的操作系统资源管理方式

D 线程有自己的堆栈和局部变量


这是学习操作系统知识的时候经常会考试的内容,但是在工作中经常会遇到多线程处理问题。通常来说,一个进程就代表着一个应用程序,而操作系统为了更好的利用资源,提供了线程用于处理并发。线程之间没有有单独的地址空间,处理完成之后还得回到主线程,所以,一个线程死掉就等于整个进程死掉。进程和线程都是操作系统的基本单元,只是分工不同,是两种不同的资源管理方式。线程所需要的资源都来自于进程,它没有自己独立的资源,也就没有自己的堆栈和局部变量。

修正:这里参考答案与描述不符合的问题。

参考答案:B

-----------------可爱的分割线------------------


4、堆和栈的区别正确的是

A 对于栈来讲,我们需要手工控制,容易产生memory leak

B 对于堆来说,释放工作由编译器自动管理,无需我们手工控制

C 在Windows下,栈是向高地址扩展的数据结构,是连续的内存区域,栈顶的地址和栈的最大容量是系统预先规定好的

D 对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低


栈是由编译器管理的,不是我们手动控制,但是栈所能分配的内存是比较少的,如果要处理大数据,则需要在堆上分配,因此在栈上比较容易出现Memory Leak;

对于堆,需要我们自己申请内存,同时也需要我们自己手动释放,否则会造成内存泄露;对于堆,如果过多地申请内存空间,会导致内存空间不连接,从而造成内存碎片,使程序效率降低。

参考答案:D

-----------------可爱的分割线------------------


5、下列回调机制的理解不正确的是

A target-action:当两个对象之间有⽐较紧密的关系时,如视图控制器与其下的某个视图。       

B delegate:当某个对象收到多个事件,并要求同一个对象来处理所有事件时。委托机制必须依赖于某个协议定义的⽅法来发送消息。       

C NSNotification:当需要多个对象或两个无关对象处理同一个事件时。       

D Block:适⽤于回调只发⽣生一次的简单任务。


对于Target-Action机制,要求两个对象之间有比较紧密的联系,比如在控制器与cell之间,可通过设置target为控制器对象,而action则为控制器中的某个回调方法;

对于Delegator机制,它是苹果提供的标准回调机制,通常会提供一个标准的协议,然后由代理类遵守协议,最常用的用法是反向传值,比如打开蓝牙后要反馈给前一个界面蓝牙的开关状态;

对于通知,通常是多对多的关系,它并不关心是谁要处理消息,任意对象都可以注册通知到通知中心,当发送通知时,所有注册了该通知的对象都可以收到消息。最常用的场景是跨模块,比如登录模块与其它模块有着非常紧密的联系,但是登录成功后各个地方可能需要做一些处理,因此通常会在登录成功或者登出成功后发送通知,以便各个需要处理的模块得到正确的处理;

对于Block是相当简单的,它只适用于一对一的关系,比如在做某个操作成功或者失败后回调。

 参考答案:B

-----------------可爱的分割线------------------


6、对于runloop的理解不正确的是

A 每一个线程都有其对应的RunLoop

B 默认非主线程的RunLoop是没有运行的

C 在一个单独的线程中没有必要去启用RunLoop

D 可以将NSTimer添加到runloop中


说到RunLoop,它可是多线程的法宝。通常来说,一个线程一次只能执行一个任务,执行完任务后就会退出线程。但是,对于主线程是不能退出的,因此我们需要让主线程即时任务执行完毕,也可以继续等待接收事件而不退出,那么RunLoop就是关键法宝了。但是非主线程通常来说就是为了执行某一任务的,执行完毕就需要归还资源,因此默认是不运行RunLoop的。

每一个线程都有其对应的RunLoop的,只是默认只有主线程的RunLoop是启动的,其它子线程的RunLoop默认是不启动的,若要启动则需要手动启动。

在一个单独的线程中,如果需要在处理完某个任务后不退出,继续等待接收事件,则需要启用RunLoop。

NSRunLoop提供了一个添加NSTimer的方法,可以指定Mode,如果要让任何情况下都回调,则需要设置Mode为Common模式。

实质上,对于子线程的runloop默认是不存在的,因为苹果采用了懒加载的方式。如果我们没有手动调用[NSRunLoop currentRunLoop],就不会去查询是否存在当前线程的RunLoop,也就不会去加载,更不会创建。

下面是CFRunLoop的部分源码:

// should only be called by Foundation

// t==0 is a synonym for "main thread" that always works

CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {

if (pthread_equal(t, kNilPthreadT)) {

  t = pthread_main_thread_np();

}

__CFSpinLock(&loopsLock);

if (!__CFRunLoops) {

  __CFSpinUnlock(&loopsLock);

  CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);

  CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_np());

  CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop);

  if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void * volatile *)&__CFRunLoops)) {

    CFRelease(dict);

  }

  CFRelease(mainLoop);

  __CFSpinLock(&loopsLock);

}

CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));

__CFSpinUnlock(&loopsLock);

if (!loop) {

  CFRunLoopRef newLoop = __CFRunLoopCreate(t);

  __CFSpinLock(&loopsLock);

  loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));

  if (!loop) {

    CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop);

    loop = newLoop;

  }

  // don't release run loops inside the loopsLock, because CFRunLoopDeallocate may end up taking it

  __CFSpinUnlock(&loopsLock);

  CFRelease(newLoop);

}

if (pthread_equal(t, pthread_self())) {

  _CFSetTSD(__CFTSDKeyRunLoop, (void *)loop, NULL);

  if (0 == _CFGetTSD(__CFTSDKeyRunLoopCntr)) {

    _CFSetTSD(__CFTSDKeyRunLoopCntr, (void *)(PTHREAD_DESTRUCTOR_ITERATIONS-1), (void (*)(void *))__CFFinalizeRunLoop);

  }

}

return loop;


关键加载过程如下:

检查全局字典里是否存在该线程的runLoop,如果有则退出,否则

创建一个新的runLoop放到全局字典中

参考答案:C

-----------------可爱的分割线------------------


7、断点续传需要在请求头中添加的控制续传最重要的关键字

A range

B length 

C type 

D size


理由:对于实现文件的断点续传和断点下载,需要设置请求头中的Range实体头,指定第一个字节的位置和最后一个字节的位置,而与之对应的响应头有Content-Range,指示了整个实体的长度及部分插入位置,如Content-Range: bytes 0-500/801,指定了范围为当前范围与文件总大小。

参考答案:A

-----------------可爱的分割线------------------


8、MVC优点不正确的是

A 低耦合性

B 高重用性和可适用性

C 较低的生命周期成本

D 代码高效率


理由:MVC只是一种构架设计模式,它的出现有比较久的历史了。Model-Controller-View是在开发中最常见到的架构设计模式,通过将Model、View、Controller三者相互联系,以Model作为数据加工厂,以Controller作为桥梁,处理业务,而View只是数据展示层,理应与业务无关。MVC设计模式降低了耦合性,提供了重用性和适用性,可有效地提高开发效率。

参考答案:D

-----------------可爱的分割线------------------


9、混编ObjC和C++的源码文件需要将文件格式的后缀改为

A .c

B .cpp

C .mm

D .m


理由:ObjC要想与C++源代码文件混编,那么就需要将文件后缀改为.mm。这个没有什么可细说了,记住就好了!

参考答案:C

-----------------可爱的分割线------------------


10、ObjC声明一个类所要用到的编译指令是

A @interface SomeClass

B @protocol SomeClass

C @implementation SomeClass

D @autorelease SomeClass


理由:A是声明类的指令;B是声明协议的指令;C是实现类的定义的指令;D是声明自动释放池的指令。

参考答案:A

-----------------可爱的分割线------------------


11、MRC文件在ARC工程混合编译时,需要在文件的Compiler Flags上添加什么参数

A -shared

B -fno-objc-arc

C -fobjc-arc

D -dynamic


理由:对于ARC工程中,如果要混编MRC文件,需要在工程的Compiler Flags添加-fno-bojc-arc;对于MRC工程中,如果要混编ARC文件,需要设置为-fobjc-arc。

参考答案:B

-----------------可爱的分割线------------------


12、下面关于Objective-C内存管理的描述错误的是

A 当使用ARC来管理内存时,代码中不可以出现autorelease

B autoreleasepool 在 drain 的时候会释放在其中分配的对象

C 当使用ARC来管理内存时,在线程中大量分配对象而不用autoreleasepool则可能会造成内存泄露

D 在使用ARC的项目中不能使用NSZone


理由:ARC只是在大多时候编译自动为我们添加上内存管理的代码,只是我们的源代码看不到而已,但是在编译时,编译器会添加上相关内存管理代码。对于自动释放池,在drain时会将自动释放池中的所有对象的引用计数减一,若引用计数为0,则会自动释放掉其内存。如果在线程中需要大量分配内存,我们理应添加上自动释放池,以防内存泄露。比如在for循环中要分配大量的内存处理数据,那么我们应该在for循环内添加自动释放池,在每个循环后就将内存释放掉,防止内存泄露。在ARC项目中,自然不能手动使用NSZone,也不能调用父类的dealloc。

参考答案:A

-----------------可爱的分割线------------------


13、下面哪个不属于对象数据序列化方法

A JSON

B Property List

C XML

D HTTP


理由:数据序列化是将对象的数据转化成某一种格式的数据,在ios开发中最常用的就是JSON,部分公司会采用XML,笔者从未遇到过使用Property List来传输数据的,但是我们通过会将一些小量的数据存储到Property List中,比如NSUserDefaults就是操作plist文件的。而HTTP是超文件传输协议,只是一种协议。

参考答案:D

-----------------可爱的分割线------------------


14、在UIKit中,frame与bounds的区别是

A. frame 是 bounds 的别名

B. frame 是 bounds 的继承类

C. frame 的参考系是父视图坐标,bounds 的参考系是自身的坐标

D. frame 的参考系是自身坐标,bounds 的参考系是父视图的坐标


理由:frame的参考系是父视图的坐标系,而bounds是参考自我的坐标系。修改父视图的bounds可以移动子视图。不过通常不会这么干法,如果父视图不需要移动,没有必要修改bounds,直接修改子视图的frame就可以实现了。

参考答案:C

-----------------可爱的分割线------------------


15、下面关于线程管理错误的是

A. GCD所用的开销要比NSThread大

B. 可以在子线程中修改UI元素

C. NSOperationQueue是比NSthread更高层的封装

D. GCD可以根据不同优先级分配线程


理由:首先,UI元素的更新必须在主线程。GCD与Block配合使用,block需要自动捕获上下文变量信息等,因此需要更多的资源,故比NSThread开销要大一些。NSOperationQueue与NSOperation配合使用,比NSThread更易于操作线程。GCD提供了多个优先级,我们可以根据设置优先级,让其自动为我们分配线程。

关系NSOperationQueue,请阅读文章:NSOperationQueue

参考答案:B

-----------------可爱的分割线------------------


最后

文章中难免有说得不合理的地方,如果您认为说法不正确或者哪里有错误的地方,请在评论中留言,笔者会在第一时间修正!!!

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信话费交错了怎么办 北京移动查话费余额怎么办 淘宝卖家客服无法联系怎么办? 微信支付月限额怎么办 微信超额20万怎么办 微信支付超额了怎么办 微信零钱超额了怎么办 微信的充值冲错了怎么办 有流量还扣话费怎么办 自动取款机充值到电子账户怎么办 淘宝qb充错了怎么办 q币冲错了人家不给怎么办 qq充值话费错号怎么办 qq充错号码了怎么办 qq交话费不到账怎么办 充错手机号码而且是空号怎么办 微信钱包充错话费怎么办 QQ充值话费充到空号了怎么办 给别人充错话费怎么办 用qq交错话费对方是空号怎么办 号码变成空号了怎么办 qq冲流量冲错了怎么办 流量冲错了套餐怎么办 微信流量充错号码怎么办 微信支付不进账怎么办 充话费充不进去怎么办 用支付宝充话费没到账怎么办 支付宝充话费未到账怎么办 话费充了不到账怎么办 转转买家不确认收货怎么办 充话费错了怎么办啊 淘宝充值流量没到账怎么办 微信手机充错了怎么办 支付宝充话费没到账怎么办 裤子摔了一个洞怎么办 顾客反应衣服质量不好怎么办 淘宝买的衣服味道很大怎么办 三国杀账号忘了怎么办 宽带连接被删了 怎么办 手机被偷了qq怎么办 手机丢了微信怎么办啊