Phát triển kiến ​​thức lập trình sâu


136

Thỉnh thoảng tôi thấy các câu hỏi về các trường hợp cạnh và sự kỳ lạ khác trên Stack Overflow dễ dàng được trả lời bởi những người như Jon Skeet và Eric Lippert, thể hiện kiến thức sâu sắc về ngôn ngữ và nhiều điều phức tạp của nó, như thế này:

Bạn có thể nghĩ rằng để sử dụng một foreachvòng lặp, bộ sưu tập bạn đang lặp đi lặp lại phải thực hiện IEnumerablehoặc IEnumerable<T>. Nhưng hóa ra, đó không thực sự là một yêu cầu. Điều bắt buộc là loại bộ sưu tập phải có một phương thức công khai được gọi GetEnumeratorvà loại đó phải trả về một loại có bộ nhận tài sản công cộng được gọi Currentvà phương thức công khai MoveNexttrả về a bool. Nếu trình biên dịch có thể xác định rằng tất cả các yêu cầu đó được đáp ứng thì mã được tạo để sử dụng các phương thức đó. Chỉ khi những yêu cầu đó không được đáp ứng, chúng tôi mới kiểm tra xem đối tượng có thực hiện IEnumerablehay không IEnumerable<T>.

Đó là điều tuyệt vời để biết. Tôi có thể hiểu tại sao Eric biết điều này; Anh ấy thuộc nhóm biên dịch, vì vậy anh ấy phải biết. Nhưng những gì về những người thể hiện kiến ​​thức sâu sắc như vậy, những người không phải là người trong cuộc?

Làm thế nào để những người bình thường (những người không thuộc nhóm biên dịch C #) tìm hiểu về những thứ như thế này?

Cụ thể, có những phương pháp mà những người này sử dụng để tìm hiểu một cách có hệ thống những kiến ​​thức như vậy, khám phá nó và tiếp thu nó (biến nó thành của riêng họ)?


10
Tôi nghĩ rằng đây là nơi đặc biệt khi phần mềm nguồn mở tỏa sáng. Thật tuyệt khi có thể bước vào khuôn khổ / hệ thống / thư viện. Tôi đã từng có cách hiểu rõ hơn về các phần bên trong khung khi tôi làm việc với Qt so với khi tôi làm việc với WinForms.
Vitor Py

2
Khi nào bạn cần biết ví dụ cụ thể này, ngoài việc không trông ngớ ngẩn trước đám đông đặc biệt? Họ ngớ ngẩn chứng minh điều này. Ngoài ra, loạt C #, Java, C ++, vv hiệu quả có thể có một số điều thú vị trong đó. Blog của Eric Lippert cũng là một nguồn tốt. Nói chung, chúng ta thường không biết những gì không biết, vì vậy họ nói "sống trong 100 năm, học trong 100 năm và chết một kẻ ngốc".
Công việc

26
Có đáng nỗ lực không? Tôi là người song ngữ và cố gắng học một vài ngôn ngữ nói khác. Tôi đã học một số lớp toán nhưng không đủ. Tôi muốn học cách chơi tennis nửa vời và học bơi bằng cách sử dụng cú đánh bướm. Tôi muốn đi du lịch nhiều hơn. Tôi muốn học một số Clojure. Điều tôi không muốn là trở thành chuyên gia về một ngôn ngữ, có bằng tiến sĩ toán học, dành 30 giờ mỗi tuần trong một hồ bơi như Michael Phelps, v.v. Kiến thức của Lippert và Skeet là do họ đặt rất nhiều nỗ lực trong một (hoặc một vài) điều trong khi bỏ lỡ những trải nghiệm khác. Có thể thay đổi công việc?
Công việc

10
"Tôi có thể hiểu tại sao Eric biết điều này; anh ấy thuộc nhóm biên dịch, vì vậy anh ấy phải biết." - rất có thể anh ta biết điều này bởi vì anh ta nghĩ nó ngay từ đầu . Tôi nghi ngờ anh ta phải 'tìm ra' rằng nó hoạt động như thế này :)
Alex ten Brink

