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

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День 2567. #ЗаметкиНаПолях
Метод HTTP PATCH: Частичные Обновления в REST API. Начало
HTTP PATCH применяет частичные изменения к ресурсу. Он решает распространённую задачу проектирования API: обновление определённых полей без замены всего ресурса. Рассмотрим метод PATCH, чем он отличается от PUT и POST, и как эффективно реализовать запросы PATCH.

Пример: Обновление роли пользователя
PATCH /api/users/12345 HTTP/1.1
Content-Type: application/json

{
"role": "Senior Developer"
}

Сервер обновляет только поле роли, оставляя остальные поля неизменными.

PATCH, PUT или POST
PATCH
Цель: частичное обновление;
Отправляемые данные: только изменяемые поля;
Идемпотентность: не является идемпотентным, но часто запросы PATCH разрабатываются с учётом возможности их идемпотентности;
Использование: обновление отдельных полей ресурса;
Результат: обновляются только отправленные поля.

PUT
Цель: полная замена;
Отправляемые данные: ресурс целиком;
Идемпотентность: да;
Использование: замена всего ресурса;
Результат: заменяется ресурс целиком.

POST
Цель: замена или действие;
Отправляемые данные: новый ресурс;
Идемпотентность: нет;
Использование: создание нового ресурса или действие над ресурсом;
Результат: отправленные поля заменяются, не отправленные устанавливаются в значения по умолчанию.

Когда не использовать
1. Нужно заменить весь ресурс (используйте PUT).
2. Обновления неидемпотентны (рассмотрите POST).
3. Контракт API требует полной проверки всех полей при каждом обновлении.
4. Ресурса не существует (верните 404 и используйте POST для его создания).

Форматы запросов
1. JSON Merge-patch
Отправляет JSON-объект, содержащий только поля для обновления:
PATCH /api/users/12345
Content-Type: application/merge-patch+json

{
"email": "updated@example.com",
"role": "Manager"
}

Этот подход прост и интуитивно понятен, но может быть неоднозначным для вложенных объектов и значений NULL.

2. JSON Patch
JSON Patch (RFC 6902) обеспечивает точный контроль с помощью массива операций:
PATCH /api/users/12345
Content-Type: application/json-patch+json

[
{ "op": "replace", "path": "/email", "value": "new@example.com" },
{ "op": "add", "path": "/phone", "value": "+1-555-0123" },
{ "op": "remove", "path": "/temporary_field" }
]

Доступные операции:
- add – добавление нового поля или элемента массива;
- remove – удаление поля;
- replace – обновление существующего поля;
- move – перемещение значения в новое место;
- copy – копирование значения в новое место;
- test – проверка значения перед применением операции.

Стандартные ответы метода PATCH
Успешные ответы:
- 200 OK — обновление успешно, возвращается обновлённый ресурс;
- 204 No Content - обновление успешно, но тело ответа отсутствует;
- 202 Accepted - обновление принято для асинхронной обработки.

Ответы с ошибкой:
- 400 Bad Request - неверный формат или данные;
- 401 Unauthorized - требуется аутентификация;
- 403 Forbidden - недостаточные права доступа;
- 404 Not Found - ресурса не существует;
- 409 Conflict - обновление конфликтует с текущим состоянием ресурса;
- 422 Unprocessable Entity - валидный JSON, но семантически некорректный.

Понимание идемпотентности PATCH
Идемпотентность означает, что многократное применение одного и того же запроса дает тот же результат, что и однократное применение. Это свойство имеет решающее значение для безопасной обработки повторных попыток в сети. PATCH по своей природе не является идемпотентным, но многие API разрабатывают запросы PATCH таким образом, чтобы они вели себя идемпотентно для обеспечения надёжности и безопасных повторных попыток.
Пример идемпотентного PATCH:
PATCH /api/users/12345

{
"email": "consistent@example.com"
}

Многократная отправка этого запроса приводит к одному и тому же итоговому состоянию ресурса.

Пример неидемпотентного PATCH:
PATCH /api/products/789

{
"inventory_adjustment": -5
}

Каждый запрос вычитает 5 единиц инвентаря, приводя к различным итоговым состояниям ресурса.

Окончание следует…

Источник:
https://blog.postman.com/http-patch-method/
👍12
День 2568. #ЗаметкиНаПолях
Метод HTTP PATCH: Частичные Обновления в REST API. Окончание

Начало

Лучшие практики реализации запросов PATCH
1. Делайте запросы идемпотентными
Используйте абсолютные значения в запросах PATCH вместо относительных. Для операций, требующих относительных обновлений, используйте запрос POST, инициирующий действие над ресурсом вместо модифицирующего ресурс запроса PATCH.

2. Документируйте модифицируемые поля
Чётко укажите, какие поля можно изменять, а какие нельзя.
PATCH /api/users/{id}

Поля, допускающие изменения:
- email (string, valid email format)
- role (string: "user", "admin", "manager")
- preferences (object)

Защищённые поля (не подлежат изменению):
- id, created_at, username

3. Проверка перед применением изменений
Сначала проверьте все поля и применяйте обновления только в том случае, если все проверки пройдены успешно.

4. Явно обрабатывайте NULL
Разделяйте пропущенные поля (оставьте их без изменений) и явно заданные значения NULL (очищайте поле).

5. Возвращайте обновлённый ресурс
После успешного выполнения PATCH возвращайте полный обновлённый ресурс, чтобы клиенты могли подтвердить изменения.

Безопасность PATCH
Поскольку PATCH изменяет существующие данные, необходимы строгие меры безопасности.

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

2. Ограничивайте доступ к конфиденциальным полям
Никогда не позволяйте PATCH изменять поля, управляемые системой или критически важные для безопасности, такие как id, created_at, password_hash или флаги разрешений.

3. Проверяйте все входные данные
Обрабатывайте данные PATCH как любые пользовательские входные данные. Проверяйте типы, форматы и диапазоны, чтобы предотвратить атаки внедрения и повреждение данных.

4. Используйте HTTPS
Запросы PATCH часто содержат конфиденциальные данные. Всегда используйте HTTPS для шифрования данных при передаче.

5. Примените ограничения запросов
Предотвратите злоупотребления, ограничив количество запросов PATCH на пользователя или IP-адрес.

Распространённые ошибки
1. Обработка запросов PATCH как PUT
Не требуйте все поля в запросе PATCH. Отправляйте только то, что нужно изменить.

2. Создание ресурсов с помощью PATCH вместо POST
Возвращайте 404 Not Found при попытке изменить несуществующие ресурсы с помощью PATCH. Используйте POST для создания ресурсов.

3. Разрешение обновлений неизменяемых полей
Защитите управляемые системой поля от изменения с помощью чётких правил проверки.

4. Игнорирование зависимостей между связанными полями
Некоторые поля зависят от других. Проверяйте эти связи перед применением изменений.

5. Пропуск защиты транспортного уровня
Даже при надлежащей аутентификации всегда используйте HTTPS для шифрования запросов PATCH и защиты конфиденциальных данных.

Итого
Метод HTTP PATCH в основном используется для указания того, какие изменения должны быть внесены в ресурс без повторной отправки всего его состояния. Когда запросы PATCH чётко определены по области действия, проверены заранее и разработаны таким образом, чтобы вести себя предсказуемо, они уменьшают случайную потерю данных и упрощают развитие API с течением времени. При таком использовании PATCH становится мощным инструментом для создания масштабируемых API без нарушения работы клиентов.

Источник: https://blog.postman.com/http-patch-method/
👍4
День 2569. #ЗаметкиНаПолях #AI
Руководство по Эффективному Промпт-Инжинирингу. Начало

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

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

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

Что делает промпт хорошим
Промпт обычно состоит из нескольких компонентов:
- Описание задачи - объясняет, что мы хотим, чтобы модель делала, включая любую роль или образ, который мы хотим, чтобы она приняла.
- Контекст - предоставляет необходимую справочную информацию. Примеры демонстрируют желаемое поведение или формат.
- Конкретный вопрос, на который нужно ответить, или действие, которое нужно выполнить.

Большинство API для моделей позволяют разделять промпты на системные и пользовательские:
- Системные обычно содержат описания задач и инструкции по роли, определяющей поведение модели на протяжении всего разговора.
- Пользовательские содержат саму задачу или вопрос.
Например, если мы создаём чат-бота, который помогает покупателям понимать информацию о недвижимости, системный промпт может указывать модели действовать как опытный агент по недвижимости, а пользовательский будет содержать конкретный вопрос о недвижимости.

Ясность — ключевой фактор эффективного промпта. Так же, как чёткая коммуникация помогает людям понять, что им нужно, конкретные и недвусмысленные инструкции помогают моделям ИИ генерировать соответствующие ответы. Мы должны точно объяснить, чего хотим, определить любые системы оценки или форматы, которые ожидаем, и исключить предположения о том, что модель уже может знать.

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

Как модели обрабатывают промпты
Обучение в контексте — способность модели обучаться новым моделям поведения на примерах, предоставленных в самом промпте, без необходимости обновления весов модели. Когда мы показываем модели примеры выполнения задачи, она может адаптировать свои ответы в соответствии с продемонстрированным нами шаблоном.

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

Количество необходимых примеров зависит как от возможностей модели, так и от сложности задачи. Более мощные модели, как правило, требуют меньшего количества примеров для понимания того, что нам нужно. Для более простых задач мощным моделям может вообще не понадобиться ни одного примера. Однако для приложений, специфичных для конкретной области, или сложных требований к форматированию предоставление нескольких примеров может существенно изменить ситуацию.

Продолжение следует…

Источник:
https://blog.bytebytego.com/p/a-guide-to-effective-prompt-engineering
👎7👍2
День 2570. #ЗаметкиНаПолях #AI
Руководство по Эффективному Промпт-Инжинирингу. Продолжение

Начало

Основные техники
1. Без примеров (Zero-Shot)

Описываем, что хотим получить, и модель пытается выполнить запрос на основе своих знаний. Подходит для простых задач, где желаемый результат ясен из самих инструкций: «Переведи текст на французский» или «Кратко изложи содержание этой статьи».
Преимущество: меньше токенов, промпт проще писать и поддерживать.
Недостаток: когда требуется определённое форматирование или поведение, промпта без примеров может быть недостаточно.
Лучшие практики:
- Максимально чёткое описание желаемого результата;
- Ясное указание формата вывода, любых ограничений или требований;

2. С примерами (Few-Shot)
Подходит, когда требуется определённый формат или когда желаемое поведение сложно определить из одних только инструкций.
Большее примеров - лучше производительность, но мы ограничены длиной контекста и соображениями стоимости. Обычно 3-5 примеров обеспечивают хороший баланс.
При форматировании примеров можно экономить токены, выбирая эффективные структуры. Например, «пицца -> съедобный» использует меньше токенов, чем «Вход: пицца, Выход: съедобный», сообщая при этом ту же информацию.

3. Цепочка рассуждений (Chain-of-Though, CoT)
Предполагает явное указание модели пошагово обдумывать получение ответа. Способствует систематическому решению проблем и значительно улучшает производительность в сложных задачах на рассуждение.
Простейшая реализация — добавление к промпту фраз типа «объясни свои рассуждения». Так модель методично решает задачу, демонстрируя процесс рассуждения, прежде чем прийти к выводу.
CoT часто улучшает производительность модели в различных тестах, особенно для математических задач, логических головоломок и задач на многошаговое рассуждение. Также помогает уменьшить количество ошибок, поскольку модель должна обосновывать свои ответы явными шагами рассуждения.
Можно указать точные шаги, которые мы хотим, чтобы модель выполнила, или предоставить примеры, демонстрирующие процесс рассуждения.
Недостаток: увеличение времени ответа и стоимости. Модель генерирует больше токенов по мере обработки рассуждений. Для сложных задач, где точность имеет решающее значение, этот компромисс обычно оправдан.

4. Ролевой
Назначает модели определённую роль или область знаний. Так мы влияем на точку зрения и стиль ответов. Особенно эффективно в приложениях для обслуживания клиентов, образовательном контенте, творческом письме и любых сценариях, где контекст или уровень квалификации имеют значение. Модель может корректировать словарный запас, уровень детализации и подход в зависимости от назначенной роли.
Следует быть максимально подробными в описании роли и любых соответствующих характеристик. Чем конкретнее, тем лучше модель сможет «сыграть эту роль».

5. Цепочка промптов и декомпозиция
Предполагает разбиение сложных задач на более мелкие, управляемые подзадачи, со своим промптом на каждую.
Например, чат-бот службы поддержки клиентов. Процесс ответа на запрос клиента можно разделить на:
- Классификацию намерения запроса: нужна ли клиенту помощь с выставлением счетов, техническая поддержка, управление учётной записью или общая информация.
- Генерацию соответствующего ответа: отдельный этап для генерации фактического ответа на основе намерения.
Недостаток: увеличение воспринимаемой пользователями задержки. Однако для сложных приложений улучшенная надёжность и удобство сопровождения часто перевешивают этот недостаток.

Окончание следует…

Источник:
https://blog.bytebytego.com/p/a-guide-to-effective-prompt-engineering
👍5👎5
День 2571. #ЗаметкиНаПолях #AI
Руководство по Эффективному Промпт-Инжинирингу. Окончание
Начало https://news.1rj.ru/str/NetDeveloperDiary/3089
Продолжение https://news.1rj.ru/str/NetDeveloperDiary/3090

Рекомендации по написанию эффективных промптов
1. Будьте ясны и конкретны: нужно устранить любую неопределённость относительно того, что мы хотим, чтобы модель сделала. Чтобы модель оценила эссе, нужно указать шкалу оценок. Допускаются ли дробные оценки? Что должна делать модель, если она не уверена в оценке?

2. Предоставьте достаточный контекст: контекст помогает моделям генерировать точные и релевантные ответы. Чтобы получить ответы на вопросы о документе, включение его в промпт крайне важно. Без него модель может полагаться только на свои обучающие данные, что может привести к устаревшей или неверной информации.

3. Укажите формат вывода: краткий ответ или подробное объяснение? JSON, маркированный список или абзац текста? Включать ли преамбулы или сразу переходить к сути?

4. Стратегически используйте примеры: их следует приводить, когда желаемый формат или поведение не очевидны из одних только инструкций.

5. Итерация и экспериментирование: разработка промптов — итеративный процесс. Начните с базового промпта, проанализируйте результаты и дорабатывайте промпт на основе полученных знаний.

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

Распространённые ошибки
1. Излишняя расплывчатость: предположение, что модель понимает наше намерение без явного объяснения. Такие промпты оставляют слишком много места для интерпретации. Модель сделает свой выбор, который может не совпадать с тем, чего мы на самом деле хотим.

2. Чрезмерное усложнение заданий: слишком сложные задания с избыточными инструкциями, большим количеством примеров или сложной логикой могут запутать модель, а не помочь ей. Стремитесь к самому простому заданию, которое достигает цели. Если задание без примеров работает хорошо, нет необходимости добавлять примеры.

3. Игнорирование формата вывода: может вызвать проблемы, особенно когда выходные данные модели передаются в другие системы. Если нужны структурированные данные, но мы не запрашиваем их явно, модель может сгенерировать неструктурированный текст, требующий дополнительной обработки или очистки. Это усложняет работу приложения и создаёт потенциальные точки отказа.

4. Недостаточное тестирование: один успешный результат не означает надёжность запроса. Необходимо тестировать запросы с различными входными данными, включая крайние случаи и необычные сценарии. То, что работает в типичных случаях, может дать сбой, если входные данные немного отличаются или неожиданны. Создание небольшого оценочного набора данных и систематическое тестирование помогают выявлять слабые места до того, как они станут проблемами в производственной среде.

Итого
Эффективная разработка промптов сочетает в себе чёткую коммуникацию, стратегическое использование примеров и систематическое экспериментирование.
Ключевые принципы остаются неизменными для различных моделей и приложений:
- Будьте конкретны и ясны в своих инструкциях.
- Предоставьте достаточный контекст для работы модели.
- Укажите необходимый формат выходных данных.
- Используйте примеры, когда они приносят пользу, и вносите изменения на основе полученных результатов.

Источник:
https://blog.bytebytego.com/p/a-guide-to-effective-prompt-engineering
👎7👍3
День 2572. #Карьера
Топ Советов по Повышению Продуктивности. Часть 8

Части 1, 2, 3, 4, 5, 6, 7

8. Освойте IDE как музыкальный инструмент
Неприятная правда: большинство разработчиков используют IDE, как будто играют на пианино двумя пальцами. Музыка звучит, но по сравнению с тем, кто в совершенстве овладел инструментом, разница колоссальная.

IDE — ваш основной интерфейс для работы с кодом. Каждое действие — открытие файлов, навигация по коду, рефакторинг, запуск тестов — либо происходит плавно на автомате, либо неуклюже серией кликов. Разница накапливается, превращаясь в часы в неделю, а затем в недели в год. Разница в продуктивности новичка и эксперта в IDE - 2-3 раза.

Уровень 1: Освойте основные сочетания клавиш
Перестаньте использовать мышь для навигации. Серьёзно. Мышь плохо предназначена редактирования и поиска кода. Вот старый, но всё ещё актуальный пост о сочетаниях клавиш в Visual Studio.
Челлендж: в течение недели каждый раз, когда вы тянетесь к мышке, делайте паузу. Спросите себя: «Есть ли для этого сочетание клавиш?» Найдите его. Используйте. Через неделю многие действия станут автоматическими.

Уровень 2: Шаблоны для повторяющегося кода
Вы пишете одни и те же шаблоны кода снова и снова. Перестаньте набирать их посимвольно. VS автоматически добавит шаблон кода при нажатии Tab после набора ключевых слов: for, foreach, switch, try, ctor (конструктор), prop (свойство) и т.п. Создайте шаблоны для наиболее используемых вами фрагментов кода.

Уровень 3: Функции IDE, которые вы, скорее всего, не используете
Инструменты рефакторинга: не переименовывайте вручную функцию и её 47 повторений. Позвольте IDE сделать это безопасно, в том числе и в разных файлах (Ctrl + R,R). То же самое относится к «Извлечь метод», «Извлечь переменную» и т.п.

Множественный курсор - освойте это. Научитесь:
- Устанавливать курсоры на нескольких строках;
- Добавлять курсоры выше/ниже текущей строки;
- Выделять все вхождения в файле.

Изучите горячие клавиши для навигации по коду:
- Переход к соответствующей скобке;
- Переход между изменениями;
- Переход к предыдущей/следующей позиции курсора (как назад/вперёд в браузере);
- Переход по ошибкам/предупреждениям;
- Закладки и навигация по ним.

Интеграция с Git: перестаньте переключаться на терминал для каждой операции Git. Научитесь добавлять фрагменты кода в индекс, просматривать различия, разрешать конфликты и создавать коммиты прямо в IDE. Одних только инструментов визуального сравнения изменений достаточно, чтобы их освоить.

Уровень 4: Оптимизация рабочего пространства и UI
Разумное разделение редакторов: не открывайте только один файл за раз. Разделите экран, чтобы видеть:
- Файл реализации слева, файл теста справа;
- Код компонента сверху, стили снизу;
- Маршрут API сверху, модель базы данных снизу.

Используйте группировки и управление вкладками:
- Закрепляйте часто используемые файлы, чтобы они не закрывались;
- Используйте вертикальное или горизонтальное разделение в зависимости от файлов;
- Научитесь переключаться между вкладками без использования мыши (Ctrl+Tab).

Создавайте настройки для конкретного рабочего пространства: разные проекты имеют разные потребности. Настройте для проекта:
- Правила форматирования кода;
- Пользовательские шаблоны кода
- Задачи сборки;
- Конфигурации отладки.

Уровень 5: Расширения и плагины, которые действительно важны
Не устанавливайте множество расширений, которые замедляют IDE. Используйте только действительно нужные. Перед установкой расширения проверьте, есть ли в IDE эта функциональность. Многие функции, ради которых люди устанавливают расширения, уже есть в IDE, если вы знаете, где искать.

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

22. Стратегии ветвления в Git
«Опишите стратегию ветвления Git, которую вы использовали в своих проектах, и как она помогает эффективно управлять циклами разработки и выпуска?»

Хороший ответ
Одна из эффективных стратегий ветвления Git — стратегия Git Flow. Согласно этой стратегии, работа организуется вокруг двух ветвей с бесконечным временем жизни:
- главная ветка (main), в которой исходный код HEAD всегда отражает состояние, готовое к использованию в продакшене.
- ветка develop служит интеграционной ветвью для новых функций. Она всегда отражает состояние с последними внесёнными изменениями для следующего релиза.

Дополнительные ветки, используемые в Git Flow:
- Ветки функций (Feature branches) – ответвляются от develop и сливаются обратно в develop. Каждая feature-ветка используется для разработки новой функции для будущего релиза. Обычно они создаются для каждой новой функции.
- Ветки релизов (Release branches) - ответвляются от develop и сливаются в develop и main. Используются для подготовки к новому релизу. Позволяют вносить незначительные исправления ошибок и подготавливать метаданные для релиза (номер версии, дату сборки и т.д.).
- Ветки исправлений (Hotfix branches) - ответвляются от main и сливаются в develop и main. Используются для быстрого обновления производственных релизов.

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

Вот как можно использовать эту стратегию на практике:
# Создание ветки для функции
git checkout -b feature/new-cool-feature develop

# Завершение работы над функцией и слияние
git checkout develop
git merge feature/new-cool-feature
git branch -d feature/new-cool-feature

# Подготовка релиза
git checkout -b release/1.2.0 develop
#Специфичная для релиза метаинформация
git checkout master
git merge release/1.2.0
git tag -a 1.2.0

# Патч бага в продакшене
git checkout -b hotfix/urgent-fix master
#Исправление бага
git checkout master
git merge hotfix/urgent-fix
git tag -a 1.2.1
git checkout develop
git merge hotfix/urgent-fix
git branch -d hotfix/urgent-fix

Эта стратегия особенно полезна для поддержания контроля над разработкой и релизами, обеспечивая надёжную доставку ПО.

Часто встречающийся плохой ответ
«Мы использовали одну ветку для всего, потому что это проще и легче в управлении. После тестирования кода мы делали коммиты напрямую в ветку main, не усложняя систему несколькими ветками.»

Почему это неправильно:
- Риск нестабильности: коммиты напрямую в main увеличивают риск внедрения нестабильного кода в продакшн. Это может привести к серьёзным проблемам с развёртыванием и эксплуатацией.

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

- Неэффективность в обработке релизов и исправлений: без выделенных веток для релизов и исправлений становится сложно управлять различными версиями и исправлять проблемы, не влияя на основной рабочий процесс разработки.

Обычно эта ошибка возникает из-за недостатка опыта работы с совместными проектами значительной сложности или непонимания важности структурированных рабочих процессов для поддержания качества и стабильности кода. Такой подход может привести к значительным проблемам масштабирования процесса разработки и управления несколькими одновременными инициативами.

Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
👍10
День 2574. #ЧтоНовенького #DotNet11
Асинхронность в Рантайме в превью 1 .NET 11. Начало

В .NET 11 превью 1 появилась революционная функция: асинхронные операции в среде выполнения. Вместо того чтобы заставлять компилятор C# переписывать методы async/await в конечные автоматы, сама среда выполнения .NET теперь будет рассматривать асинхронные методы как нативную концепцию. Рассмотрим, что это такое, почему это важно и как вы можете поэкспериментировать с ними.

Проблема с текущей реализацией
С тех пор, как в C# 5 были введены async/await, компилятор был единственным ответственным за работу асинхронных операций. Когда вы пишете асинхронный метод, компилятор C# переписывает его в конечный автомат — сгенерированную структуру, реализующую IAsyncStateMachine, которая отслеживает прогресс метода в точках приостановки.

Недостатки
1. Накладные расходы на конечный автомат
Каждый асинхронный метод генерирует структуру конечного автомата с полями для каждой локальной переменной, которая «переходит через await». Когда метод не завершается синхронно, эта структура помещается в кучу.
2. Неудобство для отладчика
Сгенерированный код конечного автомата затрудняет пошаговое выполнение асинхронных методов. Трассировка стека показывает синтетические методы MoveNext вместо исходных имён методов.
3. Слепые зоны профилировщика
Инструменты анализа
производительности с трудом правильно распределяют время между точками приостановки асинхронных операций, поскольку среда выполнения не знает асинхронной семантики — она видит только обычные вызовы методов.
4. Упущенные возможности оптимизации
Т.к. среда выполнения не понимает паттерн асинхронности, она не может оптимизировать цепочки асинхронных вызовов. Каждый вызов await приводит к полному циклу приостановки/возобновления, даже если среда выполнения теоретически могла бы оптимизировать передачу управления.

Что такое асинхронность в среде выполнения?
Асинхронность в среде выполнения переносит понятие асинхронных методов из компилятора в саму среду выполнения .NET. Вместо того чтобы компилятор генерировал сложный конечный автомат, он генерирует более простой IL-код, аннотированный [MethodImpl(MethodImplOptions.Async)]. Затем среда выполнения берёт на себя ответственность за:
- Приостановление и возобновление: среда выполнения управляет сохранением и восстановлением состояния метода в точках приостановки, устраняя необходимость в структурах конечного автомата, генерируемых компилятором.
- Поднятие локальных переменных: «Поднимаются» (сохраняются при переходе через await) только те переменные, которые фактически существуют между точками приостановки, и среда выполнения обрабатывает это напрямую.
- Оптимизированные асинхронные вызовы: когда один асинхронный метод среды выполнения вызывает другой, среда выполнения может оптимизировать передачу, потенциально полностью избегая аллокаций экземпляров Task в цепочках асинхронных вызовов.

Как работает новая модель?
В модели асинхронности в среде выполнения асинхронные методы используют AsyncHelpers для выражения приостановки:
namespace System.Runtime.CompilerServices
{
public static class AsyncHelpers
{
[MethodImpl(MethodImplOptions.Async)]
public static void Await(Task task);
[MethodImpl(MethodImplOptions.Async)]
public static void Await(ValueTask task);

}
}

Когда компилятор C# генерирует асинхронный IL-код, вместо построения полного конечного автомата он создает вызов AsyncHelpers.Await(…). Среда выполнения перехватывает этот вызов, и, если задача ещё не завершена, приостанавливает выполнение метода, сохраняя только необходимое состояние, и возобновляет его позже, когда результат станет доступен.

Окончание следует…

Источник:
https://laurentkempe.com/2026/02/14/exploring-net-11-preview-1-runtime-async-a-dive-into-the-future-of-async-in-net/
2👍35
День 2575. #ЧтоНовенького #DotNet11
Асинхронность в Рантайме в превью 1 .NET 11. Окончание

Начало

Что изменилось в .NET 11 Preview 1
Асинхронность в Рантайме была доступна в виде экспериментальной функции в .NET 10, но требовала установки флагов в переменных среды. В .NET 11 превью 1:
- Поддержка CoreCLR включена по умолчанию
Больше не нужно устанавливать DOTNET_RuntimeAsync=1. Среда выполнения готова к выполнению асинхронных методов сразу после установки.
- Нативная поддержка AOT
Превью 1 включает базовую нативную поддержку AOT для асинхронных методов во время выполнения. Т.е. код, скомпилированный с runtime-async=on, теперь может быть предкомпилирован, включая поддержку продолжений и инфраструктуру для диагностики.

Как попробовать?
1. Установите целевую платформу на .NET 11:
<TargetFramework>net11.0</TargetFramework>


2. Включите функции предварительного просмотра и асинхронную компиляцию в файле .csproj:
<PropertyGroup>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<Features>$(Features);runtime-async=on</Features>
</PropertyGroup>


3. Пишите код, как обычно:
async Task<string> FetchDataAsync(
HttpClient client, string url)
{
var resp = await client.GetAsync(url);
resp.EnsureSuccessStatusCode();
return await resp.Content.ReadAsStringAsync();
}


При включенных асинхронных операциях в среде выполнения компилятор C# генерирует более простой IL-код без полноценного конечного автомата. Среда выполнения обрабатывает приостановку и возобновление выполнения нативно. Ваш исходный код при этом не меняется — улучшение заключается исключительно в способе компиляции и выполнения кода. Вот пример низкоуровневого кода C# для .NET 11:
[NullableContext(1)]
[CompilerGenerated]
[MethodImpl(MethodImplOptions.Async)]
internal static Task<string> <<Main>$>g__FetchDataAsync|0_0(HttpClient client, string url)
{
HttpResponseMessage httpResponseMessage = AsyncHelpers.Await<HttpResponseMessage>(client.GetAsync(url));
httpResponseMessage.EnsureSuccessStatusCode();
return (Task<string>) AsyncHelpers.Await<string>(httpResponseMessage.Content.ReadAsStringAsync());
}

