Làm cách nào để cải thiện việc kiểm tra và xử lý lỗi?


13

Gần đây tôi đã phải vật lộn để hiểu mức độ kiểm tra phù hợp là gì và phương pháp thích hợp là gì.

Tôi có một vài câu hỏi liên quan đến điều này:

Cách thích hợp để kiểm tra lỗi (đầu vào xấu, trạng thái xấu, v.v.) là gì? Là tốt hơn để kiểm tra lỗi rõ ràng, hoặc sử dụng các chức năng như xác nhận có thể được tối ưu hóa từ mã cuối cùng của bạn? Tôi cảm thấy như kiểm tra một cách rõ ràng một chương trình có rất nhiều mã bổ sung không nên được thực thi trong hầu hết các tình huống - và không đề cập đến hầu hết các lỗi kết thúc với lỗi hủy bỏ / thoát. Tại sao làm lộn xộn một chức năng với kiểm tra rõ ràng chỉ để hủy bỏ? Tôi đã tìm kiếm các xác nhận so với kiểm tra lỗi rõ ràng và tìm thấy rất ít để thực sự giải thích khi nào nên làm.

Hầu hết nói 'sử dụng các xác nhận để kiểm tra lỗi logic và sử dụng kiểm tra rõ ràng để kiểm tra các lỗi khác.' Điều này dường như không đưa chúng ta đi rất xa mặc dù. Chúng tôi sẽ nói điều này là khả thi:

Malloc returning null, check explictly
API user inserting odd input for functions, use asserts

Điều này sẽ làm cho tôi tốt hơn trong việc kiểm tra lỗi? Tôi có thể làm gì nữa? Tôi thực sự muốn cải thiện và viết tốt hơn, mã 'chuyên nghiệp'.


3
Câu hỏi hay, nhưng tôi nghĩ nó có thể phù hợp hơn với một trong những trang web chị em (lập trình viên?).

Cảm ơn, tôi không chắc chắn. Tôi nghĩ rằng vì nó khá liên quan đến mã SO nên sẽ ổn thôi.
Anon

3
Câu trả lời đơn giản là "Đây là lý do tại sao các ngoại lệ được phát minh. Có được một ngôn ngữ tốt hơn."
DeadMG

1
@DeadMG: setjmp/ longjmpcó sẵn bằng C, vì vậy bạn không cần một ngôn ngữ mới.
dùng786653

3
@DeadMG: Một người không thể kiểm tra lỗi C có quyền có quả cầu tuyết trong địa ngục khi xử lý ngoại lệ C ++ ngay ...
Coder

Câu trả lời:


4

Cách dễ nhất để tôi nói sự khác biệt là xác định xem điều kiện lỗi được đưa ra vào thời gian biên dịch hay thời gian chạy. Nếu vấn đề là một lập trình viên sử dụng chức năng sai cách nào đó, hãy xác nhận để thu hút sự chú ý vào vấn đề, nhưng một khi bản sửa lỗi được biên dịch thành mã gọi, bạn không cần phải lo lắng về việc kiểm tra nữa. Các vấn đề như hết bộ nhớ hoặc đầu vào của người dùng cuối xấu không thể được giải quyết tại thời điểm biên dịch, vì vậy bạn để lại kiểm tra.


2

Kiểm tra bất cứ điều gì bất cứ lúc nào (nó có thể đã thay đổi sau lần kiểm tra cuối cùng của bạn) không phải là 100% theo lệnh của bạn . Và cũng: Trong quá trình phát triển, thậm chí không tin tưởng chính mình! ;-)

Okokok ... "bất cứ điều gì" có nghĩa được đọc là kiểm tra những thứ như vậy sẽ gây ra sự hủy bỏ bất thường hoặc bất cứ điều gì có thể khiến ứng dụng / hệ thống của bạn làm những việc không nên làm.

Nghiêm túc mà nói, phần cuối của câu cuối là rất cần thiết vì nó chỉ ra vấn đề chính:

Nếu bạn muốn xây dựng một hệ thống ổn định, mối quan tâm chính không phải là hệ thống nên làm gì, mà là để nó có thể làm những việc bắt buộc như vậy, người ta cần quan tâm đến những gì nó không nên làm, ngay cả khi nó "làm phiền bạn mã ".


1
+1 cho 'kiểm tra mọi thứ'. Tôi không mua đối số của sự lộn xộn mã: bất kỳ lập trình viên nào cũng có thể phân biệt giữa kiểm tra lỗi và logic thực tế.
stijn

2

Mấu chốt của việc xử lý lỗi không phải là liệu bạn có gặp rắc rối hay không. Đó là nhiều hơn những gì bạn làm sau khi bạn tìm hiểu về nó .

Trước hết - tôi sẽ nói, không có lý do tại sao bất kỳ lỗi đơn lẻ nào được trả về bởi phương thức cấp dưới trở lại không nên được xử lý. Và lỗi và ngoại lệ chỉ nhiều hơn giá trị trả về hoặc tất cả thử / bắt.

  1. Chỉ ném và bắt là không đủ.
    Xem điều này : nơi tác giả giải thích rằng chỉ bằng cách bắt nhưng không làm gì có khả năng ngăn chặn ngoại lệ và trừ khi thực hiện đủ để hoàn tác thiệt hại - điều tồi tệ hơn là để mã đi như vậy. Tương tự chỉ viết câu lệnh "log" khi có lỗi mở hoặc đọc tệp có thể giúp tìm ra lý do tại sao - nhưng khi chương trình kết thúc, nó có thể khiến dữ liệu bị hỏng! Nói tôi có nhiều lần thử / bắt là không đủ - điều quan trọng hơn là phải biết họ thực sự làm gì!

  2. Đừng lạm dụng thử và bắt.
    Đôi khi - chủ yếu là các lập trình viên lười biếng hoặc ngây thơ nghĩ rằng sau khi viết đủ thử / bắt, công việc của họ đã kết thúc và dễ dàng. Thông thường, tốt nhất là áp dụng hành động khắc phục và tiếp tục thay vì chỉ đổ toàn bộ. Nếu điều này không thể được thực hiện, người ta cần quyết định mức độ bạn cần quay lại. Tùy thuộc vào bối cảnh và mức độ nghiêm trọng, hãy thử bắt lồng cần thiết kế cẩn thận. Ví dụ- Xem cái nàycái này

  3. Xác định người chịu trách nhiệm:
    Một trong những điều đầu tiên bạn nên làm là xác định xem liệu đầu vào được cung cấp cho chính thường trình chỉ là một kịch bản không được chấp nhận (hoặc không được xử lý cho đến nay) hay là ngoại lệ do môi trường (như vấn đề hệ thống, vấn đề bộ nhớ) hoặc là tình huống này hoàn toàn phát sinh nội bộ từ kết quả thuật toán. Trong mọi trường hợp - mức độ bạn có thể muốn quay lại hoặc hành động bạn muốn thực hiện khác nhau đáng kể. Trong ánh sáng này, tôi muốn nói rằng - khi bạn chạy mã trong sản xuất - thực hiện hủy bỏ () để thoát khỏi chương trình là tốt - nhưng không phải cho mọi việc nhỏ. Nếu bạn phát hiện ra bộ nhớ bị hỏng hoặc hết bộ nhớ thì chắc chắn rằng ngay cả sau khi cố hết sức - mọi thứ sẽ chết. Nhưng nếu bạn nhận được một con trỏ NULL ở đầu vào - tôi sẽ '

  4. Xác định đâu là kết quả tốt nhất có thể:
    Những gì tất cả mọi thứ phải được thực hiện trong trường hợp ngoại lệ là rất quan trọng. Ví dụ: nếu trong một trong các trường hợp của chúng tôi - một trình phát đa phương tiện thấy rằng nó không có dữ liệu đầy đủ để phát cho người dùng - thì phải làm gì?

    • hoặc bỏ qua một số phần xấu và xem nếu nó có thể đi trước với những điều tốt.
    • Nếu điều này xảy ra quá nhiều xem xét nếu nó có thể bỏ qua bài hát tiếp theo.
    • nếu nó thấy rằng nó không thể đọc bất kỳ tập tin nào - hãy dừng lại và hiển thị một cái gì đó.
    • trong khi đó
    • người chơi nên bật POP-UP cho người dùng ở trạng thái nào và
    • Khi nào nó nên tự mang?
    • Có nên "tạm dừng" mọi thứ để yêu cầu người dùng phản hồi
    • hoặc nó nên đặt ghi chú lỗi nhỏ không phô trương ở một số góc?

    Tất cả những điều này là chủ quan - và có lẽ có nhiều cách để xử lý vấn đề hơn chúng ta điều tầm thường. Tất cả những điều trên đòi hỏi phải xây dựng và hiểu sâu về ngoại lệ và hơn là tạo ra các kịch bản khác nhau để có thể phát triển thành.

  5. Đôi khi chúng ta cần kiểm tra ngoại lệ trước khi chúng phát sinh. Ví dụ phổ biến nhất là chia cho sai số không. Lý tưởng nhất là người ta phải kiểm tra xem trước khi ngoại lệ đó được đưa ra - và nếu đó là trường hợp - hãy thử đặt giá trị khác không thích hợp nhất và tiếp tục thay vì tự sát!

  6. Dọn dẹp. Ít nhất đây là những gì bạn phải làm! Nếu một chức năng xảy ra để mở 3 tệp và tệp thứ tư không mở được - không cần phải nói 3 tệp đầu tiên đã bị đóng. Ủy thác công việc này cho một lớp ở trên là một ý tưởng tồi. nếu bạn quyết định không rời đi mà không dọn dẹp bộ nhớ. Và quan trọng nhất - ngay cả khi bạn đã sống sót qua ngoại lệ, hãy thông báo cho cấp trên rằng mọi thứ chưa diễn ra bình thường.

Cách chúng ta thấy chức năng (bình thường) của phần mềm theo các phân cấp hoặc lớp hoặc trừu tượng khác nhau, giống như cách chúng ta phải phân loại ngoại lệ dựa trên mức độ nghiêm trọng cũng như phạm vi mà chúng phát sinh và chúng đang ảnh hưởng đến các phần khác của hệ thống - điều đó xác định làm thế nào để xử lý các trường hợp ngoại lệ khác nhau theo cách tốt nhất có thể.

Tài liệu tham khảo tốt nhất: Code Craft chương 6 - có sẵn để tải về


1

Chỉ kiểm tra các lỗi trong quá trình xây dựng gỡ lỗi là BAD IDEA (tm), biên dịch theo phiên bản phát hành chồng các biến có thể sử dụng lại trên ngăn xếp, loại bỏ các trang bảo vệ, thực hiện các thủ thuật iffy bằng các phép tính, thay thế các phép đo nặng bằng các dịch chuyển được tính toán trước, v.v.

Cũng sử dụng kiểm tra lỗi trong bản phát hành, bạn có thể sử dụng một cái gì đó đơn giản như:

if(somethinghitthefan)
     abort();

Điều này cũng có tác dụng phụ rất tốt mà bạn chắc chắn sẽ không bỏ qua lỗi này khi ứng dụng bắt đầu gặp sự cố trên PC betta testers.

Người xem sự kiện và nhật ký hoàn toàn vô dụng so với abort(), ai vẫn kiểm tra chúng?


thoát / hủy bỏ == trải nghiệm người dùng tồi tệ nhất từng có: ứng dụng chỉ biến mất mà không cho biết lý do ..
stijn

@stijn: abortđột nhập vào trình gỡ lỗi / tạo kết xuất. exitlà xấu, vâng. Mặc dù, tôi thích __asm int 3nhất.
Coder

điều đó là đúng và trong C / C ++, tôi cũng có xu hướng viết các xác nhận bằng cách sử dụng __asm ​​int 3, nhưng không bao giờ không hiển thị ít nhất một mô tả về lý do, và tốt nhất là cả dòng và tệp. Sau đó, ít nhất khách hàng có thể cung cấp thông tin về những gì đã xảy ra chính xác.
stijn

0

Những điều khác nhau mà bạn có thể làm là
1. Đọc và đồng hóa nhiều mã trực tuyến và xem cách thực hiện
2.Sử dụng một số công cụ sửa lỗi để giúp bạn xác định vị trí các vùng lỗi
3. Nhận biết các lỗi nhỏ do gán sai và lỗi cú pháp.
4. Một số lỗi tồi tệ hơn phát sinh do lỗi logic trong chương trình khó tìm hơn. Hoặc điều này bạn có thể khắc phục và tìm hoặc đối với những lỗi phức tạp hơn hãy thử nói với mọi người hoặc sử dụng các tài nguyên như Stackoverflow , Wikipedia , google để nhận trợ giúp từ Mọi người.

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.