Trích dẫn của Torvalds về lập trình viên giỏi [đã đóng]


238

Tình cờ tôi đã vấp phải câu nói sau đây của Linus Torvalds:

"Các lập trình viên xấu lo lắng về mã. Các lập trình viên giỏi lo lắng về cấu trúc dữ liệu và các mối quan hệ của họ."

Tôi đã nghĩ về nó trong vài ngày qua và tôi vẫn còn bối rối (có lẽ đó không phải là một dấu hiệu tốt), do đó tôi muốn thảo luận về những điều sau đây:

  • Điều gì giải thích điều này có thể / có ý nghĩa?
  • Những gì có thể được áp dụng / học hỏi từ nó?

18
Tôi nghĩ rằng câu hỏi này có thể có nhiều câu trả lời có giá trị như nhau. Nhưng dù sao đó cũng là một câu hỏi hay. Tôi thích câu nói đó. Nó diễn tả lý do tại sao tôi không hiểu các lập trình viên lo lắng về việc chuyển đổi ngôn ngữ. Nó hiếm khi là ngôn ngữ quan trọng trong một chương trình, đó là cấu trúc dữ liệu và cách chúng liên quan.
Ryan Kinal

5
Có lẽ nếu bạn dành thời gian làm cho các cấu trúc dữ liệu trở nên "thanh lịch" thì mã không cần phải được cấu thành để xử lý các cấu trúc dữ liệu này? Tôi có lẽ quá ngu ngốc để thực sự biết ý nghĩa của trích dẫn của Torvalds. :}
lập trình viên

3
@RyanKinal Nhưng tất nhiên ngôn ngữ có vấn đề , bởi vì nó giúp dễ dàng xử lý và suy nghĩ về các cấu trúc dữ liệu nhất định. Ví dụ, hãy suy nghĩ về tất cả các ngôn ngữ chuyên về Phân tích LISt hoặc các ngôn ngữ có hỗ trợ riêng cho các cấu trúc dữ liệu phải được hack sang các ngôn ngữ khác, (các bộ và các mảng thưa thớt xuất hiện).
kojiro

83
Nhân tiện, Torvalds không đơn độc trong việc này: "Hãy cho tôi xem sơ đồ của bạn và che giấu các bảng của bạn, và tôi sẽ tiếp tục bị làm cho bí ẩn. Hãy cho tôi xem các bảng của bạn, và tôi thường sẽ không cần sơ đồ của bạn; " - Fred Brooks, Người đàn ông huyền thoại. "Cho tôi xem mã của bạn và che giấu các cấu trúc dữ liệu của bạn, và tôi sẽ tiếp tục bị bí ẩn. Hãy cho tôi xem cấu trúc dữ liệu của bạn và tôi thường sẽ không cần mã của bạn; điều đó sẽ rõ ràng." và "Cấu trúc dữ liệu thông minh và mã câm hoạt động tốt hơn rất nhiều so với cách khác." - Eric S. Raymond, Nhà thờ và Chợ.
Jörg W Mittag

4
Điều này giải thích tại sao nhân Linux là một mớ hỗn độn :)
l1x

Câu trả lời:


326

Có thể giúp xem xét những gì Torvalds đã nói ngay trước đó:

git thực sự có một thiết kế đơn giản, với các cấu trúc dữ liệu ổn định và hợp lý. Trên thực tế, tôi là một người ủng hộ rất lớn trong việc thiết kế mã của bạn xung quanh dữ liệu, chứ không phải là cách khác, và tôi nghĩ đó là một trong những lý do git đã khá thành công [trên thực tế, tôi sẽ cho rằng sự khác biệt giữa một lập trình viên tồi và một người giỏi là liệu anh ta xem mã của mình hay cấu trúc dữ liệu của mình quan trọng hơn.

Những gì ông đang nói là các cấu trúc dữ liệu tốt làm cho mã rất dễ thiết kế và bảo trì, trong khi mã tốt nhất không thể bù cho các cấu trúc dữ liệu kém.

Nếu bạn đang tự hỏi về ví dụ git, rất nhiều hệ thống kiểm soát phiên bản thay đổi định dạng dữ liệu tương đối thường xuyên để hỗ trợ các tính năng mới. Khi bạn nâng cấp để có được tính năng mới, bạn thường phải chạy một số loại công cụ để chuyển đổi cơ sở dữ liệu.

Ví dụ, khi DVCS lần đầu tiên trở nên phổ biến, nhiều người không thể hiểu được điều gì về mô hình phân tán đã làm cho sự hợp nhất trở nên sạch sẽ hơn nhiều so với kiểm soát phiên bản tập trung. Câu trả lời là hoàn toàn không có gì, ngoại trừ các cấu trúc dữ liệu phân tán phải tốt hơn nhiều để có hy vọng làm việc. Tôi tin rằng các thuật toán hợp nhất tập trung đã bắt kịp, nhưng phải mất khá nhiều thời gian vì cấu trúc dữ liệu cũ của chúng đã hạn chế các loại thuật toán mà chúng có thể sử dụng và cấu trúc dữ liệu mới đã phá vỡ rất nhiều mã hiện có.

Ngược lại, mặc dù có sự bùng nổ của các tính năng trong git, các cấu trúc dữ liệu cơ bản của nó hầu như không thay đổi. Lo lắng về cấu trúc dữ liệu trước tiên và mã của bạn sẽ tự nhiên sạch hơn.


25
mã tốt nhất không thể bù cho cấu trúc dữ liệu kém hấp dẫn là sự thật
Conrad Frix

5
Anh ấy nói từ quan điểm của các lập trình viên thực hiện thay đổi để git chính nó. Quan điểm của người dùng cuối hoàn toàn trực giao với cuộc thảo luận này, ngoài việc tạo mã dễ bảo trì để tạo ra ít lỗi hơn và bổ sung tính năng nhanh hơn.
Karl Bielefeldt

2
@James: Anh ấy nói rằng phần mềm tốt hơn (do đó dễ sử dụng hơn và được nhiều người sử dụng hơn) vì cấu trúc dữ liệu tốt hơn. Tất nhiên bạn không cần biết về cấu trúc dữ liệu của phần mềm bạn sử dụng, nhưng bạn quan tâm đến chúng, một cách gián tiếp, ngay cả khi bạn không nhận ra nó, bởi vì cấu trúc dữ liệu là thứ thúc đẩy những điều bạn nhận ra bạn quan tâm
ruakh

1
+1. Câu trả lời này đặt bối cảnh vào một tuyên bố có thể được hiểu là có nghĩa gì đó rất khác. Bất cứ ai đã đọc 5000 dòng quái dị của một tập tin đều biết chính xác ý tôi là gì.
riwalk

20
"Lo lắng về cấu trúc dữ liệu trước tiên và mã của bạn sẽ tự nhiên sạch hơn.": Chính khách La Mã Cato ( en.wikipedia.org/wiki/Cato_the_Elder ) đã từng nói "Rem tene, verba sequentur" = " tâm trí của bạn, những từ sẽ theo tự nhiên ". Điều tương tự với lập trình: hiểu cấu trúc dữ liệu và thiết kế trước, mã thực tế sẽ tự theo sau.
Giorgio

60

Thuật toán + Cấu trúc dữ liệu = Chương trình

Mã chỉ là cách để thể hiện các thuật toán và cấu trúc dữ liệu.


Phiên bản mới nhất ethoberon.ethz.ch/WirthPubl/AD.pdf
dchest

Điều này đúng cho lập trình thủ tục; trong OOP thì hơi khác một chút.
m3th0dman

3
Nó không phải về cơ bản bất kỳ khác nhau. Bạn có dữ liệu và thực hiện các thao tác trên đó. Biến thành viên và phương thức. Chính xác là điều tương tự. Toàn bộ bản chất của điện toán kể từ những năm 50 đã được xây dựng dựa trên quy tắc rất đơn giản đó là các chương trình bao gồm các thuật toán sửa đổi cấu trúc dữ liệu và nó vẫn giữ đúng 60 năm sau. Bạn cũng có thể coi các chương trình là các chức năng . Họ lấy đầu vào mà họ hoạt động để sản xuất đầu ra . Chính xác như các hàm toán học làm.
zxcdw

31

Câu nói này rất quen thuộc với một trong những quy tắc trong "Nghệ thuật lập trình Unix", sở trường của Torvalds là người tạo ra Linux. Cuốn sách được đặt trực tuyến tại đây

Từ cuốn sách là câu trích dẫn sau đây cho thấy những gì Torvalds đang nói.

Quy tắc đại diện: Gấp kiến ​​thức vào dữ liệu để logic chương trình có thể ngu ngốc và mạnh mẽ.

Ngay cả logic thủ tục đơn giản nhất cũng khó để con người xác minh, nhưng các cấu trúc dữ liệu khá phức tạp khá dễ để mô hình hóa và lý do. Để thấy điều này, hãy so sánh khả năng biểu cảm và khả năng giải thích của sơ đồ (nói) một cây con trỏ năm mươi nút với một sơ đồ của chương trình năm mươi dòng. Hoặc, so sánh một trình khởi tạo mảng biểu thị bảng chuyển đổi với câu lệnh chuyển đổi tương đương. Sự khác biệt về tính minh bạch và rõ ràng là rất lớn. Xem Quy tắc 5 của Rob Pike.

Dữ liệu dễ điều khiển hơn logic chương trình. Nó theo sau khi bạn thấy sự lựa chọn giữa độ phức tạp trong cấu trúc dữ liệu và độ phức tạp trong mã, hãy chọn cái trước. Hơn nữa: trong quá trình phát triển một thiết kế, bạn nên chủ động tìm cách chuyển sự phức tạp từ mã sang dữ liệu.

Cộng đồng Unix không bắt nguồn cái nhìn sâu sắc này, nhưng rất nhiều mã Unix hiển thị ảnh hưởng của nó. Đặc biệt, cơ sở của ngôn ngữ C khi thao túng con trỏ, đặc biệt, đã khuyến khích sử dụng các cấu trúc tham chiếu được sửa đổi động ở tất cả các cấp mã hóa từ kernel trở lên. Các con trỏ đơn giản đuổi theo các cấu trúc như vậy thường xuyên thực hiện các nhiệm vụ mà việc triển khai bằng các ngôn ngữ khác thay vào đó sẽ phải thực hiện các quy trình phức tạp hơn.


Tôi cũng nhớ điều này!
Jesvin Jose

1
OTOH, nhìn vào bất kỳ câu hỏi StackOverflow về int**. Điều đó sẽ thuyết phục bạn rằng dữ liệu trên thực tế KHÔNG rõ ràng; nó chỉ trở nên như vậy bằng cách gắn ý nghĩa với dữ liệu. Và ý nghĩa đó là trong mã.
MSalters

29

Mã rất dễ, đó là logic đằng sau mã phức tạp.

Nếu bạn lo lắng về mã có nghĩa là bạn chưa có được những điều cơ bản đó và có khả năng bị mất trên phức tạp (nghĩa là cấu trúc dữ liệu và các mối quan hệ của chúng).


17
Heh, tôi tự hỏi nếu thế hệ lập trình viên tiếp theo sẽ hỏi: "Morons đã từng nói Code is easy, it's the logic behind the code that is complex, ý anh ta là gì?"
yannis

36
@YannisRizos Điều đó sẽ đặc biệt khó hiểu khi mọi người không chắc chắn liệu nó được nói bởi những người có đạo đức hay một người duy nhất tên là Morons.
KChaloux

14

Để mở rộng câu trả lời của Morons một chút, ý tưởng là việc hiểu các chi tiết của mã (cú pháp và ở mức độ thấp hơn, cấu trúc / bố cục) đủ dễ để chúng tôi xây dựng các công cụ có thể làm điều đó. Trình biên dịch có thể hiểu tất cả những gì cần biết về mã để biến nó thành một chương trình / thư viện hoạt động. Nhưng một trình biên dịch thực sự không thể giải quyết các vấn đề mà các lập trình viên làm.

Bạn có thể tiến thêm một bước nữa và nói "nhưng chúng tôi có các chương trình tạo mã", nhưng mã mà nó tạo ra dựa trên một số loại đầu vào hầu như luôn được xây dựng bằng tay.

Vì vậy, bất cứ con đường nào bạn đi để lấy mã: có thể thông qua một số loại cấu hình hoặc đầu vào khác sau đó tạo mã thông qua một công cụ hoặc nếu bạn viết nó từ đầu, đó không phải là mã quan trọng. Đó là suy nghĩ phê phán của tất cả các phần được yêu cầu để có được mã đó là vấn đề. Trong thế giới của Linus, phần lớn là các cấu trúc dữ liệu và các mối quan hệ, mặc dù trong các lĩnh vực khác, nó có thể là các phần khác. Nhưng trong bối cảnh này, Linus chỉ nói "Tôi không quan tâm nếu bạn có thể viết mã, tôi quan tâm rằng bạn có thể hiểu những điều sẽ giải quyết các vấn đề tôi đang giải quyết".


Mỗi lập trình viên sử dụng các chương trình tạo mã. Chúng thường được gọi là "trình biên dịch", đôi khi kết hợp với "trình liên kết". Họ lấy một đầu vào (tương đối) có thể đọc được và có thể ghi được của con người, thường được cung cấp (nhưng không phải luôn luôn) được cung cấp theo một số định dạng văn bản và biến nó thành dữ liệu mà máy tính có thể hiểu là hướng dẫn và thực thi.
một CVn

13

Linus có nghĩa là:

Chỉ cho tôi sơ đồ của bạn [mã] và che giấu các bảng [lược đồ] của bạn, và tôi sẽ tiếp tục được giải mã; cho tôi xem bảng của bạn [lược đồ] và tôi thường sẽ không cần sơ đồ của bạn [mã]: chúng sẽ rõ ràng.

- Fred Brooks, "Tháng huyền thoại", ch 9.


12

Tôi nghĩ rằng anh ta nói rằng thiết kế cấp cao tổng thể (cấu trúc dữ liệu và các mối quan hệ của họ) quan trọng hơn nhiều so với các chi tiết triển khai (mã). Tôi nghĩ rằng ông đánh giá cao các lập trình viên có thể thiết kế một hệ thống hơn những người chỉ có thể tập trung vào các chi tiết của một hệ thống.

Cả hai đều quan trọng, nhưng tôi đồng ý rằng nhìn chung sẽ tốt hơn nhiều để có được bức tranh lớn và có vấn đề với các chi tiết hơn so với cách khác. Điều này liên quan chặt chẽ đến những gì tôi đã cố gắng bày tỏ về việc chia nhỏ các chức năng lớn thành những người nhỏ bé .


+1: Tôi đồng ý với bạn. Một khía cạnh khác là thường các lập trình viên lo lắng hơn về tính năng ngôn ngữ tuyệt vời mà họ sẽ sử dụng, thay vì tập trung vào cấu trúc dữ liệu và thuật toán của họ và về cách viết chúng ra một cách đơn giản, rõ ràng.
Giorgio

Tôi cũng đồng ý. Thực tế là việc thay đổi các đoạn mã bị cô lập rất dễ dàng, nhưng khó thay đổi cấu trúc dữ liệu hoặc giao diện giữa các đoạn mã (vì các loại thay đổi này có thể ảnh hưởng đến nhiều thứ thay vì chỉ một điều).
Brendan

5

Chà, tôi không thể hoàn toàn đồng ý, vì bạn phải lo lắng về tất cả. Và đối với vấn đề đó, một trong những điều tôi yêu thích về lập trình là các công tắc thông qua các mức độ trừu tượng và kích thước khác nhau nhanh chóng chuyển từ suy nghĩ về nano giây sang suy nghĩ về tháng và quay lại.

Tuy nhiên, những thứ cao hơn là quan trọng hơn.

Nếu tôi có một lỗ hổng trong một vài vấn đề gây ra hành vi không chính xác, có lẽ không quá khó để khắc phục. Nếu nó làm cho nó hoạt động kém, nó có thể thậm chí không quan trọng.

Nếu tôi có một lỗ hổng trong việc lựa chọn cấu trúc dữ liệu trong một hệ thống phụ, điều đó gây ra hành vi không chính xác, thì đó là một vấn đề lớn hơn và khó khắc phục hơn. Nếu nó khiến nó hoạt động kém, nó có thể khá nghiêm trọng hoặc có thể chịu đựng được, vẫn kém tốt hơn so với cách tiếp cận đối thủ.

Nếu tôi có một lỗ hổng trong mối quan hệ giữa các cấu trúc dữ liệu quan trọng nhất trong một ứng dụng, điều đó gây ra hành vi không chính xác, thì tôi đã thiết kế lại lớn trước mặt tôi. Nếu nó khiến nó hoạt động kém, nó có thể tệ đến mức gần như sẽ tốt hơn nếu nó cư xử sai.

nó sẽ là điều khiến cho việc tìm kiếm những vấn đề ở cấp độ thấp trở nên khó khăn (việc sửa các lỗi cấp độ thấp thường rất dễ dàng, đó là việc tìm ra chúng có thể khó khăn).

Các công cụ cấp thấp quan trọng, và tầm quan trọng còn lại của nó thường được đánh giá thấp, nhưng nó nhạt so với các công cụ lớn.


2

Một người biết mã nhìn thấy "cây". Nhưng ai đó hiểu cấu trúc dữ liệu sẽ thấy "khu rừng". Do đó, một lập trình viên giỏi sẽ tập trung nhiều vào cấu trúc dữ liệu hơn là mã.


2
Nhưng việc tập trung vào rừng hoặc cây để loại trừ người khác có thể gây bất lợi, vì vậy tôi không nghĩ sự tương tự này phù hợp.
kojiro

1
@kojiro: Trong biểu thức không thể thấy rừng cho cây , người ta cho rằng ai đó có thể nhìn thấy rừng cũng sẽ thấy cây (xem en.wiktionary.org/wiki/see_the_forest_for_the_trees ). Vì vậy, tôi nghĩ rằng đó là một tương tự tốt ở đây.
Treb

2

Biết làm thế nào dữ liệu sẽ chảy là tất cả quan trọng. Biết lưu lượng yêu cầu bạn thiết kế cấu trúc dữ liệu tốt.

Nếu bạn quay trở lại hai mươi năm, đây là một trong những điểm bán hàng lớn cho cách tiếp cận hướng đối tượng bằng cách sử dụng SmallTalk, C ++ hoặc Java. Cú hích lớn - ít nhất là với C ++ vì đó là điều tôi học được đầu tiên - là thiết kế lớp và phương thức, và sau đó mọi thứ khác sẽ rơi vào vị trí.

Linus chắc chắn đã nói về các thuật ngữ rộng hơn, nhưng các cấu trúc dữ liệu được thiết kế kém thường đòi hỏi phải làm lại mã, điều này cũng có thể dẫn đến các vấn đề khác.


2

Những gì có thể được áp dụng / học hỏi từ nó?

Nếu tôi có thể, kinh nghiệm của tôi trong vài tuần qua. Các cuộc thảo luận trước đã làm rõ câu trả lời cho câu hỏi của tôi: "tôi đã học được gì?"

Tôi viết lại một số mã và phản ánh kết quả mà tôi vẫn thấy và nói "cấu trúc, cấu trúc ..." là lý do tại sao có sự khác biệt lớn như vậy. Bây giờ tôi thấy rằng chính cấu trúc dữ liệu đã tạo ra sự khác biệt. Và tôi có nghĩa là tất cả .

  • Khi kiểm tra giao hàng ban đầu của tôi, nhà phân tích kinh doanh nói với tôi rằng nó không hoạt động. Chúng tôi đã nói "thêm 30 ngày" nhưng ý nghĩa của chúng tôi là "thêm một tháng" ( ngày trong ngày kết quả không thay đổi). Thêm năm rời rạc, tháng, ngày; không phải là 540 ngày trong 18 tháng chẳng hạn.

  • Cách khắc phục: trong cấu trúc dữ liệu thay thế một số nguyên bằng một lớp chứa nhiều số nguyên, việc thay đổi cấu trúc của nó bị giới hạn trong một phương thức. Thay đổi báo cáo số học ngày thực tế - tất cả 2 trong số chúng.

Phần thưởng

  • Việc triển khai mới có nhiều chức năng hơn nhưng mã thuật toán ngắn hơn và rõ ràng đơn giản hơn.

Trong Sửa lỗi hành vi / kết quả mã:

  • Tôi đã thay đổi cấu trúc dữ liệu, không phải thuật toán.
  • KHÔNG kiểm soát logic đã được chạm vào bất cứ nơi nào trong mã.
  • Không có API nào được thay đổi.
  • Lớp nhà máy cấu trúc dữ liệu không thay đổi chút nào.

1

Tôi muốn tưởng tượng một đội ngũ thủ thư rất thông minh trong một thư viện được làm đẹp với hàng triệu cuốn sách ngẫu nhiên và xuất sắc, nó sẽ khá điên rồ.


1

Không thể đồng ý nhiều hơn với Linus. Tập trung vào dữ liệu giúp chắt lọc rất nhiều giải pháp đơn giản và linh hoạt cho một vấn đề nhất định. Bản thân Git là một ví dụ minh chứng - cung cấp rất nhiều tính năng được hỗ trợ trong những năm phát triển, cấu trúc dữ liệu cốt lõi không thay đổi nhiều. Đó là phép màu! --2c


0

Tôi đã thấy đây là nhiều lĩnh vực.

Hãy suy nghĩ về phân tích kinh doanh ... Giả sử bạn đang phân tích cách tốt nhất để hỗ trợ Marketing tại một công ty sản phẩm tiêu dùng như Colgate. Nếu bạn bắt đầu với các cửa sổ ưa thích hoặc công nghệ mới nhất, bạn sẽ không giúp doanh nghiệp nhiều như bạn nghĩ thông qua nhu cầu dữ liệu của doanh nghiệp trước, và sau đó lo lắng về việc trình bày sau. Mô hình dữ liệu tồn tại lâu hơn phần mềm trình bày.

Xem xét làm một trang web. Trước tiên, tốt hơn là nghĩ về những gì bạn muốn hiển thị (HTML) và lo lắng về phong cách (CSS) và kịch bản (chọn công cụ của bạn) sau.

Điều này không có nghĩa là mã hóa cũng không quan trọng. Bạn cần kỹ năng lập trình để có được những gì bạn cần cuối cùng. Đó là dữ liệu là nền tảng. Một mô hình dữ liệu kém phản ánh một mô hình kinh doanh quá phức tạp hoặc không suy nghĩ.


0

Tôi thấy mình viết các hàm mới và cập nhật các hàm hiện có thường xuyên hơn nhiều so với việc phải thêm các cột hoặc bảng mới vào lược đồ cơ sở dữ liệu của tôi. Điều này có lẽ đúng với tất cả các hệ thống được thiết kế tốt. Nếu bạn cần thay đổi lược đồ của mình mỗi lần bạn cần thay đổi mã, thì đó là một dấu hiệu rõ ràng bạn là một nhà phát triển rất tệ.

chất lượng của chỉ báo mã = ​​[thay đổi mã] / [thay đổi lược đồ cơ sở dữ liệu]

"Cho tôi xem sơ đồ của bạn và che giấu các bảng của bạn, và tôi sẽ tiếp tục bị làm cho bí ẩn. Hãy cho tôi xem các bảng của bạn, và tôi thường sẽ không cần sơ đồ của bạn; chúng sẽ rõ ràng." (Fred Brooks)


-2

Có vẻ như ý tưởng này có nhiều cách hiểu khác nhau trong các loại lập trình khác nhau. Nó đúng cho phát triển hệ thống và cũng đúng cho phát triển doanh nghiệp. Ví dụ, người ta có thể lập luận rằng sự thay đổi mạnh về trọng tâm đối với miền trong thiết kế hướng theo miền giống như sự tập trung vào các cấu trúc dữ liệu và các mối quan hệ.


-4

Đây là cách giải thích của tôi về nó: Bạn sử dụng mã để tạo cấu trúc dữ liệu, vì vậy trọng tâm phải là cái sau. Nó giống như xây dựng một cây cầu - bạn nên đặt ra để thiết kế một cấu trúc vững chắc chứ không phải là một cái nhìn hấp dẫn. Nó chỉ xảy ra rằng các cấu trúc dữ liệu được viết tốt và các cây cầu trông giống như kết quả của các thiết kế hiệu quả của chúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.