День 2160. #УрокиРазработки
Уроки 50 Лет Разработки ПО
Урок 37. Не ждите, что без обучения и освоения передовых практик продуктивность повысится как по волшебству. Окончание
Начало
Инструменты и обучение
Правильно подобранные инструменты могут повысить продуктивность. В действительности прирост продуктивности, вызванный использованием одного нового инструмента, редко превышает 35%. Продуктивность разработчиков ПО с годами растёт благодаря накопленным преимуществам нескольких инструментов, новым языкам и методам разработки, повторному использованию ПО и другим факторам. Не забывайте учитывать затраты на обучение, в ходе которого люди выясняют, как заставить новый инструмент работать эффективно. Ищите инструменты, позволяющие автоматизировать и документировать повторяющиеся задачи, такие как тестирование.
Обучение — мощный рычаг повышения продуктивности. Руководители, пытающиеся сделать больше с меньшими затратами, могут не решаться оторвать членов команды от работы на прохождение обучения, да и курсы стоят дорого. Но посчитайте. Сэкономив хотя бы час-два на своей работе (в любое время до конца жизни) за счёт того, что вы узнали из книги, вы с лихвой окупите затраченные на неё деньги. Инвестиции в обучение окупаются всегда, если новая практика, позволяющая получить более качественный результат за меньшее время, применяется в работе.
Индивидуальные особенности разработчиков
Любому хотелось бы думать, что в его команде собрались самые талантливые специалисты. Но половина всех программистов по своей продуктивности находится ниже медианы. Все эти люди где-то работают, и не у каждого руководителя есть возможность нанять специалистов высшей квалификации. Нелегко количественно оценить продуктивность разработчика ПО, но нередко продуктивность и качество команды зависят от того, кому будет поручена работа.
В многочисленных публикациях по разработке ПО отмечается десятикратный и более разброс в продуктивности между лучшими и худшими исполнителями. Однако в недавнем отчёте Билла Николса (Bill Nichols) из Software Engineering Institute утверждается, что это миф, и индивидуальные особенности могут увеличить продуктивность разработчиков максимум в два раза в любой конкретной деятельности.
Нет сомнений, что квалифицированные и талантливые люди и команды работают более продуктивно. Неудивительно, что, согласно отчету The Standish Group (2015), проекты, укомплектованные «одаренными» командами, использующими методы Agile-разработки, оказались более успешными, чем проекты, реализуемые низкоквалифицированными командами. При этом интересно отметить, что небольшие проекты имели более высокий уровень успеха, чем крупные. Возможно, это объясняется тем, что небольшую команду проще укомплектовать высококвалифицированными специалистами. Но не каждый может позволить себе нанимать лучших из лучших.
Если вы не можете собрать звёздную команду, то сосредоточьтесь на создании продуктивного окружения, чтобы добиться наилучших результатов от тех, кто у вас есть. Развивайте таланты каждого, делитесь передовым опытом. Постарайтесь понять, в чём секрет успеха ваших лучших работников (они известны всем), и поощряйте всех, кто учится у них. Технические навыки важны, но не менее ценны общение, сотрудничество, наставничество и отношение к продукту как к общей собственности. Лучшие разработчики, уделяют большое внимание качеству. Они проявляют интеллектуальную любознательность, обладают обширным опытом, постоянно занимаются самообучением и всегда готовы делиться знаниями.
Если вы должны делать больше с меньшими затратами, то не добьётесь желаемого, отдавая ничем не подкрепленные приказы, оказывая больше давления на команду или нанимая таланты только из 90-го процентиля. Путь к повышению продуктивности неизбежно состоит из обучения, овладения передовыми практиками и совершенствования процессов.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
Уроки 50 Лет Разработки ПО
Урок 37. Не ждите, что без обучения и освоения передовых практик продуктивность повысится как по волшебству. Окончание
Начало
Инструменты и обучение
Правильно подобранные инструменты могут повысить продуктивность. В действительности прирост продуктивности, вызванный использованием одного нового инструмента, редко превышает 35%. Продуктивность разработчиков ПО с годами растёт благодаря накопленным преимуществам нескольких инструментов, новым языкам и методам разработки, повторному использованию ПО и другим факторам. Не забывайте учитывать затраты на обучение, в ходе которого люди выясняют, как заставить новый инструмент работать эффективно. Ищите инструменты, позволяющие автоматизировать и документировать повторяющиеся задачи, такие как тестирование.
Обучение — мощный рычаг повышения продуктивности. Руководители, пытающиеся сделать больше с меньшими затратами, могут не решаться оторвать членов команды от работы на прохождение обучения, да и курсы стоят дорого. Но посчитайте. Сэкономив хотя бы час-два на своей работе (в любое время до конца жизни) за счёт того, что вы узнали из книги, вы с лихвой окупите затраченные на неё деньги. Инвестиции в обучение окупаются всегда, если новая практика, позволяющая получить более качественный результат за меньшее время, применяется в работе.
Индивидуальные особенности разработчиков
Любому хотелось бы думать, что в его команде собрались самые талантливые специалисты. Но половина всех программистов по своей продуктивности находится ниже медианы. Все эти люди где-то работают, и не у каждого руководителя есть возможность нанять специалистов высшей квалификации. Нелегко количественно оценить продуктивность разработчика ПО, но нередко продуктивность и качество команды зависят от того, кому будет поручена работа.
В многочисленных публикациях по разработке ПО отмечается десятикратный и более разброс в продуктивности между лучшими и худшими исполнителями. Однако в недавнем отчёте Билла Николса (Bill Nichols) из Software Engineering Institute утверждается, что это миф, и индивидуальные особенности могут увеличить продуктивность разработчиков максимум в два раза в любой конкретной деятельности.
Нет сомнений, что квалифицированные и талантливые люди и команды работают более продуктивно. Неудивительно, что, согласно отчету The Standish Group (2015), проекты, укомплектованные «одаренными» командами, использующими методы Agile-разработки, оказались более успешными, чем проекты, реализуемые низкоквалифицированными командами. При этом интересно отметить, что небольшие проекты имели более высокий уровень успеха, чем крупные. Возможно, это объясняется тем, что небольшую команду проще укомплектовать высококвалифицированными специалистами. Но не каждый может позволить себе нанимать лучших из лучших.
Если вы не можете собрать звёздную команду, то сосредоточьтесь на создании продуктивного окружения, чтобы добиться наилучших результатов от тех, кто у вас есть. Развивайте таланты каждого, делитесь передовым опытом. Постарайтесь понять, в чём секрет успеха ваших лучших работников (они известны всем), и поощряйте всех, кто учится у них. Технические навыки важны, но не менее ценны общение, сотрудничество, наставничество и отношение к продукту как к общей собственности. Лучшие разработчики, уделяют большое внимание качеству. Они проявляют интеллектуальную любознательность, обладают обширным опытом, постоянно занимаются самообучением и всегда готовы делиться знаниями.
Если вы должны делать больше с меньшими затратами, то не добьётесь желаемого, отдавая ничем не подкрепленные приказы, оказывая больше давления на команду или нанимая таланты только из 90-го процентиля. Путь к повышению продуктивности неизбежно состоит из обучения, овладения передовыми практиками и совершенствования процессов.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
👍10
День 2161. #ЗаметкиНаПолях
Планировка Фоновых Задач с Помощью Quartz. Начало
Большинству приложений ASP.NET Core необходимо обрабатывать фоновые задачи. Хотя существует множество способов их реализации, Quartz.NET выделяется своими надёжными возможностями планирования, настройкой хранения заданий и богатой функциональностью. Основы Quartz в этом посте. Здесь рассмотрим некоторые продвинутые настройки. Извините за многокода.
Настройка Телеметрии Quartz в ASP.NET Core
Сначала установим пакеты Quartz:
Также потребуются некоторые пакеты OpenTelemetry.
Затем настроим сервисы Quartz и инструментарий OpenTelemetry:
Определение и планирование заданий
Все задания реализуют IJob и выполняются как сервисы с ограниченной областью действия, поэтому при необходимости можно внедрять зависимости. Quartz позволяет передавать данные заданию с помощью словаря JobDataMap. Рекомендуется использовать только примитивные типы для данных задания, чтобы избежать проблем с сериализацией и использовать MergedJobDataMap для извлечения данных задания.
Создадим задание для email-напоминания:
Замечание: JobDataMap не строго типизирован. Поэтому рекомендуется:
- Использовать константы для ключей;
- Проверять данные в методе Execute;
- Создавать сервисы-обёртки для планирования заданий.
Вот как запланировать одноразовые напоминания:
Конечная точка планирует одноразовые напоминания по email с помощью Quartz. Она создаёт задание с данными пользователя, устанавливает триггер на указанное время и планирует их. EmailJob получает уникальный идентификатор в группе "email-reminders".
Пример запроса:
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/scheduling-background-jobs-with-quartz-in-dotnet-advanced-concepts
Планировка Фоновых Задач с Помощью Quartz. Начало
Большинству приложений ASP.NET Core необходимо обрабатывать фоновые задачи. Хотя существует множество способов их реализации, Quartz.NET выделяется своими надёжными возможностями планирования, настройкой хранения заданий и богатой функциональностью. Основы Quartz в этом посте. Здесь рассмотрим некоторые продвинутые настройки. Извините за многокода.
Настройка Телеметрии Quartz в ASP.NET Core
Сначала установим пакеты Quartz:
Install-Package Quartz.Extensions.Hosting
Install-Package Quartz.Serialization.Json
# Пока в предрелизе
Install-Package OpenTelemetry.Instrumentation.Quartz
Также потребуются некоторые пакеты OpenTelemetry.
Затем настроим сервисы Quartz и инструментарий OpenTelemetry:
builder.Services.AddQuartz();
builder.Services.AddQuartzHostedService(opts =>
{
opts.WaitForJobsToComplete = true;
});
builder.Services.AddOpenTelemetry()
.WithTracing(trc =>
{
trc
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation()
.AddQuartzInstrumentation();
})
.UseOtlpExporter();
Определение и планирование заданий
Все задания реализуют IJob и выполняются как сервисы с ограниченной областью действия, поэтому при необходимости можно внедрять зависимости. Quartz позволяет передавать данные заданию с помощью словаря JobDataMap. Рекомендуется использовать только примитивные типы для данных задания, чтобы избежать проблем с сериализацией и использовать MergedJobDataMap для извлечения данных задания.
Создадим задание для email-напоминания:
public class EmailJob(
IEmailService emailSvc) : IJob
{
public const string Name = nameof(EmailJob);
public async Task Execute(
IJobExecutionContext ctx)
{
var data = ctx.MergedJobDataMap;
try
{
await emailSvc.SendAsync(
data.GetString("userId"),
data.GetString("message"));
}
catch (Exception ex)
{
// … обработка … и throw,
// чтобы Quartz попробовал снова
throw;
}
}
}
Замечание: JobDataMap не строго типизирован. Поэтому рекомендуется:
- Использовать константы для ключей;
- Проверять данные в методе Execute;
- Создавать сервисы-обёртки для планирования заданий.
Вот как запланировать одноразовые напоминания:
public record Reminder(
string UserId,
string Message,
DateTime ScheduleTime
);
app.MapPost("/api/reminders/schedule", async (
ISchedulerFactory schFactory,
Reminder rem) =>
{
var scheduler = await schFactory.GetScheduler();
var jobData = new JobDataMap
{
{ "userId", rem.UserId },
{ "message", rem.Message }
};
var group = "email-reminders";
var job = JobBuilder.Create<EmailJob>()
.WithIdentity(
$"reminder-{Guid.NewGuid()}", group)
.SetJobData(jobData)
.Build();
var trigger = TriggerBuilder.Create()
.WithIdentity(
$"trigger-{Guid.NewGuid()}", group)
.StartAt(rem.ScheduleTime)
.Build();
await scheduler.ScheduleJob(job, trigger);
return Results.Ok(new
{
scheduled = true,
at = rem.ScheduleTime
});
})
.WithName("ScheduleReminder")
.WithOpenApi();
Конечная точка планирует одноразовые напоминания по email с помощью Quartz. Она создаёт задание с данными пользователя, устанавливает триггер на указанное время и планирует их. EmailJob получает уникальный идентификатор в группе "email-reminders".
Пример запроса:
POST /api/reminders/schedule
{
"userId": "user42",
"message": "Meeting!",
"scheduleTime": "2024-12-31T23:00:00"
}
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/scheduling-background-jobs-with-quartz-in-dotnet-advanced-concepts
👍10
День 2162. #ЗаметкиНаПолях
Планировка Фоновых Задач с Помощью Quartz. Окончание
Начало
Планирование повторяющихся заданий
Для повторяющихся фоновых заданий можно использовать расписания cron:
Триггеры Cron более эффективны, чем простые. Они позволяют определять сложные расписания, например «каждый будний день в 10 утра»:
Настройка хранения заданий
По умолчанию Quartz использует хранилище в памяти, т.е. задания теряются при перезапуске приложения. Для постоянного хранения поддерживается несколько провайдеров БД. Вот как настроить постоянное хранилище с надлежащей изоляцией схемы:
Замечания:
- TablePrefix помогает организовать таблицы Quartz - в данном случае, помещая их в отдельную схему scheduler;
- Нужно будет запустить соответствующие скрипты БД для создания этих таблиц. Каждый поставщик БД имеет свои скрипты настройки.
Долгосрочные Задания
Мы настроили EmailJob с StoreDurably. Это позволяет определить задание 1 раз и повторно использовать его с разными триггерами:
Такой подход имеет несколько преимуществ:
- Определения заданий централизованы в стартовой конфигурации;
- Не получится случайно запланировать задание, которое не было правильно настроено;
- Конфигурации заданий согласованы во всех расписаниях.
Источник: https://www.milanjovanovic.tech/blog/scheduling-background-jobs-with-quartz-in-dotnet-advanced-concepts
Планировка Фоновых Задач с Помощью Quartz. Окончание
Начало
Планирование повторяющихся заданий
Для повторяющихся фоновых заданий можно использовать расписания cron:
public record RecurringReminder(
string UserId,
string Message,
string CronExpression
);
app.MapPost("/api/recurring/schedule", async (
ISchedulerFactory schFactory,
RecurringReminder rem) =>
{
var scheduler = await schFactory.GetScheduler();
var jobData = new JobDataMap
{
{ "userId", rem.UserId },
{ "message", rem.Message }
};
var group = "recurring-reminders";
var job = JobBuilder.Create<EmailJob>()
.WithIdentity(
$"recurring-{Guid.NewGuid()}", group)
.SetJobData(jobData)
.Build();
var trigger = TriggerBuilder.Create()
.WithIdentity(
$"rectrigger-{Guid.NewGuid()}", group)
.WithCronSchedule(rem.CronExpression)
.Build();
await scheduler.ScheduleJob(job, trigger);
return Results.Ok(new {
scheduled = true,
cron = rem.CronExpression });
})
.WithName("RecurringReminder")
.WithOpenApi();
Триггеры Cron более эффективны, чем простые. Они позволяют определять сложные расписания, например «каждый будний день в 10 утра»:
POST /api/recurring/schedule
{
"userId": "user69",
"message": "Daily",
"cronExpression": "0 0 10 ? * MON-FRI"
}
Настройка хранения заданий
По умолчанию Quartz использует хранилище в памяти, т.е. задания теряются при перезапуске приложения. Для постоянного хранения поддерживается несколько провайдеров БД. Вот как настроить постоянное хранилище с надлежащей изоляцией схемы:
builder.Services.AddQuartz(opts =>
{
opts.AddJob<EmailJob>(c => c
.StoreDurably()
.WithIdentity(EmailJob.Name));
opts.UsePersistentStore(o =>
{
o.UsePostgres(cfg =>
{
cfg.ConnectionString = "…";
cfg.TablePrefix = "scheduler.qrtz_";
},
dataSourceName: "reminders"); // Имя БД
o.UseNewtonsoftJsonSerializer();
o.UseProperties = true;
});
});
Замечания:
- TablePrefix помогает организовать таблицы Quartz - в данном случае, помещая их в отдельную схему scheduler;
- Нужно будет запустить соответствующие скрипты БД для создания этих таблиц. Каждый поставщик БД имеет свои скрипты настройки.
Долгосрочные Задания
Мы настроили EmailJob с StoreDurably. Это позволяет определить задание 1 раз и повторно использовать его с разными триггерами:
public async Task ScheduleReminder(
string userId, string msg, DateTime dt)
{
var scheduler = await schFactory.GetScheduler();
// Извлекаем задание по его имени
var jobKey = new JobKey(EmailJob.Name);
var trigger = TriggerBuilder.Create()
// Используем задание по ссылке
.ForJob(jobKey)
.WithIdentity($"trigger-{Guid.NewGuid()}")
.UsingJobData("userId", userId)
.UsingJobData("message", msg)
.StartAt(dt)
.Build();
// Передаём только триггер
await scheduler.ScheduleJob(trigger);
}
Такой подход имеет несколько преимуществ:
- Определения заданий централизованы в стартовой конфигурации;
- Не получится случайно запланировать задание, которое не было правильно настроено;
- Конфигурации заданий согласованы во всех расписаниях.
Источник: https://www.milanjovanovic.tech/blog/scheduling-background-jobs-with-quartz-in-dotnet-advanced-concepts
5👍9
День 2163.
Дорогие подписчики, с новым 2025м годом!
.NET появился в начале века,
Стал любимой платформой для каждого человека.
От Windows Forms до ASP.NET,
Он покорил разработчиков свет.
C# и VB.NET были языки его,
На них кодить просто и легко.
WPF и WCF — его дети,
Служили верой и правдой всем на свете.
С каждым годом он рос и крепчал,
Новые фичи в себя включал.
.NET Core пришел на смену,
Кроссплатформенность — его арена.
Теперь .NET — это единая платформа,
Для устройств любого цвета и формы.
От мобильных до облачных решений,
.NET ведёт мир к новым свершениям.
(с) Copilot, естественно. Я бы так не написал 😄
Дорогие подписчики, с новым 2025м годом!
.NET появился в начале века,
Стал любимой платформой для каждого человека.
От Windows Forms до ASP.NET,
Он покорил разработчиков свет.
C# и VB.NET были языки его,
На них кодить просто и легко.
WPF и WCF — его дети,
Служили верой и правдой всем на свете.
С каждым годом он рос и крепчал,
Новые фичи в себя включал.
.NET Core пришел на смену,
Кроссплатформенность — его арена.
Теперь .NET — это единая платформа,
Для устройств любого цвета и формы.
От мобильных до облачных решений,
.NET ведёт мир к новым свершениям.
(с) Copilot, естественно. Я бы так не написал 😄
2👍51
День 2164. #Оффтоп
Никому Больше не Нравится Название .NET Core
Автор оригинала: Стивен Клири
Я подумал, что будет неплохо написать об истории терминологии «.NET Core». Вот каким я запомнил термин «.NET Core». Это не гарантирует правильности и, конечно, не гарантирует полноты! Я что-то упустил? Не стесняйтесь сообщить в комментариях!
.NET Compact Framework
Я думаю, что впервые услышал термин «.NET Core» в отношении .NET Compact Framework. Это было давно, когда .NET Framework 3.5 был новинкой. Точнее это был «.NET Framework 3.5 SP1» — Service Pack 1. Да, и у .NET раньше были пакеты обновлений.
Я не уверен, является ли «.NET Core» правильным термином для обозначения NetCF или нет. Насколько мне известно, это был неофициальный термин, который был применён, поскольку .NET Compact Framework содержал небольшое подмножество огромного .NET Framework, предназначенное для работы на встраиваемых устройствах. Следовательно, это был «основной» (core), минимальный, фреймворк.
Silverlight, WinRT, Windows Phone, Windows Store и Universal Windows Platform
Прошу прощенья у всех, кого передёрнуло от одного прочтения названия этого раздела…
Все эти технологии имели какое-то отношение к «.NET Core» как к термину. Все они были минимальными подфреймворками полной .NET Framework. И по крайней мере некоторые из них имели схожую терминологию для своих сред выполнения (например, Silverlight работал на «Core CLR»). Мой мозг милостиво забыл грязные подробности. Я только смутно помню, что платформа Windows Phone отличалась от платформы для приложений в Windows Store, а Silverlight стал ещё более урезанным для работы на Windows Phone.
Это было не самое весёлое время для разработчика библиотек.
netcore как моникер целевой платформы
Моникеры целевой платформы (Target framework moniker - TFM) очень важны для разработчиков библиотек.
Термин «.NET Core» официально вошёл в пространство NuGet как TFM, но не для того, что мы называем .NET Core сегодня. Он был для приложений Windows Store (и приложений WinRT) и ненадолго распространился на приложения UWP.
Да, проекты Windows Store ещё в Windows 8.0 (а также WinRT) использовали идентификатор TFM netcore45. Windows 8.1 использовал netcore451. Когда приложения Windows Store были заменены приложениями универсальной платформы Windows (UWP), они недолго использовали netcore50, прежде чем перейти на uap10.0.
Поэтому, если (современной) команде .NET Core вдруг понадобится TFM, они обнаружат, что netcoreNN недоступен. Я предполагаю, что именно поэтому был выбран моникер netcoreappNN (после краткого использования на dnxcore50 и aspnetcore50). Так что .NET Core TFM для старых версий (1.0-3.1) – это с netcoreapp1.0 до netcoreapp3.1. Это была просто досадная историческая случайность.
Больше никакого .NET Core
Команда .NET отказалась от «Core». Теперь у нас единый .NET — большое облегчение для авторов библиотек!
С версии 5 даже TFM изменились: современный .NET использует net9.0 и подобные, опустив прозвище «core» даже из TFM.
Я все ещё время от времени называю .NET как «.NET Core», особенно в разговорах, где упоминаются как .NET Framework, так и нового .NET. Например, я буду говорить «миграция на .NET Core», а не просто «миграция на .NET» для проекта, который в настоящее время нацелен на .NET Framework. Однако правильный термин больше не «.NET Core», а просто «.NET».
Источник: https://blog.stephencleary.com/2024/12/netcore.html
Никому Больше не Нравится Название .NET Core
Автор оригинала: Стивен Клири
Я подумал, что будет неплохо написать об истории терминологии «.NET Core». Вот каким я запомнил термин «.NET Core». Это не гарантирует правильности и, конечно, не гарантирует полноты! Я что-то упустил? Не стесняйтесь сообщить в комментариях!
.NET Compact Framework
Я думаю, что впервые услышал термин «.NET Core» в отношении .NET Compact Framework. Это было давно, когда .NET Framework 3.5 был новинкой. Точнее это был «.NET Framework 3.5 SP1» — Service Pack 1. Да, и у .NET раньше были пакеты обновлений.
Я не уверен, является ли «.NET Core» правильным термином для обозначения NetCF или нет. Насколько мне известно, это был неофициальный термин, который был применён, поскольку .NET Compact Framework содержал небольшое подмножество огромного .NET Framework, предназначенное для работы на встраиваемых устройствах. Следовательно, это был «основной» (core), минимальный, фреймворк.
Silverlight, WinRT, Windows Phone, Windows Store и Universal Windows Platform
Прошу прощенья у всех, кого передёрнуло от одного прочтения названия этого раздела…
Все эти технологии имели какое-то отношение к «.NET Core» как к термину. Все они были минимальными подфреймворками полной .NET Framework. И по крайней мере некоторые из них имели схожую терминологию для своих сред выполнения (например, Silverlight работал на «Core CLR»). Мой мозг милостиво забыл грязные подробности. Я только смутно помню, что платформа Windows Phone отличалась от платформы для приложений в Windows Store, а Silverlight стал ещё более урезанным для работы на Windows Phone.
Это было не самое весёлое время для разработчика библиотек.
netcore как моникер целевой платформы
Моникеры целевой платформы (Target framework moniker - TFM) очень важны для разработчиков библиотек.
Термин «.NET Core» официально вошёл в пространство NuGet как TFM, но не для того, что мы называем .NET Core сегодня. Он был для приложений Windows Store (и приложений WinRT) и ненадолго распространился на приложения UWP.
Да, проекты Windows Store ещё в Windows 8.0 (а также WinRT) использовали идентификатор TFM netcore45. Windows 8.1 использовал netcore451. Когда приложения Windows Store были заменены приложениями универсальной платформы Windows (UWP), они недолго использовали netcore50, прежде чем перейти на uap10.0.
Поэтому, если (современной) команде .NET Core вдруг понадобится TFM, они обнаружат, что netcoreNN недоступен. Я предполагаю, что именно поэтому был выбран моникер netcoreappNN (после краткого использования на dnxcore50 и aspnetcore50). Так что .NET Core TFM для старых версий (1.0-3.1) – это с netcoreapp1.0 до netcoreapp3.1. Это была просто досадная историческая случайность.
Больше никакого .NET Core
Команда .NET отказалась от «Core». Теперь у нас единый .NET — большое облегчение для авторов библиотек!
С версии 5 даже TFM изменились: современный .NET использует net9.0 и подобные, опустив прозвище «core» даже из TFM.
Я все ещё время от времени называю .NET как «.NET Core», особенно в разговорах, где упоминаются как .NET Framework, так и нового .NET. Например, я буду говорить «миграция на .NET Core», а не просто «миграция на .NET» для проекта, который в настоящее время нацелен на .NET Framework. Однако правильный термин больше не «.NET Core», а просто «.NET».
Источник: https://blog.stephencleary.com/2024/12/netcore.html
👍19👎2
День 2165. #Оффтоп #AI
ИИ не Заменит Команду Инженеров. Начало
Если позволите, я тоже немного отдохну. Поэтому вот вам лёгкий лонгрид на праздники.
На заре распространения персональных компьютеров найти работу сисадмином или веб-дизайнером было проще простого. Если ты знал пяток команд командной строки и мог набросать простенькую HTML-форму, обязательно нашёлся бы тот, кто был согласен тебе платить. Не нужно было даже образования. Только настойчивость и желание работать. Сейчас это совсем не так.
В какой-то степени это всегда происходит, когда отрасль взрослеет. Ранние дни любой отрасли — это что-то вроде Дикого Запада, где ставки низкие, регулирование отсутствует, а стандарты только зарождаются. Это никогда не длится долго. Количество предварительных знаний и опыта, которые вам необходимо иметь, прежде чем вы сможете войти в отрасль, стремительно увеличивается. Растут ставки, масштабы и цена ошибок. Появляются сертификации, тренинги, стандарты, юридические процедуры. Мы спорим о том, являются ли инженеры-программисты на самом деле инженерами.
ПО - индустрия обучения
Сейчас никто не возьмёт недоучившегося студента в штат. Необходимые для входа в индустрию знания выросли, вы больше не можете научиться буквально всему на работе, как когда-то.
Но не похоже, что вы можете научиться всему и в вузе. Степень в области компьютерных наук обычно лучше готовит вас к жизни компьютерных исследователей, чем к жизни в качестве обычного инженера-программиста. Более практичным путём в индустрию может стать хороший учебный лагерь по кодированию с упором на решение проблем и изучение современного инструментария. В любом случае вы не столько узнаете, «как выполнять работу», сколько «узнаете достаточно основ, чтобы понимать и использовать инструменты, необходимые для изучения работы».
ПО — индустрия обучения. Вы не можете научиться быть инженером-программистом, читая книги. Вы можете учиться только делая… и делая, и ещё делая. Неважно, какое у вас образование, большая часть обучения происходит на работе… и никогда не заканчивается!
Требуется более 7 лет, чтобы выковать компетентного инженера-программиста (как в большинстве случаев называют, сеньора). Это много лет написания, проверки и развёртывания кода каждый день в команде вместе с более опытными инженерами.
Что значит быть «сеньором»?
Об этом есть целая серия постов на канале. Ищите по тэгу #КакСтатьСеньором
По поводу сроков есть очень много споров:
«7 лет?! Пфф, мне потребовалось 2 года!»
«Меня повысили до сеньора меньше, чем за 5 лет!»
Молодцы! Да, в 7 годах нет ничего волшебного. Но для того, чтобы стать опытным инженером, способным сплотить команду, требуются время и опыт. Более того, нужна практика.
Думаю, мы стали использовать слово «сеньор» как сокращение для инженеров, которые могут поставлять готовый чистый код и быть продуктивными, и кажется, что это огромная ошибка. Это подразумевает, что младшие инженеры менее продуктивны, что неверно. И это упускает из виду истинную природу работы по разработке ПО, в которой написание кода является лишь небольшой частью.
Быть сеньором — это не способность писать код. Это гораздо больше связано с вашей способностью понимать, поддерживать, объяснять и управлять большим объёмом ПО в производстве с течением времени, а также способностью переводить бизнес-потребности в техническую реализацию. Большая часть работы связана с созданием и курированием этих больших, сложных социотехнических систем, а код — это всего лишь одно из представлений этих систем. Это значит, что вы научились, прежде всего, учиться и учить; как держать эти модели в голове и рассуждать о них, и как поддерживать, расширять и эксплуатировать эти системы с течением времени. Это значит, что у вас есть здравый смысл и инстинкты, которым вы можете доверять.
Что подводит нас к вопросу об ИИ.
Продолжение следует…
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
ИИ не Заменит Команду Инженеров. Начало
Если позволите, я тоже немного отдохну. Поэтому вот вам лёгкий лонгрид на праздники.
На заре распространения персональных компьютеров найти работу сисадмином или веб-дизайнером было проще простого. Если ты знал пяток команд командной строки и мог набросать простенькую HTML-форму, обязательно нашёлся бы тот, кто был согласен тебе платить. Не нужно было даже образования. Только настойчивость и желание работать. Сейчас это совсем не так.
В какой-то степени это всегда происходит, когда отрасль взрослеет. Ранние дни любой отрасли — это что-то вроде Дикого Запада, где ставки низкие, регулирование отсутствует, а стандарты только зарождаются. Это никогда не длится долго. Количество предварительных знаний и опыта, которые вам необходимо иметь, прежде чем вы сможете войти в отрасль, стремительно увеличивается. Растут ставки, масштабы и цена ошибок. Появляются сертификации, тренинги, стандарты, юридические процедуры. Мы спорим о том, являются ли инженеры-программисты на самом деле инженерами.
ПО - индустрия обучения
Сейчас никто не возьмёт недоучившегося студента в штат. Необходимые для входа в индустрию знания выросли, вы больше не можете научиться буквально всему на работе, как когда-то.
Но не похоже, что вы можете научиться всему и в вузе. Степень в области компьютерных наук обычно лучше готовит вас к жизни компьютерных исследователей, чем к жизни в качестве обычного инженера-программиста. Более практичным путём в индустрию может стать хороший учебный лагерь по кодированию с упором на решение проблем и изучение современного инструментария. В любом случае вы не столько узнаете, «как выполнять работу», сколько «узнаете достаточно основ, чтобы понимать и использовать инструменты, необходимые для изучения работы».
ПО — индустрия обучения. Вы не можете научиться быть инженером-программистом, читая книги. Вы можете учиться только делая… и делая, и ещё делая. Неважно, какое у вас образование, большая часть обучения происходит на работе… и никогда не заканчивается!
Требуется более 7 лет, чтобы выковать компетентного инженера-программиста (как в большинстве случаев называют, сеньора). Это много лет написания, проверки и развёртывания кода каждый день в команде вместе с более опытными инженерами.
Что значит быть «сеньором»?
Об этом есть целая серия постов на канале. Ищите по тэгу #КакСтатьСеньором
По поводу сроков есть очень много споров:
«7 лет?! Пфф, мне потребовалось 2 года!»
«Меня повысили до сеньора меньше, чем за 5 лет!»
Молодцы! Да, в 7 годах нет ничего волшебного. Но для того, чтобы стать опытным инженером, способным сплотить команду, требуются время и опыт. Более того, нужна практика.
Думаю, мы стали использовать слово «сеньор» как сокращение для инженеров, которые могут поставлять готовый чистый код и быть продуктивными, и кажется, что это огромная ошибка. Это подразумевает, что младшие инженеры менее продуктивны, что неверно. И это упускает из виду истинную природу работы по разработке ПО, в которой написание кода является лишь небольшой частью.
Быть сеньором — это не способность писать код. Это гораздо больше связано с вашей способностью понимать, поддерживать, объяснять и управлять большим объёмом ПО в производстве с течением времени, а также способностью переводить бизнес-потребности в техническую реализацию. Большая часть работы связана с созданием и курированием этих больших, сложных социотехнических систем, а код — это всего лишь одно из представлений этих систем. Это значит, что вы научились, прежде всего, учиться и учить; как держать эти модели в голове и рассуждать о них, и как поддерживать, расширять и эксплуатировать эти системы с течением времени. Это значит, что у вас есть здравый смысл и инстинкты, которым вы можете доверять.
Что подводит нас к вопросу об ИИ.
Продолжение следует…
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
5👍20👎1
День 2166. #Оффтоп #AI
ИИ не Заменит Команду Инженеров. Продолжение
1. ПО - индустрия обучения
Нужно перестать каннибализировать наше будущее
Получить первую должность инженера очень сложно. Недостаточно окончить вуз по специальности. Сейчас написано множество статей о том, что начальные должности в различных отраслях заменяются ИИ. Любая работа, которая состоит из рутины, вроде преобразования документа из одного формата в другой, чтение и обобщение кучи текста и т.п., кажется довольно очевидно уязвимой. И это не так уж революционно, это просто часть бума автоматизации.
Однако в последнее время ряд руководителей и «лидеров мнений» в сфере технологий, похоже, убедили себя в том, что ИИ находится на грани замены всей работы, выполняемой джунами. Это говорит о глубоком непонимании того, чем на самом деле занимаются инженеры. Не нанимая и не обучая джунов, мы каннибализируем собственное будущее.
Писать код легко
Написание кода — самая лёгкая часть разработки ПО, и с каждым днём становится проще. Сложная часть — это эксплуатация, понимание, расширение и управление им на протяжении всего его жизненного цикла.
Джун начинает с того, что учится писать и отлаживать строки, функции и фрагменты кода. Затем - составлять системы из ПО и проводить их через волны изменений и трансформаций.
Социотехнические системы состоят из ПО, инструментов и людей; для их понимания требуется знакомство с взаимодействием между ПО, пользователями, производством, инфраструктурой и непрерывными изменениями с течением времени. Эти системы фантастически сложны и подвержены хаосу и непредсказуемому поведению. Если кто-то утверждает, что понимает систему, которую он разрабатывает и эксплуатирует, то либо система мала, либо (более вероятно) он недостаточно знает, чтобы знать, чего он не знает. Код прост, а системы сложны.
Текущая волна инструментов ИИ сделала многое, чтобы помочь нам быстро генерировать много кода. Простые части становятся ещё проще. Но она не сделала ничего, чтобы помочь в работе по управлению, пониманию или эксплуатации этого кода. Т.е. ИИ только усложнил сложную работу.
Сложно генерировать хороший код
У вас может возникнуть образ инженеров-программистов, весело создающих запросы к ChatGPT или использующих Copilot для генерации тонн кода, а затем отправляющих всё, что получается, в GitHub. Это не похоже на реальность.
Инструменты вроде Copilot больше похожи на причудливую функцию автодополнения или копирования-вставки результатов из Google «Мне повезёт». Эти инструменты лучше всего работают, когда уже есть аналогичный код, и вы хотите просто скопировать-вставить его с небольшими изменениями, или когда вы пишете тесты по шаблону.
Однако вы не можете доверять сгенерированному коду. Он всегда выглядит правдоподобно, но даже когда он как-то «работает», он редко соответствует вашим желаниям и потребностям. ИИ с радостью сгенерирует код, который не скомпилируется, придумает переменные, имена методов, вызовы функций; сгаллюцинирует поля, которых не существует. Код не будет следовать вашим практикам или соглашениям кодирования. Чем важнее, сложнее или значимее фрагмент кода, тем меньше вероятность того, что вы сгенерируете пригодный для использования артефакт с помощью ИИ.
Вы можете сэкономить время, не вводя код, но придётся пройтись по нему строка за строкой, исправляя их по ходу дела, прежде чем вы сможете отправить его в производство. Во многих случаях это займет столько же или даже больше времени, чем написание. Генерация кода, который может компилироваться, выполняться и проходить набор тестов, не так уж и сложна; сложная часть — это создание кодовой базы, на которую последующие поколения команд смогут полагаться и модифицировать в течение многих лет.
Продолжение следует…
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
ИИ не Заменит Команду Инженеров. Продолжение
1. ПО - индустрия обучения
Нужно перестать каннибализировать наше будущее
Получить первую должность инженера очень сложно. Недостаточно окончить вуз по специальности. Сейчас написано множество статей о том, что начальные должности в различных отраслях заменяются ИИ. Любая работа, которая состоит из рутины, вроде преобразования документа из одного формата в другой, чтение и обобщение кучи текста и т.п., кажется довольно очевидно уязвимой. И это не так уж революционно, это просто часть бума автоматизации.
Однако в последнее время ряд руководителей и «лидеров мнений» в сфере технологий, похоже, убедили себя в том, что ИИ находится на грани замены всей работы, выполняемой джунами. Это говорит о глубоком непонимании того, чем на самом деле занимаются инженеры. Не нанимая и не обучая джунов, мы каннибализируем собственное будущее.
Писать код легко
Написание кода — самая лёгкая часть разработки ПО, и с каждым днём становится проще. Сложная часть — это эксплуатация, понимание, расширение и управление им на протяжении всего его жизненного цикла.
Джун начинает с того, что учится писать и отлаживать строки, функции и фрагменты кода. Затем - составлять системы из ПО и проводить их через волны изменений и трансформаций.
Социотехнические системы состоят из ПО, инструментов и людей; для их понимания требуется знакомство с взаимодействием между ПО, пользователями, производством, инфраструктурой и непрерывными изменениями с течением времени. Эти системы фантастически сложны и подвержены хаосу и непредсказуемому поведению. Если кто-то утверждает, что понимает систему, которую он разрабатывает и эксплуатирует, то либо система мала, либо (более вероятно) он недостаточно знает, чтобы знать, чего он не знает. Код прост, а системы сложны.
Текущая волна инструментов ИИ сделала многое, чтобы помочь нам быстро генерировать много кода. Простые части становятся ещё проще. Но она не сделала ничего, чтобы помочь в работе по управлению, пониманию или эксплуатации этого кода. Т.е. ИИ только усложнил сложную работу.
Сложно генерировать хороший код
У вас может возникнуть образ инженеров-программистов, весело создающих запросы к ChatGPT или использующих Copilot для генерации тонн кода, а затем отправляющих всё, что получается, в GitHub. Это не похоже на реальность.
Инструменты вроде Copilot больше похожи на причудливую функцию автодополнения или копирования-вставки результатов из Google «Мне повезёт». Эти инструменты лучше всего работают, когда уже есть аналогичный код, и вы хотите просто скопировать-вставить его с небольшими изменениями, или когда вы пишете тесты по шаблону.
Однако вы не можете доверять сгенерированному коду. Он всегда выглядит правдоподобно, но даже когда он как-то «работает», он редко соответствует вашим желаниям и потребностям. ИИ с радостью сгенерирует код, который не скомпилируется, придумает переменные, имена методов, вызовы функций; сгаллюцинирует поля, которых не существует. Код не будет следовать вашим практикам или соглашениям кодирования. Чем важнее, сложнее или значимее фрагмент кода, тем меньше вероятность того, что вы сгенерируете пригодный для использования артефакт с помощью ИИ.
Вы можете сэкономить время, не вводя код, но придётся пройтись по нему строка за строкой, исправляя их по ходу дела, прежде чем вы сможете отправить его в производство. Во многих случаях это займет столько же или даже больше времени, чем написание. Генерация кода, который может компилироваться, выполняться и проходить набор тестов, не так уж и сложна; сложная часть — это создание кодовой базы, на которую последующие поколения команд смогут полагаться и модифицировать в течение многих лет.
Продолжение следует…
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
5👍8
День 2167. #Оффтоп #AI
ИИ не Заменит Команду Инженеров. Продолжение
1. ПО – индустрия обучения
2. Просто писать код, сложно писать хороший код
Как инженеры на самом деле используют ИИ
Вы можете сгенерировать много кода очень быстро, но вы не можете доверять тому, что получится. Однако есть некоторые примеры использования, в которых ИИ неизменно блистает:
1. Часто проще попросить ChatGPT сгенерировать пример кода с использованием незнакомых API, чем читать документацию по API.
2. Создание кода, который раздражает или утомителен для написания, но при этом имеет узкую область действия и легко объясняется. Чем более предсказуем сценарий, тем лучше эти инструменты пишут код за вас.
3. Написание небольших функций, чтобы делать что-то на незнакомых языках или в незнакомых сценариях. Если у вас есть фрагмент кода Python и вы хотите то же самое на Java, но вы не знаете Java, ИИ поможет.
Но, помните: вероятность того, что результат полностью выдуман, составляет 50/50. Всегда придется предполагать, что результаты неверны, пока вы не проверите их вручную.
ИИ немного похож на джуна
ИИ похож на младшего инженера в том, что вы не можете запустить его код в производство. Вы несёте за него ответственность — юридически, этически и практически. Всё равно нужно потратить время, чтобы понять код, протестировать, инструментировать, модифицировать стилистически и тематически, чтобы он соответствовал остальной части кодовой базы, и убедиться, что коллеги также могут его понимать и поддерживать.
Аналогия хорошая, только если ваш код одноразовый и самодостаточный, т.е. не предназначен для интеграции в более крупный объём работы или для выживания и чтения или изменения другими.
И есть такие уголки отрасли, где большая часть — одноразовый код. Есть компании, которые выпускают десятки одноразовых приложений в год, каждое из которых написано для конкретного запуска или маркетингового мероприятия, а затем выбрасывается. Но это не относится к большинству ПО.
Но ИИ не член вашей команды
ИИ похож на джуна, но во всех других отношениях аналогия не работает. В автоматической генерации кода нет обратной связи. Предоставление код-ревью младшему инженеру не похоже на редактирование сгенерированного кода. Это возможность передать уроки, которые вы усвоили в своей карьере. Да и само оформление обратной связи заставляет вас продумывать проблему более строго и помогает вам глубже понять материал. Время, которое вы вкладываете в помощь младшему инженеру в повышении уровня, может окупиться удивительно быстро.
Мы недооцениваем стоимость найма сеньоров и переоцениваем стоимость найма джунов
Люди часто думают, что как только вы нанимаете сеньора, вы можете поместить его в команду, и он сразу же станет продуктивным. Тогда как джун снизит производительность команды навсегда. Ни то, ни другое неверно. Большая часть работы, которую приходится выполнять большинству команд, не так уж сложна, если её разбить на составные части.
Существует множество способов, как человек может внести вклад в общую скорость команды. И множество способов, как он может высасывать энергию из команды или добавлять трения и помехи всем вокруг. Это не всегда коррелирует с уровнем человека.
Каждому нанятому инженеру требуется время на разгон, прежде чем он сможет внести свой вклад, независимо от его уровня. Сколько времени? Зависит от чистоты и организованности кодовой базы, прошлого опыта работы с вашими инструментами и технологиями и многого другого, но, скорее всего, 6-9 месяцев. Да, разгон будет дольше для джуна, и это потребует больше инвестиций от команды. Но не критически больше. Джун должен начать приносить пользу в течение примерно того же периода времени, и джуны развиваются гораздо быстрее, чем более опытные работники.
Продолжение следует…
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
ИИ не Заменит Команду Инженеров. Продолжение
1. ПО – индустрия обучения
2. Просто писать код, сложно писать хороший код
Как инженеры на самом деле используют ИИ
Вы можете сгенерировать много кода очень быстро, но вы не можете доверять тому, что получится. Однако есть некоторые примеры использования, в которых ИИ неизменно блистает:
1. Часто проще попросить ChatGPT сгенерировать пример кода с использованием незнакомых API, чем читать документацию по API.
2. Создание кода, который раздражает или утомителен для написания, но при этом имеет узкую область действия и легко объясняется. Чем более предсказуем сценарий, тем лучше эти инструменты пишут код за вас.
3. Написание небольших функций, чтобы делать что-то на незнакомых языках или в незнакомых сценариях. Если у вас есть фрагмент кода Python и вы хотите то же самое на Java, но вы не знаете Java, ИИ поможет.
Но, помните: вероятность того, что результат полностью выдуман, составляет 50/50. Всегда придется предполагать, что результаты неверны, пока вы не проверите их вручную.
ИИ немного похож на джуна
ИИ похож на младшего инженера в том, что вы не можете запустить его код в производство. Вы несёте за него ответственность — юридически, этически и практически. Всё равно нужно потратить время, чтобы понять код, протестировать, инструментировать, модифицировать стилистически и тематически, чтобы он соответствовал остальной части кодовой базы, и убедиться, что коллеги также могут его понимать и поддерживать.
Аналогия хорошая, только если ваш код одноразовый и самодостаточный, т.е. не предназначен для интеграции в более крупный объём работы или для выживания и чтения или изменения другими.
И есть такие уголки отрасли, где большая часть — одноразовый код. Есть компании, которые выпускают десятки одноразовых приложений в год, каждое из которых написано для конкретного запуска или маркетингового мероприятия, а затем выбрасывается. Но это не относится к большинству ПО.
Но ИИ не член вашей команды
ИИ похож на джуна, но во всех других отношениях аналогия не работает. В автоматической генерации кода нет обратной связи. Предоставление код-ревью младшему инженеру не похоже на редактирование сгенерированного кода. Это возможность передать уроки, которые вы усвоили в своей карьере. Да и само оформление обратной связи заставляет вас продумывать проблему более строго и помогает вам глубже понять материал. Время, которое вы вкладываете в помощь младшему инженеру в повышении уровня, может окупиться удивительно быстро.
Мы недооцениваем стоимость найма сеньоров и переоцениваем стоимость найма джунов
Люди часто думают, что как только вы нанимаете сеньора, вы можете поместить его в команду, и он сразу же станет продуктивным. Тогда как джун снизит производительность команды навсегда. Ни то, ни другое неверно. Большая часть работы, которую приходится выполнять большинству команд, не так уж сложна, если её разбить на составные части.
Существует множество способов, как человек может внести вклад в общую скорость команды. И множество способов, как он может высасывать энергию из команды или добавлять трения и помехи всем вокруг. Это не всегда коррелирует с уровнем человека.
Каждому нанятому инженеру требуется время на разгон, прежде чем он сможет внести свой вклад, независимо от его уровня. Сколько времени? Зависит от чистоты и организованности кодовой базы, прошлого опыта работы с вашими инструментами и технологиями и многого другого, но, скорее всего, 6-9 месяцев. Да, разгон будет дольше для джуна, и это потребует больше инвестиций от команды. Но не критически больше. Джун должен начать приносить пользу в течение примерно того же периода времени, и джуны развиваются гораздо быстрее, чем более опытные работники.
Продолжение следует…
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
👍16
День 2168. #Оффтоп #AI
ИИ не Заменит Команду Инженеров. Продолжение
1. ПО - индустрия обучения
2. Просто писать код, сложно писать хороший код
3. ИИ похож на джуна
Не обязательно быть сеньором, чтобы добавлять ценность
С точки зрения написания и поставки функций, одни из самых продуктивных инженеров - мидлы. Они ещё не увязли во встречах, кураторстве, наставничестве, консультациях и архитектуре, их календари ещё не забиты прерываниями, они могут просто создавать вещи. Они надевают наушники утром, пишут код весь день и уходят вечером, достигнув невероятного прогресса.
Мидлы находятся в этом прекрасном временном состоянии, когда они достаточно хорошо разбираются в программировании, чтобы быть очень продуктивными, но всё ещё учатся создавать и обслуживать системы. Всё, что они делают, это пишут код, много кода.
И они полны энергии… вовлечены. Они получают удовольствие! Это обычно означает, что они будут делать работу лучше, особенно под руководством кого-то более опытного. Наличие в команде мидлов — это потрясающе. Единственный способ получить их — нанять джунов.
Почти все согласны, что нанимать джунов — это хорошо в долгосрочной перспективе… и это должен делать кто-то другой, т.к. «нам сейчас нужны сеньоры», «джунов долго обучать» и т.п. Долгосрочное мышление — не то, в чём компании или капитализм в целом обычно хороши. Компании гораздо более склонны выносить такие издержки за пределы компании. Но есть несколько аргументов в пользу найма джунов в краткосрочной перспективе.
Найм инженеров — это не процесс «выбора лучшего человека для работы». Это создание команд. Наименьшая единица владения ПО — не отдельный человек, а команда. Если бы найм инженеров был связан с выбором «лучших людей», имело бы смысл нанять самого «сеньористого» человека, которого вы можете получить за имеющиеся деньги, т.к. мы используем термин «сеньор» как синоним «производительности». Но производительность отдельного человека — не то, что мы должны оптимизировать. Производительность команды — вот, что имеет значение.
И лучшие команды всегда те, в которых есть разнообразие сильных сторон, перспектив и уровней знаний. Нужно нанимать джунов постоянно. Они остаются джунами всего пару лет, а мидлы превращаются в сеньоров. Самые опытные инженеры на самом деле не лучшие люди для наставничества джунов; самый эффективный наставник обычно тот, кто на один уровень выше, и помнит, каково это было на вашем месте.
Здоровая команда включает людей разных уровней
Вы не будете укомплектовывать команду по разработке продукта шестью экспертами по БД и одним мобильным разработчиком. Также нельзя включать в неё 6 сеньоров и 1 джуна. Существует не так много высокоуровневой архитектуры и планирования, не так много важных решений, которые нужно принять. Сеньоры будут проводить большую часть времени, выполняя работу, которая кажется им скучной и повторяющейся, поэтому будут оверинжинирить решения и/или экономить на них — иногда в одно и то же время. Они будут хронически недодокументировать и недоинвестировать в работу, которая делает системы простыми и управляемыми.
Команды, из инженеров одного уровня будут иметь разные патологии, но схожие проблемы с разногласиями и «слепыми пятнами». Сама работа имеет широкий диапазон сложности и трудности — от простых, узконаправленных функций до сложных, высокорискованных архитектурных решений. Лучшие команды — те, где никому не скучно, потому что каждый работает над чем-то, что бросает ему вызов и расширяет границы. Единственный способ добиться этого — иметь в команде разные уровни навыков.
Окончание следует…
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
ИИ не Заменит Команду Инженеров. Продолжение
1. ПО - индустрия обучения
2. Просто писать код, сложно писать хороший код
3. ИИ похож на джуна
Не обязательно быть сеньором, чтобы добавлять ценность
С точки зрения написания и поставки функций, одни из самых продуктивных инженеров - мидлы. Они ещё не увязли во встречах, кураторстве, наставничестве, консультациях и архитектуре, их календари ещё не забиты прерываниями, они могут просто создавать вещи. Они надевают наушники утром, пишут код весь день и уходят вечером, достигнув невероятного прогресса.
Мидлы находятся в этом прекрасном временном состоянии, когда они достаточно хорошо разбираются в программировании, чтобы быть очень продуктивными, но всё ещё учатся создавать и обслуживать системы. Всё, что они делают, это пишут код, много кода.
И они полны энергии… вовлечены. Они получают удовольствие! Это обычно означает, что они будут делать работу лучше, особенно под руководством кого-то более опытного. Наличие в команде мидлов — это потрясающе. Единственный способ получить их — нанять джунов.
Почти все согласны, что нанимать джунов — это хорошо в долгосрочной перспективе… и это должен делать кто-то другой, т.к. «нам сейчас нужны сеньоры», «джунов долго обучать» и т.п. Долгосрочное мышление — не то, в чём компании или капитализм в целом обычно хороши. Компании гораздо более склонны выносить такие издержки за пределы компании. Но есть несколько аргументов в пользу найма джунов в краткосрочной перспективе.
Найм инженеров — это не процесс «выбора лучшего человека для работы». Это создание команд. Наименьшая единица владения ПО — не отдельный человек, а команда. Если бы найм инженеров был связан с выбором «лучших людей», имело бы смысл нанять самого «сеньористого» человека, которого вы можете получить за имеющиеся деньги, т.к. мы используем термин «сеньор» как синоним «производительности». Но производительность отдельного человека — не то, что мы должны оптимизировать. Производительность команды — вот, что имеет значение.
И лучшие команды всегда те, в которых есть разнообразие сильных сторон, перспектив и уровней знаний. Нужно нанимать джунов постоянно. Они остаются джунами всего пару лет, а мидлы превращаются в сеньоров. Самые опытные инженеры на самом деле не лучшие люди для наставничества джунов; самый эффективный наставник обычно тот, кто на один уровень выше, и помнит, каково это было на вашем месте.
Здоровая команда включает людей разных уровней
Вы не будете укомплектовывать команду по разработке продукта шестью экспертами по БД и одним мобильным разработчиком. Также нельзя включать в неё 6 сеньоров и 1 джуна. Существует не так много высокоуровневой архитектуры и планирования, не так много важных решений, которые нужно принять. Сеньоры будут проводить большую часть времени, выполняя работу, которая кажется им скучной и повторяющейся, поэтому будут оверинжинирить решения и/или экономить на них — иногда в одно и то же время. Они будут хронически недодокументировать и недоинвестировать в работу, которая делает системы простыми и управляемыми.
Команды, из инженеров одного уровня будут иметь разные патологии, но схожие проблемы с разногласиями и «слепыми пятнами». Сама работа имеет широкий диапазон сложности и трудности — от простых, узконаправленных функций до сложных, высокорискованных архитектурных решений. Лучшие команды — те, где никому не скучно, потому что каждый работает над чем-то, что бросает ему вызов и расширяет границы. Единственный способ добиться этого — иметь в команде разные уровни навыков.
Окончание следует…
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
1👍17
День 2169. #Оффтоп #AI
ИИ не Заменит Команду Инженеров. Окончание
1. ПО - индустрия обучения
2. Просто писать код, сложно писать хороший код
3. ИИ похож на джуна
4. Здоровая команда включает людей разных уровней
Узкое место — найм, а не обучение
Узкое место сейчас — это предоставление джунам их первой работы. Оно в компаниях, которые видят в джунах издержки, а не инвестиции в своё будущее.
После первой работы инженер обычно может найти работу. Но получить первую работу практически невозможно, если только вы не окончили лучший вуз или у вас нет крутых связей.
Многие думают, что им не нужны джуны, но никто не говорит, что им нужно меньше сеньоров. Можно с уверенностью предположить, что всё детерминированное и автоматизируемое в итоге будет автоматизировано. Программная инженерия не исключение. Конечно, мы всегда ищем способы автоматизации и повышения эффективности, так и должно быть.
Но большие программные системы непредсказуемы. Само существование пользователей вносит хаос в систему. Компоненты можно автоматизировать, но сложностью можно только управлять.
Даже если бы системы можно было полностью автоматизировать и управлять ими с помощью ИИ, тот факт, что мы не можем понять, как ИИ принимает решения, является огромной, возможно, непреодолимой проблемой. Ведение бизнеса в системе, которую люди не могут отладить или понять, кажется риском настолько существенным, что ни одна служба безопасности, юридическая или финансовая служба никогда не одобрит этого. Может быть, какая-то версия этого будущего и наступит, но отсюда её трудно увидеть.
Нам нужны сеньоры, но единственный способ их получить – растить из джунов.
Должна ли каждая компания нанимать джунов?
Нет. Вот несколько факторов, которые не позволят компании нанимать джунов:
- Меньше двух лет работы;
- Команда постоянно находится в режиме пожаротушения;
- Нет опытных менеджеров;
- Нет дорожной карты продукта;
- Никто в команде не заинтересован в том, чтобы быть их наставником или руководителем.
Единственное, что хуже, чем вообще не нанимать джунов, — это нанимать их в ужасные условия, где они не смогут ничему научиться. Хотя большинство джунов скорее предпочтут паршивую первую работу, чем вообще ничего.
Удалённая работа лучше, чем ничего, но сильно сложнее. Джунам лучше искать работу в офисе, если возможно. Вы учитесь гораздо быстрее, когда можете впитывать неформальные разговоры и техническую болтовню, и вы теряете это, работая из дома. Удалённому работодателю придется работать усерднее, чтобы компенсировать это.
Никто не придёт решить наши проблемы за нас
В большинстве мест, где есть программа найма и обучения инженеров начального уровня, она есть только потому, что инженеры решили за неё бороться. Инженеры её создавали, выбивали ресурсы, разрабатывали программу, проводили собеседования и нанимали джунов и их наставников. Это вполне в пределах возможностей большинства мотивированных, опытных инженеров (и также полезно для вашей карьеры).
Финансы будут против. Руководители вряд ли вмешаются. Чем больше роль человека склоняет его относиться к инженерам как к взаимозаменяемым ресурсам, тем меньше вероятность, что он поймёт, почему это важно.
ИИ не решит все наши проблемы и не напишет весь код за нас. А даже если бы это было так, написание кода — лишь часть того, что делают профессиональные инженеры-программисты, и, возможно, самая простая часть. Только у нас есть контекст и авторитет, чтобы управлять изменениями, которые составляют основу для отличных команд и совершенствования как инженер.
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
ИИ не Заменит Команду Инженеров. Окончание
1. ПО - индустрия обучения
2. Просто писать код, сложно писать хороший код
3. ИИ похож на джуна
4. Здоровая команда включает людей разных уровней
Узкое место — найм, а не обучение
Узкое место сейчас — это предоставление джунам их первой работы. Оно в компаниях, которые видят в джунах издержки, а не инвестиции в своё будущее.
После первой работы инженер обычно может найти работу. Но получить первую работу практически невозможно, если только вы не окончили лучший вуз или у вас нет крутых связей.
Многие думают, что им не нужны джуны, но никто не говорит, что им нужно меньше сеньоров. Можно с уверенностью предположить, что всё детерминированное и автоматизируемое в итоге будет автоматизировано. Программная инженерия не исключение. Конечно, мы всегда ищем способы автоматизации и повышения эффективности, так и должно быть.
Но большие программные системы непредсказуемы. Само существование пользователей вносит хаос в систему. Компоненты можно автоматизировать, но сложностью можно только управлять.
Даже если бы системы можно было полностью автоматизировать и управлять ими с помощью ИИ, тот факт, что мы не можем понять, как ИИ принимает решения, является огромной, возможно, непреодолимой проблемой. Ведение бизнеса в системе, которую люди не могут отладить или понять, кажется риском настолько существенным, что ни одна служба безопасности, юридическая или финансовая служба никогда не одобрит этого. Может быть, какая-то версия этого будущего и наступит, но отсюда её трудно увидеть.
Нам нужны сеньоры, но единственный способ их получить – растить из джунов.
Должна ли каждая компания нанимать джунов?
Нет. Вот несколько факторов, которые не позволят компании нанимать джунов:
- Меньше двух лет работы;
- Команда постоянно находится в режиме пожаротушения;
- Нет опытных менеджеров;
- Нет дорожной карты продукта;
- Никто в команде не заинтересован в том, чтобы быть их наставником или руководителем.
Единственное, что хуже, чем вообще не нанимать джунов, — это нанимать их в ужасные условия, где они не смогут ничему научиться. Хотя большинство джунов скорее предпочтут паршивую первую работу, чем вообще ничего.
Удалённая работа лучше, чем ничего, но сильно сложнее. Джунам лучше искать работу в офисе, если возможно. Вы учитесь гораздо быстрее, когда можете впитывать неформальные разговоры и техническую болтовню, и вы теряете это, работая из дома. Удалённому работодателю придется работать усерднее, чтобы компенсировать это.
Никто не придёт решить наши проблемы за нас
В большинстве мест, где есть программа найма и обучения инженеров начального уровня, она есть только потому, что инженеры решили за неё бороться. Инженеры её создавали, выбивали ресурсы, разрабатывали программу, проводили собеседования и нанимали джунов и их наставников. Это вполне в пределах возможностей большинства мотивированных, опытных инженеров (и также полезно для вашей карьеры).
Финансы будут против. Руководители вряд ли вмешаются. Чем больше роль человека склоняет его относиться к инженерам как к взаимозаменяемым ресурсам, тем меньше вероятность, что он поймёт, почему это важно.
ИИ не решит все наши проблемы и не напишет весь код за нас. А даже если бы это было так, написание кода — лишь часть того, что делают профессиональные инженеры-программисты, и, возможно, самая простая часть. Только у нас есть контекст и авторитет, чтобы управлять изменениями, которые составляют основу для отличных команд и совершенствования как инженер.
Источник: https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
👍8
День 2170. #ЗаметкиНаПолях
Подписываем Коммиты в Git SSH-Ключами в Windows
Подписание коммитов в Git — это способ проверки подлинности и целостности коммитов. Это гарантирует, что коммиты действительно сделаны вами и не были подделаны. В Windows легко настроить SSH-Agent для подписи.
Сначала установим SSH в Windows. Откройте окно PowerShell от имени администратора и выполните следующую команду:
Можно проверить статус так:
Теперь создадим пару ключей SSH (для PowerShell 7.1+):
Чтобы не вводить парольную фразу каждый раз при использовании ключа, можно добавить её в SSH Agent. Запустим сервис SSH Agent и настроим его на автоматический запуск:
Теперь добавим ключ в SSH Agent:
Можно проверить, что ключ добавлен:
Должен отобразиться публичный ключ.
Вы можете удалить приватный ключ, если хотите, так как теперь он сохраняется в SSH Agent между сеансами и перезагрузками.
Теперь, если нужно, установите Git:
Наконец, настроим Git для использования SSH-ключа для подписи коммитов:
Последний шаг — зарегистрировать SSH-ключ в провайдере Git. Вы можете найти открытый ключ в папке .ssh в каталоге вашего профиля пользователя. Скопируйте содержимое файла id_ed25519.pub и добавьте его у провайдера Git:
GitHub: https://github.com/settings/ssh/new
GitLab: https://gitlab.com/-/user_settings/ssh_keys
Для GitHub можно также использовать GitHub CLI:
Проверяем подпись коммита:
На сайте GitHub вы должны увидеть значок "Verified" рядом с сообщением коммита.
Можно проверить подпись локально. Сначала добавим SSH-ключ в доверенных подписантов:
Теперь можно проверить подпись коммита:
Эта настройка позволяет проверить ваш коммит, используя ваш SSH-ключ. Если вы хотите проверять коммиты, подписанные другими людьми, нужно добавить их ключи в файл allowed_signers. Для GitHub вы можете запросить ключи SSH, используя API GitHub:
Затем вы можете добавить ключ в файл allowed_signers и выполнить предыдущую команду для проверки подписи.
Источник: https://www.meziantou.net/signing-commits-in-git-using-ssh-keys-on-windows.htm
Подписываем Коммиты в Git SSH-Ключами в Windows
Подписание коммитов в Git — это способ проверки подлинности и целостности коммитов. Это гарантирует, что коммиты действительно сделаны вами и не были подделаны. В Windows легко настроить SSH-Agent для подписи.
Сначала установим SSH в Windows. Откройте окно PowerShell от имени администратора и выполните следующую команду:
Add-WindowsCapability -Online -Name OpenSSH.Client
Можно проверить статус так:
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Client*'
Теперь создадим пару ключей SSH (для PowerShell 7.1+):
$passphrase = Read-Host -Prompt "Enter passphrase" -AsSecureString
$KeyName = "git"
ssh-keygen -t ed25519 -C $KeyName -N (ConvertFrom-SecureString -AsPlainText $passphrase)
Чтобы не вводить парольную фразу каждый раз при использовании ключа, можно добавить её в SSH Agent. Запустим сервис SSH Agent и настроим его на автоматический запуск:
Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent
Теперь добавим ключ в SSH Agent:
ssh-add $env:USERPROFILE\.ssh\id_ed25519
Можно проверить, что ключ добавлен:
ssh-add -L
Должен отобразиться публичный ключ.
Вы можете удалить приватный ключ, если хотите, так как теперь он сохраняется в SSH Agent между сеансами и перезагрузками.
Теперь, если нужно, установите Git:
winget install --id Git.Git –exact
Наконец, настроим Git для использования SSH-ключа для подписи коммитов:
# Используем SSH-ключ для подписей
git config --global user.signingkey (Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub)
git config --global gpg.format ssh
git config --global gpg.ssh.program (Get-Command ssh-keygen.exe).Source
git config --global core.sshCommand (Get-Command ssh.exe).Source
# Настраиваем подписывать коммиты и теги по умолчанию
git config --global commit.gpgsign true
git config --global tag.gpgsign true
Последний шаг — зарегистрировать SSH-ключ в провайдере Git. Вы можете найти открытый ключ в папке .ssh в каталоге вашего профиля пользователя. Скопируйте содержимое файла id_ed25519.pub и добавьте его у провайдера Git:
GitHub: https://github.com/settings/ssh/new
GitLab: https://gitlab.com/-/user_settings/ssh_keys
Для GitHub можно также использовать GitHub CLI:
gh ssh-key add $env:USERPROFILE\.ssh\id_ed25519 --title git --type signing
Проверяем подпись коммита:
git commit --allow-empty --message="Testing SSH signing"
На сайте GitHub вы должны увидеть значок "Verified" рядом с сообщением коммита.
Можно проверить подпись локально. Сначала добавим SSH-ключ в доверенных подписантов:
git config --global gpg.ssh.allowedSignersFile $env:USERPROFILE/.ssh/allowed_signers
$email = (git config user.email)
$key = (Get-Content $env:USERPROFILE/.ssh/id_ed25519.pub)
$signer = "$email $key"
echo $signer | Out-File $env:USERPROFILE/.ssh/allowed_signers -Append
Теперь можно проверить подпись коммита:
git show --show-signature
Эта настройка позволяет проверить ваш коммит, используя ваш SSH-ключ. Если вы хотите проверять коммиты, подписанные другими людьми, нужно добавить их ключи в файл allowed_signers. Для GitHub вы можете запросить ключи SSH, используя API GitHub:
gh api /users/meziantou/ssh_signing_keys
Затем вы можете добавить ключ в файл allowed_signers и выполнить предыдущую команду для проверки подписи.
Источник: https://www.meziantou.net/signing-commits-in-git-using-ssh-keys-on-windows.htm
👍22
Anonymous Quiz
6%
$exception
24%
$returnvalue
10%
$thread
60%
$user
👎3
День 2171. #ЗаметкиНаПолях
Псевдопеременные в Отладчике Visual Studio в C#
Псевдопеременные — это термины, используемые для отображения определённой информации в окне Watch или Immediate. Вы можете ввести псевдопеременную так же, как вы вводите обычную переменную. Однако псевдопеременные не являются переменными и не соответствуют именам переменных в вашем коде.
1. $exception
Оценивает текущее выброшенное исключение. Переменная доступна в момент выбрасывания исключения, а также в блоке catch, если исключение перехвачено. Это полезно в случаях, когда вы не добавили параметр Exception в предложение catch. Вы также можете увидеть исключение в окне Locals.
2. $returnvalue
Показывает и возвращает значение метода, из которого только что вышли. Это полезно, если вы не присваиваете возвращаемое значение какой-то переменной (а, например, сразу используете return). Заметьте, однако, что значение будет доступно только сразу после выхода из метода:
- на следующей строке, если вы поставили там точку останова, либо перескочили (F10) через вызов метода;
- при выходе из метода (на строке с закрывающей скобкой после return), если вы проходите по коду самого метода.
Кроме того, возвращаемое значение автоматически показывается в окнах Locals и Autos.
3. $user
Показывает информацию о текущем пользователе ОС и процессе. Сюда входит имя машины, привилегии процесса и некоторые другие сведения, связанные с безопасностью.
4. $threadSmallObjectHeapBytes
Отображает общее количество байт, выделенных в куче малых объектов (Small Object Heap) текущим потоком. (.NET 6+)
5. $threadUserOldHeapBytes
Отображает общее количество байт, выделенных в Пользовательской Куче Старшего поколения (User Old Heap) текущим потоком. User Old Heap = Large Object Heap + Pinned Object Heap (.NET 6+)
6. $1, $2, …, $n
Отображают по порядку объекты, для которых создан Object ID при отладке. Подробнее в этом посте.
Источники:
- Michael Shpilt «Practical Debugging for .NET Developers». - 2020. Глава 3.
- https://learn.microsoft.com/en-us/visualstudio/debugger/pseudovariables?view=vs-2022
Псевдопеременные в Отладчике Visual Studio в C#
Псевдопеременные — это термины, используемые для отображения определённой информации в окне Watch или Immediate. Вы можете ввести псевдопеременную так же, как вы вводите обычную переменную. Однако псевдопеременные не являются переменными и не соответствуют именам переменных в вашем коде.
1. $exception
Оценивает текущее выброшенное исключение. Переменная доступна в момент выбрасывания исключения, а также в блоке catch, если исключение перехвачено. Это полезно в случаях, когда вы не добавили параметр Exception в предложение catch. Вы также можете увидеть исключение в окне Locals.
2. $returnvalue
Показывает и возвращает значение метода, из которого только что вышли. Это полезно, если вы не присваиваете возвращаемое значение какой-то переменной (а, например, сразу используете return). Заметьте, однако, что значение будет доступно только сразу после выхода из метода:
- на следующей строке, если вы поставили там точку останова, либо перескочили (F10) через вызов метода;
- при выходе из метода (на строке с закрывающей скобкой после return), если вы проходите по коду самого метода.
Кроме того, возвращаемое значение автоматически показывается в окнах Locals и Autos.
3. $user
Показывает информацию о текущем пользователе ОС и процессе. Сюда входит имя машины, привилегии процесса и некоторые другие сведения, связанные с безопасностью.
4. $threadSmallObjectHeapBytes
Отображает общее количество байт, выделенных в куче малых объектов (Small Object Heap) текущим потоком. (.NET 6+)
5. $threadUserOldHeapBytes
Отображает общее количество байт, выделенных в Пользовательской Куче Старшего поколения (User Old Heap) текущим потоком. User Old Heap = Large Object Heap + Pinned Object Heap (.NET 6+)
6. $1, $2, …, $n
Отображают по порядку объекты, для которых создан Object ID при отладке. Подробнее в этом посте.
Источники:
- Michael Shpilt «Practical Debugging for .NET Developers». - 2020. Глава 3.
- https://learn.microsoft.com/en-us/visualstudio/debugger/pseudovariables?view=vs-2022
👍24
День 2172. #ЗаметкиНаПолях
Функции Пригодности в Архитектуре ПО
Нефункциональные требования важны, но мы часто забываем их проверять. Вы можете измерить их, настроив функции пригодности. Достаточно ли быстра ваша система? Проходит ли она все проверки безопасности? А как насчёт тестируемости, ремонтопригодности и других качеств?
Функции пригодности — это компоненты архитектуры, которые не выполняют функциональные операции, но, используя набор тестов и измерений, позволяют вам проверить, что система соблюдает все предварительно определённые нефункциональные требования.
Если у нас нет четкого понимания нефункциональных требований, то их невозможно измерить. И как только мы определили способ их измерения, как мы можем гарантировать, что мы оправдываем ожидания? Вот где пригодятся функции пригодности.
Будучи связанными с конкретными и измеримыми метриками, функции пригодности предоставляют способ оценки качества и производительности архитектуры, снижая зависимость от субъективных мнений с помощью объективных измерений. Метрика может быть простым числом (например, «максимальное количество запросов в секунду»), процентным значением (например, «процент кода, покрытого тестами») или другими измеримыми значениями.
Знание того, как система ведёт себя в отношении этих показателей, позволяет архитекторам работать над постоянным совершенствованием системы: команды могут определять области для улучшения и принимать решения, основанные не на личном мнении, а на фактических данных, для улучшения системы.
Наличие централизованного места для просмотра исторических значений показателя помогает понять, достигли ли вы прогресса или со временем качество ухудшилось. А чёткое понимание текущего статуса таких показателей может помочь в выявлении потенциальных проблем на ранних этапах процесса разработки, позволяя командам решать их до того, как они станут критическими проблемами.
Например, используя функции пригодности, вы можете гарантировать, что система сможет обрабатывать определённое количество пользователей в секунду: имея надлежащие измерения, вы можете определить, какие функции менее производительны и, в случае высокого трафика, могут привести к падению всей системы.
Скорее всего, вы уже используете функции пригодности, не зная об этом (или хотя бы слышали о них).
Такие инструменты, как SonarQube и NDepend, используют функции пригодности для оценки качества кода на основе метрик, вроде сложности кода, дублирования и соответствия стандартам кодирования. Метрики рассчитываются на основе статического анализа кода, и команды могут определять пороговые значения, при которых система может подвергаться риску потери возможности обслуживания. Примером метрики, связанной с качеством кода, является процент покрытия тестами.
Инструменты, типа JMeter или K6, помогают измерять производительность системы в различных условиях. Наличие истории результатов нагрузочного тестирования может помочь гарантировать, что при добавлении новых функций в систему производительность некоторых конкретных модулей не снизится.
В целом, большинство функций пригодности можно настроить как часть конвейера CI/CD. Например, можно настроить конвейер CD так, чтобы он блокировал развёртывание кода, если результаты нагрузочного тестирования нового кода хуже, чем в предыдущей версии. Или блокировал пул-реквест, если процент покрытия кода снижается.
Вы можете создать свои собственные функции пригодности на основе всего, что вы можете (и должны) измерить: от времени средней загрузки страницы до оценки удовлетворенности клиентов. В сочетании с понятной панелью управления вы можете иметь чёткое представление истории таких показателей.
Источник: https://www.code4it.dev/architecture-notes/fitness-functions/
Функции Пригодности в Архитектуре ПО
Нефункциональные требования важны, но мы часто забываем их проверять. Вы можете измерить их, настроив функции пригодности. Достаточно ли быстра ваша система? Проходит ли она все проверки безопасности? А как насчёт тестируемости, ремонтопригодности и других качеств?
Функции пригодности — это компоненты архитектуры, которые не выполняют функциональные операции, но, используя набор тестов и измерений, позволяют вам проверить, что система соблюдает все предварительно определённые нефункциональные требования.
Если у нас нет четкого понимания нефункциональных требований, то их невозможно измерить. И как только мы определили способ их измерения, как мы можем гарантировать, что мы оправдываем ожидания? Вот где пригодятся функции пригодности.
Будучи связанными с конкретными и измеримыми метриками, функции пригодности предоставляют способ оценки качества и производительности архитектуры, снижая зависимость от субъективных мнений с помощью объективных измерений. Метрика может быть простым числом (например, «максимальное количество запросов в секунду»), процентным значением (например, «процент кода, покрытого тестами») или другими измеримыми значениями.
Знание того, как система ведёт себя в отношении этих показателей, позволяет архитекторам работать над постоянным совершенствованием системы: команды могут определять области для улучшения и принимать решения, основанные не на личном мнении, а на фактических данных, для улучшения системы.
Наличие централизованного места для просмотра исторических значений показателя помогает понять, достигли ли вы прогресса или со временем качество ухудшилось. А чёткое понимание текущего статуса таких показателей может помочь в выявлении потенциальных проблем на ранних этапах процесса разработки, позволяя командам решать их до того, как они станут критическими проблемами.
Например, используя функции пригодности, вы можете гарантировать, что система сможет обрабатывать определённое количество пользователей в секунду: имея надлежащие измерения, вы можете определить, какие функции менее производительны и, в случае высокого трафика, могут привести к падению всей системы.
Скорее всего, вы уже используете функции пригодности, не зная об этом (или хотя бы слышали о них).
Такие инструменты, как SonarQube и NDepend, используют функции пригодности для оценки качества кода на основе метрик, вроде сложности кода, дублирования и соответствия стандартам кодирования. Метрики рассчитываются на основе статического анализа кода, и команды могут определять пороговые значения, при которых система может подвергаться риску потери возможности обслуживания. Примером метрики, связанной с качеством кода, является процент покрытия тестами.
Инструменты, типа JMeter или K6, помогают измерять производительность системы в различных условиях. Наличие истории результатов нагрузочного тестирования может помочь гарантировать, что при добавлении новых функций в систему производительность некоторых конкретных модулей не снизится.
В целом, большинство функций пригодности можно настроить как часть конвейера CI/CD. Например, можно настроить конвейер CD так, чтобы он блокировал развёртывание кода, если результаты нагрузочного тестирования нового кода хуже, чем в предыдущей версии. Или блокировал пул-реквест, если процент покрытия кода снижается.
Вы можете создать свои собственные функции пригодности на основе всего, что вы можете (и должны) измерить: от времени средней загрузки страницы до оценки удовлетворенности клиентов. В сочетании с понятной панелью управления вы можете иметь чёткое представление истории таких показателей.
Источник: https://www.code4it.dev/architecture-notes/fitness-functions/
👍5
День 2173. #УрокиРазработки
Уроки 50 Лет Разработки ПО
Урок 38. Люди много говорят о своих правах, но права подразумевают ответственность
В жизни мы имеем не только права, но и обязанности. Вы имеете право владеть автомобилем, но также должны его зарегистрировать и застраховать. Наряду с правом на покупку недвижимости возникает обязанность платить налог за неё. Сочетание прав и обязанностей определяет отношения людей с обществом.
Люди, работающие над программными проектами, тоже имеют права и обязанности. Наши права в этом случае можно представить как наши ожидания по отношению к другим, а обязанности — как ответственность перед ними. Каждый имеет такие права/обязанности перед своими коллегами, клиентами, руководителями, поставщиками и широкой общественностью.
Помимо конкретных обязательств, которые мы берём на себя перед другими, все специалисты по ПО несут ответственность за соблюдение профессиональной этики: действовать в интересах общества, сохранять конфиденциальность, уважать право интеллектуальной собственности, стремиться к высокому качеству и т.д.
Между правами и обязанностями специалистов по ПО существует определённая симметрия. Если члены команды А имеют право рассчитывать на некие услуги или действия членов команды Б, то верно и обратное.
Вот несколько примеров прав и обязанностей команд, участвующих в разработке ПО. Если вас не устраивает формализм записи прав и обязанностей, то можно сформулировать их в виде: «Для меня резонно ожидать от вас Х, а для вас резонно ожидать от меня Y».
Клиенты
- Право ожидать, что бизнес-аналитик будет использовать информацию о вашем бизнесе исключительно для вашего блага. Вы обязаны дать бизнес-аналитикам и разработчикам всю интересующую их информацию о своем бизнесе.
- Право получить систему, отвечающую потребностям и ожиданиям в отношении качества. Вы обязаны выделить время, необходимое для предоставления и уточнения требований.
- Право изменить свои требования. Вы обязаны оперативно сообщить об изменениях требований команде разработчиков.
Разработчики
- Право на признание и уважение вашей интеллектуальной собственности другими. Вы обязаны уважать право интеллектуальной собственности других лиц, повторно используя плоды их труда только с их разрешения.
- Право знать приоритет каждого требования. Вы обязаны информировать заказчика о влиянии на график новых требований и изменений в приоритетах требований.
- Право оценивать и переоценивать свою работу. Вы обязаны делать свои оценки как можно более точными и как можно быстрее корректировать графики работ, приближая их к реальности.
Руководители или спонсоры проекта
- Право ожидать от разработчиков высококачественного ПО. Вы обязаны предоставить среду, ресурсы и время, чтобы разработчики могли создавать высококачественное ПО.
- Право определять цели проекта и устанавливать графики их реализации. Вы обязаны уважать оценки разработчиков и не принуждать их выполнять работы в нереалистичные сроки.
Вы можете думать, что вам полагаются определённые права, присущие какому-то другому сообществу, но порой они не могут или не хотят оправдывать ваши ожидания. Всякий раз, сталкиваясь с подобным несоответствием, стороны должны научиться работать вместе конструктивно и без раздражения. Стоит потратить время, чтобы обсудить взаимные права и обязанности, и, может быть, даже записать их, чтобы избежать недоразумений. Достижение общего понимания прав и обязанностей помогает избежать неприятных межличностных кризисов.
Наша главная обязанность — справедливое и уважительное отношение к коллегам по профессии. Мы все должны быть в состоянии сделать это.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
Уроки 50 Лет Разработки ПО
Урок 38. Люди много говорят о своих правах, но права подразумевают ответственность
В жизни мы имеем не только права, но и обязанности. Вы имеете право владеть автомобилем, но также должны его зарегистрировать и застраховать. Наряду с правом на покупку недвижимости возникает обязанность платить налог за неё. Сочетание прав и обязанностей определяет отношения людей с обществом.
Люди, работающие над программными проектами, тоже имеют права и обязанности. Наши права в этом случае можно представить как наши ожидания по отношению к другим, а обязанности — как ответственность перед ними. Каждый имеет такие права/обязанности перед своими коллегами, клиентами, руководителями, поставщиками и широкой общественностью.
Помимо конкретных обязательств, которые мы берём на себя перед другими, все специалисты по ПО несут ответственность за соблюдение профессиональной этики: действовать в интересах общества, сохранять конфиденциальность, уважать право интеллектуальной собственности, стремиться к высокому качеству и т.д.
Между правами и обязанностями специалистов по ПО существует определённая симметрия. Если члены команды А имеют право рассчитывать на некие услуги или действия членов команды Б, то верно и обратное.
Вот несколько примеров прав и обязанностей команд, участвующих в разработке ПО. Если вас не устраивает формализм записи прав и обязанностей, то можно сформулировать их в виде: «Для меня резонно ожидать от вас Х, а для вас резонно ожидать от меня Y».
Клиенты
- Право ожидать, что бизнес-аналитик будет использовать информацию о вашем бизнесе исключительно для вашего блага. Вы обязаны дать бизнес-аналитикам и разработчикам всю интересующую их информацию о своем бизнесе.
- Право получить систему, отвечающую потребностям и ожиданиям в отношении качества. Вы обязаны выделить время, необходимое для предоставления и уточнения требований.
- Право изменить свои требования. Вы обязаны оперативно сообщить об изменениях требований команде разработчиков.
Разработчики
- Право на признание и уважение вашей интеллектуальной собственности другими. Вы обязаны уважать право интеллектуальной собственности других лиц, повторно используя плоды их труда только с их разрешения.
- Право знать приоритет каждого требования. Вы обязаны информировать заказчика о влиянии на график новых требований и изменений в приоритетах требований.
- Право оценивать и переоценивать свою работу. Вы обязаны делать свои оценки как можно более точными и как можно быстрее корректировать графики работ, приближая их к реальности.
Руководители или спонсоры проекта
- Право ожидать от разработчиков высококачественного ПО. Вы обязаны предоставить среду, ресурсы и время, чтобы разработчики могли создавать высококачественное ПО.
- Право определять цели проекта и устанавливать графики их реализации. Вы обязаны уважать оценки разработчиков и не принуждать их выполнять работы в нереалистичные сроки.
Вы можете думать, что вам полагаются определённые права, присущие какому-то другому сообществу, но порой они не могут или не хотят оправдывать ваши ожидания. Всякий раз, сталкиваясь с подобным несоответствием, стороны должны научиться работать вместе конструктивно и без раздражения. Стоит потратить время, чтобы обсудить взаимные права и обязанности, и, может быть, даже записать их, чтобы избежать недоразумений. Достижение общего понимания прав и обязанностей помогает избежать неприятных межличностных кризисов.
Наша главная обязанность — справедливое и уважительное отношение к коллегам по профессии. Мы все должны быть в состоянии сделать это.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
👍9
День 2174. #ЗаметкиНаПолях
Изучаем CollectionsMarshal на Примере Словарей
Небезопасный класс CollectionsMarshal предоставляет набор методов для эффективного доступа к базовым представлениям данных коллекций. Обратите внимание на слово «небезопасный». Хотя представленные методы и эффективны, неосторожное обращение может нарушить целостность данных. Сегодня рассмотрим, как использовать CollectionsMarshal для эффективной работы со словарями.
В отличие от ConcurrentDictionary, Dictionary не имеет метода GetOrAdd. Этот метод полезен, когда вы хотите добавить пару ключ-значение в словарь, если ключ не существует, или вернуть значение, если ключ уже существует. Наивная реализация:
Проблема в том, что к словарю обращаются дважды: один раз для проверки существования ключа и один раз для добавления пары ключ-значение. Это означает, что вы дважды вычисляете хэш ключа и вызываете метод Equals как минимум дважды, что неэффективно.
Метод CollectionsMarshal.GetValueRefOrAddDefault возвращает ссылку на значение, связанное с ключом, и логическое значение, указывающее, существует ли ключ. Поскольку метод возвращает ссылку, вы можете обновить значение:
Другой полезны метод, GetValueRefOrNullRef, позволяет, например, обновлять значение по ключу, если оно существует:
Источник: https://www.meziantou.net/exploring-collectionsmarshal-for-dictionary.htm
Изучаем CollectionsMarshal на Примере Словарей
Небезопасный класс CollectionsMarshal предоставляет набор методов для эффективного доступа к базовым представлениям данных коллекций. Обратите внимание на слово «небезопасный». Хотя представленные методы и эффективны, неосторожное обращение может нарушить целостность данных. Сегодня рассмотрим, как использовать CollectionsMarshal для эффективной работы со словарями.
В отличие от ConcurrentDictionary, Dictionary не имеет метода GetOrAdd. Этот метод полезен, когда вы хотите добавить пару ключ-значение в словарь, если ключ не существует, или вернуть значение, если ключ уже существует. Наивная реализация:
public static TValue GetOrAdd<TKey, TValue>(
this Dictionary<TKey, TValue> dict,
TKey key,
TValue value)
where TKey : notnull
{
if (dict.TryGetValue(key, out var result))
return result;
dict[key] = value;
return value;
}
Проблема в том, что к словарю обращаются дважды: один раз для проверки существования ключа и один раз для добавления пары ключ-значение. Это означает, что вы дважды вычисляете хэш ключа и вызываете метод Equals как минимум дважды, что неэффективно.
Метод CollectionsMarshal.GetValueRefOrAddDefault возвращает ссылку на значение, связанное с ключом, и логическое значение, указывающее, существует ли ключ. Поскольку метод возвращает ссылку, вы можете обновить значение:
public static TValue GetOrAdd<TKey, TValue>(
this Dictionary<TKey, TValue> dict,
TKey key,
TValue value)
where TKey : notnull
{
ref var dictVal = ref CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out var exists);
if (exists)
return dictVal;
dictVal = value;
return value;
}
Другой полезны метод, GetValueRefOrNullRef, позволяет, например, обновлять значение по ключу, если оно существует:
public static bool TryUpdate<TKey, TValue>(
this Dictionary<TKey, TValue> dict,
TKey key,
TValue value)
where TKey : notnull
{
ref var dictVal = ref CollectionsMarshal.GetValueRefOrNullRef(dict, key);
if (!Unsafe.IsNullRef(ref dictVal))
{
dictVal = value;
return true;
}
return false;
}
Источник: https://www.meziantou.net/exploring-collectionsmarshal-for-dictionary.htm
👍28
День 2175. #AI
Работа с LLM в .NET. Начало
Большие языковые модели (LLM) произвели революцию в подходе к приложениям на базе ИИ. Хотя многие разработчики знакомы с облачными решениями, такими как модели GPT от OpenAI, локальный запуск LLM становится всё более доступным благодаря таким проектам, как Ollama. Рассмотрим, как использовать LLM в приложениях .NET с Microsoft.Extensions.AI.
LLM — модели глубокого обучения, построенные на огромных объемах данных, способные понимать и генерировать текст, похожий на человеческий. Они могут выполнять различные задачи, вроде завершения текста, резюмирования, классификации или поддержания разговора.
Ollama — проект с открытым кодом, который упрощает запуск LLM локально. Он предоставляет контейнер Docker, который может запускать различные модели с открытым кодом, такие как Llama, что упрощает эксперименты с ИИ без зависимости от облачных сервисов. Ollama занимается управлением и оптимизацией моделей и предоставляет простой API для взаимодействия.
Microsoft.Extensions.AI — библиотека, которая предоставляет унифицированный интерфейс для работы с LLM в приложениях .NET. Созданная на основе семантического ядра Microsoft, она абстрагируется от сложности различных реализаций LLM, позволяя разработчикам переключаться между поставщиками (такими как Ollama, Azure или OpenAI) без изменения кода приложения.
Подготовка
Замечание: сразу оговорюсь, я стараюсь проверять весь код, который выкладываю на канале, но этот пример проверить не было возможности, поэтому доверюсь автору оригинальной статьи. Если вы попробуете это воспроизвести, и у вас возникнут проблемы, пожалуйста, напишите в комментариях.
Для начала надо запустить LLM локально:
1) Запустите Docker
2) Запустите контейнер Ollama с моделью llama3:
3) Добавьте несколько NuGet-пакетов (эти для .NET 9):
Простой чат
Для начала создадим простой чат с ИИ. Вот минимальный код:
Мы настраиваем внедрение зависимости и задаём простой вопрос. Метод расширения AddChatClient регистрирует клиент чата в контейнере DI. Это позволяет внедрять IChatClient в сервисы и взаимодействовать с LLM с помощью простого API. Реализация использует OllamaChatClient для связи с контейнером Ollama, запущенным локально.
Чат с историей
Основываясь на предыдущем примере, создадим интерактивный чат, который сохраняет историю разговоров. Всё, что нам нужно - хранить историю чата:
Здесь мы получаем потоковый ответ — постепенный текстовый вывод, как в ChatGPT. Мы также сохраняем историю чата, что позволяет модели понимать контекст из предыдущих сообщений, делая разговоры более естественными.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/working-with-llms-in-dotnet-using-microsoft-extensions-ai
Работа с LLM в .NET. Начало
Большие языковые модели (LLM) произвели революцию в подходе к приложениям на базе ИИ. Хотя многие разработчики знакомы с облачными решениями, такими как модели GPT от OpenAI, локальный запуск LLM становится всё более доступным благодаря таким проектам, как Ollama. Рассмотрим, как использовать LLM в приложениях .NET с Microsoft.Extensions.AI.
LLM — модели глубокого обучения, построенные на огромных объемах данных, способные понимать и генерировать текст, похожий на человеческий. Они могут выполнять различные задачи, вроде завершения текста, резюмирования, классификации или поддержания разговора.
Ollama — проект с открытым кодом, который упрощает запуск LLM локально. Он предоставляет контейнер Docker, который может запускать различные модели с открытым кодом, такие как Llama, что упрощает эксперименты с ИИ без зависимости от облачных сервисов. Ollama занимается управлением и оптимизацией моделей и предоставляет простой API для взаимодействия.
Microsoft.Extensions.AI — библиотека, которая предоставляет унифицированный интерфейс для работы с LLM в приложениях .NET. Созданная на основе семантического ядра Microsoft, она абстрагируется от сложности различных реализаций LLM, позволяя разработчикам переключаться между поставщиками (такими как Ollama, Azure или OpenAI) без изменения кода приложения.
Подготовка
Замечание: сразу оговорюсь, я стараюсь проверять весь код, который выкладываю на канале, но этот пример проверить не было возможности, поэтому доверюсь автору оригинальной статьи. Если вы попробуете это воспроизвести, и у вас возникнут проблемы, пожалуйста, напишите в комментариях.
Для начала надо запустить LLM локально:
1) Запустите Docker
2) Запустите контейнер Ollama с моделью llama3:
# Получаем контейнер Ollama
docker run --gpus all -d -v ollama_data:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
# Получаем модель llama3
docker exec -it ollama ollama pull llama3
3) Добавьте несколько NuGet-пакетов (эти для .NET 9):
Install-Package Microsoft.Extensions.AI
Install-Package Microsoft.Extensions.AI.Ollama
Install-Package Microsoft.Extensions.Hosting
Простой чат
Для начала создадим простой чат с ИИ. Вот минимальный код:
var builder = Host.CreateApplicationBuilder();
builder.Services.AddChatClient(
new OllamaChatClient(
new Uri("https://localhost:11434"),
"llama3")
);
var app = builder.Build();
var client = app.Services
.GetRequiredService<IChatClient>();
var response =
await client.CompleteAsync(
"What is .NET? Reply in 50 words max.");
Console.WriteLine(response.Message.Text);
Мы настраиваем внедрение зависимости и задаём простой вопрос. Метод расширения AddChatClient регистрирует клиент чата в контейнере DI. Это позволяет внедрять IChatClient в сервисы и взаимодействовать с LLM с помощью простого API. Реализация использует OllamaChatClient для связи с контейнером Ollama, запущенным локально.
Чат с историей
Основываясь на предыдущем примере, создадим интерактивный чат, который сохраняет историю разговоров. Всё, что нам нужно - хранить историю чата:
var history = new List<ChatMessage>();
while (true)
{
Console.WriteLine("Enter prompt:");
var prompt = Console.ReadLine();
history.Add(
new ChatMessage(ChatRole.User, prompt));
Console.WriteLine("Response:");
var response = "";
await foreach (var item in
client.CompleteStreamingAsync(history))
{
Console.Write(item.Text);
response += item.Text;
}
history.Add(new ChatMessage(
ChatRole.Assistant, response));
Console.WriteLine();
}
Здесь мы получаем потоковый ответ — постепенный текстовый вывод, как в ChatGPT. Мы также сохраняем историю чата, что позволяет модели понимать контекст из предыдущих сообщений, делая разговоры более естественными.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/working-with-llms-in-dotnet-using-microsoft-extensions-ai
👍27
День 2176. #AI
Работа с LLM в .NET. Окончание
Начало
Резюмирование статьи
Попробуем что-то более полезное — выделение главной мысли (резюмирование) текста:
Совет: конкретизация выходного формата (например, запрос JSON, соответствующего RFC8259) помогает получать согласованные результаты.
Интеллектуальная категоризация
Мы можем получать строго типизированные ответы напрямую от LLM:
Строго типизированный подход обеспечивает безопасность во время компиляции и лучшую поддержку IDE, что упрощает поддержку и рефакторинг кода, взаимодействующего с ответами LLM.
Использование различных поставщиков LLM
Одним из ключевых преимуществ Microsoft.Extensions.AI является поддержка различных поставщиков. Хотя в наших примерах используется Ollama, вы можете легко переключиться на других поставщиков:
Это позволяет:
- Начать разработку с локальных моделей
- Развернуть приложение с облачными поставщиками
- Переключаться между поставщиками без изменения кода приложения
- Смешивать разных поставщиков для разных вариантов использования (категоризирование, распознавание изображений и т. д.)
Источник: https://www.milanjovanovic.tech/blog/working-with-llms-in-dotnet-using-microsoft-extensions-ai
Работа с LLM в .NET. Окончание
Начало
Резюмирование статьи
Попробуем что-то более полезное — выделение главной мысли (резюмирование) текста:
var posts = Directory.GetFiles("posts")
.Take(5).ToArray();
foreach (var post in posts)
{
var prompt = $$"""
You will receive an input text and the desired output format.
You need to analyze the text and produce the desired output format.
You are not allowed to change code, text, or other references.
# Desired response
Only provide a RFC8259 compliant JSON response following this format without deviation.
{
"title": "Title pulled from the front matter section",
"summary": "Summarize the article in no more than 100 words"
}
# Article content:
{{File.ReadAllText(post)}}
""";
var response =
await client.CompleteAsync(prompt);
Console.WriteLine(response.Message.Text);
Console.WriteLine(Environment.NewLine);
}
Совет: конкретизация выходного формата (например, запрос JSON, соответствующего RFC8259) помогает получать согласованные результаты.
Интеллектуальная категоризация
Мы можем получать строго типизированные ответы напрямую от LLM:
class PostCategory
{
public string Title { get; set; } = string.Empty;
public string[] Tags { get; set; } = [];
}
var posts = Directory.GetFiles("posts").Take(5).ToArray();
foreach (var post in posts)
{
//Такой же запрос, что и в предыдущем примере, только изменим формат JSON-ответа
var prompt = $$"""
…
{
"title": "Title pulled from the front matter section",
"tags": "Array of tags based on analyzing the article content. Tags should be lowercase."
}
…
""";
var response = await
client.CompleteAsync<PostCategory>(prompt);
Console.WriteLine(
$"{response.Result.Title}. Tags: {string.Join(",",response.Result.Tags)}");
}
Строго типизированный подход обеспечивает безопасность во время компиляции и лучшую поддержку IDE, что упрощает поддержку и рефакторинг кода, взаимодействующего с ответами LLM.
Использование различных поставщиков LLM
Одним из ключевых преимуществ Microsoft.Extensions.AI является поддержка различных поставщиков. Хотя в наших примерах используется Ollama, вы можете легко переключиться на других поставщиков:
// Azure OpenAI
builder.Services.AddChatClient(
new AzureOpenAIClient(
new Uri("AZURE_OPENAI_ENDPOINT"),
new DefaultAzureCredential())
.AsChatClient());
// Using OpenAI
builder.Services.AddChatClient(
new OpenAIClient("OPENAI_API_KEY")
.AsChatClient());
Это позволяет:
- Начать разработку с локальных моделей
- Развернуть приложение с облачными поставщиками
- Переключаться между поставщиками без изменения кода приложения
- Смешивать разных поставщиков для разных вариантов использования (категоризирование, распознавание изображений и т. д.)
Источник: https://www.milanjovanovic.tech/blog/working-with-llms-in-dotnet-using-microsoft-extensions-ai
👍11
День 2177. #ЗаметкиНаПолях
Быстрое и Безопасное Восстановление NuGet-пакетов
Некоторые параметры могут помочь повысить производительность и безопасность при восстановлении NuGet-пакетов.
Файлы блокировки
При восстановлении пакетов NuGet создает граф зависимостей, включающий все объявленные и транзитивные пакеты. Затем этот граф используется для определения того, какие пакеты следует загрузить и установить. Файл блокировки позволяет хранить граф зависимостей и повторно использовать его при восстановлении пакета. Это гарантирует, что разрешение всегда восстанавливает те же пакеты.
Преимущества:
- Безопасность: файл содержит хэш пакета. Если вы загружаете поврежденный или вредоносный пакет, NuGet может обнаружить его и отменить установку.
- Детерминированное восстановление: есть некоторые случаи, когда вычисление графа зависимостей не является детерминированным (разная конфигурация NuGet, плавающие версии, пакет удален на сервере и т. д.). Использование файла блокировки позволяет восстанавливать те же пакеты независимо от конфигурации.
- Производительность: не нужно снова вычислять график зависимости при восстановлении пакетов.
- Надёжность: при использовании сервера NuGet с поддержкой вышестоящего уровня, например Azure Artifacts или Artifactory, серверу не нужно связываться с вышестоящим сервером для вычисления графика зависимости. Таким образом, если nuget.org не работает, вы все равно можете восстановить пакеты, если они уже есть в кэше сервера.
Недостатки:
- Вы можете получить больше конфликтов слияния из-за файла блокировки.
- Некоторые инструменты, такие как Dependabot, не обновляют файл блокировки (на момент написания поста).
Чтобы включить файл блокировки, нужно добавить следующую строку в файл .csproj:
Сопоставление источников пакетов
Если у вас несколько источников NuGet для восстановления пакетов, может потребоваться включить сопоставление источников пакетов. NuGet пытается загрузить пакеты из всех источников параллельно и получить результат из первого, кто ответит. Сопоставление источников пакетов позволяет указать, какой источник следует использовать для восстановления пакета.
Преимущества
- Детерминированное восстановление/безопасность: если несколько серверов содержат один и тот же пакет, его можно восстановить с любого из них. Но если пакеты отличаются, вы можете получить несогласованное восстановление.
- Производительность: NuGet не будет тратить время на запросы к нескольким серверам, поэтому вы сокращаете количество сетевых запросов на восстановление пакетов.
Чтобы использовать сопоставление источников пакетов, вам необходимо создать файл nuget.config в корне репозитория и адаптировать конфигурацию для каждого пакета:
См. также документацию по сопоставлению источников пакетов.
Источник: https://www.meziantou.net/faster-and-safer-nuget-restore-using-source-mapping-and-lock-files.htm
Быстрое и Безопасное Восстановление NuGet-пакетов
Некоторые параметры могут помочь повысить производительность и безопасность при восстановлении NuGet-пакетов.
Файлы блокировки
При восстановлении пакетов NuGet создает граф зависимостей, включающий все объявленные и транзитивные пакеты. Затем этот граф используется для определения того, какие пакеты следует загрузить и установить. Файл блокировки позволяет хранить граф зависимостей и повторно использовать его при восстановлении пакета. Это гарантирует, что разрешение всегда восстанавливает те же пакеты.
Преимущества:
- Безопасность: файл содержит хэш пакета. Если вы загружаете поврежденный или вредоносный пакет, NuGet может обнаружить его и отменить установку.
- Детерминированное восстановление: есть некоторые случаи, когда вычисление графа зависимостей не является детерминированным (разная конфигурация NuGet, плавающие версии, пакет удален на сервере и т. д.). Использование файла блокировки позволяет восстанавливать те же пакеты независимо от конфигурации.
- Производительность: не нужно снова вычислять график зависимости при восстановлении пакетов.
- Надёжность: при использовании сервера NuGet с поддержкой вышестоящего уровня, например Azure Artifacts или Artifactory, серверу не нужно связываться с вышестоящим сервером для вычисления графика зависимости. Таким образом, если nuget.org не работает, вы все равно можете восстановить пакеты, если они уже есть в кэше сервера.
Недостатки:
- Вы можете получить больше конфликтов слияния из-за файла блокировки.
- Некоторые инструменты, такие как Dependabot, не обновляют файл блокировки (на момент написания поста).
Чтобы включить файл блокировки, нужно добавить следующую строку в файл .csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--Генерация lock-файла -->
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<!-- Восстановление пакетов только из lock-файла -->
<RestoreLockedMode Condition="'$(ContinuousIntegrationBuild)' == 'true'">true</RestoreLockedMode>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="…" Version="…" />
</ItemGroup>
</Project>
Сопоставление источников пакетов
Если у вас несколько источников NuGet для восстановления пакетов, может потребоваться включить сопоставление источников пакетов. NuGet пытается загрузить пакеты из всех источников параллельно и получить результат из первого, кто ответит. Сопоставление источников пакетов позволяет указать, какой источник следует использовать для восстановления пакета.
Преимущества
- Детерминированное восстановление/безопасность: если несколько серверов содержат один и тот же пакет, его можно восстановить с любого из них. Но если пакеты отличаются, вы можете получить несогласованное восстановление.
- Производительность: NuGet не будет тратить время на запросы к нескольким серверам, поэтому вы сокращаете количество сетевых запросов на восстановление пакетов.
Чтобы использовать сопоставление источников пакетов, вам необходимо создать файл nuget.config в корне репозитория и адаптировать конфигурацию для каждого пакета:
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="mycompany.org" value="https://mycompany.org/nuget/" />
</packageSources>
<packageSourceMapping>
<!-- key должен соответствовать <packageSources> -->
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="mycompany.org">
<package pattern="MyCompany.*" />
<package pattern="MyCompanySpecificPackage" />
</packageSource>
</packageSourceMapping>
См. также документацию по сопоставлению источников пакетов.
Источник: https://www.meziantou.net/faster-and-safer-nuget-restore-using-source-mapping-and-lock-files.htm
👍5
День 2178. #Оффтоп
Почему Открытый Код Важен и Бесплатный ли он? Начало
Какие из продуктов вы используете в своей личной или профессиональной работе: Serilog, Polly, PostgreSQL, Git, Curl, Jenkins, Blazor?
Скорее всего вы используете хотя бы один. Большинство ПО в той или иной степени построено на продуктах или библиотеках с открытым кодом. И часто они не поддерживаются большой компанией. Например, Log4J - самая известная библиотека логирования в экосистеме Java. Основная работа выполняется горсткой разработчиков без какой-либо финансовой поддержки. А она использовалась в Apple, Amazon, Steam, Alibaba и т.п.
Log4J / Log4Shell
Коротко напомню: специальный пользовательский ввод может привести к удалённому выполнению кода через сервер LDAP в контексте приложения. А удалённое выполнение кода – это большой красный флаг в сфере ПО. Проблема в том, как это было воспринято теми самыми компаниями, использовавшими Log4J. Согласно этой статье, мейнтейнеры библиотеки получили такое сообщение: «Мы обещаем сохранить это в тайне, пока не выйдет ваш официальный патч. Пожалуйста, поторопитесь.»
Понятно, что из-за такой уязвимости, возможно, придётся отключить затронутые сервисы. А для Amazon или Alibaba это может стоить миллионов и миллиардов дохода за очень короткое время. Мейнтейнеры написали в Твиттере о ситуации: «Сотрудники Log4j не покладая рук трудятся над мерами по смягчению последствий: исправлениями, документацией, CVE, ответами на запросы и т.д. Однако ничто не мешает людям критиковать нас за работу, за которую нам не платят, за функцию, которая нам всем не нравится, но которую необходимо сохранить из-за проблем с обратной совместимостью.»
Другие инциденты
LeftPad был пакетом NPM, который был удалён из-за спора между ментейнером, NPM и компанией. Суть: у мейнтейнера Azer был пакет под названием "kik". Также была компания "kik", которая хотела зарезервировать это имя для себя. Поскольку Azer уже занял это имя, были привлечены юристы. И NPM отдал имя компании. После этого Azer просто удалил свою наиболее используемую библиотеку "leftpad" (да, вы могли просто удалить пакеты из NPM). Конечно, если вы использовали "leftpad" напрямую или транзитивно, ваша сборка ломалась!
Moq — одна из самых известных библиотек в экосистеме dotnet. Создатель Дэниел Каццулино (более известный как kzu) попробовал альтернативный подход к монетизации: он разработал SponsorLink. По сути, в то время он проверял, сделал ли пользователь пожертвование на библиотеку, в которой используется SponsorLink. Он делал это, выполняя HTTP-запрос на какой-то сервер. Я описывал эту ситуацию подробно в этом посте.
Fluent Assertions — одна из популярнейших библиотек для утверждений в юнит-тестах начиная с версии 8 стала платной.
Эти инциденты вызвали довольно много негативной реакции, но все они показывают некоторые фундаментальные недостатки открытого кода:
- Проекты с открытым кодом считаются бесплатными.
- Монетизация — это сложно!
- Требуется поддержка проекта в рабочем состоянии в течение длительного периода
времени.
Продолжение следует…
Источник: https://steven-giesel.com/blogPost/591f2354-a205-4507-bbb2-7d88781e0563/why-is-open-source-important-and-is-it-free
Почему Открытый Код Важен и Бесплатный ли он? Начало
Какие из продуктов вы используете в своей личной или профессиональной работе: Serilog, Polly, PostgreSQL, Git, Curl, Jenkins, Blazor?
Скорее всего вы используете хотя бы один. Большинство ПО в той или иной степени построено на продуктах или библиотеках с открытым кодом. И часто они не поддерживаются большой компанией. Например, Log4J - самая известная библиотека логирования в экосистеме Java. Основная работа выполняется горсткой разработчиков без какой-либо финансовой поддержки. А она использовалась в Apple, Amazon, Steam, Alibaba и т.п.
Log4J / Log4Shell
Коротко напомню: специальный пользовательский ввод может привести к удалённому выполнению кода через сервер LDAP в контексте приложения. А удалённое выполнение кода – это большой красный флаг в сфере ПО. Проблема в том, как это было воспринято теми самыми компаниями, использовавшими Log4J. Согласно этой статье, мейнтейнеры библиотеки получили такое сообщение: «Мы обещаем сохранить это в тайне, пока не выйдет ваш официальный патч. Пожалуйста, поторопитесь.»
Понятно, что из-за такой уязвимости, возможно, придётся отключить затронутые сервисы. А для Amazon или Alibaba это может стоить миллионов и миллиардов дохода за очень короткое время. Мейнтейнеры написали в Твиттере о ситуации: «Сотрудники Log4j не покладая рук трудятся над мерами по смягчению последствий: исправлениями, документацией, CVE, ответами на запросы и т.д. Однако ничто не мешает людям критиковать нас за работу, за которую нам не платят, за функцию, которая нам всем не нравится, но которую необходимо сохранить из-за проблем с обратной совместимостью.»
Другие инциденты
LeftPad был пакетом NPM, который был удалён из-за спора между ментейнером, NPM и компанией. Суть: у мейнтейнера Azer был пакет под названием "kik". Также была компания "kik", которая хотела зарезервировать это имя для себя. Поскольку Azer уже занял это имя, были привлечены юристы. И NPM отдал имя компании. После этого Azer просто удалил свою наиболее используемую библиотеку "leftpad" (да, вы могли просто удалить пакеты из NPM). Конечно, если вы использовали "leftpad" напрямую или транзитивно, ваша сборка ломалась!
Moq — одна из самых известных библиотек в экосистеме dotnet. Создатель Дэниел Каццулино (более известный как kzu) попробовал альтернативный подход к монетизации: он разработал SponsorLink. По сути, в то время он проверял, сделал ли пользователь пожертвование на библиотеку, в которой используется SponsorLink. Он делал это, выполняя HTTP-запрос на какой-то сервер. Я описывал эту ситуацию подробно в этом посте.
Fluent Assertions — одна из популярнейших библиотек для утверждений в юнит-тестах начиная с версии 8 стала платной.
Эти инциденты вызвали довольно много негативной реакции, но все они показывают некоторые фундаментальные недостатки открытого кода:
- Проекты с открытым кодом считаются бесплатными.
- Монетизация — это сложно!
- Требуется поддержка проекта в рабочем состоянии в течение длительного периода
времени.
Продолжение следует…
Источник: https://steven-giesel.com/blogPost/591f2354-a205-4507-bbb2-7d88781e0563/why-is-open-source-important-and-is-it-free
👍19👎1
День 2179. #Оффтоп
Почему Открытый Код Важен? И Бесплатный ли он? Продолжение
Начало
Открытый код бесплатный?
Простой ответ: Да. Можно же просто скачать любой пакет и использовать его? Ну… и да, и нет. Конечно, это «бесплатно». В том смысле, что вы не платите за труд по написанию кода, но есть другие затраты: обслуживание и зависимости. Это звучит странно. Разве не поэтому люди используют библиотеки других людей - чтобы меньше обслуживать код?
Плата за обслуживание
Когда вы используете открытый код, вы наследуете не только его функции, но и его жизненный цикл. Библиотеки с открытым кодом со временем развиваются. У них могут быть критические проблемы, из-за которых вам придётся обновлять пакет. Критические изменения или другие вещи, из-за которых придётся проверять, всё ли ваше ПО по-прежнему делает то, что оно должно делать.
Некоторые проекты с открытым кодом со временем теряют активных мейнтейнеров. Если вы полагаетесь на такую библиотеку, у вас остаётся три варианта:
- Продолжить использовать устаревшую версию (риск безопасности).
- Перейти на альтернативу (может потребовать много усилий, не предоставив прямой ценности).
- Взять на себя обслуживание (сделать форк). Это затраты на обслуживания кода, который вам нужен, а может и не нужен или нужен не весь. Иногда библиотека, от которой вы зависите, не соответствует вашим потребностям, поэтому вам, возможно, придется её форкнуть. Теперь вы также «владеете» кодом со всеми его затратами, зависимостями и последствиями.
Во всех этих случаях вы платите, тратите время и деньги. Каждая зависимость, которую вы создаёте, будет иметь цену. Вам нужно взвесить, оправдана ли она. И эти затраты будут возникать время от времени, а не один раз за весь срок существования проекта. Это особенно важно, если вы используете много микробиблиотек, вроде Left Pad, которые чаще всего содержат не более 10 строк кода и выполняют элементарные функции. Еще один отличный пример: is-even и is-odd. У обеих до сих пор 200000 (да, двести тысяч) загрузок в неделю.
Так что нет, открытый код не бесплатный. Он бесплатный в том смысле, что не стоит денег, но почти всё имеет свою цену! Конечно, то же самое относится и к библиотекам с закрытым кодом, которые вы можете использовать. Они также стоят денег, но они стоят вам большую часть времени денег сверху, и вы не можете наблюдать за процессом разработки открыто.
Все инциденты, описанные ранее, известны и были быстро устранены, потому что всё происходило открыто и прозрачно. Это хорошо. Этим открытый код и прекрасен. И в заключении мы поговорим о другой стороне – мейнтейнерах.
Окончание следует…
Источник: https://steven-giesel.com/blogPost/591f2354-a205-4507-bbb2-7d88781e0563/why-is-open-source-important-and-is-it-free
Почему Открытый Код Важен? И Бесплатный ли он? Продолжение
Начало
Открытый код бесплатный?
Простой ответ: Да. Можно же просто скачать любой пакет и использовать его? Ну… и да, и нет. Конечно, это «бесплатно». В том смысле, что вы не платите за труд по написанию кода, но есть другие затраты: обслуживание и зависимости. Это звучит странно. Разве не поэтому люди используют библиотеки других людей - чтобы меньше обслуживать код?
Плата за обслуживание
Когда вы используете открытый код, вы наследуете не только его функции, но и его жизненный цикл. Библиотеки с открытым кодом со временем развиваются. У них могут быть критические проблемы, из-за которых вам придётся обновлять пакет. Критические изменения или другие вещи, из-за которых придётся проверять, всё ли ваше ПО по-прежнему делает то, что оно должно делать.
Некоторые проекты с открытым кодом со временем теряют активных мейнтейнеров. Если вы полагаетесь на такую библиотеку, у вас остаётся три варианта:
- Продолжить использовать устаревшую версию (риск безопасности).
- Перейти на альтернативу (может потребовать много усилий, не предоставив прямой ценности).
- Взять на себя обслуживание (сделать форк). Это затраты на обслуживания кода, который вам нужен, а может и не нужен или нужен не весь. Иногда библиотека, от которой вы зависите, не соответствует вашим потребностям, поэтому вам, возможно, придется её форкнуть. Теперь вы также «владеете» кодом со всеми его затратами, зависимостями и последствиями.
Во всех этих случаях вы платите, тратите время и деньги. Каждая зависимость, которую вы создаёте, будет иметь цену. Вам нужно взвесить, оправдана ли она. И эти затраты будут возникать время от времени, а не один раз за весь срок существования проекта. Это особенно важно, если вы используете много микробиблиотек, вроде Left Pad, которые чаще всего содержат не более 10 строк кода и выполняют элементарные функции. Еще один отличный пример: is-even и is-odd. У обеих до сих пор 200000 (да, двести тысяч) загрузок в неделю.
Так что нет, открытый код не бесплатный. Он бесплатный в том смысле, что не стоит денег, но почти всё имеет свою цену! Конечно, то же самое относится и к библиотекам с закрытым кодом, которые вы можете использовать. Они также стоят денег, но они стоят вам большую часть времени денег сверху, и вы не можете наблюдать за процессом разработки открыто.
Все инциденты, описанные ранее, известны и были быстро устранены, потому что всё происходило открыто и прозрачно. Это хорошо. Этим открытый код и прекрасен. И в заключении мы поговорим о другой стороне – мейнтейнерах.
Окончание следует…
Источник: https://steven-giesel.com/blogPost/591f2354-a205-4507-bbb2-7d88781e0563/why-is-open-source-important-and-is-it-free
👍7