关于ios:iOS面试题攻略分析

40次阅读

共计 7325 个字符,预计需要花费 19 分钟才能阅读完成。

以下是回顾之前上、中、下三篇底层面试题的补充,附上答案。

俗话说得好,底层不牢,地动山摇。

这些答案只是给大家一些参考,大家能够再联合本人了解进行答复,有须要的敌人们上面来一起看看吧。

本文收录:公众号【iOS 进阶宝典《iOS 底层面试干货分享(补充)》】

iOS 开发中的加密形式

iOS 加密相干算法框架:CommonCrypto

1: 对称加密: DES、3DES、AES

  • 加密和解密应用同一个密钥。
  • 加密解密过程:
  • 明文 -> 密钥加密 -> 密文
  • 密文 -> 密钥解密 -> 明文
  • 长处:算法公开、计算量少、加密速度快、加密效率高、适宜大批量数据加密;
  • 毛病:单方应用雷同的密钥,密钥传输的过程不平安,易被破解,因而为了窃密其密钥须要常常更换。

AES:AES 又称高级加密规范,是下一代的加密算法规范,反对 128、192、256 位密钥的加密,加密和解密的密钥都是同一个。iOS 个别应用 ECB 模式,16 字节 128 位密钥。

AES 算法次要包含三个方面:轮变动 圈数 密钥扩大

  • 长处:高性能、高效率、灵便易用、安全级别高。
  • 毛病:加密与解密的密钥雷同,所以前后端利用 AES 进行加密的话,如何平安保留密钥就成了一个问题。

DES:数据加密规范,DES 算法的入口参数有三个:KeyDataMode

  • 其中 Key 为 7 个字节共 56 位,是 DES 算法的工作密钥;Data 为 8 个字节 64 位,是要被加密或被解密的数据;Mode 为 DES 的工作形式,有两种:加密、解密
  • 毛病:与 AES 相比,安全性较低。

3DES:3DES 是 DES 加密算法的一种模式,它应用 3 条 64 位的密钥对数据进行三次加密。是 DES 向 AES 过渡的加密算法,是 DES 的一个更平安的变形。它以 DES 为根本模块,通过组合分组办法设计出分组加密算法。

2. 非对称加密:RSA 加密

  • 非对称加密算法须要成对呈现的两个密钥,公开密钥(publickey) 和公有密钥(privatekey)。
  • 加密解密过程:对于一个私钥,有且只有一个与之对应的公钥。生成者负责生成私钥和公钥,并保留私钥,公开公钥。

公钥加密,私钥解密;或者私钥数字签名,公钥验证。公钥和私钥是成对的,它们相互解密。

  • 特点:

    1).对信息窃密,避免中间人攻打 :将明文通过接管人的公钥加密,传输给接管人,因为只有接管人领有对应的私钥,他人不可能领有或者不可能通过公钥推算出私钥,所以传输过程中无奈被中间人截获。只有领有私钥的接管人才能浏览。 此办法通常用于替换对称密钥

    2). 身份验证和避免篡改 :权限狗用本人的私钥加密一段受权明文,并将受权明文和加密后的密文,以及公钥一并发送进去,接管方只须要通过公钥将密文解密后与受权明文比照是否统一,就能够判断明文在中途是否被篡改过。 此办法用于数字签名。

  • 长处:加密强度小,加密工夫长,罕用于数字签名和加密密钥、安全性十分高、解决了对称加密保留密钥的平安问题。
  • 毛病:加密解密速度远慢于对称加密,不适宜大批量数据加密。

3. 哈希算法加密:MD5 加密.SHA 加密HMAC 加密

  • 哈希算法加密是通过哈希算法对数据加密,加密后的后果不可逆,即加密后不能再解密。
  • 特点:不可逆、算法公开、雷同数据加密后果统一。
  • 作用:信息摘要,信息“指纹”,用来做数据辨认的。如:用户明码加密、文件校验、数字签名、鉴权协定。

MD5 加密:对不同的数据加密的后果都是定长的 32 位字符。

.SHA 加密 :平安哈希算法,次要实用于数字签名规范(DSS) 外面定义的数字签名算法 (DSA)。对于长度小于2^64 位的音讯,SHA1会产生一个 160 位的音讯摘要。当接管到音讯的时候,这个音讯摘要能够用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的音讯摘要。当然除了 SHA1 还有 SHA256 以及 SHA512 等。

HMAC 加密:给定一个密钥,对明文加密,做两次“散列”,失去的后果还是 32 位字符串。

