Мои конспекты обо всём, что связано с информационными технологиями (англ. information technology, IT), программированием и смежными ему областями.
- Почему я решил всё это написать
- Как подготовиться к собеседованию по этим заметкам
- Общая теория
- Дискретная математика
- Информация и данные
- Типы данных
- Структуры данных и алгоритмы
- Модели данных и базы данных
- Программирование
- Тестирование
- Архитектурные стили
- Архитектурные паттерны
- Паттерны проектирования
- Принципы проектирования
- Масштабирование
- Инженерия ИИ-приложений
- Рендеринг веб-приложений
- Как сайт попадает в интернет
- Инфраструктура как код
- API: REST, GraphQL, RPC и gRPC
- Технологии, библиотеки, фреймворки и языки программирования
Поскольку я всей душой за Open Source, я хочу в открытом доступе поделиться с вами всеми моими познаниями, моим опытом, моим виденьем всего, с чем мне доводилось сталкиваться за последние годы работы, что можно было написать словами и о чём мне хотелось писать. К данным заметкам я стараюсь подходить с практической точки зрения, поскольку большая часть материалов была подготовлена на основании теоретических и практических вопросов, которые мне доводилось встречать как на собеседованиях, так и при непосредственной работе на проектах.
Человеческая память - это самое ненадёжное хранилище информации.
Никогда не знаешь, что и когда оттуда пропадёт. Ни в чём нельзя быть уверенным, если дело касается воспоминаний. Как бы хорошо ты ни разобрал какой-то материал, твоя уверенность в своих знаниях касательно него тает спустя несколько лет без практики, без перечитывания, возвращения к материалу.
Самая лучшая память находится на кончике карандаша
То, что нам покорилось однажды, обычно намного проще и быстрее можно наверстать по сравнению с тем, сколько времени и сил мы затрачиваем на это при первом знакомстве.
Даже если порой кажется, что мы забыли что-то безвозвратно, одно слабое упоминание, один мимолётный триггер может помочь восстановить почти достоверную картину.
Итак, изначальная цель данного проекта - это сохранение моих мыслей, сравнений, умозаключений в моменты наивысшего подъёма в какой-либо области (в каком-либо домене), когда и основательнее всего подошёл к разбору материалов. Это позволяет в любой момент времени (через неделю, месяц или даже через 5 лет) практически мгновенно найти решение проблемы, которую я уже решал, или ответ на вопрос, на который мне уже доводилось отвечать (себе или кому-либо ещё). Ускоряет этот процесс ещё и то, что материал однороден (ведь всё написано одним человеком и на одном языке) и имеет структуру, оптимальную для повторения.
В какой-то момент я осознал, что эти мысли и опыт можно запечатлеть таким образом, чтобы их могли перенять и другие. С тех пор я всегда стараюсь придерживаться такой формы повествования: пишу не для себя - стараюсь писать доступно для всех.
Примерный список вопросов по этим конспектам я прикладываю здесь, чтобы читатель мог проверить свои знания и убедиться, что я пишу многие материалы не просто так, а потому что такие вопросы уже встречались. Ответы будут прилагаться в виде ссылок на отдельные параграфы из заметок по мере их написания.
Стоит также отметить, что некоторые вещи покоряются лишь с опытом, с практикой, спустя некоторое время (например, абстракция, паттерны проектирования, принципы по типу SOLID, архитектуры приложений). И это не беда, если у вас сразу что-то постигнуть не получается. Возможно, время ещё не пришло. Главное - не стоит сдаваться и отчаиваться. Просто идите вперёд так, как можете и умеете сейчас! А я постараюсь облегчить этот путь так, как только смогу.
«Дискретная математика занимается изучением дискретных (конечных) математических структур - таких структур, количество элементов которых конечно, а значит эти элементы можно пересчитать, перечислить. Из-за ограниченности ресурсов компьютера на нём можно реализовывать (рассматривать) только дискретные структуры. Именно эти структуры легли в основу компьютера, стали фундаментом при его создании».
«Всё, что мы видим и слышим каждый день, несёт в себе какую-то информацию. По сути говоря, вся наша жизнь связана с получением, обработкой и передачей информации. Данные - это цифровая оболочка информации, последовательность нулей и единиц. Представить информацию как данные означает дать возможность компьютеру обрабатывать её. Данные могут быть представлены текстом, изображением, видео, аудио и другими способами».
«Типом данных называют множество допустимых значений и совокупность операций над этими значениями. Типы данных позволяют разбить разнородную информацию на несколько заданных типов (строковый, числовой, логический, дата и другие типы). К каждому типу может применяться лишь ограниченное множество операций (например, разность чисел, конкатенация строк и так далее)».
- О типе данных
- Примитивные типы данных
- Логический тип
- Строковый тип
- Символьный тип
- Целочисленный тип
- Число с плавающей точкой
- Ссылка
- Указатель
Заметка о том, как хранить данные и как быстро с ними работать: сложность алгоритмов и нотация O с наглядными расчётами, массив, связный список, стек, очередь, хеш-таблица, дерево, куча и граф — с реализациями на TypeScript и сравнением сложности операций. Дальше — линейный и бинарный поиск, четыре сортировки с подсчётом сравнений, как сортирует JavaScript, обход графа в ширину и в глубину и таблица «какую структуру выбрать».
- Сложность алгоритмов
- Структуры данных
- Алгоритмы поиска
- Алгоритмы сортировки
- Обход графа
- Как выбрать структуру данных
Заметка о программировании как таковом: что такое программа, алгоритм и язык программирования, чем синтаксис отличается от семантики, краткая история — от примечаний Ады Лавлейс до JavaScript — со ссылками на первоисточники, и строительные блоки любой программы: переменные, выражения, ветвления и циклы, функции и процедуры, рекурсия, массивы, записи и словари. Одна задача решена в процедурном, объектно-ориентированном, функциональном и декларативном стилях на C, JavaScript, Python и SQL. В конце — работа со строками и регулярные выражения.
- Что такое программирование
- Краткая история
- Из чего состоит программа
- Одна задача в разных стилях
- Работа со строками
- Регулярные выражения
«Не было бы смысла в таком количестве языков программирования, если бы они хотя бы немного не отличались друг от друга. И дело не только в синтаксисе - критериев сравнения (характеристик) с годами выработалось очень много. Не существует идеального языка программирования (этакой "серебряной пули"), превосходно подходящего под каждый проект. Наоборот, язык должен выбираться в соответствии с техническими требованиями проекта. И где один язык прекрасно вписывается, реализуя все свои преимущества, другой проявляет себя как нельзя хуже из-за своих "узких мест", ограничений. В данном разделе мы детально рассмотрим каждый из критериев сравнения, чтобы вы могли научиться описанию и сравнению языков программирования, а также принятию решения о том, какой язык подходит больше именно под нужды вашего текущего проекта».
- О характеристиках языков программирования
- Типизация
- Компилируемость и интерпретируемость
- Потоки, однопоточность и многопоточность
- Синхронность и асинхронность
- Кроссплатформенность и нативность
- Поддержка парадигм программирования
«Тестированием называют процесс испытания некоторого продукта с целью проверки соответствия готовой реализации продукта первоначальным требованиям заказчика. Качественное тестирование очень важно для приложения. Хороший тестировщик продумывает все возможные и невозможные исходы и проверяет каждый из них. Без такого тестирования невозможно гарантировать корректность работы приложения, а значит оно может сломаться в любом месте и в любой момент времени». Здесь мы рассмотрим подходы к тестированию, основные понятия и инструменты, используемые при тестировании приложений.
- Зачем тестировать приложение
- Тестирование и его разновидности
- Подходы к написанию тестов
- Тестовые объекты
- Паттерны тестирования
Заметка о самом верхнем уровне решений: из каких крупных частей состоит система и как эти части общаются. Разобраны монолит и совет начинать именно с него, слои и чем слой отличается от уровня, клиент-сервер, конвейер и фильтры на примере командной строки Unix, событийная и сервис-ориентированная архитектуры, микросервисы с их паттернами — сага, ящик исходящих, API Gateway и BFF, — а также микрофронтенды, ячеистая архитектура и постепенный переход от монолита (Strangler Fig). В конце — сводная таблица. Определения — из первоисточников: работы Гарлана и Шоу, диссертации Филдинга, статей Фаулера.
- Что такое архитектурный стиль
- Монолитная архитектура
- Многослойная архитектура
- Клиент-серверная архитектура
- Конвейер и фильтры
- Событийная архитектура
- Сервис-ориентированная архитектура
- Микросервисная архитектура
- Микрофронтенды
- Ячеистая архитектура
- Сравнение
Заметка о типовых решениях для организации кода внутри приложения: семейство MVC (MVP, MVVM, MVPVM), EBI, трёхуровневая архитектура, DDD, Порты и Адаптеры, Луковая, Кричащая и Чистая архитектуры с правилом зависимостей, Event Sourcing и CQRS, а в конце — современные способы организовать код: вертикальные срезы и Feature-Sliced Design.
- MVC (1979)
- Иерархический MVC (2000), PAC (1987)
- MVP (1996)
- MVVM (2005)
- MVPVM
- EBI (1992)
- Трёхуровневая архитектура
- DDD (2003)
- Шестиугольная архитектура, Порты и Адаптеры (2005)
- Луковая архитектура (2008)
- Кричащая архитектура (2011)
- Чистая архитектура (2012)
- Event Sourcing
- CQRS
- Vertical Slice Architecture (2018)
- Feature-Sliced Design
Заметка о 23 паттернах «Банды четырёх» и внедрении зависимостей: порождающих, структурных и поведенческих. Примеры — на TypeScript, а рядом — то, что уже встроено в JavaScript: модули, Proxy, итераторы, EventEmitter, промежуточные обработчики Express. Отдельная группа — паттерны устойчивости: таймаут, повтор с джиттером, предохранитель и переборка. В конце — таблица похожих паттернов и чем они отличаются.
- Откуда взялись паттерны
- Порождающие
- Структурные
- Поведенческие
- Паттерны устойчивости
- Похожие паттерны
Заметка о понятиях и принципах, на которые опираются стили и паттерны: чем архитектурный стиль отличается от архитектурного паттерна и паттерна проектирования, связанность и сплочённость, инверсия управления, основы ООП, SOLID, DRY, KISS и YAGNI.
- Определения
- Поддерживаемый код
- Принципы пакетов
- Принцип разделения ответственности (SoC)
- Принцип инверсии управления (IoC)
- Основные принципы ООП
- Основные термины ООП
- Композиционный принцип повторного использования
- Принципы SOLID
- Принцип DRY
- Принцип KISS
- Принцип YAGNI
Заметка о том, как система выдерживает рост нагрузки: что такое масштабируемость и почему её измеряют перцентилями, а не средним, вертикальное и горизонтальное масштабирование с плюсами и минусами, серверы без состояния и три способа хранить сессии, балансировка нагрузки, кэширование, очереди и автомасштабирование в Kubernetes, пределы роста — закон Амдала и универсальный закон масштабируемости с расчётами. Масштабирование баз данных — репликация, шардинг и партиционирование — в отдельной главе.
- Что такое масштабируемость
- Вертикальное масштабирование
- Горизонтальное масштабирование
- Серверы без состояния
- Балансировка нагрузки
- Кэширование
- Очереди
- Автомасштабирование
- Пределы масштабирования
- Масштабирование баз данных
- Репликация, шардинг и партиционирование: сравнение
Заметка о том, как устроены приложения поверх больших языковых моделей. Начинается с понятий: чем искусственный интеллект отличается от машинного обучения, что такое нейронная сеть, токен, токенизатор и контекстное окно, как считать токены и за что идёт оплата. Дальше — инженерная часть: харнесс, инструменты и цикл вызова, стриминг, воркфлоу против агента, подключение внешних систем через коннекторы и MCP, поиск по документам, глубокий поиск, скиллы. Заканчивается тем, что отличает прототип от продакшена: модерация ввода, оценка качества, надёжность и долгоживущие воркфлоу. Числа в главах про цены и модели взяты из документации, датированы и снабжены ссылками: эта область устаревает быстро.
- Искусственный интеллект и машинное обучение
- Нейронные сети
- Что такое языковая модель
- Токен
- Токенизатор
- Контекстное окно
- Как посчитать токены
- Сколько это стоит
- Кэширование промпта
- Пакетная обработка
- Подписка и оплата по токенам
- Харнесс (harness)
- Динамическая сборка промпта
- Инструменты и цикл вызова
- Стриминг и цикл агента
- Воркфлоу против агента
- Рассуждение и уровень усилий
- Коннекторы
- MCP: протокол подключения инструментов
- Поиск по документам (Retrieval-Augmented Generation, RAG)
- Глубокий поиск
- Скиллы (Agent Skills)
- Структурированный вывод и генерация документов
- Модерация ввода
- Оценка качества
- Надёжность и долгоживущие воркфлоу
Заметка о том, кто и когда собирает HTML, который видит пользователь: браузер, сервер или сборщик. Разобраны рендеринг на клиенте и на сервере, гидратация и её цена, статическая генерация и инкрементальная регенерация, потоковый рендеринг, серверные компоненты, острова и возобновляемость. В конце — сводная таблица и ориентиры, что под какую задачу брать. Определения — из первоисточников: статьи Rendering on the Web и документации фреймворков.
- Что происходит между кликом и картинкой
- Рендеринг на клиенте (CSR)
- Рендеринг на сервере (SSR)
- Гидратация
- Статическая генерация (SSG)
- Инкрементальная регенерация (ISR)
- Потоковый рендеринг
- Серверные компоненты
- Острова (Islands Architecture)
- Возобновляемость (Resumability)
- Что выбирать
Заметка о пути от доменного имени до страницы в браузере: кто владеет адресом — реестр, регистратор и DNS-хостинг, — какие бывают записи зоны, почему CNAME нельзя ставить на корень домена, откуда берётся задержка после изменения записей, что делает сеть доставки контента и как выпускаются сертификаты. Начинается с общих понятий эксплуатации — окружений, конфигурации, секретов и CI/CD, — а заканчивается разбором настройки своего домена для сайта на GitHub Pages.
- Общие понятия
- Домен и кто за что отвечает
- Зона и записи DNS
- Псевдоним (CNAME)
- Время жизни записи (TTL)
- Сеть доставки контента и обратный прокси
- Сертификаты и HTTPS
- Пример: свой домен для GitHub Pages
Заметка о том, почему инфраструктуру описывают кодом, а не настраивают руками: декларативный подход, устройство Terraform — провайдеры, ресурсы, состояние, цикл plan / apply, — пример с записью DNS в Cloudflare, почему файл состояния нельзя класть в git, история с лицензией и появлением OpenTofu, и чем отличаются инструменты, которые создают инфраструктуру, от тех, что её настраивают.
- Зачем описывать инфраструктуру кодом
- Декларативный подход
- Terraform: провайдеры, ресурсы, состояние
- Цикл работы
- Пример: запись DNS в Cloudflare
- Где хранить состояние
- Лицензия Terraform и OpenTofu
- Создать или настроить: альтернативы
Заметка о способах, которыми программы запрашивают друг у друга данные и действия. Разобраны ограничения REST по диссертации Филдинга и свойства методов HTTP, GraphQL с его тремя типами операций, удалённый вызов процедур на примере JSON-RPC и gRPC — контракт .proto, Protocol Buffers, HTTP/2 и четыре вида методов. В конце — сводная таблица по семи признакам и ориентиры, что где уместно.