消息推送系统的设计与实现
所有真理的成长都需要经过3个阶段:首先是遭到无情地嘲笑,然后是激烈地反对,最终被当成理所当然所接受。 弹幕系统的技术挑战技术复杂度系统调用的瓶颈以一个直播间为例,假设在线人数为100W,每秒发送的弹幕数量为1000条,据此可以推算出单个直播间的吞吐量要达到100W1000条 = 10亿条/秒,把问题延伸到N个直播间,则系统的吞吐量为...
秒杀系统的设计与实现
特征与难点 写强一致性:抢购商品的时候不能出现超卖现象 读弱一致性:可能读到有库存,但是实际下单会失败 抢购人数远多于库存,读写并发巨大 库存少导致有效写少(真正形成订单的比较少) 难点在于极致性能的实现以及高可用的保证。 高并发下,某个小依赖可能直接造成雪崩 流量预估难精确,过高也造成雪崩 分布式集群,机器多,出故障的概率高 秒杀原理 合理利用 CDN:例如订单详情页,有效减少回源流量 Nginx 限流:过载保护 异步队列:高并发的流量 -> 均匀的流量 Nginx 负载均衡:接入层分摊流量到无状态 service 层提供服务 CDN原理 用户输入访问的域名,操作系统向 LocalDns 查询域名的ip地址. LocalDns向 ROOT DNS 查询域名的授权服务器(这里假设LocalDns缓存过期) ROOT DNS将域名授权dns记录回应给 LocalDns LocalDns得到域名的授权dns记录后,继续向域名授权dns查询域名的ip地址 域名授权dns查询域名记录后(一般是CNAME),回应给...
短地址服务的设计与实现
有不少网站可以提供长链转短链的服务,例如新浪短地址服务、bitly。背后的原理其实是将长链和短链进行一一映射。换而言之,通过各家短链服务商的锻炼和长链是一一对应的。其中的关键点在于如何根据长链生成短链,以及当用户访问短链后怎么处理。 如何生成短地址比较直观想到的解法是使用哈希函数,但是无论怎样构造哈希函数,都存在哈希碰撞的问题。再次想到碰撞之后可以在hash字符串后面补充其他字符串来实现,但是需要补充多少位呢?这种方案显然不是那么方便。联想到全局唯一,以及数据存储我们很容易想到数据库的自增id,其实这样也是可以的,这里为了实现简单(主要是天然的过期时间),采用了redis来存储数据,其key设计如下: globalId:全局自增id,用于保证短链的唯一性shortToLong:短地址到长地址的映射,key为短地址,可以很方便通过短地址找到长地址longToShortInfo:长链到短链的映射,如果这个键存在值就无需重复生成了. 1234567891011121314151617181920212223242526272829303132333435363738const...
面试常用套路
墨菲定理:任何事情都没有表面看起来那么简单;所有的事情都会比你预估的时间长;会出错的事情总会出错;你总是担心的事情,它总会发生的。 如何规范写日志日志要有分隔符大多数时候使用|作为分隔符。分析数据的时候直接用分隔符拆分对应的字段和属性。 123456# 正确例子类名|方法名|输入参数|输出参数# 错误例子1(不用分隔符)类名方法名输入参数输出参数# 错误例子2(用多种分隔符)类名#方法名 输入参数|输出参数 通过UUID编号来保证日志的连贯性每次请求都应该有一个唯一编号,每记录一次日志还应该有一个唯一编号。例如: 12api.ERROR: 79a8ea37dceff105|0|responseObj is error:{"return_code":"SUCCESS","return_msg":"OK"}api.ERROR:...
深入理解HashMap
原理HashMap的底层采用的散列算法是拉链法(另一种散列算法是线性探测法)。并且在JDK1.8中使用红黑树对长链表进行优化。 初始容量、负载因子、阈值初始容量比较好理解,阈值指的是当桶的个数超过了这个值后Hash表会进行扩容。 12345678910/*** The next size value at which to resize (capacity * load factor).** @serial*/// (The javadoc description is true upon serialization.// Additionally, if the table array has not been allocated, this// field holds the initial array capacity, or zero signifying// DEFAULT_INITIAL_CAPACITY.)int...
红包业务系统的构建
...
情人节有感
...
2018年年度小结
...
有趣的算法
爬虫底层的算法是广度优先搜索。 二项分布和递归问题来源于算法第四版问题1.1.27。 12345678910111213141516let count = 0;const binomial = (N, k, p) => { count++; if (count % 10000000 === 0) console.log(count); // 因为每次递归都是N-1,并且k-1,因此这种情况很难出现 if (N === 0 && k === 0) return 1; // 最终应该会调用这个if if (N < 0 || k < 0) return 0; return (1 - p) * binomial(N - 1, k, p) + p * binomial(N - 1, k - 1, p);};// 5分钟算不出来,舍弃console.time('二项分布-递归');const ret = binomial(10, 50,...
Elastic Stack 入门
常见术语 Document:存储在ES中的一些数据,存储的最小单元。表中的一行数据。是JSON object,由field组成,有数据类型,每一个文档有唯一id,拥有meta data标注文档(_source,_id等)的相关信息。 Index:具有相同结构的文档的集合。对应表。拥有自己的mapping定义,定义字段名和类型。一个集群可以有多个索引,例如nginx日志可以按照每天生成一个索引来存储。 Node:一个es的运行实例,是构成集群的基本单元 Cluster:由一个或者多个节点组成,对外提供服务 倒排索引和分词 正排索引:文档id到文档内容、单词的关联关系 倒排索引:单词到文档id的关联关系 查询流程,通过关键字从倒排索引中找到文档id,然后通过文档id使用正排索引返回所有符合条件的文档。 倒排索引是搜索引擎的核心,主要包含2部分: 单词词典(Term Dictionary):记录文档所有单词和单词到倒排列表的关联信息,一般比较大。实现方式一般是B+树 倒排列表(Posting List):包含文档id,单词词频(Term...