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

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

Ir al canal en Telegram

Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads

Mostrar más
2 164
Suscriptores
+224 horas
+47 días
-330 días
Atraer Suscriptores
oct '26
octubre '26
+8
en 0 canales
septiembre '26
+22
en 0 canales
Get PRO
agosto '26
+25
en 0 canales
Get PRO
julio '26
+18
en 0 canales
Get PRO
junio '26
+32
en 1 canales
Get PRO
mayo '26
+21
en 0 canales
Get PRO
abril '26
+23
en 0 canales
Get PRO
marzo '26
+35
en 0 canales
Get PRO
febrero '26
+45
en 1 canales
Get PRO
enero '26
+58
en 0 canales
Get PRO
diciembre '25
+28
en 0 canales
Get PRO
noviembre '25
+156
en 1 canales
Get PRO
octubre '25
+26
en 0 canales
Get PRO
septiembre '25
+41
en 0 canales
Get PRO
agosto '25
+38
en 0 canales
Get PRO
julio '25
+27
en 0 canales
Get PRO
junio '25
+34
en 0 canales
Get PRO
mayo '25
+50
en 0 canales
Get PRO
abril '25
+87
en 0 canales
Get PRO
marzo '25
+151
en 2 canales
Get PRO
febrero '25
+123
en 1 canales
Get PRO
enero '25
+127
en 53 canales
Get PRO
diciembre '24
+55
en 1 canales
Get PRO
noviembre '24
+75
en 0 canales
Get PRO
octubre '24
+193
en 42 canales
Get PRO
septiembre '24
+348
en 251 canales
Get PRO
agosto '24
+98
en 0 canales
Get PRO
julio '24
+140
en 54 canales
Get PRO
junio '24
+411
en 244 canales
Get PRO
mayo '24
+646
en 191 canales
Get PRO
abril '24
+353
en 23 canales
Fecha
Crecimiento de Suscriptores
Menciones
Canales
06 octubre0
05 octubre+3
04 octubre0
03 octubre+2
02 octubre+1
01 octubre+2
Publicaciones del Canal
🤔 Что такое замыкание? Замыкание (closure) — это блок кода, который можно передать и выполнить позже. Оно может захватывать значения из окружающего контекста. Аналог лямбда-функций и функциональных выражений. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

2
🤔 Что нужно сделать, чтобы кастомная структура стала ключом в dictionary? В Swift ключи в словаре (Dictionary) должны быть уникальными и сравниваться между собой. Поэтому, если вы хотите использовать*свою структуру в качестве ключа, она должна соответствовать протоколу Hashable. 🚩Что нужно? Структура должна соответствовать Hashable Должен быть реализован hash(into:) или использовать Equatable + Hashable автоматически Свойства структуры должны быть Hashable (если String, Int, Double – все ок) 🚩Пример кастомной структуры в `Dictionary` struct Person: Hashable { let id: Int let name: String } // Теперь можно использовать `Person` как ключ var peopleAges: [Person: Int] = [ Person(id: 1, name: "Alice"): 25, Person(id: 2, name: "Bob"): 30 ] // Доступ по ключу let alice = Person(id: 1, name: "Alice") print(peopleAges[alice] ?? "Не найдено") // 25 🚩Ручная реализация `hash(into:)` Если нужно кастомное хеширование, можно реализовать hash(into:): struct Person: Hashable { let id: Int let name: String func hash(into hasher: inout Hasher) { hasher.combine(id) // Используем только id для хеша } } Ставь 👍 и забирай 📚 Базу знаний
127
3
🤔 Какой есть механизм для показа экрана? Обычно используются: - pushViewController (в UINavigationController); - present(_:animated:) — для модального показа; - В SwiftUI — NavigationStack, .sheet, .fullScreenCover. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
165
4
🤔 Что такое notification центр? Это механизм в iOS и macOS для обмена сообщениями между различными частями приложения. Он позволяет объектам отправлять и получать уведомления без необходимости напрямую ссылаться друг на друга, что способствует более гибкому и модульному дизайну. 🚩Основные аспекты 🟠Отправка уведомлений Любой объект может отправить уведомление с помощью Notification Center. Уведомления идентифицируются по имени (Notification.Name). Можно передать дополнительную информацию в виде словаря (userInfo). NotificationCenter.default.post(name: .myNotification, object: nil) 🟠Получение уведомлений Объекты могут регистрироваться для получения уведомлений с определенным именем. Для обработки уведомлений используется метод, который будет вызван при получении уведомления. NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: .myNotification, object: nil) @objc func handleNotification(notification: Notification) { print("Received notification") } 🟠Удаление наблюдателей Важно удалять наблюдателей, когда они больше не нужны, чтобы избежать утечек памяти. Обычно это делается в методе deinit или перед уничтожением объекта. NotificationCenter.default.removeObserver(self, name: .myNotification, object: nil) 🚩Плюсы ➕Слабая связанность Объекты не нужно напрямую ссылаться друг на друга, что улучшает модульность кода. ➕Гибкость Позволяет легко организовать обмен сообщениями между различными частями приложения. ➕Повторное использование Уведомления могут использоваться многими объектами, что облегчает реализацию функций, таких как обновление интерфейса или реагирование на события. 🚩Примеры использования 1⃣Обновление интерфейса Когда данные изменяются, можно отправить уведомление для обновления пользовательского интерфейса. NotificationCenter.default.post(name: .dataDidUpdate, object: nil) 2⃣Реакция на системные события Например, можно подписаться на уведомление о смене состояния сети. NotificationCenter.default.addObserver(self, selector: #selector(handleNetworkChange), name: .reachabilityChanged, object: nil) 3⃣Межмодульное взаимодействие Различные модули приложения могут общаться друг с другом через Notification Center, не создавая сильных зависимостей. NotificationCenter.default.post(name: .userDidLogin, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(updateUI), name: .userDidLogin, object: nil) Ставь 👍 и забирай 📚 Базу знаний
186
5
🤔 Как устроено наследование в Swift? Наследование в Swift позволяет классу (подклассу) унаследовать свойства, методы и инициализаторы от другого класса (суперкласса). Подклассы могут переопределять (override) поведение суперкласса, добавлять новые свойства и методы, но не могут наследовать структуры, перечисления или протоколы. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
178
6
🤔 Расскажи про кодирование и декодирование в user defaults UserDefaults — это хранилище для сохранения простых данных (строки, числа, массивы). Но если нужно сохранить сложные объекты, их сначала кодируют в `Data` (Codable), а затем сохраняют. 🟠Сохранение и загрузка простых данных Для примитивных типов (строки, числа, массивы, словари) UserDefaults работает без кодирования: let defaults = UserDefaults.standard // Сохранение defaults.set("Иван", forKey: "username") defaults.set(25, forKey: "age") // Чтение let name = defaults.string(forKey: "username") ?? "Нет имени" let age = defaults.integer(forKey: "age") print(name, age) // Иван 25 🟠Сохранение сложных объектов (Codable) Если нужно сохранить свой объект, сначала его нужно закодировать в Data. struct User: Codable { let name: String let age: Int } Сохранение в UserDefaults let user = User(name: "Иван", age: 25) let defaults = UserDefaults.standard if let encoded = try? JSONEncoder().encode(user) { defaults.set(encoded, forKey: "user") } Загрузка из UserDefaults if let savedData = defaults.data(forKey: "user"), let savedUser = try? JSONDecoder().decode(User.self, from: savedData) { print(savedUser.name, savedUser.age) // Иван 25 } 🟠Удаление данных из `UserDefaults` Чтобы удалить ключ: defaults.removeObject(forKey: "user") 🟠Сохранение массива объектов Можно сохранить массив объектов, просто закодировав его: let users = [ User(name: "Иван", age: 25), User(name: "Анна", age: 30) ] if let encoded = try? JSONEncoder().encode(users) { defaults.set(encoded, forKey: "users") } // Читаем массив обратно if let savedData = defaults.data(forKey: "users"), let savedUsers = try? JSONDecoder().decode([User].self, from: savedData) { print(savedUsers) // [{name: Иван, age: 25}, {name: Анна, age: 30}] } Ставь 👍 и забирай 📚 Базу знаний
179
7
🤔 Что знаешь про capture list? Capture list используется в замыканиях Swift, чтобы управлять тем, как значения захватываются: как weak, unowned или strong. Это предотвращает retain cycle и утечки. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
177
8
🤔 Как устроено наследование? Это ключевой механизм ООП, позволяющий классам наследовать свойства, методы и другие характеристики от других классов. Это позволяет создавать новые классы на основе существующих, расширяя их функциональность или изменяя её. 🚩Основы наследования 🟠Определение базового класса Базовый класс определяет общие свойства и методы, которые могут быть унаследованы подклассами. 🟠Создание подкласса Подкласс наследует (или "расширяет") базовый класс. Он может переопределять унаследованные методы и свойства, добавлять новые методы и свойства, а также добавлять инициализаторы или изменять существующие. 🟠Переопределение методов и свойств Подклассы могут переопределять методы, свойства и индексаторы базового класса для изменения или расширения их поведения. 🟠Предотвращение переопределения Можно предотвратить переопределение методов, свойств или индексаторов с помощью ключевого слова final. Если метод, свойство или индексатор объявлен как final, то он не может быть переопределён в подклассе. class Vehicle { var currentSpeed = 0.0 var description: String { return "traveling at \(currentSpeed) miles per hour" } func makeNoise() { // Этот метод будет переопределен в подклассах, если необходимо } } class Bicycle: Vehicle { var hasBasket = false } class Car: Vehicle { var gear = 1 final func drive() { print("Car is moving") } override func makeNoise() { print("Vroom!") } } 🚩Использование super Подклассы могут вызывать методы своего суперкласса с помощью ключевого слова super. Это позволяет подклассам расширять, а не заменять поведение суперкласса. Ставь 👍 и забирай 📚 Базу знаний
197
9
🤔 На какой механизм Swift похож associatedtype? associatedtype — это аналог дженериков, но на уровне протоколов. Он позволяет абстрагировать конкретный тип и использовать его позже в реализации, сохраняя гибкость и строгость типизации. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
191
10
🤔 Как отлавливать, где допущена ошибка в свифте? В Swift есть несколько способов отлавливать и диагностировать ошибки в коде: 🚩Обработка ошибок через `do-catch` Используется, если функция генерирует ошибку (throws). enum LoginError: Error { case wrongPassword case userNotFound } func login(user: String, password: String) throws { if user != "admin" { throw LoginError.userNotFound } if password != "1234" { throw LoginError.wrongPassword } } do { try login(user: "admin", password: "wrong") } catch LoginError.wrongPassword { print("Ошибка: Неверный пароль") } catch { print("Ошибка: \(error)") } 🚩`assert()`, `precondition()`, `fatalError()` (для отладки) Эти функции прерывают выполнение программы, если что-то пошло не так. assert() (только в Debug) let age = -5 assert(age >= 0, "Возраст не может быть отрицательным") precondition() (работает в Release) precondition(age >= 0, "Возраст не может быть отрицательным") fatalError() (прерывает программу) func getData() -> String { fatalError("Метод ещё не реализован") } Ставь 👍 и забирай 📚 Базу знаний
217
11
🤔 Что такое Notification Center? Это механизм публикации и подписки на события в iOS. - Позволяет компонентам приложения обмениваться данными без прямых ссылок. - Работает по принципу наблюдателя: объект отправляет уведомление, а подписчики получают его. - Используется для глобального взаимодействия между модулями (например, обновление UI после фоновой загрузки данных). Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
199
12
🤔 Как бы реализовал словарь в Swift при помощи массива? В Swift словарь (Dictionary) представляет собой структуру данных, которая хранит пары ключ-значение и обеспечивает быстрый доступ к значениям по ключу (O(1) в среднем). Но если бы мы хотели реализовать словарь на основе массива, то пришлось бы использовать линейный поиск, что делает операции менее эффективными (O(n)). 🚩Реализация словаря через массив кортежей Один из простых способов создать словарь на базе массива — использовать массив кортежей (ключ, значение). struct ArrayDictionary<Key: Equatable, Value> { private var items: [(Key, Value)] = [] // Храним пары ключ-значение // Получение значения по ключу func value(for key: Key) -> Value? { for (k, v) in items { if k == key { return v } } return nil } // Добавление или обновление значения mutating func insert(value: Value, for key: Key) { for i in 0..<items.count { if items[i].0 == key { items[i].1 = value // Обновляем значение, если ключ уже есть return } } items.append((key, value)) // Добавляем новую пару } // Удаление элемента по ключу mutating func remove(for key: Key) { items.removeAll { $0.0 == key } } } // Пример использования var myDict = ArrayDictionary<String, Int>() myDict.insert(value: 42, for: "age") myDict.insert(value: 30, for: "height") print(myDict.value(for: "age")!) // 42 myDict.remove(for: "age") print(myDict.value(for: "age")) // nil 🚩Оптимизация: Использование бинарного поиска Если мы отсортируем массив по ключам, можно использовать бинарный поиск (O(log n)) для ускорения поиска ключа. struct SortedArrayDictionary<Key: Comparable, Value> { private var items: [(Key, Value)] = [] // Бинарный поиск индекса ключа private func index(of key: Key) -> Int? { var left = 0 var right = items.count - 1 while left <= right { let mid = (left + right) / 2 if items[mid].0 == key { return mid } else if items[mid].0 < key { left = mid + 1 } else { right = mid - 1 } } return nil } // Получение значения по ключу func value(for key: Key) -> Value? { if let index = index(of: key) { return items[index].1 } return nil } // Вставка с сохранением сортировки mutating func insert(value: Value, for key: Key) { if let index = index(of: key) { items[index].1 = value } else { items.append((key, value)) items.sort { $0.0 < $1.0 } // Сортируем после вставки } } } // Использование var sortedDict = SortedArrayDictionary<String, Int>() sortedDict.insert(value: 50, for: "b") sortedDict.insert(value: 20, for: "a") sortedDict.insert(value: 70, for: "c") print(sortedDict.value(for: "b")!) // 50 Ставь 👍 и забирай 📚 Базу знаний
205
13
🤔 Где хранятся ссылочные типы и типы, которые хранятся по значению? Ссылочные типы (class) хранятся в куче (heap), а переменные содержат ссылки на них. Значимые типы (struct, enum) хранятся в стеке, если не вложены в ссылочные, и копируются при передаче. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
204
14
🤔 Для каких сущностей работает copy on write? Механизм Copy-on-Write (CoW) используется для оптимизации производительности и использования памяти при копировании объектов. Этот механизм особенно полезен для неизменяемых (immutable) структур данных. CoW часто ассоциируется со стандартными коллекциями и собственными типами данных, реализованными как структуры (value types), такие как Array, String, Dictionary, и Set. 🚩Принцип работы Copy-on-Write Работает так, что копия объекта создаётся только в тот момент, когда происходит попытка модификации. До этого момента все копии объекта фактически ссылаются на одни и те же данные в памяти. Это позволяет сэкономить как время, так и память, поскольку избегается ненужное дублирование данных, когда оно не требуется. 🚩Как это работает в Swift Автоматически применяет механизм CoW к своим стандартным коллекциям, таким как Array, String, Dictionary, и Set. Это означает, что при передаче этих объектов в функции или при их копировании реальное дублирование данных происходит только в случае модификации одной из копий. Таким образом, если вы создаёте копию массива и не изменяете его, обе переменные будут указывать на одни и те же данные в памяти. Как только вы модифицируете одну из копий, Swift создаст реальную копию данных для этой копии, обеспечивая независимость данных между оригиналом и копией. var originalArray = [1, 2, 3] var copiedArray = originalArray // На этом этапе данные не дублируются copiedArray.append(4) // Теперь данные копируются, потому что copiedArray модифицируется Ставь 👍 и забирай 📚 Базу знаний
227
15
🤔 Что такое Actor? Это концепция, обеспечивающая безопасность при работе с многопоточностью. Он изолирует доступ к своим данным, гарантируя, что только один поток может обращаться к данным в любой момент. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
221
16
🤔 Зачем нужны свойства "Content Hugging Priority"? Свойства "Content Hugging Priority" и "Content Compression Resistance Priority" играют ключевую роль в системе Auto Layout. Эти свойства помогают определить, как вьюшки (views) должны быть отформатированы и как они реагируют на изменения в доступном пространстве в интерфейсе пользователя. Рассмотрим подробнее, что означает каждое из этих свойств и как они используются в разработке интерфейсов. 🚩Content Hugging Priority Определяет, насколько сильно вьюшка должна "обнимать" своё содержимое. Это свойство указывает на желательность вьюшки быть как можно ближе к своим внутренним размерам, основанным на своем содержимом. 🚩Content Compression Resistance Priority Определяет, насколько сильно вьюшка должна противостоять сжатию размеров меньше, чем размеры её содержимого. Ставь 👍 и забирай 📚 Базу знаний
243
17
🤔 Что известно про механизм отмены в Operation? Operation поддерживает isCancelled, cancel(), и встроенные состояния. Это позволяет создавать отменяемые, приостанавливаемые и последовательные операции. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
227
18
🤔 Какие знаешь способы внедрения зависимостей? Внедрение зависимостей (Dependency Injection, DI) в iOS-приложениях позволяет сделать код более модульным, тестируемым и поддерживаемым. Рассмотрим основные способы внедрения зависимостей в Swift. 🟠Внедрение через инициализатор (Initializer Injection) Это самый распространенный и рекомендуемый способ. Зависимости передаются в объект через его инициализатор. protocol NetworkServiceProtocol { func fetchData() } class NetworkService: NetworkServiceProtocol { func fetchData() { print("Данные загружены") } } // Класс, которому нужна зависимость class ViewModel { private let networkService: NetworkServiceProtocol init(networkService: NetworkServiceProtocol) { self.networkService = networkService } func loadData() { networkService.fetchData() } } // Использование let networkService = NetworkService() let viewModel = ViewModel(networkService: networkService) viewModel.loadData() 🟠Внедрение через свойства (Property Injection) Зависимость передается через свойство класса. class ViewModel { var networkService: NetworkServiceProtocol? func loadData() { networkService?.fetchData() } } // Использование let viewModel = ViewModel() viewModel.networkService = NetworkService() viewModel.loadData() 🟠Внедрение через метод (Method Injection) Зависимость передается непосредственно в метод, который её использует. class ViewModel { func loadData(with networkService: NetworkServiceProtocol) { networkService.fetchData() } } // Использование let viewModel = ViewModel() let networkService = NetworkService() viewModel.loadData(with: networkService) 🟠Использование Service Locator (Антипаттерн) Класс сам запрашивает зависимость у глобального локатора. class ServiceLocator { static let shared = ServiceLocator() private var services: [String: Any] = [:] func register<T>(_ service: T) { let key = String(describing: T.self) services[key] = service } func resolve<T>() -> T? { let key = String(describing: T.self) return services[key] as? T } } // Регистрация зависимостей let locator = ServiceLocator.shared locator.register(NetworkService() as NetworkServiceProtocol) // Использование class ViewModel { func loadData() { let networkService: NetworkServiceProtocol? = ServiceLocator.shared.resolve() networkService?.fetchData() } } 🟠Использование DI-контейнеров (например, Swinject) Специальные библиотеки помогают управлять зависимостями. import Swinject let container = Container() container.register(NetworkServiceProtocol.self) { _ in NetworkService() } class ViewModel { private let networkService: NetworkServiceProtocol init(networkService: NetworkServiceProtocol) { self.networkService = networkService } func loadData() { networkService.fetchData() } } // Разрешение зависимости через контейнер let networkService = container.resolve(NetworkServiceProtocol.self)! let viewModel = ViewModel(networkService: networkService) viewModel.loadData() Ставь 👍 и забирай 📚 Базу знаний
230
19
🤔 Как можно предотвратить цикл Retain Cycle? Использовать слабые (weak) или безвладельные (unowned) ссылки в замыканиях и свойствах между объектами, особенно когда один объект владеет другим, и наоборот. Также помогает осознание, кто должен владеть кем и соблюдение архитектурных границ. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
207
20
🤔 Где могут располагаться стеки помимо структуры В программировании стек (stack) — это структура данных и область памяти, используемая для хранения временных данных. В зависимости от контекста, стек может существовать в нескольких местах. 🟠Стек вызовов (Call Stack) Это главная область памяти в оперативной памяти (RAM), где хранятся: - Локальные переменные функций. - Адреса возврата после завершения функции. - Контекст выполнения программы. func functionA() { functionB() } func functionB() { print("Вызов B") } functionA() func infiniteRecursion() { infiniteRecursion() // ❌ Бесконечный вызов } 🟠Стек в структуре данных (например, `Array`) В Swift можно реализовать стек вручную, используя массив (Array). struct Stack<T> { private var elements: [T] = [] mutating func push(_ item: T) { elements.append(item) } mutating func pop() -> T? { return elements.popLast() } } var stack = Stack<Int>() stack.push(10) stack.push(20) print(stack.pop()!) // 20 🟠Потоковый стек (Thread Stack) Каждый поток (Thread) в многопоточном программировании получает свой стек. DispatchQueue.global().async { print("Фоновый поток") } print("Главный поток") 🟠Стек в автоматическом управлении памятью (ARC) Swift использует Automatic Reference Counting (ARC) для управления памятью. Когда объект больше не нужен, он удаляется из памяти (в том числе из стека). func createPerson() { let person = "Иван" // Создаётся в стеке print(person) } createPerson() // Переменная person удаляется при выходе из функции Ставь 👍 и забирай 📚 Базу знаний
230