├── .github
└── FUNDING.yml
├── LICENSE
├── README.md
├── README_RUS.md
└── files
├── building-architecture
├── horizontal-vertical-scaling_eng.png
├── horizontal-vertical-scaling_rus.png
├── monolith-microservices_eng.png
└── monolith-microservices_rus.png
├── common
├── BigO.png
├── BigO_eng.png
├── array.png
├── array_eng.png
├── binary.png
├── graph.png
├── graph_eng.png
├── hash-table.png
├── hash-table_eng.png
├── heap.png
├── heap_eng.png
├── hex.png
├── linked-list.png
├── logic.png
├── logic_eng.png
├── octal.png
├── queue.gif
├── stack.png
├── stack_eng.png
└── tree.png
├── databases
├── mongodb-cheatsheet.md
└── sql-cheatsheet.md
├── linux
├── bash-scripts-cheatsheet.md
├── chmod.png
├── chmod_eng.png
├── cron.png
└── cron_eng.png
├── logo.png
├── network-internet
├── Browser.png
├── Domain.png
├── Hosting.png
├── IPv4-IPv6.png
├── Internet.png
├── Problems.gif
├── Traceroute.png
├── browser_eng.png
├── dns.png
├── domain_eng.png
├── http.png
├── http_eng.png
├── osi.png
├── problems_eng.gif
├── proxy-vpn.png
├── proxy-vpn_eng.png
├── tcp-ip.png
├── tcp-ip_eng.png
├── tcp.png
├── topologies.png
├── topologies_rus.png
└── udp.png
├── optimization
├── cdn.png
├── cdn_eng.png
├── load-balancer.png
└── load-balancer_eng.png
├── os
├── concurrency-parallel.png
├── os-layer.png
├── os-layer_eng.png
├── process.png
└── process_eng.png
├── programming-language
└── regex-cheatsheet.md
├── security
├── hashing.png
└── hashing_eng.png
├── software
├── message-queue.png
├── message-queue_eng.png
├── web-server_eng.png
└── web-server_rus.png
└── testing
├── testing-pyramid_eng.png
└── testing-pyramid_rus.png
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [cheatsnake]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: yurace
14 | thanks_dev: # Replace with a single thanks.dev username
15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022-2023 Yury (cheatsnake)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/files/building-architecture/horizontal-vertical-scaling_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/building-architecture/horizontal-vertical-scaling_eng.png
--------------------------------------------------------------------------------
/files/building-architecture/horizontal-vertical-scaling_rus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/building-architecture/horizontal-vertical-scaling_rus.png
--------------------------------------------------------------------------------
/files/building-architecture/monolith-microservices_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/building-architecture/monolith-microservices_eng.png
--------------------------------------------------------------------------------
/files/building-architecture/monolith-microservices_rus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/building-architecture/monolith-microservices_rus.png
--------------------------------------------------------------------------------
/files/common/BigO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/BigO.png
--------------------------------------------------------------------------------
/files/common/BigO_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/BigO_eng.png
--------------------------------------------------------------------------------
/files/common/array.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/array.png
--------------------------------------------------------------------------------
/files/common/array_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/array_eng.png
--------------------------------------------------------------------------------
/files/common/binary.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/binary.png
--------------------------------------------------------------------------------
/files/common/graph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/graph.png
--------------------------------------------------------------------------------
/files/common/graph_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/graph_eng.png
--------------------------------------------------------------------------------
/files/common/hash-table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/hash-table.png
--------------------------------------------------------------------------------
/files/common/hash-table_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/hash-table_eng.png
--------------------------------------------------------------------------------
/files/common/heap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/heap.png
--------------------------------------------------------------------------------
/files/common/heap_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/heap_eng.png
--------------------------------------------------------------------------------
/files/common/hex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/hex.png
--------------------------------------------------------------------------------
/files/common/linked-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/linked-list.png
--------------------------------------------------------------------------------
/files/common/logic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/logic.png
--------------------------------------------------------------------------------
/files/common/logic_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/logic_eng.png
--------------------------------------------------------------------------------
/files/common/octal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/octal.png
--------------------------------------------------------------------------------
/files/common/queue.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/queue.gif
--------------------------------------------------------------------------------
/files/common/stack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/stack.png
--------------------------------------------------------------------------------
/files/common/stack_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/stack_eng.png
--------------------------------------------------------------------------------
/files/common/tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/tree.png
--------------------------------------------------------------------------------
/files/databases/mongodb-cheatsheet.md:
--------------------------------------------------------------------------------
1 | # Шпаргалка по MongoDB
2 |
3 |
4 |
5 | - Подготовка БД
6 |
7 | ```js
8 | show dbs // показать список всех БД
9 | use db_name // подключиться/создать БД с именем db_name
10 | db // вывести имя текущей базы данных
11 | db.createCollection("users") // создать коллекцию "notes"
12 | show collections // показать список коллекций в текущей БД
13 | db.dropDatabase() // удалить текущую БД
14 | ```
15 |
16 | - Добавление элементов
17 |
18 | ```js
19 | // Добавить один элемент
20 | db.users.insertOne({
21 | name: "Alex",
22 | age: 27,
23 | isMarried: false,
24 | city: "NewYork"
25 | })
26 |
27 | // Добавить несколько элементов
28 | db.users.insertMany([{...}, {...}])
29 | ```
30 |
31 | - Получение элементов
32 |
33 | ```js
34 | // Получить все элементы из коллекции
35 | db.users.find();
36 | // Получить элементы по указанному критерию
37 | db.user.find({ age: 27 });
38 | // Получить один элемент
39 | db.users.findOne({ name: "Alex" });
40 | // Получить отсортированный список элементов
41 | // 1 - по возрастанию; -1 - по убыванию
42 | db.users.find().sort({ age: 1 });
43 | // Получить количество элементов
44 | db.users.find().count();
45 | // Лимит количества получаемых элементов
46 | db.users.find().limit(10);
47 | // Выборка с помощью операторов сравнения
48 | db.users.find({ age: { $gt: 20 } }); // > 20
49 | db.users.find({ age: { $gte: 20 } }); // >= 20
50 | db.users.find({ age: { $lt: 50 } }); // < 50
51 | db.users.find({ age: { $lte: 50 } }); // <= 50
52 | db.users.find({ age: { $ne: 35 } }); // != 35
53 | ```
54 |
55 | - Изменение элементов
56 |
57 | ```js
58 | // Полное изменение элемента (первый аргумент - критерий поиска)
59 | db.users.updateOne({name: "Alex"}, {новые_данные})
60 | // Изменение определенных полей элемента
61 | db.users.updateOne({name: "Alex"}, {$set: {age: 28, isMarried: true}})
62 | // Переименовать поле у нескольких элементов
63 | db.users.updateMany({name: "Alex"}, {&rename: {city: "town"}})
64 | // Удаление элемента/элементов
65 | db.users.deleteOne({name: "Alex"})
66 | db.users.deleteMany({name: "Alex"})
67 | ```
68 |
--------------------------------------------------------------------------------
/files/databases/sql-cheatsheet.md:
--------------------------------------------------------------------------------
1 | # Шпаргалка по SQL
2 |
3 |
4 |
5 | - Создание новой БД
6 | ```sql
7 | CREATE DATABASE db_name;
8 | ```
9 | - Создание новой таблицы
10 | ```sql
11 | CREATE TABLE users (
12 | id SERIAL PRIMARY KEY, # Уникальный id
13 | firstName VARCHAR(100), # Строка
14 | lastName VARCHAR(100), # Строка
15 | age INT, # Число
16 | gender VARCHAR(10), # Строка
17 | isMarried BOOLEAN # true/false
18 | );
19 | ```
20 | - Основные типы данных
21 | > - INT (целые числа от -2^32 до +2^32)
22 | > - FLOAT / DOUBLE / DECIMAL (дробные числа)
23 | > - CHAR / VARCHAR / TEXT (строки)
24 | > - DATA / DATETIME / TIME (дата и время)
25 | > - ENUM (перечисления - списки допустимых значений)
26 | > - [И другие](https://sql-language.ru/osnova-sql/tipy-dannykh-sql.html)
27 | - Добавление данных в таблицу
28 | ```sql
29 | INSERT INTO users(
30 | firstName, lastName, age, gender, isMarried
31 | ) VALUES (
32 | 'Alex', 'Manson' 25, 'male', false
33 | );
34 | ```
35 | - Выборка данных из таблицы
36 | ```sql
37 | # SELECT
38 | ## Получить всю таблицу users
39 | SELECT * FROM users;
40 | ## Получить только столбцы firstName и age из таблицы users
41 | SELECT firstName, age FROM users;
42 |
43 | # LIMIT
44 | ## Получить первых 20 записей таблицы users
45 | SELECT * FROM users LIMIT 20;
46 |
47 | # DISTINCT
48 | ## Получить только уникальные значения из столбца firstName
49 | SELECT DISTINCT(firstName) FROM users;
50 |
51 | # WHERE
52 | ## Записи, где столбец gender = 'male'
53 | SELECT * FROM users WHERE gender = 'male';
54 | ## AND, OR
55 | SELECT * FROM users WHERE age = 25 AND isMarried = falsel
56 | SELECT * FROM users WHERE age = 20 OR age = 50;
57 |
58 | # BETWEEN
59 | ## Записи, где значения столбца age находятся в промежутке от 20 до 30
60 | SELECT * FROM users WHERE age BETWEEN 20 AND 30;
61 |
62 | #NULL
63 | ## Записи, где столбец lastName не пуст
64 | SELECT * FROM users WHERE lastName IS NOT NULL;
65 | ```
66 | - Поиск данных по шаблону
67 | ```sql
68 | # IN, LIKE, NOT LIKE
69 | ## % - подстановочный знак, который указывает на любое кол-во символов
70 | ## _ - подстановочный знак, который указывает на один символ
71 |
72 | ## Записи, где firstname равен 'John', 'Mike' или 'Kane'
73 | SELECT * FROM users WHERE firstName IN ('John', 'Mike', 'Kane');
74 | ## Записи, где firstname начинается c буквы 'A'
75 | SELECT * FROM users WHERE firstName LIKE 'A%';
76 | ## Записи, где первая буква в firstName равна 'A', 'B' или 'C'
77 | SELECT * FROM users WHERE firstName LIKE '[ABC]%';
78 | ## Записи, где вторая буква в firstname не равна 'o'
79 | SELECT * FROM users WHERE firstName NOT LIKE '_o%';
80 | ```
81 | - Сортировка и фильтрация данных таблиц
82 | ```sql
83 | # ORDER BY
84 | ## ASC - по возрастанию (по умолчанию)
85 | ## DESC - по убыванию
86 | SELECT * FROM users ORDER BY firstName ASC;
87 | SELECT * FROM users ORDER BY age DESC;
88 | SELECT * FROM users ORDER BY lastName DESC, isMarried ASC;
89 |
90 | # HAVING
91 | ## Фильтрация результатов группировки
92 | ```
93 | - Использование псевдонимов
94 | ```sql
95 | # AS
96 | SELECT firstName AS name FROM users WHERE name = "Alex";
97 | ```
98 | - Изменение таблиц
99 | ```sql
100 | # ALTER TABLE
101 | ## Добавить новую колонку city к таблицe users
102 | ALTER TABLE users ADD COLUMN city VARCHAR(50);
103 | ## Удалить колонку isMarried из таблицы users
104 | ALTER TABLE users DROP COLUMN isMarried;
105 | ## Переименовать колонку firstName в fName в таблицe users
106 | ALTER TABLE users RENAME COLUMN firstName TO fName;
107 | ## Переименовать таблицу users в consumers
108 | ALTER TABLE users RENAME TO consumers;
109 | ```
110 | - Изменение данных в таблице
111 | ```sql
112 | # UPDATE
113 | ## Изменить в таблицe users записать с id = 1
114 | UPDATE users SET firstName = 'Kale', age = 33 WHERE id = 1;
115 | ## Изменить записи, где gender = 'female'
116 | UPDATE users SET city = 'Paris' WHERE gender = 'famale';
117 | ```
118 | - Удаление данных из таблицы
119 | ```sql
120 | # DELETE
121 | # Удалить запись в таблице users, где id = 2
122 | DELETE FROM users WHERE id = 2;
123 | # Удалить все записи в таблице users, где gender = 'male'
124 | DELETE FROM users WHERE gender = 'male';
125 | ```
126 | - [Агрегатные функции](https://codetown.ru/sql/agregatnye-funkcii/)
127 | > Используются для обобщения/подсчёта данных.
128 | ```sql
129 | # COUNT
130 | ## Возвращает количество элементов в таблице users
131 | SELECT COUNT(*) FROM users;
132 | ## Возвращает количество не повторяющихся значений столбца firstName
133 | SELECT COUNT(DISTINCT(firstName)) FROM users;
134 |
135 | # MAX, MIN
136 | SELECT MAX(age) FROM users;
137 | SELECT MIN(age) FROM users;
138 |
139 | # SUM
140 | # Сумма всех значений столбца age
141 | SELECT SUM(age) FROM users;
142 |
143 | # AVG
144 | ## Среднее значение столбца age
145 | SELECT AVG(age) FROM users;
146 | ```
--------------------------------------------------------------------------------
/files/linux/bash-scripts-cheatsheet.md:
--------------------------------------------------------------------------------
1 | # Шпаргалка по Bash скриптам
2 |
3 |
4 |
5 | **Содержание:**
6 |
7 | - [Hello world](#hello-world)
8 | - [Комментарии](#комментарии)
9 | - [Переменные](#переменные)
10 | - [Пользовательский ввод](#пользовательский-ввод)
11 | - [Передача аргументов](#передача-аргументов)
12 | - [Условия if else](#условия-if-else)
13 | - [Операторы условий](#операторы-условий)
14 | - [Логические операторы](#логические-операторы)
15 | - [Арифметические операторы](#арифметические-операторы)
16 | - [Конструкция switch case](#конструкция-switch-case)
17 | - [Массивы](#массивы)
18 | - [Цикл while](#цикл-while)
19 | - [Цикл until](#цикл-until)
20 | - [Цикл for](#цикл-for)
21 | - [Цикл select](#цикл-select)
22 | - [Break и continue в циклах](#break-и-continue-в-циклах)
23 | - [Функции](#функции)
24 | - [Локальные переменные](#локальные-переменные)
25 | - [Ключевое слово readonly](#ключевое-слово-readonly)
26 | - [Обработка сигналов](#обработка-сигналов)
27 |
28 | Скрипты Bash имеют расширение `.sh`:
29 | ```
30 | $ touch script.sh
31 | ```
32 |
33 | Хорошей практикой считается указывать путь до вашего терминала вначале каждого скрипта:
34 | ```sh
35 | #! /bin/bash
36 | ```
37 | > Этот прием называется **shebang**, подробнее можно почитать [тут](https://ru.wikipedia.org/wiki/%D0%A8%D0%B5%D0%B1%D0%B0%D0%BD%D0%B3_(Unix))
38 |
39 | Список доступных терминалов в вашей системе можно посмотреть с помощью этой команды:
40 | ```
41 | $ cat /etc/shells
42 | ```
43 |
44 | ## Hello world
45 |
46 | ```sh
47 | #! /bin/bash
48 | echo "Hello world"
49 | ```
50 |
51 | Запуск скрипта:
52 | ```
53 | $ bash script.sh
54 | ```
55 |
56 | Скрипт можно сделать исполняемым файлом и запускать без команды `bash`:
57 | ```
58 | $ chmod +x script.sh
59 | ```
60 | ```
61 | $ ./script.sh
62 | ```
63 |
64 | ## Комментарии
65 |
66 | Однострочные комментарии:
67 | ```sh
68 | # Это просто коммент
69 | # И это тоже
70 | echo "Hello from bash" # эта команда выводит строку в консоль
71 | ```
72 |
73 | Мультистрочные комментарии:
74 | ```sh
75 | : 'Мультистрочные комментарии очень удобны
76 | для подробного описания ваших скриптов.
77 | Успользуйте их с умом!'
78 | ```
79 |
80 | ## Переменные
81 |
82 | ```sh
83 | MY_STRING="bash is cool"
84 | echo $MY_STRING # Вывод значения переменной
85 | ```
86 | > Имя переменной не должно начинаться с цифры
87 |
88 | ## Пользовательский ввод
89 |
90 | Команда `read` читает пользовательский ввод и записывает его в указанную переменную:
91 | ```sh
92 | echo "Введите ваше имя:"
93 | read NAME
94 | echo "Привет $NAME!"
95 | ```
96 | > Если переменная не указана, то команда `read` по умолчанию сохранит все данные в переменную `REPLY`
97 |
98 |
99 | Можно записывать несколько переменных. Для этого, при вводе из терминала, значения необходимо разделять пробелом:
100 | ```sh
101 | read V1 V2 V3
102 | echo "1 переменная: $V1"
103 | echo "2 переменная: $V2"
104 | echo "3 переменная: $V3"
105 | ```
106 | ```
107 | $ bash script.sh
108 | $ hello world some other text
109 | 1 переменная: hello
110 | 2 переменная: world
111 | 3 переменная: some other text
112 | ```
113 |
114 | Флаг `-a` позволяет создать массив в который будут записываться строки пользовательского ввода разделенные пробелом:
115 | ```sh
116 | read -a NAMES
117 | echo "Массив имён: ${NAMES[0]}, ${NAMES[1]}, ${NAMES[2]}"
118 | ```
119 | ```
120 | $ bash script.sh
121 | Alex Mike John
122 | Массив имён: Alex, Mike, John
123 | ```
124 |
125 | Флаг `-p` позволяет не переносить пользовательский ввод на следующую строку.
126 |
127 | Флаг `-s` позволяет скрыть вводимые символы (как это происходит при вводе пароля).
128 | ```sh
129 | read -p "Введите ваш логин: " LOGIN
130 | read -sp "Введите ваш пароль: " PASSWD
131 | ```
132 | ```
133 | $ bash script.sh
134 | Введите ваш логин: bash_hacker
135 | Введите ваш пароль:
136 | ```
137 |
138 | ## Передача аргументов
139 |
140 | Аргументы это просто значения, которые могут быть указаны при запуске скрипта.
141 |
142 | Всем переданным аргументам присваивается уникальное имя равное их порядковому номеру:
143 | ```sh
144 | echo "Аргумент 1 - $1; aргумент 1 - $2; aргумент 1 - $3."
145 | ```
146 | ```
147 | $ bash script.sh hello test 1337
148 | Аргумент 1 - hello; aргумент 1 - test; aргумент 1 - 1337.
149 | ```
150 |
151 | Нулевой аргумент всегда равен названию файла со скриптом:
152 | ```sh
153 | echo "Вы запустили файл $0"
154 | ```
155 | ```
156 | $ bash script.sh
157 | Вы запустили файл script.sh
158 | ```
159 |
160 | Все аргументы можно положить в именованный массив:
161 | ```sh
162 | args=("$@")
163 | echo "Полученные аргументы: ${args[0]}, ${args[1]}, ${args[2]}."
164 | ```
165 | ```
166 | $ bash script.sh some values 123
167 | Полученные аргументы: some, values, 123
168 | ```
169 | > `@` - это название массива по умолчанию, который хранит все аргументы (за исключением нулевого)
170 |
171 | Количество переданных аргументов (за исключением нулевого) хранится в переменной `#`:
172 | ```sh
173 | echo "Всего получено аргументов: $#"
174 | ```
175 |
176 | ## Условия if else
177 |
178 | Условия всегда начинаются с ключевого слова `if` и заканчиваются на `fi`:
179 | ```sh
180 | echo "Введите ваш возраст:"
181 | read AGE
182 |
183 | if (($AGE >= 18))
184 | then
185 | echo "Доступ разрешен"
186 | else
187 | echo "Доступ запрещен"
188 | fi
189 | ```
190 | ```
191 | $ bash script.sh
192 | Введите ваш возраст:
193 | 19
194 | Доступ разрешен
195 |
196 | $ bash script.sh
197 | Введите ваш возраст:
198 | 16
199 | Доступ запрещен
200 | ```
201 |
202 | Условий может быть сколько угодно много, для этого используется конструкция `elif`, которая также как `if` может проверять условия:
203 | ```sh
204 | read COMMAND
205 |
206 | if [ $COMMAND = "help" ]
207 | then
208 | echo "Доступные команды:"
209 | echo "ping - вернет строку PONG"
210 | echo "version - вернет номер версии программы"
211 | elif [ $COMMAND = "ping" ]
212 | then
213 | echo "PONG"
214 | elif [ $COMMAND = "version" ]
215 | then
216 | echo "v1.0.0"
217 | else
218 | echo "Команда не определена. Воспользуйтесь командой 'help' для справки"
219 | fi
220 | ```
221 | > Обратите внимание, что после конструкций `if` и `elif` всегда следует строчка с ключевым словом `then`
222 | > Так же не забывайте отделять условия пробелами внутри фигурных скобок -> `[ condition ]`
223 |
224 | ## Операторы условий
225 |
226 | Для цифр и строк могут использоваться разные операторы сравнения. Полные их списки с примерами приведены в таблицах ниже.
227 | > Обратите внимания, что разные операторы используются с определенными скобками
228 |
229 | ### Операторы сравнения для чисел
230 |
231 | | Оператор | Описание | Пример |
232 | | -------- | -------------------- | ------------------ |
233 | | -eq | равняется ли | if [ $age -eq 18 ] |
234 | | -ne | не равняется | if [ $age -ne 18 ] |
235 | | -gt | больше чем | if [ $age -gt 18 ] |
236 | | -ge | больше чем или равно | if [ $age -ge 18 ] |
237 | | -lt | меньше чем | if [ $age -lt 18 ] |
238 | | -le | меньше чем или равно | if [ $age -le 18 ] |
239 | | > | больше чем | if (($age > 18)) |
240 | | < | меньше чем | if (($age < 18)) |
241 | | => | больше чем или равно | if (($age => 18)) |
242 | | <= | меньше чем или равно | if (($age <= 18)) |
243 |
244 | ### Операторы сравнения для строк
245 |
246 | | Оператор | Описание | Пример |
247 | | -------- | ------------------------------------------- | ------------------------ |
248 | | = | проверка на равенство | if [ $str = "hello" ] |
249 | | == | проверка на равенство | if [ $str == "hello" ] |
250 | | != | проверка на НЕ равенство | if [ $str != "hello" ] |
251 | | < | сравнение меньше чем по ASCII коду символов | if [[ $str < "hello" ]] |
252 | | > | сравнение больше чем по ASCII коду символов | if [[ $str > "hello" ]] |
253 | | -z | проверка пустая ли строка | if [ -z $str ] |
254 | | -n | проверка есть ли в строке хоть один символ | if [ -n $str ] |
255 |
256 | Так же существуют операторы для проверки различных условий над файлами.
257 |
258 | ### Операторы для проверки файлов
259 |
260 | | Оператор | Описание | Пример |
261 | | -------- | --------------------------------------------------------------------------------- | --------------- |
262 | | -e | проверяет, существует ли файл | if [ -e $file ] |
263 | | -s | проверяет, пустой ли файл | if [ -s $file ] |
264 | | -f | проверяет, является ли файл обычным файлом, а не каталогом или специальным файлом | if [ -f $file ] |
265 | | -d | проверяет, является ли файл каталогом | if [ -d $file ] |
266 | | -r | проверяет, доступен ли файл для чтения | if [ -r $file ] |
267 | | -w | проверяет, доступен ли файл для записи | if [ -w $file ] |
268 | | -x | проверяет, является ли файл исполяемым | if [ -x $file ] |
269 |
270 | ## Логические операторы
271 |
272 | Условия с оператором "И" возвращают истину только в том случае, когда все условия истины.
273 | > Существует несколько вариантов написания условий с логическими операторами
274 |
275 | ```sh
276 | if [ $age -ge 18 ] && [ $age -le ]
277 | ```
278 | ```sh
279 | if [ $age -ge 18 -a $age -le ]
280 | ```
281 | ```sh
282 | if [[ $age -ge 18 && $age -le ]]
283 | ```
284 |
285 | Условия с оператором "ИЛИ" возвращают истину в том случае, когда хотя бы одно условие истинно.
286 |
287 | ```sh
288 | if [ -r $file ] || [ -w $file ]
289 | ```
290 | ```sh
291 | if [ -r $file -o -w $file ]
292 | ```
293 | ```sh
294 | if [[ -r $file || -w $file ]]
295 | ```
296 |
297 | ## Арифметические операторы
298 |
299 | ```bash
300 | num1=10
301 | num2=5
302 |
303 | # Сложение
304 | echo $((num1 + num2)) # 15
305 | echo $(expr $num1 + $num2) # 15
306 |
307 | # Вычитание
308 | echo $((num1 - num2)) # 5
309 | echo $(expr $num1 - $num2) # 5
310 |
311 | # Умножение
312 | echo $((num1 * num2)) # 50
313 | echo $(expr $num1 \* $num2) # 50
314 |
315 | # Деление
316 | echo $((num1 / num2)) # 2
317 | echo $(expr $num1 / $num2) # 2
318 |
319 | # Остаток от деления
320 | echo $((num1 % num2)) # 0
321 | echo $(expr $num1 % $num2) # 0
322 | ```
323 | > Обратите внимание, что при использовании умножения с ключевым словом `expr` необходимо использовать косую черту.
324 |
325 | ## Конструкция switch case
326 |
327 | Не всегда удобно использовать конструкции if/elif для большого количества условий. Для этого лучше подойдет конструкция case:
328 |
329 | ```sh
330 | read COMMAND
331 |
332 | case $COMMAND in
333 | "/help" )
334 | echo "Вы открыли справочное меню" ;;
335 | "/ping" )
336 | echo "PONG" ;;
337 | "/version" )
338 | echo "Текущая версия: 1.0.0" ;;
339 | * )
340 | echo "Такой команды нет :(" ;;
341 | esac
342 | ```
343 |
344 | > Случай со звездочкой * отработает лишь в том случае, если не подойдет ни одно из условий выше.
345 |
346 | ## Массивы
347 |
348 | Массивы позволяют хранить целую коллекцию данных в одной переменной. С этой переменной можно удобно и легко взаимодействовать:
349 |
350 | ```sh
351 | array=('aaa' 'bbb' 'ccc' 'ddd')
352 |
353 | echo "Элементы массива: ${array[@]}"
354 | echo "Первый элемент массива: ${array[0]}"
355 | echo "Индексы элементов массива: ${!array[@]}"
356 |
357 | array_length=${#array[@]}
358 | echo "Длинна массива: ${array_length}"
359 | echo "Последний элемент массива: ${array[$((array_length - 1))]}"
360 | ```
361 | ```
362 | $ bash script.sh
363 | Элементы массива: aaa bbb ccc ddd
364 | Первый элемент массива: aaa
365 | Индексы элементов массива: 0 1 2 3
366 | Длинна массива: 4
367 | Последний элемент массива: ddd
368 | ```
369 | > Обратите внимание, что элементы массива разделются пробелом без запятой.
370 |
371 | Элементы массива можно добавлять/перезаписывать/удалять по ходу выполнения скрипта:
372 |
373 | ```sh
374 | array=('a' 'b' 'c')
375 |
376 | array[3]='d'
377 | echo ${array[@]} # a b c d
378 |
379 | array[0]='x'
380 | echo ${array[@]} # x b c d
381 |
382 | array[0]='x'
383 | echo ${array[@]} # x b c d
384 |
385 | unset array[2]
386 | echo ${array[@]} # x b d
387 | ```
388 |
389 | ## Цикл while
390 |
391 | Цикл while повторяет выполение блока кода описанного между ключевыми словами `do` - `done` пока истино заданное условие.
392 |
393 | ```sh
394 | i=0
395 |
396 | while (( $i < 5 ))
397 | do
398 | i=$((i + 1))
399 | echo "Итерация номер $i"
400 | done
401 | ```
402 | ```
403 | $ bash script.sh
404 | Итерация номер 1
405 | Итерация номер 2
406 | Итерация номер 3
407 | Итерация номер 4
408 | Итерация номер 5
409 | ```
410 |
411 | Операция увеличения числа на 1 единицу называется инкриментом и для неё существует специальная запись:
412 |
413 | ```sh
414 | (( i++ )) # post increment
415 | ```
416 | ```sh
417 | (( ++i )) # pre increment
418 | ```
419 |
420 | Противоположная операция - декремент:
421 |
422 | ```sh
423 | (( i-- )) # post decrement
424 | ```
425 | ```sh
426 | (( --i )) # pre decrement
427 | ```
428 |
429 | С помощью while циклов можно построчно читать различные файлы. Существует несколько способов сделать это:
430 |
431 | ```sh
432 | echo "Чтение файла по строкам:"
433 | while read line
434 | do
435 | echo $line
436 | done < text.txt
437 | ```
438 |
439 | ```sh
440 | echo "Чтение файла по строкам:"
441 | cat text.txt | while read line
442 | do
443 | echo $line
444 | done
445 | ```
446 |
447 | ```sh
448 | echo "Чтение файла по строкам:"
449 | while IFS='' read -r line
450 | do
451 | echo $line
452 | done < text.txt
453 | ```
454 |
455 | ## Цикл until
456 |
457 | Цикл until противоположен циклу while тем, что он выполняет блок кода описанный между ключевыми словами `do` - `done` тогда, когда заданное условие возвращает false:
458 |
459 | ```sh
460 | i=5
461 | until (( $i == 0 )) # будет выполняться пока i не станет равным 0
462 | do
463 | echo "Значение переменной i = $i"
464 | (( i-- ))
465 | done
466 | ```
467 | ```
468 | $ bash script.sh
469 | Значение переменной i = 5
470 | Значение переменной i = 4
471 | Значение переменной i = 3
472 | Значение переменной i = 2
473 | Значение переменной i = 1
474 | ```
475 |
476 | ## Цикл for
477 |
478 | Самый классический цикл:
479 | ```sh
480 | for (( i=1; i<=10; i++ ))
481 | do
482 | echo $i
483 | done
484 | ```
485 |
486 | В новых версиях Bash существует более удобный способ записи с помощью оператора `in`:
487 |
488 | ```sh
489 | for i in {1..10}
490 | do
491 | echo $i
492 | done
493 | ```
494 |
495 | Условие после ключевого слова `in` в общем случае выгядит так:
496 |
497 | ```
498 | {START..END..INCREMENT}
499 | ```
500 | > _START_ - с какого элемента начинать цикл;
501 | > _END_ - до какого элемента продолжать цикл;
502 | > _INCREMENT_ - на сколько увеличивать элемент после каждой итерации (по умолчанию на 1).
503 |
504 |
505 | Цикл for можно использовать для последовательного запуска набора команд:
506 |
507 | ```sh
508 | for command in ls pwd date # Список команд для запуска
509 | do
510 | echo "---Запуск команды $command---"
511 | $command
512 | echo "------------------------"
513 | done
514 | ```
515 | ```
516 | $ bash script.sh
517 | ---Запуск команды ls---
518 | script.sh text.txt
519 | ------------------------
520 | ---Запуск команды pwd---
521 | /home/user/bash
522 | ------------------------
523 | ---Запуск команды date---
524 | Сб 03 сен 2022 10:35:57 +03
525 | ------------------------
526 | ```
527 |
528 | Ключевое слово `break` останавливает выполнение цикла.
529 |
530 | Ключевое слово `continue` завершает текущую итерацию цикла и переходит к следующей.
531 |
532 | ## Цикл select
533 |
534 | Крайне удобный цикл для создания меню выбора опций:
535 |
536 | ```sh
537 | select color in "Красный" "Зеленый" "Синий" "Белый"
538 | do
539 | echo "Вы выбрали $color цвет..."
540 | done
541 | ```
542 | ```
543 | $ bash script.sh
544 | 1) Красный
545 | 2) Зеленый
546 | 3) Синий
547 | 4) Белый
548 | #? 1
549 | Вы выбрали Красный цвет...
550 | #? 2
551 | Вы выбрали Зеленый цвет...
552 | #? 3
553 | Вы выбрали Синий цвет...
554 | #? 4
555 | Вы выбрали Белый цвет...
556 | ```
557 |
558 | Цикл `select` очень хорошо сочетается с оператором выбора `case`. Таким образом можно очень просто создавать интерактивные консольные приложения с большим количеством разветвлений:
559 |
560 | ```sh
561 | echo "---Добро пожаловать в меню---"
562 |
563 | select cmd in "Запуск" "Настройки" "О программе" "Выход"
564 | do
565 | case $cmd in
566 | "Запуск")
567 | echo "Программа запущена"
568 | echo "Введите число:"
569 | read input
570 | echo "$input в квадрате = $(( input * input ))" ;;
571 | "Настройки")
572 | echo "Настройки программы" ;;
573 | "О программе")
574 | echo "Версия 1.0.0" ;;
575 | "Выход")
576 | echo "Выход из программы..."
577 | break ;;
578 | esac
579 | done
580 | ```
581 |
582 | ## Break и continue в циклах
583 |
584 | Для принудительного выхода из цикла используется ключевое слово `break`:
585 |
586 | ```sh
587 | count=1
588 |
589 | while (($count)) # всегда возвращает истину
590 | do
591 | if (($count > 10))
592 | then
593 | break # принудительный выход несмотря на условие после while
594 | else
595 | echo $count
596 | ((count++))
597 | fi
598 | done
599 | ```
600 |
601 | Для того, чтобы пропустить выполнение текущей итерации в цикле и перейти к следующей - используется ключевое слово `continue`:
602 |
603 | ```sh
604 | for (( i=5; i>0; i-- ))
605 | do
606 | if ((i % 2 == 0))
607 | then
608 | continue
609 | fi
610 |
611 | echo $i
612 | done
613 | ```
614 | ```
615 | $ bash script.sh
616 | 5
617 | 3
618 | 1
619 | ```
620 |
621 | ## Функции
622 |
623 | Функции - это именованные участки кода, которые могут переиспользоваться неограниченное количество раз:
624 |
625 | ```sh
626 | hello() {
627 | echo "Hello World!"
628 | }
629 |
630 | # вызываем функцию 3 раза:
631 | hello
632 | hello
633 | hello
634 | ```
635 | ```
636 | $ bash script.sh
637 | Hello World!
638 | Hello World!
639 | Hello World!
640 | ```
641 |
642 | Функции, так же, как и сами скрипты, могут принимать аргументы. Они имеют такие же названия, но аргументы функций видны только внутри функции, в которую они были переданы:
643 |
644 | ```sh
645 | echo "$1" # аргумент переданный при запуске скрипта
646 |
647 | calc () {
648 | echo "$1 + $2 = $(($1 + $2))"
649 | }
650 |
651 | # передача двух аргументов в функцию calc
652 | calc 42 17
653 | ```
654 | ```
655 | $ bash script.sh hello
656 | hello
657 | 42 + 17 = 59
658 | ```
659 |
660 | ## Локальные переменные
661 |
662 | Если мы объявим какую-либо переменную, а затем объявим ещё одну с таким же именем, но уже внутри функции, то у нас произойдет перезапись:
663 |
664 | ```sh
665 | VALUE="hello"
666 |
667 | test() {
668 | VALUE="linux"
669 | }
670 |
671 | test
672 | echo $VALUE
673 | ```
674 | ```
675 | $ bash script.sh
676 | linux
677 | ```
678 |
679 | Чтобы предотвратить такое поведение используются ключевое слово `local` перед именем переменной, которая объявляется внутри функции:
680 |
681 | ```sh
682 | VALUE="hello"
683 |
684 | test() {
685 | local VALUE="linux"
686 | echo "Переменная внутри функции: $VALUE"
687 | }
688 |
689 | test
690 | echo "Глобальная переменная: $VALUE"
691 | ```
692 | ```
693 | $ bash script.sh
694 | Переменная внутри функции: linux
695 | Глобальная переменная: hello
696 | ```
697 |
698 | ## Ключевое слово readonly
699 |
700 | По умолчанию, каждая созданная переменная в Bash в последующем может перезаписываться. Чтобы защитить переменную от изменений можно использовать ключевое слово `readonly`:
701 |
702 | ```sh
703 | readonly PI=3.14
704 | PI=100
705 |
706 | echo "PI = $PI"
707 | ```
708 | ```
709 | $ bash script.sh
710 | script.sh: строка 2: PI: переменная только для чтения
711 | PI = 3.14
712 | ```
713 |
714 | `readonly` можно использовать не только в момент объявления переменной, но и после:
715 |
716 | ```sh
717 | VALUE=123
718 | VALUE=$(($VALUE * 1000))
719 | readonly VALUE
720 | VALUE=555
721 |
722 | echo $VALUE
723 | ```
724 | ```
725 | $ bash script.sh
726 | script.sh: строка 4: VALUE: переменная только для чтения
727 | 123000
728 | ```
729 |
730 | Тоже самое касается функций. Они так же могут быть переопределены, поэтому их можно защитить с помощью `readonly` указав при этом флаг `-f`:
731 |
732 | ```sh
733 | test() {
734 | echo "This is test function"
735 | }
736 |
737 | readonly -f test
738 |
739 | test() {
740 | echo "Hello World!"
741 | }
742 |
743 | test
744 | ```
745 | ```
746 | $ bash script.sh
747 | script.sh: строка 9: test: значение функции можно только считать
748 | This is test function
749 | ```
750 |
751 | ## Обработка сигналов
752 |
753 | Во время выполнения скриптов, могут происходить неожиданные действия. Например, пользователь может прервать выполнения скрипта с помощь комбинации `Ctrl + C`, либо может случайно закрыть терминал или в самом скрипте может случится какая-либо ошибка и так далее...
754 |
755 | В POSIX-системах существуют специальные сигналы - уведомления процесса о каком-либо событии. Их список определен в таблице ниже:
756 |
757 | | Сигнал | Код | Действие | Описание |
758 | | ------- | -------- | -------------------------- | -------------------------------------------------------- |
759 | | SIGHUP | 1 | Завершение | Закрытие терминала |
760 | | SIGINT | 2 | Завершение | Сигнал прерывания (Ctrl-C) с терминала |
761 | | SIGQUIT | 3 | Завершение с дампом памяти | Сигнал «Quit» с терминала (Ctrl-) |
762 | | SIGILL | 4 | Завершение с дампом памяти | Недопустимая инструкция процессора |
763 | | SIGABRT | 6 | Завершение с дампом памяти | Сигнал, посылаемый функцией abort() |
764 | | SIGFPE | 8 | Завершение с дампом памяти | Ошибочная арифметическая операция |
765 | | SIGKILL | 9 | Завершение | Процесс уничтожен (kill signal) |
766 | | SIGSEGV | 11 | Завершение с дампом памяти | Нарушение при обращении в память |
767 | | SIGPIPE | 13 | Завершение | Запись в разорванное соединение (пайп, сокет) |
768 | | SIGALRM | 14 | Завершение | Сигнал истечения времени, заданного alarm() |
769 | | SIGTERM | 15 | Завершение | Сигнал завершения (сигнал по умолчанию для утилиты kill) |
770 | | SIGUSR1 | 30/10/16 | Завершение | Пользовательский сигнал № 1 |
771 | | SIGUSR2 | 31/12/17 | Завершение | Пользовательский сигнал № 2 |
772 | | SIGCHLD | 20/17/18 | Игнорируется | Дочерний процесс завершен или остановлен |
773 | | SIGCONT | 19/18/25 | Продолжить выполнение | Продолжить выполнение ранее остановленного процесса |
774 | | SIGSTOP | 17/19/23 | Остановка процесса | Остановка выполнения процесса |
775 | | SIGTSTP | 18/20/24 | Остановка процесса | Сигнал остановки с терминала (Ctrl-Z) |
776 | | SIGTTIN | 21/21/26 | Остановка процесса | Попытка чтения с терминала фоновым процессом |
777 | | SIGTTOU | 22/22/27 | Остановка процесса | Попытка записи на терминал фоновым процессом |
778 |
779 | В Bash есть ключевое слово `trap` с помощью которого можно отлавливать различные сигналы и предусматривать выполнение определенных команд:
780 |
781 | ```
782 | trap <КОМАНДА> <СИГНАЛ>
783 | ```
784 | > Под сигналом можно использовать его название (колонка _Сигнал_ в таблице), либо его код (колонка _Код_ в таблице). Можно указывать несколько сигналов разделяя их названия или коды пробелом.
785 | > **Исключения:** сигналы SIGKILL (9) и SIGSTOP (17/19/23) отловить невозможно, поэтому нет смысла их указывать.
786 |
787 | ```sh
788 | trap "echo Выполнение программы прервано...; exit" SIGINT
789 |
790 | for i in {1..10}
791 | do
792 | sleep 1
793 | echo $i
794 | done
795 | ```
796 | ```
797 | $ bash script.sh
798 | 1
799 | 2
800 | 3
801 | 4
802 | ^CВыполнение программы прервано...
803 | ```
804 |
805 | ## Отладка скриптов
806 |
807 | Запуск скрипта с параметром `-x` покажет его поэтапное выполнение, что будет полезно при отладке и поиске ошибок:
808 |
809 | ```
810 | $ bash -x script.sh
811 | ```
812 |
813 |
--------------------------------------------------------------------------------
/files/linux/chmod.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/linux/chmod.png
--------------------------------------------------------------------------------
/files/linux/chmod_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/linux/chmod_eng.png
--------------------------------------------------------------------------------
/files/linux/cron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/linux/cron.png
--------------------------------------------------------------------------------
/files/linux/cron_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/linux/cron_eng.png
--------------------------------------------------------------------------------
/files/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/logo.png
--------------------------------------------------------------------------------
/files/network-internet/Browser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Browser.png
--------------------------------------------------------------------------------
/files/network-internet/Domain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Domain.png
--------------------------------------------------------------------------------
/files/network-internet/Hosting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Hosting.png
--------------------------------------------------------------------------------
/files/network-internet/IPv4-IPv6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/IPv4-IPv6.png
--------------------------------------------------------------------------------
/files/network-internet/Internet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Internet.png
--------------------------------------------------------------------------------
/files/network-internet/Problems.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Problems.gif
--------------------------------------------------------------------------------
/files/network-internet/Traceroute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Traceroute.png
--------------------------------------------------------------------------------
/files/network-internet/browser_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/browser_eng.png
--------------------------------------------------------------------------------
/files/network-internet/dns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/dns.png
--------------------------------------------------------------------------------
/files/network-internet/domain_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/domain_eng.png
--------------------------------------------------------------------------------
/files/network-internet/http.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/http.png
--------------------------------------------------------------------------------
/files/network-internet/http_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/http_eng.png
--------------------------------------------------------------------------------
/files/network-internet/osi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/osi.png
--------------------------------------------------------------------------------
/files/network-internet/problems_eng.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/problems_eng.gif
--------------------------------------------------------------------------------
/files/network-internet/proxy-vpn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/proxy-vpn.png
--------------------------------------------------------------------------------
/files/network-internet/proxy-vpn_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/proxy-vpn_eng.png
--------------------------------------------------------------------------------
/files/network-internet/tcp-ip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/tcp-ip.png
--------------------------------------------------------------------------------
/files/network-internet/tcp-ip_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/tcp-ip_eng.png
--------------------------------------------------------------------------------
/files/network-internet/tcp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/tcp.png
--------------------------------------------------------------------------------
/files/network-internet/topologies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/topologies.png
--------------------------------------------------------------------------------
/files/network-internet/topologies_rus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/topologies_rus.png
--------------------------------------------------------------------------------
/files/network-internet/udp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/udp.png
--------------------------------------------------------------------------------
/files/optimization/cdn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/optimization/cdn.png
--------------------------------------------------------------------------------
/files/optimization/cdn_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/optimization/cdn_eng.png
--------------------------------------------------------------------------------
/files/optimization/load-balancer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/optimization/load-balancer.png
--------------------------------------------------------------------------------
/files/optimization/load-balancer_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/optimization/load-balancer_eng.png
--------------------------------------------------------------------------------
/files/os/concurrency-parallel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/concurrency-parallel.png
--------------------------------------------------------------------------------
/files/os/os-layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/os-layer.png
--------------------------------------------------------------------------------
/files/os/os-layer_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/os-layer_eng.png
--------------------------------------------------------------------------------
/files/os/process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/process.png
--------------------------------------------------------------------------------
/files/os/process_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/process_eng.png
--------------------------------------------------------------------------------
/files/programming-language/regex-cheatsheet.md:
--------------------------------------------------------------------------------
1 | # Шпаргалка по регулярным выражениям
2 |
3 |
4 |
5 | **Содержание:**
6 |
7 | - [Базовое применение](#базовое-применение)
8 | - [Флаги](#флаги)
9 | - [Основной синтаксис](#основной-синтаксис)
10 | - [Любой символ .](#любой-символ-)
11 | - [Перечень []](#перечень-)
12 | - [Исключающий перечень [^]](#исключающий-перечень-)
13 | - [Диапазон [-]](#диапазон--)
14 | - [Повторения *](#повторения-)
15 | - [Повторения +](#повторения--1)
16 | - [Необязательный символ ?](#необязательный-символ-)
17 | - [Количество повторений {}](#количество-повторений-)
18 | - [Диапазон повторений {,}](#диапазон-повторений-)
19 | - [Группировка ()](#группировка-)
20 | - [Логическое ИЛИ |](#логическое-или-)
21 | - [Экранирование](#экранирование-)
22 | - [Поиск в начале строки ^](#поиск-в-начале-строки-)
23 | - [Поиск в конце строки $](#поиск-в-конце-строки-)
24 | - [Классы символов](#классы-символов)
25 | - [Позиционные проверки](#позиционные-проверки)
26 |
27 |
28 | [Регулярные выражения](https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F) – это мощный инструмент для поиска и замены слов в тексте. Само регулярное выражение представляет из себя обычную строку составленную по определенным правилами. В общем виде она представляет из себя две косые черты `/ /`, где после первой черты идёт специальный паттерн для поиска, а после второй – набор флагов.
29 |
30 | Для тренировки использования регулярных выражений можно воспользоваться сайтом [Regex101.com](https://regex101.com/).
31 |
32 | Также можно воспользоваться возможностями для работы с регулярными выражениями в одном из языков программирования. Вот примеры для [Python](https://pythonru.com/primery/primery-primeneniya-regulyarnyh-vyrazheniy-v-python), [JavaScript](https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Regular_Expressions), [Go](https://tproger.ru/articles/puteshestvie-v-golang-regexp/), [Kotlin](https://java-blog.ru/kotlin/vvedenie-v-regulyarnye-vyrazheniya-kotlin), [C#](https://metanit.com/sharp/tutorial/7.4.php) и [так далее](https://www.google.com/search?q=%D0%BA%D0%B0%D0%BA+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C+%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5+%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F+%D0%B2+%5B%D0%B2%D0%B0%D1%88+%D1%8F%D0%B7%D1%8B%D0%BA+%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%5D%5D)
33 |
34 | ## Базовое применение
35 |
36 | Возьмем для примера любой текст. Представим, что в этом тексте нам нужно найти все слова `London`. Это самый простой случай использования регулярных выражения, нам всего лишь необходимо вписать нужное слово между косыми чертами:
37 |
38 | 
39 |
40 | ## Флаги
41 |
42 | Флаги влияют на результат поиска. Их всего 5 штук:
43 |
44 | - `i` – позволяет игнорировать регистры букв (нет разницы между *A* и *a*).
45 | - `g` – позволяет искать все совпадения в тексте, без него – только первое.
46 | - `m` – включение многострочного режима (влияет только на поведение `^` и `$`).
47 | - `s` – текст трактуется как одна строка, в этом случае метасимволу `.` (точка) соответствует любой одиночный символ, включая символ новой строки.
48 | - `u` – unicode-трактовка. Выражение может содержать специальные паттерны, характерные для юникода.
49 |
50 | ## Основной синтаксис
51 |
52 | ### Любой символ `.`
53 |
54 | На месте точки может быть любой символ. Количеством точек можно определять длину слов.
55 |
56 | ```js
57 | /t..k/g
58 | ```
59 |
60 | > take look team took hike track teak time
61 |
62 | ### Перечень `[]`
63 |
64 | Позволяют указать определенный перечень символов.
65 |
66 | ```js
67 | /t[aoi]k/g
68 | ```
69 |
70 | > tek tok tdk tak tik tuk tyk took taoik
71 |
72 | ### Исключающий перечень `[^]`
73 |
74 | Позволяет исключить определенный набор символ из поиска, используется вместе с квадратными скобками.
75 |
76 | ```js
77 | /ba[^td]/g
78 | ```
79 |
80 | > ban bag bat bas bad
81 |
82 | ### Диапазон `[-]`
83 |
84 | Указывает диапазон с первого по последний символ (включительно) в алфавитном порядке.
85 |
86 | ```js
87 | /[a-d]../g
88 | ```
89 |
90 | > ost hst ast fst cst bst
91 |
92 | Аналогично работает с цифрами:
93 |
94 | ```js
95 | /201[5-9]/g
96 | ```
97 |
98 | > 2010 2012 2015 2017 2019 2022
99 |
100 | ### Повторения `*`
101 |
102 | Звездочка после символа указывает, что данный символ может отсутствовать, либо совпадать один или более раз.
103 |
104 | ```js
105 | /wo*w/g
106 | ```
107 |
108 | > wow waw wiw woooow wawe ww woow
109 |
110 | ### Повторения `+`
111 |
112 | Плюс после символа указывает, что данный символ должен присутствовать один или более раз.
113 |
114 | ```js
115 | /go+gle/g
116 | ```
117 |
118 | > google ggle gogle gugle g00gle goooogle
119 |
120 | ### Необязательный символ `?`
121 |
122 | Вопросительный знак после символа указывает, что данный символ является не обязательным (может либо отсутствовать, либо встрачаться только один раз).
123 |
124 | ```js
125 | /bou?nd/g
126 | ```
127 |
128 | > bond bound bouuund boynd
129 |
130 | ### Количество повторений `{}`
131 |
132 | Чтобы указать точное количеcтво повторений, необходимо после символа записать фигурные скобки с нужным числом.
133 |
134 | ```js
135 | /bo{3}m/g
136 | ```
137 |
138 | > boom bom booom bm boooom
139 |
140 | ### Диапазон повторений `{,}`
141 |
142 | Чтобы указать диапазон повторений, необходимо после символа записать фигурный скобки с нужным диапазоном, разделенным запятой.
143 |
144 | ```js
145 | /lo{2,4}k/g
146 | ```
147 |
148 | > lok look lk loook looook loooooook
149 |
150 | Верхнюю границу можно опускать. Например, запись `a{3,}` говорит о том, что символ _a_ должен встречаться не менее трёх раз.
151 |
152 | ### Группировка `()`
153 |
154 | Скобки позволяют сгруппировать любую последовательность символов, чтобы в дальнейшем обращается к ним используя выражение `\число`, где число - порядковый номер сгруппированной последовательности.
155 |
156 | ```js
157 | /(la)-\1{2}-\1{3}/g // Группируем выражение "la" и затем, обращаемся к нему через "\1"
158 | ```
159 |
160 | > la-laaa-la-lala-lalala-lalala-la-la-la
161 |
162 | ```js
163 | /(la)-\1-(laa)-\2/g
164 | ```
165 |
166 | > laa-la-laa-la-la-laa-laa-lalal
167 |
168 | Чтобы игнорировать сохранение группы используется конструкция `(?:)`.
169 |
170 | ```js
171 | /(?:abc)-(test),\1,\1/g // В данном случае группа "abc" не будет сохранена, поэтому первый индекс указывает на "test".
172 | ```
173 |
174 | > abc,test-abc-test,test,test-abc-test
175 |
176 | Группам можно задавать любые имена. Для этого используется конструкция - `(?P...)`, где Name - название, ... - любая последовательность символов. Для обращения к именованным группам используется конструкция - `(?P=Name)`.
177 |
178 | ```js
179 | /(?P7{3})-(?P=seven){2}-(?P=seven)/g
180 | ```
181 |
182 | > 7777-77-7777777-777-777777-777-777-7-7-7-7777-7
183 |
184 | Если у Вас возникли трудности с пониманием группировки, советую [посмотреть данное видео](https://youtu.be/W9CffcsYpAU).
185 |
186 | ### Логическое ИЛИ `|`
187 |
188 | Вертикальная черта позволяет указывать альтернативные варианты для поиска. Это чем-то похоже на использование квадратных скобок `[abc]`, но только вертикальная черта может работать с целыми словами и выражениями, а не только с отдельными символами.
189 |
190 | ```js
191 | /yes|no/g
192 | ```
193 |
194 | > yes,maybe,no,idk,ok
195 |
196 | ### Экранирование `\`
197 |
198 | Для того, чтобы использовать в поиске специальные символы `{} [] / \ + *. $ ^ |?`, необходимо поставить впереди знак косой черты `\`.
199 |
200 | ```js
201 | /\.|\?/g // Поиск точек "." или знаков вопроса "?"
202 | ```
203 |
204 | > What now? What next? Times up. Wake up.
205 |
206 | ### Поиск в начале строки `^`
207 |
208 | Символ каретки в регулярном выражении говорит о том, что поиск производится только по началу строк.
209 |
210 | ```js
211 | /^[0-9]*/gm // Поиск чисел которые находятся в начале строки
212 | ```
213 |
214 | > 1. Apples x10
215 | > 2. Cookies x5
216 | > 3. Eggs x7
217 |
218 | ### Поиск в конце строки `$`
219 |
220 | Символ доллара в регулярном выражении говорит о том, что поиск производится только по концу строк.
221 |
222 | ```js
223 | /com|net/gm
224 | ```
225 |
226 | > google.com
227 | > nodejs.org
228 | > sourceforge.net
229 |
230 | ### Классы символов
231 |
232 | Для более удобного поиска целого класса символов существуют встроенные обозначения.
233 |
234 | #### Любой словесный символ `\w`
235 |
236 | Обе записи ниже эквивалентны.
237 |
238 | ```js
239 | /[a-zA-Z0-9_]/g
240 | ```
241 |
242 | ```js
243 | /\w/g
244 | ```
245 |
246 | > some random words for example
247 |
248 | #### Любой не словесный символ `\W`
249 |
250 | ```js
251 | /[^a-zA-Z0-9_]/g
252 | ```
253 |
254 | ```js
255 | /\W/g
256 | ```
257 |
258 | > developer_2022@gmail.com
259 |
260 | #### Любая цифра `\d`
261 |
262 | ```js
263 | /[0-9]/g
264 | ```
265 |
266 | ```js
267 | /\d/g
268 | ```
269 |
270 | > developer_2022@gmail.com
271 |
272 | #### Любой символ кроме цифр `\D`
273 |
274 | ```js
275 | /[^0-9]/g
276 | ```
277 |
278 | ```js
279 | /\D/g
280 | ```
281 |
282 | > developer_2022@gmail.com
283 |
284 | #### Пробел `\s`
285 |
286 | К пробелам также относятся различные символы переноса строк.
287 |
288 | ```js
289 | /[\r\n\t\f\v ]/g
290 | ```
291 |
292 | ```js
293 | /\s/g
294 | ```
295 |
296 | #### Любой символ кроме пробела `\S`
297 |
298 | ```js
299 | /[^\r\n\t\f\v ]/g
300 | ```
301 |
302 | ```js
303 | /\S/g
304 | ```
305 |
306 | ### Позиционные проверки
307 |
308 | Для того, чтобы найти фразу, которая должна находится до или после другой фразы используются позиционные проверки (lookarounds).
309 |
310 | #### Опережающие проверки `(?=)` `(?!)`
311 |
312 | Чтобы найти выражение Х после которого стоит выражение Y, используется конструкция `X(?=Y)`.
313 |
314 | ```js
315 | /\d+(?=€)/g
316 | ```
317 |
318 | > 200$ 750€ 100$ 330€ 550$
319 |
320 | Чтобы найти выражение Х после которого НЕ стоит выражение Y, используется конструкция `X(?!Y)`.
321 |
322 | ```js
323 | /\d{4,}(?!€)/g
324 | ```
325 |
326 | > This car was costed about 7000€ in 2015
327 |
328 | #### Ретроспективные проверки `(?<=)` `(? {"id":4,"value":123,name:"test"}
337 |
338 | Чтобы найти выражение X перед которым НЕ стоит выражение Y, используется конструкция `(? $5 $6 $7 2019 2009 1999
345 |
346 |
347 | ## Практика
348 |
349 | Потратьте немного времени на закрепление изученного материала. Напишите простую библиотеку на Вашем любимом языке программирования, которая будет выполнять валидации (проверки) заданных строк. Например, на соответствие электронной почты или номера телефона. Напишите валидатор для паролей, чтобы он соответствовал заданным требованиям по длине, наличию специальных символов, заглавных букв или цифр. Это будет вдвойне полезным занятием, поскольку в будущем вы сможете использовать эту библиотеку в Ваших приложениях.
350 |
351 | Дополнительно по запросу в Google – _regex practice_, можно найти много интересных заданий на тему регулянрых выражений.
352 |
353 | ## Дополнительные материалы
354 |
355 | 1. 📄 [**Awesome Regex** – GitHub](https://github.com/aloisdg/awesome-regex)
356 | 1. 📺 [**Регулярные выражения в SEO: где и как применяются** – YouTube](https://youtu.be/ZxWfQW32dIE)
357 | 1. 📘 [**Регулярные выражения. Сборник рецептов** – Ян Гойвертс, Стивен Левитан, 2010](https://www.litmir.me/data/Book/0/156000/156298/Goiverts_Yan_Regulyarnye_vyracheniya._Sbornik_receptov_%5BPodrobnye_resheniya_na_vosmi_yazykah_programmirova_Litmir.net_bid156298_original.pdf)
358 |
--------------------------------------------------------------------------------
/files/security/hashing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/security/hashing.png
--------------------------------------------------------------------------------
/files/security/hashing_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/security/hashing_eng.png
--------------------------------------------------------------------------------
/files/software/message-queue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/software/message-queue.png
--------------------------------------------------------------------------------
/files/software/message-queue_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/software/message-queue_eng.png
--------------------------------------------------------------------------------
/files/software/web-server_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/software/web-server_eng.png
--------------------------------------------------------------------------------
/files/software/web-server_rus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/software/web-server_rus.png
--------------------------------------------------------------------------------
/files/testing/testing-pyramid_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/testing/testing-pyramid_eng.png
--------------------------------------------------------------------------------
/files/testing/testing-pyramid_rus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/testing/testing-pyramid_rus.png
--------------------------------------------------------------------------------