.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
День девятьсот двадцать девятый. #Оффтоп
Удивительная История Алгоритма Нахождения Обратного Квадратного Корня из Quake III
Я, кажется, как-то уже писал, что не считаю себя труЪ программистом. Я скорее разработчик, использующий строительные блоки, созданные другими, чтобы собрать из них что-то работающее, как из деталей конструктора. Настоящими же программистами лично я считаю людей, создающих уникальные алгоритмы или эффективные способы хранения данных и манипуляций над ними.

И сегодня речь пойдёт как раз о таком случае. Дейв Пламер на своём канале рассказывает историю одного такого алгоритма вычисления обратного квадратного корня, который нашли в выпущенном в 2005м году исходном коде игры Quake III Arena.

В двух словах. Графика в игре постоянно имеет дело с векторами. И самой распространённой задачей является нормализация вектора, т.е. преобразование заданного вектора в вектор в том же направлении, но с единичной длиной. Например, для вектора {x, y, z}, его длина будет определяться как sqrt(x*x + y*y + z*z), а нормальный вектор получится путём деления каждой величины на эту длину. Таким образом, задача состоит в быстром нахождении значения 1.0/sqrt(x).

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

Подробнее в 2х частях видео от Дейва Пламера:
- Часть 1
- Часть 2

Сразу предупреждаю, очень много математики.
День девятьсот тридцатый. #DesignPatterns #Microservices
Паттерны в Микросервисах
10. Тестирование Контрактов, Ориентированных на Потребителя
В микросервисной архитектуре зачастую разные микросервисы разрабатываются отдельными группами. Эти микросервисы работают вместе для выполнения бизнес-требований (например, запроса клиента) и взаимодействуют друг с другом синхронно или асинхронно. Интеграционное тестирование микросервиса со стороны потребителя - непростая задача. Обычно в таких сценариях используется объект-имитация для более быстрой и дешёвой реализации тестов. Но он зачастую не полностью представляет собой настоящий микросервис провайдера. Кроме того, если микросервис провайдера изменяет свой API или сообщение, объект-имитация не может это отразить. Другой вариант - провести сквозное тестирование. Хотя сквозное тестирование является обязательным перед выпуском продукта, оно хрупкое, медленное, дорогое и не может заменить интеграционное тестирование.

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

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

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

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

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

Поддержка
Pact, Postman, Spring Cloud Contract

Подробнее
- Microservices Pattern: Service Integration Contract Test
- Consumer-Driven Contracts: A Service Evolution Pattern

Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍2
День девятьсот тридцать первый. #ЗаметкиНаПолях
Генерация случайных чисел в .NET
Уже давно мы можем использовать класс Random для генерации «случайных» чисел:
var randomGenerator = new Random();
randomGenerator.Next(1, 1000000);
Этот код выдаст случайное число от 1 до 1 миллиона.

Однако Random в C# использует значение посева, которое затем используется в алгоритме генерации чисел. Передав одно и то же значение посева, вы получите ту же последовательность случайных чисел. Например:
var randomGenerator = new Random(123);
var random1 = randomGenerator.Next(1, 1000000);
randomGenerator = new Random(123);
var random2 = randomGenerator.Next(1, 1000000);
Console.WriteLine(random1 == random2); //true

И вы, вероятно, скажете: «Тогда просто не передавайте ему то же самое число посева». На самом деле в класс Random всегда передаётся посев, нравится вам это или нет. Когда конструктору Random не передан посев, в .NET Framework он использует миллисекундную часть времени в качестве посева, а в .NET Core/.NET5+ используется генератор псевдослучайных чисел.

Поэтому в .NET Framework, согласно документации:
В большинстве систем Windows случайные объекты, созданные с интервалом в 15 миллисекунд, скорее всего, будут иметь идентичные начальные значения.

Но это происходит только в том случае, если вы создаёте генератор случайных чисел несколько раз. Если вместо этого вы каждый раз используете один и тот же экземпляр Random, то такой коллизии не возникнет:
var randomGenerator = new Random();
var random1 = randomGenerator.Next(1, 1000000);
//другое число из того же экземпляра Random
var random2 = randomGenerator.Next(1, 1000000);

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

Использование класса RandomNumberGenerator
Этот класс фактически присутствует во всех версиях .NET, но в .NET Core 3+ в нём появились вспомогательные методы, помогающие вам оперировать не случайными байтами, а сразу числами:
var random = RandomNumberGenerator.GetInt32(1, 1000000);

