Это порождающий шаблон проектирования, который гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру. Этот шаблон часто используется для управления ресурсами, такими как базы данных или логирование, где требуется, чтобы доступ был централизованным и единичным.
Класс Singleton создаёт только один экземпляр своего типа и предотвращает создание дополнительных экземпляров.
Singleton предоставляет глобальный доступ к своему экземпляру. Это может быть реализовано через статический метод, который возвращает экземпляр класса.
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
# Пример использования
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2) # True
public class Singleton {
private static Singleton instance;
private Singleton() {
// приватный конструктор предотвращает создание объектов вне класса
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// Пример использования
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton1 == singleton2); // TrueСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
- INNER JOIN: возвращает строки, когда есть совпадение в обеих таблицах.
- LEFT OUTER JOIN: возвращает все строки из левой таблицы и совпадающие строки из правой таблицы.
- RIGHT OUTER JOIN: возвращает все строки из правой таблицы и совпадающие строки из левой таблицы.
- FULL OUTER JOIN: возвращает строки, когда есть совпадение в любой из таблиц.
- CROSS JOIN: возвращает декартово произведение обеих таблиц.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Это код, который не только выполняет поставленные задачи, но и соответствует ряду критериев, обеспечивающих его качество, читаемость, сопровождение и эффективность.
Переменные, функции, классы и другие сущности должны иметь понятные и описательные имена, которые отражают их назначение. Следование стандартам кодирования и стиля, включая правильное форматирование, отступы и использование комментариев. Использование комментариев для объяснения сложных или неочевидных частей кода, но не для очевидных вещей, которые можно понять из названий переменных и функций.
Код должен быть разбит на модули, функции или классы с чётко определёнными задачами. Это упрощает его понимание, тестирование и изменение. Избегание дублирования кода через применение принципа DRY (Don't Repeat Yourself). Код должен быть легко тестируемым. Написание автоматических тестов для проверки корректности работы помогает предотвратить ошибки.
Код должен быть оптимизирован для выполнения задач с минимальными затратами ресурсов, таких как время выполнения и использование памяти. Использование эффективных алгоритмов и структур данных для обеспечения хорошей производительности, особенно на больших объемах данных.
Код должен корректно обрабатывать ошибки и исключительные ситуации, предотвращая неожиданные сбои. Проверка входных данных для предотвращения некорректного поведения программы.
Написание документации, описывающей основные компоненты системы, их взаимодействие и использование. Хорошо документированный код облегчает его понимание для других разработчиков.
Применение принципов SOLID для создания устойчивого, гибкого и масштабируемого кода. Использование проверенных решений для общих задач проектирования.
Читаемость и сопровождаемость
def calculate_area(radius):
"""Calculate the area of a circle given its radius."""
import math
if radius < 0:
raise ValueError("Radius cannot be negative")
return math.pi * radius ** 2
Тестируемость
def add(a, b):
"""Add two numbers and return the result."""
return a + b
# Unit test for the add function
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
test_add()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Это принцип программирования, который гласит, что информация или логика в коде не должны дублироваться. Каждый фрагмент знаний должен иметь одно, однозначное и авторитетное представление в системе. Этот принцип был введен в книге "The Pragmatic Programmer" Эндрю Хантом и Дэвидом Томасом.
Код должен быть написан так, чтобы не повторяться. Если одно и то же действие или информация используются в нескольких местах, они должны быть вынесены в одно место и использоваться повторно.
Изменения в коде нужно вносить в одном месте, что упрощает его сопровождение и уменьшает вероятность ошибок.
Код становится более понятным и структурированным, что облегчает его чтение и понимание.
Вынос общих операций в функции или методы, которые затем можно вызывать в различных частях программы.
Создание модулей или библиотек, которые содержат повторяющуюся логику и могут быть переиспользованы в различных проектах.
Объявление констант вместо использования "магических чисел" или строковых литералов в нескольких местах кода.
Использование шаблонов в HTML, XML или других языках разметки для генерации повторяющихся структур.
Хранение конфигурационных данных в одном месте, а не встраивание их в код.
Меньшее количество кода и дублирования упрощает понимание системы и снижает её сложность.
Легче поддерживать и обновлять код, так как изменения нужно вносить в одном месте.
Снижается вероятность ошибок, поскольку одно и то же изменение не нужно делать в нескольких местах.
Переиспользование кода ускоряет разработку, так как не нужно повторно писать уже существующий функционал.
Одинаковые блоки кода, выполняющие одну и ту же задачу, размещены в разных частях программы.
Те же самые данные (например, настройки или конфигурации) хранятся в нескольких местах.
Одни и те же структуры данных определены в разных местах программы.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
- Первая нормальная форма (1NF): данные разбиваются на атомарные единицы.
- Вторая нормальная форма (2NF): таблица находится в 1NF и все не ключевые атрибуты полностью зависят от первичного ключа.
- Третья нормальная форма (3NF): таблица находится в 2NF и все его атрибуты не зависят друг от друга, кроме зависимости от первичного ключа.
- Нормальная форма Бойса-Кодда (BCNF), Четвертая (4NF) и Пятая (5NF) нормальные формы далее уменьшают избыточность данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Асинхронные операции позволяют программам выполнять задачи в фоновом режиме, не блокируя основной поток выполнения. Это улучшает производительность и отзывчивость приложений.
HTTP-запросы: Асинхронные HTTP-запросы позволяют приложениям запрашивать данные у веб-серверов без блокировки пользовательского интерфейса. Например, загрузка данных из API, отправка форм и файлов. WebSockets: Поддержка двустороннего взаимодействия между клиентом и сервером в реальном времени. Это используется в чатах, онлайн-играх и других приложениях, где требуется мгновенная передача данных. API-вызовы: Асинхронные вызовы к внешним API позволяют продолжать выполнение других операций, не дожидаясь ответа от сервера.
Файловые операции: Асинхронное чтение и запись файлов позволяет обрабатывать большие объемы данных без блокировки основного потока выполнения. Работа с базами данных: Асинхронные запросы к базам данных уменьшают время ожидания и улучшают масштабируемость приложения.
Обработка задач в фоне: Выполнение длительных задач, таких как обработка изображений, видео, данных, без блокировки основного потока. Это позволяет улучшить пользовательский опыт, так как приложение остается отзывчивым. Периодические задания: Планирование и выполнение задач по расписанию, например, обновление данных, резервное копирование, мониторинг системы.
Асинхронные события: Обработка событий пользовательского интерфейса (например, нажатие кнопок, ввод данных) асинхронно для повышения отзывчивости приложений. Анимации и переходы: Асинхронное выполнение анимаций и переходов улучшает пользовательский опыт за счет плавности и непрерывности интерфейса.
Стриминг данных: Асинхронная обработка потоков данных в реальном времени, таких как видео, аудио, данные с датчиков. Это позволяет эффективно управлять непрерывными потоками информации. Реактивное программирование: Асинхронное реагирование на изменения данных и событий. Реактивные системы позволяют обрабатывать данные по мере их поступления, что особенно важно в приложениях, работающих с большим количеством данных.
Параллельные вычисления: Разделение больших задач на более мелкие части, которые выполняются параллельно. Это улучшает производительность при обработке больших объемов данных или выполнении сложных вычислений. Машинное обучение: Асинхронное обучение моделей и выполнение предсказаний позволяет эффективно использовать вычислительные ресурсы.
Асинхронная обработка пользовательских запросов, выполнение сетевых операций и взаимодействие с базами данных для повышения производительности и отзывчивости.
Асинхронные операции обеспечивают плавную работу интерфейса и эффективное использование ресурсов при выполнении сетевых запросов и операций ввода/вывода.
Асинхронное взаимодействие с серверами, обработка событий пользователя и управление игровыми объектами в реальном времени.
Параллельное выполнение вычислительных задач и обработка больших объемов данных для повышения эффективности исследований.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👾2👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Forwarded from Идущий к IT
Твое резюме на HeadHunter — ОК, если ты видишь это.
HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.
Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.
Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.
Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.
О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.
Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.
Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.
Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.
О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
Это высокопроизводительная система управления базами данных, работающая в памяти (in-memory), которая поддерживает множество структур данных, таких как строки, списки, множества, хэш-таблицы и другие. Redis широко используется в современных проектах благодаря своей скорости и функциональности.
Снижение нагрузки на базу данных: Кэширование часто запрашиваемых данных в Redis позволяет снизить нагрузку на основную базу данных и ускорить время ответа. Ускорение доступа к данным: Быстрое чтение данных из памяти обеспечивает низкую задержку и высокую производительность.
Управление сессиями пользователей: Redis часто используется для хранения сессионных данных пользователей в веб-приложениях благодаря своей скорости и поддержке автоматического удаления старых данных (TTL).
Асинхронные задачи: Redis используется для реализации очередей задач в таких системах, как Celery. Это позволяет распределять и выполнять задачи асинхронно и эффективно. Сообщения и события: Redis поддерживает механизм Pub/Sub для организации обмена сообщениями между различными частями приложения.
Счётчики и трекеры: Используется для хранения временных данных, таких как счётчики посещений, лайков, просмотров и других показателей, которые часто обновляются. Краткосрочные данные: Хранение временных данных, которые необходимы на короткий срок и могут быть удалены после их использования.
Репликация данных: Redis поддерживает мастеровую репликацию, что позволяет создавать копии данных на нескольких серверах для обеспечения отказоустойчивости и балансировки нагрузки. Снятие резервных копий: Redis поддерживает создание резервных копий данных, что обеспечивает восстановление в случае сбоев.
Работа с временными рядами: Redis позволяет эффективно управлять временными рядами данных, используя такие структуры, как списки и отсортированные множества. Графы и социальные сети: Использование структур данных Redis для реализации графов и сетей, что полезно в социальных сетях и рекомендательных системах.
Реализация распределённых блокировок: Redis позволяет создавать механизмы блокировок для управления доступом к ресурсам в распределённых системах.
Кэширование результатов запросов к базе данных. Хранение сессионных данных пользователей. Управление очередями задач для обработки данных в фоне.
Кэширование API-запросов для уменьшения задержек. Хранение временных данных и метрик использования.
Хранение текущих состояний игр и информации о пользователях. Реализация лидеров и таблиц рекордов.
Кэширование результатов аналитических запросов. Управление счётчиками и метриками в реальном времени.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Это структура данных, в которой каждый узел имеет не более двух дочерних узлов. Эти дочерние узлы называются левым и правым дочерними узлами. В бинарном дереве может быть один или несколько уровней узлов, начиная с корневого узла, который является начальной точкой дерева.
Основной элемент бинарного дерева, содержащий данные и ссылки на дочерние узлы.
Верхний узел дерева, не имеющий родительских узлов.
Узел, не имеющий дочерних узлов.
Путь от корня к любому другому узлу.
Максимальное количество уровней от корня до самого нижнего листа.
Расстояние от корня до данного узла.
Все уровни, кроме, возможно, последнего, полностью заполнены, и все узлы последнего уровня выровнены влево.
Все уровни полностью заполнены, и каждый узел имеет два дочерних узла, кроме листьев.
Для каждого узла все значения в левом поддереве меньше значения узла, а все значения в правом поддереве больше значения узла.
Процесс вставки нового узла в дерево. В случае двоичного дерева поиска, новый узел вставляется в соответствующее место, чтобы сохранить порядок элементов.
Процесс удаления узла из дерева. Может потребовать реорганизации дерева для поддержания его свойств.
Процесс нахождения узла с определенным значением. В двоичном дереве поиска это осуществляется быстрее благодаря упорядоченности узлов.
Процесс посещения всех узлов дерева в определенном порядке. Основные методы обхода:
Бинарное дерево поиска позволяет эффективно хранить и извлекать отсортированные данные.
Использование деревьев для организации и поиска данных.
Базовая структура для многих алгоритмов, включая сортировки, балансировки и другие операции с данными.
Используются для построения и обработки синтаксических деревьев при разборе кода.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Итератор — это объект, который позволяет поочередно перебирать элементы коллекции или другого объекта. Он предоставляет методы для доступа к следующему элементу и проверки, есть ли ещё элементы. Итераторы используются для упрощения работы с коллекциями в циклах.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Celery поддерживает различные брокеры сообщений, включая RabbitMQ и Redis, для управления очередями задач.
Позволяет запускать длительные операции в фоновом режиме, освобождая основной поток выполнения приложения для других задач.
Поддержка периодических и плановых заданий, что позволяет автоматизировать повторяющиеся процессы.
Способен управлять задачами в распределенной системе, используя несколько рабочих узлов (workers) для параллельного выполнения задач.
Легко масштабируется, добавляя больше рабочих узлов для увеличения производительности.
Отправка электронной почты: Асинхронная отправка писем для улучшения производительности веб-приложений.
Обработка данных: Включает такие задачи, как анализ данных, обработка изображений или видео, преобразование форматов и другие ресурсоемкие операции.
Взаимодействие с API: Выполнение запросов к внешним API, которое может быть долгим или неэффективным при синхронном выполнении.
Обновление данных: Регулярное обновление кэшей, индексов поиска или других данных в базе данных.
Мониторинг и сбор метрик: Периодический сбор и обработка метрик для мониторинга состояния системы.
Очистка данных: Периодическая очистка устаревших или временных данных из базы данных.
Уведомления в реальном времени: Отправка уведомлений пользователям через различные каналы (email, SMS, push-уведомления).
Событийное оповещение: Реагирование на события и триггеры, такие как изменения в базе данных или действия пользователя.
Параллельная обработка данных: Выполнение параллельных вычислений для обработки больших объемов данных.
Машинное обучение: Асинхронное обучение моделей и выполнение предсказаний на больших наборах данных.
Веб-скрейпинг: Асинхронный сбор данных с веб-сайтов для агрегации или анализа.
Интеграция данных: Асинхронная интеграция данных из различных источников и API.
Улучшение производительности веб-приложений за счет выполнения долгих операций в фоне.
Обработка заказов, обновление статусов заказов и управление инвентарем в фоновом режиме.
Обработка пользовательских данных, отправка уведомлений и обновление лент новостей.
Выполнение сложных вычислений и обработка больших объемов данных в распределенной среде.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
HTTP (HyperText Transfer Protocol) — это протокол прикладного уровня для передачи гипертекста между клиентом (например, веб-браузером) и сервером. Он является основой для обмена данными в веб-пространстве и используется для передачи HTML-документов, изображений, видео и других ресурсов.
HTTP работает по модели запрос-ответ, где клиент отправляет запрос серверу, а сервер возвращает ответ. Запросы и ответы состоят из трех основных частей:
Стартовая строка: Определяет метод запроса (например, GET, POST) и URI (Uniform Resource Identifier).
Заголовки: Несут метаданные, такие как тип контента, длина контента, информация о сессии и т. д.
Тело: Содержит данные, отправляемые в запросе или ответе (например, данные формы, JSON).
Основные методы включают:
GET: Запрашивает данные с сервера.
POST: Отправляет данные на сервер для создания или обновления ресурса.
PUT: Обновляет существующий ресурс.
DELETE: Удаляет ресурс.
HEAD: Запрашивает только заголовки без тела ответа.
OPTIONS: Запрашивает информацию о возможностях сервера для определенного ресурса.
Сервер отвечает статусными кодами, которые показывают результат обработки запроса. Например:
200 OK: Запрос успешно обработан.
404 Not Found: Ресурс не найден.
500 Internal Server Error: Внутренняя ошибка сервера.
HTTPS (HyperText Transfer Protocol Secure) — это расширение HTTP, которое использует шифрование для защиты данных, передаваемых между клиентом и сервером. HTTPS обеспечивает конфиденциальность, целостность и аутентификацию данных.
HTTPS использует протоколы SSL (Secure Sockets Layer) или его более современную версию TLS (Transport Layer Security) для шифрования данных. Это предотвращает перехват и чтение данных третьими лицами.
Серверы, использующие HTTPS, имеют цифровые сертификаты, которые проверяются клиентом. Это гарантирует, что клиент общается с подлинным сервером, а не с мошенником.
Шифрование также обеспечивает целостность данных, предотвращая их изменение или подмену во время передачи.
Для использования HTTPS владелец сайта должен получить цифровой сертификат от доверенного центра сертификации (CA).
Установите сертификат на сервере и настройте его для использования HTTPS.
Обеспечьте перенаправление HTTP-трафика на HTTPS для повышения безопасности.
Защищает данные от перехвата и изменения.
Пользователи больше доверяют сайтам с HTTPS, что может повысить их активность и лояльность.
Поисковые системы, такие как Google, предпочитают сайты с HTTPS, что может улучшить их ранжирование в результатах поиска.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Интерес к функциональному программированию (ФП) возрастает по следующим основным причинам, связанным с изменениями в требованиях к производительности, масштабируемости и поддерживаемости современных программных систем.
Современные процессоры имеют многоядерную архитектуру, что требует программ, способных эффективно использовать параллельное выполнение. Функциональное программирование, благодаря отсутствию побочных эффектов и неизменяемости данных, упрощает параллельное выполнение, поскольку модули можно безопасно исполнять одновременно без риска гонок за состояние. Это особенно важно для высоконагруженных и распределённых систем.
В функциональном программировании важны "чистые" функции — такие функции, которые всегда возвращают одинаковый результат при одних и тех же входных данных и не изменяют состояния системы. Благодаря этому упрощаются тестирование и отладка, так как поведение программы предсказуемо, а ошибки легче выявить и устранить.
Принцип неизменяемости данных (или работы с их копиями) снижает вероятность появления ошибок, связанных с изменением состояния. Это повышает надёжность кода, так как изменения данных происходят через создание новых версий, а не модификацию текущих. Такой подход также облегчает поддержку системы, так как меньше вероятность случайных изменений, влияющих на другие части программы.
Функциональные принципы, такие как использование функций высшего порядка и замыканий, позволяют создавать модули, которые легко комбинируются и переиспользуются. Это способствует созданию гибкой архитектуры, что важно для разработки и поддержки сложных систем.
Популярные языки, такие как JavaScript, Python и Java, начали включать функциональные конструкции, такие как лямбда-выражения и неизменяемые коллекции, что делает функциональный подход доступным для более широкого круга разработчиков. Применение функциональных подходов в этих языках облегчает разработку масштабируемых и устойчивых приложений.
Фреймворки, такие как React (JavaScript), активно используют принципы функционального программирования, такие как "чистые" функции и неизменяемость. Это позволяет создавать более предсказуемые и стабильные пользовательские интерфейсы, что также стимулирует интерес к функциональному программированию в широком сообществе разработчиков.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
В контексте CAP-теоремы(Consistency, Availability, Partition Tolerance) системы обычно делят на три группы: CP (Consistency + Partition Tolerance), AP (Availability + Partition Tolerance) и CA (Consistency + Availability).
Системы, которые обеспечивают согласованность данных и устойчивость к разделению сети, но могут временно отказаться от доступности при возникновении сетевых сбоев. Такие системы при сетевом разделении блокируют часть данных или операций, чтобы сохранить согласованное состояние.
Оба эти хранилища данных поддерживают согласованность при сетевых сбоях, но могут ограничивать доступность данных, блокируя операции до восстановления связи.
Система координации распределённых приложений, обеспечивающая согласованность, но жертвующая доступностью в случае сетевых проблем. Она часто используется для управления конфигурацией и синхронизацией данных.
Системы, которые фокусируются на доступности и устойчивости к разделению сети, но допускают временную неидеальную согласованность данных (например, данные могут быть не сразу синхронизированы между репликами).
Эта система обеспечивает доступность и устойчивость к разделению сети, но может допускать задержки в синхронизации данных между узлами.
Поддерживает доступность и устойчивость к разделению сети, за счёт возможного отклонения в согласованности. DynamoDB был разработан Amazon для обеспечения высокой доступности даже в условиях сбоя сети.
Распределённое хранилище, оптимизированное для доступности и устойчивости к разделениям сети. Оно допускает временные рассогласования данных, которые разрешаются позже.
Системы, обеспечивающие согласованность и доступность данных, но не гарантирующие устойчивости к разделению сети. В реальных распределённых системах подобный подход встречается редко, так как любая сеть может столкнуться с разделением, что нарушит работу.
Например, PostgreSQL или MySQL в традиционной конфигурации, работающей на одном сервере без распределения данных. Они поддерживают согласованность и доступность, так как нет сетевого разделения.
Такие системы, как Redis, при отсутствии распределённой конфигурации и работе в пределах одного узла, могут обеспечить согласованность и доступность.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
MVC (Model-View-Controller) и MVP (Model-View-Presenter) — это архитектурные паттерны для разделения логики. В MVC контроллер обрабатывает логику и обновляет представление, а в MVP презентер выполняет аналогичную роль, но взаимодействие с представлением более тесное. MVP чаще используется в мобильной разработке, где логика взаимодействия с представлением более сложная.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1