Как реализовать функцию сокращения URL
Что проверяют
Умеете ли вы превратить простую идею в сервис: откуда берётся короткий ключ, как не выдать один ключ двум ссылкам и что будет под нагрузкой. Следом почти всегда спрашивают, как масштабировать это на миллионы ссылок и что делать, если одну и ту же ссылку сокращают повторно.
Как отвечать
Начните с двух операций: POST /shorten принимает длинный URL и возвращает код, GET /{code} отвечает редиректом. Дальше выбор способа генерации ключа:
- счётчик и base62: берёте автоинкрементный
idиз базы и кодируете алфавитом из цифр и латиницы в обоих регистрах. Семь символов дают 62^7, около 3,5 трлн комбинаций, коллизий нет по построению. Минус: коды идут подряд, и их легко перебрать; - случайная строка:
secrets.choiceилиsecrets.token_urlsafeплюс уникальный индекс на колонкеcode. При конфликте ловитеIntegrityErrorи генерируете заново, а не делаетеSELECTпередINSERT: между проверкой и вставкой успеет влезть другой запрос; - хэш от URL: первые символы
sha256в base62. Одинаковые ссылки получают одинаковый код, но на усечённом хэше коллизии всё равно нужно обрабатывать.
Хранилище: таблица с полями code, original_url, created_at, при необходимости expires_at и счётчик переходов. Чтений у сокращателя на порядки больше, чем записей, поэтому перед базой ставят кэш, например Redis. Код ответа тоже выбор: 301 браузер кэширует, и статистика переходов теряется, 302 или 307 приводят каждый переход на ваш сервер.
На Python это обычно FastAPI или Django. URL валидируют через pydantic.HttpUrl или urllib.parse и пропускают только схемы http и https.
Где спотыкаются
Берут модуль random для генерации кодов. Он предсказуем, а для идентификаторов, которые не должны угадываться, нужен secrets.
Проверяют коллизию отдельным SELECT, как в учебных примерах. Под конкурентной нагрузкой это гонка, и защищает от неё только уникальный индекс в базе.
Забывают про злоупотребления: сокращатель быстро становится прикрытием для фишинга и открытых редиректов. Стоит упомянуть проверку схемы, лимит запросов на создание и возможность заблокировать код.