Khung chương trình phân môn Khoa học máy tính (CS - Computer Science) trong môn Tin học của Anh quốc. PIV
12/05/2017

IV. Tư duy máy tính: năng lực tư duy quan trọng nhất của CS

Trong phần này sẽ mô tả các năng lực tư duy và kỹ năng cơ bản của học sinh cần nắm vững trong phân môn khoa học máy tính. Hay nói cách khác phần này sẽ mô tả những điều mà học sinh cần nắm được, làm được, thực hành được và hiểu rõ sau khi học phần kiến thức Khoa học máy tính của môn Tin học. Xuyên suốt có thể nói 1 câu: năng lực tư duy chính của Khoa học máy tính là Tư duy máy tính (computational thinking).


Trước khi đi vào chi tiết các vấn đề chúng ta cùng tìm hiểu xuất xứ của khái niệm Tư duy máy tính (computational thinking).

Người đầu tiên nhắc đến cụm từ này là Seymour Papert (29/2/1928 – 31/7/2016), giáo sư toán đại học MIT đồng thời là tác giả của phần mềm và ngôn ngữ lập trình LOGO, trong khi muốn đưa việc giảng dạy thuật toán bằng phần mềm này cho học sinh nhỏ tuổi.

Tác giả GS Jeannette Wing (hiện là phó chủ tịch Microsoft) là người đầu tiên đưa ra định nghĩa của khái niệm này (tư duy máy tính), như sau:

tạm dịch:

"… là các quá trình tư duy bao gồm cả mô tả và lời giải bài toán sao cho lời giải có thể được thực hiện một cách hiệu quả bởi các tác tử xử lý thông tin".

"Lời giải phải (và có thể) được thực hiện bởi con người hoặc máy tính, hoặc tổng quát hơn, bởi sự kết hợp (đồng thời) con người và máy tính".

Như vậy tư duy máy tính chính là kỹ năng rất cơ bản để chúng ta có thể hiểu, biết một cách có lý, logic về thế giới xung quanh dựa trên sức mạnh của máy tính.

Tư duy máy tính ở đây cần được hiểu là nói về khả năng con người có thể làm, chứ không phải máy tính có thể làm. Ví dụ khi nhắc đến tư duy máy tính người ta thường nhắc đến các khả năng suy nghĩ và làm việc logic, có tính (tối ưu) thuật toán, có thể lặp lại và có thể trừu tượng hóa.

Trong mô hình phân môn Khoa học máy tính của Tin học, tư duy máy tính cần được trang bị cho học sinh ngay từ cấp Tiểu học.

Các năng lực, kỹ năng cơ bản của tư duy máy tính bao gồm:

- Trừu tượng hóa.

- Lập trình.

Chúng ta sẽ cùng tìm hiểu chi tiết các kỹ năng trên.

1. Trừu tượng hóa: mô hình, phân rã và tổng quát

Khi sử dụng tư duy máy tính để giải quyết 1 bài toán thì vấn đề khó khăn nhất khi độ phức tạp và độ lớn dữ liệu của bài toán tăng lên. Khi làm 1 bài toán với ít dữ liệu hoặc số liệu nhỏ thì việc giải khá dễ dàng. Nhưng khi qui mô, độ phức tạp của bài toán tăng lên thì việc giải sẽ vô cùng khó khăn. Tư duy quan trọng nhất khi giải quyết các bài toán phức tạp chính là quá trình trừu tượng hóa. Quá trình này có thể được thể hiện rất đa dạng, dưới nhiều kiểu, dạng khác nhau như mô hình hóa, phân rã thành các vấn đề nhỏ hơn, hoặc tổng quát hóa một số tham số để mở rộng phạm vi áp dụng. Trong tất cả các trường hợp, điểm cột lõi là phải giấu đi các chi tiết phức tạp. Xét 1 vài ví dụ:

