What is an idempotent operation?
什么是等幂运算?
在计算中,如果使用相同的输入参数多次调用等幂运算,则等幂运算没有额外的效果。例如,从集合中移除项可以被视为集合上的等幂运算。
在数学中,等幂运算是f(f(x))=f(x)的运算。例如,
考虑到数学定义中的x代表一个对象的状态,并且f是一个可能使该对象发生变化的操作,可以调和这些稍有不同的定义。例如,考虑python
1 | my_set.discard(x) |
与两次相同的操作效果完全相同:
1 2 | my_set.discard(x) my_set.discard(x) |
等幂运算通常用于网络协议的设计,在这种情况下,执行一个操作的请求保证至少发生一次,但也可能发生多次。如果操作是等幂的,那么在执行两次或两次以上的操作时不会有任何伤害。
有关更多信息,请参阅维基百科关于等幂的文章。
上述答案之前有一些错误和误导性的例子。以下在2014年4月之前所写的评论指的是旧版本。
一个幂等运算可以重复任意次数,结果将与仅做一次的结果相同。在算术中,数字加零是等幂的。
在"RESTful"Web服务的上下文中,关于等幂性的讨论很多。REST试图最大限度地利用HTTP来让程序访问Web内容,并且通常与基于SOAP的Web服务不同,后者只在HTTP请求和响应中隧道化远程过程调用样式的服务。
REST将Web应用程序组织为"资源"(如Twitter用户或Flickr图像),然后使用Post、Put、Get和Delete的HTTP谓词来创建、更新、读取和删除这些资源。
等幂性在休息中起着重要作用。如果您获得了一个REST资源的表示(例如,从Flickr获取一个jpeg图像),并且操作失败,您可以一次又一次地重复get,直到操作成功。对于Web服务来说,获取多少次图像并不重要。同样,如果您使用一个RESTful Web服务来更新您的Twitter帐户信息,您可以尽可能多次地放置新信息,以便从Web服务获得确认。把它放一千次和把它放一次是一样的。同样,将一个REST资源删除一千次与删除一次相同。因此,等幂性使得构建一个能够抵御通信错误的Web服务变得容易得多。
进一步阅读:由Richardson和Ruby撰写的RESTful Web服务(第103-104页讨论了等幂性),以及RoyFielding关于REST的博士论文。菲尔丁是HTTP1.1,RFC-2616的作者之一,该书在第9.1.2节中讨论了等幂性。
无论您调用操作多少次,结果都是相同的。
等幂意味着一次应用一个操作或多次应用它具有相同的效果。
实例:
- 乘以零。不管你做了多少次,结果仍然是零。
- 设置布尔标志。无论你做了多少次,旗子都会保持不变。
- 从具有给定ID的数据库中删除行。如果再试一次,该行仍将不存在。
对于纯函数(无副作用的函数),则幂次意味着f(x)=f(f(x))=f(f(f(x)))=f(f(f(x)))=f(f(f(x)))=……对于x的所有值
对于有副作用的函数,等幂性还意味着在第一次应用之后不会产生额外的副作用。如果您愿意,可以将世界状态视为函数的附加"隐藏"参数。
注意,在一个同时进行操作的世界中,您可能会发现您认为是等幂运算的操作不再是等幂运算(例如,另一个线程可能会取消设置上述示例中布尔标志的值)。基本上,当您有并发性和可变状态时,您需要更仔细地考虑等幂性。
在建立鲁棒系统中,等幂性通常是一个有用的性质。例如,如果存在可能从第三方收到重复消息的风险,那么让消息处理程序充当等幂运算有助于使消息效果只发生一次。
一个等幂运算在相同的状态下产生结果,即使你多次调用它,只要你传递相同的参数。
只是想抛出一个证明了等幂性的真实用例。在JavaScript中,假设您正在定义一组模型类(如在MVC模型中)。这种实现方式在功能上与以下类似(基本示例):
1 2 3 4 5 6 7 | function model(name) { function Model() { this.name = name; } return Model; } |
然后您可以这样定义新类:
1 2 | var User = model('user'); var Article = model('article'); |
但是,如果您试图通过
1 2 3 | var User = model('user'); // ... then somewhere else in the code (in a different scope) var User = model('user'); |
这两个
1 | model('user') !== model('user'); |
为了使其等幂,您只需添加某种缓存机制,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 | var collection = {}; function model(name) { if (collection[name]) return collection[name]; function Model() { this.name = name; } collection[name] = Model; return Model; } |
通过添加缓存,每次执行
1 | model('user') === model('user'); |
等幂运算是一种操作、操作或请求,可以多次应用,而不改变初始应用之外的结果,即系统状态。
示例(Web应用上下文):
NULLIPOTENT:如果一个操作没有任何副作用,比如仅仅在网页上显示信息而数据库没有任何变化(换句话说,您只是在读取数据库),那么我们认为该操作是无效的。一切都是无效的。否则,使用post。
幂等元:电子邮件消息系统中的消息将在数据库中打开并标记为"已打开"。可以多次打开消息,但重复的操作只会导致该消息处于"打开"状态。这是一个等幂运算。
非等幂的:如果一个操作总是导致状态的改变,比如一遍又一遍地向用户发送相同的消息,每次都会导致一条新消息被发送并存储在数据库中,那么我们就说这个操作是非等幂的。
当谈到系统的状态时,我们显然忽略了一些无害的和不可避免的影响,比如日志记录和诊断。
相当详细和技术性的回答。只是添加一个简单的定义。
Idempotent = Re-runnable
例如,如果执行多次,
等幂运算:如果多次执行就没有副作用的运算。< BR>示例:从数据资源中检索值并说打印该值的操作
BR/>非等幂运算:如果多次执行会造成一定伤害的运算。(当它们改变某些值或状态时)< BR>示例:从银行帐户中提取的操作
集合上的等幂运算在应用一次或多次时使其成员保持不变。
它可以是一元运算,如绝对(x),其中x属于一组正整数。这里是绝对的(绝对的(x))=x。
它可以是一个二进制运算,就像集合本身的集合总是返回相同的集合一样。
干杯
每个第n个结果都将导致与第一个结果的值匹配的输出的任何操作。例如-1的绝对值是1。绝对值-1的绝对值是1。绝对值-1的绝对值的绝对值为1。等等。
另请参见:什么时候使用递归才是真正愚蠢的?
简而言之,等幂运算意味着无论您操作等幂运算多少次,操作都不会产生不同的结果。
例如,根据HTTP规范的定义,
我的5C:在集成和网络中,等幂性非常重要。现实生活中的几个例子:想象一下,我们向目标系统交付数据。由一系列消息传递的数据。1。如果序列在通道中混合会发生什么?(网络包总是这样做:)如果目标系统是幂等的,则结果不会是不同的。如果目标系统依赖于序列中的正确顺序,则必须在目标站点上实现ReSeCeNeReR,这将恢复正确的顺序。2。如果有消息副本会发生什么?如果目标系统的信道不及时应答,则源系统(或信道本身)通常发送消息的另一副本。因此,我们可以在目标系统侧有重复的消息。如果目标系统是幂等的,它会处理它,结果不会是不同的。如果目标系统不是幂等的,我们必须在信道的目标系统侧实现去重复制器。
重试安全。
通常是理解它在计算机科学中的意义的最简单的方法。