Làm thế nào có sự gia tăng về sự phức tạp của các hệ thống ảnh hưởng đến các thế hệ lập trình viên kế tiếp nhau?


127

Là một lập trình viên "mới" (lần đầu tiên tôi viết một dòng mã vào năm 2009), tôi đã nhận thấy việc tạo ra một chương trình thể hiện các yếu tố khá phức tạp ngày nay với những thứ như .NET framework chẳng hạn. Tạo một giao diện trực quan hoặc sắp xếp danh sách có thể được thực hiện với rất ít lệnh bây giờ.

Khi tôi học lập trình, tôi cũng học song song lý thuyết điện toán. Những thứ như sắp xếp thuật toán, nguyên tắc về cách phần cứng hoạt động cùng nhau, đại số boolean và máy trạng thái hữu hạn. Nhưng tôi nhận thấy nếu tôi từng muốn thử nghiệm một số nguyên tắc rất cơ bản mà tôi đã học về lý thuyết, thì việc bắt đầu luôn khó khăn hơn rất nhiều vì rất nhiều công nghệ bị che khuất bởi những thứ như thư viện, khung và HĐH.

Việc tạo ra một chương trình tiết kiệm bộ nhớ được yêu cầu 40/50 năm trước vì không đủ bộ nhớ và nó rất tốn kém, vì vậy hầu hết các lập trình viên đều chú ý đến các loại dữ liệu và cách xử lý các hướng dẫn của bộ xử lý. Ngày nay, một số người có thể lập luận rằng do sức mạnh xử lý tăng lên và bộ nhớ khả dụng, những lo ngại đó không phải là ưu tiên hàng đầu.

Câu hỏi của tôi là nếu các lập trình viên lớn tuổi xem những đổi mới như thế này là một ơn trời hoặc một lớp bổ sung để trừu tượng hóa, và tại sao họ có thể nghĩ như vậy? Và các lập trình viên trẻ có lợi hơn khi học lập trình cấp thấp TRƯỚC KHI khám phá các lĩnh vực của các thư viện mở rộng không? Nếu vậy thì tại sao?


24
Bài viết của Joel Spolsky từ năm 2002 có liên quan: joelonsoftware.com/articles/LeakyAbstrilities.html Là cụm từ / công thức, tuy nhiên, câu hỏi này cuối cùng có thể được xem là chủ yếu dựa trên quan điểm.
BrianH

Tôi than thở về việc thiếu các tùy chọn đơn giản hơn để khám phá các kỹ thuật lập trình rất cơ bản.
GrandmasterB

1
Điều này có liên quan. Sắp xếp (Ý tôi là, tôi hy vọng hình ảnh đó là một trò đùa, nhưng với một số điều xảy ra với StackOverflow ...)
Izkata

1
Nó có ưu và nhược điểm của nó. Nó mở ra thế giới lập trình cho rất nhiều lập trình viên mới, những người không cần kỹ năng cao để thành công - trái với những gì một số người có thể nói, đó là một điều tốt. Và chúng tôi vẫn đang viết các chương trình hiệu quả, không bao giờ thay đổi - chỉ là các mục tiêu đã thay đổi. Lưu một byte vào một năm trong ngày không còn là điều tốt - sự khác biệt về bộ nhớ thường không có khả năng tạo ra sự khác biệt và sử dụng ví dụ. hai byte là linh hoạt hơn và bằng chứng trong tương lai. Chi phí lập trình viên so với chi phí SW và CTNH cũng là một yếu tố quan trọng. Nhu cầu về phần mềm mới là rất lớn. Coders rất ít.
Luaan

1
40/50 năm thời gian là sai. Lập trình hiệu quả bộ nhớ vẫn cực kỳ quan trọng trong Windows 16 bit (ít hơn 20 năm trước) và (không may) trong hầu hết các nhúng / robot hiện nay.
david.pfx

Câu trả lời:


174

nó chỉ không cần thiết vì tăng sức mạnh xử lý và bộ nhớ khả dụng.

Có bộ nhớ rẻ, ổ đĩa khổng lồ và bộ xử lý nhanh không phải là điều duy nhất giải phóng mọi người khỏi nhu cầu ám ảnh qua từng byte và chu kỳ. Trình biên dịch bây giờ rất xa, tốt hơn nhiều so với con người trong việc tạo ra mã được tối ưu hóa cao khi nó quan trọng.

Hơn nữa, chúng ta đừng quên những gì chúng ta thực sự đang cố gắng tối ưu hóa, đó là giá trị được tạo ra cho một chi phí nhất định. Lập trình viên đắt hơn nhiều so với máy móc. Bất cứ điều gì chúng tôi làm điều đó làm cho các lập trình viên sản xuất các chương trình làm việc, chính xác, mạnh mẽ, đầy đủ tính năng nhanh hơn và rẻ hơn dẫn đến việc tạo ra nhiều giá trị hơn trên thế giới.

Câu hỏi của tôi là mọi người cảm thấy thế nào về việc "che giấu" các yếu tố cấp thấp hơn này. Bạn có lập trình viên lớn tuổi xem nó như một ơn trời hay một lớp không cần thiết để vượt qua?

Nó là hoàn toàn cần thiết để có được bất kỳ công việc được thực hiện. Tôi viết máy phân tích mã để kiếm sống; nếu tôi phải lo lắng về việc phân bổ đăng ký hoặc lập lịch xử lý hoặc bất kỳ hàng triệu chi tiết nào khác thì tôi sẽ không dành thời gian để sửa lỗi, xem xét báo cáo hiệu suất, thêm tính năng, v.v.

Tất cả các chương trình là về trừu tượng hóa lớp bên dưới bạn để tạo ra một lớp có giá trị hơn trên đầu trang của nó. Nếu bạn thực hiện "sơ đồ bánh lớp" hiển thị tất cả các hệ thống con và cách chúng được xây dựng trên nhau, bạn sẽ thấy rằng có hàng tá lớp giữa phần cứng và trải nghiệm người dùng. Tôi nghĩ trong sơ đồ bánh lớp Windows có khoảng 60 cấp hệ thống con cần thiết giữa phần cứng thô và khả năng thực thi "hello world" trong C #.

Bạn có nghĩ rằng các lập trình viên trẻ tuổi sẽ có lợi hơn khi học lập trình cấp thấp TRƯỚC KHI khám phá các lĩnh vực của các thư viện mở rộng?

Bạn nhấn mạnh vào TRƯỚC, vì vậy tôi phải trả lời câu hỏi của bạn theo cách tiêu cực. Tôi đang giúp một người bạn 12 tuổi học lập trình ngay bây giờ và bạn nên tin rằng tôi đang bắt đầu họ trong Trình biên dịch chế biến chứ không phải trình biên dịch x86. Nếu bạn bắt đầu một lập trình viên trẻ trong một cái gì đó giống như Processing.jshọ sẽ viết các trò chơi bắn súng của riêng họ trong khoảng tám giờ. Nếu bạn khởi động chúng trong trình biên dịch chương trình, chúng sẽ nhân ba số với nhau trong khoảng tám giờ. Mà bạn nghĩ có nhiều khả năng thu hút sự quan tâm của một lập trình viên trẻ?

Bây giờ nếu câu hỏi là "các lập trình viên hiểu lớp n của bánh có được lợi gì từ việc hiểu lớp n - 1 không?" câu trả lời là có, nhưng không phụ thuộc vào tuổi tác hay kinh nghiệm; luôn luôn là trường hợp bạn có thể cải thiện chương trình cấp cao hơn bằng cách hiểu rõ hơn các khái niệm trừu tượng cơ bản.


12
Trích dẫn thú vị +1: Số Dunbars là một ví dụ điển hình (có những người khác) về các chỉ tiêu năng lực nhận thức được nghiên cứu có thể được nhìn thấy qua nhiều người cho thấy rằng chúng ta có một không gian tinh thần cố định. Trừu tượng hóa nhiều thứ thành khái quát hóa số ít là cách duy nhất để chúng ta có thể tăng cường số lượng mọi thứ trong không gian tinh thần của chúng ta, và đó là điều mà lập trình cấp cao hơn tìm cách tận dụng.
Jimmy Hoffa

18
@Euphoric: Câu hỏi của bạn có ý nghĩa nhưng bạn dừng lại ở đâu? Giả sử tôi nói "tốt, thay vì học Treatment.js, hãy học cách viết trò chơi video trong C ++ bằng DirectX". Được rồi Bây giờ điều gì ngăn bạn nói "không phải nó sẽ tạo ra vấn đề nếu họ muốn làm một cái gì đó ít trừu tượng hơn?" và vì vậy có lẽ chúng ta muốn bắt đầu với cách viết trình điều khiển card đồ họa. Nhưng sau đó bạn lại đặt câu hỏi và trước khi bạn biết câu hỏi đó, chúng tôi đang nhập mã máy vào Altair bằng các công tắc bật tắt. Bạn phải chọn một mức độ trừu tượng ở đâu đó !
Eric Lippert

35
@Euphoric: Bạn có thể lập luận tương tự với kế toán không? Chúng tôi không cần nhiều người có thể giữ những cuốn sách đơn giản cho một doanh nghiệp nhỏ mới; chúng tôi cần kế toán TUYỆT VỜI, đẳng cấp thế giới. Nếu các khóa học kế toán giới thiệu khó khăn đến mức họ sợ những người chỉ mong muốn làm việc hiệu quả, kế toán công nhân, TỐT. Chúng tôi không cần những người trong ngành kế toán! Còn nghệ sĩ piano thì sao? Nếu những bài học piano giới thiệu làm mất đi những người sẽ không trở thành nghệ sĩ piano TUYỆT VỜI, điều đó thật tốt; chúng tôi chỉ muốn những nghệ sĩ piano tuyệt vời trên thế giới. Có điều gì đó có vẻ sai với lập luận này?
Eric Lippert

25
@Euphoric: Câu trả lời ngắn gọn là TỐT HẤP DẪN CÓ, chúng tôi cần nhiều lập trình viên đàng hoàng hơn! Chúng tôi cần nhiều lập trình viên ở mọi cấp độ khả năng và kinh nghiệm. Thế giới chạy trên phần mềm . Càng nhiều người có bất kỳ hiểu biết về cách làm cho thế giới của họ hoạt động, thì tốt hơn.
Eric Lippert

6
@Euphoric (và những người khác) - chúng tôi thuộc loại giới hạn về tính xây dựng của các bình luận. Vui lòng tham gia với chúng tôi trong Trò chuyện Kỹ thuật phần mềm nếu bạn muốn tiếp tục cuộc trò chuyện này.

50

Tôi đã có ý tưởng về chủ đề này, và tôi đã đưa chúng vào một cuốn sách 20 năm trước . Nó đã hết bản in, nhưng bạn vẫn có thể nhận được các bản sao đã sử dụng trên Amazon .

Một câu trả lời đơn giản cho câu hỏi của bạn cũng lâu đời như Aristotle: Thiên nhiên ghét một khoảng trống . Càng nhiều máy móc càng ngày càng nhanh, phần mềm càng ngày càng chậm.

Để mang tính xây dựng hơn, những gì tôi đề xuất là lý thuyết thông tin và sự liên quan trực tiếp của nó với phần mềm, là một phần của giáo dục khoa học máy tính. Nó chỉ được dạy bây giờ, nếu có, theo một cách rất tiếp tuyến.

Ví dụ, hành vi big-O của thuật toán có thể được hiểu rất gọn gàng và trực quan nếu bạn nghĩ về một chương trình như một kênh thông tin kiểu Shannon, với các ký hiệu đầu vào, ký hiệu đầu ra, nhiễu, dự phòng và băng thông.

Mặt khác, năng suất của một lập trình viên có thể được hiểu theo các thuật ngữ tương tự bằng cách sử dụng lý thuyết thông tin Kolmogorov. Đầu vào là một cấu trúc khái niệm mang tính biểu tượng trong đầu của bạn và đầu ra là văn bản chương trình xuất hiện trong tầm tay bạn. Quá trình lập trình là kênh giữa hai. Khi tiếng ồn đi vào quá trình, nó tạo ra các chương trình (lỗi) không nhất quán. Nếu văn bản chương trình đầu ra có đủ dự phòng, nó có thể cho phép bắt lỗi và sửa lỗi (phát hiện và sửa lỗi). Tuy nhiên, nếu nó quá dư thừa thì nó quá lớn và kích thước rất lớn của nó, kết hợp với tỷ lệ lỗi, gây ra sự ra đời của các lỗi. Do lý do này, tôi đã dành một phần tốt của cuốn sách chỉ ra cách coi lập trình là một quá trình thiết kế ngôn ngữ, với mục tiêu có thể xác định ngôn ngữ dành riêng cho tên miền phù hợp với nhu cầu. Chúng tôi trả tiền dịch vụ môi cho các ngôn ngữ cụ thể theo miền trong giáo dục CS, nhưng, một lần nữa, nó là tiếp tuyến.

Xây dựng ngôn ngữ là dễ dàng. Mỗi khi bạn xác định một chức năng, lớp hoặc biến, bạn sẽ thêm từ vựng vào ngôn ngữ bạn đã bắt đầu, tạo một ngôn ngữ mới để làm việc. Điều thường không được đánh giá cao là mục tiêu nên làm cho ngôn ngữ mới phù hợp hơn với cấu trúc khái niệm của vấn đề. Nếu điều này được thực hiện, thì nó có tác dụng rút ngắn mã và làm cho nó ít bị lỗi hơn bởi vì, lý tưởng nhất là có một ánh xạ 1-1 giữa các khái niệm và mã. Nếu ánh xạ là 1-1, bạn có thể mắc lỗi và mã hóa một khái niệm không chính xác như một khái niệm khác, nhưng chương trình sẽ không bao giờ bị sập, đó là điều xảy ra khi nó mã hóa không có yêu cầu nhất quán .

Chúng tôi không nhận được điều này. Đối với tất cả các cuộc nói chuyện dũng cảm của chúng tôi về thiết kế hệ thống phần mềm, tỷ lệ mã theo yêu cầu ngày càng lớn hơn, lớn hơn nhiều.

Đó là sự thật, chúng tôi có các thư viện rất hữu ích. Tuy nhiên, tôi nghĩ rằng chúng ta nên rất hạn chế về sự trừu tượng. Chúng ta không nên cho rằng nếu B xây dựng trên A và điều đó là tốt, rằng nếu C xây dựng trên B thì thậm chí còn tốt hơn. Tôi gọi đó là hiện tượng "công chúa và hạt đậu". Xếp chồng các lớp lên trên một thứ rắc rối không nhất thiết phải sửa nó.

Để chấm dứt một bài viết dài, tôi đã phát triển một phong cách lập trình (đôi khi khiến tôi gặp rắc rối) trong đó

  • Phát minh không phải là một điều xấu. Đó là một điều tốt, vì nó là trong các ngành kỹ thuật khác. Chắc chắn nó có thể tạo ra một đường cong học tập cho những người khác, nhưng nếu kết quả tổng thể là năng suất tốt hơn, nó là đáng giá.
  • Mã tối giản theo phong cách Haiku. Điều đó đặc biệt đi cho thiết kế cấu trúc dữ liệu. Theo kinh nghiệm của tôi, vấn đề lớn nhất trong phần mềm hiện nay là cấu trúc dữ liệu cồng kềnh.

9
Điều này nghe có vẻ rất nhiều những gì Chuck Moore (nhà phát minh của Forth ) luôn ủng hộ. Chẳng hạn, từ Nhận xét của Chuck Moore về Forth , "Tôi không nghĩ rằng bản chất của phần mềm là nó phải lớn, cồng kềnh, có lỗi. Đó là bản chất của xã hội chúng ta. ... Có rất nhiều động lực kinh tế để sản xuất ... bloatware này, rằng tôi cảm thấy vô trách nhiệm khi đứng lên và nói rằng hoàng đế không có quần áo. ".
Peter Mortensen

3
@PeterMortensen: Đồng ý. Nó cô đơn. Có một từ cho điều đó - Cassandra phức tạp .
Mike Dunlavey

2
Mặc dù việc viết các tạo phẩm mã cho các ngôn ngữ "mở rộng" không phải là một công việc khó khăn, nhưng việc tạo ra một API tốt phản ánh chính xác và trực quan miền vấn đề là.
Robert Harvey

3
@MikeDunlavey: BTW: Bạn cũng là anh chàng "không có hồ sơ" (điều này có nghĩa là theo cách tích cực). Vài tháng trước, tôi lại sử dụng kỹ thuật của bạn trong thế giới thực để nhanh chóng giảm thời gian tải tệp tài liệu từ 25 giây xuống còn 1 giây (thời gian tải mà người dùng trực tiếp trải nghiệm). Phải mất một vài lần lặp lại, và 10-20 mẫu trong tất cả các lần lặp là quá đủ. Các vấn đề hiệu suất tất nhiên là ở những nơi không mong đợi.
Peter Mortensen

2
@Izkata và Peter: Vâng, tôi là người kỳ quặc đó. FWIW, tôi đã đưa ra một vài video (cực kỳ nghiệp dư), với hy vọng làm cho nó dễ hiểu hơn. Tạm dừng ngẫu nhiên. Thi công vi sai. Chúc mừng.
Mike Dunlavey

35

Sự trừu tượng hóa ở mức độ cao là điều cần thiết để đạt được sự tiến bộ liên tục trong điện toán.

Tại sao? Bởi vì con người chỉ có thể nắm giữ rất nhiều kiến ​​thức trong đầu tại bất kỳ thời điểm nào. Các hệ thống hiện đại, quy mô lớn chỉ có thể có ngày hôm nay bởi vì bạn có thể tận dụng sự trừu tượng như vậy. Nếu không có những thứ trừu tượng đó, các hệ thống phần mềm sẽ đơn giản sụp đổ dưới sức nặng của chính chúng.

Mỗi khi bạn viết một phương thức, bạn đang tạo ra một sự trừu tượng. Bạn đang tạo một chút chức năng ẩn sau một cuộc gọi phương thức. Tại sao bạn viết chúng? Bởi vì bạn có thể kiểm tra phương thức, chứng minh nó hoạt động và sau đó gọi chức năng đó bất cứ lúc nào bạn muốn chỉ bằng cách thực hiện cuộc gọi phương thức và bạn không phải suy nghĩ thêm về mã bên trong phương thức đó.

Trong những ngày đầu của máy tính, chúng tôi sử dụng ngôn ngữ máy. Chúng tôi đã viết các chương trình kim loại nhỏ, trần trụi với kiến ​​thức sâu sắc về phần cứng mà chúng tôi đã viết cho chúng. Đó là một quá trình khó khăn. Không có trình sửa lỗi; chương trình của bạn thường hoạt động hoặc bị hỏng. Không có GUI; tất cả mọi thứ là dòng lệnh hoặc quá trình hàng loạt. Mã bạn đã viết sẽ chỉ hoạt động trên máy cụ thể đó; nó sẽ không hoạt động trên một máy có bộ xử lý hoặc hệ điều hành khác.

Vì vậy, chúng tôi đã viết các ngôn ngữ cấp cao để trừu tượng hóa tất cả các chi tiết đó. Chúng tôi đã tạo ra các máy ảo để các chương trình của chúng tôi có thể được chuyển sang các máy khác. Chúng tôi đã tạo bộ sưu tập rác để các lập trình viên không cần phải siêng năng trong việc quản lý bộ nhớ, loại bỏ cả một lớp lỗi khó. Chúng tôi đã thêm giới hạn kiểm tra ngôn ngữ của mình để tin tặc không thể khai thác chúng với lỗi tràn bộ đệm. Chúng tôi đã phát minh ra Lập trình hàm để chúng tôi có thể suy luận về các chương trình của mình theo một cách khác và đã khám phá lại nó gần đây để tận dụng lợi thế đồng thời tốt hơn.

Có phải tất cả sự trừu tượng này cách ly bạn khỏi phần cứng? Chắc chắn là có. Có phải sống trong một ngôi nhà thay vì dựng lều cách ly bạn với thiên nhiên? Chắc chắn rồi. Nhưng mọi người đều biết tại sao họ sống trong một ngôi nhà thay vì một cái lều, và xây dựng một ngôi nhà là một trò chơi bóng hoàn toàn khác so với việc dựng lều.

Tuy nhiên, bạn vẫn có thể dựng lều khi cần thiết phải làm điều đó và trong lập trình, bạn có thể (nếu bạn quá nghiêng) vẫn thả xuống một mức gần với phần cứng hơn để có được lợi ích về hiệu năng hoặc bộ nhớ mà bạn có thể không mặt khác đạt được trong ngôn ngữ cấp cao của bạn.


Bạn có thể trừu tượng quá nhiều? "Vượt qua hệ thống ống nước," như Scotty sẽ nói gì? Tất nhiên bạn có thể. Viết API tốt thật khó. Viết API tốt, thể hiện chính xác và toàn diện miền vấn đề, theo cách trực quan và có thể khám phá, thậm chí còn khó hơn. Chồng chất lên các lớp phần mềm mới không phải lúc nào cũng là giải pháp tốt nhất. Các mẫu thiết kế phần mềm , ở một mức độ nào đó, đã làm cho tình trạng này tồi tệ hơn, bởi vì các nhà phát triển thiếu kinh nghiệm đôi khi tiếp cận với họ khi một công cụ sắc nét hơn, gọn gàng hơn phù hợp hơn.


1
+1, mặc dù tôi nghĩ rằng bạn đã có lịch sử lập trình chức năng ngược (tính toán lambda có trước máy tính điện tử và nhiều ngôn ngữ chức năng có trước lập trình đồng thời).
amon

1
Tôi đã thêm một làm rõ nhỏ.
Robert Harvey

2
"Trong những ngày đầu của máy tính, chúng tôi đã sử dụng ngôn ngữ máy. Chúng tôi đã viết các chương trình kim loại nhỏ, trần trụi với kiến ​​thức sâu sắc về phần cứng mà chúng tôi đã viết cho chúng." Một số người trong chúng ta trong lập trình nhúng đôi khi vẫn làm điều đó, trên 8 - nhưng các bộ vi điều khiển có bộ nhớ chương trình ít hơn 1K, 64 byte RAM và có giá khoảng một phần tư. Không có trình biên dịch C ở đó. (Nhưng tôi thường làm việc với các bộ vi điều khiển 32 bit với không gian chương trình thường là 1/2 MB.)
tcrosley

9

Đào tạo thực sự tốt liên quan đến cả hai thái cực, cũng như một cầu nối giữa.

Về phía cấp độ thấp: cách máy tính thực thi mã từ đầu *, bao gồm kiến ​​thức về ngôn ngữ lắp ráp và trình biên dịch đang làm gì.

Về phía cấp cao: các khái niệm chung, ví dụ như sử dụng mảng kết hợp, đóng cửa, v.v. mà không phải lãng phí thời gian để lo lắng về cách thức hoạt động của nó dưới mui xe.

IMHO tất cả mọi người nên có kinh nghiệm với cả hai, bao gồm cả nhược điểm của họ và cách tìm hiểu từ các khái niệm cấp thấp đến các khái niệm cấp cao. Tình yêu mảng kết hợp? Tuyệt vời, giờ hãy thử sử dụng chúng trên bộ xử lý nhúng 50 cent với RAM 1kB. Thích viết mã nhanh bằng C? Tuyệt vời, bây giờ bạn có ba tuần để viết một ứng dụng web; bạn có thể dành thời gian xử lý các cấu trúc dữ liệu và quản lý bộ nhớ bằng C hoặc bạn có thể dành thời gian học một khung web mới và sau đó triển khai ứng dụng web trong vài ngày.

Theo như khía cạnh phức tạp của nó: tôi nghĩ rằng ngày nay quá dễ dàng để tạo ra các hệ thống phức tạp mà không có sự hiểu biết rõ ràng về chi phí để làm như vậy . Kết quả là, trong một xã hội, chúng ta đã tạo ra một số nợ kỹ thuật khổng lồ cắn chúng ta theo thời gian. Nó giống như động đất (chỉ là chi phí sống gần một lỗi địa chất, phải không?), Chỉ là nó đang dần trở nên tồi tệ hơn. Và tôi không biết phải làm gì về nó. Lý tưởng nhất là chúng ta học hỏi và cải thiện sự phức tạp, nhưng tôi không nghĩ điều đó sẽ xảy ra. Một nền giáo dục kỹ thuật có trách nhiệm cần bao gồm nhiều cuộc thảo luận về hậu quả của sự phức tạp hơn hầu hết các trường đại học của chúng tôi hiện đang cung cấp.


* và, dù sao, "mặt đất" ở đâu trong cách máy tính thực thi mã? Có phải là ngôn ngữ lắp ráp? Hay kiến ​​trúc máy tính? Hay logic kỹ thuật số? Hay bóng bán dẫn? Hoặc vật lý thiết bị?


7

Tôi cảm thấy lập trình cấp cao có nhiều ưu điểm và là một phần thiết yếu của ngôn ngữ lập trình. Một trong những lý do khiến Java trở nên thành công là vì nó có một thư viện toàn diện. Bạn đạt được nhiều hơn với ít mã hơn - chỉ cần gọi một hàm được xác định trước.

Bây giờ chúng ta có thể phân biệt người dùng ngôn ngữ lập trình với người viết ngôn ngữ lập trình (người viết trình biên dịch). Chúng tôi để lại sự tối ưu cho các nhà văn biên dịch. Chúng tôi tập trung nhiều hơn vào khả năng bảo trì, tái sử dụng, v.v.


7

Sự gia tăng độ phức tạp của các hệ thống là không ngừng, áp bức và cuối cùng làm tê liệt. Đối với tôi là một lập trình viên thế hệ cũ, điều đó cũng thật đáng thất vọng.

Tôi đã lập trình được hơn 40 năm, đã viết mã bằng 50 - 100 ngôn ngữ hoặc phương ngữ khác nhau và trở thành chuyên gia trong 5-10. Lý do tôi có thể yêu cầu rất nhiều là vì hầu hết chúng chỉ là cùng một ngôn ngữ, với các điều chỉnh. Các tinh chỉnh thêm phức tạp, làm cho mọi ngôn ngữ chỉ khác nhau một chút.

Tôi đã thực hiện cùng một số thuật toán vô số lần: bộ sưu tập, chuyển đổi, sắp xếp và tìm kiếm, mã hóa / giải mã, định dạng / phân tích cú pháp, bộ đệm và chuỗi, số học, bộ nhớ, I / O. Mỗi triển khai mới đều tăng thêm độ phức tạp, bởi vì mỗi thứ chỉ khác nhau một chút.

Tôi tự hỏi về phép thuật được tạo ra bởi các nghệ sĩ hình thang bay cao của các khung web và ứng dụng di động, làm thế nào họ có thể tạo ra một thứ gì đó thật đẹp trong một thời gian ngắn như vậy. Sau đó, tôi nhận ra họ không biết bao nhiêu, họ sẽ cần học bao nhiêu về dữ liệu hoặc truyền thông hoặc thử nghiệm hoặc chủ đề hoặc bất cứ điều gì trước khi những gì họ làm trở nên hữu ích.

Tôi đã học được nghề của mình trong kỷ nguyên của các ngôn ngữ thế hệ thứ tư, nơi chúng tôi thực sự tin rằng chúng tôi sẽ tạo ra một chuỗi các ngôn ngữ cấp cao hơn và cao hơn để dần dần nắm bắt được nhiều hơn các phần lặp đi lặp lại của phần mềm viết. Vì vậy, làm thế nào mà bật ra, chính xác?

Microsoft và IBM đã giết chết ý tưởng đó bằng cách quay lại C để viết ứng dụng cho Windows và OS / 2, trong khi dBase / Foxpro và thậm chí Delphi không hoạt động. Sau đó, web đã làm điều đó một lần nữa với bộ ba ngôn ngữ lắp ráp cuối cùng: HTML, CSS và JavaScript / DOM. Tất cả đã xuống dốc từ đó. Luôn luôn có nhiều ngôn ngữ hơn và nhiều thư viện hơn và nhiều khung hơn và phức tạp hơn.

Chúng tôi biết chúng ta nên làm điều đó khác đi. Chúng tôi biết về CoffeeScript và Dart, về Ít và Sass, về mẫu để tránh phải viết HTML. Chúng tôi biết và chúng tôi làm điều đó anyway. Chúng tôi có khuôn khổ của chúng tôi, đầy những trừu tượng bị rò rỉ, và chúng tôi thấy những điều kỳ diệu có thể được thực hiện bởi những người được chọn học những câu thần chú phức tạp, nhưng chúng tôi và các chương trình của chúng tôi bị mắc kẹt bởi các quyết định đưa ra trong quá khứ. Quá phức tạp để thay đổi hoặc bắt đầu lại.

Kết quả là những thứ phải dễ dàng không phải là dễ, và những thứ phải có thể là gần như không thể, vì sự phức tạp. Tôi có thể ước tính chi phí thực hiện các thay đổi để triển khai một tính năng mới trong cơ sở mã đã được thiết lập và tự tin rằng tôi sẽ ổn. Tôi có thể ước tính, nhưng tôi không thể biện minh hay giải thích nó. Nó quá phức tạp.

Để trả lời cho câu hỏi cuối cùng của bạn, tôi đặc biệt khuyên các lập trình viên trẻ nên bắt đầu càng cao trên lớp bánh càng tốt, và chỉ lặn xuống các lớp thấp hơn khi nhu cầu và mong muốn cung cấp động lực. Sở thích của tôi là dành cho các ngôn ngữ không có vòng lặp, ít hoặc không có trạng thái phân nhánh và rõ ràng. Lisp và Haskell đến với tâm trí. Trong thực tế, tôi luôn hoàn thành với C # / Java, Ruby, Javascript, Python và SQL vì đó là nơi có cộng đồng.

Lời cuối cùng: sự phức tạp là kẻ thù tối thượng! Đánh bại điều đó và cuộc sống trở nên đơn giản.


Hơn 30 năm lập trình của tôi đã dạy tôi sử dụng ngôn ngữ cấp cao nhất có sẵn, sẽ làm những gì cần phải làm và vẫn cho phép sử dụng ngôn ngữ cấp thấp hơn khi được yêu cầu. Môi trường dễ nhất cho điều đó là kịch bản shell có thể gọi các mô-đun được viết bằng bất kỳ ngôn ngữ nào. Phần khó là phá vỡ suy nghĩ chi phối rằng tất cả các chức năng của một dự án phải được thực hiện trong cùng một ngôn ngữ.
DocSalvager

@dicsalvage: Tôi đồng ý, và sự thất vọng lớn của tôi là thiếu trình độ cao hơn bao giờ hết. Những gì awk có thể làm trong 10 dòng trong những năm 1980 hiện có 15 dòng trong Ruby hoặc Python, nhưng tôi tìm kiếm thứ gì đó để làm trong 3. Và các môi trường bị khóa trên điện thoại có nghĩa là điều tương tự mất 50 trong Java hoặc Objective C. Không kịch bản shell đó!
david.pfx

Google "bash for android" cho thấy rất nhiều người làm việc trên các cổng. Ngoài ra còn có các phiên bản Python như Kivy
DocSalvager

@DocSalvage: Sớm hay muộn môi trường điện thoại sẽ tham gia nền văn minh (như chúng ta biết). Khiếu nại của tôi là thời gian để làm đi làm lại nhiều lần những điều dường như đã được hoàn thành. Chúng tôi tiếp tục phải quay trở lại để đặt nền móng và gạch và hệ thống thoát nước và lán khi tôi muốn xây dựng các tòa nhà chọc trời.
david.pfx

4

Câu hỏi của tôi là mọi người cảm thấy thế nào về việc "che giấu" các yếu tố cấp thấp hơn này. Bạn có lập trình viên lớn tuổi xem nó như một ơn trời hay một lớp không cần thiết để vượt qua?

Không, thực sự.

Layering là cần thiết bởi vì không có nó, bạn đạt đến một điểm mà hệ thống của bạn trở thành spaghetti không thể nhầm lẫn. Đây cũng là một trong những nguyên lý của khả năng sử dụng lại: nếu nhà phát triển thư viện làm tốt công việc, những người sử dụng nó không cần phải quan tâm đến các chi tiết của việc triển khai. Số lượng mã đóng hộp mà chúng tôi sử dụng trong các hệ thống của chúng tôi đã tăng lên theo các đơn đặt hàng so với khi tôi viết chương trình đầu tiên của mình cách đây 35 năm. Sự tăng trưởng đó có nghĩa là chúng ta có thể làm những điều mạnh mẽ hơn khi thời gian trôi qua. Điều này là tốt

Nơi đó là một vấn đề đối với tôi hoàn toàn là văn hóa. Một nửa thực dụng của tôi hiểu rằng không còn có thể bao bọc tâm trí tôi đến từng chi tiết cuối cùng và có thể hoàn thành những điều tôi muốn hoàn thành. (Việc già đi cũng không giúp được gì.) Một nửa con mèo xám gầy gò của tôi đã có một khoảng thời gian khó khăn khi buông bỏ nhiều năm để có một sự hiểu biết chính xác về mọi thứ tôi làm.

Bạn có nghĩ rằng các lập trình viên trẻ tuổi sẽ có lợi hơn khi học lập trình cấp thấp TRƯỚC KHI khám phá các lĩnh vực của các thư viện mở rộng?

Như đã được chỉ ra trong các câu trả lời khác, có một sự cân bằng giữa thu hút và duy trì sự chú ý của tân sinh viên và mang đến cho họ một nền giáo dục lý tưởng, từ dưới lên. Nếu bạn không thể làm cái trước, cái sau không thể xảy ra.

Tôi thấy những điều trong ngành công nghiệp của chúng tôi song song với phần còn lại của xã hội. Trước đây, hầu hết mọi người đều tự trồng thực phẩm và dành nhiều thời gian để làm việc đó. Kể từ đó, chúng tôi đã phát triển các chuyên gia gọi là nông dân làm công việc đó, giải phóng những người khác để làm những việc khác đóng góp cho xã hội. Tôi mua thực phẩm của mình tại một cửa hàng tạp hóa và hoàn toàn không thể tự sản xuất hầu hết trong số đó nếu tôi phải. Chúng tôi có một điều tương tự đang diễn ra, mặc dù trên quy mô thời gian nén hơn nhiều. Các lập trình viên chuyên về một số tập hợp các lớp chứ không phải các lớp khác. Một anh chàng trung bình viết GUI có thể biết rằng có một thứ như không gian hoán đổi nhưng có lẽ không biết hoặc quan tâm nhiều đến cách hệ điều hành đang quản lý nó.

