swift我们应该知道的

1.class 和 struct 的区别?

  • swift中,class是引用类型,struct是值类型。值类型在传递和赋值时将进行复制,而引用类型则只会使用引用对象的一个"指向"。所以他们两者之间的区别就是两个类型的区别。
  • class有这几个功能struct没有的:
    1.class可以继承,这样子类可以使用父类的特性和方法
    2.类型转换可以在runtime的时候检查和解释一个实例的类型
    3.可以用deinit来释放资源
    4.一个类可以被多次引用
  • struct也有这样几个优势:
    1.结构较小,适用于复制操作,相比于一个class的实例被多次引用更加安全。
    2.无须担心内存memory leak或者多线程冲突问题
  • 补充:
    C语言中,struct与的class的区别:
    struct只是作为一种复杂数据类型定义,不能用于面向对象编程。
    C++中,struct和class的区别:
    对于成员访问权限以及继承方式,class中默认的是private的,而struct中则是public的。class还可以用于表示模板类型,struct则不行。

2.介绍一下观察者模式

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

  • 观察者Observer,通过NSNotificationCenter的addObserver:selector:name:object接口来注册对某一类型通知感兴趣。在注册时候一定要注意,NSNotificationCenter不会对观察者进行引用计数+1的操作,我们在程序中释放观察者的时候,一定要去报从center中将其注销了。
  • 通知中心NSNotificationCenter,通知的枢纽。
  • 被观察的对象,通过postNotificationName:object:userInfo:发送某一类型通知,广播改变。
  • 通知对象NSNotification,当有通知来的时候,Center会调用观察者注册的接口来广播通知,同时传递存储着更改内容的NSNotification对象。

3.在一个HTTPS连接的网站里,输入账号密码点击登录后,到服务器返回这个请求前,中间经历了什么?

image.png
  1. 客户端打包请求。包括url,端口啊,你的账号密码等等。账号密码登陆应该用的是Post方式,所以相关的用户信息会被加载到body里面。这个请求应该包含三个方面:网络地址,协议,资源路径。注意,这里是HTTPS,就是HTTP + SSL / TLS,在HTTP上又加了一层处理加密信息的模块(相当于是个锁)。这个过程相当于是客户端请求钥匙。
  2. 服务器接受请求。一般客户端的请求会先发送到DNS服务器。 DNS服务器负责将你的网络地址解析成IP地址,这个IP地址对应网上一台机器。这其中可能发生Hosts Hijack和ISP failure的问题。过了DNS这一关,信息就到了服务器端,此时客户端会和服务器的端口之间建立一个socket连接,socket一般都是以file descriptor的方式解析请求。这个过程相当于是服务器端分析是否要向客户端发送钥匙模板。
  3. 服务器端返回数字证书。服务器端会有一套数字证书(相当于是个钥匙模板),这个证书会先发送给客户端。这个过程相当于是服务器端向客户端发送钥匙模板。
  4. 客户端生成加密信息。根据收到的数字证书(钥匙模板),客户端会生成钥匙,并把内容锁上,此时信息已经加密。这个过程相当于客户端生成钥匙并锁上请求。
  5. 客户端发送加密信息。服务器端会收到由自己发送出去的数字证书加锁的信息。 这个时候生成的钥匙也一并被发送到服务器端。这个过程是相当于客户端发送请求。
  6. 服务器端解锁加密信息。服务器端收到加密信息后,会根据得到的钥匙进行解密,并把要返回的数据进行对称加密。这个过程相当于服务器端解锁请求、生成、加锁回应信息。
  7. 服务器端向客户端返回信息。客户端会收到相应的加密信息。这个过程相当于服务器端向客户端发送回应。
  8. 客户端解锁返回信息。客户端会用刚刚生成的钥匙进行解密,将内容显示在浏览器上。

HTTPS加密过程详解请去:https原理:证书传递、验证和数据加密、解密过程解析

4.在一个app中间有一个button,在你手触摸屏幕点击后,到这个button收到点击事件,中间发生了什么?

  • 响应链大概有以下几个步骤:
  1. 设备将touch到的UITouch和UIEvent对象打包, 放到当前活动的Application的事件队列中
  2. 单例的UIApplication会从事件队列中取出触摸事件并传递给单例UIWindow
  3. UIWindow使用hitTest:withEvent:方法查找touch操作的所在的视图view
  • RunLoop这边我大概讲一下
  1. 主线程的RunLoop被唤醒
  2. 通知Observer,处理Timer和Source 0
  3. Springboard接受touch event之后转给App进程中
  4. RunLoop处理Source 1,Source1 就会触发回调,并调用_UIApplicationHandleEventQueue() 进行应用内部的分发。
  5. RunLoop处理完毕进入睡眠,此前会释放旧的autorelease pool并新建一个autorelease pool

深挖请去深入理解RunLoop

5. 不通过继承,代码复用(共享)的方式有哪些?

在swift 文件里直接写方法,相当于一个全局函数。
extension 给类直接扩展方法。

6. Set 独有的方法有哪些?

  • 不会出现重复的值。
  • 里面的元素必须时相同的类型。

7. 实现一个 min 函数,返回两个元素较小的元素?

func min(_ a : T , b : T) -> T {
    return a < b ? a : b
}

8. map、filter、reduce 的作用?

  • map : 映射 , 将一个元素根据某个函数 映射 成另一个元素(可以是同类型,也可以是不同类型)
  • filter : 过滤 , 将一个元素传入闭包中,如果返回的是false , 就过滤掉
  • reduce :先映射后融合(这样说容易理解) , 将数组中的所有元素映射融合在一起。举个例子:
struct Person {
    let name : String
    let money : String
}
let a = Person(name: "小王", money: "5.0")
let b = Person(name: "小李", money: "7.1")
let c = Person(name: "小张", money: "3.22")

let sumMoney = [a , b , c].reduce(0) {
    return $0 + ($1.money as NSString).doubleValue
}
print(sumMoney)

9.map 与 flatmap 的区别

map不能将元素映射成可选类型,flatmap可以

10.如何获取当前代码的函数名和行号?

函数名#functio 行号#line 文件名#file

11.如何声明一个只能被类 conform 的 protocol?

protocol OnlyClassProtocol : class {
}

12.guard 使用场景?

可以理解为拦截,凡是不满足 guard 后面条件的,都不会再执行下面的代码。
我一般用来解包 。 不能解包的, 就不能执行下面的代码

相当于

if !(...) {
  return
}

13. defer 使用场景?

在一对花括号 : { } 里 使用defer ,这个defer 里面的内容将会在结束 {} 前(or 后?) 被执行


image.png

14.String 与 NSString 的关系与区别?

能够互相转换,一个值类型,一个引用类型

15.怎么获取一个 String 的长度?

print( "abcdefg".characters.count ) 
//7
("abcdefg" as NSString).length //这个要算作NSString的获取长度的方法

16.throws 和 rethrows 的用法与作用?

  • throws 声明在函数的末尾,表示这个函数会抛出 Error的子类.
  • rethrows 再传入throws的闭包时,这个函数返回用rethrows

17. try? 和 try!是什么意思?

  • try! 强制抛出错误,有错误就会崩溃
  • try? 抛出错误,没错误不会崩溃直接返回
    try
    如果不用do catch , 就会编译报错
    image.png

    如果函数后面加上 throws , 将错误传递下去. 即使不用都do catch 编译也不会报错。 但是调用throwfun2()还是要使用do catch
    image.png

17.associatedtype 的作用?

相当于protocol的范型

protocol Animal {
    associatedtype AnimalType : Comparable
}
extension Animal {
    typealias AnimalType = Self
}

18. 什么时候使用 final?

  • 不允许class 被继承
  • 不允许函数被重写

19. private、fileprivate、internal、public和open的区别的区别?

在Swift语言中,访问修饰符有五种,分别为fileprivate,private,internal,public和open,其中 fileprivate和open是Swift 3新添加的。由于过去 Swift对于访问权限的控制是基于文件的,不是基于类的。这样会有问题,所以Swift 3新增了两个修饰符对原来的private、public进行细分。
private

  • private所修饰的属性或者方法只能在当前类里访问
  • private所修饰类只能在当前.swift文件里访问
    fileprivate
  • fileprivate访问级别所修饰的属性或者方法在当前的Swift源文件里可以访问。
    internal(默认访问级别,internal修饰符可写可不写)
  • internal访问级别所修饰的属性或方法在源代码所在的整个模块都可以访问、被继承、被重写
  • 如果是框架或者库代码,则在整个框架内部都可以访问,框架由外部代码所引用时,则不可以访问。
    即使使用import,也会提示错误:
No such module '...'