- Khi thiết kế các tuyến xe buýt 1 sao cho tối ưu trong 1 thành phố, người ta thường giấu đi tất cả các thông số kỹ thuật và yêu cầu chỉ tiết, chỉ để lại các thông tin cơ bản nhất, ví dụ 1 bản đồ các đường phố chính.

- Khi đưa ra cho người dùng 1 hàm số đơn giản, ví dụ tính căn bậc 2 của 1 số, hàm sqrt(x), người thiết kế đã giấu đi các thuật toán phức tạp bên trong của hàm số này khi tính gần đúng căn bậc 2 của 1 số thực dương x. Người dùng không cần biết tất cả chi tiết bên trong của hàm số này.

(1) Mô hình hóa (modelling)

Mô hình hóa là quá trình xây dựng một biểu diễn của một vấn đề của thế giới thực, một hệ thống hoặc một trạng thái quan trọng cần thiết cho một mục đích nào đó. Khi thực hiện mô hình bao giờ cũng cần lấy ra các thông tin, đặc tính quan trọng nhất của mô hình thực tế để đưa vào mô hình và bỏ qua các chi tiết ít quan trọng khác.

Ví dụ của mô hình hóa rất nhiều: thiết lập 1 bản đồ đường phố; thiết lập bản đồ địa hình 1 khu vực trên trái đất; mô phỏng 1 thí nghiệm ảo; mô tả sự chuyển động của con lắc; ….

Mỗi mô hình được xây dựng có những mục đích khác nhau, đó đó bản thân khái niệm mô hình và biểu diễn của chúng cũng rất đa dạng, khác nhau.

Một bài toán có thể cần nhiều mô hình. Ví dụ khi thiết kế 1 Website thì cần các mô hình như: mô hình phân tích bản đồ liên kết website; mô hình thể hiện font chữ cho các tiêu đề; mô hình thể hiện và phân bổ các thông tin chính trên trang.

Một ví dụ khác khi thiết kế mô hình mô phỏng một hệ thống nào có của thực tế, ví dụ mô hình Trái Đất quay xung quanh Mặt Trời, mô hình các hành tinh trong hệ Mặt Trời. Trong các mô hình này chỉ giữ lại 1 số ít thông tin quan trọng ví dụ như quĩ đạo chuyển động, tốc độ chuyển động, … còn lại các thông tin khác sẽ được bỏ qua.

(2) Phân rã (decomposing)

Phân rã là quá trình chuyển, đưa 1 bài toán lớn thành các bài toán nhỏ hơn (và do đó dễ hơn) để giải. Khi giải xong các bài toán con này thì gộp lại sẽ thu được lời giải bài toán lớn. Để hình dung đơn giản chúng ta xét 1 ví dụ bài toán chuẩn bị 1 bữa cơm. Chúng ta sẽ phân rã bào toán này thành các bài toán, công việc nhỏ hơn như:

1- Chuẩn bị gạo - nấu cơm.

2- Chuẩn bị rau - luộc rau.

3- Chuẩn bị các món có chất đạm - làm trứng, thịt.

Khi cả 3 công việc con trên đã hoàn thành thì toàn bộ bài toán chuẩn bị 1 bữa cơm cũng xong.

Chú ý: các bài toán con (subproblem) cũng có thể lại được phân rã 1 lần nữa thành các bài toán nhỏ hơn nữa. Ví dụ công việc 3 ở trên có thể phân rã thành 2 việc nhỏ nữa: rán trứng và kho thịt.

Một ví dụ khác của khái niệm phân rã là bài toán xử lý dữ liệu thống kê dân số của một khu vực. Người ta đã phân loại thông tin dân số theo các nhóm như thông tin cá nhân; thông tin vị trí địa lý và các thông tin nghề nghiệp khác. Việc xử lý dữ liệu sẽ được phân rã thành các bài toán nhỏ hơn khi phân tích riêng các nhóm dữ liệu.