10
@Alex: Tôi thực sự chỉ làm việc trên C # kể từ khi chúng tôi thực sự xây dựng việc triển khai C # 3. Đặc tả "foreach" đã được viết hơn sáu năm trước đó. Tôi vẫn tìm ra những điều lịch sử điên rồ về ngôn ngữ mỗi ngày. Ví dụ, tôi đã học ngày hôm nay rằng đối với các đại biểu, ((A + B) + C) - (A + C) = A + B + C, nhưng ((A + B) + C) - (B + C) = A . Kỳ dị!
Eric Lippert

Câu trả lời:


167

Trước hết, cảm ơn những lời tốt đẹp.

Nếu bạn muốn có kiến ​​thức sâu về C #, chắc chắn có một lợi thế là có đặc tả ngôn ngữ, mười năm ghi chú thiết kế, mã nguồn, cơ sở dữ liệu lỗi, và Anders, Mads, Scott và Peter ở dưới sảnh. Tôi chắc chắn may mắn, không có câu hỏi về nó.

Tuy nhiên, ngay cả khi không có những lợi thế đó, vẫn có thể có được kiến ​​thức sâu rộng về chủ đề này.

Quay lại khi tôi bắt đầu tại Microsoft, tôi đã làm việc với trình thông dịch JScript được cung cấp cùng với Internet Explorer 3. Người quản lý của tôi lúc đó đã nói với tôi điều gì đó là một trong những lời khuyên tốt nhất tôi từng nhận được. Anh ấy nói rằng anh ấy muốn tôi trở thành chuyên gia được công nhận tại Microsoft về cú pháp và ngữ nghĩa của ngôn ngữ JScript, và tôi nên giải quyết vấn đề này bằng cách tìm hiểu các câu hỏi về các khía cạnh của JScript và trả lời chúng. Đặc biệt trả lời các câu hỏi tôi không biết câu trả lời, vì đó là những câu tôi sẽ học được.

Rõ ràng StackOverflow và các diễn đàn Hỏi & Đáp công khai khác giống như uống rượu từ thuốc chữa cháy cho loại điều đó. Trước đó, tôi đã đọc comp.lang.javascript và các diễn đàn "Người dùng JS" nội bộ của chúng tôi một cách tôn giáo và làm theo lời khuyên của người quản lý của tôi: khi tôi thấy một câu hỏi về ngữ nghĩa ngôn ngữ mà tôi không biết câu trả lời, tôi đã trả lời doanh nghiệp của tôi để tìm hiểu.

Nếu bạn muốn thực hiện một "chuyến lặn sâu" như thế, bạn phải lựa chọn cẩn thận. Tôi cho đến ngày nay là đáng kể không biết gì về cách mô hình đối tượng trình duyệt hoạt động. Vì tôi đã tập trung trở thành chuyên gia ngôn ngữ C # trong những năm vừa qua, tôi đặc biệt không biết gì về cách các lớp khác nhau trong các thư viện lớp cơ sở hoạt động. Tôi may mắn vì tôi có một công việc trao giải kiến ​​thức chuyên sâu; nếu công việc hoặc tài năng của bạn phù hợp hơn với việc trở thành một người tổng quát, đi sâu có thể không phù hợp với bạn.

Viết một blog cũng rất hữu ích; bằng cách yêu cầu tôi giải thích các chủ đề phức tạp cho người khác, tôi buộc phải đối mặt với sự hiểu biết không đầy đủ của mình về các chủ đề khác nhau mọi lúc.


14
Không kéo chủ đề này ra, nhưng sau khi đọc câu trả lời này, tôi tò mò về lý do tại sao bạn không hỏi bất kỳ câu hỏi nào ở đây hoặc trên Stack Overflow. Đồng nghiệp của bạn, blog, vv có đủ cho bạn tại thời điểm này? Có tài nguyên nào tốt hơn SO mà chúng ta nên biết không?
Matthew Đọc

6
Có lẽ bạn đã hiểu nhầm những gì anh ấy nói. Theo trực giác, anh không đặt câu hỏi để học hỏi, anh đang trả lời câu hỏi.
jhocking

65

