.NET Разработчик
6.51K subscribers
427 photos
2 videos
14 files
2.04K links
Дневник сертифицированного .NET разработчика.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День 1659. #МоиИнструменты
Веб-Инструменты для Каждого Разработчика
Сегодня поделюсь с вами подборкой веб-сайтов с инструментами, которые пригодятся каждому разработчику вне зависимости от области и языка программирования.

1. Transform.tools
Позволяет преобразовывать почти всё, например, HTML в JSX, JavaScript в JSON, CSS в объекты JS и многое другое. Действительно экономит время. К сожалению, отсутствует поддержка C#, поэтому JSON можно преобразовать разве что в объект Java, но с парочкой изменений руками (когда уже в Java человеческие свойства завезут?) потянет.

2. Convertio
Простой инструмент для конвертации файлов онлайн. Более 309 различных документов, изображений, электронных таблиц, электронных книг, архивов, презентаций, аудио и видео форматов. Например, PNG в JPEG, SVG в PNG, PNG в ICO и многие другие. Попробовал конвертнуть PDF книгу в DOCX. Очень даже неплохо. У бесплатной версии есть ограничение на общее время конвертации в день, но сколько это, я не нашёл. Думаю, для конвертации парочки файлов время от времени хватит.

3. Code Beautify
Онлайн версия программ Code Beautifier и Code Formatter, позволяющая форматировать исходный код. Но, кроме этого, также поддерживает некоторые преобразователи, такие как изображение в base64, CSV в Excel и т.п., минификаторы и обфускаторы кода для многих языков и много чего ещё.

4. Removebg
Мы программисты чаще всего плохо умеем в фотошоп, поэтому ловите инструмент, который позволяет легко удалить фон любого изображения. RemoveBG мгновенно определяет объект изображения и удаляет фон, оставляя изображение объекта на прозрачном фоне, которое вы можете легко использовать в своих проектах. Я попробовал его на паре фоток и должен отметить, что работает отлично. Потом результат можно перенести визуальный редактор canva.com и добавить фон, эффекты и даже создать видео.

5. ray.so
ray.so преобразует ваш фрагмент кода в визуально привлекательное изображение в пару кликов! Вы можете настроить иллюстрацию, выбрав из множества подсветок синтаксиса, добавить фон или выбрать тёмную или светлую тему. Это идеальный способ продемонстрировать свой код в посте или презентации по-настоящему стильно.

Источник: https://dev.to/j471n/top-10-websites-every-developer-needs-to-know-about-f5j
👍19👎1
День 1660. #ЗаметкиНаПолях
Неявные Операторы — Секрет Чистого Кода или Источник Ошибок?
Неявные операторы — мощная функция языка C#, которая позволяет сделать код более читаемым и выразительным. Они позволяют определять пользовательские преобразования, которые происходят без явного приведения, и, таким образом, устранять неуклюжий синтаксис.

Неявные операторы определяются с помощью ключевого слова implicit и могут использоваться для создания метода, преобразующего один тип в другой:
public readonly record struct Money
{
public decimal Amount { get; init; }

public static implicit operator Money(
decimal amount)
{
return new Money { Amount = amount };
}

public static implicit operator decimal(
Money money)
{
return money.Amount;
}
}

// Использование
Money money = 10.0m;
decimal amount = money;

Здесь мы определили неявный оператор, который позволяет нам преобразовать значение double в объект Money и наоборот. Компилятор автоматически применяет оператор, когда это необходимо. Согласитесь, код использования выше выглядит проще и понятнее, чем
Money m = new Money(10.0m);
decimal amount = m.Amount;

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

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

Однако чрезмерное использование неявных операторов может привести к тому, что код будет труден для понимания и сопровождения. Одной из основных вещей, которых следует избегать, является создание неявных операторов, которые могут привести к потере данных или вызвать исключения. Поскольку неявные операторы применяются компилятором автоматически, любые исключения, которые они вызывают, может быть трудно отследить. Например, когда у нас возникает исключение InvalidCastException из-за неправильной операции преобразования типа, мы привыкли видеть строку кода с явной операцией приведения: мы видим в скобках тип, в который пытаемся преобразовать, применяемый к переменной или значению, и сразу знаем, что существует какая-то несовместимость, о чем свидетельствует исключение, указывающее на этот номер строки. С неявными операторами преобразование происходит «волшебным образом, под капотом». Поэтому, если в результате выполнения оператора возникает какая-либо ошибка, нам нужно не только сделать паузу, чтобы понять, что применяется неявный оператор (например, «Секундочку, как может double присваиваться к этому типу, который не является double?!»). Придётся также изучить код этого типа (будем надеяться, что у нас есть его исходный код!), а затем диагностировать, что не так с логикой.

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

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

Источник: https://www.devleader.ca/2023/08/04/implicit-operators-clean-code-secrets-or-buggy-nightmare/
👍16
День 1661. #PostgresTips
Советы по Postgres для Начинающих

6. Используйте ветки БД для разработки
Процесс разработки и тестирования в базах данных часто требует копии базы, что может быть ресурсоёмким, медленным и громоздким. Однако тонкое клонирование и ветвление БД предоставляют более удобный способ.

Что такое тонкое клонирование?
Инструменты тонкого клонирования обеспечивают легковесные, доступные для записи клоны вашей базы данных. Эти клоны используют те же базовые блоки данных, что и источник, но отображаются для пользователя как независимые базы данных. Когда в клон вносятся изменения, только эти изменения потребляют дополнительное место на диске — это достигается с помощью копирования при записи (copy-on-write, CoW), аналогично тому, что есть в контейнерах или Git, но на уровне блоков, а не на уровне файлов. Это позволяет невероятно быстро и эффективно создавать несколько копий для разработки, тестирования или анализа.

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

Database Lab
Такие инструменты, как Database Lab (DBLab), предоставляют мощные возможности тонкого клонирования и ветвления. Более того, в сочетании с решениями ИИ, такими как ChatGPT, разработчики могут даже получать мгновенные результаты своих экспериментов с SQL-запросами, не влияя на производственную среду или работу коллег. У ChatGPT часто возникают проблемы с «галлюцинациями», и всегда важно проверять советы, сгенерированные ИИ, на клоне базы данных. Ветвление даёт наиболее эффективный с точки зрения затрат и времени способ сделать это.

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

Самый быстрый способ начать работу с тонкими клонами и ветвлением БД — установить DBLab SE в несколько кликов с помощью консоли Postgres.ai (поддерживаются: AWS, GCP, DigitalOcean и Hetzner Cloud, а также любые другие локации, в том числе on-premise).

Источник: https://postgres.ai/blog/20230722-10-postgres-tips-for-beginners
👍9👎2
День 1662. #Карьера
Управляем Вверх: Руководство Разработчика по Карьерному Росту
Управление «вверх» (Managing up), по сути, является стратегией активной работы с вашим начальством для достижения общих целей. Речь идет о понимании ожиданий вашего руководителя, согласовании их с вашими целями и обеспечении того, чтобы вы оба слаженно работали над достижением общих побед. Для разработчиков это означает нечто большее, чем просто достижение целей спринта; это стремление продемонстрировать свою ценность и помочь вашему менеджеру добиться успеха в своей роли.

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

2. Инициатива: вы обнаружили технический долг, который замедляет работу команды. Вместо того, чтобы ждать ежегодной проверки, чтобы обсудить его, назначьте встречу со своим руководителем, чтобы представить проблему и возможные решения.

3. Цикл обратной связи: после завершения проекта попросите своего руководителя оставить отзыв, демонстрируя своё стремление расти и соответствовать ожиданиям команды.

Советы и рекомендации
1. Поймите цели руководителя: узнайте, что движет вашим менеджером. Чего от него ожидает его начальство? Есть ли у него определённые KPI, которых нужно достичь? Поняв это, вы можете согласовать свой вклад, чтобы напрямую повлиять на его успех. В конце концов, какую бы роль вы ни занимали, ваша работа в основном состоит в том, чтобы ваш босс выглядел хорошо. Если у вас есть возможность взаимодействовать с людьми ещё на уровень выше, вы можете применить тот же принцип и к ним.

2. Регулярно отчитывайтесь: не ждите плановых обзоров продуктивности. Организуйте короткие регулярные «проверки связи», чтобы обсудить прогресс, проблемы и получить отзыв. Это помогает в построении отношений доверия и прозрачности. Не заставляйте своего менеджера запрашивать у вас отчёты о статусе — еженедельно отправляйте электронное письмо с кратким изложением того, что вы сделали. Это отличный способ держать его в курсе, а также напоминать о вашем вкладе. Кроме того, такие регулярные отчёты очень пригодятся во время планового обзора продуктивности.

3. Будьте ориентированы на решение: одно дело — определить проблему, а другое — предложить решение. При обсуждении проблем всегда старайтесь предлагать возможные решения, даже если это решения, которые вы не в состоянии реализовать. Это демонстрирует вашу инициативу и умение решать проблемы.

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

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

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

Источник: https://ardalis.com/managing-up-developers-guide-career-advancement/
👍9
День 1663.
Результаты розыгрыша онлайн-билета на DotNext 2023

Победителя я определил простым рандомом из всех прокомментировавших исходный пост. Весь процесс в видео в первом комментарии.

Победил Stas Horoshavcev, поздравляю! В скором времени с вами свяжутся представители конференции и передадут билет.

Для всех остальных промокод канала netdeveloper поможет купить билет «Для частных лиц» со скидкой. Также билет на конференцию вам может оплатить работодатель.

Я лично буду на конференции офлайн. Если тоже будете, можем пересечься.

Узнать подробности о DotNext 2023, почитать программу и купить билеты можно на сайте.
👍5
День 1664. #ЧтоНовенького
Конкурентный Запуск и Остановка Hosted-Сервисов в .NET 8
Библиотека Microsoft.Extensions.Hosting, используемая как в шаблоне проекта ASP.NET Core, так и в шаблоне Worker Service, обеспечивает возможность запуска долго работающего консольного приложения. В .NET 8 в ней появилась новая функциональность, влияющая на размещённые (hosted) сервисы.

В ASP.NET Core приложение запускает веб-сервер Kestrel и работает до тех пор, пока процесс не будет остановлен. Шаблон Worker Service идеально подходит для создания легковесных приложений обработки, которые работают постоянно. Например, это могут быть микросервисы, которые запрашивают сообщения из очереди и обрабатывают их.

Размещённые сервисы — это фоновые задачи, запускаемые хостом, которые выполняют работу приложения. Приложения могут определять один или несколько размещённых сервисов, регистрируя реализацию интерфейса IHostedService в DI-контейнере. Microsoft предоставляет общую реализацию этого интерфейса в абстрактном классе BackgroundService. Разработчики наследуют от этого класса и предоставляют реализацию абстрактного метода ExecuteAsync. Когда платформа размещения запускается, она запускает задачу, определённую в методе ExecuteAsync.

До .NET 8 код, который запускает и останавливает размещённые сервисы, делал это последовательно. Каждый IHostedService запускался последовательно через ожидание вызова StartAsync экземпляра. Т.е. каждая задача StartAsync должна была быть завершена до запуска следующей. Это не оказывало существенного влияния на большинство приложений, но это поведение по умолчанию всё же может вызывать проблемы. Несмотря на то, что внутри StartAsync рекомендуется выполнять небольшую работу, медленный размещённая сервис может задерживать запуск оставшейся части приложения.

При остановке приложений сервисы так же останавливались в обратном порядке через ожидание StopAsync. Это может быть более проблематичным, т.к. настроен тайм-аут (ShutdownTimeout), ограничивающий продолжительность корректного завершения работы. Т.е. тайм-аут должен учитывать время, необходимое для корректного закрытия всех размещённых сервисов. В некоторых ситуациях при сбросе текущих незавершённых работ это может привести к тому, что некоторые сервисы будут использовать большую часть тайм-аута.

В .NET 8 добавлены две новые опции, которые позволяют переключаться на параллельный запуск и/или остановку:
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(svc =>
{
svc.Configure<HostOptions>(o =>
{
o.ServicesStartConcurrently = true;
o.ServicesStopConcurrently = true;
});

svc.AddHostedService<WorkerOne>();
svc.AddHostedService<WorkerTwo>();
})
.Build();

В примере выше регистрируются два размещённых сервиса, которые будут запускаться и останавливаться одновременно, не задерживая друг друга. Внутри .NET это достигается путём добавления всех сервисов в группу задач и ожидания завершения этой группы через Task.WhenAll. Для конкурентного останова это позволяет каждому размещённому сервису завершить свою работу в течение всего времени тайм-аута.

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

Источник: https://www.stevejgordon.co.uk/concurrent-hosted-service-start-and-stop-in-dotnet-8
👍20
День 1665. #ЧтоНовенького
Новый Интерфейс IHostedLifecycleService в .NET 8
Вчера я писал про конкурентный запуск и остановку hosted-сервисов в .NET 8, однако этим нововведения для размещённых сервисов не ограничиваются.

В пространство имён Microsoft.Extensions.Hosting добавлен интерфейс IHostedLifecycleService. Он наследуется от IHostedService, расширяя его методами для новых событий жизненного цикла, которые происходят до или после существующих методов StartAsync и StopAsync соответственно:
- StartingAsync,
- StartedAsync,
- StoppingAsync,
- StoppedAsync.

Метод StartingAsync будет выполняться очень рано в жизненном цикле приложения, прежде чем StartAsync будет вызван для любого зарегистрированного размещённого сервиса. Это может использоваться для выполнения некоторых очень ранних проверок перед запуском приложения, таких как проверка критических требований или наличия зависимостей. Это позволит приложению потенциально завершаться сбоем при запуске до того, как какие-либо размещённые сервисы начнут выполнять свою основную рабочую нагрузку. Другие варианты использования включают «предварительный нагрев» и инициализацию синглтонов и других состояний, используемых приложением.

StartedAsync будет вызываться в реализациях после завершения всех методов StartAsync для зарегистрированных размещённых сервисов. Его можно использовать для проверки состояния или условий приложения непосредственно перед пометкой приложения как успешно запущенного.

StoppingAsync и StoppedAsync работают аналогично во время завершения работы приложения и предоставляют расширенные перехватчики для проверок до и после завершения работы.

Кроме того, в HostOptions добавлена новая опция StartupTimeout, позволяющая предоставить TimeSpan, который будет контролировать максимальное время, разрешённое для запуска всех размещённых сервисов. При установке в небесконечное (по умолчанию) значение токен отмены, передаваемый в события жизненного цикла запуска, будет отменяться по заданному тайм-ауту.

Использование интерфейса
Довольно распространённая работа перед запуском приложения — инициализация БД. В таких средах, как CI, нам может потребоваться создавать фиктивную БД и заполнить её тестовыми данными. Одним из возможных вариантов решения является использование размещённых сервисов. В .NET 8, если сервисы запускаются конкурентно, может возникнуть проблема, когда один сервис зависит от результатов работы другого (например, от наличия инициализированной БД). Поэтому мы можем использовать IHostedLifecycleService, чтобы инициализировать базу до того, как она будет использована каким-либо другим сервисом:
public class ServiceA : IHostedService,
IHostedLifecycleService
{
public Task StartingAsync(CancellationToken ct)
{
// инициализация БД
return Task.CompletedTask;
}

// реализация других методов
}

public class ServiceB : BackgroundService
{
protected override Task ExecuteAsync(
CancellationToken stoppingToken)
{
// использование БД
return Task.CompletedTask;
}
}

Здесь ServiceA реализует IHostedLifecycleService и инициализирует БД на самом раннем этапе жизненного цикла приложения, до любой из основных рабочих нагрузок. ServiceB, производный от BackgroundService, теперь может безопасно использовать БД, т.к. ExecuteAsync вызывается базовой реализацией StartAsync. Т.е. он не вызывается до тех пор, пока не будут завершены все методы StartingAsync для зарегистрированных сервисов. Также теперь не имеет значения, в каком порядке сервисы регистрируются в DI-контейнере:
builder.Services.AddHostedService<ServiceB>();
builder.Services.AddHostedService<ServiceA>();

Источник: https://www.stevejgordon.co.uk/introducing-the-new-ihostedlifecycleservice-interface-in-dotnet-8
👍13
День 1666. #ВопросыНаСобеседовании
Самые часто задаваемые вопросы на собеседовании по C#

21. Что такое слабые ссылки и когда их использовать в C#?
В C# слабые ссылки — это ссылки на объекты, которые недостаточно надёжны, чтобы предотвратить сборку мусора для этих объектов. Они позволяют поддерживать ссылку на объект до тех пор, пока объект жив в памяти, но не препятствуя сборщику мусора (GC) освобождать объект при увеличении нагрузки на память. Со слабыми ссылками вы можете получить доступ к объекту, пока он всё ещё находится в памяти, но это не помешает GC удалить объект, если это необходимо.

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

Чтобы использовать слабую ссылку в C#, создайте экземпляр класса WeakReference или WeakReference<T>:
WeakReference<MyLargeObject> wr 
= new(new MyLargeObject());

MyLargeObject lo;
if (wr.TryGetTarget(out largeObject))
{
// объект всё ещё в памяти, используем его
Console.WriteLine("Используем объект.");
}
else
{
// объект удалён сборщиком мусора
Console.WriteLine("Объект удалён.");
largeObject = new MyLargeObject();
}

class MyLargeObject
{
private byte[] _data = new byte[1000000];
}

В этом примере, если GC решит освободить память, используемую экземпляром MyLargeObject, вызов weakReference.TryGetTarget возвратит значение false. В противном случае largeObject останется доступным через слабую ссылку.

Источник: https://dev.to/bytehide/20-senior-developer-c-interview-questions-and-answers-2023-3bjc
👍42
День 1667. #ЗаметкиНаПолях #Debugging
Отладка с Разных Точек Зрения
Отладка — это процесс выявления основной причины ошибки и её исправления.

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

Мышление
Кэрол Дуэк, известный психолог, представила концепции «мышления на рост» и «фиксированного мышления». Люди с мышлением на рост считают, что их способности и интеллект можно развить с помощью усилий, обучения и настойчивости. Люди с фиксированным мышлением считают, что их качества являются врождёнными и неизменными, что приводит к страху неудачи и нежеланию принимать вызовы. Дуэк подчёркивает важность воспитания мышления на рост для повышения устойчивости, обучения и личного развития.

Прежде чем приступить к отладке, важно принять соответствующий образ мышления. Это влечёт за собой отказ от защиты своего эго, игнорирование любого давления проекта и обеспечение личного комфорта. Помните первое правило отладки: НЕ ПАНИКУЙТЕ.

Это возможность
Отладку следует воспринимать как ценную возможность:
- Лучше понять программу, над которой вы работаете.
- Распознать типы ошибок, которые вы обычно совершаете.
- Оценить качество вашего кода с точки зрения того, кто должен его читать и понимать.
- Узнать, как вы подходите к решению проблем.

Правильное отношение
При правильном отношении отладка может быть весёлой, как решение головоломки. Вот некоторые ключевые аспекты правильного отношения к эффективной отладке:
- Любознательность: будьте готовы исследовать и понять основную причину проблемы.
- Терпение: отладка может занять много времени. Будьте терпеливы и настойчивы.
- Открытость к обучению: рассматривайте отладку как возможность учиться и улучшать свои навыки.
- Смирение: признайте, что все совершают ошибки. Отладка — это поиск и исправление этих ошибок, а не отражение вашей ценности или интеллекта.
- Системный подход: используйте системный подход для выявления и изоляции проблемы. Избегайте поспешных предположений и тщательно исследуйте код или систему.
- Сотрудничество: не стесняйтесь обращаться за помощью.
- Внимание к деталям: обратите внимание на мельчайшие детали, поскольку они часто могут содержать ключ к разгадке источника проблемы.
- Оптимизм: вера в свою способность успешно решить проблему может помочь сохранить концентрацию и мотивацию.
- Документация: отслеживайте процесс отладки, предпринятые шаги и решения. Эта документация может оказаться полезной для будущих справок и обучения.

Отладка в два раза сложнее, чем написание кода. Следовательно, если вы пишете код максимально умно, вы по определению недостаточно умны, чтобы его отлаживать.
Брайан В. Керниган

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

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

Источник: https://dev.to/rajasegar/debugging-from-different-viewpoints-46k0
👍4👎1
Свойства A и B эквивалентны?
public class MyClass
{ public int A { get; } = Random.Shared.Next(1000); public int B => Random.Shared.Next(1000); }
Anonymous Quiz
25%
да
75%
нет
👍14
День 1668. #ЗаметкиНаПолях
Используем Секреты в Юнит-Тестах
Хотя большинство юнит-тестов должны соответствовать характеристикам FIRST и быть «изолированными» путём имитации их зависимостей, бывают случаи, когда может быть полезно фактически подключиться к внешнему ресурсу, и использовать средство запуска модульных тестов для проверки вашего кода на «реальной» зависимости. По сути, такие тесты являются интеграционными, но не будем сейчас углубляться в терминологию.

Допустим, вам нужна строка подключения к базе данных или другому внешнему ресурсу. Но вы не хотите включать её в код, поскольку все мы знаем, что секретам не место в системе контроля версий. Конечно, очевидным решением было бы получить доступ к строке подключения как к переменной среды, но Visual Studio Test Explorer (по крайней мере, насколько я могу судить) не предлагает простого способа установки переменных среды для запуска тестов. Существует файл .runsettings, но он страдает от точно такой же проблемы — в конечном итоге вам придётся добавить секреты в систему контроля версий.

К счастью, функция пользовательских секретов .NET может помочь нам в этом. И хотя во многих статьях о ней предполагается, что вы используете ASP.NET Core, вы можете использовать пользовательские секреты .NET в любом типе проекта, включая тестовую сборку.

Всё довольно просто. Сначала в командной строке в каталоге проекта модульного тестирования введите команду
init dotnet user-secrets
Это добавит GUID UserSecretsId в ваш файл .csproj.

Затем вы можете сохранить свой секрет с помощью команды user-secrets set, например:
dotnet user-secrets set MyConnectionString "my-connection-string"

Чтобы получить секретное значение в модульном тесте, просто используйте ConfigurationBuilder и вызовите AddUserSecrets, используя любой класс из вашей сборки в качестве аргумента типа. Затем вы сможете получить доступ к секретам по имени в экземпляре конфигурации и получите значение null, если секрет отсутствует.
using Microsoft.Extensions.Configuration;
// ...

var config = new ConfigurationBuilder()
.AddUserSecrets<MyUnitTests>()
.Build();
var connectionString = config["MyConnectionString"];

