Skip to content

Instantly share code, notes, and snippets.

@s3rgeym
Last active October 27, 2023 11:49
Show Gist options
  • Save s3rgeym/c45e35634df47fbfebb6f267a126dd4e to your computer and use it in GitHub Desktop.
Save s3rgeym/c45e35634df47fbfebb6f267a126dd4e to your computer and use it in GitHub Desktop.
Запрягли меня значит написать вопросы для собеседования

Общие вопросы

Жизненный цикл JavaScript-приложения

Нужно рассказать как работает JavaScript-приложение. Каждая вкладка браузера ‒ это отдельное приложение. Рендеринг страницы и интрепретация JavaScript происходит в одном потоке, в основном цикле приложения, а значит ресурсоемких операций следует избегать. Следует упомянуть про событийную модель, про то, что она работает на неблокирующих сокетах (в т.ч.).

Тут еще можно вспомнить про requestAnimationFrame.

EcmaScript

Что это (спецификация и язык)? Какая спецификация является текущей (ES 2019)? Какие существуют различия между ними (зачет ‒ вспомнить про const, let, классы, приватные методы, генераторы, Map, Set и т.п.)?

JSON

image

Что такое JSON (JavaScript Object Notation ‒ представление данных, которое является валидным JS кодом)? Какие существуют функции для работы с JSON (JSON.parse, JSON.stringify)? Почему нельзя просто использовать eval? Для чего используется (в этом формате хранятся конфиги, а так же отдается ответ сервера в AJAX-приложениях)?

SPA

image

Что это (Single Page Application)? Как оно работает? Что такое Rest API? Какие есть приницпы проектирования Rest API? Какие есть стандарты (JSON API)? Какие есть альтернативы (SOAP, JSON RPC, GraphQL, Protocol Buffers)?

JavaScript

Задания выполняются на листке/доске, без компа.

Строгое сравнение

Почему всегда нужно использовать строгое сравнение (===)?

Пример:

0 == false // true
[42] == '42' // и т.п.

Определение типа объекта

Чем плохи typeof и instanceof?

typeof null === "object" // true
42 instnaceof Number // false

Напишите функцию isPlainObject(o).

const isPlainObject = o => Object.prototype.toString.call(o) === '[object Object]'

NaN

Что такое (Not A Number)? Как получить такое значение ('foo' / 2)? Как проверить (isNan)?

typeof NaN // "number" охуенно?

Еще про типы

  • Чему равен аргумент функции по-умолчанию(undefined)?
  • Как проверить является ли значение массивом(Array.isArray)?
  • Что будет если поделить число на 0(Вселенная взорвется наху... Infinity вернет)?
  • Как проверить является ли число конечным(isFinite)?
  • Как проверить является ли число целым(Number.isInteger)?
  • Являеются ли строки мутабельными(нет)?
  • При передачи строки в функцию она передается по ссылке или по значению(по ссылке)?

Копирование объектов

Чем отличается передача объекта по ссылке от передачи по значению? Какие объекты передаются по значению?

Задание: напишите самую простую реализацию функции copy(o: <any>) для копирования объекта произвольной вложенности.

function copy(o) {
  return JSON.parse(JSON.stringify(o))
}

var vs const vs let

Чем отличается var от const и let (у const и let область видимости ограничена фигурными скобками {})? Чем отличается const от let (значение, объявленное через const, нельзя присвоить повторно)?

// 1)
{
  let x = 42
}
console.log(x) // что выведет?
// 2)
const arr = []
arr.push(42) // Какую ошибку сгенерирует?

Ответы:

  1. Приведет к ошибке: Uncaught ReferenceError: x is not defined
  2. Ошибки не произойдет

Как сделать объект, например, массив, иммутабельным (неизменяемым)?

Object.freeze(o). Не знает и ладно, потом прочитает.

Замыкания

Классика. На любом собеседованиии задают такой вопрос.

Сам вопрос:

Есть такой код:

for (var i = 0; i < 10; i++) {
  setTimeout(() => console.log(`i=${i}`), 3000)
}

Что будет выведено?

Правильный ответ: «i=10» 10 раз.

Почему так происходит? Как исправить?

for (let i = 0; i < 10; i++) {
  setTimeout(() => console.log(`i=${i}`), 3000)
}

Если справился, то следующий вопрос:

А как бы вы переписали этот код с использованием ES2015:

Правильный ответ:

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

Что означает строка 'use strict' в начале скрипта либо в начале тела функции (включает строгий режим)? Что происходит при его включении (бросаются исключения, например, при попытке присвоить значение ранее необъявленной переменной (в обычном все ок))?

Контекст this

Что выведет этот код?

'use strict'

const test = {
  prop: 42,
  meth() {
    return this.prop
  }
}

const fn = test.meth
console.log(fn())

Ответ:

Будет сгенерирована ошибка TypeError. На что ссылается this в этом примере (window)?

Можно спросить почему так происходит (ответ).

Как исправить?

Вариант 1 (его должны обязательно указать):

const fn = test.meth.bind(test)

Вариант 2:

const fn = () => test.meth()

Так же можно спросить чем отличаются стрелочные функции от анонимных и в чем их преимущество (стрелочные функции захватывают контекст this).

Обмен значениями

Данные две переменные x = 3 и y = 5.

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

Ответ:

[ x, y ] = [ y, x ]

Правильным так же является и ответ типа такого:

x = x ^ y
y = x ^ y
x = x ^ y

Но он для надмозгов.

Спреды

Как используются спреды (что это я и сам затруднюсь ответить)?

// При объявлении функции с произвольным количеством аргументов
function foo(...args) {
  console.log(args)
}

foo(1, 2, 3) // args будет содержать массив [1, 2, 3]

// Спреды можно использовать при передаче списка аргументов
Math.max(...[3, 5, 1])

// Является альтернативой использованию метода функции apply
Math.max.apply(null, [3, 5, 1])

const [ first, ...rest ] = [1, 2, 3, 4, 5]
console.log(first) // содержит 1
console.log(rest) // [2, 3, 4, 5]

Колбеки

Что такое -/- (функция-обработчик, передаваемая в функцию в качестве аргумента и вызываемая внутри этой фунгкции с передачей ей результата выполнения какой-то асинхронной операции)? Что такое callback-hell (множество вложенных колбеков)? Как избежать его (использовагние промисов)?

image

Promises

image

Что такое Promise?

‒ Это бъект, которые позволяет обрабатывать результаты асинхронны операций в будущем.

Для чего нужны async/await?

Напишите асинхронную функции sleep вида:

function sleep(timeout) {
  [some code]
}

// Пример использования
async run() {
  console.log('Ждем 3 секунды')
  await sleep(3000)
  console.log('Продолжаем работу...')
}

Решение:

function sleep(timeout) { 
  return new Promise((resolve, reject) => setTimeout(resolve, timeout)) 
}

Генераторы

  • В: Что такое генераторы?
  • О: Это функции, которые приостанавливают свое выполнение в определенной точке и при последующих вызовах продолжает выполнение с этой точки.

Общий вид:

function* g() {
  yield 'foo'
  yield 'bar'
  yield 'baz'
}

Что возвращает функция генератор (итератор)? Что делает оператор yield (приостонавливает выполнение функции и возвращает значение, но в отличии от return при последующем вызове функции продолжает работу с места остановки)? С помощью какого метода можно получить текущее значение итератора (next)? Что он возвращает(объект вида: { value: <any>, done: <bool> })?

Какая конструкция используется для цикла по итератору?

Ответ:

for (let it of g()) {
  // ...
}

Задание: напишите с использование генераторов функцию, возвращающую числа Фиббоначи.

Ряд Фиббоначи выглядит следующим образом:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, …

В нем каждое последующее число равно сумме двух предыдущих.

Решение:

function* fib() {
  let [ cur, next ] = [ 0, 1 ]
  for (;;) {
    yield cur
    ;[ cur, next ] = [ next, cur + next ]
  }
}

Что делает функция fetch?

‒ Возвращает Promise и делает запрос.

В чем ее преимущество по сравнению с XMLHttpRequest (коротко: более богатый API)?

ООП

Нет ни одного js-кодера, который не пытался написать свой eventEmitter.

Напишите class EventEmitter:

class EventEmitter {
  // ...
  on(event, listener) {
    // ...
  }
  off(event, listener) {
    // ...
  }
  emit(event, ...args) {
    // ...
  }
}

const events = new EventEmitter()
events.on('greeting', name => {
  console.log(`Hello ${name}!`)
})
events.emit('greeting', 'Sergey')

Решение:

class EventEmitter {
  // Приватные методы (NEW)
  // Используем Map вместо Plain Object, 
  // так как у первого ключами могут быть любые объекты, а не только строки +
  // не нужна проверка hasOwnProperty
  #listeners = new Map()
  
  on(event, listener) {
    let listeners = this.#listeners.get(event)
    if (!listeners) {
      // Используем Set вместо Array, чтобы нельзя было добавить один и тот же 
      // обработчик два раза
      listeners = new Set()
      this.#listeners.set(event, listeners)
    }
    listeners.add(listener)
    return this
  }
  off(event, listener) {
    const listeners = this.#listeners.get(event)
    if (listeners) {
      listeners.delete(listener)
      // Если листенеров больше не осталось, то нужно удалить ключ
      if (listeners.size === 0) {
        this.#listeners.delete(event)
      }
    }
    return this
  }
  emit(event, ...args) {
    const listeners = this.#listeners.get(event)
    if (listeners) {
      for (const listener of listeners) {
        listener(...args)
      }
    }
    return this
  }
}

Еще вопросы:

  • Для чего нужен super? Как вызвать родительский конструктор(super([args]) в методе construct класса наследника)? Как обратиться к родительскому методу(super.meth)?
  • Что такое геттеры и сеттеры?
  • Как происходит наследование (extends)?
  • Как сделать метод статическим (static)?

Сессии

Что такое cookies (небольшие порции данных, которые хранятся на стороне клиента)?

Как установить cookie со значением foo=bar на неопределенный срок?

document.cookie = 'foo=bar'

Как получить все куки в виде объекта (ассоциативного массива)?

// Такой вариант
const c={}
document.cookie.split('; ').forEach(pair => {
 const [ k, v ] = pair.split('=')
 c[decodeURIComponent(k)] = decodeURIComponent(v) 
})
console.log(c)
// Тру функицональщина
document.cookie.split('; ').reduce((acc, pair) => {
 const [ k, v ] = pair.split('=', 2).map(decodeURIComponent)
 acc[k] = v
 return acc
}, {})

// С циклами не айс

Как еще можно хранить сессионные данные на стороне клиента (localStorage)?

Что такое JWT?

JSON Web Tokens ‒ токены, хранящиеся на стороне клиента. Такой токен состоит из трех частей: заголовков, тела и сигнатуры. В теле хранятся сессионные данные (обычно идентефикатор пользователя). Сигнатуру нельзя подделать не зная секретного ключа (который хранится на сервере).

Модули

Какие ключевые слова используется при работе с модулями (import/export)?

Нужно привести примеры:

// Если функция экспортируется так
export const func = () => {}

// То ее импорт выглядит так
import { func } from './lib'

// Можно импортировать под другим именем
import { func as name } from './lib'

// Можно импортировать все под определенным неймспейсом
import { * as lib } from './lib'

// Нужно упомянуть про export default
export default ...

// При его использование импортировать можно только так
import lib from './lib'

Можно ли использовать import/export в браузере без компиляторов типа Babel?

‒ Да.

<script type="module" src="main.js">

В main.js можно испортировать уже привычным образом.

DOM

Что такое DOM?

‒ Это представление документа в виде дерева узлов. Каждый узел представляет собой элемент определенного типа (элемент, текст, комментарий, атрибут, документ, фрагмент и т.д.). Узлы содержат ссылки на детей и родителей.

Какие существуют методы для поиска элементов на странице с помощью CSS-селекторов

О: [ Document | Element ].querySelector и [ Document | Element ].querySelectorAll.

Как с помощью querySelector выбрать вторую колонку таблицы со значением Second?

<!doctype html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <table>
      <tr>
        <td>First</td>
        <td>Second</td>
        <td>Third</td>
      </tr>
    </table>
  </body>
</html>

Ответ:

document.querySelector('td:nth-child(2)')

А как сделать тоже самое, но без querySelector?

document.getElementsByTagName('td')[1]

Vue

VDOM

Что такое виртуальный DOM? Суть: позволяет избежать повторного построения DOM-дерева, если данные (модель) не изменились.

Two-Way Binding

Что это? ‒ Это механизм, позволяющий синхронизировать изменения модели и представления.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment