Backend
3.95K subscribers
35 photos
706 links
Комьюнити Backend программистов.
Python, Java, Golang, PHP, C#, C/C++, DevOps

Сайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp
Download Telegram
Структурные шаблоны проектирования

Эти шаблоны в основном посвящены компоновке объектов (object composition). То есть тому, как сущности могут друг друга использовать. Ещё одно объяснение: структурные шаблоны помогают ответить на вопрос «Как построить программный компонент?»

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

Список шаблонов:

• Адаптер
• Мост
• Компоновщик
• Декоратор
• Фасад
• Приспособленец
• Заместитель

О каждом из ним мы подробно поговорим в последующих постах, оставайтесь с нами!
👍7
Что такое APO

«Avoid Premature Optimization / Избегайте преждевременной оптимизации»

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

Поймите правильно, предвидеть, что произойдет что-то плохое – это хорошо. Но прежде чем вы погрузитесь в детали реализации, убедитесь, что эти оптимизации действительно полезны.

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

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

Многие считают преждевременную оптимизацию корнем всех зол.
👍12🔥1
​​Закрыт ли доступ к тестовой версии вашей разработки?

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

Что делать? С самого начала вам нужна какая‑то тактика!

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

Ограничьте доступ к любым тестовым версиям: убедитесь, что dev, qa, staging и другие версии сайта, кроме финальной, нельзя открыть просто так. Необходимо произвести такую настройку, чтобы они были доступны, например, только через VPN.

Защитите тестовые версии от индексации. Даже если тестовые версии вашего проекта доступны только через VPN и находятся на отдельных секретных доменах, их следует защитить от индексации поисковиками с помощью файла robots.txt или метатегов noindex.
​​Что такое JWT

JWT (JSON Web Token) - это стандарт для создания токенов, которые могут использоваться для аутентификации и передачи информации между сторонами. Он использует формат JSON.

Вот как работает JWT:

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

2. Подпись токена: Токен подписывается с использованием секретного ключа. Это делает его неподдельным и обеспечивает его целостность.

3. Передача токена: Токен передается между клиентом и сервером через HTTP заголовок, обычно в форме Authorization: Bearer <токен>.

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

JWT обычно используется для создания токенов с информацией о пользователе после успешной аутентификации, чтобы идентифицировать пользователя при последующих запросах без необходимости повторной отправки учетных данных. Он также может использоваться для передачи других данных между сторонами, таких как права доступа или другие свойства пользователя.
👍13👾2
​​Вывод актуальных изменений в файл Git

Пример команды: git log -p filename

С помощью команд git log -p или git log -p filename можно посмотреть не только примечание к коммиту, автора и дату, но также сделанные в этом коммите изменения.

Далее можно использовать функцию поиска утилиты less, набрав «слеш» и введя поисковый запрос: /{{поисковый-запрос}} (используйте маленькую "n" для перехода к следующему результату поиска и большую "N" для того, чтобы вернуться к предыдущему).
👍5
Адаптер

Приведем аналогию: Допустим, у вас на карте памяти есть какие-то картинки. Их нужно перенести на компьютер. Нужен адаптер, совместимый с входным портом компьютера, в который можно вставить карту памяти. В данном примере адаптер — это картридер. Ещё один пример: переходник, позволяющий использовать американский блок питания с российской розеткой. Третий пример: переводчик — это адаптер, соединяющий двух людей, говорящих на разных языках.

Шаблон «Адаптер» позволяет помещать несовместимый объект в обёртку, чтобы он оказался совместимым с другим классом.

Шаблон проектирования «Адаптер» позволяет использовать интерфейс существующего класса как другой интерфейс. Этот шаблон часто применяется для обеспечения работы одних классов с другими без изменения их исходного кода.
👍8
Пример структурного шаблона Адаптер

Представим себе охотника на львов.

Создадим интерфейс Lion, который реализует все типы львов.

interface Lion
{
public function roar();
}

class AfricanLion implements Lion
{
public function roar()
{
}
}

class AsianLion implements Lion
{
public function roar()
{
}
}


Охотник должен охотиться на все реализации интерфейса Lion.

class Hunter
{
public function hunt(Lion $lion)
{
}
}

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


// Это нужно добавить
class WildDog
{
public function bark()
{
}
}

// Адаптер вокруг собаки сделает её совместимой с охотником
class WildDogAdapter implements Lion
{
protected $dog;

public function __construct(WildDog $dog)
{
$this->dog = $dog;
}

public function roar()
{
$this->dog->bark();
}
}


Теперь WildDog может вступить в игру действие благодаря WildDogAdapter.


$wildDog = new WildDog();
$wildDogAdapter = new WildDogAdapter($wildDog);

$hunter = new Hunter();
$hunter->hunt($wildDogAdapter);
🔥9🤔6
Что такое Бритва Оккама

Бри́тва О́ккама (иногда ле́звие О́ккама) — методологический принцип, в кратком виде гласящий: «Не следует множить сущее без необходимости» (либо «Не следует привлекать новые сущности без крайней на то необходимости»).

— Википедия


Что это значит в мире программирования? Не создавайте ненужных сущностей без необходимости. Будьте прагматичны — подумайте, нужны ли они, поскольку они могут в конечном итоге усложнить вашу кодовую базу.
👍51
​​Скрываем реальный IP адрес, задраиваем/закрываем порты

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

Спрятав реальный IP‑адрес сервера, вы сразу затрудните задачу потенциальным атакующим. В этом вопросе могут оказаться весьма полезными CDN (сеть доставки контента) или сервисы защиты от DDoS‑атак. Например, есть такое популярное и при этом бесплатное решение, как CloudFlare, которое сочетает в себе сразу и возможности CDN, и защиту от DDoS. Можно использовать Imperva (бывшая Incapsula), предлагающую аналогичные функции, или, например, Qrator, специализирующийся на защите веб‑приложений как Web Application Firewall, но это уже будет стоить денег.

Хотя эти инструменты могут эффективно помочь в обеспечении безопасности, есть некоторые нюансы, которые тоже стоит помнить:

1. Существует риск утечки IP через почтовые заголовки. Если вы используете ваш основной сервер в качестве почтового, реальный IP‑адрес может быть раскрыт в заголовках электронных писем, и все ваши старания полетят коту под хвост.

2. С помощью ресурсов вроде DNS History или Whois Request, можно просмотреть историю IP‑адресов, ассоциированных с доменом. Если реальный IP‑адрес когда‑либо был связан с рабочим доменом, его следует изменить.

3. Будьте особенно осторожны при использовании DDoS‑защиты для доменов, применяемых в качестве API‑эндпоинтов. Системы защиты иногда могут вводить проверку пользователя, подменяя ваш json/xml на HTML код, что может привести к сбоям в работе клиентской части.

4. Не забывайте, что отправляя запросы со своего сервера на API сторонних ресурсов, вы также можете раскрыть его IP. Для того, чтобы избежать этого недоразумения, вы можете использовать proxy‑серверы, ведь их изменить будет гораздо проще, чем разгребать последствия атаки.
👍1
​​Миграция баз данных

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

Существует 2 типа процесса миграции:

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

2. Версионная миграция данных. При данном типе база данных обновляется до новой версии. Помимо апгрейда, может быть откат к более старым версиям. Также данный тип миграции затрагивает схему, о которой более подробно рассказали в разделе «Основные понятия».

Цели миграция баз данных

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

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

Сейчас мы рассмотрим, почему бизнес нуждается в миграции баз данных и какие задачи она решает:

• Чтобы повысить уровень сохранности и надежности данных.

• Улучшить качество командной работы. Если над проектом работает команда разработчиков, миграция помогает синхронизировать код и контролировать версии программного обеспечения.

• Устранить проблемы с масштабированием проектов.

• Обновить функционал и повысить производительность системы хранения информации.

• Чтобы воспользоваться возможностями современных технологий, например, работать с BigData или искусственным интеллектом.

• Сократить расходы на сопровождение и поддержку информационных систем.

Следующим постом рассмотрим пример миграции базы данных PostgreSQL
👍101🔥1👀1
​​Миграция базы данных PostgreSQL

Мы будем использовать две логические процедуры, а именно: репликацию и дампу.

Для начала необходимо подготовить исходный кластер, выполнив команды в данной последовательности:

ALTER ROLE <name> WITH REPLICATION, в скобках вместо name необходимо указать имя пользователя;

• Затем откройте postgresql.conf и укажите следующую информацию: wal_level = logical

