Как посчитать среднее арифметическое для последовательности чисел
Что проверяют
Задача простая, поэтому смотрят на детали: типы, пустой вход, переполнение и знание стандартной библиотеки. Следом обычно спрашивают, что вернёт ваш метод на пустой коллекции и почему именно так.
Как отвечать
Короткий ответ на C# это LINQ: numbers.Average(). Важно знать его поведение:
- для
IEnumerable<int>иIEnumerable<long>результатdouble, дляdecimalвозвращаетсяdecimal; - на пустой последовательности бросается
InvalidOperationException; - для nullable-последовательностей (
IEnumerable<int?>) значенияnullпропускаются, а на пустом входе возвращаетсяnullбез исключения.
Если просят написать вручную, покажите один проход: копите сумму и счётчик в одном цикле по IEnumerable<T>. Вызов Count() и Sum() по отдельности перечислит последовательность дважды, а для ленивого генератора или IQueryable это два обхода или два запроса к базе.
Тип суммы выбирайте с запасом: для int копите в long, результат делите как (double)sum / count. Для денег берите decimal, чтобы не ловить ошибки округления двоичной плавающей точки.
Контракт на пустой вход назовите явно: исключение, double.NaN или null. Любой вариант годится, если он задокументирован и покрыт тестом. Проверку аргумента удобно делать через ArgumentNullException.ThrowIfNull(numbers).
Чтобы показать уровень, упомяните generic math: начиная с .NET 7 можно написать один метод Average<T>(IEnumerable<T> xs) where T : INumber<T> для любых числовых типов. Для огромных последовательностей double скажите про накопление погрешности и суммирование Кэхэна.
Где спотыкаются
Делят int на int: sum / count с целыми даёт целое, и среднее для чисел 1 и 2 теряет дробную часть и становится 1.
Не знают разницы между целым и дробным делением на ноль: целочисленное деление бросает DivideByZeroException, а double при делении нуля на ноль тихо даёт NaN, который расползается по расчётам.
Копят сумму в int и не думают о переполнении. Арифметика в C# по умолчанию unchecked, поэтому сумма молча перейдёт через int.MaxValue в отрицательные числа. Спасают long, блок checked или сразу Average(), который для int внутри копит в long.