Các ngoại lệ về cơ bản tồn tại để ngăn chặn một hệ thống bị sập?


16

Thứ hai, tôi đã tự hỏi liệu có ai biết sự khác biệt giữa các ngoại lệ (trong lĩnh vực của luồng kiểm soát ngoại lệ) và Ngoại lệ (như được sử dụng trong Java) không.

Nhưng họ có ở đó để cơ bản bảo vệ hệ thống khỏi sự cố bằng cách chấm dứt chương trình người dùng không?

Câu trả lời:


29

Các ngoại lệ tồn tại để cho phép Xử lý ngoại lệ , có thể tránh sự cố nhưng nói chung là ngăn chặn hành vi hệ thống không mong muốn hoặc không thể đoán trước. Ví dụ, nếu kết nối chương trình của tôi với cơ sở dữ liệu hết thời gian, nó thường sẽ không làm sập hệ thống, nhưng nếu tôi phụ thuộc vào dữ liệu từ cơ sở dữ liệu, một ngoại lệ có thể cho phép tôi xử lý tình huống không có dữ liệu này khác với bình thường.

Nói theo mặc định, chương trình của tôi hiển thị một trang dữ liệu dựa trên những gì được trả về từ cơ sở dữ liệu - thật tệ, tôi không có dữ liệu. Thay vì trình bày một khung nhìn lộn xộn hoặc tiếp tục một hoạt động có khả năng không hợp lệ, tôi có thể bắt ngoại lệ này và quay lại cơ sở dữ liệu khác, đọc từ dữ liệu cục bộ, yêu cầu người dùng cung cấp dữ liệu hoặc trả lại cho người dùng hoặc hệ thống về trạng thái an toàn (có thể là một Điều đó sẽ không ngay lập tức gây ra ngoại lệ tương tự!)

Ngoài ra, trong các hệ thống mà đầu vào của người dùng có thể là nguyên nhân / giải pháp cho vấn đề, ngoại lệ có thể cho phép người dùng biết thông tin chi tiết và hữu ích về sự cố. Thay vì quá phổ biến "Một ngoại lệ chưa được xử lý xảy ra tại ..." hoặc "Thông báo lỗi đáng sợ trực tiếp từ SQL", bạn có thể nói với người dùng một cái gì đó hữu ích hoặc ít nhất có thể hiểu được như "Không thể kết nối với tài nguyên B."


5
Tôi cảm thấy đây là câu trả lời chính xác nhất. Các chương trình là máy trạng thái hữu hạn làm việc. Có nhiều cách để phá vỡ máy bằng cách giới thiệu dữ liệu xấu, điều này sẽ khiến máy gặp trục trặc. Các ngoại lệ được ném để ngăn chặn điều này. Đôi khi máy có thể tự phục hồi, nhưng đôi khi không thể.
Andy

1
Tôi không thể làm điều tương tự chính xác với mã lỗi? Bạn trả lại một lỗi, và tôi xử lý nó.
mskw

16

Các ngoại lệ được tạo để đơn giản hóa việc xử lý lỗi. Không có ngoại lệ, logic xử lý lỗi phải được trải đều trong một ứng dụng. Bất kỳ chức năng nào có thể dẫn đến lỗi đều phải trả lại trạng thái lỗi và mỗi cuộc gọi phải được theo dõi bằng kiểm tra lỗi. Thông thường người gọi không thể làm gì hữu ích trong trường hợp có lỗi và chỉ có thể trả lại lỗi. Một nửa mã ứng dụng có thể được dành cho xử lý lỗi. Mã như vậy là vô cùng mong manh. Tất cả quá dễ dàng để bỏ qua kiểm tra lỗi và sự cố, hoặc tệ hơn là trả về kết quả không chính xác do lỗi không được chú ý.

Với các ngoại lệ, lỗi chỉ có thể được kiểm tra tại điểm có thể xử lý. Hầu hết các mã ứng dụng có thể được viết theo kiểu đường thẳng, vì các hàm sẽ trả về giá trị có thể sử dụng hoặc ném ngoại lệ.


5

Điểm của một ngoại lệ là thông báo cho người dùng về các trường hợp đặc biệt. Nếu có sự cố xảy ra với hệ thống, chương trình nên biết và được phép xử lý nó * một cách thích hợp.

Điều đó nói rằng, không, một ngoại lệ không tồn tại để ngăn hệ thống "sập". Một ngoại lệ là cho tôi biết có một vấn đề. Làm thế nào tôi tiến hành xác định có thể xác định nếu hệ thống "gặp sự cố".

Cũng lưu ý rằng một ngoại lệ không phải chấm dứt ứng dụng như bạn đã nói. Một ngoại lệ có thể được xử lý bởi lập trình viên và sửa chữa hoặc biến thành một số lỗi có ý nghĩa đối với người dùng.


* Việc sử dụng các ngoại lệ được kiểm tra (các ngoại lệ buộc phải bị bắt) là một điểm đau. Một số (có lẽ hầu hết) các nhà phát triển thấy rằng việc xử lý ngoại lệ bắt buộc là cồng kềnh, không cần thiết và chỉ là thực tiễn tồi.


2
Tôi không đồng ý, định nghĩa này quá hạn chế. Chỉ một tập hợp các trường hợp ngoại lệ nên được hiển thị cho người dùng. Các ngoại lệ là để xử lý lỗi, và từ bỏ và thông báo cho người dùng là bước cuối cùng thường được thực hiện và không nên là chuẩn mực. Một số hệ thống được thiết kế để sử dụng ngoại lệ cho một số loại điều khiển luồng, như kết thúc lặp, EOF, v.v.
Jürgen Strobel

Jürgen, tôi hiểu và hoàn toàn đồng ý với nhận xét của bạn. "Sửa chữa hoặc biến thành một số lỗi có ý nghĩa" - Tôi không truyền đạt suy nghĩ đó bằng tuyên bố này?

Vâng, bây giờ tốt hơn nhiều.
Jürgen Strobel

Có thể cho rằng, ngoại lệ không bao giờ được hiển thị cho người dùng. (Các điều kiện khiến chúng được tạo ra có thể cần phải được báo cáo cho người dùng bằng cách nào đó, nhưng không phải là ngoại lệ.) Nhưng một ngoại lệ luôn tốt hơn chương trình chỉ thực hiện DIAF hoặc thoát bất ngờ. (Voi Mỗi khi tôi cố gắng sắp xếp email của mình theo tên người gửi, ứng dụng email sẽ thoát ra một cách im lặng !! Cho dù lối thoát đó có sạch sẽ đến đâu, nó vẫn sai.)
Donal Fellows

2

Các ngoại lệ cho phép xử lý lỗi hiện đại bằng cách tách vị trí lỗi khỏi trình xử lý lỗi. Đôi khi điều này được sử dụng để kiểm soát dòng chảy quá.

Các trường hợp ngoại lệ chưa được xử lý chấm dứt một chương trình. Nhưng những điều này không khác với các trường hợp ngoại lệ trước đây, chỉ là một lập trình viên lười biếng quên đưa các trình xử lý lỗi thích hợp vào mọi đường dẫn khiến chúng hiển thị cho người dùng cuối. Tôi coi một chương trình bị chấm dứt bởi ngoại lệ giống như bất kỳ kết thúc bất ngờ nào khác.

Các hệ điều hành rất tốt trong việc dọn dẹp các quy trình bị hỏng cho dù chúng bị hỏng như thế nào, vì vậy các trường hợp ngoại lệ không thêm an toàn cho HĐH bằng bất kỳ cách nào khác ngoài việc chấm dứt các quy trình gặp trục trặc và giải phóng tài nguyên của chúng.


Có những giới hạn đối với những gì Hệ điều hành có thể dọn sạch. Nói chung, HĐH không thể biết liệu có bất kỳ tài nguyên liên tục nào (ví dụ: tệp) cần được dọn sạch hoặc khôi phục hay không, cũng không thể biết liệu có cần dọn dẹp cho kết nối từ xa hay không, ngoài việc đóng kết nối ở phía cục bộ.
8

2

Nó rất đơn giản.

  • Để chỉ làm hỏng chương trình chứ không phải toàn bộ hệ thống - chúng tôi có Hệ điều hành [tốt].
  • Để đánh sập một chương trình thay vì bỏ qua một lỗi nghiêm trọng - chúng tôi có ngoại lệ.

Trước khi các ngoại lệ được phát minh, mọi hàm phải trả về mã thoát (lỗi / thành công) và bất kỳ kết quả hoặc đầu ra nào từ hàm phải được truy xuất bằng cách chuyển nó một con trỏ tới bộ nhớ để được đặt bởi nó.

Vấn đề là nhiều lập trình viên đã không nhớ / bận tâm kiểm tra mã thoát sai cho từng chức năng và do đó các lỗi nghiêm trọng đôi khi bị bỏ qua, dẫn đến các hành vi khá khó giải thích.

Do đó, nó đã được quyết định - khi xảy ra lỗi, mà bạn không xem xét, gặp sự cố ngay lập tức! Xử lý ngoại lệ AKA.


1

Các ngoại lệ chỉ đơn giản là một cơ chế phát hiện lỗi. Tự chúng không có ích.

Nhưng bằng cách phát hiện lỗi, họ cho phép kích hoạt các cơ chế chống lỗi để phục hồi từ trạng thái lỗi bằng cách chuyển sang trạng thái không có lỗi (trạng thái trước hoặc trạng thái mới). Bằng cách đó, lỗi không được lan truyền đến các bộ phận khác của hệ thống.


0

Các ngoại lệ tồn tại để tách luồng chương trình bình thường (những gì chương trình được thiết kế để làm) khỏi luồng xử lý lỗi (cách chương trình đang cố gắng phục hồi từ một tình huống đặc biệt).

Điều này làm cho mã rõ ràng hơn và dễ bảo trì hơn.

Hãy xem xét hai đoạn mã:

try:
    do1()  # this is obvoiusly a normal
    do2()  # program flow
except:
    oups()  # this is exception handling code

So với cái này:

if foo():
    thing1()  # is this part of normal program flow?
else:
    thing2()  # or maybe this one? Or both? When?

Tất nhiên, xử lý ngoại lệ có thể được sử dụng để ngăn chương trình bị sập bằng cách:

try {    // very bad code
    my();
    whole();
    ugly();
    application();
    here();
} catch (Throwable t) {
    // pretend it's ok
}

nhưng đây không phải là lý do cho các ngoại lệ trong các ngôn ngữ lập trình hiện đại.

Bạn cũng có thể sử dụng whilebreakthay vì ifnhưng đây không phải là những gì whilebreaklà dành cho.


Trên thực tế, việc xử lý luồng điều khiển "bất thường" là chính xác khi goto và bạn bè của nó phá vỡ là hữu ích nhất. Ưu điểm của các trường hợp ngoại lệ là chúng có thể vượt qua các ranh giới chức năng và người gọi có thể xác định nơi nào phù hợp nhất để bắt nó.
hugomg

@hugomg: Một lợi thế lớn khác của các trường hợp ngoại lệ là chúng cho phép dọn sạch tài nguyên và các hành động khác như vậy được thực hiện giữa nơi ném ngoại lệ và nơi xử lý.
supercat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.