Содержание статьи
Парни из Parallels не зря пользуются уважением среди нашего брата программиста. Именно в этой компании придумали контейнерную виртуализацию (и уже реализовали возможность живой миграции контейнеров), сделали такой крутой и всемирно известный продукт, как Parallels Desktop для Mac, и научили смартфоны и планшеты под iOS и Android удаленно воспринимать десктопные приложения с Mac и ПК как нативные (Parallels Access).
Офис Parallels имеет все признаки «офиса мечты», тем более что именно там работают такие крутые специалисты, как технический советник Linux Foundation и мейнтейнер ядра Linux Джеймс Боттомли, создатель 90% стека TCP/IP в Linux Алексей Кузнецов, самый известный хакер 2000-х Алексей Смирнов, создатель Windows NT Марк Збиковски (кстати, сигнатура exe-файла, MZ, — это его инициалы. — Прим. ред.) и автор проекта CRIU Павел Емельянов. Если хочешь влиться в их стройные ряды — решай наши задачки! Между прочим, некоторые из них предлагают на собеседовании прямо сейчас :).
Какие Вакансии есть в Parallels?
Сейчас команда разработчиков активно расширяется (а все продукты с мировой известностью делают исключительно в России) — только в московском офисе открыто более 40 вакансий, причем практически во все команды. Больше всего нужны мобильные разработчики (iOS, Android), те, кто будет писать для ядра Linux, а также разработчики в команду облачной платформы Parallels Automation. Собеседования в Parallels редко длятся меньше часа (если меньше, можешь собраться и уйти — пазл не сошелся). Чтобы не терять этот час жизни, попробуй решить сначала их задачи. Все, кто пришлет правильные ответы, полу- чат лицензии на Parallels Desktop для Mac 10 и Parallels Access, а также, как предупреждают в компании, горячий интерес ее эйчаров и тимлидов. Хотя там смотрят прежде всего на логику решающих и опыт и могут нанять даже тех, кто задачи не решил, но чей ход мысли понравился.
Задачи на логику
С задачами на логику любят работать практически во всех командах — и тех, что работают с десктопной виртуализацией для конечных пользователей, и тех, что пишут коммиты для ядра Linux и решают задачи серверной виртуализации, и тех, что создают облачные платформы для сер- вис-провайдеров. Мы описали здесь только свои самые любимые.
Задача 1
Человек хочет пройти через туннель для поездов. Он начи- нает свой путь в начале туннеля и, когда проходит четверть пути, слышит, что сзади приближается поезд. Неизвестно, как быстро поезд едет и насколько он далеко. Известно только вот что:
- Если человек развернется и побежит назад, то он достигнет начала туннеля одновременно с поездом.
- Если человек побежит вперед, то конца туннеля он также достигнет одновременно с поездом
- Считай, что человек ускоряется мгновенно и бегает с постоянной и одинаковой скоростью в обе стороны туннеля, поезд также едет с постоянной скоростью.
Вопрос: насколько быстрее движется поезд по сравнению с человеком?
Задача 2
Крестьянину нужно перевезти через реку волка, козу и капусту. Но лодка такова, что в ней может поместиться только крестьянин, а с ним или один волк, или одна коза, или одна капуста. Но если оставить волка с козой, то волк съест козу, а если оставить козу с ка- пустой, то коза съест капусту. Сколько реше- ний имеет эта задача (нет, не одно ;). — Прим. ред.)?
Программные задачи
Задачи 3 и 4 проверяют знание POSIX-подсистем и то, как человек думает в ситуации, когда на кажущийся ему очевидным ответ собеседующий говорит, что этот ответ неверен.
Задача 3
Программа запускается в обычном терминале, без перенаправления потоков ввода/вывода.
#include <unistd.h>
#include <stdio.h>
int main()
{
printf("Hello");
fork();
return 0; }
Вопрос: что будет напечатано?
Задача 4
Программа запускается в обычном терминале, без перенаправления потоков ввода/вывода.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int pid;
void handler()
{
printf("%d\n", pid);
exit(0);
{
signal(SIGCHLD, handler);
pid = fork();
wait(NULL);
return 0;
}
}
int main()
Вопрос: что будет напечатано?
Задача 5
Сколько памяти занимает такая структура?
struct xx {
uint8_t a;
uint16_t b;
uint32_t c;
uint64_t d;
};
Задача 6
Примечание: вопросы типа «Какие функции для аллокации памяти вы знаете в ядре Linux?» или «Какие примитивы синхронизации в ядре Linux доступны для програм- миста?» не задает только ленивый. Их касаться даже неинтересно. Гораздо интереснее попросить человека построить уже известный примитив, не сказав о том, что он уже известен.
У вас есть некоторая система, которая должна обновлять некоторый счетчик (64-битный на 32-битной архитектуре) и технически не может выполнить операцию атомарно. Это обновление происходит очень часто и должно выполняться очень быстро, например в обработчике прерывания от устройства. Также известно, что это обновление может быть вызвано только на одном процессоре, то есть синхронизировать обновления между собой не надо. Использование стандартного спинлока реально замедляет систему и не подходит. Нужно развязать это изменение счетчика с его чтением, которое происходит а) редко, б) из контекста пользовательского процесса и может происходить относительно медленно.
Задача 7
int main() {
int i;
for (i = 0; i < 3; i++)
{
printf(".");
fork(); }
}
Вопрос: сколько точек будет выведено в терминале?
Читатели, шлите нам свои решения!
Правильные ответы присылай или мне, или сразу представителю компании, Ольге Русаковой, на orusakova@parallels.com.