Это объект, который позволяет поочередно проходить через элементы коллекции (например, списка или множества) без необходимости знать внутреннее представление этой коллекции. Итераторы предоставляют стандартный интерфейс для доступа к элементам, что делает их важной частью объектно-ориентированного программирования и функционального программирования.
Объекты, которые поддерживают протокол итерации, называются итерабельными. Примеры включают списки, кортежи, множества и словари.
В 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
HTTP (HyperText Transfer Protocol) методы представляют собой набор стандартных операций, которые используются для взаимодействия между клиентом и сервером в сети. Каждый метод определяет конкретное действие, которое должен выполнить сервер. Вот основные HTTP методы и их предназначение:
Метод GET используется для получения данных с сервера. Он запрашивает представление ресурса, не изменяя его состояния. GET запросы часто используются для запросов веб-страниц и получения данных из API.
Метод POST используется для отправки данных на сервер с целью создания или обновления ресурса. Это может включать отправку формы на веб-сайте или загрузку файла. POST запросы обычно содержат данные в теле запроса.
Метод PUT используется для обновления существующего ресурса или создания нового ресурса на сервере. Если ресурс уже существует, он будет обновлен, если нет — будет создан.
Метод DELETE используется для удаления ресурса с сервера. Запросы DELETE могут быть небезопасными, так как они изменяют состояние сервера, удаляя данные.
Метод PATCH используется для частичного обновления ресурса. В отличие от PUT, который заменяет весь ресурс, PATCH изменяет только указанные части ресурса.
Метод HEAD аналогичен GET, но без тела ответа. Используется для получения метаданных о ресурсе, таких как заголовки, без загрузки самого ресурса.
Метод OPTIONS используется для запроса информации о поддерживаемых методах на сервере или на конкретном ресурсе. Это может быть полезно для определения доступных операций перед отправкой основного запроса.
Метод CONNECT используется для установления туннеля к серверу через прокси. Обычно используется для HTTPS через прокси.
Метод TRACE выполняет тестовый запрос по маршруту до ресурса. Он возвращает запрос, полученный сервером, что может помочь в диагностике сетевых проблем или выявлении изменений в маршруте запроса.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Это инструмент, который позволяет определить и управлять многоконтейнерными Docker приложениями. С помощью Docker Compose можно описать конфигурацию всех сервисов вашего приложения в одном файле и затем легко запустить их вместе с помощью одной команды.
Docker Compose использует YAML-файл (
docker-compose.yml) для описания всех контейнеров (сервисов), которые составляют ваше приложение. В этом файле можно указать образы, настройки сети, монтируемые тома и переменные окружения.Позволяет указать зависимости между сервисами, что обеспечивает правильный порядок запуска контейнеров.
С помощью простой команды
docker-compose up можно запустить все контейнеры, указанные в docker-compose.yml. Команда docker-compose down останавливает и удаляет все контейнеры, сети и тома, созданные up.Можно легко масштабировать сервисы (запускать несколько экземпляров одного контейнера) с помощью команды
docker-compose up --scale.docker-compose.yml для веб-приложения, состоящего из веб-сервера и базы данных:version: '3'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Создает и запускает все контейнеры, указанные в
docker-compose.yml.Останавливает и удаляет все контейнеры, сети и тома, созданные
docker-compose up.Показывает статус запущенных контейнеров.
Выводит логи всех контейнеров.
Выполняет команду в запущенном контейнере.
Легко настроить и запустить все необходимые сервисы для разработки.
Простота в управлении многоконтейнерными приложениями с помощью нескольких команд.
Единый файл конфигурации для разработки, тестирования и производства, что снижает вероятность ошибок из-за различий в конфигурациях.
Легко масштабировать отдельные сервисы приложения.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это конструкция SQL, используемая для группировки строк в таблице на основе значений одного или нескольких столбцов. Она часто используется в сочетании с агрегатными функциями (такими как
COUNT, SUM, AVG, MAX, MIN), чтобы выполнять вычисления для каждой группы в результате запроса.Операция
GROUP BY группирует строки, имеющие одинаковые значения в указанных столбцах, в одну группу.В сочетании с
GROUP BY часто используются агрегатные функции для выполнения вычислений на уровне групп, а не отдельных строк.SELECT column1, aggregate_function(column2)
FROM table_name
GROUP BY column1;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это подход к разработке программного обеспечения, при котором приложение разбивается на независимые, взаимосвязанные части, называемые модулями. Каждый модуль отвечает за выполнение определенной функции или набора функций, что делает программу более структурированной, управляемой и легко поддерживаемой.
Каждый модуль скрывает свою внутреннюю реализацию и предоставляет четко определенный интерфейс для взаимодействия с другими модулями. Это уменьшает зависимость между модулями и улучшает устойчивость к изменениям.
Принцип единственной ответственности применяется к модулям, что означает, что каждый модуль отвечает за выполнение одной конкретной задачи или группы тесно связанных задач.
Модули могут быть повторно использованы в других частях программы или в других проектах, что уменьшает дублирование кода и облегчает его поддержку.
Разделение программы на модули облегчает управление проектом и его масштабирование. Изменения в одном модуле обычно не требуют изменений в других модулях, что ускоряет разработку и тестирование.
Так как модули изолированы друг от друга, их можно тестировать и отлаживать независимо. Это облегчает нахождение и исправление ошибок.
Разделение кода на небольшие, управляемые части улучшает его структуру и упрощает понимание и поддержку.
Разные команды могут работать над разными модулями параллельно, что ускоряет процесс разработки.
Изменения в одном модуле не оказывают значительного влияния на другие модули, что облегчает внедрение новых функций и улучшений.
Модули могут быть оформлены как библиотеки функций, которые предоставляют определенные функциональные возможности, например, работа с файлами, обработка строк или взаимодействие с базами данных.
В объектно-ориентированном программировании классы и объекты можно рассматривать как модули, инкапсулирующие данные и методы.
Многие языки программирования поддерживают концепцию модулей и пакетов, например, модули в Python, пакеты в Java и модули в ECMAScript (JavaScript).
На Python
# file: math_operations.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
# file: main.py
import math_operations
x = 10
y = 5
print("Addition:", math_operations.add(x, y))
print("Subtraction:", math_operations.subtract(x, y))
На JavaScript
// file: mathOperations.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// file: main.js
import { add, subtract } from './mathOperations.js';
const x = 10;
const y = 5;
console.log('Addition:', add(x, y));
console.log('Subtraction:', subtract(x, y));
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Spring обнаруживает
@Transactional и создает прокси для класса или метода.Прокси перехватывает вызов метода, аннотированного
@Transactional.Прокси делегирует управление
TransactionInterceptor, который начинает транзакцию через PlatformTransactionManager.Исходный метод выполняется.
Если метод завершился успешно, транзакция фиксируется (
commit). Если метод выбросил исключение, транзакция откатывается (rollback).Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Чтобы выбрать данные из двух таблиц в одном запросе, используется оператор 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
Это методология управления проектами и одна из наиболее популярных реализаций Agile, предназначенная для гибкой разработки программного обеспечения. Scrum помогает командам работать более эффективно и адаптироваться к изменениям в требованиях и приоритетах. Основные концепции и элементы Scrum включают следующие компоненты:
Scrum разбивает работу над проектом на небольшие итерации, называемые спринтами. Каждый спринт обычно длится от одной до четырех недель и заканчивается созданием работающего инкремента продукта.
Команды в Scrum сами управляют своей работой и распределяют задачи между участниками без вмешательства извне.
В Scrum выделяются три основных роли:
Product Owner (Владелец продукта): отвечает за создание и управление бэклогом продукта, определение приоритетов и взаимодействие с заинтересованными сторонами.
Scrum Master: помогает команде следовать принципам Scrum, устраняет препятствия и обеспечивает эффективность работы команды.
Development Team (Команда разработки): непосредственно занимается созданием продукта, включает специалистов различных профилей, необходимых для выполнения задач.
список всех требований и функций, которые должны быть реализованы в продукте. Элементы бэклога приоритизируются владельцем продукта.
список задач, которые команда обязуется выполнить в текущем спринте. Эти задачи выбираются из бэклога продукта на основе приоритетов и возможностей команды.
фиксированный период времени, в течение которого команда работает над выполнением задач из бэклога спринта. В конце спринта команда демонстрирует результат своей работы.
ежедневные короткие встречи (обычно 15 минут), на которых команда обсуждает прогресс, планирует работу на день и выявляет препятствия.
встреча в конце каждого спринта, на которой команда демонстрирует результаты своей работы заинтересованным сторонам и получает обратную связь.
встреча после завершения спринта, на которой команда анализирует свою работу, обсуждает, что было хорошо, что можно улучшить, и разрабатывает план улучшений на следующий спринт.
Scrum позволяет быстро адаптироваться к изменяющимся требованиям и приоритетам.
Частые демонстрации результата и обратная связь обеспечивают высокую степень прозрачности процесса разработки.
Регулярные проверки и ретроспективы помогают команде постоянно улучшать качество продукта и процесса.
Scrum способствует более тесному взаимодействию между членами команды и заинтересованными сторонами.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
В реляционных базах данных, операции объединения (JOIN) позволяют объединить строки из двух или более таблиц на основе связанных между собой столбцов. Существует несколько типов JOIN, каждый из которых имеет свои особенности и применим для разных ситуаций. Рассмотрим основные типы JOIN:
Объединяет строки из обеих таблиц, если они удовлетворяют условию объединения. Когда необходимо выбрать только те строки, которые имеют соответствующие значения в обеих таблицах.
SELECT *
FROM таблица1
INNER JOIN таблица2
ON таблица1.ключ = таблица2.ключ;
Возвращает все строки из левой таблицы и соответствующие строки из правой таблицы. Если соответствующей строки в правой таблице нет, в результирующем наборе данных для столбцов правой таблицы будут значения NULL. Когда необходимо выбрать все строки из одной таблицы и соответствующие данные из другой таблицы, если они существуют.
SELECT *
FROM таблица1
LEFT JOIN таблица2
ON таблица1.ключ = таблица2.ключ;
Возвращает все строки из правой таблицы и соответствующие строки из левой таблицы. Если соответствующей строки в левой таблице нет, в результирующем наборе данных для столбцов левой таблицы будут значения NULL. Когда необходимо выбрать все строки из одной таблицы (правой) и соответствующие данные из другой таблицы (левой), если они существуют.
SELECT *
FROM таблица1
RIGHT JOIN таблица2
ON таблица1.ключ = таблица2.ключ;
Возвращает все строки, когда есть совпадения либо в левой, либо в правой таблице. Если строки не соответствуют в одной из таблиц, для этой таблицы будут значения NULL. Когда необходимо выбрать все строки из обеих таблиц, независимо от того, есть ли соответствующие строки в другой таблице.
SELECT *
FROM таблица1
FULL JOIN таблица2
ON таблица1.ключ = таблица2.ключ;
Возвращает декартово произведение двух таблиц, то есть все возможные комбинации строк из обеих таблиц. Когда необходимо создать комбинации всех строк из обеих таблиц. Используется редко и с осторожностью, так как может привести к очень большому количеству строк.
SELECT *
FROM таблица1
CROSS JOIN таблица2;
Применяется для объединения таблицы самой с собой. Обычно используется для сравнения строк внутри одной и той же таблицы. Когда необходимо сопоставить строки одной таблицы друг с другом, например, для анализа иерархий или поиска парных записей.
SELECT A.*
FROM таблица A, таблица B
WHERE A.ключ = B.ключ;
Автоматически объединяет таблицы по всем столбцам с одинаковыми именами и типами данных. Когда у таблиц есть столбцы с одинаковыми именами, и нужно объединить их без явного указания условий объединения.
SELECT *
FROM таблица1
NATURAL JOIN таблица2;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM