龙空技术网

程序员应该了解的14种常用算法

川后静波kimble 2213

前言:

此刻兄弟们对“常见算法及其应用”可能比较着重,朋友们都想要剖析一些“常见算法及其应用”的相关资讯。那么小编在网上汇集了一些关于“常见算法及其应用””的相关内容,希望我们能喜欢,大家快快来学习一下吧!

00、序言

整理了一份算法清单,这些算法对任何软件工程师来说都很容易理解。

我们最需要明白的是"这些算法如何在我们实际系统中得到应用"。

就程度来说:掌握 > 熟悉> 了解。

了解:听说过

熟悉:会用

掌握:能举一反三。

五颗星:非常重要,应该了解它是如何工作的以及为什么。即:掌握

三颗星:在某种程度上很重要,可能不需要了解具体细节。即:熟悉

一颗星:有难度,了解即可。即:了解

01、Geohash算法基本原理:

Geohash算法就是将经纬度编码,将二维变一维,给地址位置分区的一种算法,它把二维的空间经纬度数据编码成一个字符串。

实现步骤:将经纬度变成二进制。就是将经纬度合并。按照Base32进行编码。应用场景:附近的人:查询附近的用户或商家。地理围栏:检测用户是否在指定的区域内。地理位置推荐:根据用户位置推荐附近的餐厅、景点等。出租车调度:根据乘客位置和司机位置匹配。02、四叉树Quadtree基本原理:

四叉树(QuadTree)是一棵包含树根(Root)的树,它的每个内部结点都有4个子结点。树中的每个结点都对应一个正方形。

是将空间区域按照四个象限进行递归分割( 2n × 2n ,且 n ≥ 1 ),直到子象限的数值单调为止。

凡数值(特征码或类型值)呈单调的单元, 不论单元大小,均作为最后的存储单元。

这样,对同一种空间要素,其区域网格的大小,随该要素分布特征而不同。

实现步骤:将当前二维空间分成四个方框。如果一个框中包含一个或多个点,则创建一个子对象,在其中存储该框的二维空间如果一个框不包含任何点,不要为其创建子框为每个孩子重复。应用场景:用于图像压缩,其中每个节点包含其每个子节点的平均颜色。在树中遍历得越深,图像的细节就越多。也用于搜索二维区域中的节点。例如,如果你想找到离给定坐标最近的点,你可以使用四叉树。03、一致性哈希算法(consistent hashing)基本原理:

一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。

一致性Hash算法是一种hash算法,它能够在Hash输出空间发生变化时,引起最小的变动。

实现步骤:

第1步、建立hash环形空间

第2步、服务器hash计算

第3步、对象hash计算

应用场景:

增加或者移除一台服务器时,对原有的服务器和用户之间的映射关系产生的影响最小。

04、漏桶算法(Leaky Bucket)基本原理:

漏桶算法(Leaky Bucket Algorithm)是一种用于流量控制和限流的经典算法。

将请求放入一个有固定容量的“桶”中,桶内的请求以固定速率传出。当桶满时,新进入的请求将被丢弃。漏桶算法可以保证处理请求的速率恒定,从而有效防止流量激增导致的服务不稳定。

实现步骤:漏桶由一个有限长度的FIFO队列组成。当一个请求到达时,如果队列中有空间,它就被附加到队列中;否则它将被拒绝。队列的另一端,则以一个恒定的速率漏出/放行请求。应用场景:保护后端服务免受大流量冲击,避免服务崩溃。对 API 调用进行限制,保证公平使用。稳定处理速率,避免流量激增。适用于对处理速率有严格要求的场景。05、令牌桶(token bucket)基本原理:

令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。

系统会以一个恒定的速度往桶里放入固定数量的令牌,而如果请求需要被处理,则需要先从桶里获取对应令牌,当桶里没有令牌可取时,则拒绝服务。

实现步骤:算法使用一个固定容量的桶。只要桶不满,系统就以一个恒定的速率(比如每秒)向桶中添加令牌。当请求到来时,就从桶中拿走1个或多个令牌,若没有可用令牌,就拒绝该请求。应用场景:

适用于电商抢购、热点事件等场景。

06、字典树(Trie)基本原理:

Trie 是一种基于键(key)的哈希树,用于快速检索和查找字符串数据集中的键(例如单词,URL 等)。

利用字符串之间的公共前缀,将它们存储在树形结构中。每个节点代表一个字符串的字符,从根节点到叶子节点的路径表示一个完整的字符串。对于每个节点,它的子节点根据不同的字符值分别存储。因此,每个节点最多有与字符集大小相等的子节点。

实现步骤:

字典树的构造其实较为简单,和一般树的构造没有太大区别。

应用场景:

单词自动补全、字符串匹配、IP 地址路由、前缀匹配查找等等

07、同步算法(Rsync)基本原理:

Rsync 算法是 Andrew Tridgell 和 Paul Mackerras 在 1998 年提出的一种远程差异文件同步算法。

