Найти в Дзене
Lyakhov Eugene

Теоретические задачи Swift

swift let maximumAttempts = 3 // константа
var currentScore = 0 // переменная
currentScore = 10 // ✅ ок
// maximumAttempts = 5 // ❌ ошибка компиляции swift var userName: String? = "Alice"
userName = nil // допустимо swift let name: String? = "Alex"
if let unwrappedName = name {
print("Hello, \(unwrappedName)")
}
let displayName = name ?? "Guest" Выбор: структуры предпочтительнее для простых данных (например, модель, не имеющая идентичности), классы — когда нужны наследование или общее состояние. swift protocol Drawable {
func draw()
}
struct Circle: Drawable {
func draw() { print("Рисуем круг") }
} swift let names = ["Anna", "Alex", "Brian"]
let sorted = names.sorted { $0 < $1 } swift enum Result<T> {
case success(T)
case failure(Error)
} swift enum FileError: Error { case notFound }
func readFile() throws -> String { ... }
do {
let content = try readFile()
} catch {
print("Ошибка: \(error)")
} Структуры автоматически получают memberwise-и

  1. Что такое Swift?
    Swift — это современный язык программирования, разработанный компанией Apple для создания приложений под iOS, macOS, watchOS, tvOS и другие платформы. Он сочетает производительность компилируемых языков с простотой и выразительностью скриптовых языков. Swift безопасен по умолчанию (опционалы, строгая типизация), быстр и поддерживает парадигмы ООП, протокольно-ориентированного и функционального программирования.
  2. Какие основные типы данных существуют в Swift?
    Swift предоставляет как фундаментальные, так и коллекционные типы:
  • Целые числа: Int, UInt (и размерные варианты Int8, Int32 и т.д.)
  • Числа с плавающей точкой: Double, Float
  • Логический тип: Bool (true/false)
  • Строки: String, Character
  • Коллекции: Array, Set, Dictionary
  • Кортежи (tuples): группировка нескольких значений
  • Опционалы: Optional<T>
  1. Чем отличается let от var?
    let объявляет константу — значение присваивается один раз и не может быть изменено. var объявляет переменную, значение которой можно менять после инициализации. Константы способствуют безопасности кода и могут быть оптимизированы компилятором.

swift

let maximumAttempts = 3 // константа
var currentScore = 0
// переменная
currentScore = 10
// ✅ ок
// maximumAttempts = 5 // ❌ ошибка компиляции

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

swift

var userName: String? = "Alice"
userName = nil
// допустимо

  1. Какие способы разворачивания (unwrap) опционалов существуют?
  • Принудительное извлечение — ! (опасно, если опционал nil — краш).
  • Привязка опционала (optional binding) — if let, guard let.
  • Оператор объединения с nil (nil-coalescing) — ??, предоставляет значение по умолчанию.
  • Неявно извлечённые опционалы (implicitly unwrapped optionals) — ! при объявлении, автоматически извлекаются при обращении (рискованно).
  • Опциональный паттерн (optional pattern) в switch или case.

swift

let name: String? = "Alex"
if let unwrappedName = name {
print("Hello, \(unwrappedName)")
}
let displayName = name ?? "Guest"

  1. В чем разница между структурами (struct) и классами (class)?
  • Тип: структуры — значимый тип (value type), копируются при присваивании; классы — ссылочный тип (reference type), передаются по ссылке.
  • Наследование: классы поддерживают наследование, структуры — нет.
  • Деинициализаторы: только у классов.
  • Подсчёт ссылок (ARC): применяется к классам, не к структурам.
  • Мутабельность: методы структур, изменяющие свойства, должны быть помечены mutating.

Выбор: структуры предпочтительнее для простых данных (например, модель, не имеющая идентичности), классы — когда нужны наследование или общее состояние.

  1. Что такое протоколы в Swift?
    Протокол — это набор требований (свойства, методы, инициализаторы), которым должен соответствовать тип, подписанный под протокол. Протоколы могут быть унаследованы, расширены и использованы как типы. Swift активно использует протоколы (например, Equatable, Codable). Протокольно-ориентированное программирование — одна из ключевых парадигм Swift.

swift

protocol Drawable {
func draw()
}
struct Circle: Drawable {
func draw() { print("Рисуем круг") }
}

  1. Что такое замыкания (closures) в Swift?
    Замыкания — самодостаточные блоки функциональности, которые могут быть переданы и использованы в коде. Они захватывают константы и переменные из контекста, в котором определены. Бывают глобальными, вложенными и «замыкающими выражениями». Синтаксис оптимизирован (опускание типов, сокращённые имена аргументов, трейлинг-замыкания).

swift

let names = ["Anna", "Alex", "Brian"]
let sorted = names.sorted { $0 < $1 }

  1. Что такое escaping-замыкания?
    По умолчанию замыкание является не-escape (выполняется внутри функции). Если замыкание переживает вызов функции (сохраняется в свойство, передаётся асинхронно), необходимо пометить параметр как @escaping. Это сигнализирует о необходимости явно указывать self. внутри, чтобы избежать сильных ссылочных циклов.
  2. Какие возможности предоставляют перечисления (enum) в Swift?
    Перечисления в Swift — это полноценные типы первого класса. Они могут:
  • Иметь вычисляемые свойства и методы.
  • Поддерживать инициализаторы.
  • Соответствовать протоколам.
  • Хранить связанные значения (associated values) — разные типы для разных кейсов.
  • Иметь исходные значения (raw values) — значения одного типа для всех кейсов.
  • Поддерживать рекурсивные кейсы (indirect).

swift

enum Result<T> {
case success(T)
case failure(Error)
}

  1. Как обрабатывать ошибки в Swift?
    Swift предлагает модель обработки ошибок с помощью throws, try, catch. Функция, которая может выбросить ошибку, помечается throws. Вызывающий код должен использовать try (или try?, try!) внутри блока do { ... } catch { ... }. Ошибки должны соответствовать протоколу Error.

swift

enum FileError: Error { case notFound }
func readFile() throws -> String { ... }
do {
let content = try readFile()
} catch {
print("Ошибка: \(error)")
}

  1. Что такое инициализаторы (init) и какие их виды бывают?
    Инициализатор подготавливает экземпляр типа к использованию. Виды:
  • Пользовательские (designated) — основные, полностью инициализируют свойства.
  • Удобные (convenience) — делегируют другому designated-инициализатору.
  • Проваливающиеся (failable) — могут вернуть nil (инициализатор с ?).
  • Обязательные (required) — должны быть реализованы в подклассах.

Структуры автоматически получают memberwise-инициализатор, если не определён свой.

  1. Как в Swift управляется памятью?
    Swift использует автоматический подсчёт ссылок (ARC) для управления памятью объектов классов. Каждый экземпляр класса имеет счетчик ссылок; когда он достигает нуля, память освобождается. Разработчик должен избегать циклов сильных ссылок с помощью ключевых слов weak или unowned. Структуры и перечисления являются value type и не используют ARC.
  2. Что такое расширения (extensions)?
    Расширения позволяют добавить новую функциональность существующему типу (классу, структуре, перечислению или протоколу): вычисляемые свойства, методы, инициализаторы, подписки (subscripts), вложенные типы, а также соответствие протоколам. Нельзя переопределять существующие методы или добавлять хранимые свойства.
  3. Что такое дженерики (generics)?
    Дженерики позволяют писать гибкий, переиспользуемый код, который работает с любым типом, удовлетворяющим заданным условиям. Используются в функциях, типах (классы, структуры, перечисления) и протоколах (с помощью associatedtype). Позволяют избежать дублирования кода и сохранить строгую типизацию.

swift

func swapValues<T>(_ a: inout T, _ b: inout T) {
(a, b) = (b, a)
}

  1. Объясните работу map, filter и reduce.
    Это методы функционального программирования над коллекциями:
  • map — преобразует каждый элемент коллекции, возвращает новый массив.
  • filter — отбирает элементы, удовлетворяющие условию.
  • reduce — объединяет все элементы в одно значение, применяя замыкание.

