.NET Разработчик
6.53K subscribers
442 photos
3 videos
14 files
2.12K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День шестьсот семьдесят третий. #ЧтоНовенького
Microsoft Запускает Сервис Q&A для .NET

Microsoft Q&A для .NET - это сервис для технических вопросов и ответов о продуктах Microsoft. Здесь вы найдёте широкий спектр тем по .NET, включая рантайм, разработку настольных и веб приложений, вопросы по языкам, данным и многое другое.

Задавайте вопросы, следите за темами или выберите вопрос, на который вы знаете ответ. Ваш профиль Microsoft Q&A связан с вашей учетной записью в Microsoft Learn, и вы можете получать очки репутации, проявляя активность (см. картинку выше).

Существует множество форумов по темам .NET, включая MSDN, ASP.NET, IIS.NET и Xamarin. Со временем все они будут полностью перенесены на платформу Microsoft Q&A. На каждом из форумов будет вывешено отдельное уведомление о том, когда он будет перенесён.

Источник: https://devblogs.microsoft.com/dotnet/announcing-microsoft-q-and-a-for-dotnet/
День шестьсот семьдесят четвёртый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
68. Отложите Мышь и Отойдите от Клавиатуры
Вы уже несколько часов решаете какую-то серьезную проблему, а решения всё нет. Вы встаёте, чтобы размять ноги или сходить за чашечкой кофе, и на обратном пути ответ внезапно становится очевидным.

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

Вот пример из реальной жизни: я чистил один устаревший код и наткнулся на «интересный» метод. Он был разработан для проверки того, что строка содержит допустимое время, используя формат hh:mm:ss xx, где xx – AM или PM. В методе использовался следующий код для преобразования двух символов (представляющих час) в число и проверки его соответствия допустимому диапазону:
try {
int.Parse(time.Substring(0,2));
}
catch (Exception x) {
return false;
}
if (int.Parse(time.Substring(0,2)) > 12) {
return false;
}

Далее тот же самый код встречался ещё дважды с соответствующими сдвигами по строке, для проверки минут и секунд. А заканчивался метод следующим блоком для проверки AM и PM:
if (!time.Substring(9,2).Equals("AM") &
!time.Substring(9,2).Equals("PM")) {
return false;
}
Если ни одно из этих сравнений не завершилось неудачей и не вернуло false, метод возвращал true.

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

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

Когда я готовился к работе на следующий день, мне в голову пришла идея: почему бы не проверить строку с помощью регулярного выражения? Через пару минут у меня была рабочая реализация всего в одной строке кода:
public static bool ValidateTime(string time) {
return new Regex(
"(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)")
.IsMatch(time);
}
Суть этой истории не в том, что я в итоге заменил более 30 строк кода одной. Дело в том, что пока я не отошёл от компьютера, я думал, что моя первая попытка была лучшим решением проблемы.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Burk Hufnagel
День шестьсот семьдесят пятый. #ЗаметкиНаПолях
Давненько я вам не рекомендовал видео. Примерно неделю назад команда DotNext выложила в открытый доступ доклады с конференции в Питере, проходившей в июне этого года. Сегодня хочу вам предложить одно из выступлений. Джон Скит (автор знаменитой книги «C# in Depth») «Dates and times: Hard, but not impossible» (Дата и время: трудно, но не невозможно).

В основном он рассказывает о своём инструменте Noda Time, созданном для работы с датой и временем в .NET. Однако доклад будет полезен и тем, кто не собирается его использовать. Например, Джон рассказывает, почему в вашем коде не должно использоваться DateTime.Now.

Хорошие новости для англонеговорящих, на Хабре предоставлена расшифровка выступления на русском.
День шестьсот семьдесят шестой. #Оффтоп #КакСтатьСеньором
Сегодня начну серию постов, которую коротко можно озаглавить «Как Стать Сеньором». Я недавно наткнулся на лонгрид от разработчика, который описывает, что он узнал на пути к должности старшего разработчика. Выдержки из его статьи, по аналогии с #97Вещей, будут появляться на канале время от времени под тегом #КакСтатьСеньором. Но для начала давайте определимся…

Кто такой сеньор?
Начало.

Замечание: Сразу оговорюсь, что многое из нижеследующего описывает «сферического сеньора в вакууме». И, наверное, часть из этих характеристик невозможно дать самому себе, их должны дать вам ваши коллеги.

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

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

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

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

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

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

Источник: https://dev.to/themarcba/what-is-a-senior-developer-really-59dg
Автор оригинала – Burk Hufnagel
День шестьсот семьдесят седьмой. #Оффтоп #КакСтатьСеньором
Кто такой сеньор? Окончание.
Начало

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

От начала до конца
Старший разработчик способен выполнить каждый шаг на пути создания программного обеспечения:
1. Проанализировать проблему
2. Понять проблему
3. Сформировать жизнеспособное решение проблемы
4. Реализовать решение
5. Проверить решение
6. Интегрировать решение
7. Развернуть решение

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

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

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

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

Источник: https://dev.to/themarcba/what-is-a-senior-developer-really-59dg
Автор оригинала – Burk Hufnagel
День шестьсот семьдесят восьмой. #юмор
День шестьсот семьдесят девятый. #ЧтоНовенького
Повышаем Продуктивность в Visual Studio 2019 v16.9 Preview 2
Под новый год разработчики Visual Studio подкинули нам действительно важных новинок. Как мы раньше без всего этого жили? Вы только оцените:
1. Автодобавление пространств имён
При копировании и вставке типов в новый файл Visual Studio 2019 теперь будет автоматически добавлять в файл недостающие директивы using. Чтобы попробовать эту опцию, включите её в меню Tools > Options > Text Editor > C# > Advanced (Инструменты > Параметры > Текстовый Редактор > C# > Дополнительно). Затем выберите Add missing using directives on paste (Добавлять недостающие директивы using при вставке).

2. Автодобавление точки с запятой
IntelliSense теперь при автозаполнении нового объекта или вызова метода будет добавлять точку с запятой в конце.

3. Новая цветовая схема для записей
В меню Tools > Options > Environment > Fonts and Colors (Инструменты > Параметры > Среда > Шрифты и Цвета) можно найти раздел User Types – Records (Пользовательские Типы – Записи) и выбрать для них особую цветовую схему.

4. Избавление от символа discard
В C#9 символ _ (discard) в некоторых случаях сопоставления с образцом не требуется. Теперь появится специальная подсказка в меню Quick Actions and Refactorings (Быстрые Действия и Рефакторинг), советующая его удалить.

Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-2019-v16-9-preview-2/
День шестьсот восьмидесятый. #ЧтоНовенького #CSharp9
Ещё Раз про Сопоставления с Образцом
Я уже писал об изменениях в сопоставлении с образцом в C#9. Здесь же хочу привести некое саммари всех изменений с примерами:

1. Шаблоны типа используются для сопоставления с типом. Если тип входных данных соответствует типу, указанному в шаблоне, совпадение считается успешным.
object checkType = new int();
var getType = checkType switch {
string => "string",
int => "int",
_ => "obj"
};
Console.WriteLine(getType);
// Вывод: int

2. Реляционные шаблоны позволяют сопоставить входные данные с константами, используя знаки >, < или = (a также >= или <=):
var person = new Person("John", 42);
var person2 = new Person("Jane", 8);
var ageInRange = person switch {
//тип Person указан явно
Person(_, < 18) => "меньше 18",
//тип выводится компилятором
(_, > 18) => "больше 18",
(_, 18) => "18!"
};
Console.WriteLine(ageInRange);
// Вывод: больше 18

3. Комбинаторные шаблоны позволяют комбинировать несколько шаблонов в одной строке:
var person = new Person("John", 42);

- Конъюнктивные представляют собой логическое «и» двух подшаблонов:
var ageInRange = person switch {
(_, < 18) => "меньше 18",
("John", _) and (_, > 18) => "Джону больше 18"
};
Console.WriteLine(ageInRange);
// Вывод: Джону больше 18

- Дизъюнктивные представляют собой логическое «или» двух подшаблонов:
var ageInRange = person switch {
(_, < 18) => "меньше 18",
(_, 18) or (_, > 18) => "18 или больше"
};
Console.WriteLine(ageInRange);
// Вывод: 18 или больше

- Отрицательные требуют несовпадения с заданным шаблоном:
var isJohn = person switch {
not ("John", 42) => "не Джон!",
_ => "Джон :)"
};
Console.WriteLine(isJohn);
// Вывод: Джон :)

4. В шаблонах допустимо использовать скобки:
public record IsNumber(bool IsValid, int Number);
var num = new IsNumber(true, 10);
var zeroToTen = num switch {
((_, >= 0 and <= 5) or (_, > 5 and <= 9))
or (_, 10) => "от 0 до 10",
_ => "больше 10"
};
Console.WriteLine(zeroToTen);
// Вывод: от 0 до 10

Источник: https://www.c-sharpcorner.com/article/c-sharp-9-cheatsheet/
День шестьсот восемьдесят первый. #ЧтоНовенького
Критические Изменения в .NET5. Библиотека Базовых Классов (BCL)
В .NET5 внесено несколько критических изменений. Подавляющее большинство из них связано с редкими случаями использования или некорректным поведением в прошлом. Но некоторые могут застать разработчиков врасплох. В первой части этой серии, рассмотрим изменения в BCL.

1. Информация о версии .NET
Некоторые разработчики используют строковое представление версии, а не числовую форму. В случае .NET у разработчиков не было выбора. Отчасти из-за путаницы в нумерации приходилось полагаться на строковое представление, вроде «.NET Framework #.#» или «.NET Core #.#».
В .NET5 моникер представляет из себя просто «.NET #.#». Приложения и библиотеки, зависящие от определения версии среды выполнения, необходимо обновить.

2. Информация о версии ОС
Раньше Environment.OSVersion могла лгать. Вместо возврата фактической версии ОС могла возвращаться эмулируемая ОС на основе настроек режима совместимости Windows. Теперь будет возвращаться фактическая версия, что больше соответствует ожиданиям разработчиков.

3. Расположение файлов в однофайловых приложениях
Когда приложение собрано в один файл вместе с его зависимостями, поведение некоторых API рефлексии перестаёт быть очевидным. В .NET5 все зависимости загружаются прямо из памяти, то есть физического файла сборки не существует. Ниже представлены новые варианты поведения для связанных сборок:
Assembly.Location - возвращает пустую строку,
Assembly.CodeBase - выбрасывает исключение,
Assembly.GetFile(String) - выбрасывает исключение,
Environment.GetCommandLineArgs()[0] - возвращает имя исполняемого файла,
AppContext.BaseDirectory - возвращает каталог, в котором находится исполняемый файл.

4. Логи
Следующие параметры ConsoleLoggerOptions отмечены как устаревшие: DisableColors, IncludeScopes, TimestampFormat, UseUtcTimestamp, Format. Они заменяются одним из нескольких подклассов ConsoleFormatterOptions.

5. Сериализация через BinaryFormatter заблокирована
BinaryFormatter в .NET существует с самого начала. Предполагалось, что он будет быстрее и компактнее, чем SoapFormatter, основанный на XML. К сожалению, в нём есть ряд проблем, самая важная из которых - невозможность безопасного использования. В .NET 5 BinaryFormatter по умолчанию отключен в приложениях ASP.NET и выдает предупреждение компилятора в других платформах. Если вам нужно его использовать, можно включить его с помощью флага EnableUnsafeBinaryFormatterSerialization.

6. UTF-7 заблокирована
Этот формат уже запрещён многими стандартами, такими как HTML5, потому что легко вставить вредоносные строки в приложение, заставив часть приложения думать, что данные находятся в формате UTF-8, в то время как другие части будут обрабатывать данные как UTF-7. Если необходима обработка устаревших данных, UTF-7 можно включить с помощью флага EnableUnsafeUTF7Encoding.

7. Пакет Microsoft.DotNet.PlatformAbstractions устарел
Разработчикам настоятельно рекомендуется прекратить использование пакета Microsoft.DotNet.PlatformAbstractions для получения информации об операционной системе. Ниже показаны устаревшие методы и их альтернативы:
ApplicationEnvironment.ApplicationBasePath
=> AppContext.BaseDirectory
HashCodeCombiner

=> System.HashCode
RuntimeEnvironment.GetRuntimeIdentifier
=> RuntimeInformation.RuntimeIdentifier
RuntimeEnvironment.OperatingSystemPlatform
=> RuntimeInformation.IsOSPlatform(OSPlatform)
RuntimeEnvironment.RuntimeArchitecture
=> RuntimeInformation.ProcessArchitecture
RuntimeEnvironment.OperatingSystem
=> RuntimeInformation.OSDescription
RuntimeEnvironment.OperatingSystemVersion

=> RuntimeInformation.OSDescription
и Environment.OSVersion

Источник: https://www.infoq.com/news/2020/12/net-5-breaking-changes/
День шестьсот восемьдесят второй. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
69. Читайте код
Мы, программисты, - странные создания. Мы любим писать код. Но когда дело доходит до чтения кода, мы обычно стесняемся и уклоняемся от этого. В конце концов, писать код намного веселее, а читать код сложно, а иногда почти невозможно. Особенно сложно читать чужой код. Не обязательно потому, что этот код плохой, а потому, что они, вероятно, думают и решают проблемы иначе, чем вы. Но задумывались ли вы когда-нибудь о том, что чтение чужого кода может улучшить ваш собственный код?

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

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

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

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Karianne Berg
День шестьсот восемьдесят третий. #ЧтоНовенького
Критические Изменения в .NET5. Исторические Технологии
Начало. BCL
Во второй части нашего обзора .NET 5 рассмотрим исторические технологии .NET, которые не были перенесены в .NET Core.

Глобальный кэш сборок
Теория, лежащая в основе глобального кэша сборок (GAC), заключалась в том, чтобы все библиотеки .NET могли храниться в одном централизованном месте с возможностью хранить несколько версий каждой библиотеки, что позволило избавиться от «ада DLL». Но проблемы с версиями остались. К моменту выпуска .NET 4.5 лишь несколько приложений использовали GAC для библиотек сторонних разработчиков. Поэтому неудивительно, что в .NET Core все зависимости развёртываются вместе с приложением, что позволяет изолировать приложение от других. Тем не менее частично API GAC по-прежнему существуют в .NET Core. Они мало полезны, например, свойство, указывающее, содержится ли сборка в GAC, всегда возвращает false. Теперь все API GAC помечены как устаревшие.

Удалённое взаимодействие
Основная идея .NET Remoting в том, что одно приложение могло использовать прокси-объект для управления реальным объектом, запущенным внутри другого приложения. Хотя технически это работало, .NET Remoting никогда не пользовался популярностью из-за трудностей с его правильным использованием и нестабильности. В .NET Core API .NET Remoting не были реализованы. Как и API GAC, они имели только неработающие заполнители. Они также помечены устаревшими и будут в итоге удалены.

Защита доступа к коду
Code Access Security - ещё одна технология .NET Framework, API которой помечены как устаревшие. CAS была создана в эпоху до изолированных контейнеров, таких как Docker. В .NET Framework несколько приложений размещались в одном экземпляре IIS. Теоретически каждое из них изолировано в отдельном домене приложения, но вырваться из него и помешать работе других приложений, работающих в IIS, несложно.

CAS использовался, чтобы ограничить размер возможного ущерба. Основная идея заключалась в том, что опасные API-интерфейсы помечались атрибутами, указывающими на риск. Такие хосты, как IIS, можно настроить для запуска приложений с различными уровнями «доверия», теоретически помещая их в песочницу.

Также CAS использовался для браузерных приложений. Задолго до Silverlight можно было запускать приложения Windows Forms в Internet Explorer. Уровень доверия к приложению частично определялся тем, откуда оно было загружено, при этом сайты интрасети предоставляли более высокие привилегии. Но, как и многие ранние технологии .NET, правильно реализовать CAS было сложно. У вредоносных приложений было множество способов обойти ограничения CAS, в то время как безобидные приложения часто сталкивались с трудностями. Браузерные приложения оказывались заблокированы, а уровни доверия CAS для IIS зачастую игнорировались.

Thread.Abort
Может показаться неожиданным, что Thread.Abort никогда не был реализован в .NET Core. Несмотря на то, что это считалось опасным, но оно было и неизбежным. Простой тайм-аут запроса или отключение клиента в ASP.NET приводило к вызову Thread.Abort. И если код не был тщательно написан для обработки этого события, это могло привести к утечкам ресурсов, таким как блокировки или открытые транзакции базы данных.

К моменту создания ASP.NET Core CancellationToken стал безопасной и широко распространенной альтернативой Thread.Abort, поэтому не было необходимости реализовывать его в первой версии .NET Core. И хотя .NET Core расширился за пределы веба, ни одна из других основных платформ приложений не нуждалась в Thread.Abort, поэтому этот вызов генерировал исключение PlatformNotSupportedException. В .NET 5 этот метод помечен как устаревший.

Источник: https://www.infoq.com/news/2020/12/net-5-breaking-changes-2/
День шестьсот восемьдесят четвёртый. #Оффтоп #КакСтатьСеньором
Что Я Узнал, Чтобы Стать Сеньором
Работник Bloomberg, пришедший туда джуниор-разработчиком, описывает свой опыт роста в компании.

1. Разносторонний Рост
Ко второму году работы я уже знал все основы. Я собрал все низко висящие плоды, и мой рост замедлился. Возник большой вопрос: «Как расти дальше?» Я мало что мог сделать, чтобы улучшить свои навыки программирования. Большинство статей и блогов про методы написания более чистого кода, KISS, DRY, YAGNI и т.д. - являются микрооптимизациями. Почти ничего из этого не приносит большой пользы для роста (хотя это не значит, что их не стоит изучать совсем).

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

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

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

2) Тренировка правильных мыслительных привычек
Разработка ПО требует правильного мышления и принятия правильных решений. Написание кода — это реализация этих решений. Мыслительная привычка — это то, что ваш мозг делает регулярно. Это может быть размышление о X всякий раз, когда случается Y, или применение инструмента X к проблеме Y. Короче говоря, мыслительные привычки помогают размышлению. Я предположил, что, если изучить общие принципы, их можно будет применить и в разработке ПО.

3) Правильное мышление
Разработка ПО - отличная область для практики правильного мышления. Циклы обратной связи короче, и оценка правильности решения не занимает много времени. Я погрузился в изучение когнитивных наук. Это полезный навык, который стоит изучить. Он поможет и тому, чем я занимаюсь по работе, и принесёт дивиденды в жизни вообще. Подробнее об этом позже.

Источник: https://medium.com/better-programming/the-things-i-learned-to-become-a-senior-software-engineer-1083686d70cd#d46c
Автор оригинала – Neil Kakkar
День шестьсот восемьдесят пятый. #Оффтоп
Перенесём разговоры по воскресеньям на разговоры по вторникам))) Судя по всему, на неделе обсуждения получаются активнее. Действительно, что ещё делать в течение дня, работать что ли?

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

В двух словах, в компании есть «On Call»-инженеры (инженеры на вызове), которым могут позвонить в середине ночи в случае, если случается что-то серьёзное. Насколько я понял, эта роль передаётся по очереди всем разработчикам. Давайте обсудим. Есть ли такое в вашей компании? Случалось ли это с вами, что было (если не секрет), и что было за это вам?)))
День шестьсот восемьдесят шестой. #Оффтоп
The API Book
Случайно наткнулся на довольно занятную книгу. Ну как книгу, она пока в стадии написания, но значительная часть её уже готова. "The API Book" за авторством Сергея Константинова. Найти её можно на гитхабе автора как в английском, так и в русском варианте.

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

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

Подробности в книге по ссылке выше.
День шестьсот восемьдесят седьмой. #ЧтоНовенького
Критические Изменения в .NET5.
ASP.NET. Начало 1/3
В третьей части нашего обзора .NET 5 рассмотрим ASP.NET.
- BCL
- Исторические технологии

1. Сериализация
Числа, которые отображаются как строки в кавычках { "Number": "5" }, теперь могут быть десериализованы с помощью стандартного инструмента System.Text.Json.JsonSerializer в числовые свойства, как если бы они были обычными числами в JSON. Раньше это вызвало исключение JsonException.

2. Заменённые пакеты
Были переименованы или заменены различные пакеты:
AzureAD.UI
=> Microsoft.Identity.Web,
API AzureADB2C.UI
=> Microsoft.Identity.Web,
Microsoft.AspNetCore.DataProtection
.AzureKeyVault
=> Azure.Extensions.AspNetCore
.DataProtection.Keys
,
Microsoft.AspNetCore.DataProtection
.AzureStorage
=> Azure.Extensions.AspNetCore
.DataProtection.Blobs
,
Microsoft.Extensions
.Configuration.AzureKeyVault
=> Azure.Extensions.AspNetCore
.Configuration.Secrets

3. Изменения в Blazor для производительности
- Незначащие пробелы будут удаляться из файлов .razor во время компиляции. Это может привести к устранению сотен пустых узлов, которые потребляют память и пропускную способность сети несмотря на то, что не влияют на отображаемый HTML. Тестирование Microsoft показало улучшение времени рендеринга до 40%.

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

- Авторам библиотек, поддерживающих как .NET Core 3.x, так и .NET 5, потребуется использовать условную ссылку на пакет Microsoft.AspNetCore.Components для учёта обеих версий:
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0'" />

<PackageReference Include="Microsoft.AspNetCore.Components" Version="5.0.0-rc.1.*" Condition="'$(TargetFramework)' != 'netstandard2.0'" />

4. Blazor прекращает поддержку IE и Edge Legacy
Blazor в .NET 5 требует дополнительных функций, которые недоступны в старых браузерах. Internet Explorer не будет поддерживаться вообще. Ранее IE 11 мог получить доступ к веб-сайтам на основе Blazor через polyfills и asm.js. Но, по словам Дэниела Рота, с этим «было много проблем, и опыт использования был не очень хорош», поэтому в Microsoft отказались от asm.js и сосредоточились на WebAssembly.
Никакой конкретной причины относительно Edge Legacy не было указано, но, похоже, это сделано потому, что браузер больше не будет поддерживаться с 9 марта 2021 года. Edge Legacy был официально заменён браузером на основе Chromium.

5. Логи в HttpClient
В .NET Core логи HttpClient записывались с именами кодов ответа HTTP:
Received HTTP response after 56.0044ms - OK
End processing HTTP request after 70.0862ms – OK

Для большей согласованности с другими частями .NET это поведение было изменено на использование числовых кодов:
Received HTTP response after 56.0044ms - 200
End processing HTTP request after 70.0862ms – 200

Целью изменения было устранение несоответствия, из-за которого «затруднялось выполнение запросов через структурированные системы ведения логов, такие как Elasticsearch». Если вам нужно сохранить старое поведение, Microsoft рекомендует взять исходный код классов логирования для версии .NET Core 3.1 и включить их в свой проект. Возможно, это впервые, когда Microsoft используют открытый исходный код для решения проблемы обратной совместимости.

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

Источник:
https://www.infoq.com/news/2020/12/net-5-breaking-changes-aspnet/
День шестьсот восемьдесят восьмой. #ЧтоНовенького
Критические Изменения в .NET5.
ASP.NET. Продолжение 2/3
Продолжаем рассматривать изменения в ASP.NET в .NET5.
- BCL
- Исторические технологии
- ASP.NET. Начало

6. Исключение BadHttpRequestException заменено на BadHttpRequestException
Это странное изменение является результатом наличия в .NET трех классов BadHttpRequestException. Их полные имена:
- Microsoft.AspNetCore.Server
.Kestrel.BadHttpRequestException
,
- Microsoft.AspNetCore.Server
.IIS.BadHttpRequestException
и
- Microsoft.AspNetCore
.Http.BadHttpRequestException
.
Поскольку все они означают одно и то же, это сочли избыточным. Теперь используется только версия Http, другие были отмечены как устаревшие. Для некоторой обратной совместимости они будут унаследованы от версии Http.

7. Повторное согласование сертификата HttpSys отключено
Чтобы повысить производительность, предотвратить взаимоблокировки и поддерживать совместимость с HTTP/2, HttpSys по умолчанию не будет повторно согласовывать сертификаты клиентов. Несмотря на то, что его можно включить, Microsoft не рекомендует этого делать.

8. MVC: ObjectModelValidator вызывает новую перегрузку ValidationVisitor.Validate
Исходная сигнатура этого метода:
public virtual bool Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel)
Разработчики могут перегружать его для выполнения своей логики проверки. Затем этот метод вызывается объектом ObjectModelValidator.

В .NET 5 введена новая виртуальная перегрузка, и ObjectModelValidator теперь вызывает её:
public virtual bool Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel, object container)
При этом старая версия оставлена, и просто вызывает новую, передавая null в последний параметр. Если разработчик переопределит исходный метод Validate, то в .NET5 это переопределение будет проигнорировано. Код будет компилироваться, но ObjectModelValidator вместо переопределённого разработчиком метода вызовет новую перегрузку, и переопределённая версия просто не будет работать без каких-либо объяснений. Если вы посчитали, что это редко используемый функционал, то заметьте, что переопределяет этот метод, например, пакет FluentValidation (хотя, его код уже, похоже, исправили)

9. Отменена кодировка имени файла cookie
В стандарте HTTP имена файлов cookie представляют собой ограниченный набор символов ASCII. Для удобства разработчиков многие платформы, включая ASP.NET Core, позволяют включать дополнительные символы и просто кодируют их. Эта возможность была удалена по соображениям безопасности. Если в имени есть не-ASCII символ, может возникнуть исключение. Значения файлов cookie будут по-прежнему кодироваться/декодироваться как обычно.

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

Источник:
https://www.infoq.com/news/2020/12/net-5-breaking-changes-aspnet/
День шестьсот восемьдесят девятый. #ЧтоНовенького
Критические Изменения в .NET5.
ASP.NET. Окончание 3/3
В этом посте завершим обзор важных изменений в ASP.NET, введённых в .NET 5.
Предыдущие посты:
- BCL
- Исторические технологии
- ASP.NET Core. Начало
- ASP.NET Core. Продолжение

10. SignalR: протокол хаба MessagePack теперь использует MessagePackSerializerOptions
Ранее SignalR использовал MessagePack 1 для сериализации сообщений. В .NET 5 он был обновлен для использования MessagePack 2. Поскольку в MessagePack 2 было сделано критическое изменение (переход от IFormatterResolver к MessagePackSerializerOptions), в SignalR потребовалось внести аналогичное изменение в процесс обработки конфигурации. Это изменение повлияет только на тех, кто изменяет MessagePackHubProtocolOptions для SignalR.

11. SignalR теперь требует маршрутизации конечных точек
Маршрутизация конечных точек появилась в ASP.NET Core 3. Подробнее о том, зачем она была введена, я писал в этом посте. SignalR в это же время добавил возможность использовать маршрутизацию конечных точек, но это было необязательно. Старый механизм настраиваемой маршрутизации все ещё был доступен, хотя и отмечен как устаревший. В .NET 5 старый метод был полностью удалён, и теперь необходимо использовать конечную точку. К счастью, изменения в коде минимальны. Вместо:
app.UseSignalR(routes =>
{
routes.MapHub<SomeHub>("/path");
});
надо использовать
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<SomeHub>("/path");
});

12. Статические файлы: тип содержимого CSV изменен на соответствующий стандартам
Последнее изменение, которое мы обсудим в этом блоке - это соответствие стандартам для файлов CSV. По странному недосмотру предыдущие версии ASP.NET Core обслуживали статические файлы CSV как application/octet-stream, вместо text/csv. Это может повлиять на то, как браузеры обрабатывают эти файлы, что раньше заставляло разработчиков использовать FileExtensionContentTypeProvider для переопределения этого поведения. Теперь будет использоваться правильный тип содержимого. Если же разработчикам, использующим ASP.NET Core 5, потребуется старое поведение, они могут использовать всё тот же FileExtensionContentTypeProvider, чтобы вернуться к application/octet-stream.

Источник: https://www.infoq.com/news/2020/12/net-5-breaking-changes-aspnet/
День шестьсот девяностый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
70. Изучайте Гуманитарные Науки
Практически в любом проекте разработки ПО, кроме самых маленьких, люди работают с другими людьми. Во всех областях исследований, кроме самых абстрактных, люди пишут для людей ПО, которое поможет им в достижении какой-либо цели. Люди пишут программы вместе с людьми для людей. Этот бизнес связан с людьми. К сожалению, в процессе обучения программистов очень мало внимания уделяется аспекту взаимодействия с людьми, с которыми они работают. К счастью, есть целая область исследований, которая может помочь.

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