• На этом этапе должна настроиться аутентификация в pg_hba.conf. Где <host>, укажите IP или DNS приемника:

host all all <host> md5

host replication all <host> md5


• Перезапустите систему управления базами данных с использованием инструкции: systemctl restart postgresql.

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

Чтобы перенести базу данных, используйте следующие утилиты: pg_dump и pg_restore.

В завершении необходимо создать публикацию в источнике при помощи инструкции CREATE PUBLICATION <name> FOR ALL TABLES, указав название публикации. Для создания публикации нужно обладать правами superuser.

После этого нужно создать подписки в приёмнике, применив инструкцию CREATE SUBSCRIPTION <name> CONNECTION, указав название подписки. Для этого действия нужно иметь доступ администратора dbaas_admin.

В связи с невозможностью репликации последовательностей необходимо произвести восстановление дампа с последовательностями при помощи утилиты psql. Для этого сбросьте подписку в приемнике, выполнив команду:

DROP SUBSCRIPTION.


Создать дамп можно при помощи вышеупомянутых утилит: pg_dump и pg_restore. Дамп базы данных можно создать в кастомном формате (для восстановления отдельных элементов) или в SQL формате.
👍6👀21🤯1
​​Что такое WebSockets

Веб-сокеты это продвинутая технология, позволяющая открыть постоянное двунаправленное сетевое соединение между браузером пользователя и сервером. С помощью его API вы можете отправить сообщение на сервер и получить ответ без выполнения http запроса, причём этот процесс будет событийно-управляемым.

Как это работает?

• Первое что мы делаем — отправляем обычный TCP-запрос на сервер, мы говорим, что хотим подключиться к серверу и ждём от него ответа. Такой процесс называется “рукопожатие” (Handshake), он используется повсеместно, например когда вы подключаетесь к роутеру ваш телефон отправляем запрос роутеру с ключами, роутер отвечает ОК и вы успешно подключаетесь.

• Затем происходит обмен данными: допустим один из множества клиентов отправил HTTP-запрос серверу и нужно отдать ответ не только одному клиенту, а целой сети! Сервер в таком случае отдаст обычный ответ отправителю запроса, а всем другим пришлёт пакеты по WebSocket-соединению с полезными данными.
👍15
​​Самая простая команда в работе с Kubernetes

Для начала, пожалуй, самое простое и полезное действие в работе с Kubernetes. Следующая команда включает автодополнение команд kubectl в оболочке bash:

echo "source <(kubectl completion bash)" >> ~/.bashrc


Автозаполнение kubectl пропишется в файл .bashrc и будет автоматически активироваться каждый раз при запуске оболочки. Это ускоряет набор длинных команд и параметров, таких как all-namespaces. Подробнее в справке Kubernetes по bash.
​​Мост

Приведем аналогию: Допустим, у вас есть сайт с несколькими страницами. Вы хотите позволить пользователям менять темы оформления страниц. Как бы вы поступили? Создали множественные копии каждой страницы для каждой темы или просто сделали отдельные темы и подгружали их в соответствии с настройками пользователей? Шаблон «Мост» позволяет реализовать второй подход.

Шаблон «Мост» — это предпочтение компоновки наследованию. Подробности реализации передаются из одной иерархии другому объекту с отдельной иерархией.

Шаблон «Мост» означает отделение абстракции от реализации, чтобы их обе можно было изменять независимо друг от друга.
👍6
Алгоритмы сортировки

• Быстрая сортировка — это алгоритм «разделяй и властвуй», который выбирает «основной» элемент из массива и разбивает остальные элементы на два подмассива. Затем подмассивы сортируются рекурсивно.

def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)

print(quicksort([3,6,8,10,1,2,1]))


• Сортировка слиянием: Алгоритм сортировки слиянием — это алгоритм «разделяй и властвуй», который делит массив на две части, сортирует две половины, а затем снова объединяет их.

def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)

def merge(left, right):
result = []
i = 0
j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
print(merge_sort([3,6,8,10,1,2,1]))


• Пирамидальная сортировка: Пирамидальная сортировка — это алгоритм сортировки на основе сравнения, который строит пирамиду из входных элементов, а затем многократно извлекает её максимальный элемент и помещает его в конец отсортированного выходного массива.

def heap_sort(arr):
n = len(arr)
for i in range(n, -1, -1):
heapify(arr, n, i)
for i in range(n-1, 0, -1):
arr[i], arr[0] = arr[0], arr[i]
heapify(arr, i, 0)

def heapify(arr, n, i):
largest = i
l = 2 * i + 1
r = 2 * i + 2
if l < n and arr[i] < arr[l]:
largest = l
if r < n and arr[largest] < arr[r]:
largest = r
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
print(heap_sort([3,6,8,10,1,2,1]))
🔥10
​​Не забывайте обновлять зависимости проекта и используемое ПО

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

Автоматизировать стоит и обновление сертификатов безопасности. Возможно, вы использовали или используете сертификаты от Let's Encrypt, а автоматизировать их обновление совсем не сложно с помощью Certbot.

То же касается и остального серверного ПО: если вы работаете с Linux, для многих его дистрибутивов, основанных на Debian/Ubuntu, с задачей автоматизации обновлений легко справится Unattended upgrades. Данная функция позволяет автоматически устанавливать обновления безопасности и не только их - всё зависит от того, какие настройки вы решите использовать. Ну а для совсем серьезных проектов с зоопарком из серверов созданы удобные решения, такие как Ansible, Chef, Puppet или Salt.
👍3
Какой HTTP метод используется для чтения данных?
Anonymous Quiz
93%
GET
5%
POST
2%
PUT
1%
DELETE
​​Что такое API: Ключевые понятия и примеры использования

API (Application Programming Interface) — это набор инструкций и правил, которые определяют, как различные программные компоненты могут взаимодействовать друг с другом. API определяет, какие запросы можно делать к компоненту, какие данные можно получать и отправлять, и какие действия можно выполнять.

Примеры использования API:


1. Web API: Веб-сервисы, такие как Twitter API или Google Maps API, предоставляют программным приложениям доступ к данным и функциям этих сервисов через интернет. Например, Twitter API позволяет приложениям получать ленту твитов, отправлять твиты и выполнять другие действия в Twitter.

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

3. API операционной системы : Операционные системы также предоставляют свои API, которые определяют, как программы могут взаимодействовать с аппаратным и программным обеспечением компьютера. Например, Windows API позволяет программам работать с файлами, сетевыми ресурсами и графическим интерфейсом.

Подведем итог. API обеспечивает стандартизированный способ взаимодействия между программами, что позволяет разработчикам легко создавать интеграции и взаимодействовать с различными компонентами программного обеспечения.
👍111👀1
Компоновщик

Приведем аналогию: Каждая компания состоит из сотрудников. У каждого сотрудника есть одни и те же свойства: зарплата, обязанности, отчётность перед кем-то, субординация...

Компоновщик - это паттерн, который позволяет обрабатывать группу объектов так же, как и отдельный объект. Он используется для построения древовидной структуры объектов, где каждый узел может содержать как отдельные объекты, так и другие поддеревья.


Пример использования "Компоновщика":

Предположим, у нас есть задачи, которые могут быть либо простыми (например, "Написать отчет"), либо составными, состоящими из нескольких подзадач. Мы можем использовать шаблон "Компоновщик", чтобы представить эти задачи в виде древовидной структуры:

class Task:
def init(self, name):
self.name = name

def execute(self):
print(f"Выполнение задачи: {self.name}")


class CompositeTask(Task):
def init(self, name):
super().init(name)
self.subtasks = []

def add_subtask(self, task):
self.subtasks.append(task)

def remove_subtask(self, task):
self.subtasks.remove(task)

def execute(self):
super().execute()
for subtask in self.subtasks:
subtask.execute()


# Создаем задачи
task1 = Task("Написать отчет")
task2 = Task("Проверить отчет")

# Создаем составную задачу
composite_task = CompositeTask("Работа над проектом")
composite_task.add_subtask(task1)
composite_task.add_subtask(task2)

# Выполняем задачи
composite_task.execute()


В этом примере Task представляет базовый класс для всех задач, CompositeTask - это составная задача, которая может содержать другие задачи (как простые, так и составные). Мы можем добавлять и удалять подзадачи из составной задачи и выполнять все задачи, включая все подзадачи, с помощью одного вызова метода execute().
👍6🤔1