一.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
这种方法可能是最容易的方法了。
- 要使用Xcode符号化 crash log,你需要下面所列的3个文件:
- crash报告(.crash文件)
- 符号文件 (.dsymb文件)
- 应用程序文件 (appName.app文件,把IPA文件后缀改为zip,然后解压,Payload目录下的appName.app文件), 这里的appName是你的应用程序的名称。
- 把这3个文件放到同一个目录下,打开Xcode的Window菜单下的organizer,然后点击Devices tab,然后选中左边的Device Logs。
- 然后把.crash文件拖到Device Logs或者选择下面的import导入.crash文件。
- 这样你就可以看到crash的详细log了。
方法2 使用命令行工具symbolicatecrash
- 有时候Xcode不能够很好的符号化crash文件。我们这里介绍如何通过symbolicatecrash来手动符号化crash log。
- 在处理之前,请依然将“.app“, “.dSYM”和 ".crash"文件放到同一个目录下。现在打开终端(Terminal)然后输入如下的命令:
- export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
- 然后输入命令:
- /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash appName.crash appName.app > appName.log
- 现在,符号化的crash log就保存在appName.log中了。
方法3 使用命令行工具atos
- 如果你有多个“.ipa”文件,多个".dSYMB"文件,你并不太确定到底“dSYMB”文件对应哪个".ipa"文件,那么,这个方法就非常适合你。
- 特别当你的应用发布到多个渠道的时候,你需要对不同渠道的crash文件,写一个自动化的分析脚本的时候,这个方法就极其有用。
- 具体方法 请百度
六.多线程有哪几种?你更倾向于哪一种?
- NSThread
- Cocoa NSOperation (使用NSOperation和NSOperationQueue)
- 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 它是在应用程序主线程上执行任务的。
七.单例的弊端
优点:
- 一个类只被实例化一次,提供了对唯一实例的受控访问。
- 节省系统资源
- 允许可变数目的实例。
缺点:
- 一个类只有一个对象,可能造成责任过重,在一定程度上违背了“单一职责原则”。
- 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
- 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。
八.App启动过慢,因素有哪些?欢迎讨论。
1.App启动过程
- 解析Info.plist
- 加载相关信息,例如如闪屏
- 沙箱建立、权限检查
- Mach-O加载
- 如果是胖二进制文件,寻找合适当前CPU类别的部分
- 加载所有依赖的Mach-O文件(递归调用Mach-O加载的方法)
- 定位内部、外部指针引用,例如字符串、函数等
- 执行声明为attribute((constructor))的C函数
- 加载类扩展(Category)中的方法
- C++静态对象加载、调用ObjC的 +load 函数
- 程序执行
- 调用main()
- 调用UIApplicationMain()
- 调用applicationWillFinishLaunching
2、影响启动性能的因素
- main()函数之前耗时的影响因素
- 动态库加载越多,启动越慢。
- ObjC类越多,启动越慢
- C的constructor函数越多,启动越慢
- C++静态对象越多,启动越慢
- ObjC的+load越多,启动越慢
- 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存储文件数据加密,保护帐号和关键信息
2.URL编码加密。
- iOS应用防反编译加密技术之二:对程序中出现的URL进行编码加密,防止URL被静态分析
3.网络传输数据加密。
- iOS应用防反编译加密技术之三:对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取数据
4.方法体,方法名高级混淆。
- iOS应用防反编译加密技术之四:对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码
5.程序结构混排加密。
- 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:非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。
传送门: