Открыть список
Как стать автором
Обновить
EPAM
Компания для карьерного и профессионального роста

Квест от ЕРАМ: пять задач с собеседований по .NET

Блог компании EPAM.NETАлгоритмыMicrosoft SQL ServerC#
Recovery mode


До того, как прийти в ЕРАМ, я побывал примерно на 20 собеседованиях в питерских IT-компаниях, и во многих давали задачи. Я синтезировал свой опыт и придумал пять задач, которые похожи на те, что дают на онлайн-тестированиях и очных собеседованиях.

19-20 мая в Питере прошла конференция DotNext, где мы предложили участникам пройти квест, который и состоял из этих задач. Отвечая правильно на задачу, участник получал следующую.

С первыми тремя могут справиться джуниоры, им часто задают подобные вопросы на собеседованиях. Четвертую можно задать кому угодно, но я бы рассчитывал на специалистов уровня middle: далеко не все джуниоры разбираются в возрастаниях сложности алгоритмов.

С пятой задачей справились единицы. Ее сложность – не в том, чтобы вычислить, что будет в селекте (с этим как раз справились многие), а в том, чтобы найти следующее число в последовательности, а для этого требуются хорошие математические знания. Мне кажется, математическая база очень важна для программиста.

Участники конференции подходили и спрашивали, как решать задачи и где можно увидеть их полный список, и я пообещал, что опубликую их тут. Правильные ответы и комментарии спрятаны, чтобы те, кто увидит задачи впервые, смогли решить их без подсказок.

Итак, начнем.

1) Какой результат выведет на консоль данная программа?

    class Program
    {
        static void Main(string[] args)
        {
            var numbers = new int[] { 7, 2, 5, 5, 7, 6, 7 };
            var result = numbers.Sum() + numbers.Skip(2).Take(3).Sum();
            var y = numbers.GroupBy(x => x).Select(x =>
            {
                result += x.Key;
                return x.Key;
            });

            Console.WriteLine(result);
        }
    }

Ответ
56. Учитываем особенности LINQ. Двоичное представление: 111000.

Комментарий
Подобные задачи довольно часто дают на собеседованиях. Если говорить о квесте, то правильный ответ дали около 80% участников. Самая распространенная ошибка – люди не замечали, что здесь присутствует отложенное выполнение запроса. Почитать подробнее о нем можно вот тут.

2) Какой результат выведет на консоль данная программа?

    class Program
    {
        private static string GetNumber(int input)
        {
            try
            {
                throw new Exception(input.ToString());
            }
            catch (Exception e)
            {
                throw new Exception((int.Parse(e.Message) + 3).ToString());
            }
            finally
            {
                throw new Exception((++input).ToString());
            }

            return (input += 4).ToString();
        }

        static void Main(string[] args)
        {
            string result;
            try
            {
                result = GetNumber(1);
            }
            catch (Exception e)
            {
                result = e.Message;
            }

            Console.WriteLine(int.Parse(result) * 100);
        }
    }

Ответ
200. Учитываем специфику finally. Двоичное представление: 11001000.

Комментарий
Сам сталкивался с подобным вопросом на собеседовании. Если говорить об участниках квеста, правильно смогли ответить около 70%. Они оставляли отзывы и предложения, среди которых – уменьшить количество лишнего кода. Мы это обсудили и пришли к выводу, что все-таки лучше уменьшать читаемость кода для искусственного введения в заблуждение.

3) Какой результат выведет на консоль данная программа?

    class MagicValue
    {
        public int Left { get; set; }
        public int Right { get; set; }

        public MagicValue(int left, int right)
        {
            Left = left;
            Right = right;
        }

        public static void Apply(MagicValue magicValue)
        {
            magicValue.Left += 3;
            magicValue.Right += 4;
            magicValue = new MagicValue(5, 6);
        }

        public static void ApplyRef(ref MagicValue magicValue)
        {
            magicValue.Left += 7;
            magicValue.Right += 8;
            magicValue = new MagicValue(9, 10);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var magicValue = new MagicValue(1, 2);
            MagicValue.ApplyRef(ref magicValue);
            MagicValue.Apply(magicValue);

            Console.WriteLine(magicValue.Left * magicValue.Right);
        }
    }

Ответ
168. Учитываем особенности ref. Двоичное представление: 10101000.

Комментарий
Это очень популярный вопрос на собеседованиях. Я сам решал подобную задачу, наверное, на каждом втором. На эту тему можно почитать вот тут. Кстати, только 45% участников квеста смогли найти правильное решение. Зачастую ошибки были не в понимании принципа работы ref, а в математике.

4) Даны 9 функций. Каждой функции соответствует номер от 1 до 9. Расположите функции в порядке возрастания сложности, после чего подставьте 9 номеров отсортированных функций последовательно в формулу _ _ _ — _ _ _ + _ _ _ = «?». Напишите, чему равно «?».

1. $log⁡(log(N))$
2. $N^{2/9}$
3. $log(N)$
4. $N$
5. $3^N$
6. $900^{10000000}$
7. $N!$
8. $N^3$
9. $N*log(N)$

Ответ
1221. Двоичное представление: 10011000101.
Решение:
6. $900^{10000000}$
1. $log⁡(log(N))$
3. $log(N)$
2. $N^{2/9}$
4. $N$
9. $N*log(N)$
8. $N^3$
5. $3^N$
7. $N!$
6 1 3 — 2 4 9 + 8 5 7 = 1221

Комментарий
Такая задача реже встречается на собеседованиях, но это – хороший старт для тех, кто изучает сложности алгоритмов. Есть много ресурсов с формулами, и найти их просто. Кроме того, задачу можно решить «подстановкой» на бумаге. На собеседовании могут задать вопрос, связанный со сложностью некоторых алгоритмов, и здорово, когда ответ подкреплен общими знаниями. Если говорить о квесте, с задачей справились только 30% участников.

5) Пусть таблица carTable содержит следующие значения:
id model price
1 Nissan 1000
2 BMW 2000
3 Toyota 1000
4 Renault 2000
5 Peugeot 1000
6 Opel 2000

Результатом представленного ниже SQL запроса будет 2 значения — <1> и <2>.

;WITH someTable AS
(SELECT 1 val
UNION ALL
SELECT val + 1 FROM someTable WHERE val BETWEEN 1 AND 3)
SELECT carTable.price / SUM(CASE WHEN carTable.price = 1000 THEN 1 ELSE 2 END) / 250 AS result
FROM someTable
INNER JOIN carTable ON carTable.id = someTable.val
GROUP BY carTable.price
ORDER BY carTable.price ASC

<1> и <2> — это первые числа последовательности <1>, <2>, 6, 34, 270, <?>.
Найдите следующее число последовательности.

Ответ
2698. Двоичное представление: 101010001010.
Решение:
Результатом запроса будут числа 2 и 2 (BETWEEN даст выборку 1,2,3,4. Join сработает на первые 4 записи, GROUP BY их сгруппирует, SELECT вычислится как $1000 / (1 + 1) / 250 = 2$, $2000 / (2 + 2) / 250 = 2$. Последовательность вычисляется как $x_{n+1}=x_{n}*2*n - 2$, где $n$ – число уже полученных элементов.
Т.е.:
$2*2*1 - 2 = 2$
$2*2*2 - 2 = 6$
$6*2*3 - 2 = 34$
$34*2*4 - 2 = 270$
$270*2*5 - 2 = 2698$

Комментарий
Это, безусловно, самая сложная задача. С ней справились только 15% участников квеста.

Заключение


Спасибо всем, кто решал задачи, а особенно тем, кто смог дойти до конца! Было интересно читать ваши отзывы и комментарии. А те, кто внимательно читал условия и давал ответы в двоичной форме – вдвойне молодцы!

Фото взято из архива конференции DotNext.
Теги:C#.NETалгоритмы
Хабы: Блог компании EPAM .NET Алгоритмы Microsoft SQL Server C#
Всего голосов 45: ↑19 и ↓26 -7
Просмотры23K

Похожие публикации

Лучшие публикации за сутки

Информация

Дата основания
1993
Местоположение
США
Сайт
www.epam.com
Численность
свыше 10 000 человек
Дата регистрации
Представитель
vesyolkinaolga

Блог на Хабре