TGViewer
Channel Public Channel
Swift | Вопросы собесов

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

@easy_swift

Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy

Контакт для рекламы: @sendme_ads
Subscribers
2.16K
Photos
32
Videos
0
Links
1.5K
Recent Posts 20 shown
Post #2021 107
🤔 Что известно о Swift Intermediate Language (SIL)?

SIL (Swift Intermediate Language) — это промежуточное представление кода, которое Swift-компилятор использует между стадиями компиляции и генерации байткода.
SIL:
- Позволяет проводить оптимизации на уровне Swift-кода.
- Более абстрактен, чем машинный код, но ближе к нему, чем сам Swift.
- Существует в двух формах: raw SIL (до оптимизаций) и canonical SIL (после).
- Используется для анализа производительности, валидации ARC, оптимизации кода, проверки правильности lifetime объектов.
SIL — ключевая часть того, почему Swift работает быстро и надёжно, несмотря на высокоуровневую природу языка.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #2020 146
🤔 Что под капотом стэка?

Это абстрактная структура данных, работающая по принципу 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 в приложениях.

Ставь 👍 и забирай 📚 Базу знаний
Post #2019 159
🤔 Как хранить объекты классов в массиве по weak-ссылке?

Обычно для этого используют обёртку, например WeakBox<T>, где T: AnyObject, и поле weak var value: T
Swift не поддерживает массив weak напрямую.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #2018 186
🤔 Как можно итерироваться по строке?

Строка — это коллекция символов. Итерироваться можно так же, как и по массиву: посимвольно через for, используя индекс, итератор или методы работы со строками (например, enumerate или split в зависимости от языка).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 👍 1
Post #2017 191
🤔 Какие есть инструменты для работы с потоками?

В 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)
}


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 2
Post #2015 206
🤔 Что такое замыкание?

Замыкание (closure) — это блок кода, который можно передать и выполнить позже. Оно может захватывать значения из окружающего контекста. Аналог лямбда-функций и функциональных выражений.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #2014 218
🤔 Что нужно сделать, чтобы кастомная структура стала ключом в 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 для хеша
}
}


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 1
Post #2013 204
🤔 Какой есть механизм для показа экрана?

Обычно используются:
- pushViewController (в UINavigationController);
- present(_:animated:) — для модального показа;
- В SwiftUI — NavigationStack, .sheet, .fullScreenCover.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 👍 2
Post #2012 216
🤔 Что такое 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)


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 1
Post #2011 194
🤔 Как устроено наследование в Swift?

Наследование в Swift позволяет классу (подклассу) унаследовать свойства, методы и инициализаторы от другого класса (суперкласса). Подклассы могут переопределять (override) поведение суперкласса, добавлять новые свойства и методы, но не могут наследовать структуры, перечисления или протоколы.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 👍 1
  • 🔥 1
Post #2010 201
🤔 Расскажи про кодирование и декодирование в 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}]
}


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 2
Post #2009 193
🤔 Что знаешь про capture list?

Capture list используется в замыканиях Swift, чтобы управлять тем, как значения захватываются: как weak, unowned или strong. Это предотвращает retain cycle и утечки.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #2008 213
🤔 Как устроено наследование?

Это ключевой механизм ООП, позволяющий классам наследовать свойства, методы и другие характеристики от других классов. Это позволяет создавать новые классы на основе существующих, расширяя их функциональность или изменяя её.

🚩Основы наследования

🟠Определение базового класса
Базовый класс определяет общие свойства и методы, которые могут быть унаследованы подклассами.

🟠Создание подкласса
Подкласс наследует (или "расширяет") базовый класс. Он может переопределять унаследованные методы и свойства, добавлять новые методы и свойства, а также добавлять инициализаторы или изменять существующие.

🟠Переопределение методов и свойств
Подклассы могут переопределять методы, свойства и индексаторы базового класса для изменения или расширения их поведения.

🟠Предотвращение переопределения
Можно предотвратить переопределение методов, свойств или индексаторов с помощью ключевого слова 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. Это позволяет подклассам расширять, а не заменять поведение суперкласса.

Ставь 👍 и забирай 📚 Базу знаний
Post #2007 209
🤔 На какой механизм Swift похож associatedtype?

associatedtype — это аналог дженериков, но на уровне протоколов. Он позволяет абстрагировать конкретный тип и использовать его позже в реализации, сохраняя гибкость и строгость типизации.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #2006 234
🤔 Как отлавливать, где допущена ошибка в свифте?

В 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("Метод ещё не реализован")
}


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 1
Post #2005 209
🤔 Что такое Notification Center?

Это механизм публикации и подписки на события в iOS.
- Позволяет компонентам приложения обмениваться данными без прямых ссылок.
- Работает по принципу наблюдателя: объект отправляет уведомление, а подписчики получают его.
- Используется для глобального взаимодействия между модулями (например, обновление UI после фоновой загрузки данных).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #2004 218
🤔 Как бы реализовал словарь в 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


Ставь 👍 и забирай 📚 Базу знаний
Post #2003 216
🤔 Где хранятся ссылочные типы и типы, которые хранятся по значению?

Ссылочные типы (class) хранятся в куче (heap), а переменные содержат ссылки на них. Значимые типы (struct, enum) хранятся в стеке, если не вложены в ссылочные, и копируются при передаче.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 👍 2
Post #2002 242
🤔 Для каких сущностей работает 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 модифицируется


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 3
  • 🔥 1
Older posts →

About this channel

How can I read @easy_swift without a Telegram account?
TGViewer shows the public web preview Telegram publishes for Swift | Вопросы собесов: recent posts, photos, videos and the subscriber count, with no app, login or account.
How many subscribers does Swift | Вопросы собесов have?
Swift | Вопросы собесов (@easy_swift) has 2.16K subscribers on Telegram, refreshed roughly every 30 minutes.
Does Swift | Вопросы собесов know I viewed it here?
No. Public channel previews carry no viewer identity, and TGViewer has no accounts or tracking of what you look up.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →