Có phải là một vấn đề để trở thành một lập trình viên không có kiến ​​thức về độ phức tạp tính toán?


30

Tôi đã được chỉ định một bài tập trong trường đại học của tôi. Tôi đoán nó về nhà và cố gắng lập trình một thuật toán để giải nó, nó là thứ gì đó liên quan đến đồ thị, tìm các thành phần được kết nối, tôi đoán vậy.

Sau đó, tôi đã làm những điều tầm thường nhất xuất hiện trong tâm trí của tôi và sau đó trình bày cho giảng viên của tôi. Sau khi quan sát ngắn, anh ta nhận thấy rằng độ phức tạp thời gian chạy của giải pháp của tôi là vô hình và cho thấy một cái gì đó hiệu quả hơn. Và có một truyền thống của các lập trình viên không có ý tưởng về độ phức tạp tính toán (tôi là một trong số đó), vậy có vấn đề gì không nếu một lập trình viên không biết gì về độ phức tạp tính toán?


3
Thông báo của người điều hành : vui lòng không sử dụng các bình luận để thảo luận mở rộng hoặc đăng câu trả lời chính đáng. Bạn có thể sử dụng phòng trò chuyện để thảo luận về câu hỏi này; ý kiến ​​trước đây đã được chuyển đến đó.
Gilles 'SO- ngừng trở nên xấu xa'

4
Tiêu đề của bạn nói lập trình viên, nhưng câu hỏi của bạn nói sinh viên. Nói chung, 'lập trình viên' ngụ ý 'lập trình viên chuyên nghiệp' - vậy bạn có hỏi liệu có phải là một lập trình viên chuyên nghiệp mà không có kiến ​​thức về độ phức tạp tính toán không? Hoặc liệu một sinh viên lập trình không có kiến ​​thức đó có ổn không? Hai câu hỏi khác nhau, ngay cả khi hóa ra họ có cùng một câu trả lời.
corsiKa

Câu trả lời:


42

Vâng, tôi sẽ nói rằng biết một cái gì đó về độ phức tạp tính toán là điều bắt buộc đối với bất kỳ lập trình viên nghiêm túc nào. Miễn là bạn không phải đối phó với các tập dữ liệu khổng lồ, bạn sẽ không biết sự phức tạp, nhưng nếu bạn muốn viết một chương trình giải quyết các vấn đề nghiêm trọng, bạn cần nó.

Trong trường hợp cụ thể của bạn, ví dụ về việc tìm các thành phần được kết nối của bạn có thể đã hoạt động cho các biểu đồ có thể nói lên tới nút. Tuy nhiên, nếu bạn đã thử một biểu đồ với nút thì thuật toán của giảng viên có thể đã quản lý được điều đó trong 1 giây, trong khi thuật toán của bạn sẽ có (tùy thuộc vào mức độ phức tạp của nó) mất 1 giờ, 1 ngày hoặc thậm chí là 1 vĩnh cửu.100.000100100.000

Một lỗi khá phổ biến mà sinh viên mắc phải trong khóa học thuật toán của chúng tôi là lặp đi lặp lại qua một mảng như thế này:

while array not empty
    examine first element of array
    remove first element from array

Đây có thể không phải là mã đẹp nhất nhưng trong một chương trình phức tạp, một cái gì đó như thế này có thể xuất hiện mà không có lập trình viên nhận thức được nó. Bây giờ, vấn đề với chương trình này là gì?

Giả sử chúng ta chạy nó trên tập dữ liệu gồm phần tử. So với chương trình sau, chương trình cũ sẽ chạy chậm hơn.50.000100.00050.000

while array not empty
    examine last element of array
    remove last element from array

Tôi hy vọng bạn đồng ý rằng có kiến ​​thức để làm cho chương trình của bạn chạy nhanh hơn lần có lẽ là một điều quan trọng đối với một lập trình viên. Hiểu được sự khác biệt giữa hai chương trình đòi hỏi một số kiến ​​thức cơ bản về lý thuyết phức tạp và một số kiến ​​thức về các chi tiết của ngôn ngữ bạn đang lập trình.50.000

Trong ngôn ngữ mã giả của tôi, "loại bỏ một phần tử khỏi một mảng" sẽ dịch chuyển tất cả các phần tử sang bên phải của phần tử được loại bỏ một vị trí từ bên trái. Điều này làm cho việc loại bỏ phần tử cuối cùng thành thao tác vì để thực hiện điều đó, chúng ta chỉ cần tương tác với 1 phần tử. Loại bỏ phần tử đầu tiên là vì để loại bỏ phần tử đầu tiên, chúng ta cần chuyển tất cả các phần tử khác sang một vị trí bên trái.O ( n ) n - 1O(1)O(n)n1

Một bài tập rất cơ bản về độ phức tạp là chứng minh rằng chương trình đầu tiên sẽ thực hiện hoạt động trong khi chương trình thứ hai chỉ sử dụng thao tác. Nếu bạn cắm bạn sẽ thấy một chương trình hiệu quả hơn nhiều so với chương trình kia.nn=100.00012n2nn=100.000

Đây chỉ là một ví dụ về đồ chơi nhưng nó đòi hỏi sự hiểu biết cơ bản về độ phức tạp để phân biệt sự khác biệt giữa hai chương trình và nếu bạn thực sự đang cố gắng gỡ lỗi / tối ưu hóa một chương trình phức tạp hơn có lỗi này thì cần phải tìm hiểu nhiều hơn ra lỗi ở đâu Bởi vì một lỗi như loại bỏ một phần tử khỏi một mảng theo kiểu này có thể được ẩn rất tốt bởi sự trừu tượng trong mã.

Có một sự hiểu biết tốt về sự phức tạp cũng giúp ích khi so sánh hai cách tiếp cận để giải quyết vấn đề. Giả sử bạn đã tự mình đưa ra hai cách tiếp cận khác nhau để giải quyết vấn đề các thành phần được kết nối: để quyết định giữa chúng, sẽ rất hữu ích nếu bạn có thể (nhanh chóng) ước tính độ phức tạp của chúng và chọn phương án tốt hơn.


10
"So long as you are not dealing with huge data sets you will be fine not knowing complexity"Điều này thường đúng, nhưng không phải lúc nào cũng như vậy. Chẳng hạn, một O(n!)thuật toán sẽ không khả thi ngay cả đối với các tập dữ liệu tương đối nhỏ. Nếu bạn sử dụng O(n!)thuật toán mà bạn có thể đã sử dụng, O(n^2)chương trình của bạn sẽ mất 36,288 lần để thực hiện trên kích thước dữ liệu là 10 . Trên kích thước dữ liệu là 20, bạn đang xem 2,4 triệu hoạt động.
thiệu lại vào

1
Tôi nghĩ rằng ví dụ của @ reirab nên được đưa vào câu trả lời. Nó kịch tính hơn và chứng minh quan điểm của bạn quyết đoán hơn. Và cá nhân tôi đã bị cắn bởi các thuật toán như vậy, trước khi tôi học được độ phức tạp tính toán.
Siyuan Ren

2
Tôi nghĩ có một vấn đề lớn hơn khi chơi. Nếu bạn chỉ đơn giản là không biết bạn tự chọn vào các nhiệm vụ không cần thiết. Vì vậy, bạn có thể nói gần như tất cả các câu hỏi tôi cần biết X kết thúc bằng, nó có thể hữu ích. Vì vậy, thiếu tôn trọng nếu nó rất quan trọng để biết hoặc cuối cùng nó có thể cắn bạn.
joojaa

"Hiểu sự khác biệt giữa hai chương trình đòi hỏi một số kiến ​​thức cơ bản về lý thuyết phức tạp" - Tôi nghĩ với ví dụ cụ thể này thì không. Bạn có thể cấu hình nó, quan sát rằng tất cả thời gian được thực hiện trong "phần tử loại bỏ", biết (không hiểu lý thuyết phức tạp) rằng loại bỏ phần tử cuối cùng nhanh hơn loại bỏ phần tử đầu tiên, thực hiện thay đổi và do đó tăng tốc chương trình. Ưu điểm của việc hiểu lý thuyết phức tạp là nó cho phép bạn giải quyết một cách lỏng lẻo những vấn đề như vậy mà không cần lược tả chúng, do đó bạn có thể "tối ưu hóa" sớm.
Steve Jessop

.. và nói chung tôi nghi ngờ rằng tất cả hoặc gần như tất cả các ví dụ thực tế có thể được giải quyết, từng cái một, mà không cần tham khảo lý thuyết phức tạp. Trong trường hợp này, biết rằng sao chép nhiều dữ liệu chậm hơn so với không làm như vậy, không phải là "lý thuyết phức tạp". Nhưng tất nhiên nó vẫn hữu ích trong lập trình (và bất kỳ ngành nghề nào) để có một mô hình tinh thần tốt về các nguyên tắc thường xuất hiện, bởi vì bạn có thể phân tích, thảo luận và giải quyết các vấn đề đó một cách thường xuyên theo nguyên tắc thay vì từng lúc bằng phương pháp ad hoc.
Steve Jessop

26

Đây là phản bác câu trả lời của Tom van der Zanden , trong đó tuyên bố rằng đây là điều bắt buộc.

Vấn đề là, hầu hết các lần, chậm hơn 50.000 lần không liên quan (tất nhiên trừ khi bạn làm việc tại Google).

Nếu thao tác bạn thực hiện mất một phần triệu giây hoặc nếu N của bạn không bao giờ vượt quá một ngưỡng nhất định (Một phần lớn mã hóa được thực hiện hiện nay) thì KHÔNG BAO GIỜ. Trong những trường hợp suy nghĩ về sự phức tạp tính toán sẽ chỉ khiến bạn lãng phí thời gian (và rất có thể là tiền).

Độ phức tạp tính toán là một công cụ để hiểu lý do tại sao một cái gì đó có thể chậm hoặc quy mô xấu, và làm thế nào để cải thiện nó, nhưng hầu hết thời gian là quá mức cần thiết.

Tôi đã là một lập trình viên chuyên nghiệp hơn năm năm nay và tôi chưa bao giờ thấy cần phải suy nghĩ về độ phức tạp tính toán khi lặp bên trong một vòng lặp O (M * N) bởi vì luôn luôn hoạt động rất nhanh hoặc M và N rất nhanh nhỏ bé.

Có nhiều thứ quan trọng hơn, thường được sử dụng và khó hiểu hơn đối với bất kỳ ai làm công việc lập trình (luồng và hồ sơ là những ví dụ tốt trong lĩnh vực hiệu suất).

Tất nhiên, có một số điều bạn sẽ không bao giờ có thể làm được nếu không hiểu độ phức tạp tính toán (ví dụ: tìm đảo chữ trên từ điển), nhưng hầu hết thời gian bạn không cần đến nó.


3
Để mở rộng quan điểm của bạn, có những trường hợp quá chú trọng vào độ phức tạp tính toán có thể khiến bạn lạc lối. Ví dụ, có thể có tình huống thuật toán "tốt hơn" thực sự chậm hơn đối với các đầu vào nhỏ. Các hồ sơ là nguồn cuối cùng của sự thật.
Kevin Krumwiede

2
@Kevin Krumwiede, tôi hoàn toàn đồng ý với bạn rằng tối ưu hóa một loại cho một tập dữ liệu tầm thường là quá mức cần thiết. Nhưng nó cũng minh họa rằng có ít nhất một sự hiểu biết về sự phức tạp vẫn còn quan trọng. Sự hiểu biết là điều sẽ dẫn bạn đến quyết định rằng một loại bong bóng phù hợp trái ngược với một số thuật toán khác, phức tạp hơn.
Kent A.

4
Khi bạn biết tập dữ liệu nhỏ trong mọi trường hợp, bạn có thể thoát khỏi loại điều này. Bạn phải rất cẩn thận về sự phức tạp quá mức trong những thứ được gọi trong các vòng lặp, mặc dù vậy - cách đây không lâu tôi đã cắt thời gian chạy một phút xuống một giây theo cách này. Tôi cũng đã gặp phải sự cố O (n ^ 8) một lần (xác thực dữ liệu.) Rất nhiều sự chăm sóc đã giảm xuống còn 12 giờ.
Loren Pechtel

7
Tôi chưa bao giờ thấy cần phải suy nghĩ về độ phức tạp tính toán khi lặp bên trong một vòng lặp O (M * N) bởi vì luôn luôn hoạt động rất nhanh hoặc M và N quá nhỏ. - Trớ trêu thay, lập luận bạn đưa ra cho thấy rằng bạn đã nghĩ về độ phức tạp tính toán. Bạn đã quyết định rằng đó không phải là vấn đề có liên quan cho những gì bạn đang làm và có thể đúng như vậy, nhưng bạn vẫn nhận thức được sự tồn tại của vấn đề này và nếu nó gây ra sự cố, bạn có thể phản ứng với nó trước khi hậu quả nghiêm trọng xảy ra với cấp độ người dùng.
Wrzlprmft 15/2/2015

4
Tối ưu hóa sớm là gốc rễ của mọi tội lỗi, nhưng bi quan sớm là gốc rễ của ít nhất một lượng lớn người dùng khó chịu. Bạn có thể không cần phải giải quyết mối quan hệ tái phát, nhưng nếu ít nhất, bạn không có khả năng nói sự khác biệt giữa O (1), O (N) và O (N ^ 2), đặc biệt là khi bạn Sẽ làm lại các vòng lặp, ai đó sẽ phải dọn dẹp mớ hỗn độn sau đó. Nguồn: những mớ hỗn độn tôi phải dọn dẹp sau đó. Một yếu tố 50.000 lớn đến mức bạn có thể biết rõ hơn nếu sau này bạn vẫn có thể đủ khả năng đó , khi đầu vào của bạn đã tăng.
Jeroen Mostert

14

Tôi đã phát triển phần mềm trong khoảng ba mươi năm, làm việc như một nhà thầu và nhân viên, và tôi đã khá thành công với nó. Ngôn ngữ đầu tiên của tôi là BASIC, nhưng tôi đã nhanh chóng tự học ngôn ngữ máy móc để có được tốc độ tốt từ chiếc hộp không đủ sức mạnh của mình. Tôi đã dành rất nhiều thời gian trong các trình biên dịch trong những năm qua và đã học được rất nhiều về việc sản xuất mã được tối ưu hóa nhanh, hiệu quả bộ nhớ.

Bất kể nói gì, tôi tự dạy. Tôi chưa bao giờ gặp ký hiệu O cho đến khi tôi bắt đầu phỏng vấn vài năm trước. Nó không bao giờ xuất hiện trong công việc chuyên môn của tôi NGOẠI TRỪ trong các cuộc phỏng vấn. Vì vậy, tôi đã phải học những điều cơ bản chỉ để xử lý câu hỏi đó trong các cuộc phỏng vấn.

Tôi cảm thấy như nhạc sĩ jazz không thể đọc được nhạc. Tôi vẫn có thể chơi tốt. Tôi biết về hashtables (quái, tôi đã phát minh ra hashtables trước khi tôi biết rằng chúng đã được phát minh) và các cấu trúc dữ liệu quan trọng khác, và tôi thậm chí có thể biết một số thủ thuật mà chúng không dạy ở trường. Nhưng tôi nghĩ rằng sự thật là nếu bạn muốn thành công trong nghề này, bạn sẽ cần phải đi indie hoặc tìm hiểu câu trả lời cho các câu hỏi mà họ sẽ hỏi trong các cuộc phỏng vấn.

Tình cờ, gần đây nhất tôi đã phỏng vấn cho vai trò nhà phát triển web mặt trước. Họ hỏi tôi một câu hỏi trong đó câu trả lời đòi hỏi cả kiến ​​thức về độ phức tạp tính toán và logarit. Tôi đã xoay sở để nhớ đủ toán từ hai mươi năm trước để trả lời nó ít nhiều chính xác, nhưng nó hơi bị chói tai. Tôi chưa bao giờ phải sử dụng logarit trong bất kỳ sự phát triển mặt trước nào.

Chúc bạn may mắn!


2
Vì vậy, câu trả lời của bạn là "có"?
Raphael

6
TL; DR: "có". Tuy nhiên, theo kinh nghiệm của tôi, bạn sẽ không nói về độ phức tạp tính toán trong hầu hết các công việc sau khi bạn được tuyển dụng. Vâng, biết cấu trúc dữ liệu của bạn và hiệu suất của chúng, nhưng chỉ cần biết rằng thuật toán là O (n) hoặc bất cứ điều gì không phải là một lập trình viên giỏi thực hiện. Tốt hơn hết là tập trung vào viết mã tốt một cách nhanh chóng và sau đó tối ưu hóa các điểm nóng sau này. Khả năng đọc và khả năng bảo trì thường quan trọng đối với hầu hết các mã hơn hiệu năng.
Scott Schafer

3
Tôi nghĩ có thể xảy ra sự phức tạp xuất hiện trong môi trường doanh nghiệp, nhưng mối quan tâm thực sự đầu tiên đối với các công ty là vận chuyển : nếu nó hoạt động, nó đủ tốt, cho đến khi có ngân sách để cải thiện ứng dụng hoặc khách hàng quay lại phàn nàn về người nghèo biểu diễn. Trong các tình huống b2b cho các dự án adhoc, có lẽ nó khá hiếm. Trong b2c, hoặc trong các thị trường cạnh tranh cao (ngoài các sản phẩm trên kệ), nó có thể sẽ xuất hiện thường xuyên hơn, với hiệu quả trực tiếp là nâng thanh nhập cảnh cho tuyển dụng mới.
didierc

4
@didierc "Đủ tốt" cũng là thứ phá vỡ mọi thứ mọi lúc.
Raphael

1
@didierc 1) Chà, những người có nền tảng vững chắc trong CS làm (hy vọng) có trực giác tốt cho những gì đúng và những gì không, trong khi những người giải quyết vấn đề đặc biệt có thể phạm phải những lỗi "đơn giản". Đảm bảo rằng việc thực hiện sau khi tổng hợp nhiều phần chính xác là những gì cụ thể là rất không tầm thường và là một vấn đề chưa được giải quyết. 2) Không .
Raphael

9

Câu hỏi khá chủ quan, vì vậy tôi nghĩ rằng câu trả lời là tùy thuộc .

Sẽ không thành vấn đề nếu bạn làm việc với một lượng nhỏ dữ liệu. Trong những trường hợp này, thường sử dụng bất cứ điều gì, ví dụ như thư viện chuẩn của ngôn ngữ của bạn cung cấp.

Tuy nhiên, khi bạn xử lý một lượng lớn dữ liệu hoặc vì một số lý do khác mà bạn khăng khăng rằng chương trình của bạn nhanh, thì bạn phải hiểu độ phức tạp tính toán. Nếu bạn không, làm thế nào để bạn biết cách giải quyết vấn đề, hoặc thậm chí có thể giải quyết vấn đề đó nhanh đến mức nào? Nhưng chỉ hiểu lý thuyết là không đủ để trở thành một lập trình viên thực sự giỏi. Để tạo mã cực nhanh, tôi tin rằng, bạn cũng phải hiểu cách máy của bạn hoạt động (bộ nhớ cache, bố cục bộ nhớ, tập lệnh) và trình biên dịch của bạn làm gì (trình biên dịch làm tốt nhất, nhưng không hoàn hảo).

Tóm lại, tôi nghĩ rằng sự hiểu biết phức tạp rõ ràng làm cho bạn trở thành một lập trình viên tốt hơn.


