Данный репозиторий представляет собой наглядную шпаргалку по основным темам в области Backend-разработки. Весь материал разбит на темы и подтемы. Структура материала состоит из трех частей:
-**Визуальная часть** - различные изображения/таблицы/шпаргалки для лучшего понимания (может отсутствовать). Все рисунки и таблицы сделаны с нуля, специально для этого репозитория.
-**Краткое описание** - очень краткая выжимка информации с перечнем основных терминов и понятий. На термины навешиваются гиперссылки ведущие на соответствующий раздел в Википедии или подобном справочном ресурсе.
-**Ссылки на источники** - ресурсы, где можно найти полную информацию по конкретному вопросу. По возможности, указываются максимально авторитетные источники, либо же те, которые предоставляют информацию максимально простым и понятным языком.
> 🛠 Репозиторий находится в стадии активной разработки, поэтому постоянно обновляется и дополняется (см. [список будущих нововведений](https://github.com/users/cheatsnake/projects/1/views/1))
> 🤝 Если уВас есть идеи как сделать проект лучше, не стесняйтесь присылать [Issues](https://github.com/cheatsnake/backend-cheats/issues) и [Pull requests](https://github.com/cheatsnake/backend-cheats/pulls)
[Интернет](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82) - это всемирная система объединяющая компьютерные сети со всего мира в единую сеть для хранения/передачи информации. Изначально Интернет разрабатывался для военных. Но вскоре он стал внедряться в учреждения образования (университеты), а затем его смогли использовать частные компании, которые начали организовывать сети провайдеров, предоставляющие услуги доступа в Интернет обычным гражданам. К началу 2020 года количество пользователей в сети Интернет перевалило за 4.5 млрд человек.
Ваш компьютер никогда не был связан с Интернетом напрямую. Поскольку он способен видеть только свою локальную сеть, в которую проводным ([Ethernet](https://ru.wikipedia.org/wiki/Ethernet)) или беспроводным (Wi-Fi, Bluetooth) путем подключены другие устройства. Для связи с Интернетом в вашей локальной сети находиться специальный мини-компьютер – [маршрутизатор](https://ru.wikipedia.org/wiki/Маршрутизатор). Далее он связывает вас с [интернет-провайдером](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82-%D0%BF%D1%80%D0%BE%D0%B2%D0%B0%D0%B9%D0%B4%D0%B5%D1%80), который в свою очередь связан с другими провайдерами более высокого уровня. Таким образом, ваше сообщение, проходит транзитом через сеть нескольких провайдеров, прежде чем достигнет сеть назначения.
Интернет – это всего лишь длинный провод, к которому напрямую присоединены небольшое количество [провайдеров первого уровня](https://ru.wikipedia.org/wiki/Tier-1-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B). Провайдеры уровня ниже просто арендуют доступ.
[Доменные имена](https://ru.wikipedia.org/wiki/%D0%94%D0%BE%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE%D0%B5_%D0%B8%D0%BC%D1%8F) - это человеко-читаемые адреса веб-серверов, доступных в Интернете. Они состоят из частей (уровней) разделенных между собой точкой. Каждая из этих частей предоставляет специфическую информацию о доменном имени. Например страну, название сервиса, локализацию и т.д.<br><br>
> Корпорация [ICANN](https://ru.wikipedia.org/wiki/ICANN) является основателем распределённой системы регистрации доменов. Она выдаёт аккредитации компаниям, которые хотят заниматься продажей доменов. Таким образом формируется конкурентный доменный рынок.
- Как купить доменное имя
> Доменное имя нельзя купить навсегда. Оно выдается в аренду на определенный срок. Покупать домены лучше у [аккредитованных регистраторов](https://www.icann.org/en/accredited-registrars?filter-letter=a&sort-direction=asc&sort-param=name&page=1) (найти их можно почти в любой стране).
[IP-адрес](https://ru.wikipedia.org/wiki/IP-%D0%B0%D0%B4%D1%80%D0%B5%D1%81) – уникальный числовой адрес, который используется для распознавания того или иного устройства в сети.
> - Внешний и доступный всем IP-адрес, который принадлежит Вашему провайдеру и используется для выхода в интернет сотен других пользователей.
> - IP-адрес вашего роутера в локальной сети провайдера, той самой, с IP-адресом которой вы выходите в интернет.
> - IP-адрес вашего компьютера в локальной (домашней) сети, созданной роутером, к которой вы можете подключать свои устройства. Как правило, имеет вид 192.168.XXX.XXX.
> - Внутренний IP-адрес компьютера, недоступный извне и используемый только для общения между запущенными процессами. У всех он одинаковый – 127.0.0.1 или просто localhost.
> На одном устройстве (компьютере) может работать множество приложений, которые используют сеть. Для того, чтобы правильно распознать, куда и какие данные, пришедшие по сети, нужно доставить (в какое из приложений) используется специальный числовой номер – порт. То есть, каждый запущенный процесс на компьютере, который использует сетевое подключение, имеет свой личный порт.
> 4 версия IP-протокола. Разработана в 1981 году и ограничивает адресное пространство около 4.3 млрд (2^32) возможными уникальными адресами.
- [IPv6](https://ru.wikipedia.org/wiki/IPv6)
> Со временем распределение адресного пространства стало происходить значительно более быстрыми темпами, что вынудило создание новой версии IP-протокола для хранения большего количества адресов. IPv6 способен выдать 2^128 уникальных адресов.
2. 📄 [**Всё об IP адресах и о том, как с ними работать** – habr.com](https://habr.com/ru/post/350878/)
3. 📄 [**Как узнать IP-адрес в Linux**](https://losst.pro/kak-uznat-ip-adres-linux)
4. 📺 [**Порты и перенаправление\открытие портов. Инструкция и объяснения на пальцах** – YouTube](https://www.youtube.com/watch?v=SGmBv_klQ9I)
5. 📄 [**Список зарезервированных портов TCP и UDP** – Википедия](https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BF%D0%BE%D1%80%D1%82%D0%BE%D0%B2_TCP_%D0%B8_UDP)
6. 📄 [**Протоколы IPv4 и IPv6. В чем разница и что лучше?**](https://bezopasnik.info/%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%8B-ipv4-%D0%B8-ipv6-%D0%B2-%D1%87%D0%B5%D0%BC-%D1%80%D0%B0%D0%B7%D0%BD%D0%B8%D1%86%D0%B0-%D0%B8-%D1%87%D1%82%D0%BE-%D0%BB%D1%83%D1%87%D1%88%D0%B5/)
[DNS (Domain Name System)](https://ru.wikipedia.org/wiki/DNS) - это децентрализованная система именования адресов в Интернете, которая позволяет создавать удобные для человека буквеные наименования (доменные имена) соответствующие числовым [IP-адресам](https://ru.wikipedia.org/wiki/IP-%D0%B0%D0%B4%D1%80%D0%B5%D1%81), которые используются компьютерами.
> DNS состоит из множества независимых узлов, каждый из которых хранит только те данные, которые входят в его зону ответственности.
- DNS Resolver
> Сервер, который расположен в непосредственной близости от вашего провайдера. Именно он выполняет поиск адресов по доменным именам, а также занимается их кэшированием (временным хранением для быстрой выдачи при последующих обращениях).
Современные [веб-приложения](https://ru.wikipedia.org/wiki/%D0%92%D0%B5%D0%B1-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5) состоят из двух частей: клиентской (frontend) и серверной (backend). Тем самым реализуя [клиент-серверную архитектуру](https://ru.wikipedia.org/wiki/%D0%9A%D0%BB%D0%B8%D0%B5%D0%BD%D1%82_%E2%80%94_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80).
> Как правило в чистом виде эти инструменты используются редко, поскольку для более удобной и быстрой разработки существуют так называемые [фреймворки](https://2020.stateofjs.com/ru-RU/technologies/front-end-frameworks/) и [препроцессоры](https://mrmlnc.gitbooks.io/less-guidebook-for-beginners/content/chapter_1/css-reprocessors.html). <br>
> Здесь может подразумевается широкий спектр задач: работа с базами данных, обработка информации, вычисления и т.д. Это, так сказать, самое сердце мира Backend. Здесь и происходит все самое важное и интересное.
1. 📄 [**Нативные, гибридные и web-приложения в сравнении** – medium.com](https://medium.com/nuances-of-programming/%D0%BD%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5-%D0%B3%D0%B8%D0%B1%D1%80%D0%B8%D0%B4%D0%BD%D1%8B%D0%B5-%D0%B8-web-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B2-%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B8-b1360258df2d)
[Браузер](https://ru.wikipedia.org/wiki/Браузер) – клиент, с помощью которого можно отправлять запросы на сервер для получения файлов, которые впоследствии используются для отрисовки web-страниц. Если совсем упрощенно, то браузер можно воспринимать как программу для просмотра HTML-файлов, которая так же может искать и скачивать их из интернета.
> Работа с запросами, отрисовка страниц, особенность работы вкладок (для каждой вкладки создается отдельный процесс, чтобы не допустить ситуации, при которой содержимое одной вкладки имеет возможность влиять на содержимое другой).
- Расширения ([WebExtensions](https://ru.wikipedia.org/wiki/WebExtensions))
> Незаменимый инструмент любого веб-разработчика. Позволяет анализировать всю возможную информацию связанную с веб-страницами, мониторить их производительность, логи и, что для нас самое важное, отслеживать информацию о сетевых запросах.
4. 📄 [**Важные аспекты работы браузера для разработчиков** – habr.com](https://habr.com/ru/company/dataart/blog/304138/)
5. 📄 [**Обзор всех инструментов разработчика Chrome DevTools** – habr.com](https://habr.com/ru/company/simbirsoft/blog/337116/)
6. 📄 [**Что на самом деле происходит, когда пользователь вбивает в браузер адрес google.com** – habr.com](https://habr.com/ru/company/htmlacademy/blog/254825/)
7. 📄 [**Принципы работы современных веб-браузеров**](https://www.html5rocks.com/ru/tutorials/internals/howbrowserswork/)
8. 📄 [**Подробное объяснение того, как работает браузер (под капотом)**](https://russianblogs.com/article/7580365317/)
Использование VPN и Proxy довольно распространённое явление в последние годы. С помощью этих технологий пользователи могут получить базовую анонимность при серфинге в сети, а также обходить различные региональные блокировки.
> Технология позволяющая стать участником приватной сети (подобной вашей локальной), где запросы всех участников проходят через единый публичный IP-адрес. Это позволяет Вам смешаться в общей массе запросов от других участников.<br>
> - Нет гарантии 100% анонимности, поскольку владелец сети знает IP-адреса всех участников. <br>
> - VPN бесполезны для работы с мультиаккаунтами и некоторыми программами, поскольку все аккаунты, работающие с одного VPN легко обнаруживаются и блокируются. <br>
> - Бесплатные VPN, как правило, имеют большую нагруженность, что приводит к нестабильной работе и снижению скорости загрузки данных. <br>
> Прокси это специальный сервер в сети, который выполняет роль посредника между Вами и конечным сервером к которому Вы намереваетесь обратиться. Когда Вы подключены к прокси-серверу все Ваши запросы будут выполняться от имени этого сервера, то есть IP-адрес и местоположение будут подменены. <br>
1. 📄 [**Чем отличается VPN от прокси и что выбрать?**](https://hidemy.name/ru/articles/chem-otlichaetsja-proksi-i-vpn-chto-vybrat-proksi-server-ili-vpn/)
[Хостинг (hosting)](https://ru.wikipedia.org/wiki/%D0%A5%D0%BE%D1%81%D1%82%D0%B8%D0%BD%D0%B3) - специальная услуга, предоставляемая [хостинг-провайдерами](https://ru.wikipedia.org/wiki/%D0%A5%D0%BE%D1%81%D1%82%D0%B8%D0%BD%D0%B3%D0%BE%D0%B2%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F), которая позволяет арендовать пространство на сервере (который круглосуточно подключён к сети Интернет), где могут храниться ваши данные и файлы. Существуют различные варианты хостинга, где вы можете использовать не только дисковое пространство сервера, но и так же процессорную мощность для работы ваших сетевых приложений.
[OSI (The Open Systems Interconnection model)](https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D1%82%D0%B5%D0%B2%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_OSI) – это набор правил, который описивает то, как должны взамиодействовать друг с другом различные сетевые устройства. Модель разделяется на 7 уровней, каждый из которых отвечает за выполнение определенной функции. Все это нужно для того, чтобы процесс обмена информацией в сети происходил по единому шаблону и все устройства, будь-то умный холодильник и смартфон, могли без проблем понять друг друга.
> На этом уровне происходит кодирование битов (единиц/нулей) в физические сигналы (ток, свет, радиоволны) и их дальнейшая передача проводным ([Ethernet](https://ru.wikipedia.org/wiki/Ethernet)) или беспроводным ([Wi-Fi](https://ru.wikipedia.org/wiki/Wi-Fi)) способом.
> Физические сигналы с первого уровня раскодируются обратно в единицы и нули, исправляются ошибки и дефекты, извлекаются [MAC-адреса](https://ru.wikipedia.org/wiki/MAC-%D0%B0%D0%B4%D1%80%D0%B5%D1%81) отправителя и получателя.
> - [TCP](https://ru.wikipedia.org/wiki/Transmission_Control_Protocol) - обеспечивающий надежную передачу данных. TCP гарантирует доставку данных и сохранение порядка следования сообщений. Это сказывается на скорости передачи. Данный протокол используется там, где потеря информации недопустима, например при отправки почты или загрузке веб-страниц. <br>
> - [UDP](https://ru.wikipedia.org/wiki/UDP) – простой протокол с быстрой передачей данных. Он не использует механизмов для гарантирования доставки и порядка следования данных. Используется, например в онлайн-играх, где частичная потеря пакетов не критична, но скорость передачи данных имеет гораздо более важное значение. Так же, запросы к DNS-серверам происходят через UDP протокол.
> Отвечает за открытие и закрытие связи (сеансов) между двумя устройствами. Гарантирует, что сеанс будет оставаться открытым достаточно долго для передачи всех необходимых данных, а затем быстро закроется, чтобы избежать траты ресурсов.
> Трансляция, шифрование/расшифровка и сжатие данных. Именно здесь данные, которые приходят в виде нулей и единиц преобразуются в нужные форматы (PNG, MP3, PDF и т.д.)
> Уровень работы с приложениями. Разрешает приложениям пользователя иметь доступ к сетевым службам, таким как обработчик запросов к базам данных, доступ к файлам, пересылке электронной почты.
[HTTP (HyperText Transport Protocol)](https://ru.wikipedia.org/wiki/HTTP) - cамый важный протокол интернета. Используется для передачи данных любого формата. Сам по себе протокол работает по простому принципу: запрос –> ответ.
> [GET](https://developer.mozilla.org/ru/docs/Web/HTTP/Methods/GET) - запрос на получение данных <br> [POST](https://developer.mozilla.org/ru/docs/Web/HTTP/Methods/POST) - запрос с передачей данных для создания новой записи <br> [PUT](https://developer.mozilla.org/ru/docs/Web/HTTP/Methods/PUT) - запрос с передачей данных для изменения записи <br> [DELETE](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE) - запрос на удаление записи <br> Другие: [HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD), [CONNECT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT), [OPTIONS](https://developer.mozilla.org/ru/docs/Web/HTTP/Methods/OPTIONS), [TRACE](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/TRACE), [PATCH](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH). <br>
> Каждый ответ от сервера имеет специальный числовой код, который характеризует состояние отправленного запроса. Эти коды делятся на 5 основных классов:
> Поскольку протокол HTTP не позволяет сохранять никакой информации о состояниях предыдущих запросов/ответов, возникает необходимость в использовании cookie. Куки позволяют серверу хранить различную информацию на стороне клиента, которую в последующем клиент может отсылать обратно на сервер. В частности куки могут использоваться для авторизации или для сохранения различных параметров/настроек.
- [HTTP/1.0 vs HTTP/1.1 vs HTTP/2](https://ru.wikipedia.org/wiki/HTTP#%D0%98%D1%81%D1%82%D0%BE%D1%80%D0%B8%D1%8F_%D1%80%D0%B0%D0%B7%D0%B2%D0%B8%D1%82%D0%B8%D1%8F)
> Главным нововведением в вeрсии 1.1 является режим "постоянного соединения", который позволяет посылать несколько запросов за одно подключение. Во второй версии протокол стал бинарным, появилась возможность передачи данных нескольких потоков по одному каналу.
1. 📺 [**Как работает HTTPS?** – YouTube](https://youtu.be/B3j4SS5P8tM)
1. 📺 [**Что такое cookies браузера** – YouTube](https://youtu.be/Ri3IAb6tdlE)
1. 📄 [**Что такое cookie в браузере и почему на многих сайтах предупреждают об их использовании?**](https://club.dns-shop.ru/blog/t-326-internet/47805-chto-takoe-cookie-v-brauzere-i-pochemu-na-mnogih-saitah-preduprejd)
1. 📄 [**CORS для чайников: история возникновения, как устроен и оптимальные методы работы** – habr.com](https://habr.com/ru/company/macloud/blog/553826/)
1. 📄 [**Улучшение сетевой безопасности с помощью Content Security Policy** – habr.com](https://habr.com/ru/company/nix/blog/271575/?)
1. 📄 [**Путь к HTTP/2** – habr.com](https://habr.com/ru/post/308846/)
1. 📄 [**Evolution of HTTP** – MDN (mozilla.org)](https://developer.mozilla.org/ru/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP)
По сравнению с [моделью OSI](#сетевая-модель-osi) [стек TCP/IP](https://ru.wikipedia.org/wiki/TCP/IP) имеет более простую архитектуру. Он получил широкое распространение и использовался сначала в качестве основы для создания глобальной сети, а после для описания работы интернета.
Качество работы сетей, и тем более интернета, далеко от идеала. Это обусловлено сложной и рассредоточенной по разным устройствам структурой сети. Поэтому на функционирование сети влияет огромное количеств факторов. Например: стабильность соединения между устройством клиента и его роутером, качество услуг провайдера, мощность и производительность сервера, физическое расстояние между клиентом и сервером и т.д.
> Не все пакеты, путешествуя по сети, могут добраться до места назначения. Чаще всего такое происходит при использовании беспроводных сетей или из-за [перегрузок сети](https://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B5%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0_%D1%81%D0%B5%D1%82%D0%B8).
- [Round Trip Time (RTT)](https://ru.wikipedia.org/wiki/%D0%9A%D1%80%D1%83%D0%B3%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%B4%D0%B5%D1%80%D0%B6%D0%BA%D0%B0)
1. 📄 [**Лаги, джиттер и потеря пакетов: откуда берутся проблемы с неткодом и как их решать** – habr.com](https://habr.com/ru/company/pixonic/blog/559780/)
1. 📄 [**Внутренние механизмы ТСР, влияющие на скорость загрузки: часть 1** – habr.com](https://habr.com/ru/company/webo/blog/326258/)
1. 📄 [**Внутренние механизмы ТСР, влияющие на скорость загрузки: часть 2** – habr.com](https://habr.com/ru/company/webo/blog/327050/)
> Процедура, позволяющая отследить по каким узлам, с какими IP адресами, передаётся отправленный вами пакет прежде чем он достигнет точки назначения. Трассировка может применяться для выявления связанных с работой компьютерной сети проблем, а также для исследования/анализа сети.
> Самый простой способ проверить сервер на работоспособность.
- [Проверка на потерю пакетов](https://ru.wikihow.com/%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%B8%D1%82%D1%8C-%D0%BF%D0%BE%D1%82%D0%B5%D1%80%D1%8E-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BE%D0%B2-%D0%BD%D0%B0-%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B5)
> Самый важный компонент ПК к которому подключаются все остальные элементы.
> - [Чипсет](https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D0%BF%D1%81%D0%B5%D1%82) - набор микросхем, который отвечает за коммуникацию всех элементов материнской платы.
> - [Сокет](https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D1%80%D0%B0%D0%B7%D1%8A%D1%91%D0%BC%D0%BE%D0%B2_%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%BE%D0%B2) - разъем для установки процессора.
> - [VRM (Voltage Regulator Module)](https://club.dns-shop.ru/blog/t-102-materinskie-platyi/38267-chto-takoe-vrm-materinskoi-platyi) - модуль который преобразовывает поступающие напряжение (как правило 12 В) в более низкое для работы процессора, встроенной графики и оперативной памяти.
> - Слоты для оперативной памяти.
> - Слоты расширения [PCI-Express](https://ru.wikipedia.org/wiki/PCI_Express) - предназначены для подключения видеокарт, внешних сетевых/звуковых карт.
> - Слоты [М.2](https://ru.wikipedia.org/wiki/M.2) / [SATA](https://ru.wikipedia.org/wiki/SATA) - предназначены для подключения жёстких дисков и SSD.
> Важнейшее устройство, которое исполняет инструкции (код программы). Процессоры работают только с 1 и 0, поэтому все программы в конечном виде представляют из себя набор двоичного кода.
> - [Регистры](https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D0%B8%D1%81%D1%82%D1%80_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%B0) - самая быстрая память в ПК, имеет крайне малый объем, встроена в процессор и предназначена для временного хранения обрабатываемых данных.
> - [Кэш (Cache)](https://ru.wikipedia.org/wiki/%D0%9A%D1%8D%D1%88_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%B0) - чуть менее быстрая память, которая так же встроена в процессор и используемая для хранения копии данных из часто используемых ячеек основной памяти.
> - Процессоры могут иметь разные [архитектуры](https://ru.wikipedia.org/wiki/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%B0). В настоящее время наиболее распространена [архитектура х86](https://ru.wikipedia.org/wiki/X86-64) (настольные ПК и ноутбуки) и [ARM](https://ru.wikipedia.org/wiki/ARM_(%D0%B0%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0)) (мобильные девайсы, а также компьютеры фирмы Apple).
> Быстрая память небольшого объема (4-16GB), предназначенная для временного хранения кода программы, а также входных, выходных и промежуточных данных, обрабатываемых процессором.
> Отдельная плата, занимающаяся переводом и обработкой данных в изображения для вывода их на экран монитора. Такое устройство ещё называют дискретной видеокартой. Обычно нужны для тех, кто занимается 3D моделированием или играет в игры. <br>
> [Встроенная видеокарта](https://ru.wikipedia.org/wiki/%D0%92%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80) – это видеокарта встроенная в процессор. Подходит для повседневной работы.
> Устройство, которое обеспечивает приём и передачу данных от других устройств подключённых к [одной сети](https://ru.wikipedia.org/wiki/%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D0%B5%D1%82%D1%8C).
[Операционная система (ОС)](https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0) – это комплексная программная система, которая предназначена для управления ресурсами компьютера. Благодаря операционным системам людям не приходится иметь дело непосредственно с процессором, оперативной памятью или другими составляющими ПК.
То есть, ОС можно представить как слой абстракции, который управляет железом (hardware) компьютера, тем самым предоставляя простую и удобную среду для работы пользовательского софта (software).
> - Управление оперативной памятью (выделение пространства для отдельных программ) <br>
> - Загрузка программ в оперативную память и их выполнение <br>
> - Выполнение запросов поступающих от пользовательских программ (ввод и вывод данных, запуск и остановка других программ, высвобождение памяти или выделение дополнительной...) <br>
> - Взаимодействие с устройствами ввода и вывода (мышь, клавиатура, монитор...) <br>
> - Взаимодействие с носителями информации (жесткие диски, SSD...) <br>
> - Ведение журнала об программных ошибках (сохранение логов)
- Дополнительные функции (могут быть не во всех ОС)
> - Организация [многозадачности](https://ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%BE%D0%B3%D0%BE%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%BD%D0%BE%D1%81%D1%82%D1%8C) (одновременное выполнение нескольких программ) <br>
> Центральная часть ОС, которая используется наиболее интенсивно. Ядро постоянно находится в памяти, в то время как другие части ОС загружаются в память и выгружаются из неё по мере надобности.
> Системный софт, который обеспечивает подготовку окружения для запуска ОС (приводит аппаратуру в нужное состояние, подготавливает память, загружает туда ядро ОС и передает ему (ядру) управление).
1. 📺 [**Что такое операционная система и как она работает** – YouTube](https://www.youtube.com/watch?v=hb9CTGSJm88&t)
1. 📺 [**Плейлист по операционным системам** – YouTube](https://www.youtube.com/playlist?list=PLo6puixMwuSPrKOCsJhrtr-m79mFthit9)
1. 📄 [**Что такое операционная система и как она работает?** – GitHub](https://github.com/Steindvart/My_study/blob/master/docs/source/OS/articles/what_is_os.rst)
1. 📺 [**Что такое ядро операционной системы? Назначение и виды ядер** – YouTube](https://youtu.be/Bdh88Fd--54)
> - [Стек вызовов](https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%BE%D0%B2) (порядок инструкций для выполнения) <br>
> - [Куча](https://ru.wikipedia.org/wiki/%D0%9A%D1%83%D1%87%D0%B0_(%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D1%8C)) (структура для хранения промежуточных данных, создаваемых во время работы процесса) <br>
> Cущность, в которой выполняются последовательности действий (процедуры) программы. Потоки находятся внутри процесса и используют то же адресное пространство. В одном процессе может быть несколько потоков, что обеспечивает возможность выполнения нескольких задач. Эти задачи, благодаря потокам, могут обмениваться данными, использовать общие данные или результаты других задач.
> Способность выполнять несколько задач одновременно используя несколько ядер процессора, где на каждом отдельном ядре выполняется отдельно взятая задача.
> Способность выполнять несколько задач, но используя одно ядро процессора. Это достигается путем разделения задач на отдельные блоки команд, которые выполняются по очереди, но переключение между этими блоками происходит настолько быстро, что для пользователей создается впечатление, будто эти процессы выполняются одновременно.
1. 📺 [**Чем отличаются Concurrency и Parallelism** – YouTube](https://youtu.be/4PNneed92lM)
1. 📄 [**Отличие между конкурентностью, параллелизмом и многопоточностью** – GitHub](https://github.com/gm-soft/knowledge-base/blob/master/dot-net/2019-11-06-asynchronous-programming-epm-theory.md)
1. 📄 [**Parallelism vs Concurrency: правильно подбираем инструменты** – habr.com](https://habr.com/ru/company/piter/blog/274569/)
1. 📄 [**Параллелизм против многопоточности против асинхронного программирования: разъяснение** – habr.com](https://habr.com/ru/post/337528/)
Механизм позволяющий организовать обмен данными между потоками одного или разных процессов. Причем, процессы могут быть запущены как на одном и том же компьютере, так и на разных, соединенных сетью. [Межпроцессорные взаимодействия](https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B6%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BD%D0%BE%D0%B5_%D0%B2%D0%B7%D0%B0%D0%B8%D0%BC%D0%BE%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D0%B5) бывают разных типов.
> Самый простой способ организовать обмен данными. Один процесс записывает данные в определенный файл, другой процесс читает этот же файл и тем самым получает данные от первого процесса.
> В частности для взаимодействия между компьютерами с помощью стека протоколов TCP/IP используются IP-адреса и порты. Эта пара определяет сокет («гнездо», соответствующее адресу и порту).
- [Сообщения](https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D0%BC%D0%B5%D0%BD_%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8) и [очереди сообщений](https://ru.wikipedia.org/wiki/%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B9)
Операционные системы на базе [ядра Linux](https://ru.wikipedia.org/wiki/%D0%AF%D0%B4%D1%80%D0%BE_Linux) это стандарт в мире серверной разработки, поскольку большинство серверов работают именно на таких ОС. Использовать Linux на серверах выгодно, ведь он распространяется бесплатно.
Существует огромное количество дистрибутивов (сборок с набором предустановленного ПО) Linux на любой вкус и цвет. Одним из самых популярных является [Ubuntu](https://ru.wikipedia.org/wiki/Ubuntu). Именно с него можно начать своё погружение в серверную разработку.
[Установить Ubuntu](https://ubuntu.com/download/desktop) можно на отдельный ПК или ноутбук. Если такой возможности нет, можно воспользоваться специальной программой [Virtual Box](https://www.virtualbox.org/wiki/Downloads), в которой можно [запускать другие ОС](https://lumpics.ru/how-install-ubuntu-on-virtualbox-virtual-machine/) поверх основной. Так же можно запустить [Docker](https://www.docker.com/products/docker-desktop) [контейнер с образом Ubuntu](https://losst.ru/zapusk-kontejnera-docker) (Docker - это [отдельная тема](#docker), которая рассматривается в этом репозитории).
[Терминал (или консоль)](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81_%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BD%D0%BE%D0%B9_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8) - программа, в которой для управления компьютером используются специальные текстовые команды. Как правило, на серверах отсутствуют графические оболочки, поэтому вам обязательно понадобятся навыки работы с терминалом.
Linux дистрибутивы можно разделить на несколько групп, в зависимости от того, какой в них используется менеджер пакетов: [apt](https://ru.wikipedia.org/wiki/Advanced_Packaging_Tool) (в дистрибутивах на основе [Debian](https://ru.wikipedia.org/wiki/Debian)), [RPM](https://ru.wikipedia.org/wiki/RPM) (система управления пакетами [Red Hat](https://ru.wikipedia.org/wiki/Red_Hat)) и [Pacman](https://ru.wikipedia.org/wiki/Pacman_(%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%B0%D0%BC%D0%B8)) (менеджер пакетов в [Arch-подобных дистрибутивах](https://ru.wikipedia.org/wiki/Arch_Linux))
С помощью скриптов (сценариев) можно автоматизировать последовательный ввод любого количества команд. В [Bash](https://ru.wikipedia.org/wiki/Bash#%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%8B) можно создавать различные условия (разветвления), циклы, таймеры и т.д. для выполнения всевозможных действий связанных с вводом в консоль.
> Самые базовые и часто используемые возможности такие как: переменные, ввод/вывод, циклы, условия и т.д.
- Практика
> Решайте задания на таких сайтах как [HackerRank](https://www.hackerrank.com/domains/shell) и [Codewars](https://www.codewars.com/join?language=shell). <br>
> Начните использовать Bash для автоматизации рутинных действий на своем компьютере. Если вы уже занимаетесь программированием, создавайте скрипты для удобной сборки вашего проекта, для установки настроек и так далее.
- [ShellCheck](https://github.com/koalaman/shellcheck) инструмент для анализа скриптов
> Укажет Вам на возможные ошибки и научит лучшим практикам написания действительно качественных скриптов.
> В таких репозиториях, как [awesome bash](https://github.com/awesome-lists/awesome-bash) и [awesome shell](https://github.com/alebcay/awesome-shell) собраны целые коллекции полезных ресурсов и инструментов, которые помогут развить ещё больше навыков работы с Bash и терминалом в общем.
ОС на базе Linux являются многопользовательскими. Это означает, что несколько людей могут запускать множество различных приложений одновременно на одном и том же компьютере. Чтобы система Linux смогла «узнать» пользователя, он должен войти в систему, соответственно каждый пользователь должен иметь уникальное имя и секретный пароль.
В Linux можно разделять привилегии между пользователями, ограничить доступ к нежелательным файлам или возможностям, контролировать доступные действия для сервисов и многое другое. В Linux существует всего три вида прав - право на чтение, запись и выполнение, а также три категории пользователей, к которым они могут применяться - владелец файла, группа файла и все остальные.
- Расширенные права [SUID](https://ru.wikipedia.org/wiki/Suid), [GUID](https://ru.wikipedia.org/wiki/Suid) и [sticky bit](https://ru.wikipedia.org/wiki/Sticky_bit)
- [ACL (Access control list)](https://help.ubuntu.ru/wiki/access_control_list)
> Продвинутая подсистема для управления правами доступа.
Процессы в Linux можно описать как контейнеры, в которых хранится вся информация о состоянии выполняемой программы. Если программа зависла и нужно восстановить её работу, тогда Вам понадобиться навыки работы по управлению процессами.
[Служба SSH](https://ru.wikipedia.org/wiki/SSH) позволяет получить удаленный доступ к терминалу другого компьютера. В случае с персональным компьютером, это может понадобиться для срочного решения какой-либо проблемы, а в случае работы с сервером это вообще является основным методом подключения.
Благодаря планировщикам можно гибко управлять отложенным запуском команд и скриптов. В Linux есть встроенный планировщик [cron](https://ru.wikipedia.org/wiki/Cron), с помощью которого можно легко выполнять необходимые действия через определенные интервалы времени.
1. 📄 [**Использование Cron для автоматизации задач** – Digital Ocean](https://www.digitalocean.com/community/tutorials/how-to-use-cron-to-automate-tasks-ubuntu-1804-ru)
[Файлы журнала (логи)](https://ru.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B9%D0%BB_%D0%B6%D1%83%D1%80%D0%BD%D0%B0%D0%BB%D0%B0) - cпециальные текстовые файлы, в которые заносится вся информация о работе компьютера, программы или пользователя. Они особенно полезны при возникновении багов и ошибок в работе программы или сервера. Рекомендуется периодически просматривать логи, даже если ничего подозрительного не происходит.
> Все свободные драйвера Linux встроены прямо в его ядро. Поэтому после установки системы все должно работать "прямо из коробки" (проблемы могут быть с совсем новым оборудованием, которое только вышло в продажу). Драйвера, исходный код, которых закрыт, считаются проприетарными и не включаются в ядро, а доустанавливаются вручную (например как у Nvidia).
[Система счисления (СС)](https://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F) представляет собой совокупность символов и правил для обозначения чисел. В информатике принято выделять четыре основных системы счисления: двоичная, восьмеричная, десятичная, шестнадцатеричная. Связано это, в первую очередь, с их использованием в различных отраслях программирования.
> Самая важная СС для вычислительной техники. Её использование обосновано тем, что логика работы процессора построена на основе всего двух состояний (включено/выключено, открыто/закрыто, высокий/низкий, истина/ложь, да/нет, больше/меньше).
> Для записи используются дополнительно буквы: A, B, C, D, E, F. Широко используется в низкоуровневом программировании и компьютерной документации из-за, того что минимальной адресуемой единицей памяти является 8-битный байт, значения которого удобно записывать двумя шестнадцатеричными цифрами.
[Логические операции](https://ru.wikipedia.org/wiki/%D0%9B%D0%BE%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F) широко используются в программировании для проверки различных условий. Результатом логического выражения всегда является _истина_ или _ложь_.
[Структуры данных (СД)](https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85) – это контейнеры в которых данные хранятся по определенным правилам. В зависимости от этих правил структура данных будет эффективна в одних задачах и неэффективна в других. Поэтому необходимо понимать, когда и где использовать ту или иную структуру.
> - Кольцевой список – разновидность двусвязного списка, где последний элемент кольцевого списка содержит указатель на первый, а первый — на последний.
> По другому ассоциативный массив. Здесь для обращения к каждому из элементов используется соответствующее ключевое значение, которое вычисляется с помощью [хеш-функции](https://ru.wikipedia.org/wiki/%D0%A5%D0%B5%D1%88-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F) по определенному алгоритму.
[Алгоритмы](https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC) подразумевают под собой наборы последовательных инструкций (шагов), которые приводят к решению поставленной задачи. За всю человеческую историю было придумано огромное количество алгоритмов, которые позволяют решать определенные задачи максимально эффективным способом. Соответственно правильный выбор алгоритмов в программировании позволит создавать максимально быстрые и ресурсоемкие решения.
> Существует очень хорошая книжка по алгоритмам – [Грокаем алгоритмы](https://github.com/mduisenov/GrokkingAlgorithms). С ней можно параллельно начать [изучение языка программирования](#язык-программирования).
> Когда функция может вызывать сама себя и так до бесконечности. С одной стороны решения на основе рекурсии выглядят очень элегантно, ас другой стороны такой подход очень быстро приводит к переполнению стека и его рекомендуют избегать.
1. 📺 [**Алгоритмы и структуры данных. Подготовительный курс (плейлист)** – YouTube](https://youtube.com/playlist?list=PLrCZzMib1e9pDxHYzmEzMmnMMUK-dz0_7)
В мире программирования существует специальная единица измерения **Big О** (Большое О или О-нотация). Она описывает то, как сложность алгоритма растёт с увеличением количества входных данных. **Big O** оценивает то, сколько действий (шагов/итераций) необходимо совершить для выполнения алгоритма, при этом всегда показывая худший вариант развития событий.
Для хранения и передачи данных по сети могут использоваться файлы разных форматов. Текстовые файлы удобны для чтения человеку, поэтому они используются, например, для файлов конфигурации. Но передавать данные в текстовых форматах по сети не всегда рационально, поскольку они весят больше, чем соответствующие им бинарные файлы.
1. 📄 [**Краткое руководство по XML**](https://xml.readthedocs.io/xml-intro.html)
1. 📄 [**YAML за 5 минут: синтаксис и основные возможности** – tproger.ru](https://tproger.ru/translations/yaml-za-5-minut-sintaksis-i-osnovnye-vozmozhnosti/)
1. 📄 [**Universal Binary JSON — ещё один бинарный JSON** – habr.com](https://habr.com/ru/post/130112/)
Компьютеры работают только с числами, а если точнее только с 0 и 1. Как преобразовывать числа из разных систем счисления в двоичную, уже понятно. Нос текстом производить такие преобразования не получится. Именно поэтому были придуманы специальные таблицы, называемые [кодировками](https://ru.wikipedia.org/wiki/%D0%9D%D0%B0%D0%B1%D0%BE%D1%80_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2), в которых текстовым символам присваиваются числовые эквиваленты.
- [ASCII (American standard code for information interchange)](https://ru.wikipedia.org/wiki/ASCII)
> Это международная таблица символов, которая помимо английского алфавита, содержит алфавиты почти всех стран. Способна вместить в себя более миллиона различных символов (на данный момент таблица заполнена не полностью).
> Unicode-кодировка переменной длинны, с помощью которой можно представить любой символ unicode.
- [UTF-16](https://ru.wikipedia.org/wiki/UTF-16)
> Главное ее отличие от UTF-8 состоит в том что структурной единицей в ней является не один а два байта. То есть в кодировке UTF-16 любой символ юникода может быть закодирован либо двумя, либо четырьмя байтами.
На этом этапе Вам предстоит выбрать для изучения один из языков программирования. В открытом доступе полно информации по различным языкам, (книги, курсы, тематические сайты и т.д.) поэтому уВас не должно возникнуть проблем.
> Ниже приведен список конкретных языков, которые [лично по моему мнению](https://github.com/cheatsnake) хорошо подходят для backend-разработки (⚠️ может не совпадать с мнением других людей, в том числе более компетентных в этом вопросе).
> Не менее популярный и практический единственный язык для полноценной Web-разработки. Благодаря платформе [Node.js](https://nodejs.org) последнее несколько лет набирает популярность и в области backend-разработки.
- [Go](https://ru.wikipedia.org/wiki/Go)
> Язык созданный внутри компании Google. Создавался специально для высоконагруженной серверной разработки. Минималистичный синтаксис, высокая производительность и богатая стандартная библиотека.
> Этакая современная версия [Java](https://ru.wikipedia.org/wiki/Java). Более простой и лаконичный синтаксис, лучшая типобезопасность, наличие встроенных инструментов для многопоточности. Один из лучших выборов для разработки под Android.
Найти хорошую книгу или онлайн-учебник на русском можно в [этом репозитории](https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-ru.md). Там собрана большая коллекция под разные ЯП и фреймворки.
Поищите специальный [awesome-репозиторий](https://github.com/sindresorhus/awesome#programming-languages) –ресурс в котором собрано огромное количество полезных ссылок на материалы под Ваш ЯП (библиотеки, шпаргалки, блоги и другие различные ресурсы).
Языков программирования много. Все они созданы не просто так. Некоторые языки могут быть совсем специфическими и использоваться только для определенных целей. Также, разные языки могут использовать разные подходы к написанию программ. А могут вообще по разному исполняться на компьютере. В общем существует множество различных [классификаций](https://ru.wikipedia.org/wiki/%D0%AF%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#%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F), в которых было бы полезно разобраться.
- [В зависимости от уровня языка](https://ru.wikipedia.org/wiki/%D0%AF%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#%D0%AF%D0%B7%D1%8B%D0%BA%D0%B8_%D0%BD%D0%B8%D0%B7%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B8_%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%BE%D0%B3%D0%BE_%D1%83%D1%80%D0%BE%D0%B2%D0%BD%D1%8F)
> Максимально близкие к машинному коду, сложные в написании, но максимально производительные. Как правило предоставляют доступ ко всем ресурсам компьютера.
> Имеют достаточно большой уровень абстракции, за счет чего достигается простота и удобство написания. Как правило безопаснее, поскольку не предоставляют доступ ко всем ресурсам компьютера.
- [В зависимости от парадигмы программирования](https://ru.wikipedia.org/wiki/%D0%AF%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#%D0%9F%D0%B0%D1%80%D0%B0%D0%B4%D0%B8%D0%B3%D0%BC%D0%B0_%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)
После освоения минимальной базы для написания простейших программ нет особого смысла продолжать изучение без наличия конкретных целей (без практики все забудется). Вам необходимо придумать/найти что-то, что вы хотели бы создать самостоятельно (игра, чат-бот, сайт, мобильное/десктопное приложение, что угодно). Для вдохновения посмотрите эти репозитории: [Build your own x](https://github.com/codecrafters-io/build-your-own-x) и [Project based learning](https://github.com/practical-tutorials/project-based-learning).
На этом моменте начинается самая продуктивная часть обучения: Вы просто ищите всевозможную информацию для реализации вашего проекта. Вашими лучшими друзьями становиться Google, YouTube и Stack Overflow.
> Поднятие HTML-страничек; хостинг картинок, PDF-файлов и т.д.
- Маршрутизация
> Создание эндпоинтов (URL-адресов) при обращении к которым на сервере будет вызывается соответствующий обработчик.
- Обработка запросов
> Как правило в HTTP-обработчиках имеется специальный объект в который приходит вся информация о запросе пользователя (заголовки, метод, тело-запроса, полный url с параметрами и т.д.)
- Обработка ответов
> Отправка соответствующего сообщения на поступивший запрос (HTTP-статус и код, тело-ответа, заголовки и т.д.)
- Обработка ошибок
> Всегда нужно предусматривать варианты когда пользователь может отправить некорректные данные, база данных не выполнила операцию или просто в приложении произошла непредвиденная ошибка, чтобы сервер не падал, а отвечал ответом с информацией об ошибке.
- Отправка запросов
> Часто внутри одного приложения вам придется обращаться по сети к другому. Поэтому важно уметь отправлять HTTP-запросы используя встроенные возможности ЯП.
Сегодня компьютеры имеют процессоры с несколькими физическими и виртуальными ядрами, а если взять в расчет серверные машины, то там их количество может доходить до сотен. Все эти имеющиеся ресурсы хорошо бы задействовать по полной, для максимальной производительности приложения. Поэтому современная серверная разработка не обходится без реализации [многопоточности](https://ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%BE%D0%B3%D0%BE%D0%BF%D0%BE%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D1%8C) и [распараллеливания](https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D0%BF%D0%B0%D1%80%D0%B0%D0%BB%D0%BB%D0%B5%D0%BB%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC).
- [Race conditions и data races](https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%B3%D0%BE%D0%BD%D0%BA%D0%B8)
> Основные проблемы которые возникают при использовании многопоточности.
> Легковесные потоки исполнения кода, которые организуются поверх аппаратных (системных) потоков. Могут существовать как отдельные библиотеки или быть уже встроенными в ЯП.
> Процесс благодаря которому сильно популяризировались языки высокого уровня – позволяет программисту не заботится о выделении и очистке памяти. Обязательно ознакомьтесь с тонкостями его работы в своем ЯП.
За эти долгие годы, что существует программирование было написано огромное количество кода, программ и целых систем. Ну и как следствие, при разработке всего этого возникали разного рода проблемы. В первую очередь они были связаны с масштабированием, поддержкой, а также порогом входа для новых разработчиков. Умные люди, естественно, не сидели на месте и начали решать эти проблемы, тем самым создавая так называемые паттерны/принципы/подходы для написания качественного кода.
Изучив лучшие практики программирования, вы не только сделаете лучше для себя, но и для других, поскольку с вашим кодом будут работать другие разработчики.
[База данных (БД)](https://ru.wikipedia.org/wiki/%D0%91%D0%B0%D0%B7%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85) – набор данных, которые организованы по определённым правилам. Например, библиотека является базой данных для книг.
[Система управления базой данных (СУБД)](https://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B1%D0%B0%D0%B7%D0%B0%D0%BC%D0%B8_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85) – программное обеспечение, которое позволяет создать БД и удобно ей манипулировать (выполнять различные операции над данными). Примером СУБД может являться библиотекарь. Он может легко и эффективно работать с книгами в библиотеке: выдавать запрашиваемые книги, принимать их обратно, добавлять новые и т.д.
БД могут существенно отличаться друг от друга и соответственно иметь разные области применения. Для понимания какая БД подойдёт для той или иной задачи, необходимо разобраться с классификацией.
> Представляют из себя хранилища, где данные организованны в виде набора таблиц (со строками и столбцами). Взаимодействия между данными организуются на основе связей между этими таблицами. БД такого типа обеспечивает быстрый и эффективный доступ к структурированной информации.
> Здесь данные представляются в виде объектов с набором атрибутов и методов. Подходят для тех случаев, когда требуется высокопроизводительная обработка данных, имеющих сложную структуру.
> Состоят из нескольких частей, расположенных на разных компьютерах (серверах). Такие БД могут полностью исключать дублирование информации, либо полностью её дублировать в каждой распределенной копии (например, как [блокчейн](https://ru.wikipedia.org/wiki/%D0%91%D0%BB%D0%BE%D0%BA%D1%87%D0%B5%D0%B9%D0%BD))
> - [Семейство столбцов](https://ru.wikipedia.org/wiki/NoSQL#%D0%A1%D0%B5%D0%BC%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%BE_%D1%81%D1%82%D0%BE%D0%BB%D0%B1%D1%86%D0%BE%D0%B2) (строки и столбцы используются как ключи) <br>
> - [Документо-ориентированные](https://ru.wikipedia.org/wiki/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F_%D0%A1%D0%A3%D0%91%D0%94) (хранят данные в виде иерархии документов) <br>
> - [Графовые](https://ru.wikipedia.org/wiki/%D0%93%D1%80%D0%B0%D1%84%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B1%D0%B0%D0%B7%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85) (применяются для данных с большим количеством связей) <br>
[SQL (Structured Query Language)](https://ru.wikipedia.org/wiki/SQL) – специальный язык для работы с реляционными базами данных. Он довольно простой и интуитивно понятный.
> Удобная документация по SQL на русском языке [здесь](https://postgrespro.ru/docs/postgresql/14/sql).
> Для этого необходимо установить специальный драйвер под ваш ЯП. Для более удобной работы существуют ORM-библиотеки, которые позволяют выполнять SQL-запросы, как если бы вы просто вызывали методы у объекта.
- [Оптимизация и производительность](https://postgrespro.ru/docs/postgresql/14/performance-tips)
[MongoDB](https://ru.wikipedia.org/wiki/MongoDB) – документо-ориентированная БД (является классическим примером [NoSQL](https://ru.wikipedia.org/wiki/NoSQL) баз данных), не требующая описания схемы таблиц. Использует JSON-подобные документы и схему БД.
1. 📄 [**Руководство по MongoDB** – metanit.com](https://metanit.com/nosql/mongodb/)
1. 📄 [**Большой курс по MongoDB: Агрегация** – medium.com](https://merrick-krg.medium.com/%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%BE%D0%B9-%D0%BA%D1%83%D1%80%D1%81-%D0%BF%D0%BE-mongodb-cab518a8f2fe)
1. 📄 [**Большой курс по MongoDB: Индексация** – medium.com](https://merrick-krg.medium.com/%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%BE%D0%B9-%D1%82%D1%83%D1%82%D0%BE%D1%80%D0%B8%D0%B0%D0%BB-%D0%BF%D0%BE-mongodb-c0ab21a16d71)
1. 📘 [**MongoDB полное руководство** – Ш. Брэдшоу, 2020](https://www.rulit.me/data/programs/resources/pdf/MongoDB-polnoe-rukovodstvo_RuLit_Me_643188.pdf)
[Redis](https://redis.io/) – быстрое хранилище данных работающее со структурами типа _ключ-значение_. Может использоваться в качестве базы данных, кэша, брокера сообщений или очереди.
- Типы данных
> Строки / Списки / Множества (sets) / Хэш-таблицы (hashes) / Упорядоченные множества (sorted sets)
- Базовые операции
```bash
SET key "value" # установка ключа key со значение "value"
GET key # получить значение по указанному ключу
SETNX key "data" # создание ключа и установщика значения, если ключ еще не существует
MSET key1 "1" key2 "2" key3 "3" # установка нескольких ключей
MGET key1 key2 key3 # получение значений сразу по нескольким ключам
DEL key # удалить пару ключ-значение
INCR someNumber # увеличение числового значения по ключу на 1
DECR someNumber # уменьшение числового значения по ключу на 1
EXPIRE key 1000 # установить таймер жизни ключа 1000 секунд
TTL key # получить информацию о времени жизни пары ключ-значение
# -1 ключ существует, но не имеет срока действия
# -2 ключ не существует
# <другоечисло> время жизни ключа в секундах
SETEX key 1000 "value" # объединение команды SET и EXPIRE
```
- Транзакции
> `MULTI` — начать запись команд для транзакции. <br>
> `EXEC` — выполнить записанные команды. <br>
> `DISCARD` — удалить все записанные команды. <br>
> `WATCH` — команда, обеспечивающая выполнение только в случае, если другие клиенты не изменили значение переменной. Иначе EXEC не выполнит записанные команды.
<details>
<summary>🔗 <b>Ссылки на материалы</b></summary>
1. 📄 [**Что такое Redis** – Amazon](https://aws.amazon.com/ru/redis/)
1. 📺 [**Redis - основы и практическое использование** – YouTube](https://youtu.be/AimUYjKs3pQ)
1. 📄 [**Структуры данных, используемые в Redis** – harb.com](https://habr.com/ru/post/144054/)
1. 📺 [**Базы данных. NoSQL. Redis** – YouTube](https://youtu.be/cSghexeHlDI)
1. 📺 [**HighLoad: Успехи и провалы с Redis** – YouTube](https://youtu.be/JBIm4sglyQU)
1. 📄 [**Опыт использования Redis в качестве главного хранилища** – habr.com](https://habr.com/ru/post/178525/)
[ACID](https://ru.wikipedia.org/wiki/ACID) – это аббревиатура состоящая из названий четырёх основных свойств, которые гарантируют надежность транзакций в БД.
[Проектирование баз данных](https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B0%D0%B7_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85) очень важная тема, которая часто упускается из виду. Грамотно спроектированная БД обеспечит долговременную масштабируемость и простоту обслуживания данных. Можно выделить несколько основных этапов при проектировании:
- Концептуальная схема
> Наиболее абстрактное видение всей системы – описание основных сущностей (таблиц) и связей между ними без ориентации на конкретную СУБД.
- Логическая схема
> Работа с моделями данных будущей БД, обозначение необходимых полей с указанием типов, определение отношений и связей с указанием первичных и внешних ключей.
- Физическая реализация
> Это уже непосредственная работа с СУБД, организация конкретных таблиц, реализация связей, создание индексов и так далее.
[API (Application Programming Interface)](https://ru.wikipedia.org/wiki/API) – программный интерфейс, который описывает определенный набор правил, по которым различные программы (приложения, боты, сайты...) могут взаимодействовать друг с другом. С помощью вызовов API можно выполнить определённые функции программы не зная, как она работает.
[REST (Representational State Transfer)](https://ru.wikipedia.org/wiki/REST) – архитектурный подход, который описывает набор правил того, как программисту организовать написание кода серверного приложения, чтобы все системы легко обменивались данными и приложение можно было легко масштабировать. При построении REST API широко используются методы HTTP-протокола.
> Для выполнения разных операций (получение/создание/изменение/удаление) этот эндпоинт должен реализовывать обработчики на соответствующие HTTP-методы (GET/POST/PUT/DELETE).
[GraphQL](https://graphql.org/) – это язык запросов, который описывает как запрашивать данные, и, в основном, используется клиентом для загрузки данных с сервера. Имеет три основных особенности:
- Позволяет клиенту точно указать, какие данные ему нужны, тем самым уменьшая потребление трафика от ненужных данных.
- Облегчает агрегацию данных из нескольких источников.
[Веб-сокеты](https://ru.wikipedia.org/wiki/WebSocket) это продвинутая технология, позволяющая открыть постоянное двунаправленное сетевое соединение между клиентом и сервером. С помощью его API вы можете отправить сообщение на сервер и получить ответ без выполнения HTTP-запроса, тем самым реализуя real-time взаимодействие.
Основная идея в том, что вам ненужно посылать запросы на сервер для получения новой информации. Когда соединение установлено, сервер сам будет отправлять новую порцию данных подключенным клиентам, как только эти данные появятся. Веб-сокеты широко используются для создания чатов, онлайн-игр, трейдерских приложений и т.д.
[RPC (remote procedure call)](https://ru.wikipedia.org/wiki/%D0%A3%D0%B4%D0%B0%D0%BB%D1%91%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D0%B4%D1%83%D1%80) – технология удаленного вызова процедур. Фактически, это просто вызов функции на сервере с набором определенных аргументов, который ответом отдает результат вызова этой функции.
Основные RPC-протоколы:
- [SOAP](https://ru.wikipedia.org/wiki/SOAP)
> Протокол работающий с использованием языка XML. Разработан в 1998 году. Из-за сложности XML и большого потребления трафика не рекомендуется к использованию.
1. 📺 [**Что такое gRPC за 10 минут** – YouTube](https://youtu.be/bfdF4AJELDc)
1. 📄 [**RPC и REST — в чём разница? Часть 1: RPC** – habr.com](https://youtu.be/vmGdIkn0CK8)
1. 📄 [**Введение в основы RPC: принципы и простые примеры**](https://russianblogs.com/article/9856396913/)
1. 📄 [**Сравнение архитектурных стилей API: SOAP vs REST vs GraphQL vs RPC** – medium.com](https://medium.com/nuances-of-programming/%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B0%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%BD%D1%8B%D1%85-%D1%81%D1%82%D0%B8%D0%BB%D0%B5%D0%B9-api-soap-vs-rest-vs-graphql-vs-rpc-68855deb3f4)
[WebRTC](https://ru.wikipedia.org/wiki/WebRTC) – open-source проект для организации передачи потоковых данных (видео, звука) в браузере. Работа WebRTC основана на [peer to peer соединении](https://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D0%BD%D0%BE%D1%80%D0%B0%D0%BD%D0%B3%D0%BE%D0%B2%D0%B0%D1%8F_%D1%81%D0%B5%D1%82%D1%8C), однако существуют реализации позволяющие организовывать сложные групповые сеансы. Например, сервис видео-звонков Google Meet широко использует WebRTC.
[Git](https://ru.wikipedia.org/wiki/Git) - специальная система для управления историей изменения исходного кода. Любые изменения которые вносятся в Git могут быть сохранены, что позволяет откатываться (возвращаться) на ранее сохраненную копию проекта. На данный момент Git является стандартом для разработки.
[Docker](https://ru.wikipedia.org/wiki/Docker) - специальная программа, которая позволяет запускать изолированные песочницы (контейнеры) с различным предустановленным окружением (будь то определенная операционная система, база данных и т.д.). Технология [контейнеризации](https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F), которую предоставляет Docker, схожа с виртуальными машинами, но в отличие от виртуальных машин, контейнеры используют ядро хостовой ОС, что требует гораздо меньших ресурсов.
> Специальный фиксированный шаблон, в котором содержится описание среды для запуска приложения (ОС, исходный код, библиотеки, переменные окружения, файлы конфигурации и т.д.). Образы можно скачивать с [официального сайта](https://hub.docker.com/search?type=image) и на их основе создавать свои.
- Контейнер (container)
> Изолированная среда, созданная на основе какого-либо образа. По сути это является запущенным процессом на компьютере, который внутри содержит то окружение, которое описано в образе.
- Основные команды
```bash
docker pull [имя_образа] # Загрузить образ из сети
docker images # Список доступных образов
docker run [id_образа] # Запуск контейнера на основе выбранного образа
RUN [команда] # Команда которая запускается только при инициализации образа
CMD ["команда"] # Команда которая отрабатывает каждый раз при запуске контейнера
ENV КЛЮЧ="ЗНАЧЕНИЕ" # Установка переменных окружения
ARG ИМЯ=ЗНАЧЕНИЕ # Задание переменных для передачи Docker во время сборки образа
ENTRYPOINT ["команда"] # Команда которая запускается во время работы контейнера
EXPOSE порт/протокол # Указывает на необходимость открыть порт
VOLUME ["путь"] # Создаёт точку монтирования для работы с постоянным хранилищем
```
- Docker-compose
> Специальный инструмент позволяющий одновременно запускать несколько контейнеров с разной инфраструктурой. В каком-то смысле это Dockerfile на максималках.
При создании серверной части приложения, возникает необходимость в тестировании его работоспособности. Это можно сделать разными способами. Один из самых простых – это воспользоваться консольной утилитой [curl](https://ru.wikipedia.org/wiki/CURL). Но такой способ годится если ваше приложение не большое и имеет всего несколько эндпоинтов. Намного эффективнее использовать специальное ПО для тестирования, которое имеют удобный интерфейс и весь необходимый функционал для автоматизации.
- [Postman](https://www.postman.com/)
> Очень популярная и многофункциональная программа. Здесь точно есть всё, что Вам может пригодиться и даже больше: начиная от банального создания коллекций до поднятия mock-серверов. Основной функционал приложения предоставляется бесплатно.
- [Insomnia](https://insomnia.rest/)
> Не такой популярный, но очень приятный инструмент. Интерфейс в Insomnia, минималистичный и понятный. Здесь поменьше функционала, но все самое необходимое есть: коллекции, переменные, автоматические тесты и т.д. Имеется возможность установки сторонних плагинов.
Главной задачей любого [веб-сервера](https://ru.wikipedia.org/wiki/%D0%92%D0%B5%D0%B1-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80) является обработка клиентских запросов и отправка ответов по протоколу HTTP (HTTPS). Помимо этого веб-сервера могут вести журналы ошибок (логи), производить аунтефикацию и авторизацию, хранить правила на обработку файлов и т.д.
При создании масштабной backend-системы может возникать проблема коммуникации между большим количеством микросервисов. Чтобы не усложнять уже имеющиеся сервисы (налаживать надёжную систему коммуникации, распределять нагрузку, предусматривать различные ошибки и т.д.) можно использовать отдельный сервис, который называется [брокером сообщений (очередью сообщений)](https://ru.wikipedia.org/wiki/%D0%91%D1%80%D0%BE%D0%BA%D0%B5%D1%80_%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B9).
Брокер берет на себя ответственность создания надежной и отказоустойчивой системы коммуникации между сервисами (выполняет балансировку, гарантирует доставки, мониторит получателей, ведёт логи, буферизацию и т.д.)
> Атака может быть возможна если, пользовательский ввод, который передаётся в SQL-запрос, способен изменить смысл оператора или добавить туда другой запрос.
> Когда на сайте для выполнения какой-либо операции используется POST-запрос, злоумышленник может подделать форму, например в электронном письме и отправить его жертве. Затем жертва, являющаяся авторизованным пользователем, взаимодействую с этим письмом, не зная того, может отправить запрос на сайт с данными, которые задал злоумышленник.
> Принцип основан на том, что поверх видимой веб-страницы располагается невидимый слой, в который и загружается нужная злоумышленнику страница, при этом элемент управления (кнопка, ссылка), необходимый для осуществления требуемого действия, совмещается с видимой ссылкой или кнопкой, нажатие на которую ожидается от пользователя.
- [DoS-атака (Denial of Service)](https://ru.wikipedia.org/wiki/DoS-%D0%B0%D1%82%D0%B0%D0%BA%D0%B0)
> Использование параметров конфигурации по умолчанию может быть опасным, поскольку это общеизвестная информация. К примеру, частой уязвимостью является то, что сетевые администраторы оставляют стандартные логины и пароли _admin:admin_.
Часто в ваших приложениях могут использоваться различные токены (например для доступа к стороннему платному API), логины и пароли (для подключения к базе данных), различные секретные ключи для подписей и так далее. Все эти данные не должны быть известны и доступны посторонним людям, соответственно оставлять их в коде программы ни в коем случае нельзя. Для решения этой проблемы существуют переменные окружения.
> Специальный файл в котором можно хранить все переменные окружения.
- Парсинг `.env` файла
> Переменные передаются в программу с помощью аргументов командной строки. Чтобы сделать подобоное с `.env` файлом необходимо воспользоваться специальной библитекой под ваш ЯП.
- Хранение и передача
> Изучите как загружать `.env` файлы на хостинг сервисы, а так же помните, что такие файлы нельзя коммитить в удаленные репозитории, поэтому не забывайте добавлять их в исключения через файл `.gitignore`.
Для обеспечения безопасности в сети широко используется криптографические алгоритмы на основе [хеш-функций](https://ru.wikipedia.org/wiki/%D0%A5%D0%B5%D1%88-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F).
> Процесс преобразования массива информации (от одной буквы и хоть до целого литературного произведения) в некую уникальную короткую строку символов (называемую хэшем), которая присуща только этому массиву информации. Причем если в этом массиве информации изменить хоть один символ, то новый хэш будет отличатся кардинально. <br>
> Хеширование является необратимым процессом, то есть по полученному хэшу невозможно восстановить изначальные данные.
> Cлучаи когда хеширование разного набора информации приводит к одинаковым хэшам.
- [Соль (в криптографии)](https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%BB%D1%8C_(%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%8F))
> Случайная строка данных, которая добавляется к входным данным перед хешированием, для вычисления хэша. Это необходимо для усложнения взлома методом перебора.
> [SHA-256]() наиболее популярный алгоритм шифрования. Используется, например, в [Bitcoin](https://ru.wikipedia.org/wiki/%D0%91%D0%B8%D1%82%D0%BA%D0%BE%D0%B9%D0%BD).
- Семейство MD (Message Digest)
> Наиболее популярный алгоритм семейства – [MD5](https://ru.wikipedia.org/wiki/MD5). Сейчас считается очень уязвимым к коллизиям (существуют даже генераторы коллизий для MD5).
[Аутентификация](https://ru.wikipedia.org/wiki/%D0%90%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F) – процедура проверки подлинности пользователя. Как правило выполняется путем сравнения введенного пользователем пароля с паролем, сохраненным в базе данных.
Так же, в это понятие часто включают и [идентификацию](https://ru.wikipedia.org/wiki/%D0%98%D0%B4%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B)) – процедуру выявления пользователя по его уникальному идентификатору (как правило это обычный логин или email). Это нужно, чтобы точно знать для какого пользователя выполняется проверка подлинности.
[Авторизация](https://ru.wikipedia.org/wiki/%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) – процедура выдачи прав доступа определенному пользователю на выполнение определенных операций. Например обычные пользователи интернет-магазина могут просматривать товары, добавлять их в корзину. А вот добавлять новые товары или удалять уже имеющиеся могут только администраторы.
> Наиболее простая схема аунтификации, при которой username и password пользователя передаются в заголовке [Authorization](https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Authorization) в незашифрованном виде (base64-encoded). При использовании HTTPS является относительно безопасным.
> Протокол авторизации благодаря которому можно зарегистрироваться в различных приложениях с помощью популярных сервисов (Google, Facebook, GitHub и т.д.)
> Стандарт аунтификации работающий на основе токенов доступа. Токены создаются сервером, подписываются секретным ключом и передаются клиенту, который в дальнейшем использует данный токен для подтверждения своей личности.
[SSL (Secure Socket Layer)](https://ru.wikipedia.org/wiki/SSL) и [TLS (Transport Layer Security)](https://ru.wikipedia.org/wiki/TLS) – это криптографические протоколы, которые обеспечивают защищённую передачу данных между двумя компьютерами в сети. По сути эти протоколы работают одинаково и отличий у них нет. SSL считается устаревшим, хотя все еще используется для поддержки старых устройств.
Тестирование позволяет проверить созданный программный продукт на то, что он работает именно так, как Вы задумали. Покрытие продукта должным количеством тестов, позволяет в дальнейшем проводить быстрые проверки на то, не сломалось ли что-нибудь в приложении, после добавления нового функционала.
> Важно понимать: успешное прохождение тестов не даёт 100% гарантии, что Ваше приложение будет работать всегда без багов и ошибок. Тесты пишутся людьми и они физически не могут учесть все возможные варианты использования программы. Поэтому успешные результаты тестов подтверждают лишь должную работу базового функционала.
Самый простой вид тестов. Как правило, около 70-80% от всех тестов занимают именно [unit-тесты](https://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5). «Unit» означает, что тестируется не вся система в целом, а небольшие и отдельные её части (функции, методы, компоненты и т.д.) в изоляции от других. Всё зависимое внешнее окружение, как правило, покрывается [моками (mocks)](https://gist.github.com/vertigra/696e9d92dc72070584e556e2169e850d).
[Интеграционное тестирование](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B5_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) подразумевает тестирование отдельных модулей (компонентов) в связке с другими (то есть, в интеграции).
End-to-end тесты подразумевают тестирование работы всей системы в целом. При этом виде тестирования, реализуется среда максимально близкая к реальным условиям. Проводятся как для API, так и для Frontend-части через браузер.
Когда вы создаете большое приложение, которое должно обслуживать большое количество запросов, возникает необходимость в тестировании этой самой возможности выдерживать большие нагрузки. Для создания [искусственной нагруженности](https://ru.wikipedia.org/wiki/%D0%9D%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BE%D1%87%D0%BD%D0%BE%D0%B5_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) существует множество утилит.
- [JMeter](https://ru.wikipedia.org/wiki/JMeter)
> Удобный интерфейс, кроссплатформенность, поддержка многопоточности, расширяемость, отличные возможности по созданию отчётов, поддержка многих протоколов для запросов.
> Имеет интересную функцию виртуальных пользователей, которые параллельно что-то делают с тестируемым приложением. Это позволяет понять как влияет работа одних пользователей, активно что-то делающих с сервисом, на работу других.
Представим, что у нас уже есть приложение с некоторым работающим и протестированным функционалом. Теперь мы добавляем новую фичу. Естественно мы тоже её тестируем. И вроде бы все хорошо, но не совсем, поскольку мы не знаем, а не сломала ли эта новая фича старый функционал. Так вот для этого и существует [регрессионное тестирование](https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%80%D0%B5%D1%81%D1%81%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B5_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) (это особенно важно на проектах, над которыми работает большая команда).
[Профилирование](https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D1%84%D0%B8%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)) кода это попытка найти узкие места в вашем коде. Профилирование позволяет проанализировать ваш код и найти его самые долго выполняющиеся участки. Инструмент, используемый для анализа работы, называют профилировщиком или профайлером.
<details>
<summary>🔗 <b>Ссылки на материалы</b></summary>
1. 📄 [**Профилирование кода к Python**](https://python-scripts.com/cprofile-code-profiling)
[Кэширование](https://aws.amazon.com/ru/caching/) является одним из самых действенных решений по оптимизации работы веб-приложений. Благодаря кэшированию можно повторно использовать ранее полученные ресурсы (статические файлы), тем самым сокращая задержку, снижая сетевой трафик и уменьшая время, необходимое для полной загрузки контента.
> Система серверов расположенная по всему миру. Такие сервера позволяют хранить дубликаты статического контента и доставлять его намного быстрее тем пользователям, которые находятся в непосредственной географической близости. Так же при использовании CDN снижается нагрузка на главный сервер.
- Браузерное (клиентское) кэширование
> Основано на загрузке страниц и других статических данных из локального кэша. Для этого браузеру (клиенту) отдается специальные заголовоки: [304 Not Modified](https://developer.mozilla.org/ru/docs/Web/HTTP/Status/304), [Expires](https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Expires), [Strict-Transport-Security](https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Strict-Transport-Security).
> Программа-демон которая реализует высокопроизводительное кэширование в оперативной памяти на основе пар _ключ-значение_. В отличие от [Redis](#redis) не может являться надёжным и долговременным хранилищем, поэтому подходит только для кэша.
1. 📄 [**Четыре уровня кэширования в сети: клиентский, сетевой, серверный и уровень приложения** – tproger.ru](https://tproger.ru/translations/cache-levels-on-the-web/)
1. 📄 [**«HTTP Strict-Transport-Security» или как обезопасить себя от атак «man-in-the-middle» и заставить браузер всегда использовать HTTPS** – habr.com](https://habr.com/ru/post/216751/)
1. 📄 [**Что такое Memcached?** – Amazon](https://aws.amazon.com/ru/memcached/)
1. 📺 [**Сравниваем Redis и Memcached, плюсы и минусы этих решений** – YouTube](https://youtu.be/sYamcfYati8)
Когда весь код приложения максимально оптимизирован и наращивание мощности сервера подходит к пределу, а нагрузка всё растёт и растёт – приходится прибегать к механизмам [кластеризации](https://ru.wikipedia.org/wiki/%D0%9A%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80_(%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%BE%D0%B2)) и [балансировки](https://ru.wikipedia.org/wiki/%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8). Суть заключается в объединении групп серверов в кластера, где нагрузка между ними распределяется при помощи специальных методов и алгоритмов, называемых балансировкой.
- Балансировка на сетевом уровне
> - **DNS-балансировка**. На одно доменное имя выделяется несколько IP-адресов и сервер на который будет перенаправлен запрос определяется по алгоритму [Round Robin](https://ru.wikipedia.org/wiki/Round-robin_(%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC)).
> - **Построение [NLB-кластера](https://learn.microsoft.com/ru-ru/windows-server/networking/technologies/network-load-balancing)**. Используется для управления двумя или более серверами в качестве одного виртуального кластера.
> - **Балансировка по территориальному признаку**. Примером может служить [метод рассылки Anycast](https://ru.wikipedia.org/wiki/Anycast).
- Балансировка на транспортном уровне
> Общение с клиентом замыкается на балансировщике, который работает как прокси. Он взаимодействует с серверами от своего имени, передавая информацию о клиенте в дополнительных данных и заголовках. Пример – [HAProxy](https://ru.wikipedia.org/wiki/HAProxy).
- Балансировка на прикладном уровне
> Балансировщик анализирует клиентские запросы и перенаправляет их на разные серверы в зависимости от характера запрашиваемого контента. Примером может служить [модуль Upstream в Nginx](https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-load-balancing) (который отвечает за балансировку) и [pgpool](https://docs.nextgis.ru/docs_ngweb/source/replication.html) из базы данных PostgreSQL (например, c его помощью можно распределять запросы на чтение на один сервер, а запросы на запись — на другой).
- Алгоритмы балансировки
> - [**Round Robin**](https://ru.wikipedia.org/wiki/Round-robin_(%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC)). Каждый запрос направляется поочередно на каждый сервер (сначала на первый, потом на второй и так по кругу).
> - [**Weighted Round Robin**](https://en.wikipedia.org/wiki/Weighted_round_robin). Улучшенный алгоритм Round Robin, который учитывает еще и производительность сервера.
> - [**Least Connections**](https://nginx.org/en/docs/http/load_balancing.html). Каждый последующий запрос направляется на сервер с наименьшим количеством поддерживаемых подключений.
> - **Destination Hash Scheduling**. Сервер, обрабатывающий запрос, выбирается из статической таблицы по IP-адресу получателя.
> - **Source Hash Scheduling**. Сервер, который будет обрабатывать запрос, выбирается из таблицы по IP-адресу отправителя.
> - [**Sticky Sessions**](https://habr.com/ru/company/domclick/blog/548610/). Запросы распределяются в зависимости от IP-адреса пользователя. Sticky Sessions предполагает, что обращения от одного клиента будут направляться на один и тот же сервер, а не скакать в пуле.
<details>
<summary>🔗 <b>Ссылки на материалы</b></summary>
1. 📄 [**Как устроен балансировщик нагрузки: алгоритмы, методы и задачи** – selectel.ru](https://selectel.ru/blog/load-balancer-review/)
2. 📄 [**Балансировка нагрузки: основные алгоритмы и методы** – habr.com](https://habr.com/ru/company/selectel/blog/250201/)
3. 📄 [**Введение в современную балансировку сетевой нагрузки и проксирование** – medium.com](https://medium.com/southbridge/introduction-to-modern-network-load-balancing-and-proxying-52e8ca36adde)
4. 📄 [**Балансировка и распределение нагрузки**](https://linkmeup.gitbook.io/sdsm/8.-bgp-i-ip-sla/2.-bgp/4.-balansirovka-nagruzki)
5. 📺 [**Балансировка нагрузки при помощи NGINX** – YouTube](https://youtu.be/XGIqSHpScrI)
6. 📺 [**HAProxy - бесплатный LoadBalancer. Установка и конфигурация** – YouTube](https://youtu.be/FmV_GMC_Sw8)
Стандарт в мире разработки. Невероятно простой, но в тоже время мощный язык разметки для описания Ваших проектов. Собственно говоря, ресурс, который Вы сейчас читаете, написан с помощью [Markdown](https://ru.wikipedia.org/wiki/Markdown).
> Сборник красивых README.md файлов (это главный файл любого репозитория на GitHub, использующий Markdown).
- Конспекты и заметки
> Markdown используются не только для написания документации. Этот невероятный инструмент отлично подходит для обучения – создания электронных конспектов и различных заметок. Лично я использую [редактор Obsidian](https://obsidian.md/) для конспектирования нового материала.
Для каждого современного языка программирования существуют [специальные инструменты](https://ru.wikipedia.org/wiki/%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%86%D0%B8%D0%B8) которые позволяют писать документацию прямо в коде программы. Благодаря этому Вы можете читать описание методов, функций, структур и так далее прямо внутри вашей IDE. Как правило, такого рода документация выполняется в виде обычных комментариев с учётом некоторых синтаксических особенностей.
Вы можете легко найти такой инструмент для своего языка введя в поиске _`docs generator for <ваш язык>`_.
> Например: [Docstring](https://peps.python.org/pep-0257/) для Python, [JSDoc](https://github.com/jsdoc/jsdoc) для JavaScript, [godoc](https://go.dev/doc/comment) для Go, [KDoc и Dokka](https://kotlinlang.org/docs/kotlin-doc.html) для Kotlin, [Javadoc](https://ru.wikipedia.org/wiki/Javadoc) для Java.
Удобная и понятная документация позволит другим пользователям быстрее разобраться и начать использовать ваш продукт. Писать документацию с нуля – это утомительный процесс. Для решения этой проблемы существуют общепринятые спецификации и инструменты автогенерации.
> Инструмент позволяющий автоматически генерировать интерактивную документацию, которую можно не только читать, но и активно с ней взаимодействовать (отправлять HTTP-запросы).
> Этакий playground в котором можно писать документацию и сразу видеть результат сгенерированной странички. Для этого используется файл YAML или JSON формата.
Со временем, когда Ваш проект разрастается и у него появляется множество модулей, одной странички README на GitHub может быть не достаточно. Уместно будет создать отдельный сайт для документации вашего проекта. Для этого совсем не обязательно учиться верстать, поскольку существует множество сайтов-генераторов для создания красивой и удобной документации.
> Наверное самый популярный генератор документации с использованием GitHub/Git и Markdown.
- [Docusaurus](https://docusaurus.io/)
> Open-source генератор от компании Facebook (Meta).
- [MkDocs](https://www.mkdocs.org/)
> Простой и широко кастомизируемый генератор документации в формате Markdown.
- [Slate](https://slatedocs.github.io/slate)
> Минималистичный генератор документации для REST API.
- [Docsify](https://docsify.js.org/#/ru-ru/)
> Ещё один простой, легкий и минималистичный генератор статики.
- [Astro](https://astro.build/)
> Генератор с современным и продвинутым дизайном.
- [mdBook](https://rust-lang.github.io/mdBook/)
> Статический генератор от разработчиков языка Rust.
- [И другие...](https://jamstack.org/generators/)
<details>
<summary>🔗 <b>Ссылки на материалы</b></summary>
1. 📺 [**GitBook для документации, портфолио и личных записей** – YouTube](https://youtu.be/z_mtp_uM4eI)
1. 📄 [**Пошаговая инструкция как использовать MkDocs для создания сайта с документацией продукта** – habr.com](https://habr.com/ru/company/rostelecom/blog/570098/)
1. 📄 [**Как писать хорошую документацию** – habr.com](https://habr.com/ru/company/plesk/blog/562960/)
Монолит – полноценное серверное приложение, которое содержит единую кодовую базу (написана на одном языке и храниться в одном репозитории) и имеет единую точку входа (для запуска всего приложения). По сути это самый распространенный подход для создания приложения в одиночку или небольшой командой.
Микросервис – по сути это тот же монолит, то есть полноценное отдельное приложение с единой кодовой базой. Но такое приложение отвечает лишь за одну функциональную единицу. То есть это маленький сервис, который решает одну задачу, но хорошо. За одним микросервисом может стоять один разрботчик.
- ### Горизонтальное и вертикальное масштабирование
Со временем, когда нагрузка на Ваше приложение начинает расти (приходит больше пользователей, появляется новый функционал и, как следствие, задействуется больше процессорного времени), становится необходимым увеличивать мощность сервера. Для этого есть [2 основных подхода](https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D0%BE%D1%81%D1%82%D1%8C):
- Вертикальное масштабирование
> Подразумевает увеличение мощности уже существующего сервера. К примеру, сюда можно отнести увеличение размера оперативной памяти, установка более быстрого накопителя или увеличение его объема, а также покупка нового процессора с большой тактовой частотой и/или большим количеством ядер и потоков. Вертикальное масштабирование имеет свой предел, поскольку мы не можем долго наращивать мощности одного сервера.
- Горизонтальное масштабирование
> Процесс развертывания новых серверов. Данный подход требует построения надёжной и масштабируемой архитектуры, которая позволит разнести логику работы всего приложения (или уже правильнее сказать сервиса) на несколько физических машин.
- [Hussein Nasser – один из лучших англоязычных каналов на YouTube по серверной разработке](https://www.youtube.com/c/HusseinNasser-software-engineering)
- [Курс по компьютерным сетям начального уровня](https://www.asozykin.ru/courses/networks_online)