Интервьюер сказал: вы разрабатываете систему генерации коротких ссылок.

Java задняя часть

введение

Я считаю, что вы будете получать много текстовых сообщений в своей жизни, особенно во время недавнего мероприятия Double Eleven, и эти текстовые сообщения имеют две характеристики. Во-первых, это почти все текстовые сообщения со спамом, которые здесь можно игнорировать. две особенностиСсылка коротка, например:

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

  • Слишком длинные ссылки легко ограничиваются по длине
  • Короткие ссылки выглядят просто, длинные — легко.
  • Безопасно, не хочу раскрывать параметры
  • Конечно, это может быть унифицированное преобразование ссылок, а также такие операции, как подсчет кликов.

那背后的原理是什么呢? Как?让你实现这样的系统,你会怎么设计呢? 【来自于某鹅场面试官】

Принцип коротких ссылок

Логика отображения короткой ссылки

Самая важная точка знаний здесь — перенаправление, сначала просмотрите его.httpКод состояния:

Классификация значение
1** Сервер получает запрос и требует от запрашивающей стороны продолжить операцию.
2** Success, операция успешно получена и обработана
3** Перенаправление, дальнейшие действия, необходимые для выполнения запроса
4** Ошибка клиента, запрос содержит синтаксическую ошибку или запрос не может быть выполнен
5** Ошибка сервера, сервер обнаружил ошибку при обработке запроса

Тогда коды состояния, начинающиеся с 3, относятся к перенаправлениям:

  • 300: несколько вариантов, могут существовать в нескольких местах.
  • 301: Постоянная переадресация, браузер кэширует и автоматически перенаправляет на новый адрес.
  • 302: Временное перенаправление, клиент продолжит использовать старый URL.
  • 303: Посмотреть другие адреса, похожие на 301.
  • 304: Не изменено. Запрошенный ресурс не был изменен, и ресурс не будет возвращен, когда сервер вернет этот код состояния.
  • 305: для доступа к ресурсу требуется прокси
  • 306: Устаревший код состояния
  • 307: Временное перенаправление, перенаправление с запросом Get

Весь процесс прыжка:

  • 1. Пользователь переходит по короткой ссылке и запрос доходит до сервера
  • 2. Сервер заменяет короткую ссылку на длинную, а затем возвращает браузеру код состояния перенаправления 301/302.
    • 301 постоянное перенаправление приведет к тому, что браузер кеширует адрес перенаправления, а система коротких ссылок будет неправильно подсчитывать количество посещений.
    • Временное перенаправление 302 может решить проблему неточного времени, но каждый раз, когда оно будет преобразовано в систему коротких ссылок, нагрузка на сервер будет возрастать.
  • 3. Браузер получает код состояния перенаправления и адрес, к которому действительно нужно получить доступ, и перенаправляет на настоящую длинную ссылку.

Как видно из рисунка ниже, ссылка действительно302Редирект на новый адрес, в возвращаемом заголовке есть полеLocationадрес для перенаправления:

Как создаются короткие ссылки?

глобальный сигнальщик

Наверняка первое, о чем мы думаем, это сжатие, как сжатие файла, после сжатия распаковать и восстановить на исходную ссылку, перенаправить на исходную ссылку, но, к сожалению, это не работает, видели ли вы какое-либо сжатие Есть ли способ напрямую сжать такое длинное число до такого короткого? На самом деле невозможно. Это какHuffmanДерево может сжимать только строки с большим количеством повторяющихся символов с высокой эффективностью, как и ссылки, параметров может быть много, и бывают разные нестандартные ситуации, поэтому алгоритм прямого сжатия нереален.

Тотhttps://dx.10086.cn/tzHLFwиhttps://gd.10086.cn/gmccapp/webpage/payPhonemoney/index.html?channel=Какая разница между ними? Передний путь не меняется, меняется задний, т.е.tzHLFwиgmccapp/webpage/payPhonemoney/index.html?channel=преобразование между.

На самом деле это очень просто, то есть часть данных в базе данных,idСоответствует длинной ссылке (эквивалентно глобальному отправителю, глобальному уникальному идентификатору):

id url
1 Guangdong 10086. Can/GMC wipe PP/Web…

Здесь используется распределенный глобальный уникальный идентификатор, о котором мы упоминали ранее.idВ качестве параметра, похоже, тоже работает:https://dx.10086.cn/1, при посещении этой ссылки перейдите к базе данных, чтобы запросить реальный URL-адрес, а затем перенаправьте.

ЕдинственныйIDОчень просто, используйте атомарные классыAtomicLongМожно, но распределённый не получится, его можно использовать простоredis, либо база инкрементируется, либо можно рассмотретьZookeeperкакой-то тип.

стратегия преобразования идентификатора

Но прямое использование инкрементных чисел имеет два недостатка:

  • Когда число большое, оно все еще очень длинное
  • Увеличение числа, небезопасно, слишком регулярно

Очевидно, что ссылки, которые мы обычно видим, представляют собой не цифры, а обычно прописные и строчные буквы плюс цифры. Чтобы сократить длину ссылки, мы должны положитьidпреобразованы, такие как наша короткая ссылкаa-z,A-Z,0-9состав, эквивалентный62основные числа, будетidпреобразовать в62Базовые номера:

public class ShortUrl {

    private static final String BASE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public static String toBase62(long num) {
        StringBuilder result = new StringBuilder();
        do {
            int i = (int) (num % 62);
            result.append(BASE.charAt(i));
            num /= 62;
        } while (num > 0);

        return result.reverse().toString();
    }

    public static long toBase10(String str) {
        long result = 0;
        for (int i = 0; i < str.length(); i++) {
            result = result * 62 + BASE.indexOf(str.charAt(i));
        }
        return result;
    }

    public static void main(String[] args) {
        // tzHLFw
        System.out.println(toBase10("tzHLFw"));
        System.out.println(toBase62(27095455234L));
    }
}

idизменять62немногоkeyилиkeyпревратиться вidРеализовано, но расчет все равно занимает много времени, лучше добавить поле и сохранить его, чтобы база данных стала:

id key url
27095455234 tzHLFw Guangdong 10086. Can/GMC wipe PP/Web…

Но все же легко догадаться, чтоidиkeyЕсли его пройти и получить к нему доступ, это все еще очень небезопасно.Если вы беспокоитесь, вы можете случайным образом перетасовать последовательность символов короткой ссылки или добавить несколько случайно сгенерированных символов в соответствующую позицию, например, в первый1,4,5 Биты являются случайными символами, а другие позиции остаются неизменными.Пока мы сохраняем соответствующее отношение к базе данных при расчете, мы можем подключитьkeyнайти соответствующийurl. (Стоит отметить, чтоkeyДолжен быть глобально уникальным и должен быть перегенерирован в случае конфликта)

Как правило, короткие ссылки имеют срок действия, поэтому мы также должны добавить соответствующие поля в базу данных, при доступе мы сначала определяем, истек ли срок их действия, и если они истекают, то они не будут перенаправлены.

соображения производительности

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

Если системаidЧто мне делать, когда я иссякну? Эта вероятность очень мала, если это все-таки случится, то можно повторно использовать старые просроченныеidНет.

Что, если кто-то лихорадочно попросит какую-то короткую ссылку, которой не существует? По сути, это проникновение в кеш, проникновение в кеш относится к,Данные, которых нет ни в кеше, ни в базе данных, запрашивается в большом количестве, например, номер заказа не может быть-1, но пользователь запросил большое количество номеров заказов-1Поскольку данных не существует, в кеше не будет данных, и все запросы будут напрямую проникать в базу данных. Если его эксплуатируют злоумышленники и лихорадочно запрашивают несуществующие данные, это приведет к чрезмерной нагрузке на базу данных и даже к ее краху.

В этом случае вы обычно можете использовать фильтр Блума для фильтрации несуществующих запросов данных, но здесь мыidИзначально он инкрементный и упорядоченный.На самом деле наш диапазон общеизвестен,по которому проще судить.Избытка не должно быть,или при приходе запроса не проблема положить в кеш пустой объект.

【Об авторе】:
Цинь Хуай, публичный аккаунт [продуктовый магазин Циньхуай】Автор, дорога технологий не в одно время, горы высоки, а реки длинны, даже если она медленная, она продолжается и продолжается. Личное направление письма:Java源码解析,JDBC,Mybatis,Spring,redis,分布式,剑指Offer,LeetCodeПодождите, каждую статью пишите внимательно, я не люблю заголовки, не люблю прибамбасы, и большинство из них пишут серию статей, не гарантирую, что пишу полностью правильно, но гарантирую, что то, что я пишу, практиковалось или искалось для информации. За упущения или ошибки, пожалуйста, поправьте меня.

Sword Point предлагает решение всех проблем PDF

Что я написал в 2020 году?

Заметки по программированию с открытым исходным кодом