Swift | Вопросы собесов
2.13K subscribers
28 photos
953 links
Download Telegram
🤔 Знаешь, что относится к value типам помимо структур в свифте?

В Swift, помимо структур (structs), к типам-значениям (value types) также относятся перечисления (enums) и кортежи (tuples).

🟠Структуры (structs)
Структуры в Swift являются типами-значениями. Когда вы создаете копию структуры, вы получаете новый экземпляр со своим собственным набором данных. Изменения в одном экземпляре не влияют на другие экземпляры.
struct Point {
var x: Int
var y: Int
}

var point1 = Point(x: 0, y: 0)
var point2 = point1
point2.x = 10

print(point1.x) // Вывод: 0
print(point2.x) // Вывод: 10


🟠Перечисления (enums)
Перечисления также являются типами-значениями. При копировании экземпляра перечисления создается новый экземпляр с тем же значением.
enum CompassDirection {
case north, south, east, west
}

var direction1 = CompassDirection.north
var direction2 = direction1
direction2 = .south

print(direction1) // Вывод: north
print(direction2) // Вывод: south


🟠Кортежи (tuples)
Кортежи в Swift тоже являются типами-значениями. Кортежи позволяют объединять несколько значений в одну составную единицу. При копировании кортежа создается новый кортеж с теми же значениями.
var tuple1 = (a: 1, b: 2)
var tuple2 = tuple1
tuple2.a = 3

print(tuple1.a) // Вывод: 1
print(tuple2.a) // Вывод: 3


🚩Отличия типов-значений от ссылочных типов

Типы-значения копируются при передаче и присваивании, а ссылочные типы (классы и замыкания) передаются по ссылке. Это важное различие влияет на то, как изменяются данные при передаче между переменными и функциями.

🚩Пример с классами для сравнения

Для сравнения, классы являются ссылочными типами (reference types). При копировании экземпляра класса копируется не сам объект, а ссылка на него. Поэтому изменения в одном экземпляре отражаются на всех его копиях.
class Person {
var name: String
init(name: String) {
self.name = name
}
}

var person1 = Person(name: "John")
var person2 = person1
person2.name = "Doe"

print(person1.name) // Вывод: Doe
print(person2.name) // Вывод: Doe


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

Нет, у unowned ссылок нет собственного счетчика ссылок. Они не увеличивают счетчик объекта, к которому ссылаются. Это означает, что если объект удален из памяти, попытка обращения к unowned ссылке вызовет runtime-ошибку.


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

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

🟠Массивы (Arrays)
Это упорядоченные коллекции элементов, которые хранятся в непрерывной области памяти. Массивы позволяют быстро получать доступ к элементам по индексу.
var numbers: [Int] = [1, 2, 3, 4, 5]
print(numbers[2]) // Вывод: 3


🟠Словари (Dictionaries)
Это коллекции пар "ключ-значение", которые позволяют быстро находить значения по ключу. Ключи в словаре должны быть уникальными.
var capitalCities: [String: String] = ["France": "Paris", "Japan": "Tokyo"]
print(capitalCities["France"]!) // Вывод: Paris


🟠Множества (Sets)
Это неупорядоченные коллекции уникальных элементов. Они полезны, когда необходимо проверить наличие элемента или выполнить операции над множествами, такие как объединение или пересечение.
var uniqueNumbers: Set<Int> = [1, 2, 3, 4, 5, 1]
print(uniqueNumbers) // Вывод: [5, 2, 3, 1, 4]


🟠Связные списки (Linked Lists)
Это последовательности элементов, где каждый элемент содержит ссылку на следующий элемент. Связные списки могут быть односвязными (только вперед) или двусвязными (вперед и назад).
class ListNode {
var value: Int
var next: ListNode?

init(value: Int) {
self.value = value
}
}

let head = ListNode(value: 1)
head.next = ListNode(value: 2)
head.next?.next = ListNode(value: 3)


🟠Стеки (Stacks)
Это структура данных, работающая по принципу "последним пришел - первым ушел" (LIFO, Last In, First Out). Стек поддерживает две основные операции: добавление (push) и удаление (pop) элемента.
var stack: [Int] = []
stack.append(1) // push
stack.append(2)
print(stack.pop()!) // pop, вывод: 2


