一个基本的思路
-
唯一性:短URL不能重复。 -
性能:百亿级规模得扛得住。
-
唯一性问题怎么解决?可以用数据库加唯一索引,但百亿量级就需要更高效的办法,比如使用分布式系统中的分布式ID生成策略。 -
短URL怎么“短”起来?这可以用Base62编码(大小写字母加数字,共62个字符),把长URL的ID压缩成短URL。
-
把长URL的原始ID取出来。 -
用Base62编码压缩成短字符串。 -
检查是否冲突,如果冲突就得处理,比如重新生成。
基础代码实现
private static final String CHAR_SET = “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789”;
private static final int BASE = CHAR_SET.length();
private Map<Long, String> urlMap = new HashMap<>();
private Map<String, Long> reverseMap = new HashMap<>();
private long idCounter = 1;
// 长URL -> 短URL
public String shorten(String longUrl) {
long id = idCounter++;
StringBuilder shortUrl = new StringBuilder();
while (id > 0) {
shortUrl.append(CHAR_SET.charAt((int) (id % BASE)));
id /= BASE;
}
String result = shortUrl.reverse().toString();
urlMap.put(idCounter, longUrl);
reverseMap.put(result, idCounter);
return result;
}
// 短URL -> 长URL
public String retrieve(String shortUrl) {
Long id = reverseMap.get(shortUrl);
return id == null ? null : urlMap.get(id);
}
}
百亿级的难点:高并发 + 无冲突
1. 分布式ID生成器
-
每个服务器分配唯一的机器ID,生成ID时把时间戳、机器ID和序列号拼起来。 -
优点是快速且唯一,生成ID后直接Base62编码就能用了。
2. 数据库设计
-
用Redis缓存热门的短URL。 -
用NoSQL(比如MongoDB)存储大量数据,减少传统SQL数据库的瓶颈。 -
数据库中可以加唯一约束,避免冲突。
3. Hash碰撞的处理
这位程序员为啥翻车?
-
没准备场景题:有些人习惯了写CRUD,一问到系统设计就迷糊,觉得“我不是架构师,我只写业务代码”。但场景题是考察工程师是否有全局视野,懂得如何应对复杂业务需求。 -
对分布式系统不熟:百亿级别的数据量,一般涉及分布式架构、缓存、多机协调等。程序员如果没接触过这些,就很难回答得漂亮。 -
临场表现差:也许他其实懂,但一紧张脑袋空白了。这种情况也不少见,谁让面试环境就像高压锅呢?
怎么准备场景题?
-
明确需求:比如短URL生成器,考点是“高性能”和“唯一性”,你得先指出这些需求,然后再答如何实现。 -
提出技术选型:别一上来就写代码,先说出思路,比如“我会用分布式ID生成器”“存储用NoSQL”。 -
展示扩展性思维:比如,能不能做成可扩展架构?能不能支持多语言平台调用?
微信赞赏支付宝扫码领红包
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。侵权投诉:375170667@qq.com