Привет, Хабр. Меня зовут Мария, я работаю в вебе с начала нулевых, то есть с засилья статичных HTML-страниц. С тех пор я освоила много новых технологий и прошла массу собеседований. Сегодня хочу поделиться опытом: что спрашивают у JS-джунов и какие тестовые дают при приёме на работу.

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

Мария Кожанова

Программист и преподаватель

Как проходят собеседования

Собеседования на должность js-программиста, как правило, включает в себя несколько этапов. Обычно первое собеседование проходит с HR, который читает вопросы, составленные техническим специалистом. Никоим образом не хочу обидеть специалистов по подбору персонала, они здесь выступают первичным фильтром. Такая беседа может пройти и по телефону или мессенджеру без видео. Обычно предупреждают, что разговор записывается.

Второе собеседование, если оно будет, уже проводят с участием технарей. Если был опыт работы, просят описать проект. Без конкретики, конечно, все знают про NDA. 

Вполне возможно, что следующий этап — разговор с людьми, которые принимают решение, нанять специалиста или нет. Но иногда это не требуется, о результатах интервью вы узнаёте по факту. Я не очень люблю эти беседы о жизни, но понимаю, зачем они нужны. Однажды в крупной компании было как раз три этапа, но начальник отдела встретился со мной на втором интервью. По результатам собеседования мне не захотелось там работать по многим причинам. Но было интересно, что будет на техническом этапе. Там было жарко, целый час задавали вопросы из разных сфер, не всегда у меня был готов ответ.

Но часто небольшие компании не хотят тратить время. Тогда на первом собеседовании кандидата уже встречают технические люди, потенциально будущие коллеги и начальники.

Технический этап: какие вопросы задают чаще всего

На собеседовании обязательно просят привести пример того, чем занимались. Один раз спросили про самую сложную задачу, которую доводилось решать. Это почему-то стало самым сложным вопросом. 

Ещё спрашивают про знания фреймворков. Если ответить про jQuery, то следующий вопрос — из «взрослых» с какими имели дело? Под «взрослыми» хотят услышать: Angular, React, Vue. Причём «имели дело» зачастую для начинающих значит, что вы просмотрели видеокурс или только начали изучать. Это нормально. Потому что странно требовать от джуниора доскональных знаний и опыта — какой он тогда джуниор? Опыт приходит с ковырянием в реальном проекте параллельно с настойчивым гуглением, желательно не только на русском. Особо можно выделить, что видеокурс или ресурс для обучения не на русском языке, вы знаете английский как минимум на уровне, пригодном для чтения документации или понимания технических слов.

Иногда звучат вопросы про стрелочные функции. Это, думаю, каждый, кто начинал систематизировать свои знания по JS, уже знает, выучил назубок. Ещё про нативный Javascript любят поговорить: как на нативном Javascript обратиться к элементам DOM-страницы? А к конкретному? А по тегам?

Если вам задали вопрос, на который не знаете ответа, описывайте, как будете искать решение: «Ответ на этот вопрос можно найти в поиске по таким-то словам». В наше время нет необходимости держать в голове всё. Надо знать, как найти информацию, как сформировать запрос, как отделить искомое знание от мусора и рекламы. Главное — показать, что подобные ситуации вас не пугают. Узнавать новое — норма жизни. Поэтому обычная практика — с первого дня работы в компании приставлять к сотруднику опытного ментора, которому новичок адресует непонятные вопросы, на которые гугл не ответил.

Странные вопросы тоже встречаются. Однажды поинтересовались, зачем я изучаю Python (действительно, зачем). Собеседование было на вакансию, не связанную с этим языком, но в резюме в разделе хобби было указано про Python. Но компании нужна была рабочая лошадка, идущая по колее должностных обязанностей. Так что той стороне увлечение показалось необычным. Вообще, странные вопросы — это главные вопросы собеседования. Они говорят многое о задающих.

Есть некоторые закономерности между тем, что говорилось в вакансии, и тем, что будет на собеседовании. Обращение на ты — определённо маркер. Если ты вы вчерашний студент, возможно, вам не режет глаз подобная фамильярность в тексте вакансии. Людям, разменявшим четвёртый или пятый десяток, скорее всего, следует насторожиться. Хотя они сделают это и без моей подсказки. Также преимущества типа «корпоративные мероприятия» не должны пройти мимо людей-интровертов. Бонусы в виде печенек — подумайте, вам это нужно? Может, лучше деньгами?

Тестовые задания для джуниоров и как их решать

Часто встречаются тестовые, особенно для начинающих специалистов. Тестовое для джуниора — это хороший способ понять, как кандидат мыслит и что делает в ситуации, когда ответ не лежит на поверхности. Ничего страшного, если кандидат чего-то не знает. Страшно, если он пугается или не пытается узнать.

Тестовое задание иногда пишут прямо в вакансии, иногда предлагают выполнить прямо на собеседовании, но могут выдать и после первого собеседования, чтобы сделать его дома.

Часто это задачки вроде «что получится при исполнении следующего кода». В таких случаях дело не в самом коде. Подобные задания довольно простые, подвох может быть в том, что в условиях встречаются опечатки, которые приведут к ошибке кода, и надо их найти. Либо хитрость в том, что какая-либо переменная может быть не определена в указанной области, что тоже может вести к ошибке. Вот несколько примеров, найденных поиском, на которых можно потренироваться.

  1. К чему приведёт выполнение кода:

    <script>
        function myfunc(x, y, z) {
          arguments[1] = 123;
          console.log(y);
        }
        myfunc(1, true, 100);
        </script>

    Ответ: объект arguments, с которым происходит работа внутри функции myfunc, представляет собой массив, содержащий аргументы, переданные в функцию (об этом несложно догадаться из его названия). В результате выполнения данного кода в консоли появится 123. В теле функции происходит замена значения второго аргумента (y), поэтому его значение станет 123.

  1. К чему приведёт выполнение кода:

    <script>
        const myarray = [0, 1, 2, 4, 6, 19, 25];
        const [myconst] = myarray;
        console.log(myconst);
        </script>

    Ответ: здесь во второй строке для myconst произведено деструктурирующее присваивание. Это значит, что мы можем взять сразу ряд переменных и сопоставить им значения некоторого массива. В данном случае аргумент у нас один, и в результате в консоли выведется значение первого аргумента массива myarray, то есть 0.

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

  1. К чему приведёт выполнение кода:

    <script>
        function person(firstName, lastName) {
          function printPerson() {
            return firstName + " " + lastName;
          }
          console.log( "Hi, " + printPerson() );
        }
        person('Petr', 'Ivanov')
        console.log( "Bye, " + printPerson() );
    </script>

    Ответ: сначала консоль выведет строку Hi, Petr Ivanov. Далее выполнение функции person() завершено, но неугомонный кодер решил вызвать функцию, которая определена внутри другой функции, а снаружи не видна. Поэтому на второй строке он закономерно получит ошибку, возникающую при обращении к несуществующей переменной.
    Uncaught ReferenceError: printPerson is not defined

Ещё встречаются вопросы, которые заставляют вспомнить, как переменные различных типов ведут себя в разных обстоятельствах.

  1. Что произойдёт при выполнении кода:

    <script>
    console.log( 1 / 0 );
    </script>

    Ответ: выведется Infinity (бесконечность — это особое значение, которое больше любого числа).

  2. В чём отличие null от undefined?

    <script>
        let param;
        console.log(param)  // выведется undefined
    </script>

    Null — это специальное значение, которое означает «пусто» или «значение неизвестно».

    <script>
        let param = null;
        console.log(param)  // выведется undefined
    </script>
  1. Что произойдёт при выполнении кода:

    <script>
        console.log(false == undefined);
        console.log(false == null);
    </script>

    Ответ: в консоли выведется два раза False. Знак == проверяет равенство, но не идентичность типов.

Отдельно могут быть вопросы про откладывание выполнения функций.

  1. Что произойдёт при работе кода (по слухам, такие вопросы задают при собеседовании в Google или Amazon):

    <script>
        const arr = [10, 12, 15, 21];
        for (var i = 0; i < arr.length; i++) {
          setTimeout(function() {
            console.log('Index: ' + i + ', element: ' + arr[i]);
          }, 3000);
        }
    </script>
    

    Ответ: четыре раза выводится одна и та же строка.

    Index: 4, element: undefined

    Это произойдёт потому, что в цикле 4 шага, на каждом шаге происходит откладывание функции на 3 секунды. Когда придёт пора выполнять функцию, значение i будет равно 4 (таким оно стало на выходе из цикла). Соответственно, элемент массива arr с таким индексом не определён, поэтому будет указано значение undefined. И так 4 раза!

  2. Что произойдёт, если в предыдущем примере заменить setTimeout на setInterval?
    Ответ: всё то же, но каждые 3 секунды будут выводиться эти 4 строчки заново.

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

<script src="script_0.js"></script> 
<script async src="script_1.js"></script>
<script defer src="script_N.js"></script>

Ответ: тут следует обращать внимание на атрибуты async, defer. Как только при загрузке страницы дело доходит до этого тега script, система сначала должна его подгрузить и выполнить. Если есть атрибут async, то кто раньше встал, того и тапки, то есть какой скрипт загружается раньше, тот и сработает. Что касается defer,  то такие скрипты смиренно ждут загрузки всей страницы и отрабатывают в порядке того, как расположены в документе.Ответ: тут следует обращать внимание на атрибуты async, defer. Как только при загрузке страницы дело доходит до этого тега script, система сначала должна его подгрузить и выполнить. Если есть атрибут async, то кто раньше встал, того и тапки, то есть какой скрипт загружается раньше, тот и сработает. Что касается defer,  то такие скрипты смиренно ждут загрузки всей страницы и отрабатывают в порядке того, как расположены в документе.

Несомненно, большим плюсом станет размещение решения тестового в Github со ссылкой на репозиторий. Независимо от того, знания каких технологий проверяются. Очень хорошо не только знать, что бывает VCS (Version Control Systems, системы контроля версий), но и уметь выполнять базовые команды: взять ветку из репозитория, создать новую ветку, сделать коммит, отправить в репозиторий, решить конфликты. Хотя бы на пальцах объяснить, что такое конфликт и в чём он проявляется. Также работа с командной строкой не должна ввергать человека в ужас. Все эти модные сборщики фронта требуют работы в командной строке. Обычно тестовые не оплачиваются. С платным тестовым я встретилась один раз, в тот момент это оказалось очень кстати. До сих пор думаю, как бы мне там работалось, но выбрала другого работодателя.

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

Как готовиться к собеседованию

Очевидно — повторить основы и быть готовым к тому, что собеседований в вашей жизни будет ещё очень и очень много. Даже если всё прошло плохо, вы узнаете, что изучить и где подтянуться.

Комментарии (20)


  1. EreminD
    24.05.2022 16:29
    +2

    Что-то, при копировании текста, жестко поехало у вас все...


    1. EreminD
      24.05.2022 16:30
      +3


      1. blognetology Автор
        24.05.2022 21:49

        Верно, дублируется код. Исправляем.


    1. blognetology Автор
      24.05.2022 21:49

      Да, поплыло, к сожалению. Исправляем.


  1. Suvitruf
    24.05.2022 17:00
    +1

    Ответ: объект arguments, с которым происходит работа внутри функции myfunc, представляет собой массив, содержащий аргументы, переданные в функцию (об этом несложно догадаться из его названия). В результате выполнения данного кода в консоли появится 123. В теле функции происходит замена значения второго аргумента (y), поэтому его значение станет 123.
    Вы или не тот код скопировали, либо не тот текст.


    1. blognetology Автор
      24.05.2022 21:49

      Не тот код. Дважды один код оказался в вёрстке.


  1. GavrilovArtem
    24.05.2022 17:05

    Первая задача - описание перекочевало под вторую задачу.
    Код второй и третьей задачи дублируется.



    1. blognetology Автор
      24.05.2022 21:59

      Да, что-то пошло не так (всё).


  1. lavrok
    24.05.2022 17:05

    Что-то вы немного напутали ????

    Второй ответ от первого задания, код во втором и третьем задании одинаковые


    1. blognetology Автор
      24.05.2022 22:00

      К сожалению, напуталось много. Исправляемся.


  1. zavod008
    24.05.2022 17:05

    "К чему приведёт выполнение кода", проверьте блоки, там явно что то не то с порядком и как я понял дублирование кода.


  1. AlexeyPotopakhin
    24.05.2022 17:05

    Примеры кода в №2 и №3 повторяются, а ответ на задачу от №1 в №2, а №2 в №3. Далее сбивается нумерация задач.


  1. vkompaniec
    24.05.2022 17:05
    +3

    прочитав первый вопрос и ответ на него - подумал сначала что что-то кардинально поменялось и пора уходить из профессии :)


  1. Alexandroppolus
    24.05.2022 18:59

    В чём отличие null от undefined?

    Странный вопрос и ответ к нему. Отличий несколько, например, у них разный typeof, а JSON.stringify({a: null, b: undefined}) потеряет значение undefined, и т.д.


  1. nochkin
    24.05.2022 20:00

    Несомненно, большим плюсом станет размещение решения тестового в Github со ссылкой на репозиторий. Независимо от того, знания каких технологий проверяются.

    Например, знание что такое NDA и как происходят утечки кода.


  1. Mikola-BLR
    24.05.2022 23:24
    +3

    console.log(false == undefined);

    console.log(false == null);

    Ответ: в консоли выведется два раза False. Знак == проверяет равенство, но не идентичность типов.

    ИМХО, тема не раскрыта, т.к. в данном случае что ==, что === даст один и тот же результат - false.


  1. DaraDari
    25.05.2022 05:18
    +1

    А какой вариант прохождения собеседования для вас наиболее предпочтителен: техническое интервью в один этап или несколько этапов?


  1. alexshipin
    25.05.2022 08:22

    Первый вопрос у начинающих как раз вызовет вопрос: а от куда вообще взялась переменная arguments? (https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/arguments)

    <script>
    let param = null;
    console.log(param) // выведется undefined
    </script>

    Данный код выведен null. Вы создали переменную param и дали ей значение, равное null.


  1. Moon1ight4
    25.05.2022 08:57

    <script>
    let param = null;
    console.log(param) // выведется undefined
    </script>

    С какого перепуга выведется undefined ? null и выведется


  1. amberv
    25.05.2022 14:48

    Штуку с arguments реально кто-то спрашивает? Там ведь в реальности ответ «как повезёт. В strict mode код выдаст ошибку». То есть, в нормальном реальнос проекте такое просто невозможно провернуть.