Как пройти собеседование по Swift: топ вопросов и ответов

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как пройти собеседование по Swift: топ вопросов

Собеседование на позицию iOS-разработчика — это не только проверка знания фреймворков, но и глубокое понимание языка Swift. Работодатели хотят видеть кандидата, который разбирается в управлении памятью, конкурентности и особенностях синтаксиса. В этой статье мы собрали топ вопросов, которые часто задают на собеседованиях, с подробными ответами и примерами кода. Статья будет полезна как джуниорам, так и опытным разработчикам, желающим освежить знания перед интервью.

1. Основы Swift: типы, опционалы и управление памятью

Базовые вопросы проверяют, насколько хорошо вы понимаете фундаментальные концепции языка. Начнём с самого популярного — опционалов.

Вопрос 1: Что такое опционалы и зачем они нужны?

Ответ: Опционалы — это механизм безопасности типов, который позволяет переменной либо содержать значение, либо быть nil (отсутствие значения). Они решают проблему null-указателей, распространённую в других языках.

// Объявление опционала
var name: String? = "Анна"
name = nil // теперь переменная не содержит значения

// Безопасное извлечение (optional binding)
if let unwrappedName = name {
    print("Привет, \(unwrappedName)")
} else {
    print("Имя отсутствует")
}

// Принудительное извлечение (force unwrap) — опасно!
// let forcedName = name! // краш, если name == nil

Вопрос 2: В чём разница между struct и class?

Ответ: struct — это тип-значение (value type), а class — ссылочный тип (reference type). Структуры копируются при присваивании, классы передаются по ссылке. Кроме того, классы поддерживают наследование, а структуры — нет.

struct Point {
    var x: Int
    var y: Int
}

class Person {
    var name: String
    init(name: String) { self.name = name }
}

var pointA = Point(x: 1, y: 2)
var pointB = pointA // копия
pointB.x = 10
print(pointA.x) // 1 — оригинал не изменился

var personA = Person(name: "Иван")
var personB = personA // ссылка на тот же объект
personB.name = "Пётр"
print(personA.name) // "Пётр" — изменился

Вопрос 3: Как работает Automatic Reference Counting (ARC)?

Ответ: ARC автоматически подсчитывает количество сильных ссылок на объект класса. Когда счётчик достигает нуля, объект освобождается из памяти. Проблемы возникают при циклических ссылках (retain cycles), которые решаются с помощью weak или unowned ссылок.

class Parent {
    var child: Child?
}

class Child {
    weak var parent: Parent? // weak предотвращает retain cycle
}

var parent: Parent? = Parent()
var child: Child? = Child()
parent?.child = child
child?.parent = parent

2. Продвинутые концепции: замыкания, протоколы и дженерики

На следующем этапе интервьюер проверяет, умеете ли вы использовать функциональные возможности Swift.

Вопрос 4: Что такое замыкания (closures) и как они захватывают значения?

Ответ: Замыкание — это блок кода, который можно передавать и использовать как функцию. Оно захватывает (captures) переменные из окружающего контекста. Захват может быть сильным или слабым.

func makeIncrementer(incrementAmount: Int) -> () -> Int {
    var total = 0
    let incrementer: () -> Int = {
        total += incrementAmount // захват total
        return total
    }
    return incrementer
}

let incrementByTwo = makeIncrementer(incrementAmount: 2)
print(incrementByTwo()) // 2
print(incrementByTwo()) // 4

Вопрос 5: В чём разница между протоколом и абстрактным классом?

Ответ: В Swift нет абстрактных классов. Протокол определяет контракт (требования), который должны реализовать классы, структуры или перечисления. Протоколы могут иметь расширения с реализацией по умолчанию.

protocol Drivable {
    var speed: Int { get set }
    func drive()
}

struct Car: Drivable {
    var speed: Int = 0
    func drive() {
        print("Машина едет со скоростью \(speed) км/ч")
    }
}

Вопрос 6: Как работают дженерики (generics)?

Ответ: Дженерики позволяют писать гибкий и переиспользуемый код, который работает с любым типом. Они широко используются в стандартной библиотеке Swift (например, Array<Element>).

func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var first = 10
var second = 20
swapTwoValues(&first, &second)
print(first, second) // 20 10

3. UIKit и архитектура iOS-приложений

Без знания UIKit собеседование по iOS невозможно. Здесь проверяют практический опыт.

Вопрос 7: Что такое MVC и в чём его недостатки?

Ответ: Model-View-Controller — это архитектурный паттерн, где Model отвечает за данные, View — за отображение, а Controller связывает их. Недостатки: Massive View Controller (контроллеры становятся слишком большими), сложность тестирования. Альтернативы: MVVM, VIPER, SwiftUI.

Вопрос 8: Как работает жизненный цикл UIViewController?

Ответ: Основные методы: viewDidLoad(), viewWillAppear(), viewDidAppear(), viewWillDisappear(), viewDidDisappear(). Порядок вызова зависит от того, как контроллер добавляется на экран.

override func viewDidLoad() {
    super.viewDidLoad()
    // Настройка UI, загрузка данных — вызывается один раз
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // Обновление данных перед показом
}

Вопрос 9: Как избежать retain cycle в замыканиях при работе с UIKit?

Ответ: Используйте capture list с [weak self] внутри

Блоги

Рекомендаций по книгам