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

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День 1736. #ЧтоНовенького #Курсы
Microsoft Applied Skills
Applied Skills — новая, заверенная Microsoft, грамота, подтверждающая наличие у вас целевых навыков, необходимых для реализации важных проектов, соответствующих целям и задачам бизнеса. Программа Applied Skills даёт вам возможность продемонстрировать, на что вы способны и что вы можете привнести в ключевые проекты организации.

«Организации ищут таланты, которые смогут возглавить их проекты в области облачных вычислений», — отмечает Ким Акерс, корпоративный вице-президент по поддержке и эксплуатации решений для клиентов и партнёров Microsoft. - «Microsoft Applied Skills предлагает упрощённый способ проверки навыков кандидата. Когда вы видите навыки, заверенные Microsoft, вы знаете, что можете доверить этому человеку выполнение поставленной задачи».

На данный момент бесплатно в течение ограниченного времени предлагаются следующие грамоты (пока процесс только на английском языке):
- Secure storage for Azure Files and Azure Blob Storage
- Configure secure access to your workloads using Azure networking
- Deploy and configure Azure Monitor
- Deploy containers by using Azure Kubernetes Service
- Develop an ASP.NET Core web app that consumes an API
- Secure Azure services and workloads with Microsoft Defender for Cloud regulatory compliance controls
- Configure SIEM security operations using Microsoft Sentinel
- Create and manage automated processes by using Power Automate

Как получить грамоту Microsoft Applied Skills
1. Подготовьтесь самостоятельно, например, используя бесплатные курсы на Microsoft Learn.
2. Получите грамоту, пройдя онлайн интерактивную лабораторную работу, которая проведёт вас через ряд задач на основе сценариев в таких продуктах, как Microsoft Azure или Microsoft Power Platform. Лабораторную оценку можно получить непосредственно на Microsoft Learn.
3. Поделитесь своими новыми навыками. Вы получите грамоту, заверенную Microsoft, которую можно опубликовать в своём профиле.

Сертификат, грамота или то и другое?
Более 30 лет сертификаты служат доказательством технического мастерства мирового класса. В сегодняшней постоянно меняющейся бизнес-среде бывают случаи, когда необходимы подтверждённые навыки работы с конкретным проектом, предлагаемые грамотами Applied Skills. Вот ключевые отличия:
1. Цель
- Сертификат: проверяет общие технические знания
- Грамота: проверяет один конкретный навык
2. Контекст
- Сертификат: для определённой роли в компании
- Грамота: для определённого проекта
3. Охват
- Сертификат: широта навыков
- Грамота: специализированные для конкретного сценария навыки
4. Формат оценки
- Сертификат: экзамен с интерактивными элементами
- Грамота: лабораторная работа
5. Гибкость сдачи
- Сертификат: назначенное время
- Грамота: любое желаемое время

Источник: https://techcommunity.microsoft.com/t5/microsoft-learn-blog/announcing-microsoft-applied-skills-the-new-credentials-to/ba-p/3775645
👍7👎1
День 1737. #ЗаметкиНаПолях #Git
Организация Нескольких Идентичностей в Git

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

Я организую свои репозитории Git в три уровня. Мои личные проекты находятся в каталоге ~/sources. Все рабочие проекты находятся в ~/work. Это первый уровень.
Уровень 2 — это клиент, например, ~/work/client1.
Уровень 3 — это репозиторий проекта, например, ~/work/client1/foo-api.

Вот как организован рабочий каталог:
/Users/garrit/work
├── client1
│ ├── foo-api
│ ├── foo-ios
│ └── foo-android
└── client2
├── bar-ios
└── bar-middleware


Теперь предположим, что client2 требует, чтобы мы делали коммиты с идентичностью, отличной от нашей рабочей электронной почты по умолчанию. Кроме того, у вас, вероятно, также есть личный адрес электронной почты для ваших проектов.

.gitconfig – это глобальный файл конфигурации Git, расположенный в корневом каталоге. Если вы когда-либо задавали такой параметр, как git config user.name «Foo Bar»: именно здесь он и сохранялся.

Одна из замечательных особенностей файла .gitconfig заключается в том, что вы можете условно включать в него другие файлы конфигурации, и в этом вся суть:
[user]
name = Garrit Franke
email = [email protected]

