[JavaScript, ReactJS, Карьера в IT-индустрии, Программирование] Вопросы, которые мне задавали на фронтенд-собеседованиях (перевод)   
    
    
        
    
    
    
    
            
    
        
            
                
                                    
                
                                    
                
                    
                
            
        
    
    
        
            
                
                
                    
                         
                         
                       
                    
                        Автор 
                        Сообщение 
                    
                                        
                        
                            
                                
                                
                                                                                                            news_bot ®
                                                                        
                                                                                                                                                
                                                                            
                                                                                                                
                                            Стаж: 7 лет 8 месяцев                                        
                                                                                                                
                                            Сообщений: 27286                                        
                                                                                                                                                
                                                             
                            
                                
                             
                         
                        
                            
                                
                                    
                                        
                                        
 Всем привет. В сентябре OTUS вновь запускает целую линейку курсов по JavaScript. Прямо сейчас вы можете посмотреть запись открытого урока по курсу "JavaScript Developer. Professional", а также зарегистрироваться на дни открытых дверей по курсам "React.js Developer" и "JavaScript Developer. Basic". Ну а мы традиционно делимся с вами переводом полезного материала.
Фронтенд-собеседование (в 2 частях) 1. Вопросы, которые мне задавали на фронтенд-собеседованиях.2. Ресурсы для подготовки к собеседованию (на должность фронтенд-разработчика).Вопросы, которые задавали на фронтенд-собеседованияхВ этой статье я собрал все вопросы, которые мне задавали на собеседованиях во время поиска работы в условиях пандемии COVID-19. Я также составил список ресурсов, которыми пользовался при подготовке к собеседованию.
Вопросы я разделил на четыре части.
- JS
 
- Код
 
- Задачи
 
- Другие вопросы
 
Представленный код не является готовым решением, но лишь дает общее представление о моем подходе. Попробуйте реализовать свой собственный.Отредактировано 20.08.2020. Посмотреть измененияJS1. Есть многомерный массив глубиной 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.js
const 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’
Решение:
2
2
1true
false
true
7. Реализуйте методы bind и reduce.Решение:
//bind
if (!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])
    }
  }
}
//reduce
Array.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.1
var x = 1;
var y = x;
x = 0;
console.log(x, y);
//Q.2
var x = [1];
var y = x;
x = [];
console.log(x,y);
//Q.3
function Abc() { console.log(this); };
Abc()
new Abc();
//Q.4
var x = 1;
var obj = {
  x: 2,
  getX: function () {
    return console.log(this.x);
  }
};
obj.getX()
let a = obj.getX
console.log(a)
//Q.5
//Как вывести 2 с использованием переменной a в коде из предыдущего вопроса?
//Q.6
console.log("A");
setTimeout(() => console.log("B"), 0);
setTimeout(() => console.log("C"), 0);
console.log("D");
//Q.7
setTimeout(function() {
  console.log("A");
}, 0);
Promise.resolve().then(function() {
  console.log("B");
}).then(function() {
  console.log("C");
});
console.log("D");
//Q.8
let obj1 = {
  a:1,
  b:2
}
function mutate(obj) {
  obj = {a:4, c:6}
}
console.log(obj1)
mutate(obj1)
console.log(obj1)
Решение:
//A.1
0 1
//A.2
[] [1]
//A.3
Будет выведен объект window
//A.4
Будут выведены значения 2 и 1
//A.5
a.call(obj);
//A.6
A, D, B , C
//A.7
D, 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 := 1
B := A*2 + 2
C := B*2 + 3 и так далее...
Напишите программу, которая :
- выводит число, соответствующее определенной букве;
 
- для строки, например 'GREP', вычисляет сумму чисел, соответствующих буквам строки (т. е. G + R + E + P) из этой последовательности;
 
- и находит самую короткую строку, соответствующую большому числу (не больше максимального 32-разрядного целого числа).
 
Для решения последней задачи можно использовать жадный алгоритм. Числовые значения, соответствующие буквам, должны рассчитываться по мере необходимости. НЕ НУЖНО вычислять их заранее и сохранять в структуре данных.Решение:
//A = 1
//B = A*2 +2
//C = B*2+ 3
//D = C*2+ 3
var 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 = 11
let 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] //Результаты: 5
if 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 = 7
let 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 = 2
console.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 = 0
const 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 : 0
maxOverall = если длина входной строки равна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 = 0
for (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 = head
let prev = null
let next = null
while(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
===========
===========
 Автор оригинала: Abhijeet Yadav
===========Похожие новости:
- [Python, Программирование] Напишем и поймем Decision Tree на Python с нуля! Часть 1. Краткий обзор (перевод)
 
- [JavaScript, TypeScript, Визуализация данных] How to display a gazillion of metrics and keep your sanity
 
- [Программирование, Системы сборки] Make на мыло, redo сила
 
- [Canvas, JavaScript] Sprite Matrix — модуль для нарезки спрайтов, редактирования и сохранения спрайт-листов
 
- [Настройка Linux, Разработка веб-сайтов, PHP, JavaScript, Серверное администрирование] Перенос почты между серверами через интерфейс пользователя посредством IMAPSync
 
- [Анализ и проектирование систем, Программирование] Мама, кажется я архитектор
 
- [Алгоритмы, Высокая производительность, Математика, Программирование] Динамическая балансировка нагрузки в pull-схеме
 
- [Python, Алгоритмы, Лайфхаки для гиков, Научно-популярное, Программирование] Определяем пульс по вебкамере в 50 строчек кода
 
- [.NET, ASP, C#, Программирование, Тестирование IT-систем] Я десять лет страдал от ужасных архитектур в C# приложениях — и вот нашел, как их исправить
 
- [Карьера в IT-индустрии, Учебный процесс в IT] Новый учебный год: новые образовательные проекты от Mail.ru Group
 
Теги для поиска: #_javascript, #_reactjs, #_karera_v_itindustrii (Карьера в IT-индустрии), #_programmirovanie (Программирование), #_javascript, #_react, #_career, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
), #_javascript, #_reactjs, #_karera_v_itindustrii (
Карьера в IT-индустрии
), #_programmirovanie (
Программирование
)
                                        
                                        
                                        
                                     
                                    
                                    
                                                                    
                                                                                             
                         
                        
                            
                                                                    
                                                             
                         
                    
                    
                
                
            
        
    
    
    
    
    
            
    
            
    
        
    
    
        
                        Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
    
    
        
        Текущее время: 04-Ноя 17:23
Часовой пояс: UTC + 5 
            
    
                
| Автор | Сообщение | 
|---|---|
| 
                                
                                
                                                                                                            news_bot ®
                                                                        
                                                                                                                                                 
                                                                            
                                                                                                                
                                            Стаж: 7 лет 8 месяцев                                          | 
                            |
