.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
День пятьсот двадцать шестой. #DotNetAZ
Dotnet A-Z. 2
В этой серии постов рассмотрим наиболее распространённые понятия в .NET в алфавитном порядке.

CLR (Common Language Runtime) - Общеязыковая Среда Исполнения
Обычно относится к среде исполнения .NET Framework. Основной функцией CLR является преобразование управляемого кода в машинный код и последующее выполнение программы. Также CLR является виртуальной машиной, которая не только выполняет приложения, но также генерирует и компилирует код на лету с использованием JIT-компилятора. Подробнее…

CoreCLR
Общеязыковая Среда Исполнения .NET Core. Построена на той же кодовой базе, что и в .Net Framework. Изначально CoreCLR была средой исполнения Silverlight и предназначалась для работы на нескольких платформах, в частности в Windows и OS X. Теперь CoreCLR является частью .NET Core и представляет собой упрощённую версию CLR. Это кросс-платформенная среда исполнения, теперь включающая поддержку многих дистрибутивов Linux.

CoreFx - Библиотека базовых классов .NET Core (*Fx обозначает фреймворк)
Набор библиотек, которые включают пространства имён System и подмножество типов пространства имён Microsoft. BCL - это низкоуровневая инфраструктура общего назначения, на которой основаны прикладные инфраструктуры более высокого уровня, такие как ASP.NET Core. Исходный код .NET Core BCL содержится в репозитории среды исполнения .NET Core. Тем не менее, большинство .NET Core API также доступны в .NET Framework, поэтому вы можете рассматривать CoreFX как ответвление .NET Framework BCL.

CoreRT - Среда Исполнения .NET Core
В отличие от CLR/CoreCLR, CoreRT не является виртуальной машиной, что означает, что она не включает в себя средства для генерации и запуска кода, потому что не содержит JIT. Однако она включает в себя GC и возможности идентификации типа во время выполнения (RTTI) и рефлексии. Система типов CoreRT разработана таким образом, что метаданные для рефлексии не требуются. Отсутствие необходимости в метаданных позволяет иметь цепочку инструментов AOT, которая может отсекать лишние метаданные и (что более важно) идентифицировать код, который приложение не использует. CoreRT пока находится в разработке.

cross-platform - кросс-платформенность
Возможность разработки и запуска приложения в нескольких различных операционных системах, таких как Linux, Windows и iOS, без необходимости переписывать его специально под каждую из них. Это позволяет повторно использовать код и обеспечивать согласованность между приложениями на разных платформах.

Источник: https://docs.microsoft.com/en-us/dotnet/standard/glossary
День пятьсот двадцать седьмой. #ЧтоНовенького
Возможности для создания кроссплатформенных приложений на C# расширяются. Сегодня рассмотрим некоторые технологии для создания UI под разные платформы.

MAUI
MAUI - это эволюция Xamarin.Forms (XF). Это технология для создания нативных мобильных и настольных приложений на C# и XAML. Технология пока в разработке, но по плану MAUI должен заменить Xamarin.Forms. MAUI будет работать в среде исполнения .NET 5/6, а Xamarin.Forms - в Mono для телефонов.
Платформы: iOS, Android, Tizen, UWP (WinUI)
Когда использовать:
- У вас есть приложение Xamarin.Forms
- Для разработки нативного для платформы UI

Uno Platform
Uno - технология для создания нативных мобильных, настольных и WebAssembly (WASM) приложений с использованием C# и XAML. Это адаптер для UWP, который переносит приложения Windows 10 (WinUI/UWP) на телефоны, macOS и браузеры. Uno Platform имеет много общего с MAUI, но поддерживается в браузерах. Второе отличие от MAUI в том, что приложения MAUI по умолчанию выглядят как нативные для платформы, тогда как Uno по умолчанию делает приложение одинаковым для всех платформ.
Платформы: браузеры, iOS, Android, macOS, UWP (WinUI), поддержка Linux в планах
Когда использовать:
- У вас есть приложение UWP или вы хотите использовать WinUI
- Необходима поддержка в браузерах
- Ваша команда знакома с парадигмой XAML от WPF, Silverlight или UWP

Avalonia UI
Avalonia позволяет разработчикам создавать нативные приложения для Windows, macOS и Linux. Она использует уникальный подход рендеринга графики, чтобы полагаться на встроенные элементы управления платформы. Платформа также имеет экспериментальную поддержку телефонов. Поддержка WASM также в планах.
Платформы: Windows, macOS, Linux, экспериментальная iOS и Android, браузеры и полная поддержка iOS в планах
Когда использовать:
- У вас есть приложение WPF
- Для рендеринга на разных платформах
- Для кроссплатформенных настольных приложений (особенно Linux)

Blazor
Blazor - это браузерная технология, использующая WASM или SignalR для переноса кода .NET в браузер. Разработчики определяют UI с помощью HTML, стили с помощью CSS, но манипулируют HTML DOM с помощью C# вместо JavaScript. Подробнее...
Платформы: Браузеры
Когда использовать:
- Для веб-приложений
- Если не нужно создавать мобильное или настольное приложение
- Ваша команда лучше знакома с HTML и CSS, чем с XAML
- Необходимо перенести приложение ASP MVC в SPA.

Мобильные Привязки Blazor (Xamarin.Forms)
Это технология привязки синтаксиса Blazor Razor к Xamarin.Forms. Технология использует синтаксис Razor, что позволяет разработчикам объединять определения UI компонентов с кодом C#. Этот синтаксис будет знаком веб-разработчикам. Однако привязки не используют HTML. Синтаксис определяет компоненты для объектной модели UI Xamarin.Forms UI.
Платформы: iOS, Android
Когда использовать:
- У вас есть веб-приложение Blazor
- Вам нужно создать нативное приложение для телефона
- Ваша команда привыкла к синтаксису Razor
- Вы не против написать раздельный код для веб и для телефонов.

Источник: https://christianfindlay.com/2020/06/24/csharp-crossplatform-2/
👍1
День пятьсот двадцать восьмой. #Оффтоп #ЗадачиНаСобеседовании
В чате просили ещё задачек. Вот вам на выходные)))

Дан массив целых положительных чисел, представляющих цену акции в разные дни (каждый элемент массива представляет день). Также дано целое число k, которое представляет количество сделок, которые вам разрешено совершить. Одна сделка состоит из покупки акции в определённый день и продажи в более поздний день (ВНИМАНИЕ: 1 сделка = 2 транзакции: покупка и продажа).
Найдите максимальную прибыль, которую вы можете получить, покупая и продавая акции, используя максимум k сделок.
Обратите внимание, что в определённый момент вы можете держать только одну акцию. То есть вы не можете купить более одной акции, и не можете купить акцию, если она у вас уже есть. Кроме того, не обязательно использовать все k сделок. Также допустим, что бюджет на покупку не ограничен.

Например,
prices = [5, 11, 3, 50, 60, 90]
k = 2
Результат: 93
//Покупка: 5, продажа: 11 (+6); покупка: 3, продажа: 90 (+87)

prices = [12, 14, 17, 10, 14, 13, 12, 15]
k = 3
Результат: 12

prices = [100, 30, 15, 10, 8, 25, 80]
k = 3
Результат: 72
//Только одна сделка

Усложнённый вариант: Написать решение со сложностью O(n*k) по времени и O(n) по памяти.

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

Источник: https://www.algoexpert.io/
День пятьсот двадцать девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
50. Учитесь Оценивать

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

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

Часто можно услышать такой диалог между менеджером проекта и программистом:
М: Сколько времени понадобится, чтобы сделать функцию xyz?
П: Примерно месяц.
М: Это слишком долго! Надо сделать за неделю.
П: Мне нужно как минимум три.
М: Я могу выделить на это максимум две.
П: Договорились.


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

1. Оценка - это приблизительный расчёт или прогноз стоимости, количества или размера чего-либо. Это определение подразумевает, что оценка является мерой, основанной на достоверных данных и предыдущем опыте. Надежды и пожелания должны игнорироваться при расчёте. Из определения также следует, что оценка не может быть точной. Разработчик не может оценить время выполнения задачи в 234,14 дня.

2. Цель - это выражение желаемого на языке бизнеса. Например: «Система должна поддерживать не менее 400 одновременно работающих пользователей».

3. Обязательство - это обещание предоставить определённую функциональность определённого качества к определённой дате или событию. Например: «Функция поиска будет доступна в следующей версии продукта».

Оценки, цели и обязательства не зависят друг от друга, но цели и обязательства должны основываться на надёжных оценках. Как отмечает Стив Макконнелл: «Основная цель оценки в разработке ПО - не предсказать дату готовности проекта, а определить, являются ли цели проекта достаточно реалистичными, чтобы проект мог их достигнуть». Таким образом, смысл оценки состоит в том, чтобы сделать возможным адекватное управление проектом и планирование, позволяя вовлечённым сторонам проекта принимать обязательства, основанные на реалистичных целях.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Giovanni Asproni
День пятьсот тридцатый. #Оффтоп #ЗадачиНаСобеседовании
Ответ на задачу

Сначала попробуем решить задачу вручную. Создадим таблицу profits. В столбцах будут дни (day), как в исходном массиве, в строках – сделки (t) от 0 до k. Значениями массива будет максимальная возможная прибыль, полученная от каждой сделки в определённый день. Например:
Цены: 5 11  3 50 60 90
Если доступно 0 сделок, то и прибыль будет 0:
t=0 : 0  0  0  0  0  0
Если доступна 1 сделка, ищем максимальную прибыль от единственной сделки (прибыль в 1й день всегда 0):
t=1 : 0  6  6 47 57 87
Продажа во второй день даёт прибыль 6. Продажа в 3й день не даёт прибыли, поэтому максимум остаётся 6. Покупка в 3й день и продажа в 4й даёт прибыль 47 (больше 6, и больше покупки в 1й день по 5, поэтому максимум 47). Аналогично в 5й и 6й день максимальная прибыль будет 57 и 87 соответственно.
Теперь рассмотрим для 2х сделок. Первые 3 дня изменений не принесут. 1 сделка, прибыль 6:
t=2 : 0  6  6
В 4й день мы можем закрыть вторую сделку, получить прибыль 47 и сложить её с прибылью от первой сделки:
t=2 : 0  6  6 53
В 5й день нам нужно определить, принесёт ли продажа больше прибыли, чем уже есть. Прибыль от второй сделки принесёт 57, общая прибыль будет 63:
t=2 : 0  6  6 53 63
Продажа в 6й день даст нам прибыль в 87 (итого 93), что больше, чем текущий максимум 63:
t=2 : 0  6  6 53 63 93
Таким образом, можно заметить закономерность. Прибыль в определённый день для текущей сделки (profit[t,day]) будет рассчитываться как максимум между:
1) Прибылью за предыдущий день (profit[t,day-1]), если мы не продаём.
2) Если мы продаём, то нужно сложить цену за текущий день (prices[day]) с максимально выгодной покупкой в предыдущие дни. То есть за каждый предыдущий день x нам нужно найти разницу между прибылью от предыдущей(-их) сделки(-ок) в этот день (profit[t-1,x]) и покупкой в этот день (prices[x]). Максимум этой разницы за предыдущие дни и будет наиболее выгодной покупкой. Для второй сделки выгода по дням будет:
x=1: 0–5=-5 (прибыль 0 минус покупка за 5).
x=2: 6-11=-5 (прибыль от 1й сделки 6 минус покупка за 11).
x=3: 6-3=3 (прибыль от 1й сделки 6 минус покупка за 3).
x=4: 47-50=-3 (максимальная прибыль от 1й сделки 47 минус покупка за 50).
x=5: 57-60=-3 (максимальная прибыль от 1й сделки 57 минус покупка за 60).
Таким образом, для 2й сделки в 6й день выгоднее всего купить в 3й день. Получим: цена в 6й день 90 + максимальная выгода от предыдущей сделки 3 = 93, что больше, чем прибыль за предыдущий день 63.

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

Сложность по времени: обход n дней k раз - O(n*k) и расчёт максимальной выгоды в каждом случае O(n) – итого O(n^2*k).
Сложность по объёму: двумерный массив – O(n*k).

Оптимизации:
1) Мы можем рассчитывать максимальную выгоду по дням по мере заполнения таблицы прибылей, чтобы исключить дополнительный вложенный цикл. Таким образом, сложность по времени будет O(n*k).
2) Если внимательно посмотреть на алгоритм, нам не нужно хранить все k+1 рядов прибыли. Для расчёта каждого следующего ряда нам нужны данные только предыдущего. Тогда, таблицу можно сократить до двух рядов, соответственно сложность по объёму памяти будет O(n).

Полный код на C#

Более подробное объяснение решения на английском

Источник:
https://www.algoexpert.io/
День пятьсот тридцать первый. #юмор
День пятьсот тридцать второй. #ЧтоНовенького
Стивен Тауб (Stephen Toub) из Майкрософт выкатил целую «Войну и Мир» на тему производительности выходящего в ноябре .NET 5. И, судя по его подробному анализу, новая версия должна порадовать нас в этом смысле. Стивен сравнил .NET Framework 4.8, .NET Core 3.1 и .NET 5 (превью 8).
В общем, тесты он описал довольно подробно, всё можно перепроверить на своей машине. По его тестам выходит, что .NET 5 будет работать гораздо быстрее:
- сортировка чисел почти в 2 раза быстрее, чем Core 3.1,
- сортировка строк - на 15%,
- ToString – в 2 раза,
- ToUpperInvariant – в 2,5 раза
- в RegularExpressions получились совсем какие-то космические улучшения, почти на порядок.
И т.п.

В общем, почитайте, довольно интересно https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/

Ждём ноября.
День пятьсот тридцать третий.
Сертификат Microsoft. Экзамен 70-486. Шаг третий
Сегодня немного необычный пост. Я продолжаю подготовку к экзамену 70-486 Developing ASP.NET MVC Web Applications.
Microsoft предлагают список оцениваемых навыков. Его довольно сложно читать, т.к. всё в кучу с вычёркиваниями, добавлениями, исправлениями… Поэтому я решил отформатировать его и начал подбирать источники для подготовки.

Весь список я выложил на GitHub в виде readme документа: https://github.com/sbzenenko/ASP.NET-MVC-Exam-70-486

Я постепенно буду его дополнять источниками. Тут акцент будет не на книги, которые стоит почитать в общем, а на то, где найти информацию по конкретной узкой теме: глава или страницы книги, ссылка на статью, туториал, видео и т.п. Проблема в том, что рекомендуемое Microsoft руководство для подготовки («Exam Ref 70-486 Developing ASP.NET MVC 4 Web») датируется 2013м годом, т.е. содержит крайне устаревшую информацию.

Поэтому у меня большая просьба к сообществу. Если кто-то знает, где найти информацию по предложенным темам (особенно интересует всё, что касается Azure), пожалуйста, советуйте:
- в личке или в чате (в этом случае лучше указывайте пункт, например, 5.1.4.
- в issues на github (я могу добавить в контрибьюторы, если вам будет удобнее сам документ редактировать).

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

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

Заранее всем спасибо.
.NET Разработчик pinned «День пятьсот тридцать третий. Сертификат Microsoft. Экзамен 70-486. Шаг третий Сегодня немного необычный пост. Я продолжаю подготовку к экзамену 70-486 Developing ASP.NET MVC Web Applications. Microsoft предлагают список оцениваемых навыков. Его довольно сложно…»
День пятьсот тридцать четвёртый. #DevOps
Как Убить Производительность Разработчиков. Начало
Немного нестандартная серия постов не совсем про кодинг, а про DevOps. Генеральный директор Humanitec Каспар фон Грюнберг делится некоторыми мыслями о производительности труда разработчиков и о том, как её улучшить.

Убийца №1: Бросить всё ради микросервисов без надлежащего инструментария
Когда команды работают с монолитными приложениями, всё работает хорошо. Цепочка инструментов хорошо подготовлена и справляется с задачей. Но малейшее изменение требует пересборки всего приложения. Необходимо провести сквозные тесты, чтобы убедиться, что всё в порядке. Чем больше монолитное приложение, тем менее эффективным это будет. Команда принимает решение использовать микросервисы. Первый опыт великолепен, коллеги могут работать над отдельными сервисами независимо, частота развёртывания возрастает, и все довольны.

Проблемы начинаются, когда команды увлекаются микросервисами и воспринимают «микро» слишком серьезно. С точки зрения инструментария вам теперь придется иметь дело с гораздо бОльшим количеством yml-файлов, docker-файлов, с зависимостями между переменными этих сервисов, проблемами маршрутизации и т.д. Микросервисы должны поддерживаться, обновляться и обслуживаться. Ваши настройки CI/CD, а также ваша организационная структура и, возможно, численность персонала нуждаются в обновлении.

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

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

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

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

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

Источник:
https://dzone.com/articles/how-to-kill-your-developer-productivity-humanitec
День пятьсот тридцать пятый. #DevOps
Как Убить Производительность Разработчиков. Продолжение
Убийца №3: Неправильное Использование Kubernetes
Все крутые ребята расхваливают Kubernetes. Тем не менее, его трудно поддерживать и трудно интегрировать в ваш поток разработки, сохраняя при этом высокую производительность. Многое может пойти не так.

Худший случай использования Kubernetes: Коллега X очень хотел его попробовать и нашёл руководство для начинающих онлайн. Они создали кластер с нуля, и он отлично работал с тестовым приложением. Затем они начали миграцию первого приложения и попросили своих коллег начать взаимодействие с кластером с помощью kubectl. Половина команды теперь была занята изучением этой новой технологии. Человек, который обслуживает кластер, теперь будет занят этим постоянно, как только кластер получит первую рабочую нагрузку. Конфигурация CI/CD совершенно не подготовлена ​​для решения этой проблемы, и общая производительность снижается, поскольку вся команда пытается сбалансировать Kubernetes.

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

Лучшие практики:
1. Там, где это возможно, команды не должны сами устанавливать и запускать barebone кластер, а должны использовать управляемую службу Kubernetes. Прочитайте отзывы о том, какой управляемый кластер Kubernetes лучше всего соответствует вашим потребностям. На данный момент Google Kubernetes Engine (GKE) является лучшим с чисто технической точки зрения. За ним следуют службы Azure Kubernetes (AKS) и Amazon Elastic Kubernetes Service.
2. Используйте платформы автоматизации или API непрерывной доставки. Они позволяют запускать вашу рабочую нагрузку на K8 вне поля зрения разработчиков. Практически не имеет смысла посвящать всех в сложности процесса конфигурации.
3. Если команда действительно хочет, чтобы разработчики сами управляли кластером Kubernetes, нужно дать им достаточно времени, чтобы по-настоящему понять архитектуру, шаблоны проектирования, kubectl и т.д. и действительно сосредоточиться на этом.

Убийца №4: Игнорирование постоянной доставки
Существует распространенное заблуждение, что работа выполнена хорошо, если настроена непрерывная интеграция. Но вам всё ещё не хватает непрерывной доставки! Многие из тех, кто использует термин «инструмент CI/CD» думают, что добились непрерывной доставки, если у них есть Jenkins, CircleCI и т.д. Но это не так.

Тщательная настройка Continuous Delivery, с использованием собственных сценариев или «как услуга», является гораздо более важным «связующим звеном»:
1. Она позволяет интегрировать все различные компоненты, от системы управления исходным кодом до CI-Pipeline, от базы данных до кластера и от настройки DNS до IaC, в удобную среду для разработчиков.
2. Это способ структурировать, поддерживать и управлять растущим количеством сценариев yml и конфигурации. Если всё сделано правильно, это позволит вашим разработчикам динамически разворачивать среды с помощью артефактов, созданных CI-Pipeline с полной настройкой и подготовкой базы данных.
3. Она может выступать в качестве системы контроля версий для состояний конфигурации с подтверждённой записью о том, что, где, в какой конфигурации развернуто, и позволяет выполнять откат назад и вперед, а также управлять развёртываниями.
4. Хорошо продуманные настройки CD оказывают кардинальное влияние на производительность труда разработчиков. Они делают разработчиков самодостаточными, уменьшают количество зависимостей в команде, повышая удобство обслуживания вашей конфигурации.
5. Команды, использующие эти методы, делают релизы чаще, быстрее, демонстрируют в целом более высокую производительность и удовлетворённость от работы.

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

Источник:
https://dzone.com/articles/how-to-kill-your-developer-productivity-humanitec
День пятьсот тридцать шестой. #DevOps
Как Убить Производительность Разработчиков. Окончание
Убийца №5: Неуправляемая автоматизация тестирования в ограниченной конфигурации тестов
Эффективное тестирование невозможно без автоматизации. С непрерывной доставкой приходит непрерывная ответственность, чтобы ничего не сломать.
Вы должны постоянно следить за тем, чтобы не попасть в ловушку инвертирования тестовой пирамиды. Для этого вам нужно иметь возможность запускать правильные тесты в нужной точке жизненного цикла разработки.

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

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

Убийца №6: Самостоятельное управление базами данных
Товарищ по команде, который только что ушел, отвечал за настройку MongoDB для клиентского проекта и, конечно, использовал проект с открытым исходным кодом, в котором размещалась база. И, естественно, передача дел была «безупречной», база данных не была должным образом защищена, и однажды вечером случилось то, что должно было: «Ваша база данных была сохранена и архивирована. У вас есть 7 дней, чтобы её восстановить. Пришлите 0.1 BTC …»
И конечно:
- Вы проверяете резервные копии.
- В коде резервного копирования обнаружилась ошибка.
- Теперь вам нужно восстанавливать все данные.

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

Убийца №7: Использование нескольких облаков без причины
Есть разница между переходом на несколько облаков и попыткой сделать ваши системы независимыми от облачных вычислений и переносимыми. Последнее имеет много различных преимуществ, таких как динамические среды, и имеет больше смысла, чем переход на несколько облаков. Конечно, есть наследие: одни команды использовали GCP, другой отдел начал с AWS, а третьим нужны специальные условия - и вуаля. Можно спорить, что одни сервисы работают лучше или дешевле, чем другие. Но чтобы эти эффекты действительно имели значение, вам нужен достаточный объём. Несложные многооблачные установки требуют высокой степени автоматизации и защиты разработчиков от задач их настройки и поддержки. В противном случае человек попадает в ад сценариев.
Как правило: не используйте несколько облаков, если в этом нет необходимости.

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

Источник: https://dzone.com/articles/how-to-kill-your-developer-productivity-humanitec
День пятьсот тридцать седьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
51. Не Забывайте про "Hello World!"
Пол Ли, более известный как Хоппи, имел в компании репутацию эксперта по вопросам программирования. Мне нужна была помощь, я подошёл к столу Хоппи и спросил, может ли он взглянуть на один кусок кода.

«Конечно», - сказал он, - «тащи стул». Я аккуратно, чтобы не опрокинуть пустые банки от колы, сложенные в пирамиду позади него, присел рядом.

- Что за код код?
- В функции XXX в файле YYY, - сказал я.
- Так, давай посмотрим на эту функцию, - Хоппи свернул свой код и пододвинул свою клавиатуру ко мне.
- А где IDE?

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

«Что тут произойдёт, если х отрицательный?» - спросил я. - «Здесь явно ошибка.»

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

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

И вот его программа, придуманная всего пару минут назад, уже работала. Мы попробовали несколько значений и подтвердили мои подозрения (ну хоть в чём-то я оказался прав!). Затем он перепроверил соответствующий код в проекте уже в IDE. Я поблагодарил Хоппи и ушёл, снова стараясь не разрушить его пирамиду из колы.

Вернувшись за свой рабочий стол, я закрыл свою IDE. Я настолько привык работать над большим проектом с помощью сложных инструментов, что стал думать, что только так и нужно делать. Но мощный компьютер может выполнять и простейшие задачи. Я открыл текстовый редактор и начал печатать:
using System;
class Program {
static void Main(string[] args) {
Console.WriteLine("Hello World!");
}
}

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Thomas Guest (в оригинале был код на C).
День пятьсот тридцать восьмой. #DotNetAZ
Dotnet A-Z. 3
В этой серии постов рассмотрим наиболее распространённые понятия в .NET в алфавитном порядке.

Ecosystem (Экосистема)
Всё ПО среды исполнения, средства разработки и ресурсы сообщества, которые используются для создания и запуска приложений для данной технологии. Термин «экосистема .NET» отличается от аналогичных терминов, таких как «стек .NET», т.к. включает сторонние приложения и библиотеки.

Framework (Фреймворк)
В общем случае - это комплексная коллекция API, которая облегчает разработку и развёртывание приложений, основанных на конкретной технологии. В этом смысле ASP.NET Core или Windows Forms являются примерами фреймворков приложений. Слово «фреймворк» имеет более конкретное значение в следующих терминах:
- .NET Framework - Реализация .NET, которая работает только в Windows.
- целевой фреймворк – Конкретная коллекция API, на которую опирается приложение или библиотека .NET.
- TFM (Моникер целевого фреймворка) – Стандартизированный токен имени фреймворка (например, net462 для .NET Framework версии 4.6.2).
В существующей документации Майкрософт термин «фреймворк» используется как для обозначения .NET Framework, так и иногда может относиться к другой реализации .NET. Например, .NET Core может называться фреймворком в некоторых статьях.

GC (Garbage collector – Сборщик мусора)
Сборщик мусора - это реализация автоматического управления памятью. GC освобождает память, занятую объектами, которые больше не используются.
Подробнее…

IL (Intermediate language - Промежуточный язык)
Языки высокого уровня, такие как C#, в .NET компилируются в аппаратно-независимый набор команд, который называется промежуточным языком (IL), иногда MSIL (Microsoft IL) или CIL (Common IL).
Подробнее…

JIT (Just-in-time компилятор)
Подобно AOT, этот компилятор переводит IL в машинный код, который понимает процессор. Но в отличие от AOT, JIT-компиляция происходит по требованию и выполняется на той же машине, на которой должен выполняться код. Поскольку JIT-компиляция происходит во время выполнения приложения, время компиляции является частью времени выполнения. Таким образом, JIT-компиляторы должны находить баланс между временем, потраченным на оптимизацию кода, и выигрышем, который эта оптимизация даёт. Преимуществом JIT-компилятора является то, что он знает конфигурацию оборудования, на котором выполняется код, поэтому может применять соответствующие процессорные оптимизации, что освобождает разработчиков от необходимости поставлять различные реализации кода для разных машин.
Подробнее…

Источник: https://docs.microsoft.com/en-us/dotnet/standard/glossary
#оффтоп Тут Хабр разжёг выкатил исследование зарплат в ИТ, что вызвало немало споров в различных сообществах. Вот и я решил поинтересоваться. Опрос ниже.
Получаете ли вы медианную зарплату по региону (ближайший город из картинки выше) и по специализации?
Anonymous Poll
24%
Да, и по региону, и по специализации вцелом
22%
Только больше медианной по региону
54%
Меньше медианной по региону
День пятьсот тридцать девятый. #ЧтоНовенького #CSharp9
C#9: Новые Ключевые слова and, or и not для Сопоставления по Шаблону
Хотя это может звучать как первоапрельская шутка, в C#9 хотят добавить and, or и not в список ключевых слов для использования в сопоставлении по шаблону.

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

В этом и проблема. Если вы работаете с логическими значениями, то операторы && и || будут неоднозначными. Компилятор не сможет определить, относятся они к значениям или к шаблонам. Чтобы проиллюстрировать эту идею, рассмотрим дизъюнктивный шаблон:
if (myBool is true or false)
Это будет интерпретировано как «истина, если myBool равно true или если myBool равно false».

Если бы мы использовали операторы && и || для объединения шаблонов, получился бы следующий код:
if (myBool is true || false)
Но это буквально означает «истина, если myBool равняется результату логического выражения (true или false)», что можно упростить до «истина, если myBool равняется true». А это совершенно не то, что мы хотели бы получить в дизъюнктивном шаблоне.

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

Источник: https://www.infoq.com/news/2020/07/CSharp-And-Or-Not/
День пятьсот сороковой. #MoreEffectiveCSharp
14. Различайте Интерфейсные и Абстрактные Методы
На первый взгляд реализация интерфейса выглядит так же, как и переопределение абстрактной функции. Но есть различия:
- Реализация абстрактного члена базового класса должна быть виртуальной; реализация члена интерфейса – не обязательно.
- Интерфейсы могут быть реализованы явно, что скроет их реализацию от открытого интерфейса класса.

Рассмотрим варианты реализации простого интерфейса в иерархии классов:
interface IMessage {
void Message();
}
public class MyClass : IMessage {
public void Message() => WriteLine(nameof(MyClass));
}
Метод Message() является частью публичного интерфейса MyClass, а также может быть вызван через приведение к IMessage. Теперь добавим производный класс:
public class MyDerivedClass : MyClass {
public new void Message() =>
WriteLine(nameof(MyDerivedClass));
}
Нам пришлось добавить ключевое слово new. MyClass.Message() не является виртуальным, его нельзя переопределить. Класс MyDerived создаёт новый метод Message, который не переопределяет MyClass.Message, а скрывает его. Однако MyClass.Message по-прежнему доступен через IMessage:
MyDerivedClass d = new MyDerivedClass();
d.Message(); // выведет "MyDerivedClass"
IMessage m = d as IMessage;
m.Message(); // выведет "MyClass"

Приведение к IMessage вызывает базовую реализацию. Если доступа к базовому классу нет, можно реализовать интерфейс и в производном классе:
public class MyDerivedClass : MyClass, IMessage {…}
Тогда поведение изменится:
m.Message(); // выведет "MyDerivedClass"
Ключевое слово new всё равно придётся использовать. Базовая реализация будет доступна через апкаст:
MyClass b = d;
b.Message(); // выведет "MyClass"

Если доступ к базовому классу есть, объявите интерфейсный метод виртуальным, а в производных классах используйте ключевое слово override. Тогда переопределённая версия метода будет вызываться всегда: и из производного класса, и после приведения как к базовому классу, так и к интерфейсу.

Также можно реализовать интерфейс без фактической реализации его методов:
public abstract class MyClass : IMessage {
public abstract void Message();
}
Тогда все конкретные производные типы должны переопределить и предоставить собственную реализацию Message(). Интерфейс IMessage является частью объявления MyClass, но реализация методов откладывается до каждого конкретного производного класса.

Можно реализовать паттерн Шаблонный метод:
public class MyClass : IMessage {
protected virtual void OnMessage() {}
public void Message() {
OnMessage();
WriteLine(nameof(MyClass));
}
}
Любой производный класс может переопределить OnMessage() и добавить свой код в реализацию контракта IMessage.

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

Источник: Bill Wagner “More Effective C#”. – 2nd ed. Глава 15.
День пятьсот сорок первый. #Оффтоп
Сегодня расскажу про классную серию видео на ютуб от Shawn Wildermuth. Серия называется Maintainers (Сопровождающие). Это видео о людях, которые сделали внушительный вклад в развитие открытого кода. В первом видео серии Jimmy Bogard описывает историю создания знаменитого AutoMapper. Как он создавался, почему было принято решение сделать его открытым, как появлялись первые контрибьюторы и почему довольно сложно сразу применять изменения сделанные контрибьюторами.

А поскольку это видео всего на 9 минут, вот вам ещё одно от Jimmy Bogard. Это его выступление на онлайн конференции NDC в апреле, где он рассказывает про «Архитектуру Вертикальных Слоёв» (Vertical Slice Architecture).

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

Почему бы не разделить приложение по слоям вариантов использования. Фактически вариантов использования веб-приложения всего два:
GET:
 Запрос (Query) – Обработчик (Handler) – Ответ (Response)
POST:
 Команда (Command) – Обработчик (Handler) – Ответ (Response)
Тогда можно использовать принцип CQRS и разделить приложение на соответствующие слои. Если совсем упрощённо, то в MVC, Модель – это Запрос/Команда, логика Контроллера помещается в Обработчик, а Ответ передаётся в Представление, либо в качестве ответа API.

В общем, гораздо более подробно это описано в видео. Энджой)))
День пятьсот сорок второй. #ЧтоНовенького #CSharp9
C#9: Операторы Диапазона в Конструкциях Switch и Сопоставлениях по Шаблону

С момента первого выхода C# разработчики жаловались на отсутствие операторов диапазона в конструкциях switch. Как часть улучшений сопоставлений по шаблону в C#9, это ограничение было устранено.
Следующие шаблоны будут разрешены после ключевых слов case или is:
- < константа
- > константа
- <= константа
- >= константа

Шаблоны всё ещё ограничены только константами. Это становится проблемой, когда вы имеете дело с датой, временем или другими аналогичными структурами, поскольку они не имеют константного представления в C#.

В обсуждении предложения на GitHub Нил Гафтер написал по этому поводу:
«Смысл этой функциональности был в расширении сопоставления по шаблону. В частности, ограничение только константами сделано, чтобы компилятор мог проанализировать и оптимизировать весь набор операций сопоставления по шаблону. Если компилятор не знает значения, с которым он сопоставляет, он не сможет этого сделать. В конце концов, чем плохи обычные выражения?»

Мариуш Павельски отвечает, почему ограничение может стать проблемой:
«Я просто думаю, что будет много людей, которые захотят использовать ключевые слова is, and и or просто как ещё один способ написания логических выражений. Ещё одна небольшая функция C#, которая делает код более лаконичным. Они не будут знать, что это часть большой функциональности сопоставления по шаблону, которая «была разработана для работы с константами». Они будут просто сбиты с толку, когда вместо константы будут использовать имя переменной и получат ошибку «CS0150: A constant value is expected» (Ожидается константное значение).»

Как бы то ни было, операторы and, or и not также могут быть использованы в сочетании с диапазонами. Например,
bool IsLetter(char c) =>
c is >= 'a' and <= 'z' or >= 'A' and <= 'Z';


Это немного трудно читать, поэтому в выражениях можно использовать круглые скобки:
bool IsLetter(char c) =>
c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');


Источник: https://www.infoq.com/news/2020/07/CSharp-9-Range-Patterns/