Swift | Вопросы собесов
2.13K subscribers
28 photos
943 links
Download Telegram
Что такое Auto Layout ?
Спросят с вероятностью 55%

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

Ограничения (constraints) описывают отношения между элементами интерфейса и между элементами интерфейса и родительским контейнером. Эти отношения могут включать размеры, положение и другие атрибуты визуальных элементов. Можно задать эти ограничения программно на Swift или визуально с использованием Interface Builder в Xcode.

Примеры ограничений:
Элемент A должен быть на 20 пунктов от верхней границы родительского представления.
Ширина элемента B должна быть равна половине ширины родительского представления.
Элемент C должен быть центрирован относительно родительского представления по горизонтали.

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

Преимущества:
Адаптивность: Интерфейс автоматически адаптируется под различные размеры экранов и ориентации.
Динамичность: Интерфейс может автоматически реагировать на изменения контента, например, при локализации или изменении контента в реальном времени.
Удобство поддержки: Меньше необходимости в создании специфических решений для разных устройств или ориентаций, что упрощает поддержку и обновление приложения.

Недостатки:
Сложность: Для новичков может быть сложным понять и правильно использовать все возможности и особенности.
Производительность: В сложных интерфейсах с большим количеством ограничений может наблюдаться снижение производительности, особенно при динамическом изменении интерфейса.

Auto Layout — это система для создания динамических и адаптивных интерфейсов, основанная на ограничениях, которая позволяет элементам интерфейса автоматически изменять свои размеры и положение в зависимости от условий экрана.

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Чем отличается rebase от merge ?
Спросят с вероятностью 18%

Rebase и merge — это две различные операции в системах управления версиями, которые используются для интеграции изменений из одной ветки в другую. Они обеспечивают разные подходы к разрешению истории коммитов в процессе разработки программного обеспечения.

1️⃣Цель использования:
Merge (слияние): Сохраняет историю обеих веток. Он создает новый коммит, который объединяет два родительских коммита. История веток остается расходящейся, что отражает параллельную работу в ветках.
Rebase (перебазирование): Переносит коммиты из одной ветки в начало другой, таким образом, изменяя базу (начало) ветки. Это делает историю проекта более линейной и понятной, так как вся история кажется последовательной.

2️⃣Визуальное представление истории:
Merge: История сохраняет все точки ветвления и слияния, делая её многообразной и, порой, сложной для понимания.
Rebase: Стремится к линейной истории, что упрощает анализ и отладку истории коммитов.

3️⃣Конфликты и их разрешение:
Merge: Конфликты разрешаются в момент слияния, и результат фиксируется в специальном коммите слияния.
Rebase: Конфликты нужно разрешать для каждого коммита по отдельности во время перебазирования. Это может быть более трудоемко, если коммитов много.

4️⃣Безопасность истории:
Merge: Считается более безопасным с точки зрения сохранности истории, так как не изменяет существующие коммиты.
Rebase: Изменяет историю, что может быть опасно для совместной работы, особенно если перебазируемые коммиты уже были отправлены в общий репозиторий. Использование rebase в таких случаях может привести к сложностям для других участников проекта, которые могут потерять свои локальные изменения.

5️⃣Применение:
Merge: Часто используется для внесения изменений из главной ветки в текущую рабочую ветку или для финального слияния ветки фичи в основную ветку разработки.
Rebase: Предпочтительнее использовать для обновления текущей рабочей ветки относительно базовой (например, основной) ветки перед выполнением merge запроса в эту основную ветку.

Пример:

Merge:
git checkout main
git merge feature-branch


Rebase:
git checkout feature-branch
git rebase main
# Затем можно выполнить merge:
git checkout main
git merge feature-branch


Выбор между merge и rebase зависит от конкретной ситуации и предпочтений команды. Rebase может помочь поддерживать чистоту истории, но требует осторожности при использовании в общих ветках. Merge сохраняет полную историю, но может создать сложную сеть коммитов, которую труднее понимать.

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍6
Кто обрабатывает тач и как и куда он проходит ?
Спросят с вероятностью 18%