4. Base64 加密

  • 一种编码方式,严格意义上来说不算加密算法。其作用就是将二进制数据编码成文本,不便网络传输。
  • base64 编码之后,数据长度会变大,减少了大概 1/3,然而益处是编码后的数据能够间接在邮件和网页中显示;
  • 尽管 base64 能够作为加密,然而 base64 可能逆运算,十分不平安!
  • base64 编码有个十分显著的特点,开端有个‘=’号。
  • 原理:
    1). 将所有字符转化为 ASCII 码;
    2). 将 ASCII 码转化为 8 位二进制;
    3). 将二进制三位一组有余补 0,共 24 位,再拆分成 6 位一组共四组;
    4). 对立在 6 位二进制前补两个 0 到八位;
    5). 将补 0 后的二进制转为十进制;
    6). 最初从 Base64 编码表获取十进制对应的 Base64 编码。

App 平安,数字签名,App 签名,重签名

因为利用实际上是一个加壳的 ipa 文件,然而有可能被砸壳甚至越狱手机下载的 ipa 包间接就是脱壳的,能够间接反编译,所以不要在 plist 文件、我的项目中的 动态文件 中存储要害的信息。所以敏感信息对称加密存储或者就存储到 keychain 里。而且加密密钥也要定期更换。

数字签名是通过 HASH 算法RSA 加密 来实现的。 咱们将明文数据加上 通过 RSA 加密 的数据 HASH 值 一起传输给对方,对方能够解密拿出HASH 值 来进行验证。这个通过 RSA 加密 HASH 值 数据,咱们称之为数字签名。

App 签名

  • 1. 在 Mac 开发机器上生成一对公钥和私钥,这里称为公钥 L,私钥 L(L:Local)。
  • 2. 苹果本人有固定的一对公钥和私钥,私钥 在苹果后盾,公钥 在每个 iOS 设施上。这里称为公钥 A,私钥 A(A:Apple)。
  • 3. 把 开发机器上的公钥 L 传到苹果后盾,用 苹果后盾的私钥 A 去签名 公钥 L 。失去一个蕴含 公钥 L 以及其 签名 数据证书。
  • 4. 在苹果后盾申请 AppID,配置好 设施 ID 列表 APP 可应用的权限 ,再加上第③步的 证书 ,组成的数据用 私钥 A 签名,把数据和签名一起组成一个 Provisioning Profile 形容文件,下载到 本地 Mac 开发机器
  • 5. 在开发时,编译完一个 APP 后,用 本地的私钥 L 对这个 APP 进行签名,同时把第④步失去的 Provisioning Profile 形容文件打包进 APP 里,文件名为embedded.mobileprovision,把 APP 装置到手机上。
  • 6. 在装置时,iOS 零碎获得证书,通过 零碎内置的公钥 A ,去验证 embedded.mobileprovision数字签名 是否正确,外面的证书签名也会再验一遍。
  • 7. 确保了 embedded.mobileprovision 里的数据都是苹果受权的当前,就能够取出外面的数据,做各种验证,包含用公钥 L 验证 APP 签名,验证设施 ID 是否在 ID 列表上,AppID 是否对应得上,权限开关是否跟 APP 里的 Entitlements 对应等。

OC 数据类型

① 根本数据类型

  • C 语言根本数据类型(如 short、int、float 等)在 OC 中都不是对象,只是肯定字节的内存空间用于存储数值,他们都不具备对象的个性,没有属性办法能够被调用。
  • OC 中的根本数据类型:
    NSInteger(相当于 long 型整数)、
    NSUInteger(相当于 unsigned long 型整数)、
    CGFloat(在 64 位零碎相当于 double,32 位零碎相当于 float)等。
    他们并不是类,只是用 typedef 对根本数据类型进行了重定义,他们仍然只是根本数据类型
  • 枚举类型:其本质是无符号整数。
  • BOOL 类型:是宏定义,OC 底层是应用 signed char 来代表 BOOL。

② 指针数据类型

指针数据类型包含: 类 classid

  • 类 class:NSStringNSSetNSArrayNSMutableArrayNSDictionaryNSMutableDictionaryNSValueNSNumber(继承 NSValue)等,都是 class,创立后便是对象,继承 NSObject
    OC 中提供了NSValueNSNumber 来封装 C 语言的根本类型,这样咱们就能够让他们具备面向对象的特色了。
  • id:id是指向 Objective- C 对象的指针,等价于 C 语言中的void*,能够映射任何对象指针指向他,或者映射它指向其余的对象。常见的 id 类型就是类的 delegate 属性。

汇合 NSSet 和数组 NSArray 区别:

  • 都是存储不同的对象的地址;
  • 然而 NSArray 是有序的汇合,NSSet 是无序的汇合,它们俩能够相互转换。
  • NSSet 会主动删除反复元素。
  • 汇合是一种哈希表,使用散列算法,查找汇合中的元素比数组速度更快,然而它没有程序。

