一份"有点难"的iOS面试题

2019-02-13  本文已影响0人  Legendary

本文非原创,是看到MrPeak大大出的题目

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

将一个NSString类型字符串获取的长度转换成类似ASCII编码的长度,如汉字2个字节,英文以及符号1个字节这个功能。由于使用[NSString length]方法调用获取的长度是一个中文和一个英文都是一个字节,而使用
[NSString lengthOfBytesUsingEncoding:NSASCIIStringEncoding] 方法无法识别中文编码,真是令人揪心。于是想获得一个char*类型的字符串,然后自己遍历一遍,将它整理为类似ASCII编码的格式,这里要用到[NSString cStringUsingEncoding:NSUnicodeStringEncoding]函数获得一个const char*指针,然后对这个字符串进行遍历,遇/0就跳过,否则length+1,下面是代码,拿出来与大家分享:
这里一定要使用gbk的编码方式,网上有很多用Unicode的,但是部分汉字计算字节数错误;比如开使用unicode编码计算出来为1个字节

NSString *text = @"Hello World! 你好,中国!";

计算以上string的长度:

NSLog(@"text.length = %lu",text.length);

得到的结果为19,明显中文符号算为1的长度。

- (int)convertToInt:(NSString*)strtemp//判断中英混合的的字符串长度
{
    int strlength = 0;
    char *p = (char *)[strtemp cStringUsingEncoding:NSUnicodeStringEncoding];
    for (int i=0; i < [strtemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding]; i++) {
        if (*p) {
            p++;
            strlength++;
        }
        else {
            p++;
        }
    }
    return strlength;
}
NSLog(@"len = %d",[self convertToInt:text]);

结算结果为:25字节。

2.PKI体系当中加密和签名有什么区别?
3.如何自己高效实现NSUserDefault?

数据量一大读取成本就高,敏感数据容易被破解,因为NSUserDefault实际上是明文存在 plist 中的,所以建议用户安全相关的(如 token)尽量不要放在 UserDefault 中,即使要存也最好做一次加密再存,最好的方式是存在 Keychain 中。UserDefault 更适合存一些轻量的数据,如当前版本(可用来做检测更新以及展示欢迎页或其他逻辑)。建议使用 Sqlite 或其他数据存储方式

4.解释下tcp的慢启动特性。
5.如何用HTTP实现长连接?

首先,http能实现长连接,是建立在tcp协议的基础上的。但http中,其实没有长连接这样的类型。保持一个tcp连接是长连接。完全是通过程序员手动来控制的。
如果程序员,想让一个http连接,比如该连接叫A,让A成为一个长连接。
那么,就不调用该连接的close()方法。
直到,不再需要A连接的时候,才关闭该连接。
那么,A就叫做一个长连接
HTTP连接分为两种:
HTTP短连接(非持久连接)是指,客户端和服务端进行一次HTTP请求/响应之后,就关闭连接。所以,下一次的HTTP请求/响应操作就需要重新建立连接。
HTTP长连接(持久连接)是指,客户端和服务端建立一次连接之后,可以在这条连接上进行多次请求/响应操作。持久连接可以设置过期时间,也可以不设置。
HTTP短连接
在首部字段中设置Connection:close,则在一次请求/响应之后,就会关闭连接。
HTTP长连接
在首部字段中设置Connection:keep-alive 和Keep-Alive: timeout=60,表明连接建立之后,空闲时间超过60秒之后,就会失效。如果在空闲第58秒时,再次使用此连接,则连接仍然有效,使用完之后,重新计数,空闲60秒之后过期。
设置HTTP长连接,无过期时间
在首部字段中只设置Connection:keep-alive,表明连接永久有效。
实现原理:
了解怎么设置之后,就开始用起来。然而,问题来了。在请求头中设置Connection:keep-alive,为什么连接空闲一段时间之后,还是断开了呢?这是因为connection字段只有服务端设置才有效。
HTTP操作是请求/响应成对出现的,即先有客户端发出请求,后有服务端处理请求。所以,一次HTTP操作的终点操作在服务端上,关闭也是由服务端发起的。

