Sunday, September 13, 2020

06 - Môn tin học lớp 11 nên dạy các em ngôn ngữ lập trình nào?

Mới đây, Bộ GD&ĐT đã ban hành Công văn hướng dẫn và điều chỉnh nội dung giảng dạy môn tin học cấp THCS, THPT [1]. Đáng chú ý là môn tin học lớp 11 sẽ loại bỏ, không đưa Pascal vào chương trình giảng dạy. Đặc biệt, từ năm học 2021-2022 các đơn vị chỉ lựa chọn một trong các Ngôn ngữ lập trình: Python, C hoặc C++ để dạy trong chương trình môn Tin học lớp 11. Nếu được lựa chọn một ngôn ngữ lập trình (NNLT) để dạy cho các em, tôi sẽ không chọn Pascal như quy định của Bộ GDĐT và tôi cũng không chọn cả C, C++ và Python mà sẽ lựa chọn Visual Basic for Application. 

Việc đầu tiên chúng ta cần thống nhất là đưa ra các tiêu chí để lựa chọn NNLT. Các tiêu chỉ để lựa chọn dường như cũng chưa được xác định rõ trong các văn bản của Bộ GDĐT. Theo cá nhân tôi thì bộ tiêu chí cho NNLT có thể là:

  • (A1) Là một NNLT đơn giản, trong sáng, không quá phức tạp để giảm tải thời gian học cho các em.
  • (A2) Minh họa và thể hiện được tư duy lập trình cơ bản, có thể giúp các em lập trình giải được các bài toán có trong chương trình phổ thông. Ví dụ như chương trình giải phương trình bậc 2.
  • (A3) Công cụ lập trình đơn giản, dễ cài đặt, trực quan dễ sử dụng.
  • (A4) Dễ dàng tạo ra các ứng dụng có giao diện thân thiện.
  • (A5) Có tính ứng dụng cao, có thể được áp dụng cho nhiều ngành, không chỉ riêng cho CNTT.
  • (A6) Có tính kế thừa, được sử dụng tiếp cho các bậc học cao hơn như lớp 12, đại học, và có thể vẫn được sử dụng trong công việc về sau.

Để đưa ra một lựa chọn, tôi cũng căn cứ vào kinh nghiệm đã có với các NNLT của bản thân, cụ thê tôi đã từng: 

  • Lập trình Turbo Pascal từ năm 1988 với phần mềm tính kết cấu bằng phương pháp phần tử hữu hạn (1988-1990), phần mềm in mã nguồn Pascal Listing (1989)...
  • Lập trình C, C++ từ năm 1990 với các sản phẩm: Bộ biên dịch ngược và xuôi cho Chip Z80, 8085, Vietkey2000, Vietkey Linux...
  • Lập trình Python từ năm 1999-2008, phát triển bộ cài đặt Anaconda cho Vietkey Linux...
  • Lập trình Basic từ năm 1986 với chương trình quy hoạc tuyến tính (Linear Programming), Phần tử hữu hạn (1988), Visual Basic for Application (VBA) cho nhiều sản phẩm Vietkey Office (kiểm tra chính tả tiếng Việt, sắp xếp tiếng việt, chuyển mã văn bản...) năm 1998-2003, chấm điểm khiêu vũ thể thao VKSkating từ năm 2007-2018 và nhiều phần mềm khác.
Trên đây là 4 ngôn ngữ được đề cập đến trong bài này, tôi sẽ không kể đến những kinh nghiệm của bản thân với các ngôn ngữ khác như: FORTRAN, Assembly, Prolog, C#, Java, Perl, PHP, Dart, Golang, Rust, HTML/CSS, LaTeX, Mapple... Nhưng những trải nghiệm từ các NNLT này cũng giúp cho quá trình đánh giá các tiêu chí lựa chọn.

Sau đây là một số phân tích về các NNLT được đề cập đến trong bài:

(Turbo) Pascal

Là một NNLT dạng biên dịch (trước khi chạy chương trình thì cần phải dịch từ NNLT ra mã máy), do Niklaus Wirth thiết kế vào năm 1970, đã có một thời gian Pascal rất phổ biến với phiên bản Turbo Pascal của hãng Borland. Pascal là một ngôn ngữ rõ ràng và trong sáng, ít dùng các ký hiệu tắt như C mà chủ yếu dùng các từ khóa (keyword) bằng tiếng Anh. Pascal có con trỏ (truy tiếp trực tiếp vào ô nhớ vật lý) nhưng hầu như không phải sử dụng đến nên nó ít bị lỗi hơn C. Pascal thành công bởi hãng Borland đã làm ra bộ công cụ soạn thảo và biên dịch Pascal và cả C một cách rất tuyệt vời. Turbo Pascal được phát triển bởi Anders Hejlsberg, một siêu thủ về trình biên dịch mà sau này Microsoft cũng phải mua lại ông về để phát triển nền tảng .NET. Đã một thời tôi từng rất ngưỡng mộ và yêu thích Delphi một nền tảng phát triển ứng dụng cho MS Windows, .NET và cả Linux, ngôn ngữ sử dụng chính của Delphi chính là Pascal. Các app viết bởi Delphi chạy rất nhay và gọn gàng, tất cả các thư viện liên quan đến chương trình đều được gói vào 1 file EXE duy nhất, không cần phải cài đặt, chỉ copy là chạy và nó không bị phụ thuộc vào các phiên bản của các thư viện DLL (Dynamic Link Library) giống như các app được phát triển bởi Visual Studio, và tránh được các lỗi version giống hệt tình trạng trên Linux, mà trong giới lập trình vẫn gọi là "Địa ngục DLL". Đáng tiếc là đến năm 2009, Borland đã bị mua bởi Micro Focus International plc. và không còn xuất hiện trên thị trường, các công cụ phát triển cho Pascal cũng vì thế mà tàn lụi.

Cho đến trước tháng 8 năm nay, Turbo Pascal 7.0 (TPascal) vẫn được dạy ở các trường phổ thông trung học ở Việt Nam trong môi trường DOS hay Command Prompt của Windows. Microsoft càng ngày càng hạn chế chế độ DOS do đó cài đặt và sử dụng TPascal càng ngày càng khó khăn, các ứng dụng được phát triển bởi TPascal cũng là các chương trình chạy trên DOS nên cũng không được hỗ trợ do đó các yêu cầu A3, A4, A5, A6 đều không đáp ứng.

Tóm lại TPascal chỉ có thể được dùng để minh họa cho thuật toán (A1, A2) mà thôi, tính ứng dụng của nó rất thấp và nó cũng không có tính kế thừa, sau này ra đời gần như không có ai sử dụng nó trong thực tế.

C, C++

C là ngôn ngữ được phát triển bởi Dennis Ritchie (Bell Labs) từ năm 1972, là một ngôn ngữ khá súc tích và rất mạnh, nó có thể can thiệp sâu vào kiến trúc phần cứng, cụ thể là có con trỏ có thể truy cập trực tiếp vào các vùng nhớ, cấp phát động và giải phóng động các vùng nhớ rất linh hoạt nhưng cũng vì đây là con dao sắc nên cũng rất dễ gây lỗi, các lỗi tràn bộ đệm chủ yếu đến từ ngôn ngữ C. Cũng có nhiều năm tôi sử dụng ngôn ngữ C để phát triển hàng chục ứng dụng khác nhau, lần gần nhất là năm 2010 với dự án 10 triệu dòng lệnh C sửa nhân Linux Kernel để biến đổi Linux thành hệ điều hành thời gian thực. C, C++ rất mạnh và được sử dụng hầu hết trong các hệ thống lớn như hệ điều hành, các thiết bị nhúng IoT và cho đến tháng 9/2020, ngôn ngữ C vẫn được được xếp thứ 1 với chiếm gần 16% trong tổng các NNLT (Hình 1).

Hình 1: Xếp hạng các NNLT tháng 9/2020 trên https://www.tiobe.com/tiobe-index/
 
Ngôn ngữ C nói chung là khó hơn Pascal nhiều và vì nó cũng súc tích nên không được sáng sủa và mạch lạc như Pascal, nếu dạy trong môi trường DOS thì C cũng gặp phải đa số các nhược điểm như đã kể trên với TPascal, tức tính ứng dụng không cao và tính kế thừa cũng không cao. Để có tính ứng dụng và độ thân thiện tốt hơn thì nên học C# của Microsoft, nhưng có nhược điểm là bộ biên dịch Visual Studio rất nặng, cài bản miễn phí community cũng mất đến hơn 15G dung lượng đĩa cứng, bản thương mại còn có giá thành rất cao nữa.

Tóm lại C, C++ khó hơn TPascal do đó học nó có khi còn thêm tải cho các em học sinh, cài đặt khó với máy cấu hình thấp nếu dùng C#, tính kế thừa cũng không cao và chủ yếu thích hợp với các em sau này có định hướng theo ngành Công nghệ thông tin.

Python

Ngôn ngữ này được tạo bởi  Guido van Rossum năm 1991, Python được thiết kế với triết lý là ngôn ngữ dễ đọc nhất, đơn giản nhất có thể, hạn chế các ký hiệu "{};...", tối giản các quy ước một cách tối đa do đó mã nguồn thường ít dòng lệnh hơn so với C, C++ và các ngôn ngữ khác. Python khác với C,C++ là ngôn ngữ thông dịch dạng script, không được dịch trước ra mã máy, nên nó chậm hơn C++ từ 200-600 lần [2], thậm chí cũng chậm hơn cả VBA 3-6 lần [3]. bộ nhớ cũng tốn hơn do dùng kiểu biến động (dynamic typed). 

Python được thiết kế như là một NNLT phổ quát, có thể được sử dụng cho nhiều lĩnh vực khác nhau, tuy nhiên nó đa phần được sử dụng cho:
  • AI (Machine Learning);
  • Phân tích (data-analysts), xử lý và hiển thị dữ liệu;
  • Được sử dụng với một số framework để làm Back-end web development.
Python do có hiệu năng tính toán khá chậm so với C++ và một số NNLT biên dịch khác như Rust, Golang nên các bộ thư viện và framework đòi hỏi tính toán nhiều thì thường được viết bằng C++ và được wrap lại để sử dụng trong môi trường Python mà ít khi được viết hoàn toàn bằng Python. Đa phần các framework cho AI như Tensorflow, Pytorch, Caffe2 đều được viết bằng C++. Lợi thế lớn nhất của Python chính là cộng động người sử dụng Python rất lớn nên có nhiều người tham gia phát triển các thư viện Python vì thế các bộ thư viện nguồn mở của Python rất phong phú và gần như tìm gì cũng có sẵn và cũng vì thế có sự support kỹ thuật tốt cho những người mới học.

Cũng vì có cộng động Python rộng lớn mà đa phần các chuyên IT và các thầy dạy IT đều thiên về xu thế sẽ thay Pascal bằng Python. Tuy nhiên tôi thì lại có ý kiến khác: Dạy Python có khá nhiều bất cập đối với học sinh lớp 11:
  • Python là ngôn ngữ đa năng, tính ứng dụng khá cao, tuy nhiên điều này chỉ đúng với các em sau này định hướng theo ngành IT, Computer Science, hay Data Science. Các ngành khác rất ít có điều kiện dùng và nhất là các em sau này chỉ dùng ở mức văn phòng, soạn thảo văn bản MS Word và quản lý dữ liệu trên Excel là chủ yếu.
  • Python dễ đọc nhưng không dễ hơn nhiều so với Pascal. Pascal rất trong sáng, so với Python thì chỉ rườm ra hơn, nhưng Python lại dòi hỏi phải học nhiều thứ hơn. Đối với kiểu tổ chức dữ liệu, Pascal chủ yếu chỉ có mảng, bảng, câu trúc thôi thì Python đưa ra nhiều khái niệm của NNLT hiện đại như List, Tuble, Set, Dictionary, nhiều kiểu na ná cách sử dụng nên cũng dễ gây nhầm lẫn. Python còn có thêm các khái niệm lập trình hướng đối tượng, lập trình hàm, và cả những khái niệm hiện đại như lambda khá là trừu tượng với các em học sinh, đó là chưa kể nếu chỉ nói đến các thư viện chuẩn (Standard Libs) thì Python có cả một rừng luôn. Như vậy so với Pascal thì Python đọc cũng không dễ hơn là bao nhưng khối lượng kiến thức để làm chủ nó lại vô cùng nhiều, dễ gây hoang mang cho học sinh. Học mãi không biết đến bao giờ mới biết được hết cơ bản. Vô hình chung Bộ đang muốn giảm tải thì có khi lại chất thêm nhiều tải hơn. Tránh vỏ dưa lại gặp vỏ dửa.
  • Điểm A3: cài đặt và sử dụng có dễ dàng không? Python cài đặt cũng không đơn giản hơn TPascal, cài đặt ở chế độ Terminal, nguyên bản khi chạy cũng ở chế độ Terminal. Tuy rằng người dùng có thể lựa chọn các công cụ phát triển (IDE) như Visual Code, Visual Studio, Pycharm...Nhiều lựa chọn công cụ phát triển và cả các thư viện thì cũng tốt nhưng đôi khi lại gây rối, phân mảnh, không được thống nhất từ triêt lý đến công cụ, điều này sẽ khó cho việc biên soạn giáo trình thống nhất, và các chuyên gia để hô trợ cũng đòi hỏi phải biết nhiều công cụ cho một ngôn ngữ hơn.
  • Do Python không phải là NNLT cho Front-End nên xây dựng các app có giao diện người dùng UI/UX sẽ gặp khó khăn, hầu như không có các công cụ trực quan kéo thả. Mặc dù có gói tkinter để làm giao diện nhưng khá là thô sơ và khó sử dụng. Cao cấp hơn thì cần các framework như PyQt, WxPython, PyGtk...thì lại phải học thêm rất nhiều về các triết lý và nền tảng Qt, WxWork, Gtk.. Để có một report đẹp như các report như Excel có thể làm được thì lại cần biểu diễn dữ liệu trên Web khi đó lại cần học một loạt các công cụ: web framework, basic Python, Pandas, SQL, command line, git, và code deployment. Nói chung là nhiêu khê và cần phải học cũng khá nhiều.
  • Nếu gói gọn chương trình chỉ có input và output từ bàn phím và bắn kết quả ra màn hình như ở chế độ DOS thôi thì chẳng khác gì TPascal. Học sinh học Python sẽ chẳng thấy hứng thú gì, vì không tạo ra được các app có giao diện đẹp, cute, thân thiện và tính ứng dụng cao.
  • Về tính kế thừa (A6), Python không có liên quan gì đến các chương trình của năm trước cũng như năm học sau của các em, tương tự như vậy đối với C, C++.
Tóm lại Python sẽ phù hợp với các em học sinh sau này có định hướng học theo ngành IT cũng giống như với C, C++, và nếu để nắm bắt được cơ bản Python thì dù dễ đọc nhưng học sinh sẽ phải học nhiều khái niệm mới của NNLT hiện đại, như thế thì lại thành tăng tải chứ không hề giảm tải. Ngoài ra Python cơ bản không có hoặc gần như không có các tính năng trực quan, kéo thả, và thường phải làm việc với chế độ dòng lệnh tối tăm không khác gì Pascal.

VBA (Visual Basic for Application)

VBA được phát triển dựa trên ngôn ngữ BASIC (Beginners' All-purpose Symbolic Instruction Code), do John G. Kemeny và Thomas E. Kurtz phát triển từ năm 1964. Ngôn ngữ này ban đầu được thiết danh cho những người mới học, do đó nó cũng trong sáng và dễ hiểu, không có những ký hiệu và dấu ngoặc nhọn '{}' như của C, C++. So với Python nó cũng dễ đọc và không khó hơn bao nhiêu, Python chỉ là tối giản hơn so với BASIC. 

VBA được đưa vào bộ MS Office từ năm 1993, đến năm 1998, nó có cú pháp giống hệt và tương thích với Visual Basic 6.0 trong bộ Visual Studio 6.0 và cũng giống với người em út là VB Script. Sau năm 1998, Microsoft chuyển sang phát triển nền tảng .NET Framework, vì thế VB6 được thay da đổi thịt thành VB.NET và gia nhập gia đình họ biên dịch tương tự như C# và cũng từ đó VBA khác dần so với VB.NET.

Từ năm 1995 tôi cũng đã bắt đầu có một số nghiên cứu về VBA, nhưng đến năm 1998 mới thực sự lập trình trên ngôn ngữ này, ban đầu cũng chỉ sử dụng như là Macro để tự động hóa các thao tác trong bộ MS Office, sau đó chúng tôi phát triển bộ Vietkey Office viết bằng VBA và tích hợp vào MS Word, MS Excel, MS PowerPoint từ năm 1999 đến nay và bộ công cụ sau hơn 20 năm vẫn hoạt động với bộ MS Office 2019, bộ sản phẩm này bao gồm các chức năng: Kiểm tra chính tả tiếng Việt, Chuyển mã font tiếng Việt, Sắp xếp tiếng Việt...(Hình 2, Hình 3).

Hình 2: Giao diện Vietkey Office (VBA Addin) cài trên MS Word 2019
 
Hình 3: Giao diện Kiểm tra chính tả tiếng Việt (VBA Addin) cài trên MS Word 2019

Kể từ đó cho đến tận bây giờ tôi đã viết nhiều phần mềm để phục vụ cho bản thân như: Phần mềm quản lý tài liệu tham khảo, phần mềm quản lý File, phần mềm sửa đổi thông tin cho các file MP3, và một số phần mềm nghiệp vụ quản trị chấm điểm cho một số môn thi đấu thể thao như Dancesport, Aerobic cũng được viết hoàn toàn bằng VBA trong Excel (cập nhật lần cuối năm 2019), hình 4.

Hình 4: Giao diện VKSkating - chấm điểm cho dancesport được viết bằng VBA trên MS Excel 2019.

Sau đây là một số lý do tại sao tôi khuyến cáo nên dạy các em học sinh lớp 11 ngôn ngữ VBA thay vì Pascal. Tôi đã xem tất cả các sách giáo khoa môn tin học tất cả các lớp 6, 7, 8, 9, 10, 11, 12, thì thấy rằng xuyên suốt chương trình đào tạo tin học ở bậc phổ thông từ cơ sở đến trung học, ngoài việc cung cấp các khái niệm cơ bản như máy tính, hệ điều hành, mạng, an toàn thông tin thì từ lớp 6, lớp 7 các em đã được làm quen với bộ soạn thảo văn phòng: MS Word, MS Excel, đến năm lớp 12 thì được giới thiệu tiếp MS Access cũng là một ứng dụng trong bộ MS Office. Về ngôn ngữ lập trình thì năm 11 các em được học sâu về ngôn ngữ Pascal. Thực ra xem kỹ SGK tin học lớp 11 do thầy Hồ sỹ Đàm chủ biên, tái bản lần thứ 4 năm 2014, thì nội dung cũng không phải quá nặng như ý kiến của một số chuyên gia, vấn đề lớn nhất là ngôn ngữ này đã lạc hậu, công cụ phát triển đã chết, không còn được hỗ trợ và phát triển, nên tính ứng dụng, tính kế thừa đều kém. Nếu chỉ để minh họa tư duy thuật toán thì quá lãng phí thời gian và công sức để các em phải lập trình trên công cụ đã chết này. Xây dựng kỹ năng lập trình ngôn ngữ này, nhưng từ đó về sau không bao giờ còn được sử dụng nữa thì quả thực lãng phí.

VBA so với các NNLT đã phân tích ở trên thì thỏa mãn đầy đủ các yêu cầu đã liệt kê ở trên từ A1-A6, và hơn nữa nó có những ưu điểm rất đáng giá và rất đáng lưu tâm sau:
  • VBA là ngôn ngữ dễ đọc, dễ học, số lượng lệnh và thư viện của nó không nhiều và đồ sộ như C, hay Python. Không có quá nhiều các khái niệm của NNLT hiện đại như list, tuble, set, lamda, hướng đối tượng đầy đủ (VBA cũng có hướng đối tượng nhưng là phiên bản tối giản). 
  • Cài đặt và sử dụng VBA khá đơn giản và dễ dàng. VBA được tích hợp sẵn trong các ứng dụng của bộ MS Office (Word, Excel, Access, Outlook, Visio, Publisher...), vì thế không cần phài cài đặt thêm bất kỳ phần mềm nào, chỉ cần nhấn tổ hợp phím ALT+F11 là công cụ soạn thảo và biên dịch VBA được mở ra và có thể bắt tay vào lập trình được luôn. Mọi công việc lập trình có thể chỉ cần xoay quanh công cụ VBA này, tra cứu các thư viện, các object từ menu, không phải thoát ra ngoài cài thêm hay vào Internet để download thêm thành phần nào.
  • Lập trình VBA rất nhanh và hiệu quả, có thể bắt đầu bằng cách ghi lại các thao tác của người dùng muốn thực hiện (Record Macro) và ứng dụng trong bộ Office sẽ sinh ra cho chúng ta một đoạn mã VBA rồi, chỉ cần tùy biến một chút (như thêm vòng lặp) là đã có thể tạo ra công cụ tự động hóa các công việc văn phòng nhằm nâng cao năng suất lao động. Cũng vì điều này mà tính ứng dụng của VBA rất cao.
  • Có thể sử dụng công cụ của VBA dạng kéo thả để tạo ra giao diện rất trực quan và nhanh chóng (Hình 4), trải nghiệm như kiểu kéo thả của Scratch mà các em đã từng học, do đó dễ dàng tạo ra được các ứng dụng giao diện thân thiện và gây được hứng khởi cho các em (khác xa với giao diện Terminal hay DOS Prompt tối đen của Pascal hay Python).
  • Có tính ứng dụng (A5) và kế thừa A6) cao, VBA có trong các công cụ văn phòng của Microsoft như Word, Excel, Access, Outlook, Visio, Publisher, những ứng dụng văn phòng này thì không chỉ các em học CNTT mà gần như các em học các ngành khác đều cần đến. Thực tế VBA được sử dụng nhiều bởi các chuyên viên không phải ngành IT như Finance, HR, Marketing, Project Management professionals, kể cả người học khối C, khối D thì vẫn cần phải có kỹ năng văn phòng và do đó cũng cần có công cụ để tối ưu và nâng cao năng suất các công việc văn phòng. Bên cạnh đó thông qua VBA có thể lập trình để gắn kết và điều khiển các ứng dụng một cách liên hoàn tạo thành một work flow hoàn hảo, ví dụ dữ liệu được nhập vào từ Access qua Excel rồi xuất qua Word và gửi email qua Outlook, một quy trình như vậy có thể được tự động hóa bằng VBA mà không cần phải thao tác của người dùng, VBA như một script để điều khiển cả hệ sinh thái của các ứng dụng văn phòng. Và không chỉ dừng ở công việc văn phòng VBA còn được tích hợp với các ứng dụng của nhiều hãng ông lớn ngành phần mềm khác như đối với các phần mềm thiết kế 2D, 3D: AutoCAD, CorelDraw, LibreOffice, SolidWorks. VBA cũng được tích hợp để lập trình trong  các dứng dụng trong hệ thông tin địa lý GIS rất nổi tiếng và thịnh hành như MicroStation, ArcGIS...
  • VBA đã tồn tại 27 năm và vẫn còn tiếp tục tồn tại đến chừng nào bộ MS Office còn tồn tại, phiên bản mới nhất là VBA 7.1 mới được cập nhật năm 2019. MS đã có nhiều lần định ngừng phát triển VBA và đã có ý định phát triển Javascript để thay thế nhằm tăng khả năng tương thích với các trình duyệt và để tích hợp sâu các ứng dụng MS Office lên Cloud nhưng tiến trình Javascript diễn ra rất chậm và dù có bản Javascript thì MS cũng không thể bỏ được VBA vì suốt 27 năm qua hàng trăm ngàn doanh nghiệp đã xây dựng hệ sinh thái và work flow của họ dựa trên VBA.
  • VBA là một công cụ tuyệt vời cho trải nghiệm lập trình, ngoài khả năng sinh mã nguồn nhanh qua cơ chế ghi lại thao tác user thì, lập trình viên có thể thao tác với dữ liệu text (trong Word), bảng biểu, dữ liệu (trong Excel) vô cùng trực quan, và kế thừa các công cụ phân tích dữ liệu, tạo các report chuyên nghiệp (còn dễ dàng và thân thiện hơn cả Crystal Report). Trong Excel chúng ta có hơn 400 hàm Built-In có thể thao tác trực tiêp với dữ liệu mà không cần phải sử dụng các lệnh lập trình. Một trong những tính năng cũng rất mạnh mẽ mà ít có ngôn ngữ nào hỗ trợ đó là khả năng debug in desgin mode. Mặc dù C# cũng được quảng cáo có tính năng này nhưng thực tế vẫn phải compile toàn bộ mã nguồn mới debug được hoặc chỉ áp dụng tính năng này 1 cách rất hạn chế. Với cửa sổ immediate window thần thánh chúng ta có thể gớ rối hay chạy từng lệnh (debug) với từng function hay sub một cách dễ dành và vô cùng thuận tiện. Ví dụ minh họa tính năng này: bình thường muốn debug chúng ta phải biên dịch và chạy chương trình ở chế độ run-time, giống như muốn uốn nắn chỉnh sửa 1 tác phẩm kim hoàn, chúng ta phải nung nóng để kim loại mềm ra thì mới uốn nắn được, thì riêng với VBA, chúng ta có thể vẫn uốn nắn được kim loại ở nhiệt độ bình thường không phải nung nóng nhiêu khê nữa. Cộng với khả năng lập trình dạng kéo-thả và theo sự kiện và tương tác sống với dữ liệu trên Excel, mà nhiều người thường chọn VBA trong Excel để lập trình Prototype. Bản thân tôi cũng thường dùng Excel VBA để xây dựng và thử nghiệm các thuật toán, ví dụ như chương trình tính tọa độ vĩ độ mặt trời, phần tử bắn cho pháo binh, phần tử phóng cho tên lửa, hay hệ thống chấm điểm, tôi vẫn dùng VBA để xây dựng thuật toán và chạy thử với dữ liệu Uni test là các dữ liệu trong Excel, sau khi thuật toán chạy đúng thì mới chuyển qua Java để viết app cho Android, hay đơn giản có thể chuyển sang VB.NET vì có cú pháp tưởng tự của Visual Basic để phát triển các app có độ chuyên nghiệp cao hơn.
Một tấm huy chương bao giờ cũng có 2 mặt, và mặt trái của VBA là:
  • Dữ liệu không quá 1.000.000 bản ghi.
  • Khó làm việc nhóm, dùlLàm việc cá nhân thì rất tốt.
  • Xử lý đa nhiệm đa luồng kém.
Tuy nhiên với các ứng dụng không quá lớn và đặc biệt đối với lứa tuổi học sinh thì các nhược điểm này hoàn toàn không đáng kể. Tôi đã từng dạy một lớp VBA cho các bạn văn phòng của một nhà hàng, gồm kế toán, thủ kho, nhân sự, chỉ sau 1 buổi họ đã biết lập trình tạo ra các hàm mới, và sau 4 buổi họ đã hoàn toàn tự động hóa được khâu chấm công, tính lương, bóc bill để làm chứng từ thuế, mà trước đây mỗi lần khai báo thuế cả đội văn phòng phải thức thâu đêm nhiều ngày để làm bằng tay, và giờ đây thời gian rút gọn xuống chỉ còn 1 vài giờ.

Kết luận

Không nên dạy Pascal cho học sinh lớp 11, vì NNLT này quá lạc hậu và tính ứng dụng kém, nhưng cũng không nên chọn C, C++ hay Python vì đó là những NNLT dành riêng cho các lập trình viên chuyên nghiệp ngành CNTT, do đó ít có tính ứng dụng và kế thừa cho các em tương lại sẽ làm việc ở nghành khác. Thay vào đó nên chọn VBA vì nó dễ đọc, dễ học, không phải học quá nhiều nhưng lại có thể tạo ra được các ứng dụng rất hữu dụng ngay cho bản thân các em khi đã học Word, Excel từ năm trước và đặc biệt đến năm lớp 12 học Access thì VBA sẽ hõ trợ rất đắc lực (Access mà không dùng VBA thì thà dùng luôn Excel cho rồi). Và ngay cả sau này ra trường dẫu các em không theo ngành CNTT thì các kỹ năng văn phòng, tối ưu tự động hóa văn phòng vẫn luôn là hữu ích, các ngành khác như thiết kế, GIS và nhiều lĩnh vực khác đều có thể ứng dụng VBA vô cùng hiệu quả và hữu dụng.
 
Tài liệu tham khảo

[1] Công văn số 3280/BGDĐT-GDTrH ngày 27 tháng 8 năm 2020 của Bộ trưởng Bộ GDĐT, "Hướng dẫn điều chỉnh nội dung dạy học cấp trung học cơ sở môn tin học", link.

[2] https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/spectralnorm.html

[3] Python loop slower than Excel VBA?

Share:

Tuesday, September 8, 2020

05 - Nên đọc mã nguồn (source code) như thế nào?

Một trong số những người có ảnh hưởng lớn nhất đến ngành Công nghệ thông tin thế giới và đến cả cuộc sống của chúng ta đó là Linus Torvalds (sinh năm 1969 ở Phần Lan). Hàng ngày hàng giờ, hàng tỷ người vẫn đang sử dụng những sản phẩm có liên quan đến đại cao thủ lập trình đó. Hệ điều hành Linux do ông sáng tạo ra vào năm 1991 đã len lỏi trong hàng tỷ thiết bị IoT nhỏ bé cho đến các siêu máy tính có sức mạnh khủng khiếp: "Linux Runs on All of the Top 500 Supercomputers, Again!" (https://itsfoss.com/linux-runs-top-supercomputers/). Hàng tháng có 2.5 tỷ người thường xuyên sử dụng thiết bị Android (điện thoại, máy tính bảng...) theo [1], trong khi đó họ nhà táo chỉ có 1.4 tỷ thiết bị IOS mà thôi. Thị phần hệ điều hành cho thiết bị di động Android: 74.25% và IOS là 25.15% [2]. Android chính là một phiên bản rút gọn của Linux. Linus Torvalds là một người rất đam mê công nghệ và gần 30 năm qua ông vẫn code và chủ trì chính dự án Linux Kernel và Git, đồng thời ông cũng là một người thẳng thắn và có nhiều phát biểu rất sốc. Linus từng nói: "Chém gió chỉ là vớ vẩn, ông hãy trình code ra đi" - “Talk is cheap. Show me the code.” Hôm nay ông giáo sẽ chia sẻ kinh nghiệm đọc mã nguồn của Linus Torvalds: Linux Kernel nói riêng và nghiên cứu mã nguồn của một dữ án mã nguồn mở nói chung. Ông giáo đã từng đọc mã nguồn Linux Kernel có 10 triệu dòng lệnh, Bitcoin: 500 nghìn dòng lệnh và Ethereum: 600 nghìn dòng lệnh.

1. Thách thức khi đọc một dự án mã nguồn mở

Ngày nay có hơn 180.000 dự án mã nguồn mở, trong số đó có rất nhiều dự án đồ sộ, ví dụ như dự án nhân của hệ điều hành Linux phiên bản 5.8.2 đã là 27.8 triệu dòng lệnh [3]. Cách đây 15 năm khi ông giáo nghiên cứu bản 2.4 thì đâu đó mới chỉ có 10 triệu dòng lệnh mà thôi. Bơi trong một biển dòng lệnh như vậy sẽ khiến cho vô vàn code sĩ hụt hơi, choáng ngợp và thường là bỏ cuộc.

Vậy những khó khăn thách thức chủ yếu là gì:

  • Không biết bắt đầu từ đâu: giống như được thả vào một cách rừng bát ngát toàn cây và không biết đi về hướng nào.
  • Ít có tài liệu hướng dẫn chi tiết và mô tả thiết kế, nên không hiểu được logic của hệ thống. Đôi khi xem lại chính code mình viết cách đây vài năm là đã thấy khó hiểu huống chi đọc code của bao nhiêu người khác có văn hóa, trình độ và thói quen hoàn toàn khác.
  • Rất khó theo dõi, đọc code không giống như đọc truyện, không như các trang sách cứ tuần tự từ đầu đến cuối. Trong mã nguồn thường một hàm sẽ gọi nhiều hàm con, trong hàm con đó lại gọi hàm cháu, hàm chắt... Và các hàm này không được viết liền nhau mà sẽ nằm ở một vị trí khác nhau trong file mà thậm chí nằm ở những file khác và ở những thư mục khác, người đọc sẽ phải switch liên tục từ chỗ này ra chỗ khác từ file này qua file khác và qua cả các thư mục khác... 
  • Với nhưng dự án lớn thì thời gian và công sức sẽ là những thách thức rất lớn, đòi hỏi người đọc phải có tinh thần thép, không bị nản, không bị ngợp mới có thể đi được đến cùng.
Để có thể đọc và nghiên cứu mã nguồn của một dự án lớn, chúng ta cần phải trang bị những công cụ hữu hiệu và một chiến lược hay một phương phát đọc mã nguồn hiệu quả.

2. Công cụ phần mềm để đọc mã nguồn

Các công cụ này không nhất thiết phải có tuy nhiên có thì sẽ hỗ trợ công việc tốt hơn và hiệu quả hơn. Các công cụ này cũng là những công cụ mà ông giáo cảm thấy hay ho và lựa chọn chúng hoàn toàn là do sở thích cá nhân, người khác có thể dùng các công cụ quen thuộc khác hoặc không dùng công cụ gì cả.
  • Bộ soạn thảo mã nguồn tích hợp IDE (Integrated Development Environment): thường thì làm việc với ngôn ngữ nào thì sẽ lựa chọn IDE thường được sử dụng để viết ra các mã nguồn đó. Các công cụ này thường tích hợp nhiều tính năng, trong đó quan trọng là soạn thảo, gỡ rối và biên dịch. Có thể kể đến vài IDE phổ biến như: MS Visual Studio, Visual Studio Code, Android Studio, XCode, Netbeans, Eclipse, IntelliJ IDEA, thậm chí là cả VIM, và Notepad.
  • Công cụ soản thảo Text. Có nhiều lựa chọn, nhưng ông giáo rất hay dùng và yêu thích phần mềm PSPad do một lập trình viên người Czech và cũng ở Brno nơi ông giáo từng học 5 năm ở đó. PSPad là một phần mềm miễn phí rất nhỏ gọn, hỗ trợ soạn thảo và hiển thị từ khóa của rất nhiều ngôn ngữ lập trình, có khả năng soạn thảo Unicode Text cũng như soạn thảo file nhị phân Hex Editor, ngoài ra nó cũng là FPT Client để có thể soạn thảo Web HTML và đẩy lên server ngay trong PSPad mà không phải dùng phần mềm khác để upload...
  • Công cụ phân tích và tạo tài liệu cho mã nguồn tự động Doxygen:  "Doxygen is the de facto standard tool for generating documentation from annotated C++ sources, but it also supports other popular programming languages such as C, Objective-C, C#, PHP, Java, Python, IDL (Corba, Microsoft, and UNO/OpenOffice flavors), Fortran, VHDL and to some extent D". Công cụ tạo các tài liệu về mã nguồn rất chuyên nghiệp, tổng hợp các lớp, các hàm có trong dự án. Khi xây dựng tài liệu cho dự án ông giáo cũng hay sử dụng công cụ này. Từ năm 2008, ông giáo đã là người đầu tiên và duy nhất cho đến bây giờ chuyển ngữ phần mô tả tiếng Việt cho Doxygen nhờ vậy chúng ta sẽ có tài liệu mô tả mã nguồn bằng tiếng Việt.
  • Công cụ bóc tách và vẽ sơ đồ thuật toán từ mã nguồn Visustin. Đây là côg cụ cũng khá mạnh để tự động vẽ sơ đồ thuật toán (flowchart) từ mã nguồn. Đối với các dự án cần xây dựng tài liệu một cách chuẩn chỉnh thì ngoài các biểu đồ Use case, biểu đồ UML thì cũng cần phải vẽ cả sơ đồ thuật toán nữa. Visutin là công cụ mạnh nhất tại thời điểm 2011 là lúc ông giáo mua bản quyền phần mềm này. Vì nó là công cụ cũng khá hữu hiệu nên giá khá đắt: 500 USD cho 1 user, riêng nâng cấp cũng mất đến 250 USD.
  • Công cụ ghi chép trong quá triình làm việc Evernote: Đây là công cụ để take notes mạnh nhất cho đến thời điểm này, cho phép viết note đầy đủ các định dạng HTML, có nhiều template rất chuyên nghiệp, có khả năng tổ chức dữ liệu và tìm kiếm nhiều chiều: theo thư mục, theo key word, theo hashtag... Evernote có bản miễn phí và bản có phí (500K/năm), có bản desktop và mobile.
  • Công cụ quản lý tài liệu tham khảo Mendeley: Đây là phần mềm miễn phí tốt nhất cho việc quản lý tài liệu tham khảo và quản lý tài liệu trích dẫn, có addin tích hợp vào MS Word để tham chiếu tài liệu tham khảo ngay trong Word, hoặc cũng có thể xuất ra LaTeX. Có bản Mobile và Desktop và free 2G dữ liệu trên cloud.
3. Phương pháp đọc mã nguồn của ông giáo

Đây là phần chia sẻ, đúc kết kinh nghiệm của ông giáo trong hàng chục năm lập trình và nghiên cứu mã nguồn, các bạn sẽ không tìm thấy trên mạng hay trong các giáo trình hay sách tham khảo đâu nhé. Tùy theo mục tiêu của người nghiên cứu, hoặc phải nắm toàn bộ project hay chỉ cần đúng phần nhỏ mình quan tâm. Nếu chỉ cần nghiên cứu một thành phần thì chúng ta sẽ chỉ tìm đúng phần quan tâm và bỏ qua tất cả các phần khác. Có thể tìm theo thư mục hoặc dùng PSPad hay IDE để tìm theo key word. Giống như khi chúng ta crack phần mềm được bảo vệ bằng số serial number, chúng ta chỉ reverse mã nguòn đến đúng đoạn kiểm tra số serial number để bypass hoặc tìm đoạn mã để tạo genkey tools mà bỏ qua tất cả các mã nguồn còn lại.

Đối với việc cần tìm hiểu một project hoàn chỉnh. thì có thể thực hiện theo các chiến lược và phương pháp như sau:
  • Hãy làm việc như một hacker, chỉ khác là hacker thường phải dùng công cụ reverse engineering để có mã nguồn thì chúng ta có đã có mã nguồn mở, bản đẹp (tên biến tên hàm rất tường minh chứ không bị mất như khi làm reverse). Khi đã hành xử như một hacker thì chúng ta cần thu thập mọi thông tin, mọi manh mối liên quan đến project giống như hacker thực hiện hành vi APT (Advanced Persistent Threat). Tìm hiểu tài liệu của dự án, đọc các commnet trong mã nguồn, tìm kiếm trên google với các key word phù hợp, trang bị các kiến thức nền tảng liên quan, tìm đọc các sách tham khảo...
  • Tìm hiểu cấu trúc thư mục của mã nguồn, các tác giả thường đặt tên thư mục mã nguồn đều có những ý nghĩa gợi nhớ khá rõ ràng và tên các thư mục đó cũng nói lên nhiều điều, hay bản thân tên của các file mã nguồn cũng đều có những ý nghĩa gợi ý rất tốt.
  • Dùng các công cụ tìm kiếm mạnh để tìm sự xuất hiện của các hàm (function, sub) được định nghĩa ở đâu được tham chiếu ở những đâu, Doxygen cũng có thể tạo ra các báo cáo này.
  • Khi bắt đầu hãy tìm hiểu các chương trình chính, các luồng chính. Tìm các hàm main(), hay các thread khởi động...
  • Có thể tìm một phiên bản cũ ngắn gọn để hiểu logic chung, ví dụ khi nghiên cứu mã nguồn của linux kernel nếu chúng ta nghiên cứu ngay vào phiên bản hiện tại 5.8.2 thì sẽ khá là choáng ngợp với 27.8 triệu dòng lệnh, hơn 800M mã nguồn, thay vì như vậy chúng ta tìm bản 1.0 chỉ có vài ngàn dòng lệnh với cỡ 50K mã nguồn mà thôi. Hiểu được kiến trúc ban đầu của Linux Kernel rồi, quay ngược lại tìm hiểu phiên bản hiện hành sẽ dễ dàng hơn nhiều.
  • Có thể cho phần mềm dự án chạy ở chế độ gõ rối (debug) để theo dõi chương trình hoạt động ở một điểm nào đó, rồi cho nó chạy từng dòng lệnh để theo dõi input và các ouput cũng như các giá trị biến trung gian.
  • Và điều quan trọng nhất để cuối cùng đây: luôn luôn phải ghi chép, vì khối lượng công việc lớn, và bộ nhớ của chúng ta có hạn, không thể nhớ được một lượng thông tin khổng lồ, do đó mỗi khi tìm hiểu được một vấn đề gì thì cần ghi chép ngay, hoặc thấy vấn đề nào hay hoặc vấn đề nào cần lưu ý thì cũng phải ghi lại. Cách tốt nhất để ghi (take notes) là dùng phần mềm Evernote. Riêng ghi chép ở Evernote thì cũng cần có các chiến lược sau:
    • Sử dụng lối ghi indent (thò thụt) giống như python để thể hiện các cấu trúc lồng nhau, thậm chí có thể sử dụng cấu trúc thò-thụt này để có thể ghi được bản dồ tư duy (mind map) dạng text có cấu trúc.
    • Ghi làm sao để có thể dễ dàng tra cứu, và khi cần tìm được lại đúng ví trí của mã nguồn gốc.
    • Sử dụng các định dạng: đậm, nghiêng, gạch chân, tô màu để làm nổi các ý cần nhấn mạnh.
    • Khi tìm hiểu 1 hàm, thì cố gắng ghi tất cả thông tin về hàm đó và cả những hàm con của nó cùng ở một chỗ để không phải switch đến chỗ khác và như vậy chúng ta sẽ có một bức tranh toàn cảnh của hàm đó, có thể xây dựng một quy ước riêng, một ngôn ngữ riêng của mình để tạo thuận tiện nhất khi tra cứu và làm rõ thông tin của hàm cần tìm hiểu.
4. Minh họa

Hình dưới đây là minh họa tìm hiểu toàn bộ phần xử lý block trong mã nguồn của Ethereum. Trong hình sẽ mô tả luồng khởi tạo, các hàm quan trọng được tổ đỏ, các hàm cần lưu ý tô đậm, và những đoạn text được đóng khung trong đoạn <<...>> là nguyên bản trong mã nguồn, khi cần copy đoạn text trong khung đó để search lại đoạn mã nguồn gốc.
  • Trong thread sẽ khởi tạo để quản lý các block, với hàm NewBlockchain thông qua lệnh <<go bc.update() >>
  • Phần dưới mô tả hàm  InsertChain và các công việc cũng như các hàm được họi trong nó, trong số đó có hàm  VerifyHeaders  cũng là một hàm quan trọng và được mô tả các công việc liên quan.
  • Với cách ghi chép như vậy chúng ta có thể hiểu khá rõ các thủ tục và các công việc cần làm khi thêm một blockchain (inserChain) một cách tường minh, đầy đủ nhưng cũng rất ngắn gọn...

BLOCK
  • Khởi tạo luồng cập nhật block: <<NewBlockChain>> gọi <<go bc.update() >> trong đó có gọi hàm << bc.procFutureBlocks()>> theo thời gian <<futureTimer.C>> là 5s, trong hàm này sẽ lấy ra danh sách các blocks và sẽ gắn vào chain qua hàm  <<bc.InsertChain(blocks[i : i+1])>>.
  • Hàm <<InsertChain>>:
    • Kiểm tra số của block thứ i phải lớn hơn block thứ i-1 giá trị 1.
    • Kiểm tra giá trị băm của block cha phải bằng giá trị băm hiện tại <<chain[i].ParentHash() != chain[i-1].Hash()>>.
    • Tăng giá trị <<bc.wg.Add(1)>>, waitGroup.
    • Kiểm tra các header của các block. <<bc.engine.VerifyHeaders(bc, headers, seals)>>.
      • Nếu tổng số headers==0, hoặc chế độ ModefullFake thì dừng <<if ethash.config.PowMode == ModeFullFake || len(headers) == 0 >>.
      • Nếu số lượng works lớn hơn số header thì điều chỉnh số workers bằng số header <<workers := runtime.GOMAXPROCS(0)>>.
      • chạy vòng for thực hiện hàm xác thực <<ethash.verifyHeaderWorker(chain, headers, seals, index)>>, hàm này kiểm tra giá trị cha, và kiểm tra tính liên tục của số (number) của block, sau đó gọi hàm <<verifyHeader>>:
        • Kiểm tra header.Extra phải nhỏ hơn  params.MaximumExtraDataSize.
        • Nếu có uncle thì header.Time phải nhỏ hơn 2^256, khi không có uncle thì header.Time < now() + allowedFutureBlockTime (15 s),  header.Time cũng phải nhỏ hơn parent.Time.
        • Kiểm tra độ khó dựa trên tem thời gian và độ khó của block cha (trước đó): <<expected := ethash.CalcDifficulty(chain, header.Time.Uint64(), parent)>>. giá trị tính được phải bằng header.Difficulty.
        • Kiểm tra phải có header.GasLimit < 2^63-1.
        • Kiểm tra phải có header.GasUsed < header.GasLimit.
        • Kiểm tra phải có:  |parent.GasLimit - header.GasLimit| < parent.GasLimit / params.GasLimitBoundDivisor (1024) và header.GasLimit > params.MinGasLimit (5000).
        • Kiểm tra phải có: header.Number = parent.Number + 1.
        • Kiểm tra PoW <<ethash.VerifySeal(chain, header)>> xem có lỗi không.
        • Kiểm tra <<misc.VerifyDAOHeaderExtraData(chain.Config(), header)>> xem có lỗi không.


5. Kết luận

Trên đây là chia sẻ những kinh nghiệp thực tế của ông giáo, có thể nó không phù hợp với một số người hoặc có thể có những người có các phương pháp hay hơn, nhưng đây là cách ông giáo đã tìm hiểu Linux Kernel (10 triệu dòng lệnh), Bitcoin (500k dòng lệnh) và Ethereum (600k dòng lệnh), và qua việc tìm hiểu mã nguồn và ghi chép như vậy mà ông giáo có thể hiểu khá sâu sắc về Bitcoin cũng như Ethereum, khi học viên hỏi bất cứ vấn đề gì liên quan ông giáo đều có thể trả lời chính xác và thực tế nó được triển khai trong mã nguồn như thế nào, và cũng từ đó mới phát hiện ra rằng ngay cuốn kinh điển và nổi tiếng là Mastering Bitcoin của Andreas M. Antonopoulos cũng có 2 lỗi sai cơ bản mà không ai phát hiện ra. Không có thông tin hay kiến thức gì chính xác và chi tiết cụ thể về một dự án bằng chính mã nguồn của dự án đó. Một người lập trình toàn bộ một phần mềm, hay kiến trúc sư của một dự án thành công, thì người lập trình đó có thể được coi là chuyên gia trong lĩnh vực đó mặc dù backround ban đầu của anh ta chỉ là một lập trình viên. Cũng bằng cách như vậy mà ông giáo có thể thao thao hàng tiếng đồng hồ về tên lửa, về pháo, về thiên văn, về virus về các Chip về phương pháp phần tử hữu hạn, và về cả skating cho dancesport.

6. Tài liệu tham khảo

[1] https://venturebeat.com/2019/05/07/android-passes-2-5-billion-monthly-active-devices/ 

[2] https://gs.statcounter.com/os-market-share/mobile/worldwide

[3] https://www.linux.com/news/linux-in-2020-27-8-million-lines-of-code-in-the-kernel-1-3-million-in-systemd/


7. Phụ lục

Một số hình ảnh về công cụ và tài liệu mô tả về Linux Kernel.






Share:

Recent Posts

Definition List