Библиотека шарписта | C#, F#, .NET, ASP.NET
22.5K subscribers
2.43K photos
40 videos
85 files
4.63K links
Все самое полезное для C#-разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/b60af5a4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead
Download Telegram
14 вопросов, после которых вам не перезвонят

Разбираем 14 вопросов, которые лучше не задавать на собеседовании: что не так с каждым из них и как переформулировать, чтобы получить нужную информацию без риска для репутации.

➡️ Прочитать статью

🐸 Библиотека шарписта
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱8👍4😁3
⚡️ Deadlock в EF Core: как восстановиться

Даже самая оптимизированная система не застрахована от deadlock на 100%. При высоких нагрузках, пиковых моментах или редких edge-case сценариях они всё равно могут возникнуть. Важно не предотвращение на 100% (это невозможно), а грамотное восстановление.

• Умный ретрай с экспоненциальной задержкой

Простой повтор без задержки только усугубит ситуацию. Используйте экспоненциальную задержку:
public 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_view
Please open Telegram to view this post
VIEW IN TELEGRAM
13👍5🔥4
⭐️ Подборка вакансий для шарпистов

.NET-разработчик на удалёнку.

Backend-developer в Москве от 200 000 ₽.

.NET Developer от 200 000 ₽ с удалёнкой.

Бустер — Удалённо (в любом городе мира).

➡️ Еще больше топовых вакансий — в нашем канале C# Jobs
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍2🥱1
👨‍💻 Ленивый фильтр больших файлов

Когда файл огромный, главное — не тянуть всё в память.

Пример:
var errors = File.ReadLines(logPath).Where(l => l.Contains("ERROR"));


ReadLines читает файл построчно, не загружая всё сразу.

Не добавляйте .ToList(), если хочется сохранить ленивость — иначе всё материализуется в памяти.

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10
🎃 Хэллоуин в Proglib Academy: скидки, призы и... немного паники

Сегодня 31 октября, и это не просто время тыкв и призраков, это ПОСЛЕДНИЙ ДЕНЬ, когда ты можешь выиграть макбук!

→ Купи любой курс со скидкой 40% 💸
→ Начни обучение, чтобы пройти 2 недели к 15 ноября 🎓
→ Напиши куратору #розыгрыш ✍️

Всё! Теперь ты в игре.

👉 Сейчас или никогда!
🎃 Хэллоуин и код

Сегодня день, когда можно немного отвлечься от кода и рутины. Костюм помогает прочувствовать праздник, даже если это всего один день.

💬 Делитесь, кто в костюме сегодня, оставляйте свои истории 👇


🐸 Библиотека шарписта

#entry_point
Please open Telegram to view this post
VIEW IN TELEGRAM
✏️ Как найти два повторяющихся числа в массиве

Вам дан массив nums длиной n+2, содержащий числа от 0 до n-1. Два числа случайным образом появились в списке дважды. Нужно вернуть эти два числа. Например, для входа [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_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
1