fa
Feedback

فریب کلاهبرداران را نخورید! تل‌متریو این کانال‌ها را شناسایی و برچسب‌گذاری می‌کند 👉 برای مشاهده برچسب، اشتراک تهیه کنید

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

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

رفتن به کانال در Telegram

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

نمایش بیشتر
2 141
مشترکین
-124 ساعت
-77 روز
-1830 روز
جذب مشترکین
اکتبر '26
اکتبر '26
+20
در 0 کانال‌ها
سپتامبر '26
+22
در 0 کانال‌ها
Get PRO
اوت '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 کانال‌ها
تاریخ
رشد مشترکین
اشارات
کانال‌ها
26 اکتبر0
25 اکتبر0
24 اکتبر0
23 اکتبر+1
22 اکتبر0
21 اکتبر+4
20 اکتبر0
19 اکتبر+1
18 اکتبر0
17 اکتبر+1
16 اکتبر0
15 اکتبر0
14 اکتبر0
13 اکتبر+1
12 اکتبر0
11 اکتبر+1
10 اکتبر+2
09 اکتبر0
08 اکتبر+1
07 اکتبر0
06 اکتبر0
05 اکتبر+3
04 اکتبر0
03 اکتبر+2
02 اکتبر+1
01 اکتبر+2
پست‌های کانال
🤔 Преимущества использования guard let? - Повышает читаемость кода: избавляет от вложенности. - Подходит для валидации входных данных в начале метода. - Позволяет сразу «отсеять» невалидные значения и продолжить выполнение с уверенностью, что данные корректны. - Используется во многих API Apple как рекомендуемый способ проверки условий. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