| 
                                 Всем привет. В сентябре OTUS вновь запускает целую линейку курсов по JavaScript. Прямо сейчас вы можете посмотреть запись открытого урока по курсу "JavaScript Developer. Professional", а также зарегистрироваться на дни открытых дверей по курсам "React.js Developer" и "JavaScript Developer. Basic". Ну а мы традиционно делимся с вами переводом полезного материала. ![]() Фронтенд-собеседование (в 2 частях) 1. Вопросы, которые мне задавали на фронтенд-собеседованиях.2. Ресурсы для подготовки к собеседованию (на должность фронтенд-разработчика).Вопросы, которые задавали на фронтенд-собеседованияхВ этой статье я собрал все вопросы, которые мне задавали на собеседованиях во время поиска работы в условиях пандемии COVID-19. Я также составил список ресурсов, которыми пользовался при подготовке к собеседованию. Вопросы я разделил на четыре части. 
 /** 
* [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()); 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) }) // 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 } 
 //service.js 
const 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(); let s1 = "sample" 
if (!String.prototype.getHashCode) { String.prototype.getHashCode = function(){ console.log('String instance ', this) return this } } 1+true 
true+true ‘1’+true ‘2’ > ’3’ ‘two’>’three’ 2 
2 1true false true //bind 
if (!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]) } } } //reduce Array.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 } const debounce = function(func, interval) { 
let timerId; return function(e){ clearTimeout(timerId) timerId = setTimeout(function(){ func.apply() }, interval) } } debounce(apiCall, 3000) 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) } } } //С использованием метода setInterval, декоратора throttle и флагов 
setInterval=>Endpoint=>Render //с инверсией управления //Endpoint=>Render=>setTimeout=>Endpoint=>Render=>SetTimeout... 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() //Q.1 
var x = 1; var y = x; x = 0; console.log(x, y); //Q.2 var x = [1]; var y = x; x = []; console.log(x,y); //Q.3 function Abc() { console.log(this); }; Abc() new Abc(); //Q.4 var x = 1; var obj = { x: 2, getX: function () { return console.log(this.x); } }; obj.getX() let a = obj.getX console.log(a) //Q.5 //Как вывести 2 с использованием переменной a в коде из предыдущего вопроса? //Q.6 console.log("A"); setTimeout(() => console.log("B"), 0); setTimeout(() => console.log("C"), 0); console.log("D"); //Q.7 setTimeout(function() { console.log("A"); }, 0); Promise.resolve().then(function() { console.log("B"); }).then(function() { console.log("C"); }); console.log("D"); //Q.8 let obj1 = { a:1, b:2 } function mutate(obj) { obj = {a:4, c:6} } console.log(obj1) mutate(obj1) console.log(obj1) //A.1 
0 1 //A.2 [] [1] //A.3 Будет выведен объект window //A.4 Будут выведены значения 2 и 1 //A.5 a.call(obj); //A.6 A, D, B , C //A.7 D, B, C, A //A.8 { a: 1, b: 2 } { a: 1, b: 2 } 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 } } A := 1 
B := A*2 + 2 C := B*2 + 3 и так далее... 
 //A = 1 
//B = A*2 +2 //C = B*2+ 3 //D = C*2+ 3 var 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); } let nums = [2, 7, 10, 1, 11, 15, 9] 
let target = 11 let 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) let x = [1, 2, 3, 5, 4] //Результаты: 5 
if 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] [ 
[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 градусов. let x = [1, 2, 3, 4, 5] 
let target = 7 let 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 } 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 = 2 console.log(characterWithCountK(str, k)) 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) 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) let arr = [4, 5, 7, 8, [5, 7, 9, [3, 5, 7]]] 
let sum = 0 const 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) 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); 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]) 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)) let str = 'bbbaaaaccadd'; //Больше последовательных вхождений (4) у символа a 
//псевдокод 
maxNow = если длина входной строки равна1 или больше 1 ? 1 : 0 maxOverall = если длина входной строки равна1 или больше 1 ? 1 : 0 для символов входной строки с индексом 1 и больше если символ равен предыдущему символу maxNow++ //увеличить на 1 maxOverall = max(maxOverall, maxNow) иначе если символ не равен предыдущему символу maxNow = 1 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 = 0 
for (let fastRunner=0;fastRunner<arr.length;fastRunner++) { if (arr[fastRunner]!==2 && arr[slow] == 2) { [arr[fastRunner], arr[slow]] = [arr[slow], arr[fastRunner]] slowRunner++ } } //На входе = 1 -> 2 -> 3 -> 4 -> 5 -> 6 
//В результате = 1 <- 2 <- 3 <- 4 <- 5 <- 6 //псевдокод 
let current = head let prev = null let next = null while(current) { next = current.next current.next = prev prev = current current = next } //псевдокод 
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) } } } 
 
 
 
 
 id: уникальный идентификатор 
имя: имя пользователя товары: список товаров, заказанных пользователем адрес: адрес пользо индекс: почтовый индекс пользователя Когда пользователь начинает вводить символы в строку поиска, появляется выпадающий список. Поиск может осуществляться по строке.Навигация по списку карточек осуществляется с клавиатуры или мышью. Если для навигации используется и клавиатура, и мышь, в каждый отдельно взятый момент времени должна подсвечиваться только одна карточка.(Навигация будет осуществляться с помощью клавиатуры, если мышь наведена на элемент списка. Если клавиатура не используется, навигация будет осуществляться с помощью мыши.)Это похоже на принцип поиска в YouTubeЕсли результаты не найдены, выводится пустая карточка. Список карточек должен прокручиваться.Подсвеченная карточка (с помощью клавиатуры или мыши) появляется в области просмотра полностью.Решение Другие вопросы 1. Как бы вы структурировали интерфейсное приложение? (посмотреть) 2. Реализуйте стратегию ленивой загрузки (посмотреть) 3. Что такое серверный рендеринг? 4. Как развернуть React-приложение в промышленной среде? 5. Что такое сервис-воркер (веб-воркер)? 6. Как оптимизировать веб-приложение и повысить его производительность? 7. Расскажите о стратегиях кэширования на стороне клиента. 8. Что такое CORS? 9. Назовите компоненты высшего порядка в React. 10. Как работает функция connect в Redux? 11. Что такое PureComponent в React?Ресурсы ссылкаУзнать подробно о курсе: =========== Источник: habr.com =========== =========== Автор оригинала: Abhijeet Yadav ===========Похожие новости: 
 Блог компании OTUS. Онлайн-образование ), #_javascript, #_reactjs, #_karera_v_itindustrii ( Карьера в IT-индустрии ), #_programmirovanie ( Программирование )  | 
                        |
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
    Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 04-Ноя 17:23
Часовой пояс: UTC + 5