Điều gì biến phát triển phần mềm thành một ngành kỹ thuật?
Không phải chức danh hay độ khó của bài toán, mà chính việc áp dụng phương pháp kỹ thuật — đo lường, ước lượng, thử nghiệm và cải tiến có hệ thống — mới là yếu tố định hình nên kỹ thuật phần mềm. Bài viết phân tích nguồn gốc khái niệm này từ hội nghị NATO năm 1968 và bàn về tương lai của nghề trước làn sóng AI.

Điều gì biến phát triển phần mềm thành một ngành kỹ thuật?
Lập trình viên làm việc với mã nguồn trên màn hình máy tính
Người làm ra phần mềm được gọi bằng rất nhiều cái tên: developer, programmer, coder, và ở một tầm khác là software engineer. Mỗi danh xưng gợi lên một cảm nhận khác nhau về mức độ chuyên nghiệp, năng lực toán học và tầm quan trọng của công việc.
Tại một số tỉnh của Canada, những chức danh như "software engineer" hay "computer engineer" trên nguyên tắc được dành riêng cho người đã được cơ quan quản lý kỹ thuật cấp phép hành nghề. Điều này cho thấy chức danh kỹ sư gắn với một chuẩn mực nghề nghiệp được công nhận, chứ không chỉ là cách gọi cho oai.
Nhưng nếu nhiều người cùng chia sẻ cảm nhận rằng kỹ sư phần mềm khác biệt với lập trình viên thông thường, thì đáng để hỏi vì sao. Nếu phát triển phần mềm hiển nhiên là một dạng kỹ thuật, chức danh "software engineer" đã chẳng có gì đặc biệt. Vậy cảm nhận ấy đến từ đâu, và điều gì thực sự biến phát triển phần mềm thành kỹ thuật?
Kỹ thuật là gì, và phần mềm liên quan thế nào?
Không có định nghĩa duy nhất cho "kỹ thuật", nhưng nhìn chung đây là lĩnh vực giải quyết vấn đề một cách có hệ thống bằng cách áp dụng kiến thức toán học và khoa học trong những ràng buộc nhất định, nhằm đáp ứng nhu cầu của con người.
UNESCO và Viện Hàn lâm Quốc gia Hoa Kỳ đưa ra những định nghĩa tương tự: kỹ thuật là lĩnh vực thực hành gắn với việc phát triển, tiếp nhận và ứng dụng tri thức khoa học – kỹ thuật, đồng thời là một phương pháp giải quyết vấn đề gọi là thiết kế trong điều kiện ràng buộc.
Nỗ lực trao cho phát triển phần mềm nền tảng hệ thống giống các ngành kỹ thuật khác đã có từ thuở sơ khai của ngành máy tính. Hội nghị Phần mềm NATO năm 1968 thường được xem là điểm khởi đầu của kỹ thuật phần mềm. Mối lo xuyên suốt tại hội nghị là phần mềm ngày càng phức tạp khi quy mô và tầm quan trọng tăng nhanh — hiện tượng được gọi là khủng hoảng phần mềm.
Cụm từ "software engineering" được chọn một cách có chủ đích nhằm gây tranh luận, ngụ ý rằng việc sản xuất phần mềm cần dựa trên những nền tảng lý thuyết và kỷ luật thực hành vốn đã truyền thống trong các ngành kỹ thuật lâu đời.
Nhà sử học Thomas Haigh nhìn thấy ý nghĩa lớn hơn trong cuộc tranh luận diễn ra trước hội nghị, bên trong Nhóm Công tác 2.1 của IFIP — nơi đang phát triển phiên bản kế nhiệm ALGOL 60. Quan điểm thịnh hành khi đó cho rằng có thể biểu đạt những chương trình phức tạp bằng cách kết hợp một số ít khái niệm cơ bản. Những người phản đối hướng đi của ALGOL 68, trong đó có Edsger Dijkstra, cho rằng phát triển phần mềm cần trở thành một hoạt động chặt chẽ và có thể kiểm soát hơn.
Cần lưu ý rằng những tranh luận này cách khá xa công việc của các lập trình viên ứng dụng thời bấy giờ. Phần lớn người dự hội nghị là nhà nghiên cứu, còn phần lớn ứng dụng khi đó là phần mềm tài chính, kế toán và nhân sự viết bằng COBOL. Dù vậy, lập trình viên được đào tạo ngày nay vẫn chịu ảnh hưởng gián tiếp, đôi khi trực tiếp, từ cuộc tranh luận ALGOL 68 và hội nghị NATO — chẳng hạn khi bạn được dạy tránh dùng goto trong C, hay tiếp xúc với lập trình hướng đối tượng, lập trình hàm.
Áp dụng phương pháp kỹ thuật vào phần mềm
Sau nhiều thập kỷ nỗ lực định vị phát triển phần mềm như một ngành kỹ thuật, tài liệu SWEBOK (Software Engineering Body of Knowledge) dẫn định nghĩa của IEEE:
Kỹ thuật là "việc áp dụng một cách tiếp cận có hệ thống, có kỷ luật và có thể định lượng vào các cấu trúc, máy móc, sản phẩm, hệ thống hoặc quy trình". Kỹ thuật phần mềm là "việc áp dụng cách tiếp cận có hệ thống, có kỷ luật và có thể định lượng vào phát triển, vận hành và bảo trì phần mềm; tức là áp dụng kỹ thuật vào phần mềm".
Theo định nghĩa này, điều biến phát triển phần mềm thành kỹ thuật chính là việc áp dụng phương pháp kỹ thuật vào nó. Phương pháp kỹ thuật là một quy trình trong đó kỹ sư chọn một trong nhiều giải pháp khả thi theo những tiêu chí nhất định, triển khai rồi theo dõi kết quả.
Quy trình này không nhất thiết tuần tự, nhưng phải có tính lặp. Kiến thức thu được ở bất kỳ giai đoạn nào cũng có thể ảnh hưởng tới giai đoạn trước, tự nhiên dẫn tới một vòng lặp mới. Vì các quyết định kỹ thuật dựa trên ước lượng, chất lượng quyết định phụ thuộc vào chất lượng ước lượng. Kỹ sư phải đối chiếu ước lượng với kết quả thực tế để tạo vòng phản hồi, nhờ đó tinh chỉnh kỹ năng ước lượng và đưa ra quyết định tốt hơn.
Cụ thể hóa trực giác bằng ngôn ngữ kỹ thuật
Hãy lấy một ví dụ thực tế. Đội vận hành báo cho một lập trình viên làm nền tảng thương mại điện tử rằng trang chi tiết sản phẩm quá chậm và yêu cầu cải thiện thời gian tải.
Một lập trình viên hiểu rõ hệ thống có thể lập tức nghĩ ra giải pháp. Điều đó không nhất thiết dẫn tới quyết định tồi. Nhưng rất khó giải thích vì sao quyết định ấy hợp lý hơn các phương án khác, cần cải thiện bao nhiêu mới gọi là thành công, hay nó thực sự tạo khác biệt bao nhiêu cho người dùng.
Phương pháp kỹ thuật bắt đầu bằng việc hiểu chính xác vấn đề thực sự. "Quá chậm" có thể mang nhiều nghĩa, nên bước đầu tiên là đo hiệu năng của những trang cần cải thiện. Chỉ số gần đây cho thấy FCP p75 của các trang này là 2.700ms, trong khi ngưỡng khuyến nghị cho trải nghiệm tốt là 1.800ms hoặc thấp hơn — đây là mục tiêu hợp lý.
Lập trình viên phân tích trace và phát hiện máy chủ SSR dành phần lớn thời gian render để chờ API chi tiết sản phẩm phản hồi. API này có độ trễ p95 là 1.000ms, và những request chậm mất 800ms để chờ truy vấn đọc cơ sở dữ liệu. Vấn đề giờ được định nghĩa lại: truy vấn cơ sở dữ liệu là điểm nghẽn độ trễ trong các truy vấn đọc sản phẩm.
Có nhiều giải pháp: thêm lớp cache trong bộ nhớ, cải thiện truy vấn hoặc chỉ mục, truy vấn read replica, hay render toàn bộ trang tĩnh và phục vụ qua CDN. Mỗi giải pháp có điểm mạnh, điểm yếu và đánh đổi riêng.
Phân tích lưu lượng cho thấy 5% sản phẩm phổ biến nhất chiếm khoảng 90% request tra cứu, và mô phỏng TTL cache gợi ý rằng thêm Redis có thể đạt tỷ lệ cache hit trên 95%. Vì đọc Redis chỉ mất vài mili-giây, một cache hit có thể đưa độ trễ xuống khoảng 200ms.
Lập trình viên chọn xây dựng lớp cache trong bộ nhớ bằng Redis. Sau khi triển khai, chỉ số cho thấy cache hit đạt 65%, độ trễ p95 của API là 850ms, FCP p75 là 2.000ms — cải thiện khiêm tốn. Điều tra nguyên nhân chênh lệch giữa thực tế và ước lượng cho thấy thông tin sản phẩm phụ thuộc dữ liệu cá nhân hóa, khiến số lượng khóa cache cao hơn dự kiến.
Lập trình viên thiết kế lại chiến lược cache: lưu thông tin tĩnh của sản phẩm vào cache toàn cục, tách riêng phần dữ liệu cá nhân hóa. Kết quả: cache hit đạt 97%, độ trễ p95 của API còn 200ms, FCP p75 còn 1.400ms.
Toàn bộ quá trình này — từ đo lường vấn đề, so sánh giải pháp, ước lượng kết quả đến so sánh thực tế với ước lượng để cải tiến — chính là phương pháp kỹ thuật.
Khi nào cần đến phương pháp kỹ thuật?
Nhìn theo cách này, phát triển phần mềm rõ ràng có khía cạnh kỹ thuật. Lý do nó vẫn khác biệt so với các ngành kỹ thuật khác có thể là vì vẫn có thể tạo ra phần mềm chạy tạm ổn mà không cần tuân theo định nghĩa kỹ thuật.
Lập trình viên có thể thiết kế không theo phương pháp hệ thống, viết mã không có kỷ luật, và tạo ra phần mềm bằng quy trình không thể định lượng. Vì phần mềm chạy được vẫn ra đời bất kể quy trình phát triển, phương pháp kỹ thuật dễ bị xem nhẹ trên thực tế.
Ngành phần mềm đã thay đổi chóng mặt trong thời gian ngắn. Ngay cả những nền tảng cơ bản của khoa học máy tính cũng thay đổi nhanh hơn nhiều so với các định luật tự nhiên mà những ngành kỹ thuật khác dựa vào. Nhiều tổ chức phát triển phần mềm vì thế tập trung vào tốc độ thay vì tuân theo các nguyên tắc vững chắc, khiến chất lượng phần mềm dễ bị coi là mối quan tâm thứ yếu.
Có những góc nhìn khác về phát triển phần mềm đáng lưu ý:
- Peter Naur cho rằng mục tiêu thực sự của lập trình là xây dựng một "lý thuyết" trong đầu lập trình viên, chứ không phải tạo ra sản phẩm gọi là chương trình. Mất đi lập trình viên cũng đồng nghĩa mất đi chương trình.
- Sherry Turkle và Seymour Papert gọi những lập trình viên làm ra phần mềm chạy được trước, rồi sửa và quan sát lặp đi lặp lại, là bricoleurs — những người giải quyết vấn đề bằng bất cứ công cụ nào trong tầm tay.
- Software gardening coi phần mềm như một sinh thể sống và chấp nhận tính bất định của nó, với lập trình viên là người chăm sóc khu vườn phần mềm bằng trực giác và tinh thần sở hữu.
Dù có nhiều góc nhìn khác nhau, các tổ chức phát triển phần mềm vẫn cần phương pháp kỹ thuật. Nó không đảm bảo phần mềm hoàn hảo, nhưng ít nhất nâng cao mức sàn chất lượng.
Những lập trình viên giàu kinh nghiệm, đã xây dựng "lý thuyết" trong đầu, không thể gắn bó với tổ chức mãi mãi. Cũng không phải ai cũng có thể là bricoleur với trực giác phi thường hay người làm vườn với tinh thần sở hữu cao. Tổ chức phải tạo ra phần mềm chất lượng cao một cách nhất quán bất chấp năng lực không đồng đều của từng cá nhân.
Sức mạnh của phương pháp kỹ thuật nằm ở chỗ: ngay cả người có ít tài năng bẩm sinh cũng có thể nâng cao cơ hội đưa ra quyết định tốt bằng cách tuân theo một quy trình được thiết kế tốt.
Kết luận: kỹ thuật phần mềm trước làn sóng AI
Điều đủ tiêu chuẩn để phát triển phần mềm được coi là kỹ thuật không liên quan tới độ khó của bài toán hay bằng cấp của kỹ sư. Chính việc áp dụng phương pháp kỹ thuật vào phát triển phần mềm làm nên tính kỹ thuật. Kỹ sư ước lượng, thử nghiệm, đo lường, tái lập kết quả, cải tiến và lặp lại.
Khoảng sáu mươi năm sau những nỗ lực đầu tiên đưa phương pháp kỹ thuật vào phát triển phần mềm, ngành này đang đối mặt với những lời tiên tri về sự diệt vong của chính nó, với lập luận rằng trí tuệ nhân tạo khiến cách tiếp cận kỹ thuật truyền thống không còn hữu ích.
Nếu trí tuệ nhân tạo ở đây nghĩa là các mô hình ngôn ngữ lớn (LLM), kỹ thuật phần mềm có lẽ sẽ không dễ kết thúc đến vậy. Điều những lời tiên tri ấy thực sự báo trước là sự kết thúc của người kỹ sư phần mềm.
Hiện tại, con người vẫn mang lại lợi ích thiết thực khi dẫn dắt việc áp dụng phương pháp kỹ thuật:
- Con người phải cung cấp cho AI bối cảnh về môi trường, gồm cả ràng buộc kỹ thuật lẫn yêu cầu cụ thể. Đưa cho AI yêu cầu kinh doanh trừu tượng, nó sẽ tạo ra kết quả trừu tượng. Sau khi vật lộn với AI để tinh chỉnh đầu ra không xử lý đúng các trường hợp biên, bạn sẽ nhận ra rằng mã nguồn mới là đặc tả rõ ràng nhất của yêu cầu kinh doanh.
- Chất lượng đầu ra của AI không đồng đều và chưa đủ độ tin cậy. Hạn chế đặc biệt rõ trong các hệ thống cũ (brownfield), nơi kỹ sư phần mềm con người phải can thiệp để đo lường và xác minh đầu ra có đáp ứng yêu cầu và ràng buộc hay không.
Vì những lý do này, kỹ thuật phần mềm do con người dẫn dắt vẫn cung cấp một khuôn khổ định hướng cho cả con người lẫn AI cùng sản xuất phần mềm tốt hơn trong thực tế.
Trong thời kỳ chuyển giao, ai cũng có thể đưa ra một lời tiên tri nghe hợp lý. Có lẽ một ngày AI sẽ tự nhận diện ràng buộc thực tế, tự định nghĩa yêu cầu và tạo ra phần mềm hộp đen giải quyết vấn đề hoàn hảo. Ben Shneiderman mô tả những hệ thống AI đạt mức tự động hóa cao hơn nhưng trao cho con người nhiều quyền kiểm soát hơn là hệ thống RST (Reliable, Safe & Trustworthy — đáng tin cậy, an toàn và đáng tín nhiệm).
Nếu chúng ta chỉ tập trung tự động hóa phát triển phần mềm, để rồi phần mềm được tạo ra mà không có con người kiểm soát, không ai chịu trách nhiệm về nó, và trong thâm tâm ta đã mong muốn điều đó, thì lời tiên tri về sự diệt vong sẽ trở thành lời tiên tri tự ứng nghiệm.
Ít nhất là cho tới hiện tại, các kỹ sư phần mềm vẫn có thể tự quyết định tương lai của chính mình.


