C# (C Sharp) programming
По всем вопросам- @notxxx1 Реестр РКН: https://clck.ru/3Fk3kb #VRHSZ
Ko'proq ko'rsatish📈 Telegram kanali C# (C Sharp) programming analitikasi
C# (C Sharp) programming (@csharp_ci) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 18 129 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 7 042-o'rinni va Rossiya mintaqasida 36 294-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 18 129 obunachiga ega bo‘ldi.
28 Avgust, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni -66 ga, so‘nggi 24 soatda esa -1 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 15.26% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 7.43% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 2 767 marta ko‘riladi; birinchi sutkada odatda 1 348 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 0 ta reaksiya keladi.
- Tematik yo‘nalishlar: Kontent .net, api, логика, архитектура, string kabi asosiy mavzularga jamlangan.
📝 Tavsif va kontent siyosati
Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
“По всем вопросам- @notxxx1
Реестр РКН: https://clck.ru/3Fk3kb
#VRHSZ”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 29 Avgust, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.
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 - это тот, в работе с которым ошибиться почти невозможно.