Điều gì có thể là nguyên nhân của các lỗi mới xuất hiện ở một nơi khác khi một lỗi đã biết được giải quyết?


14

Trong một cuộc thảo luận, một trong những đồng nghiệp của tôi nói rằng anh ta gặp một số khó khăn với dự án hiện tại của mình trong khi cố gắng giải quyết các lỗi. "Khi tôi giải quyết một lỗi, một thứ khác sẽ ngừng hoạt động ở nơi khác", anh nói.

Tôi bắt đầu suy nghĩ về việc làm thế nào điều này có thể xảy ra, nhưng không thể hiểu được.

  • Đôi khi tôi gặp vấn đề tương tự khi tôi quá mệt mỏi / buồn ngủ để thực hiện công việc một cách chính xác và để có cái nhìn tổng thể về phần mã tôi đang làm việc. Ở đây, vấn đề dường như là trong vài ngày hoặc vài tuần, và không liên quan đến trọng tâm của đồng nghiệp của tôi.
  • Tôi cũng có thể tưởng tượng vấn đề này phát sinh trong một dự án rất lớn, được quản lý rất tệ , nơi các đồng đội không có ý tưởng về việc ai làm gì và ảnh hưởng gì đến công việc của người khác có thể làm thay đổi họ đang làm. Đây cũng không phải là trường hợp: đó là một dự án khá nhỏ chỉ có một nhà phát triển.
  • Nó cũng có thể là một vấn đề với codebase cũ, được bảo trì kém và không bao giờ được ghi nhận , nơi các nhà phát triển duy nhất thực sự có thể tưởng tượng hậu quả của một thay đổi đã rời khỏi công ty nhiều năm trước. Ở đây, dự án chỉ mới bắt đầu và nhà phát triển không sử dụng cơ sở mã của bất kỳ ai.

Vì vậy, điều gì có thể là nguyên nhân của vấn đề như vậy trên một cơ sở mã mới, kích thước nhỏ được viết bởi một nhà phát triển duy nhất tập trung vào công việc của mình ?

Điều gì có thể giúp đỡ?

  • Kiểm tra đơn vị (không có)?
  • Kiến trúc phù hợp (Tôi khá chắc chắn rằng codebase hoàn toàn không có kiến ​​trúc và được viết không có suy nghĩ sơ bộ), đòi hỏi phải tái cấu trúc toàn bộ?
  • Lập trình cặp?
  • Thứ gì khác?

14
Ah, mẫu thiết kế "sóng xếp tầng thất bại" tốt của ol. :-)
Brian Knoblauch

1
Tôi ví nó như một bong bóng trong một tờ liên lạc. Đẩy nó xuống, nó bật lên ở nơi khác. Mã hóa của tôi càng tốt, tôi càng thấy ít hơn
johnc

2
Bên cạnh đó, tôi đã có chính xác điều đó trên một hệ thống nhúng. Tôi đã thêm một cuộc gọi chức năng để khắc phục một vấn đề. Cuộc gọi chức năng đó là quá nhiều cho ngăn xếp (vi điều khiển không có phát hiện stackoverflow) và vì vậy nó đã viết một số thứ ngẫu nhiên ở nơi khác vào bộ nhớ, tất nhiên đã phá vỡ một cái gì đó hoàn toàn khác. Vì vậy, điều này CÓ THỂ xảy ra trên một cơ sở mã nhỏ chỉ có một nhà phát triển và kiến ​​trúc tốt.
tăngDarkness

... Và đó là một cơn ác mộng để gỡ lỗi.
tăngDarkness

Câu trả lời:


38

Nó không liên quan nhiều đến trọng tâm, quy mô dự án, tài liệu hoặc các vấn đề quy trình khác. Các vấn đề như vậy thường là kết quả của sự khớp nối quá mức trong thiết kế, điều này khiến cho việc cô lập các thay đổi rất khó khăn.


15
điều này kết hợp với thử nghiệm hồi quy kém hoặc không hồi quy
Ryathal

3
Đúng, @Ryathal, mặc dù thử nghiệm hồi quy sẽ không ngăn được các loại lỗi đó, chỉ cần cho bạn biết về chúng sớm hơn.
Karl Bielefeldt

Nếu bạn biết về chúng sớm (ví dụ trong vòng vài phút tạo lỗi) thì bạn có thể hoàn tác các thay đổi của mình và giả vờ hiệu quả chúng không bao giờ xảy ra.
bdsl

