小白的第一次面试总结

2015-11-05  本文已影响897人  与佳期

前言

投的第一份简历,第一次面试
首先说一下印象吧:一家创业公司,HR姐姐很nice,公司环境很不错,位置也好就在南京路步行街附近,交通方便。
至于面试题,不了解的后端、动画、Autolayout和CALayer一带而过。了解的就问得很简单基础,不过毕竟第一次面试,感觉答得。。。呵呵!所以在这里重新整理为自己总结一下吧!

面试问题如下

1.对MVC的理解

答:M代表Model(模型数据);V代表View(视图/界面);C代表Controller(控制器)
Controller从Model中取到数据控制View的内容显示,所以Controller可以访问Model和View。但是Model为了重用而不能访问Controller和View,View不能直接到Model中取数据,他需要设置Controller中的数据源方法,让Controller帮它到Model中取数据。
额......是不是有点乱,上图:


MVC图解.png

注:图中的标注“1”处,并不是代表View拥有Controller属性,而是访问Controller的dataSource方法

另:用文章MVC模式下通过xib自定义cell中的MVC模式为例大体总结一下MVC之间的工作(对MVC不了解的建议先看这篇文章)
1.模型Borrow中,写一个构造方法解析字典属性,写一个类方法 通过调用构造方法返回解析的数据。
2.自定义的BorrowCell继承自UITableViewCell,拥有cell中控件的属性,写一个类方法返回这个自定义的cell。同行BorrowCell拥有模型Borrow属性,并重写其setter方法,在setter方法中为BorrowCell中的控件绑定模型数据
3.BorrowViewController里添加UITableView,并使用自定义的BorrowCell。在Controller里加载plist文件,通过Model里的类方法解析后数据传给BorrowCell的Borrow属性

