Что такое cherrypick ?
Спросят с вероятностью 18%
"cherry-pick" означает выборочное применение одного или нескольких коммитов из одной ветки кода в другую ветку. Это особенно полезно, когда вам нужно внести определённые изменения из одной ветки в другую, но не нужно переносить все изменения.
Как он работает
Допустим, у вас есть две ветки в вашем репозитории:
Пример:
Здесь
Причины его использовать
1️⃣Изолированные исправления: Если вы обнаружили ошибку, которая была исправлена в одной ветке, и вам нужно быстро применить это исправление в другую ветку (например, из
2️⃣Конфликты: В процессе него могут возникнуть конфликты, особенно если существующие изменения в целевой ветке не совместимы с изменениями в его коммите. Эти конфликты необходимо разрешить вручную.
3️⃣Контроль: Дает более тонкий контроль над тем, какие именно изменения вы хотите внести в ветку, что удобно в больших и сложных проектах.
Недостатки:
✅Управление историей: Может привести к запутанной истории коммитов, особенно если одни и те же изменения применяются в различных ветках. Это может усложнить отладку и отслеживание изменений.
✅Риск конфликтов: Может вызвать конфликты, которые нужно будет решать вручную, и это может стать проблемой в больших проектах с множеством активных веток.
Cherry-picking — мощный инструмент, но его следует использовать осторожно и с пониманием потенциальных последствий для управления проектом и истории изменений.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 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
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 разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 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
Forwarded from Идущий к IT
10$ за техническое собеседование на английском языке:
1. Отправьте запись технического собеседования на английском языке файлом на этот аккаунт
2. Добавьте ссылку на вакансию или пришлите название компании и должность
3. Напишите номер кошелка USDT (Tether) на который отправить 10$
🛡 Важно:
– Запись будет использована только для сбора данных о вопросах
– Вы останетесь анонимны
– Запись нигде не будет опубликована
🤝 Условия:
– Внятный звук, различимая речь
– Допустимые профессии:
• Любые программисты
• DevOps
• Тестировщики
• Дата сайнтисты
• Бизнес/Системные аналитики
• Прожекты/Продукты
• UX/UI и продукт дизайнеры
1. Отправьте запись технического собеседования на английском языке файлом на этот аккаунт
2. Добавьте ссылку на вакансию или пришлите название компании и должность
3. Напишите номер кошелка USDT (Tether) на который отправить 10$
– Запись будет использована только для сбора данных о вопросах
– Вы останетесь анонимны
– Запись нигде не будет опубликована
– Внятный звук, различимая речь
– Допустимые профессии:
• Любые программисты
• DevOps
• Тестировщики
• Дата сайнтисты
• Бизнес/Системные аналитики
• Прожекты/Продукты
• UX/UI и продукт дизайнеры
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5👾1
Как происходит механизм обработки нажатий ?
Спросят с вероятностью 18%
Механизм обработки нажатий в пользовательских интерфейсах операционных систем и приложений включает в себя несколько ключевых этапов, которые обеспечивают реакцию системы на действия пользователя. Рассмотрим общий процесс на примере смартфонов и десктопных операционных систем:
1️⃣События ввода от устройств
Всё начинается с событий ввода, которые генерируются устройствами ввода, такими как сенсорные экраны, мыши или трекпады. Когда пользователь нажимает на экран или кликает мышью, устройство ввода отправляет сигнал операционной системе о том, что было совершено нажатие.
2️⃣Операционная система и диспетчер окон
Операционная система получает эти сигналы и передаёт их диспетчеру окон или системному обработчику событий. Диспетчер окон определяет, какому приложению или части интерфейса принадлежит область экрана, по которой было совершено нажатие.
3️⃣Передача событий в приложение
После того как определено, что событие нажатия принадлежит определённому приложению, событие передаётся этому приложению. В приложении событие перенаправляется в систему управления событиями внутри самого приложения.
4️⃣Обработка событий в приложении
Внутри приложения событие нажатия перенаправляется к соответствующему компоненту интерфейса (например, кнопке или ссылке), который зарегистрирован для обработки такого типа событий. Каждый элемент управления (или виджет) в пользовательском интерфейсе имеет свой обработчик событий, который определяет, что делать при нажатии на него.
5️⃣Вызов обработчиков событий
Компонент интерфейса вызывает заранее определённый обработчик события (например, функцию обратного вызова или "слушатель" событий), который исполняет код, ассоциированный с этим нажатием. Это может включать изменение внешнего вида элемента, открытие нового окна, отправку данных и т.д.
6️⃣Отклик интерфейса
После обработки события интерфейс может обновиться в ответ на действия пользователя — например, кнопка может изменить свой цвет, чтобы показать, что она была нажата, или может появиться новое окно с дополнительной информацией.
Пример на примере iOS (UIKit):
Процесс обработки нажатий осуществляется с помощью UIResponder цепочки, где события передаются от приложения к текущему активному объекту. Если объект не обрабатывает событие, оно передаётся дальше по цепочке, пока не найдёт подходящий обработчик или не достигнет корня иерархии представлений.
Этот механизм позволяет разработчикам создавать интерактивные, интуитивно понятные интерфейсы, отзывающиеся на различные действия пользователя.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 18%
Механизм обработки нажатий в пользовательских интерфейсах операционных систем и приложений включает в себя несколько ключевых этапов, которые обеспечивают реакцию системы на действия пользователя. Рассмотрим общий процесс на примере смартфонов и десктопных операционных систем:
1️⃣События ввода от устройств
Всё начинается с событий ввода, которые генерируются устройствами ввода, такими как сенсорные экраны, мыши или трекпады. Когда пользователь нажимает на экран или кликает мышью, устройство ввода отправляет сигнал операционной системе о том, что было совершено нажатие.
2️⃣Операционная система и диспетчер окон
Операционная система получает эти сигналы и передаёт их диспетчеру окон или системному обработчику событий. Диспетчер окон определяет, какому приложению или части интерфейса принадлежит область экрана, по которой было совершено нажатие.
3️⃣Передача событий в приложение
После того как определено, что событие нажатия принадлежит определённому приложению, событие передаётся этому приложению. В приложении событие перенаправляется в систему управления событиями внутри самого приложения.
4️⃣Обработка событий в приложении
Внутри приложения событие нажатия перенаправляется к соответствующему компоненту интерфейса (например, кнопке или ссылке), который зарегистрирован для обработки такого типа событий. Каждый элемент управления (или виджет) в пользовательском интерфейсе имеет свой обработчик событий, который определяет, что делать при нажатии на него.
5️⃣Вызов обработчиков событий
Компонент интерфейса вызывает заранее определённый обработчик события (например, функцию обратного вызова или "слушатель" событий), который исполняет код, ассоциированный с этим нажатием. Это может включать изменение внешнего вида элемента, открытие нового окна, отправку данных и т.д.
6️⃣Отклик интерфейса
После обработки события интерфейс может обновиться в ответ на действия пользователя — например, кнопка может изменить свой цвет, чтобы показать, что она была нажата, или может появиться новое окно с дополнительной информацией.
Пример на примере iOS (UIKit):
Процесс обработки нажатий осуществляется с помощью UIResponder цепочки, где события передаются от приложения к текущему активному объекту. Если объект не обрабатывает событие, оно передаётся дальше по цепочке, пока не найдёт подходящий обработчик или не достигнет корня иерархии представлений.
@IBAction func buttonTapped(_ sender: UIButton) {
print("Кнопка нажата")
}Этот механизм позволяет разработчикам создавать интерактивные, интуитивно понятные интерфейсы, отзывающиеся на различные действия пользователя.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
❤1
Anonymous Quiz
6%
Для инициализации переменных.
73%
Для выхода из функций или методов при определенном условии.
1%
Для создания асинхронного кода.
21%
Для обработки ошибок.
Какие есть примитивы в gcd ?
Спросят с вероятностью 18%
Grand Central Dispatch (GCD) предоставляет различные примитивы для управления параллельным выполнением кода в iOS и macOS. Эти примитивы помогают разработчикам эффективно управлять асинхронными задачами, синхронизировать доступ к ресурсам и контролировать поток выполнения программы. Вот основные примитивы, предоставляемые GCD:
1️⃣Dispatch Queues (Очереди)
Это фундаментальный компонент GCD, который управляет выполнением блоков кода (задач). Они бывают двух типов:
✅Serial Queues (Последовательные очереди): Выполняют задачи одну за другой в порядке их добавления.
✅Concurrent Queues (Параллельные очереди): Позволяют нескольким задачам выполняться одновременно, но порядок начала и завершения выполнения может отличаться от порядка добавления задач.
2️⃣Dispatch Groups (Группы)
Позволяют объединять несколько задач в одну группу для координированного управления. Вы можете отслеживать, когда все задачи в группе завершены, что особенно полезно при выполнении нескольких асинхронных операций, завершение которых необходимо отслеживать.
3️⃣Dispatch Work Items (Элементы работы)
Представляет собой блок кода, который может быть добавлен в очередь для выполнения. Элементы работы можно приостанавливать, возобновлять и отменять, что предоставляет дополнительный контроль над выполнением задач.
4️⃣Dispatch Semaphores (Семафоры)
Используются для управления доступом к ограниченному ресурсу. Они позволяют ограничить количество потоков, которые могут одновременно обращаться к этому ресурсу.
5️⃣Dispatch Sources (Источники событий)
Позволяют вам мониторить различные типы системных событий асинхронно. Это могут быть таймеры, файловые дескрипторы, сигналы и другие источники.
6️⃣Dispatch Barriers (Барьеры)
Используются на параллельных очередях для создания точки синхронизации, в которой очередь приостанавливает выполнение своих параллельных задач до тех пор, пока не выполнится задача с барьером.
Каждый из этих примитивов предназначен для решения определённых задач по управлению параллельным выполнением и синхронизации в приложениях, делая многопоточное программирование более доступным и безопасным.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 18%
Grand Central Dispatch (GCD) предоставляет различные примитивы для управления параллельным выполнением кода в iOS и macOS. Эти примитивы помогают разработчикам эффективно управлять асинхронными задачами, синхронизировать доступ к ресурсам и контролировать поток выполнения программы. Вот основные примитивы, предоставляемые GCD:
1️⃣Dispatch Queues (Очереди)
Это фундаментальный компонент GCD, который управляет выполнением блоков кода (задач). Они бывают двух типов:
✅Serial Queues (Последовательные очереди): Выполняют задачи одну за другой в порядке их добавления.
✅Concurrent Queues (Параллельные очереди): Позволяют нескольким задачам выполняться одновременно, но порядок начала и завершения выполнения может отличаться от порядка добавления задач.
2️⃣Dispatch Groups (Группы)
Позволяют объединять несколько задач в одну группу для координированного управления. Вы можете отслеживать, когда все задачи в группе завершены, что особенно полезно при выполнении нескольких асинхронных операций, завершение которых необходимо отслеживать.
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
DispatchQueue.global().async {
// Задача 1
dispatchGroup.leave()
}
dispatchGroup.enter()
DispatchQueue.global().async {
// Задача 2
dispatchGroup.leave()
}
dispatchGroup.notify(queue: DispatchQueue.main) {
// Вызывается, когда обе задачи завершены
print("Все задачи в группе выполнены.")
}
3️⃣Dispatch Work Items (Элементы работы)
Представляет собой блок кода, который может быть добавлен в очередь для выполнения. Элементы работы можно приостанавливать, возобновлять и отменять, что предоставляет дополнительный контроль над выполнением задач.
var workItem: DispatchWorkItem?
workItem = DispatchWorkItem {
print("Выполнение задачи")
if workItem?.isCancelled ?? false {
return
}
// Продолжение выполнения
}
DispatchQueue.global().async(execute: workItem!)
4️⃣Dispatch Semaphores (Семафоры)
Используются для управления доступом к ограниченному ресурсу. Они позволяют ограничить количество потоков, которые могут одновременно обращаться к этому ресурсу.
let semaphore = DispatchSemaphore(value: 1)
DispatchQueue.global().async {
semaphore.wait() // Ожидание сигнала
// Критическая секция
semaphore.signal() // Отправка сигнала
}
5️⃣Dispatch Sources (Источники событий)
Позволяют вам мониторить различные типы системных событий асинхронно. Это могут быть таймеры, файловые дескрипторы, сигналы и другие источники.
6️⃣Dispatch Barriers (Барьеры)
Используются на параллельных очередях для создания точки синхронизации, в которой очередь приостанавливает выполнение своих параллельных задач до тех пор, пока не выполнится задача с барьером.
let queue = DispatchQueue(label: "com.example.queue", attributes: .
concurrent)
queue.async(flags: .barrier) {
// Задача с барьером
}
Каждый из этих примитивов предназначен для решения определённых задач по управлению параллельным выполнением и синхронизации в приложениях, делая многопоточное программирование более доступным и безопасным.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
🔥3❤1
Что такое optional chaining в Swift?
Anonymous Quiz
70%
Позволяет выполнять операции только если объект не равен nil.
11%
Используется для обработки ошибок.
13%
Не позволяет переменной быть nil.
6%
Это способ создания замыканий.
Есть ли отличия value тайпа от референса тайпа ?
Спросят с вероятностью 55%
Между типами значений (value types) и ссылочными типами (reference types) существуют существенные отличия, которые влияют на работу с данными.
Основные отличия:
1️⃣Способ хранения:
✅Value types хранятся в стеке, и их значения копируются при передаче. Это значит, что если вы передадите структуру функции или присвоите её новой переменной, создастся новая копия этого значения.
✅Reference types хранятся в куче, а переменные хранят ссылки на эти объекты. При передаче переменной класса, вы передаёте ссылку на один и тот же объект, а не его копию.
2️⃣Примеры:
✅В Swift value types включают структуры (
✅Reference types включают классы (
3️⃣Идентификация:
✅Для value types равенство определяется по содержимому объекта. Два объекта считаются равными, если их содержимое идентично.
✅Для reference types равенство может определяться как равенство по ссылке. Два объекта считаются равными, если они указывают на один и тот же участок памяти.
4️⃣Поведение при передаче данных:
✅Передача value types ведёт к созданию копии. Изменения одной копии не влияют на другую.
✅Передача reference types означает передачу ссылки на тот же объект. Изменения в одном месте отразятся на всех ссылках на этот объект.
5️⃣Использование:
✅Value types обычно используются, когда копирование или независимость данных предпочтительнее. Они обеспечивают более предсказуемое управление памятью, так как Swift автоматически управляет жизненным циклом структур и других типов значений.
✅Reference types полезны, когда необходимо иметь общее состояние или взаимодействовать с объектами, которые могут изменяться в разных частях программы.
✅Value types (типы значений) копируются при передаче и обычно используются для базовых типов данных. Они предоставляют простоту и безопасность при работе с данными.
✅Reference types (ссылочные типы) передаются по ссылке, позволяя разным частям программы взаимодействовать с одним и тем же объектом. Это полезно для работы с комплексными структурами данных и для реализации определённых шаблонов проектирования.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 55%
Между типами значений (value types) и ссылочными типами (reference types) существуют существенные отличия, которые влияют на работу с данными.
Основные отличия:
1️⃣Способ хранения:
✅Value types хранятся в стеке, и их значения копируются при передаче. Это значит, что если вы передадите структуру функции или присвоите её новой переменной, создастся новая копия этого значения.
✅Reference types хранятся в куче, а переменные хранят ссылки на эти объекты. При передаче переменной класса, вы передаёте ссылку на один и тот же объект, а не его копию.
2️⃣Примеры:
✅В Swift value types включают структуры (
struct), перечисления (enum) и базовые типы данных (Int, String, Array, и т.д.).✅Reference types включают классы (
class).3️⃣Идентификация:
✅Для value types равенство определяется по содержимому объекта. Два объекта считаются равными, если их содержимое идентично.
✅Для reference types равенство может определяться как равенство по ссылке. Два объекта считаются равными, если они указывают на один и тот же участок памяти.
4️⃣Поведение при передаче данных:
✅Передача value types ведёт к созданию копии. Изменения одной копии не влияют на другую.
✅Передача reference types означает передачу ссылки на тот же объект. Изменения в одном месте отразятся на всех ссылках на этот объект.
5️⃣Использование:
✅Value types обычно используются, когда копирование или независимость данных предпочтительнее. Они обеспечивают более предсказуемое управление памятью, так как Swift автоматически управляет жизненным циклом структур и других типов значений.
✅Reference types полезны, когда необходимо иметь общее состояние или взаимодействовать с объектами, которые могут изменяться в разных частях программы.
✅Value types (типы значений) копируются при передаче и обычно используются для базовых типов данных. Они предоставляют простоту и безопасность при работе с данными.
✅Reference types (ссылочные типы) передаются по ссылке, позволяя разным частям программы взаимодействовать с одним и тем же объектом. Это полезно для работы с комплексными структурами данных и для реализации определённых шаблонов проектирования.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
❤4
Какой метод используется для сортировки массива в Swift?
Anonymous Quiz
8%
sortArray()
91%
sorted()
0%
orderArray()
1%
arrange()
Можно сделать так, чтобы отменилась операция во время выполнения в gcd ?
Спросят с вероятностью 18%
В Grand Central Dispatch (GCD) отмена операции не поддерживается напрямую, так как он не предоставляет встроенных механизмов для отмены уже запущенных задач. Однако, вы можете реализовать поддержку отмены операций на уровне вашего приложения, используя кастомные проверки внутри блоков выполнения.
Как реализовать отмену операции
Нужно будет использовать внешнюю переменную или структуру, которая будет отслеживать, нужно ли отменить выполнение задачи. Вот как это можно сделать на практике:
1️⃣Определите переменную для отслеживания состояния отмены.
Вы можете использовать переменную типа
2️⃣Проверяйте эту переменную внутри вашей асинхронной задачи.
В ключевых точках вашей задачи добавьте проверки этой переменной, и, если задача должна быть отменена, корректно завершите выполнение блока.
3️⃣Изменяйте эту переменную из других частей вашего приложения при необходимости отмены.
Это позволит вам контролировать выполнение задачи из любой части приложения.
Пример:
Важные моменты
✅Проверки отмены должны быть распределены равномерно по всему коду задачи, чтобы обеспечить своевременное реагирование на запросы отмены.
✅Безопасность доступа к данным: Убедитесь, что доступ к переменной
Хотя GCD не предоставляет встроенной поддержки отмены задач, вы можете организовать такую поддержку самостоятельно, используя простые проверки состояния в коде своих асинхронных задач.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 18%
В Grand Central Dispatch (GCD) отмена операции не поддерживается напрямую, так как он не предоставляет встроенных механизмов для отмены уже запущенных задач. Однако, вы можете реализовать поддержку отмены операций на уровне вашего приложения, используя кастомные проверки внутри блоков выполнения.
Как реализовать отмену операции
Нужно будет использовать внешнюю переменную или структуру, которая будет отслеживать, нужно ли отменить выполнение задачи. Вот как это можно сделать на практике:
1️⃣Определите переменную для отслеживания состояния отмены.
Вы можете использовать переменную типа
Bool, которая будет указывать, следует ли продолжать выполнение задачи.2️⃣Проверяйте эту переменную внутри вашей асинхронной задачи.
В ключевых точках вашей задачи добавьте проверки этой переменной, и, если задача должна быть отменена, корректно завершите выполнение блока.
3️⃣Изменяйте эту переменную из других частей вашего приложения при необходимости отмены.
Это позволит вам контролировать выполнение задачи из любой части приложения.
Пример:
import Foundation
class TaskHandler {
var isCancelled = false
func performLongRunningTask() {
DispatchQueue.global().async {
for i in 1...10 {
if self.isCancelled {
print("Операция была отменена!")
return
}
sleep(1) // Имитация длительной операции
print("Итерация \(i) завершена")
}
}
}
func cancelTask() {
isCancelled = true
}
}
let taskHandler = TaskHandler()
taskHandler.performLongRunningTask()
// Отменить задачу через 3 секунды
DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
taskHandler.cancelTask()
}
Важные моменты
✅Проверки отмены должны быть распределены равномерно по всему коду задачи, чтобы обеспечить своевременное реагирование на запросы отмены.
✅Безопасность доступа к данным: Убедитесь, что доступ к переменной
isCancelled потокобезопасен, особенно если вы изменяете её из разных потоков. В приведённом примере, так как доступ к переменной осуществляется только из задач, запущенных на глобальной очереди, проблем с потокобезопасностью не возникает.Хотя GCD не предоставляет встроенной поддержки отмены задач, вы можете организовать такую поддержку самостоятельно, используя простые проверки состояния в коде своих асинхронных задач.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Как опциональный тип реализован под капотом ?
Спросят с вероятностью 18%
Опциональный тип (Optional) реализован как перечисление (
Реализация:
Определяет
Это определение показывает, что
Примеры:
Работа с ними:
Предоставляет несколько способов для работы с опциональными значениями:
1️⃣Принудительное извлечение (`force unwrapping`):
Использование
2️⃣Опциональное связывание (`optional binding`):
Это позволяет безопасно извлечь значение, если оно существует.
3️⃣Оператор объединения с nil (`nil coalescing`):
Это позволяет предоставить значение по умолчанию для опционального типа в случае, если он содержит
Особенности:
✅Каждый опциональный тип на самом деле представляет собой один из двух случаев перечисления
✅С точки зрения памяти, опциональный тип потребляет больше ресурсов, чем его неопциональный аналог, потому что он должен хранить дополнительную информацию о том, содержит ли он значение или нет.
✅Компилятор обрабатывает опциональные типы особым образом, в частности, предоставляя специальный синтаксис (
Это базовое понимание того, как опциональные типы реализованы под капотом. Их использование является фундаментальным аспектом безопасной работы с данными, которые могут отсутствовать.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 18%
Опциональный тип (Optional) реализован как перечисление (
enum). Это перечисление имеет два случая: .none, который эквивалентен значению nil, и .some(Wrapped), который содержит значение типа Wrapped. Тип Wrapped здесь — это тип данных, который может быть или не быть (то есть может быть опциональным).Реализация:
Определяет
Optional как:enum Optional<Wrapped> {
case none
case some(Wrapped)
}Это определение показывает, что
Optional является универсальным типом с параметром Wrapped. Он может либо содержать значение (some), либо не содержать его вообще (none).Примеры:
var optionalInt: Optional<Int> = .some(5)
var nilInt: Optional<Int> = .none
// Swift предоставляет синтаксический сахар для опциональных типов
var optionalIntSugar: Int? = 5
var nilIntSugar: Int? = nil
Работа с ними:
Предоставляет несколько способов для работы с опциональными значениями:
1️⃣Принудительное извлечение (`force unwrapping`):
let unwrappedInt = optionalIntSugar!
Использование
! для извлечения значения из опционального типа. Это приведет к ошибке времени выполнения, если значение будет nil.2️⃣Опциональное связывание (`optional binding`):
if let unwrappedInt = optionalIntSugar {
print("Значение: \(unwrappedInt)")
} else {
print("Нет значения")
}
Это позволяет безопасно извлечь значение, если оно существует.
3️⃣Оператор объединения с nil (`nil coalescing`):
let number = optionalIntSugar ?? 0
Это позволяет предоставить значение по умолчанию для опционального типа в случае, если он содержит
nil.Особенности:
✅Каждый опциональный тип на самом деле представляет собой один из двух случаев перечисления
Optional.✅С точки зрения памяти, опциональный тип потребляет больше ресурсов, чем его неопциональный аналог, потому что он должен хранить дополнительную информацию о том, содержит ли он значение или нет.
✅Компилятор обрабатывает опциональные типы особым образом, в частности, предоставляя специальный синтаксис (
?) и интегрируя проверки на nil в процесс компиляции.Это базовое понимание того, как опциональные типы реализованы под капотом. Их использование является фундаментальным аспектом безопасной работы с данными, которые могут отсутствовать.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
👍2
Для чего используется ключевое слово inout в Swift?
Anonymous Quiz
4%
Для создания асинхронного кода.
85%
Для передачи значений по ссылке.
2%
Для обработки ошибок.
10%
Для создания замыканий.
Какие типы коллекций существуют ?
Спросят с вероятностью 55%
Существует несколько основных типов коллекций, каждый из которых имеет свои уникальные характеристики и предназначен для решения определённых задач. К основным типам коллекций относятся массивы (Arrays), множества (Sets) и словари (Dictionaries).
1️⃣Массивы (Arrays)
Используются для хранения упорядоченных коллекций элементов одного типа. Они могут содержать дубликаты и сохраняют порядок элементов, в котором те были добавлены. Являются типами значений (value types), что означает, что при их передаче происходит копирование данных.
Пример:
Представляют неупорядоченные коллекции уникальных элементов одного типа. Они очень похожи на массивы, но, в отличие от массивов, не сохраняют порядок элементов и не могут содержать дубликаты. Особенно эффективны при проверке на принадлежность, добавлении или удалении элементов.
Пример:
Используются для хранения неупорядоченных коллекций элементов, которые доступны по уникальному ключу. Каждый элемент в словаре является парой "ключ-значение". Ключи словаря должны быть уникальными, а значения могут дублироваться. Они также являются типами значений.
Пример:
✅Массивы хранят упорядоченные коллекции элементов и могут содержать дубликаты. Используются, когда порядок элементов важен.
✅Множества хранят уникальные элементы в неопределённом порядке. Эффективны для проверки на принадлежность и исключения дубликатов.
✅Словари хранят неупорядоченные пары "ключ-значение", доступные по уникальному ключу. Подходят для быстрого доступа к элементам по идентификатору.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 55%
Существует несколько основных типов коллекций, каждый из которых имеет свои уникальные характеристики и предназначен для решения определённых задач. К основным типам коллекций относятся массивы (Arrays), множества (Sets) и словари (Dictionaries).
1️⃣Массивы (Arrays)
Используются для хранения упорядоченных коллекций элементов одного типа. Они могут содержать дубликаты и сохраняют порядок элементов, в котором те были добавлены. Являются типами значений (value types), что означает, что при их передаче происходит копирование данных.
Пример:
var someInts = [Int]()Множества (Sets)
someInts.append(3) // Добавление элемента
someInts = [] // Очистка массива
2️⃣
Представляют неупорядоченные коллекции уникальных элементов одного типа. Они очень похожи на массивы, но, в отличие от массивов, не сохраняют порядок элементов и не могут содержать дубликаты. Особенно эффективны при проверке на принадлежность, добавлении или удалении элементов.
Пример:
var letters = Set<Character>()Словари (Dictionaries)
letters.insert("a") // Добавление элемента
letters = [] // Очистка множества
3️⃣
Используются для хранения неупорядоченных коллекций элементов, которые доступны по уникальному ключу. Каждый элемент в словаре является парой "ключ-значение". Ключи словаря должны быть уникальными, а значения могут дублироваться. Они также являются типами значений.
Пример:
var namesOfIntegers = [Int: String]() // Пустой словарь
namesOfIntegers[16] = "sixteen" // Добавление нового элемента
namesOfIntegers = [:] // Очистка словаря
✅Массивы хранят упорядоченные коллекции элементов и могут содержать дубликаты. Используются, когда порядок элементов важен.
✅Множества хранят уникальные элементы в неопределённом порядке. Эффективны для проверки на принадлежность и исключения дубликатов.
✅Словари хранят неупорядоченные пары "ключ-значение", доступные по уникальному ключу. Подходят для быстрого доступа к элементам по идентификатору.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Какие инициализаторы можно добавить в extension ?
Спросят с вероятностью 18%
С помощью расширений (extensions), вы можете добавлять новые инициализаторы к существующим классам, структурам и перечислениям. Однако существуют определенные ограничения и различия в возможностях добавления инициализаторов в зависимости от типа данных. Рассмотрим более подробно, какие инициализаторы можно добавить через расширения в разных случаях:
1️⃣Структуры (Structs)
Обладают особенностью автоматически создавать "синтезированный" инициализатор, который требует, чтобы все свойства структуры были инициализированы. При добавлении новых инициализаторов через расширения:
✅Вы можете добавлять дополнительные удобные (convenience) инициализаторы, которые могут облегчить создание экземпляров структуры с предопределенными значениями или упрощенной логикой инициализации.
2️⃣Классы (Classes)
Добавление инициализаторов к классам через расширения включает в себя более строгие ограничения:
✅Вспомогательные инициализаторы (Convenience initializers) могут быть добавлены через расширения, но вы не можете добавить назначенные инициализаторы (designated initializers) через расширение.
✅Вспомогательные инициализаторы должны в конечном итоге вызвать другой существующий инициализатор класса.
3️⃣Перечисления (Enums)
Могут получать дополнительные инициализаторы через расширения:
✅Вы можете добавлять инициализаторы, которые помогут создать экземпляры перечисления на основе различных условий или параметров.
✅Инициализаторы в расширениях не могут добавлять новые хранимые свойства к типу.
✅Инициализаторы в расширениях полезны для предоставления альтернативных способов создания экземпляров типов, особенно когда нужно интегрировать типы с внешними системами или упростить создание экземпляров с определенными конфигурациями.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 18%
С помощью расширений (extensions), вы можете добавлять новые инициализаторы к существующим классам, структурам и перечислениям. Однако существуют определенные ограничения и различия в возможностях добавления инициализаторов в зависимости от типа данных. Рассмотрим более подробно, какие инициализаторы можно добавить через расширения в разных случаях:
1️⃣Структуры (Structs)
Обладают особенностью автоматически создавать "синтезированный" инициализатор, который требует, чтобы все свойства структуры были инициализированы. При добавлении новых инициализаторов через расширения:
✅Вы можете добавлять дополнительные удобные (convenience) инициализаторы, которые могут облегчить создание экземпляров структуры с предопределенными значениями или упрощенной логикой инициализации.
struct Point {
var x: Double
var y: Double
}
extension Point {
init() {
self.init(x: 0, y: 0)
}
}2️⃣Классы (Classes)
Добавление инициализаторов к классам через расширения включает в себя более строгие ограничения:
✅Вспомогательные инициализаторы (Convenience initializers) могут быть добавлены через расширения, но вы не можете добавить назначенные инициализаторы (designated initializers) через расширение.
✅Вспомогательные инициализаторы должны в конечном итоге вызвать другой существующий инициализатор класса.
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
extension Person {
convenience init() {
self.init(name: "Unknown", age: 0)
}
}3️⃣Перечисления (Enums)
Могут получать дополнительные инициализаторы через расширения:
✅Вы можете добавлять инициализаторы, которые помогут создать экземпляры перечисления на основе различных условий или параметров.
enum TemperatureUnit {
case celsius, fahrenheit, kelvin
}
extension TemperatureUnit {
init?(symbol: Character) {
switch symbol {
case "C":
self = .celsius
case "F":
self = .fahrenheit
case "K":
self = .kelvin
default:
return nil
}
}
}✅Инициализаторы в расширениях не могут добавлять новые хранимые свойства к типу.
✅Инициализаторы в расширениях полезны для предоставления альтернативных способов создания экземпляров типов, особенно когда нужно интегрировать типы с внешними системами или упростить создание экземпляров с определенными конфигурациями.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Какой метод используется для добавления элемента в конец массива в Swift?
Anonymous Quiz
89%
append()
5%
add()
5%
insert()
1%
push()
Что в extension можно добавить, кроме функции ?
Спросят с вероятностью 18%
Расширения (extensions) позволяют добавлять новую функциональность к существующим классам, структурам, перечислениям, а также протоколам. Они могут значительно улучшить читаемость и организацию кода, а также помогают расширять функционал типов, которые вы не контролируете напрямую (например, типы из стандартной библиотеки Swift или сторонних библиотек). Вот что вы можете добавлять в типы данных через расширения:
1️⃣Вычисляемые свойства
Расширения могут добавлять новые вычисляемые свойства к типам, но они не могут содержать хранимые свойства или добавлять свойства с наблюдателями за их изменениями.
2️⃣Методы
Расширения могут добавлять новые методы экземпляра и новые методы типа к существующим типам.
3️⃣Модифицирующие (
Позволяет им изменять переменные экземпляра.
4️⃣Инициализаторы
Позволяет создавать типы новыми способами.
5️⃣Сабскрипты
Расширения могут добавлять новые сабскрипты к существующим типам.
6️⃣Вложенные типы
Расширения могут добавлять новые вложенные типы к существующим классам, структурам и перечислениям.
Эти возможности делают расширения чрезвычайно мощным инструментом для модульного дизайна и рефакторинга кода.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 18%
Расширения (extensions) позволяют добавлять новую функциональность к существующим классам, структурам, перечислениям, а также протоколам. Они могут значительно улучшить читаемость и организацию кода, а также помогают расширять функционал типов, которые вы не контролируете напрямую (например, типы из стандартной библиотеки Swift или сторонних библиотек). Вот что вы можете добавлять в типы данных через расширения:
1️⃣Вычисляемые свойства
Расширения могут добавлять новые вычисляемые свойства к типам, но они не могут содержать хранимые свойства или добавлять свойства с наблюдателями за их изменениями.
extension Double {
var km: Double { return self * 1_000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1_000.0 }
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters") // Вывод: "One inch is 0.0254 meters"2️⃣Методы
Расширения могут добавлять новые методы экземпляра и новые методы типа к существующим типам.
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
3.repetitions {
print("Hello!")
}
// Вывод: "Hello!" будет напечатано три раза3️⃣Модифицирующие (
mutating) методы экземпляраПозволяет им изменять переменные экземпляра.
extension Int {
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square() // someInt теперь равен 94️⃣Инициализаторы
Позволяет создавать типы новыми способами.
struct Size {
var width: Double
var height: Double
}
extension Size {
init(squareWithSide side: Double) {
self.width = side
self.height = side
}
}
let squareSize = Size(squareWithSide: 5) // width и height будут равны 55️⃣Сабскрипты
Расширения могут добавлять новые сабскрипты к существующим типам.
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
print(746381295[0]) // Выводит 56️⃣Вложенные типы
Расширения могут добавлять новые вложенные типы к существующим классам, структурам и перечислениям.
extension Int {
enum Kind {
case negative, zero, positive
}
var kind: Kind {
switch self {
case 0:
return .zero
case let x where x > 0:
return .positive
default:
return .negative
}
}
}Эти возможности делают расширения чрезвычайно мощным инструментом для модульного дизайна и рефакторинга кода.
👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых