iOS面试题

1.NSString如何计算字符的个数?

应该是用countElements的函数来统计字符串所包含的字符个数,把参数为要统计的字符串就好了。

但是需要注意以下的几个点:

1.因为不同的Unicode字符,同样的字符不同的编码都可能导致占用不同的内存。所以按正常来说,字符串中的每个字符会占用不同的内存。因此,只能通过遍历字符串中的每个字符来计算字符串的长度。但是当在处理一个特别长的字符串的话,可以通过遍历整个字符串,这样既可以算出字符串的长度了。

2.同一个字符串,countElements计算出来的字符个数与NSString的length计算出来的长度也不一定总是一样的的。因为NSString的长度是基UTF-16编码的编码来计算的,而不是Unicode编码的个数。但是,好像在Swift中可以使用字符串的utf16count属性来来获得原来NSString的length值,忘记了,很久没用Swift了。

2.PKI(公开密钥基础设施 Public Key Infrastructure)体系当中加密和签名有什么区别?

这个问题我来答的话,应该先说说PKI是一种安全技术, 数字签名和加密基本原理是什么,在说区别,话说基本原理我也不记得了,就大概记得一个HUSH函数什么的了,他们的过程都是使用公开密钥体系,但实现的过程是不同的,相反,使用的密钥对也不同。

1.数字签名是发送方的密钥对,发送方用自己的私有密钥进行加密,接收方用发送方的公开密钥进行解密,大致就是这样吧,它一个一对多的关系,任何拥有发送方公开密钥的人都可以验证数字签名的正确性,还有只采用了非对称密钥加密算法,能保证发送信息的完整性、身份认证和不可否认性。

2.数字加密是接收方的密钥对,这是多对一的关系,任何知道接收方公开密钥的人都可以向接收方发送加密信息,只有唯一拥有接收方私有密钥的人才能对信息解密,用的对称密钥加密算法和非对称密钥加密算法相结合的方法,它能保证发送信息保密性。

3.如何自己高效实现NSUserDefault?

这个,真心不知道,peak大大。只知道NSUserDefaults是定时把缓存中的数据写入磁盘的,而不是即时写入,为了防止在写完NSUserDefaults后程序退出导致的数据丢失,可以在写入数据后使用synchronize强制立即将数据写入磁盘,现在要高效的实现NSUserDefaults,个人见解就是不频繁的使用synchornize,自定义一个类,再存取时通过NSData做载体。

4.解释下tcp的慢启动特性。

现在公司应该都是在避免慢启动,做性能优化吧,优化应该可以尽量把大量小文件放在一个TCP连接中排队传输吧,没试验过,自己YY的。

这问的是Tcp慢启动的特点,难道就是它在新建立的连接不能够一开始就发送大尺寸的数据包,而只能从一个小尺寸的包开始发送,在发送和数据被对方确认的过程中去计算对方的接收速度,来逐步增加每次发送的数据量,但是这样的话 性能呢,请科普下,谢谢。

5.如何用HTTP实现长连接?

首先HTTP是无状态的,要维持一个长连接可以用心跳包啊,公司项目第一个版本就是这样用的,然后各种原因,各种呵呵呵,丢包,沾包,应该可以对http连接进行轮询,但是http定时轮询会存在延迟 用户体验就不好了 或者用socket流方法,监听服务器消息

6.HTTP2.0针对同一个域名的多个请求,会建立多少个tcp连接?

一个吗?不是很清楚啊。

7.数据库建表的时候索引有什么用?

创建索引可以大大提高系统的性能,加快数据的检索速度,加速表和表之间的连接,保证数据库表中每一行数据的唯一性,但是有些列不应该创建索引,这又要考虑到性能了,所以具体情况具体分析了。

8.Full Text Search为什么快?

这我不是后台不是很了解,问题偏后台系统多一点点了,但是自己会写一点点PHP,好像是用空间来换时间,通过分词器,降索引的表分割啥的,不是很清楚原理啊,看来要系统学下后台语言。

9.iOS下如何实现指定线程数目的线程池?

