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 319 suscriptores, ocupando la posición 7 281 en la categoría Tecnologías y Aplicaciones y el puesto 36 747 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 319 suscriptores.
Según los últimos datos del 23 junio, 2026, el canal mantiene una actividad estable. En los últimos 30 días la variación de miembros fue de 27, y en las últimas 24 horas de 4, conservando un alto alcance.
- Estado de verificación: No verificado
- Tasa de interacción (ER): El promedio de interacción de la audiencia es 17.49%. Durante las primeras 24 horas tras publicar, el contenido suele obtener 7.97% de reacciones respecto al total de suscriptores.
- Alcance de las publicaciones: Cada publicación recibe en promedio 3 204 visualizaciones. En el primer día suele acumular 1 460 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 24 junio, 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.
docker-compose.yml, опишите сервисы в AppHost. Aspire Docker publisher сможет сгенерировать Compose-артефакты из этой модели.
Но важно понимать границу: Aspire не деплоит приложение за вас.
Он не заменяет CI/CD, не управляет секретами и не переносит контейнеры на сервер. Вам всё равно нужно собрать image, задать реальные env-переменные, скопировать файлы и запустить Docker Compose.
Зато это хороший баланс: меньше ручной YAML-рутины, но без магии, которая скрывает реальную схему деплоя. 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/
i & -i
Она находит младший установленный бит числа.
Именно это значение говорит структуре, на сколько нужно прыгнуть по индексам.
Пример:
i = 12 // 1100
i & -i = 4 // 0100
Реализация на C#:
public sealed class FenwickTree
{
private readonly int[] _tree;
public FenwickTree(int size)
{
_tree = new int[size + 1];
}
public void Update(int index, int delta)
{
while (index < _tree.Length)
{
_tree[index] += delta;
index += index & -index;
}
}
public int Query(int index)
{
var sum = 0;
while (index > 0)
{
sum += _tree[index];
index -= index & -index;
}
return sum;
}
}
Как это работает:
* Update идёт вверх по структуре и обновляет все узлы, которые отвечают за индекс
* Query идёт вниз и собирает блоки, из которых состоит prefix sum
* index & -index каждый раз выбирает размер текущего блока
Главный нюанс: Fenwick Tree обычно использует 1-based indexing.
То есть первый элемент имеет индекс 1, а не 0.
Пример использования:
var tree = new FenwickTree(5);
tree.Update(1, 10);
tree.Update(2, 20);
tree.Update(3, 30);
Console.WriteLine(tree.Query(3)); // 60
Красота Fenwick Tree в том, что дерево не хранится явно.
Нет узлов.
Нет ссылок.
Нет рекурсии.
Только массив и один битовый трюк.
Дерево спрятано прямо внутри двоичного представления индексов.
order._items.AddRange(items);
Поле _items объявлено как private.
Значит ли это, что доступ к нему разрешён только через this._items?
Нет.
Код скомпилируется.
В C# модификатор private ограничивает доступ типом, а не конкретным экземпляром объекта.
То есть любой код внутри класса Order может обращаться к private-полям любого другого экземпляра Order.
Пример:
public class Order
{
private readonly List<OrderItem> _items = new();
public void CopyItemsFrom(Order other)
{
_items.AddRange(other._items);
}
}
Здесь other._items тоже валиден, потому что мы всё ещё находимся внутри типа Order.
Это часто путают на собеседованиях:
private означает не «доступно только этому объекту», а «доступно только коду внутри этого класса».
В примере это используется в static factory method:
var order = new Order { ... };
order._items.AddRange(items);
return order;
Метод Create находится внутри Order, поэтому он имеет полный доступ к private-состоянию создаваемого экземпляра.
Более интересный вопрос тут даже не в компиляции, а в дизайне.
Такой подход часто встречается в DDD:
* private constructor
* static factory method
* закрытая коллекция _items
* наружу отдаётся IReadOnlyList<OrderItem>
* изменение состояния контролируется внутри агрегата
Но есть нюанс.
_items.AsReadOnly() каждый раз создаёт новый wrapper. Обычно лучше кэшировать read-only view или возвращать IReadOnlyCollection<T>, если индексатор не нужен.
Ещё важнее: фабрика должна не просто копировать items, а проверять инварианты:
if (items is null || items.Count == 0)
throw new DomainException("Order must contain at least one item.");
Иначе получается не DDD entity, а просто объект с красивой фабрикой.
Да, код компилируется.
Потому что private в C# работает на уровне типа, а не экземпляра.
А хороший senior-вопрос здесь такой:
скомпилируется ли код - это база.
А вот защищает ли этот Order свои инварианты - уже архитектура.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
var actions = new List<Func<Task>>();
for (int i = 0; i < 3; i++)
{
actions.Add(async () =>
{
await Task.Yield();
Console.Write(i + " ");
});
}
foreach (var action in actions)
{
await action();
}
Что выведет код?
Варианты:
0 1 2 3 3 3 0 0 0 1 2 3Правильный ответ: 3 3 3 Разбор коротко: i в for не копируется в каждую лямбду. Все три лямбды захватывают одну и ту же переменную i. Когда цикл закончился, i == 3. Поэтому каждая отложенная async-функция печатает уже финальное значение. Чтобы получить 0 1 2, нужно создать локальную копию внутри цикла: ``` for (int i = 0; i < 3; i++) { int copy = i; actions.Add(async () => { await Task.Yield(); Console.Write(copy + " "); }); } ```
Db.ChangeTracker.Clear();
4. Бонус, который теряют 90% команд - тест миграций
Реальная БД позволяет прогнать EF-миграции на чистой схеме.
Если миграция падает или схема разъехалась с моделью, вы узнаёте об этом в CI, а не в проде в пятницу вечером.
Пример базового подхода:
public class IntegrationTestBase : IAsyncLifetime
{
private static readonly PostgreSqlContainer _db =
new PostgreSqlBuilder()
.WithImage("postgres:16-alpine")
.Build();
private Respawner _respawner = null!;
protected AppDbContext Db = null!;
public async Task InitializeAsync()
{
await _db.StartAsync();
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseNpgsql(_db.GetConnectionString())
.Options;
Db = new AppDbContext(options);
// Реальные миграции - заодно проверяем, что они накатываются
await Db.Database.MigrateAsync();
await using var conn = new NpgsqlConnection(_db.GetConnectionString());
await conn.OpenAsync();
_respawner = await Respawner.CreateAsync(conn, new RespawnerOptions
{
DbAdapter = DbAdapter.Postgres,
SchemasToInclude = ["public"]
});
}
// Сброс данных перед каждым тестом - без пересоздания контейнера
protected async Task ResetAsync()
{
await using var conn = new NpgsqlConnection(_db.GetConnectionString());
await conn.OpenAsync();
await _respawner.ResetAsync(conn);
// Иначе тест может читать из кеша, а не из БД
Db.ChangeTracker.Clear();
}
public Task DisposeAsync() => Task.CompletedTask;
}
Testcontainers - это не галочка «best practice», а смена философии.
Без нормальной изоляции данных вы просто пересели с быстрого вранья на медленное.
А как вы изолируете состояние БД между интеграционными тестами - Respawn, транзакции или пересоздание контейнера?
#dotnet #csharp #testing #efcore__sw_hweight64.
Красивый пример того, как старый битовый трюк пережил десятилетия и всё ещё работает в современном системном коде.
using System;
using System.Collections.Generic;
var list = new List<Func<int>>();
for (int i = 0; i < 3; i++)
{
int x = i;
list.Add(() => x);
x = 100;
}
foreach (var f in list)
{
Console.Write(f() + " ");
}
A) 0 1 2
😎 100 100 100
C) 3 3 3
D) 0 100 100
Правильный ответ: 😎 100 100 100
Почему так:
Внутри каждой итерации создаётся новая локальная переменная x, и именно её захватывает лямбда. Кажется, что ответы должны быть 0 1 2, потому что x получает значение i.
Но после добавления лямбды переменная x всё ещё та же самая захваченная переменная. Потом мы меняем её на 100.
В итоге каждая лямбда хранит свою отдельную x, но каждая из этих x была изменена на 100.
¡Ya disponible! Investigación de Telegram 2025 — los principales insights del año 
