debian

Lâu lắm rồi mới quay trở lại với HĐH ưa thích, Debian Linux, đương nhiên không thể mượt mà, bóng bẩy như MacOS được, nhưng cũng có những điều thú vị riêng mà những HĐH khác không thể nào có được! Về lập trình, tôi vẫn rất thích Linux ở cái “performance – hiệu suất” của nó, xử lý files, gởi nhận dữ liệu qua mạng, giữa các máy với nhau nhanh như chớp, xử lý tiến trình, tiểu trình cho các hệ thống client / server rất hiệu quả! Ngoài ra thì thích phá gì thì phá, tha hồ thay đổi tùy thích. Đầu tiên là build gói CoreCtrl từ source (do Debian vẫn chưa hỗ trợ gói này trong repo chính thức). Open-source vẫn có những cái rắc rối, phiền phức riêng của nó, mà phổ biến là code thường lỗi, không build được, phải sửa một hồi rồi make, make install, etc…

Chạy CoreCtrl kiểm tra nhiệt độ CPU, GPU, đếm số vòng quay của các quạt tản nhiệt! Rồi dùng phần mềm để disable luôn cái quạt, tháo ra dẹp qua bên, cái card màn hình giờ chỉ còn tản nhiệt, không còn phần nào chuyển động (no moving part)! Phần vì không có nhu cầu xài đồ họa mạnh nên nhiệt độ GPU hiếm khi vượt quá 50C, phần là muốn xác minh cái “tin đồn”: nếu tháo quạt, hệ thống sẽ tự động tắt card màn hình nếu bị quá nhiệt! Hình như “tin đồn” không được đúng cho lắm, ít ra là trên Linux! Tiếp đến, build gói OpenRGB cũng từ source để điều khiển mấy cái đèn LED trang trí, LED bàn phím, có hàng chục “kịch bản chiếu sáng” khác nhau: đổi màu, đổi độ sáng, nhấp nháy, tất cả đã được lập trình sẵn, chỉ cần load lên và chạy!

dual xeon

Đã hơn 15 năm không xài PC, chỉ xài Mac, nay thử quay lại xem sao, đem về một con con Dual Xeon. Lần cuối cùng tự ráp để xài một con PC là cách đây cỡ 25 năm, lúc đó hãy còn là bộ VXL Pentium II, riêng con CPU là đã to gấp đôi cái điện thoại iPhone 7 á! Tôi còn nhớ rõ thời đó, máy chủ của khoa KNTN, đại học KHTN chạy song song 2 con VXL Pentium III, phải 4 người khiêng 4 góc mới đem đi được! Đem Dual Xeon so với con MacMini M2Pro, đáng ngạc nhiên là phần mềm PassMark cho điểm 2 hệ thống xêm xêm nhau, đều khoảng 23000. Về hiệu năng tính toán số nguyên, số thực thuần túy thì DualXeon vượt trội, nhưng M2 hơn ở khá nhiều khoản tính toán khác!

Đương nhiên so sánh vậy chả công bằng chút nào, một bên chỉ là hệ thống “mini”, bé có chút xíu và chỉ xài một con CPU. Còn bên kia là hệ thống “lớn”, dùng đến 2 CPU loại mạnh chạy song song với nhau, chưa kể lượng RAM nhiều hơn gấp 4 lần! Hai cái tản nhiệt nước, 7 cái quạt gió cỡ lớn, toàn bộ cái máy nó hú như máy bay đang chạy “taxi-ing” vậy! Ai xài Mac thì sẽ thấy kích thước nó vừa nhỏ xinh, vừa mát mẻ, chạy hầu như không phát ra tiếng động! Haizza, còn cái kia to như khủng long, hú cũng gần như động cơ phản lực! Đem so PC với Mac cũng như so phim VN với phim TQ vậy: ăn nói oang oang, thô lỗ, bỗ bã, hàm hồ, thiếu hẳn sự ý tứ, tinh tế!

3M Novec

Làm mát bằng nước hay bằng dầu khoáng (mineral oil) là xưa rồi… giờ họ làm mát bằng dung dịch “3M Novec xxxx” (có bán đầy ở ngoài thị trường). Thực ra, kỹ thuật này đã được dùng với siêu máy tính Cray-2 từ năm… 1985, nhưng chỉ phổ biến trong thị trường máy tính dân dụng vài năm gần đây! Toàn bộ board mạch máy tính được nhúng ngập trong “3M Novec”, loại chất lỏng không dẫn điện, sôi ở 56 độ C, có thể hạ tiếp nhiệt độ sôi bằng cách rút bớt không khí ra khỏi case, tạo môi trường áp thấp, như ta biết, nhiệt độ sôi phụ thuộc vào áp suất! Sau khi hấp thu nhiệt, bốc hơi thành thể khí, khí này chạy qua bộ phận làm mát, ngưng tụ (condenser) với các lá kim loại tản nhiệt và quạt gió ở phía trên, lại hóa thành thể lỏng và rơi xuống dưới trở lại!

Giống như là mây – mưa vậy, cứ thế tuần hoàn! Kỹ thuật này giúp tăng mật độ thiết bị điện tử lên cả chục lần mà vẫn bảo đảm vấn đề tản nhiệt! Và quan trọng là có thể thực hiện tương đối dễ dàng, cho cả quy mô cá nhân (như PC) lẫn quy mô công nghiệp (như data-center). Cũng gần gần giống như cách làm các trạm biến áp xưa, toàn bộ thiết bị được bỏ trong container kim loại chứa ngập dầu khoáng, dùng dầu làm chất dẫn nhiệt! Nhiều người đã làm dàn máy tính cá nhân sử dụng tản nhiệt bằng “3M Novec” kiểu aquarium, trông giống như cái bể cá thủy sinh thật sự, nhìn rất đẹp mắt! Rất thích tự build một cái workstation thế này, nhưng trước tiên là… phải đi kiếm những bài toán cần đến năng lực tính khủng như thế đã!

