2021iOS面试题总结day4

准备:
1.weex

Weex 致力于使开发者能基于通用跨平台的 Web 开发语言和开发经验,来构建 Android、iOS 和 Web 应用。简单来说,在集成了 WeexSDK 之后,你可以使用 JavaScript 语言和前端开发经验来开发移动应用。

2.iOS 架构设计

MVC
MVVM

3.Vue
4.Swift

今日面试问题:

1.UIWindow的切换方式有哪些?

刚开始面试官问我如何切换UIWindow,我不太明白,UIWindow不是一般只有一个吗,后来他解释说比如主页面切换到登录注册页面。我想了一下平时切换页面不都是切换的UIViewController吗,为什么会直接切换整个UIWindow,我以为是有这种方法而我不知道,所以没有答出来。后来才反应过来,面试官想问的可能是UIWindow的rootViewController的切换方式,我在项目中是把登录、注册还有回到主页封装成了一个工具类,这几个页面的切换方式有push、pop、present、dissmiss,也可以直接改变rootViewController,每种切换方式也可以分别设置他们的动画效果。

2.NSTimer在倒计时的过程中文字为什么会消失,如何解决?

答:当NSTimer运行在NSDefaultRunLoopMode下的时候会因为RunLoopMode的改变而无法正常工作。需要切换到NSRunLoopCommonModes才能保证NSTimer在NSDefaultRunLoopMode和UITrackingRunLoopMode下正常工作。解决办法就是使用GCD。

总结:倒计时功能以前在项目中经常使用,比如抢购、秒杀,第一次用倒计时的时候确实出现过文字消失倒计时不准确之类的问题,当时只是去网上找了解决办法的源码,直接粘贴到项目里了,没有去深究产生问题的原因,所以导致现在还没有真正理解GCD的用途。还有周一面试官也问我了关于NSTimer的问题,问的是在TableView中使用NSTimer,实际上这两个问题是一样的,都是用GCD来解决,开辟一个线程(dispatch_async),然后回到主线程刷新UI(dispatch_get_main_queue)。

3.NSUserDefaults是如何存储网络图片到本地的,又如何从本地读取显示出来的?SDWebImage的底层原理。

答:将图片转换成二进制数据,再把二进制数据通过NSUserDefaults存到本地,读取时先通过先通过NSUserDefaults取到二进制数据,再把二进制数据转换成图片。

图片转为二进制数据的方法:UIImageJPEGRepresentation
二进制数据转为图片的方法:imageWithData

SDWebImage加载图片的过程大致如下:

1.从内存(字典)中找图片(当这个图片在本次使用程序的过程中已经被加载过),找到直接使用。
2.从沙盒中找(当这个图片在之前使用程序的过程中被加载过),找到使用,缓存到内存中。
3.从网络上获取,使用,缓存到内存,缓存到沙盒。

总结:面试官问我平时用NSUserDefaults存的都是什么,我回答了用户名还有头像,问我是用什么类型存的,我答了字符串,问我头像怎么是用字符串存的,我还答了个图片地址就是字符串。这么基础的问题都答错确实不应该。之前做项目头像都是从网络下载的,没存过本地,把这个方法忽略了。后来面试官提示我把网断了图片是不是加载不出来了,还给我讲了SDWebImage的底层是通过网络加载的,这些我都明白,就是没说二进制的事,而且以前做本地相册上传的时候也都是把图片先转换成二进制,换了个场景就想不起来了。把题答成这样估计面试官都得怀疑我是刚毕业的了。

4.TCP、UDP的区别,都是怎么连接的?

答:TCP协议是一种可靠的通信协议,它要求传输的过程是可靠的,因此需要经过三次握手的环节,确立连接关系之后,才可以进行传输。除此之外,TCP还有超时重传机制,还有排序的机制,有发送的窗口,有窗口大小等等,保证接收方接收到的就是发送方发送过去的。

UDP是一种不可靠的通信协议,它不需要建立连接,不需要对连接进行确认ACK的操作,不需要重传,不需要排序,它只管传输。

总结:我只答出了TCP是可靠的、传输层协议,UDP是面向用户数据报的不可靠的协议。面试官又问我他们都是怎么连接的,我说了TCP是三次握手,UDP就不知道了,面试官直接告诉我UDP是不用连接的。

5.代理和通知在开发中具体是怎么应用的?delegate、Notification、KVC和KVO的区别?

看了一下我的项目中用到代理的地方:

1.实现系统类自带协议里的方法,实现系统类的自带功能,比如TableView的Delegate,可以设置TableView的Cell的高度,等等。
2.实现自定义协议里的方法,给自定义的类增加功能。一个类向另一个类传递消息。比如自定义一个关于支付的代理,需在多个页面实现支付功能都可以用这个代理。

用到通知的地方:

1.支付完成时点击回到首页,给首页发送通知,根据需求自动切换分类。
2.ScrollView嵌套TableView的时候出现滑动冲突,可以使用通知,在TableView滑动的时候禁用ScrollView滑动。
3.滑动ScrollView改变导航栏透明度,使用通知监听页面的位移。
4.人脸认证成功完成以后给认证页面返回认证完成的消息(因为人脸认证完成的回调在AppDelegate中)。
5.监听网络状态的变化。

用到KVC的地方:
1.对私有变量进行赋值:如用max.floatValue取一个数组中的最大值并转换为字符串。
2.字典转模型。

