ru
Feedback
Swift | Вопросы собесов

Swift | Вопросы собесов

Открыть в Telegram
2 167
Подписчики
+124 часа
-17 дней
-1830 дней
Привлечение подписчиков
сентябрь '26
сентябрь '26
+13
в 0 каналах
август '26
+25
в 0 каналах
Get PRO
июль '26
+18
в 0 каналах
Get PRO
июнь '26
+32
в 1 каналах
Get PRO
май '26
+21
в 0 каналах
Get PRO
апрель '26
+23
в 0 каналах
Get PRO
март '26
+35
в 0 каналах
Get PRO
февраль '26
+45
в 1 каналах
Get PRO
январь '26
+58
в 0 каналах
Get PRO
декабрь '25
+28
в 0 каналах
Get PRO
ноябрь '25
+156
в 1 каналах
Get PRO
октябрь '25
+26
в 0 каналах
Get PRO
сентябрь '25
+41
в 0 каналах
Get PRO
август '25
+38
в 0 каналах
Get PRO
июль '25
+27
в 0 каналах
Get PRO
июнь '25
+34
в 0 каналах
Get PRO
май '25
+50
в 0 каналах
Get PRO
апрель '25
+87
в 0 каналах
Get PRO
март '25
+151
в 2 каналах
Get PRO
февраль '25
+123
в 1 каналах
Get PRO
январь '25
+127
в 53 каналах
Get PRO
декабрь '24
+55
в 1 каналах
Get PRO
ноябрь '24
+75
в 0 каналах
Get PRO
октябрь '24
+193
в 42 каналах
Get PRO
сентябрь '24
+348
в 251 каналах
Get PRO
август '24
+98
в 0 каналах
Get PRO
июль '24
+140
в 54 каналах
Get PRO
июнь '24
+411
в 244 каналах
Get PRO
май '24
+646
в 191 каналах
Get PRO
апрель '24
+353
в 23 каналах
Дата
Привлечение подписчиков
Упоминания
Каналы
17 сентября+1
16 сентября+2
15 сентября+2
14 сентября+1
13 сентября+1
12 сентября+1
11 сентября0
10 сентября+1
09 сентября+2
08 сентября0
07 сентября+2
06 сентября0
05 сентября0
04 сентября0
03 сентября0
02 сентября0
01 сентября0
Посты канала
🤔 Чем опасна утечка памяти? Утечка памяти (memory leak) – это ситуация, когда память остаётся выделенной, но больше не используется программой и не освобождается.
class Person {
    var pet: Pet? 
    deinit { print("Person удалён") }
}

class Pet {
    var owner: Person?
    deinit { print("Pet удалён") }
}

var person: Person? = Person()
var pet: Pet? = Pet()

person?.pet = pet
pet?.owner = person

person = nil
pet = nil
🚩Как избежать утечек памяти? 🟠Использовать `weak` или `unowned` ссылки Слабые (weak) или безвладельческие (unowned) ссылки не увеличивают счётчик ссылок, что разрывает цикл.
class Person {
    var pet: Pet?
    deinit { print("Person удалён") }
}

class Pet {
    weak var owner: Person? // Слабая ссылка
    deinit { print("Pet удалён") }
}

var person: Person? = Person()
var pet: Pet? = Pet()

person?.pet = pet
pet?.owner = person

person = nil  // "Person удалён"
pet = nil     // "Pet удалён"
🟠Использовать `unowned`, если объект всегда будет существовать unowned похож на weak, но он не может быть `nil`.
class Owner {
    var car: Car?
    deinit { print("Owner удалён") }
}

class Car {
    unowned var owner: Owner // Безвладельческая ссылка
    init(owner: Owner) { self.owner = owner }
    deinit { print("Car удалён") }
}

var owner: Owner? = Owner()
owner?.car = Car(owner: owner!)

owner = nil // "Owner удалён", "Car удалён"
🟠Разрывать циклы в замыканиях (`[weak self]`) Замыкания захватывают объекты, создавая циклические ссылки. Проблема: self удерживается замыканием
class ViewController {
    var closure: (() -> Void)?
    
    func setup() {
        closure = {
            print(self) // Удерживает self, создавая цикл!
        }
    }

    deinit { print("ViewController удалён") }
}

var vc: ViewController? = ViewController()
vc?.setup()
vc = nil // ❌ "ViewController" НЕ удалится
🚩Как найти утечки памяти? 🟠Использовать `Instrument – Leaks` в Xcode - Открываем Xcode > Product > Profile. - Выбираем Leaks. - Запускаем приложение и проверяем, остаются ли объекты в памяти. 🟠Проверить `deinit` Если метод deinit не вызывается – значит, объект утёк в память.
class Test {
    deinit { print("Test удалён") }
}

var obj: Test? = Test()
obj = nil // Должно напечатать "Test удалён"
🟠Включить `Malloc Stack Logging` - В Xcode открываем "Debug Memory Graph" (нажимая значок в Debugger). - Смотрим, какие объекты остались в памяти. Ставь 👍 и забирай 📚 Базу знаний

2
🤔 Что такое Generics (обобщённое программирование)? Generics позволяют писать обобщённый код, который может работать с разными типами, сохраняя типовую безопасность. Например, можно создать функцию, которая сортирует любые массивы, не указывая конкретный тип. Это снижает дублирование кода и делает библиотеки гибкими. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
142
3
🤔 Есть ли в свифте множественное наследование? В Swift нет множественного наследования классов, но можно использовать множественное наследование через протоколы. 🚩Почему нет множественного наследования классов? Swift запрещает множественное наследование классов, потому что оно может привести к конфликтам и алмазной проблеме (diamond problem). Допустим, в языке с поддержкой множественного наследования у нас есть два родительских класса с одинаковым методом: class A { public: void greet() { cout << "Hello from A"; } }; class B { public: void greet() { cout << "Hello from B"; } }; // C наследуется от A и B class C : public A, public B {}; C obj; obj.greet(); // Какой метод вызвать? A или B? 🚩Как обойти ограничение? Используем протоколы! В Swift можно реализовать множественное наследование через протоколы, поскольку класс может соответствовать нескольким протоколам одновременно. protocol Flyable { func fly() } protocol Swimmable { func swim() } class Animal {} class Duck: Animal, Flyable, Swimmable { func fly() { print("Утка летит") } func swim() { print("Утка плывёт") } } let duck = Duck() duck.fly() // Утка летит duck.swim() // Утка плывёт 🚩Что делать, если нужен код по умолчанию? Если хочется, чтобы протокол предоставлял реализацию по умолчанию (почти как родительский класс), можно использовать extension: protocol Walker { func walk() } extension Walker { func walk() { print("Иду вперёд") } } class Person: Walker {} let human = Person() human.walk() // "Иду вперёд" (метод взят из extension) Ставь 👍 и забирай 📚 Базу знаний
174
4
🤔 Какие инструменты Xcode есть? Xcode предлагает: - Интегрированную среду разработки (IDE). - Инструменты отладки: LLDB, Breakpoints, Debug View Hierarchy. - Инструменты профилирования: Instruments. - Интерфейсный редактор: Storyboard, Interface Builder. - Симуляторы, автотесты, Git-интеграция, Code Review, Device logs. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
183
5
🤔 Какие можно выделить главные принципы ООП? Объектно-ориентированное программирование (ООП) — это парадигма, основанная на концепции "объектов", которые могут содержать данные в виде полей (часто называемых атрибутами или свойствами) и код в виде процедур (часто называемых методами). ООП фокусируется на использовании объектов для моделирования реального мира (или абстракций), облегчая разработку и поддержку сложных программ. Существует четыре основных принципа: 🟠Инкапсуляция Механизм ООП, который объединяет данные (атрибуты) и код (методы), манипулирующий этими данными, внутри одного объекта и скрывает детали реализации от внешнего использования. Это позволяет защитить внутреннее состояние объекта от прямого доступа извне и обеспечить контролируемый интерфейс для работы с этим объектом. 🟠Наследование Позволяет создавать новый класс на основе уже существующего класса, перенимая его свойства и методы. Новый класс может добавлять собственные свойства и методы или модифицировать унаследованные. Наследование обеспечивает повторное использование кода, упрощает его расширение и поддержку. 🟠Полиморфизм Способность объектов с одинаковым интерфейсом предоставлять различную реализацию для одного и того же метода. Это означает, что функция или метод могут использоваться для различных типов объектов, и каждый тип может реализовать эту функцию или метод по-своему. Полиморфизм упрощает написание общего кода для работы с объектами разных классов и обеспечивает гибкость в его использовании. 🟠Абстракция Позволяет скрыть сложность системы, представляя её ключевые аспекты и скрывая детали реализации. Это достигается за счёт использования абстрактных классов и интерфейсов, которые определяют шаблон для классов-наследников. Абстракция помогает сосредоточиться на взаимодействии объектов на более высоком уровне, игнорируя ненужные детали. Ставь 👍 и забирай 📚 Базу знаний
201
6
🤔 Что означают IBOutlet и IBAction, для чего они нужны, и что значат для препроцессора? - IBOutlet – указывает, что свойство связано с элементом интерфейса (Storyboard/XIB). - IBAction – указывает, что метод вызывается при взаимодействии пользователя (например, нажатие кнопки). Оба являются атрибутами (@property в Objective-C, аннотациями в Swift), но игнорируются препроцессором и служат только для связи с Interface Builder. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
201
7
🤔 Какие плюсы и минусы layout'а? Каждый способ создания макетов (layout'а) в iOS-разработке имеет свои преимущества и недостатки. 🚩Interface Builder (IB) ➕Визуальное редактирование Удобный графический интерфейс для быстрой настройки и визуального просмотра изменений. ➕Интеграция с Auto Layout Простая настройка ограничений (constraints) для адаптивного интерфейса. ➕Быстрое прототипирование Возможность быстрого создания и изменения макетов без написания кода. ➖Меньшая гибкость Ограниченные возможности для создания сложных и динамических макетов. ➖Конфликты при совместной работе Трудности при слиянии изменений в storyboard или xib файлах в больших командах. ➖Производительность Более медленное время загрузки по сравнению с программными подходами. 🚩Auto Layout ➕Адаптивность Поддержка различных устройств и ориентаций экрана. ➕Мощные инструменты Возможность создания сложных и адаптивных макетов с помощью ограничений. ➕Интеграция с Interface Builder Упрощенная настройка ограничений через визуальный интерфейс. ➖Крутая кривая обучения Может быть сложно освоить, особенно для новичков. ➖Управление сложными макетами Требует тщательного планирования и может стать сложным при работе с большим количеством ограничений. 🚩Programmatic Layout ➕Полный контроль Возможность точной настройки макета с помощью кода. ➕Гибкость Легкость создания динамических и условных макетов. ➕Управление версиями Легче управлять изменениями в коде по сравнению с визуальными файлами. ➖Большая трудоемкость Требует больше времени и усилий для настройки, особенно для сложных макетов. ➖Меньшая наглядность Отсутствие визуального редактора может затруднить представление конечного результата. 🚩Stack Views ➕Упрощение макетов Легкость создания и управления сложными макетами с минимальными усилиями. ➕Интеграция с Auto Layout Автоматическое управление ограничениями для вложенных элементов. ➕Адаптивность Поддержка различных ориентаций и размеров экранов. ➖Ограниченная гибкость Менее гибкие по сравнению с чистым Auto Layout или программными подходами. ➖Поддержка Не всегда подходят для всех типов макетов, особенно для более сложных компоновок. 🚩SwiftUI ➕Декларативный синтаксис Простота и понятность кода благодаря декларативному подходу. ➕Превью в реальном времени Мгновенное обновление интерфейса при изменении кода. ➕Интеграция с Swift Современные возможности языка и тесная интеграция с экосистемой Apple. ➕Кроссплатформенность Поддержка различных платформ (iOS, macOS, watchOS, tvOS). ➖Требования к версии iOS Поддержка только iOS 13 и выше, что может ограничить использование на старых устройствах. ➖Зрелость фреймворка Некоторые функции еще находятся в стадии разработки, и могут быть ограничены возможности по сравнению с UIKit. Ставь 👍 и забирай 📚 Базу знаний
204
8
🤔 Что такое Notification Service Extension? Это расширение для iOS-приложений, которое позволяет модифицировать push-уведомления до их показа. Например, можно добавить изображение, вложение или изменить текст перед отображением пользователю. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
191
9
🤔 Что может быть ключом и значением для dictionary? Словарь (Dictionary) представляет собой коллекцию пар ключ-значение, где каждый ключ должен быть уникальным. Чтобы использовать какой-либо тип в качестве ключа словаря, этот тип должен соответствовать протоколу Hashable. Это требование обусловлено тем, что Swift использует хеш-таблицу для хранения элементов словаря, что обеспечивает быстрый доступ к его элементам. 🚩Ключи Должны быть уникальными: Каждый ключ в словаре должен быть уникальным. При попытке добавить в словарь элемент с ключом, который уже существует в словаре, старое значение будет заменено на новое. Должны соответствовать протоколу Hashable: Это означает, что тип ключа должен иметь способность быть правильно хешированным. Большинство базовых типов Swift (например, String, Int, Double и др.) уже соответствуют Hashable, поэтому их можно использовать в качестве ключей без дополнительных усилий. 🚩Значения Могут быть любого типа: Значения в словаре могут быть любого типа, и они не обязаны соответствовать протоколу Hashable. Могут повторяться: Разные ключи могут иметь одинаковые значения. var personAge: [String: Int] = ["John": 30, "Sara": 25] 🚩Собственные типы в качестве ключей Вы также можете использовать собственные пользовательские типы в качестве ключей словаря, но для этого ваш тип должен соответствовать протоколу Hashable. Это включает в себя реализацию требуемых методов для сравнения на равенство (==) и хеширования (hash(into:)). struct Person: Hashable { var name: String var id: Int } var peopleDictionary: [Person: String] = [Person(name: "John", id: 1): "Engineer"] Ставь 👍 и забирай 📚 Базу знаний
217
10
🤔 Что лучше: closures или delegate? Зависит от ситуации. Делегаты лучше для долгоживущих однонаправленных связей (например, между контроллером и вью). Замыкания — для кратковременных, локальных задач (например, сетевые запросы, анимации). Делегаты лучше масштабируются, замыкания — лаконичнее. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
226
11
🤔 Расскажи про две семантики в swift'е В Swift все типы данных делятся на два вида по семантике хранения и передачи: 🚩Значимая семантика (Value Semantics) Структуры (struct), перечисления (enum) и кортежи (tuple) передаются по значению, то есть каждое присваивание создаёт копию объекта. struct User { var name: String } var user1 = User(name: "Alice") var user2 = user1 // Копия! user2.name = "Bob" print(user1.name) // "Alice" (НЕ изменилось) print(user2.name) // "Bob" 🚩Ссылочная семантика (Reference Semantics) Классы (class), акторы (actor) и замыкания (closure) передаются по ссылке, то есть несколько переменных могут ссылаться на один и тот же объект. class User { var name: String init(name: String) { self.name = name } } var user1 = User(name: "Alice") var user2 = user1 // Передача ссылки! user2.name = "Bob" print(user1.name) // "Bob" (ИЗМЕНИЛОСЬ!) print(user2.name) // "Bob" Ставь 👍 и забирай 📚 Базу знаний
237
12
🤔 Что будет, если убрать опционал? 1. Удаление опционалов лишит язык возможности безопасно работать с отсутствием значений. 2. Программистам придётся вручную проверять наличие значений, что повысит вероятность ошибок и крашей. 3. Опционалы делают код более безопасным и читаемым, позволяя явно выражать ситуацию, когда значение может отсутствовать. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
199
13
🤔 Какие есть фрейм ворк механизмы в айос для выполненной бэкраунд задач? В iOS для выполнения фоновых задач существуют несколько ключевых механизмов: 🚩Основные механизмы 🟠Grand Central Dispatch (GCD): Используется для асинхронного выполнения задач на глобальных или пользовательских очередях. DispatchQueue.global(qos: .background).async { // Фоновая задача } 🟠OperationQueue: Высокоуровневый API для управления очередями операций с возможностью указания зависимостей. let queue = OperationQueue() queue.addOperation { // Фоновая операция } 🟠Background Fetch: Позволяет приложению периодически загружать новые данные в фоновом режиме. func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // Фоновое обновление данных completionHandler(.newData) } 🟠BGTaskScheduler: Новый фреймворк для планирования и выполнения фоновых задач. import BackgroundTasks func scheduleBackgroundTask() { let request = BGAppRefreshTaskRequest(identifier: "com.example.app.refresh") request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) try? BGTaskScheduler.shared.submit(request) } 🟠URLSession Background Transfers: Выполнение загрузки и выгрузки данных в фоновом режиме. let configuration = URLSessionConfiguration.background(withIdentifier: "com.example.app.background") let session = URLSession(configuration: configuration) let url = URL(string: "https://example.com/largefile")! let task = session.downloadTask(with: url) task.resume() Ставь 👍 и забирай 📚 Базу знаний
215
14
🤔 Чем отличается set от dictionary? Set хранит уникальные элементы без порядка, а Dictionary — пары ключ-значение, где ключи уникальны. Set быстрее для операций проверки принадлежности и поиска. Dictionary удобен для поиска по ключу и хранения дополнительных данных для каждого ключа. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
204
15
🤔 Что будет, если открыть несколько экранов и сделать dismiss последнего? Когда вы открываете несколько экранов (UIViewController) в iOS, они обычно создают стек представлений (View Controller Stack). В зависимости от способа открытия экранов (модально или через навигационный стек), поведение dismiss будет разным. 🚩Модальное представление (`present`) Если экраны открывались модально (present), то dismiss на последнем экране просто закроет только этот экран, и управление вернётся к предыдущему. let newVC = UIViewController() present(newVC, animated: true) Позже вызываем: dismiss(animated: true) Если вызвать dismiss на первом модально представленном контроллере, все последующие модальные контроллеры закроются сразу. // Открываем два экрана последовательно let vc1 = UIViewController() let vc2 = UIViewController() present(vc1, animated: true) vc1.present(vc2, animated: true) Если вызвать dismiss на vc2: vc2.dismiss(animated: true) Если вызвать dismiss на vc1: vc1.dismiss(animated: true) 🚩Навигационный стек (`push`) Если экраны открывались через UINavigationController (pushViewController), то dismiss не работает для удаления последнего экрана. Нужно использовать popViewController. let vc1 = UIViewController() let vc2 = UIViewController() navigationController?.pushViewController(vc1, animated: true) navigationController?.pushViewController(vc2, animated: true) Теперь если мы вызовем: vc2.dismiss(animated: true) Правильный способ закрытия последнего экрана в UINavigationController: navigationController?.popViewController(animated: true) Если вы хотите закрыть весь стек экранов, используйте: navigationController?.popToRootViewController(animated: true) Ставь 👍 и забирай 📚 Базу знаний
219
16
🤔 Что происходит в системе, когда мы тапаем по экрану? Когда пользователь касается экрана, происходит следующий процесс: 1. Аппаратный слой (дисплей) фиксирует касание и передаёт его в iOS. 2. Система генерирует объект события (UIEvent, UITouch). 3. Событие передаётся в главное окно (UIWindow) и далее — вью-контроллерам и иерархии UIView. 4. Система запускает hit-testing — определяет, какая вьюшка находится под точкой касания. 5. Вызываются методы: - hitTest(_:with:) — определяет целевую вью. - touchesBegan(_:with:), touchesMoved, touchesEnded — передают событие в конкретную вью. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
217
17
🤔 Что из себя представляет структура данных stack? Stack (стек) – это структура данных, работающая по принципу LIFO (Last In, First Out – "последним пришел, первым ушел"). 🚩Пример реализации стека в Swift В Swift нет встроенного стека (кроме Array), но можно создать свой: struct Stack<T> { private var elements: [T] = [] mutating func push(_ item: T) { elements.append(item) } mutating func pop() -> T? { return elements.popLast() // Удаляет и возвращает верхний элемент } func peek() -> T? { return elements.last // Возвращает верхний элемент без удаления } func isEmpty() -> Bool { return elements.isEmpty } } // Пример использования: var stack = Stack<Int>() stack.push(10) stack.push(20) stack.push(30) print(stack.pop()!) // 30 print(stack.peek()!) // 20 print(stack.isEmpty()) // false 🚩Где используется стек? Обратный порядок выполнения (рекурсия) – стек вызовов функций. Алгоритмы (обратная польская нотация, DFS – поиск в глубину) История действий (назад-вперед в браузере, отмена в редакторе). Ставь 👍 и забирай 📚 Базу знаний
238
18
🤔 Как увеличить область нажатия на кнопку? Чтобы увеличить зону клика UIButton: 1. Создать кастомную кнопку и переопределить point(inside:with:) 2. Либо обернуть кнопку в UIView с большим frame, но маленькой кнопкой внутри. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
235
19
🤔 Какие изменения надо сделать в constrait перед вызовом layout? Перед вызовом layoutIfNeeded() или layoutSubviews() в iOS-приложении, нужно изменить значение констрейнта и вызвать анимацию, если необходимо. Вот основные шаги: 🟠Обновление значения констрейнта Перед вызовом layoutIfNeeded(), измените свойство констрейнта (например, constant у NSLayoutConstraint). class ViewController: UIViewController { @IBOutlet weak var button: UIButton! @IBOutlet weak var heightConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.changeButtonHeight() } } func changeButtonHeight() { heightConstraint.constant = 100 // Меняем значение констрейнта UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() // Перестраиваем макет } } } 🟠Если меняется набор констрейнтов Если нужно удалить/добавить констрейнты, используйте `activate()` / `deactivate()`. var expanded = false @IBOutlet weak var smallHeightConstraint: NSLayoutConstraint! @IBOutlet weak var largeHeightConstraint: NSLayoutConstraint! func toggleHeight() { expanded.toggle() if expanded { NSLayoutConstraint.deactivate([smallHeightConstraint]) NSLayoutConstraint.activate([largeHeightConstraint]) } else { NSLayoutConstraint.deactivate([largeHeightConstraint]) NSLayoutConstraint.activate([smallHeightConstraint]) } UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } } 🟠Если работа идёт в `viewDidLoad()` Во viewDidLoad() элементы ещё не отрисованы, поэтому layoutIfNeeded() не сработает. Используйте viewDidAppear() или вызовите layoutIfNeeded() после view.layoutIfNeeded(). override func viewDidLoad() { super.viewDidLoad() heightConstraint.constant = 100 view.layoutIfNeeded() // НЕ обновит макет, потому что он ещё не загружен } Решение override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) heightConstraint.constant = 100 UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } } Разница между layoutIfNeeded() и setNeedsLayout() heightConstraint.constant = 100 view.setNeedsLayout() // Обновление произойдет на следующем цикле рендера Ставь 👍 и забирай 📚 Базу знаний
240
20
🤔 Как поменять иконку приложения в зависимости от среды? Для этого используют App Icon Sets, и в Info.plist можно указать набор иконок в зависимости от build-конфигурации. В Xcode можно также использовать xcconfig или Build Scheme, чтобы переключать иконки по окружению. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
216