text:
<repo_name>sagalatov/checklist<file_sep>/Tasks.md
## Задачи по JS

1. Что выведет консоль и как исправить.
```javaScript
var a = {
	lol: 'whut',
  kek: function() {
  	console.log(this.lol)
	}
}

var fn = a.kek ? a.kek : a. kek;
fn(); // ?
```
___
2.  Чему в результате равен x.
```javaScript
Promise.resolve(123)
  .then(x => x + 1)
  .catch(x => x + 2)
  .then(x => x + 3)
```
___
3. Написать функцию сложения вида sum(1)(2)(3)...:
```javaScript
function sum (num) {
    //...
}
sum(1)(2)(3)(4); // 10
```
___
4. Написать функцию с асинхронными запросами:
```javaScript

function getAuth() {} // return Promise (critical) with token

function getUser(token) {} // [return Promise with userId]
function getOrder(token, userId) {} // [return Promise]

async function getData() {
	// return Promise with {auth, order?, promo?} data
}
```
___
5. Что выведет консоль
```javaScript
let a = 1;
let b = { prop: 2 };
let c = { prop: 3 };

function foo(d, e, f) {
 d = -1;
 e = { prop: -1 };
 f.prop = -1;
}

foo(a, b, c);

console.log(a, b, c);
```
___
6. Какая очередность вывода будет в консоле
```javaScript
console.log(1);

setTimeout(function() {
  console.log(2);
}, 0);

setTimeout(function() {
  console.log(3);
}, 1);

console.log(4);

Promise.resolve()
  .then(function() {
    console.log(5);
  })
  .then(function() {
    console.log(6);
  });

console.log(7);
```
___
7. Что будет в консоли и почему?:
```javaScript
var a = 5;
function test () {
    a = 10;
    if (false) {
        var a = 20;
    }
}
test();
console.log(a); // ?
```
___
8. Нечётные числа должны отсортироваться по возрастанию, а чётные должны остаться на своих местах:
```javaScript
const nums = [1,9,4,2,3,6,7,1,5]; // [1,1,4,2,3,6,5,7,9]
```
Та же задача с тестами: [codewars](https://www.codewars.com/kata/578aa45ee9fd15ff4600090d)

___
9. Сделать вложенный объект из строки:
```javaScript
const str = 'one.two.three.four.five';

/*{
    one: {
        two: {
            three: {
                ...
            }
        }
    }
}*/
```
___
10. Написать функцию, которая будет возвращать true если строка (слово) является **палиндромом**, иначе false:
TODO: Найти такую задачу с тестами на https://www.codewars.com/
```javaScript
function isPalindrom (str) {
    //...
}
isPalindrom('казак'); // true
isPalindrom('строка'); // false
isPalindrom('шалаш'); // true
```
___
11. Напишите функцию, проверяющую, являются ли две строки **анаграммами** друг друга (регистр букв не имеет значения). Важны только символы, пробелы или знаки препинания не учитываются:
TODO: Найти такую задачу с тестами на https://www.codewars.com/
```javaScript
function isAnagram (str) {
    //...
}
isAnagram('finder', 'Friend'); // true
isAnagram('hello', 'bye'); // false
```
___
12. Написать полифил для: filter, map, bind.
  Тесты для [bind](https://codesandbox.io/s/mybind-r2eo1?file=/index.html)
___

13. Что выведет консоль и как исправить.

```javascript
const x = 1;
if (true) {
 console.log(x);
 let x = 2;
}
```

14. Что выведет консоль и почему?
```javascript
const b = [1, 2, 3];
const fn = (a, ...b) => a + b;
console.log(fn(1));
```

15. Что выведет консоль и почему?
```javascript
const a = { prop: 1 };
const b = { prop: 2 };
const c = { ...a, ...b, b };
b.prop = 5;
console.log(c);
```

16. Что выведет консоль и почему?
```javascript
Object.prototype.x = 10
console.log(window.x)
```

17. Написать обертку (example: await promiseTimeout(promise, 1000);)
```javascript
const promiseTimeout = (
  promise: Promise<any>,
  ms: number
): Promise<any> => {
}
```
<file_sep>/OOP.md
# ООП
* Статическое поле/метод
* Инкапсуляция; модификаторы доступа: public, private, protected; свойство класса (геттер, сеттер)
* Наследование, Абстрактный класс
* Ассоциация, Агрегация, Композиция, разница между ними
* Плюсы и минусы наследования. В каких случаях стоит применять композицию, а в каких наследование, при проектировании. (привести пример сравнения)
* Основное назначение интерфейсов. Полиморфизм подтипов
* Множественное наследование, проблема ромбовидного наследования. Наследование через интерфейсы делегирование
* Связность, связанность. Как повысить связность, как понизить связанность? Декомпозиция
* UML диаграмма классов
* Шаблоны (понимание, обоснование применения): Издатель-подписчик (Publish–subscribe), Одиночка,Фабричный метод, Абстрактная фабрика
* MVC - Отношения между моделью, вьюхой и контроллером
* СОЛИД, первые четыре принципа (поверхностное представление)

***

## Статическое поле/метод.
Метод, свойство не привязанное к конкретному экземпляру. Записывается в функцию конструктор.
Используется для служебных функций, логирования, фабричных методов.
Статические поля, методы наследуются.

***

## Инкапсуляция; модификаторы доступа: public, private, protected; свойство класса (геттер, сеттер).
Инкапсуляция это свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе и скрыть детали реализации от пользователя. Инкапсуляция неразрывно связана с понятием интерфейса класса. По сути, всё то, что не входит в интерфейс, инкапсуляция в классе.

#### Модификаторы доступа:
* public — общедоступные
* protected —доступуные только для потомко
* private — доступные только внутри класса
* Get/set - это свойства-аксессоры (accessor properties). По своей сути это функции, которые используются для присвоения и получения значения, но во внешнем коде они выглядят как обычные свойства объекта. Они позволяют в любой момент взять «обычное» свойство и изменить его поведение, поменяв на геттер и сеттер.
```javascript
const obj = {
	_name: '',

	get name() {
  	return this._name;
  },
  set name(value) {
  	this._name = value;
  }
}

obj.name = 'Bobby';
console.log(obj.name) // Bobby
```
[подробнее о get/set](https://learn.javascript.ru/property-accessors)

***

## Наследование, Абстрактный класс.
#### Наследование
Cвойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым или родительским. Новый класс – потомком, наследником или производным классом.
#### Абстрактный класс
Базовый класс, не предпологающий создание экземпляров. Обычно содержит абстрактные методы, наследуемые потомками ( реализация полиморфизма ).

***

## Ассоциация, Агрегация, Композиция, разница между ними.

#### Ассоциация
Ассоциация это такой тип при котором объекты будут ссылаться друг на друга. При этом они остаются полностью независимыми друг от друга.
(Ассоциация это когда у одного класса есть ссылка на другой класс)

```javascript
class Logger {
  constructor() {
    this.stream = null;
  }
  log(message) {
    if (this.stream) {
      this.stream.write(message);
    }
  }
}
const logger = new Logger();
logger.stream = process.stdout;
logger.log('Here we are');
```

#### Агрегация
Агрегация это тип отношений когда один объект является частью другого. Агрегация образует слабую связь между объектами. Все зависимые классы инициализируются вне основного объекта.
```javascript
class Logger {
  constructor(stream) {
    this.stream = stream;
  }
  log(message) {
    if (this.stream) {
      this.stream.write(message);
    }
  }
}
const logger = new
logger(process.stdout);
logger.log('Here we are’);

```

#### Композиция
 При таком типе отношений основной объект полностью обеспечивает жизненный цикл объектов от которых он зависит. (Класс вызывающий внешний класс из библиотеки)
```javascript
const fs = require('fs')
class Logger {
  constructor(name) {
    this.stream = fs.createWriteStream(name);
  }
  log(message) {
    this.stream.write(message);
  }
}
const logger = new Logger('file.log');
logger.log('Here we are');
```

***

## Плюсы и минусы наследования. В каких случаях стоит применять композицию, а в каких наследование, при проектировании. (привести пример сравнения)
#### Плюсы наследования:
+ используется статически на этапе компиляции.
+ выстраивает понятную архитектуру

#### Минусы наследования
⁃ нарушает инкапсуляцию.
⁃ Тесная связь влекущая за собой изменение в подклассе.
⁃ Зависимость от реализации может повлечь за собой проблемы при попытке повторного использования подкласса. Если хотя бы один аспект унаследованной реализации непригоден для новой предметной области, то приходится переписывать родительский класс или заменять его чем-то более подходящим.

***

## Основное назначение интерфейсов. Полиморфизм подтипов.

#### Интерфейс
**Интерфейс** - это граница между объектами системы, через которую они взаимодействуют.
Определяет основные средства и границы коммуникации между классами или компонентами.
Также можно представить как спецификацию или контракт который должен реализовать класс. В typescript интерфейс описывает поля и методы классов ( например в React это могут быть интерфесы для props и state ).

#### Полиморфизм
Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта нее стоит путать с параметрическим полиморфизмом.
Параметрический полиморфизм - подразумевает исполнение одного и того же кода для всех допустимых типов аргументов.

***

## Множественное наследование, проблема ромбовидного наследования. Наследование через интерфейсы, делегирование.
#### Проблемы
Проблемы как такого множественного наследование это дублирование переменных.
Проблемы ромбовидного наследования, это замыкание в следствии которого потеря памяти из за дублирование переменных в дочерних классах.

#### Наследование через интерфейсы
У интерфейсов нет данных как у абстрактных классов и каждая функция которая есть у интерфейса должна быть виртуальной.

#### Делегирование
- TODO

***

## Связность, связанность. Как повысить связность, как понизить связанность? Декомпозиция.
#### Cвязывание - это когда часть кода (модуль) знает структуру данных, методы, события, контракты другой части модуля.
Способы связывания:
1. через обращение к данны (Наиболее связанный код, получается неразрывный модуль)
2. Вызовов функций или методов (Менее связанный, разные модули)
3. трансляция событий

#### Под связностью (связка) подразумевают насколько тот или иной модуль является узкопрофильным. Связность должна быть высокой.
Если в слое бизнес-процесса расположить инициализацию строки соединения, выборку данных , то это приведет к сильной связанности (увязки) программного кода и слабой связности внутри модуля.
Для обратного поведения нужно разделять логику на разные уровни. (использовать dependency ingection)
(Вместо того, чтобы создавать Service объект внутри App класса, надо создать Service заранее и затем передать его в объект App как аргумент конструктора.)
[Подробнее](https://tyapk.ru/blog/post/dependency-injection-and-service-container)

***

## UML диаграмма классов.
Структурная диаграмма языка моделирования UML, демонстрирующая общую структуру иерархии классов системы, их коопераций, атрибутов (полей), методов, интерфейсов и взаимосвязей между ними.

***

## Шаблоны (понимание, обоснование применения) Издатель-подписчик (Publish–subscribe), Одиночка, Фабричный метод, Абстрактная фабрика.
#### Шаблон проектирования, или паттерн.
В разработке программного обеспечения — повторяемая архитектурная конструкция, представляющая собой решение проблемы проектирования, в рамках некоторого часто возникающего контекста.

#### Одиночка
Обеспечивает тот факт, что создаваемый объект является единственным объектом своего класса.
Вообще шаблон одиночка признан антипаттерном, необходимо избегать его чрезмерного использования. Он необязательно плох и может иметь полезные применения, но использовать его надо с осторожностью, потому что он вводит глобальное состояние в ваше приложение.

#### Фабричный метод
Порождающий шаблон проектирования, предоставляющий подклассам интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс создавать. Иными словами, данный шаблон делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне.

#### Абстрактная фабрика
Порождающий шаблон проектирования, предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов. Шаблон реализуется созданием абстрактного класса Factory, который представляет собой интерфейс для создания компонентов системы (например, для оконного интерфейса он может создавать окна и кнопки). Затем пишутся классы, реализующие этот интерфейс.

#### Издатель-подписчик (англ. PubSub)
Поведенческий шаблон проектирования передачи сообщений, в котором отправители сообщений, именуемые издателями (англ. publishers), напрямую не привязаны программным кодом отправки сообщений к подписчикам(англ. subscribers). Вместо этого сообщения делятся на классы и не содержат сведений о своих подписчиках, если таковые есть. Аналогичным образом подписчики имеют дело с одним или несколькими классами сообщений, абстрагируясь от конкретных издателей..

***

## MVC - Отношения между моделью, вьюхой и контроллером.
#### MVC
Подход к проектированию приложения, который предполагает выделение кода в блоки модель, представление и контроллер.
* Контроллер обрабатывает входящие запросы.
* Модель достаёт из базы данных информацию, нужную для выполнения конкретных запросов.
* Представление определяет результат запроса, который получает пользователь.

***

## СОЛИД, первые четыре принципа (поверхностное представление).
#### S: Single Responsibility
Principle (Принцип единственной ответственности).
Класс должен быть ответственным только за что то одно.

#### O: Open-Closed Principle
(Принцип открытости-закрытости).

#### L: Liskov Substitution Principle
(Принцип подстановки Барбары Лисков).

#### I: Interface Segregation Principle
(Принцип разделения интерфейса).

#### D: Dependency Inversion Principle
(Принцип инверсии зависимостей).
Позволяет направить зависимости от низкоуровниевых сущностей (логгер) к более высокооуровневым (бизнес логика) с большим приоритетом. Например используя интерфейсы в высокоуровненых сущностях.
Это необходимо для предотвращения необходимости вносить изменения в бизнес логику при изменении мение важных частей системы.
[Подробное видео на это тему](https://www.youtube.com/watch?v=u6gAVCEJjQ4)

***
<file_sep>/PureCode.md
## Командный код
Чеклист представляет из себя оглавление из книги чистый код. Книга большая и очень полезная, но ее лучше читать по оглавлению. Имя большинства глав – тезис. Если для вас он очевиден, и не подразумевает разночтений, и вы с ним согласны – можно не чиать.
В противном случае читать обязательно. Можно не соглашаться, но делать это надо аргументировано.
"А мне не нравится" – не аргумент.
Примеры согласия или несогласия с каждым из тезисов надо будет суметь показать в личном или эталонном коде.

***

### Именование
1. Имена должны передавать намерения программиста:
Имя не должно требовать дополнительных комментариев;
 -должна отвечать на главные вопросы, почему эта переменная существует и что она делает.
 -должно быть содержательным

2.  Избегать дезинформации
 Ложные ассоциации
 Избегать скрытые значения отличные от предполагаемого
 -hp это и разновидность Unix и длина гипотенузы.
 -Длинные похожие имена можно спутать, как пример автодополнение
 -Не стоит писать acountList если данные не в List
 -Строчная l и 1 0 и o (избегать)

3.  Осмысленные различия
 -a1, a2 - не несут информации.
 -Есть класс: Product -> ProductInfo и ProductData
 Info Data не несут полезной информации.

4. Удобопроизносимые имена
Программирование это социальная деятельность и не хочется выглядишь идиотом. GenerationTimestamp вместо genymdhms

5. Выбирать имена удобные для поиска
«e» самая распространённая буква английского алфавита подобное именование может быть использовано только только в локальных переменных в коротких методах. Длинна имени должна соответствовать размеру области видимости

6. Избегать схем кодирования имён
 Плохо произносится, легко сделать опечатку, дополнительная нагрузка для изучения

7. Избегать мысленных преобразований
 Не создавать временных заменителей который должен мысленно преобразован
 (Нет хуже концепции выбрать с если а уже занято)

8. Имена классов и методов
 Имена классов и объектов должны быть существительными и их комбинациями Customer, Account, AddressParser. Не использовать: info data processor manager, имя класса не должно быть глаголом.
 Имя методов: глаголы и глагольные сочетания. postPayment, deletePage, save
 Методы чтения / записи get set и is

9. Избегать остроумия
 У всех разное чувство юмора, возможна неправильная трактовка переменных.

10. Выбирать одно слово для каждой концепции
 Не должно существовать в разных классах эквивалентных методов (путаница)

11. Использовать имена из пространства решения
Не стесняться использовать термины из области информатики, паттернов, тех.понятий понятных разработчикам AccountVisitor

12. Использовать имена из пространства задачи
 Если нет подходящих названий из пространства решений, использовать имена из пространства задачи. Уточнить у специалиста предметной области

13. Добавлять содержательные контекст
 При помощи префиксов add addFirstName addLastName
 Или разделить функцию на меньшие смысловые фрагменты создав класс и сделать переменные полями этого класса // уточнить

14.  Не добавлять избыточный контекст
 Если приложение называется Gas Station Deluxe, не нужно снабжать имя класса префиксом GSD

 ***

### Функции
15. Функции Компактность
 Функции должны быть максимально понятными

16.  Правило одной операции
 Функция должна выполнять одну операцию.

17.  Один уровень абстракции
 Все Команды функции должны находиться на одном уровне абстракции. //Уточнить
 1 уровень залез в базу
 2 уровень прочитал данные
 3 отрисовал данные
 Если добавляется необходимость подключения к базе номер 2 то реализация должна быть выполнена на 1 уровне.

18. Чтение кода сверху вниз: правило понижения
 За каждой функцией должны следовать функции следующего уровня абстракции. // уточнить

19. Аргумент функции
 Унарная и бинарная, максимум тернарная. (Не более 3, в идеале без аргументов)полинарных быть Не должно. Сложно тестировать как входные параметры так и проблемы с выходными.

20. Избавиться от побочных эффектов.
 Функция не должно выполнять скрытых операций (работа должна быть прозрачной для понимания)
21. Разделение команд и запросов.
 Функция должна либо изменять состояние объекта либо возвращать информацию о нем, но не все вместе.

22. Не повторяйтесь (Do not repeat your self)
 Код не должен повторяться, все технологии программирования являются стратегиями борьбы с дублированием

23. Структурное программирование
 Изложено Эдгаром Дейкстрой
 Каждая функция должна иметь 1 точку входа и одну выхода. (Return, continue, goto)
 Не должны использоваться никогда. /// в компактной функции все кроме goto можно использовать.

***

### Комментарии
24. Комментарии не компенсируют плохого кода
 Если нет понимания кода, лучше его переписать.

25. Юридический комментарий
 Например заявление об авторских правах, лучше ограничатся ссылкой на лицензию.

26. Информативные комментарии
 // Поиск по формату: kk:mm:ss EEE. MMM dd, yyyy
 Пример регулярное выражение предназначенное для идентификации времени и даты. (Также можно избежать комментария переместив код в спец. Класс)

27. Представление намерений
 // мы пытаемся.. (комментарий о намерении, не лучший способ документирования)

28. Прояснение
 Комментарий прояснения уместен если это код вы не можете изменить например библиотека. (Есть риск что комментарий окажется неверным, лучше тщательно смотреть за выходными и входными параметрами и сделать их более понятными)

29. Предупреждение о последствии
 Обьясняет почему конкретный сценарий был отключён, такой комментарий бывает полезным. (Поможет ретивому программисту более серьезно отнестись к данному сценарию)

30. TODO
 Что по мнению программиста сделать необходимо, но по какой то причине нельзя сделать прямо сейчас. ( Нужно регулярно просматривать и редактировать удалить те, которые потеряли актуальность)

31. Усиление
 Подчёркивает важность обстоятельства, которое на первый взгляд кажется не существенным.
 //вызов trim() важен. Он удаляет начальные проблемы

32. Комментарий JS в общедоступных API
 Если речь идёт о разработке API для общего пользования, для него следует написать хорошие комментарии JSDoc, (соблюдая все правила комментирования)
/**
* @Param {*} name
*/

33. Виды плохих комментариев
 Подпорки для некачественного кода и оправдания сомнительных решений.
Вертикальное форматирование
34. Вертикальное форматирование
 Желательно, система или приложение должно состоять из файлов от 200 до 500 строк.

35. Газетная метафора
 Начальные блоки исходного файла описывают высокоуровневые концепции и алгоритмы, степень детализации увеличивается при перемещении к концу файла. В самом конце собираются все функции и подробности низшего уровня в исходном файле.

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

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

38. Вертикальное расстояние
 Концепции тесно связанные друг с другом должны находиться поблизости по вертикали. Вертикальное разделение должно показывать насколько они важны для понимания друг друга.
 -Объявление переменных
 Переменные следует объявлять как можно ближе к месту использования. Локальные переменные должны перечисляться в начале каждой функции
 Управляющие перемененные циклов объявляться внутри цикла, в отдельном случае в начале блока или перед циклом в длинной функции.
 Переменны экземпляров должны объявляться в начале класса (в хорошо спроектированном проекте они используются многими если не всеми методами класса)
 Зависимые функции
 Если одна вызывает другую то вызывающая функция должна быть над вызываемой.
 Концептуальное родство - если фрагменты требуют что бы их вблизи от других фрагментов, то они обладают концептуальными родством. Чем сильнее родство тем меньше вертикальное расстояние.(функция вызывает функцию, группа функций выполняет антологичным операции)

39. Вертикальное упорядочивание
 От высокого уровня к более низкому, вызываемая функция расположена ниже вызывающей. (Как в газетных статьях, важные концепции изложены сначала)
Классы

***

### Классы

40. Строение классов
    1. Класс должен начинаться со списка переменных
        1. открытые статические константы
        2. приватные статические переменные
        3. приватные переменные экземпляров (Открытых переменянных обычно нет)

    2. За переменными
        1. Открытые функции (Приватные вспомогательные, вызываемые открытыми, непосредственно за самой открытой) - соответсвует правилу понижения, читается как газетная статья.

41. Инкапсуляция
 Если тест из того же пакета должен вызывать функцию или обратиться к переменной, используем защищённый или пакетный уровень доступа. Тем не менее начинать следует с поиска способов сохраняющего приватность, ослабление инкапсуляции всегда должно быть последней мерой.

42. Классы должны быть компактными
 Класс как и функция должен быть компактным и иметь разумное количество ответственностей.
 Чем туманнее имя класса, тем больше вероятность что он имеет слишком много ответственностей.

43. Принцип единой ответсвенности (SRP)
 Принцип единой ответсвенности утверждает что класс или модуль должен иметь одну и только одну причину для изменения.

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

45. Поддержание связности приводит к уменьшению классов
 При разбиений большой функции с переменными на мелкие, не стоит передавать переменные а лучше преобразовать эти переменные в переменные экземпляров класса. Таким образом разбиение функции на меньшие фрагменты упрощается. (Если группа функций должна работать с некоторыми переменными, группа  образует класс сама по себе. Если классы утрачивают связность, их нужно разбить)

46. Структурирование с учетом изменений
 Структура класса должна быть такой что бы класс не приходилось открывать и нарушать принцип единой ответсвенности. (Необходимо создать субклассы.)??

47. Изоляция изменений
 Создание класса прослойки, что бы при тестировани входные данные не изменялись (если мы не можем гарантировать точность данных которые пришли)

 ***
<file_sep>/JavaScriptFrontend.md
## JavaScript Фронтэнд
* способы оптимизации работы с ДОМом. Список самых дорогих операций
* манипуляции с DOM - поиск, добавление, изменение, удаление классов и узлов
* repaint и reflow

### способы оптимизации
1. Работать с «offline» элементом (т.е. который находится не в DOM, а в памяти), с последующим помещением его в DOM.
Добавляем в дом дерево фрагмент из элементов / а не каждый раз обращаемся к дом дереву для добовдления элемента
```
const  fragment = document.createDocumentFragment();
fragment.appendChild(li)
list.appendChild(fragment)
```
2. Для изменения стилей элементов лучше модифицировать только атрибут «class», и как можно глубже в дереве DOM.
3. Анимировать желательно только абсолютно и фиксировано спозиционированные элементы.
4. ...TODO...

### cписок самых дорогих операций
TODO

#### поиск

| Метод                   | Ищет по..       | Ищет внутри элемента? | Возвращает живую коллекцию?|
|:----------------------- |:---------------:| ---------------------:| --------------------------:|
| querySelector           |CSS-selector     |+                      |-                           |
| querySelectorAll        |CSS-selector     |+                      |_                           |
| getElementById          |id               |-                      |_                           |
| getElementsByName       |name             |_                      |+                           |
| getElementsByTagName    |tag or '*'       |+                      |+                           |
| getElementsByClassName  |class            |+                      |+                           |

### добавление
Создаёт новый элемент с заданным тегом:
```
let div = document.createElement('div’);
```

Создаёт новый текстовый узел с заданным текстом:
```
let textNode = document.createTextNode('А вот и я’);
```
Клонирует элемент, если deep==true, то со всеми дочерними элементами.
```
elem.cloneNode(deep)
```
методы для различных вариантов вставки:
```
node.append(...nodes or strings) – добавляет узлы или строки в конец node,
node.prepend(...nodes or strings) – вставляет узлы или строки в начало node,
node.before(...nodes or strings) –- вставляет узлы или строки до node,
node.after(...nodes or strings) –- вставляет узлы или строки после node,
```

### изменение
```
node.replaceWith(...nodes or strings) –- заменяет node заданными узлами или строками.
```

### удаление классов
```
elem.classList.add/remove("class") – добавить/удалить класс.
elem.classList.toggle("class") – добавить класс, если его нет, иначе удалить.
elem.classList.contains("class") – проверка наличия класса, возвращает true/false.
```

### удаление узлов
```
node.remove()
```
### The rendering process of a web page
![rebase](/img/browser_flow.png)

### repaint
В случае изменения стилей элемента, не влияющих на его размеры и положение на странице (например, background-color, border-color, visibility), браузер просто отрисовывает его заново, с учётом нового стиля — происходит repaint (или restyle).

### reflow
Если же изменения затрагивают содержимое, структуру документа, положение элементов — происходит
reflow (или relayout).
Причинами таких изменений обычно являются:
* Манипуляции с DOM (добавление, удаление, изменение, перестановка элементов);
* Изменение содержимого, в т.ч. текста в полях форм;
* Расчёт или изменение CSS-свойств;
* Добавление, удаление таблиц стилей;
* Манипуляции с атрибутом «class»;
* Манипуляции с окном браузера — изменения размеров, прокрутка;
*  Активация псевдо-классов (например, :hover).

Браузеры по возможности локализуют repaint и reflow в пределах элементов, подвергнувшимися изменению.
Например, изменение размеров абсолютно или фиксировано спозиционированного элемента затронет только
сам элемент и его потомков, в то время как изменение статично спозиционированного — повлечет reflow всех элементов, следующих за ним.

#### Аппаратное ускорение
Использование GPU для отрисовки слоев графики. В CSS могут быть обработаны напрямую через GPU:
* transform
* opacity
* fulter
* 3D трансформации ( translate Z )
* тэги Video Canvas
* z-index
В этом случае создается отдельный слой обрабатываемый через GPU.

### cписок самых дорогих операций.
TODO

<file_sep>/HtmlCss.md
## Верстка
* БЭМ. Вся вёрстка должна быть по БЭМу, показать в примерах. Без инструментов, только методология (именование и декомпозиция)
* сверствать 2-3 колонки всеми способами способами: flex, float, inline-blocks, position, tables
* отцентрировать блок. По горизонтали, по вертикали. Без js и с
* примеры transition и animation, включая варианты с аппаратным ускорением
* примеры адаптивной верстки: на телефоне, планшете и десктопе. media-queries, виртуальные пиксели подход s, m, l, xl
* подключение к проекту кастомного шрифта, с разными начертаниями
* пример испольования спрайтов, для иконок, под ретину

#### БЭМ. Вся вёрстка должна быть по БЭМу, показать в примерах. Без инструментов, только методология (именование и декомпозиция)

[Пример именования](http://yoksel.github.io/easy-markup/bem-rules/)

```
Декомпозиция (разделение целого на части)
.block {
    &__element {
    }
}
.block-element {
    &__child {
        color: black;
    }
    &_active &__child {
        color: red;
    }
}
```

#### сверствать 2-3 колонки всеми способами способами: flex, float, inline-blocks, position, tables.

TODO

#### отцентрировать блок. По горизонтали, по вертикали. Без js и с.

TODO

#### примеры transition и animation, включая варианты с аппаратным ускорением

Transition
```
div {
width: 100px;
transition-property: width;
}
div:hover {
width: 300px;
}
```

#### Animation

TODO

#### примеры адаптивной верстки: на телефоне, планшете и десктопе. media-queries, виртуальные пиксели, подход s, m, l, xl

TODO

#### подключение к проекту кастомного шрифта, с разными начертаниями

TODO

#### пример испольования спрайтов, для иконок, под ретину
<file_sep>/Console.md
# Console
* создать файл и директорию, удалить, скопировать, переместить;
* chmod
* chown
* ssh, scp
* find/grep
* vim: создать файл, сохранить, отредактировать, выйти (с сохранением и без)
* top/kill

***

### создать файл
* Используя утилиту touch
```
touch file.txt
```

Используя редактор
```
vim file.txt
nano file.txt
cat file.txt
```

Оператор перенаправления
```
> file.txt
echo «строка» > file.txt
```

### создать директорию
Cоздание каталогов выполняется командой "mkdir" (от англ. make directory):
```
mkdir dir_name
```

Создать директорию с именем "dir1»:
```
mkdir dir1
```

Создать две директории одновременно:
```
mkdir dir1 dir2
```

Создать дерево директорий:
```
mkdir -p /dir1/dir2
```

### удалить файл
Для удаления файлов используется команда "rm" (от англ. remove).
Работает очень просто, пишете команду rm и путь к файлу, который хотите удалить:
Удалить файл с именем "file1»:
```
rm file1
```

Но команда "rm" позволяет удалять не только файлы, но и директории (каталоги) вместе с их содержимым
Удалить директорию с именем "dir1" и рекурсивно всё её содержимое:
```
rm -r dir1
```

Удалить две директории и рекурсивно их содержимое:
```
rm -r dir1 dir2
```

Также можно добавить параметр -f, который означает, что при удалении не будет запрашиваться подтверждение на удаление. Команды будут выглядеть так:
```
rm -f file1
rm -rf dir1
```

### скопировать файл
cp опции файл-источник файл-приемник
cp опции файл-источник директория-приемник/

Список опций:
* --attributes-only - не копировать содержимое файла, а только флаги доступа и владельца;
* -f, --force - перезаписывать существующие файлы;
* -i, --interactive - спрашивать, нужно ли перезаписывать существующие файлы;
* -L - копировать не символические ссылки, а то, на что они указывают;
* -n - не перезаписывать существующие файлы;
* -P - не следовать символическим ссылкам;
* -r - копировать папку Linux рекурсивно;
* -s - не выполнять копирование файлов в Linux, а создавать символические ссылки;
* -u - скопировать файл, только если он был изменён;
* -x - не выходить за пределы этой файловой системы;
* -p - сохранять владельца, временные метки и флаги доступа при копировании;
* -t - считать файл-приемник директорией и копировать файл-источник в эту директорию.
Пример:
```
cp ~/pic.png ~/pictures/
```

### переместить
Чтобы переместить файл в другое место или изменить его имя, используйте команду mv (move).
Она принимает два аргумента: имя файла или каталога для перемещения, а затем имя пути для перемещения.
Если Вы перемещаете файл в каталог, в котором уже есть файл с таким именем, то он будет перезаписан.
Чтобы переместить файл notes из текущего рабочего каталога в каталог ../play
```
mv notes ../play
```

Если в родительском каталоге текущего каталога нет подкаталога play, эта команда переместит файл notes
в родительский каталог и переименует его в play.
Чтобы переместить файл или каталог, который не находится
в текущем каталоге, укажите в качестве аргумента его полное имя и путь.
Чтобы переместить файл /usr/tmp/notes в текущий рабочий каталог.
```
mv /usr/tmp/notes
```

Чтобы переместить каталог, укажите путь к каталогу, который нужно переместить и путь к каталогу-приемнику.
Чтобы переместить каталог work из текущего рабочего каталога в каталог play.
```
mv work play
```

Если каталог play уже существует, mv поместит work внутрь play - эта команда не перезаписывает каталоги.
Переименование файла - это то же самое, что и его перемещение; просто укажите в качестве аргументов файл для переименования и его новое имя.
Чтобы переименовать файл notes в notes.old
```
mv notes notes.old
```

### chmod
chmod опции права /путь/к/файлу
* 0 - никаких прав;
* 1 - только выполнение;
* 2 - только запись;
* 3 - выполнение и запись;
* 4 -  только чтение;
* 5 - чтение и выполнение;
* 6 - чтение и запись;
* 7 - чтение запись и выполнение.

Права на папку linux такие же, как и для файла. Во время установки прав сначала укажите цифру прав для владельца, затем для группы, а потом для остальных.
* 744 - разрешить все для владельца, а остальным только чтение;
* 755 - все для владельца, остальным только чтение и выполнение;
* 764 - все для владельца, чтение и запись для группы, и только чтение для остальных;
* 777 - всем разрешено все.

Пример
```
chmod 766 file
```

### chown
Команда chown позволяет менять только владельца и группу
chown пользователь опции /путь/к/файлу

```
chown root ./dir1
```
изменим владельца папки dir1 на root:

```
chown root:root ./dir2
```
поменять сразу владельца и группу каталога

```
chown -R root:root ./dir3
```
(применить изменения ко всем подкаталогам -R)

### ssh
Сетевой протокол. Используется для удаленного управления операционными системами и передачи файлов.
Ключевая особенность заключается в том, что SSH шифрует трафик, делая подключения безопасными.
По умолчанию, использует 22-й порт. Аббревиатура расшифровывается как Secure Shell.
Программные реализации SSH делятся на серверные и клиентские части.
В основном, в качестве сервера применяется OpenSSH, клиентов:
* OpenSSH (UNIX)
* PuTTY
* SecureCRT (Windows, Linux)
Пример подключения по SSH из командной строки Linux:
```
ssh root@192.168.0.15
```

* root — учетная запись, из-под которой выполняем подключение.
* 192.168.0.15 — IP-адрес компьютера, с которым соединяемся.

Для получения полного списка ключей можно воспользоваться командой
```
man ssh.

```

### scp
SCP (от англ. secure copy) — утилита и протокол копирования , в отличие от утилиты RCP, в качестве транспорта не RSH, а шифрованный SSH. Сходная по функционалу утилита — sftp.
В UNIX-подобных операционных системаходноимённая (scp) утилита удалённого копирования файлов часто входит в состав пакета openssh.

Команда копирования локального SourceFile на удалённый хост:
```
scp SourceFile user@host:/directory/TargetFile
```

Команда копирования SourceFile с удалённого хоста:
```
scp user@host:/directory/SourceFile TargetFile
```

Если ssh работает на другом порту, то тогда указывается:
```
scp -P port user@host:/directory/SourceFile /directory/TargetFile
```

Копирование SourceFolder с удалённого хоста внутрь локального TargetFolder
(на локальном хосте получится, что SourceFolder будет находиться внутри TargetFolder):
```
scp -r user@host:/directory/SourceFolder TargetFolder
```

### find
Find - это одна из наиболее важных и часто используемых утилит системы Linux.
Это команда для поиска файлов и каталогов на основе специальных условий.
Ее можно использовать в различных обстоятельствах, например, для поиска файлов по разрешениям, владельцам, группам, типу, размеру и другим подобным критериям.
find [папка] [параметры] критерий шаблон [действие]
* Папка - каталог в котором будем искать
* Параметры - дополнительные параметры, например, глубина поиска, и т д
* Критерий - по какому критерию будем искать: имя, дата создания, права, владелец и т д.
* Шаблон - непосредственно значение по которому будем отбирать файлы.

Основные параметры:
* -P никогда не открывать символические ссылки.
* -L - получает информацию о файлах по символическим ссылкам. Важно для дальнейшей обработки, чтобы обрабатывалась не ссылка, а сам файл.
* -maxdepth - максимальная глубина поиска по подкаталогам, для поиска только в текущем каталоге установите 1.
* -depth - искать сначала в текущем каталоге, а потом в подкаталогах
* -mount искать файлы только в этой файловой системе.
* -version - показать версию утилиты find.
* -print - выводить полные имена файлов.
* -type f - искать только файлы.
* -type d - поиск папки в Linux.

Основные критерии:
* -name - поиск файлов по имени.
* -perm - поиск файлов в Linux по режиму доступа.
* -user - поиск файлов по владельцу.
* -group - поиск по группе.
* -mtime - поиск по времени модификации файла.
* -atime - поиск файлов по дате последнего чтения.
* -nogroup - поиск файлов, не принадлежащих ни одной группе.
* -nouser - поиск файлов без владельцев.
* -newer - найти файлы новее чем указанный.
* -size - поиск файлов в Linux по их размеру.
[Примеры](https://losst.ru/komanda-find-v-linux)

### grep (Global regular expression printer)
Утилита командной строки, которая находит на вводе целые строки, отвечающие заданному регулярному выражению, и выводит их, если вывод не отменён специальным ключом.
Примеры grep в чистом виде:

```
grep '12:00' /home/david/backup/log.txt
```
Производит поиск подстроки 12.00 в файле /home/david/backup/log.txt и отображает все строки где эта подстрока встречается.
Эта комбинация может быть использована например для поиска бекапов которые происходили в 12:00.

```
rep -v '12.00' /home/david/backup/log.txt
```
С использованием ключа -v наоборот покажет только те строки где подстрока ’12:00′ не встречается.

```
grep -l 'delay' /code/*.c
```
Ищет все файлы оканчивающиеся на .c и текст в найденых файлах соответствующий подстроке 'delay' и в конечном итоге выведет только имена файлов где эта подстрока встречается.

```
grep -w '\<bay' *  grep -w 'watch\>'
```
Состоит из комбинации двух команд grep. Первая ищет строки которые начинаются со слова ‘bay’ а вторая строки которые заканчиваются на слово ‘watch’.
Примеры grep использования вместе с потоком.

```
 ls -l | grep rwxrwxrwx
```
Часть grep rwxrwxrwx фильтрует результат полученый от ls -l и выводит только те директории у которых установлены соответствующие права доступа.
Вывод от команды grep может также быть направлен потоком в другую команду, например как в следующем примере:

```
 du | grep 'mp3' | more
```
Выводит постранично список mp3 файлов найденых в текущей директории.

```
grep '^#' /home/david/script1 | more
```
Отобразит все строки в файле /home/david/script1 которые начинаются с символа ‘#’. Определение тип ‘^#’ означает что символ ‘#’ должен быть первым символом с троке.

```
grep -v '^[0-9]' /home/david/backup/log.txt | more
```
Ищет строки содержащие в первом символе цифры от 0 до 9 а потом выводит только те строки которые не
попали в результаты поиска. Как вы видите — был использован ключ ‘-v’ означающий реверсивный поиск.
Важно: Необходимо заключать искомые строки в одинарные кавычки как указано в двух предыдущих примерах для того чтобы интерпретатор командной строки мог воспринимать их корректно. Иначе интерпретатор  может понять это как другую команду и результат выполнения будет непредсказуем.

### vim: создать файл, сохранить, отредактировать, выйти (с сохранением и без)

VIM - это свободный текстовый редактор, возможности которого во многом превосходят возможности обычного редактора.
Однако есть минус - интерфейс редактора не интуитивен, поэтому для работы с ним нужно некоторое время потратить на изучение команд, горячих клавиш и т.п.
VIM имеет три режима работы:

* командный
* режим редактирования
* визуальный режим

Для перехода в командный режим требуется нажатие Esc.
Все команды в VIM вводятся с символа двоеточия - ":" (без кавычек).
Для перехода в визуальный режим требуется нажатие Ctrl+V.
q - закрыть файл, если не требует сохранения, т.е. в файле не было изменений. В противном случае VIM выдаст сообщение об ошибке, как показано на рисунке;

:q! - закрыть файл без сохранения;
:qa! - закрыть все файлы без сохранения;
:wq - закрыть и сохранить файл;
:wqa - закрыть все файлы с сохранением.

Работа с текстом
Перемещение по тексту.
VIM обладает большими возможностями для ускорения работы с текстом и имеет большое количество команд для перемещения по тексту.
Для перемещения можно использовать стрелочки, а также h (Влево), l (Вправо), j (Вниз), k (Вверх).
Другие команды для перемещения по тексту:
* |, 0, home — в начало строки;
* ^ — на первый непустой символ в строке;
* , end — в конец строки;
* m — на половину ширины экрана;
* g — на нижнюю строку;
* e — до конца слова;
* . — на строку вверх и на первый непустой символ;
* +, Enter — на строку вниз и на первый непустой символ;
* G — на последнюю строку;
* H — на первую строку экрана;
* M — на среднюю строку экрана;
* L — на последнюю строку экрана;
* w — на слово вперед;
* b — на слово назад;
* ( — на предложение назад (до точки);
* ) — на предложение вперед (до точки);
* { — на абзац назад (до пустой строки);
* } — на абзац вперед (до пустой строки);
* :ju — список переходов.

Редактирование текста.
VIM также имеет большое количество возможностей для быстрого редактирования.
* Del, x - удаление символа под курсором;
* X - удаление символа перед курсором;
* u, :u — отмена последнего действия;
* U — отменить все изменения, повлиявшие на текущую строку;
* ~ — перевести в верхний или нижний регистр в зависимости от текущего символа под курсором;
* C — удалить от курсора и до конца строки с переходом в режим ввода;
* D — удалить от текущего символа до конца строки;
* dd — вырезать строку, на которой стоит курсор. Перед любой командой можно ввести числовой модификатор, который укажет сколько раз выполнить команду. Например: 3dd - удалит три строки начиная с текущей;
* yy — копирует строку. Также можно использовать числовой модификатор;
* p — вставить после текущей строки;
* P — вставить перед текущей строкой;
* << — сдвиг влево текущей строки;
* '>>' — сдвиг вправо текущей строки (без кавычек);
* J — объединение текущей строки с последующей.

* :set number — включить отображение номеров строк;
* :set nonumber — отключить отображение номеров строк;
* = — расстановка отступов для языка программирования С.

### top/kill (table of processes)
Консольнаякоманда, которая выводит список работающих в системе процессов и информацию о них.
По умолчанию она в реальном времени сортирует их по нагрузке на процессор.

1 строка общая реформация top.
* текущее время.
* время работы системы.
* количество открытых пользовательских сессий.
* среднюю загрузку системы.

2 строка - статистика процессов.
* общее количество процессов в системе.
* количество работающих в данный момент процессов.
* количество ожидающих событий процессов.
* количество остановленных процессов.
* количество процессов, ожидающих родительский процесс для передачи статуса завершения.

3 строка - статистика использования центрального процессора.
* процент использования центрального процессора пользовательскими процессам.
* процент использования центрального процессора системными процессами.
* процент использования центрального процессора процессами с приоритетом, повышенным при помощи вызова nice.
* процент времени, когда центральный процессор не используется.
* процент использования центрального процессора процессами, ожидающими завершения операций ввода-вывода.
* процент использования центрального процессора обработчиками аппаратных прерываний.
* процент использования центрального процессора обработчиками программных прерываний.
* количество ресурсов центрального процессора "заимствованных" у виртуальной машины гипервизором для других задач (таких, как запуск другой виртуальной машины); это значение будет равно нулю на настольных компьютерах и серверах, не использующих виртуальные машины

4 и 5 строки - статистика использования памяти выводится информация об использовании физической оперативной памяти и раздела подкачки соответственно.

Значения в порядке следования:
* общее количество памяти.
* количество используемой памяти.
* количество свободной памяти.
* количество памяти в кэше буферов.

Последним источником информации является список процессов, отсортированный по степени использования центрального процессора (по умолчанию).

Значения столбцов списка:
* PID - идентификатор процесса
* USER - имя пользователя, который является владельцем процесса (root)
* PR - приоритет процесса
* NI - значение "NICE", влияющие на приоритет процесса
* VIRT - объем виртуальной памяти, используемый процессом
* RES - объем физической памяти, используемый процессом
* SHR - объем разделяемой памяти процесса
* S - указывает на статус процесса: S=sleep (ожидает событий) R=running (работает) Z=zombie (ожидает родительский процесс) (S)
* %CPU - процент использования центрального процессора данным процессом
* %MEM - процент использования оперативной памяти данным процессом
* TIME+ - общее время активности процесса
* COMMAND - имя процесса

```
kill
```
Когда вы выполняете команду "kill", то фактически вы посылаете системе сигнал, чтобы заставить ее завершить некорректно ведущее себя приложение. Всего вы можете использовать до 60 сигналов.

Основные два сигнала:
* SIGTERM (15)
* SIGKILL (9)

```
kill -l
```
(посмотреть перечень всех сигналов)

SIGTERM - этот сигнал запрашивает остановку работы процесса. Он может быть проигнорирован. Процессу дается время на корректное завершение.
Если программа завершается корректно, значит она использовала данное время на то, чтобы сохранить свое состояние или результаты работы и освободить ресурсы.
Другими словами, ее не заставляли остановиться.

SIGKILL - этот сигнал заставляет процесс прекратить работу немедленно. Программа не может проигнорировать этот сигнал.
Несохраненные результаты будут потеряны.

kill [сигнал или опция] PID
Сигнал по умолчанию (если он не задан) - SIGTERM. Если он не помогает, для принудительного завершения процесса можно использовать следующие варианты:

```
kill SIGKILL PID
kill -9 PID
```
где флаг "-9" ссылается на сигнал SIGKILL.

Если вы не знаете точно PID приложения, просто запустите команду:

```
ps ux
```

Она выведет информацию по всем запущенным программам.
Также обратите внимание, что можно завершать несколько процессов одной командой.
```
kill -9 PID1 PID2 PID 3
```

Команда "pkill" позволяет использовать расширенные шаблоны регулярных выражений и другие критерии соответствия. Вместо использования PID вы теперь можете завершить приложение, введя имя его процесса. Например, для завершения работы Firefox просто введите команду:
```
pkill firefox
```

Так как оно соответствует шаблону регулярного выражения, вы можете также ввести имя только частично, например:
```
pkill fire
```

Чтобы предотвратить завершение не тех приложений, которые требовалось, можно использовать команду "pgrep -l [process name]" для вывода списка всех подходящих процессов.
```
Killall
```

также использует имя процесса вместо PID и завершает все экземпляры процесса с этим именем. Например, если вы запустили несколько экземпляров Firefox, вы можете завершить их все с помощью команды:
```
killall firefox
```

В Gnome вы можете перезапустить Nautilus с помощью команды:
```
killall nautilus
```

Xkill - это графический способ завершения приложений. Когда вы введете "xkill" в терминале, курсор примет вид крестика. Все, что вам требуется, кликнуть этим крестиком в окне нужного приложения и оно немедленно завершится. Если вам понравится такой способ, можно настроить для активации xkill горячие клавиши.

<file_sep>/JavaScript.md
## JavaScript
* типы
* this, call, apply, bind
* замыкание
* функциональное програмирование
* каррирование
* prototype, рассказ что это и как работает
* ООП в js: наследование, инкапсуляция
* ES6 - const и let, arrow function, классы, шаблонные строки, spread operator, rest parameters, деструктивное присваивание объектов/массивов, cтруктуры данных ES2015: Map, Set, Iterable.
* как устроена асинхронность в js. Event loop
* работа с асинхронностью; promise - основные методы, создание промиса из функции с колбэком

#### Основные архитектурные черты Javascript:

* динамическая типизация - позволяет переопределить переменную в коде тем самым меняя ее тип. Переменная связывается с типом в момент присвоения значения, а не в момент объявления переменной как при статической типизации.
* слабая типизация - характерной чертой является [приведение типов](https://learn.javascript.ru/type-conversions).
* автоматическое управление памятью - [garbage-collection](https://learn.javascript.ru/garbage-collection).
* прототипное программирование.
* функции как объекты первого класса.

### Типы даннных Javascript.
* null
* undefined
* boolean
* string
* number (также сюда относятся Infinity и NaN).
* object (также сюда относятся Array)
* symbol (ES6) - применяется для создания уникальных идентификаторов объектов.

### this, call, apply, bind.
#### this
Указывает на текущий контекст выполнения функции. Задается следующими способами:
1. Функция вызвана через new, this - новый объект.
`const bar = new Foo()`.
2. Функция вызвана с call, aplly или bind.
`const bar = foo.call(obj)` - где this указывает на obj.
3. Функция вызвана с контекстом ( метод объекта ).
`const bar = obj.foo()`.
4. Без явно заданного контекста.
  В режиме 'use strict' - undefined иначе объект global.
  ` const bar = foo()`.

  Стрелочные функции не содержат собственный контекст this, а используют значение this окружающего контекста.
  ```javascript
  function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // `this` указывает на объект Person
  }, 1000);
}

var p = new Person();
```

#### bind
Встроенные метод который возвращает функцию с новым контекстом, контекст передается 1 аргументом. Также можно передать последующие аргументы которые
в дальнейшем будут использоваться.

#### call
Встроенные метод который возвращает и вызывает функцию с новым контекстом, контекст передается 1 аргументом. Также можно передать последующие аргументы которые в дальнейшем будут использоваться.

#### apply
Встроенные метод который возвращает и вызывает функцию с новым контекстом, принимает 2 обязательных параметра это контекст и массив из аргументов.

```javascript
function hello() {
console.log(this)
}

hello()
const person = {
  name: 'Sergey',
  age: 27,
  seyHello: hello,
  seyHelloWindow: hello.bind(window), // window
  logInfo: function (phone, method) {
    console.log(`Name is ${this.name}`)
    console.log(`Age is ${this.age}`)
    console.log(`Phone is ${phone}`)
    console.log(`Method is ${method}`)
  }
}
const alina = {
  name: 'Alina',
  age: 27
}

person.seyHelloWindow() // window
```

**Bind** (Возвращает функцию и мы вызываем ее когда необходимо)
```
const fnAlinaInfoLogBind = person.logInfo.bind(alina, '8-800-888-80-80', 'bind');
fnAlinaInfoLogBind();
```

**Call** (Возвращает функцию и вызывает ее сразу)
```
person.logInfo.call(alina, '8-800-888-80-80', 'call');
```

**Apply** (Поведение аналогично call, разница только в том что принимает вторым аргумент массив из параметров)
```
person.logInfo.apply(alina, ['8-800-888-80-80', 'apply']);
```
#### Замыкание.
Замыкание – это функция, которая запоминает свои внешние переменные и может получить к ним доступ.

В JavaScript у каждой выполняемой функции, блока кода и скрипта есть связанный с ними внутренний (скрытый) объект, называемый лексическим окружением **LexicalEnvironment**.

Объект лексического окружения состоит из двух частей:
 1. Environment Record – объект, в котором как свойства хранятся все локальные переменные (а также некоторая другая информация, такая как значение this).
 2. Ссылка на внешнее лексическое окружение – то есть то, которое соответствует коду снаружи (снаружи от текущих фигурных скобок).

Когда код хочет получить доступ к переменной – сначала происходит поиск во внутреннем лексическом окружении, затем во внешнем, затем в следующем и так далее, до глобального.
`Функция получает текущее значение внешних переменных, то есть, их последнее значение.`

### Функциональное программирование
Это когда функции становятся объектами первого класса которые в свою очередь можно передавать в другие функции в качестве аргументов и получать их в качестве значений.

### Каррирование
Техника функционального программирования, когда функция принимающая несколько аргументов разбивается на набор функций каждая из которых принимает только один аргумент
```javascript
  function cor(a) {
    return (b) => {
      return (c) => {
        return a + b + c
      }
    }
  }
console.log(cor(1)(3)(6)) // 10
```

### prototype, рассказать что это и как работает.
При вызове функции у не всегда создается свойство prototype, изначально ссылается на практически пустой объект у которого есть __proto__ которая указывает на object prototype и конструктор ссылающейся на самом функцию и этот объект начинает работать когда мы вызываем функцию с помощью оператора new.

При создании через оператор new есть три отличия от стандартного поведения
1. Создается новый объект и этот новый объект передается функции в качестве this сама функция тоже вызывается но this-ом является новый объект.
2. Новый объект неявно возвращается из функции (возвращается this  а точнее вновь созданный объект).
3. Ссылка __proto__ нового объекта будет ссылаясь на тот объект который лежит в свойстве  prototype в функции.
Таким образом методы созданные через функцию конструктор, будут взяты у вновь созданных объектов через прототип.
Пример расширения через prototype:
```javascript
const array = [1, 2, 3, 4, 5]
Array.prototype.multBy = function(n) {
  return this.map(function(i) {
    return i * n
  })
}
console.log(array.multBy(2)) // [2, 4, 6, 8, 10]
```

### ООП в js: наследование, инкапсуляция

#### Наследование
Любой объект в JavaScript имеет второй связанный с ним объект который является его прототипом объект наследуют свойство своего прототипа или все свойства которые есть у прототипа будут доступны через дочерний объект.
Это называется prototype inheritance (наследование основное на прототипах), это единственный тип наследования который есть в языке JavsScript.
(В ООП под наследованием понимают наследование дочерними классами свойств и методов родительских классов.)
Работает это следующим образом: создается объект который должен быть прототипам

```javascript
var ObjectProto = {
  name: 'Sergey',
 }
 //и на основе его создаются дочерние объекты при помощи

 //Object.create(Prototype)
 var object = Object.create(ObjectProto)
 console.log(object.name) // Sergey

 //Пример использования, создания однотипных объектов
 var Person = {
 constructor: function(name, age) {
     this.name = name;
     this.age = age;

     return this;
   },
     greet: function () {
     console.log('Hi, my name is' + this.name)
   }
 }

 var firstPerson, secondPerson
 firstPerson = Object.create(Person).constructor('Sergey', 28);
 secondPerson = Object.create(Person).constructor('Alina', 27);
 console.log(firstPerson.name) //Sergey
 secondPerson.greet() //Hi my name is Alina
 ```

#### Инкапсуляция
Данные и методы связанный логическим контекстом, объединяются в общую сущность, а также доступ к этим данным разграничивается на уровни.

1. Приватная или защищенная переменная которая объявлена через let или const.
2. Публичная которую мы записываем через контекст  this.
Пример инкапсуляции - разграничение на уровни доступа наши переменные и методы.

```javascript
function Product(
  name = 'Default product',
  price = 0,
  category = new Date()
) {
this.name = name; //Публичная
this.price = price; //Публичная
this.category = category; //Публичная
const createdDate = createdAt;  //Приватная
}
```

### ES6 - const и let, arrow function, классы, шаблонные строки, spread operator, rest parameters, деструктивное присваивание объектов/массивов

#### const
Позволяет создавать константы которые нельзя изменить входе программы.
(Не поднимаются - нельзя использовать до объявления)

#### let
область видимости внутри блока а именно фигурных скобок { }
(Не поднимаются - нельзя использовать до объявления)

#### arrow function - стрелочная функция
компактные, иная работа с this, не имеет имени.
Особенности:

```javascript
let add = (x, y) => x + y // Присвоили для вызова
//С одним параметром скобки не нужны
x => x + y
//Если в функции несколько строк то необходимо указать скобки и return
let multiply = (x, y) => {
  let result = x * y
  return result;
}

console.log(add(2, 3)); //5
console.log(multiply(2, 2));// 4
```

Если возвращаем литерал объекта то необходимо оборачивать в скобки ()
```
let getPerson = ( ) => ( {name : 'Sergey'} );
```

Вызов функции сразу после ее объявления (immediately invoked function expression)
(() => console.log('IIFI'))(); //IIFI

Стрелочную функцию:
* Нельзя использовать как конструктор.
* Нельзя использовать bind call apply - так как в стрелочных функциях мы не можем менять значение this, так как оно автоматически берется из контекста.
* Не имеет псевдомассив аргументов - *arguments*.

Пример перебора:
```javascript
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = 0;
numbers.forEach(num => sum += num);
console.log(sum) // 55
```

Решение проблемы контекста с помощью стрелочной функции
```javascript
let person = {
    name: 'Sergey',
    greet: function() {
    var that = this; //Сохраняем контекст объекта.
    setTimeout(function() {
        console.log('Hello, my name is' + " " + that.name);
      }, 2000);
    }
};

person.greet() //Hello, my name is Sergey
```

Так как у setTimout контекст window  мы сохранили контекст в переменную что бы c помощью замыкания иметь доступ к контексту объекта.
Данную проблему можно решить с помощью стрелочной функции:
```javascript
let person = {
  name: 'Sergey',
  greet: function () {
    setTimeout(() => {
      console.log('Hello, my name is' + " " + this.name);
    }, 2000);
  }
};

person.greet() //Hello, my name is Sergey
```

### классы
Классы это функции которые создают объекты через ключевое свойство new (синтаксический сахар).
```javascript
class Task {
  constructor(title = Task.getDefaultTitle()) {
    this.title = title
    this._done = false;
    Task.count += 1;
  }
  get done() {
    return this._done === true ? 'Выполнено' : 'Не выполнено';
  }
  set done(value) {
    if (value !== undefined && typeof value === 'boolean') {
      this._done = value;
    } else {
      console.error();
    }
  }
  complete() {
    this.done = true; //Почему done без _ ?
  }

  static getDefaultTitle() {
    return 'Task';
  }
}
let task = new Task('Any');
```

* constructor - особый метод который вызывается в момент создания объекта, он создает свойства и инициализирует его (подготавливает объект к использованию, может быть только один и если его не создать то класс создаст самостоятельно пустой конструктор)
* свойства - характеристики объекта которые создаются в конструкторе
* методы - функции объекта //compleate()
* статические свойства -  Task.count
* статические методы - это методы которые принадлежат самому классу а не объектам созданным на его основе, часто используются для создания вспомогательных функций //getDefaultTitle()
* get set (гетеры и сеттеры) внутри класса ведут себя как методы а снаружи как свойства, позволяют получить доступ и присвоить значения "настоящим свойствам" объекта.
(Названия свойств get и set не должны совпадать с названиями свойств объекта)
set принимает параметр который мы можем присвоить свойству предварительно проверив данный параметр.

Наследование класса

```javascript
class Task {
  constructor(title) {
    this.title = title;
    this.done = false;
  }
  complete() {
    this.done = true;
  }
}
class SubTask extends Task {

}

let task = new Task("Изучить ES5");
console.log(task)

let subtask = new SubTask("Изучить ES6");
console.log(subtask)
```

Если у подкласса нет своего конструктора он воспользуется конструктором родителя.
Метод complete также будет наследован.

```javascript
class Task {
  constructor(title) {
    this.title = title;
    this.done = false;
    console.log("Создание задачи в конструкторе Task")
  }
  complete() {
    this.done = true;
  }
}
class SubTask extends Task {
  constructor(title) {
    super(title)
    console.log("Создание задачи в конструкторе SubTask")
  }
}

let task = new Task("Изучить ES5");
console.log(task)

let subtask = new SubTask("Изучить ES6");
console.log(subtask)
```
Определили подклассу свой конструктор

super - вызывает родительский конструктор.
super - также перезаписывает родительский метод.

#### шаблонные строки
поддерживают многосторонность и имеют тип строки а значит есть возможность применять методы строк. toUpperCase() и так далее.

Пример:
function greet(name) {
    Console.log(`Првет` + `${name}`)
}
greet('Sergey'); //Привет Sergey

#### spread operator
оператор разворота в виде троеточие, позволяет разворачивать элементы массива для передачи в качестве аргумента функции или другого массива.
```javascript
let staticLanguages = ['c', 'c++', 'java'];
let dynamicLanguages = ['js', 'php', 'ruby']
let languages = [...staticLanguages, 'c#', ...dynamicLanguages, 'python']
console.log(languages) // ['c', 'c++', 'java’, 'c#' , 'js', 'php', 'ruby', 'python']
```

#### rest parameters
```javascript
function add(x, y, z) {
  console.log(x + y + z);
}

let number = [1, 2, 3];
add(...number); // 6
```

#### Деструктивное присваивание массивов
```javascript
let languages = ['JavaScript', 'PHP', 'Phyton', 'Ruby'];
let [js, php, phyton, ruby] = languages;
console.log(js) // JavaScript
```
Значения из масива копируются по порядку.

#### Деструктивное присваивание объектов
Название переменных и свойств в данном случае должны совпадать.
```javascript
let person = {
  firstName: 'Sergey',
  lastName: 'Sagalatov'
}

let {firstName, lastName} = person;
console.log(firstName, lastName) // <NAME>
```

Вариант когда названия переменных не совпадают
```javascript
let person = {
  firstName: 'Sergey',
  lastName: 'Sagalatov'
}

let { firstName: first, lastName: last } = person;
console.log(first, last) // <NAME>
```
#### Структуры данных ES2015: Map, Set, Iterable.
**Iterable** - перебираемые объекты (коллекции элементов) для которого может быть использован метод **for of**.
К таким объектам относятся строки, псевдомассивы - объекты, имеющие индексированные свойства и length ( function arguments, выборка DOM elements ).
Технически итерируемые объекты должны иметь метод Symbol.iterator.
Результат вызова obj[Symbol.iterator] называется итератором. Он управляет процессом итерации.
Есть универсальный метод **Array.from**, который принимает итерируемый объект или псевдомассив и делает из него «настоящий» Array. После этого мы уже можем использовать методы массивов.
``` Array.from('some strings') // ["s", "o", "m", "e", " ", "s", "t", "r", "i", "n", "g", "s"] ```
```javascript
function foo(a, b, c) {
  arguments.forEach(item => console.log(item))
}
foo(1, 2, 3) // Uncaught TypeError: arguments.forEach is not a function

function boo(a, b, c) {
  Array.from(arguments).forEach(item => console.log(item))
}
boo(1, 2, 3) // 1, 2, 3
```
[Перебираемые объекты](https://learn.javascript.ru/iterable#array-from).
[Примеры использования Array.from](https://dmitripavlutin.com/javascript-array-from-applications/)

**Map** – это коллекция ключ/значение, как и Object. Но основное отличие в том, что Map позволяет использовать ключи любого типа.
Для перебора коллекции Map есть 3 метода:
map.keys() – возвращает итерируемый объект по ключам,
map.values() – возвращает итерируемый объект по значениям,
map.entries() – возвращает итерируемый объект по парам вида [ключ, значение], этот вариант используется по умолчанию в for..of.
```javascript
const map = new Map()
map.set('one', 'string as key');
map.set(2, 'number as key');
map.set({name: 'Jimmy'}, 'object as key')

console.log( map.get(2)) // number as key

console.log(map)
/*
[[Entries]]
  0: {"one" => "string as key"}
  1: {2 => "number as key"}
  2: {Object => "object as key"}
    key: {name: "Jimmy"}
    value: "object as key"
*/
```
**Set** – это особый вид коллекции: «множество» значений (без ключей), *где каждое значение может появляться только один раз*.
Хорошо подходит для фильтрации повторяющихся элементов массивов.
```javascript
console.log(new Set(['one', 'two', 'one', 'three', 'two', 'four'])); // Set(4) {"one", "two", "three", "four"}
```
Set имеет те-же методы что и Map: keys, values, entries.
Set можно перебирать с помощью: ```for..of``` и ```forEach```.
[Более подробно о Map и Set](https://learn.javascript.ru/map-set).

### как устроена асинхронность в js. Event loop.
```javascript
console.log(’Start’) //1
console.log(’Start2’) //2
setTimeout(function() {
  console.log(‘Inside timeout, after 2000 seconds’)
} //3
console.log(’End’) //4
```
1. Start
2. Start2
3. End
4. Inside timeout, after 2000 seconds
Асинхронность:
Регистрация -> Сторонние API -> Event loop  -> callStack
Event loop: (очередь которая отдает события поочередно)
setTimeout - пришла из браузерного api  метод глобального объекта window.
[Пример Event Loop](latentflip.com/loupe)

### работа с асинхронностью; promise - основные методы, создание промиса из функции с колбэком
```javascript
const p = new Promise(function (resolve, reject) {
  setTimeout(() => {
    console.log('Prepering data..')
    const backendData = {
      server: 'aws',
      port: 2000,
      status: 'working'
    }
    resolve()
  }, 2000)
})
p.then(() => {
  console.log("promise resolve");
})
```
После разрешения промиса у нас есть переменная p которая является промисом.
Так как мы получаем ее из класса Promise, поэтому мы можем использовать у p метод then.
Конструкция p.then - будет выполнена когда промис разрешится.

#### промис из функции с колбэком (колбэк)
```javascript
console.log('Request data..')
setTimeout(() => {
  console.log('Preparing data..')
  const backendData = {
    server: 'aws',
    port: 2000,
    status: 'working'
  }
  setTimeout(() => {
    backendData.modified = true
    console.log('Data received', backendData)
  }, 2000)
}, 2000)
```
Итог большая вложенность

```javascript
const p = new Promise(function (resolve, reject) {
  setTimeout(() => {
    console.log("Preparing data...");
    const backendData = {
      server: "aws",
      port: 2000,
      status: "working"
    };
    resolve(backendData);
  }, 2000);
});

p.then(data => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      data.modified = true
      resolve(data)
    }, 2300)
  })
}).then(clientData => {
  clientData.port = 2020
  console.log(clientData)
  return clientData
})
  .catch(err => console.log('Error', err))
  .finally(() => console.log('Finally'))
  .catch //сработает при вызове rejcet
  .finally //сработает в любом случае

//Sleep - решение для установки таймера
const sleep = ms => {
  return new Promise(resolve => {
    setTimeout(() => resolve(), ms)
  })
}

//Метод All - отработает после выполнения всех промисов
Promise.all([sleep(2000), sleep(5000)]).then(() => {
console.log('All promises')
})

//Метод Race - отработает как только завершиться первый провис (позволяет определить какой первый завершается)
Promise.race([sleep(2000), sleep(5000)]).then(() => {
  console.log('Race promises')
})
```
<file_sep>/ComputerScience.md
## ComputerScience
* [Структуры данных](https://github.com/sagalatov/checklist/blob/master/ComputerScience.md#%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D1%8B-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85)
* [Сложность алгоритмов](https://github.com/sagalatov/checklist/blob/master/ComputerScience.md#%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D1%8C-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D0%BE%D0%B2-on)

### Структуры данных.
1. **Arrays** - массив, простой способ хранения набора элементов в памяти компьютера. Выделяется пространство в памяти для последовательной записи элементов. Все элементы занимают равные объемы памяти. Каждому из них присваивается неотрицательное числовое значение – индекс, который соответствует позиции этого элемента в массиве.
2. **Linked list** - связный список. Позволяет хранить элементы в цепи ячеек, которые не обыязательно должны находиться в последовательных адресах памяти. Каждая ячейка имеет указатель, сообщающий об адресе следующей в цепи.
3. **Stack** - стек это базовая структура данных, которая позволяет добавлять или удалять элементы только в её начале.
Стек организован по принципу LIFO (Last In First Out, «последним пришёл — первым вышел»).
4. **Queue** - Очередь устроена по принципу FIFO (First In First Out, «первый пришёл — первый вышел»). Это значит, что удалить элемент можно только после того, как были убраны все ранее добавленные элементы.
5. **Map** - это структура, которая хранит данные в парах ключ/значение, где каждый ключ уникален. Иногда её также называют ассоциативным массивом или словарём. Map часто используют для быстрого поиска данных.
6. **Hash Table** - это похожая на Map структура, которая содержит пары ключ/значение. Она использует хэш-функцию для вычисления индекса в массиве из блоков данных, чтобы найти желаемое значение.
7. **Binary tree** - ячейки в дереве имеют указатели на другие ячейки, однако, в отличае от связных списков, они распологаются не линейно. Диревья удобны для иерархических структур, таких как каталоги файлов. Все узлы имеют одного радителя. Двоичные деревья поиска позволяют быстро находить, добавлять и удалять элементы. Они устроены так, что время каждой операции пропорционально логарифму общего числа элементов в дереве.
8. **Graph** - аналогичен дереву, с разницей в том, что у него не ни дочерних ни родительских узлов, так что любой узел может иметь произвольное количетво входящих и исходящих ребер.

[Более подробно о структурах данных](https://netology.ru/blog/10-data-structures)

### Сложность алгоритмов O(n).
**O(n)** - функция позволяющая выразить рост временных затрат на выполнение вычислений (алгоритмов). Где n - количество элементов входных данных.
![Big_O](/img/big_O_chart.png)
Например:
1. Выборка из объекта (хэш таблицы): Θ(1)
2. Поиск по массиву: Θ(n)
3. Поиск по бинарному дереву Θ(log(n))
4. Quiksort Θ(n log(n))
5. Bubble Sort Θ(n^2)
6. Бинарный поиск в отсортированном массиве - O(logn).

[Таблица сложностей алгоритмов](https://www.bigocheatsheet.com/)
<file_sep>/README.md
# Чек лист фронтенд разработчика

 1. [OOP](https://github.com/sagalatov/checklist/blob/master/OOP.md)

 2. [Чистый код](https://github.com/sagalatov/checklist/blob/master/PureCode.md)

 3. [JavaScript](https://github.com/sagalatov/checklist/blob/master/JavaScript.md)

 4. [TypeScript](https://github.com/sagalatov/checklist/blob/master/TypeScript.md)

 5. [Верстка](https://github.com/sagalatov/checklist/blob/master/HtmlCss.md)

 6. [JavaScript Фронтэнд](https://github.com/sagalatov/checklist/blob/master/JavaScriptFrontend.md)

 7. [React](https://github.com/sagalatov/checklist/blob/master/React.md)

 8. [Redux](https://github.com/sagalatov/checklist/blob/master/Redax.md)

 9. [Node.js](https://github.com/sagalatov/checklist/blob/master/NodeJS.md)

10. [Web](https://github.com/sagalatov/checklist/blob/master/Web.md)

11. [Console](https://github.com/sagalatov/checklist/blob/master/Console.md)

12. [GIT](https://github.com/sagalatov/checklist/blob/master/GIT.md)

13. [ComputerScience](https://github.com/sagalatov/checklist/blob/master/ComputerScience.md)

14. [Bundling CI CD](https://github.com/sagalatov/checklist/blob/master/Bundling_Ci_CD.md)

15. [Performance web app](https://github.com/sagalatov/checklist/blob/master/Performance.md)

16. [Tasks](https://github.com/sagalatov/checklist/blob/master/Tasks.md)

<file_sep>/Redax.md
## Redax
* store, основные идеи, причины для использования, vожно ли (и считается ли это нормальным) использовать state, если используется Redux?
* action, dispatch
* reducer, почему в reducer'ax надо возвращать новые объекты?
* Библиотека react-redux, Provider, connect
* Библиотеки для уменьшения боллерплейта.
* Альтернативные стейт менеджеры.

#### store, основные идеи, причины для использования, vожно ли (и считается ли это нормальным) использовать

TODO

#### state, если используется Redux?

TODO

#### action, dispatch.

TODO

#### reducer, почему в reducer'ax надо возвращать новые объекты?

TODO

#### Библиотека react-redux, Provider, connect.

TODO

### Библиотеки для уменьшения боллерплейта

1. **typescript-fsa, typescript-fsa-reducers, typescript-fsa-redux-thunk** - фабрики для создания action с поддержкой typescript. Имеют состояние started, done and failed.
[typescript-fsa](https://github.com/aikoven/typescript-fsa)
2. **redux-symbiote** - также позволяет автоматически создавать экшены с тремя состояниями started, finish and failed.
[redux-symbiote](https://github.com/sergeysova/redux-symbiote)
<file_sep>/TypeScript.md
## TypeScript
* Типизация
    * Вывод типов
    * Совместимость типов
    * User-Defined Type Guards
* Классы;
    * Наследование
    * Модификаторы доступа
    * Абстрактные классы
* Enum'ы
* Интерфейсы - использование, отличие от интерфейсов в "классичиских" ЯП
* Генерики (обобщения)
* Декораторы: создание, примеры использования
* async await
* Partial, Pick, Omit.
* The keyof Operator.
* Intersection Types (пересечения)
* Union Types

### Типизация
TypeScript является строго типизированным языком, и каждая переменная и константа в нем имеет определенный тип. При этом в отличие от javascript мы не можем динамически изменить ранее указанный тип переменной.

### Вывод типов
##### Boolean
const isFetching: boolean = true

##### Number
const int: number = 42
const float: number = 4.2
const num: number = 3e10
const message: string = ’TypeScript’

##### Array
```javascript
const numberArray: number[ ] = [1,2,3,4,5]
const numberArray<number> = [1,2,3,4,5]
```
В скобках указывается тип

##### String
const words: string[ ] = [‘Hello’, ‘World’]

##### Tuple
const contact: [string, number] = [’Sergey’, 7519747]

##### Any
let variable: any = 42;

Явное указание возвращаемого типа данных.

**void** - функция ничего не вернет.
```javascript
function sayMyName(name: string):void{
console.log(name)
}
```
**never** - когда функция возвращает ошибку
```javascript
function throwError(message: string):never {
    throw new Error(message)
}
```
**Именованные типы**
type Login = string
const login: Login = ‘admin'
type ID = string | number
const id1: ID = 1234
const id2: ID = '1234'
const id3: ID = true // Так сделать не получиться.

type SomeType = string | null | undefined

### Совместимость типов
В TypeScript совместимость типов основана на структурной совместимости.
```javascript
interface Monster {
    health : number;
}

class Daemon {
    health : number;
    name : String;
}

class Goblin {
    health : number;
}

class Ghaul {
   flying : boolean;
}

let v1:Monster = new Daemon(); // OK

let v2:Monster = new Goblin();  // OK

let v3:Monster = new Ghaul(); // Ошибка, так как в Ghaul нет поля health;
```
В Daemon есть дополнительный атрибут name, но это нам не мешает присвоить его переменной типа Monster, так как в Daemon есть все поля из Monster. Но мы не можем присвоить переменной типа Monster экземпляр Ghaul, так как в нём нет атрибута health.
```javascript
let x = function(arg0:number):void {
    alert(arg0);
}

let y = function(arg0:number, arg1 : string):void {
    alert(arg1);
}

y = x;
x = y;  // Ошибка, так как в x количество аргументов меньше.
```
При сравнении двух функций тоже действует совместимость типов. Мы можем присвоить переменной с типом функции, в которой больше элементов, ссылку на функции с меньшим числом элементов, так как в JavaScript последние параметры функции могут опускаться.

### User-Defined Type Guards
Guards - Некоторые вспомогательные конструкции которые позволяют удобно работать с типами
type AlertType = 'success' | 'danger' | ‘warning’    //Type Guards

function setAlertType(type: AlertType) {
  //....
}

setAlertType(type: 'success')

setAlertType(type: 'warning')

setAlertType(type: 'default') // is not assingnable to parameter of type 'Alert Type'

### Классы
 Создаются также как es6 но с некоторыми отличиями
class Typescript {
  varsion: string  //Поля

  constructor(varsion: string) {
    this.version = version
  }

  info(name: string) {
    return `[${name}]: Typescript version is ${this.version}`
  }
}
Все тоже самое только добавили типы.

***

```javascript
class Сar {
  readonly moodel: string
  readonly numberOfWheels: number = 4  // Хорошоей практикой считается определять поля до конструктора

  constructor(theModel: string) {
    this.model = theModel // model можно перезаписать только внутри конструктора
  }
}
```

Короткая запись
```javascriptjavascript
class Сar {
readonly numberOfWheels: number = 4
constructor(readonly model: string) {

  }
}
```
Поскольку мы указываем модификатор внутри конструкторта в таком случае typescript создаст readonly поля model в классе и в контсрукторе определит его на входящее параметр model.

### Наследование
Наследование интерфейсов
```javascript
Interface RectWithArea extends Rect {
getArea: () => number
}

const rect5: RectWithArea = {
id: ‘123’,
size: {
    width: 10,
    height: 5
    },
    getArea(): number {
return this.size.width + this.size.height
}
}

//Класс наследует интерфейс

Interface IClock {
    time: Date
    setTime(date: Date): void
}
class Clock implements Clock {
    time: Date = new Date()
    setTime(date: Date): void {
    this.time = date
    }
}
```

### Модификаторы доступа
Одной из ключевых концепций объектно-ориентированного программирования является инкапсуляция, подразумевающая сокрытие от внешнего доступа к состоянию объекта
и управление доступом к этому состоянию.
В TypeScript три модификатора: public, protected и private
Если к свойствам и функциям классов не применяется модификатор, то такие свойства и функции расцениваются как будто они определены с модификатором public
Если же к свойствам и методам применяется модификатор private, то к ним нельзя будет обратиться извне при создании объекта данного класса.
Модификатор protected во многом аналогичен private - свойства и методы с данным модификатором не видны из вне, но к ним можно обратиться из классов-наследников:

```javascript
class User {
    private name: string;
    protected age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    public displayInfo(): void {
        console.log("name: " + this.name + "; age: " + this.age);
    }
}

class Employee extends User {
    private company: string;
    constructor(name: string, age: number, company: string) {
        super(name, age);
        this.company = company;
    }
    public showData(): void {
        console.log("Age: " + this.age);
        //console.log("Name: " + this.name); // не работает, так как name - private
    }
}
```

Используя модификаторы в параметрах конструктора, нам больше не надо явно создать свойства для этих параметров. Свойства создаются автоматически, называются они по имени параметров и имеют те же модификаторы, что и параметры
class User {
    constructor(private name: string, private age: number) {
    }
    public displayInfo(): void {
        console.log("name: " + this.name + "; age: " + this.age);
    }
}

### Абстрактные классы
Не во что не компелируются, нужны на этапе разработки чтоб бы от них наследоваться

```javascript
abstract class Component {
  abstract render():void
  abstract info():string
}

class AppComponent extends Component {
  render():void {
    console.log("Component on render")
  }
  info():void {
    console.log("This is info)
  }
}
```

При компиляции в es5 Будет преобразование в функции, при компиляции в es6 абстрактных классов мы не увидим.

### Enum'ы

Вспомогательная сущность которая позволяет лучше структурировать код если присутствуют однотипные элементы.

```javascript
enum Membership {
    Simple,
    Standart,
    Premium
}
```
const membership = Membership.Standart //1
//По умолчанию присваиваются индексы
const membershipReverse = Membership[2] // Premium
//Логика отличается от массива

Если мы присваиваем енуму строчку то на выходе мы ее и получаем.

```javascript
enum SocialMedia {
VK = ‘VK'
FACEBOOK = ‘FACEBOOK’,
INSTAGRAM = ‘INSTAGRAM'
}
const social = SocialMedia.VK
console.log(social) // VK
```

### Интерфейсы - использование, отличие от интерфейсов в "классичиских" ЯП
```javascript
interface Rect {
readonly id: string
color?: string
    size: {
    width: 20,
    height: 30
    },
color: ‘#ccc'
}

const rect1: Rect = {
id: ‘1234’,
    size: {
    width: 10,
    height: 5
    }
}

rect1.color = ‘black’
```
Так как мы в конечном счете работаем с JS мы можем менять внутреннее состояние объектов или массива но только внутреннее. Записать новое значение в переменную мы не можем.
Возможно указывать к какому типу относиться объект
```javascript
const rect3 = {} as Rect
const rect4 = <Rect> {} //Альтернативная старая запись.
```
Ситуация кода нужно создать интерфейс для объекта у которого будет много динамических ключей

```javascript
Interface Styles {
    [key: string]: string
}
const css = {
    border: ‘1px solid red’,
    marginTop: ‘2px’,
    bordRadius: ‘5px’
}
```
Для того что бы не прописывать все типы свойств в интерфейсе.
[key: string] относиться к свойству.
string к значению.

### Generics (обобщения)
Обобщения (англ. generics) или дженерики - это инструмент, который позволяет писать на TypeScript компоненты, способные работать с различными типами данных.
```javascript
const arrayOfNumbers: Array<number> = [1,2,3,4,5]
const arrayOfStrings: Array<string> = [‘Hello’, ’Sergey’]
```
<> - из чего будет состоять

```javascript
function reverse<T>(array: T[]):T[] {
  return array.reverse() //Как пример простой реализации
}
```

Для того что бы одна функция работала с разными типами данных c указанием типов мы используем дженерик типа Т, дженерик тип который будет **динамически подстраиваться** под тот контент который есть в массиве. Дженерики позволяют делать код более гибким и переиспользуемым, но при этом повышают сложность чтения.

### Декораторы: создание, примеры использования.
Функция декоратор принимает один параметр: это контсруктор класса к которому данный дкоратор будет применяться
function logger(contstrFn: Function) {
  constructorFN.prototype.log = function(){ //Расширили через prototype
    console.log(this);
  }
}

@logger //Перед классом нужно указать данную конструкцию для закрепления декоратора
class User {
  constructor(public name: string, public age: number) {
  }
}

let user = nes User("Sergey", "27");
(<any>user).log(); //Выведет в консоль обьект.
В итоге все инстансы класса получать методы которые были определены в функции декораторе.

### async await
```javascript
const delay = ms => {
  return new Promise(r => setTimeout(() => r(), ms))
}
const url = 'https://jsonplaceholder.typicode.com/todos';
//delay(2000).then(() => console.log('2 sec'))
//Вариант на промисах

function fetchTodos() {
  console.log('Fetch todo startes...')
  return delay(2000)
  .then(() => fetch(url))
  .then(response => response.json())
}
fetchTodos()
.then(data => {
  console.log('Data:', data)
})
.catch(e => console.error(e));
```

Вариант с "async await"

Если внутри функции мы используем await то ферхнеуровненвая функция должна быть асинхронной

```javascript
async function fetchAsyncTodos() {
  console.log('Fetch todo startes...')
  try { //try catch для обработки ошибок
    await delay(2000) //Пока не будет зарезолвиза промис задержки интерпритатор не перейдет на следующую строчку. (Возможность await)
    const responce = await fetch(url) //Fetch также возвращает responce поэтому нужно присвоить в переменную
    const data = await responce.json()
    console.log('Data:', data)
  } catch (e) {
    console.error(e)
  } finally {
    // Таже есть возможность выполнить блок finally
  }
}
fetchAsyncTodos()
fetchAsyncTodos().then() // Возможно

```
### `Partial<Type>`
   Делает все свойства типа в *Type* необязательными.

### `Pick<Type, Keys>`
   Создает тип используя переданные ключи из *Type*
   `type TodoPreview = Pick<Todo, "title" | "completed">;`

### `Omit<Type, Keys>`
   Создает тип исключая переданные ключи.
   `type TodoPreview = Omit<Todo, "description">`

### The keyof Operator
Предоставляет более удобную запись чем *union type* для ожидаемого значнния, имя
которого будет равно одному из ключей указанному после keyof.
   ```typescript
  interface Todo {
     id: number;
     text: string;
     due: Date;
}

type TodoKeys = keyof Todo; // "id" | "text" | "due"
   ```
### Intersection Types
Перечесения позволяют объединить несколько типов в один, полученный тип должен удовлетворять
условиям всех включенных в *intersection* типов. Во включенных типах не должно быть свойств с одинаковыми именами
и разными типами, это вызовет ошибку `Type 'number' is not assignable to type 'never'.`
```typescript
interface Animal {
  kind: string;
}
interface Person {
  firstName: string;
  lastName: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let employee: Animal & Person & Employee = {
  kind: 'human',
  firstName: 'Jane',
  lastName: 'Smith',
  age: 20,
  employeeCode: '123'
}
```
### Union Types
Объединенные типы могут включать все или некоторые свойства перечисленных типов. Однако доступ в объекте
реализующем объединенный тип можно получить только к свойствам перечисленным во всех включенных типах. Если свойства имеют одинаковые имены,
но разные типы, результирующий тип будет вида `number | string`
```typescript
interface Animal {
  kind: string;
}
interface Person {
  kind: string;
  firstName: string;
  lastName: string;
  age: number;
}
interface Employee {
  kind: string;
  employeeCode: string;
}
let employee: Animal | Person | Employee = {
  kind: 'human',
  firstName: 'Jane',
  lastName: 'Smith',
  age: 20,
  employeeCode: '123'
}
console.log(employee.kind)
```
<file_sep>/Performance.md
## Оптимизация производительности веб приложений
* Оптимизация Изображений
* Оптимизация Шрифтов
* Lazy Load и Code-Splitting
* Кэширование
* Минификация
* Оптимизации js
* React performance

***

### Оптимизация Изображений
* Сжимать изображения. С помощью сервисов, например [tinypng](https://tinypng.com/)
* Выбирать подходящие форматы изображений jpg, png, WebP.
* Использовать превью изображений, например для карточек.
* Использовать разные размеры изображений для различных устройств. Атребуты srcset and sizes:
```html
<img srcset="elva-fairy-320w.jpg 320w,
             elva-fairy-480w.jpg 480w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 320px) 280px,
            (max-width: 480px) 440px,
            800px"
     src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
```
или использовать элемент picture.
* Использовать векторную графику SVG там где это возможно.
* Использовать lazy loading. Библиотеки или атребут loading:
`<img align="center" src="unicorn.jpg" loading="lazy" alt=".."/>`
Поддержка loading пока не велика, но для прогрессивного улучшения подходит.
***

### Оптимизация Шрифтов
* Использовать оптимальные форматы шрифтов. Например **WOFF2**.
Преимущество использования WOFF2 заключается в пользовательских алгоритмах предварительной обработки и сжатия,
что приводит к 30% уменьшению размера шрифта.
* Удаление лишних начертания, например extra-supra-bold-italic-800.
* Можно удалить неиспользуемые символы из шрифтов.
* Использовать **Font-display** (выбор алгоритма загрузки шрифтов).
  * **auto** Стратегию загрузки шрифта определяет пользовательский агент.
  * **block** Для шрифта задается короткий период блокировки и бесконечный период подмены.
  * **swap** Для шрифта не задается период блокировки и задается бесконечный период подмены.
  * **fallback** Для шрифта задается очень короткий период блокировки и короткий период подмены.
  * **optional** Для шрифта задается очень короткий период блокировки и не задается период подмены.

### Оптимизация JS
* Lazy Load и Code-Splitting с помощью webpack, а также с помощью динамических импортов и React.lazy.
  Таким образом доставка только нужного кода пользователю и рабиение бандла.
* Удалние лишних зависимостей. Для оценки размеров рависимостей - webpack-bundle-analyzer.
  Импорт только нужных частей библиотек.
* Минификация - по дефолту webpack минифицирует бандл, но это поведение можно сконфигурировать.
* Уменьшение количетва запросов и кэширование. Варианты - graphQL, reactQuery, WS, HTTP-2.

### Оптимизация React
* Использование прод. режима в webpack. Который также включает минификацию.
* Использование расширения для браузера React profiler.
* Постепенная загрузка длинных списков. (react-window and react-virtualized are popular windowing libraries).
* Для **Class components**:
   * Избежание перерендера с помощью **shouldComponentUpdate**
   * Избежание перерендера с помощью наследования от **React.PureComponent**.
   Который релизует логику shouldComponentUpdate автоматически c shallow comparison of props and state.
* Для **Function components**:
  * React.memo - позволяет пропустить рендер елси props не изменилтись. Осуществляет shallow comparison.
  Также в hoc можно передать функцию для сравнения prevProps, nextProps.
  ```javaScript
  const MyComponent = React.memo(
    function MyComponent(props) {
      /* render using props */
    },
    function areEqual(prevProps, nextProps): boolean {}
  );
  ```
  * **useMemo** - позволяет избежать пресчета больших вычислений и возвращет мемоизованное значение
  в случае, если зависимости не изменились.
  ```javaScript
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  ```
  * **useCallback** - действует похожим образом но возвращает мемоизованную функцию.
  ```javaScript
    const memoizedCallback = useCallback(
      () => {
        doSomething(a, b);
      },
      [a, b],
   );
  ```
  Официальный блог React о [performance](https://reactjs.org/docs/optimizing-performance.html).
<file_sep>/Web.md

## Web
* сессии
* cors
* csrf
* headers (cache, useragent, location)
* cookie
* get, post, option; body, query; http status
* REST - принципы наименование методов, принцип stateless
* Используемые коды ошибок

### сессии
Это некоторый отрезок во времени, в пределах которого веб-приложение может определять все запросы от одного клиента.
(Когда клиент в первые передает свои данные в запросе, на сервере создается новая сессия для этого клиента и в пределах
и в период времени жизни сессии  все запросы от этого клиента будут однозначно идентифицированы только с ним, по истечению времени запрос связь будет потеряна и новый запрос будет обрабатываться как совершенно новый и не связанный с клиентом)

### cors
CORS — это механизм безопасности, который позволяет веб-странице из одного домена обращаться к ресурсу с другим доменом (кросс-доменным запросом). Без таких функций, как CORS, веб-сайты ограничиваются доступом к ресурсам одного
и того же происхождения через так называемую политику единого происхождения.
Спецификация CORS определяет набор заголовков, которые позволяют серверу и браузеру определять, какие запросы для междоменных ресурсов (изображения, таблицы стилей, сценарии, данные и т. д.) разрешены, а какие нет. CORS является техникой для ослабления правила одного источника, позволяя JavaScript на web странице обрабатывать REST API запросы от другого источника.

### csrf
CSRF-атака – это когда «злая страница» отправляет форму или запрос на сайт, где посетитель, предположительно, залогинен.
Если сайт проверяет только куки, то он такую форму принимает. А делать это не следует, так как её сгенерировал злой хакер.
Для защиты от атаки формы, которые генерирует mail.com, подписываются специальным токеном. Можно не все формы,
а только те, которые осуществляют действия от имени посетителя, то есть могут служить объектом атаки.

### headers (cache, useragent, location )

* headers : HTTP заголовки сопровождают обмен данными по протоколу HTTP. Они могут содержать описание данных и информацию необходимую для взаимодействия между клиентом и сервером. Заголовки и их статусы перечислены в реестре IANA, который постоянно обновляется.

* cashe:  Кеширование - этот метод, заключающийся в сохранении копии полученного ресурса, чтобы вернуть ее по запросу. Запрос на ресурс, уже имеющийся в веб-кеше, перехватывается, и вместо обращения к исходному серверу выполняется загрузка копии
из кеша. Таким образом снижается нагрузка на сервер, которому не приходится самому обслуживать всех клиентов, и повышается производительность - кеш ближе к клиенту, и ресурс передается быстрее. Кеширование является  основным источником повышения производительности веб-сайтов. Однако, кеш надо правильно сконфигурировать: ресурсы редко остаются неизменными, так что копию требуется хранить только до того момента, как ресурс изменился, но не дольше.
Существует несколько видов кешей, которые можно разделить на две основные категории: приватные кеши и кеши совместного использования. В кешах совместного использования (shared cache) хранятся копии, которые могут направляться разным пользователями. Приватный кеш (private cache) предназначен для отдельного пользователя
useragent: User-Agent — это текстовая часть запроса, которую веб-приложения используют для сообщения сайту информации о себе. User-Agent браузера содержит название и версию приложения, а также данные об операционной системе компьютера: версия, разрядность, язык по умолчанию и другие параметры.

* locationc: HTTP-заголовок Location возвращается в ответах HTTP-сервера в двух случаях:
Чтобы попросить браузер загрузить другую web-страницу (Перенаправление URL). В этом случае заголовок Location должен быть отправлен вместе с кодом состояния 3xx
Для предоставления информации о новом местоположении ресурса. Код состояния должен быть 201 или 202

### 5. cookie
HTTP cookie (web cookie, cookie браузера) - это небольшой фрагмент данных, отправляемый сервером на браузер пользователя, который тот может сохранить и отсылать обратно с новым запросом к данному серверу. Это, в частности, позволяет узнать,
с одного ли браузера пришли оба запроса (например, для аутентификации пользователя). Они запоминают информацию о состоянии
для протокола HTTP, который сам по себе этого делать не умеет.

Cookie используются, главным образом, для:
* Управления сеансом (логины, корзины для виртуальных покупок)
* Персонализации (пользовательские предпочтения)
* Мониторинга (отслеживания поведения пользователя)

До недавнего времени cookie принято было использовать в качестве хранилища информации на стороне пользователя. Это могло
иметь смысл в отсутствии вариантов, но теперь, когда в распоряжении браузеров появились различные API (программные интерфейсы приложения) для хранения данных, это уже не так. Из-за того, что cookie пересылаются с каждым запросом, они могут слишком сильно снижать производительность (особенно в мобильных устройствах). В качестве хранилищ данных на стороне пользователя вместо них можно использовать Web storage API (localStorage and sessionStorage) и IndexedDB.

### 6. get, post, option; body, query; http status

* get: метод GET запрашивает представление ресурса. Запросы с использованием этого метода могут только извлекать данные.

* post: в программировании POST — один из многих методов запроса, поддерживаемых HTTP протоколом, используемым во Всемирной паутине. Метод запроса POST предназначен для запроса, при котором веб-сервер принимает данные, заключённые в тело сообщения,
для хранения. Он часто используется для загрузки файла или представления заполненной веб-формы.

* option: HTTP-метод OPTIONS используется для описания параметров соединения с целевым ресурсом. Клиент может указать особый URL для обработки метода OPTIONS, или * (зведочку) чтобы указать весь сервер целиком.

* body

    Тело запроса. Оно бывает не у всех запросов: запросы, собирающие (fetching) ресурсы, такие как GET, HEAD, DELETE,
    или OPTIONS, в нем обычно не нуждаются. Но некоторые запросы отправляют на сервер данные для обновления, как это часто         бывает с запросами POST (содержащими данные HTML-форм)
    Тела можно грубо разделить на две категории:
    Одноресурсные тела (Single-resource bodies), состоящие из одного отдельного файла, определяемого двумя заголовками:           Content-Type и Content-Length.
    Многоресурсные тела (Multiple-resource bodies), состоящие из множества частей, каждая из которых содержит свой бит             информации. Они обычно связаны с HTML-формами.

    Тело ответа. Оно есть не у всех ответов: у ответов с кодом состояния, например, 201 или 204, оно обычно отсутствует.
    Тела можно разделить на три категории:
    Одноресурсные тела (Single-resource bodies), состоящие из отдельного файла известной длины, определяемые двумя                 заголовками: Content-Type и Content-Length.
    Одноресурсные тела (Single-resource bodies), состоящие из отдельного файла неизвестной длины, разбитого на небольшие части     (chunks) с заголовком Transfer-Encoding, значением которого  является chunked.
    Многоресурсные тела (Multiple-resource bodies), состоящие из многокомпонентного тела, каждая часть которого содержит свой     сегмент информации. Они относительно редки.

* query: cтрока запроса - часть унифицированного указателя ресурса
Пример: <http://example.com/over/there?name=ferret&сOlof=purpule>
? - разделитель
& - разделитель множественных запросов

    Ссылка по теме: ru.qwe.wiki/wiki/query_string

* http: HTTP (англ. HyperText Transfer Protocol — «протокол передачи гипертекста») — протокол прикладного уровня передачи данных изначально — в виде гипертекстовых документов в формате «HTML», в настоящий момент используется для передачи произвольных данных. Основой HTTP является технология «клиент-сервер», то есть предполагается существование:
Потребителей (клиентов), которые инициируют соединение и посылают запрос;
Поставщиков (серверов), которые ожидают соединения для получения запроса, производят необходимые действия и возвращают обратно сообщение с результатом.

* status: Код состояния HTTP (англ. HTTP status code) — часть первой строки ответа сервера при запросах по протоколу HTTP.
Он представляет собой целое число из трёх десятичных цифр. Первая цифра указывает на класс состояния. За кодом ответаобычно следует отделённая пробелом поясняющая фраза на английском языке, которая разъясняет человеку причину именно такого ответа
<https://yandex.ru/support/webmaster/error-dictionary/http-codes.html>

### 7. REST - принципы наименование методов, принцип stateless
REST (Representational state transfer) – это стиль архитектуры программного обеспечения для распределенных систем, таких
как World Wide Web, который, как правило, используется для построения веб-служб. Термин REST был введен в 2000 году
Роем Филдингом, одним из авторов HTTP-протокола. Системы, поддерживающие REST, называются RESTful-системами.

* Принципы наименования: www.restapitutorial.ru/lessons/restfulresourcenaming.html

* Принцип stateless
Состояние хранится на клиенте

Ссылка: <TODO>

### 8. Используемые коды ошибок

TODO

***<file_sep>/GIT.md
## GIT
* Как добавить файлы в коммит?
* Как добавить чанки?
* Почему нельзя добавлять файлы по звезде или точке?
* Пуш. Что такое фастфовард? Чем опасен пуш с форсом?
* Ветвление.
    * Как создать и удалить ветку, локально и в origin`е.
    * Как привязать локальную ветку "a1" к удаленной ветке "b2", и пушить в нее?
    * Как получить список комитов из локальной ветки, которую вы только что удалили?
    * Сколько веток может указывать на один коммит?
* Что такое мердж?
    * Как его откатить?
    * Какие бывают стратегия мерджа?
    * Что такое ребейз?
    * Зачем нужен пулл по ребейзу?
    * Что такое черрипик?
* Как перименовать коммит?
* Как удалить последний коммит?
* Как удалить коммит из середины и запушить его? Вкаких случаях так можно делать, а в каких нет?
* Как пользоваться reflog?
* bisect
* Что такое хуки?

### Как добавить файлы в коммит?

```
git add file
git commit -m “massage”
```

### Как добавить чанки?
TODO

### Почему нельзя добавлять файлы по звезде или точке?
TODO

### Пуш. Что такое фастфовард?
[Ссылка на статью](habr.com/ru/post/195674)

### Чем опасен пуш с форсом?
```
push -f
```
Риск затоптать локальной версией выше расположенную ветку и все изменения которые к тому моменту не подтянули будут стёрты из истории.

### Ветвление. Как создать и удалить ветку, локально и в origin`е.
Создать ветку
```
git branch mybranch или
git checkout -b mybranch
```
Удалить локально
```
git branch -d mybranch
```
Удалить в origin
```
git push origin -d mybranch
```

### Как привязать локальную ветку  "a1" к  удаленной ветке "b2", и пушить в нее?
```
git branch —set-upstream-to=origin/b2 b1
```
### Как получить список комитов из локальной ветки, которую вы только что удалили?

TODO

### Сколько веток может  указывать на один коммит

TODO

### Что такое мердж? Как его откатить? Какие бывают стратегия мерджа? Что такое ребейз? Зачем нужен пулл по ребейзу? Что такое черрипик?

![rebase](/img/rebase.PNG)
git rebase devel - собачка на молнии - "сшивает" коммиты по дате их создания
(ветка devel "растворяется" в основной ветке)

![merge](/img/merge.PNG	)
git merge devel - пожарная лестница, все коммиты ветки devel крепятся в конец, образуется пересечение
(devel остается отдельной веткой, к которой можно вернуться)

#### откатить merge
откатить ветку master до коммита перед слиянием: git reset --hard commit-name
т.к. на гитхабе теперь есть коммиты, которых в вашей ветке нет, поэтому не получится автоматический fast-forward merge. Поможет git push -f. Эта команда заменяет содержимое удаленной ветки.

![cherry-pick](/img/cherry-pick.PNG)
git chery-pick idea - забрать коммиты из ветки idea

### стратегии merge

TODO

###  пулл по ребейзу

TODO

### Как переименовать коммит? Как удалить последний? Как удалить коммит из середины и запушить его? В каких случаях так можно делать, а в каких нет?

#### переименовать коммит
Чтобы изменить имя последнего коммита:
```
git commit --amend -m "Новое название"
```
Для изменения имени других коммитов:
```
git commit --amend -c <commit ID>
```
После этого придётся явным образом переписать ветку master на удаленном репозитории (на GitHub). Поскольку история коммитов разошлась, GitHub не примет изменения просто так, нужно добавить ключ --force:
```
git push --force origin <имя ветки на удаленном репозитории>
```
Осторожно: в общем случае команда push --force опасна, так как переписывает состояние ветки на удаленном репозитории и может привести к потерям.

####  удалить последний коммит
Отменить последний коммит, но сохранить изменения:
```
git reset HEAD~
```
Удалить последний коммит и откатить изменения:
```
git reset —hard HEAD~
```
Команда git reset откатывает HEAD до определенного состояния.
В нашем случае она откатывает HEAD до HEAD~ (сокращенно от HEAD~1), что означает состояние на один коммит старше чем HEAD

#### удалить коммит из середины и запушить его.
```
git rebase -i HEAD~6
```
Вместо HEAD~6 (шесть коммитов назад), можете взять хеш любого коммита перед коммитом откроется вим или другой редактор. Там будет список коммитов. Теперь удаляем ненужные коммиты (просто удаляем строки). Если это вим, тогда просто нажимаем дважды d на нужных строках (то есть тех, которых нужно удалить) и выходим с редактора.
После этого git откатит эти коммиты и накатит их по новому.
Вполне возможно, что нужно будет по ходу дела решать конфликты.
Помните, что на самом деле старые коммиты никуда не уйдут, просто будут созданы новые коммиты. Если эти коммиты уже были запушены на удаленный сервер, то лучше не делать подобного. Но если над проектом работаете только Вы, то нет ничего страшного. Но пуш придется делать форсированным (-f).
* Можно если работа ведётся локально
* Нельзя если данные коммиты запущены и загружены другими разработчиками.
(так как при перезаписи создаются новые коммиты, у коллег будут дубликаты)

### Как пользоваться reflog?
Возврат в фиксированную точку во времени (отменив все действия от текущего момента)
```
git reflog
```
Смотрим последние изменения.
```
git reflog -n 10
```
Смотрим последние 10 изменений
```
git reset —hard HEAD@{5}
```
(Для windows могут понадобиться кавычки)
```
git reset — "hard HEAD@{5}"
```
Флаг —hard
Означает, что добавленные изменения будут удалены
(если откатываемые изменения содержат добавленный файл, то данный файл будет удалён)
Флаг —soft
Означает, что после отката коммита файл останется как не зафиксированные изменения.

### bisect
Возможность бинарного поиска по коммитам
1. Запуск механизма и установка состояния проекта "нерабочее"
```
git bisect start
git bisect bad
```
2. Откатываемся на рабочее состояние проекта как пример на 10 коммитов назад по истории
```
git bisect good HEAD~10
```
3. Смотрим проявиться ли баг в текущем состоянии. Допустим, сейчас с проектом все хорошо. Поэтому продолжаем поиск дальше
```
git bisect good
```
(перемотка состояния в середину, между хорошим и плохим коммитом. Сейчас мы находимся в 5 коммитах назад по истории, с каждой такой итерацией расстояние уменьшиться в два раза)
4. После завершения поиска сбрасываем репозиторий в исходное состояние.
```
git bisect reset
```

### Что такое хуки?
Git Hooks - скрипты оболочки, которые запускаются автоматически до или после того, как Git выполнит важную команду, такую как commit или push
Hooks (хуки) хранятся в папке .git/hooks (данная папка создаётся при инициализации репозитория, что бы посмотреть скрытые папки используем ls -la )
[Примеры использования](https://www.hostinger.ru/rukovodstva/kak-ispolzovat-git-hooks/)
<file_sep>/Bundling_Ci_CD.md
# Сборка CI CD
* webpack
* отличия webpack loader / plugin
* babel
***

**webpack** - bundler (сборщик модулей). С помощью плагинов умеет:
* Собирать в один файл js (при необходимости минифицировать, кастовать uglify)
* транспилировать JavaScript следующего поколения до более старого стандарта JavaScript (ES5) с помощью Babel
* может конвертировать встроенные изображения в data:URI, а также импортировать изображения.
* позволяет использовать *require()* для CSS файлов
* webpack-dev-server (в нём встроен локальный сервер и livereload (“живая перезагрузка браузера”))
* может работать с Hot Module Replacement (замена модулей в рантайм)
* разделить бандл на чанки
* Tree Shaking

**Loader** - принимает содержимое файла, преобразовывают и включают результат в общую сборку.
* стили `css-loader, sass-loader, postcss-loader`
* js, ts - `babel-loader, ts-loader`
* файлы - `url-loader, file-loader`
* svg - `svgo-loader`

**Plugins** - функции встраивающиеся в pipline и преобразовывают код. Наиболее популярные:
* HtmlWebpackPlugin - создает html и подключает скрипты
* HotModuleReplacementPlugin - частичная замена модулей при изменении кода в рантайме
* DefinePlugin - добавляет гобальные переменные webpack
* ExtractTextWebpackPlugin извлекает текст (css) в отдельный файл
* bundleAnalyzer - создает отчет по составу бандла с весом модулей
* NoEmitOnErrorsPlugin - пропускает ошибки на этапе компиляции
* CopyWebpackPlugin - копирует файлы в сборочную директорию (например статику)

**Babel** - преобразователь кода из ECMAScript 2015+ в более ранние версии для поддержки браузером. Преобразовывает синтакс, применяет полифилы, транспилирует jsx. Пример конфига:
```json
{
  "plugins": [
    "babel-plugin-styled-components",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-transform-runtime"
  ],
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}
```
<file_sep>/NodeJS.md
## Node.js
* Gulp - самые основные моменты
* Основные утилы ноды (fs, path etc)
* Express - как использовать app.use, отдача статики по разным путям, middleware (подключаемые и свои)
* Пакетные менеджеры npm, yarn - установка, удаление, обновление пакетов. Файл package.json.

### Gulp - самые основные моменты

TODO

### Основные утилы ноды (fs, path etc)

TODO

### Express - как использовать app.use, отдача статики по разным путям, middleware (подключаемые и свои)

TODO

### Пакетные менеджеры npm, yarn - установка, удаление, обновление пакетов. Файл package.json.

#### npm
node package manager) — это стандартный менеджер пакетов, автоматически устанавливающийся вместе с Node. js. Он используется для скачивания пакетов из облачного сервера npm, либо для загрузки пакетов на эти сервера.
Установка пакета:

```
npm install package_name
```
позволяет установить любой пакет по его имени. Если при этом к команде добавить префикс -gпакет будет установлен глобально на весь компьютер.
Удаление пакета:

```
npm uninstall package_name
```

удаляет установленный пакет по имени
Обновление пакета:

```
npm update package_name
```

Сама по себе такая комада редка нужна. Чаще нужно обновить npm пакеты проекта за записью новых версий в package.json, для этого в корневой директории проекта выполните команду

```
npm update —save
```

Как всегда, есть нюанс. Update обновляет пакеты в соответствии с записями из package.json, поэтому надо учитавать знаки больше/меньше, тильды, крышки и равно. Если пакет задан как = 1.0.67, то npm update его не обновит.
Если нужно поставить версии пакетов, отличные от записей в package.json, то следует воспользоваться командой
```
npm install
```

#### yarn
Yarn это новый менеджер пакетов, совместно созданный Facebook, Google, Exponent и Tilde. Как можно прочитать в официальной документации, его целью является решение целого ряда проблем, с которыми столкнулись разработчики при использовании npm, а именно:
* установка пакетов не была достаточно быстрой и последовательной;
* существовали проблемы с безопасностью, так как npm позволяет пакетам запускать код при установке.
Установка пакета:

```
yarn add [package]
```

установит пакет и запишет его в зависимости Dependencies

```
yarn add [package]@[version]
```
установит пакет определенной версии

```
yarn add [package]@[tag]
```
установит пакет определенной версии
Удаление пакета:

```
yarn remove [package]
```

Обновление пакета:
```
yarn upgrade [package]
yarn upgrade [package]@[version]
yarn upgrade [package]@[tag]
```

#### package.json
содержит различные мета-данные, например, имя проекта, версия, описания и автор. Также он содержит список зависимостей, которые будут установлены, если вызвать из этой папки команду npm install.
Кроме этого он ещё имеет скрипты, которые вызывают другие команды консоли.
Во время работы часто возникает необходимость установить некоторые пакеты. Если установить пакет с префиксом --save, то он автоматически запишется в package.json в раздел dependencies. Такая же команда с префиксом --save-dev запишет пакет в раздел devDependencies.
<file_sep>/React.md
## React
* Компоненты, свойства: Props, State
* Метод setState
* Особенности синтаксиса JSX
* Что такое keys в React и чем их важность?
* Презентационные компоненты и компоненты контейнеры
* Что такое refs?
* React router, компонент withRouter
* Компоненты высшего порядка
* Однонаправленный поток данных, работа с событиями в React
* Жизненный цикл компонента, в каких методах жизненного цикла стоит выполнять ajax запросы? В каких стоит "обновлять state на основе props" ?
Оптимизации производительности.
* Hooks
* articles

#### Компоненты, свойства: Props, State.

* props (намеренно сокращённо от англ. «properties» — свойства), передаются в компонент (служат как параметры функции).

```javascript

//title, created, author, post_hint в данном случае наши пропсы которые в дальнейшем пробрасываються в компонент Title

export function TextContent({title, created, author, post_hint}: ITextContentInterface) {
    return (
        <div className={styles.textContent}>
            <div className={styles.metaData}>
                <div className={styles.userLink}>
                    <a href="#user-url" className={styles.username}>{author}</a>
                </div>
                <span className={styles.createdAt}>
                         <span className={styles.publishedLabel}>опубликовано</span>
                    {moment(created).format("DD-MM-YYYY h:mm:ss")}</span>
            </div>
            <Title title={title} post_hint={post_hint}/>
        </div>
    );
}

export function Title({title, post_hint}: ITitleInterface) {
    return (
        <h2 className={styles.title}>
           <span className={styles.postLink}>{title}</span>
                <Link to="/posts/1" className={styles.postLink}>
                    {title}
                </Link>
            }
        </h2>
    );
}
```

* state — это обычные JavaScript-объекты. Несмотря на то, что оба содержат информацию, которая влияет на то, что увидим после рендера, есть существенное различие: props передаётся в компонент (служат как параметры функции), в то время как state находится внутри компонента (по аналогии с переменными, которые объявлены внутри функции).

#### Метод setState.

Метод setState используется для обновления состояния. Он принимает новое значение состояния и ставит в очередь повторный рендер компонента.

#### Особенности синтаксиса JSX.

JSX — расширение языка JavaScript, представляет собой объекты

Следующие два примера кода эквивалентны между собой:
Babel компилирует JSX в вызовы React.createElement()

```javascript
const element = (
  <h1 className="greeting">
    Привет, мир!
  </h1>
);

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Привет, мир!'
);
```

React.createElement() проводит некоторые проверки с целью выявить баги в коде, но главное — создаёт объект похожий на такой:

```javascript
// Примечание: этот код несколько упрощён.
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Привет, мир!'
  }
};
```

* Предотвращает атаки, основанные на инъекции кода
  (По умолчанию React DOM экранирует все значения, включённые в JSX перед тем как отрендерить их.)

* Допускает использование любых корректных JavaScript-выражений внутри фигурных скобок

  ```javascript
    const element = (
      <h1>
        Здравствуй, {formatName(user)}!
      </h1>
    );
  ```
* Можно использовать внутри выражений if и циклов for, присваивать переменным, передавать функции в качестве аргумента и возвращать из функции.

```javascript
function getGreeting(user) {
     if (user) {
       return <h1>Здравствуй, {formatName(user)}!</h1>;
     }
     return <h1>Здравствуй, незнакомец.</h1>;
   }
```

#### Что такое keys в React и чем их важность?

Ключи помогают React определять, какие элементы были изменены, добавлены или удалены. Их необходимо указывать, чтобы React мог сопоставлять элементы массива с течением времени:

#### Презентационные компоненты и компоненты контейнеры.

Изначально в мире React существовало условное разделение на компоненты содержащие логику, обращение к api, state и
компоненты занимающиеся отрисовкой (презинтационные компоненты). Это было удобно для консолидации стейта в о дном месте, например для форм, а также для
шеринга логики между разными презентационными компонентами (или view), например для логики оплаты которую могут использовать разные страницы, попапы или виджеты.
Также для удобства использования контенеров без создания дополнительных компонентов прослоек часто используются *HOC* или *render props*. После появления *hooks*
появился еще один способ шарить логику между компонентами, благодаря написанию кастомных хуков.
```javascript
const MyComponent = () => {
  const [time] = useClock();
  const [x, y] = useMouseMove();
  // do something with those values
  return (
    <>
      <div>Current time: {time}</div>
      <div>Mouse coordinates: {x},{y}</div>
    </>
  );
}
```

#### Что такое refs?
В обычном потоке данных React родительские компоненты могут взаимодействовать с дочерними только через пропсы. Чтобы модифицировать потомка, вы должны заново отрендерить его с новыми пропсами. Тем не менее, могут возникать ситуации, когда вам требуется императивно изменить дочерний элемент, обойдя обычный поток данных. Подлежащий изменениям дочерний элемент может быть как React-компонентом, так и DOM-элементом. React предоставляет лазейку для обоих случаев.

Рефы дают возможность получить доступ к DOM-узлам или React-элементам, созданным в рендер-методе.
создаются с помощью React.createRef() и прикрепляются к React-элементам через ref атрибут.

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

* Управление фокусом, выделение текста или воспроизведение медиа.
* Императивный вызов анимаций.
* Интеграция со сторонними DOM-библиотеками.

```JavaScript
// textInput должна быть объявлена здесь, чтобы реф мог иметь к ней доступ
     const textInput = useRef(null);

     function handleClick() {
       textInput.current.focus();
     }

     return (
       <div>
         <input
           type="text"
           ref={textInput} />
         <input
           type="button"
           value="Фокус на поле для ввода текста"
           onClick={handleClick}
         />
       </div>
     );
   }
```

#### React router, компонент withRouter

Библиотека которая добавляет клиенсткусю маршрутицию.

#### Компоненты высшего порядка.
Компонент высшего порядка — это функция, которая принимает компонент и возвращает новый компонент.

```JavaScript
function logProps(WrappedComponent) {
  return class extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('Текущие пропсы: ', this.props);
      console.log('Предыдущие пропсы: ', prevProps);
    }
    render() {
      // Оборачиваем компонент в контейнер без мутаций. Супер!
      return <WrappedComponent {...this.props} />;
    }
  }
}
```

#### Однонаправленный поток данных, работа с событиями в React.

TODO

### Жизненный цикл компонента, в каких методах жизненного цикла стоит выполнять ajax запросы? В каких стоит "обновлять state на основе props»?

В данный момент существует последовательность жизненных циклов React указанная на рисунке.
![merge](/img/react_lifecycle1.PNG)
[ссылка на диаграмму](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)

**ajax** запросы можно выполнять в методе *componentDidMount()* или в хуке *useEffect*.

#### Оптимизация
  Для разного синтаксиса сущуствуют различные методы отптимизация производительности React приложений, направленные в основном для
уменьшения количества перерендеринга страниц.
В классовых компонентах стоит упомянуть:
* **React.PureComponent** - реализует *shouldComponentUpdate()* c поверхностным сравнением props, state (shallow prop and state comparison).
* **shouldComponentUpdate(nextProps, nextState)** - дает возможность сравнить this.props, this.state с nextProps, nextState и в случае если перерендер не нужен
вернуть false.
* **componentDidUpdate(prevProps, prevState, snapshot)** - метода дает возможность сранить prevProps, prevState c this.props, this.state и в случае необходимости сделать запрос по api или this.setState().

Для фнкциональных компонентов:
* Второй аргумент в *useEffect*, следящий за переменными от которых зависит рендер (подробнее в разделе hooks).
* Второй аргумент в *useMemo*, *useCallback* также следящий за изменениями в переменных от которых зависит рендер.

Для мониторинга частей рендеринга удобно использовать `React DevTools -> Profiler -> Highlight updates when components render`.

### Hooks

 **useState** - `const [state, setState] = useState(initialState)` возвращает значение с состоянием и функцию для его обновления. Функция setState используется для обновления состояния. Она принимает новое значение состояния и ставит в очередь повторный рендер компонента. `setState(newState)`

  **useEffect** - `useEffect(didUpdate)` Функция, переданная в useEffect, будет запущена после того, как рендер будет зафиксирован на экране. Применяется для подписок, таймеров, логирования, обращения к DOM или API (для api лучше использовать мотоды в библиотрках mobX, redux thunk и т.д.).
  Второй аргумент useEffect отвечает за условия обновления,
  ```
  useEffect(() => {
    return () => {
      subscription.unsubscribe();
    };
  }, [props.source] )
  ```
  Сработает только при изменении *source*, если передать пустой массив [ ] сработает один раз.
  Возвращенная функция (clean-up function) вызывается перед извлечением компонента из UI.

  **useContext** - `const value = useContext(MyContext)` принимает объект контекста (значение, возвращённое из React.createContext) и возвращает текущее значение контекста для этого контекста. Текущее значение контекста определяется пропом value ближайшего <MyContext.Provider>

  **useRef** - `const refContainer = useRef(initialValue)` возвращает изменяемый ref-объект. Дает доступ к DOM. Если вы передадите React объект рефа с помощью подобного выражения `<div ref={myRef}/>`, React установит собственное свойство .current на соответствующий DOM-узел при каждом его изменении. Получить доступ к объекту - `myRef.current`

  **useCallback** - Возвращает мемоизированный колбэк.
  ```javascript
  const memoizedCallback = useCallback(
    () => {
        doSomething(a, b);
    },
    [a, b],
  )
  ```
  изменяется только, если изменяются значения одной из зависимостей.

  **useMemo** - `const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])` Аналогично useCallback но возвращает значение вычислений а не саму функцию.

  **useReducer** - `const [state, dispatch] = useReducer(reducer, initialArg, init)` Принимает редюсер типа (state, action) => newState и возвращает текущее состояние в паре с методом dispatch. Работает по принципу редакса.

  ### Articles

[How to Reuse Logic with React Hooks](https://rafaelquintanilha.com/how-to-reuse-logic-with-react-hooks/)

repo_name: sagalatov/checklist