Kết quả cuối cùng là nó không còn chỉ là sự phát triển. Chuyên môn hóa liên tục có nghĩa là các nhà phát triển sẽ cần tiếp tục cải thiện kỹ năng giao tiếp và tích hợp.


3

Như với tất cả mọi thứ, một chút làm bạn tốt, nhưng quá nhiều đau đớn. Vấn đề là có quá nhiều hệ thống không biết khi nào nên dừng lại - chỉ cần thêm 1 lần trừu tượng hóa, để giúp bạn lập trình nhanh hơn ... nhưng sau đó, bạn kết thúc việc viết mã trong thế giới thực, nơi mọi thứ không bao giờ đơn giản như bạn muốn, và bạn dành nhiều thời gian để làm việc quanh các cạnh hơn bạn đã dành với một sự trừu tượng ít đặc trưng hơn.

Nó được mô tả ở đây

hoặc tại đây - "với một dòng mã, bạn có thể thêm 500 người dùng vào miền" ...

Sự trừu tượng của bạn cố gắng che giấu sự phức tạp khỏi bạn, nhưng thực sự tất cả những gì họ làm là che giấu sự phức tạp đó. Sự phức tạp vẫn còn đó, chỉ là bạn có ít quyền kiểm soát hơn - và đó là lý do tại sao bạn kết thúc với tình huống này.


2

Các lập trình viên trẻ có được hưởng lợi nhiều hơn khi học lập trình cấp thấp TRƯỚC KHI khám phá các lĩnh vực của các thư viện mở rộng không? Nếu vậy thì tại sao?

Tôi không nghĩ vậy. Vẫn còn nhiều tình huống trong đó có ích khi nhận thức được các lớp 'bên dưới' hoạt động thấp, vd

  • Khi gỡ lỗi một vấn đề trên lớp n, nó thường có thể được giải thích bằng cách xem xét những gì xảy ra trên lớp n-1(tức là lớp bên dưới). Tôi đoán lớp 0 sẽ là "bóng bán dẫn" nhưng nếu bạn muốn giải thích một vấn đề với bóng bán dẫn thì có lẽ bạn sẽ nói về vật lý (ví dụ nhiệt), vì vậy có lẽ vật lý thực sự là cấp 0.

  • Khi tối ưu hóa mã, không may, đôi khi nó sẽ giúp giảm mức độ trừu tượng, tức là thực hiện một thuật toán theo lớp cấp thấp hơn. Tuy nhiên, trình biên dịch trở nên thực sự tốt khi làm điều này cho bạn nếu họ thực sự thấy tất cả các mã liên quan. Lý do này trở nên phổ biến gần đây với sự bùng nổ của thiết bị di động và thiết bị nhúng, có xu hướng có bộ xử lý yếu hơn và trong đó "hiệu suất trên mỗi watt" có liên quan nhiều hơn so với các hệ thống máy tính để bàn.

Tuy nhiên, nói chung, việc chế tạo máy tính trở nên dễ dàng hơn rất nhiều (ngay cả khi theo những cách hơi kém hiệu quả), điều đó có nghĩa là có nhiều lập trình viên hơn trước đây. Chính điều này đã làm cho yếu tố "con người" trở nên quan trọng hơn nhiều: câu trả lời của Robert Harvey đã đề cập rằng "con người chỉ có thể nắm giữ rất nhiều kiến ​​thức trong đầu tại bất kỳ thời điểm nào" và tôi nghĩ rằng đó là một khía cạnh rất phù hợp hiện nay.

Một động lực chính trong ngôn ngữ lập trình và thiết kế thư viện (tức là API) là làm cho mọi thứ dễ dàng hơn trên bộ não con người. Cho đến ngày nay, mọi thứ vẫn được biên dịch thành mã máy. Tuy nhiên, điều này không chỉ dễ bị lỗi mà còn rất khó hiểu. Vì vậy, nó rất mong muốn

  • Có máy tính giúp bạn tìm lỗi logic trong các chương trình bạn viết. Những thứ như hệ thống loại tĩnh hoặc máy phân tích mã nguồn (tôi nghe thấy Eric Lippert hoạt động trên một thiết bị khá phổ biến hiện nay) giúp ích cho điều đó.

  • Có một ngôn ngữ có thể được xử lý hiệu quả bởi trình biên dịch truyền đạt ý định của lập trình viên đến các lập trình viên khác để làm việc với chương trình dễ dàng hơn. Là một cực kỳ vô lý, hãy tưởng tượng viết chương trình bằng tiếng Anh đơn giản là có thể. Các lập trình viên có thể có một thời gian dễ dàng hơn để tưởng tượng những gì đang diễn ra nhưng vẫn vậy, phần mô tả sẽ rất khó để biên dịch thành các giảng viên máy, và nó rất mơ hồ. Vì vậy, bạn cần một ngôn ngữ mà trình biên dịch có thể hiểu được nhưng cũng dễ hiểu.

Cho rằng rất nhiều trình biên dịch (hầu hết?) Vẫn còn rất nhiều mục đích chung, chúng có một tập lệnh rất chung chung. Không có hướng dẫn "vẽ nút" hoặc "phát phim này". Do đó, việc chuyển xuống hệ thống phân cấp trừu tượng làm cho bạn kết thúc với các chương trình rất khó để hiểu và duy trì (mặc dù không quan trọng để biên dịch). Thay thế duy nhất là di chuyển lên thứ bậc, dẫn đến ngày càng nhiều ngôn ngữ và thư viện trừu tượng.



1

"nếu các lập trình viên lớn tuổi xem những đổi mới như thế này là một ơn trời hoặc một lớp bổ sung để trừu tượng hóa, và tại sao họ có thể nghĩ như vậy?"

Tôi đã lập trình từ khi còn học cấp ba, khoảng 34 năm, bắt đầu với Trình biên dịch cơ bản và Z80, chuyển sang C, các ngôn ngữ 4GL khác nhau, Lược đồ, SQL và giờ là các ngôn ngữ Web khác nhau. Phạm vi, quy mô và độ sâu của các vấn đề được giải quyết bởi nghề đã trải qua một thời kỳ lạm phát trong thời gian đó, đặc biệt là trong những năm 1990. Các cấu trúc như thư viện, khung và dịch vụ HĐH là tất cả các yếu tố nhằm giải quyết sự phức tạp đi cùng với không gian mở rộng của các vấn đề. Chúng không phải là một ơn trời và cũng không phải là gánh nặng của chính chúng - chỉ là một cuộc khám phá tiếp tục về một không gian giải pháp rộng lớn.

Nhưng, IMHO, "đổi mới" được hiểu rõ hơn về các hình thức tiểu thuyết và không bị nhầm lẫn với chuyển động ngang - các hình thức giới thiệu lại mà chúng tôi đã thấy được giới thiệu. Theo một cách nào đó, sự phong phú của một hệ sinh thái bị ảnh hưởng khi các hình thức nguyên thủy không sáng tác, khi chúng sửa chữa các quyết định được đưa ra sớm trong quá trình tiến hóa, hoặc không thể tự xử lý lại mảnh vụn của chúng. Một số, nếu không phải hầu hết, các công trình mà chúng tôi vẫn tập trung không ưu tiên duy trì giá trị lâu dài như một mối quan tâm. Điều đó đã bắt đầu thay đổi - các cách tiếp cận như Định hướng dịch vụ và Thiết kế hướng tên miền, chưa kể các mô hình siêu văn bản và dựa trên biểu đồ, chẳng hạn, đang thay đổi cảnh quan. Giống như bất kỳ hệ sinh thái nào, cuối cùng các hình thức thống trị sẽ nhường chỗ cho các hình thức mới; chúng tôi được phục vụ tốt nhất bằng cách cho phép sự đa dạng,

"Và các lập trình viên trẻ có lợi hơn khi học lập trình cấp thấp TRƯỚC KHI khám phá các lĩnh vực của các thư viện mở rộng không? Nếu vậy thì tại sao?"

Tôi sẽ lập luận rằng hầu hết ngôn ngữ của con người dựa trên các ẩn dụ đã bị lãng quên từ lâu, vì vậy trong khi tôi hỗ trợ học lập trình cấp thấp từ quan điểm xóa mù chữ khoa học / số, điều quan trọng hơn là chúng tôi tìm kiếm các nguyên thủy sẽ hỗ trợ quy mô và phạm vi các vấn đề chúng ta đang giải quyết theo cách mà chúng ta có thể bỏ qua mức độ chi tiết thấp hơn một cách an toàn. Một khung công tác không phải là nguyên thủy, cũng không phải là hệ điều hành hay thư viện - họ khá kém trong việc thực hiện loại trừu tượng mà chúng ta thực sự cần. Tiến bộ thực sự sẽ đưa những người (a) biết những gì đã đi trước và (b) có thể nghĩ trong một cuốn tiểu thuyết đủ để đưa ra một cái gì đó đủ khác biệt để khám phá một không gian giải pháp chưa được khám phá trước hoặc bị khám phá và lãng quên.

OTOH, ngay cả khi mục tiêu của bạn là làm kỹ thuật viên / trình độ cơ khí, một số mức độ tiếp xúc với lập trình cấp thấp vẫn sẽ hữu ích để phát triển kỹ năng giải quyết vấn đề của bạn.


1

Chương trình đầu tiên của tôi (khi còn là một thiếu niên 15 tuổi) là vào năm 1974 trong PL / 1 trên các thẻ đục lỗ cho một máy tính lớn IBM 370/168. Cha tôi đang làm việc tại IBM và tôi đã may mắn có thể đến trung tâm dữ liệu vào Chủ nhật.

Vào thời điểm đó, một chương trình gồm vài ngàn câu lệnh (thẻ iepunched) là một chương trình lớn (và cũng là một chương trình nặng, vì hàng ngàn thẻ đục lỗ nặng nhiều kg). Giao diện trực quan không tồn tại (một chương trình điển hình được đọc từ "đầu vào tiêu chuẩn" của nó bằng cách sử dụng lệnh thẻ đục lỗ bắt đầu bằng //GO.SYSIN DD *IIRC, nhưng tôi không thành thạo JCL ). Thuật toán là quan trọng và IIRC thư viện tiêu chuẩn khá nhỏ theo tiêu chuẩn ngày nay.

Ngày nay, các chương trình của vài ngàn dòng thường được coi là nhỏ. Ví dụ, trình biên dịch GCC có hơn mười triệu dòng mã nguồn và không ai hiểu chúng đầy đủ.

Cảm giác của tôi là lập trình ngày nay khá khác so với những năm 1970, bởi vì bạn cần sử dụng nhiều tài nguyên hơn (đặc biệt là các thư viện và khung phần mềm hiện có). Tuy nhiên, tôi đoán rằng những người phát triển phần mềm trung tâm dữ liệu (ví dụ: công cụ tìm kiếm tại Google) hoặc một số phần mềm nhúng quan tâm nhiều đến thuật toán và hiệu quả so với lập trình viên trung bình của thập niên 1970.

Tôi vẫn nghĩ rằng việc hiểu lập trình cấp thấp là rất quan trọng ngay cả ngày nay (ngay cả khi hầu hết các lập trình viên sẽ không tự mã hóa các thuật toán container cơ bản như cây cân bằng, các mảng được sắp xếp truy cập nhị phân, v.v ...) bởi vì hiểu toàn bộ bức tranh vẫn còn quan trọng.

Một sự khác biệt lớn giữa thập niên 1970 và ngày nay là tỷ lệ chi phí giữa nỗ lực của nhà phát triển (con người) và sức mạnh máy tính.

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.