public

  • 可以被任何人访问。但其他module中不可以被override和继承,而在module内可以被override和继承。
    open
  • 可以被任何人使用,包括override和继承。
  • 访问权限排序从高到低排序:open>public>interal > fileprivate >private

20.声明一个只有一个参数没有返回值闭包的别名?

typealias NoReturn = (String) -> Void

21.dynamic 的作用?

由于 swift 是一个静态语言, 所以没有 Objective-C 中的消息发送这些动态机制, dynamic 的作用就是让 swift 代码也能有 Objective-C 中的动态机制, 常用的地方就是 KVO 了, 如果要监控一个属性, 则必须要标记为 dynamic

22.什么时候使用 @objc?

  • @objc 用途是为了在 Objective-C 和 Swift 混编的时候, 能够正常调用 Swift 代码. 可以用于修饰类, 协议, 方法, 属性.
  • 常用的地方是在定义 delegate 协议中, 会将协议中的部分方法声明为可选方法, 需要用到@objc

23.Optional(可选型) 是用什么实现的?

  • Optional 是一个泛型枚举
    大致定义如下:
enum Optional {
 case none
 case some(Wrapped)
}
  • 除了使用 let someValue: Int? = nil 之外, 还可以使用let optional1: Optional = nil 来定义

24.如何自定义下标获取?

实现 subscript 即可, 如


image.png

索引除了数字之外, 其他类型也是可以的

24.?? 的作用

当 ?? 前面的值为nil 的时候就取 ??后面的值

25. lazy 的作用?

只有属性被调用的时候才会执行lazy

26. 一个类型表示选项,可以同时表示有几个选项选中(类似 UIViewAnimationOptions ),用什么类型表示?

继承了OptionSet的struct , enum 。 class 没有试过,应该也可以

27. inout 的作用?

改变函数外的值

28. Error 如果要兼容 NSError 需要做什么操作?

  • Error是一个协议, swift中的Error 都是enum, 可以转 NSError
  • 如果需要Error有NSError的功能,实现 LocalizedError CustomNSError 协议

29. 下面的代码都用了哪些语法糖 [1, 2, 3].map{ $0 * 2 }?

  • 用$0 捕获第一个参数。
  • 只有一行代码的时候, 隐藏掉了 return 。

30.什么是高阶函数?

一个函数如果可以以某一个函数作为参数, 或者是返回值, 那么这个函数就称之为高阶函数, 如map、flatMap、filter、reduce?

30.如何解决引用循环?

  • 转换为值类型, 只有类会存在引用循环, 所以如果能不用类, 是可以解引用循环的,
  • delegate 使用 weak 属性.
  • 闭包中, 对有可能发生循环引用的对象, 使用 weak 或者 unowned, 修饰

31.定义静态方法时关键字 static 和 class 有什么区别?

static 定义的方法不可以被子类继承, class 则可以
struct 只能用static
class 的属性只能用 static , 其他地方都能随便用。
非class类型 一般 统一用 static 例如 枚举 结构体
protocol中 使用 static ,实现协议的 枚举 结构体 用 static

32.一个 Sequence 的索引是不是一定从 0 开始?

不是。
ArraySlice是Sequence的子类,ArraySlice就不是

33.autoclosure 的作用?

自动闭包,将参数自动封装为闭包参数

34.编译选项 whole module optmization 优化了什么?

编译器可以跨文件优化编译代码, 不局限于一个文件.

35.dynamic framework 和 static framework 的区别是什么?

静态库和动态库, 静态库是每一个程序单独打包一份, 而动态库则是多个程序之间共享

36.如何让自定义对象支持字面量初始化?

ExpressibleByArrayLiteral 可以由数组形式初始化
ExpressibleByDictionaryLiteral 可以由字典形式初始化
ExpressibleByNilLiteral 可以由nil 值初始化
ExpressibleByIntegerLiteral 可以由整数值初始化
ExpressibleByFloatLiteral 可以由浮点数初始化
ExpressibleByBooleanLiteral 可以由布尔值初始化
ExpressibleByUnicodeScalarLiteral
ExpressibleByExtendedGraphemeClusterLiteral
ExpressibleByStringLiteral
这三种都是由字符串初始化, 上面两种包含有 Unicode 字符和特殊字符

一.卓同学的 Swift 面试题
答 《卓同学的 Swift 面试题》
答《卓同学的 Swift 面试题》上
答《卓同学的 Swift 面试题》下

你可能感兴趣的:(swift我们应该知道的)