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

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День 2522. #Карьера
Топ Советов по Повышению Продуктивности. Часть 2
Часть 1

2. Агрессивный таймбоксинг: техника Помодоро для разработчиков (на этот раз действительно работающая)
Да, да, все уже слышали о Помодоро. 25 минут работы, 5 минут перерыва, и так до бесконечности. В теории звучит отлично, а на практике… Вы уже 11 минут сосредоточенно работаете над кодом, когда срабатывает таймер, и вы должны просто… остановиться? На полпути? Когда вы наконец-то вошли в «поток»? Да ни за что!

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

Помодоро для разработчиков, или «агрессивный таймбоксинг».
Вместо жестких 25-минутных интервалов используйте таймбоксинг, основанный на естественных границах работы, и поддерживайте строгие правила относительно того, что происходит, когда таймер достигает нуля.

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

Шаг 2: Честно оцените время. Это займёт 30 минут? 45? 90? Будьте реалистичны. Добавьте 25% к тому, что подсказывает интуиция, потому что вы, вероятно, недооцениваете.

Шаг 3: Установите таймер и начните. Важно: не останавливайтесь, когда срабатывает таймер. Вместо этого оцените результат:
- Вы «в потоке»? Добавьте ещё один временной интервал и продолжайте.
- Застряли? Это естественная точка остановки. Сделайте перерыв.
- Слишком часто переключаетесь между задачами? Таймер вас поймал — признайте, что выбились из рабочего ритма, перефокусируйтесь или сделайте перерыв.

Шаг 4: После 2-3 последовательных временных интервалов (90-120 минут) сделайте настоящий перерыв. Не перерыв для проверки мессенджеров. Прогуляйтесь по офису или выйдите на улицу, по-настоящему отключитесь от работы.

Главное: Отслеживайте каждый временной интервал в простом документе. Записывайте, над чем вы работали и закончили ли. Это создаёт подотчетность и, что более важно, данные. Через неделю вы увидите закономерности:
- заметите, что всегда недооцениваете работу с БД на 40%;
- увидите, что дневные/вечерние временные интервалы менее продуктивны.
У вас будут реальные доказательства для улучшения планирования.

Настоящая польза: дело не в таймере или перерывах. Дело в осознании того, как вы работаете. Как только вы узнаете свои паттерны — когда вы наиболее сосредоточены, как долго можете поддерживать глубокую работу, какие задачи всегда выходят за рамки оценок — вы сможете соответствующим образом планировать свой день: планировать наиболее сложную работу на наиболее продуктивные интервалы. Это не продуктивность, основанная на мотивации; это биология. Вы работаете в соответствии со своими естественными ритмами, а не против них.

Источник: https://dev.to/thebitforge/top-10-productivity-hacks-every-developer-should-know-151h
👍14
День 2523. #ВопросыНаСобеседовании
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.

14. Внедрение зависимостей в .NET
«Как реализовать внедрение зависимостей (DI) в приложении .NET, и каковы основные преимущества использования DI? Пожалуйста, приведите примеры кода, демонстрирующие, как настроить и использовать DI для управления сервисами и зависимостями».

Хороший ответ
Внедрение зависимостей в .NET — это метод, используемый для достижения слабой связанности между объектами и их зависимостями. Используя DI-контейнер, .NET управляет созданием и внедрением зависимостей вместо того, чтобы классы сами их создавали. Такой подход упрощает проектирование классов, повышает модульность и улучшает тестируемость приложений.

Для реализации DI в .NET обычно определяют сервисы и интерфейсы, а затем регистрируют их во встроенном DI-контейнере в файле Program.cs, как показано в следующем коде:
var builder = WebApplication.CreateBuilder(args);

// Регистрируем Scoped-сервис
builder.Services.AddScoped<IService, MyService>();

var app = builder.Build();

// Используем сервис в компоненте приложения
app.MapGet("/", (IService service) => {
return service.PerformOperation();
});

app.Run();

В этом примере IService — интерфейс, а MyService — класс, реализующий его. Сервис регистрируется как имеющий область видимости (scoped), то есть для каждого запроса будет создаваться новый экземпляр, но он будет использоваться совместно в рамках одного запроса. Другие распространённые варианты:
- transient - новый экземпляр создаётся при каждом использовании;
- singleton – создаётся один экземпляр на всё время жизни приложения.

Ключевые преимущества использования DI:
- Слабая связанность: Объекты не имеют жёстко заданных зависимостей. Это упрощает модификацию и расширение системы.
- Удобство тестирования: Зависимости можно заменять моками или заглушками во время тестирования, что упрощает написание тестов и повышает их надёжность.
- Централизованная конфигурация: Управление созданием объектов и разрешением зависимостей в одном месте делает код чище, а приложение — более масштабируемым.

Часто встречающийся неверный ответ
«В .NET достаточно добавить сервисы в файл Program.cs, используя builder.Services.AddSingleton() или любой аналогичный метод, и .NET автоматически обработает все требования DI без дополнительной настройки».

Этот ответ демонстрирует неполное понимание DI:
- Недостаток деталей о потреблении зависимостей: В ответе упоминается добавление сервисов в DI-контейнер, но не объясняется, как эти сервисы потребляются в приложении. Простая регистрация сервиса не завершает процесс DI; разработчики также должны внедрять эти сервисы в компоненты, где они необходимы.

- Чрезмерное упрощение DI: Ответ подразумевает, что DI не требует тщательного рассмотрения времени жизни сервисов или того, как зависимости внедряются в потребляющие классы. Он упускает из виду важность выбора правильного времени жизни сервиса (singleton, scoped, transient) в зависимости от варианта использования.

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

Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
День 2524. #SystemDesign101
8 Распространённых Проблем Проектирования Систем и их Решения

1. Система с нагрузкой на чтение
- Используйте кэширование для ускорения операций чтения.

2. Большой трафик на запись
- Используйте асинхронные рабочие процессы для обработки операций записи.
- Используйте базы данных на основе LSM-деревьев.

3. Единая точка отказа
- Внедрите механизмы дублирования и отказоустойчивости для критически важных компонентов, таких как базы данных.

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

5. Высокие задержки
- Используйте сеть доставки контента (CDN) для уменьшения задержек.

6. Обработка больших файлов
- Используйте блочное и объектное хранилище для обработки больших файлов и сложных данных.

7. Мониторинг и уведомления
- Используйте централизованную систему логирования, например, стек ELK.

8. Медленные запросы к базе данных
- Используйте правильные индексы для оптимизации запросов.
- Используйте шардинг для горизонтального масштабирования базы данных.

Источник: https://bytebytego.com/guides/8-common-system-design-problems-and-solutions/
👍6👎1
День 2525. #ЗаметкиНаПолях
Разбираем Веб-Метки Файлов в .NET

Веб-метка (Mark of the Web, MOTW) — это функция безопасности Windows, которая защищает пользователей от потенциально опасных файлов, загружаемых из интернета. При загрузке файла Windows автоматически добавляет специальный метатег, указывающий на то, что файл получен из ненадёжного источника и может содержать вредоносный контент. При попытке открыть файл с MOTW Windows отображает предупреждение или запрашивает подтверждение перед открытием.

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

MOTW реализован как альтернативный поток данных (ADS), прикреплённый к файлу. ADS содержит информацию об источнике файла, включая URL, с которого он был загружен, и его зону безопасности:
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://www.google.com/

ZoneId обозначает зону безопасности:
0 - Local Machine
1 - Intranet
2 - Trusted Sites
3 - Internet
4 - Untrusted

Мы можем использовать интерфейс IInternetSecurityManager для проверки файлов. Создадим консольное приложение.

Нам понадобятся:
- пакет Microsoft.Windows.CsWin32, который содержит генератор кода для работы с Win32;
- файл NativeMethods.txt в корне проекта с перечислением нужных нам API:
CoInternetCreateSecurityManager
MUTZ_NOSAVEDFILECHECK
MUTZ_REQUIRESAVEDFILECHECK

- вспомогательный enum:
enum UrlZone
{
Invalid = -1,
LocalMachine = 0,
Intranet = 1,
Trusted = 2,
Internet = 3,
Untrusted = 4,
}

Создадим статический класс для проверки MOTW:
public static class MOTW
{
[SupportedOSPlatform("windows")]
public static bool IsUntrusted(string path)
{
path = Path.GetFullPath(path);

var hr = PInvoke
.CoInternetCreateSecurityManager(
null,
out var secMgr,
0
);

if (hr.Failed || secMgr is null)
return true;

try
{
secMgr.MapUrlToZone(
path,
out var zone,
PInvoke.MUTZ_NOSAVEDFILECHECK);
if (zone >= (int)UrlZone.Internet)
return true;

secMgr.MapUrlToZone(
path,
out zone,
PInvoke.MUTZ_REQUIRESAVEDFILECHECK);
if (zone >= (int)UrlZone.Internet)
return true;

return false;
}
finally
{
Marshal.ReleaseComObject(secMgr);
}
}
}

Мы проверяем и сохраняемые, и уже сохранённые в доверенных зонах файлы.

Использование:
var path = @"C:\Users\user\Downloads\file.txt";
bool isUntrusted = MarkOfTheWeb.IsUntrusted(path);

Полный код, содержащий также методы установки и удаления ADS, см. в GitHub Meziantou.

Источник: https://www.meziantou.net/understanding-and-managing-mark-of-the-web-in-dotnet.htm
👍6