Swift interview questions

Swift quiz questions

  • 1.

    In Swift enumerations, what’s the difference between raw values and associated values?

    Answer:

    Raw values are used to associate constant (literal) values to enum cases. The value type is part of the enum type, and each enum case must specify a unique raw value (duplicate values are not allowed).

    The following example shows an enum with raw values of type Int:

    enum IntEnum : Int {
        case ONE = 1
        case TWO = 2
        case THREE = 3
    }
    

    An enum value can be converted to its raw value by using the rawValue property:

    var enumVar: IntEnum = IntEnum.TWO
    var rawValue: Int = enumVar.rawValue
    

    A raw value can be converted to an enum instance by using a dedicated initializer:

    var enumVar: IntEnum? = IntEnum(rawValue: 1)
    

    Associated values are used to associate arbitrary data to a specific enum case. Each enum case can have zero or more associated values, declared as a tuple in the case definition:

    enum AssociatedEnum {
        case EMPTY
        case WITH_INT(value: Int)
        case WITH_TUPLE(value: Int, text: String, data: [Float])
    }
    

    Whereas the type(s) associated to a case are part of the enum declaration, the associated value(s) are instance specific, meaning that an enum case can have different associated values for different enum instances.

    View
  • 2.

    The String struct doesn’t provide a count or length property or method to count the number of characters it contains. Instead a global countElements<T>() function is available. When applied to strings, what’s the complexity of the countElements function:

    • O(1)
    • O(n)

    and why?

    Answer:

    Swift strings support extended grapheme clusters. Each character stored in a string is a sequence of one or more unicode scalars that, when combined, produce a single human readable character. Since different characters can require different amounts of memory, and considering that an extreme grapheme cluster must be accessed sequentially in order to determine which character it represents, it’s not possible to know the number of characters contained in a string upfront, without traversing the entire string. For that reason, the complexity of the countElements function is O(n).

    View
  • 3.

    Consider the following code:

    var defaults = NSUserDefaults.standardUserDefaults()
    var userPref = defaults.stringForKey("userPref")!
    printString(userPref)
    
    func printString(string: String) {
        println(string)
    }
    

    Where is the bug? What does this bug cause? What’s the proper way to fix it?

    Answer:

    The second line uses the stringForKey method of NSUserDefaults, which returns an optional, to account for the key not being found, or for the corresponding value not being convertible to a string.

    During its execution, if the key is found and the corresponding value is a string, the above code works correctly. But if the key doesn’t exist, or the corresponding value is not a string, the app crashes with the following error:

    fatal error: unexpectedly found nil while unwrapping an Optional value
    

    The reason is that the forced unwrapping operator ! is attempting to force unwrap a value from a nil optional. The forced unwrapping operator should be used only when an optional is known to contain a non-nil value.

    The solution consists of making sure that the optional is not nil before force-unwrapping it:

    let userPref = defaults.stringForKey("userPref")
    if userPref != nil {
        printString(userPref!)
    }
    

    An even better way is by using optional binding:

    if let userPref = defaults.stringForKey("userPref") {
        printString(userPref)
    }
    View
  • 4.

    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?

    Answer:

    Swift doesn’t define any implicit cast between data types, even if they are conceptually almost identical (like UInt and Int).

    To fix the error, rather than casting, an explicit conversion is required. In the sample code, all expression operands must be converted to a common same type, which in this case is Double:

    var result = Double(op1) + Double(op2) + op3
    View
  • 5.

    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?

    Answer:

    The len variable is equal to 5, meaning that 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 is actually created and assigned.

    The reason is that swift arrays are value types (implemented as structs) and not reference types (i.e. classes). When a value type is assigned to a variable, passed as argument to a function or method, or otherwise moved around, a copy of it is actually created and assigned or passed. Note that swift dictionaries are also value types, implemented as structs.

    Value types in swift are:

    • structs (incl. arrays and dictionaries)
    • enumerations
    • basic data types (boolean, integer, float, etc.)
    View
  • 6.

    What output will be produced by the code below?

    struct Spaceship {
        fileprivate(set) var name = "Serenity"
    }
    
    var serenity = Spaceship()
    serenity.name = "Jayne's Chariot"
    print(serenity.name)

    Correct answer: "Jayne's Chariot".

    Explanation: Creating a property using fileprivate(set) means that Swift won't let code from other files modify that property directly. However, Swift playgrounds are compiled into a single file when run, and code that exists in the same file as a fileprivate property can access it directly.

     

    View
  • 7.

    When this code is executed, what will example2 be set to?

    var names = [String]()
    names.append("Amy")
    
    let example1 = names.popLast()
    let example2 = names.popLast()

    Correct answer: nil.

    Explanation: The popLast() method returns an optional version of the data type the array contains, which in this code is a String?. As the only string in the array was already removed, the second call will return nil.

     

    View
  • 8.

    What output will be produced by the code below?

    let (captain, engineer, doctor) = ("Mal", "Kailee", "Simon")
    print(engineer)

    Correct answer: "Kailee".

    Explanation: This code demonstrates tuple destructuring, which is a method of pulling a tuple into multiple individual values in one line of code. In this example, it will create three constants (captainengineer, and doctor), giving them the values "Mal", "Kailee", and "Simon" respectively.

     

    View
  • 9.

    What output will be produced by the code below?

    var spaceships1 = Set<String>()
    spaceships1.insert("Serenity")
    spaceships1.insert("Enterprise")
    spaceships1.insert("TARDIS")
    
    let spaceships2 = spaceships1
    
    if spaceships1.isSubset(of: spaceships2) {
        print("This is a subset")
    } else {
        print("This is not a subset")
    }

     

    Correct answer: "This is a subset".

    Explanation: Sets distinguish between subsets and strict (or "proper") subsets, with the difference being that the latter necessarily excludes identical sets. That is, Set A is a subset of Set B if every item in Set A is also in Set B. On the other hand, Set A is a strict subset of Set B if every element in Set A is also in Set B, but Set B contains at least one item that is missing from Set A.

    View
  • 10.

    When this code is executed, what will result be set to?

    func fetchCrewMember() -> (job: String, name: String) {
        return ("Public Relations", "Jayne")
    }
    
    let result = fetchCrewMember().0

     

    Correct answer: "Public Relations".

    Explanation: Even though we name the elements in fetchCrewMember()'s tuple return value, those elements are still accessible using their numerical index as used in the code.

    View
  • 11.

    Once this code is executed, what value will result hold?

    let numbers = [1, 3, 5, 7, 9]
    let result = numbers.reduce(0, +)

    Correct answer: 25.

    Explanation: The reduce method combines the integers in the numbers array into a single value by applying a function to each one. In our case, that's the + operator, which means "add all these numbers together", giving 25.

     

    View
  • 12.

    What output will be produced by the code below?

    func foo(_ number: Int) -> Int {
        func bar(_ number: Int) -> Int {
            return number * 5
        }
    
        return number * bar(3)
    }
    
    print(foo(2))

    Correct answer: 30.

    Explanation: This code uses inner functions, which means that the foo() function is visible at the end whereas the bar() function is not. The final line calls foo() with a value of 2; this then multiplies that by the result of calling bar()with a value of 3, which in turn multiplies that 3 by 5. So, you get 3 2, i.e. 30.

     

    View
  • 13.

    In the code below, what data type will be assigned to result?

    let result = UInt8.addWithOverflow(UInt8.max, 1)

     

    Correct answer: Tuple.

    Explanation: The UInt8.addWithOverflow() method returns a tuple (UInt8, Bool) where the first value stores the result of the add operation, and the second value stores whether an overflow happened.

    View
  • 14.

    What output will be produced by the code below?

    let string: String = String(describing: String.self)
    print(string)

    Correct answer: "String".

    Explanation: Among the many constructors for strings is one that lets you pass in a class to have the string set to the name of that class. That is, String(describing: String.self) means "create a string out of the name of the String class." This is equivalent to the NSStringFromClass() function that Objective-C developers often use.

     

    View
  • 15.

    What output will be produced by the code below?

    func square<T>(_ value: T) -> T {
        return value * value
    }
    
    print(square(5))

    Correct answer: This code will not compile.

    Explanation: This code has attempted to create a generic number squaring function, but has failed to declare that T(the data type being used) has the ability to work with the * operator, so Swift cannot compile it. One solution might be to modify it to square<T: Integer>, which would allow it to work on IntUIntInt64 and so on.

     

    View
  • 16.

    What output will be produced by the code below?

    func greet(_ name: String = "Anonymous") {
        print("Hello, \(name)!")
    }
    
    let greetCopy = greet
    greetCopy("Dave")

    Correct answer: "Hello, Dave!".

    Explanation: This code assigns the greet() method to the greetCopy constant, which means you can then call greetCopy() as if it were greet().

     

    View
  • 17.

    When this code is executed, what will example2 be set to?

    var names = [String]()
    names.append("Amy")
    let example1 = names.removeLast()
    let example2 = names.removeLast()

    Correct answer: This code will compile but crash.

    Explanation: The removeLast() method returns the same data type as the array contains, which in this code is a String. As the only string in the array was already removed, the second call will throw an exception and crash.

     

    View
  • 18.

    How many lines will be printed by the code below?

    import Foundation
    
    let data: [Any?] = ["Bill", nil, 69, "Ted"]
    
    for datum in data where !(datum is Hashable) {
        print(datum)
    }

    Correct answer: 1.

    Explanation: The loop will print only items that do not conform to the hashable protocol. In this code, the only such item is nil, so one line will be printed.

     

    View
  • 19.

    In the code below, what data type is testVar?

    let names = ["Pilot": "Wash", "Doctor": "Simon"]
    
    for (key, value) in names.enumerated() {
        let testVar = value
    }

     

    Correct answer: (String, String).

    Explanation: If you iterate over the names dictionary without using enumerated()key would be Pilot then Doctor, and value would be Wash then Simon. However, this code uses enumerated(), which means that key will be the integer position of the item in the loop, and value will be a (String, String) tuple containing the key and the value for this item in the dictionary: ("Pilot", "Wash") then ("Doctor", "Simon").

    View
  • 20.

    What output will be produced by the code below?

    var first = [1, 2, 3]
    var second = ["one", "two", "three"]
    var third = Array(zip(first, second))
    print(third)

    Correct answer: [(1, "one"), (2, "two"), (3, "three")].

    Explanation: This code creates a Zip2Sequence struct out of two arrays: one containing 1, 2, 3, and another containing "one", "two", "three". The Zip2Sequence will match each item in the first array with the item at the same index in the second array, giving (1, "one") and so on. This is then converted to an array for easier access.

     

    View

© 2017 QuizBucket.org