Đã ở bên "guru" của cuộc trò chuyện một hoặc hai lần, tôi có thể nói với bạn rằng rất nhiều lần những gì bạn cho là "kiến thức sâu" về ngôn ngữ lập trình hoặc hệ thống thường là kết quả của "guru" gần đây đang vật lộn một tháng để giải quyết vấn đề chính xác Điều đó đặc biệt đúng trên một diễn đàn nơi mọi người có thể chọn câu hỏi nào họ sẽ trả lời. Ngay cả những người như Jon Skeet và Eric Lippert cũng phải học xin chào thế giới. Họ tiếp thu kiến ​​thức của mình một khái niệm tại một thời điểm, giống như bất kỳ ai khác.


1
Một điểm rất tốt. Tôi thường tìm thấy khi bắt tay vào nghiên cứu trong thời gian dài mà tôi tìm thấy những câu hỏi mà bây giờ tôi có thể trả lời do những điều tôi đã học trước đó trong ngày.
Matthew đọc

47

Diễn giải Yogi Bhajan:

"Nếu bạn muốn học một cái gì đó, hãy đọc về nó; nếu bạn muốn hiểu một cái gì đó, hãy viết về nó; nếu bạn muốn thành thạo một cái gì đó, hãy lập trình nó."

Lập trình giống như thử thách giảng dạy cuối cùng. Dạy máy tính làm một cái gì đó đòi hỏi, rằng bạn biết công cụ của mình thực sự tốt - hoặc bạn sẽ học cách làm chủ nó.

Ví dụ, nếu bạn muốn học vật lý, hãy viết một công cụ vật lý. Nếu bạn muốn học cờ vua, hãy lập trình một ván cờ. Nếu bạn muốn tìm hiểu kiến ​​thức sâu về C #, hãy viết trình biên dịch C # (hoặc một số công cụ khác).


2
Lập trình cũng là một nỗ lực khiêm tốn trong việc viết (tất nhiên là được mọi người đọc) theo cách rõ ràng nhất.
vpit3833

4
Câu nói đó nghe có vẻ rất sâu sắc cho đến khi tôi đọc ví dụ về cờ vua. Thật không may, việc lập trình một AI cờ vua sẽ không giúp bạn trở thành một người chơi cờ giỏi hơn (về cơ bản đó là tìm kiếm trong cây Min-Max). Vẫn +1
bughi

1
@bughi Có lẽ bạn có thể nắm vững các quy tắc: D
Julio

@bughi, 'chương trình' là thuật ngữ rất rộng không phải lúc nào cũng liên quan đến viết mã !! Chỉ cần suy nghĩ một chút ra khỏi hộp.
Nitesh Verma

25

Theo tôi biết, các cách để học điều này là:

  • Đọc về nó từ một người như Eric Lippert
  • Kinh nghiệm và sau đó giải quyết các vấn đề đầu tiên.

Cách thứ hai có thể mất nhiều thời gian hơn nhưng có thể sẽ dẫn đến sự hiểu biết sâu sắc hơn (nhưng không phải lúc nào cũng vậy).


17
Hoặc cả hai. [15 ký tự]
Michael K

23

Tôi sẽ nói làm như sau:

Sau khi học một chồng ngôn ngữ tương đối hữu ích (những ngôn ngữ bạn cần cho một công việc thực tế) ở cấp độ mà bạn có thể thực hiện hầu hết các nhiệm vụ phổ biến, hãy ngừng học thêm ngôn ngữ cho đến khi bạn đã học ít nhất một ngôn ngữ. Theo tôi, một phần của vấn đề trong ngành của chúng tôi là mọi người chỉ học 5-10% ngôn ngữ đầu tiên trước khi chuyển sang một số ngôn ngữ khác. Một khi bạn có khả năng thực hiện hầu hết các nhiệm vụ phổ biến trong công việc, thì hãy bắt đầu xem xét một điều sâu sắc. (Bạn có thể quay lại để lấy chiều rộng sau khi bạn có được một số chiều sâu, sau đó quay lại giữa hai người.)

