C# (C Sharp) programming
По всем вопросам- @notxxx1 Реестр РКН: https://clck.ru/3Fk3kb #VRHSZ
Mostrar más📈 Análisis del canal de Telegram C# (C Sharp) programming
El canal C# (C Sharp) programming (@csharp_ci) en el segmento lingüístico de Ruso es un actor destacado. Actualmente la comunidad reúne a 18 129 suscriptores, ocupando la posición 7 042 en la categoría Tecnologías y Aplicaciones y el puesto 36 294 en la región Rusia.
📊 Métricas de audiencia y dinámica
Desde su creación el невідомо, el proyecto ha mostrado un crecimiento acelerado, reuniendo a 18 129 suscriptores.
Según los últimos datos del 28 agosto, 2026, el canal mantiene una actividad estable. En los últimos 30 días la variación de miembros fue de -66, y en las últimas 24 horas de -1, conservando un alto alcance.
- Estado de verificación: No verificado
- Tasa de interacción (ER): El promedio de interacción de la audiencia es 15.26%. Durante las primeras 24 horas tras publicar, el contenido suele obtener 7.43% de reacciones respecto al total de suscriptores.
- Alcance de las publicaciones: Cada publicación recibe en promedio 2 767 visualizaciones. En el primer día suele acumular 1 348 visualizaciones.
- Reacciones e interacción: La audiencia responde de forma activa: el promedio de reacciones por publicación es 0.
- Intereses temáticos: El contenido se centra en temas clave como .net, api, логика, архитектура, string.
📝 Descripción y política de contenido
El autor describe el recurso como un espacio para expresar opiniones subjetivas:
“По всем вопросам- @notxxx1
Реестр РКН: https://clck.ru/3Fk3kb
#VRHSZ”
Gracias a la alta frecuencia de actualizaciones (últimos datos recibidos el 29 agosto, 2026), el canal mantiene la vigencia y un amplio alcance. La analítica demuestra que la audiencia interactúa activamente con el contenido, lo que lo convierte en un punto de referencia dentro de la categoría Tecnologías y Aplicaciones.
date DESC, id DESC, лимит на 1000 записей и composite index по (date, id). На первый взгляд, все должно работать быстро.
Но EXPLAIN ANALYZE показывает другое: Postgres вроде бы использует Index Scan, но после этого выкидывает 900 000 строк через Filter.
То есть индекс есть, но запрос все равно тащит слишком много лишнего.
Проблема в условии:
`date < @date OR (date = @date AND id <= @lastId)`
Для разработчика это выглядит логично: сначала сравниваем дату, потом id.
Но для оптимизатора такой OR плохо ложится на composite index. В итоге база не может сразу пойти по нужному диапазону и вынуждена фильтровать огромный кусок данных.
Правильнее записать условие через tuple comparison:
`(date, id) <= (@date, @lastId)`
Смысл тот же, но для Postgres это уже понятный диапазон по составному индексу.
И результат: 298 мс превращаются в 0,66 мс.
Индекс сам по себе ничего не гарантирует.
Важно не только создать индекс, но и написать запрос так, чтобы оптимизатор реально смог его использовать.Guid.NewGuid().
Проблема в том, что классический UUID случайный. Для уникальности это удобно, но для базы данных - не всегда.
Когда значения генерируются хаотично, новые записи вставляются в разные части индекса. Отсюда:
- больше фрагментации
- дороже вставки
- чаще перестраиваются страницы индекса
- хуже поведение на больших таблицах
Поэтому многие разработчики начали использовать ULID.
ULID состоит из двух частей:
- timestamp
- random
За счет timestamp такие ID сортируются по времени, а значит база может вставлять новые записи более последовательно.
Но начиная с .NET 9 появился встроенный вариант:
Guid.CreateVersion7()
UUID v7 тоже содержит временную часть, поэтому лучше подходит для индексируемых ключей, чем полностью случайный UUID.
Главное отличие:
ULID - отдельный формат и часто сторонняя библиотека.
UUID v7 - обычный Guid, который уже поддерживается в .NET.
Для новых проектов это выглядит как более разумный дефолт:
- не Guid.NewGuid()
- не отдельный ULID-пакет
- а Guid.CreateVersion7()
Особенно если Guid используется как primary key в базе. async Task<IActionResult> пишется на автомате. Вы точно знаете, почему EF Core сгенерировал именно такой SQL - и как переписать запрос, чтобы он летал.
Это не фантазия. Это результат после 16 модулей, в которых каждая концепция объясняется через код и закрепляется практикой.
ООП, SOLID, LINQ, async/await, DI, EF Core, ASP.NET Core, Docker, Kubernetes - всё, что казалось магией, станет рабочим инструментом.
А бонусом - портфолио проектов: от CLI-утилит и REST API до собственного SaaS с multi-tenancy, JWT и деплоем в Kubernetes под TLS.
Скидка - 58% доступна 48 часов: https://stepik.org/a/282984/fingerd`, переполнял буфер и заставлял систему выполнять чужой код.
Итог: около 6000 машин были заражены за считанные часы. По оценкам того времени, это была примерно десятая часть всего интернета.
Самое безумное здесь не сам червь, а то, насколько маленькой была причина. Один небезопасный вызов. Один буфер без проверки. Одна функция, которую годами использовали как обычный инструмент.
Позже `gets()` признали настолько опасной, что её фактически выкинули из современного C.
Урок простой: в системном программировании безопасность часто ломается не на сложной криптографии, а на банальном «а что будет, если ввод окажется длиннее, чем мы ожидали?»
#history[InlineData(...)], когда параметры можно прямо указать над тестом.
Если данных больше или нужна нормальная типизация, можно вынести их в TheoryData<T> и подключить через [ClassData(typeof(...))].
Смысл простой: меньше копипасты, чище тесты, проще добавлять новые кейсы.
Вместо пяти почти одинаковых тестов - один понятный сценарий и набор входных данных.
Для xUnit это один из тех приемов, который быстро окупается в любом C# проекте.ApiVersionSet: можно явно объявить поддерживаемые версии, включить репортинг доступных версий и привязать конкретный endpoint к нужной версии.
В примере создается набор версий API:
v1 - текущая стабильная версия
v2 - новая версия для развития контракта
После этого endpoint /api/v{version:apiVersion}/workouts/{workoutId} получает привязку через .WithApiVersionSet(apiVersionSet) и явно мапится на .MapToApiVersion(1).
Главная идея простая: версия становится частью маршрута, а не скрытой договоренностью между клиентом и backend.
Это особенно важно, когда API уже используют мобильные приложения, внешние интеграции или несколько фронтендов. Вы можете развивать v2, не ломая клиентов, которые все еще сидят на v1.
Для C# backend-разработчика это один из тех паттернов, который выглядит мелочью на старте, но сильно экономит нервы на проде.
public decimal CalculateTotal(Order order)
{
decimal total = 0;
if (order != null)
{
if (order.Items != null)
{
foreach (var item in order.Items)
{
if (item != null)
{
if (item.IsActive)
{
if (item.Price > 0)
{
if (item.Quantity > 0)
{
total += item.Price * item.Quantity;
}
}
}
}
}
}
if (order.Customer != null)
{
if (order.Customer.IsVip)
{
total = total * 0.9m;
}
}
}
return total;
}
Как бы ты почистил этот код?
A - Заменить вложенные if на guard clauses
B - Использовать LINQ для фильтрации и суммы
C - Вынести скидку VIP в отдельный метод
D - Все варианты выше
@csharp_ci async Task<IActionResult> пишется на автомате. Вы точно знаете, почему EF Core сгенерировал именно такой SQL - и как переписать запрос, чтобы он летал.
Это не фантазия. Это результат после 16 модулей, в которых каждая концепция объясняется через код и закрепляется практикой.
ООП, SOLID, LINQ, async/await, DI, EF Core, ASP.NET Core, Docker, Kubernetes - всё, что казалось магией, станет рабочим инструментом.
А бонусом - портфолио проектов: от CLI-утилит и REST API до собственного SaaS с multi-tenancy, JWT и деплоем в Kubernetes под TLS.
Скидка - 58% доступна 48 часов: https://stepik.org/a/282984/
foreach (var transaction in GetTransactions(userId))
{
// boom, если null
}
В итоге получаешь:
• лишние null-проверки повсюду
• более громоздкий код
• ошибки в рантайме, если кто-то забыл проверить
Всегда этого возвращай пустую коллекцию:
Enumerable.Empty<T>()
new List<T>()
[] в C# 12
var transactions = GetTransactions(userId)
?? Enumerable.Empty<TransactionDto>();
Теперь код становится чище и понятнее.
Ты всегда можешь итерироваться и не думаешь о null каждый раз.
Хороший API - это тот, в работе с которым ошибиться почти невозможно.