🟠Очереди (Queues)
Это структура данных, работающая по принципу "первым пришел - первым ушел" (FIFO, First In, First Out). Очередь поддерживает операции добавления (enqueue) и удаления (dequeue) элемента.
var queue: [Int] = []
queue.append(1) // enqueue
queue.append(2)
print(queue.removeFirst()) // dequeue, вывод: 1


🟠Деревья (Trees)
Это иерархическая структура данных, состоящая из узлов, где каждый узел имеет одно родительское и ноль или более дочерних узлов. Наиболее распространенный тип дерева - бинарное дерево, где каждый узел имеет не более двух потомков.
class TreeNode {
var value: Int
var left: TreeNode?
var right: TreeNode?

init(value: Int) {
self.value = value
}
}

let root = TreeNode(value: 1)
root.left = TreeNode(value: 2)
root.right = TreeNode(value: 3)


🟠Графы (Graphs)
Это набор узлов (вершин), соединенных ребрами. Графы могут быть направленными или ненаправленными, взвешенными или невзвешенными.
class GraphNode {
var value: Int
var neighbors: [GraphNode] = []

init(value: Int) {
self.value = value
}
}

let node1 = GraphNode(value: 1)
let node2 = GraphNode(value: 2)
let node3 = GraphNode(value: 3)
node1.neighbors = [node2, node3]
node2.neighbors = [node1]
node3.neighbors = [node1]


🟠Хеш-таблицы (Hash Tables)
Это структура данных, которая реализует словарь с использованием хеш-функции для быстрого доступа к данным по ключу.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
3
🤔 Зачем сделан сайд-таблица (side table)?

Сайд-таблица используется для хранения дополнительной информации об объектах, управляемых системой подсчета ссылок:
1. Счетчик ссылок: хранится для каждого объекта.
2. Другие данные: например, слабые ссылки (weak references) или ассоциированные объекты.
Она позволяет эффективно управлять объектами без увеличения их базового размера.


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

В iOS разработке существует два основных способа управления расположением и размером пользовательского интерфейса: Auto Layout и использование фреймов (frames). Давайте рассмотрим плюсы и минусы каждого из них.

🚩Auto Layout

Плюсы

Адаптивность
Auto Layout позволяет создавать интерфейсы, которые адаптируются к разным размерам экранов и ориентациям устройств. Это особенно важно для поддержки различных устройств, включая iPhone и iPad.

Реакция на изменения
Легко изменять пользовательский интерфейс при изменении содержимого или размера экрана, например, при повороте устройства.

Удобство локализации
Автоматически учитывает изменения размеров элементов интерфейса при переводе приложения на разные языки.

Поддержка динамического типа
Легко адаптирует интерфейс для поддержки различных размеров шрифтов, что важно для доступности.

Гибкость
Позволяет создавать сложные интерфейсы с минимальными усилиями благодаря использованию констрейнтов (constraints).

Минусы

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

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

Версия Xcode
Требует использования более новых версий Xcode для получения всех возможностей и улучшений.

🚩Frames

Плюсы

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

Производительность
Чаще всего более быстрый способ размещения элементов интерфейса, так как не требует вычислений для констрейнтов.

Контроль
Полный контроль над положением и размером каждого элемента интерфейса.

Минусы

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

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

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

Сложные интерфейсы
Создание сложных интерфейсов может быть затруднено и занять много времени.

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

Auto Layout
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
button.widthAnchor.constraint(equalToConstant: 100),
button.heightAnchor.constraint(equalToConstant: 50)
])


Frames
let button = UIButton()
button.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
view.addSubview(button)


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

Кэпчур-лист в замыканиях ([weak self] или [unowned self]) предотвращает образование сильных ссылок на объект. Это разрывает цикл ссылок между замыканием и объектом, позволяя последнему быть корректно освобожденным из памяти.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое 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)


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

1. Если ссылка weak, обращение к объекту вернет nil, так как объект уже освобожден.
2. Если ссылка unowned, произойдет runtime-ошибка, так как unowned не проверяет существование объекта перед доступом.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
Привет, ребята!
1,5 года я учился на программиста, а сайт easyoffer.ru стал моим пет-проектом. Я создавал его, потому что:
а) нужно было добавить хоть какой-нибудь проект в резюме
б) подготовиться к прохождению собесов

И всё получилось! Благодаря еasyoffer я успешно прошёл собеседование и устроился Python Junior-разработчиком на удаленку с зарплатой 115 тысяч рублей.

Однако ещё во время разработки я понял, что у этого проекта есть потенциал. Казалось, что сайт может стать популярным и, возможно, превратиться в стартап.

По-этому я с самого начала заложил в проект минимальную бизнес-модель, на случай, если сайт начнёт набирать трафик. Я предложил пользователям полный доступ к сайту в обмен на подписку на Telegram-каналы. Это позволяло развивать аудиторию, а в будущем — зарабатывать на рекламе.

Результат превзошёл ожидания!
С момента запуска easyoffer посетило 400 тысяч человек. А когда доход с рекламы превысил мою зарплату программиста, я принял решение уйти с работы и полностью посвятить себя разработке новой версии сайта.

Вот так, зайдя в IT, через 4 месяца вышел через свой же пет-проект. Мне очень повезло

Уже год я работаю над easyoffer 2.0.
Это будет более масштабный и качественной новый проект:
– Появится тренажер
– Появятся задачи из собесов
– Фильтрация контента по грейдам
и еще очень много фич, о которых я расскажу позже.

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

А те, кто поддержат проект первыми, получат специальные лимитированные выгодные вознаграждения. Следите за этим телеграм каналом, если хотите стать первыми сапортерами.
🔥3👾1
🤔 Почему приложения под Swift массивные?

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

🟠Статическая связка Swift Runtime
Swift — это относительно новый язык, и его стандартная библиотека не встроена в iOS (как, например, Objective-C runtime). Это значит, что при компиляции приложения в его бинарь включаются стандартные Swift-библиотеки.

🟠Bitcode и архитектуры (Fat Binary)
При публикации в App Store, Xcode компилирует приложение для нескольких архитектур (arm64, armv7, x86_64). Это называется Fat Binary — один исполняемый файл включает версии для разных процессоров.

🟠Swift ABI Stability – улучшение, но не панацея
С версии Swift 5.0 ABI (Application Binary Interface) стабилизирован. Это означает, что в iOS 12.2+ уже есть встроенные Swift-библиотеки.

🟠Использование SwiftUI и Combine
SwiftUI и Combine — новые технологии, они не так оптимизированы, как UIKit. При их использовании код разрастается за счёт декларативного подхода и дополнительной логики от Apple.

🟠Дополнительные ресурсы и Assets
Если приложение использует локализацию, изображения, шрифты, CoreML, ARKit, это тоже увеличивает размер .ipa.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Можем ли на переменную "повесить" Synchronized?

1. Нельзя использовать synchronized напрямую на переменной.
2. Однако переменная может быть защищена с использованием синхронизированного блока или метода.
3. Например, synchronized(this) { sharedVariable = value; }.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4
🤔 Как бы реализовал словарь в 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


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

1. Object — базовый класс для всех классов в Java.
2. Он предоставляет базовые методы, такие как toString(), hashCode(), equals(), clone().
3. Это корневой элемент иерархии классов, от которого наследуются все остальные классы.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6🤔4👀2
Forwarded from easyoffer
Ищу работу пол года

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

Честно говоря, искать работу полгода — это нонсенс. Очевидно, что человек делает что-то не так. Главная ошибка, которую совершают многие, — это создание иллюзии поиска работы.

То есть человек вроде бы ищет работу, но делает это неэффективно, тратя время на нецелевые действия. Например:

Просматривает вакансии перед откликом.
Пытается понять, подходит ли он под вакансию. Если считает, что не подходит — не откликается.
Пишет сопроводительные письма (иногда даже уникальные под каждую вакансию).
Заполняет анкеты, проходит тесты.

Все эти действия отнимают время, но не приводят к результату.

Почему это не работает?

HR-менеджер не может вручную отсмотреть 2000 откликов, оценить каждое резюме и прочитать сопроводительные письма. Поэтому компании используют ATS-системы (системы автоматического подбора), которые анализируют резюме и определяют процент его соответствия вакансии.

Что делать, чтобы повысить шансы?

1️⃣ Добавить ключевые навыки в резюме — и в основной текст, и в теги. Возьмите их с easyoffer.ru

2️⃣ Убрать нерелевантный опыт, оставить только подходящий.

3️⃣ Оформить опыт так, чтобы он выглядел релевантным. Если у вас его нет, укажите проекты, стажировки или другой опыт, который можно представить как работу от 1 года. Если опыт слишком большой, сузьте его до 6 лет.

4️⃣ Откликаться на все вакансии без разбору. Если вы Junior, не ищите только стажер или Junior-вакансии — пробуйте везде. Не отказывайте себе сами, пусть это решит HR

5️⃣ Сделать резюме публичным, потому что HR-менеджеры часто ищут кандидатов не только среди откликов, но и в базе резюме.

6️⃣ Используйте ИИ по минимуму – ATS-системы считывают это и помечают "сгенерировано ИИ"

‼️ Главное правило: чем больше откликов — тем выше шанс получить оффер. Делайте резюме удобным для ATS-систем, и вас заметят.

1. Посмотрите видео о том как я вывел свою резюме в Топ1 на HH
2. Посмотрите видео как я нашел первую работу
3. Прочитайте этот кейс про оптимизацию резюме

Если прям вообще тяжело.

Создайте несколько разных резюме. Создайте 2, 3 да хоть 10 резюме. Настройте авто-отлики и ждите приглашения на собесы.

Не нужно создавать иллюзию поиска работы, сделайте несколько простых и актуальных действий.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какие знаешь способы внедрения зависимостей?

Внедрение зависимостей (Dependency Injection, DI) в iOS-приложениях позволяет сделать код более модульным, тестируемым и поддерживаемым. Рассмотрим основные способы внедрения зависимостей в Swift.

🟠Внедрение через инициализатор (Initializer Injection)
Это самый распространенный и рекомендуемый способ. Зависимости передаются в объект через его инициализатор.
protocol NetworkServiceProtocol {
func fetchData()
}

class NetworkService: NetworkServiceProtocol {
func fetchData() {
print("Данные загружены")
}
}

// Класс, которому нужна зависимость
class ViewModel {
private let networkService: NetworkServiceProtocol

init(networkService: NetworkServiceProtocol) {
self.networkService = networkService
}

func loadData() {
networkService.fetchData()
}
}

// Использование
let networkService = NetworkService()
let viewModel = ViewModel(networkService: networkService)
viewModel.loadData()


🟠Внедрение через свойства (Property Injection)
Зависимость передается через свойство класса.
class ViewModel {
var networkService: NetworkServiceProtocol?

func loadData() {
networkService?.fetchData()
}
}

// Использование
let viewModel = ViewModel()
viewModel.networkService = NetworkService()
viewModel.loadData()


🟠Внедрение через метод (Method Injection)
Зависимость передается непосредственно в метод, который её использует.
class ViewModel {
func loadData(with networkService: NetworkServiceProtocol) {
networkService.fetchData()
}
}

// Использование
let viewModel = ViewModel()
let networkService = NetworkService()
viewModel.loadData(with: networkService)


🟠Использование Service Locator (Антипаттерн)
Класс сам запрашивает зависимость у глобального локатора.
class ServiceLocator {
static let shared = ServiceLocator()

private var services: [String: Any] = [:]

func register<T>(_ service: T) {
let key = String(describing: T.self)
services[key] = service
}

func resolve<T>() -> T? {
let key = String(describing: T.self)
return services[key] as? T
}
}

// Регистрация зависимостей
let locator = ServiceLocator.shared
locator.register(NetworkService() as NetworkServiceProtocol)

// Использование
class ViewModel {
func loadData() {
let networkService: NetworkServiceProtocol? = ServiceLocator.shared.resolve()
networkService?.fetchData()
}
}


🟠Использование DI-контейнеров (например, Swinject)
Специальные библиотеки помогают управлять зависимостями.
import Swinject

let container = Container()
container.register(NetworkServiceProtocol.self) { _ in NetworkService() }

class ViewModel {
private let networkService: NetworkServiceProtocol

init(networkService: NetworkServiceProtocol) {
self.networkService = networkService
}

func loadData() {
networkService.fetchData()
}
}

// Разрешение зависимости через контейнер
let networkService = container.resolve(NetworkServiceProtocol.self)!
let viewModel = ViewModel(networkService: networkService)
viewModel.loadData()


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

1. Если синхронизация применяется к блоку внутри метода, монитор захватывается для указанного объекта.
2. Например, synchronized(this) блокирует текущий объект, а synchronized(ClassName.class) — класс.
3. Монитор защищает только код внутри синхронизированного блока.


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

Слабые ссылки (weak references) играют важную роль в управлении памятью, особенно когда нужно предотвратить циклы сильных ссылок (retain cycles) и утечки памяти.

🚩Основные причины использования

🟠Предотвращение циклов сильных ссылок
Циклы сильных ссылок возникают, когда два объекта держат сильные ссылки друг на друга, что препятствует их освобождению из памяти. Слабые ссылки разрывают этот цикл, позволяя одному из объектов освобождаться.
class Person {
var name: String
weak var friend: Person?
init(name: String) {
self.name = name
}
}

var alice: Person? = Person(name: "Alice")
var bob: Person? = Person(name: "Bob")

alice?.friend = bob
bob?.friend = alice

alice = nil // Теперь объекты могут быть освобождены
bob = nil


🟠Избежание утечек памяти
Утечки памяти происходят, когда объекты, которые больше не нужны, не освобождаются из памяти. Слабые ссылки помогают избежать этих утечек, обеспечивая правильное освобождение памяти. Делегаты часто объявляются как слабые ссылки, чтобы избежать утечек памяти.
protocol TaskDelegate: AnyObject {
func taskDidFinish()
}

class Task {
weak var delegate: TaskDelegate?
func complete() {
delegate?.taskDidFinish()
}
}

class ViewController: TaskDelegate {
var task = Task()
init() {
task.delegate = self
}

func taskDidFinish() {
print("Task finished")
}
}


🟠Управление временными зависимостями
Слабые ссылки удобны для временных зависимостей, когда объект не должен удерживаться в памяти, если нет других сильных ссылок. Использование слабых ссылок для временных объектов.
class Cache {
weak var temporaryObject: SomeClass?
}

class SomeClass {
// Код класса
}

var cache = Cache()
var object = SomeClass()
cache.temporaryObject = object
object = SomeClass() // Старый объект удаляется, так как на него нет сильных ссылок


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

Предотвращение циклов ссылок
Основное преимущество слабых ссылок заключается в их способности разрывать циклы ссылок, предотвращая утечки памяти.
Обеспечение корректного управления памятью
Слабые ссылки позволяют объектам освобождаться из памяти, когда на них больше нет сильных ссылок, что улучшает управление ресурсами.
Гибкость и безопасность
Использование слабых ссылок обеспечивает более гибкое и безопасное управление зависимостями между объектами.
Сложности управления
Необходимо учитывать, что слабые ссылки могут стать nil в любой момент, поэтому требуется дополнительная проверка.
Понимание жизненного цикла объектов
Требуется хорошее понимание жизненного цикла объектов и управления памятью, чтобы правильно использовать слабые ссылки.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Для чего нужен volatile?

1. Модификатор volatile используется для указания, что значение переменной должно всегда читаться из основной памяти, а не из кеша потока.
2. Это гарантирует видимость изменений переменной между потоками.
3. Однако volatile не обеспечивает атомарность операций, таких как инкремент или декремент.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯5😁1
🤔 Если обозначить внутри метода Synchronized , что будет монитору?

Это высокоуровневый механизм синхронизации, который объединяет взаимное исключение (mutex) и условные переменные (condition variables) для управления доступом к объектам в многопоточной среде.

🚩Как работает

🟠Взаимное исключение (Mutual Exclusion)
Только один поток может выполнить защищенный блок кода в любой момент времени.
🟠Условные переменные (Condition Variables)
Позволяют потокам ожидать определенных условий, а другим потокам уведомлять их о наступлении этих условий.

🚩Примеры

class ThreadSafeClass {
private var internalState = 0
private let queue = DispatchQueue(label: "com.example.threadSafeQueue")

func increment() {
queue.sync {
internalState += 1
}
}

func getState() -> Int {
return queue.sync {
internalState
}
}
}


С NSLock
class ThreadSafeClass {
private var internalState = 0
private let lock = NSLock()

func increment() {
lock.lock()
internalState += 1
lock.unlock()
}

func getState() -> Int {
lock.lock()
let state = internalState
lock.unlock()
return state
}
}


С objc_sync_enter и objc_sync_exit
class ThreadSafeClass: NSObject {
private var internalState = 0

func increment() {
objc_sync_enter(self)
internalState += 1
objc_sync_exit(self)
}

func getState() -> Int {
objc_sync_enter(self)
let state = internalState
objc_sync_exit(self)
return state
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что делает Synchronized?

1. Ключевое слово synchronized в Java обеспечивает доступ к критической секции кода только одному потоку одновременно.
2. Оно используется для синхронизации методов или блоков кода, защищая общий ресурс от конкурентного доступа.
3. Гарантирует целостность данных в многопоточных приложениях, но может снизить производительность из-за блокировок.


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