初级

问题1- Swift 1.0 or later

什么是optional类型,它是用来解决什么问题的?

答案:optional类型被用来表示任何类型的变量都可以表示缺少值。在Objective-C中,引用类型的变量是可以缺少值得,并且使用nil作为缺少值。基本的数据类型如int 或者float没有这种功能。

Swift用optional扩展了在基本数据类型和引用类型中缺少值的概念。一个optional类型的变量,在任何时候都可以保存一个值或者为nil。

问题2- Swift 1.0 or later

在Swfit中,什么时候用结构体,什么时候用类?

答案:一直都有这样的争论:到底是用类的做法优于用结构体,还是用结构体的做法优于类。函数式编程倾向于值类型,面向对象编程更喜欢类。

在Swift 中,类和结构体有许多不同的特性。下面是两者不同的总结:

类支持继承,结构体不支持。

类是引用类型,结构体是值类型

并没有通用的规则决定结构体和类哪一个更好用。一般的建议是使用最小的工具来完成你的目标,但是有一个好的经验是多使用结构体,除非你用了继承和引用语义。

想要了解更多,点击这里

注意:在运行时,结构体的在性能方面更优于类,原因是结构体的方法调用是静态绑定,而类的方法调用是动态实现的。这就是尽可能得使用结构体代替类的又一个好的原因。

问题3- Swift 1.0 or later

什么是泛型?泛型是用来解决什么问题的?

答案:泛型是用来使类型和算法安全的工作的一种类型。在Swift中,在函数和数据结构中都可以使用泛型,例如类、结构体和枚举。

泛型一般是用来解决代码复用的问题。常见的一种情况是,你有一个函数,它带有一个参数,参数类型是A,然而当参数类型改变成B的时候,你不得不复制这个函数。

例如,下面的代码中第二个函数就是复制第一个函数——它仅仅是用String类型代替了Integer类型。

1
2
3
4
5
6
7
8
9
10
func areIntEqual(x: Int, _ y: Int) -> Bool {
  return x == y
}
  
func areStringsEqual(x: String, _ y: String) -> Bool {
  return x == y
}
  
areStringsEqual("ray""ray"// true
areIntEqual(1, 1) // true

Objective-C开发人员可能想到用NSObject类来解决这个问题,代码如下:

1
2
3
4
5
6
7
8
import Foundation
  
func areTheyEqual(x: NSObject, _ y: NSObject) -> Bool {
  return x == y
}
  
areTheyEqual("ray""ray"// true
areTheyEqual(1, 1) // true

这个代码会按照预期的方式工作,但是它在编译时不安全。它允许字符串和整数相比较,像这样:

1
areTheyEqual(1, "ray")

应用程序不会崩溃,但是允许字符串和整数相比较可能不是预想的结果。

通过采用泛型,可以合并这两个函数为一个并同时保持类型安全。下面是代码实现:

1
2
3
4
5
6
func areTheyEqual(x: T, _ y: T) -> Bool {
  return x == y
}
  
areTheyEqual("ray""ray")
areTheyEqual(1, 1)

上面的例子是测试两个参数是否相等,这两个参数的类型受到约束都必须遵循Equatable协议。上面的代码达到预想的结果,并且防止了传递不同类型的参数。

问题4- Swift 1.0 or later

哪些情况下你不得不使用隐式拆包?说明原因。

答案:对optional变量使用隐式拆包最常见的原因如下:

1、对象属性在初始化的时候不能nil,否则不能被初始化。典型的例子是Interface Builder outlet类型的属性,它总是在它的拥有者初始化之后再初始化。在这种特定的情况下,假设它在Interface Builder中被正确的配置——outlet被使用之前,保证它不为nil。

2、解决强引用的循环问题——当两个实例对象相互引用,并且对引用的实例对象的值要求不能为nil时候。在这种情况下,引用的一方可以标记为unowned,另一方使用隐式拆包。

建议:除非必要,不要对option类型使用隐式拆包。使用不当会增加运行时崩溃的可能性。在某些情况下,崩溃可能是有意的行为,但有更好的方法来达到相同的结果,例如,通过使用fatalError( )函数。

问题5- Swift 1.0 or later

对一个optional变量拆包有多少种方法?并在安全方面进行评价。

答案:

  • 强制拆包 !操作符——不安全

  • 隐式拆包变量声明——大多数情况下不安全

  • 可选绑定——安全

  • 自判断链接(optional chaining)——安全

  • nil coalescing 运算符(空值合并运算符)——安全

  • Swift 2.0 的新特性 guard 语句——安全

  • Swift 2.0 的新特性optional pattern(可选模式) ——安全(@Kametrixom支持)

中级

问题1- Swift 1.0 or later

Swift 是面向对象编程语言还是函数式编程语言?

答案:Swift是一种混合编程语言,它包含这两种编程模式。它实现了面向对象的三个基本原则:

  • 封装

  • 继承

  • 多态

说道Swift作为一种函数式编程语言,我们就不得不说一下什么是函数式编程。有很多不同的方法去定义函数式编程语言,但是他们表达的意义相同。

最常见的定义来自维基百科:...它是一种编程规范…它把电脑运算当做数学函数计算,避免状态改变和数据改变。

很难说Swift是一个成熟的函数式语言,但是它已经具备了函数式语言的基础。

问题2- Swift 1.0 or later

下面的功能特性都包含在Swift中吗?

1、泛型类

2、泛型结构体

3、泛型协议

答案:

  • Swift 包含1和2特性。泛型可以在类、结构体、枚举、全局函数或者方法中使用。

  • 3是通过typealias部分实现的。typealias不是一个泛型类型,它只是一个占位符的名字。它通常是作为关联类型被引用,只有协议被一个类型引用的时候它才被定义。

问题3- Swift 1.0 or later

在Objective-C中,一个常量可以这样定义:

1
const int number = 0;

类似的Swift是这样定义的:

1
let number = 0

两者之间有什么不同吗?如果有,请说明原因。

答案:const常量是一个在编译时或者编译解析时被初始化的变量。通过let创建的是一个运行时常量,是不可变得。它可以使用stattic 或者dynamic关键字来初始化。谨记它的的值只能被分配一次。

问题4- Swift 1.0 or later

声明一个静态属性或者函数,我们常常使用值类型的static修饰符。下面就是一个结构体的例子:

1
2
3
struct Sun {
  static func illuminate() {}
}

对类来说,使用static 或者class修饰符,都是可以的。它们使用后的效果是一样的,但是本质上是不同的。能解释一下为什么不同吗?

答案:

static修饰的属性或者修饰的函数都不可以重写。但是使用class修饰符,你可以重写属性或者函数。

当static在类中应用的时候,static就成为class final的一个别名。

例如,在下面的代码中,当你尝试重写illuminate()函数时,编译器就会报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Star {
  class func spin() {}
  static func illuminate() {}
}
  
class Sun : Star {
  override class func spin() {
    super.spin()
  }
  override static func illuminate() { // error: class method overrides a 'final' class method
    super.illuminate()
  }
}

问题5- Swift 1.0 or later

你能通过extension(扩展)保存一个属性吗?请解释一下原因。

答案:不能。扩展可以给当前的类型添加新的行为,但是不能改变本身的类型或者本身的接口。如果你添加一个新的可存储的属性,你需要额外的内存来存储新的值。扩展并不能实现这样的任务。

高级

问题1- Swift 1.2

在Swift1.2版本中,你能解释一下用泛型来声明枚举的问题吗?拿下面代码中Either枚举来举例说明吧,它有两个泛型类型的参数T和V,参数T在关联值类型为left情况下使用,参数V在关联值为rihgt情况下使用,代码如下:

1
2
3
4
enum Either{
  case Left(T)
  case Right(V)
}

提示:验证上面的条件,需要在Xcode工程里面,而不是在Playgroud中。同时注意,这个问题跟Swift1.2相关,所以Xcode的版本必须是6.4以上。

答案:上面的代码会出现编译错误:

1
unimplemented IR generation feature non-fixed multi-payload enum layout

问题是T的内存大小不能确定前期,因为它依赖于T类型本身,但enum情况下需要一个固定大小的有效载荷。

最常用的解决方法是讲泛类型用引用类型包装起来,通常称为box,代码如下:

1
2
3
4
5
6
7
8
9
10
11
class Box{
  let value: T
  init(_ value: T) {
    self.value = value
  }
}
  
enum Either{
  case Left(Box)
  case Right(Box)
}

这个问题在Swift1.0及之后的版本出现,但是Swift2.0的时候,被解决了。

问题2- Swift 1.0 or later

闭包是引用类型吗?

答案:闭包是引用类型。如果一个闭包被分配给一个变量,这个变量复制给另一个变量,那么他们引用的是同一个闭包,他们的捕捉列表也会被复制。

问题3- Swift 1.0 or later

UInt类型是用来存储无符号整型的。下面的代码实现了一个有符号整型转换的初始化方法:

init(_ value: Int)

然而,在下面的代码中,当你给一个负值的时候,它会产生一个编译时错误:

let myNegative = UInt(-1)

我们知道负数的内部结构是使用二进制补码的正数,在保持这个负数内存地址不变的情况下,如何把一个负整数转换成一个无符号的整数?

答案:使用下面的初始化方法:

UInt(bitPattern: Int)

问题4- Swift 1.0 or later

描述一种在Swift中出现循环引用的情况,并说明怎么解决。

答案:循环引用出现在当两个实例对象相互拥有强引用关系的时候,这会造成内存泄露,原因是这两个对像都不会被释放。只要一个对象被另一个对象强引用,那么该对象就不能被释放,由于强引用的存在,每个对象都会保持对方存在。

解决这个问题的方法是,用weak或者unowned引用代替其中一个的强引用,来打破循环引用。

问题5- Swift 2.0 or later

Swift2.0 增加了一个新的关键字来实现递归枚举。下面的例子是一个枚举类型,它在Node条件下有两个相关联的值类型T和List:

1
2
3
enum List{
    case Node(T, List)
}

什么关键字可以实现递归枚举?

答案:indirect 关键值可以允许递归枚举,代码如下:

1
2
3
enum List{
    indirect case Cons(T, List)
}

Where To Go From Here?

恭喜你到了文章的最后,如果你不知道所有问题的答案,也不要感到沮丧。

因为上面中得有些问题还是比较复杂的,并且Swift是一门富有表现力的语言,还有很多需要我们学。此外,苹果公司一直改善Swift的新特性,所以即使学的最好的人也不可能知道所有的一切。

【面试必备】Swift 面试题及其答案的更多相关文章

  1. 面试(4)-spring-Spring面试题和答案

    1:69道Spring面试题和答案 转自:http://ifeve.com/spring-interview-questions-and-answers/ 目录 Spring 概述 依赖注入 Spri ...

  2. Python/Java程序员面试必备常用问题解析与答案

    转自AI算法联盟,理解python技术问题,以及一些常见的java面试中经常遇到的问题,这些面试问题分为四类: 是什么(what) 如何做(how) 说区别/谈优势(difference) 实践操作( ...

  3. 史上最全 40 道 Dubbo 面试题及答案,看完碾压面试官!

    想往高处走,怎么能不懂 Dubbo? Dubbo是国内最出名的分布式服务框架,也是 Java 程序员必备的必会的框架之一.Dubbo 更是中高级面试过程中经常会问的技术,无论你是否用过,你都必须熟悉. ...

  4. 金九银十跳槽高峰,面试必备之 Redis + MongoDB 常问80道面试题

    前言 有着“金九银十”之称的招聘旺季已经开启,跳槽高峰期也如约而至. 本文为主要是 Redis + MongoDB 知识点的攻略,希望能帮助到大家. 内容较多,大家准备好耐心和瓜子矿泉水. Redis ...

  5. 李洪强iOS经典面试题156 - Runtime详解(面试必备)

    李洪强iOS经典面试题156 - Runtime详解(面试必备)   一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...

  6. 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)

    李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...

  7. 【面试必备】常见Java面试题大综合

    一.Java基础 1.Arrays.sort实现原理和Collections.sort实现原理答:Collections.sort方法底层会调用Arrays.sort方法,底层实现都是TimeSort ...

  8. Android&Java面试题大全—金九银十面试必备

    声明本文由作者:Man不经心授权转载,转载请联系原文作者原文链接:https://www.jianshu.com/p/375ad14096b3, 类加载过程 Java 中类加载分为 3 个步骤:加载. ...

  9. AI面试必备/深度学习100问1-50题答案解析

    AI面试必备/深度学习100问1-50题答案解析 2018年09月04日 15:42:07 刀客123 阅读数 2020更多 分类专栏: 机器学习   转载:https://blog.csdn.net ...

随机推荐

  1. Monyer's game Google Hack关的BT玩法

    玩Monyer's game的朋友都知道里面有Google Hack这关,其实这里本来应该用到的技术是逆向回溯搜索,但因为有好几个人都说利用其他方式看到的密码,所以Monyer不得不重新站在玩家的角度 ...

  2. (甲)PAT-1001

    1001. A+B Format (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B   Calculate a + b and output the sum ...

  3. C#照片批量压缩小工具

    做了一个照片批量压缩工具,其实核心代码几分钟就完成了,但整个小工具做下来还是花了一天的时间.中间遇到了大堆问题,并寻求最好的解决方案予以解决.现在就分享一下这个看似简单的小工具所使用的技术. 软件界面 ...

  4. Web Service和WCF的到底有什么区别

    [1]Web Service:严格来说是行业标准,也就是Web Service 规范,也称作WS-*规范,既不是框架,也不是技术. 它有一套完成的规范体系标准,而且在持续不断的更新完善中. 它使用XM ...

  5. 第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理

    温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发 第三篇 :微信公众 ...

  6. linux: 获取监听指定端口的进程PID

    在 linux 下经常需要杀死(重启)监听某端口的进程, 因此就写了一个小脚本, 通过 ss 命令获取监听制定端口的进程 PID, 然后通过 kill 命令结束掉进程: #!/bin/sh # set ...

  7. ES5严格模式(Strict mode)

    严格模式(Strict mode)是由ECMA-262规范定义的新兴JavaScript标准,第五版发布于2009年12月.旨在改善错误检查功能并且标识可能不会延续到未来JavaScript版本的脚本 ...

  8. [转]移动web开发中meta标签作用

    今天在尝试做移动页面的时候遇到了一个问题,<meta content="telephone=no,email=no" name="format-detection& ...

  9. 一道题看bitset应用 --ZOJ 3642

    题意:给n个文件,包括文件名和文件大小,然后给出k个关键词,查询包含该关键词的文件的大小总和.文件名为一些中括号括起的关键词的合集. 解法:可用bitset记录每一个关键词在哪些文件中出现,然后查询即 ...

  10. POJ 1845 Sumdiv 【逆元】

    题意:求A^B的所有因子之和 很容易知道,先把分解得到,那么得到,那么 的所有因子和的表达式如下 第一种做法是分治求等比数列的和  用递归二分求等比数列1+pi+pi^2+pi^3+...+pi^n: ...