ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

iOS面试合集+答案(一)

2021-07-21 20:58:05  阅读:146  来源: 互联网

标签:文件 HTTP 请求 iOS 面试 服务器 合集 加载


这个栏目将持续更新–请iOS的小伙伴关注!


(答案不唯一,仅供参考,文章最后有福利)

一.HTTP post的body体使用form-urlencoded和multipart/form-data的区别。


1)application/x-www-form-urlencoded:
窗体数据被编码为名称/值对,这是标准且默认的编码格式。当action为get时候,客户端把form数据转换成一个字串append到url后面,用?分割。当action为post时候,浏览器把form数据封装到http body中,然后发送到server。

2)multipart/form-data:
multipart表示的意思是单个消息头包含多个消息体的解决方案。multipart媒体类型对发送非文本的各媒体类型是有用的。一般多用于文件上传。
multipart/form-data只是multipart的一种。目前常用的有以下这些类型(注:任何一种执行时无法识别的multipart子类型都被视为子类型"mixed")

二.给你1w让你设计一种机制检测UIViewController的内存泄漏,你会怎么做


如果Controller被释放了,但其曾经持有过的子对象如果还存在,那么这些子对象就是泄漏的可疑目标。

一个小示例:子对象(比如view)建立一个对controller的weak引用,如果Controller被释放,这个weak引用也随之置为nil。那怎么知道子对象没有被释放呢?用一个单例对象每个一小段时间发出一个ping通知去ping这个子对象,如果子对象还活着就会一个pong通知。所以结论就是:如果子对象的controller已不存在,但还能响应这个ping通知,那么这个对象就是可疑的泄漏对象。

三.[通过[UIImage imageNamed:]生成的对象什么时候被释放?]


使用imageNamed这个方法生成的UIImage对象,会在应用的bundle中寻找图片,如果找到则Cache到系统缓存中,作为内存的cache,而程序员是无法操作cache的,只能由系统自动处理,如果我们需要重复加载一张图片,那这无疑是一种很好的方式,因为系统能很快的从内存的cache找到这张图片,但是试想,如果加载很多很大的图片的时候,内存消耗过大的时候,就会会强制释放内存,即会遇到内存警告(memory warnings).

由于在iOS系统中释放图片的内存比较麻烦,所以冲易产生内存泄露。
像[[UIImageView alloc] init]还有一些其他的 init 方法,返回的都是 autorelease 对象。而 autorelease 不能保证什么时候释放,所以不一定在引用计数为 0 就立即释放,只能保证在 autoreleasepool 结尾的时候释放。

像 UIImage 还有 NSData 这种,大部分情况应该是延迟释放的,可以理解为到 autoreleasepool 结束的时候才释放。

四.applicationDidBecomeActive和applicationWillEnterForeground在哪些场景下被调用呢?举例越多越好


1)applicationWillResignActive(将进入后台)
对应applicationWillEnterForeground(将进入前台)
程序将要失去Active状态时调用,比如按下Home键或有电话信息进来,这个方法用来

  • 暂停正在执行的任务;
  • 禁止计时器;
  • 减少OpenGL ES帧率;
  • 若为游戏应暂停游戏;

总结为一个字:停!
2)applicationDidEnterBackground(已经进入后台)
对应applicationDidBecomeActive(已经变成前台)
程序已经进入后台时调用,这个方法用来

  • 释放共享资源;
  • 保存用户数据(写到硬盘);
  • 作废计时器;
  • 保存足够的程序状态以便下次恢复;总结为4个字:释放、保存!

五.dSYM我们可以如何分析的


方法1 使用XCode