Quá trình phân rã bài toán trong khoa học máy tính đóng vai trò rất quan trọng. Việc phân rã liên tục được gọi là đệ qui (recursive). Quá trình thực hiện giải bài toán bằng cách phân rã được gọi là quá trình giải quyết vấn đề từ trên xuống dưới (top-down).

Với rất nhiều bài toán, việc phân rã thành các bài toán con chính là một phần của lời giải bài toán này. Tuy nhiên nhiều khi cần hiểu ý tưởng phát triển lời giải ngay từ đầu, mà không cần hoặc chưa cần tiến hành quá trình phân rã bài toán. Ví dụ nhìn vào 1 sơ đồ khối làm việc của các cấu thành hệ thống (ví dụ 1 hệ thống gồm các máy tính chủ, máy trạm, hub, máy in với các sơ đồ kết nối giữa chúng) sẽ giúp chúng ta hiểu ngay hệ thống mà chưa cần tiến hành bất cứ quá trình phân rã nào.

(3) Tổng quát hóa (generalising) và phân loại hóa (classifying)

Tổng quát hóa cũng là 1 phương pháp để giải quyết các vấn đề của sự phức tạp của vấn đề cần giải quyết. Khi có quá nhiều các dữ liệu, các ví dụ mẫu, tham số, … làm cho bài toán cần giải trở nên quá phức tạp thì khi đó quá trình tổng quát hóa sẽ có ý nghĩa. Ví dụ đơn giản nếu chúng ta cần phải thực hiện các công việc cụ thể là vẽ 1 vòng tròn bán kính 3, một vòng tròn khác bán kính 5 và 1 vòng tròn nữa bán kính 7. Khi đó chúng ta sẽ cố gắng thiết lập một qui trình vẽ vòng tròn với bán kính R bất kỳ, gọi nó là 1 thủ tục (hay hàm số) với tham số là bán kính R. Khi đó chỉ cần gọi thủ tục này với các tham số R bằng 3, 5, 7 là xong. Với cách làm như trên, rất nhiều đoạn chương trình riêng rẽ có thể được viết 1 lần, được kiểm thử 1 lần, viết tài liệu 1 lần và được hiểu 1 lần.

Một ví dụ khá rõ của phân loại hóa là khả năng của các ngôn ngữ lập trình hướng đối tượng cho phép tạo ra các lớp. Các lớp cha sẽ mô tả các tính năng chung của đối tượng hiện thời, ví dụ như màu sắc đối tượng. Trong khi đó các lớp con sẽ mô tả các thuộc tính riêng biệt (ví dụ hình dạng vuông, tam giác hay tròn).

Quá trình tổng quát là quá trình tìm ra các đặc tính chung của mẫu, từ đó sẽ kiểm soát được một phần sự phức tạp của hệ thống bằng cách chia sẻ các tính chất chung đó.

2. Lập trình

Khoa học máy tính tất nhiên rộng hơn lập trình. Tuy nhiên lập trình là quá trình then chốt, cơ bản nhất và quan trọng nhất của khoa học máy tính. Giảng dạy, truyền đạt kỹ năng lập trình tốt sẽ rèn luyện, cổ vũ sự sáng tạo, tư duy logic, kỹ năng giải quyết vấn đề, thái độ lao động chăm chỉ. Rèn luyện lập trình tốt sẽ thúc đẩy cá nhân sáng tạo và biết cách làm việc trong môi trường nhóm. Tư duy lập trình sẽ giúp học sinh biết trừu tượng hóa, tổng quát hóa các vấn đề trong cuộc sống, từ đó tạo ra được các kỹ năng đặc biệt để giải quyết vấn đề.

Trong phân môn Khoa học máy tính, học sinh cần học để biết, nắm vững các yêu cầu sau liên quan đến lập trình.

(1) Thiết kế và viết chương trình

a. Mỗi học sinh cần được có điều kiện thực hiện liên tục để thực hiện các công việc thiết kế, viết chương trình, dịch, chạy, kiểm thử và sửa lỗi các chương trình chạy được (executable programs). Thời gian để thực hiện các công việc trên có thể khác nhau với từng lứa tuổi và điều kiện thực tế, nhưng bắt buộc phải liên tục. Ở đây "chương trình chạy được" được hiểu theo nghĩa rộng, phụ thuộc vào công cụ, phần mềm và ngôn ngữ mà học sinh được học.

Ví dụ các công việc sau đều có thể gọi là lập trình.

- Thiết lập chương trình bởi các ngôn ngữ nhỏ, riêng biệt, ví dụ qui trình điều khiển robot, lắp ráp LEGO, điều khiển Rùa trong LOGO.

- Các ngôn ngữ kéo thả ví dụ Scratch, Kodu, Alice, Snap, ….

- Các ngôn ngữ bậc cao dạng "văn bản" như Pascal, C, C++, Java, C#, PHP, Python, Visual Basic, JavaScript, …

- Công thức tính toán trong bảng tính.

Trong mọi trường hợp, điều quan trọng là các khái niệm, kỹ năng tư duy lập trình, thuật toán chứ không phải bản chất của ngôn ngữ lập trình hay chương trình dịch.

b. Không những chỉ là điều kiện thực hiện viết chương trình, mà khả năng hiểu và giải thích được chương trình mới là quan trọng nhất. Học sinh nhất thiết phải học và làm được điều sau đây.

- Thiết kế và viết chương trình sẽ cần phải hiểu được:

+ Tính tuần tự (sequencing): các lệnh phải được thực hiện tuần từ, lệnh này sau 1 lệnh khác.

+ Sự lựa chọn (selection): có thể thực hiện theo cách này hoặc cách khác, ví dụ lệnh if-then-elsse. Trong ngôn ngữ và tư duy lập trình hay gọi điều này là rẽ nhánh.

+ Khả năng lặp lại (repetition): lặp có điều kiện, lặp vô hạn và lặp chính nó (đệ qui).

+ Khả năng trừu tượng hóa (abstraction): có thể tạo ra các khái niệm "trừu tượng" để có thể dùng lại nhiều lần. Ví dụ thông qua khả năng tạo thủ tục và hàm số với tham số.

+ Khả năng tạo tương tác trực tiếp với bên ngoài thông qua việc trao đổi vào/ra files (input/output).

- Tìm và sửa được lỗi trong chương trình.

- Phân tích kỹ lưỡng và sâu sắc chương trình, biết được chương trình dẫn đến kết quả đúng hay sai, kết quả chương trình có thỏa mãn yêu cầu đề ra hay không.

- Mô tả được thiết kế, ý nghĩa các lệnh (coding), biến nhớ, thủ tục, hàm số và trình bày lại cho mọi người cùng biết.

(2) Cơ chế trừu tượng hóa

Sử dụng hiệu quả cơ chế trừu tượng hóa khi viết chương trình (ví dụ sử dụng hàm số, thủ tục, lớp đối tượng, …) đóng vai trò trung tâm và quan trọng nhất khi xử lý các vấn đề có độ phức tạp lớn. Ví dụ thiết kế các thủ tục chính là quá trình trừu tượng hóa bằng cách giấu đi các tính toán cụ thể, phức tạp bên trong thông qua một giao diện đơn giản bên ngoài.

Các quá trình trừu tượng hóa này có thể lồng nhau, chồng lớp lên nhau. Ví dụ: Thủ tục vẽ hình vuông sẽ gọi các thủ tục vẽ một đoạn thẳng; thủ tục tô màu 1 điểm pixel trên mặt phẳng sẽ phải gọi thủ tục lấy địa chỉ bộ nhớ của điểm với tọa độ (x, y) trên mặt phẳng.

Khi sử dụng quá trình trừu tượng hóa bằng cách tạo ra các thủ tục của riêng mình, hoặc sử dụng các thư viện thủ tục của người khác, học sinh cần hiểu rõ và thành thạo công việc này. Sau đây là một ví dụ minh họa.