用到KVO的地方:

1.日历选择监听日期的选中、头尾标记来控制点击日历的颜色变化。
2.商品详情页面监听WKWebView的位移来控制页面的上拉查看图文详情,下拉返回商品详情。
3.WKWebView通过监听加载进度实现进度条。

delegate:是一种设计模式。是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。
Notification:任何对象对可以发送通知到中心,同时任何对象可以监听中心的通知。
KVC:全称是Key-value coding,翻译成键值编码。使用字符串去访问一个对象实例变量的机制。
KVO:全称是Key-value observing,翻译成键值观察。当其它对象属性被修改的时候能通知当前对象的机制。

总结:答题的时候我把Notification和KVO搞混了,观察者模式是KVO不是Notification,Notification Center是消息中心,还有让我举出来具体的应用我一时想不起来,回家看了代码才想起来哪些地方用了。应该记住具体的应用场景,以后别人问的时候可以马上说出来。

6.cookie是做什么用的,在代码中如何使用?

用于保存登录状态信息

我的项目中在WKWebView中使用了Cookie

NSString *cookie = [NSString stringWithFormat:@"num=1"];
WKUserScript *cookieScript = [[WKUserScript alloc]initWithSource: [NSString stringWithFormat:@"document.cookie = '%@';",cookie]injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[self.webView.wkWebView.configuration.userContentController addUserScript:cookieScript];

关键代码:WKUserScript

这种方法是在创建WKWebView的时候添加cookie

第二种:加载某个url的时候添加cookie,需要先手动获取当前NSHTTPCookieStorage中的所有cookie,然后将cookie放到NSMutableURLRequest请求头中

NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];

    for (NSHTTPCookie *cookie in [cookieJar cookies]) {

        [cookieDic setObject:cookie.value forKey:cookie.name];

    }

    // cookie重复,先放到字典进行去重,再进行拼接

    for (NSString *key in cookieDic) {

        NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]];

        [cookieValue appendString:appendString];
}

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];

[request addValue:cookieValue forHTTPHeaderField:@"Cookie"];

[self loadRequest:request];

第三种:AFNetworking存取cookie

// 取

NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
//存

[manager.requestSerializer setValue:cookieValue forHTTPHeaderField:@"Cookie"];

总结:目前我的项目中只在WKWebView中用过cookie,面试官问我具体代码的时候没有想起来,应该把三种存cookie方法的关键代码记住。

7.用过哪些第三方?
答:AFNetworking、JSONModel、Masonry、SDWebImage、MJRefresh、IQKeyboardManager、MBProgressHUD等

SDK:友盟(统计、推送、分享)、高德地图、极验验证、AlipaySDK、WechatOpenSDK、ShareSDK等

小众一些的第三方:SDCycleScrollView、CCPCalendar、ZFPlayer、lottie等

总结:我只回答了最普遍用的几个第三方,其他的一时没想起来,应该说一些复杂的第三方,这样才能显示出项目的深度。

8.h5页面交互主要采用什么方式?

1.使用WKWebView
2.WebViewJavascriptBridge开源库使用,然后注入相应的JS。
3.reactiveNative,是facebook2015年开放的一个开源框架。
4.JavaScriptCore.framework

总结:我只用过第一种,之前的项目基本都是原生开发,如果以后项目中需要希望可以学习一下,目前先知道有哪些种方式吧。

9.造成TableView加载高清大图滑动卡顿的真正原因,解决办法,是内存的原因吗,图片的大小会影响内存吗?

答:

真正原因:因为我们拖拽tableview,runloop就要循环一次,对UI进行绘制一遍,由于图片太大,绘制时间长,出现卡顿。

解决办法:
拖拽tableview的时候runloop处于NSEventTrackingRunLoopMode模式,如果在这个模式下我们不让他绘制图片,等他处于NSDefaultRunLoopMode(拖拽完后他就会回到NSDefaultRunLoopMode模式),我们再让它绘制图片就不会卡顿了。可以通过对runloop进行监听来实现。

不是内存的原因,图片太多占用内存过多并不是图片太大导致的,而是因为主线程阻塞。

总结:这个问题是问我工作中遇到过什么困难,我先说了有时候会遇到审核失败不过的问题,面试官让我回答技术方面遇到的问题,我就说了加载大量高清图片时页面会出现卡顿的问题,然后问我解决办法,我说了先压缩图片,这样说就显得外行了,图片高清不是卡顿的根本原因,是可以通过其他方法解决的,不能为了省事直接压缩图片,这样体现不出来任何技术含量,应该通过监听runloop,等runloop的模式恢复成NSDefaultRunLoopMode以后再加载图片。这个问题已经被问多次了,我之前一直都答错了,而且还没有意识到自己的错误,一定要引以为戒。

10.app的用户量有多少?

因为之前公司的用户分为移动端、支付宝小程序端和Web端,我只知道移动端的用户量,在离职之前我特意看了一下友盟上的数据iOS和安卓端加起来的用户量是16万多,非常少,因为我们主要的流量是在支付宝小程序上,移动端大概只占用户总量的百分之五,所以总共的用户量大概在几百万,要是再加上web端的用户量会不会超过一千万我也说不好,我只好回答用户量有几百万。用户量太少我也不想说谎,要不然我最后也用不着离职了。

推荐阅读更多精彩内容