Заметьте, что для этого вам понадобится установить NuGet-пакет Microsoft.Extensions.Configuration.UserSecrets.

Если вы запускаете тесты в конвейере CI/CD, можно использовать переменные среды машины, на которой запущен конвейер. Просто добавьте вызов .AddEnvironmentVariables() в ConfigurationBuilder.

Источник: https://markheath.net/post/use-secrets-in-unit-tests
👍17
День 1669.
Сертификат Microsoft. Доступ к Microsoft Learn
Microsoft добавили возможность открывать и исследовать портал Microsoft Learn во время сдачи сертификационных экзаменов. Этот ресурс будет доступен для всех ролевых и специализированных экзаменов на всех языках к середине сентября.

В повседневной жизни и работе нам часто нужно посмотреть что-то, что мы могли забыть или в чём мы не уверены. Теперь это возможно и при сдаче экзамена на сертификат Microsoft. В Microsoft расценивают портал, как вспомогательный ресурс, очень похожий на калькулятор. Поэтому предоставляют к нему доступ, однако время экзамена при этом не будет увеличено. Вопросы останутся прежними, они будут сконцентрированы на жизненных проблемах или сценариях, для решения которых требуется реальный опыт. В результате этот ресурс предназначен для ответов на вопросы, описывающих проблемы, для решения которых вам может потребоваться что-то поискать в Microsoft Learn. Использовать ресурс, чтобы ответить на все вопросы, не получится.

Вот некоторые детали:
- У вас будет доступ ко всему домену Learn.microsoft.com, кроме секции вопросов и ответов и вашего профиля (вы не сможете войти в систему).
- Время экзамена не будет добавлено. Таймер экзамена продолжит идти, пока вы будете искать в «Learn» необходимую вам информацию.
- Ресурс будет доступен только для ролевых экзаменов, но не для экзаменов по основам.
- Ресурс будет доступен на тех же языках, на которых доступен экзамен.

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

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

Поэтому, если вы хотели сдать сертификационный экзамен Microsoft, но не решались из-за боязни не вспомнить какие-нибудь детали, теперь этот барьер убран. По-моему, это отличное решение, особенно если готовиться к экзамену, используя сам портал Microsoft Learn, и хорошенько его изучить.

Источник: https://techcommunity.microsoft.com/t5/microsoft-learn-blog/introducing-a-new-resource-for-all-role-based-microsoft/ba-p/3500870
👍10
День 1670. #ЗаметкиНаПолях
Неожиданное Поведение Enum.TryParse
Перечисления — это очень простые структуры, но некоторые функции, такие как Enum.TryParse, могут вести себя неожиданно. Сегодня рассмотрим, в чём дело, и как это исправить.

Enum.TryParse «преобразует строковое представление имени или числового значения одной или нескольких перечислимых констант в эквивалентный перечислимый объект. Возвращаемое значение указывает, удалось ли преобразование».

Итак, если у нас есть такое перечисление:
public enum Weekend
{
Saturday = 0,
Sunday = 1
}

И мы вызываем функцию:
var couldParse = 
Enum.TryParse("1", out Weekend day);

Console.WriteLine($"Удача: {couldParse}");
Console.WriteLine($"Значение: {day}");

//Вывод:
Удача: True
Значение: Sunday

Пока всё нормально, но вот что интересно. Если вы укажете значение, которое не является частью перечисления, это всё равно будет работать:
var couldParse = 
Enum.TryParse("3", out Weekend day);

//Вывод:
Удача: True
Значение: 3

И хотя «Значение: 3» может иметь смысл, так как вы также можете делать вещи, вроде
var myValue = (WeekendDay)3;
кажется странным, что функция возвращает true и сообщает, что смогла без проблем преобразовать аргумент.

Что делать?
Используйте Enum.IsDefined, чтобы проверить, находится ли данное значение в правильном диапазоне. С помощью Enum.IsDefined мы можем проверить, правильно ли значение для данного перечисления.
var couldParse = 
Enum.TryParse("3", out Weekend day);
if (couldParse
&& Enum.IsDefined(typeof(Weekend), day))
{
// Только здесь мы уверены в
// корректности значения Weekend
}

Источник: https://steven-giesel.com/blogPost/64d479f1-823f-4fc7-a56a-2b1ff06dcf72
👍50
День 1671. #ЗаметкиНаПолях
Атрибуты From… в .NET Web API. Начало
Несмотря на то, что ASP.NET «из коробки» неплохо справляется с привязкой параметров методов действий контроллеров или свойств модели, мы можем детально контролировать, откуда мы хотим получить тот или иной параметр или свойство с помощью атрибутов [From<…>].

1. FromQuery
Атрибут FromQuery используется для получения параметра из строки запроса. Мы можем добавить атрибут FromQuery к параметру метода действия, и по умолчанию он будет сопоставлять имя параметра метода с соответствующим именем параметра строки запроса.

В примере ниже, если мы выполним запрос GET к /api/from-api/from-query?page=4, параметр page получит значение 4, и это значение будет возвращено как часть ответа:
[ApiController]
[Route("api/from-api")]
public class FromApiController : Controller
{
[HttpGet("from-query")]
public IActionResult FromQuery([FromQuery] int page)
{
return Ok(new { page });
}
}

Можно добавить необязательный параметр атрибута Name, если имя параметра метода действия отличается от имени в строке запроса:
public IActionResult FromQuery(
[FromQuery(Name = "p")] int page)
Тогда /api/from-api/from-query?p=8 задаст параметру page значение 8.

2. FromHeader
Атрибут FromHeader сопоставляет параметр с соответствующим заголовком запроса на основе имени. Примером этого является использование аутентификации. Если мы используем аутентификацию JWT в веб-API, нам нужно добавить в запрос заголовок авторизации. Если мы хотим получить значение заголовка авторизации, мы можем добавить параметр метода authorization с атрибутом FromHeader.
public IActionResult FromHeader(
[FromHeader] string authorization)
{

}
Аналогично FromQuery, мы можем использовать необязательный параметр атрибута Name, если хотим, чтобы имя параметра метода отличалось от имени заголовка.

3. FromForm
Атрибут FromForm работает с запросами POST, если используется тип контента multipart/form-data или x-www-url-encoded. Точно так же, он сопоставит имя поля формы с именем параметра метода. Используя параметр атрибута Name, можно задать требуемое имя поля формы для сопоставления.
public IActionResult FromForm([FromForm] string name)
{

}

4. FromRoute
FromRoute используется, если атрибут маршрута используется как часть действия. Добавив FromRoute к параметру действия, можно получить значение на основе имени атрибута маршрута. В следующем примере имеется атрибут маршрута с именем {category}. По умолчанию FromRoute сопоставит его атрибут с параметром метода действия category, что также можно переопределить с помощью параметра атрибута Name:
[HttpGet("from-route/{category}")]
public IActionResult FromRoute(
[FromRoute(Name="category")] string name)
{

}

Окончание следует…

Источник:
https://www.roundthecode.com/dotnet-tutorials/fromquery-fromform-what-do-the-net-web-api-attributes-do
👍21
День 1672. #ЗаметкиНаПолях
Атрибуты From… в .NET Web API. Окончание
Начало

Атрибут ApiController
Атрибут ApiController добавляется к контроллеру, когда методы действия внутри него используются для обслуживания ответов API. Он настраивает функции и поведение методов действий контроллера для работы с API, облегчая жизнь разработчику, например, выдачу ответа HTTP 400, если ModelState недействителен, или выдачу деталей проблемы при ошибках.

5. FromBody
Атрибут FromBody используется для извлечения информации из тела запроса, когда тип контента в запросе указан как application/json, application/xml и т.п. Среда выполнения ASP.NET Core делегирует ответственность за чтение тела средству форматирования ввода (по умолчанию используется формат JSON). Для XML его можно добавить следующим образом:
builder.Services.AddControllers()
.AddXmlSerializerFormatters();

Если контроллер имеет атрибут ApiController, необходимость в использовании атрибута FromBody отпадает.

FromBody можно использовать только для одного параметра действия. После того как поток запроса прочитан средством форматирования ввода, он больше не доступен для повторного чтения для привязки других параметров через FromBody. Таким образом, если в теле JSON передается более одного значения, их необходимо добавить в один класс и использовать его в качестве типа для параметра действия.

Когда FromBody применяется к параметру сложного типа, любые атрибуты источника привязки, применённые к его свойствам, игнорируются. Например, следующее действие Create указывает, что его параметр pet заполняется из тела:
public ActionResult<Pet> Create([FromBody] Pet pet)

Класс Pet указывает, что его свойство Breed заполняется из параметра строки запроса:
public class Pet
{
public string Name { get; set; };
[FromQuery]
public string Breed { get; set; };
}

Здесь:
- Атрибут FromQuery игнорируется.
- Свойство Breed не заполняется из параметра строки запроса.

Средства форматирования ввода читают только тело и не понимают атрибуты источника привязки. Если подходящее значение найдено в теле, это значение используется для заполнения свойства Breed.

6. FromServices
Атрибут FromServices не имеет ничего общего с HTTP-запросом. Вместо этого он позволяет использовать параметр метода действия для сопоставления с сервисом из контейнера внедрения зависимостей. Его цель — предоставить альтернативу внедрению через конструктор, когда вам нужен сервис только при вызове определённого метода.

Если экземпляр типа не зарегистрирован в контейнере внедрения зависимостей, приложение выдаст исключение при попытке привязать параметр. Чтобы сделать параметр необязательным, используйте один из следующих подходов:
- Сделайте параметр обнуляемым (в теле метода при обращении к параметру убедитесь, что он не null).
- Установите значение по умолчанию для параметра.

Атрибут FromServices также не требуется, если контроллер помечен атрибутом ApiController.

Источники:
-
https://www.roundthecode.com/dotnet-tutorials/fromquery-fromform-what-do-the-net-web-api-attributes-do
-
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
👍14
День 1673. #ЗаметкиНаПолях
Отправляем Письма с Помощью FluentEmail
В вашем приложении зарегистрировался новый пользователь? Код подтверждения должен быть отправлен на его email. Пользователь забыл пароль? Нужно отправить ему ссылку для сброса пароля. Сегодня приложения не могут существовать без отправки электронной почты. Поэтому нужно что-то легко и быстро настраиваемое для отправки электронных писем.

FluentEmail — популярная библиотека с открытым исходным кодом для отправки email из приложений .NET. Он предоставляет fluent-интерфейс, т.е. мы можем легко создать сообщение, добавить получателей, установить тему и т. д., используя цепочку методов.

Сначала нужно добавить в проект NuGet-пакеты FluentEmail.Core и FluentEmail.Smtp. Теперь создать и отправить email очень просто:
var email = await Email
.From("[email protected]")
.To("[email protected]")
.Subject("Hi")
.Body("Hello world!")
.SendAsync();

Заметьте, что From – единственный статический метод, поэтому в этом примере должен идти первым.

Доступны наиболее распространённые методы:
- .To(string emailAddress) — добавить получателей.
- .SetFrom(string emailAddress) — изменить адрес отправителя.
- .CC/BCC(string emailAddress) — добавление CC или BCC.
- .Subject(string subject) — тема.
- .Body(string body) — тело сообщения.
- .Attach(Attachment attachment) — вложения.
- .UsingTemplate(string template, T model, bool isHtml = true) — использовать шаблон (см. ниже).
- .SendAsync() — отправить, используя настроенного отправителя (см. ниже).

