Учебный проект на Laravel 12, демонстрирующий алгоритмы сортировки, поиска, структуры данных, алгоритмы кэширования и работу с очередями RabbitMQ / Kafka. Всё завёрнуто в Docker.
- Стек технологий
- Структура проекта
- Быстрый старт
- API — Сортировки
- API — Поиск
- API — Структуры данных
- API — Кэширование
- API — Очереди
| Компонент | Версия / Образ | Порт |
|---|---|---|
| PHP | 8.3 FPM Alpine | — |
| Laravel | 12 | — |
| Nginx | 1.25 Alpine | 8080 |
| PostgreSQL | 16 Alpine | 5432 |
| Redis | 7 Alpine | 6379 |
| RabbitMQ | 3.13 Management Alpine | 5672, 15672 (UI) |
| Kafka | Confluent 7.6 | 9092 |
| Kafka UI | provectuslabs/kafka-ui | 8090 |
.
├── docker-compose.yml
├── docker/
│ ├── php/
│ │ ├── Dockerfile # PHP 8.3 + расширения (pgsql, redis, rdkafka, amqp)
│ │ ├── entrypoint.sh # composer install → key:generate → migrate → php-fpm
│ │ └── php.ini
│ ├── nginx/
│ │ └── default.conf
│ └── postgres/
│ └── init.sql # Тестовые данные
├── app/
│ ├── Cache/ # LRUCache, LFUCache, FIFOCache, TTLCache, LRUCacheNode
│ ├── DataStructures/ # BSTNode, BinarySearchTree, Graph, TrieNode, Trie
│ ├── Services/
│ │ ├── Sorting/ # SortingService
│ │ ├── Search/ # SearchService
│ │ ├── DataStructures/ # DataStructuresService
│ │ ├── Cache/ # CacheAlgorithmsService
│ │ └── Messaging/ # RabbitMQService, KafkaService
│ └── Http/Controllers/Api/
└── routes/
└── api.php # 29 маршрутов
git clone <repo-url>
cd algorithms_and_data_structures.docker-compose up --buildПервый запуск занимает несколько минут — собирается образ с PHP расширениями.
entrypoint.sh автоматически выполнит composer install, key:generate и migrate.
# Laravel healthcheck
curl http://localhost:8080/up
# Первый API запрос
curl http://localhost:8080/api/sorting/demo| Сервис | URL | Логин / Пароль |
|---|---|---|
| RabbitMQ UI | http://localhost:15672 | rabbit_user / rabbit_pass |
| Kafka UI | http://localhost:8090 | — |
# Войти в контейнер приложения
docker exec -it algo_app sh
# Запустить миграции вручную
docker exec -it algo_app php artisan migrate
# Посмотреть логи
docker-compose logs -f app
# Остановить всё
docker-compose down
# Остановить и удалить volumes (сброс БД)
docker-compose down -vБазовый URL: http://localhost:8080/api/sorting
GET /api/sorting/demo
GET /api/sorting/demo?size=200 # случайный массив из 200 элементов
GET /api/sorting/demo?array[]=5&array[]=3&array[]=8Возвращает результаты и время выполнения для всех алгоритмов:
quicksort, bubble_sort, merge_sort, insertion_sort, selection_sort, heap_sort, counting_sort, radix_sort, php_sort
GET /api/sorting/quicksort
GET /api/sorting/quicksort?array[]=64&array[]=34&array[]=25&array[]=12Возвращает отсортированный массив + описание сложности и принципа работы.
# Сортировка массива объектов по полю
GET /api/sorting/usort?field=age&direction=asc
GET /api/sorting/usort?field=name&direction=descGET /api/sorting/benchmark?size=500 # сравнение скоростей на 500 элементах
GET /api/sorting/benchmark?size=5000Базовый URL: http://localhost:8080/api/search
GET /api/search/demo?target=42
GET /api/search/demo?target=999&size=10000 # массив из 10000 элементовСравнивает: linear, binary, binary_recursive, jump, interpolation, exponential
Показывает количество сравнений и время для каждого алгоритма.
Пример ответа:
{
"array_size": 1000,
"target": 42,
"algorithms": {
"linear": { "found": true, "index": 41, "comparisons": 42, "time_ms": 0.08 },
"binary": { "found": true, "index": 41, "comparisons": 10, "time_ms": 0.003 },
"jump": { "found": true, "index": 41, "comparisons": 10, "time_ms": 0.005 }
}
}GET /api/search/linear?target=5
GET /api/search/linear?target=99&array[]=10&array[]=99&array[]=30GET /api/search/binary?target=42Возвращает результаты итеративного и рекурсивного вариантов.
Базовый URL: http://localhost:8080/api/data-structures
GET /api/data-structures/allGET /api/data-structures/arraysДемонстрирует: порядок вставки, смешанные ключи, ловушки с числовыми ключами. PHP array = HashTable + DoublyLinkedList (O(1) доступ + сохранение порядка).
GET /api/data-structures/splДемонстрирует все SPL структуры с примерами операций:
| Класс | Тип | get/set |
|---|---|---|
SplStack |
LIFO стек | O(1) |
SplQueue |
FIFO очередь | O(1) |
SplMinHeap |
Мин-куча | O(log n) |
SplMaxHeap |
Макс-куча | O(log n) |
SplPriorityQueue |
Приоритетная очередь | O(log n) |
SplDoublyLinkedList |
Двусвязный список | O(1) на концах |
SplFixedArray |
Фикс. массив | O(1), -37% памяти |
GET /api/data-structures/hash-tableДемонстрирует: PHP array как хэш-таблица, WeakMap, хранение свойств объектов.
GET /api/data-structures/treeВставка, поиск, три обхода: inorder (отсортированный), preorder, postorder. Высота дерева.
GET /api/data-structures/graphГраф A-B-C-D-E. Сравнение BFS (обход в ширину, Queue) и DFS (обход в глубину, Stack).
GET /api/data-structures/trieПоиск по словарю [apple, app, application, apply, banana]. Автодополнение по префиксу.
Базовый URL: http://localhost:8080/api/cache
GET /api/cache/compareGET /api/cache/lruПошаговая трассировка: видно какой элемент вытесняется и почему.
SET a=1 → cache: a
SET b=2 → cache: a,b
SET c=3 → cache: a,b,c
GET a → HIT | cache: b,c,a ← 'a' переместился в конец (самый свежий)
SET d=4 → cache: c,a,d ← 'b' вытеснен (давно не использовался)
GET b → MISS
GET /api/cache/lfuТрассировка с частотами: { "a": 3, "b": 2, "c": 1 } → вытесняется c.
GET /api/cache/fifoGET /api/cache/ttl
⚠️ Этот эндпоинт делаетsleep(3)для демонстрации истечения TTL. Ответ придёт через ~3 секунды.
Базовый URL: http://localhost:8080/api/messaging
Требуется: запущенные контейнеры
rabbitmqиkafka.
GET /api/messaging/compareПодробное сравнение: модель, throughput, replay, маршрутизация, use cases.
POST /api/messaging/rabbitmq/direct
Content-Type: application/json
{
"routing_key": "error",
"payload": { "message": "Database connection failed", "service": "db" }
}Сообщение попадёт только в очередь algo.error.
POST /api/messaging/rabbitmq/fanout
Content-Type: application/json
{
"payload": { "event": "cache.invalidate", "timestamp": "2024-01-01T10:00:00" }
}Сообщение разойдётся во все очереди: service_a, service_b, service_c.
POST /api/messaging/rabbitmq/topic
Content-Type: application/json
{
"routing_key": "logs.db.error",
"payload": { "level": "error", "message": "Connection timeout" }
}| Routing key | Попадёт в logs.# |
logs.*.error |
logs.db.* |
|---|---|---|---|
logs.db.error |
✅ | ✅ | ✅ |
logs.api.warn |
✅ | ❌ | ❌ |
logs.db.info |
✅ | ❌ | ✅ |
GET /api/messaging/rabbitmq/consume?queue=algo.errorGET /api/messaging/rabbitmq/dlxНастраивает DLX: просроченные / отклонённые сообщения → algo.dead.letters.
POST /api/messaging/kafka/publish
Content-Type: application/json
{
"topic": "algo.orders",
"key": "order:123",
"payload": { "order_id": 123, "event": "order.created", "amount": 1500 }
}Все события с одинаковым key попадают в одну партицию → гарантия порядка.
GET /api/messaging/kafka/consumer-groupsОбъясняет ключевое отличие от RabbitMQ:
- RabbitMQ: одно сообщение → один консьюмер
- Kafka: одно событие → все Consumer Groups
GET /api/messaging/kafka/offsetsПоказывает как перечитать события с любой точки в прошлом.
GET /api/messaging/kafka/exactly-once| Критерий | RabbitMQ | Kafka |
|---|---|---|
| Модель | Брокер сообщений | Журнал событий |
| Push/Pull | Push → консьюмер | Pull ← консьюмер |
| Хранение | Удаляет после ACK | Хранит N дней |
| Replay | ❌ Невозможен | ✅ Любой offset |
| Маршрутизация | Гибкая (4 типа exchange) | Простая (topic + partition key) |
| Throughput | ~50k msg/sec | ~1M+ msg/sec |
| Когда выбрать | RPC, TTL, DLX, приоритеты | Event Sourcing, CDC, аналитика |