.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
День девятьсот семнадцатый. #Оффтоп
Отбываю в (очень) жаркую страну отдохнуть. Посты продолжат выходить, но, возможно, не такие информативные, как обычно.

А пока сообщу вам, что у нас появилось сообщество на Яндекс.Кью, куда будут дублироваться посты, и где можно пообщаться отдельно. Зачем это всё надо, я пока не совсем понимаю. Просто предложили сделать автопостинг туда, ну пусть будет. Выживет так выживет. Да, посты пока туда публикуются немного криво. Не обессудьте, все вопросы в Яндекс.Кью :)

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

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

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

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

2. Наставничество улучшает софт скилы
В любой профессии ваш набор навыков можно разделить на две категории: «жёсткие» (hard) и «мягкие» (soft). Жёсткие навыки, как правило, представляют собой «техническую» часть вашей профессии (написание кода, разработка архитектуры, контроль версий и т. д.). Мягкие навыки, такие как общение и командная работа, труднее поддаются количественной оценке. Наставляя других, вы обучаете жёстким навыкам, используя свои мягкие навыки, и у вас обоих есть шанс стать лучше.

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

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

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

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

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

Источник:
https://stackoverflow.blog/2021/07/07/the-unexpected-benefits-of-mentoring-others/
Автор оригинала - Matt Studdert
👍1
День девятьсот девятнадцатый. #Оффтоп
Неожиданные Преимущества Наставничества. Окончание
Начало

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

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

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

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

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

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

Где наставлять других
1. Отвечать на вопросы
Stack Overflow - ярчайший пример. Если успеете! По опыту ответ на новый вопрос появляется там быстрее, чем вы успеете его напечатать, если только это не супер узкая тема. Есть русская версия, там в этом плане попроще.

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

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

2. Наставничество один-на-один
CodingCoach - это бесплатная платформа с открытым исходным кодом, которая сводит наставников-добровольцев с подопечными.

3. Отзывы о задачах на кодирование
Если вы предпочитаете более алгоритмические упражнения, то отзывы на таких платформах, как Codewars и Exercism, могут быть идеальными. Поскольку многие люди выполняют упражнения и ждут отзывов, эти платформы всегда ищут разработчиков, которые поддержат других.

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

Источник: https://stackoverflow.blog/2021/07/07/the-unexpected-benefits-of-mentoring-others/
Автор оригинала - Matt Studdert
👍1
День девятьсот двадцатый. #Оффтоп #Курсы
30-дневный Челлендж от Microsoft
30-дневный Челлендж от Microsoft может помочь вам развить свои навыки подготовиться к сертификации Майкрософт. Курс содержит теоретические материалы и практические задания, выполнив которые вы получите скидку в 50% на соответствующий экзамен Майкрософт. Челленджи предлагаются по следующим направлениям:

1. Azure AI Fundamentals
Фундамент для использования концепций машинного обучения и искусственного интеллекта, таких как компьютерное зрение, обработка естественных языков и виртуальный собеседник на основе ИИ.
Экзамен AI-900: Microsoft Azure AI Fundamentals

2. Azure Solutions Architect
Узнайте, как с помощью инфраструктуры Azure усовершенствовать свои приложения и стать архитектором решений Azure.
Экзамены:
- AZ-303: Microsoft Azure Architect Technologies
- AZ-304: Microsoft Azure Architect Design

3. Microsoft 365 Developer
Разрабатывайте, создавайте, тестируйте и обслуживайте приложения и решения с помощью Microsoft 365, Microsoft Teams, Microsoft Identity и Microsoft Graph.
Экзамен MS-600: Building Applications and Solutions with Microsoft 365 Core Services

4. Azure IoT Developer
Научитесь внедрять и обслуживать облачные и периферийные компоненты решений из сферы Интернета вещей.
Экзамен AZ-220: Microsoft Azure IoT Developer