③ 构造类型

构造类型包含:构造体、联合体

  • 构造体:struct,将多个根本数据类型的变量组合成一个整体。构造体中拜访外部成员用点运算符拜访。
  • 联合体 (共用体):union,有些相似构造体struct 的一种数据结构,联合体 (union) 和构造体 (struct) 同样能够蕴含很多种数据类型和变量。

构造体和联合体的区别:

  • 构造体 (struct) 中所有变量是“共存”的,同一时刻每个成员都有值,其 sizeof 为所以成员的和。

长处: 是“有容乃大”,全面;

毛病: 是 struct 内存空间的调配是粗放的,不论用不必,全

调配,会造成内存节约。

  • 联合体 (union) 中各变量是“互斥”的,同一时刻只有一个成员有值,其 sizeof 为最长成员的sizeof

长处: 是内存应用更为精密灵便,也节俭了内存空间。

毛病: 就是不够“容纳”,批改其中一个成员时会笼罩原来的成员值;

property 和属性修饰符

@property 的实质 ivar(实例变量) + setter + getter.

咱们每次减少一个属性时外部都做了什么:

  • 1. 零碎都会在 ivar_list 中增加一个成员变量的形容;
  • 2. 在 method_list 中减少 settergetter 办法的形容;
  • 3. 在属性列表中减少一个属性的形容;
  • 4. 而后计算该属性在对象中的偏移量;
  • 5. 给出 settergetter 办法对应的实现,在 setter 办法中从偏移量的地位开始赋值,在 getter 办法中从偏移量开始取值,为了可能读取正确字节数,零碎对象偏移量的指针类型进行了类型强转。

修饰符:

  • MRC 下: assign、retain、copy、readwrite、readonly、nonatomic、atomic等。
  • ARC 下:assign、strong、weak、copy、readwrite、readonly、nonatomic、atomic、nonnull、nullable、null_resettable、_Null_unspecified等。

上面别离解释

  • assign:用于根本数据类型,不更改援用计数。如果润饰对象(对象在堆需手动开释内存,根本数据类型在栈零碎主动开释内存),会导致对象开释后指针不置为 nil 呈现野指针。
  • retain:和 strong 一样,开释旧对象,传入的新对象援用计数 +1;在 MRC 中和 release 成对呈现。
  • strong:在 ARC 中应用,通知零碎把这个对象保留在堆上,直到没有指针指向,并且 ARC 下不须要放心援用计数问题,零碎会主动开释。
  • weak:在被强援用之前,尽可能的保留,不扭转援用计数;weak 援用是弱援用,你并没有持有它;它实质上是调配一个不被持有的属性,当援用者被销毁 (dealloc) 时,weak 援用的指针会主动被置为 nil。
    能够防止循环援用。
  • copy:个别用来润饰不可变类型属性字段,如:NSStringNSArrayNSDictionary等。用 copy 润饰能够避免本对象属性受外界影响,在 NSMutableString 赋值给 NSString 时,批改前者 会导致 后者的值跟着变动。还有 block 也常常应用 copy 修饰符,然而其实在 ARC 中编译器会主动对 block 进行 copy 操作,和 strong 的成果是一样的。然而在 MRC 中办法外部的 block 是在栈区,应用 copy 能够把它放到堆区。
  • readwrite:能够读、写;编译器会主动生成 setter/getter 办法。
  • readonly:只读;会通知编译器不必主动生成 setter 办法。属性不能被赋值。
  • nonatomic:非原子性拜访。用 nonatomic 意味着能够多线程拜访变量,会导致读写线程不平安。然而会进步执行性能。
  • atomic:原子性拜访。编译器会主动生成互斥锁,对 setter 和 getter 办法进行加锁来保障属性的 赋值和取值 原子性操作是线程平安的,但不包含可变属性的操作和拜访。比方咱们对数组进行操作,给数组增加对象或者移除对象,是不在 atomic 的负责范畴之内的,所以给被 atomic 润饰的数组增加对象或者移除对象是没方法保障线程平安的。原子性拜访的毛病是会耗费性能导致执行效率慢。
  • nonnull:设置属性或办法参数不能为空,专门用来润饰指针的,不能用于根本数据类型。
  • nullable:设置属性或办法参数能够为空。
  • null_resettable:设置属性,get 办法不能返回为空,set 办法能够赋值为空。
  • _Null_unspecified:设置属性或办法参数不确定是否为空。

后四个属性应该次要就是为了进步开发标准,提醒应用的人应该传什么样的值,如果违反了对标准值的要求,就会有正告。

weak 润饰的对象开释则主动被置为 nil 的实现原理:

