Русский
Русский
English
Статистика
Реклама

Перевод Вопросы, которые мне задавали на фронтенд-собеседованиях

Всем привет. В сентябре OTUS вновь запускает целую линейку курсов по JavaScript. Прямо сейчас вы можете посмотреть запись открытого урока по курсу "JavaScript Developer. Professional", а также зарегистрироваться на дни открытых дверей по курсам "React.js Developer" и "JavaScript Developer. Basic". Ну а мы традиционно делимся с вами переводом полезного материала.


Фронтенд-собеседование (в 2 частях)

1. Вопросы, которые мне задавали на фронтенд-собеседованиях.

2. Ресурсы для подготовки к собеседованию (на должность фронтенд-разработчика).

Вопросы, которые задавали на фронтенд-собеседованиях


В этой статье я собрал все вопросы, которые мне задавали на собеседованиях во время поиска работы в условиях пандемии COVID-19. Я также составил список ресурсов, которыми пользовался при подготовке к собеседованию.


Вопросы я разделил на четыре части.

  • JS

  • Код

  • Задачи

  • Другие вопросы

Представленный код не является готовым решением, но лишь дает общее представление о моем подходе. Попробуйте реализовать свой собственный.

Отредактировано 20.08.2020. Посмотреть изменения

JS

1. Есть многомерный массив глубиной N, который нужно сгладить. После сглаживания используйте его в качестве метода и привяжите к экземпляру объекта array.

Решение:

/** * [1,2,[3,4]] -> [1,2,3,4] */let arr = [1,2,[3,4, [5,6, [7, [8, 9, 10]]]]]function flatten(arr) {  return arr.reduce(function(acc, next){    let isArray =  Array.isArray(next)    return acc.concat(isArray ? flatten(next) : next)  }, [])}if (!Array.prototype.flatten) {  Array.prototype.flatten = function() {    return flatten(this)  }}console.log(arr.flatten());

2. Создайте промис с нуля

Решение:

class CustomPromise {  state = "PENDING"  value = undefined  thenCallbacks = []  errorCallbacks = []  constructor(action) {    action(this.resolver.bind(this), this.reject.bind(this))  }  resolver(value) {    this.state = "RESOLVED"    this.value = value    this.thenCallbacks.forEach((callback) => {      callback(this.value)    })  }  reject(value) {    this.state = "REJECTED"    this.value = value    this.errorCallbacks.forEach((callback) => {      callback(this.value)    })  }  then(callback) {    this.thenCallbacks.push(callback)    return this   }  catch (callback) {    this.errorCallbacks.push(callback)    return this   }}let promise = new CustomPromise((resolver, reject) => {  setTimeout(() => {    const rand = Math.ceil(Math.random(1 * 1 + 6) * 6)    if (rand > 2) {      resolver("Success")    } else {      reject("Error")    }  }, 1000)})promise  .then(function(response){    console.log(response)  })  .catch(function(error){    console.log(error)  })

3. Отфильтруйте список фильмов по среднему рейтингу, названию. Отсортируйте отфильтрованный список по любому полю.

Решение:

// O(M)function getMovies() {  return []; // [{id, name, year}]}// O(R)function getRatings() {  return []; // [{id, movie_id, rating}]   0 <= rating <= 10   // e.g 9.3}/** * minAvgRating -> *    avgRating >= minAvgRating * * sort -> *    name -> ascending order movies by name *   -name -> descending * *    avgRating *  * * search -> *   'ave' -> 'Avengers' *   'avengers' -> 'Avengers' *   'AvengersInfinitywar' -> 'Avengers' */const toLower = str => str.toLocaleLowerCase()const getAvrgRating = (movie, movingWithRatings) => {  let count = 0;  return movingWithRatings.reduce((acc, value, index) => {    const movieMatch = movie.id === value.movie_id    if (movieMatch) {      acc+=value.rating      count++    }    if (index === movingWithRatings.length - 1) {      acc = acc/count    }    return acc  }, 0)}const isSubString = (str1, str2) => {  str1 = toLower(str1.split(" ").join(""))  str2 = toLower(str2.split(" ").join(""))  if (str1.length > str2.length) {    return str1.startWith(str2)  } else {    return str2.startWith(str1)  }}const moviesList = getMovies()const movingWithRatings = getRatings();function queryMovies({ search, sort, minAvgRating }) {  let filteredMovies = movingWithRatings.filter(movie => getAvrgRating(movie, movingWithRatings) >= minAvgRating);  filteredMovies = filteredMovies.map(movie => moviesList.filter(listItem => listItem.id === movie.movie_id).pop())  filteredMovies = filteredMovies.filter(movie => isSubString(toLower(movie.name), toLower(search)))  filteredMovies = filteredMovies.sort((a, b) => {    const isDescending = sort[0] === '-' ? true : false    let sortCopy = isDescending ? sort.slice(1) : sort    const value1 = a[sortCopy]    const value2 = b[sortCopy]    if (isDescending) {      return value1 > value2 ? -1 : 1    }else {      return value1 < value2 ? -1 : 1    }  })  filteredMovies = filteredMovies.map(movie => ({    ...movie,    avgRating: movingWithRatings.filter(ratedMovie => ratedMovie.movie_id === movie.id)[0].rating  }))  return filteredMovies}

