Pull to refresh

Задачи с собеседований (front-end)

Reading time 18 min
Views 325K
Так получилось, что за свою карьеру front-end разработчика, я побывала на многих собеседованиях. Тема прохождения интервью не теряет своей актуальности, а в комментариях, когда речь заходит о собеседованиях, начинают ломаться копья. Хочу тоже внести свой вклад и поделиться накопившейся коллекцией вопросов. Прошу.

image

Лирическое отступление


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

Задачи


Для начала что-нибудь полегче.

1. Есть некоторая строка (var str = 'fgfggg';), что будет, если мы возьмем str[0]?

Ответ
str[0] вернет символ строки, который находится по нулевому индексу. Строка в js — immutable, то есть из нее можно прочитать символ, а вот записать нет.

2. Реализовать методы, которые в процессе выполнения строки (2).plus(3).minus(1) дали бы на выходе 4.

Ответ
Поскольку, мы работаем с числами, надо расширить прототип Number новыми методами.

Number.prototype.plus = function (value) {
	return this + value;
}

Number.prototype.minus = function (value) {
	return this - value;
}

Число два будет доступно через this в функции plus. Из нее мы возвращаем результат сложения числа, на которое указывает this и числа, переданного в качестве аргумента. Аналогично для minus.

3. Сейчас уже редко, но до сих еще спрашивают: «Почему плохо писать прямо в прототипы базовых типов?»

Ответ
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, при этом у блоков должны быть границы.



Ответ
так или так

8. Как применяются скругленные углы для элементов и стили для текста(шрифт, тип шрифта, цветащте и тд)?

Ответ
Стилевые свойства применятся ко всем элементам с текстом, если у тегов не указаны стилевые правила. К примеру у ссылок указан цвет текста по умолчанию и он более приоритетный, чем определенный нами в body. Дело в том, что для многих свойств по умолчанию стоит значение inherit, то есть как у родителя. Получается поднимается вверх, пока не дойдет до body.
Для свойства border-radius, наоборот, применяется только к тегу, у которого мы хотим что бы били скругленные углы.

9. Что такое ресет стилей?

Ответ
Многим тегам стили прописаны по умолчанию, в процессе верстке нам приходится переопределять их. Что бы не делать это каждый раз, мы «скидываем» их «массово». Для этого заводим файл под стили, подключаем его первым или в первом стилевом файле, в самом верху указываем наши стили для базовых тегов.
К примеру. Мы часто используем список 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. Нарисовать стилями полукруг.


Ответ
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. Что же делать?

Ответ
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. Что будет выведено в консоль, как можно модифицировать пример что бы он возвращал правильный результат(назовите как можно больше способов)?

Ответ
Самый распространенный, обернуть в замыкание

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», но при этом в теле функции нельзя использовать ни цифры, ни буквы, а циклы, массивы, объекты можно, но без цифр.

Ответ
Увы, эти интересные люде не сказали мне как ее решать, поэтому, подумав дома, я могу только предположить.

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? Плюсы, минусы разных способов?

Ответ
Можно с помощью тегов
<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; — скрывает все, что попадет за его пределы.

Модное слово — каррирование


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

30. JSONP, как реализовать


Ответ
Мы не хотим находясь на одном сайте, получать данные с другого и как-то их обрабатывать. Что же делать? Может ajax, но у него есть ограничение по политике бозопасности. Надо что-то совпадали протокол, домен и порт, даже на поддомены мы не можем слать ajax-запросы.
Все же разработчики нашли некий лайфхак для крос-доменных запросов.
Если вы используете 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-заголовки
<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 на модули и на разных страницах подключать по мере необходимости.

Можно найти еще несколько, но они менее популярны или устарели.

33. CommonJS и AMD или модульность?

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

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

Ответ
На собеседование я начала решать так:

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%, как это все будет выглядеть?

Ответ
.wrap {
  width: 200px;
  border: 1px solid green;
}

.block {
  width: 200px;
  padding-bottom: 50%;
  border: 1px solid red;
}



Собеседник предложил мне посмотреть дома как оно сработает, хотя мне стало очень интересно.
Как вы считаете, правильно ли на собеседование отвечать самому на вопрос, если кандидат с ним не справился?

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], так как за счет функции

(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
Tags:
Hubs:
+42
Comments 230
Comments Comments 230

Articles