这种方法可能是最容易的方法了。

  1. 要使用Xcode符号化 crash log,你需要下面所列的3个文件:
  2. crash报告(.crash文件)
  3. 符号文件 (.dsymb文件)
  4. 应用程序文件 (appName.app文件,把IPA文件后缀改为zip,然后解压,
  5. 4.Payload目录下的appName.app文件), 这里的appName是你的应用程序的名称。
  6. 把这3个文件放到同一个目录下,打开Xcode的Window菜单下的organizer,然后点击Devices tab,然后选中左边的Device Logs。
  7. 然后把.crash文件拖到Device Logs或者选择下面的import导入.crash文件。
    这样你就可以看到crash的详细log了。

方法2 使用命令行工具symbolicatecrash

  1. 有时候Xcode不能够很好的符号化crash文件。我们这里介绍如何通过symbolicatecrash来手动符号化crash log。
  2. 在处理之前,请依然将“.app“, “.dSYM”和 ".crash"文件放到同一个目录下。现在打开终端(Terminal)然后输入如下的命令:
  3. export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  4. 然后输入命令:
  5. /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash appName.crash appName.app > appName.log
  6. 现在,符号化的crash log就保存在appName.log中了。

方法3 使用命令行工具atos

  1. 如果你有多个“.ipa”文件,多个".dSYMB"文件,你并不太确定到底“dSYMB”文件对应哪个".ipa"文件,那么,这个方法就非常适合你。
  2. 特别当你的应用发布到多个渠道的时候,你需要对不同渠道的crash文件,写一个自动化的分析脚本的时候,这个方法就极其有用。
  3. 具体方法 请百度

