Чтобы выбрать данные из двух таблиц в одном запросе, используется оператор JOIN. Например, INNER JOIN объединяет строки, где есть совпадения в обеих таблицах, а LEFT JOIN возвращает все строки из первой таблицы и соответствующие строки из второй, заполняя NULL там, где данных нет.
В SQL существует несколько видов операторов JOIN, которые позволяют объединять данные из двух или более таблиц на основе определенных условий. Основные типы JOIN включают
INNER JOIN, LEFT JOIN, RIGHT JOIN, и каждый из них имеет свои особенности и использование. Рассмотрим их различия на примере двух таблиц:Таблица A:
id | name
-----------
1 | Alice
2 | Bob
3 | Charlie
Таблица B:
id | city
-----------
1 | New York
3 | Los Angeles
4 | Chicago
INNER JOIN возвращает только те строки, которые имеют совпадения в обеих таблицах. Если нет совпадающих строк, такие строки не включаются в результат.SELECT A.id, A.name, B.city
FROM A
INNER JOIN B ON A.id = B.id;
Результат:
id | name | city
------------------------
1 | Alice | New York
3 | Charlie | Los Angeles
LEFT JOIN возвращает все строки из левой таблицы (A) и совпадающие строки из правой таблицы (B). Если совпадения не найдено, в результате будут строки из левой таблицы с NULL значениями для столбцов из правой таблицы.SELECT A.id, A.name, B.city
FROM A
LEFT JOIN B ON A.id = B.id;
Результат:
id | name | city
------------------------
1 | Alice | New York
2 | Bob | NULL
3 | Charlie | Los Angeles
RIGHT JOIN возвращает все строки из правой таблицы (B) и совпадающие строки из левой таблицы (A). Если совпадения не найдено, в результате будут строки из правой таблицы с NULL значениями для столбцов из левой таблицы.SELECT A.id, A.name, B.city
FROM A
RIGHT JOIN B ON A.id = B.id;
Результат:
id | name | city
------------------------
1 | Alice | New York
3 | Charlie | Los Angeles
4 | NULL | Chicago
FULL JOIN возвращает все строки, когда есть совпадение в одной из таблиц. Это объединение LEFT JOIN и RIGHT JOIN. Если совпадения не найдено, результат будет содержать NULL значения для столбцов из другой таблицы.SELECT A.id, A.name, B.city
FROM A
FULL JOIN B ON A.id = B.id;
id | name | city
------------------------
1 | Alice | New York
2 | Bob | NULL
3 | Charlie | Los Angeles
4 | NULL | Chicago
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
HTTP-методы (или глаголы) определяют тип действия, которое клиент хочет выполнить с ресурсом на сервере.
Назначение: Получение данных с сервера. Используется для чтения информации, не изменяя состояние сервера. Безопасный и идемпотентный метод (выполнение одного и того же запроса несколько раз даёт одинаковый результат).
Запрос страницы или API-ресурса
GET /users/123
Назначение: Создание нового ресурса или выполнение действий на сервере. Может изменять состояние сервера (например, добавлять новые данные). Не идемпотентен (повторный запрос создаёт новый ресурс или дублирует операцию).
Создание нового пользователя
POST /users
Назначение: Полное обновление ресурса на сервере. Идемпотентен (повторный запрос с одинаковыми данными не изменяет результат).
Обновление профиля пользователя:
PUT /users/123
Назначение: Частичное обновление ресурса. Обновляет только указанные поля, не затрагивая остальные. Не всегда идемпотентен (зависит от реализации).
Обновление только имени пользователя
PATCH /users/123
Назначение: Удаление ресурса с сервера. Идемпотентен (повторный запрос удаления того же ресурса не вызывает ошибку).
Удаление пользователя
DELETE /users/123
Назначение: Получение метаинформации о ресурсе без передачи его содержимого. Аналогичен GET, но сервер возвращает только заголовки ответа. Полезен для проверки существования ресурса или его свойств (например, размера).
HEAD /users/123
Назначение: Запрос информации о поддерживаемых сервером методах или возможностях ресурса. Используется, например, в CORS для проверки, какие методы доступны для клиента.
OPTIONS /users
Назначение: Диагностика и отладка соединения между клиентом и сервером. Возвращает запрос клиента в теле ответа, позволяя понять, какие изменения произошли на пути от клиента до сервера. Редко используется из-за риска безопасности.
TRACE /users/123
Назначение: Установка туннеля для защищённого соединения (например, через прокси). Чаще всего используется для создания HTTPS-соединений.
CONNECT www.example.com:443
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Объектно-ориентированное программирование (ООП) базируется на нескольких ключевых принципах, которые помогают создавать гибкие, понятные и легко поддерживаемые программы.
Абстракция заключается в выделении значимых характеристик объекта и игнорировании незначимых. Это позволяет создавать упрощенные модели реальных объектов.
Инкапсуляция скрывает внутренние детали объекта и позволяет взаимодействовать с объектом только через определенные методы. Это защищает данные от некорректного использования и облегчает изменение и поддержку кода.
Наследование позволяет создавать новые классы на основе существующих. Новый класс (наследник) получает все свойства и методы родительского класса и может добавлять новые или изменять существующие.
Полиморфизм позволяет объектам разных классов обрабатывать запросы одинаковым образом. Это достигается через переопределение методов в наследуемых классах и интерфейсы.
Композиция предполагает создание объектов других классов внутри данного класса. Это позволяет использовать функциональность существующих классов, не создавая зависимостей через наследование.
Агрегация - это специальный вид композиции, который позволяет одному объекту быть частью другого с возможностью существования вне этого объекта. Агрегация описывает "имеет" отношения.
Принципы ООП позволяют создавать более понятный и структурированный код.
Наследование и полиморфизм способствуют использованию уже написанных классов в новых контекстах.
Инкапсуляция и абстракция делают код легче в сопровождении и модификации.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Это принцип программирования, который гласит, что информация или логика в коде не должны дублироваться. Каждый фрагмент знаний должен иметь одно, однозначное и авторитетное представление в системе. Этот принцип был введен в книге "The Pragmatic Programmer" Эндрю Хантом и Дэвидом Томасом.
Код должен быть написан так, чтобы не повторяться. Если одно и то же действие или информация используются в нескольких местах, они должны быть вынесены в одно место и использоваться повторно.
Изменения в коде нужно вносить в одном месте, что упрощает его сопровождение и уменьшает вероятность ошибок.
Код становится более понятным и структурированным, что облегчает его чтение и понимание.
Вынос общих операций в функции или методы, которые затем можно вызывать в различных частях программы.
Создание модулей или библиотек, которые содержат повторяющуюся логику и могут быть переиспользованы в различных проектах.
Объявление констант вместо использования "магических чисел" или строковых литералов в нескольких местах кода.
Использование шаблонов в HTML, XML или других языках разметки для генерации повторяющихся структур.
Хранение конфигурационных данных в одном месте, а не встраивание их в код.
Меньшее количество кода и дублирования упрощает понимание системы и снижает её сложность.
Легче поддерживать и обновлять код, так как изменения нужно вносить в одном месте.
Снижается вероятность ошибок, поскольку одно и то же изменение не нужно делать в нескольких местах.
Переиспользование кода ускоряет разработку, так как не нужно повторно писать уже существующий функционал.
Одинаковые блоки кода, выполняющие одну и ту же задачу, размещены в разных частях программы.
Те же самые данные (например, настройки или конфигурации) хранятся в нескольких местах.
Одни и те же структуры данных определены в разных местах программы.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это два типа данных в SQL, которые используются для хранения строковых данных. Основные различия между ними касаются способа хранения данных и управления памятью.
CHAR(n) хранит строки фиксированной длины n. Если строка короче, она дополняется пробелами до указанной длины.Использует фиксированное количество памяти, равное указанной длине
n, независимо от фактической длины строки.Может быть быстрее в некоторых случаях, так как длина строк фиксирована и известна заранее, что упрощает управление памятью.
Подходит для хранения данных, которые всегда имеют одинаковую длину, например, коды стран, идентификаторы и т.д.
CREATE TABLE example (
fixed_char CHAR(10)
);
VARCHAR(n) хранит строки переменной длины, где n — это максимальная длина строки. Реальная длина строки определяется по количеству символов в ней.Использует только столько памяти, сколько необходимо для хранения фактической длины строки, плюс дополнительные байты для хранения информации о длине строки.
Может быть менее эффективным в некоторых случаях по сравнению с
CHAR, так как длина строки не фиксирована и требует дополнительной обработки для управления памятью.Подходит для хранения данных, длина которых может варьироваться, например, имена, адреса, описания и т.д.
CREATE TABLE example (
variable_char VARCHAR(50)
);
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это метод, используемый для оценки значений функции в точках, находящихся между известными значениями. В программировании и математике интерполяция помогает найти промежуточные значения между данными точками, что особенно полезно в задачах аппроксимации, анализа данных и компьютерной графики.
Самый простой и широко используемый метод интерполяции. Предполагает, что значения между двумя известными точками изменяются линейно.
Использует полиномы для аппроксимации значений функции. Чем выше степень полинома, тем точнее можно аппроксимировать функцию, но это также может привести к проблемам с осцилляциями между точками (эффект Рунге). Интерполяция Лагранжа, интерполяция Ньютона.
Использует кусочно-полиномиальные функции (сплайны) для интерполяции. Самый популярный вид — кубические сплайны, которые обеспечивают гладкую и плавную кривую между точками. Преимущество сплайнов в том, что они минимизируют осцилляции и обеспечивают гладкость первой и второй производных.
Использует синусоидальные функции для интерполяции, что полезно для данных, которые имеют волнообразный характер.
Интерполяция используется для заполнения пропущенных данных, аппроксимации значений в точках, где данные не были измерены, и для сглаживания данных.
Интерполяция используется для анимации и отрисовки графики, включая интерполяцию цветов, координат и других параметров.
Интерполяция используется для создания контурных карт, аппроксимации высот, температуры и других параметров на основе точечных измерений.
Интерполяция применяется для увеличения разрешения сигнала и восстановления пропущенных данных.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1💊1
Это исполняемый код (например, SQL-скрипты), который хранится и выполняется непосредственно в базе данных. Разработка бизнес-логики внутри хранимых процедур является спорной практикой. Она имеет как преимущества, так и недостатки в зависимости от требований системы, архитектуры и команды разработки.
Хранимые процедуры выполняются на сервере базы данных, что уменьшает накладные расходы на передачу данных между приложением и базой. Обработка больших объёмов данных становится быстрее, так как нет необходимости отправлять их в приложение и обратно.
Вся логика предметной области сосредоточена в одном месте (в БД), что облегчает контроль доступа и выполнение важных операций. Удобно для многослойных систем, где несколько клиентских приложений используют одну базу данных.
Вместо передачи большого количества SQL-запросов между сервером базы данных и приложением, выполняется один вызов процедуры.
Системы могут ограничить доступ к таблицам и предоставить доступ только к хранимым процедурам, что снижает риск несанкционированного доступа. Встроенные механизмы контроля прав доступа (например, в PostgreSQL и Oracle).
Современные СУБД поддерживают процедурные языки, такие как PL/pgSQL (PostgreSQL), T-SQL (SQL Server) или PL/SQL (Oracle), которые предоставляют функции, циклы и исключения, что позволяет реализовать сложную логику.
При необходимости переноса части функциональности между разными приложениями (например, Web-приложением и мобильным клиентом) логика в БД остаётся неизменной.
Хранимые процедуры часто сложны для чтения, отладки и тестирования по сравнению с кодом на языке программирования (например, Java, C#, Python). Версионный контроль затруднён, так как БД не всегда удобно интегрируется с системами контроля версий (Git).
Логика, написанная в хранимых процедурах, привязывает систему к конкретной СУБД (например, Oracle или SQL Server). Переход на другую БД становится дорогостоящим и трудоёмким.
Сервер базы данных становится "узким местом" системы. Если бизнес-логика выполняется только на сервере БД, это может привести к перегрузке, особенно при высоком трафике.
Инструменты для юнит-тестирования и автоматизированного тестирования хранимых процедур менее развиты, чем для традиционного кода приложений. Тестирование бизнес-логики требует специальной инфраструктуры (например, отдельной тестовой БД).
Внедрение логики в БД нарушает принципы многослойной архитектуры, такие как Separation of Concerns (разделение ответственности). Логика бизнес-уровня смешивается с уровнем данных.
Разработка и деплой изменений в хранимых процедурах требуют взаимодействия с базой данных, что замедляет процесс внедрения обновлений. Изменения в хранимых процедурах могут повлиять на производительность всей системы.
Написание и оптимизация хранимых процедур требуют специфических навыков SQL и понимания особенностей СУБД. Не все разработчики владеют этими навыками.
Если необходимо минимизировать сетевые вызовы и максимально эффективно обрабатывать большие объёмы данных.
Если бизнес-логика должна быть единой для нескольких клиентов (например, мобильного приложения, веб-сервиса).
Если безопасность и контроль доступа являются приоритетом.
Например, для старых систем или проектов, где миграция на новую архитектуру невозможна.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Индексы являются ключевым механизмом для улучшения производительности запросов в базах данных. Они позволяют значительно ускорить операции поиска и выборки данных, снижая необходимость полного сканирования таблицы. Вот как работают индексы и для чего они нужны.
Индексы организованы в специализированные структуры данных, такие как B-деревья, B+-деревья или хеш-таблицы. Эти структуры оптимизированы для быстрого поиска, вставки и удаления данных.
Когда создается индекс на один или несколько столбцов таблицы, база данных строит структуру данных, которая хранит значения этих столбцов в отсортированном виде, вместе с указателями на соответствующие строки таблицы. Это позволяет базе данных быстро находить нужные строки по значению индекса.
При выполнении запроса, который включает условия поиска по индексируемым столбцам, база данных может использовать индекс для быстрого нахождения строк. Вместо полного сканирования таблицы, база данных проходит по дереву индекса и быстро находит нужные строки.
Когда данные в таблице обновляются (добавляются новые строки, изменяются или удаляются существующие), индексы также должны обновляться. Это может привести к дополнительным затратам на время вставки и обновления данных, так как требуется поддерживать актуальность структуры индекса.
Правильный выбор индексов важен для оптимальной производительности. Индексы следует создавать на столбцах, которые часто используются в условиях поиска, соединениях и сортировках. Избыточные индексы могут увеличивать объем хранения и снижать производительность операций вставки и обновления.
Это уникальный индекс, который не допускает дубликатов и обычно используется для идентификации строк в таблице.
Обеспечивает уникальность значений в индексируемом столбце, но допускает одно или несколько NULL значений.
Используется для ускорения поиска и может содержать дублирующиеся значения.
Индекс, созданный на нескольких столбцах. Полезен, когда запросы часто включают условия на несколько столбцов одновременно.
Определяет физический порядок хранения строк в таблице. У таблицы может быть только один кластерный индекс, так как строки могут быть отсортированы только одним способом.
Запросы типа
SELECT * FROM users WHERE age > 30 значительно ускоряются, если столбец age индексирован.Запросы типа
SELECT * FROM users ORDER BY name будут быстрее, если столбец name индексирован.Запросы, которые соединяют несколько таблиц по индексируемым столбцам, выполняются быстрее, так как индексы облегчают поиск соответствующих строк.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💊1
Это объект, который позволяет поочередно проходить через элементы коллекции (например, списка или множества) без необходимости знать внутреннее представление этой коллекции. Итераторы предоставляют стандартный интерфейс для доступа к элементам, что делает их важной частью объектно-ориентированного программирования и функционального программирования.
Объекты, которые поддерживают протокол итерации, называются итерабельными. Примеры включают списки, кортежи, множества и словари.
В Python, чтобы объект был итерабельным, он должен реализовать метод
__iter__(), который возвращает итератор.Итератор — это объект, который реализует методы
__iter__() и __next__(). Метод __next__() возвращает следующий элемент последовательности, а когда элементы заканчиваются, возбуждает исключение StopIteration.Пример с использованием встроенного итератора
numbers = [1, 2, 3, 4, 5]
iterator = iter(numbers) # Получение итератора из списка
print(next(iterator)) # Вывод: 1
print(next(iterator)) # Вывод: 2
print(next(iterator)) # Вывод: 3
print(next(iterator)) # Вывод: 4
print(next(iterator)) # Вывод: 5
# print(next(iterator)) # Вызывается StopIteration
Пример создания собственного итератора
class MyIterator:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
else:
self.current += 1
return self.current - 1
# Использование собственного итератора
my_iter = MyIterator(1, 5)
for num in my_iter:
print(num) # Вывод: 1 2 3 4
Итераторы предоставляют единый интерфейс для прохода по элементам коллекции, независимо от их типа.
Итераторы генерируют элементы по одному, что экономит память при работе с большими наборами данных.
Итераторы инкапсулируют логику обхода элементов, упрощая код и делая его более читаемым.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
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
👍1
Это программное обеспечение, которое позволяет пользователям просматривать и взаимодействовать с информацией в Интернете. Основные функции браузера включают получение, рендеринг и отображение веб-страниц, а также выполнение веб-приложений.
Пользователь вводит URL (Uniform Resource Locator) в адресную строку браузера. Браузер определяет тип протокола (например, HTTP или HTTPS) и преобразует доменное имя в IP-адрес с помощью DNS (Domain Name System). Затем браузер отправляет HTTP-запрос к веб-серверу по указанному IP-адресу.
Веб-сервер получает запрос и отправляет HTTP-ответ, который обычно содержит HTML-документ, CSS-стили, JavaScript-код и другие ресурсы, такие как изображения и видео. Ответ передается обратно браузеру.
Браузер анализирует полученный HTML-документ и строит дерево DOM (Document Object Model), представляющее структуру страницы. Одновременно браузер загружает и обрабатывает связанные ресурсы (CSS, JavaScript, изображения).
Браузер анализирует CSS-файлы и строит CSSOM (CSS Object Model), описывающую, как элементы должны отображаться. DOM и CSSOM объединяются для создания render tree, которая содержит видимые элементы страницы с их стилями.
Render tree используется для определения положения и внешнего вида элементов на экране. Браузер выполняет layout (разметку) элементов и отрисовывает их на экране.
Браузер интерпретирует и выполняет JavaScript-код, который может изменять DOM и CSSOM. JavaScript может также взаимодействовать с сервером через AJAX-запросы для динамического обновления страницы без перезагрузки.
Браузер обрабатывает взаимодействие пользователя с элементами страницы (клики, ввод текста и т.д.). Изменения, вызванные действиями пользователя или выполнением JavaScript, могут обновлять render tree и перерисовывать элементы.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Это распределённая система контроля версий, разработанная Линусом Торвальдсом в 2005 году. Она предназначена для отслеживания изменений в исходном коде во время разработки программного обеспечения. Git позволяет нескольким разработчикам работать над одним и тем же проектом одновременно, не опасаясь потерять работу или перезаписать изменения друг друга.
Это хранилище для проекта, в котором хранятся все файлы и история их изменений.
Зафиксированный снимок текущего состояния файлов в репозитории. Коммиты образуют историю изменений проекта.
Отдельная линия разработки. Ветви позволяют параллельно работать над разными функциями или исправлениями без вмешательства в основную кодовую базу.
Процесс объединения изменений из одной ветви в другую. Обычно используется для интеграции новых функций или исправлений из отдельных ветвей в основную ветвь.
Создание копии удалённого репозитория на локальной машине разработчика.
Создание копии чужого репозитория (обычно на платформе вроде GitHub) для внесения собственных изменений без воздействия на оригинальный проект.
Запрос на включение изменений из одной ветви в другую, часто используемый в коллаборативных платформах (например, GitHub, GitLab).
Удалённый репозиторий, который может быть связан с локальным репозиторием. Основные команды взаимодействуют с ним для синхронизации данных.
Создание нового локального репозитория.
Клонирование удалённого репозитория на локальную машину.
Добавление изменений в индекс (стадия подготовки к коммиту).
Создание коммита с заданным сообщением.
Проверка состояния файлов в рабочем каталоге и индексе.
Просмотр истории коммитов.
Управление ветвями (создание, просмотр, удаление).
Переключение между ветвями или возврат к определённому коммиту.
Слияние указанной ветки с текущей.
Получение изменений из удалённого репозитория и слияние с текущей веткой.
Отправка изменений из локального репозитория в удалённый.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊1
Разница между SQL и NoSQL базами данных заключается в их архитектуре, структуре, методах хранения данных и использовании. Рассмотрим эти различия подробнее.
SQL (Structured Query Language) базы данных
Реляционные базы данных: SQL базы данных являются реляционными и используют таблицы для хранения данных. Каждая таблица состоит из строк и столбцов, что позволяет структурировать данные в виде отношений.
Схемы данных: SQL базы данных требуют четко определенных схем (schemas), которые строго контролируют структуру данных. Все записи в таблице должны следовать заранее определенной структуре.
Язык запросов: SQL использует структурированный язык запросов для манипуляции данными. Язык SQL стандартизирован и включает команды для создания, чтения, обновления и удаления данных (CRUD).
Нереляционные базы данных: NoSQL базы данных не обязательно используют таблицы для хранения данных. Вместо этого они могут использовать различные модели данных, такие как документы, графы, ключ-значение и столбцы
Гибкость схем: NoSQL базы данных часто не требуют фиксированных схем. Это позволяет хранить данные разной структуры в одной и той же коллекции или таблице.
Разнообразие языков запросов: В NoSQL базах данных отсутствует единый стандарт языка запросов. Они могут использовать различные методы доступа к данным, включая REST API и собственные языки запросов.
Вертикальная масштабируемость: SQL базы данных обычно масштабируются вертикально, то есть увеличивая мощность сервера (CPU, RAM, дисковое пространство).
Транзакции и консистентность: SQL базы данных поддерживают ACID транзакции (Atomicity, Consistency, Isolation, Durability), что обеспечивает высокую надежность и консистентность данных.
Горизонтальная масштабируемость: NoSQL базы данных предназначены для горизонтального масштабирования, что позволяет распределять данные по множеству серверов.
Гибкость и скорость: NoSQL базы данных обычно более гибки и могут обеспечивать высокую производительность при работе с большими объемами данных и высокими нагрузками на запись и чтение.
MySQL, PostgreSQL, Oracle, Microsoft SQL Server.
Финансовые системы, системы управления запасами, системы управления клиентами (CRM), где требуется сложные запросы и транзакции.
MongoDB, Cassandra, Redis, Couchbase.
Системы больших данных, реального времени аналитика, социальные сети, приложения для интернета вещей (IoT), где требуется высокая производительность и гибкость.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Разработчики могут не любить Java по нескольким причинам, связанным с особенностями языка, его экосистемы и исторической репутацией.
Java часто критикуют за необходимость писать много шаблонного (boilerplate) кода. Например, для выполнения простых операций, таких как создание POJO-классов (Plain Old Java Object), разработчики вынуждены прописывать геттеры, сеттеры, конструкторы, методы
equals и hashCode. Несмотря на наличие библиотек, таких как Lombok, для уменьшения шаблонности, это остается одной из претензий к языку.Исторически Java обновлялась медленно, что вызывало недовольство. До перехода на модель выпуска версий каждые шесть месяцев (с Java 9), промежутки между релизами были слишком большими. Это приводило к отставанию языка от более динамично развивающихся конкурентов, таких как Kotlin, Scala или Python.
Некоторые считают Java "устаревшим" языком из-за особенностей, таких как ручное управление многопоточностью (до появления улучшенных инструментов в Java 8 и последующих версиях) или отсутствие "современного" синтаксиса (например, до появления
var).Раньше Java часто ассоциировалась с медленной работой из-за интерпретируемой природы байт-кода и большого объема памяти, необходимого для запуска JVM. Хотя современные реализации JVM (HotSpot, GraalVM) сделали Java очень быстрой, этот стереотип все еще живет.
В крупных проектах на Java все еще можно столкнуться с использованием старых библиотек и инструментов, таких как XML-конфигурации для Spring. Такие проекты требуют больше усилий для модернизации и поддержки.
Java — строго типизированный язык. Это обеспечивает надежность и удобство поддержки, но снижает гибкость при разработке прототипов или экспериментировании. Это особенно заметно в сравнении с языками, такими как Python или JavaScript.
Kotlin, развиваемый JetBrains, стал официальным языком разработки для Android в 2017 году. Он предлагает более лаконичный синтаксис, мощные функции работы с null-значениями, и в целом воспринимается как более "современный" язык.
Java обладает огромной экосистемой, которая может быть одновременно преимуществом и недостатком. Иногда требуется глубокое понимание JVM, инструментов сборки (Maven, Gradle), и других особенностей.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Блокировки (локи) в базе данных - это механизмы, которые управляют доступом к данным, чтобы обеспечить их целостность и предотвратить конфликты при одновременном доступе нескольких транзакций.
ACCESS SHARE: Позволяет чтение данных, блокирует команды, изменяющие таблицу.
ROW SHARE: Применяется для команд SELECT FOR UPDATE и SELECT FOR SHARE.
ROW EXCLUSIVE: Используется при вставке, обновлении или удалении строк.
SHARE UPDATE EXCLUSIVE: Используется для команд VACUUM.
SHARE: Обеспечивает видимость текущего состояния данных (ANALYZE).
SHARE ROW EXCLUSIVE: Используется для операций, требующих более строгого контроля (CREATE INDEX CONCURRENTLY).
EXCLUSIVE: Требуется для команд, изменяющих структуру таблицы (ALTER TABLE).
ACCESS EXCLUSIVE: Блокирует все команды, включая SELECT (DROP TABLE, ALTER TABLE).
SELECT FOR UPDATE: Блокирует строки для изменения.
SELECT FOR NO KEY UPDATE: Похоже на SELECT FOR UPDATE, но позволяет другим транзакциям выполнять SELECT FOR SHARE и SELECT FOR KEY SHARE.
SELECT FOR SHARE: Блокирует строки для чтения.
SELECT FOR KEY SHARE: Похоже на SELECT FOR SHARE, но позволяет другим транзакциям выполнять SELECT FOR NO KEY UPDATE и SELECT FOR UPDATE.
Устанавливаются вручную для синхронизации произвольных ресурсов.
pg_advisory_lock: Устанавливает консультативную блокировку.
pg_advisory_unlock: Снимает консультативную блокировку.
pg_try_advisory_lock: Пытается установить консультативную блокировку без ожидания.
Обеспечивают корректность данных при одновременном доступе нескольких транзакций.
Выполнение каждой транзакции в изолированном контексте.
Предотвращение одновременного изменения данных, что может привести к их несогласованности.
Блокировки могут предотвращать одновременное изменение состояния товара.
При переводе средств используются блокировки для предотвращения одновременного списания или зачисления.
При одновременном редактировании одной записи несколькими пользователями.
Ситуация, когда транзакции блокируют друг друга, ожидая освобождения ресурсов.
Блокировки высокой гранулярности могут снижать производительность.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Это процесс создания системы, которая продолжает корректно работать даже при частичных сбоях. Отказоустойчивость позволяет приложению оставаться доступным, минимизировать потери данных и поддерживать положительный пользовательский опыт в случае непредвиденных ситуаций.
Балансировщики нагрузки распределяют входящий трафик между несколькими серверами, чтобы снизить нагрузку на отдельные серверы и избежать перегрузок. В случае сбоя одного сервера запросы автоматически перенаправляются на работающие экземпляры. Использование балансировщика повышает масштабируемость системы, поскольку позволяет легко добавлять или убирать серверы по мере необходимости.
Развертывание приложения на нескольких серверах (в кластере) позволяет избежать единой точки отказа (SPOF — Single Point of Failure). Горизонтальное масштабирование даёт возможность добавлять дополнительные серверы при увеличении нагрузки, что повышает отказоустойчивость и общую производительность системы. Сервисы, такие как Kubernetes и Docker Swarm, упрощают управление и оркестрацию контейнеров в кластере, автоматизируя процесс развертывания, обновлений и балансировки нагрузки.
Важные данные должны регулярно сохраняться в резервных копиях и реплицироваться на несколько узлов или в несколько дата-центров. Репликация базы данных (например, master-slave или master-master репликация) обеспечивает доступность данных, даже если один из узлов выходит из строя. Для обеспечения целостности данных реплики могут быть синхронными (обеспечивают актуальность данных на всех узлах, но добавляют задержку) или асинхронными (с меньшей задержкой, но возможностью устаревания данных).
Использование кешей (Redis, Memcached) снижает нагрузку на базу данных и позволяет быстрее обрабатывать запросы, снижая риски сбоев из-за высокой нагрузки. Content Delivery Network (CDN) распределяет контент по серверам, находящимся близко к пользователю. Это снижает нагрузку на основной сервер и обеспечивает доступность контента в случае перегрузки или отказа в одном из центров обработки данных.
Настройка систем мониторинга (например, Prometheus, Grafana, New Relic) позволяет оперативно выявлять сбои и реагировать на проблемы. Системы автоматического восстановления могут перезапускать упавшие серверы или контейнеры. Например, инструменты оркестрации, такие как Kubernetes, могут автоматически восстанавливать неработающие контейнеры. Настройка системы оповещений для обнаружения потенциальных проблем (например, медленного ответа сервера) позволяет вовремя реагировать на них и предотвращать крупные сбои.
Для работы с критически важными задачами, которые могут быть временно отложены, целесообразно использовать системы очередей сообщений (например, RabbitMQ, Kafka). Очереди позволяют обрабатывать запросы асинхронно, обеспечивая бесперебойную работу системы при перегрузках. Если один компонент выходит из строя, другой может продолжить обработку сообщений из очереди после восстановления.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊1
Git-flow — это модель ветвления в Git, предложенная Винсентом Дриссеном, которая структурирует разработку, упрощает выпуск версий и поддерживает стабильность проекта.
master: Эта ветка содержит стабильные и готовые к выпуску версии продукта. Каждый коммит в master должен представлять собой релизную версию.
develop: Эта ветка используется для интеграции всех новых разработок. Она содержит последний готовый к выпуску код, но ещё может быть нестабильной.
feature: Эти ветки создаются для разработки новых функций. Они ответвляются от develop и сливаются обратно в develop после завершения работы. Например,
feature/новая-функция.release: Эти ветки создаются для подготовки нового релиза. Они ответвляются от develop, и после завершения всех необходимых исправлений и тестирования сливаются в master и develop. Например
release/1.0.0hotfix: Эти ветки используются для срочных исправлений в стабильной версии продукта. Они ответвляются от master и после завершения работы сливаются в master и develop. Например,
hotfix/исправление-ошибки.Создайте ветку feature от develop.
Разработайте новую функцию.
Слейте feature ветку обратно в develop.
Создайте ветку release от develop.
Проведите финальное тестирование и внесите мелкие исправления.
Слейте release ветку в master и develop.
Создайте тег для новой версии на master.
Создайте ветку hotfix от master.
Исправьте проблему.
Слейте hotfix ветку в master и develop.
Создайте тег для новой версии на master.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это один из фундаментальных принципов объектно-ориентированного программирования (ООП), который позволяет объектам разного типа обрабатывать данные по-разному, используя один и тот же интерфейс. Основная идея полиморфизма заключается в том, что метод или функция могут принимать объекты разных классов и корректно выполнять для них свою работу, не зная их конкретного типа заранее.
Это форма полиморфизма, при которой функция или метод могут быть применены к аргументам разных типов. В ООП это достигается через наследование и интерфейсы. Классический пример – это использование базового класса или интерфейса, когда конкретная реализация определяется в дочерних классах. Пример: метод
draw() может быть определен в интерфейсе Shape, а конкретная реализация этого метода – в классах Circle, Square, Triangle.Это форма полиморфизма, при которой функции или методы могут работать с любыми типами данных. Обычно это реализуется через использование обобщенных типов (generics). Например, в языке Java или C# можно создать класс или метод, который работает с любым типом данных, используя синтаксис шаблонов (generics).
Это форма полиморфизма, при которой метод конкретного объекта выбирается во время выполнения программы. Обычно это достигается с помощью виртуальных функций и механизма позднего связывания (late binding). Пример: вызов метода
move() у объекта, который может быть как автомобилем, так и самолетом. Виртуальная функция обеспечивает вызов правильной реализации метода в зависимости от реального типа объекта.Полиморфизм позволяет писать более общий и абстрактный код. Вместо работы с конкретными типами, программист может работать с более абстрактными интерфейсами или базовыми классами, что упрощает расширение системы и поддержку кода.
Полиморфизм позволяет программистам думать о более высокоуровневых концепциях, не углубляясь в детали реализации конкретных классов. Это делает код более понятным и легким для восприятия.
Полиморфизм помогает следовать этому принципу, который гласит, что "программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для изменения". То есть, для добавления новых функциональностей не нужно изменять существующий код, достаточно создать новый подкласс или реализовать новый интерфейс.
Благодаря полиморфизму, можно избежать дублирования кода, создавая более общие решения и переиспользуя их в разных частях программы.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Представляют собой системы управления базами данных, которые не используют традиционную реляционную модель. Эти базы данных разработаны для работы с большими объемами данных, высокой скоростью обработки запросов и гибкостью в моделировании данных.
Хранят данные в формате документов (например, JSON, BSON, XML). Например, MongoDB, CouchDB. Подходит для приложений, работающих с данными, которые могут иметь гибкую и изменяющуюся структуру.
Хранят данные в виде столбцов, а не строк. Это позволяет эффективно обрабатывать большие объемы данных и выполнять аналитические запросы. Например Apache Cassandra, HBase. Аналитика, обработка больших данных, телекоммуникации.
Хранят данные в виде пар "ключ-значение". Очень проста по своей природе и обеспечивает быструю работу. Например Redis, Riak, DynamoDB. Кеширование, сессии пользователей, реализация простых хранилищ данных.
Хранят данные в виде графов с узлами, ребрами и свойствами. Отлично подходят для моделирования связей и взаимосвязей между данными. Например Neo4j, OrientDB. Социальные сети, рекомендательные системы, управление сетями.
Графовые базы данных для моделирования взаимоотношений между пользователями.
Документные базы данных для хранения информации о продуктах с различной структурой данных.
Колонковые базы данных для выполнения сложных аналитических запросов на больших объемах данных.
Ключ-значение базы данных для быстрого доступа к часто используемым данным.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Программирование включает множество принципов, которые помогают разработчикам создавать эффективный, читаемый и поддерживаемый код.
Каждый класс должен иметь одну единственную ответственность. Пример: Класс
Invoice должен обрабатывать только логику, связанную с инвойсами, а не управление базой данных или пользовательский интерфейс.Классы должны быть открыты для расширения, но закрыты для модификации. Пример: Добавление нового типа фигуры без изменения существующего кода классов фигур.
Объекты базового класса должны быть заменяемыми объектами подклассов без изменения правильности программы. Пример: Если класс
Bird имеет метод fly, то подкласс Penguin не должен его нарушать.Клиенты не должны быть вынуждены зависеть от интерфейсов, которые они не используют. Пример: Разделение крупного интерфейса на несколько специфичных интерфейсов.
Модули верхнего уровня не должны зависеть от модулей нижнего уровня; оба должны зависеть от абстракций. Пример: Использование интерфейсов для взаимодействия между классами вместо конкретных реализаций.
Избегайте дублирования кода, вынеся повторяющиеся части в отдельные функции или классы. Пример: Использование функций для повторяющихся блоков кода.
Держите код простым и избегайте сложных решений, когда более простое решение будет работать. Пример: Не используйте сложные алгоритмы там, где достаточно простого цикла.
Не реализовывайте функциональность, которая не нужна прямо сейчас. Пример: Добавляйте новые функции только тогда, когда в них есть необходимость.
Разделяйте разные аспекты программы, чтобы каждый модуль решал отдельную задачу. Пример: Отдельные модули для бизнес-логики, пользовательского интерфейса и доступа к данным.
Объект должен общаться только с непосредственными "друзьями" и не тянуть цепочку вызовов. Пример: Использование методов класса без вызова методов через несколько объектов.
Ошибки должны быть выявлены как можно раньше. Пример: Проверка входных данных на валидность в начале функции.
Предпочтение композиции перед наследованием для достижения гибкости. Пример: Использование объектов других классов для расширения функциональности вместо создания подклассов.
Сотрудничество с заказчиком важнее согласования условий контракта. Пример: Регулярные встречи с заказчиком для обсуждения прогресса и изменений.
Готовность к изменениям важнее следования плану. Пример: Внедрение новых требований, даже если они появились на поздних стадиях разработки.
Управление инфраструктурой с помощью кода и автоматизации. Пример: Использование Terraform или Ansible для развертывания серверов.
Автоматизация сборки, тестирования и развертывания приложений. Пример: Использование Jenkins или GitHub Actions для автоматизации процессов разработки.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это код, который устарел, но продолжает использоваться в производственных системах. Он может быть плохо документирован, сложным для понимания, не покрытым тестами или написанным на устаревших технологиях. Работа с таким кодом — частая задача разработчиков, требующая особого подхода.
Без тестов сложно понять, работает ли изменение корректно.
Легаси-код часто плохо документирован и написан без соблюдения современных стандартов.
Легаси-код может быть привязан к фреймворкам или библиотекам, которые больше не поддерживаются.
Даже небольшие изменения могут привести к непредсказуемым ошибкам.
Из-за сложности внесения изменений и отсутствия автоматизированных процессов разработка занимает больше времени.
Прежде чем вносить изменения, изучите код и его окружение: Проведите рефакторинг "окружающего контекста" (например, упростите сложные методы). Используйте дебаггеры, чтобы понять поведение системы. Привлеките экспертов, знакомых с системой, если они доступны. Постарайтесь выделить области, которые наиболее часто модифицируются, чтобы сосредоточиться на них.
Перед внесением изменений напишите базовые unit-тесты или интеграционные тесты: Начните с регрессионных тестов для фиксации текущего поведения. Используйте "Characterization Tests", чтобы зафиксировать, как работает система, а не как она должна работать. Постепенно увеличивайте покрытие тестами.
Если возможно, изолируйте старые модули, минимизируя их влияние на новую разработку. Используйте "стратегию шва" (Seam Technique) для упрощения взаимодействия с легаси-кодом: Добавьте промежуточный слой между новым и старым кодом. Это позволит вам изменять и тестировать функциональность поэтапно.
Разделяйте большие методы и классы на мелкие, с понятной ответственностью. Переименовывайте переменные и методы для улучшения читаемости. Используйте шаблоны проектирования, если это обоснованно. Применяйте правило "Boy Scout Rule": оставляйте код чуть лучше, чем он был.
Постепенно выделяйте функциональность в независимые модули или микросервисы: Определите ключевые компоненты системы. Реализуйте новые функции вне легаси-кода, минимизируя его изменения.
Если легаси-код зависит от устаревших библиотек или фреймворков, поэтапно обновите их: Обновляйте зависимости в порядке их важности и уровня риска. Тщательно тестируйте каждое обновление.
Если документация отсутствует, создайте её: Описывайте ключевые части системы. Добавляйте комментарии в код, объясняющие сложные места.
Используйте статический анализатор кода (например, SonarQube, ReSharper) для выявления проблем и повышения качества.
Полный рефакторинг "с нуля" без понимания бизнеса и текущих процессов. Внесение изменений без тестирования. Игнорирование влияния изменений на систему в целом.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM