День 1606. #BestPractices
Правильно Используем HttpClient. Начало
Самый простой способ делать HTTP-запросы в .NET — использовать HttpClient. Это отличная абстракция, особенно при передаче данных в JSON. К сожалению, легко неправильно использовать HttpClient.
Самый простой способ — создать новый экземпляр, задать необходимые свойства и использовать его для отправки запросов. Однако каждый экземпляр использует собственный пул соединений в целях изоляции. Если сервер находится под высокой нагрузкой, а приложение постоянно создаёт новые подключения, это может привести к исчерпанию доступных портов. Это вызовет исключение во время выполнения при попытке отправить запрос.
Вместо самостоятельного управления временем жизни HttpClient вы можете использовать IHttpClientFactory для создания экземпляра. Просто вызовите метод CreateClient и используйте возвращённый экземпляр HttpClient для отправки запросов.
Дорогостоящей частью HttpClient является фактический обработчик сообщений — HttpMessageHandler. Каждый HttpMessageHandler имеет внутренний пул HTTP-соединений, который можно использовать повторно. IHttpClientFactory будет кэшировать HttpMessageHandler и повторно использовать его при создании нового экземпляра HttpClient. Важным примечанием здесь является то, что экземпляры HttpClient, созданные IHttpClientFactory, должны быть недолговечными.
Использование IHttpClientFactory решит большинство проблем, связанных с созданием HttpClient вручную. Но нам по-прежнему необходимо настраивать параметры запроса по умолчанию каждый раз, когда мы получаем новый экземпляр из CreateClient().
Можно настроить именованный клиент. AddHttpClient принимает имя и делегат, который можно использовать для настройки параметров по умолчанию экземпляра HttpClient:
Источник: https://www.milanjovanovic.tech/blog/the-right-way-to-use-httpclient-in-dotnet
Правильно Используем HttpClient. Начало
Самый простой способ делать HTTP-запросы в .NET — использовать HttpClient. Это отличная абстракция, особенно при передаче данных в JSON. К сожалению, легко неправильно использовать HttpClient.
Самый простой способ — создать новый экземпляр, задать необходимые свойства и использовать его для отправки запросов. Однако каждый экземпляр использует собственный пул соединений в целях изоляции. Если сервер находится под высокой нагрузкой, а приложение постоянно создаёт новые подключения, это может привести к исчерпанию доступных портов. Это вызовет исключение во время выполнения при попытке отправить запрос.
Вместо самостоятельного управления временем жизни HttpClient вы можете использовать IHttpClientFactory для создания экземпляра. Просто вызовите метод CreateClient и используйте возвращённый экземпляр HttpClient для отправки запросов.
Дорогостоящей частью HttpClient является фактический обработчик сообщений — HttpMessageHandler. Каждый HttpMessageHandler имеет внутренний пул HTTP-соединений, который можно использовать повторно. IHttpClientFactory будет кэшировать HttpMessageHandler и повторно использовать его при создании нового экземпляра HttpClient. Важным примечанием здесь является то, что экземпляры HttpClient, созданные IHttpClientFactory, должны быть недолговечными.
// в Program регистрируем фабрику:Сокращаем дублирование с помощью именованных клиентов
services.AddHttpClient();
// в сервисе внедряем её
public class MyService
{
private IHttpClientFactory _factory;
public MyService(
IHttpClientFactory factory)
{
_factory = factory;
}
public async Task<string> GetAsync()
{
var client =
_factory.CreateClient();
client.BaseAddress =
new Uri("https://my.api.com");
…
}
}
Использование IHttpClientFactory решит большинство проблем, связанных с созданием HttpClient вручную. Но нам по-прежнему необходимо настраивать параметры запроса по умолчанию каждый раз, когда мы получаем новый экземпляр из CreateClient().
Можно настроить именованный клиент. AddHttpClient принимает имя и делегат, который можно использовать для настройки параметров по умолчанию экземпляра HttpClient:
services.AddHttpClient(Отличие в том, что теперь нужно указывать имя при получении экземпляра через CreateClient:
"client1",
(c) =>
{
c.BaseAddress =
new Uri("https://my.api.com");
}
);
var client = _factory.CreateClient("client1");Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/the-right-way-to-use-httpclient-in-dotnet
👍21
День 1607. #BestPractices
Правильно Используем HttpClient. Окончание
Начало
Замена именованных клиентов типизированными
Недостатком использования именованных клиентов является необходимость разрешать HttpClient, каждый раз передавая имя. Добиться того же поведения можно через типизированный клиент, вызвав AddClient<TClient>(), где TClient – сервис, в который будет внедряться HttpClient.
Замечание: «Под капотом» всё равно используется именованный клиент, имя которого совпадает с именем типа. Также это зарегистрирует MyService с временем жизни transient.
Поскольку типизированный клиент является transient-сервисом, внедрение его в singleton-сервис приведёт к его кэшированию на время существования singleton-сервиса, что помешает типизированному клиенту реагировать на изменения DNS. Если вы хотите использовать типизированный клиент в singleton-сервисе, рекомендуется использовать SocketsHttpHandler в качестве основного обработчика и настроить свойство PooledConnectionLifetime. Также, т.к. теперь SocketsHttpHandler будет управлять пулом подключений, для него можно установить бесконечное время жизни:
Согласно рекомендациям Microsoft:
- Используйте статический или singleton-экземпляр HttpClient с настроенным PooledConnectionLifetime, так как это решает проблемы как исчерпания портов, так и отслеживания изменений DNS.
- Используйте IHttpClientFactory, если вы хотите переместить конфигурацию в одно место или использовать несколько разных клиентов, настроенных для разных вариантов использования. Но помните, что клиенты должны быть недолговечными, и после создания клиента фабрика больше не может управлять им.
- Используйте типизированный клиент, если вам нужна возможность настройки IHttpClientFactory.
Источник: https://www.milanjovanovic.tech/blog/the-right-way-to-use-httpclient-in-dotnet
Правильно Используем HttpClient. Окончание
Начало
Замена именованных клиентов типизированными
Недостатком использования именованных клиентов является необходимость разрешать HttpClient, каждый раз передавая имя. Добиться того же поведения можно через типизированный клиент, вызвав AddClient<TClient>(), где TClient – сервис, в который будет внедряться HttpClient.
Замечание: «Под капотом» всё равно используется именованный клиент, имя которого совпадает с именем типа. Также это зарегистрирует MyService с временем жизни transient.
services.AddHttpClient<MyService>(В MyService внедряем HttpClient, а не фабрику:
(c) =>
{
c.BaseAddress =
new Uri("https://my.api.com");
}
);
public class MyServiceИзбегайте типизированных клиентов в синглтонах
{
private HttpClient client;
public MyService(HttpClient client)
{
_client = client;
}
public async Task<string> GetAsync()
{
return await
client.GetFromJsonAsync(…);
}
}
Поскольку типизированный клиент является transient-сервисом, внедрение его в singleton-сервис приведёт к его кэшированию на время существования singleton-сервиса, что помешает типизированному клиенту реагировать на изменения DNS. Если вы хотите использовать типизированный клиент в singleton-сервисе, рекомендуется использовать SocketsHttpHandler в качестве основного обработчика и настроить свойство PooledConnectionLifetime. Также, т.к. теперь SocketsHttpHandler будет управлять пулом подключений, для него можно установить бесконечное время жизни:
services.AddHttpClient<MyService>(Какой вариант использовать?
(c) => { … }
)
.ConfigurePrimaryHttpMessageHandler(() =>
{
return new SocketsHttpHandler()
{
PooledConnectionLifetime
= TimeSpan.FromMinutes(15)
};
})
.SetHandlerLifetime(Timeout.InfiniteTimeSpan);
Согласно рекомендациям Microsoft:
- Используйте статический или singleton-экземпляр HttpClient с настроенным PooledConnectionLifetime, так как это решает проблемы как исчерпания портов, так и отслеживания изменений DNS.
- Используйте IHttpClientFactory, если вы хотите переместить конфигурацию в одно место или использовать несколько разных клиентов, настроенных для разных вариантов использования. Но помните, что клиенты должны быть недолговечными, и после создания клиента фабрика больше не может управлять им.
- Используйте типизированный клиент, если вам нужна возможность настройки IHttpClientFactory.
Источник: https://www.milanjovanovic.tech/blog/the-right-way-to-use-httpclient-in-dotnet
👍9
День 1608. #ЧтоНовенького
Новинки ASP.NET Core в .NET 8 Превью 5
Последний выпуск .NET 8 Preview 5 содержит важные дополнения в ASP.NET Core, которые кратко сегодня рассмотрим.
1. Продуктивность. Улучшения отладки в ASP.NET Core касаются введения атрибутов настройки отладки (DebuggerDisplay), упрощающих извлечение важной информации, связанной с такими типами, как HttpContext, HttpRequest, HttpResponse и ClaimsPrincipal, в отладчике Visual Studio.
2. «Незаметные повторные подключения» в SignalR. Эта новая функция направлена на минимизацию времени простоя клиентов, сталкивающихся с временными сбоями в работе сети. Временная буферизация данных как на стороне сервера, так и на стороне клиента и подтверждение сообщений обеспечивают более плавное взаимодействие с пользователем. В настоящее время эта поддержка ограничена клиентами .NET, использующими WebSockets, а конфигурация пока недоступна. Разработчики могут свободно использовать эту функцию и настраивать параметры options.UseAks в HubConnectionBuilder. Ожидается, что в будущих версиях будет представлена конфигурация на стороне сервера, настраиваемые параметры буферизации, ограничения времени ожидания и расширенная поддержка других видов клиентов.
3. Blazor
- Компонент Blazor Router теперь интегрируется с маршрутизацией конечных точек для обработки маршрутизации как на стороне сервера, так и на стороне клиента. Эта интеграция обеспечивает согласованную маршрутизацию к компонентам независимо от того, используется ли рендеринг на стороне сервера или на стороне клиента. Новый шаблон Blazor Web App включает образцы страниц, такие как Index.razor и ShowData.razor, которые используют маршрутизацию конечных точек и потоковую визуализацию для отображения данных прогноза погоды, а улучшенная поддержка навигации ожидается в будущих предварительных версиях .NET 8.
- Blazor Server предоставляет возможность включения интерактивности для отдельных компонентов. С помощью нового атрибута [RenderModeServer] разработчики могут активировать интерактивность для определённых компонентов, используя метод расширения AddServerComponents. Это усовершенствование обеспечивает большую гибкость и контроль при создании интерактивных приложений в режиме рендеринга Blazor Server.
4. Обобщённые атрибуты, добавленые в C#11, теперь предоставляют более ясные альтернативы атрибутам, которые ранее полагались на параметр типа System.Type. Обобщённые варианты теперь доступны для следующих атрибутов: ProducesResponseType<T>, Produces<T>, MiddlewareFilter<T>, ModelBinder<T>, ModelMetadataType<T>, ServiceFilter<T> и TypeFilter<T>.
5. Аутентификация и авторизация. Шаблоны проектов ASP.NET Core React и Angular удалили зависимость от Duende IdentityServer. Вместо этого теперь используется пользовательский интерфейс ASP.NET Core Identity по умолчанию и аутентификация по файлам cookie. Кроме того, представлен новый анализатор Roslyn, чтобы облегчить принятие более «краткого» синтаксиса с использованием API AddAuthorizationBuilder, где это применимо.
6. В области Native AOT добавлены улучшения для минимальных API, создаваемых во время компиляции. Они включают поддержку параметров, дополненных атрибутом AsParameters, и автоматический вывод метаданных для типов запросов и ответов.
Разработчики могут оставлять отзывы и следить за ходом работы над ASP.NET Core в .NET 8, посетив официальный репозиторий проекта на GitHub.
Источник: https://www.infoq.com/news/2023/06/aspnet-core-8-preview-5/
Новинки ASP.NET Core в .NET 8 Превью 5
Последний выпуск .NET 8 Preview 5 содержит важные дополнения в ASP.NET Core, которые кратко сегодня рассмотрим.
1. Продуктивность. Улучшения отладки в ASP.NET Core касаются введения атрибутов настройки отладки (DebuggerDisplay), упрощающих извлечение важной информации, связанной с такими типами, как HttpContext, HttpRequest, HttpResponse и ClaimsPrincipal, в отладчике Visual Studio.
2. «Незаметные повторные подключения» в SignalR. Эта новая функция направлена на минимизацию времени простоя клиентов, сталкивающихся с временными сбоями в работе сети. Временная буферизация данных как на стороне сервера, так и на стороне клиента и подтверждение сообщений обеспечивают более плавное взаимодействие с пользователем. В настоящее время эта поддержка ограничена клиентами .NET, использующими WebSockets, а конфигурация пока недоступна. Разработчики могут свободно использовать эту функцию и настраивать параметры options.UseAks в HubConnectionBuilder. Ожидается, что в будущих версиях будет представлена конфигурация на стороне сервера, настраиваемые параметры буферизации, ограничения времени ожидания и расширенная поддержка других видов клиентов.
3. Blazor
- Компонент Blazor Router теперь интегрируется с маршрутизацией конечных точек для обработки маршрутизации как на стороне сервера, так и на стороне клиента. Эта интеграция обеспечивает согласованную маршрутизацию к компонентам независимо от того, используется ли рендеринг на стороне сервера или на стороне клиента. Новый шаблон Blazor Web App включает образцы страниц, такие как Index.razor и ShowData.razor, которые используют маршрутизацию конечных точек и потоковую визуализацию для отображения данных прогноза погоды, а улучшенная поддержка навигации ожидается в будущих предварительных версиях .NET 8.
- Blazor Server предоставляет возможность включения интерактивности для отдельных компонентов. С помощью нового атрибута [RenderModeServer] разработчики могут активировать интерактивность для определённых компонентов, используя метод расширения AddServerComponents. Это усовершенствование обеспечивает большую гибкость и контроль при создании интерактивных приложений в режиме рендеринга Blazor Server.
4. Обобщённые атрибуты, добавленые в C#11, теперь предоставляют более ясные альтернативы атрибутам, которые ранее полагались на параметр типа System.Type. Обобщённые варианты теперь доступны для следующих атрибутов: ProducesResponseType<T>, Produces<T>, MiddlewareFilter<T>, ModelBinder<T>, ModelMetadataType<T>, ServiceFilter<T> и TypeFilter<T>.
5. Аутентификация и авторизация. Шаблоны проектов ASP.NET Core React и Angular удалили зависимость от Duende IdentityServer. Вместо этого теперь используется пользовательский интерфейс ASP.NET Core Identity по умолчанию и аутентификация по файлам cookie. Кроме того, представлен новый анализатор Roslyn, чтобы облегчить принятие более «краткого» синтаксиса с использованием API AddAuthorizationBuilder, где это применимо.
6. В области Native AOT добавлены улучшения для минимальных API, создаваемых во время компиляции. Они включают поддержку параметров, дополненных атрибутом AsParameters, и автоматический вывод метаданных для типов запросов и ответов.
Разработчики могут оставлять отзывы и следить за ходом работы над ASP.NET Core в .NET 8, посетив официальный репозиторий проекта на GitHub.
Источник: https://www.infoq.com/news/2023/06/aspnet-core-8-preview-5/
👍4👎1
День 1609. #TipsAndTricks #PerformanceTips
Советы по Оптимизации Производительности
VII. Обнуляемость и обнуляемые ссылочные типы
Обработка ссылочных типов, допускающих значение null, является важной частью программирования на C#, особенно для предотвращения исключений NullReferenceException. Рассмотрим несколько советов по безопасной работе с типами, допускающими значение null, без ущерба для производительности.
1. Используйте операторы объединения с null (??, ??=)
Операторы объединения с null помогают писать краткий и производительный код при работе с типами, допускающими значение NULL, гарантируя, что значения null заменяются значением по умолчанию.
Плохо:
Хорошо:
2. Используйте обнуляемые ссылочные типы, чтобы избежать исключений NullReferenceException во время выполнения
Обнуляемые ссылочные типы, появившиеся в C# 8.0, помогают перехватывать потенциальные исключения NullReferenceException во время компиляции, а не во время выполнения.
Плохо:
Хорошо:
Источник: https://dev.to/bytehide/50-c-advanced-optimization-performance-tips-18l2
Советы по Оптимизации Производительности
VII. Обнуляемость и обнуляемые ссылочные типы
Обработка ссылочных типов, допускающих значение null, является важной частью программирования на C#, особенно для предотвращения исключений NullReferenceException. Рассмотрим несколько советов по безопасной работе с типами, допускающими значение null, без ущерба для производительности.
1. Используйте операторы объединения с null (??, ??=)
Операторы объединения с null помогают писать краткий и производительный код при работе с типами, допускающими значение NULL, гарантируя, что значения null заменяются значением по умолчанию.
Плохо:
string input = GetNullableString();Неудачный пример демонстрирует многословный и менее производительный код при работе с нулевыми значениями.
if (input == null)
{
input = "default";
}
Хорошо:
var input = GetNullableString() ?? "default";Здесь используется оператор объединения с нулевым значением, который обеспечивает более лаконичный и эффективный способ обработки нулевых значений в C#. Это обеспечивает лучшую производительность и более понятный код.
2. Используйте обнуляемые ссылочные типы, чтобы избежать исключений NullReferenceException во время выполнения
Обнуляемые ссылочные типы, появившиеся в C# 8.0, помогают перехватывать потенциальные исключения NullReferenceException во время компиляции, а не во время выполнения.
Плохо:
string name = GetName();Здесь у нас потенциально во время выполнения может возникнуть исключение NullReferenceException, что может привести к неожиданным сбоям.
int length = name.Length;
Хорошо:
string? name = GetName();Используя обнуляемые ссылочные типы, и условный доступ с нулевым значением через оператор ?., вы можете избежать потенциальных исключений NullReferenceException в своём коде. Это помогает создавать более безопасный и производительный код, который легче понять как во время разработки, так и во время отладки.
int length = name?.Length ?? 0;
Источник: https://dev.to/bytehide/50-c-advanced-optimization-performance-tips-18l2
👍13
День 1610. #ЗаметкиНаПолях
Отключаем HSTS для Локального Хоста в Браузерах на Движке Chromium
Http Strict Transport Security (HSTS) — это механизм безопасности, который предписывает браузеру автоматически перенаправлять http-запросы на https перед отправкой запроса на сервер. При разработке веб-приложения иногда полезно отключить HSTS для локального хоста. Это связано с тем, что включение HSTS на локальном хосте влияет на другие приложения. Например, некоторые приложения запускают локальный веб-сервер и открывают браузер. Однако, если они не могут использовать сертификат безопасности, то не могут использовать https. Если веб-сайт один раз активирует HSTS на локальном хосте, эти приложения перестанут работать, поскольку они не прослушивают https.
ASP.NET Core достаточно умён, чтобы не отправлять заголовок HSTS, когда приложение работает на локальном хосте. Однако это может быть не так для других веб-фреймворков.
Отключение политики HSTS вручную
Вы можете открыть страницу
Использование другого домена для разработки
HSTS применяется отдельно для каждого домена. Поэтому вы можете использовать другой домен для вашего приложения, например, myapp.local вместо localhost. Таким образом, даже если приложение использует HSTS, это не повлияет на другие приложения, использующие localhost. Чтобы настроить домен, нужно отредактировать файл hosts (C:\Windows\System32\drivers\etc\hosts), добавив туда запись вроде:
См. также «Принудительный HTTPS в Приложениях ASP.NET Core»
Источник: https://www.meziantou.net/disabling-hsts-for-localhost-on-chromium-based-browsers.htm
Отключаем HSTS для Локального Хоста в Браузерах на Движке Chromium
Http Strict Transport Security (HSTS) — это механизм безопасности, который предписывает браузеру автоматически перенаправлять http-запросы на https перед отправкой запроса на сервер. При разработке веб-приложения иногда полезно отключить HSTS для локального хоста. Это связано с тем, что включение HSTS на локальном хосте влияет на другие приложения. Например, некоторые приложения запускают локальный веб-сервер и открывают браузер. Однако, если они не могут использовать сертификат безопасности, то не могут использовать https. Если веб-сайт один раз активирует HSTS на локальном хосте, эти приложения перестанут работать, поскольку они не прослушивают https.
ASP.NET Core достаточно умён, чтобы не отправлять заголовок HSTS, когда приложение работает на локальном хосте. Однако это может быть не так для других веб-фреймворков.
Отключение политики HSTS вручную
Вы можете открыть страницу
about://net-internals/#hsts
в браузере, работающем на движке Chromium (Chrome, Edge и т.п.) и удалить политику безопасности домена для localhost в разделе "Delete domain security policies".Использование другого домена для разработки
HSTS применяется отдельно для каждого домена. Поэтому вы можете использовать другой домен для вашего приложения, например, myapp.local вместо localhost. Таким образом, даже если приложение использует HSTS, это не повлияет на другие приложения, использующие localhost. Чтобы настроить домен, нужно отредактировать файл hosts (C:\Windows\System32\drivers\etc\hosts), добавив туда запись вроде:
127.0.0.1 myapp.localЗатем, измените applicationUrl в файле launchSettings.json вашего приложения на использование https://myapp.local, и можно использовать https://myapp.local в браузере.
См. также «Принудительный HTTPS в Приложениях ASP.NET Core»
Источник: https://www.meziantou.net/disabling-hsts-for-localhost-on-chromium-based-browsers.htm
👍12
День 1611. #Карьера
Парное Программирование: Лучшие Практики и Инструменты. Начало
В этой серии рассмотрим концепцию парного программирования, его преимущества и полезные инструменты, а также развеем несколько распространённых мифов.
Парное программирование — это метод, при котором два разработчика работают вместе над одной и той же задачей. При этом один человек пишет код (водитель), а другой просматривает каждую строку и даёт обратную связь (штурман). Этот подход отличается от традиционного сольного программирования и имеет некоторые преимущества.
Обязанность водителя - работа с компьютером и ввод кода. Обязанность штурмана — думать о том, что нужно делать и в каком направлении двигаться. Они постоянно общаются и меняются ролями обычно каждые несколько минут.
Преимущества
1. Улучшенное качество кода
Два программиста могут быстро выявлять ошибки друг друга, что улучшает качество кода и значительно снижает вероятность пропуска ошибок. Партнёры могут предлагать друг другу ценную информацию, улучшения и получать отзывы о своих идеях, прежде чем приступить к их реализации. Таким образом, команда может создавать более чистый, функциональный и оптимизированный код.
2. Расширение сотрудничества и коммуникации
Парное программирование помогает коллегам работать над одной кодовой базой и делиться своими знаниями и навыками, что приводит к лучшему решению проблем, а также устраняет разрыв в общении между коллегами, поскольку способствует общению, позволяя быстро и легко обмениваться информацией.
Например, во время работы над новой функцией один программист может объяснить свой мыслительный процесс и идеи, а другой – дать отзыв и задать вопросы, чтобы прояснить, что нужно сделать. Таким образом, команда может работать вместе, чтобы найти лучшее решение и избежать недоразумений.
3. Повышение продуктивности
Когда два программиста работают вместе, они могут быстрее выполнять задачи, разделяя ответственность. Один может работать над проблемой, а другой - искать потенциальные ошибки. Таким образом, команда может более эффективно работать и решать проблемы. Хотя это зависит от конкретного человека, некоторые программисты более продуктивны, работая в одиночку.
Например, пара, работающая над проектом, может потратить 1-2 часа на выполнение задачи, на выполнение которой у одиночного разработчика ушло бы 3-4 часа. Вторая пара может сосредоточиться на поиске ошибок или других проблем в коде. Это означает, что команда выполнит задачу за меньшее время и с меньшими усилиями, повышая общую продуктивность.
Мифы
1. Это дорого
На самом деле повышенная стоимость - это инвестиции в продуктивность команды, качество кода и инновации. В долгосрочной перспективе это экономит время и снижает затраты, вследствие обнаружения ошибок на ранних стадиях.
2. Это медленно
Парное программирование может быть быстрее, чем другие подходы к кодированию, потому что оно позволяет быстро вносить исправления. Когда два разработчика сотрудничают, они могут избежать многих ошибок и ускорить решение проблем.
3. Это давит на разработчиков
Некоторые считают, что парное программирование может оказывать слишком большое давление на разработчиков, что приводит к конфликтам. Однако это происходит только при плохом атмосфере в команде. Так что всё зависит от того, какие у вас отношения с вашим партнёром. Если хорошие, то вас это не коснётся.
Окончание следует…
Источник: https://dev.to/documatic/pair-programming-best-practices-and-tools-154j
Парное Программирование: Лучшие Практики и Инструменты. Начало
В этой серии рассмотрим концепцию парного программирования, его преимущества и полезные инструменты, а также развеем несколько распространённых мифов.
Парное программирование — это метод, при котором два разработчика работают вместе над одной и той же задачей. При этом один человек пишет код (водитель), а другой просматривает каждую строку и даёт обратную связь (штурман). Этот подход отличается от традиционного сольного программирования и имеет некоторые преимущества.
Обязанность водителя - работа с компьютером и ввод кода. Обязанность штурмана — думать о том, что нужно делать и в каком направлении двигаться. Они постоянно общаются и меняются ролями обычно каждые несколько минут.
Преимущества
1. Улучшенное качество кода
Два программиста могут быстро выявлять ошибки друг друга, что улучшает качество кода и значительно снижает вероятность пропуска ошибок. Партнёры могут предлагать друг другу ценную информацию, улучшения и получать отзывы о своих идеях, прежде чем приступить к их реализации. Таким образом, команда может создавать более чистый, функциональный и оптимизированный код.
2. Расширение сотрудничества и коммуникации
Парное программирование помогает коллегам работать над одной кодовой базой и делиться своими знаниями и навыками, что приводит к лучшему решению проблем, а также устраняет разрыв в общении между коллегами, поскольку способствует общению, позволяя быстро и легко обмениваться информацией.
Например, во время работы над новой функцией один программист может объяснить свой мыслительный процесс и идеи, а другой – дать отзыв и задать вопросы, чтобы прояснить, что нужно сделать. Таким образом, команда может работать вместе, чтобы найти лучшее решение и избежать недоразумений.
3. Повышение продуктивности
Когда два программиста работают вместе, они могут быстрее выполнять задачи, разделяя ответственность. Один может работать над проблемой, а другой - искать потенциальные ошибки. Таким образом, команда может более эффективно работать и решать проблемы. Хотя это зависит от конкретного человека, некоторые программисты более продуктивны, работая в одиночку.
Например, пара, работающая над проектом, может потратить 1-2 часа на выполнение задачи, на выполнение которой у одиночного разработчика ушло бы 3-4 часа. Вторая пара может сосредоточиться на поиске ошибок или других проблем в коде. Это означает, что команда выполнит задачу за меньшее время и с меньшими усилиями, повышая общую продуктивность.
Мифы
1. Это дорого
На самом деле повышенная стоимость - это инвестиции в продуктивность команды, качество кода и инновации. В долгосрочной перспективе это экономит время и снижает затраты, вследствие обнаружения ошибок на ранних стадиях.
2. Это медленно
Парное программирование может быть быстрее, чем другие подходы к кодированию, потому что оно позволяет быстро вносить исправления. Когда два разработчика сотрудничают, они могут избежать многих ошибок и ускорить решение проблем.
3. Это давит на разработчиков
Некоторые считают, что парное программирование может оказывать слишком большое давление на разработчиков, что приводит к конфликтам. Однако это происходит только при плохом атмосфере в команде. Так что всё зависит от того, какие у вас отношения с вашим партнёром. Если хорошие, то вас это не коснётся.
Окончание следует…
Источник: https://dev.to/documatic/pair-programming-best-practices-and-tools-154j
👍13
День 1612. #Карьера
Парное Программирование: Лучшие Практики и Инструменты. Окончание
Начало
Лучшие практики
1. Чёткое определение ролей
Чётко определите роли водителя и штурмана. Водитель пишет код, а штурман проверяет и даёт обратную связь. Часто меняйтесь ролями, чтобы оба разработчика были вовлечены.
2. Эффективная коммуникация
Оба разработчика должны активно участвовать, выражать свои мысли и внимательно слушать. Делитесь идеями, задавайте вопросы и обсуждайте код. Используйте инструменты для совместной работы.
3. Уважение и эмпатия
Цените мнения, идеи и опыт друг друга. Будьте открыты для конструктивной критики и избегайте личных нападок. Создайте среду, которая поощряет сотрудничество и обучение.
4. Перерывы
Важно делать регулярные перерывы, чтобы предотвратить усталость и сохранить продуктивность. Используйте перерывы, чтобы поразмышлять о прогрессе, обсудить проблемы и спланировать следующие шаги. Учитывайте уровень энергии друг друга и соответственно планируйте перерывы.
5. Возможности обучения
Делитесь знаниями и опытом с партнёром. Будьте открыты для новых идей и подходов. Поощряйте непрерывное обучение и рост обоих разработчиков.
6. Активные обзоры кода
Обсуждайте возможные улучшения, заблаговременно выявляйте дефекты и устраняйте недостатки дизайна.
7. Планирование
Перед началом сеанса обсудите и согласуйте цели и задачи. Разбейте работу на более мелкие, управляемые части. Установите сроки и приоритеты задач, чтобы сохранять концентрацию и прогресс.
8. Документирование
Делайте заметки, записывайте важные обсуждения, решения и идеи. Создавайте документацию, которой можно поделиться с командой, помогая распространять знания и обеспечивать согласованность по всему проекту.
9. Выводы
После завершения сеанса найдите время, чтобы обдумать свой опыт. Обсудите, что получилось, а что можно улучшить. Постоянно совершенствуйтесь на основе извлечённых уроков.
Инструменты
Live Share
Расширение VS и VS Code, которое позволяет разработчикам сотрудничать в режиме реального времени.
Replit
Онлайн-инструмент, позволяющий сотрудничать с другими разработчиками в браузере, без необходимости загружать или устанавливать какое-либо дополнительное ПО. Идеален, когда просто нужно отредактировать код вместе с другими в режиме реального времени. Поддерживает более 50 языков программирования.
CodeSandbox Live
Позволяет нескольким разработчикам одновременно работать над одной кодовой базой, что упрощает совместную работу над сложными проектами.
Codeanywhere
Облачная IDE, которая позволяет писать код, сотрудничать и управлять проектами из любого места, используя любое устройство с подключением к Интернету. Предоставляет полный набор инструментов и функций для облегчения написания кода и оптимизации процесса разработки.
CodeTogether
Позволяет создавать и присоединяться к совместным сеансам кодирования из Eclipse, IntelliJ или VS Code. Гости могут присоединиться к сеансу из любой поддерживаемой IDE или из браузера.
Источник: https://dev.to/documatic/pair-programming-best-practices-and-tools-154j
Парное Программирование: Лучшие Практики и Инструменты. Окончание
Начало
Лучшие практики
1. Чёткое определение ролей
Чётко определите роли водителя и штурмана. Водитель пишет код, а штурман проверяет и даёт обратную связь. Часто меняйтесь ролями, чтобы оба разработчика были вовлечены.
2. Эффективная коммуникация
Оба разработчика должны активно участвовать, выражать свои мысли и внимательно слушать. Делитесь идеями, задавайте вопросы и обсуждайте код. Используйте инструменты для совместной работы.
3. Уважение и эмпатия
Цените мнения, идеи и опыт друг друга. Будьте открыты для конструктивной критики и избегайте личных нападок. Создайте среду, которая поощряет сотрудничество и обучение.
4. Перерывы
Важно делать регулярные перерывы, чтобы предотвратить усталость и сохранить продуктивность. Используйте перерывы, чтобы поразмышлять о прогрессе, обсудить проблемы и спланировать следующие шаги. Учитывайте уровень энергии друг друга и соответственно планируйте перерывы.
5. Возможности обучения
Делитесь знаниями и опытом с партнёром. Будьте открыты для новых идей и подходов. Поощряйте непрерывное обучение и рост обоих разработчиков.
6. Активные обзоры кода
Обсуждайте возможные улучшения, заблаговременно выявляйте дефекты и устраняйте недостатки дизайна.
7. Планирование
Перед началом сеанса обсудите и согласуйте цели и задачи. Разбейте работу на более мелкие, управляемые части. Установите сроки и приоритеты задач, чтобы сохранять концентрацию и прогресс.
8. Документирование
Делайте заметки, записывайте важные обсуждения, решения и идеи. Создавайте документацию, которой можно поделиться с командой, помогая распространять знания и обеспечивать согласованность по всему проекту.
9. Выводы
После завершения сеанса найдите время, чтобы обдумать свой опыт. Обсудите, что получилось, а что можно улучшить. Постоянно совершенствуйтесь на основе извлечённых уроков.
Инструменты
Live Share
Расширение VS и VS Code, которое позволяет разработчикам сотрудничать в режиме реального времени.
Replit
Онлайн-инструмент, позволяющий сотрудничать с другими разработчиками в браузере, без необходимости загружать или устанавливать какое-либо дополнительное ПО. Идеален, когда просто нужно отредактировать код вместе с другими в режиме реального времени. Поддерживает более 50 языков программирования.
CodeSandbox Live
Позволяет нескольким разработчикам одновременно работать над одной кодовой базой, что упрощает совместную работу над сложными проектами.
Codeanywhere
Облачная IDE, которая позволяет писать код, сотрудничать и управлять проектами из любого места, используя любое устройство с подключением к Интернету. Предоставляет полный набор инструментов и функций для облегчения написания кода и оптимизации процесса разработки.
CodeTogether
Позволяет создавать и присоединяться к совместным сеансам кодирования из Eclipse, IntelliJ или VS Code. Гости могут присоединиться к сеансу из любой поддерживаемой IDE или из браузера.
Источник: https://dev.to/documatic/pair-programming-best-practices-and-tools-154j
👍5
День 1613. #ЗаметкиНаПолях
Сжатие Ответов в ASP.NET Core
Уменьшение размера ответа API может заметно повысить производительность вашего приложения. А поскольку пропускная способность сети является ограниченным ресурсом, следует, по крайней мере, рассмотреть преимущества сжатия ответов.
Использовать сжатие ответов в приложениях .NET очень просто. Нужно вызвать два метода:
- AddResponseCompression – для настройки сервисов сжатия ответа;
- UseResponseCompression – для добавления промежуточного ПО сжатия ответа в конвейер.
Сжатие ответов по умолчанию отключено в HTTPS, поэтому его надо явно включить:
В идеале лучше использовать серверное сжатие ответа, если ваш сервер приложений (IIS, Apache, Nginx) поддерживает его. Если сервер не поддерживает сжатие ответов, то оправдано использование промежуточного ПО. Однако т.к. оно происходит на уровне приложения, производительность обычно падает.
Еще одной проблемой является безопасность, т.к. использование сжатия ответов в HTTPS может подвергнуть вас атакам CRIME и BREACH. Вот что можно сделать, чтобы защититься от них:
- Добавить токены защиты от подделки (anti-forgery).
- Не отправлять секреты приложения в теле запроса.
- Добавить ограничитель трафика
Настройка провайдеров сжатия
При вызове AddResponseCompression по умолчанию добавляются два провайдера сжатия (но можно добавить свои в настройках AddResponseCompression):
- BrotliCompressionProvider
- GzipCompressionProvider
По умолчанию используется сжатие Brotli, если оно поддерживается клиентом. В противном случае будет использоваться Gzip. Можно настроить уровень сжатия для Brotli и Gzip:
- Optimal,
- Fastest (по умолчанию),
- NoCompression,
- SmallestSize.
Итого
Сжатие ответов — хороший метод повышения производительности API и снижения сетевых затрат. В идеале желательно использовать серверное сжатие ответов, если оно поддерживается вашим сервером приложений. Если нет, сжатие ответов в приложении доступно в .NET через промежуточное ПО.
Это увеличивает нагрузку на ЦП и может подвергнуть HTTPS некоторым рискам безопасности, но есть способы смягчить это.
Обычно конфигурации по умолчанию для провайдера сжатия и уровня сжатия дают отличные результаты.
Вы можете протестировать значение сжатия ответа в своём приложении и изучить изменения в размере и времени ответа. Попробуйте разные провайдеры сжатия, изменяя заголовок Accept-Encoding клиента, а также настраивая разные уровни сжатия в приложении.
Источник: https://www.milanjovanovic.tech/blog/response-compression-in-aspnetcore
Сжатие Ответов в ASP.NET Core
Уменьшение размера ответа API может заметно повысить производительность вашего приложения. А поскольку пропускная способность сети является ограниченным ресурсом, следует, по крайней мере, рассмотреть преимущества сжатия ответов.
Использовать сжатие ответов в приложениях .NET очень просто. Нужно вызвать два метода:
- AddResponseCompression – для настройки сервисов сжатия ответа;
- UseResponseCompression – для добавления промежуточного ПО сжатия ответа в конвейер.
Сжатие ответов по умолчанию отключено в HTTPS, поэтому его надо явно включить:
builder.ServicesКогда использовать
.AddResponseCompression(opts =>
{
opts.EnableForHttps = true;
});
В идеале лучше использовать серверное сжатие ответа, если ваш сервер приложений (IIS, Apache, Nginx) поддерживает его. Если сервер не поддерживает сжатие ответов, то оправдано использование промежуточного ПО. Однако т.к. оно происходит на уровне приложения, производительность обычно падает.
Еще одной проблемой является безопасность, т.к. использование сжатия ответов в HTTPS может подвергнуть вас атакам CRIME и BREACH. Вот что можно сделать, чтобы защититься от них:
- Добавить токены защиты от подделки (anti-forgery).
- Не отправлять секреты приложения в теле запроса.
- Добавить ограничитель трафика
Настройка провайдеров сжатия
При вызове AddResponseCompression по умолчанию добавляются два провайдера сжатия (но можно добавить свои в настройках AddResponseCompression):
- BrotliCompressionProvider
- GzipCompressionProvider
По умолчанию используется сжатие Brotli, если оно поддерживается клиентом. В противном случае будет использоваться Gzip. Можно настроить уровень сжатия для Brotli и Gzip:
- Optimal,
- Fastest (по умолчанию),
- NoCompression,
- SmallestSize.
builder.ServicesЗаметим, что уровень SmallestSize ожидаемо имеет сильное негативное влияние на время ответа.
.Configure<BrotliCompressionProviderOptions>(opts =>
{
opts.Level = CompressionLevel.Optimal;
});
Итого
Сжатие ответов — хороший метод повышения производительности API и снижения сетевых затрат. В идеале желательно использовать серверное сжатие ответов, если оно поддерживается вашим сервером приложений. Если нет, сжатие ответов в приложении доступно в .NET через промежуточное ПО.
Это увеличивает нагрузку на ЦП и может подвергнуть HTTPS некоторым рискам безопасности, но есть способы смягчить это.
Обычно конфигурации по умолчанию для провайдера сжатия и уровня сжатия дают отличные результаты.
Вы можете протестировать значение сжатия ответа в своём приложении и изучить изменения в размере и времени ответа. Попробуйте разные провайдеры сжатия, изменяя заголовок Accept-Encoding клиента, а также настраивая разные уровни сжатия в приложении.
Источник: https://www.milanjovanovic.tech/blog/response-compression-in-aspnetcore
👍10
День 1614. #ЧтоНовенького
Новинки Превью 5 .NET 8
Продолжаем рассматривать, что нового появилось в превью 5 8й версии .NET.
1. IHttpSysRequestTimingFeature
Новый интерфейс IHttpSysRequestTimingFeature предоставляет подробные данные о временных метках, связанных с обработкой запросов при использовании сервера HTTP.sys. Раньше информация о запросе HTTP.sys предоставлялась через интерфейс IHttpSysRequestInfoFeature. С добавлением IHttpSysRequestTimingFeature мы движемся к более чётко определённым API, которые обеспечивают лучший доступ к данным о времени запроса.
Метод TryGetTimestamp извлекает метку времени для предоставленного типа времени, а метод TryGetElapsedTime даёт время, прошедшее между двумя указанными временами.
Это усовершенствование предоставляет разработчикам:
- Более детальное понимание различных этапов обработки запросов.
- Возможности точной диагностики производительности.
- Улучшенный доступ к данным о времени запросов HTTP.sys и контроль над ними.
2. Имя хоста в ITlsHandshakeFeature
Имя хоста Server Name Indication (SNI) теперь доступно в интерфейсе ITlsHandshakeFeature.
Предоставление имени хоста особенно полезно для крупномасштабных сервисов, управляющих тысячами привязок SNI. С помощью этой функции вы получаете ценную информацию о выбранном SNI во время TLS-рукопожатия, тем самым значительно улучшая свои возможности отладки при росте количества клиентов. Это позволяет быстрее решать проблемы и повышать надёжность обслуживания.
Источник: https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-5/#servers
Новинки Превью 5 .NET 8
Продолжаем рассматривать, что нового появилось в превью 5 8й версии .NET.
1. IHttpSysRequestTimingFeature
Новый интерфейс IHttpSysRequestTimingFeature предоставляет подробные данные о временных метках, связанных с обработкой запросов при использовании сервера HTTP.sys. Раньше информация о запросе HTTP.sys предоставлялась через интерфейс IHttpSysRequestInfoFeature. С добавлением IHttpSysRequestTimingFeature мы движемся к более чётко определённым API, которые обеспечивают лучший доступ к данным о времени запроса.
namespace Microsoft.AspNetCore.Server.HttpSysСвойство Timestamps предоставляет доступ ко всем временным меткам HTTP.sys. Временные метки получаются с помощью QueryPerformanceCounter, а частота временных меток может быть определена с помощью QueryPerformanceFrequency.
{
public interface IHttpSysRequestTimingFeature
{
ReadOnlySpan<long> Timestamps { get; }
bool TryGetTimestamp(
HttpSysRequestTimingType timestampType,
out long timestamp);
bool TryGetElapsedTime(
HttpSysRequestTimingType startingTimestampType,
HttpSysRequestTimingType endingTimestampType,
out TimeSpan elapsed);
}
}
Метод TryGetTimestamp извлекает метку времени для предоставленного типа времени, а метод TryGetElapsedTime даёт время, прошедшее между двумя указанными временами.
Это усовершенствование предоставляет разработчикам:
- Более детальное понимание различных этапов обработки запросов.
- Возможности точной диагностики производительности.
- Улучшенный доступ к данным о времени запросов HTTP.sys и контроль над ними.
2. Имя хоста в ITlsHandshakeFeature
Имя хоста Server Name Indication (SNI) теперь доступно в интерфейсе ITlsHandshakeFeature.
/// <summary>SNI является частью процесса TLS-рукопожатия и позволяет клиентам указывать имя хоста, к которому они пытаются подключиться. Это позволяет серверам, на которых размещается несколько виртуальных хостов или доменов, предоставлять правильный сертификат безопасности во время процесса установки связи, следовательно, позволяет работать нескольким HTTPS-сайтам (или другим сервисам поверх TLS) на одном IP-адресе без использования одного и того же сертификата для всех сайтов. Обычно SNI обрабатывается только в стеке TLS и используется для выбора соответствующего сертификата, но теперь раскрытие имени хоста позволяет другим компонентам приложения использовать эту информацию для диагностики, ограничения скорости, маршрутизации и т. д.
/// Gets the host name from the "server_name" (SNI) extension of the client hello if present.
/// See <see href="https://www.rfc-editor.org/rfc/rfc6066#section-3">RFC 6066</see>.
/// </summary>
string? HostName => null;
Предоставление имени хоста особенно полезно для крупномасштабных сервисов, управляющих тысячами привязок SNI. С помощью этой функции вы получаете ценную информацию о выбранном SNI во время TLS-рукопожатия, тем самым значительно улучшая свои возможности отладки при росте количества клиентов. Это позволяет быстрее решать проблемы и повышать надёжность обслуживания.
Источник: https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-5/#servers
👍8
День 1615. #ЗаметкиНаПолях
Разбираем и Оптимизируем SQL-Запросы. Начало
Сегодня разберём, как SQL-запросы выполняются механизмом базы данных и как мы можем использовать эти знания для оптимизации запросов.
Порядок выполнения SQL — это фактическая последовательность, в которой механизм БД обрабатывает различные компоненты запроса. Он может серьёзно отличаться от порядка написания запроса. Так ядро БД может свести к минимуму дисковый ввод-вывод, эффективно использовать индексы и избежать ненужных операций. Рассмотрим запрос:
1. FROM: определение таблиц, задействованных в запросе (customers и orders).
2. JOIN: выполнение операции соединения на основе условия соединения (customers.id = orders.customer_id).
3. WHERE: применение условия фильтрации к объединённой таблице (order_date >= '2023-01-01'), которое отбирает только заказы, сделанные 1 января 2023 года или позже.
4. GROUP BY: группировка строк по указанным столбцам (customers.name).
5. HAVING: фильтрация групп по условию (total_spent >= 1000), при котором выбираются только клиенты с общей потраченной суммой 1000 и более.
6. SELECT: выбор столбцов и агрегатных функций из каждой группы (customers.name, COUNT(order_id) и SUM(order_amount)).
7. ORDER BY: сортировка строк по указанным столбцам (customers.name).
8. LIMIT: ограничение результата максимум 100 строками.
Запросы SARGABLE
SARGABLE (Searched ARGUment ABLE) - это запрос, который может использовать индексы для более быстрого выполнения. Запрос SARGABLE использует операторы и функции, которые могут использовать преимущества индексов. Например, использование операторов равенства (=), неравенства (<>, !=), диапазона (BETWEEN) или членства (IN) в индексированных столбцах может сделать запрос пригодным для поиска.
Запрос не является SARGABLE, если он использует операторы или функции, которые препятствуют использованию индекса или требуют полного сканирования таблицы. Например, использование операторов отрицания (NOT), подстановочных знаков (LIKE) или арифметических операций (+, -, *, /) в индексированных столбцах может сделать запрос недоступным для поиска.
Чтобы написать SARGABLE-запрос, обычно нужно ИЗБЕГАТЬ использования следующих конструкций в предложении WHERE:
1. Функций для индексированных столбцов: UPPER(), LOWER(), SUBSTRING() и т. д.
2. Арифметических операций над индексированными столбцами: столбец + 1 > 10, столбец * 2 < 20 и т. д.
3. Операторов отрицания для индексированных столбцов: NOT IN, NOT LIKE, NOT EXISTS и т. д.
4. Ведущих подстановочных знаков в индексированных столбцах: LIKE '%abc', LIKE '%xyz%' и т. д.
5. Неявных преобразований типов, которые могут повлиять на использование индекса.
Замечание: некоторые СУБД могут эффективно обрабатывать такие запросы и использовать индексы, а также некоторые виды индексов специально предназначены для таких запросов, но в общем случае полагаться на это не стоит.
Окончание следует…
Источник: https://dev.to/kanani_nirav/secret-to-optimizing-sql-queries-understand-the-sql-execution-order-28m1
Разбираем и Оптимизируем SQL-Запросы. Начало
Сегодня разберём, как SQL-запросы выполняются механизмом базы данных и как мы можем использовать эти знания для оптимизации запросов.
Порядок выполнения SQL — это фактическая последовательность, в которой механизм БД обрабатывает различные компоненты запроса. Он может серьёзно отличаться от порядка написания запроса. Так ядро БД может свести к минимуму дисковый ввод-вывод, эффективно использовать индексы и избежать ненужных операций. Рассмотрим запрос:
SELECT customers.name,Порядок выполнения этого запроса следующий:
COUNT(order_id) as Total_orders,
SUM(order_amount) as total_spent
FROM customers
JOIN orders ON customers.id = orders.customer_id
WHERE order_date >= '2023-01-01'
GROUP BY customers.name
HAVING total_spent >= 1000
ORDER BY customers.name
LIMIT 100;
1. FROM: определение таблиц, задействованных в запросе (customers и orders).
2. JOIN: выполнение операции соединения на основе условия соединения (customers.id = orders.customer_id).
3. WHERE: применение условия фильтрации к объединённой таблице (order_date >= '2023-01-01'), которое отбирает только заказы, сделанные 1 января 2023 года или позже.
4. GROUP BY: группировка строк по указанным столбцам (customers.name).
5. HAVING: фильтрация групп по условию (total_spent >= 1000), при котором выбираются только клиенты с общей потраченной суммой 1000 и более.
6. SELECT: выбор столбцов и агрегатных функций из каждой группы (customers.name, COUNT(order_id) и SUM(order_amount)).
7. ORDER BY: сортировка строк по указанным столбцам (customers.name).
8. LIMIT: ограничение результата максимум 100 строками.
Запросы SARGABLE
SARGABLE (Searched ARGUment ABLE) - это запрос, который может использовать индексы для более быстрого выполнения. Запрос SARGABLE использует операторы и функции, которые могут использовать преимущества индексов. Например, использование операторов равенства (=), неравенства (<>, !=), диапазона (BETWEEN) или членства (IN) в индексированных столбцах может сделать запрос пригодным для поиска.
Запрос не является SARGABLE, если он использует операторы или функции, которые препятствуют использованию индекса или требуют полного сканирования таблицы. Например, использование операторов отрицания (NOT), подстановочных знаков (LIKE) или арифметических операций (+, -, *, /) в индексированных столбцах может сделать запрос недоступным для поиска.
Чтобы написать SARGABLE-запрос, обычно нужно ИЗБЕГАТЬ использования следующих конструкций в предложении WHERE:
1. Функций для индексированных столбцов: UPPER(), LOWER(), SUBSTRING() и т. д.
2. Арифметических операций над индексированными столбцами: столбец + 1 > 10, столбец * 2 < 20 и т. д.
3. Операторов отрицания для индексированных столбцов: NOT IN, NOT LIKE, NOT EXISTS и т. д.
4. Ведущих подстановочных знаков в индексированных столбцах: LIKE '%abc', LIKE '%xyz%' и т. д.
5. Неявных преобразований типов, которые могут повлиять на использование индекса.
Замечание: некоторые СУБД могут эффективно обрабатывать такие запросы и использовать индексы, а также некоторые виды индексов специально предназначены для таких запросов, но в общем случае полагаться на это не стоит.
Окончание следует…
Источник: https://dev.to/kanani_nirav/secret-to-optimizing-sql-queries-understand-the-sql-execution-order-28m1
👍22
День 1615. #ЗаметкиНаПолях
Разбираем и Оптимизируем SQL-Запросы. Окончание
Начало
Настройка производительности на уровне БД
Повышение производительности в порядке выполнения SQL включает в себя оптимизацию шагов, выполняемых ядром БД для обработки и выполнения SQL-запросов. Вот несколько способов повысить производительность в порядке выполнения SQL:
1. Используйте соответствующие индексы: проанализируйте шаблоны запросов и определите столбцы, часто используемые в операциях поиска, объединения и фильтрации. Создайте индексы для этих столбцов для более быстрого извлечения данных и уменьшения потребности в полном сканировании таблиц.
2. Используйте покрывающие индексы: по возможности добавьте в индекс все столбцы, которые требуются для выполнения запроса. Тогда ядро БД для выполнения запроса просканирует только индекс (INDEX ONLY SCAN в плане выполнения запроса), вообще не обращаясь к таблице. Например, если у вас есть индекс таблицы клиентов по дате рождения, а в запросе нужно вывести имена клиентов определённого года рождения, имеет смысл добавить поля имени в индекс. Это несколько увеличит накладные расходы на индекс и его обновление, зато запрос, извлекающий только имя по дате рождения, будет сканировать только индекс и выполняться значительно быстрее. В противном случае имя клиента должно будет извлекаться из таблицы по ссылке для каждой строки индекса (INDEX SCAN в плане выполнения запроса), что обычно быстрее полного сканирования таблицы (FULL TABLE SCAN), но медленнее сканирования только индекса.
3. Оптимизируйте операции соединения: убедитесь, что условия соединения эффективны, и используйте соответствующие индексы. По возможности используйте INNER JOIN вместо OUTER JOIN, поскольку это обычно приводит к повышению производительности. Рассмотрите порядок соединения нескольких таблиц, чтобы свести к минимуму размер промежуточного набора результатов.
4. Ограничьте размер набора результатов: используйте предложение LIMIT, чтобы ограничить количество строк, возвращаемых запросом. Это может уменьшить объём обрабатываемых данных и сократить время ответа на запрос.
5. Избегайте ненужной сортировки и группировки: устраните ненужные операции сортировки и группировки, добавляя их только при необходимости. Этого можно добиться путем тщательного анализа запроса и удаления ненужных предложений ORDER BY и GROUP BY.
6. Используйте раннюю фильтрация в предложении WHERE: применяйте условия фильтрации как можно раньше в порядке выполнения запроса с помощью предложения WHERE. Это уменьшит количество строк, обрабатываемых на последующих этапах, повышая производительность. Также используйте наиболее ограничивающие условия первыми в предложении WHERE.
7. Используйте подходящие типы данных: выберите правильные типы данных для столбцов, чтобы обеспечить эффективное хранение и извлечение данных. Использование соответствующих типов данных может помочь сократить потребление памяти и повысить скорость выполнения запросов.
8. Избегайте ненужных вычислений и функций: сведите к минимуму использование вычислений и функций в запросе, особенно в индексированных столбцах. Эти операции могут препятствовать использованию индекса и влиять на производительность. Рассмотрите возможность предварительного вычисления значений или использования производных столбцов, когда это необходимо.
9. Используйте инструменты оптимизации запросов: инструменты или подсказки оптимизатора запросов для конкретной базы данных помогут механизму базы данных создавать эффективные планы выполнения. Эти инструменты могут предоставить информацию, рекомендации и статистику для повышения производительности.
Итого
Порядок выполнения SQL влияет на производительность запросов и эффективность базы данных. Мы можем улучшить производительность с помощью индексации, эффективных объединений, фильтрации, SARGABLE-запросов и лучших практик.
Источник: https://dev.to/kanani_nirav/secret-to-optimizing-sql-queries-understand-the-sql-execution-order-28m1
Разбираем и Оптимизируем SQL-Запросы. Окончание
Начало
Настройка производительности на уровне БД
Повышение производительности в порядке выполнения SQL включает в себя оптимизацию шагов, выполняемых ядром БД для обработки и выполнения SQL-запросов. Вот несколько способов повысить производительность в порядке выполнения SQL:
1. Используйте соответствующие индексы: проанализируйте шаблоны запросов и определите столбцы, часто используемые в операциях поиска, объединения и фильтрации. Создайте индексы для этих столбцов для более быстрого извлечения данных и уменьшения потребности в полном сканировании таблиц.
2. Используйте покрывающие индексы: по возможности добавьте в индекс все столбцы, которые требуются для выполнения запроса. Тогда ядро БД для выполнения запроса просканирует только индекс (INDEX ONLY SCAN в плане выполнения запроса), вообще не обращаясь к таблице. Например, если у вас есть индекс таблицы клиентов по дате рождения, а в запросе нужно вывести имена клиентов определённого года рождения, имеет смысл добавить поля имени в индекс. Это несколько увеличит накладные расходы на индекс и его обновление, зато запрос, извлекающий только имя по дате рождения, будет сканировать только индекс и выполняться значительно быстрее. В противном случае имя клиента должно будет извлекаться из таблицы по ссылке для каждой строки индекса (INDEX SCAN в плане выполнения запроса), что обычно быстрее полного сканирования таблицы (FULL TABLE SCAN), но медленнее сканирования только индекса.
3. Оптимизируйте операции соединения: убедитесь, что условия соединения эффективны, и используйте соответствующие индексы. По возможности используйте INNER JOIN вместо OUTER JOIN, поскольку это обычно приводит к повышению производительности. Рассмотрите порядок соединения нескольких таблиц, чтобы свести к минимуму размер промежуточного набора результатов.
4. Ограничьте размер набора результатов: используйте предложение LIMIT, чтобы ограничить количество строк, возвращаемых запросом. Это может уменьшить объём обрабатываемых данных и сократить время ответа на запрос.
5. Избегайте ненужной сортировки и группировки: устраните ненужные операции сортировки и группировки, добавляя их только при необходимости. Этого можно добиться путем тщательного анализа запроса и удаления ненужных предложений ORDER BY и GROUP BY.
6. Используйте раннюю фильтрация в предложении WHERE: применяйте условия фильтрации как можно раньше в порядке выполнения запроса с помощью предложения WHERE. Это уменьшит количество строк, обрабатываемых на последующих этапах, повышая производительность. Также используйте наиболее ограничивающие условия первыми в предложении WHERE.
7. Используйте подходящие типы данных: выберите правильные типы данных для столбцов, чтобы обеспечить эффективное хранение и извлечение данных. Использование соответствующих типов данных может помочь сократить потребление памяти и повысить скорость выполнения запросов.
8. Избегайте ненужных вычислений и функций: сведите к минимуму использование вычислений и функций в запросе, особенно в индексированных столбцах. Эти операции могут препятствовать использованию индекса и влиять на производительность. Рассмотрите возможность предварительного вычисления значений или использования производных столбцов, когда это необходимо.
9. Используйте инструменты оптимизации запросов: инструменты или подсказки оптимизатора запросов для конкретной базы данных помогут механизму базы данных создавать эффективные планы выполнения. Эти инструменты могут предоставить информацию, рекомендации и статистику для повышения производительности.
Итого
Порядок выполнения SQL влияет на производительность запросов и эффективность базы данных. Мы можем улучшить производительность с помощью индексации, эффективных объединений, фильтрации, SARGABLE-запросов и лучших практик.
Источник: https://dev.to/kanani_nirav/secret-to-optimizing-sql-queries-understand-the-sql-execution-order-28m1
👍12
День 1617. #ЗаметкиНаПолях
Отслеживание Кликов по Ссылке на HTML-Странице
Существует множество способов отслеживать, когда пользователь щёлкает по ссылке на HTML-странице. Большинство из них требуют JS-скрипта и регистрации события click для элемента <a>. Совсем недавно в элемент <a> был добавлен атрибут ping. Он позволяет указать URL-адрес, на который будет отправлен ping-запрос при нажатии на ссылку. Таким образом отпадает необходимость в JS-скрипте.
Атрибут ping хорошо поддерживается. Только Firefox отключил эту функцию по умолчанию. Кроме того, блокировщики рекламы могут заблокировать ping-запрос (так же как они блокируют некоторые JS-скрипты). Поэтому, глобальная поддержка функции составляет около 93%.
Использование атрибута ping даёт некоторые преимущества:
- работает, когда JavaScript отключен,
- ping-запросы являются фоновыми, т.е., когда пользователь покидает страницу, запрос ping не будет прерван.
- тело ответа на ping-запрос игнорируется; браузеру разрешено немедленно завершать соединение, когда сервер отправляет тело ответа. Это помогает экономить ресурсы сервера и браузера.
- ping-запросы не кэшируются, так как это POST-запрос, поэтому каждый ping приводит к запросу на сервер.
Вот пример использования атрибута ping:
Если вам нужно различить несколько ссылок на одной странице, можно использовать параметр строки запроса. Например, если у вас есть две ссылки на одной странице, вы можете использовать
Источник: https://www.meziantou.net/tracking-click-on-anchors-in-an-html-page.htm
Отслеживание Кликов по Ссылке на HTML-Странице
Существует множество способов отслеживать, когда пользователь щёлкает по ссылке на HTML-странице. Большинство из них требуют JS-скрипта и регистрации события click для элемента <a>. Совсем недавно в элемент <a> был добавлен атрибут ping. Он позволяет указать URL-адрес, на который будет отправлен ping-запрос при нажатии на ссылку. Таким образом отпадает необходимость в JS-скрипте.
Атрибут ping хорошо поддерживается. Только Firefox отключил эту функцию по умолчанию. Кроме того, блокировщики рекламы могут заблокировать ping-запрос (так же как они блокируют некоторые JS-скрипты). Поэтому, глобальная поддержка функции составляет около 93%.
Использование атрибута ping даёт некоторые преимущества:
- работает, когда JavaScript отключен,
- ping-запросы являются фоновыми, т.е., когда пользователь покидает страницу, запрос ping не будет прерван.
- тело ответа на ping-запрос игнорируется; браузеру разрешено немедленно завершать соединение, когда сервер отправляет тело ответа. Это помогает экономить ресурсы сервера и браузера.
- ping-запросы не кэшируются, так как это POST-запрос, поэтому каждый ping приводит к запросу на сервер.
Вот пример использования атрибута ping:
<a href="/demo" ping="/ping">Demo</a>Вы можете обработать этот ping-запрос в вашем приложении ASP.NET Core application. Например:
app.MapPost("/ping",В примере выше заголовки ping-from и ping-to выдают исходный URL и запрашиваемый URL (указанный в атрибуте href) соответственно.
([FromHeader(Name = "ping-from")]string from,
[FromHeader(Name = "ping-to")] string to) =>
{
// обрабатываем ping-запрос
return Results.Ok();
});
Если вам нужно различить несколько ссылок на одной странице, можно использовать параметр строки запроса. Например, если у вас есть две ссылки на одной странице, вы можете использовать
<a ping="/ping?id=Link1">
и <a ping="/ping?id=Link2">
, чтобы различать их.Источник: https://www.meziantou.net/tracking-click-on-anchors-in-an-html-page.htm
👍17
День 1618. #ЗаметкиНаПолях
LINQ: Select.Where или Where.Select?
LINQ — очень мощный инструмент для запросов данных. Поскольку большинство функций построены на основе IEnumerable<T> и в большинстве случаев он также возвращает IEnumerable<T>, очень легко объединять несколько функций в цепочку. Возникает вопрос: есть ли разница между Select.Where или Where.Select?
Сначала замечу, что далее мы рассматриваем только коллекции «в памяти», и не IQueryable<T>. Там порядок зависит в основном от провайдера, поэтому Entity Framework и LINQ to SQL могут давать разные результаты.
Рассмотрим следующий пример кода:
Скорее всего, первый, т.к. второй вариант создаст анонимный тип для всех пользователей, даже для тех, кто не является студентом. Т.е. второму варианту придётся проделать больше работы. Для больших списков разница может быть значительна. Как правило, всегда нужно пытаться отфильтровать как можно больше, прежде чем начинать создавать новые объекты. Аналогично с OrderBy. Если список предварительно не фильтруется, OrderBy должен будет проверить гораздо больше записей.
А теперь рассмотрим такой пример:
Если всё же не обойтись без нескольких предложений Where, имеет смысл поставить лучший фильтр в начале, либо попробовать реорганизовать все фильтры в один метод:
LINQ: Select.Where или Where.Select?
LINQ — очень мощный инструмент для запросов данных. Поскольку большинство функций построены на основе IEnumerable<T> и в большинстве случаев он также возвращает IEnumerable<T>, очень легко объединять несколько функций в цепочку. Возникает вопрос: есть ли разница между Select.Where или Where.Select?
Сначала замечу, что далее мы рассматриваем только коллекции «в памяти», и не IQueryable<T>. Там порядок зависит в основном от провайдера, поэтому Entity Framework и LINQ to SQL могут давать разные результаты.
Рассмотрим следующий пример кода:
var users = GetAllUsers();Результат обоих запросов будет одинаковым. Но это не означает, что они делают одно и то же. Первый вариант сначала отфильтрует всех пользователей, которые не являются студентами, а затем создаст анонимный тип. Второй вариант сначала создаст анонимный тип для всех пользователей, а затем отфильтрует тех, кто не является студентами. Какой запрос быстрее?
// Вариант 1
users.Where(u => u.IsStudent)
.Select(u =>
new { u.FirstName, u.LastName, u.IsStudent });
// Вариант 2
users.Select(u =>
new { u.FirstName, u.LastName, u.IsStudent })
.Where(u => u.IsStudent);
Скорее всего, первый, т.к. второй вариант создаст анонимный тип для всех пользователей, даже для тех, кто не является студентом. Т.е. второму варианту придётся проделать больше работы. Для больших списков разница может быть значительна. Как правило, всегда нужно пытаться отфильтровать как можно больше, прежде чем начинать создавать новые объекты. Аналогично с OrderBy. Если список предварительно не фильтруется, OrderBy должен будет проверить гораздо больше записей.
А теперь рассмотрим такой пример:
// вариант 1Опять же семантически они делают одно и то же. Результат будет одинаковым, но способ его достижения - разным. Первый вариант сразу проверит оба условия. Второй вариант (хотя это и не очевидно) также пройдёт по списку только один раз, но здесь возникнут дополнительные накладные расходы на вызов нескольких функций. Кстати, автор оригинальной статьи (см. источник ниже) считает, что этими расходами можно пренебречь. Однако, судя по моим бенчмаркам (см. картинку ниже) разница в некоторых средах может быть довольно существенной (хотя, в .NET 8 выполнение заметно оптимизировали).
users.Where(u => u.IsStudent && u.Age > 30);
// вариант 2
users.Where(u => u.IsStudent)
.Where(u => u.Age > 30);
Если всё же не обойтись без нескольких предложений Where, имеет смысл поставить лучший фильтр в начале, либо попробовать реорганизовать все фильтры в один метод:
private bool IsStudentAndOlderThan30(User user)Источник: https://steven-giesel.com/blogPost/57ed9867-4afd-4d02-9f35-e0941bc6f715
{
return user.IsStudent && user.Age > 30;
}
users.Where(IsStudentAndOlderThan30);
👍21
День 1619. #ЗаметкиНаПолях
Время в .NET. Начало
Время – важная часть наших программ. Отслеживание часовых поясов и тестирование кода, зависящего от времени, - вечная головная боль разработчиков.
История
DateTime была основной структурой для хранения даты и времени в .NET, начиная с версии 1.1. У неё есть большой недостаток - отсутствие часового пояса. Чтобы решить эту проблему, было добавлено свойство Kind с возможными значениями: Local (по умолчанию), Utc или Unspecified.
Для конвертации в UTC нужно вызвать метод ToUniversalTime() или использовать свойство DateTime.UtcNow. Как .NET понимает разницу в часовых поясах, если DateTime не предоставляет эту информацию? Метод ToUniversalTime берёт часовой пояс из операционной системы, что может приводить к проблемам. Если создать локальное время на сервере в одном часовом поясе, а потом переместить его на другой сервер (например, на клиента API), то результат вызова ToUniversalTime на этих серверах будут разным.
Поэтому Microsoft выпустили «Рекомендации по написанию кода с использованием даты и времени в платформе .NET Framework», переложив всю ответственность на разработчиков:
«Разработчик несёт ответственность за отслеживание информации о часовом поясе, связанным со значением DateTime, с помощью некоторого внешнего механизма. Обычно это достигается путём определения другого поля или переменной, которые вы используете для записи информации о часовом поясе при сохранении значения типа DateTime.»
.NET ожидает, что информация о часовом поясе будет связана со свойством Kind во время восстановления даты и времени: DateTimeKind.Local с TimeZoneInfo.Local, DateTimeKind.Utc с TimeZoneInfo.Utc и DateTimeKind.Unspecified в остальных случаях. Пользовательский часовой пояс, как рекомендует Microsoft, требует использования DateTimeKind.Unspecified:
В .NET 2 была введена структура DateTimeOffset. Она состоит из:
- структуры DateTime
- свойства Offset, хранящего смещение относительно UTC.
Однако проблема с серверами в разных часовых поясах никак не решается через DateTimeOffset.Now. Всё дело в переходе на летнее время. Для разных дат смещение в одном и том же часовом поясе будет разным. Кроме того, правила перехода на летнее время могут меняться (нам ли в РФ не знать). А значит невозможно определить происхождение даты и времени, просто взглянув на значение смещения. Поэтому для международного ПО лучше хранить часовой пояс для возможного пересчёта смещения по новым правилам. Для этого подходит класс TimeZoneInfo.
Окончание следует…
Источник: https://www.infoq.com/articles/dotnet-unit-tests-time-timezone/
Время в .NET. Начало
Время – важная часть наших программ. Отслеживание часовых поясов и тестирование кода, зависящего от времени, - вечная головная боль разработчиков.
История
DateTime была основной структурой для хранения даты и времени в .NET, начиная с версии 1.1. У неё есть большой недостаток - отсутствие часового пояса. Чтобы решить эту проблему, было добавлено свойство Kind с возможными значениями: Local (по умолчанию), Utc или Unspecified.
Для конвертации в UTC нужно вызвать метод ToUniversalTime() или использовать свойство DateTime.UtcNow. Как .NET понимает разницу в часовых поясах, если DateTime не предоставляет эту информацию? Метод ToUniversalTime берёт часовой пояс из операционной системы, что может приводить к проблемам. Если создать локальное время на сервере в одном часовом поясе, а потом переместить его на другой сервер (например, на клиента API), то результат вызова ToUniversalTime на этих серверах будут разным.
Поэтому Microsoft выпустили «Рекомендации по написанию кода с использованием даты и времени в платформе .NET Framework», переложив всю ответственность на разработчиков:
«Разработчик несёт ответственность за отслеживание информации о часовом поясе, связанным со значением DateTime, с помощью некоторого внешнего механизма. Обычно это достигается путём определения другого поля или переменной, которые вы используете для записи информации о часовом поясе при сохранении значения типа DateTime.»
.NET ожидает, что информация о часовом поясе будет связана со свойством Kind во время восстановления даты и времени: DateTimeKind.Local с TimeZoneInfo.Local, DateTimeKind.Utc с TimeZoneInfo.Utc и DateTimeKind.Unspecified в остальных случаях. Пользовательский часовой пояс, как рекомендует Microsoft, требует использования DateTimeKind.Unspecified:
var nowInNY = DateTime.Now;Альтернативным решением будет создавать и хранить дату только в UTC:
var nyTZ = TimeZoneInfo
.FindSystemTimeZoneById("Eastern Standard Time");
nowInNY = DateTime
.SpecifyKind(nowInNY, DateTimeKind.Unspecified);
var utc = TimeZoneInfo
.ConvertTimeToUtc(nowInNY, nyTZ);
var utc = DateTime.UtcNow;и преобразовывать её в локальную:
var localTime = utc.ToLocalTime();или в нужный часовой пояс:
var nyTime = TimeZoneInfoЭто требует дополнительных проверок на предмет случайного использования DateTime с локальной инициализацией через DateTime.Now, а также не исключает таких нюансов, как изменение правил перехода на летнее время.
.ConvertTimeFromUtc(utc, nyTZ);
В .NET 2 была введена структура DateTimeOffset. Она состоит из:
- структуры DateTime
- свойства Offset, хранящего смещение относительно UTC.
Однако проблема с серверами в разных часовых поясах никак не решается через DateTimeOffset.Now. Всё дело в переходе на летнее время. Для разных дат смещение в одном и том же часовом поясе будет разным. Кроме того, правила перехода на летнее время могут меняться (нам ли в РФ не знать). А значит невозможно определить происхождение даты и времени, просто взглянув на значение смещения. Поэтому для международного ПО лучше хранить часовой пояс для возможного пересчёта смещения по новым правилам. Для этого подходит класс TimeZoneInfo.
Окончание следует…
Источник: https://www.infoq.com/articles/dotnet-unit-tests-time-timezone/
👍18
День 1620. #ЗаметкиНаПолях #ЧтоНовенького
Время в .NET. Окончание
Начало
Юнит-Тесты
Для тестирования важно иметь возможность имитировать вызов метода объекта с пользовательской реализацией. Поскольку DateTime и DateTimeOffset не имеют интерфейсов, можно создать пользовательскую абстракцию, а затем имитировать её во время тестов. Например, следующий интерфейс может предоставить абстракцию для DateTimeOffset:
В .NET 8 были добавлены долгожданные абстракции времени: абстрактный класс TimeProvider и интерфейс ITimer. Они не безупречны, но это значительный прогресс.
Недостатки TimeProvider
1. Абстрактный класс получился громоздким. Не зная внутренних деталей класса, зависящего от TimeProvider, невозможно решить, какие его члены надо имитировать: GetUtcNow(), GetLocalNow(), CreateTimer(...) или все сразу. Разработчики предложили разбить новый тип на небольшие интерфейсы, но идея была отвергнута.
2. Экземпляр TimeProvider можно создать с помощью статического члена TimeProvider.System. Его легко использовать, хотя он не сильно отличается от DateTime.Now. В дальнейшем это приведёт к проблемам с написанием юнит-тестов, поэтому ожидается, что разработчики будут внедрять абстрактный TimeProvider в свои классы.
Преимущества TimeProvider и ITimer
1. Юнит-тесты сервисов, зависящих от времени, стали более универсальными. TimeProvider был добавлен в BCL и поддерживается в широком спектре сред выполнения .NET.
2. Команда Microsoft исправила в новой реализации старую ошибку, DateTime.Now было ошибочно введено как свойство вместо функции DateTime.Now(), поскольку по рекомендации Microsoft свойства не должны иметь побочных эффектов. TimeProvider правильно использует функции и методы: GetUtcNow(), GetLocalNow(), GetTimestamp() и т. д.
3. Можно тестировать события временных рядов с помощью функций TimeProvider.CreateTimer(...) и Timer.Change(...). Это особенно важно для вызовов функций Task.Delay(...) и Task.WaitAsync(...), которые теперь также принимают аргумент TimeProvider.
4. Планируется создать FakeTimeProvider как часть .NET для дальнейшего упрощения юнит-тестирования. Возможно, тогда пункт 2 из недостатков потеряет актуальность.
Стивен Тауб, инженер-программист Microsoft, надеется, что «в будущем почти никто не будет использовать ничего, кроме TimeProvider.System, в производственной среде. В отличие от многих других абстракций, эта особенная: она существует исключительно для возможности тестирования.»
Итого
Добавление класса TimeProvider в 4м превью .NET 8 определяет стандартизированную и унифицированную абстракцию для управления временем. Хотя он имеет ряд незначительных недостатков, команды Microsoft уже пометили свои интерфейсы времени ISystemClock как устаревшие и теперь выступают за внедрение TimeProvider.
Источник: https://www.infoq.com/articles/dotnet-unit-tests-time-timezone/
Время в .NET. Окончание
Начало
Юнит-Тесты
Для тестирования важно иметь возможность имитировать вызов метода объекта с пользовательской реализацией. Поскольку DateTime и DateTimeOffset не имеют интерфейсов, можно создать пользовательскую абстракцию, а затем имитировать её во время тестов. Например, следующий интерфейс может предоставить абстракцию для DateTimeOffset:
public interface ISystemClockАналогичный подход использовался внутри Microsoft, где один и тот же код был добавлен как минимум в четыре различных области .NET.
{
DateTimeOffset UtcNow { get; }
}
В .NET 8 были добавлены долгожданные абстракции времени: абстрактный класс TimeProvider и интерфейс ITimer. Они не безупречны, но это значительный прогресс.
Недостатки TimeProvider
1. Абстрактный класс получился громоздким. Не зная внутренних деталей класса, зависящего от TimeProvider, невозможно решить, какие его члены надо имитировать: GetUtcNow(), GetLocalNow(), CreateTimer(...) или все сразу. Разработчики предложили разбить новый тип на небольшие интерфейсы, но идея была отвергнута.
2. Экземпляр TimeProvider можно создать с помощью статического члена TimeProvider.System. Его легко использовать, хотя он не сильно отличается от DateTime.Now. В дальнейшем это приведёт к проблемам с написанием юнит-тестов, поэтому ожидается, что разработчики будут внедрять абстрактный TimeProvider в свои классы.
Преимущества TimeProvider и ITimer
1. Юнит-тесты сервисов, зависящих от времени, стали более универсальными. TimeProvider был добавлен в BCL и поддерживается в широком спектре сред выполнения .NET.
2. Команда Microsoft исправила в новой реализации старую ошибку, DateTime.Now было ошибочно введено как свойство вместо функции DateTime.Now(), поскольку по рекомендации Microsoft свойства не должны иметь побочных эффектов. TimeProvider правильно использует функции и методы: GetUtcNow(), GetLocalNow(), GetTimestamp() и т. д.
3. Можно тестировать события временных рядов с помощью функций TimeProvider.CreateTimer(...) и Timer.Change(...). Это особенно важно для вызовов функций Task.Delay(...) и Task.WaitAsync(...), которые теперь также принимают аргумент TimeProvider.
4. Планируется создать FakeTimeProvider как часть .NET для дальнейшего упрощения юнит-тестирования. Возможно, тогда пункт 2 из недостатков потеряет актуальность.
Стивен Тауб, инженер-программист Microsoft, надеется, что «в будущем почти никто не будет использовать ничего, кроме TimeProvider.System, в производственной среде. В отличие от многих других абстракций, эта особенная: она существует исключительно для возможности тестирования.»
Итого
Добавление класса TimeProvider в 4м превью .NET 8 определяет стандартизированную и унифицированную абстракцию для управления временем. Хотя он имеет ряд незначительных недостатков, команды Microsoft уже пометили свои интерфейсы времени ISystemClock как устаревшие и теперь выступают за внедрение TimeProvider.
Источник: https://www.infoq.com/articles/dotnet-unit-tests-time-timezone/
👍7
День 1621. #Оффтоп
Продолжая тему времени последних двух дней, сегодня порекомендую вам интересное видео от нашего старого знакомого системного инженера Microsoft, Дейва Пламера. В новом видео он рассказывает, почему системные часы Windows до недавних версий системы не отображали секунды.
https://youtu.be/qe1ltXdKMow
Лично я, помимо просто интересной истории и некоторых деталей реализации Windows, почерпнул для себя полезную идею о том, как правильно отображать «живое время» на сайте. В общем, не буду спойлерить, посмотрите, мне понравилось.
Продолжая тему времени последних двух дней, сегодня порекомендую вам интересное видео от нашего старого знакомого системного инженера Microsoft, Дейва Пламера. В новом видео он рассказывает, почему системные часы Windows до недавних версий системы не отображали секунды.
https://youtu.be/qe1ltXdKMow
Лично я, помимо просто интересной истории и некоторых деталей реализации Windows, почерпнул для себя полезную идею о том, как правильно отображать «живое время» на сайте. В общем, не буду спойлерить, посмотрите, мне понравилось.
👍7
День 1622. #ProjectManagement
Управляем Здоровьем Команды, Техническим Долгом и Предотвращаем Переписывание с Нуля. Начало
Обычно бывает так: опытная команда блестящих инженеров запускает новый продукт, клиентам нравится, фичи релизятся как из автомата. А спустя какое-то время внезапно продуктивность падает, выпускать новые функции всё сложнее, клиенты недовольны, инженеры устают от работы больше, чем когда-либо прежде, и призывают переписать всё с нуля. Время паники. Что случилось?
Первые признаки ухудшения
Команды похожи на огороды. Вначале растения мелкие, сорняков мало. Затем, из-за того, что вы не пропалывали, не поливали и не подкармливали, половина растений погибла, а другая превратилась в джунгли. Три вещи заставляют команды переходить в режим бурлаков:
- Первоначальные архитектурные решения были неверны или основывались на несовершенных предпосылках.
- Команда вынуждена выпускать продукт любой ценой, откладывая работу над техническим долгом.
- У команды нет системного плана решения проблем долга по мере роста системы.
Технический долг — убийца команд. Думайте о функциях и долге как о кредитной карте. Залезать в долги по кредитке каждый месяц — это нормально. Однако высокая процентная ставка разорит вас, если вы не выплатите долг.
Уменьшение объёмов предоставляемых функций при увеличении серьёзности возникающих проблем указывает на то, что команда в опасности. Если команда замедлилась с выпуска пяти средних и крупных функций в квартал до 1 функции с 3-кратным увеличением количества серьёзных ошибок за тот же период без изменений в составе команды, она движется к провалу. Задача для любого хорошего лидера в том, чтобы постоянно поддерживать минимальный уровень технического долга, позволяя команде продолжать выпускать функции.
Хорошая практика №1: постоянные обзоры архитектуры
Обзоры архитектуры распространены в начале проекта. Сначала команда придерживается надёжных архитектурных принципов, система не слишком сложна в обслуживании и т. д. Как только выходит версия 1.0, команда обычно прекращает рассмотрение новых функций с точки зрения влияния на архитектуру в пользу быстрой доставки. Это компромисс. Нет времени пересматривать архитектурные изменения. Но правильно ли это? Понимаем ли мы растущую систему?
Что делать?
Необходим официальный анализ архитектуры каждой новой функции среднего и крупного размера. Назначьте команде фиксированное время для рассмотрения влияния на архитектуру всех новых функций. 3-5 страниц или слайдов обзора с 1-3 диаграммами архитектуры вполне достаточно. Включите требование о проведении архитектурного анализа во все планы проекта. Все участвуют в рассмотрении, и все оценивают.
Зачем?
- Все в команде понимают, что делают все члены команды.
- Команда может взвесить технические компромиссы до того, как код будет написан и помещён в репозиторий — тогда обычно уже слишком поздно.
- Сложность системы и потенциальные проблемы со стабильностью, производительностью и масштабируемостью выявляются заранее.
- Команда создаёт архив диаграмм, чтобы будущим товарищам по команде было проще адаптироваться.
- Младшие инженеры узнают, как легко создавать более сложные системы.
Непрерывные обзоры архитектуры — первая защита от деградации проекта. В конечном счёте 30-минутная встреча в будущем сэкономит месяцы. Поэтому обозревайте архитектуру заранее, регулярно и используйте обзоры как средство раннего предупреждения.
Продолжение следует…
Источник: https://betterprogramming.pub/managing-team-health-tech-debt-and-avoiding-the-dreaded-rewrite-94878da7ca43
Управляем Здоровьем Команды, Техническим Долгом и Предотвращаем Переписывание с Нуля. Начало
Обычно бывает так: опытная команда блестящих инженеров запускает новый продукт, клиентам нравится, фичи релизятся как из автомата. А спустя какое-то время внезапно продуктивность падает, выпускать новые функции всё сложнее, клиенты недовольны, инженеры устают от работы больше, чем когда-либо прежде, и призывают переписать всё с нуля. Время паники. Что случилось?
Первые признаки ухудшения
Команды похожи на огороды. Вначале растения мелкие, сорняков мало. Затем, из-за того, что вы не пропалывали, не поливали и не подкармливали, половина растений погибла, а другая превратилась в джунгли. Три вещи заставляют команды переходить в режим бурлаков:
- Первоначальные архитектурные решения были неверны или основывались на несовершенных предпосылках.
- Команда вынуждена выпускать продукт любой ценой, откладывая работу над техническим долгом.
- У команды нет системного плана решения проблем долга по мере роста системы.
Технический долг — убийца команд. Думайте о функциях и долге как о кредитной карте. Залезать в долги по кредитке каждый месяц — это нормально. Однако высокая процентная ставка разорит вас, если вы не выплатите долг.
Уменьшение объёмов предоставляемых функций при увеличении серьёзности возникающих проблем указывает на то, что команда в опасности. Если команда замедлилась с выпуска пяти средних и крупных функций в квартал до 1 функции с 3-кратным увеличением количества серьёзных ошибок за тот же период без изменений в составе команды, она движется к провалу. Задача для любого хорошего лидера в том, чтобы постоянно поддерживать минимальный уровень технического долга, позволяя команде продолжать выпускать функции.
Хорошая практика №1: постоянные обзоры архитектуры
Обзоры архитектуры распространены в начале проекта. Сначала команда придерживается надёжных архитектурных принципов, система не слишком сложна в обслуживании и т. д. Как только выходит версия 1.0, команда обычно прекращает рассмотрение новых функций с точки зрения влияния на архитектуру в пользу быстрой доставки. Это компромисс. Нет времени пересматривать архитектурные изменения. Но правильно ли это? Понимаем ли мы растущую систему?
Что делать?
Необходим официальный анализ архитектуры каждой новой функции среднего и крупного размера. Назначьте команде фиксированное время для рассмотрения влияния на архитектуру всех новых функций. 3-5 страниц или слайдов обзора с 1-3 диаграммами архитектуры вполне достаточно. Включите требование о проведении архитектурного анализа во все планы проекта. Все участвуют в рассмотрении, и все оценивают.
Зачем?
- Все в команде понимают, что делают все члены команды.
- Команда может взвесить технические компромиссы до того, как код будет написан и помещён в репозиторий — тогда обычно уже слишком поздно.
- Сложность системы и потенциальные проблемы со стабильностью, производительностью и масштабируемостью выявляются заранее.
- Команда создаёт архив диаграмм, чтобы будущим товарищам по команде было проще адаптироваться.
- Младшие инженеры узнают, как легко создавать более сложные системы.
Непрерывные обзоры архитектуры — первая защита от деградации проекта. В конечном счёте 30-минутная встреча в будущем сэкономит месяцы. Поэтому обозревайте архитектуру заранее, регулярно и используйте обзоры как средство раннего предупреждения.
Продолжение следует…
Источник: https://betterprogramming.pub/managing-team-health-tech-debt-and-avoiding-the-dreaded-rewrite-94878da7ca43
👍13👎1
День 1623. #ProjectManagement
Управляем Здоровьем Команды, Техническим Долгом и Предотвращаем Переписывание с Нуля. Продолжение
Начало
Хорошая практика №2: Журнал ошибок и постоянные исправления
Журнал ошибок указывает на проблемы продукта. Разберитесь со списком ошибок. Это требует времени, но сделайте это всё равно.
Обработка ошибок – принудительная функция, как соглашение об уровне обслуживания (SLA), в котором мы объявляем обязательство по исправлению ошибок перед с нашими внутренними клиентами. И не все ошибки равны. Некоторые более сложны или более важны:
1. Система неработоспособна
- Затронуты все пользователи: Критическая ошибка - Исправлять немедленно!
- Некоторые пользователи: Серьёзная – 3-5 часов.
- Мало пользователей: Средняя – 2-3 дня.
2. Система сильно повреждена
- Все: Серьёзная – 3-5 часов.
- Некоторые: Средняя – 2-3 дня.
- Мало: Средняя – 2-3 дня.
3. У пользователей есть альтернативное решение
- Все: Серьёзная – 3-5 часов.
- Некоторые: Незначительная – 1-2 недели.
- Мало: В период исправления ошибок – 1 месяц.
4. Не влияет на систему
- Все: Незначительная – 1-2 недели.
- Некоторые: В период исправления ошибок – 1 месяц.
- Мало: Можно игнорировать
Журнал ошибок должен содержать список ошибок с их уровнем критичности. Кроме того, за состоянием проекта можно следить, отмечая на графике оценку количества ошибок с коэффициентом их критичности:
- Критическая – 2х
- Серьёзная – 1,5х
- Средняя – 1х
- Незначительная – 0,5х
Тогда, если на 1й неделе случилось 5 средних и одна серьёзная ошибка – это 5*1 + 1*1,5 = 6,5. На второй неделе 1 серьёзная и 6 незначительных – 1*1,5 + 6*0,5 = 4,5. Со временем этот график будет показывать состояние продукта.
Что делать?
- Определите SLA ошибки. Каждый продукт и каждая команда отличаются, но мы можем установить внутренние ожидания в отношении времени обработки для серьёзных, но не критических проблем. Мы быстро исправим серьёзные ошибки, а ошибки с более низким приоритетом будут исправлены или подвергнуты рефакторингу позже.
- Каждый спринт члены команды просматривают журнал ошибок и назначают исправления, чтобы обеспечить постоянный цикл исправления и сокращения количества ошибок.
- Сообщайте об исправлениях ошибок в заметках о выпуске, публикации во внутреннем чате или в каком-либо другом средстве. Например, сделайте «день выпуска отчёта об ошибках» и публикуйте этот отчёт.
- Используйте простые формулы для расчёта количества ошибок и удерживайте количество ошибок как можно более равномерным спринт за спринтом. Отслеживайте это желательно на общих дашбордах о состоянии проекта.
Зачем?
- Создаёт «систему раннего предупреждения». Команда привыкает к ритму и осознанию своих невыполненных работ по ошибкам и рабочей нагрузке. В результате разработчики могут определить, когда ошибки накапливаются, и спланировать их исправление.
- Внутренние клиенты имеют чёткие ожидания относительно того, когда появятся исправления ошибок, и у них есть возможность видеть работу команды.
- Команда узнаёт о горячих точках продукта раньше и может использовать эту информацию для следующего раунда планирования спринта. Чем короче время, чтобы избежать проблемы, тем меньше времени тратится впустую.
Примечание: сделайте так, чтобы ваши клиенты могли легко сообщать об ошибках! Не прячьте средство сообщения об ошибках, вы не всегда будете ловить ошибки в журналах.
Окончание следует…
Источник: https://betterprogramming.pub/managing-team-health-tech-debt-and-avoiding-the-dreaded-rewrite-94878da7ca43
Управляем Здоровьем Команды, Техническим Долгом и Предотвращаем Переписывание с Нуля. Продолжение
Начало
Хорошая практика №2: Журнал ошибок и постоянные исправления
Журнал ошибок указывает на проблемы продукта. Разберитесь со списком ошибок. Это требует времени, но сделайте это всё равно.
Обработка ошибок – принудительная функция, как соглашение об уровне обслуживания (SLA), в котором мы объявляем обязательство по исправлению ошибок перед с нашими внутренними клиентами. И не все ошибки равны. Некоторые более сложны или более важны:
1. Система неработоспособна
- Затронуты все пользователи: Критическая ошибка - Исправлять немедленно!
- Некоторые пользователи: Серьёзная – 3-5 часов.
- Мало пользователей: Средняя – 2-3 дня.
2. Система сильно повреждена
- Все: Серьёзная – 3-5 часов.
- Некоторые: Средняя – 2-3 дня.
- Мало: Средняя – 2-3 дня.
3. У пользователей есть альтернативное решение
- Все: Серьёзная – 3-5 часов.
- Некоторые: Незначительная – 1-2 недели.
- Мало: В период исправления ошибок – 1 месяц.
4. Не влияет на систему
- Все: Незначительная – 1-2 недели.
- Некоторые: В период исправления ошибок – 1 месяц.
- Мало: Можно игнорировать
Журнал ошибок должен содержать список ошибок с их уровнем критичности. Кроме того, за состоянием проекта можно следить, отмечая на графике оценку количества ошибок с коэффициентом их критичности:
- Критическая – 2х
- Серьёзная – 1,5х
- Средняя – 1х
- Незначительная – 0,5х
Тогда, если на 1й неделе случилось 5 средних и одна серьёзная ошибка – это 5*1 + 1*1,5 = 6,5. На второй неделе 1 серьёзная и 6 незначительных – 1*1,5 + 6*0,5 = 4,5. Со временем этот график будет показывать состояние продукта.
Что делать?
- Определите SLA ошибки. Каждый продукт и каждая команда отличаются, но мы можем установить внутренние ожидания в отношении времени обработки для серьёзных, но не критических проблем. Мы быстро исправим серьёзные ошибки, а ошибки с более низким приоритетом будут исправлены или подвергнуты рефакторингу позже.
- Каждый спринт члены команды просматривают журнал ошибок и назначают исправления, чтобы обеспечить постоянный цикл исправления и сокращения количества ошибок.
- Сообщайте об исправлениях ошибок в заметках о выпуске, публикации во внутреннем чате или в каком-либо другом средстве. Например, сделайте «день выпуска отчёта об ошибках» и публикуйте этот отчёт.
- Используйте простые формулы для расчёта количества ошибок и удерживайте количество ошибок как можно более равномерным спринт за спринтом. Отслеживайте это желательно на общих дашбордах о состоянии проекта.
Зачем?
- Создаёт «систему раннего предупреждения». Команда привыкает к ритму и осознанию своих невыполненных работ по ошибкам и рабочей нагрузке. В результате разработчики могут определить, когда ошибки накапливаются, и спланировать их исправление.
- Внутренние клиенты имеют чёткие ожидания относительно того, когда появятся исправления ошибок, и у них есть возможность видеть работу команды.
- Команда узнаёт о горячих точках продукта раньше и может использовать эту информацию для следующего раунда планирования спринта. Чем короче время, чтобы избежать проблемы, тем меньше времени тратится впустую.
Примечание: сделайте так, чтобы ваши клиенты могли легко сообщать об ошибках! Не прячьте средство сообщения об ошибках, вы не всегда будете ловить ошибки в журналах.
Окончание следует…
Источник: https://betterprogramming.pub/managing-team-health-tech-debt-and-avoiding-the-dreaded-rewrite-94878da7ca43
👍9
День 1624. #ProjectManagement
Управляем Здоровьем Команды, Техническим Долгом и Предотвращаем Переписывание с Нуля. Окончание
Начало
Продолжение
Хорошая практика №3: дисциплинированное исправление/рефакторинг
Организуйте ротацию дежурных в момент отправки продукта. Несмотря на то, что в продукте мало ошибок, может быть, мало клиентов и нет шансов выхода из строя под нагрузкой, назначение дежурных и их ротация заранее запускает «мышечную память».
Дежурство в команде с небольшим продуктом, пользовательской базой или активностью кажется контрпродуктивным, поскольку дежурные не создают новых функций. Кажется, что нужно задействовать всех на улучшение продукта, и не беспокоиться о поддержке, пока это не понадобится. Но так вы лишаете себя хорошего и простого средства управления техническим долгом и поддержания здоровья команды.
Что делать?
- Установите ротацию в тот момент, когда пользователи продукта смогут получить доступ к продукту. Наличие пользователей – это сообщения об ошибках.
- Установите разумную продолжительность (1 неделя, 1 спринт), чёткие процедуры передачи задач и расписание, чтобы все знали, когда они будут дежурить.
- Дежурство — это устранение инцидентов, исправление ошибок, снижение сложности кода (рефакторинг), а только затем работа над новыми функциями. Если бэклог ошибок заполняет всё дежурство, этот инженер не работает над новыми функциями.
- Не назначайте дежурному инженеру ничего, кроме дежурных задач.
Зачем?
- Команда методично устраняет ошибки, и технический долг стабилизируется.
- Команда выполняет SLA по ошибкам — внутренние и внешние клиенты довольны.
- Более стабильный продукт => меньше пожаров в продакшене и меньше простоев.
- Младшие инженеры получают возможность исправлять ошибки во всех частях системы, быстрее повышая свой уровень.
- Ещё одна система раннего предупреждения о здоровье команды. Если дежурство занято сложными, серьёзными ошибками, мы узнаём о проблемах сразу, а не через несколько месяцев.
Помните о компромиссе: команда предоставит меньше функций за счёт более стабильного продукта. Устанавливайте ожидания относительно ротации дежурных не в команде, а в организации в целом.
Переписывать ли заново?
Вышеупомянутые принципы должны создать систему раннего предупреждения и сосредоточить команду на поиске рефакторинга архитектуры из-за изменения технологии или бизнес-условий задолго до того, как вы достигнете этого состояния.
Инженеры любят работать над чистой кодовой базой и всегда агитируют начать все сначала. Но почти никогда не следует начинать заново, потому что это сопряжено с невероятными рисками.
Но иногда приходится:
- Нужно объединить два или более продукта в один с перекрывающимися возможностями и множеством новых требований. Создать новый продукт чаще намного быстрее.
- Первоначальные архитектурные предположения настолько ошибочны, или проблемы безопасности/конфиденциальности/соответствия настолько серьёзны, что единственным решением является создание нового продукта.
- Компания так далеко отошла от первоначальной основной миссии, что рефакторинг не спасёт кодовую базу.
Это серьёзное событие. Риски сумасшедшие: клиенты могут не захотеть использовать переписанный продукт. Команда может развалиться до или во время переписывания. Компания может рухнуть или у неё закончатся деньги. Переписать на новую архитектуру может не получиться по какой-то технической причине. Рассмотрите все компромиссы и убедитесь, что все согласны с вашим решением.
Итого
Большая часть этого процесса происходит за счёт времени команды на создание функций, но время, потерянное при этом, намного меньше, чем потеря всей команды. Держите технический долг под контролем.
Источник: https://betterprogramming.pub/managing-team-health-tech-debt-and-avoiding-the-dreaded-rewrite-94878da7ca43
Управляем Здоровьем Команды, Техническим Долгом и Предотвращаем Переписывание с Нуля. Окончание
Начало
Продолжение
Хорошая практика №3: дисциплинированное исправление/рефакторинг
Организуйте ротацию дежурных в момент отправки продукта. Несмотря на то, что в продукте мало ошибок, может быть, мало клиентов и нет шансов выхода из строя под нагрузкой, назначение дежурных и их ротация заранее запускает «мышечную память».
Дежурство в команде с небольшим продуктом, пользовательской базой или активностью кажется контрпродуктивным, поскольку дежурные не создают новых функций. Кажется, что нужно задействовать всех на улучшение продукта, и не беспокоиться о поддержке, пока это не понадобится. Но так вы лишаете себя хорошего и простого средства управления техническим долгом и поддержания здоровья команды.
Что делать?
- Установите ротацию в тот момент, когда пользователи продукта смогут получить доступ к продукту. Наличие пользователей – это сообщения об ошибках.
- Установите разумную продолжительность (1 неделя, 1 спринт), чёткие процедуры передачи задач и расписание, чтобы все знали, когда они будут дежурить.
- Дежурство — это устранение инцидентов, исправление ошибок, снижение сложности кода (рефакторинг), а только затем работа над новыми функциями. Если бэклог ошибок заполняет всё дежурство, этот инженер не работает над новыми функциями.
- Не назначайте дежурному инженеру ничего, кроме дежурных задач.
Зачем?
- Команда методично устраняет ошибки, и технический долг стабилизируется.
- Команда выполняет SLA по ошибкам — внутренние и внешние клиенты довольны.
- Более стабильный продукт => меньше пожаров в продакшене и меньше простоев.
- Младшие инженеры получают возможность исправлять ошибки во всех частях системы, быстрее повышая свой уровень.
- Ещё одна система раннего предупреждения о здоровье команды. Если дежурство занято сложными, серьёзными ошибками, мы узнаём о проблемах сразу, а не через несколько месяцев.
Помните о компромиссе: команда предоставит меньше функций за счёт более стабильного продукта. Устанавливайте ожидания относительно ротации дежурных не в команде, а в организации в целом.
Переписывать ли заново?
Вышеупомянутые принципы должны создать систему раннего предупреждения и сосредоточить команду на поиске рефакторинга архитектуры из-за изменения технологии или бизнес-условий задолго до того, как вы достигнете этого состояния.
Инженеры любят работать над чистой кодовой базой и всегда агитируют начать все сначала. Но почти никогда не следует начинать заново, потому что это сопряжено с невероятными рисками.
Но иногда приходится:
- Нужно объединить два или более продукта в один с перекрывающимися возможностями и множеством новых требований. Создать новый продукт чаще намного быстрее.
- Первоначальные архитектурные предположения настолько ошибочны, или проблемы безопасности/конфиденциальности/соответствия настолько серьёзны, что единственным решением является создание нового продукта.
- Компания так далеко отошла от первоначальной основной миссии, что рефакторинг не спасёт кодовую базу.
Это серьёзное событие. Риски сумасшедшие: клиенты могут не захотеть использовать переписанный продукт. Команда может развалиться до или во время переписывания. Компания может рухнуть или у неё закончатся деньги. Переписать на новую архитектуру может не получиться по какой-то технической причине. Рассмотрите все компромиссы и убедитесь, что все согласны с вашим решением.
Итого
Большая часть этого процесса происходит за счёт времени команды на создание функций, но время, потерянное при этом, намного меньше, чем потеря всей команды. Держите технический долг под контролем.
Источник: https://betterprogramming.pub/managing-team-health-tech-debt-and-avoiding-the-dreaded-rewrite-94878da7ca43
👍8
День 1625. #ЧтоНовенького
Превью Новых Функций C# 12
В превью 6 .NET 8 продолжилась эволюция языка C#12. Эта версия превью включает функции, призванные заложить основу для будущих улучшений производительности.
1. nameof получил доступ к членам экземпляра
Ключевое слово nameof теперь работает с именами членов класса, включая инициализаторы, статические члены и атрибуты:
Атрибут InlineArrayAttribute идентифицирует тип, который можно рассматривать как непрерывную последовательность примитивов для эффективных, типобезопасных, защищённых от переполнения индексируемых/разрезаемых встроенных данных. Библиотеки .NET повысят производительность приложений и инструментов, используя встроенные массивы.
Компилятор создаёт другой IL для доступа к встроенным массивам. Это приводит к некоторым ограничениям, таким как отсутствие поддержки шаблонов списков. Но в большинстве случаев вы сможете получить доступ к встроенным массивам так же, как и к обычным. Также другой IL обеспечивает прирост производительности без изменения вашего кода:
Перехватчики позволяют перенаправлять вызовы определённых методов в другой код. При этом атрибут перехватчика указывает фактическое расположение исходного кода, который надо перехватить. Во время выполнения код с указанного в атрибуте места переходит в код перехватчика и исполняет его вместо исходного метода. По задумке перехватчики предназначаются для генераторов кода. Это экспериментальная функция, и она может быть изменена или удалена в будущей версии, поэтому не может использоваться в производственном коде. У Ника Чапсаса недавно вышло видео на тему перехватчиков.
Источник: https://devblogs.microsoft.com/dotnet/new-csharp-12-preview-features/
Превью Новых Функций C# 12
В превью 6 .NET 8 продолжилась эволюция языка C#12. Эта версия превью включает функции, призванные заложить основу для будущих улучшений производительности.
1. nameof получил доступ к членам экземпляра
Ключевое слово nameof теперь работает с именами членов класса, включая инициализаторы, статические члены и атрибуты:
internal class NameOf2. Встроенные массивы
{
public string S { get; } = "";
public static int StaticField;
public string NameOfLength { get; }
= nameof(S.Length);
public static void NameOfExamples()
{
Console.WriteLine(nameof(S.Length));
Console.WriteLine(nameof(StaticField.MinValue));
}
[Description($"String {nameof(S.Length)}")]
public int StringLength(string s)
{ return s.Length; }
}
Атрибут InlineArrayAttribute идентифицирует тип, который можно рассматривать как непрерывную последовательность примитивов для эффективных, типобезопасных, защищённых от переполнения индексируемых/разрезаемых встроенных данных. Библиотеки .NET повысят производительность приложений и инструментов, используя встроенные массивы.
Компилятор создаёт другой IL для доступа к встроенным массивам. Это приводит к некоторым ограничениям, таким как отсутствие поддержки шаблонов списков. Но в большинстве случаев вы сможете получить доступ к встроенным массивам так же, как и к обычным. Также другой IL обеспечивает прирост производительности без изменения вашего кода:
private static void InlineArrayAccess(В большинстве случаев вы будете потреблять встроенные массивы, а не создавать их. Встроенные массивы работают быстро, потому что они основаны на точном расположении данных заданной длины. Встроенный массив — это тип с одним полем, помеченный атрибутом InlineArrayAttribute, указывающим длину массива. В типе, использованном в предыдущем примере, среда выполнения создает хранилище ровно для десяти элементов в Buffer10<T> благодаря параметру атрибута:
Buffer10<int> arr)
{
for (int i = 0; i < 10; i++)
{
arr[i] = i * i;
}
foreach (int i in arr)
{
Console.WriteLine(i);
}
}
[System.Runtime.CompilerServices.InlineArray(10)]3. Перехватчики
public struct Buffer10<T>
{
private T _element0;
}
Перехватчики позволяют перенаправлять вызовы определённых методов в другой код. При этом атрибут перехватчика указывает фактическое расположение исходного кода, который надо перехватить. Во время выполнения код с указанного в атрибуте места переходит в код перехватчика и исполняет его вместо исходного метода. По задумке перехватчики предназначаются для генераторов кода. Это экспериментальная функция, и она может быть изменена или удалена в будущей версии, поэтому не может использоваться в производственном коде. У Ника Чапсаса недавно вышло видео на тему перехватчиков.
Источник: https://devblogs.microsoft.com/dotnet/new-csharp-12-preview-features/
👍9