forked from rbmonster/learning-note
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
672 additions
and
126 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# 短连接设计 | ||
|
||
相关文章: | ||
- https://github.com/soulmachine/system-design/blob/master/cn/tinyurl.md | ||
- https://github.com/xitu/system-design-primer/blob/translation/solutions/system_design/pastebin/README-zh-Hans.md | ||
- https://www.cnblogs.com/rickiyang/p/12178644.html | ||
- https://www.zhihu.com/question/20103344/answer/573638467 | ||
- https://segmentfault.com/a/1190000006140476 | ||
|
||
## 确定问题的范围 | ||
1. 数据量,增长数据量。 | ||
2. 链接过期时间设置。 | ||
3. 使用数据库或不使用数据库保存。 | ||
|
||
|
||
## 短链接设计 | ||
### 使是否使用数据库 | ||
使用数据库,可以收集数据,进而再进行数据分析。而不适用数据库纯粹只是生成短连接服务。 | ||
|
||
### 确定短连接长度 | ||
1. 使用大小写字母+数字的62进制方案,取6~8位便可以支持上亿的不同短连接 | ||
|
||
62^6 = 568,00235584 | ||
62^7 = 35216,14606208 | ||
|
||
2. 使用32进制小写字母+数字 36位 | ||
36^8 = 3w亿 | ||
|
||
|
||
### 方案一: 摘要算法 | ||
|
||
#### 单使用md5加密 | ||
使用MD5 摘要算法进行长URL加密(分为16位和32位),获取前8个字符,当成短连接地址。 | ||
##### hash冲突 | ||
1. 加密后,必定会出现hash冲突的情况,可以对原有的url进行加减字符重新加密。或者对于加密后的md5再次md5加密。 | ||
2. 使用url+时间戳生成,生成失败后获取新的时间戳生成。 | ||
|
||
#### 混合使用MD5 与 base 62 | ||
1. 使用 MD5 来哈希用户的 IP 地址 + 时间戳 | ||
- MD5 是一个普遍用来生成一个 128-bit 长度的哈希值的一种哈希方法 | ||
2. 用 Base 62 编码 MD5 哈希值 | ||
- 对于 urls,使用 Base 62 编码 [a-zA-Z0-9] 是比较合适的, 对于每一个原始输入只会有一个 hash 结果,Base 62 是确定的(不涉及随机性) | ||
> Base 64 是另外一个流行的编码方案,但是对于 urls,会因为额外的 + 和 - 字符串而产生一些问题 | ||
|
||
### 方案二:使用UUID的发号器方案 | ||
|
||
使用如雪花主键的UUID当成长链接对应的键, | ||
|
||
|
||
### 数据库映射 | ||
加密后,存储数据库根据数据纬度讨论长链接与短链接的映射关系。 | ||
1. 若长链接需要区分分享的用户,地点,时间等信息,长链接与短链接以1对多的方式存储。可用于后序的数据分析。 | ||
2. 若长连接无需区分用户的类型,可直接公用相同的短链接。如何建立映射关系可见下方: | ||
- 可选的方案为,使用LRU或者Redis带过期时间的Hash,来进行数据映射。 | ||
|
||
|
||
## 短链接跳转,301还是302重定向 | ||
这个问题主要是考察你对301和302的理解,以及**浏览器缓存**机制的理解。 | ||
|
||
301是永久重定向,302是临时重定向。短地址一经生成就不会变化,所以用301是符合http语义的。但是如果用了301, Google,百度等搜索引擎,搜索的时候会直接展示**真实地址**(即短链接对应的长连接地址,浏览器缓存),那我们就无法统计到短地址被点击的次数了,也无法收集用户的Cookie, User Agent 等信息,这些信息可以用来做很多有意思的大数据分析,也是短网址服务商的主要盈利来源。 | ||
|
||
所以,正确答案是302重定向。 | ||
|
||
|
||
## 数据库设计 | ||
|
||
使用shortlink 当成组件 | ||
``` | ||
shortlink char(7) NOT NULL | ||
expiration_length_in_minutes int NOT NULL | ||
created_at datetime NOT NULL | ||
paste_path varchar(255) NOT NULL | ||
PRIMARY KEY(shortlink) | ||
``` | ||
|
||
### 分库分表 | ||
由于短链接可直接做进制转换,并具有唯一性 | ||
|
||
使用短连接作为sharding key,进行水平分库拆分。 | ||
|
||
另外可以基于一季度做数据归档。 | ||
|
||
### 读写分离 | ||
|
||
|
||
## 预防攻击 | ||
1. 频繁生成短链接的 使用ip黑名单屏蔽。 | ||
2. 使用redis建立长连接->ID 的缓存。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
src/main/java/com/learning/basic/CONCURRENT_APPLICATION.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Java并发应用 | ||
|
||
## 生产者与消费者模型 | ||
|
||
|
||
|
||
## 线程安全的类定义 | ||
1. 无状态的类:没有任何成员变量的类,如无任何方法的枚举类型。 | ||
2. 让类不可变 | ||
1. 加final关键字 | ||
2. 不提供修改成员变量,也不提供获取成员变量方法 | ||
3. 使用volatile,保证类的可见性,不能保证线程安全。适合一写多读的场景 | ||
4. 加锁和CAS,使用synchronized、lock、原子变量AtomicInteger等 | ||
1. 如StringBuffer 修改的方法都使用synchronize修饰。 | ||
2. 如concurrentHashMap 使用自旋加CAS修改。 | ||
3. 使用Atomic包的基本类型,如AtomicInteger、AtomicReference、AtmoicStampReference修饰变量。 | ||
|
||
|
||
## 单订单重复退款请求 | ||
1. synchronize修饰退款方法。 | ||
2. 缩小synchronize锁范围,使用对象锁。对象锁,创建弱引用的一个订单ID对象,放到同一的锁对象资源池中。 | ||
- 清理锁对象可以使用守护线程的方法,基于Unsafe的包操作去清除。 | ||
3. 分布式应用,使用分布式锁来处理。 | ||
|
||
|
||
### 分布式锁的处理方案 | ||
|
||
1. 数据库锁,数据库乐观锁,数据库悲观锁。 | ||
|
||
2. redis 锁 或者 ZooKeeper锁 | ||
|
||
3. 使用消息队列顺序消费,保证不重复退款 |
Oops, something went wrong.