Category Archives: 05.Xử lý biệt lệ

Bài 16-Cách gỡ lỗi Kotlin bằng công cụ Debug


bài 15 Tui đã trình bày cách xử lý biệt lệ để kiểm soát lỗi phát sinh trong quá trình runtime. Tuy nhiên để lần vết tường tận từng bước chương trình thực hiện để tìm ra các lỗi khó như lỗi Logic thì bắt buộc ta phải sử dụng công cụ Debug, phần mềm IntelliJ IDEA đã tích hợp sẵn công cụ Debug giúp chúng ta dễ dàng lần vết.

Theo kinh nghiệm của Tui thì thời gian viết mã lệnh mới chiếm khoảng 40% còn 60% thời gian còn lại là chúng ta phải lần vết sửa lỗi (nói cho sang miệng thì giới lập trình viên gọi bằng cụm từ Fix Bug). Dĩ nhiên con số này chỉ là cảm tính của Tui thôi, nó không phải là 1 con số chính xác cho từng lập trình viên. Nhưng Tui cam đoan rằng thời gian Fix Bug phải luôn luôn > thời gian viết code mới.

Với một công cụ Debug bất kỳ thì ta thường có 3 thao tác chính:

  1. Cách đặt break point
  2. Cách debug từng dòng
  3. Cách xem giá trị của biến trong khi debug

Bây giờ Tui sẽ hướng dẫn chi tiết từng thao tác trong công cụ IntelliJ IDEA để  bạn Debug nhé, giả sử Tui có đoạn lệnh giải phương trình bậc 2 dưới đây (Tui đang chủ ý làm sai Logic), nhiệm vụ của ta là tìm ra các lỗi sai Logic này bằng công cụ Debug:


fun NhapGiaTri():Double
{
var s:String?= readLine()
if(s!=null)
return s.toDouble()
return 0.0
}
fun main(args: Array) {
var a:Double=0.0
var b:Double=0.0
var c:Double=0.0
println("Nhập a:")
a=NhapGiaTri()
println("Nhập b:")
b=NhapGiaTri()
println("Nhập c:")
c=NhapGiaTri()
if(a==0.0)
{
if(b==0.0 && c==0.0)
println("PT Vô số No")
else if(b==0.0 && c!=0.0)
println("PT Vô No")
else
println("X="+(-b/c))
}
else
{
val delta:Double=Math.pow(b,2.0)-4*a*c
if(delta<0)
println("Vô nghiệm")
else if(delta==0.0)
{
var x:Double=-b/(2*a)
println("No kép x1=x2=$x")
}
else
{
var x1:Double=(b-Math.sqrt(delta))/(2*a)
var x2:Double=(b+Math.sqrt(delta))/(2*a)
println("x1=$x1")
println("x2=$x2")
}
}
}

Nhìn lệnh trên bạn phát hiện ra sai Logic chỗ nào?

Tui đưa ra 2 trường hợp để Test xuất hiện lỗi Logic bên trên như sau:

1.Trường hợp 1:  0x^2+5x+2=0

Nếu đúng thì kết quả phải là x=-0.4, nhưng khi chạy lên kết quả lại là x=-2.5 đây chính là lỗi sai Logic đầu tiên

2.Trường hợp 2: x^2+5x-6 =0

Nếu đúng thì kết quả sẽ là: x1=-6, x2= 1. Nhưng kết quả ở trên lại ra x1=-1.0, x2=6.0 đây chính là lỗi sai Logic thứ 2

Vậy làm sao sửa cho đúng? thường ta phải Debug vào từng dòng để kiểm tra (dĩ nhiên khi làm thực tế thì chả bao giờ gặp những giải thuật tầm thường như thế này, đây là Tui lấy ví dụ cụ thể bài giải phương trình bậc 2 để hướng dẫn các bạn cách thức Debug và cũng chỉ rõ luôn 2 chỗ sai Logic) .

Bây giờ ta đi vào chi tiết:

Bước 1: Muốn dừng lại kiểm tra lệnh ở dòng nào thì tạo break point ở dòng đó (bước này gọi là đặt Break Point):

Ví dụ bạn muốn đặt Break Point ở dòng lệnh 25 và dòng lệnh 39 thì lần lượt bấm chuột vào kế bên số dòng chỗ mũi tên màu đỏ Tui trỏ tới đó, nó sẽ xuất hiện Núm tròn màu đó, muốn bỏ nó thì Bấm lại lần nữa:

Khi dòng nào có Núm tròn đỏ xuất hiện thì chính là Break Point được đặt thành công.

Bước 2: Chạy Debug từng dòng

Ta vào menu Run/ chọn Debug App_debug.kt (là tập tin mà ta viết lệnh main muốn Debug)

Chương trình sẽ thực thi và ta nhập các giá trị cho các biến:

Ở trên ta thử nhập a=0, b=5 và c=2 ==> lúc này chương trình sẽ tự động xuất hiện Tab Debugger kế bên Tab Console và di chuyển con trỏ lệnh tới dòng 25 mà ta đã đặt Break Point:

Ở màn hình trên ta có thể thấy được giá trị của các biến ngay dòng debug.

Và công cụ ở chế độ Debug cho phép ta dùng các phím F7, F8, F9 để điều hướng quá trình Debug:

F7 là đi vào bên trong phương thức được triệu gọi, F8 là vượt qua phương thức triệu gọi, F9 là quay trở về chế độ bình thường. Và còn nhiều các phím tắt khác các bạn có thể test.

Bước 3: Cách xem giá trị của biến trong khi debug

Để xem thêm các giá trị của các Biến trong quá trình Debug, IntelliJ IDEA còn cung cấp chức năng Add to Watches (bôi đen biến bất kỳ -> bấm chuột phải –>chọn Add to Watches):

Sau khi chọn Add to Watches –> biến này sẽ được xuất hiện trong màn hình Variables:

Ta nhấn F8 để chạy tiếp thì thấy kết quả:

Dĩ nhiên vì lỗi Logic Tui nói trước nên tới đây ta cũng biết kết quả nó sai, và cần sửa lại lệnh cho đúng (thực tế nó khó hơn nhiều, có khi bạn phải F7 F8 cả ngày chưa chắc tìm ra nó lỗi chỗ nào mà sửa)

Tương tự như vậy bạn Test trường hợp thứ 2 là có 2 nghiệm phân biệt bị sai

Như vậy tới đây Tui đã hướng dẫn xong cách gỡ lỗi Kotlin bằng công cụ Debug, các bạn chú ý học kỹ và hiểu được nó thông qua các ví dụ ở trên nhé. Cần thành thạo công cụ Debug, các phím duyệt debug cũng như add to Watches để có thể áp dụng tốt vào các dự án thực tế của mình.

Các bạn có thể tải source code sai logic bài này ở đây: http://www.mediafire.com/file/zo2t52p0qorz1dz/HocDebug.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://ssoftinc.com/)

Bài 15-Xử lý biệt lệ trong Kotlin


Tại sao phải xử lý biệt lệ?

Trong quá trình thực thi phần mềm sẽ có những lỗi phát sinh mà trong quá trình coding ta đã dự đoán hoặc chưa dự đoán được

Việc kiểm soát các biệt lệ giúp cho phần mềm tiếp tục hoạt động nếu lỗi xảy ra hoặc cũng đưa ra các gợi ý bên phía User Problem

Khi lập trình thường chúng ta gặp 3 cấp độ lỗi:

  • Lỗi biên dịch (mới học lập trình, viết đâu sai đó… rất đáng thương)
  • Lỗi runtime exception (học lập trình chưa thông, chạy lên báo lỗi om sòm)
  • Lỗi logic exception – sai nghiệp vụ yêu cầu (đã thành lập trình viên, gặp những lỗi khó sửa)

Và khi gặp lỗi thì thường có 2 hành vi với lỗi: Không quan tâm (Unchecked error) và quan tâm(Checked error)

Để hướng tới lập trình viên chuyên nghiệp thì ta cần quan tâm tới những lỗi này, phải kiểm tra cẩn thận để khi có gặp lỗi xảy ra thì chương trình vẫn tiếp tục mà không bị tắt ngang.

Kotlin hỗ trợ chúng ta cú pháp tổng quát để xử lý biệt lệ như sau:

try {

// viết lệnh ở đây và các lệnh này có khả năng sinh ra lỗi

}

catch (e: SomeException) {

// handler lỗi ở đây -> thông báo lỗi chi tiết để biết mà sửa cái gì

}

finally {

// optional finally block – cho dù có lỗi hay không có lỗi xảy ra thì block luôn luôn thực hiện

}

Ví dụ 1: Viết chương trình chia 2 số a và b. Chủ ý cho mẫu số =0 để sinh ra lỗi


fun main(args: Array) {
try {
var a:Int=5
var b:Int=0;
var c=a/b
println("$a/$b=$c")
}
catch (e:Exception)
{
println(e.message)
}
finally {
println("Đây là finally, 100% chạy, cho dù lỗi hay không")
}
}

Khi chạy đoạn lệnh ở trên thì đến dòng a/b sẽ sinh ra lỗi và nó nhảy vào exception, sau đó finally sẽ được thực hiện:

/ by zero
Đây là finally, 100% chạy, cho dù lỗi hay không

Ngoài ra Kotlin cũng hỗ trợ từ khóa throws để ném lỗi này ra nơi khác, những chỗ nào gọi nó sẽ xử lý lỗi này.

Ví dụ 2:


fun chia(a:Int,b:Int):Int
{
if(b==0)
throw Exception("Mẫu số =0")
return a/b
}
fun main(args: Array) {
chia(5,0)
println("Cám ơn!")
}

Khi chạy chương trình ở ví dụ 2 lên thì nó sẽ xuất ra thông báo lỗi: Mẫu số =0 và tắt ngang phần mềm, không cho dòng chữ “Cám ơn”có cơ hội xuất hiện. VÌ lúc này ta chưa dùng try..catch để checked error:

Exception in thread “main” java.lang.Exception: Mẫu số =0
at App_bietle_throwsKt.chia(app_bietle_throws.kt:7)
at App_bietle_throwsKt.main(app_bietle_throws.kt:11)

Ta sửa lại mã lệnh ở trên để khi có lỗi xảy ra thì chương trình vẫn tiếp tục hoạt động:

Ví dụ 3:


fun chia(a:Int,b:Int):Int
{
if(b==0)
throw Exception("Mẫu số =0")
return a/b
}
fun main(args: Array) {
try {
chia(5, 0)
}
catch (e:Exception)
{
println(e.message)
}
println("Cám ơn!")
}

Khi có try .. catch thì cho dù có lỗi xảy ra, chương trình vẫn tiếp tục thực hiện các lệnh còn lại (tránh tắt ngang phần mềm), chương trình trên khi chạy sẽ có kết quả:

Mẫu số =0
Cám ơn!

Như vậy tới đây Tui đã hướng dẫn xong xử lý biệt lệ trong Kotlin, các bạn chú ý học kỹ và hiểu được nó thông qua các ví dụ ở trên nhé. Đặc biệt nắm được cách thức vận hành của try..catch..finally…throw để có thể áp dụng tốt vào các dự án thực tế của mình.

Các bạn có thể tải source code bài này ở đây: http://www.mediafire.com/file/ko46c0s2d476669/HocXuLyBietLe.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://ssoftinc.com/)

%d bloggers like this: