码迷,mamicode.com
首页 > 移动开发 > 详细

ios面试题目(一)

时间:2016-05-11 21:53:48      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

1.多线程在实际现实中有哪些应用?(网络操作和大量图片处理不算)

通常耗时的操作都会放在子线程里处理,然后再回到主线程来显示。下面举几个例子:

  1. 我们要从数据库提取数据还要将数据分组后显示,那么就会开个子线程来处理,处理完成后才去刷新UI显示。
  2. 拍照后,会在子线程处理图片,完成后才回到主线程来显示图片。拍照出来的图片太大了,因此要做处理。
  3. 音频、视频处理会在子线程来操作
  4. 文件较大时,文件操作会在子线程中处理
  5. 做客户端与服务端数据同步时,会在后台闲时自动同步

 

2、如果app比较大,怎么样减少app的大小?

参考答案:

  1. 将build setting中的Optimization Level设置为Fastest, Smallest [-Os],在发布模式下,默认就是这样设置的
  2. 将build setting 中的Strip Debug Symbols During Copy设置为YES,在发布模式下,默认就是这样设置的
  3. 资源文件查找出所有未使用的,去掉这些永远不会使用的资源文件
  4. 对嵌入App的音频进行压缩处理

3、你在迭代开发中是怎么处理版本兼容问题?

参考答案:

版本迭代一定要注意兼容老版本,比如新增了字段或者去掉了某些不再使用的字段,不能引起应用闪退。我们这里只谈程序代码兼容新老版本问题,不考虑业务。因为业务是要求后台来兼容的,通常接口会有版本号控制,用于兼容不同版本的客户端。

对于任何一个App,当可以升级的时候,不会是所有用户就立刻去升级,通常会有很大一部分的用户是不愿意立刻升级的。原因会有很多种,比如我这种的就不会频繁升级,因为对于我来说,这个App并不是天天用,没有必要升级。

那么,我们在iOS开发时,如何去兼容老版本的,保证新版本的增加或者删减不会影响到老版本呢?其实这个问题似乎并不是说有没有新、老版本问题,更重要的是程序的健壮性问题。

对于我们做前端的,永远不要相信后台一定会按照原先约定返回我们想要的数据结构以及所有字段。

假设接口返回来的数据是这样的,我们需要通过类型判断,确保不会因为接口变化返回无效数据而引起闪退。当然,当接口返回的数据结构与我们原先约定的不一样时,通常是因为后台出错了,因此为了程序更健壮,我们应该要容得下后台的错误:

 
AFHTTPRequestOperation *op = [selfPostRequestWithUrl:urlparams:paramscompletion:^(id responseObject) {
  BOOL isSuccess = NO;
  if ([responseObjectisKindOfClass:[NSDictionary class]]) {
    
    NSDictionary *response = responseObject[@"response"];
    if ([responseisKindOfClass:[NSDictionary class]]) {
      
      NSArray *resultList = response[@"resultList"];
      if ([resultListisKindOfClass:[NSArray class]]) {
        NSArray *listModels = [HYBCosmesisModelobjectArrayWithKeyValuesArray:resultList];
        isSuccess = YES;
        completion(listModels);
      }
    }
  }
  
  if (!isSuccess) {
    // 表示出错
    completion(nil);
  }
}errorBlock:^(NSError *error) {
  errorBlock(error);
}];
 

而我们在使用的时候,对于字符串、数组、字典都应该要做一下类型判断和空处理。比如:

 
if ([responseisKindOfClass:[NSDictionary class]]) {
  NSString *value = response[@"blogName"];
  if (!kIsEmptyString(value)) {
    // Do my job
  }
  
  NSArray *array = response[@"array"];
  if ([arrayisKindOfClass:[NSArray class]]) {
    // Do my job
  }
}
 

对于业务方面的话,由后台来做版本控制,通过在接口做添加公共参数,[email protected] 

?要调用的是哪个版本的接口。

 

4、你和后端服务器是怎么进行交互的

参考答案:

这个问题非常简单,但是对于新手就不太清楚了。在很多小公司里,前端好像什么都不需要管,只等后台给你一个接口及参数说明就可以了,根本不清楚后端为什么要这么设计这个接口。