14

Một trong những nguyên nhân có thể là sự kết hợp chặt chẽ giữa các thành phần của phần mềm của bạn: nếu không có giao diện đơn giản, được xác định rõ ràng giữa các thành phần, thì ngay cả một thay đổi nhỏ trong một phần của mã cũng có thể gây ra tác dụng phụ không mong muốn ở các phần khác của mã.

Ví dụ, gần đây tôi đang làm việc trên một lớp thực hiện một thành phần GUI trong ứng dụng của mình. Trong nhiều tuần, các lỗi mới đã được báo cáo, tôi đã sửa chúng và các lỗi mới xuất hiện ở một nơi khác. Tôi nhận ra rằng lớp học đã phát triển quá lớn, đang làm quá nhiều thứ và nhiều phương thức phụ thuộc vào các phương thức khác được gọi theo đúng trình tự để hoạt động đúng.

Thay vì sửa ba lỗi mới nhất, tôi đã thực hiện một số tái cấu trúc mạnh: chia thành phần thành một lớp chính cộng với các lớp MVC (ba lớp bổ sung). Theo cách này, tôi phải chia mã thành các phần nhỏ hơn, đơn giản hơn và xác định các giao diện rõ ràng hơn. Sau khi tái cấu trúc, tất cả các lỗi đã được giải quyết và không có lỗi mới nào được báo cáo.


7

Thật dễ dàng để một lỗi để che giấu một lỗi khác. Giả sử lỗi "A" dẫn đến chức năng sai được gọi để xử lý đầu vào. Khi lỗi "A" được sửa, đột nhiên chức năng đúng được gọi, chưa bao giờ được kiểm tra.


5

Chà, nguyên nhân trước mắt là hai cái sai làm cho một cái đúng, hoặc ít nhất là làm cho một cái không rõ ràng là sai. Một phần của mã đang bù cho hành vi không chính xác của phần kia. Hoặc nếu phần đầu tiên không "sai" như vậy, có một số thỏa thuận bất thành văn giữa hai phần bị vi phạm khi thay đổi mã.

Ví dụ: giả sử các hàm A và B sử dụng quy ước dựa trên số không cho một số lượng, để chúng hoạt động chính xác với nhau, nhưng C sử dụng một, bạn có thể "sửa" A để làm việc với C và sau đó phát hiện ra sự cố với B.

Vấn đề sâu xa hơn là thiếu xác minh độc lập về tính chính xác của các bộ phận riêng lẻ. Kiểm tra đơn vị được thiết kế để giải quyết điều này. Họ cũng hoạt động như một đặc điểm kỹ thuật của đầu vào thích hợp. Ví dụ, một bộ kiểm tra tốt sẽ làm rõ rằng các chức năng A và B dự kiến ​​đầu vào dựa trên 0 và dựa trên C 1.

Nhận thông số kỹ thuật đúng cũng có thể được thực hiện theo những cách khác, từ các tài liệu chính thức đến các nhận xét tốt trong mã, tùy thuộc vào nhu cầu của dự án. Điều quan trọng là hiểu được mỗi thành phần mong đợi và những gì nó hứa hẹn, vì vậy bạn có thể tìm thấy sự không nhất quán.

Kiến trúc tốt giúp giải quyết vấn đề hiểu mã, làm cho việc này dễ dàng hơn. Lập trình cặp là hữu ích để tránh lỗi ở nơi đầu tiên, hoặc tìm thấy chúng nhanh hơn.

Hi vọng điêu nay co ich.


5

Khớp nối chặt chẽ, thiếu kiểm tra, đây có lẽ là những thủ phạm phổ biến nhất. Về cơ bản, vấn đề chung chỉ là các tiêu chuẩn và thủ tục kém chất lượng. Một cách khác là quản lý mã không chính xác để có được may mắn trong một thời gian với hành vi đúng. Xem xét memcpylỗi từ Linus Torvalds khi thay đổi triển khai (không gây ra) lỗi trong các máy khách được sử dụng memcpyở những nơi đáng lẽ phải sử dụng memmovevới nguồn và đích chồng chéo.


4

Có vẻ như những lỗi "mới" này không thực sự là những lỗi "mới". Chúng chỉ không phải là một vấn đề, cho đến khi mã khác bị hỏng, thực sự đã được sửa. Nói cách khác, đồng nghiệp của bạn không nhận ra rằng anh ta thực sự có hai lỗi trong toàn bộ thời gian. Nếu mã không được chứng minh bị phá vỡ sẽ không bị hỏng, nó sẽ không bị lỗi, một khi các đoạn mã khác thực sự được sửa.

Trong cả hai trường hợp, chế độ kiểm tra tự động tốt hơn có thể hữu ích. Có vẻ như đồng nghiệp của bạn cần đơn vị kiểm tra cơ sở mã hiện tại. Trong thử nghiệm hồi quy trong tương lai sẽ xác minh mã hiện có tiếp tục hoạt động.


0

Cải thiện bề rộng của chế độ kiểm tra tự động của bạn. LUÔN LUÔN chạy toàn bộ các thử nghiệm trước khi thực hiện thay đổi mã. Bằng cách đó, bạn sẽ phát hiện ra tác động nguy hiểm của những thay đổi của mình.


0

Tôi chỉ gặp phải điều này khi một bài kiểm tra không chính xác. Các thử nghiệm đã kiểm tra một trạng thái cho phép đã được chính xác! Tôi đã cập nhật mã và chạy thử nghiệm cho phép. Nó đã làm việc. Sau đó tôi chạy tất cả các bài kiểm tra. Tất cả các thử nghiệm khác sử dụng tài nguyên đã kiểm tra đều thất bại. Tôi đã sửa bài kiểm tra và kiểm tra giấy phép, nhưng lúc đầu có chút hoảng loạn.

Thông số kỹ thuật không nhất quán xảy ra là tốt. Sau đó, gần như đảm bảo rằng việc sửa một lỗi sẽ tạo ra một lỗi khác (thú vị khi phần cụ thể đó không được thực hiện cho đến sau này trong dự án).


0

Hãy tưởng tượng rằng bạn có một sản phẩm hoàn chỉnh. Sau đó, bạn thêm một cái gì đó mới, mọi thứ có vẻ tốt, nhưng bạn đã phá vỡ một thứ khác, điều này phụ thuộc vào một số mã mà bạn thay đổi để làm cho tính năng mới hoạt động. Ngay cả khi bạn không thay đổi bất kỳ mã nào, chỉ cần thêm chức năng vào hiện tại, nó có thể đã phá vỡ thứ khác.

Vì vậy, về cơ bản, bạn gần như tự trả lời:

  • khớp nối lỏng lẻo
  • thiếu các bài kiểm tra

Chỉ cần học cách thích ứng với nguyên tắc TDD (ít nhất là đối với các tính năng mới) và thử kiểm tra mọi trạng thái có thể xảy ra.

Lập trình cặp là tuyệt vời, nhưng không phải lúc nào cũng "có sẵn" (thời gian, tiền bạc, cả ..). Nhưng đánh giá mã (ví dụ bởi đồng nghiệp của bạn) một lần một ngày / tuần / bộ cam kết cũng sẽ giúp ích rất nhiều, đặc biệt, khi đánh giá bao gồm bộ kiểm tra. (Tôi thấy thật khó để không viết lỗi vào bộ kiểm tra ... đôi khi tôi phải kiểm tra nội bộ (kiểm tra độ chính xác) :)).


0

Giả sử nhà phát triển A đã viết một số mã có lỗi. Mã không chính xác những gì nó phải làm, nhưng một cái gì đó hơi khác. Nhà phát triển B đã viết mã dựa vào mã của A để thực hiện chính xác những gì được quy định và mã của B không hoạt động. B điều tra, tìm ra hành vi không chính xác trong mã của A và sửa nó.

Trong khi đó, mã của nhà phát triển C chỉ hoạt động chính xác vì anh ta dựa vào hành vi không đúng của mã A. Mã của A là chính xác. Và mã của C ngừng hoạt động. Điều đó có nghĩa là khi bạn sửa mã, bạn cần kiểm tra thật kỹ xem ai sử dụng mã này và hành vi của họ sẽ thay đổi như thế nào với mã cố định.

Tôi đã có một tình huống khác: Một số mã bị lỗi và dừng hoàn toàn một tính năng hoạt động trong một số tình huống X. Vì vậy, tôi đã thay đổi hành vi sai và làm cho tính năng này hoạt động. Tác dụng phụ đáng tiếc là toàn bộ tính năng có vấn đề nghiêm trọng trong tình huống X và thất bại ở mọi nơi - điều này hoàn toàn không được ai biết đến vì tình huống này chưa từng xảy ra trước đây. Chà, thật khó khăn.

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.