├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── Architecture-Design.md ├── Auth.md ├── Browsers.md ├── Bundling.md ├── CSS.md ├── CyberSecurityFundamentals.md ├── Data.md ├── DataModels-Databases.md ├── DataStructures.md ├── DataTypes.md ├── Development.md ├── DiscreteMath.md ├── Docker.md ├── Elasticsearch.md ├── Encoding.md ├── Features.md ├── Flux-Redux-Vuex-Mobx.md ├── FunctionalProgramming.md ├── Git.md ├── GraphQL-REST.md ├── HTML.md ├── InterviewQuestions.md ├── JavaScript.md ├── JavaScriptDOM.md ├── NodeJS.md ├── ProductQuality.md ├── Programming.md ├── ProgrammingLanguageCharacteristics.md ├── README.md ├── React.md ├── Testing.md ├── TypeScript.md ├── _config.yml ├── assets ├── 3-tier.png ├── DNS.png ├── EBI.png ├── EBI_2.png ├── HMVC.png ├── Hzb_FIGWrqs.jpg ├── MVC.png ├── MVP.png ├── MVPVM.png ├── MVVM.png ├── Onion.png ├── SQL_1.png ├── SQL_2.png ├── SQL_3.png ├── SQL_4.png ├── SQL_5.png ├── SQL_6.png ├── SQL_7.png ├── SQL_aggregate.png ├── SQL_as.png ├── SQL_groupby.png ├── SQL_join_1.png ├── SQL_join_2.png ├── SQL_join_3.png ├── SQL_join_4.png ├── SQL_join_5.png ├── SQL_orderby.png ├── SQL_orderby_2.png ├── SQL_view_1.png ├── SQL_view_2.png ├── css-box-model.png ├── sibling-combinators.png └── testing-pyramid.png ├── in-progress ├── Algorithms-Structures.md ├── C++.md ├── Colors.md ├── English.md ├── Protocols.md ├── ReactNative.md ├── VSCode.md └── npm.md └── tech ├── ApacheVelocity.md ├── Chai-Mocha.md ├── ESlint-TSlint-Prettier.md ├── ErrorHandling.md ├── Files.md ├── Firebase.md ├── Heroku.md ├── Jest.md ├── Klaviyo.md ├── Kubernetes.md ├── Microservices.md ├── MongoDB.md ├── Parcing-Preprocessing-StaticChecking.md ├── PostCSS.md ├── Postman.md ├── Python.md ├── Redis.md ├── SQL.md ├── Scala.md ├── Shell.md ├── Shortcuts.md ├── Sisense.md ├── Snowflake.md ├── Vim.md ├── Webpack.md ├── jQuery.md ├── nvm.md └── pip.md /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /Auth.md: -------------------------------------------------------------------------------- 1 | - [Аутентификация, Авторизация и Идентификация](#аутентификация-авторизация-и-идентификация) 2 | - [Разновидности идентификаторов. `ID`, `UID`, `UUID` и `GUID`](#разновидности-идентификаторов-id-uid-uuid-и-guid) 3 | - [Виды аутентификации](#виды-аутентификации) 4 | - [Базовая (`Basic`)](#базовая-basic) 5 | - [`Bearer`](#bearer) 6 | - [Сессии (`Sessions`) и `Cookie`](#сессии-sessions-и-cookie) 7 | - [`JSON Web Token` (`JWT`)](#json-web-token-jwt) 8 | - [Виды токенов](#виды-токенов) 9 | - [`OAuth`](#oauth) 10 | 11 | ## Аутентификация, Авторизация и Идентификация 12 | 13 | **Идентификация** (англ. `identification`, лат. `identifico` — отождествлять) — *процедура распознавания объекта* (субъекта) по его *идентификатору*. 14 | 15 | Например, можно *идентифирировать* человека по имени, электронной почте, номеру телефона или паспорта. 16 | 17 | **Аутентификация** (англ. `authentication`, греч. `αυθεντικός` — подлинный) — процедура проверки подлинности. 18 | 19 | Например, можно определить подлинность проверкой пароля, отпечатка пальца, наличием пропуска или ключа от двери. 20 | 21 | **Авторизация** (англ. `authorization` - разрешение, уполномочивание) – предоставление доступа к какому-либо ресурсу. 22 | 23 | ### Взаимосвязь 24 | Стандартная последовательность действий на любом сайте. 25 | * *Установление личности* (username, email, phone) – *идентификация*. 26 | * *Проверка подлинности* (password) – *аутентификация*. 27 | * *Предоставление доступа* – *авторизация*. 28 | 29 | ## Объект и субъект 30 | **Объект** (лат. objectum — предмет) — философская категория, обозначающая вещь, явление или процесс, на которые направлена предметно-практическая, управляющая и познавательная деятельность субъекта (наблюдателя); при этом в качестве объекта может выступать и сам субъект. 31 | 32 | ## Разновидности идентификаторов. `ID`, `UID`, `UUID` и `GUID` 33 | 34 | **Идентификатор** (англ. `identifier`, `ID`) — уникальный признак объекта (субъекта), позволяющий отличать его от других объектов (идентифицировать). 35 | 36 | Поле `ID` обычно является главным ключом (англ. `primary key`), по которому можно найти конкретный объект в коллекции объектов. 37 | 38 | Поле `ID` чаще всего представлено в виде некоторого хэша, сгенерированного в заданном формате по некоторому алгоритму. Существует множество форматов ID, при этом для генерации могут использовать индексы (последовательное инкрементирование - самый простой случай), даты (англ. `timestamps`), рандомные числа, другие поля объекта, которые тоже по некоторому алгоритму становятся хэшем. Далее рассмотрим некоторые варианты `ID`. 39 | 40 | `UUID` (англ. `Universally Uique IDentifier`) — *стандарт идентификации*, стандартизированный Open Software Foundation как часть среды распределённых вычислений (DCE). 41 | 42 | UUID позволяет уникально идентифицировать информацию, не имея при этом центра координации. 43 | То есть любой может создать `UUID` и использовать его для идентификации чего-либо с достаточным уровнем уверенности, что этот идентификатор не будет использован для чего-либо ещё непреднамеренно. 44 | 45 | `UUID` имеет *несколько версий*, в которых используются: 46 | * **Версии 1 и 2** - *время* и *MAC-адрес*. 47 | * **Версия 3** - *хеширование* алгоритмом *MD5*. 48 | * **Версия 4** - генерация *случайным образом*. 49 | * **Версия 5** - *хеширование* алгоритмом *SHA-1*. 50 | 51 | Библиотека в `npm`, позволяющая создавать и проверять валидность `UUID`: 52 | ```bash 53 | npm i uuid 54 | ``` 55 | 56 | # Виды аутентификации 57 | 58 | Для *проверки подлинности* (аутентификации) пользователя обычно на сервер вместе с запросом передаётся заголовок `Authorization`, в котором размещают тип аутентификации и соответствующие ей данные. 59 | ```http 60 | Authorization: 61 | ``` 62 | 63 | ## Базовая (`Basic`) 64 | 65 | **Базовая** (Basic) **аутентификация** подразумевает передачу в заголовок имени пользователя и пароля в виде строки следующего вида `username:password`, зашифрованной в Base64. 66 | ```http 67 | Authorization: Basic 68 | ``` 69 | В JavaScript можно кодировать и декорировать Base64 следующим образом. 70 | ```js 71 | const credentials = 'admin:admin'; 72 | /* кодировка */ 73 | const encodedCredentials = btoa('admin:admin'); 74 | console.log(encodedCredentials); // 'YWRtaW46YWRtaW4=' 75 | /* декодировка */ 76 | const decodedCredentials = atob('YWRtaW46YWRtaW4='); 77 | console.log(decodedCredentials); // 'admin:admin' 78 | ``` 79 | 80 | ## `Bearer` 81 | 82 | ```http 83 | Authorization: Basic 84 | ``` 85 | 86 | # Сессии (`Sessions`) и `Cookie` 87 | 88 | ```js 89 | /* получение Cookie */ 90 | /* Auth request 91 | with credentials */ 92 | Client --------------------> Server 93 | 94 | /* Set-Cookie 95 | response header */ 96 | Client <-------------------- Server 97 | 98 | /* Cookie 99 | request header */ 100 | Client --------------------> Server 101 | ``` 102 | Когда Cookie устаревают, они удаляются и на клиенте, и на сервере, поэтому описанный выше алгоритм повторяется. 103 | ```js 104 | /* обновление auth_token */ 105 | 106 | /* Cookie is 107 | missing (401) */ 108 | Client <-------------------- Server 109 | ``` 110 | 111 | 112 | 113 | # `JSON Web Token (JWT)` 114 | 115 | ## Содержимое токена 116 | ```js 117 | /* header.payload.signature */ 118 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImdhcnJ5QGl0ZWNoYXJ0LWdyb3VwLmNvbSIsInN1YiI6MSwiaWF0IjoxNTgxMzUzMTk1LCJleHAiOjE1ODEzNjM5OTV9.sIAg18cc66dLi4PyLGzITOou8nppH056pxVVH0pgWMs 119 | ``` 120 | ## Виды токенов 121 | 122 | ### Токен доступа 123 | 124 | ```js 125 | /* получение или обновление refresh_token */ 126 | 127 | /* Auth request 128 | with credentials */ 129 | Client --------------------> Auth Server 130 | 131 | /* auth_token, 132 | refresh_token */ 133 | Client <-------------------- Auth Server 134 | 135 | /* Authorization 136 | request header with 137 | auth_token */ 138 | Client --------------------> Server 139 | ``` 140 | 141 | **Токены доступа** (Access Tokens) представляют собой учётные данные (credentials), которые используеются для доступа к защищенным ресурсам. 142 | 143 | Токен доступа отправляется на сервер с каждым запросом в `Authorization` заголовке запроса. 144 | 145 | *Токены доступа* можно использовать неограниченное количество раз, но они обычно имеют *короткую продолжительность жизни* (обычно устанавливают ~15 минут), чтобы их нельзя было украсть и постоянно использовать. 146 | 147 | Таким образом, если токен доступа украдут, то им можно будет пользоваться не более указанного в нём времени (например, не более 15 минут). 148 | 149 | Время истечения токена может быть определено по полям `exp` (expiration time), определяющим время жизни токена и `iat` (issued at), определяющим дату создания токена. Подделать это время нельзя, поскольку формула формирования токена нарушится и он станет невалидным. 150 | 151 | Токены доступа не хранятся на сервере, на клиенте чаще всего хранятся в Local Storage (и берутся оттуда, чтобы их можно было отправить в заголовке запроса). 152 | 153 | ### Токен обновления 154 | 155 | ```js 156 | /* обновление auth_token */ 157 | 158 | /* auth_token is 159 | expired (401) */ 160 | Client <-------------------- Auth Server 161 | 162 | /* Auth request 163 | with refresh_token */ 164 | Client --------------------> Auth Server 165 | 166 | /* auth_token, 167 | refresh_token */ 168 | Client <-------------------- Server 169 | ``` 170 | 171 | Когда токен доступа истекает и требуется новый для доступа к ресурсу, клиенту необходимо обратиться к серверу аутентификации (Auth Server) для получения нового токена. 172 | 173 | **Токен обновления** (Refresh Token) содержит информацию, необходимую для получения нового токена доступа. 174 | 175 | Серверу аутентификации отсылается токен обновления и возвращается токен доступа. 176 | 177 | Токены обновления одноразовые и обычно имеют долгую продолжительность жизни. 178 | 179 | Если токен обновления украден, его можно использовать только один раз, а значит получить только один токен доступа. 180 | 181 | Если клиент видит, что его токен доступа невалиден (им уже воспользовались), он может перелогиниться. Таким образом сгенерируется новый токен обновления, а старый станет невалидным. 182 | 183 | Токены обновления не хранят в себе какую-то информацию, как JWT-токены, и обычно представляют обычную хеш-строку. Токены обновления необходимо хранить на сервере. 184 | 185 | В отличие от токенов доступа токены обновления хранятся на сервере. Они также хранятся и на клиенте. 186 | 187 | # `OAuth` 188 | -------------------------------------------------------------------------------- /Bundling.md: -------------------------------------------------------------------------------- 1 | # Сборка проекта (Bundling) 2 | 3 | ## Встряска дерева (Three Shaking) 4 | 5 | **Встряска дерева** (англ. `three shaking`) - подход к сборке проекта, позволяющий добиться исключения "мёртвого кода" (англ. `dead code elimination`) - тех файлов (или методов в этих файлах), которые не задействованы в приложении. 6 | 7 | При этом подходе проект представляется в виде **дерева зависимостей**: 8 | * Выбирается *лючевой, корневой* файл (`app.js`, `index.js`), с которого *начинается запуск приложения* (например, `node index.js`). Этот *файл* становится *корнем дерева* (англ `root`). 9 | * *Корневой файл* чаше всего *имеет зависимости* (`require`, `import`) в виде *других файлов*, которые в *дереве зависимостей* *становятся* его *дочерними узлами*. Поскольку эти *файлы тоже* могут *иметь зависимости*, то и у них могут быть *дочерние узлы*. *Выстроив все цепочки зависимостей файлов*, *получаем* некоторый *граф*. 10 | * Если некоторая *зависимость* уже была *внедрена* (импортирована), то *второй раз* она в итоговую *сборку не включается* - *берётся уже существующая ссылка на файл*. Это *позволяет исключить циклические зависимости*, а значит *граф можно представить* в виде *дерева*. 11 | ```js 12 | /* пример циклической зависимости */ 13 | // a.js 14 | require('b.js'); 15 | // b.js 16 | require('a.js'); 17 | ``` 18 | * Таким образом, те файлы в проекте, которые по каким-либо причинам нигде не были импортированы, не попадают в дерево зависимотей, а значит и в сборку проекта. Это позволяет уменьшить размер бандла, а значит ускорить загрузку страницы. 19 | * Если учесть, что можно импортировать не только файлы, но и отдельные методы, то узлами дерева могут становиться эти самые методы. В таком случае неимпортированные методы не так же не попадут в сборку. 20 | 21 | Отсюда можно сделать *вывод касательно названия*. Когда мы *трясём дерево* - то, что *держится за ветку не* достаточно *прочно*, - *падает* (яблоки, шишки, каштаны, листья, а в нашем случае - *"мёртвый код"*). 22 | 23 | *Концепция "встряски дерева"* была *популяризирована* [Rollup](https://github.com/rollup/rollup#tree-shaking) и [Webpack](https://webpack.js.org/guides/tree-shaking/). 24 | 25 | Рассмотрим *пример исключения неиспользуемых методов* из *сборки* (с *файлами* всё *аналогично*). 26 | 27 | Допустим, есть некоторый *модуль* `utils.js` по типу `lodash`, *содержащий множество полезных утилит*. 28 | ```js 29 | // utils.js 30 | export const debounce = () => { /* ... */ }; 31 | export const throttle = () => { /* ... */ }; 32 | export const groupBy = () => { /* ... */ }; 33 | ``` 34 | И есть *модуль* `app.js`, который *использует метод* `splitIntoChunks` из этого *модуля*. Пусть *другие модули не используют* `utils.js`. 35 | ```js 36 | // app.js 37 | import { groupBy } from 'utils'; 38 | ``` 39 | В таком случае в *сборку попадёт только метод* `groupBy`, а *методы* `debounce` и `throttle` в неё *не попадут*. 40 | 41 | ## Разбиение на чанки 42 | 43 | 44 | -------------------------------------------------------------------------------- /CyberSecurityFundamentals.md: -------------------------------------------------------------------------------- 1 | - [Переферия и устройства ввода-вывода](#переферия-и-устройства-ввода-вывода) 2 | - [Компьютерная сеть](#компьютерная-сеть) 3 | - [Масштаб компьютерной сети (`LAN`, `WAN`)](#масштаб-компьютерной-сети-lan-wan) 4 | - [Конечная точка (`endpoint`)](#конечная-точка-endpoint) 5 | - [Разница между компьютером, сервером и рабочей станцией](#разница-между-компьютером-сервером-и-рабочей-станцией) 6 | - [Устройства интернета вещей (`IoT devices`)](#устройства-интернета-вещей-iot-devices) 7 | - [Защита конечных точек (`endpoint protection`)](#защита-конечных-точек-endpoint-protection) 8 | - [Антивирусные программы (`anti-virus software`)](#антивирусные-программы-anti-virus-software) 9 | - [`Endpoint Protection Platform` (`EPP`)](#endpoint-protection-platform-epp) 10 | - [`Endpoint Detection and Response` (`EDR`)](#endpoint-detection-and-response-EDR) 11 | - [`Managed Detection and Remediation`, `Managed EDR` (`MDR`)](#) 12 | - XDR 13 | 14 | 15 | # Переферия и устройства ввода-вывода 16 | 17 | В широком смысле слова, **переферией** (англ. `peripheral`, греч. `περιφέρεια` — *окружность*) называют *внешнюю часть чего-либо*, другими словами, *часть*, *противопоставляющуются центру*. 18 | 19 | Если говорить о компьютере, то **переферией** называют *совокупность всех переферических устройств*, *подключенных* к *компьютеру* в данный момент. 20 | 21 | **Переферийным устройством** (англ. `peripheral device`) или **устройством ввода-вывода** (англ. `input-output device`) называют любое устройство, которое 22 | позволяет вводить информацию в компьютер или выводить из него. 23 | 24 | Таким образом, устройство ввода-вывода позволяет компьютеру взаимодействовать с внешним миром (в том числе и с человеком, например, посредством графичекого изображения или звукового сопровождения). 25 | 26 | Например, к **устройствам ввода** (англ. `input devices`) относят: 27 | * *комьютерную мышь* (англ. `computer mouse`) 28 | * *клавиатуру* (англ. `keyboard`) 29 | * *тачпад* (англ. `touchpad`) 30 | * *сенсор экрана* (англ. `screen sensor`) 31 | * *микрофон* (англ. `microphone`)* 32 | * *веб-камеру* (англ. `webcab`) 33 | * *графических планшет* (англ. `graphic tablet`) 34 | * *джойстик* (англ. `joystick`) 35 | 36 | К **устройствам вывода** (англ. `output devices`) относят: 37 | * *принтер* (англ. `printer`) 38 | * *монитор* (англ. `monitor`) 39 | * *динамики* (англ. `speakers`) 40 | 41 | Ну и к **устройствам ввода-вывода** (англ. `input-output devices`, `I/O devices`) обычно относят любые съёмные накопители, которые можно подключить к компьютеру и с которых можно передавать информацию в обе стороны. 42 | 43 | 44 | # Компьютерная сеть 45 | 46 | **Компьютерной сетью** (англ. `computer network`) называют *группу* из *двух и более компьютеров*, *соединённых* между собой *для* электронной *передачи данных*. 47 | 48 | ## Масштаб компьютерной сети (`LAN`, `WAN`) 49 | 50 | 51 | 52 | По своему *масштабу компьютерные сети делятся* на *локальные* и *глобальные*. 53 | 54 | ### Локальная компьютерная сеть 55 | 56 | **Локальная компьютерная сеть** (англ. `locan-area network`, `LAN`) объединяет компьютеры и периферические устройства на какой-то небольшой, физически ограниченной территории: обычно в рамках одного здания (квартира или небольшой жилой дом, рабочий офис, лабаратория, университет, военная база и так далее). 57 | 58 | ### Глобальная компьютерная сеть 59 | **Глобальная компьютерная сеть** (ангд. `wide-area network`, `WAN`) 60 | 61 | # Конечная точка (endpoint) 62 | 63 | **Конечной точкой** (англ. `endpoint`, `entry point`) или **устройством конечного пользователя** (англ. `end-user device`) называет *удалённое вычислительное устройство*, которое подключено к сети Интернет, *производит по этой сети двухсторонее взаимодействие* (англ. `communicates back and forth`), то есть и *отправляет данные* на другие устройства, и *получает данные* от *подобных устройств*. 64 | 65 | Чаще всего *конечными точками* в *сети Интернет* *выступают*: 66 | 1) *Персональный компьютер* (англ. `PC`, `desktop`), 67 | 2) *Ноутбук* (англ. `laptop`), 68 | 3) *Планшет* (англ. `tablet`), 69 | 4) *Смартфон* (англ. `smartphone`) 70 | 5) *Сетевой сервер* (англ. `network server`). Например, сервер `Amazon`, `Digital Ocean`. 71 | 6) *Рабочая станция* (англ. `workstation`). 72 | 7) *Устройство интернета вещей* (англ. `internet-of-things device`, `IoT device`). 73 | 74 | ## Разница между компьютером, сервером и рабочей станцией 75 | 76 | ## Устройства интернета вещей (`IoT devices`) 77 | 78 | Internet-of-things (IoT) devices 79 | 80 | # Защита конечных точек (`endpoint protection`) 81 | 82 | **Защитой конечных точек** (англ `endpoint security`, `endpoint protection`) называют *процесс обезапашивания конечных точек*, *подключенных* к *сети Интернет*. 83 | 84 | Всё, что имеет доступ к сети интернет (например, по кабелю или по беспроводному Wi-Fi подключению), а это телефоны, компьютеры, телевизоры, уйстройства умного дома и так далее, является потенциальной мишенью для кибератаки (атаки по сети), то есть находится под угрозой безопасности. 85 | 86 | Для защиты конечных точек необходимо регулярно (а лучше в режиме реального времени) проводить проверки на то, что конечные устройства в текущий момент соблюдают допустимый уровень соответствия стандартам компьютерной безопасности. 87 | 88 | Стандартов и способов защитить своё устройство существует много, поэтому далее познакомимся отдельно с каждым из них. 89 | 90 | # Антивирусные программы (`anti-virus software`) 91 | 92 | **Антивирусные программы** или **антивирусы** (англ. `anti-virus software`, `AV`) является самым распространённым и широкоизвестных среди решением проблем кибербезопасности для пользователей сети интернет. *Антивирное ПО* появилось ещё в 1988 году и помогло устранить многие проблемы на устройствам пользователей, но с момента создания технология антивирусов почти не изменилась. 93 | 94 | Ниже перечислены одни из самых известных и сильных антивирусов: 95 | - Norton 360 Deluxe. 96 | - Bitdefender Antivirus Plus. 97 | - Kaspersky Total Security. 98 | - McAfee Internet Security. 99 | - ESET Smart Security Premium. 100 | - Windows Defender Antivirus. 101 | 102 | ## Сканирование - основное оружие антивируса 103 | 104 | Принцип работы антивируса заключатся в регуляром сканировании девайса. Обычно имеется возможность запустить сканирование в любое время, либо можно настроить планирование сканирований с какой-то периодичностью (например, раз в неделю). 105 | 106 | 107 | # `Endpoint Protection Platform` (`EPP`) 108 | 109 | **Платформы защиты конечных точек** (англ. `Endpoint Protection Platform`, `EPP`) разворачиваются (устанавливаются) на конечных устройствах (англ. `endpoint devices`) для предотвращения вредоносных атак (англ. `malware attacks`) на основе файлов, а также для обнаружения вредоносной активности с возможностью расследования и исправления тех или иных динамических инцедентов безопасности, а также оповещения об этих инцедентах. 110 | 111 | Чаще всего `EPP` распознаёт некоторые извесные и неизвестные вредоносные программы и блокирует им доступ к ресурсу (или спрашивает пользователя, что нужно с ними делать). 112 | 113 | 115 | # `Endpoint Detection and Response` (`EDR`) 116 | 117 | **Обноружение конечной точки и ответ** 118 | Технология **EDR** (англ. `Endpoint detection and response`), дословно *переводящаяяся* как **обнаружение конечной точки и ответ**, предоставляет видимость активности конечной точки в режиме реального времени (англ. `real time`) посредством обнаружения злонамеренного поведения (англ. `malicious behavior`), мониторинга (слежения, отслеживанию) подобных случаев, записью данных конечной точки и ответом на угрозы. 119 | 120 | Чаще всего это работает таким образом, что `EDR` мониторит и записывает данные об активности конечной точки, а киберспециалисты уже сами вручную анализируют записанные данные и предпринимают решения, как поступить с угрозой. 121 | 122 | 123 | Endpoint detection and response is a type of security solution that provides real-time visibility into endpoint activities. This is done by detecting malicious behavior, monitoring and recording endpoint data, and responding to threats. Security teams proactively prevent threats by manually analyzing endpoint data received from EDR solutions. 124 | 125 | 126 | 127 | # `Managed Detection and Remediation`, `Managed EDR` (`MDR`) 128 | 129 | -------------------------------------------------------------------------------- /DataStructures.md: -------------------------------------------------------------------------------- 1 | - [Структуры данных](#структуры-данных) 2 | 3 | # Структуры данных 4 | 5 | **Структура данных** (англ. data structure) - это *набор значений* некоторых *логически связанных данных*, *отношения между этими данными* и *доступные операции*, которые *можно к ним применить*. 6 | 7 | -------------------------------------------------------------------------------- /Development.md: -------------------------------------------------------------------------------- 1 | # Оглавление 2 | - [SCRUM теория и жестокая реальность](#scrum-теория-и-жестокая-реальность) 3 | 4 | # SCRUM теория vs жестокая реальность 5 | - [О SCRUM](#о-scrum) 6 | - [Скрам-артефакты](#скрам-артефакты) 7 | - [Спринт (`Sprint`)](#спринт-sprint) 8 | - [Бэклог (`Backlog`)](#бэклог-backlog) 9 | - [Инкремент (`Increment`)](#инкремент-increment) 10 | - [Скрам-команда](#скрам-команда) 11 | - [Владелец продукта (`Product Owner`)](#владелец-продукта-product-owner) 12 | - [Скрам-мастер (`Scrum Master`)](#скрам-мастер-scrum-master) 13 | - [Команда разработчиков (`Developer Team`)](#команда-разработчиков-developer-team) 14 | - [Скрам-события](#скрам-события) 15 | - [Планирование спринта (`Sprint Planning`)](#планирование-спринта-sprint-planning) 16 | - [Ретроспектива спринта (`Sprint Retrospective`, `Retro`)](#ретроспектива-спринта-sprint-retrospective-retro) 17 | 18 | ## О SCRUM 19 | 20 | ### Что такое SCRUM 21 | 22 | **SCRUM** (англ. `scrum` - "схватка") — это методология управления проектами, которая чаще всего встречается при разработке программного обеспечения (англ. `software development`), но может применяться и в других сферах, в том числе в сферах маркетинга (англ. `marketing`), продаж (англ. `sales`) и исследования (англ. `research`) чего-либо. 23 | 24 | ### Кому стоит читать книгу с SCRUM целиком 25 | Если вы разработчик, то, возможно, вам нет смысла читать книгу о SCRUM - существует множетсво других книг, которые могут принести вам намного больше пользы. 26 | 27 | Очень детально изучить SCRUM стоит менеджерам (например, проектным менеджерам), бизнесс-аналитикам. Идеал недостижим, но к нему стоит стремиться. А ещё их об этом очень активно спрашивают на собеседованиях, поскольку эффективное управление - их основная задача. Оснавная же задача программиста - создание чего-либо. 28 | 29 | Очень часто программисты, которые доходят до позиции Team Lead или хотя бы Tech Lead и думаю о своём дальнейшем развитии, уходят в менеджмент в последствии. Потому что чем больше людей в твоём подчинении, тем выше твоя позиция и больше доход. Более того, многие задачи можно делигировать, выстраивая иерархию ответственности. И код самому больше писать уже не нужно - сплошные митинги. Не всем такое подходит, но очень многим. 30 | 31 | ### SCRUM в реальной жизни 32 | 33 | В реальной жизни он в 90% случаев SCRUM используется не больше, чем на 50% от того, что в нём предусматривается. 34 | 35 | Чаше всего на небольших проектах с маленькими командами имеется двухнедельных спринт, спринт планинг, доска в Trello с несколькими колонками (Backlog, To do, Doing, Done) и несколько звонков разработчиков с заказчиками в неделю. Вот и весь SCRUM. 36 | 37 | 38 | ## Скрам-артефакты 39 | - [Спринт (`Sprint`)](#спринт-sprint) 40 | - [Бэклог (`Backlog`)](#бэклог-backlog) 41 | - [Инкремент (`Increment`)](#инкремент-increment) 42 | 43 | ### Спринт (`Sprint`) 44 | 45 | **Спринт** (англ. `Sprint`) - итерация в скраме, в ходе которой создается инкремент бизнес-продукта; повторяющийся фиксированный временной интервал (repeatable fixed time-box) от одной недели до месяца, в течение которого создаётся "готовый" (Done) продукт с максимально возможным значением (value). Спринты имеют одинаковую продолжительность на протяжении всего процесса разработки. Новый Спринт начинается сразу после завершения предыдущего Спринта. Чем короче спринт, тем гибче скрам и тем чаще выходят релизы. 46 | 47 | ### Бэклог (`Backlog`) 48 | 49 | **Бэклог продукта** (англ. `Product Backlog`) - упорядоченный список всего, что может быть нужно продукту; единственный источник требований любых будущих изменений продукта. За бэклог продукта отвечает владелец продукта (содержание, доступность, упорядочивание). 50 | 51 | **Бэклог спринта** (англ. `Sprint Backlog`) - набор элементов из бэклога продукта, выбранных для спринта, а также план доставки инкремента продукта и реализации целей спринта. 52 | 53 | ### Инкремент (`Increment`) 54 | 55 | **Инкремент** (англ. `Increment`) - совокупность всех элементов бэклога продукта, выполненных за время спринта, и значение инкрементов всех предыдущих спринтов. 56 | 57 | ## Скрам-команда 58 | **Скрам-командом** (англ. `Scrum team`) называют *команду*, которая работает над проектом, разрабатыващимся по методологии SCRUM. 59 | 60 | В скрам-команду входят: 61 | - [Владелец продукта (`Product Owner`)](#владелец-продукта-product-owner) 62 | - [Скрам-мастер (`Scrum Master`)](#скрам-мастер-scrum-master) 63 | - [Команда разработчиков (`Developer Team`)](#команда-разработчиков-developer-team) 64 | 65 | включает в себя владельца продукта, скрам-мастера и команду разработчиков. 66 | 67 | ### Владелец продукта (`Product Owner`) 68 | 69 | **Владельцем продукта** (англ. `Product Owner`) называют *члена скрам-команды*, который *знает* и *понимает желания клиента* (англ. `customer`) и может донести команде их бизнес-значение (business value). 70 | 71 | Владелец продукта может консультировать команду, чтобы она корректно выполняла свои задачи. 72 | 73 | Владелец продукта должен принимать все все важные решения для завершения проекта. 74 | 75 | *Владелец продукта* отвечает за *бэклог продукта*. Пункты в бэклоге должны быть чёткими и понятными всем, отсортироваными по значимости (value). 76 | 77 | ### Скрам-мастер (`Scrum Master`) 78 | 79 | **Скрам-мастер** (англ. `Scrum Master`) управляет скрам-процессом, помогая команде быть отчётной (accountable) за свои обязательства перед бизнесом и устраняя любые препятствия работе и продуктивности команды. 80 | 81 | Скрам-мастер организует митинги. 82 | 83 | Скрам-мастеру следует тренировать и мотивировать команду, а не навязывать ей правила. 84 | 85 | На реальных проектах скрам-мастером чаще всего назначают одного из членов других частей скрам-команды. Я участвовал на проектах, на которых скрам-мастером могли быть: 86 | 1) Владелец продукта. 87 | 2) PM/BA. 88 | 3) Опытный разработчик из команды разработчиков с хорошими коммуникационными способностями. 89 | 90 | Иногда данную в качестве скрам-мастера могут назвачать опытного разработичика с хорошими 91 | 92 | ## Команда разработчиков (`Developer Team`) 93 | 94 | Команда разработчиков (англ. `Developer Team`, `Dev Team`, `Engineering Team`) стрктурирована и уполномочена на организацию своей работы. Хорошая синергия команды оптимизирует общую эффективность и результативность. 95 | 96 | Команда разработчиков самоорганизуется: никто (даже скрам-мастер) не говорит команде, как превратить бэклог продукта в инкременты. 97 | 98 | Скрам не признаёт званий членов команды вне зависимости от их деятельности. 99 | 100 | Скрам не признаёт подгруппы в команде разработчиков. Вне зависимости от их областей (тестирование, архитектура, бизнес-анализ). Отдельные члены команды могут обладать специализированными навыками, но отчётность (`accountability`) принадлежит всей команде в целом. 101 | 102 | 103 | ## Скрам-события 104 | 105 | Скрам-событиями называют митинги, которые команды проводят каждый спринт. 106 | 107 | - [Планирование спринта (`Sprint Planning`)](#планирование-спринта-sprint-planning) 108 | - [Ретроспектива спринта (`Sprint Retrospective`, `Retro`)](#ретроспектива-спринта-sprint-retrospective-retro) 109 | 110 | * **Планирование спринта** (англ. `Sprint Planning`) происходит в его начале. Обсуждаются задачи на следующий спринт, выбирающиеся из бэклога проекта. 111 | * **Ежедневный скрам** (англ. `Daily Scrum`) - 15-минутное событие для команды разработчиков, предназначенное для синхронизации действий и создания плана на ближайшие сутки. 112 | * **Ревью спринта** (англ. `Sprint Review`) происходит в конце спринта. Проверяется Инкремент спринта и, при необходимости, пополняется бэклог продукта. 113 | * **Ретроспектива спринта** (англ. `Sprint Retrospective`, `Retro`) предоставляет возможность скрам-команде изучить себя и составить план улучшений, которые будут приняты во время следующего спринта. 114 | 115 | На практике чаще всего 116 | 117 | ### Планирование спринта (`Sprint Planning`) 118 | 119 | Планирование стринта проводится в начале нового спринта на митинге. 120 | Продолжительность митинга зависит от продолжительности спринта. 121 | 122 | На первой части митинга участвует вся скрам-команда (владелец продукта, скрам-мастер и команда разработчиков): обсуждаются задачи на текущий спринт. Задачи берутся из бэклога проекта с учётом того, что 123 | На второй части митинга участвует только скрам-команда: обсуждаются технические детали реализации, заполняется бэклог спринта. 124 | 125 | * Выбираются задачи из бэклога проекта, на основании которых создаётся бэклог спринта. 126 | * Задачи оцениваются в человеко-часах (не более 12 часов или одного дня на задачу) либо в стори-поинтах. Слишком долгие задачи разбиваются на подзадачи. 127 | 128 | ### Ретроспектива спринта (`Sprint Retrospective`, `Retro`) 129 | -------------------------------------------------------------------------------- /Encoding.md: -------------------------------------------------------------------------------- 1 | - [Cистемы счисления](#системы-счисления) 2 | - [Представление чисел в различных с/с](#представление-чисел-в-различных-с-с) 3 | - [Кодировки символов](#кодировки-символов) 4 | - [ASCII](#ascii) 5 | - [Кодирование и декодирование](#кодирование-и-декодирование) 6 | - [UTF](#utf) 7 | - [Медиа тип (`MIME type`)](#медиа-тип-mime-type) 8 | 9 | # Системы счисления 10 | 11 | **Система счисления** (англ. `numeral system`, `system of numeration`) — представление чисел при помощи символов. 12 | 13 | **Двоичная, бинарная** (англ. `binary`): 0, 1. 14 | **Десятичная** (англ. `decimal`): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. 15 | **Шестнадцатеричная** (англ. `hexadecimal`): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. 16 | 17 | Чтобы не путать с 10 с/с, к числу в 16 с/с обычно добавляют `0x` в начало или `h` (`₁₆`) в конец. 18 | Чтобы не путать с 10 с/с, к числу в 2 с/с обычно добавляют `b` (`₂`) в конец. 19 | 10 с/с считается стандартной, поэтому к числу обычно ничего не добавляют (но иногда можно явно указать `₁₀`). 20 | 21 | Двоичные цифры 0 и 1 называют **битами** (англ. `bit`), они взаимоисключаемы: 0 - ложь, 1 - истина. 22 | 23 | **Байт** (англ. `byte`), **октет** (англ. `octet`) — *последовательность из 8 бит*, её можно компактно представить в виде шестнадцатеричного числа. 24 | ```css 25 | 00000000₂ = 0x0 26 | 10110011₂ = 0xB3 27 | 11111111₂ = 0xFF 28 | ``` 29 | 30 | Аналогично, **ниббл** (англ. `nibble`), **полубайт** (англ. `half-byte`) или **тетрада** (англ. `tetrade`) — 4 бита, **слово** (англ. `word`) — 16 бит, **двойное слово** (англ. `double word`, `dword`) — 32 бита. 31 | 32 | *Отсчёт битов* в *двоичном числе* начинается *с нуля* и идёт *справа налево*. 33 | **Младший бит** (англ. `least significant`, `low-order`) — крайний справа, **старший бит** (англ. `most significant`, `hight-order`) — крайний слева. 34 | 35 | **Порядок байтов от старшего к младшему** (англ. `big-endian`, `BE`) соответствует порядку записи арабских цифр: 123 (сто двадцать три). 36 | Этот порядок также называют **сетевым порядком байтов**, поскольку он является стандартным для протоколов TCP/IP. 37 | Используется также в технической и учебной литературе, в PNG и JPEG. 38 | 39 | **Порядок байтов от младшего к старшему** (англ. `little-endian`, `LE`) соответствует обратному порядку записи арабских цифр: 321 (сто двадцать три). 40 | Этот порядок также называют **интеловским порядком байтов**, так как он используется в памяти ПК с процессорами архитектуры x86. 41 | 42 | ## Представление чисел в различных с/с 43 | 44 | **Числовой разряд** — место, позиция цифры в числе. 45 | 46 | Разряды начинают считать справа налево (`BE`), начиная с нулевого. 47 | 48 | Представление чисел в `N` c/c: 49 | число представляется в виде многочлена степени n - 1 (n - количество цифр), 50 | с переменной `N` и цифрами в качестве коэффициентов. 51 | ```css 52 | /* в 10 с/с */ 53 | /* 4 - нулевой разряд, 3 - первый, 2 - второй, 1 - третий */ 54 | 1234₁₀ = 1 * 10³ + 2 * 10² + 3 * 10¹ + 4 * 10⁰ 55 | 56 | /* в 16 с/с */ 57 | /* C₁₆ - нулевой разряд, B₁₆ - первый, A₁₆ - второй */ 58 | ABC₁₆ = A₁₆ * (10₁₆)² + B₁₆ * (10₁₆)¹ + C₁₆ * (10₁₆)⁰ 59 | 60 | /* в 2 с/с */ 61 | /* 0₂ - нулевой разряд, 1₂ - первый, 1₂ - второй */ 62 | 110₂ = 1₂ * (10₂)² + 1₂ * (10₂)¹ + 0₂ * (10₂)⁰ 63 | ``` 64 | 65 | Перевод чисел в 10 с/с из другой c/c. 66 | ```css 67 | /* из 16 c/c */ 68 | /* A₁₆ = 10, B₁₆ = 11, C₁₆ = 12 */ 69 | ABC₁₆ = 10 * 16² + 11 * 16¹ + 12 * 16⁰ = 2748 70 | 71 | /* из 2 с/c */ 72 | /* 1₂ = 1, 0₂ = 0 */ 73 | 110₂ = 1 * 2² + 1 * 2¹ + 0 * 2⁰ = 6 74 | ``` 75 | Перевод чисел из 10 с/с в другую `N` с/c: 76 | последовательно делим число в 10 с/с на `N` до тех пор, пока не останется остаток `<= (N - 1)`, 77 | ответ состоит из остатков деления в обратном порядке. 78 | ```css 79 | /* в 2 с/с */ 80 | 22₁₀ 81 | 22 / 2 = 11 (ост. 0) 82 | 11 / 2 = 5 (ост. 1) 83 | 5 / 2 = 2 (ост. 1) 84 | 2 / 2 = 1 (ост. 0) 85 | 1 <= 1 (ост. 1) 86 | 10110₂ 87 | 88 | /* в 16 с/с */ 89 | 7327₁₀ 90 | 7327 / 16 = 457 (ост. 15) 91 | 457 / 16 = 28 (ост. 9) 92 | 28 / 16 = 1 (ост. 12) 93 | 1 <= 15 (ост. 1) 94 | /* 12₁₀ → C₁₆, 15₁₀ → F₁₆ */ 95 | 1C9F₁₆ 96 | ``` 97 | 98 | Другие переводы (например, 2 c/c -> 16 c/c) можно проводить в два действия: 2 с/c -> 10 c/c -> 16 c/c. 99 | # Кодировки символов 100 | 101 | **Символ** (англ . `character`) — минимальная единица текста, имеющая семантическое значение. 102 | 103 | Пример символов: `G` — латинская буква G, `(` — открывающая круглая скобка, `<` — знак меньше. 104 | 105 | **Множество символов** (англ. `character set`) — набор, совокупность символов, которые могут быть использованы в разных языках. 106 | 107 | Например, множество символов `{ A, B, C, D }` используются в английском, немецком и других языках. 108 | 109 | **Кодировка символов** (англ. `character encoding`, `charset`) — представление символов какой-то системой кодирования. 110 | 111 | **Закодированное множество символов** (англ. `coded character set`) — *множество символов*, каждый символ которого соответствует какому-то уникальному номеру. 112 | ```css 113 | /* закодированное множество символов { A, B, C, D } (ключ — значение) */ 114 | 115 | /* ASCII */ 116 | 65 — A 117 | 66 — B 118 | 67 — C 119 | 68 — D 120 | 121 | /* Unicode */ 122 | U+41 — A 123 | U+42 — B 124 | U+43 — C 125 | U+44 — D 126 | ``` 127 | То есть существует другое множество — *множество уникальных номеров*, определяемое *кодировкой*, с которым у *множества символов* установлено *взаимно однозначное соответствие*. 128 | 129 | **Взаимно однозначное соответствие, биекция** (англ. `bijection`) — такое *соответствие между элементами двух множеств*, при котором *каждому элементу первого* множества *соответствует один определенный элемент второго* множества, а *каждому элементу второго* множества — *один определенный элемент первого* множества. 130 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/85d50dda-e9e9-4c27-ba90-ce8097cf0d56) 131 | 132 | 133 | **Кодовая точка, позиция кода** (англ. `code point`, `code position`) — любой элемент из *множества уникальных номеров* заданной *кодировки*. 134 | 135 | В примере выше *кодовыми точками* в кодировках *ASCII* и *Unicode* являются `66, 66, 67, 68` и `U+41, U+42, U+43, U+44` соответственно. 136 | 137 | 138 | Количество кодовых точек в различных кодировках: 139 | * ASCII - 128 кодовых точек (0 - 7F). 140 | * Extended ASCII - 256 (0 - FF). 141 | * Unicode - 1114112 (0 - 10FFFF), поскольку состоит из 17 плоскостей (каждая из них содержит 2¹⁶ кодовых точек). 142 | 143 | К *кодовым точкам Unicode* принято добавлять `U+` в начало, чтобы можно было отличить кодировку от других. 144 | ```css 145 | /* кодовые точки латинской буквы "M" */ 146 | UTF-8: U+4D 147 | UTF-16: U+004D 148 | UTF-32: U+0000004D 149 | 150 | /* кодовые точки фигурной скобки "{" */ 151 | UTF-8: U+65115 152 | UTF-16: U+65115 153 | UTF-32: U+00065115 154 | ``` 155 | 156 | **Кодовая единица** (англ. `code unit`) — последовательность бит, используемая для кодирования символа из множества символов заданной кодировки. 157 | 158 | *Кодовая единица* состоит из *заданного кодировкой количества бит*: 159 | * ASCII - 7 бит 160 | * UTF-8 - 8 бит 161 | * UTF-16 - 16 бит 162 | * UTF-32 - 32 бит 163 | 164 | Каждая *кодовая точка* представляется в виде *последовательности кодовых единиц*. 165 | 166 | Чем *больше бит вмещается* в *кодовой единице*, тем *меньше кодовых единиц требуется* для *представления кодовой точки*. 167 | * UTF-8: 1-4 кодовых единиц 168 | * UTF-16: 1-2 кодовые единицы (две требуеются для символов, идущих после U+10000) 169 | * UTF-32: 1 кодовая единица 170 | 171 | ```css 172 | /* кодовые единицы латинской буквы "M" */ 173 | UTF-8: 4D 174 | UTF-16: 004D 175 | UTF-32: 0000004D 176 | 177 | /* кодовые единицы фигурной скобки "{" */ 178 | UTF-8: EF B9 9B 179 | UTF-16: FE5B 180 | UTF-32: 0000FE5B 181 | ``` 182 | 183 | ## ASCII 184 | 185 | **ASCII** (American Standard Code for Information Interchange) — американский стандартный код для обмена информацией. 186 | 187 | Большинство кодировок символов берут ASCII за основу (например, Unicode), дополняя её другими символами. 188 | 189 | ASCII создавалась для кодирования символов, коды которых вмещались в 7 бит (2⁷ = 128 символов), 8-ой бит использовался для ошибок, возникших при передаче данных. 190 | 191 | На большинстве компьютеров минимально адресуемая единица памяти — байт (8 бит), поэтому там используются 8-битные вместо 7 (добавляется дополнительный старший бит, например, 0). 192 | 193 | Затем появилась **расширенная ASCII кодировка** (англ. `extended ASCII`), использующая 8 бит (2⁸ = 256 символов). 194 | 195 | Изначально ASCII была разработана для телекомуникационного оборудования (печатные машинки для передачи сообщений), поэтому помимо символов, выводимых на печать, содержит управляющие символы, которые не печатаются. 196 | * `EOT` (англ. `end of transmission`) — конец файла 197 | * `LF` (line feed) — перевод строки (характерен для Unix) 198 | * `CR` (carriage return) — возврат каретки (курсор перемещается в начало текущей строки, не переходя на новую) 199 | * `CR LF` - перевод строки (характерен для Windows) 200 | * `FF` (form feed) — прогон страницы (продолжить печать со следующего листа) 201 | * `BS` (backspace) — возврат на один символ 202 | * `DEL` (delete) — стереть последний символ 203 | * `TAB` (tab) — горизонтальная табуляция 204 | * `CAN` (cancel) — отмена 205 | * и другие. 206 | 207 | С помощью символа BS (возврат на один символ) можно печатать один символ поверх другого (например, добавить диакритический знак). 208 | * `a BS '` → á 209 | * `c BS ,` → ç 210 | * `o BS /` → ø 211 | * `t BS t` → **t** (дважды тот же символ — выделение жирным) 212 | 213 | Существуют национальные варианты ASCII, где некоторые символы заменяются на свойственные языку. 214 | 215 | # Кодирование и декодирование 216 | 217 | ## UTF 218 | 219 | **UTF** (Unicode Transformation Format) — формат преобразования Юникода. 220 | 221 | **Маркер последовательности байтов**, **метка порядка байтов** (Byte Order Mark, BOM) — специальный Unicode-символ `U+FEFF`, вставляемый в начало текстового файла или потока, чтобы указать кодировку и порядок байтов, с помощью которых символы Unicode были закодированы. Маркер не обязателен, но очень желателен. 222 | ```css 223 | U+FEFF /* кодовое слово маркера */ 224 | 225 | /* кодовые единицы */ 226 | EF BB BF /* UTF-8 */ 227 | FE FF /* UTF-16 (BE) */ 228 | FF FE /* UTF-16 (LE) */ 229 | 00 00 FE FF /* UTF-32 (BE) */ 230 | FF FE 00 00 /* UTF-32 (LE) */ 231 | ``` 232 | 233 | ### Алгоритм кодирования UTF-8 234 | 1) Определить кодовую точку (номер) рассматриваемого символа в Unicode. 235 | ```css 236 | $ /* символ */ 237 | U+0024 /* кодовая точка */ 238 | ``` 239 | 2) Определить по кодовой точке количество октетов (байтов, последовательностей из 8 бит; 1 - 4), требуемых для кодирования символам. 240 | ```css 241 | 0 - 7F /* 1 октет */ 242 | 80 - 7FF /* 2 октета */ 243 | 800 - FFFF /* 3 октета */ 244 | 10000 - 10FFFF /* 4 октета */ 245 | ``` 246 | 3) Установить старшие биты первого октета, опираясь на вычисленное количество необходимых октетов (`0` - 1 октет, `110` - 2 октета, `1110` - три октета, `11110` - четыре октета), во 2-4 октетах установить старшие биты равными 10. При декодировании файла это позволяет определить, где начинается новая точка и сколько следующих октетов она занимает. 247 | ```css 248 | 0xxxxxxx /* 1 октет */ 249 | 110xxxxx 10xxxxxx /* 2 октета */ 250 | 1110xxxx 10xxxxxx 10xxxxxx /* 3 октета */ 251 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx /* 4 октета */ 252 | ``` 253 | 4) `x` - значащие биты. Вместо них нужно подставить биты кодовой точки в двоичном представлении. Если их не хватает, чтобы заполнить все значащие биты, заполняем старшие значащие биты нулями. В результате получим последовательность кодовых единиц. 254 | ```css 255 | € → 0xE2 0x82 0xAC 256 | ``` 257 | 258 | Полные примеры кодирования символов: 259 | ```css 260 | $ /* символ */ 261 | U+0024 /* кодовая точка */ 262 | 24₁₆ < 7F₁₆ /* 1 октет */ 263 | 0xxxxxxx /* маска */ 264 | 24₁₆ = 36₁₀ = 100100₂ /* двоичное представление кодовой точки */ 265 | 00100100 /* кодовые единицы в 2 с/с */ 266 | 0x24 /* кодовые единицы в 16 с/с */ 267 | 268 | € /* символ */ 269 | U+20AC /* кодовая точка */ 270 | 800 < 20AC < FFFF /* 3 октета */ 271 | 1110xxxx 10xxxxxx 10xxxxxx /* маска */ 272 | 20AC₁₆ = 8364₁₀ = 10000010101100₂ /* двоичное представление кодовой точки */ 273 | 11100010 10000010 10101100 /* кодовые единицы в 2 с/с */ 274 | 0xE2 0x82 0xAC /* кодовые единицы в 16 с/с */ 275 | ``` 276 | 277 | ### Алгоритм декодирования UTF-8 278 | 279 | Аналогично, но наоборот 280 | 281 | Имеем поток байт. 282 | 283 | # Медиа тип (`MIME type`) 284 | 285 | **Медиа тип**, **MIME тип** (англ. `Media type`, `MIME type`, `Multipurpose Internet Mail Extensions`) это стандарт, описывающий природу и формат файла или набора байтов. 286 | 287 | Медиа типы *определёны* и *стандартизированы* в спецификации [RFC 6838](https://datatracker.ietf.org/doc/html/rfc6838). 288 | 289 | Ответственной организацией за все *официальные медиа типы*, то есть *официально стандартизированные*, является **IANA** (`The Internet Assigned Numbers Authority`). Страница про медиа типы на их сайте: https://www.iana.org/assignments/media-types/media-types.xhtml. 290 | 291 | ## Структура MIME типа 292 | MIME тип состоит из *типа* (англ. `type`) и **подтипа** (англ. `subtype`). Они разделяются наклонной чертой `/`. 293 | ``` 294 | type/subtype 295 | ``` 296 | 297 | **Типом** (англ. `type`) называют *общую категория данных* (например, `text`, `aplication`, `video`, `audio`, `image`). 298 | 299 | **Подтипом** (англ. `subtype`) называют *подкатегорию*. (например, простой текст `text/plain`, HTML `text/html`). 300 | 301 | ## Параметры MIME типа 302 | 303 | К MIME типу опционально может быть добавлен параметр после `;`. 304 | ``` 305 | type/subtype;param=value 306 | ``` 307 | 308 | Например, для текста в качестве *параметра* может быть указана *кодировка*. Для задания кодировки (англ. `charset`) UTF-8 используется `text/plain;charset=UTF-8`. Если параметр `charset` не задан, его значение по умолчанию US-ASCII (`text/plain;charset=ASCII`). Другие кодировки можно найти [здесь](https://help.hcltechsw.com/dom_designer/9.0.1/appdev/LSAZ_APPENDIX_E_MIME_CHARSET_NAMES.html). 309 | 310 | ## Регистр MIME типа 311 | *Регистр не имеет значения* (англ. `case insensitive`) для всего, *кроме значения параметра* `value`. Как правило, используют *нижний регистр*, *значение параметра* может быть в *любом регистре*. 312 | 313 | ## 314 | 315 | 316 | -------------------------------------------------------------------------------- /Features.md: -------------------------------------------------------------------------------- 1 | # Типы веб-сайтов 2 | 3 | Онлайн-магазин, новостной портал, социальная сеть, информационная страница (информационный портал) человека или организации, ресурсы для обучения, для просмотра картинок, видео, фильмов, для прослушивания музыки, страницы для управления бизнесом - админки, конструкторы сайтов. 4 | 5 | # Виды технологий 6 | Библиотеки - 7 | 8 | Фреймворки - 9 | 10 | Сервисы - 11 | 12 | Приложения - 13 | 14 | Сайты - 15 | 16 | # Фичи 17 | 18 | ## Регистрация, авторизация, аутентицикафия 19 | Ключевые слова: `auth`, `authorization`, `authentication`, `registration`, `login`, `signup`, `signin`, `forget password` 20 | 21 | Аутентификация чаще всего проводится через сторонние приложения или: например, через Gmail или другую почту, Facebook, иногда через VK, Github, через номер телефона. 22 | 23 | ## Работа с формами 24 | Ключевые слова: `Forms`, `working with forms`, `inputs`. 25 | 26 | ## Работа с таблицами 27 | Ключевые слова: `tables`, `sheets`, 28 | 29 | Ключевые технологии: `CSV` (`comma separated values`), `Excel`, `Google Docs`, таблицы из таких библиотек компонентов, как `Bootstrap`, `Antd`, `MUI` и так далее. 30 | 31 | ## Работа с файлами 32 | Ключевые слова: `working with files`, `file upload`, `file download`. 33 | 34 | Ключевые расширения файлов: `PDF`, `TXT`, `CSV`, расширения `Excel` и `Word`. 35 | 36 | ## Пагинация 37 | Ключевые слова: `pagination`, `infinite scroll`, `loading by parts` (by `chanks`) 38 | 39 | Ограничения количества отображаемых на странице элементов. 40 | 41 | ## Фильтрация, фильтр 42 | Ключевые слова: `filter`, `filtration` 43 | 44 | Ограничение выборки по какому-то заданному критерию - фильтру. 45 | 46 | Например, фильтруем все модели телефонов по марке `Xiaomi` или `Apple`, сотрудников компании по специальности. 47 | 48 | ## Поиск 49 | Ключевые слова: `search`, `match`, `query`, `full text search` 50 | 51 | ## Сортировка 52 | Ключевые слова: `Sorting`, `sort`, `sort order` 53 | 54 | ## Уведомления 55 | Ключевые слова: `Notifications`, `email notifications`, `push notifications`, `sms notifications`, `broadcast`, `broadcasting` 56 | 57 | 58 | ## Подписка на обновления, новостная рассылка 59 | Ключевые слова `Subscriptions`, ``subscription`, `email notifications`, `newsletter` 60 | 61 | Чаще всего присутствует на новостных порталах, на сайтах онлайн-магазинов (условный wildberries), фаст-фуда (Dodo, dominos, McDonnals) 62 | 63 | ## Управление пользователям 64 | Ключевые слова: `User Roles`, `User Permissions`, `User Management`, `User Access`, `Users` 65 | 66 | Обычно такая фича требуется в приложениях, в которых необходима некоторая иерархия 67 | 68 | Например, есть онлайн магазин (для покупателей). И есть отдельная онлайн страница для управления этим магазином - админка. 69 | 70 | ## Работа с картой 71 | Ключевые слова: `Map`, `Map integration`, `Map API`, `Geolocation`, `Location`. 72 | 73 | Приложения: `Yandex map`, `Google Maps`. Пять менее известных альтернатив: 74 | ``` 75 | If you need navigation, choose TomTom 76 | If you need accuracy, choose Mapfit 77 | If you need affordability, choose OpenLayers 78 | If you need map visualizations, choose * HERE 79 | If you need custom maps, choose Mapbox 80 | ``` 81 | 82 | ## Статистика, аналитика 83 | 84 | ## Платёжные системы 85 | Payments, Payment Systems 86 | 87 | ## Чат 88 | Ключевые слова: `Messaging`, `Chat`, `Communication`, `Messager` 89 | 90 | ## Новостная лента 91 | Ключевые слова: `Feed`, `news`, `news feed`, `news line` 92 | 93 | Чаще всего встречается в соцсетях. У некоторых соц. сетей является главной фичей (например, у Twitter, Instagram) 94 | 95 | ## Анимации 96 | 97 | ## Голосовой помошник 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /GraphQL-REST.md: -------------------------------------------------------------------------------- 1 | - [REST](#rest) 2 | - [GraphQL](#graphql) 3 | - [Преимущества GraphQL](преимущества-graphql) 4 | - [REST на практике](#rest-на-практике) 5 | - [Данные в QUERY](#данные-в-query) 6 | - [Данные в BODY](#данные-в-body) 7 | - [Данные в PARAMS](#данные-в-params) 8 | 9 | # REST 10 | 11 | TODO 12 | 13 | # GraphQL 14 | 15 | **GraphQL** — *язык запросов* (query language) для API. 16 | 17 | Клиент посылает **запрос** (query) к сервису GraphQL и получает ответ в виде JSON-объекта по указанной в запросе схеме. 18 | 19 | Например, клиент может послать запрос. 20 | ```Graphql 21 | query { 22 | currentUser { 23 | id 24 | username 25 | role 26 | } 27 | } 28 | ``` 29 | Если сервер позволяет получить данные по заданной выше схеме, по клиенту придёт ответ, соответствующий этой схеме. 30 | ```json 31 | { 32 | "data": { 33 | "currentUser": { 34 | "id": "1", 35 | "username": "Notes", 36 | "role": "Admin" 37 | } 38 | } 39 | } 40 | ``` 41 | 42 | ## Запросы query и mutation 43 | 44 | Существуют два типа запросов (requests): *query* и *mutation*. 45 | 46 | **Запрос query** отвечает за получение данных, он не может их изменять (аналог GET-запроса в REST). 47 | ```Graphql 48 | query { 49 | users { 50 | id 51 | username 52 | } 53 | } 54 | ``` 55 | 56 | **Запрос mutation** отвечает за изменение данных (объединяет в себе возможности POST, PUT, DELETE и других в REST). 57 | ```Graphql 58 | mutation { 59 | logOut 60 | } 61 | ``` 62 | ## Схемы и типы 63 | 64 | Все поля, которые может получить клиент, должны быть описаны в **типе** (type). 65 | 66 | Типы `Query` и `Mutation` являются типами по умолчанию. В них должны быть описаны все возможные запросы. 67 | 68 | ```Graphql 69 | type Query { 70 | currentUser: User 71 | } 72 | 73 | type Mutation { 74 | logOut 75 | } 76 | ``` 77 | ```Graphql 78 | schema { 79 | query: Query 80 | mutation: Mutation 81 | } 82 | ``` 83 | Могут создаваться пользовательские типы. 84 | ```Graphql 85 | type User { 86 | id: ID 87 | username: String 88 | role: String 89 | image: String 90 | } 91 | ``` 92 | 93 | Если схема в запросе с клиента не удовлетворяет схеме на сервере, то возникнет валидационная ошибка. Например, поле `age` отсутствует в типе `User`. 94 | ```json 95 | { 96 | "data": null, 97 | "errors": [ 98 | { 99 | "...": "...", 100 | "message": "Validation error of type FieldUndefined: Field 'age' in type 'User' is undefined 101 | } 102 | ] 103 | } 104 | ``` 105 | 106 | ### Динамические объекты в GraphQL 107 | 108 | GraphQL не позволяет создавать динамические объекты в качестве `type`. 109 | 110 | Примеры динамических объектов. 111 | ```js 112 | const commentsMap = { 113 | 123: { 114 | id: "123", 115 | message: "Hello" 116 | }, 117 | 456: { 118 | id: "456", 119 | message: "Hi" 120 | } 121 | }; 122 | ``` 123 | ```js 124 | const reportsInfoMap = { 125 | spam: ["id1", "id2"], 126 | flood: [], 127 | bullying: ["id3"] 128 | } 129 | ``` 130 | ```js 131 | const flags = { 132 | isReviewed: true, 133 | isVisited: true, 134 | /* ... */ 135 | } 136 | ``` 137 | 138 | Есть два решения, как это можно обойти 139 | * Передавать объекты текстовый как JSON и указывать встроенный тип `String` (не лучшая валидация) или подключить библиотеку, которая имеет скалярный тип JSON (например, [эту](https://github.com/taion/graphql-type-json)). Например, *AWS AppSync* имеет встроенный тип `AWSJSON`. 140 | ```GraphQL 141 | type Res { 142 | commentsMap: String 143 | reportsMap: JSON 144 | flags: AWSJSON 145 | } 146 | ``` 147 | * Представить объекты в виде массивов (предпочтительный вариант). 148 | ```GraphQL 149 | 150 | type Comment { 151 | id: ID 152 | message: String 153 | } 154 | 155 | type ReportsInfo { 156 | name: String 157 | values: [ID] 158 | } 159 | 160 | type Flag { 161 | name: String 162 | value Boolean 163 | } 164 | 165 | type Res { 166 | commentsMap: [Comment] 167 | reportsMap: [ReportsInfo] 168 | flags: [Flag] 169 | } 170 | ``` 171 | 172 | 173 | ## Взаимодействие с сервером 174 | 175 | ### Отправка query 176 | ```GraphQL 177 | query Users { 178 | users { 179 | id 180 | username 181 | role 182 | } 183 | } 184 | ``` 185 | 186 | ### Query с переменными 187 | ```GraphQL 188 | query User($userId: ID!) { 189 | user(userId: $userId) { 190 | id 191 | username 192 | role 193 | } 194 | } 195 | ``` 196 | `Variables` 197 | ```json 198 | { 199 | "userId": "auth0|72d45e398924235638341891" 200 | } 201 | ``` 202 | 203 | ### Query с input 204 | ```graphql 205 | query QueryLeaders($credentialsInput: Credentials) { 206 | login(credentials: $credentialsInput) { 207 | auth_token 208 | } 209 | } 210 | ``` 211 | 212 | `Variables` 213 | ```json 214 | { 215 | "credentialsInput": { 216 | "username": "admin", 217 | "password": "admin" 218 | } 219 | } 220 | ``` 221 | 222 | 223 | 224 | ## Преимущества GraphQL 225 | 226 | * *Строгая типизация*. Конкретная схема, полностью описывающая, как можно работать с данными. 227 | ```gql 228 | type User { 229 | id: ID! 230 | username: String! 231 | } 232 | 233 | type Article { 234 | id: ID! 235 | title: String! 236 | description: String 237 | author: User! 238 | } 239 | 240 | type Query { 241 | articles: [Article] 242 | article(id: ID!): Article 243 | } 244 | ``` 245 | * Клиент всегда запрашивает только то, что ему нужно. Он не может получить те поля, которые не запрашивал, ровно как и те, которые не предусмотрены описанной схемой. 246 | 247 | Следующий запрос вернёт `articles`, содержащие только поля `id` и `title`. Все эти поля должны присутствовать в схеме запроса на бэкенде (описана выше), иначе будет ошибка. 248 | ```gql 249 | query { 250 | articles { 251 | id 252 | title 253 | } 254 | } 255 | ``` 256 | * Один запрос может объединять в себе несколько различных ресурсов. 257 | 258 | Следующий запрос объединяет в себе информацию, собранную из `Articles` и `Users`. 259 | ```gql 260 | query { 261 | articles { 262 | id 263 | title 264 | description 265 | author { 266 | id 267 | username 268 | } 269 | } 270 | } 271 | ``` 272 | 273 | # REST на практике 274 | 275 | ## Данные в QUERY 276 | * Форма запроса на клиенте. 277 | ```http 278 | GET /route?field=value&anotherField=anotherValue 279 | ``` 280 | ```js 281 | /* axios */ 282 | axios.get('/route', { 283 | params: { 284 | field: 'value', 285 | anotherField: 'anotherValue', 286 | }, 287 | }); 288 | ``` 289 | * Форма запроса на сервере. 290 | ```http 291 | GET /route 292 | ``` 293 | * Получение данных из запроса на сервере. 294 | ```js 295 | /* Express */ 296 | app.get('/route', (request, response) => { 297 | const { field, anotherField } = request.query; 298 | }); 299 | ``` 300 | 301 | Передача массива `arr [1, 3, 7]` с клиента. 302 | ```http 303 | GET /route?arr[]=1&arr[]=3&arr[]=7 304 | ``` 305 | Передача объекта `obj { foo: '1', bar: '7' }` с клиента. 306 | ```http 307 | GET /route?obj[foo]=1&obj[bar]=7 308 | ``` 309 | 310 | ## Данные в BODY 311 | * Форма запроса на клиенте. 312 | ```http 313 | POST /route 314 | Content-Type: application/json 315 | 316 | { "field": "value", "anotherField": "anotherValue" } 317 | ``` 318 | ```js 319 | /* axios */ 320 | axios.post('/route', { 321 | field: 'value', 322 | anotherField: 'anotherValue', 323 | }); 324 | ``` 325 | * Форма запроса на сервере. 326 | ```http 327 | POST /route 328 | ``` 329 | * Получение данных из запроса на сервере. 330 | ```js 331 | /* Express */ 332 | app.post('/route', (request, response) => { 333 | const { field, anotherField } = request.body; 334 | }); 335 | ``` 336 | 337 | ## Данные в PARAMS 338 | * Форма запроса на клиенте. 339 | ```http 340 | GET /route/paramValue 341 | ``` 342 | ```js 343 | /* axios */ 344 | axios.get(`/route/${paramValue}`); 345 | ``` 346 | * Форма запроса на сервере. 347 | ```http 348 | GET /route/:param 349 | ``` 350 | 351 | * Получение данных из запроса на сервере. 352 | ```js 353 | /* Express */ 354 | app.post('/route/:param', (request, response) => { 355 | const { param } = request.params; 356 | }); 357 | ``` 358 | 359 | Пример отправки нескольких параметров. 360 | ```http 361 | PATCH /users/17/name 362 | PATCH /users/:id/:field 363 | ``` 364 | -------------------------------------------------------------------------------- /InterviewQuestions.md: -------------------------------------------------------------------------------- 1 | # Бэкграунд, проверка общих знаний, фундамента 2 | 3 | ## Математика 4 | - Что такое множество? 5 | - Что такое кортеж? 6 | - Что такое декартово произведение? 7 | 8 | ## Алгоритмы и структуры данных 9 | - Какие структуры данных вы знаете? Что такое очередь, стэк, FIFO, LIFO? 10 | - Что такое хэш? Хэш-таблица? 11 | - Что такое граф? 12 | - Как вы понимаете понятие трудоёмкость или временная сложность алгоритма? Как она вычисляется? Какова трудоёмкость поиска элемента в массиве? В хэш-таблице? 13 | 14 | 17 | 18 | ## Компьютерные сети 19 | - Что такое протокол? Какие протоколы вы знаете? 20 | - Расскажите про HTTP протокол. Что такое клиент, сервер, как они взаимодействуют? 21 | - Из чего состоит HTTP-запрос? 22 | - Какие методы HTTP вы знаете? Какие из них имеют BODY? Какие нет? 23 | - Чем отличаются GET и POST? 24 | - Чем отличаются PUT и PATCH? 25 | - Что такое идемпотентность? Какие методы считаются идемпотентными? 26 | - Что такое API? 27 | - Что такое REST API и зачем он нужен? 28 | - Какие группы статус-кодов вы знаете? Расскажите в двух словах про каждую из групп 1xx, 2xx, 3xx, 4xx, 5xx. 29 | - Чем отличаются REST и GraphQL? 30 | - Слышали ли вы что-нибудь про GRPC? Чем он отличается от REST и GraphQL? 31 | - Какие библиотеки и встроенные методы используются для обработки HTTP-запросов на стороне клиента? Какие на стороне сервера? 32 | - Что вы знаете об HTTPS? Об TCP/IP? 33 | - Чем отличаются протоколы TCP и UDP? 34 | - Что вам известно о доменной системе имён DNS? Как она работает на примере сайта `development.starling.com`? 35 | 36 | ## Операционные системы 37 | - Чем отличается RAM и ROM память? 38 | - Что такое поток? 39 | - Что такое однопоточность и многопоточность? Какие у них плюсы и минусы? 40 | - Какие проблемы встречаются при многопоточность? Что вы знаете о состоянии гонки? Что происходит, когда два потока обращаются к одному ресурсу одновременно? Какие есть способы решения проблемы? 41 | 42 | ## Разработка 43 | - Из каких этапов состоит разработка? 44 | - Какие специальности в IT-сфере вы знаете, за что они отвечают? 45 | 46 | ## Программирование 47 | - Что такое польская нотация? Обратная польская нотация? 48 | - Что такое конкатенация строк? 49 | - Зачем нужны регулярные выражения? Как с ними работать? 50 | - Что такое указатель? Какой размер он имеет? Что можно делать с указателями? 51 | - Что такое синтаксис? Что такое семантика? Чем они отличаются? 52 | 53 | # Узконаправленные темы 54 | 55 | ## Git 56 | - Что такое система контроля версий и зачем она нужна на проекте? Почему будет трудно писать код без неё? 57 | - Что такое коммит? Как сделать коммит? 58 | - Какие команды Git ты помнишь? Как переключиться на другую ветку? 59 | - Зачем нужен команда git stash? 60 | - Как работает Git? Что такое дельта изменений? Чем отличается Git от своих альтернатив? 61 | - Чем отличается git pull и git fetch? 62 | - Чем отличается git merge и git rebase? 63 | - Какие существуют стратегии merge в Git? 64 | - Что такое Git flow и как он работает? Что такое environment? Какие environments ты знаешь? 65 | 66 | ## HTML 67 | - Какая сейчас версия HTML используется? Чем отличается от предыдущих версий? 68 | - С чего начинается HTML-документ? Что такое Doctype и зачем он нужен? Что содержит `dtd` файл? 69 | - Зачем нужны семантические теги? Какие семантические теги вы знаете? Почему нельзя просто всегда использовать `
`? 70 | - Из каких блоков состоит HTML? 71 | - Что размещается в блоке head? 72 | - Где стоит хранить css: в head или body? Аналогичный вопрос касается скриптов. 73 | - Как сделать так, чтобы скрипты загружались параллельно? Можно ли сделать так, чтобы один скрипт дожидался выполнения другого? Если да, то каким образом? 74 | - Какие типы HTML-элементов ты знаешь? Чем отличаются блочные и строчные элементы? 75 | 76 | ## CSS 77 | - Как переводится CSS? Что такое каскад? Как работает алгоритм каскада, из каких этапов состоит? 78 | - Что такое специфичность? Как её вычислить? Покажите на примере. 79 | - Что такое наследование в CSS? Какие свойства наследуются, а какие нет? Имеет ли наследование специфичность? 80 | - Что такое CSS Box model. 81 | - Что такое z-index и как с ним работать? На каких элементах он работает? 82 | - Как зафиксировать элемент на экране? 83 | - Какими способами можно позиционировать элемент по центру? 84 | - Какая самая большая проблема в CSS? Есть ли область видимости в CSS? Что вы знаете о CSS Modules? 85 | - Что такое BEM? Зачем нужны методологии в CSS? Какие из них вы знаете? 86 | - Что такое SCSS/SASS/LESS? Что такое постпроцессоры и препроцессоры? 87 | - Какие типы вёрстки вы знаете? Чем отличается респонсив и адаптивная вёрстка? Посредством чего в CSS они реализуются? 88 | - Что такое viewport и viewport values 89 | - Как высчитывается em и rem? Чем они отличаются? 90 | 91 | 92 | ## JavaScript 93 | - Как вы охарактеризуете язык JavaScript? 94 | - Охарактеризуйте типизацию языка JavaScript. 95 | - Расскажите про события в JavaScript? Как работает Event Loop? Что такое таски и микротаски? Чем они отличаются и какие вы из них знаете? 96 | - Что вам известно про область видимости (Scope), замыкание (Closure), Lexical environment? 97 | - Какие примитивные типы данных есть в JavaScript? 98 | - Как вы понимаете фразу: функция - это объект в JavaScript. Виды функций и их различия. 99 | - Какие парадигмы есть в JavaScript? Как использовать ООП, классы в JavaScript? 100 | - Что вы знаете о прототимном наследовании в JavaScript? Что такое прототип, скрытое свойство `__proto__`? 101 | - Что такое ключевое слово `this`? Где оно встречается в JavaScript? 102 | - Как можно явно привязать контекст? Чем отличаются методы `apply`, `call` и `bind` 103 | - Зачем нужен тип данных `Symbol`? 104 | - Какие методы массивов вы знаете? Какие из них изменяют исходный массив, а какие возвращают копию? 105 | - Что такое асинхронность в JavaScript? 106 | - Что такое функция обратного вызова (`callback`)? Какую роль эта функция выполняет? 107 | - За что отвечает встроенный объект `Promise`? Какие состояния есть у промисса? Как навешивать обработчики на `Promise`? Что такое `Promise Chaining`? 108 | - Что такое `async/await` и чем он принципиально отличается от `Promise`? Что возвращает функция с пометкой async? 109 | - Зачем нужен `eval` в JavaScript? Стоит ли его использовать? 110 | - Что такое строгий режим (`"use strict"`) в JavaScript? Зачем он нужен? 111 | 112 | ## JavaScript DOM 113 | - Что такое DOM? В виде какой структуры данных он представляется? 114 | - Что такое Selector API в JavaScropt? Какие методы этого API вы знаете? 115 | - Производительно ли работать с DOM? 116 | - Зачем нужен jQuery? Что можно с ним делать? 117 | - Как подписаться на событие пользователя? Как работать с addEventListener? Как отписаться от события? 118 | - Что такое всплытие (hoisting) и погружение (capturing)? Как с ними работать? Зачем нужен третий параметр addEventListener? 119 | - Зачем нужны методы event.preventDefault и event.stopPropagation? 120 | 121 | ## Browser 122 | - Что происходит, когда вы что-то вводите в поисковое окно 123 | - Что такое Critical Rendering Path и из чего он состоит 124 | - Что такое совместимость? 125 | - Что такое полифилл? 126 | - Какие инструменты есть в Chrome Dev Tools? 127 | - Чем отличаются LocalStorage от IndexedDB, от Session Storage? 128 | ![image](https://user-images.githubusercontent.com/22237384/165200922-6b595629-0f35-4d06-9b0b-7a8fc5fe81e8.png) 129 | - Может ли браузер понимать SCSS, TypeScript? Что такое трайспайлер? Babel? 130 | 131 | ## React 132 | - Что такое React? Для чего используется? За что отвечает? 133 | - Чем отличаются фреймворк и библиотека? React - фреймворк или библиотека? 134 | - Как вы понимаете component-based подход? 135 | - Какие принципы React вы можете выделить? 136 | - Что такое JSX? Можно ли написать React-приложение без JSX? 137 | - Может ли браузер понимать JSX? Если нет, то что нужно для того, чтобы превратить JSX в JS? Что вы знаете о транспайлерах, о Babel? 138 | - Что такое состояние? Какими способами можно управлять состоянием в React? 139 | - Чем отличаются функциональный и классовый компонент? 140 | - Что такое жизненный цикл и хуки жизненного цикла? Жизненный цикл классового компонента. Как вы понимаете слово mounting? 141 | - React Hooks. Что это такое, зачем нужны, как работают под капотом. Какие хуки вы знаете? Какие доводилось использовать и для чего? 142 | - Что такое мемоизация? Чем отличаются memo, useMemo, useCallback? 143 | - Что такое High Order Component (HOC)? С какими HOC-ами вам доводилось иметь дело? 144 | - Что такое композиция? Пример композиции в React. Сравнение композиции и наследования. 145 | - Чем отличается useState и this.setState? 146 | - Зачем нужно передавать callback в this.setState? Почему state в React обновляется асинхронно? 147 | - Что вы знаете о Context API? 148 | - Зачем нужны порталы в React? 149 | - Что вы знаете о Virtual DOM? Зачем он нужен? Как работает? 150 | - Что такое PropTypes и зачем они нужны? 151 | - Что и когда лучше: React Hooks + Context или Redux? Когда можно избежать использования Redux? 152 | - Можно ли использовать TypeScript и React вместе? Доводилось ли вам это делать? 153 | 154 | ## Redux 155 | - Что такое состояние в приложении? Зачем нужны инструменты для управления состоянием? 156 | - Назовите три основных принципа Redux. 157 | - Жизненный цикл Redux. 158 | - Как подключить Redux Dev Tools? 159 | - Как использовать асинхронные функции в Redux? Что вы знаете о redux-thunk и redux-saga. 160 | - Что такое middleware? 161 | - Всегда ли нужно использовать Redux? Когда стоит его использовать и когда не стоит? 162 | 163 | ## NodeJS 164 | - Что такое NodeJS? Охарактеризуйте его. 165 | - Как работает Event Loop в рамках NodeJS. 166 | 167 | ## Базы данных 168 | - Чем отличается SQL и NoSQL? 169 | - Что такое отношение в SQL? Что такое реляционная база данных? 170 | - Какие типы связей между отношениями вы знаете в SQL? 171 | - Что такое нормализация базы данных? Чем оно отличается от денормализации? Какие преимущества и недостатки у нормализации и денормализации бд? Какие нормальные формы вы знаете ? 172 | - Что такое транзакция? Какие принципы транзакций вы знаете? Что вы знаете об принципах ACID? Как работать с транзакциями в микросервисной архитектуре? Что вы знаете о паттерне Saga? 173 | - Какие типы операций в SQL вы знаете? 174 | - Напишите SQL-запрос, который выбирает работников с зарплатой > 1000$, группирует их по заданному критерию, а затем сортирует их. Зарплата и работники хранятся в разных таблицах, которые нужно предварительно соединить. 175 | - Что вы знаете об агрегационных функциях SQL? Какие из них знаете? Когда их можно применять? 176 | - Какие блоки вы знаете у метода aggregate в MongoDB? Зачем нужна проекция? 177 | - Что такое популяция? 178 | - Что такое ORM? С какими ORM доводилось работать? Зачем использовать ORM? 179 | - Какие движки баз данных вы знаете? 180 | - Что такое индексы? Зачем их используют? В каком виде хранятся индексы? 181 | 182 | ## TypeScript 183 | - Что такое статическая типизация? Чем она отличается от динамической? 184 | - Что такое компилятор? Зачем он нужен TypeScript? 185 | - Какие типы данных есть в TypeScript? Обязательно ли их указывать? 186 | - Чем отличается класс и интерфейс? Возможно ли множественное наследование в JavaScript/TypeScript? 187 | 188 | ## Парадигмы программирования 189 | - Какие парадигмы программирования вы знаете? 190 | - Почему JavaScript можно назвать мультипарадигменным языком программирования? 191 | - Что такое ООП? Что такое объект и класс? Приведите примеры из реальной жизни. 192 | - Какие принципы ООП знаете? Что такое наследование? 193 | - Какие паттерны ООП знаете? 194 | - Что такое композиция в ООП? Чем отличаются композиция и наследование? Что лучше использовать и когда? 195 | - Что такое SOLID? Раскройте смысл каждой буквы, приведите примеры. 196 | - Что вы знаете о функциональном программировании? 197 | - Что такое каррирование? 198 | - Что такое мемоизация? 199 | - Чем отличаются ФП и ООП? Когда и что лучше использовать? 200 | 201 | ## Тестирование 202 | - Что вы знаете о пирамиде тестирования? Из каких слоёв она состоит? Сколько и каких должно быть тестов на проекте? Приведите пример Unit-теста, интеграционного теста(API-теста), end-to-end теста. 203 | - Что такое подход TDD? Чем он отличается от BDD? С какими фреймворками для тестирования вам приходилось работать? 204 | - Какие паттерны тестирования вы знаете? Что такое загрушка? 205 | - Что такое регрессионное тестирование? Стоит ли его проводить и почему? 206 | - Как тестировать "чёрный ящик"? 207 | 208 | ## Паттерны, архитектуры и принципы программирования 209 | 210 | -------------------------------------------------------------------------------- /JavaScriptDOM.md: -------------------------------------------------------------------------------- 1 | 2 | # DOM 3 | 4 | # Всплытие и погружение 5 | 6 | # Обработка пользовательских событий 7 | 8 | ## Обработка данных формы 9 | ```html 10 |
11 | Name: 12 |
13 | Card Type: 14 | 21 |
22 | 23 |
24 | ``` 25 | ```js 26 | function handleSubmit(e) { 27 | e.preventDefault(); 28 | const formData = new FormData(e.target); 29 | const values = Object.fromEntries(formData); 30 | console.log(values); // { name: '...', cardType: '...' } 31 | } 32 | ``` 33 | ![image](https://user-images.githubusercontent.com/22237384/155226176-9895af8e-86c9-4ae9-a19e-7a4a5cdca933.png) 34 | ![image](https://user-images.githubusercontent.com/22237384/155226480-9a4ef714-8a1a-4051-90e7-0e8ce224588b.png) 35 | 36 | 37 | -------------------------------------------------------------------------------- /ProductQuality.md: -------------------------------------------------------------------------------- 1 | ## О чистоте кода 2 | 3 | ## О логировании 4 | 5 | **Лог** (англ. `log`, дословно *переводится* как *бревно*) - это *информация* о некотором *событии*, которое *произошло в системе*. 6 | 7 | **Логирование** (англ. `logging`) - это *написание логов*, то есть *вывод информации* о том, что *происходит* в *системе*. 8 | 9 | Пример *событий* в *системе*: "Сервер запущен", "База данных подключена", "Произошла ошибка", "Пришёл запрос с клиента", "Пользователь авторизировался" и так далее. 10 | 11 | Логи могут иметь любую структуру, которую определяет пишущий их человек. 12 | 13 | Например, самый примитивный лог предтавляет собой обычный текст 14 | ```log 15 | Server is running on PORT: 3000 16 | ``` 17 | Более продвинутый лог может содержать время с часовым поясом, имя файла или класса, тип события, текст и так далее 18 | ```log 19 | Jan 4, 2022 17:46:27 (UTCMSK) | index.js | SUCCESS | App is running on the port: 8080 20 | Jan 4, 2022 22:00:15 (UTCMSK) | dbContext.js | ERROR | Connection to MongoDB was interrupted! 21 | ``` 22 | 23 | Логи могут выводиться в консоли, записываться в базу данных или в файл. Поскольку события в системе происходят довольно часто, со временем логов может накопиться слишком много. Поэтому логи наделяют сроком годности (скажем, месяц), а затем удаляют их. 24 | 25 | **Логером** называют сервис, который позволяет записывать логи. Существует множество библиотек логеров, но его также несложно написать самому. 26 | 27 | Логирование очень важно, поскольку оно отражает историю событий в системе. Оно позволяет отслеживать любые интерисующие вас действия в системе. И при возникновении ошибки вы всегда можете знать, какое действие предшествовало этой ошибке и в чём ошибка заключалась. 28 | 29 | Всегда довольно неприятно, когда в какой-либо программе появляется ошибка, а в консоли пусто или написано что-то вроде `ERROR CODE 110050` без всяких пояснений и без возможности найти описание ошибки в интернете. Поэтому давайте писать подробные, отчётливые логи, которые будут понятны и помогут вам или вашему товарищу по проекту быстро найти и исправить проблему. 30 | 31 | ## Об аналитике 32 | 33 | Аналитика похожа на логирование тем, что работает с событиями, но она имеет немного другую цель. 34 | 35 | Логи нацелены на то, чтобы сохранить историю того, что происходило в системе. Аналитика направлена на то, чтобы отследить, какие действия были совершены пользователем. 36 | 37 | Логи становятся бесполезными через некоторый, достаточно короткий промежуток времени. Аналитика, наоборот, стремится получить статистику действий пользователей: на какие страницы заходят чаще, какие товары чаще просматриваются и покупаются, какие кнопки больше всего кликаются. Эта статистика позволяет бизнесу понять, что пользователям интереснее всего. На основании этой статистики можно делать рекламу, предложения пользователю. 38 | 39 | Если на проекте используется Server Side Rendering (SSR), то аналитика может подсказать, какие страницы стоит загрузить в первую очередь, поскольку велика вероятность, что именно на них пользователь зайдёт скорее всего (а время отклика играет большую роль, когда речь идёт о вебсайтах). 40 | 41 | ## Об отладке 42 | 43 | ## О валидации 44 | 45 | ## О тестировании 46 | 47 | Автоматизированное тестирование подобно лабораторным анализам или техосмотру. 48 | 49 | 50 | 51 | Действительно, врачи советуют в качестве профилактики многих заболеваний ежегодно сдавать некоторые примитивные лабораторные анализы и не менее базовые обследования (анализ крови, УЗИ, флюрография и так далее). Эти анализы и обследования позволяют убедиться, что с вашим организмов сейчас всё в норме. 52 | 53 | Водителям необходимо проходить ежегодный техосмотр, который позволяет убедиться, что ничего страшного с техникой за год не произошло и можно смело продолжать на ней ездить. 54 | 55 | Чем быстрее вы находите отклонение в вашем организме или неисправность в вашей технике, тем больше шансов, что вы сможете исправить её с малыми затратами. 56 | 57 | И далеко не всегда такие вещи можно рассмотреть невооружённым глазом, иногда требуется специальное оборудование, некоторый инструмент. 58 | 59 | 60 | 61 | Когда дело касается приложений, таким инструментом выступают автоматизированные тесты. Они позволяют проверить, соответствует ли приложение всем указанным требованиям на данный момент. 62 | 63 | Чем шире покрытие приложения тестами, чем детальнее тесты описывают требования бизнеса, тем больше шансов быстро и безболезненно найти и устранить отклонение в коде. 64 | 65 | Когда вы приступаете к написанию тестов, вы начинаете продумывать все возможные варианты (англ. `edge cases`), исходы, случаи. И на каждый случай пишете отдельный тест. Затем все тесты запускаются последовательно. И те, которые провалились, указывают на проблему. 66 | 67 | 68 | 69 | Это тем более важно, поскольку каждый новый кусочек кода может непредсказуемо повлиять на весь предыдущий код. Чем больше кода написано за всё время, тем больше потенциальных багов и тем больше времени необходимо на поиск бага (дебаг). И чтобы не проверять каждый раз все возможные случаи вручную, достаточно один раз их описать в виде тестов и время от времени их запускать (или настроить автоматический запуск тестов при каждом пуше или деплое). 70 | 71 | 72 | 73 | 74 | 75 | 77 | 78 | 79 | 80 | 81 | ## Об обработке ошибок 82 | 83 | ## О безопасности 84 | 85 | Следует помнить, что под безопасностью подразумевается не только безопасность приложения, но и безопасность любого пользователя, которому довелось это приложение использовать. 86 | 87 | **Безопасность** (англ. `safety`) - состояние защищённости кого-либо или чего-либо. 88 | 89 | Приложение в безопасности, если злоумышленники не могут подвернуть его взлому. 90 | 91 | Приложение безопасно для пользователя, если данные пользователя, который пользуется данным приложением, находятся в безопасности и не могут быть украдены ни создателем сайта, ни злоумышленниками. 92 | 93 | Безопасность является довольно обширной темой, которая в каждом приложении раскрывается по-разному, но я постараюсь привести список довольно часто встречающихся моментов. 94 | 95 | ### Некоторые общие правила безопасности 96 | 1) Не храните важные данные (пароли, ключи, номера карточек и так далее) в Local Storage. 97 | 2) Если в системе есть логгирование, следует отключить логирование тех параметров запросов, которые содержат введённые имя пользователя и пароль. 98 | 3) Не храните ключи, пароли и другие важные данные в константах, в свойстве `scripts` . Используйте для этих нужд `dotenv` или другие библиотеки, работающие с переменными окружения. 99 | 4) Регулярно делайте `npm audit`, обновляйте пакеты, в которых были обнаружены уязвимости. 100 | 5) Не сохраняйте пароль пользователя в явном виде в базу данных. Вместо этого сохраняйте хэш, который получается из настоящего пароля и соли при использовании `bcrypt`. 101 | 6) Не позволяйте пользователям системы выбирать пароль, состоящий менее, чем из 8 символов латинского алфавита. Такие пароли будет сложнее подобрать. 102 | 7) Для аутентификации/авторизации старайтесь использовать сторонние сервисы (например, Auth0, Google Sign-In, Github и другие). При соблюдении требуемых этими сервисами условий вы можете быть уверены, что ваши пользователи находятся в безопасности. 103 | 8) Используйте протокол HTTPS вместо HTTP, если сайт находится в публичном доступе (доступен не через localhost). HTTPS шифрует данные тела запроса, что не позволяет злоумышленникам перехватить ценную информацию. 104 | 9) Не используйте формат `md5` для шифрования каких-либо важных данных. Этот формат можно с лёгкостью перевести в обычный текст, не имея при этом никакого ключа. Для этого существует множество сервисов в интернете. 105 | 10) Не используйте примитивные пароли для админки приложения (по типу `admin - admin`, `admin - qwerty12345789`, `username - password`) 106 | 11) По возможности используйте двухфакторную аутентификацию. Так, если злоумышленник украдёт или подберёт ваш пароль, он всё равно не сможет войти без телефона, который будет всегда при вас. 107 | 108 | ## 109 | -------------------------------------------------------------------------------- /Programming.md: -------------------------------------------------------------------------------- 1 | 2 | - [Работа со строками](#работа-со-строками) 3 | - [Регулярные выражения](#регулярные-выражения) 4 | - [Семиотика, синтаксис и семантика](#семиотика-синтаксис-и-семантика) 5 | 6 | # Работа со строками 7 | - [Конкатенация](#конкатенация) 8 | 9 | ## Конкатенация 10 | 11 | # Регулярные выражения 12 | - [О регулярных выражениях](#о-регулярных-выражениях) 13 | - [Классы символов](#классы-символов) 14 | 15 | ## О регулярных выражениях 16 | 17 | **Регулярное выражение** (англ. `regular expression`, `regex`, `regexp`) - это **поисковый шаблон** (англ. `search pattern`), который *позволяет* по *заданным* в нём *правилам* *найти подстроку* (некоторую *последовательность символов*) в некоторой *строке*. 18 | 19 | Таким образом, *основной целью использования регулярного выражения* является *проверка на соответствие* (англ. `match`) некоторой *строки заданному шаблону*. 20 | 21 | Для *написания поискового шаблона* используется специальный *формальный язык*, который *поддерживается* во многих *системах* и *языках программирования*. 22 | 23 | ### Регулярное выражение позволяет задавать в шаблоне 24 | * *конкретные символы* алфавита, 25 | * *класс символов* (цифры, буквы, знаки пунктуации), 26 | * *промежуток символов*, которые должны быть *включены* в поиск или должны быть *исключены* из него, 27 | * *количество символов заданного вида*, 28 | * *логические условия* и многое другое. 29 | 30 | Всё это мы *рассмотрим далее* на *примерах*. 31 | 32 | ### Когда регулярные выражения могут быть полезны 33 | * при *поиске*: для *включения* удовлетворяющих шаблону *строк* в некоторую *выборку* 34 | * при *валидации* строки: проверка сложность пароля, проверка правильности введённого номера телефона или электронной почты 35 | * при *необходимости обрабатывать строку по-разному* в *зависимости* от того, что она *содержит*. 36 | 37 | ### Простейшее регулярное выражение 38 | Подобно тому, как *строки* обычно *заключаются* в *одинарные*, *двойные* или *косые ковычки*: 39 | ```javascript 40 | 'hello' 41 | "hi" 42 | `welcome` 43 | ``` 44 | *регулярные выражения размещают между двумя косыми чертами* `/` (англ. `slash`): 45 | ```regex 46 | /hey/ 47 | ``` 48 | Это *позволяет интерпретатору (компилятору) отличить регулярное выражение* от *других выражений*. 49 | 50 | *Самим простым поисковым шаблоном* является *конкретная последовательность символов*. 51 | 52 | Например, выясним, *какие* из *указанных строк содержат подстроку* `"ay"`. *Регулярное выражение* примет вид `/ay/`. 53 | ```js 54 | 'Ray Palmer'.match(/ay/); // ['ay', index: 1] (начинается с 1-ого символа) 55 | 'Dorian Gray'.match(/ay/); // ['ay', index: 9] (начинается с 9-ого символа) 56 | 'Max Starling'.match(/ay/); // null (соответствий не найдено) 57 | ``` 58 | 59 | ## Перечисление допустимых символов 60 | 61 | ### Перечисление символов 62 | 63 | Регулярное выражение позволяет *перечислить допустимые символы*. Для этого используются **квадратные скобки** `[]` (англ. `square brackets`. *Читается* как *"любой символ из символов ..."*. 64 | 65 | Например, 66 | * регулярному выражению `[abc]` удовлетворяет каждый из символов `a`, `b`, `c` и никакой другой символ, 67 | * регулярному выражению `[13579]` удовлетворяют только символы `1`, `3`, `5`, `7`, `9` 68 | ```js 69 | 'May'.match(/[abc]/) // ['a', index: 1] 70 | '#ff00ff'.match(/[0123456789]/) // ['0', index: 2] 71 | ``` 72 | 73 | ### Исключение перечисленных символов 74 | 75 | Для *исключения* из *регулярного выражения символов* используется символ **карет** `^` (англ. `caret`) *внутри квадратных скобок*. *Читается* как *"любой символ кроме символов из интервала"*. 76 | 77 | ### Включение символа из интервала символов 78 | 79 | Для *включения* в *регулярное выражение* *символов* из *некоторого интервала символов* используется символ `-` (англ. hyphen) внутри *квадратных скобок*. *Читается* как *"любой символ из интервала ..."*. 80 | 81 | Например, 82 | * *регулярное выражение* `/[0-9]/` *удовлетворяет любому* из *символов* `0, 1, 2, 3, 4, 5, 6, 7, 8, 9` (то есть *любой цифре*), 83 | * *регулярное выражение* `[A-Z]` - *любой большой букве латинского алфавита*, 84 | * *регулярное выражение* `[a-z]` - *любой маленькой букве латинсткого алфавита*, 85 | * а *выражение* `[А-я]` - *любой букве* (*большой* или *маленькой*) русского алфавита* 86 | ```js 87 | 'Hello'.match(/[A-Z]/) // ['H', index: 0] 88 | 'Hi'.match(/[a-z]/) // ['i', index: 1] 89 | 'Hey'.match(/[0-9]/) // null 90 | 'Greetings user2000'.match(/[0-9]/) // ['2', index: 14] 91 | ``` 92 | 93 | ### Исключение символа из интервала символов 94 | 95 | Для *исключения* из *регулярного выражения символов* из *некоторого интервала* так же используется символ **карет** `^` (англ. `caret`). 96 | 97 | Например, 98 | ```js 99 | 'Greetings user2000'.match(/[^0-9]/) // ['G', index: 0] 100 | 101 | '15,000 dollars'.match(/[0-9]/) // ['1', index: 0] 102 | '15,000 dollars'.match(/[^0-9]/) // [',', index: 2] 103 | 104 | 'GitHub'.match(/[^A-z]/) // null 105 | ``` 106 | 107 | ### Комбинация перечислений символов 108 | 109 | Например, *регулярное выражение* `[A-Za-z0-9]` удовлетворяет *любой букве латинского алфавита или цифре*, а *регулярное выражение* `[^A-Za-z0-9]` удовлетворяет *любому символу*, который *не является буквой латинского алфавита и числом*. 110 | ```js 111 | "Hey! How is it going?".match(/[A-Za-z0-9.]/) // ['H', index: 0] 112 | "Hey! How is it going?".match(/[^A-Za-z0-9]/) // ['!', index: 3] 113 | ``` 114 | 115 | 116 | ## Классы символов 117 | 118 | **Классы символов** (англ. `character classes`) чем-то *напоминают типы данных*: они ограничивают область допустимых значений (в данном случае, область допустимых символов). 119 | 120 | # Семиотика, синтаксис и семантика 121 | 122 | Говоря простыми словами, **язык программирования** - это средство коммуникации между программистом и компьютером. С помощью него программист может "рассказать" компьютеру, что нужно сделать (исполнить, выполнить) последнему. 123 | 124 | В любой системе, где используются знаки, выделяют 125 | 126 | Рассматривая любую знаковую систему (в том числе и язык программирования), обычно выделяют синтаксис -- правила построения сообщений в этой системе, семантику -- правила истолкования сообщений тем, кому они адресованы, а также прагматику, сопоставляющую сообщения желаниям того, от кого они исходят. 127 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Заметки программиста 2 | 5 | 6 | Мои *конспекты* обо *всём*, что связано с *информационными технологиями* (англ. `information technology`, `IT`), *программированием* и *смежными* ему *областями*. 7 | 8 | ## Оглавление 9 | - [Почему я решил всё это написать](#почему-я-решил-всё-это-написать) 10 | - [Как подготовиться к собеседованию по этим заметкам](#как-подготовиться-к-собеседованию-по-этим-заметкам) 11 | - [Общая теория](#общая-теория) 12 | - [Дискретная математика](#дискретная-математика) 13 | - [Информация и данные](#информация-и-данные) 14 | - [Типы данных](#типы-данных) 15 | - [Структуры данных и алгоритмы](#структуры-данных-и-алгоритмы) 16 | - [Модели данных и базы данных](#модели-данных-и-базы-данных) 17 | - [Программирование](#программирование) 18 | - [Тестирование](#тестирование) 19 | - [Архитектурные стили и архитектурные паттерны](#архитектурные-стили-и-архитектурные-паттерны) 20 | - [Паттерны проектирования и принципы проектирования](#паттерны-проектирования-и-принципы-проектирования) 21 | - [Технологии, библиотеки, фреймворки и языки программирования](#технологии-библиотеки-фреймворки-и-языки-программирования) 22 | - [CSS](./CSS.md) 23 | - [Docker](./Docker.md) 24 | - [Elasticsearch](./Elasticsearch.md) 25 | - [Git](./Git.md) 26 | - [JavaScript](./JavaScript.md) 27 | - [Сравнение Flux, Redux, Vuex и Mobx](./Flux-Redux-Vuex-Mobx.md) 28 | 29 | ## Почему я решил всё это написать 30 | 31 | Поскольку я *всей душой за Open Source*, я хочу в *открытом доступе поделиться* с *вами* всеми моими *познаниями*, *моим опытом*, *моим виденьем* всего, с чем мне *доводилось сталкиваться* за *последние годы работы*, что *можно было написать словами* и *о чём мне хотелось писать*. К данным *заметкам* я *стараюсь подходить* с *практической точки зрения*, поскольку *большая часть материалов* была *подготолена* на *основании теоритических* и *практических вопросов*, которые мне *доводилось встречать* как на *собеседованиях*, так и при *непосредственной работе* на *проектах*. 32 | 33 | > *Человеческая память* - это *самое ненадёжное хранилище информации*. 34 | 35 | *Никогда не знаешь, что и когда оттуда пропадёт*. *Ни в чём нельзя быть уверенным*, если *дело касается воспоминаний*. Как бы ты хорошо не разобрал какой-то материал, твоя уверенность в своих знаниях касательно него тает спустя несколько лет без практики, без перечитывания, возвращения к материалу. 36 | > *Самая лучшая память находится на кончике карандаша* 37 | 38 | > То, что нам *покорилось однажды*, обычно намного *проще* и *быстрее можно наверстать* по *сравнению* с тем, сколько *времени* и *сил* мы *затрачиваем на это* при *первом знакомстве*. 39 | 40 | Даже *если* порой *кажется*, что мы *забыли что-то безвозвратно*, *одно слабое упоминание*, *один мимолётный триггер* может *помочь восстановить почти достоверную картину*. 41 | 42 | Итак, *изначальная цель данного проекта* - это *сохранение моих мыслей, сравнений, умозаключений* в *моменты наивысшего подъёма* в *какой-либо области* (в *каком-либо домене*), когда и *основательнее всего подошёл* к *разбору материалов*. Это *позволяет* в *любой момент времени* (через неделю, месяц или даже через 5 лет) *практически мгновенно найти решение проблемы*, которую *я уже решал*, или *ответ на вопрос*, на который *мне уже доводилось отвечать* (*себе* или *кому-либо ещё*). *Ускоряет этот процесс* ещё и то, что *материал однороден* (ведь *всё написано одни человеком и на одном языке*) и *имеет структуру*, *оптимальную для повторения*. 43 | 44 | *В какой-то момент* я *осознал*, что этот *мысли и опыт можно запечатлить таким образом*, чтобы *их могли перенять и другие*. *С тех пор я всегда стараюсь придерживаться такой формы повествования*: *пишу не для себя* - *стараюсь писать доступно для всех*. 45 | 46 | ## Как подготовиться к собеседованию по этим заметкам 47 | 48 | [*Примерный список вопросов* по этим *конспектам* я *прикладываю* здесь](https://github.com/Max-Starling/Notes/blob/master/InterviewQuestions.md), чтобы *читатель* мог *проверить свои знания* и *убедиться*, что я *пишу многие материалы не просто так*, а потому что *такие вопросы уже встречались*. *Ответы будут прилагаться* в *виде ссылок* на *отдельные параграфы* из *заметок по мере их написания*. 49 | 50 | *Стоит* также *отметить*, что *некоторые вещи покоряются лишь с опытом, с практикой, спустя некоторое время* (например, *абстракция*, *паттерны проектирования*, *принципы по типу SOLID*, *архитектуры приложений*). И это *не беда*, если у вас *сразу что-то постигнуть не получается*. Возможно, *время ещё не пришло*. *Главное* - *не стоит сдаваться* и *отчаиваться*. Просто *идите вперёд так, как можете и умеете сейчас*! А я *постараюсь облегчить* этот *путь* так, как только смогу. 51 | 52 | ## Общая теория 53 | 54 | ### [Дискретная математика](./DiscreteMath.md) 55 | ***«Дискретная математика*** занимается *изучением* ***дискретных** (конечных) математических **структур*** - таких *структур*, *количество элементов* которых *конечно*, а значит эти *элементы* *можно пересчитать, перечислить*. Из-за *ограниченности ресурсов* *компьютера* на нём *можно реализовывать (рассматривать) только дискретные структуры*. Именно эти *структуры* легли в *основу компьютера*, стали *фундаментом* при его *создании»*. 56 | 57 | - [Введение](./DiscreteMath.md#введение) 58 | - [Теория множеств](./DiscreteMath.md#теория-множеств) 59 | - [Теория мультимножеств](./DiscreteMath.md#теория-мультимножеств) 60 | - [Теория графов](./DiscreteMath.md#теория-графов) 61 | - [Математическая логика](./DiscreteMath.md#математическая-логика) 62 | - [Комбинаторика](./DiscreteMath.md#комбинаторика) 63 | 64 | ### [Информация и данные](./Data.md) 65 | 66 | 67 | 68 | *«Всё*, что мы *видим* и *слышим* каждый день, *несёт* в себе какую-то ***информацию***. По сути говоря, вся наша *жизнь связана* с *получением*, *обработкой* и *передачей информации*. ***Данные*** - это *цифровая оболочка* *информации*, *последовательность нулей и единиц*. *Представить информацию* как *данные означает* дать возможность *компьютеру обрабатывать её*. *Данные* могут быть *представлены текстом*, *изображением*, *видео*, *аудио* и *другими способами»*. 69 | - [Оглавление](./Data.md#оглавление) 70 | - [Информация и данные](./Data.md#информация-и-данные) 71 | - [Кодирование информации](./Data.md#кодирование-информации) 72 | - [Метаданные](./Data.md#метаданные) 73 | 74 | ### [Типы данных](./DataTypes.md) 75 | ***«Типом данных*** называют *множество допустимых значений* и *совокупность операций* над этими *значениями*. *Типы данных* позволяют *разбить разнородную информацию* на *несколько заданных типов* (строковый, числовой, логический, дата и другие типы). К *каждому типу* может *применяться* лишь *ограниченное множество операций* (например, *разность чисел*, *конкатенация строк* и так далее)*»*. 76 | - [О типе данных](./DataTypes.md#о-типе-данных) 77 | - [Классификация типов данных](./DataTypes.md#классификация-типов-данных) 78 | - [Логический тип](./DataTypes.md#логический-тип) 79 | - [Строковый тип](./DataTypes.md#строковый-тип) 80 | - [Символьный тип](./DataTypes.md#символьный-тип) 81 | - [Целочисленный тип](./DataTypes.md#целочисленный-тип) 82 | - [Число с плавающей точкой](./DataTypes.md#число-с-плавающей-точкой) 83 | - [Ссылка](./DataTypes.md#ссылка) 84 | - [Указатель](./DataTypes.md#указатель) 85 | 86 | ### [Структуры данных и алгоритмы]() 87 | - [Структуры данных](./DataStructures.md#структуры-данных) 88 | 89 | ### [Модели данных и базы данных]() 90 | 91 | - [Общие понятия баз данных](./DataModels-Databases.md#общие-понятия-баз-данных) 92 | - [Реляционная модель данных](./DataModels-Databases.md#реляционная-модель-данных) 93 | - [Масштабирование баз данных](./DataModels-Databases.md#масштабирование-баз-данных) 94 | 95 | ### [Программирование](./Programming.md) 96 | 97 | ### [Характеристики языков программирования](./ProgrammingLanguageCharacteristics.md) 98 | «*Не было бы смысла* в таком *количестве языков программирования*, если бы они *хотя бы немного не отличались* друг от друга. И дело *не только* в *синтаксисе* - *критериев сравнения* (***характеристик***) с годами выработалось очень *много*. *Не существует идеального языка* программирования (этакой *"серебрянной пули"*), превосходно *подходящего* под *каждый проект*. Наоборот, *язык должен выбираться* в *соответствии* с *техническими требованиями проекта*. И где *один язык прекрасно вписывается*, *реализуя все свои преимущества*, *другой проявляет* себя как нельзя *хуже из-за* своих *"узких мест"*, *ограничений*. В *данном разделе* мы детально рассмотрим *каждый* из *критериев сравнения*, чтобы вы могли *научиться описанию* и *сравнению языков программирования*, а также *принятию решения* о том, *какой язык подходит* больше именно *под нужды вашего текущего проекта*». 99 | - [О характеристиках языков программирования](./ProgrammingLanguageCharacteristics.md#о-характеристиках-языков-программирования) 100 | - [Типизация](./ProgrammingLanguageCharacteristics.md#типизация) 101 | - [Компилируемость и интерпретируемость](./ProgrammingLanguageCharacteristics.md#компилируемость-и-интерпретируемость) 102 | - [Потоки, однопоточность и многопоточность](./ProgrammingLanguageCharacteristics.md#потоки-однопоточность-и-многопоточность) 103 | - [Синхронность и асинхронность](./ProgrammingLanguageCharacteristics.md#синхронность-и-асинхронность) 104 | - [Кроссплатформенность и нативность](./ProgrammingLanguageCharacteristics.md#кроссплатформенность-и-нативность) 105 | - [Поддержка парадигм программирования](./ProgrammingLanguageCharacteristics.md#поддержка-парадигм-программирования) 106 | 107 | 108 | ### [Тестирование](./Testing.md) 109 | ***«Тестированием*** называют *процесс испытания* некоторого *продукта* с *целью проверки* *соответствия* *готовой реализации продукта* *первоначальным требованиям заказчика*. *Качественное тестирование* очень *важно* для *приложения*. *Хороший тестировщик продумывает все возможные* и *невозможные исходы* и *проверяет каждый* из них. *Без* такого *тестирования невозможно гарантировать корректность работы прилолжения*, а значит оно *может сломаться* в *любом месте* и в *любой момент времени»*. Здесь мы рассмотрим *подходы к тестированию*, *основные понятия* и *инстументы*, *используемые* при *тестировании* приложений. 110 | - [Зачем тестировать приложение](./Testing.md#зачем-тестировать-приложение) 111 | - [Тестирование и его разновидности](./Testing.md#тестирование-и-его-разновидности) 112 | - [Подходы к написанию тестов](./Testing.md#подходы-к-написанию-тестов) 113 | - [Тестовые объекты](./Testing.md#тестовые-объекты) 114 | - [Паттерны тестирования](./Testing.md#паттерны) 115 | 116 | 117 | ### [Архитектурные стили и архитектурные паттерны](./Architecture-Design.md) 118 | 119 | ### [Паттерны проектирования и принципы проектирования](./Architecture-Design.md) 120 | 121 | 122 | 135 | 136 | 137 | 138 | ## Технологии, библиотеки, фреймворки и языки программирования 139 | - [CSS](./CSS.md) 140 | - [Docker](./Docker.md) 141 | - [Elasticsearch](./Elasticsearch.md) 142 | - [Git](./Git.md) 143 | - [JavaScript](./JavaScript.md) 144 | - [Сравнение Flux, Redux, Vuex и Mobx](./Flux-Redux-Vuex-Mobx.md) 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /assets/3-tier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/3-tier.png -------------------------------------------------------------------------------- /assets/DNS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/DNS.png -------------------------------------------------------------------------------- /assets/EBI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/EBI.png -------------------------------------------------------------------------------- /assets/EBI_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/EBI_2.png -------------------------------------------------------------------------------- /assets/HMVC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/HMVC.png -------------------------------------------------------------------------------- /assets/Hzb_FIGWrqs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/Hzb_FIGWrqs.jpg -------------------------------------------------------------------------------- /assets/MVC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/MVC.png -------------------------------------------------------------------------------- /assets/MVP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/MVP.png -------------------------------------------------------------------------------- /assets/MVPVM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/MVPVM.png -------------------------------------------------------------------------------- /assets/MVVM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/MVVM.png -------------------------------------------------------------------------------- /assets/Onion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/Onion.png -------------------------------------------------------------------------------- /assets/SQL_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_1.png -------------------------------------------------------------------------------- /assets/SQL_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_2.png -------------------------------------------------------------------------------- /assets/SQL_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_3.png -------------------------------------------------------------------------------- /assets/SQL_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_4.png -------------------------------------------------------------------------------- /assets/SQL_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_5.png -------------------------------------------------------------------------------- /assets/SQL_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_6.png -------------------------------------------------------------------------------- /assets/SQL_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_7.png -------------------------------------------------------------------------------- /assets/SQL_aggregate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_aggregate.png -------------------------------------------------------------------------------- /assets/SQL_as.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_as.png -------------------------------------------------------------------------------- /assets/SQL_groupby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_groupby.png -------------------------------------------------------------------------------- /assets/SQL_join_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_join_1.png -------------------------------------------------------------------------------- /assets/SQL_join_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_join_2.png -------------------------------------------------------------------------------- /assets/SQL_join_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_join_3.png -------------------------------------------------------------------------------- /assets/SQL_join_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_join_4.png -------------------------------------------------------------------------------- /assets/SQL_join_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_join_5.png -------------------------------------------------------------------------------- /assets/SQL_orderby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_orderby.png -------------------------------------------------------------------------------- /assets/SQL_orderby_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_orderby_2.png -------------------------------------------------------------------------------- /assets/SQL_view_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_view_1.png -------------------------------------------------------------------------------- /assets/SQL_view_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/SQL_view_2.png -------------------------------------------------------------------------------- /assets/css-box-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/css-box-model.png -------------------------------------------------------------------------------- /assets/sibling-combinators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/sibling-combinators.png -------------------------------------------------------------------------------- /assets/testing-pyramid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Max-Starling/Notes/6c15bf62cb11c79d80e822f99571fce7b2712ae8/assets/testing-pyramid.png -------------------------------------------------------------------------------- /in-progress/Algorithms-Structures.md: -------------------------------------------------------------------------------- 1 | # Трудоёмкость алгоритмов 2 | 3 | # Алгоритмы сортировки 4 | 5 | ## Сортировка пузырьком (bubble sort) 6 | 7 | *Cравниваются соседние элементы* и *меняются местами*, если *следующий* элемент *меньше предыдущего*. 8 | Требуется *несколько проходов по данным*. 9 | 10 | ```js 11 | const bubbleSort = (array) => { 12 | const length = array.length; 13 | let tmp = 0; 14 | for (let i = 0; i < length; i += 1){ 15 | for (let j = length - 1; j >= i + 1; j -= 1) { 16 | if (array[j] < array[j-1]) { 17 | tmp = array[j]; 18 | array[j] = array[j-1]; 19 | array[j-1] = tmp; 20 | } 21 | } 22 | } 23 | } 24 | ``` 25 | 26 | https://function-x.ru/cpp_algoritmy_sortirovki.html 27 | https://habr.com/ru/post/204600/ 28 | https://en.wikipedia.org/wiki/Timsort 29 | 30 | # Структуры данных 31 | 32 | ## Список с пропусками 33 | 34 | **Список с пропусками** (Skip List) — вероятностная структура данных, основанная на нескольких параллельных отсортированных связных списках. Позволяет производить поиск и вставку сложности `O(log n)` в среднем в упорядоченной последовательности `n` элементов, что сравнимо с двоичным деревом. 35 | 36 | -------------------------------------------------------------------------------- /in-progress/C++.md: -------------------------------------------------------------------------------- 1 | 2 | ## Указатели 3 | 4 | **Указатель** (pointer) — переменная, значением которой является адрес ячейки памяти, то есть указатель ссылкается на начала какого-то блока данных из области памяти. 5 | 6 | ### Размер указателя 7 | 8 | **Размер указателя** (pointer size) зависит от версии приложения 9 | * *4 байта* — 32-битная версия. 10 | * *8 байт* — 64-битная версия. 11 | 12 | Размер указателя можно узнать при помощи `sizeof`. 13 | ```cpp 14 | int* pointer = new int(1); 15 | cout << sizeof(pointer) << endl; 16 | ``` 17 | 18 | ## Абстрактные классы 19 | 20 | **Виртуальная функция** (virtual function) - функция, которая определена базовым классом и переопределена производным классом. 21 | 22 | *Виртуальаня функция* отличается от обычной функции тем, что для обычной функции связывание вызова функции с её определением происходит на этапе компиляции, а для виртуальных функций связывание происходит во время выполнения программы. 23 | ```cpp 24 | class Bird { 25 | public: 26 | virtual void fly(); // виртуальная функция 27 | } 28 | ``` 29 | 30 | *Виртуальная функция* вызывается только через указатель или ссылку на базовый класс. 31 | 32 | **Чистая виртуальная функция** (pure virtual function), **абстрактная функция** (abstract function) — виртуальная функция, которая не имеет реализации: имеет только объявление. 33 | 34 | ```cpp 35 | class Bird { 36 | public: 37 | virtual void fly(); // виртуальная функция 38 | virtual void eat() = 0; // чистая виртуальная функция 39 | } 40 | ``` 41 | 42 | **Абстрактный класс** — любой класс, содержащий хотя бы одну чистую виртуальную функцию. 43 | 44 | Мы не можем создать экземпляр (instance) абстрактного класса. 45 | ```cpp 46 | const bird = new Bird(); // Compiler Error: cannot declare variable 'bird' to be of abstract type 'Bird' because the following virtual functions are pure within 'Bird': ... 47 | ``` 48 | 49 | Дочерние классы классы не должны реализовывать все виртуальные функции родителя, но должны реализовать все чистые функции. 50 | ```cpp 51 | class Chicken: Bird { 52 | public: 53 | void eat() { 54 | cout<< "eat grain"; 55 | } 56 | } 57 | ``` 58 | -------------------------------------------------------------------------------- /in-progress/Colors.md: -------------------------------------------------------------------------------- 1 | * `rgba(255, 255, 255, 1)` - red-green-blue-alpha 2 | * `hsl(360, 100%, 100%)` - hue-saturation-lightness (оттенок-насыщенность-светлость) 3 | * `#rrggbb` - hex rgb 4 | -------------------------------------------------------------------------------- /in-progress/Protocols.md: -------------------------------------------------------------------------------- 1 | - [HTTP](#http) 2 | - [О протоколе](#о-протоколе) 3 | - [Связь между URI, URL и URN](#связь-между-uri-url-и-urn) 4 | - [Формат сообщений](#формат-сообщений) 5 | - [HTTP-методы](#http-методы) 6 | - [Идемпотентность и безопасность HTTP-методов](#идемпотентность-и-безопасность-http-методов) 7 | - [Разница между HTTP и HTTP/2](#разница-между-http-и-http2) 8 | - [REST](#rest) 9 | 10 | # HTTP 11 | 12 | ## О протоколе 13 | **HyperText Transfer Protocol** (HTTP, протокол передачи гипертекста) — *протокол прикладного уровня передачи данных*. 14 | В *основу* данного протокола входит технология **Клиент-Сервер**. 15 | *Клиенты* и *серверы обмениваются* *сообщениями* по схеме **запрос-ответ** (request–response): *клиент отправляет запрос*, *сервер возвращает ответ*. 16 | 17 | *HTTP* является *общим языком* и *набором правил* для *клиента* и *сервера*. 18 | 19 | *HTTP* определяет 20 | * *синтаксис* (формат данных и кодирование), 21 | * *семантику* (смысловое значение, связанное с синтаксисом), 22 | * *время* (скорость и последовательность). 23 | 24 | *Каждый HTTP-запрос и ответ* считается отдельной **HTTP-транзакцией**. 25 | 26 | *HTTP* основан на **текстовых данных** — **сообщениях**, состоящих из *битов текста*. 27 | *Каждое сообщение* состоит из *заголовка* (header) и *тела* (body). 28 | 29 | *HTTP* — протокол *прикладного* уровня: *уровень абстракции*, стандартизирующий взаимодействие хостов. 30 | Сам *HTTP не передаёт данные*, а обращается за помощью к протоколу TCP / IP, чтобы получить запрос и ответ. 31 | 32 | Основным объектом манипуляции в HTTP является ресурс, на который указывает URI в запросе клиента. 33 | 34 | Одной из важных особенностей HTTP является то, что есть возможность задавать параметры в запросах и ответах: формат, кодировку и прочее. 35 | Несмотря на то, что HTTP является текстовым протоколом, он может обмениваться двоичными данными благодаря возможности кодировки. 36 | 37 | Для идентификации ресурсов HTTP использует глобальные URI. 38 | 39 | *HTTP не хранит своё состояние* в отличие от многих других протоколов. 40 | Это означает, что сохранение промежуточного состояния между парами запрос-ответ отсутствует и HTTP не осведомлён о предыдущих запросах и ответах. 41 | 42 | Клиент, сервер и браузер могут самостоятельно хранить состояние, опираясь на данные последних запросов и ответов. 43 | Например, на стороне клиента могут храниться токены или куки. 44 | Сервер может хранить IP-адреса клиентов. 45 | Браузер может отслеживать задержки ответов. 46 | 47 | Обычные *HTTP-запрос* и *HTTP-ответ* *не зашифрованы и уязвимы* для различных типов атак. 48 | Эту проблему решает HTTPS (HTTP Secure) — безопастная версия протокола, использующая протол TLS или SSL для шифрования. 49 | 50 | **SSL** - это **протокол безопасности**, который позволяет клиенту и серверу безопасно 51 | обмениваться данными по сети, предотвращая подслушивание и фальсификацию, в то 52 | время как сообщение передается по сети. 53 | 54 | Другие протоколы прикладного уровня: FTP, SMTP. 55 | 56 | ## Связь между URI, URL и URN 57 | 58 | **Uniform Resource Identifier** (URI) — символьная строка, позволяющая идентифицировать какой-либо ресурс: документ, изображение, электронную почту и прочее. 59 | Прежде всего, речь идёт о ресурсах сети Интернет и Всемирной паутины. 60 | URI предоставляет простой и расширяемый способ идентификации ресурсов. 61 | 62 | **Uniform Resource Locator** (URL) — URI, предоставляющий информацию о местонахождении ресурса. 63 | 64 | **Uniform Resource Name** (URN) — URI, который только идентифицирует ресурс в определённом пространстве имён (в определённом контексте), но не указывает его местонахождение. 65 | Пример: urn:ISBN:0-395-36341-1 — URI, указывающий на ресурс (книгу) 0-395-36341-1 в пространстве имён ISBN. 66 | 67 | Поскольку URI не всегда указывает на то, как получить ресурс, в отличие от URL, а только идентифицирует его, это даёт возможность описывать с помощью RDF (Resource Description Framework) ресурсы, которые не могут быть получены через Интернет (например, личность, автомобиль, город и проч.). 68 | 69 | ## Формат сообщений 70 | 71 | Как отмечалось ранее, клиент и сервер общаются сообщениями. 72 | 73 | Каждое сообщение содержит заголовки с метаданными и иногда тело с данными. 74 | 75 | ### Заголовки сообщения 76 | 77 | **HTTP-заголовки** (HTTP Headers) обычно содержат **метаданные** (metadata), то есть *данные о данных*. 78 | 79 | ```http 80 | GET /url 81 | Header-Name: header-value 82 | Another-Header-Name: header-value 83 | ``` 84 | 85 | *Метаданные* включают в себя: 86 | - Тип запроса (request type): `GET`, `POST`, `PUT`, `DELETE` и другие. 87 | - Путь запроса (URL). 88 | - Код статуса запроса (status code): `100` - `5xx`. 89 | - Тип контента в запросе (content-type). 90 | - Данные с клиента (User-agent): браузер, ОС и прочее. 91 | - Куки (Cookie): текущая сессия. 92 | 93 | ### Тело сообщения 94 | 95 | **Тело сообщения** (Message body) содержит *данные*. 96 | 97 | Оно отделяется от заголовков пустой строкой. 98 | ```http 99 | POST /url 100 | Content-Type: application/json 101 | 102 | Body data 103 | ``` 104 | В зависимости от HTTP-метода тело может отсутствовать. 105 | 106 | ## HTTP-методы 107 | 108 | **HTTP-методы**, **HTTP-глаголы** (verbs) сообщают серверу, что требуется сделать с данными, хранящимися по указанному URL. 109 | 110 | 111 | Когда *клиент делает запрос*, он *указывает тип запроса*, используя один из следующим методов: 112 | - [GET](#get) 113 | - [HEAD](#head) 114 | - [POST](#post) 115 | - [PUT](#put) 116 | - [DELETE](#delete) 117 | - [OPTIONS](#options) 118 | - [PATCH](#patch) 119 | 120 | ### GET 121 | 122 | **Метод GET** используется для *чтения информации с сервера по данному URL*. 123 | 124 | *Метод GET* доступен *только для чтения*. По запросу `GET` данные на сервере не должны изменяться, сервер должен отправлять данные без изменений. 125 | ```http 126 | GET /user/friends 127 | ``` 128 | 129 | *Метод GET* не имеет тела запроса* (Request Body). Все данные запроса GET содержатся в URL и видны всем, поэтому не стоит передавать секретную информацию в методе GET. 130 | 131 | *Статус-коды метода GET* 132 | * **200** (OK) — *запрашиваемый ресурс найден*. 133 | * **404** (Not found) — *запрашиваемый ресурс не найден*. 134 | 135 | ### HEAD 136 | 137 | **Метод HEAD** идентичен *методу GET*, поскольку запрашивает у сервера такой же ответ, но без тела ответа (Response Body). 138 | ```http 139 | HEAD /user/friends 140 | ``` 141 | При помощи *метода HEAD* можно получить мета-данные, хранящиеся в заголовке ответа (Reponse Headers), и при этом напрасно не передавать данные с сервера. 142 | 143 | Как и *метод GET*, *метод HEAD* является *безопасным* и *идемпотентным*. 144 | 145 | ### POST 146 | 147 | **Метод POST** обычно используется для *создания нового ресурса*. 148 | ```http 149 | POST /users/create 150 | 151 | username=max&sex=male 152 | ``` 153 | 154 | При поздании нового ресурса подразумевается создание нового подчинённого ресурса (subordinate) для ресурса, заданного по URL. Например, в случае примера выше это создание нового пользователя для ресурса `users`, содержащего информацию о пользователях. 155 | 156 | *Статус-коды GET-запроса* 157 | * **201** (Created) — *подчинённый ресурс создан успешно для указанного ресурса*. 158 | * **404** (Not found) — *запрашиваемый ресурс не найден*. 159 | 160 | ### PUT 161 | 162 | **Метод PUT** используется для обновления ресурса, идентифицируемого URL-адресом, с использованием информации в теле запроса. 163 | ```http 164 | PUT /users/17 165 | 166 | username=dana&sex=female 167 | ``` 168 | 169 | PUT также может быть использован для создания нового ресурса. 170 | 171 | PUT запросы отвечают статусом 200 если запрос успешно обновлён и 404 если ресурс не найден. 172 | 173 | ### DELETE 174 | 175 | **Метод DELETE** используется для удаления ресурса, указанного в URL. 176 | 177 | На запросы DELETE в ответ удаляется код состояния 200 (ОК), если он был успешно 178 | удален, или 404 (НЕ НАЙДЕН), если удаляемый ресурс не может быть найден. 179 | 180 | https://medium.freecodecamp.org/how-the-web-works-part-iii-http-rest-e61bc50fa0a 181 | 182 | ### OPTIONS 183 | 184 | ## Идемпотентность и безопасность HTTP-методов 185 | 186 | **Идемпотентность** (Idempotence) — свойство объекта (или операции) при повторном применении операции к объекту (или при повторном вызове операции) давать тот же результат, что и при первом. 187 | 188 | Таким образом, запросы GET считаются безопасными операциями, потому что вызов его один 189 | раз или вызов 20 раз будет иметь тот же эффект. 190 | 191 | Кроме того, **запросы GET являются идемпотентными**. 192 | Это означает, что отправка нескольких запросов GET на один и тот же URL-адрес должна 193 | вызывать тот же эффект, что и один запрос GET, поскольку запрос GET просто запрашивает 194 | данные у сервера и фактически не изменяет какие-либо данные на сервере. 195 | 196 | **POST не является ни безопасным, ни идемпотентным**. Это связано с тем, что выполнение 197 | двух или более одинаковых запросов POST может привести к созданию двух новых идентичных 198 | ресурсов. 199 | 200 | Запросы PUT не считаются безопасными операциями, поскольку они изменяют состояние на сервере. 201 | Однако PUT идемпотентен, потому что несколько идентичных запросов PUT на обновление ресурса 202 | должны иметь тот же эффект, что и первый. 203 | 204 | Запросы DELETE являются идемпотентными, потому что если вы удаляете ресурс, 205 | он удаляется, и даже если вы делаете несколько идентичных запросов DELETE, 206 | результат остается тем же: удаленный ресурс. 207 | 208 | Скорее всего, вы просто получите сообщение об ошибке 404, если отправите запрос 209 | DELETE более одного раза для одного и того же ресурса, потому что сервер не сможет 210 | найти его после его удаления. 211 | 212 | ## Разница между HTTP и HTTP/2 213 | 214 | 226 | 227 | ## REST 228 | 229 | **REST** (Representational State Transfer) — архитектурный стиль для разработки 230 | приложений. 231 | 232 | Его автор, Рой Филдинг, выступал за использование стандартных HTTP методов так, 233 | чтобы придать запросам определённый смысл. А также за то, что между кодами ответов 234 | и самими ответами должен быть определённый смысл. 235 | 236 | Основная идея заключается в том, что вы используете протокол «без сохранения 237 | состояния», «клиент-сервер», «кэшируемый» для выполнения вызовов между компьютерами 238 | - и чаще всего этот протокол является HTTP. 239 | 240 | Это просто причудливый способ сказать, что REST дает вам набор ограничений для 241 | разработки приложения. Эти ограничения помогают сделать систему более производительной, 242 | масштабируемой, прозрачной и надежной. 243 | 244 | **Список ограничений**: 245 | * **Uniform interface (единый интерфейс)**. 246 | * **Stateless (отсутствие состояния)**. То есть все данные о состоянии, необходимые 247 | для обработки клиентского запроса, должны содержаться в самом запросе, и сервер должен 248 | отправлять все необходимые данные состояния обратно клиенту через сам ответ. 249 | 250 | Наличие такой системы без сохранения состояния делает приложения намного более 251 | масштабируемыми, потому что ни одному серверу не нужно беспокоиться о том, чтобы 252 | поддерживать одно и то же состояние сеанса в течение нескольких запросов. 253 | Все необходимое для получения данных о состоянии доступно в самом запросе и ответе. 254 | -------------------------------------------------------------------------------- /in-progress/ReactNative.md: -------------------------------------------------------------------------------- 1 | # Основы React Native 2 | 3 | **React Native** — фреймворк, TODO 4 | 5 | -------------------------------------------------------------------------------- /in-progress/VSCode.md: -------------------------------------------------------------------------------- 1 | ## LF vs CRLF 2 | 3 | 1) ctrl + P 4 | 2) > settings 5 | 3) 6 | For LF (line feed): 7 | ```json 8 | { 9 | "files.eol": "\n", 10 | } 11 | ``` 12 | For CRLF (carrige return and line feed): 13 | ```json 14 | { 15 | "files.eol": "\r\n", 16 | } 17 | ``` 18 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/e4aebd55-0ac7-452c-bb04-4a4257022106) 19 | -------------------------------------------------------------------------------- /in-progress/npm.md: -------------------------------------------------------------------------------- 1 | - [Зависимости в `package.json`](#зависимости-в-packagejson) 2 | - [Нормальные зависимости `dependencies`](#нормальные-зависимости-dependencies) 3 | - [Зависимости разработчика `devDependencies`](#зависимости-разработчика-devdependencies) 4 | - [Одноранговые зависимости `peerDependencies`](#одноранговые-зависимости-peerdependencies) 5 | - [`peerDependenciesMeta`](#peerdependenciesmeta) 6 | - [Другие свойства `package.json`](#другие-свойства-packagejson) 7 | - [Переопределения `overrides`](#переопределения-overrides) 8 | - [Скрипты `scripts`](#скрипты-scripts) 9 | - [Передача параметров скрипту](#передача-параметров-скрипту) 10 | 11 | # Зависимости в `package.json` 12 | 13 | **Зависимостями** (англ. `devendencies`) в приложении выступают *сторонние пакеты* (модули), которые *декларируются* в `package.json`. Чаще всего зависимости скачиваются из [NPM Registry](https://www.npmjs.com/) 14 | 15 | ## Нормальные зависимости `dependencies` 16 | 17 | Свойство `dependencies` (англ. `зависимости`) содержит *зависимости приложения*, то есть пакеты (модули), которые используются в приложении. 18 | 19 | Каждая зависимость представлена в виде пары *двух строковых значений*: 20 | 1) *Уникальное название пакета*. Например, [`"explicit"`](https://www.npmjs.com/package/explicit), [`"implicit"`](https://www.npmjs.com/package/implicit). 21 | 2) *Версия пакета*. *Версия пакета* может быть задана *явно* (то есть *тремя конкретными числами*, например, `2.3.21`) или *неявно* (например, в виде *промежутка*: `>= 2.0.0 < 3.0.0`, `>= 2.0.0 < 3.0.0`, `2.x`, `^2.3.21`) 22 | ```json 23 | { 24 | "name": "my-project", 25 | "version": "1.0.0", 26 | "dependencies": { 27 | "explicit": "2.3.21", 28 | "implicit": "^2.3.21", 29 | "implicit-foo": "2.0.0 - 3.0.0", 30 | "implicit-bar": ">= 2.0.0 < 3.0.0", 31 | "implicit-baz": "2.x" 32 | } 33 | } 34 | ``` 35 | 36 | Далее *детально разберём все возможные способы задания версии*. 37 | 38 | 39 | ## Зависимости разработчика `devDependencies` 40 | 41 | 42 | ## Одноранговые зависимости `peerDependencies` 43 | - [`peerDependenciesMeta`](#peerdependenciesmeta) 44 | 45 | Если в некотором пакете `foo` указаны `peer dependencies` (рус. `одноранговые зависимости`, иногда `одноуровневые` или `прямые`), то *при установке* пакета `foo` в ваше *приложение* *необходимо будет* также *установить* все *зависимости* из этого *списка*. 46 | 47 | Таким образом, если пакет `foo` имеет следующий `package.json` 48 | ```js 49 | { 50 | "name": "foo", 51 | "version": "2.1.1", 52 | "peerDependencies": { 53 | "bar": "^18.0.0", 54 | "baz": "7.1.x" 55 | } 56 | } 57 | ``` 58 | то `package.json` вашего приложения после установки `foo` и его одноранговых зависимостей с помощью `npm install` должен выглядить примерно следующим образом 59 | ```js 60 | { 61 | "name": "my-awesome-app", 62 | "version": "1.0.0", 63 | "dependencies": { 64 | "foo": "2.1.1", 65 | "bar": "^18.0.0", 66 | "baz": "7.1.x" 67 | } 68 | } 69 | ``` 70 | а *дерево зависимостей*, например, так 71 | ```terminal 72 | ├── ... 73 | ├── foo@2.1.1 74 | ├── bar@18.0.3 75 | └── baz@7.1.1 76 | ``` 77 | Это будет *отображено* у вас в *консоли* и в несколько другом виде *отражено* в `package-lock.json`. 78 | 79 | Если же пакеты `bar` и `baz` *не будут установлены*, то `npm` *выдаст ошибку*. 80 | 81 | Пример *реальной ошибки* со [*Stackoverflow*](https://stackoverflow.com/questions/35207380/how-to-install-npm-peer-dependencies-automatically): 82 | ```terminal 83 | npm install --save angular2 84 | temp@1.0.0 /Users/doug/Projects/dougludlow/temp 85 | ├── angular2@2.0.0-beta.3 86 | ├── UNMET PEER DEPENDENCY es6-promise@^3.0.2 87 | ├── UNMET PEER DEPENDENCY es6-shim@^0.33.3 88 | ├── UNMET PEER DEPENDENCY reflect-metadata@0.1.2 89 | ├── UNMET PEER DEPENDENCY rxjs@5.0.0-beta.0 90 | └── UNMET PEER DEPENDENCY zone.js@0.5.11 91 | 92 | npm WARN angular2@2.0.0-beta.3 requires a peer of es6-promise@^3.0.2 but none was installed. 93 | npm WARN angular2@2.0.0-beta.3 requires a peer of es6-shim@^0.33.3 but none was installed. 94 | npm WARN angular2@2.0.0-beta.3 requires a peer of reflect-metadata@0.1.2 but none was installed. 95 | npm WARN angular2@2.0.0-beta.3 requires a peer of rxjs@5.0.0-beta.0 but none was installed. 96 | npm WARN angular2@2.0.0-beta.3 requires a peer of zone.js@0.5.11 but none was installed. 97 | ``` 98 | 99 | *Автоматическая установка* `peer dependencies` была *удалена* из `NPM v3`, поскольку *создавала больше проблем*, чем *решала*. Тем не менее, она была *возвращена* в версии `NPM v7` - начиная с этой версии все `peer dependencies` снова *устанавливаются автоматически*. На версиях `NPM 4, 5, 6` необходимо устанавливать каждую `peer dependency` вручную при помощи `npm install package_name@version`. 100 | 101 | ### `peerDependenciesMeta` 102 | Для `peer dependencies` есть свойство `peerDependenciesMeta`, хранящее метаданные об одноранговых зависимостях. Эти данные позволяют объяснить NPM, как именно используется та или иная `peer dependency`. 103 | 104 | В основном, данные `peerDependenciesMeta` используют, чтобы пометить некоторую `peer dependency` вашего пакета как *необязательную*, *опциональную* (англ. `optional`) для установки зависимость. Это позволит *избежать предупреждений* (ошибок) о неустановленных `peer dependencies`. 105 | 106 | Например, ниже `peer dependency` `baz` помечена как опциональная зависимость для пакета `foo`, а значит, что если при установке пакета `foo` в ваше приложение не установить зависимость `baz`, то ошибки не будет. 107 | ```js 108 | { 109 | "name": "foo", 110 | "version": "2.1.1", 111 | "peerDependencies": { 112 | "bar": "^18.0.0", 113 | "baz": "7.1.x" 114 | }, 115 | "peerDependenciesMeta": { 116 | "baz": { 117 | "optional": true 118 | } 119 | } 120 | } 121 | ``` 122 | 123 | 124 | # Другие свойства `package.json` 125 | 126 | ## Переопределения `overrides` 127 | 128 | Указание свойства `overrides` (рус. `переопреедения`) позволяет *принудительно установить* (*перезаписывать*) *версии* некоторых *пакетов* в приложении. 129 | 130 | Возможны несколько случаев применения. 131 | 132 | 146 | 147 | https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides 148 | 149 | ## Свойство `scripts` (скрипты) 150 | 151 | ### Передача параметров скрипту 152 | - [UNIX (Linux, Mac)](#unix-linux-mac) 153 | - [Windows](#windows) 154 | - [Кроссплатформенное решение](#кроссплатформенное-решение) 155 | 156 | #### UNIX (Linux, Mac) 157 | * *Передача строки* 158 | ```JSON 159 | "scripts": { 160 | "start:prod": "NODE_ENV=production npm start" 161 | } 162 | ``` 163 | ```js 164 | process.env.NODE_ENV // 'production' 165 | ``` 166 | * *Передача числа* 167 | ```JSON 168 | "scripts": { 169 | "start:prod": "PORT=5001 npm start" 170 | } 171 | ``` 172 | ```js 173 | parseInt(process.env.PORT, 10) // 5001 174 | ``` 175 | #### Windows 176 | ```cmd 177 | "scripts": { 178 | "start:prod": "set NODE_ENV=production& npm start" 179 | } 180 | ``` 181 | ```js 182 | process.env.NODE_ENV // 'production' 183 | ``` 184 | Если поставить пробел перед `&` 185 | ```cmd 186 | "scripts": { 187 | "start:prod": "set NODE_ENV=production & npm start" 188 | } 189 | ``` 190 | ```js 191 | process.env.NODE_ENV // 'production ' (появляется пробел на конце) 192 | ``` 193 | #### Кроссплатформенное решение 194 | * Передача *одной переменной*. 195 | ```cmd 196 | npm i --save-dev cross-env 197 | ``` 198 | ```cmd 199 | "scripts": { 200 | "start:prod": "cross-env NODE_ENV=production npm start" 201 | } 202 | ``` 203 | * Передача *нескольких переменных*. 204 | ```cmd 205 | "scripts": { 206 | "start:prod": "cross-env NODE_ENV=production PORT=5001 npm start" 207 | } 208 | ``` 209 | -------------------------------------------------------------------------------- /tech/ApacheVelocity.md: -------------------------------------------------------------------------------- 1 | 2 | ## Установка значения переменной 3 | 4 | ```js 5 | #set($size = 10) 6 | ``` 7 | ```js 8 | #set($title = "Notes") 9 | ``` 10 | 11 | ## Использование переменной 12 | ```js 13 | { 14 | "size": $size, 15 | "title": "$title" 16 | } 17 | ``` 18 | 19 | Нельзя использовать выражение в качестве значения как в примере ниже. Нужно выносить выражение в переменную и использовать её. Иначе в значение попадёт само выражение, а не его результат. 20 | ```js 21 | { 22 | "size": $size + 1, 23 | } 24 | /* результат 10 + 1, а не 11 */ 25 | ``` 26 | 27 | ## Инкремент 28 | ```js 29 | #set($counter = 0) 30 | #set($counter = $counter + 1) 31 | ``` 32 | 33 | ## Условный оператор 34 | 35 | ## if..else 36 | ```js 37 | #if($a > $b) 38 | #set($max = $a) 39 | #else 40 | #set($max = $b) 41 | #end 42 | ``` 43 | 44 | 45 | ## elseif 46 | ```js 47 | #if($counter == 0) 48 | #set($str = "zero") 49 | #elseif($counter == 1) 50 | #set($str = "one") 51 | #else 52 | #set($str = "another number") 53 | #end 54 | ``` 55 | 56 | ## Краткая запись 57 | ```js 58 | #if($a > $b)it's true!#{else}it's not!#end 59 | ``` 60 | ## Цикл 61 | ```js 62 | #foreach($entry in $array) 63 | #set($prop = $entry.get("property")) 64 | #end 65 | ``` 66 | 67 | ## Массив 68 | 69 | ### Объявление 70 | ```js 71 | #set($array = [42, "a string", $counter]) 72 | ``` 73 | ### Обращение к элементу 74 | ```js 75 | $array.get(1) 76 | $array[1] 77 | ``` 78 | ### Проверка на пустоту 79 | ```js 80 | #if ($myMap.isEmpty()) #end 81 | #if ($myMap.size() == 0) #end 82 | ``` 83 | ### Добавление элементов 84 | ```js 85 | $array.add(17) 86 | ``` 87 | -------------------------------------------------------------------------------- /tech/Chai-Mocha.md: -------------------------------------------------------------------------------- 1 | ## Get started 2 | 3 | * Install packages 4 | ```npm 5 | npm install --save-dev chai 6 | npm install --save-dev mocha 7 | ``` 8 | * Set up the test script in the package.json 9 | * --timeout (number, default: 2000) 10 | * --recursive (string, dafault: './test/*.js') 11 | ```JSON 12 | "scripts": { 13 | "test": "mocha --timeout 10000 --recursive './test/**/*.spec.js'" 14 | } 15 | ``` 16 | * Create `your-filename-here.spec.js` file in the test folder 17 | * Start using chai сhai `expect` or chai `should` 18 | ```js 19 | const expect = require('chai').expect; 20 | // or 21 | const chai = require('chai'); 22 | chai.should(); 23 | ``` 24 | 25 | ### "expect" and "should" syntax 26 | ```js 27 | const getArticles = () => [/* ... */]; 28 | 29 | expect(getArticles()).to.be.an('array'); 30 | 31 | getArticles().should.be.an('array'); 32 | ``` 33 | ## Basic functions 34 | 35 | ```js 36 | expect(something).to.equal('value'); // something === 'value' 37 | 38 | expect(something).to.be.a('type'); // typeof something === 'value, but 39 | expect([]).to.be.an('array'); // success 40 | 41 | expect(object).to.have.property('property'); // Object.keys(object).includes('property'); 42 | 43 | const keys = [/* ... */]; 44 | expect(object).to.have.all.keys(...keys); // keys.every(key => Object.keys(object).includes(key)); 45 | expect(object).to.have.any.keys(...keys); // keys.some(key => Object.keys(object).includes(key)); 46 | ``` 47 | 48 | 49 | ## Basic structure for unit tests 50 | Simple module: 51 | ```js 52 | module.exports = { 53 | isInteger: number => number === parseInt(number, 10), 54 | getRandomNaturalNumber: (max = 1000) => Math.floor(Math.random() * (max - 1)) + 1, 55 | }; 56 | ``` 57 | Tests for the module: 58 | ```js 59 | const expect = require('chai').expect; 60 | const numberFuncs = require('/*...*/'); 61 | 62 | describe('numberFuncs', () => { 63 | describe('isInteger', () => { 64 | it('should always return a boolean', () => { 65 | expect(numberFuncs.isInteger('article')).to.be.a('boolean'); 66 | }); 67 | 68 | it('should return true', () => { 69 | expect(numberFuncs.isInteger(5)).to.equal(true); 70 | }); 71 | 72 | it('should return false', () => { 73 | expect(numberFuncs.isInteger(7.5)).to.equal(false); 74 | }); 75 | }); 76 | 77 | describe('getRandomNaturalNumber', () => { 78 | it('should return a natural number', () => { 79 | const natural = numberFuncs.getRandomNaturalNumber(); 80 | expect(natural).to.be.an('number'); 81 | expect(natural).to.be.above(0); 82 | expect(numberFuncs.isInteger(natural)).to.equal(true); 83 | }); 84 | }); 85 | }); 86 | ``` 87 | 88 | ## Basic structure for API tests 89 | Simple Express API: 90 | ```js 91 | const Express = require('express'); 92 | const app = Express(); 93 | 94 | const checkCredentials = (username, password) => { /* ... */ }; 95 | const createAuthToken = (username) => { /* ... */ }; 96 | 97 | app.get('/login', async (req, res) => { 98 | const { username, password } = req.params; 99 | const user = await checkCredentials(username, password); 100 | if (user) { 101 | const token = await createAuthToken(username); 102 | res.status(200).send({ ...user, token }); 103 | } else { 104 | res.status(400).send(); 105 | } 106 | }); 107 | 108 | const ARTICLES = [/* ... */]; 109 | const getAuthTokenFromHeaders = (headers) => { /* ... */ }; 110 | const checkAuthToken = (token) => { /* ... */ }; 111 | 112 | app.get('/articles', async (req, res) => { 113 | const authToken = getAuthTokenFromHeaders(req.headers); 114 | const isAuthorized = await checkAuthToken(authToken); 115 | if (isAuthorized)) { 116 | res.status(200).send(ARTICLES); 117 | } else { 118 | res.status(400).send(); 119 | } 120 | }); 121 | ``` 122 | Tests for the API above: 123 | ```js 124 | const axios = require('axios'); 125 | const expect = require('chai').expect; 126 | 127 | const API = axios.create({ baseURL: 'http://localhost:3002' }); 128 | const POST = ({ endpoint, body }) => API.post(endpoint, body)); 129 | const GET = ({ endpoint, query, authToken }) => API.get( 130 | endpoint, 131 | { params: query }, 132 | { headers: { 'Authorization': `Bearer ${authToken}` }, 133 | }); 134 | 135 | let authToken = ''; 136 | 137 | describe('POST /login', () => { 138 | const credentials = { username: 'admin', password: 'admin' }; 139 | 140 | it('should return status 200 and object containing auth token', async () => { 141 | const response = await POST({ endpoint: '/login', body: credentials }); 142 | expect(response).to.be.an('object'); 143 | const { status, data } = response; 144 | expect(status).to.equal(200); 145 | expect(data).to.be.an('object'); 146 | const { token } = data; 147 | expect(token).to.be.a('string'); 148 | authToken = token; 149 | }); 150 | }); 151 | 152 | describe('GET /articles', () => { 153 | it('should return an array of objects containing title, text and username', async () => { 154 | const response = await GET({ endpoint: '/articles', authToken }); 155 | expect(response).to.be.an('object'); 156 | const { status, data } = response; 157 | expect(status).to.equal(200); 158 | expect(data).to.be.an('array'); 159 | const article = data[0]; 160 | expect(article).to.be.an('object'); 161 | expect(article).to.have.all.keys('title', 'text', 'username'); 162 | }); 163 | }); 164 | 165 | 166 | ``` 167 | try - catch 168 | before, beforeAll, after, afterAll 169 | this (timeouts, skip) 170 | -------------------------------------------------------------------------------- /tech/ESlint-TSlint-Prettier.md: -------------------------------------------------------------------------------- 1 | ## О линтерах 2 | 3 | **Линтер** (англ. `linter`) в программировании — это программа (инструмент), которая анализирует код приложения с целью выявления потенциальных ошибок, проблем, уязвимостей, нарушений код стайла и так далее до реального выполнения кода. 4 | 5 | Линтеры позволяют улучшить качество кода вашего приложения. 6 | 7 | Настраивая линтер в своём проекте, вы сами задаёте для него правила с учётом уже встроенных рекомендаций, после чего каждый разработчик на проекте автоматически подстаивается под них. 8 | 9 | Все мы разные, у каждого из нас свой опыт, своя точка зрения. Кому-то нравятся пробелы, кому-то - табы. Кто-то любит точки с запятой, закрывающие запятые, фигурные скобки, а кто-то топит за минимализм символов. Линтер позволяет установить соглашение о едином стиле между разработчиками. 10 | 11 | 12 | ### Как использовать линтер 13 | Чаще всего линтеры встраивают в качестве расширения в IDE (например, [расширение Eslint в VSCode](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)), в этом случае ошибки будут подсвечиваться прямо у вас в коде. 14 | 15 | Если же вы приверженец терминала, то для Eslint также предлагает CLI решение https://eslint.org/docs/latest/use/command-line-interface 16 | ```py 17 | # запуск линтинга одного файла 18 | eslint app.js 19 | # запуск линтинга в папке 20 | eslint src/* 21 | ``` 22 | 23 | ### Алгоритм линтера 24 | 25 | * Производится статический анализ кода (то есть код анализируется без реального выполнения). 26 | * Проанализированный код парсится, затем строится абстракное синтаксическое дерево (англ. `abstract syntax tree`, `AST`). 27 | * Для каждой вершины построенного дерева прогоняются все сконфигурированные на проекте правила линтера. 28 | * Результат отображается на экране (например, в консоли или в IDE) 29 | 30 | ### Забавная ассоциация для наилучшего запоминания 31 | 32 | [Англ.](https://www.merriam-webster.com/dictionary/linters) `lint`, `linters` переводится как ворс - пушок, который удаляют с семян хлопка во время его обработки. 33 | 34 | [Англ.](https://www.merriam-webster.com/dictionary/linters) `linter` - это машина, которая удаляет ворсинки с хлопка во время его обработки. 35 | 36 | То есть хлопковый линтер "причёсывает хлопок", избавляясь от ворсинок, в то время, как линтер в программировании "причёсывает" наш код, устраняя его неровности (недостатки). 37 | 38 | ## О форматтерах 39 | **Форматтер** (англ. `formatter`) в программировании — это программа (инструмент), которая форматирует код. 40 | 41 | Так же, как и линтер, форматтер анализирует код и строит абстрактное синтаксическое дерево (англ. `AST`) 42 | 43 | ## Сравнение линтера и форматера 44 | 45 | Линтеры анализируют 46 | 47 | Из гугла: 48 | > Linting is distinct from Formatting because linting analyzes how the code runs and detects errors whereas formatting only restructures how code appears. 49 | 50 | С сайта Prettier: 51 | > Linters usually contain not only code quality rules, but also stylistic rules. Most stylistic rules are unnecessary when using Prettier, but worse – they might conflict with Prettier! Use Prettier for code formatting concerns, and linters for code-quality concerns, as outlined in Prettier vs. Linters. 52 | 53 | ## Зачем нужны линтеры и форматеры 54 | 55 | Линтеры и форматеры позволяют задать общий стиль всему проекту, а поэтому когда он уже настроен 56 | * Не нужно тратить время и энергию на извечные споры в комментариях Pull Request-ам, комментариев в целом становится меньше, а значит Pull Requuest-ы мержатся быстрее и чаще. Более того, если постоянно не отвлекаться на такие мелочи как стиль кода при ревью, можно сфокусироваться на действительно важной составляющей кода - бизнес-логике и потенциальных ошибках. 57 | * Новым людям намного проще влиться в проект и команду, когда правила явно заданы и хорошо описаны. Так они чувствуют себя увереннее и комфортнее, а большинство вопросов отпадают сами, что экономит время каждого члена проекта. 58 | * Когда линтинг и форматинг происходят автоматически, можно тратить меньше времени на красивое оформление, а значит и писать код быстрее (и качествее, потому что все правила в голове не удержишь). 59 | 60 | ## Мои предпочтения в настройках линтера с пояснением 61 | -------------------------------------------------------------------------------- /tech/ErrorHandling.md: -------------------------------------------------------------------------------- 1 | # Обработка ошибок в Node.js 2 | 3 | Обработка ошибок в приложении на Node.js — одна из важнейших частей разработки, ведь она позволяет предотвратить аварийные ситуации и обеспечивает стабильную работу приложения. 4 | 5 | Далее будут представлены несколько подходов для обработки ошибок на Node.js: 6 | 7 | ## Использование try-catch и async/await 8 | Для обработки ошибок в асинхронных функциях с `async..await` можно использовать блоки `try..catch`: 9 | ```js 10 | async function fetchData() { 11 | try { 12 | const data = await call(); 13 | return data; 14 | } catch (error) { 15 | console.error('Error fething data:', error); 16 | throw new Error('Не удалось получить данные'); 17 | } 18 | } 19 | ``` 20 | Важно логировать ошибки и выдавать пользователю информативные сообщения, но при этом не раскрывать внутренние детали приложения. 21 | 22 | ## Централизованная обработка ошибок (Middleware в Express) 23 | В Express можно настроить *централизованный обработчик ошибок* с помощью специального middleware: 24 | ```js 25 | const express = require('express'); 26 | const app = express(); 27 | 28 | // Пример маршрута 29 | app.get('/data', async (req, res, next) => { 30 | try { 31 | const data = await call(); 32 | res.send(data); 33 | } catch (error) { 34 | next(error); // Передаем ошибку в следующий middleware 35 | } 36 | }); 37 | 38 | // Централизованный обработчик ошибок 39 | app.use((err, req, res, next) => { 40 | console.error(err.stack); 41 | res.status(500).json({ message: 'Internal server error' }); 42 | }); 43 | 44 | app.listen(3000, () => { 45 | console.log('Server is listening at 3000'); 46 | }); 47 | ``` 48 | 49 | Здесь используется функция `next()`, которая *передает ошибку* в *централизованный обработчик ошибок*. 50 | Это позволяет *отделить логику обработки ошибок от основной логики маршрутов*. 51 | 52 | ## Использование пользовательских классов ошибок 53 | Создание пользовательских классов ошибок позволяет делать сообщения более специфичными и легко различать типы ошибок: 54 | 55 | ```js 56 | class NotFoundError extends Error { 57 | constructor(message) { 58 | super(message); 59 | this.name = 'NotFoundError'; 60 | this.statusCode = 404; 61 | } 62 | } 63 | 64 | // Использование пользовательской ошибки 65 | app.get('/user/:id', async (req, res, next) => { 66 | try { 67 | const user = await getUserById(req.params.id); 68 | if (!user) { 69 | throw new NotFoundError('User not found'); 70 | } 71 | res.json(user); 72 | } catch (error) { 73 | next(error); 74 | } 75 | }); 76 | ``` 77 | В зависимости от нужд приложения можно создавать сколь угодно много классов ошибок, например, для валидации `ValidationError`, аутентификации `AuthError`, таймаутов `TimeoutError` и т.д. 78 | 79 | Это помогает централизованно обрабатывать разные типы ошибок в одном месте, предоставляя соответствующие HTTP-коды и сообщения. 80 | Затем эти ошибки можно централизованно отлавливать 81 | ```js 82 | try { 83 | 84 | } catch (err) { 85 | if (err instanceof NotFoundError) { /* ... */ } 86 | else if (err instanceof ValidationError) { /* ... */ } 87 | else if (err instanceof AuthError { /* .. */} 88 | } 89 | ``` 90 | 91 | ## Обработка необработанных ошибок и необработанных отклоненных промисов 92 | Для обработки ошибок, которые не были перехвачены в коде, можно использовать *глобальные обработчики* `uncaughtException` и `unhandledRejection`. В них можно завершить приложение, логировать ошибки и так далее. 93 | ```js 94 | process.on('uncaughtException', (error) => { 95 | console.error('Uncaught exception:', error); 96 | // Обычно на этом этапе приложение завершает работу, чтобы избежать непредсказуемых состояний 97 | process.exit(1); 98 | }); 99 | 100 | process.on('unhandledRejection', (reason, promise) => { 101 | console.error('НUnhandled promise rejection:', reason); 102 | // Здесь также можно выполнить какую-то логику, например, логирование, алерты и т.д. 103 | }); 104 | ``` 105 | Важно помнить, что после `uncaughtException` лучше завершить работу приложения, чтобы избежать неконсистентного состояния. 106 | 107 | ## Логирование ошибок 108 | Логирование играет важную роль в обработке ошибок, и его следует реализовать с помощью специализированных библиотек, таких как winston или pino: 109 | ```js 110 | const winston = require('winston'); 111 | 112 | const logger = winston.createLogger({ 113 | level: 'error', 114 | format: winston.format.json(), 115 | transports: [ 116 | new winston.transports.File({ filename: 'error.log' }) 117 | ] 118 | }); 119 | 120 | // Пример использования логгера 121 | app.use((err, req, res, next) => { 122 | logger.error(err.message); 123 | res.status(500).json({ message: 'Ошибка сервера' }); 124 | }); 125 | ``` 126 | Логирование ошибок помогает отслеживать проблемы в продакшене. 127 | Также можно настроить отправку уведомлений, если возникла критическая ошибка. 128 | 129 | ## Валидация входящих данных 130 | 131 | Используйте библиотеки, такие как Joi или express-validator, чтобы валидировать данные до выполнения бизнес-логики: 132 | 133 | ```js 134 | const { body, validationResult } = require('express-validator'); 135 | 136 | app.post('/user', [ 137 | body('email').isEmail(), 138 | body('password').isLength({ min: 6 }) 139 | ], (req, res, next) => { 140 | const errors = validationResult(req); 141 | if (!errors.isEmpty()) { 142 | return res.status(400).json({ errors: errors.array() }); 143 | } 144 | next(); 145 | }); 146 | ``` 147 | Это позволяет избежать выполнения лишнего кода, если входные данные невалидны. 148 | Позволяет централизованно обрабатывать ошибки валидации. 149 | Заключение 150 | Наилучшие практики обработки ошибок в Node.js включают использование try-catch, централизованную обработку ошибок с middleware, создание пользовательских ошибок, логирование и валидацию входящих данных. Эти подходы помогают сделать код более надежным, улучшить обслуживание и быстрее находить и исправлять проблемы. 151 | -------------------------------------------------------------------------------- /tech/Files.md: -------------------------------------------------------------------------------- 1 | 2 | It is available in standard text format and used for saving and transporting the data. JSON helps to transmit data in web applications where the data is sent from server to client and can be viewed on the web page. YAML is used for scripting configuration files and can be incorporated with added programming languages. It is popular for data serialization language, human-readable language, and adaptive. The difference and comparison of JSON and YAML are described in the article. 3 | 4 | # JSON 5 | 6 | JSON is abbreviated as JavaScript Object Notation which is easy to understand and self-describing. 7 | 8 | # BSON 9 | 10 | # YAML 11 | 12 | # TOML 13 | -------------------------------------------------------------------------------- /tech/Firebase.md: -------------------------------------------------------------------------------- 1 | # Firebase Deployment 2 | 3 | ## Get Started 4 | * Install Firebase tools: 5 | ```yarn 6 | npm i -g firebase-tools 7 | ``` 8 | * Init hosting project: 9 | ```yarn 10 | firebase init hosting 11 | ``` 12 | * Select a default Firebase project for the directory. 13 | 14 | ## Basic commands 15 | * Show all your firebase projects: 16 | ```js 17 | firebase list 18 | ``` 19 | * Serve locally 20 | ```js 21 | firebase serve --only functions, hosting 22 | ``` 23 | * Deploy 24 | ```js 25 | firebase deploy 26 | ``` 27 | * Deploy by using token 28 | ```yml 29 | firebase deploy --token "$FIREBASE_TOKEN" 30 | ``` 31 | 32 | ## Deploy React App (frontend) 33 | 34 | * Create a new project with the [Firebase console](https://console.firebase.google.com). 35 | * Choose a project name. 36 | * Click "Add Firebase into web app" 37 | * Choose an app name. 38 | * Select the "Set up Firebase Hosting" option and go next. 39 | * Open web app settings -> Configuration and copy object like this: 40 | ```js 41 | const firebaseConfig = { 42 | apiKey: "...", 43 | authDomain: "...", 44 | databaseURL: "...", 45 | projectId: "...", 46 | storageBucket: "...", 47 | messagingSenderId: "...", 48 | appId: "..." 49 | }; 50 | ``` 51 | * Now open index.html file and post this two scripts at the end of the body tag: 52 | ```HTML 53 | 54 | 55 | 56 | 57 | 63 | 64 | ``` 65 | * Create firebase.json in the root project folder and set up Firebase hosting: 66 | * public - path to the build folder (the only one required attribure for hosting) 67 | * ignore - files to ignore on deploy 68 | * rewrites - serve index.html for requests to files or directories that do not exist 69 | ```json 70 | { 71 | "hosting": { 72 | "public": "dist", 73 | "ignore": [ 74 | "firebase.json", 75 | "**/.*", 76 | "**/node_modules/**" 77 | ], 78 | "rewrites": [ 79 | { 80 | "source": "**", 81 | "destination": "/index.html" 82 | } 83 | ] 84 | } 85 | } 86 | ``` 87 | * (optional) Create .firebaserc in the root project folder and set up default: 88 | ```json 89 | { 90 | "projects": { 91 | "default": "your_project_name" 92 | } 93 | } 94 | ``` 95 | * Create a build: 96 | ```NPM 97 | npm run build 98 | ``` 99 | * Deploy your app: 100 | ```npm 101 | firebase deploy 102 | ``` 103 | 104 | ## Deploy Node.js App (backend) 105 | 106 | ## Bitbucket Integration 107 | * Get deployment token: 108 | ```yml 109 | firebase login:ci 110 | ``` 111 | * Visit shown URL to confirm your request. 112 | * Copy generated token. 113 | * Create *bitbucket-pipelines.yml* file in the root directory: 114 | ```yml 115 | pipelines: 116 | default: 117 | - step: 118 | name: Client: install modules and run build 119 | image: node:10.15.3 120 | deployment: test 121 | script: 122 | - cd ./client 123 | - npm install 124 | - npm run build 125 | artifacts: # cache for next steps 126 | - client/dist/** 127 | - step: 128 | name: Client: Deploy to firebase 129 | script: 130 | - pipe: atlassian/firebase-deploy:0.2.4 131 | variables: 132 | FIREBASE_TOKEN: "FIREBASE_TOKEN" # paste generated token 133 | PROJECT_ID: "PROJECT_ID" # you can find projectId in firebase config 134 | DEBUG: 'true' 135 | ``` 136 | 137 | 138 | # Set up `node-gyp` for Windows (to make `grpc` work) 139 | 140 | Firebase may require GRPC module and GRPC requires [node-gyp](https://github.com/nodejs/node-gyp). 141 | There is a guide how I managed to install it after reading tons of stackoverflows resolving issues one after another. 142 | 143 | Download and open `Visual Studio Installer` (https://visualstudio.microsoft.com/downloads/). 144 | Intall `Visual Studio Build Tools 2022`. Select there: 145 | * `Desktop development with C++` 146 | 147 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/edb4764e-7e59-412d-bce5-477962bbed1c) 148 | 149 | * Some `SDK` 150 | 151 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/f2e17f8b-72e3-48bf-a9de-456db9d52b01) 152 | 153 | * `VC++` 154 | 155 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/f1dc472f-6870-4300-91de-0d8eae83f0a8) 156 | 157 | Then install, restart PC. 158 | 159 | ``` 160 | npm config edit 161 | 162 | msbuild_path=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\MSBuild.exe 163 | msbuild-path=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\MSBuild.exe 164 | msvs_version=2022 165 | msvs-version=2022 166 | python=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools 167 | ``` 168 | 169 | ``` 170 | SETX VCINSTALLDIR 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC' 171 | SETX VSINSTALLDIR 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools' 172 | refreshenv 173 | ``` 174 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/5dbe6296-09c7-4cf8-aa03-d514e247201a) 175 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/7a892ee6-b4cc-46ea-bd32-bb34dce4c238) 176 | 177 | ``` 178 | npm i -g node-gyp 179 | ``` 180 | 181 | Create `binding.gyp` text tile 182 | ```json 183 | { 184 | "targets": [ 185 | { 186 | "target_name": "binding", 187 | "sources": [ "./binding.cc" ] 188 | } 189 | ] 190 | } 191 | ``` 192 | Create empty `binding.cc` text file. 193 | 194 | ``` 195 | node-gyp configure 196 | node-gyp build 197 | node-gyp rebuild 198 | ``` 199 | now you can do `npm install` without `node-gyp` errors 200 | 201 | -------------------------------------------------------------------------------- /tech/Heroku.md: -------------------------------------------------------------------------------- 1 | # Heroku Deployment 2 | 3 | ## Get Started 4 | * Install Heroku CLI: 5 | ```yarn 6 | npm i -g heroku 7 | ``` 8 | * Login with: 9 | ```yarn 10 | heroku login 11 | ``` 12 | * Create a new empty heroku app: 13 | ```yarn 14 | heroku create 15 | ``` 16 | * Copy *app_id* and set up git remote with it: 17 | ```yarn 18 | heroku git:remote -a 19 | ``` 20 | * Make changes and commit them: 21 | ```git 22 | git add -A 23 | git commit -m "" 24 | ``` 25 | * Now you can deploy the app via: 26 | ```git 27 | git push heroku master 28 | ``` 29 | 30 | ## Basic commands 31 | * Command list: 32 | ```js 33 | heroku help 34 | ``` 35 | * Open app in a browser: 36 | ```js 37 | heroku open 38 | ``` 39 | -------------------------------------------------------------------------------- /tech/Jest.md: -------------------------------------------------------------------------------- 1 | # Concurrency params 2 | 3 | `--maxConcurrency=` 4 | Prevents Jest from executing more than the specified amount of tests at the same time. Only affects tests that use test.concurrent. 5 | 6 | `--maxWorkers=|` 7 | Alias: -w. Specifies the maximum number of workers the worker-pool will spawn for running tests. In single run mode, this defaults to the number of the cores available on your machine minus one for the main thread. In watch mode, this defaults to half of the available cores on your machine to ensure Jest is unobtrusive and does not grind your machine to a halt. It may be useful to adjust this in resource limited environments like CIs but the defaults should be adequate for most use-cases. 8 | 9 | For environments with variable CPUs available, you can use percentage based configuration: --maxWorkers=50% 10 | 11 | `--runInBand` 12 | Alias: -i. Run all tests serially in the current process, rather than creating a worker pool of child processes that run tests. This can be useful for debugging. 13 | 14 | 15 | -------------------------------------------------------------------------------- /tech/Klaviyo.md: -------------------------------------------------------------------------------- 1 | # Klavio 2 | - [Переменные и их методы](#переменные-и-их-методы) 3 | - [Циклы](#циклы) 4 | - [Условные операторы](#условные-операторы) 5 | - [Массивы и их методы](#массивы-и-их-методы) 6 | - [Форматирование](#форматирование) 7 | 8 | 9 | Klavio использует Django (Python) в качестве *шаблонизатора* (англ. `template engine`). 10 | 11 | ## Переменные и их методы 12 | - [Обращение к переменной](#обращение-к-переменной) 13 | - [Использование встроенных методов](#использование-встроенных-методов) 14 | - [Переменные со знаком `$` в названии](#переменные-со-знаком--в-названии) 15 | - [Передача переменной значения по умолчанию](#передача-переменной-значения-по-умолчанию) 16 | 17 | ### Обращение к переменной 18 | 19 | Обращение к переменной `foo`: 20 | ```hbs 21 | {{ foo }} 22 | ``` 23 | Если использовать переменную в тексте: 24 | ```hbs 25 | Hello, {{ name }}! 26 | ``` 27 | 28 | ### Использование встроенных методов 29 | Например, для применения метода с названием `method` с переменной `foo` используется следующий синтаксис: 30 | ```hbs 31 | {{ foo|method }} 32 | ``` 33 | Если метод может принимать параметры, то вызов метода `method` с параметром `param` имеет вид: 34 | ```hbs 35 | {{ foo|method:param }} 36 | ``` 37 | Если нужно применить к переменной `bar` последовательно два метода `method1` и `method2`, то 38 | ```hbs 39 | {{ foo|method1:param1|method2:param2 }} 40 | ``` 41 | 42 | ### Переменные со знаком `$` в названии 43 | Если переменная из контекста имеет знак `$` в своём названии (например, `$value`), то к ней нельзя обратиться как к `{{ $value }}`, поскольку это приведёт к синтаксической ошибке. 44 | Такие переменные нужно находить с помощью метода `lookup`, передавая ему в качестве параметра название переменной строкой: 45 | ```hbs 46 | {{ event|lookup:'$value' }} 47 | ``` 48 | 49 | ### Передача переменной значения по умолчанию 50 | ```hbs 51 | Hello, {{ name|default:'Sir' }}! 52 | ``` 53 | 54 | ## Циклы 55 | В Django существует только один вид циклов: `for..in`. Циклы `foreach`, `while`, `for`, `do..while` отсутствуют. 56 | ### Цикл `for` 57 | ```django 58 |
    59 | {% for unit in unit_list %} 60 |
  • {{ unit.name }} {{ unit.price }}
  • 61 | {% endfor %} 62 |
63 | ``` 64 | 65 | ## Условные операторы 66 | В Django существует только один вид условных операторов: `if..else`. Тернарный оператор `a ? b : c` отсуствует. 67 | 68 | ### Оператор if..else 69 | ```klaviyo 70 | {% if unit_list and unit_list|length > 1 %} 71 | Number of units: {{ unit_list|length }} 72 | {% else %} 73 | There are no units. 74 | {% endif %} 75 | ``` 76 | 78 | 79 | 80 | ## Массивы и их методы 81 | * `length` возвращает длину массива с названием `array` (также подходит для строк) 82 | ```hbs 83 | {{ array|length }} 84 | ``` 85 | * `length_is` возвращает логическое значение `true/false`, если длина массива `array` совпадает с указанной (например, `3`) 86 | ```hbs 87 | {{ array|length_is:"3" }} 88 | ``` 89 | 90 | ## Форматирование 91 | ### Форматирование числа с плавающей точкой 92 | * Приведение *числа с плавающей точкой* `float` к *точности* (англ. `precision`) до *двух знаков после запятой* 93 | (`7.3193 --> 7.32`, `6 --> 6.00`, `1.1 --> 1.10`, `3.0000000001 --> 3.00`): 94 | ```hbs 95 | {{ event.float|floatformat:2 }} 96 | ``` 97 | 98 | ### Форматирование даты 99 | * Перевод даты `date` из формата `ISO` (например, `2022-02-16T21:57:21.323Z`) в *американский формат* `MM/DD/YYYY`: 100 | ```hbs 101 | {{ event.date|format_date_string|date:'m/d/Y' }} 102 | ``` 103 | 104 | -------------------------------------------------------------------------------- /tech/Kubernetes.md: -------------------------------------------------------------------------------- 1 | 2 | # Компоненты 3 | 4 | ## Кластер `Cluster`, узлы `Nodes`, модули `Pods`, `Workload` 5 | Для начала работы с Kubernetes необходимо создать *Кластер*. 6 | 7 | **Кластер** (англ. `Cluster`) представляет собой *множество* *Узлов*. 8 | 9 | Каждый **Узел** *представляет собой рабочую машину* (англ. `worker machine`), являющуюся *частью Кластера* и *запускающую контейнерные приложения* (англ. `containerized applications`). *Узлы* в *Кластере* *не являются частью публичного интернета*, то есть они *не общедоступны*. 10 | 11 | На рабочих *Узлах размещаются* **Модули** (англ. `Pods`), являющиеся *компонентами приложения*, компонентами Workload. 12 | **Workload** (рус. `рабочая нагрузка`) - это приложение, запущенное в Kubernetes. 13 | 14 | ## Контрольный план 15 | 16 | **Контрольный план** (англ. `Control plane`) 17 | > The container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers. 18 | 19 | 20 | 21 | 22 | ## Ingress 23 | -------------------------------------------------------------------------------- /tech/Microservices.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Принципы построения микросервисов 4 | 5 | При разделении приложения на микросервисы важно следовать определённым принципам, чтобы система оставалась поддерживаемой, масштабируемой и эффективной. Вот ключевые принципы, которые следует учитывать: 6 | 7 | Следуя этим принципам, вы можете разбить своё приложение на микросервисы таким образом, чтобы максимально использовать преимущества микросервисной архитектуры, минимизируя при этом потенциальные недостатки, такие как повышенная сложность и операционные накладные расходы. 8 | 9 | ## Принцип единственной ответственности 10 | 11 | Каждый микросервис должен фокусироваться на конкретной бизнес-возможности или функции. 12 | Это повышает поддерживаемость и делает сервисы легче для понимания и управления. 13 | 14 | ## Ограниченные контексты (Domain-Driven Design) 15 | 16 | Используйте предметно-ориентированное проектирование для идентификации отдельных областей (ограниченных контекстов) внутри вашей доменной модели. 17 | Соотнесите микросервисы с этими контекстами, чтобы обеспечить инкапсуляцию связанных данных и поведения. 18 | 19 | ## Слабая связанность и высокая когезия 20 | 21 | **Слабая связанность** (англ. `low coupling`) - cервисы должны иметь минимальные зависимости друг от друга, чтобы снизить влияние изменений. 22 | 23 | **Высокая когезия** (англ. `high cohesion`) - группируйте связанные функции внутри одного сервиса, чтобы сохранить их целостность. 24 | 25 | 26 | ## Ориентация на бизнес-возможности (англ. `Business Capability Orientation`) 27 | 28 | Организуйте микросервисы вокруг бизнес-возможностей, а не технических слоёв (например, пользовательский интерфейс, бизнес-логика, доступ к данным). 29 | Это обеспечивает предоставление сервисами полной функциональности от начала до конца. 30 | 31 | ## Независимая развертываемость 32 | Проектируйте сервисы так, чтобы их можно было разрабатывать, тестировать, развертывать и масштабировать независимо. 33 | 34 | Это снижает риски развертывания и позволяет быстрее проводить итерации. 35 | 36 | ## Владение данными и их хранение: 37 | 38 | Каждый микросервис должен владеть своей базой данных и управлять своими данными, чтобы предотвратить тесную связанность через общие базы данных. 39 | Это способствует инкапсуляции данных и автономности сервисов. 40 | 41 | ## Явные контракты сервисов (API): 42 | 43 | Определите чёткие и стабильные интерфейсы для взаимодействия между сервисами. 44 | Используйте хорошо определённые API для управления коммуникацией и обеспечения обратной совместимости при обновлении сервисов. 45 | 46 | ## Асинхронная коммуникация: 47 | 48 | Предпочитайте асинхронное обмен сообщениями для межсервисного взаимодействия, чтобы улучшить масштабируемость и устойчивость. 49 | Это помогает разъединить сервисы и более эффективно обрабатывать изменяющиеся нагрузки. 50 | 51 | ## Избегайте преждевременной оптимизации (правильный размер сервисов): 52 | 53 | Избегайте слишком детального разделения сервисов с самого начала; начните с более крупных сервисов и при необходимости рефакторьте. 54 | Чрезмерно гранулированные сервисы могут привести к повышенной сложности и накладным расходам. 55 | 56 | ## Организационное соответствие (закон Конуэя): 57 | 58 | Соотнесите границы микросервисов со структурой команд, чтобы усилить владение и ответственность. 59 | Кросс-функциональные команды могут управлять сервисами от разработки до развертывания. 60 | 61 | ## Устойчивость и изоляция отказов: 62 | 63 | Проектируйте сервисы так, чтобы они могли справляться с отказами без влияния на всю систему. 64 | Реализуйте прерыватели цепи, повторные попытки и тайм-ауты для управления сбоями в межсервисной коммуникации. 65 | 66 | ## Независимость технологий и платформ: 67 | 68 | Позвольте сервисам использовать наиболее подходящие технологии для их специфических потребностей. 69 | Эта гибкость может оптимизировать производительность и использовать специализированные инструменты. 70 | 71 | ## Соображения масштабируемости: 72 | 73 | Идентифицируйте сервисы, которые требуют независимого масштабирования на основе нагрузки. 74 | Разделите сервисы для оптимизации использования ресурсов и производительности. 75 | 76 | ## Мониторинг и логирование: 77 | 78 | Реализуйте централизованный мониторинг и логирование для отслеживания состояния и производительности сервисов. 79 | Обеспечьте видимость межсервисной коммуникации для устранения неполадок и анализа. 80 | 81 | ## Границы безопасности: 82 | 83 | Рассматривайте каждый сервис как границу безопасности. 84 | Обеспечьте аутентификацию и авторизацию на уровне сервиса для повышения безопасности. 85 | Соответствие нормативным требованиям и чувствительность данных: 86 | 87 | Учитывайте юридические и нормативные требования при определении границ сервисов. 88 | Изолируйте сервисы, обрабатывающие конфиденциальные данные, чтобы упростить управление соответствием. 89 | 90 | ## Эволюционный дизайн: 91 | 92 | Будьте готовы, что границы сервисов могут изменяться со временем, а это значит, что придётся рефакторить и развивать архитектуру по мере углубления понимания домена. 93 | -------------------------------------------------------------------------------- /tech/MongoDB.md: -------------------------------------------------------------------------------- 1 | - [О MongoDB](#о-mongodb) 2 | - [Основные понятия](#основные-понятия) 3 | - [Документ](#документ) 4 | - [Коллекция](#коллекция) 5 | - [Операции над данными](#операции-над-данными) 6 | - [Агрегации](#агрегации) 7 | - [Работа с типами данных](#работа-с-типами-данных) 8 | - [Обновление данных в массиве](#обновление-данных-в-массиве) 9 | - [Оператор $push](#оператор-push) 10 | - [Оператор $pull](#оператор-pull) 11 | - [Выборка элементов](#выборка-элементов) 12 | - [Поиск объекта в массиве объектов (`$elemMatch`)](#поиск-объекта-в-массиве-объектов-elemmatch) 13 | 14 | # О MongoDB 15 | 16 | **MongoDB** - это *документно-ориентированная* база данных (англ. document-oriented database), что означает, что *каждый объект* (реальный или абстрактный) *представляется* в виде *отдельного документа*, *хранящегося* в *базе данных* в *формате JSON*. 17 | 18 | *MongoDB* относят к *типу NoSQL баз данных* или *нереляционных баз данных*, поскольку *MongoDB* не *использует синтаксис языка SQL* и *реляционную модель данных*. 19 | 20 | # Основные понятия 21 | - [Документ](#документ) 22 | - [Коллекция](#коллекция) 23 | 24 | 25 | ## Документ 26 | 27 | Любой объект в MongoDB представляются в виде **документа** (англ. document). 28 | 29 | *Каждый документ представляет* собой *множество* пар **"ключ-значение"** (англ. key-value). 30 | 31 | Ключи также называют **полями** (англ. fields). 32 | 33 | Каждый документ обязательно хранит поле `_id`, по которому можно уникально идентифицировать любой документ. Это поле имеет тип `ObjectId` и генерируется автоматически при добавлении документа, если его не задать. 34 | 35 | *Пример документа*, *хранящего данные* некоторого *сообщения*, отправленного в некоторой *системе* для *обмена сообщениями*: 36 | ```js 37 | { 38 | "_id": ObjectId("60b3a171e3168e00b9f28e33"), 39 | "text": "Go for it.", 40 | "sender": ObjectId("5f694dcf36a0f350f8ea75f3"), 41 | "recipients": [ 42 | ObjectId("5f694dce36a0f350f8ea75cf" 43 | ] 44 | } 45 | ``` 46 | 47 | Аналагом документа в SQL является **строка таблицы** (англ. row), а одному *полю* соответствует **столбец таблицы** (англ. column). 48 | 49 | ## Коллекция 50 | Несколько объектов, обладающих схожими свойствами, объединяют в **коллекцию** (англ. collection). 51 | 52 | Пример коллекции `users`: 53 | ```js 54 | [{ 55 | "_id": ObjectId("3ae0017l0ff1234567b0be7e"), 56 | "username": "Max-Starling", 57 | "following": [ 58 | ObjectId("5f694d9936a0f350f8ea6e83") 59 | ], 60 | "followers": [ 61 | ObjectId("5f694d9936a0f350f8ea6e83"), 62 | ObjectId("4a694d7196e3f350f4ea3e16") 63 | ], 64 | "settings": { 65 | "mode": "dark" 66 | }, 67 | "createdAt": "2017-07-17T01:07:01.787+00:00", 68 | }, 69 | { 70 | "_id": ObjectId("4a694d7196e3f350f4ea3e16"), 71 | "username": "Manfredi", 72 | "following": [ 73 | ObjectId("3ae0017l0ff1234567b0be7e") 74 | ], 75 | "followers": [], 76 | "settings": { 77 | "mode": "light", 78 | "fontSize": 12, 79 | }, 80 | "createdAt": "2018-08-18T00:04:01.123+00:00", 81 | }] 82 | ``` 83 | 84 | # Операции над данными 85 | - [Агрегации](#агрегации) 86 | - [Доступные операции в методе aggregate](#доступные-операции-в-методе-aggregate) 87 | - [Работа с типами данных](#работа-с-типами-данных) 88 | 89 | 90 | ## Агрегации 91 | - [Определения и разновидности агрегаций](#определения-и-разновидности-агрегаций) 92 | - [Доступные операции в методе aggregate](#доступные-операции-в-методе-aggregate) 93 | 94 | ### Определения и разновидности агрегаций 95 | 96 | **Агрегация** (от лат. `aggregatio` - *присоединение*, англ. `agregation`) в *общем случае* означает *процесс объединения* некоторых *объектов* в одну *группу* ( (англ. `a cluster of things`, `a collection of items`). 97 | 98 | 99 | 100 | 101 | 102 | В терминалогии баз данных **агрегациями** или **агрегационными функциями** (англ. `aggregate function`) называют *операции*, которые *преобразуют* некоторую *заданную группу значений* (a set of values) в *одно значение* (single value). 103 | 104 | Например, такими агрегационными функциями являются: 105 | * *Сумма* (`sum`). 106 | * *Подсчёт количества элементов* (`count`). 107 | * *Вычисление среднего значения* (`avg`). 108 | * *Нахождение минимума* (`min`). 109 | * *Нахождение максимума* (`max`). 110 | 111 | 112 | К *агрегациям* также *относят операцию группировки* (`group`). 113 | 114 | В *JavaScript* нечто *подобное* можно *сделать* с *массивом* при помощи *метода* `Array.reduce()`: 115 | ```js 116 | const values = [1, 2, 3]; 117 | 118 | const sum = values.reduce((sum, value) => sum + value, 0); 119 | console.log(sum); // 6 120 | 121 | const count = values.reduce((count, value) => count + 1, 0); 122 | console.log(count); // 3 123 | 124 | const avg = values.reduce((sum, value) => sum + (value / count), 0); 125 | console.log(avg); // 2 126 | 127 | const min = values.reduce((sum, value) => Math.min(sum, value)); 128 | console.log(min); // 1 129 | 130 | const max = values.reduce((sum, value) => Math.max(sum, value)); 131 | console.log(max); // 3 132 | ``` 133 | 134 | Так, например, при помощи агрегации можно выбрать документы из коллекции, сгруппировать их по некоторому критерию и оставить только необходимые поля. 135 | 136 | В MongoDB агрегирование чаще всего осуществляется за счёт метода `collection.aggregate(pipeline)`, где `pipeline` - массив, каждый объект которого описывает некоторую операцию над данными. 137 | 138 | 139 | 140 | ### Доступные операции в методе aggregate 141 | #### Операция $match 142 | #### Операция $group 143 | #### Операция $project 144 | 145 | ### Пример агрегации с группировкой и подсчётом 146 | 147 | В примере ниже мы ищем сотрудников компании с зарплатой больше 1000, группируем их по их роду деятельности и считаем количество сотрудников в каждой группе. 148 | ```js 149 | const pipeline = [ 150 | { $match: { salary: { $gte: 1000 } }, 151 | { 152 | $group: { 153 | _id: '$profession', 154 | number: { $sum: 1 }, 155 | }, 156 | }, 157 | { 158 | $project: { 159 | _id: 0, 160 | profession: '$_id', 161 | number: 1, 162 | }, 163 | }, 164 | ]); 165 | ]; 166 | 167 | /* workers: [ 168 | { _id: 1, salary: 500, profession: 'cleaner' }, 169 | { _id: 2, salary: 1200, profession: 'developer' }, 170 | { _id: 3, salary: 1500, profession: 'developer' }, 171 | { _id: 3, salary: 1000, profession: 'tester' }, 172 | { _id: 4, salary: 900, profession: 'tester' }, 173 | ] */ 174 | 175 | const workersCollection = db.collection('workers'); 176 | 177 | const bigSalaryInfo = await workersCollection.aggregate(pipeline); 178 | 179 | /* bigSalaryInfo: [ 180 | { profession: 'developer', number: 2 }, 181 | { profession: 'tester', number: 1 }, 182 | ] */ 183 | ``` 184 | 185 | 186 | 187 | ## Работа с типами данных 188 | - [Получение документов по заданному типу данных](#получение-документов-по-заданному-типу-данных) 189 | - [Приведение типа некоторого поля документов коллекции](#приведение-типа-некоторого-поля-у-документов-коллекции) 190 | 191 | Допустимые типы данных: 192 | ```js 193 | const MONGO_TYPES = { 194 | bool: 'bool', 195 | date: 'date', 196 | decimal: 'decimal', 197 | double: 'double', 198 | int: 'int', 199 | long: 'long', 200 | objectId: 'objectId', 201 | string: 'string' 202 | } 203 | ``` 204 | 205 | ### Получение документов по заданному типу данных 206 | 207 | ```js 208 | const animalsCollection = db.collection('animals'); 209 | const document animalsCollection.find({ 210 | age: { $type: 'int' }, 211 | }) 212 | ``` 213 | 214 | ### Приведение типа некоторого поля у документов коллекции 215 | 216 | Допустимые методы приведения типов: 217 | ```js 218 | const MONGO_CAST_METHODS= { 219 | bool: '$toBool', 220 | date: '$toDate', 221 | decimal: '$toDecimal', 222 | double: '$toDouble', 223 | int: '$toInt', 224 | long: '$toLong', 225 | objectId: '$toObjectId', 226 | string: '$toString', 227 | }; 228 | ``` 229 | Код ниже *обновляет только* те *документы коллекции* `bills`, *значение поля* `amount` которых имеет *строковый тип*, при этом *производится приведение* этого *значения* к *числовому типу* `double`. 230 | ```js 231 | const billsCollection = db.collection('bills'); 232 | 233 | /* bills: [ 234 | { _id: ObjectId(...), "amount': "123.50" }, 235 | { _id: ObjectId(...), "amount': 17 } 236 | ] */ 237 | 238 | await billsCollection.update( 239 | { 240 | "amount": { $type: 'string' }, 241 | }, 242 | [{ 243 | $set: { 244 | "amount": { $toDouble: "$amount" }, 245 | }, 246 | }], 247 | { multi: true }, 248 | ); 249 | 250 | /* bills: [ 251 | { _id: ObjectId(...), "amount': 123.5 }, 252 | { _id: ObjectId(...), "amount': 17 } 253 | ] */ 254 | ``` 255 | 256 | Метод ниже *находит все документы колекции* `collection`, *значение поля* `fieldName` которых *имеет строковый тип*, и *приводит* их к *типу* `date`. 257 | ```js 258 | const castStringFieldToDate = (collection, fieldName) => { 259 | return collection.update( 260 | { 261 | `${fieldName}`: { $type: 'string' }, 262 | }, 263 | [ 264 | { 265 | $set: { 266 | `${fieldName}`: { 267 | $toDate: `$${fieldName}`, 268 | }, 269 | }, 270 | }, 271 | ], 272 | { multi: true }, 273 | ); 274 | } 275 | 276 | /* ... */ 277 | 278 | const usersCollection = db.collection('users'); 279 | /* users: [{ _id: ObjectId(...), "joinDate': "2020-09-22T01:05:18.486Z" }] */ 280 | await castStringFieldToDouble(usersCollection, 'joinDate') 281 | /* users: [{ _id: ObjectId(...), "joinDate': { $date: "2020-09-22T01:05:18.486Z" }}] */ 282 | ``` 283 | 284 | # Обновление данных в массиве 285 | 286 | ## Оператор $push 287 | 288 | *Оператор* `$push` *добавляет один элемент* `` в *массив* ``. 289 | ```js 290 | { $push: { : } } 291 | ``` 292 | 293 | ```js 294 | db.favoritePages.insertOne({ 295 | _id: 17, 296 | pages: [3, 21, 73] 297 | }) 298 | // favoritePages: [{ _id: 17, pages: [3, 21, 73] }] 299 | db.favoritePages.updateOne( 300 | { _id: 17 }, 301 | { $push: { pages: 101 } } 302 | ) 303 | // favoritePages: [{ _id: 17, pages: [3, 21, 73, 101] }] 304 | ``` 305 | Для *добавления нескольких элементов* ``, `` в *массив* `` 306 | 307 | ```js 308 | { $push: { : { $each: [, ] } } } 309 | ``` 310 | 311 | ```js 312 | db.favoritePages.updateOne( 313 | { _id: 17 }, 314 | { $push: { pages: { $each: [277, 314] } } } 315 | ) 316 | // favoritePages: [{ _id: 17, pages: [3, 21, 73, 101, 277, 314] }] 317 | ``` 318 | 319 | ## Оператор $pull 320 | 321 | # Выборка элементов 322 | 323 | ## Поиск объекта в массиве объектов (`$elemMatch`) 324 | 325 | Допустим, у нас в схеме коллекции `workspace` содержится массив пользователей. 326 | ```js 327 | /* Workspace Schema */ 328 | { 329 | uuid: String; 330 | name: String; 331 | users: [{ 332 | uuid: String; 333 | name: String; 334 | }] 335 | } 336 | ``` 337 | Если мы хотим найти воркспейс, содержащий определённого пользователя, следует использовать оператор `$elemMatch`. 338 | 339 | Оператор `$elemMatch` находит документы, которые содержат в поле-массиве хотя бы один элемент, который удовлетворяет всем указанным параметрам вложенного query-запроса, передаваемого в качестве значения для `$elemMatch`. 340 | 341 | Допустим, в коллекции имеется следующий документ. 342 | ```js 343 | { 344 | id: 'w17', 345 | name: 'lab', 346 | users: [{ 347 | id: 'u19', 348 | name: 'Kat', 349 | }, { 350 | id: 'u22', 351 | name: 'Tom', 352 | }] 353 | } 354 | ``` 355 | Оба query-запроса ниже включат документ выше в выборку: 356 | ```js 357 | { users: { $elemMatch: { id: 'u19' } } } 358 | { users: { $elemMatch: { name: 'Tom' } } } 359 | ``` 360 | -------------------------------------------------------------------------------- /tech/Parcing-Preprocessing-StaticChecking.md: -------------------------------------------------------------------------------- 1 | 2 | ## Препроцессинг 3 | 4 | **Препроцессинг** (англ. `Preprocessing`) подразумевает приведение кода одного формата к другому формату. 5 | Например, удалить все лишние проблемы, или все комментарии. Это может быть сделано при помощи резулярных выражений, строить синтаксическое дерево в данном случае не требуется. 6 | 7 | ## Парсинг 8 | 9 | **Парсинг** (англ. `Parsing`) подразумевает лесический анализ кода и построение абстрактного синтаксического дерева. 10 | В этом случае код (представляющий из себя набор/поток символов) разбивается на токены отделимые блоки. 11 | 12 | Например, код `while (count > 0)` может быть разбит на токены: 13 | * `keyword(while)` 14 | * `leftParenthesis` 15 | * `variable(count)` 16 | * `operator(>)` 17 | * `number(0)` 18 | * `rightPerenthesis` 19 | 20 | ### Статический парсинг 21 | 22 | ### Динамический парсинг 23 | 24 | ## Статическая проверка кода 25 | 26 | Существует два этапа: компиляция (интерпретация) кода и его непосредственное выполнение. 27 | 28 | Статическая проверка кода подразумевает статический анализ кода, то есть проверку кода на этапа компиляции. В этом случае код реально не выполняется. 29 | 30 | Таким образом, строится синтаксическое дерево и проверку кода на ошибки (компиляции) производится на основании результата поостроения. 31 | -------------------------------------------------------------------------------- /tech/PostCSS.md: -------------------------------------------------------------------------------- 1 | # PostCSS Setup 2 | ## NPM 3 | ``` 4 | npm install postcss-cli stylelint stylelint-config-standard postcss-cssnext precss postcss-cssnext cssnano --save-dev 5 | npm install stylelint -g 6 | ``` 7 | ## package.json 8 | ```json 9 | { 10 | "scripts": { 11 | "styles": "postcss input.postcss --config postcss.config.js --output output.min.css --watch" 12 | }, 13 | } 14 | ``` 15 | ## postcss.config.js 16 | ```js 17 | module.exports = () => ({ 18 | plugins: { 19 | 'stylelint': {}, 20 | 'precss': {}, 21 | 'postcss-cssnext': {}, 22 | 'cssnano': { 23 | 'autoprefixer': false 24 | } 25 | } 26 | }); 27 | ``` 28 | ## .stylelintrc 29 | ```json 30 | { 31 | "extends": "stylelint-config-standard", 32 | "rules": { 33 | "selector-max-class": 2 34 | } 35 | } 36 | ``` 37 | ## VSCode Settings (settings.json) 38 | ```json 39 | { 40 | "emmet.includeLanguages":{ 41 | "postcss": "css" 42 | }, 43 | "emmet.syntaxProfiles": { 44 | "postcss": "css" 45 | }, 46 | "css.validate": false, 47 | "less.validate": false, 48 | "scss.validate": false, 49 | "postcss.validate": false, 50 | "files.associations": { 51 | "*.postcss": "postcss", 52 | }, 53 | "[postcss]": { 54 | "editor.defaultFormatter": "esbenp.prettier-vscode" 55 | } 56 | } 57 | ``` 58 | 59 | ## VSCode extensions 60 | * postcss-sugarss-language 61 | * Prettier - Code formatter (format document with Alt + Shift + F) 62 | * stylelint 63 | 64 | ## PostCSS Setup (Webpack) 65 | ```js 66 | { 67 | test: /\.css$/, 68 | use: [ 69 | 'style-loader', 70 | 'css-loader', 71 | { 72 | loader: 'postcss-loader', 73 | options: { 74 | ident: 'postcss', 75 | plugins: [ 76 | require('stylelint')(), 77 | /* ... */, 78 | ], 79 | }, 80 | }, 81 | ], 82 | } 83 | { 84 | loader: 'postcss-loader', 85 | options: { 86 | ident: 'postcss', 87 | plugins: [ 88 | require('autoprefixer')(), 89 | require('stylelint')(), 90 | /* ... */ 91 | ] 92 | } 93 | } 94 | ``` 95 | 96 | ## CSS Modules Setup (Webpack) 97 | ```js 98 | { 99 | test: /\.css$/, 100 | use: [ 101 | 'style-loader', 102 | { 103 | loader: 'css-loader', 104 | options: { 105 | modules: true, 106 | importLoaders: 1, 107 | localIdentName: '[name]__[local]___[hash:base64:4]', 108 | }, 109 | }, 110 | { 111 | loader: 'postcss-loader', 112 | options: { /* ... */ }, 113 | }, 114 | ], 115 | } 116 | ``` 117 | -------------------------------------------------------------------------------- /tech/Postman.md: -------------------------------------------------------------------------------- 1 | ## Понятия в Postman 2 | 3 | Есть рабочее пространство (англ. `Workspace`), по умолчанию используется `My workspace`. 4 | В рабочем пространстве можно создавать коллекции (англ. `Collections`) логически сгруппированных запросов. 5 | 6 | Каждый запрос (`Request`) представляет собой сохранённую информацию об HTTP-запросе: 7 | * классические метод, URL, параметры, заголовки, тело запроса 8 | * но также тесты, Pre-request script и настройки запроса. 9 | 10 | Сохраняя информацию о запросе в коллекцию, вы можете в любой момент переиспользовать её в качестве темплейта для новых запросов или же переодически вызывать один и тот же запрос в один клик в любое время. 11 | 12 | У колекции также есть свои настройки, которые применяются ко всем запросам в ней: 13 | * переменные окружения 14 | * pre-request-script 15 | * тесты и так далее 16 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/9b118c4e-8cfa-47ae-b23d-7964764fe698). 17 | 18 | Ниже представлен небольшой схематичный пример, как можно было бы использовать свое личное рабочее пространство: 19 | * My workspace 20 | * Users dashboard Prod 21 | * Get users - GET https://users-dashboard.com/api/users 22 | * Get user by id - GET http://users-dashboard.com/api/users/:id 23 | * Users dashboard Local 24 | * Get users - GET http://localhost:3001/api/users 25 | * Get user by id - GET http://localhost:3001/api/users/:id 26 | * Calculator 27 | * Calculate - POST http://localhost:3002/api/calculate 28 | 29 | но можно также для каждого проекта создавать новое рабочее пространство для наилучшей изолированности (вдруг вы собираетесь давать доступ кому-то к ворксейсам): 30 | * Users dashboard 31 | * Production 32 | * Get users - GET https://users-dashboard.com/api/users 33 | * Get user by id - GET http://users-dashboard.com/api/users/:id 34 | * Localhost 35 | * Get users - GET http://localhost:3001/api/users 36 | * Get user by id - GET http://localhost:3001/api/users/:id 37 | * Calculator workspace 38 | * Localhost 39 | * Calculate - POST http://localhost:3002/api/calculate 40 | 41 | Часто бывает так, что в одной компании может быть несколько проектов, на каждый проект- отдельная коллекция, но все проекты в одном пространстве. 42 | 43 | Если есть версионирование, можно разбивать коллекции по версиям. 44 | 45 | * Users dashboard 46 | * Api v1.0 47 | * Get users - GET https://users-dashboard.com/api/v1.0/users 48 | * Api v1.1 49 | * Get users - GET https://users-dashboard.com/api/v1.1/users 50 | * Get users by name - GET https://users-dashboard.com/api/v1.1/users/:name 51 | * Api v2 52 | * Get users - GET https://users-dashboard.com/api/v2/users 53 | * Get users by ID - GET https://users-dashboard.com/api/v2/users/:id 54 | 55 | ## Использование переменных в Postman 56 | 57 | Чтобы постоянно не клонировать коллекции с одними и теми же запросами и минимальными различиями в параметрах, можно задать переменные окружения. Сделать это можно в настройках коллекции: 58 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/80a01de8-5c23-4b8f-be23-03d41f521def) 59 | 60 | например, вместо того, чтобы создавать две коллекции `Users dashboard Local`, `Users dashboard Production`, досточно просто завести переменную `base_url`. 61 | ``` 62 | base_url = http://localhost:3001 63 | ``` 64 | и использовать её в запросе: 65 | ``` 66 | GET {{base_url}}/api/v1.0/users 67 | ``` 68 | 69 | 70 | ## Postman pre-request script 71 | Скрипт, который производит ре-аутентификацию с каждым запросом. Сохраняется в 72 | ```js 73 | const postRequest = { 74 | url: `${pm.collectionVariables.get("base_url")}${pm.collectionVariables.get("access_token_endpoint")}`, 75 | method: "post", 76 | header: { 77 | "Content-Type": "application/json", 78 | }, 79 | body: JSON.stringify({ 80 | clientId: pm.collectionVariables.get("client_id"), 81 | secret: pm.collectionVariables.get("secret") 82 | }), 83 | }; 84 | 85 | pm.sendRequest(postRequest, (error, response) => { 86 | if (error) { 87 | console.log(error); // catch in Postamn debug console 88 | } else { 89 | pm.collectionVariables.set("access_token", response.json().accessToken); 90 | } 91 | }); 92 | ``` 93 | -------------------------------------------------------------------------------- /tech/Python.md: -------------------------------------------------------------------------------- 1 | 2 | # Types 3 | 4 | ## String 5 | 6 | ### Concat string 7 | Binary `+` operator is used for *string concatenation*. 8 | ```py 9 | hi = "Hi" 10 | there = "There" 11 | result_str = hi + " " + there 12 | print(result_str) 13 | ``` 14 | ### Convert to string 15 | 16 | ```py 17 | n = 17 18 | s = str(num) 19 | print(s) // "17" 20 | ``` 21 | 22 | ## Список `list` 23 | 24 | ## Кортеж `tuple` 25 | 26 | ## Словарь `dictionary` 27 | 28 | ## Конкатенация `contatenation` при помощи `join` 29 | 30 | Конкатенация при помощи`join`может быть применена к любому перечисляемому типу данных (англ. `iterable`), то есть к: 31 | * множествам `set` 32 | * спискам `list` 33 | * кортежам `tuple` 34 | * словарям `dict` 35 | * строкам `str` 36 | 37 | Примеры 38 | ```python 39 | # set 40 | greeting_set = {"world", "Hello"} 41 | print(" ".join(greeting_set)) # --> "Hello world" (в обратном порядке) 42 | 43 | # list 44 | vowels_list = ['a', 'e', 'i', 'o', 'u'] 45 | print(", ".join(vowels_list)) # --> "a, e, i, o, u" 46 | 47 | # tuple 48 | country_tuple = ("Ukraine", "Ukrainian", 36.7) # ("country", "language", "population (m)") 49 | print(" - ".join(country_tuple)) # --> Ukraine - Ukrainian - 36.7 50 | 51 | # dict 52 | users_dict = {"Max": 17, "Frank": 21, "Tom": 13} 53 | print(" and ".join(users_dict)) # --> Max and Frank and Tom 54 | 55 | ## str 56 | nickname = 'starling' 57 | print("_".join(nickname)) # s_t_a_r_l_i_n_g 58 | ``` 59 | 60 | ## JSON 61 | ### Parse JSON to Dictionary 62 | ```py 63 | import json 64 | 65 | repo_json = '{ "user":"Max-Starling", repo: "Notes" }' 66 | 67 | # Parse repo_json 68 | repo_dict = json.loads(repo_json) 69 | 70 | # Access a dictionary field 71 | print(repo_dict["user"]) 72 | ``` 73 | ### Convert to JSON 74 | ```py 75 | import json 76 | 77 | repo_dict = { 78 | "user":"Max-Starling" 79 | repo: "Notes" 80 | } 81 | 82 | # Convert to JSON 83 | repo_json = json.dumps(x) 84 | 85 | # Print JSON 86 | print(repo_json) 87 | ``` 88 | ### Intends in JSON 89 | You can set number of indents in JSON 90 | ```py 91 | json.dumps(x, indent=4) 92 | ``` 93 | ### JSON Types mapping table 94 | 95 | | Python Type | JSON | 96 | | ------- | ------ | 97 | | dict | Object | 98 | | list, typle | Array | 99 | | str | String | 100 | | int, float | Number | 101 | | True | true | 102 | | False | false | 103 | | None | null | 104 | 105 | # Типизация (`Typing`) 106 | 107 | Python не требует от нас явного указания типов, но их указание помогает избежать множества ошибок, а ещё делает ваш код более понятным для других разработчиков. 108 | 109 | Задать тип можно 110 | * переменной после двоеточия `:`: 111 | ```py 112 | BASE_URL: str = 'http://localhost:8080' 113 | ``` 114 | * аргументу функции после `:` и возвращаемому значению функции после `->`. 115 | ```py 116 | def getFullUrl(baseUrl: str, endpoint: str) -> str: 117 | return f"{baseUrl}{endpoint}"; 118 | ``` 119 | * параметру класса после `:` (причём в классах тип обязателен для каждого поля) 120 | ```py 121 | class User: 122 | email: str 123 | age: int 124 | 125 | testUser: User = { 126 | 'email': 'test@email', 127 | 'age': 0 128 | } 129 | ``` 130 | ### Примитивные типы данных 131 | * `str` - строковый тип 132 | * `int` - целочисленный тип 133 | * `float` - тип числа с правающей точкой 134 | * `bool` - логический тип 135 | * `complex` - тип комплексного числа, то есть числа с действительной и мнимой частью, содержащей мнимую единицу `j` 136 | 137 | ## Составные типы данных 138 | 139 | Составные типы данных (например, состоящие из нескольких значений, возможно, разных типов данных) испортируются из библиотеки `typing`: 140 | * `List[x]` - список, массив 141 | * `Set[x]` - множество 142 | * `Tuple` - кортеж 143 | * `Dict[x, y]` - словарь, объект, ассоциативный массив ("ключ-значение") 144 | * `Union` - объединение, перечисление допустимых типов. 145 | ```py 146 | Union[int, str] # тип `int` или `str` 147 | Union[int] == int # объединение одного типа эквивалентно этому типу 148 | Union[int, str, int] == Union[int, str] # повторяющиеся типы исключаются из объединения 149 | Union[Union[int, str], float] == Union[int, str, float] 150 | Union[int, str] == Union[str, int] # порядок задания типом в объединении не важен 151 | ``` 152 | * `Option` означает, что значение задавать не обязательно. Если значение не задать, ошибки не будет. 153 | ```py 154 | Optional[T] # эквивалентно `Union[T, None]` 155 | ``` 156 | ```py 157 | from typing import Optional 158 | 159 | class DatabricksConnectionStringConfig: 160 | hostname: str 161 | token: str 162 | port: Optional[int] = 443 163 | ``` 164 | 165 | ### Чем отличаются List, Set, Dict 166 | 167 | #### Список 168 | 169 | List - упорядоченный набор элементов. Каждому элементу присваивается индекс (порядок), по которому вы можете найти нужный элемент. 170 | 171 | Используете его, если *порядок элементов важен*. 172 | 173 | Например, список призёров турнира, номера камер хранения в магазине. 174 | 175 | #### Множество 176 | 177 | Set - неупорядоченный набор уникальных элементов. Используете его, если порядок не важен - важна уникальность элементов. 178 | 179 | Например, список имён всех авторов комментариев под постом в некой социальной сети (один человек может отставить комментарий сколько угодно раз, но в список его имя попадёт лишь единожды). 180 | 181 | #### Словарь 182 | 183 | Dict - словарь, ассоциативный массив "ключ-значение", хеш-таблица, карта. 184 | 185 | Используйте словарь, если вам нужно связать некоторые данные с каким-то ключом, по которому вы всегда эффективно сможете их найти. 186 | 187 | Например, англо-русский словарь: ключ: "hello" - значение "привет". 188 | 189 | Do you just need an ordered sequence of items? Go for a list. 190 | Do you just need to know whether or not you've already got a particular value, but without ordering (and you don't need to store duplicates)? Use a set. 191 | Do you need to associate values with keys, so you can look them up efficiently (by key) later on? Use a dictionary. 192 | 193 | # Функции 194 | 195 | ## Лямбда-функции 196 | 197 | TODO 198 | 199 | Лямбда-выражение в программировании — специальный синтаксис для определения функциональных объектов, заимствованный из λ-исчисления. 200 | 201 | Лямбда-выражения принимают две формы. Форма, которая наиболее прямо заменяет анонимный метод, представляет собой блок кода, заключенный в фигурные скобки. Это — прямая замена анонимных методов. Лямбда-выражения, с другой стороны, предоставляют ещё более сокращенный способ объявлять анонимный метод и не требуют ни кода в фигурных скобках, ни оператора return. Оба типа лямбда-выражений могут быть преобразованы в делегаты. 202 | 203 | Во всех лямбда-выражениях используется лямбда-оператор =>, который читается как «переходит в» (в языках Java, F# и PascalABC.NET используется оператор ->). Левая часть лямбда-оператора определяет параметры ввода (если таковые имеются), а правая часть содержит выражение или блок оператора. Лямбда-выражение x => x * 5 читается как «функция x, которая переходит в x, умноженное на 5» 204 | ```py 205 | lambda : 206 | ``` 207 | 208 | Лямбда-фунция возведения в степень. 209 | ```py 210 | pow = lambda x, power: x ** power 211 | print(pow(2, 5)) 212 | ``` 213 | что эквивалентно 214 | ```py 215 | def pow(x, power): 216 | return x ** power 217 | print(pow(2, 5)) 218 | ``` 219 | 220 | 221 | 222 | # `*args` and `**kwargs` 223 | 224 | Оператор `*args` (`asterisk operator`) используется для *"распаковки" перечисляемых объектов* (англ. `iterable`), например, таких как *массив* и *список аргументов функции*. 225 | 226 | То есть, `*[1, 2, 3]` это ничто иное, как `1, 2, 3`. 227 | 228 | Оператор `**kwargs` (`double asterisk operator`) используется для *"распаковки" объектов*. 229 | 230 | То есть, `**{ name: "Max", sex: "male" }` это ничто иное, как `name="Max", sex="male"`. 231 | 232 | Не путайте унарный оператор `**kwargs`, который применим только к объектам, с бинарным оператором возведения числа в степень `number ** power`. 233 | 234 | Не путайте унарный оператор `*args`, который применим только к перечисляемым объектам, с бинарным оператором умножения чисел `a * b`. 235 | 236 | Операторы `*args` и `**kwargs` являются аналогами оператора `...` (`spread operator`) в JavaScript. 237 | 238 | ## Массивы и `*args` 239 | 240 | При применении унарного оператора `*` к *массиву* вы передаёте в выражение все значения массива через запятую. Например, это может быть полезным при построении нового массива путём расширения предыдущего. 241 | 242 | На примере ниже происходит слияние двух массивов. 243 | ```py 244 | arr = [3, 4] 245 | another_arr = [1, 2] 246 | merged = [*another_arr, *arr] 247 | print(merged) # [1, 2, 3, 4] 248 | ``` 249 | ```javascript 250 | // JavaScript 251 | const foo = [3, 4]; 252 | const bar = [1, 2]; 253 | const merged = [...bar, ...foo]; 254 | console.log(merged); // [1, 2, 3, 4] 255 | ``` 256 | Ещё немного слияний массивов для закрепления. 257 | ```py 258 | foo = [1, 2, 3] 259 | bar = [*foo, 4] 260 | print(bar) # [1, 2, 3, 4] 261 | 262 | baz = [0, *bar, 5] 263 | print(baz) # [0, 1, 2, 3, 4, 5] 264 | ``` 265 | ```javascript 266 | // JavaScript 267 | const foo = [1, 2, 3]; 268 | const bar = [...foo, 4]; 269 | console.log(bar); // [1, 2, 3, 4] 270 | 271 | const baz = [0, ...bar, 5] 272 | console.log(baz); // [0, 1, 2, 3, 4, 5] 273 | ``` 274 | ## Параметры функции и `*args` 275 | Аналогично примерам выше, можно "передать значения массива через запятую" в качестве параметров функции. 276 | ```python 277 | def sum(a, b): 278 | return a + b 279 | numbers = [3, 7] 280 | print(sum(*numbers)) # 10 281 | ``` 282 | ```js 283 | function sum(a, b) { 284 | return a + b; 285 | } 286 | 287 | const numbers = [3, 7]; 288 | console.log(sum(...numbers)); // 10 289 | // что эквивалентно 290 | console.log(sum(3, 7)); // 10 291 | ``` 292 | ## Аргументы функции и `*args` 293 | Применим `*args` к аргументами функции, вы получите функцию, которая может обрабатывать любое количество аргументов вплоть до бесконечности. Собранные аргументы помещаются в кортеж `tuple`. 294 | ```python 295 | def sum(*numbers): 296 | result = 0 297 | for num in numbers: 298 | result = result + num 299 | print(result) 300 | 301 | sum(3, 7) # 10 302 | sum(3, 7, 2) # 12 303 | sum(3, 7, 2, 5) # 17 304 | ``` 305 | ```js 306 | // JavaScript 307 | function sum(...numbers) { 308 | let result = 0; 309 | for (const num of numbers) { 310 | result += num; 311 | } 312 | console.log(result); 313 | } 314 | 315 | sum(3, 7); // 10 316 | sum(3, 7, 2); // 12 317 | sum(3, 7, 2, 5); // 17 318 | ``` 319 | ## Объекты и **kwargs 320 | 321 | Оператор `**kwargs` (keyword args) может быть использован для "распаковки" объектов. 322 | 323 | Например, для слияния двух и более объектов. 324 | ```py 325 | user_personal_info = { "first_name": "Max", "last_name": "Starling" } 326 | user_job_info = { "job": "engineer", "experience": "6 years" } 327 | user_info = { **user_personal_info, **user_job_info } 328 | print(user_info) # { "first_name": "Max", "last_name": "Starling", "job": "engineer", "experience": "6 years" } 329 | ``` 330 | ```js 331 | // JavaScript 332 | const userPersonalInfo = { firstName: "Max", lastName: "Starling" }; 333 | const userJobInfo = { job: "engineer", experience: "6 years" }; 334 | const userInfo = { ...userPersonalInfo, ...userJobInfo }; 335 | console.log(userInfo); // { firstName: "Max", last_name: "Starling", job: "engineer", experience: "6 years" } 336 | ``` 337 | или для создания копии объекта с возможностью расширения его свойств 338 | ```py 339 | file_info = { "file_name": "test.json", "size": "1376kb" } 340 | print({ **file_info, "created_at": "15/12/2022" }) # { "file_name": "test.json", "size": "1376kb", "created_at": "15/12/2022" } 341 | ``` 342 | ```js 343 | // JavaScript 344 | const fileInfo = { fileName: "test.json", size: "1376kb" } 345 | console.log({ ...fileInfo, createdAt: "15/12/2022" }) // { fileName: "test.json", size: "1376kb", createdAt: "15/12/2022" } 346 | ``` 347 | 348 | ## Аргументы функции и `**kwargs` 349 | Функции в питоне могут принимать **ключевые аргументы** (англ. `keyword arguments`) в виде `kwarg=value`. В этом случае *порядок передачи параметров* функции *не важен*. 350 | ```py 351 | def print_user_info(status, name, age): # порядок не важен 352 | print("\nUser info:") 353 | print("- {} is {}".format("name",name)) 354 | print("- {} is {}".format("age",age)) 355 | print("- {} is {}".format("status",status)) 356 | 357 | print_user_info(name="Alex", age=22, status="married") 358 | # User info: 359 | # - name is Alex 360 | # - age is 22 361 | # - status is married 362 | ``` 363 | Чтобы функция могла принимать любое количество параметров и при этом было удобно их обрабатывать, можно использовать `**kwards`, который соберёт все параметры функции в словарь `dict` (англ. `dictionary`). 364 | ```py 365 | def print_user_info(**user_info): 366 | # type(user_info) = dict 367 | print("\nUser info:") 368 | for key, value in user_info.items(): 369 | print("- {} is {}".format(key,value)) 370 | 371 | print_user_info(name="Alex", age=22, status="married") 372 | # User info: 373 | # - name is Alex 374 | # - age is 22 375 | # - status is married 376 | print_user_info(name="Kate", age=18, sex="female", status="single") 377 | # User info: 378 | # - name is Kate 379 | # - age is 18 380 | # - sex is female 381 | # - status is single 382 | ``` 383 | ```js 384 | // JavaScript 385 | // ключевые аргументы не доступны в языке - передаём объект с любым количеством свойств 386 | function printUserInfo(userInfo) { 387 | console.log("\nUser info:"); 388 | for (const [key, value] of Object.entries(userInfo)) { 389 | console.log(`- ${key} is ${value}`); 390 | } 391 | } 392 | printUserInfo({ name: "Alex", age: 22, status: "married" }) 393 | // User info: 394 | // - name is Alex 395 | // - age is 22 396 | // - status is married 397 | printUserInfo({ name: "Kate", age: 18, sex: "female", status: "single" }) 398 | // User info: 399 | // - name is Kate 400 | // - age is 18 401 | // - sex is female 402 | // - status is single 403 | ``` 404 | ## Все виды аргументов сразу в функции 405 | `error_type` - одиночный позиционный аргумент. 406 | `*messages` собирает позиционные элементы, начиная со второго и до последнего, в кортеж `tuple`. 407 | `**metadata` собирает все ключевые аргументы в словарь `dict`. 408 | ```py 409 | def print_errors(error_type, *messages, **metadata): 410 | # type(user_info) = dict 411 | print(f"{error_type}:") 412 | for index, message in enumerate(messages): 413 | print(f" * Error #{index}: - {message} *") 414 | for key, value in metadata.items(): 415 | print("** Metadata: - {} is {} **".format(key,value)) 416 | 417 | print_errors( 418 | "ValidationError", 419 | "password is too short", 420 | "password must contain at least one special character", 421 | "password must contain at least one capital letter", 422 | email="test@smail.com", 423 | browser="Safari" 424 | ) 425 | # ValidationError: 426 | # * Error #0: - password is too short * 427 | # * Error #1: - password must contain at least one special character * 428 | # * Error #2: - password must contain at least one capital letter * 429 | # ** Metadata: - email is test@smail.com ** 430 | # ** Metadata: - browser is Safari ** 431 | ``` 432 | ```js 433 | // JavaScript 434 | // ключевые аргументы в языке отсутствуют, оператор `...` должен быть в конце, 435 | // значит используем объект в качестве `metadata` и меняем его местами с `messages` 436 | function printErrors(errorType, metadata, ...messages) { 437 | console.log(`${errorType}:`) 438 | for (const [index, message] of Object.entries(messages)) { 439 | console.log(` * Error #${index}: - ${message} *`) 440 | } 441 | for (const [key, value] of Object.entries(metadata)) { 442 | console.log(`** Metadata: - ${key} is ${value} **`) 443 | } 444 | } 445 | 446 | printErrors( 447 | "ValidationError", 448 | { email: "test@smail.com", browser: "Safari" }, 449 | "password is too short", 450 | "password must contain at least one special character", 451 | "password must contain at least one capital letter" 452 | ) 453 | // ValidationError: 454 | // * Error #0: - password is too short * 455 | // * Error #1: - password must contain at least one special character * 456 | // * Error #2: - password must contain at least one capital letter * 457 | // ** Metadata: - email is test@smail.com ** 458 | // ** Metadata: - browser is Safari ** 459 | ``` 460 | 461 | 462 | ## Полезные функции 463 | 464 | ### `is_json` 465 | 466 | ```py 467 | import json 468 | 469 | def is_json(myjson): 470 | try: 471 | json.loads(myjson) 472 | except ValueError as e: 473 | return False 474 | return True 475 | 476 | print is_json("{}") # True 477 | print is_json("{abc}") # False 478 | print is_json('{"name":"ghost"}') # True 479 | print is_json("{'rank':17 }") # False 480 | print is_json("{\"rank\":17 }") # True 481 | ``` 482 | -------------------------------------------------------------------------------- /tech/Redis.md: -------------------------------------------------------------------------------- 1 | # Redis for Windows 2 | 3 | **Redis** is an in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. 4 | 5 | ## Get started 6 | * Download [redis-latest.zip](https://github.com/ServiceStack/redis-windows/raw/master/downloads/redis-latest.zip). 7 | * Unzip archive. 8 | * Open appeared folder. 9 | * Run *redis-server.exe*. 10 | * Run *redis-cli.exe*. 11 | * Use Redis CLI (command line interface) to execute commands. 12 | 13 | ## Basic commands 14 | 15 | * `GET key` - get value by key 16 | * `SET key value` - save key with value in storage 17 | * `DEL key` - delete key 18 | * `Keys *` - show all keys 19 | * `FLUSHALL` - drop all keys 20 | -------------------------------------------------------------------------------- /tech/Scala.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tech/Shell.md: -------------------------------------------------------------------------------- 1 | # Linux 2 | 3 | ## Команды 4 | * `echo <данные>` - вывод данных в консоль. 5 | * `echo $USER`, `whoami` - вывод имени текущего пользователя 6 | * `mkdir directory_name` - создание папки. 7 | * `ls` - список файлов и папок в текущей директории. 8 | * `rm file_name` - удаление файла. 9 | * `rm -rf directory_name` - удаление папки. 10 | * `cat file_name` - вывод содержимого файла в консоль. 11 | * `cd directory_name` - переход в папку. 12 | * `cd ..` - переход в папку выше. 13 | * `printenv` - вывести все переменные окружения (англ. `environment variables`) 14 | 15 | ```shell 16 | # /app/src 17 | cd .. 18 | # /app 19 | ``` 20 | * `ssh @` - вход на сервер по ssh при помощи имени и пароля (интерактивный режим). 21 | * `which <название команды>` - вывод месторасположения команды. 22 | ```shell 23 | which docker-compose 24 | # выведет /usr/bin/docker-compose 25 | ``` 26 | 27 | ### sudo и переменные окружения 28 | 29 | По умолчанию `sudo` отказывается принимать переменные окружения. 30 | ``` 31 | sudo: sorry, you are not allowed to set the following environment variables: POSTGRES_USER, POSTGRES_PASSWORD 32 | ``` 33 | Чтобы это исправить, необходимо установить доступ к этим переменным в `sudoers`. 34 | ```js 35 | sudo nano /etc/sudoers.d/ld_preload 36 | /* или */ 37 | sudo vim /etc/sudoers.d/ld_preload 38 | ``` 39 | Нужно дописать переменные в файл. 40 | ```js 41 | /* /etc/sudoers.d/ld_preload */ 42 | Defaults env_keep += "POSTGRES_USER" 43 | Defaults env_keep += "POSTGRES_PASSWORD" 44 | ``` 45 | 46 | # Windows 47 | 48 | ## Команды 49 | * `dir` - список файлов и папок в текущей директории (аналог `ls` в Linux). 50 | * `type` - вывод содержимого файла в консоль (аналог `cat` в Linux). 51 | * `cls` - очистить консоль (аналог `clear` в Linux) 52 | * `:` - переход на диск disk_name. 53 | 54 | ```shell 55 | # переход на диск C 56 | C: 57 | # переход на диск D 58 | D: 59 | ``` 60 | 61 | ## PowerShell 62 | 63 | 64 | # Shebang `!#` 65 | 66 | **Шебанг** (англ. `shebang`, `sha-bang`, `sharp-exclamation`, `hashbang`, `pound-bang`, `hash-pling`) - последовательность из двух символов `#!` в начале скрипта. 67 | 68 | Если Unix выполняет скрипт с шебангом в начале скрипта, загрузчик программ рассматривает остаток строки после шебанга как имя файла программы-интерпретатора. 69 | 70 | Например, чтобы выполнить файл с помощью `sh` (`Bourne shell`), необходимо написать в начале скрипта. 71 | ```sh 72 | #!/bin/sh 73 | ... 74 | ``` 75 | 76 | Поскольку `#` является символов начала комментария во многих скриптовых языках программирования, строка с шебангом обычно пропускается интерпретатором. 77 | 78 | JavaScript не является таким языком, поскольку комментарии в нём объявляются через `/**/`, `//`. Однако в ES14 (ECMAScript2023) добавили поддержку шебанга. 79 | ``` 80 | #!/usr/bin/env node 81 | console.log('Hello JavaScript!'); 82 | ``` 83 | Скриншот из Chrome: 84 | 85 | ![image](https://github.com/Max-Starling/Notes/assets/22237384/c15eeac6-e9d6-495d-b9ad-6a54be56dc22) 86 | 87 | # Комментарии 88 | `#` 89 | 90 | # Замена символов 91 | `-replace '',''` 92 | ```powershell 93 | $foo = 'hi-notes!' 94 | $bar = $foo -replace '[-]',' ' -replace '!', '' 95 | echo $bar # hi notes 96 | ``` 97 | -------------------------------------------------------------------------------- /tech/Shortcuts.md: -------------------------------------------------------------------------------- 1 | # Сочетания клавиш 2 | 3 | ## Chrome 4 | * `Ctrl + Tab`, `Ctrl + Shift + Tab` — переключение между вкладками вправо и влево. 5 | * `Ctrl + L` — выделение URL или текста в адресной строке. 6 | * `Ctrl + N` — новое окно. 7 | * `Ctrl + T` — новая вкладка. 8 | * `Ctrl + Shift + N` — новое окно в режиме инкогнито. 9 | * `Ctrl + клик` — открытие ссылки в новой фоновой вкладке. 10 | * `Ctrl + Shift + клик` — открытие ссылки в новой вкладке с переключением на неё. 11 | * `Ctrl + Shift + T` — восстановление последней закрытой вкладки. 12 | * `Ctrl + W` — закрытие активной вкладки или всплывающего окна. 13 | * `Ctrl + F` — поиск. 14 | * `Ctrl + U` — исходный код страницы. 15 | * `Ctrl + "+"`, Ctrl + "-", Ctrl + 0 — масштабирование. 16 | * `Space` — поэкранная прокрутка страницы. 17 | * `Shift + Esc` — диспетчер задач. 18 | * `Alt + Enter` — открытие URL в новой вкладке. 19 | -------------------------------------------------------------------------------- /tech/Sisense.md: -------------------------------------------------------------------------------- 1 | 2 | # Основные понятия 3 | # 4 | ![image](https://user-images.githubusercontent.com/22237384/220296705-a06e8dca-9103-4e90-9bce-48ea758d6815.png) 5 | 6 | ## Data Model 7 | 8 | **Модель данных** (англ. `Data Model`) в Sisense представляет собой ничто иное, как схему базы данных, то есть множество таблиц, отображённых в виде вершин графа и рёбер между вершинами, которые показывают связи между таблицами. 9 | 10 | Каждая таблица имеет набор столбцов, каждый из которых имеет определённый тип данных из списка поддерживаемых в Sisense типов. 11 | 12 | Строки таблиц можно получить 13 | 14 | Data Model может быть двух типов: 15 | * `live` - делает запросы напрямую к сторонней базе данных, используя строку подключения (англ. `connection string`), переданный при инициализации. 16 | * `elastic cube` - данные клонируются со сторонней базы данных в Sisense, далее запросы отправляются непосредственно к скопированным данным. 17 | 18 | Смешивать эти типы невозможно. 19 | 20 | ## Dataset 21 | 22 | Чтобы получить строки таблиц, необходимо отправить запрос. Одной таблице в модели данных может соответствовать несколько источников данных. 23 | 24 | **Набор данных** (англ. `Dataset`) представляет собой один из источников данных, используемых текущей моделью данных. Например, если модель данных содержит данные из трёх CSV-файлов и двух баз данных SQL, то всего у нас 5 источников, а значит 5 наборов данных. 25 | 26 | Например, `connection string` может быть 27 | ``` 28 | Server=ServerName;Database=DatabaseName;User Id=UserName;Password=UserPassword; 29 | Server=localhost;Database=SisenseNotes;User Id=SuperAdmin;Password=qwerty; 30 | ``` 31 | 32 | Каждый набор данных содержит информацию о подключении к своему источнику (например, строку подключения к SQL-базе или путь к CSV-файлу) 33 | 34 | 35 | ## Table 36 | -------------------------------------------------------------------------------- /tech/Snowflake.md: -------------------------------------------------------------------------------- 1 | 2 | # Хранение больших объёмов информации 3 | 4 | Оба понятие "озеро" и "склад данных" связаны с хранением огромного количества данных (обычно террабайты, десятки террабайт и больше) 5 | 6 | ## Об озере даннных (`Data Warehouse`) 7 | 8 | **Озером данных** (англ. `Data Lake`) называют репозитарий, в котором *хранятся огромные объемы сырых данных* (англ. `vast pool of raw data`) в их *первоначальном*, *неотформатированном виде* до тех пор, *пока они не будут использованы*. 9 | 10 | Например, хранение данных в *озере данных* может подобиться специалистам из области *Data Science* для *изучения* таких данных, *применения* к ним *машинного обучения* и *разничных аналитических функций*. 11 | 12 | На *момент хранения данных* в *озере* ещё *не ясно*, *как и когда данные будут использованы* - они просто *ждут подходящего случая*. 13 | 14 | ## О хранилище данных (`Data Lake`) 15 | 16 | **Хранилищем данных** (англ. `Data Warehouse`, `DW`, *дословно* **складом данных**, называют такую *систему управления данными* (англ. `data management system`), в которую *размещают огромные объёмы данных* из *разных источников* (*других баз данных*, *приложений*, *файлов* и так далее) и затем на основании этих данных *подготавливают отчётов бизнес-анализа* (англ. `business intelligence`) и *составляют* *аналитику* (англ. `analytics`). 17 | 18 | Таким образом, данные в хралищие данных чаще всего используется бизнес-аналитиками в аналитичеких целях. Например, для построения аналитических графиков и составления отчётов по ним. Данные в хранилище данных попадают в уже отформатированном виде и их цель применения уже задана. 19 | 20 | Данные, послупающие из разных источников, автоматически адаптируются под единый формат и становятся доступны для поисковых запросов. 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ## Различия между складом и озером данных 29 | 30 | 1) Хранение данных. Данные в озере хранятся в исходном, неотформатированном или слабоотформатированном виде. Данные на складе хранятся в чётко заданном виде, то есть они структурированны и отформатированны. 31 | 2) Цель и время применения данных. Цель и время использования данных из озера обычно не ясны на данный момент, в то время, как данные на складе размещаются с целью их дальнейшего анализа (который происходит постоянно, в режиме реального времени, или интервально). 32 | 3) Кто использует данные. Чаще всего данные в озере использубтся Data Science специалистами, а данные на складе - аналитиками. 33 | 34 | Вполне логично, что данные из озера могут попасть на склад для их структуризации, форматирования и аналики, но отправлять данные со склада в озеро обычно не имеет смысла. 35 | 36 | # Что такое Snowflake? 37 | 38 | 39 | Snowflake - это хранилище данных, которое полностью выполняется в облачной инфраструктуре и не может быть запущено на некотором приватном облаке. 40 | 41 | Система Snowflake не является реляционной базой данных, поэтому в ней не поддерживается концепция первичных и вторичных ключей (англ. `primary and foreign keys`, `PK & FK`). 42 | 43 | Тем не менее, Snowflake поддерживает набор SQL-команд для удобства чтения, в том числе: 44 | - DDL/DML, 45 | - SQL Functions, 46 | - User Defined Functions (UDFs), процедуры с использованием JavaScript. 47 | 48 | Поддерживаются команды: 49 | ```sql 50 | SELECT 51 | JOIN 52 | INSERT UPDATE DELETE 53 | VIEW 54 | ``` 55 | а также merge statements, subqueries, ACID transactions, Analytical Aggregations (cube, rollup, groping sets, windowing functions, connect-by, recursive CTE) 56 | 57 | A data warehouse is a type of data management system that is designed to enable and support business intelligence (BI) activities, especially analytics. Data warehouses are solely intended to perform queries and analysis and often contain large amounts of historical data. 58 | 59 | In computing, a data warehouse, also known as an enterprise data warehouse, is a system used for reporting and data analysis and is considered a core component of business intelligence. DWs are central repositories of integrated data from one or more disparate sources. 60 | -------------------------------------------------------------------------------- /tech/Vim.md: -------------------------------------------------------------------------------- 1 | 2 | ## Команды 3 | * `i` - режим вставки. 4 | * `ESC` - режим просмотра. 5 | * `:q` - выход. 6 | * `:q!` - выход без сохранения. 7 | * `u`, `:u` - отмена предыдущего действия. 8 | * `CTRL+R` - отмена отмены предыдущего действия. 9 | -------------------------------------------------------------------------------- /tech/Webpack.md: -------------------------------------------------------------------------------- 1 | 2 | ## Плагины 3 | 4 | **DefinePlugin** позвоняет созначать глобальные константы, которые могут быть заданы во время компиляции. Это особенно полезно, когда есть разные версии сборок (builds): например, `production` и `development`. 5 | ```sh 6 | npm start NODE_ENV=production 7 | ``` 8 | ```js 9 | new webpack.DefinePlugin({ 10 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 11 | }); 12 | /* после этого переменную можно использовать в JavaScript */ 13 | ``` 14 | -------------------------------------------------------------------------------- /tech/jQuery.md: -------------------------------------------------------------------------------- 1 | 2 | ## Обращение к элементу 3 | Обращение к элементу при помощи `jQuery` работает аналогино методу `document.querySelector`: 4 | ```js 5 | document.querySelector('#element-id') // обращение к элементу по атрибуту id 6 | document.querySelector('.element-class') // обращение к элементу по атрибуту class 7 | ``` 8 | Только для подобного поиска элемента используется метод `$`. 9 | ```js 10 | $('#element-id') 11 | $('.element-class') 12 | ``` 13 | 14 | 15 | ## Сокрытие элемента 16 | *Убрать элемент* со страницы: 17 | ```js 18 | $('.element-class').hide(); 19 | /* или */ 20 | $('.element-class').css('display', 'none'); 21 | ``` 22 | *Вернуть элемент* на страницу: 23 | ```js 24 | $('.element-class').show(); 25 | /* или */ 26 | $('.element-class').css('display', 'block'); 27 | ``` 28 | -------------------------------------------------------------------------------- /tech/nvm.md: -------------------------------------------------------------------------------- 1 | # NVM for Windows 2 | ## Get started 3 | * Open [nvm-windows releases](https://github.com/coreybutler/nvm-windows/releases) 4 | * Download nvm-setup.zip 5 | * Unzip the archive 6 | * Start nvm-setup.exe 7 | * Agree with all (even in the case of a huge number of modal windows during installation) 8 | * Run in cmd as Administrator: 9 | ```cmd 10 | C:\Users\\AppData\Roaming\nvm\nvm.exe 11 | ``` 12 | ## Basic commands 13 | * `node -v` - check nodejs version 14 | * `nvm install ` - install necessary 15 | * `nvm list` - check installed versions 16 | * `nvm use ` - set nodejs version 17 | * `nvm version` - version of nvm 18 | 19 | ## Issue 20 | 21 | If **nodejs version doesn't change**: 22 | * Rename "C:\Program Files\nodejs" to "C:\Program Files\nodejsx" 23 | * Restart console 24 | 25 | 26 | -------------------------------------------------------------------------------- /tech/pip.md: -------------------------------------------------------------------------------- 1 | ## О репозитории Python Package Index 2 | **Python Package Index (PyPI)** - это *репозиторий*, *хранящий программное обеспечение* для *языка* Python в виде *пакетов*. *Пакеты находятся* в *открытом доступе* и *разработанны сообществом* Python-разработчиков. 3 | 4 | *Аналогом* `PyPI` для языка *JavaScript* является *репозиторий* **NPM Registry**. 5 | 6 | ## О менеджере пакетов PIP 7 | 8 | **PIP** (англ. `Package Installer for Pyton`) - это *менежер пакетов* для языка Python, который позволяет устанавливать их из репозитория PyPI и затем управлять ими при помощи консольной команды `pip`. 9 | 10 | *Аналогом* `PIP` является *репозиторий* **NPM** (англ. `NodeJS Package Manager`). 11 | 12 | ## Установка и обновление `PIP` 13 | 14 | Для `Windows`, `Linux` и `MAC` *процесс установки* `PIP` *ничем не отличается*. 15 | 16 | Для начала убедитесь, что у вас установлен *Python* и он *доступен для запуска из терминала*: 17 | ```css 18 | > py 19 | /* или */ 20 | > python 21 | ``` 22 | У меня установлены разные версии, поэтому обе команды работают. 23 | ![image](https://user-images.githubusercontent.com/22237384/169065170-9258362e-cb7d-4882-8aa5-2e88bd6a8de0.png) 24 | Если заходит в терминал `python`, то всё хорошо. 25 | Нужно ввести `exit()` для выхода из него. 26 | 27 | Если Python установлен на Windows, но не виден в терминале, то следует добавить папку, в которой лежит `py.exe` или `python.exe` в переменные окружения, Path (`Environment Variables -> Path`). 28 | 29 | Если Python уже установлен и добавлен в переменные окружения, то достаточно ввести в теринале ОДНУ из следующих команд (`py` или `python` *зависит* от *версии* `Python`): 30 | ```css 31 | py -m ensurepip --upgrade 32 | /* или */ 33 | python -m ensurepip --upgrade 34 | ``` 35 | 36 | 37 | 38 | ## Установка пакетов при помощи `PIP` 39 | ### Установка пакета последней версии 40 | ```css 41 | pip install package_name 42 | ``` 43 | ### Установка пакета определённой версии 44 | Версия пакета указывается через `==` после его названия в формате `MAJOR.MINOR.PATCH`: 45 | ```css 46 | pip install == 47 | ``` 48 | Например, установим пакет `WTForms` версии 2.3.3: 49 | ```css 50 | pip install WTForms==2.3.3 51 | ``` 52 | ### Установка пакетов из списка 53 | Имеется возможность передавать список зависимостей для установки в виде текстового файла. В этом случае менеджер поочерёдно установит все зависимости. 54 | ```css 55 | pip install -r ./dependencies.txt 56 | ``` 57 | ```css 58 | /* ./dependencies.txt */ 59 | flask 60 | flask-cors 61 | flask-api 62 | flask-admin 63 | flask-migrate 64 | WTForms==2.3.3 65 | ``` 66 | --------------------------------------------------------------------------------