Swift | Вопросы собесов
2.13K subscribers
28 photos
957 links
Download Telegram
🤔 Как работают выделения?

Процесс выделения (allocation) связан с резервированием памяти для хранения объектов или данных в программе. В зависимости от типа памяти выделение может происходить в куче (heap) или стеке (stack). Куча используется для объектов с длительным сроком жизни, а стек — для временных данных, таких как локальные переменные. В языках с автоматическим управлением памятью, например, в Swift или Java, выделение и освобождение памяти обрабатываются системой.


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

Термин "посылка" может означать разные вещи в зависимости от контекста
Передача данных между экранами (Navigation, Segue, Delegate, Notification)
Передача данных через API (Network Request, JSON, WebSocket)
Передача данных в многопоточной среде (DispatchQueue, OperationQueue)

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4👀1
🤔 Что будет, если убрать опционал?

1. Удаление опционалов лишит язык возможности безопасно работать с отсутствием значений.
2. Программистам придётся вручную проверять наличие значений, что повысит вероятность ошибок и крашей.
3. Опционалы делают код более безопасным и читаемым, позволяя явно выражать ситуацию, когда значение может отсутствовать.


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

NSManagedObjectID – это уникальный идентификатор объекта в Core Data, который остаётся неизменным на протяжении всего жизненного цикла объекта.

🚩Как сохранить `NSManagedObjectID`?

Используем uriRepresentation() – это строка (URL), которая уникально идентифицирует объект.
func saveObjectID(_ object: NSManagedObject) {
let objectID = object.objectID.uriRepresentation().absoluteString
UserDefaults.standard.set(objectID, forKey: "savedObjectID")
}


🚩Как восстановить объект по `NSManagedObjectID`?

1. Получаем URL из UserDefaults.
2. Преобразуем URL в NSManagedObjectID.
3. Загружаем объект из Core Data.
func fetchSavedObjectID(context: NSManagedObjectContext) -> NSManagedObject? {
guard let objectIDString = UserDefaults.standard.string(forKey: "savedObjectID"),
let objectURL = URL(string: objectIDString) else { return nil }

let objectID = context.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: objectURL)

if let objectID = objectID {
return context.object(with: objectID)
}
return nil
}


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

В SwiftUI можно условно разделить View на несколько категорий:
1. Контейнеры (Layout):
- VStack, HStack, ZStack, Grid, List, Form, ScrollView.
2. Элементы интерфейса:
- Text, Image, Button, Toggle, Slider, TextField.
3. Навигация и управление:
- NavigationView, NavigationStack, TabView, Sheet, Popover.
4. Декоративные и вспомогательные:
- Spacer, Divider, Group, EmptyView.
5. Анимации и эффекты:
- LottieView, TimelineView, Canvas, GeometryReader.


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

Мьютекс (от англ. "mutex" - mutual exclusion, взаимное исключение) — это механизм синхронизации, используемый в многопоточном программировании для предотвращения одновременного доступа нескольких потоков к общим ресурсам, таким как переменные, структуры данных или файлы. Он помогает избежать состояния гонки (race condition), когда результат выполнения программы зависит от неопределённого порядка доступа потоков к ресурсу.

🚩Основные концепции мьютекса

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

🟠Захват и освобождение
Поток захватывает мьютекс перед доступом к общему ресурсу и освобождает его после завершения работы с этим ресурсом. Если мьютекс уже захвачен другим потоком, текущий поток будет блокирован до тех пор, пока мьютекс не будет освобождён.

🚩Пример использования мьютекса в Swift

import Foundation

class SafeCounter {
private var value = 0
private let lock = NSLock()

func increment() {
lock.lock() // Захват мьютекса
value += 1
lock.unlock() // Освобождение мьютекса
}

func getValue() -> Int {
lock.lock() // Захват мьютекса
let currentValue = value
lock.unlock() // Освобождение мьютекса
return currentValue
}
}

let counter = SafeCounter()
DispatchQueue.global().async {
for _ in 0..<1000 {
counter.increment()
}
}

DispatchQueue.global().async {
for _ in 0..<1000 {
counter.increment()
}
}

// Подождём немного, чтобы дать потокам закончить работу
Thread.sleep(forTimeInterval: 1)
print("Final counter value: \(counter.getValue())")


🚩Плюсы и минусы

Безопасность данных
Мьютексы защищают общие ресурсы от одновременного доступа, предотвращая повреждение данных.

Предсказуемость
Код становится более предсказуемым и стабильным, так как исключаются состояния гонки.

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

Производительность
Чрезмерное использование мьютексов может привести к снижению производительности из-за увеличения времени ожидания потоков.

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

Для многопоточности в iOS обычно используются технологии, такие как Grand Central Dispatch (GCD) для управления легковесными операциями и потоками, и `Operation` и `OperationQueue` для более сложных задач многопоточности, позволяющих более тонко управлять выполнением задач и зависимостями между ними.

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

Фреймы (frames) в iOS-разработке используются для задания размеров и расположения элементов интерфейса (UIView) вручную.

🟠Кастомные анимации
Когда нужно анимировать движение элемента, проще всего работать с его frame, так как он напрямую управляет origin (координаты) и size (размеры).
UIView.animate(withDuration: 0.5) {
self.button.frame.origin.x += 100
}


🟠Ручная верстка (без Auto Layout)
Если вы не используете Auto Layout или хотите задать положение элементов программно, frame позволяет точно указать размеры и координаты.
let button = UIButton(type: .system)
button.frame = CGRect(x: 50, y: 100, width: 200, height: 50)
button.setTitle("Нажми меня", for: .normal)
view.addSubview(button)


🟠Оптимизация производительности
При динамической подгрузке ячеек в UITableView или UICollectionView можно вручную вычислять frame для ускорения работы, вместо использования Auto Layout, который может замедлить скроллинг.

🟠Работа с Core Graphics и CALayer
При рисовании или настройке слоев CALayer используется frame, чтобы точно определить размеры слоя.
let borderLayer = CALayer()
borderLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
borderLayer.borderWidth = 2
borderLayer.borderColor = UIColor.red.cgColor
view.layer.addSublayer(borderLayer)


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

Это объектные типы данных, но с разными принципами работы.
- Классы передаются по ссылке, поддерживают наследование.
- Структуры передаются по значению, копируются при изменении.
- Классы хранятся в куче (Heap), а структуры – в стеке (Stack).
- Классы используют deinit, а структуры – нет.


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

RunLoop — это фундаментальный механизм в iOS и macOS, который управляет циклом обработки событий в приложении. Он отслеживает и обрабатывает входящие события, такие как нажатия клавиш, касания экрана, таймеры и сетевые запросы, и поддерживает приложение в активном состоянии, пока оно не завершится.

🚩Основные аспекты `RunLoop`

🟠Цикл обработки событий
RunLoop постоянно выполняет цикл, ожидая входящие события и обрабатывая их по мере поступления. Этот цикл состоит из нескольких этапов: ожидание события, обработка события и повтор цикла.

🟠Режимы (Modes)
RunLoop может работать в разных режимах, которые определяют, какие источники событий будут отслеживаться и обрабатываться. Основные режимы включают default и tracking (для событий отслеживания, таких как прокрутка). В каждой итерации RunLoop обрабатывает события только для текущего режима.
RunLoop.current.run(mode: .default, before: Date.distantFuture)     


🟠Источники событий (Event Sources)
RunLoop может отслеживать различные источники событий, такие как таймеры (Timer), порты (Port), ввод пользователей (такие как касания экрана и клики мыши), а также пользовательские источники (Input Source).

🟠Таймеры
RunLoop может управлять таймерами, которые выполняют задачи через определенные интервалы времени.
     let timer = Timer(timeInterval: 1.0, repeats: true) { _ in
print("Timer fired!")
}
RunLoop.current.add(timer, forMode: .default)


🟠Обработка событий
RunLoop используется для обработки событий в основном потоке (main thread) приложения. Это особенно важно для поддержания отзывчивости пользовательского интерфейса, поскольку все взаимодействия с UI происходят в основном потоке.

🚩Пример использования `RunLoop`

import Foundation

class Example {
var timer: Timer?

func startRunLoop() {
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
RunLoop.current.run()
}

@objc func timerFired() {
print("Timer fired!")
}
}

let example = Example()
example.startRunLoop()


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Что под капотом стэка?

Под капотом стек организован как непрерывный блок памяти, управляемый указателем вершины. Операции добавления и удаления происходят за константное время O(1), а память автоматически освобождается при удалении элементов. Стек обычно используется для хранения вызовов функций, локальных переменных и управления потоком выполнения.

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

Garbage Collector (GC) и Automatic Reference Counting (ARC) – это два разных подхода к управлению памятью в программировании. Они решают одну задачу: автоматическое освобождение неиспользуемой памяти, но делают это по-разному.

🚩Garbage Collector (GC)

Java, Kotlin, C#, Python, JavaScript
- GC периодически просматривает всю память приложения и ищет объекты, на которые больше нет ссылок.
- Когда такие объекты находятся, они удаляются, а память освобождается.
- Это автоматический процесс, который запускается по мере необходимости.

🚩Подсчет ссылок (ARC - Automatic Reference Counting)

Где используется: Swift, Objective-C
- Каждый объект имеет счетчик ссылок (reference count).
- Когда переменная создает ссылку на объект, счетчик увеличивается.
- Когда переменная перестает ссылаться на объект, счетчик уменьшается.
- Когда счетчик достигает нуля, объект удаляется из памяти сразу же.
class Person {
var pet: Pet?
}

class Pet {
var owner: Person?
}

let person = Person()
let pet = Pet()

person.pet = pet
pet.owner = person // Теперь оба объекта держат друг друга, и ARC их не удалит


Решение – использовать weak:
class Pet {
weak var owner: Person? // Теперь утечки памяти не будет
}

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

Есть обычные инициализаторы, задающие начальные значения свойств, и факультативные (init?), возвращающие nil, если объект не может быть создан.

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

Если функция ожидает параметр типа Double, но вместо этого передаем саму функцию, произойдет ошибка компиляции, так как тип функции и Double — это разные вещи

func printDouble(value: Double) {
print("Значение: \(value)")
}

printDouble(value: printDouble) // Ошибка: Несовместимые типы


🚩Как исправить?

Если вы хотите передавать функцию в качестве аргумента, ее нужно объявить в параметрах как (Double) -> Void:
func processDouble(_ value: Double, action: (Double) -> Void) {
action(value)
}

processDouble(42.0, action: printDouble) // Выведет: "Значение: 42.0"


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

SwiftUI создаст новую View с измененными параметрами, не изменяя оригинальный объект. Это позволяет оптимизировать ререндеринг, так как фреймворк пересоздает только измененные элементы.
Благодаря иммутабельности View-дерева, SwiftUI автоматически сравнивает изменения (diffing), обновляя только те части интерфейса, которые изменились. Это делает рендеринг быстрым и эффективным.


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

Это файл, содержащий отладочную информацию, используемую для сопоставления адресов в машинном коде с исходным кодом. В iOS и macOS разработке dSYM-файлы играют важную роль в процессе отладки и анализа сбоев (crash reports).

🚩Основные аспекты

🟠Содержание
dSYM-файл содержит символы отладки, такие как имена методов и классов, которые соответствуют машинному коду скомпилированного приложения. Эта информация позволяет разработчикам интерпретировать сбои и ошибки, связывая их с исходным кодом.

🟠Создание
dSYM-файлы автоматически создаются Xcode при сборке приложения. Они хранятся в специальной директории и могут быть включены в архив сборки (archive) для последующей загрузки в инструменты анализа сбоев.

🟠Использование
Декодирование отчетов о сбоях: При сбое приложения, отчет о сбое содержит машинные адреса, которые трудно интерпретировать без символов отладки. dSYM-файл помогает преобразовать эти адреса в понятные строки исходного кода.
Инструменты анализа: Инструменты, такие как Xcode, Crashlytics, или другие платформы сбора и анализа сбоев, используют dSYM-файлы для декодирования и анализа отчетов о сбоях.

🚩Пример использования

🟠Получение отчета о сбое (crash report)
Отчеты о сбоях можно получить из Xcode, TestFlight, App Store Connect, или от пользователей.
🟠Загрузка dSYM в сервис анализа
Сервис анализа сбоев, такой как Crashlytics, запрашивает загрузку соответствующего dSYM-файла для декодирования отчетов. Обычно это можно сделать через интерфейс разработчика или автоматически при настройке сборочного процесса.
🟠Декодирование отчета
С помощью dSYM-файла отчет о сбое преобразуется в читаемый формат, содержащий строки исходного кода, где произошел сбой.

🚩Важные моменты

🟠Сохранение dSYM-файлов
Всегда сохраняйте dSYM-файлы для каждой версии вашего приложения, так как они уникальны для каждой сборки.
🟠Управление версиями
Храните dSYM-файлы в безопасном месте (например, в системе управления версиями), чтобы всегда иметь доступ к нужной информации для анализа сбоев.
🟠Сопоставление версий
Убедитесь, что используемый dSYM-файл соответствует версии приложения, из которой получен отчет о сбое.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Чем отличается UIView-based animation от Core Animation?

UIView-based animation — это высокоуровневый API, удобный для анимаций интерфейса. Работает с UIView.animate, абстрагирует детали.
Core Animation — это низкоуровневая система, напрямую работающая с CALayer, позволяющая более тонко управлять производительностью, таймингами, переходами и 3D-эффектами.


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

Оптимизация выполнения кода в Swift может быть достигнута различными методами, начиная с улучшения структуры кода и заканчивая использованием эффективных алгоритмов и данных. Вот несколько ключевых методов для оптимизации:

🟠Использование правильных структур данных
Array vs. Set vs. Dictionary: Выбирайте структуру данных в зависимости от задачи. Например, для уникальных элементов и быстрого поиска используйте Set, для пар ключ-значение — Dictionary.
   var array = [1, 2, 3, 4, 5]
var set: Set = [1, 2, 3, 4, 5]
var dictionary = ["one": 1, "two": 2, "three": 3]


🟠Минимизация использования опционалов
Избегайте чрезмерного использования опционалов и принудительного разворачивания, так как это может снижать производительность и приводить к ошибкам.
   var name: String? = "John"
if let unwrappedName = name {
print("Name is \(unwrappedName)")
}


🟠Избегание ненужного копирования
Используйте inout параметры для избежания копирования при передаче значений в функции.
   func increment(value: inout Int) {
value += 1
}
var number = 1
increment(value: &number)


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

🟠Асинхронность и параллелизм
Используйте GCD (Grand Central Dispatch) и OperationQueue для выполнения задач в фоновом режиме.
   DispatchQueue.global(qos: .background).async {
// Фоновая задача
DispatchQueue.main.async {
// Обновление UI на главном потоке
}
}


🟠Lazy Loading
Используйте ленивую загрузку для отложенной инициализации свойств до момента их первого использования.
   class MyClass {
lazy var expensiveObject: ExpensiveObject = {
return ExpensiveObject()
}()
}


🟠Избегание ненужных вычислений
Кэшируйте результаты дорогостоящих вычислений.
   var cache = [Int: Int]()
func fibonacci(_ n: Int) -> Int {
if let result = cache[n] {
return result
}
if n <= 1 { return n }
let result = fibonacci(n - 1) + fibonacci(n - 2)
cache[n] = result
return result
}


🟠Оптимизация циклов
Используйте эффективные конструкции циклов и избегайте лишних операций внутри них.
   for i in 0..<1000 {
// Оптимизированный код
}


🟠Использование Value Types
Структуры (value types) могут быть более эффективными, чем классы (reference types), особенно для небольших объектов.
   struct Point {
var x: Int
var y: Int
}


🟠Избегание глобальных переменных
Глобальные переменные могут приводить к снижению производительности и трудностям с отладкой.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Forwarded from easyoffer
Я боялся, что провалю собеседование. Так появился easyoffer

Когда я только начинал искать первую работу программистом, меня пугала мысль, что я просто не смогу ответить на вопросы на собеседовании.

Типа… ты потратил месяцы на то, чтобы учиться, писал pet-проекты, собирал резюме, рассылаешь отклики — и всё может закончиться на одном-единственном вопросе, на который ты не знаешь ответ.

Я реально боялся.
Я смотрел видео mock-собеседований на YouTube, останавливал каждое, выписывал вопросы в Notion. Потом вручную писал к ним ответы. И потом ещё по нескольку раз перечитывал. Такой вот "тренажёр" на коленке.

📎 (там на картинке — один из моих реальных списков в Notion, ставь 🔥 если тоже так делал)

В какой-то момент я посчитал — у меня уже было выписано больше 500 вопросов. Я почувствовал ужас.
Потому что невозможно всё это зазубрить. А что, если спросят как раз тот, к которому я не успел подготовиться?..

Тогда и пришла идея

А что если понять, какие из вопросов встречаются чаще всего? Чтобы не учить всё подряд, а сфокусироваться на главном.

Так родился easyoffer.

Сначала — просто как пет-проект, чтобы показать в резюме и подготовиться к собесам. А потом оказалось, что он реально помогает людям. За первые месяцы его посетили сотни тысяч человек. И я понял: это больше, чем просто пет-проект.

Сейчас я делаю EasyOffer 2.0
И уже не один, а вместе с вами.

В новой версии будут:
– вопросы из реальных собесов, с фильтрацией по грейду, компании, типу интервью
– тренажёр с карточками (по принципу интервальных повторений — как в Anki)
– база задач с интервью
– тренажёр «реальное собеседование», чтобы отрепетировать как в жизни

Каждая фича упрощает и сокращает время на подготовку. Все эти штуки я бы мечтал иметь, когда сам готовился к собеседованиям.

Я делаю всё на свои деньги. Никаких инвесторов. Только вы и я.

Если вы хотите помочь — сейчас самое важное время.
Краудфандинг уже стартовал. Благодаря нему я смогу привлечь больше людей для разработки, сбору и обработки собеседований.

Все, кто поддержат проект до релиза, получат:

🚀 1 год PRO-доступа по цене месячной подписки. Его можно активировать в любое время, например когда начнете готовится к собесам.
Доступ к закрытому бета-тесту

Поддержать 👉 https://planeta.ru/campaigns/easyoffer

Спасибо, что верите в этот проект 🙌