Interview Q/A

Algorithms and Data Structures

Collection types in Swift, differences in operations complexity

easy
Short Answer: Swift has 3 common collection types arrays, dictionaries, and sets. The array is an ordered list of data. The dictionary is an unordered collection of items, it stores elements in key/value pairs. Set is an unordered collection of unique data. All these types a generic based and can work with any type

Array

Set

Dictionary

Collection Types

 

The array is an ordered random-access collection

Read – O(1)  – read by index

Search – O(N)

Add element –  O(1) or O(N) worst case. If the array should be shifted to the new memory space, than O(N). If the array has enough place from the start or at the end – than O(1). O(N) if adding inside the array with shifting.

Removing element – O(N) should be shifted after deletion.

 


A set is a collection of unique data

Search – O(1)

Add element –  O(1)

Removing element – O(1)

In worst cases with collision, it is O(N) for all operations

Set has a hidden array inside where indexes hash code which is a result of the hash function of value. Value is saved by this calculated index.

If new different values have the same hashcode, they are stored in the same element as the new value of the linked list

If new values are the same and hashcodes are also the same, than this insert operation will be ignored, because this value is not unique and is already in the Set


The dictionary is a collection of pairs of key-value

Search – O(1)

Add element –  O(1)

Removing element – O(1)

In worst cases with collision, it is O(N) for all operations

Dictionary has a hidden array inside where indexes hash code which is a result of the hash function of key. Key and value are saved by this calculated index.

If new different key-value has the same hashcode, they are stored in the same element as the new value of the linked list

If new values are the same and hashcodes are also the same, than this insert operation will be ignored, because this value is not unique and is already in the Dictionary


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Swift

Життєвий цикл UIViewController

easy
Short Answer: "Життєвий цикл UIViewController" - це послідовність станів, через які проходить об'єкт типу UIViewController від моменту його створення до моменту знищення. (viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear та viewDidDisappear, кожен з яких відповідає за певний етап життєвого циклу)

Що відбувається на кожному етапі завантаження контролера:
спочатку викликається функція viewDidLoad.
viewDidLoad – оутлети вже встановлені і можна робити налаштування інтерфейсу з моделі, але врахуйте, що можуть бути не обчислені розмір та положення елементів на екрані, тому намагайтеся не використовувати код пов’язаний з bounds у цій функції. Ця функція викликається один раз на
життєвий цикл контролера.

viewWillAppear –  працюємо з даними, які могли змінитися, поки контролер не відображається на екрані (усі розміри вже встановлені). viewWillAppear викликається до того, як екран буде показаний, він викликається після viewDidLoad, тут ми вже можемо зчитувати frame наприклад з Label, Button, які були поставлені, тут frame вже встановлені коректно.
viewDidAppear – стартуємо анімацію
viewWillDisappear – тут ми зупиняємо анімацію робимо чищення екрана, якихось даних, якщо це необхідно
viewDidDisappear – викликається дуже рідко.
Методи можуть викликати кілька разів у життєвому
цикл контролера. Обов’язково викликайте super.view… для всіх
методів.
Вони потрібні для того, щоб відстежувати стан вашого контролера, стан екрану, що взагалі відбувається.


Layout:
func view WillLayoutSubviews()
func viewDidLayoutSubviews()
Методи викликаються щоразу, коли frame був змінений (досить часто). Необхідні для відстеження геометричних параметрів елементів, до та після Autolayout.
Між will і did відбувається Autolayout.

awakeFromNib ()
Метод викликається для всіх елементів, які з’являються з Storyboard, Xib files, відбувається до того, як будуть встановлені всі оутлети, постарайтеся не використовувати цей спосіб і помістити код, в viewDidLoad або
viewWillAppear.


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What is "CLOSURES" and why is it used?

easy
Short Answer: Closures in Swift are function objects that allow functions to be passed as values, stored in variables, and passed to other functions. They can also capture and store references to variables and constants from the surrounding scope. Closures do not require the word func for description, may have non-name input parameters, may have no default input parameter values. Closure must be described once, called many times. Closures can be used to create anonymous functions that can be passed as arguments to other functions or stored in variables or constants. They can be used to perform various operations such as sorting, filtering, traversing collections, and more.

There are three types of closures in Swift:

Global functions are functions that are declared in the global scope of the program.
Nested functions are functions that are declared inside another function and have access to variables and constants from the outer function.
Closure expressions are anonymous functions that can be passed as arguments to other functions or stored in variables or constants.

 

@escaping, non-escaping and Optional closure:

@escaping – Informs that the closure can be saved or how the calling scope can survive.

non-escaping – Informs that the closure will not be saved and it will not survive the scope of the calling function.

Optional closure – if the closure is optional, then it is not necessary to mark it as @escaping, it will be optional by default.

 

Func and closures – Reference Type:

This is when functions and closures are written in variables, they do not create new objects, they store references. That is,
a closure can be stored in many places, but it will actually be the same closure, not copies of it.

Retain Cycle is a situation when 2 objects hold strong links to each other and thereby keep each other in memory. This causes them to prevent ARC from destroying itself from memory (because ARC holds on to the object until it has at least one strong reference. This situation leads to a memory leak, which in turn can cause the application to crash.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Difference between "STRUCT and CLASS" in Swift?

easy
Short Answer: In Swift, structs are value types and classes are reference types. When you copy a structure, you get two unique copies of the data. When you copy a class, you get two references to the same data instance. This is a fundamental difference and it influences your choice between classes or structs.

Classes have additional features that structures do not have:

Comparison of classes and structures
Classes and structures in Swift have a lot in common. In both classes and structs, you can:

  • Declare properties to store values
  • Declare methods to provide functionality
  • Declare indexes to provide access to their values via index syntax
  • Declare initializers to set their initial state
  • They can both be extended to extend their functionality beyond the standard implementation.
  • They can both conform to protocols to provide standard functionality of a particular type.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Collection types in Swift, differences in operations complexity

easy
Short Answer: Swift has 3 common collection types arrays, dictionaries, and sets. The array is an ordered list of data. The dictionary is an unordered collection of items, it stores elements in key/value pairs. Set is an unordered collection of unique data. All these types a generic based and can work with any type

Array

Set

Dictionary

Collection Types

 

The array is an ordered random-access collection

Read – O(1)  – read by index

Search – O(N)

Add element –  O(1) or O(N) worst case. If the array should be shifted to the new memory space, than O(N). If the array has enough place from the start or at the end – than O(1). O(N) if adding inside the array with shifting.

Removing element – O(N) should be shifted after deletion.

 


A set is a collection of unique data

Search – O(1)

Add element –  O(1)

Removing element – O(1)

In worst cases with collision, it is O(N) for all operations

Set has a hidden array inside where indexes hash code which is a result of the hash function of value. Value is saved by this calculated index.

If new different values have the same hashcode, they are stored in the same element as the new value of the linked list

If new values are the same and hashcodes are also the same, than this insert operation will be ignored, because this value is not unique and is already in the Set


The dictionary is a collection of pairs of key-value

Search – O(1)

Add element –  O(1)

Removing element – O(1)

In worst cases with collision, it is O(N) for all operations

Dictionary has a hidden array inside where indexes hash code which is a result of the hash function of key. Key and value are saved by this calculated index.

If new different key-value has the same hashcode, they are stored in the same element as the new value of the linked list

If new values are the same and hashcodes are also the same, than this insert operation will be ignored, because this value is not unique and is already in the Dictionary


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What is a "DELEGATE PATTERN" and how is it applied?

easy
Short Answer: Delegation is a design pattern that allows a class to transfer or "delegate" some of its responsibilities to another class.

Our task is to pass data from the FirstViewController class to the SecondViewController class using a delegate.                          First, let’s create a protocol with a required method and a String type parameter.


Let’s create a class called First View Controller.


FirstViewController has an optional delegate, type is FirstViewControlleDelegate.                                                                              The delegate property will be initialized with the SecondViewController class.                                                                                    This class will conform to the FirstViewControlleDelegate protocol


Let’s create two objects and initialize them.


Let’s assign the property optional delegate to the class secondVC.


Next, you can execute the passData method from the class FirstViewController, even though the passData method is in the class SecondViewController.


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What are nested functions?

easy
Short Answer: If a function exists inside the body of another function, it's called nested function.

As shown in the following example:

    func funcname() {

        //statements of outer function

        func anotherFuncname() {

            //statements of inner function

        }

    }

Here, the function anotherFuncname() is inside the body of another function funcname().

It should be noted that, inner functions can be only called and used inside the enclosing function (outer function).

Example: Nested function with parameters and return values

    func operate(with symbol:String) -> (Int, Int) -> Int {

        func add(num1:Int, num2:Int) -> Int {

            return num1 + num2

        }

        func subtract(num1:Int, num2:Int) -> Int {

            return num1 num2

        }

        let operation = (symbol == “+”) ?  add : subtract

        return operation

    }

    let operation = operate(with: “+”)

    let result = operation(2, 3)

    print(result)

When you run the program, the output will be:  5 .

In the above program,

  • the outer function is operate()  with return value of type Function (Int,Int) -> Int.
  • and the inner (nested) functions are add()  and substract()

The nested function add()  and  substract() in a way are being used outside of the enclosing function operate() . This is possible because the outer function returns one of these functions.

We’ve used the inner function outside the enclosing function operate()  as operation(2, 3). The program internally calls add(2, 3) which outputs 5 in the console.



---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

How to silence compiler warning about unused return value from a function?

easy
Short Answer: Apply @discardableResult attribute to a function or method declaration to suppress the compiler warning when the function or method that returns a value is called without using its result

Swift – Attributes

With @discardableResult attribute, the compiler won’t show a warning about the unused return value


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Is It possible or how to use reserved keywords as variable names? (like class, default, etc)

easy
Short Answer: It is possible if this keyword will be wrapped in `` like `default`

Swift – Lexical Structure

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Constants and variables differences, naming. Can constants have Optional Type?

easy
Short Answer: Constants can be declared with the let keyword. Variables can be declared with the var keyword. The value of a constant can’t be changed once it’s set, whereas a variable can be set to a different value in the future. Constants can be Optional.

Swift – The Basics

Naming Constants and Variables. Constant and variable names can’t contain whitespace characters, mathematical symbols, arrows, private-use Unicode scalar values, or line- and box-drawing characters. Nor can they begin with a number, although numbers may be included elsewhere within the name.

Once you’ve declared a constant or variable of a certain type, you can’t declare it again with the same name in the same scope, or change it to store values of a different type. Nor can you change a constant into a variable or a variable into a constant.


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What are the control transfer statements that are used in iOS Swift?

easy
Short Answer: continue, break, fallthrough, return, throw

Control Transfer Statements

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What type of objects are basic data types in Swift?

easy
Short Answer: Integer, Double, Float, Bool, String, Character, Optional, Typles. Arrays, Dictionaries, Sets are not basic Swift types. They are collection generic types and they consist of basic types

Swift – Data Types

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Is Swift an object-oriented programming language?

easy
Short Answer: Swift is a general-purpose, multi-paradigm programming language. It supports object-oriented, protocol-oriented, functional approaches

Swift (programming language)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What are the most important features of Swift?

easy
Short Answer: Typles, ARC (automatic reference counting), Optional Type, Optional chaining, Guard statement, Closures, Type Safety, and Type inference, Generics, Functional programming patterns, e.g., map and filter. Structs support methods, extensions, and protocols

Swift features

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Explain Swift vs Objective-C

easy
Short Answer: Swift is a multi-paradigm programming language, Objective-C is a class-based object-oriented programing language Swift supports dynamic libraries, Tuples Objective-C doesn't support dynamic libraries, Tuples Swift is more human-friendly (have good syntax) Swift is faster than Objective-C in ~2.6 times Swift has Optionals types Objective-C doesn't have automatic memory management, it has Manual Retain Release Swift has unified files that make code easier to maintain (see description) Unified files make code easier to maintain (see description) Swift has a better compiler Swift has type inference Swift has Higher Order Functions like map, filter, reduce, compactMap Swift has guard and defer conditional statements. Guard is a super powerful feature

Optionals

ARC (Automatic Reference Counting)

Type inference

Guard Statement

Optionals. Swift also introduces optional types, which handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. Using optionals is similar to using nil pointers in Objective-C, but they work for any type, not just classes. Not only are optionals safer and more expressive than nil pointers in Objective-C, but they’re also at the heart of many of Swift’s most powerful features

Unified files make code easier to maintain. Again, an old standard of the C language holds Objective-C back: a two-file requirement. This means that programmers have to update and maintain two separate files of code, whereas, in Swift, these become one. That means less work for programmers, but not at the cost of speed on the front end

Better compiler. Swift is built with the Low-Level Virtual Machine (LLVM), a compiler that’s used by languages like Scala, Ruby, Python, C# and Go. The LLVM is faster and smarter than previous C compilers, so more workload is transferred from the programmer to Xcode, and the compiler

Type inference. Swift uses type inference extensively, allowing you to omit the type or part of the type of many variables and expressions in your code. For example, instead of writing var x: Int = 0, you can write var x = 0, omitting the type completely—the compiler correctly infers that x names a value of type Int


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What are the advantages and disadvantages of Swift?

easy
Short Answer: Advantages: Compiled language (error can be found on the compilation stage), Fast, Safe, Clean, Open-source language, Easy to learn and maintain, Supported by multiple devices, Optional types, Closures, Generics, Automatic memory management (with a problem, see disadvantages) Disadvantages: Automatic memory management doesn't have garbage collection, the language is still quite young, limited talent pool

Swift Introduction

Automatic Reference Counting

Automatic memory management

A lot of programming languages has automatic memory management, but also they have garbage collection mechanism which allows removing unused objects from memory. Swift doesn’t have this mechanism. The automatic memory management ins Swift names ARC (Automatic reference counting) and you need to watch out for the weak and strong references between objects. If two or more objects will have strong references to each other, that it will be a retain cycle and all of these objects can’t be removed from memory, which leads to memory leaks and critical app shut down. More about weak and strong links in a source section


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What is Swift programming language?

easy
Short Answer: Swift is a primary programming language for iOS, iPadOS, macOS, tvOS, watchOS. It was released in June 2014. Swift is a multi-paradigm statically/strongly typed compiled language. Apple created Swift language to work with both Cocoa Touch and Cocoa. Swift supports multiple operating systems such as Free BSD, Linux, Darwin, etc

Swift Documentation

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What is a "protocol" in Swift ? How and where to use "protocols"?

average
Short Answer: A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol doesn't have an implementation details, it only has a list of properties and methods which need to implement for conforming to this protocol. Protocols uses for loose coupling code, design patterns implementations, modularity and testing

Swift Documentation – Protocols

Dependency Injection

SOLID

The protocol in Swift is a mechanism to achieve abstraction. It is easy with protocols to build a communication between classes or modules with  high level of replacability. When class e.g, based on protocol, not on concrete class, then it is super easy to replace this part on another class which just conformed this protocol. This technique is super useful in testing and for applying a OO(object oriented), SOLID and DI (dependency injection) principles.


On the first screen defined protocol and two classes which implemented this protocol. Both of them should implement the load method, but each of them can implement it in different way. RemoteProductsProvider loads products from server, LocalProductsProvider loads products from local disk for example. So this two classes conforms the ProductLoaderProtocol protocol.

On the second screen you can see that HomeController works not with concrete class, but through protocol (abstraction). Controller don’t know with which actual implementation of loader it works.

This concept widely used for testing. For example, in testing mode it is convenient to replace RemoteLoader on LocalLoader and don’t spent time on request to real server


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Tooling

What are the tools that are required to develop iOS applications?

easy
Short Answer: macOS, Xcode, Swift or Objective-C programming language, Apple Developer Program (if an app needs to be pushed to App Store)

Xcode

Swift

Objective-C

Apple Developer Program

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

How to test iOS apps without a real device? What disadvantage of this method?

easy
Short Answer: iOS apps can be tested on simulators provided by Apple on the Mac system. Disadvantages: iOS simulator doesn't have camera access, more than two fingers gesture. Doesn't work Apple Push Notification Service, External Accessory, Media Player, Message UI, Event Kit In UIKit, the UIVideoEditorController class, Store Kit
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

UI

Життєвий цикл UIViewController

easy
Short Answer: "Життєвий цикл UIViewController" - це послідовність станів, через які проходить об'єкт типу UIViewController від моменту його створення до моменту знищення. (viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear та viewDidDisappear, кожен з яких відповідає за певний етап життєвого циклу)

Що відбувається на кожному етапі завантаження контролера:
спочатку викликається функція viewDidLoad.
viewDidLoad – оутлети вже встановлені і можна робити налаштування інтерфейсу з моделі, але врахуйте, що можуть бути не обчислені розмір та положення елементів на екрані, тому намагайтеся не використовувати код пов’язаний з bounds у цій функції. Ця функція викликається один раз на
життєвий цикл контролера.

viewWillAppear –  працюємо з даними, які могли змінитися, поки контролер не відображається на екрані (усі розміри вже встановлені). viewWillAppear викликається до того, як екран буде показаний, він викликається після viewDidLoad, тут ми вже можемо зчитувати frame наприклад з Label, Button, які були поставлені, тут frame вже встановлені коректно.
viewDidAppear – стартуємо анімацію
viewWillDisappear – тут ми зупиняємо анімацію робимо чищення екрана, якихось даних, якщо це необхідно
viewDidDisappear – викликається дуже рідко.
Методи можуть викликати кілька разів у життєвому
цикл контролера. Обов’язково викликайте super.view… для всіх
методів.
Вони потрібні для того, щоб відстежувати стан вашого контролера, стан екрану, що взагалі відбувається.


Layout:
func view WillLayoutSubviews()
func viewDidLayoutSubviews()
Методи викликаються щоразу, коли frame був змінений (досить часто). Необхідні для відстеження геометричних параметрів елементів, до та після Autolayout.
Між will і did відбувається Autolayout.

awakeFromNib ()
Метод викликається для всіх елементів, які з’являються з Storyboard, Xib files, відбувається до того, як будуть встановлені всі оутлети, постарайтеся не використовувати цей спосіб і помістити код, в viewDidLoad або
viewWillAppear.


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Difference between "STRUCT and CLASS" in Swift?

easy
Short Answer: In Swift, structs are value types and classes are reference types. When you copy a structure, you get two unique copies of the data. When you copy a class, you get two references to the same data instance. This is a fundamental difference and it influences your choice between classes or structs.

Classes have additional features that structures do not have:

Comparison of classes and structures
Classes and structures in Swift have a lot in common. In both classes and structs, you can:

  • Declare properties to store values
  • Declare methods to provide functionality
  • Declare indexes to provide access to their values via index syntax
  • Declare initializers to set their initial state
  • They can both be extended to extend their functionality beyond the standard implementation.
  • They can both conform to protocols to provide standard functionality of a particular type.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Explain hitTest process. How iOS system handles user events?

difficult
Short Answer: hitTest is a method that returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point. When the system detects a touch on the screen, than it creates an event and sends it to UIApplication, and after that to UIWindow. UIWindows' responsibility is to find a view in the view's hierarchy to which this event relates. This search is realized through a recursive hitTest method call. Useful for overriding the hitTest method and writing custom logic for handling or preventing handling events by the view and their subviews.

HitTest on iOS

hitTest methods return nil if

  • Hit is not inside the view which hitTest is called
  • If alpha is less than 0.01, isUserInteractionEnabled is false or isHidden is true

If the hitTest method returns nil, than it won’t pass the event to the hitTest of its subviews

By overriding the hitTest method you can prevent handling or write pass-through logic for subviews. For example, if you want to handle events only in subviews but not for container view.


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Explain iOS Responder Chain?

difficult
Short Answer: The Responder Chain is the name given to an UIKit-generated linked list of UIResponder objects and is the foundation for everything regarding events (like touch and motion) in iOS. Responder Chain is managed by UIKit behind the scenes and only in some cases do you need to interact with it directly (work with UITextField for example). This is the realization of Chain Of Responsibility design patterns from the GOF book

Documentation

Using The Responder Chain

iOS Responder Chain: UIResponder, UIEvent, UIControl and uses

Apps receive and handle events using responder objects. A responder object is any instance of the UIResponder class and common subclasses include UIView, UIViewController, and UIApplication. Responders receive the raw event data and must either handle the event or forward it to another responder object. When your app receives an event, UIKit automatically directs that event to the most appropriate responder object, known as the first responder.

Unhandled events are passed from responder to responder in the active responder chain, which is the dynamic configuration of your app’s responder objects. The following image shows the responders in an app whose interface contains a label, a text field, a button, and two background views. The diagram also shows how events move from one responder to the next, following the responder chain.

If the view chooses to not handle a touch event, then it will be sent up the responder chain, which will follow this path:

  • The first responder is the hit-tested view (the view under the touch)
  • The next responder is its superview
  • The chain continues up the view hierarchy until it reaches a view that is associated with a view controller
  • That view controller will be the next responder
  • If this view controller is a root controller, then the window will be the next responder
  • The application is the window’s next responder
  • The last responder in the chain is the App delegate

The application will receive events from sources such as:

  • UIControl Actions: these are the actions that are registered using the action/target pattern
  • User events: Events from users such as touches, shakes, motion, etc
  • System events: Such as low memory, rotation, etc

Determine an event’s first responder

UIKit designates an object as the first responder to an event based on the type of that event. Event types include:


Note

Motion events related to the accelerometers, gyroscopes, and magnetometer don’t follow the responder chain. Instead, Core Motion delivers those events directly to the designated object. For more information, see Core Motion Framework

When a touch occurs, UIKit creates an UITouch object and associates it with a view. As the touch location or other parameters change, UIKit updates the same UITouch object with the new information. The only property that doesn’t change is the view. (Even when the touch location moves outside the original view, the value in the touch’s view property doesn’t change). When the touch ends, UIKit releases the UITouch object.


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------