美文网首页
一份"有点难"的iOS面试题

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

作者: Legendary | 来源:发表于2019-02-13 22:44 被阅读0次

    本文非原创,是看到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,你有什么心里话要对老板说吗?

    相关文章

      网友评论

          本文标题:一份"有点难"的iOS面试题

          本文链接:https://www.haomeiwen.com/subject/euszzftx.html