Так получилось, что за свою карьеру front-end разработчика, я побывала на многих собеседованиях. Тема прохождения интервью не теряет своей актуальности, а в комментариях, когда речь заходит о собеседованиях, начинают ломаться копья. Хочу тоже внести свой вклад и поделиться накопившейся коллекцией вопросов. Прошу.
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/ce9/386/ca1/ce9386ca193aeb8d3fe1925ba163af28.jpg)
На собеседования меня приглашают охотно, не знаю, виной этому симпатичная фоточка в резюме или его содержание. Если о резюме, то для описания технологий, используемых на каждой текущей работе, я трачу часа два, три. Порой просматриваю в чужие, как они оформлены, да и вдруг найду что-то полезное для себя…
Для начала что-нибудь полегче.
1. Есть некоторая строка (var str = 'fgfggg';), что будет, если мы возьмем str[0]?
2. Реализовать методы, которые в процессе выполнения строки (2).plus(3).minus(1) дали бы на выходе 4.
3. Сейчас уже редко, но до сих еще спрашивают: «Почему плохо писать прямо в прототипы базовых типов?»
4. Дана функция, она принимает в качестве аргументов строки '*', '1', 'b', '1c', реализуйте ее так, что бы она вернула строку '1*b*1c'
5. Дано дерево, надо найти сумму всех вершин.
6. Можно ли из js менять значения в before, after?
Давайте, что-нибудь для разгрузки мозга, вопрос на верстку.
7. Вместить три блока 20X20px в ряд, в блок шириной 60px, при этом у блоков должны быть границы.
![](https://habrastorage.org/r/w1560/webt/iz/bd/dj/izbddjakfergd1lp0mic2tf-qgw.png)
8. Как применяются скругленные углы для элементов и стили для текста(шрифт, тип шрифта, цветащте и тд)?
9. Что такое ресет стилей?
10. Требуется сверстать попап по центру, его размеры нам известны, но мы не хотим что бы он прокручивался вместе со страницей, причем по высоте может и не влезать в высоту экрана.
11. Нарисовать стилями полукруг.
![](https://habrastorage.org/r/w1560/webt/ua/ys/d6/uaysd6ndv68ik75dpqv5znd76ku.png)
12. Есть массив в котором лежат объекты с датами, отсортировать по датам.
13. Есть несколько слов, определить состоят ли они из одних и тех же букв('кот', 'ток', 'окт')
В последнее время часто стали задавать вопросы про promse, что это такое, какие методы обработки ошибок, можно ли обойтись без них.(14, 15, 16)
17. И конечно вопрос на засыпку: «Каким образом можно обойтись без промисов?».
18. Еще вспомнился вопрос про обработку ошибок в промисах. У нас есть три запроса к серверу, один возвращает нам имя пользователя, второй его данные, а третий изображение для аватарки, мы для каждого запроса используем по промису, объединяя их в цепочку, что будет если в одном из запросов произойдет ошибка, довыполнится ли цепочка?
Промисы все разрастаются и на смену Callback Hell приходит Promise Hell. Что же делать?
(19)Вот еще один примерчик на асинхронность. Объяснить в какой последовательности выведутся цифры и почему так.
Достаточно популярный, надо сказать. Вот мне он и достался в очередной раз. Уже отработано начала отвечать: «1, 3, 2. Так как хоть js и асинхронен, но внутри его есть очередь выполнения и setTimeout и setInterval, если им указан 0, помещают вызов функции в конец очереди.»
Тут надо сказать ребята зафейлились, заявив, что я ответила правильно, про 132, но не объяснила почему.
(20)Вообще вопросы на setTimeout и setInterval весьма актуальны.Меня спрашивали: «Какое минимальное время можно задать?»
Не давно выделили целую статью для этого примера(тут), читатели в комментариях расписывали всевозможные способы решения, от традиционных до фантастических. Вот о которых я обычно рассказывала на собеседованиях.
21. Что будет выведено в консоль, как можно модифицировать пример что бы он возвращал правильный результат(назовите как можно больше способов)?
Давайте что-нибудь похардкорнее.
22. Надо написать функцию, которая вернет «hello world», но при этом в теле функции нельзя использовать ни цифры, ни буквы, а циклы, массивы, объекты можно, но без цифр.
(23) От них же. Числа от 1 до 100 лежат в массиве, они хаотично перемешанные, от туда изъяли одно число, надо найти, что это за число. алгоритм не должен превышать O(n^2) сложности.
Просто мне вспомнилось, что когда-то спрашивали: «Как быстрее всего найти сумму элементов массива?»
Вот на тот момент вспомнилось и не пришло ни чего лучше.
(24) Вот еще фейл-задача. Приведу дословно, те напишу как написали мне.
Реализовать Foo
(25) Да, до сих пор ее задают. Причем она попалась мне несколько раз. В первый раз я стала решать циклом, вроде бы получилось, только оставалась проблема с разными символами, писать для каждого символа replace — это не вариант, а в регулярках я не сильна, да и сработает он до первого подходящего вхождения. Я не привыкла оставлять за спиной что-то непонятное, поэтому разобралась как реализовать функцию.
Красиво, просто, изящно.
Забавно, но где-то через год мне попался этот же вопрос. Я обрадовалась: «Свезло». Как оказалось, нет. Требовалось решить с помощью цикла, а регулярку можно было использовать только для одного символа. Собеседник мотивировал это тем, что replace с регуляркой по всей строке — слишком ресурсоемко.
Подумав дома, у меня получилось вот так:
26. Как подключить js, css? Плюсы, минусы разных способов?
27. Чем opacity отличается от visible: hidden и что это такое, отличие от overflow: hidden?
28. Реализовать функцию f: f(2, 3) -> 5, при вызове f(2)(3), тоже вернет 5
Более сложный вариант.
f(1)(2)(3)() -> 6, f(0)(3)(1)(5)() -> 8
Реализовать функцию, которая возвращает результаты
foo(1)(2)(3) -> 6
foo(1)(2)(3)(4) -> 10
foo(-1)(2)(3)(4)(7) -> 15
foo(1)(2)(3)...(n) вернет результатом сумму 1+2+3...+n
Самый сложный вариант, когда вызов этой конструкции не заканчивается пустыми скобками, а значит мы не имеем явного указателя на выход. Задача досталась не мне, в комментариях к статье мне любезно рассказали решение.
29. На собесе на прошлую работу мне попался вопрос: 'Что такое live/die'
31. Заголовки CORS?
32. Ускорение загрузки страницы.
33. CommonJS и AMD или модульность?
34. Еще интересный пример. Реализовать методы seven, plus, one, five, minus, two. seven(plus(one())) -> 8. five(minus(two())) -> 3
35. Сортировка пузырьком.
Да, да, ее еще спрашивают.
36. Обратная польская нотация.
Основной принцип. Дана строчка 23+1-, начинаем двигаться по ней, как только доходим до первого арифметического знака, берем две цифры перед ним и на их место, записываем результат вычисления. Получится 51-. Начинаем все с начала.
Кому интересно, вот статья wikipedia
37. Есть div, в нем другой div, у второго задан padding 50%, как это все будет выглядеть?
Собеседник предложил мне посмотреть дома как оно сработает, хотя мне стало очень интересно.
Как вы считаете, правильно ли на собеседование отвечать самому на вопрос, если кандидат с ним не справился?
38. Есть строка, состоящая из разных скобок, проверить закрыты ли все. Пример строки: "())({}}{()][]["
39. Напишите код, который при клике на любой div внутри root будет выводить в консоль его id.
40. Напишите код, который сделает из массива объект
// на входе массив
// на выходе объект
41. Что выведется в результате?
42. Есть функция и объект. Напишите все известные вам способы, чтобы вывести в консоли значение x из объекта используя функцию
43.
Что вернет метод?
а) ошибку, т.к. метод объявлен позже, чем создание экземпляра
б) вернется 'FOO'
44. В js переменные объявленные следующим образом:
a=3; b=«hello»;
Укажите правильные утверждения.
а) создаются в локальном контексте
б) создаются в глобальном контексте
в) создание переменной без ключевого слова var — синтаксическая ошибка.
45. Что вернёт этот код — typeof (function(){})()
а) callback
б) method
в) undefined
г) function
46. Что будет если задать margin: -10px;
47. Почему 0.1 + 0.2 даст 0.30000000000000004
48. Моему коллеге на должность php-разраба, предложили такую
Есть два блока, второй скрытый, если в первом нет дочерних элементов, то показать второй.
Конечно это не все задания, которые мне довелось решать, какие-то я благополучно забыла, какие-то слишком банальные, масса вопросов, просто на теорию, остались за кадром.
Вот еще парочка вопросов, они на прямую не касаются фронта, но, наверно не лишне знать.
Идеальный интерфейс в вашем представление?
Как вы бы сделали отказоустойчивый сайт?
Какие типы уязвимостей знаете?
Ссылка на вторую часть — Задачи с собеседований (front-end) часть 2
![image](https://habrastorage.org/getpro/habr/post_images/ce9/386/ca1/ce9386ca193aeb8d3fe1925ba163af28.jpg)
Лирическое отступление
На собеседования меня приглашают охотно, не знаю, виной этому симпатичная фоточка в резюме или его содержание. Если о резюме, то для описания технологий, используемых на каждой текущей работе, я трачу часа два, три. Порой просматриваю в чужие, как они оформлены, да и вдруг найду что-то полезное для себя…
Задачи
Для начала что-нибудь полегче.
1. Есть некоторая строка (var str = 'fgfggg';), что будет, если мы возьмем str[0]?
Ответ
str[0] вернет символ строки, который находится по нулевому индексу. Строка в js — immutable, то есть из нее можно прочитать символ, а вот записать нет.
2. Реализовать методы, которые в процессе выполнения строки (2).plus(3).minus(1) дали бы на выходе 4.
Ответ
Поскольку, мы работаем с числами, надо расширить прототип Number новыми методами.
Число два будет доступно через this в функции plus. Из нее мы возвращаем результат сложения числа, на которое указывает this и числа, переданного в качестве аргумента. Аналогично для minus.
Number.prototype.plus = function (value) {
return this + value;
}
Number.prototype.minus = function (value) {
return this - value;
}
Число два будет доступно через this в функции plus. Из нее мы возвращаем результат сложения числа, на которое указывает this и числа, переданного в качестве аргумента. Аналогично для minus.
3. Сейчас уже редко, но до сих еще спрашивают: «Почему плохо писать прямо в прототипы базовых типов?»
Ответ
Ожидаемый результат — [1, 2, 22], а вернется undefined.
Мы рассчитываем, что стандартные методы сработают согласно документации, но какой-то разработчик можем переопределить метод, и он вернет совершенно неожиданный результат.
Именно поэтому библиотека prototype.js уступила jQuery.
Array.prototype.sort = function () {}
var t = [2, 1, 22];
t.sort()
Ожидаемый результат — [1, 2, 22], а вернется undefined.
Мы рассчитываем, что стандартные методы сработают согласно документации, но какой-то разработчик можем переопределить метод, и он вернет совершенно неожиданный результат.
Именно поэтому библиотека prototype.js уступила jQuery.
4. Дана функция, она принимает в качестве аргументов строки '*', '1', 'b', '1c', реализуйте ее так, что бы она вернула строку '1*b*1c'
Ответ
Ее можно решать прямо в лоб, перебирая в цикле все аргументы, но мы поступим умнее.
function getStr() {
return [].slice.call(arguments, 1).join(arguments[0])
}
5. Дано дерево, надо найти сумму всех вершин.
Ответ
Я решила задачу рекурсией, потом мы упростили решение, а затем переписали на очередь.
Рекурсия.
Очередь.
Рекурсия.
var sum = 0;
function getSum(obj) {
sum += obj.valueNode;
if (obj.next != null) {
for (var i = 0; i < obj.next.length; i++) {
getSum(obj.next[i]);
}
}
return sum;
}
var tree1 = {
valueNode: 1,
next: [
{
valueNode: 3,
next: null
},
{
valueNode: 2,
next: null
}
]
}
var tree = {
valueNode: 3,
next: [{
valueNode: 1,
next: null
},
{
valueNode: 3,
next: null
},
{
valueNode: 2,
next: null
},
{
valueNode: 2,
next: [
{
valueNode: 1,
next: null
},
{
valueNode: 5,
next: null
}
]
}]
};
console.log(getSum(tree1));
sum = 0;
console.log(getSum(tree));
Очередь.
function getSum(obj) {
var arr = [obj],
sum = 0,
current;
while(arr.length > 0) {
current = arr.shift();
sum += current.valueNode;
if (current.next != null) {
for (var i = 0; i < current.next.length; i++) {
arr.push(current.next[i]);
}
}
}
return sum;
}
var tree = {
valueNode: 3,
next: [{
valueNode: 1,
next: null
},
{
valueNode: 3,
next: null
},
{
valueNode: 2,
next: null
},
{
valueNode: 2,
next: [
{
valueNode: 1,
next: null
},
{
valueNode: 5,
next: null
}
]
}]
};
getSum(tree)
6. Можно ли из js менять значения в before, after?
Ответ
Нет, единственное что мы можем — это удалить класс, у которого указаны before или after, либо наоборот добавить.
Давайте, что-нибудь для разгрузки мозга, вопрос на верстку.
7. Вместить три блока 20X20px в ряд, в блок шириной 60px, при этом у блоков должны быть границы.
![](https://habrastorage.org/webt/iz/bd/dj/izbddjakfergd1lp0mic2tf-qgw.png)
8. Как применяются скругленные углы для элементов и стили для текста(шрифт, тип шрифта, цветащте и тд)?
Ответ
Стилевые свойства применятся ко всем элементам с текстом, если у тегов не указаны стилевые правила. К примеру у ссылок указан цвет текста по умолчанию и он более приоритетный, чем определенный нами в body. Дело в том, что для многих свойств по умолчанию стоит значение inherit, то есть как у родителя. Получается поднимается вверх, пока не дойдет до body.
Для свойства border-radius, наоборот, применяется только к тегу, у которого мы хотим что бы били скругленные углы.
Для свойства border-radius, наоборот, применяется только к тегу, у которого мы хотим что бы били скругленные углы.
9. Что такое ресет стилей?
Ответ
Многим тегам стили прописаны по умолчанию, в процессе верстке нам приходится переопределять их. Что бы не делать это каждый раз, мы «скидываем» их «массово». Для этого заводим файл под стили, подключаем его первым или в первом стилевом файле, в самом верху указываем наши стили для базовых тегов.
К примеру. Мы часто используем список ul для верстки меню, для этого мы каждый раз вынуждены обнулять padding, margin и list-style-type. Можно один раз задать стили, и списки станут без внешней и внутренней границы, а так же без маркеров.
К примеру. Мы часто используем список ul для верстки меню, для этого мы каждый раз вынуждены обнулять padding, margin и list-style-type. Можно один раз задать стили, и списки станут без внешней и внутренней границы, а так же без маркеров.
10. Требуется сверстать попап по центру, его размеры нам известны, но мы не хотим что бы он прокручивался вместе со страницей, причем по высоте может и не влезать в высоту экрана.
Ответ
body {
overflow: hidden;
}
.wrap {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow-y: auto;
background-color: rgba(230, 230, 230, .1);
}
.popup {
position: absolute;
width: 400px;
height: 300px;
right: 0;
left: 0;
top: 0;
bottom: 0;
margin: auto;
}
11. Нарисовать стилями полукруг.
![](https://habrastorage.org/webt/ua/ys/d6/uaysd6ndv68ik75dpqv5znd76ku.png)
Ответ
width: 100px;
height: 100px;
border-right: 1px solid #f00;
border-radius: 0 50% 50% 0;
12. Есть массив в котором лежат объекты с датами, отсортировать по датам.
Ответ
var arr = [{date: '10.01.2017'}, {date: '05.11.2016'}, {date: '21.13.2002'}];
arr.forEach(function(item) {
var arrDate = item.date.split('.'),
date = new Date(Number(arrDate[2]), Number(arrDate[1]), Number(arrDate[0]));
item.time = date.getTime();
});
arr.sort(function (a, b) {
if (a.time - b.time < 0) {
return false;
} else {
return true;
}
});
var res = arr.map(function (item) {
return {date: item.date};
});
console.log(res);
13. Есть несколько слов, определить состоят ли они из одних и тех же букв('кот', 'ток', 'окт')
Ответ
var arr = ['kot', 'tok', 'okt'],
arr1 = ['kot', 'tok', 'ott'];
function sameWords(arr) {
var word1, word2;
for (var i = 0; i < arr.length-1; i++) {
word1 = 0;
word2 = 0;
if (arr[i].length !== arr[i+1].length) {
return false;
} else {
for (var j = 0; j < arr[i].length; j++) {
word1 += arr[i][j].charCodeAt(0);
word2 += arr[i+1][j].charCodeAt(0);
}
if (word1 !== word2) {
return false;
}
}
}
return true;
}
console.log(sameWords(arr));
console.log(sameWords(arr1));
Про промисы
В последнее время часто стали задавать вопросы про promse, что это такое, какие методы обработки ошибок, можно ли обойтись без них.(14, 15, 16)
Ответ
Начну издалека, так как js-асинхронен, то в результате отслеживания завершения определенного когда в качестве аргументов передавались callback-функции, которые и вызывались по мере готовности. Цепочка ассинхронных методов росла, что приводило к Callback Hell, что затрудныло работу с кодом, отлаживание ошибок и им на смену пришли промисы.
Несколько промисов можно объединить и получить разом ответ от них
var promis = new Promise(function (resolve, reject) {
...
setTimeout(function () {
resolve(res);
}, 5000);
});
Несколько промисов можно объединить и получить разом ответ от них
var promisesImages = [];
for (let i = 0; i < count; i++) {
promisesImages.push(new Promise((resolveImg, rejectImg) => {
let img = new Image(),
startTime = Date.now();
img.src = this.imgUrl + '?' + Math.floor(Math.random() * 100000000);
img.onload = () => {
resolveImg(Date.now() - startTime);
};
img.onerror = rejectImg;
}));
}
Promise.all(promisesImages)
.then((timings) => {...})
17. И конечно вопрос на засыпку: «Каким образом можно обойтись без промисов?».
Ответ
По старинке, вводили переменную-счетчик и как-только наступало окончание очередного асинхронного действия, сравнивали переменную с общем количеством.
18. Еще вспомнился вопрос про обработку ошибок в промисах. У нас есть три запроса к серверу, один возвращает нам имя пользователя, второй его данные, а третий изображение для аватарки, мы для каждого запроса используем по промису, объединяя их в цепочку, что будет если в одном из запросов произойдет ошибка, довыполнится ли цепочка?
Ответ
Нет
Промисы все разрастаются и на смену Callback Hell приходит Promise Hell. Что же делать?
Ответ
Фактически выполнение test1 как бы «останавливается» до того момета пока мы не получим ответ от test. Я и раньше читала про эти методы, но особо не обращала внимание, а как-то в разговоре речь зашла о них, я удивилась: «Как так, выполнение останавливает, это же не понятно, что за функция, где она определена, когда callback — здесь все понятно, видно что произойдет в функции по завершению операции, ну или всегда можем поискать по имени, опять же, привычно про контекст». На что мне ответили, что у меня javascript головного мозга и я на столько привыкла к асинхронности, что синхронное выполнение мне кажется чем-то за гранью, а ведь в в пыхе, на которой я некогда программировала все синхронно, там даже если чтение из файла, пока не завершиться, дальше не продолжится.
function test() {
return new Promise(function (resolve) {
setTimeout (function () {
resolve(1);
})
})
}
async function test1() {
var res = await test();
console.log(res + 1);
}
Фактически выполнение test1 как бы «останавливается» до того момета пока мы не получим ответ от test. Я и раньше читала про эти методы, но особо не обращала внимание, а как-то в разговоре речь зашла о них, я удивилась: «Как так, выполнение останавливает, это же не понятно, что за функция, где она определена, когда callback — здесь все понятно, видно что произойдет в функции по завершению операции, ну или всегда можем поискать по имени, опять же, привычно про контекст». На что мне ответили, что у меня javascript головного мозга и я на столько привыкла к асинхронности, что синхронное выполнение мне кажется чем-то за гранью, а ведь в в пыхе, на которой я некогда программировала все синхронно, там даже если чтение из файла, пока не завершиться, дальше не продолжится.
(19)Вот еще один примерчик на асинхронность. Объяснить в какой последовательности выведутся цифры и почему так.
console.log(1);
setTimeout(function() {
console.log(2);
}, 0)
console.log(3);
Достаточно популярный, надо сказать. Вот мне он и достался в очередной раз. Уже отработано начала отвечать: «1, 3, 2. Так как хоть js и асинхронен, но внутри его есть очередь выполнения и setTimeout и setInterval, если им указан 0, помещают вызов функции в конец очереди.»
Тут надо сказать ребята зафейлились, заявив, что я ответила правильно, про 132, но не объяснила почему.
(20)Вообще вопросы на setTimeout и setInterval весьма актуальны.Меня спрашивали: «Какое минимальное время можно задать?»
Ответ
В каждом браузере есть свой минимум, если вы указываете меньше него, то все равно задержка будет не меньше минимуму. Иногда даже и больше указанного времени, так как задача попадает в очередь и время складывается из заданного плюс затраты в на выполнение на задач в очереди перед ней.
Куда же без замыканий
Не давно выделили целую статью для этого примера(тут), читатели в комментариях расписывали всевозможные способы решения, от традиционных до фантастических. Вот о которых я обычно рассказывала на собеседованиях.
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i);
}, 100);
}
21. Что будет выведено в консоль, как можно модифицировать пример что бы он возвращал правильный результат(назовите как можно больше способов)?
Ответ
Самый распространенный, обернуть в замыкание
Не все обращали внимание, что в i можно передать не только контекст
Так же методам setInterval и setTimeout можно передать аргументы, которые будут прокинуты в качестве аргументов калбек-функции
es6
Одна из возможностей es6, в данном случае сработает несколько неожиданно, let не в блоке {}.
for (var i = 0; i < 10; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, 100);
})(i)
}
Не все обращали внимание, что в i можно передать не только контекст
for (var i = 0; i < 10; i++) {
setTimeout(function (i) {
console.log(i);
}.bind(this, i), 100);
}
Так же методам setInterval и setTimeout можно передать аргументы, которые будут прокинуты в качестве аргументов калбек-функции
for (var i = 0; i < 10; i++) {
setTimeout(function (i) {
console.log(i);
}, 100, i);
}
es6
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i);
}, 100);
}
Одна из возможностей es6, в данном случае сработает несколько неожиданно, let не в блоке {}.
Давайте что-нибудь похардкорнее.
22. Надо написать функцию, которая вернет «hello world», но при этом в теле функции нельзя использовать ни цифры, ни буквы, а циклы, массивы, объекты можно, но без цифр.
Ответ
Увы, эти интересные люде не сказали мне как ее решать, поэтому, подумав дома, я могу только предположить.
Так я получила букву H, но это изврат еще тот, осталось сделать оставшиеся 10 знаков…
var zero = [].length,
one = [{}].length,
two = [,,].length,
seven = [,,,,,,,].length;
console.log(String.fromCharCode(Number(String(seven) + String(two))));
Так я получила букву H, но это изврат еще тот, осталось сделать оставшиеся 10 знаков…
(23) От них же. Числа от 1 до 100 лежат в массиве, они хаотично перемешанные, от туда изъяли одно число, надо найти, что это за число. алгоритм не должен превышать O(n^2) сложности.
Ответ
Пройти массив циклом и сложить все имеющиеся там цифры и вычесть из числа, полученного по формуле (n + 1) / (n / 2).
Мне пришло в голову более экзотическое решение. Детям и слабонервным лучше не смотреть.
Мне пришло в голову более экзотическое решение. Детям и слабонервным лучше не смотреть.
var sum = 101*50,
sumArr = eval([4, 2, ... 3, 7].join('+').replace('++', '+')),
res;
res = sum-sumArr;
Просто мне вспомнилось, что когда-то спрашивали: «Как быстрее всего найти сумму элементов массива?»
Ответ
eval([4, 2, ... 3, 7].join('+')
Вот на тот момент вспомнилось и не пришло ни чего лучше.
(24) Вот еще фейл-задача. Приведу дословно, те напишу как написали мне.
function Book(name, author) {
this.name = name;
this.author = author;
return this;
}
function Foo(Book, 'Учебник javascript', 'Петр Сергеев')
Реализовать Foo
Ответ
Меня сбила эта строчка function Foo(Book, 'Учебник javascript', 'Петр Сергеев'). Только я вижу, что здесь что-то не так? Мне предложили решать через Object.create(), но я не согласна. Свойства и методы, записаные в саму функцию-конструктор, не будут «скопированы» Object.create.
Конечно меня не взяли, а на последок посоветовали лучше учить теорию. Хнык-хнык.
В любом случае, я бы предпочла решать так.
Хочу посоветовать чувакам лучше готовиться к собеседованиям.
function Book(name, author) {
this.name = name;
this.author = author;
return this;
}
function Foo(Cclass, name, author) {
return Object.create(Cclass.prototype);
}
var book = Foo(Book, 'js', 'petr');
console.log(book.name); -> undefined
Конечно меня не взяли, а на последок посоветовали лучше учить теорию. Хнык-хнык.
В любом случае, я бы предпочла решать так.
function Book(name, author) {
this.name = name;
this.author = author;
return this;
}
function Foo(Cclass, name, author) {
return Cclass.call({}, name, author);
}
var book = Foo(Book, 'js', 'petr');
console.log(book.name);
Хочу посоветовать чувакам лучше готовиться к собеседованиям.
Задача про палиндром
(25) Да, до сих пор ее задают. Причем она попалась мне несколько раз. В первый раз я стала решать циклом, вроде бы получилось, только оставалась проблема с разными символами, писать для каждого символа replace — это не вариант, а в регулярках я не сильна, да и сработает он до первого подходящего вхождения. Я не привыкла оставлять за спиной что-то непонятное, поэтому разобралась как реализовать функцию.
function isPalindrom1(str) {
if (str.toLowerCase().replace(/[^а-яА-ЯёЁ]/g, '') === str.toLowerCase().replace(/[^а-яА-ЯёЁ]/g,
'').split('').reverse().join('')) {
return true;
} else {
return false;
}
}
Красиво, просто, изящно.
Забавно, но где-то через год мне попался этот же вопрос. Я обрадовалась: «Свезло». Как оказалось, нет. Требовалось решить с помощью цикла, а регулярку можно было использовать только для одного символа. Собеседник мотивировал это тем, что replace с регуляркой по всей строке — слишком ресурсоемко.
Подумав дома, у меня получилось вот так:
function isPalindrom(str) {
var str = str.toLowerCase(),
lim = str.length - 1,
i = 0,
j = str.length - 1;
while (i <= lim) {
if (/[^а-яА-ЯёЁ]/.test(str[i])) {
i += 1;
}
if (/[^а-яА-ЯёЁ]/.test(str[j])) {
j -= 1;
}
if (str[i] != str[j]) {
return false;
}
i += 1;
j -= 1;
}
return true;
}
console.log(isPalindrom('А роза упала на лапу Азора'));
26. Как подключить js, css? Плюсы, минусы разных способов?
Ответ
Можно с помощью тегов
прямо на странице или
подключаем из внешних файлов.
Минус подключения внешних файлов заключается в том, что для их скачки, открываются дополнительные соединения. Может случиться так, что мы не сможем закачать, а если это еще и js файл, подключенный где-то в начале, то мы рискуем показать пользователю пустую страницу.
Размещение стилей и скриптов в самом документе, в этом плане, надежнее. Но при этом скрипты и стили совершенно не кешируются.
<script></script>
<style></style>
прямо на странице или
<script src="script.js"><script>
<link rel="stylesheet" href="/css/style.css">
подключаем из внешних файлов.
Минус подключения внешних файлов заключается в том, что для их скачки, открываются дополнительные соединения. Может случиться так, что мы не сможем закачать, а если это еще и js файл, подключенный где-то в начале, то мы рискуем показать пользователю пустую страницу.
Размещение стилей и скриптов в самом документе, в этом плане, надежнее. Но при этом скрипты и стили совершенно не кешируются.
27. Чем opacity отличается от visible: hidden и что это такое, отличие от overflow: hidden?
Ответ
opacity отвечает за прозрачность элемента. Принимает значения от 0 до 1, при 0 — элемент не виден, .5 — полупрозрачен, 1 — полностью виден. Даже при 0 занимает место на странице.
Элемент со стилями visible: hidden так же занимает место, не видим. Но в отличие от элемента с opacity, js-события на нем не срабатывают.
display: none — полностью скрывает элемент, он не видим и не занимает место на странице. javascript не может получить ни width, height.
overflow: hidden; — скрывает все, что попадет за его пределы.
Элемент со стилями visible: hidden так же занимает место, не видим. Но в отличие от элемента с opacity, js-события на нем не срабатывают.
display: none — полностью скрывает элемент, он не видим и не занимает место на странице. javascript не может получить ни width, height.
overflow: hidden; — скрывает все, что попадет за его пределы.
Модное слово — каррирование
28. Реализовать функцию f: f(2, 3) -> 5, при вызове f(2)(3), тоже вернет 5
Ответ
Хоть данный шаблон упоминается в книге Стефанова, на практике я ни разу не видела, что бы кто-то его использовал.
function f(a, b) {
if (b !== undefined) {
return a + b;
} else {
return function (b) {
return a + b;
}
}
}
Хоть данный шаблон упоминается в книге Стефанова, на практике я ни разу не видела, что бы кто-то его использовал.
Более сложный вариант.
f(1)(2)(3)() -> 6, f(0)(3)(1)(5)() -> 8
Ответ
function f(arg) {
var value = arg;
return function (arg) {
if (arg !== undefined) {
return f(value + arg);
} else {
return value;
}
}
}
Реализовать функцию, которая возвращает результаты
foo(1)(2)(3) -> 6
foo(1)(2)(3)(4) -> 10
foo(-1)(2)(3)(4)(7) -> 15
foo(1)(2)(3)...(n) вернет результатом сумму 1+2+3...+n
Самый сложный вариант, когда вызов этой конструкции не заканчивается пустыми скобками, а значит мы не имеем явного указателя на выход. Задача досталась не мне, в комментариях к статье мне любезно рассказали решение.
В итоге получилось
function foo(value) {
var acc = value;
function addNext(next) {
acc += next;
return addNext;
}
addNext.toString = addNext.valueOf = function() {
return acc;
}
return addNext;
}
29. На собесе на прошлую работу мне попался вопрос: 'Что такое live/die'
Ответ
Где то из глубины сознания всплыло, что это аналог on/off, с помощью них можно навешивать/удалять обработчики на события их. Но более старые методы, по сравнению on/off.
В проекте я столкнулась с еще и с bind/unbind
В проекте я столкнулась с еще и с bind/unbind
30. JSONP, как реализовать
Ответ
Мы не хотим находясь на одном сайте, получать данные с другого и как-то их обрабатывать. Что же делать? Может ajax, но у него есть ограничение по политике бозопасности. Надо что-то совпадали протокол, домен и порт, даже на поддомены мы не можем слать ajax-запросы.
Все же разработчики нашли некий лайфхак для крос-доменных запросов.
Если вы используете jquery, то всего-то надо указать в параметре «dataType» — «jsonp».
Мало кто знает, что лежит в основе данного запроса, реализация нативным js приблизительно такая
тег script начинает выкачивать скрипт, лежащий по адресу в атрибуте src, а после закачки, происходит выполнение. Поэтому мы создаем тег script. Случайным образом генерируем имя функции. Формируем урл к ресурсу, где в качестве параметра передается имя нашей новой функции.
В глобальную область, по ключу callbackName помещается функция, которая вызовется, при получение данных от ресурса, они станут доступны внутри через параметр.
На сервере ресурса сработает что-то в этом роде
В window попадет
Так как теги с атрибутом src способы посылать только GET запросы, то jsonp не поддерживает POST
Все же разработчики нашли некий лайфхак для крос-доменных запросов.
Если вы используете jquery, то всего-то надо указать в параметре «dataType» — «jsonp».
Мало кто знает, что лежит в основе данного запроса, реализация нативным js приблизительно такая
var url = 'http://mydomen.com/news.php',
script = document.createElement('script'),
callbackName = 'jsonCallback' + Math.randome();
script.src = url + '?callback' + callbackName;
window[callbackName] = function(response){
console.log(response);
}
document.header.appendChild(script);
тег script начинает выкачивать скрипт, лежащий по адресу в атрибуте src, а после закачки, происходит выполнение. Поэтому мы создаем тег script. Случайным образом генерируем имя функции. Формируем урл к ресурсу, где в качестве параметра передается имя нашей новой функции.
В глобальную область, по ключу callbackName помещается функция, которая вызовется, при получение данных от ресурса, они станут доступны внутри через параметр.
<script src='http://mydomen.com/news.php?callback0.90428777...'>
На сервере ресурса сработает что-то в этом роде
echo $_REQUEST[callback] + '(' + json_encode($arDate) + ')';
В window попадет
window.jsonCallback0.90428777 -> function (response) {
console.log(response);
}
Так как теги с атрибутом src способы посылать только GET запросы, то jsonp не поддерживает POST
31. Заголовки CORS?
Ответ
Это альтернатива jsonp, в специальном заголовках перечисляются «доверенные» ресурсы, которые смогут получать данные от него, а если указать '*', то любые сайты, при обращение, станут получать данные.
Так же как и с jsonp доступны только GET запросы.
Когда я рассказывала про альтернативу jsonp интервьюер от этого вариант «отмахнулся», сказав, что не надежный. Я с ним не согласна. JSONP легче подменить, чем CORS-заголовки
В date подпихнуть вут такую строчку
За место данных можно вернуть какой-то код, который закроет вызов функции и выполнится у пользователя.
Сейчас уже исправили, но раньше наблюдалась критическая уязвимость в json-е, с помощью символа переноса строки он подламывался.
Так же как и с jsonp доступны только GET запросы.
Когда я рассказывала про альтернативу jsonp интервьюер от этого вариант «отмахнулся», сказав, что не надежный. Я с ним не согласна. JSONP легче подменить, чем CORS-заголовки
<script src="http://bla-bla/get?callback=f'></script>
<? echo $GET['callback'].'('.$date.')';
В date подпихнуть вут такую строчку
');alert(document.cookie);'
За место данных можно вернуть какой-то код, который закроет вызов функции и выполнится у пользователя.
Сейчас уже исправили, но раньше наблюдалась критическая уязвимость в json-е, с помощью символа переноса строки он подламывался.
32. Ускорение загрузки страницы.
Ответ
1 минимизировать и склеить в один все js-файлы
2 то же и с css
3 собрать изображения в спрайты
4 кеширование
а) файлы js и css кешируются навсегда( или на длительный период, к примеру на год), когда в них вносятся какие-то изменения, в результате разработки, меняется номер версии, браузер считает, что это новые файлы и закачивает их. Время кеширование содержится в заголовке expires.
б) файл кешируется до тех пор, пока в нем не произошли изменения. Когда пользователь в первый раз заходит на сайт, у него еще нет кеша, файлы закачиваются и в следующий раз, когда происходит обмен заголовками происходит анализ ETag(хеш суммы содержимого содержимого файла или хеш последнего времени изменения, или номер версии) Если он изменился, то закачивается, в противном случае, берется из хеша.
Так же можно брать заголовки с датой последней модификации(Last_Modifed), но это менее надежно.
в) можно сжать данные перед отправкой, решается настройкой конфига в nginx. Пример. Content-Encoding: gzip
г) можно разбить js на модули и на разных страницах подключать по мере необходимости.
Можно найти еще несколько, но они менее популярны или устарели.
2 то же и с css
3 собрать изображения в спрайты
4 кеширование
а) файлы js и css кешируются навсегда( или на длительный период, к примеру на год), когда в них вносятся какие-то изменения, в результате разработки, меняется номер версии, браузер считает, что это новые файлы и закачивает их. Время кеширование содержится в заголовке expires.
б) файл кешируется до тех пор, пока в нем не произошли изменения. Когда пользователь в первый раз заходит на сайт, у него еще нет кеша, файлы закачиваются и в следующий раз, когда происходит обмен заголовками происходит анализ ETag(хеш суммы содержимого содержимого файла или хеш последнего времени изменения, или номер версии) Если он изменился, то закачивается, в противном случае, берется из хеша.
Так же можно брать заголовки с датой последней модификации(Last_Modifed), но это менее надежно.
в) можно сжать данные перед отправкой, решается настройкой конфига в nginx. Пример. Content-Encoding: gzip
г) можно разбить js на модули и на разных страницах подключать по мере необходимости.
Можно найти еще несколько, но они менее популярны или устарели.
33. CommonJS и AMD или модульность?
Ответ
Один принцип архетектры асинхронен, а второй синхронен. В качестве примера можно привести RequaerJs, по одному его виду можно сказать, что он асинхронен
define — фактически простая функция, все, что написано за ее приделами будет выполняться без оглядки на то, что происходит в define, поэтому одним аргументом идет callbeck-функция. Как только подгрузятся все зависимости, перечисленные в массиве, так они станут доступны внутри через аргументы callbeck-функции.
Система модулей в Node.Js наоборот синхронна. Мы пишем:
и сразу ниже с mod можно работать, все останавливается, пока модуль не загрузится
define([
mod1,
mod2,
mod3
], function (Mod1, Mod2, Mod3) {
new Mod1();
....
});
define — фактически простая функция, все, что написано за ее приделами будет выполняться без оглядки на то, что происходит в define, поэтому одним аргументом идет callbeck-функция. Как только подгрузятся все зависимости, перечисленные в массиве, так они станут доступны внутри через аргументы callbeck-функции.
Система модулей в Node.Js наоборот синхронна. Мы пишем:
var mod = requaer('modul');
и сразу ниже с mod можно работать, все останавливается, пока модуль не загрузится
34. Еще интересный пример. Реализовать методы seven, plus, one, five, minus, two. seven(plus(one())) -> 8. five(minus(two())) -> 3
Ответ
На собеседование я начала решать так:
Аналогично пишутся функции для five, minus, two. Уже дома, поразмышляв в спокойной обстановке, появилось такое решение
function one(arg){
if (typeof arg === 'function') {
return arg(1);
} else {
return 1;
}
}
function seven(arg) {
if (typeof arg === 'function') {
return arg(7);
} else {
return 7;
}
}
function plus(arg) {
return function (a) {
return a + arg;
}
}
Аналогично пишутся функции для five, minus, two. Уже дома, поразмышляв в спокойной обстановке, появилось такое решение
function one(arg) {
return 1 + (arg || 0);
}
function two(arg) {
return 2 + (arg || 0);
}
function five(arg) {
return 5 + (arg || 0);
}
function seven(arg) {
return 7 + (arg || 0);
}
function plus(arg) {
return arg;
}
function minus(arg) {
return -arg;
}
35. Сортировка пузырьком.
Да, да, ее еще спрашивают.
Ответ
var m = [1, 7, 5, 13, 8],
count = m.length - 1,
max;
for (var i = 0; i < count; i++) {
for (var j = 0; j < count - i; j++) {
if (m[j] > m[j + 1]) {
max = m[j];
m[j] = m[j + 1];
m[j + 1] = max;
}
}
}
36. Обратная польская нотация.
Основной принцип. Дана строчка 23+1-, начинаем двигаться по ней, как только доходим до первого арифметического знака, берем две цифры перед ним и на их место, записываем результат вычисления. Получится 51-. Начинаем все с начала.
Кому интересно, вот статья wikipedia
Ответ
Мне рассказали ее принцип, поэтому только реализовать механизм.
var notation = '23+1-', notation1 = '7 2 3 * -', notation2 = '1 2 + 4 * 3 +';
function getComputation(notation) {
var queue = [], tmp, num1, num2;
for (var i = 0; i < notation.length; i++) {
if (/\d+/.test(notation[i]) === true) {
queue.push(Number(notation[i]));
}
else {
switch (notation[i]) {
case '+':
tmp = queue.pop() + queue.pop();
queue.push(tmp);
break;
case '-':
num1 = queue.pop();
num2 = queue.pop();
if (num1 > num2) {
tmp = num1 - num2;
}
else {
tmp = num2 - num1;
}
queue.push(tmp);
break;
case '*':
tmp = queue.pop() * queue.pop();
queue.push(tmp);
break;
case '/':
tmp = queue.pop() / queue.pop();
queue.push(tmp);
break;
}
}
}
return queue[0];
}
console.log(getComputation(notation));
console.log(getComputation(notation1));
console.log(getComputation(notation2));
Мне рассказали ее принцип, поэтому только реализовать механизм.
37. Есть div, в нем другой div, у второго задан padding 50%, как это все будет выглядеть?
Ответ
![](https://habrastorage.org/r/w1560/webt/7_/su/9n/7_su9nvtvjpiso8o-6mywxlndgi.png)
.wrap {
width: 200px;
border: 1px solid green;
}
.block {
width: 200px;
padding-bottom: 50%;
border: 1px solid red;
}
![](https://habrastorage.org/webt/7_/su/9n/7_su9nvtvjpiso8o-6mywxlndgi.png)
Собеседник предложил мне посмотреть дома как оно сработает, хотя мне стало очень интересно.
Как вы считаете, правильно ли на собеседование отвечать самому на вопрос, если кандидат с ним не справился?
38. Есть строка, состоящая из разных скобок, проверить закрыты ли все. Пример строки: "())({}}{()][]["
Ответ
Если бы передавались строки из скобок '{', '[', ']', '}'
function validBraces(str) {
var arrOpenSymbols = [],
result = false,
countOpenSymbols;
if (str.length > 0) {
for (var i = 0; i < str.length; i++) {
if (str[i] === '{' || str[i] === '[' || str[i] === '(') {
arrOpenSymbols.push(str[i]);
} else {
countOpenSymbols = arrOpenSymbols.length;
if ((str[i] === '}' && arrOpenSymbols[(countOpenSymbols-1)] === '{') ||
(str[i] === ']' && arrOpenSymbols[(countOpenSymbols-1)] === '[') ||
(str[i] === ')' && arrOpenSymbols[(countOpenSymbols-1)] === '(')
) {
arrOpenSymbols.pop();
}
}
}
if (arrOpenSymbols.length === 0) {
result = true;
} else {
result = false;
}
}
return result;
}
console.log('');
console.log(validBraces('()'));
console.log(validBraces('[)'));
console.log(validBraces('{}[]()'));
console.log(validBraces('([{}])'));
console.log(validBraces('())({}}{()][]['));
Если бы передавались строки из скобок '{', '[', ']', '}'
function validBraces(str) {
try {
eval(str);
return true;
} catch (err) {
return false;
}
}
39. Напишите код, который при клике на любой div внутри root будет выводить в консоль его id.
<div id="root" style="background: red;">
root
<span id="id1" style="background: lightblue;">id1</span>
<div id="id2" style="background: green;">
id2
<div id="id3" style="background: yellow;">id3</div>
</div>
</div>
Ответ
$('#root').on('click', function (event) {
event.stopPropogation();
console.log($(event.target).attr('id'));
})
40. Напишите код, который сделает из массива объект
// на входе массив
var arr = [
{name: 'width', value: 10},
{name: 'height', value: 20}
]
// на выходе объект
{width: 10, height: 20}
Ответ
function getObj(arr) {
var obj = {};
arr.forEach(function(item){
obj[item.name] = item.value;
});
return obj;
}
41. Что выведется в результате?
var i = 10;
var array = [];
while (i--) {
(function (i) {
var i = i;
array.push(function() {
return i + i;
});
})(i);
}
console.log([
array[0](),
array[1](),
])
Ответ
[18, 16], так как за счет функции
создает замыкание, var i = i — уже принадлежат областям видимости в замыканиях.
в начале поищет в своей области видимости i, не найдя, подымется на уровень выше и там найдет его. Из функции вернется сумма, которая будет положена в массив последним элементом.
(function (i) {})(i);
создает замыкание, var i = i — уже принадлежат областям видимости в замыканиях.
function() { return i + i; }
в начале поищет в своей области видимости i, не найдя, подымется на уровень выше и там найдет его. Из функции вернется сумма, которая будет положена в массив последним элементом.
42. Есть функция и объект. Напишите все известные вам способы, чтобы вывести в консоли значение x из объекта используя функцию
function f() { console.log(this.x); }
var obj = {x: 'bar'};
Ответ
f.call(obj, a, b);
f.apply(obj, [a, b]);
obj.funk = function f() { console.log(this.x); }
obj.funk();
function f() { console.log(this.x); }.bind(obj, a, b);
f();
43.
function Book() {
this.name = 'foo'
}
Book.prototype = {
getName: function() {
return this.name;
}
};
var book = new Book();
Book.prototype.getUpperName = function() {
return this.getName().toUpperCase();
}
book.getUpperName();
Что вернет метод?
а) ошибку, т.к. метод объявлен позже, чем создание экземпляра
б) вернется 'FOO'
Ответ
'FOO'
44. В js переменные объявленные следующим образом:
a=3; b=«hello»;
Укажите правильные утверждения.
а) создаются в локальном контексте
б) создаются в глобальном контексте
в) создание переменной без ключевого слова var — синтаксическая ошибка.
Ответ
б) и в)
45. Что вернёт этот код — typeof (function(){})()
а) callback
б) method
в) undefined
г) function
Ответ
в)
46. Что будет если задать margin: -10px;
47. Почему 0.1 + 0.2 даст 0.30000000000000004
Ответ
Связано с системой представления десятичных чисел, не точностью их вычисления.
48. Моему коллеге на должность php-разраба, предложили такую
Есть два блока, второй скрытый, если в первом нет дочерних элементов, то показать второй.
Представляю вашему вниманию мое решение
<div class="block1">
<div></div>
</div>
<div class="block2">
<div></div>
</div>
.block1 {
width: 150px;
height: 20px;
border: 1px solid red;
}
.block2 {
display: none;
width: 100px;
height: 50px;
border: 1px solid red;
}
function showBlock() {
var block1 = document.getElementsByClassName('block1')[0],
block2 = document.getElementsByClassName('block2')[0];
if (!(block1.childNodes.length > 0 )) {
block2.style.display = 'block';
}
}
document.addEventListener("DOMContentLoaded", function () {
showBlock();
});
Конечно это не все задания, которые мне довелось решать, какие-то я благополучно забыла, какие-то слишком банальные, масса вопросов, просто на теорию, остались за кадром.
Прочее
Вот еще парочка вопросов, они на прямую не касаются фронта, но, наверно не лишне знать.
Идеальный интерфейс в вашем представление?
Как вы бы сделали отказоустойчивый сайт?
Какие типы уязвимостей знаете?
Ссылка на вторую часть — Задачи с собеседований (front-end) часть 2