Tình nguyện cho các nhiệm vụ phức tạp hơn, khó hơn, những nhiệm vụ khiến bạn phải đi sâu để giải quyết các vấn đề. Nếu không có nơi nào bạn làm việc, hãy tìm kiếm các nhiệm vụ nguồn mở để thực hiện hoặc bắt đầu làm việc với một dự án cá nhân sẽ khiến bạn phải đi sâu. Nếu công việc của bạn không có vấn đề thú vị, hãy xem xét tìm kiếm một công việc khó khăn hơn.

Đọc các sách nâng cao trên một ngôn ngữ (ví dụ: đối với Máy chủ SQl, điều này sẽ bao gồm đọc về điều chỉnh hiệu suất và nội bộ cơ sở dữ liệu) thay vì tìm hiểu X trong loại sách 30 ngày.

Đọc các câu hỏi thú vị ở đây và những nơi khác mà họ được hỏi và cố gắng tự giải quyết một số. Nếu bạn muốn tìm hiểu, hãy cố gắng giải quyết một số mà không cần đọc các câu trả lời khác trước. Ngay cả khi câu hỏi đã được trả lời, bạn sẽ tìm hiểu thêm nếu bạn tự tìm câu trả lời. Bạn thậm chí có thể tìm thấy một câu trả lời tốt hơn câu trả lời.

Hỏi một vài câu hỏi khó hơn. Đánh giá các câu trả lời bạn đưa ra, đừng chỉ sử dụng chúng. Hãy chắc chắn để hiểu tại sao câu trả lời sẽ hoặc không hoạt động. Sử dụng những câu trả lời như một nơi bắt đầu để nghiên cứu.

Tìm một số blog kỹ thuật tốt từ các chuyên gia nổi tiếng trong lĩnh vực này và đọc chúng.

Ngừng vứt bỏ kiến ​​thức của bạn sau khi bạn đã hoàn thành với nó. Học cách giữ lại. Hầu hết các chuyên gia không phải tìm kiếm cú pháp phổ biến. Họ không phải phát minh lại bánh xe mỗi khi gặp phải vấn đề vì họ nhớ cách họ tiếp cận vấn đề simliar trước đây. Họ có thể kết nối các dấu chấm và xem vấn đề X mà họ đã làm cách đây hai năm tương tự như vấn đề Y mà họ có ngay bây giờ (điều đó làm tôi ngạc nhiên khi có rất ít người dường như có thể tạo kết nối như vậy). Do đó, họ có nhiều thời gian hơn để dành cho việc nghiên cứu các chủ đề thú vị hơn.


Một câu trả lời tốt đẹp. Nhưng tôi đang tự hỏi, làm thế nào để tôi có thể giữ được kiến ​​thức và kết nối các dấu chấm tốt hơn?

Tôi đề nghị bạn ghi chép lại bất cứ điều gì bạn học. Tôi đã bắt đầu làm điều này trong Evernote của mình, và trong vài năm, tôi thấy rằng tôi có thể sống nhờ các ghi chú của mình. Dần dần, tôi cũng đã đi đến điểm mà các ghi chú của tôi có thể được đưa vào các bài thuyết trình, mà tôi đã sẵn sàng để trình bày tại một thời điểm.
Shivasubramanian

9

Bạn có thể bắt đầu bằng cách nghiên cứu sâu các thông số kỹ thuật ngôn ngữ của những người bạn muốn trở thành một chuyên gia. Ví dụ:


3
Câu trả lời hay - ví dụ, phần 15.8.4 của đặc tả C # được liên kết bao gồm việc thực hiện foreachvà nêu ra hành vi được mô tả trong bài đăng trên blog được trích dẫn từ Eric Lippert. Nếu bất cứ ai từng thấy mình suy nghĩ điều gì đó như "Tôi tự hỏi làm thế nào foreach thực sự hoạt động .." thì đây sẽ là một nơi tốt để bắt đầu tìm kiếm.
Carson63000

6

Nhận Reflector hoặc bất kỳ trình dịch ngược nào khác (vì hiện đang trả tiền) và bắt đầu mở một số thư viện .NET được sử dụng nhiều nhất để tìm hiểu cách thức hoạt động của các bộ phận bên trong. Kết hợp với một cuốn sách như CLR thông qua C #, bạn sẽ nhận được khá sâu (sâu hơn hầu hết chúng ta sẽ làm công việc thường xuyên của họ).


5
Tôi thực sự đã làm điều này với các BitConverterlớp và phát hiện ra IsLittleEndiancờ cụ thể của hệ thống.
Robert Harvey

CƯỜI NGẢ NGHIÊNG. +1 cho isLittleEndian
Rudy

4

Tôi đã phát triển loại kiến ​​thức đó trong C ++ bằng cách đi chơi trong comp.lang.c++.moderatedmột vài năm, mặc dù lúc đó tôi không thực sự làm việc chăm chỉ để viết mã trong đó. Tôi không chắc chắn làm thế nào guru tôi có thể nói tôi là, mặc dù.

Tôi nghĩ có hai loại kiến ​​thức mà người ta có thể tiếp thu về ngôn ngữ lập trình:

  1. Biết những câu đố về ngôn ngữ, và biết cách tránh những cạm bẫy.
  2. Biết cách giải quyết vấn đề hiệu quả.

Số 2 chỉ có thể đạt được bằng cách lập trình bằng ngôn ngữ và xem mã của người khác, nhưng số 1 có thể đạt được bằng cách dành nhiều thời gian để đọc về ngôn ngữ trên các diễn đàn thảo luận của mình, xem mọi người hỏi gì và câu hỏi gì Câu trả lời là. StackOverflow là một nơi tốt cho điều đó quá.


4

Kiến thức sâu và chuyên môn lập trình có nghĩa là thoải mái ở tất cả các cấp độ trừu tượng. I E

  • thư viện và API
  • ngữ nghĩa ngôn ngữ
  • tối ưu hóa trình biên dịch
  • trình biên dịch nội bộ và tạo mã
  • thời gian chạy và hành vi thu gom rác
  • vấn đề kiến ​​trúc và hướng dẫn

Tất cả mọi thứ tôi đã thấy trong 15 năm qua đã chỉ ra rằng chỉ khi bạn thực sự có thể vào trình biên dịch và thời gian chạy, bạn mới có cơ hội trở nên thành thạo sâu sắc. Bạn có thể buộc mình phải thực hiện bước này và bắt đầu lý luận (và xây dựng) phần mềm ở cấp độ trừu tượng tiếp theo thấp hơn trong ngăn xếp , nhưng đó là cách duy nhất để thành thạo.

Tất cả chúng ta có là ngôn ngữ cho sự trừu tượng. Bạn phải hiểu cách ngôn ngữ lập trình được thiết kế và xây dựng để thực sự biết máy đang làm gì.


3

Đọc Hướng dẫn tốt Đây không phải là kiến ​​thức đặc biệt sâu sắc. Nó được xuất bản trong phần đặc tả ngôn ngữ C # 8.6.4. Bạn nên tập thói quen ít nhất là lướt qua các thông số kỹ thuật cho các ngôn ngữ bạn sử dụng, cũng như đọc lướt tài liệu cho tất cả các thư viện dựng sẵn.

Dù sao, đây không phải là ý tưởng của tôi về kiến ​​thức sâu sắc; nó chỉ là một chi tiết thực hiện không thú vị. Sẽ thú vị hơn nếu nhà thiết kế giải thích lý do tại sao nó được thực hiện theo cách năng động hơn này, thay vì chỉ kiểm tra xem đối tượng thực hiện Iterable.


1
Tôi không nghĩ có một thứ như "lướt qua" đặc tả ngôn ngữ C #.
Robert Harvey

@RobertHarvey: bạn có thể đọc lướt qua hầu hết các ngôn ngữ chính thức bao gồm những điều bạn đã biết, như ưu tiên toán tử và cú pháp khai báo và tập trung vào các chi tiết bất ngờ nhưng hữu ích, như hành vi chính xác của C # foreach hoặc Java enum constructor.
kevin cline

Bạn có thể mua một phiên bản chú thích của tiêu chuẩn. Bây giờ là một chút ngày nhưng các ý kiến ​​vẫn rất thú vị cho các phần của ngôn ngữ được bảo hiểm.
Jørgen Fogh
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.