Runtime保护了一个 weak 表,存储指向某个对象的所有weak 指针weak 表 其实是一个 hash(哈希)表Key 是所指对象的地址,Valueweak 指针的地址数组(这个地址的值是所指对象的地址)。

weak 的实现原理能够概括一下三步:

  • 1、初始化时:runtime会调用 objc_initWeak 函数,初始化一个新的 weak 指针指向对象的地址。
  • 2、增加援用时:objc_initWeak函数会调用 objc_storeWeak()函数,objc_storeWeak() 的作用是更新指针指向,创立对应的弱援用表。
  • 3、开释时,调用 clearDeallocating 函数。clearDeallocating函数首先依据对象地址获取所有 weak 指针地址的数组,而后遍历这个数组把其中的数据设为nil,最初把这个 entry 从 weak 表中删除,最初清理对象的记录。

成员变量 ivar 和属性 property 的区别,以及不同关键字的作用

成员变量: 成员变量的默认修饰符是@protected、不会主动生成 set 和 get 办法,须要手动实现、不能应用点语法调用,因为没有 set 和 get 办法,只能应用->

属性: 属性会默认生成带下划线的成员变量和 setter/getter 办法、能够用点语法调用,理论调用的是 set 和 get 办法。

留神:分类中增加的属性是不会主动生成 **setter/getter** 办法的,必须要手动增加。

实例变量: class 类进行实例化进去的对象为实例对象

关键字作用:

  • 拜访范畴关键字

    • @public:申明公共实例变量,在任何中央都能间接拜访对象的成员变量。
    • @private:申明公有实例变量,只能在以后类的对象办法中间接拜访,子类要拜访须要调用父类的 get/set 办法。
    • @protected:能够在以后类及其子类对象办法中间接拜访(零碎默认)。
    • @package:在同一个包下就能够间接拜访,比如说在同一个框架。
  • 关键字

    • @property:申明属性,主动生成一个以下划线结尾的成员变量_propertyName(默认用 @private 润饰)、属性 setter、getter 办法的申明、属性 setter、getter 办法的实现。留神: 协定 @protocol中只会生成 getter 和 setter 办法的申明,所以不仅须要手动实现 getter 和 setter 办法还须要手动定义变量。
    • @sythesize:批改 @property 主动生成的_propertyName 成员变量名,@synthesize propertyName = newName;
    • @dynamic:通知编译器:属性的 setter 与 getter 办法由用户本人实现,不主动生成。审慎应用:如果对属性赋值取值能够编译胜利,但运行会造成程序解体,这就是常说的动静绑定。
    • @interface:申明类
    • @implementation:类的实现
    • @selecter:创立一个 SEL,类成员指针
    • @protocol:申明协定
    • @autoreleasepool:ARC 中的主动开释池
    • @end:类完结

类簇

类簇 是 Foundation 框架中宽泛应用的设计模式。类簇在公共形象超类下对多个公有的具体子类进行分组 。以这种形式对类进行分组简化了面向对象框架的公共可见体系结构,而不会升高其功能丰富度。 类簇是基于形象工厂设计模式的

常见的类簇有 NSStringNSArrayNSDictionary等。以数组为例:不论创立的是可变还是不可变的数组,在 alloc 之后失去的类都是 __NSPlaceholderArray。而当咱们 init 一个不可变的空数组之后,失去的是 __NSArray0;如果有且只有一个元素,那就是 __NSSingleObjectArrayI;有多个元素的,叫做 __NSArrayIinit 进去一个可变数组的话,都是 __NSArrayM

长处:

  • 能够将形象基类背地的简单细节暗藏起来。
  • 程序员不会须要记住各种创建对象的具体类实现,简化了开发成本,进步了开发效率。
  • 便于进行封装和组件化。
  • 缩小了 if-else 这样不足扩展性的代码。
  • 减少新性能反对不影响其余代码。

毛病:

  • 已有的类簇十分不好扩大。

咱们使用类簇的场景:

  1. 呈现 bug 时,能够通过解体报告中的类簇关键字,疾速定位 bug 地位。
  2. 在实现一些固定且并不需要常常批改的事物时,能够高效的抉择类簇去实现。例:
  • 针对不同版本,不同机型往往须要不同的设置,这时能够抉择应用类簇。
  • app 的设置页面这种并不需要常常批改的页面,能够应用类簇去创立大量反复的布局代码。

文末举荐:iOS 热门文集 & 视频解析

① Swift

② iOS 底层技术

③ iOS 逆向防护

④ iOS 面试合集

⑤ 大厂面试题 + 底层技术 + 逆向安防 +Swift

喜爱的小伙伴记得点赞喔~

珍藏等于白嫖,点赞才是真情ღ(´・ᴗ・`)ღ

正文完
 0