Làm thế nào quan trọng là biết làm thế nào để lập trình cho TCS?


66

Đến từ một nền tảng toán học hơn, tôi không bao giờ thực sự học cách viết mã. Tôi đang bắt đầu học tiến sĩ về TCS và nhiều người ngạc nhiên về việc tôi biết rất ít về lập trình (và về máy tính nói chung). Tôi có thể viết các thuật toán bằng mã giả, nhưng tôi không thực sự biết bất kỳ ngôn ngữ lập trình nào.

Tôi có thể tưởng tượng rằng một ngày nào đó tôi có thể phải thực hiện một số thuật toán cho công việc của mình, nhưng sau đó tôi có thể chờ đợi thời điểm này không? Hay là có gì hơn?

Làm thế nào quan trọng là biết cách viết mã trong TCS (trong các lĩnh vực mà lập trình không liên quan trực tiếp): có lý do nào có thể khiến một nhà lý thuyết CC (ví dụ) biết cách viết mã không? Có đáng để dành nhiều thời gian để học cách viết mã? Và nếu có, có một phạm trù (chức năng, mệnh lệnh, hướng đối tượng ..) của ngôn ngữ lập trình sẽ phù hợp hơn không?


12
Bạn nên lập trình một số để viết có ý nghĩa, tức là xác định và phản ánh thời gian chạy, mã giả. Các nhà toán học thường không làm. Ngoài ra, nếu bạn muốn thực sự sử dụng lý thuyết bạn phát triển, rất có thể bạn sẽ phải thực hiện một cái gì đó. Đối với ngôn ngữ, có lẽ bạn nên học một cái gì đó có chức năng. C là tốt cho hiệu suất nhưng khó lý luận và lộn xộn về nhiều mặt. (Như bạn có thể thấy, YMMW)
Raphael

6
Tôi đồng tình với "Các nhà toán học thường không làm." Một bài kiểm tra đơn giản cho việc một nhà toán học mô tả thuật toán đã thực sự được lập trình hay chưa là hỏi " Chính xác ý bạn là gì khi nói 'Đưa ra một X ...'?"
Jeffε

4
Lập trình, cái gì vậy? Các định lý là chương trình của tôi. Một quy trình nấu ăn khác với nghệ thuật nấu ăn. Xin lỗi, trong hơn 20 năm tôi không thể đọc bất kỳ mã chương trình nào. Trên thực tế, tôi ghét sự lộn xộn "được hiện thực hóa trên PC" này. (Đã ký hiệu này làm cho bệnh.) Euclid không thể lập trình. Tuy nhiên, ông đã thực hiện các chương trình trong nhiều thế kỷ.
Stasys

6
@StasysJukna: Euclid thực sự là một lập trình viên thực sự rất nhảm nhí. Anh ta không chỉ không bao giờ thực hiện các thuật toán của mình, thậm chí anh ta còn không bao giờ chạy chúng bằng tay trên các trường hợp thử nghiệm phức tạp vừa phải.
Jeffε

3
@ Jɛ E: Vâng, Euclid là một lập trình viên ngu ngốc, chính xác là điều tôi muốn nói. Chúng tôi, trong TCS, đang có xu hướng không phân biệt giữa sách nấu ăn và nghệ thuật đá gà. Euclid có thể. Tôi rất tôn trọng những người CÓ THỂ lập trình. Nhưng tôi không nghĩ rằng tính năng này có nghĩa là "một CAN trong TCS". Nó sẽ không đau.
Stasys

Câu trả lời:


55

Khoa học máy tính lý thuyết là một lĩnh vực rộng lớn và tầm quan trọng của lập trình phụ thuộc vào những gì bạn làm trong TCS. Tôi sẽ đề cập đến hai cách mà lập trình có thể giúp bạn, mà không ngụ ý rằng đây là những cách duy nhất.

Đầu tiên, nếu bạn thiết kế các thuật toán cho các vấn đề có tầm quan trọng thực tế, việc triển khai các thuật toán của bạn và làm cho mã có sẵn cho người khác có thể là một điểm cộng lớn. Ví dụ, vấn đề vỏ lồi phát sinh trong nhiều lĩnh vực và mọi người sử dụng các gói phần mềm như cdd của Komei Fukuda và lrs của David Avis để giải quyết vấn đề này. Nếu họ đã xuất bản thuật toán của họ chỉ trên các bài báo, có lẽ ít người sẽ sử dụng thuật toán của họ. Nhiều người dùng hơn có nghĩa là nhiều phản hồi hơn và có lẽ cũng có nhiều cơ hội hợp tác hơn, đó là điều vô giá.

Thứ hai, ngay cả khi bạn không làm việc trong các thuật toán, viết mã một lần giúp bạn kiểm tra một phỏng đoán đơn giản khi phỏng đoán phù hợp với tính toán số. Ví dụ: nếu bạn tự hỏi liệu sản phẩm của ba ma trận xác định dương luôn có dấu vết dương hay không, thì có thể dễ dàng viết mã để kiểm tra nó cho một số lựa chọn ngẫu nhiên của ma trận xác định dương 2 × 2 hoặc 3 × 3 và tìm một ví dụ mẫu. Mặc dù bạn không quảng cáo rằng bạn đã viết bất kỳ chương trình nào để kiểm tra phỏng đoán, lập trình có thể tiết kiệm thời gian vô ích khi cố gắng chứng minh một tuyên bố sai.

Ngôn ngữ lập trình để lựa chọn phụ thuộc vào những gì bạn muốn làm với lập trình, và nó có thể là một chủ đề cho toàn bộ cuốn sách theo ý kiến ​​của tôi. Nhưng nếu bạn thiết kế các thuật toán và muốn thực hiện các thuật toán của mình để người khác có thể sử dụng triển khai, thì một yếu tố quan trọng là tính khả dụng. Mặc dù bạn có thể mong đợi rằng hầu hết người dùng tiềm năng của mã của bạn đều có quyền truy cập vào trình biên dịch C, nhưng bạn không thể mong đợi rằng cùng một người có quyền truy cập vào trình biên dịch Haskell. Đối với các chương trình một lần, sự lựa chọn dựa trên các thư viện có sẵn và bao gồm các môi trường như Matlab.

Nhân tiện, lập trình cũng có thể là niềm vui.


2
@SureshVenkat: Trên thực tế, nếu lập trình là niềm vui, câu hỏi về mức độ quan trọng của lập trình? Có thể không liên quan lắm. Nhưng sau đó, phần lớn câu trả lời của tôi sẽ trở nên không liên quan. Buồn làm sao! :)
Tsuyoshi Ito

Tôi đã không nghĩ về cuộc tranh luận thứ hai của bạn trước đây, thực sự có vẻ là một ý tưởng thực sự tốt để kiểm tra một phỏng đoán với một chương trình ngắn! Đối với lập trình có thể là niềm vui, có vẻ như vậy, nhưng tôi vẫn chưa thấy hết việc học cuối tuần dài =).
Gopi

@Gopi: Điều đó nói rằng, nhiều phỏng đoán không phù hợp với bài kiểm tra này với một khung chương trình đơn giản. Ví dụ, chúng tôi thường không thể kiểm tra các hành vi tiệm cận (ít nhất là bằng một chương trình đơn giản). Nhưng khi bạn có một số phỏng đoán có thể được kiểm tra, một lập trình nhỏ có thể là một công cụ mạnh mẽ. Đối với niềm vui, vâng, tôi hiểu. Tôi chỉ không muốn bỏ qua quan điểm về niềm vui của người Viking bằng cách chỉ liệt kê một số động lực từ quan điểm của tính hữu dụng của YouTube.
Tsuyoshi Ito

3
Ghi chú của Knuth về một lớp giải quyết vấn đề có một ví dụ tuyệt vời về sự tương tác giữa các phỏng đoán và mã (xem Bài toán 1): www-cs-facemony.stanford.edu/~knuth/ con / cs1055.pdf (Tôi đặc biệt thích hình ảnh của ai đó ùa vào lớp học với một đống bản in)
Suresh Venkat

47

Tôi cảm thấy buộc phải trích dẫn Doron Zeilberger về điều này:

Ý kiến ​​37 : Lập trình thậm chí còn thú vị hơn cả việc cung cấp, và, điều quan trọng hơn là nó mang lại càng nhiều, nếu không phải là nhiều hơn, cái nhìn sâu sắc và hiểu biết.

Đọc ý kiến, nó đầy đá quý (btw anh ấy có xu hướng cố tình khiêu khích). Ví dụ: "Cách tốt nhất để hiểu một cái gì đó là dạy nó. Nhưng thậm chí tốt hơn sau đó dạy nó cho con người là dạy nó cho máy tính".

Kinh nghiệm cá nhân của tôi là ngay cả khi làm công việc lý thuyết thuần túy, bạn sẽ cần một số công cụ tính toán. Tôi tránh được rất nhiều thao tác đại số thông thường tẻ nhạt với Mathematica. Tôi kiểm tra các phỏng đoán nửa nướng của mình bằng cách bắt buộc các trường hợp nhỏ trên Matlab hoặc Python. Tôi đã cùng viết một bài báo về sự kết hợp thuần túy và đó là công việc được hưởng lợi nhiều nhất từ ​​việc chạy các thí nghiệm máy tính rộng rãi để hiểu những gì đang diễn ra. Euler đã tạo ra những bảng tính toán tẻ nhạt để hiểu rõ hơn về các vấn đề. Chúng tôi nợ anh ấy để sử dụng các công cụ của chúng tôi để tự động hóa quá trình này khi chúng tôi làm toán học.

Bên cạnh đó, nếu bạn làm việc trên các thuật toán và cấu trúc dữ liệu, lập trình sẽ đưa ra một viễn cảnh không thể thay thế về các vấn đề về hiệu quả và khả năng sử dụng. Ý kiến ​​của tôi ở đây khác với những người khác một chút. Tôi nghĩ rằng việc học một ngôn ngữ chức năng để bạn có thể viết bằng chứng loại chính xác là một sự lãng phí thời gian (tôi nghĩ rằng đó là một điểm tuyệt vời mà những người có kinh nghiệm với một ngôn ngữ đánh máy mạnh có thể có xu hướng viết bằng chứng có cấu trúc cẩn thận hơn; Tôi không nghĩ rằng nó đáng để bạn dành thời gian để trải qua bài tập đó). Lập trình chức năng che khuất các vấn đề về thiết kế thuật toán và thời gian chạy và nhấn mạnh các vấn đề logic và ngữ nghĩa (và tất nhiên, học lập trình chức năng có lẽ là điều bắt buộc và sẽ đến một cách tự nhiên nếu bạn quan tâm đến ngữ nghĩa logic / PL). Tương tự như vậy, Tôi nghĩ rằng việc đi sâu vào các chi tiết OO của Java và C ++ cũng không phải là cách tối ưu để sử dụng thời gian của bạn, vì mục đích của OO là viết mã có thể sử dụng lại theo mô-đun. Đó là cách để đi nếu bạn tạo mã cho người khác sử dụng. Nhưng trong trường hợp bạn muốn hiểu rõ hơn về hiệu quả và thời gian chạy, nếu bạn quan tâm đến các thuật toán và cấu trúc dữ liệu thực sự hiệu quả, tôi thứ hai gợi ý để xem xét C. Nó cho phép bạn ở gần máy trong khi vẫn cung cấp mức độ trừu tượng hợp lý . Bằng cách này, bạn sẽ cảm nhận được cái gì nhanh và cái gì chậm, cấu trúc dữ liệu hợp lý, v.v. Nhưng trong trường hợp bạn muốn hiểu rõ hơn về hiệu quả và thời gian chạy, nếu bạn quan tâm đến các thuật toán và cấu trúc dữ liệu thực sự hiệu quả, tôi thứ hai gợi ý để xem xét C. Nó cho phép bạn ở gần máy trong khi vẫn cung cấp mức độ trừu tượng hợp lý . Bằng cách này, bạn sẽ cảm nhận được cái gì nhanh và cái gì chậm, cấu trúc dữ liệu hợp lý, v.v. Nhưng trong trường hợp bạn muốn hiểu rõ hơn về hiệu quả và thời gian chạy, nếu bạn quan tâm đến các thuật toán và cấu trúc dữ liệu thực sự hiệu quả, tôi thứ hai gợi ý để xem xét C. Nó cho phép bạn ở gần máy trong khi vẫn cung cấp mức độ trừu tượng hợp lý . Bằng cách này, bạn sẽ cảm nhận được cái gì nhanh và cái gì chậm, cấu trúc dữ liệu hợp lý, v.v.


10
"Lập trình chức năng che khuất các vấn đề về thiết kế thuật toán và thời gian chạy và nhấn mạnh các vấn đề logic và ngữ nghĩa". Từ chiến đấu :)
Suresh Venkat

3
"Lập trình chức năng che khuất các vấn đề về thiết kế thuật toán và thời gian chạy và nhấn mạnh các vấn đề logic và ngữ nghĩa." Đó là lý do tại sao nó là một lựa chọn tốt nếu bạn làm việc trong lĩnh vực logic hoặc ngữ nghĩa của TCS. :)
Radu GRIGore


3
@Sasho: Tất cả các kỹ thuật thông thường vẫn hoạt động trong các ngôn ngữ chức năng. "Vấn đề" duy nhất là lập trình chức năng khuyến khích một phong cách lập trình và thiết kế cấu trúc dữ liệu mà các kỹ thuật phân tích thuật toán thông thường không được trang bị để xử lý. (Ví dụ, phần lớn của thành phần chức năng là gì? Hoạt động này không quan trọng , nhưng nó hoàn toàn phá vỡ các giả định về độ phức tạp tiệm cận - không có số liệu kích thước số đơn giản nào cho đầu vào chức năng.)
Neel Krishnaswami