25 năm sau

Hai mươi lăm năm sau, trên một cái máy tính có 16 GB RAM chứ không phải chỉ vẻn vẹn… 4 MB như hồi đó! Cái thời còn chạy Win 3.1.1, rồi sau nữa là Win 95, Win 97, Win ME, Win NT, etc… Mới trước đó chỉ độ vài năm thì thậm chí, máy tính… không nhất thiết cần phải có ổ cứng mới chạy được, chỉ cần đúng một cái đĩa mềm để khởi động hệ điều hành MS-DOS 5.0 rồi chạy Turbo-Pascal hay Borland-C để học lập trình!

Làm phép tính nhẩm để kiểm chứng định luật Moore, định luật nói rằng: mật độ transistor tăng gấp đôi sau mỗi 2 năm, tổng thời gian là cỡ 24 năm, tức là RAM phải tăng ước chừng khoảng 2 ^ (24 / 2) = 4096 lần, tính ra thì thấy đúng chính xác là như vậy, 4 MB x 4096 = 16 GB (!!!) Có quá nhiều thứ đã đổi thay, nhưng vẫn có một số thứ hoài không thay đổi, cái này ai trãi qua rồi mới cảm thấy có chút… hoài niệm!

vừng ơi, mở ra!

Tình hình là vẫn code cho đến tận ngày cuối năm Dương, và ngồi setup cái máy tính mới! Dù sao thì xài con laptop $3000 để thay thế cho vai trò của desktop một cách tạm bợ, từ ngày này sang ngày khác như vậy cũng thấy hơi xót, đến lúc cũng nên trang bị một máy desktop cho đúng nghĩa, công nhận chip M2 chạy cực lẹ…

Nãy cấu hình máy, đến phần username / password, định đặt pass là “open sesame” – tiếng Việt tức là: “Vừng ơi, mở ra!” (truyện Alibaba và 40 tên cướp), nhưng thấy pass dễ đoán quá nên thôi! Năm mới đang đến, hy vọng mọi thứ cũng sẽ… “Vừng ơi, mở ra”! Chúc mọi người năm mới… thân tâm an lạc, vạn sự như ý!

avl tree

Lâu rồi mới trở về những “bài tập lập trình” cơ bản, như thời ĐH, những vấn đề thú vị, nhưng cần sự tập trung cao và kéo dài khi coding. Bài toán như sau: hầu hết các hệ điều hành đều cung cấp cho người dùng hệ thống tập tin (file), các thư mục lồng nhau (nested) và chứa trong đó những thư mục con, tạo thành một hình cây (tree)! Nhưng đó là với người dùng, thực chất, hệ thống tổ chức bên dưới dạng flat – list, một danh sách phẳng, hiểu đơn giản là một cái mảng lớn không phân cấp chứa tất cả các tập tin! Mỗi tập tin ở mức quản lý thấp của HĐH chỉ có số (inode) chứ không có tên, đọc từ đầu đến cuối đĩa chỉ là cái mảng một chiều có rất nhiều phần tử. Tiếp theo đó, ở lớp (layer) kế trên, người ta mới đề cập đến tên của tập tin (file name, path).

Ví dụ như: ~/Downloads/aaa.pdf hay /System/Library/CoreServices… Từ những đường dẫn đầy đủ này truy vấn từng cấp, ra được số inode và tìm đến các khối lưu trữ thực bên dưới! Nhưng lưu và tìm thế nào cho nhanh, không phải duyệt cái mảng quá lớn? Tên tập tin, đường dẫn thư mục thực chất được tổ chức thành dạng cây AVL – AVL tree! Độ phức tạp của thuật toán tìm kiếm sẽ giảm từ O(n) xuống thành O(log(n)). Ngồi đọc lại bài xuất bản năm 1962 của hai nhà bác học Liên Xô: Georgy Adelson-Velsky và Evgenii Landis, lâu lắm rồi mới được trở lại code C đúng nghĩa! Đơn giản là tự ra bài tập để làm cho vui, tìm lại cái cảm giác lập trình chân chính, thực sự, sau nhiều năm tháng toàn code lảm nhảm Swift, Python, etc…


weekend humor

Weekend humor, picture created by me using GIMP! About programming languages, just for fun, don’t take it too literally and seriously! There’re a lot, a lot more stuffs like JavaScript. It reminds me just that: what users really want is a smoothly-run “program”, not some mis-reading, mis-interpreted “scripts”!

async/await is a big scam

L
âu lắm mới có hứng nói về vấn đề kỹ thuật, lần này mạnh dạn đưa ra một nhận định: async/await là một trò bịp lớn trong các ngôn ngữ lập trình – async/await is just a big scam in programming languages! Mọi người chờ 5, 10 năm nữa xem nhận định này đúng không nhé! Lâu về trước có làm một chút với async/await trên C# và JavaScript, là đã thấy nó không được đúng lắm! Gần đây làm với async/await trên Swift lại thấy càng không đúng! Những cái về threading – process – synchronization – tiến trình, tiểu trình và đồng bộ hóa là phải đọc giữa các dòng chữ – read between the lines! Còn cái mindset của những người làm ra async/await nó giống kiểu bắt chết vào ngôn từ hình thức, họ chấp vào ngôn từ bề mặt!

