iOS面试题目二

转上篇---iOS面试题目一

目录

1. 传值方式
2. 数据请求方式
2.1. GET与POST区别
2.2. 其他的网络请求方式
3.网络判断
4.支付
4.1支付宝
4.2微信文档
4.3对支付的大致总结
5.与网页交互问题
6.推送
7. 谓词查询
8. CoreData相关问题
9. 正则表达式
10.常见 App 拒绝情况
11.如何把一张大图缩小为原图的1/2?
12.Metal有了解吗?
13.Swift里的值类型与引用类型的区别? 闭包是引用类型吗?
14.你是如何储存用户的认证信息?
14.1 利用第三方使用keychain;
14.2 利用系统提供的API使用keychain;
15、项目开发大致流程?
16. 怎么将UIView的背景色设置为渐变色?不使用背景图.

1.传值方式

Demo

2.数据请求方式

超文本传输协议(HTTP, HyperText Transfer Protocol)是一种无状态的协议,它位于OSI七层模型的应用层。HTTP客户端会根据需要构建合适的HTTP请求方法,而HTTP服务器会根据不同的HTTP请求方法做出不同的响应。

最基本的方法有4种,分别是GET,POST,PUT,DELETE。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息

2.1GET与POST区别

区别一:表面现像上

1.GET请求: GET请求的数据会附在URL之后, 以?分割URL和传输数据,参数之间以&相连,
如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。其中%XX中的XX为该符号以16进制表示的ASCII。

2.POST把提交的数据则放置在是HTTP包的包体中。

区别二:长度

1. GET请求: URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是
特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,
如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。

2. POST请求:POST是没有大小限制的,HTTP协议规范也没有进行大小限制.


区别三: 安全

1.POST的安全性要比GET的安全性高。

2.通过GET提交数据,用户名和密码将明文出现在URL上,因为登录页面有可能被浏览器缓存,其他人查看
浏览器的历史纪录,那么别人就可以拿到你的账号和密码了


2.2 其他的网络请求方式

DELETE

DELETE请求用于请求服务器删除所请求URI(统一资源标识符,Uniform Resource Identifier)所标识
的资源。DELETE请求后指定资源会被删除,DELETE方法也是幂等的。

幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。


PUT

PUT请求会身向指定资源位置上传其最新内容,PUT方法是幂等的方法。通过该方法客户端可以将指定资源的最新
数据传送给服务器取代指定的资源的内容。


3.网络判断





4.支付

4.1支付宝

iOS面试题目二_第1张图片
Paste_Image.png
1.  与支付宝签约,获得商户ID(partner)和账号ID(seller)
2.  下载相应的公钥私钥文件(加密签名用)
3.  下载支付宝SDK
4.  生成订单信息
5.  调用支付宝客户端,由支付宝客户端跟支付宝安全服务器打交道
6.  支付完毕后返回支付结果给商户客户端和服务器


4.2微信文档

微信支付流程图


1.审核时间7个工作日以内通知审核结果;
2、个人开发的移动应用不可以申请微信APP支付,只接受公司主体的移动应用。
3、交纳的支付手续费,会开具发票或收据。


4.3对支付的大致总结


首先,微信和支付宝公司会给商户提供一个唯一标识PID,而且与该标识相对应的会有一个KEY,双方使用这个KEY作为加密的密钥。

其次,商户使用接口的时候,根据不同支付方的开发文档的要求,将所需要的参数(订单的相关信息如:金额、商品等)
拼接成相应的形式。在发送请求之前需要对数据进行加密,而加密的方式会由支付方提供,文档中会有相应的描述,有的接口
也会提供现成的方法供商户使用。加密后就可以调用接口向支付网关发送请求了。

最后,是对于支付结果的处理。支付方在对相应的资金进行处理后收到相应的返回值。

5. 与网页交互问题

5.1 平台简单介绍

5.1.1 原生


1.针对不同平台分别开发
2.下载使用门槛高
3.升级更新需重新下载
4.界面流畅
5.可以调用底层API
6.可离线使用

5.1.2 H5

1.跨平台
2.用户无需下载
3.用户无需升级
4.界面反应不及时
5.有限的API访问
6.无法离线使用

混编

优点

1. 跨平台性能好
2. UI可以随时更替
3. 快速调整入口方案
4. 不用提交新包审核。

缺点
1. 数据更新问题;
2. 离线问题;
3. 流程问题

混编第三方框架--JSPatch

6.推送

6.1 系统推送的步骤参照--iOS面试题目一中27题
6.2 详细请看极光推送--iOS通知----极光推送(四)

大致步骤为


1. 登陆苹果开发者创建Bundle ID, 证书, 描述文件, 配置证书中的推送;
2. 从钥匙串中导出p12证书, 上传至极光中已经创建的项目中的指定位置; 
3. 在Xcode中开启推送功能, 获取设备Devicetoken,真机测试的步骤(配置Bundle ID. 证书. 描述文件), 注册并获取通知;
4. 极光官网可以根据广播/设备标签等进行推送

7. 谓词查询

谓词是通过NSPredicate,是通过给定的逻辑条件作为约束条件,完成对数据的筛选。

NSPredicate *predicate =[NSPredicatepredicateWithFormat:@"customerID == %d",n];
result = [customers filteredArrayUsingPredicate:predicate];

8. CoreData相关问题

8.1 CoreData是什么?


CoreData 是苹果针对 Mac 和 iOS 平台开发的一个框架,主要用来将模型对象的状态持久化到磁盘。它能够让
开发者以面向对象而非 sql 语句的方式操作数据,提高了开发效率。

参考文章
参考书籍

iOS面试题目二_第2张图片
工作流程.png

8.2 大致流程:

1.初始化NSManagedObjectModel对象,加载模型文件,读取app中的所有实体信息;
2.初始化NSPersistentStoreCoordinator对象(持久化存储协调器),添加持久化库(这里采取SQLite数据库), 
作用是上下文和数据库需要交互时在中间调节。
3.初始化NSManagedObjectContext对象,拿到这个上下文对象操作实体,管理其所包含的模型对象,进行
CRUD操作<增删改查操作>.

一些细节


1. 创建实体---NSEntityDescription;
2. 通过模型上下文, 创建NSFetchRequest 查询对象的条件;
3. 模糊查询: 谓词查询predicate,;
------------------------------------------------------------
// 查询 age 字段中大于等于"20"的元素
request.predicate = [NSPredicate predicateWithFormat:@"age >= %@", @"20"];
// 查询 name 字段中包含"1"的元素
request.predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*1*"];
 ------------------------------------------------------------

2.2  分页查询: 设置 fetchLimit 和 fetchOffset 属性。
 ------------------------------------------------------------
/ 分页查询
request.fetchLimit = 5; // 每一页数据数量
int num = 10; // 页号
request.fetchOffset = (num - 1) * request.fetchLimit; // 分页起始索引
 ------------------------------------------------------------

2.3  设置 sortDescriptors 属性,通过 NSSortDescriptor 类对指定字段排序。
 ------------------------------------------------------------
// 排序
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
request.sortDescriptors = @[sort];
 ------------------------------------------------------------

3. 增删改类似于查找, 都需要创建NSFetchRequest.

8.3 Core Data版本迁移

如果iOS App 使用到CoreData,并且在上一个版本上有数据库更新(新增表、字段等操作),那在覆盖安装程序
时就要进行CoreData数据库的迁移,具体操作如下:

1.选中你的mydata.xcdatamodeld文件,选择菜单editor->Add Model Version  比如取名:mydata2.xcdatamodel
2.设置当前版本
   选择上级mydata.xcdatamodeld ,在inspector中的Versioned Core Data Model选择Current模版为mydata2
3.修改新数据模型mydata2,在新的文件上添加字段及表
4.删除原来的类文件,重新生成下类。
5.重新编译

9. 正则表达式

9.1 正则表达式是什么?

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

正则表达式用于字符串处理、表单验证等场合,实用高效。

9.2 使用方法参照如下,

//验证是否是邮箱/ 
- (BOOL)isEmail  
{  
    NSString *regex = @"/^(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w+)+)$/";  
    NSPredicate *   pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];  
      
    return [pred evaluateWithObject:self];  
}  


9.3 常用的正则表达式

1. 匹配中文字符的正则表达式: [\\u4e00-\\u9fa5]
2. 匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
3. 匹配身份证:\\d{15}|\\d{18}
4. 匹配ip地址:\\d+\\.\\d+\\.\\d+\\.\\d+
5. 匹配车牌号: ^[\\u4e00-\\u9fa5]{1}[a-zA-Z]{1}[a-zA-Z_0-9]{4}[a-zA-Z_0-9_\\u4e00-\\u9fa5]$


9.4 正则表达式更多学习

10.常见 App 拒绝情况
2016年详细审核规则详见
2016年苹果审核规则之苹果官网链接

1. 崩溃和错误;
2. 链接损坏, App 中的所有链接必需能正常使用;
3. 信息不完整: 如果某些功能需要登录,请提供有效的演示帐户用户名和密码。如果有特殊配置需要设置,请添加
相关规范。如果功能需要难于复制的环境或需要特定硬件,请准备好提供演示视频或硬件。此外,请确保联系人信
息完整且是最新的。
4. 重复提交类似 App;
5. 持久价值不足: 如果你的 app 缺乏足够的功能或内容,或者只适用于小众市场,则可能无法获得批准。在构建 app 
之前,请在 App Store 中查看你的类别中的 app,并考虑如何提供更好的用户体验。
6. 广告: 在你提交 app 以供审核时,将向你询问你的 app 是否使用“广告标识符”(IDFA) 来投放广告。

11.如何把一张大图缩小为原图的1/2?


NSData *imageData = UIImageJPEGRepresentation(image, 0.5);


12.Metal有了解吗?

在iOS 8里,苹果发布了一个新的接口叫做Metal,它是一个支持GPU加速3D绘图的API。Metal和OpenGL ES相似,它也是一个底层API,负责和3D绘图硬件交互。它们之间的不同在于,Metal不是跨平台的。与之相反的,它设计的在苹果硬件上运行得极其高效,与OpenGL ES相比,它提供了更快的速度和更低的开销。

13.Swift里的值类型与引用类型的区别? 闭包是引用类型吗?

1. 值类型(Value Types):每个实例都保留了一分独有的数据拷贝,一般以结构体 (struct)、枚举(enum) 或者元组(tuple)的形式出现。
2. 引用类型(Reference Type):每个实例共享同一份数据来源,一般以类(class)的形式出现。

值类型和引用类型最基本的分别在复制之后的结果。

1. 值类型(A)复制相当于创造一个新的实例(B), 复制后与原身无关, (A)的更改不会再次影响(B), 反之亦然;
2. 引用类型(A)复制相当于创造一个新的实例(B), 复制后与原身共享一份数据, (A)的更改会再次影响(B), 反之亦然;

闭包是引用类型。如果一个闭包被分配给一个变量,这个变量复制给另一个变量,那么他们引用的是同一个闭包,他们的捕捉列表也会被复制。

14.你是如何储存用户的认证信息?

14.1 可以参考使用第三方框架keychain----SAMKeychain

14.2 利用苹果提供的API进行自己封装

iOS中保存密码,如果要追求安全性,那么使用苹果自带的Keychain Services无疑是最佳选择。如果要在程序
中使用Keychain Services,首先要添加Security.framework。
Keychain Services提供了一系列api用以存取和更新keychain item:

