Pull to refresh

Стрёмное собеседование в Яндекс

Reading time3 min
Views92K
Находит меня хеадхантерша из другой страны и предлагает попробовать пройти собеседование в Яндекс. Работы почти нет, зарплаты, судя по рассылкам, там большие. Немножко не тот профиль вообще, но в частности в требуемой теме полгода опыта есть. Сказала, что там задачи решать.

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

Реализованная задумка скорее всего получалась бы такой:

struct list
{
    struct list* next;
    int my;
};

list* joint(list* a, list* b)
{
    list fst = { a }; list scd = { b }; list trd = {0};
    list* res = &trd;
    while (fst.next || scd.next) {
        int ref = 0;
        list* dst = 0;
        bool flg = 0;
        for (list* src = fst.next? &fst:&scd; src->next; src = src->next->next || flg? src->next : (flg = 1, &scd) ) {
            if (src->next->my > ref) {
                ref = src->next->my;
                dst = src;
            }
        }
        res->next =  dst->next; 
        dst->next = res->next->next;
        res = res->next; 
    }
    return trd.next;
}

Сразу скажу, что писать так нельзя (или можно для себя, какой-нибудь тест).

Вкратце было так: мне дан какой-то неудобный вебовский редактор, с подсказками и подсветками не в тему. Плюс переговариваюсь я на маке и там не программирую. Много опечаток, раздражаюсь.
Интуитивно хочу поменьше писать и поместить все в два цикла (из соображений сложности алгоритма).
Смастерив тот вложенный for(для двух списков разом), я выдаю замечание, что суть задачи неадекватна предложенной форме исполнения. На что получаю ответ, что он, опытный мастер, наблюдая за моими руками, никакой осмысленности в моем черновом коде не видит. И предлагает на этом завершиться.
Выбесило, но что есть, то есть. Над задачей стоило подумать прежде, чем начать что-то писать. Там все просто, этот for надо дублировать для каждого из списков, пренебрегая тем, что дублируется и тело цикла один к одному. В процессе дальнейшего кодирования, возможно, я бы это увидел, но это сослагательное наклонение.

Правда, остаются вопросы.

Человек из Яндекса не может прочесть код с оператором “запятая”? В чем глубокий смысл требовать написать код в крайне неестественных условиях (без компилятора и в неиспользованном ранее редакторе)? Не предложив изначально оценить трудоемкость, не давая время на дизайн в минимальной форме? Я вот играю в блиц на класс ниже, чем в обычные шахматы — в Яндекс нужны скорострелы?

Короче, кто туда собирается, должен иметь эти вещи ввиду. Хорошо оплачиваемые работы всегда с каким-нибудь подвохом, им выбраковывать много кандидатов надо :)

PS: 29.12 Не могу отвечать в комментах, в свое впемя был забанен (за программисткий разбор писания:), разбанили — статья в неделю, коммент в день(даже на свою статью). Не суть.
Откликаюсь под катом:
про код как надо
Разговор у многих выходит на требования, где додумываются дополнительные. Но фактически в таких оказиях требование одно — время. Я даже узнал здесь (и соглашусь), что не обязательно, что бы работало (но себе к сожалению при собеседовании ставил).
Да, практически трое спросили некий код «как надо». Тоже надо понимать, что правильных кодов не бывает, код зависит от требований. Интервьюер не ставил и не мог ставить цели читабельности с таким временем, с таким подходом и инструментарием. Форумская общественность ставит — я уже писал про запатченный bool-ем for, который интервюер не понял. Разлагаю его на два цикла + читаемые имена.
Не сильно тестированный вариант:
struct list
{
    struct list* next;
    int my_number; 
};

list* joint(list* a, list* b)
{
    list pseudo_headers[] = { {0}, {a}, {b} }; // trick: first element of array is [pseudo]header of result list
    list* res_ptr = &pseudo_headers[0];
    while (pseudo_headers[1].next || pseudo_headers[2].next) {
        list* ahead_max;
        int cur_max_data = 0;
        for (int i = 1; i < sizeof(pseudo_headers)/sizeof(pseudo_headers[0]); i++) {
            for (list* ahead = &pseudo_headers[i]; ahead->next; ahead = ahead->next) {
                if (ahead->next->my_number >= cur_max_data) {
                    cur_max_data = ahead->next->my_number;
                    ahead_max = ahead;
                }
            }
        }
        res_ptr->next =  ahead_max->next; 
        ahead_max->next = res_ptr->next->next;
        res_ptr = res_ptr->next; 
    }
    return pseudo_headers[0].next;
}

Tags:
Hubs:
Total votes 154: ↑68 and ↓86-18
Comments235

Articles