Async/await chỉ là vấn đề, và cũng chỉ là giải pháp của… riêng JavaScript! Khởi thuỷ xa xưa, JavaScript chỉ được phép có đúng một thread, nên để không block thread này thì họ đã tìm cách offload các hàm sang thread background của hệ thống, và vì làm việc này theo kiểu tuỳ tiện nên phải sinh ra cái async/await để “đánh dấu”, thuận tiện hơn cho việc đồng bộ hoá! Vấn đề này đơn giản là của riêng JavaScript, các ngôn ngữ khác… không thấy có! Async/await khi đem một cách khiên cưỡng sang những ngôn ngữ khác không tạo ra lợi ích nào đáng kể, ngược lại làm phức tạp hoá vấn đề và hiệu suất – performance… rất tệ! Những newbie chưa hiểu sự phức tạp của hệ thống mới thần thánh hoá và cho rằng async/await là cái gì đó siêu việt!

Async/await nó mang cái mindset 2 threads: foreground & background, xuất phát từ hạn chế chỉ được phép có một thread của JavaScript! Với những ngôn ngữ như C, C++, Obj-C, etc… thì bản thân cái không gian tính toán nó đã là n-thread, từ ngàn xưa là đã dã man, phức tạp và đa năng rồi! Chuyện với async/await không biết phải nói làm sao… nó giống như câu: “màn hình cong (curved monitor) có rất nhiều vấn đề, mà vấn đề đầu tiên là nó… cong”! Tương tự vậy, async/await không đúng đầu tiên là ở chính 2 từ khoá đó, một kiểu chấp niệm vào hình thức khi cho rằng nếu tôi là sync, thì những code viết ra trước đây là async! Đây là kiểu chấp niệm, thực ra code block bản thân nó không sync, cũng chẳng async, là do cách xài mà thôi!

Tại sao nói async/await là vấn đề của riêng JavaScript!? Với các ngôn ngữ khác, tuyệt đại đa số các lời gọi hàm hệ thống là sync về mặt bản chất, điều này nhằm giúp cho coder hiểu rõ cái cost – chi phí gọi hàm! Chỉ một số ít hàm hệ thống là async, và coder phải hiểu rõ điều đó khi sử dụng! Trong trường hợp có nhu cầu không block main thread thì họ sẽ chạy code block trong một thread khác, chuyện này y hệt như vai trò của Task vậy! Nên async/await không đưa ra được một điều gì mới, càng không phải là cách giải quyết vấn đề mới! Nó đơn giản là cách vá lỗi lầm cũ của quá khứ, bằng cách đặt ra một cú pháp, và cú pháp này… rất thừa thải trong nhiều ngôn ngữ khác ngoài JavaScript, thêm phức tạp mà không giải quyết được chuyện gì!

Nên async/await là vấn đề của riêng JavaScript, thứ mà một lập trình viên nghiêm chỉnh còn… chưa xem là ngôn ngữ lập trình! Khi đem sang các ngôn ngữ khác, bản thân người thiết kế tính năng này chắc chắn là không hiểu được cơ bản về điều phối tiến trình, tiểu trình, đặt ra một thứ hoàn toàn không cần thiết! Async/wait hoàn toàn không phải là công cụ dùng để điều phối tiểu trình, tuyệt đối không có tính năng thay thế mutex, semaphore, critical sections, locks, etc… và do đó không thể dùng để giải các bài toán đồng bộ phức tạp như Producer/Consumer, Dining Philosophers, Sleeping Barber, etc… Đừng nhầm lẫn giữa một cú pháp “lảm nhảm” với các bài toán đồng bộ vốn rất phức tạp, và nên đầu tư thời gian học về căn bản!

Hãy cứ phát minh lại cái bánh xe

Có một dạo thời còn đại học, bị ám ảnh với những thứ 3D, nên tự đi viết một cái 3D-engine: phối cảnh vật thể trong không gian 3 chiều! Mà tôi biết thừa là chỉ làm cho vui, chứ những engine 3D đã có như OpenGL, DirectX nó làm tốt hơn tôi một triệu lần! Nhưng xem như bài tập, cứ làm thử xem sao! Nhờ đó mà đọc qua các lý thuyết về một tá các phép chiếu (projection) khác nhau, ôn lại một mớ Toán vector, ma trận. Cái engine tôi viết ra hiển thị tốt các đối tượng 3D phức tạp, nhưng chưa có đổ bóng hay các thao tác advanced khác!

Bạn bè cùng lứa là toàn dùng ngôn ngữ và công nghệ cấp cao, kéo thả, cắt dán các kiểu rồi, còn tôi vẫn lập trình DOS với Turbo C++ sơ đẳng như thế! Và cực kỳ ghét những câu chữ bóng bẫy, trơn tuột (catching, slippery phrases) kiểu: Don’t reinvent the wheel – Đừng phát minh lại cái bánh xe! Không làm được cái đơn giản, sao làm được cái phức tạp!? Mà điều đó thấy rất rõ ở những coder trẻ: cái gì cũng biết, mà không làm được những điều đơn giản! Mà những điều đơn giản nó không có đao to búa lớn, không huênh hoang chữ nghĩa!

Và thế rồi đi chê Trung Quốc toàn chỉ biết copy (mà mình thì đến copy vẫn chưa làm được)! Copy hay không không quan trọng, quan trọng là bắt đầu với việc đơn giản đã! Và họ cứ “trường kỳ copy” như thế hàng chục năm, trước khi có được khả năng sáng tạo cái mới! Cũng như hoạ sĩ học vẽ thôi, trước khi tạo thành phong cách, thành danh thì hàng chục năm trước, họ đã dày công học hỏi, copy hết phong cách này đến xì-tai khác! Tự dưng mới sinh ra đã thành phong cách, đã thành sáng tạo, đã có kết quả thì chỉ có “cuội VN” thôi!

