Домой / Группы / Пять типичных вопросов по JavaScript при собеседовании на работу

Пять типичных вопросов по JavaScript при собеседовании на работу

Разработчики JavaScript широко востребованы в it-индустрии. Так, при желании повысить, к примеру, свой оклад, недостатка в вариантах трудоустройства, как правило, не бывает. Однако, прежде чем устроиться на работу, необходимо на практике продемонстрировать свои знания и пройти собеседование. В этой стать будут рассмотрены 5 типичных вопросов, задаваемых кандидату при собеседовании, чтобы оценить его знания по JavaScript.

Вопрос 1-ый: Область видимости (scope)

Возьмем следующий код:

jQuery

(function() { var a = b = 5; })(); console.log(b);

Что что покажет консоль?

Ответ

Код выше выведет 5 .

Подвох заключается в том, что IIFE (немедленно выполняемая функция) имеет два присваивания, но переменная a объявлена посредством ключевого слова var . То есть a - это локальная переменная функции, а b , напротив, присваивается глобальной области видимости/действия.

Одним подвохом вопрос не ограничивается: внутри функции (строгий режим) ("usestrict";) не применяется. В случае его применения код выдал бы ошибку "UncaughtReferenceError: bisnotdefined" . Надо помнить, что жесткий режим требует, чтобы вы явно ссылались на глобальную область видимости, если так было задумано. То есть вы должны написать следующее:

jQuery

(function() { "use strict"; var a = window.b = 5; })(); console.log(b);

Вопрос 2-ой: Создайте «нативные» методы

Опишите функцию repeatify объекта String . Функция принимает целое число. Число определяет сколько раз необходимо дублировать строку. Функция возвращает повторяемую строку столько раз, сколько было заранее определено. Пример:

Console.log("hello".repeatify(3));

Будет выведено: hellohellohello .

Ответ

Возможное решение показано ниже:

Javascript

String.prototype.repeatify = String.prototype.repeatify || function(times) { var str = ""; for (var i = 0; i < times; i++) { str += this; } return str; };

Вопрос проверяет знания разработчика о наследовании в JavaScript и о свойстве prototype , а также его знания касательно расширения функциональности нативных данных.

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

Javascript

String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};

Этот прием особенно полезен, когда просят заклинить JavaScript функцию.

Вопрос 3-ий: Подъем (Hoisting)

Каким будет результат выполнения этого кода и почему?

Javascript

function test() { console.log(a); console.log(foo()); var a = 1; function foo() { return 2; } } test();

Ответ

Результат будет – undefined и 2 .

Причина: переменная и функции (перемещены на верх функции), а назначенные переменным значения потеряны. То есть, когда переменная выводится в консоли, она существует в функции (объявлена), но еще undefined . Другими словами, код выше равнозначен следующему:

Javascript

function test() { var a; function foo() { return 2; } console.log(a); console.log(foo()); a = 1; } test();

Вопрос 4-ый: как работает this в JavaScript

Каким будет результат следующего кода? Обоснуйте ответ.

Javascript

var fullname = "John Doe"; var obj = { fullname: "Colin Ihrig", prop: { fullname: "Aurelio De Rosa", getFullname: function() { return this.fullname; } } }; console.log(obj.prop.getFullname()); var test = obj.prop.getFullname; console.log(test());

Ответ

Код выведет AurelioDeRosa и JohnDoe . Причина: контекст функции (то, на что ссылается ключевое слово this) в JavaScript зависит от того, как функция вызывается, а не определяется.

В первом console.log() , getFullname() вызывается как функция объекта obj.prop . Таким образом, контекст ссылается на последний объект и функция возвращает fullname свойство данного объекта. С другой стороны, когда переменной test присваивается getFullname() , контекст ссылается на глобальный объект (window). Это объясняется тем, что переменная test по умолчанию установлена как свойство глобального объекта. Именно по этой причине функция возвращает значение свойства fullname от window , которое в нашем случае определенно в первой строке сниппета.

Вопрос 5-ый: call() и apply()

Возвращаясь к 4 вопросу, сделайте так, чтобы последний console.log() выводил AurelioDeRosa .

Вопрос может быть решен путем переопределения контекста функции. Для этого можно использовать методы call() или apply() . Если вам неизвестны эти функции, советую обратиться к статье . В коде ниже используется метод call() , однако в нашем случае метод apply() даст тот же результат:

Javascript

console.log(test.call(obj.prop));

Заключение

Были рассмотрены 5 типичных вопрос при собеседовании для проверки знаний разработчика JavaScript. От собеседования к собеседованию вопросы могут варьироваться в деталях и частностях, однако их общая проблематика остается неизменной.

Продолжаем разбирать часто задаваемые вопросы на интервью.

6. Что такое прототипное наследование (prototypal inheritance)

Грамотным ответом будет: изначально каждый объект обладает свойством — прототипом. Вы можете добавлять в него методы и свойства. Создавать другие объекты на основе прототипа. Создаваемый объект автоматически унаследует свойства и своего прототипа. Если свойство в новом объекте отсутствует, то будет произведен его поиск в прототипе.

Let car = function(model) { this.model = model; }; car.prototype.getModel = function(){ return this.model; } let honda = new car("honda"); console.log(honda.getModel()); //honda let bmw = new car("bmw"); console.log(bmw.getModel()); //bmw
Функция car называется конструктором. Далее мы добавляем метод getModel в ее прототип, с помощью специальной конструкции car.prototype.getModel(). Если вы не поняли о чем здесь говорится, настоятельно рекомендую ознакомиться с прототипным ООП: https://learn.javascript.ru/prototypes
30% вам зададут этот или похожий вопрос.

7. Разница между объявлением функции (function declaration) и функциональным выражением (function expression)?

Function funcA(){ console.log("function declaration"); }; var funcB = function() { console.log("function expression"); }

Как видим, функциональное выражение, — это переменная, которой присваивается функция.
Важная особенность заключается в том, что функция объявленная через function declaration доступна по тексту программы до ее описания. В то время как функциональное выражение ведет себя как переменная, таким образом, к функции можно обратиться только после. Если мы в предыдущем примере, в самом начале допишем две строки:

Console.log(funcA()); //function declaration concole.log(funcB()); //Uncaught ReferenceError: funcB is not defined.
Кстати, вместо var можно использовать let, со всеми вытекающими последствиями, касающимися области видимости.
Если вы хотите передать функцию в качестве аргумента другой функции, то вам необходимо воспользоваться функциональным выражением. Потому что это переменная. То есть передать переменную в другую функцию.

8. Что такое промисы (promises) и для чего их используют.

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

$.ajax({ url: "test.json", success: function(r) { $.ajax({ url: "baz.json?" + r.test, success: function(result) { $("#div1").html(result); } }); } });

Видите, насколько сильно ветвится данный код? Теперь, напишем тоже самое с использованием промисов (схематично):

Var p1 = new Promise(function(resolve, reject) { resolve($.ajax("test.json")); }); p1.then(function(r){ return new Promise(…); }).then(function(result){ $(“#div1”).html(result); });

9. Вопрос про setTimeout()

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

Console.log("a"); console.log("b"); console.log("c"); //увидим последовательный вывод a затем b и с. Теперь сделаем тоже самое, только вывод "а" обернем в setTimeout().

SetTimeout(function() {
 console.log("a");
}, 0);

По логике вещей, поскольку таймаут равен 0, мы можем предположить, что последовательность вывода останется такой же. Однако на самом деле, мы увидим сначала b, потом c и только в конце – a.
Так происходит потому, что когда мы использует setTimeout, код, который в него заключен, становится асинхронным. JS выполнит его после того, как освободится стэк. То есть после b и c.

10. Замыкания (closure) и как их использовать

Наверняка вам зададут вопрос на собеседовании.

Когда одна функция возвращает другую функцию (или объект), последняя содержит окружение своего как бы «родителя». Обратимся к примеру:

Let bar = function() { let i = 0; return { setI(b) { i = b; }, getI() { return i; } } }; let x = bar(); x.setI(2); console.log(x.getI()); //2

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

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

Неделя собеседований на Хабре прошла, но я решил добить ещё живого уважаемого читателя статьёй, в которой поделюсь некоторыми заданиями, которые мне давали на собеседованиях работодатели в течение последнего месяца (среди них - Яндекс, Topface, ITMozg, парочка весьма интересных и пара довольно мутных стартапов).

Разумеется, у вас не получится успешно пройти собеседование, просто заучив ответы на эти вопросы. Ответ на каждый вопрос будет необходимо пояснить, иногда - очень подробно. Многие вопросы будут ещё дополнены собеседующими. Я прошу рассматривать эти вопросы как некоторую «планку», которой необходимо самостоятельно достичь, чтобы стать Junior"ом в хорошей компании.

Собственно, сами задания

1

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

Vagabond.goUp().goLeft().goDown().goDown().goRight();

2

Имеется массив произвольной длины, заполненный случайными значениями:

Var list = ;

необходимо найти значение максимального элемента.

3

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

4

В чем разница между уткой == и === ?

5

Что такое Local Storage, Cookies и Session Storage? В чем разница между ними?

6
@media only screen and (max-width: 1200px) { }

Что это за конструкция? Зачем она может понадобиться?

7

Чем в Git отличаются merge и rebase ?

8

Var a = new F(); var b = new F(); alert(a == b); function F() {}

Сделать так, чтобы a == b возвращало true .

9

Напишите результаты выполнения операций:

"1" + 2; 1 + "2"; null == undefined; null == 0; null > 0; null >= 0; "a" > "A";

10

Var list = ; function sum() { var sum = 0; for (i=0; i

11

Представьте большую и сложную страницу, которая очень медленно загружается. Допустим, на ней плохо всё. Ваша задача - оптимизировать время загрузки. Ваши действия?

Заключение

Практически все задания нужно было выполнить устно или в старой доброй IDE «Paper & Pencil». Безбажного кода никто не требовал. Тех, что поадекватнее, в первую очередь, интересовал ход мысли, а не знание тонкостей технологии. Но, естественно, уровень знаний HTML, JS и CSS тоже имеет значение (а вы как хотели). Собеседования в некоторых случаях больше напоминают экзамен с хорошими преподавателями (так было в ITMozg и в Topface), в некоторых - приятную дружескую беседу с чаепитием (Яндекс, Radario), а в некоторых - вообще чёрт знает что (не буду называть компании, к тому же, они малоизвестны).

Если кому-нибудь из читателей после прочтения придёт в голову мысль «Оказывается, на собеседованиях даже в самые крутые компании бояться нечего. Работа в Яндексе и Топфэйсе - это вполне досягаемо», значит, я писал это не зря.

Спасибо за внимание. Всем удачи.

Доброго времени суток, дорогой гость! Рада приветствовать на страницах своего блога.

Сегодня речь пойдет о том, какие вопросы задаются на техническом собеседовании кандидату на позицию Javascript-разработчика. Цель — проверить необходимый уровень знаний языка кандидата и теоретической подготовки.

Мне бы хотелось выразить благодарность Senior Frontend Developer Греченок Евгению и Senior Backend Developer Гиззатову Марселю за помощь в создании статьи. Те вопросы, которые идут дальше, из их методички, которую они используют для собеседований кандидатов «и на 30 тысяч, и на 130». Большое спасибо, ребята, за время, которое мне уделили, и считаю, что для меня на собеседовании был хороший стимул убрать пробелы в собственных знаниях и сделать еще один шаг к тому, чтобы стать профессионалом.

Вопросы по JavaScript (синтаксис и особенности языка)

1. Если вам необходимо проверить, определено ли свойство у самого объекта … (hasOwnProperty)
2. Как работает this (http://bonsaiden.github.io/JavaScript-Garden/ru/#function.this)
3. Замыкания (http://bonsaiden.github.io/JavaScript-Garden/ru/#function.closures)
4. Определение переменных (всплытие)
5. Переменные let, const, var (https://learn.javascript.ru/let-const)
6. Равенство и сравнение (оператор == и ===)
7. Операторы typeof и instanceof (для чего используются http://bonsaiden.github.io/JavaScript-Garden/ru/#types.instanceof)
8. Почему нельзя использовать eval (http://bonsaiden.github.io/JavaScript-Garden/ru/#core.eval)
9. Деструктуризация (https://learn.javascript.ru/destructuring)
10. Строки-шаблоны (https://learn.javascript.ru/es-string)
11. Классы (прототипы, современные)
12. Итераторы (https://learn.javascript.ru/iterator)
13. Генераторы (https://learn.javascript.ru/generator)
14. Новые типы данных (https://learn.javascript.ru/set-map)
15. Что такое Eventloop? Объясните принцип его работы.

Общие вопросы по программированию

  1. Отличие компилируемого языка от интерпретируемого
    Чем компиляция С отличается от Java
  2. Отличие статической типизации от динамической
  3. Отличие наследование от композиции (https://habrahabr.ru/post/325478/)
  4. Алгоритмы и их сложность (JS https://tproger.ru/translations/algorithms-and-data-structures/)
    a. В приложении к любому языку привести примеры стандартных методов сортировки / обхода дерева / поиска в массиве, дикте с пояснением о их сложности и как работают.
  5. FIFO, LIFO
  6. Структуры данных (JS https://learn.javascript.ru/data-structures)
    a. Числа, Строки
    b. Объекты (ассоциативные массивы), передача по ссылке (что передаётся по значению)
    c. Массивы
    d. Деревья, Списки (связанный, ссылочный)
  7. Архитектура (в чём разница)
    a. асинхронная,
    b. многопоточная
  8. Микросервисы
    a. Будет ли микросервисами распределённая архитектура через общую шину данных
    b. Требования к микросервисам
    i. горизонтальное масштабирование
    ii. отказоустойчивость
  9. Преимущества микросервисов:
    i. легкая поддержка (небольшие сервисы легче)
    ii. нет ограничения на языки и библиотеки для решения задачи
    iii. упрощенное тестирование, возможность замокать взаимодействия
    iv. легкое накатывание и откатывание новых версий
    v. можно экспериментировать с технологиями

Гибкие методологии

  1. Зачем нужны
  2. Какие подходы есть
  3. Выявление проблем в разработке, зачем нужна ретроспектива в scrum
  4. Распределение задач по разработчикам
    • горят сроки
    • планирование

И напоследок...

Задача на понимание JavaScript

Задача 1. Что выведет данный код?

Var b = 5; var a = function() { alert(b); }; a();

Цель задачи: проверить понимание замыкания.

Тема: Замыкание (closure).

Ответ: Если исходить из определения замыкания — способность функции запоминать область видимости переменной, в которой та была объявлена, то правильный ответ 5. Функция a запомнила содержимое объявленной ранее переменной за пределами функции, и после вывода функции, передала в alert 5.

Сколько угодно.

  • Нужно алертом вывести какое-то сообщение, спустя 3 секунды после запуска скрипта. Как это сделать?

Так:

Или так:

  • Чем отличается наследование в JavaScript от наследования в PHP?

В отличие от PHP, где наследование можно делать одним способом, в JavaScript таких способов много. На уровне языка реализовано наследование на прототипах.

В JavaScript каждый объект может иметь ассоциацию с другим объектом - так называемый "прототип" (prototype). В случае, если поиск некоторого свойства (или метода) в исходном объекте заканчивается неудачно, интерпретатор пытается найти одноименное свойство (метод) в его прототипе, затем - в прототипе прототипа и т. д. К примеру, если мы затребовали обращение к obj.prop (или, что абсолютно то же самое, obj["prop"]), JavaScript начнет искать свойство prop в самом объекте obj, затем – в прототипе obj, прототипе прототипа obj, и так до конца.

  • Приведи пример наследования в JavaScript.

Например, пусть объект "cat" наследуется от объекта "animal". В наследовании на прототипах это реализуется как ссылка

Или вот чуть более развернутый пример. MyType наследуется от Obj:


  • Пара слов об объектах в JavaScript?

Объекты (они же - ассоциативные массивы, хэши) и работа с ними в JavaScript реализованы не так, как в большинстве языков. Объект в JavaScript представляет собой обычный ассоциативный массив или, иначе говоря, "хэш". Он хранит любые соответствия "ключ => значение" и имеет несколько стандартных методов.

  • Что представляет из себя метод объекта в JavaScript?

Метод объекта в JavaScript - это просто функция, которая добавлена в ассоциативный массив.

  • Зачем в JavaScript перед переменной писать var?

Если создавать переменную через обычное присваивание - будет создана "глобальная переменная". Пример:

Если создавать переменную с использованием слова var, тогда будет создана "локальная переменная", которая перестаёт существовать после завершения работы функции. Пример:

  • Есть две функции: function f(a,b) { return a+b } и var f = function(a,b) { return a+b }. Есть ли между ними разница? Если есть то какая?

Есть, разница в видимости функции. Вариант функции без var виден везде в текущей области видимости. В том числе и до самого определения функции. Вариант с var присваивает функцию переменной, поэтому такая функция видна только после определения.

  • Как создать массив в JavaScript?

Вот несколько способов.

  • Можно ли в JavaScript использовать функцию в качестве конструктора?

Вот так:

  • Сколько и какие конструкции для циклов есть в JavaScript?

Три: for, while и do...while.

  • Что cделает код: break mark; ?

Выйдет из текущего блока цикла или switch на метку " mark ".

  • Можно ли задать массив таким образом: var a = "a,b".split(",")?

Да, можно.

  • Что выведет alert(typeof null); ?

Выведет сообщение "object".

  • А это: alert(null instanceof Object); ?

Выведет сообщение "false".

  • 0.1 + 0.2 == 0.3 ?

Нет, т.к. вычисленное значение будет равно 0.30000000000000004. Это действие точности вычислений и проявляется она не только в JavaScript.

  • Что выведет alert(typeof NaN); ?

"Number"

  • Что выведет alert(NaN === NaN); ?

"false"

  • В чём различие свойств innerHTML и outerHTML?

Свойство любого DOM элемента innerHTML содержит HTML код, который находится внутри этого элемента. При установке нового значения этого свойства, внутренний HTML код рендерится браузером заново.

outerHTML почти аналогичен innerHTML, разница в том, что он возвращает полный HTML элемента.

Также, важно отметить, что innerHTML поддерживается всеми современными браузерами, а outerHTML поддерживается в IE (с некоторыми отличиями от остальных браузеров), в последних версиях Opera, и в браузерах на основе последних WebKit (Safari, Chrome), но не поддерживается в Firefox.

Для кода:

innerHTML возвратит:

outerHTML возвратит:


  • Какая разница между операторами == и ===?

Оператор == сравнивает на равенство, а вот === сравнивает на идентичность. Плюс оператора === состоит в том, что он не приводит два значения к одному типу. Именно из-за этого он обычно и используется.

  • В чем разница между Object.getOwnPropertyNames() и Object.keys()?

Object.getOwnPropertyNames() возвращает перечислимые и не перечислимые свойства из объекта или массива.

Object.keys() возвращает перечислимые свойства из объекта или массива.

  • С помощью какой конструкции языка можно управлять потоком выполнения скрипта и отслеживать ошибки?

Это возможно с помощью конструкции try{}... catch{}

  • Почему вызов a(); происходит успешно, а вызов b(); выдает ошибку?

Функция а() инициализируется на этапе загрузки скрипта, как бы "всплывает вверх" а функция б инициализируется, когда объявляется переменная b

  • Что такое глобальные переменные? Как они создаются? Какие проблемы связаны с использованием глобальных переменных?

Глобальная переменная - переменная, которая доступна (видима) во всем документе, в отличии от локальной (ограничена рамками блока программного кода, внутри которого она определена)

Большинство JavaScript разработчиков избегает использования глобальных переменных. Одна из причин - возможный конфликт имен глобальных и локальных переменных. Так же код использующий глобальные переменные может быть тяжелее сопровождать и тестировать.

  • Что такое замыкания (closure) в JavaScript?

Простыми словами это внутренняя функция, т.е. функция в функции.

Замыканием (closure) называют потому, что после выполнения родительской или внешней функции, код внутренней все еще "живет" в интерпретаторе, и его можно выполнить. Ошибок не возникнет даже если внутренняя функция (замыкание) будет использовать переменные из внешней функции. Например, эту особенность можно использовать для создания функций обработчиков событий:


  • Напишите функцию принимающую строку с именем файла и возвращающую расширение (фрагмент после последней точки).

    • Что такое prototype в javascript?

    В общих чертах prototype - это свойство позволяющее добавлять уже существующим объектам свойства, также используется для эмуляции наследования классов в JavaScript. Подробный ответ написан здесь. Еще как вариант, можно упомянуть о Prototype.js. Это популярная библиотека добавляющая удобные ООП возможности в программы на JavaScript-е.

    • Какие способы навешивания обработчиков событий вы знаете?

    События можно добавлять тремя способами:

    • htmlElement.onclick = function(event) { .... } - так можно добавить только один обработчик
    • htmlElement.addEventListener("click", ...) - так можно навесить несколько обработчиков, сохраняет порядок обработчиков
    • htmlElement.attachEvent("on"+имя_события, обработчик) - тоже можно навесить несколько, не сохраняет порядок обработчиков, нет доступа к элементу на котором сработало событие.