Lỗi khái niệm thường gặp khi học lập trình và cách phát hiện sớm
Có những lỗi của học sinh không đến từ việc gõ sai hay quên cú pháp, mà từ cách các em hình dung sai về việc máy tính chạy chương trình như thế nào. Trong giáo dục, người ta gọi đó là lỗi khái niệm (misconception): một cách hiểu chưa chính xác nhưng khá bền, khiến học sinh lặp lại cùng một kiểu sai dù đã được sửa từng lỗi nhỏ. Bài viết này tóm lược những gì các nghiên cứu về lập trình nhập môn đã ghi nhận, đề xuất cách phát hiện sớm trong lớp và nêu các giới hạn của bằng chứng.
Nghiên cứu cho thấy điều gì
Khó khăn không chỉ nằm ở cú pháp
Qian và Lehman (2017) tổng quan các nghiên cứu về lỗi khái niệm và những khó khăn khác trong lập trình nhập môn. Họ nhận thấy học sinh gặp khó khăn ở ba loại tri thức: tri thức cú pháp, tri thức khái niệm và tri thức chiến lược. Các khó khăn này liên quan đến nhiều yếu tố, trong đó tác giả nêu sự chưa quen với cú pháp, ngôn ngữ tự nhiên, kiến thức toán, mô hình tư duy (mental model) chưa chính xác, thiếu chiến lược, môi trường lập trình, và kiến thức cùng cách dạy của giáo viên. Họ cũng nhận xét nhiều nguồn khó khăn có liên hệ với kiến thức nền sẵn có của người học. Về hướng giải quyết, họ kiến nghị đưa lý thuyết thay đổi khái niệm vào nghiên cứu và phát triển kiến thức sư phạm chuyên môn của giáo viên, trong đó có hiểu biết về lỗi khái niệm của học sinh.
"Máy tính khái niệm" và việc hiểu cách chương trình chạy
Du Boulay (1986) là một trong những người nhấn mạnh khái niệm máy tính khái niệm (notional machine), tức mô hình trừu tượng về máy tính thực thi chương trình. Bài báo xem xét những lỗi sinh ra từ việc áp dụng sai các phép so sánh (analogy) khi giảng, các lỗi tương tác, và đặc biệt nhấn mạnh việc hiểu mối quan hệ giữa thiết bị đầu cuối (terminal) với máy tính và việc hiểu phép gán. Sorva (2013) tổng hợp nhiều hướng nghiên cứu, gồm lỗi khái niệm trong lập trình và lý thuyết về mô hình tư duy, rồi kết luận rằng máy tính khái niệm là một thách thức lớn trong dạy lập trình nhập môn. Ông lập luận rằng giáo viên nên coi máy tính khái niệm là một mục tiêu học tập tường minh và giảng dạy nó một cách chủ động.
Lỗi khái niệm không phụ thuộc ngôn ngữ
Pea (1986) lập luận rằng tồn tại những "lỗi" khái niệm bền vững, không gắn với một ngôn ngữ lập trình cụ thể, và xuất hiện ở người mới từ tiểu học đến đại học. Bài báo xác định ba nhóm lỗi: tính song song (parallelism), tính chủ ý (intentionality) và tính tự quy chiếu (egocentrism). Tác giả đề xuất rằng chúng bắt nguồn từ một "siêu lỗi" (superbug): chiến lược mặc định cho rằng đâu đó trong ngôn ngữ lập trình có một "bộ óc ẩn" với khả năng diễn giải thông minh. Nói đơn giản, học sinh có thể kỳ vọng máy tính tự hiểu được điều mình muốn. Mô tả chi tiết ba nhóm lỗi có trong bài gốc; người biên tập chỉ đọc được phần tóm tắt.
Bằng chứng gần với lớp học phổ thông
Kaczmarczyk và cộng sự (2010) phỏng vấn người học môn lập trình nhập môn (CS1) và thấy bốn chủ đề lỗi khái niệm. Bài chi tiết ba lỗi, gồm hai lỗi về mô hình bộ nhớ và một lỗi về cách dữ liệu được gán khi khai báo kiểu nguyên thủy; các tác giả nhận xét các lỗi liên quan nhau nhưng rất khác nhau.
Swidan, Hermans và Smit (2018) khảo sát 145 người từ 7 đến 17 tuổi có kinh nghiệm lập trình bằng bảng hỏi trắc nghiệm gồm các bài Scratch, đại diện cho 11 lỗi khái niệm đã biết. Ba lỗi phổ biến nhất là khó hiểu tính tuần tự của các câu lệnh, việc một biến chỉ giữ một giá trị tại một thời điểm, và tính tương tác khi chương trình cần dữ liệu người dùng. Việc mắc lỗi chịu ảnh hưởng của "hiệu ứng toán học" của số, ý nghĩa của tên định danh và kỳ vọng quá cao về máy tính. Học sinh lớn tuổi trả lời đúng nhiều hơn, nhất là ở biến và cấu trúc điều khiển, và trẻ chỉ lập trình bằng Scratch có vẻ gặp khó hơn so với trẻ dùng Scratch cùng ngôn ngữ khác. Các tác giả gợi ý cần chú ý các lỗi do Scratch gây ra và nên cung cấp học liệu giàu khái niệm với nhiều bài tập đa dạng cho mỗi khái niệm.
Sirkiä và Sorva (2012) nghiên cứu những sai lầm học sinh mắc khi thực hiện mô phỏng chương trình trực quan (visual program simulation), một dạng bài trong đó người mới luyện lần theo từng bước thực thi chương trình trên giao diện đồ họa. Qian (2018), trong luận án tiến sĩ với học sinh trung học học Java, báo cáo rằng 15 lỗi biên dịch phổ biến chiếm 92% mọi lỗi biên dịch được ghi nhận và được liên hệ với ba nhóm lỗi khái niệm: cấu trúc chương trình, biểu thức và biến; nhóm nhận phản hồi nhắm đúng các lỗi này cải thiện bài sai với tỉ lệ cao hơn đáng kể. Cần lưu ý đây là một luận án với nhóm học sinh năng khiếu trong một chương trình hè, chưa phải kết quả đã qua phản biện hội nghị hay tạp chí.
Ứng dụng trong lớp học
Các gợi ý dưới đây do người biên tập rút ra từ những nghiên cứu trên, chưa được kiểm chứng riêng ở lớp học Việt Nam. Ví dụ Scratch và Python là minh họa tự nghĩ ra.
Hỏi "dự đoán trước khi chạy". Cho đoạn chương trình ngắn và yêu cầu học sinh nêu kết quả trước khi chạy. Cách này tương tự các bảng hỏi chẩn đoán trong Swidan và cộng sự (2018) và bài lần theo từng bước thực thi trong Sirkiä và Sorva (2012).
Chọn câu hỏi nhắm vào lỗi đã được ghi nhận. Ví dụ minh họa về biến: trong Scratch đặt "điểm" bằng 5 rồi đặt "điểm" bằng 8, hỏi "bây giờ điểm là bao nhiêu và giá trị 5 đi đâu?" (liên hệ lỗi "biến chỉ giữ một giá trị tại một thời điểm" ở Swidan và cộng sự, 2018). Với phép gán trong Python, ví dụ minh họa là dòng x = x + 1 : nếu học sinh đọc như một phương trình toán thì có thể thấy vô lý, phù hợp với ghi nhận về ảnh hưởng của kiến thức toán trong Qian và Lehman (2017).
Kiểm tra tính tuần tự. Đổi thứ tự hai khối lệnh trong Scratch (ví dụ "đi 10 bước" rồi "nói Xin chào" và ngược lại) và hỏi sự khác nhau. Đây là ví dụ minh họa cho lỗi về tính tuần tự trong Swidan và cộng sự (2018).
Nói rõ máy tính chỉ làm đúng điều được viết. Một hoạt động minh họa: học sinh viết hướng dẫn từng bước cho bạn đóng vai máy tính, bạn đó chỉ làm đúng chữ. Việc này nhằm đối phó với kỳ vọng máy tính tự hiểu ý (siêu lỗi trong Pea, 1986; kỳ vọng quá cao về máy tính trong Swidan và cộng sự, 2018).
Dạy mô hình thực thi một cách tường minh. Vẽ trên bảng ô nhớ của các biến và con trỏ chạy từng dòng, theo hướng của Sorva (2013) về máy tính khái niệm. Du Boulay (1986) cũng lưu ý các phép so sánh dùng khi giảng có thể tự gây lỗi nếu bị áp dụng sai; hãy nói rõ chỗ phép so sánh không còn đúng.
Phỏng vấn ngắn. Hỏi vài học sinh "em nghĩ máy đang làm gì ở dòng này?" như các nghiên cứu phỏng vấn của Kaczmarczyk và cộng sự (2010), rồi ghi lại các cách hiểu chung của lớp.
Theo dõi lỗi lặp lại. Nếu học sinh liên tục mắc cùng một dạng lỗi, hãy nghi có lỗi khái niệm bên dưới và đổi cách giải thích thay vì chỉ sửa từng dòng.
Giới hạn và lưu ý
Đối tượng khác nhau. Kaczmarczyk và cộng sự (2010) phỏng vấn người học môn lập trình nhập môn (CS1); Swidan và cộng sự (2018) với trẻ 7–17 tuổi bằng bảng hỏi Scratch; luận án của Qian (2018) với học sinh năng khiếu học Java. Kết quả không nhất thiết suy rộng được cho mọi lớp học.
Bảng hỏi chỉ cho thấy câu trả lời, không cho thấy suy nghĩ. Swidan và cộng sự dùng câu hỏi trắc nghiệm, nên chọn sai chưa chắc đã là lỗi khái niệm; nên kết hợp hỏi lý do.
Thuật ngữ chưa thống nhất. Qian và Lehman (2017) bàn tới cả lỗi khái niệm lẫn các khó khăn khác (cú pháp, chiến lược); không phải mọi lỗi của học sinh đều là lỗi khái niệm.
Bài chỉ đọc phần tóm tắt của đa số nguồn. Người biên tập chưa đọc toàn văn nên không liệt kê hết các lỗi cụ thể trong từng nghiên cứu và không nêu tỉ lệ ngoài những số liệu có trong phần tóm tắt.
Bằng chứng về hiệu quả của cách phát hiện sớm còn hạn chế. Qian và Lehman (2017) ghi nhận các công cụ và phương pháp đã có nhưng việc phổ biến còn hạn chế và tác dụng lâu dài cần được nghiên cứu thêm.
Kết luận
Nhiều khó khăn của người mới học lập trình đến từ cách hiểu chưa chính xác về biến, thứ tự thực thi và việc máy tính làm gì với chương trình, chứ không chỉ từ cú pháp. Các nghiên cứu cho thấy những cách hiểu này xuất hiện từ tuổi tiểu học đến đại học, và cả với công cụ trực quan như Scratch. Giáo viên có thể phát hiện sớm bằng câu hỏi dự đoán kết quả, bài lần theo từng bước, phỏng vấn ngắn và theo dõi lỗi lặp lại, đồng thời giảng rõ mô hình về cách máy thực thi. Vì bằng chứng còn giới hạn về đối tượng, người dạy nên coi các gợi ý là điểm khởi đầu để quan sát lớp của mình.
Tài liệu tham khảo
Du Boulay, B. (1986). Some difficulties of learning to program. Journal of Educational Computing Research, 2 (1), 57–73. https://doi.org/10.2190/3LFX-9RRF-67T8-UVK9
Kaczmarczyk, L. C., Petrick, E. R., East, J. P., & Herman, G. L. (2010). Identifying student misconceptions of programming. In Proceedings of the 41st ACM Technical Symposium on Computer Science Education (pp. 107–111). ACM. https://doi.org/10.1145/1734263.1734299
Pea, R. D. (1986). Language-independent conceptual "bugs" in novice programming. Journal of Educational Computing Research, 2 (1), 25–36. https://doi.org/10.2190/689T-1R2A-X4W4-29J2
Qian, Y. (2018). Understanding and addressing misconceptions in introductory programming: A data-driven approach [Doctoral dissertation, Purdue University]. https://docs.lib.purdue.edu/open_access_dissertations/1805
Qian, Y., & Lehman, J. (2017). Students' misconceptions and other difficulties in introductory programming: A literature review. ACM Transactions on Computing Education, 18 (1), 1–24. https://doi.org/10.1145/3077618
Sirkiä, T., & Sorva, J. (2012). Exploring programming misconceptions: An analysis of student mistakes in visual program simulation exercises. In Proceedings of the 12th Koli Calling International Conference on Computing Education Research (pp. 19–28). ACM. https://doi.org/10.1145/2401796.2401799
Sorva, J. (2013). Notional machines and introductory programming education. ACM Transactions on Computing Education, 13 (2), 1–31. https://doi.org/10.1145/2483710.2483713
Swidan, A., Hermans, F., & Smit, M. (2018). Programming misconceptions for school students. In Proceedings of the 2018 ACM Conference on International Computing Education Research (pp. 151–159). ACM. https://doi.org/10.1145/3230977.3230995