Как я в 14 лет написал свой аналог LeetCode с котиками за месяц (и немного поехал башкой)

от автора

Привет, Хабр! Мне 14 лет, и пока мои ровесники ругаются в cs2, а нормальные люди спят по 8 часов, я решил, что мне катастрофически не хватает стресса в жизни. Поэтому за последний месяц я написал собственную платформу для решения алгоритмических задач — с изолированным выполнением кода, микросервисами и котиками.

Встречайте — ЛитКот. Проект уже крутится в проде на leetcot.ru, а в этой статье я расскажу, как организовать архитектуру такого сервиса, не задохнуться в монорепе и защитить сервер от мамкиных хакеров (вроде меня самого).

Зачем нужен ещё один тренажёр?

LeetCode — это классика, но давайте честно: решать сухие задачи про инверсию бинарного дерева бывает невероятно скучно. Особенно когда на реальном собеседовании тебя попросят просто отцентрировать div или переложить JSON из одной апишки в другую. Мне захотелось добавить геймификации, сюжета и немного (а точнее, нездорово много) безумия.

Например, в моём курсе «Щёлкаем алгоритмы как рыбку» нет унылой задачи «Поиск элемента в отсортированном массиве». Зато есть «Прятки с сосиской»! Пользователю нужно написать алгоритм бинарного поиска за O(log n), чтобы помочь коту найти сосиску в контейнерах. Согласитесь, ради виртуальной сосиски писать код как-то приятнее, чем ради мифического оффера в бигтех.

Выполнение кода: даём пользователю гранату (и надеемся на лучшее)

Самое весёлое в разработке аналога LeetCode — это запуск чужого кода. Разрешить случайным людям из интернета выполнять Python-скрипты на твоём сервере — это как добровольно пригласить в дом полтергейста. Один случайно (или специально) запущенный while True: fork() — и твой сервер со слезами отправляется в Вальгаллу, попутно наматывая счёт за хостинг до астрономических высот.

Пришлось продумать надёжную изоляцию процессов. Код каждого пользователя выполняется в изолированной песочнице со строгими ограничениями по памяти и жёстким тайм-аутом. Не успел найти сосиску вовремя — лови Time Limit Exceeded и иди оптимизируй. У нас тут суровый кошачий киберспорт.

Инфраструктура, или «Я у мамы DevOps»

Чтобы проект не жил только на моём localhost, я настроил полноценный CI/CD-пайплайн в GitHub Actions. Проект пакуется в Docker-контейнеры с аккуратным Dockerfile и .dockerignore, чтобы случайно не утянуть в прод папку node_modules весом с небольшую чёрную дыру.

Для удобной разработки настроены DevContainers — настраивать локальное окружение руками каждый раз это для слабаков.

А чтобы после моих гениальных релизов не отваливались вёрстка и логика, прикручены E2E-тесты на Playwright. Да, я даже пишу тесты. Сам в шоке.

name: Deploy Productionon:  release:    types: [published]jobs:  deploy:    runs-on: self-hosted    steps:      - name: Cleanup host        run: |          docker system prune -af --volumes          sudo journalctl --vacuum-size=10M          sudo apt-get clean      - uses: actions/checkout@v4      - name: Environment        run: |          [ -f /home/user1/actions-runner/secrets.env ] && cp /home/user1/actions-runner/secrets.env ./.env || exit 1      - name: Update and Deploy        run: |          docker compose pull          docker compose up -d --remove-orphans      - name: Migrations        run: |          docker compose exec -T app pnpm --filter @repo/db exec prisma migrate deploy

Что дальше?

Месяц плотного кодинга на энтузиазме дал свои плоды. Проект работает, пользователи могут учить алгоритмы, а котики находят свои сосиски.

Но почивать на лаврах скучно. Прямо сейчас я готовлю к релизу следующий проект -и это будет кое-что большее чем просто тренажёр задач. Следите за leetcot.ru и arlist.ru.

Буду рад конструктивной критике (и неконструктивному хейту) в комментариях. Пишите, как вы реализовывали безопасное выполнение кода в своих пет-проектах, ставьте плюсики и буду рад увидеться с вами вновь!

ссылка на оригинал статьи https://habr.com/ru/articles/1050358/