👨💻Задачи точного покрытия — фундамент для многих алгоритмических подходов. Но пока теория лежит на полке, она мало что меняет в вашем инженерном мышлении
На открытом уроке мы разберем Dancing Links через практику: соберем пентамино на столе, представим фигуры в виде строк матрицы и разберемся, как работает поиск с возвратом. Когда алгоритм становится наглядным, вы начинаете понимать, что на самом деле происходит внутри.
Если вы хотите развивать алгоритмическое мышление, системно улучшать свои решения и уверенно чувствовать себя в задачах уровня middle+, такие разборы — обязательная часть роста.
📆 Встречаемся 22 декабря в 20:00 МСК в преддверие старта курса «Алгоритмы и структуры данных», регистрация открыта: https://tglink.io/3be365254757?erid=2W5zFHNTeic
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
На открытом уроке мы разберем Dancing Links через практику: соберем пентамино на столе, представим фигуры в виде строк матрицы и разберемся, как работает поиск с возвратом. Когда алгоритм становится наглядным, вы начинаете понимать, что на самом деле происходит внутри.
Если вы хотите развивать алгоритмическое мышление, системно улучшать свои решения и уверенно чувствовать себя в задачах уровня middle+, такие разборы — обязательная часть роста.
📆 Встречаемся 22 декабря в 20:00 МСК в преддверие старта курса «Алгоритмы и структуры данных», регистрация открыта: https://tglink.io/3be365254757?erid=2W5zFHNTeic
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
This media is not supported in your browser
VIEW IN TELEGRAM
🔍 Инструмент для перехвата сессий в C#
SessionHop — это утилита на C#, использующая COM-объект IHxHelpPaneServer для перехвата пользовательских сессий. С помощью создания "сессионного моникера" и интерфейса Execute можно запускать произвольные файлы в контексте другой сессии, что полезно для таких задач, как кейлоггинг или скриншоты.
🚀Основные моменты:
- Перехват сессий пользователей с помощью COM-объекта.
- Запуск файлов в контексте другой сессии.
- Альтернатива удаленному инжектированию процессов.
- Полезен для доступа к ресурсам как затронутый пользователь.
📌 GitHub: https://github.com/3lp4tr0n/SessionHop
#csharp
SessionHop — это утилита на C#, использующая COM-объект IHxHelpPaneServer для перехвата пользовательских сессий. С помощью создания "сессионного моникера" и интерфейса Execute можно запускать произвольные файлы в контексте другой сессии, что полезно для таких задач, как кейлоггинг или скриншоты.
🚀Основные моменты:
- Перехват сессий пользователей с помощью COM-объекта.
- Запуск файлов в контексте другой сессии.
- Альтернатива удаленному инжектированию процессов.
- Полезен для доступа к ресурсам как затронутый пользователь.
📌 GitHub: https://github.com/3lp4tr0n/SessionHop
#csharp
Что выведет на экран этот код?
Anonymous Quiz
24%
true
39%
false
18%
null
11%
Возникнет ошибка времени выполнения
8%
🚦 Feature Flags в .NET - как управлять релизами без redeploy
Feature flags (фиче-флаги) позволяют включать и выключать функциональность на лету, без повторного деплоя и риска для продакшена.
Идея простая:
код задеплоен → поведение управляется конфигурацией.
Что это даёт на практике:
— Постепенные релизы
Можно включить новую фичу сначала для 1%, 10% или конкретной группы пользователей.
— Быстрый rollback
Если что-то пошло не так — просто выключаете флаг. Без откатов и срочных хотфиксов.
— A/B тесты
Разные пользователи получают разное поведение одного и того же кода.
— Targeting пользователей
Фичи можно включать:
• по user id
• по роли
• по региону
• по environment (dev / staging / prod)
— Меньше фиче-веток
Код живёт в main, а не за флагами в git.
В .NET обычно используют:
- Microsoft.FeatureManagement
- Azure App Configuration
- LaunchDarkly / Unleash / ConfigCat
Где это особенно полезно:
- публичные API
- high-traffic сервисы
- SaaS-продукты
- экспериментальные и рискованные фичи
Коротко:
Feature flags превращают релиз из «одного опасного момента» в управляемый процесс.
Это один из самых мощных инструментов для зрелой backend-архитектуры.
👉 Подробнее
Feature flags (фиче-флаги) позволяют включать и выключать функциональность на лету, без повторного деплоя и риска для продакшена.
Идея простая:
код задеплоен → поведение управляется конфигурацией.
Что это даёт на практике:
— Постепенные релизы
Можно включить новую фичу сначала для 1%, 10% или конкретной группы пользователей.
— Быстрый rollback
Если что-то пошло не так — просто выключаете флаг. Без откатов и срочных хотфиксов.
— A/B тесты
Разные пользователи получают разное поведение одного и того же кода.
— Targeting пользователей
Фичи можно включать:
• по user id
• по роли
• по региону
• по environment (dev / staging / prod)
— Меньше фиче-веток
Код живёт в main, а не за флагами в git.
В .NET обычно используют:
- Microsoft.FeatureManagement
- Azure App Configuration
- LaunchDarkly / Unleash / ConfigCat
Где это особенно полезно:
- публичные API
- high-traffic сервисы
- SaaS-продукты
- экспериментальные и рискованные фичи
Коротко:
Feature flags превращают релиз из «одного опасного момента» в управляемый процесс.
Это один из самых мощных инструментов для зрелой backend-архитектуры.
👉 Подробнее
3 простые оптимизации, которые реально ускоряют код
1️⃣ Забирай данные пачкой
Меньше запросов — меньше сетевых задержек.
Вместо десятков запросов — один
2️⃣ Делай больше параллельно
Если задачи не зависят друг от друга — выполняй их одновременно.
Асинхронность часто даёт бесплатный прирост скорости.
3️⃣ Кэшируй результаты
Если данные не меняются — не пересчитывай и не запрашивай их заново.
Память дешевле времени.
Никакой магии и сложных алгоритмов — просто базовые приёмы, которые в реальных проектах дают самый заметный эффект.
1️⃣ Забирай данные пачкой
Меньше запросов — меньше сетевых задержек.
Вместо десятков запросов — один
IN (...).2️⃣ Делай больше параллельно
Если задачи не зависят друг от друга — выполняй их одновременно.
Асинхронность часто даёт бесплатный прирост скорости.
3️⃣ Кэшируй результаты
Если данные не меняются — не пересчитывай и не запрашивай их заново.
Память дешевле времени.
Никакой магии и сложных алгоритмов — просто базовые приёмы, которые в реальных проектах дают самый заметный эффект.
⚡️ В мире #dotnet есть куда больше вариантов для messaging, чем RabbitMQ и Kafka.
И для real-time систем эти инструменты часто избыточны.
Большинство брокеров сообщений заточены под надёжность, сложную маршрутизацию и enterprise-сценарии.
Это отлично, когда нужны гарантии доставки и сложные пайплайны.
Но если система живёт на частых событиях, минимальной задержке и мгновенной реакции, этот вес начинает мешать.
Здесь идеально заходит NATS.
NATS - лёгкая и сверхбыстрая система обмена сообщениями, спроектированная именно для real-time:
- минимальная латентность
- простая модель
- высокая масштабируемость
Отлично подходит для:
- телеметрии и sensor data
- live-обновлений
- edge-систем
- сценариев, где важно «сейчас», а не «через секунду»
В статье подробно разобрано:
- когда NATS имеет смысл (а когда нет)
- сравнение с RabbitMQ и Kafka
- использование NATS в .NET с понятными примерами кода
- Pub/Sub, queue groups и request–reply
https://thecodeman.net/posts/introduction-to-nats-real-time-messaging
И для real-time систем эти инструменты часто избыточны.
Большинство брокеров сообщений заточены под надёжность, сложную маршрутизацию и enterprise-сценарии.
Это отлично, когда нужны гарантии доставки и сложные пайплайны.
Но если система живёт на частых событиях, минимальной задержке и мгновенной реакции, этот вес начинает мешать.
Здесь идеально заходит NATS.
NATS - лёгкая и сверхбыстрая система обмена сообщениями, спроектированная именно для real-time:
- минимальная латентность
- простая модель
- высокая масштабируемость
Отлично подходит для:
- телеметрии и sensor data
- live-обновлений
- edge-систем
- сценариев, где важно «сейчас», а не «через секунду»
В статье подробно разобрано:
- когда NATS имеет смысл (а когда нет)
- сравнение с RabbitMQ и Kafka
- использование NATS в .NET с понятными примерами кода
- Pub/Sub, queue groups и request–reply
https://thecodeman.net/posts/introduction-to-nats-real-time-messaging
Интеграционные тесты прямо в CI/CD - максимум уверенности в коде 🚀
Я запускаю интеграционные тесты прямо внутри CI/CD пайплайна.
Так я проверяю не абстракции и моки, а реальное поведение системы.
Всё это возможно благодаря:
- Docker
- Testcontainers
Идея простая:
ты поднимаешь реальные внешние сервисы как контейнеры и используешь их прямо в тестах.
В примере поднимаются:
- PostgreSQL
- Redis
- Keycloak
Контейнеры:
- автоматически стартуют перед тестами
- доступны из кода приложения
- уничтожаются после выполнения тестов
Почему это работает лучше моков:
- тесты максимально близки к продакшену
- одинаковое поведение локально и в CI
- сразу ловятся проблемы с конфигурацией, миграциями, auth
- меньше сюрпризов после деплоя
Особенно полезно для:
- backend-сервисов
- микросервисной архитектуры
- систем с авторизацией и внешними зависимостями
- .NET-приложений с серьёзной бизнес-логикой
Если хочешь вывести интеграционное тестирование в .NET на новый уровень — Testcontainers стоит попробовать обязательно.
#dotnet, #testing
Я запускаю интеграционные тесты прямо внутри CI/CD пайплайна.
Так я проверяю не абстракции и моки, а реальное поведение системы.
Всё это возможно благодаря:
- Docker
- Testcontainers
Идея простая:
ты поднимаешь реальные внешние сервисы как контейнеры и используешь их прямо в тестах.
В примере поднимаются:
- PostgreSQL
- Redis
- Keycloak
Контейнеры:
- автоматически стартуют перед тестами
- доступны из кода приложения
- уничтожаются после выполнения тестов
Почему это работает лучше моков:
- тесты максимально близки к продакшену
- одинаковое поведение локально и в CI
- сразу ловятся проблемы с конфигурацией, миграциями, auth
- меньше сюрпризов после деплоя
Особенно полезно для:
- backend-сервисов
- микросервисной архитектуры
- систем с авторизацией и внешними зависимостями
- .NET-приложений с серьёзной бизнес-логикой
Если хочешь вывести интеграционное тестирование в .NET на новый уровень — Testcontainers стоит попробовать обязательно.
#dotnet, #testing
🔍 Как делать code review, которые находят реальные баги, а не только придираются к стилю
Большинство code review застревают на форматировании, нейминге и мелочах. В итоге реальные проблемы - логические ошибки, гонки, неправильные инварианты - проходят мимо.
Идея правильного code review:
— Проверять поведение кода, а не его внешний вид
— Искать сценарии отказа, а не соответствие линтеру
— Думать как система, а не как форматтер
Что реально стоит смотреть на ревью:
• Граничные случаи и ошибки в бизнес-логике
• Null / empty сценарии и некорректные состояния
• Побочные эффекты и порядок операций
• Работа с асинхронностью, транзакциями и ресурсами
• Соответствие инвариантам доменной модели
Инструменты с AI-ассистентами для code review помогают сместить фокус:
— меньше шума про стиль
— больше внимания к логике и потенциальным багам
— автоматические подсказки прямо в PR
Хороший code review — это не «код красивый»,
а «код не сломается в проде».
Большинство code review застревают на форматировании, нейминге и мелочах. В итоге реальные проблемы - логические ошибки, гонки, неправильные инварианты - проходят мимо.
Идея правильного code review:
— Проверять поведение кода, а не его внешний вид
— Искать сценарии отказа, а не соответствие линтеру
— Думать как система, а не как форматтер
Что реально стоит смотреть на ревью:
• Граничные случаи и ошибки в бизнес-логике
• Null / empty сценарии и некорректные состояния
• Побочные эффекты и порядок операций
• Работа с асинхронностью, транзакциями и ресурсами
• Соответствие инвариантам доменной модели
Инструменты с AI-ассистентами для code review помогают сместить фокус:
— меньше шума про стиль
— больше внимания к логике и потенциальным багам
— автоматические подсказки прямо в PR
Хороший code review — это не «код красивый»,
а «код не сломается в проде».
В какой строке возникнет первое исключение?
Anonymous Quiz
26%
1
11%
2
8%
3
7%
4
5%
5
29%
Весь код выполнится корректно
14%
🎄
💡 В EF Core есть штука, о которой многие забывают: CompileAsyncQuery.
С её помощью можно заранее скомпилировать LINQ-запрос,а потом выполнять его асинхронно: быстрее и без лишнего overhead’а.
И важный еще момент:
вам не нужно писать отдельную “async-версию” самого LINQ-запроса.
EF сам оборачивает выполнение в асинхронный пайплайн. Немного странно, но работает.
Пример:
Что получаем:
• повторные запросы выполняются быстрее
• нет лишней компиляции выражений
• async-подход сохраняется
Если в проекте есть часто вызываемые запросы - Compiled Queries могут дать хороший прирост производительности, особенно под нагрузкой.
С её помощью можно заранее скомпилировать LINQ-запрос,а потом выполнять его асинхронно: быстрее и без лишнего overhead’а.
И важный еще момент:
вам не нужно писать отдельную “async-версию” самого LINQ-запроса.
EF сам оборачивает выполнение в асинхронный пайплайн. Немного странно, но работает.
Пример:
private static Func<AppDbContext, string, Task<Newsletter?>> GetByTitle =
EF.CompileAsyncQuery(
(AppDbContext context, string title) =>
context.Set<Newsletter>()
.FirstOrDefault(c => c.Title == title)
);
public async Task<Newsletter?> GetNewsletterByTitleAsync(string title)
{
return await GetByTitle(this, title);
}
Что получаем:
• повторные запросы выполняются быстрее
• нет лишней компиляции выражений
• async-подход сохраняется
Если в проекте есть часто вызываемые запросы - Compiled Queries могут дать хороший прирост производительности, особенно под нагрузкой.
Индекс TIOBE подвел итоги года: звание «Язык 2025 года» досталось C#, который показал рекордный рост популярности (+2.94%)? однако в общем зачете он по-прежнему занимает 5-ю строчку. Абсолютным лидером остается Python с 22.61% долей рынка.
В первой пятерке произошли перестановки: язык C поднялся на 2 место, сместив C++ на 4-ю позицию; 3 место досталось Java, а R вернулся в топ-10. Провал года - Go, который неожиданно сдал позиции, опустившись сразу на 16-е место.
Индекс оценивает популярность технологий на основе поисковых запросов, активности комьюнити и количества обучающих материалов.
https://www.tiobe.com/tiobe-index/
Please open Telegram to view this post
VIEW IN TELEGRAM
💻Полный перебор выглядит простым решением, пока не сталкивается с реальностью. Как только задача усложняется, перебор становится неприемлемо медленным — и именно здесь начинаются настоящие алгоритмы.
📆На открытом уроке вы напишете алгоритм Dancing Links Дональда Кнута — один из самых элегантных способов решения задач точного покрытия. Мы разберём, почему классический перебор не работает, и как четырёхсвязный список позволяет добавлять и удалять элементы практически без затрат.
Вы увидите, как несколько десятков строк кода решают задачи, которые выглядят непосильными для brute force. Реализуете алгоритм полностью, разберёте его внутреннюю механику и примените к задаче пентамино.
👉Встречаемся 12 января в 20:00 МСК в преддверие старта курса «Алгоритмы и структуры данных». Регистрация открыта: https://tglink.io/cb04fae31111?erid=2W5zFHHfYCx
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
📆На открытом уроке вы напишете алгоритм Dancing Links Дональда Кнута — один из самых элегантных способов решения задач точного покрытия. Мы разберём, почему классический перебор не работает, и как четырёхсвязный список позволяет добавлять и удалять элементы практически без затрат.
Вы увидите, как несколько десятков строк кода решают задачи, которые выглядят непосильными для brute force. Реализуете алгоритм полностью, разберёте его внутреннюю механику и примените к задаче пентамино.
👉Встречаемся 12 января в 20:00 МСК в преддверие старта курса «Алгоритмы и структуры данных». Регистрация открыта: https://tglink.io/cb04fae31111?erid=2W5zFHHfYCx
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
🔥 Как просто добавить multi-tenant в .NET через заголовок запроса
Иногда нужно понимать, какому клиенту (tenant) принадлежит запрос.
Самый простой вариант - передавать
Пример сервиса:
Иногда нужно понимать, какому клиенту (tenant) принадлежит запрос.
Самый простой вариант - передавать
X-TenantId в HTTP-заголовке и читать его в сервисе.Пример сервиса:
public sealed class TenantProvider
{
private const string TenantIdHeaderName = "X-TenantId";
private readonly IHttpContextAccessor _httpContextAccessor;
public TenantProvider(IHttpContextAccessor httpContextAccessor)
=> _httpContextAccessor = httpContextAccessor;
public string TenantId =>
_httpContextAccessor.HttpContext.Request.Headers[TenantIdHeaderName];
}
using System;
class Base
{
public virtual void Foo(object o) => Console.WriteLine("Base.Foo(object)");
}
class Derived : Base
{
public override void Foo(object o) => Console.WriteLine("Derived.Foo(object)");
public void Foo(string s) => Console.WriteLine("Derived.Foo(string)");
}
class Program
{
static void Main()
{
Base b = new Derived();
b.Foo("A");
((Derived)b).Foo("A");
dynamic d = b;
d.Foo("A");
object x = "A";
d.Foo(x);
d.Foo(null);
}
}
📌 Ответ:
Derived.Foo(string)
Derived.Foo(string)
Derived.Foo(string)
Derived.Foo(string)
Пояснение:
Статический тип переменной - Base.
Компилятор видит только Foo(object).
Вызов виртуальный, поэтому выполняется override:
Derived.Foo(object)
2) ((Derived)b).Foo("A")
Статический тип - Derived.
Есть перегрузка Foo(string), она точнее для string:
Derived.Foo(string)
3) dynamic d = b; d.Foo("A")
dynamic откладывает выбор метода до runtime.
Реальный тип объекта - Derived.
Реальный тип аргумента - string:
Derived.Foo(string)
4) object x = "A"; d.Foo(x)
Для dynamic учитывается реальный тип аргумента.
x содержит string:
Derived.Foo(string)
5) d.Foo(null)
null подходит и для object, и для string.
string - более специфичный тип:
Derived.Foo(string)
Please open Telegram to view this post
VIEW IN TELEGRAM