C# C#  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  ·  👥 1 прошёл

Управление памятью и Span

Посвящён управляемой памяти, поколениям, Span/Memory и пулам массивов. Задания требуют проследить время жизни буфера, владение арендованной памятью, причины аллокаций и момент, когда оптимизация без измерения становится опаснее обычного массива.

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. На 30 вопросов отведено 85 минут. В заданиях с кодом учитывайте указанную конструкцию и не додумывайте отсутствующие условия. После завершения откроются общий результат, тематические шкалы и разбор каждого ответа.
Вопрос 1 из 30
Когда managed-объект становится кандидатом на сборку?
C#
var customer = new Customer();
cache[customer.Id] = customer;
customer = null;
// Объект всё ещё достижим через cache.
Вопрос 2 из 30
Почему Dispose не освобождает память объекта немедленно?
C#
using (var stream = File.OpenRead(path))
{
    ReadHeader(stream);
} // handle закрыт; память объекта stream будет собрана позднее
Вопрос 3 из 30
Зачем типу с SafeHandle обычно не нужен собственный финализатор?
Вопрос 4 из 30
Какой эффект у финализатора для объекта?
C#
sealed class NativeOwner
{
    ~NativeOwner() => ReleaseNative();
}
Вопрос 5 из 30
Почему регулярный GC.Collect в обработчике запроса обычно вреден?
Вопрос 6 из 30
Почему большинство новых небольших объектов начинается в Gen0?
C#
for (var i = 0; i < 1_000_000; i++)
{
    var temporary = new byte[128];
    Consume(temporary);
}
Вопрос 7 из 30
Что происходит с объектом, пережившим сборку поколения?
Вопрос 8 из 30
Как интерпретировать высокий Gen2 collection count?
C#
var gen2 = GC.CollectionCount(2);
var heap = GC.GetGCMemoryInfo().HeapSizeBytes;
metrics.Record(gen2, heap);
Вопрос 9 из 30
Куда обычно попадает большой массив байтов?
Вопрос 10 из 30
Почему кэш может увеличивать стоимость Gen2?
C#
private readonly MemoryCache _cache = new(new MemoryCacheOptions
{
    SizeLimit = 10_000
});
// Каждая запись задаёт Size и срок жизни.
Вопрос 11 из 30
Что делает span.Slice(2, 3)?
C#
var data = new[] { 0, 1, 2, 3, 4, 5 };
Span<int> part = data.AsSpan(2, 3);
part[0] = 99;
Console.WriteLine(data[2]); // 99
Вопрос 12 из 30
Почему Span<T> нельзя хранить полем обычного класса?
C#
public sealed class Holder
{
    private Span<byte> _buffer;
}
Вопрос 13 из 30
Какой тип использовать для буфера, который нужно передать через await?
C#
async Task<int> ReadAsync(Memory<byte> buffer, CancellationToken token) =>
    await stream.ReadAsync(buffer, token);
Вопрос 14 из 30
Что даёт ReadOnlySpan<char> параметру парсера?
Вопрос 15 из 30
Почему нельзя вернуть Span<byte> на stackalloc из метода?
C#
static Span<byte> CreateBuffer()
{
    Span<byte> buffer = stackalloc byte[16];
    return buffer;
}
Вопрос 16 из 30
Гарантирует ли ArrayPool<byte>.Rent(1000) массив длины ровно 1000?
C#
var rented = ArrayPool<byte>.Shared.Rent(1000);
Console.WriteLine(rented.Length >= 1000);
ArrayPool<byte>.Shared.Return(rented);
Вопрос 17 из 30
Почему Return должен быть в finally?
C#
var buffer = ArrayPool<byte>.Shared.Rent(size);
try { Process(buffer.AsSpan(0, size)); }
finally { ArrayPool<byte>.Shared.Return(buffer); }
Вопрос 18 из 30
Когда нужен clearArray: true или ручная очистка?
Вопрос 19 из 30
Что опасно в возврате массива до завершения SendAsync?
C#
var rented = pool.Rent(length);
var sendTask = socket.SendAsync(rented.AsMemory(0, length), token);
pool.Return(rented); // слишком рано
await sendTask;
Вопрос 20 из 30
Когда ArrayPool не нужен?
Вопрос 21 из 30
Как найти типы, создающие больше всего мусора?
BashКоманда dotnet-trace
dotnet-trace collect --process-id 1234 \
  --providers Microsoft-Windows-DotNETRuntime:0x1C000080018:5 \
  --output allocations.nettrace
# Затем сгруппировать стеки аллокаций по типу и месту вызова.
Вопрос 22 из 30
Как проверить «парсер не выделяет память»?
C#
[MemoryDiagnoser]
public class ParserBench
{
    private readonly string text = "12345";
    [Benchmark] public int Parse() => Parser.Parse(text.AsSpan());
}
Вопрос 23 из 30
Что показывает рост heap при стабильном allocation rate после полных GC?
Вопрос 24 из 30
Как тестировать use-after-return для пула?
C#
var pool = new PoisoningArrayPool<byte>();
await sut.ProcessAsync(pool);
Assert.Equal(pool.RentCount, pool.ReturnCount);
Assert.False(pool.HasOutstandingBuffers);
Вопрос 25 из 30
Какие метрики памяти полезны в сервисе?
Вопрос 26 из 30
Когда Span-API оправдан в публичной библиотеке?
Вопрос 27 из 30
Как совместить удобство и производительность парсера?
C#
public static Result Parse(string text) => Parse(text.AsSpan());
public static Result Parse(ReadOnlySpan<char> text) { /* общий алгоритм */ }
Вопрос 28 из 30
Почему безлимитный кэш быстрее только сначала?
Вопрос 29 из 30
Как backpressure связан с памятью?
C#
var channel = Channel.CreateBounded<Job>(new BoundedChannelOptions(1_000)
{
    FullMode = BoundedChannelFullMode.Wait
});
Вопрос 30 из 30
Как оценить пользу ArrayPool в архитектуре?

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу