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

Лирическое отступление
На собеседования меня приглашают охотно, не знаю, виной этому симпатичная фоточка в резюме или его содержание. Если о резюме, то для описания технологий, используемых на каждой текущей работе, я трачу часа два, три. Порой просматриваю в чужие, как они оформлены, да и вдруг найду что-то полезное для себя…
Задачи
Для начала что-нибудь полегче.
1. Есть некоторая строка (var str = ‘fgfggg’;), что будет, если мы возьмем str[0]?
Ответ
str[0] вернет символ строки, который находится по нулевому индексу. Строка в js — immutable, то есть из нее можно прочитать символ, а вот записать нет.
2. Реализовать методы, которые в процессе выполнения строки (2).plus(3).minus(1) дали бы на выходе 4.Ответ
Курс «Верстка сайтов на HTML и CSS»
Запусти интернет-магазин в США!
Не окупается трафик?Поскольку, мы работаем с числами, надо расширить прототип Number новыми методами.
| 1234567 | Number.prototype.plus = function (value) { return this + value;} Number.prototype.minus = function (value) { return this – value;} |
Число два будет доступно через this в функции plus. Из нее мы возвращаем результат сложения числа, на которое указывает this и числа, переданного в качестве аргумента. Аналогично для minus.
3. Сейчас уже редко, но до сих еще спрашивают: «Почему плохо писать прямо в прототипы базовых типов?»
Ответ
| 123 | 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’
ОтветЕе можно решать прямо в лоб, перебирая в цикле все аргументы, но мы поступим умнее.
| 123 | function getStr() { return [].slice.call(arguments, 1).join(arguments[0])} |
5. Дано дерево, надо найти сумму всех вершин.https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-5265008544060842&output=html&h=174&slotname=6021157728&adk=3433315321&adf=1003853764&pi=t.ma~as.6021157728&w=696&fwrn=4&lmt=1579122260&rafmt=11&tp=site_kit&psa=1&format=696×174&url=https%3A%2F%2Fbookflow.ru%2Fzadachi-s-sobesedovanij-front-end%2F&flash=0&wgl=1&adsid=ChEI8J2thQYQzuX0pJySqsr6ARJMACsQijhlccQW8Xb_JrKOtSWAEfxP5aiipY3IlFMs6dJ80Ju3MppacMAcAoXjyQjEP4HHf6wcK42dn0AfKMP1enclJF3C1Q5jEPu66A&uach=WyJXaW5kb3dzIiwiMTAuMCIsIng4NiIsIiIsIjkwLjAuNDQzMC4yMTIiLFtdXQ..&dt=1621874715002&bpp=47&bdt=785&idt=1162&shv=r20210517&cbv=%2Fr20190131&ptt=9&saldr=aa&abxe=1&cookie=ID%3D6743a4d5726e8698-22b0e3801dc80040%3AT%3D1621872912%3ART%3D1621872912%3AS%3DALNI_MYsDLDw-OY4dK_E-l9g4cMH2sxZEw&prev_fmts=0x0%2C728x90%2C324x250%2C1349x625&nras=3&correlator=4947704027232&frm=20&pv=1&ga_vid=718439799.1621874716&ga_sid=1621874716&ga_hid=615518131&ga_fc=0&rplot=4&u_tz=180&u_his=1&u_java=0&u_h=768&u_w=1366&u_ah=728&u_aw=1366&u_cd=24&u_nplug=3&u_nmime=4&adx=141&ady=2893&biw=1349&bih=625&scr_x=0&scr_y=500&eid=42530672%2C31060614&oid=3&psts=AGkb-H_d9QpZpuCVVjcgNARwnbGtSSgz0SEF1zDUe_cKdjtDDUWgKPhRNk-dRUfoZnQRND5w1iXlNql0HA5s&pvsid=976531787617029&pem=314&eae=0&fc=1920&brdim=0%2C0%2C0%2C0%2C1366%2C0%2C1366%2C728%2C1366%2C625&vis=1&rsz=%7C%7CoeEbr%7C&abl=CS&pfx=0&fu=128&bc=31&jar=2021-05-24-11&ifi=3&uci=a!3&btvi=2&fsb=1&xpc=a07uaMQpSH&p=https%3A//bookflow.ru&dtd=26339
ОтветЯ решила задачу рекурсией, потом мы упростили решение, а затем переписали на очередь.
Рекурсия.
| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 | 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)); |
Очередь.
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 | 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. Требуется сверстать попап по центру, его размеры нам известны, но мы не хотим что бы он прокручивался вместе со страницей, причем по высоте может и не влезать в высоту экрана.
Ответ
| 123456789101112131415161718192021222324 | 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. Нарисовать стилями полукруг.

Ответ
| 1234 | width: 100px;height: 100px;border-right: 1px solid #f00;border-radius: 0 50% 50% 0; |
12. Есть массив в котором лежат объекты с датами, отсортировать по датам.Ответ
| 123456789101112131415161718192021 | 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. Есть несколько слов, определить состоят ли они из одних и тех же букв(‘кот’, ‘ток’, ‘окт’)
Ответ
| 1234567891011121314151617181920212223242526272829 | 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, что затрудныло работу с кодом, отлаживание ошибок и им на смену пришли промисы.
| 123456 | var promis = new Promise(function (resolve, reject) { … setTimeout(function () { resolve(res); }, 5000);}); |
Несколько промисов можно объединить и получить разом ответ от них
| 123456789101112131415161718 | 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. Что же делать?
Ответ
| 123456789101112 | 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)Вот еще один примерчик на асинхронность. Объяснить в какой последовательности выведутся цифры и почему так.
| 12345 | console.log(1);setTimeout(function() { console.log(2);}, 0)console.log(3); |
Достаточно популярный, надо сказать. Вот мне он и достался в очередной раз. Уже отработано начала отвечать: «1, 3, 2. Так как хоть js и асинхронен, но внутри его есть очередь выполнения и setTimeout и setInterval, если им указан 0, помещают вызов функции в конец очереди.»
Тут надо сказать ребята зафейлились, заявив, что я ответила правильно, про 132, но не объяснила почему.
(20)Вообще вопросы на setTimeout и setInterval весьма актуальны.Меня спрашивали: «Какое минимальное время можно задать?»ОтветВ каждом браузере есть свой минимум, если вы указываете меньше него, то все равно задержка будет не меньше минимуму. Иногда даже и больше указанного времени, так как задача попадает в очередь и время складывается из заданного плюс затраты в на выполнение на задач в очереди перед ней.
Куда же без замыканий
Не давно выделили целую статью для этого примера(тут), читатели в комментариях расписывали всевозможные способы решения, от традиционных до фантастических. Вот о которых я обычно рассказывала на собеседованиях.
| 12345 | for (var i = 0; i < 10; i++) { setTimeout(function () { console.log(i); }, 100);} |
21. Что будет выведено в консоль, как можно модифицировать пример что бы он возвращал правильный результат(назовите как можно больше способов)?ОтветСамый распространенный, обернуть в замыкание
| 1234567 | for (var i = 0; i < 10; i++) { (function (i) { setTimeout(function () { console.log(i); }, 100); })(i)} |
Не все обращали внимание, что в i можно передать не только контекст
| 12345 | for (var i = 0; i < 10; i++) { setTimeout(function (i) { console.log(i); }.bind(this, i), 100);} |
Так же методам setInterval и setTimeout можно передать аргументы, которые будут прокинуты в качестве аргументов калбек-функции
| 12345 | for (var i = 0; i < 10; i++) { setTimeout(function (i) { console.log(i); }, 100, i);} |
es6
| 12345 | for (let i = 0; i < 10; i++) { setTimeout(function () { console.log(i); }, 100);} |
Одна из возможностей es6, в данном случае сработает несколько неожиданно, let не в блоке {}.
Давайте что-нибудь похардкорнее.
22. Надо написать функцию, которая вернет «hello world», но при этом в теле функции нельзя использовать ни цифры, ни буквы, а циклы, массивы, объекты можно, но без цифр.ОтветУвы, эти интересные люде не сказали мне как ее решать, поэтому, подумав дома, я могу только предположить.
| 123456 | 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).
Мне пришло в голову более экзотическое решение. Детям и слабонервным лучше не смотреть.
| 1234 | var sum = 101*50, sumArr = eval([4, 2, … 3, 7].join(‘+’).replace(‘++’, ‘+’)), res;res = sum-sumArr; |
Просто мне вспомнилось, что когда-то спрашивали: «Как быстрее всего найти сумму элементов массива?»Ответ
| 1 | eval([4, 2, … 3, 7].join(‘+’) |
Вот на тот момент вспомнилось и не пришло ни чего лучше.
(24) Вот еще фейл-задача. Приведу дословно, те напишу как написали мне.
| 1234567 | 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.
| 12345678910111213 | 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 |
Конечно меня не взяли, а на последок посоветовали лучше учить теорию. Хнык-хнык.
В любом случае, я бы предпочла решать так.
| 123456789101112 | 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 — это не вариант, а в регулярках я не сильна, да и сработает он до первого подходящего вхождения. Я не привыкла оставлять за спиной что-то непонятное, поэтому разобралась как реализовать функцию.
| 12345678 | function isPalindrom1(str) { if (str.toLowerCase().replace(/[^а-яА-ЯёЁ]/g, ”) === str.toLowerCase().replace(/[^а-яА-ЯёЁ]/g, ”).split(”).reverse().join(”)) { return true; } else { return false; }} |
Красиво, просто, изящно.
Забавно, но где-то через год мне попался этот же вопрос. Я обрадовалась: «Свезло». Как оказалось, нет. Требовалось решить с помощью цикла, а регулярку можно было использовать только для одного символа. Собеседник мотивировал это тем, что replace с регуляркой по всей строке — слишком ресурсоемко.
Подумав дома, у меня получилось вот так:
| 12345678910111213141516171819202122 | 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? Плюсы, минусы разных способов?ОтветМожно с помощью тегов
| 12 | <script></script><style></style> |
прямо на странице или
| 12 | <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
| 123456789 | 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Ответ
| 1234567891011 | 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
Самый сложный вариант, когда вызов этой конструкции не заканчивается пустыми скобками, а значит мы не имеем явного указателя на выход.В итоге получилось
| 1234567891011 | 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 приблизительно такая
| 12345678910 | 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 помещается функция, которая вызовется, при получение данных от ресурса, они станут доступны внутри через параметр.
| 1 | <script src=’http://mydomen.com/news.php?callback0.90428777…’> |
На сервере ресурса сработает что-то в этом роде
| 1 | echo $_REQUEST[callback] + ‘(‘ + json_encode($arDate) + ‘)’; |
В window попадет
| 123 | window.jsonCallback0.90428777 -> function (response) { console.log(response);} |
Так как теги с атрибутом src способы посылать только GET запросы, то jsonp не поддерживает POST
31. Заголовки CORS?ОтветЭто альтернатива jsonp, в специальном заголовках перечисляются «доверенные» ресурсы, которые смогут получать данные от него, а если указать ‘*’, то любые сайты, при обращение, станут получать данные.
Так же как и с jsonp доступны только GET запросы.
Когда я рассказывала про альтернативу jsonp интервьюер от этого вариант «отмахнулся», сказав, что не надежный. Я с ним не согласна. JSONP легче подменить, чем CORS-заголовки
| 1 | <script src=”http://bla-bla/get?callback=f’></script> |
| 1 | <? echo $GET[‘callback’].'(‘.$date.’)’; |
В date подпихнуть вут такую строчку
| 1 | ‘);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, по одному его виду можно сказать, что он асинхронен
| 12345678 | define([ mod1, mod2, mod3], function (Mod1, Mod2, Mod3) { new Mod1(); ….}); |
define — фактически простая функция, все, что написано за ее приделами будет выполняться без оглядки на то, что происходит в define, поэтому одним аргументом идет callbeck-функция. Как только подгрузятся все зависимости, перечисленные в массиве, так они станут доступны внутри через аргументы callbeck-функции.
Система модулей в Node.Js наоборот синхронна. Мы пишем:
| 1 | var mod = requaer(‘modul’); |
и сразу ниже с mod можно работать, все останавливается, пока модуль не загрузится
34. Еще интересный пример. Реализовать методы seven, plus, one, five, minus, two. seven(plus(one())) -> 8. five(minus(two())) -> 3ОтветНа собеседование я начала решать так:
| 123456789101112131415161718192021 | 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. Уже дома, поразмышляв в спокойной обстановке, появилось такое решение
| 1234567891011121314151617181920212223 | 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. Сортировка пузырьком.
Да, да, ее еще спрашивают.
Ответ
| 123456789101112 | 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
Ответ
| 12345678910111213141516171819202122232425262728293031323334353637383940 | 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%, как это все будет выглядеть?Ответ
| 12345678910 | .wrap { width: 200px; border: 1px solid green;} .block { width: 200px; padding-bottom: 50%; border: 1px solid red;} |

Собеседник предложил мне посмотреть дома как оно сработает, хотя мне стало очень интересно.
Как вы считаете, правильно ли на собеседование отвечать самому на вопрос, если кандидат с ним не справился?
38. Есть строка, состоящая из разных скобок, проверить закрыты ли все. Пример строки: «())({}}{()][][»Ответ
| 12345678910111213141516171819202122232425262728293031323334 | 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(‘())({}}{()][][‘)); |
Если бы передавались строки из скобок ‘{‘, ‘[‘, ‘]’, ‘}’
| 12345678 | function validBraces(str) { try { eval(str); return true; } catch (err) { return false; }} |
39. Напишите код, который при клике на любой div внутри root будет выводить в консоль его id.
| 12345678 | <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> |
Ответ
| 1234 | $(‘#root’).on(‘click’, function (event) { event.stopPropogation(); console.log($(event.target).attr(‘id’));}) |
40. Напишите код, который сделает из массива объект
// на входе массив
| 1234 | var arr = [ {name: ‘width’, value: 10}, {name: ‘height’, value: 20}] |
// на выходе объект
| 1 | {width: 10, height: 20} |
Ответ
| 123456789 | function getObj(arr) { var obj = {}; arr.forEach(function(item){ obj[item.name] = item.value; }); return obj;} |
41. Что выведется в результате?
| 12345678910111213141516 | 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], так как за счет функции
| 1 | (function (i) {})(i); |
создает замыкание, var i = i — уже принадлежат областям видимости в замыканиях.
| 1 | function() { return i + i; } |
в начале поищет в своей области видимости i, не найдя, подымется на уровень выше и там найдет его. Из функции вернется сумма, которая будет положена в массив последним элементом.
42. Есть функция и объект. Напишите все известные вам способы, чтобы вывести в консоли значение x из объекта используя функцию
| 12 | function f() { console.log(this.x); }var obj = {x: ‘bar’}; |
Ответ
| 12345678 | 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.
| 1234567891011121314151617 | 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-разраба, предложили такую
Есть два блока, второй скрытый, если в первом нет дочерних элементов, то показать второй.Представляю вашему вниманию мое решение
| 123456 | <div class=”block1″> <div></div></div><div class=”block2″> <div></div></div> |
| 1234567891011 | .block1 { width: 150px; height: 20px; border: 1px solid red;}.block2 { display: none; width: 100px; height: 50px; border: 1px solid red;} |
| 12345678910 | 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();}); |
Конечно это не все задания, которые мне довелось решать, какие-то я благополучно забыла, какие-то слишком банальные, масса вопросов, просто на теорию, остались за кадром.
Прочее
Вот еще парочка вопросов, они на прямую не касаются фронта, но, наверно не лишне знать.
Идеальный интерфейс в вашем представление?
Как вы бы сделали отказоустойчивый сайт?
Какие типы уязвимостей знаете?