那笔者也来聊聊如何与后端服务器交互:

  1. 在需求确定,定下了开发的周期后,就需要准备开发了。
  2. iOS、安卓及后端各端主要负责人员在了解完需求后,开始分析本期需求需要哪些接口,是否需要新的接口,是否需要改动原有的接口等。在三端统一后,后端接口负责人确定哪天出接口文档及接口假数据。为什么要三端一起定接口呢?因为即使是后端接口负责人,也不一定对原有的业务和原有的接口全部都了解,任何一方的了解加起来才能确定是否可行。
  3. 如果App还没有开发过,首先开发一款新的App,那么iOS、安卓端的架构师,或者主要开发负责人,需要与后端接口负责人共同分析需求,然后初步写出第一版本接口文档,然后各方再各自好好看看、分析分析接口是否合理,参数是否合理,结构是否合理等。这数据的结构会决定着整个网络框架的搭建。

好了,就扯谈这些吧~

 

5、怎么用GCD加载多张图片之后,把图片放到融合到一张图片里?

参考答案:

使用Dispatch Group追加block到Global Group Queue,这些block如果全部执行完毕,就会执行Main Dispatch Queue中的结束处理的block。

当放到group中的所有请求都完成时,才会回调dispatch  group notify的block: 

 
dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_tgroup = dispatch_group_create();
dispatch_group_async(group, queue, ^{ /*加载图片1 */ });
dispatch_group_async(group, queue, ^{ /*加载图片2 */ });
dispatch_group_async(group, queue, ^{ /*加载图片3 */ }); 
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // 合并图片
}); 
 

6、使用GCD的时候,如何在一个group里添加几个任务的依赖关系(这几个任务放在一个组中)

参考答案:

这个不太清楚想问什么,笔者翻看了看GCD中dispatch  group t里,也没有什么可以设置同一个组内的任务依赖关系的,就看到dispatch  group wait这个API: 

 
long
dispatch_group_wait(dispatch_group_tgroup, dispatch_time_ttimeout);
 

这个API是等待group中的所有任务都执行完毕才能继续往下执行其它任务。它是同步地等待任务执行完毕。比如,A、B、C、D四个任务,要求A、B执行完毕后,C、D才能开始执行,那么可以通过这样做:

 
dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_tgroup = dispatch_group_create();
 
dispatch_group_async(group, queue, ^{ /* 任务A */ }); 
dispatch_group_async(group, queue, ^{ /* 任务B */ }); 
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    dispatch_group_async(group, queue, ^{ /* 任务C */ });
    dispatch_group_async(group, queue, ^{ /* 任务D */ });
}); 
 

或者可以这样:

 
dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_tgroup = dispatch_group_create();
 
dispatch_group_async(group, queue, ^{ /* 任务A */ }); 
dispatch_group_async(group, queue, ^{ /* 任务B */ }); 
// 同步等待A、B执行
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);
 
// 重新创建组
group = dispatch_group_create();
dispatch_group_async(group, queue, ^{ /* 任务C */ });
dispatch_group_async(group, queue, ^{ /* 任务D */ });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // C、D执行完毕后,想干嘛就干嘛去吧
}); 
 

不知道笔者对题目的理解是否到位,上面的代码是随手写的,可能单词会写错~~~

 

7 iOS如何在用户修改头像后正常显示

 

方案一

笔者所能想到的方案:

笔者针对这个问题,第一想到的就是通过图片的摘要验证。服务端在接口中返回用户信息时,连同图片的摘要(md5)值也下发到客户端,然后每次App登录时,服务端都将最新的用户信息返回来,客户端将本地所缓存的用户头像取出,也生成摘要(md5)五,与服务端所返回来的md5值比较,若相同表示没有头像没有修改过;若不相同,表示头像已经修改过。

缺点:只要重新登录或者App在后台自动登录后,才能更新。也就是说,如果用户没有退出登录,或者没有过期而不会自动登录,头像也没有更新得了。

方案二

在微博上收集到大家的方案。给URL添加一个参数version,当图片修改之后,URL的version发生变化,那么就会重新下载图片来缓存。

缺点:与方案一类似,要求重新请求数据才能得到最新的URL。

方案三

在修改图片时,要求不能使用相同的名字,这样链接路径是一样的,但是因为名字不同而找不到。此时,就会重新获取图片而不是缓存的。可以在文件名中带上前缀进行上传,譬如avatar-3/v1.jpg,更新后改为avatar-3/v2.jpg。

方案四

客户端在请求头加上If-Modified-Since字段,表明请求此时间后最新的文件资源,服务端也会在响应头返回这个last-modified字段表示上次修改时间。

 

ios面试题目(一)

标签:

原文地址:http://www.cnblogs.com/wyk19910103/p/5483416.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!