这个问题问的太深了吧,一般开发根本用不到,还好最近在看线程安全方面的书籍,要不然问到真的会懵逼。

1.循环通过pthread_create创建线程,创建s_tfthread对象做为线程句,加入线程数组,s_tftask_content->methord初始化为空函数

2.创建任务执行函数,执行完通过task初始化函数后,在执行函数中通过pthread_cond_wait信号将当前创建的线程挂起

3.创建完之后,程序中将会有n个挂起状态的线程,当需要执行新的task的时候查找,我们就可以根据不同的task标志在k_threads中查询出空闲线程,并创建新的s_tftask_content加入s_tfthread的任务列表,通过pthread_cond_signal重新唤醒该线程继续执行任务

10.介绍下iOS设备获取唯一设备号的历史变迁。

这个没做过几年开发的真心不知道,iOS中获取设备唯一标示符的方法一直随版本的更新而变化。iOS 2.0版本以后UIDevice提供一个获取设备唯一标识符的方法uniqueIdentifier,但是好像是iOS 4还是iOS5就被苹果废弃掉了,然后iOS6是用WiFi的mac地址来获取的,iOS7后大家都知道了,主要是由于苹果又坑爹了,封杀mac地址,但是推荐大家用KeyChain来保存获取到的UDID,因为APP删了再装回来,也可以从KeyChain中读取回来,哈哈,公司的项目都是把UDID存在KeyChain。

11.函数式编程当中的 first-class function是什么意思呢?

这个问题好像以前就在知乎看过,就是类型,定义了一个可以操作的取值的集合,就像C语言的int类型一样,可进行加减乘除等操作,但是它的设计又有一个模块复用和访存控制,这样设计的原因应该是让我们更好用吧,没有深究过这个。

12.如何使用runtime hook一个class的某个方法,又如何hook某个instance的方法?

做到这里在电脑码字快三十分钟了啊,peak大大,你问的问题都好难回答啊,要分各种情况。这题也是首先要考虑 hook是否有公开头文件的类,有的话写一个Utility函数,再使用category,没有的话就建一个类作为新函数载体,然后先为被hook的类增加函数,再替换,没错就是这个样子。后面如何h如何hook某个instance的方法,应该可以定义一个函数指针变量,hook时将要调用的地址赋给这个变量,调用时把这个变量当作函数来用就行了。

13.谈下Objective C都有哪些锁机制,你一般用哪个?

synchronized、NSLOCK、GCD、递归锁、分布锁、同步锁(这个是C语言的),一般用GCD,这里就不说了,真心不想码字了,peak大大可能会问,为什么,又要把各种锁机制对比,这我会疯,我脑袋要死机了,重启中…

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

http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE,刚好公司上个项目都用了这四种方式的请求,怎么都是踩过得坑。

form-urlencoded是默认的mime内容编码类型,是通用的,但是它在传输比较大的二进制或者文本数据时效率极低。

multipart/form-data是当上传文件或者二进制数据和非ASCII数据使用。

15.让你设计一种机制检测UIViewController的内存泄漏,你会怎么做?

这个问题没有考虑过,都是自己写单元测试什么的来测试,都是些基础的测试,一般都是用Instrument来测试一些东西的。自己设计的话,主要还是要考虑一个VC的生命周期。

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

应该是到@autoreleasepool 结束的时候才释放的,但是我都是用这imageWithContentsOfFile方法加载图片的

17.applicationWillEnterForeground和applicationDidBecomeActive都会在哪些场景下被调用?举例越多越好。

推送、做支付的时候,跳到人家运用,后台杀进程的时候、做IM的时候、第三方授权分享登录回调情况下等等

18.如何终止正在运行的工作线程?

在线程中调用exit、pthread_exit、pthread_kill、pthread_cance都行吧

19.穷举iOS下所有的本地持久化方案。

沙盒

plist文件(属性列表)

preference(偏好设置)

NSKeyedArchiver(归档)

SQLite 3

CoreData

推荐阅读更多精彩内容