4. Загрузите все публикации и комментарии по URL-адресу конечной точки. Выполните следующее.

  • Соотнесите все комментарии с публикациями, к которым они относятся. В результате данные должны иметь следующую структуру.

Решение:

//service.jsconst POSTS_URL = `https://jsonplaceholder.typicode.com/posts`;const COMMENTS_URL = `https://jsonplaceholder.typicode.com/comments`;export const fetchAllPosts = () => {  return fetch(POSTS_URL).then(res => res.json());};export const fetchAllComments = () => {  return fetch(COMMENTS_URL).then(res => res.json());};import { fetchAllPosts, fetchAllComments } from "./service";const fetchData = async () => {  const [posts, comments] = await Promise.all([    fetchAllPosts(),    fetchAllComments()  ]);  const grabAllCommentsForPost = postId =>    comments.filter(comment => comment.postId === postId);  const mappedPostWithComment = posts.reduce((acc, post) => {    const allComments = grabAllCommentsForPost(post.id);    acc[post.id] = allComments;    return acc;  }, {});  console.log("mappedPostWithComment ", mappedPostWithComment);};fetchData();

5. Реализуйте метод getHashCode в экземпляре объекта string. Метод должен быть доступен для всех строк.

Решение:

let s1 = "sample"if (!String.prototype.getHashCode) {  String.prototype.getHashCode = function(){    console.log('String instance ', this)    return this  }}

6. Какой результат будет у приведенных ниже выражений?

    1+true    true+true    1+true    2 > 3    two>three

Решение:

221truefalsetrue

7. Реализуйте методы bind и reduce.

Решение:

//bindif (!Function.prototype.bind) {  Function.prototype.bind = function(...arg){    const func = this    const context = arg[0]    const params = arg.slice(1)    return function(...innerParam) {      func.apply(context, [...params, ...innerParam])    }  }}//reduceArray.prototype.reduce = function(func, initState) {  const arr = this  const callback = func  let init = initState  arr.forEach(function(value, index){      init=callback(init, value)  })  return init}

8. Реализуйте функцию debounce

Решение:

const debounce = function(func, interval) {  let timerId;  return function(e){    clearTimeout(timerId)    timerId = setTimeout(function(){      func.apply()    }, interval)  }}debounce(apiCall, 3000)

9. Реализуйте функцию throttle

Решение:

const throttle = (callback, interval) => {  let timerId;  let allowEvents = true;  return function() {    let context = this;    let args = arguments;    if (allowEvents) {      callback.apply(context, args)      allowEvents = false;      timerId = setTimeOut(function(){        allowEvents = true      }, interval)    }  }}

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

Нужно описать свой подход к решению, код писать не нужно. Возможны разные варианты решения.

Решение:

//С использованием метода setInterval, декоратора throttle и флаговsetInterval=>Endpoint=>Render//с инверсией управления//Endpoint=>Render=>setTimeout=>Endpoint=>Render=>SetTimeout...

11. Конвертируйте этот код, основанный на наследовании классов, в ES5.

class Parent(name){  constructor(name) {    this.name=name  }  getName(){return this.name}}class Children extends Parent {  constructor(props){    super(props)  }}

Решение:

function Parent(name) {  this.name = name}Parent.prototype.getName = function() {  return this.name}function Children(name){  Parent.call(this, name)}Children.prototype = new Parent()

12. Что выведет следующий код?

//Q.1var x = 1;var y = x;x = 0;console.log(x, y);//Q.2var x = [1];var y = x;x = [];console.log(x,y);//Q.3function Abc() { console.log(this); };Abc()new Abc();//Q.4var x = 1;var obj = {  x: 2,  getX: function () {    return console.log(this.x);  }};obj.getX()let a = obj.getXconsole.log(a)//Q.5//Как вывести 2 с использованием переменной a в коде из предыдущего вопроса?//Q.6console.log("A");setTimeout(() => console.log("B"), 0);setTimeout(() => console.log("C"), 0);console.log("D");//Q.7setTimeout(function() {  console.log("A");}, 0);Promise.resolve().then(function() {  console.log("B");}).then(function() {  console.log("C");});console.log("D");//Q.8let obj1 = {  a:1,  b:2}function mutate(obj) {  obj = {a:4, c:6}}console.log(obj1)mutate(obj1)console.log(obj1)

Решение:

//A.10 1//A.2[] [1]//A.3Будет выведен объект window//A.4Будут выведены значения 2 и 1//A.5a.call(obj);//A.6A, D, B , C//A.7D, B, C, A//A.8{ a: 1, b: 2 }{ a: 1, b: 2 }

13. Есть массив чисел. Выведите следующие элементы.

const list = [1,2,3,4,5,6,7,8]const filteredArray = list.filter(between(3, 6)) // [4,5]

Решение:

function between(start, end) {  return function (value,index) {    return value>start && value<end  }}

Алгоритмы

1. Рассмотрите последовательность.

A := 1B := A*2 + 2C := B*2 + 3 и так далее...

Напишите программу, которая :

  • выводит число, соответствующее определенной букве;

  • для строки, например 'GREP', вычисляет сумму чисел, соответствующих буквам строки (т.е. G + R + E + P) из этой последовательности;

  • и находит самую короткую строку, соответствующую большому числу (не больше максимального 32-разрядного целого числа).

Для решения последней задачи можно использовать жадный алгоритм. Числовые значения, соответствующие буквам, должны рассчитываться по мере необходимости. НЕ НУЖНО вычислять их заранее и сохранять в структуре данных.

Решение:

//A = 1//B = A*2 +2 //C = B*2+ 3//D = C*2+ 3var genCharArray = function(charA, charZ) {    var a = [], i = charA.charCodeAt(0), j = charZ.charCodeAt(0);    for (; i <= j; ++i) {        a.push(String.fromCharCode(i));    }    return a;}var charMap = {};var charArray = genCharArray('a', 'z');charArray.forEach(function(char, index){    charMap[char] = Number(index + 1);});var charSequence = function(char){    if(typeof char==="string"){        char = charMap[char];    }    if(char==1){        return 1;    }else{        return char + 2 * charSequence(char-1);    }}var input = process.argv[2];if(input.length===1){    console.log(charSequence(charMap[input]));}else if(input.length>1){    var charTotalSequence = input.split("").reduce(function(acc, curr){         return acc + charSequence(charMap[curr]);    },0);    console.log(charTotalSequence);}

2. Найдите в массиве пару чисел, сумма которых равна заданному числу.

Решение:

let nums = [2, 7, 10, 1, 11, 15, 9]let target = 11let numsMap = new Map()let pairs = nums.reduce((acc, num) => {  let numToFind = target - num  if (numsMap.get(numToFind)) {    return [...acc, [num, numToFind]]  } else {    numsMap.set(num, true)    return [...acc]  }}, [])console.log("Pairs ", pairs)

3. Найдите локальный максимум в заданном массиве. Локальный максимум это элемент, значение которого превышает значения элементов, расположенных справа и слева от него. Я использовал нотацию O(n). Это очевидное решение, которое можно оптимизировать.

Решение:

let x = [1, 2, 3, 5, 4] //Результаты: 5if x.length == 1 return x[0]else  let i = 1 for(;i<x.length-1;i++){  if x[i-1]<x[i] and x[i] > x[i+1] return x[i] } if x.length - 1 == i return x[i]

4. Поверните матрицу на 90 градусов по часовой стрелке. Решение должно выполняться в памяти, содержащей входные данные (алгоритм in-place, на месте).

leetcode

Решение:

[ [1, 2, 3], [4, 5, 6], [7, 8, 9]]//Сначала транспонируем матрицу.//После транспонирования матрица будет выглядеть так.[ [1, 4, 7], [2, 5, 8], [3, 6, 9]]//Теперь остается всего лишь изменить порядок элементов массива на обратный.//В результате матрица будет выглядеть так.[ [7, 4, 1], [8, 5, 2], [9, 6, 3]]//Первоначальная матрица развернута на 90 градусов.