Nhưng nói điều đơn giản, làm điều cơ bản, ở cái thời gian và không gian này, có khi bị coi là ngu và ngố á! Đồ dở người, đồ hâm hấp, cứ mấy cái đơn giản, cơ bản đem ra nói hoài, chả có cái gì “cao siêu” cả, toàn cộng trừ nhân chia, toán hình toán số cơ bản thôi, xem có làm được không đã! Bữa xài cái app trả tiền điện nước, mới thấy mấy cái dòng tô đỏ bên dưới, nào là “Simulate”, nào là “Giả lập”, đem cả code test vào production – môi trường chạy thật như thế, có mỗi một dòng “#if DEBUG” cũng không thêm vào được, chả hiểu làm gì để ăn!? :(

tư duy hình thức

Nhân một tranh luận gần đây trên báo chí: “trẻ em như tờ giấy trắng là một suy nghĩ sai hoàn toàn”… nhân chuyện này bàn về kiểu tư duy máy móc, hình thức của người Việt! “Trẻ em như tờ giấy trắng”, câu cũng có phần đúng, chúng nó chưa biết gì và chỉ tiếp thu, tiêm nhiễm những gì được dạy, được thấy! Nhưng câu đó cũng không đúng hoàn toàn, trẻ em như một hạt giống mang thông tin di truyền, và biết đâu đó, có thể được thừa hưởng cả những “duyên nghiệp” từ kiếp trước (từ ngữ hơi duy tâm một tí)! Nên hành trình phát triển của một đứa bé, rất thường khi là nằm ngoài tiên liệu của phụ huynh và giáo viên! Trẻ em vừa là tờ giấy trắng, vừa không phải là tờ giấy trắng, đó đơn giản chỉ là những cách diễn đạt khác nhau, hình thức lý luận nhị nguyên, một điểm yếu cố hữu của tư duy con người!

Nhưng 99% người Việt (có khi là nhiều hơn) chấp vào cái hình thức nhị nguyên thô thiển, sơ khai đó! Họ chấp vào đó như “gà mắc tóc”, điều đó dẫn đến sự “đối kháng” giữa những “suy nghĩ” khác nhau! Theo tôi, ai còn mắc vào những lỗi “tư duy hình thức” như vậy là chỉ cho thấy tầm tư duy nông cạn, hời hợt trên bề mặt, không nghĩ ra được những nội dung sâu xa hơn, không thể đi hết độ phức tạp của vấn đề, nên đành đứng trên bề mặt trắng đen như thế. Bao nhiêu “học hỏi, tư duy”, lên mạng đọc này kia, biết được một vài “ngôn từ lảm nhảm” là đã tự cho mình giỏi, nghĩ rằng bao nhiêu đó là đủ rồi! Sự việc trở nên tồi tệ hơn khi họ ngày càng “chấp ngã”, bám vào những cái lý lẽ đó theo kiểu “take position” – giữ vị trí y như trong quân sự vậy, bên này là “ta”, bên kia là “địch”!

Các tranh luận ở VN đều mang tính “đối kháng”, “chiếm lĩnh vị trí” như thế, kiểu tư duy bên kia là “địch”, bên này là “ta”, trắng đen rõ ràng! Nhưng tiếc thay, kiến thức không phải 3D hay 4D như quân sự, nó là không gian n-D vô cùng phức tạp, bao gồm rất nhiều chiều kích, thay vì đối kháng, cần phải gợi mở, để cùng phát triển, đó mới là tranh luận thực sự. Trong giáo dục, “giữ vị trí”, cố sống chết bám vào một điểm thì cũng chẳng khác nào tự giới hạn mình! Chuyện này cũng như khác biệt giữa cờ vây và cờ vua vậy! Cờ vua có tính đối kháng rõ ràng, mục tiêu là ăn “hậu” của đối phương! Nhưng cờ vây không có tính “đối kháng, ăn quân” rõ ràng, mục tiêu là chiếm lĩnh càng nhiều “dư địa”, tạo ra càng nhiều “không gian phát triển” càng tốt, nói theo ngôn ngữ cờ vây là có thêm nhiều “khí” để “thở”.

Tôi rất sợ những kiểu người bám víu vào lý luận hình thức… Họ “take position, hold the line, take the side”, ngôn ngữ của họ cứ “điểm, tuyến & diện” như thế! Mọi cách diễn đạt đều tương đối, đều không chính xác hoàn toàn, dùng nó như thế nào là cả một sự cân nhắc! Phải bước qua được rào cản của ngôn ngữ thì mới hiểu được những nội dung khác truyền tải bên dưới! Nhưng không, họ bám víu vào mớ ngôn từ chết ấy, tìm cách “tranh tiên”, chiếm lấy một lợi thế nho nhỏ bằng ngôn từ, rồi mắc cứng luôn ở đó, sau đó bằng những kiểu: do đó, cho nên, vì vậy, suy ra… tìm cách chứng minh chỉ có tôi đúng và đối phương là sai! Tranh đấu với đối phương thực chất chỉ thể hiện những mâu thuẫn, lúng túng, hạn chế nội tại mà thôi, vẫn là kiểu “tôi đúng anh sai” chứ chưa phải là khai mở kiến thức!

for… loop

For…loop… ăn, ngủ, code, đạp xe, chơi với mèo… và cứ thế lặp lại! Nhàm chán, đơn điệu, nhưng cũng phải tập lại tính kỷ luật một tí! Ku Tom có chỗ nằm mới, cứ thế leo lên nằm ngủ, đôi khi lười biếng và lơ đãng nhìn xuống xem mình coding! Chút suy nghĩ về vòng “for”… theo tôi, luôn có cái gọi là “khoảng cách thế hệ – generation gap” bên trong thế giới coder, chiều sâu suy nghĩ, độ chính chắn hoàn toàn khác xa nhau! Từ xưa, như với ngôn ngữ C, người ta điều khiển “for” bằng một biến số nguyên “i”, chỉ đơn giản là như thế!

Có nhiều phép toán số học có thể làm được với “i”, đây mới là điều quan trọng nhất! Thế nhưng các ngôn ngữ mới không chịu, cứ phải đẻ ra cái “for in stride”, rồi những thao tác lặp phức tạp trở nên rất khó thực hiện! Chỉ đọc spec một ngôn ngữ, ví dụ như Swift, tôi có thể hiểu được khá rõ độ sâu, độ chính chắn trong suy nghĩ của tác giả! Mấy người “sáng chế” ra các ngôn ngữ mới này cũng chỉ là những coder bình thường như chúng ta mà thôi, chưa đạt đến tầm như của Donald Knuth, Edsger W. Dijkstra, Robert Sedgewick, etc… ngày xưa đâu!

Planimeter

Mấy chục năm KHMT và CNTT, đôi khi tôi cảm thấy cần phải cho đi lại từ đầu, chưa đi vội về sau, đôi khi cần phải hiểu lại những điều rất rất cơ bản! Ví dụ như vẫn có nhiều người có thể đã học hết 12 năm phổ thông nhưng chưa chắc đã hiểu một “phép nhân” đơn giản!

Dưới đây là ví dụ vế Planimeter, một cái “máy” rất chi là “hấp dẫn và kích thích suy nghĩ”, máy tính “cơ học”, máy tính “analog”, dùng để tính diện tích của một hình bất kỳ, đó là thời đại trước khi máy tính, với tất cả những phần mềm CAD, CAM xuất hiện…

apps

Con đường đau khổ sẽ còn dài… cứ trậm trầy trậm trật thế này, nhiều năm không giải quyết được, cuối cùng có khi phải bỏ đi làm app khác, rồi vẫn tiếp tục lặp lại vết xe đổ như thế! Nguyên nhân từ đâu? Làm trong ngành CNTT nên em là em cứ nói thẳng: nguyên nhân từ cấp 2, cấp 3 đọc nhưng không hiểu chữ, hoặc có hiểu nhưng hiểu không sâu, chỉ lơ mơ ngôn từ bề mặt! Lên đại học, những khái niệm cơ bản đọc mãi không thông, toán đơn giản như vector, ma trận làm không được, học thiết kế CSDL cũng y vậy, viết câu lệnh SELECT 3 cấp lồng nhau vô tư…

Không biết “INNER JOIN” là cái gì, làm sao tạo “VIEW”… Không nói quá đâu vì đã thấy nhiều rồi, tất cả đều quay về cơ bản mà thôi! Nên đừng trách, em mà bắt bẻ cái gì là bẻ từng từ một! Nói thì hay lắm, lúc nào cũng Trí tuệ nhân tạo, Máy học này kia, trên mây không à, nhưng coding căn bản không làm được, sợ có khi cài đặt thuật toán QuickSort còn không được! Nên kiểu giống như học võ ngày xưa các ông thầy bắt tấn “mã bộ” suốt mấy tháng là có lý do! Vẫn phải quay về những điều căn bản nhất, mà căn bản nhất của giáo dục chính là… làm người!

PKC

Nôm na về mã hoá khoá công khai (public-key cryptography) cho nhiều người dễ hiểu, cái này chỉ cần toán cấp 2, 3 thôi! Ta lấy hai số nguyên tố rất lớn: p1 và p2 nhân với nhau, kết quả được một số nguyên siêu lớn: n = p1 x p2, n được gọi là khoá công khai (public key), còn bộ (p1, p2) được gọi là khoá bí mật (private key)! Đây cũng giống như hai mặt của một đồng xu, nếu biết trước (p1, p2) thì tính ra n rất dễ (chỉ là một phép nhân), nhưng ngược lại, khai triển luỹ thừa, từ n lần ngược trở lại (p1, p2) là siêu khó, ngay cả siêu máy tính cũng có thể mất nhiều triệu năm mới giải mã được! Về bản chất toán học, vấn đề chỉ đơn giản là như thế!

Đi sâu vào sẽ có nhiều điều phức tạp hơn! Nếu anh X được cấp bộ 2 khoá, thứ nhất là khoá công khai: n, và thứ nhì là khoá bí mật: (p1, p2), anh ta sẽ bỏ cái khoá công khai n đó lên internet hay ở nơi nào đó để ai cũng đọc được, và giữ bí mật cặp (p1, p2). Nếu Y muốn gởi mật thư cho X, Y sẽ mã hoá dùng khoá công khai n (của X), và thông điệp đã mã hoá đó chỉ có thể được giải bằng (p1, p2) mà thôi! Điều ngược lại cũng đúng, nếu X gởi đi một thông điệp có thể giải mã thành công nhờ khoá n, thì điều đó có nghĩa là: chắc chắn nó đã được mã hoá bằng (p1, p2), xác nhận được gởi đúng từ anh X, đây chính là cách xác thực chữ ký số!

Ưu điểm của mã hoá khoá công khai chính là… nó công khai, không mất công phân phối, chuyển giao “khoá” như các phương pháp khác, và khoá bí mật chỉ giữ riêng cho chủ nhân của nó! Ưu điểm cũng là khuyết điểm, cần có một tổ chức đứng ra xác thực khoá công khai này đúng là thuộc về ai đó! Ngoài ra, mã hoá khoá công khai có thể được dùng để bổ trợ cho mã hoá khoá bí mật (như các cách dùng trong quân sự): dùng phương pháp công khai để truyền tải khoá bí mật, rồi dùng khoá bí mật để mã hoá / giải mã tài liệu, như thế có thể đổi khoá bí mật định kỳ, thường xuyên một cách dễ dàng, nhanh chóng mà vẫn an toàn!

Quốc phòng vẫn chuộng sử dụng các phương pháp mã hoá khoá bí mật, đơn giản vì tốc độ xử lý! Khoá công khai dùng những số nguyên cực lớn nên tính toán mất thời gian, nhất là với dữ liệu lớn như âm thanh, hình ảnh! Có người lo ngại những thế hệ máy tính lượng tử mới có thể giải các loại khoá này, điều đó là có thật, nhất là với các khoá đã có sẵn! Nhưng nếu ta tăng p1 & p2 lên, dùng những số nguyên tố lớn hơn, thì tính toán lượng tử cũng sẽ bó tay! Năng lực “lượng tử” dùng để phá mã đó thực ra cũng có thể được dùng để tìm ra những số nguyên tố lớn hơn, “ma cao một thước thì đạo vẫn có thể cao lên một trượng”!

chatgpt

Nhân chuyện ChatGPT và các thể loại AI xôn xao dư luận gần đây. Có nhiều cách nhận định khác nhau, đương nhiên không nên đánh giá thấp vai trò của trí tuệ nhân tạo và ứng dụng của nó, nhưng bảo máy móc có trí tuệ thì chắc chắn là không! Nói ngắn gọn thế này: sáng tạo là đặc quyền của con người (hay đúng hơn là của một số người), là khả năng đi vào những vùng chưa biết, những lỗ đen kiến thức, khai phá, lập thuyết, chứng minh, etc… Chừng nào mà AI nó chứng minh được Bổ đề cơ bản, ví dụ như thế, thì tôi mới tin là máy có trí tuệ. Còn lại, máy nó chỉ lặp lại những kiến thức thu thập được, càng ngày càng nhiều, dùng khả năng siêu tốc độ của mình để xử lý, tối ưu, và trình bày ra dưới một dạng khôn khéo mà thôi! Mấy ông già “biết tuốt” VN chắc khoái con ChatGPT này lắm, cái gì cũng biết…

Có người đưa các ví dụ AI có thể tối ưu hoá những đoạn code, rồi vẽ ra viễn cảnh máy có thể code được! Chuyện này theo tôi vẫn còn xa, xa lắm! Máy nó chỉ lặp lại một số “bài” được học thôi, vì học quá nhiều nên đôi khi còn có vẻ “giỏi” hơn cả coder – con người! Và thực ra cũng có một số coder giống như thế (giống máy): rất giỏi logic, test IQ, giỏi xử lý các “câu đố” được đưa ra, nhưng kỳ lạ thay, không code được, hoặc code nhưng không giỏi, tại sao thế? Tại vì cái anh chàng “thông minh” đó thực ra chỉ “thuộc bài”, phỏng vấn các vòng đều rất ấn tượng, và cũng đôi khi là “thông minh” thật, giỏi “làm tính, giỏi logic”! Nhưng code, hiểu theo nghĩa rộng, là đi giải một bài toán thực tế, mà giải quyết vấn đề thực tế thì đôi khi “thông minh” chưa đủ, như trên đã nói, “phát minh, sáng tạo” là đặc quyền của con người.

Việc lặp lại “như vẹt” một số kiến thức đã biết chỉ tạo ra được sự “thông minh”, hay “có vẻ thông minh”, chứ không tạo ra được “phát minh, sáng kiến”, không tìm ra hướng đi mới, cách tiếp cận đúng, tìm ra giải pháp hữu ích giữa những cái “hỗn mang, vô tri, bất định”. Cuộc đời của mỗi con người đều giống như “Miếng da lừa” (tiểu thuyết của Honoré de Balzac), có bao nhiêu sinh lực dành để nhớ những kiến thức không thực sự cần thiết, những thông tin vụn vặt cốt chỉ để “loè người” hay để theo đuổi những mục đích “bất chính, bất thiện” thì đương nhiên không còn năng lực để theo đuổi những tri thức hữu ích đích thực. Thông tin thì càng ngày càng nhiều, “Hằng hà sa số” như thế, làm sao mà nhớ hết nổi?! Chuyện học “nhồi nhét kiến thức” đã nói rồi, chuyện “trọc phú tri thức” cũng bàn rồi…

Nhưng tiếc thay, lại sa đà vào mớ trừu tượng “kiến thức nguyên bản” một cách vô bổ, không đưa ra được kết luận gì hữu ích. Nhưng không ai nói cho rõ “kiến thức thật sự, kiến thức có thể sáng tạo” nó là như thế nào, bắt nguồn từ đâu, làm sao để có. Tôi cũng không hiểu lắm, nhưng cho rằng nó liên quan mật thiết đến cảm hứng sống, đến động cơ, mục đích của con người, đến sự can đảm đối diện với bản thân, và có lẽ là, từ trong sâu thẳm, liên quan đến bản chất “hướng thiện” của mỗi người! Trở lại chuyện ứng dụng ChatGPT, chuyện chẳng có gì to tát, các bác cứ làm quá lên! Chỉ là một cỗ máy thuộc bài, lặp lại như vẹt mà thôi! Nói cho đúng là một phần lớn báo chí và cư dân MXH VN về dân trí cũng cỡ đó, như cái thùng rỗng vọng lại những thứ người ta dội vào, viết tiếng Việt thì trúc trắc đọc không được…

Dịch tiếng Anh thì ngô nghê, tối nghĩa, trình ngôn ngữ e là chưa bằng máy! Và chính vì dân trí đang là như thế… nên ChatGPT rồi cũng là công cụ như Wikipedia mà thôi, ý tôi tức là một công cụ… nô dịch tư tưởng! Ví như đám lưu manh trên mạng, mỗi lần có tranh cãi gì là chăm chăm đi sửa Wiki theo hướng có lợi cho mình! Không thể phủ nhận Wiki cũng là nguồn thông tin hữu ích, nhưng nó cũng chỉ là “cái chợ” của con người, có đủ thứ “thượng vàng hạ cám” ở trên đó. ChatGPT rồi cũng sẽ được dùng như một công cụ “nô dịch tư tưởng”, dùng cho những loại óc “bã đậu”, chuyển giao “thông tin” dưới dạng “mì ăn liền”, cái “thông tin” đó được nguỵ trang là “kiến thức”, “tri thức”, là “chân lý”. Nếu có sợ là sợ cho những thành phần dân trí quá thấp, nói gì cũng nghe, chứ ai lại đi sợ cái máy!?

Ai cũng biết, sự học thuộc lòng (dù nhồi nhét) chính là điểm khởi đầu của giáo dục, trẻ con đâu có biết gì nên cứ phải ép nó học thuộc một số “nguyên liệu thô” ban đầu, kiểu như: Nhân chi sơ, tính bản thiện, tính tương cận… ChatGPT, tôi xem như đứa trẻ 3, 4 tuổi, bắt đầu bi bô những kiến thức đầu tiên. Và kệ mịa nó nói gì, lớn lên rồi thì nhiều người sẽ dễ dàng đồng ý là: Nhân chi sơ, tính bản ác! Trở lại với ChatGPT, tôi vẫn xem nó là “con vẹt” học tiếng người, thấy con chuột đến giả tiếng mèo để đuổi chuột đi, thấy con mèo tới giả tiếng người nạt nộ để đuổi mèo đi. Nếu là vẹt thì người ta kêu là nó thông minh, nhưng nếu là người, mà suốt ngày lặp lại mãi một số ngôn từ vay mượn, máy móc, vô nghĩa, chả có tí nội hàm, nội tâm nào, cứ mãi “giả tiếng”… thì người ta kêu bằng: “thiểu năng trí tuệ”.

jacquard loom

Lâu về trước có viết bài nói về công nghiệp dệt may đã là động cơ chủ yếu của Cách mạng Công nghiệp Anh như thế nào, góp phần hình thành nên một xã hội bắt đầu có nhu cầu tiêu dùng, mà tiêu dùng đầu tiên là ăn mặc đẹp đẽ, sang trọng. Nhưng đôi khi nhìn lại, ta sẽ thấy sự phát triển kỳ diệu của các ngành công nghệ khác nhau như những tấm gương lấp lánh phản chiếu lẫn nhau nhiều cấp! Dưới đây nói về sự phát triển của ngành dệt đã góp phần tạo ra công nghệ thông tin hiện đại như thế nào! Trung Quốc phát minh ra các kiểu dệt gấm, Trung Đông có những kiểu dệt thảm rất đẹp! Để tạo ra những hoa văn đầy sắc màu đó, đơn giản là điều chỉnh cách thức các sợi vải ngang, dọc, chéo đan xen vào nhau! Đến năm 1804, thương gia Pháp Joseph Marie Jacquard phát minh ra cái máy dệt mang tên mình!

Nhìn từ trên xuống, có thể hình dung tấm gấm như một ma trận điểm (dot matrix), mà ‘on’ hay ‘off’ là trạng thái nổi hay chìm của các sợi vải đan xen vào nhau! Jacquard đã dùng các bìa giấy đục lỗ (punched card) để mã hoá các thông tin hoa văn này, cho phép dệt ra những kiểu hoa văn tuỳ ý! Đây xem như là máy dùng bìa đục lỗ đầu tiên, chỉ cần thay một băng giấy khác là có thể dệt ra được kiểu hoa văn tương ứng! Bìa đục lỗ được sử dụng như cách mã hoá đầu vào – input, rồi sau đó được sử dụng để mã hoá đầu ra – output! Đến năm 1888 thì Herman Hollerith người Mỹ sử dụng bìa đục lỗ tương tự để làm ra máy thống kê sử dụng để điều tra dân số, máy chạy nhanh hơn 10 lần so với người tính toán thủ công! Tiền thân của các loại máy tính hiện đại đã ra đời… từ nghề dệt như thế!

games

Thực ra viết con game để chơi là phụ, chính yếu vẫn là muốn thử nghiệm các kỹ thuật khác nhau với “lambda function – anonymous function – hàm không tên”!

Tự viết con game Solitaire này mấy năm trước, nhưng lười, không bỏ lên AppStore. Game mà tôi tự viết để tự chơi thì cũng khá nhiều, viết vì kiếm không được game tương tự đúng ý, cái thì quảng cáo quá nhiều, cái thì đồ hoạ quá xấu, cái thì nặng nề, tốc độ quá chậm, chạy không mượt, mà tôi chơi Solitaire, mấy ngón tay bấm liên hồi như đánh piano vậy! Trò Solitaire chuẩn chơi trên máy Windows tối đa chỉ 24K điểm, nhưng cầm cái iPad mà chơi thì trên 30K điểm là chuyện thường! Game này viết chỉ một source code, chạy trên tất cả các nền Apple (Mac, iPhone, iPad…), làm cái engine sẵn, đọc game rules từ file lên, hiện tại hỗ trợ đến 99 biến thể (variant) Solitaire khác nhau!