1
Tôi nghĩ rằng bạn thường có ý tưởng đúng, nhưng "chủ quan" không mô tả vấn đề này đầy đủ; "hoàn cảnh" sẽ là một từ tốt hơn. Ngoài ra, người ta có thể viết các chương trình rất chậm mà không hoạt động trên nhiều dữ liệu. Gần đây tôi đã trả lời một câu hỏi trên math.se về biểu diễn / lưu trữ đa thức. Điều đó thường liên quan đến một lượng dữ liệu khá nhỏ, ví dụ ~ đa thức 1000 kỳ là điển hình; tuy nhiên, có sự khác biệt lớn trong thế giới thực về hiệu suất (hàng trăm hoặc hàng nghìn giây so với vài giây cho phép nhân) tùy thuộc vào việc thực hiện.
Fizz

4

Đó chắc chắn là một vấn đề nếu ai đó đang phát triển các thuật toán quan trọng không hiểu được độ phức tạp của thuật toán. Người dùng thuật toán thường dựa vào chất lượng thực hiện tốt có các đặc tính hiệu suất tốt. Mặc dù độ phức tạp không phải là yếu tố duy nhất đóng góp cho các đặc tính hiệu năng của thuật toán, nhưng nó là một yếu tố quan trọng. Một người không hiểu độ phức tạp của thuật toán sẽ ít có khả năng phát triển các thuật toán với các đặc tính hiệu suất hữu ích.

Nó ít gây ra vấn đề cho người dùng thuật toán, giả sử các thuật toán có sẵn có chất lượng tốt. Điều này đúng với các nhà phát triển sử dụng các ngôn ngữ có thư viện chuẩn, được chỉ định rõ ràng, được chỉ định - họ chỉ cần biết cách chọn một thuật toán đáp ứng nhu cầu đó. Vấn đề xuất hiện ở chỗ chúng là nhiều thuật toán thuộc một số loại (giả sử, sắp xếp) có sẵn trong một thư viện, bởi vì độ phức tạp thường là một trong những tiêu chí để chọn giữa. Một nhà phát triển không hiểu sự phức tạp thì không thể hiểu được cơ sở để chọn một thuật toán hiệu quả cho nhiệm vụ của họ.

Sau đó, có những nhà phát triển tập trung vào (vì muốn mô tả tốt hơn) những mối quan tâm phi thuật toán. Ví dụ, họ có thể tập trung vào phát triển giao diện người dùng trực quan. Các nhà phát triển như vậy thường sẽ không cần phải lo lắng về độ phức tạp của thuật toán mặc dù, một lần nữa, họ có thể dựa vào các thư viện hoặc mã khác được phát triển với chất lượng cao.


3

Nó phụ thuộc, nhưng không phụ thuộc vào lượng dữ liệu bạn đang làm việc, mà phụ thuộc vào loại công việc bạn làm, các chương trình bạn phát triển.

Chúng ta hãy gọi cho lập trình viên mà không biết về lập trình viên không phức tạp về khái niệm.

Các lập trình viên noobish có thể làm:

  • phát triển cơ sở dữ liệu lớn - anh ta không cần phải biết cách thức hoạt động bên trong, tất cả những gì anh ta phải biết là các quy tắc về phát triển cơ sở dữ liệu. Anh ta biết những thứ như: những gì nên được lập chỉ mục, ... nơi tốt hơn là tạo ra sự dư thừa trong dữ liệu, nơi không ...
  • làm trò chơi - anh ta chỉ cần nghiên cứu cách một số công cụ trò chơi hoạt động và tuân theo mô hình, trò chơi và đồ họa máy tính của nó là một vấn đề dữ liệu khá lớn. Xem xét 1920 * 1080 * 32bit = cca 7,9 MB cho một ảnh / khung hình duy nhất ... @ 60 FPS, tốc độ tối thiểu là 475 MB / s. Hãy xem xét, chỉ một bản sao không cần thiết của ảnh toàn màn hình sẽ lãng phí khoảng 500 MB thông lượng bộ nhớ mỗi giây. Nhưng, anh ta không cần quan tâm đến điều đó, vì anh ta chỉ sử dụng động cơ!

Các lập trình viên noobish không nên làm:

  • phát triển các chương trình phức tạp được sử dụng rất thường xuyên, bất kể kích thước của dữ liệu mà nó hoạt động, ... ví dụ, dữ liệu nhỏ sẽ không gây ra tác động đáng chú ý của giải pháp không phù hợp trong quá trình phát triển, vì nó sẽ chậm hơn thời gian biên dịch, v.v. giây cho một chương trình đơn giản không phải là nhiều từ góc độ lập trình viên mới, Vâng, hãy xem xét máy chủ máy chủ, chạy chương trình này hai mươi lần mỗi giây. Nó sẽ đòi hỏi 10 lõi để có thể duy trì tải đó!
  • phát triển các chương trình cho các thiết bị nhúng. Các thiết bị nhúng hoạt động với dữ liệu nhỏ, nhưng chúng cần phải hiệu quả nhất có thể, bởi vì các hoạt động dư thừa tạo ra sự tiêu hao năng lượng không cần thiết

Vì vậy, lập trình viên noobish là tốt, khi bạn muốn chỉ sử dụng công nghệ. Vì vậy, khi nói đến việc phát triển các giải pháp mới, công nghệ tùy chỉnh, v.v ... Vậy thì tốt hơn là thuê người lập trình không nũng nịu.

Tuy nhiên, nếu công ty không phát triển công nghệ mới, chỉ sử dụng những công nghệ đã được tạo ra. Sẽ thật lãng phí tài năng khi thuê lập trình viên giỏi và tài năng. Điều tương tự cũng áp dụng, nếu bạn không muốn làm việc trên các công nghệ mới và bạn sẽ ổn khi đưa ý tưởng của khách hàng vào các thiết kế và chương trình sử dụng các khung đã được tạo sẵn, thì sẽ lãng phí thời gian của bạn, để tìm hiểu thứ gì đó bạn sẽ không cần, ngoại trừ nếu đó là sở thích của bạn và bạn thích những thách thức logic.


1
Câu trả lời này có thể được cải thiện nếu nó sử dụng nhãn trung tính hơn hoặc hoàn toàn không có nhãn, giống như câu trả lời khác sử dụng thuật ngữ "lập trình viên bất tài".
Đĩa Moby

1
Tôi không chắc ý của bạn là "sự phức tạp về khái niệm". Kinh nghiệm của tôi là những người không biết đủ về cây hoặc hashtables không thể đưa ra quyết định thông minh về cách lập chỉ mục (một phần) cơ sở dữ liệu lớn.
Fizz

3

Tôi hơi do dự khi viết một câu trả lời ở đây nhưng vì tôi thấy mình đang cảm thấy khó chịu với một số người khác [một số ý kiến ​​của tôi đã được chuyển sang trò chuyện], đây là cách tôi nhìn thấy nó ...

Có nhiều cấp độ / mức độ kiến ​​thức cho rất nhiều thứ trong điện toán (và theo thuật ngữ này, tôi muốn nói đại khái là sự kết hợp giữa khoa học máy tính với công nghệ thông tin). Độ phức tạp tính toán chắc chắn là một lĩnh vực rộng lớn (Bạn có biết OptP là gì không? Hoặc định lý Abiteboul-Vianu nói gì?) Và cũng thừa nhận rất nhiều chiều sâu: hầu hết những người có bằng CS không thể đưa ra bằng chứng chuyên môn đi vào nghiên cứu ấn phẩm trong tính phức tạp tính toán.

n2

Tôi thực sự dám so sánh tình huống biết khi nào nên áp dụng các khái niệm phức tạp tính toán (và biết khi nào bạn có thể bỏ qua chúng một cách an toàn) với thực tiễn hơi phổ biến (bên ngoài thế giới Java) khi thực hiện một số mã nhạy cảm hiệu năng trong C và không nhạy cảm hiệu năng nội dung trong Python, v.v. (Như một bên, điều này được gọi trong Julia nói về "sự thỏa hiệp tiêu chuẩn" .) Biết khi nào bạn không phải nghĩ về hiệu suất giúp bạn tiết kiệm thời gian lập trình, đó cũng là một mặt hàng khá có giá trị.

Và một điểm nữa là việc biết độ phức tạp tính toán sẽ không tự động giúp bạn tối ưu hóa các chương trình; bạn cần hiểu thêm các công cụ liên quan đến kiến ​​trúc như cục bộ bộ đệm, [đôi khi] đường ống và ngày nay cũng lập trình song song / đa lõi; cái sau có cả lý thuyết phức tạp của riêng nó và những cân nhắc thực tế là tốt; một hương vị sau này từ một bài báo SOSP 2013 "Mọi kế hoạch khóa đều có mười lăm phút nổi tiếng. Không có chín kế hoạch khóa nào chúng tôi xem xét vượt trội so với bất kỳ kiến ​​trúc nào khác, trên tất cả các kiến ​​trúc mục tiêu hoặc khối lượng công việc. Nói đúng ra, để tìm kiếm sự tối ưu, một Do đó, nên chọn thuật toán khóa dựa trên nền tảng phần cứng và khối lượng công việc dự kiến. "


1
Về lâu dài, phát triển hoặc tìm kiếm một thuật toán tốt hơn thường có lợi hơn so với việc thay đổi ngôn ngữ lập trình cho các bit nhạy cảm hiệu năng. Tôi đồng ý với bạn rằng có một mối liên hệ mạnh mẽ giữa việc thiếu hiểu biết về độ phức tạp và tối ưu hóa sớm - bởi vì chúng thường nhắm mục tiêu các bit ít nhạy cảm hiệu năng để tối ưu hóa.
Cướp

1
Trong thực tế, (vô tình) Schlemiel Các thuật toán của Họa sĩ thường xuyên hơn nhiều so với sắp xếp O (n ^ 2).
Peter Mortensen

-1

Nếu bạn không biết big-O, bạn nên học nó. Nó không khó, và nó thực sự hữu ích. Bắt đầu với việc tìm kiếm và sắp xếp.

Tôi nhận thấy rằng rất nhiều câu trả lời và nhận xét đề nghị hồ sơ , và hầu như chúng luôn có nghĩa là sử dụng một công cụ định hình .

Vấn đề là, các công cụ định hình trên khắp bản đồ về mức độ hiệu quả của chúng để tìm kiếm những gì bạn cần để tăng tốc. Ở đây tôi đã liệt kê và giải thích những quan niệm sai lầm mà các trình hồ sơ mắc phải.

Kết quả là các chương trình, nếu chúng lớn hơn một bài tập học thuật, có thể chứa những người khổng lồ đang ngủ , mà ngay cả trình hồ sơ tự động tốt nhất cũng không thể lộ ra. Bài đăng này cho thấy một vài ví dụ về cách các vấn đề hiệu suất có thể ẩn khỏi trình biên dịch.

Nhưng họ không thể trốn tránh kỹ thuật này.


Bạn tuyên bố "Big-Oh" là hữu ích nhưng sau đó bạn ủng hộ một cách tiếp cận khác. Ngoài ra, tôi không thấy cách học "Big-Oh" (toán học) có thể "bắt đầu với việc tìm kiếm và sắp xếp" (các vấn đề về thuật toán).
Raphael

@Raphael: Tôi không ủng hộ một cách tiếp cận khác - đó là trực giao.Big-O là kiến ​​thức cơ bản để hiểu các thuật toán, trong khi tìm các vấn đề về hiệu năng trong phần mềm phi đồ chơi là điều bạn làm sau khi mã được viết và chạy, không phải trước đó. (Đôi khi các học giả không biết điều này, vì vậy họ tiếp tục dạy gprof, gây hại nhiều hơn lợi.) Khi làm như vậy, bạn có thể hoặc không thể thấy rằng vấn đề là sử dụng thuật toán O (n * n), vì vậy bạn nên có thể nhận ra điều đó. (Và big-O chỉ là một thuộc tính toán học được xác định theo thuật toán, không phải là một chủ đề khác.)
Mike Dunlavey

"Và big-O chỉ là một thuộc tính toán học được xác định theo thuật toán, không phải là một chủ đề khác." - đó là sai, và nguy hiểm là như vậy. "Big-Oh" định nghĩa các lớp chức năng ; mỗi lần, nó không liên quan gì đến thuật toán cả.
Raphael

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.