Процесс обработки тача (касания экрана) включает несколько этапов и компонентов операционной системы и приложений. Рассмотрим процесс на примере iOS, так как он является хорошо документированным и понятным примером обработки сенсорных входов в современных мобильных операционных системах.

Этапы обработки тача:

1️⃣Аппаратный уровень
Когда пользователь касается сенсорного экрана устройства, сенсор экрана обнаруживает физическое прикосновение. Эта информация в виде сырых данных (координаты касания, сила прикосновения, если поддерживается) передается операционной системе.

2️⃣Операционная система
Обрабатывает эти входные данные на уровне операционной системы с помощью драйверов устройства ввода. ОС интерпретирует сырые данные касания и преобразует их в более высокоуровневые события, такие как начало касания, перемещение, окончание касания и отмена.

3️⃣UIApplication и UIWindow
Преобразованные события касания передаются в приложение через объект UIApplication. Далее UIApplication маршрутизирует события в главное окно приложения (UIWindow), которое в свою очередь начинает распределение события по цепочке респондеров.

4️⃣Цепочка респондеров (Responder Chain)
Это механизм, с помощью которого события (не только тачи, но и другие, например, жесты и нажатия кнопок) передаются от первого респондера (обычно UIView, который пользователь коснулся) к следующим респондерам. Событие касания передается от вида к его родителю и так далее вверх по иерархии видов, пока не будет обработано или не достигнет самого верха иерархии.

5️⃣Обработка в UIView и UIViewController
Может обработать событие касания. Это делается путем переопределения методов, таких как touchesBegan(_:with:), touchesMoved(_:with:), touchesEnded(_:with:) и touchesCancelled(_:with:).

6️⃣Реакция на касание
После обработки события соответствующие компоненты интерфейса могут изменить свое состояние или внешний вид (например, кнопка может изменить цвет при нажатии) и выполнить необходимые действия (например, открыть новый экран или изменить данные).

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍5
Как устроена память ?
Спросят с вероятностью 55%

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

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

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

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

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

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

Управление памятью

Операционная система и среда выполнения Swift автоматически управляют памятью, используя счетчик ссылок (ARC - Automatic Reference Counting) для отслеживания и управления жизненным циклом объектов в памяти. ARC автоматически освобождает память, когда на объект больше нет активных ссылок, предотвращая таким образом утечки памяти и переполнение памяти.

Память устройства устроена в виде иерархии, включающей регистры процессора, кэш, ОЗУ и ПЗУ. Автоматически управляют памятью через систему ARC, которая помогает предотвращать утечки памяти, освобождая память объектов, на которые больше нет ссылок.

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Где хранятся типы данных ?
Спросят с вероятностью 18%

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

1️⃣Стек (Stack)
Хранение: Локальные переменные, параметры функций и управляющая информация вызовов функций (например, адреса возврата).
Особенности: Область памяти стека управляется автоматически. В стеке данные хранятся и удаляются в порядке LIFO (Last In, First Out). Это означает, что последний сохраненный элемент будет первым извлеченным. Стек быстр, но его размер обычно ограничен.

2️⃣Куча (Heap)
Хранение: Динамически выделенные данные, такие как объекты и массивы, которые создаются во время выполнения программы с помощью операций выделения памяти (например, new в C++ или malloc).
Особенности: Управление памятью в куче требует больше ручной работы по сравнению со стеком, хотя в некоторых языках, таких как Java и C#, существует автоматическая сборка мусора. Куча позволяет хранить данные с неопределенным или изменяющимся сроком жизни.

3️⃣Статическая память (Static or Global Memory)
Хранение: Глобальные переменные, статические переменные.
Особенности: Данные в этой области памяти существуют на протяжении всего времени выполнения программы и инициализируются перед выполнением основной части программы.

