iOS面试题

前提:上周同事去一家初创型互联网公司去面试iOS开发遇到如下的面试题,也跟我分享了一下具体面试内容,写篇博客总结一下。

面试题如下

  • 极光推送使用
  • 谈谈对高德地图的使用
  • 项目中使用过阿里云的即时通讯,是否使用过非第三方的即时通讯
  • 谈谈高并发编程
  • 你理解的多线程
  • 介绍APP启动过程,如果启动比较耗时是否有优化的方法
  • 简单说说TCP和UDP的理解
  • 说下MD5 base64以及AES加密,以及如何防止反编译
  • 说一下了解的设计模式,以及架构设计
  • 项目中的角色权限和分配,是否做过单点登录
  • 有没有处理过万以上的数据实时传输,如何处理
  • 是否有自己的博客和开源,或者谈谈对于常用框架的理解

看到具体的面试题后,我总结了一下如下分四个部分:

1.第一部分的是对常规SDK的使用和项目中常用框架。

  • 友盟、极光、支付宝/微信、高德。
  • 登录、分享,通知,支付,地图
友盟
极光
支付宝、微信
高德地图
  • AFNetworking、SDWebImage、Masonry、MJExtension
  • 网络请求,图片加载,布局,转模型解析
AFNetworking
SDWebImage
Masonry
MJExtension

2.第二部分的是对概念设计模式的理解。

高并发编程

围绕高并发的核心词 : Grand Central Dispatch(简称GCD)、NSOperation、NSThreadOperation Queues(运行队列)多线程

  • GCD:GCD属于Apple开发的线程管理,是最常使用的并发编程方式。其核心思想是将并发执行的任务封装到Block回调中,在把Block分发到不同类型的队列里,对不同类型的队列,实现并发执行。GCDdispatch_async开头是一套C函数的调用方法:
//dispatch_async:异步执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#time#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
   <#do something#> // 待执行的任务
});
  • NSOperation:NSOperation的核心是对GCD的一种封装,把需要并发执行的任务封装到NSOperation中,然后添加到NSOperationQueue并发执行。调用start方法即可开始执行操作,调用cancel方法中途取消操作,completionBlock处理完的回调。
  • NSThread:GCD的清量易用一定意义上替代诸NSThread这种较为复杂技术高效的技术。每一个NSThread都是一个线程。selector:线程执行的方法,该selector只能有一个参数,而且返回值是voidtarget:selector消息发送的对象argument:传递给target的唯一参数,可以为nilNSThread的开启,关闭以及一些执行状态控制都需要开发者自己管理
  • detachNewThreadSelector:toTarget:withObject:
  • initWithTarget:selector:object:
两者区别在于下面获取到了NSThread对象方便终止线程。
[NSThread detachNewThreadSelector:@selector(loadData) toTarget:self withObject:nil];

#pragma mark - 加载耗时数据
- (void)loadData
{
    //并发执行执行任务
}

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadData) object:nil];

[thread start]; //调用

总结:如果选择的话我更倾向于GCD ,GCD是一个轻量级别的级别,底层实现影藏的技术,通过其和Block相结合可以轻松实现多线程编程。

参考博客:使用GCD、iOS多线程

你理解的多线程

  • 多线程的原理

同一时间,CPU只能处理1条线程,只有1条线程在工作(执行) 多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换) 如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象 思考:如果线程非常非常多,会发生什么情况?
CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源 每条线程被调度执行的频次会降低(线程的执行效率降低)

  • 多线程的优点

能适当提高程序的执行效率 能适当提高资源利用率(CPU、内存利用率)

  • 多线程的缺点

开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用 512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能
线程越多,CPU在调度线程上的开销就越大 程序设计更加复杂:比如线程之间的通信、多线程的数据共享

简单说说TCP和UDP的理解

这两个工作在TCP/IP协议传输层的两个不同的协议,是用来传输数据用的。

TCP:(Transmission Control Protocol)和UDP(User Datagram Protocol)属于传输层协议。这是一个全双工的、面向连接的、可靠的并且是精确控制的协议。
  • 主要应用在那些实用性不强,但要求不能出错的地方。比如网页浏览,文件下载,文件收发。
UDP:(User Datagram protocol)是面向数据报的运输层协议。是一个不可靠的传输协议。
  • 不关心传输数据段到达的目的方的顺序,所以不可靠。开销比TCP小很多。比如及时通讯,视频,语音。
两者的区别和联系:

区别:TCP是面向连接的可靠的传输控制协议,UDP是面向非连接的用户数据协议。
联系:TCP(三次握手保证相对可靠性)可传大量数据,速度相对比较慢,UDP一次性传输少量对可靠性要求不高的数据,速度比较快
tcp一般用于音频、视频等数据的传输,资源能耗比较小,对可靠性要求不高,即使丢失一两条数据也不会产生太大影响。

什么是“三次握手”:

是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换 TCP 信息。

iOS面试题_第1张图片
三次握手

介绍APP启动过程,如果启动比较耗时是否有优化的方法

APP启动过程
1. 解析Info.plist
  • 加载相关信息,如闪屏
  • 沙箱建立,权限检查
2. Mach-O加载
  • 如果是胖二进制,寻找合适CUP类别的部分
  • 加载所有依赖Mach-O文件
  • 定位内部,外部指针引用,如字符串,函数
  • 执行声明函数
  • 加载扩展类
  • C++静态对象加载,调用Objc的+(load)函数
3. 程序执行
  • main函数
  • 执行UIApplicationMain函数
  • UIApplicationDelegate对象开始处理监听事件
APP启动缓慢,想到的因素
  1. main( ) 函数内有耗时操作
  2. 动态库加载太多
  3. rootViewControlle以及childViewController的加载,viewsubViews的加载耗时
优化
  • 移除不需要用到的动态库
  • 移除不需要用到的类
  • 合并功能类似的类和扩展(Category)
  • 压缩图片资源
  • 优化applicationWillFinishLaunching
  • 优化rootViewController加载

设计模式

MVC:

MVC(Model View Controller):模型(model)-视图(view)-控制器(controller)

  • M(Model):实际上考虑的是什么的问题,你程序本质上是什么,独立于UI工作,是程序中用于处理应用逻辑的部分,通常赋值存取数据。
  • C(Controller):控制你的数据(Model)如何显示在屏幕上,他需要数据的时候会告诉Model,你帮我获取数据,当他需要如何展示界面的时候和更新界面的时候他告诉V(View),是V和M之间的沟通桥梁。
  • V(View):是Controller的使用类,用于构建视图。通常根据Model来创建。
MVC的优点
  • 低耦合性

视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。

  • 高重用性和可适用性

由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面使用。例如,很多数据可能用HTML来表示,但是也有可能用WAP来表示,而这些表示所需要的命令是改变视图层的实现方式,而控制层和模型层无需做任何改变。

  • 较低的生命周期成本

MVC使开发和维护用户接口的技术含量降低。

  • 可维护性

分离视图层和业务逻辑层也使得应用更易于维护和修改。

总结优点:提高代码的可读性和可移植性,降低耦合度,提高内聚,大大提高开发的效率。

MVC的缺点:

对于一些接单的界面额外的增加复杂性,视图与控制器间的过于紧密的连接。不适合中小型APP的开发,会额外增加开发成本。

MVC
V向C发消息:
  • target-action:C会在自己的内部“悬挂”一个目标(target),可能屏幕上是一个按钮,当按钮被点击时,action就会被发送给与之对应的target,这样V和C就有了交流。
  • delegate(代理):delegate在上图中是黄色的箭头,C把自己设置为V的委托(delegate),它让V知道,如果该显示什么,就给C发delegate消息。
  • datasource(数据源):当V需要显示数据的时候,他将需要别人的帮助将数据传递给他,这就是数据源了。
  • Notification & KVO:一种类似电台的方法,Model信息改变时会广播消息给感兴趣的人。

参考:浅谈 MVC、MVP 和 MVVM 架构模式,iOS中MVC设计模式

架构设计:

建议可以从以下几个方面回答

  • 网络层的设计方案
  • 本地持久化方案
  • View层组织和调用方案
APP好的架构的评判标准
  • 代码整齐,分类明确
  • 易扩展,方便测试
  • 没有横向依赖,不到万不得已没有跨层访问
  • 接口少,统一,参数少
  • 高性能
  • 思路与方法上统一保持一致

说下MD5 base64以及AES加密

MD5:Message Digest Algorithm 5

MD5是iOS中比较常见的加密方法之一,其特点有一下几点

  • 加密的不可逆性,只能够加密,不能够解密。

  • 明文加密后长度都是固定的,长度为16进制32位。

  • AES加解密:相较于DES和3DES算法而言,AES算法有着更高的速度和资源使用效率,安全级别也较之更高了。

  • AES使用的是对称加密.所谓对称加密就是加解密双方使用的密钥相同.因此通过一种保密的方法让客户端与服务器拥有该密钥,即可成功使用加解密。

base64加密:使用64个字符来对任意数据进行编码。
  • base64加密:base64EncodedStringWithOptions
  • base64解密:initWithBase64EncodedString
如何防止反编译
  • 本地数据加密:对NSUserDefaultssqlite等本地存储数据加密
  • URL编码加密:对程序中出现的URL进行加密,防止URL被静态分析
  • 网络传输加密:有效的防止数据接口拦截
  • 程序结构混排加密:把应用程序的逻辑打乱,将可读性降到最低。

3.第三部分的是对项目中具体某个功能点的实现。

角色权限和分配,是否做过单点登录

在处理这类问题的时候,角色权限和分配对后台的依赖比较大。拿单点登录来说:单点登录SSO(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。简单来说单点登录核心就是要解决,验证信任机制的有效性即存储信任和验证信任。如下优缺点和三种实现方式
单点登录优点
  • 提高用户的效率。
  • 提高开发人员的效率。
  • 简化管理。
单点登录缺点
  • 不利于重构
  • 无人看守桌面
1.以Cookie作为凭证媒介

最简单的单点登录实现方式,是使用cookie作为媒介,存放用户凭证。
用户登录父应用之后,应用返回一个加密的cookie,当用户访问子应用的时候,携带上这个cookie,授权应用解密cookie并进行校验,校验通过则登录当前用户。

iOS面试题_第2张图片
Cookie凭借
以上通过Cookie的方式实现单点登录很容易发现弊端
  • Cookie不安全
  • 以及不能跨域

第一个Cookie不安全上我们可以通过加密等方式来避免泄露,但第二天跨域是硬伤。

2.通过JSONP实现

相比较Cookie的方法,JSONP更好的在于解决了跨域问题,我们父应用在登录成功后把Session匹配的Cookie会存到应用中。当用户需要登录子应用的时候,授权应用访问父应用提供的JSONP接口,并在请求中带上父应用域名下的Cookie,父应用接收到请求,验证用户的登录状态,返回加密的信息,子应用通过解析返回来的加密信息来验证用户。

iOS面试题_第3张图片
JSONP

虽然解决了跨域但是还是存在上一个方法一样的弊端,就是信任机制的不安全性,易泄露。

3.通过页面重定向的方式

通过父应用和子应用来回重定向中进行通信,解决信任机制的不安全性,实现信息的安全传递。
父类提供一个登录接口,用户通过子应用登录连接访问这个接口,判断如果用户还未登录,则返回登录界面输入账号密码登录。如以及登录则声称密码Token,验证Token的接口,检验后是否登录成功。

iOS面试题_第4张图片
页面重定向

这个方法固然解决了跨域和安全两个问题,但是相比较上两种而言增加了登录的复杂度。

参考:单点登录的三种实现方式

4.博客,开源。

开源的话,推荐GitHub

  • github地址:RocketsChen欢迎StarFollow

坚持开源写博客,对技术的提升还是很有帮助的,如果把平常项目开发中小技巧和问题记录下来,长期积累下去也是一件有意义的事。

最后就总结到这,欢迎补充~

你可能感兴趣的:(iOS面试题)