2013-05-10 41 views
5

tôi thấy một bài thuyết trình ngày khác, trong đó loa đã sử dụng các kỹ thuật nêu trong giấy McIlroy của A Killer Adversary for Quicksort để tạo ra một đầu vào để Arrays.sort cho kiểu primitive mà sẽ kích hoạt O (n) hành vi. Trình tự gây ra sự lựa chọn trục xoay luôn luôn chỉ làm giảm kích thước mảng bằng một hằng số, khiến cho hàm Java Arrays.sort gây ra tràn ngăn xếp.Tại sao việc thực hiện JDK của quicksort có nguy cơ tràn ngăn xếp?

Theo the source files from the JDK, chức năng triển khai quicksort Arrays.sort1 không có biện pháp bảo vệ để ngăn chặn tràn ngăn xếp. Nó luôn luôn có thể làm cho quicksort không bao giờ bị tràn do có thói quen sắp xếp không kích hoạt hai cuộc gọi đệ quy, nhưng thay vào đó sử dụng một vòng lặp while để tái sử dụng khung stack hiện tại cho subarray lớn hơn và chỉ đệ quy một lần (trên subarray nhỏ hơn). Điều này gây ra sự suy giảm hiệu suất tối thiểu và làm cho nó không thể gây ra tràn ngăn xếp cho bất kỳ đầu vào có kích thước hợp lý nào, vì chiều sâu ngăn xếp không bao giờ vượt quá khung ngăn xếp O (log n) trên đầu vào có kích thước n. Các tác giả cũng có thể đã sử dụng thuật toán introsort, thuật toán sửa đổi quicksort để chuyển sang thuật toán phân loại O (n log n) tồi tệ nhất khi độ sâu đệ quy quicksort vượt quá giới hạn, để ngăn chặn điều này.

Có lý do nào khiến các tác giả của Arrays.sort không chọn làm điều này? Nó có vẻ như một vấn đề nghiêm trọng mà thuật toán phân loại dựng sẵn có thể gây ra tràn ngăn xếp, vì nó làm cho nó có thể khởi động một cuộc tấn công DoS chống lại một hệ thống như vậy bằng cách kích hoạt các luồng tràn lặp đi lặp lại.

+0

Để biết chắc chắn chúng tôi cần hỏi Vladimir Yaroslavskiy, Jon Bentley hoặc Josh Bloch. Tuy nhiên trong java 1.7, phương thức sort1 được loại bỏ và thay thế bằng một DualPivotQuicksort nhưng tôi không đủ tốt ở công cụ này để hiểu xem điều này có tốt hơn như cách tiếp cận cũ hay không. – mszalbach

Trả lời

5

Tại sao? Bởi vì giải quyết vấn đề sẽ là quá mức cần thiết.

Thuật toán được sử dụng sẽ ổn định trong mọi trường hợp đặc biệt bất thường và nếu những trường hợp đó thường xảy ra thì tình huống sẽ được bảo vệ chống lại bên ngoài. Đó là lý do tại sao họ có tài liệu API xác định thuật toán được sử dụng sau hậu trường. Vì vậy, bạn có thể bảo vệ chống lại nó.

Khả năng thứ tự cụ thể phá vỡ thuật toán được trình bày là biến mất nhỏ.

Tôi hy vọng nếu bạn xem xét cẩn thận, sẽ có bộ dữ liệu làm cho hầu như tất cả các cấu trúc JVM tiêu chuẩn bị hỏng. Chi phí bảo vệ chống lại chúng là gì và chi phí đáng để nỗ lực và sự suy giảm không thể tránh khỏi của thuật toán do các biện pháp phòng thủ.

Các vấn đề liên quan