День шестьсот девятый. #ЗаметкиНаПолях
Паттерн Options. Окончание
Начало
Продолжение
Валидация
Валидацию параметров можно осуществлять несколькими способами:
1. Аннотации
Аналогично валидации модели, можно использовать атрибуты из
Можно реализовать более сложную, чем аннотации, логику валидации при регистрации:
3. IValidateOption<T>
При этом подходе создаётся класс валидации, реализующий
Остаётся одна проблема в том, что валидация происходит "лениво", то есть только при обращении к параметрам (только на той странице, где они используются), что может приводить к сложным в обнаружении проблемам. См. текущее положение дел.
В этом случае одним из вариантов может быть создание фонового сервиса, который будет запускаться вместе с приложением и проверять все параметры. Кроме того, ему можно передать реализацию
А в
Паттерн Options. Окончание
Начало
Продолжение
Валидация
Валидацию параметров можно осуществлять несколькими способами:
1. Аннотации
Аналогично валидации модели, можно использовать атрибуты из
System.ComponentModel.DataAnnotations
:public class PositionOptions {При этом в регистрации используется метод
public string Title { get; set; }
[Required]
public string Name { get; set; }
}
AddOptions
, позволяющий добавить валидацию в цепочку:services.AddOptions<PositionOptions>()2. Метод Validate
.Bind(Configuration
.GetSection("Position"))
.ValidateDataAnnotations();
Можно реализовать более сложную, чем аннотации, логику валидации при регистрации:
services.AddOptions<PositionOptions>()Метод должен возвращать результат валидации в виде булева значения.
.Bind(Configuration
.GetSection("Position"))
.Validate(с => { … });
3. IValidateOption<T>
При этом подходе создаётся класс валидации, реализующий
IValidateOption<T>
, например:public class PositionOptionsValidation :Класс должен реализовать метод
IValidateOption<PositionOptions> {
…
}
Validate
интерфейса. Преимущество этого подхода в том, что для валидации можно использовать другие сервисы через DI. Регистрируется класс как Singleton после регистрации параметров:services.Configure<MyConfigOptions>(Метод
Configuration.GetSection("Position"));
services.TryAddEnumerable(
ServiceDescriptor
.Singleton<
IValidateOptions<PositionOptions>,
PositionOptionsValidation>());
TryAddEnumerable
позволяет регистрировать в DI коллекцию реализаций для интерфейса, поскольку у нас может быть несколько классов валидаторов.Остаётся одна проблема в том, что валидация происходит "лениво", то есть только при обращении к параметрам (только на той странице, где они используются), что может приводить к сложным в обнаружении проблемам. См. текущее положение дел.
В этом случае одним из вариантов может быть создание фонового сервиса, который будет запускаться вместе с приложением и проверять все параметры. Кроме того, ему можно передать реализацию
IHostApplicationLifetime
, позволяющую управлять основным приложением:public class ValidateOptionsService : IHostedService {
public ValidateOptionsService(
IHostApplicationLifetime appLifetime,
IOptions<PositionOptions> posOptions,
//другие параметры…) {
_appLifetime = appLifetime;
_posOptions = posOptions;
…
}
}
IHostedService
предполагает реализацию двух методов, возвращающих Task
: StartAsync
и StopAsync
. В последнем можно ничего не делать, просто вернуть Task.CompletedTask
. А в
StartAsync
добавляется код проверки параметров. Как вариант, при возникновении ошибок валидации можно останавливать приложение:public Task StartAsync(CancellationToken ct) {Источник: https://app.pluralsight.com/library/courses/dotnet-core-aspnet-core-configuration-options/
try {
//доступ к параметру приводит к валидации
_ = _posOptions.Value;
}
catch (OptionsValidationException ex) {
// останавливаем приложение
_appLifetime.StopApplication();
}
return Task.CompletedTask;
}
👍1
День шестьсот десятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
61. Завладейте Сборкой
Нередки случаи, когда команды разработчиков, которые в остальном очень дисциплинированно относятся к коду, пренебрегают дисциплиной относительно скриптов сборки. То ли думая, что это незначительная деталь, то ли из опасения, что релиз - это отдельный сложный процесс и вообще, забота другого отдела. В результате слабо сопровождаемые скрипты сборки с дублированием кода и ошибками вызывают проблемы не реже, чем плохо написанный код.
Одно из объяснений того, почему дисциплинированные и опытные разработчики рассматривают сборку как нечто второстепенное по сравнению с их работой, заключается в том, что скрипты сборки часто написаны на языке, отличном от языка исходного кода. Во-вторых, сборка - это «не совсем код». Эти оправдания противоречат тому факту, что большинству разработчиков программного обеспечения нравится изучать новые языки, и что сборка создаёт исполняемый код, которые тестируют разработчики и запускают конечные пользователи. Код бесполезен, пока он не будет собран. Сборка – вот что определяет компонентную архитектуру приложения. Она является важной частью процесса разработки, и правильная настройка сборки может упростить написание кода.
Скрипты сборки, написанные с использованием неправильных идиом, сложно поддерживать и, что более важно, улучшать. Стоит потратить некоторое время, чтобы понять, как правильно вносить изменения. Ошибки могут возникать, когда приложение использует неправильную версию зависимости или неправильную конфигурацию сборки.
Традиционно тестирование всегда оставалось на усмотрение команды обеспечения качества (QA). Теперь мы понимаем, что тестирование в процессе написания кода необходимо для получения предсказуемых результатов. Точно так же процесс сборки должен принадлежать команде разработчиков.
Понимание сборки может упростить весь жизненный цикл разработки и снизить затраты. Простая в исполнении сборка позволяет новому разработчику быстро и легко приступить к работе. Автоматизация сборки может позволить вам получать согласованные результаты, когда над проектом работают несколько человек, избегая ситуаций вроде «а у меня оно работает». Многие инструменты сборки позволяют создавать отчеты о качестве кода, что позволяет заранее обнаруживать потенциальные проблемы. Потратив время на понимание того, как получить полный контроль над сборкой, вы можете помочь и себе, и всей вашей команде. После этого вы можете сосредоточиться на написании кода. Сборка больше не будет казаться этапом, на котором происходит неведомая магия, и ваша работа станет более приятной.
Изучите процесс сборки достаточно, чтобы знать, когда и куда вносить изменения. Скрипты сборки – это тоже код. Они слишком важны, чтобы оставлять их кому-то другому, хотя бы по той причине, что приложение не завершено, пока оно не собрано. Работа программиста не может считаться завершённой, пока мы не поставим клиенту работающее программное обеспечение.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Steve Berczuk
97 Вещей, Которые Должен Знать Каждый Программист
61. Завладейте Сборкой
Нередки случаи, когда команды разработчиков, которые в остальном очень дисциплинированно относятся к коду, пренебрегают дисциплиной относительно скриптов сборки. То ли думая, что это незначительная деталь, то ли из опасения, что релиз - это отдельный сложный процесс и вообще, забота другого отдела. В результате слабо сопровождаемые скрипты сборки с дублированием кода и ошибками вызывают проблемы не реже, чем плохо написанный код.
Одно из объяснений того, почему дисциплинированные и опытные разработчики рассматривают сборку как нечто второстепенное по сравнению с их работой, заключается в том, что скрипты сборки часто написаны на языке, отличном от языка исходного кода. Во-вторых, сборка - это «не совсем код». Эти оправдания противоречат тому факту, что большинству разработчиков программного обеспечения нравится изучать новые языки, и что сборка создаёт исполняемый код, которые тестируют разработчики и запускают конечные пользователи. Код бесполезен, пока он не будет собран. Сборка – вот что определяет компонентную архитектуру приложения. Она является важной частью процесса разработки, и правильная настройка сборки может упростить написание кода.
Скрипты сборки, написанные с использованием неправильных идиом, сложно поддерживать и, что более важно, улучшать. Стоит потратить некоторое время, чтобы понять, как правильно вносить изменения. Ошибки могут возникать, когда приложение использует неправильную версию зависимости или неправильную конфигурацию сборки.
Традиционно тестирование всегда оставалось на усмотрение команды обеспечения качества (QA). Теперь мы понимаем, что тестирование в процессе написания кода необходимо для получения предсказуемых результатов. Точно так же процесс сборки должен принадлежать команде разработчиков.
Понимание сборки может упростить весь жизненный цикл разработки и снизить затраты. Простая в исполнении сборка позволяет новому разработчику быстро и легко приступить к работе. Автоматизация сборки может позволить вам получать согласованные результаты, когда над проектом работают несколько человек, избегая ситуаций вроде «а у меня оно работает». Многие инструменты сборки позволяют создавать отчеты о качестве кода, что позволяет заранее обнаруживать потенциальные проблемы. Потратив время на понимание того, как получить полный контроль над сборкой, вы можете помочь и себе, и всей вашей команде. После этого вы можете сосредоточиться на написании кода. Сборка больше не будет казаться этапом, на котором происходит неведомая магия, и ваша работа станет более приятной.
Изучите процесс сборки достаточно, чтобы знать, когда и куда вносить изменения. Скрипты сборки – это тоже код. Они слишком важны, чтобы оставлять их кому-то другому, хотя бы по той причине, что приложение не завершено, пока оно не собрано. Работа программиста не может считаться завершённой, пока мы не поставим клиенту работающее программное обеспечение.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Steve Berczuk
День шестьсот одиннадцатый. #ЧтоНовенького
Сканирование кода от GitHub
Сканирование кода - это функционал GitHub, позволяющий легко находить уязвимости безопасности до того, как они попадут в продакшн. Уже год GitHub сотрудничает с Semmle, чтобы предоставить пользователям возможности анализа кода по технологии CodeQL.
Сканирование кода предназначено в первую очередь для разработчиков. Вместо того, чтобы перегружать вас советами от анализатора кода, сканирование кода по умолчанию запускает только проверку актуальных правил безопасности. Оно интегрируется с GitHub Actions или другой системой CI/CD, чтобы обеспечить максимальную гибкость для вашей команды. Код сканируется по мере его создания, автоматизируя проверку безопасности. Это помогает гарантировать, что уязвимости никогда не попадут в продакшн.
Сканирование кода осуществляется с помощью CodeQL - самого мощного в мире механизма анализа кода. Вы можете использовать более 2000 запросов CodeQL, созданных GitHub и сообществом, или создавать собственные запросы, чтобы легко находить и предотвращать новые проблемы безопасности.
Сканирование основано на открытом стандарте SARIF и является расширяемым, поэтому вы можете добавлять решения SAST (Статическое Тестирование Защищенности Приложений) как с открытым исходным кодом, так и коммерческие. Вы можете интегрировать сторонние механизмы сканирования, чтобы просматривать результаты всех проверок безопасности в едином интерфейсе, а также экспортировать результаты сканирования через единый API.
С момента представления бета-версии в мае просканировано более 12 000 репозиториев и обнаружено более 20 000 уязвимостей вроде удаленного выполнения кода (RCE), SQL-инъекций и межсайтовых сценариев (XSS).
Сканирование кода бесплатно для публичных репозиториев. Для закрытых репозиториев сканирование кода доступно в GitHub Enterprise через Advanced Security.
Источник: https://github.blog/2020-09-30-code-scanning-is-now-available/
Сканирование кода от GitHub
Сканирование кода - это функционал GitHub, позволяющий легко находить уязвимости безопасности до того, как они попадут в продакшн. Уже год GitHub сотрудничает с Semmle, чтобы предоставить пользователям возможности анализа кода по технологии CodeQL.
Сканирование кода предназначено в первую очередь для разработчиков. Вместо того, чтобы перегружать вас советами от анализатора кода, сканирование кода по умолчанию запускает только проверку актуальных правил безопасности. Оно интегрируется с GitHub Actions или другой системой CI/CD, чтобы обеспечить максимальную гибкость для вашей команды. Код сканируется по мере его создания, автоматизируя проверку безопасности. Это помогает гарантировать, что уязвимости никогда не попадут в продакшн.
Сканирование кода осуществляется с помощью CodeQL - самого мощного в мире механизма анализа кода. Вы можете использовать более 2000 запросов CodeQL, созданных GitHub и сообществом, или создавать собственные запросы, чтобы легко находить и предотвращать новые проблемы безопасности.
Сканирование основано на открытом стандарте SARIF и является расширяемым, поэтому вы можете добавлять решения SAST (Статическое Тестирование Защищенности Приложений) как с открытым исходным кодом, так и коммерческие. Вы можете интегрировать сторонние механизмы сканирования, чтобы просматривать результаты всех проверок безопасности в едином интерфейсе, а также экспортировать результаты сканирования через единый API.
С момента представления бета-версии в мае просканировано более 12 000 репозиториев и обнаружено более 20 000 уязвимостей вроде удаленного выполнения кода (RCE), SQL-инъекций и межсайтовых сценариев (XSS).
Сканирование кода бесплатно для публичных репозиториев. Для закрытых репозиториев сканирование кода доступно в GitHub Enterprise через Advanced Security.
Источник: https://github.blog/2020-09-30-code-scanning-is-now-available/
День шестьсот двенадцатый. #Оффтоп
Топ 10 Советов по Работе в VS Code
Visual Studio Code уже несколько лет держит первое место по популярности среди сред разработки, согласно аналитики на StackOverflow. Сегодня представлю несколько советов по эффективной работе в этом редакторе.
1. Сочетания клавиш
Самый быстрый способ навигации по окнам и файлам проекта – это запомнить несколько сочетаний клавиш. В этом вам поможет страница сочетаний клавиш, которую можно открыть по
Наверное, наиболее важное сочетание – вызов панели команд (Command Palette) с помощью
2. Расширения
Сам по себе редактор VS Code достаточно лёгкий. Вся его мощь в огромном количестве доступных расширений. Более того, при открытии проекта редактор сам предложит вам установить рекомендуемые для конкретного языка расширения. Например, мне при открытии проекта на C# предложил установить расширение "C# for Visual Studio Code".
Ещё одно крутое расширение "Paste JSON as Code" позволяет вставлять код JSON отформатированный в класс на соответствующем языке (поддерживается множество языков). Например, в файл
3. Сниппеты
Доступны через расширения (например, "
4. Окно Терминала
Окно терминала, содержащее Windows Power Shell или аналогичный терминал в других ОС, можно вызвать по
5. IntelliSense
Всем знакомый инструмент автодополнения кода. Работает в строго типизированных языках либо автоматически, либо по нажатию
6. Просмотр определения
Знакомый всем по Visual Studio инструмент «Перейти к определению»
7. Zen Mode
Чтобы убрать всё, что вас отвлекает от работы, можно перейти в Zen Mode (
Для полного расслабона есть даже расширение для Spotify, но оно работает только с премиум подпиской.
8. Отладка
Для этого также придётся установить расширение под соответствующий язык. Ничего сложного, просто откройте панель команд (
9. Git
Работа с Git уже встроена в VS Code. Просто перейдите на вкладку Source Control слева или нажмите
А если установить расширение GitLens, вы сможете не только работать с репозиторием в панели Source Control, но и видеть в коде подсказки, кто и когда изменил определённые блоки кода.
10. Visual Studio Live Share
Расширение для командной разработки в режиме реального времени. Позволяет совместно вносить изменения, совместно выполнять отладку, созваниваться и общаться в чате с коллегами, просматривать комментарии, предоставлять общий доступ к терминалам и серверам, и т.д., и т.п.
Источник: https://youtu.be/u21W_tfPVrY
Топ 10 Советов по Работе в VS Code
Visual Studio Code уже несколько лет держит первое место по популярности среди сред разработки, согласно аналитики на StackOverflow. Сегодня представлю несколько советов по эффективной работе в этом редакторе.
1. Сочетания клавиш
Самый быстрый способ навигации по окнам и файлам проекта – это запомнить несколько сочетаний клавиш. В этом вам поможет страница сочетаний клавиш, которую можно открыть по
Ctrl+K,S
.Наверное, наиболее важное сочетание – вызов панели команд (Command Palette) с помощью
Ctrl+P
. Откроется строка универсального поиска, позволяющая искать файлы, команды или пункты меню. Чтобы увидеть все возможности, введите ?
.2. Расширения
Сам по себе редактор VS Code достаточно лёгкий. Вся его мощь в огромном количестве доступных расширений. Более того, при открытии проекта редактор сам предложит вам установить рекомендуемые для конкретного языка расширения. Например, мне при открытии проекта на C# предложил установить расширение "C# for Visual Studio Code".
Ещё одно крутое расширение "Paste JSON as Code" позволяет вставлять код JSON отформатированный в класс на соответствующем языке (поддерживается множество языков). Например, в файл
.cs
вставится класс на C#, а в файл .ts
– класс на TypeScript.3. Сниппеты
Доступны через расширения (например, "
C# Snippets
"). Позволяют существенно сократить затраты на написание шаблонных блоков. И не ограничиваются обычными prop
или ctor
, а позволяют вставлять целые классы, например, ASP.NET MVC контроллера.4. Окно Терминала
Окно терминала, содержащее Windows Power Shell или аналогичный терминал в других ОС, можно вызвать по
Ctrl+`
(Ctrl+ё
в русской раскладке).5. IntelliSense
Всем знакомый инструмент автодополнения кода. Работает в строго типизированных языках либо автоматически, либо по нажатию
Ctrl+пробел
.6. Просмотр определения
Знакомый всем по Visual Studio инструмент «Перейти к определению»
F12
или «Посмотреть определение» Ctrl+F12
. И наоборот, в определении класса или интерфейса вы можете найти все ссылки на него по Shift+F12
. А также переименовать все упоминания по F2
с возможностью предпросмотра изменений. Кроме того, введя @
в панели команд, вы можете посмотреть все классы, методы, свойства и т.п. в текущем файле и быстро к ним перейти. Доступно через упомянутое выше расширение (или аналогичное в другом языке). 7. Zen Mode
Чтобы убрать всё, что вас отвлекает от работы, можно перейти в Zen Mode (
Ctrl+K,Z
). Редактор перейдёт в полноэкранный режим, уберёт все меню, боковые и нижние панели. Ничего лишнего, только код.Для полного расслабона есть даже расширение для Spotify, но оно работает только с премиум подпиской.
8. Отладка
Для этого также придётся установить расширение под соответствующий язык. Ничего сложного, просто откройте панель команд (
Ctrl+P
), наберите >
для команд и "Debugger
". Подсказка предложит установить отладчик для текущего языка. Для отладки клиентский код прямо в VS Code можно установить, например, "Debugger for Chrome".9. Git
Работа с Git уже встроена в VS Code. Просто перейдите на вкладку Source Control слева или нажмите
Ctrl+Shift+G
. Вам откроется список изменённых файлов. Всё, что остаётся сделать, это ввести сообщение и нажать Commit. Другие возможности Git доступны в меню по кнопке "…".А если установить расширение GitLens, вы сможете не только работать с репозиторием в панели Source Control, но и видеть в коде подсказки, кто и когда изменил определённые блоки кода.
10. Visual Studio Live Share
Расширение для командной разработки в режиме реального времени. Позволяет совместно вносить изменения, совместно выполнять отладку, созваниваться и общаться в чате с коллегами, просматривать комментарии, предоставлять общий доступ к терминалам и серверам, и т.д., и т.п.
Источник: https://youtu.be/u21W_tfPVrY
День шестьсот тринадцатый. #Оффтоп #ВопросыНаСобеседовании
Поведенческое интервью
У меня на канале было несколько постов на тему «Что спрашивают на собеседовании?», но до сих пор я не затрагивал эту тему. Если не понятно из названия, на этом собеседовании задают вопросы о вас лично, пытаясь узнать, какой вы человек, ваш опыт, ваши сильные и слабые стороны, пытаясь определить, какой из вас выйдет работник. Обычно это один из первых этапов собеседования (или первое в серии). Несмотря на то, что здесь, казалось бы, не проверяют ваши знания, некоторые вопросы могут ввести в ступор, либо ваши ответы могут быть неверно восприняты настолько, что вашу кандидатуру отметут уже на начальном этапе.
На вопросы поведенческого собеседования нет как таковых «правильных» ответов. Однако на некоторые каверзные вопросы важно придумать адекватные ответы заранее, чтобы не задумываться над ними слишком долго. По большому счёту интервьюеры в большинстве случаев ожидают, что ответы на такие вопросы продуманы заранее.
Например, «Как ваш предыдущий опыт поможет вам в будущей работе?» Ваш предыдущий опыт может быть не связан с технологией, которая используется в компании, с методами разработки и работы вообще принятыми в компании, и т.д., и т.п. Стоит найти хоть какие-нибудь точки соприкосновения и придумать, как их можно использовать.
«Как вы относитесь к критике?» Критиковать вас будут обязательно: коллеги, менеджеры, начальники повыше. Простой заученный ответ, вроде «Я адекватно восприму и постараюсь быть лучше» тут вряд ли подойдёт. Вспомните случай из опыта, когда вы отреагировали на критику в ваш адрес таким образом, что это помогло решить проблему.
«Какой ваш самый главный недостаток, и как вы собираетесь его исправить?» Вот тут многие и впадают в ступор. Нужно придумать что-то, что звучит правдоподобно (лучше всего, если правда), но в то же время не вызовет у интервьюеров желания тут же вас выдворить. В видео, которое послужило мотивом написания этого поста (ссылка ниже), «интервьюируемый» придумал интересный недостаток, который, кстати, и я могу сказать про себя. Я часто в разговоре могу отшучиваться, уводя разговор в более неформальный тон, не подозревая, что не все люди готовы на это. В моей карьере большинство начальников нормально относились к этому, и сами были не против пошутить. Но на самом деле это далеко не всегда так. И, конечно, к каждому человеку нужен свой подход. Если я вдруг окажусь в супер серьёзном коллективе, мне скорее всего будет не очень комфортно.
Вопрос, который очень любят задавать у нас: «Почему вы хотите работать в нашей компании?» Иногда это звучит довольно глупо, особенно из уст эйчара какой-нибудь ноунеймовой конторы, возомнившей, что они как минимум Гугл, и все мечтают у них работать. И как бы вас ни порывало ответить что-нибудь в духе «Да вы были последние в моём списке» или «Обещали хорошую ЗП», всё-таки перед интервью поищите информацию о компании и покажите, что вы в них заинтересованы.
Одно из замечаний от интервьюера в видео мне также показалось интересным:
Не используйте абсолютные выражения.
В видео «кандидат» заявил, что никогда бы не стал работать с легаси-кодом. Это очень сильное заявление сразу в нескольких аспектах. Во-первых, легаси код есть в каждой компании (кроме, может быть, только что созданных стартапов). Может быть в компании много легаси кода, который они хотят или не хотят переписывать (если работает, не трогай). Во-вторых, код – такая вещь, что самая свежая и прорывная технология через пару лет станет легаси, а то и вовсе умрёт (R.I.P Silverlight). Но и в остальных вопросах избегайте использования категоричных суждений. Это как раз тот момент, когда за нечаянно вырвавшееся у вас «никогда» могут зацепиться и истолковать вашу мысль совсем не так, как вы пытались её донести.
Что вы думаете? Какие самые сложные, неприятные или глупые нетехнические вопросы вам задавали на собеседовании? Телеграм на днях выкатил обновление, позволяющее добавлять комментарии (надеюсь, клиенты уже у всех обновились). Давайте их опробуем!
Источник: https://www.youtube.com/watch?v=GxCD7Q_qDpU
Поведенческое интервью
У меня на канале было несколько постов на тему «Что спрашивают на собеседовании?», но до сих пор я не затрагивал эту тему. Если не понятно из названия, на этом собеседовании задают вопросы о вас лично, пытаясь узнать, какой вы человек, ваш опыт, ваши сильные и слабые стороны, пытаясь определить, какой из вас выйдет работник. Обычно это один из первых этапов собеседования (или первое в серии). Несмотря на то, что здесь, казалось бы, не проверяют ваши знания, некоторые вопросы могут ввести в ступор, либо ваши ответы могут быть неверно восприняты настолько, что вашу кандидатуру отметут уже на начальном этапе.
На вопросы поведенческого собеседования нет как таковых «правильных» ответов. Однако на некоторые каверзные вопросы важно придумать адекватные ответы заранее, чтобы не задумываться над ними слишком долго. По большому счёту интервьюеры в большинстве случаев ожидают, что ответы на такие вопросы продуманы заранее.
Например, «Как ваш предыдущий опыт поможет вам в будущей работе?» Ваш предыдущий опыт может быть не связан с технологией, которая используется в компании, с методами разработки и работы вообще принятыми в компании, и т.д., и т.п. Стоит найти хоть какие-нибудь точки соприкосновения и придумать, как их можно использовать.
«Как вы относитесь к критике?» Критиковать вас будут обязательно: коллеги, менеджеры, начальники повыше. Простой заученный ответ, вроде «Я адекватно восприму и постараюсь быть лучше» тут вряд ли подойдёт. Вспомните случай из опыта, когда вы отреагировали на критику в ваш адрес таким образом, что это помогло решить проблему.
«Какой ваш самый главный недостаток, и как вы собираетесь его исправить?» Вот тут многие и впадают в ступор. Нужно придумать что-то, что звучит правдоподобно (лучше всего, если правда), но в то же время не вызовет у интервьюеров желания тут же вас выдворить. В видео, которое послужило мотивом написания этого поста (ссылка ниже), «интервьюируемый» придумал интересный недостаток, который, кстати, и я могу сказать про себя. Я часто в разговоре могу отшучиваться, уводя разговор в более неформальный тон, не подозревая, что не все люди готовы на это. В моей карьере большинство начальников нормально относились к этому, и сами были не против пошутить. Но на самом деле это далеко не всегда так. И, конечно, к каждому человеку нужен свой подход. Если я вдруг окажусь в супер серьёзном коллективе, мне скорее всего будет не очень комфортно.
Вопрос, который очень любят задавать у нас: «Почему вы хотите работать в нашей компании?» Иногда это звучит довольно глупо, особенно из уст эйчара какой-нибудь ноунеймовой конторы, возомнившей, что они как минимум Гугл, и все мечтают у них работать. И как бы вас ни порывало ответить что-нибудь в духе «Да вы были последние в моём списке» или «Обещали хорошую ЗП», всё-таки перед интервью поищите информацию о компании и покажите, что вы в них заинтересованы.
Одно из замечаний от интервьюера в видео мне также показалось интересным:
Не используйте абсолютные выражения.
В видео «кандидат» заявил, что никогда бы не стал работать с легаси-кодом. Это очень сильное заявление сразу в нескольких аспектах. Во-первых, легаси код есть в каждой компании (кроме, может быть, только что созданных стартапов). Может быть в компании много легаси кода, который они хотят или не хотят переписывать (если работает, не трогай). Во-вторых, код – такая вещь, что самая свежая и прорывная технология через пару лет станет легаси, а то и вовсе умрёт (R.I.P Silverlight). Но и в остальных вопросах избегайте использования категоричных суждений. Это как раз тот момент, когда за нечаянно вырвавшееся у вас «никогда» могут зацепиться и истолковать вашу мысль совсем не так, как вы пытались её донести.
Что вы думаете? Какие самые сложные, неприятные или глупые нетехнические вопросы вам задавали на собеседовании? Телеграм на днях выкатил обновление, позволяющее добавлять комментарии (надеюсь, клиенты уже у всех обновились). Давайте их опробуем!
Источник: https://www.youtube.com/watch?v=GxCD7Q_qDpU
👍1
День шестьсот четырнадцатый. #ЗаметкиНаПолях
Внедрение Зависимостей в ASP.NET Core. Начало (1/4)
ASP.NET Core активно использует внедрение зависимостей. Теорию я описывал в этом посте, а тут будет только практика.
По умолчанию в приложениях используется контейнер внедрения зависимостей (контейнер DI) от Microsoft, который несколько ограничен в функционале, по сравнению с другими, но подходит в большинстве случаев. Он находится в отдельной библиотеке в пространстве имён
Необходимые для внедрения интерфейсы и классы (также называемые сервисами) регистрируются в коллекции типа
Что регистрировать в сервисах?
В первую очередь – зависимости. Просмотрите свой код и найдите использования ключевого слова
1. Выделяем интерфейс из класса
Однако, если, например, метод действия контроллера использует new для создания объекта модели и передаёт её в представление, то модель в этом случае используется для передачи данных между слоями приложения, и не является зависимостью.
В коде приложения могут появиться цепочки зависимостей, когда класс
Продолжение следует…
Источник: https://app.pluralsight.com/library/courses/aspdotnet-core-dependency-injection/
Внедрение Зависимостей в ASP.NET Core. Начало (1/4)
ASP.NET Core активно использует внедрение зависимостей. Теорию я описывал в этом посте, а тут будет только практика.
По умолчанию в приложениях используется контейнер внедрения зависимостей (контейнер DI) от Microsoft, который несколько ограничен в функционале, по сравнению с другими, но подходит в большинстве случаев. Он находится в отдельной библиотеке в пространстве имён
Microsoft.Extensions.DependencyInjection
. В проект он обычно включается в составе метапакета Microsoft.AspNetCore.All
.Необходимые для внедрения интерфейсы и классы (также называемые сервисами) регистрируются в коллекции типа
IServiceCollection
. Чаще всего это происходит в методе ConfigureServices
класса Startup
. Во время работы приложения контейнер DI отвечает за обнаружение необходимого сервиса и создание его экземпляра с нужным сроком жизни.public void ConfigureServices(IServiceCollection services) { … }Параметр services на момент вызова метода будет инициализирован хостом. В отличие от регистрации промежуточного ПО в методе Configure, порядок регистрации сервисов чаще всего не имеет значения.
Что регистрировать в сервисах?
В первую очередь – зависимости. Просмотрите свой код и найдите использования ключевого слова
new
. Если ваш класс A
создаёт экземпляр класса B
, вызывает его методы и использует результат их работы, то класс A
зависит от класса B
. class A {Класс
public MethodA() {
var b = new B();
b.MethodB();
}
}
B
- кандидат на регистрацию в сервисах. В общем случае это делается в 3 этапа:1. Выделяем интерфейс из класса
B
:interface InterfaceB {2. Добавляем интерфейс в параметры конструктора класса
void MethodB();
}
class B : InterfaceB {…}
A
:class A {3. Регистрируем реализацию интерфейса в контейнере DI:
private readonly InterfaceB _b;
public A(InterfaceB b) {
_b = b;
}
}
services.AddTransient<InterfaceB, B>();
Однако, если, например, метод действия контроллера использует new для создания объекта модели и передаёт её в представление, то модель в этом случае используется для передачи данных между слоями приложения, и не является зависимостью.
В коде приложения могут появиться цепочки зависимостей, когда класс
A
зависит от класса B
, а тот зависит от C
. Контейнер DI способен разрешать эти зависимости и находить соответствующие сервисы автоматически.Продолжение следует…
Источник: https://app.pluralsight.com/library/courses/aspdotnet-core-dependency-injection/
День шестьсот пятнадцатый. #ЗаметкиНаПолях
Внедрение Зависимостей в ASP.NET Core. Продолжение (2/4)
Начало
Время жизни сервисов
Контейнер DI отвечает за создание и уничтожение экземпляров сервисов. Доступно 3 варианта регистрации:
1. Transient – новый экземпляр сервиса создаётся каждый раз, когда он требуется. Каждый класс, зависящий от такого сервиса, получит отдельный экземпляр:
- не требует потокобезопасности, т.к. не подходит для сохранения состояния;
- потенциально может неэффективно использовать память и вести к созданию и уничтожению множества объектов.
2. Singleton – экземпляр создаётся на всё время работы приложения. Один и тот же экземпляр сервиса будет использоваться во всех зависящих от него классах всё время:
- обычно более эффективен, чем Transient, т.к. создаётся только один объект, поэтому подходит для дорогих в создании объектов,
- может приводить к утечкам памяти при регистрации больших редко используемых объектов;
- подходит для объектов с общими функциями, не сохраняющими состояние (например, логгер).
3. Scoped – экземпляр сервиса создаётся на время обработки запроса к приложению. Зависимые объекты в течение обработки одного запроса получат один и тот же экземпляр. Например, в EntityFramework класс
Сервис не должен зависеть от другого сервиса с меньшим временем жизни! Если Singleton-сервис зависит от Transient- или Scoped-сервиса, то последний может быть захвачен и не будет уничтожен в течение всего времени жизни приложения. Это может приводить как к утечкам памяти, так и к совместному использованию непотокобезопасного кода из Transient-сервисов.
Начиная с ASP.NET Core 2.0 по умолчанию включена валидация времени жизни сервисов (
Регистрация открытых обобщённых типов
Иногда требуется зарегистрировать реализацию обобщённого интерфейса. Например,
Дескрипторы сервисов
Дескрипторы сервисов (класс
Продолжение следует…
Источник: https://app.pluralsight.com/library/courses/aspdotnet-core-dependency-injection/
Внедрение Зависимостей в ASP.NET Core. Продолжение (2/4)
Начало
Время жизни сервисов
Контейнер DI отвечает за создание и уничтожение экземпляров сервисов. Доступно 3 варианта регистрации:
1. Transient – новый экземпляр сервиса создаётся каждый раз, когда он требуется. Каждый класс, зависящий от такого сервиса, получит отдельный экземпляр:
services.AddTransient<IEmailSender, EmailSender>();- самый простой в работе: если срок жизни сервиса сложно определить, Transient сервис чаще всего будет наиболее подходящим;
- не требует потокобезопасности, т.к. не подходит для сохранения состояния;
- потенциально может неэффективно использовать память и вести к созданию и уничтожению множества объектов.
2. Singleton – экземпляр создаётся на всё время работы приложения. Один и тот же экземпляр сервиса будет использоваться во всех зависящих от него классах всё время:
services.AddSingleton<ILoggerFactory, LoggerFactory>();- изменение состояния сервиса (если оно допускается) должно быть потокобезопасно;
- обычно более эффективен, чем Transient, т.к. создаётся только один объект, поэтому подходит для дорогих в создании объектов,
- может приводить к утечкам памяти при регистрации больших редко используемых объектов;
- подходит для объектов с общими функциями, не сохраняющими состояние (например, логгер).
3. Scoped – экземпляр сервиса создаётся на время обработки запроса к приложению. Зависимые объекты в течение обработки одного запроса получат один и тот же экземпляр. Например, в EntityFramework класс
DbContext
регистрируется как Scoped:services.AddScoped<IOrderService, OrderService>();Избегайте захвата сервисов
Сервис не должен зависеть от другого сервиса с меньшим временем жизни! Если Singleton-сервис зависит от Transient- или Scoped-сервиса, то последний может быть захвачен и не будет уничтожен в течение всего времени жизни приложения. Это может приводить как к утечкам памяти, так и к совместному использованию непотокобезопасного кода из Transient-сервисов.
Начиная с ASP.NET Core 2.0 по умолчанию включена валидация времени жизни сервисов (
ValidateScopes
). Она приводит к ошибке времени выполнения при старте приложения, если будет обнаружен захват сервисов. Однако, учтите, что эта функция отключена в продакшн, и её не рекомендуется включать вне среды разработки.Регистрация открытых обобщённых типов
Иногда требуется зарегистрировать реализацию обобщённого интерфейса. Например,
ILogger<T>
. В этом случае используется необобщённый метод Add…
и typeof
:services.AddSingleton(Если параметров типа больше одного, внутрь угловых скобок добавляются запятые(например,
typeof(ILogger<>), typeof(MyLogger<>));
typeof(ISomeInterface<,>)
).Дескрипторы сервисов
Дескрипторы сервисов (класс
ServiceDescriptor
) содержат информацию о регистрируемых сервисах и используются внутри контейнера DI. var sd = new ServiceDescriptor(typeof(IOrderService),Чаще всего создание дескриптора скрыто в методах расширения, описанных выше, и создание его вручную не требуется.
typeof(OrderService), ServiceLifetime.Scoped);
services.Add(sd);
Продолжение следует…
Источник: https://app.pluralsight.com/library/courses/aspdotnet-core-dependency-injection/
День шестьсот шестнадцатый. #ЗаметкиНаПолях
Внедрение Зависимостей в ASP.NET Core. Продолжение (3/4)
Начало
Продолжение
Регистрация нескольких сервисов
Если в методе
Чтобы избежать случайной «перезаписи» зарегистрированных сервисов, можно использовать соответствующий
Важно отметить, что без использования
Иногда нужно явно перезаписать предыдущую регистрацию. Тогда используется метод
Зачем же контейнер DI регистрирует несколько реализаций? Это может пригодиться, когда вам нужно, например, зарегистрировать несколько отправителей сообщений, валидаторов данных или бизнес-правил, которые должны будут применены одно за другим. В этом случае в конструктор зависимого класса внедряется коллекция сервисов:
При регистрации нескольких реализаций может быть нежелательно регистрировать одинаковые реализации, что обычными методами не проверяется. В нашем случае, если случайно зарегистрировать
Окончание следует…
Источник: https://app.pluralsight.com/library/courses/aspdotnet-core-dependency-injection/
Внедрение Зависимостей в ASP.NET Core. Продолжение (3/4)
Начало
Продолжение
Регистрация нескольких сервисов
Если в методе
ConfigureServices
используется несколько регистраций для одного интерфейса, то последняя из них имеет приоритет.services.AddTransient<IMessageSender, EmailSender>();Здесь в приложении будет использован
services.AddTransient<IMessageSender, SMSSender>();
SMSSender
.Чтобы избежать случайной «перезаписи» зарегистрированных сервисов, можно использовать соответствующий
TryAdd…
метод (например, TryAddTransient
). Тогда реализация будет добавлена, только если она ещё не была зарегистрирована ранее.Важно отметить, что без использования
TryAdd…
зарегистрированы будут оба сервиса, но лишь последняя реализация будет использована при обнаружении сервиса.Иногда нужно явно перезаписать предыдущую регистрацию. Тогда используется метод
Replace
, принимающий дескриптор сервиса:services.Replace(Чтобы удалить все регистрации сервисов для определённого интерфейса, используется метод
new ServiceDescriptor(typeof(IMessageSender),
typeof(SMSSender), ServiceLifetime.Transient)
);
RemoveAll
:services.RemoveAll<IMessageSender>();Использовать эти методы придётся редко. Например, чтобы предоставить свою реализацию одного из сервисов сторонней библиотеки.
Зачем же контейнер DI регистрирует несколько реализаций? Это может пригодиться, когда вам нужно, например, зарегистрировать несколько отправителей сообщений, валидаторов данных или бизнес-правил, которые должны будут применены одно за другим. В этом случае в конструктор зависимого класса внедряется коллекция сервисов:
public class Notifier {Таким образом, если мы хотим добавить, скажем, отправку через пуш-уведомления, нам нужно только добавить реализацию и зарегистрировать её в контейнере DI. Это одно из ограничений стандартного контейнера. Другие, более продвинутые, позволяют автоматически сканировать сборку и добавлять все реализации интерфейса.
IEnumerable<IMessageSender> _senders;
public Notifier(
IEnumerable<IMessageSender> senders) {
_senders = senders;
}
public void SendMessage() {
foreach (var s in _senders) {
// обработка каждого отправителя
}
}
}
При регистрации нескольких реализаций может быть нежелательно регистрировать одинаковые реализации, что обычными методами не проверяется. В нашем случае, если случайно зарегистрировать
SMSSender
дважды, сообщение по смс будет отправлено 2 раза. Тогда можно использовать метод TryAddEnumerable
, принимающий коллекцию дескрипторов сервисов:services.TryAddEnumerable(new[]В этом случае будет зарегистрирована только одна реализация
{
new ServiceDescriptor(typeof(IMessageSender),
typeof(EmailSender), ServiceLifetime.Transient),
new ServiceDescriptor(typeof(IMessageSender),
typeof(SMSSender), ServiceLifetime.Transient),
new ServiceDescriptor(typeof(IMessageSender),
typeof(SMSSender), ServiceLifetime.Transient)
});
SMSSender
.Окончание следует…
Источник: https://app.pluralsight.com/library/courses/aspdotnet-core-dependency-injection/
День шестьсот семнадцатый. #ЗаметкиНаПолях
Внедрение Зависимостей в ASP.NET Core. Окончание (4/4)
Начало
Продолжение 1
Продолжение 2
Чистый код
В более-менее большом приложении метод ConfigureServices разрастается довольно быстро, и в нём становится сложно ориентироваться. В этом случае поможет создание методов расширения для
Механизмы обнаружения сервисов
В ASP.NET Core используется два основных механизма обнаружения. За обнаружение сервисов, зарегистрированных в контейнере DI, отвечает провайдер сервисов, реализующий
Другие типы внедрения зависимостей
1. В методы действия контроллеров
В ASP.NET Core помимо обычного внедрения зависимостей через конструктор доступно внедрение в методы действия контроллеров. Для этого используется атрибут параметра
2. В промежуточное ПО (Middleware)
Проблема внедрения зависимостей в конструктор промежуточного ПО может быть при попытке внедрения Scoped сервиса, т.к. промежуточное ПО создаётся на всё время жизни приложения. В результате возникает ошибка захвата сервисов, описанная в предыдущем посте. В этом случае доступно внедрение зависимости прямо в метод
3. В представления
Внедрять зависимости прямо в представления требуется редко, и это не рекомендуется, т.к. обычно это помещает бизнес логику в слой представления, где ей не место. Одним из сценариев использования может быть получение набора опций для выпадающего списка. В представлении используется ключевое слово
Внедрение Зависимостей в ASP.NET Core. Окончание (4/4)
Начало
Продолжение 1
Продолжение 2
Чистый код
В более-менее большом приложении метод ConfigureServices разрастается довольно быстро, и в нём становится сложно ориентироваться. В этом случае поможет создание методов расширения для
IServiceCollection
. По соглашению имена таких методов начинаются с Add
:public static IServiceCollection AddCoreServices(Важно возвращать из метода набор сервисов, чтобы эти методы расширения можно было объединять в цепочки. Тогда метод
this IServiceCollection services) {
services.AddScoped<…>();
//…
return services;
}
ConfigureServices
будет выглядеть компактнее и понятнее:public void ConfigureServices(Для многих внутренних сервисов ASP.NET Core уже добавлены методы расширения, например,
IServiceCollection services) {
services.AddCoreServices()
.AddDatabaseServices()
.AddCaching()
…
}
AddMvc()
, AddIdentity()
, AddDbContext()
и т.п.Механизмы обнаружения сервисов
В ASP.NET Core используется два основных механизма обнаружения. За обнаружение сервисов, зарегистрированных в контейнере DI, отвечает провайдер сервисов, реализующий
IServiceProvider
. Также используются статические методы класса ActivatorUtilities
. В этом случае можно создавать сервисы, не зарегистрированные в контейнере DI, через конструктор. Конструктору можно передавать параметры либо напрямую, либо указать сервисы, зарегистрированные в конструкторе DI, и они будут обнаружены через провайдер сервисов. В ASP.NET Core таким образом создаются внутренние компоненты, вроде контроллеров, тег-хелперов, фильтров и т.п.Другие типы внедрения зависимостей
1. В методы действия контроллеров
В ASP.NET Core помимо обычного внедрения зависимостей через конструктор доступно внедрение в методы действия контроллеров. Для этого используется атрибут параметра
FromServices
:public async Task<IActionResult> Update(Это полезно, если сервис используется только в одном методе действия контроллера, и его не нужно создавать при вызовах других методов действия, как было бы при использовании внедрения через конструктор.
[FromServices] IMessageSender sender) {…}
2. В промежуточное ПО (Middleware)
Проблема внедрения зависимостей в конструктор промежуточного ПО может быть при попытке внедрения Scoped сервиса, т.к. промежуточное ПО создаётся на всё время жизни приложения. В результате возникает ошибка захвата сервисов, описанная в предыдущем посте. В этом случае доступно внедрение зависимости прямо в метод
Invoke
/InvokeAsync
промежуточного ПО. В конструктор промежуточного ПО можно внедрять только Singleton-сервисы.3. В представления
Внедрять зависимости прямо в представления требуется редко, и это не рекомендуется, т.к. обычно это помещает бизнес логику в слой представления, где ей не место. Одним из сценариев использования может быть получение набора опций для выпадающего списка. В представлении используется ключевое слово
inject
@inject IOptionsProvider optionsИсточник: https://app.pluralsight.com/library/courses/aspdotnet-core-dependency-injection/
День шестьсот восемнадцатый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
62. Парное Программирование и Состояние Потока
Представьте, что вы полностью поглощены тем, что вы делаете, сосредоточены, погружены в процесс. Возможно, вы потеряли счёт времени. Вы чувствуете себя счастливым. Вы поймали кураж. Вы в состоянии потока. Однако достичь и поддерживать состояние потока у всей команды разработчиков одновременно слишком трудно. Много вынужденных пауз взаимодействий между членами команды и других отвлекающих факторов, которые легко сбивают с ритма.
Если вы уже практиковали парное программирование, вы, вероятно, знаете, как оно помогает поймать поток. Если нет, я поделюсь с вами своим опытом, чтобы мотивировать вас начать прямо сейчас! Чтобы добиться успеха в парном программировании, как отдельные члены команды, так и команда в целом, должны приложить определённые усилия.
Как член команды, будьте терпеливы с менее опытными разработчиками. Боритесь со страхом более опытных разработчиков. Поймите, что люди разные, и цените это. Помните о своих сильных и слабых сторонах, а также о сильных и слабых сторонах других членов команды. Вы можете быть удивлены, узнав, как многому вы можете научиться у своих коллег.
На уровне команды продвигайте парное программирование для распространения навыков и знаний. Вы должны решать задачи в парах и часто тасовать пары и задачи. Согласуйте правила ротации, и изменяйте их при необходимости. Мой опыт показывает, что вам не обязательно выполнять задачу до конца, прежде чем передавать её другой паре. Прерывание задачи для передачи её другой паре может показаться нелогичным, но я обнаружил, что это работает.
Существует множество ситуаций, когда состояние потока нарушается, а парное программирование помогает его сохранить:
1. Ослабление «фактора грузовика». Звучит цинично, но всё-таки: сколько и каких членов вашей команды придётся сбить грузовиком, чтобы команда не смогла успешно завершить проект? Другими словами, насколько ваша работа зависит от определённых членов команды? Являются ли их знания о проекте их личными или эти знания распределены между многими членами команды? Если вы ротируете задачи между парами, всегда будет кто-то, кто обладает нужными знаниями и сможет выполнить работу. В результате поток вашей команды менее подвержен "фактору грузовика".
2. Эффективное решение проблемы. Если вы занимаетесь парным программированием и сталкиваетесь со сложной проблемой, вам всегда есть с кем её обсудить. Такой диалог с большей вероятностью сдвинет вас с мёртвой точки, чем если бы вы застряли в одиночестве. При переходе задачи к другой паре ваше решение будет пересмотрено и проверено, поэтому не страшно, если вы изначально выбрали не самое оптимальное решение.
3. Плавная интеграция. Если ваша текущая задача включает вызов другого фрагмента кода, вы надеетесь, что имена методов, документация и тесты достаточно информативны, чтобы дать вам представление о том, что делает код. Если нет, объединение с разработчиком, который участвовал в написании этого кода, даст вам лучшее представление о нём и более быструю интеграцию с вашим кодом. Кроме того, вы сможете обсудить как можно улучшить именование, документацию и тесты.
4. Устойчивость к сбоям. Если что-то вас отвлекает: вам нужно ответить на телефонный звонок или email или поприсутствовать на встрече, - ваш партнёр по парному программированию может продолжать писать код. Когда вы вернётесь, ваш партнёр все еще будет в потоке, и вы быстро присоединитесь к нему.
5. Быстрое включение новичков. Благодаря парному программированию и правильной ротации пар и задач новички быстро знакомятся как с кодом, так и с другими членами команды.
В состоянии потока вы наиболее продуктивны, но оно очень уязвимо. Делайте всё возможное, чтобы поймать и удержаться в нём!
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Gudny Hauknes
97 Вещей, Которые Должен Знать Каждый Программист
62. Парное Программирование и Состояние Потока
Представьте, что вы полностью поглощены тем, что вы делаете, сосредоточены, погружены в процесс. Возможно, вы потеряли счёт времени. Вы чувствуете себя счастливым. Вы поймали кураж. Вы в состоянии потока. Однако достичь и поддерживать состояние потока у всей команды разработчиков одновременно слишком трудно. Много вынужденных пауз взаимодействий между членами команды и других отвлекающих факторов, которые легко сбивают с ритма.
Если вы уже практиковали парное программирование, вы, вероятно, знаете, как оно помогает поймать поток. Если нет, я поделюсь с вами своим опытом, чтобы мотивировать вас начать прямо сейчас! Чтобы добиться успеха в парном программировании, как отдельные члены команды, так и команда в целом, должны приложить определённые усилия.
Как член команды, будьте терпеливы с менее опытными разработчиками. Боритесь со страхом более опытных разработчиков. Поймите, что люди разные, и цените это. Помните о своих сильных и слабых сторонах, а также о сильных и слабых сторонах других членов команды. Вы можете быть удивлены, узнав, как многому вы можете научиться у своих коллег.
На уровне команды продвигайте парное программирование для распространения навыков и знаний. Вы должны решать задачи в парах и часто тасовать пары и задачи. Согласуйте правила ротации, и изменяйте их при необходимости. Мой опыт показывает, что вам не обязательно выполнять задачу до конца, прежде чем передавать её другой паре. Прерывание задачи для передачи её другой паре может показаться нелогичным, но я обнаружил, что это работает.
Существует множество ситуаций, когда состояние потока нарушается, а парное программирование помогает его сохранить:
1. Ослабление «фактора грузовика». Звучит цинично, но всё-таки: сколько и каких членов вашей команды придётся сбить грузовиком, чтобы команда не смогла успешно завершить проект? Другими словами, насколько ваша работа зависит от определённых членов команды? Являются ли их знания о проекте их личными или эти знания распределены между многими членами команды? Если вы ротируете задачи между парами, всегда будет кто-то, кто обладает нужными знаниями и сможет выполнить работу. В результате поток вашей команды менее подвержен "фактору грузовика".
2. Эффективное решение проблемы. Если вы занимаетесь парным программированием и сталкиваетесь со сложной проблемой, вам всегда есть с кем её обсудить. Такой диалог с большей вероятностью сдвинет вас с мёртвой точки, чем если бы вы застряли в одиночестве. При переходе задачи к другой паре ваше решение будет пересмотрено и проверено, поэтому не страшно, если вы изначально выбрали не самое оптимальное решение.
3. Плавная интеграция. Если ваша текущая задача включает вызов другого фрагмента кода, вы надеетесь, что имена методов, документация и тесты достаточно информативны, чтобы дать вам представление о том, что делает код. Если нет, объединение с разработчиком, который участвовал в написании этого кода, даст вам лучшее представление о нём и более быструю интеграцию с вашим кодом. Кроме того, вы сможете обсудить как можно улучшить именование, документацию и тесты.
4. Устойчивость к сбоям. Если что-то вас отвлекает: вам нужно ответить на телефонный звонок или email или поприсутствовать на встрече, - ваш партнёр по парному программированию может продолжать писать код. Когда вы вернётесь, ваш партнёр все еще будет в потоке, и вы быстро присоединитесь к нему.
5. Быстрое включение новичков. Благодаря парному программированию и правильной ротации пар и задач новички быстро знакомятся как с кодом, так и с другими членами команды.
В состоянии потока вы наиболее продуктивны, но оно очень уязвимо. Делайте всё возможное, чтобы поймать и удержаться в нём!
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Gudny Hauknes
День шестьсот девятнадцатый. #ЗаметкиНаПолях
Запуск Миграций EFCore из Вашего Кода
Все пользователи Entity Framework/EF Core знают, что запустить миграции из консоли или менеджера пакетов можно с помощью команды:
Миграция EF Core в C#
На самом деле все очень просто.
Проверка Ожидающих Миграций
Также может быть нужно проверить, есть ли ожидающие миграции, прежде чем пытаться их запустить. Например, может быть полезно узнать, в каком состоянии находится база данных, из панели администратора:
В некоторых случаях вам всё равно, когда выполняется миграция, вы просто хотите, перенести базу данных до запуска приложения. Это подойдёт для проектов, в которых время миграции базы данных не имеет значения или оно относительно небольшое. Например, для мало нагруженных веб-сайтов, расположенных на одном сервере. Для этого в .NET Core есть парадигма «Фильтров Запуска» (StartupFilter). Код будет примерно следующим:
Осталось добавить наш фильтр в контейнер DI в
Источник: https://dotnetcoretutorials.com/
Запуск Миграций EFCore из Вашего Кода
Все пользователи Entity Framework/EF Core знают, что запустить миграции из консоли или менеджера пакетов можно с помощью команды:
Update-DatabaseКроме того, можно использовать команду
dotnet ef
:dotnet ef database updateНо иногда может потребоваться запускать миграции по запросу из кода C#, например, вызвав конечную точку API из панели администратора сайта. Как правило, это было проблемой в более старых версиях Entity Framework, когда «версия» базы данных не совпадала с «версией» нужной EF Code. В этом случае «всё падало». В EF Core с этим меньше проблем, так как ваш код не рухнет, пока не попытается сделать что-то, что не может завершить (например, выбрать столбец, который ещё не существует). Но все же есть случаи, когда нужно развернуть код, протестировать его работу в промежуточной среде с действующей базой данных, а затем запустить миграцию базы данных по запросу.
Миграция EF Core в C#
На самом деле все очень просто.
var migrator = _context.Database.GetService<IMigrator>();Где
await migrator.MigrateAsync();
_context
– это контекст вашей базы данных.Проверка Ожидающих Миграций
Также может быть нужно проверить, есть ли ожидающие миграции, прежде чем пытаться их запустить. Например, может быть полезно узнать, в каком состоянии находится база данных, из панели администратора:
await _context.Database.GetPendingMigrationsAsync();Миграция При Запуске Приложения
В некоторых случаях вам всё равно, когда выполняется миграция, вы просто хотите, перенести базу данных до запуска приложения. Это подойдёт для проектов, в которых время миграции базы данных не имеет значения или оно относительно небольшое. Например, для мало нагруженных веб-сайтов, расположенных на одном сервере. Для этого в .NET Core есть парадигма «Фильтров Запуска» (StartupFilter). Код будет примерно следующим:
public class MigrationStartupFilter<TContext> :Фильтры запуска в .NET Core в основном похожи на фильтры в MVC. Они встраиваются в процесс запуска и выполняют код перед запуском приложения, причём только при запуске. Если вы когда-либо использовали
IStartupFilter where TContext : DbContext {
public Action<IApplicationBuilder>
Configure(Action<IApplicationBuilder> next) {
return app => {
using (var scope =
app.ApplicationServices.CreateScope()) {
foreach (var context in
scope.ServiceProvider.GetServices<TContext>()) {
context.Database.SetCommandTimeout(160);
context.Database.Migrate();
}
}
next(app);
};
}
}
Application_Start()
в global.asax
в .NET Framework, то это очень похоже.Осталось добавить наш фильтр в контейнер DI в
Startup.cs
:services.AddTransient<IStartupFilter,Здесь
MigrationStartupFilter<Context>>();
Context
- это контекст нашей базы данных.Источник: https://dotnetcoretutorials.com/
День шестьсот двадцатый. #Оффтоп #Курсы
Сегодня расскажу вам о нескольких предстоящих онлайн событиях, которые могут быть интересны разработчикам .NET. Пойдём в хронологическом порядке.
Решения SAP в Microsoft Azure
13 октября 2020г., начало в 10:00 (мск.)
Язык: русский
Темой вебинара станет переход на SAP S/4HANA в Microsoft Azure, который мгновенно обеспечивает компаниям гибкость и возможности для получения полезных сведений. Кроме того, такой переход упрощает будущее развитие инноваций и усовершенствование бизнес-процессов. Представители Microsoft и SAP расскажут, каким образом эти компании использовали SAP S/4HANA в Azure для трансформации собственных бизнес-процессов. Вы познакомитесь со всеми инфраструктурными предложениями от Microsoft Azure, которые базируются на новейших технологиях Intel и разработаны специально для SAP S/4HANA.
Pluralsight LIVE
13 октября 2020г., начало в 22:00 (мск.)
Язык: английский
Pluralsight LIVE - ежегодная конференция по технологическим навыкам, которая в этом году будет виртуальной. Microsoft представляет в этом году углублённое занятие, посвященное развитию навыков работы с Azure (Build your Azure skills with Microsoft Learn and Pluralsight). На этом занятии вы узнаете, как получить навыки, необходимые для решения задач современного облачного цифрового мира. Вы узнаете:
- что нового в Azure,
- как приобретение необходимых навыков в Azure может вам помочь использовать новейшие технологии,
- как работает совместное предложение от Microsoft Learn и Pluralsight,
- какие сертификаты подходят вам или вашей команде.
Основы проектирования защищённых облачных решений в Azure
16 октября 2020г., начало в 10:00 (мск.)
Язык: русский
Аспекты, связанные с безопасностью, нужно учитывать на протяжении всего жизненного цикла приложения — от разработки и реализации до развертывания и эксплуатации. Используйте подходы, описанные в Azure Well-Architected Framework для построения безопасных решений, способных противостоять современным киберугрозам.
В ходе этого вебинара вы узнаете об:
- Общих принципах проектирования защищённой облачной архитектуры.
- Ключевых рисках и требованиях безопасности.
- Подходах к проектированию защищённых систем управления удостоверениями и доступом, сетей, хранилищ и баз данных, приложений и служб.
- Практиках управления безопасностью.
State of .NET - .NET 5 Preview
28 октября 2020г.
Язык: английский
Очередной эпизод из серии вебинаров «State of .NET» от CODE Magazine. В нём расскажут о том, чего ожидать от предстоящего релиза .NET 5.
PS: Все вебинары бесплатны.
PPS: Pluralsight объявили неделю бесплатных курсов для новых подписчиков с 12 по 18 октября! Налетай!
Сегодня расскажу вам о нескольких предстоящих онлайн событиях, которые могут быть интересны разработчикам .NET. Пойдём в хронологическом порядке.
Решения SAP в Microsoft Azure
13 октября 2020г., начало в 10:00 (мск.)
Язык: русский
Темой вебинара станет переход на SAP S/4HANA в Microsoft Azure, который мгновенно обеспечивает компаниям гибкость и возможности для получения полезных сведений. Кроме того, такой переход упрощает будущее развитие инноваций и усовершенствование бизнес-процессов. Представители Microsoft и SAP расскажут, каким образом эти компании использовали SAP S/4HANA в Azure для трансформации собственных бизнес-процессов. Вы познакомитесь со всеми инфраструктурными предложениями от Microsoft Azure, которые базируются на новейших технологиях Intel и разработаны специально для SAP S/4HANA.
Pluralsight LIVE
13 октября 2020г., начало в 22:00 (мск.)
Язык: английский
Pluralsight LIVE - ежегодная конференция по технологическим навыкам, которая в этом году будет виртуальной. Microsoft представляет в этом году углублённое занятие, посвященное развитию навыков работы с Azure (Build your Azure skills with Microsoft Learn and Pluralsight). На этом занятии вы узнаете, как получить навыки, необходимые для решения задач современного облачного цифрового мира. Вы узнаете:
- что нового в Azure,
- как приобретение необходимых навыков в Azure может вам помочь использовать новейшие технологии,
- как работает совместное предложение от Microsoft Learn и Pluralsight,
- какие сертификаты подходят вам или вашей команде.
Основы проектирования защищённых облачных решений в Azure
16 октября 2020г., начало в 10:00 (мск.)
Язык: русский
Аспекты, связанные с безопасностью, нужно учитывать на протяжении всего жизненного цикла приложения — от разработки и реализации до развертывания и эксплуатации. Используйте подходы, описанные в Azure Well-Architected Framework для построения безопасных решений, способных противостоять современным киберугрозам.
В ходе этого вебинара вы узнаете об:
- Общих принципах проектирования защищённой облачной архитектуры.
- Ключевых рисках и требованиях безопасности.
- Подходах к проектированию защищённых систем управления удостоверениями и доступом, сетей, хранилищ и баз данных, приложений и служб.
- Практиках управления безопасностью.
State of .NET - .NET 5 Preview
28 октября 2020г.
Язык: английский
Очередной эпизод из серии вебинаров «State of .NET» от CODE Magazine. В нём расскажут о том, чего ожидать от предстоящего релиза .NET 5.
PS: Все вебинары бесплатны.
PPS: Pluralsight объявили неделю бесплатных курсов для новых подписчиков с 12 по 18 октября! Налетай!
День шестьсот двадцать первый. #BestPractices
6 Советов по Работе с Памятью в Приложениях .NET. Начало 1-2
Проблемы с памятью в большом .NET-приложении - своего рода тихий убийца. Как гипертония. Вы можете долго есть нездоровую пищу, игнорируя её, пока однажды не столкнетесь с серьезной проблемой. В случае программы .NET серьезной проблемой может быть высокое потребление памяти, проблемы с производительностью и сбои в работе.
Как узнать, правильно ли вы используете память? Что нужно делать, чтобы с ней не возникало проблем? Мы рассмотрим 6 рекомендаций, которые помогут сохранить память в рабочем состоянии и выявить проблемы, если они возникнут.
1. Объекты должны собираться сборщиком мусора как можно раньше
Чтобы ваша программа работала быстро, главная цель - как можно раньше уничтожать объекты. Чтобы понять, почему это важно, нужно иметь понятие о поколениях объектов в .NET. https://t.iss.one/NetDeveloperDiary/208 Когда объекты создаются с помощью new, они помещаются в куче в поколении 0. Это очень маленький объем памяти. Если после сборки мусора на них по-прежнему есть ссылки, они переводятся в поколение 1. Поколение 1 - это больший объем памяти. Если после следующей сборки мусора на них по-прежнему ссылаются, они переводятся в поколение 2.
Сборки мусора в поколении 0 производятся наиболее часто и очень быстро. Сборка в поколении 1 охватывает как пространства памяти как поколения 0, так и поколения 1, поэтому она более дорогая. Сборка в поколении 2 включает в себя всё пространство памяти, включая кучу больших объектов (LOH). Сборка мусора в поколении 2 очень дорогая. Сборщик мусора (GC) оптимизирован, чтобы проводить много сборок в поколении 0, меньше в поколении 1 и очень мало сборок в поколении 2. Но, если у вас много объектов, которые переходят в более высокое поколение, вы получите обратный эффект. Это приводит к нехватке памяти (также известной как давление на GC) и снижению производительности.
Кстати, размещение новых объектов обходится крайне дешево. Единственное, о чем нужно беспокоиться, - это сборка мусора.
Так как же держать объекты в младшем поколении? Просто убедитесь, что ссылки на них удаляются как можно раньше. Некоторые объекты, например одиночки, должны всегда оставаться в памяти. Ничего страшного, обычно это будут службы, которые в любом случае не потребляют много памяти.
2. Используйте кэширование… но осторожно
Такие механизмы, как кэширование, по определению проблемные. Это долговечные временные объекты, которые, скорее всего, будут переведены в поколение 2, хотя это плохо для сборщика мусора, но обычно стоит того, потому что кэширование действительно может улучшить производительность. Однако нужно следить за ним.
Один из способов уменьшить это давление на память - использовать изменяемые объекты кэша. Это означает, что вместо замены объекта кэша вы обновляете существующий объект. То есть у сборщика мусора будет меньше работы по продвижению объектов между поколениями и больше сборок мусора в поколениях 0 и 1.
Допустим, вы кэшируете товары интернет-магазина. У вас есть механизм кэширования, который хранит цены и информацию для фиксированного набора часто запрашиваемых товаров. Предположим, каждые 5 минут вы должны обновлять кэш из базы в случае изменения данных. Тогда вместо создания нового набора товаров просто изменяйте состояние существующих объектов.
Продолжение следует…
Источник: https://michaelscodingspot.com/application-memory-health/
6 Советов по Работе с Памятью в Приложениях .NET. Начало 1-2
Проблемы с памятью в большом .NET-приложении - своего рода тихий убийца. Как гипертония. Вы можете долго есть нездоровую пищу, игнорируя её, пока однажды не столкнетесь с серьезной проблемой. В случае программы .NET серьезной проблемой может быть высокое потребление памяти, проблемы с производительностью и сбои в работе.
Как узнать, правильно ли вы используете память? Что нужно делать, чтобы с ней не возникало проблем? Мы рассмотрим 6 рекомендаций, которые помогут сохранить память в рабочем состоянии и выявить проблемы, если они возникнут.
1. Объекты должны собираться сборщиком мусора как можно раньше
Чтобы ваша программа работала быстро, главная цель - как можно раньше уничтожать объекты. Чтобы понять, почему это важно, нужно иметь понятие о поколениях объектов в .NET. https://t.iss.one/NetDeveloperDiary/208 Когда объекты создаются с помощью new, они помещаются в куче в поколении 0. Это очень маленький объем памяти. Если после сборки мусора на них по-прежнему есть ссылки, они переводятся в поколение 1. Поколение 1 - это больший объем памяти. Если после следующей сборки мусора на них по-прежнему ссылаются, они переводятся в поколение 2.
Сборки мусора в поколении 0 производятся наиболее часто и очень быстро. Сборка в поколении 1 охватывает как пространства памяти как поколения 0, так и поколения 1, поэтому она более дорогая. Сборка в поколении 2 включает в себя всё пространство памяти, включая кучу больших объектов (LOH). Сборка мусора в поколении 2 очень дорогая. Сборщик мусора (GC) оптимизирован, чтобы проводить много сборок в поколении 0, меньше в поколении 1 и очень мало сборок в поколении 2. Но, если у вас много объектов, которые переходят в более высокое поколение, вы получите обратный эффект. Это приводит к нехватке памяти (также известной как давление на GC) и снижению производительности.
Кстати, размещение новых объектов обходится крайне дешево. Единственное, о чем нужно беспокоиться, - это сборка мусора.
Так как же держать объекты в младшем поколении? Просто убедитесь, что ссылки на них удаляются как можно раньше. Некоторые объекты, например одиночки, должны всегда оставаться в памяти. Ничего страшного, обычно это будут службы, которые в любом случае не потребляют много памяти.
2. Используйте кэширование… но осторожно
Такие механизмы, как кэширование, по определению проблемные. Это долговечные временные объекты, которые, скорее всего, будут переведены в поколение 2, хотя это плохо для сборщика мусора, но обычно стоит того, потому что кэширование действительно может улучшить производительность. Однако нужно следить за ним.
Один из способов уменьшить это давление на память - использовать изменяемые объекты кэша. Это означает, что вместо замены объекта кэша вы обновляете существующий объект. То есть у сборщика мусора будет меньше работы по продвижению объектов между поколениями и больше сборок мусора в поколениях 0 и 1.
Допустим, вы кэшируете товары интернет-магазина. У вас есть механизм кэширования, который хранит цены и информацию для фиксированного набора часто запрашиваемых товаров. Предположим, каждые 5 минут вы должны обновлять кэш из базы в случае изменения данных. Тогда вместо создания нового набора товаров просто изменяйте состояние существующих объектов.
Продолжение следует…
Источник: https://michaelscodingspot.com/application-memory-health/
День шестьсот двадцать второй. #BestPractices
6 Советов по Работе с Памятью в Приложениях .NET. Продолжение 3-4
Начало
3. Следите за процентом времени, затрачиваемым на сборку мусора
Если вы хотите узнать, насколько сборка мусора влияет на время выполнения программы, это довольно легко сделать. Просто посмотрите на счётчик производительности (Performance Monitor) .NET CLR Memory | % Time in GC. Он покажет, какой процент времени выполнения используется сборщиком мусора. Есть много инструментов для просмотра счетчиков производительности. В Windows вы можете использовать PerfMon. В Linux вы можете использовать dotnet-trace.
Далее приведены пара «магических чисел», но относитесь к ним с подозрением, потому что у каждого приложения свой контекст. Для большого приложения 10% времени в GC – это, скорее всего, нормальный процент. 20% времени в сборке мусора - это предел, а большее число означает, что у вас проблемы.
4. Следите за сборками мусора в поколении 2
Помимо процента времени на сборку мусора, другой полезной метрикой является количество сборок мусора в поколении 2. А точнее относительное количество сборок мусора в поколении 2. Задача состоит в том, чтобы их было как можно меньше. Учтите, что это полные сборки мусора во всей куче памяти. Они фактически замораживают все потоки приложения, пока сборщик мусора всё собирает.
Нельзя точно сказать, сколько сборок в поколении 2 у вас должно быть. Просто следите за их количеством, и, если этот показатель возрастает, вероятно, вы добавили какое-то нехорошее поведение. Вы можете посмотреть это число с помощью счётчика производительности .NET CLR Memory | % Gen 2 Collections (см. картинку ниже).
Окончание следует…
Источник: https://michaelscodingspot.com/application-memory-health/
6 Советов по Работе с Памятью в Приложениях .NET. Продолжение 3-4
Начало
3. Следите за процентом времени, затрачиваемым на сборку мусора
Если вы хотите узнать, насколько сборка мусора влияет на время выполнения программы, это довольно легко сделать. Просто посмотрите на счётчик производительности (Performance Monitor) .NET CLR Memory | % Time in GC. Он покажет, какой процент времени выполнения используется сборщиком мусора. Есть много инструментов для просмотра счетчиков производительности. В Windows вы можете использовать PerfMon. В Linux вы можете использовать dotnet-trace.
Далее приведены пара «магических чисел», но относитесь к ним с подозрением, потому что у каждого приложения свой контекст. Для большого приложения 10% времени в GC – это, скорее всего, нормальный процент. 20% времени в сборке мусора - это предел, а большее число означает, что у вас проблемы.
4. Следите за сборками мусора в поколении 2
Помимо процента времени на сборку мусора, другой полезной метрикой является количество сборок мусора в поколении 2. А точнее относительное количество сборок мусора в поколении 2. Задача состоит в том, чтобы их было как можно меньше. Учтите, что это полные сборки мусора во всей куче памяти. Они фактически замораживают все потоки приложения, пока сборщик мусора всё собирает.
Нельзя точно сказать, сколько сборок в поколении 2 у вас должно быть. Просто следите за их количеством, и, если этот показатель возрастает, вероятно, вы добавили какое-то нехорошее поведение. Вы можете посмотреть это число с помощью счётчика производительности .NET CLR Memory | % Gen 2 Collections (см. картинку ниже).
Окончание следует…
Источник: https://michaelscodingspot.com/application-memory-health/
День шестьсот двадцать третий. #BestPractices
6 Советов по Работе с Памятью в Приложениях .NET. Окончание 5-6
Начало
Продолжение
5. Следите за стабильностью потребления памяти.
Рассмотрим обычное состояние приложения. Некоторые события происходят постоянно. Это может быть сервер, обслуживающий запросы, служба, извлекающая сообщения из очереди, настольное приложение с множеством форм. В это время ваше приложение постоянно создаёт новые объекты, выполняет какие-то операции, а затем освобождает эти объекты и возвращается в нормальное состояние. Это означает, что потребление памяти должно быть более или менее одинаковым в долгосрочной перспективе. Конечно, оно может возрастать во время пиковых нагрузок или интенсивной обработки данных, но после этого оно должно возвращаться в нормальное состояние.
Но если у вас есть опыт подобного отслеживания приложений, вы, вероятно, знаете, что иногда объём потребляемой памяти со временем увеличивается. Среднее потребление медленно растёт, хотя по логике этого не должно быть. Причина такого поведения почти всегда - утечки памяти. Это происходит, когда объект больше не используется, но по какой-то причине на него всё ещё ссылаются и, следовательно, он никогда не попадает в сборку мусора.
Если операция вызывает утечку объектов, каждая такая операция увеличивает потребление памяти. Когда проходит достаточно времени, потребление памяти приближается к своему пределу. В 32-битном процессе этот предел составляет 4 ГБ. В 64-битном процессе это зависит от ограничений компьютера. Когда потребление памяти приближаемся к пределу, сборщик мусора паникует. Он начинает запускать полную сборку мусора при каждом выделении памяти, чтобы не исчерпать её совсем. Это может замедлить ваше приложение до скорости улитки. Однако в итоге потребление памяти таки достигает предела, и приложение аварийно завершает работу, выбрасывая OutOfMemoryException.
Чтобы убедиться, что с вашим приложением такого не случится, активно отслеживайте потребление памяти с течением времени. Лучший способ сделать это - посмотреть на счетчик производительности Process | Private Bytes. Вы можете легко сделать это с помощью Process Explorer или PerfMon.
6. Периодически ищите утечки памяти
Виновник проблем с памятью №1, без сомнения, - утечки памяти. Их легко вызвать, их можно долго игнорировать, но в итоге они наносят непоправимый ущерб. Устранять утечки памяти на этапе, когда ваше приложение систематически падает, очень сложно. Вам придётся в спешке менять код, что может приводить к разнообразным ошибкам. Поэтому очень важно вовремя вносить коррективы и избегать утечек памяти.
Нереально ожидать, что ваша команда никогда не их допустит утечек памяти. И нецелесообразно проверять их во всем приложении при каждом изменении. Вместо этого введите практику периодической проверки на утечки памяти. Это может быть еженедельно, ежемесячно или ежеквартально, как вам удобно.
Другой вариант проверять утечки памяти каждый раз, когда вы замечаете увеличение объема потребляемой памяти (как описано в совете №5). Но проблема в том, что даже небольшие утечки могут вызывать множество проблем. Например, у вас могут быть объекты, которые должны были быть собраны GC, но остаются живыми и в них продолжает исполняться какой-то код, что приводит к неправильному поведению.
Лучший способ обнаружить и исправить утечки памяти - использовать профилировщик памяти.
Источник: https://michaelscodingspot.com/application-memory-health/
6 Советов по Работе с Памятью в Приложениях .NET. Окончание 5-6
Начало
Продолжение
5. Следите за стабильностью потребления памяти.
Рассмотрим обычное состояние приложения. Некоторые события происходят постоянно. Это может быть сервер, обслуживающий запросы, служба, извлекающая сообщения из очереди, настольное приложение с множеством форм. В это время ваше приложение постоянно создаёт новые объекты, выполняет какие-то операции, а затем освобождает эти объекты и возвращается в нормальное состояние. Это означает, что потребление памяти должно быть более или менее одинаковым в долгосрочной перспективе. Конечно, оно может возрастать во время пиковых нагрузок или интенсивной обработки данных, но после этого оно должно возвращаться в нормальное состояние.
Но если у вас есть опыт подобного отслеживания приложений, вы, вероятно, знаете, что иногда объём потребляемой памяти со временем увеличивается. Среднее потребление медленно растёт, хотя по логике этого не должно быть. Причина такого поведения почти всегда - утечки памяти. Это происходит, когда объект больше не используется, но по какой-то причине на него всё ещё ссылаются и, следовательно, он никогда не попадает в сборку мусора.
Если операция вызывает утечку объектов, каждая такая операция увеличивает потребление памяти. Когда проходит достаточно времени, потребление памяти приближается к своему пределу. В 32-битном процессе этот предел составляет 4 ГБ. В 64-битном процессе это зависит от ограничений компьютера. Когда потребление памяти приближаемся к пределу, сборщик мусора паникует. Он начинает запускать полную сборку мусора при каждом выделении памяти, чтобы не исчерпать её совсем. Это может замедлить ваше приложение до скорости улитки. Однако в итоге потребление памяти таки достигает предела, и приложение аварийно завершает работу, выбрасывая OutOfMemoryException.
Чтобы убедиться, что с вашим приложением такого не случится, активно отслеживайте потребление памяти с течением времени. Лучший способ сделать это - посмотреть на счетчик производительности Process | Private Bytes. Вы можете легко сделать это с помощью Process Explorer или PerfMon.
6. Периодически ищите утечки памяти
Виновник проблем с памятью №1, без сомнения, - утечки памяти. Их легко вызвать, их можно долго игнорировать, но в итоге они наносят непоправимый ущерб. Устранять утечки памяти на этапе, когда ваше приложение систематически падает, очень сложно. Вам придётся в спешке менять код, что может приводить к разнообразным ошибкам. Поэтому очень важно вовремя вносить коррективы и избегать утечек памяти.
Нереально ожидать, что ваша команда никогда не их допустит утечек памяти. И нецелесообразно проверять их во всем приложении при каждом изменении. Вместо этого введите практику периодической проверки на утечки памяти. Это может быть еженедельно, ежемесячно или ежеквартально, как вам удобно.
Другой вариант проверять утечки памяти каждый раз, когда вы замечаете увеличение объема потребляемой памяти (как описано в совете №5). Но проблема в том, что даже небольшие утечки могут вызывать множество проблем. Например, у вас могут быть объекты, которые должны были быть собраны GC, но остаются живыми и в них продолжает исполняться какой-то код, что приводит к неправильному поведению.
Лучший способ обнаружить и исправить утечки памяти - использовать профилировщик памяти.
Источник: https://michaelscodingspot.com/application-memory-health/
День шестьсот двадцать четвёртый. #Книги
Несколько человек спрашивали в чате и в личке, какие книжки почитать, поэтому сделаю тут небольшую подборку.
Следующие книги распространяются свободно в PDF.
1. "Learn Azure in a Month of Lunches"
Быстрый старт в Azure в 21 уроке. В этой книге более 350 страниц, но лишь краткое описание всего того, что вы можете делать в Azure. В ней выборочно представлено только самое главное из того, чем вам может помочь Azure при создании приложений. Книга не охватывает все из более сотни сервисов Azure и не дает исчерпывающих подробностей о сервисах, которые включены в неё. Вместо этого она фокусируется на основных моментах некоторых основных сервисов и показывает примеры, как их безопасно соединить, а также знакомит с возможностями того, что вы можете создать в Azure.
Далее пара книг, которые представляют собой скомпилированную документацию Майкрософт:
2. "Architecting Modern Web Applications with ASP.NET Core and Azure"
В этом руководстве представлены комплексные рекомендации по созданию монолитных веб-приложений с использованием ASP.NET Core и Azure. Здесь понятие «монолитный» означает, что эти приложения развёртываются как единое целое, а не как набор взаимодействующих сервисов и приложений.
3. ".NET Microservices. Architecture for Containerized .NET Applications"
В противовес предыдущей книге, это введение в разработку приложений на основе микросервисов и управление ими с помощью контейнеров. Здесь обсуждаются подходы к архитектурному проектированию и реализации с использованием контейнеров .NET Core и Docker.
Ещё несколько недавно вышедших книг, которые советовали в чате. Их в PDF выкладывать не буду, чтобы не пиратить, мы тут люди приличные))) А, если очень хочется, гуглить все умеют, надеюсь ;)
4. Jason Alls "Clean Code in C#", Packt Publishing, 2020
Советы по рефакторингу легаси кода C# и улучшению производительности приложения применяя передовые практики. Вы узнаете, как определить проблемный код, который не обеспечивает читабельность, поддерживаемость и расширяемость. А также о различных инструментах, паттернах и способах рефакторинга кода, чтобы сделать его чистым.
5. Stephen Cleary "Concurrency in C# Cookbook: Asynchronous, Parallel, and Multithreaded Programming" 2nd Edition. O’Reilly, 2019.
Параллелизм - ключевой аспект красивого программного обеспечения. На протяжении десятилетий параллелизм был возможен, но труден: параллельное ПО было сложно писать, трудно отлаживать и поддерживать. В результате многие разработчики выбирали более простой путь и избегали параллелизма. Однако с библиотеками и языковыми функциями, доступными для современных программ .NET, параллелизм стал намного проще. Раньше параллельное программирование было прерогативой экспертов, в наши дни каждый разработчик может (и должен) использовать параллелизм.
Несколько человек спрашивали в чате и в личке, какие книжки почитать, поэтому сделаю тут небольшую подборку.
Следующие книги распространяются свободно в PDF.
1. "Learn Azure in a Month of Lunches"
Быстрый старт в Azure в 21 уроке. В этой книге более 350 страниц, но лишь краткое описание всего того, что вы можете делать в Azure. В ней выборочно представлено только самое главное из того, чем вам может помочь Azure при создании приложений. Книга не охватывает все из более сотни сервисов Azure и не дает исчерпывающих подробностей о сервисах, которые включены в неё. Вместо этого она фокусируется на основных моментах некоторых основных сервисов и показывает примеры, как их безопасно соединить, а также знакомит с возможностями того, что вы можете создать в Azure.
Далее пара книг, которые представляют собой скомпилированную документацию Майкрософт:
2. "Architecting Modern Web Applications with ASP.NET Core and Azure"
В этом руководстве представлены комплексные рекомендации по созданию монолитных веб-приложений с использованием ASP.NET Core и Azure. Здесь понятие «монолитный» означает, что эти приложения развёртываются как единое целое, а не как набор взаимодействующих сервисов и приложений.
3. ".NET Microservices. Architecture for Containerized .NET Applications"
В противовес предыдущей книге, это введение в разработку приложений на основе микросервисов и управление ими с помощью контейнеров. Здесь обсуждаются подходы к архитектурному проектированию и реализации с использованием контейнеров .NET Core и Docker.
Ещё несколько недавно вышедших книг, которые советовали в чате. Их в PDF выкладывать не буду, чтобы не пиратить, мы тут люди приличные))) А, если очень хочется, гуглить все умеют, надеюсь ;)
4. Jason Alls "Clean Code in C#", Packt Publishing, 2020
Советы по рефакторингу легаси кода C# и улучшению производительности приложения применяя передовые практики. Вы узнаете, как определить проблемный код, который не обеспечивает читабельность, поддерживаемость и расширяемость. А также о различных инструментах, паттернах и способах рефакторинга кода, чтобы сделать его чистым.
5. Stephen Cleary "Concurrency in C# Cookbook: Asynchronous, Parallel, and Multithreaded Programming" 2nd Edition. O’Reilly, 2019.
Параллелизм - ключевой аспект красивого программного обеспечения. На протяжении десятилетий параллелизм был возможен, но труден: параллельное ПО было сложно писать, трудно отлаживать и поддерживать. В результате многие разработчики выбирали более простой путь и избегали параллелизма. Однако с библиотеками и языковыми функциями, доступными для современных программ .NET, параллелизм стал намного проще. Раньше параллельное программирование было прерогативой экспертов, в наши дни каждый разработчик может (и должен) использовать параллелизм.
Если_бы_программисты_строили_дома.pdf
96.6 KB
День шестьсот двадцать пятый. #Юмор
Олды тут? Вон чего откопал в старых документах. Помню, дико популярны были такие «Хроники» в начале 2000х. Решил молодость вспомнить)))
Если понравится, пишите в комментариях, ещё выложу чего-нибудь. Хорошей пятницы.
https://telegra.ph/Esli-by-programmisty-stroili-doma-10-16
Олды тут? Вон чего откопал в старых документах. Помню, дико популярны были такие «Хроники» в начале 2000х. Решил молодость вспомнить)))
Если понравится, пишите в комментариях, ещё выложу чего-нибудь. Хорошей пятницы.
https://telegra.ph/Esli-by-programmisty-stroili-doma-10-16
День шестьсот двадцать шестой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
63. Используйте Типы Специфичные для Домена Вместо Примитивных
23 сентября 1999г. Mars Climate Orbiter стоимостью 327,6 млн долларов был потерян при выходе на орбиту Марса из-за ошибки в программном обеспечении на Земле. Позднее выяснили, что перепутали единицы измерения. Программное обеспечение на Земле, поставленное компанией Локхид-Мартин, подавало команды аппарату, используя британские единицы силы фунты, в то время как космический корабль, сделанный в НАСА, ожидал принятые в системе СИ ньютоны. Из-за этого наземная станция недооценила мощность двигателей космического корабля почти в 4,5 раза. Эта неудача считается одной из причин окончательного и полного перехода NASA на метрическую систему, объявленного в 2007 году.
Это один из многих примеров сбоев программного обеспечения, которые можно было бы предотвратить, если бы применялась более строгая и специфичная для домена типизация. Это также объясняет наличие многих функций языка Ada, одной из основных целей разработки которого было создание программного обеспечения с высокими требованиями к безопасности. В Ada есть строгая типизация со статической проверкой как для примитивных, так и для определённых пользователем типов.
Если
а
Разработчики, работающие в менее требовательных к безопасности доменах, также могут извлечь выгоду из применения более специфичной для предметной области типизации, где в противном случае они могли бы продолжать использовать примитивные типы данных, такие как строки и числа с плавающей точкой. В Java, C++, C#, Python и других современных языках абстрактный тип данных известен как класс. Использование таких классов, как
- Код становится более читабельным, поскольку он выражает намерения в терминах домена, а не в виде общих Float или String.
- Код становится более тестируемым, поскольку легче тестировать инкапсулированное поведение.
- Упрощается повторное использование в приложениях и системах.
Этот подход одинаково применим как в статически, так и в динамически типизированных языках. Единственное отличие состоит в том, что разработчики, использующие языки со статической типизацией, получают некоторую помощь от компилятора, в то время как разработчики, использующие языки с динамической типизацией, с должны больше полагаться на модульные тесты. Стиль проверки может быть разным, но мотивация и стиль выражений - нет.
Мораль в том, что для повышения качества вашего программного обеспечения стоит использовать типы, специфичные для предметной области.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Einar Landre
97 Вещей, Которые Должен Знать Каждый Программист
63. Используйте Типы Специфичные для Домена Вместо Примитивных
23 сентября 1999г. Mars Climate Orbiter стоимостью 327,6 млн долларов был потерян при выходе на орбиту Марса из-за ошибки в программном обеспечении на Земле. Позднее выяснили, что перепутали единицы измерения. Программное обеспечение на Земле, поставленное компанией Локхид-Мартин, подавало команды аппарату, используя британские единицы силы фунты, в то время как космический корабль, сделанный в НАСА, ожидал принятые в системе СИ ньютоны. Из-за этого наземная станция недооценила мощность двигателей космического корабля почти в 4,5 раза. Эта неудача считается одной из причин окончательного и полного перехода NASA на метрическую систему, объявленного в 2007 году.
Это один из многих примеров сбоев программного обеспечения, которые можно было бы предотвратить, если бы применялась более строгая и специфичная для домена типизация. Это также объясняет наличие многих функций языка Ada, одной из основных целей разработки которого было создание программного обеспечения с высокими требованиями к безопасности. В Ada есть строгая типизация со статической проверкой как для примитивных, так и для определённых пользователем типов.
Если
VelocityInKnots
представляет собой Float
в диапазоне от 0.0
до 500.00
,а
DistanceInNauticalMiles
- Float
от 0.0
до 3000.00
, то следующий код:SomeNumber : Float;приведёт к ошибке компиляции.
SomeNumber := DistanceInNauticalMiles + VelocityInKnots;
Разработчики, работающие в менее требовательных к безопасности доменах, также могут извлечь выгоду из применения более специфичной для предметной области типизации, где в противном случае они могли бы продолжать использовать примитивные типы данных, такие как строки и числа с плавающей точкой. В Java, C++, C#, Python и других современных языках абстрактный тип данных известен как класс. Использование таких классов, как
VelocityInKnots
и DistanceInNauticalMiles
, серьёзно повысит качество кода:- Код становится более читабельным, поскольку он выражает намерения в терминах домена, а не в виде общих Float или String.
- Код становится более тестируемым, поскольку легче тестировать инкапсулированное поведение.
- Упрощается повторное использование в приложениях и системах.
Этот подход одинаково применим как в статически, так и в динамически типизированных языках. Единственное отличие состоит в том, что разработчики, использующие языки со статической типизацией, получают некоторую помощь от компилятора, в то время как разработчики, использующие языки с динамической типизацией, с должны больше полагаться на модульные тесты. Стиль проверки может быть разным, но мотивация и стиль выражений - нет.
Мораль в том, что для повышения качества вашего программного обеспечения стоит использовать типы, специфичные для предметной области.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Einar Landre
День шестьсот двадцать седьмой. #Оффтоп
Вот вам тема для воскресного обсуждения: «Как получить повышение в должности разработчика?»
Ниже приведу мой пересказ видео с ютуба (ссылка внизу). Все эти советы, конечно, элементарные, сферические в вакууме, взяты на примере западного рынка, поэтому не учитывают нашу специфику, и вообще, вроде бы проще переходить с повышением в другую компанию, и тэдэ, и тэпэ. Но это просто в качестве затравки.
1. Узнайте правила или критерии для повышения
Многие разработчики тратят огромные усилия, выполняя (и хорошо выполняя) работу, которая не расценивается в компании, как критерий для повышения. Если вы исправляете множество мелких недочётов в ПО, вы можете считать, что по количеству исправленных тикетов вы чемпион, но в компании могут цениться совсем другие качества. В гигантах, вроде FAGMA, есть чёткая градация уровней и список требований к квалификации на каждом уровне. В небольших компаниях вы можете прямо спросить об этом тимлида, начальника отдела или коллегу, которого недавно повысили.
2. Работайте на уровне, которого хотите достичь при повышении
Нет смысла быть высококлассным джуном. Нужно работать на уровне, требуемом от мидла, чтобы команда видела, что вы по факту превосходите уровень джуна. По мере роста вашей квалификации вам должно требоваться гораздо меньше подробностей в описании задачи, чтобы её выполнить. Джуну может требоваться описание, какие классы или таблицы БД создать, как реализовать тот или иной функционал. Более опытные разработчики принимают архитектурные и дизайнерские решения самостоятельно.
3. Ищите возможности
Чем выше должность в иерархии, тем объёмнее и серьёзнее задачи, которые выполняет специалист. Но и количество таких задач меньше. Как же их заполучить? Посещайте собрания, говорите с коллегами и менеджерами, предлагайте свои идеи. Проще говоря, повышайте софт скилы.
4. Не упускайте возможности
Не бойтесь нового, не бойтесь браться за незнакомые или сложные проекты (хотя, трезво оценивая свои силы, конечно). Но, если уж взялись, доводите дело до конца.
5. Дайте знать окружающим о своей работе
Этого разработчики обычно не любят, но без этого никуда. Ваши коллеги, а, главное, ваши начальники должны знать о том, что вы делаете и какие усилия вы прикладываете. Многие путают это с офисными интригами, подсиживанием коллег и присваиванием чужих результатов. Нет, не будьте такими. Здесь речь идёт исключительно о ваших заслугах и вашем вкладе в общее дело. Убедитесь, что ваши начальники в курсе. А это означает, что нужно поддерживать с ними связь и хорошие отношения. Снова софт скиллз.
6. Усердно работайте
«Спасибо, кэп», - скажете вы. Но факт остаётся фактом. Повышение – это не только «лычка» и больше денег, но и больше работы и ответственности. Повышения «за выслугу лет», конечно, случаются, но это скорее исключения.
В комментариях предлагаю вам описать свой опыт. Как вам удалось добиться повышения? Это было в крупной или небольшой компании? Какими советами вы можете поделиться?
Источник: https://www.youtube.com/watch?v=vm4OsDPK1gA
Вот вам тема для воскресного обсуждения: «Как получить повышение в должности разработчика?»
Ниже приведу мой пересказ видео с ютуба (ссылка внизу). Все эти советы, конечно, элементарные, сферические в вакууме, взяты на примере западного рынка, поэтому не учитывают нашу специфику, и вообще, вроде бы проще переходить с повышением в другую компанию, и тэдэ, и тэпэ. Но это просто в качестве затравки.
1. Узнайте правила или критерии для повышения
Многие разработчики тратят огромные усилия, выполняя (и хорошо выполняя) работу, которая не расценивается в компании, как критерий для повышения. Если вы исправляете множество мелких недочётов в ПО, вы можете считать, что по количеству исправленных тикетов вы чемпион, но в компании могут цениться совсем другие качества. В гигантах, вроде FAGMA, есть чёткая градация уровней и список требований к квалификации на каждом уровне. В небольших компаниях вы можете прямо спросить об этом тимлида, начальника отдела или коллегу, которого недавно повысили.
2. Работайте на уровне, которого хотите достичь при повышении
Нет смысла быть высококлассным джуном. Нужно работать на уровне, требуемом от мидла, чтобы команда видела, что вы по факту превосходите уровень джуна. По мере роста вашей квалификации вам должно требоваться гораздо меньше подробностей в описании задачи, чтобы её выполнить. Джуну может требоваться описание, какие классы или таблицы БД создать, как реализовать тот или иной функционал. Более опытные разработчики принимают архитектурные и дизайнерские решения самостоятельно.
3. Ищите возможности
Чем выше должность в иерархии, тем объёмнее и серьёзнее задачи, которые выполняет специалист. Но и количество таких задач меньше. Как же их заполучить? Посещайте собрания, говорите с коллегами и менеджерами, предлагайте свои идеи. Проще говоря, повышайте софт скилы.
4. Не упускайте возможности
Не бойтесь нового, не бойтесь браться за незнакомые или сложные проекты (хотя, трезво оценивая свои силы, конечно). Но, если уж взялись, доводите дело до конца.
5. Дайте знать окружающим о своей работе
Этого разработчики обычно не любят, но без этого никуда. Ваши коллеги, а, главное, ваши начальники должны знать о том, что вы делаете и какие усилия вы прикладываете. Многие путают это с офисными интригами, подсиживанием коллег и присваиванием чужих результатов. Нет, не будьте такими. Здесь речь идёт исключительно о ваших заслугах и вашем вкладе в общее дело. Убедитесь, что ваши начальники в курсе. А это означает, что нужно поддерживать с ними связь и хорошие отношения. Снова софт скиллз.
6. Усердно работайте
«Спасибо, кэп», - скажете вы. Но факт остаётся фактом. Повышение – это не только «лычка» и больше денег, но и больше работы и ответственности. Повышения «за выслугу лет», конечно, случаются, но это скорее исключения.
В комментариях предлагаю вам описать свой опыт. Как вам удалось добиться повышения? Это было в крупной или небольшой компании? Какими советами вы можете поделиться?
Источник: https://www.youtube.com/watch?v=vm4OsDPK1gA
День шестьсот двадцать восьмой. #ЗаметкиНаПолях #AsyncAwaitFAQ
Самые Частые Ошибки при Работе с async/await. Начало 1-4
1. Лишний async/await
Использование ключевых слов async/await приводит к неявному выделению памяти под конечный автомат, который отвечает за организацию асинхронных вызовов. Когда ожидаемое выражение является единственным или последним оператором в функции, его можно пропустить. Однако с этим есть несколько проблем, о которых вам следует знать.
❌ Неверно
Если мы используем асинхронный код, мы всегда должны использовать асинхронные методы, если они существуют. Многие API предлагают асинхронные аналоги своих хорошо известных синхронных методов.
❌ Неверно
Есть две причины, по которым
- Вызывающий код не может ожидать метод
- Невозможно обработать исключение, вызванное этим методом. Если возникает исключение, ваш процесс падает!
Вы всегда должны использовать
❌ Неверно
Если передать асинхронную лямбда-функцию в качестве аргумента типа
- изменить тип параметра с
- реализовать этот делегат синхронно.
Стоит отметить, что некоторые API-интерфейсы уже предоставляют аналоги своих методов, которые принимают
Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/
Самые Частые Ошибки при Работе с async/await. Начало 1-4
1. Лишний async/await
Использование ключевых слов async/await приводит к неявному выделению памяти под конечный автомат, который отвечает за организацию асинхронных вызовов. Когда ожидаемое выражение является единственным или последним оператором в функции, его можно пропустить. Однако с этим есть несколько проблем, о которых вам следует знать.
❌ Неверно
async Task DoSomethingAsync(){✅ Верно
await Task.Yield();
}
Task DoSomethingAsync() {2. Вызов синхронного метода внутри асинхронного метода
return Task.Yield();
}
Если мы используем асинхронный код, мы всегда должны использовать асинхронные методы, если они существуют. Многие API предлагают асинхронные аналоги своих хорошо известных синхронных методов.
❌ Неверно
async Task DoAsync(Stream file, byte[] buffer) {✅ Верно
file.Read(buffer, 0, 10);
}
async Task DoAsync(Stream file, byte[] buffer) {3. Использование async void
await file.ReadAsync(buffer, 0, 10);
}
Есть две причины, по которым
async void
вреден:- Вызывающий код не может ожидать метод
async void
.- Невозможно обработать исключение, вызванное этим методом. Если возникает исключение, ваш процесс падает!
Вы всегда должны использовать
async Task
вместо async void
, если только это не обработчик событий, но тогда вы должны гарантировать себе, что метод не выбросит исключения.❌ Неверно
async void DoSomethingAsync() {✅ Верно
await Task.Yield();
}
async Task DoSomethingAsync() {4. Неподдерживаемые асинхронные делегаты
await Task.Yield();
}
Если передать асинхронную лямбда-функцию в качестве аргумента типа
Action
, компилятор сгенерирует метод async void
, недостатки которого были описаны выше. Есть два решения этой проблемы:- изменить тип параметра с
Action
на Func<Task>
, - реализовать этот делегат синхронно.
Стоит отметить, что некоторые API-интерфейсы уже предоставляют аналоги своих методов, которые принимают
Func<Task>.
void DoSomething() {
Callback(async() => {
await Task.Yield();
});
}
❌ Неверноvoid Callback(Action action){…}✅ Верно
void Callback(Func<Task> action){…}Продолжение следует…
Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/
👍1