День восемьсот семьдесят седьмой. #ЧтоНовенького
Асинхронные Потоки в EF Core и ASP.NET Core 6
Давней проблемой в ASP.NET была невозможность обрабатывать возврат больших файлов JSON без использования большого количества памяти. По умолчанию фреймворк выполняет буферизацию всего вывода сразу, конвертирует его весь в JSON, а затем начинает передавать результаты клиенту. Это может привести к нехватке памяти, если объём данных достаточно велик.
Однако потоковая передача результатов не была проблемой для ASP.NET. При работе с более простыми форматами, такими как CSV, разработчик всегда имел возможность писать прямо в поток результатов.
Начиная с ASP.NET Core 5, класс Utf8JsonWriter может использоваться для достижения того же эффекта. Возникнет несколько сложностей, таких как необходимость явного отключения буферизации, но код сможет работать, если вы, например, последуете совету Александра Васильева.
ASP.NET Core 6 упрощает нашу жизнь, напрямую поддерживая
Один из способов получить
В объявлении №463 разработчики были проинформированы о том, что новое поведение
В большинстве случаев приложение не отслеживает отсутствие буферизации. Однако некоторые сценарии могли непреднамеренно полагаться на семантику буферизации для правильной сериализации. Например, возврат
Чтобы вернуться к предыдущему поведению, разработчикам необходимо явно вызвать
Источник: https://www.infoq.com/news/2021/06/ASP-Net-Core-6-IAsyncEnumerable/
Асинхронные Потоки в EF Core и ASP.NET Core 6
Давней проблемой в ASP.NET была невозможность обрабатывать возврат больших файлов JSON без использования большого количества памяти. По умолчанию фреймворк выполняет буферизацию всего вывода сразу, конвертирует его весь в JSON, а затем начинает передавать результаты клиенту. Это может привести к нехватке памяти, если объём данных достаточно велик.
Однако потоковая передача результатов не была проблемой для ASP.NET. При работе с более простыми форматами, такими как CSV, разработчик всегда имел возможность писать прямо в поток результатов.
Начиная с ASP.NET Core 5, класс Utf8JsonWriter может использоваться для достижения того же эффекта. Возникнет несколько сложностей, таких как необходимость явного отключения буферизации, но код сможет работать, если вы, например, последуете совету Александра Васильева.
ASP.NET Core 6 упрощает нашу жизнь, напрямую поддерживая
IAsyncEnumerable
. Если IAsyncEnumerable
возвращается функцией, платформа интерпретирует его как запрос на асинхронную потоковую передачу данных клиенту без буферизации.Один из способов получить
IAsyncEnumerable
- использовать Entity Framework Core. Фактически, эта функция присутствовала, начиная с EF Core 3, но до сих пор её полезность на веб-серверах была ограничена. ASP.NET Core не поддерживал результаты типа IAsyncEnumerable
до версии 5, но даже в этом случае результаты буферизовались.В объявлении №463 разработчики были проинформированы о том, что новое поведение
IAsyncEnumerable
следует рассматривать как критическое изменение.В большинстве случаев приложение не отслеживает отсутствие буферизации. Однако некоторые сценарии могли непреднамеренно полагаться на семантику буферизации для правильной сериализации. Например, возврат
IAsyncEnumerable<>
, который поддерживается запросом EF для типа с отложенной загрузкой свойств, может привести к параллельному выполнению запроса, который может не поддерживаться поставщиком.Чтобы вернуться к предыдущему поведению, разработчикам необходимо явно вызвать
ToListAsync()
:// До ASP.NET Core 6Кроме того, для решения проблемы можно отключить отложенную загрузку.
public IActionResult Get()
{
return Ok(dbContext.Blogs);
}
// Начиная с ASP.NET Core 6
public async Task<IActionResult> Get()
{
return Ok(await dbContext.Blogs.ToListAsync());
}
Источник: https://www.infoq.com/news/2021/06/ASP-Net-Core-6-IAsyncEnumerable/
День восемьсот семьдесят восьмой. #Оффтоп #Здоровье
Сегодня не про программирование, но тема не менее важная – здоровье. Как всегда случайно наткнулся в ютубе на занятное видео про поддержание здоровья и продуктивности при нашем сидячем образе жизни. Там даётся 10 советов. Не могу сказать, что со всеми согласен, на некоторые, вроде регулируемого по высоте стола, придётся заметно потратиться. Но некоторые вещи, например, сидение на фитболе и режим работы 25-5 пробовал.
Давайте обсудим. Что из этого использовали вы? Что понравилось, что нет? Используете ли вы какие-нибудь другие приёмы?
Сегодня не про программирование, но тема не менее важная – здоровье. Как всегда случайно наткнулся в ютубе на занятное видео про поддержание здоровья и продуктивности при нашем сидячем образе жизни. Там даётся 10 советов. Не могу сказать, что со всеми согласен, на некоторые, вроде регулируемого по высоте стола, придётся заметно потратиться. Но некоторые вещи, например, сидение на фитболе и режим работы 25-5 пробовал.
Давайте обсудим. Что из этого использовали вы? Что понравилось, что нет? Используете ли вы какие-нибудь другие приёмы?
YouTube
Рабочее место программиста БЕЗ БОЛЕЙ В СПИНЕ // Девайсы для здоровья и продуктивности работы из дома
Миша делится девайсами, которые помогли ему избавиться от болей в спине и повысить концентрацию внимания во время работы за компьютером.
✈️ 🇺🇸 РЕЛОКЕЙТ в США со мной — https://ocitizens.com/ (uDevs Inc.)
⏱ ТАЙМИНГ:
0:00 - Почему этот выпуск необычный
1:07…
✈️ 🇺🇸 РЕЛОКЕЙТ в США со мной — https://ocitizens.com/ (uDevs Inc.)
⏱ ТАЙМИНГ:
0:00 - Почему этот выпуск необычный
1:07…
День восемьсот семьдесят девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
89. Используйте Правильные Алгоритмы и Структуры Данных
Большой банк с множеством филиалов жаловался, что новые компьютеры, которые он закупил для кассиров, слишком медленные. Это было ещё до того, как все начали использовать онлайн банки, а банкоматы не были так широко распространены, как сейчас. Люди ходили в банк гораздо чаще, а из-за медленных компьютеров выстраивались очереди. Тогда банк пригрозил разорвать контракт с поставщиком.
Поставщик направил специалиста по анализу производительности и настройке, чтобы определить причину задержек. Вскоре он обнаружил, что на терминале работала одна конкретная программа, которая потребляла почти всю мощность процессора. Используя профилировщик, специалист нашёл функцию, на которую приходилась большая часть нагрузки:
Не должен ли был программист постараться чуть лучше, чем выдать код, который без необходимости выполнялся за квадратичное время? Каждый вызов
Всем известна поговорка «сначала заставь это работать, а потом заставь работать быстро», чтобы избежать ошибок микрооптимизации. Но предыдущий пример почти заставляет вас поверить, что программист скорее следовал подходу «сначала заставьте это работать медленно».
С таким легкомыслием вы можете сталкиваться довольно часто. И это не просто принцип «не изобретайте велосипед». Иногда начинающие программисты просто начинают печатать, не особо задумываясь, и внезапно «изобретают» пузырьковую сортировку. Они могут даже хвастаться этим.
Другой стороной выбора правильного алгоритма является выбор структуры данных. Это может иметь большое значение: использование связанного списка для коллекции из миллиона элементов, по которым вы хотите выполнить поиск (по сравнению с хешированной структурой данных или бинарным деревом) будет иметь большое влияние на оценку пользователем вашего продукта.
Программистам не следует изобретать велосипед и следует по возможности использовать существующие библиотеки. Но чтобы избежать проблем, подобных проблеме банка, они также должны знать об алгоритмах и способах их масштабирования. Многие говорят, что повторное использование кода в программировании имеет первостепенное значение. Однако прежде всего программисты должны знать, когда, что и как использовать повторно. Для этого они должны знать проблемную область, а также алгоритмы и структуры данных.
Хороший программист также должен знать, когда можно использовать даже отвратительный алгоритм. Например, если заранее известно, что элементов не может быть больше пяти, вы знаете, что вам всегда нужно отсортировать не более пяти элементов. В этом случае пузырьковая сортировка может оказаться наиболее эффективным способом. Всему своё время и место.
Так что читайте умные книги и разбирайтесь в том, что там написано. А если вы действительно прочитали Дональда Кнута «Искусство программирования» и смогли найти ошибку у автора, то можете получить один из его шестнадцатеричных долларов.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Jan Christiaan “JC” Van Winkel
97 Вещей, Которые Должен Знать Каждый Программист
89. Используйте Правильные Алгоритмы и Структуры Данных
Большой банк с множеством филиалов жаловался, что новые компьютеры, которые он закупил для кассиров, слишком медленные. Это было ещё до того, как все начали использовать онлайн банки, а банкоматы не были так широко распространены, как сейчас. Люди ходили в банк гораздо чаще, а из-за медленных компьютеров выстраивались очереди. Тогда банк пригрозил разорвать контракт с поставщиком.
Поставщик направил специалиста по анализу производительности и настройке, чтобы определить причину задержек. Вскоре он обнаружил, что на терминале работала одна конкретная программа, которая потребляла почти всю мощность процессора. Используя профилировщик, специалист нашёл функцию, на которую приходилась большая часть нагрузки:
for (i=0; i<strlen(s); ++i) {При этом строка s в среднем состояла из тысяч символов. Код (написанный банком) был быстро исправлен, и с тех пор кассиры жили долго и счастливо…
if (… s[i] …) …
}
Не должен ли был программист постараться чуть лучше, чем выдать код, который без необходимости выполнялся за квадратичное время? Каждый вызов
strlen
проходил по всем тысячам символов в строке, чтобы найти завершающий нулевой байт. При этом строка в цикле не изменялась. Заранее определив её длину, программист мог бы сэкономить тысячи вызовов strlen
:n=strlen(s);*Замечание: понятно, что пример взят из конкретного языка и старого компилятора. Сейчас большинство таких проблем компилятор может оптимизировать, а нахождение длины строки или размера коллекции далеко не всегда требует пересчёта всех элементов. Но всё же, это не значит, что за подобными вещами не стоит следить.
for (i=0; i<n; ++i) {
if (… s[i] …) …
}
Всем известна поговорка «сначала заставь это работать, а потом заставь работать быстро», чтобы избежать ошибок микрооптимизации. Но предыдущий пример почти заставляет вас поверить, что программист скорее следовал подходу «сначала заставьте это работать медленно».
С таким легкомыслием вы можете сталкиваться довольно часто. И это не просто принцип «не изобретайте велосипед». Иногда начинающие программисты просто начинают печатать, не особо задумываясь, и внезапно «изобретают» пузырьковую сортировку. Они могут даже хвастаться этим.
Другой стороной выбора правильного алгоритма является выбор структуры данных. Это может иметь большое значение: использование связанного списка для коллекции из миллиона элементов, по которым вы хотите выполнить поиск (по сравнению с хешированной структурой данных или бинарным деревом) будет иметь большое влияние на оценку пользователем вашего продукта.
Программистам не следует изобретать велосипед и следует по возможности использовать существующие библиотеки. Но чтобы избежать проблем, подобных проблеме банка, они также должны знать об алгоритмах и способах их масштабирования. Многие говорят, что повторное использование кода в программировании имеет первостепенное значение. Однако прежде всего программисты должны знать, когда, что и как использовать повторно. Для этого они должны знать проблемную область, а также алгоритмы и структуры данных.
Хороший программист также должен знать, когда можно использовать даже отвратительный алгоритм. Например, если заранее известно, что элементов не может быть больше пяти, вы знаете, что вам всегда нужно отсортировать не более пяти элементов. В этом случае пузырьковая сортировка может оказаться наиболее эффективным способом. Всему своё время и место.
Так что читайте умные книги и разбирайтесь в том, что там написано. А если вы действительно прочитали Дональда Кнута «Искусство программирования» и смогли найти ошибку у автора, то можете получить один из его шестнадцатеричных долларов.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Jan Christiaan “JC” Van Winkel
День восемьсот восьмидесятый. #BestPractices #CodeReview
Лучшие Практики для Эффективных Обзоров Кода. Начало
Обзор кода, если проведён правильно, позволяет разработчикам предоставлять оптимальный исходный код, одновременно узнавая больше об эффективном написании и отладке кода.
Процесс написания кода требует больших умственных усилий и концентрации, что очень затрудняет достижение безупречного результата. Однако важно помнить, что идеального кода не бывает. Программисты должны стремиться к созданию «лучшего» кода, который можно постоянно улучшать. Проверка работы автора кода не может гарантировать предотвращение всех ошибок, но может защитить пользователей от их возникновения. Вот почему интеграция обзоров кода в процесс разработки помогает предоставлять высококачественные приложения.
Обзор кода - это систематическая проверка исходного кода ПО, используемая для выявления ошибок на ранних стадиях, отслеживания возможных упущений и повышения общего качества и согласованности кода. Этот процесс помогает коду оставаться более удобным для сопровождения. Анализ кода, проводимый коллегами-программистами и специалистами по обеспечению качества, направлен на ускорение и оптимизацию процесса разработки ПО.
Важно убедиться, что все члены команды понимают правила и рекомендации по проведению обзора кода в компании. Взаимная проверка кода - это объединение усилий для повышения производительности, а не конкуренция.
1. Знайте, что искать
Разработчики должны точно знать, какие аспекты им следует охватить: дизайн, функциональность, стиль, логику, структуру, согласованность, покрытие тестами, сложность кода и т.д. Некоторые из вышеупомянутых характеристик могут быть проверены автоматически благодаря статическим анализаторам кода (например, структура, логика или покрытие тестами), в то время как другие (например, дизайн и функциональность) требуют проверки вручную.
Чтобы сделать процесс проверки более эффективным, рецензенты должны сосредоточиться на следующих вопросах:
- Можно ли чётко понять, что делает код?
- Код работает так, как ожидалось?
- Соответствует ли код нормативным требованиям?
Если они могут ответить на эти вопросы с уверенностью «да», код можно считать хорошим.
2. Автоматизируйте перед проверкой
Стоит обратить внимание на непрерывную интеграцию, то есть на выполнение серии автоматических тестов при сборке и тестировании кода каждый раз, когда происходит изменение. Перед экспертной оценкой должна проводиться непрерывная интеграция. Когда серия автоматических тестов проходит, разработчики получают код с меньшим количеством ошибок, а процесс ручной проверки становится более плавным и быстрым, что экономит время разработчиков.
3. Ограничьте время обзора
Эффективная проверка может быть проведена только тогда, когда разработчики на 100% сосредоточены на выполняемой задаче. Большинство исследований показывают, что, когда люди занимаются какой-либо деятельностью, требующей высокой концентрации, их эффективность снижается через 60 минут. При проверке кода не нужно торопиться. Лучше разбить этот процесс на короткие сеансы, что даст разработчикам возможность отдохнуть и тем самым улучшить качество проверки.
4. Проверяйте не больше 400 строк кода в час
Одна неправильно рассмотренная строка кода может иметь плохие последствия для всей системы. Вот почему попытка проверить как можно больше строк за один сеанс может привести к провалу всей команды разработчиков. Обзор кода нельзя делать в спешке, иначе он теряет смысл. Попытка сосредоточиться максимум на 400 строках для каждого сеанса проверки приведёт к более тщательному и эффективному процессу проверки.
Окончание следует…
Источник: https://dzone.com/articles/9-best-practices-for-effective-code-review
Лучшие Практики для Эффективных Обзоров Кода. Начало
Обзор кода, если проведён правильно, позволяет разработчикам предоставлять оптимальный исходный код, одновременно узнавая больше об эффективном написании и отладке кода.
Процесс написания кода требует больших умственных усилий и концентрации, что очень затрудняет достижение безупречного результата. Однако важно помнить, что идеального кода не бывает. Программисты должны стремиться к созданию «лучшего» кода, который можно постоянно улучшать. Проверка работы автора кода не может гарантировать предотвращение всех ошибок, но может защитить пользователей от их возникновения. Вот почему интеграция обзоров кода в процесс разработки помогает предоставлять высококачественные приложения.
Обзор кода - это систематическая проверка исходного кода ПО, используемая для выявления ошибок на ранних стадиях, отслеживания возможных упущений и повышения общего качества и согласованности кода. Этот процесс помогает коду оставаться более удобным для сопровождения. Анализ кода, проводимый коллегами-программистами и специалистами по обеспечению качества, направлен на ускорение и оптимизацию процесса разработки ПО.
Важно убедиться, что все члены команды понимают правила и рекомендации по проведению обзора кода в компании. Взаимная проверка кода - это объединение усилий для повышения производительности, а не конкуренция.
1. Знайте, что искать
Разработчики должны точно знать, какие аспекты им следует охватить: дизайн, функциональность, стиль, логику, структуру, согласованность, покрытие тестами, сложность кода и т.д. Некоторые из вышеупомянутых характеристик могут быть проверены автоматически благодаря статическим анализаторам кода (например, структура, логика или покрытие тестами), в то время как другие (например, дизайн и функциональность) требуют проверки вручную.
Чтобы сделать процесс проверки более эффективным, рецензенты должны сосредоточиться на следующих вопросах:
- Можно ли чётко понять, что делает код?
- Код работает так, как ожидалось?
- Соответствует ли код нормативным требованиям?
Если они могут ответить на эти вопросы с уверенностью «да», код можно считать хорошим.
2. Автоматизируйте перед проверкой
Стоит обратить внимание на непрерывную интеграцию, то есть на выполнение серии автоматических тестов при сборке и тестировании кода каждый раз, когда происходит изменение. Перед экспертной оценкой должна проводиться непрерывная интеграция. Когда серия автоматических тестов проходит, разработчики получают код с меньшим количеством ошибок, а процесс ручной проверки становится более плавным и быстрым, что экономит время разработчиков.
3. Ограничьте время обзора
Эффективная проверка может быть проведена только тогда, когда разработчики на 100% сосредоточены на выполняемой задаче. Большинство исследований показывают, что, когда люди занимаются какой-либо деятельностью, требующей высокой концентрации, их эффективность снижается через 60 минут. При проверке кода не нужно торопиться. Лучше разбить этот процесс на короткие сеансы, что даст разработчикам возможность отдохнуть и тем самым улучшить качество проверки.
4. Проверяйте не больше 400 строк кода в час
Одна неправильно рассмотренная строка кода может иметь плохие последствия для всей системы. Вот почему попытка проверить как можно больше строк за один сеанс может привести к провалу всей команды разработчиков. Обзор кода нельзя делать в спешке, иначе он теряет смысл. Попытка сосредоточиться максимум на 400 строках для каждого сеанса проверки приведёт к более тщательному и эффективному процессу проверки.
Окончание следует…
Источник: https://dzone.com/articles/9-best-practices-for-effective-code-review
День восемьсот восемьдесят первый. #BestPractices #CodeReview
Лучшие Практики для Эффективных Обзоров Кода. Окончание
Начало
5. Давайте конструктивную обратную связь
Взаимная проверка кода направлена на повышение производительности команды, а не на разжигание конкуренции между автором кода и рецензентом. В любом случае код необходимо проверять. И если разработчики воспринимают это как процесс обучения, а не критику своей работы, это способствует общему успеху проекта. Получение конструктивной обратной связи побудит разработчиков учиться на своих ошибках и расширять свои возможности. Рецензенты могут оставлять комментарии с префиксом «Nit:» (от «nitpicking» - придирки). Это означает, что такие вещи не обязательно должны исправляться, а имеют образовательную цель и помогают разработчикам постоянно совершенствовать свои навыки. Например:
Если цели процесса обзора кода определены заранее, гораздо проще измерить эффективность кода и решить, приносит ли проверка пользу и помогает ли достичь ожидаемых результатов. Настройка внешних и внутренних показателей позволяет разработчикам улучшить качество кода. Примерами внешних показателей могут быть «уменьшение процента дефектов, сообщаемых конечными пользователями» или «уменьшение количества дефектов, обнаруженных до запуска продукта».
Внутренние показатели включают:
- Скорость проверки.
- Дефектность: среднее количество ошибок, обнаруженных за один сеанс.
- Плотность дефектов: среднее количество ошибок на строку кода.
7. Комментируйте код для рецензента
Комментарии предоставляет информацию о том, что пытается выполнить каждая строка или раздел кода. Они также могут показать рецензенту, какие изменения были внесены, какие методы модификации кода использовались и почему это было полезно. Эта практика способствует более глубокому пониманию кода рецензентом и упрощает общий процесс проверки кода. Например:
Разработчик – человек, поэтому может упустить из виду некоторые аспекты кода. Чек-лист сделает процесс проверки более последовательным, поскольку будет постоянно напоминать о том, что следует проверять. Он особенно полезен для рецензента, поскольку помогает проводить проверку по конкретным критериям. Однако существует и такое понятие, как личный чек-лист. Если автор кода знает о своих типичных ошибках и недостатках в работе, он может составить чек-лист, чтобы постоянно улучшать качество своего кода. Кроме того, чек-листы проверки кода очень важны для выявления упущений, которые труднее всего проверять, потому что сложно обнаружить отсутствие чего-либо.
Вот некоторые вопросы для чек-листа:
- Легко ли понять код?
- Соответствует ли форматирование кода соглашению по проекту?
- Достаточно ли модульная структура кода?
- Соответствует ли выбранное решение требованиям?
- Проверена ли вся логика и все ошибки?
- Есть ли проблемы в безопасности?
- Как дела с производительностью? (Есть ли очевидные моменты для оптимизации?)
- Весь ли код покрыт тестами?
- Насколько эффективно и информативно описание пул реквеста?
9. Включайте всех
Чем больше будет глаз, тем легче найти ошибку. Люди, как правило, работают лучше, если знают, что их работа будет проверена. Неважно, какой уровень квалификации у программиста - каждый должен участвовать в процессе обзора кода. Младшие разработчики могут обучаться новым или альтернативным методам выполнения чего-либо у своих старших коллег, а старшие могут совершенствовать свои навыки программирования, написав код, понятный и читаемый для всех.
Источник: https://dzone.com/articles/9-best-practices-for-effective-code-review
Лучшие Практики для Эффективных Обзоров Кода. Окончание
Начало
5. Давайте конструктивную обратную связь
Взаимная проверка кода направлена на повышение производительности команды, а не на разжигание конкуренции между автором кода и рецензентом. В любом случае код необходимо проверять. И если разработчики воспринимают это как процесс обучения, а не критику своей работы, это способствует общему успеху проекта. Получение конструктивной обратной связи побудит разработчиков учиться на своих ошибках и расширять свои возможности. Рецензенты могут оставлять комментарии с префиксом «Nit:» (от «nitpicking» - придирки). Это означает, что такие вещи не обязательно должны исправляться, а имеют образовательную цель и помогают разработчикам постоянно совершенствовать свои навыки. Например:
var file = app != null && !string.IsNullOrEmpty(app.FilePath);6. Установка целей и сбор метрик
// Nit: может быть заменено на
// !string.IsNullOrEmpty(app?.FilePath);
Если цели процесса обзора кода определены заранее, гораздо проще измерить эффективность кода и решить, приносит ли проверка пользу и помогает ли достичь ожидаемых результатов. Настройка внешних и внутренних показателей позволяет разработчикам улучшить качество кода. Примерами внешних показателей могут быть «уменьшение процента дефектов, сообщаемых конечными пользователями» или «уменьшение количества дефектов, обнаруженных до запуска продукта».
Внутренние показатели включают:
- Скорость проверки.
- Дефектность: среднее количество ошибок, обнаруженных за один сеанс.
- Плотность дефектов: среднее количество ошибок на строку кода.
7. Комментируйте код для рецензента
Комментарии предоставляет информацию о том, что пытается выполнить каждая строка или раздел кода. Они также могут показать рецензенту, какие изменения были внесены, какие методы модификации кода использовались и почему это было полезно. Эта практика способствует более глубокому пониманию кода рецензентом и упрощает общий процесс проверки кода. Например:
// Начинаем с 1, чтобы 0 был недопустимым8. Используйте чек-листы
// и это можно было проверять при передаче параметра извне
public enum SupplierStatsType {
All = 1, General = 2, Custom = 3
}
Разработчик – человек, поэтому может упустить из виду некоторые аспекты кода. Чек-лист сделает процесс проверки более последовательным, поскольку будет постоянно напоминать о том, что следует проверять. Он особенно полезен для рецензента, поскольку помогает проводить проверку по конкретным критериям. Однако существует и такое понятие, как личный чек-лист. Если автор кода знает о своих типичных ошибках и недостатках в работе, он может составить чек-лист, чтобы постоянно улучшать качество своего кода. Кроме того, чек-листы проверки кода очень важны для выявления упущений, которые труднее всего проверять, потому что сложно обнаружить отсутствие чего-либо.
Вот некоторые вопросы для чек-листа:
- Легко ли понять код?
- Соответствует ли форматирование кода соглашению по проекту?
- Достаточно ли модульная структура кода?
- Соответствует ли выбранное решение требованиям?
- Проверена ли вся логика и все ошибки?
- Есть ли проблемы в безопасности?
- Как дела с производительностью? (Есть ли очевидные моменты для оптимизации?)
- Весь ли код покрыт тестами?
- Насколько эффективно и информативно описание пул реквеста?
9. Включайте всех
Чем больше будет глаз, тем легче найти ошибку. Люди, как правило, работают лучше, если знают, что их работа будет проверена. Неважно, какой уровень квалификации у программиста - каждый должен участвовать в процессе обзора кода. Младшие разработчики могут обучаться новым или альтернативным методам выполнения чего-либо у своих старших коллег, а старшие могут совершенствовать свои навыки программирования, написав код, понятный и читаемый для всех.
Источник: https://dzone.com/articles/9-best-practices-for-effective-code-review
День восемьсот восемьдесят второй. #ЧтоНовенького
Горячая Перезагрузка и Другие Обновления ASP.NET Core в .NET 6 Preview 5
Горячая Перезагрузка (Hot Reload) - долгожданная функциональность, позволяющая разработчикам вносить изменения в код во время отладки, которые мгновенно отражаются в работающем приложении без необходимости перезапуска - была представлена на конференции разработчиков May Build. Она поддерживалась в ранней неполной форме в Visual Studio 2019 версии 16.11 Preview 1. С тех пор были добавлены дополнительные улучшения.
Для ASP.NET Core основное улучшение Hot Reload затрагивает
Больше не нужно указывать hotReloadProfile в launchSettings.json. .NET Hot Reload с соответствующим поведением проекта теперь включена по умолчанию. Когда вносится изменение, которое не может быть перезагружено горячим способом («грубое» изменение), dotnet watch теперь спросит, хотите ли вы перезапустить приложение, чтобы применить изменение. «Грубые» изменения в приложениях Blazor WebAssembly будут применены при обновлении браузера или при загрузке приложения в отдельной вкладке или новом окне браузера.
Размеры загружаемых файлов Blazor WebAssembly были уменьшены с помощью функции, известной как повторное связывание (relinking). Она позволяет исключить ненужную логику выполнения - такую как глобализация - из загрузки.
Другие новинки ASP.NET Core .NET 6 Preview 5:
- Шаблоны ASP.NET Core SPA обновлены до Angular 11 и React 17
- Использование синтаксиса Razor в элементах SVG foreignObject
- Настраиваемый порог буфера перед записью на диск в Json.NET
- Подкатегории для лучшей фильтрации журналов Kestrel
- Более быстрое получение и установка заголовков HTTP
- Настраиваемый размер входящего буфера для IIS
Пока существуют известные проблемы с использованием ASP.NET Core в .NET 6 Preview 5:
1. Начиная с .NET 6 Preview 1, существует проблема с запуском приложений Blazor WebAssembly с использованием сервера IIS Express во время разработки в Visual Studio. Чтобы обойти это, рекомендуется использовать Kestrel во время разработки.
2. Начиная с .NET 6 Preview 3, изменения представлений Razor не будут обновляться во время инкрементных сборок. Чтобы обойти это, вы можете:
- Осуществлять сборку из командной строки
- Настроить VS, чтобы всегда вызывать MSBuild при сборке проектов
- Очищать и собирать проекты, чтобы изменения отражались
3. Начиная с .NET 6 Preview 5, при использовании обработчика JWT Bearer в часовом поясе выше, чем UTC (например, UTC+2), вы можете наблюдать исключение
Вы можете обойти это, всегда предоставляя ненулевое и не минимальное значение для параметра
Источник: https://visualstudiomagazine.com/articles/2021/06/18/aspnet-core-updates.aspx
Горячая Перезагрузка и Другие Обновления ASP.NET Core в .NET 6 Preview 5
Горячая Перезагрузка (Hot Reload) - долгожданная функциональность, позволяющая разработчикам вносить изменения в код во время отладки, которые мгновенно отражаются в работающем приложении без необходимости перезапуска - была представлена на конференции разработчиков May Build. Она поддерживалась в ранней неполной форме в Visual Studio 2019 версии 16.11 Preview 1. С тех пор были добавлены дополнительные улучшения.
Для ASP.NET Core основное улучшение Hot Reload затрагивает
dotnet watch
- инструмент командной строки (CLI), который выполняет команду .NET Core при изменении исходных файлов и обновляет браузер при обнаружении изменений в наблюдаемых файлах. Это позволяет перезагружать проекты ASP.NET Core в реальном времени.Больше не нужно указывать hotReloadProfile в launchSettings.json. .NET Hot Reload с соответствующим поведением проекта теперь включена по умолчанию. Когда вносится изменение, которое не может быть перезагружено горячим способом («грубое» изменение), dotnet watch теперь спросит, хотите ли вы перезапустить приложение, чтобы применить изменение. «Грубые» изменения в приложениях Blazor WebAssembly будут применены при обновлении браузера или при загрузке приложения в отдельной вкладке или новом окне браузера.
Размеры загружаемых файлов Blazor WebAssembly были уменьшены с помощью функции, известной как повторное связывание (relinking). Она позволяет исключить ненужную логику выполнения - такую как глобализация - из загрузки.
Другие новинки ASP.NET Core .NET 6 Preview 5:
- Шаблоны ASP.NET Core SPA обновлены до Angular 11 и React 17
- Использование синтаксиса Razor в элементах SVG foreignObject
- Настраиваемый порог буфера перед записью на диск в Json.NET
- Подкатегории для лучшей фильтрации журналов Kestrel
- Более быстрое получение и установка заголовков HTTP
- Настраиваемый размер входящего буфера для IIS
Пока существуют известные проблемы с использованием ASP.NET Core в .NET 6 Preview 5:
1. Начиная с .NET 6 Preview 1, существует проблема с запуском приложений Blazor WebAssembly с использованием сервера IIS Express во время разработки в Visual Studio. Чтобы обойти это, рекомендуется использовать Kestrel во время разработки.
2. Начиная с .NET 6 Preview 3, изменения представлений Razor не будут обновляться во время инкрементных сборок. Чтобы обойти это, вы можете:
- Осуществлять сборку из командной строки
- Настроить VS, чтобы всегда вызывать MSBuild при сборке проектов
- Очищать и собирать проекты, чтобы изменения отражались
3. Начиная с .NET 6 Preview 5, при использовании обработчика JWT Bearer в часовом поясе выше, чем UTC (например, UTC+2), вы можете наблюдать исключение
ArgumentOutOfRangeException
, если токен JWT не содержит значение nbf
(Действует с). Проблема отслеживается здесь и будет исправлена в .NET 6 Preview 6.Вы можете обойти это, всегда предоставляя ненулевое и не минимальное значение для параметра
notBefore
при использовании System.IdentityModel.Tokens.Jwt.JwtSecurityToken или поле 'nbf
' при использовании другой библиотеки JWT.Источник: https://visualstudiomagazine.com/articles/2021/06/18/aspnet-core-updates.aspx
День восемьсот восемьдесят третий. #DesignPatterns #Microservices
Микросервисная Архитектура и Паттерны Проектирования
Существует множество определений микросервисной архитектуры. Вот одно из них:
Микросервисная архитектура представляет собой вертикальное разделение больших сложных систем (по функциональным или бизнес-требованиям) на более мелкие подсистемы, которые являются отдельными процессами (следовательно, могут развёртываться независимо), и эти подсистемы взаимодействуют друг с другом через лёгкие, не зависящие от языка сетевые вызовы либо синхронным (например, через REST, gRPC) или асинхронным (через обмен сообщениями) способом.
Компонентное представление бизнес-веб-приложения с микросервисной архитектурой представлено на рисунке ниже.
Характеристики:
- Всё приложение разделено на отдельные процессы, каждый из которых может содержать несколько внутренних модулей.
- В отличие от модульных монолитов или сервисно-ориентированной архитектуры, микросервисное приложение разделено по вертикали (в соответствии с бизнес-потребностями или доменами).
- Границы микросервисов внешние, то есть микросервисы взаимодействуют друг с другом через сетевые вызовы (RPC или сообщения).
- Поскольку микросервисы являются независимыми процессами, их можно развёртывать независимо.
- Они общаются легко и не нуждаются в каком-то хитром канале связи.
Преимущества:
- Лучшее масштабирование разработки.
- Более высокая скорость разработки.
- Поддерживается итеративная или инкрементная модернизация.
- Возможность использовать преимущества современной экосистемы разработки ПО (облако, контейнеры, DevOps, бессерверная среда).
- Поддерживается как горизонтальное, так и гранулярное масштабирование (возможность масштабировать отдельные микросервисы).
- Благодаря меньшему размеру, снижается нагрузка на разработчиков, которым не приходится держать в голове большую систему.
Недостатки:
- Большее количество элементов (сервисы, базы данных, процессы, контейнеры, фреймворки).
- Сложность переходит от кода к инфраструктуре.
- Большее количество вызовов RPC и сетевого трафика.
- Управление безопасностью всей системы является сложной задачей.
- Проектировать всю систему сложнее.
- Возникают сложности распределённых систем.
Варианты использования:
- Разработка веб-приложений.
- Разработка корпоративных приложений, когда над приложением работают несколько команд.
- В случаях, когда долгосрочный эффект предпочтительнее краткосрочного.
- В команде есть архитекторы ПО, способные разработать микросервисную архитектуру.
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Микросервисная Архитектура и Паттерны Проектирования
Существует множество определений микросервисной архитектуры. Вот одно из них:
Микросервисная архитектура представляет собой вертикальное разделение больших сложных систем (по функциональным или бизнес-требованиям) на более мелкие подсистемы, которые являются отдельными процессами (следовательно, могут развёртываться независимо), и эти подсистемы взаимодействуют друг с другом через лёгкие, не зависящие от языка сетевые вызовы либо синхронным (например, через REST, gRPC) или асинхронным (через обмен сообщениями) способом.
Компонентное представление бизнес-веб-приложения с микросервисной архитектурой представлено на рисунке ниже.
Характеристики:
- Всё приложение разделено на отдельные процессы, каждый из которых может содержать несколько внутренних модулей.
- В отличие от модульных монолитов или сервисно-ориентированной архитектуры, микросервисное приложение разделено по вертикали (в соответствии с бизнес-потребностями или доменами).
- Границы микросервисов внешние, то есть микросервисы взаимодействуют друг с другом через сетевые вызовы (RPC или сообщения).
- Поскольку микросервисы являются независимыми процессами, их можно развёртывать независимо.
- Они общаются легко и не нуждаются в каком-то хитром канале связи.
Преимущества:
- Лучшее масштабирование разработки.
- Более высокая скорость разработки.
- Поддерживается итеративная или инкрементная модернизация.
- Возможность использовать преимущества современной экосистемы разработки ПО (облако, контейнеры, DevOps, бессерверная среда).
- Поддерживается как горизонтальное, так и гранулярное масштабирование (возможность масштабировать отдельные микросервисы).
- Благодаря меньшему размеру, снижается нагрузка на разработчиков, которым не приходится держать в голове большую систему.
Недостатки:
- Большее количество элементов (сервисы, базы данных, процессы, контейнеры, фреймворки).
- Сложность переходит от кода к инфраструктуре.
- Большее количество вызовов RPC и сетевого трафика.
- Управление безопасностью всей системы является сложной задачей.
- Проектировать всю систему сложнее.
- Возникают сложности распределённых систем.
Варианты использования:
- Разработка веб-приложений.
- Разработка корпоративных приложений, когда над приложением работают несколько команд.
- В случаях, когда долгосрочный эффект предпочтительнее краткосрочного.
- В команде есть архитекторы ПО, способные разработать микросервисную архитектуру.
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍1
День восемьсот восемьдесят четвёртый. #DesignPatterns #Microservices
Паттерны в Микросервисах
1. База Данных на Микросервис
Когда компания заменяет большую монолитную систему множеством мелких микросервисов, самое важное решение, с которым она сталкивается, - это база данных. В монолитной архитектуре используется большая централизованная база данных. Многие архитекторы предпочитают сохранять базу данных как есть, даже при переходе на микросервисную архитектуру. Хотя это даёт некоторую краткосрочную выгоду, это анти-шаблон, особенно в крупной системе, поскольку микросервисы будут тесно связаны на уровне базы данных. Весь смысл перехода на микросервисы (расширение возможностей команды, независимая разработка) потеряется.
Лучший подход - предоставить каждому микросервису собственное хранилище данных, чтобы не было сильной связи между службами на уровне базы данных (см. рисунок ниже). Здесь термин «база данных» используется, чтобы показать логическое разделение данных, то есть микросервисы могут совместно использовать одну и ту же физическую базу данных, но они должны использовать отдельную схему/коллекцию/таблицу. Это также гарантирует, что микросервисы правильно разделены в соответствии с предметно-ориентированным проектированием (DDD).
Плюсы
- Полное владение данными для каждого сервиса.
- Слабая связь между командами, разрабатывающими сервисы.
Минусы
- Обмен данными между службами становится проблематичным.
- Предоставление транзакционной гарантии ACID для приложения становится намного сложнее.
- Разделение монолитной базы данных на более мелкие части требует тщательного проектирования и является сложной задачей.
Когда использовать:
- В крупномасштабных корпоративных приложениях.
- Когда команде необходимо полное владение своими микросервисами для масштабирования и скорости разработки.
Когда не использовать:
- В небольших приложениях.
- Если одна команда разработает все микросервисы.
Поддержка
Все базы данных SQL и NoSQL предлагают логическое разделение данных (например, отдельные таблицы, коллекции, схемы, базы данных).
Подробнее:
- Microservices Pattern: Database per service
- Распределённые данные
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Паттерны в Микросервисах
1. База Данных на Микросервис
Когда компания заменяет большую монолитную систему множеством мелких микросервисов, самое важное решение, с которым она сталкивается, - это база данных. В монолитной архитектуре используется большая централизованная база данных. Многие архитекторы предпочитают сохранять базу данных как есть, даже при переходе на микросервисную архитектуру. Хотя это даёт некоторую краткосрочную выгоду, это анти-шаблон, особенно в крупной системе, поскольку микросервисы будут тесно связаны на уровне базы данных. Весь смысл перехода на микросервисы (расширение возможностей команды, независимая разработка) потеряется.
Лучший подход - предоставить каждому микросервису собственное хранилище данных, чтобы не было сильной связи между службами на уровне базы данных (см. рисунок ниже). Здесь термин «база данных» используется, чтобы показать логическое разделение данных, то есть микросервисы могут совместно использовать одну и ту же физическую базу данных, но они должны использовать отдельную схему/коллекцию/таблицу. Это также гарантирует, что микросервисы правильно разделены в соответствии с предметно-ориентированным проектированием (DDD).
Плюсы
- Полное владение данными для каждого сервиса.
- Слабая связь между командами, разрабатывающими сервисы.
Минусы
- Обмен данными между службами становится проблематичным.
- Предоставление транзакционной гарантии ACID для приложения становится намного сложнее.
- Разделение монолитной базы данных на более мелкие части требует тщательного проектирования и является сложной задачей.
Когда использовать:
- В крупномасштабных корпоративных приложениях.
- Когда команде необходимо полное владение своими микросервисами для масштабирования и скорости разработки.
Когда не использовать:
- В небольших приложениях.
- Если одна команда разработает все микросервисы.
Поддержка
Все базы данных SQL и NoSQL предлагают логическое разделение данных (например, отдельные таблицы, коллекции, схемы, базы данных).
Подробнее:
- Microservices Pattern: Database per service
- Распределённые данные
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
День восемьсот восемьдесят пятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
90. Навыки, Необходимые Сеньору, Помимо Программирования
Сегодня вашему вниманию несколько шуточный список навыков, которыми должен обладать старший разработчик или тимлид. Предлагайте свои варианты в комментариях.
1. Как провести собрание. И нет, больше всего говорить на собрании, не то же самое, что проводить его.
2. Как написать проектную документацию, получить отзывы и довести её до решения в разумные сроки.
3. Как подсказать товарищу по команде, начинающему карьеру, инженеру в середине карьеры, новому менеджеру, которому нужен технический совет.
4. Как говорить со старшим менеджером о технических вещах, в которых он на самом деле ничего не понимает, не закатывая глаза и не заставляя его чувствовать себя глупо.
5. Как объяснить техническую концепцию важному начальнику, который стесняется признаться, что он её не понимает.
6. Как убедить другую команду использовать ваше решение вместо написания собственного.
7. Как заставить другого инженера сделать что-то для вас, попросив о помощи таким образом, чтобы он почувствовал, что его ценят.
8. Как вести проект, даже если вы не управляете никем из людей, работающих над ним.
9. Как заставить других инженеров прислушиваться к вашим идеям, не заставляя их чувствовать в вас угрозу.
10. Как прислушиваться к идеям других инженеров и не чувствовать в них угрозы.
11. Как отказаться от своего ребёнка (от проекта, который вы превратили во что-то существенное), чтобы заняться чем-то другим.
12. Как научить другого инженера заботиться о том, что вас действительно волнует (операции, форматирование, тестирование, качество кода, производительность, простота и т.д.).
13. Как правильно сообщать о статусе проекта инвесторам.
14. Как убедить руководство в том, что им нужно инвестировать в нетривиальный технический проект.
15. Как создавать программное обеспечение, привнося при этом дополнительную ценность в процессе.
16. Как составить проектное предложение, разрекламировать его и получить поддержку для его реализации.
17. Сколько раз достаточно повторить, чтобы люди начали слушать.
18. Как выбрать правильных бойцов в команду.
19. Как помочь кому-то продвинуться по службе.
20. Как получить информацию о том, что на самом деле происходит (как сплетничать, как найти подход к разным людям).
21. Как найти интересную работу самостоятельно, а не ждать, пока кто-то её вам принесет.
22. Как сказать кому-то, что он неправ, не унизив его.
23. Как правильно воспринимать отрицательные отзывы.
Источник: https://skamille.medium.com/an-incomplete-list-of-skills-senior-engineers-need-beyond-coding-8ed4a521b29f
Автор оригинала – Camille Fournier
97 Вещей, Которые Должен Знать Каждый Программист
90. Навыки, Необходимые Сеньору, Помимо Программирования
Сегодня вашему вниманию несколько шуточный список навыков, которыми должен обладать старший разработчик или тимлид. Предлагайте свои варианты в комментариях.
1. Как провести собрание. И нет, больше всего говорить на собрании, не то же самое, что проводить его.
2. Как написать проектную документацию, получить отзывы и довести её до решения в разумные сроки.
3. Как подсказать товарищу по команде, начинающему карьеру, инженеру в середине карьеры, новому менеджеру, которому нужен технический совет.
4. Как говорить со старшим менеджером о технических вещах, в которых он на самом деле ничего не понимает, не закатывая глаза и не заставляя его чувствовать себя глупо.
5. Как объяснить техническую концепцию важному начальнику, который стесняется признаться, что он её не понимает.
6. Как убедить другую команду использовать ваше решение вместо написания собственного.
7. Как заставить другого инженера сделать что-то для вас, попросив о помощи таким образом, чтобы он почувствовал, что его ценят.
8. Как вести проект, даже если вы не управляете никем из людей, работающих над ним.
9. Как заставить других инженеров прислушиваться к вашим идеям, не заставляя их чувствовать в вас угрозу.
10. Как прислушиваться к идеям других инженеров и не чувствовать в них угрозы.
11. Как отказаться от своего ребёнка (от проекта, который вы превратили во что-то существенное), чтобы заняться чем-то другим.
12. Как научить другого инженера заботиться о том, что вас действительно волнует (операции, форматирование, тестирование, качество кода, производительность, простота и т.д.).
13. Как правильно сообщать о статусе проекта инвесторам.
14. Как убедить руководство в том, что им нужно инвестировать в нетривиальный технический проект.
15. Как создавать программное обеспечение, привнося при этом дополнительную ценность в процессе.
16. Как составить проектное предложение, разрекламировать его и получить поддержку для его реализации.
17. Сколько раз достаточно повторить, чтобы люди начали слушать.
18. Как выбрать правильных бойцов в команду.
19. Как помочь кому-то продвинуться по службе.
20. Как получить информацию о том, что на самом деле происходит (как сплетничать, как найти подход к разным людям).
21. Как найти интересную работу самостоятельно, а не ждать, пока кто-то её вам принесет.
22. Как сказать кому-то, что он неправ, не унизив его.
23. Как правильно воспринимать отрицательные отзывы.
Источник: https://skamille.medium.com/an-incomplete-list-of-skills-senior-engineers-need-beyond-coding-8ed4a521b29f
Автор оригинала – Camille Fournier
День восемьсот восемьдесят шестой. #ЗаметкиНаПолях
Начиная с .NET 5 Изменение Значений в Dictionary в Foreach не Выбрасывает Исключения
Давно известно, что внутри цикла
System.InvalidOperationException: Collection was modified; enumeration operation may not execute. (Коллекция изменена; операция перечисления не может быть выполнена.)
Однако, начиная с .NET 5, он выполняется без проблем. Что случилось?
В исходный код
Удаление из словаря с помощью метода Remove также больше не влияет на перечисление. Это, однако, существует с .NET Core 3.0 и соответствующим образом упоминается в документации метода
«Только .NET Core 3.0+: Этот метод изменения может быть безопасно вызван без аннуляции активных перечислителей экземпляра Dictionary<TKey,TValue>. Но это не подразумевает потокобезопасность.»
Несмотря на то, что вышеупомянутое изменение значений при перечислении просят внести в документацию, на момент выхода этого поста, этого пока не сделано.
Источник: https://stackoverflow.com/questions/66939923/what-changed-in-net-5-that-makes-it-not-throw-when-changing-dictionary-values-i
Начиная с .NET 5 Изменение Значений в Dictionary в Foreach не Выбрасывает Исключения
Давно известно, что внутри цикла
foreach
нельзя изменять элементы коллекции. Однако, рассмотрим следующий код:var d = new Dictionary<string, int>
{ { "a", 0 }, { "b", 0 }, { "c", 0 } };
foreach (var k in d.Keys)
{
d[k]+=1;
}
В .NET Core 3.1 и ранее этот код выдавал ожидаемое исключение:System.InvalidOperationException: Collection was modified; enumeration operation may not execute. (Коллекция изменена; операция перечисления не может быть выполнена.)
Однако, начиная с .NET 5, он выполняется без проблем. Что случилось?
В исходный код
Dictionary<TKey, TValue>
было внесено изменение, позволяющее обновлять значения по существующим ключам во время перечисления. Убрали обновление внутреннего поля _version при изменении элементов. Поле _version (которое используется для обнаружения изменений) теперь обновляется только при определённых условиях, но не при изменении значения по существующему ключу.Удаление из словаря с помощью метода Remove также больше не влияет на перечисление. Это, однако, существует с .NET Core 3.0 и соответствующим образом упоминается в документации метода
Remove
:«Только .NET Core 3.0+: Этот метод изменения может быть безопасно вызван без аннуляции активных перечислителей экземпляра Dictionary<TKey,TValue>. Но это не подразумевает потокобезопасность.»
Несмотря на то, что вышеупомянутое изменение значений при перечислении просят внести в документацию, на момент выхода этого поста, этого пока не сделано.
Источник: https://stackoverflow.com/questions/66939923/what-changed-in-net-5-that-makes-it-not-throw-when-changing-dictionary-values-i
День восемьсот восемьдесят седьмой. #DesignPatterns #Microservices
Паттерны в Микросервисах
2. Источники Событий (Event Sourcing)
В микросервисной архитектуре, особенно с использованием паттерна «База данных на микросервис», микросервисы должны обмениваться данными. Для отказоустойчивых, высокомасштабируемых и отказоустойчивых систем они должны обмениваться данными асинхронно, обмениваясь Событиями. В этом случае вам может понадобиться выполнить атомарные операции, например, обновить базу данных и отправить сообщение. Если у вас есть базы данных SQL и вы хотите иметь распределённые транзакции для большого объема данных, вы не можете использовать двухфазную блокировку (2PL), поскольку она не масштабируется. Если вы используете базы данных NoSQL и хотите иметь распределённую транзакцию, вы не можете использовать 2PL, поскольку многие базы данных NoSQL не поддерживают двухфазную блокировку.
В таких сценариях используйте архитектуру на основе событий. В традиционных базах данных бизнес-объект с текущим «состоянием» сохраняется напрямую. В Event Sourcing любое событие, изменяющее состояние, или другие важные события сохраняются вместо сущностей. Это означает, что изменения бизнес-объекта сохраняются в виде серии неизменяемых событий. Состояние бизнес-объекта высчитывается путём повторной обработки всех событий этого бизнес-объекта в заданное время. Поскольку данные сохраняются в виде серии событий, а не через прямые обновления в хранилищах данных, различные службы могут воспроизводить события из хранилища событий, чтобы вычислить необходимое состояние соответствующих хранилищ данных. См. картинку ниже.
Плюсы
- Обеспечение атомарности высокомасштабируемым системам.
- Автоматическое сохранение истории сущностей, включая функционал «путешествий во времени».
- Возможность создания слабосвязанных микросервисов, управляемых событиями.
Минусы
- Чтение сущностей из хранилища событий становится сложной задачей и обычно требует дополнительного хранилища данных (паттерн CQRS)
- Общая сложность системы возрастает, и обычно требуется доменно-ориентированный дизайн.
- Система должна обрабатывать повторяющиеся события (идемпотентные) или отсутствующие события.
- Миграция схемы событий становится сложной задачей.
Когда использовать:
- Высокомасштабируемые транзакционные системы с базами данных SQL.
- Транзакционные системы с базами данных NoSQL.
- Высоко масштабируемая и устойчивая микросервисная архитектура.
- Типичные системы, управляемые сообщениями или событиями (системы электронной коммерции, бронирования и резервирования).
Когда не использовать:
- Слабо масштабируемые транзакционные системы с базами данных SQL.
- В простой микросервисной архитектуре, где микросервисы могут синхронно обмениваться данными (например, через API).
Поддержка
Хранилища: EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, Amazon DynamoDB.
Фреймворки: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
Подробнее:
- Microservices Pattern: Event sourcing
- Шаблон источников событий
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Паттерны в Микросервисах
2. Источники Событий (Event Sourcing)
В микросервисной архитектуре, особенно с использованием паттерна «База данных на микросервис», микросервисы должны обмениваться данными. Для отказоустойчивых, высокомасштабируемых и отказоустойчивых систем они должны обмениваться данными асинхронно, обмениваясь Событиями. В этом случае вам может понадобиться выполнить атомарные операции, например, обновить базу данных и отправить сообщение. Если у вас есть базы данных SQL и вы хотите иметь распределённые транзакции для большого объема данных, вы не можете использовать двухфазную блокировку (2PL), поскольку она не масштабируется. Если вы используете базы данных NoSQL и хотите иметь распределённую транзакцию, вы не можете использовать 2PL, поскольку многие базы данных NoSQL не поддерживают двухфазную блокировку.
В таких сценариях используйте архитектуру на основе событий. В традиционных базах данных бизнес-объект с текущим «состоянием» сохраняется напрямую. В Event Sourcing любое событие, изменяющее состояние, или другие важные события сохраняются вместо сущностей. Это означает, что изменения бизнес-объекта сохраняются в виде серии неизменяемых событий. Состояние бизнес-объекта высчитывается путём повторной обработки всех событий этого бизнес-объекта в заданное время. Поскольку данные сохраняются в виде серии событий, а не через прямые обновления в хранилищах данных, различные службы могут воспроизводить события из хранилища событий, чтобы вычислить необходимое состояние соответствующих хранилищ данных. См. картинку ниже.
Плюсы
- Обеспечение атомарности высокомасштабируемым системам.
- Автоматическое сохранение истории сущностей, включая функционал «путешествий во времени».
- Возможность создания слабосвязанных микросервисов, управляемых событиями.
Минусы
- Чтение сущностей из хранилища событий становится сложной задачей и обычно требует дополнительного хранилища данных (паттерн CQRS)
- Общая сложность системы возрастает, и обычно требуется доменно-ориентированный дизайн.
- Система должна обрабатывать повторяющиеся события (идемпотентные) или отсутствующие события.
- Миграция схемы событий становится сложной задачей.
Когда использовать:
- Высокомасштабируемые транзакционные системы с базами данных SQL.
- Транзакционные системы с базами данных NoSQL.
- Высоко масштабируемая и устойчивая микросервисная архитектура.
- Типичные системы, управляемые сообщениями или событиями (системы электронной коммерции, бронирования и резервирования).
Когда не использовать:
- Слабо масштабируемые транзакционные системы с базами данных SQL.
- В простой микросервисной архитектуре, где микросервисы могут синхронно обмениваться данными (например, через API).
Поддержка
Хранилища: EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, Amazon DynamoDB.
Фреймворки: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
Подробнее:
- Microservices Pattern: Event sourcing
- Шаблон источников событий
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍4
Конференция по .NET-разработке DotNext ищет спикеров 🎙
Вам есть о чем рассказать и что обсудить с коллегами по цеху? Тогда вам нужно подать заявку на участие в конференции!
Осенью DotNext пройдет 18-21 октября, онлайн (гибридный формат решили отложить из-за непредсказуемости ввода ограничений на офлайн мероприятия).
Темы, которые ждут больше всего:
✔️ Internals;
✔️ Architecture;
✔️ Security;
✔️ Performance;
✔️ DevOps & Tools.
Но не ограничивайте себя этим списком — вы можете подать заявку с любой темой из области .NET-разработки.
Если все-таки сомневаетесь, то программный комитет всегда готов обсудить актуальность темы и помочь выбрать правильный вектор доклада. Плюс, ребята помогут с прокачкой ваших ораторских навыков, если у вас мало опыта в публичных выступлениях.
✅ Подать заявку и узнать подробности можно на сайте.
❓Вопросы присылайте на почту [email protected]
Вам есть о чем рассказать и что обсудить с коллегами по цеху? Тогда вам нужно подать заявку на участие в конференции!
Осенью DotNext пройдет 18-21 октября, онлайн (гибридный формат решили отложить из-за непредсказуемости ввода ограничений на офлайн мероприятия).
Темы, которые ждут больше всего:
✔️ Internals;
✔️ Architecture;
✔️ Security;
✔️ Performance;
✔️ DevOps & Tools.
Но не ограничивайте себя этим списком — вы можете подать заявку с любой темой из области .NET-разработки.
Если все-таки сомневаетесь, то программный комитет всегда готов обсудить актуальность темы и помочь выбрать правильный вектор доклада. Плюс, ребята помогут с прокачкой ваших ораторских навыков, если у вас мало опыта в публичных выступлениях.
✅ Подать заявку и узнать подробности можно на сайте.
❓Вопросы присылайте на почту [email protected]
День восемьсот восемьдесят восьмой. #TypesAndLanguages
4. Проблема Алмаза. Начало
Проблема Алмаза, иногда называемая Смертельным Алмазом Смерти, возникает, когда мы наследуем одно и то же через несколько базовых сущностей. Если вы думаете, что «проблема есть в C++, но её не существует в Java или C#», то вы слишком сосредотачиваетесь на технической части.
Наследование
Обычно мы говорим, что в Java или C# существует одиночное наследование и множественная реализация интерфейсов. Это правда, но за этим скрывается гораздо более широкая картина.
Наследование позволяет наследовать характеристики и функции от базовой сущности (в большинстве случаев от класса или объекта). Есть много вещей, которые мы можем унаследовать, или много уровней наследования:
1. Наследование сигнатуры
В интерфейсе объявлен метод, мы наследуем его и предоставляем реализацию. Сигнатура здесь означает, что это только «заголовок» метода, без тела. Важно понимать, что эта «сигнатура наследования» не обязательно должна совпадать с «сигнатурой вызова». Например, вы не можете изменить тип возвращаемого значения при реализации интерфейса в C#, но тип возвращаемого значения не является частью «сигнатуры вызова». Java допускает это, но это детали реализации. Когда мы говорим о «наследовании сигнатуры», мы имеем в виду только заголовок метода, который мы получаем от базовой сущности.
2. Наследование реализации
При наследовании реализации мы получаем не только сигнатуру, но и всё тело метода. Это не так давно стало доступно в Java или C# через реализации интерфейса по умолчанию. Это можно рассматривать как типажи (traits). И хотя между наследованием реализации и трейтами есть некоторые различия, они довольно близки друг к другу.
3. Наследование состояния
Это наследование полей. При наследовании состояния мы получаем поле из базовой сущности, которое мы можем использовать в подклассе. В некоторой степени это похоже на примеси (mixins). Также стоит отметить, что у нас может быть наследование состояния без наследования реализации, но в большинстве случаев эти два аспекта объединяются.
4. Наследование идентичности
Можно считать «наследованием конструктора» (не вдаваясь в теорию типов). Разница между миксином и наследованием от класса сводится к конструктору. Вы можете создать экземпляр и получить новую идентичность. Обычно мы получаем идентичность, создавая базовую сущность и «удерживая» её внутри подобъекта.
Наследование в C# и Java
C++ имеет множественное наследование и не делает различий между классом и интерфейсом. В C# и Java запрещено всё, кроме наследования сигнатур. Однако важно понимать, что утверждение, что «в C# и Java не существует множественного наследования», неверно. Существует множественное наследование для сигнатур и одиночное наследование для всего остального.
Однако позже создатели языков поняли, что это может быть не лучшая идея, и была добавлена реализация интерфейса по умолчанию, которая по сути является «наследованием реализации».
Продолжение следует…
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
4. Проблема Алмаза. Начало
Проблема Алмаза, иногда называемая Смертельным Алмазом Смерти, возникает, когда мы наследуем одно и то же через несколько базовых сущностей. Если вы думаете, что «проблема есть в C++, но её не существует в Java или C#», то вы слишком сосредотачиваетесь на технической части.
Наследование
Обычно мы говорим, что в Java или C# существует одиночное наследование и множественная реализация интерфейсов. Это правда, но за этим скрывается гораздо более широкая картина.
Наследование позволяет наследовать характеристики и функции от базовой сущности (в большинстве случаев от класса или объекта). Есть много вещей, которые мы можем унаследовать, или много уровней наследования:
1. Наследование сигнатуры
В интерфейсе объявлен метод, мы наследуем его и предоставляем реализацию. Сигнатура здесь означает, что это только «заголовок» метода, без тела. Важно понимать, что эта «сигнатура наследования» не обязательно должна совпадать с «сигнатурой вызова». Например, вы не можете изменить тип возвращаемого значения при реализации интерфейса в C#, но тип возвращаемого значения не является частью «сигнатуры вызова». Java допускает это, но это детали реализации. Когда мы говорим о «наследовании сигнатуры», мы имеем в виду только заголовок метода, который мы получаем от базовой сущности.
2. Наследование реализации
При наследовании реализации мы получаем не только сигнатуру, но и всё тело метода. Это не так давно стало доступно в Java или C# через реализации интерфейса по умолчанию. Это можно рассматривать как типажи (traits). И хотя между наследованием реализации и трейтами есть некоторые различия, они довольно близки друг к другу.
3. Наследование состояния
Это наследование полей. При наследовании состояния мы получаем поле из базовой сущности, которое мы можем использовать в подклассе. В некоторой степени это похоже на примеси (mixins). Также стоит отметить, что у нас может быть наследование состояния без наследования реализации, но в большинстве случаев эти два аспекта объединяются.
4. Наследование идентичности
Можно считать «наследованием конструктора» (не вдаваясь в теорию типов). Разница между миксином и наследованием от класса сводится к конструктору. Вы можете создать экземпляр и получить новую идентичность. Обычно мы получаем идентичность, создавая базовую сущность и «удерживая» её внутри подобъекта.
Наследование в C# и Java
C++ имеет множественное наследование и не делает различий между классом и интерфейсом. В C# и Java запрещено всё, кроме наследования сигнатур. Однако важно понимать, что утверждение, что «в C# и Java не существует множественного наследования», неверно. Существует множественное наследование для сигнатур и одиночное наследование для всего остального.
Однако позже создатели языков поняли, что это может быть не лучшая идея, и была добавлена реализация интерфейса по умолчанию, которая по сути является «наследованием реализации».
Продолжение следует…
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
День восемьсот восемьдесят девятый. #TypesAndLanguages
4. Проблема Алмаза. Продолжение
Начало
Википедия определяет проблему алмаза как ситуацию, когда два класса B и C наследуются от класса A, переопределяют что-то, а затем класс D наследуется от классов B и C, не переопределяя член из A. Когда мы теперь хотим использовать член из A в классе D, мы не знаем, какой из них использовать (из B или из C).
Важно понимать, что это не имеет ничего общего с технической реализацией. Это логическая проблема (какой из членов выбрать), а не техническая.
Рассмотрим наследование сигнатуры:
Что же с реализацией интерфейса по умолчанию?
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
4. Проблема Алмаза. Продолжение
Начало
Википедия определяет проблему алмаза как ситуацию, когда два класса B и C наследуются от класса A, переопределяют что-то, а затем класс D наследуется от классов B и C, не переопределяя член из A. Когда мы теперь хотим использовать член из A в классе D, мы не знаем, какой из них использовать (из B или из C).
Важно понимать, что это не имеет ничего общего с технической реализацией. Это логическая проблема (какой из членов выбрать), а не техническая.
Рассмотрим наследование сигнатуры:
interface A {Здесь никаких проблем нет, поскольку сигнатуры одинаковые, и неважно, какую из них использовать. Но что, если мы изменим тип результата:
void foo();
}
interface B {
void foo();
}
class C : A, B {
public void foo(){
Console.WriteLine("FOO");
}
}
interface A {В Java это сработает, в C# компилятор выдаст ошибку, требуя реализации
object foo();
}
interface B {
string foo();
}
class C : A, B {
public string foo() {
return "Foo";
}
}
A.foo()
из-за другого типа результата. Здесь «Ситуация Алмаза» решается в Java, но является проблемой в C#.Что же с реализацией интерфейса по умолчанию?
interface A {Следующий код
void foo() => Console.WriteLine("A");
}
interface B {
void foo() => Console.WriteLine("B");
}
class C : A, B { }
C c = new C();Вызовет ошибку компиляции в обоих языках. В Java с сообщением, что интерфейсы
c.foo();
A
и B
несовместимы. В C#, что класс C
не содержит реализации метода foo
. Всё дело в том, что C# заставляет использовать явную реализацию, и выбор остаётся за клиентским кодом (нужно привести экземпляр класса к одному из интерфейсов):C c = new C();Окончание следует…
((A)c).foo();
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
День восемьсот девяностый. #TypesAndLanguages
4. Проблема Алмаза. Окончание
Начало
Продолжение
Так в чём же состоит Проблема Алмаза? Не в наследовании несовместимого, а в выборе, какой унаследованный член использовать. Ситуация усложняется, когда мы вводим состояние в базовый класс. Нам нужно решить, хотим ли мы иметь независимые состояния для каждого подкласса (обычное наследование) или разделять его между подклассами (виртуальное наследование). Если мы делимся состоянием, оно может легко сломаться (поскольку две разные реализации используют одни и те же переменные). Если нет, нам нужно указать, какие переменные мы имеем в виду в самом низком подклассе.
В C# и Java проблема решается ошибкой времени компиляции. Но в других языках есть другие решения, например в Scala приоритет получает член «крайнего правого» унаследованного класса.
Проблема Алмаза в Java и C# с первого дня
По сути Проблема Алмаза была в Java и C# с самого начала. Как мы уже говорили, проблема состоит в том, чтобы решить, какому из членов отдать приоритет. Например:
По сути, это та же Проблема Алмаза, что и раньше. У нас есть две вещи, и мы не можем решить, какую из них использовать. При реализациях интерфейса по умолчанию языки выдают ошибку компиляции, но при перегрузке метода они просто выбирают один метод вместо другого.
Это, кстати, может привести к нарушению совместимости. Представьте, что кто-то добавит ещё один метод
Итого
Хотя правильно сказать, что в Java и C# нет множественного наследования, лучше иметь в виду, что существует много уровней наследования, и мы должны быть конкретными. Мы можем унаследовать реализацию начиная с C# 8 — это множественное наследование или нет?
Хотя правильно сказать, что до 8 версии языка не было Проблемы Алмаза, по сути, проблема существует в перегрузке методов. И это имеет те же последствия.
Стоит помнить, как, казалось бы, совершенно разные языковые элементы приводят к аналогичным проблемам. Мы все «боимся» Проблемы Алмаза, но не боимся перегрузки методов. Более того, считаем что это классная функция, пока однажды не нарушим совместимость.
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
4. Проблема Алмаза. Окончание
Начало
Продолжение
Так в чём же состоит Проблема Алмаза? Не в наследовании несовместимого, а в выборе, какой унаследованный член использовать. Ситуация усложняется, когда мы вводим состояние в базовый класс. Нам нужно решить, хотим ли мы иметь независимые состояния для каждого подкласса (обычное наследование) или разделять его между подклассами (виртуальное наследование). Если мы делимся состоянием, оно может легко сломаться (поскольку две разные реализации используют одни и те же переменные). Если нет, нам нужно указать, какие переменные мы имеем в виду в самом низком подклассе.
В C# и Java проблема решается ошибкой времени компиляции. Но в других языках есть другие решения, например в Scala приоритет получает член «крайнего правого» унаследованного класса.
Проблема Алмаза в Java и C# с первого дня
По сути Проблема Алмаза была в Java и C# с самого начала. Как мы уже говорили, проблема состоит в том, чтобы решить, какому из членов отдать приоритет. Например:
class A {Что выведет следующий код?
public string foo(long l) => "Long";
public string foo(double d) => "Double";
}
A a = new A();У нас есть два метода с разными сигнатурами. Мы хотим вызвать метод и передать недопустимое значение - значение другого типа. Однако Java и C# достаточно «умны», и просто приводят значение к типу, который им больше нравится (в данном случае -
Console.WriteLine(a.foo(123));
long
).По сути, это та же Проблема Алмаза, что и раньше. У нас есть две вещи, и мы не можем решить, какую из них использовать. При реализациях интерфейса по умолчанию языки выдают ошибку компиляции, но при перегрузке метода они просто выбирают один метод вместо другого.
Это, кстати, может привести к нарушению совместимости. Представьте, что кто-то добавит ещё один метод
foo(int i)
. Что будет с вашим кодом? Раньше int
приводился к long
, но после добавления нового метода приведение не требуется, и будет вызван новый метод. Это нарушает совместимость.Итого
Хотя правильно сказать, что в Java и C# нет множественного наследования, лучше иметь в виду, что существует много уровней наследования, и мы должны быть конкретными. Мы можем унаследовать реализацию начиная с C# 8 — это множественное наследование или нет?
Хотя правильно сказать, что до 8 версии языка не было Проблемы Алмаза, по сути, проблема существует в перегрузке методов. И это имеет те же последствия.
Стоит помнить, как, казалось бы, совершенно разные языковые элементы приводят к аналогичным проблемам. Мы все «боимся» Проблемы Алмаза, но не боимся перегрузки методов. Более того, считаем что это классная функция, пока однажды не нарушим совместимость.
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
День восемьсот девяносто первый. #DesignPatterns #Microservices
Паттерны в Микросервисах
3. Разделение Ответственности Запросов и Команд (CQRS)
При использовании паттерна Источников Событий иногда чтение данных из хранилища событий становится затруднительным. Чтобы получить сущность из хранилища, нам нужно обработать все события сущности. Кроме того, иногда у нас разные требования к согласованности и пропускной способности для операций чтения и записи.
В таких случаях мы можем использовать шаблон CQRS. В шаблоне CQRS функционал изменения данных системы (Команды) отделён от функционала чтения данных (Запросов). Шаблон CQRS имеет две формы: простую и расширенную, что приводит к некоторой путанице среди разработчиков.
В своей простой форме для чтения и записи используется единое хранилище данных, но отдельные сущности или модели ORM, как показано в левой части рисунка ниже. Это помогает обеспечить соблюдение принципов единственной ответственности и разделения ответственности, что приводит к более чистому дизайну.
В расширенной форме (см. в правой части рисунка ниже) для операций чтения и записи используются разные хранилища данных. Расширенный CQRS используется с паттерном Источников Событий. В зависимости от реализации могут использоваться разные типы хранилищ для записи и для чтения. Хранилище для записи - это краеугольный камень всей системы.
Для приложений с интенсивным чтением или микросервисной архитектуры в качестве хранилища для записи используется база данных OLTP (любая база данных SQL или NoSQL, предлагающая гарантию транзакции ACID) или платформа распределённого обмена сообщениями. В приложениях с интенсивной записью (для высокой масштабируемости и пропускной способности записи) используется база данных с возможностью горизонтального масштабирования для записи (глобальные облачные базы данных). В хранилище для записи сохраняются нормализованные данные.
В качестве хранилища для чтения используется база данных NoSQL, оптимизированная для поиска (например, Apache Solr, Elasticsearch) или чтения (хранилище пар ключ-значение, хранилище документов). Во многих случаях, когда требуется SQL-запрос, используются масштабируемые для чтения базы данных SQL. В хранилище для чтения сохраняются денормализованные и оптимизированные данные.
Данные копируются из хранилища для записи в хранилище для чтения асинхронно. В результате хранилище чтения отстает от хранилища записи и имеет место Окончательная Согласованность (Eventual Consistency).
Плюсы
- Более быстрое чтение данных в микросервисах, управляемых событиями.
- Высокая доступность данных.
- Системы чтения и записи могут масштабироваться независимо.
Минусы
- Хранилище для чтения слабо согласовано (окончательная согласованность)
- Общая сложность системы увеличивается. Чрезмерная увлечённость CQRS может поставить под угрозу весь проект.
Когда использовать
- В высокомасштабируемой микросервисной архитектуре, где используется паттерн источников событий.
- В сложной модели предметной области, где для чтения данных требуется запрос в несколько хранилищ данных.
- В системах, где операции чтения и записи имеют разную нагрузку.
Когда не использовать
- В микросервисной архитектуре, где объём событий незначителен, создание моментального снимка хранилища событий для вычисления состояния объекта является лучшим выбором.
- В системах, где операции чтения и записи имеют одинаковую нагрузку.
Поддержка
Хранилища для Записи: EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, Amazon DynamoDB
Хранилища для Чтения: Elastic Search, Solr, Cloud Spanner, Amazon Aurora, Azure Cosmos DB, Neo4j
Фреймворки: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
Подробнее:
- CQRS
- Что такое шаблон CQRS?
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Паттерны в Микросервисах
3. Разделение Ответственности Запросов и Команд (CQRS)
При использовании паттерна Источников Событий иногда чтение данных из хранилища событий становится затруднительным. Чтобы получить сущность из хранилища, нам нужно обработать все события сущности. Кроме того, иногда у нас разные требования к согласованности и пропускной способности для операций чтения и записи.
В таких случаях мы можем использовать шаблон CQRS. В шаблоне CQRS функционал изменения данных системы (Команды) отделён от функционала чтения данных (Запросов). Шаблон CQRS имеет две формы: простую и расширенную, что приводит к некоторой путанице среди разработчиков.
В своей простой форме для чтения и записи используется единое хранилище данных, но отдельные сущности или модели ORM, как показано в левой части рисунка ниже. Это помогает обеспечить соблюдение принципов единственной ответственности и разделения ответственности, что приводит к более чистому дизайну.
В расширенной форме (см. в правой части рисунка ниже) для операций чтения и записи используются разные хранилища данных. Расширенный CQRS используется с паттерном Источников Событий. В зависимости от реализации могут использоваться разные типы хранилищ для записи и для чтения. Хранилище для записи - это краеугольный камень всей системы.
Для приложений с интенсивным чтением или микросервисной архитектуры в качестве хранилища для записи используется база данных OLTP (любая база данных SQL или NoSQL, предлагающая гарантию транзакции ACID) или платформа распределённого обмена сообщениями. В приложениях с интенсивной записью (для высокой масштабируемости и пропускной способности записи) используется база данных с возможностью горизонтального масштабирования для записи (глобальные облачные базы данных). В хранилище для записи сохраняются нормализованные данные.
В качестве хранилища для чтения используется база данных NoSQL, оптимизированная для поиска (например, Apache Solr, Elasticsearch) или чтения (хранилище пар ключ-значение, хранилище документов). Во многих случаях, когда требуется SQL-запрос, используются масштабируемые для чтения базы данных SQL. В хранилище для чтения сохраняются денормализованные и оптимизированные данные.
Данные копируются из хранилища для записи в хранилище для чтения асинхронно. В результате хранилище чтения отстает от хранилища записи и имеет место Окончательная Согласованность (Eventual Consistency).
Плюсы
- Более быстрое чтение данных в микросервисах, управляемых событиями.
- Высокая доступность данных.
- Системы чтения и записи могут масштабироваться независимо.
Минусы
- Хранилище для чтения слабо согласовано (окончательная согласованность)
- Общая сложность системы увеличивается. Чрезмерная увлечённость CQRS может поставить под угрозу весь проект.
Когда использовать
- В высокомасштабируемой микросервисной архитектуре, где используется паттерн источников событий.
- В сложной модели предметной области, где для чтения данных требуется запрос в несколько хранилищ данных.
- В системах, где операции чтения и записи имеют разную нагрузку.
Когда не использовать
- В микросервисной архитектуре, где объём событий незначителен, создание моментального снимка хранилища событий для вычисления состояния объекта является лучшим выбором.
- В системах, где операции чтения и записи имеют одинаковую нагрузку.
Поддержка
Хранилища для Записи: EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, Amazon DynamoDB
Хранилища для Чтения: Elastic Search, Solr, Cloud Spanner, Amazon Aurora, Azure Cosmos DB, Neo4j
Фреймворки: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
Подробнее:
- CQRS
- Что такое шаблон CQRS?
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍1
День восемьсот девяносто второй. #ЧтоНовенького
GitHub и OpenAI Запускают Новую Утилиту, Которая Генерирует Код за Вас
GitHub и OpenAI запустили предварительную техническую версию нового инструмента с искусственным интеллектом под названием Copilot, который находится внутри редактора кода Visual Studio и автоматически генерирует фрагменты кода.
Согласно GitHub, Copilot делает больше, чем просто выдаёт код, который где-то видел раньше. Вместо этого он анализирует код, который вы уже написали, и генерирует новый соответствующий код, включая определённые функции, которые ранее использовались. На веб-сайте проекта выложено несколько примеров популярных блоков кода, которые программистам приходится писать раз за разом, вроде получения ответа от API, нахождения количества дней между датами, и даже написания юнит-тестов.
Пока Copilot работает на Python, JavaScript, TypeScript, Ruby и Go.
GitHub рассматривает это как эволюцию парного программирования, когда два программиста работают над одним и тем же проектом, чтобы выявлять ошибки друг друга и ускорять процесс разработки. В Copilot один из этих программистов является виртуальным.
Этот проект - первый крупный результат инвестиций Microsoft в OpenAI, исследовательскую фирму, которую возглавляет Сэм Альтман. С тех пор как Альтман взял бразды правления, OpenAI перешёл от некоммерческого статуса к модели «с ограничением прибыли», принял инвестиции от Microsoft и начал лицензировать свой алгоритм генерации текста GPT-3.
GPT-3 - это флагманский алгоритм генерации текстов от OpenAI, который может генерировать текст, иногда неотличимый от человеческого языка. Он это делает так убедительно из-за огромного массива в 175 миллиардов параметров настройки, которые позволяют алгоритму связывать отношения между буквами, словами, фразами и предложениями.
Copilot построен на новом алгоритме под названием OpenAI Codex, который технический директор OpenAI Грег Брокман описывает как потомка GPT-3. GPT-3 генерирует английский текст, а Codex генерирует код. OpenAI планирует выпустить версию Codex в своём API этим летом, чтобы разработчики могли создавать свои собственные приложения с использованием этой технологии.
Codex был обучен на терабайтах открыто кода, взятого с GitHub, а также на примерах на английском языке. Разработчики говорят, что предложенные варианты кода были верны в 43% случаев с первого раза и в 57% случаев, когда алгоритму давалось до 10 попыток. При этом алгоритм будет становиться умнее со временем.
Хотя первые пользователи на сайте восторженно отзываются о росте продуктивности, который обеспечивает Copilot, GitHub подразумевает, что не весь используемый код был проверен на наличие ошибок, небезопасных действий или защиты личных данных. Компания пишет, что они установили несколько фильтров, чтобы Copilot не генерировал оскорбительные выражения, но фильтры могут быть не идеальны.
Компания также предупреждает, что модель может предлагать адреса электронной почты, ключи API или номера телефонов, но это происходит редко, и эти данные были скорее всего синтетические или псевдослучайно сгенерированные алгоритмом. При этом код, созданный Copilot, во многом оригинален. Тест, проведенный GitHub, показал, что только 0,1% сгенерированного кода можно было точно найти в обучающем наборе.
Прямо сейчас Copilot находится в ограниченной предварительной технической версии, но вы можете зарегистрироваться на веб-сайте проекта, чтобы получить к нему доступ.
Источник: https://www.theverge.com/2021/6/29/22555777/github-openai-ai-tool-autocomplete-code
GitHub и OpenAI Запускают Новую Утилиту, Которая Генерирует Код за Вас
GitHub и OpenAI запустили предварительную техническую версию нового инструмента с искусственным интеллектом под названием Copilot, который находится внутри редактора кода Visual Studio и автоматически генерирует фрагменты кода.
Согласно GitHub, Copilot делает больше, чем просто выдаёт код, который где-то видел раньше. Вместо этого он анализирует код, который вы уже написали, и генерирует новый соответствующий код, включая определённые функции, которые ранее использовались. На веб-сайте проекта выложено несколько примеров популярных блоков кода, которые программистам приходится писать раз за разом, вроде получения ответа от API, нахождения количества дней между датами, и даже написания юнит-тестов.
Пока Copilot работает на Python, JavaScript, TypeScript, Ruby и Go.
GitHub рассматривает это как эволюцию парного программирования, когда два программиста работают над одним и тем же проектом, чтобы выявлять ошибки друг друга и ускорять процесс разработки. В Copilot один из этих программистов является виртуальным.
Этот проект - первый крупный результат инвестиций Microsoft в OpenAI, исследовательскую фирму, которую возглавляет Сэм Альтман. С тех пор как Альтман взял бразды правления, OpenAI перешёл от некоммерческого статуса к модели «с ограничением прибыли», принял инвестиции от Microsoft и начал лицензировать свой алгоритм генерации текста GPT-3.
GPT-3 - это флагманский алгоритм генерации текстов от OpenAI, который может генерировать текст, иногда неотличимый от человеческого языка. Он это делает так убедительно из-за огромного массива в 175 миллиардов параметров настройки, которые позволяют алгоритму связывать отношения между буквами, словами, фразами и предложениями.
Copilot построен на новом алгоритме под названием OpenAI Codex, который технический директор OpenAI Грег Брокман описывает как потомка GPT-3. GPT-3 генерирует английский текст, а Codex генерирует код. OpenAI планирует выпустить версию Codex в своём API этим летом, чтобы разработчики могли создавать свои собственные приложения с использованием этой технологии.
Codex был обучен на терабайтах открыто кода, взятого с GitHub, а также на примерах на английском языке. Разработчики говорят, что предложенные варианты кода были верны в 43% случаев с первого раза и в 57% случаев, когда алгоритму давалось до 10 попыток. При этом алгоритм будет становиться умнее со временем.
Хотя первые пользователи на сайте восторженно отзываются о росте продуктивности, который обеспечивает Copilot, GitHub подразумевает, что не весь используемый код был проверен на наличие ошибок, небезопасных действий или защиты личных данных. Компания пишет, что они установили несколько фильтров, чтобы Copilot не генерировал оскорбительные выражения, но фильтры могут быть не идеальны.
Компания также предупреждает, что модель может предлагать адреса электронной почты, ключи API или номера телефонов, но это происходит редко, и эти данные были скорее всего синтетические или псевдослучайно сгенерированные алгоритмом. При этом код, созданный Copilot, во многом оригинален. Тест, проведенный GitHub, показал, что только 0,1% сгенерированного кода можно было точно найти в обучающем наборе.
Прямо сейчас Copilot находится в ограниченной предварительной технической версии, но вы можете зарегистрироваться на веб-сайте проекта, чтобы получить к нему доступ.
Источник: https://www.theverge.com/2021/6/29/22555777/github-openai-ai-tool-autocomplete-code