За свою карьеру в Сбере я провел около 35 интервью со студентами старших курсов, которые пытались попасть на стажировку. Из них мы взяли всего 5 человек.

Почему так получилось?

Не сказал бы, что ребята совсем были непригодны, а скорее наоборот. Полный отказ (не подходит нам и другим) получали примерно 30%. Остальные сортировались по рейтингу, который формировал я сам для личного удобства. Из одной сессии на 10 человек “финалистами” становились 1-2 человека с первых мест, которых брали на стажировку, хотя талантливых и достойных было примерно 7 из 10.

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

Начинаем интервью

Интервью с одним кандидатом занимает примерно 30-40 минут. Это достаточно мало, поэтому я имею четкий план:

  1. Получить общее представление о человеке и его опыте (5 мин)

  2. Знания JavaScript и CSS (20 мин)

  3. Задача (10 мин)

  4. Ответы на вопросы кандидата (5 мин)

Общее представление о человеке

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

Обычно со стажера нечего взять: у него нет опыта, нет понимания о процессах работы, что вообще делают программисты в крупных компаниях. И это нормально! Если человек говорит, что сейчас учится на 4 курсе и не имел никакого опыта, то это ок. Такие факты не поставят его ниже того, кто успел где-то подработать, что-то на фрилансе сделать и т.д.

Но. Всегда важно послушать про домашние проекты (туду листы, мессенджеры, чат-боты, дипломные проекты на React и прочее). Чем больше у вас такого опыта, тем лучше!

Я могу спросить про технологии, которые использовались в этих проектах (React, Redux, Vue, TypeScript, Node.js, styled-components, SCSS и т.д). Буквально пару минут, не углубляясь в точные вопросы. Ваша заинтересованность в изучении различных инструментов показывает, что вы выбрали фронтенд-направление осознанно и уже проделали огромную работу над собой, чтобы скрестить инструменты вместе и выдать работающий прототип чего-либо.

Знание языка JavaScript

Это один из самых главных этапов. Не секрет, что JavaScript – это основной инструмент фронтенд-разработчика. Поэтому вы обязаны его знать, а также уметь применять в решении прикладных задач. Попробуем разобрать сейчас какие именно темы нужно знать. Я приведу для примера по несколько вопросов из каждой темы. Сами темы примерно остаются такими же, но вопросы могут меняться, потому что некоторые ребята возвращаются в новый сезон стажировок, если не получилось предыдущий раз.

Тема 1: Общее понимание особенностей языка

☝️ Что будет храниться в следующих переменных?

const var1 = true || false;
const var2 = true && false;
const var3 = 1 && 2;
const var4 = 1 || 2;
const var5 = 0 || 1;
const var6 = '1' + '2';
const var7 = '1' + 2;
Ответ
console.log(var1); // true
console.log(var2); // false
console.log(var3); // 2
console.log(var4); // 1
console.log(var5); // 1
console.log(var6); // '12'
console.log(var7); // '12'

Тема 2. Переменные и области видимости

☝️ Каким ключевыми словами можно объявить переменные?

Ответ

var, let, const

☝️ В чем различия этих ключевых слов?

Ответ

var:объявляет переменную, инициализация переменной значением является необязательной

let: объявляет локальную переменную, инициализация переменной значением является необязательной.

const: объявляет именованную константу, доступную только для чтения

☝️ Какая область видимости у переменных в js?

Ответ

У var функциональная или глобальная область видимости. У let и const блочная

☝️ Что будет в результате выполнения следующего кода?

var test1 = 2;

function fn1 () {
  var test1 = 3;
  console.log(test1);
}

fn1();
console.log(test1);
Ответ
3
2

Так как у переменной с ключевым словом var блочная или глобальная область видимости, то var test1 = 2 инициализируется в глобальной области видимости, а var test1 = 3 в функции fn1, не перезатирая первую переменную.

☝️ Что будет в результате выполнения следующего кода?

var test1 = 2;

if (true) {
  var test1 = 3;
  console.log(test1);
}

console.log(test1);
Ответ
3
3

Здесь же переменная с ключевым словом var пропускает блочную область видимости, поэтому она переопределяется в блоке if.

☝️ Как сделать так, чтобы переменные из кода выше были изолированны в своей области? В глобальной области осталось 2, а в блоке if было 3?

Ответ

Достаточно просто заменить var на const или let. Тогда переменные будут изолированы в своей области видимости.

const test1 = 2;

if (true) {
  const test1 = 3;
  console.log(test1);
}

console.log(test1);

Тема 3. Контекст

☝️ Что будет в контексте this?

function Person () {
  console.log(this);
}

const person1 = new Person();
const person2 = Person();
Ответ
{}
window

В первом console.log() будет выведен пустой объект, потому что конструктор создает новый экземпляр и ссылается на него в this. А в случае вызова без ключевого слова new контекст this будет ссылаться либо на глобальный контекст, либо будет undefined в строгом режиме.

Тема 4. Замыкания

☝️ Что такое замыкание?

Ответ

Замыкание — это комбинация функции и лексического окружения, в котором эта функция была определена. Другими словами, замыкание даёт вам доступ к Scope (en-US) внешней функции из внутренней функции. В JavaScript замыкания создаются каждый раз при создании функции, во время её создания.

https://developer.mozilla.org/ru/docs/Web/JavaScript/Closures

☝️ Допишите функцию так, чтобы можно было получить количество вызовов метода add

function myMath () {
  // можно добавлять внутри этой функции что угодно
  return {
    add: function (a, b) {
      return a + b;
    },
		getNumOfCalls: function() {},
  };
}

const math = myMath();

math.add(2, 3);
math.add(1, 2);
math.add(4, 1);

const numOfCalls = math.getNumOfCalls();
console.log(numOfCalls); // 3
Ответ
function myMath () {
  let count = 0;
  return {
    add: function (a, b) {
      count ++;
      return a + b;
    },
    getNumOfCalls: function () {
      return count;
    },
  };
}

const math = myMath();

math.add(2, 3);
math.add(1, 2);
math.add(4, 1);

const numOfCalls = math.getNumOfCalls();

console.log(numOfCalls); // 3;

Здесь просто создается локальная переменная, которая недоступна снаружи функции myMath.

Тема 5. Event loop

☝️ Что код выведет в консоли?

setTimeout(() => {
  console.log('Таймаут');
}, 0);

let p = new Promise((resolve, reject) => {
  console.log('Создание промиса');
  resolve();
});

p.then(function(){
  console.log('Обработка промиса');
});

console.log('Конец скрипта');
Ответ
Создание промиса
Конец скрипта
Обработка промиса
Таймаут

CSS

☝️ Какие способы позиционирования знаешь?

Ответ

absolute - указывает, что элемент абсолютно позиционирован, при этом другие элементы отображаются на веб-странице словно абсолютно позиционированного элемента и нет. Положение элемента задается свойствами left, top, right и bottom, также на положение влияет значение свойства position родительского элемента. Так, если у родителя значение position установлено как static или родителя нет, то отсчет координат ведется от края окна браузера. Если у родителя значение position задано как fixed, relative или absolute, то отсчет координат ведется от края родительского элемента.

fixed - по своему действию это значение близко к absolute, но в отличие от него привязывается к указанной свойствами left, top, right и bottom точке на экране и не меняет своего положения при прокрутке веб-страницы.

relative - положение элемента устанавливается относительно его исходного места. Добавление свойств left, top, right и bottom изменяет позицию элемента и сдвигает его в ту или иную сторону от первоначального расположения.

sticky - относительно позиционированный до тех пор, пока содержащий его блок не пересечёт указанный порог (например, установка top в значение, отличное от auto) внутри его корня потока (или в контейнере, в котором он прокручивается), после чего он обрабатывается как «застрявший» до тех пор, пока не встретит противоположный край содержащего его блока

static - элементы отображаются как обычно. Использование свойств left, top, right и bottom не приводит к каким-либо результатам.

inherit - наследует значение родителя.

https://developer.mozilla.org/ru/docs/Web/CSS/position

Задача

Это второй основной этап после знаний языка. Здесь кандидату необходимо решить алгоритмическую задачу с написанием кода решения (желательно на JavaScript).

☝️ Представьте, что в js нет методов сортировки массивов. Попробуйте написать функцию самостоятельно.

function sort(arr) {
  // написать код
}

const arr = [3, 2, 6, 1, 5];
sort(arr);

console.log(arr); // [1, 2, 3, 5, 6]
Решение
function sort(arr) {
  for (let j = arr.length - 1; j > 0; j--) {
    for (let i = 0; i < j; i++) {
      if (arr[i] > arr[i + 1]) {
        [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]];
      }
    }
  }
  return arr;
}

const arr = [3, 2, 6, 1, 5];
sort(arr);

console.log(arr); // [1, 2, 3, 5, 6]

У нас есть 2 вложенных цикла. Каждый раз, когда мы выполняем итерацию, верхняя граница уменьшается на единицу.

Многие на задаче из примера выше вспоминают про пузырьковый метод. Но смысл задания не в знании известных алгоритмов. Можно решить своим любым способом. Здесь оценивается несколько вещей:

  • человек рассказал как должен работать алгоритм по шагам

  • человек написал код алгоритма

  • код запускается и работает

  • человек сам нашел свои ошибки или смог оптимизировать алгоритм

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

Оценка кандидата

На основании всех этих этапов может появиться табличка, которая будет состоять из нескольких полей:

  • Имя

  • Общее понимание особенностей JS (0-10 баллов)

  • Область видимости (0-10 баллов)

  • Контекст (0-10 баллов)

  • Замыкания (0-10 баллов)

  • Event Loop (0-10 баллов)

  • CSS( 0-10 баллов)

  • Задача (0-50 баллов)

  • Общее впечатление

Содержание этой таблички может меняться от серии к серии. Главное, чтобы она будет одна в одной серии собеседований и по ней просто сравниваются кандидаты между собой.

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

Итог

Подведем небольшой итог! Вы практически со стопроцентной вероятностью пройдете на стажировку, если будете соблюдать следующие советы:

  1. Будьте уверены в себе - не сомневайтесь в себе, говорите уверенно, не производите впечатление будто вы пытаетесь угадать ответ

  2. Изучите как работает JS - прочитайте несколько книг по JavaScript и попробуйте поприменять новые знания на практике

  3. Познакомтесь с основными свойствами CSS - фронтенд разработчик не может существовать без знаний CSS, иначе он будет пытаться все решить через JS. Верстайте больше, делайте компоненты, сетки, изучите для примера как сделан Bootstrap и следуйте принятым стандартам

  4. Научитесь решать алгоритмические задачи - решайте, решайте и решайте больше задач

  5. Расширяйте кругозор - развивайтесь, читайте статьи, эксперементируйте, делайте домашние проекты. Обязательно попробуйте поработать с одной из популярных библиотек (советую React или Vue)

А дальше дело за вами. Стажировка – это отличный шанс начать карьеру сразу в крупной компании. Всем удачи!

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


  1. Zibx
    31.01.2022 16:16
    +1

    5 из 35 — это великолепная конверсия при поиске разработчиков.


  1. Metotron0
    31.01.2022 17:21
    +3

    Какие способы позиционирования знаешь

    sticky тоже знаю

    Htmlbook давно заброшен, ещё во времена, когда я там на форуме сидел (а форум ещё был активен). Они переехали на webref, а сейчас уже не знаю, что живо, а что нет. Лучше давать ссылку на MDN.

    не производите впечатление будто вы пытаетесь угадать ответ

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


    1. vital_pavlenko Автор
      31.01.2022 17:31

      Спасибо, исправил)


      1. Metotron0
        01.02.2022 14:18

        Ниже по комментериям я поставил вопрос, будут ли считаться ещё двумя способами объявления переменных присвоение свойств объекту self напрямую (через точку или квадратные скобки) и через defineProprty? Ведь по факту появляется глобальная переменная.

        Ещё такой же вопрос в ту же копилку: если задание id у HTML-элемента создаёт одноимённую глобальную переменную в JS, можно ли это считать уже шестым способом задания переменной?


    1. Hait
      31.01.2022 18:14

      >>> Я всегда жду подвоха в вопросе, особенно если он выглядит простым, поэтому начинаю сомневаться в собственных знаниях.

      Как же это знакомо. Особенно если после правильного ответа они ещё и не подтверждают и не опровергают его


  1. JustDont
    31.01.2022 17:39
    +1

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


    Впрочем, в целом не самый плохой вариант собеседовать. Но нет никаких особых причин давать реализовать библиотечную функцию. Вы что, не можете придумать простую задачу, примерно похожую на то, что у вас в проекте происходит?


  1. AndyPike
    31.01.2022 21:32
    +1

    Планируете джунов на поддержку древнего legacy?
    Кому в 2021 реально надо знать особенности var? (опытные и так знают)
    Во время расцвета Typescript рекомендую в его сторону направлять собеседуемых.


  1. jh7
    01.02.2022 11:08

    Тема 2

    Каким ключевыми словами можно объявить переменные?

    var, let, const

    и сами же пишите:

    const: объявляет именованную константу, доступную только для чтения


    1. Metotron0
      01.02.2022 12:11

      Я вот подумал, можно ли window.varname = 1 считать ещё одним способом объявления переменной? Ну или self.varname = 1.

      А то же самое через defineProperty — это ещё один способ?


      1. jh7
        01.02.2022 12:19

        Честно говоря, я не силен JS. Просто тут противоречие в самом вопросе, да и еще в базовых вещах. За такое у нас можно было и зачет не получить.


        1. Metotron0
          01.02.2022 14:14

          Я не спорю с противоречием. Полностью согласен. Просто начал читать про "три способа" и у меня возникла идея, что можно сделать defineProperty без writable, а отсюда подумалось, можно ли это считать ещё одним способом объявления переменной.