5. Максимальная сумма подмассивов по модулю M.

Решение

6. Найдите в массиве три элемента, сумма которых равна заданному числу.

Решение:

let x = [1, 2, 3, 4, 5]let target = 7let found = []const twoPointer = (l ,r, current) => {  while(l<r){    const totalSum = current + x[l] + x[r]    if (totalSum === target) {      found.push([current, x[l], x[r]])      return    } else if (totalSum > target) {      r--    } else {      l++    }  }}const threeSum = (x, target) => {    for (let i=0;i<x.length;i++) {      const current = x[i];      let leftPointer = i+1      let rightPointer = x.length - 1      if (current+x[leftPointer]+x[rightPointer] === target) {        found.push([current, x[leftPointer], x[rightPointer]])      } else {        twoPointer(leftPointer, rightPointer, current)      }  }  return found}

7. Есть строка и целое число k. Вычислите количество подстрок, в которых каждый уникальный символ встречается ровно k раз.

ссылка

Решение:

const subStrHasSameCharCount = (str, startIndex, endIndex, totalHop) => {  let charMap = {}  for (let k=startIndex;k<endIndex;k++) {    let currentChar = str[k]    if (charMap[currentChar]) {      charMap[currentChar]++    } else {      charMap[currentChar] = 1    }  }  let totalCount = Object.values(charMap).length > 0  return totalCount ? Object.values(charMap).every(item => item == totalHop) : false}const characterWithCountK = (str, k) => {  if (k == 0) return ''  let count = 0  let initialHop = k  while (initialHop < str.length) {    for (let j=0;j<str.length;j++) {      let startIndex = j      let endIndex = j + initialHop      if(endIndex > str.length) continue      count = subStrHasSameCharCount(str, startIndex, endIndex, k)        ? count + 1: count    }    initialHop+=k  }  count = subStrHasSameCharCount(str, 0, initialHop, k)        ? count + 1: count  return count}let str = 'aabbcc'let k = 2console.log(characterWithCountK(str, k))

8. Есть две строки s1 и s2, каждая из которых содержит символы от a до z в разном порядке. Проверьте, можно ли переставить символы в строке s1 таким образом, чтобы строки стали равными.

Решение:

let s1 = 'dadbcbc'let s2 = 'ccbbdad'let charMap = {}const canBeRearranged = (s1, s2) => {  if(s1.length!==s2.length){    return false  }  for(let i=0;i<s1.length;i++){    const charFromString1 = s1[i]    const charFromString2 = s2[i]    if(charFromString1 in charMap){      charMap[charFromString1]++    } else {      charMap[charFromString1] = 1    }    if(charFromString2 in charMap){      charMap[charFromString2]--    } else {      charMap[charFromString2] = -1    }  }  for(let x in charMap){    if (charMap[x]!==0){      return false    }  }  return true}canBeRearranged(s1, s2)

9. Есть массив с переменной начальной длиной. Расположите элементы массива в случайном порядке.

Решение:

const swap = (index1, index2, arr) => {  let temp = arr[index1]  arr[index1] = arr[index2]  arr[index2] = temp}const shuffle = (arr) => {  let totalLength = arr.length  while(totalLength > 0) {    let random = Math.floor(Math.random() * totalLength)    totalLength--    swap(totalLength, random, arr)  }  return arr}let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]arr = shuffle(arr)

10. Вычислите сумму всех элементов многомерного массива с бесконечной глубиной.

Решение:

let arr = [4, 5, 7, 8, [5, 7, 9, [3, 5, 7]]]let sum = 0const calculateSum = (arr) => {  arr.reduce(function(acc, currentVal) {    const isEntryArray = Array.isArray(currentVal)    if (isEntryArray) {      return acc.concat(calculateSum(currentVal))    } else {      sum+=currentVal      return acc.concat(currentVal)    }  }, [])}calculateSum(arr)console.log(sum)

11. Сгладьте многоуровневый вложенный объект.

Решение:

const obj = {  level1: {    level2: {      level3: {        more: 'stuff',         other: 'otherz',        level4: {          the: 'end',        },      },    },    level2still: {      last: 'one',    },    am: 'bored',  },  more: 'what',  ipsum: {    lorem: 'latin',  },};var removeNesting = function(obj, parent){  for (let key in obj){    if (typeof obj[key] === "object") {      removeNesting(obj[key], parent+"."+key)    } else {      flattenedObj[parent+'.'+key] = obj[key]    }  }}let flattenedObj = {}const sample = removeNesting(obj, "");console.log(flattenedObj);

12. Есть данные в формате json, где каждый объект обозначает каталог и может, в свою очередь, содержать другой вложенный объект. Выведите на экран структуру каталога.

Решение

13. Есть массив объектов, содержащих информацию о сотрудниках (у каждого сотрудника есть несколько подчиненных). На основании этих данных постройте иерархию сотрудников.

Решение:

const employeesData = [{  id: 2,  name: 'Андрей (главный технический директор)',  reportees: [6] }, {  id: 3,  name: 'Алексей (главный операционный директор)',  reportees: []}, {  id: 6,  name: 'Александр (руководитель инженерной группы)',  reportees: [9] }, {  id: 9,  name: 'Анатолий (старший инженер)',  reportees: []}, {  id: 10,  name: 'Антон (генеральный директор)',  reportees: [2, 3],}];/*A (генеральный директор)----B (главный технический директор)--------D (руководитель инженерной группы)------------E (старший инженер-разработчик)----C (главный операционный директор)*/const findCeo = (currentEmp) => {  let parentEmployee = employeesData.filter(emp => emp.reportees.indexOf(currentEmp.id) > -1)  if (parentEmployee && parentEmployee.length > 0) {    return findCeo(parentEmployee[0])  } else {    return currentEmp  }}const logHierarchy = (currentEmp, indent) => {  console.log("-".repeat(indent) + currentEmp.name)  indent+=4;  for(let i=0;i <currentEmp.reportees.length;i++) {    let employee = employeesData.filter(emp => emp.id === currentEmp.reportees[i])    logHierarchy(employee[0], indent)  }}const traverse = (employee) => {  let ceo = findCeo(employee)  logHierarchy(ceo, 0)}traverse(employeesData[0])

14. Преобразуйте заданную матрицу в спиральную и выведите на экран

const inputMatrix = [  [1, 2, 3, 4,  5],  [6, 7, 8, 9, 10],  [11,12,13,14,15],  [16,17,18,19,20],]const exprectOutput = [1,2,3,4,5,10,15,20,19,18,17,16,11,6,7,8,9,14,13,12]

Решение:

function spiralParser(inputMatrix){  const output = [];  let rows = inputMatrix.length;  let cols = rows > 0 ? inputMatrix[0].length : 0;  //singleEmptyRow => Edge case 1 //[]  if (rows === 0) {    return []  }  if (rows === 1) {    //singleElementRowNoCol => Edge case 2 //[[]]    if (cols === 0) {      return []    } else if (cols === 1){      //singleElementRow => Edge case 3 //[[1]]      output.push(inputMatrix[0][0])      return output     }  }  let top = 0;  let bottom = rows - 1;  let left = 0;  let right = cols - 1;  let direction = 0;  //0 => left->right  //1 => top->bottom  //2 => right->left  //3 => bottom->top  while(left <= right && top <= bottom) {    if(direction === 0) {      //left->right      for (let i=left; i<=right;i++) {        output.push(inputMatrix[top][i])      }      top++;    } else if (direction === 1) {      //top->bottom      for (let i=top; i<=bottom;i++) {        output.push(inputMatrix[i][right])      }      right--    } else if (direction === 2) {      //right->left      for (let i=right; i>=left;i--) {        output.push(inputMatrix[bottom][i])      }      bottom--    } else if (direction === 3) {      //bottom->top      for (let i=bottom; i>=top;i--) {        output.push(inputMatrix[i][left])      }      left++    }    direction = (direction + 1) % 4  }  return output;}console.log(spiralParser(inputMatrix2))

15. Найдите символ с максимальным количеством последовательных вхождений в заданной строке.

let str = 'bbbaaaaccadd'; //Больше последовательных вхождений (4) у символа a

Решение:

//псевдокодmaxNow = если длина входной строки равна1 или больше 1 ? 1 : 0maxOverall = если длина входной строки равна1 или больше 1 ? 1 : 0для символов входной строки с индексом 1 и больше  если символ равен предыдущему символу    maxNow++ //увеличить на 1    maxOverall = max(maxOverall, maxNow)  иначе если символ не равен предыдущему символу        maxNow = 1

16. Есть массив переменной длины. Переместите все двойки (2) в конец массива.

let inputArr = [2,9,1,5,2,3,1,2,7,4,3,8,29,2,4,6,54,32,2,100]//ouput => [9,1,5,3,1,7,4,3,8,29,4,6,54,32,100,2,2,2,2,2]

Решение:

let slowRunner = 0for (let fastRunner=0;fastRunner<arr.length;fastRunner++) {  if (arr[fastRunner]!==2 && arr[slow] == 2) {    [arr[fastRunner], arr[slow]] = [arr[slow], arr[fastRunner]]    slowRunner++  }}

17. Выведите список в обратном порядке

//На входе = 1 -> 2 -> 3 -> 4 -> 5 -> 6//В результате = 1 <- 2 <- 3 <- 4 <- 5 <- 6

Решение:

//псевдокодlet current = headlet prev = nulllet next = nullwhile(current) {  next = current.next  current.next = prev  prev = current  current = next}

18. Реализуйте прямой обход дерева с помощью итераций (без рекурсии)

Решение:

//псевдокодconst preorder = (root) => {  let stack = []  stack.push(root)  пока(переменная stack содержит данные) {    let current = stack.pop()    console.log(current.value)    if (current.right) {      stack.push(current.right)    }    if (current.left) {      stack.push(current.left)    }  }}

Задачи

1. Разработайте систему для автоматизации парковки, отвечающую следующим требованиям.

  • Она хранит данные об N автомобилях. Она обрабатывает данные о наличии парковочных мест.

  • Она регистрирует въезжающие и выезжающие автомобили.

  • Автоматизированная система учета автомобилей регистрирует все въезжающие и выезжающие автомобили по следующим данным: регистрационный номер, цвет, парковочное место.

Система должна предоставлять следующую информацию:

  • регистрационные номера всех автомобилей определенного цвета;

  • номер парковочного места автомобиля по регистрационному номеру;

  • парковочные места автомобилей определенного цвета.

  • список свободных парковочных мест.

Требования:

  • для структурирования кода можно пользоваться классами/структурами;

  • решение должно быть расширяемым для последующего применения.

Некоторые принципы разработки кода:

  • модульность кода;

  • соглашения об именовании;

  • принципы SOLID.

Решение

2. Создайте React-компонент Ping, при использовании которого API будет отправлять запрос по заданному URL. Если возвращается код состояния 200, это означает, что пользователь в Сети. Если возвращается любой другой код состояния, это означает, что пользователь не в Сети.

Попробуйте изменить статус из сетевой панели dev tools.

Решение

3. Создайте конструктор динамических форм на базе json. Формы должны группироваться по id. В каждой группе может быть другая вложенная группа.

Решение

4. Создайте на чистом JavaScript простейший лист Excel, в котором можно добавлять и удалять строки и столбцы. На решение этой задачи отводилось 40 минут.

Решение

5. Создайте строку поиска по списку пользователей.

Объект user (пользователь) включает следующие поля.

id: уникальный идентификаторимя: имя пользователятовары: список товаров, заказанных пользователемадрес: адрес пользоиндекс: почтовый индекс пользователя

Поиск должен осуществляться по всем полям.

Результаты поиска должны выводиться в виде карточки пользователя.

Требования:
Когда пользователь начинает вводить символы в строку поиска, появляется выпадающий список. Поиск может осуществляться по строке.

Навигация по списку карточек осуществляется с клавиатуры или мышью.
Если для навигации используется и клавиатура, и мышь, в каждый отдельно взятый момент времени должна подсвечиваться только одна карточка.

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

Это похоже на принцип поиска в YouTube

Если результаты не найдены, выводится пустая карточка.
Список карточек должен прокручиваться.

Подсвеченная карточка (с помощью клавиатуры или мыши) появляется в области просмотра полностью.

Решение

Другие вопросы

1. Как бы вы структурировали интерфейсное приложение? (посмотреть)
2. Реализуйте стратегию ленивой загрузки (посмотреть)
3. Что такое серверный рендеринг?
4. Как развернуть React-приложение в промышленной среде?
5. Что такое сервис-воркер (веб-воркер)?
6. Как оптимизировать веб-приложение и повысить его производительность?
7. Расскажите о стратегиях кэширования на стороне клиента.
8. Что такое CORS?
9. Назовите компоненты высшего порядка в React.
10. Как работает функция connect в Redux?
11. Что такое PureComponent в React?

Ресурсы

ссылка


Узнать подробно о курсе:

Источник: habr.com
К списку статей
Опубликовано: 02.09.2020 18:14:51
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании otus. онлайн-образование

Javascript

Reactjs

Карьера в it-индустрии

Программирование

React

Career

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru