Swift | Вопросы собесов
2.13K subscribers
28 photos
957 links
Download Telegram
🤔 Что такое многопоточность?

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

🚩Основные понятия

🟠Поток (Thread)
Минимальная единица обработки, которая может быть выполнена операционной системой.

🟠Конкуренция (Concurrency)
Способность программы делать прогресс в нескольких задачах одновременно. Конкуренция достигается за счёт переключения между задачами.

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

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Если экран обладает и альбомной, и портретной ориентацией, что удобнее использовать: AutoLayout или Frame?

AutoLayout однозначно предпочтительнее, так как автоматически адаптируется к изменению размеров экрана и ориентации. Использование фреймов потребует ручного пересчета координат и размеров при каждом повороте устройства.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 А если сделать свою структуру, то она будет поддерживать copyright?

Если вы создадите свою структуру (struct) в Swift, то сама по себе она не будет автоматически защищена авторским правом (copyright). Авторские права относятся к защите исходного кода как текста, но не к самим структурам данных или идеям.

🚩Как защитить свою структуру?

🟠Авторские права (Copyright)
автоматически защищает исходный код.
Можно указать копирайт в файле:
// Copyright © 2025 [Ваше имя]. All rights reserved.


🟠Лицензия (MIT, Apache, GPL и т. д.)
если публикуете код в открытом доступе.
Позволяет контролировать, как другие могут использовать ваш код.
The MIT License (MIT)
Copyright (c) 2025 [Ваше имя]
Permission is hereby granted, free of charge, to any person obtaining a copy...


🟠Патент (если структура или алгоритм уникальны)
Если у вас уникальная структура данных, можно попробовать её запатентовать. Патент защищает не код, а саму идею реализации.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊7
🤔 Что нужно сделать, чтобы кастомная структура стала ключом в 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 для хеша
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Почему порядок ключей будет сохраняться между мутациями в словаре?

Начиная с Swift 4, стандартный Dictionary сохраняет порядок вставки ключей. Даже при изменении значений или добавлении новых элементов порядок сохраняется, пока явным образом не удаляются ключи или не происходит массовая перераспределённая перестройка.
Это стало возможным благодаря обновлённой реализации хеш-таблицы внутри Dictionary.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Чем опасна утечка памяти?

Утечка памяти (memory leak) – это ситуация, когда память остаётся выделенной, но больше не используется программой и не освобождается.

class Person {
var pet: Pet?
deinit { print("Person удалён") }
}

class Pet {
var owner: Person?
deinit { print("Pet удалён") }
}

var person: Person? = Person()
var pet: Pet? = Pet()

person?.pet = pet
pet?.owner = person

person = nil
pet = nil


🚩Как избежать утечек памяти?

🟠Использовать `weak` или `unowned` ссылки
Слабые (weak) или безвладельческие (unowned) ссылки не увеличивают счётчик ссылок, что разрывает цикл.
class Person {
var pet: Pet?
deinit { print("Person удалён") }
}

class Pet {
weak var owner: Person? // Слабая ссылка
deinit { print("Pet удалён") }
}

var person: Person? = Person()
var pet: Pet? = Pet()

person?.pet = pet
pet?.owner = person

person = nil // "Person удалён"
pet = nil // "Pet удалён"


🟠Использовать `unowned`, если объект всегда будет существовать
unowned похож на weak, но он не может быть `nil`.
class Owner {
var car: Car?
deinit { print("Owner удалён") }
}

class Car {
unowned var owner: Owner // Безвладельческая ссылка
init(owner: Owner) { self.owner = owner }
deinit { print("Car удалён") }
}

var owner: Owner? = Owner()
owner?.car = Car(owner: owner!)

owner = nil // "Owner удалён", "Car удалён"


🟠Разрывать циклы в замыканиях (`[weak self]`)
Замыкания захватывают объекты, создавая циклические ссылки.
Проблема: self удерживается замыканием
class ViewController {
var closure: (() -> Void)?

func setup() {
closure = {
print(self) // Удерживает self, создавая цикл!
}
}

deinit { print("ViewController удалён") }
}

var vc: ViewController? = ViewController()
vc?.setup()
vc = nil // "ViewController" НЕ удалится


🚩Как найти утечки памяти?

🟠Использовать `Instrument – Leaks` в Xcode
- Открываем Xcode > Product > Profile.
- Выбираем Leaks.
- Запускаем приложение и проверяем, остаются ли объекты в памяти.

🟠Проверить `deinit`
Если метод deinit не вызывается – значит, объект утёк в память.
class Test {
deinit { print("Test удалён") }
}

var obj: Test? = Test()
obj = nil // Должно напечатать "Test удалён"


🟠Включить `Malloc Stack Logging`
- В Xcode открываем "Debug Memory Graph" (нажимая значок в Debugger).
- Смотрим, какие объекты остались в памяти.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Как компилятор находит метод, который нужно вызвать?

В Swift компилятор использует статическую диспетчеризацию (на этапе компиляции), если это final, struct, enum, или static. В остальных случаях — динамическую диспетчеризацию через таблицу методов (vtable) для классов. Метод выбирается по сигнатуре, контексту и типу.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Что такое gitflow?

В основе Git Flow – несколько веток с разными ролями, чтобы команда могла параллельно разрабатывать новые фичи, исправлять баги и выпускать релизы.

🚩Как работает Git Flow?

🟠Основные ветки (`main` и `develop`)
- main – содержит только стабильные версии.
- developосновная ветка разработки, в неё вливаются все новые фичи.

