+2

Gỡ lỗi chương trình

Hôm nay mình muốn nói về “Gỡ lỗi”(Debugging) 🐞, một qui trình sửa lỗi trong chương trình phần mềm.

Điều quan trọng đầu tiên cần nhớ là:

Đừng cảm thấy thất vọng khi bạn tạo ra một con bug.

Khi viết một chương trình thì việc gặp bug 🐞 là việc đương nhiên 🥲, vì khi đã viết chương trình ⌨️ tức là mình đã bắt đầu một việc để tạo ra các bạn ấy cơ mà. Đó có thể là sai cú pháp, sai chính tả, chương trình không chạy đúng, …

Sau khi đã có một mindset đúng đắn hơn(như ở trên), là không sợ bug, bug là chuyện đương nhiên, may quá có bug rồi, bug mình gặp thì review code sẽ không gặp, QA sẽ không mắc công bắt, lên production lại đỡ làm phiền người dùng. Cho nên:

Bug là bạn, bug là bạn, bug là bạn nha 🥲

Tiếp theo sẽ là một số mẹo và kỹ thuật để nhận dạng bug và sửa nó hiệu quả:

✍️ Mô tả vấn đề(describe the problem)

Để fix bug, đầu tiên bạn cần mô tả được vấn đề mà mình gặp phải.

Đôi khi có những vấn đề đơn giản chỉ cần bạn mô tả và kiểm tra vài thông tin liên quan là có thể sửa được rồi.

Ví dụ: Thực hiện in ra một danh sách các số từ 1 đến 5 với đoạn code Python sau:

Mô tả vấn đề:

Không có số 5 trong danh sách như mong đợi dù range(1, 5) là mong đợi sẽ trả về từ 1 đến 5.

Sửa lỗi:

Để giải quyết vấn đề này sẽ cần đọc lại về hàm range, bạn sẽ thấy cú pháp là:

range(start, stop, step=1) với stop sẽ bị bỏ qua.

Do đó muốn giải quyết thì mình cần tăng stop từ 5 lên 6, tức range(1, 6)

🐞 Tái tạo lại lỗi(reproduce the bug)

Rất nhiều khi bug chỉ thỉnh thoảng xuất hiện. Để fix được những bug như vậy lập trình viên cần biết cách tái tạo lại con bug đó và tìm hiểu chính xác vấn đề mà trường hợp đó gặp phải là gì thì mới có thể sửa lỗi được

Ví dụ:

Giả sử bạn có một danh sách: numbers = [1, 2, 3, 4, 5, 6]. Bạn muốn chọn ngẫu nhiên một số trong 6 số ở trên. Gọi choice = randint(1, 6) để chọn số từ 1 đến 6 và kết quả chọn được sẽ là numbers[choice]

Khi chạy chương trình, bạn sẽ thấy chương trình chạy ổn.

Tuy nhiên nếu chạy nhiều lần thì sẽ có một lỗi như thế này xuất hiện:

Vậy làm sao có thể tái tạo lại lỗi này nhỉ?

Tái tạo lỗi:

Đầu tiên, choice = randint(1, 6) nên mình cần đọc lại về randint, bạn sẽ thấy nó được mô tả là sẽ trả về một số nguyên giữa khoảng 1 và 6, bao gồm cả số 1, 6.

Bạn có thể thử nghiệm bằng cách gán giá trị từ 1 đến 6 cho biến choice để thấy được là khi choice = 6 thì sẽ có lỗi trên xuất hiện.

**Sửa lỗi: **

Như vậy ở đây lỗi sẽ xảy ra với số 6 vì numbers có 6 phần tử với index đếm từ 0 đến 5. Do đó lỗi này sẽ được sửa với choice = randint(1, 5)

💻 Thử đóng vai là máy tính(play computer)

Với một chương trình phức tạp như có logic với nhiều điều kiện rẽ nhánh, hay gọi nhiều hàm khác nhau, thì việc sửa lỗi sẽ càng khoai hơn.

Lúc này bạn cần tưởng tượng mình là máy tính, và bạn tự kiểm tra từng dòng một của chương trình như cách máy tính chạy để tìm manh mối cho lỗi của mình.

Ví dụ: Đoạn chương trình dưới đây sẽ kiểm tra nếu số tuổi nhỏ hơn 16 và lớn hơn 60 sẽ không được chơi trò chơi.

Mô tả vấn đề: khi nhập 16 tuổi thì lại không in ra gì cả.

Play computer: Để sửa được lỗi này, mình sẽ áp dụng Play computer như sau:

– Đầu tiên, year_old được nhập là 16, ở dòng số 1

– Tiếp theo, máy tính sẽ chạy đến dòng số 4:

  – `year_old > 60 tức là `16 > 60` là `False`

year_old < 16 tức là 16 < 16False

Do đó ở đây là: if False and False. Kết quả là False, nên dòng số 5 sẽ không được thực thi.

– Tiếp theo, máy tính sẽ chạy đến dòng số 6, year_old > 1616 > 16 cũng là False, nên dòng số 7 cũng không được thực thi

Vậy kết quả là không in gì ra hết.

Sửa lỗi: Vì 16 không có điều kiện đúng ở đâu cả, nên mình cần làm 16 trả về True để có thể chơi game, tức là thay vì year_old > 16 sẽ là year_old >= 16

🏹 Sửa lỗi(fix the errors)

Khi bạn viết chương trình, nếu trình soạn thảo(editor) hiển thị các lỗi(như hiện gạch đỏ ở nơi có lỗi)

Khi bạn chạy chương trình, nếu có lỗi hiển thị các lỗi thì bạn cũng cần sửa chúng. Bạn có thể đọc thông tin của lỗi hiện ra, và cũng có thể dùng thông tin đó tìm trên mạng(StackOverflow).

Và cũng có những lỗi mà không có bất cứ thông tin hay lỗi nào thực sự xuất hiện.

Ví dụ bạn viết:

print("Hello {name}") thì kết quả sẽ là Hello {name}, chỉ đơn giản là nó không đúng với cái bạn mong đợi Hello Thanh với name ở đây là Thanh.

Để sửa lỗi này, bạn cần phải xem lại các kiến thức mình đã học, cụ thể ở đây là dùng một biến trong chuỗi ký tự thì sẽ cần có f-strings, nên sửa lại là print(f"Hello {name}")

🛠 Dùng các công cụ hỗ trợ kiểm tra lỗi(print, log, debugger)

Cuối cùng, để kiểm tra chính xác từng kết quả khi chương trình thực thi, bạn có thể dùng các câu lệnh in ra màn hình(print) để kiểm tra các tham số, kết quả hay chỉ là chương trình đã chạy đến dòng nào đó hay chưa. Như chương trình if/else với year_old ở trên là chưa in ra các câu tức là chương trình chưa chạy vào đó.

Debugger là một công cụ mạnh mẽ hơn cả print, nó giúp bạn đi qua từng dòng code và xem chương trình thực thi ra sao(với Python bạn có thể dùng pythontutor hay Thony, VSCode Debugger)

Đây là một ví dụ mình thực hiện debug với pythontutor.com:


Trên đây là Trên đây là một vài note từ bài học gỡ lỗi mà mình học được, chúc các bạn code ít bug và gặp bug thì không ngại nha.

Nếu bạn có những cách gỡ lỗi nào hiệu quả thì giới thiệu đến mình và độc giả của BeautyOnCode với nhé.

Bài gốc của blog này nằm ở blog cá nhân của mình, mời bạn ghé chơi!

Nếu thích bạn cũng có thể follow fanpage này để nhận thông báo bài viết mới nhé.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.