1 điểm bởi GN⁺ 2024-03-25 | 1 bình luận | Chia sẻ qua WhatsApp
  • Đầu năm 1982, nhóm phần mềm Lisa chịu áp lực phải phát hành trong vòng 6 tháng nên định đo tiến độ bằng số dòng mã hàng tuần của từng kỹ sư
  • Bill Atkinson cho rằng số dòng mã không phản ánh đúng năng suất, và cũng đi ngược mục tiêu tạo ra chương trình nhỏ gọn và nhanh
  • Khi viết lại bộ máy tính toán vùng của QuickDraw bằng một thuật toán đơn giản và tổng quát hơn, các phép toán vùng trở nên nhanh hơn gần 6 lần và mã giảm khoảng 2.000 dòng
  • Trong biểu mẫu quản lý đầu tiên, ở mục hỏi số dòng mã đã viết trong tuần đó, Bill ghi -2000, qua đó phơi bày nguyên vẹn lỗ hổng của cách đo này
  • Vài tuần sau, các quản lý không còn yêu cầu Bill nộp biểu mẫu đó nữa, và giai thoại này cho thấy quản lý dựa trên số dòng mã có thể bỏ lỡ những cải tiến thực sự

Đo số dòng mã trong nhóm Lisa

  • Đầu năm 1982, nhóm phần mềm Lisa muốn tăng tốc công việc כדי phát hành phần mềm trong 6 tháng tới
  • Một số quản lý đã cố theo dõi tiến độ bằng số dòng mã mà mỗi kỹ sư viết ra mỗi tuần
  • Các kỹ sư nhận được một biểu mẫu phải nộp vào mỗi thứ Sáu, trong đó có mục ghi số dòng mã đã viết trong tuần đó

-2000 của Bill Atkinson

  • Bill Atkinson, tác giả của QuickDraw và là nhà thiết kế giao diện người dùng chủ chốt, giữ vai trò quan trọng trong việc hiện thực hóa Lisa
  • Bill cho rằng chỉ số số dòng mã không thể đo đúng năng suất
    • Ông tin rằng mục tiêu của phần mềm tốt là viết ra chương trình nhỏ gọn và nhanh nhất có thể
    • Một chỉ số khuyến khích tăng số dòng có thể thúc đẩy việc viết mã cẩu thả, cồng kềnh và dễ hỏng
  • Khi đó ông đang tối ưu hóa bộ máy tính toán vùng của QuickDraw
    • Ông viết lại hoàn toàn bộ máy vùng bằng một thuật toán đơn giản và tổng quát hơn
    • Sau khi điều chỉnh, các phép toán vùng trở nên nhanh hơn gần 6 lần
    • Đồng thời, mã giảm khoảng 2.000 dòng
  • Khi điền biểu mẫu quản lý đầu tiên, ông nhìn mục số dòng mã một lúc rồi ghi -2000
  • Không rõ các quản lý đã phản ứng thế nào, nhưng vài tuần sau họ không còn yêu cầu Bill nộp biểu mẫu nữa

1 bình luận

 
GN⁺ 2024-03-25
Ý kiến trên Hacker News
  • Gợi nhớ đến trường hợp xung đột về số dòng code giữa Microsoft và IBM
    Trong loạt chương trình truyền hình của PBS dựa trên Accidental Empires của Bob Cringely, có một đoạn Steve Ballmer kể lại trải nghiệm cùng phát triển OS/2 với IBM
    Microsoft có thái độ hoàn thành công việc như một công ty nhỏ, còn IBM thì tập trung vào các chỉ số nội bộ, đặc biệt là đo năng suất lập trình viên bằng KLoC (số dòng code tính theo nghìn dòng)
    Ballmer nói rằng: “Điều họ quan tâm chỉ là KLoC, KLoC, rồi lại KLoC”, và có vẻ IBM quan tâm số lượng code nhiều hơn là code có tốt hay không
    https://ubiquity.acm.org/article.cfm?id=1022357

    • Không chỉ riêng IBM như vậy. Vài năm trước tôi từng làm trong một dự án lớn mà một công ty tư vấn quốc tế lớn là nhà thầu chính, và khi codebase vượt 1 triệu dòng, họ mở tiệc cho cả nhóm
      Những người hiểu chuyện xem màn “ăn mừng” đó chẳng khác nào một đám tang
    • Loạt TV được nhắc ở đây là Triumph of the Nerds, và xem lại bây giờ vẫn rất hay. Có khi giờ còn đáng xem hơn nữa
  • Dùng số dòng code làm chỉ số năng suất thật sự là điều ngớ ngẩn
    Tôi từng sửa một bug không ai giải được suốt 20 năm chỉ bằng một dòng code, và cũng nhớ có bug tồn tại 3 năm được giải quyết chỉ với một order by. Làm sao đo được tác động của một dòng code? Theo kinh nghiệm của tôi, lập trình viên kém thường viết nhiều code hơn rất nhiều
    Cũng không thể quên câu chuyện một lập trình viên Microsoft viết lại đoạn code IBM dài 33 nghìn ký tự xuống còn 220 ký tự[1]. Kết quả là khối lượng công việc của Microsoft thành ra “âm”, và chiến tranh nổ ra vì chuyện đó
    [1] https://archive.org/details/bigbluesunmaking00carr/page/4/mode/2up trang 101

    • Bản thân việc dùng chỉ số năng suất nói chung đã là ngớ ngẩn, và là cách rất dễ khiến lập trình viên tối ưu chỉ số thay vì làm công việc tốt
      Ví dụ hiện nay là có công ty lấy “tác động”, tức việc ra mắt sản phẩm mới, làm tiêu chí thăng chức. Kết quả là dễ sinh ra hàng đống sản phẩm thất bại mà chẳng ai bảo trì
    • Chắc chắn có những kỹ sư vài tháng mới sửa một bug nghiêm trọng nhưng tạo ra giá trị hàng triệu đô, nhưng nhìn chung thì kỹ sư giỏi thường có sản lượng cao, còn kỹ sư có sản lượng thấp thường không giỏi
    • Xét trong dài hạn, tôi cho rằng có một mức độ tương quan nào đó giữa số dòng code và đầu ra kỹ thuật
      Trong số các nhà khoa học máy tính và kỹ sư vĩ đại có những người tạo ra lượng code khổng lồ, và tôi tin điều đó bằng cách nào đó liên hệ trực tiếp với sức ảnh hưởng của họ. Vấn đề bắt đầu từ lúc số dòng code trở thành chỉ số để đo thành tích
      Khi đó định luật Goodhart sẽ phát huy tác dụng: “Khi một thước đo trở thành mục tiêu, nó sẽ không còn là thước đo tốt nữa”
    • Như ví dụ cho thấy, một trong những lý do khiến số dòng code là chỉ số năng suất tệ là vì nó phản ánh khá rõ quy mô gánh nặng mà người bảo trì codebase sẽ phải gánh
      Theo góc nhìn chỉ số năng suất, code được xem là tài sản, nhưng cách nhìn gần với thực tế hơn là tính năng mới là tài sản còn bản thân code là nợ
  • Chủ đề này lên lại khá thường xuyên. Các thảo luận trước đây gồm có
    https://news.ycombinator.com/item?id=33483165 (2022)
    https://news.ycombinator.com/item?id=26387179 (2021)
    https://news.ycombinator.com/item?id=10734815 (2015)
    https://news.ycombinator.com/item?id=7516671 (2014)
    https://news.ycombinator.com/item?id=4040082 (2012)
    https://news.ycombinator.com/item?id=1114223 (2010)
    https://news.ycombinator.com/item?id=1545452 (2010)

  • Đầu sự nghiệp, tôi từng tối ưu một chương trình C hơn 10 nghìn dòng mà mình được bàn giao xuống còn chưa tới 500 dòng. Đó là một chương trình C gọi SQL tới cơ sở dữ liệu Sybase
    Không phải vì tôi có hiểu biết gì ghê gớm, mà vì tôi đưa ra một giả định đơn giản rằng có lẽ người tiền nhiệm không biết cách dùng hàm, hoặc không biết cách dùng tham số để đưa dữ liệu biến đổi vào truy vấn SQL. Quả đúng vậy: họ viết inline cùng một câu SQL lặp đi lặp lại, chỉ thay vài giá trị mỗi lần
    Tôi viết lại phần gọi SQL thành các lời gọi hàm, và truyền bind variable như tham số của hàm. Phần code inline lặp lại được thay bằng cách lấy các giá trị bind thay đổi từ một mảng rồi gọi hàm trong vòng lặp

  • Tác động lớn nhất đôi khi đến từ việc đặt ra những câu hỏi đơn giản như “X sẽ được xử lý như thế nào?” để rồi khiến người ta không xây dựng thứ gì đó ngay từ đầu
    Nếu thứ đó thậm chí còn chưa có cơ hội hoạt động đúng, thì coi như đã tiết kiệm được toàn bộ chi phí của việc cố gắng tạo ra nó
    Kiểu này không chỉ không thể đo bằng chỉ số số học mà còn dễ làm mất lòng người khác. Dù vậy, vẫn xin dành lời tán dương cho những ai dám làm thế

    • Vì thế tôi dạy những người mới vào rằng hãy giữ vòng lặp đó trong đầu, đừng vừa bắt đầu là đã gõ phím thật nhanh
      Những người xem lập trình giống như đánh máy thật nhanh có điểm tương đồng thú vị với LLM. Họ viết ra cả đống mã không được dùng đến, rồi xóa đi, rồi lại viết tiếp, rồi lại xóa
    • Khi quản lý phần mềm ở một công ty lớn, tôi từng để một hộp bút chì trên bàn
      Khoảng một nửa các yêu cầu thông tin gửi đến bộ phận lúc nào cũng theo kiểu “rất quan trọng, cần ngay lập tức, và có thể kiếm hoặc tiết kiệm rất nhiều tiền”, nhưng câu trả lời hiển nhiên là “Hãy tính bằng những thông tin đã có. Chẳng phải anh đã có máy tính và bảng tính rồi sao. Có cần tôi đưa bút chì không?”
      Tránh để hệ thống phải xử lý X còn tốt hơn là bắt nó xử lý X. Những trường hợp đặc biệt chỉ dùng một hai lần sẽ làm hệ thống phình to ra, và rồi chẳng ai biết những trường hợp đặc biệt hay chương trình đó có tồn tại hay không, hoặc thực sự làm gì. Dù có tài liệu tốt đi nữa thì cũng hiếm ai bỏ thời gian học xem hệ thống làm được gì. Vì vậy phần lớn những tính năng đặc biệt như thế trên thực tế chỉ là lãng phí thời gian
  • Như một thí nghiệm tư duy tương ứng, có thể nghĩ đến tình huống ngược lại. Nếu một quản lý đọc bài này rồi đơn giản quyết định đo lường bằng số dòng mã đã xóa, liệu mọi thứ sẽ tốt hơn hay tệ hơn?

    • Tùy công ty và cách đo, nó có thể bị thao túng dễ hơn. Có thể bảo llama tạo ra đoạn mã trông hợp lý, thêm vào một chút để nó không tạo ra hiệu quả thực sự rồi commit, sau đó xóa đi sau này là xong
      Loại thước đo này nhìn chung gần như vô dụng trừ khi có quy trình review code thật chắc chắn. Trái với điều mọi người ở đây muốn tin, những quy trình như vậy là hiếm. Nhưng nếu đã có review tốt thì hiệu suất kém hay việc thao túng chỉ số cũng sẽ bị phát hiện, nên lý do để đưa loại chỉ số này vào ngay từ đầu lại càng ít đi
    • Có lẽ sẽ tệ hơn đôi chút, nhưng có thể không tồi tệ nhất như người ta nghĩ. Vì trong ngành vốn đã tồn tại xung lực thiển cận theo hướng đó ở mức tương tự
      Ví dụ như ý tưởng cũ kỹ rằng hãy loại bỏ toàn bộ kỹ sư phần mềm và những đoạn văn bản mã khó hiểu, thay bằng việc để quản lý sản phẩm vẽ các loại sơ đồ hay lưu đồ đặc biệt để tạo ra sản phẩm “low-code” hoặc “no-code”
    • Mọi chỉ số dựa trên số dòng đều đáng ngờ, nhưng ΔSLOC có lẽ là loại đỡ tệ hơn trong số đó
      Đếm riêng số dòng thêm vào và số dòng xóa đi, thì một bản vá +50,-150 sẽ được tính là 200 ΔSLOC
      Đây không phải thước đo tốt để đánh giá năng suất, đặc biệt là nếu dùng riêng lẻ thì càng không. Dù vậy, như một chỉ số kiểu tính nhẩm để ước lượng mức độ thay đổi thì nó vẫn hợp lý. Việc một lập trình viên có ΔSLOC cao hơn có năng suất hơn đồng nghiệp có ΔSLOC bằng 0 trong 1–2 tuần hay không còn tùy người đồng nghiệp đó đang làm gì, nhưng ít nhất có thể chắc chắn rằng trong khoảng thời gian đo đó, người thứ nhất đã thay đổi codebase nhiều hơn
    • Tệ hơn. Biến toàn bộ codebase thành đối tượng của code golf là điều không mong muốn
    • Chắc chắn sẽ không có tính năng mới
      Nếu sản phẩm đã “hoàn thiện” thì có thể vẫn như cũ hoặc tốt hơn. Nếu không thì các thay đổi số dòng mã âm sẽ không thể đi đến mức triển khai
      Nhưng hầu hết sản phẩm đều tiếp tục tiến hóa. Vì thế chúng ta mới có thể ở lại cùng một dự án trong nhiều năm, và những đóng góp chỉ toàn xóa bỏ cuối cùng sẽ chẳng bổ sung được gì
  • Câu chuyện thật sự là có những lúc khi bắt đầu một dự án, ta không biết chính xác mình đang đi về đâu
    Trong quá trình làm, ta hiểu bài toán và câu trả lời mong muốn rõ hơn rất nhiều, rồi từ đó có thể bóc bỏ những khối lớn để thay bằng thứ nhỏ hơn và tốt hơn
    Và cũng không được quên rằng những người này phải nhét mọi thứ, kể cả mã assembly, vào trong ROM 64KB, với -2000 dòng mã. Áp lực phải làm cho nó nhỏ hơn là cực kỳ lớn

  • Bill Atkinson, người nổi tiếng với Atkinson Dither. https://beyondloom.com/blog/dither.html

    • Bill Atkinson là người tạo ra QuickDraw, thư viện đồ họa đặt nền tảng cho UI của Lisa và Mac, cùng với MacPaint và HyperCard
      Trong quá trình đó, ông liên tục phải phát minh ra những cách mới để giao diện người dùng vận hành, cũng như cách viết phần mềm để giải quyết chúng. Ông tối ưu hóa đồng thời để “chạy nhanh trên phần cứng Mac” mà vẫn “mang lại trải nghiệm người dùng tuyệt vời”, và sự cộng hưởng đó đã để lại dấu ấn của ông lên toàn bộ thẩm mỹ của những chiếc Mac đen trắng thời kỳ đầu. Kiểu dithering đó cũng là một ví dụ khác về sự kết hợp giữa thiên tài thuật toán và cảm quan thẩm mỹ
      Cảm quan này cũng thể hiện ở những thứ như đường viền chọn kiểu “marching ants” (https://en.wikipedia.org/wiki/Marching_ants). Tương tự, rất nhiều phản hồi trong UI Mac cổ điển được thể hiện bằng cách đảo ngược pixel. Việc chọn văn bản, làm nổi bật menu, cách nút bấm hiển thị khi đang giữ nút chuột, hay đường viền khi kéo cửa sổ đều như vậy, và vẽ chồng lên bằng chế độ XOR là một cách rất phù hợp để tạo ra các hiệu ứng này
      Cách QuickDraw kết hợp các công cụ như vậy đã dẫn tới việc cuộc đối thoại nổi tiếng về hình chữ nhật bo góc với Steve Jobs (https://www.folklore.org/Round_Rects_Are_Everywhere.html) thực sự kết tinh thành kết quả là trong QuickDraw, việc vẽ hình chữ nhật bo góc trở nên dễ như vẽ hình chữ nhật thường, và khiến các hình bo góc xuất hiện khắp hệ điều hành
      Thành công của UI Mac không chỉ vì nó trông đẹp. Một phần rất lớn là vì Bill Atkinson đã tạo ra một bộ công cụ nhỏ nhưng thông minh, giúp việc làm ra thứ gì đó đẹp mắt trở nên dễ dàng
      Những biểu tượng tuyệt vời của Susan Kare cũng sẽ không được nhớ đến đầy trìu mến như vậy nếu Bill không tạo ra các công cụ cho phép dễ dàng đưa bitmap mask 32x32 pixel vào UI và đảo ngược chúng khi được nhấp
  • Bài học là dù có thông minh đến mức Einstein thì cuối cùng vẫn là một nhân viên, và với tư cách nhân viên thì phải làm những việc một nhân viên cần làm

    • Nếu Einstein bị áp lực bởi KPI thì có lẽ chúng ta đã chẳng bao giờ nghe đến tên ông
  • Tôi chưa bao giờ hiểu vì sao khi nói về số dòng mã mà mọi người viết, họ luôn tính theo kiểu “số dòng thêm vào - số dòng xóa đi”
    Việc tôi chạy 10km rồi quay lại điểm xuất phát không có nghĩa là tôi đã chạy 0km

    • Có lẽ cũng một phần vì các công cụ diff ngớ ngẩn có thể ghi nhận cả việc di chuyển dòng qua lại thành khác biệt lớn, dù thay đổi về chức năng rất hạn chế
      Ví dụ như đổi từ dạng if cond { ... return; } ... sang if cond { ... return; } else { .... }
      Nhưng dẫu vậy thì cách giải thích đó cũng không bao quát được toàn bộ