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

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

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

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

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

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

Задачи

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

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

Ответ

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

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

Курс «Верстка сайтов на HTML и CSS»

Запусти интернет-магазин в США!

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

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

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

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

Ответ

123Array.prototype.sort = function () {}var t = [2, 1, 22];t.sort()

Ожидаемый результат — [1, 2, 22], а вернется undefined.
Мы рассчитываем, что стандартные методы сработают согласно документации, но какой-то разработчик можем переопределить метод, и он вернет совершенно неожиданный результат.
Именно поэтому библиотека prototype.js уступила jQuery.

4. Дана функция, она принимает в качестве аргументов строки ‘*’, ‘1’, ‘b’, ‘1c’, реализуйте ее так, что бы она вернула строку ‘1*b*1c’

ОтветЕе можно решать прямо в лоб, перебирая в цикле все аргументы, но мы поступим умнее.

123function 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

ОтветЯ решила задачу рекурсией, потом мы упростили решение, а затем переписали на очередь.

Рекурсия.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758var 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));

Очередь.

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

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

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

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

9. Что такое ресет стилей?ОтветМногим тегам стили прописаны по умолчанию, в процессе верстке нам приходится переопределять их. Что бы не делать это каждый раз, мы «скидываем» их «массово». Для этого заводим файл под стили, подключаем его первым или в первом стилевом файле, в самом верху указываем наши стили для базовых тегов.
К примеру. Мы часто используем список ul для верстки меню, для этого мы каждый раз вынуждены обнулять padding, margin и list-style-type. Можно один раз задать стили, и списки станут без внешней и внутренней границы, а так же без маркеров.

10. Требуется сверстать попап по центру, его размеры нам известны, но мы не хотим что бы он прокручивался вместе со страницей, причем по высоте может и не влезать в высоту экрана.

Ответ

123456789101112131415161718192021222324body {  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. Нарисовать стилями полукруг.

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

Ответ

1234width: 100px;height: 100px;border-right: 1px solid #f00;border-radius: 0 50% 50% 0;

12. Есть массив в котором лежат объекты с датами, отсортировать по датам.Ответ

123456789101112131415161718192021var 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. Есть несколько слов, определить состоят ли они из одних и тех же букв(‘кот’, ‘ток’, ‘окт’)
Ответ

1234567891011121314151617181920212223242526272829var 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, что затрудныло работу с кодом, отлаживание ошибок и им на смену пришли промисы.

123456var promis = new Promise(function (resolve, reject) {  …  setTimeout(function () {    resolve(res);  }, 5000);});

Несколько промисов можно объединить и получить разом ответ от них

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

123456789101112function 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)Вот еще один примерчик на асинхронность. Объяснить в какой последовательности выведутся цифры и почему так.

12345console.log(1);setTimeout(function() {  console.log(2);}, 0)console.log(3);

Достаточно популярный, надо сказать. Вот мне он и достался в очередной раз. Уже отработано начала отвечать: «1, 3, 2. Так как хоть js и асинхронен, но внутри его есть очередь выполнения и setTimeout и setInterval, если им указан 0, помещают вызов функции в конец очереди.»
Тут надо сказать ребята зафейлились, заявив, что я ответила правильно, про 132, но не объяснила почему.

(20)Вообще вопросы на setTimeout и setInterval весьма актуальны.Меня спрашивали: «Какое минимальное время можно задать?»ОтветВ каждом браузере есть свой минимум, если вы указываете меньше него, то все равно задержка будет не меньше минимуму. Иногда даже и больше указанного времени, так как задача попадает в очередь и время складывается из заданного плюс затраты в на выполнение на задач в очереди перед ней.

Куда же без замыканий

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

12345for (var i = 0; i < 10; i++) {  setTimeout(function () {    console.log(i);  }, 100);}

21. Что будет выведено в консоль, как можно модифицировать пример что бы он возвращал правильный результат(назовите как можно больше способов)?ОтветСамый распространенный, обернуть в замыкание

1234567for (var i = 0; i < 10; i++) {  (function (i) {    setTimeout(function () {      console.log(i);    }, 100);  })(i)}

Не все обращали внимание, что в i можно передать не только контекст

12345for (var i = 0; i < 10; i++) {  setTimeout(function (i) {    console.log(i);  }.bind(this, i), 100);}

Так же методам setInterval и setTimeout можно передать аргументы, которые будут прокинуты в качестве аргументов калбек-функции

12345for (var i = 0; i < 10; i++) {  setTimeout(function (i) {    console.log(i);  }, 100, i);}

es6

12345for (let i = 0; i < 10; i++) {  setTimeout(function () {    console.log(i);  }, 100);}

Одна из возможностей es6, в данном случае сработает несколько неожиданно, let не в блоке {}.

Давайте что-нибудь похардкорнее.

22. Надо написать функцию, которая вернет «hello world», но при этом в теле функции нельзя использовать ни цифры, ни буквы, а циклы, массивы, объекты можно, но без цифр.ОтветУвы, эти интересные люде не сказали мне как ее решать, поэтому, подумав дома, я могу только предположить.

123456var 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).

Мне пришло в голову более экзотическое решение. Детям и слабонервным лучше не смотреть.

1234var sum = 101*50,     sumArr = eval([4, 2, … 3, 7].join(‘+’).replace(‘++’, ‘+’)),     res;res = sum-sumArr;

Просто мне вспомнилось, что когда-то спрашивали: «Как быстрее всего найти сумму элементов массива?»Ответ

1eval([4, 2, … 3, 7].join(‘+’)

Вот на тот момент вспомнилось и не пришло ни чего лучше.

(24) Вот еще фейл-задача. Приведу дословно, те напишу как написали мне.

1234567function Book(name, author) {    this.name = name;    this.author = author;    return this;} function Foo(Book, ‘Учебник javascript’, ‘Петр Сергеев’)

Реализовать FooОтветМеня сбила эта строчка function Foo(Book, ‘Учебник javascript’, ‘Петр Сергеев’). Только я вижу, что здесь что-то не так? Мне предложили решать через Object.create(), но я не согласна. Свойства и методы, записаные в саму функцию-конструктор, не будут «скопированы» Object.create.

12345678910111213function 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

Конечно меня не взяли, а на последок посоветовали лучше учить теорию. Хнык-хнык.
В любом случае, я бы предпочла решать так.

123456789101112function 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 — это не вариант, а в регулярках я не сильна, да и сработает он до первого подходящего вхождения. Я не привыкла оставлять за спиной что-то непонятное, поэтому разобралась как реализовать функцию.

12345678function isPalindrom1(str) {    if (str.toLowerCase().replace(/[^а-яА-ЯёЁ]/g, ”) === str.toLowerCase().replace(/[^а-яА-ЯёЁ]/g,     ”).split(”).reverse().join(”)) {        return true;     } else {        return false;     }}

Красиво, просто, изящно.

Забавно, но где-то через год мне попался этот же вопрос. Я обрадовалась: «Свезло». Как оказалось, нет. Требовалось решить с помощью цикла, а регулярку можно было использовать только для одного символа. Собеседник мотивировал это тем, что replace с регуляркой по всей строке — слишком ресурсоемко.

Подумав дома, у меня получилось вот так:

12345678910111213141516171819202122function 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

123456789function 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Ответ

1234567891011function 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

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

1234567891011function 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 приблизительно такая

12345678910var 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…’>

На сервере ресурса сработает что-то в этом роде

1echo $_REQUEST[callback] + ‘(‘ + json_encode($arDate) + ‘)’;

В window попадет

123window.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, по одному его виду можно сказать, что он асинхронен

12345678define([  mod1,  mod2,  mod3], function (Mod1, Mod2, Mod3) {  new Mod1();  ….});

define — фактически простая функция, все, что написано за ее приделами будет выполняться без оглядки на то, что происходит в define, поэтому одним аргументом идет callbeck-функция. Как только подгрузятся все зависимости, перечисленные в массиве, так они станут доступны внутри через аргументы callbeck-функции.
Система модулей в Node.Js наоборот синхронна. Мы пишем:

1var mod = requaer(‘modul’);

и сразу ниже с mod можно работать, все останавливается, пока модуль не загрузится

34. Еще интересный пример. Реализовать методы seven, plus, one, five, minus, two. seven(plus(one())) -> 8. five(minus(two())) -> 3ОтветНа собеседование я начала решать так:

123456789101112131415161718192021function 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. Уже дома, поразмышляв в спокойной обстановке, появилось такое решение

1234567891011121314151617181920212223function 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. Сортировка пузырьком.

Да, да, ее еще спрашивают.
Ответ

123456789101112var 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
Ответ

12345678910111213141516171819202122232425262728293031323334353637383940var 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;}
Задачи с собеседований (front-end)

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

38. Есть строка, состоящая из разных скобок, проверить закрыты ли все.  Пример строки: «())({}}{()][][»Ответ

12345678910111213141516171819202122232425262728293031323334function 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(‘())({}}{()][][‘));

Если бы передавались строки из скобок ‘{‘, ‘[‘, ‘]’, ‘}’

12345678function 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. Напишите код, который сделает из массива объект
// на входе массив

1234var arr = [ {name: ‘width’, value: 10}, {name: ‘height’, value: 20}]

// на выходе объект

1{width: 10, height: 20}

Ответ

123456789function getObj(arr) {    var obj = {};        arr.forEach(function(item){        obj[item.name] = item.value;    });        return obj;}

41. Что выведется в результате?

12345678910111213141516var 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 — уже принадлежат областям видимости в замыканиях.

1function() { return i + i; }

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

42. Есть функция и объект. Напишите все известные вам способы, чтобы вывести в консоли значение x из объекта используя функцию

12function f() { console.log(this.x); }var obj = {x: ‘bar’};

Ответ

12345678f.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.

1234567891011121314151617function 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;}
12345678910function 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();});

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

Прочее

Вот еще парочка вопросов, они на прямую не касаются фронта, но, наверно не лишне знать.
Идеальный интерфейс в вашем представление?
Как вы бы сделали отказоустойчивый сайт?
Какие типы уязвимостей знаете?