说到在UITableView里使用自定义的Cell,面试时的一件极惭愧的事:面试官看到我的代码在cellForRow方法中有这么一段:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DetailCell *cell = [[DetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[DetailCell ID]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
说:你的cell没有采用重用机制吗?毕竟第一次面试,当时竟然懵了。想怎么会没有重用机制呢,所有的TableViewCell最基本的嘛。当时没答出来,回来之后才发现只有这里忘写了而已,改为:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DetailCell *cell = [tableView dequeueReusableCellWithIdentifier:[DetailCell ID]];
if (cell == nil) {
cell = [[DetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[DetailCell ID]];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
面试官以为我不知道 dequeueReusableCellWithIdentifier方法呢
由此引发下一个面试题

2.UITableViewCell的重用机制

答:UITableView刚出现时只会创建视图上看得见cell,向下滚动UITableView,即将出现新的cell时,它会去缓存池中取带有自定标识reuseIdentifier的cell(这个缓存池是UITableView自带的)缓存池中有这样的cell就取出重用,没有就创建。对于上方消失的cell会带着重用标记reuseIdentifier放到缓存池中去。

3.在你的作品中Cell是怎么计算行高的

答:以文章MVC模式下代码自定义cell(自计算行高)为例:
UITableView在代理方法cellForRowAtIndexPath里展示cell的时候,对于cell的创建是采用重用的机制,但是对于代理方法heightForRowAtIndexPath里是统一将所有的cell高度全部计算出来的。
为证明我的说法,在cellForRowAtIndexPath里添加如下打印语句:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 打印语句
NSLog(@"cellForRow--%ld", (long)indexPath.row);
heightForRowAtIndexPath里添加如下打印语句:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"heightForRow--%ld", (long)indexPath.row);
打印结果如下:

屏幕快照 2015-11-04 18.37.32.png
看到打印我就懵了,和以前不一样了......
总共有6个cell,高度全部计算出来了。在界面能显示出来的两个cell中先执行cellForRowAtIndexPath,再执行heightForRowAtIndexPath
具体哪个版本目前还不清楚,但至少在Xcode6.3以前heightForRowAtIndexPath方法将所有的cell高度全部计算出之后就不再执行此方法了,但目前来看显然不是。
好吧,先按照之前的情况来吧,目前这种自计算行高的方法仍然适用(如果看过文章MVC模式下代码自定义cell(自计算行高)会发现肯定适用啊)其实就是把cell的高度提前全都计算出来

这里以文章MVC模式下代码自定义cell(自计算行高)为例大体总结一下:
1.模型Query中,写一个构造方法解析字典属性,写一个类方法 通过调用构造方法返回解析的数据。
2.在继承自UIView的QueryFrame中,拥有cell中控件的属性,同行拥有模型Query属性和一个cellHeight属性,并重写其setter方法,在setter方法中计算cell中控件的frame和cell的高度
3.自定义的QueryCell继承自UITableViewCell,重写- (instancetype)initWithStyle方法,添加cell子控件。拥有QueryFrame属性,并重写其setter方法,在setter方法中为QueryCell中的控件绑定模型数据和计算子控件frame
4.QueryViewController里添加UITableView,并使用自定义的QueryCell。在Controller里加载plist文件,通过Model里的类方法解析后数据传给QueryCell的Borrow属性
5.在代理方法heightForRowAtIndexPath里调用QueryCell的QueryFrame属性的cellHeight来返回cell高度

4.代理模式是怎么使用的,自己写过吗?

答:自己写一个代理,用一个最简单经典的买票的例子吧。Person拥有一个买票的代理来查询票价和剩余票数
首先新建协议,声明代理中拥有的方法:
#import <Foundation/Foundation.h>
@protocol TicketDelegate <NSObject>
- (int)leftTicket;
- (double)ticketPrice;
@end
Person拥有一个代理和买票方法:
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@interface Person : NSObject
@property (nonatomic, retain)id<TicketDelegate> ticketDelegate;
- (void)buyTicket;
@end
在代理对象中遵守代理协议:
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@interface Delegate : NSObject <TicketDelegate>
@end
并实现代理的方法:
#import "Delegate.h"
@implementation Delegate
- (int)leftTicket {
return 10;
}
- (double)ticketPrice {
return 45.5;
}
@end
这样一来,就可以设置Person的代理为TicketDelegate,并调用代理的方法了:

Person *p = [[Person alloc] init];
Delegate *d = [[Delegate alloc] init];
p.ticketDelegate = d;
[p buyTicket];

同样的,要想让Person拥有其他的代理也是这样。
而想让另一个对象改变代理的具体行为,只需要让这个对象遵守TicketDelegate的协议并实现其声明的方法即可。当然这只是最简单基础的例子啦!

5.frame与bounds的区别

答:

6.关于CALayer

答:关于CALayer只是设置控件圆角的时候用过控件的layer属性
详细的就附几篇文章来看吧:
iOS开发UI篇—CALayer简介--系列
iOS 面试大全从简单到复杂(简单篇)
详解CALayer 和 UIView的区别和联系

7.关于GCD

答:这个......怎么答呢,因为开头就没有答好,所以面试官也没有往下问。
先看这篇博客吧iOS开发多线程篇—GCD介绍
组织好语言再来补充......

8.如何自定义UITabBarController和ViewController

答:没答出来。附一个连接,共同学习其开源代码吧https://github.com/ChenYilong/CYLTabBarController
有心得再来补充......

9.是否了解动画、Autolayout和后端

答:不了解所以就一带而过了。学到了再写Blog吧,迫不及待的学习......

以下是一些个人问题:

10.英语怎么样,阅读文档呢?
11.什么时候开始自学的,如何自学的?
12.来上海的原因
13.职业规划

就记得这么多了。

体会

后记

小白出手,请多指教。
如言有误,还望斧正!

再次感谢我的iOS启蒙老师MJ大大,遥祝小码哥越来越茁壮!----MJ万千桃李之一

上一篇下一篇

猜你喜欢

热点阅读