This media is not supported in your browser
VIEW IN TELEGRAM
День 1678. #ЧтоНовенького
Превью Изображений в Visual Studio
Любой разработчик часто работает с изображениями: локальными, размещёнными в Интернете или в общих сетевых ресурсах, либо существующими только в виде строк в кодировке Base64. В коде мы ссылаемся на них по-разному, но всегда как на строковые значения, которые не показывают нам, как выглядит изображение.
Для Visual Studio теперь есть расширение Image Preview от Мэдса Кристенсена. Когда указатель мыши наводится на ссылку на изображение, появляется всплывающая подсказка, показывающая визуализированное изображение. Поддерживаются GIF, PNG, JPG, ICO и SVG в следующих случаях:
- Абсолютный URL (
- Относительный URL (
- Путь к файлу (
- URI данных (
- URI пакета (
При относительной ссылке, например
Источник
Превью Изображений в Visual Studio
Любой разработчик часто работает с изображениями: локальными, размещёнными в Интернете или в общих сетевых ресурсах, либо существующими только в виде строк в кодировке Base64. В коде мы ссылаемся на них по-разному, но всегда как на строковые значения, которые не показывают нам, как выглядит изображение.
Для Visual Studio теперь есть расширение Image Preview от Мэдса Кристенсена. Когда указатель мыши наводится на ссылку на изображение, появляется всплывающая подсказка, показывающая визуализированное изображение. Поддерживаются GIF, PNG, JPG, ICO и SVG в следующих случаях:
- Абсолютный URL (
http
, https
и ftp
)- Относительный URL (
./
, ../
и /
)- Путь к файлу (
c:\
, c:/
, \
и /
)- URI данных (
data:image/png;base64,…
)- URI пакета (
pack://application:,,,/Images/MyImage.png
)При относительной ссылке, например
/file.png
, расширение попытается разрешить его относительно корневой папки проекта или папки wwwroot в случае проектов ASP.NET.Источник
👍13
День 1679. #ЗаметкиНаПолях #Debugging
Правила Отладки: Понимание Системы
Решение проблем без подлинного их понимания может создать ненужные трудности и поставить под угрозу качество программы. Поэтому крайне важно тщательно понять систему, прежде чем пытаться её исправить. Чтобы добиться этого, триангулируйте дефект, протестировав сценарии, которые должны воспроизводить ошибку, и те, которые не должны воспроизводить её. Продолжайте этот процесс до тех пор, пока не поймете проблему достаточно хорошо, чтобы точно предсказать её возникновение в каждом случае.
1. Читайте документацию
Понимание предполагаемого поведения системы, её конструкции, а иногда и обоснования её конструкции, очень важно. Когда отсутствует понимание какого-либо конкретного аспекта системы, это часто становится основной причиной проблем.
Часто люди пытаются устранить проблемы, не вникая в документацию, просматривая её бегло и сосредотачиваясь только на тех разделах, которые они считают важными, непреднамеренно упуская из виду ключевую подсказку, скрытую в неисследованном разделе, которая могла бы раскрыть основную причину проблемы.
Документация может казаться сложной из-за её размера, но важно в неё тщательно вникать. Часто функция, которая на первый взгляд кажется понятной, может вызывать неожиданные проблемы.
Документация также часто содержит ценную информацию о проблемах, с которыми сталкивались другие. Предупреждения о типичных ошибках оказываются невероятно полезными, даже если вы считаете, что у вас необычная ошибка.
Примеры кода могут помочь, но следует соблюдать осторожность. Они демонстрируют один из способов использования продукта, но могут не придерживаться передовых методов проектирования и не соответствовать реальным приложениям. Простое копирование кода без полного его понимания может привести к появлению ошибок в дальнейшем.
2. Знайте, что разумно
При изучении системы крайне важно иметь чёткое представление о её типичном функционировании. Понимание стандартных операций позволяет эффективно выявлять отклонения или аномалии. Многим сложно выявить проблемы просто потому, что им не хватает фундаментального понимания того, как должна работать система.
3. Знайте дорожную карту
Важно знать структуру системы. Когда определённые части системы считаются «черными ящиками», понимание того, как они должны взаимодействовать с другими компонентами, помогает определить, находится ли проблема внутри ящика или за его пределами.
4. Изучите свои инструменты
Инструменты отладки предоставляют ценную информацию. Чтобы эффективно их использовать, важно освоить три аспекта:
- выбор подходящего инструмента для задачи,
- правильное его использование,
- точная интерпретация результатов.
Понимание ограничений инструментов не менее важно для обеспечения эффективных и успешных процессов отладки.
5. Изучайте подробности
Избегайте предположений. Потратьте время на исследование и получение точной информации. Подробные детали были задокументированы либо вами, либо создателем библиотеки, API или платформы. Неразумно полагаться исключительно на свою память.
Предположения могут вывести вас на ложный путь, где неверная информация может показаться верной, и вы упустите из виду важные проблемы. Вы можете столкнуться с запутанными данными или, что еще хуже, с ложно обнадёживающими данными.
Берите пример с Эйнштейна, который никогда не трудился запоминать свой номер телефона. Он знал, что его всегда можно найти в телефонной книге.
Источник: https://dev.to/rajasegar/debugging-rules-understand-the-system-ho5
Правила Отладки: Понимание Системы
Решение проблем без подлинного их понимания может создать ненужные трудности и поставить под угрозу качество программы. Поэтому крайне важно тщательно понять систему, прежде чем пытаться её исправить. Чтобы добиться этого, триангулируйте дефект, протестировав сценарии, которые должны воспроизводить ошибку, и те, которые не должны воспроизводить её. Продолжайте этот процесс до тех пор, пока не поймете проблему достаточно хорошо, чтобы точно предсказать её возникновение в каждом случае.
1. Читайте документацию
Понимание предполагаемого поведения системы, её конструкции, а иногда и обоснования её конструкции, очень важно. Когда отсутствует понимание какого-либо конкретного аспекта системы, это часто становится основной причиной проблем.
Часто люди пытаются устранить проблемы, не вникая в документацию, просматривая её бегло и сосредотачиваясь только на тех разделах, которые они считают важными, непреднамеренно упуская из виду ключевую подсказку, скрытую в неисследованном разделе, которая могла бы раскрыть основную причину проблемы.
Документация может казаться сложной из-за её размера, но важно в неё тщательно вникать. Часто функция, которая на первый взгляд кажется понятной, может вызывать неожиданные проблемы.
Документация также часто содержит ценную информацию о проблемах, с которыми сталкивались другие. Предупреждения о типичных ошибках оказываются невероятно полезными, даже если вы считаете, что у вас необычная ошибка.
Примеры кода могут помочь, но следует соблюдать осторожность. Они демонстрируют один из способов использования продукта, но могут не придерживаться передовых методов проектирования и не соответствовать реальным приложениям. Простое копирование кода без полного его понимания может привести к появлению ошибок в дальнейшем.
2. Знайте, что разумно
При изучении системы крайне важно иметь чёткое представление о её типичном функционировании. Понимание стандартных операций позволяет эффективно выявлять отклонения или аномалии. Многим сложно выявить проблемы просто потому, что им не хватает фундаментального понимания того, как должна работать система.
3. Знайте дорожную карту
Важно знать структуру системы. Когда определённые части системы считаются «черными ящиками», понимание того, как они должны взаимодействовать с другими компонентами, помогает определить, находится ли проблема внутри ящика или за его пределами.
4. Изучите свои инструменты
Инструменты отладки предоставляют ценную информацию. Чтобы эффективно их использовать, важно освоить три аспекта:
- выбор подходящего инструмента для задачи,
- правильное его использование,
- точная интерпретация результатов.
Понимание ограничений инструментов не менее важно для обеспечения эффективных и успешных процессов отладки.
5. Изучайте подробности
Избегайте предположений. Потратьте время на исследование и получение точной информации. Подробные детали были задокументированы либо вами, либо создателем библиотеки, API или платформы. Неразумно полагаться исключительно на свою память.
Предположения могут вывести вас на ложный путь, где неверная информация может показаться верной, и вы упустите из виду важные проблемы. Вы можете столкнуться с запутанными данными или, что еще хуже, с ложно обнадёживающими данными.
Берите пример с Эйнштейна, который никогда не трудился запоминать свой номер телефона. Он знал, что его всегда можно найти в телефонной книге.
Источник: https://dev.to/rajasegar/debugging-rules-understand-the-system-ho5
👍9
День 1680. #Безопасность
Cookie и Управление Сессиями
Управление сессиями в ASP.NET Core зависит от файлов cookie. Сервер отправляет cookie с использованием HTTP-заголовка Set-Cookie, который содержит имя файла cookie, его значение и необязательные атрибуты, например дату истечения срока действия (по умолчанию cookie истекает при закрытии браузера). Браузер может принять, отклонить файл cookie или спросить пользователя, что делать. Почти всегда действует первый вариант. Отключение файлов cookie в браузере практически не позволяет использовать многие веб-приложения.
Поскольку cookie хранятся в браузере, их значениями легко манипулировать. Нельзя хранить конфиденциальную информацию в файле cookie, например текущее имя пользователя или его привилегии. Управление сессиями использует cookie, но снижает риски манипулирования данными. Сервер хранит уникальный идентификатор сессии, который отправляется клиенту в виде файла cookie. Идентификатор генерируется на сервере, он довольно длинный, и его практически невозможно угадать.
В ASP.NET Core функциональность сессий должна быть активирована явно. В Program.cs нужно вызвать
Браузер отправляет файлы cookie обратно на сервер с каждым последующим запросом, поэтому сервер всегда может идентифицировать сессию и получить доступ к правильным данным. Пока идентификатор сессии не будет украден, процесс безопасен. Но если злоумышленник получает идентификатор, он может выдать себя за пользователя при общении с сервером.
Злоумышленник может украсть идентификатор сессии 3 способами:
1. на стороне клиента, как правило, используя межсайтовый скриптинг;
2. на стороне сервера, но осуществить такую атаку довольно непросто;
3. при передаче данных между клиентом и сервером через анализ трафика (сниффинг). Обычно такое возможно, только через HTTP.
См. также Принудительный HTTPS в ASP.NET Core.
Защитить файлы cookie можно с помощью флагов:
- HttpOnly – скрывает cookie от прямого доступа из кода JavaScript, что затрудняет межсайтовый скриптинг;
- secure – гарантирует, что cookie отправляется только через HTTPS.
Настройку флагов сеансовых файлов cookie нужно сделать явно в Program.cs:
Есть несколько признаков – но не доказательств! – успешной атаки:
1. Изменение IP-адреса.
Однако на это могут быть и законные причины: переключение мобильных устройств с Wi-Fi на мобильный интернет и обратно, балансировщики интернет-нагрузки в сети компании, автоматический сброс подключения через 24 часа у некоторых провайдеров и т.п.
2. Изменение других заголовков HTTP, например, строки user agent.
Это более весомый признак, хотя может случаться при обновлении браузера, поэтому сравнивать useк agent как строки посимвольно – не очень хорошая идея.
Требование повторного входа перед выполнением каких-либо критически важных операций может быть хорошей защитой от перехвата.
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 3.
Cookie и Управление Сессиями
Управление сессиями в ASP.NET Core зависит от файлов cookie. Сервер отправляет cookie с использованием HTTP-заголовка Set-Cookie, который содержит имя файла cookie, его значение и необязательные атрибуты, например дату истечения срока действия (по умолчанию cookie истекает при закрытии браузера). Браузер может принять, отклонить файл cookie или спросить пользователя, что делать. Почти всегда действует первый вариант. Отключение файлов cookie в браузере практически не позволяет использовать многие веб-приложения.
Поскольку cookie хранятся в браузере, их значениями легко манипулировать. Нельзя хранить конфиденциальную информацию в файле cookie, например текущее имя пользователя или его привилегии. Управление сессиями использует cookie, но снижает риски манипулирования данными. Сервер хранит уникальный идентификатор сессии, который отправляется клиенту в виде файла cookie. Идентификатор генерируется на сервере, он довольно длинный, и его практически невозможно угадать.
В ASP.NET Core функциональность сессий должна быть активирована явно. В Program.cs нужно вызвать
builder.Services.AddSession()
и app.UseSession()
.Браузер отправляет файлы cookie обратно на сервер с каждым последующим запросом, поэтому сервер всегда может идентифицировать сессию и получить доступ к правильным данным. Пока идентификатор сессии не будет украден, процесс безопасен. Но если злоумышленник получает идентификатор, он может выдать себя за пользователя при общении с сервером.
Злоумышленник может украсть идентификатор сессии 3 способами:
1. на стороне клиента, как правило, используя межсайтовый скриптинг;
2. на стороне сервера, но осуществить такую атаку довольно непросто;
3. при передаче данных между клиентом и сервером через анализ трафика (сниффинг). Обычно такое возможно, только через HTTP.
См. также Принудительный HTTPS в ASP.NET Core.
Защитить файлы cookie можно с помощью флагов:
- HttpOnly – скрывает cookie от прямого доступа из кода JavaScript, что затрудняет межсайтовый скриптинг;
- secure – гарантирует, что cookie отправляется только через HTTPS.
Настройку флагов сеансовых файлов cookie нужно сделать явно в Program.cs:
builder.Services.AddSession(opt => {Там же можно ограничить время, в течение которого можно использовать сеансовые cookie (по умолчанию 20 минут бездействия):
opt.Cookie.HttpOnly = true;
opt.Cookie.SecurePolicy =
CookieSecurePolicy.Always;
});
opt.IdleTimeout = TimeSpan.FromMinutes(5);Обнаружение перехвата сессии
Есть несколько признаков – но не доказательств! – успешной атаки:
1. Изменение IP-адреса.
Однако на это могут быть и законные причины: переключение мобильных устройств с Wi-Fi на мобильный интернет и обратно, балансировщики интернет-нагрузки в сети компании, автоматический сброс подключения через 24 часа у некоторых провайдеров и т.п.
2. Изменение других заголовков HTTP, например, строки user agent.
Это более весомый признак, хотя может случаться при обновлении браузера, поэтому сравнивать useк agent как строки посимвольно – не очень хорошая идея.
Требование повторного входа перед выполнением каких-либо критически важных операций может быть хорошей защитой от перехвата.
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 3.
👍17
День 1681. #ЧтоНовенького
Новинки ASP.NET Core в Превью 7 .NET 8
Последний превью выпуск .NET 8 содержит существенные дополнения и изменения в ASP.NET Core. Наиболее заметные улучшения связаны с Blazor, Native AOT, новыми шаблонами SPA в Visual Studio и промежуточным ПО защиты от поддельных запросов.
1. В Blazor конечные точки теперь должны по умолчанию использовать защиту от подделки (antiforgery). Начиная с этой версии компонент EditForm теперь автоматически добавляет токен защиты от подделки. Разработчики могут отключить его с помощью:
2. Для Minimal API было добавлено новое промежуточное ПО для проверки токенов защиты от подделки. Оно активируется при регистрации сервиса через AddAntiforgery. Обработчики запросов POST в минимальных API теперь будут автоматически проверять токен защиты от подделки. Если проверка токена завершается неудачей, в средах разработки будет выброшено исключение, в средах Production, будет добавляться запись в лог.
3. Автоматический интерактивный режим рендеринга в Blazor теперь сочетает в себе режимы рендеринга Server и WebAssembly. Этот режим оптимизирует рендеринг путём использования WebAssembly, если среда выполнения .NET загружается быстро (в течение 100 мс). Обычно это происходит в том случае, если среда выполнения была предварительно загружена и кэширована или используется высокоскоростная сеть. В противном случае используется серверный режим рендеринга, пока среда выполнения .NET WebAssembly загружается в фоновом режиме.
Чтобы использовать автоматической режим визуализации, укажите атрибут
4. Добавлен новый фабричный метод
-
-
-
5. Критическое изменение, затрагивающее веб-проекты, скомпилированные с включенным триммингом (
6. Представлены новые шаблоны Visual Studio для JavaScript и TypeScript разработки. Они включают шаблоны для Angular, React и Vue, используют новую систему проектов JavaScript (
Источники:
- https://www.infoq.com/news/2023/08/aspnet-core-8-preview-7/
- https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-7/
Новинки ASP.NET Core в Превью 7 .NET 8
Последний превью выпуск .NET 8 содержит существенные дополнения и изменения в ASP.NET Core. Наиболее заметные улучшения связаны с Blazor, Native AOT, новыми шаблонами SPA в Visual Studio и промежуточным ПО защиты от поддельных запросов.
1. В Blazor конечные точки теперь должны по умолчанию использовать защиту от подделки (antiforgery). Начиная с этой версии компонент EditForm теперь автоматически добавляет токен защиты от подделки. Разработчики могут отключить его с помощью:
@attribute [RequireAntiforgeryToken(required: false)]но делать так не рекомендуется.
2. Для Minimal API было добавлено новое промежуточное ПО для проверки токенов защиты от подделки. Оно активируется при регистрации сервиса через AddAntiforgery. Обработчики запросов POST в минимальных API теперь будут автоматически проверять токен защиты от подделки. Если проверка токена завершается неудачей, в средах разработки будет выброшено исключение, в средах Production, будет добавляться запись в лог.
3. Автоматический интерактивный режим рендеринга в Blazor теперь сочетает в себе режимы рендеринга Server и WebAssembly. Этот режим оптимизирует рендеринг путём использования WebAssembly, если среда выполнения .NET загружается быстро (в течение 100 мс). Обычно это происходит в том случае, если среда выполнения была предварительно загружена и кэширована или используется высокоскоростная сеть. В противном случае используется серверный режим рендеринга, пока среда выполнения .NET WebAssembly загружается в фоновом режиме.
Чтобы использовать автоматической режим визуализации, укажите атрибут
@rendermode="@RenderMode.Auto"
в экземпляре компонента или @attribute [RenderModeAuto]
в определении компонента. Обратите внимание, что компонент необходимо настроить для запуска как на сервере, так и в браузере, поэтому он должен находиться в клиентском проекте, и его реализация не должна быть привязана ни к серверу, ни к WebAssembly.4. Добавлен новый фабричный метод
WebApplication.CreateEmptyBuilder
, который позволяет создавать приложения наименьшего размера, содержащие только необходимые функции. Теперь доступно 3 варианта создания построителя приложения:-
CreateBuilder()
– полноценный построитель со всеми функциями;-
CreateSlimBuilder()
– построитель с минимальным набором функций (например, отсутствуют: поддержка IHostingStartup; поддержка UseStartup; поддержка провайдеров логов в логи событий Windows и в консоль отладки; поддержка интеграции с IIS; поддержка HTTPS; поддержка Regex в шаблонах маршрутов и т.п.);-
CreateEmptyBuilder()
– для поддержки минимальных приложений, который не будет содержать вообще никаких встроенных функций, только те, которые вы явно добавите.5. Критическое изменение, затрагивающее веб-проекты, скомпилированные с включенным триммингом (
PublishTrimmed=true
). Раньше в проектах по умолчанию использовался частичный режим тримминга (TrimMode=partial
). Однако, начиная с этого выпуска, все проекты, ориентированные на .NET 8 или более позднюю версию, по умолчанию будут использовать TrimMode=full
.6. Представлены новые шаблоны Visual Studio для JavaScript и TypeScript разработки. Они включают шаблоны для Angular, React и Vue, используют новую систему проектов JavaScript (
.esproj
) и легко интегрируются с серверными проектами ASP.NET Core.Источники:
- https://www.infoq.com/news/2023/08/aspnet-core-8-preview-7/
- https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-7/
👍6
День 1682. #Карьера
Как Общаться, Когда Доверие Низко (Не Закапывая Себя ещё Больше). Начало
Когда в отношениях мало доверия, вы склонны интерпретировать всё, что вам говорят, в худшем свете или слышать враждебность или пренебрежение там, где их нет. С другой стороны, трудно общаться, когда кажется, что всё, что вы говорите, неверно истолковывается или поворачивается против вас, независимо от того, насколько осторожными вы пытаетесь быть. Это может превратиться в смертельную спираль доверия, где каждое взаимодействие заканчивается тем, что каждый из вас немного больше ожесточается против собеседника и накапливает всё больше ран и обид.
Но чтобы работать вместе, НЕОБХОДИМО общаться! Вы должны иметь возможность спрашивать что-то и давать обратную связь. Доверие восстанавливается посредством маленьких позитивных взаимодействий. Если вы находитесь в «яме доверия», вы не сможете ясно услышать собеседника, а он не сможет ясно услышать вас (или ваши намерения). Поэтому придётся стараться сверхкоммуницировать и сверхкомпенсировать.
Существует множество книг о том, как говорить на сложные темы (например, «Трудные диалоги» Рона МакМиллана). Все они чертовски банальны, но прочитать хотя бы одну из них стоит. Вот коротко несколько тактик, которые могут сработать.
1. Заранее сообщите, что это трудно
«Мне есть что сказать, но я не знаю, как ты это воспримешь.»
Это заставит вас замедляться и внимательно выбирать слова, которые вы собираетесь использовать. А также даст собеседнику понять, что вам трудно это сказать, покажет, что вы заботитесь о его чувствах и стараетесь сделать для него всё возможное.
2. Либо признайтесь после
«Я не уверен, как я это донёс. Можно ли было бы это сформулировать лучше?»
Ничего страшного, если это произойдет через несколько минут, часов или дней; если это всё ещё вас гложет, объяснитесь.
3. Говорите осторожно
Очень полезно, когда отношения испортились, потому что вы явно допускаете, что у собеседника может быть другое восприятие, и выражаетесь безопасно, чтобы донести мысль.
«Мне кажется, что эти результаты могут быть неверны… вы видите то же самое?» - открывает дверь для дружеского разговора, основанного на конкретных результатах, тогда как фраза «Тут ошибка» может звучать обвинительно и вызывать защитную реакцию.
4. Старайтесь звучать дружелюбно
Чаще говорите «пожалуйста» и «спасибо», «привет», «лол» и т.п. Даже простое использование эмодзи в переписке сообщит о вашем настроении и смягчит реакцию собеседника. Это может показаться глупым, но это работает. Когда доверие низкое, отсутствие излишеств легко может быть воспринято как грубость.
5. Выдохните
Если вы испытываете паническую реакцию, сообщите, что вам нужно несколько минут, прежде чем ответить. Соберитесь с силами. Ответ, когда вы находитесь в режиме «сражайся или беги», почти всегда приводит к непреднамеренной эскалации. Если вам нужно несколько раз перечитать и осмыслить сообщение, найдите время. Но не молчите, сообщите, что вам нужна пара минут.
6. «В моей голове»
Если вы предполагаете худшее и считываете враждебные намерения в словах или действиях, постарайтесь проверить себя. Повторите собеседнику его слова вместе со своей интерпретацией, например: «В моей голове ваша просьба о статусе исполнения задачи выглядит как то, что вы не верите, что я выполняю работу». Это даст возможность ответить и уточнить, что собеседник на самом деле имел в виду.
7. Ищите позитивные коммуникации даже через силу
Эксперты по взаимоотношениям говорят, что в счастливых и здоровых отношениях на каждое негативное взаимодействие приходится как минимум пять положительных. Если у вас натянутые отношения с кем-то, вы общаетесь с ним только тогда, когда вам приходится это делать. И вы всегда будете этого бояться. Это может показаться искусственным, но ищите возможности для любого позитивного взаимодействия и используйте их.
Окончание следует…
Источник: https://charity.wtf/2023/08/17/how-to-communicate-when-trust-is-low-without-digging-yourself-into-a-deeper-hole/
Как Общаться, Когда Доверие Низко (Не Закапывая Себя ещё Больше). Начало
Когда в отношениях мало доверия, вы склонны интерпретировать всё, что вам говорят, в худшем свете или слышать враждебность или пренебрежение там, где их нет. С другой стороны, трудно общаться, когда кажется, что всё, что вы говорите, неверно истолковывается или поворачивается против вас, независимо от того, насколько осторожными вы пытаетесь быть. Это может превратиться в смертельную спираль доверия, где каждое взаимодействие заканчивается тем, что каждый из вас немного больше ожесточается против собеседника и накапливает всё больше ран и обид.
Но чтобы работать вместе, НЕОБХОДИМО общаться! Вы должны иметь возможность спрашивать что-то и давать обратную связь. Доверие восстанавливается посредством маленьких позитивных взаимодействий. Если вы находитесь в «яме доверия», вы не сможете ясно услышать собеседника, а он не сможет ясно услышать вас (или ваши намерения). Поэтому придётся стараться сверхкоммуницировать и сверхкомпенсировать.
Существует множество книг о том, как говорить на сложные темы (например, «Трудные диалоги» Рона МакМиллана). Все они чертовски банальны, но прочитать хотя бы одну из них стоит. Вот коротко несколько тактик, которые могут сработать.
1. Заранее сообщите, что это трудно
«Мне есть что сказать, но я не знаю, как ты это воспримешь.»
Это заставит вас замедляться и внимательно выбирать слова, которые вы собираетесь использовать. А также даст собеседнику понять, что вам трудно это сказать, покажет, что вы заботитесь о его чувствах и стараетесь сделать для него всё возможное.
2. Либо признайтесь после
«Я не уверен, как я это донёс. Можно ли было бы это сформулировать лучше?»
Ничего страшного, если это произойдет через несколько минут, часов или дней; если это всё ещё вас гложет, объяснитесь.
3. Говорите осторожно
Очень полезно, когда отношения испортились, потому что вы явно допускаете, что у собеседника может быть другое восприятие, и выражаетесь безопасно, чтобы донести мысль.
«Мне кажется, что эти результаты могут быть неверны… вы видите то же самое?» - открывает дверь для дружеского разговора, основанного на конкретных результатах, тогда как фраза «Тут ошибка» может звучать обвинительно и вызывать защитную реакцию.
4. Старайтесь звучать дружелюбно
Чаще говорите «пожалуйста» и «спасибо», «привет», «лол» и т.п. Даже простое использование эмодзи в переписке сообщит о вашем настроении и смягчит реакцию собеседника. Это может показаться глупым, но это работает. Когда доверие низкое, отсутствие излишеств легко может быть воспринято как грубость.
5. Выдохните
Если вы испытываете паническую реакцию, сообщите, что вам нужно несколько минут, прежде чем ответить. Соберитесь с силами. Ответ, когда вы находитесь в режиме «сражайся или беги», почти всегда приводит к непреднамеренной эскалации. Если вам нужно несколько раз перечитать и осмыслить сообщение, найдите время. Но не молчите, сообщите, что вам нужна пара минут.
6. «В моей голове»
Если вы предполагаете худшее и считываете враждебные намерения в словах или действиях, постарайтесь проверить себя. Повторите собеседнику его слова вместе со своей интерпретацией, например: «В моей голове ваша просьба о статусе исполнения задачи выглядит как то, что вы не верите, что я выполняю работу». Это даст возможность ответить и уточнить, что собеседник на самом деле имел в виду.
7. Ищите позитивные коммуникации даже через силу
Эксперты по взаимоотношениям говорят, что в счастливых и здоровых отношениях на каждое негативное взаимодействие приходится как минимум пять положительных. Если у вас натянутые отношения с кем-то, вы общаетесь с ним только тогда, когда вам приходится это делать. И вы всегда будете этого бояться. Это может показаться искусственным, но ищите возможности для любого позитивного взаимодействия и используйте их.
Окончание следует…
Источник: https://charity.wtf/2023/08/17/how-to-communicate-when-trust-is-low-without-digging-yourself-into-a-deeper-hole/
👍14
День 1683. #Карьера
Как Общаться, Когда Доверие Низко (Не Закапывая Себя ещё Больше). Окончание
Начало
8. Сообщайте позитивные намерения
В среде с низким уровнем доверия вы можете предположить, что всё, что вы говорите, будет прочитано угрожающим, пренебрежительным или насмешливым тоном. Вам следует обратить особое внимание на тон и голос, а также добавить дополнительные слова, которые передадут нужный вам посыл. Нейтральное утверждение типа «Это число выглядит неправильным» или «Почему этот показатель не растёт?» прозвучит резко и обвинительно. Например: показатель не растет, это твоя вина, ты должен это знать, я виню тебя, ты плохо делаешь свою работу. Не «может прозвучать», а «именно так и прозвучит». Постарайтесь защитить свой посыл от искажений, сказав что-то вроде:
«Эй, я знаю, что ты только что работал с этим, тебе не кажется, что это число неверное?»
«Этот показатель кажется ниже, чем обычно. Мне интересно, связано ли это с другой вещью, которую мы пробовали. Или у тебя есть идеи получше?»
«Я знаю, что это не совсем в твоей сфере, но можешь ли ты помочь мне это понять?»
Это может показаться чрезмерным и отнимающим много времени, но в итоге это сэкономит время и усилия, поскольку у вас накопится меньше недопониманий для отладки.
9. Дайте людям возможность сформулировать лучше
Мы склонны очень быстро формировать мнение о людях и с этого момента смотреть на них через эту призму. Требуется работа, чтобы изменить мнение о человеке.
«Всегда предполагать позитивное намерение» — хорошая цель, но на практике она не соответствует действительности. Если каждое сказанное кем-то слово звучит для вас обвинительно или покровительственно, что делать с этим советом? Просто притвориться, что не слышите, или сказать себе, что они подразумевают добрые намерения? Это неустойчиво; ваш гнев и сомнения будут только нарастать. Но можно удержать мысль о том, что собеседник имеет добрые намерения, и дать ему возможность уточнить (и, возможно, в следующий раз использовать другие слова). Например,
А: «Почему этот показатель такой низкий?»
Б: «Я не уверен».
(Пауза)
Б: «…. Эй, извини, что прерываю, но мне показалось, что ты думаешь, что я отвечаю за этот показатель, а теперь ты расстроен из-за меня или думаешь, что я некомпетентен в своей работе».
А: «Вовсе нет. Я просто пытаюсь выяснить, кто разбирается в этой части системы, поскольку, похоже, никто из этого не понимает! Извини, что заставил нервничать!»
и, возможно, в следующий раз всё начнётся так…
А: «Привет, ты не в курсе, почему этот показатель такой низкий? А то кажется, никто из тех, с кем я разговаривал, не знает».
10. Цените усилия
Вы когда-нибудь встречали в онлайне кого-то, кто вам не понравился, а при личной встрече понимали, что он прекрасный человек? Онлайн-общение очень много теряет «при транспортировке». Если вы в большинстве случаев общаетесь с кем-то в чате, обсуждайте самые спорные темы «ртом», по телефону или видеосвязи. Это не так хорошо, как личное общение, но гораздо лучше, чем текст.
После того, как вы встретились с кем-то лично, обычно легче прочитать написанные слова его голосом. Некоторые люди просто не очень хороши в письменном общении. Возможно, ваш язык общения – не родной для собеседника. И так далее. Ставьте собеседнику плюсики за усилия. Если он пытается донести мысль дружелюбно, очевидно, для него важно, как вы это воспримете.
В меру своих возможностей старайтесь не читать (и не писать) «между строк» в текстовом общении. Будьте проще, передавайте намерения явно и просите ясности от собеседника. А если кто-то просит вас внести ясность, помогите ему, и это сработает на вас.
Источник: https://charity.wtf/2023/08/17/how-to-communicate-when-trust-is-low-without-digging-yourself-into-a-deeper-hole/
Как Общаться, Когда Доверие Низко (Не Закапывая Себя ещё Больше). Окончание
Начало
8. Сообщайте позитивные намерения
В среде с низким уровнем доверия вы можете предположить, что всё, что вы говорите, будет прочитано угрожающим, пренебрежительным или насмешливым тоном. Вам следует обратить особое внимание на тон и голос, а также добавить дополнительные слова, которые передадут нужный вам посыл. Нейтральное утверждение типа «Это число выглядит неправильным» или «Почему этот показатель не растёт?» прозвучит резко и обвинительно. Например: показатель не растет, это твоя вина, ты должен это знать, я виню тебя, ты плохо делаешь свою работу. Не «может прозвучать», а «именно так и прозвучит». Постарайтесь защитить свой посыл от искажений, сказав что-то вроде:
«Эй, я знаю, что ты только что работал с этим, тебе не кажется, что это число неверное?»
«Этот показатель кажется ниже, чем обычно. Мне интересно, связано ли это с другой вещью, которую мы пробовали. Или у тебя есть идеи получше?»
«Я знаю, что это не совсем в твоей сфере, но можешь ли ты помочь мне это понять?»
Это может показаться чрезмерным и отнимающим много времени, но в итоге это сэкономит время и усилия, поскольку у вас накопится меньше недопониманий для отладки.
9. Дайте людям возможность сформулировать лучше
Мы склонны очень быстро формировать мнение о людях и с этого момента смотреть на них через эту призму. Требуется работа, чтобы изменить мнение о человеке.
«Всегда предполагать позитивное намерение» — хорошая цель, но на практике она не соответствует действительности. Если каждое сказанное кем-то слово звучит для вас обвинительно или покровительственно, что делать с этим советом? Просто притвориться, что не слышите, или сказать себе, что они подразумевают добрые намерения? Это неустойчиво; ваш гнев и сомнения будут только нарастать. Но можно удержать мысль о том, что собеседник имеет добрые намерения, и дать ему возможность уточнить (и, возможно, в следующий раз использовать другие слова). Например,
А: «Почему этот показатель такой низкий?»
Б: «Я не уверен».
(Пауза)
Б: «…. Эй, извини, что прерываю, но мне показалось, что ты думаешь, что я отвечаю за этот показатель, а теперь ты расстроен из-за меня или думаешь, что я некомпетентен в своей работе».
А: «Вовсе нет. Я просто пытаюсь выяснить, кто разбирается в этой части системы, поскольку, похоже, никто из этого не понимает! Извини, что заставил нервничать!»
и, возможно, в следующий раз всё начнётся так…
А: «Привет, ты не в курсе, почему этот показатель такой низкий? А то кажется, никто из тех, с кем я разговаривал, не знает».
10. Цените усилия
Вы когда-нибудь встречали в онлайне кого-то, кто вам не понравился, а при личной встрече понимали, что он прекрасный человек? Онлайн-общение очень много теряет «при транспортировке». Если вы в большинстве случаев общаетесь с кем-то в чате, обсуждайте самые спорные темы «ртом», по телефону или видеосвязи. Это не так хорошо, как личное общение, но гораздо лучше, чем текст.
После того, как вы встретились с кем-то лично, обычно легче прочитать написанные слова его голосом. Некоторые люди просто не очень хороши в письменном общении. Возможно, ваш язык общения – не родной для собеседника. И так далее. Ставьте собеседнику плюсики за усилия. Если он пытается донести мысль дружелюбно, очевидно, для него важно, как вы это воспримете.
В меру своих возможностей старайтесь не читать (и не писать) «между строк» в текстовом общении. Будьте проще, передавайте намерения явно и просите ясности от собеседника. А если кто-то просит вас внести ясность, помогите ему, и это сработает на вас.
Источник: https://charity.wtf/2023/08/17/how-to-communicate-when-trust-is-low-without-digging-yourself-into-a-deeper-hole/
👍5
День 1684. #PostgresTips
Советы по Postgres для Начинающих
9. Оптимизация запросов или настройки конфигурации
Когда дело касается производительности, в большинстве случаев полезно оптимизировать конфигурацию Postgres «достаточно хорошо», изредка пересматривая решения (например, после серьёзного обновления Postgres), а затем полностью сосредоточиться на настройке запросов. Особенно, если вы часто меняете приложение.
Первоначальная настройка конфигурации может привести к повышению производительности. Но по мере роста и развития приложения основная борьба за производительность часто смещается к оптимизации запросов. Среди новичков распространено заблуждение: «Если я хорошо настрою конфигурацию, у меня не будет проблем». Настройка конфигурации жизненно важна, но это только начало. В конце концов, придётся сосредоточиться на постоянной оптимизации запросов.
Уже обсуждавшийся pg_stat_statements — бесценный инструмент для выявления проблемных запросов. Он предоставляет ранжированный список операторов SQL, упорядоченный по различным показателям. В сочетании с EXPLAIN (ANALYZE, BUFFERS), вы можете понять план выполнения запроса и выявить неэффективность.
10. Ведение индекса: необходимая практика
Индексы имеют решающее значение для производительности любой реляционной БД, и Postgres не является исключением. Со временем, по мере изменения данных, индексы становятся фрагментированными и менее эффективными. Даже при использовании современных версий Postgres и хорошо настроенной автоочистке работоспособность индекса по-прежнему ухудшается с течением времени, по мере того как происходят многочисленные записи.
Когда данные вставляются, обновляются или удаляются, индексы, отражающие эти данные, претерпевают изменения. Эти изменения могут привести к тому, что структура индекса станет несбалансированной или появится неработающие записи, что замедлит производительность поиска.
Индексы не сохраняют свою оптимальную структуру бесконечно. Периодически их необходимо восстанавливать (REINDEX). Этот процесс включает в себя создание новой версии индекса, что часто приводит к более компактной и эффективной структуре. Настройка таких восстановлений, желательно в автоматическом режиме, гарантирует постоянство производительности БД.
Не менее важно удалять неиспользуемые или избыточные индексы. Они не только тратят место, но и могут замедлять операции записи. Регулярная проверка и очистка ненужных индексов должны быть частью вашей процедуры обслуживания.
Бонус: документация Postgres - ваш надёжный спутник
Всегда имейте в закладках официальную документацию Postgres:
- Она всеобъемлюща и актуальна: является наиболее авторитетным источником информации, подробно описывающим каждую функцию, поведение и нюансы Postgres.
- Содержит примечания к релизу с кратким описанием всех изменений, новых функций и улучшений. Это отличный способ быть в курсе того, что нового появилось и что может повлиять на ваши существующие настройки.
- Комментарии к исходному коду/файлы README: для тех, кто любит глубоко погружаться, исходный код Postgres — это не только учебный ресурс, но и справочный материал. Они могут дать ценную информацию и объяснения, которые могут быть неочевидны в других источниках.
Источник: https://postgres.ai/blog/20230722-10-postgres-tips-for-beginners
Советы по Postgres для Начинающих
9. Оптимизация запросов или настройки конфигурации
Когда дело касается производительности, в большинстве случаев полезно оптимизировать конфигурацию Postgres «достаточно хорошо», изредка пересматривая решения (например, после серьёзного обновления Postgres), а затем полностью сосредоточиться на настройке запросов. Особенно, если вы часто меняете приложение.
Первоначальная настройка конфигурации может привести к повышению производительности. Но по мере роста и развития приложения основная борьба за производительность часто смещается к оптимизации запросов. Среди новичков распространено заблуждение: «Если я хорошо настрою конфигурацию, у меня не будет проблем». Настройка конфигурации жизненно важна, но это только начало. В конце концов, придётся сосредоточиться на постоянной оптимизации запросов.
Уже обсуждавшийся pg_stat_statements — бесценный инструмент для выявления проблемных запросов. Он предоставляет ранжированный список операторов SQL, упорядоченный по различным показателям. В сочетании с EXPLAIN (ANALYZE, BUFFERS), вы можете понять план выполнения запроса и выявить неэффективность.
10. Ведение индекса: необходимая практика
Индексы имеют решающее значение для производительности любой реляционной БД, и Postgres не является исключением. Со временем, по мере изменения данных, индексы становятся фрагментированными и менее эффективными. Даже при использовании современных версий Postgres и хорошо настроенной автоочистке работоспособность индекса по-прежнему ухудшается с течением времени, по мере того как происходят многочисленные записи.
Когда данные вставляются, обновляются или удаляются, индексы, отражающие эти данные, претерпевают изменения. Эти изменения могут привести к тому, что структура индекса станет несбалансированной или появится неработающие записи, что замедлит производительность поиска.
Индексы не сохраняют свою оптимальную структуру бесконечно. Периодически их необходимо восстанавливать (REINDEX). Этот процесс включает в себя создание новой версии индекса, что часто приводит к более компактной и эффективной структуре. Настройка таких восстановлений, желательно в автоматическом режиме, гарантирует постоянство производительности БД.
Не менее важно удалять неиспользуемые или избыточные индексы. Они не только тратят место, но и могут замедлять операции записи. Регулярная проверка и очистка ненужных индексов должны быть частью вашей процедуры обслуживания.
Бонус: документация Postgres - ваш надёжный спутник
Всегда имейте в закладках официальную документацию Postgres:
- Она всеобъемлюща и актуальна: является наиболее авторитетным источником информации, подробно описывающим каждую функцию, поведение и нюансы Postgres.
- Содержит примечания к релизу с кратким описанием всех изменений, новых функций и улучшений. Это отличный способ быть в курсе того, что нового появилось и что может повлиять на ваши существующие настройки.
- Комментарии к исходному коду/файлы README: для тех, кто любит глубоко погружаться, исходный код Postgres — это не только учебный ресурс, но и справочный материал. Они могут дать ценную информацию и объяснения, которые могут быть неочевидны в других источниках.
Источник: https://postgres.ai/blog/20230722-10-postgres-tips-for-beginners
👍4
День 1685. #ЗаметкиНаПолях
Решение Проблем Гонки с Помощью Оптимистической Блокировки EF Core. Начало
Как часто вы думаете о конфликтах параллелизма при написании кода? Вы пишете код новой функции, проверяете, что она работает, и всё. Но неделю спустя вы обнаруживаете, что допустили неприятную ошибку, потому что не подумали о параллелизме. Наиболее распространённой проблемой являются условия гонки, когда два конкурирующих потока выполняют одну и ту же функцию. Если вы не учтёте это во время разработки, вы рискуете оставить систему в повреждённом состоянии.
Рассмотрим пример.
Бизнес-требование: нельзя иметь два перекрывающихся бронирования на одни и те же даты. В следующем примере кода скрывается проблема состояния гонки:
Проблема в том, что существует вероятность того, что параллельный запрос пройдёт проверку IsOverlapping и попытается сделать бронирование. Без какого-либо контроля параллелизма оба запроса будут успешными, и в итоге мы получим несогласованное состояние БД.
При пессимистическом подходе обработки параллелизма данные в БД блокируются между чтением и изменением. Это медленно и приводит к блокировке конкурирующих транзакций до тех пор, пока блокировка не будет снята. EF Core не поддерживает этот подход «из коробки». Оптимистический параллелизм в EF Core не требует блокировок, но любые изменения данных не будут сохранены, если данные изменились с момента чтения.
Чтобы реализовать оптимистичный параллелизм в EF Core, необходимо настроить свойство как токен параллелизма. Оно загружается и отслеживается вместе с сущностью. Когда вы вызываете SaveChanges, EF Core сравнивает значение токена параллелизма со значением в базе данных.
Например, в SQL Server есть столбец rowversion, который автоматически меняется при обновлении строки, поэтому это отличный вариант для токена параллелизма. Можно настроить теневое свойство в EF Core, чтобы спрятать его от основного класса сущности:
При загрузке сущности Apart EF также загрузит токен параллелизма.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
Решение Проблем Гонки с Помощью Оптимистической Блокировки EF Core. Начало
Как часто вы думаете о конфликтах параллелизма при написании кода? Вы пишете код новой функции, проверяете, что она работает, и всё. Но неделю спустя вы обнаруживаете, что допустили неприятную ошибку, потому что не подумали о параллелизме. Наиболее распространённой проблемой являются условия гонки, когда два конкурирующих потока выполняют одну и ту же функцию. Если вы не учтёте это во время разработки, вы рискуете оставить систему в повреждённом состоянии.
Рассмотрим пример.
Бизнес-требование: нельзя иметь два перекрывающихся бронирования на одни и те же даты. В следующем примере кода скрывается проблема состояния гонки:
public Result<Guid> Handle(Вызов IsOverlapping — это оптимистичная проверка, существует ли бронирование на указанные даты. Если ответ true, это попытка конкурентного бронирования на те же даты, поэтому мы возвращаем ошибку. Но если возвращается false, мы бронируем и вызываем SaveChanges, чтобы сохранить изменения в БД.
ReserveBooking command,
AppDbContext ctx)
{
var user = ctx.Users.GetById(command.UserId);
var apart = ctx.Aparts.GetById(command.ApartId);
var (start, end) = command;
if (dbContext.Bookings
.IsOverlapping(apart, start, end))
return Result.Failure<Guid>(Errors.Overlap);
var booking = Booking
.Reserve(apart, user, start, end);
ctx.Add(booking);
ctx.SaveChanges();
return booking.Id;
}
Проблема в том, что существует вероятность того, что параллельный запрос пройдёт проверку IsOverlapping и попытается сделать бронирование. Без какого-либо контроля параллелизма оба запроса будут успешными, и в итоге мы получим несогласованное состояние БД.
При пессимистическом подходе обработки параллелизма данные в БД блокируются между чтением и изменением. Это медленно и приводит к блокировке конкурирующих транзакций до тех пор, пока блокировка не будет снята. EF Core не поддерживает этот подход «из коробки». Оптимистический параллелизм в EF Core не требует блокировок, но любые изменения данных не будут сохранены, если данные изменились с момента чтения.
Чтобы реализовать оптимистичный параллелизм в EF Core, необходимо настроить свойство как токен параллелизма. Оно загружается и отслеживается вместе с сущностью. Когда вы вызываете SaveChanges, EF Core сравнивает значение токена параллелизма со значением в базе данных.
Например, в SQL Server есть столбец rowversion, который автоматически меняется при обновлении строки, поэтому это отличный вариант для токена параллелизма. Можно настроить теневое свойство в EF Core, чтобы спрятать его от основного класса сущности:
protected override void OnModelCreating(* Точная конфигурация будет зависеть от типа вашей БД.
ModelBuilder mb)
{
mb.Entity<Apart>()
.Property<byte[]>("Version")
.IsRowVersion();
}
При загрузке сущности Apart EF также загрузит токен параллелизма.
SELECT a.Id, a.VersionА при вызове SaveChanges, запрос UPDATE сравнит его с текущим токеном в БД:
FROM Aparts a
WHERE a.Id = @p0
UPDATE Aparts aЕсли версия в базе отличается, будет обновлено 0 строк, а EF Core ожидает обновления 1 строки, поэтому будет выброшено исключение DbUpdateConcurrencyException, которое надо обработать.
SET a.LastBookedOnUtc = @p0
WHERE a.Id = @p1 AND a.Version = @p2;
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
👍22
День 1686. #ЗаметкиНаПолях
Решение Проблем Гонки с Помощью Оптимистической Блокировки EF Core. Окончание
Начало
Обработка исключений параллелизма
Теперь мы можем исправить предыдущий фрагмент кода.
Если два одновременных запроса проходят проверку IsOverlapping, только один может завершить вызов SaveChanges. Другой конкурентный запрос приведёт к несоответствию версии в базе данных и выдаст исключение DbUpdateConcurrencyException.
На случай конфликта параллелизма нам нужно добавить оператор try-catch, чтобы перехватить исключение DbUpdateConcurrencyException. То, как вы будете обрабатывать фактическое исключение, зависит от ваших бизнес-требований.
Оптимистический параллелизм предполагает, что успешный сценарий также является наиболее вероятным. Он предполагает, что конфликты между транзакциями будут нечастыми и не блокирует данные. Это означает, что ваша система может лучше масштабироваться, поскольку нет блокировок, снижающих производительность.
Однако вам всё равно придётся ожидать конфликтов параллелизма и реализовать специальную логику для их обработки.
Оптимистический параллелизм — хороший выбор, если ваше приложение не ожидает большого количества конфликтов.
Другая причина использовать оптимистический параллелизм — когда вы не можете поддерживать открытое соединение с базой данных на протяжении всей транзакции. Это необходимо для пессимистической блокировки.
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
Решение Проблем Гонки с Помощью Оптимистической Блокировки EF Core. Окончание
Начало
Обработка исключений параллелизма
Теперь мы можем исправить предыдущий фрагмент кода.
Если два одновременных запроса проходят проверку IsOverlapping, только один может завершить вызов SaveChanges. Другой конкурентный запрос приведёт к несоответствию версии в базе данных и выдаст исключение DbUpdateConcurrencyException.
На случай конфликта параллелизма нам нужно добавить оператор try-catch, чтобы перехватить исключение DbUpdateConcurrencyException. То, как вы будете обрабатывать фактическое исключение, зависит от ваших бизнес-требований.
public Result<Guid> Handle(Когда следует использовать оптимистический параллелизм?
ReserveBooking command,
AppDbContext ctx)
{
var user = ctx.Users.GetById(command.UserId);
var apart = ctx.Aparts.GetById(command.ApartId);
var (start, end) = command;
if (ctx.Bookings.IsOverlapping(apart, start, end))
return Result.Failure<Guid>(Errors.Overlap);
try
{
var booking = Booking
.Reserve(apart, user, start, end);
ctx.Add(booking);
ctx.SaveChanges();
return booking.Id;
}
catch (DbUpdateConcurrencyException)
{
return Result.Failure<Guid>(Errors.Overlap);
}
}
Оптимистический параллелизм предполагает, что успешный сценарий также является наиболее вероятным. Он предполагает, что конфликты между транзакциями будут нечастыми и не блокирует данные. Это означает, что ваша система может лучше масштабироваться, поскольку нет блокировок, снижающих производительность.
Однако вам всё равно придётся ожидать конфликтов параллелизма и реализовать специальную логику для их обработки.
Оптимистический параллелизм — хороший выбор, если ваше приложение не ожидает большого количества конфликтов.
Другая причина использовать оптимистический параллелизм — когда вы не можете поддерживать открытое соединение с базой данных на протяжении всей транзакции. Это необходимо для пессимистической блокировки.
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
👍15
Какие (относительно) редкие управляющие ключевые слова вы используете в своём коде?
Anonymous Poll
58%
continue
26%
checked/unchecked
24%
do
46%
finally
30%
goto
39%
lock
27%
unsafe
День 1687. #ВопросыНаСобеседовании #Многопоточность
Самые часто задаваемые вопросы на собеседовании по C#
22. В контексте многопоточности C# каковы основные различия между ThreadPool и созданием выделенных экземпляров Thread?
1. Управление ресурсами: ThreadPool управляет пулом рабочих потоков, которые повторно используются для нескольких задач, сокращая накладные расходы на создание и уничтожение потоков. Непосредственное создание потоков создаёт новый поток для каждой задачи, что может быть ресурсоёмким, особенно при обработке большого количества задач.
2. Время жизни потока: потоки из ThreadPool имеют фоновый статус, и их время жизни управляется системой. Выделенные потоки по умолчанию имеют приоритетный статус, а их время существования контролируется разработчиком.
3. Масштабируемость: ThreadPool автоматически регулирует количество рабочих потоков в зависимости от загрузки системы и доступных ресурсов, обеспечивая лучшую масштабируемость приложений. При создании выделенных потоков вы должны самостоятельно управлять количеством потоков, что может быть более сложным и подверженным ошибкам.
4. Приоритет и настройка: потоки из ThreadPool имеют приоритет по умолчанию и ограниченную настройку. Выделенные потоки можно настраивать по приоритету, имени, размеру стека и другим свойствам.
5. Синхронизация: ThreadPool помогает с синхронизацией потоков, поскольку рабочие элементы ставятся в очередь и выполняются доступными потоками. При использовании выделенных потоков за синхронизацию потоков отвечают разработчики.
Пример использования ThreadPool:
Самые часто задаваемые вопросы на собеседовании по C#
22. В контексте многопоточности C# каковы основные различия между ThreadPool и созданием выделенных экземпляров Thread?
1. Управление ресурсами: ThreadPool управляет пулом рабочих потоков, которые повторно используются для нескольких задач, сокращая накладные расходы на создание и уничтожение потоков. Непосредственное создание потоков создаёт новый поток для каждой задачи, что может быть ресурсоёмким, особенно при обработке большого количества задач.
2. Время жизни потока: потоки из ThreadPool имеют фоновый статус, и их время жизни управляется системой. Выделенные потоки по умолчанию имеют приоритетный статус, а их время существования контролируется разработчиком.
3. Масштабируемость: ThreadPool автоматически регулирует количество рабочих потоков в зависимости от загрузки системы и доступных ресурсов, обеспечивая лучшую масштабируемость приложений. При создании выделенных потоков вы должны самостоятельно управлять количеством потоков, что может быть более сложным и подверженным ошибкам.
4. Приоритет и настройка: потоки из ThreadPool имеют приоритет по умолчанию и ограниченную настройку. Выделенные потоки можно настраивать по приоритету, имени, размеру стека и другим свойствам.
5. Синхронизация: ThreadPool помогает с синхронизацией потоков, поскольку рабочие элементы ставятся в очередь и выполняются доступными потоками. При использовании выделенных потоков за синхронизацию потоков отвечают разработчики.
Пример использования ThreadPool:
ThreadPool.QueueUserWorkItem((_) =>Пример выделенного потока:
{
// Логика вашей задачи здесь
});
var thread = new Thread(() =>Источник: https://dev.to/bytehide/c-multithreading-interview-questions-and-answers-4opj
{
// Логика вашей задачи здесь
});
thread.Start();
👍10
День 1688. #ЧтоНовенького
Сохраняем Регистр Символов при Замене в Visual Studio
В инструмент поиска и замены Visual Studio добавлена новая функция, которая позволяет пользователям находить и заменять текст, не беспокоясь о различных регистрах. Например, в случае, когда параметр метода
Эта функция была запрошена пользователями на Stack Overflow ещё в 2008 (sic!) году. И наконец стала доступна, начиная с версии 17.8 Preview 1.
Когда вы выполняете замену, вы можете сохранить исходный регистр каждого совпадения в коде. Переключите сохранение регистра в окне «Заменить» с помощью
В окне «Заменить в Файлах» отметьте флажок «Сохранить регистр» (Preserve case). Регистр также сохраняется в тексте, содержащем дефисы и символы подчёркивания.
Источник
Сохраняем Регистр Символов при Замене в Visual Studio
В инструмент поиска и замены Visual Studio добавлена новая функция, которая позволяет пользователям находить и заменять текст, не беспокоясь о различных регистрах. Например, в случае, когда параметр метода
catalogItemId
и свойство объекта CatalogItemId
имеют одно и то же имя, но разные заглавные буквы, но оба должны быть заменены чем-то вроде productId
в соответствии с регистром (см. картинку).Эта функция была запрошена пользователями на Stack Overflow ещё в 2008 (sic!) году. И наконец стала доступна, начиная с версии 17.8 Preview 1.
Когда вы выполняете замену, вы можете сохранить исходный регистр каждого совпадения в коде. Переключите сохранение регистра в окне «Заменить» с помощью
Alt+V
или нажав кнопку «Сохранить регистр» (иконка AB
).В окне «Заменить в Файлах» отметьте флажок «Сохранить регистр» (Preserve case). Регистр также сохраняется в тексте, содержащем дефисы и символы подчёркивания.
Источник
👍6👎1
День 1689. #TipsAndTricks
Теневые Свойства в Entity Framework Core
Множество моделей, перегружено свойствами, которые на самом деле не обязательно в них включать. Вместо этого мы можем использовать теневые свойства, чтобы сохранить чистоту модели и включать в неё только те свойства, которые относятся к предметной области.
Вариантом использования теневых свойств являются столбцы аудита, например
Другой вариант использования — свойства, которые содержат ссылку на внешний ключ, или свойства навигации. Это очень путает, потому что неясно, какое свойство использовать. Например:
Рассмотрим пример создания теневого свойства для «мягкого удаления»:
Теневые Свойства в Entity Framework Core
Множество моделей, перегружено свойствами, которые на самом деле не обязательно в них включать. Вместо этого мы можем использовать теневые свойства, чтобы сохранить чистоту модели и включать в неё только те свойства, которые относятся к предметной области.
Вариантом использования теневых свойств являются столбцы аудита, например
CreatedOn
, CreatedBy
и т.п. Или столбцы периода из темпоральной таблицы. Эти столбцы полезны для отслеживания того, кто создал или обновил запись, но они не добавляют никакой ценности сущности домена.Другой вариант использования — свойства, которые содержат ссылку на внешний ключ, или свойства навигации. Это очень путает, потому что неясно, какое свойство использовать. Например:
class CustomerМы можем сказать Entity Framework создать теневое свойство AddressId и добавить необходимые ограничения отношений.
{
// внешний ключ
public Guid AddressId { get; set; }
// навигационное свойство
public Address Address { get; set; }
}
Рассмотрим пример создания теневого свойства для «мягкого удаления»:
protected override voidЧтобы устанавливать и обновлять значения теневого свойства, получите EntityEntry сущности и используйте метод Property:
OnModelCreating(ModelBuilder mb)
{
mb.Entity<Customer>()
.Property<DateTime?>("DeletedOn");
mb.Entity<Customer>()
.HasQueryFilter(e =>
EF.Property<DateTime?>(e, "DeletedOn") == null);
}
dbContextЭто более полезно, когда не нужно думать об этих свойствах, а они устанавливаются автоматически. Этого можно добиться, переопределив метод SaveChanges объекта DbContext:
.Entry(customer)
.Property("DeletedOn")
.CurrentValue = DateTime.UtcNow;
dbContext.SaveChanges();
public class DemoDbContext : DbContextИсточник: https://timdeschryver.dev/blog/entity-framework-features-i-wish-i-knew-earlier#shadow-properties
{
public override int SaveChanges()
{
ChangeTracker.DetectChanges();
foreach (var e in
ChangeTracker.Entries())
{
if (e.State == EntityState.Added)
e.Property("CreatedOn")
.CurrentValue = DateTime.UtcNow;
if (e.State == EntityState.Modified)
e.Property("UpdatedOn")
.CurrentValue = DateTime.UtcNow;
if (e.State == EntityState.Deleted)
e.Property("DeletedOn")
.CurrentValue = DateTime.UtcNow;
}
return base.SaveChanges();
}
}
👍18
День 1690. #Карьера
Худший Программист, Которого Я Знаю
Самое замечательное в измерении продуктивности разработчиков заключается в том, что вы можете быстро выявить плохих программистов. Я хочу рассказать вам о худшем программисте, которого я знаю, и почему я боролся за то, чтобы удержать его в команде. Его зовут Тим Маккиннон, и я хочу, чтобы вы знали, насколько он непродуктивен.
Мы работали в известной консалтинговой компании по производству ПО для большого банка, которая решила ввести индивидуальные показатели эффективности «для целей оценки и личного развития». Это было распространено каскадно по всей организации, а на нашу команду оно легло в виде стори-пойнтов. Это произошло после обстоятельного обсуждения с руководителем отдела, который знал, что не следует измерять такие вещи, как количество строк кода или обнаруженные ошибки, потому что люди могут легко ими манипулировать.
Вместо этого мы измеряли количество реализованных стори-пойнтов, потому что они представляли ценность для бизнеса. Мы использовали что-то вроде Jira, и люди ставили свои имена рядом с историями, что очень упрощало подсчёт этих показателей производительности.
Это подводит меня к Тиму. Оценка Тима стабильно была нулевой. Ноль! Не просто низкой или имеющей тенденцию к снижению, а буквально нулевой. Неделя за неделей, итерация за итерацией. Ноль очков у Тима.
Что ж, Тиму явно пора было уходить. Таков был вывод менеджера, и он попросил меня принять необходимые меры, чтобы Тима уволили и заменили кем-то, кто будет… творить истории. Но я наотрез отказался. Для меня это даже не было трудным решением, я просто сказал «нет».
Видите ли, причина того, что показатель продуктивности Тима был нулевым, заключалась в том, что он никогда не подписывался ни на какие истории. Вместо этого он проводил день в парах с разными товарищами по команде. Менее опытным разработчикам он терпеливо позволял писать код, планомерно подталкивая их к решению. Он не собирался давить на них или мешать им, а позволял им тратить время на обучение, тщательно создавая моменты озарения и обучения, часто в виде сократовских вопросов: а что, если?, а как ещё?
Со старшими это было больше похоже на совместное творчество или спарринг; привлечение различных точек зрения к решению проблемы, чтобы создать что-то лучше, чем каждый из нас мог бы придумать самостоятельно. Тим — потрясающий программист, и вместе с ним всегда чему-то учишься.
Тим не поставлял ПО; Тим руководил командой, которая поставляла ПО. Вся команда становилась более эффективной, более продуктивной, более слаженной и более веселой, потому что Тим был в команде.
Я объяснил всё это менеджеру и пригласил его время от времени приходить и наблюдать за нашей работой. Всякий раз, когда он заходил, он видел Тима, сидящего с кем-то другим. И вы могли быть уверены, что качество того, над чем они работали, будет значительно лучше, а затраченное время значительно меньше, чем когда Тим не объединялся с людьми. Да, можно было бы сделать лучше, быстрее и дешевле в одиночку, это просто требует много дисциплины.
В конце концов мы сохранили Тима и незаметно отказались от показателей индивидуальной производительности в пользу командной, где мы отслеживали — и отмечали — влияние на бизнес, которое мы оказывали, как высокопроизводительное подразделение.
Итого
Измеряйте производительность любым способом — я полностью за подотчётность — в идеале как ощутимый эффект для бизнеса, выраженный в сэкономленных, созданных или сохранённых долларах. Обычно это сложно, поэтому прокси-показатели тоже подойдут. Только не пытайтесь измерить индивидуальный вклад каждой единицы в сложную адаптивную систему, потому что такая постановка вопроса ошибочна. Измеряйте работу двигателя в целом, а не вклад отдельных поршней, потому что это не имеет смысла.
Источник: https://dannorth.net/2023/09/02/the-worst-programmer/
Автор оригинала: Дэн Норт
Худший Программист, Которого Я Знаю
Самое замечательное в измерении продуктивности разработчиков заключается в том, что вы можете быстро выявить плохих программистов. Я хочу рассказать вам о худшем программисте, которого я знаю, и почему я боролся за то, чтобы удержать его в команде. Его зовут Тим Маккиннон, и я хочу, чтобы вы знали, насколько он непродуктивен.
Мы работали в известной консалтинговой компании по производству ПО для большого банка, которая решила ввести индивидуальные показатели эффективности «для целей оценки и личного развития». Это было распространено каскадно по всей организации, а на нашу команду оно легло в виде стори-пойнтов. Это произошло после обстоятельного обсуждения с руководителем отдела, который знал, что не следует измерять такие вещи, как количество строк кода или обнаруженные ошибки, потому что люди могут легко ими манипулировать.
Вместо этого мы измеряли количество реализованных стори-пойнтов, потому что они представляли ценность для бизнеса. Мы использовали что-то вроде Jira, и люди ставили свои имена рядом с историями, что очень упрощало подсчёт этих показателей производительности.
Это подводит меня к Тиму. Оценка Тима стабильно была нулевой. Ноль! Не просто низкой или имеющей тенденцию к снижению, а буквально нулевой. Неделя за неделей, итерация за итерацией. Ноль очков у Тима.
Что ж, Тиму явно пора было уходить. Таков был вывод менеджера, и он попросил меня принять необходимые меры, чтобы Тима уволили и заменили кем-то, кто будет… творить истории. Но я наотрез отказался. Для меня это даже не было трудным решением, я просто сказал «нет».
Видите ли, причина того, что показатель продуктивности Тима был нулевым, заключалась в том, что он никогда не подписывался ни на какие истории. Вместо этого он проводил день в парах с разными товарищами по команде. Менее опытным разработчикам он терпеливо позволял писать код, планомерно подталкивая их к решению. Он не собирался давить на них или мешать им, а позволял им тратить время на обучение, тщательно создавая моменты озарения и обучения, часто в виде сократовских вопросов: а что, если?, а как ещё?
Со старшими это было больше похоже на совместное творчество или спарринг; привлечение различных точек зрения к решению проблемы, чтобы создать что-то лучше, чем каждый из нас мог бы придумать самостоятельно. Тим — потрясающий программист, и вместе с ним всегда чему-то учишься.
Тим не поставлял ПО; Тим руководил командой, которая поставляла ПО. Вся команда становилась более эффективной, более продуктивной, более слаженной и более веселой, потому что Тим был в команде.
Я объяснил всё это менеджеру и пригласил его время от времени приходить и наблюдать за нашей работой. Всякий раз, когда он заходил, он видел Тима, сидящего с кем-то другим. И вы могли быть уверены, что качество того, над чем они работали, будет значительно лучше, а затраченное время значительно меньше, чем когда Тим не объединялся с людьми. Да, можно было бы сделать лучше, быстрее и дешевле в одиночку, это просто требует много дисциплины.
В конце концов мы сохранили Тима и незаметно отказались от показателей индивидуальной производительности в пользу командной, где мы отслеживали — и отмечали — влияние на бизнес, которое мы оказывали, как высокопроизводительное подразделение.
Итого
Измеряйте производительность любым способом — я полностью за подотчётность — в идеале как ощутимый эффект для бизнеса, выраженный в сэкономленных, созданных или сохранённых долларах. Обычно это сложно, поэтому прокси-показатели тоже подойдут. Только не пытайтесь измерить индивидуальный вклад каждой единицы в сложную адаптивную систему, потому что такая постановка вопроса ошибочна. Измеряйте работу двигателя в целом, а не вклад отдельных поршней, потому что это не имеет смысла.
Источник: https://dannorth.net/2023/09/02/the-worst-programmer/
Автор оригинала: Дэн Норт
👍35
День 1691. #ЧтоНовенького
Обновление Visual Studio без Прав Администратора
В мире ИТ администраторам и организациям крайне важно эффективно управлять безопасностью и применять передовые методы обеспечения безопасности. Одна из распространённых практик предполагает внедрение соответствующих уровней разрешений, чтобы гарантировать, что только авторизованные учётные записи могут получить доступ к конфиденциальным данным и функциям. Ещё один полезный совет – регулярные обновления ПО с последними обновлениями безопасности.
До сих пор установщик Visual Studio требовал прав администратора, поскольку ему необходимо записывать в «защищённые» области Windows. Однако если у пользователя, запускающего установщик, нет необходимых повышенных разрешений, ему запрещалось использовать функции установщика для обновления или изменения Visual Studio. Таким образом во многих организациях разработчик с привилегиями обычного пользователя не мог получить обновления продукта.
Теперь обычные пользователи теперь могут обновлять и изменять Visual Studio, начиная с версии 17.7. Стандартным пользователям может быть предоставлена возможность полноценно использовать установщик для получения обновлений и внесения изменений в Visual Studio. Администратор должен явно делегировать управление обычному пользователю и включить эту функцию, выполнив два простых шага на клиентском компьютере:
1. Выполнить первоначальную установку. Для первого получения установщика на любом клиентском компьютере всегда требуются права администратора.
2. Настроить политику AllowStandardUserControl. Для настройки политик Visual Studio также потребуются права администратора.
После выполнения этих двух шагов обычный пользователь сможет получить доступ к любым функциям установщика и выполнять обновления, модификации и даже установку новых компонентов Visual Studio.
Другие функции управления безопасностью
Visual Studio значительно упростила для корпоративных администраторов соблюдение общих рекомендаций по обеспечению безопасности. Например, недавно администраторы получили возможность легко настраивать политики Visual Studio и включать автоматические ежемесячные обновления безопасности администратора с помощью Microsoft Intune. Также во время обновления можно автоматически удалять компоненты, для которых прекратилась поддержка.
Источник: https://devblogs.microsoft.com/visualstudio/standard-user-update/
Обновление Visual Studio без Прав Администратора
В мире ИТ администраторам и организациям крайне важно эффективно управлять безопасностью и применять передовые методы обеспечения безопасности. Одна из распространённых практик предполагает внедрение соответствующих уровней разрешений, чтобы гарантировать, что только авторизованные учётные записи могут получить доступ к конфиденциальным данным и функциям. Ещё один полезный совет – регулярные обновления ПО с последними обновлениями безопасности.
До сих пор установщик Visual Studio требовал прав администратора, поскольку ему необходимо записывать в «защищённые» области Windows. Однако если у пользователя, запускающего установщик, нет необходимых повышенных разрешений, ему запрещалось использовать функции установщика для обновления или изменения Visual Studio. Таким образом во многих организациях разработчик с привилегиями обычного пользователя не мог получить обновления продукта.
Теперь обычные пользователи теперь могут обновлять и изменять Visual Studio, начиная с версии 17.7. Стандартным пользователям может быть предоставлена возможность полноценно использовать установщик для получения обновлений и внесения изменений в Visual Studio. Администратор должен явно делегировать управление обычному пользователю и включить эту функцию, выполнив два простых шага на клиентском компьютере:
1. Выполнить первоначальную установку. Для первого получения установщика на любом клиентском компьютере всегда требуются права администратора.
2. Настроить политику AllowStandardUserControl. Для настройки политик Visual Studio также потребуются права администратора.
После выполнения этих двух шагов обычный пользователь сможет получить доступ к любым функциям установщика и выполнять обновления, модификации и даже установку новых компонентов Visual Studio.
Другие функции управления безопасностью
Visual Studio значительно упростила для корпоративных администраторов соблюдение общих рекомендаций по обеспечению безопасности. Например, недавно администраторы получили возможность легко настраивать политики Visual Studio и включать автоматические ежемесячные обновления безопасности администратора с помощью Microsoft Intune. Также во время обновления можно автоматически удалять компоненты, для которых прекратилась поддержка.
Источник: https://devblogs.microsoft.com/visualstudio/standard-user-update/
👍3
День 1692. #ЗаметкиНаПолях
Общее Хранилище или Долгоживущие Ветки Функций?
Эффективные стратегиях разработки ПО, часто делятся на два подхода: разработка на основе общего хранилища кода и долгоживущие ветки функций. Каждый имеет свои преимущества и проблемы, и знание того, какой подход выбрать, может существенно повлиять на успех вашего проекта.
Общее хранилище
Подход к разработке ПО, при котором разработчики часто интегрируют свои изменения кода в одну общую ветку, известную как trunk. Цель — выполнять небольшие инкрементные обновления, чтобы минимизировать конфликты слияния и оптимизировать конвейер разработки. Непрерывная интеграция (CI) часто является неотъемлемой частью этой стратегии, поскольку позволяет быстро обнаруживать и решать проблемы.
Плюсы:
- CI обеспечивает мгновенную обратную связь, что упрощает раннее выявление проблем.
- Слияние становится проще благодаря частым интеграциям.
- Частые слияния улучшают общение в команде.
- Функции можно развёртывать быстрее и чаще.
- Единый источник достоверной информации (общая ветка) упрощает настройку CI/CD.
Минусы:
- Без надежных автоматизированных тестов может быть рискованным. Важно знать, что каждое новое изменение не сломало что-то в системе.
- Значительные обновления может быть сложно реализовать поэтапно. Хотя, крупные изменения в качестве исключения могут быть выделены в отдельные ветки.
- Флаги функций могут добавить дополнительный уровень сложности. Условная логика добавляет хаоса, и после добавления функций необходимо приложить дополнительные усилия для удаления условных операторов.
Долгоживущие* ветки функций
Этот подход предполагает создание отдельных веток для разработки новых функций или внесения существенных изменений. Они существуют независимо от основной в течение длительного периода времени, что позволяет разработчикам работать изолированно. Как только функция или изменение готовы и протестированы, ветка сливается с основной, что часто требует всестороннего анализа и потенциально сложного разрешения конфликтов.
*Термин «долгоживущий» даётся без какой-либо конкретной меры. Его «долголетие» зависит от того, насколько активна кодовая база. Важным фактором является количество изменений в основной ветке с момента открытия ветки функции, а не календарное время.
Плюсы:
- Разработчики могут работать над большими функциями, не затрагивая основную ветку.
- Основная ветка остается стабильной. Легче гарантировать, что только проверенный рабочий код будет разрешён для слияния с основной веткой.
- Идеально подходит для реализации значительных изменений.
- Функции можно выпускать массово, используя (ещё одну) ветку для релиза и объединяя несколько веток функций в ветку релиза. Особенно полезно для взаимозависимых функций.
Минусы:
- Чем старше ветка, тем сложнее её объединить. Разрешение конфликтов слияния может отнять значительное время, если веткам часто позволено отклоняться от основной на длительные периоды времени.
- Интеграция происходит реже. Проблемы и несовместимости между функциями будут обнаружены позже, часто только после попытки слияния.
- Работа в изоляции может оказаться контрпродуктивной. Дублирование кода, недопонимание, застой в работе и т.п. могут встречаться чаще в изолированной ветке, чем в основной, над которой активно работает вся команда.
- Ветка функции может значительно отличаться от основной. Обычно это происходит, когда разработка основной ветки продолжается. Слияние изменений из основной ветки в ветку функции может смягчить эту ситуацию, но часто игнорируется членами команды.
Итого
Оба подхода могут иметь смысл в разных контекстах. Если вы используете один подход, а кто-то из команды предлагает другой, подумайте над этим. Что выбор во многом зависит от потребностей вашей команды, сложности проекта и требований бизнеса. Лучшая стратегия — та, которая адаптируется к потребностям вашего проекта и одновременно смягчает его проблемы. Это не вопрос универсального подхода, а поиск идеального решения для вашей команды.
Источник
Общее Хранилище или Долгоживущие Ветки Функций?
Эффективные стратегиях разработки ПО, часто делятся на два подхода: разработка на основе общего хранилища кода и долгоживущие ветки функций. Каждый имеет свои преимущества и проблемы, и знание того, какой подход выбрать, может существенно повлиять на успех вашего проекта.
Общее хранилище
Подход к разработке ПО, при котором разработчики часто интегрируют свои изменения кода в одну общую ветку, известную как trunk. Цель — выполнять небольшие инкрементные обновления, чтобы минимизировать конфликты слияния и оптимизировать конвейер разработки. Непрерывная интеграция (CI) часто является неотъемлемой частью этой стратегии, поскольку позволяет быстро обнаруживать и решать проблемы.
Плюсы:
- CI обеспечивает мгновенную обратную связь, что упрощает раннее выявление проблем.
- Слияние становится проще благодаря частым интеграциям.
- Частые слияния улучшают общение в команде.
- Функции можно развёртывать быстрее и чаще.
- Единый источник достоверной информации (общая ветка) упрощает настройку CI/CD.
Минусы:
- Без надежных автоматизированных тестов может быть рискованным. Важно знать, что каждое новое изменение не сломало что-то в системе.
- Значительные обновления может быть сложно реализовать поэтапно. Хотя, крупные изменения в качестве исключения могут быть выделены в отдельные ветки.
- Флаги функций могут добавить дополнительный уровень сложности. Условная логика добавляет хаоса, и после добавления функций необходимо приложить дополнительные усилия для удаления условных операторов.
Долгоживущие* ветки функций
Этот подход предполагает создание отдельных веток для разработки новых функций или внесения существенных изменений. Они существуют независимо от основной в течение длительного периода времени, что позволяет разработчикам работать изолированно. Как только функция или изменение готовы и протестированы, ветка сливается с основной, что часто требует всестороннего анализа и потенциально сложного разрешения конфликтов.
*Термин «долгоживущий» даётся без какой-либо конкретной меры. Его «долголетие» зависит от того, насколько активна кодовая база. Важным фактором является количество изменений в основной ветке с момента открытия ветки функции, а не календарное время.
Плюсы:
- Разработчики могут работать над большими функциями, не затрагивая основную ветку.
- Основная ветка остается стабильной. Легче гарантировать, что только проверенный рабочий код будет разрешён для слияния с основной веткой.
- Идеально подходит для реализации значительных изменений.
- Функции можно выпускать массово, используя (ещё одну) ветку для релиза и объединяя несколько веток функций в ветку релиза. Особенно полезно для взаимозависимых функций.
Минусы:
- Чем старше ветка, тем сложнее её объединить. Разрешение конфликтов слияния может отнять значительное время, если веткам часто позволено отклоняться от основной на длительные периоды времени.
- Интеграция происходит реже. Проблемы и несовместимости между функциями будут обнаружены позже, часто только после попытки слияния.
- Работа в изоляции может оказаться контрпродуктивной. Дублирование кода, недопонимание, застой в работе и т.п. могут встречаться чаще в изолированной ветке, чем в основной, над которой активно работает вся команда.
- Ветка функции может значительно отличаться от основной. Обычно это происходит, когда разработка основной ветки продолжается. Слияние изменений из основной ветки в ветку функции может смягчить эту ситуацию, но часто игнорируется членами команды.
Итого
Оба подхода могут иметь смысл в разных контекстах. Если вы используете один подход, а кто-то из команды предлагает другой, подумайте над этим. Что выбор во многом зависит от потребностей вашей команды, сложности проекта и требований бизнеса. Лучшая стратегия — та, которая адаптируется к потребностям вашего проекта и одновременно смягчает его проблемы. Это не вопрос универсального подхода, а поиск идеального решения для вашей команды.
Источник
👍7
День 1693. #ЧтоНовенького
Доступ к Закрытым Членам Класса без Рефлексии в .NET 8
Закрытые члены класса в C# создаются для того, чтобы к ним нельзя было получить доступ извне. Но если нельзя, а очень хочется… то в .NET 8 появился ещё один способ получить к ним доступ без использования рефлексии.
Рассмотрим следующий класс:
Конструкторы
Используем "ref", чтобы получить ссылку на поле для чтения и записи в него:
Аналогично со статическими полями. Как и для статических методов, необходим аргумент с типом класса:
Помните, что имя атрибута начинается с "Unsafe", потому что позволяет делать небезопасные вещи.
Источник: https://www.meziantou.net/accessing-private-members-without-reflection-in-csharp.htm
Доступ к Закрытым Членам Класса без Рефлексии в .NET 8
Закрытые члены класса в C# создаются для того, чтобы к ним нельзя было получить доступ извне. Но если нельзя, а очень хочется… то в .NET 8 появился ещё один способ получить к ним доступ без использования рефлексии.
Рассмотрим следующий класс:
class Sample.NET 8 предоставляет новый атрибут
{
// Конструкторы
private Sample() { }
private Sample(int value) { }
// Поле
private int field1 = 1;
// Статическое поле
private static int staticField = 2;
// Методы
private int Method(int value) => value;
private static int StaticMethod(int value) => value;
}
[UnsafeAccessor]
. Чтобы получить доступ к закрытому члену, вы можете объявить внешний (extern) метод с атрибутом [UnsafeAccessor]
, чтобы объявить метод доступа для закрытого члена. Реализация метода, аннотированного этим атрибутом, будет предоставлена средой выполнения на основе информации в атрибуте и сигнатуры метода, к которому применяется атрибут. Обратите внимание, что UnsafeAccessor менее функционален, чем рефлексия. Например, вы не можете получить доступ к свойствам, а также обобщённые типы пока не полностью поддерживаются.Конструкторы
var sample1 = CallConstructor();Методы
var sample2 = CallConstructorWithArg(1);
// Возвращаемый тип метода должен быть типом класса
[UnsafeAccessor(
UnsafeAccessorKind.Constructor)]
extern static Sample CallConstructor();
[UnsafeAccessor(
UnsafeAccessorKind.Constructor)]
extern static Sample CallConstructorWithArg(int value);
var sample = CallConstructor();В статических методах так же. Несмотря на то, что экземпляр не требуется, среда выполнения должна знать тип:
Console.WriteLine(Method(sample, 1));
// Первый аргумент – экземпляр класса
[UnsafeAccessor(
UnsafeAccessorKind.Method,
Name = "Method")]
extern static int
Method(Sample @this, int value);
Console.WriteLine(StaticMethod(null, 2));Поля
[UnsafeAccessor(
UnsafeAccessorKind.StaticMethod,
Name = "StaticMethod")]
extern static int StaticMethod(Sample @this, int value);
Используем "ref", чтобы получить ссылку на поле для чтения и записи в него:
[UnsafeAccessor(UnsafeAccessorKind.Field,В readonly поля также возможна запись, как и при использовании рефлексии.
Name = "field1")]
extern static ref int
GetField(Sample @this);
var sample = CallConstructor();
_ = GetField(sample);
GetField(sample) = 42;
Аналогично со статическими полями. Как и для статических методов, необходим аргумент с типом класса:
[UnsafeAccessor(Вы можете записывать в static readonly поля, но с осторожностью. Эти поля очень похожи на константы для JIT. Поэтому запись значения в них может приводить к непредсказуемому поведению, т.к. значение может не читаться повторно в дальнейшем. Заметьте, что это невозможно при использовании рефлексии.
UnsafeAccessorKind.StaticField,
Name = "staticField")]
extern static ref int
GetStaticField(Sample @this);
_ = GetStaticField(sample);
Помните, что имя атрибута начинается с "Unsafe", потому что позволяет делать небезопасные вещи.
Источник: https://www.meziantou.net/accessing-private-members-without-reflection-in-csharp.htm
👍11
День 1694.
DotNext 2023
Посетил конференцию DotNext 2023. Это мой первый опыт офлайн конференции. Вот некоторые фотки оттуда. Доклады выбирал по степени полезности для текущей работы, поэтому некоторые хотел, но не посетил, обязательно посмотрю в записи.
Были и другие активности. Великолепно неформально с Антоном Оникийчуком и Юлией Цисык про найм в .NET. Чего ждут работодатели, случаи были на собеседовании, красные флаги для компаний и для кандидатов и о многом другом. Множество шуток, баек и полезной информации. К концу 3го часа Антон с Юлей взмолились отпустить их домой :)
PVS-Studio предлагали задачки на поиск ошибок (я молодец, заслужил пряник – реальный тульский пряник). Positive Technologies - найти уязвимости в примерах кода. А также можно было поиграть на старых консольках, пособирать деревянные паззлы или потыкать механические клавиатуры.
В общем, если у вас будет возможность, советую посещать конференции офлайн. А ещё лучше там выступить, в DotNext уже принимают заявки.
DotNext 2023
Посетил конференцию DotNext 2023. Это мой первый опыт офлайн конференции. Вот некоторые фотки оттуда. Доклады выбирал по степени полезности для текущей работы, поэтому некоторые хотел, но не посетил, обязательно посмотрю в записи.
Были и другие активности. Великолепно неформально с Антоном Оникийчуком и Юлией Цисык про найм в .NET. Чего ждут работодатели, случаи были на собеседовании, красные флаги для компаний и для кандидатов и о многом другом. Множество шуток, баек и полезной информации. К концу 3го часа Антон с Юлей взмолились отпустить их домой :)
PVS-Studio предлагали задачки на поиск ошибок (я молодец, заслужил пряник – реальный тульский пряник). Positive Technologies - найти уязвимости в примерах кода. А также можно было поиграть на старых консольках, пособирать деревянные паззлы или потыкать механические клавиатуры.
В общем, если у вас будет возможность, советую посещать конференции офлайн. А ещё лучше там выступить, в DotNext уже принимают заявки.
👍46👎1