6.HTTP2.0针对同一个域名的多个请求,会建立多少个tcp连接?
7.数据库建表的时候索引有什么用?
8.Full Text Search为什么快?
9.iOS下如何实现指定线程数目的线程池?
10.介绍下iOS设备获取唯一设备号的历史变迁。

iOS中获取设备唯一标示符的方法一直随版本的更新而变化
但是,推荐大家用KeyChain来保存获取到的UDID,因为APP删了再装回来,也可以从KeyChain中读取回来,哈哈,公司的项目都是把UDID存在KeyChain。(SAMKeychain)

image
11.函数式编程当中的 first-class function是什么意思呢?
12.如何使用runtime hook一个class的某个方法,又如何hook某个instance的方法?

首先要考虑 hook是否有公开头文件的类
方法一,hook已有公开头文件的类,写一个Utility函数.
方法二,hook没有公开头文件的类,需要另建一个类作为新函数载体,然后先为被hook的类增加函数,再替换。
方法三,hook没有公开头文件的类,另建一个类作为新函数载体,用新函数替换旧函数,并把旧函数保存到静态变量里.

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

iOS开发中常用的锁有如下几种:

  1. @synchronized 同步锁
  2. NSLock 对象锁
  3. NSRecursiveLock 递归锁
  4. NSConditionLock 条件锁
  5. pthread_mutex 互斥锁(C语言)
  6. dispatch_semaphore 信号量实现加锁(GCD)
  7. OSSpinLock 参考YY
14.聊下HTTP post的body体使用form-urlencoded和multipart/form-data的区别。

http与服务器交互最常用的就是GET,POST两个方法.
1.application/x-www-form-urlencoded:
这是标准且默认的编码格式。当action为get时候,客户端把form数据转换成一个字串append到url后面,用?分割。当action为post时候,浏览器把form数据封装到http body中,然后发送到server。
2.multipart/form-data:
multipart表示的意思是单个消息头包含多个消息体的解决方案。multipart媒体类型对发送非文本的各媒体类型是有用的。一般多用于文件上传。

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

一般都是用Instrument来测试的.

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

为了方便,一开始读取图像资源的时候都是直接使用了[UIImage imageNamed:@""]方法,这个方法非常方便,一句话就可以从bundle中读取图片。而[UIImage imageNamed:]只适合与UI界面中小的贴图的读取,而一些比较大的资源文件应该尽量避免使用这个接口。使用[UIImage imageWithContentsOfFile]替代.
类方法创建的会自动加入到自动释放池中。

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

当程序进入后台状态时,名为applicationWillEnterForeground委托方法会被调用:
-(void)applicationWillEnterForeground:(UIApplication *)application { }
当程序复原时,applicationDidBecomeActive 委托方法会被调用
推送、支付、应用跳转、分享、退到后台等.

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

一般来讲网络操作都是可以终止的,就 URLSession 来说,每个 task 都有 cancel 方法,直接 cancel 掉就好了。如果说是耗时的计算类线程,在恰当的地方加个 flag,cancel 时把 flag 置 false,线程就能及时终止。但是,GCD本身是没有提供这样的API的。
终止一个线程中正在执行的任务:
设置一个标识符,假如是BOOL类型的,当它为NO的时候执行任务,当它变为YES的时候终止执行任务。

dispatch_async(dispatch_get_global_queue(0, 0), ^{
        for (NSInteger i = 0; i < 10000; i++) {
            NSLog(@"%lu",(long)i);
            sleep(2);
            if (flag == YES) {
                NSLog(@"终止任务...");
            }
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"回到主线程刷新UI");
        });
    });
19.穷举iOS下所有的本地持久化方案。

所有的本地持久化数据存储的本质都是写文件,而且只能存到沙盒中。
沙盒机制是苹果的一项安全机制,本质就是系统给每个应用分配了一个文件夹来存储数据,而且每个应用只能访问分配给自己的那个文件夹,其他应用的文件夹是不能访问的。
数据存储的核心都是写文件。主要有四种持久化方式:属性列表,对象序列化,SQLite 数据库, CoreData

20.如果公司强制996,你有什么心里话要对老板说吗?
上一篇下一篇

猜你喜欢

热点阅读