5. Azure Developer
Участвуйте во всех этапах разработки комплексных облачных решений. Проектируйте, создавайте, тестируйте и обслуживайте облачные приложения с помощью служб вычислений, хранения, управления и обеспечения безопасности на платформе Azure.
Экзамен AZ-204: Developing Solutions for Microsoft Azure

6. Java on Azure Developer
Начните разрабатывать современные приложения на Java в облаке с использованием служб управляемых вычислений, базами данных и DevOps.
Экзамен AZ-204: Developing Solutions for Microsoft Azure

7. Power Platform App Maker
Создавайте решения, включающие в себя приложения, функции ИИ и отчетность, практически без написания программного кода и необходимости что-то настраивать.
Экзамен PL-100: Microsoft Power Platform App Maker

8. DevOps Engineer
Проектируйте и внедряйте процессы и методы DevOps. Управляйте исходным кодом с помощью GitHub для оптимизации взаимодействия и автоматизации процессов разработки и развертывания.
Экзамен AZ-400: Designing and Implementing Microsoft DevOps Solutions

9. Azure Data Scientist
Узнайте, как создавать модели машинного обучения, прогнозные модели без написания программного кода и решения в сфере машинного обучения, а также выполнять обработку и анализ данных в облаке.
Экзамен DP-100: Designing and Implementing a Data Science Solution on Azure

10. Azure Synapse Analytics
Научитесь интегрировать, преобразовывать и консолидировать данные из различных структурированных и неструктурированных систем, чтобы получать структуры данных, на основе которых можно строить решения для аналитики.

Источник: https://developer.microsoft.com/ru-ru/offers/30-days-to-learn-it
День девятьсот двадцать первый. #юмор
День девятьсот двадцать второй. #DesignPatterns #Microservices
Паттерны в Микросервисах
9. Внешняя конфигурация
Каждое бизнес-приложение имеет множество параметров конфигурации для различной инфраструктуры (например, база данных, сеть, адреса подключенных служб, учетные данные, путь к сертификату). Кроме того, в корпоративной среде приложение обычно развёртывается в различных средах выполнения (локальной, тестовой, производственной). Один из способов добиться этого - использовать конфигурацию внутри каждого приложения в каждом случае, что является фатальной плохой практикой. Это может привести к серьёзным угрозам безопасности, поскольку производственные учётные данные могут быть легко скомпрометированы. Кроме того, при любом изменении параметра конфигурации необходимо пересобрать приложение. Это ещё более важно в микросервисной архитектуре, поскольку у нас потенциально есть сотни сервисов.

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

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

Минусы
- Нам нужно выбрать фреймворк, поддерживающий внешнюю конфигурацию.

Когда использовать
- Любое серьезное производственное приложение должно использовать внешнюю конфигурацию.

Когда не использовать
- В тестовых приложениях.

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

Подробнее
- Microservices Pattern: Externalized configuration
- Build Once, Run Anywhere: Externalize Your Configuration

Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍1
День девятьсот двадцать третий. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
94. Пишите тесты для людей
Вы пишете тесты для части или для всего вашего кода? Поздравляю! Вы пишете тесты перед написанием кода? Ещё лучше! Это делает вас одним из первых, кто встал на передовые позиции в области разработки программного обеспечения. Но хорошие ли вы пишете тесты? Как вы можете их оценить? Один из способов - спросить: «Для кого я пишу тесты?» Если ответ - «Для себя, чтобы избавить себя от усилий по исправлению ошибок» или «Для компилятора, чтобы убедиться, что они проходят», то велика вероятность, что вы пишете не самые лучшие тесты. Так для кого же вы должны писать тесты? Для человека, пытающегося понять ваш код.

Хорошие тесты служат документацией для кода, который они тестируют. Они описывают, как работает код. Для каждого сценария использования тест(ы):
1. Описывают контекст, отправную точку или предварительные условия, которые должны быть выполнены.
2. Иллюстрируют, как запускается программное обеспечение.
3. Описывают ожидаемые результаты или постусловия, которые необходимо проверить.

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

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

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Gerard Meszaros
👍1
День девятьсот двадцать четвёртый. #ЧтоНовенького
.NET 6: Улучшения Потоковой Обработки. Начало
Продолжаем знакомиться с новинками .NET 6.

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

