10个重要的面试问题 *
最优秀的Swift开发人员和工程师可以回答的基本问题. 在我们社区的推动下,我们鼓励专家提交问题并提供反馈.
现在就雇佣一名顶尖的Swift开发者Interview Questions
Consider the following code:
var array1 = [1, 2, 3, 4, 5]
var array2 = array1
array2.append(6)
var len = array1.count
What’s the value of the len
variable, and why?
The len
变量等于5,也就是说 array1
has 5 elements, whereas array2
has 6 elements:
array1 = [1, 2, 3, 4, 5]
array2 = [1, 2, 3, 4, 5, 6]
When array1
is assigned to array2
, a copy of array1
实际上是创建和分配的吗.
原因是swift数组是值类型(作为结构体实现)而不是引用类型(i.e. classes). 将值类型赋值给变量时, 作为参数传递给函数或方法, or otherwise moved around, 它的副本实际上被创建、分配或传递. 注意swift字典也是作为结构体实现的值类型.
Value types in swift are:
- structs (incl. arrays and dictionaries)
- enumerations
- 基本数据类型(布尔型、整数型、浮点型等).)
Consider the following code:
let op1: Int = 1
let op2: UInt = 2
let op3: Double = 3.34
var result = op1 + op2 + op3
Where is the error and why? How can it be fixed?
Swift没有在数据类型之间定义任何隐式强制转换, 即使它们在概念上几乎相同(比如 UInt
and Int
).
要修复错误,而不是强制转换,需要显式转换. In the sample code, 所有表达式操作数必须转换为通用的相同类型, which in this case is Double
:
var result = Double(op1) + Double(op2) + op3
Consider the following code:
var defaults = NSUserDefaults.standardUserDefaults()
var userPref = defaults.stringForKey("userPref")!
printString(userPref)
函数printString(string: string) {
println(string)
}
Where is the bug? What does this bug cause? 正确的解决方法是什么?
The second line uses the stringForKey
method of NSUserDefaults
, which returns an optional, 为了解释钥匙没找到的原因, 或者对应的值不能转换为字符串.
During its execution, 如果找到键并且对应的值是字符串, 以上代码可以正常工作. But if the key doesn’t exist, 或者对应的值不是字符串, 应用程序崩溃,出现以下错误:
致命错误:在展开可选值时意外发现nil
原因是强制展开操作符 !
尝试强制从nil展开值是可选的吗. 强制展开操作符只应在已知可选项包含非nil值时使用.
解决方案包括在强制展开可选对象之前确保它不是nil:
let userPref = defaults.stringForKey("userPref")
if userPref != nil {
printString(userPref!)
}
一个更好的方法是使用 optional binding:
if let userPref = defaults.stringForKey("userPref") {
printString(userPref)
}
申请加入Toptal的发展网络
并享受可靠、稳定、远程 自由Swift开发者职位
The String
struct doesn’t provide a count
or length
属性或方法来计算其包含的字符数. Instead a global countElements
function is available.
当应用于字符串时,复杂度是多少 countElements
function:
- O(1)
- O(n)
and why?
Swift字符串支持扩展字形集群. 存储在字符串中的每个字符是一个或多个unicode标量的序列, when combined, 生成一个人类可读的字符. 因为不同的字符需要不同数量的内存, 考虑到必须顺序访问一个极端字素簇,以确定它代表哪个字符, 不可能预先知道字符串中包含的字符数, 不遍历整个字符串. 因为这个原因,复杂的 countElements
function is O(n)
.
Raw values 用于将常量(文字)值关联到枚举情况. 该值类型是枚举类型的一部分, 每个枚举情况必须指定一个唯一的原始值(不允许重复的值)。.
下面的示例显示了具有类型为的原始值的枚举 Int
:
enum IntEnum : Int {
case ONE = 1
case TWO = 2
case THREE = 3
}
方法将枚举值转换为原始值 rawValue
property:
var enumVar: intum = intum.TWO
var rawValue: Int = enumVar.rawValue
原始值可以通过使用专用初始化器转换为enum实例:
var enumVar: IntEnum? = IntEnum(rawValue: 1)
Associated values 用于将任意数据关联到特定的枚举大小写. 每个枚举情况可以有零个或多个关联值,在情况定义中声明为元组:
enum AssociatedEnum {
case EMPTY
case WITH_INT(value: Int)
case WITH_TUPLE(value: Int, text: String, data: [Float])
}
而与case相关联的类型是枚举声明的一部分, 关联的值是特定于实例的, 这意味着对于不同的枚举实例,枚举大小写可以具有不同的关联值.
Swift defines the AnyObject
类型别名表示任何引用类型的实例,它在内部定义为协议.
Consider the following code:
var array = [AnyObject]()
struct Test {}
array.append(Test())
这段代码生成一个编译错误,错误信息如下:
类型“Test”不符合协议“AnyObject”
这个错误很明显,因为struct是一个值而不是引用类型, 因此,它不实现也不能强制转换为 AnyObject
protocol.
现在考虑下面的代码:
var array = [AnyObject]()
array.append(1)
array.append(2.0)
array.append("3")
array.append([4, 5, 6])
array.append([7: "7", 8: "8"])
struct Test {}
array.append(Test())
The array
数组分别用int、double、string、Array和dictionary类型的值填充. 它们都是值类型,而不是引用类型, 在所有情况下,编译器都不会报告错误. Why?
原因是swift自动桥接:
- number types to
NSNumber
- strings to
NSString
- arrays to
NSArray
- dictionaries to
NSDictionary
哪些都是引用类型.
Consider the following code:
class Master {
lazy var detail: detail = detail (master: self)
init() {
println("Master init")
}
deinit {
println("Master deinit")
}
}
class Detail {
var master: Master
init(master: Master) {
println("Detail init")
self.master = master
}
deinit {
println("Detail deinit")
}
}
func createMaster() {
var master: master = master ()
var detail = master.detail
}
createMaster()
这个bug是什么?它是如何影响内存的? How can it be fixed?
There is a strong reference cycle between Master
and Detail
, with Master
creating an instance of Detail
并存储对它的引用 Detail
类的实例的引用 Master
creator. In both cases, references are strong, 这意味着两个实例都不会被释放, causing a memory leak.
要解决这个问题,有必要至少打破两种牢固关系中的一种, by using either the weak
or unowned
modifier.
这两个修饰语的区别是:
-
unowned
:因此,假定引用在其生命周期中始终具有一个值, 该属性必须为非可选类型. -
weak
在某些情况下,作为结果,引用可能没有价值, 属性必须是可选类型.
在上面的代码示例中,正确的解决方案是定义 Detail
the reference to Master
as unowned
:
class Detail {
unowned var master: Master
...
}
下面的代码片段会导致编译时错误:
struct IntStack {
var items = [Int]()
func add(x: Int) {
items.append(x) //编译时错误.
}
}
解释发生编译时错误的原因. How can you fix it?
Structures are value types. 默认情况下,不能从值类型的实例方法中修改其属性.
However, you can optionally allow such modification to occur by declaring the instance methods as ‘mutating’; e.g.:
struct IntStack {
var items = [Int]()
mutating func add(x: Int) {
items.append(x) // All good!
}
}
Consider this code:
令d = ["john": 23, "james": 24, "vincent": 34, "louis": 29]
let x = d.sort{ $0.1 < $1.1 }.map{ $0.0 }
What is the type of x
? And what is its value?
x
is of type [String]
and of value [“约翰”,“詹姆斯”,“路易斯”,“文森特”]
.
Consider the following code:
struct Planet {
let name: String
let distanceFromSun: Double
}
let planets = [
行星(名称:"水星",距离:0.387),
行星(名称:“金星”,距离:0.722),
行星(名称:“地球”,距离:1.0),
行星(名称:“Mars”,距离:1.52),
行星(名称:“木星”,距离:5.20),
行星(名称:“土星”,距离:9.58),
行星(名称:“天王星”,距离:19.2),
行星(名称:“海王星”,距离:30.1)
]
let result1 = planets.map { $0.name }
let result2 = planets.reduce(0) { $0 + $1.distanceFromSun }
的类型和值是什么 result1
and result2
variables?
Explain why.
result1
是包含行星名称列表的字符串数组吗
result2
双星是所有行星距离的总和吗
The map
method of the Array
结构类型执行源数组到另一类型数组的转换, 谁的值是通过执行作为参数传递给数组的每个元素的闭包获得的.
在上面的代码中,闭包返回 name
property, so the map
方法返回行星名称数组.
给定一个初始值和一个闭包 reduce
method of the Array
结构类型返回通过将闭包递归应用于数组的每个元素而获得的单个值. 闭包接受前一步计算的值(如果是第一次迭代,则为初始值)和当前数组元素, 并且期望返回与初始值相同类型的值.
In the above code, 闭包返回前一步计算的总和, plus the value of the distanceFromSun
属性设置当前元素的属性. 最后的结果是所有行星距离的总和.
面试不仅仅是棘手的技术问题, 所以这些只是作为一个指南. 并不是每一个值得雇佣的“A”候选人都能回答所有的问题, 回答所有问题也不能保证成为A级考生. At the end of the day, 招聘仍然是一门艺术,一门科学,需要大量的工作.
Why Toptal
Submit an interview question
提交的问题和答案将被审查和编辑, 并可能会或可能不会选择张贴, 由Toptal全权决定, LLC.
Looking for Swift Developers?
Looking for Swift Developers? 看看Toptal的Swift开发者.
Josip Petrić
Freelance Swift Developer
作为一个有十多年经验的软件工程师, 约瑟普对建筑的可扩展性有着敏锐的认识, maintainable, 以及用户友好的应用程序. 他选择的平台是iOS,他已经为其设计和开发了广泛的应用程序, from simple ones to complex, large-scale applications. 约瑟普是一个成熟的团队领导者和团队成员,具有模范的沟通和社交技巧.
Show MoreRyan Bradley Lons
Freelance Swift Developer
Ryan是一名高级iOS和网页开发人员,热衷于创造令人惊叹的用户界面和体验. 他在开发堆栈的任何地方工作都很舒服,并且有10多年的工作经验. He's well-spoken, 很容易沟通, quick to respond, 并且擅长为你面临的任何挑战找出最佳解决方案. 瑞安有创业的动力,也了解创业公司面临的挑战.
Show MoreJosh Reynolds
Freelance Swift Developer
拥有超过15年的成功经验,在世界各地建立了伟大的数字产品, 乔希以同情心和榜样来领导. 他会在需要的时候与团队的其他成员一起跳进战壕,并带来清晰的战略,帮助我们安全地驾驭数字海洋的湍流. Josh选择的工具是证据,同理心,清晰而动态的沟通,以及成长的心态.
Show MoreToptal Connects the Top 3% 世界各地的自由职业人才.
Join the Toptal community.