swift

let numbers = [1, 2, 3]
let squares = numbers.map { $0 * $0 }
// [1, 4, 9]
let even = numbers.filter { $0 % 2 == 0 }
// [2]
let sum = numbers.reduce(0, +)
// 6

  1. Что такое опциональная цепочка (optional chaining)?
    Опциональная цепочка — процесс обращения к свойствам, методам и сабскриптам опционала, который может быть nil. Если опционал не nil, вызов выполняется, иначе вся цепочка возвращает nil. Результат всегда опционален. Используется оператор ?.

swift

let apartmentNumber = person.residence?.address?.apartmentNumber

  1. Чем willSet и didSet отличаются от get/set?
    willSet и didSet — наблюдатели свойств (property observers). Вызываются
    после изменения значения хранимого свойства. get и set — аксессоры для вычисляемых свойств, которые сами не хранят значение, а вычисляют его при каждом обращении.
  2. Какие модификаторы доступа есть в Swift?
  • open — доступ везде, можно наследовать и переопределять вне модуля.
  • public — доступ везде, но наследование/переопределение только внутри модуля.
  • internal — доступ внутри модуля (по умолчанию).
  • fileprivate — доступ только в пределах одного файла.
  • private — доступ только в пределах декларации (и её расширений в том же файле, Swift 4+).
  1. Как работает приведение типов (type casting) в Swift?
    Используются операторы is, as?, as!.
  • is — проверяет, является ли экземпляр типом (возвращает Bool).
  • as? — условное приведение, возвращает опционал.
  • as! — принудительное приведение (опасно, если типы несовместимы).
    Приведение также работает с протоколами и классовой иерархией.
  1. Что такое lazy-свойства?
    Ленивые свойства — это хранимые свойства, инициализация которых откладывается до момента первого обращения. Объявляются с ключевым словом lazy. Полезны, когда начальное значение ресурсоёмко или зависит от других свойств, которые могут быть ещё не готовы. Может использоваться только с var.
  2. Как работает оператор defer?
    defer откладывает выполнение блока кода до выхода из текущей области видимости (функции, цикла, блока). Используется для гарантированного выполнения очистки (закрытие файлов, освобождение ресурсов) независимо от того, как завершился блок (return, throw, break). Блоки defer выполняются в обратном порядке объявления.
  3. Что такое async/await в Swift?
    async/await — модель конкурентности, введённая в Swift 5.5. async маркирует асинхронные функции; await — точка ожидания выполнения асинхронной операции. Код выглядит как синхронный, но не блокирует поток. Асинхронные функции могут вызывать другие асинхронные функции, приостанавливаться и возобновляться. Эта модель упрощает работу с асинхронным кодом по сравнению с замыканиями.

swift

func fetchData() async throws -> Data { ... }
Task {
let data = try await fetchData()
}

  1. Что такое тип Result?
    Result<Success, Failure: Error> — перечисление, представляющее либо успех (со значением типа Success), либо неудачу (с ошибкой типа Failure). Используется для обработки результатов операций, которые могут завершиться ошибкой, без использования throw. Удобно в сочетании с замыканиями и async/await (например, в Combine).

swift

enum NetworkError: Error { case badRequest }
let result: Result<Data, NetworkError> = .failure(.badRequest)

  1. Что такое протокол Codable?
    Codable — псевдоним для протоколов Encodable и Decodable. Типы, соответствующие Codable, могут быть легко преобразованы во внешние форматы (например, JSON, Property List) и обратно без ручного парсинга. Swift автоматически синтезирует реализацию, если все свойства соответствуют Codable. Используется с JSONEncoder/JSONDecoder.

swift

struct User: Codable {
let id: Int
let name: String
}
let json = try JSONEncoder().encode(user)

Страховка на собеседовании

Знание есть, но стресс мешает?
Бесплатное сообщество для прокачки карьеры в IT

Подпишись на https://t.me/IT_Interview_Partner_Bot

Подпишись на
https://t.me/LyakhovEugene