Сгенерированный IL-код также значительно проще. Для сравнения, конечный автомат, генерируемый в .NET 10.

Что дальше?
В рамках задачи по асинхронной обработке в среде выполнения для .NET 11 осталось реализовать:
- Перекомпиляцию библиотек
Компиляция библиотек System.* и ASP.NET Core с поддержкой асинхронной обработки во время выполнения позволит добиться повышения производительности на уровне всей платформы.
- Улучшения диагностики
Улучшенное форматирование и вывод трассировки стека для асинхронных методов во время выполнения.
- Тестирование
Включение асинхронной компиляции во время выполнения для модульных тестов и библиотек во всей экосистеме.

После перекомпиляции и поставки основных библиотек с включенной асинхронной обработкой в среде выполнения, все преимущества в производительности — уменьшение выделений памяти, меньший размер состояния и оптимизированные цепочки асинхронных вызовов — должны стать измеримыми в реальных приложениях, таких как ASP.NET Core.

Источник: https://laurentkempe.com/2026/02/14/exploring-net-11-preview-1-runtime-async-a-dive-into-the-future-of-async-in-net/
👍21
День 2576. #МоиИнструменты #PostgresTips
Инструменты Оптимизации Запросов в PostgreSQL. Часть 1

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

Замечание: анализ инструментов основан на обширном тестировании в Snowflake, BigQuery, Postgres и Redshift по состоянию на февраль 2025 года. Улучшения производительности — это реальные измерения на производственных нагрузках, а не синтетические бенчмарки.

1. pgBadger (PostgreSQL Query Analyzer)
Что даёт: понимание, что на самом деле происходит в Postgres, не утопая в логах.

Зачем нужен:
Логи запросов PostgreSQL полны, но нечитаемы. Тысячи строк показывают время выполнения, планы и ошибки — но нет чёткого представления о том, что именно снижает производительность.
pgBadger преобразует чистые логи PostgreSQL в полезные HTML-отчеты, показывающие:
- Самые медленные запросы (с фактическим временем выполнения);
- Наиболее часто выполняемые запросы (цели оптимизации с высоким уровнем влияния);
- Запросы, вызывающие ошибки;
- Анализ ожидания блокировок;
- Использование временных файлов;
- Паттерны соединений.

До pgBadger (чистые логи):
2025-02-07 14:23:11 UTC [12345]: LOG:  duration: 45231.234 ms  statement: SELECT...
2025-02-07 14:23:56 UTC [12346]: LOG: duration: 123.456 ms statement: SELECT...

И так 50 тысяч строк. Не понятно, какие запросы важны.

С pgBadger (создание отчёта из логов):
pgbadger /var/log/postgresql/postgresql-*.log -o report.html

Создаёт красивый HTML-отчет, показывающий:
- 10 самых медленных запросов;
- Варианты быстрых решений.

Когда использовать
- Использование PostgreSQL в продакшене;
- Проблемы с производительностью, но неясно, в каких запросах;
- Необходим ретроспективный анализ паттернов запросов;
- Желание показать значимость оптимизации.

Когда отказаться
- Не производственная среда (есть альтернативы);
- Отладка отдельных запросов (используйте EXPLAIN);
- Необходим мониторинг в реальном времени (pgBadger - это пакетный анализ).

Скрытая функция
Инкрементальная генерация отчетов вместо обработки всего лога:
pgbadger --last-parsed /var/log/last_parsed.log \
/var/log/postgresql/postgresql-*.log \
-o incremental-report.html

- Анализирует только новые записи лога;
- В 100 раз быстрее для ежедневных отчётов;
- Идеальна для автоматического мониторинга.

Недостаток
Использование памяти pgBadger’ом возрастает с ростом размера лога.
Для больших логов (>10Гб) используйте сэмплинг:
# Анализируем 10% логов
pgbadger --sample 10 large_logfile.log

# Делим на временные отрезки
pgbadger --begin "2025-02-07 00:00:00" \
--end "2025-02-07 23:59:59" \
postgresql.log


Источник: https://medium.com/@reliabledataengineering/15-sql-optimization-tools-that-make-queries-10x-faster-8629ac451d97
👍8
День 2577. #Оффтоп #AI
Языковым Моделям Нужна Функция «Отметить как Ответ»

Современные LLM уже усвоили практически всю доступную информацию для построения своих моделей. Для дальнейшего совершенствования им потребуется искать дополнительные источники информации. Одним из очевидных таких источников является взаимодействие с пользователями. И важный аспект в этом - оценка качества. Как LLM узнает, привёл ли данный обмен сообщениями к решению? Без этих знаний LLM не сможет отдавать приоритет ответам, которые в итоге оказались более полезными.

Форумы и Stack Overflow
Некоторые из моих читателей достаточно стары, чтобы помнить времена до Stack Overflow. Тогда, когда у вас возникала проблема, вы вводили сообщение об ошибке в Google и надеялись, что кто-то уже сталкивался с этой проблемой. Форумы были основным источником ответов. Но даже если вы находили подходящую тему на форуме, часто приходилось пролистывать множество ответов, чтобы увидеть, решил ли кто-нибудь проблему. Иногда автор писал, что нашёл ответ, но не делился им. Одним из правильных решений Stack Overflow было предоставление возможности и стимулирование пользователей отмечать конкретный ответ как решение.

Так эффективность поиска и предоставления ответов значительно возросла. Люди могли быстро найти ответы, которые, скорее всего, сработали, поскольку они уже помогли кому-то другому с аналогичной проблемой. Эта функция в сочетании с геймификацией во многом способствовала полезности и популярности Stack Overflow. Также она превратила данные Stack Overflow в золотую жилу для ИИ-компаний, которые воспользовались политикой открытых данных Stack Overflow для обучения своих моделей на многолетних исторических данных вопросов и ответов. К сожалению, это и привело к гибели Stack Overflow.

Но без миллионов новых вопросов и ответов для обучения, откуда модели ИИ будут брать данные, которые им необходимы для предоставления релевантных и полезных ответов?

Новый источник данных
Очевидным источником данных являются собственно диалоги пользователей с существующими моделями. Эти диалоги представляют собой огромный объём информации, в основном текстовой, но они страдают от той же проблемы, что и ранние форумы: каков был результат?

Подумайте о типичном диалоге с чат-ботом. Вы задаёте вопрос, он даёт ответ. Иногда он полезен, иногда нет. Иногда приходится перефразировать первоначальный вопрос, добавить контекст, уточнить. Или вы задаёте совершенно несвязанный вопрос в том же чате, потому что… а почему бы и нет? Чат-бот не скажет, что это «не по теме» — он с удовольствием ответит на любой ваш вопрос.

Теперь представьте, что вам поручено определить, какие ответы чат-бота были наиболее полезными. Конечно, иногда пользователи помогают и пишут в чат: «Спасибо, это работало!» или «Нет, это не то, что мне нужно». Но чаще всего они просто закрывают сессию или задают другой вопрос, независимо от того, решили они проблему или просто сдались.

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

Итого
ИИ-агентам необходимо будет обучаться на основе своих диалогов с пользователями, чтобы продолжать учиться. Однако, если это делать без явных данных, указывающих на то, решил ли данный ответ данную проблему, будет очень сложно определить, каким ответам следует придавать больший вес, чем другим. Добавление механизма, аналогичного функции «отметить как ответ» на Stack Overflow, к взаимодействиям с LLM обеспечит этот сигнал и позволит в будущем обучать модели на ответах с большим весом, что со временем повысит полезность модели.

