内容绝大部分摘抄网上,如有侵权请联系我删除,谢谢!
下面的问题有的没有做解答,后面会慢慢补上!
前言
关于"面试官问这么基础的问题有必要吗"这个话题一直以来争论不休;其实我们可以这样理性的分析问题。
面试官问的这些基础问题更多的是一些知识的深入, 这些知识大多是我们开发中不怎么想深入或者觉得不需要深入了解的; 比如NSString属性用strong关键字有啥利弊等。
我目前在小公司待着,对于网上的面试题我70%都不能完美解答但是项目依然不会出现明显问题;这样看来基础显得不重要,因为小公司我们大多只有一至二个人开发没时间去深入基础,我们的应用量级也不大问题也就不会暴露出来;对我来说这些基础更多的是工作之余深入。
但是对于BAT这样的公司来说基础尤为重要,因为量级的原因问题很容易被暴露出来,在大公司的开发者写代码需要更严谨,这时候基础的作用体现出来了,不深入理解根本写不出能支持如此大体量的代码;所以他们时刻都在深入基础。
对于小公司来说,需要的是能按照需求写出功能的开发者,项目不难体量也不大,基础不怎么看重,所以问面试者的问题更多的是自己公司用到的一些技术。也就是说小公司招一个基础很好的也没用,在小公司待久了的程序员更多会变为业务型程序员。
业务型程序员:能完成指定的功能,技术难度低;一只写业务代码对自己的 技术没有太大的提升;更多的提升在于对业务的了解。
对于大公司,需要的是深入基础的程序员,因为要写出支持大体量的代码,对于一些没用过的技术比如音视频处理无所谓,因为基础好了学啥都快。
首先是为了提升自己,因为自己在小公司,不想变成纯业务型程序员;
然后是公司闲暇时间多,有时间去了解并整理这些;
其实是自己有一个开发群,很容易收集问题;
最后是把整个文章当成一个笔记的作用,时不时的翻阅。
问题列表汇总,你可以复制其中的问题全文搜索找到对应的答案。
面向对象设计原则 iOS应用导航模式有哪些 iOS持久化方式有哪些NSClassFromString加载静态库中的类什么情况是nilid和NSObject*的区别 简单描述一下Runtime Runtime给类添加属性、成员变量 KVO原理 Property修饰符 程序内存分区extern的作用 指针函数/函数指针/Block __weak、__strong、__block理解 事件传递链/事件响应链 简述RunLoopNSTimer原理 简述GCD 自动释放池 iOS中的定时器UIView/UILayer关系 简述你了解的锁 ISO七层、TCP/IP四层协议 什么是ARC iOS类和结构体有什么区别 iOS通知和协议的区别 iOS内存使用注意事项和优化 ViewController完整生命周期 frame和bounds区别@synthesize和@dynamic的作用 SDWebImage作用 XML解析方式 AFNetWorking作用 Http协议特点,GET/POST请求区别 Socket连接和Http连接区别 Tcp三次握手、四次挥手 performSelector传三个参数(未解答) main方法前过程 线程安全方法NSOperationQueue和GCD区别联系 iOS常用设计模式 简述Block 消息动态处理/转发流程weak变量怎么置为nil对nil发消息会发生什么 安全区域的理解UITableView优化方法 ssl/tls证书作用 MVC、MVP、MVVM
单一职责原则,开闭原则,依赖倒置原则(面向接口编程),迪米特原则,里氏替换原则,接口隔离原则。
这个问题更多是设计人员考虑的,不过我们也需要了解,不然我们都不知道UITabBarController和UINavigationController等存在的意义是啥。
iOS应用属于客户端应用,问题其实是问下面两个部分:
1:什么是导航模式?客户端导航模式有哪些常见的? 2:iOS中存在哪些导航模式?
导航模式:将信息以最优的方式组织起来展现给用户。
客户端常见模式:tab、抽屉、列表、平铺/轮播、宫格和悬浮icon等。
注:不要太在意名称,你会在网上搜到一种模式有多种名称。
这里并不是问你哪些控件/控制器对应这些导航模式,所以iOS具有上面提到的所有导航模式。
首先这里的持久化指的是数据持久化,目前客户端的持久化也只有这一个含义。
为何要持久化:iOS开发可以没有持久化,持久化更多的是业务需求;比如记录用户是否登陆,下次进应用不需要再登陆。
因为iOS的沙盒机制,所以持久化分为两类:沙盒内和沙盒外。
只要遵循了NSCoding协议并正确实现了initWithCoder和encodeWithCoder方法的类都可以通过NSKeyedArchiver来序列化。
归档使用archiveRootObject,解归档使用unarchiveObjectWithFile;需要指定文件路径。
[NSUserDefaults standardUserDefaults]获取NSUserDefaults对象,以key-value方式进行持久化操作。
写入使用writeToFile,读取使用xxxWithContentsOfFile;需要指定文件路径。
数据库无疑是大量数据最好的持久化方案,数据库目前有:sqlite、CoreData和Realm等。这里就不用回答FMDB它只是封装了sqlite而已。
这里要和plist区分一下,plist方式是字典/数组数据格式写入文件;而这里的文件方式不限数据格式。
沙盒内的方式在应用被删除后数据都会丢失,如果想要不丢失则需要使用KeyChain。
KeyChain本质是一个sqlite数据库,其保存的所有数据都是加密过的。
KeyChain分为私有和公有,公有则需要指定group,一个group中的应用可以共享此KeyChain。
使用KeyChain过程中要理解下面几个问题:
1:自己使用的KeyChain和系统自带的KeyChain数据是隔离的,内部应该是不同数据库文件; 2:KeyChain数据可备份到iCloud中; 3:不需要联网,也不用登陆iCloud账号;一个设备一个sqlite数据库,但是不同应用组不共享数据; 4:要在另一台设备上使用当前设备存储的KeyChain信息,需要当前设备进行数据备份, 再在另一设备上复原数据;比较常用的是iCloud备份方式; 5:系统自带的KeyChain中账号密码分类数据可在系统设置->账号与密码里面看到, 你退出iCloud账号还是存在,只是iCloud会帮你备份如果你设置了的话;这个和照片是一样的道理。
持久化
iOS 数据持久化的几种方法
聊聊iOS KeyChain
NSClassFromString动态加载是OC中runtime的一个方法,用来从字符串得到一个class对象,当系统给应用分配的运行内存中没有这个类时会返回nil;静态库在链接阶段会被写入到执行文件,这里要注意了,如果工程中没有用到静态库中的某些类,那么这些类是不会写入到执行文件的,自然系统给应用分配的运行内存中没有这个类。所以NSClassFromString返回nil只在工程中没有使用到该类的情况下。
有人可能会问了,那我可以在运行的时候手动加载库到运行内存吗?动态库是可以的,这样就是插件化了;静态库因为最后打包的包里没有这个文件了,所以没办法获取到该静态库。而动态库在工程General的Embedded Binaries中加入该动态库,则打包后包内有一个framework文件夹专门放动态库,则可以实现手动加载。
又有人问了,General的Linked Frameworks and Libraries又是什么作用呢?好吧一般我们都忽略这个了,因为拖入库到工程默认就会把该库加入到此处,如果不加且你工程直接使用了该类则build通不过;使用workspace设置工程依赖实现组件化等为了解决相应问题而使用此实现思路情况下,要在适当的project的此处手动添加被依赖库,如果不加且你工程直接使用了该类则build通不过。
这个问题没有固定的答案,只需要答到比较重要的点就可以了。
你可以从
id的定义:
typedef struct objc_object { struct objc_class *isa; } *id;
NSObject的定义:
@interface NSObject { struct objc_class *isa; }
开始分析得先知道这样一个事实,iOS中不是所有的类都继承自NSObject:
@interface NSProxy { struct objc_class *isa; }
所以也就得出了答案:id可以指向oc中的任何对象,而NSObject*只能指向NSObject及子类对象。
Runtime是一个运行时系统,用来执行编译链接后的可执行文件;它将很多静态语言在编译和链接时期做的事放到了运行时来处理。这种我们写代码更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等。
objc_class的定义:
struct objc_class { Class _Nonnull isa OBJC_ISA_AVAILABILITY; Class _Nullable super_class OBJC2_UNAVAILABLE; const char * _Nonnull name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE; struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE; struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE; struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;};
从中可以看出,我们可以修改一些值达到运行时改变原有行为的目的;比如给对象调用方法是从methodLists查找方法实现等。
延伸内容举个例子:Runtime是怎么对对象发送消息的呢?
先需要了解object_class中isa和super_class指的是什么。
本文由 投稿者 创作,文章地址:https://blog.isoyu.com/archives/iosmianshitimianshidazhemeduojiukeyile.html
采用知识共享署名4.0 国际许可协议进行许可。除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为:5 月 31, 2018 at 05:54 下午