50 điểm bởi GN⁺ 2025-03-26 | 5 bình luận | Chia sẻ qua WhatsApp
  • Leslie Lamport là một trong những người phát triển đầu tiên của LaTeX và là người tiên phong trong lĩnh vực hệ thống phân tán. Ông nhận giải Turing năm 2013
  • Trong bài keynote tại SCaLE 22x, ông nhấn mạnh tầm quan trọng của sự trừu tượng hóa, đồng thời chỉ ra rằng phần lớn lập trình viên quá tập trung vào việc viết code và ngôn ngữ, trong khi tư duy trừu tượng và thiết kế trước khi code mới là cốt lõi

Tóm tắt bài nói

  • Mọi người có thể kỳ vọng tôi sẽ nói về tính đồng thời (Concurrency), nhưng tôi không có gì mới để nói về chủ đề đó
  • Tuy nhiên, những hiểu biết về việc "viết chương trình concurrent" cũng áp dụng cho toàn bộ hoạt động lập trình nói chung
  • Bài nói này bàn về lập trình nói chung

Thuật toán vs. chương trình

  • Thuật toán: ý tưởng trừu tượng, không phụ thuộc vào ngôn ngữ. Đây là khái niệm trừu tượng hơn và ở cấp cao hơn chương trình
  • Chương trình: dạng cụ thể hiện thực thuật toán bằng một ngôn ngữ nhất định. Ngôn ngữ lập trình quá phức tạp để biểu đạt thuật toán
  • Thuật toán không được thực thi, và nói chung ngắn gọn, đơn giản
  • Đặc biệt với mã liên quan đến đồng thời, cần định nghĩa chính xác thuật toán trước rồi mới hiện thực

Trừu tượng hóa qua ví dụ tìm giá trị lớn nhất trong mảng

  • Ngay cả với một bài toán đơn giản cũng cần định nghĩa rõ "sẽ làm gì (What)"
  • Ví dụ: "trả về giá trị lớn nhất của mảng số nguyên" → "trả về số nhỏ nhất mà không nhỏ hơn mọi phần tử"
  • Cách xử lý mảng rỗng cũng cần được định nghĩa trước (ví dụ dùng -∞)
  • Nhờ định nghĩa rõ ràng như vậy, có thể rút ra thuật toán (How) đơn giản và vững chắc hơn

Việc thực thi chương trình là dòng chảy của trạng thái

  • Việc thực thi chương trình không chỉ là thứ tự các lệnh, mà là chuỗi liên tục các trạng thái (state)
  • Mỗi lần chuyển trạng thái tương ứng với việc thực thi một phần của mã
  • Góc nhìn này quan trọng khi chứng minh tính đúng đắn của thuật toán (chẳng hạn dùng bất biến)

Công cụ cho hệ thống phức tạp: TLA+

  • Để biểu đạt sự trừu tượng hóa một cách chính xác, cần có một ngôn ngữ chính xác
  • TLA+ là công cụ được thiết kế cho mục đích đó
  • Amazon Web Services đã dùng TLA+ để phát hiện trước các lỗi thiết kế nghiêm trọng
  • Virtuoso, hệ điều hành của tàu vũ trụ Rosetta, cũng được thiết kế dựa trên TLA+, và mã nguồn vừa gọn vừa ổn định

Vai trò của trừu tượng hóa ngay cả với đặc tả chưa hoàn chỉnh

  • Ví dụ: với pretty printer, tiêu chí căn chỉnh có thể mang tính chủ quan
  • Dù vậy, việc xác định sẵn một tập quy tắc trừu tượng vẫn quan trọng cho gỡ lỗi và bảo trì

Mối quan hệ giữa viết và tư duy

  • Viết suy nghĩ ra thành lời giúp làm rõ tư duy
  • Trừu tượng hóa không chỉ diễn ra trong đầu mà cần được diễn đạt bằng văn bản thì mới hiệu quả
  • Lamport cho biết quá trình rèn luyện toán học đã giúp ông phát triển năng lực trừu tượng hóa
  • Các nhà toán học có thể dạy lập trình viên về trừu tượng hóa

Góc nhìn về thư viện và bug

  • Phần hai của bài nói, "Vì sao chương trình phải có bug", bàn về vấn đề độ phức tạp
  • Phần mềm hiện đại phụ thuộc vào nhiều thư viện, nhưng chúng thiếu các mô tả chính xác, độc lập với ngôn ngữ
  • Vì vậy, trong quá trình tích hợp thường phát sinh các bug ngoài dự kiến
  • Ví dụ: trải nghiệm gỡ lỗi JavaScript trên website khóa học TLA+ của chính ông
  • Góc nhìn dựa trên trạng thái hữu ích để hiểu kiểu phức tạp này

Những chủ đề được đề cập trong phần hỏi đáp

  • Ảnh hưởng của AI đối với trừu tượng hóa
  • Sự tách rời giữa mã nguồn mở và học thuật
  • Thực tế là các lập trình viên thường xem nhẹ định nghĩa hình thức (formal definition)
  • Điều quan trọng nhất vẫn là "suy nghĩ trước khi code"

Kết luận: bản chất của lập trình là tư duy

  • Lamport cho rằng cần ưu tiên tư duy trừu tượng và đặc tả hình thức hơn việc chỉ đơn thuần viết code
  • Nỗ lực ban đầu có thể lớn, nhưng cuối cùng sẽ dẫn đến phần mềm vững chắc hơn và dễ bảo trì hơn
  • Viết code chỉ là một phần của lập trình, còn lập trình thực sự bắt đầu từ thuật toán chính xác và sự trừu tượng hóa
  • Trong thời đại mà độ phức tạp hệ thống và tính đồng thời ngày càng tăng, trừu tượng hóa là năng lực thiết yếu, và lập trình viên cần rèn luyện khả năng tư duy và trừu tượng hóa

5 bình luận

 
softer 2025-03-27

Tôi cũng đồng cảm với bài viết này
Tôi cũng cho rằng việc định nghĩa vấn đề bằng các giá trị trạng thái đã được trừu tượng hóa rất hữu ích cho việc phát hiện vấn đề, và đang muốn tạo ra các công cụ quản lý trạng thái rõ ràng, trực quan và minh thị như trực quan hóa trạng thái bằng sơ đồ, Unreal Blueprint hay workflow

Có lẽ trước hết cần xem xét ngôn ngữ

 
felizgeek 2025-03-27

Đây là một bài viết khiến tôi nhớ đến các môn học chuyên ngành về lý thuyết tính toán! Tôi khuyên những ai làm lập trình nên thử học qua.

 
aer0700 2025-03-26

Tôi tò mò không biết TLA là gì
Chắc tôi sẽ phải tìm thử mới được

 
GN⁺ 2025-03-26
Ý kiến trên Hacker News
  • Các "coder" trong demoscene tự gọi mình như vậy và cảm thấy tự hào về điều đó, và họ cũng thường là những "programmer" và "software engineer" xuất sắc. Dù dùng tên gọi nào như coder, programmer hay software engineer, điều quan trọng là làm cho máy tính hoạt động theo ý muốn của bạn

  • Bài keynote năm sau có lẽ sẽ là "vibing không phải là coding, cũng không phải là programming...; đôi khi chỉ là một kim tự tháp rác chạy được đôi chút". May mà Dijkstra không phải nhìn thấy điều này. Ông đã nổi giận trong phòng khách nhà bố mẹ tôi từ những năm 80. Tôi không thể tưởng tượng ông ấy sẽ phản ứng thế nào khi thấy "vibe coding"

  • Keynote SCaLE 22x của Leslie Lamport: hãy suy nghĩ, trừu tượng hóa, rồi mới code. Lamport kêu gọi một sự thay đổi căn bản trong cách tiếp cận lập trình, nhấn mạnh suy nghĩ và trừu tượng hóa trước khi code, và điều này áp dụng cho mọi đoạn mã không tầm thường

    • Ưu tiên trừu tượng hóa: xác định góc nhìn trừu tượng của chương trình trước khi viết mã. Thiết kế ở mức cao này giúp làm rõ logic và phát hiện lỗi sớm. Tập trung vào ý tưởng thay vì một ngôn ngữ cụ thể
    • Thuật toán != chương trình: thuật toán là khái niệm trừu tượng, còn chương trình là hiện thực cụ thể
    • Thực thi như trạng thái: mô hình hóa việc thực thi chương trình như một chuỗi trạng thái, trong đó tương lai của mỗi trạng thái chỉ phụ thuộc vào hiện tại. Điều này đặc biệt giúp đơn giản hóa việc suy luận trong môi trường đồng thời
    • Tầm quan trọng của bất biến: xác định các bất biến, tức những thuộc tính đúng với mọi trạng thái thực thi. Hiểu được chúng là yếu tố thiết yếu để đảm bảo tính đúng đắn
    • Tầm quan trọng của đặc tả rõ ràng: nhiều thư viện thiếu đặc tả rõ ràng, khiến việc sử dụng đúng trở nên khó khăn. Đặc biệt trong đồng thời, cần có mô tả chức năng rõ ràng và độc lập với ngôn ngữ
    • Viết là suy nghĩ: viết buộc ta phải rõ ràng và làm lộ ra những suy nghĩ cẩu thả. Suy nghĩ lại cải thiện cách viết. Đây là một vòng lặp tích cực
    • Học cách trừu tượng hóa: trừu tượng hóa là kỹ năng cốt lõi của toán học, và lập trình viên cần phát triển năng lực này
    • Trừu tượng hóa thông qua AI? Có câu hỏi được đặt ra về việc liệu các mô hình AI có thể được tận dụng cho quá trình tư duy trừu tượng trong lập trình hay không
  • Lập trình nên là một quá trình có chủ đích, trong đó phần hiện thực hóa (coding) diễn ra sau thiết kế cẩn thận (trừu tượng hóa), đồng thời tập trung vào việc hiểu hành vi chương trình thông qua đặc tả rõ ràng, chuỗi trạng thái và các bất biến. Suy nghĩ luôn tốt hơn

  • Giáo sư toán gọi mọi hành động biến đổi khái niệm sang dạng chính xác hơn và máy có thể đọc được là coding. Không chỉ là viết bằng ngôn ngữ lập trình điều bạn muốn máy tính làm, mà còn bao gồm cả việc mã hóa dữ liệu. Từ "encode" làm điều này rõ hơn. Ông giao bài tập định nghĩa một cách coding để chuyển cây nhị phân thành số tự nhiên. Từ coding quá mơ hồ nên ông không dùng nó nhiều

  • Lamport cho rằng nên tách biệt "cái gì" và "làm thế nào". Tuy nhiên, tôi tự hỏi liệu trong hầu hết vấn đề thì "cái gì" và "làm thế nào" của chương trình có phần nào hòa vào nhau hay không. Ví dụ, các cân nhắc về hiệu năng là một phần của "cái gì", hay của "làm thế nào"?

  • Một bản tóm tắt thú vị: thuật toán không phải là chương trình, không nên được viết bằng ngôn ngữ lập trình và nên đơn giản. Trong khi đó, chương trình phải chạy nhanh trên những tập dữ liệu có thể rất lớn nên phải phức tạp. Điều này đặc biệt được bàn tới vì các chương trình đồng thời chạy trên nhiều CPU có thứ tự thực thi khác nhau

  • Định nghĩa chương trình là loại mã cần suy nghĩ trước khi viết, và là loại mã dành cho người không muốn đọc code sử dụng. Bài nói này đã được trình bày từ rất lâu. Ví dụ về việc đơn giản hóa thao tác tìm mục nhỏ nhất trùng khớp chính xác với "Define Errors Out of Existence" trong sách của John Ousterhout

  • Tôi thấy thú vị trước sự mỉa mai rằng phần bình luận chủ yếu đầy những người không hiểu thông điệp. Điểm cốt lõi của Leslie Lamport là phát triển năng lực tư duy trừu tượng sẽ dẫn tới những chương trình tốt hơn. Trừu tượng hóa theo nghĩa toán học và logic cho phép loại bỏ mọi chi tiết không liên quan. Điều tương tự cũng đúng với phát triển phần mềm được AI dẫn dắt

  • Như có thể đoán trước với mọi thứ liên quan đến sự nghiêm ngặt, nhiều người chỉ đọc tiêu đề rồi phản ứng tiêu cực. Một hacker trên Hacker News có thể là một lập trình viên lành nghề có thể giải quyết vấn đề. Giờ đây nó cũng có thể mang nghĩa kiểu "You're a Hack", tức một người kém năng lực và tạo ra kết quả chất lượng thấp

  • Bài nói và cuộc thảo luận này quá sa đà vào tiểu tiết

  • Hiện ACM có một bài viết hay nói rằng dù không đồng ý về việc trừu tượng hóa là gì, nó vẫn cực kỳ hữu ích. Tôi phần lớn đồng ý về chỗ mà điểm quan trọng nằm ở đâu. Tôi không đồng ý chính xác nó là gì và vì sao nó quan trọng. Có thể nhận được rất nhiều cảm hứng từ đó, và bản thân điều đó đã có giá trị

  • Hacking không phải là coding, cũng không phải là programming, cũng không phải phát triển phần mềm, cũng không phải kỹ nghệ phần mềm. Nhưng rốt cuộc rất nhiều người dùng các thuật ngữ này gần như thay thế cho nhau, và việc nhấn mạnh sự khác biệt giữa các định nghĩa cá nhân thường không phải là cách dùng thời gian hiệu quả