Библиотека шарписта | C#, F#, .NET, ASP.NET
Все самое полезное для C#-разработчика в одном канале. Наши курсы: https://clc.to/y3LDtw По рекламе: @proglib_adv Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead
Show more📈 Analytical overview of Telegram channel Библиотека шарписта | C#, F#, .NET, ASP.NET
Channel Библиотека шарписта | C#, F#, .NET, ASP.NET (@csharpproglib) in the Russian language segment is an active participant. Currently, the community unites 21 701 subscribers, ranking 5 943 in the Technologies & Applications category and 30 267 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 21 701 subscribers.
According to the latest data from 29 August, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -48 over the last 30 days and by -6 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 16.72%. Within the first 24 hours after publication, content typically collects 7.84% reactions from the total number of subscribers.
- Post reach: On average, each post receives 3 628 views. Within the first day, a publication typically gains 1 702 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 23.
- Thematic interests: Content is focused on key topics such as .net, шарписта, навигация, await, string.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“Все самое полезное для C#-разработчика в одном канале.
Наши курсы: https://clc.to/y3LDtw
По рекламе: @proglib_adv
Для обратной связи: @proglibrary_feeedback_bot
РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead”
Thanks to the high frequency of updates (latest data received on 30 August, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
[0][1][1][2][3][3][4] ответ будет [1][3].
Для решения можно воспользоваться подсчётом количества появлений каждого числа.
Если встретили число во второй раз — записываем его в ответ:
public int[] GetSneakyNumbers(int[] nums)
{
int n = nums.Length;
int[] count = new int[101];
int[] res = new int[2];
int idx = 0;
foreach (var num in nums)
{
count[num]++;
if (count[num] == 2)
{
res[idx] = num;
idx++;
}
}
return res;
}
При помощи вспомогательного массива считаем, сколько раз встречается каждое число, и когда оно появилось второй раз — запоминаем.
➡️ Попробовать решить
🐸 Библиотека шарписта
#dotnet_challengevar errors = File.ReadLines(logPath).Where(l => l.Contains("ERROR"));
ReadLines читает файл построчно, не загружая всё сразу.
Не добавляйте .ToList(), если хочется сохранить ленивость — иначе всё материализуется в памяти.
🐸 Библиотека шарписта
#sharp_viewpublic async Task<bool> SaveWithRetryAsync(DbContext context, int maxRetries = 3)
{
for (int attempt = 0; attempt < maxRetries; attempt++)
{
try
{
await context.SaveChangesAsync();
return true;
}
catch (DbUpdateException ex) when (IsDeadlock(ex))
{
if (attempt == maxRetries - 1)
throw;
// Экспоненциальная задержка: 100ms, 200ms, 400ms
var delay = TimeSpan.FromMilliseconds(100 * Math.Pow(2, attempt));
await Task.Delay(delay);
Console.WriteLine($"Deadlock detected, retry {attempt + 1}/{maxRetries}");
}
}
return false;
}
bool IsDeadlock(Exception ex) =>
ex.InnerException is SqlException sqlEx &&
(sqlEx.Number == 1205 || // Deadlock victim
ex.InnerException.Message.Contains("deadlocked"));
• Ограничение параллелизма
Если ваше приложение обрабатывает большие пакеты данных, ограничьте количество одновременных операций:
public class OrderProcessor
{
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(5); // Макс 5 одновременно
public async Task ProcessOrdersAsync(List<int> orderIds)
{
var tasks = orderIds.Select(id => ProcessWithSemaphoreAsync(id));
await Task.WhenAll(tasks);
}
private async Task ProcessWithSemaphoreAsync(int orderId)
{
await _semaphore.WaitAsync();
try
{
await using var context = new AppDbContext();
var order = await context.Orders.FindAsync(orderId);
order.Status = "Processed";
await SaveWithRetryAsync(context);
}
finally
{
_semaphore.Release();
}
}
}
• Логирование и анализ
Недостаточно просто повторить — нужно понять причину:
catch (DbUpdateException ex) when (IsDeadlock(ex))
{
_logger.LogWarning(ex,
"Deadlock on order {OrderId}, attempt {Attempt}/{MaxAttempts}",
orderId, attempt + 1, maxRetries);
// Отправьте метрику в мониторинг
_telemetry.TrackMetric("Deadlocks", 1, new Dictionary<string, string>
{
["Entity"] = "Order",
["Operation"] = "Update"
});
}
• Захват графов блокировок
SQL Server создаёт подробные графы взаимоблокировок. Настройте их захват:
-- Extended Events для захвата deadlock
CREATE EVENT SESSION [DeadlockMonitoring] ON SERVER
ADD EVENT sqlserver.xml_deadlock_report
ADD TARGET package0.event_file(SET filename = N'C:\Logs\Deadlocks.xel')
WITH (MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS);
ALTER EVENT SESSION [DeadlockMonitoring] ON SERVER STATE = START;
Сочетание правильного предотвращения и надежного восстановления создаст устойчивую систему, способную справиться с любыми нагрузками.
Чтобы строить надёжные решения нужно знать архитектуру и уметь её спроектировать. Для этого можно пройти наш интенсив по архитектуре и шаблонам проектирования. Осталось всего 3 дня скидок!
🐸 Библиотека шарписта
#sharp_viewSqlException: Transaction (Process ID xx) was deadlocked on resources...Пример простого дедлока: два контекста одновременно меняют одну строку и пытаются сохранить изменения. Один запрос блокирует строку, второй вызывает дедлок.
await using var context1 = new AppDbContext();
await using var context2 = new AppDbContext();
var order1 = await context1.Orders.FindAsync(1);
var order2 = await context2.Orders.FindAsync(1);
order1.Status = "Paid";
order2.Status = "Shipped";
await context1.SaveChangesAsync(); // Блокирует строку
await context2.SaveChangesAsync(); // Возможен deadlock
Стратегии предотвращения
• Короткие транзакции
Минимизируйте работу внутри транзакции:
await using var tx = await context.Database.BeginTransactionAsync();
var order = await context.Orders.FindAsync(orderId);
order.Status = "Paid";
await context.SaveChangesAsync();
await tx.CommitAsync();
Избегайте сетевых вызовов и посторонних запросов перед коммитом.
• Правильные индексы
Отсутствие индексов приводит к сканированию таблиц и длительным блокировкам. Используйте SQL Profiler для мониторинга.
• Оптимальный уровень изоляции
ReadCommitted обычно достаточен для большинства операций:
await using var tx = await context.Database.BeginTransactionAsync(
IsolationLevel.ReadCommitted);
• Логика повторов
Используйте встроенную политику retry в EF Core:
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(connectionString, sql =>
sql.EnableRetryOnFailure(
maxRetryCount: 3,
maxRetryDelay: TimeSpan.FromSeconds(5),
errorNumbersToAdd: null)));
• RowVersion для контроля конкурентности
public class Order
{
public int Id { get; set; }
public string Status { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
EF Core выбросит DbUpdateConcurrencyException при конфликте изменений.
Дедлоки не баги, а следствие паттернов конкурентного доступа.
🐸 Библиотека шарписта
#sharp_viewvar last10 = text[^10..];
Такой способ делает код короче и легче для чтения.
Но есть один момент — если строка короче десяти символов, программа выбросит ошибку.
Чтобы этого избежать, добавьте проверку:
var last10 = text.Length >= 10 ? text[^10..] : text;Теперь код работает безопасно даже с короткими строками. 🐸 Библиотека шарписта #sharp_view
List<T> — это универсальный солдат C#. Но универсальный не значит оптимальный. Пока вы перебираете 10 000 элементов через .FirstOrDefault(), Dictionary находит нужное за одно обращение. И это только начало.
Queue — когда порядок имеет значение
Обрабатываете задачи по очереди? Вот вам готовое решение:
var tasks = new Queue<UserRequest>();
tasks.Enqueue(new UserRequest { Id = 1, Name = "Alice" });
tasks.Enqueue(new UserRequest { Id = 2, Name = "Bob" });
// Безопасное извлечение (с .NET 6+)
while (tasks.TryDequeue(out var request))
{
await ProcessAsync(request);
}
Первым пришел — первым обработался. Никаких индексов, никаких сортировок.
Stack — для истории действий
Делаете undo/redo или навигацию? Стек решает это из коробки:
var history = new Stack<string>();
history.Push("/home");
history.Push("/products");
history.Push("/cart");
// Вернуться назад
if (history.TryPop(out var lastPage))
{
Console.WriteLine($"Back to: {lastPage}"); // /cart
}
Последнее действие всегда доступно первым. Логика браузерной кнопки «Hазад» готова.
Dictionary — когда нужна скорость
Поиск по ключу за O(1) вместо перебора всего списка:
var users = new Dictionary<int, User>();
users.Add(1, new User { Name = "Alice" });
users.Add(2, new User { Name = "Bob" });
// Безопасная проверка
if (users.TryGetValue(2, out var user))
{
Console.WriteLine(user.Name); // Bob
}
Никаких .FirstOrDefault(x => x.Id == 2) с перебором тысяч записей.
List отлично работает, когда вам нужен доступ по индексу и порядок элементов. Но если задача укладывается в одну из этих трёх структур — используйте их.
🐸 Библиотека шарписта
#il_люминатор