4️⃣Код программы (Text or Code Segment)
Хранение: Бинарный код вашей программы, включая все функции и процедуры.
Особенности: Эта область памяти обычно защищена от записи, чтобы предотвратить изменение исполняемого кода программы.

5️⃣Память регистров (Registers)
Хранение: Небольшие количества данных и инструкции, которые непосредственно обрабатываются процессором.
Особенности: Регистры предлагают самый быстрый доступ к данным, по сравнению с любой другой областью памяти, но их количество и размер ограничены.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
1👍1
Какие есть типы данных ?
Спросят с вероятностью 18%

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

1️⃣Примитивные типы данных
Это основные типы, которые напрямую оперируют на низком уровне аппаратных ресурсов. Они включают в себя:

Целочисленные типы (Integer types): int, short, long, byte и так далее, которые могут быть как знаковыми, так и беззнаковыми.
Вещественные типы (Floating-point types): float, double, которые используются для представления чисел с плавающей точкой.
Символьные типы (Character types): char, предназначенные для хранения отдельных символов.
Логический тип (Boolean type): bool, принимающий значения true или false.

2️⃣Составные (комплексные) типы данных
Позволяют группировать множество элементов, возможно разных типов, в единую структуру. К ним относятся:

Массивы (Arrays): Коллекция элементов одного типа, расположенных последовательно в памяти.
Структуры (Structures): В языках C, C++, Swift и других можно определять struct, которые группируют различные элементы данных под одним именем.
Классы (Classes): Определяют типы, которые включают в себя как данные, так и функции для работы с этими данными, поддерживая парадигму объектно-ориентированного программирования.
Кортежи (Tuples): Коллекция элементов, которые могут быть разных типов. Кортежи используются для временного группирования связанных значений.

3️⃣Специализированные типы данных
Эти типы данных предназначены для выполнения специфических задач и могут варьироваться в зависимости от языка программирования:

Перечисления (Enumerations): Определяют переменную, которая может иметь одно из предопределенных значений.
Ссылочные типы (Reference types): В языках, поддерживающих ссылки (например, в C++), это могут быть указатели на другие переменные или объекты.
Множества (Sets): Коллекция уникальных элементов.
Словари (Dictionaries или Maps): Коллекции пар ключ-значение, где каждый ключ уникален.

4️⃣Абстрактные типы данных
Это концептуальные модели, которые определяют поведение данных:

Стек (Stack): Структура данных типа LIFO (Last In, First Out).
Очередь (Queue): Структура данных типа FIFO (First In, First Out).
Связанные списки (Linked Lists): Коллекция узлов, где каждый узел содержит элемент данных и ссылку на следующий узел в списке.
Деревья (Trees), графы (Graphs) и другие.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
🤔2👍1
Что такое value types ?
Спросят с вероятностью 55%

Типы значений (value types) — это типы данных, экземпляры которых хранят непосредственно своё значение. В отличие от ссылочных типов (reference types), которые хранят ссылку на место в памяти, где фактически расположено значение, типы значений при присваивании или передаче в функции копируются. Это означает, что каждый экземпляр типа значения имеет собственную копию данных, и изменение одного экземпляра не влияет на другой.

Типы значений включают в себя:
Структуры (struct)
Перечисления (enum)
Базовые типы данных, такие как Int, Double, String, и Bool.

Пример:
var a = 5
var b = a
b += 5
print(a) // Выведет 5
print(b) // Выведет 10

В этом примере a и b являются типами значений. Когда мы присваиваем b = a, создается копия значения a, и изменения b не влияют на a.

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

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

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
1
🤔 Какая из функций Swift позволяет отложить выполнение кода до выхода из текущего контекста?
Anonymous Quiz
7%
dispatch_async
64%
defer
14%
asyncAfter
15%
await
Какая диспетчеризация используется для Extension-ов ?
Спросят с вероятностью 18%

