Mục lục bài họcĐang ở d06-b3
Program design, testing and maintenance
Decomposition and modularity
Break a problem into subproblems, each solved by a procedure (no return value) or function (returns a value). Parameters may be passed by value — the routine gets a copy and the original is unchanged — or by reference, where the routine can change the caller's variable. Local variables exist only inside the routine, which is what makes modules independent and reusable.
Structured English and pseudocode
Use IF … THEN … ELSE … ENDIF, FOR … NEXT, WHILE … ENDWHILE, REPEAT … UNTIL. A WHILE loop may run zero times because the condition is tested first; a REPEAT loop always runs at least once. Choosing the wrong one is a standard exam trap.
Test data, in three kinds
Normal data should be accepted; abnormal (erroneous) data should be rejected; boundary data sits exactly on the edge of the acceptable range and is where most defects hide. For a value that must be $1$–$100$, the boundary tests are $0$, $1$, $100$ and $101$ — and giving both sides of each edge is what earns the marks.
Kinds of testing
Unit or module testing checks one routine; integration testing checks they work together; alpha testing is in-house; beta testing uses real users; acceptance testing checks the requirements are met.
Maintenance
Corrective fixes faults found after release; adaptive changes the program for a new environment or new law; perfective improves performance or usability. Most of a system's lifetime cost is maintenance, not writing it — which is the real argument for clear naming, comments and modular design.
Phân rã và mô-đun hoá
Chia bài toán thành các bài toán con, mỗi cái do một thủ tục (không trả về giá trị) hoặc một hàm (có trả về giá trị) giải quyết. Tham số có thể truyền theo giá trị — chương trình con nhận một bản sao và biến gốc không đổi — hoặc theo tham chiếu, khi chương trình con thay đổi được biến của nơi gọi. Biến cục bộ chỉ tồn tại bên trong chương trình con, và chính điều đó làm các mô-đun độc lập và dùng lại được.
Mã giả
Dùng IF … THEN … ELSE … ENDIF, FOR … NEXT, WHILE … ENDWHILE, REPEAT … UNTIL. Vòng WHILE có thể chạy $0$ lần vì điều kiện được kiểm TRƯỚC; vòng REPEAT luôn chạy ít nhất một lần. Chọn nhầm loại vòng lặp là một cái bẫy quen thuộc của đề thi.
Dữ liệu kiểm thử, ba loại
Dữ liệu bình thường phải được chấp nhận; dữ liệu bất thường (sai) phải bị từ chối; dữ liệu biên nằm đúng ở mép của khoảng hợp lệ và đó là nơi phần lớn lỗi ẩn nấp. Với một giá trị bắt buộc trong khoảng $1$–$100$, các trường hợp biên là $0$, $1$, $100$ và $101$ — và nêu đủ cả HAI phía của mỗi mép mới được điểm.
Các loại kiểm thử
Kiểm thử đơn vị hoặc mô-đun kiểm một chương trình con; kiểm thử tích hợp kiểm chúng phối hợp với nhau; kiểm thử alpha làm nội bộ; kiểm thử beta dùng người dùng thật; kiểm thử nghiệm thu kiểm xem yêu cầu đã được đáp ứng chưa.
Bảo trì
Sửa lỗi khắc phục sai sót phát hiện sau khi phát hành; thích nghi sửa chương trình cho môi trường mới hoặc quy định mới; hoàn thiện cải thiện hiệu năng hoặc tính dễ dùng. Phần lớn chi phí trong vòng đời một hệ thống nằm ở bảo trì chứ không ở lúc viết — và đó mới là lý lẽ thực sự cho việc đặt tên rõ ràng, viết chú thích và thiết kế mô-đun.
Viết mã giả cho một chương trình yêu cầu người dùng nhập điểm từ $0$ đến $100$, lặp lại cho tới khi nhập hợp lệ, rồi in xếp loại: $\ge80$ Giỏi, $\ge65$ Khá, $\ge50$ Đạt, còn lại Chưa đạt.
Sau đó lập bảng dữ liệu kiểm thử.
Mã giả
REPEAT
OUTPUT "Nhập điểm (0-100): "
INPUT Diem
IF Diem < 0 OR Diem > 100 THEN
OUTPUT "Điểm không hợp lệ"
ENDIF
UNTIL Diem >= 0 AND Diem <= 100
IF Diem >= 80 THEN
OUTPUT "Giỏi"
ELSE IF Diem >= 65 THEN
OUTPUT "Khá"
ELSE IF Diem >= 50 THEN
OUTPUT "Đạt"
ELSE
OUTPUT "Chưa đạt"
ENDIF
Vì sao dùng REPEAT chứ không WHILE: phải nhập ít nhất một lần trước khi có gì để kiểm tra. Dùng WHILE ở đây sẽ phải khởi tạo Diem bằng một giá trị giả trước vòng lặp — dài hơn và dễ sai hơn.
Vì sao thứ tự IF phải từ CAO xuống THẤP: nếu kiểm $\ge50$ trước thì điểm $90$ sẽ rơi vào nhánh ‘Đạt’ và không bao giờ tới được nhánh ‘Giỏi’.
Bảng dữ liệu kiểm thử
Bình thường: $72$ ⇒ Khá; $55$ ⇒ Đạt; $91$ ⇒ Giỏi. (Chọn giá trị nằm giữa mỗi khoảng để kiểm từng nhánh.)
Bất thường: $-5$ ⇒ báo lỗi và hỏi lại; $150$ ⇒ báo lỗi và hỏi lại; "abc" ⇒ phải bị từ chối (kiểm kiểu dữ liệu).
Biên — quan trọng nhất và phải đi theo CẶP:
$-1$ và $0$ (mép dưới của khoảng hợp lệ)
$100$ và $101$ (mép trên)
$49$ và $50$ (mép Chưa đạt / Đạt)
$64$ và $65$ (mép Đạt / Khá)
$79$ và $80$ (mép Khá / Giỏi)
Vì sao phải đi theo cặp: chỉ thử $80$ thì không phát hiện được lỗi lập trình viên viết > thay vì >=. Cặp $79$–$80$ mới phân biệt được hai trường hợp đó, và đây chính là loại lỗi mà kiểm thử biên sinh ra để bắt.
> với >=, và một giá trị đơn lẻ không phát hiện được.WHILE kiểm điều kiện trước nên có thể chạy $0$ lần; REPEAT luôn chạy ít nhất một lần. Dữ liệu kiểm thử phải đủ ba loại, và biên phải đi theo cặp. Nhớ ba loại bảo trì và nhớ rằng bảo trì mới chiếm phần lớn chi phí vòng đời.Đọc xong rồi — làm thử ngay
Bài tập của chương Algorithms and Data Structures gồm 14 câu trắc nghiệm và 3 đề tự luận. Đáp án hiện ngay khi chọn, miễn phí.