A living list of tricky questions found in interviews, especially if rarely found in the wild.
Design patterns in swift GOF book
What is a buffer?
Memory used to temporarily data while it is being moved from one place to another.
Capturing the value stored at a name before the name references a new value.
You can create a buffer with a simple declaration
let buffer = nameAboutToPointToSomethingElse
nameAboutToPointToSomethingElse = new
buffer.property = nameAboutToPointToSomethingEl
Its used for data structure related algorithms such as shifting pointers in linked lists and graphs.
What are sockets? Have you worked with them?
What are sockets? bidirectional stream. Sockets are a way to send messages to and receive messages from other computer processes. Http ultimately uses sockets, but unlike http protocols, sockets don’t require http methods.
Sockets only need to know three things:
- ports,
- transport layers (TCP or UDP) and the
- payload.
Two main types
- Stream Sockets − Ordered, error checked and verified delivery (tcp or Transmission Control Protocol)
- Datagram Sockets − Unordered,where each data unit is individually addressed making for faster delivery. use cases: simple quick messages, updating information, gaming data, when sessions are too memory expensive.
Here is a cool tutorial for working with sockets
While Rest methods use sockets under the hood, they do not allowed messages to be pushed from the server, only permitting a pull method. Using sockets directly we can both push and pull from the server.
There are some frameworks to make it simpler to use:
Or you can use sockets directly
//1. You only need Foundation.
import Foundationfunc setupNetworkCommunication(hostname: CFString = .localHost, port: UInt32 = 80) { // 2. Declare your Unmanaged<CFReadStream> and Unmanaged<CFWriteStream>. An unmanaged struct require you to manually release memory of the object passed in.
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
// 3. Creates readable and writable streams connected to a TCP/IP port of a particular host
CFStreamCreatePairWithSocketToHost(
kCFAllocatorDefault,
hostname,
port,
&readStream,
&writeStream
)// 4. Gets the value of this unmanaged reference as a managed reference and consumes an unbalanced retain of it.
inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue() // 5. Assigns self as the listener for the incoming messages.
inputStream.delegate = self // 6. Adds the service to the specified run loop.
inputStream.schedule(in: .current, forMode: .common)
outputStream.schedule(in: .current, forMode: .common)
// 7. A stream must be created before it can be opened. Once opened, a stream cannot be closed and reopened.
inputStream.open()
outputStream.open()
}
What is ARC, how is it different from Garbage collection, and what do they have in common?
What is Arc? Its a memory management technique that counts the references on all objects and when an object’s reference count reaches 0, it is automatically deallocated. Memory can be leaked when 2 objects have exclusive references to each other.
Differences between ARC and Garbage Collection:
Garbage collection is a type of brute force management of memory, it uses the the Mark and Sweep algorithm which starts at the roots of available objects, and traverserse their object trees, marking all objects that are referenced as alive (Mark), then it reclaims memory from objects that are not marked (Sweep). It is a memory intensive process on its own, and it takes a lot of processing as well. You can even have memory leaks if you reference an object that is deallocated, because Garbage collection will mark it as alive along with other potentially deallocated objects it is referencing.
Dereferencing vs Deallocating.
Dereferencing is when a reference is removed, deallocated is when the object is removed from memory which is reclaimed.
What is Sync vs Async:
Synchronous function returns the control on the current queue only after task is finished. It pauses iterations through the task queue and waits until the designated synchronous task is finished.
Asynchronous function returns control on the current queue right after task has been sent to be performed on the different queue. It doesn’t wait until the task is finished. It doesn’t block iterations of the current queue.
What is a scripting vs non-scripting language?
A scripting language uses an interpreter at runtime to compile into machine code, where as a non-scripting language uses a compiler before runtime to convert into machine code.
A scripting language will run its first line sooner, but a compiled language will run its tasks faster.
A scripting language compiles while it runs, a compiled language compiles before it runs.
What is the difference between weak, unowned, and strong references? When should you use each?
A reference is a way to access an object in code. The default reference is strong. Weak and unowned references are introduced to mitigate the occurances of retain cycles.
What are some of the differences between Swift X and Swift X+1?
Swift 2:
- Open sourced.
- Error Handling
@available
- protocol extensions
- Annotated SDK renames so that you don’t have to handle optional non-optionals.
Swift 3:
Swift 4:
Swift 5:
- opaque can be used to mask implementation details.
Self
can be used for classes and value types, not just protocols.
What are the different types of thread priorities available?
static let userInteractive: DispatchQoS
The quality-of-service class for user-interactive tasks, such as animations, event handling, or updating your app’s user interface.
static let userInitiated: DispatchQoS
The quality-of-service class for tasks that prevent the user from actively using your app.
static let `default`: DispatchQoS
The default quality-of-service class.
static let utility: DispatchQoS
The quality-of-service class for tasks that the user does not track actively.
static let background: DispatchQoS
The quality-of-service class for maintenance or cleanup tasks that you create.
static let unspecified: DispatchQoS
The absence of a quality-of-service class.
What is the difference between a run-loop and a thread.
Run loop: Run loops are part of the fundamental infrastructure associated with threads. A run loop is an event processing loop that you use to schedule work and coordinate the receipt of incoming events. The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none.
Thread: Use this class when you want to have an Objective-C method run in its own thread of execution. Threads are especially useful when you need to perform a lengthy task, but don’t want it to block the execution of the rest of the application. In particular, you can use threads to avoid blocking the main thread of the application, which handles user interface and event-related actions. Threads can also be used to divide a large job into several smaller jobs, which can lead to performance increases on multi-core computers.
The Thread
class supports semantics similar to those of Operation
for monitoring the runtime condition of a thread. You can use these semantics to cancel the execution of a thread or determine if the thread is still executing or has finished its task. Canceling a thread requires support from your thread code; see the description for cancel()
for more information.
What is a DispatchGroup and when did you use one?
Overview
Groups allow you to aggregate a set of tasks and synchronize behaviors on the group. You attach multiple work items to a group and schedule them for asynchronous execution on the same queue or different queues. When all work items finish executing, the group executes its completion handler. You can also wait synchronously for all tasks in the group to finish executing.
What are the requirements for using Swift UI?
SwiftUI provides views, controls, and layout structures for declaring your app’s user interface. The framework provides event handlers for delivering taps, gestures, and other types of input to your app, and tools to manage the flow of data from your app’s models down to the views and controls that users will see and interact with.
Create your own custom views that conform to the View
protocol, and compose them with SwiftUI views for displaying text, images, and custom shapes using stacks, lists, and more. Apply powerful modifiers to built-in views and your own views to customize their rendering and interactivity. Share code between apps on multiple platforms with views and controls that adapt to their context and presentation.
What is the difference between MVVM and MVC?
I made a Medium article for this.
MVVM
- View ➡ ViewModel ➡ Model
- The view has a reference to the ViewModel but not vice versa.
- The ViewModel has a reference to the Model but not vice versa.
- The View has no reference to the Model and vice versa.
2. If you are using a controller, it can have a reference to Views and ViewModels, though a Controller is not always necessary as demonstrated in SwiftUI.
3. Data Binding: we create listeners for ViewModel Properties.
class CustomView: UIView {
var viewModel = MyViewModel {
didSet {
self.color = viewModel.color
}
} convenience init(viewModel: MyViewModel) {
self.viewModel = viewModel
}
}
struct MyViewModel {
var viewColor: UIColor {
didSet {
colorChanged?() // This is where the binding magic happens.
}
} var colorChanged: ((UIColor) -> Void)?
}
class MyViewController: UIViewController { let myViewModel = MyViewModel(viewColor: .green)
let customView: CustomView! override func viewDidLoad() {
super.viewDidLoad() // This is where the binder is assigned.
myViewModel.colorChanged = { [weak self] color in
print("wow the color changed")
}
customView = CustomView(viewModel: myViewModel)
self.view = customView
}
}
differences in setup
- Business logic is held in the controller for MVC and the ViewModels for MVVM.
- Events are passed directly from the View to the controller in MVC while events are passed from the View to the ViewModel to the Controller (if there is one) for MVVM.
Common features
- Both MVVM and MVC do not allow the View to send messages directly to the Model/s.
- Both have models.
- Both have views.
Advantages of MVVM
- Because the ViewModels hold business logic, they are smaller concrete objects making them easy to unit tests. On the other hand, in MVC, the business logic is in the ViewController. How can you trust that a unit test of a view controller is comprehensively safe without testing all the methods and listeners simultaneously? You can’t wholly trust the unit test results.
- In MVVM, because business logic is siphoned out of the Controller into atomic ViewModel units, the size of the ViewController shrinks and this makes the ViewController code more legible.
Advantages of MVC
- Providing business logic within the controller reduces the need for branching and therefore statements are more likely to run on the cache which is more performant over encapsulating business logic into ViewModels.
- Providing business logic in one place can accelerate the development process for simple applications, where tests are not required. I don’t know when tests are not required.
- Providing business logic in the ViewController is easier to think about for new developers.
What is Viper?
Viper is a design pattern that implements ‘separation of concern’ paradigm. Mostly like MVP or MVC it follows a modular approach. One feature, one module. For each module VIPER has five (sometimes four) different classes with distinct roles. No class go beyond its sole purpose. These classes are following.
View: Class that has all the code to show the app interface to the user and get their responses. Upon receiving a response View alerts the Presenter.
Presenter: Nucleus of a module. It gets user response from the View and work accordingly. Only class to communicate with all the other components. Calls the router for wire-framing, Interactor to fetch data (network calls or local data calls), view to update the UI.
Interactor: Has the business logics of an app. Primarily make API calls to fetch data from a source. Responsible for making data calls but not necessarily from itself.
Router: Does the wire-framing. Listens from the presenter about which screen to present and executes that.
Entity: Contains plain model classes used by the interactor.
Below shows a simple diagram of VIPER
Assignment:
Create an iOS project that has 4 quadrants with uiviews. Give them constraints so that they are all equal height and equal width and fill the screen. Now create the constraints in storyboard so that, when the device is iPhone, it will only show two quadrant views, and when its ipad it will show all 4.