+ Cần nhận ra khi cần phải viết các đoạn chương trình bị lặp lại giống nhau. Ví dụ lệnh vẽ 1 đường tròn bán kính 7 và 1 đường tròn khác bán kính 5.

+ Thiết kế một thủ tục để tổng quát hóa công việc lặp lại đó. Ví dụ thiết lập thủ tục vẽ đường tròn bán kính R.

+ Thay thế các đoạn chương trình lặp lại trên bằng cách gọi thủ tục vừa khởi tạo sau khi thay thế các tham số bằng các giá trị cụ thể, ví dụ R = 7 và R = 5. Quá trình thay thế đoạn chương trình bằng thủ tục chính là quá trình trừu tượng hóa sau khi áp dụng các mẫu. Việc thiết kế thủ tục chính là thiết kế các mẫu để được dùng lại nhiều lần.

Ở mức độ cao hơn, việc thiết kế các mẫu để được sử dụng lặp lại nhiều lần khi giải quyết bài toán đóng vai trò trung tâm của rất nhiều các lớp bài toán. Ví dụ:

+ Khi chúng ta thiết kế chương trình, sử dụng các "mẫu" như biến nhớ, bản ghi, mảng, danh sách, cây dữ liệu, bảng hash.

+ Các mẫu ở mức cao hơn nữa như: chia để trị, hàng đợi, sắp xếp, tìm kiếm, quay lui, đệ qui, client/server, bộ nhớ đệm, qui hoạch động, …

(3) Kiểm thử và sửa lỗi chương trình

Khi một chương trình gặp lỗi thì ta phải làm gì để sửa lỗi?

Máy tính thường rất lạ, kỳ ảo (nhiều người lập trình vẫn nói vui là trong máy tính có ma). Máy tính thường hay đưa ra các kết quả kỳ lạ, sai be bét, vô cùng khó hiểu trước khi nó hoạt động chính xác theo yêu cầu đúng của chương trình. 

Thông qua lập trình, học sinh cần phải học được các cơ hội, khả năng và kỹ năng để có thể tự dự đoán, tìm lỗi và sửa lỗi chương trình. Một số yêu cầu sau là cần thiết cho công việc này:

- Đọc và hiểu tài liệu của chương trình.

- Giải thích được một đoạn chương trình sẽ chạy như thế nào, hoặc có thể không làm việc như thế nào.

- Có thể "thực hiện", "chạy" chương trình bằng suy luận (chay), không cần máy tính, ví dụ chỉ dùng bút và giấy trắng.

- Phân tách, cô lập lỗi bằng các công cụ như tìm vết và kiểm thử.

- Bổ sung thêm chú thích cho các dòng lệnh để làm cho chương trình dễ hiểu hơn.

- Viết bổ sung các đoạn chương trình có nhiệm vụ riêng để tìm lỗi bên trong chương trình. Thông thường các lỗi này thuộc về logic nội tại của bài toán, lỗi logic, lỗi phá vỡ tính đồng bộ, nhất quán của chương trình hoặc dữ liệu.

- Tìm được các đoạn code tạo ra lỗi của chương trình.

- Thiết lập và lựa chọn các bộ dữ liệu, bộ test có thể tạo ra lỗi.

Trong chương trình khoa học máy tính dành cho học sinh phổ thông không yêu cầu học sinh nắm được hay trở thành các nhà viết phần mềm, sản phẩm phần mềm chuyên nghiệp. Ví dụ các công việc mang tính chuyên nghiệp như viết phân tích yêu cầu đầu vào, mô tả chức năng thiết kế, tài liệu sản phẩm, kế hoạch kiểm thử, …. sẽ không cần trang bị cho học sinh.
URL của bài viết này::http://www.schoolnet.vn/modules.php?name=News&file=article&sid=8209