[iOS面试]第10章 架构框架相关面试问题

注意:本文主讲架构框架相关面试问题,包括图片缓存、阅读时长统计、复杂页面结构、客户端整体架构。

问题: 架构框架解决什么问题?
答:

  • 引入架构框架为了实现模块化, 将各功能按模块进行划分
  • 分层
  • 解耦
  • 降低代码重合度

一、图片缓存

1、图片缓存

问题:怎样设计一个图片缓存框架?

图片缓存框架

  • 首先有Manager模块, 用以协调和调度框架内部各个模块
  • 内存管理模块. 比如: 涉及图片缓存 就需要模拟计算机组成原理涉及到的多级缓存思想运用
  • 图片磁盘缓存处理模块.
  • 网络模块. 本地没有图片支持通过网络下载图片
    以上构成基本图片框架,如果图片压缩, 保存图片需要解压缩的话,需要以下模块
  • codeManager 解码相关管理者.
  • 图片解码模块.
  • 图片压缩/解压缩模块.

2、图片读写

问题:图片通过什么方式进行读写,过程是怎样的?

答:

  • 以图片URL的单向Hash值作为Key, 存储到图片对应框架中
  • 图片读取按照多级缓存读取图片,提交查找效率

图片读取流程

3、内存设计

问题:内存的设计上需要考虑哪些问题?

答:

  • 存储的Size. (内存存储空间大小)
  • 淘汰策略. (有size限制, 后边再有新图片,需要有淘汰策略)

存储size实现

存储Size
需要考虑图片大小本身,以及不同图片大小的使用频率高低问题.
通过队列方式存取图片.

淘汰策略:考虑两种方案

  • 以队列先进先出的方式淘汰
  • 模拟计算机中LRU(Least Recently Used 最近最少使用)算法. (如30分钟之内是否使用过)

具体淘汰策略:
1>定时检查.
2>提高检查触发频率: 每次进行读写时 前后台切换时.
注意开销问题

补充: LRU算法是核心思想是:如果一个数据在最近一段时间都没有被用到,那么它在将来被使用到的可能性也很小。故当缓存空间已满的情况下,我们需要淘汰掉最久没有被访问到的数据。理想的LRU算法读写是时间复杂度应该都为O(1)。

4、磁盘设计

问题:磁盘设计需要考虑哪些问题?

  • 存储方式
  • 大小限制(如100MB)
  • 淘汰策略(如某一图片存储时间距今已超过7天)

5、网络设计

问题:网络部分的设计需要考虑哪些问题?

  • 图片请求最大并发量 (比如同一时间最大请求数量,限定在10张或者20张)
  • 请求超时策略 (比如超时,可以采取重试机制再去请求图片, 2次再失败先不请求这张图片)
  • 请求优先级 (比如下载或者缓存的图片是否当前用户最紧急使用, 如果是请求优先级高些)

6、图片解码

问题:对于不同格式图片,解码采用什么方式来做?

  • 应用策略模式对不同图片格式进行解码

问题:在哪个阶段做图片解码处理?

  • 磁盘读取后 (从磁盘读取是未解码,放到内存中最好解码完成, 因为系统在显示图片前会在主线程进行图片解码操作,减少主线程压力)
  • 网络请求返回后

7、线程处理

二、阅读时长统计

1、框架设计

问题:怎样设计一个时长统计框架?

阅读时长框架

1)记录器: 对每一条时长统计数据进行记录

  • 页面式记录器 :
    常见场景:记录用户读取或者访问页面时长,一般从页面push开始作为阅读时长开始节点, pop后代表记录结束)
  • 流式页面记录器 :
    比如浏览微博flow流以及腾讯新闻, 头条新闻,这种新闻的阅读记录, 每条定义为流式记录器
  • 自定义式记录器 :
    比如实际业务开发,有不同业务场景,微博, 腾讯新闻横滑式新闻条目的播放,由业务方控制具体控制开始结束的逻辑

2)记录管理者: 管理通过记录器记录的时长统计数据

  • 记录缓存 :
  • 磁盘存储 : 用来维护和处理异常场景,可能到时内存缓存丢失问题
  • 上传器 : 用来将本地所记录下来的时长数据上传给server端

2、记录的缓存&存储

1)问题: 为何要有不同类型记录器,你的考虑是什么?
答: 基于不同分类场景提供的关于记录的封装, 适配

2)问题:记录的数据会由于某种原因丢失, 你是怎样处理的?
(考察降低丢失率, 不是每条都不丢失)

  • 定时写磁盘
    比如每满50条,进行磁盘写入
  • 限定内存缓存条数(如10条), 超过该条数, 即写磁盘

3、记录上传器

问题: 关于延时上传的具体场景有哪些?

  • 前后台切换
  • 从无网到有网的变化
  • 通用的轻量接口捎带
    如果以企业级实践方式落地, 建议使用前两种是最优的, 最后有耦合在里边.

问题: 长传时机是怎样把控的?
答:

  • 立刻上传
  • 延时上传
  • 定时上传

三、复杂页面结构

  • MVVM框架思想
  • ReactNative的数据流思想
  • 系统UIView更新机制的思想
  • FaceBook的开源框架AsyncDisplayKit关于预排版的设计思想

1、MVVM

MVVM

2、ReactNative的数据流思想

RN数据流思想

任何一个子孙节点是没有权利做自己的变化更新的, 它必须要把自己变化更新的消息传递给根节点, 由根节点自顶向下方式询问哪些需要更新.由主动行为变为被动行为.

四、客户端整体架构

问题:你所在公司客户端整体架构是怎样的?如果让你设计,怎样设计客户端的整体架构?

客户端整体架构

  • 独立App的通用层
    比如通用层中可以有时长统计框架, 崩溃统计, 网络的第三方库. 这一层架构放到任何一个App中都可以起到底层支撑作用, 独立于APP

  • 通用业务层:
    针对当前公司有某些通用的基础组件, 比如自定义布景控件, 特殊UIImageView的封装. 这些是和当前公司业务有关的, 对于整体App来说各个业务线对于通用控件都有需求,把这些内容沉降到通用业务层.

  • 中间层: 协调解耦作用
    为了实现业务A 业务B 业务C 业务D的解耦

  • 各个业务代码

问题:业务之间的解耦通信方式

  • OpenURL
  • 依赖注入

中间层做业务A和业务C解耦, 业务C通过注入方式将自己注入到中间层, 业务A去中间层获取所依赖的方法或者成员变量.
例如: 中间层实现策略: 某一个业务方通过一个protocal注册到对应中间层中, 同时实现中间层代理方法返回给中间层一个具体实例对象. 业务A使用时, 可以通过事先和业务C商量的协议,从中间层中根据某一方法获取遵从某一协议的实例, 然后在业务A中把实例当做完全遵从协议透明对象来使用.

五、架构框架面试总结