当您说某个特定框架是“异步”、“非阻塞”和“事件驱动”时,请确保您使用的是正确的词。当您的同事将某事描述为非阻塞异步I/O时,这意味着什么?是否可以使用阻塞异步I/O?如果不是,非阻塞和异步是同一回事吗?在本文中,我将解释这些(以及许多其他)常用(经常被误用)的软件工程术语和用法的正确含义。并发与并行执行并发-重叠执行或时间切片。并发性是一种编程属性,即使对于单核计算机也可能出现。并行性——同时执行。这是执行硬件的一个属性,其中任务实际上是同时执行的。同步与异步同步-在同步操作的情况下,发起操作的一方必须等待操作完成。异步——在异步操作中,发起者不需要等待操作完成。无需等待对方的结果就可以进行下一步。稍后可以通过某种其他机制检测到操作的完成。这个概念可以应用于编程以外的其他领域。电子邮件是异步通信的一个例子,而电话交谈是同步的。阻塞与非阻塞这是一个编程概念,与您编写代码的方式有关(不同于同步与异步)。如果函数调用立即返回一个值,则称为非阻塞。在某些情况下,例如I/O,函数的逻辑完成结果不是立即可用的。但是,它返回对占位符的引用,该值稍后可用。例如,Java期货。以下函数会立即返回,即使该值仅在10秒后可用。publicFuturecalculate(Integerinput){returnexecutor.submit(()->{Thread.sleep(10000);returninput*input;});}异步函数调用不能阻塞。根据上下文,非阻塞和异步可能意味着也可能不同。尽管电子邮件通信是异步的,但将电子邮件称为非阻塞调用没有任何意义。命令式与声明式编程风格声明式编程是一种编程范例,用于表达计算逻辑(做什么)而不描述其控制流(如何做)。例如SQL命令。命令式编程是一种编程范例,它根据改变程序状态的语句来描述计算。下面的示例循环遍历数字1到10并找到偶数。ListnumbersOneThroughTen=newArrayList<>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));//使用英制编程,我们将逐步执行此操作,并且decide//whatwewant:ListevenNumbers=newArrayList<>();for(IntegereachValue:numbersOneThroughTen){if(eachValue%2==0){evenNumbers.add(eachValue);}}//以下代码使用声明式编程来完成//同样的事情。//在这里,我们重述“Giveuseeverythingwhereit'sodd”evenNumbers=numbersOneThroughTen.stream().filter(num->num%2==0).collect(Collectors.toList());注意:这是一个抽象的概念。在上面的例子中,你可以进一步说我们没有得到“foreach”的实际实现,所以在某种意义上它描述的是“做什么”而不是“怎么做”。每种编程风格都属于一个范围,从纯命令式到纯声明式。函数式编程比过程式编程更具声明性。函数式编程一种编程范式,其中通过应用和组合函数来构造程序。在函数式编程中,函数被视为一等公民,这意味着它们可以绑定到名称(包括本地标识符),作为参数传递,并从其他函数返回,就像任何其他数据类型一样。这允许以声明和可组合的方式编写程序,其中组合小功能以创建更大的功能和程序。纯函数式编程是函数式编程的一个子集,其中所有函数都是纯函数。我将写另一篇关于函数式编程的详细博客文章。事件驱动或基于消息的架构事件是系统状态的重大变化。例如,当消费者购买汽车时,汽车的状态从“待售”变为“已售出”。汽车经销商的系统架构可以将这种状态变化视为一个事件,该事件的发生可以为架构内的其他应用程序所知。严格来说,事件无法传播,它们只是发生了。实际上,事件通知以纯文本消息的形式发出、处理和传播。在事件驱动系统中,不同的参与组件通过异步消息进行通信。反应式系统和反应式编程反应式系统是一种程序,其架构允许它对运行时环境的变化做出反应。ReactiveManifesto(http://www.reactivemanifesto.org)正式规定了反应式系统应具有的属性。这些属性中的三个可以概括为响应性、弹性和弹性。反应性意味着反应性系统实时响应输入,而不是因为系统正在为其他人做大量工作而延迟一个简单的查询。弹性意味着系统通常不会因为一个组件发生故障而发生故障;断开的网络链接不会影响不涉及该链接的查询,并且可以将对无响应组件的查询重新路由到备用组件。弹性意味着系统可以适应其工作负载的变化并继续高效运行。由于您可能会在服务食物和服务饮料之间动态地重新分配酒吧中的人员,以便两行具有相似的等待时间,因此您可以调整与各种软件服务相关联的工作线程的数量,以确保没有工作人员空闲,同时确保每个队列继续待定。显然,可以通过多种方式实现这些属性,但一种主要方法是使用响应式编程风格。响应式编程是使用表示为异步消息的事件进行编程(如在事件驱动的体系结构中)。这些消息通常被建模为数据流。例如,在Web应用程序中,典型的点击事件可以建模为数据流,您可以在其中观察并产生一些副作用。您可以创建任何数据流,而不仅仅是单击和悬停事件。流很便宜而且无处不在,任何东西都可以是流:变量、用户输入、属性、缓存、数据结构等。例如,你的Twitter提要是一个数据流,就像点击事件一样。您可以收听该流并做出相应的反应。一个流可以用作另一个流的输入。甚至多个流也可以用作另一个流的输入。您可以合并两个流。您可以过滤流以获取仅包含您感兴趣的事件的另一个流。您可以将数据值从一个流映射到另一个新流。