company_banner

Подведение итогов конкурса самых странных заданий на собеседованиях



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

    Задание, которое прислали читатели


    Мы отобрали, на наш взгляд, самые интересные задания и вы можете провести их оценку. Мы не ограничивали количество примеров, поэтому некоторые пользователи привели сразу несколько.

    1. Пользователь с ником jakushev привёл два задания (первое и второе).
    Первое задание:
    Ну, не знаю, на сколько интересное, но абсолютно глупое задание:«Написать „Hellow, World!“ без единой ';' ». На Си.
    Второе задание:
    На «бареметалл» еще такое любят: Есть очень простой контроллер, с минимальным ОЗУ, допустим, PIC16F873, он «нюхает» RS-485. По интерфейсу передается пакет, состоящий из 32х битных чисел. Формат, начало и конец пакета известны, известно, что каждое число передается четное количество раз. Так же известно, что канал 100% надежен. А поток может быть ОЧЕНЬ длинный. Но 1 число из выборки передается нечетное количество раз. Как его найти?
    2. Пользователь с ником nick758 привёл следующую задачу:
    Задачка с собеседования. Что выведет программа? Решить без запуска. В тексте незначительные ошибки, чтобы сразу не скомпилировалось.

    Самая наркоманская задачка такого рода из тех, что я видел.

    float bon_jovi[4][4]=
     { {0,   2,    0.5,   2},
       {1,   3,    3 ,    0},
       {2,   0.5,  0,     1},
       {0,   0,    0,     0}
     }
    
    #define FIRST_SONG 3
    #define LAST_SONG 1
    #define CD 0
    #define ARTIST 1
    
    void f(float *p, int jazz, int hiphop)
    {
      int high_rating=0;
      int low_rating=high_rating
      int music;
      float sum=0.0;
    
      for (music = jazz; music <= hiphop; music++)
      {
          sum += *(p++)
          if ( p[music])
            high_rating++;
          else
            ++low_rating
      }
    
      p--;
      sum += *(--p)
    
      printf("%d %d %f", high_rating, low_rating, sum)
    }
    
    int main()
    {
      f(&bon_jovi[CD][ARTIST], LAST_SONG, FIRST_SONG)
    
      return 0;
    }
    3. Пример с собеседования от пользователя VolCh
    :

    • интерпретатор простого ЯП (подмножество паскаль кажется): переменные, арифметика,
    • задача на выявление рассинхронизации тактовых генераторов двух компьютеров с вымышленными(?) архитектурой и ассемблером с простейший одноранговой сеткой, скорее даже прямым соединением
    • удалённый лайвкодинг: написать и поднять простой CRUD на symfony без генераторов в докере (не помню Докер условием был или сам решил)
    • нарисовать грубую модель предметной области jira, нарисовать схему сервисов: серверы, сторы, очереди, СУБД и т. п.

    4. Пользователь iamdev95 привёл занимательную задачку:
    Есть два регистра: R1 и R2
    Есть две команды:
    C1: R1 := K*R2 — R1
    C2: R2 := K*R1 + R2
    Есть целевое число N
    На входе: K, N, R1, R2
    Нужно: распечатать минимальную последовательность из команд, позволяющую получить N в R1 или в R2 (в любом из двух регистров)
    Либо напечатать ничего
    Известно, что K != 0, R1 != R2, K, R1, R2 — натуральные, N — целое.
    5. Шуточная (но вполне реальная) задача от vadim_bv
    Задача из физтеховской шутки «решала вся кафедра, но к экзамену решила»: Отсортировать 8-терабайтный массив байтов.
    В ваших силах определить победителя! Голосуем за самое интересное задание на интервью. По результатам голосования победитель получит интересный приз! Результаты голосования подведём в воскресенье 11 октября.

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Кто привёл наиболее интересное задание на собеседовании

    • 30,9%Две задачи от @jakushev: вывести hellowold без ";"55
    • 15,7%Задание от @nick758: «что выведет программа»28
    • 7,9%Сложнейшие задачи от @VolCh: такое как «интерпретатор ЯП»14
    • 10,1%Занимательная задача с регистрами от @iamdev9518
    • 35,4%Шуточная задача с физтеха от @vadim_bv63
    RUVDS.com
    VDS/VPS-хостинг. Скидка 10% по коду HABR

    Комментарии 28

      +8

      Первое легко
      if (printf("hello")) {}
      А return 0; в некоторых компиляторах можно не писать

        +15

        Второе тоже элементарно — xor-им все и делов то. Любой системщик это сразу поймет.

          +3
          Не просто элементарно, а вполне адекватно.
          Было похожее задание на собеседовании, недоумения у меня не вызвало. Идея проверить знает ли кандидат битики и умеет ли их применять хотя бы на простом уровне.
            0

            Да, это очевидно с самого начала.


            "Мы говорим "чётное" — подразумеваем XOR,
            Мы говорим "XOR" — подразумеваем чётное!" ©

          +18
          Отсортировать 8-терабайтный массив байтов
          Сортируется за O(n) — надо завести массив из 256 счётчиков.
            0
            Если по логике задачи подходит, можно ещё и «псевдо-массив» сделать, чтоб память зря не занимать, и генерировать значение по индексу прямо в момент обращения.
              0
              Потеря скорости будет на обращении к каждому элементу.
              Тем более учитывая объем данных — маловероятно что там не встретятся ВСЕ 256 вариантов, а значит ваше решение на рандомных данных проиграет и по памяти и по скорости.
              Это, кстати, причина по которой не используется везде hashmap, и все таки часто используется обычный map. Хотя казалось бы — hashmap быстрее же в лучшем случае. Ну в лучшем случае да, быстрее. А в худшем — медленней.А map дает стабильно O(log(n))
                +3
                Ну всё-таки чтение, даже из оперативки — операция тоже не бесплатная, даже если опустить, что впихнуть в оперативу 8 терабайт одним куском — сильно не дешёвое удовольствие. А тут все данные помещаются в кэше, псевдо-выборка произвольного индекса делается бинарным поиском за максимум 9 if-ов, а итерация, считай, бесплатная.

                P.S. может мы о разном спорим, я то имел в виду для уже отсортированного массива, а не для исходного.
                +3
                это лол. вы вообще представляете себе как работают эти псевдо-массивы и какой там оверхед будет? как по скорости, так и по памяти ))
                  0
                  Не понимаю, что оверхедного может быть в вычислении на лету значения, которое должно вернуться по индексу из отсортированного 8-терабайтного псевдо-массива, когда мы имеем массив кол-ва значений каждого байта из 256 возможных?
                  0

                  Да что там "зря занимать"…
                  Чтобы адресовать 4G надо 32 бита. Для 8T, соответственно, 43. Если округлять до байтов — проще взять 6 (т.е. 48 бит), а значит, можно что 8T, что 128T шпарить одним и тем же кодом.
                  6 байт на 256 значений — 1.5К. Это не влезет в L1, но вроде как начиная с L2 будет прямо совсем шустро, не обращая внимания на "псевдо-массивное" обращение.
                  А по итогу да, считаем получившийся блоб окончательным, закодированным с помощью RLE.

                    0

                    Premature optimization. Кто Вам сказал, что "8-терабайтный массив" лежит в памяти, и для него вообще понадобится кэш? Может, он по телеграфному каналу приходит (только если бы это было сказано в условии задачи, то её решение было бы уж совсем очевидным).

                +3
                У меня свитер такой как на картинке есть
                0
                Решить без запуска. В тексте незначительные ошибки, чтобы сразу не скомпилировалось.

                Меня кстати подобного рада один раз спрашивали. Только не уточняли что ошибки там специально.
                Я начал читать код последовательно в слух, собираясь размышлять, но сразу как дошел до синтаксической ошибки сказал что не скомпилируется. :D Было слышно что чел расстроился, но настаивать на ответе не стал :D

                  0
                  По-моему, я не успел сказать, что оно не скомпилируется, собеседующий предупредил сразу, но я надеялся, что там какой-то простой ответ, типа UB (выход за граница массива), но нет в этом плане оказалось всё корректно.
                    0

                    А каков сценарий то?
                    Ну, допустим, не скомпилируется из-за пары пропущенных;
                    На примере без шаблонов и на пару десятков строчек — ну, я тупо скопипащу, запущу раз — поправлю первую ошибку. Запущу два — вторую.
                    Если ошибка буквально в каждой строчке — интуитивно допишу.
                    Цель то какая? Подозреваю, понять, сообразит ли кандидат, как решить задачу проще всего (т.е. не напрягая мозг). Запускать компиляцию в течение минуты и каждый раз править ошибки (сколько раз выйдет? Дважды? Пятирежды? Десятикратно?) — ок. Понять, что ошибка буквально в каждой строчке — проще на раз пройтись глазами.
                    Компилировать "в уме" весь пример — наверное, супер-гуру хотят нанять...

                      0
                      Цель, видимо, была узнать насколько быстро кандидат разберётся с этим кодом.
                      Не знаю, может я странный, но если мне сказали не запускать, то я запускать не буду. В целом, мой ответ на этот вопрос собеседующего удовлетворил, несмотря на то, что я ответил не до конца правильно.
                  +3

                  "Есть два регистра: R1 и R2
                  Есть две команды:
                  C1: R1 := KR2 — R1
                  C2: R2 := K
                  R1 + R2
                  Есть целевое число N
                  На входе: K, N, R1, R2
                  Нужно: распечатать минимальную последовательность из команд, позволяющую получить N в R1 или в R2 (в любом из двух регистров)
                  Либо напечатать ничего
                  Известно, что K != 0, R1 != R2, K, R1, R2 — натуральные, N — целое."
                  Какая злобная задачка. Понятно, что N просто так в машину не засунешь. Придется где-то отыгрывать это число, например, в количестве команд или их групп, стало быть надо искать операции инкремента и декремента ибо N может быть отрицательным. Тогда можно используя заранее заданные значения R1 R2 и K использовать их для зануления. И от этого уже отыграть N раз инкремент или декремент. Но если вчитаться в условие задачи внимательнее, то нам оставили возможность напечатать ничего вместо поиска программы. Так давайте же воспользуемся этой возможностью. Ответ "напечатать ничего".

                    +1
                    Строим дерево из троек {C,R1,R2}, где C — какая-то из команд. У каждого узла будет два подчиненных. R1 и R2 — значения, вычисленные из узла-родителя соответствующей командой.
                    Если R1 и R2 повторились, то для этого узла вычисления не продолжаем.
                    Далее нужно выяснить, будут ли последовательности R1,R2 постепенно убывать или возрастать. Если постепенность будет, то с какого-то числа, по модулю большего чем N (2N, 3N и т.п.), построение дерева можно прекратить. Т.о. получится конечное дерево. Если в нем не нашли N, то результат пустая строка. Если нашли, то цепочка узлов до корня дерева дает последовательность команд.
                    Но это наивные предположения. Точно доказать не могу, забыл уже математику.
                    +2
                    У меня похожий случай был — дали кусок реального кода с вопросом «что он выведет»? Я им говорю — «такое не скомпилируется 100%». Они — «мы знаем, но что он должен вывести-то?»
                      +1

                      Ну что… "syntax error..."
                      А под капотом разочарованные вздохи — не смогли усилить армию леммингов...

                        +1
                        Так «syntax error» выводит компилятор, а не рассматриваемый код.

                        А что код должен выводить и вообще делать — это по сути эквивалент «что хотел сделать кодер». И чтоб это узнать, надо залезть кодеру в голову, ведь сущности «что хотел сделать» и «что реально сделал» могут не совпадать. Хотя, конечно, какие-то предположения строить можно.

                        Другими словами, это «восстановите ТЗ по результату».
                      +1

                      Для справки: все "мои" задачи на Senior Backend (PHP) Developer. Там, где принимал в итоге оффер, ни интерпретаторов, ни синков тактовых компов и близко не было :) Но было интересно, в частности вспомнить теорию компиляторов, AST, обход его и т. п. — собственно один раз за 20 лет и пригодилась.

                        0
                        не очень понял, почему создание CRUD на symfony без генераторов попало в список?
                          0

                          Я их рекорд по скорости с учётом нюансов побил )

                        +1

                        На последнем вопросе в голову тут же пришла классика 2008 года:
                        https://bash.im/quote/394858


                        Именно после этой цитаты я решил, что однажды буду изучать перл. Но пока ещё это время не пришло.

                          +1

                          Вообще, "странными" тут являются задачи из третьей группы. Нафига такое спрашивать на собеседовании? Первая группа — синтаксис (и то скорее шуточная) и простой алгоритм, вторая — на чтение code flow, пусть и довольно извратная конкретно эта, кое-где нужно понимать, что выполнится сначала, что потом, четвертая, вообще говоря, на чтение ТЗ (конкретно эта, а алгоритм-то нетривиален, если решать в лоб), пятая — на сортировки типа count.

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое