public const Price = OldPrice; // до 20.01Мы меняем значение константы: завтра обучение станет дороже. Успейте пробросить заказ сегодня, чтобы зафиксировать текущую стоимость в своём стеке.
Инициализировать рост компетенций
🥱2👍1
🚀 Одна строка кода для ускорения EF Core
Когда EF Core загружает связанные сущности через
Пример:
При 100 постах, у каждого по 10 комментариев, в каждом по 10 реакций — вместо 11 100 записей получаем результирующий набор на 10 000 строк.
Добавьте
Query Splitting — это не хак и не костыль. Это правильный способ работы с EF Core в read-heavy сценариях.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
Когда EF Core загружает связанные сущности через
Include(), он генерирует один огромный SQL-запрос с множеством JOIN. Результат? Тысячи дублирующихся строк, гигабайты трафика и медленная работа.Пример:
var posts = await context.Posts
.Include(p => p.Comments)
.ThenInclude(c => c.Reactions)
.ToListAsync();
При 100 постах, у каждого по 10 комментариев, в каждом по 10 реакций — вместо 11 100 записей получаем результирующий набор на 10 000 строк.
Добавьте
.AsSplitQuery() — и EF Core разобьёт один большой запрос на несколько маленьких:var posts = await context.Posts
.AsSplitQuery() // ← магия здесь
.Include(p => p.Comments)
.ThenInclude(c => c.Reactions)
.ToListAsync();
Query Splitting — это не хак и не костыль. Это правильный способ работы с EF Core в read-heavy сценариях.
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21❤1😁1
🛠 Parallel.For — когда циклы работают параллельно
Представьте: у вас есть массив из миллиона элементов, и каждый нужно обработать. Обычный цикл for будет делать это последовательно — один элемент за другим. А что если задействовать все ядра процессора?
Базовое использование:
Вот и всё. Task Parallel Library сам распределит работу по потокам, сам управляет ThreadPool, сам балансирует нагрузку.
Когда это имеет смысл:
+ Обработка изображений, видео
+ Математические вычисления
+ Парсинг больших объёмов данных
+ Криптографические операции
Не подходит:
- Обработка меньше 100 элементов
- Операции с базой данных или API
- Быстрые операции вроде i * 2
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
Представьте: у вас есть массив из миллиона элементов, и каждый нужно обработать. Обычный цикл for будет делать это последовательно — один элемент за другим. А что если задействовать все ядра процессора?
Базовое использование:
// Было
for (int i = 0; i < 1000; i++)
{
ProcessImage(images[i]);
}
// Стало
Parallel.For(0, 1000, i =>
{
ProcessImage(images[i]);
});
Вот и всё. Task Parallel Library сам распределит работу по потокам, сам управляет ThreadPool, сам балансирует нагрузку.
Когда это имеет смысл:
+ Обработка изображений, видео
+ Математические вычисления
+ Парсинг больших объёмов данных
+ Криптографические операции
Не подходит:
- Обработка меньше 100 элементов
- Операции с базой данных или API
- Быстрые операции вроде i * 2
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15🥱2
👍 JIT .NET 10 убирает абстракции почти бесплатно
В .NET 10 Microsoft сильно доработали JIT компилятор. Цель простая сделать так, чтобы привычный высокоуровневый С# код работал почти как вручную вылизанный низкоуровневый.
Главная идея обновления JIT убрать лишнюю цену за высокоуровневые конструкции. Раньше интерфейсы, делегаты, итераторы легко приносили дополнительные аллокации и лишнюю индирекцию, сейчас JIT старается пробиться сквозь них к конкретным типам и генерировать более плотный машинный код.
Ключевой механизм это улучшенный escape analysis. Если JIT может доказать, что объект живет только внутри метода не передается наружу и не сохраняется в поля, он размещает его на стеке.
Пример:
В старой версии платформы такой код почти гарантировал лишнюю аллокацию делегата и замыкания в куче.
По сути JIT делает за разработчика ту оптимизацию которую раньше приходилось реализовывать вручную через отказ от лямбд и делегатов на горячем пути.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
В .NET 10 Microsoft сильно доработали JIT компилятор. Цель простая сделать так, чтобы привычный высокоуровневый С# код работал почти как вручную вылизанный низкоуровневый.
Главная идея обновления JIT убрать лишнюю цену за высокоуровневые конструкции. Раньше интерфейсы, делегаты, итераторы легко приносили дополнительные аллокации и лишнюю индирекцию, сейчас JIT старается пробиться сквозь них к конкретным типам и генерировать более плотный машинный код.
Ключевой механизм это улучшенный escape analysis. Если JIT может доказать, что объект живет только внутри метода не передается наружу и не сохраняется в поля, он размещает его на стеке.
Пример:
[Benchmark]
[Arguments(42)]
public int SumWithOffset(int offset)
{
Func<int, int> addOffset = value => value + offset;
return ApplyTwice(addOffset, offset);
}
В старой версии платформы такой код почти гарантировал лишнюю аллокацию делегата и замыкания в куче.
По сути JIT делает за разработчика ту оптимизацию которую раньше приходилось реализовывать вручную через отказ от лямбд и делегатов на горячем пути.
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29
Сделаем минимальный код для чтения таблиц для конвертации в JSON.
Подключите NuGet-пакеты
FreeSpire.XLS и Newtonsoft.Json. Первая читает .xlsx без зависимостей, вторая формирует JSON.Код начинается с загрузки файла в поток. Библиотека преобразует лист в DataSet, где строки становятся объектами. Первая строка служит заголовками полей.
Чтение и конвертация данных:
using Spire.Xls;
using Newtonsoft.Json;
Workbook wb = new Workbook();
wb.LoadFromFile("данные.xlsx");
DataTable таблица = wb.Worksheets.ExportDataTable();
JsonSerializerSettings опции = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore
};
string результат = JsonConvert.SerializeObject(таблица, опции);
File.WriteAllText("выход.json", результат);
Игнорируйте null для компактности. Форматируйте даты единообразно. Тестируйте на реальных данных — библиотека FreeSpire.XLS ограничена объемом, но достаточна для большинства случаев.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🥱2
🧬 Мутационное тестирование
Вы пишете unit-тесты, coverage показывает 80-90%, но уверены ли вы, что эти тесты реально ловят баги? Мутационное тестирование помогает проверить качество самих тестов.
Суть подхода
Инструмент автоматически вносит небольшие изменения в ваш код: меняет операторы, условия, константы. Если тесты проходят с «поломанным» кодом — значит, они недостаточно строгие.
Stryker.NET в действии
Установка занимает пару минут через
• Какие мутации выжили
• Mutation Score — процент убитых мутантов
• Конкретные строки кода, где тесты слабые
Практический пример
Допустим, у вас метод проверяет возраст пользователя. Stryker меняет
Stryker умеет работать с xUnit, NUnit, MSTest. Настраивается через JSON-файл, где можно указать пороговые значения mutation score, исключить файлы из анализа, настроить уровни логирования.
Процесс требует времени — каждая мутация прогоняет весь набор тестов. Но результат того стоит: вы находите слепые зоны в тестовом покрытии, которые обычный coverage не показывает.
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
Вы пишете unit-тесты, coverage показывает 80-90%, но уверены ли вы, что эти тесты реально ловят баги? Мутационное тестирование помогает проверить качество самих тестов.
Суть подхода
Инструмент автоматически вносит небольшие изменения в ваш код: меняет операторы, условия, константы. Если тесты проходят с «поломанным» кодом — значит, они недостаточно строгие.
Stryker.NET в действии
Установка занимает пару минут через
dotnet tool. После запуска Stryker анализирует код, создаёт мутантов и прогоняет по ним тесты. В отчёте вы видите:• Какие мутации выжили
• Mutation Score — процент убитых мутантов
• Конкретные строки кода, где тесты слабые
Практический пример
Допустим, у вас метод проверяет возраст пользователя. Stryker меняет
age >= 18 на age > 18. Если тест с граничным значением 18 отсутствует — мутант выживает, и вы понимаете, где дописать проверку.Stryker умеет работать с xUnit, NUnit, MSTest. Настраивается через JSON-файл, где можно указать пороговые значения mutation score, исключить файлы из анализа, настроить уровни логирования.
Процесс требует времени — каждая мутация прогоняет весь набор тестов. Но результат того стоит: вы находите слепые зоны в тестовом покрытии, которые обычный coverage не показывает.
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14🤔3
🔄 NBomber 6.2.0: фильтрация метрик, OpenTelemetry и улучшенные отчёты
NBomber — это фреймворк для распределённого нагрузочного тестирования в .NET. Вы пишете сценарии на обычном C# или F#, тестируете любые системы независимо от протокола и модели взаимодействия.
Что нового в версии 6.2.0:
Теперь можно фильтровать метрики по имени — полезно, когда у вас десятки показателей. На графике Throughput отображается Fail RPS, так что проблемы видны сразу.
Кластерный режим теперь настраивается через CLI без JSON-конфига. Можно указать целевые сценарии, а группы агентов стали опциональными.
Реализована интеграция с OpenTelemetry — теперь метрики можно отправлять в стандартные системы мониторинга.
➡️ Релиз на GitHub
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#async_news
NBomber — это фреймворк для распределённого нагрузочного тестирования в .NET. Вы пишете сценарии на обычном C# или F#, тестируете любые системы независимо от протокола и модели взаимодействия.
Что нового в версии 6.2.0:
Теперь можно фильтровать метрики по имени — полезно, когда у вас десятки показателей. На графике Throughput отображается Fail RPS, так что проблемы видны сразу.
Кластерный режим теперь настраивается через CLI без JSON-конфига. Можно указать целевые сценарии, а группы агентов стали опциональными.
Реализована интеграция с OpenTelemetry — теперь метрики можно отправлять в стандартные системы мониторинга.
📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤3
This media is not supported in your browser
VIEW IN TELEGRAM
😁3❤1
Интеграция LLM в .NET: подходы RAG и Fine-tuning
23 января в 19:00 обсудим создание интеллектуальных ассистентов на открытом уроке к курсу «Разработка ИИ агентов». Разберём, как реализовать контекстный поиск по вашим документам и когда стоит прибегать к дообучению моделей.
Спикер — Игорь Стурейко, тимлид в «Газпроме» и эксперт с 20-летним опытом в ML. Игорь подготовил видеосообщение, в котором рассказывает о переходе от чат-ботов к автономным агентам и архитектуре будущей программы.
Ключевые темы:
— использование
— фреймворки уровня
— работа с хранилищами векторных эмбеддингов (
📅 Когда: 23.01 в 19:00 МСК
Узнать подробности
23 января в 19:00 обсудим создание интеллектуальных ассистентов на открытом уроке к курсу «Разработка ИИ агентов». Разберём, как реализовать контекстный поиск по вашим документам и когда стоит прибегать к дообучению моделей.
Спикер — Игорь Стурейко, тимлид в «Газпроме» и эксперт с 20-летним опытом в ML. Игорь подготовил видеосообщение, в котором рассказывает о переходе от чат-ботов к автономным агентам и архитектуре будущей программы.
Ключевые темы:
— использование
RAG для ответов по внутренней документации;— фреймворки уровня
LangChain и LlamaIndex в Enterprise-среде;— работа с хранилищами векторных эмбеддингов (
FAISS, Chroma).📅 Когда: 23.01 в 19:00 МСК
Узнать подробности
🤔1
C# Developer — удалёнка в Ростиксе.
.NET разработчик — долларовая удалёнка.
Senior Unity Developer Teamlead — до 400 000 ₽ на гибрид в Москву.
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🗑 Soft Delete в базах данных
Многие проекты добавляют в таблицы колонку deleted или archived_at, чтобы не удалять данные окончательно. Звучит удобно: пользователь случайно что-то удалил — можно восстановить. Но на практике это создаёт массу проблем.
Основные проблемы классического подхода
Мёртвые данные в живых таблицах. 99% архивных записей никогда не будут прочитаны, но они постоянно болтаются рядом с актуальными данными.
Каждый запрос должен фильтровать
Создание записи затрагивает внешние системы. Восстановление может требовать сложной логики, которая всегда будет неполной копией API создания. Старые данные могут не пройти новые правила валидации.
Альтернативные подходы
• Архивирование на уровне приложения
При удалении записи приложение отправляет событие в очередь, а отдельный сервис сохраняет архивные данные в другом месте.
Плюсы: основная БД остаётся простой, удаление асинхронное (быстрее и надёжнее), данные можно сериализовать в удобном формате.
Минусы: легко допустить баг и потерять архивные данные, больше инфраструктуры, сложнее искать записи для восстановления.
• Триггеры PostgreSQL
Создаём универсальную таблицу archive, которая хранит JSON-представление удалённых записей:
Триггер автоматически копирует удаляемую строку в архив. Можно даже отслеживать каскадные удаления через session variables.
• Реплика без DELETE
Держать логическую реплику, которая игнорирует DELETE-запросы или превращает их в archived_at.
➡️ Источник
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
Многие проекты добавляют в таблицы колонку deleted или archived_at, чтобы не удалять данные окончательно. Звучит удобно: пользователь случайно что-то удалил — можно восстановить. Но на практике это создаёт массу проблем.
Основные проблемы классического подхода
Мёртвые данные в живых таблицах. 99% архивных записей никогда не будут прочитаны, но они постоянно болтаются рядом с актуальными данными.
Каждый запрос должен фильтровать
WHERE archived_at IS NULL. Индексы раздуваются. Миграции данных становятся сложнее — надо ли обрабатывать записи двухлетней давности? Всегда есть риск, что архивные данные случайно попадут туда, где их быть не должно.Создание записи затрагивает внешние системы. Восстановление может требовать сложной логики, которая всегда будет неполной копией API создания. Старые данные могут не пройти новые правила валидации.
Альтернативные подходы
• Архивирование на уровне приложения
При удалении записи приложение отправляет событие в очередь, а отдельный сервис сохраняет архивные данные в другом месте.
Плюсы: основная БД остаётся простой, удаление асинхронное (быстрее и надёжнее), данные можно сериализовать в удобном формате.
Минусы: легко допустить баг и потерять архивные данные, больше инфраструктуры, сложнее искать записи для восстановления.
• Триггеры PostgreSQL
Создаём универсальную таблицу archive, которая хранит JSON-представление удалённых записей:
CREATE TABLE archive (
id UUID PRIMARY KEY,
table_name TEXT NOT NULL,
record_id TEXT NOT NULL,
data JSONB NOT NULL,
archived_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Триггер автоматически копирует удаляемую строку в архив. Можно даже отслеживать каскадные удаления через session variables.
• Реплика без DELETE
Держать логическую реплику, которая игнорирует DELETE-запросы или превращает их в archived_at.
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥3😁3