- Регистрация
- 21.07.20
- Сообщения
- 40.408
- Реакции
- 1
- Репутация
- 0
Всем привет. В сентябре OTUS вновь запускает целую линейку курсов по JavaScript. Прямо сейчас вы можете посмотреть запись открытого урока по курсу
Вопросы, которые задавали на фронтенд-собеседованиях
В этой статье я собрал все вопросы, которые мне задавали на собеседованиях во время поиска работы в условиях пандемии COVID-19. Я также составил список ресурсов, которыми пользовался при подготовке к собеседованию.
Вопросы я разделил на четыре части.
Представленный код не является готовым решением, но лишь дает общее представление о моем подходе. Попробуйте реализовать свой собственный.
Отредактировано 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 / 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 = `
const COMMENTS_URL = `
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 && valuecode>
Алгоритмы
1. Рассмотрите последовательность.
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 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[i+1] return x
}
if x.length - 1 == i return x
4. Поверните матрицу на 90 градусов по часовой стрелке. Решение должно выполняться в памяти, содержащей входные данные (алгоритм in-place, «на месте»).
Решение:
[
[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 target) {
r--
} else {
l++
}
}
}
const threeSum = (x, target) => {
for (let i=0;icode>
7. Есть строка и целое число k. Вычислите количество подстрок, в которых каждый уникальный символ встречается ровно k раз.
Решение:
const subStrHasSameCharCount = (str, startIndex, endIndex, totalHop) => {
let charMap = {}
for (let k=startIndex;k 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) 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;icode>
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 emp.id === currentEmp.reportees)
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 /left->right
for (let i=left; i/top->bottom
for (let i=top; i/right->left
for (let i=right; i>=left;i--) {
output.push(inputMatrix[bottom])
}
bottom--
} else if (direction === 3) {
//bottom->top
for (let i=bottom; i>=top;i--) {
output.push(inputMatrix
You must be registered for see links
, а также зарегистрироваться на дни открытых дверей по курсам
You must be registered for see links
и
You must be registered for see links
. Ну а мы традиционно делимся с вами переводом полезного материала.
You must be registered for see links
You must be registered for see links
You must be registered for see links
Вопросы, которые задавали на фронтенд-собеседованиях
В этой статье я собрал все вопросы, которые мне задавали на собеседованиях во время поиска работы в условиях пандемии COVID-19. Я также составил список ресурсов, которыми пользовался при подготовке к собеседованию.
Вопросы я разделил на четыре части.
JS
Код
Задачи
Другие вопросы
Представленный код не является готовым решением, но лишь дает общее представление о моем подходе. Попробуйте реализовать свой собственный.
Отредактировано 20.08.2020.
You must be registered for see links
изменения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 / 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-адресу конечной точки. Выполните следующее.
Соотнесите все комментарии с публикациями, к которым они относятся. В результате данные должны иметь следующую структуру.
You must be registered for see links
//service.js
const POSTS_URL = `
You must be registered for see links
`;const COMMENTS_URL = `
You must be registered for see links
`;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 && valuecode>
Алгоритмы
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 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[i+1] return x
}
if x.length - 1 == i return x
4. Поверните матрицу на 90 градусов по часовой стрелке. Решение должно выполняться в памяти, содержащей входные данные (алгоритм in-place, «на месте»).
You must be registered for see links
Решение:
[
[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.
You must be registered for see links
6. Найдите в массиве три элемента, сумма которых равна заданному числу.
Решение:
let x = [1, 2, 3, 4, 5]
let target = 7
let found = []
const twoPointer = (l ,r, current) => {
while(l target) {
r--
} else {
l++
}
}
}
const threeSum = (x, target) => {
for (let i=0;icode>
7. Есть строка и целое число k. Вычислите количество подстрок, в которых каждый уникальный символ встречается ровно k раз.
You must be registered for see links
Решение:
const subStrHasSameCharCount = (str, startIndex, endIndex, totalHop) => {
let charMap = {}
for (let k=startIndex;k 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) 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;icode>
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, где каждый объект обозначает каталог и может, в свою очередь, содержать другой вложенный объект. Выведите на экран структуру каталога.
You must be registered for see links
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 emp.id === currentEmp.reportees)
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 /left->right
for (let i=left; i/top->bottom
for (let i=top; i/right->left
for (let i=right; i>=left;i--) {
output.push(inputMatrix[bottom])
}
bottom--
} else if (direction === 3) {
//bottom->top
for (let i=bottom; i>=top;i--) {
output.push(inputMatrix
)
}
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;fastRunnercode>
17. Выведите список в обратном порядке
//На входе = 1 -> 2 -> 3 -> 4 -> 5 -> 6
//В результате = 1 code>
Решение:
//псевдокод
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. Разработайте систему для автоматизации парковки, отвечающую следующим требованиям.
Система должна предоставлять следующую информацию:
Требования:
Некоторые принципы разработки кода:
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?
Ресурсы
Узнать подробно о курсе:
}
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;fastRunnercode>
17. Выведите список в обратном порядке
//На входе = 1 -> 2 -> 3 -> 4 -> 5 -> 6
//В результате = 1 code>
Решение:
//псевдокод
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.
You must be registered for see links
2. Создайте React-компонент Ping, при использовании которого API будет отправлять запрос по заданному URL. Если возвращается код состояния 200, это означает, что пользователь в Сети. Если возвращается любой другой код состояния, это означает, что пользователь не в Сети.
Попробуйте изменить статус из сетевой панели dev tools.
You must be registered for see links
3. Создайте конструктор динамических форм на базе json. Формы должны группироваться по id. В каждой группе может быть другая вложенная группа.
You must be registered for see links
4. Создайте на чистом JavaScript простейший лист Excel, в котором можно добавлять и удалять строки и столбцы. На решение этой задачи отводилось 40 минут.
You must be registered for see links
5. Создайте строку поиска по списку пользователей.
Объект user (пользователь) включает следующие поля.
id: уникальный идентификатор
имя: имя пользователя
товары: список товаров, заказанных пользователем
адрес: адрес пользо
индекс: почтовый индекс пользователя
Поиск должен осуществляться по всем полям.
Результаты поиска должны выводиться в виде карточки пользователя.
Требования:
Когда пользователь начинает вводить символы в строку поиска, появляется выпадающий список. Поиск может осуществляться по строке.
Навигация по списку карточек осуществляется с клавиатуры или мышью.
Если для навигации используется и клавиатура, и мышь, в каждый отдельно взятый момент времени должна подсвечиваться только одна карточка.
(Навигация будет осуществляться с помощью клавиатуры, если мышь наведена на элемент списка. Если клавиатура не используется, навигация будет осуществляться с помощью мыши.)
Это похоже на принцип поиска в YouTube
Если результаты не найдены, выводится пустая карточка.
Список карточек должен прокручиваться.
Подсвеченная карточка (с помощью клавиатуры или мыши) появляется в области просмотра полностью.
You must be registered for see links
Другие вопросы
1. Как бы вы структурировали интерфейсное приложение?
You must be registered for see links
2. Реализуйте стратегию ленивой загрузки
You must be registered for see links
3. Что такое серверный рендеринг?
4. Как развернуть React-приложение в промышленной среде?
5. Что такое сервис-воркер (веб-воркер)?
6. Как оптимизировать веб-приложение и повысить его производительность?
7. Расскажите о стратегиях кэширования на стороне клиента.
8. Что такое CORS?
9. Назовите компоненты высшего порядка в React.
10. Как работает функция connect в Redux?
11. Что такое PureComponent в React?
Ресурсы
You must be registered for see links
Узнать подробно о курсе:
You must be registered for see links
You must be registered for see links
You must be registered for see links