Более правильным подходом будет настроить отправителя и шаблон в DI-контейнере:
builder.Services
.AddFluentEmail("[email protected]")
.AddRazorRenderer()
.AddSmtpSender(…);

- .AddFluentEmail() – настраивает FluentEmail с адресом отправителя по умолчанию.
- AddSmtpSender() – настраивает провайдера отправителя SmtpSender.
- AddRazorRenderer() – настраивает провайдера шаблонов RazorRenderer.

Использование Razor-шаблонов сообщений – одна из самых популярных функций FluentEmail. Чтобы её использовать, добавьте NuGet-пакет FluentEmail.Razor. RazorRenderer поддерживает любой код Razor. Используя шаблоны, вы можете заменить вызов .Body(…) в примере выше на один из следующих:
- UsingTemplate<T>(string template, T model) – использует шаблон из строки template (не очень удобно писать код Razor внутри простой строки, но подойдёт для простых шаблонов).
- UsingTemplateFromFile<T>(string fileName, T model) – позволяет указать путь к файлу шаблона – обычной странице .cshtml.

FluentEmail позволяет вам подключить популярные провайдеры отправки email (или создать собственный, реализовав интерфейс ISender). Чтобы использовать отправителя, добавьте провайдера и настройте его в DI-контейнере. Доступны следующие основные провайдеры:
- SMTP – стандартный клиент System.Net.Mail.SmtpClient
- Mailgun
- SendGrid
- MimeKit

Например, добавить провайдера SendGrid можно, установив NuGet-пакет FluentEmail.SendGrid и вызвав:
builder.Services
.AddFluentEmail("[email protected]")
.AddRazorRenderer()
.AddSendGridSender("apikey");

Источники:
-
https://stefandjokic.tech/blog.html
-
https://lukelowrey.com/send-email-in-dotnet-core-with-fluent-email/
👍31
День 1674. #Безопасность
Политика Безопасности Контента. Начало
Политика безопасности контента (Content Security Policy, CSP) представляет собой HTTP-заголовок Content-Security-Policy, который указывает браузерам, откуда загружать (и, в случае JavaScript, исполнять) контент, что может сделать почти невозможным осуществление межсайтового скриптинга. Значение заголовка состоит из директив и связанных значений.

Основная директива default-src предоставляет браузеру список всех действительных источников* или URI ресурсов.

*Источник определяется как следующие три значения:
- схема – http: или https:;
- полностью определённое имя доменаwww.example.com;
- порт – по умолчанию 80 для HTTP или 443 для HTTPS (если используется порт по умолчанию, то обычно он не является частью значения источника).
Если все три части различных источников идентичны, значит они совпадают. Например, у www.example.com и example.com разный источник, поскольку имена доменов не совпадают.

Кроме HTTP-заголовка можно использовать тег <meta>:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
Однако, это не очень удобно, когда значение директивы длинное. Кроме того, не будут работать некоторые функции CSP.

CSP определяет большое количество директив для различных видов ресурсов:
- base-uri – значения или пути, разрешенные для <base href="">;
- child-src - фреймы и веб-воркеры,
- connect-src - запросы HTTP и WebSocket,
- font-src – шрифты,
- form-action – значения для атрибута action элементов <form>;
- img-src – изображения,
- media-src - аудио- и видеофайлы,
- object-src – плагины,
- script-src - код JavaScript,
- style-src - cтили CSS,
и другие.

Специализированные директивы переопределяют значения default-src.

В заголовке директивы разделяются точкой с запятой, а их значения пробелами, например:
default-src 'self'; style-src 'self' https://cdn.jsdelivr.net

Здесь мы разрешаем использовать ресурсы только из того же источника, что и сама страница ('self'), а также разрешаем получать стили из сети доставки контента (CDN). Заметьте, что для style-src также указано значение 'self', чтобы была возможность использовать локальные файлы стилей (т.к. style-src полностью перезаписывает значение default-src).

Для указания источника есть следующие варианты:
- сайт – https://example.com;
- путь – https://example.com/assets/ (завершающий слеш обязателен для указания папки, а не файла с таким именем);
- полный URI – https://example.com/assets/style.css;
- подстановочный знак (*).
Рекомендуется использовать наиболее строгое указание источника, например, не разрешать все ресурсы из сети CDN.

Продолжение следует…

Источник: Кристиан Венц “Безопасность
ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
👍2
День 1675. #Безопасность
Политика Безопасности Контента. Продолжение
Начало

Встроенный код
Если существует директива CSP default-src или style-src, то встроенные стили перестают работать. Аналогично, при наличии default-src или script-src встроенный код JavaScript больше выполняться не будет. Это позволяет защититься от внедрения кода вида
<script>/* вредоносный код */</script>.
При этом
<script src="script.js"></script>
будет работать. Обычно лучше избегать встроенного кода. Вынесите код JavaScript и CSS во внешние файлы.

Однако, если нужно активировать встроенный контент, есть несколько вариантов:
1. Атрибут nonce (одноразовый номер)
Случайный одноразовый токен (например, GUID), который добавляется в HTTP заголовок:
default-src 'self'; style-src 'self' 'nonce-123456'; script-src 'self' 'nonce-123456'
и во все элементы <script> и <style>, где используются встроенный код:
<script nonce="123456'">…</script>

2. Хэш контента элемента
Нужно вычислить хеш SHA256, SHA384 или SHA512 контента элемента <script> или <style>, включая разрывы строк и другие пробельные символы, и добавить в HTTP-заголовок значение 'sha<алгоритм>-<хэш>':
default-src 'self'; script-src 'self' 'sha256-nzw…='
Теперь эта политика явно разрешает встроенный код JavaScript, соответствующий хэшу.

Использование хэша не распространяется на:
- атрибуты обработчиков событий (например, onclick);
- ссылки JavaScript: (<a href="JavaScript:…">);
- атрибуты стилей (style="…").
Для активации этих функций, к значениям политики script-src или style-src надо добавить константу 'unsafe-hashes' (в дополнение к хэшам кода в этих атрибутах).
Также перестанет работать динамическое выполнение кода (eval(), setInterval(), setTimeout() со строковыми аргументами и т.п.). Чтобы включить это, нужно добавить 'unsafe-eval'.

3. Значение 'unsafe-inline'.
Разрешает исполнение встроенного кода (практически сводя на нет преимущества CSP).

Проверка кода JavaScript с помощью Subresource Integrity (SRI)
Если вы загружаете файл JavaScript со стороннего сервера, то можно проверить, что он не был подделан. Присвойте атрибуту integrity тега <script> хэш содержимого файла JavaScript:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="></script>
Если содержимое файла JavaScript не совпадает с хэшем, браузер откажется выполнить код.

Окончание следует…

Источник: Кристиан Венц “Безопасность
ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
👍9
День 1676. #Безопасность
Политика Безопасности Контента. Окончание
Начало
Продолжение

Отправка отчётов
Часто полезно знать, когда политика CSP нарушается. Это означает, что либо вы не разрешили использование какого-либо источника, либо есть уязвимость, которая активно эксплуатируется.

Директива report-uri заставит браузер отправлять POST-запрос на выбранную конечную точку при нарушении одной из политик:
default-src 'self'; style-src 'self' https://cdn.jsdelivr.net …; report-uri /csp-reports

Браузер отправит отчёт в формате JSON на эту конечную точку (которая также может находиться на другом домене) с информацией, какая политика была нарушена, какой файл (скрипт) её нарушил, в каком месте кода страницы он был вызван, и т.п. Существуют коммерческие системы, которые будут принимать ваши отчёты CSP и форматировать их в приятные UI представления (например, https://report-uri.com/). Стоит ли отправлять информацию о безопасности вашего сайта третьей стороне – решать вам.

Однако, можно не дожидаться, пока в производственной среде что-то перестанет работать, прежде чем исправлять это. HTTP-заголовок Сontent-Security-Policy-Report-Only подойдёт для тестирования политик. В отличие от заголовка Content-Security-Policy, он не будет применять политики безопасности контента, а просто будет сообщать о найденных нарушениях политик на заданную конечную точку (если она задана в report-uri).

При добавлении политик CSP к уже имеющемуся сайту полезно начать с использования заголовка Сontent-Security-Policy-Report-Only и политики, запрещающей всё. Для этого используется константа 'none':
default-src 'none'; form-action 'none'; report-uri /csp-reports

Затем, по мере получения отчётов либо вносите изменения в сайт, либо ослабляйте политики.

Конечная цель – максимально строгая CSP, насколько это возможно при используемом вами стеке. Обязательно нужно отключить плагины
и базовый URI:
object-src 'none'; base-uri 'none'

Также стоит рассмотреть возможность ограничения контента JavaScript только теми скриптами, для которых задан одноразовый токен:
script-src 'nonce-…'

Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
👍9
День 1677. #PostgresTips
Советы по Postgres для Начинающих

7. Убедитесь, что контрольные суммы данных включены.
Целостность данных является краеугольным камнем любой базы данных. Без уверенности в точности и согласованности данных даже самые совершенные структуры и алгоритмы БД станут бесполезными. Именно здесь контрольные суммы данных в Postgres играют решающую роль.

Что это?
В контексте БД контрольная сумма — это значение, полученное из суммы всех байтов в блоке данных. Если контрольные суммы данных включены, Postgres использует их для проверки целостности данных, хранящихся на диске. Когда данные записываются на диск, Postgres вычисляет и сохраняет значение контрольной суммы. Позже, когда эти данные считываются обратно в память, Postgres пересчитывает контрольную сумму и сравнивает её с сохранённым значением, чтобы убедиться, что данные не были повреждены.

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

Активация и накладные расходы
Важно отметить, что контрольные суммы необходимо активировать во время создания кластера БД (initdb). Их невозможно включить для существующего кластера БД без дампа и восстановления данных или без использования специального инструмента pg_checksums (для этого потребуется некоторый опыт). Накладные расходы, связанные с контрольными суммами, относительно малы, особенно по сравнению с преимуществами обеспечения целостности данных.

8. Настройте автоочистку для частых запусков и более быстрого выполнения.
Процесс автоочистки (autovacuum) в Postgres похож на бригаду уборщиков для БД. Он работает незаметно, очищая старые данные и освобождая место для новых данных, обеспечивая эффективность БД.

Что это?
Каждая операция INSERT, UPDATE или DELETE в Postgres создаёт новую версию строки (в случае DELETE помечает строку как удалённую). Со временем старые версии строк накапливаются, и их необходимо очищать. Autovacuum выполняет эту очистку, освобождая место для хранения и удаляя «мёртвые» строки. Он также отвечает за поддержание актуальности статистики таблиц и предотвращение инцидентов, связанных с переносом идентификаторов транзакций.

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

Как настроить
Настройка автоочистки сводится к тому, чтобы она запускалась чаще и быстрее выполняла свои задачи. По сути, настройку приходится вести в двух направлениях:
- дать автоочистке больше мощности (больше рабочих процессов, большая квоту), т.к. по умолчанию разрешено только 3 рабочих процесса, и они довольно консервативно ограничиваются;
- заставить её срабатывать чаще, т.к., опять же, по умолчанию она срабатывает только при значительных изменениях строк (10-20%); в OLTP базе данных желательно уменьшить этот показатель до 1% или даже ниже.

Источник: https://postgres.ai/blog/20230722-10-postgres-tips-for-beginners
👍13