3
@SashoNikolov: Bất cứ khi nào tôi dạy một lớp cấu trúc dữ liệu tốt nghiệp, tôi thực sự thực sự ước mình có thể cho rằng mọi người đều có một số kinh nghiệm lập trình chức năng. Thay vì dành ba bài giảng dài 90 phút để giải thích sự kiên trì, tôi chỉ có thể nói "Này, bạn có để ý rằng cấu trúc dữ liệu của bạn đã làm NÀY không?"
Jeffε

33

Bạn có thể là một nhà khoa học máy tính lý thuyết khá thành công mà không cần lập trình. Đối với một số người, việc lập trình khá khó khăn và nếu bạn là một trong số họ, bạn không nên tuyệt vọng và chuyển trường.

Tuy nhiên, đối với hầu hết sinh viên tốt nghiệp ngành toán và khoa học máy tính, học lập trình không phải là điều đặc biệt khó khăn và là một kỹ năng rất hữu ích. Bạn nên học một ngôn ngữ lập trình, và nếu bạn thích nó, bạn nên cố gắng thực hành đủ để trở nên thành thạo một cách hợp lý. Sau đó, khi có ý kiến ​​(và nó sẽ) rằng nó sẽ hữu ích trong nghiên cứu của bạn để viết một chương trình, bạn sẽ có thể làm điều đó.

Nếu bạn không học lập trình ngay bây giờ, có khả năng là cuối cùng khi bạn cần viết chương trình, bạn sẽ không có thời gian để học, và vì vậy bạn có thể không thực sự viết nó, và cuối cùng bạn sẽ kém hiệu quả hơn nghiên cứu. Mặc dù có được một sinh viên tốt nghiệp hoặc một sinh viên chưa tốt nghiệp để làm điều này cho bạn không quá khó, có nhiều lúc việc tự làm nó dễ dàng hơn và ít tốn thời gian hơn là giải thích vấn đề cho họ.

Bạn nên học ngôn ngữ nào? Tôi muốn giới thiệu một ngôn ngữ hướng đối tượng, vì đây là những ngôn ngữ hiện đang được sử dụng nhiều nhất và tôi nghi ngờ điều này sẽ đúng hơn trong tương lai. Có thể Python hoặc Java, cả hai đều là ngôn ngữ hướng đối tượng và trong khi chúng được sử dụng ít hơn trong thực tế so với C ++, ấn tượng của tôi là cả hai đều dễ học hơn nhiều. (Hãy cẩn thận: Tôi không biết C ++, mặc dù đã làm việc tại Bell Labs, vì vậy có lẽ tôi đã sai về điều này.)


2
Tôi thấy sự thật trong đoạn thứ ba của bạn :).
Gopi

1
"Tuy nhiên, đối với hầu hết mọi người, học lập trình không đặc biệt khó khăn" - kinh nghiệm của tôi khiến tôi không đồng ý với điều này, nhưng hầu hết mọi người không phải là nhà nghiên cứu của TCS.
Tối đa

2
Với sự phát triển của Sage, có thể làm việc với một ngôn ngữ phổ biến, đẹp như Python trong khi vẫn có sẵn các thư viện toán học theo kiểu Mathicala / Maple / Matlab.
András Salamon

1
C ++ có hệ thống lập trình / siêu dữ liệu tiên tiến nhất của bất kỳ ngôn ngữ lập trình mục đích chung chính thống nào tôi từng thấy, ngoại trừ họ ngôn ngữ Lisp. Vì vậy, nếu bạn đi vào lý thuyết loại, thiết kế ngôn ngữ hoặc lý thuyết trình biên dịch, hoặc rộng hơn là vào ngữ nghĩa chính thức, bạn có thể muốn làm quen với nó. Ngoài C ++, Java và C # là điều bắt buộc nếu bạn muốn thực hiện nghiên cứu về Khoa học máy tính thử nghiệm hoặc hy vọng có được công việc là lập trình viên hoặc kỹ sư phần mềm trong ngành. Python nên được dạy trong các trường trung học: D
Antonio Valerio Miceli-Barone

4
@ AntonioValerioMiceli-Barone: Tôi phải không đồng ý, ít nhất là đối với lý thuyết loại, thiết kế ngôn ngữ, ngữ nghĩa chính thức và lý thuyết ngôn ngữ lập trình (PLT) nói chung: C ++ không phải là ngôn ngữ để học cho các lĩnh vực đó; TT và ngữ nghĩa chính thức hầu như chỉ liên quan đến lập trình chức năng, trong khi cộng đồng PL đa dạng hơn, nhưng thích ngôn ngữ thanh lịch hơn C ++. Haskell là ngôn ngữ "chính thống" với hệ thống loại tiên tiến nhất, tiếp theo là Scala (ít nâng cao hơn, chính thống hơn một chút). C ++ có các tính năng thú vị, nhưng mức độ quá thấp cho hương vị hiện đại.
Blaisorblade

33

Có một câu trả lời khác mà không ai thực sự đưa ra. Lập trình thực sự có thể dẫn đến lý thuyết thú vị. Rất nhiều sự phát triển gần đây trong băm (đặc biệt là băm theo bảng) được thúc đẩy không phải bởi các mối quan tâm về mặt lý thuyết, mà bởi thực tế là các thuật toán tối ưu về mặt lý thuyết không thực sự tuyệt vời trong thực tế. Tất nhiên đây là điều bạn không biết trừ khi bạn có thể viết mã.

Ngay cả trong lĩnh vực của các thuật toán thời gian theo cấp số mũ chính xác, một động lực là tạo ra các thuật toán thực sự có thể hoạt động. Người giải SAT là ví dụ điển hình cho việc này.

Nói tóm lại, khả năng viết mã cho phép bạn nhận ra những thiếu sót và điểm yếu trong những gì có thể trông giống như kết quả lý thuyết tối ưu, và điều đó mở ra hướng nghiên cứu lý thuyết mới.


Câu trả lời của bạn có thể giúp ích cho câu hỏi về kết quả thực nghiệm trong TCS .
Gopi

có thể: nhưng chủ đề đó đã chết từ lâu :)
Suresh Venkat

Thật vậy, tôi đã không nhìn vào ngày, đó là trong bản tin cuối cùng tôi nhận được, trong phần "Lượt truy cập lớn nhất từ ​​các tuần trước" =).
Gopi

18

Ba điểm:

1) Có một cách tiếp cận toán học gọi là Toán học thực nghiệm (xem thêm wikipedia: // Bằng chứng hỗ trợ máy tính ) trong đó bạn sử dụng các chương trình máy tính để điều tra về mô hình và cấu trúc của các đối tượng để đưa ra bằng chứng phân tích về các đối tượng này. Đối với phương pháp này, bạn nên biết cách lập trình. Bạn có thể chắc chắn rằng bạn sẽ thấy mình cần sự tiếp cận này để chứng minh những tuyên bố rất lý thuyết. Tôi tin rằng hợm hĩnh chống lại lập trình thường hóa ra không thực sự hữu ích trong nghiên cứu TCS.

AL(X,Y)BL(Y,C)

3) Khi bạn nói "với chương trình", bạn cũng có nghĩa là " chương trình tuyến tính " hay " chương trình semidefinite "? :)


2
Không ai tôi biết sử dụng "lập trình" cho "chương trình tuyến tính" hoặc "chương trình bán chính xác". Thay vào đó, bạn sẽ nói "để xây dựng / giải quyết một chương trình tuyến tính".
Peter Shor

2
@PeterShor Điểm 3 không nghiêm trọng
Alessandro Cosentino

3
Và tất nhiên, bạn cũng nên học lập trình tuyến tính và chương trình semidefinite ... cả hai kỹ năng hữu ích.
Peter Shor

3
+1 cho điểm 2, tôi thực sự đã được dạy một chút OCaml khi tôi còn là sinh viên chưa tốt nghiệp, mặc dù tôi chỉ sử dụng nó trong một năm, tôi đã có thói quen kiểm tra các loại bằng chứng của mình.
Gopi

4
Tôi lập trình năng động !
Jeffε

16

Cảm ơn bạn Gopi cho câu hỏi này. Tôi muốn mở rộng nhiều câu trả lời thú vị ở một khía cạnh khác chưa được đề cập.

Nghiên cứu không phải là điều duy nhất chúng tôi làm ở trường đại học: nếu bạn muốn ở lại học viện, cuối cùng bạn sẽ phải dạy. Nếu bạn may mắn, bạn sẽ phải dạy các khóa học khá xa khu vực chuyên môn của bạn. Rất có thể bạn sẽ được chỉ định các khóa học với một thành phần lập trình đáng kể. Đây là nơi thậm chí một khả năng vừa phải để lập trình giúp ích đáng kể: bạn sẽ trở thành một giáo viên tốt hơn nhiều nếu bạn biết cách lập trình. Trước hết, bạn sẽ thấy thoải mái hơn với tài liệu này, bạn sẽ có thể trả lời các câu hỏi của sinh viên tốt hơn và bạn hiểu những khó khăn mà sinh viên gặp phải khi học lập trình, vì bạn đã tự mình trải nghiệm quá trình học tập này. Hơn nữa, bạn có thể sản xuất tài liệu giảng dạy tốt hơn. Chẳng hạn, bạn có thể tự kiểm tra các bài tập lập trình trước khi đưa chúng cho sinh viên,