Этот генератор случайных чисел построен на основе API криптографии, чтобы быть максимально случайным. Таким образом, если вам нужно что-то по-настоящему случайное (например, соль для пароля), вам следует использовать RandomNumberGenerator, а не класс Random.

Зачем же тогда вообще использовать Random?
Одной из причин может быть скорость. Вызов метода Next класса Random гораздо быстрее, чем использование RandomNumberGenerator.GetInt32. Поэтому, если вам не критична «настоящая случайность», но требуется создать много псевдослучайных чисел, лучшим вариантом будет создание объекта Random и генерация серии чисел через последовательный вызов метода Next на этом объекте.

Источник: https://dotnetcoretutorials.com/2021/08/10/generating-random-numbers-in-net/
День девятьсот тридцать второй. #TipsAndTricks
Скрытые Трюки для Повышения Продуктивности в ReSharper и Rider. Начало
Практически после каждого поста по поводу горячих клавиш или новых фишек в Visual Studio (см. по тегу #TipsAndTricks) в чате и в личке меня просили выпустить похожий пост для Rider. Дело в том, что я им не пользуюсь, поэтому из первых уст ничего рассказать не могу. Положусь на мнение Майка Шпильта.

1. Ctrl+T, Ctrl+T+T, Ctrl+T+T+T
Вы наверняка знаете отличную команду Ctrl+T, которая позволяет быстро находить поля, файлы и типы. Однако вы могли не знать, что можете нажать T еще один или два раза.
Ctrl+T+T позволяет вам искать только типы.
Ctrl+T+T+T позволяет искать любой текст в вашем решении аналогично Ctrl+Shift+F в Visual Studio.

2. Открыть результаты Ctrl+T в виде списка
Навигация в огромном приложении может быть довольно сложной. Вы не всегда помните точное название поля, которое ищете. Или вы можете вспомнить, что ищете что-то со словом Home, но количество полей и классов, подходящих для этого поиска, огромно. Ctrl+T показывает только первые результаты, помещающиеся на одном экране. Но если при поиске вы нажмёте Shift+Enter, вы увидите все результаты в окне инструментов. Теперь вы можете быстро прокрутить или отфильтровать результаты, чтобы найти то, что хотели.

3. Источник значения и назначение значения
ReSharper позволяет для любой переменной увидеть все возможные стеки вызовов, из которых вы можете её получить (в качестве параметра) и куда она направляется (в качестве аргумента). Начнем источника. Используйте либо сочетание клавиш Ctrl+Alt+Shift+A, либо контекстное меню «Inspect this». Выберите «Value Origin» в подменю, и вы увидите все возможные пути получения значения текущей переменной.

Чтобы увидеть все возможные места назначения переменной, выберите в подменю «Value Destination». Вы увидите все места, где эта переменная будет использоваться или передаваться в качестве аргумента, начиная с этого момента.

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

Источник:
https://michaelscodingspot.com/productivity-in-resharper-and-rider/
День девятьсот тридцать третий. #TipsAndTricks
Скрытые Трюки для Повышения Продуктивности в ReSharper и Rider. Окончание
Начало

4. Шаблоны автозавершения
Вам могут быть знакомы сниппеты в Visual Studio. В ReSharper есть аналогичная функция, которая позволяет вставлять выражение в шаблон после того, как вы его уже набрали. Например:
Enumerable.Range(0, 100).fore
Если нажать Enter или Tab, ReSharper автоматически создает оператор foreach:
foreach(var i in Enumerable.Range(0, 100))
{

}
Этот приём можно использовать для любой коллекции.

Вот ещё пример:
count > 100.if
Выбор шаблона if создаст следующий блок:
if(count > 100)
{

}
Шаблонов много, можете посмотреть полный список здесь.

5. Комплексный анализ решения
ReSharper постоянно анализирует всё ваше решение и находит ошибки и предупреждения. Как ошибки компиляции, так и ошибки времени выполнения. Это можно использовать как своего рода проверку работоспособности. Всякий раз, когда вы выполняете рефакторинг большого количества кода, эта функция действительно полезна, чтобы убедиться, что вы не делаете ошибок. Понятно, что находятся очевидные ошибки. ReSharper пока не может найти логические ошибки вместо разработчика.
Комплексный анализ решения отключен по умолчанию по уважительным причинам. Он съедает производительность. По крайней мере, при использовании Visual Studio + ReSharper. С другой стороны, если вы используете Rider, вы, вероятно, даже не заметите, что он включен.

6. Извлечение класса
Одна из самых впечатляющих особенностей ReSharper - это его возможности рефакторинга. К большинству из них можно получить доступ из меню Refactor This, доступного с помощью сочетания клавиш Ctrl+Shift+R. Наиболее впечатляющий вид – извлечение класса (Extract Class). Он извлечёт поля, свойства и методы, в новый класс, который будет добавлен в исходный класс как поле. При нажатии Ctrl+Shift+R на одном из членов исходного класса появляется диалоговое окно, где вы можете выбрать члены, которые нужно извлечь в новый класс, назвать новый класс и поле исходного класса, в которое он будет внедрён, а также выбрать, будет ли класс создан в том же файле или в отдельном.
Это значительно упрощает обычное действие по разбиению большого класса на более мелкие.

Источник: https://michaelscodingspot.com/productivity-in-resharper-and-rider/
👍2
День девятьсот тридцать четвёртый.
4 Мифа о Юнит-Тестах
Многие разработчики выступают против модульного тестирования или просто используют подход «абстрагируйте и имитируйте всё, что можно». Сегодня рассмотрим 4 самых распространённых мифа о модульном тестировании.

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

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

2. Это сложно или занимает слишком много времени
Когда вы впервые начнёте писать модульные тесты, это, вероятно, покажется сложным. Как и в первый раз, когда вы сели за руль. Педаль газа, тормоза, поворотники, зеркало заднего вида… Всё новое. Но как только вы преодолеете первоначальные трудности, вождение покажется простой задачей. И это открывает новый мир возможностей, который вы можете свободно исследовать. С модульным тестированием то же самое. По мере накопления опыта время, затрачиваемое на написание тестов, резко сокращается, что повышает окупаемость ваших усилий.

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

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

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

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

Источник: https://enterprisecraftsmanship.com/
Автор оригинала: Vladimir Khorikov
День девятьсот тридцать пятый. #TipsAndTricks
Использование Сценариев и CLI
Одна из моих любимых особенностей новой платформы .NET Core/.NET 5 - это упор на интерфейс командной строки. В .NET Framework этого не было. В первую очередь он предназначался для использования с Visual Studio и IIS, и поставлялся в то время, когда большинство приложений для Windows не предлагали реализацию из командной строки, по крайней мере, не в качестве полноценной опции.

Сегодня большинство вещей в Windows можно создавать с помощью сценариев, и практически всё, что вы хотите делать в .NET, вы можете делать из CLI. Даже для вещей, которые обычно требовали IDE или ручного редактирования файлов проекта. Некоторые из этих вещей сначала были доступны в виде сценариев PowerShell, но позже появились кроссплатформенные CLI, которые теперь кажутся стандартом. Будь то управление ресурсами Azure или создание и тестирование проектов dotnet, интерфейсы командной строки доступны и, как правило, довольно просты в использовании.

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

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

В качестве простого примера я привык использовать простой скрипт для создания небольших решений, используя то соглашение, которое я предпочитаю. Для небольших образцов и даже более крупных репозиториев, в которых есть одно решение, мне нравится, когда файл решения находится в корне репозитория git, а проекты – в папках src и tests. Создание такой структуры с помощью Visual Studio утомительно, потому что Visual Studio не любит раскладывать вещи по папкам по умолчанию. Но с помощью нескольких строк кода в CLI легко получить именно тот вариант, который вы хотите.

Типичная структура проекта:
- папка src – содержит код,
- папка tests – содержит все виды тестов,
- файл решения CompanyName.ApplicationName.sln

Чтобы создать такую структуру я просто использую небольшой скрипт, изменяя имена по необходимости:
dotnet new sln

mkdir src
mkdir tests

dotnet new console -o src/Sample.Console
dotnet sln add src/Sample.Console/Sample.Console.csproj

Первый шаг создает новое пустое решение. По умолчанию он будет иметь то же имя, что и папка, в которой вы находитесь, что обычно соответствует имени вашего репозитория git. Если вы хотите указать имя, просто добавьте к этой команде параметр -n {ИМЯ}.

Второй шаг - создать подпапки src и tests. Вы также можете добавить сюда дополнительные папки, если хотите.

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

Источник: https://ardalis.com/script-new-dotnet-solution-from-cli/
Автор оригинала: Steve "Ardalis" Smith
День девятьсот тридцать шестой. #ЧтоНовенького
Поддержка нескольких репозиториев в Visual Studio 2022
Вам когда-нибудь приходилось работать над решением с проектами, размещёнными в разных репозиториях Git? Раньше вам пришлось бы либо использовать несколько экземпляров Visual Studio, либо полагаться на сторонние инструменты для работы с Git. Начиная с Visual Studio 2022 Preview 3, вы можете включить превью функцию поддержки нескольких репозиториев, которая позволит вам работать в одном решении с проектами в нескольких репозиториях и вносить изменения в них в одном экземпляре Visual Studio.

Самый простой способ включить поддержку нескольких репозиториев - использовать CTRL+Q, ввести «preview» и открыть панель функций предварительного просмотра. Прокрутите вниз до пункта «Enable multi-repo support» («Включить поддержку нескольких репозиториев») и установите флажок.

Если у вас уже есть решение с проектами, размещенными в разных репозиториях Git, просто откройте его в начальном окне Visual Studio или с помощью меню File > Open > Project/Solution (Файл > Открыть > Проект/Решение), и Visual Studio автоматически подключит до 10 репозиториев одновременно. Вы сможете узнать, активировала ли Visual Studio различные репозитории Git, посмотрев на средство выбора репозитория в строке состояния (в правом нижнем углу), которое покажет вам количество активных репозиториев. Активные репозитории будут выделены жирным шрифтом в средстве выбора репозиториев.

Вы также можете добавить проекты, размещённые в разных репозиториях, к существующему решению, щёлкнув правой кнопкой мыши своём решении в обозревателе решений и выбрав Add > Existing Project (Добавить > Существующий Проект).

Окно изменений Git автоматически отслеживает изменения в разных репозиториях. Всё, что вам нужно сделать, это написать сообщение и нажать кнопку «Commit All Repos». Вы также можете сначала выполнить stage изменений, что позволит вам выбрать репозитории, куда вы хотите внести изменения. Либо можно выбрать репозиторий в верхней части окна Git Changes, чтобы зафиксировать изменения только в одном репозитории. См. рисунок ниже.

Поддержка нескольких репозиториев для Amend, Stash, переключения между ветками и сетевых операций, включая Pull, Push, Fetch и Sync, появится в окне Git Changes в будущих итерациях. Чтобы использовать любую из этих операций сейчас, вам нужно сначала выбрать репозиторий, чтобы выполнить операцию только на выбранном репозитории.

Источник: https://devblogs.microsoft.com/visualstudio/multi-repo-support-in-visual-studio/
День девятьсот тридцать седьмой. #TipsAndTricks
Как Измерить Прошедшее Время без Аллокаций
Есть много случаев, когда вам нужно вычислить время выполнения метода. Классический способ - использовать класс Stopwatch. Это ссылочный тип, поэтому его создание может увеличить нагрузку на сборщик мусора. В случае однопоточного приложения вы можете повторно использовать экземпляр, чтобы избежать создания большого количества экземпляров. Однако в многопоточном приложении может быть сложнее повторно использовать экземпляры. Вы можете использовать поле [ThreadStatic] или ObjectPool<Stopwatch>, но и за это придется заплатить производительностью.

Если вам не нужны все функции Stopwatch, такие как остановка и перезапуск секундомера, вы можете создать структуру, которая предоставляет только минимум функционала. Таким образом, можно легко замерить время без каких-либо аллокаций. Идея состоит в том, чтобы использовать значение Stopwatch.GetTimestamp() при инициализации структуры и при вычислении прошедшего времени. Затем вычислить разницу, чтобы получить искомое время.

// За основу взят код отсюда: https://github.com/dotnet/runtime/blob/26b6e4ea97a627ab800362b2c10f32ebecea041d/src/libraries/Common/src/Extensions/ValueStopwatch/ValueStopwatch.cs

using System.Diagnostics;
public readonly struct ValueStopwatch
{
private static readonly double _timeToTicks =
TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;

private readonly long _startTimestamp;

private ValueStopwatch(long startTimestamp)
=> _startTimestamp = startTimestamp;

public static ValueStopwatch StartNew()
=> new ValueStopwatch(GetTimestamp());

public static long GetTimestamp()
=> Stopwatch.GetTimestamp();

public static TimeSpan
GetElapsedTime(long start, long end) {
var delta = end - start;
var ticks = (long)(_timeToTicks * delta);
return new TimeSpan(ticks);
}

public TimeSpan GetElapsedTime()
=> GetElapsedTime(_startTimestamp, GetTimestamp());
}

Использование:
var stopwatch = ValueStopwatch.StartNew();
// измеряемый код
Console.WriteLine(stopwatch.GetElapsedTime());

Источник: https://www.meziantou.net/how-to-measure-elapsed-time-without-allocating-a-stopwatch.htm
День девятьсот тридцать восьмой. #Курсы
10 Фактов о Microsoft Learn, Которые Полезно Знать
В Microsoft Learn есть ресурсы, необходимые для развития ваших навыков, а также инструменты, которые помогут вам добиться большего для вашей команды, вашей организации и вашей карьеры. Вот 10 фактов о Microsoft Learn, которые вам следует знать:

1. Учитесь бесплатно, в удобном для вас темпе
Вы можете бесплатно получить доступ к интерактивным материалам для самостоятельного обучения и учиться в удобном для вас темпе и в удобное для вас время.

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

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

4. Создайте собственную коллекцию контента и поделитесь ею
Создавайте и делитесь наборами обучающего контента, технической документации, образцов кода, архитектуры и многого другого с помощью коллекций в Microsoft Learn. Коллекции позволяют вам составить и поделиться личным планом занятий, который поможет подготовиться и вам, и другим.

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

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

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

8. Зарабатывайте значки и трофеи
По мере изучения материалов для самостоятельного обучения собирайте значки и трофеи, отслеживая свой прогресс в своём профиле. Когда вы получаете сертификат Microsoft, вы получаете значок сертификата, подтверждающий, что у вас есть технические навыки.

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

10. Смотрите телевизор и учитесь
У Microsoft Learn есть телеканал Learn TV. Смотрите прямые трансляции, шоу и обучающие видеоролики, чтобы узнать, как создавать решения с использованием продуктов Microsoft, от экспертов, которые эти продукты создали.

Источник: https://techcommunity.microsoft.com/t5/microsoft-learn-blog/10-facts-you-should-know-about-microsoft-learn/ba-p/2038073
День девятьсот тридцать девятый. #ЧтоНовенького
Превью Функции в .NET 6. Начало
В .NET 6 представлены несколько новых функций, пока в виде превью. Это значит, что они не поддерживаются для использования в производственной среде в .NET 6. Они пока выпущены для оценки сообществом и предоставления обратной связи относительно сценариев их использования и возможных улучшений.

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

1. Статические абстрактные члены интерфейсов
Как видно из названия, это означает, что теперь вы можете объявлять статические абстрактные методы как часть интерфейса и реализовывать их в производном типе. Простой, но мощный пример этого - IParseable, который позволяет определять контракт парсинга строки для создания данного типа:
public interface IParseable<TSelf>
where TSelf : IParseable<TSelf> {
static abstract TSelf Parse(
string s,
IFormatProvider? provider);

static abstract bool TryParse(
[NotNullWhen(true)] string? s,
IFormatProvider? provider,
out TSelf result);
}

public readonly struct Guid : IParseable<Guid>
{
public static Guid Parse(
string s, IFormatProvider? provider)
{
/* Реализация */
}

public static bool TryParse(
[NotNullWhen(true)] string? s,
IFormatProvider? provider, out Guid result)
{
/* Реализация */
}
}

Особенности:
- Теперь вы можете объявлять элементы интерфейса, которые одновременно являются статическими и абстрактными.
- В настоящее время это не поддерживается для методов интерфейса с реализацией по умолчанию, поэтому сочетание static virtual не является допустимой комбинацией.
- Эта функциональность доступна только для интерфейсов, она недоступна для других типов, таких как абстрактный класс.
- Эти члены недоступны через интерфейс, то есть IParseable<Guid>.Parse(someString, null) приведет к ошибке компиляции.

Поясним последний пункт. Обычно абстрактные или виртуальные члены вызываются через какую-либо виртуальную диспетчеризацию (при полиморфном использовании). Для статических методов у нас нет объекта или экземпляра, поэтому среда выполнения не сможет определить, что IParseable<Guid>.Parse(…) должно разрешиться в Guid.Parse. Чтобы это работало, нужно где-то указать фактический тип, и это можно сделать с помощью дженериков:
public static T InvariantParse<T>(string s)
where T : IParseable<T>
{
return T.Parse(s, CultureInfo.InvariantCulture);
}

В этом случае среда выполнения может определить, какой метод Parse следует разрешить, подсмотрев его на конкретном используемом T. Если пользователь указал InvariantParse<int>(someString), он будет преобразован в метод Parse из System.Int32. А InvariantParse<Guid>(someString) будет преобразован в метод Parse из System.Guid и так далее.

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

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

Источник:
https://devblogs.microsoft.com/dotnet/preview-features-in-net-6-generic-math/
День девятьсот сороковой. #ЧтоНовенького
Превью Функции в .NET 6. Продолжение
Начало

2. Обобщённая математика
Одна из давно востребованных функций .NET - это возможность использовать операторы для обобщённых типов. Нововведение добавляет возможность писать обобщённый код относительно, например, числовых типов, на которые наложены ограничения в виде интерфейсов с нужными операторами. Таким образом, алгоритмы могут выражены в следующем виде:
// Интерфейс определяет статические свойства и операторы
interface IAddable<T> where T : IAddable<T>
{
static abstract T Zero { get; }
static abstract T operator +(T t1, T t2);
}

// Классы и структуры (включая встроенные) реализуют интерфейс
struct Int32 : …, IAddable<Int32>
{
public static Int32 operator +(Int32 x, Int32 y)
=> x + y;
public static Int32 Zero => 0;
}

// Обобщённые алгоритмы могут использовать статические члены типа Т
public static T AddAll<T>(T[] ts)
where T : IAddable<T>
{
// вызов статического свойства
T result = T.Zero;
// вызов статического оператора +
foreach (T t in ts) { result += t; }
return result;
}

Это стало возможным благодаря появлению нескольких новых статических абстрактных интерфейсов, которые соответствуют различным операторам, доступным для языка, и предоставлению нескольких других интерфейсов, представляющих обобщённые функции, такие как синтаксический анализ или обработка чисел. Интерфейсы были разработаны для расширяемости и повторного использования и поэтому обычно представляют лишь отдельные операторы или свойства. Например, в одном интерфейсе не используются парные операции, такие как умножение и деление, поскольку они подходят не для всех типов. Matrix4x4*Matrix4x4 является допустимым, а Matrix4x4/Matrix4x4 - нет. Кроме того, интерфейсы обычно позволяют типам исходных данных и результата различаться, чтобы поддерживать такие сценарии, как double = TimeSpan/TimeSpan или Vector4 = Vector4*float.

Вот некоторые из новых интерфейсов:
- INumber – члены общие для числовых типов,
- IFloatingPoint – члены общие для чисел с плавающей точкой,
- IAdditionOperatorsx+y,
- ISubtractionOperatorsx–y,
- IMultiplyOperatorsx*y,
- IDivisionOperatorsx/y,
- IComparisonOperatorsx<y, x>y, x<=y и x>=y,
- IEqualityOperatorsx==y и x!=y,
- IIncrementOperators++x и x++.

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

Источники:
-
https://devblogs.microsoft.com/dotnet/preview-features-in-net-6-generic-math/
-
https://habr.com/ru/post/572902/
👍1
День девятьсот сорок первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
96. Ваши Клиенты Говорят Не То, Что Думают
Я никогда не встречал клиента, который не был бы счастлив описать мне в деталях, что он хочет. Проблема в том, что клиенты не всегда говорят вам всей правды. Обычно они не лгут, но говорят на языке клиентов, а не разработчиков. Они используют свои термины и контекст. Они не учитывают важные детали. Они предполагают, что вы проработали в их компании 20 лет, как и они. Это усугубляется тем фактом, что многие клиенты вообще не знают, чего хотят! Некоторые имеют представление о «большой картине», но редко могут хорошо рассказать о деталях. Другие могут вообще слабо представлять, что хотят, но твёрдо знать, чего они не хотят. Так как же вы можете доставить программный продукт тому, кто не говорит вам всю правду о том, чего он хочет? Это довольно просто. Просто больше взаимодействуйте с ними.

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

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

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

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Nate Jackson
День девятьсот сорок второй. #юмор
Знакомо?
День девятьсот сорок третий. #ЗаметкиНаПолях
Почему Вы Всегда Должны Разрабатывать в Среде "Development" в
ASP.NET
В .NET Core/5+ появилось понятие «среды». Среды используются для описания различных этапов на пути к производственному коду. Например, локальная разработка, тестирование, staging, production и т.д. У вас может быть неограниченное количество сред, и нет никаких правил о том, как вы их называете. Или есть?

Недавно я помогал коллеге решить проблему, которая возникала только в одной среде (первом этапе CD в Azure). В других средах проблем не было. Возникала ошибка “Cannot Consume Scoped Service From Singleton“ (Невозможно Получить Scoped Сервис из Синглтон Сервиса). В общем-то решить её было довольно просто, но почему же она возникала только в этой среде?

«Известные» среды в .NET
Как сказано выше, правил именования сред в .NET нет. Однако, существуют 3 «предустановленные» среды: Development, Staging и Production. Мы даже можем использовать в коде специальные методы:
env.IsDevelopment();
env.IsProduction();
//Проверяет, называется ли текущая среда Test1
env.IsEnvironment("Test1");

На самом деле, под капотом IsDevelopment просто вызывает IsEnvironment(“Development”). Вроде всё логично.

Возвращаясь к проекту. Там среда разработки называлась “Local”, а первый этап CD в Azure назывался “Development”. Таков был корпоративный стандарт, вроде никаких проблем возникать не должно, просто используем
env.IsEnvironment("Local");
вместо
env.IsDevelopment();

Проверки на IsDevelopment во фреймворке
А что там в коде собственно .NET, написанном Microsoft? В принципе уже должно быть очевидно: проблема в том, что Microsoft ожидает, что среда вашей локальной разработки будет называться именно «Development». Не «Local», не «Dev», не «DevMachine», а «Development». Даже когда мы создаём новое веб-приложение ASP.NET Core, мы получаем шаблонный код, который выглядит так:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

Поэтому я полез в исходный код .NET (как же хорошо иметь исходники!), и нашёл это:
bool isDevelopment = context.HostingEnvironment.IsDevelopment();
options.ValidateScopes = isDevelopment;
options.ValidateOnBuild = isDevelopment;

Установка ValidateScopes в true фактически запускает проверку захвата сервисов и выдаёт упомянутое выше исключение «Cannot use scoped service from singleton». Поскольку среда разработки называлась «Local», а среда CD - «Development», мы видели исключение только в CD.

Очевидно, что называть CD среду как «Development», скорее всего, неправильно. Но думаю, что есть масса разработчиков, называющих свою локальную среду разработки как угодно, даже не осознавая, что глубоко в коде .NET есть проверка, что среда называется именно «Development» и никак иначе.

Источник: https://dotnetcoretutorials.com/2021/08/06/why-you-should-always-use-asp-net-development-environment-for-local-development/
День девятьсот сорок четвёртый. #Оффтоп
Советы по Улучшению Ваших Навыков Разработки в .NET. Начало

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

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

«Если вы знаете врага и знаете себя, вам не нужно бояться результата сотни сражений. Если вы знаете себя, но не знаете врага, при каждой одержанной победе вы также будете терпеть поражение. Если вы не знаете ни врага, ни себя, вы проиграете в каждой битве».
- Сунь-цзы, Искусство войны

Зная себя и свои инструменты, вы сможете привести свои программные проекты к успеху. По крайней мере, я так понимаю смысл этой цитаты.

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

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

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

Когда я освоился с F#, я заметил, что нахожу время, чтобы продумать, как должны формироваться данные. Не только форма имеет значение, но и её характеристики и то, как она будет связана с другими компонентами. Будучи более строгим языком, чем C#, F# заставляет меня тратить больше времени на обдумывание и проектирование того, как части будут объединены для достижения своей цели (целей). Когда я вижу, что часть данных становится слишком сложной, я быстро разбиваю её на более мелкие компоненты, чтобы чтение кода было менее утомительным для тех, потребуется понять предназначение системы/приложения.

Это оказывает существенное влияние на подход к созданию ПО. Я применял эту концепцию всякий раз, когда разрабатывал ПО на C# или другом языке. Кроме того, выявление взаимосвязей в данных поможет вам во многих отношениях. Тот, кто будет поддерживать код сможет легче понять разницу между построением отношений и реальной бизнес-логикой. Улучшение жизни тех, кто читает ваш код, улучшает вас как разработчика. Вы продемонстрируете черту великих разработчиков: эмпатию к коллегам.

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

Источник:
https://kevinavignon.com/2020/12/23/guidelines-to-improve-your-software-design-skills-with-net-part-i/
Автор оригинала: Kevin Avignon
👍1
День девятьсот сорок пятый. #Оффтоп
Советы по Улучшению Ваших Навыков Разработки в .NET. Продолжение
Начало

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

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

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

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

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

Это также поможет вам обрести уверенность в решении текущих вопросов. Только после того, как у вас будет готовое решение, вы должны искать способы его улучшения. Улучшить решение можно:
- Проверив граничные случаи в вашей реализации.
- Использовав передовые методы, такие как механизм кэширования.
- Использовав более подходящие структуры данных для вашей конкретной проблемы. Например, существует множество сценариев, в которых хеш-таблица является отличной структурой данных для улучшения вашего решения.

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

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

Источник:
https://kevinavignon.com/2020/12/23/guidelines-to-improve-your-software-design-skills-with-net-part-i/
Автор оригинала: Kevin Avignon
День девятьсот сорок шестой. #Оффтоп
Советы по Улучшению Ваших Навыков Разработки в .NET. Продолжение
Начало
Продолжение

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

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

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

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

6. Несмотря на гибкость, List<T> не всегда будет лучшей коллекцией для использования
Изучение структур данных - это ключевой компонент, который поможет вам постоянно совершенствоваться. От вас всегда ждут, что вы понимаете, как всё работает под капотом. От вас требуется глубокое понимание кода и систем, которые вы разрабатываете или обслуживаете. Использование правильной структуры данных может быть разницей между быстро и медленно работающим алгоритмом. Как разработчик вы бы не хотели создать систему, которая не может обрабатывать большой объём данных из-за плохой реализации.

Современные языки, такие как C#, позволяют разработчикам безболезненно писать плохо продуманный код. Например, из коллекций можно всегда использовать только List<T>. Почему это плохо? Отличный вопрос, особенно потому, что ваша IDE не предупреждает вас о том, что вы, вероятно, могли бы сделать лучше.

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

Возвращаясь к List<T>. Он удобен, если вы не знаете заранее размер нужного вам массива. Но в нём нет никакой магии. Под капотом он выделяет всё тот же массив (по умолчанию из 4х элементов). Когда место в нём заканчивается, этот массив копируется в новый, в 2 раза больше. Это важно понимать, что вы будете выделять избыточную память для вашей коллекции данных, добавляя элементы, каждый раз, когда вы достигаете предела ёмкости коллекции. Если у вас есть возможность узнать размер коллекции в момент инициализации, лучше всего его предоставить.

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

Источник:
https://kevinavignon.com/2020/12/23/guidelines-to-improve-your-software-design-skills-with-net-part-i/
Автор оригинала: Kevin Avignon
День девятьсот сорок седьмой. #Оффтоп
Советы по Улучшению Ваших Навыков Разработки в .NET. Окончание
Начало
Продолжение
Продолжение

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

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

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

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

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

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

В заключение
- Разработчики ПО должны понимать все, что связано с приложением, которое они разрабатывают/обслуживают.
- При реализации кода проявляйте эмпатию. Человек, исправляющий ошибку в этом коде, может быть вами, но спустя 3 года. К тому времени вы забудете, о чём думали, когда писали этот код.
- Убедитесь, что понимаете компромиссы по объёму данных и времени, решая, какой подход лучше подходит для решения проблемы. Здесь не существует серебряной пули. Выберите один вариант и живите с этим.
- Не переусердствуйте с проектированием функции/класса/архитектуры ПО. Это может сделать будущие итерации разработки нестабильными и затруднить внесение изменений.
- Реализация без тестов производительности - это просто мнение разработчика о его ощущения. Вы не можете утверждать, что ваш код быстрый, без каких-либо подтверждающих фактов. Используйте BenchmarkDotNet для исследования производительности.
- Постарайтесь сначала разобраться в проблеме и подумать об альтернативных подходах, прежде чем бросаться за реализацию.
- При оптимизации решения нужно учесть множество факторов и соображений. Например, имеет ли смысл тратить месяц на рефакторинг кода, когда компания спешит стать первым приложением на рынке?

Источник: https://kevinavignon.com/2020/12/23/guidelines-to-improve-your-software-design-skills-with-net-part-i/
Автор оригинала: Kevin Avignon