终端查看命令有哪些功能命令_从命令式功能到纯粹功能式功能,再返回:Monads与范围内的延续...

终端查看命令有哪些功能命令

  • 这段视频附带了这篇文章,没有它就不会太有意义

上个月,我在Curry On会议上做了演讲,该会议是与学术,编程语言会议ECOOP共同举办的新会议。 Curry On旨在弥合学术界之间的鸿沟。 我的学术兴趣不包括编程语言,我认为编程语言是计算机科学的子学科,与其他任何学科相比,其始终被高估和交付不足(可能是AI除外)。 我对算法比对抽象更感兴趣,并且编程语言研究主要与后者有关。 但是,作为开发人员,我必须使用我选择使用的编程语言提供的抽象,而令我感到震惊的是,我注意到某些抽象从学术语言到主流的流行,在某些情况下使身体不好,主要引起疼痛。 举个例子,我想想一个事实,即Java中使用monad的人比Haskell中使用monad的人更多。

在我的演讲中,我提出了命令式编程的核心抽象是阻塞线程。 一旦将其删除,您将失去大多数其他命令式抽象,例如控制流和异常处理(要求它们在库中重新实现),命令式语言带来的大多数优势包括事后调试,性能分析和自动背压。 这也使代码难以编写和阅读。 我声称,无论您是否使用monad减轻其痛苦,异步编程都是对命令式语言的厌恶。 异步与命令之间的不匹配是根本的。 一直以来,我们可以达到与monads一样强大的抽象(如果不是更多的话),这自然适合命令式语言,并与它们的结构和功能完美地结合在一起。

如果您还没有的话,现在是观看演讲的好时机:

在我的演讲中,我声称就像monads是纯函数式编程超级抽象一样,延续是命令式编程超级抽象,并且引入了一个抽象,我称之为“作用域延续”,这仅是带分隔符的延续 。一种特殊的酱料(我不知道这个概念是否在其他地方讨论过;如果有,我很想知道它的专有名称(请参阅文章末尾的附加内容))。

由于我在演讲之前不久就想到了这个主意,因此在介绍范围内的延续时我并没有做好准备,并且由于此后我最近对该主题进行了更多考虑,因此我想继续讨论这个主意。 我提出了三点主张:

  1. 范围内的延续自然适合命令性代码
  2. 范围连续像单子一样强大
  3. 有范围的延续比单子更好

我认为我为第1点提出了理由,因为范围内的延续使您可以保持命令式控制流,并且它们保留了堆栈上下文,这对于事后调试和性能分析至关重要。 当谈到#2时,我更加模糊,直觉地注意到了monad与续奏之间的联系,并提供了一些示例,但没有证明,而听众中的人则正确地要求我这样做。

第一回合:连锁–定界延续vs.单声道

演讲结束后,我与朱利安·阿尼 ( Julian Arni )进行了交谈,后者向我展示了丹·皮波尼 ( Dan Piponi)撰写的博客文章《所有单子的母亲》 。 有关Reddit的讨论 )使我想到了由Andrzej Filinski 1于1994年提出的证明 ,定界的连续性(在Filinski的论文中称为部分或可组合的连续性)可以表示任何单峰组合。 他说:

我们表明,任何其单元和扩展操作可表示为纯功能术语的monad都可以通过“可组合的延续”嵌入按值调用语言中…

…值得注意的是,monad对“不纯”函数式编程没有可比的影响。 可能的主要原因可能是……单子框架已经内置在渴望有效的功能性语言的语义核心中,因此无需明确表达。 语言(例如,可更新状态,异常或一流的延续)和语言外部(I / O,OS接口等)的“不纯净”构造都遵循一元法。 似乎唯一缺少的方面是程序员能够以与内置效果相同的便利性和自然性使用自己的,特定于应用程序的单子抽象(例如,不确定性或解析器)。

……在下文中,我们将展示……具有第一类延续性的语言……已经“单调完成”,因为任何以某种扭曲的单调风格表达的程序也可以直接编写。

我没有遵循Filinski论文的必要背景,但是,如果我没记错的话,证明的困难源于以下事实:从单子形式到连续形式(他称为“直接样式”)的转换是不是单调函数或单调作曲者的简单数学映射(Haskell称之为bind ),而是需要对其源代码表示进行更深层次的转换。 但是,我将以一种有希望的方式介绍定界连续的具体实现方式,以期解释moand-continuation相似性背后的直觉。

定界的延续捕获了调用堆栈的一部分。 它使我们暂停计算然后再恢复它。 让我们看一下Java中定界的延续API:

public class Continuation<T> implements Runnable, Serializable, Cloneable {public Continuation(Callable<T> target) { ... }public T run() { ... }public boolean isDone() { ... }public T getResult() { ... }public static Continuation<?> suspend(Consumer<Continuation<?>> ccc) { ... }
}

suspend方法(类似于Scheme的shift )暂停当前的延续(假设我们正在内部运行),并调用(可选)提供的回调ccc (名称cccCalled with Current Continuation的首字母缩写,这是一种玩法)在Scheme的call-cc )。 run功能(对应于Scheme的reset )将执行继续,直到其暂停或终止。 因此,例如:

class Foo {static int foo() {bar();bar();return 3;}static void bar() {System.out.println("Pausing...");Continuation.suspend(null);}public static void main(String[] args) {Continuation<Integer> c = new Continuation(Foo::foo);c.run(); // prints "Pausing..."c.run(); // prints "Pausing..."c.run();System.out.println(c.getResult()); // prints "3"}
}

因为suspend返回继续并将其传递给回调,所以我们可以扩展Continuation类并添加一些内部字段以产生ValuedContinuation

public class ValuedContinuation<T, Out, In> extends Continuation<T> {private Out pauseOut;private In pauseIn;private RuntimeException pauseInException;public run(In in);public run(RuntimeException e);public Out getPauseValue() { ... }public static <Out, In> In pause(Out value) {...}public static      <In> In pause(Consumer<ValuedContinuation<?, ?, In>> ccc) {...}public static   <V, In> In pause(V x, BiConsumer<V, ValuedContinuation<?, ?, In>> ccc) {...}
}

ValuedContinutation ,我们可以将值传入和传出延续。 如果我们调用pause(3) ,则getPauseValue将返回值3 ,而如果使用run(5)恢复继续,则将由pause返回值5run(new RuntimeException())将导致pause以引发该异常。 例如:

ValuedContinuation<Void, Integer, Integer> c = new ValuedContinuation<>(() -> {int x = pause(5);x = pause(x + 10);x = pause(x * 100);return null;});while(!c.isDone()) {c.run(3);System.out.println(c.getPauseValue()); // prints: 5, 13, 300
}

现在我们可以理解连续性可以表示任何monad的主张的直觉: 我们的monadic作曲者 (或bind将是传递给pause的回调ccc 每次pause的代码是c.run(x)序列中的下一个monadic函数,并且调用c.run(x)正在应用链中的下一个c.run(x)函数。

不同的是,一元函数蹦床回到封闭作曲家(绑定),而在这里我们所说的作曲家(我们的ccc我们延续 )。 正如我在演讲中所声称的,命令式语言的延续是命令式语言与所有命令式概念(例如命令式控制流和异常)之间的良好交互,并且保留了对于调试和性能分析非常重要的堆栈上下文。

在继续之前,让我们看一个使用ccc回调的示例。 它是延续形式的“未来单子”的一个示例。 假设我们有一个异步服务:

interface AsyncHandler<T> {void success(T result);void failure(RuntimeException error);
}interface AsyncService<T> {void submit(AsyncHandler<T> callback);  
}

然后,我们可以定义此方法:

static <T> Consumer<ValuedContinuation<?, ?, T>> await(AsyncService<T> service) {return c -> {service.submit(new AsyncHandler<T>() {public void success(T result) {c.run(result);}public void failure(RuntimeException error) {c.run(error);}});};
}

我们将在延续中运行的代码中使用该代码,如下所示:

String y = pause(await(service));

上面的代码将暂停继续,直到服务请求完成,然后将其恢复为结果。

第二轮:作曲–范围延续与Monad变形金刚

在演讲中,我还声称即使在纯功能语言中,monad也很难编写2 ,这非常适合monads。 编写monad(即编写使用异常 IO 产生序列的monadic代码)需要使用monad转换器 ,因为它们利用非常高阶的函数来形成一个让人脑筋急转的Lambdish间接函数 ,因此很难理解。

为了创建易于组合的延续,在我的演讲中,我介绍了作用域延续 ,这是带分隔符的延续的变体。 范围内的延续是嵌套的延续,在任何级别,代码都可以自由地暂停其任何包含的延续。 这个想法与嵌套的try / catch块非常相似,在嵌套的try / catch块中,根据异常类型,执行将跳转到相应嵌套范围的catch块。

为了测试该想法在实践中的效果如何,我已经在Java和Clojure中实现了一个有范围的延续原型。 您可以分别在 Quasar和Pulsar的cont分支( 此处和此处)中使用作用域延续来查找代码。

为了实现延续,我使用了Quasar的工具,该工具非常简单(尽管有范围的延续可能有一天会进入上游Quasar,但这种情况不会很快发生,因为我们首先需要使工具完全透明且可以不使用,我们希望Java 9发布时该怎么做)。 困难的部分是支持在嵌套连续引用不仅存在于堆栈中,而且还可能存在于堆中的环境中克隆嵌套的延续(下面介绍的非确定性延续所需要)。 我尝试了三种不同的方法,但我对其中任何一种都不满意。

对于范围连续,我们需要稍微更改Continuation (和类似ValuedContinuation )类:

public class Continuation<S extends Suspend, T> implements Runnable, Serializable, Cloneable {public Continuation(Class<S> scope, Callable<T> target) { ... } // <-- scopepublic T run() { ... }public boolean isDone() { ... }public T getResult() { ... }public static Continuation<?> suspend(S scope, Consumer<Continuation<?>> ccc) { ... } // <-- scope
}

范围是全局名称。 在Java中,我选择代表范围,就像表示异常范围一样:作为类名(在当前实现中,范围是扩展Suspend类, Suspend是一种异常类型)。

范围的延续定义和使用方式如下:

class ACont<T> extends ValuedContinuation<AScope, T> {public Continuation(Callable<T> target) {super(AScope.class);// ...}public static AScope A = new AScope();
}// similarly BCont, and then:static void foo() {Continuation<Void> c = new ACont(() -> {// ...Continuation<Void> c = new BCont(() -> {// ...suspend(B, ...); // suspends the enclosing BCont// ...suspend(A, ...); // suspends the enclosing ACont// ...});// ...});// ...
}

在Clojure中,范围是全局符号,并且可以将范围的延续定义为:

(let ; ....(let ; ....(pause B ...); ...(pause A ...); ...))])))]; ...
)

范围延续的概念是,暂停任何封闭的延续范围相当于返回到任何封闭的作曲家(绑定)的单子函数。 但是在范围连续的情况下,我们不需要monad转换器来转换作曲者或链接的monadic函数。

为了了解这种组合在实际代码中的外观,我实现了两种延续类型: CoIterable (与Python生成器一样,生成具有延续的Iterable并对应于Haskell的list monad)和Ambiguity (实现了不确定性计算)回溯a-la Scheme的amb并对应于Haskell的amb monad。

孤立地, CoIterable的用法如下:

Iterable<Integer> range(int from, int to) {return new CoIterable<>(() -> {for (int i = from; i < to; i++)produce(i);});
}

有关CoIterable运算符的示例,例如flatmapmapfilter请参见此处 ,并请注意,额外的灵活性延续给了我们单子。 由于单子函数将蹦床返回给作曲者,因此必须根据单个平面映射作曲者来实现filtermap操作,而对于延续,我们可以自由地从延续中选择自己的构图规则,并且可以实现filter并独立于flatMap进行map ,以获得更好的性能。

这是隔离中使用Ambiguity的示例:

Ambiguity<Integer> amb = solve(() -> {int a = amb(1, 2, 3); // a is either 1, 2, or 3int b = amb(2, 3, 4); // b is either 2, 3, or 4assertThat(b < a);    // ... but we know that b < areturn b;});amb.run(); // returns 2 as that's the only possible solution for b

现在,让我们看看两者是如何无缝组合的:

Ambiguity<Integer> amb = solve(() -> {Iterable<Integer> a = iterable(() -> {produce(amb(2, 1)); // pauses on Ambiguity and CoIterableproduce(amb(3, 10));});int sum = 0;for (int x : a) { // using imperative loops on purpose; functional would work, toosum += x;assertThat(x % 2 == 0); // we assert that all elements are even}return sum;
});amb.run(); // returns 12

注意如何a延续中止既对Ambiguity以及对CoIterable范围。 它创建一个列表,其第一个元素为21 ,其第二个元素为310 ,产生四个可能的列表: (2, 3)(2, 10)(1, 3)(1, 10) 。 后来,我们断言所有元件必须是偶数,这意味着对于唯一有效的列表a(2, 10)以及用于唯一可能的值sum是12。

作为最后一个示例(可以在此处和此处的测试中找到更多示例;可以在此处找到Clojure示例),让我们通过另一层嵌套将事情进一步复杂化:

Fiber<Integer> f = new Fiber<>(() -> {Ambiguity<Integer> amb = solve(() -> {Iterable<Integer> a = iterable(() -> {produce(amb(2, 1));sleep(20); // pauses on the Fiber scopeproduce(amb(3, 10));});int sum = 0;for (int x : a) {sum += x;Fiber.sleep(20);assertThat(x % 2 == 0);}return sum;});return amb.run();
}).start();f.get(); // returns 12

现在,我们将整个内容嵌套在光纤中-Quasar的轻量级线程实现-仅仅是Java的ForkJoin调度程序调度的延续而已。 现在,内嵌套代码a在三个不同范围内暂停没有打破汗水,没有任何形式的变压器。

但是类型安全呢?

Haskell具有非常丰富的类型系统,而Monad可以极大地发挥作用。 通过查看(monadic)函数的签名,您可以立即知道它可以“驻留”在哪种monad类型中,并且不能在该monad之外的任何地方使用它。 事实证明,可以在不失去其任何期望属性的情况下,对作用域延续进行安全类型化。 为此,我们需要一个(简单的)类型系统来声明:

void foo() suspends A, B

这意味着foo可能会在AB范围内暂停延续,因此只能在两个范围内的代码中调用。 然后,将Continuation类定义为(在伪Java中):

public class Continuation<S extends Suspend, T> implements Runnable, Serializable, Cloneable {public Continuation(Class<S> scope, [Callable<T> suspends S|Others] target) { ... }public T run() suspends Others { ... }public static Continuation<?> suspend(S scope, Consumer<Continuation<?>> ccc) suspends S
}

因此,延续可以运行任何可能在参数化S范围以及其他范围上可能挂起的目标代码,而run方法可以吞咽S范围,但仍在挂起其他范围。

事实证明,我们已经有了这样的类型系统- 几乎是 Java的检查异常。 如果我们创建了Suspend范围(所有范围都从该范围下降),则可以像上面的伪Java中的suspend一样使用Java的throws 。 我之所以没有这样做,是因为Java的类型系统不允许您捕获多个经过检查的异常类型,就像我在上述“ Others所做的那样,这意味着我们需要显式的实例来处理显式的范围变量(挂起一个范围的函数,两个范围等),这可能会使事情变得麻烦。

然后,我们还可以通过参数化范围来提高ValuedContinuation的类型安全性,这样我们就可以:

void foo() suspends CoIterableScope<Integer>

这只会让foo在产生一个Integer序列(而不是String )的CoIterable中被调用。 不幸的是,我们也不能完全做到这一点,因为Java当前不允许泛型异常类型。

未完待续?

我希望通过更深入地讨论范围内的连续性,我能够比我在演讲中挥舞过的挥手更好地解释这个想法,并且我很高兴找到Filinski的证明(这在PL圈子中可能是众所周知的) )。

我希望我的讲话使您相信单语在命令式语言中没有地位(也许除了并行计算之外),如果没有,我很想听听为什么不这样做。 我还相信,即使在PFP语言中,范围连续的合成也比monad更好(而且,monad通常不是一种很好的效果建模方法,但这是另外一个讨论)。

最后,虽然我坚信命令性语言应该具有某种形式的轻量级线程(AKA光纤,AKA用户模式线程,AKA绿线程排序)和线程(任何类型)不过是由适当的调度程序调度的延续,我不一定认为命令式语言应该直接将范围化的延续公开为抽象。 毕竟,存在抽象以增加代码重用性,帮助代码维护和帮助验证:总之,它们存在以降低开发成本,并且(至少从非研究的角度来看)它们是唯一的度量标准判断3 。 我认为延续性是PFP优雅的monad的优雅命令,但是我还不相信它们在实践中的作用。

如果您想了解更多有关延续的知识,那么这就是延续发展的历史,它使所有合适的人都受惠。

附录1

自从首次发布此博客文章以来,我设法在Philip Wadler于1993年发表的一篇论文中找到了关于范围延续的参考,该论文称为Monads and composablecontinuations ,他将范围延续简单地称为“具有多个层次的可组合延续”。 正如Wadler显示定界延续可由monad表示,而Filinsky显示(一年后)monad可表现为定界延续,这有理由推论两者是对偶的。 尽管如此,有理由认为,即使是对偶,每种也都更适合于特定的编程风格,并且毫无疑问,延续更适合于不纯洁的按值调用的语言(命令式和函数式命令式)。 瓦德勒在总结论文时说:

具有多个层次的可组合延续的一个目标是能够将不同的影响分解为不同的层次。 Danvy和Filinski声称以这种方式将各种效果均匀地组合起来相对容易。 Monads还旨在通过简化组合的方式来分解效果。 但是,没有统一的规则来组合任何两个单子。 本文使用了monad来阐明可组合的延续。 可组合的延续词会阐明单子组合的问题吗?

附录2

在网上讨论中,一位读者评论说,我通过谈论单子而不是单子来误解了单子。 我认为这仅是解释上的区别,因此我想澄清一下:

正如已经证明的(我认为),任何效果都可以由单子模拟,您可以说所有效果都是单子的,但是就像著名笑话中的数学家一样,这是绝对正确的,但绝对没有用(取决于您的观点)。 -视图,我猜)。

从数学的角度来看,只要两件事同构,它们就是“相同”的。 但是从编程的角度来看,两者可能是非常不同的,因为抽象是与程序员思想上的心理交互,而两个同构的数学概念在心理上与程序员之间的交互也非常不同。 因此,如果在处理抽象时我不必“思考单子”,那么即使它们之间存在同构,抽象也不是单子。

根据数学解释,“反对单子”与反对数字1一样荒谬。在我的解释中,用阿拉伯数字,教堂数字或集合论数字表示数字1在心理上有很大不同,并且因此,在编程语言上有本质的不同,因为编程语言首先是人类语言的一种。 在编程语言中,抽象是通过数学以及心理(或经济)特性来定义(和测量)的。

我是一个“算法论者”,而不是一个“抽象论者”(不幸的是,我认为这两个CS观点常常是矛盾的),因此我仅在抽象化在编写和维护方面带来的成本变化方面衡量其有用性我的算法,对我来说,单子是一种设计模式,而不是以某种特定符号表示的数学对象。

  1. 然后我发现这篇文章说,Filinski的证明并不扩展到利用懒惰(按名字呼叫)评估的单子
  2. 例如,尝试使用CompletableFutures组成Java流。 这并不容易。
  3. 请参阅此HN关于该主题的讨论 。

翻译自: https://www.javacodegeeks.com/2015/08/from-imperative-to-pure-functional-and-back-again-monads-vs-scoped-continuations.html

终端查看命令有哪些功能命令

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337300.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 空指针和野指针

点击蓝字关注我们来源于网络&#xff0c;侵删1.空指针指针变量指向内存中编号为0的空间为空指针。空指针指向的内存空间是不可以访问的 。代码&#xff1a;#include<iostream> using namespace std; int main() {int a 10;int * p &a;cout << p << end…

jdbc事务 jta事务_将非事务性资源绑定到JTA事务中的几种模式

jdbc事务 jta事务我最近发表了一篇有关如何将非事务性资源&#xff08;如Web服务/微服务&#xff09;绑定到全局分布式事务中的文章&#xff0c;以便自动处理恢复。 多年来&#xff0c;我经常不得不将“非事务性”系统集成到Java EE应用程序服务器中&#xff0c;而数据一致性通…

sap abap开发从入门到精通_SAP开发-ABAP数据字典(锁)

企业级软件或开发框架&#xff0c;必然支持后台高并发&#xff0c;即支持多人同时访问数据库。SAP作为资深企业管理软件&#xff0c;自然也不例外&#xff0c;ABAP可以很方便的开发出支持高并发的程序&#xff0c;要实现高并发&#xff0c;正确使用锁对象是其中一个重要环节&am…

(acm)C++加速输入的几种方法

点击蓝字关注我们来源于网络&#xff0c;侵删1.CIO流的同步和绑定在C中&#xff0c;cin和cout的速度其实不并不慢&#xff0c;C中的流的IO速度相当的快&#xff0c;其速度与初始设定的缓存区大小和硬盘的IO速度有关。但在C中&#xff0c;为了兼容C的IO(scanf和printf)&#xff…

python引用函数_python 调用函数

Python内置了很多有用的函数&#xff0c;我们可以直接调用。要调用一个函数&#xff0c;需要知道函数的名称和参数&#xff0c;比如求绝对值的函数abs&#xff0c;只有一个参数。可以直接从Python的官方网站查看文档&#xff1a;也可以在交互式命令行通过help(abs)查看abs函数的…

服务器编写_编写下载服务器。 第六部分:描述您发送的内容(内容类型等)...

服务器编写就HTTP而言&#xff0c;客户端下载的只是一堆字节。 但是&#xff0c;客户真的很想知道如何解释这些字节。 它是图像吗&#xff1f; 还是ZIP文件&#xff1f; 本系列的最后一部分描述了如何向客户端提示她下载的内容。 设置 内容类型描述了返回的资源的MIME类型 。 …

python读取xls文件详解_python3解析excel文件

一.需要的依赖 : xlrd二.代码#codingutf-8import xlrd读取Excel每个sheet的第一列和第二列的值,拼接成json串,写入文件def resolveExcel():# 获取excel文件data xlrd.open_workbook("/you/excel/location/?.xlsx",encoding_overrideutf-8)#获取一个excel有多少个sh…

jdbc时区_什么比日期和时区更难? SQL / JDBC中的日期和时区!

jdbc时区在jOOQ邮件列表上&#xff0c;最近有一个有趣的讨论&#xff0c;关于jOOQ当前缺乏对TIMESTAMP WITH TIME ZONE数据类型的现成支持。 没有人说日期&#xff0c;时间和时区很容易&#xff01; 这里有一个有趣的文章&#xff0c;我建议阅读&#xff1a; 虚假的程序员相信…

C语言与C++的区别终于有人说清楚了!

点击蓝字关注我们来源于网络&#xff0c;侵删1、前言在很大程度上&#xff0c;C是C的超集&#xff0c;这意味着一个有效的C程序也是一个有效的C程序。C和C的主要区别是&#xff0c;C支持许多附加特性。但是&#xff0c;C中有许多规则与C稍有不同。这些不同使得C程序作为C程序编…

postgresql两个列模糊比较_数据分析之SQL优化系列(二)---PostgreSQL 的索引

参考《PostgreSQL11.2-中文手册》下面这个链接&#xff0c;讲的通俗易懂&#xff0c;可以看看。数据分析师不得不知道的SQL优化 - 鑫获 - 博客园​www.cnblogs.com索引是提高数据库性能的常用途径。比起没有索引&#xff0c;使用索引可以让数据库服务器更快找到并获取特定行。但…

淘宝客静态单页_单页应用程序的Spring Boot静态Web资源处理

淘宝客静态单页诸如gulp和grunt之类的Javascript构建工具确实让我大吃一惊&#xff0c;我看着这些工具的构建脚本之一&#xff0c;发现很难理解它&#xff0c;并且无法想象从头开始编写其中一个构建脚本。 这就是yeoman出现的地方&#xff0c;它是一种非常方便的工具&#xff0…

高达 36 斤的 C/C++ 编译器?

点击蓝字关注我们来源于网络&#xff0c;侵删前言软件有重量吗&#xff1f;有人说&#xff0c;现代的软件主要搭载在硬件之上&#xff0c;只有占用内存的大小&#xff1b;也有人说&#xff0c;软件都是在网络上下载下来的&#xff0c;哪有什么重量可言&#xff1b;还有人说&…

双屏全屏跳回到主屏_双屏笔记本了解下?剪视频不要太好使

[PConline 评测]每天一开始上班&#xff0c;我们就要开始跟各种电脑程序和窗口打交道&#xff0c;而当面对各种信息和数据的轰炸时&#xff0c;恨不得就要把ALTTAB两个键给磨烂了。↑每天至少要面对十多个窗口gif而今天&#xff0c;笔记本厂商也不再吝啬于给予用户更多更大的屏…

jvm与非jvm语言优劣_都灵JVM编程语言:使用ANTLR构建高级词法分析器

jvm与非jvm语言优劣正如我在上一篇文章中所写的那样&#xff0c;我最近开始研究一种名为Turin的新编程语言。 可以在GitHub上找到适用于languag初始版本的编译器。 我目前正在改善语言&#xff0c;并正在开发Maven和IntelliJ插件。 在这里和下一篇文章中&#xff0c;我将介绍编…

一例看懂C语言程序中的内聚和耦合

点击蓝字关注我们来源自网络&#xff0c;侵删一、原理篇&#xff08;清楚相关原理的读者&#xff0c;请直接看第二部分示例篇&#xff09;在软件工程中&#xff0c;模块的内聚和耦合是度量模块化质量的标准之一。内聚是指模块的功能强度的度量&#xff0c;即一个模块内部各个元…

openfire消息通知推送_APP消息推送功能之前端后台设计

APP消息推送功能之前端后台设计最近有不少小伙伴问APP消息推送功能&#xff0c;前端、后台如何设计的&#xff1f;消息系统的架构是什么样的&#xff1f;最近刚好做到后台消息推送这块&#xff0c;简单谈谈个人心得&#xff0c;欢迎拍砖。消息推送是让自己的用户获取信息最有效…

apache spark_Apache Spark:更改架构之前必须解决的5个陷阱

apache spark迁移到Apache Spark之前需要了解的5件事 似乎每个人都只是在谈论最热门的新技术&#xff0c;而忽略采用它的实际含义。 但这是自然的&#xff0c;对吧&#xff1f; 新功能和承诺胜过其他所有事物&#xff0c;而艰难的挑战和决​​定被抛在一边。 这次不行。 软件…

分步解析C++实现通讯录管理系统

点击蓝字关注我们来源于网络&#xff0c;侵删一、前言建议亲手写一遍代码&#xff0c;感受指针神奇的魅力&#xff1b;可以帮助你更好的巩固知识体系&#xff0c;熟悉指针&#xff0c;结构体与函数一起使用时的妙处完成通讯录管理系统所需知识体系结构体指针函数的封装指针与函…

python代码可以内嵌在asp文件中_在IE中使用Python作为开发脚本(转)

正在学习python&#xff0c;除了语法优美&#xff0c;功能强大外&#xff0c;最看重的是它的可扩展性&#xff0c;可以嵌入到asp和其他一些开发语言中。对IIS配置了.py的扩展名解析&#xff0c;可以对.py的页面进行访问&#xff0c;但asp页面的python脚本仍然无法解析&#xff…

服务器禁止head 请求_编写下载服务器。 第四部分:有效地执行HEAD操作

服务器禁止head 请求HEAD是一个经常被遗忘的HTTP方法&#xff08;动词&#xff09;&#xff0c;其行为类似于GET&#xff0c;但不返回正文。 您使用HEAD来检查资源的存在&#xff08;如果不存在&#xff0c;它应该返回404&#xff09;&#xff0c;并确保您的缓存中没有陈旧的版…