Có một khía cạnh thực dụng bổ sung: giảng dạy bao gồm nhiều nhiệm vụ lặp đi lặp lại mà một lập trình viên lành nghề thường có thể tự động hóa, như nhanh chóng tạo một trang web mà sinh viên có thể sử dụng để gửi bài tập và tự động phân loại (theo số lượng bài kiểm tra tự động mà mã đi qua).


Nếu bạn may mắn, bạn sẽ phải dạy các khóa học ở khá xa khu vực chuyên môn của mình.
Tsuyoshi Ito

3
@ Tsuyoshi: Chà, nó buộc bạn phải làm quen với một chủ đề mới. Trong ngắn hạn, điều đó có nghĩa là rất nhiều công việc (sẽ được khấu hao trong thời gian dài, vì bạn có thể sẽ dạy tài liệu này nhiều lần). Đồng thời, nó mở rộng tầm nhìn trí tuệ của bạn đáng kể.
Martin Berger

@TsuyoshiIto: Vâng!
Jeffε

13

Lập trình là một cách tốt để cải thiện sự hiểu biết của bạn về các khái niệm khác nhau, nhưng nó cũng là một thời gian nguy hiểm.

Một lập luận điển hình chống lại lập trình là nó khiến bạn mất thời gian với những chi tiết không quan trọng; một lập luận điển hình cho lập trình là nó khiến bạn nhận ra rằng các chi tiết bạn nghĩ là không quan trọng trong thực tế rất quan trọng. Trở nên giỏi lập trình chủ yếu có nghĩa là trở nên có khả năng xử lý các phần không quan trọng một cách nhanh chóng. Trở nên tốt đẹp mất một thời gian dài .

Đối với ngôn ngữ lập trình để học: "tất cả chúng" là câu trả lời của tôi.


2
Cuối cùng một lập luận chống lại lập trình :).
Gopi

1
@Gopi, tôi nghĩ rằng lập trình có thể rất thú vị và sự hiểu biết tốt hơn mà bạn đạt được là rất quan trọng. Các câu trả lời khác đưa ra các ví dụ tuyệt vời về cách lập trình giúp hiểu. Vì vậy, tôi sẽ khuyến khích bạn học lập trình và không từ bỏ nếu doanh nghiệp dường như không thanh toán nhanh chóng.
Radu GRIGore

6
Chứng minh các định lý cũng là một cách tốt để cải thiện sự hiểu biết của bạn về các khái niệm khác nhau, nhưng đó cũng là một thời gian nguy hiểm.
Jeffε

@ Jɛ ff E, ý kiến ​​của tôi được bảo tồn bằng cách thay thế [pseudocode-> bằng chứng trên giấy, mã-> bằng chứng trong một trợ lý chứng minh].
Radu GRIGore

12

Tôi đến bữa tiệc muộn, và đây đều là những câu trả lời tuyệt vời, nhưng tôi có một lý do khác:

Hình dung.

Có, thường thì bạn sẽ làm việc với những thứ không thể hình dung được, nhưng thường thì bạn sẽ làm việc với những thứ có thể. Biết cách lập trình là không thể thiếu cho nhiệm vụ này và trực quan hóa có thể cung cấp cho bạn nhiều cái nhìn sâu sắc về một vấn đề.


3
Tôi biết cách lập trình, và tôi hoàn toàn vô vọng khi hình dung. Tôi cũng nghi ngờ rằng có những công cụ sẽ cho phép bạn hình dung mọi thứ mà không cần phải lập trình nhiều; nếu không có, nên có, và có thể sẽ có trong một vài năm nữa.
Peter Shor

@PeterShor: Bởi vì bạn không sử dụng C ++! (Đùa thôi)
Tsuyoshi Ito

1
@PeterShor: Tôi không đề cập đến bất kỳ ngôn ngữ hoặc môi trường cụ thể nào; MATLAB tính ở đây. Nhưng biết làm thế nào để lập trình có thể giúp bạn hình dung mà sẽ vô cùng bất tiện. Ví dụ, không gian của ma trận xác định dương hai chiều là ba chiều và tôi muốn hình dung một họ các cấu trúc trong không gian này. Tôi đã phải đưa ra một chuyển đổi và sau đó mã hóa nó để thực sự nhìn thấy các đối tượng của tôi.
John Moeller

@ John ... bạn nói đúng, tôi không nghĩ bạn có thể làm điều đó theo bất kỳ cách nào khác.
Peter Shor

7

Chỉ cần một điểm nhanh: biết cách lập trình cho tôi một công cụ bổ sung trong nghiên cứu lý thuyết. Khi tôi có một thuật toán mà tôi nghĩ sẽ hoạt động, nếu nó đủ dễ, tôi có thể mã hóa nó và kiểm tra xem nó có thực sự không. Nếu ý tưởng của tôi không (thậm chí) hoạt động trong thực tế, thì nó không có khả năng hoạt động trên lý thuyết và phương pháp này thường giúp tôi không bị chìm trong một lượng lớn thời gian cố gắng chứng minh điều gì đó sai.


Tsuyoshi Ito đã viết một lập luận tương tự trong câu trả lời của mình (điểm thứ hai :)).
Gopi

Rất tiếc, bạn đã đúng - Tôi đã bỏ lỡ nó.
Lev Reyzin

5

Không ai ở đây đã giải quyết các vấn đề thực tế tại sao một người học TCS nên học lập trình.

Nếu bạn dự định làm tiến sĩ về TCS trong khoa Khoa học máy tính, rất có thể bạn sẽ cần tham gia một số khóa học không phải là Lý thuyết, và những khóa học này gần như chắc chắn sẽ rất chuyên sâu về lập trình. Tùy thuộc vào chương trình bạn tham gia, bạn cũng có thể cần kiến ​​thức về các môn học không phải là Lý thuyết để vượt qua các bài kiểm tra trình độ của bạn.

Khi bạn hoàn thành bằng tiến sĩ, hầu hết các cơ hội việc làm cho TCS đều ở trong học viện. Nếu bạn làm việc trong học viện, bạn sẽ được dạy, và bạn có thể được yêu cầu dạy một lớp CS cấp dưới giới thiệu sẽ được lập trình nhiều hơn lý thuyết. Ngay cả khi bạn đang dạy một lớp lý thuyết cho sinh viên đại học, như nói về Thuật toán, bạn có thể mong đợi rằng sinh viên của bạn sẽ biết nhiều về lập trình hơn lý thuyết, và nếu không biết những gì sinh viên của bạn biết, bạn sẽ khó có thể thu hẹp khoảng cách trong sự hiểu biết của họ . Tôi rùng mình khi nghĩ về những sinh viên CS đang được dạy bởi một người không biết lập trình!

Nếu bạn không quan tâm đến những mối quan tâm thực tế này, thì có lẽ bạn có thể nhận được bằng cách nghiên cứu mà không thực sự biết gì về lập trình. Chắc chắn bạn có rất nhiều công ty trong cộng đồng TCS, nhưng số dặm sẽ thay đổi tùy thuộc vào khu vực chính xác của Lý thuyết bạn đang làm việc. Ví dụ, nếu bạn đang thực hiện lý thuyết phức tạp tính toán thuần túy, chứng minh giới hạn thấp hơn trong các lớp mà không ai có đã từng nghe nói, thì có khả năng lập trình sẽ không có ích gì với bạn. Nhưng nếu bạn đang làm một cái gì đó có thuật toán hơn, thì tôi cảm thấy rằng việc có thể viết mã làm việc sạch sẽ tốt sẽ tăng cường trực giác của bạn nếu không có gì khác.

Tôi khuyên bạn nên học C (không phải C ++). Nhặt một bản sao của K & R và đọc nó từ trước ra sau. C không có nhiều tính năng ưa thích của các ngôn ngữ hiện đại, nhưng nó có cú pháp và ngữ nghĩa đơn giản nhưng thanh lịch, mà bạn sẽ có thể học toàn bộ. Tuy nhiên, ngay cả khi bạn hiểu toàn bộ ngôn ngữ, vẫn cần thực hành để thành thạo viết mã không có lỗi thanh lịch tốt trong C. Tuy nhiên, nếu bạn có thể thành thạo mã hóa bằng C, bạn sẽ có thể thành thạo bất kỳ ngôn ngữ lập trình nào bạn gặp phải. Hơn nữa, kỷ luật đó sẽ giúp bạn nghĩ cách phần cứng nghĩ, sẽ có ích khi thiết kế các thuật toán.

Các ý tưởng như con trỏ rất quan trọng đối với bất kỳ ai thiết kế thuật toán, nhưng thật không may, các ngôn ngữ như Java và Python che khuất chúng khỏi bạn, vì vậy đó là lý do tại sao tôi không giới thiệu chúng như ngôn ngữ đầu tiên cho người có nền tảng toán học. OOP quan trọng hơn đối với những người phải duy trì các dự án phần mềm khổng lồ, chứ không phải ai đó đang thiết kế thuật toán.


0

Tôi khuyên bạn không nên chờ bắt đầu khóa học vì khoa học máy tính ở mọi cấp độ liên quan đến việc thực hiện các thuật toán thông qua máy tính để thực hiện / xác minh / giải quyết bất kỳ lý thuyết nào bạn sẽ phải đối mặt trong suốt khóa học của mình, ĐẢM BẢO ở cấp độ của bạn.

Trước tiên tôi phải lập trình vào lớp 10 (cấp ba) và tôi đã biết cách sử dụng một dòng lệnh và điều này thực sự hữu ích (điều này cho bạn thấy các kỹ năng lập trình "cơ bản" được xem xét như thế nào trong CS).

Sự ngạc nhiên của các đồng nghiệp của bạn là hoàn toàn có cơ sở, vì mã giả và thuật toán là một trong những điều đầu tiên người ta phải học để lập trình.

Tuy nhiên, bạn sẽ không bị mất hoàn toàn trong khóa học sắp tới vì bạn có thể sử dụng các kỹ năng toán học rộng hơn (một mình) để bỏ qua lập trình hướng đối tượng để bắt kịp việc học ngôn ngữ lập trình chức năng nhanh hơn.

  • Lập trình hàm là RẤT định hướng toán học, được coi là khó học hơn vì nền tảng toán học cần thiết, được coi là rất mạnh mẽ (theo cách đơn giản, "toán học" của nó để thực hiện các vấn đề khó khăn thông qua các phương tiện thanh lịch và "sạch").
  • Định hướng đối tượng là tốt khi bạn không muốn hiểu các thuật toán cơ bản và nguyên tắc triển khai và chỉ muốn "sử dụng lại" các đối tượng đã có.

Tôi nghĩ rằng bạn có thể giải quyết Haskell (thường không phải là ngôn ngữ đầu tiên) bởi vì nó hoàn toàn là toán học, chức năng và về cơ bản có thể làm bất cứ điều gì bạn muốn. Học Haskell sẽ đưa bạn đến một mức độ mà bạn không cần phải học nhiều hơn để theo kịp, và thậm chí sẽ đặt bạn vào tình huống kiểm soát và nắm quyền trong khóa học của bạn. Nếu bạn đang thống kê, học R là một lợi thế, nhưng không nhiều như Haskell. Tôi đã thấy các báo cáo từ các nhà toán học nói rằng họ ngạc nhiên như thế nào về sự gần gũi với toán học và cách nó chấp nhận cách suy nghĩ của họ.

Ngoài ra, một thách thức đáng để giải quyết (để nhanh chóng làm quen với môi trường lập trình) sẽ là cài đặt và sử dụng Linux (Ubuntu Linux sẽ làm). Tin tôi đi, bạn sẽ học được rất nhiều bằng cách chơi với nó ...

Những lời khuyên này là cách tốt nhất mà tôi biết để bắt kịp nhanh và chắc chắn cho một nhà toán học về khoa học máy tính. Ngoài ra, cộng đồng nguồn mở rất thân thiện và hữu ích và nếu bạn gặp khó khăn, IRC là cách trực tiếp nhất để nói về bất kỳ chủ đề nào thông qua các kênh chuyên biệt (kết nối trên FreeNode). Hãy nhớ rằng: hỏi là cách duy nhất để giải quyết các câu hỏi, cho chính bạn, một diễn đàn, một công cụ tìm kiếm hoặc trong các phòng chat.


4
Tôi không biết bạn trả lời câu hỏi ban đầu bao nhiêu: Tôi không hỏi "làm thế nào", nhưng nhiều hơn "để làm gì".
Gopi

0

Một ví dụ về việc triển khai C ++ của một hệ thống bằng chứng tương tác là bài báo sau: Bằng chứng tương tác tối ưu thời gian để đánh giá mạch, bởi Justin Thaler. Nó có sẵn tại http://people.seas.harvard.edu/~jthaler/ . Nó dường như là một bước tiến tới mục tiêu phát triển triển khai thực tế các hệ thống chứng minh tương tác có mục đích chung.

Các giấy tờ tương tự và mã nguồn liên quan xuất hiện tại trang web được đề cập ở trên.


3
Bạn có thể giải thích bài báo này liên quan đến câu hỏi như thế nào là quan trọng như thế nào là biết cách lập trình cho TCS ?
scaaahu

Ngay cả khi đó là một ví dụ về kết quả lý thuyết được hưởng lợi từ lập trình, nó sẽ không trả lời câu hỏi ban đầu?
Jeremy

Câu hỏi đặt ra nếu cần một nhà lý thuyết phức tạp để biết mã hóa. Bài viết được đề cập ở trên rõ ràng sử dụng kết quả thực nghiệm để bổ sung cho các khái niệm lý thuyết; điều này đòi hỏi mã hóa. Trong mọi trường hợp, tôi đã mất một thời gian rất dài để tìm thấy một dự án lập trình có liên quan mật thiết đến một khái niệm trung tâm trong khoa học máy tính lý thuyết. Tôi hy vọng bài đăng này có thể hữu ích cho ai đó trên một tìm kiếm tương tự.
lgidwani
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.