如何生成短連接

這也是一道leetcode的題目html

leetcode.com/problems/en…java

leetcode-cn.com/problems/en…數據庫

描述

生成短連接.後端

思路

若是僅僅是作題,那麼其實有不少辦法.瀏覽器

在實際中,應該使用分佈式發號器(Distributed ID Generator)緩存

64位的整數能表示的範圍184467440737億遠遠大於全球網頁數量45億。來一個長網址,就分配一個ID去生成短網址.服務器

並且這樣能夠支持一個長網址對應多個短網址。通常而言,一個長網址,在不一樣的地點,不一樣的用戶等狀況下,生成的短網址應該不同,這樣,在後端數據庫中,能夠更好的進行數據分析。app

爲了方便轉化爲字符串,通常使用62進制,字符串的一位能夠是大小寫字母加數字共62個字母.分佈式

通常採用一個7位的字符串,62^7=3521614606208627=35216億.性能

其餘的辦法大概還有取HASH值的前N位,碰撞,不重複就爲短網址.這樣性能不高。

代碼

public class EncodeAndDecodeTinyURL {

    Map<String, String> map = new HashMap<>();

    long index = 10000; // 這裏是模擬一個當前計數值.
    private static String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static int scale = 62;

    // Encodes a URL to a shortened URL.
    public String encode(String longUrl) {

        String tinyUrl = indexToStr(index, 7);
        map.put(tinyUrl, longUrl);
        return tinyUrl;
    }

    public String indexToStr(long num, int length) {
        StringBuilder sb = new StringBuilder();
        int remainder = 0;

        while (num > scale - 1) {
            /** * 對 scale 進行求餘,而後將餘數追加至 sb 中,因爲是從末位開始追加的,所以最後須要反轉(reverse)字符串 */
            remainder = Long.valueOf(num % scale).intValue();
            sb.append(chars.charAt(remainder));

            num = num / scale;
        }

        sb.append(chars.charAt(Long.valueOf(num).intValue()));
        String value = sb.reverse().toString();

        while (value.length() < length) {
            value = "0" + value;
        }
        return value;


    }

    // Decodes a shortened URL to its original URL.
    public String decode(String shortUrl) {
        return map.get(shortUrl);
    }

    public static void main(String[] args) {
        EncodeAndDecodeTinyURL codec = new EncodeAndDecodeTinyURL();
        codec.decode(codec.encode("https://leetcode.com/problems/design-tinyurl"));
    }
複製代碼

其餘

如下內容出自武林的回答

如何存儲

若是存儲短網址和長網址的對應關係?以短網址爲 primary key, 長網址爲value, 能夠用傳統的關係數據庫存起來,例如MySQL,PostgreSQL,也能夠用任意一個分佈式KV數據庫,例如Redis, LevelDB。 若是你手癢想要手工設計這個存儲,那就是另外一個話題了,你須要完整地造一個KV存儲引擎輪子。當前流行的KV存儲引擎有LevelDB何RockDB,去讀它們的源碼。

301仍是302重定向

這也是一個有意思的問題。這個問題主要是考察你對301和302的理解,以及瀏覽器緩存機制的理解。 301是永久重定向,302是臨時重定向。短地址一經生成就不會變化,因此用301是符合http語義的。可是若是用了301, Google,百度等搜索引擎,搜索的時候會直接展現真實地址,那咱們就沒法統計到短地址被點擊的次數了,也沒法收集用戶的Cookie, User Agent 等信息,這些信息能夠用來作不少有意思的大數據分析,也是短網址服務商的主要盈利來源。因此,正確答案是302重定向。

預防攻擊

若是一些別有用心的黑客,短期內向TinyURL服務器發送大量的請求,會迅速耗光ID,怎麼辦呢?
首先,限制IP的單日請求總數,超過閾值則直接拒絕服務。光限制IP的請求數還不夠,由於黑客通常手裏有上百萬臺肉雞的,IP地址大大的有,因此光限制IP做用不大。
能夠用一臺Redis做爲緩存服務器,存儲的不是 ID->長網址,而是 長網址->ID,僅存儲一天之內的數據,用LRU機制進行淘汰。這樣,若是黑客大量發同一個長網址過來,直接從緩存服務器裏返回短網址便可,他就沒法耗光咱們的ID了。

參考

youzhixueyuan.com/how-to-gene…

相關文章
相關標籤/搜索