Lời kêu gọi phần mềm tinh gọn năm 2024
(spectrum.ieee.org)- Trong thực tế hiện nay, ngay cả những chức năng đơn giản cũng kéo theo hàng nghìn phụ thuộc và hàng chục triệu dòng mã, khiến bản thân sự phình to của phần mềm trở thành một nguyên nhân lớn gây ra lỗ hổng bảo mật
- Bảo mật không chỉ phụ thuộc vào mật độ lỗi mà còn phụ thuộc vào tổng lượng mã mà kẻ tấn công có thể chạm tới; bề mặt tấn công rộng một cách không cần thiết có thể dẫn tới xâm nhập thực sự
- Hệ sinh thái Electron JS, Node.js, Docker image và các phụ thuộc npm·PyPI làm mờ đi lượng mã được triển khai và nguồn gốc của chúng; ngay cả một ứng dụng mở cửa gara cũng có thể liên quan tới hơn 50 triệu dòng mã đang hoạt động
- Rust, sanitizer và fuzzer giúp nâng cao chất lượng mã, nhưng các thất bại logic trong thiết kế như tự động thực thi mã nằm trong tài liệu thì khó có thể ngăn chặn chỉ bằng việc loại bỏ bug
- Trifecta cung cấp tính năng chia sẻ ảnh chỉ với 1.600 dòng mã mới, khoảng 5 phụ thuộc cốt lõi và tổng dung lượng 3MB, cho thấy vẫn có thể xây dựng phần mềm hiện đại với lượng mã và phụ thuộc hạn chế
Tình trạng bảo mật phần mềm đã trở nên nguy hiểm
- Tình hình bảo mật phần mềm gần đây là rất tệ
- Trong một năm qua đã xảy ra các vụ xâm nhập nghiêm trọng ở những phần mềm tiêu chuẩn trong ngành như Ivanti, MOVEit, Outlook, Confluence, Barracuda Email Security Gateway, Citrix NetScaler ADC·NetScaler Gateway
- Ngay cả những công ty có nhiều nguồn lực như Apple và Google cũng mắc sai lầm bảo mật làm khách hàng gặp rủi ro
- Vì nhận thức rằng phần mềm đã trở nên quá nguy hiểm, lời khuyên phổ biến là không tự chạy trực tiếp mà hãy giao cho X as a service hoặc đám mây
- Giả định rằng đám mây có thể khiến phần mềm dễ tổn thương trở nên đáng tin cậy cũng đang lung lay
- Nền tảng email của Microsoft đã bị tấn công, bao gồm cả email chính phủ mật
- Vẫn còn những lo ngại về bảo mật của đám mây Azure
- Okta đã chịu vụ xâm nhập thứ hai trong vòng 2 năm, và sau đó các vụ hack nhắm vào người dùng Okta tiếp tục diễn ra một cách đáng ngờ
- EU đang thúc đẩy ba văn bản lập pháp để xử lý bảo mật phần mềm
- NIS2: áp dụng cho các dịch vụ quan trọng
- Cyber Resilience Act: áp dụng cho gần như mọi phần mềm thương mại và thiết bị điện tử
- Product Liability Directive: mở rộng phạm vi trách nhiệm sang cả phần mềm
Lỗ hổng phát sinh từ cả chất lượng mã lẫn số lượng mã
- Bảo mật phần mềm phụ thuộc vào hai trục
- Mật độ vấn đề bảo mật trong mã nguồn
- Lượng mã mà hacker có thể tiếp cận
- Càng nhiều mã thì rủi ro càng lớn
- Ngay cả khi mật độ lỗi thấp, trong hàng triệu dòng mã vẫn có thể tìm ra lỗ hổng có thể khai thác
- Trường hợp iMessage cho thấy việc mở rộng bề mặt tấn công tạo ra vấn đề gì
- Ngay cả iMessage không mong muốn cũng được xử lý ngay trên iPhone để tạo bản xem trước
- Apple hỗ trợ nhiều định dạng ảnh khác nhau, và ngay cả PDF chứa phông chữ nén kỳ lạ cũng nằm trong diện được xử lý
- Định dạng cũ đó trên thực tế gần như chứa cả một ngôn ngữ lập trình, và kẻ tấn công có thể dùng nó để dò tìm các điểm yếu khác của điện thoại
- Apple lẽ ra có thể giảm bề mặt tấn công bằng cách giới hạn bản xem trước vào ít định dạng ảnh hơn nhiều hoặc chỉ một định dạng “đã biết là tốt”
- EU Cyber Resilience Act cũng nêu rõ rằng nhà cung cấp phải giảm thiểu bề mặt tấn công
Chỉ có mã tốt hơn thôi là chưa đủ
- Đã có những nỗ lực nhằm nâng cao chất lượng mã
- Ngôn ngữ an toàn bộ nhớ như Rust
- Công cụ tăng cường bảo mật như AddressSanitizer
- Fuzzer tự động biến đổi đầu vào để tìm lỗ hổng và bug
- Nhưng nhiều vấn đề bảo mật phát sinh từ logic bên dưới hơn là bug của chính đoạn mã
- Lỗ hổng email của Barracuda bắt nguồn từ việc một thư viện bên thứ ba quét bảng tính Excel để kiểm tra virus nhưng trên thực tế lại thực thi mã
- Quyết định thêm tính năng tự động thực thi mã trong tài liệu sẽ không được giải quyết chỉ bằng cách loại bỏ mọi bug trong mã
Không biết mình đang triển khai thứ gì
- Phần mềm hiện đại đã trở nên quá lớn đến mức khó biết thực sự mình đang triển khai cái gì
- Trong “A Plea for Lean Software” năm 1995, Niklaus Wirth đã chỉ trích việc phần mềm phình lên tới quy mô megabyte
- Hệ điều hành Oberon của ông, bao gồm trình soạn thảo và trình biên dịch, chỉ có 200KB
- Giờ đây có những dự án mà riêng file cấu hình đã vượt quá 200KB
- Ngày nay một ứng dụng điển hình có thể được xây dựng dựa trên Electron JS
- Electron JS bao gồm Chromium và Node.js
- Node.js cho phép truy cập tới hàng chục nghìn gói JavaScript
- Chỉ riêng việc dùng Electron JS thôi cũng được ước tính có thể kéo theo tối thiểu 50 triệu dòng mã, tính cả phụ thuộc
- Ứng dụng kéo về hàng trăm đến hàng nghìn gói phụ trợ, và phụ thuộc lại kéo theo phụ thuộc khác
- Chính xác những gì được đưa vào bản build có thể thay đổi mỗi ngày
- Một số gói mặc định có thể khiến người dùng bị lộ cho nhà quảng cáo hoặc nhà môi giới dữ liệu
- Ứng dụng điều khiển thiết bị trong nhà cũng có thể kết nối tới stack phần mềm phía Amazon, và stack đó cũng có thể dùng Node.js cùng nhiều phụ thuộc
- Kết quả là ngay cả việc mở cửa gara cũng có thể khiến hơn 50 triệu dòng mã hoạt động chạy trên nhiều image hệ điều hành và nhiều máy chủ
Gánh nặng của container và chuỗi cung ứng phụ thuộc
- Trước đây người ta phân phối đầu ra của trình biên dịch hoặc một gói file được thông dịch, và phải nghĩ xem bên trong gói có gì trong quá trình cài đặt, cấu hình
- Ngày nay thường phân phối bằng container, kèm theo không chỉ phần mềm mà cả các file hệ điều hành để khớp môi trường chạy
- Trên thực tế, tình huống phân phối gần như cả một disk image máy tính hoàn chỉnh xảy ra khá thường xuyên
- Trên Docker Hub có rất nhiều image vượt quá 350MB
- Container có thể được dùng cho mục đích tốt, nhưng cách sử dụng thực tế có thể làm tăng rất mạnh lượng mã được triển khai
- Cũng không rõ liệu bản vá bảo mật của phụ thuộc có được truyền tới ứng dụng cuối cùng hay không
- Rất khó biết các bug xử lý ảnh mà Google và Apple từng gấp rút vá có còn tồn tại trong các ứng dụng Electron hay không
- Hệ sinh thái npm có tiền sử bị chiếm quyền kho gói, hijack và hồi sinh các gói trùng tên
- PyPI cũng gặp các vấn đề tương tự
- Phụ thuộc cần được rà soát, nhưng khó có thể kỳ vọng việc thường xuyên kiểm tra hàng nghìn cái
- Tự tay viết lại mọi thứ cũng không phải lời giải; cũng có những module tốt như SQLite có khả năng an toàn hơn so với thứ tự viết lại
Trifecta: công cụ chia sẻ ảnh được làm bằng lượng mã nhỏ
- Trifecta là một phần mềm chia sẻ ảnh độc lập theo hướng tối giản nhưng vẫn thực sự dùng được
- Có thể dễ dàng chia sẻ ảnh bằng cách kéo thả trong trình duyệt
- Nếu dùng imgur, trình duyệt sẽ bị cài nhiều cookie và tracker, và ngay cả người xem ảnh được chia sẻ cũng có thể bị ép nhận tracker
- Các công cụ chia sẻ ảnh tự host cũng thường dựa trên framework lớn nên bị xem là khó tin cậy
- Trifecta được làm nhỏ để có thể rà soát toàn bộ mã chỉ trong vài giờ
- 1.600 dòng mã nguồn mới
- Khoảng 5 phụ thuộc quan trọng
- Tổng quy mô mã 3MB
- Một giải pháp chia sẻ ảnh khác được đem ra so sánh được phân phối dưới dạng Docker image 288MB
- Một giải pháp chia sẻ ảnh khác dựa trên Node được cho là có 1.600 phụ thuộc và hơn 4 triệu dòng JavaScript
- Trifecta không nhắm tới website công khai nơi người bất kỳ có thể tải ảnh lên, mà phù hợp cho công ty hoặc sử dụng cá nhân
Vấn đề nhầm lẫn độ phức tạp với sức mạnh
- Một trong những phản ứng phổ biến với Trifecta là khuyên triển khai bằng gói Amazon Web Services
- Đây là phản ứng không phù hợp với mục tiêu là phần mềm độc lập, không phụ thuộc dịch vụ bên ngoài
- Cũng có phản ứng cho rằng bài viết đối xử không công bằng với Docker, nhưng tác giả thừa nhận container có thể được dùng cho mục đích tốt
- Trong bài viết năm 1995, Niklaus Wirth chỉ ra xu hướng con người nhầm độ phức tạp với sự tinh vi
- Như Tony Hoare từng nói, có hai cách thiết kế phần mềm
- Làm chương trình đơn giản đến mức rõ ràng là không có lỗi
- Hoặc làm nó phức tạp đến mức trông như không có lỗi rõ ràng nào
- Wirth cho rằng áp lực thời gian là nguyên nhân chính của phần mềm phình to
- Áp lực thời gian cản trở việc lập kế hoạch cẩn thận
- Nó khiến người ta nhanh chóng thêm thắt và chỉnh sửa thay vì cải thiện một giải pháp chấp nhận được
- Nó dần làm xói mòn tiêu chuẩn chất lượng và mức độ chỉn chu của kỹ sư
- Sự bùng nổ phần mềm không phải quy luật tự nhiên, mà là thứ các kỹ sư phần mềm cần giảm bớt
Giảm lượng mã cũng là một biện pháp bảo mật
- Hiện tại thế giới đang triển khai quá nhiều mã
- Phần lớn là mã của bên thứ ba
- Một phần được đưa vào ngoài ý muốn
- Phần lớn không được kiểm tra đầy đủ
- Kết quả là xuất hiện một bề mặt tấn công khổng lồ, trong đó một lượng lớn mã ở mức tầm thường bị phơi ra
- Những nỗ lực cải thiện chất lượng mã vẫn đang tiếp tục, nhưng nhiều khai thác xuất phát từ thất bại logic, và tiến bộ trong việc phát hiện chúng còn tương đối ít
- Chỉ riêng việc giảm lượng mã phơi ra với thế giới cũng có thể mang lại cải thiện lớn
- Thời gian ra mắt sản phẩm có thể sẽ dài hơn, nhưng các quy định sắp tới có thể buộc nhà cung cấp phải nghiêm túc hơn với bảo mật
- Trifecta và Oberon cho thấy vẫn có thể cung cấp nhiều chức năng với lượng mã và phụ thuộc hạn chế
1 bình luận
Ý kiến trên Hacker News
Trong A Deepness in the Sky của Vernor Vinge, loài người đã lan rộng giữa các vì sao chỉ với công nghệ dưới tốc độ ánh sáng, và các phi thuyền liên sao xuất hiện như một mớ công nghệ cổ xưa pha trộn từ nhiều hệ sao và nền văn minh
Các hệ thống máy tính cũng đã tiến hóa quá lâu đến mức hầu như không còn ai hiểu phần lớn mã nguồn nữa, người ta cứ dùng rồi chồng thêm lớp mới lên trên
Đặc biệt, có một nhân vật là kỹ sư hệ thống từ thời rất xa xưa, thuộc hàng những con người còn sống lâu đời nhất vì liên tục lặp lại trạng thái ngủ đông và du hành dài ngày; trong tương lai nơi mọi người chỉ biết chất thêm nhiều lớp lên trên, việc ông ấy hiểu cách hệ thống thời đại mình vận hành và các điểm yếu của nó lại trở thành lợi thế lớn
Tôi nghĩ Vinge đã nhìn rất đúng vào điều gì đó
Vế đầu là một bí ẩn thật sự cần khoa học hiện đại và những người cực kỳ thông minh giải quyết, còn vế sau gần như chỉ là do thiếu quan tâm
Nếu trả đủ tiền, một kỹ sư giỏi sẽ tháo máy giặt ra và tìm chính xác lỗi ở đâu, nhưng chẳng ai muốn trả khoản đó; họ sẽ vứt đi rồi mua cái mới
Kiến thức phần mềm trong quá khứ rõ ràng thuộc kiểu thứ hai. Nếu đào đủ sâu vào bất kỳ phần nào thì cuối cùng vẫn có thể hiểu hoàn toàn, nhưng đa số trường hợp thì bỏ qua hoặc đắp thêm một lớp khác lên trên rẻ hơn và thực tế hơn nhiều
Câu chuyện kể về tương lai nơi loài người đã quên mất phép tính số học cơ bản, và khi có ai đó tái phát hiện ra nó thì những kẻ nắm quyền lại muốn dùng nó cho chiến tranh; tôi hiểu thông điệp muốn truyền tải, nhưng bối cảnh quá phi thực tế đến mức lố bịch nên làm nó mất đi sức nặng
Nếu muốn bàn sâu hơn, xem http://lambda-the-ultimate.org/node/4424
Chúng ta đã gặp vấn đề này rồi. Chú tôi ngoài 60 đang bảo trì phần mềm vận tải xe tải cũ viết bằng COBOL, và đúng là vẫn có những công việc với công nghệ kiểu cổ như vậy. Nếu quan tâm thì tôi có thể giới thiệu
Vấn đề gốc cũng giống vụ left-pad. Người ta hay cười nhạo mấy kỹ sư junior tự cài dependencies một cách hời hợt mà không có giám sát, nhưng qua hàng chục năm và nhiều thế hệ lập trình viên, cuối cùng phần lớn phần mềm sẽ ở mức nào đó dựa vào các dependency không ai thực sự hiểu
Cứ giả sử phải phát hành một bản cập nhật vào năm 2100, thì bạn sẽ đẩy nó qua hệ thống quản lý dependency npm của thời đó. Đồng thời sẽ có cả một quy mô thiết bị phụ thuộc cỡ Hệ Mặt Trời cần cập nhật bảo mật, với hàng nghìn tỷ thiết bị và các bộ nhớ đệm trung gian mà không ai biết còn đồng bộ hay không. Tôi không tưởng tượng nổi cây phụ thuộc như thế sẽ trông ra sao
Cũng rất bực khi phải làm trong môi trường mà muốn chạm tới cốt lõi thì phải đào bới mã nguồn của framework. Cảm giác như đang lãng phí thời gian
Tình trạng phình to này thấy ở phần lớn thư viện npm. Tác giả không biết thiết kế tốt là gì, và cố biến mọi thư viện thành thứ làm được mọi việc
Tự xưng là thư viện chuyển đổi mã hóa chuỗi nhưng lại nhét cả tải file, lưu file, tải xuống từ Internet, thậm chí cả công cụ dòng lệnh vào cùng một kho. Thư viện chỉ nên làm đúng một việc của mình, còn lại để cho người dùng
Bên Rust cũng không có vẻ khá hơn. Chỉ cần thử sửa tài liệu Rust là sẽ thấy cỡ 1000 crate được cài vào
Vấn đề không nằm ở ngôn ngữ mà ở chỗ ai cũng có thể đăng thư viện lên, và thực tế là đúng là ai cũng đăng lên. Những người “chỉ muốn xong việc” sẽ chọn thư viện có nhiều tính năng nhất, rồi lại đòi thêm tính năng chỉ vì không muốn tự viết 3 dòng code ở ngoài thư viện. Kiểu như “có thể thêm cả render PDF không?”
Tôi không rõ giải pháp là gì, nhưng có nghĩ đến việc lập một nhóm cổ vũ Low Dependency cùng huy hiệu để các tác giả thư viện muốn có huy hiệu đó, và người dùng cũng tìm nó khi chọn thư viện
Ngược lại, nếu muốn thư viện ít phụ thuộc, bạn sẽ phải lấy vài thứ làm được rất nhiều việc
Theo góc nhìn của tôi, thư viện hơi dày một chút nhưng ít phụ thuộc, do tác giả đáng tin làm ra, sẽ tốt hơn. Lodash thì lớn, nhưng bản ES6 module hỗ trợ tree shaking, và trên thực tế đóng vai trò như thư viện chuẩn mà JavaScript vốn thiếu. date-fns cũng tương tự với Date. Tôi mặc định đưa cả hai vào gần như mọi dự án để lấp những chỗ trống trong thư viện lõi của JavaScript
Trước đây tôi từng làm hợp đồng Ruby on Rails, và vấn đề hiệu năng tệ đến mức chúng tôi phải phát triển ở chế độ release. Máy chủ không thể tự động reload khi file thay đổi nữa
Một ngày nọ tôi quá mệt nên bắt đầu đào sâu, và số lượng gem bị kéo vào nhiều đến mức tôi không còn nhớ nổi. Trong đó có một gem đúng nghĩa là để tiết kiệm 3 dòng code
Từ đó về sau tôi tránh xa cộng đồng RoR. Gần đây, sau vài năm, tôi lại nhận hợp đồng RoR; tuy không tệ như trước nhưng vẫn chẳng tốt
Có những cộng đồng hoàn toàn không coi trọng rủi ro mà phụ thuộc mang lại
Mặt khác, việc bất kỳ kho Git nào cũng có thể host thư viện Go, và ai cũng có thể dùng từ URL đó, thực sự rất tiện
Trước hết là các tác giả gói muốn biến việc này thành sự nghiệp, mà cách để có được sự chú ý thì chỉ có tạo ra thật nhiều gói. Thế là họ tiếp tục tạo các gói phụ thuộc vào những gói khác do chính họ viết, rồi cố đưa một hai gói hữu ích vào code của người khác
Thứ hai là những người tin rằng giải quyết vấn đề lúc nào cũng đồng nghĩa với việc thêm một gói mới. Họ không quan tâm có bao nhiêu phụ thuộc, cũng chẳng quan tâm vấn đề thực sự có khó hay không. Vì vậy thay vì học cách giải quyết vấn đề, họ lại học API của một wrapper trên GitHub có 4 sao
Lý tưởng nhất là công cụ như vậy sẽ dành thời gian nhàm chán để tỉa bỏ các gói không cần thiết, giảm trách nhiệm của từng gói xuống mức tối thiểu, sắp xếp môi trường cho hợp lý rồi cache độc lập để loại bỏ phụ thuộc vào LLM. Chỉ khi có sự cố thì mới gọi bộ kiểm tra cập nhật hay người tuyển chọn vào
Thành thật mà nói, đây là một trong những vấn đề tệ nhất của phần mềm hiện đại, và theo tôi nó làm hơn 50% dự án trở nên vô dụng. Đây là vấn đề buồn tẻ nhưng giải được, nên cực kỳ hợp với một LLM agent tử tế, và nếu có thì sẽ rất hữu ích
“Bạn đã từng nhìn máy bay hiện đại chưa? Đã từng theo dõi cách đường nét của nó tiến hóa qua từng năm chưa? Và không chỉ máy bay, với mọi thứ do con người tạo ra, bạn đã từng nghĩ rằng nỗ lực công nghiệp của con người, những phép tính và những đêm dài bên bản vẽ, rốt cuộc đều hội tụ về nguyên lý duy nhất và thống trị là sự giản đơn tối hậu chưa?
Cứ như thể có một quy luật tự nhiên ra lệnh rằng để mài giũa đường cong của đồ nội thất, sống tàu hay thân máy bay cho đến khi chúng gần với sự thuần khiết nguyên sơ như đường cong của ngực hay vai con người, thì cần đến những cuộc thử nghiệm của nhiều thế hệ thợ lành nghề. Dường như sự hoàn hảo đạt tới không phải khi không còn gì để thêm vào, mà là khi không còn gì để bỏ đi.”
— Antoine de Saint Exupéry, Terre des Hommes
Viết ra kiểu như “để mở cửa gara có thể cần hơn 50 triệu dòng mã đang hoạt động và image hệ điều hành của nhiều máy chủ” thì nghe thật điên rồ
Chỉ cần nghĩ đến việc có bao nhiêu code đang chạy trên cỗ máy mà tôi dùng để gõ những dòng này là đã thấy choáng váng. Toàn những thứ tôi chưa từng rà soát, và có lẽ cũng hầu như chưa từng được rà soát nghiêm ngặt
Thôi, quay lại cài dependency npm đây
Ví von này đáng để mang ra dùng: “Phần mềm giờ bị xem là nguy hiểm đến mức người ta bảo đừng tự chạy nó. Thay vào đó, hãy giao cho nhà cung cấp ‘X as a service’ hoặc đơn giản là ‘đám mây’. Hãy so sánh với một tình huống giả định nơi ô tô bốc cháy quá thường xuyên đến mức người ta khuyên đừng tự lái, mà hãy giao việc lái xe cho một chuyên gia luôn có lính cứu hỏa chuyên nghiệp đi kèm”
Bạn gái cũ của tôi không tin vào “đám mây”, vì những lý do hoàn toàn hợp lý do từng lớn lên ở khối Đông Âu cũ. Nhưng lựa chọn thay thế chỉ là hy vọng cô ấy đừng làm mất chiếc laptop HP mua rẻ nhất. Sau khi hướng dẫn một chút, ít nhất ở điểm đó cô ấy đã yên tâm hơn
Vấn đề là sự thiếu hụt giáo dục nói chung, và việc thiếu cân nhắc về hệ quả của điều đó. Cuối cùng bạn либо phải chấp nhận rủi ro, hoặc tự học, hoặc dựa vào các công ty SaaS và đám mây. Tôi đã thấy rất nhiều nước mắt, và không thấy nhiều trường hợp tự học lấy
Đây là vấn đề trách nhiệm cá nhân, nhưng vì chẳng ai muốn gánh trách nhiệm đó nên giao cho chuyên gia có thể là lời giải ít tệ hơn so với tự tin vào chính mình. Đáp án đúng là giáo dục, nhưng khó đến mức tuyệt vọng
Phần mềm không thể nhẹ hơn được nữa. Muốn vậy cần thời gian, kỹ năng và nhân lực đắt tiền, chứ không thể chỉ dựa vào những người ghép 12 ví dụ từ các stack công nghệ khác nhau thành một Franken-suite
Tôi là lập trình viên độc lập, và người mới học node.js từ năm ngoái thì lúc nào cũng chào giá thấp hơn tôi để lắp ghép trong một ngày một webapp khuôn mẫu nhưng vẫn đầy lỗ hổng bằng node.js, container, một dịch vụ DB hosted nào đó trên AWS, Lambda, object storage, Cloudflare, YAML, React, Vite và đủ loại dependency khác
Phần mềm gọn nhẹ, nhanh, chi phí chạy thấp và bảo trì cũng rẻ hơn sẽ rẻ hơn về dài hạn, nhưng rất khó viết sao cho có lãi
Ngày xưa từng có giấc mơ rằng mọi người sẽ dùng các hook và routine chuẩn do hệ thống cung cấp cho những thứ như giao diện. Hãy nghĩ đến Macintosh Toolbox hay QuickDraw
Người ta từng nói công việc chính của lập trình viên là viết logic chương trình, còn thay đổi hay bổ sung thì phải mang tính trong suốt. System call sẽ thực hiện cùng một tác vụ một cách mượt mà dù mã bên trong thay đổi, còn tính năng mới sẽ là siêu tập của tính năng cũ, để mã cũ vẫn biên dịch hoặc chạy bình thường trong khi phần mềm mới có thêm nhiều khả năng hơn
Người ta cho rằng làm vậy sẽ giúp bảo trì dễ hơn, giao diện được chuẩn hóa, và mã cũng gọn nhẹ hơn vì phụ thuộc nhiều vào system call. Khi đó còn có không khí cho rằng nên tránh thư viện bên ngoài
Giấc mơ này nhanh chóng sụp đổ, cứ nghĩ đến DLL là được. Rất nhiều quản lý gói và đóng gói ngày nay trông giống như việc đảm bảo đúng thư viện cần thiết thực sự tồn tại
Khi ấy phát triển phần mềm quy mô lớn vẫn còn gần như ở thời kỳ sơ khai, nên việc nó không thành như kỳ vọng cũng có thể hiểu được. Giờ thì đã tích lũy rất nhiều kinh nghiệm tập thể về những vấn đề này, nên tôi tự hỏi liệu kết luận đã là giấc mơ đó không thể thực hiện một cách tỉnh táo, hay chính vì đã nếm đủ tình trạng lộn xộn hiện tại mà chúng ta sẽ hướng đến một lần thử hiện đại hơn
Nếu muốn phần mềm nhanh, gọn, ổn định và an toàn thì dù có thể khó mà có đủ cả bốn cùng lúc, tôi cũng không chắc tình hình hiện tại có đang đi theo hướng đó hay không
Lisp thời kỳ đầu đưa rất ít thứ vào ngôn ngữ, nhưng Raku lại đẩy vào đặc tả ngôn ngữ cả những thứ vụn vặt vốn có thể thành thư viện npm
C để bạn tự quyết cách build mã, nhưng đa số ngôn ngữ biên dịch mới hơn đều đi kèm một dạng công cụ build nào đó
Có những việc khá hiệu quả trong bối cảnh này, nhưng chúng diễn ra ngoài bối cảnh “bạn, cái máy, dự án mới” từng dẫn dắt công trình của Wirth. Vấn đề là chúng có xu hướng đi kèm ngưỡng phụ thuộc vào những dependency khổng lồ như cơ sở dữ liệu hay browser engine, và nếu bạn không thích cách những dependency đó được tạo ra thì rốt cuộc bạn sẽ khổ sở
Tôi vẫn luôn nói điều này về Rust
Nếu 70% lỗ hổng cũ của C++ thực sự là liên quan đến bộ nhớ, thì số lỗ hổng trên mỗi dòng mã có thể ít hơn C++ 70%
Nhưng nếu trong Rust bạn kéo vào hàng trăm package và số dòng mã tăng gấp 10 thì câu chuyện sẽ khác
30% của 100.000 dòng vẫn lớn hơn 100% của 10.000 dòng
Nếu thứ như QT được viết bằng Rust thì bản thân nó cũng sẽ thành hàng trăm crate, nhưng lượng mã và mức rủi ro phải chấp nhận sẽ hoàn toàn y hệt
Nhưng vấn đề lớn là lỗ hổng. Sửa một lỗi trong một thư viện dùng chung để vá hàng trăm thư viện thì tốt hơn, hay phải vá từng thư viện một trong hàng trăm thư viện thì tốt hơn?
Việc Rust khiến người ta dễ kéo vào nhiều dependency nhỏ thay vì vài dependency lớn là chuyện không liên quan. Không phải là bạn đang viết nhiều mã hơn
Ví dụ, bạn có tính crate
regexcủa Rust là một dependency không? Trong C++ thì thứ đó nằm trong thư viện chuẩnBạn có tính Boost là một dependency trong C++ không? Nếu ở Rust thì nó có lẽ tương đương khoảng 30 crate riêng biệt
Trong các chương trình Rust thực tế đã có bao nhiêu trường hợp so với C++? Tần suất thực thi mã từ xa ở C++ có lẽ cao hơn Rust rất nhiều, vượt xa mức 70%
Dù hiện nay ứng dụng thường được làm bằng Electron JS, có vẻ nhiều người chưa thực sự biết rằng vẫn có thể dùng web control native của từng nền tảng mà không cần đóng gói kèm Electron
Làm vậy thì ứng dụng phát hành có thể chỉ còn ở mức kilobyte. Cách tiếp cận này cũng cho phép tự do dùng bất kỳ ngôn ngữ backend hay tech stack nào, miễn là có thể giao tiếp với web view
Ngày nay, chẳng phải PWA nên khả thi với một tỷ lệ khá lớn các ứng dụng sao?
Tôi không chắc lắm, nhưng liệu Discord cũng có thể trở thành PWA thay vì ứng dụng Electron không?
Có lẽ khoảng trống lớn nhất là một thứ đủ mạnh tương đương SQLite và sự khác biệt với IndexedDB, nhưng dù vậy, phần lớn ứng dụng có lẽ cũng không nhất thiết cần một ngôn ngữ truy vấn ở mức cao hơn mô hình B-tree của IndexedDB
Lại thêm một lần hô vang cho triết lý suckless. Vạn tuế
[0 ]https://suckless.org/