[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work

[includeIf "gitdir:~/work/client2/"]
path = ~/.gitconfig-client2

[includeIf "gitdir:~/sources/"]
path = ~/.gitconfig-personal

# ...

По умолчанию мое имя и адрес электронной почты всегда соответствуют моей личной информации. Я также храню здесь некоторые другие глобальные настройки, но они нам сейчас не важны. Если репозиторий расположен внутри каталога ~/work, в него включается файл с именем ~/.gitconfig-work. Это просто ещё один файл gitconfig. Вот как он выглядит в моём случае:
[user]
name = Garrit Franke
signingkey = 12345678
email = [email protected]

[commit]
gpgsign = true


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

Этот трюк немного упростил адаптацию моего проекта. Больше никаких запросов от клиентов «Вы забыли обновить свой email»!

Источник: https://garrit.xyz/posts/2023-10-13-organizing-multiple-git-identities
Автор оригинала: Garrit Franke
👍27
День 1738. #ЗаметкиНаПолях #Debugging
Правила Отладки: Хватит Думать, Наблюдайте

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

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

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

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

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

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

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

5. Гадайте только, чтобы сузить поиск
Угадывание может быть ценным инструментом, но важно использовать догадки как средство сузить область поиска. Вы всё равно должны подтверждать свои предположения, воспроизводя сбой, прежде чем пытаться его исправить.

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

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

Источник: https://dev.to/rajasegar/debugging-rules-quit-thinking-and-look-3ang
👍5
День 1739. #BestPractices #ProjectManagement
Раздувание Процессов: Тихий Убийца Продуктивности Разработчиков

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

Факторов, приводящих к этому, множество:
1. Организационная культура.
Слишком осторожная организация может создать несколько уровней бюрократии, предполагая, что чем больше формализованы процессы тем меньше риск.
2. Недостаток доверия.
Руководство, которому не хватает уверенности в возможностях разработчиков, может навязать несколько уровней утверждения и документацию.
3. Сложность масштаба.
Расширение проектов часто влечёт увеличение числа заинтересованных сторон, каждая из которых добавляет свой уровень сложности и свои процессы.
4. Устаревший багаж.
Иногда ненужные процессы задерживаются просто потому, что «так было всегда».

Последствия
1. Снижение производительности.
Разработчики часто тратят больше времени на административную работу, чем на фактическую разработку.
2. Утечка инноваций.
Бюрократия может подавить творчество и ограничить эксперименты.
3. Задержка вывода продукта на рынок.
Сложные процессы удлиняют циклы разработки.
4. Снижение морального духа.
Потеря гибкости и рутина процессов могут подорвать моральный дух команды.

Примеры раздувания процессов
1. Чрезмерные проверки кода.
Обязательное проведение нескольких уровней проверок даже для тривиальных изменений может серьёзно замедлить цикл разработки.
2. Слишком сложные системы заявок.
Сложные системы тикетов, требующие заполнения множества полей ещё до того, как задача будет одобрена, могут занять столько же времени, сколько и исполнение задачи.
3. Обязательные отчеты.
Требование подробных отчетов с описанием каждой потраченной минуты может отнять время и отвлечь внимание от фактического кодирования.
4. Чрезмерное количество совещаний

Борьба с раздуванием процессов
1. Регулярные аудиты.
Последовательно анализируйте существующие процессы для оценки их актуальности и эффективности. Это следует делать в рамках регулярных командных (и организационных) ретроспектив. Но убедитесь, что такие аудиты полезны, а не усугубляют проблему раздувания процессов!
2. Принципы бережливости и гибкости.
Примите методологии, направленные на получение максимальной отдачи при минимальных затратах на процессы. Многие agile-практики, подчёркивают важность обеспечения быстрого прохождения процесса с минимальными церемониями.
3. Поощряйте доверие и автономию.
Дайте разработчикам полномочия принимать решения без ненужных бюрократических одобрений. Ваша команда не сможет заслужить ваше доверие, если вы как менеджер первый не доверитесь ей.
4. Минимально жизнеспособный процесс.
Внедряйте только те процессы, которые абсолютно необходимы для поддержания качества и контроля. Если сомневаетесь, выбросьте. Если есть возможность сократить процессы и повысить производительность, поэкспериментируйте с этим и посмотрите, сработает ли это для вашей команды и организации.

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

Источник: https://ardalis.com/process-bloat-silent-killer-developer-productivity/
👍7
День 1740. #Карьера
Чек-листы. Как Ничего не Забыть

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

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

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

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

Например, чек-лист для новой кодовой базы:
1. Использовать Git.
2. Автоматизировать сборку.
3. Включить все сообщения об ошибках.

1. Использовать Git.
Первое, что нужно сделать в новой кодовой базе, — инициализировать локальный репозиторий Git. Рекомендация – делать это для любой кодовой базы, которая должна прожить больше недели. Вы всегда можете всё отменить, просто удалив папку .git.

2. Автоматизировать сборку.
Создайте минимальный объём кода, который сможете развернуть. Даже если у вас нет конвейера развёртывания или доступа к производственной среде. Создайте файл сценария, выполняющего сборку, и тоже отправьте коммит в Git. Например, простой .bat файл с командой:
dotnet build --configuration Release


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

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

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

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

Ключевой момент — правило бойскаута: оставлять код в лучшем состоянии, чем вы его нашли.

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

Когда сверху от вас требуют «просто сделать побыстрее», т.к. «нет времени делать как положено», представьте, что вы отвечаете: «Если я сделаю так, код не скомпилируется». Даже если это будет не очень честно, вы всегда сможете утверждать, что конечная цель — это качественное ПО. Это должно быть выгодно для всей организации.

Источник: Марк Симан “Код, который умещается в голове”. СПб.: Питер, 2023. Глава 2.
👍16
День 1741. #ЗаметкиНаПолях #Testing
Пишем Тесты с Autofixture
AutoFixture - мощный инструмент для юнит-тестирования повседневных задач. Он помогает писать меньше кода в блоке Arrange. Рассмотрим его использование на примере совместно с библиотекой xUnit.

Сначала надо создать AutoFixture в тестовом классе:

private readonly IFixture _fixture;
public SampleTests()
{
_fixture = new Fixture();
}

AutoFixture использует обобщённый метод Create, генерирующий случайные данные для заданного типа, например:

var name = _fixture.Create<string>();
var age = _fixture.Create<int>();

Однако, с помощью дополнительного пакета AutoFixture.Xunit2, вы можете автоматически создавать целые классы, вообще без блока Arrange с помощью атрибута AutoData:

[Theory, AutoData]
public void TestEmployee(
string name, int age,
string pos, decimal rate)
{
// Act
var emp = new Employee(name, age, pos, rate);
// Assert
emp.Name.Should().Be(name);
emp.Age.Should().Be(age);
emp.Position.Should().Be(pos);
emp.Rate.Should().Be(rate);
}

Либо можно использовать метод Create:

[Fact]
public void TestEmployee()
{
// Arrange
var emp = _fixture.Create<Employee>();
var comp = _fixture.Create<Company>();

}

Здесь все свойства классов будут заданы случайными значениями.

Вы можете управлять созданием, задавая данные для определённых свойств. Также можно создавать коллекции элементов:

var emps = _fixture
.CreateMany<Employee>(5).ToList();
var comp = _fixture.Build<Company>()
.OmitAutoProperties()
.With(x => x.Employees, emps)
.Without(x => x.City)
.Create();

Здесь вызов OmitAutoProperties не будет задавать случайные значения свойствам, у которых есть значения по умолчанию. А Without не будет задавать значение выбранного свойства (в примере выше City останется null).

Вы можете создавать реализации интерфейсов с помощью метода Register:

_fixture.Register<IMyInterface>(() =>
new FakeMyInterface());

Здесь каждый раз, когда Autofixture нужно будет создать класс, зависящий от IMyInterface, будет создаваться экземпляр FakeMyInterface.

AutoFixture также можно использовать с пакетами для создания моков, вроде Moq или NSubstitute. Для этого надо настроить создание Autofixture (пример для Moq):

var _fixture = new Fixture()
.Customize(new AutoMoqCustomization
{ ConfigureMembers = true });

Тогда Autofixture можно будет использовать для создания реализаций интерфейсов:

var result = _fixture.Create<IMyInterface>();

При этом установка ConfigureMembers в true приводит к тому, что для классов-реализаций интерфейсов Autofixture сгенерирует случайные значения для свойств.

Здесь можно посмотреть множество других примеров использования AutoFixture.

Источник: https://dev.to/serhii_korol_ab7776c50dba/you-write-unit-tests-wrong-5d9f
👍24
День 1742. #ЧтоНовенького
«Короткая» Маршрутизация в .NET 8

Маршрутизация в ASP.NET Core обрабатывается двумя частями промежуточного ПО:
- EndpointRoutingMiddleware (RoutingMiddleware) — выбирает, какую зарегистрированную конечную точку выполнить для данного запроса.
- EndpointMiddleware — обычно размещается в конце конвейера промежуточного ПО и выполняет выбранную конечную точку.

Это разделение помогает размещать промежуточное ПО между RoutingMiddleware и EndpointMiddleware, которое может изменять своё поведение на основе метаданных, связанных с конечной точкой, и выполняться до выполнения самой конечной точки. Например, так работают AuthorizationMiddleware и CorsMiddleware.
См. схему

Обычно именно так работает маршрутизация независимо от того, используете ли вы минимальные API или контроллеры MVC, и она легко расширяема. Вы можете добавить дополнительные метаданные к конечным точкам, а затем добавить дополнительное промежуточное ПО между RoutingMiddleware и EndpointMiddleware, чтобы обеспечить новое поведение. Но иногда конечной точке не требуется авторизация, поддержка CORS и т.п.

«Короткая» (short-circuit) маршрутизация — новая функция в .NET 8, которая означает, что конечная точка «пропускает» промежуточное ПО между RoutingMiddleware и EndpointMiddleware. Т.е. RoutingMiddleware немедленно выполняет конечную точку и отбрасывает остальную часть конвейера.

Например:

app.MapGet("/", () => "Hello World!")
.ShortCircuit();

Здесь конечная точка "/" будет выполнена сразу в RoutingMiddleware. Также можно добавить код HTTP статуса:

….ShortCircuit(201);


Когда это полезно
Основной вариант использования — сократить накладные расходы на запросы, которые, как вы знаете, либо вернут ответ 404, либо никогда не потребуют авторизации или CORS. Некоторыми примерами могут быть известные URL-адреса, которые браузеры запрашивают автоматически, или другие стандартные пути. Например:
- /robots.txt — сообщает веб-роботам, таким как Google, что индексировать.
- /favicon.ico — значок вкладки в браузере, который автоматически запрашивается браузером.
- /.well-known/* (все пути имеют префикс .well-known/) — используется различными спецификациями, такими как OpenID Connect, security.txt или webfinger.

Это простые, хорошо известные URL-адреса, которые браузер и другие сайты могут запрашивать автоматически. Если вы не добавите их на свой сайт, то каждый запрос на них будет проходить через промежуточное ПО, только чтобы вернуть 404. Это большая лишняя работа. «Короткие» маршруты позволяют избежать этих накладных расходов.

var builder = WebApplication
.CreateBuilder(args);
var app = builder.Build();

// возвращаем 404
app.MapGet("/favicon.ico",
() => Task.CompletedTask)
.ShortCircuit(404);

// возвращаем корректный robots.txt
app.MapGet("/robots.txt",
() => """
User-agent: *
Allow: /
""")
.ShortCircuit(200);

// любой запрос к /.well-known/ вернёт 404
app.MapShortCircuit(404, ".well-known");

// все другие запросы будут проходить
// через полный конвейер промежуточного ПО
app.MapGet("/", () => "Hello World!");

app.Run();

Источник: https://andrewlock.net/exploring-the-dotnet-8-preview-short-circuit-routing/
👍18
День 1743. #ВопросыНаСобеседовании #Многопоточность
Самые часто задаваемые вопросы на собеседовании по C#

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

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

В C# можно использовать класс ThreadLocal<T> для объявления локальной переменной потока:

var localSum = new ThreadLocal<int>(() => 0);

// Каждый поток может безопасно использовать и изменять свою localSum без синхронизации
localSum.Value += 1;

Свойство IsValueCreated локальной переменной потока возвращает true, если переменная уже была инициализирована в этом потоке. Так можно определить, что управление вернулось в созданный ранее поток.

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

Перераспределение может выполняться статически или динамически, в зависимости от конкретной задачи и целей приложения. Parallel.ForEach и Parallel LINQ (PLINQ) — это два примера встроенных механизмов .NET, которые используют секционирование данных для более эффективного выполнения параллельных операций.

Пример разделения данных с использованием Parallel.ForEach:

var data = new List<int> { … };
Parallel.ForEach(data, item =>
{
// обработка элемента
});

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

Источник: https://dev.to/bytehide/c-multithreading-interview-questions-and-answers-4opj
👍21
День 1744. #Оффтоп
У Интерфейсов Могут Быть Приватные Методы

Вот вам немного бесполезных знаний. Интерфейсы могут иметь приватные методы.

Это связано с функцией C#8: «реализация интерфейса по умолчанию». Она позволяет нам определить реализацию по умолчанию для метода в интерфейсе. Это полезно, когда мы хотим добавить новый метод к интерфейсу, но не хотим разрушать все классы, реализующие этот интерфейс. Что-то вроде этого:

public interface IMyInterface
{
public void MyMethod()
{
// Что-то делаем
}
}

public class MyClass : IMyInterface
{
// Не надо реализовывать MyMethod
}

Но при использовании мы не можем вызвать MyMethod из MyClass:
cs 

var myClass = new MyClass();
myClass.MyMethod();

Код выше не скомпилируется. Метод надо вызвать вот так:

IMyInterface myInterface = myClass;
myInterface.MyMethod();

И чтобы ещё больше всё запутать, мы также можем провести рефакторинг приватных членов интерфейса:

public interface IMyInterface
{
public void MyMethod()
{
MyPrivateMethod();
}

private void MyPrivateMethod()
{
// что-то делаем
}
}

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

Источник: https://steven-giesel.com/blogPost/03957748-73b3-40f9-a9f7-cc95501a3a8e
👍16
День 1745. #Карьера #ProjectManagement
Как Дать Эффективную Обратную Связь Сложному Человеку. Начало

Если слишком долго позволять трудным в общении людям делать всё по-своему, это может нанести непоправимый ущерб. Предоставление им обратной связи будет неэффективным, если она не будет правильной. Рассмотрим стратегии предоставления обратной связи таким трудным людям.

В коллективах бывают умные, талантливые и результативные люди. Они умеют решать сложные проблемы, и на них можно положиться для достижения цели. Но что, если они хороши только при самостоятельном выполнении работы? Что, если команде трудно общаться и сотрудничать с ними, что снижает продуктивность и результативность команды? Что, если они:
- Унижают других, когда их идеи неудачны.
- Занимают оборонительную позицию, когда другие с ними не согласны.
- Устанавливают высокие стандарты и ожидают, что другие будут им соответствовать.
- Выражают недовольство криком и гневом.
- Перебивают других и не позволяя им говорить.
- Ожидают особого к себе отношения.

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

Роберт Саттон в книге «Хороший босс, плохой босс» говорит, что лучшие начальники делают больше, чем просто заряжают людей, набирают и воспитывают работяг. Они устраняют негатив, потому что даже один токсичный человек или несколько деструктивных поступков могут навредить множеству хороших людей и конструктивных действий.

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

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

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

1. Тщательно выбирайте слова
Для сложного человека определённые слова в обратной связи вызывают сильные негативные чувства, которые заставляют его защищаться:
- Обобщающие, типа «всегда» и «никогда».
- Навязывающие, как «не могу», «не должен», «должен», «подчиняться».
- Бросающие вызов: «плохой», «требовательный», «непрофессиональный», «грубый».
- Осуждающие: «ошибка», «неудача», «неприемлемо».

Селеста Хэдли пишет в книге «Нам надо поговорить»: «Высокообразованные люди склонны придавать большое значение логике и преуменьшать важность эмоций. Конечно, вы не можете выиграть дебаты с помощью эмоциональных аргументов, но разговор — это не дебаты, а люди по своей сути нелогичны. Мы эмоциональные существа. Удалить или попытаться удалить эмоции из вашего разговора — значит извлечь большую часть смысла и важности».

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

Например:
Вместо: Вы всегда опаздываете на встречи. Ваше поведение испортит и других членов команды.
Скажите: На последних двух встречах я заметил, что вы приходили через 10-15 минут после начала. Вы можете приходить на собрания вовремя и подать хороший пример другим?

Вместо: Вы должны позволить другим высказываться в обсуждениях. Перебивать их – это грубо.
Скажите: Выслушивание различных точек зрения поможет нам принимать более правильные решения. Давайте попробуем стимулировать участие других в обсуждениях.

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

Источник:
https://www.techtello.com/give-feedback-to-a-difficult-person/
👍11
День 1746. #Карьера #ProjectManagement
Как Дать Эффективную Обратную Связь Сложному Человеку. Продолжение

Начало

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

Керри Паттерсон говорит в книге «Ключевые переговоры»: «Уважение подобно воздуху. Пока оно есть, об этом никто не думает. Но если убрать его, это все, о чём люди смогут думать. В тот момент, когда люди чувствуют неуважение в разговоре, взаимодействие больше не имеет первоначальной цели — теперь речь идёт о защите достоинства».

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

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

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

Вместо: Вы кричите на других. Это не поможет. Научитесь контролировать свой характер.
Скажите: Мне сказали, что на последней встрече вы повысили голос (факт). Из-за этого другие в комнате не захотели высказываться. Без их вклада и согласия мы не сможем принять решение, что задержит реализацию проекта. Давайте попробуем поддерживать идеи других и побудить их делиться мыслями. (решение)

Вместо: Вы очень грубы и постоянно перебиваете других. Это неприемлемо.
Скажите: В последнем обсуждении я заметил, что, когда Рея делилась решением, вы несколько раз перебивали её и уводили разговор в сторону (факт). Когда вы не позволяете другим договорить, они чувствуют себя неуслышанными, что подрывает их уверенность. Мы можем расти как команда только тогда, когда каждый имеет возможность делиться своим мнением. Что вы можете сделать, чтобы этому поспособствовать? (решение)

Вместо: Ты сказал Карлу, что он тупой. Это непрофессионально.
Скажите: Мне сказали, что ты назвал дизайн Карла тупым (факт). Карл — очень преданный своему делу сотрудник, который всегда стремится учиться. Это нормально чего-то не знать. Это не делает человека тупым. Вместо того, чтобы разочаровывать людей, когда они чего-то не знают, нам нужно поощрять их учиться. Давайте решим, как вы можете работать с командой так, чтобы поощрять коллег, а не разочаровывать? (решение)

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

Источник:
https://www.techtello.com/give-feedback-to-a-difficult-person/
👍9
День 1747. #Карьера #ProjectManagement
Как Дать Эффективную Обратную Связь Сложному Человеку. Окончание

Начало
Продолжение

3. Слушайте, дайте человеку почувствовать себя услышанным
Доктор Ральф Николс, пионер изучения умения слушать, сказал: «Самая основная из всех человеческих потребностей — это потребность понимать и быть понятым. Лучший способ понять людей — это слушать их». Слушать не означает соглашаться с их точкой зрения, это просто даёт им понять, что вы их услышали.

Чувство того, что вас не слышат, вызывает негативные эмоции, которые омрачают способность ясно мыслить и участвовать в конструктивной дискуссии. Как только человек чувствует неодобрение, срабатывает защитная реакция, спасающая его от риска эмоционального воздействия: он отказывается брать на себя ответственность или перекладывает вину на кого-то другого.

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

Вот несколько дополнительных вопросов для взаимодействия и общения:
- Расскажите подробнее об этом.
- Что вы об этом думаете?
- Как бы вы это решили?
- Как вы думаете, почему это произошло?
- Какой может быть альтернативная точка зрения на это?
- Если бы вы оказались в такой ситуации, как бы вы себя почувствовали?

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

4. Установите дедлайн изменений
Джоко Виллинк говорит в книге «Экстремальная ответственность»: «Важно не то, что вы проповедуете, а то, что вы терпите».

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

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

Когда вы даёте обратную связь сложному человеку, не говорите просто «о проблеме». Установите время на взаимно согласованные изменения и дайте понять, что человек должен быть готов столкнуться с последствиями, если не сможет учиться и совершенствоваться.

Для этого скажите: «Давайте убедимся, что мы друг друга поняли. Через [сколько-то времени] вы [излагаете ваши ожидания]. Я готов помочь вам, если вы захотите обсудить что-нибудь ещё. Но имейте в виду, что я не отношусь к этому легкомысленно, и, если ситуация не улучшится, будут последствия».

Итого
«Трудные» люди, особенно те, у которых к тому же все хорошо на работе, плохо воспринимают обратную связь. Чтобы разговор был эффективным:
1. Будьте аккуратны в выборе слов. Эмоционально заряженные слова могут вызвать негативные эмоции и заставить человека защищаться.
2. Исключите обратную связь, которая воспринимается как осуждение. Поделитесь наблюдениями, поговорите о влиянии на команду и предложите человеку найти решение.
3. Послушайте человека. Дайте ему возможность подумать, поразмышлять и найти собственное решение.
4. Не оставляйте отзыв без чётких ожиданий относительно желаемых изменений, сроков и последствий несерьёзного отношения к критике.

Источник: https://www.techtello.com/give-feedback-to-a-difficult-person/
👍6
День 1748. #ЧтоНовенького
Оператор Расширения для Коллекций в C# 12.

Выражения коллекций (также известные как литералы коллекций) — это новая функция C#12, которая добавляет в C# оператор расширения. Он позволяет объединить коллекции распространённых типов (массивы, диапазоны и списки) в одну. Кроме того, для типов коллекций изменён синтаксис, который упрощает код и помогает уменьшить его многословность.

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

var a = new int[] { 1, 2, 3 };
var b = new Span<int>(new int[] { 2, 4, 5, 4, 4 });
var c = new List<int> { 4, 6, 6, 5 };

Новый синтаксис в C#12
Теперь мы можем использовать выражения коллекций. Мы объявляем переменную с типом коллекции, который хотим использовать, а затем заключаем значения в квадратные скобки:

int[] a = [1, 2, 3];
Span<int> b = [2, 4, 5, 4, 4];
List<int> c = [4, 6, 6, 5];

Это сокращает количество кода, и, как по мне, более читабельно выглядит.

Оператор расширения (spread)
Оператор расширения популярен в JavaScript для объединения и добавления значений к существующим типам коллекций. И наконец он появился в C#.

Чтобы использовать его, инициализируйте новый тип коллекции, а затем добавьте .. перед добавлением переменной типа коллекции.

int[] join = [..a, ..b, ..c];

Также можно добавлять дополнительные значения:

int[] join = [..a, ..b, ..c, 6, 5];

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

int[] a = [1, 2, 3];
Span<int> b = [2, 4, 5, 4, 4];
List<int> c = [4, 6, 6, 5];

List<int> join = [..a, ..b, ..c, 6, 5];

Источник: https://www.roundthecode.com/dotnet-tutorials/collection-expressions-brings-spread-operator-csharp-12
👍51
День 1749.
.NET Conf 2023.
Вот опять ноябрь, а это значит, выпуск новой версии .NET и посвящённая этому .NET Conf 2023.

https://www.dotnetconf.net/

Вот краткое расписание первого дня по московскому времени (подробное расписание на сегодня и последующие дни тут https://www.dotnetconf.net/agenda).

14 ноября
19:00-20:00 Welcome to .NET 8 (Damian Edwards, Safia Abdalla, David Fowler, Gaurav Seth, Daniel Roth, Glenn Condron, Maddy Montaquila, Maria Naggaga)
20:00-21:00 Full stack web UI with Blazor in .NET 8 (Daniel Roth, Steve Sanderson)
21:00-22:00 Building Cloud Native apps with .NET 8 (Glenn Condron, David Fowler)
22:00-23:00 Performance Improvements in .NET 8, ASP.NET Core, and .NET MAUI (David Fowler, Stephen Toub, Jonathan Peppers)
23:00-23:45 What's New in C# 12 (Mads Torgersen, Dustin Campbell)
23:45-00:30 Packing light with VS Code and the C# Dev Kit (Burke Holland, Leslie Richardson)

15 ноября
00:30-01:15 Entity Framework Core 8: Improved JSON, queryable collections, and more… (Arthur Vickers, Shay Rojansky)
01:15-02:00 .NET 💖 AI (John Maeda, Scott Hanselman)
02:00-02:45 Build Intelligent Apps with .NET and Azure (Luis Quintanilla, Maria Naggaga)
02:45-03:30 What’s New in .NET MAUI (David Ortinau, Maddy Montaquila)
03:30-04:15 Building and scaling cloud-native, intelligent applications on Azure and .NET (Scott Hunter)
04:15-05:15 CodeParty Attendee Party (Jeffrey T. Fritz)

Смотрим!
👍13👎1
День 1750. #ЧтоНовенького
Топ 10 Новых Функций .NET 8. Начало

Итак, .NET 8 выпущен. Это LTS версия - с долгосрочной поддержкой в течение как минимум трех лет с момента запуска. Рассмотрим 10 лучших новых функций .NET 8.

1. Производительность
Как обычно, много внимания было уделено повышению производительности. Стивен Тауб написал огромную статью, в которой описываются все улучшения.

Вот наиболее заметные:
- Очень много улучшений связано с усовершенствованной оптимизацией на основе профиля (Dynamic PGO). Это метод оптимизации JIT-компилятора, который позволяет JIT собирать дополнительную информацию об окружении (так называемом профиле) в коде, чтобы полагаться на неё позже и «пересобирать» методы на «горячем пути», делая их ещё эффективнее. Так виртуальные вызовы методов могут заменяться прямыми, условные операторы инвертироваться, чтобы чаще переходить по «более горячему пути», могут клонироваться циклы и т.п.
- List<T>.AddRange(IEnumerable<T>) был переписан для повышения производительности, когда последовательность не является ICollection<T>. В этом случае AddRange не может использовать свойство Count и приходится итерировать всю добавляемую коллекцию. В .NET 8 этот метод работает быстрее на 60%, по сравнению с .NET 7.
- Int32.ToString() ускорен благодаря кэшированию значений от 0 до 299. В результате для этих чисел ToString() работает быстрее почти на 90% и ничего не аллоцирует, но и для других чисел он ускорен примерно на 40%.

2. Динамическая Адаптация к Размерам Приложений (DATAS)
В .NET 8 в сборщик мусора добавлена функция DATAS (Dynamic Adaptation To Application Sizes). Она регулирует использование памяти приложением на основе размера текущих данных (LDS), который включает в себя долгоживущие данные и текущие данные во время события сборки мусора. У DATAS есть два основных варианта использования:
- Для изменяющихся рабочих нагрузок в средах с ограниченной памятью, таких как контейнерные приложения с ограничениями памяти. DATAS уменьшает или увеличивает размер кучи по мере необходимости.
- Для небольших рабочих нагрузок с использованием Server GC - обеспечивает соответствие размера кучи фактическим требованиям приложения.
Основная задача DATAS — адаптация к размеру приложения. Сборщик мусора всегда динамически изменял параметры своей работы, но DATAS настраивает его так, чтобы он лучше соответствовал рабочим нагрузкам. См.
подробнее о DATAS.

3. Сериализация и десериализация в System.Text.Json
.NET 8 повышает удобство использования приложений Native AOT благодаря множеству улучшений в генераторах кода, включая:
- Поддержку сериализации типов с required и init свойствами.
- Атрибут JsonSourceGenerationOptions соответствующий JsonSerializerOptions, позволяющий настраивать сериализацию во время компиляции.
- Улучшенную обработку типов: игнорирует недоступные свойства, позволяет вкладывать объявления JsonSerializerContext и динамически обрабатывает типы, созданные компилятором.
- JsonStringEnumConverter<TEnum> новый тип преобразователя упрощающий сериализацию перечислений в нативных AOT-приложениях.
- Свойство JsonConverter.Type позволяющее получить тип неуниверсального экземпляра JsonConverter с поддержкой значений NULL для различных сценариев.

Множество других улучшений, в том числе:
- JsonNamingPolicy теперь включает новые политики именования для преобразования имён свойств в Snake_case и Kebab-Case.
- Десериализация данных в readonly поля или свойства, не имеющие сеттера.
- Отключение сериализатора на основе рефлексии по умолчанию. Эта возможность полезна для предотвращения непреднамеренного включения компонентов рефлексии, особенно в усеченных и нативных AOT-приложениях.
См. подробнее о новинках в System.Text.Json.

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

Источник:
https://blog.ndepend.com/net-8-top-10-new-features/
👍29👎1
День 1751. #ЧтоНовенького
Топ 10 Новых Функций .NET 8. Продолжение

Начало

4. Работа с коллекциями
Теперь синтаксис квадратных скобок можно использовать для инициализации многих видов коллекций (а также для объединения коллекций), в том числе коллекций только для чтения и неизменяемых коллекций, которые нельзя инициализировать с помощью старого синтаксиса фигурных скобок:
// не компилируется
ImmutableList<int> list = { 1, 2, 3, 4 };

// работает
ImmutableList<int> list = [ 1, 2, 3, 4 ];

Также синтаксис [] можно использовать для инициализации пустой коллекции (в том числе словаря) вместо использования new List или Array.Empty.
К сожалению, к этому релизу не успели полноценно реализовать синтаксис инициализации словарей, вроде:
Dictionary<string, int> dict = ["a": 1, "b": 2];

Но он есть в предложениях на C# 13.

Кроме того, появились удобные методы для случайного перемешивания элементов коллекции. Например, новые методы System.Random.GetItems() и System.Security.Cryptography.RandomNumberGenerator.GetItems() позволяют случайным образом выбирать указанное количество элементов из входного набора:
ReadOnlySpan<int> numbers = 
[1, 2, 3, 4, 5, 6];
var diceRolls =
Random.Shared.GetItems(numbers, 5);
// 5, 1, 1, 4, 4

Новые методы Random.Shuffle и RandomNumberGenerator.Shuffle<T>(Span<T>) теперь позволяют рандомизировать элементы диапазона:
Span<int> numbers = [1, 2, 3, 4, 5, 6];
Random.Shared.Shuffle(numbers);
// 3, 4, 1, 5, 2, 6

5. Новые абстракции времени
Недавно представленный класс TimeProvider и интерфейс ITimer предлагают абстракции времени, облегчая моделирование времени в сценариях тестирования. TimeProvider — это абстрактный класс с множеством виртуальных функций, что делает его идеальным кандидатом для интеграции с фреймворками моков.

Заметьте, что вы также можете использовать абстракцию времени для имитации операций Task, которые зависят от хода времени, например Task.Delay() и Task.WaitAsync().
См. также
- Подробнее про класс TimeProvider.
- Большая статья Эндрю Лока

6. Форматирование UTF8
Чтобы включить генерацию строкового представления вашего типа в целевом спане, реализуйте недавно представленный интерфейс IUtf8SpanFormattable для вашего типа:
public interface IUtf8SpanFormattable {
bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider);
}


Этот интерфейс похож на ISpanFormattable, но разработан специально для UTF-8 и Span<byte>, в отличие от UTF-16 и Span<char>. В .NET 8 все примитивные типы (и другие) реализуют этот интерфейс: Byte, Complex, Char, DateOnly, DateTime, DateTimeOffset, Decimal, Double, Guid, Half, IPAddress, IPNetwork, Int16, Int32, Int64, Int128, IntPtr, NFloat. , SByte, Single, Rune, TimeOnly, TimeSpan, UInt16, UInt32, UInt64, UInt128, UIntPtr и Version.

Разработан он в первую очередь для применения в minimal API и вебе (именно там мы чаще всего используем UTF-8). Вот пример:
Span<byte> dest = stackalloc byte[16];
int written = 0;
// 123.456
123.456123.TryFormat(dest, out written, ".###");
// 2021-11-16
DateTime.Now.TryFormat(dest, out written, "yyyy-MM-dd");

Console.WriteLine(
Encoding.UTF8.GetString(dest.Slice(0, written)));

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

Источник:
https://blog.ndepend.com/net-8-top-10-new-features/
👍15
День 1752. #ЧтоНовенького
Топ 10 Новых Функций .NET 8. Окончание

Начало
Продолжение

7. Потоковые методы ZipFile
Теперь можно сжимать файлы из каталога в поток без необходимости кэшировать их во временный файл. Это позволяет напрямую управлять результатом сжатия в памяти. Новый API полезен в сценариях, где дисковое пространство ограничено, поскольку устраняет необходимость использования диска в качестве промежуточного шага. Новые статические методы: ZipFile.CreateFromDirectory и ExtractToDirectory.

8. Новые типы, которые могут улучшить производительность в различных ситуациях
1) System.Collections.Frozen содержит новые классы коллекций FrozenSet<T> и FrozenDictionary<TKey,TValue>. Эти коллекции нельзя изменить после создания. Внутри реализация использует это требование, чтобы обеспечить более быстрое перечисление и более быстрые операции поиска, такие как Contains() или TryGetValue(). Эти коллекции оказываются особенно ценными в сценариях, где коллекции изначально заполняются и впоследствии сохраняются в течение всего жизненного цикла долгоживущего приложения.
См. подробнее о замороженных коллекциях

2) Класс System.Buffers.SearchValues<T> предназначен для эффективного поиска набора байтов или символов в другом наборе, например, в реализации String.IndexOfAny(char[]). При создании экземпляра SearchValues<T> все данные, необходимые для оптимизации будущего поиска, вычисляются заранее и выбирается наиболее эффективный алгоритм поиска. Класс уже широко используется внутри .NET, например, в кодогенерации для регулярных выражений.

3) Класс System.Text.CompositeFormat предназначен для оптимизации строк формата, таких как «Имя: {0} Фамилия: {1}», неизвестных во время компиляции. Он позволяет динамически создавать строки формата путем объединения строк и элементов формата (аналогично классу StringBuilder), а также предоставляет ряд функций для оптимизации строк формата, таких как кэширование и повторное использование. Несмотря на то, что такие задачи, как анализ строк, требуют начальных накладных расходов, этот упреждающий подход значительно снижает вычислительную нагрузку при последующих использованиях, повышая производительность и эффективность.

9. Поддержка набора инструкций Intel AVX-512.
В .NET Core 3.0 предложена поддержка SIMD за счёт включения аппаратной поддержки для платформы x86/x64. .NET 5 расширил эту поддержку до Arm64, в .NET 7 были представлены кроссплатформенные аппаратные функции. .NET 8 ещё расширяет возможности SIMD за счет введения Vector512<T> и поддержки инструкций Intel Advanced Vector Extensions 512 (AVX-512). Обратите внимание: если у вас есть оборудование, совместимое с AVX-512, Vector512.IsHardwareAccelerated теперь будет возвращать true.

10. Криптография
.NET 8 предлагает поддержку примитивов хеширования SHA-3. SHA-3 в настоящее время совместим с Linux и OpenSSL 1.1.1 или новее, а также с Windows 11 сборки 25324 или новее. Существующие API, предлагающие SHA-2, теперь включают свои аналоги SHA-3, включающие SHA3_256, SHA3_384 и SHA3_512 для хеширования; HashAlgorithmName.SHA3_256, HashAlgorithmName.SHA3_384 и HashAlgorithmName.SHA3_512 для хеширования, с настраиваемым алгоритмом; HMACSHA3_256, HMACSHA3_384 и HMACSHA3_512 для HMAC; и RSAEncryptionPadding.OaepSHA3_256, RSAEncryptionPadding.OaepSHA3_384 и RSAEncryptionPadding.OaepSHA3_512 для шифрования RSA OAEP.

Источник: https://blog.ndepend.com/net-8-top-10-new-features/
👍15
День 1753. #Оффтоп
Давненько не рекомендовал вам видосиков. Сегодня просто полный оффтоп, и не совсем про программирование. У АйтиБороды вышло шикарное интервью с Интервью с Михаилом Климарёвым, директором Общества Защиты Интернета.
Как зарождался и развивался Рунет, как его пытаются контролировать сейчас. А поскольку я в сети тоже уже очень давно, то знатно поностальгировал по временам диалапа и ADSL.

Так что запасайтесь 3,5 часами свободного времени https://youtu.be/eaz3vSihX0o

ЗЫ: если у кого аллергия на политоту, то её тут довольно много. Если что, я предупредил.
👎15👍11
День 1754. #Книги
Вчера пришла очередная книга, над переводом которой я работал совместно с сообществом DotNetRu. Крис Сейнти «Blazor в действии» — М.: ДМК Пресс, 2023.

Книгу у меня получилось не только вычитать, но и проверить код (кстати, исправил несколько косяков в оригинале). В принципе, тем, кто хочет познакомиться с технологией и понять, что там к чему и зачем, могу книгу порекомендовать. Единственная проблема, как и со всеми книгами по новым технологиям – книги сильно отстают, а новая технология быстро и кардинально меняется. Так и тут, после выхода .NET 8 различия между Blazor Server и Blazor WebAssembly практически нивелировались. Теперь при создании проекта не обязательно выбирать одно или другое, их можно использовать совместно. Однако, это не значит, что книга совсем бесполезна, вполне можно изучить основы по ней, а новинки посмотреть в документации (тем более, что эти нововведения только-только появились и пока ещё нет большой практики их применения).

Подробнее про книгу в статье на Хабре
👍33
День 1755. #ЧтоНовенького
Упрощаем Облачную Разработку с .NET Aspire

.NET Aspire — это оркестратор для создания отказоустойчивых, наблюдаемых и настраиваемых облачных приложений в .NET. Он включает набор компонентов для обнаружения сервисов, телеметрии, поддержки устойчивости и проверки работоспособности.

Новый шаблон .NET Aspire Starter доступен в Visual Studio 2022 (17.9 Preview 1), либо из командной строки. Приложение шаблона состоит из двух проектов (веб-интерфейс Blazor и API) и кэша Redis. Также включены два новых проекта:
1. <appname>.AppHost запускает .NET-проекты, контейнеры или исполняемые файлы, необходимые для вашего распределённого приложения.
2. <appname>.ServiceDefaults содержит общую сервисную логику, которая применяется к каждому из проектов в приложении: обнаружение сервисов, телеметрия и конечные точки проверки работоспособности.

Панель мониторинга
Запуск приложения .NET Aspire отображает панель мониторинга. Она даёт единое представление о ваших сервисах с их журналами, метриками, трассировками и ошибками. На картинке 1 ниже показано изображение проекта с ошибкой, обозначенной красной точкой. Также можно смотреть журналы всех проектов и распределённую трассировку, показывающую запрос на страницу погоды (см. картинку 2 ниже). На панели собираются все диагностические данные во время разработки. Используются открытые стандарты, такие как Grafana+Prometheus, Application Insights и т. д.

Компоненты
В веб-проекте приложения есть NuGet-пакет Aspire.StackExchange.Redis.OutputCaching. Такие пакеты называются компонентами .NET Aspire. Это связующие библиотеки, которые настраивают SDK для работы в облачной среде. Каждый компонент должен:
- Предоставлять схему JSON для конфигурации.
- Использовать настраиваемые шаблоны устойчивости, такие как повторные попытки, тайм-ауты и автоматические выключатели, чтобы максимизировать доступность.
- Предоставлять проверки работоспособности.
- Предлагать интегрированное ведение журнала, метрики и трассировку с использованием современных абстракций .NET (ILogger, Meter, Activity).
- Предлагать методы расширения, которые «склеивают» сервисы из SDK в DI-контейнер с правильным временем жизни для регистрируемых типов.

То есть компоненты .NET Aspire настраивают зависимости для соблюдения ряда требований для успешной работы в облаке. Они не оборачивают и не скрывают фактический SDK/библиотеку, а действуют как связующее звено, гарантируя, что библиотека настроена с хорошим набором значений по умолчанию и правильно зарегистрирована в DI.

Код
В Program.cs веб-проекта вы можете увидеть код:
builder.Services
.AddHttpClient<WeatherApiClient>(
client => client
.BaseAddress = new("https://apiservice"));

Это настройка веб-интерфейса для вызова API погоды. Название apiservice взято из проекта AppHost:
var builder = 
DistributedApplication.CreateBuilder(args);

var cache =
builder.AddRedisContainer("cache");

var apiservice = builder
.AddProject<Projects.AspireApp_ApiService>(
"apiservice");

Builder
.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithReference(cache)
.WithReference(apiservice);

builder.Build().Run();

AppHost —стартовый проект. Он запускает все проекты, их зависимости и настраивает их, позволяя им взаимодействовать. Механизм обнаружения сервисов позволяет использовать логические имена вместо IP-адресов и портов при выполнении HTTP-вызовов. Здесь API-сервис назван "apiservice", и это имя можно использовать при выполнении HTTP-вызовов через IHttpClientFactory. Аналогично кэш Redis назван "cache". Вызовы, выполненные с использованием этого метода, также будут автоматически повторяться и обрабатывать временные сбои благодаря интеграции с Polly.

Подробнее о .NET Aspire смотрите в:
- докладе с .NET Conf
- видео от Ника Чапсаса
- деплой в Azure от Ника Чапсаса

Источник: https://devblogs.microsoft.com/dotnet/introducing-dotnet-aspire-simplifying-cloud-native-development-with-dotnet-8/
👍12