Swift | Вопросы собесов
Ir al canal en Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
Mostrar más2 141
Suscriptores
-124 horas
-77 días
-1830 días
Cargando datos
Canales Similares
Nube de Etiquetas
Menciones Entrantes y Salientes
---
---
---
---
---
---
Atraer Suscriptores
octubre '26oct '26
octubre '26
+20
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 | |
| 26 octubre | 0 | |||
| 25 octubre | 0 | |||
| 24 octubre | 0 | |||
| 23 octubre | +1 | |||
| 22 octubre | 0 | |||
| 21 octubre | +4 | |||
| 20 octubre | 0 | |||
| 19 octubre | +1 | |||
| 18 octubre | 0 | |||
| 17 octubre | +1 | |||
| 16 octubre | 0 | |||
| 15 octubre | 0 | |||
| 14 octubre | 0 | |||
| 13 octubre | +1 | |||
| 12 octubre | 0 | |||
| 11 octubre | +1 | |||
| 10 octubre | +2 | |||
| 09 octubre | 0 | |||
| 08 octubre | +1 | |||
| 07 octubre | 0 | |||
| 06 octubre | 0 | |||
| 05 octubre | +3 | |||
| 04 octubre | 0 | |||
| 03 octubre | +2 | |||
| 02 octubre | +1 | |||
| 01 octubre | +2 |
Publicaciones del Canal
🤔 Преимущества использования 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 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 |