🟠Разработка новых фич (feature branches)
- Каждая новая фича создаётся в отдельной ветке feature/*.
- После завершения сливается в develop.
git checkout develop
git checkout -b feature/new-cool-feature
# Разработка...
git checkout develop
git merge feature/new-cool-feature
git branch -d feature/new-cool-feature


🟠Подготовка к релизу (release branches)
- Когда код стабилен, создаётся ветка release/* от develop.
- Здесь можно тестировать и исправлять баги.
- После финального теста сливается в main и develop.
git checkout develop
git checkout -b release/1.0
# Фиксим баги, тестируем...
git checkout main
git merge release/1.0
git tag -a v1.0 -m "Release 1.0"
git checkout develop
git merge release/1.0
git branch -d release/1.0


🟠Горячие фиксы (hotfix branches)
- Если критический баг в main, создаём hotfix/*.
- После исправления вливаем в main и в develop.
git checkout main
git checkout -b hotfix/urgent-bugfix
# Фиксим баг...
git checkout main
git merge hotfix/urgent-bugfix
git checkout develop
git merge hotfix/urgent-bugfix
git branch -d hotfix/urgent-bugfix


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Объяснение NSOperation?

NSOperation — это объектно-ориентированный способ организации задач в iOS/macOS. Он позволяет управлять очередями задач с возможностью их приостановки, отмены, приоритезации и установления зависимостей между операциями. Работает в связке с NSOperationQueue. В отличие от GCD, даёт больше контроля и читаемости, особенно при работе со сложными асинхронными цепочками.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 В чём разница между вью и леером?

В iOS и macOS приложениях, разработанных с использованием Swift или Objective-C, UIView и CALayer играют ключевые роли в управлении и отображении пользовательского интерфейса. Несмотря на то, что они тесно связаны, между ними есть важные различия. Давайте рассмотрим их подробнее.

🚩UIView

UIView — это базовый класс для всех элементов пользовательского интерфейса в iOS. Он представляет собой прямоугольную область на экране, которая может отображать контент и реагировать на события пользователя, такие как нажатия, жесты и касания.
UIView предоставляет множество свойств и методов для управления внешним видом, положением и поведением представления. Примеры включают frame, bounds, center, backgroundColor, alpha, isHidden, и subviews. UIView также поддерживает анимации, автолэйаут и работу с событийной системой.
UIView обрабатывает пользовательские события, такие как касания и жесты. Он предоставляет методы, такие как touchesBegan, touchesMoved, и touchesEnded, для обработки этих событий.
   let myView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
myView.backgroundColor = .blue
view.addSubview(myView)


🚩CALayer

CALayer — это базовый класс для всех графических слоев, используемых в Core Animation. Он обеспечивает низкоуровневую поддержку для рендеринга, анимации и композиции графики.
CALayer предоставляет свойства для управления внешним видом, такими как backgroundColor, borderWidth, cornerRadius, shadowOpacity, contents (для отображения изображений), и transform. CALayer также поддерживает анимации, используя ключевые кадры и основные анимации. CALayer не обрабатывает пользовательские события напрямую. Эти задачи оставлены на UIView, который может содержать один или несколько слоев.
   let myLayer = CALayer()
myLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
myLayer.backgroundColor = UIColor.blue.cgColor
view.layer.addSublayer(myLayer)


🚩Основные различия между UIView и CALayer

🟠По уровеню абстракции
UIView
— это более высокий уровень абстракции, предназначенный для работы с пользовательским интерфейсом и обработкой событий. CALayer — более низкоуровневый элемент, который фокусируется на рендеринге и анимации графики.

🟠Реакция на события
UIView обрабатывает события пользовательского интерфейса. CALayer не обрабатывает события, но предоставляет возможности для рендеринга и анимации.

🟠Иерархия
UIView может содержать другие представления (subviews) и управлять их иерархией. CALayer может содержать другие слои (sublayers) и управлять их иерархией.

🟠Анимации
UIView использует UIView.animate для создания анимаций, которые высокоуровневые и просты в использовании. CALayer использует CAAnimation и его подклассы для создания анимаций, которые более гибкие и мощные, но требуют большего количества кода.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 В чём разница между var и let?

- var — переменная, её значение можно изменить.
- let — константа, значение нельзя переопределить после инициализации.
Это помогает контролировать изменяемость данных в коде.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔2
🤔 Какие есть способы верстать?

В iOS существует несколько способов вёрстки пользовательского интерфейса. Каждый из них имеет свои плюсы и минусы в зависимости от проекта.

🟠Interface Builder (Storyboard & XIB)
Используется: визуальный редактор в Xcode.
Storyboard
- Позволяет создавать весь UI в одном файле .storyboard.
- Поддерживает Auto Layout и Size Classes для адаптивного дизайна.
- Можно настраивать Segue (переходы между экранами).

🟠Верстка кодом (без Storyboard)
Используется: Полностью программная вёрстка без использования Interface Builder.
let button = UIButton()
button.setTitle("Нажми", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)

NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])


🟠SwiftUI – декларативный подход
Используется: Современный способ верстки с декларативным синтаксисом.
struct ContentView: View {
var body: some View {
VStack {
Text("Привет, SwiftUI!")
.font(.largeTitle)
Button("Нажми меня") {
print("Кнопка нажата")
}
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Зачем нужны свойства "Content Hugging Priority"?

1. Свойства управляют тем, как сильно элемент интерфейса сопротивляется увеличению своего размера.
2. Высокий приоритет указывает, что элемент предпочитает оставаться минимального размера, основываясь на содержимом.
3. Используется для разрешения конфликтов автолейаута, чтобы определять, какой элемент должен изменяться.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Inam относится ли к value тайпам?

enum (перечисления) относится к типам значений (value types). Это означает, что при передаче перечисления функции или при его присвоении переменной создается новая копия этого перечисления. Это работает аналогично другим типам значений, таким как struct и базовые типы данных (Int, String, Double и т.д.).

🚩Особенности

🟠Копирование при присвоении
Когда переменной перечисления присваивается значение другой переменной перечисления, создается независимая копия этого значения.

🟠Безопасность типов
enum поддерживает безопасность типов, что позволяет создавать код, легкий для понимания и поддержки.

🟠Связанные значения
enum может хранить связанные значения различных типов.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}


🟠Методы
enum может иметь методы, которые предоставляют функциональность, связанную с перечислением.
enum Planet {
case earth, mars, venus

func isHabitable() -> Bool {
switch self {
case .earth:
return true
default:
return false
}
}
}


Пример
enum TrafficLight {
case red, yellow, green
}

var light = TrafficLight.red
var lightCopy = light
lightCopy = .green

print(light) // Выводит "red"
print(lightCopy) // Выводит "green"


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊7🤔2
🤔 Какие ситуации могут быть с isUserInteractionEnabled = false, когда UIView не может обработать тач?

Если isUserInteractionEnabled == false, то:
- Вью не участвует в hit-тестировании.
- Касания игнорируются, и управление не передаётся даже в её subviews.
- Это может использоваться для пропуска вью при касаниях, например для декоративных вьюшек или контейнеров.
Ситуации:
- Кнопка, которая кажется активной, но isUserInteractionEnabled = false — не реагирует.
- Обёртка вокруг интерактивной вью с отключенным взаимодействием — вложенные вью тоже не реагируют.
Чтобы вложенные вью реагировали, при этом контейнер не мешал, можно либо оставить userInteractionEnabled = true, либо использовать прозрачный hitTest.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
🤔 Как устроена память?

Память устройства можно представить в виде нескольких уровней, каждый из которых имеет свою скорость доступа, размер и назначение:

🟠Регистры процессора
Это самая быстрая память, непосредственно встроенная в процессор. Регистры хранят те данные, с которыми процессор работает в данный момент времени.

🟠Кэш-память
Она находится непосредственно на процессоре или рядом с ним. Кэш-память используется для временного хранения копий часто используемых данных из основной памяти для ускорения доступа к ним. Кэш-память делится на несколько уровней (L1, L2, и иногда L3), где L1 — самый быстрый и обычно самый маленький.

🟠Оперативная память (ОЗУ)
Здесь хранятся данные и программы, с которыми компьютер работает в данный момент. Доступ к ОЗУ быстрый, но оно является временным хранилищем: при выключении устройства данные в ОЗУ теряются.

🟠Постоянная память (ПЗУ, SSD, HDD)
Это память для долговременного хранения данных. Она сохраняет информацию даже при выключении питания. HDD (жесткие диски) использовались ранее и работают на принципе магнитного записывания данных, в то время как SSD (твердотельные накопители) работают на основе флеш-памяти и обеспечивают более быстрый доступ к данным.

🟠Виртуальная память
Это техника, которая позволяет операционной системе использовать часть жесткого диска (или SSD) как дополнительную оперативную память. Когда ОЗУ заполнено, операционная система может перемещать редко используемые данные из ОЗУ на диск в специальный файл подкачки (swap file), освобождая ОЗУ для других задач.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Существует 2 типа queue?

Да, существуют два основных типа dispatch-очередей:
- Serial queue — задачи выполняются строго по одной, по порядку.
- Concurrent queue — задачи могут выполняться одновременно, в зависимости от доступных ресурсов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Какие виды диспетчеризации существуют в свифт?

В 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


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
🤔 К какому типу относится замыкание?

Замыкание — это референсный тип. Оно является объектом и передаётся по ссылке. При захвате переменных — сохраняет их в памяти до завершения использования.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1
🤔 Что такое Satisfiable?

В контексте Swift термин Satisfiable (удовлетворяемый) относится к тому, может ли конкретный тип соответствовать (удовлетворять) требованиям протокола.

🚩Что значит, что протокол satisfiable?
Протокол считается satisfiable, если его можно реализовать без противоречий. Например, если в протоколе указаны требования, которые могут быть выполнены в классе или структуре.
protocol Animal {
var name: String { get }
func speak()
}

struct Dog: Animal {
var name = "Барсик"

func speak() {
print("Гав-гав")
}
}

let dog = Dog()
dog.speak() // "Гав-гав"


🚩Когда протокол не satisfiable?

Протокол не может быть удовлетворён (то есть, не satisfiable), если он содержит требования, которые невозможно реализовать в конкретном типе.
protocol Impossible {
var value: Self { get } // Self требует, чтобы свойство содержало сам тип
}

struct Example: Impossible {
var value: Example // ОШИБКА: бесконечная рекурсия!
}


🚩Проверка satisfiability в Swift

Если вы видите ошибку Protocol 'X' cannot be satisfied, значит, Swift не может найти способ правильно реализовать все его требования.
Проверьте ассоциированные типы и Self – они должны корректно ссылаться на реализуемый тип.
Проверьте требования протокола – убедитесь, что все свойства и методы могут быть реализованы в классе/структуре.
Попробуйте использовать any Protocol – если Self создаёт проблемы, возможно, нужно использовать any:
   func test(value: any Impossible) { } // Позволяет работать с протоколом без строгого Self


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM