# JS
---
var, let, const
---
> Расскажите что знаете?
```javascript=
console.log(a);
var a = 'value';
console.log(b);
let b = 'value';
```
```javascript=
if (true) {
const c = 'Hello'
console.log(c);
}
console.log(c);
```
**Ответы:**
1. (3) undefined; (6) ошибка
2. (3) Hello; (5) ReferenceError
3. Видимости бывают блочные ({} для let const), функциональные для всех типов, глобальная и модульная
- [ ] Рассказал верно о областях видимости переменных **0.5**
- [ ] Сам **0.5**
- [ ] Рассказал верно о всплытии **0.25**
- [ ] Сам **0.25**
- [ ] Верно сказал о том что console.log(a); *не* ругнеться ошибкой **0.25**
- [ ] Сам **0.25**
- [ ] Верно сказал что a = 'value'; останеться на 2ой строке **0.25**
- [ ] Сам **0.25**
- [ ] Верно сказал о том что console.log(b); *ругнеться* ошибкой **0.25**
- [ ] Сам **0.25**
- [ ] Всопнмил про import/export перменных в es6 **1**
- [ ] Сам **1**
---
---
---
Наследование
---
1. Напишите функциональное наследование
```javascript=
// Employee должен наследоваться от
// Person в функциональном стиле и переиспользовать
// методы getName и getSpecificName
function Person(name) {
// Реализовать
}
function Employee(name, position) {
// Реализовать
}
// Нужно получить метод:
var vasia = new Person('Васян');
console.log(vasia.getName()); // Вася
console.log(vasia.getSpecificName()); // Вася (из Person)
console.log(vasia instanceof Person); // true
var petia = new Employee('Петя', 'Прогер');
console.log(petia.getName()); // Петя (Прогер)
console.log(petia.getSpecificName()); // Петя (из Person)
console.log(petia instanceof Person); // true
console.log(petia instanceof Employee); // true
```
**Ответы:**
1.
```javascript=
function Person(pname) {
this.pname = pname;
}
Person.prototype.getName = function() {
return this.pname;
}
Person.prototype.getSpecificName = function() {
return this.pname + ' из Person';
}
function Employee(pname, position) {
Person.call(this, pname);
this.position = position;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.getName = function() {
return Person.prototype.getName.call(this) + '(' + this.position + ')';
}
var vasia = new Person('Вася');
console.log(vasia.getName()); // Вася
console.log(vasia.getSpecificName()); // Вася (из Person)
console.log(vasia instanceof Person); // true
var petia = new Employee('Петя', 'Прогер');
console.log(petia.getName()); // Петя (Прогер)
console.log(petia.getSpecificName()); // Петя (из Person)
console.log(petia instanceof Person); // true
console.log(petia instanceof Employee); // true
```
- [ ] `this.pname = pname;` + `this.position = position;` в разных конструкторах **0.25**
- [ ] Сам **0.25**
- [ ] `this.pname = pname;` не дублируеться **0.25**
- [ ] `Person.call(this, pname);` **0.25**
- [ ] Сам **0.25**
- [ ] `Employee.prototype = Object.create(Person.prototype);` **0.5**
- [ ] Сам **0.5**
- [ ] `Employee.prototype = new Person` порассуждал о этом **0.5**
- [ ] `Person.prototype.getName.call(this) + '(' + this.position + ')';` **0.5**
- [ ] Сам **0.5**
---
---
---
Object.create
---
1. Зачем он используеться?
2. Напишите его полифил
```javascript=
function create(obj) {
// Реализовать
}
const Parent = function() {}
Parent.prototype.test = function() {
return this.prop;
}
Parent.prototype.prop = 'propVal'
function Child() {};
Child.prototype = create(Parent.prototype);
const _child = new Child;
console.log(_child instanceof Child); // true
console.log(_child instanceof Parent); // true
console.log(_child.prop); // propVal
console.log(_child.test()); // propVal
```
**Ответы:**
1. Метод используется с тем чтобы не использовать ключевое слово `new` при создании нового обьекта. Это нужно если мы не можем запустить/у нас нет конструктора.
2.
```javascript=
function create(obj) {
function Temp() {}
Temp.prototype = obj;
return new Temp;
}
const Parent = function() {}
Parent.prototype.test = function() {
return this.prop;
}
Parent.prototype.prop = 'propVal'
function Child() {};
Child.prototype = create(Parent.prototype);
const _child = new Child;
console.log(_child instanceof Child); // true
console.log(_child instanceof Parent); // true
console.log(_child.prop); // propVal
console.log(_child.test()); // propVal
```
- [ ] Верно ответил о назначении метода **1**
- [ ] Верно реализовал метод **1**
- [ ] Сам **2**
---
---
---
Ключевое слово this
---
0. Что это такое? Какие есть особенности в языке javascript связанные с конетекстом? Методы apply, call, bind расскажите о них.
1.
```javascript=
const a = {
b: function() {
console.log(this.c)
},
c: 'value'
}
a.b(); // ?
const t = a.b;
t(); // ?
```
2.
```javascript=
'use strict';
const a = {
b: function() {
console.log(this.c)
},
c: 'value'
}
a.b(); // ?
const t = a.b;
t(); // ?
```
3.
```javascript=
var o = {
f: function() {
return this;
}
}
var o2 = {f: o.f};
console.log(o.f() === o); // ?
console.log(o2.f() === o2); // ?
```
4. (*)
```javascript=
var f = function() {
this.x = 5;
(function() {
this.x = 3;
})();
console.log(this.x); // ?
};
new f();
```
**Ответы:**
0. В отличие от многих других языков программирования ключевое слово this в javascript не привязывается к объекту, а зависит от контекста вызова
1.
```javascript=
const a = {
b: function() {
console.log(this.c)
},
c: 'value'
}
a.b(); // value
const t = a.b;
t(); // undefined
```
2.
```javascript=
'use strict';
const a = {
b: function() {
console.log(this.c)
},
c: 'value'
}
a.b(); // value
const t = a.b;
t(); // throw exception
```
3.
```javascript=
var o = {
f: function() {
return this;
}
}
var o2 = { f: o.f };
console.log(o.f() === o); // true
console.log(o2.f() === o2); // true - не важно как ф-ция попала в обьект
// важно как (от какого обьекта) взывана
```
4. (*)
```javascript=
var f = function() {
// Функция f вызывается с использованием ключевого слова new,
// поэтому this ссылается на создаваемый объект (обозначим его как object)
this.x = 5; // object.x = 5;
// В самовызывающихся функциях this ссылается на глобальный объект
(function() {
this.x = 3; // window.x = 3
})();
console.log(this.x); // console.log(object.x)
};
new f();
```
- [ ] Верно ответил на теоретический вопрос **0.5**
- [ ] (без use strict) 1 вопрос **0.5**
- [ ] Обьяснил куда в этом кейсе смотрит this **0.25**
- [ ] (use strict) 2 вопрос **0.25**
- [ ] Сам **0.25**
- [ ] 3 вопрос **0.25**
- [ ] 4 вопрос **1**
---
---
---
Фазы распространение события (Event Propagation) в DOM
---
1. Какие фазы бывают
2. Как можно перехватить погружающееся событие?
**Ответы:**
1. Погружение таргет и всплытие
2. `elem.addEventListener('click', function() {...}, { capture: true })`
- [ ] Всплытие **0.25**
- [ ] Погружение **0.5**
- [ ] Таргет **0.5**
- [ ] Перехват **0.25**
---
---
---
Event loop
---
1. Что вы знаете о Event loop
2. Синхронный ли javascript?
3. Что использует под капотом setTimeout?
4. Сколько очередей задач в event loop javascript?
5.
```javascript=
console.log('1');
setTimeout(function() {
console.log('2');
}, 0);
Promise.resolve().then(function() {
console.log('3');
})
console.log('4');
```
6.
```javascript=
function fn() {
setTimeout(function() {
fn();
}, 0);
}
fn();
```
7.
```javascript=
function fn() {
Promise.resolve().then(function() {
fn();
});
}
fn();
```
**Ответы:**
2. JS асинхронный. Это достигаеться за счет браузреных API и очереди задачь
3. Бразуерные АПИ которые помещают калбек, в нужны момент, в очередь макротасок
4. 2
5. 1, 4, 3, 2
6. Все ок
7. Зависнет
- [ ] Рассказал про браузерные апи, очереди, стек вызовов **0.25**
- [ ] Рассазал про асинхронность работы JS **0.25**
- [ ] Рассказал про две очереди вызовов **0.5**
- [ ] 5 **0.25**
- [ ] 6 **0.25**
- [ ] 7 **0.25**
---
---
---
Как работает браузер. Отрисовка страниц
---
- [ ] Рассказал про резолв ip адресов **0.25**
- [ ] Рассказал про обработку пакетов виртуальными веб-срверами **0.25**
- [ ] Рассказал про разбор страницы в токены, парсинг, валидацию **0.25**
- [ ] Рассказал про паралельные загрузки и http2 **0.5**
- [ ] Сам **0.5**
- [ ] Верно расположил построение DOM **0.25**
- [ ] Сам **0.25**
- [ ] CSSOM **0.5**
- [ ] Сам **0.5**
- [ ] Рассказал про рендерер три и его нюансы **0.5**
- [ ] Сам **0.5**
- [ ] Верно расположил Reflow/Repaint/Composit **0.5**
- [ ] Сам **0.5**
- [ ] Отдельный поток композитора **0.5**
- [ ] Указал что transform, opacity выносят слой на отдельный поток **1**
---
# Ангуляр
---
Назовите жизненный цикл компонентов
---
1. Назовите методы жизненного цикла
2. Какие методы вызываються 1 раз
3. Какие методы вызываються много раз
**Ответы:**
1.
```
Constructor
ngOnChanges: вызывается до метода ngOnInit() при начальной установке свойств,
которые связаны механизмом привязки, а также при любой их переустановке
или изменении их значений. Данный метод в качестве параметра принимает
объект класса SimpleChanges, который содержит предыдущие и
текущие значения свойства.
ngOnInit: вызывается один раз после установки свойств компонента, которые
участвуют в привязке. Выполняет инициализацию компонента
ngDoCheck: вызывается при каждой проверке изменений свойств компонента
сразу после методов ngOnChanges и ngOnInit
ngAfterContentInit: вызывается один раз после метода ngDoCheck()
после вставки содержимого в представление компонента кода html
ngAfterContentChecked: вызывается фреймворком Angular при проверке
изменений содержимого, которое добавляется в представление компонента.
Вызывается после метода ngAfterContentInit() и после каждого
последующего вызова метода ngDoCheck().
ngAfterViewInit: вызывается фреймворком Angular после инициализации
представления компонента, а также представлений дочерних компонентов.
Вызывается только один раз сразу после первого вызова метода ngAfterContentChecked()
ngAfterViewChecked: вызывается фреймворком Angular после проверки
на изменения в представлении компонента, а также проверки представлений дочерних
компонентов. Вызывается после первого вызова метода ngAfterViewInit()
и после каждого последующего вызова ngAfterContentChecked()
ngOnDestroy: вызывается перед тем, как фреймворк Angular удалит компонент.
```
2. Методы вызываються 1 раз:
Constructor, ngOnInit, ngAfterContentInit, ngAfterViewInit, ngOnDestroy
3. Методы вызываються мгного раз:
ngOnChanges, ngDoCheck, ngAfterContentChecked, ngAfterViewChecked
- [ ] Навзал некотрые методы **0.25**
- [ ] Все методы **0.25**
- [ ] Ответил на вопрос 2 **0.25**
- [ ] Ответил на вопрос 3 **0.5**
---
---
---
Как работает change detection
---
1. Назовите cтратегии обнаружения
2. Ручное управление
3. Как ведет себя ngDoCheck в OnPush режиме
**Ответы:**
1.
Стратегии обнаружения Default/OnPush
- Default:
Если стратегия компонента не настраивается, она обозначается как стратегия «Default». Стратегия обнаружения «Default» применяется к компоненту во время его создания. В этой стратегии цикл обнаружения изменений выполняется для каждого отдельного события, происходящего внутри компонента
Каждый раз, когда в ParentComponent (родительском компоненте) обновляется переменная, в жизненном цикле ChildComponent также инициируется повторное отображение дочернего компонента.
- OnPush:
Согласно этой стратегии, дочерний компонент ChildComponent не всегда проверяется на изменение данных. Такая проверка не должна проводиться, если родительский элемент обновляет значения, которые не передаются дочернему компоненту в свойствах @Input
Компонент не будет обновляться/повторно отображаться при обновлении свойства родительского компонента.
2.
Ручное управление:
использование стратегии OnPush и markforCheck():
detectChanges запускает цикл обнаружения изменений непосредственно для компонента
markForCheck делает то, что называется, помечает компонент для проверки
например, мы запускаете setInterval , это означает, что changeDetection запускается setInterval, но запускается в вашем компоненте в следующем цикле.
Это потому, что NgZone делает что-то вроде обезьяньего патча всех дефолтных api, которые он может достичь, чтобы запустить changeDetection . С помощью on Push вы подключаетесь туда и сообщаете своему компоненту, что вы сообщаете angular, когда ему нужно выполнить дополнительные проверки.
- [ ] Назвал cтратегии обнаружения **0.25**
- [ ] Описал Default **0.5**
- [ ] Описал OnPush **0.25**
- [ ] Рассказал про ручное управление **0.25**
- [ ] Рассказал про markForCheck **0.25**
- [ ] ngDoCheck в OnPush режиме **1**
---
---
---
Компоненты и директивы
---
1. Чем отличаються?
2. Какие типы директив бывают?
**Ответы:**
1.
Компонента имеет свой шаблон и с ним работает, директива не имеет шаблона и ставится на хост чтобы изменить поведение.
2.
- С собственным шаблоном, или по-другому компоненты (компоненты являются директивами);
- Структурные, которые изменяют структуру DOM-дерева; // *ngIf, *ngFor, *ngSwitch
- Атрибуты, которые изменяют внешний вид или поведение по умолчанию элемента DOM-дерева. // [ngClass], [ngStyle]
>
- [ ] Назвал отличие **0.25**
- [ ] Назвал типы директив **0.25**
- [ ] Описал типы директив **0.5**
---
---
---
Операторы rxjs
---
1. Какие операторы rxjs знаете?
2. Чем пользоваться чтобы поддержать порядок эмиссии Observable, например для создания последоваетльных выховов
3. В чем отличие на примере mergeMap, switchMap и concatMap?
**Ответы:**
1. Ожидается перечисление операторов rxjs // Concat, forkJoin, mergeMap, switchMap, pairwise, combineLatest
2. concatMap
3. Отличие на примере mergeMap, switchMap и concatMap
- [ ] Назвал операторы rxjs **0.25**
- [ ] Назвал concatMap **0.5**
- [ ] Отличие на примере **0.5**
---
---
---
Observable
---
1. Горячий холодный обсервебл
**Ответы:**
Холодные начинают эмиссию данных только тогда когда на них кто-нибудь подпишется. Горячие же эмитят данные вне зависимости от того есть ли подписант или нет.
- [ ] Рассказал про отличие холодного и горячего обесрвабл **0.5**
- [ ] Сам **0.5**
---
---
---
Ngrx
---
1. Принцип устройства
2. Зачем нужен?
3. Почему редюсеры не должны мутировать стейт?
4. Как используете эффекты?
**Ответы:**
1. Реализует принцип работы Redux для Angular. Главная цель NgRx - централизовать и сделать максимально понятным управление всеми состояниями приложения.
2. Зачем нужен/цель:
- Наличие единственного источника данных о состоянии - хранилища (store);
- Доступность состояния только для чтения;
- Изменение состояние осуществляется только через действия (actions), которые обрабатываются редюсерами (reducer), представляющими собой чистые функции.
3. NgRx Reducers регистрируются в хранилище и должны быть чистыми функциями. Редюсер принимает исходное состояние и возникшее действие в качестве аргументов, но для применения изменений он должен вернуть новое состояние, но ни в коем случае не изменять напрямую исходное. Если в редюсере не предусмотрена обработка возникшего действия, то он просто должен вернуть исходное состояние.
4. Отслеживая поток действий, отправляемых в Store
NgRx Effect начинается c отслеживания потока событий, который представлен сервисом Actions и предваряется декоратором @Effect(). Далее с помощью оператор ofType() задается тип действия, при возникновении которого будет выполнен побочный эффект, который в свою очередь должен возвращать новое действие, передаваемое далее в хранилище. Также не забывайте обрабатывать ошибки.
- [ ] Назвал Принцип устройства **0.25**
- [ ] Рассказал зачем нужен **0.25**
- [ ] Рассказал почему редюсеры не должны мутировать стейт **0.5**
- [ ] Рассказал как используете эффекты **0.25**
# Задачи
---
---
---
0 Большое O(). Расскажите что это и зачем его используют.
---
1. Что это и зачем нужно
2. Какие большие O используют для анализа алгоритмов
- [ ] 1 **0.25**
- [ ] Сам **0.25**
- [ ] 2 **0.25**
- [ ] Сам **0.25**
---
1 Реализовать метод parallel который выполняет все методы последовательно
---
```
parallel([
function (resolve) {
setTimeout(function () {
resolve(10);
}, 50);
},
function () {
return 5;
},
function (resolve) {
setTimeout(function () {
resolve(0);
}, 10)
},
function () {
return 7;
},
], function (results) {
console.log('results = ', results); // [10, 5, 0, 7]
});
```
---
**Решение:**
https://jsfiddle.net/ozuh8fgv/1/
2 Реализовать стек на двух очередях
---
```
class Queue {
constructor() {
this.stack1 = new Stack();
this.stack2 = new Stack();
}
enqueue(val) {
// реализовать
}
dequeue() {
// реализовать
}
size() {
// реализовать
}
}
class Stack {
constructor(){
this.length = 0;
this._data = [];
}
push(val) {
this._data.push(val);
this.length++;
}
pop() {
this.length--;
return this._data.pop();
}
}
let queue = new Queue();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
console.log(queue.dequeue()); // 1
console.log(queue.dequeue()); // 2
queue.enqueue(4);
queue.enqueue(5);
console.log(queue.dequeue()); // 3
console.log(queue.dequeue()); // 4
console.log(queue.dequeue()); // 5
console.log(queue.dequeue()); // undefined
```
---
Решение:
https://jsfiddle.net/a265d9t1/5/
3 Каррирование что это такое? Напишите функцию каррирование
---
```
function curry(func) {
// реализовать
}
function sum(a, b, c) {
return a + b + c;
}
let curriedSum = curry(sum);
console.log( curriedSum(1, 2, 3) ); // 6
console.log( curriedSum(1)(2,3) ); // 6
console.log( curriedSum(1)(2)(3) ); // 6
console.log( curriedSum(1)(2) ); // function...
console.log( curriedSum(1) ); // function...
```
---
Решение:
- Каррирование – это трансформация функций таким образом, чтобы они принимали аргументы не как f(a, b, c), а как f(a)(b)( c) и f(a)(b, c).
- https://jsfiddle.net/4tdufqL3/