Лакофф и Джонсон представляют нам сборник «Метафоры, которыми мы живем» (Дж. Лакофф, М. Джонсон - ЛКИ, 2008) предполагая, что язык в значительной степени метафоричен, и что эти метафоры дают представление о том, как мы воспринимаем мир. Даже такие, казалось бы, конкретные термины, как «денежный поток» (cash flow), используемый в разговоре о финансовой системе, можно рассматривать как метафору: «деньги как вода». Как эта метафора влияет на наше восприятие систем, работающих с деньгами? Или же часто используется метафора слоёв в стеке протоколов, где пользовательские слои «вверху», а детали технологии «внизу». Это влияет на то, как мы представляем структуру систем, которые мы строим. Это также может указывать на стремление мыслить шаблонно, от чего время от времени бывает полезно отказываться.

Мартин Хайдеггер внимательно изучил, как люди пользуются инструментами. Программисты создают, меняют, дорабатывают и используют инструменты. Инструменты – постоянный объект интереса программистов. Но для пользователей, как показывает Хайддегер в книге «Бытие и время», инструмент невидим, и понять его можно только при использовании. Для пользователей инструменты становятся объектами изучения только тогда, когда они не работают. Это различие в акцентах стоит иметь в виду всякий раз, когда обсуждается удобство использования.

Элеонора Рош пересмотрела модель категорий Аристотеля, согласно которой мы выстраиваем своё понимание мира. Когда программисты спрашивают пользователей об их желаниях относительно системы, они, как правило, просят дать определения на основе предикатов (некоторых утверждений о субъекте разговора). Например, делать что-то, если случаются события A, B или C. Для программистов это очень удобно. Предикаты могут легко стать атрибутами класса или столбцами в таблице. Эти категории чёткие, непересекающиеся и аккуратные. К сожалению, как показала Рош в работе «Естественные категории» ("Natural categories", Rosch, E. H. - Cognitive Psychology, 1973) и более поздних работах, обычные люди понимают мир иначе. Они постигают его на примерах. Некоторые примеры, так называемые прототипы, лучше других. Поэтому результаты могут получаться нечёткими, перекрываться с другими и иметь сложную внутреннюю структуру. Поскольку мы настаиваем на аристотелевских ответах, мы не можем задать пользователям правильных вопросов, отсюда и сложности в достижении взаимопонимания.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Keith Braithwaite
День шестьсот девяносто первый. #ЧтоНовенького
Нововведения в GitHub

Ручные Подтверждения в GitHub Actions
В GitHub Actions в бета версии появились функции развёртывания. Теперь вы можете:
1. Визуализировать пайплайн
2. Создавать среды, в которых можно устанавливать
- Рецензентов, которые подтверждают развёртывание вручную
- Время ожидания перед запуском развёртывания
- Секреты специфичные для каждой среды

Перейдите в Settings > Environments и создайте новую среду. Задайте имя среды и нажмите Configure environment. Добавьте требуемых рецензентов, установив флажок Required reviewers (вы можете добавить список людей и/или команд). После этого не забудьте нажать Save protection rules (см. картинку 1 ниже).
Теперь можно отредактировать файл YAML. В него нужно добавить блок:
environment:
name: <имя среды>
url: <url развёрнутого в среде сайта>
Обратите внимание, что имя среды в YAML файле должно совпадать с именем среды, заданной в параметрах GitHub выше.

Появится красивая визуализация пайплайна (см. картинку 2 ниже). Как видите, процесс прошёл стадии развёртывания и функциональных тестов, а затем остановился. Теперь он ждёт подтверждения от заданных рецензентов. У рецензентов, соответственно, появляется сообщение, что процесс развёртывания ждёт подтверждения. После получения подтверждения процесс продолжается.

Обсуждения
До сих пор GitHub предлагал только Issues и Pull Requests в качестве площадки для обсуждений. Проблема в том, что они имеют линейный формат и хорошо подходят для обсуждения изменений в коде, но не для создания базы знаний сообщества. Беседам нужно отдельное место - для этого и созданы GitHub Discussions.

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

Источники:
-
https://devblogs.microsoft.com/devops/i-need-manual-approvers-for-github-actions-and-i-got-them-now/
-
https://github.blog/2020-05-06-new-from-satellite-2020-github-codespaces-github-discussions-securing-code-in-private-repositories-and-more/