Источник:
https://ardalis.com/llms-need-mark-as-answer/
👍10
День 2578. #Карьера
Топ Советов по Повышению Продуктивности. Часть 9. Начало

Части 1, 2, 3, 4, 5, 6, 7, 8

9. Объединяйте задачи по контексту
Вы в состоянии потока глубоко погружены в реализацию сложной функции, добиваетесь реального прогресса. Вдруг – уведомление: кому-то нужна проверка кода. Вы переключаетесь, тратите 15 минут на проверку и возвращаетесь к своей функции. Но теперь требуется ещё 15 минут, чтобы вспомнить, где вы были и о чём думали. К 17:00 вы написали код, проверили три PR, посетили две встречи, ответили на дюжину сообщений, исправили ошибку в рабочей версии и обновили документацию. Вы были заняты весь день. А та функция, которую вы начали в 10 утра? Все ещё не закончена. Вы продвинулись в 12 задачах и не закончили главной.

Это проблема переключения контекста. Мозг — не компьютер. Невозможно мгновенно переключаться между разными типами мышления без затрат. Каждое переключение требует времени.

Решение: объединяйте похожие задачи в пакеты.

1. Пакет на день (для смелых)
Если у вас достаточно контроля над своим расписанием, попробуйте структурировать целые дни:
- Понедельник: Планирование и архитектура. Сессии по проектированию. Написание технических спецификаций. Мышление в масштабе системы.
- Вторник/Среда: Дни глубокой работы. Реализация функций. Решение сложных проблем. Минимум встреч.
- Четверг: День сотрудничества. Проверки кода. Парное программирование. Обсуждения в команде.
- Пятница: Уборка и обучение. Написание документации. Рефакторинг. Изучение новых инструментов. Планирование следующей недели.
Звучит жёстко, но это раскрепощает. Во вторник, вы знаете, что будете писать код весь день. Никакой неопределённости. Никакой усталости от принятия решений о том, чему отдать приоритет.

2. Пакет на полдня (более реалистично)
- Утро: Глубокая работа. Сложные когнитивные задачи. Никаких совещаний. Никаких мессенджеров.
- День: Совместная работа. Совещания, проверки кода, обсуждения, административная работа.
У большинства людей мозг работает наиболее эффективно утром. Используйте это время для сложных задач. Более лёгкую, требующую общения работу оставьте на то время, когда мозг будет менее активен.

3. Деление по часам (наименее эффективно для пакетной обработки задач)
Если вы не можете контролировать большие блоки, объединяйте задачи по часам:
- 9-10: проверка сообщений.
- 10-12: работа над новыми функциями. Мессенджеры в режиме «не беспокоить». Полная концентрация.
- 12-13 часов: обед и проверки кода.
- 13-14: встречи (если неизбежны).
- 14-16: работа над функциями, второй этап.
- 16-17: подведение итогов, планирование завтрашнего дня, организационные вопросы.

Магия пакетной обработки похожих задач
- Проверка кода
Не проверяйте один PR каждые два часа в течение всего дня. Выделите 30-60 минут и проверьте все ожидающие PR одновременно. Вы остаётесь в «режиме проверки» — критическом мышлении, поиске закономерностей, проверке граничных случаев. Каждая проверка проходит быстрее и эффективнее.
- Встречи
Старайтесь группировать их. Совещания одно за другим утомительны, но менее разрушительны, чем разбросанные по всему дню.
- Коммуникации
Установите время для проверки сообщений. Вне этих временных промежутков закрывайте приложения. Вы не пропустите настоящие ЧП (вас найдут), но избежите постоянного потока отвлекающих факторов.
- Небольшие задачи
Составьте список быстрых задач. Объедините их в группы. Уделяйте 30 минут один или два раза в неделю очистке списка.
- Обучение
Выделите специальное время, когда вы целенаправленно изучаете новые инструменты, читаете документацию, смотрите обучающие видео или экспериментируете с новыми методами.

Окончание следует…

Источник:
https://dev.to/thebitforge/top-10-productivity-hacks-every-developer-should-know-151h
👍7
День 2579. #Карьера
Топ Советов по Повышению Продуктивности. Часть 9. Окончание

Начало

Как защитить время, отведённое на пакетную работу
1. Чётко обозначьте границы
Обновите статус в мессенджере «🧠 Глубокая работа до полудня». Заблокируйте время в календаре. Договоритесь с командой, что определённое время защищено.
2. Создайте препятствия для отвлечений
Закройте мессенджеры. Отключите уведомления. Уберите телефон в другую комнату. Используйте блокировщики веб-сайтов, если необходимо. Сделайте так, чтобы вас было сложнее отвлечь.
3. Проактивно общайтесь
Расскажите команде о системе пакетной работы. «Я провожу проверку кода с 13 до 16. Если это срочно, пишите мне напрямую». Большинство людей уважают чёткие ожидания.
4. Отслеживайте и совершенствуйтесь
Заметьте, когда вы наиболее продуктивны. Вы «жаворонок» или «сова»? Когда совещания вас больше всего истощают? Когда вы лучше всего работаете «в потоке»? Разрабатывайте свою пакетную работу, исходя из ваших естественных ритмов, а не из какого-то идеального расписания, которое, как вам кажется, у вас должно быть.

Эффект накопления
Пакетная работа — не попытка втиснуть больше работы в меньшее время. Это возможность выполнять более качественную работу с меньшим умственным истощением.

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

При пакетной проверке кода вы начинаете замечать закономерности в PR. «О, 3 человека допустили одну и ту же неточность в обработке ошибок — нужно обновить документацию». Это понимание появляется только тогда, когда вы видите несколько PR подряд.

Начните с малого
Не нужно перестраивать всю свою неделю завтра. Выберите одну стратегию пакетной работы:
- Объедините все проверки кода в два окна в день;
- Выделите первые два часа дня для глубокой работы;
- Проверяйте мессенджеры только в запланированное время;
- Выделите пятничные вечера как время для обучения/уборки.
Попробуйте в течение пары недель. Заметьте разницу. Затем добавьте ещё одну стратегию пакетной работы.

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

Лучшие разработчики не доступны 24/7. Они обдуманно выбирают, когда и для чего они доступны. Они бережно относятся к своему вниманию, как к дефицитному ресурсу. Пакетная работа — это их способ достижения цели.

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

23. Проверки кода и парное программирование
«Опишите преимущества проверок кода и парного программирования в команде разработчиков. Как вы применяли эти методы в прошлых проектах?»

Хороший ответ
Практики проверок кода и парного программирования помогают улучшить качество ПО и навыки членов команды в любой команде разработчиков.

Проверка кода включает в себя изучение одним или несколькими разработчиками кода, написанного другим разработчиком.
Преимущества:
- Улучшение качества: помогает выявлять ошибки и проектные недочёты до этапа интеграции кода, что приводит к более стабильным релизам.
- Обмен знаниями: способствует распространению знаний о кодовой базе и стандартах кодирования внутри команды, что имеет решающее значение для адаптации новых членов команды.
- Улучшение командного взаимодействия: регулярные проверки кода создают культуру коллективного владения кодом и ответственности.
Например, мы использовали Azure DevOps и практику пул-реквестов (PR) как обязательный шаг для слияния кода в основную ветку. Каждый PR запускал автоматическую сборку и должен был быть проверен как минимум двумя другими членами команды. Это гарантировало, что ни один код не попадал в производство без тщательной проверки командой.

Парное программирование — метод, при котором два разработчика работают вместе за одной рабочей станцией; один пишет код (драйвер), а другой проверяет каждую строку кода по мере её ввода (навигатор).
Преимущества:
- Немедленная обратная связь по написанному коду, что ускоряет процесс обучения и повышает качество кода.
- Эффективность в решении проблем: два человека, работающие над одной и той же проблемой, как правило, решают её быстрее и креативнее, чем один.
- Повышение квалификации: начинающие разработчики могут быстро учиться у более опытных коллег, сокращая общую кривую обучения и повышая компетентность команды.
В одном проекте мы регулярно проводили сессии парного программирования, особенно при работе над сложными подсистемами приложения. Это не только ускорило разработку, но и обеспечило более высокое качество получаемого ПО.

Внедрение этих практик требует поддерживающей культуры, которая ценит качество и сотрудничество выше показателей индивидуальной продуктивности.

Рекомендация: Очевидно, если вы никогда не использовали эти методы, не говорите, что использовали! Будьте честны, опишите основные концепции этих методов и скажите, что хотели бы сами попробовать их на практике.

Часто встречающийся плохой ответ
«Проверка кода и парное программирование слишком трудоёмки и уменьшают объём кода, который может создать каждый разработчик. Лучше сосредоточиться на индивидуальной работе, чтобы максимизировать результат».

Почему это неправильно:
- Неправильное понимание продуктивности: ответ путает чистый результат с продуктивным результатом. Хотя индивидуальное программирование может создавать больший объём кода, это не обязательно приводит к повышению качества или улучшению поддерживаемости, которые снижают затраты на обслуживание и уменьшают количество ошибок в будущем.

- Краткосрочная перспектива: хотя эти методы могут замедлить начальные этапы кодирования, они экономят время на сопровождении кода и отладке на более поздних стадиях.

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

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

Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
👎6👍2
День 2581. #МоиИнструменты #PG
Инструменты Оптимизации Запросов в PostgreSQL. Часть 2

2. Анализатор производительности БД (DPA) SolarWinds
Что даёт: Мониторинг производительности запросов к различным базам данных в одном унифицированном интерфейсе.
Тип: Коммерческий (доступна бесплатная пробная версия)
Базы данных: Postgres, MySQL, Oracle, SQL Server, MongoDB
Зачем нужен: Большинство компаний используют несколько БД. Postgres для транзакционных операций, MySQL для устаревших приложений, Redshift для аналитики. Для каждой из них существуют разные инструменты мониторинга. DPA обеспечивает унифицированный мониторинг производительности для всех из них.
Главная особенность: анализ времени ожидания. Вместо того чтобы просто показывать медленные запросы, DPA показывает почему они медленные — ожидание блокировок, дисковый ввод-вывод, ЦП, сеть и т. д.

Что показывает
Query: SELECT * FROM orders WHERE customer_id = ?
Total time: 12.5 seconds
Breakdown:
- CPU time: 0.3s (2%)
- Lock wait: 11.8s (94%) ← Проблема тут
- I/O wait: 0.2s (2%)
- Network: 0.2s (2%)
Action: Investigate lock contention, not query optimization
(Решение: Исследуйте конфликты блокировок, а не оптимизацию запросов.)


Когда использовать
- Многобазовая среда;
- Бюджет на коммерческие инструменты ($1500-5000 в год на БД);
- Необходима корреляция между базами данных;
- Требуется анализ исторических тенденций.

Когда отказаться
- Одна БД (pgBadger или специализированные под БД инструменты дешевле);
- Ограниченный бюджет;
- Необходимо профилирование на уровне кода (DPA ориентирован на уровень запросов).

Скрытая функция
Обнаружение аномалий без настройки. DPA автоматически изучает шаблоны поведения:
- Typical query response time: 2.3s ±0.5s
(Типичное время ответа на запрос: 2,3с ±0,5с)
- Today's execution: 8.7s
(Время выполнения сегодня: 8,7с)
- Alert: Query degraded 3.7x from baseline
(Предупреждение: Скорость выполнения запроса снизилась в 3,7 раза по сравнению с базовым уровнем).

Не требуется ручная настройка порогового значения.
Снижает усталость от оповещений.

С осторожностью
Реальные накладные расходы агента DPA:
- ЦП: +2-5% на сервере БД;
- Память: ~500 МБ на каждый отслеживаемый экземпляр;
- Сеть: ~10-50 Мбит/с телеметрии.

Для высоконагруженной производственной среды:
- Запускайте агент на отдельном сервере;
- Используйте выборочный мониторинг (отслеживайте 10% запросов);
- Настройте частоту сбора данных.

Источник: https://medium.com/@reliabledataengineering/15-sql-optimization-tools-that-make-queries-10x-faster-8629ac451d97
👎5👍1
День 2582. #ЧтоНовенького #NET11
Вышла Превью 1 .NET 11. Начало
Команда Microsoft .NET выпустила первую предварительную версию .NET 11. Про главную особенность превью – асинхронную обработку в среде выполнения – я уже писал. Теперь рассмотрим другие важные новинки.

Библиотеки
1. Добавлена нативная поддержка сжатия Zstandard (zstd) благодаря новому классу ZstandardStream. Zstandard обеспечивает значительно более быстрое сжатие и распаковку по сравнению с существующими алгоритмами, сохраняя при этом конкурентоспособные коэффициенты сжатия. Новые API включают полный набор возможностей потокового, однократного и словарного сжатия и распаковки.
// Сжатие с ZstandardStream
using var compressStream =
new ZstandardStream(outputStream, CompressionMode.Compress);
await inputStream.CopyToAsync(compressStream);

// Распаковка
using var decompressStream
= new ZstandardStream(inputStream, CompressionMode.Decompress);
await decompressStream.CopyToAsync(outputStream);


2. В ZipArchiveEntry добавлены:
- параметр FileAccess, позволяющий указать, тип доступа к открываемому файлу FileAccess.Read или FileAccess.Write;
- свойство CompressionMethod в ZipArchiveEntry типа перечисления ZipCompressionMethod, позволяющее приложениям определять алгоритм сжатия для каждой записи.

3. Добавлены аргументы выражений коллекций с ключевым словом with и поддержка выражений коллекций для FrozenDictionary:
FrozenDictionary<string, int> lookup = 
[with(StringComparer.Ordinal), "one":1, "two":2, "three":3];


4. Поддержка рун в String, StringBuilder и TextWriter
System.Text.Rune теперь можно использовать гораздо шире. Это значительно упрощает корректную работу приложений с текстом Unicode, особенно для символов, находящихся за пределами базовой многоязычной плоскости, которые требуют суррогатных пар при представлении в виде символов:
var s = "Hello 🌍";
var glb = new Rune(0x1F30D); // 🌍

s.Contains(glb); // true
s.IndexOf(glb); // 6
s.StartsWith(glb); // false
s.Replace(glb, new Rune('X')); // "Hello X"


5. Помощник по MIME-типам System.Net.Mime.MediaTypeMap

