iOS 开发者 2019 面试总结

前言:致一个开发者,有一个学习的氛围跟一个交流圈子特别重要这是一个我的iOS交流群:869685378,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

 

在投递简历之前,就是所谓的寒冬将至,开个年会都是守望寒冬,然后我身边的准备跳槽的大佬们,都是有几分凉意,不过我还好,总感觉一个人吃饱,全家不饿,O(∩_∩)O哈!没想那么多,直接就全身投入,找工作。现在做个回顾吧,为自己,也为路过的各位大侠。


先说一个问题,是寒冬吗?我真没觉得,说自己的一个亲身体会,不夸张的说,基本上是每天2家,且持续一个月,当然是距离可以接受,公司小中大都有的,我感觉不是互联网的寒冬,是自己的寒冬,有一句说的很好,人生就两季,努力是旺季,不努力是淡季!我感觉很有道理~~~~


现在面试要求高在要会各种语言,另外要很深入,要够底层,要懂数据结构与算法之美(面试过的都会体会什么是真是一言难尽吧),看一些大佬,进入一个大厂,也写了自己的准备,我感觉真是有付出有回报的,也看出自己的一些不足吧!so,革命尚未成功,同志们仍需努力伐!!

 

知识点总结

 

因为自己水平有限,可能有些路过的大佬感觉比较简单,我也总结了下,请飘过~~还有一些答案仅供参考,如有错误,请不吝赐教,在此谢过—->

 

+(void)initinstance 与 +(void)load两个方法的区别于比较//小红书面试问题\

 

先看下面表格两者的区别,后续会继续介绍

 

  +load +initialize
调用时机 被添加runtime时 收到第一条消息时,可能永远不调用
调用顺序 父类->子类->分类 父类->子类
调用次数 1次 多次
是否需要显示调用父类实现
是否沿用父类的实现
分类中的实现 类和分类都执行  

 

相同点:

 

  1. 系统都执行一次。

  2. 假如父类和子类都被调用,父类在子类之前被调用

 

不同点:

 

 

  1. load 方法会在加载类的时候就被调用,也就是 ios 应用启动的时候,就会加载所有的类,就会调用每个类的 + load 方法。

  2. +initialize 这个方法会在 第一次初始化这个类之前 被调用,我们用它来初始化静态变量

  3. load 会在main()函数之前调用。initialize 则在类实例化 或 类方法被调用时调用;

  4. 如果子类中没有initialize方法,则会再次调用父类的initialize方法,类别会覆盖主类的initialize,load则不会被覆盖

  5. load顺序在 initialize之前;

  6.  •  initialize 方法的调用看起来会更合理,通常在它里面写代码比在 + load 里写更好,因为它是懒调用的,也有可能完全不被调用。类第一次被加载时,

  7. 类接收消息时,运行时会先检查 + initialize 有没有被调用过。如果没有,会在消息被处理前调用

 

—>>>>
initialize 最终是通过 objc_msgSend 来执行的,objc_msgSend 会执行一系列方法查找,并且 Category 的方法会覆盖类中的方法
load 是在被添加到 runtime 时开始执行,父类最先执行,然后是子类,最后是 Category。又因为是直接获取函数指针来执行,不会像 objc_msgSend 一样会有方法查找的过程。

 

—->>>>

 

怎么实现单例, 2种方法实现//喜马拉雅面试问题\

 

 

 

//第一种方式:线程安全的单例2(不推荐 效率低)
+ (instancetype)shareSingleton2 {
    @synchronized(self) {
        if (!singleton) {
            singleton = [[self alloc]init];
        }
    }
    return singleton;
}

//第二种方式 线程安全的单例
+ (instancetype)shareSingleton {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[self alloc]init];
    });
    return singleton;
}

 

 

然而仅仅知道这些是不够的,说了上面的,面试官会继续问单例,怎么实现的,加锁了吗?单例什么时候释放?然后你就会一脸懵~有同感的举个手

 

  • 单例,怎么实现的,加锁了吗?单例什么时候释放
    其实在上面的两个单例的创建中,@synchronized是一个锁,后面会讲到,就是说第一种是通过加锁的方式来实现,而第二种解析如下:
    GCD创建:dispatch_once中dispatch_once_t类型为typedef long
    •   onceToken= 0,线程执行dispatch_once的block中代码
    •   onceToken= -1,线程跳过dispatch_once的block中代码不执行
    •   onceToken= 其他值,线程被线程被阻塞,等待onceToken值改变
    用途:限制创建,提供全局调用,节约资源和提高性能。参考
    常见的应用场景:
    •   UIApplication
    •   NSNotificationCenter
    •   NSFileManager
    •   NSUserDefaults
    •   NSURLCache
    •   NSHTTPCookieStorage

 


 

那么单例是怎么销毁的呢?如下:

 

 

 

 

方法一:
+(void)attemptDealloc{
    [_instance release]; //mrc 需要释放,当然你就不能重写release的方法了.
    _instance = nil;
}


方法二:
1. 必须把static dispatch_once_t onceToken; 这个拿到函数体外,成为全局的.
2.
+(void)attempDealloc{
    onceToken = 0; // 只有置成0,GCD才会认为它从未执行过.它默认为0.这样才能保证下次再次调用shareInstance的时候,再次创建对象.
    [_instance release];
    _instance = nil;
 }

 

 

数据持久化

 

 

下面说下数据持久化吧?如果是在2年前,你说了数据持久化有NSUserDefaults,plist,归档,CoreData巴拉巴拉,感觉这位童靴还阔以,但是现在就有点low了,你懂得~
面试大佬会问有几种?然后每种有什么不同?什么能存储什么不能存储?每个在具体使用应该注意什么?等等,问到你怀疑人生

 

  • 属性列表(plist存储)通常叫做plist文件,用于存储在程序中不经常修改、数据量小的数据,不支持自定义对象存储,支持数据存储的类型为:Array,Dictionary,String,Number,Data,Date,Boolean,通常用来存放接口名、城市名、银行名称、表情名等极少修改的数据
    plist文件是将某些特定的类,通过xml的方式保存在目录中。

 

 

  • 偏好设置(NSUserDefaults)
    用于存储用户的偏好设置,同样适合于存储轻量级的用户数据,数据会自动保存在沙盒的Libarary/Preferences目录下,本质上就是一个plist文件,所以同样的不支持自定义对象存储,支持数据存储的类型为:Array,Dictionary,String,Number,Data,Date,Boolean,可以用做检查版本是否更新、是否启动引导页、自动登录、版本号等等,需要注意的是NSUserDefaults是定时的将缓存中的数据写入磁盘,并不是即时写入,为了防止在写完NSUserDefaults后,程序退出导致数据的丢失,可以在写入数据后使用synchronize强制立即将数据写入磁盘
    如果这里你没有调用synchronize方法的话,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。

 

 


 

PS: 在这里说了小问题,就是有面试官会问,你在开发中用NSUserDefaults有没有什么坑?你可以这样答:比如你存储一个值时,没有进行及时的调用synchronize方法,然后此时程序就crash了或者强制杀死,那么你再下次去取值的时候,就会取不到你之前存储的值,路过的大佬可以试下~~

 

  • 归档序列化存储
    归档可以直接将对象存储为文件,也可将文件直接解归档为对象,相对于plist文件与偏好设置数据的存储更加多样,支持自定义的对象存储,归档后的文件是加密的,也更加的安全,文件存储的位置可以自定义。
    遵守NSCoding或者NSSecureCoding协议

 

 

 

  • 沙盒存储
    可以提高程序的体验度,为用户节约数据流量,主要在用户阅读书籍、听音乐、看视频等,在沙盒中做数据的存储,主要包含文件夹:Documents: 最常用的目录,存放重要的数据,iTunes同步时会备份该目录Library/Caches: 一般存放体积大,不重要的数据,iTunes同步时不会备份该目录Library/Preferences: 存放用户的偏好设置,iTunes同步时会备份该目录tmp: 用于存放临时文件,在程序未运行时可能会删除该文件夹中的数据,iTunes同步时不会备份该目录

 

 

  • Core Data
    Core Data是框架,并不是数据库,该框架提供了对象关系的映射功能,使得能够将OC对象转换成数据,将数据库中的数据还原成OC对象,在转换的过程中不需要编写任何的SQL语句,在Core Data中有三个重要的概念:
    NSPersistentStoreCoordinator:持久化存储协调器,在NSPersistentStoreCoordinator中包含了持久化存储区,在持久化存储区中包含了数据表中的很多数据,持久化存储区的设置通常选择NSSQLiteStoreType,也就是选择SQLite数据库
    NSManagedObjectModel:托管对象模型,用于描述数据结构的模型

 

 

  • SQLite3
    SQLite是轻量级的数据库,占用资源很少,最初是用于嵌入式的系统,在iOS中使用SQLite,需要加入”libsqlite3.tbd”依赖库并导入头文件。不应该频繁的打开关闭数据库,有可能会影响性能, 应在启动程序时打开数据库,在退出程序是关闭数据库

     

 

 

  • FMDB
    FMDB以OC的方式封装了SQLite的C语言API,减去了冗余的C语言代码,使得API更具有OC的风格,更加的面向对象,相对于Core Data框架更加的轻量级,FMDB还提供了多线程安全的数据库操作方法,在FMDB中有三个重要的概念:
    FMDatabase:一个FMDatabase就代表一个SQLite数据库,执行sql语句
    FMResultSet:执行查询后的结果集
    FMDatabaseQueue:用于在多线程中执行多个查询或更新,安全的

 

===
紧接着说下CoreData吧?它总是比你知道的还要多?
CoreData中的多线程问题

 

主要推荐的实施方案,也是最优方案,如下:
1.使用一个NSPersistentStoreCoordinator,以及两个独立的Contexts,一个context负责主线程与UI协作,一个context在后台负责耗时的处理,用Notifications的方式通知主线程的NSM

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值