День 1814. #Оффтоп
Давно не советовал вам хороших видео. Недавно наткнулся на прекрасный рассказ Enrico Tartarotti, продакт менеджера в Maze, «Ложь, которая заставляет работать технологии».
За простыми вещами, которые вы делаете каждый день и считаете само собой разумеющимися, скрывается огромный мир дизайна, инженерии, психологии, копирования природы и трюков, которые делают технологии пригодными для использования людьми. И большинство людей никогда этого не замечают.
Как на самом деле работает клавиатура в смартфоне? Сколько инженерных решений вложено в простое нажатие клавиши на экране? Не говоря уже про скроллинг или «свайп». Все мы привыкли к тому, что курсор в тексте мигает. А вы замечали, что он перестаёт мигать, когда вы набираете текст? Мы привыкли к двойному нажатию мыши на иконке, чтобы открыть. Мы привыкли к жесту разведения пальцев, чтобы увеличить что-то на экране или к двойному нажатию на пост в телефоне, чтобы поставить лайк (кстати... ну, вы поняли, что надо сделать 😉). И это кажется нам вполне естественным. Но кто научил наш мозг этим «естественным» жестам? И каким жестам нам придётся обучиться в мире дополненной реальности?
А также про многие другие решения, о которых мы даже не задумываемся, когда пользуемся привычными технологиями.
https://youtu.be/rAVV4kAYlI8
Приятного просмотра.
Давно не советовал вам хороших видео. Недавно наткнулся на прекрасный рассказ Enrico Tartarotti, продакт менеджера в Maze, «Ложь, которая заставляет работать технологии».
За простыми вещами, которые вы делаете каждый день и считаете само собой разумеющимися, скрывается огромный мир дизайна, инженерии, психологии, копирования природы и трюков, которые делают технологии пригодными для использования людьми. И большинство людей никогда этого не замечают.
Как на самом деле работает клавиатура в смартфоне? Сколько инженерных решений вложено в простое нажатие клавиши на экране? Не говоря уже про скроллинг или «свайп». Все мы привыкли к тому, что курсор в тексте мигает. А вы замечали, что он перестаёт мигать, когда вы набираете текст? Мы привыкли к двойному нажатию мыши на иконке, чтобы открыть. Мы привыкли к жесту разведения пальцев, чтобы увеличить что-то на экране или к двойному нажатию на пост в телефоне, чтобы поставить лайк (кстати... ну, вы поняли, что надо сделать 😉). И это кажется нам вполне естественным. Но кто научил наш мозг этим «естественным» жестам? И каким жестам нам придётся обучиться в мире дополненной реальности?
А также про многие другие решения, о которых мы даже не задумываемся, когда пользуемся привычными технологиями.
https://youtu.be/rAVV4kAYlI8
Приятного просмотра.
YouTube
The LIES That Make Your Tech ACTUALLY Work
Learn EXACTLY how I make my videos:
https://www.enricotartarotti.com/storybehind?utm_source=desc
Instagram: https://www.instagram.com/thisisenri
--------
📮 Behind the scenes and nuggets on my free newsletter:
https://www.enricotartarotti.com/email-club…
https://www.enricotartarotti.com/storybehind?utm_source=desc
Instagram: https://www.instagram.com/thisisenri
--------
📮 Behind the scenes and nuggets on my free newsletter:
https://www.enricotartarotti.com/email-club…
👍18👎1
День 1815. #Карьера
Забота – это Больше, чем Долгие Часы Работы
Бывший инженер Netflix Алекс Кастильо в твите размышляет о ценности заботы о результате. Их команда в пятницу обнаружила неработающее приложение и сумела всё исправить к понедельнику. Быстрый результат объясняется тем, насколько «заботились о продукте» вовлеченные люди.
Приложение, унаследованное командой Алекса, они не смогли даже запустить локально, не говоря уже о том, чтобы исправить в пятницу. В понедельник они решили собраться, чтобы найти решение. Алекс, стремясь проявить себя, в выходные написал новое приложение для замены. Он представил его своему менеджеру, но тот поделился с ним приложением, которое другой член команды создал за выходные. Развернули второе предложение (скорее всего, собравшись и сравнив варианты). Алекс пишет: «Именно тогда я понял, что я работаю с неравнодушными людьми и хочу работать только с такими людьми». И он прав.
Когда все в команде преданы цели, их результаты превосходят сумму их индивидуальных способностей. Но нельзя приравнивать работу в выходные к заботе!
Мы знаем историю только по короткому твиту и не в курсе деталей. Но твит сочетает в себе положительную ценность засучивания рукавов для поиска решений неотложных проблем с переутомлением и геройским менталитетом, что опасно. Есть разница между заботой, бросаться с головой в проблему, и заботой, сделать шаг назад и все тщательно обдумать.
Долгий рабочий день — плохая замена хорошей инженерии
Иногда надо поработать на выходных. Похоже, команда Алекса оказалась в такой ситуации. Их усилия помогли решить проблему, что наверняка принесло пользу бизнесу.
Но. Два инженера в команде из трёх провели выходные за работой. Насколько хорошо команда сможет выступить на этой неделе? Что, если бы новое приложение оказалось неисправным или возник бы другой, более серьёзный сбой? Работа сверхурочно — эффективный способ потушить пожар. Но это неустойчивый подход, и его не следует поощрять как способ проявить заботу.
Работа в выходные — это решение симптомов, которое не устраняет основную проблему. Исправлять сломанное приложение бессмысленно, если вы не устраните проблемы, которые изначально привели к поломке. Если не провести анализ для выявления основной причины проблемы и способов её предотвращения в будущем, это приведёт лишь к созданию прецедента, который другие могут счесть нормальностью.
Лучший подход — постоянно концентрироваться на качестве. Проявите заботу через результаты труда, а не через количество рабочих часов. Забота — это выполнение скромной, скучной, но необходимой работы по очистке, которую требует каждая устоявшаяся кодовая база. Иногда приходится сопротивляться давлению, требованию новых фич, чтобы обеспечить надёжную реализацию.
Общение – это забота
Ещё одна проблема в истории Алекса - отсутствие общения. Почему он или его коллега не договорились? Они могли бы поработать вместе и достичь лучшего результата. А менеджер мог бы либо уговорить их отдохнуть, либо подбодрить и компенсировать им работу в выходные отгулом на неделе.
Коммуникация является важнейшим компонентом эффективной и продуманной командной работы.
Проявляйте заботу последовательно, а не интенсивно
Третий член команды, не представивший своё решение, ему разве было всё равно? Возможно, но этот случай не показатель. Хорошо работать только с людьми, которым не всё равно, но в первую очередь нужно заботиться о долгосрочной игре. Важно расслабляться, чтобы сосредоточиться во время работы и придумывать новые решения, которые может дать только отдохнувший мозг.
Алекс хотел подчеркнуть ценную черту, но выбрал для этого не ту историю. Он и его коллега проявили большую заботу, но не потому, что работали в выходные. Они взяли на себя ответственность и инициативу и принялись за решение насущной проблемы. Ищите людей, которые возьмут на себя ответственность за проблемы и посвятят себя их решению. Но не путайте переработку с заботой.
Источник: https://betterprogramming.pub/theres-more-to-caring-than-working-long-hours-f64a89e9c718
Забота – это Больше, чем Долгие Часы Работы
Бывший инженер Netflix Алекс Кастильо в твите размышляет о ценности заботы о результате. Их команда в пятницу обнаружила неработающее приложение и сумела всё исправить к понедельнику. Быстрый результат объясняется тем, насколько «заботились о продукте» вовлеченные люди.
Приложение, унаследованное командой Алекса, они не смогли даже запустить локально, не говоря уже о том, чтобы исправить в пятницу. В понедельник они решили собраться, чтобы найти решение. Алекс, стремясь проявить себя, в выходные написал новое приложение для замены. Он представил его своему менеджеру, но тот поделился с ним приложением, которое другой член команды создал за выходные. Развернули второе предложение (скорее всего, собравшись и сравнив варианты). Алекс пишет: «Именно тогда я понял, что я работаю с неравнодушными людьми и хочу работать только с такими людьми». И он прав.
Когда все в команде преданы цели, их результаты превосходят сумму их индивидуальных способностей. Но нельзя приравнивать работу в выходные к заботе!
Мы знаем историю только по короткому твиту и не в курсе деталей. Но твит сочетает в себе положительную ценность засучивания рукавов для поиска решений неотложных проблем с переутомлением и геройским менталитетом, что опасно. Есть разница между заботой, бросаться с головой в проблему, и заботой, сделать шаг назад и все тщательно обдумать.
Долгий рабочий день — плохая замена хорошей инженерии
Иногда надо поработать на выходных. Похоже, команда Алекса оказалась в такой ситуации. Их усилия помогли решить проблему, что наверняка принесло пользу бизнесу.
Но. Два инженера в команде из трёх провели выходные за работой. Насколько хорошо команда сможет выступить на этой неделе? Что, если бы новое приложение оказалось неисправным или возник бы другой, более серьёзный сбой? Работа сверхурочно — эффективный способ потушить пожар. Но это неустойчивый подход, и его не следует поощрять как способ проявить заботу.
Работа в выходные — это решение симптомов, которое не устраняет основную проблему. Исправлять сломанное приложение бессмысленно, если вы не устраните проблемы, которые изначально привели к поломке. Если не провести анализ для выявления основной причины проблемы и способов её предотвращения в будущем, это приведёт лишь к созданию прецедента, который другие могут счесть нормальностью.
Лучший подход — постоянно концентрироваться на качестве. Проявите заботу через результаты труда, а не через количество рабочих часов. Забота — это выполнение скромной, скучной, но необходимой работы по очистке, которую требует каждая устоявшаяся кодовая база. Иногда приходится сопротивляться давлению, требованию новых фич, чтобы обеспечить надёжную реализацию.
Общение – это забота
Ещё одна проблема в истории Алекса - отсутствие общения. Почему он или его коллега не договорились? Они могли бы поработать вместе и достичь лучшего результата. А менеджер мог бы либо уговорить их отдохнуть, либо подбодрить и компенсировать им работу в выходные отгулом на неделе.
Коммуникация является важнейшим компонентом эффективной и продуманной командной работы.
Проявляйте заботу последовательно, а не интенсивно
Третий член команды, не представивший своё решение, ему разве было всё равно? Возможно, но этот случай не показатель. Хорошо работать только с людьми, которым не всё равно, но в первую очередь нужно заботиться о долгосрочной игре. Важно расслабляться, чтобы сосредоточиться во время работы и придумывать новые решения, которые может дать только отдохнувший мозг.
Алекс хотел подчеркнуть ценную черту, но выбрал для этого не ту историю. Он и его коллега проявили большую заботу, но не потому, что работали в выходные. Они взяли на себя ответственность и инициативу и принялись за решение насущной проблемы. Ищите людей, которые возьмут на себя ответственность за проблемы и посвятят себя их решению. Но не путайте переработку с заботой.
Источник: https://betterprogramming.pub/theres-more-to-caring-than-working-long-hours-f64a89e9c718
👍12
День 1817. #ЧтоНовенького #CSharp13
Новый Тип Блокировки в .NET 9.
Продолжаем заглядывать в будущее. Новый тип System.Threading.Lock, представлен для .NET 9.
Предупреждение: тип Lock всё ещё находится в режиме предварительного просмотра. Вы можете загрузить текущую сборку .NET 9 и выбрать новый тип блокировки с помощью переключателя
в файле csproj. Тем не менее, в будущем в этом типе ещё могут произойти кардинальные изменения.
Новый тип блокировки имеет одну основную цель: быть блокировкой. Т.е. представляет собой блокировку и только блокировку. Нет никакой двусмысленности в том, что он делает. До сих пор мы сделали что-то вроде следующего:
Новый тип Lock выражает это более явно:
Есть и другое предложение: "Паттерн оператора блокировки". Идея в том, чтобы иметь маркерный интерфейс ILockPattern, который «специально обрабатывается» компилятором и несколько новых типов блокировок. Например, следующий код:
Будет преобразовано в:
Здесь _lock может быть любым типом блокировки, реализующим ILockPattern. EnterLockScope будет выдавать disposable контекст блокировки.
Источник: https://steven-giesel.com/blogPost/d7f923b3-13ff-4ecc-8b8f-d847ae581f68/a-new-lock-type-in-net-9
Новый Тип Блокировки в .NET 9.
Продолжаем заглядывать в будущее. Новый тип System.Threading.Lock, представлен для .NET 9.
Предупреждение: тип Lock всё ещё находится в режиме предварительного просмотра. Вы можете загрузить текущую сборку .NET 9 и выбрать новый тип блокировки с помощью переключателя
<EnablePreviewFeatures>true</EnablePreviewFeatures>
в файле csproj. Тем не менее, в будущем в этом типе ещё могут произойти кардинальные изменения.
Новый тип блокировки имеет одну основную цель: быть блокировкой. Т.е. представляет собой блокировку и только блокировку. Нет никакой двусмысленности в том, что он делает. До сих пор мы сделали что-то вроде следующего:
object _obj = new();
void DoSomething()
{
lock (_obj)
{
// Что-то делаем
}
}
Новый тип Lock выражает это более явно:
Lock _lock = new();Использование его абсолютно такое же (на данный момент). Но новый тип явный и теоретически может быть быстрее. Это зависит от используемой базовой реализации. До сих пор конструкция lock { … } всегда заменялась на пару операторов Monitor.Enter/Monitor.Exit, но теперь это не обязательно будет так.
void DoSomething()
{
lock (_lock)
{
// Что-то делаем
}
}
Есть и другое предложение: "Паттерн оператора блокировки". Идея в том, чтобы иметь маркерный интерфейс ILockPattern, который «специально обрабатывается» компилятором и несколько новых типов блокировок. Например, следующий код:
class MyDataStructure
{
private Lock _lock = new();
void Foo()
{
lock (_lock)
{
// Что-то делаем
}
}
}
Будет преобразовано в:
class MyDataStructure
{
private Lock _lock = new();
void Foo()
{
using (_lock.EnterLockScope())
{
// Что-то делаем
}
}
}
Здесь _lock может быть любым типом блокировки, реализующим ILockPattern. EnterLockScope будет выдавать disposable контекст блокировки.
Источник: https://steven-giesel.com/blogPost/d7f923b3-13ff-4ecc-8b8f-d847ae581f68/a-new-lock-type-in-net-9
👍24
День 1818. #ЗаметкиНаПолях
Создаём Защитные Предложения
Защитные предложения (Guard Clause) в .NET — это простые проверки данных или условий в начале функции или метода.
Преимущества:
- уменьшают сложность и повышают читаемость, позволяя избегать глубокой вложенности кода;
- повышают безопасность и надёжность кода, проверяя входные данные или условия в начале, предотвращая потенциальные ошибки во время выполнения или непредвиденное поведение;
- проясняют цель кода, явно указывая предварительные условия, необходимые для правильного выполнения последующего кода.
Обычно проверка входных данных выглядит примерно так:
Здесь всё просто. Спорный вопрос про выброс исключения в случае невалидных данных, но сейчас не об этом. Что здесь не так? В принципе, всё нормально, кроме читаемости кода. А что, если проверок будет больше?
Создадим статический метод для проверки условий.
Здесь вместо того, чтобы постоянно передавать имя параметра, для которого выдаётся исключение, мы используем атрибут CallerArgumentExpression, передавая ему имя нужного параметра. Во время выполнения это значение будет прочитано и присвоено атрибуту paramName.
Теперь работа по проверке условий и выбросу исключений ложится на отдельный класс, а код проверяемого класса проще:
Многие разработчики уже создали качественные библиотеки для этой же цели.
Вот некоторые из них:
- Ardalis
- Dawn
- Throw
Какую бы вы ни выбрали, у вас не возникнет никаких проблем. А если вам хочется большего контроля, вы всегда можете создать собственное защитное предложение, как показано выше.
Источник: https://stefandjokic.tech/posts/how-to-create-dotnet-custom-guard-clause
Создаём Защитные Предложения
Защитные предложения (Guard Clause) в .NET — это простые проверки данных или условий в начале функции или метода.
Преимущества:
- уменьшают сложность и повышают читаемость, позволяя избегать глубокой вложенности кода;
- повышают безопасность и надёжность кода, проверяя входные данные или условия в начале, предотвращая потенциальные ошибки во время выполнения или непредвиденное поведение;
- проясняют цель кода, явно указывая предварительные условия, необходимые для правильного выполнения последующего кода.
Обычно проверка входных данных выглядит примерно так:
public class Person
{
public string Name { get; private set; }
public Person(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException(
"Имя не может быть пустым.",
nameof(name));
Name = name;
}
}
Здесь всё просто. Спорный вопрос про выброс исключения в случае невалидных данных, но сейчас не об этом. Что здесь не так? В принципе, всё нормально, кроме читаемости кода. А что, если проверок будет больше?
Создадим статический метод для проверки условий.
public static class Ensure
{
public static void NotNullOrEmpty(
string? value,
[CallerArgumentExpression("value")]
string? paramName = null)
{
if(string.IsNullOrEmpty(value))
throw new ArgumentException(
"Значение не может быть пустым",
paramName);
}
}
Здесь вместо того, чтобы постоянно передавать имя параметра, для которого выдаётся исключение, мы используем атрибут CallerArgumentExpression, передавая ему имя нужного параметра. Во время выполнения это значение будет прочитано и присвоено атрибуту paramName.
Теперь работа по проверке условий и выбросу исключений ложится на отдельный класс, а код проверяемого класса проще:
public Person(string name)
{
Ensure.NotNullOrEmpty(name);
//…
}
Многие разработчики уже создали качественные библиотеки для этой же цели.
Вот некоторые из них:
- Ardalis
- Dawn
- Throw
Какую бы вы ни выбрали, у вас не возникнет никаких проблем. А если вам хочется большего контроля, вы всегда можете создать собственное защитное предложение, как показано выше.
Источник: https://stefandjokic.tech/posts/how-to-create-dotnet-custom-guard-clause
👍24
День 1819. #ЗаметкиНаПолях
Непостоянные Строковые Константы
Ключевое слово const работает следующим образом: компилятор помещает строку в блок памяти только для чтения, а затем заменяет все ссылки на строку адресом строки в памяти. Поэтому следующий код:
Будет преобразован в:
В скомпилированном коде нет foo. Поэтому нельзя использовать в константах переменные или вещи, которые «неизвестны» во время компиляции. Но можем ли мы изменить константную строку?
Интернирование строк
Где-то в памяти должна храниться строка. Используемый здесь механизм называется интернированием строк. Компилятор проверяет все константные строки в коде и помещает их в специальную таблицу в памяти. Если у вас есть две константные строки с одинаковым значением, они будут помещены в одну запись таблицы. Поэтому код:
Будет преобразован в:
… и выведет True.
Компилятор заменит все ссылки на foo и other_foo строкой «bar», а поскольку строки интернированы, они будут равны.
Теперь попробуем изменить запись в таблице интернированных строк. Итак, по логике, даже после вызова ModifyString, на консоль должно быть выведено
Как это изменить? Просто получим адрес строки в памяти и изменим то, что там хранится:
В итоге в выводе получим
Самые внимательные заметили, что мы записали больше символов, чем длина строки. Компилятор поместит строку в буфер с длиной строки + 1. Поэтому, если мы напишем больше, чем длина строки, мы перезапишем следующую строку в буфере. Выводится всё равно Foo, поскольку метаданные объекта сохраняют его длину, поэтому длина нашей строки по-прежнему составляет 3 символа. Вы можете подумать: а что, если в следующем блоке памяти есть что-нибудь, могу ли я там что-то перезаписать? Короткий ответ: нет, вы получите исключение System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. (Попытка чтения или записи защищенной памяти». Часто это указывает на то, что другая память повреждена.)
Напоследок ещё один момент, касающийся интернирования строк. Если в конец предыдущего примера мы добавим вывод строки, построенной следующим образом:
Как вы думаете, что будет выведено на консоль:
Будет выведено
Итого
Мы увидели, что константные строки в конце концов не такие уж и константные (не без костылей, но всё же). Вам, скорее всего (надеюсь), это не пригодится, но понимание внутренностей может быть интересным и полезным! Вот ссылка на Sharplab.io, если вы хотите напрямую поиграть с кодом.
Источник: https://steven-giesel.com/blogPost/544c33da-be2e-4d96-99c9-9313f48548bd/const-strings-are-not-so-const-after-all
Непостоянные Строковые Константы
Ключевое слово const работает следующим образом: компилятор помещает строку в блок памяти только для чтения, а затем заменяет все ссылки на строку адресом строки в памяти. Поэтому следующий код:
const string foo = "bar";
Console.WriteLine(foo);
Console.WriteLine(foo);
Будет преобразован в:
Console.WriteLine("bar");
Console.WriteLine("bar");
В скомпилированном коде нет foo. Поэтому нельзя использовать в константах переменные или вещи, которые «неизвестны» во время компиляции. Но можем ли мы изменить константную строку?
Интернирование строк
Где-то в памяти должна храниться строка. Используемый здесь механизм называется интернированием строк. Компилятор проверяет все константные строки в коде и помещает их в специальную таблицу в памяти. Если у вас есть две константные строки с одинаковым значением, они будут помещены в одну запись таблицы. Поэтому код:
const string foo = "bar";
const string other_foo = "bar";
Console.WriteLine(foo);
Console.WriteLine(other_foo);
Console.WriteLine(ReferenceEquals(foo, other_foo));
Будет преобразован в:
Console.WriteLine("bar");
Console.WriteLine("bar");
Console.WriteLine((object)"bar" == "bar");
… и выведет True.
Компилятор заменит все ссылки на foo и other_foo строкой «bar», а поскольку строки интернированы, они будут равны.
Теперь попробуем изменить запись в таблице интернированных строк. Итак, по логике, даже после вызова ModifyString, на консоль должно быть выведено
bar
:const string foo = "bar";
ModifyString(foo);
Console.WriteLine(foo);
Как это изменить? Просто получим адрес строки в памяти и изменим то, что там хранится:
unsafe void ModifyString(string foo)
{
fixed(char* f = foo)
{
f[0] = 'F';
f[1] = 'o';
f[2] = 'o';
f[3] = '!';
}
}
В итоге в выводе получим
Foo
. Мы не можем изменить строку (в смысле ее адреса), но можем изменить её содержимое. Интересно, что это также сработает и для переменной var foo = "bar"
.Самые внимательные заметили, что мы записали больше символов, чем длина строки. Компилятор поместит строку в буфер с длиной строки + 1. Поэтому, если мы напишем больше, чем длина строки, мы перезапишем следующую строку в буфере. Выводится всё равно Foo, поскольку метаданные объекта сохраняют его длину, поэтому длина нашей строки по-прежнему составляет 3 символа. Вы можете подумать: а что, если в следующем блоке памяти есть что-нибудь, могу ли я там что-то перезаписать? Короткий ответ: нет, вы получите исключение System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. (Попытка чтения или записи защищенной памяти». Часто это указывает на то, что другая память повреждена.)
Напоследок ещё один момент, касающийся интернирования строк. Если в конец предыдущего примера мы добавим вывод строки, построенной следующим образом:
Console.WriteLine(string.Concat("b", "ar"));
Как вы думаете, что будет выведено на консоль:
Foo
или bar
? Будет выведено
bar
, поскольку «динамические» строки не интернируются, и поэтому в нашем случае строка, созданная из string.Concat, находится по другому адресу в памяти.Итого
Мы увидели, что константные строки в конце концов не такие уж и константные (не без костылей, но всё же). Вам, скорее всего (надеюсь), это не пригодится, но понимание внутренностей может быть интересным и полезным! Вот ссылка на Sharplab.io, если вы хотите напрямую поиграть с кодом.
Источник: https://steven-giesel.com/blogPost/544c33da-be2e-4d96-99c9-9313f48548bd/const-strings-are-not-so-const-after-all
👍27👎1
День 1820. #ЧтоНовенького
NuGetSolver: Разрешение Конфликтов Зависимостей в Visual Studio
Microsoft представили новый экспериментальный инструмент NuGetSolver. Это расширение Visual Studio было создано совместно с Microsoft Research. Цель — упростить разрешение конфликтов зависимостей NuGet в проектах Visual Studio. Расширение эффективно устраняет распространённые ошибки и предупреждения NuGet, такие как ограничения зависимостей между пакетами (NU1107), случаи, когда пакет зависимостей не содержит ресурсов, совместимых с проектом (NU1202), обнаруженные понижения версии пакета (NU1605), и предупреждения о несовместимости версий (NU1701).
Чтобы начать использовать NuGetSolver, разработчики могут загрузить расширение из Visual Studio Marketplace. Расширение предлагает решение исследуя все зависимости и предоставляя интеллектуальные и автоматизированные предложения. Доступ к этому инструменту можно получить через обозреватель решений, щёлкнув правой кнопкой мыши и выбрав Resolve Dependency Conflicts (Разрешить конфликты зависимостей). Инструмент отобразит различия между текущим и предлагаемым состояниями. Пользователи также могут включить флажок Show only changes (Показать только изменения), чтобы просмотреть полный список зависимостей. По умолчанию инструмент предлагает стабильные версии с возможностью включения предварительных версий при необходимости. Если рекомендуемое предложение приемлемо для разработчика, нужно нажать кнопку Apply fix (Применить исправление) и пересобрать решение.
Создатели рекомендуют включить решение в систему контроля версий, чтобы при необходимости можно было легко отменить любые изменения, внесённые NuGetSolver.
Если в решении в настоящее время отсутствуют конфликты зависимостей, разработчики всё равно могут запустить инструмент для эффективного обновления зависимостей, минимизируя изменения. Это оказывается более быстрой и надёжной альтернативой обновлению пакетов по одному с помощью менеджера пакетов NuGet.
Однако существуют некоторые рекомендации по использованию и известные ограничения:
1. В настоящее время поддерживается только канал nuget.org.
2. Исправление может не полностью поддерживать обновление версий, если для настроек версии используется пользовательская логика MSBuild.
3. NuGetSolver может не учитывать все доступные предварительные версии во время расчёта предложений.
4. Для проектов, использующих packages.config или устаревшие sdk, инструмент может генерировать предложения, но не может применить исправление автоматически, требуется исправление вручную.
5. Хотя NuGetSolver может разрешать конфликты зависимостей во время компиляции, ошибки во время выполнения все равно могут возникать.
6. Инструмент не проверяет наличие известных уязвимостей в предлагаемых версиях, поэтому разработчикам рекомендуется использовать функцию аудита в NuGet для решения этой проблемы.
Источник: https://www.infoq.com/news/2024/01/introducing-nuget-solver/
NuGetSolver: Разрешение Конфликтов Зависимостей в Visual Studio
Microsoft представили новый экспериментальный инструмент NuGetSolver. Это расширение Visual Studio было создано совместно с Microsoft Research. Цель — упростить разрешение конфликтов зависимостей NuGet в проектах Visual Studio. Расширение эффективно устраняет распространённые ошибки и предупреждения NuGet, такие как ограничения зависимостей между пакетами (NU1107), случаи, когда пакет зависимостей не содержит ресурсов, совместимых с проектом (NU1202), обнаруженные понижения версии пакета (NU1605), и предупреждения о несовместимости версий (NU1701).
Чтобы начать использовать NuGetSolver, разработчики могут загрузить расширение из Visual Studio Marketplace. Расширение предлагает решение исследуя все зависимости и предоставляя интеллектуальные и автоматизированные предложения. Доступ к этому инструменту можно получить через обозреватель решений, щёлкнув правой кнопкой мыши и выбрав Resolve Dependency Conflicts (Разрешить конфликты зависимостей). Инструмент отобразит различия между текущим и предлагаемым состояниями. Пользователи также могут включить флажок Show only changes (Показать только изменения), чтобы просмотреть полный список зависимостей. По умолчанию инструмент предлагает стабильные версии с возможностью включения предварительных версий при необходимости. Если рекомендуемое предложение приемлемо для разработчика, нужно нажать кнопку Apply fix (Применить исправление) и пересобрать решение.
Создатели рекомендуют включить решение в систему контроля версий, чтобы при необходимости можно было легко отменить любые изменения, внесённые NuGetSolver.
Если в решении в настоящее время отсутствуют конфликты зависимостей, разработчики всё равно могут запустить инструмент для эффективного обновления зависимостей, минимизируя изменения. Это оказывается более быстрой и надёжной альтернативой обновлению пакетов по одному с помощью менеджера пакетов NuGet.
Однако существуют некоторые рекомендации по использованию и известные ограничения:
1. В настоящее время поддерживается только канал nuget.org.
2. Исправление может не полностью поддерживать обновление версий, если для настроек версии используется пользовательская логика MSBuild.
3. NuGetSolver может не учитывать все доступные предварительные версии во время расчёта предложений.
4. Для проектов, использующих packages.config или устаревшие sdk, инструмент может генерировать предложения, но не может применить исправление автоматически, требуется исправление вручную.
5. Хотя NuGetSolver может разрешать конфликты зависимостей во время компиляции, ошибки во время выполнения все равно могут возникать.
6. Инструмент не проверяет наличие известных уязвимостей в предлагаемых версиях, поэтому разработчикам рекомендуется использовать функцию аудита в NuGet для решения этой проблемы.
Источник: https://www.infoq.com/news/2024/01/introducing-nuget-solver/
👍11
День 1821. #ЗаметкиНаПолях
Разница Mежду CultureInfo.Get и new CultureInfo
Если вы хотите получить объект CultureInfo, вы можете использовать статический метод CultureInfo.GetCultureInfo или конструктор класса CultureInfo. Рассмотрим разницу между ними.
Конструктор создает новый экземпляр указанной культуры. Вы можете редактировать данные этого экземпляра. Это означает, что вы можете изменить календарь, числовой формат и т. д. Следующий код показывает, как изменить символ валюты:
Статический метод CultureInfo.GetCultureInfo возвращает доступный только для чтения экземпляр указанной культуры. Вы не можете редактировать данные этого экземпляра. И поэтому метод может кэшировать экземпляр. Таким образом, это может быть быстрее и уменьшить использование памяти.
Если выполнить простой тест производительности, можно увидеть разницу в распределении между двумя методами:
Итого
Используйте CultureInfo.GetCultureInfo большую часть времени, поскольку редактирование объекта CultureInfo требуется очень редко.
Замечание: GetCultureInfo возвращает экземпляр культуры, доступный только для чтения, однако компилятор не запретит вам изменять его свойства и не выдаст ошибку компиляции. В этом случае при попытке изменить свойства такого экземпляра возникнет ошибка времени выполнения.
Источник: https://www.meziantou.net/difference-between-cultureinfo-get-and-new-cultureinfo.htm
Разница Mежду CultureInfo.Get и new CultureInfo
Если вы хотите получить объект CultureInfo, вы можете использовать статический метод CultureInfo.GetCultureInfo или конструктор класса CultureInfo. Рассмотрим разницу между ними.
var c1 = CultureInfo.GetCultureInfo("en-US");
var c2 = new CultureInfo("en-US");
Конструктор создает новый экземпляр указанной культуры. Вы можете редактировать данные этого экземпляра. Это означает, что вы можете изменить календарь, числовой формат и т. д. Следующий код показывает, как изменить символ валюты:
var c = new CultureInfo("en-US");
c.NumberFormat.CurrencySymbol = "€";
Console.WriteLine(42.ToString("C", c));
// €42.00
Статический метод CultureInfo.GetCultureInfo возвращает доступный только для чтения экземпляр указанной культуры. Вы не можете редактировать данные этого экземпляра. И поэтому метод может кэшировать экземпляр. Таким образом, это может быть быстрее и уменьшить использование памяти.
var c1 = CultureInfo.GetCultureInfo("en-US");
var c2 = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(ReferenceEquals(c1, c2));
// True
Если выполнить простой тест производительности, можно увидеть разницу в распределении между двумя методами:
[MemoryDiagnoser]
public class CultureInfoBenchmark
{
[Benchmark(Baseline = true)]
public void Ctor()
{
_ = new CultureInfo("en-US");
}
[Benchmark]
public void StaticMethod()
{
_ = CultureInfo.GetCultureInfo("en-US");
}
}
Method Mean Allocated
Ctor 33.74 ns 144 B
StaticMethod 24.44 ns 32 B
Итого
Используйте CultureInfo.GetCultureInfo большую часть времени, поскольку редактирование объекта CultureInfo требуется очень редко.
Замечание: GetCultureInfo возвращает экземпляр культуры, доступный только для чтения, однако компилятор не запретит вам изменять его свойства и не выдаст ошибку компиляции. В этом случае при попытке изменить свойства такого экземпляра возникнет ошибка времени выполнения.
Источник: https://www.meziantou.net/difference-between-cultureinfo-get-and-new-cultureinfo.htm
👍13
День 1822. #Карьера
6 Факторов, Определяющих Победите Вы или Провалитесь. Начало
Во всех наших начинаниях успех – это желаемое конечное состояние. Он приносит воодушевление, радость и гордость. А неудача разочаровывает и может даже лишить некоторых мотивации пытаться достичь своих целей. Не существует единого ключа к успеху, т.к. он часто является сочетанием множества различных факторов: не только ваших усилий, но и обстоятельств, опыта и удачи.
Вот 6 факторов, которые не гарантируют успеха, но определённо помогут изменить баланс в вашу пользу.
1. Ясность критериев успеха
Если иметь лишь смутное представление о том, что для вас значит успех, может быть сложно определить, достигли ли вы своей цели. Достижение успеха начинается с определения того, что он для вас значит: что для вас важно, чего вы хотите достичь, почему это важно, как вы можете это измерить?
Определите успех, ответив на следующие вопросы:
- Как выглядит успех?
- Что изменится, когда вы достигнете этого?
- Что останется прежним, если вы не достигнете своей цели?
- Какие показатели, параметры или другие данные необходимы для отслеживания вашего прогресса?
- Как узнать, находитесь ли вы на правильном пути, а когда отклонились от него?
Будьте ясны, кратки и конкретны. Расплывчатые определения, такие как счастливая семья, успешная карьера, финансовая безопасность, только заставят вас чувствовать себя застрявшим, несчастным и неудовлетворенным.
2. Последовательность в действиях
Нужно работать над своим планом каждый день, даже когда тяжело и не хочется. Последовательность превращает небольшие ежедневные достижения в большие результаты.
Вот несколько важных практик, которые помогут достичь ежедневных целей:
- Разбейте цель на небольшие задачи. Маленькие шаги отключают систему сигнализации мозга, которая сопротивляется переменам и боится их.
- Работая над задачей, используйте «помидорный график».
- Запланируйте самые важные задачи на пик вашей умственной энергии.
- В конце каждого дня выделяйте 15–20 минут, чтобы поразмышлять о прогрессе и определить, как его можно улучшить.
3. Реакция на неожиданные события или результаты
Неожиданности, изменение обстоятельств или отсутствие желаемых результатов, несмотря на все усилия, могут выбить вас из колеи. Дела будут трудными. Возникнут новые проблемы. Вместо того, чтобы сдаваться, вы должны научиться отряхиваться, вставать и продолжать двигаться вперёд.
Разрешите себе чувствовать разочарование, но не позволяйте временным неудачам превратиться в постоянные оправдания.
При столкновении с препятствием:
- Попробуйте другую стратегию.
- Поэкспериментируйте с несколькими вариантами, чтобы определить тот, который работает.
- Изучите новые способы ведения дел.
- Развивайтесь всесторонне, чтобы получать идеи из других областей знаний.
Когда вы продолжаете искать способы изменить ситуацию к лучшему, у вас есть шанс их найти. Когда вы прекращаете поиск, предполагая, что их невозможно найти, вы признаёте поражение.
Окончание следует…
Источник: https://betterprogramming.pub/6-factors-that-determine-whether-you-will-succeed-or-fail-ae1dfe446e2b
6 Факторов, Определяющих Победите Вы или Провалитесь. Начало
Во всех наших начинаниях успех – это желаемое конечное состояние. Он приносит воодушевление, радость и гордость. А неудача разочаровывает и может даже лишить некоторых мотивации пытаться достичь своих целей. Не существует единого ключа к успеху, т.к. он часто является сочетанием множества различных факторов: не только ваших усилий, но и обстоятельств, опыта и удачи.
Вот 6 факторов, которые не гарантируют успеха, но определённо помогут изменить баланс в вашу пользу.
1. Ясность критериев успеха
Если иметь лишь смутное представление о том, что для вас значит успех, может быть сложно определить, достигли ли вы своей цели. Достижение успеха начинается с определения того, что он для вас значит: что для вас важно, чего вы хотите достичь, почему это важно, как вы можете это измерить?
Определите успех, ответив на следующие вопросы:
- Как выглядит успех?
- Что изменится, когда вы достигнете этого?
- Что останется прежним, если вы не достигнете своей цели?
- Какие показатели, параметры или другие данные необходимы для отслеживания вашего прогресса?
- Как узнать, находитесь ли вы на правильном пути, а когда отклонились от него?
Будьте ясны, кратки и конкретны. Расплывчатые определения, такие как счастливая семья, успешная карьера, финансовая безопасность, только заставят вас чувствовать себя застрявшим, несчастным и неудовлетворенным.
2. Последовательность в действиях
Нужно работать над своим планом каждый день, даже когда тяжело и не хочется. Последовательность превращает небольшие ежедневные достижения в большие результаты.
Вот несколько важных практик, которые помогут достичь ежедневных целей:
- Разбейте цель на небольшие задачи. Маленькие шаги отключают систему сигнализации мозга, которая сопротивляется переменам и боится их.
- Работая над задачей, используйте «помидорный график».
- Запланируйте самые важные задачи на пик вашей умственной энергии.
- В конце каждого дня выделяйте 15–20 минут, чтобы поразмышлять о прогрессе и определить, как его можно улучшить.
3. Реакция на неожиданные события или результаты
Неожиданности, изменение обстоятельств или отсутствие желаемых результатов, несмотря на все усилия, могут выбить вас из колеи. Дела будут трудными. Возникнут новые проблемы. Вместо того, чтобы сдаваться, вы должны научиться отряхиваться, вставать и продолжать двигаться вперёд.
Разрешите себе чувствовать разочарование, но не позволяйте временным неудачам превратиться в постоянные оправдания.
При столкновении с препятствием:
- Попробуйте другую стратегию.
- Поэкспериментируйте с несколькими вариантами, чтобы определить тот, который работает.
- Изучите новые способы ведения дел.
- Развивайтесь всесторонне, чтобы получать идеи из других областей знаний.
Когда вы продолжаете искать способы изменить ситуацию к лучшему, у вас есть шанс их найти. Когда вы прекращаете поиск, предполагая, что их невозможно найти, вы признаёте поражение.
Окончание следует…
Источник: https://betterprogramming.pub/6-factors-that-determine-whether-you-will-succeed-or-fail-ae1dfe446e2b
👍9
День 1823. #Карьера
6 Факторов, Определяющих Победите Вы или Провалитесь. Окончание
Начало
4. История, которую вы рассказываете себе
Ваш разум — это машина, создающая смыслы. Ему нравится объяснять вещи, придумывая истории, которые соответствуют вашим убеждениям и ожиданиям.
Когда вы чего-то достигаете, учитываете ли вы роль внутренних факторов, таких как ваши усилия, навыки и упорство, которые способствовали этому успеху, или вы игнорируете свои достижения, приписывая их внешним факторам, таким как удача, другие люди или стечение обстоятельств? Аналогично, когда вы терпите неудачу, как вы реагируете? Берёте ли вы на себя ответственность и анализируете своё поведение или обвиняете внешние обстоятельства или других людей?
Ваши убеждения об успехе и неудаче существенно влияют на восприятие, чувства и, в итоге, на то, как вы действуете. Когда вы не осознаёте свои сильные стороны, которые сделали успех возможным, или чувствуете себя неспособным противостоять неудачам, даже когда всё находится вне вашего контроля, ваши самоограничивающие убеждения мешают вашему росту.
Чтобы оставаться в контакте с реальностью:
- Определите вещи, которые находятся под вашим контролем, и те, которые находятся за его пределами.
- Расширьте круг своего влияния, работая над вещами, находящимися под вашим контролем.
- Перестаньте тратить время и энергию на вещи, находящиеся вне вашего контроля.
5. Возможность отделить сигнал от шума
Работая над целью, вы обязательно получите много обратной связи. Однако большая её часть — это шум: она не помогает достичь чего-то значительного или отвлекает вас от целей. Но среди шума скрывается тот редкий совет, мудрость или знание, которые помогут двигаться вперёд и приблизиться к цели.
Чтобы добиться успеха, нужно понять, что другие могут поделиться ценной обратной связью и научиться конструктивно воспринимать критику:
- Не принимайте обратную связь на личный счёт и не привязывайте её к своей ценности и значимости.
- Не отказывайтесь признавать пробелы в своих знаниях.
- Не относитесь к другим как к неполноценным и не отказывайтесь доверять их суждениям.
- Не позволяйте своему эго мешать.
Критика может быть неприятна, но она необходима. Она выполняет ту же функцию, что и боль - привлекает внимание к проблеме.
6. Получение нужной помощи в нужное время
У всех успешных людей есть одна общая черта: они не уклоняются от обращения за помощью, когда она им нужна. Не обращение за помощью, когда она вам нужна, не только мешает вам получить идеи и советы для продвижения вперёд, но и является глупой ошибкой. Никто не будет смотреть на вас свысока, если вы попросите о помощи. Никто не будет подвергать сомнению ваши способности. Это показывает, что вы верите, что ответ существует, и готовы сделать всё возможное, чтобы получить его.
Когда обращаетесь за помощью:
- Прямо попросите о помощи. Не думайте, что другие могут читать ваши мысли.
- Излагайте проблему конкретно и чётко.
Относитесь к своей уязвимости как к силе, и вы удивитесь, увидев, как много людей готовы вам помочь.
Источник: https://betterprogramming.pub/6-factors-that-determine-whether-you-will-succeed-or-fail-ae1dfe446e2b
6 Факторов, Определяющих Победите Вы или Провалитесь. Окончание
Начало
4. История, которую вы рассказываете себе
Ваш разум — это машина, создающая смыслы. Ему нравится объяснять вещи, придумывая истории, которые соответствуют вашим убеждениям и ожиданиям.
Когда вы чего-то достигаете, учитываете ли вы роль внутренних факторов, таких как ваши усилия, навыки и упорство, которые способствовали этому успеху, или вы игнорируете свои достижения, приписывая их внешним факторам, таким как удача, другие люди или стечение обстоятельств? Аналогично, когда вы терпите неудачу, как вы реагируете? Берёте ли вы на себя ответственность и анализируете своё поведение или обвиняете внешние обстоятельства или других людей?
Ваши убеждения об успехе и неудаче существенно влияют на восприятие, чувства и, в итоге, на то, как вы действуете. Когда вы не осознаёте свои сильные стороны, которые сделали успех возможным, или чувствуете себя неспособным противостоять неудачам, даже когда всё находится вне вашего контроля, ваши самоограничивающие убеждения мешают вашему росту.
Чтобы оставаться в контакте с реальностью:
- Определите вещи, которые находятся под вашим контролем, и те, которые находятся за его пределами.
- Расширьте круг своего влияния, работая над вещами, находящимися под вашим контролем.
- Перестаньте тратить время и энергию на вещи, находящиеся вне вашего контроля.
5. Возможность отделить сигнал от шума
Работая над целью, вы обязательно получите много обратной связи. Однако большая её часть — это шум: она не помогает достичь чего-то значительного или отвлекает вас от целей. Но среди шума скрывается тот редкий совет, мудрость или знание, которые помогут двигаться вперёд и приблизиться к цели.
Чтобы добиться успеха, нужно понять, что другие могут поделиться ценной обратной связью и научиться конструктивно воспринимать критику:
- Не принимайте обратную связь на личный счёт и не привязывайте её к своей ценности и значимости.
- Не отказывайтесь признавать пробелы в своих знаниях.
- Не относитесь к другим как к неполноценным и не отказывайтесь доверять их суждениям.
- Не позволяйте своему эго мешать.
Критика может быть неприятна, но она необходима. Она выполняет ту же функцию, что и боль - привлекает внимание к проблеме.
6. Получение нужной помощи в нужное время
У всех успешных людей есть одна общая черта: они не уклоняются от обращения за помощью, когда она им нужна. Не обращение за помощью, когда она вам нужна, не только мешает вам получить идеи и советы для продвижения вперёд, но и является глупой ошибкой. Никто не будет смотреть на вас свысока, если вы попросите о помощи. Никто не будет подвергать сомнению ваши способности. Это показывает, что вы верите, что ответ существует, и готовы сделать всё возможное, чтобы получить его.
Когда обращаетесь за помощью:
- Прямо попросите о помощи. Не думайте, что другие могут читать ваши мысли.
- Излагайте проблему конкретно и чётко.
Относитесь к своей уязвимости как к силе, и вы удивитесь, увидев, как много людей готовы вам помочь.
Источник: https://betterprogramming.pub/6-factors-that-determine-whether-you-will-succeed-or-fail-ae1dfe446e2b
👍8
День 1824. #ЧтоНовенького
MSTest Runner
Microsoft представили MSTest Runner, небольшую утилиту для запуска тестов под MSTest. Основная цель — повысить переносимость, надёжность и скорость, одновременно предоставляя пользователям расширяемые возможности тестирования.
MSTest Runner представлен как независимый переносимый исполняемый файл с упором на устранение необходимости во внешних инструментах, таких как vstest.console, dotnet test или Visual Studio, для выполнения тестов. Команда разработчиков считает, что он подходит для разработки тестов на устройствах с ограниченной мощностью или объёмом памяти, предлагая упрощённое решение для тестирования.
MSTest Runner поставляется в комплекте с NuGet-пакетом MSTest.TestAdapter, начиная с версии 3.2.0.
По сравнению с VSTest, MSTest Runner предлагает несколько преимуществ:
1) Портативность
Упрощает выполнение тестов, запуская тесты непосредственно из исполняемого файла, устраняя сложности, связанные с традиционной инфраструктурой тестирования. С помощью MSTest Runner проекты рассматриваются как обычные объекты, что позволяет разработчикам использовать существующие инструменты dotnet и запускать тесты на разных компьютерах без дополнительной настройки.
Сообщается, что существует план добиться поддержки NativeAOT. Кроме того, на GitHub представлен пример запуска тестов для приложения dotnet, размещённого в Docker, где нет полноценного .NET SDK.
2) Производительность
MSTest Runner оптимизирует использование ресурсов на серверах сборки, по сравнению с dotnet test. Как заявила команда разработчиков, во внутренних проектах Microsoft, внедривших MSTest Runner, наблюдалась существенная экономия в использовании ЦП и памяти, при этом некоторые проекты завершали тесты в три раза быстрее, используя при этом в четыре раза меньше памяти по сравнению с dotnet test.
Также MSTest Runner вводит новые настройки по умолчанию, отдающие приоритет безопасности и снижающие вероятность случайного пропуска выполнения теста. Кроме того, благодаря своей архитектуре без сканирования папок, динамической загрузки или рефлексии для обнаружения расширений гарантирует согласованное поведение как в локальной среде, так и в среде CI. А асинхронная природа утилиты сводит к минимуму зависания и взаимоблокировки, устраняя распространённые проблемы, наблюдаемые при использовании VSTest.
3) Расширяемость
MSTest Runner предлагает гибкую модель, позволяющую пользователям расширять или переопределять различные аспекты выполнения тестов. Эта модель поддерживает генераторы пользовательских отчётов, оркестрацию тестов, средства ведения журнала и дополнительные параметры командной строки. Microsoft предоставляет список расширений с обещанием постоянно его дополнять.
Хотя в настоящее время утилита поддерживает только MSTest, она была намеренно построена с учётом независимости от платформы. Было принято решение сосредоточиться на MSTest, который обеспечивает большую гибкость, простоту обратной совместимости, а также более быструю и уверенную реализацию изменений благодаря знакомству команды с кодовой базой MSTest. Разработчикам предлагается проголосовать и оставить свои пожелания относительно других платформ тестирования.
Источник: https://www.infoq.com/news/2024/01/introducing-new-ms-test-runner/
MSTest Runner
Microsoft представили MSTest Runner, небольшую утилиту для запуска тестов под MSTest. Основная цель — повысить переносимость, надёжность и скорость, одновременно предоставляя пользователям расширяемые возможности тестирования.
MSTest Runner представлен как независимый переносимый исполняемый файл с упором на устранение необходимости во внешних инструментах, таких как vstest.console, dotnet test или Visual Studio, для выполнения тестов. Команда разработчиков считает, что он подходит для разработки тестов на устройствах с ограниченной мощностью или объёмом памяти, предлагая упрощённое решение для тестирования.
MSTest Runner поставляется в комплекте с NuGet-пакетом MSTest.TestAdapter, начиная с версии 3.2.0.
По сравнению с VSTest, MSTest Runner предлагает несколько преимуществ:
1) Портативность
Упрощает выполнение тестов, запуская тесты непосредственно из исполняемого файла, устраняя сложности, связанные с традиционной инфраструктурой тестирования. С помощью MSTest Runner проекты рассматриваются как обычные объекты, что позволяет разработчикам использовать существующие инструменты dotnet и запускать тесты на разных компьютерах без дополнительной настройки.
Сообщается, что существует план добиться поддержки NativeAOT. Кроме того, на GitHub представлен пример запуска тестов для приложения dotnet, размещённого в Docker, где нет полноценного .NET SDK.
2) Производительность
MSTest Runner оптимизирует использование ресурсов на серверах сборки, по сравнению с dotnet test. Как заявила команда разработчиков, во внутренних проектах Microsoft, внедривших MSTest Runner, наблюдалась существенная экономия в использовании ЦП и памяти, при этом некоторые проекты завершали тесты в три раза быстрее, используя при этом в четыре раза меньше памяти по сравнению с dotnet test.
Также MSTest Runner вводит новые настройки по умолчанию, отдающие приоритет безопасности и снижающие вероятность случайного пропуска выполнения теста. Кроме того, благодаря своей архитектуре без сканирования папок, динамической загрузки или рефлексии для обнаружения расширений гарантирует согласованное поведение как в локальной среде, так и в среде CI. А асинхронная природа утилиты сводит к минимуму зависания и взаимоблокировки, устраняя распространённые проблемы, наблюдаемые при использовании VSTest.
3) Расширяемость
MSTest Runner предлагает гибкую модель, позволяющую пользователям расширять или переопределять различные аспекты выполнения тестов. Эта модель поддерживает генераторы пользовательских отчётов, оркестрацию тестов, средства ведения журнала и дополнительные параметры командной строки. Microsoft предоставляет список расширений с обещанием постоянно его дополнять.
Хотя в настоящее время утилита поддерживает только MSTest, она была намеренно построена с учётом независимости от платформы. Было принято решение сосредоточиться на MSTest, который обеспечивает большую гибкость, простоту обратной совместимости, а также более быструю и уверенную реализацию изменений благодаря знакомству команды с кодовой базой MSTest. Разработчикам предлагается проголосовать и оставить свои пожелания относительно других платформ тестирования.
Источник: https://www.infoq.com/news/2024/01/introducing-new-ms-test-runner/
👍8👎3
День 1825. #ЗаметкиНаПолях
Короткие URL в .NET. Начало
Короткие URL - простой, но мощный инструмент, преобразующий длинные URL в более удобные и короткие. Два популярных инструмента сокращения URL-адресов — Bitly и TinyURL. Посмотрим, как создать его самому.
Нам нужны 2 конечные точки:
- Генерирующая уникальный кода для данного URL,
- Перенаправляющая с короткой ссылки, на исходный URL.
URL будут храниться в БД.
Длина кода и набор символов определяют, сколько коротких URL может сгенерировать система. Для генерации будем использовать Random, т.к. его легко реализовать, и он имеет приемлемо низкий уровень коллизий.
Модель данных
ShortUrl представляет URL, хранящиеся в нашей системе:
Класс включает исходный URL (Url) и уникальный код (Code), представляющий сокращённый URL. Id и CreatedOn используются для БД и отслеживания.
В AppDbContext настроим сущность и контекст БД:
- Максимальную длину кода,
- Уникальный индекс на столбце Code, чтобы в БД не было повторяющихся значений кода.
- Также некоторые БД обрабатывают строки без учета регистра. Это значительно уменьшает количество доступных коротких URL. Нужно настроить БД для обработки уникального кода с учетом регистра:
Генерация уникального кода
Есть несколько алгоритмов реализации. Мы хотим равномерного распределения уникальных кодов по всем возможным значениям. Это поможет уменьшить коллизии. Здесь рассмотрим генератор случайного кода с предопределённым алфавитом. Его просто реализовать, и вероятность коллизий относительно невелика. ShortLinkSettings содержит две константы - длину кода и алфавит:
В алфавите 62 символа, что даёт больше 3х триллионов(!!!) уникальных комбинаций.
UrlShorteningService генерирует уникальные коды. Мы выбираем случайные символы из алфавита до достижения длины, а затем проверяем, нет ли уже такого кода в БД. Если нет, возвращаем его, если есть, повторяем процесс:
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/how-to-build-a-url-shortener-with-dotnet
Короткие URL в .NET. Начало
Короткие URL - простой, но мощный инструмент, преобразующий длинные URL в более удобные и короткие. Два популярных инструмента сокращения URL-адресов — Bitly и TinyURL. Посмотрим, как создать его самому.
Нам нужны 2 конечные точки:
- Генерирующая уникальный кода для данного URL,
- Перенаправляющая с короткой ссылки, на исходный URL.
URL будут храниться в БД.
Длина кода и набор символов определяют, сколько коротких URL может сгенерировать система. Для генерации будем использовать Random, т.к. его легко реализовать, и он имеет приемлемо низкий уровень коллизий.
Модель данных
ShortUrl представляет URL, хранящиеся в нашей системе:
public class ShortUrl
{
public Guid Id { get; set; }
public string Url { get; set; }
public string Code { get; set; }
public DateTime CreatedOn { get; set; }
}
Класс включает исходный URL (Url) и уникальный код (Code), представляющий сокращённый URL. Id и CreatedOn используются для БД и отслеживания.
В AppDbContext настроим сущность и контекст БД:
- Максимальную длину кода,
- Уникальный индекс на столбце Code, чтобы в БД не было повторяющихся значений кода.
- Также некоторые БД обрабатывают строки без учета регистра. Это значительно уменьшает количество доступных коротких URL. Нужно настроить БД для обработки уникального кода с учетом регистра:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions opts)
: base(options)
{ }
public DbSet<ShortUrl> ShortUrls { get; set; }
protected override void
OnModelCreating(ModelBuilder mb)
{
mb.Entity<ShortUrl>(b =>
{
b.Property(u => u.Code)
.HasMaxLength(ShortLinkSettings.Length);
b.HasIndex(u => u.Code)
.IsUnique();
});
}
}
Генерация уникального кода
Есть несколько алгоритмов реализации. Мы хотим равномерного распределения уникальных кодов по всем возможным значениям. Это поможет уменьшить коллизии. Здесь рассмотрим генератор случайного кода с предопределённым алфавитом. Его просто реализовать, и вероятность коллизий относительно невелика. ShortLinkSettings содержит две константы - длину кода и алфавит:
public static class ShortLinkSettings
{
public const int Length = 7;
public const string Alphabet =
"ABCDEF…xyz01…89";
}
В алфавите 62 символа, что даёт больше 3х триллионов(!!!) уникальных комбинаций.
UrlShorteningService генерирует уникальные коды. Мы выбираем случайные символы из алфавита до достижения длины, а затем проверяем, нет ли уже такого кода в БД. Если нет, возвращаем его, если есть, повторяем процесс:
public class UrlShorteningService(AppDbContext ctx)
{
private Random _rnd = new();
public async Task<string> GetCode()
{
const len = ShortLinkSettings.Length;
var chars = new char[len];
const int maxVal =
ShortLinkSettings.Alphabet.Length;
while (true)
{
for (var i = 0; i < len; i++)
{
var idx = _rnd.Next(maxVal);
chars[i] =
ShortLinkSettings.Alphabet[idx];
}
var code = new string(chars);
if (!await ctx.ShortUrls.AnyAsync(
s => s.Code == code))
return code;
}
}
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/how-to-build-a-url-shortener-with-dotnet
👍16
День 1826. #ЗаметкиНаПолях
Короткие URL в .NET. Окончание
Начало
Теперь создадим конечные точки для минимального API.
Первая принимает URL, создаёт короткий URL и возвращает его:
Здесь возникает небольшая ситуация гонки, поскольку мы сначала генерируем уникальный код, а затем вставляем его в БД. Параллельный запрос может сгенерировать тот же уникальный код и вставить его в БД до того, как мы завершим транзакцию. Однако вероятность того, что это произойдет, невелика, кроме того, уникальный ключ в БД защищает нас от дублирования значений.
Вторая конечная точка перенаправит на исходный URL при доступе к сокращённому:
Эта конечная точка ищет код в БД и, если он найден, перенаправляет пользователя на исходный длинный URL. Ответ будет иметь код состояния 302 (Found) согласно стандартам HTTP.
Недостатки и улучшения
1. Недостатком реализации сервиса является длинная задержка, т.к. мы проверяем каждый генерируемый код в БД. Улучшением может стать заблаговременное создание уникальных кодов в БД.
2. Кэширование второй конечной точки позволит снизить нагрузку на БД для часто используемых коротких URL.
Источник: https://www.milanjovanovic.tech/blog/how-to-build-a-url-shortener-with-dotnet
Короткие URL в .NET. Окончание
Начало
Теперь создадим конечные точки для минимального API.
Первая принимает URL, создаёт короткий URL и возвращает его:
app.MapPost("shorten", async (
string url,
UrlShorteningService svc,
AppDbContext dbCtx,
HttpContext httpCtx) =>
{
if (!Uri.TryCreate(url, UriKind.Absolute, out _))
return Results.BadRequest(
"Предоставленный URL неверный.");
var code = await svc.GetCode();
var req = httpCtx.Request;
var shortUrl = new ShortUrl
{
Id = Guid.NewGuid(),
Url = url,
Code = code,
CreatedOn = DateTime.UtcNow
};
dbCtx.ShortenedUrls.Add(shortUrl);
await dbCtx.SaveChangesAsync();
return Results.Ok(
$"{req.Scheme}://{req.Host}/{code}");
});
Здесь возникает небольшая ситуация гонки, поскольку мы сначала генерируем уникальный код, а затем вставляем его в БД. Параллельный запрос может сгенерировать тот же уникальный код и вставить его в БД до того, как мы завершим транзакцию. Однако вероятность того, что это произойдет, невелика, кроме того, уникальный ключ в БД защищает нас от дублирования значений.
Вторая конечная точка перенаправит на исходный URL при доступе к сокращённому:
csharp
app.MapGet("{code}",
async (
string code,
AppDbContext dbCtx) =>
{
var shortUrl = await
dbCtx.ShortUrls
.SingleOrDefaultAsync(
s => s.Code == code);
if (shortUrl is null)
return Results.NotFound();
return Results.Redirect(shortUrl.Url);
});
Эта конечная точка ищет код в БД и, если он найден, перенаправляет пользователя на исходный длинный URL. Ответ будет иметь код состояния 302 (Found) согласно стандартам HTTP.
Недостатки и улучшения
1. Недостатком реализации сервиса является длинная задержка, т.к. мы проверяем каждый генерируемый код в БД. Улучшением может стать заблаговременное создание уникальных кодов в БД.
2. Кэширование второй конечной точки позволит снизить нагрузку на БД для часто используемых коротких URL.
Источник: https://www.milanjovanovic.tech/blog/how-to-build-a-url-shortener-with-dotnet
👍7
День 1827.
Нам 5 лет!
А вас почти 4000. Спасибо, что читаете, лайкаете и комментируете.
Для тех, кто пришёл недавно, вот здесь подборка тематических тегов. Либо вы просто можете поискать по сообщениям в канале то, что вам нужно.
Также добро пожаловать в наш чат, где собралась неплохая компания, и где вам всегда постараются помочь.
Ещё раз спасибо, что читаете, а те, кто кроме этого хочет поддержать, добро пожаловать в Boosty или Patreon.
Нам 5 лет!
А вас почти 4000. Спасибо, что читаете, лайкаете и комментируете.
Для тех, кто пришёл недавно, вот здесь подборка тематических тегов. Либо вы просто можете поискать по сообщениям в канале то, что вам нужно.
Также добро пожаловать в наш чат, где собралась неплохая компания, и где вам всегда постараются помочь.
Ещё раз спасибо, что читаете, а те, кто кроме этого хочет поддержать, добро пожаловать в Boosty или Patreon.
👍84👎1
.NET Разработчик pinned «День 1827. Нам 5 лет! А вас почти 4000. Спасибо, что читаете, лайкаете и комментируете. Для тех, кто пришёл недавно, вот здесь подборка тематических тегов. Либо вы просто можете поискать по сообщениям в канале то, что вам нужно. Также добро пожаловать в…»
День 1828. #ЧтоНовенького
Новые Функции Расширения Visual Studio GitHub Copilot
В последнем выпуске расширения Visual Studio GitHub Copilot Chat представлены две примечательные функции повышения производительности: команды с косой чертой и контекстные переменные. Кроме того, разработчики могут изучить несколько функций в превью-версии, такие как Помощник по исключениям, Анализ сбоев тестов, Рекомендации для выражений точек останова, Рекомендации по сообщениям коммита и многие другие.
Первым заметным дополнением является добавление команд с косой чертой, представляющих собой набор специализированных директив, которые разработчики могут использовать в интерфейсе чата для запуска определённых действий, связанных с кодом. Введено несколько команд:
-
-
-
-
-
-
-
Другая примечательная новинка - функция контекстных переменных, которая позволяет разработчикам легко включать в вопросы файлы из решения, используя символ
Также доступно несколько экспериментальных функций в превью-версии.
- Ассистент по исключениям в отладчике автоматически добавит ссылку Ask Copilot (Спросить Copilot) в окно сообщения об ошибке при отладке.
- Solution Reference (Справочник решения), позволяющий пользователям находить ссылки на элементы кода в решении и перемещаться по ним. При использовании директивы
- Предложения в профилировщике производительности проанализируют данные о производительности, собранные профилировщиком производительности Visual Studio, и покажут рекомендации по оптимизации скорости кода, использования памяти и скорости ответа.
- Анализ сбоев тестов поможет отлаживать и исправлять сбои модульных тестов. Copilot предоставит вам полезную информацию о сбое теста, такую как сообщение с утверждения, ожидаемые и фактические значения, исходный код и возможные решения.
Отзывы сообщества о Visual Studio Copilot Chat в целом положительные: пользователи хвалят такие функции, как
Некоторые пользователи сравнивают Copilot с другими инструментами, подчёркивая его ценность как встроенного инструмента, но отдавая предпочтение инструментам с расширенными функциями. В целом отзывы сообщества подчеркивают как высокую оценку существующих функций, так и стремление к постоянному совершенствованию инструмента.
Для использования Visual Studio Copilot Chat нужно использовать Visual Studio 2022 версии 17.8 или выше. Кроме того, необходимо убедиться, что учётная запись GitHub, с которой выполнен вход в Visual Studio, связана с активной подпиской GitHub Copilot.
Источник: https://www.infoq.com/news/2024/01/vs-github-copilot-new-features/
Новые Функции Расширения Visual Studio GitHub Copilot
В последнем выпуске расширения Visual Studio GitHub Copilot Chat представлены две примечательные функции повышения производительности: команды с косой чертой и контекстные переменные. Кроме того, разработчики могут изучить несколько функций в превью-версии, такие как Помощник по исключениям, Анализ сбоев тестов, Рекомендации для выражений точек останова, Рекомендации по сообщениям коммита и многие другие.
Первым заметным дополнением является добавление команд с косой чертой, представляющих собой набор специализированных директив, которые разработчики могут использовать в интерфейсе чата для запуска определённых действий, связанных с кодом. Введено несколько команд:
-
/doc
добавит документацию в код.-
/explain
даст подробное объяснение кода, -
/fix
предложит решения выявленных проблем в выбранном коде,-
/generate
запустит Copilot для создания кода по запросу,-
/help
откроет помощь в Copilot Chat,-
/optimize
проанализирует и улучшит время выполнения выбранного кода,-
/tests
создаст модульные тесты для выбранного кода.Другая примечательная новинка - функция контекстных переменных, которая позволяет разработчикам легко включать в вопросы файлы из решения, используя символ
#
. Это позволяет Copilot получать доступ к содержимому файлов, на которые имеются ссылки, и предоставлять более целенаправленные ответы. Например, разработчики могут задать вопрос о функциональности определённого файла, например #Main.cs
, и получить соответствующую информацию в чате Copilot. Обратите внимание, что в один вопрос можно включить несколько файлов. В ответах будут видны ссылки на добавленные файлы. Нажатие на эти ссылки перенаправит пользователей к их содержимому, предлагая удобный способ навигации и понимания файлов, на которые имеются ссылки.Также доступно несколько экспериментальных функций в превью-версии.
- Ассистент по исключениям в отладчике автоматически добавит ссылку Ask Copilot (Спросить Copilot) в окно сообщения об ошибке при отладке.
- Solution Reference (Справочник решения), позволяющий пользователям находить ссылки на элементы кода в решении и перемещаться по ним. При использовании директивы
#solution
, вы дадите Copilot команду добавить код решения в контекст вопроса и предложить более точное решение. - Предложения в профилировщике производительности проанализируют данные о производительности, собранные профилировщиком производительности Visual Studio, и покажут рекомендации по оптимизации скорости кода, использования памяти и скорости ответа.
- Анализ сбоев тестов поможет отлаживать и исправлять сбои модульных тестов. Copilot предоставит вам полезную информацию о сбое теста, такую как сообщение с утверждения, ожидаемые и фактические значения, исходный код и возможные решения.
Отзывы сообщества о Visual Studio Copilot Chat в целом положительные: пользователи хвалят такие функции, как
#solution
. Однако есть и проблемы с некоторыми командами с косой чертой, такими как /doc
для больших блоков кода, а также слишком общий характер описаний в /explain
. Пользователи предлагают варианты настройки, такие как выбор языка для сообщений коммита. Есть также предложения относительно будущих улучшений, таких как возможности мониторинга и выражения эмоций.Некоторые пользователи сравнивают Copilot с другими инструментами, подчёркивая его ценность как встроенного инструмента, но отдавая предпочтение инструментам с расширенными функциями. В целом отзывы сообщества подчеркивают как высокую оценку существующих функций, так и стремление к постоянному совершенствованию инструмента.
Для использования Visual Studio Copilot Chat нужно использовать Visual Studio 2022 версии 17.8 или выше. Кроме того, необходимо убедиться, что учётная запись GitHub, с которой выполнен вход в Visual Studio, связана с активной подпиской GitHub Copilot.
Источник: https://www.infoq.com/news/2024/01/vs-github-copilot-new-features/
👍4👎2
День 1829. #Карьера
Когда Начальник Вас не Слушает
В идеале руководитель должен вдохновлять и поддерживать вас, назначать вам проекты и направлять вас к росту и устранять любые препятствия. Обычно не всё так гладко. Многие сотрудники жалуются, что их менеджеры «просто не слушают»: от явного игнорирования при предоставлении обратной связи до упущения продвижения по службе. Рассмотрим как мы можем каждый раз достигать наилучшего результата в разных сценариях.
1. Начальник не слушает отзывы
Возможно, будет полезно обсудить проблему с остальной командой. Это типично для всех или направлено конкретно против вас? Убедитесь, что ваш руководитель понимает ваши отзывы, сделав их прямыми, конкретными и своевременными. Изучите, как вы выражаете эту обратную связь, поскольку ваши стили общения могут противоречить. Во время встреч обращайте внимание на то, как с ним разговаривают другие люди, и поймите, какой стиль общения привлекает внимание вашего начальника.
2. Начальник игнорирует мои идеи
Упорно работать над чем-то может показаться деморализующим, если начальство игнорирует ваш вклад и выбирает совершенно другое направление.
В таких случаях может помочь переоценка вашей презентации. Постарайтесь найти наиболее важную часть вашей идеи и договориться о ней, вместо того чтобы настаивать на полном пакете.
Сосредоточьтесь на чём-то, что принесет ощутимые результаты для бизнеса либо напрямую (за счет зарабатывания денег), либо косвенно (например, за счет снижения затрат или повышения эффективности). Если возможно, создайте доказательство концепции и измерьте результат. Представьте эти результаты руководителю.
3. Начальник не помогает с проблемами по работе
Всего 23% сотрудников сообщают, что их руководитель всегда конструктивно реагирует, когда они делятся своими рабочими проблемами, а 17% утверждают, что их руководитель вообще им не помогает.
Постарайтесь разобраться в проблеме. Может у него много дел, и нет времени вам помочь. Тогда предложите свою помощь в каких-то вопросах.
Ещё одна причина, может быть в том, что начальник хочет, чтобы вы сами нашли решение и получили опыт. Если вы исчерпали все возможные варианты и не знаете, как двигаться дальше, важно подчеркнуть это.
4. Начальник игнорирует мой запрос на повышение
Во-первых, вы просили или просто намекнули об этом? Если явно просили, попробуйте узнать, это осознанное и окончательное решение, проблема с бюджетом или местом в текущей команде? Если не хватает бюджета, спросите, есть ли график продвижений и что нужно сделать, чтобы получить повышение, и когда на него рассчитывать?
Поднимите проблему
Не уклоняйтесь от обсуждения проблем и не позволяйте проблеме накапливаться. Относитесь к этому так же, как к любой обратной связи; давайте её своевременно и привяжите к конкретным фактам. Какое именно поведение начальства заставило вас почувствовать, что вас игнорируют? Соблазнительно начать жаловаться, но полезнее переключиться в режим решения проблем. Подумайте, как вы можете быть наиболее полезны для бизнеса.
Говорить ли с начальством начальства?
Иногда может возникнуть соблазн переступить через голову. Прежде чем делать это, учтите последствия. Это необратимо повлияет на ваши отношения. Даже если вы добьётесь своего, после этого вашему руководителю будет трудно вам доверять. В некоторых компаниях начальник вашего руководителя наотрез откажется с вами разговаривать, вам могут сделать выговор или даже уволить. Это можно делать, только если произойдёт что-то неэтичное или незаконное.
Итого
Вы не можете «исправить» людей. Ожидать, что другие будут соответствовать вашему представлению о «хорошем поведении», бессмысленно. Для достижения карьерных целей нужно поддерживать продуктивные отношения со своим руководителем. Однако не следует перенапрягаться, если видите, что это не работает. Вместо этого сосредоточьтесь на своей цели, продуктивности и вкладе в организацию и подумайте о том, чтобы подать заявку на работу в другой команде.
Источник: https://betterprogramming.pub/when-your-manager-does-not-listen-55875a35c974
Когда Начальник Вас не Слушает
В идеале руководитель должен вдохновлять и поддерживать вас, назначать вам проекты и направлять вас к росту и устранять любые препятствия. Обычно не всё так гладко. Многие сотрудники жалуются, что их менеджеры «просто не слушают»: от явного игнорирования при предоставлении обратной связи до упущения продвижения по службе. Рассмотрим как мы можем каждый раз достигать наилучшего результата в разных сценариях.
1. Начальник не слушает отзывы
Возможно, будет полезно обсудить проблему с остальной командой. Это типично для всех или направлено конкретно против вас? Убедитесь, что ваш руководитель понимает ваши отзывы, сделав их прямыми, конкретными и своевременными. Изучите, как вы выражаете эту обратную связь, поскольку ваши стили общения могут противоречить. Во время встреч обращайте внимание на то, как с ним разговаривают другие люди, и поймите, какой стиль общения привлекает внимание вашего начальника.
2. Начальник игнорирует мои идеи
Упорно работать над чем-то может показаться деморализующим, если начальство игнорирует ваш вклад и выбирает совершенно другое направление.
В таких случаях может помочь переоценка вашей презентации. Постарайтесь найти наиболее важную часть вашей идеи и договориться о ней, вместо того чтобы настаивать на полном пакете.
Сосредоточьтесь на чём-то, что принесет ощутимые результаты для бизнеса либо напрямую (за счет зарабатывания денег), либо косвенно (например, за счет снижения затрат или повышения эффективности). Если возможно, создайте доказательство концепции и измерьте результат. Представьте эти результаты руководителю.
3. Начальник не помогает с проблемами по работе
Всего 23% сотрудников сообщают, что их руководитель всегда конструктивно реагирует, когда они делятся своими рабочими проблемами, а 17% утверждают, что их руководитель вообще им не помогает.
Постарайтесь разобраться в проблеме. Может у него много дел, и нет времени вам помочь. Тогда предложите свою помощь в каких-то вопросах.
Ещё одна причина, может быть в том, что начальник хочет, чтобы вы сами нашли решение и получили опыт. Если вы исчерпали все возможные варианты и не знаете, как двигаться дальше, важно подчеркнуть это.
4. Начальник игнорирует мой запрос на повышение
Во-первых, вы просили или просто намекнули об этом? Если явно просили, попробуйте узнать, это осознанное и окончательное решение, проблема с бюджетом или местом в текущей команде? Если не хватает бюджета, спросите, есть ли график продвижений и что нужно сделать, чтобы получить повышение, и когда на него рассчитывать?
Поднимите проблему
Не уклоняйтесь от обсуждения проблем и не позволяйте проблеме накапливаться. Относитесь к этому так же, как к любой обратной связи; давайте её своевременно и привяжите к конкретным фактам. Какое именно поведение начальства заставило вас почувствовать, что вас игнорируют? Соблазнительно начать жаловаться, но полезнее переключиться в режим решения проблем. Подумайте, как вы можете быть наиболее полезны для бизнеса.
Говорить ли с начальством начальства?
Иногда может возникнуть соблазн переступить через голову. Прежде чем делать это, учтите последствия. Это необратимо повлияет на ваши отношения. Даже если вы добьётесь своего, после этого вашему руководителю будет трудно вам доверять. В некоторых компаниях начальник вашего руководителя наотрез откажется с вами разговаривать, вам могут сделать выговор или даже уволить. Это можно делать, только если произойдёт что-то неэтичное или незаконное.
Итого
Вы не можете «исправить» людей. Ожидать, что другие будут соответствовать вашему представлению о «хорошем поведении», бессмысленно. Для достижения карьерных целей нужно поддерживать продуктивные отношения со своим руководителем. Однако не следует перенапрягаться, если видите, что это не работает. Вместо этого сосредоточьтесь на своей цели, продуктивности и вкладе в организацию и подумайте о том, чтобы подать заявку на работу в другой команде.
Источник: https://betterprogramming.pub/when-your-manager-does-not-listen-55875a35c974
👍10👎2
День 1830. #ЗаметкиНаПолях
Проверяем, Пустая ли Коллекция в C#
В C# существуют разные способы проверить, пустая ли коллекция. В зависимости от типа коллекции вы можете проверить свойства Length, Count или IsEmpty. Также можно использовать метод расширения Enumerable.Any().
В C# 11, вы можете использовать сопоставление с образцом, чтобы позволить компилятору использовать лучший метод для проверки того, пуста ли коллекция. Не нужно запоминать правильное имя свойства, можно использовать оператор is:
Обратите внимание, что предыдущий код не совсем эквивалентен проверке свойства Length. Если экземпляру коллекции присвоить NULL, проверка свойства вызывает исключение NullReferenceException, а сопоставление с образцом вернёт false:
Проверить на null и пустую коллекцию, можно так:
Ту же логику можно использовать и для строк, хотя использование string.IsNullOrEmpty гораздо более распространено:
Источник: https://www.meziantou.net/checking-if-a-collection-is-empty-in-csharp.htm
Проверяем, Пустая ли Коллекция в C#
В C# существуют разные способы проверить, пустая ли коллекция. В зависимости от типа коллекции вы можете проверить свойства Length, Count или IsEmpty. Также можно использовать метод расширения Enumerable.Any().
// массив: Length
int[] array = ...;
var isEmpty = array.Length == 0;
// List: Count
List<int> list = ...;
var isEmpty = list.Count == 0;
// ImmutableArray<T>: IsEmpty
ImmutableArray<int> immArray = ...;
var isEmpty = immArray.IsEmpty;
// Span: IsEmpty
Span<int> span = ...;
var isEmpty = span.IsEmpty;
// метод расширения
List<int> list = ...;
var isEmpty = !list.Any();
В C# 11, вы можете использовать сопоставление с образцом, чтобы позволить компилятору использовать лучший метод для проверки того, пуста ли коллекция. Не нужно запоминать правильное имя свойства, можно использовать оператор is:
var collection = ...;
var isEmpty = collection is [];
Обратите внимание, что предыдущий код не совсем эквивалентен проверке свойства Length. Если экземпляру коллекции присвоить NULL, проверка свойства вызывает исключение NullReferenceException, а сопоставление с образцом вернёт false:
int[] array = null;
// NullReferenceException
var isEmpty = array.Length == 0;
// false
var isEmpty = array is [];
Проверить на null и пустую коллекцию, можно так:
var isNullOrEmpty = array is null or [];
Ту же логику можно использовать и для строк, хотя использование string.IsNullOrEmpty гораздо более распространено:
string str = "";
isEmpty = str is "";
isEmpty = str is [];
Источник: https://www.meziantou.net/checking-if-a-collection-is-empty-in-csharp.htm
👍37
День 1831. #ЧтоНовенького #CSharp13
Три новых метода LINQ в .NET 9
Продолжаем заглядывать в будущее .NET. Сегодня посмотрим, какие новые методы будут добавлены во всеми любимый LINQ.
CountBy
Многие функции LINQ имеют расширение By, в котором можно предоставить функцию выбора для группировки элементов. Например, MinBy, MaxBy, DistinctBy и т. д. Теперь у нас есть новый: CountBy. Он группирует элементы по функции селектора и возвращает перечисление KeyValuePairs. Ключ — это объект, а значение — количество элементов в группе.
Index
Не то, чтоб совсем новинка, это можно делать и сейчас, но с другим синтаксисом. Index возвращает элемент и его индекс в коллекции:
Сейчас такого можно добиться, используя перегрузку метода Select:
Интересно, что в методе Index решили поменять порядок индекса и элемента. Оказывается, это было осознанным решением команды дотнет: «Мы решили сначала возвращать индекс, а затем значение, потому что это кажется более естественным, несмотря на то, что существующий метод Select() сначала возвращает значение, а потом индекс.»
AggregateBy
Этот метод похож на CountBy, но вместо подсчёта элементов он их агрегирует. Вы можете предоставить начальное значение и функцию агрегирования. Функция получает текущее агрегированное значение и текущий элемент в качестве параметров и должна вернуть новое агрегированное значение.
Источник: https://steven-giesel.com/blogPost/0594ba85-356b-47f1-89a9-70e9761c582e/three-new-linq-methods-in-net-9
Три новых метода LINQ в .NET 9
Продолжаем заглядывать в будущее .NET. Сегодня посмотрим, какие новые методы будут добавлены во всеми любимый LINQ.
CountBy
Многие функции LINQ имеют расширение By, в котором можно предоставить функцию выбора для группировки элементов. Например, MinBy, MaxBy, DistinctBy и т. д. Теперь у нас есть новый: CountBy. Он группирует элементы по функции селектора и возвращает перечисление KeyValuePairs. Ключ — это объект, а значение — количество элементов в группе.
public record Person(string FirstName, string LastName);
List<Person> people =
[
new("Steve", "Jobs"),
new("Steve", "Carell"),
new("Elon", "Musk")
];
foreach (var p in people.CountBy(p => p.FirstName))
Console.WriteLine($"{p.Value} людей с именем {p.Key}");
Вывод:
2 людей с именем Steve
1 людей с именем Elon
Index
Не то, чтоб совсем новинка, это можно делать и сейчас, но с другим синтаксисом. Index возвращает элемент и его индекс в коллекции:
foreach (var (index, item) in people.Index())
Console.WriteLine($"№{index}: {item}");
Сейчас такого можно добиться, используя перегрузку метода Select:
foreach (var (item, index) in
people.Select((item, index) => (item, index)))
{
Console.WriteLine($"№{index}: {item}");
}
Интересно, что в методе Index решили поменять порядок индекса и элемента. Оказывается, это было осознанным решением команды дотнет: «Мы решили сначала возвращать индекс, а затем значение, потому что это кажется более естественным, несмотря на то, что существующий метод Select() сначала возвращает значение, а потом индекс.»
AggregateBy
Этот метод похож на CountBy, но вместо подсчёта элементов он их агрегирует. Вы можете предоставить начальное значение и функцию агрегирования. Функция получает текущее агрегированное значение и текущий элемент в качестве параметров и должна вернуть новое агрегированное значение.
public record Person(
string FirstName,
string Department,
int Salary);
List<Person> people =
[
new("Jobs", "Sales", 100),
new("Carell", "Sales", 120),
new("Musk", "IT", 290)
];
var aggregateBy = people.AggregateBy(
p => p.Department,
x => 0,
(x, y) => x + y.Salary
);
foreach (var kvp in aggregateBy)
Console.WriteLine($"ФОТ отдела {kvp.Key}: {kvp.Value}");
Вывод:
ФОТ отдела Sales: 220
ФОТ отдела IT: 290
Источник: https://steven-giesel.com/blogPost/0594ba85-356b-47f1-89a9-70e9761c582e/three-new-linq-methods-in-net-9
👍25
День 1832. #ЗаметкиНаПолях
.http-Файл в Visual Studio не Отправляет Заголовок Авторизации
При отправке запросов к API в Visual Studio возникает странная проблема. Bearer-токен, который в Swagger работает нормально, в файле .http просто игнорируется, что приводит к ошибке 401 Unauthorized.
Проблема
Простой проект Webapi ASP.NET Core, используя шаблон по умолчанию со встроенной поддержкой .http-файлов для выполнения запросов к проекту. Регистрация и вход в систему работают нормально, но попытка доступа к конечной точке, требующей аутентификации, всегда приводит к ошибке 401. Тот же токен, добавленный в тот же заголовок авторизации, отлично работает при использовании Swagger/Swashbuckle в браузере.
Диагностика проблемы
На вкладке Request info (Информация о запросе) в файле .http даже не отображался заголовок Authorization (но отображался кастомный заголовок Authorization2, который был идентичен во всех отношениях, кроме имени). Стало ясно, что это было так и задумано. Проблема в том, что запрос из .http-файла первоначально отправлялся на https://localhost:5206/cart, который перенаправлялся на https://localhost:7248/cart из-за использования промежуточного ПО UseHttpsRedirection.
Конечная точка http была настроена как переменная в верхней части файла .http, поэтому даже в самом файле не было очевидно, что данный запрос использует не тот URL/порт:
На вкладке Request (Запрос) вывода .http-файла отображался URL https://localhost:7248/cart, что никак не обозначает, что он неправильный (не тот, куда шёл изначальный запрос). Единственная проблема – отсутствие заголовка авторизации.
Возможно, было бы неплохо включить на вкладке Request (или где-то еще) информацию о том, что было выполнено перенаправление и что конечный URL не соответствует исходному запрошенному URL.
Заголовки перенаправления и авторизация
Основная проблема тут в том, как работает UseHttpsRedirection. Он отправляет клиенту в ответ заголовок перенаправления, и если клиент настроен на автоматическое следование перенаправлениям, он «молча» переходит на предложенный в перенаправлении URL. Однако также существует соглашение не пересылать заголовки авторизации при перенаправлениях:
«Заголовок Authorization очищается при автоматическом перенаправлении, и обработчик автоматически пытается повторно пройти аутентификацию на целевом URL. Никакие другие заголовки не очищаются. На практике это означает, что приложение не может помещать пользовательскую информацию аутентификации в заголовок Authorization, если есть возможность столкнуться с перенаправлением. Вместо этого приложение должно реализовать и зарегистрировать собственный модуль аутентификации.»
Обратите внимание, что в этом документе буквально говорится, что вам не следует использовать заголовки аутентификации, «если возможно столкнуться с перенаправлением», что, по сути, означает, что вы никогда не должны комбинировать UseHttpsRedirection с API, защищённым токеном.
Посмотрите предложение об изменении поведения файлов .http в Visual Studio и проголосуйте, если заинтересует.
Итого
Надеюсь, изложенное выше поможет сэкономить кому-то время. Если вы получаете ошибку 401 Unauthorized, даже если вы правильно настроили заголовок авторизации, и заметили, что заголовок авторизации отсутствует, ищите виновника в перенаправлении. Это может быть неочевидно в ваших инструментах, особенно если всё настроено на автоматическое следование перенаправлениям.
Источник: https://ardalis.com/http-file-not-sending-auth-header/
.http-Файл в Visual Studio не Отправляет Заголовок Авторизации
При отправке запросов к API в Visual Studio возникает странная проблема. Bearer-токен, который в Swagger работает нормально, в файле .http просто игнорируется, что приводит к ошибке 401 Unauthorized.
Проблема
Простой проект Webapi ASP.NET Core, используя шаблон по умолчанию со встроенной поддержкой .http-файлов для выполнения запросов к проекту. Регистрация и вход в систему работают нормально, но попытка доступа к конечной точке, требующей аутентификации, всегда приводит к ошибке 401. Тот же токен, добавленный в тот же заголовок авторизации, отлично работает при использовании Swagger/Swashbuckle в браузере.
Диагностика проблемы
На вкладке Request info (Информация о запросе) в файле .http даже не отображался заголовок Authorization (но отображался кастомный заголовок Authorization2, который был идентичен во всех отношениях, кроме имени). Стало ясно, что это было так и задумано. Проблема в том, что запрос из .http-файла первоначально отправлялся на https://localhost:5206/cart, который перенаправлялся на https://localhost:7248/cart из-за использования промежуточного ПО UseHttpsRedirection.
Конечная точка http была настроена как переменная в верхней части файла .http, поэтому даже в самом файле не было очевидно, что данный запрос использует не тот URL/порт:
POST {{BaseUrl}}/cart
На вкладке Request (Запрос) вывода .http-файла отображался URL https://localhost:7248/cart, что никак не обозначает, что он неправильный (не тот, куда шёл изначальный запрос). Единственная проблема – отсутствие заголовка авторизации.
Возможно, было бы неплохо включить на вкладке Request (или где-то еще) информацию о том, что было выполнено перенаправление и что конечный URL не соответствует исходному запрошенному URL.
Заголовки перенаправления и авторизация
Основная проблема тут в том, как работает UseHttpsRedirection. Он отправляет клиенту в ответ заголовок перенаправления, и если клиент настроен на автоматическое следование перенаправлениям, он «молча» переходит на предложенный в перенаправлении URL. Однако также существует соглашение не пересылать заголовки авторизации при перенаправлениях:
«Заголовок Authorization очищается при автоматическом перенаправлении, и обработчик автоматически пытается повторно пройти аутентификацию на целевом URL. Никакие другие заголовки не очищаются. На практике это означает, что приложение не может помещать пользовательскую информацию аутентификации в заголовок Authorization, если есть возможность столкнуться с перенаправлением. Вместо этого приложение должно реализовать и зарегистрировать собственный модуль аутентификации.»
Обратите внимание, что в этом документе буквально говорится, что вам не следует использовать заголовки аутентификации, «если возможно столкнуться с перенаправлением», что, по сути, означает, что вы никогда не должны комбинировать UseHttpsRedirection с API, защищённым токеном.
Посмотрите предложение об изменении поведения файлов .http в Visual Studio и проголосуйте, если заинтересует.
Итого
Надеюсь, изложенное выше поможет сэкономить кому-то время. Если вы получаете ошибку 401 Unauthorized, даже если вы правильно настроили заголовок авторизации, и заметили, что заголовок авторизации отсутствует, ищите виновника в перенаправлении. Это может быть неочевидно в ваших инструментах, особенно если всё настроено на автоматическое следование перенаправлениям.
Источник: https://ardalis.com/http-file-not-sending-auth-header/
👍17