SecItemAdd(添加)
SecItemUpdate(更新)
SecItemCopyMatching(查找)
SecItemDelete(删除)

优点


*1.每个组(keychain-access-groups)之间数据访问隔离,没有权限的app如何读取他人数据,保证了数据安全。
*2.全局统一存储,即使删除了app,keychain里的数据也还在,下次重新安装app后依然能访问*
*3.存储后的数据加密*
*4.同一个组的app可以共享keychain中的数据*

缺点

1.删除app后不会自动清除keychain里的数据,如果存储密码等敏感数据会有一定风险(越狱后keychain能被导出来)
*2.有可能会速度略慢(原因是最近无意间导了台4s的keychain的数据库文件出来一看,好家伙,几万条数据,估计有和长年积累有关,也估计是有不少app已经把它当kv数据库用了····无语···)*

** 举例子使用 **


#import "CHKeychain.h"

@implementation CHKeychain
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service account:(NSString *)acc{
    NSMutableDictionary *dicx = [NSMutableDictionary dictionaryWithObjectsAndKeys:
            (__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,
            nil];
    if (acc) {
        dicx[(__bridge_transfer id)kSecAttrAccount]=acc;
    }
    if (service) {
        dicx[(__bridge_transfer id)kSecAttrService]=service;
    }
    return dicx;
}

+ (void)save:(NSString *)service account:(NSString *)acc data:(NSData *)data
{
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service account:acc];
    SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
    [keychainQuery setObject:data forKey:(__bridge_transfer id)kSecValueData];
    SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);
}

+ (void)save:(NSString *)service data:(id)data {
    [[self class] save:service account:service data:data];
}

+ (NSData *)load:(NSString *)service account:(NSString *)acc
{
    NSData *ret = nil;
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service account:acc];
    [keychainQuery setObject:(__bridge_transfer id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];
    [keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];
    CFDataRef keyData = NULL;
    if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
        ret = (__bridge_transfer NSData*)keyData;
    }
    if (keyData)
        CFRelease(keyData);
    return ret;
}

+ (NSData *)load:(NSString *)service {
   return [[self class] load:service account:service];
}

+ (void)delete:(NSString *)service {
   return [[self class] delete:service account:service];
}

+ (void)delete:(NSString *)service account:(NSString *)acc
{
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service account:acc];
    SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
}
@end


15、项目开发大致流程?


1. 总体把握设计图/需求文档;
2. 搭建iOS客户端框架<主样式>以及目录规范;
3. 配置Cocoapods并准备<需要用到的第三方>;
4. 封装网络请求/数据库等常用功能;
5. 根据UI设计图, 搭建UI界面;
6. 按文档进行网络请求并与后台沟通;  进行数据持久化并显示在UI界面上;
7. 排除bug; 并打包上传AppStore或企业分发

16.怎么将UIView的背景色设置为渐变色?不使用背景图.

使用CA动画中的梯度动画.


//初始化CAGradientlayer对象,使它的大小为UIView的大小
self.gradientLayer = [CAGradientLayer layer]; 
self.gradientLayer.frame = self.theView.bounds; 
//将CAGradientlayer对象添加在我们要设置背景色的视图的layer层 [self.theView.layer addSublayer:self.gradientLayer];

 //设置渐变区域的起始和终止位置(范围为0-1) 
self.gradientLayer.startPoint = CGPointMake(0, 0); 
self.gradientLayer.endPoint = CGPointMake(0, 1); 

//设置颜色数组 
self.gradientLayer.colors = @[(__bridge id)[UIColor blueColor].CGColor, (__bridge id)[UIColor redColor].CGColor]; 
//设置颜色分割点(范围:0-1) 
self.gradientLayer.locations = @[@(0.5f), @(1.0f)];

参考苹果官网
iOS开发 -- KeyChain使用与共享数据

更多精彩内容请关注“IT实战联盟”哦~~~


iOS面试题目二_第3张图片
IT实战联盟.jpg

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