Hoa Ban Không TànCh.40 / 47
Chapter 40

Người dùng không phải thuật toán

Tôi quay lại nhìn cô gái vừa chê chương trình của mình, chắc mẩm cô không hiểu một dòng thuật toán nào trong đó.

Trong căn phòng máy tầng ba nhà D9, không khí đặc quánh mùi nhựa đường cháy dở, mùi vi mạch bị nung nóng suốt từ ca học sáng sớm và tiếng rít ro ro dai dẳng như cưa gỗ của hàng chục chiếc quạt tản nhiệt đã rão trục. Ánh nắng hanh vàng của những ngày đầu đông Hà Nội xiên qua những ô cửa chớp bám bụi xám xịt, rọi rõ từng hạt bụi li ti đang lơ lửng cuộn xoáy trên nóc những chiếc vỏ case máy tính màu cháo lòng. Trên dãy bàn gỗ ép đã bong tróc mép lòi cả lớp dăm gỗ ẩm mục, Bùi Thanh Hà đứng đó.

Cô đứng thẳng lưng, một bên hông tựa hờ vào gờ bàn, hai tay khoanh lại trước ngực trong một tư thế vừa tự chủ vừa xa cách. Chiếc áo sơ mi kẻ ca-rô xanh thẫm của cô phẳng phiu đến từng nếp gấp cổ tay, cổ áo cài kín cúc, sạch sẽ một cách kỳ lạ giữa một không gian sực nức mồ hôi đàn ông, khói thuốc lá vụng trộm ngoài hành lang và sự nhếch nhác thường thấy của dân kỹ thuật sau những đợt nộp bài tập lớn. Nó tương phản tàn nhẫn với chiếc áo phông xám bạc màu loang lổ những vệt mồ hôi muối vặn vẹo sau lưng của tôi—chiếc áo vương vất mùi bã cà phê khét lẹt và mùi dầu mỡ rán ngập từ quán Mùa Gió mà tôi đã mặc liền tù tì hai ngày đêm, chưa kịp giặt giũ kể từ khi rời ca làm tối hôm trước. Đôi mắt Hà sáng, đen láy, hàng mi cong mảnh không hề chớp, nhìn trừng trừng vào góc trên bên phải của chiếc màn hình CRT mười bảy inch đang rung rung những vệt quét ngang, nơi những dòng lệnh xanh lét vừa cuộn qua với tốc độ kỷ lục.

“Cậu bảo sản phẩm này không ai muốn dùng?”

Tôi nghe giọng mình bật ra, khô khốc như tiếng hai mảnh ngói vỡ cọ vào nhau. Từng âm tiết gằn xuống, run rẩy bởi sự tự ái bị chạm nọc của một kẻ vừa trải qua trọn vẹn bốn mươi tám tiếng không chợp mắt. Hai hốc mắt tôi cay xè như bị xát ớt bột, thái dương giật thây lẩy từng hồi theo nhịp đập của quả tim mệt mỏi, và dưới đáy dạ dày, một cơn đau quen thuộc đang cuộn lên từng chặp vì những ngụm nước lã cầm hơi suốt từ rạng sáng ở vòi nước công cộng nhà B7. Tôi đã dồn vào cái màn hình lồi này từng giọt sinh lực cuối cùng, từng phép toán tối ưu rứt ra từ những đêm trắng để kéo cả nhóm thoát khỏi một bàn thua trông thấy trước hạn nộp bài của bộ môn.

“Cậu có nhìn thấy con số không phẩy không ba mươi tám giây kia không?” Tôi chỉ thẳng ngón tay trỏ vào góc dưới màn hình, móng tay còn cáu đen một vệt mực bút bi gai. “Mười nghìn nút mạng giao thông. Hơn bốn mươi nghìn cung nối có trọng số âm và chu trình phức tạp. Tất cả chạy trên một cấu trúc cây đống tối thiểu dựng thẳng trên một mảng phẳng tĩnh. Không cấp phát động một lần nào trong suốt quá trình duyệt đồ thị, không phân mảnh vùng nhớ heap, không rò rỉ dù chỉ là một byte. Các nhóm khác trong phòng này dùng danh sách kề với con trỏ cấp phát động, chạy bài này mất ít nhất ba đến năm giây và nuốt trọn cả chục megabyte RAM, thậm chí máy yếu là đơ cứng hệ điều hành. Về mặt kỹ thuật, nó chạy hoàn hảo. Cậu lấy tư cách gì để bảo nó là đồ bỏ đi?”

Hà không hề giật mình trước thái độ xù lông nhím dữ dằn của tôi. Cô khẽ nghiêng đầu sang một bên, vài sợi tóc mai mềm mại rơi xuống gò má trắng xanh. Khóe môi cô khẽ động đậy, nhưng không phải là một nụ cười mỉa mai trịch thượng, mà là một sự bình thản đến mức lạnh lùng—thứ bình thản của một người đứng trên bờ nhìn xuống một kẻ đang vùng vẫy dưới vũng bùn lầy.

“Tôi không nói thuật toán của cậu sai,” Hà rành rọt đáp. Giọng cô trong trẻo, âm lượng vừa đủ nhưng từng từ rớt xuống mặt bàn phím như những viên bi sắt nảy trên mặt kính. “Tôi đã đọc mã nguồn của cậu từ sáng sớm. Tôi thừa nhận cậu giải bài toán tối ưu đường đi rất giỏi, có khi là giỏi nhất cái khóa năm mươi tám này. Cậu ép từng chu kỳ xung nhịp của vi xử lý, tận dụng tối đa bộ nhớ đệm L1, L2 bằng cách trải phẳng dữ liệu trên mảng một chiều. Rất xuất sắc. Nhưng Nam này, cậu nghĩ người ta dùng phần mềm để làm gì? Để ngồi ngắm cái bảng đen sì với con số không phẩy không ba mươi tám giây của cậu à?”

Cô tiến lên nửa bước, mùi hương xà phòng thơm dịu nhẹ thoảng qua cánh mũi đầy bụi bặm của tôi, hoàn toàn lạc lõng giữa căn phòng máy nồng nặc mùi kim loại rỉ sét.

“Nhìn vào màn hình đi,” Hà chỉ ngón tay thon dài về phía tấm kính CRT đang tỏa hơi nóng hầm hập. “Người dùng phải bấm vào đâu? Con trỏ chuột của hệ thống biến đi đâu mất rồi? Những ký hiệu `-m 0x0F`, `-k 4`, `--mem-static` mà cậu bắt người ta gõ vào dòng lệnh có nghĩa là gì đối với một người chỉ muốn tra đường từ điểm A đến điểm B? Một bác tài xế xe buýt, một cô bán hàng ngoài chợ, hay thậm chí là một sinh viên năm nhất khoa khác mượn máy, họ có hiểu `0x0F` là mặt nạ bit để bật cờ tối ưu hóa không gian trạng thái không? Và nếu họ lỡ tay gõ nhầm một chữ cái, hệ thống của cậu sẽ làm gì?”

Không đợi tôi kịp mở miệng biện minh, Hà đưa bàn tay trắng trẻo ra trước mặt tôi. Những ngón tay thon mảnh của cô gõ một phím bất kỳ trên bàn phím cơ cũ kỹ đầy bụi—phím chữ `z` vô thưởng vô phạt—rồi dứt khoát ấn phím Enter.

*Cạch.*

Màn hình CRT lập tức giật nảy lên một cái, quét ngang một vệt sáng trắng chói gắt, rồi nhả ra vỏn vẹn một dòng chữ đỏ quạch đơn độc ở góc trên:

`Error 0x7B: Invalid argument syntax. Process terminated.`

Ngay sau đó, toàn bộ tiến trình tính toán tự động đóng phụt lại trong chớp mắt. Màn hình tối sầm lại trong nửa giây trước khi trả về dấu nhắc lệnh trơ khốc của hệ điều hành DOS: `C:\TC\BIN> _`.

“Đấy,” Hà khoanh tay lại, mắt nhìn xoáy vào đồng tử vằn đỏ của tôi. “Người ta chỉ nhập sai một ký tự không mong muốn, chương trình của cậu lập tức văng ra ngoài không một lời giải thích. Không báo sai ở tham số nào, không cho phép sửa, không lưu lại dữ liệu mười nghìn nút mà người ta vừa cất công nạp vào từ tệp văn bản. Cậu coi người dùng là những cỗ máy biết đọc mã máy, hay cậu nghĩ ai bước vào phòng máy này cũng phải mang một bộ não chứa sẵn cấu trúc bộ nhớ bên trong đầu cậu thì mới có quyền chạm vào phần mềm?”

Máu trong người tôi rần rần dồn hết lên mang tai, nóng bừng và rát buốt. Cả cơ thể tôi run lên bần bật vì một sự uất nghẹn nghẽn cứng nơi cổ họng. Những ký ức nặng nề của chuỗi ngày vừa qua như một đàn ong vỡ tổ ùa về cắn xé tâm can tôi: đêm trắng buốt lạnh ở phòng tự học tầng bốn nhà B7 gió lùa thấu xương; nỗi nhục nhã ê chề khi nhận điểm không tròn trĩnh trong bài kiểm tra mười lăm phút môn Toán giải tích chỉ vì ngủ gục trên bàn sau ca rửa bát thâu đêm; ánh nhìn giễu cợt của gã khách trung niên mặc áo vest bóng bẩy ở quán cà phê Mùa Gió khi tôi làm đổ vỡ tách trà sen vì run tay...

Tất cả những đắng cay, nhọc nhằn ấy dường như bị cô gái thành phố này thu nhỏ lại thành một lỗi ngớ ngẩn trên bàn phím. Tôi chỉ thấy những lời Hà nói là chuyện hình thức vụn vặt, là thói vẽ vời rỗng tuếch của những kẻ sinh ra trong nhung lụa, có sẵn máy tính cá nhân để nghịch ngợm từ thuở bé, chưa từng bao giờ phải đối mặt với bài toán sinh tử về tài nguyên phần cứng eo hẹp.

Ở trường huyện vùng cao hay những buổi chiều muộn ở bản Nà Ban xa xôi, khi tôi cùng thầy Dũng đánh vật với chiếc máy tính phế liệu chắp vá từng thanh RAM một trăm hai mươi tám megabyte bị rỉ chân cắm, cái cốt lõi duy nhất để sinh tồn là làm sao cho dòng lệnh biên dịch qua được, cỗ máy không bị treo cứng và thuật toán trả về đúng đáp số của đề bài. Kết quả là chân lý. Thuật toán đúng là sự sống còn. Mọi thứ vỏ bọc bên ngoài—giao diện đồ họa bóng bẩy, những cái nút bấm bo tròn màu mè, những câu thông báo dài dòng dỗ dành người dùng lười biếng—chỉ là thứ trang trí rẻ tiền, phù phiếm của những kẻ không biết bản chất của máy tính là những phép toán luận lý trần trụi.

“Đây là bài tập lớn môn Kỹ thuật lập trình của Khoa Công nghệ Thông tin, không phải môn đồ họa ứng dụng của bên Mỹ thuật công nghiệp!” Tôi đanh giọng, lồng ngực phập phồng sau lớp áo mỏng, hai nắm đấm siết chặt giấu sau đùi. “Yêu cầu của đề bài thầy Tuấn giao là tìm đường đi ngắn nhất với độ phức tạp tính toán và độ phức tạp không gian ở mức tối thiểu. Thầy giáo chấm điểm dựa trên thuật toán, dựa trên độ chính xác tuyệt đối của kết quả và thời gian chiếm dụng CPU, không ai rảnh rỗi đi chấm xem cái nút bấm có đẹp mắt hay câu thông báo lỗi có ngọt ngào như lời ru hay không! Người có học, người biết dùng công cụ kỹ thuật thì chỉ cần đọc tài liệu năm phút là hiểu các cờ tham số. Còn loại người không chịu đọc tài liệu, không chịu hiểu nguyên lý vận hành của công cụ mà đòi nhảy vào dùng, rồi gõ bừa bãi làm sập hệ thống, thì lỗi là do sự dốt nát của họ, không phải do chương trình của tôi!”

“Thôi nào, hai người bớt nóng đi. Cả phòng đang nhìn kìa.”

Một bàn tay thô ráp, ấm áp đặt mạnh lên vai tôi. Phong từ nãy đến giờ đứng lặng bên mép bàn máy số hai, hai tay đút trong túi chiếc quần bò sờn gối, lúc này mới vội vàng lách người bước chen vào giữa tôi và Hà.

Phong là dân Nam Định, tính tình xởi lởi, khéo léo và luôn là chất keo làm dịu đi những va chạm nảy lửa giữa cái vẻ thô lậu, cộc cằn của một đứa miền núi như tôi với thế giới bên ngoài. Cậu ta liếc nhìn tôi, thấy rõ những đường gân xanh đang giật giật hai bên thái dương và đôi mắt vằn tia máu đỏ ngầu vì kiệt sức; rồi cậu quay sang nhìn vẻ điềm tĩnh cương quyết, không chút nhượng bộ của Hà.

“Cãi nhau bằng mồm thế này thì đến tối mịt cũng chẳng ngã ngũ được,” Phong chép miệng, lắc đầu quầy quậy, bàn tay vỗ bồm bộp lên bả vai tôi như muốn dùng trọng lượng cơ thể để ghìm cơn thịnh nộ đang chực trào ra khỏi lồng ngực tôi. “Hà nói có cái lý của người tiếp cận sản phẩm từ góc độ sử dụng thực tế. Còn Nam thì đang sống chết bảo vệ cái lõi kỹ thuật đỉnh cao mà cả đêm qua ông ấy suýt đột quỵ trong phòng tự học để viết cho xong. Thầy Tuấn còn khoảng hai mươi lăm, ba mươi phút nữa mới từ văn phòng khoa xuống nghiệm thu phòng máy. Thay vì đứng đây gân cổ cãi xem cái lõi quan trọng hơn hay cái vỏ quan trọng hơn, chi bằng chúng ta làm một bài thử nghiệm mù nho nhỏ đi.”

Tôi trừng mắt nhìn Phong, chân mày cau chặt lại thành một búi: “Thử nghiệm cái gì nữa? Mã nguồn tôi đã tự tay kiểm tra ba lần trên tập dữ liệu chuẩn của đề thi Olympic Tin học, không có bất kỳ lỗi logic nào. Từng bước dịch chuyển con trỏ bộ nhớ đều chuẩn xác một trăm phần trăm.”

“Tôi biết, tôi biết cái đầu của ông kinh khủng thế nào rồi,” Phong giơ hai tay lên làm động tác xoa dịu, rồi quay ngoắt sang phía Hà. “Hà này, cậu bảo phần mềm này người bình thường không thể dùng nổi đúng không? Bây giờ cậu kéo thử vài bạn đang ngồi ở các dãy máy bên cạnh sang đây. Để họ tự ngồi vào vị trí này, tự bật chương trình lên, tự thao tác từ đầu đến cuối để giải quyết một bài toán cụ thể mà Nam không được mở miệng can thiệp hay chỉ dẫn dù chỉ nửa lời. Nếu họ dùng được một cách suôn sẻ và ra kết quả, Hà phải rút lại câu chê ban nãy và thừa nhận Nam làm đúng. Còn nếu người ta kẹt lại thật, nếu họ lúng túng không biết bấm vào đâu như lời cậu nói, thì Nam cũng phải hạ cái tôi xuống, ngồi nghe xem người ta kẹt ở chỗ nào. Được không?”

Hà nhướng nhẹ đôi mày thanh tú, ánh mắt đen sâu thẳm quét qua mặt tôi một lượt rồi dừng lại ở Phong, không hề có một nét nao núng:

“Tôi đồng ý. Nhưng không phải chỉ một người để bảo là ngẫu nhiên hay thiên vị. Hãy để ba người thử sức: một bạn nam nhóm bên cạnh đang làm đề tài quản lý, một bạn nữ lớp bên đang đứng chờ máy trống để thực hành bài tập C cơ bản, và người thứ ba là chính tôi. Tôi sẽ thao tác như một người dùng chưa từng nhìn thấy mã nguồn của cậu.”