Nhớ lại đợt Sài Gòn giãn cách XH vì Covid-19, suốt ngày chỉ có chơi game giải trí, hoặc làm mộc, cưa bào, đục đẽo để vận động tay chân! Nói về chơi game, căn bản đó không phải là chuyện gì xấu, nhưng tôi thường chỉ chơi game logic đơn giản, mỗi ngày chơi 15 ~ 30 phút tối đa, không chơi các game có kịch bản hay những game mất quá nhiều thời gian! Tác hại của game đối với giới trẻ không cần phải nói, nhưng lỗi không nằm ở game, lỗi ở xã hội và giáo dục, tạo ra cho chúng nó một môi trường nghèo nàn, một tâm hồn trống rỗng, như cái lỗ đen sâu hoắm, nên ngoài những thứ vớ vẩn, nhảm nhí ra, chúng nó không còn biết điều gì khác, riết rồi thành thần kinh, bệnh hoạn và tệ nạn!

toán

Nối tiếp post trước, minh hoạ bằng một screenshot – chụp màn hình. Đến tận bây giờ vẫn còn xài khá nhiều toán, không phải là Toán cao cấp (vi phân, tích phân, đạo hàm, xác suất thống kê, etc…) mà chủ yếu là Toán rời rạc (discrete mathematics) và Thuật toán, thuật giải, thêm một chút Hình, Số và Xác suất thống kê… Chính là vì mấy cái này nên code vẫn còn có vài niềm vui, ngoài những chuyện debug phức tạp, nhức đầu, mệt mỏi và vô số những công việc… trâu bò khác!

Ở một góc nhìn khác, có thể… nhìn code đoán tuổi! Những người viết mã thành khối 80 cột như tôi có nguyên nhân sâu xa từ cái thời còn trên x86 và DOS, lúc đó màn hình text có kích thước 16 (dòng) x 80 (cột), còn màn hình thời bây giờ viết đến 160 cột có khi vẫn chưa xuống hàng! Đến tận giờ tôi vẫn cho rằng bắt đầu từ tầng thấp – low level là một điều nên làm, phần lớn coder bây giờ cái gì cũng biết, công nghệ nào cũng rành, chỉ một điều là không… rành code!

The fallacy of high-level programming

For the last 5 years or so, I’ve stopped writing on technical subjects on this blog. But that doesn’t mean I stop writing completely, in fact, I keep on writing a lot, but keep them to myself instead of posting out. For reasons too numerous to tell, or to be short, just because I’m lazy. Software engineering is a still a relatively – young industry, hence, naivety, untruthfulnesses, deceptions, myths, lies, and dogmas are… countless. In that environment, writings could be controversial and misleading, so I choose to note down my ideas in private.

I started with Turbo-C on DOS, then move on to different dialects of the C language: Watcom C, Borland C++, C++, glibC, Obj-C… For me, the most important thing in programming is… crashes. It crashes right away to tell you that you’ve done something wrong! It crashes when you access a null pointer, it crashes when you use an API the wrong way, it crashes when you allocate an infeasible amount of memory, it crashes when you access a dangling pointer referencing to an object which has gone out of scope, just because you can’t track on the life-cycle of that object. It doesn’t even throw an exception and try going on until the situation is unmanageable. Simply put, there’s NO exception, you’re punished immediately, as soon as you’ve done something wrong!

I strongly advocate the use of ARC for memory management, in fact, I would call it the most brilliant feature of the Obj-C language for the last 25 years or so, ARC makes life much more easier. But I also advocate the use of crashes as a “graceful” way to tell that you’ve done something wrong with the deallocated blocks. It crashes right away when you allocate an unbearable amount of memory so that you would know that your algorithms and data – structures are not efficient enough, and you will need to improve, to do tuning, optimization! For me, modern languages are good and friendly, the down side is that it’s also too friendly to the developers, without punishments, how can the devs’ skills could be improved!

Thus, by the interacting between you – the coder and the computer & compiler combination, the reward – punishment model will help greatly boost the devs’ skills over time, and help producing good code. There’re huge differences between an experienced programmer who write good code, and foresee possibilities of bugs, and a novice one who only try to make it… just run. I really want to emphasize here, that the “reward – punishment” model of programming is what made a good programmer! Also by learning to handle memory problems by yourself give you opportunities to follow and understand the life cycles of objects, of memory blocks, understand the precise flows of code, understand the cost-and-benefits of each coding approaches.

e-ink display

Hiện tại, giá còn hơi chát, nhưng tương lai 1, 2 năm nữa, có một viễn cảnh như thế này: máy tính của coder nên có hai màn hình, một LCD truyền thống, và một e-ink, trong ảnh là màn hình e-ink Dasung, cty trụ sở tại Bắc Kinh, TQ (đã có màn hình kích cỡ 25.3 inch). Tất nhiên, nhiều thao tác máy tính vẫn cần đến màn hình đầy đủ mầu sắc.

Nhưng với một coder – lập trình viên mà nói, một ngày có khi hơn 12 tiếng, phần nhiều chỉ edit text, thì màn hình e-ink hoàn toàn không phát sáng, đúng nghĩa là “giấy trắng mực đen”, có thể bảo vệ mắt tốt hơn rất nhiều, càng tốt hơn nữa nếu có thể hiển thị 256 mức xám! Xứ sở phát minh ra giấy, đương nhiên sẽ làm giấy điện tử thật tốt!