Вопросы на собеседовании: Swift-разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня iOS-разработчик.
Смотреть пример резюме: Swift-разработчик →Тренировка флешкарточками
Интервальное повторение · Hunter Pass
Вопросы
let создаёт неизменяемую привязку, а значение, объявленное через var, можно менять.
- Предпочитайте let: тогда случайное повторное присваивание станет ошибкой компиляции.
- Используйте var для счётчика или суммы, которые должны изменяться.
- В Array, объявленный через let, нельзя добавить элемент с помощью append, а в Array через var можно.
Зачем это спрашивают: Вопрос проверяет понимание неизменяемых и изменяемых привязок в Swift.
Swift определяет по литералу тип Int, поэтому явно указывать тип не нужно.
- Выведенный тип фиксируется во время компиляции.
- Напишите : Int64, если API требует именно этот тип.
- Попытка позже присвоить несовместимое значение всё равно приведёт к ошибке компиляции.
Зачем это спрашивают: Вопрос проверяет понимание статического вывода типов.
Swift требует явного преобразования, потому что при сужении типа часть данных может потеряться.
- Int(3.8) намеренно отбрасывает дробную часть.
- Проверяйте границы диапазона, если входное число может оказаться слишком большим.
- Для вычислений с дробной частью преобразуйте Int в Double.
Зачем это спрашивают: Вопрос проверяет понимание безопасной работы с числовыми типами.
При присваивании значения создаётся независимая копия, а при присваивании ссылки две переменные указывают на один экземпляр.
- struct, enum, Array и Dictionary имеют семантику значений.
- Экземпляры class имеют ссылочную семантику.
- Изменение одной копии структуры не влияет на другую.
Зачем это спрашивают: Вопрос проверяет понимание поведения значимых и ссылочных типов.
Копии Array могут использовать общее хранилище, пока одну из них не изменят.
- При присваивании обычно не происходит немедленного копирования каждого элемента.
- При первом изменении для этой копии при необходимости создаётся отдельное хранилище.
- Внешне Array всё равно ведёт себя как значимый тип.
Зачем это спрашивают: Вопрос проверяет понимание механизма copy-on-write.
Optional хранит либо значение заданного типа, либо nil.
- Int? является сокращённой записью Optional<Int>.
- Там, где требуется обычный Int, опциональное значение нужно извлечь.
- Так можно представить отсутствие данных без условных значений вроде -1.
Зачем это спрашивают: Вопрос проверяет понимание опциональных значений.
Ветка if let выполняется, только если опциональное значение не равно nil.
- При nil условие просто не выполняется, и приложение не падает.
- Внутри ветки связанное имя имеет уже не опциональный тип.
- Ветка else позволяет явно обработать отсутствие значения.
Зачем это спрашивают: Вопрос проверяет понимание безопасного извлечения опциональных значений.
guard let удобен для проверки условия, при нарушении которого функция должна сразу завершить текущий путь.
- Блок else должен выполнить return, throw, break или continue.
- Извлечённое значение остаётся доступным после guard.
- Основной успешный сценарий не приходится помещать в глубокую вложенность.
Зачем это спрашивают: Вопрос проверяет выбор конструкции для управления потоком с опциональными значениями.
String использует String.Index, потому что один Character может состоять из нескольких скаляров Unicode.
- startIndex указывает на первую допустимую границу символа.
- index(after:) переводит индекс к следующей допустимой границе.
- Для небольших задач можно использовать Array(string), но это потребует дополнительной памяти.
Зачем это спрашивают: Вопрос проверяет понимание безопасной работы со строками Unicode.
Array хранит упорядоченные элементы, Set только уникальные элементы, а Dictionary сопоставляет ключи со значениями.
- Array допускает повторы и доступ по позиции.
- Set подходит для быстрой проверки наличия элемента, когда порядок не важен.
- Обращение к Dictionary возвращает опциональное значение, потому что ключ может отсутствовать.
Зачем это спрашивают: Вопрос проверяет умение выбрать подходящую коллекцию.
Кортеж объединяет фиксированный набор связанных значений без объявления нового именованного типа.
- Имена полей делают запись (code: 200, message: "OK") понятной.
- Функция может вернуть два небольших результата одним кортежем.
- Если данным нужны методы или многократное использование, лучше объявить struct.
Зачем это спрашивают: Вопрос проверяет понимание назначения кортежей.
Диапазон a...b включает b, а a..<b не включает его.
- 1...3 содержит 1, 2 и 3.
- 0..<array.count соответствует обычным целочисленным индексам массива.
- Если индекс не нужен, лучше перебирать сами элементы.
Зачем это спрашивают: Вопрос проверяет понимание границ диапазонов.
Для небольшого одноразового результата функция может вернуть именованный кортеж.
- Возвращаемый тип можно записать как (min: Int, max: Int).
- Вызывающий код обращается к полям через result.min и result.max.
- Если результат становится частью предметной модели, лучше использовать struct.
Зачем это спрашивают: Вопрос проверяет способы возврата нескольких значений из функции.
Метки аргументов поясняют назначение параметров в месте вызова функции.
- Вызов move(from: 1, to: 3) читается как фраза.
- Внутреннее имя параметра может отличаться от его метки.
- Используйте _ только тогда, когда вызов без метки остаётся понятным.
Зачем это спрашивают: Вопрос проверяет понимание меток аргументов.
Значение по умолчанию позволяет не передавать необязательный аргумент и при этом сохранить одну реализацию функции.
- В greet(name:punctuation:) для punctuation можно задать значение "!".
- Явно переданный аргумент заменяет значение по умолчанию.
- Обязательные для логики данные не следует скрывать за значением по умолчанию.
Зачем это спрашивают: Вопрос проверяет понимание параметров со значениями по умолчанию.
inout позволяет функции изменить переменную, переданную вызывающим кодом.
- В объявлении inout ставится перед типом параметра.
- При вызове используется &, например increment(&count).
- Константу let передать нельзя, потому что функция должна изменить значение.
Зачем это спрашивают: Вопрос проверяет понимание изменения аргументов через inout.
Замыкание представляет исполняемый код, который можно хранить и передавать как значение.
- Оно может захватывать имена из окружающей области видимости.
- Методы map и filter принимают замыкания.
- Синтаксис завершающего замыкания позволяет вынести его за круглые скобки.
Зачем это спрашивают: Вопрос проверяет базовое понимание замыканий.
@escaping означает, что замыкание-параметр может продолжить существовать после завершения вызова функции.
- Сохраняемые обработчики завершения обычно требуют @escaping.
- Обычное неубегающее замыкание выполняется во время вызова функции.
- В убегающем замыкании при захвате экземпляра нужно явно писать self.
Зачем это спрашивают: Вопрос проверяет понимание убегающих замыканий.
Исходное значение задаёт каждому case одно постоянное значение общего простого типа.
- В enum Direction: String каждому варианту можно назначить строковое значение.
- Инициализатор init(rawValue:) возвращает опциональное значение, потому что входные данные могут не совпасть ни с одним case.
- Исходное значение объявляется один раз, а не передаётся при создании каждого экземпляра.
Зачем это спрашивают: Вопрос проверяет понимание исходных значений у перечислений.
Связанные значения добавляют данные времени выполнения к конкретному case перечисления.
- Разные варианты могут хранить значения разных типов, например success(Data).
- Шаблон в switch позволяет извлечь связанное значение.
- Исходные значения постоянны, а связанные могут отличаться у разных экземпляров.
Зачем это спрашивают: Вопрос проверяет различие между связанными и исходными значениями enum.
Закрытые вопросы
- 21
Когда стоит выбрать struct вместо class?
swiftvalue-typesreference-types - 22
Чем хранимые свойства отличаются от вычисляемых?
- 23
Что такое willSet и didSet?
- 24
Почему методу структуры иногда нужен mutating?
swiftvalue-typesmutation - 25
За что отвечает инициализатор?
- 26
Что определяет протокол?
typingprotocols - 27
Что можно добавить с помощью extension?
extensions - 28
Зачем использовать обобщённую функцию вместо Any?
generics - 29
Как вместе работают throws, try и do-catch?
error-handling - 30
Когда полезен Result?
result-type - 31
Что делает defer?
resource-cleanup - 32
Чем управляет ARC?
memory - 33
Чем отличаются weak и unowned?
memorymemory-management - 34
Что предоставляет Codable?
codableserialization - 35
Как CodingKeys помогает при работе с JSON?
serialization - 36
Что представляют URL, Data и Date в Foundation?
- 37
Чем отличаются private, fileprivate, internal и public?
- 38
Что такое модуль Swift и что делает import?
swiftmodules - 39
Что означают package, target и product в SPM?
swift-package-manager - 40
Что означают async и await?
asyncconcurrency - 41
Для чего используется Task?
structured-concurrency - 42
Что гарантирует @MainActor?
actor-isolation - 43
Какую проблему решает actor?
concurrency - 44
Что выражает Sendable?
concurrency - 45
Как устроен простой тест XCTest?
xctestswiftvalue-types - 46
Для чего нужны setUp и tearDown?
- 47
Где проходит граница между SwiftUI View и состоянием?
swiftuiswift - 48
Чем отличаются SwiftUI и UIKit?
uikitswiftuiswift - 49
Как консольная программа на Swift может прочитать аргументы процесса?
concurrencyswift - 50
Что делает простой маршрут в Vapor?
server-side - 51
Int("abc") возвращает nil. Как консольная программа должна сообщить о неверном вводе?
- 52
Принудительное извлечение приводит к падению, если поля нет в JSON. Что нужно изменить?
- 53
Если nickname отсутствует, нужно показать "Guest". Какое выражение с Optional подойдёт?
swiftoptionals - 54
При декодировании возникает keyNotFound для поля, которое иногда отсутствует. Как исправить модель?
- 55
JSON содержит "age": "20", а в модели используется Int. Почему декодирование завершается ошибкой?
- 56
В JSON используется user_id, а в Swift свойство называется userID. Как локально исправить keyNotFound?
swift - 57
Удаление элементов Array во время обхода старых индексов приводит к падению. Как переписать код?
- 58
Почему counts[word] += 1 не компилируется для Dictionary?
- 59
После var b = a добавление элемента в Array b не меняет a. Это ожидаемое поведение?
- 60
После let b = a для экземпляра class изменение b.name также меняет a.name. Почему?
reference-types - 61
text[0] приводит к ошибке компиляции. Как прочитать первый Character?
- 62
Сохранённое замыкание выводит последнее значение counter, а не значение на момент создания. Как захватить снимок?
closuressnapshot - 63
Обратный вызов с @escaping требует явно указать self для свойства. Чего добивается компилятор?
callbacksescaping-closures - 64
Контроллер не деинициализируется после сохранения замыкания, которое использует self. В чём вероятная причина?
closures - 65
Обратный вызов с [weak self] при выполнении получает nil. Всегда ли это ошибка?
callbacksmemory - 66
Тип не выполняет требование протокола к свойству get-set. Что он должен предоставить?
typingprotocols - 67
Протокол Resettable требует mutating func reset(), но reset у struct получает ошибку "self is immutable" на count = 0. Как это исправить?
immutabilitytypingswift - 68
Обобщённая функция maximum не может применить > к T без ограничений. Чего не хватает?
generics - 69
Для readFile() компилятор сообщает, что вызов функции с ошибкой не помечен try. Какие есть варианты?
- 70
Общий catch скрывает известный случай invalidInput. Как сохранить его сообщение?
- 71
Функция выводит ошибку, а вызывающий код продолжает работу так, будто всё удалось. Что нужно изменить?
- 72
Дескриптор файла остаётся открытым, если разбор данных бросает ошибку. Что гарантирует очистку?
error-handling - 73
Для асинхронного вызова компилятор сообщает, что он не помечен await. Что требуется?
asyncconcurrency - 74
Синхронный обработчик кнопки должен вызвать async load(). Какое небольшое изменение исправит границу?
asynccallbacksconcurrency - 75
Отмена Task не останавливает долгий цикл. Чего не хватает?
structured-concurrency - 76
Две задачи увеличивают счётчик, но итоговое значение оказывается слишком маленьким. Как поможет actor?
concurrency - 77
Чтение counter.value за пределами actor приводит к ошибке изоляции. Что должен сделать вызывающий код?
concurrency - 78
Асинхронная работа обновляет состояние интерфейса и вызывает предупреждение об actor. Как это исправить?
asyncconcurrencystate - 79
Захват изменяемого экземпляра class в замыкании @Sendable вызывает предупреждение. Какое простое безопасное решение подойдёт?
closuresconcurrencyreference-types - 80
Два независимых асинхронных запроса выполняются последовательно. Как запустить оба до ожидания результатов?
asyncconcurrency - 81
Тесту XCTest нужно значение из async loadName(). Какая сигнатура подойдёт?
asyncconcurrencytesting - 82
parse("bad") должна бросить ошибку. Как проверить это в XCTest?
xctest - 83
Тест проходит отдельно, но падает после того, как другой тест изменил singleton. Что исправить первым?
- 84
SPM сообщает no such module Utility, хотя цель существует. Что проверить сначала?
swift-package-managermodules - 85
Продукт называется ToolsKit, а модуль ToolsCore. Какое имя нужно указать в import?
modules - 86
SPM ожидает исходные файлы AppCLI в Sources/AppCLI. Какие два исправления допустимы?
swift-package-manager - 87
FileManager не находит config.json из консольной программы. Как проверить путь?
configfile-system - 88
Консольная программа для JSON выводит только "decode failed". Как показать полезную причину?
- 89
CLI падает на CommandLine.arguments[1], если аргументов нет. Каково минимальное исправление?
- 90
ArgumentParser требует --input, но пользователь не передаёт этот параметр. Что должно произойти?
argument-parser - 91
ArgumentParser получает --count many для Int. На каком этапе должна возникнуть ошибка?
argument-parser - 92
GET /users возвращает 404, но в Vapor зарегистрирован app.post. В чём ошибка?
server-side - 93
Маршрут Vapor /users/:id совпал с /users/abc, но обработчику нужен id типа Int. Какой ответ и какое исправление верны?
server-side - 94
Vapor POST получает некорректный JSON для Content. Что должен сделать обработчик?
server-side - 95
Запрос Vapor принимает пустой username и позже завершается ошибкой. Где нужно выполнять проверку?
validationserver-side - 96
Поиск Vapor возвращает nil для пользователя 42. Какой статус лучше пустого ответа 200?
server-side - 97
Асинхронный обработчик Vapor вызывает сервис с ошибкой без try await. Что требуется?
asyncconcurrencyserver-side - 98
Кнопка SwiftUI меняет локальный var внутри body, но текст не обновляется. Что требуется?
swiftuiswift - 99
SwiftUI List теряет строки, потому что элементы имеют одинаковый id. Что нужно изменить?
swiftuiswift - 100
Переиспользуемая UITableViewCell на мгновение показывает асинхронно загруженное изображение предыдущей строки. Как это исправить?
asyncconcurrencyuikit