Tôi cười khẩy một tiếng khô khốc trong họng, lùi lại phía sau một bước, kéo lê chiếc ghế xoay bọc da rách nát để lộ cả lớp mút xốp màu vàng ố ra sau lưng. Cơn kiêu hãnh của một kẻ làm chủ những thuật toán hóc búa nhất bùng lên dữ dội. Trong đầu tôi lúc đó, logic của chương trình rõ ràng, rành mạch và đẹp đẽ như một định lý hình học không gian: bước thứ nhất là chỉ định đường dẫn tệp dữ liệu thông qua cờ `-i`, bước thứ hai là cấu hình cờ thuật toán `-alg` với giá trị `0` cho Dijkstra cải tiến hoặc `1` cho Bellman-Ford trên đống, bước thứ ba là truyền mã định danh nút nguồn `-src` và nút đích `-dst`. Mọi thứ đều được sắp xếp theo đúng quy chuẩn dòng lệnh của hệ điều hành Unix cổ điển, tối ưu hóa đến từng chu kỳ xung nhịp. Một phần mềm đỉnh cao, giải quyết bài toán giao thông phức tạp với tốc độ tính bằng phần nghìn giây, tự thân nó đã là một tượng đài bằng thép. Nó không cần bất kỳ ai phải vuốt ve hay dỗ dành thì mới chịu tỏa sáng.

“Được thôi,” tôi khoanh tay trước ngực, cằm hất lên đầy thách thức. “Cứ để họ thử. Nhưng tôi nói trước, tôi sẽ đứng khoanh tay ở đây và không bấm hộ một phím nào cả. Để xem người ta dốt do không chịu đọc tài liệu, hay do phần mềm của tôi có vấn đề.”

Hà không đáp lại lời mỉa mai của tôi. Cô xoay người, tà áo sơ mi khẽ bay lên theo nhịp bước dứt khoát. Cô đi thẳng sang dãy bàn máy tính số bốn đối diện, nơi có mấy sinh viên đang chụm đầu gõ lạch cạch bên những màn hình hiển thị giao diện đồ họa Turbo C màu xanh da trời. Chỉ vài phút sau, cô quay trở lại, đi sau là Lâm—một thành viên của nhóm làm đề tài phần mềm quản lý thư viện trường học—và Mai, một nữ sinh viên lớp Công nghệ Thông tin 2 với mái tóc buộc đuôi ngựa, trên tay ôm khư khư xấp giáo trình Lập trình C căn bản dày cộp của thầy Phạm Văn Ất.

“Ngồi vào đây đi Lâm,” Hà kéo chiếc ghế gỗ đối diện màn hình CRT, chỉ tay vào cỗ máy tính đang để ngỏ dấu nhắc lệnh hệ thống. “Cậu thử chạy chương trình này và tìm đường đi ngắn nhất từ trạm xe buýt Đại học Bách khoa sang bến xe Gia Lâm xem mất bao lâu.”

Lâm kéo ghế ngồi xuống, vẻ mặt hăng hái và tự tin ra mặt. Dù sao cậu ta cũng là sinh viên Bách khoa chính cống, đã vượt qua kỳ thi đầu vào khốc liệt và vừa cày cuốc cả kỳ học qua các môn kiến trúc máy tính lẫn kỹ thuật lập trình. Lâm bẻ khớp ngón tay kêu *răng rắc*, liếc nhìn tôi gật đầu một cái chào hỏi xã giao, rồi nhìn vào màn hình. Cậu ta gõ dòng lệnh thực thi chương trình mà Phong vừa tạo sẵn trong thư mục hiện hành: `./router`.

*Enter.*

Màn hình CRT chớp nhẹ một cái, toàn bộ giao diện dòng lệnh của hệ thống bị xóa sạch, thay thế bằng một khoảng đen sâu thẳm, trơ trụi đến rợn ngườI, chỉ có đúng hai dòng chữ đơn độc hiện ra ở góc trên cùng bên trái:

```text === NETWORK SOLVER v1.0 === Config: > _ ```

Dấu gạch dưới nhấp nháy liên hồi theo từng nhịp: *tắt, sáng, tắt, sáng*. Ngoài ra, không còn bất cứ thứ gì khác. Không có danh sách các trạm dừng, không có dòng gợi ý cú pháp, không có một thực đơn lựa chọn nào được bung ra.

Lâm khựng lại. Bàn tay đang đặt trên bàn phím của cậu ta bỗng lơ lửng giữa không trung. Cậu ta chớp chớp mắt, ghé sát mặt vào lớp kính màn hình lồi để tìm kiếm xem có dòng chữ ẩn nào không, rồi quay đầu lại nhìn tôi với ánh mắt dò hỏi:

“Nhập gì ở đây hả Nam? Nhập tên điểm xuất phát à?”

Cơ mặt tôi giật nhẹ. Tôi cắn chặt môi dưới, hai hàm răng nghiến chặt vào nhau đến mức quai hàm bạnh ra, kiên quyết đứng bất động như một pho tượng đá mục. Lời giao kèo khi nãy như một chiếc đinh sắt đóng chặt miệng tôi lại: không được can thiệp, không được giải thích.

Thấy tôi im lặng nhìn lên trần nhà, Lâm ngập ngừng một thoáng, rồi nhún vai. Cậu ta đưa ngón tay gõ chậm rãi từng ký tự vào dấu nhắc lệnh: `BachKhoa`.

Ngón tay cậu ta ấn xuống phím Enter.

*Títtttttt!*

Một tiếng còi bíp chói tai, gắt gỏng phát ra từ chiếc loa thạch anh nhỏ xíu gắn sâu trong thùng máy sắt vụn bên dưới gầm bàn. Âm thanh đanh thép ấy vang dội khắp góc phòng thực hành khiến mấy người ở dãy bàn bên cạnh cũng phải giật mình ngó sang. Ngay lập tức, bên dưới chữ `BachKhoa`, một dòng thông báo cụt lủn hiện ra bằng màu xám lạnh ngắt:

`ERR: 0x02 - Expected flag prefix.`

Dấu nhắc lệnh lại nhảy xuống dòng tiếp theo, tiếp tục nhấp nháy trơ trẽn: `> _`.

Nụ cười tự tin trên khuôn mặt Lâm biến mất, thay vào đó là sự bối rối lộ rõ trên vầng trán bắt đầu rịn mồ hôi: “Cờ tiền tố là cái gì? Sao nó không hiện danh sách các trạm xe buýt để chọn? Hay là phải gõ lệnh trợ giúp?”

Cậu ta lẩm bẩm, gõ vội: `help`.

*Títtttttt!*

Chiếc loa thùng máy lại trừng phạt cậu ta bằng một tiếng rú đanh thép không chút thương xót:

`ERR: 0x02 - Expected flag prefix.`

“Cái quái gì thế này?” Lâm bắt đầu mất bình tĩnh. Hai tai cậu ta đỏ ửng lên vì ngượng ngùng trước ánh mắt quan sát của mọi người xung quanh. Cậu ta gõ liên tiếp: dấu hỏi chấm `?`, rồi gõ chữ `menu`, rồi gõ con số `1`.

Mỗi một lần ngón tay Lâm dằn mạnh xuống phím Enter, cỗ máy lại phát ra một tiếng kêu the thé giận dữ, và màn hình trôi tuột dần xuống phía dưới, để lại một chuỗi những dòng mã lỗi hex giống hệt nhau: `ERR: 0x02`, `ERR: 0x02`, `ERR: 0x02`. Chúng như những cái tát vô hình giáng liên tiếp vào không gian yên ắng của căn phòng.

Tôi đứng nhìn, lồng ngực thắt lại từng cơn như có ai đang bóp nghẹt khí quản. Bên trong màng nhĩ tôi, một tiếng gào thét câm lặng đang gầm rú: *Thằng ngốc này! Phải gõ `-src 101`! Mã số của trạm trung chuyển Bách khoa là 101, đã được tôi định nghĩa rõ ràng trong tệp dữ liệu cấu hình đồ thị `nodes.dat` rồi cơ mà! Ai đời lại đi gõ nguyên cả một chuỗi ký tự chữ cái không dấu vào một hệ thống tính toán ma trận bao giờ? Nó phải xử lý theo định dạng số nguyên bốn byte để tối ưu hóa việc truy cập mảng chứ!*

Nhưng Lâm làm sao biết được cái tệp `nodes.dat` quái quỷ ấy nằm ở xó xỉnh nào trong ổ đĩa, và làm sao cậu ta biết được quy ước gán mã trạm dừng của tôi là gì khi mà toàn bộ giao diện phần mềm chẳng thèm bố thí lấy một dòng hướng dẫn?

Sau gần ba phút toát mồ hôi hột vật lộn trong vô vọng với những tiếng còi báo lỗi chói óc, Lâm buông thõng hai tay khỏi bàn phím, tựa lưng ra sau thành ghế gỗ, thở dài thườn thượt với vẻ mặt bực bội không thèm giấu giếm:

“Chịu chết thôi Nam ơi. Phần mềm của ông bị lỗi vòng lặp hay bị đơ bàn phím rồi. Gõ cái gì nó cũng chửi bíp bíp vào mặt. Chẳng biết bắt đầu từ đâu, cũng chẳng biết cái hệ thống này nó cần cái giống gì để chạy nữa. Dùng ức chế kinh khủng.”

Cậu ta đứng phắt dậy, xua tay lia lịa rồi lách người đi thẳng về chỗ cũ, không thèm nhìn lại màn hình lấy một lần.

Hà khẽ quay sang nhìn tôi, ánh mắt không hề chớp. Cô không nói một lời mỉa mai nào, chỉ quay sang cô bạn sinh viên đang đứng nép bên cạnh: “Đến lượt cậu đấy Mai. Cứ bình tĩnh thao tác.”

Mai khẽ cắn môi, rụt rè kéo chiếc ghế gỗ ngồi xuống. Nhìn thấy sự thất bại thảm hại của Lâm, cô gái tỏ ra cẩn trọng hơn hẳn. Mai mở xấp giáo trình đặt lên đùi, đưa mắt nhìn kỹ từng dòng chữ trên màn hình đen sì, ngón tay mân mê mép bàn phím nhựa cáu bẩn rồi ngước lên nhìn tôi, giọng ngập ngừng:

“Nam ơi... nhóm cậu có tệp văn bản hướng dẫn sử dụng hay tài liệu đặc tả tham số không? Cho tớ mượn đọc một phút được không?”

Một cảm giác thẹn thùng xen lẫn cay đắng xộc lên mũi tôi. Tôi cúi người xuống gầm bàn, luồn tay vào chiếc ba lô con cóc bằng vải dù sờn rách đặt dưới sàn gạch hoa bám bụi, lôi ra một tờ giấy A4 đã bị gấp làm tư. Mép giấy đã quăn queo, sờn rách và lem nhem những vết ngón tay dính dầu xích xe đạp. Tôi đặt cạch tờ giấy lên mặt bàn gỗ ép bên cạnh bàn phím.

Đó là tờ giấy nháp duy nhất tôi dùng để vạch ra sơ đồ cấu trúc dữ liệu và các cờ tham số trong đêm trắng lạnh buốt ở phòng tự học B7. Trên mặt giấy chi chít những dòng chữ viết tay nguệch ngoạc bằng bút bi xanh, xen lẫn những công thức toán rời rạc, những ký hiệu ma trận kề, sơ đồ cây nhị phân và hàng loạt quy ước viết tắt rối rắm như mật mã chiến tranh mà ngoài tôi ra, có lẽ chỉ có trời mới hiểu nổi.

Mai cầm tờ giấy nháp lên bằng hai đầu ngón tay, xoay ngang rồi lại xoay dọc, đôi mày lá liễu chau chặt lại:

“Cái này... cái này toàn là công thức giải tích với mã giả của thuật toán Dijkstra mà Nam? Chỗ nào chỉ cho người dùng biết phải gõ câu lệnh như thế nào để tra cứu đường đi?”

Tôi nuốt khan một ngụm nước bọt đắng ngắt, không thể kìm chế được nữa, ngón tay run run chỉ thẳng vào một góc giấy dưới cùng bên phải, nơi có một dòng chữ bé tí xíu bị gạch xóa hai ba lần:

“Ở góc đó. Chỗ ghi `-src [id] -dst [id] -alg [0|1]` đấy.”

Mai nheo mắt đọc từng ký tự tí hon: “`-src [id]`... Vậy... vậy mã trạm của bến xe Gia Lâm là bao nhiêu hả Nam?”

“Trong tệp dữ liệu,” tôi đáp cộc lốc, mắt lảng tránh ánh nhìn trong trẻo của cô bạn.

“Tệp dữ liệu mở ra bằng cách nào?” Mai tròn xoe mắt, giọng đầy hoang mang. “Phần mềm của cậu có nút bấm hay câu lệnh nào để in danh sách các trạm dừng ra xem không? Hay là tớ phải mở một cửa sổ soạn thảo khác, tìm cái tệp văn bản thô nặng mấy nghìn dòng để tự dùng mắt thường quét tìm xem mã của bến xe Gia Lâm là số mấy?”

Căn phòng máy dường như rơi vào một khoảng lặng nặng nề đến nghẹt thở. Tiếng rít của những chiếc quạt tản nhiệt cũ kỹ vẫn đều đặn cào xé không khí, nhưng trong tai tôi, nó biến thành một thứ âm thanh u u nhức nhối, như tiếng gió rít qua những khe nứt trên vách nứa nhà tôi ở Nà Ban mỗi mùa đông về.

Mai thở dài một cái thật khẽ, quyết định không hỏi thêm nữa. Cô cố gắng làm theo đúng những gì ghi trên tờ giấy nháp nhàu nát của tôi. Đôi ngón tay nhỏ nhắn của cô gõ cẩn thận từng ký tự một: `-src 101`. Nhưng vì chiếc bàn phím máy tính trong phòng thực hành đã quá cũ, phím cách (spacebar) bị kẹt lò xo và rão đệm cao su, nên khi chuyển sang tham số tiếp theo, ngón tay cái của cô vô tình nhấn cách hai lần liên tiếp trước khi gõ tiếp `-dst 205`.

Chuỗi nhập vào trên màn hình hiện lên rõ ràng: `-src 101 -dst 205`.

Mai thở phào một cái, ngước nhìn tôi như muốn tìm kiếm một sự xác nhận, rồi ngập ngừng ấn phím Enter.

Bên trong hàm `parse_arguments()` mà tôi đã viết bằng ngôn ngữ C thuần túy trong cơn sốt mê mệt đêm qua, tôi đã dùng một mảng ký tự tĩnh cố định và một vòng lặp kiểm tra con trỏ thô sơ để bóc tách chuỗi. Bộ phân tích cú pháp tự chế ấy được thiết kế dựa trên một giả định duy nhất: người dùng là một cỗ máy hoàn hảo, luôn luôn chỉ nhập đúng một dấu cách duy nhất giữa các cờ tham số. Khi con trỏ duyệt chuỗi chạm phải dấu cách thứ hai bất thường, nó không tìm thấy tiền tố dấu gạch ngang mong đợi, lập tức nhảy vọt ra khỏi phạm vi cấp phát của mảng đệm và cố gắng truy xuất vào một vùng nhớ bất hợp pháp.

*Cạch.*

Màn hình CRT không thèm phát ra một tiếng bíp nào nữa. Nó chớp lóe lên một dải sáng trắng ma quái, toàn bộ giao diện đen sì lập tức biến mất không để lại dấu vết.

Chương trình sụp đổ tan tành. Người dùng bị ném thô bạo trở lại màn hình dòng lệnh câm lặng của hệ thống với một dòng thông báo lỗi kinh hoàng của trình biên dịch:

`Segmentation fault (core dumped)`

Mai giật nảy mình như vừa chạm tay vào một ổ điện hở. Cô rụt phắt hai tay lại, lùi chiếc ghế xoay ra phía sau nửa mét, khuôn mặt nhỏ nhắn tái mét vì hoảng sợ:

“Ôi trời ơi... máy... máy tính bị cháy bộ nhớ rồi à? Tớ làm hỏng chương trình của nhóm các cậu rồi phải không? Tớ xin lỗi, tớ chỉ bấm thừa một dấu cách thôi mà...”

“Không sao đâu Mai, máy tính không hỏng được đâu,” Phong vội vàng bước tới, giọng nói trầm ấm đầy kiên nhẫn vang lên để trấn an cô gái đang run rẩy. “Chỉ là phần mềm bị xung đột bộ nhớ tạm thời khi đọc chuỗi thôi. Không có gì cháy cả. Cảm ơn cậu nhiều nhé, cậu sang dãy máy bên kia làm bài tập đi kẻo hết giờ thực hành.”

Mai đứng dậy như được tha bổng. Cô ôm chặt xấp giáo trình vào ngực, cúi đầu chào rồi vội vã rảo bước rời khỏi góc bàn máy của chúng tôi, ánh mắt vẫn còn vương vất vẻ e ngại và sợ hãi—thứ cảm giác của một người vừa vô tình bước chân vào một bãi mìn mà bất cứ một cử động sơ sẩy nào cũng sẽ dẫn đến sự hủy diệt tàn bạo.

Hai người thử nghiệm. Hai sinh viên Bách khoa chính quy. Và cả hai đều đầu hàng vô điều kiện ngay từ những giây phút đầu tiên tiếp xúc với chương trình.

Chưa một ai, tuyệt nhiên chưa một ai chạm được đến cái lõi thuật toán Min-Heap tối ưu tuyệt hảo mà tôi đã đánh đổi cả giấc ngủ, cả bữa ăn lót dạ và sức lực cạn kiệt của mình để thai nghén. Cái kỳ quan kỹ thuật mà tôi hằng tôn thờ, cái tốc độ không phẩy không ba mươi tám giây có thể nghiền nát hàng vạn cung nối đồ thị trong chớp mắt, rốt cuộc vẫn nằm im lìm, câm lặng và bất động phía sau một bức tường thành bằng đá đen sì, gai góc và đầy thù địch.

Hà không nói một lời nào. Cô kéo chiếc ghế gỗ mà Mai vừa bỏ lại, ngồi xuống đối diện với chiếc màn hình CRT vẫn đang trơ trơ dòng chữ báo lỗi vỡ phân vùng bộ nhớ. Cô không nhìn vào màn hình nữa. Đôi mắt đen láy, sâu thẳm và sáng quắc của cô từ từ ngước lên, ghim chặt lấy ánh nhìn của tôi.

Trong đôi mắt ấy, tôi không tìm thấy sự đắc thắng tầm thường của một kẻ vừa chứng minh được mình đúng trong một cuộc tranh cãi vặt vãnh. Ở đó chỉ có một sự lạnh lùng, thẳng thắn đến mức tàn nhẫn—thứ tàn nhẫn buốt giá của một sự thật trần trụi vừa bị lột trần ra giữa thanh thiên bạch nhật.

“Họ không chịu đọc kỹ hướng dẫn,” tôi nghe thấy giọng mình run rẩy, một phản xạ tự vệ vụng về, thảm hại và yếu ớt bật ra từ đáy sâu của sự tự ái bị dồn vào chân tường. “Nếu họ chịu khó để tâm nhìn vào tờ giấy ghi chú... Nếu họ cẩn thận hơn một chút khi gõ phím, không bấm thừa dấu cách một cách vô ý thức... Một công cụ kỹ thuật phức tạp đòi hỏi người vận hành nó phải có trình độ và sự tập trung tương xứng. Máy móc không sinh ra để dung dưỡng và chiều chuộng sự cẩu thả của con người!”

“Nam,” Hà ngắt lời tôi. Giọng cô không hề cao lên, nhưng từng âm tiết buông ra nặng trịch như những quả tạ gang rơi xuống sàn tàu. “Cậu đang đổ lỗi cho người khác chỉ vì họ không có khả năng đọc được những suy nghĩ rối rắm trong đầu cậu đấy à?”

Tôi nghẹn ứ nơi cuống họng. Hai bàn tay nắm chặt giấu sau lưng run lên bần bật, móng tay cắm sâu vào da thịt lòng bàn tay đau nhói, nhưng nỗi đau thể xác ấy chẳng thấm tháp gì so với cảm giác cay đắng đang trào dâng trong lồng ngực.

“Một người bình thường khi bước chân lên một chiếc xe buýt, mục đích duy nhất của họ là gì?” Hà hỏi, ngón tay cô gõ nhẹ từng nhịp đều đặn lên mặt bàn gỗ. “Họ chỉ cần biết chuyến xe đó có đưa họ về nhà an toàn, đúng giờ và đúng tuyến đường hay không. Họ không có nhu cầu, và quan trọng hơn là họ hoàn toàn không có nghĩa vụ phải hiểu xem khối động cơ diesel bốn kỳ bên dưới gầm xe hoạt động theo chu trình nhiệt động lực học nào, áp suất phun dầu của kim phun là bao nhiêu bar, hay bu-gi đánh lửa sớm bao nhiêu độ trước điểm chết trên.”

Cô đứng thẳng dậy, vóc dáng mảnh khảnh nhưng tư thế thẳng thắn khiến cô toát lên một uy lực áp đảo kỳ lạ giữa căn phòng máy nồng nặc mùi kim loại cũ kỹ này.

“Cậu đang bắt một người muốn đi xe buýt phải thuộc làu sơ đồ cấu tạo cơ khí của chiếc xe thì mới cho phép họ bước chân lên cửa. Nếu họ lỡ bước hụt một bậc thang vì bậc quá cao, cậu lập tức đá văng họ xuống lòng đường đầy bụi bặm. Cậu gọi một cỗ máy như thế là một cỗ xe hoàn hảo sao? Cậu gọi đó là đỉnh cao của kỹ thuật sao?”

“Đó là hai phạm trù hoàn toàn khác nhau!” Tôi gằn giọng cãi lại, cổ họng rát bỏng như nuốt phải than hồng. “Xe buýt là phương tiện công cộng phổ thông, còn đây là phần mềm chuyên dụng phục vụ tính toán kỹ thuật!”

“Chẳng có gì khác nhau về bản chất cả,” Hà lắc đầu, ánh mắt cô không hề dời khỏi khuôn mặt hốc hác của tôi. “Bất kỳ một công cụ nào trên cõi đời này sinh ra cũng là để phục vụ con người. Nếu một phần mềm được viết ra mà chỉ có duy nhất một mình người tạo ra nó mới biết cách dùng, nếu chỉ có người hiểu rõ từng địa chỉ con trỏ, từng cấu trúc ô nhớ bên trong mới không làm cho nó phát nổ và sụp đổ, thì cái phần mềm đó chưa bao giờ là một sản phẩm hoàn thiện. Nó chỉ là một món đồ chơi cá nhân đắt đỏ, ích kỷ và hoàn toàn vô dụng đối với toàn bộ phần còn lại của xã hội.”

Hà dừng lại một nhịp dài. Ánh mắt cô chậm rãi lướt qua chiếc áo phông bạc màu nhăn nhúm của tôi, lướt qua đôi dép tổ ong sứt mũi cáu bẩn dưới chân tôi, rồi dừng lại thật lâu trên đôi bàn tay thô ráp, chai sần đầy những vết xước—đôi bàn tay của một đứa trẻ lớn lên từ những mùa phát rẫy, cuốc đất trồng ngô trên những triền đá tai mèo sắc lẹm ở Nà Ban.

Trong suốt cuộc tranh cãi gay gắt đến nghẹt thở này, Hà chưa từng buông một lời nào xúc phạm đến hoàn cảnh bần hàn của tôi. Cô không nhìn tôi bằng ánh mắt thương hại trịch thượng hay khinh miệt như gã khách giàu có ở quán cà phê Mùa Gió. Cô cũng không hề phủ nhận năng lực thuật toán xuất sắc của tôi—ngay từ câu đầu tiên, cô đã thừa nhận tôi là người tối ưu mảng phẳng và giải thuật đồ thị giỏi nhất cái khóa học này.

Hà đối xử với tôi như một người đồng nghiệp kỹ thuật hoàn toàn ngang hàng, sòng phẳng và không khoan nhượng. Và chính vì cái thái độ bình đẳng, không thương hại ấy, từng lời phê bình của cô mới cắm sâu vào lòng kiêu hãnh của tôi đau đớn đến thế. Cô không hề bẻ gãy thuật toán của tôi; cô chỉ tàn nhẫn xé toạc tấm rèm che mắt tôi, bắt tôi phải nhìn thẳng vào sự thật: sự ngạo mạn kỹ thuật của tôi vừa tạo ra một thứ quái thai vô dụng đối với những con người bằng xương bằng thịt.

“Cậu nghĩ những đêm thức trắng của cậu là hy sinh vì khoa học, là đang tạo ra giá trị to lớn,” Hà nói khẽ, giọng cô chùng xuống nhưng sức nặng của nó như đóng đinh vào không gian ngột ngạt của phòng máy D9. “Nhưng nếu người ta buộc phải bỏ cuộc ngay từ ngưỡng cửa đầu tiên, nếu không một ai có thể chạm được vào kết quả tính toán của cậu... thì tất cả những dòng mã tối ưu kia, tất cả những giọt mồ hôi và những đêm không ngủ kia của cậu... rốt cuộc là để phục vụ ai ngoài cái tôi của chính cậu?”

Không gian phòng máy chìm vào một sự im lặng tuyệt đối, chỉ còn lại tiếng rít khô khốc của cánh quạt tản nhiệt sau lưng những khối sắt xám xịt. Lời nói của Hà không tan biến vào hư không; nó dội thẳng vào lồng ngực tôi, đập liên hồi lên hai bên màng tang đang giật giật từng cơn vì thiếu ngủ.

Tôi đứng sững sờ giữa lối đi hẹp. Một phần trong tôi—phần tăm tối, cố chấp và đầy mặc cảm của một đứa trẻ nghèo khó luôn phải gồng mình lên để không bị người đời coi thường—vẫn muốn gầm lên cãi lại. Tôi muốn bảo rằng người dùng phải tự nâng cao dân trí, rằng người viết mã không sinh ra để dọn dẹp sự bất cẩn của thiên hạ. Nhưng hình ảnh ngón tay run rẩy rụt lại của Mai, ánh mắt tức tối và bất lực của Lâm khi buông tay khỏi bàn phím, tất cả đều là những bằng chứng thép rành rành không thể chối cãi.

Phong bước thêm một bước, vỗ thật mạnh lên vai tôi một lần nữa. Lần này, cái vỗ vai mang trọn sự thấu hiểu và sẻ chia của một người bạn cùng phòng đã chứng kiến tôi vật lộn với từng dòng mã suốt những đêm dài đói lả.

“Hà nói đúng đấy Nam,” Phong khẽ nói, chất giọng trầm ấm xứ đồng bằng phá tan bầu không khí đông cứng. “Cậu viết thuật toán giỏi, cái đó cả phòng 314 này ai cũng biết và ai cũng nể. Không có cái lõi đống phẳng chạy trên mảng tĩnh của cậu, bài tập này chắc chắn trượt thẳng cẳng ngay từ vòng quét hiệu năng tự động của bộ môn. Nhưng chúng ta làm phần mềm là để mô phỏng một hệ thống giao thông thực tế cho người dân đi lại, chứ đâu phải viết một đoạn mã thi đấu chấm tự động trên máy chủ đóng kín cổng cao tường? Cậu đã làm được cái phần khó nhất, cái phần linh hồn của cỗ máy rồi. Bây giờ, chỉ cần mở cho nó một cánh cửa để con người bước vào nữa thôi. Đừng để công sức bao đêm của cậu đổ sông đổ biển chỉ vì một chút bướng bỉnh.”

Phong nhìn sang chiếc đồng hồ đeo tay cũ kỹ: “Còn đúng mười hai phút nữa là đến giờ thầy Tuấn nghiệm thu. Vẫn còn kịp nếu cậu muốn sửa.”

Tôi đứng lặng đi trong ba giây dài như cả thế kỷ. Một cơn gió hanh heo lùa qua ô cửa chớp bám bụi, mang theo mùi hoa sữa nồng nặc cuối mùa từ phía sân trường hắt vào phòng máy. Tôi nhìn xuống đôi bàn tay mình, những ngón tay khẳng khiu, chai sạn vì lao động chân tay từ nhỏ, nhưng cũng là những ngón tay có thể điều khiển hàng vạn bóng bán dẫn chuyển trạng thái chỉ bằng những dòng mã logic.

Tôi không nói một lời nào, lẳng lặng bước tới, kéo chiếc ghế xoay bọc đệm rách ngồi phịch xuống trước bàn máy. Tôi không nhìn Hà, nhưng chiếc lưng áo ướt lạnh mồ hôi của tôi đã thôi không còn gồng cứng lên nữa. Tôi vươn tay, nhấn tổ hợp phím tắt quen thuộc trên bàn phím: mở lại tệp mã nguồn `main.c` trong trình soạn thảo.

“Hà,” tôi cất tiếng, giọng vẫn trầm đục và khô khốc vì khát nước, nhưng không còn vằn vện những nét thù hằn gay gắt như trước. “Ngồi xuống đây. Chỉ cho tôi xem người dùng bình thường cần nhìn thấy những gì đầu tiên.”

Khóe mắt Hà khẽ lay động. Cô không để lộ một nét cười đắc thắng nào, chỉ lẳng lặng kéo chiếc ghế gỗ sát lại gần bàn máy, mở cuốn sổ tay bìa cứng đặt lên đùi, cây bút bi kẹp sẵn trên những ngón tay thon thả.

“Trước hết là hàm bóc tách tham số `parse_arguments()`,” Hà chỉ đầu bút bi vào màn hình. “Xóa bỏ toàn bộ những lệnh ngắt đột ngột `exit(1)`. Bất kỳ chuỗi nào người dùng nhập vào, cậu phải viết một hàm phụ để tự động cắt tỉa toàn bộ các khoảng trắng thừa ở đầu chuỗi, cuối chuỗi và giữa các tham số. Người ta có thể lỡ tay ấn hai, ba hay mười dấu cách, hệ thống của cậu vẫn phải gom chúng lại thành một dấu phân cách duy nhất.”

Những ngón tay thô ráp của tôi bắt đầu lướt trên bàn phím. Tiếng gõ phím lạch cạch vang lên giòn giã, dứt khoát và chuẩn xác như tiếng máy khâu. Tôi xóa phăng đoạn mã kiểm tra điều kiện ngặt nghèo cũ. Tôi viết một vòng lặp `while` nhỏ gọn, dùng hai con trỏ trượt để chuẩn hóa chuỗi ký tự đầu vào ngay trên bộ đệm tĩnh.

“Còn thông báo lỗi?” Tôi hỏi, mắt không rời màn hình.

“Đừng bao giờ in ra những mã hex vô nghĩa như `0x02` hay `0x7B`,” Hà nói, giọng điềm tĩnh và rõ ràng. “Hãy in ra một câu tiếng Việt không dấu dễ hiểu: `Lỗi: Tham số không hợp lệ`. Và quan trọng nhất là phải đưa ra gợi ý sửa sai ngay bên dưới. Ví dụ: `Cú pháp đúng phải là: -src [Mã_Trạm] -dst [Mã_Trạm]`.”

Tôi gõ thoăn thoắt. Từng dòng lệnh mới hiện ra trên nền đen:

```c void trim_whitespace(char *str) { char *src = str, *dst = str; while (*src == ' ') src++; while (*src) { if (*src == ' ' && *(src + 1) == ' ') { src++; continue; } *dst++ = *src++; } *dst = '\0'; if (dst > str && *(dst - 1) == ' ') *(dst - 1) = '\0'; } ```

“Tiếp theo là màn hình khởi động,” Hà nói tiếp. “Xóa cái dấu nhắc lệnh đen sì trơ trọi đó đi. Hãy in ra một cái bảng tóm tắt danh mục mười trạm trung chuyển lớn nhất nội thành Hà Nội kèm theo mã số của chúng. Đừng bắt người ta phải mò mẫm mở tệp dữ liệu ra tra cứu bằng mắt.”

Tôi cắn chặt môi dưới, viết thêm một hàm hiển thị bảng điều khiển ngắn gọn. Thay vì chỉ hiển thị một dấu nhắc lệnh nhấp nháy đầy đe dọa, tôi tạo ra một khung viền đơn giản bằng các ký tự mã ASCII, bên trong liệt kê rõ ràng: `101: DH Bach Khoa | 102: DH Quoc Gia | 205: BX Gia Lam | 302: BX My Dinh | 401: BX Giap Bat`.

“Đoạn nạp dữ liệu từ đĩa cứng,” giọng Hà bất chợt vang lên sát bên tai tôi. Hơi thở nhẹ của cô thoảng qua vành tai nóng bừng của tôi. “Trong hàm `load_graph_data()`, nếu tệp `nodes.dat` bị thiếu, bị hỏng hoặc bị ai đó vô tình đổi tên, chương trình của cậu sẽ xử lý thế nào?”

Ngón tay tôi khựng lại trên phím bấm. Tôi nhìn chằm chằm vào dòng lệnh kiểm tra tệp:

```c FILE *fp = fopen("nodes.dat", "rb"); if (!fp) return NULL; ```

“Nó trả về con trỏ `NULL`,” tôi đáp cộc lốc. “Và sau đó hàm dựng đống sẽ nhận một con trỏ rỗng.”

“Và rồi con trỏ rỗng đó sẽ bị giải phóng bộ nhớ hoặc truy xuất ô nhớ trái phép ở địa chỉ `0x00000000`, hệ điều hành sẽ lập tức ném ra lỗi `Segmentation fault` như Mai vừa gặp phải,” Hà nói dứt khoát. “Đừng chỉ trả về giá trị rỗng. Hãy bẫy lỗi ngay tại đó: in ra thông báo tệp dữ liệu không tồn tại, sau đó tự động chuyển hướng sử dụng một mảng dữ liệu dự phòng có sẵn trong bộ nhớ tĩnh để chương trình không bao giờ bị sập phụt một cách đột ngột. Một chương trình chạy chậm hơn một chút nhưng ổn định, vẫn tốt hơn gấp ngàn lần một chương trình chạy siêu tốc nhưng có thể lăn ra chết bất đắc kỳ tử bất cứ lúc nào.”

Tôi nghiến chặt quai hàm. Lời góp ý của Hà chuẩn xác và sắc bén đến mức tôi không thể tìm ra dù chỉ là một kẽ hở nhỏ nhất để phản biện. Cô gái này không hề can thiệp vào cách tôi cân bằng cây đống nhị phân hay cách tôi trải phẳng mảng dữ liệu để tối ưu hóa bộ nhớ đệm CPU—những thứ thuộc về chuyên môn thuật toán sâu xa. Nhưng cô có một trực giác nhạy bén phi thường về sự an toàn của toàn bộ hệ thống khi va chạm với thế giới thực tế đầy rẫy sự bất cẩn của con người.

Tôi không nói thêm một lời, dồn hết sự tập trung cao độ vào mười đầu ngón tay. Tôi gõ thêm khối lệnh kiểm tra mã lỗi tệp tin, nạp mảng dữ liệu mặc định và bẫy toàn bộ các trường hợp ngoại lệ có thể xảy ra.

“Còn ba phút nữa!” Phong đứng ở mép cửa hành lang thò đầu vào giục, giọng khẩn trương. “Thầy Tuấn đã bước qua khúc quanh chiếu nghỉ cầu thang tầng ba rồi!”

“Xong ngay đây!”

Tôi gõ tổ hợp phím lưu tệp, rồi nhanh như cắt gõ dòng lệnh biên dịch tối ưu hóa trực tiếp từ giao diện điều khiển:

`gcc -O2 -Wall main.c -o router`

Dòng nhắc lệnh chớp nhẹ một cái trong nửa giây rồi trả về trạng thái sẵn sàng. Không một dòng cảnh báo (warning), không một lỗi cú pháp nào phát sinh.

Tôi thở hắt ra một hơi dài, lồng ngực như vừa trút bỏ được một tảng đá ngàn cân. Tôi đẩy chiếc bàn phím cơ dính bụi về phía trước mặt Hà:

“Xong rồi. Cậu thử đi.”

Hà không chần chừ một giây nào. Cô ngồi thẳng lưng, đưa hai bàn tay đặt lên bàn phím. Đôi mắt đen láy của cô ánh lên một vẻ tập trung cao độ. Hà gõ: `./router` rồi nhấn Enter.

Màn hình CRT không còn chớp tắt tối om như trước nữa. Một bảng giao diện văn bản ngay ngắn, sáng sủa và gọn gàng hiện ra:

```text ====================================================== HE THONG DINH TUYEN XE BUYT TOI UU v1.1 ====================================================== Cac tram trung chuyen chinh: [101] DH Bach Khoa [205] Ben xe Gia Lam [102] DH Quoc Gia [302] Ben xe My Dinh [103] DH Xay Dung [401] Ben xe Giap Bat

Nhap lenh tim duong (VD: -src 101 -dst 205) Hoac go 'help' de xem huong dan chi tiet. ------------------------------------------------------ > _ ```

Hà khẽ nhếch mép. Cô không gõ lệnh chuẩn ngay, mà cố tình nhập vào một chuỗi sai lệch đầy ác ý với hàng loạt khoảng trắng thừa thãi:

` BachKhoa -> GiaLam `

Nhấn Enter.

Không có tiếng còi báo lỗi chói tai nào rú lên từ thùng máy nữa. Không có màn hình sụp đổ nào xuất hiện. Ngay bên dưới dòng chữ của Hà, một dòng chữ màu vàng nhạt hiện ra một cách nhã nhặn:

`Goi y: Ban vua nhap ten tram bang chu. Vui long su dung ma so tram tuong ung.` `Vi du tim duong tu Bach Khoa sang Gia Lam: nhap '-src 101 -dst 205'` `> _`

Hà khẽ nhướng đôi mày thanh tú lên một chút. Cô không tìm thêm được kẽ hở nào nữa, bèn đưa tay gõ lại đúng dòng lệnh gợi ý:

`-src 101 -dst 205`

*Enter.*

Trong một khoảnh khắc ngắn ngủi đến mức mắt thường khó lòng nhận biết—đúng không phẩy không ba mươi tám giây—thuật toán Min-Heap trên mảng phẳng của tôi gầm vang bên trong các cổng luận lý của CPU. Hàng vạn phép so sánh trọng số hoàn tất trong chớp mắt. Toàn bộ lộ trình tối ưu lập tức hiển thị rành mạch từng dòng trên màn hình:

```text ================ KET QUA DINH TUYEN ================ Thoi gian tinh toan: 0.038 giay | Bo nho: 1.2 MB Lo trinh toi uu (Qua 12 tram trung gian): [101] DH Bach Khoa -> [108] Dai Co Viet -> [115] Tran Khat Chan -> [122] De Nguyen Khoai -> [140] Cau Vinh Tuy -> ... -> [205] BX Gia Lam Tong chieu dai quang duong: 11.4 km Thoi gian di chuyen uoc tinh: 28 phut ==================================================== ```

Phong đứng bên cạnh vỗ mạnh hai bàn tay vào nhau đánh *đét* một cái, reo lên khẽ khàng nhưng đầy phấn khích:

“Tuyệt vời! Đẹp như mơ! Thế này thì thầy Tuấn có khó tính đến mấy cũng chẳng thể nào bẻ hoe được một điểm nào nữa!”

Hà ngồi yên lặng, nhìn chằm chằm vào bảng kết quả chi tiết đang sáng rực trên màn hình CRT trong vài giây. Cô buông lỏng những ngón tay khỏi bàn phím, chậm rãi quay đầu sang nhìn tôi. Trong đôi mắt đen sâu thẳm của cô, nét sắc lạnh, gay gắt ban nãy đã hoàn toàn biến mất, thay vào đó là một vẻ điềm tĩnh, công bằng và một sự thừa nhận kín đáo nhưng rõ ràng.

Tôi nhìn xuống đôi bàn tay thô ráp của mình, cảm thấy cuống họng khô khốc. Cơn giận dữ và nỗi tự ái cộc cằn của một thằng con trai nghèo khó từng khiến tôi muốn quay lưng lại với cả thế giới. Nhưng lúc này, đứng trước cái màn hình hiển thị kết quả vừa nhanh, vừa chuẩn xác, lại vừa dễ hiểu đến từng chi tiết, tôi nhận ra một sự thật hiển nhiên: nếu không có nhát dao phê bình tàn nhẫn của Hà mười lăm phút trước, cỗ máy của tôi dù có chạy nhanh đến đâu cũng sẽ mãi mãi chỉ là một khối sắt vụn câm lặng, cô độc và vô dụng.

“Cảm ơn,” tôi cất tiếng, giọng nói rất khẽ, gần như chìm nghỉm vào tiếng ồn ào của căn phòng máy.

Hà đứng dậy, cẩn thận gập cuốn sổ tay lại rồi cho vào chiếc cặp vải đeo chéo. Cô nhìn thẳng vào mắt tôi, khóe môi khẽ cong lên một thoáng—đó không phải là một nụ cười xã giao màu mè, mà là cái gật đầu công nhận sòng phẳng giữa hai người thợ kỹ thuật vừa cùng nhau hiệu chỉnh xong một cỗ máy hỏng hóc.

“Cảm ơn sau cũng chưa muộn,” Hà nói, giọng cô đã lấy lại vẻ bình thản thường nhật. “Miễn là từ nay về sau, trước khi bắt người khác phải chịu đựng những gì cậu viết ra, hãy dành lấy một phút để nhìn xem họ thực sự cần cái gì đã. Thuật toán của cậu rất cừ, Nam ạ. Đừng bao giờ để nó chết gí sau một cái màn hình đen sì chỉ vì sự kiêu ngạo của mình.”

Nói đoạn, Hà xoay người bước ra phía cửa lớn, vừa vặn lúc thầy Tuấn ôm một tập giáo trình dày cộp bước vào phòng máy D9.

Buổi nghiệm thu bài tập lớn của nhóm chúng tôi diễn ra suôn sẻ ngoài sức tưởng tượng. Thầy Tuấn—vị giảng viên nổi tiếng khắt khe và hay bắt bẻ từng dấu chấm phẩy của khoa—đã đứng trầm ngâm trước màn hình của nhóm tôi gần mười phút. Thầy liên tục thử nghiệm các ca kiểm thử biên (edge cases) hóc búa nhất: nhập sai cú pháp, ngắt kết nối tệp dữ liệu, ép bộ nhớ chạy ở mức tải tối đa. Nhưng cỗ máy không hề sụp đổ dù chỉ một lần.

Thầy gật đầu lia lịa, cặp kính lão trễ xuống tận sống mũi, đặc biệt khen ngợi nhóm không chỉ có năng lực tối ưu hóa cấu trúc dữ liệu ở tầng thấp cực kỳ vững vàng, mà còn có tư duy thiết kế trải nghiệm người dùng và cơ chế bẫy lỗi ngoại lệ chu đáo—điều mà hầu hết các nhóm sinh viên năm thứ nhất mải mê chạy theo thuật toán đều hoàn toàn bỏ quên. Nhóm chúng tôi nhận điểm mười tuyệt đối cho phần thực hành kỹ thuật.

***

Khi buổi thực hành kết thúc, phòng máy D9 dần dần vãn người. Tiếng bàn ghế xô lệch chan chát và tiếng bước chân rầm rập của hàng trăm sinh viên túa ra hành lang để kịp giờ cơm trưa ký túc xá xua tan đi cái ngột ngạt thường ngày.

Tôi nán lại sau cùng để tắt máy, cẩn thận rút chiếc USB vỏ nhựa màu xanh của Phong ra khỏi cổng cắm sau thùng máy, rồi cúi người cuộn gọn sợi dây cáp nguồn bám đầy bụi đen. Khi đứng thẳng dậy, một cơn đau dạ dày dữ dội lại âm ỉ nhói lên nơi hạ sườn trái, nhắc nhở tôi rằng suốt từ rạng sáng đến giờ, bụng tôi vẫn hoàn toàn trống rỗng, chỉ có vài ngụm nước lã cầm hơi ở vòi nước công cộng nhà B7.

“Nam này,” tiếng Phong từ ngoài cửa hành lang vọng vào. Cậu ta bước nhanh về phía tôi, trên tay cầm một tờ giấy A4 màu trắng vừa được bóc vội từ bảng tin của khoa đặt ngay cạnh cầu thang tầng ba. “Nhìn cái này đi. Vừa mới dán lên lúc nãy xong.”

Tôi ngẩng đầu lên, đón lấy tờ giấy từ tay Phong. Tờ giấy còn phẳng phiu, thơm nồng mùi mực in ruy-băng của chiếc máy in kim cũ:

**THÔNG BÁO VỀ CUỘC THI LẬP TRÌNH ỨNG DỤNG SINH VIÊN K58** **NĂM HỌC 2013 – 2014** *Chủ đề: Xây dựng giải pháp công nghệ phục vụ đời sống và kết nối cộng đồng.* *Quy chế: Các đội thi bao gồm đúng 03 thành viên. Danh sách phân bổ nhóm do Hội đồng chuyên môn của Khoa chỉ định ngẫu nhiên dựa trên kết quả bài tập lớn giai đoạn một, nhằm bảo đảm sự cân bằng tối ưu giữa năng lực thuật toán nền tảng, thiết kế hạ tầng dữ liệu và xây dựng trải nghiệm người dùng.*

Ánh mắt tôi lướt nhanh xuống bảng phân bổ danh sách các đội thi được in chi tiết ở trang đính kèm phía sau. Và ở dòng thứ bảy, mực in kim dập nổi từng nét chữ sắc cạnh, rõ mồn một từng cái tên:

**ĐỘI THI SỐ 07:** 1. **Nguyễn Văn Nam** – Lớp KHMT-01 *(Phụ trách Lõi thuật toán & Tối ưu hiệu năng)* 2. **Vũ Đức Phong** – Lớp CNTT-02 *(Phụ trách Hạ tầng hệ thống & Cơ sở dữ liệu)* 3. **Bùi Thanh Hà** – Lớp HTTT-01 *(Phụ trách Thiết kế trải nghiệm & Giao diện người dùng)*

Tôi đứng chết trân tại chỗ, những ngón tay thô ráp bất giác siết chặt lấy mép tờ giấy A4 phẳng phiu khiến nó hơi nhăn nhúm lại.

Qua ô cửa sổ vỡ kính ngoài hành lang tầng ba, bóng lưng mảnh khảnh của Bùi Thanh Hà trong chiếc áo sơ mi kẻ ca-rô xanh thẫm vừa bước xuống những bậc tam cấp cuối cùng, hòa vào dòng người đông đúc trên con đường rợp bóng xà cừ cổ thụ ngập tràn nắng hanh vàng của khuôn viên Bách khoa.

Một cảm giác lạ lùng, dữ dội và hoàn toàn mới mẻ dâng lên cuồn cuộn trong lồng ngực tôi. Đó là sự căng thẳng tột độ trước một thử thách lớn hơn gấp bội, là nỗi bất an mơ hồ của một đứa trẻ quen sống thu mình trong vỏ ốc cô độc, nhưng đồng thời, nó cũng nhen nhóm lên một ngọn lửa rực cháy mà suốt những năm tháng cắm mặt vào nương ngô khô cằn hay cặm cụi bên cỗ máy tính phế liệu ở chái nhà Nà Ban tôi chưa từng một lần cảm nhận được.

Một cuộc chiến mới thực sự vừa mở ra trước mắt. Và lần này, tôi biết chắc chắn rằng mình sẽ không thể tiếp tục một mình một ngựa trốn chạy vào thế giới của những dòng mã câm lặng được nữa.

How was this chapter?Ratings help Readeep recommend better stories