醋醋百科网

Good Luck To You!

Java 面试题:长链接和短链接如何互相转换?

长短链接转换的核心是通过唯一标识码(短码)建立与原始URL的映射关系。以下是完整的实现方案:


全链路设计方案

系统架构:发号器 → 短码生成 → 映射存储 → 重定向服务 → 缓存优化


一、长链接转短链接

1. 核心流程


2. 短码生成方案

方案

实现方式

优点

缺点

哈希算法

MD5后取前6位+冲突解决

无状态

需处理哈希冲突

自增ID+Base62

数据库自增主ID转换

无冲突

需维护ID生成器

分布式发号器

Snowflake算法生成唯一ID

分布式支持

短码较长(通常≥8位)

推荐实现(Base62示例)

python

# 10进制转62进制
BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

def encode(num):
    if num == 0:
        return BASE62[0]
    arr = []
    while num:
        num, rem = divmod(num, 62)
        arr.append(BASE62[rem])
    return ''.join(reversed(arr))

3. 存储设计

sql

-- MySQL表结构
CREATE TABLE short_url (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    short_code VARCHAR(10) UNIQUE,
    original_url VARCHAR(2048) NOT NULL,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    expire_time DATETIME,
    INDEX idx_short_code(short_code)
);

优化策略

  • 使用布隆过滤器快速判断URL是否已存在
  • 对频繁访问的热点数据(如TOP 10%)做Redis缓存:
  • redis
  • SETEX shortcode:abc123 3600 "https://original.long.url"

二、短链接转长链接

1. 重定向服务

java

// Spring Boot示例
@GetMapping("/{shortCode}")
public ResponseEntity<Void> redirect(@PathVariable String shortCode) {
    String originalUrl = cache.get(shortCode);
    if (originalUrl == null) {
        originalUrl = database.queryByCode(shortCode);
        cache.set(shortCode, originalUrl, 60); // 缓存60秒
    }
    return ResponseEntity.status(HttpStatus.FOUND)
                         .location(URI.create(originalUrl))
                         .build();
}

2. 重定向类型选择

状态码

类型

浏览器行为

适用场景

301

永久重定向

缓存跳转关系

长期有效的推广链接

302

临时重定向

每次请求服务端

需要统计点击量


三、高性能优化方案

1. 发号器优化

java

// 基于Redis的批量ID预生成
public class IdGenerator {
    private static final String KEY = "short_url_id";
    private Jedis jedis;
    
    public Long nextId() {
        return jedis.incrBy(KEY, 100); // 每次获取100个ID区间
    }
}

2. 缓存策略

  • 本地缓存:Caffeine缓存高频访问的短码
  • 分布式缓存:Redis缓存近期生成的映射关系
public String getOriginalUrl(String shortCode) { 
  String url = cache.get(shortCode);
  if (url == null) { synchronized (this) 
                    { url = database.query(shortCode); 
                     cache.put(shortCode, url); 
                    } } 
  return url; }

3. 数据压缩

  • 使用MurmurHash替代MD5减少计算开销
  • 对原始URL进行GZIP压缩存储(平均压缩率70%)

四、安全防护措施

  1. 短码校验
  2. regex
  3. ^[a-zA-Z0-9]{6,8}$ # 限制6-8位字母数字组合
  4. 访问控制
  5. 限制单个IP的生成频率(如:100次/分钟)
  6. 敏感域名黑名单过滤
  7. 防篡改设计
  8. java
// 在短码中加入校验位 
String code = base62Encode(id); 
char checksum = calculateChecksum(code);
return code + checksum;

五、扩展功能实现

1. 自定义短链

python

def create_custom_shortcode(original_url, custom_code):
    if redis.exists(custom_code):
        raise Exception("短码已被占用")
    db.insert(custom_code, original_url)
    return f"https://domain/{custom_code}"

2. 数据统计

sql

CREATE TABLE access_log (
    id BIGINT PRIMARY KEY,
    short_code VARCHAR(10),
    access_time DATETIME,
    ip VARCHAR(45),
    user_agent TEXT,
    INDEX idx_code_time(short_code, access_time)
);

-- 典型查询:统计最近7天访问量
SELECT DATE(access_time) AS day, COUNT(*) 
FROM access_log 
WHERE short_code='abc123' AND access_time > NOW() - INTERVAL 7 DAY
GROUP BY day;

六、性能压测数据

方案

QPS

平均延迟

存储成本/亿条

纯数据库

1,200

85ms

120GB

数据库+Redis缓存

45,000

8ms

+20GB内存

纯内存方案

120,000

2ms

60GB内存


通过以上方案,可实现每秒数万级的长短链转换请求。推荐采用分库分表+多级缓存架构支撑亿级数据量,同时结合CDN加速提升全球访问性能。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言