Механизм, который используется для вызова методов, добавленных через расширения (extensions), называется статической диспетчеризацией. Это означает, что вызов метода, определенного в расширении, решается на этапе компиляции, а не во время выполнения программы.

Статическая диспетчеризация

Означает, что компилятор заранее определяет, какой метод будет вызван. Это приводит к следующим особенностям:

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

2️⃣Предсказуемость: Статическая диспетчеризация делает поведение программы более предсказуемым, так как вы точно знаете, какой метод будет вызван, без влияния возможных изменений в иерархии классов или переопределений методов.

3️⃣Ограничения на переопределение: Методы, добавленные через расширения, не могут быть переопределены потомками типа, к которому они добавляются. Это означает, что если вы добавляете метод к протоколу через расширение, и этот метод затем реализуется в классе, который соответствует этому протоколу, вызов этого метода через экземпляр класса будет использовать реализацию из класса, а не из расширения.
protocol MyProtocol {
func defaultMethod()
}

extension MyProtocol {
func defaultMethod() {
print("Called from protocol extension")
}
}

class MyClass: MyProtocol {
func defaultMethod() {
print("Called from class implementation")
}
}

let myInstance: MyProtocol = MyClass()
myInstance.defaultMethod() // Вывод: "Called from class implementation"


В этом примере, хотя myInstance типизирован как MyProtocol, метод defaultMethod вызывается из реализации в классе MyClass, а не из расширения протокола, благодаря статической диспетчеризации, которая определяется во время компиляции.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍2🔥1
Как ловить утечки памяти ?
Спросят с вероятностью 18%

Утечки памяти могут стать серьезной проблемой, особенно в больших и сложных приложениях. Они происходят, когда выделенная память не освобождается, даже если она больше не используется. Существуют различные инструменты и техники для обнаружения и устранения утечек памяти.

1️⃣Инструменты профайлинга
Большинство современных сред разработки (IDE) и платформ предоставляют инструменты для профайлинга памяти:

Xcode Instruments (для iOS и macOS): Используйте инструмент "Leaks" для обнаружения утечек памяти в приложениях на базе iOS или macOS. Он может помочь выявить не только утечки, но и другие проблемы, связанные с памятью, такие как чрезмерное использование памяти и зацикливание ссылок.
Android Studio Profiler: Для Android-разработчиков Android Studio предлагает инструменты для мониторинга использования памяти приложениями, выявления утечек и анализа содержимого кучи.
Valgrind: Это мощный инструмент анализа памяти для программ на C и C++. Он помогает обнаруживать утечки памяти, неправильное использование памяти и другие связанные с памятью ошибки.
Visual Studio Diagnostic Tools: Для разработчиков на C# и .NET Visual Studio предлагает инструменты диагностики, которые включают профайлеры памяти и производительности.

2️⃣Код-ревью и лучшие практики
Помогает выявить потенциальные утечки памяти до того, как код будет запущен:

Избегайте зацикленных ссылок, особенно в языках, поддерживающих автоматический подсчет ссылок, таких как Swift и Objective-C.
Используйте слабые (weak) и неуправляемые (unowned) ссылки для предотвращения сильных ссылочных циклов.
В C++ используйте умные указатели (std::unique_ptr, std::shared_ptr) для автоматического управления памятью.

3️⃣Статические анализаторы кода
Могут обнаруживать утечки памяти на этапе разработки:

Clang Static Analyzer для C и Objective-C.
Cppcheck, Coverity и другие для C++.
SonarQube для различных языков программирования.

4️⃣Юнит-тестирование
Проверяют не только функциональность, но и производительность и управление памятью:

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

5️⃣Регулярный мониторинг и логирование
Для серверных и долгоживущих приложений регулярно мониторьте использование памяти и логируйте информацию о состоянии системы:

Используйте системы мониторинга, такие как Prometheus, для отслеживания метрик памяти в продакшн.
Логируйте предупреждения, если использование памяти превышает ожидаемые пороги.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
1
Что такое reference types ?
Спросят с вероятностью 55%

Ссылочные типы (reference types)
— это типы данных, экземпляры которых хранят не само значение, а ссылку на область в памяти, где это значение расположено. Это означает, что при присваивании переменной или передаче аргумента функции копируется не само значение, а ссылка на него. В результате, если вы измените данные в одном месте через одну переменную, изменения отразятся и на всех других переменных, которые ссылаются на это же место в памяти.

Ссылочные типы включают:
Классы (class)

Пример:
class MyClass {
var number: Int
init(number: Int) {
self.number = number
}
}

var a = MyClass(number: 5)
var b = a
b.number = 10

print(a.number) // Выведет 10
print(b.number) // Также выведет 10

В этом примере a и b ссылаются на один и тот же экземпляр класса MyClass. Изменение b.number приводит к изменению a.number, поскольку обе переменные ссылаются на один и тот же объект в памяти.

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

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

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
🤔 Что будет результатом вызова метода filter на массиве, если ни один элемент не соответствует критерию?
Anonymous Quiz
17%
nil
69%
пустой массив
11%
исходный массив
3%
генерируется ошибка
Какие ссылки есть у нас изначально ?
Спросят с вероятностью 18%

Обычно обсуждаются два основных типа ссылок: сильные (strong) и слабые (weak) ссылки. В некоторых контекстах также упоминаются неуправляемые (unowned) и мягкие (soft) ссылки. Давайте рассмотрим каждый тип ссылок подробнее, чтобы лучше понять их природу и использование.

1️⃣Сильные ссылки (Strong References)
Определение: Сильные ссылки — это самый обычный тип ссылок, который не только указывает на объект, но и активно удерживает его в памяти. Пока на объект существует хотя бы одна сильная ссылка, объект не будет уничтожен сборщиком мусора (в языках с автоматическим управлением памятью) или останется валидным (в языках с ручным управлением памятью).
Использование: В большинстве случаев используются сильные ссылки, когда нужно гарантировать, что объект остается в памяти в течение всего времени его необходимости.

2️⃣Слабые ссылки (Weak References)
Определение: Слабые ссылки не удерживают объект в памяти. Если на объект нет других сильных ссылок, он будет уничтожен, даже если на него указывают слабые ссылки. В момент уничтожения объекта все слабые ссылки автоматически становятся nil или null, что предотвращает появление "висячих" ссылок.
Использование: Слабые ссылки часто используются для разрешения циклов сильных ссылок в объектных графах, например, когда два объекта взаимно ссылаются друг на друга.

3️⃣Неуправляемые ссылки (Unowned References)
Определение: Неуправляемые ссылки похожи на слабые, но они не обнуляются, когда объект уничтожается. Это означает, что они могут указывать на уже освобожденную память, что опасно.
Использование: Неуправляемые ссылки используются, когда вы уверены, что ссылка будет использоваться только пока существует объект. Их использование требует осторожности, чтобы избежать ошибок доступа к памяти.

4️⃣Мягкие ссылки (Soft References) (применимо к Java)

Определение: Мягкие ссылки в Java автоматически удаляются, если JVM (Java Virtual Machine) нужно освободить память. Мягкие ссылки удерживают объект в памяти, пока есть достаточно памяти.
Использование: Обычно мягкие ссылки используются для реализации кэшей.

Пример:
class Person {
let name: String
init(name: String) { self.name = name }
deinit { print("\(name) is being deinitialized") }
}

var reference1: Person?
var reference2: Person?
var reference3: Person?

reference1 = Person(name: "John Doe") // Сильная ссылка
reference2 = reference1 // Еще одна сильная ссылка
reference3 = reference1 // Еще одна сильная ссылка

reference1 = nil
reference2 = nil


reference3 = nil // Объект уничтожается только после удаления последней сильной ссылки


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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
2🔥1🤔1
Что такое cherrypick ?
Спросят с вероятностью 18%

"cherry-pick" означает выборочное применение одного или нескольких коммитов из одной ветки кода в другую ветку. Это особенно полезно, когда вам нужно внести определённые изменения из одной ветки в другую, но не нужно переносить все изменения.

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

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

Пример:
git checkout master      # Переключитесь на ветку master
git cherry-pick <commit> # Примените коммит из ветки feature

Здесь <commit> — это идентификатор коммита (например, хеш), который вы хотите "поднять" и применить к ветке master.

Причины его использовать
1️⃣Изолированные исправления: Если вы обнаружили ошибку, которая была исправлена в одной ветке, и вам нужно быстро применить это исправление в другую ветку (например, из development в production), cherry-pick позволяет это сделать без переноса других изменений.
2️⃣Конфликты: В процессе него могут возникнуть конфликты, особенно если существующие изменения в целевой ветке не совместимы с изменениями в его коммите. Эти конфликты необходимо разрешить вручную.
3️⃣Контроль: Дает более тонкий контроль над тем, какие именно изменения вы хотите внести в ветку, что удобно в больших и сложных проектах.

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

Cherry-picking — мощный инструмент, но его следует использовать осторожно и с пониманием потенциальных последствий для управления проектом и истории изменений.

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
2
🤔 Какой из следующих вариантов используется для создания однократного экземпляра класса в Swift?
Anonymous Quiz
92%
Singleton
4%
SharedInstance
2%
OnlyInstance
3%
UniqueInstance
Какие паттерны есть ?
Спросят с вероятностью 55%

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

Порождающие паттерны (Creational Patterns)
Упрощают процесс создания объектов, делая систему независимой от способа создания, компоновки и представления объектов.
Одиночка (Singleton): Обеспечивает наличие только одного экземпляра класса и предоставляет к нему глобальный доступ.
Фабричный метод (Factory Method): Определяет интерфейс для создания объекта, но позволяет подклассам изменять тип создаваемых объектов.
Абстрактная фабрика (Abstract Factory): Позволяет создавать семейства связанных или зависимых объектов без указания их конкретных классов.
Прототип (Prototype): Позволяет копировать существующие объекты без делания кода зависимым от их классов.
Строитель (Builder): Позволяет создавать сложные объекты пошагово, используя один и тот же код для создания различных представлений объектов.

Структурные паттерны (Structural Patterns)
Описывают, как объединять объекты и классы в более крупные структуры.
Адаптер (Adapter): Позволяет объектам с несовместимыми интерфейсами работать вместе.
Мост (Bridge): Разделяет один или несколько классов на две отдельные иерархии — абстракцию и реализацию, позволяя им изменяться независимо друг от друга.
Композит (Composite): Позволяет группировать множество объектов в древовидную структуру, и работать с этой структурой так, как будто это единственный объект.
Декоратор (Decorator): Позволяет динамически добавлять новые функции объектам, помещая их в объекты-обёртки.
Фасад (Facade): Предоставляет простой интерфейс к сложной системе классов, библиотеке или фреймворку.

Поведенческие паттерны (Behavioral Patterns)
Регулируют эффективное взаимодействие и распределение обязанностей между объектами.
Наблюдатель (Observer): Позволяет объектам получать уведомления об изменениях в других объектах.
Стратегия (Strategy): Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми.
Состояние (State): Позволяет объекту изменять своё поведение в зависимости от его состояния.
Команда (Command): Превращает запросы в объекты, позволяя передавать их как аргументы при вызове методов, ставить их в очередь, логировать и т.д.
Цепочка обязанностей (Chain of Responsibility): Позволяет передавать запросы последовательно по цепочке обработчиков, пока один из них не обработает запрос.
Посредник (Mediator): Позволяет уменьшить взаимосвязь между классами, вынося межклассовые взаимодействия в класс-посредник.
Итератор (Iterator): Даёт возможность последовательно обходить элементы составных объектов, не раскрывая их внутреннего представления.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
1👍1