2
🤔 Какие есть инструменты для работы с потоками? В Swift есть несколько инструментов для работы с многопоточностью и параллельным выполнением кода. Вот основные из них: 🟠GCD (Grand Central Dispatch) – главный инструмент для потоков GCD – это низкоуровневая технология, позволяющая управлять задачами (тасками) в очередях (DispatchQueue). DispatchQueue.global(qos: .background).async { print("Фоновый поток") DispatchQueue.main.async { print("Вернулись в главный поток") } } 🟠OperationQueue – более удобный API для задач OperationQueue – это более гибкая и объектно-ориентированная альтернатива GCD. let queue = OperationQueue() queue.maxConcurrentOperationCount = 2 // Ограничение на 2 задачи одновременно queue.addOperation { print("Операция 1") } queue.addOperation { print("Операция 2") } 🟠Actors – безопасная работа с потоками в Swift 5.5+ С actor можно работать с потоками без гонок данных, потому что все его свойства защищены от одновременного доступа. actor Counter { private var value = 0 func increment() { value += 1 } func getValue() -> Int { return value } } let counter = Counter() Task { await counter.increment() print(await counter.getValue()) // Потокобезопасный доступ } 🟠Task & Async/Await (Swift 5.5+) – современный подход к асинхронности С async/await код становится читаемым и удобным. func fetchData() async -> String { try? await Task.sleep(nanoseconds: 1_000_000_000) // 1 секунда задержки return "Данные загружены" } Task { let result = await fetchData() print(result) } Ставь 👍 и забирай 📚 Базу знаний
120
3
🤔 Что такое Task? Task — это единица асинхронной работы, которая может быть запущена, приостановлена, возобновлена и завершена. В Swift и других языках (например, C#, Kotlin) Task представляет собой объект, выполняющий асинхронный код, часто с возможностью получения результата. Задачи помогают структурировать конкурентный код более удобно, чем вручную через потоки. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
154
4
🤔 Расскажи про кодирование и декодирование в 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}] } Ставь 👍 и забирай 📚 Базу знаний
176
5
🤔 Какие есть способы сделать коллекции потокобезопасными? - Использовать сериализацию доступа через DispatchQueue.sync (последовательная очередь). - Применять NSLock, os_unfair_lock или pthread_mutex. - Использовать конкурентные очереди с барьерами (DispatchQueue.concurrent + barrier). - Использовать встроенные потокобезопасные типы, если они доступны в библиотеке (например, ConcurrentDictionary в .NET). - Создавать обёртки (wrapper) вокруг коллекции с контролем доступа. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
154
6
🤔 Какие виды диспетчеризации существуют в свифт? В Swift существует несколько видов диспетчеризации, которые определяют, как и когда вызываются методы или функции. Основные виды диспетчеризации включают статическую диспетчеризацию (static dispatch), диспетчеризацию по таблице виртуальных функций (vtable dispatch), диспетчеризацию по свидетелю (witness table dispatch) и динамическую диспетчеризацию (dynamic dispatch). Рассмотрим их подробнее: 🟠Статическая диспетчеризация (Static Dispatch) Вызов функции или метода определяется на этапе компиляции. Используется для функций и методов, которые не переопределяются в подклассах или не являются динамическими. Для структур, перечислений и final классов. struct MyStruct { func printMessage() { print("Hello from MyStruct") } } let instance = MyStruct() instance.printMessage() // Вызов определяется на этапе компиляции 🟠Диспетчеризация по таблице виртуальных функций (Vtable Dispatch) Используется для вызова методов класса, которые могут быть переопределены в подклассах. Виртуальная таблица (vtable) используется для определения, какой метод вызывать. Для классов и их подклассов. class BaseClass { func printMessage() { print("Hello from BaseClass") } } class SubClass: BaseClass { override func printMessage() { print("Hello from SubClass") } } let instance: BaseClass = SubClass() instance.printMessage() // Вызов определяется в runtime с использованием vtable 🟠Диспетчеризация по свидетелю (Witness Table Dispatch) Используется для вызова методов протоколов, реализованных типами. Таблица свидетелей (witness table) используется для определения, какой метод вызывать. Для типов, соответствующих протоколам. protocol MyProtocol { func printMessage() } struct MyStruct: MyProtocol { func printMessage() { print("Hello from MyStruct") } } let instance: MyProtocol = MyStruct() instance.printMessage() // Вызов определяется в runtime с использованием witness table 🟠Динамическая диспетчеризация (Dynamic Dispatch) Используется для вызова методов, отмеченных как dynamic или методов Objective-C. Метод определяется в runtime с использованием Objective-C runtime. Для методов, которые должны быть динамически разрешены в runtime, обычно для взаимодействия с Objective-C. import Foundation class MyClass: NSObject { @objc dynamic func printMessage() { print("Hello from MyClass") } } let instance = MyClass() instance.printMessage() // Вызов определяется в runtime с использованием Objective-C runtime Ставь 👍 и забирай 📚 Базу знаний
174
7
🤔 Каким образом подключая интерфейс мы получаем поведение? Протокол (интерфейс) описывает поведение, а при подключении к нему класс или структура обязываются реализовать методы, тем самым приобретая определённое поведение. Это форма абстракции и инверсии управления. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
151
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. Это позволяет подклассам расширять, а не заменять поведение суперкласса. Ставь 👍 и забирай 📚 Базу знаний
178
9
🤔 Наследником чего является UIView? UIView наследуется от UIResponder, что позволяет ему реагировать на события (касания, движения и т.д.). Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
188
10
🤔 Что может быть ключом и значением для 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"] Ставь 👍 и забирай 📚 Базу знаний
211
11
🤔 Какие есть проблемы с приоритетами? Если у элементов AutoLayout установлены противоречивые приоритеты (например, одинаковые и максимальные), может произойти конфликт ограничений. Это приводит к ошибкам в логах и непредсказуемой верстке. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
177
12
🤔 Что под капотом стэка? Это абстрактная структура данных, работающая по принципу LIFO (Last In, First Out), что означает "последний пришёл — первый вышел". Это значит, что последний добавленный элемент будет первым при извлечении из стека. Под капотом реализации стека могут быть разные, и они зависят от конкретного языка программирования и задач, которые необходимо решить. 🟠Массивы Один из самых распространённых способов реализации стека — это использование массива. В такой реализации элементы стека хранятся в массиве, и индекс последнего элемента (вершина стека) отслеживается отдельной переменной. struct Stack<Element> { private var storage: [Element] = [] mutating func push(_ element: Element) { storage.append(element) } mutating func pop() -> Element? { return storage.popLast() } func peek() -> Element? { return storage.last } var isEmpty: Bool { return storage.isEmpty } } 🟠Связные списки Стек можно реализовать с использованием связных списков, где каждый элемент списка содержит данные и ссылку на следующий элемент в стеке. Вершина стека в такой реализации — это начало связного списка. class Node<Element> { var value: Element var next: Node? init(value: Element) { self.value = value } } struct Stack<Element> { private var head: Node<Element>? mutating func push(_ element: Element) { let node = Node(value: element) node.next = head head = node } mutating func pop() -> Element? { let node = head head = head?.next return node?.value } func peek() -> Element? { return head?.value } var isEmpty: Bool { return head == nil } } 🟠Стек вызовов Это системный стек, который используется во время выполнения программы для хранения информации о вызовах функций/методов. Он хранит адреса возврата, параметры функций, локальные переменные и другие данные, необходимые для управления вызовами функций и их возврата. 🚩Зачем он нужен? Обратную польскую нотацию для вычисления арифметических выражений. Управление вызовами функций в программном стеке. Поддержка операций undo в приложениях. Ставь 👍 и забирай 📚 Базу знаний
200
13
🔥 Скрытые вакансии с удаленной работой для iOS разработчика, которые нигде больше не публикуются. Напрямую от компаний, с ко
🔥 Скрытые вакансии с удаленной работой для iOS разработчика, которые нигде больше не публикуются. Напрямую от компаний, с контактами рекрутеров. 🔹 iOS Jobs | Вакансии 🔹 Flutter Dart Jobs | Вакансии 🔹 Android Jobs | Вакансии 🔸 Все каналы с вакансиями
218
14
🤔 Архитектура REST? REST (Representational State Transfer) — это архитектурный стиль, основанный на взаимодействии клиента и сервера через HTTP. Основные принципы: - Клиент-серверная модель — чёткое разделение фронтенда и бэкенда. - Статус ресурса через URL — всё доступно через уникальные адреса. - Методы HTTP — используются для управления ресурсами (GET, POST, PUT, DELETE и т.д.). - Без сохранения состояния — каждый запрос содержит всю необходимую информацию. - Кеширование — серверные ответы можно кешировать. REST удобен, масштабируем и хорошо ложится на веб-приложения. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
219
15
🤔 Где могут располагаться стеки помимо структуры В программировании стек (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 удаляется при выходе из функции Ставь 👍 и забирай 📚 Базу знаний
221
16
🤔 Как можно посмотреть утечки? Инструмент Instruments (особенно Leaks и Allocations) из Xcode позволяет отслеживать живые объекты и найти retain cycles. Также можно использовать Xcode Memory Graph Debugger (в процессе отладки). Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
226
17
@autoclosure позволяет передавать выражение как замыкание, но писать его без фигурных скобок. Компилятор автоматически оборачивает выражение в замыкание. Используется, например, в функциях вроде assert, чтобы отложить выполнение до нужного момента и сохранить читаемость. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
256
18
🤔 Что такое барьеры? Барьер (Barrier) – это механизм синхронизации потоков, который позволяет контролировать порядок выполнения операций** в многопоточной среде. 🚩Барьеры памяти (Memory Barriers) Используются в многопоточном программировании для управления порядком операций с памятью. В многопоточной среде процессоры и компиляторы могут оптимизировать порядок команд, что может привести к непредсказуемому поведению. Барьеры памяти предотвращают это. #include <stdatomic.h> atomic_int sharedValue = 0; void updateValue() { atomic_store_explicit(&sharedValue, 10, memory_order_release); } void readValue() { int value = atomic_load_explicit(&sharedValue, memory_order_acquire); } 🚩Барьеры в GCD (`dispatch_barrier`) Используются в Grand Central Dispatch (GCD)** для контроля порядка выполнения задач в DispatchQueue. - Позволяет блокировать очередь на время выполнения задачи. - Все задачи до барьера выполняются параллельно. - Барьер ждёт завершения всех предыдущих задач, выполняется эксклюзивно, затем разрешает следующие задачи. let queue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent) queue.async { print("Задача 1") } queue.async { print("Задача 2") } // БАРЬЕРНАЯ ОПЕРАЦИЯ queue.async(flags: .barrier) { print("🔴 Барьер: все предыдущие задачи завершены, выполняюсь один!") } queue.async { print("Задача 3") } 🚩Барьеры в OpenMP (Параллельные вычисления) В OpenMP (#pragma omp barrier) ждёт завершения всех потоков перед выполнением следующего кода. #pragma omp parallel { printf("До барьера\n"); #pragma omp barrier printf("После барьера\n"); } Ставь 👍 и забирай 📚 Базу знаний
260
19
🤔 Зачем нужен тип ссылок unowned в Swift? Unowned ссылки используются для предотвращения сильных циклов ссылок (retain cycles) между экземплярами классов, когда два объекта ссылаются друг на друга сильно. В отличие от `weak`, `unowned` не делает объект опциональным и не автоматически обнуляется, что делает его подходящим для случаев, когда другой объект гарантированно будет иметь тот же или более долгий срок жизни. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
217
20
🤔 Что происходит с классом при компиляции? При компиляции в Swift класс проходит несколько стадий обработки: Анализ синтаксиса и семантики – компилятор проверяет код на ошибки. Генерация промежуточного представления (IR) – создаётся код на уровне LLVM IR. Оптимизация – Swift применяет различные оптимизации, например, inlining, dead code elimination и другие. Генерация машинного кода – итоговый код превращается в исполняемый машинный код, специфичный для платформы. 🚩Что конкретно происходит с классом? В отличие от структур, классы в Swift являются ссылочными типами и хранятся в куче (heap). Это означает, что: - При создании объекта выделяется память в куче. - Swift автоматически использует ARC (Automatic Reference Counting) для управления памятью. - Методы класса могут вызываться через виртуальную таблицу (vtable), если класс использует динамическую диспетчеризацию. 🚩Важные моменты - Если класс final, компилятор может оптимизировать вызовы методов, убрав динамическую диспетчеризацию. - Наследование делает вызовы методов менее предсказуемыми (они идут через vtable). - В отличие от структур, классы не копируются при передаче в функцию, а передаётся ссылка. class Animal { var name: String init(name: String) { self.name = name } func speak() { print("Some sound") } } final class Dog: Animal { override func speak() { print("Woof!") } } let myDog = Dog(name: "Buddy") myDog.speak() Ставь 👍 и забирай 📚 Базу знаний
233