Проходил интервью на юниора в http://verdiem.com. Собеседовали долго. Длинная сессия (4 часа) в понедельник и коротенькая в пятницу (сегодня).
Было пять человек и пять вопросов от каждого:
Понедельник
1. Обьяснить как мультипоточность поможет в создании интернет-краулера. Есть грубо говоря три функции
StorePage
ParsePage
DownloadPage
первые две срабатывают за 0 секунд, вторая за неопределенное время.
Нужно построить дерево и сохранить страницы. Я правильно подметил что иногда страницы пересекаются и поэтому второй раз грузить страницу не надо.
Но реально протупил в очень простом приложении многопоточности на однопроцессорной машине.
2. Найти проблему в
class A {};
class B : public A {};
class C : public A {};
class D
{
private:
A *ptr;
public:
};
и решить её.
Тупил первые 10 минут потом мне интервьювер дал пинок и я после повторного осмотра быстренько написал правильный ответ с использованием виртуального clone.
3. Написать алгоритм нахождения самого большого числа меньше чем некий X в правильном бинарном дереве. Легко
Пятница
4. а) написать класс матрицы с учетом того что матрица будет дико юзать память.
б) написать функцию умножения матриц
Легко но нудно ибо на доске и фломастером блин.
5. Развернуть linked list. АА!!! я с испугу принял linked list за doubly linked list и написал...
template<typename Data>
class element
{
public:
element<Data> *prev;
element<Data> *next;
Data _data;
};
... чем эффектно выпендрился юзая шаблоны :\ Однако написать prev в llist это позор
После назидательного "но-но" со стороны дяденьки я удалил к чертовым бабушкам prev и вспех написал на доске фломастером что-то типо такого:
void reverse(element *head)
{
element *curcopy;
element *temp;
element *headcopy = head;
curcopy = head; head->next = NULL;
while(curcopy)
{
//забыл
}
//забыл и не буду вспоминать ибо это решение ужасное и рекурсия рулит
}
и вроде все правильно.
Очень сложно было то что заставляли писать маркером на доске. У меня почерк ужасный и поэтому тяжело было "дебаггить".
А в целом понравилось. Первое интервью такого масштаба
Здравствуйте, chipsеt, Вы писали:
C>2. Найти проблему в C>
C>class A {};
C>class B : public A {};
C>class C : public A {};
C>class D
C>{
C>private:
C>A *ptr;
C>public:
C>};
C>
C>и решить её. C>Тупил первые 10 минут потом мне интервьювер дал пинок и я после повторного осмотра быстренько написал правильный ответ с использованием виртуального clone.
что за клон? что за проблема? при копировании Д указатель у копии будет указывать туда же куда и у оригинала? так деструктора вообще нету — т.е. почему бы и нет? ptr всё равно никогда не инициализируется, т.е. на объекты не будет указывать
я здесь не вижу никаких проблем, классы A,B,C — вообще пустые, какие тут проблемы? В отсутствии смысла?
Вы либо чего то не договариваете, либо сакральное знание "проблемы" таковым на самом деле не является.
C>void reverse(element *head)
C>{
C>element *curcopy;
C>element *temp;
C>element *headcopy = head;
C>curcopy = head; head->next = NULL;
C>while(curcopy)
C>{
C>//забыл
C>}
C>//забыл и не буду вспоминать ибо это решение ужасное и рекурсия рулит
C>}
C>
рекурсия не рулит, если список длинный(а предполагать обратное без веских обоснований по моему не логично), поскольку стек не резиновый.
Тем более, что если память не изменяет есть способ развернуть его вообще с константными требованиями по памяти.
Здравствуйте, dotidot, Вы писали:
D>Здравствуйте, chipsеt, Вы писали:
D>что за клон? что за проблема? при копировании Д указатель у копии будет указывать туда же куда и у оригинала? так деструктора вообще нету — т.е. почему бы и нет? ptr всё равно никогда не инициализируется, т.е. на объекты не будет указывать D>я здесь не вижу никаких проблем, классы A,B,C — вообще пустые, какие тут проблемы? В отсутствии смысла?
D>Вы либо чего то не договариваете, либо сакральное знание "проблемы" таковым на самом деле не является.
Не договариваю конечно Предполагаеся что в B и C есть некоторые данные а вот насчёт деструктора не помню. да! там предполагалось что нужно написать assignment operator с deep copy.
Здравствуйте, chipsеt, Вы писали:
C>Не договариваю конечно Предполагаеся что в B и C есть некоторые данные а вот насчёт деструктора не помню. да! там предполагалось что нужно написать assignment operator с deep copy.
а потом коммисия, наверное, долго хихикала, тыкая пальцем в доску и говоря, что у вас нету виртуального десруктора, и в delete ptr не вызовутся деструкторы подкласса, если он указывает на инстанс B или C.
Что интересно, про виртуальный деструктор спрашивают почти все. Но побывав по ту сторону интервью, я, с удивлением для себя, отметил, что почти никто на этот вопрос не может пролить свет и несут полную пургу.
Здравствуйте, dotidot, Вы писали:
D>Здравствуйте, chipsеt, Вы писали:
C>>Не договариваю конечно Предполагаеся что в B и C есть некоторые данные а вот насчёт деструктора не помню. да! там предполагалось что нужно написать assignment operator с deep copy. D>а потом коммисия, наверное, долго хихикала, тыкая пальцем в доску и говоря, что у вас нету виртуального десруктора, и в delete ptr не вызовутся деструкторы подкласса, если он указывает на инстанс B или C. D>Что интересно, про виртуальный деструктор спрашивают почти все. Но побывав по ту сторону интервью, я, с удивлением для себя, отметил, что почти никто на этот вопрос не может пролить свет и несут полную пургу.
Здравствуйте, shrecher, Вы писали:
S>Здравствуйте, dip_2000, Вы писали:
_>>(поскипано много кода) _>>Простите, это что с++ ?!
S>вы что думаете c++ это обязательно куча темплейтов, наследование и пр. Это не всегда нужно особенно для базовых алгоритмов.
Это не тот случай. У dotidot код сишный.
Даже для базовых типов на C++ пишут конструкторы и деструкторы, а не функции
makeList и deleteList.
S>Кстати, посмотрите в STL, там тоже полно pointer-ой арифметики.
Ну они же скрыты эти детали pointer-ой арифметики
и тот же vector имеет вполне нормальные конструкторы, деструктор и прочие методы.
а зачем для D виртуальный деструктор, если он сам ptr не создает/аллокирует и "A *ptr;" задан как private? Т.е. в принципе ничего в "A *ptr" положить нельзя.
Здравствуйте, bkat, Вы писали:
S>>вы что думаете c++ это обязательно куча темплейтов, наследование и пр. Это не всегда нужно особенно для базовых алгоритмов.
B>Это не тот случай. У dotidot код сишный. B>Даже для базовых типов на C++ пишут конструкторы и деструкторы, а не функции B>makeList и deleteList.
Ну это формализм. Как я понимаю, на собеседовании проверяют как человек мыслит с указателями и понимает как устроен список.
Здравствуйте, shrecher, Вы писали:
S>Ну это формализм. Как я понимаю, на собеседовании проверяют как человек мыслит с указателями и понимает как устроен список.
Фиг знает...
Указатели и внутреннее устройство списка вещь конечно важная,
но и продуманные интерфейсы классов вещь тоже не менее важная.
В общем не соглашусь с тем, что это формализм.
Просто это другой, не менее важный пункт.
А если на интервью человек вместо деструктора пишет функцию deleteList
вместо дектруктора, то как мне это понимать?
Понимать ли что человек понятия не имеет о деструкторах
или что он проженный сишник или что он решил приколоться над собеседующими и посмотреть на ихнюю реакцию?
Здравствуйте, bkat, Вы писали:
B>или что он проженный сишник или что он решил приколоться над собеседующими и посмотреть на ихнюю реакцию?
там вся соль в выделенном жирным шрифтом кодом. С конструкторами/деструкторами было бы намного больше и сложнее — здесь этого точно не надо.
Здравствуйте, chipsеt, Вы писали:
C>Проходил интервью на юниора в http://verdiem.com. Собеседовали долго. Длинная сессия (4 часа) в понедельник и коротенькая в пятницу (сегодня).
Простите за назойливость, а это вопросы действительно для юниорского уровня?
Здравствуйте, Alex Dav, Вы писали:
AD>Простите за назойливость, а это вопросы действительно для юниорского уровня?
По моему да. Они предполагают только знакомство с языком и фундаментальными структурами данных/алгоритмами.
Про краулер — тоже на общее понимание, хотя многопоточность и джуниор, на мой взгляд, не совсем совместимые вещи