实现增量传输的主要过程,就是差异检测和差异数据组织及传输,前者是rsync增量传输算法的核心。

实现步骤:主机 β 将文件 B 划分为连续的不重叠的长度为 S 字节的定长数据块,最后一个数据块长度可能小于 S 。针对每个数据块主机 β 为它们计算一个弱滚动校验和以及一个强校验和(MD5)。主机 β 将校验和信息发送给主机 α 。主机 α 针对文件 A 每个偏移位置查找与文件 B 具有相同强弱校验值的数据块。通过滚动校验和算法可以在单次扫描过程中快速地完成此操作。主机 α 发送构建指令给主机 β 构建文件 A 的副本。每个构建指令不是文件 B 的数据块索引就是文件原始数据。文件原始数据只有在文件 A 没有匹配到文件 B 中的数据块才会发送。应用场景:

文件增量同步

08、分布式一致性算法(Paxos 和 Raft 算法)基本原理:

Paxos和Raft算法都是分布式一致性算法,它们的目的都是在一个分布式系统中保证数据的一致性

应用场景:

在一个分布式系统中,由于各个节点之间的网络延迟、节点故障等原因,数据同步可能会出现问题,这时候就需要使用一致性算法来保证数据的一致性。

09、布隆过滤器(Bloomfilter)基本原理:

布隆过滤器的主要原理是使用一组哈希函数,将元素映射成一组位数组中的索引位置。当要检查一个元素是否在集合中时,将该元素进行哈希处理,然后查看哈希值对应的位数组的值是否为1。如果哈希值对应的位数组的值都为1,那么这个元素可能在集合中,否则这个元素肯定不在集合中。

实现步骤:将要添加的元素给k个哈希函数得到对应于位数组上的k个位置将这k个位置设为1应用场景:

网页爬虫对URL去重、反垃圾邮件、缓存穿透

10、梅克尔树(Merkle tree)基本原理:

梅克尔树(Merkle trees)是区块链的基本组成部分。梅克尔树是一种二叉树,能快速检查和归纳大量数据,可用于验证区块中交易记录的完整性。

应用场景:构建区块头时会维护一个 MerkleTree 根使用 SPV 钱包,验证区块数据作为数据结构,生成Neo区块的stateRoot,以便在跨链、轻节点等场景中, 用以快速校验区块的有效性11、基数统计HyperLogLog基本原理:

HyperLogLog是用来做基数统计的。

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

应用场景:

HyperLogLog可以非常省内存的去统计各种计数,比如注册ip数、每日访问IP数、页面实时UV(PV肯定字符串就搞定了)、在线用户数等在对准确性不是很重要的应用场景。

12、计数(Count-min sketch)基本原理:

Count-min Sketch算法是一个可以用来计数的算法,在数据大小非常大时,一种高效的计数算法,通过牺牲准确性提高的效率。

实现步骤:

创建一个长度为 x 的数组,用来计数,初始化每个元素的计数值为 0;

对于一个新来的元素,哈希到 0 到 x 之间的一个数,比如哈希值为 i,作为数组的位置索引;

这时,数组对应的位置索引 i 的计数值加 1;

那么,这时要查询某个元素出现的频率,只要简单的返回这个元素哈希望后对应的数组的位置索引的计数值即可。

应用场景:

海量数据下,如何快速获取给定年龄区间的微信用户数量?

13、多级时间轮(Hierarchical timing wheels)基本原理:

时间轮(Timing Wheel)是George Varghese和Tony Lauck在1996年的论文'Hashed and Hierarchical Timing Wheels: data structures to efficiently implement a timer facility'实现的,它在Linux内核中使用广泛,是Linux内核定时器的实现方法和基础之一。

实现步骤:时间轮在创建时需要指定调度精度,即时间轮内部逻辑上1次tick的间隔。维护一个桶数组,由于不同超时时间的任务可能会被映射到同一个桶中,因此数组桶中维护一个指向某一列表的指针(引用)。创建新计时器时,对于任意超时时间的任务基于tick间隔进行哈希,计算出需要存入的对应数组桶的下标(第100纳秒和第999999纳秒超时的计时器,都放入第0个桶)并插入对应桶的列表中。维护一个当前时间指针,指向某一个数组桶。每1次tick处理时,推动该指针,令其指向下一个tick对应的桶,并将桶指向的列表中的全部任务取出,丢到一个线程池中异步处理。应用场景:

海量定时任务方案

14、协同算法(Operational transformation)实现步骤:定义原子操作类型:将用户在UI上触发的基于Event的操作抽象成由可枚举的N个原子操作类型组成的操作序列。设计冲突解决算法:在冲突问题发生时,通过冲突解决算法解决冲突。多端冲突解决:通过向各端同步新的可串行操作序列完成冲突解决应用场景:

应用于协同编辑领域的并发控制和冲突解决系统,要解决的是“多个用户对同一个文本域的同一个版本进行编辑时如何处理”的问题。

标签: #常见算法及其应用