Что такое Маршалинг и чем он отличается от Сериализации максимально содержательно и с примерами
Маршалинг (Marshalling) и сериализация (Serialization) - это процессы преобразования данных из структурированного формата (например, объекты в памяти) в формат, который может быть передан или сохранен (например, в виде байтового потока), и наоборот. Оба термина часто используются в контексте передачи данных между различными приложениями или процессами.
Маршалинг представляет собой процесс преобразования данных из формата, применяемого в одном контексте, в формат, применимый в другом контексте, например, для передачи данных через сеть или сохранения в файл. Обычно маршалинг приводит к преобразованию данных в структурированный текстовый или бинарный формат, который может быть передан или сохранен.
import pickle
Здесь объект
Сериализация подразумевает преобразование данных в формат, который может быть сохранен в файле или передан через сеть, чтобы потом быть восстановленным в исходное состояние. Сериализация часто используется для сохранения состояния объектов или передачи структурированных данных между различными приложениями или устройствами.
Здесь объект
• Формат вывода: Маршалинг чаще всего приводит к преобразованию данных в текстовый формат (например, JSON), который читаем человеком. Сериализация может быть бинарной или текстовой и предназначена для сохранения данных или передачи между системами.
• Цель использования: Маршалинг чаще всего используется для передачи данных через сеть или взаимодействия между различными приложениями. Сериализация чаще всего используется для сохранения состояния объектов или данных в файлы.
• Используемые форматы: Маршалинг часто осуществляется в формате, понятном различным системам (например, JSON для веб-сервисов). Сериализация может быть более специфичной и привязанной к определенному формату (например, использование pickle для сериализации объектов Python).
Маршалинг (Marshalling) и сериализация (Serialization) - это процессы преобразования данных из структурированного формата (например, объекты в памяти) в формат, который может быть передан или сохранен (например, в виде байтового потока), и наоборот. Оба термина часто используются в контексте передачи данных между различными приложениями или процессами.
Маршалинг (Marshalling):
Маршалинг представляет собой процесс преобразования данных из формата, применяемого в одном контексте, в формат, применимый в другом контексте, например, для передачи данных через сеть или сохранения в файл. Обычно маршалинг приводит к преобразованию данных в структурированный текстовый или бинарный формат, который может быть передан или сохранен.
import pickle
import json
# Преобразование объекта Python в JSON-строку (маршалинг)
data = {'name': 'John', 'age': 30, 'city': 'New York'}
json_string = json.dumps(data)
print(json_string)
Здесь объект
data (словарь Python) маршализуется в JSON-строку с помощью функции json.dumps(). Результатом будет строка {"name": "John", "age": 30, "city": "New York"}.Сериализация (Serialization):
Сериализация подразумевает преобразование данных в формат, который может быть сохранен в файле или передан через сеть, чтобы потом быть восстановленным в исходное состояние. Сериализация часто используется для сохранения состояния объектов или передачи структурированных данных между различными приложениями или устройствами.
import pickle
# Сериализация объекта Python в бинарный формат (pickle)
data = {'name': 'Alice', 'age': 25, 'city': 'Los Angeles'}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)
Здесь объект
data (словарь Python) сериализуется в бинарный формат с помощью модуля pickle и сохраняется в файл data.pkl.Отличия между Маршалингом и Сериализацией:
• Формат вывода: Маршалинг чаще всего приводит к преобразованию данных в текстовый формат (например, JSON), который читаем человеком. Сериализация может быть бинарной или текстовой и предназначена для сохранения данных или передачи между системами.
• Цель использования: Маршалинг чаще всего используется для передачи данных через сеть или взаимодействия между различными приложениями. Сериализация чаще всего используется для сохранения состояния объектов или данных в файлы.
• Используемые форматы: Маршалинг часто осуществляется в формате, понятном различным системам (например, JSON для веб-сервисов). Сериализация может быть более специфичной и привязанной к определенному формату (например, использование pickle для сериализации объектов Python).
В целом, маршалинг и сериализация представляют собой важные процессы для обмена и сохранения данных в программировании, и различаются преимущественно по форматам вывода и целям использования.
❤5👍4🤯1
Задача: Сделать конвейер чисел
Даны два канала. В первый пишутся числа. Нужно, чтобы числа читались из первого по мере поступления, что-то с ними происходило (допустим, возводились в квадрат) и результат записывался во второй канал.
Решается довольно прямолинейно — запускаем две горутины. В одной пишем в первый канал. Во второй читаем из первого канала и пишем во второй. Главное — не забыть закрыть каналы, чтобы ничего нигде не заблокировалось.
Как всегда, решение закину следующим постом👇
Даны два канала. В первый пишутся числа. Нужно, чтобы числа читались из первого по мере поступления, что-то с ними происходило (допустим, возводились в квадрат) и результат записывался во второй канал.
Довольно частая задача, более подробно можно почитать тут: https://blog.golang.org/pipelines
Решается довольно прямолинейно — запускаем две горутины. В одной пишем в первый канал. Во второй читаем из первого канала и пишем во второй. Главное — не забыть закрыть каналы, чтобы ничего нигде не заблокировалось.
Как всегда, решение закину следующим постом👇
Решение задачи «Сделать конвейер чисел»
package main
import (
"fmt"
)
func main() {
naturals := make(chan int)
squares := make(chan int)
go func() {
for x := 0; x <= 10; x++ {
naturals <- x
}
close(naturals)
}()
go func() {
for x := range naturals {
squares <- x * x
}
close(squares)
}()
for x := range squares {
fmt.Println(x)
}
}
Вышла Node.js 22
По данным OpenNET, основные изменения и дополнения в Node.js 22:
• движок V8 обновлён до версии 12.4, применяемой в Chromium 124;
• включён по умолчанию оптимизирующий JIT-компилятор Maglev, нацеленный на быструю генерацию высокопроизводительного машинного кода для активно используемого кода на JavaScript. Включение Maglev позволяет заметно ускорить работу короткоживущих CLI-приложений, не выполняющих длительных операций, например, время прохождения теста Jetstrea сокращается на 7.5%, а теста Speedometer на 5%;
• ускорена работа с потоками за счёт увеличения значения опции highWaterMark с 16 KB до 65 KB (определяет лимит, до которого выполняется буферизация записи). Изменение приводит к увеличению потребления памяти, поэтому приложениям, рассчитанным на работу с ограниченным объёмом ОЗУ, возможно, потребуется вернуть старое значение через вызов setDefaultHighWaterMark();
• повышена производительность API fetch() и test runner за счёт повышения эффективности создания экземпляров AbortSignal. Повышена производительность API, связанных с синхронной работой с файловыми системами;
• предоставлена экспериментальная возможность использования вызова "require()" для загрузки JavaScript-модулей ESM (ECMAScript Modules) в синхронном режиме. ESM-модули применяются в браузерах и идут на смену модулям CommonJS, специфичным для Node.js. Для загрузки через "require()" ESM-модуль должен выполняться в синхронном режиме (без await на верхнем уровне). Поддержка включается через флаг "--experimental-require-module";
• добавлена экспериментальная возможность запуска скриптов, определённых в файле package.json, используя команду "--run ";
• в категорию стабильных переведена команда "node --watch" с реализацией режима наблюдения, обеспечивающего перезапуск процесса при изменении импортированного файла (например, в случае выполнения "node --watch index.js" процесс будет автоматически перезапущен при изменении index.js);
• стабилизирована встроенная реализация API WebSocket, позволяющего использовать WebSocket в режиме клиента без установки дополнительных зависимостей;
• добавлена частичная поддержка API Navigator;
• в API Webstreams добавлена поддержка формата сжатия deflate-raw;
• в модуль node:fsmodule добавлены функции glob и globSync для сопоставления файловых путей по образцу;
• улучшена обработка некорректно настроенных стеков IPv6. Реализован алгоритм Happy Eyeballs для быстрого отката в случае проблем с работой IPv6;
• объявлен устаревшим API util;
• обновлены версии зависимостей: npm 10.5.1, libuv 1.48.0, simdutf 5.2.3, c-ares 1.28.1, zlib 1.3.0.1-motley-24c07df, simdjson to 3.8.0, ada 2.7.7 и undici 6.6.0.
Ставь 🔥 если хочешь больше новостей!
По данным OpenNET, основные изменения и дополнения в Node.js 22:
• движок V8 обновлён до версии 12.4, применяемой в Chromium 124;
• включён по умолчанию оптимизирующий JIT-компилятор Maglev, нацеленный на быструю генерацию высокопроизводительного машинного кода для активно используемого кода на JavaScript. Включение Maglev позволяет заметно ускорить работу короткоживущих CLI-приложений, не выполняющих длительных операций, например, время прохождения теста Jetstrea сокращается на 7.5%, а теста Speedometer на 5%;
• ускорена работа с потоками за счёт увеличения значения опции highWaterMark с 16 KB до 65 KB (определяет лимит, до которого выполняется буферизация записи). Изменение приводит к увеличению потребления памяти, поэтому приложениям, рассчитанным на работу с ограниченным объёмом ОЗУ, возможно, потребуется вернуть старое значение через вызов setDefaultHighWaterMark();
• повышена производительность API fetch() и test runner за счёт повышения эффективности создания экземпляров AbortSignal. Повышена производительность API, связанных с синхронной работой с файловыми системами;
• предоставлена экспериментальная возможность использования вызова "require()" для загрузки JavaScript-модулей ESM (ECMAScript Modules) в синхронном режиме. ESM-модули применяются в браузерах и идут на смену модулям CommonJS, специфичным для Node.js. Для загрузки через "require()" ESM-модуль должен выполняться в синхронном режиме (без await на верхнем уровне). Поддержка включается через флаг "--experimental-require-module";
• добавлена экспериментальная возможность запуска скриптов, определённых в файле package.json, используя команду "--run ";
• в категорию стабильных переведена команда "node --watch" с реализацией режима наблюдения, обеспечивающего перезапуск процесса при изменении импортированного файла (например, в случае выполнения "node --watch index.js" процесс будет автоматически перезапущен при изменении index.js);
• стабилизирована встроенная реализация API WebSocket, позволяющего использовать WebSocket в режиме клиента без установки дополнительных зависимостей;
• добавлена частичная поддержка API Navigator;
• в API Webstreams добавлена поддержка формата сжатия deflate-raw;
• в модуль node:fsmodule добавлены функции glob и globSync для сопоставления файловых путей по образцу;
• улучшена обработка некорректно настроенных стеков IPv6. Реализован алгоритм Happy Eyeballs для быстрого отката в случае проблем с работой IPv6;
• объявлен устаревшим API util;
• обновлены версии зависимостей: npm 10.5.1, libuv 1.48.0, simdutf 5.2.3, c-ares 1.28.1, zlib 1.3.0.1-motley-24c07df, simdjson to 3.8.0, ada 2.7.7 и undici 6.6.0.
Поддержка Node.js 22.x будет осуществляться до 30 апреля 2027 года. Сопровождение прошлой LTS-ветки Node.js 20.x продлится до апреля 2026 года, а позапрошлой LTS-ветки 18.x — до апреля 2025 года. Сопровождение промежуточной ветки Node.js 21.x будет прекращено 1 июня 2024 года.
Ставь 🔥 если хочешь больше новостей!
👍3❤1🔥1
Сравнение различных баз данных: Когда выбирать SQL, а когда NoSQL?
Сравнение различных типов баз данных - SQL и NoSQL - зависит от конкретных потребностей проекта, его структуры данных и требований к масштабируемости, производительности и консистентности данных. Давайте рассмотрим основные аспекты выбора между SQL и NoSQL с примерами.
Структурированные данные: Если ваши данные имеют жесткую структуру и связи между ними легко описать в виде таблиц, то SQL базы данных, такие как MySQL, PostgreSQL или SQLite, будут лучшим выбором. SQL базы данных отлично подходят для приложений, где необходимо соблюдать строгие правила целостности данных.
Транзакционность: Если ваше приложение требует поддержки транзакций с ACID (Atomicity, Consistency, Isolation, Durability) свойствами, то SQL базы данных и их транзакционные возможности подходят лучше. Это важно для финансовых приложений, систем управления инвентаризацией и других приложений, где целостность данных является критически важной.
Гибкие и неструктурированные данные: Если ваше приложение работает с гибкими или неструктурированными данными, такими как JSON, XML или документы, то NoSQL базы данных, такие как MongoDB, Couchbase или Cassandra, могут быть более подходящим выбором. Они позволяют хранить и обрабатывать данные без явного определения схемы.
Масштабируемость: NoSQL базы данных часто предоставляют горизонтальное масштабирование (scaling out), что позволяет эффективно масштабировать приложение с ростом количества данных или нагрузки. Это особенно полезно для приложений с высокой нагрузкой и большими объемами данных, таких как социальные сети или аналитические приложения.
В этом примере каждый документ представляет собой отдельную запись о пользователе с полями
Сравнение различных типов баз данных - SQL и NoSQL - зависит от конкретных потребностей проекта, его структуры данных и требований к масштабируемости, производительности и консистентности данных. Давайте рассмотрим основные аспекты выбора между SQL и NoSQL с примерами.
Когда выбирать SQL:
Структурированные данные: Если ваши данные имеют жесткую структуру и связи между ними легко описать в виде таблиц, то SQL базы данных, такие как MySQL, PostgreSQL или SQLite, будут лучшим выбором. SQL базы данных отлично подходят для приложений, где необходимо соблюдать строгие правила целостности данных.
Транзакционность: Если ваше приложение требует поддержки транзакций с ACID (Atomicity, Consistency, Isolation, Durability) свойствами, то SQL базы данных и их транзакционные возможности подходят лучше. Это важно для финансовых приложений, систем управления инвентаризацией и других приложений, где целостность данных является критически важной.
CREATE TABLE Users (
UserID INT PRIMARY KEY,
Username VARCHAR(50),
Email VARCHAR(100)
);
Когда выбирать NoSQL:
Гибкие и неструктурированные данные: Если ваше приложение работает с гибкими или неструктурированными данными, такими как JSON, XML или документы, то NoSQL базы данных, такие как MongoDB, Couchbase или Cassandra, могут быть более подходящим выбором. Они позволяют хранить и обрабатывать данные без явного определения схемы.
Масштабируемость: NoSQL базы данных часто предоставляют горизонтальное масштабирование (scaling out), что позволяет эффективно масштабировать приложение с ростом количества данных или нагрузки. Это особенно полезно для приложений с высокой нагрузкой и большими объемами данных, таких как социальные сети или аналитические приложения.
{
"userID": 123,
"username": "john_doe",
"email": "[email protected]",
"posts": [
{"title": "Post 1", "content": "Content 1"},
{"title": "Post 2", "content": "Content 2"}
]
}В этом примере каждый документ представляет собой отдельную запись о пользователе с полями
userID, username, email и массивом posts, содержащим посты пользователя.В итоге, выбор между SQL и NoSQL базами данных зависит от конкретных требований вашего приложения по структуре данных, требованиям к масштабируемости и производительности, а также предпочтений команды разработчиков. Обе модели имеют свои преимущества и ограничения, и выбор должен быть сделан на основе тщательного анализа и оценки потребностей проекта.
👍7
Что такое RabbitMQ
RabbitMQ - это мощная и гибкая система сообщений (Message Queue), которая обеспечивает асинхронную связь между различными компонентами системы.
1. Producer (Производитель): Программа или сервис, который отправляет сообщения в RabbitMQ.
2. Queue (Очередь): Хранилище сообщений в RabbitMQ. Сообщения остаются в очереди до тех пор, пока они не будут обработаны и прочитаны Consumer'ом.
3. Consumer (Потребитель): Программа или сервис, который получает сообщения из RabbitMQ и обрабатывает их.
4. Exchange (Обменник): Компонент, который получает сообщения от Producer'а и направляет их в одну или несколько очередей. Exchange определяет, как сообщения будут маршрутизироваться.
Предположим, у вас есть приложение для обработки заказов в интернет-магазине. Когда пользователь размещает заказ, ваш веб-сервер отправляет сообщение в RabbitMQ, содержащее детали заказа. Затем приложение для обработки заказов, подписанное на соответствующую очередь в RabbitMQ, получает сообщение, обрабатывает заказ и отправляет его на доставку.
В этом примере Python-программа отправляет сообщение "New order: #123" в очередь "orders" RabbitMQ. Другое приложение, подписанное на эту очередь, будет получать и обрабатывать это сообщение.
RabbitMQ обладает широким спектром возможностей, таких как управление ошибками, маршрутизация сообщений, подтверждения доставки и многое другое, что делает его очень гибким и мощным инструментом для построения асинхронной архитектуры приложений.
RabbitMQ - это мощная и гибкая система сообщений (Message Queue), которая обеспечивает асинхронную связь между различными компонентами системы.
Основные компоненты RabbitMQ:
1. Producer (Производитель): Программа или сервис, который отправляет сообщения в RabbitMQ.
2. Queue (Очередь): Хранилище сообщений в RabbitMQ. Сообщения остаются в очереди до тех пор, пока они не будут обработаны и прочитаны Consumer'ом.
3. Consumer (Потребитель): Программа или сервис, который получает сообщения из RabbitMQ и обрабатывает их.
4. Exchange (Обменник): Компонент, который получает сообщения от Producer'а и направляет их в одну или несколько очередей. Exchange определяет, как сообщения будут маршрутизироваться.
Пример использования RabbitMQ:
Предположим, у вас есть приложение для обработки заказов в интернет-магазине. Когда пользователь размещает заказ, ваш веб-сервер отправляет сообщение в RabbitMQ, содержащее детали заказа. Затем приложение для обработки заказов, подписанное на соответствующую очередь в RabbitMQ, получает сообщение, обрабатывает заказ и отправляет его на доставку.
import pika
# Подключение к RabbitMQ серверу
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# Создание очереди
channel.queue_declare(queue='orders')
# Отправка сообщения в очередь
channel.basic_publish(exchange='', routing_key='orders', body='New order: #123')
print(" [x] Sent 'New order: #123'")
# Закрытие соединения
connection.close()
В этом примере Python-программа отправляет сообщение "New order: #123" в очередь "orders" RabbitMQ. Другое приложение, подписанное на эту очередь, будет получать и обрабатывать это сообщение.
RabbitMQ обладает широким спектром возможностей, таких как управление ошибками, маршрутизация сообщений, подтверждения доставки и многое другое, что делает его очень гибким и мощным инструментом для построения асинхронной архитектуры приложений.
👍14
Задача: Написать WorkerPool с заданной функцией
Нам нужно разбить процессы на несколько горутин — при этом не создавать новую горутину каждый раз, а просто переиспользовать уже имеющиеся. Для этого создадим канал с джобами и результирующий канал. Для каждого воркера создадим горутину, который будет ждать новую джобу, применять к ней заданную функцию и пулять ответ в результирующий канал.
Решение будет следующим постом ⬇️
Довольно распространенная задача, плюс подобные задачи встречаются на практике.
Нам нужно разбить процессы на несколько горутин — при этом не создавать новую горутину каждый раз, а просто переиспользовать уже имеющиеся. Для этого создадим канал с джобами и результирующий канал. Для каждого воркера создадим горутину, который будет ждать новую джобу, применять к ней заданную функцию и пулять ответ в результирующий канал.
Решение будет следующим постом ⬇️
👍1🔥1
Решение:
package main
import (
"fmt"
)
func worker(id int, f func(int) int, jobs <-chan int, results chan<- int) {
for j := range jobs {
results <- f(j)
}
}
func main() {
const numJobs = 5
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
multiplier := func(x int) int {
return x * 10
}
for w := 1; w <= 3; w++ {
go worker(w, multiplier, jobs, results)
}
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)
for i := 1; i <= numJobs; i++ {
fmt.Println(<-results)
}
}
🔥6
Что такое gRPC максимально содержательно и с примерами
gRPC (gRPC Remote Procedure Call) - это высокопроизводительный фреймворк для удаленного вызова процедур (RPC), разработанный компанией Google. Он использует простой и эффективный механизм взаимодействия между клиентом и сервером, основанный на протоколе HTTP/2 для передачи данных и Protocol Buffers (protobuf) для сериализации структурированных данных.
1. Простота использования: gRPC позволяет определять удаленные сервисы с использованием простого и понятного синтаксиса Protocol Buffers. Он обеспечивает прозрачное взаимодействие между клиентом и сервером, скрывая сложности низкоуровневых деталей сетевого взаимодействия.
2. Высокая производительность: Фреймворк использует протокол HTTP/2 для эффективной передачи данных между клиентом и сервером. Это позволяет уменьшить задержки и улучшить производительность сетевых запросов.
3. Поддержка множества языков программирования: gRPC поддерживает множество языков программирования, включая C++, Java, Python, Go, Ruby и многие другие. Это позволяет создавать многоязыковые приложения с использованием единого RPC-интерфейса.
4. Сильная типизация данных: Благодаря использованию Protocol Buffers, gRPC обеспечивает сильную типизацию данных, что делает взаимодействие между клиентом и сервером более надежным и безопасным.
5. Поддержка различных типов RPC: gRPC поддерживает различные типы RPC, включая унарный (Unary), сервер-стриминг (Server-streaming), клиент-стриминг (Client-streaming) и двусторонний поток (Bidirectional-streaming) RPC. Это позволяет выбирать наиболее подходящий тип взаимодействия в зависимости от требований приложения.
Следующим постом разберем примеры использования gRPC 👇
gRPC (gRPC Remote Procedure Call) - это высокопроизводительный фреймворк для удаленного вызова процедур (RPC), разработанный компанией Google. Он использует простой и эффективный механизм взаимодействия между клиентом и сервером, основанный на протоколе HTTP/2 для передачи данных и Protocol Buffers (protobuf) для сериализации структурированных данных.
Основные характеристики gRPC:
1. Простота использования: gRPC позволяет определять удаленные сервисы с использованием простого и понятного синтаксиса Protocol Buffers. Он обеспечивает прозрачное взаимодействие между клиентом и сервером, скрывая сложности низкоуровневых деталей сетевого взаимодействия.
2. Высокая производительность: Фреймворк использует протокол HTTP/2 для эффективной передачи данных между клиентом и сервером. Это позволяет уменьшить задержки и улучшить производительность сетевых запросов.
3. Поддержка множества языков программирования: gRPC поддерживает множество языков программирования, включая C++, Java, Python, Go, Ruby и многие другие. Это позволяет создавать многоязыковые приложения с использованием единого RPC-интерфейса.
4. Сильная типизация данных: Благодаря использованию Protocol Buffers, gRPC обеспечивает сильную типизацию данных, что делает взаимодействие между клиентом и сервером более надежным и безопасным.
5. Поддержка различных типов RPC: gRPC поддерживает различные типы RPC, включая унарный (Unary), сервер-стриминг (Server-streaming), клиент-стриминг (Client-streaming) и двусторонний поток (Bidirectional-streaming) RPC. Это позволяет выбирать наиболее подходящий тип взаимодействия в зависимости от требований приложения.
Следующим постом разберем примеры использования gRPC 👇
👍11
Пример использования gRPC:
Рассмотрим простой пример использования gRPC для создания клиент-серверного приложения на Python.
1. Определение сервиса и сообщений в файле example.proto с использованием синтаксиса Protocol Buffers:
2. Генерация кода на основе файла example.proto с помощью компилятора Protocol Buffers:
3. Создание сервера на Python с использованием gRPC:
4. Создание клиента на Python с использованием gRPC:
Рассмотрим простой пример использования gRPC для создания клиент-серверного приложения на Python.
1. Определение сервиса и сообщений в файле example.proto с использованием синтаксиса Protocol Buffers:
syntax = "proto3";
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
2. Генерация кода на основе файла example.proto с помощью компилятора Protocol Buffers:
protoc -I=. --python_out=. --grpc_python_out=. example.proto
3. Создание сервера на Python с использованием gRPC:
import grpc
import example_pb2
import example_pb2_grpc
class GreeterServicer(example_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return example_pb2.HelloResponse(message=f"Hello, {request.name}!")
def serve():
server = grpc.server(grpc.insecure_server())
example_pb2_grpc.add_GreeterServicer_to_server(GreeterServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if name == 'main':
serve()
4. Создание клиента на Python с использованием gRPC:
import grpc
import example_pb2
import example_pb2_grpc
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = example_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(example_pb2.HelloRequest(name='world'))
Использование JWT и OAuth для аутентификации и авторизации в веб-приложениях
JWT - это компактный и самодостаточный способ представления информации об аутентификации в форме JSON, которая может быть передана между двумя сторонами как часть HTTP запроса или в теле. Он состоит из трех частей: заголовка (header), полезной нагрузки (payload) и подписи (signature). Заголовок содержит информацию о типе токена и используемом алгоритме шифрования. Полезная нагрузка содержит информацию об аутентифицированном пользователе или другие данные. Подпись обеспечивает проверку целостности данных.
OAuth - это протокол авторизации, который позволяет приложениям делегировать доступ к ресурсам пользователям без передачи им своих учетных данных. OAuth включает в себя несколько этапов, включая запрос разрешения у пользователя, получение временного токена доступа, обмен временного токена на токен доступа и использование токена доступа для доступа к защищенным ресурсам.
Следующим постом рассмотрим пример кода на Python с использованием библиотеки Flask для реализации аутентификации с помощью JWT ⬇️
JWT (JSON Web Token) и OAuth - это два распространенных стандарта для реализации аутентификации и авторизации в веб-приложениях.
JWT - это компактный и самодостаточный способ представления информации об аутентификации в форме JSON, которая может быть передана между двумя сторонами как часть HTTP запроса или в теле. Он состоит из трех частей: заголовка (header), полезной нагрузки (payload) и подписи (signature). Заголовок содержит информацию о типе токена и используемом алгоритме шифрования. Полезная нагрузка содержит информацию об аутентифицированном пользователе или другие данные. Подпись обеспечивает проверку целостности данных.
OAuth - это протокол авторизации, который позволяет приложениям делегировать доступ к ресурсам пользователям без передачи им своих учетных данных. OAuth включает в себя несколько этапов, включая запрос разрешения у пользователя, получение временного токена доступа, обмен временного токена на токен доступа и использование токена доступа для доступа к защищенным ресурсам.
Пример использования JWT и OAuth в веб-приложении:
• Пользователь входит в систему, предоставляя учетные данные (например, имя пользователя и пароль).
• Сервер аутентификации проверяет учетные данные пользователя и создает JWT токен с информацией об аутентифицированном пользователе (например, идентификатор пользователя, роль и срок действия токена).
• Сервер возвращает JWT токен клиентскому приложению.
• При последующих запросах клиентское приложение включает JWT токен в заголовок Authorization.
• Сервер проверяет подлинность токена и авторизует запрос на основе информации в токене.Следующим постом рассмотрим пример кода на Python с использованием библиотеки Flask для реализации аутентификации с помощью JWT ⬇️
👍5
Пример кода на Python с использованием библиотеки Flask для реализации аутентификации с помощью JWT:
В этом примере, при запросе на
from flask import Flask, jsonify, request
import jwt
from functools import wraps
app = Flask(name)
app.config['SECRET_KEY'] = 'secret'
def token_required(f):
@wraps(f)
def decorated(*args, **kwargs):
token = request.headers.get('Authorization')
if not token:
return jsonify({'message': 'Token is missing!'}), 401
try:
data = jwt.decode(token, app.config['SECRET_KEY'])
except:
return jsonify({'message': 'Token is invalid!'}), 401
return f(*args, **kwargs)
return decorated
@app.route('/login', methods=['POST'])
def login():
auth = request.authorization
if auth and auth.password == 'password':
token = jwt.encode({'username': auth.username}, app.config['SECRET_KEY'])
return jsonify({'token': token.decode('UTF-8')})
return jsonify({'message': 'Could not verify!'}), 401
@app.route('/protected', methods=['GET'])
@token_required
def protected():
return jsonify({'message': 'This is protected route!'})
if name == 'main':
app.run(debug=True)
В этом примере, при запросе на
/login пользователь предоставляет учетные данные и, если они верны, сервер создает JWT токен, который включает в себя имя пользователя. После этого, для доступа к защищенному маршруту /protected, клиент должен предоставить этот токен в заголовке Authorization. Функция token_required обеспечивает аутентификацию пользователя на основе JWT токена.👍8
⚙️ Обработка NULL с DISTINCT
Результатом запроса будет значение 4531 для столбца
with new_table as (
select patient_id from patients
UNION
select null
)
select
count()
, count(distinct patient_id)
, count(patient_id)
from new_table
Результатом запроса будет значение 4531 для столбца
COUNT() и 4530 для двух оставшихся столбцов. Когда вы указываете столбец, ключевое слово COUNT исключает нулевые значения.Однако, при использовании звездочки в подсчет включаются значения NULL.Это может сбивать с толку при проверке, является ли столбец первичным ключом, поэтому я посчитал нужным упомянуть об этом.
❤1
Что такое ACID максимально содержательно и с примерами
ACID (Atomicity, Consistency, Isolation, Durability) - это набор основных принципов транзакционной обработки в базах данных, обеспечивающих надежность и целостность данных.
Вот более подробное объяснение каждого из принципов:
Этот принцип гарантирует, что транзакция будет выполнена либо полностью, либо не выполнится вообще. Если одна часть транзакции не может быть завершена успешно, то все изменения, внесенные другими частями транзакции, отменяются, и база данных остается в неизменном состоянии.
Пример: Представьте, что пользователь хочет выполнить банковский перевод со счета A на счет B. Если перевод прошел успешно, то деньги будут вычтены со счета A и добавлены на счет B. Если произошла ошибка в середине процесса (например, проблемы с сетью), ни один из счетов не будет изменен.
Этот принцип гарантирует, что база данных остается в согласованном состоянии после выполнения транзакции. Это означает, что транзакция должна переводить базу данных из одного согласованного состояния в другое.
Пример: Представьте, что у нас есть база данных счетов клиентов в банке, и транзакция перевода средств должна гарантировать, что сумма денег на всех счетах остается неизменной после выполнения транзакции.
Этот принцип гарантирует, что выполнение одной транзакции не зависит от выполнения других транзакций, которые происходят параллельно. Изоляция предотвращает влияние одной транзакции на другие транзакции.
Пример: Если две транзакции пытаются изменить одни и те же данные одновременно, изоляция гарантирует, что результат выполнения одной транзакции не повлияет на результат выполнения другой транзакции.
Этот принцип гарантирует, что результаты успешно завершенных транзакций остаются постоянными и сохраняются даже в случае сбоя системы. Долговечность гарантирует, что данные, измененные в рамках транзакции, останутся сохраненными и доступными после перезапуска системы.
Пример: После того, как транзакция перевода средств выполнена успешно и пользователь получил подтверждение, долговечность гарантирует, что эти изменения останутся в базе данных и не будут потеряны даже в случае сбоя системы.
ACID (Atomicity, Consistency, Isolation, Durability) - это набор основных принципов транзакционной обработки в базах данных, обеспечивающих надежность и целостность данных.
Вот более подробное объяснение каждого из принципов:
Atomicity (Атомарность):
Этот принцип гарантирует, что транзакция будет выполнена либо полностью, либо не выполнится вообще. Если одна часть транзакции не может быть завершена успешно, то все изменения, внесенные другими частями транзакции, отменяются, и база данных остается в неизменном состоянии.
Пример: Представьте, что пользователь хочет выполнить банковский перевод со счета A на счет B. Если перевод прошел успешно, то деньги будут вычтены со счета A и добавлены на счет B. Если произошла ошибка в середине процесса (например, проблемы с сетью), ни один из счетов не будет изменен.
Consistency (Согласованность):
Этот принцип гарантирует, что база данных остается в согласованном состоянии после выполнения транзакции. Это означает, что транзакция должна переводить базу данных из одного согласованного состояния в другое.
Пример: Представьте, что у нас есть база данных счетов клиентов в банке, и транзакция перевода средств должна гарантировать, что сумма денег на всех счетах остается неизменной после выполнения транзакции.
Isolation (Изоляция):
Этот принцип гарантирует, что выполнение одной транзакции не зависит от выполнения других транзакций, которые происходят параллельно. Изоляция предотвращает влияние одной транзакции на другие транзакции.
Пример: Если две транзакции пытаются изменить одни и те же данные одновременно, изоляция гарантирует, что результат выполнения одной транзакции не повлияет на результат выполнения другой транзакции.
Durability (Долговечность):
Этот принцип гарантирует, что результаты успешно завершенных транзакций остаются постоянными и сохраняются даже в случае сбоя системы. Долговечность гарантирует, что данные, измененные в рамках транзакции, останутся сохраненными и доступными после перезапуска системы.
Пример: После того, как транзакция перевода средств выполнена успешно и пользователь получил подтверждение, долговечность гарантирует, что эти изменения останутся в базе данных и не будут потеряны даже в случае сбоя системы.
👍12
Clean Architecture
Clean Architecture - это методология проектирования программного обеспечения, предложенная Робертом Мартином (также известным как Uncle Bob), которая призвана создать гибкую, легко поддерживаемую и расширяемую архитектуру приложения.
Основной принцип Clean Architecture заключается в разделении программы на независимые компоненты, каждый из которых отвечает за конкретный аспект бизнес-логики и имеет четкие границы и интерфейсы с внешним миром.
Entities (Сущности): Это основные объекты, которые представляют бизнес-логику приложения. Сущности содержат логику и данные, специфичные для предметной области.
Use Cases (Случаи использования): Это компоненты, которые описывают то, что система должна делать. Они содержат логику, которая координирует взаимодействие между сущностями и другими компонентами.
Interfaces (Интерфейсы): Это абстракции, которые определяют способ взаимодействия между компонентами системы. Интерфейсы разделяют код на уровни и определяют контракты между компонентами.
Frameworks and Drivers (Фреймворки и драйверы): Это внешние компоненты, такие как фреймворки, библиотеки и инструменты, которые используются для реализации конкретных функций или подключения системы к внешним ресурсам.
Представьте, что у вас есть веб-приложение для управления задачами. Вы можете реализовать Clean Architecture, разделив приложение на следующие компоненты:
Entities: Сущности могут включать в себя объекты, такие как Task (Задача) с полями, такими как название, описание, статус и т. д.
Use Cases: Случаи использования могут включать в себя логику для создания, чтения, обновления и удаления задач, а также выполнение других операций, связанных с управлением задачами.
Interfaces: Интерфейсы могут определять, как компоненты приложения будут взаимодействовать между собой, например, через REST API для взаимодействия с веб-интерфейсом пользователя или через сервисы для доступа к базе данных.
Frameworks and Drivers: Фреймворки и драйверы могут включать в себя фреймворки для разработки веб-приложений, библиотеки для работы с базами данных и инструменты для автоматизации тестирования.
Clean Architecture - это методология проектирования программного обеспечения, предложенная Робертом Мартином (также известным как Uncle Bob), которая призвана создать гибкую, легко поддерживаемую и расширяемую архитектуру приложения.
Основной принцип Clean Architecture заключается в разделении программы на независимые компоненты, каждый из которых отвечает за конкретный аспект бизнес-логики и имеет четкие границы и интерфейсы с внешним миром.
Основные компоненты Clean Architecture включают в себя:
Entities (Сущности): Это основные объекты, которые представляют бизнес-логику приложения. Сущности содержат логику и данные, специфичные для предметной области.
Use Cases (Случаи использования): Это компоненты, которые описывают то, что система должна делать. Они содержат логику, которая координирует взаимодействие между сущностями и другими компонентами.
Interfaces (Интерфейсы): Это абстракции, которые определяют способ взаимодействия между компонентами системы. Интерфейсы разделяют код на уровни и определяют контракты между компонентами.
Frameworks and Drivers (Фреймворки и драйверы): Это внешние компоненты, такие как фреймворки, библиотеки и инструменты, которые используются для реализации конкретных функций или подключения системы к внешним ресурсам.
Пример применения Clean Architecture:
Представьте, что у вас есть веб-приложение для управления задачами. Вы можете реализовать Clean Architecture, разделив приложение на следующие компоненты:
Entities: Сущности могут включать в себя объекты, такие как Task (Задача) с полями, такими как название, описание, статус и т. д.
Use Cases: Случаи использования могут включать в себя логику для создания, чтения, обновления и удаления задач, а также выполнение других операций, связанных с управлением задачами.
Interfaces: Интерфейсы могут определять, как компоненты приложения будут взаимодействовать между собой, например, через REST API для взаимодействия с веб-интерфейсом пользователя или через сервисы для доступа к базе данных.
Frameworks and Drivers: Фреймворки и драйверы могут включать в себя фреймворки для разработки веб-приложений, библиотеки для работы с базами данных и инструменты для автоматизации тестирования.
Clean Architecture способствует созданию гибких, модульных и легко поддерживаемых приложений, которые легко масштабировать и изменять.
👍4🔥2🤔1
Как и просили, делаю пример применения Clean Architecture в коде
Рассмотрим пример применения Clean Architecture на простом веб-приложении для управления задачами. Мы разделим приложение на несколько слоев: представление (View), бизнес-логику (Use Cases) и данные (Repositories). Для простоты мы будем использовать Python и фреймворк Flask для реализации веб-интерфейса.
В этом примере:
• entities.py содержит базовую сущность задачи.
• repositories.py содержит репозиторий для доступа к данным задачи.
• use_cases.py содержит бизнес-логику приложения (создание и получение задачи).
• app.py - это веб-приложение Flask, которое обрабатывает HTTP-запросы и использует компоненты бизнес-логики для создания и получения задач.
Рассмотрим пример применения Clean Architecture на простом веб-приложении для управления задачами. Мы разделим приложение на несколько слоев: представление (View), бизнес-логику (Use Cases) и данные (Repositories). Для простоты мы будем использовать Python и фреймворк Flask для реализации веб-интерфейса.
# entities.py
class Task:
def init(self, title, description, status):
self.title = title
self.description = description
self.status = status
# repositories.py
class TaskRepository:
def get_task_by_id(self, task_id):
# код для получения задачи из базы данных
pass
def save_task(self, task):
# код для сохранения задачи в базу данных
pass
# use_cases.py
class TaskManager:
def init(self, task_repository):
self.task_repository = task_repository
def create_task(self, title, description):
task = Task(title=title, description=description, status='todo')
self.task_repository.save_task(task)
def get_task(self, task_id):
return self.task_repository.get_task_by_id(task_id)
# app.py (Flask приложение)
from flask import Flask, request, jsonify
from entities import Task
from repositories import TaskRepository
from use_cases import TaskManager
app = Flask(name)
task_repository = TaskRepository()
task_manager = TaskManager(task_repository)
@app.route('/tasks', methods=['POST'])
def create_task():
data = request.json
title = data.get('title')
description = data.get('description')
task_manager.create_task(title, description)
return jsonify({'message': 'Task created successfully'})
@app.route('/tasks/<task_id>', methods=['GET'])
def get_task(task_id):
task = task_manager.get_task(task_id)
return jsonify({'title': task.title, 'description': task.description, 'status': task.status})
if name == 'main':
app.run(debug=True)
В этом примере:
• entities.py содержит базовую сущность задачи.
• repositories.py содержит репозиторий для доступа к данным задачи.
• use_cases.py содержит бизнес-логику приложения (создание и получение задачи).
• app.py - это веб-приложение Flask, которое обрабатывает HTTP-запросы и использует компоненты бизнес-логики для создания и получения задач.
Этот пример демонстрирует, как Clean Architecture разделяет приложение на независимые слои, что делает его более гибким, легко поддерживаемым и тестируемым. Каждый компонент отвечает только за свою часть функциональности, что делает его более независимым и переносимым.
❤3👍2🔥2
10 причин, по которым стоит выбрать Django вместо FastAPI
FastAPI предлагает производительное, асинхронное, компактное и современное решение для разработки бэкенда и API на Python по сравнению с более зрелым, но несколько более громоздким Django. И все же многие опытные бэкендеры предпочитают Django.
Стабильность – превыше всего, а Django – образец стабильности, с минимальным количеством серьезных изменений и регрессий на протяжении многих лет. Каждое обновление тщательно тестируется, а сам фреймворк имеет минимум внешних зависимостей, что помогает избежать значительных проблем.
За 18 лет существования Django в интернете накопилось огромное количество ресурсов, многие из которых до сих пор актуальны. Ответы на Stack Overflow остаются действительными годами, а ChatGPT предоставляет корректные ответы, основанные на огромном объеме полезного и релевантного контента.
Django одинаково хорошо подходит и для бэкенда, и для фулстек-разработки.
При работе с FastAPI можно использовать несколько ORM, но выбор менее распространенного инструмента несет свои проблемы, включая меньшее количество документации и поддержки.
Одним из преимуществ FastAPI считается встроенная поддержка ASGI-сервер, но на практике такая функциональность требуется не так уж часто. Для действительно асинхронных задач достаточно инструментов вроде Celery, а для вебсокетов можно использовать решения типа Soketi или Pusher.
Легкость запуска проекта уровня hello world не равнозначна простоте управления и масштабирования со временем.
Конвенции Django могут показаться жесткими, но на самом деле они помогают понять оптимальные архитектурные практики и избежать попадания в типичные ловушки.
Хотя Django – не самый производительный фреймворк, особенно в сравнении с FastAPI, на самом деле навыки разработчика влияют на проблемы с производительностью гораздо больше, чем внутренние возможности используемой технологии. Кроме того, не каждый проект требует экстремальной производительности, а для тех, что требуют, Python – не лучший выбор.
В отличие от FastAPI, разработкой и поддержкой Django занимается большая команда.
Для проектов с относительно простым бэкендом оптимальным выбором может быть не Django и не FastAPI, а фреймворк типа AdonisJS, в сочетании с ORM вроде Prisma: это упрощает управление проектом за счет единого языка для фронтенда и бэкенда.
FastAPI предлагает производительное, асинхронное, компактное и современное решение для разработки бэкенда и API на Python по сравнению с более зрелым, но несколько более громоздким Django. И все же многие опытные бэкендеры предпочитают Django.
Проверенная надежность вместо модных фишек
Стабильность – превыше всего, а Django – образец стабильности, с минимальным количеством серьезных изменений и регрессий на протяжении многих лет. Каждое обновление тщательно тестируется, а сам фреймворк имеет минимум внешних зависимостей, что помогает избежать значительных проблем.
Обилие справочных ресурсов
За 18 лет существования Django в интернете накопилось огромное количество ресурсов, многие из которых до сих пор актуальны. Ответы на Stack Overflow остаются действительными годами, а ChatGPT предоставляет корректные ответы, основанные на огромном объеме полезного и релевантного контента.
Гибкость
Django одинаково хорошо подходит и для бэкенда, и для фулстек-разработки.
Более удобная ORM
При работе с FastAPI можно использовать несколько ORM, но выбор менее распространенного инструмента несет свои проблемы, включая меньшее количество документации и поддержки.
Ограниченная полезность асинхронных возможностей
Одним из преимуществ FastAPI считается встроенная поддержка ASGI-сервер, но на практике такая функциональность требуется не так уж часто. Для действительно асинхронных задач достаточно инструментов вроде Celery, а для вебсокетов можно использовать решения типа Soketi или Pusher.
Вводящие в заблуждение утверждения о «меньшем количестве шаблонного кода»
Легкость запуска проекта уровня hello world не равнозначна простоте управления и масштабирования со временем.
Ценность конвенций
Конвенции Django могут показаться жесткими, но на самом деле они помогают понять оптимальные архитектурные практики и избежать попадания в типичные ловушки.
Производительность – не самое главное
Хотя Django – не самый производительный фреймворк, особенно в сравнении с FastAPI, на самом деле навыки разработчика влияют на проблемы с производительностью гораздо больше, чем внутренние возможности используемой технологии. Кроме того, не каждый проект требует экстремальной производительности, а для тех, что требуют, Python – не лучший выбор.
Потенциальные проблемы с поддержкой проекта
В отличие от FastAPI, разработкой и поддержкой Django занимается большая команда.
Иногда лучше выбрать TypeScript-фреймворк
Для проектов с относительно простым бэкендом оптимальным выбором может быть не Django и не FastAPI, а фреймворк типа AdonisJS, в сочетании с ORM вроде Prisma: это упрощает управление проектом за счет единого языка для фронтенда и бэкенда.
👍3😁3🤔2
Протоколы TLS/SSL максимально содержательно и с примерами
Протоколы TLS (Transport Layer Security) и SSL (Secure Sockets Layer) - это криптографические протоколы, которые обеспечивают защищенную передачу данных в сети Интернет. Они используются для обеспечения конфиденциальности, целостности и подлинности данных, передаваемых между клиентом и сервером.
Протокол SSL был разработан компанией Netscape и стал широко использоваться для защищенной передачи данных в Интернете. Однако из-за уязвимостей и проблем безопасности SSL, протокол был заменен более современным и безопасным протоколом TLS.
SSL/TLS Handshake Protocol: Этот протокол используется для установления защищенного соединения между клиентом и сервером. В процессе рукопожатия происходит обмен криптографическими ключами, установка параметров шифрования и аутентификация сторон.
SSL/TLS Record Protocol: Этот протокол используется для защищенной передачи данных между клиентом и сервером. Он обеспечивает конфиденциальность, целостность и аутентификацию сообщений путем шифрования и аутентификации данных.
Когда вы заходите на защищенный сайт (например, сайт банка или интернет-магазина), ваш браузер и сервер взаимодействуют по следующему сценарию:
1. Браузер отправляет запрос на сервер.
2. Сервер отвечает с помощью сертификата SSL/TLS, который содержит открытый ключ сервера.
3. Браузер проверяет сертификат, чтобы убедиться, что он действителен и принадлежит запрашиваемому серверу.
4. Если сертификат действителен, браузер и сервер выполняют SSL/TLS Handshake Protocol для установления защищенного соединения.
5. После успешного рукопожатия данные между браузером и сервером передаются с использованием SSL/TLS Record Protocol, обеспечивая конфиденциальность и целостность данных.
Протоколы TLS (Transport Layer Security) и SSL (Secure Sockets Layer) - это криптографические протоколы, которые обеспечивают защищенную передачу данных в сети Интернет. Они используются для обеспечения конфиденциальности, целостности и подлинности данных, передаваемых между клиентом и сервером.
Протокол SSL был разработан компанией Netscape и стал широко использоваться для защищенной передачи данных в Интернете. Однако из-за уязвимостей и проблем безопасности SSL, протокол был заменен более современным и безопасным протоколом TLS.
Протоколы TLS и SSL работают на разных уровнях сетевой модели OSI
SSL/TLS Handshake Protocol: Этот протокол используется для установления защищенного соединения между клиентом и сервером. В процессе рукопожатия происходит обмен криптографическими ключами, установка параметров шифрования и аутентификация сторон.
SSL/TLS Record Protocol: Этот протокол используется для защищенной передачи данных между клиентом и сервером. Он обеспечивает конфиденциальность, целостность и аутентификацию сообщений путем шифрования и аутентификации данных.
Когда вы заходите на защищенный сайт (например, сайт банка или интернет-магазина), ваш браузер и сервер взаимодействуют по следующему сценарию:
1. Браузер отправляет запрос на сервер.
2. Сервер отвечает с помощью сертификата SSL/TLS, который содержит открытый ключ сервера.
3. Браузер проверяет сертификат, чтобы убедиться, что он действителен и принадлежит запрашиваемому серверу.
4. Если сертификат действителен, браузер и сервер выполняют SSL/TLS Handshake Protocol для установления защищенного соединения.
5. После успешного рукопожатия данные между браузером и сервером передаются с использованием SSL/TLS Record Protocol, обеспечивая конфиденциальность и целостность данных.
Протоколы TLS и SSL играют ключевую роль в обеспечении безопасности передачи данных в Интернете и используются в различных сферах, включая веб-браузеры, электронную почту, мессенджеры и другие приложения.
👍5
Задача: Сделать кастомную waitGroup на семафоре
В нашем случае мы хотим сделать семафор, который будет ждать выполнения пяти горутин. Для этого просто добавим вместо обычного канала буфферизированный. И внутри каждой горутины положим в него значение. А в конце будем дожидаться, что все ок — мы вычитаем все значения из канала.
Решение ⬇️
Семафор можно легко получить из канала. Чтоб не аллоцировать лишние данные, будем складывать туда пустые структуры.
В нашем случае мы хотим сделать семафор, который будет ждать выполнения пяти горутин. Для этого просто добавим вместо обычного канала буфферизированный. И внутри каждой горутины положим в него значение. А в конце будем дожидаться, что все ок — мы вычитаем все значения из канала.
Решение ⬇️
package main
import (
"fmt"
)
type sema chan struct{}
func New(n int) sema {
return make(sema, n)
}
func (s sema) Inc(k int) {
for i := 0; i < k; i++ {
s <- struct{}{}
}
}
func (s sema) Dec(k int) {
for i := 0; i < k; i++ {
<-s
}
}
func main() {
numbers := []int{1, 2, 3, 4, 5}
n := len(numbers)
sem := New(n)
for _, num := range numbers {
go func(n int) {
fmt.Println(n)
sem.Inc(1)
}(num)
}
sem.Dec(n)
}
Архитектурный паттерн CQRS максимально содержательно и с примерами
CQRS (Command Query Responsibility Segregation) - это архитектурный паттерн, который предлагает разделять операции записи (команды) и операции чтения (запросы) в приложении. Этот подход позволяет разработчикам создавать более гибкие и масштабируемые системы, а также улучшить производительность и обеспечить согласованность данных.
1. Разделение операций записи и операций чтения: Команды (операции записи) и запросы (операции чтения) обрабатываются отдельно. Это позволяет оптимизировать обработку каждого типа операций и использовать различные модели данных для команд и запросов.
2. Моделирование данных: Для команд и запросов могут использоваться различные модели данных, оптимизированные для конкретных потребностей. Например, для операций записи может использоваться нормализованная модель данных, а для операций чтения - денормализованная модель данных или материализованные представления.
3. Асинхронная обработка: Обработка команд может быть асинхронной и происходить в фоновом режиме, что позволяет улучшить производительность и масштабируемость системы.
Следующим постом рассмотрим пример использования CQRS ⬇️
CQRS (Command Query Responsibility Segregation) - это архитектурный паттерн, который предлагает разделять операции записи (команды) и операции чтения (запросы) в приложении. Этот подход позволяет разработчикам создавать более гибкие и масштабируемые системы, а также улучшить производительность и обеспечить согласованность данных.
Основные принципы CQRS:
1. Разделение операций записи и операций чтения: Команды (операции записи) и запросы (операции чтения) обрабатываются отдельно. Это позволяет оптимизировать обработку каждого типа операций и использовать различные модели данных для команд и запросов.
2. Моделирование данных: Для команд и запросов могут использоваться различные модели данных, оптимизированные для конкретных потребностей. Например, для операций записи может использоваться нормализованная модель данных, а для операций чтения - денормализованная модель данных или материализованные представления.
3. Асинхронная обработка: Обработка команд может быть асинхронной и происходить в фоновом режиме, что позволяет улучшить производительность и масштабируемость системы.
Следующим постом рассмотрим пример использования CQRS ⬇️
👍5