1. Асинхронный Parallel.ForEach
Когда был создан класс Parallel, в C# не было языковой поддержки асинхронного программирования. Хотя в .NET 1.1 был шаблон IAsyncResult, он не получил широкого распространения, и подавляющее большинство кода было разработано для синхронного выполнения.

Это стало проблемой, поскольку акцент сместился на асинхронный код с использованием async/await. В настоящее время нет встроенной поддержки для запуска операции Parallel.ForEach и асинхронного ожидания результата.

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

Чтобы решить эту проблему, был создан набор методов Parallel.ForEachAsync. Каждый метод принимает IEnumerable или IAsyncEnumerable. Опционально могут быть переданы экземпляр ParallelOptions или токен отмены:
public static Task ForEachAsync<TSource>(
IEnumerable<TSource> source,
ParallelOptions parallelOptions,
Func<TSource, CancellationToken, ValueTask> body);
public static Task ForEachAsync<TSource>(
IAsyncEnumerable<TSource> source,
CancellationToken cancellationToken,
Func<TSource, CancellationToken, ValueTask> body);

Parallel.ForEachAsync - один из редких случаев, когда вместо Task используется ValueTask. Основная идея здесь в том, что поскольку значения будут обрабатываться в цикле, дополнительные накладные расходы на создание полного объекта Task неоправданы.

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

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

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

Источник:
https://www.infoq.com/news/2021/08/net6-Threading/
👍1
День девятьсот двадцать пятый. #ЧтоНовенького
.NET 6: Улучшения Потоковой Обработки. Окончание
Начало

2. Thread.ManagedThreadId устарел
Свойство Environment.CurrentManagedThreadId было введено в .NET 4.5 как более эффективная альтернатива свойству Thread.ManagedThreadId. Однако об этом никогда не сообщалось в документации, и разработчики продолжают использовать Thread.ManagedThreadId.

Чтобы направить разработчиков к лучшему варианту, для Thread.ManagedThreadId было добавлено предупреждение для анализатора кода.

Хотя это фактически означает, что Thread.ManagedThreadId устарел, он не помечается как устаревший. Разработчики могут продолжать использовать его в обозримом будущем, даже при том, что Environment.CurrentManagedThreadId теперь является предпочтительным.

3. Thread.UnsafeStart
Новая функция для запуска потоков называется «небезопасной», потому что она не захватывает контекст выполнения. UnsafeStart был добавлен, потому что нужно было лениво создавать потоки пула потоков и поток таймера в контексте выполнения по умолчанию. UnsafeStart избегает захвата текущего контекста выполнения и его восстановления при запуске потока. Есть и другие места, где создаются потоки, которые могут использовать аналогичную логику.
Эта функция уже используется:
- в FileSystemWatcher для OS X,
- в SocketAsyncEngine для Unix,
- в CounterGroup в Tracing API,
- в ThreadPoolTaskScheduler, когда задача помечена как LongRunning.

При запуске в браузере UnsafeStart выбросит PlatformNotSupportedException.

4. Класс PeriodicTimer
Класс PeriodicTimer предназначен для использования в асинхронном контексте. Как вы можете видеть ниже, необходимо использовать await между каждым тиком таймера:
var second = TimeSpan.FromSeconds(1);
using var timer = new PeriodicTimer(second);
while (await timer.WaitForNextTickAsync())
Console.WriteLine($"Tick {DateTime.Now}");

Основные свойства класса PeriodicTimer:
- Этот API имеет смысл только для таймеров, которые срабатывают многократно. Таймеры, которые срабатывают один раз, могут быть основаны на задачах (у нас уже есть Task.Delay для этого).
- Таймер будет приостановлен во время выполнения кода пользователя и вернёт следующий тик после его завершения.
- Таймер можно остановить с помощью CancellationToken.
- Контекст выполнения не захватывается.

Таймер также можно остановить, вызвав Stop или Dispose, даже если в настоящее время выполняется вызов WaitForNextTickAsync.

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

Интересный факт: класс PeriodicTimer будет первым таймером, который разделит пространство имен с другим таймером. Ранее каждый таймер помещался в отдельное пространство имен:
- System.Timers.Timer
- System.Threading.Timer
- System.Windows.Forms.Timer
- System.Web.UI.Timer
- System.Windows.Threading.DispatcherTimer

Источник: https://www.infoq.com/news/2021/08/net6-Threading/
👍2
День девятьсот двадцать шестой. #юмор
Лайк, если было такое)))
День девятьсот двадцать седьмой. #ЧтоНовенького
System.Threading.RateLimiting для .NET
Хотя ограничение пропускной способности является хорошо известной проблемой для веб-серверов, существует множество других ситуаций, когда требуются аналогичные возможности. Например, клиентское приложение может выиграть, если будет иметь собственное встроенное ограничение, чтобы оно не заставляло срабатывать ограничения веб-сервера. И для других ресурсов, таких как файловые серверы и серверы баз данных, могут потребоваться ограничения пропускной способности, чтобы клиенты не могли монопольно использовать их.

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

Абстрактный базовый класс, который должны реализовать все ограничители, просто называется RateLimiter. Он предлагает как синхронный, так и асинхронный способ получения слота (lease), а также подсчёт доступных слотов. Слот - это разрешение ограничителя на выполнение работы. Он представлен классом RateLimitLease, который должен быть возвращён в пул после завершения текущей задачи.

В настоящее время предлагаются четыре встроенных ограничителя. Самым простым является ConcurrencyLimiter, который, как семафор, позволяет одновременно использовать только определённое количество параллельных рабочих процессов.

FixedWindowRateLimiter и SlidingWindowRateLimiter ограничивают количество запросов в течение заданного временного окна. Первый использует простой временной интервал для сброса счетчика. Второй предлагает более сложный вариант, когда временное окно разделено на N сегментов со счётчиком запросов для каждого сегмента.

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

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

Один из вариантов использования, который эта библиотека явно не поддерживает, - это агрегированные ограничители. Объясняется это тем, что для поддержки сценариев, в которых требуется агрегированный ограничитель, требуется отдельная абстракция. К примеру, чтобы реализовать ограничение скорости по IP, ограничителю придётся реализовать отдельное ограничение для каждого сегмента, то есть принимать идентификатор сегмента (IP адрес). Здесь же реализованы более простые ограничители, где идентификатор не требуется. Пока каких-либо вариантов использования агрегированных ограничителей в dotnet/runtime не нашли, поэтому их решили не добавлять в текущую реализацию.

Если вам нужен агрегированный ограничитель, можете рассмотреть, например, пакеты, разработанные специально для ASP.NET Core, такие как AspNetCoreRateLimit.

Источник: https://www.infoq.com/news/2021/08/DotNet-Rate-Limiting/
День девятьсот двадцать восьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
95. Вы должны заботиться о коде
Не нужно способностей Шерлока Холмса, чтобы понять, что хорошие программисты пишут хороший код, а плохие программисты… нет. Они производят чудовищ, которых всем остальным приходится истреблять. Вы ведь хотите писать хороший код? Вы хотите быть хорошим программистом.

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

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

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

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

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

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

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

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

4. Каждый раз, когда вы касаетесь фрагмента кода, стремитесь оставить его лучше, чем вы его нашли (лучше структурированным, лучше протестированным, более понятным…).

5. Заботиться о коде и программировании, поэтому постоянно изучать новые языки, идиомы и методы. Но применять их только тогда, когда это необходимо.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Pete Goodliffe
День девятьсот двадцать девятый. #Оффтоп
Удивительная История Алгоритма Нахождения Обратного Квадратного Корня из 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/