最爛的回答
實現(xiàn)一個算法,將長地址轉(zhuǎn)成短地址。實現(xiàn)長和短一一對應(yīng)。然后再實現(xiàn)它的逆運算,將短地址還能換算回長地址。
這個回答看起來挺完美的,然后候選人也會說現(xiàn)在時間比較短,如果給我時間我去找這個算法就解決問題了。但是稍微有點計算機(jī)或者信息論常識的人就能發(fā)現(xiàn),這個算法就跟永動機(jī)一樣,是永遠(yuǎn)不可能找到的。即使我們定義短地址是100位。那么它的變化是62的100次方。62=10數(shù)字+26大寫字母+26小寫字母。無論這個數(shù)多么大,他也不可能大過世界上可能存在的長地址。所以實現(xiàn)一一對應(yīng),本身就是不可能的。
再換一個說法來反駁,如果真有這么一個算法和逆運算,那么基本上現(xiàn)在的壓縮軟件都可以歇菜了,而世界上所有的信息,都可以壓縮到100個字符。這~可能嗎。
另一個很爛的回答
和上面一樣,也找一個算法,把長地址轉(zhuǎn)成短地址,但是不存在逆運算。我們需要把短對長的關(guān)系存到DB中,在通過短查長時,需要查DB。
怎么說呢,沒有改變本質(zhì),如果真有這么一個算法,那必然是會出現(xiàn)碰撞的,也就是多個長地址轉(zhuǎn)成了同一個短地址。因為我們無法預(yù)知會輸入什么樣的長地址到這個系統(tǒng)中,所以不可能實現(xiàn)這樣一個絕對不碰撞的hash函數(shù)。
比較爛的回答
那我們用一個hash算法,我承認(rèn)它會碰撞,碰撞后我再在后面加1,2,3不就行了。
ok,這樣的話,當(dāng)通過這個hash算法算出來之后,可能我們會需要做btree式的大于小于或者like查找到能知道現(xiàn)在應(yīng)該在后面加1,2,或3,這個也可能由于輸入的長地址集的不確定性。導(dǎo)致生成短地址時間的不確定性。同樣爛的回答還有隨機(jī)生成一個短地址,去查找是否用過,用過就再隨機(jī),如此往復(fù),直到隨機(jī)到一個沒用過的短地址。
正確的原理
上面是幾種典型的錯誤回答,下面咱們直接說正確的原理。
正確的原理就是通過發(fā)號策略,給每一個過來的長地址,發(fā)一個號即可,小型系統(tǒng)直接用mysql的自增索引就搞定了。如果是大型應(yīng)用,可以考慮各種分布式key-value系統(tǒng)做發(fā)號器。不停的自增就行了。
幾個子問題
1. 62進(jìn)制如何用數(shù)據(jù)庫或者KV存儲來做?
其實我們并不需要在存儲中用62進(jìn)制,用10進(jìn)制就好了。比如第10000個長地址,我們給它的短地址對應(yīng)的編號是9999,我們通過存儲自增拿到9999后,再做一個10進(jìn)制到62進(jìn)制的轉(zhuǎn)換,轉(zhuǎn)成62進(jìn)制數(shù)即可。這個10~62進(jìn)制轉(zhuǎn)換,你完全都可以自己實現(xiàn)。