Java 为什么快速排序的JDK实现有堆栈溢出的风险?

Java 为什么快速排序的JDK实现有堆栈溢出的风险?,java,arrays,sorting,stack-overflow,quicksort,Java,Arrays,Sorting,Stack Overflow,Quicksort,前几天我看了一个演讲,演讲者使用了McIlroy论文中概述的技术,为触发O(n2)行为的基本类型生成数组.sort的输入。该序列导致pivot选择始终只将数组大小减少一个常量,这导致JavaArrays.sort函数导致堆栈溢出 据介绍,Arrays.sort1quicksort实现函数没有防止堆栈溢出的保护。通过使排序例程不触发两个递归调用,而是使用while循环将当前堆栈帧重新用于较大的子数组,并且仅递归一次(在较小的子数组上),始终可以使quicksort从不堆栈溢出。这会导致最小的性能下

前几天我看了一个演讲,演讲者使用了McIlroy论文中概述的技术,为触发O(n2)行为的基本类型生成
数组.sort
的输入。该序列导致pivot选择始终只将数组大小减少一个常量,这导致Java
Arrays.sort
函数导致堆栈溢出

据介绍,
Arrays.sort1
quicksort实现函数没有防止堆栈溢出的保护。通过使排序例程不触发两个递归调用,而是使用while循环将当前堆栈帧重新用于较大的子数组,并且仅递归一次(在较小的子数组上),始终可以使quicksort从不堆栈溢出。这会导致最小的性能下降,并且不可能对任何大小合理的输入造成堆栈溢出,因为在大小为n的输入上,堆栈深度永远不会超过O(logn)个堆栈帧。作者还可以使用该算法,当快速排序递归深度超过某个限制时,该算法修改快速排序以切换到最坏情况下的O(n log n)排序算法,以防止出现这种情况


Arrays.sort
的作者没有选择这样做有什么原因吗?内置排序算法可能导致堆栈溢出,这似乎是一个严重的问题,因为它可以通过触发重复的堆栈溢出来对这样的系统发起DoS攻击。

为什么?因为解决这个问题太过分了

所使用的算法在除异常情况外的所有情况下都是稳定的,如果这些情况比通常更可能发生,则应对外部情况进行防范。这就是为什么他们有API文档来定义幕后使用的算法。所以你可以抵抗它

特定顺序打破所提出算法的可能性非常小


我希望,如果您足够仔细地观察,会有一些数据集导致几乎所有标准JVM结构都崩溃。保护它们的成本是多少?这种成本值得付出努力吗?由于防御措施,算法不可避免地会退化。

要确定这一点,我们需要询问弗拉基米尔·亚罗斯拉夫斯基、乔恩·本特利或乔什·布洛赫。然而,在Java1.7中,sort1方法被删除并替换为DualPivotQuicksort,但我不太了解这是否比旧方法更好。