6. API для проверки HMAC и KMAC
Добавлены методы Verify ко всем классам HMAC и KMAC. Значения HMAC часто необходимо сравнивать за фиксированное время, чтобы предотвратить атаки по времени. Ранее это требовало двух шагов: вычисления HMAC с помощью HashData, а затем сравнения с помощью CryptographicOperations.FixedTimeEquals. Новые методы Verify объединяют оба этапа в один безопасный вызов.

7. DivisionRounding для целочисленного деления
Добавлена поддержка альтернативных режимов округления при целочисленном делении с помощью нового перечисления DivisionRounding и новых методов в IBinaryInteger<T>: Divide, DivRem и Remainder. Большинство аппаратных средств реализуют деление нацело (/ и % в C#), но разные языки и предметные области требуют округления до большего или меньшего целого числа, евклидова округления или округления от нуля. Хотя это довольно тривиально, новые API позволяют выбрать правильный режим и хорошо оптимизированную реализацию:
int truncated = 
int.Divide(-7, 2, DivisionRounding.Truncate); // -3

int floored =
int.Divide(-7, 2, DivisionRounding.Floor); // -4

// всегда неотрицательный
int euclideanRem =
int.Remainder(-7, 3, DivisionRounding.Euclidean); // 2

// Получаем частное и остаток сразу
var (q, r) =
int.DivRem(-7, 2, DivisionRounding.Floor); // q=-4, r=1


Окончание следует…

Источник:
https://github.com/dotnet/core/tree/main/release-notes/11.0/preview/preview1
1👍5
День 2583. #ЧтоНовенького #NET11
Вышла Превью 1 .NET 11. Окончание

Начало

.NET MAUI
1. Генерация исходного кода XAML по умолчанию в .NET MAUI. Чтобы вернуться к XAMLC, нужно добавить в файл проекта:
<PropertyGroup>
<MauiXamlInflator>XamlC</MauiXamlInflator>
</PropertyGroup>


2. CoreCLR в качестве среды выполнения Android по умолчанию для релизных сборок. Это должно улучшить совместимость с остальными компонентами .NET, а также сократить время запуска при разумном увеличении размера приложения. Чтобы вернуться к Mono:
<PropertyGroup>
<UseMonoRuntime>true</UseMonoRuntime>
</ProperyGroup>


3. Интерактивный выбор целевой платформы и устройства для dotnet run. Теперь после запуска в консоли вам будет предложен выбор целевой платформы или устройства/эмулятора (если их несколько).

Blazor
1. Новый компонент EnvironmentBoundary позволяет осуществлять условный рендеринг в зависимости от среды хостинга, аналогично тег-хелперу environment в MVC:
<EnvironmentBoundary Include="Development,Staging">
<p>Pre-production environment</p>
</EnvironmentBoundary>


2. Blazor WebAssembly теперь поддерживает IHostedService для запуска фоновых сервисов в браузере и может получать доступ к переменным среды через IConfiguration для настройки во время выполнения без пересборки приложения.

3. Фреймворк также добавляет новые компоненты Label и DisplayName для форм. Они будут отображать значения из атрибутов [Display] или [DisplayName] свойства:
<Label For="() => model.Name" />


4. Добавлено событие щелчка по строкам в QuickGrid.

5. Относительная навигация в NavigationManager.NavigateTo() и NavLink с помощью опции RelativeToCurrentUri="true".

6. Шаблон проекта Blazor Web App теперь поддерживает опцию «Добавить поддержку контейнеризации» в Visual Studio.

ASP.NET Core
1. OpenAPI для конечных точек, возвращающих FileContentResult, теперь будет генерировать соответствующую документацию схемы:
FileContentResult:
type: string
format: binary


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

3. Сертификаты разработчика в средах WSL теперь автоматически считаются доверенными как в WSL, так и в Windows.

Источник: https://github.com/dotnet/core/tree/main/release-notes/11.0/preview/preview1
1👍5
День 2584. #Карьера
Коллега Сказал Мне, что Мой Код «Уровня Джуна». Начало
47 комментариев. Я посчитал дважды, потому что сначала подумал, что что-то пошло не так. Может глюк утилиты сравнения? Но нет.

Знаете чувство, когда ты только что выпустил что-то, чем искренне гордишься. Я отправил PR, ожидая… ну, не знаю… пару придирок. Вместо этого я получил бесконечный документ с комментариями. Каждый комментарий — небольшой, точечный удар. А внизу, от инженера, которого я никогда не встречал, фраза, которая перевернула что-то внутри меня: «Это похоже на код джуна».

Я закрыл ноутбук, прогулялся вокруг квартала… дважды… Тот момент, когда обратная связь перестаёт касаться вашей работы и начинает ощущаться как касающаяся вас. Инстинкт срабатывает быстро. Отвергать. Защищаться. Обновить резюме.

Чего я тогда не понимал, но понимаю сейчас: самые болезненные отзывы часто несут в себе самый сильный сигнал. Не потому, что резкость — это хорошо. Но тот, кто готов быть настолько прямолинейным, обычно указывает на реальные проблемы, которых я не замечал.

PR, которым я гордился
Я работал уже 5 лет без нареканий. Получил уверенность, которая появляется, когда то, что вы выпускаете, в целом работает, и на вас никто не орёт. PR представлял собой рефакторинг конвейера данных. Около 800 строк в шести файлах. Тесты пройдены. Производительность улучшена. Я даже добавил подробные комментарии, что (как мне казалось) свидетельствовало о зрелости. В моей голове такой PR одобряют без лишних проблем, может быть, с небольшим комплиментом. Вместо этого я получил мастер-класс по всему, чего я не знал, что не знаю.

Коллега не указывал на ошибки. Он указывал на огрехи мышления. Паттерны, которые работали, но не выдержали бы контакта с реальностью. Абстракции, которые решали сегодняшнюю проблему, тихо закладывая основу для завтрашней.

Одна функция одновременно обрабатывала валидацию и преобразование. «Это разные обязанности», — написал коллега. «Когда требования изменятся, а они изменятся, ты потратишь дни на то, чтобы разобраться в этом».

Я написал умный код. Компактный. Гордился его плотностью. «Мне пришлось перечитывать это три раза», — один из комментариев. «Умно — значит дорого. Ясность — вот в чём ценность».

Моя обработка ошибок была оптимистической. Счастливый путь сиял, несчастливые пути были запутанными и несогласованными. «В проде в основном несчастливые пути. Твой код этого ещё не знает».

Моей первой реакцией было то, что коллега придирался. Код работал. Почему гипотетические будущие проблемы перевешивали текущую функциональность? Позже я понял, что эта реакция была именно тем пробелом, на который он указывал.

Я думал, что сеньор — это решение более сложных проблем. Более сложные алгоритмы и архитектуры. Это не так. Работа опытного инженера заключается в решении проблем таким образом, чтобы не создавать новых. Код, который выдерживает взаимодействие с коллегами, меняющиеся требования, инциденты в 2 часа ночи и вашу забывчивость. Речь идёт не о том, чтобы быть умным, а о том, чтобы быть внимательным к будущему.

На практике для меня это было неочевидно. Я оптимизировал код, ориентируясь на «работает ли это», вместо того чтобы оптимизировать его на «что произойдёт, когда это сломается».

Окончание следует…

Источник:
https://medium.com/beyond-localhost/a-google-staff-engineer-told-me-my-code-was-junior-level-he-was-right-69ba2f80b7d3
👍37👎2