六.多线程有哪几种?你更倾向于哪一种?


  1. NSThread
  2. Cocoa NSOperation (使用NSOperation和NSOperationQueue)
  3. GCD (Grand Central Dispatch)`

1.NSThread:(两种创建方式)

1. [NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];
2.
3.NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
4.
5.[myThread start];
6.

优点:NSThread 比其他两个轻量级。 缺点:需要自己管理线程的生命周期,线程同步,线程同步时对数据的加锁会有一定的系统开销。

2.Cocoa Operation

1.NSOperationQueue*oprationQueue= [[NSOperationQueuealloc] init];
2.
3.oprationQueueaddOperationWithBlock:^{
4.
5.//这个block语句块在子线程中执行
6.
7.}

优点:不需要关心线程管理,数据同步的事情。 Cocoa Operation 相关的类是 NSOperation ,NSOperationQueue。NSOperation是个抽象类,使用它必须用它的子类,可以实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行,我们会把我们的执行操作放在NSOperation中main函数中。

3.GCD Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术的很高效和强大的技术。它让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务,一个任务可以是一个函数(function)或者是一个block。 dispatch queue分为下面三种: private dispatch queues,同时只执行一个任务,通常用于同步访问特定的资源或数据。 global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。 Main dispatch queue 它是在应用程序主线程上执行任务的。

七.单例的弊端

优点:
1:一个类只被实例化一次,提供了对唯一实例的受控访问。
2:节省系统资源
3:允许可变数目的实例。
缺点:
1:一个类只有一个对象,可能造成责任过重,在一定程度上违背了“单一职责原则”。
2:由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
3:滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。

八.App启动过慢,因素有哪些?欢迎讨论。

1. App启动过程

  1. 解析Info.plist
  • 加载相关信息,例如如闪屏
  • 沙箱建立、权限检查
  1. Mach-O加载
  • 如果是胖二进制文件,寻找合适当前CPU类别的部分
  • 加载所有依赖的Mach-O文件(递归调用Mach-O加载的方法)
  • 定位内部、外部指针引用,例如字符串、函数等
  • 执行声明为attribute((constructor))的C函数
  • 加载类扩展(Category)中的方法
  • C++静态对象加载、调用ObjC的 +load 函数
  1. 程序执行
  • 调用main()
  • 调用UIApplicationMain()
  • 调用applicationWillFinishLaunching

2、影响启动性能的因素

  1. main()函数之前耗时的影响因素
  • 动态库加载越多,启动越慢。
  • ObjC类越多,启动越慢
  • C的constructor函数越多,启动越慢
  • C++静态对象越多,启动越慢
  • ObjC的+load越多,启动越慢
  1. main()函数之后耗时的影响因素
  • 执行main()函数的耗时
  • 执行applicationWillFinishLaunching的耗时
  • rootViewController及其childViewController的加载、view及其subviews的加载

另外参考一下今日头条的启动优化方案

针对于今日头条这个App我们可以优化的点如下:

  • 纯代码方式而不是storyboard加载首页UI。
  • 对didFinishLaunching里的函数考虑能否挖掘可以延迟加载或者懒加载,需要与各个业务方pm和rd共同check 对于一些已经下线的业务,删减冗余代码。
  • 对于一些与UI展示无关的业务,如微博认证过期检查、图片最大缓存空间设置等做延迟加载。
    对实现了+load()方法的类进行分析,尽量将load里的代码延后调用。
  • 上面统计数据显示展示feed的导航控制器页面(NewsListViewController)比较耗时,对于viewDidLoad以及viewWillAppear方法中尽量去尝试少做,晚做,不做。

九.如何防止反编译?

  1. 本地数据加密。
  • iOS应用防反编译加密技术之一:对NSUserDefaults,sqlite存储文件数据加密,保护帐号和关键信息
  1. URL编码加密。
  • iOS应用防反编译加密技术之二:对程序中出现的URL进行编码加密,防止URL被静态分析
  1. 网络传输数据加密。
  • iOS应用防反编译加密技术之三:对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取数据
  1. 方法体,方法名高级混淆。
  • iOS应用防反编译加密技术之四:对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码
  1. 程序结构混排加密。
  • iOS应用防反编译加密技术之五:对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低

十.UDP和TCP的区别于联系

  • TCP为传输控制层协议,为面向连接、可靠的、点到点的通信;
  • UDP为用户数据报协议,非连接的不可靠的点到多点的通信;
  • TCP侧重可靠传输,UDP侧重快速传输。

十一.TCP连接的三次握手

第一次握手:客户端发送 syn 包(syn=j)到服务器,并进入 SYN_SEND 状态,等待服务器确认;

第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP 连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开 TCP 连接的请求,断开过程需要经过“四次握手”(过程就不细写了,就是服务器和客户端交互,最终确定断开)
请添加图片描述

十二.Scoket连接和HTTP连接有什么区别


区别:

  • HTTP协议是基于TCP连接的,是应用层协议,主要解决如何包装数据。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

  • HTTP连接:短连接,客户端向服务器发送一次请求,服务器响应后连接断开,节省资源。服务器不能主动给客户端响应(除非采用HTTP长连接技术),iPhone主要使用类NSURLConnection。

  • Socket连接:长连接,客户端跟服务器端直接使用Socket进行连接,没有规定连接后断开,因此客户端和服务器段保持连接通道,双方可以主动发送数据,一般多用于游戏.Socket默认连接超时时间是30秒,默认大小是8K(理解为一个数据包大小)。

十三.HTTP协议的特点,关于HTTP请求GET和POST的区别

GET和POST的区别:

  • HTTP超文本传输协议,是短连接,是客户端主动发送请求,服务器做出响应,服务器响应之后,链接断开。HTTP是一个属于应用层面向对象的协议,HTTP有两类报文:请求报文和响应报文。

  • HTTP请求报文:一个HTTP请求报文由请求行、请求头部、空行和请求数据4部分组成。

  • HTTP响应报文:由三部分组成:状态行、消息报头、响应正文。

  • GET请求:参数在地址后拼接,没有请求数据,不安全(因为所有参数都拼接在地址后面),不适合传输大量数据(长度有限制,为1024个字节)。

GET提交、请求的数据会附在URL之后,即把数据放置在HTTP协议头< requestline>中。以分割URL和传输数据,多个参数用&连接。如果数据是英文字母或数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密。

  • POST请求:参数在请求数据区放着,相对GET请求更安全,并且数据大小没有限制。把提交的数据放置在HTTP包的包体< request-body>中.

  • GET提交的数据会在地址栏显示出来,而POST提交,地址栏不会改变。

传输数据的大小:

  • GET提交时,传输数据就会受到URL长度限制,POST由于不是通过URL传值,理论上书不受限。

安全性:

  • POST的安全性要比GET的安全性高;

  • 通过GET提交数据,用户名和密码将明文出现在URL上,比如登陆界面有可能被浏览器缓存。

  • HTTPS:安全超文本传输协议(Secure Hypertext Transfer Protocol),它是一个安全通信通道,基于HTTP开发,用于客户计算机和服务器之间交换信息,使用安全套结字层(SSL)进行信息交换,即HTTP的安全版。

十四.AFNetWorking、ASIHttpRequest两者的区别

  • ASIHttpRequest功能强大,主要是在MRC下实现的,是对系统CFNetwork API进行了封装,支持HTTP协议的CFHTTP,配置比较复杂,并且ASIHttpRequest框架默认不会帮你监听网络改变,如果需要让ASIHttpRequest帮你监听网络状态改变,并且手动开始这个功能。

  • AFNetWorking构建于NSURLConnection、NSOperation以及其他熟悉的Foundation技术之上。拥有良好的架构,丰富的API及模块构建方式,使用起来非常轻松。它基于NSOperation封装的,AFURLConnectionOperation子类。

  • ASIHttpRequest是直接操作对象ASIHttpRequest是一个实现了NSCoding协议的NSOperation子类;AFNetWorking直接操作对象的AFHttpClient,是一个实现NSCoding和NSCopying协议的NSObject子类。

  • 同步请求:ASIHttpRequest直接通过调用一个startSynchronous方法;AFNetWorking默认没有封装同步请求,如果开发者需要使用同步请求,则需要重写getPath:paraments:success:failures方法,对于AFHttpRequestOperation进行同步处理。

  • 性能对比:AFNetworking请求优于ASIHttpRequest;

十五.XML有各有什么不同的数据解析方式,JSON解析有哪些框架?(iOS面试题)

  • XML数据解析的两种解析方式:DOM解析和SAX解析;

  • DOM解析必须完成DOM树的构造,在处理规模较大的XML文档时就很耗内存,占用资源较多,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过遍历树结构可以检索任意XML节点,读取它的属性和值,通常情况下,可以借助XPath查询XML节点;

  • SAX与DOM不同,它是事件驱动模型,解析XML文档时每遇到一个开始或者结束标签、属性或者一条指令时,程序就产生一个事件进行相应的处理,一边读取XML文档一边处理,不必等整个文档加载完才采取措施,当在读取解析过程中遇到需要处理的对象,会发出通知进行处理。因此,SAX相对于DOM来说更适合操作大的XML文档。
    -JSON解析:性能比较好的主要是第三方的JSONKIT和iOS自带的JSON解析类,其中自带的JSON解析性能最高,只能用于iOS5之后。

十六.SVN的使用

  • SVN=版本控制+备份服务器,可以把SVN当成备份服务器,并且可以帮助你记住每次上服务器的档案内容,并自动赋予每次变更的版本;

  • SVN的版本控制:所有上传版本都会帮您记录下来,也有版本分支及合并等功能。SVN可以让不同的开发者存取同样的档案,并且利用SVN Server作为档案同步的机制,即您有档案更新时,无需将档案寄送给您的开发成员。SVN的存放档案方式是采用差异备份的方式,即会备份到不同的地方,节省硬盘空间,也可以对非文字文件进行差异备份。

  • SVN的重要性:备份工作档案的重要性、版本控管的重要性、伙伴间的数据同步的重要性、备份不同版本是很耗费硬盘空间的;

  • 防止冲突:
    1.防止代码冲突:不要多人同时修改同一文件,例如:A、B都修改同一个文件,先让A修改,然后提交到服务器,然后B更新下来,再进行修改;
    2.服务器上的项目文件Xcodeproj,仅让一个人管理提交,其他人只更新,防止文件发生冲突。

十七.如何高效的进行网络消息的推送

  • 一种是Apple自己提供的通知服务(APNS服务器)、一种是用第三方推送机制。

  • 首先应用发送通知,系统弹出提示框询问用户是否允许,当用户允许后向苹果服务器(APNS)请求deviceToken,并由苹果服务器发送给自己的应用,自己的应用将DeviceToken发送自己的服务器,自己服务器想要发送网络推送时将deviceToken以及想要推送的信息发送给苹果服务器,苹果服务器将信息发送给应用。

  • 推送信息内容,总容量不超过256个字节;

  • iOS SDK本身提供的APNS服务器推送,它可以直接推送给目标用户并根据您的方式弹出提示。
    优点:不论应用是否开启,都会发送到手机端;
    缺点:消息推送机制是苹果服务端控制,个别时候可能会有延迟,因为苹果服务器也有队列来处理所有的消息请求;

  • 第三方推送机制,普遍使用Socket机制来实现,几乎可以达到即时的发送到目标用户手机端,适用于即时通讯类应用。
    优点:实时的,取决于心跳包的节奏;
    缺点:iOS系统的限制,应用不能长时间的后台运行,所以应用关闭的情况下这种推送机制不可用。

十八.网络七层协议

  • 应用层:
    1.用户接口、应用程序;
    2.Application典型设备:网关;
    3.典型协议、标准和应用:TELNET、FTP、HTTP

  • 表示层:
    1.数据表示、压缩和加密presentation
    2.典型设备:网关
    3.典型协议、标准和应用:ASCLL、PICT、TIFF、JPEG|MPEG
    4.表示层相当于一个东西的表示,表示的一些协议,比如图片、声音和视频MPEG。

  • 会话层:
    1.会话的建立和结束;
    2.典型设备:网关;
    3.典型协议、标准和应用:RPC、SQL、NFS、X WINDOWS、ASP

  • 传输层:
    1.主要功能:端到端控制Transport;
    2.典型设备:网关;
    3.典型协议、标准和应用:TCP、UDP、SPX

  • 网络层:
    1.主要功能:路由、寻址Network;
    2.典型设备:路由器;
    3.典型协议、标准和应用:IP、IPX、APPLETALK、ICMP;

  • 数据链路层:
    1.主要功能:保证无差错的疏忽链路的data link;
    2.典型设备:交换机、网桥、网卡;
    3.典型协议、标准和应用:802.2、802.3ATM、HDLC、FRAME RELAY;

  • 物理层:
    1.主要功能:传输比特流Physical;
    2.典型设备:集线器、中继器
    3.典型协议、标准和应用:V.35、EIA/TIA-232.

十九.知道关键字volatile有什么含意?

  • 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
    • 并行设备的硬件寄存器(如:状态寄存器);
    •一个中断服务子程序中会访问到的非自动变量(Non-automatic variables);
    • 多线程应用中被几个任务共享的变量。

二十.属性property修饰符的作用

  • getter=getName、setter=setName:设置setter与getter的方法名;

  • readwrite、readonly:设置可供访问级别;

  • assign:方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题;

  • retain:其setter方法对参数进行release旧值再* retain新值,所有实现都是这个顺序;

  • copy:其setter方法进行copy操作,与retain处理流程一样,先对旧值release,再copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。

  • nonatomic:非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。

(一)完 持续更新哦~

传送门

iOS面试资料大全 (https://docs.qq.com/doc/DZlphVG9SU0FwUmVZ )

标签:文件,HTTP,请求,iOS,面试,服务器,合集,加载
来源: https://blog.csdn.net/IOSNF/article/details/118974497

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有