Swift | Вопросы собесов
Ir al canal en Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
Mostrar más2 164
Suscriptores
+224 horas
+47 días
-330 días
Carga de datos en curso...
Canales Similares
Nube de Etiquetas
Menciones Entrantes y Salientes
---
---
---
---
---
---
Atraer Suscriptores
octubre '26oct '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 octubre | 0 | |||
| 05 octubre | +3 | |||
| 04 octubre | 0 | |||
| 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 |
