Pada pengembangan pengetahuan pemrograman yang mendalam

136

Kadang-kadang saya melihat pertanyaan tentang kasus tepi dan keanehan lain di Stack Overflow yang mudah dijawab oleh orang-orang seperti Jon Skeet dan Eric Lippert, menunjukkan pengetahuan mendalam tentang bahasa dan banyak seluk beluknya, seperti ini:

Anda mungkin berpikir bahwa untuk menggunakan foreachloop, koleksi yang Anda iterasi harus diimplementasikan IEnumerableatau IEnumerable<T>. Tetapi ternyata, itu sebenarnya bukan keharusan. Yang diperlukan adalah bahwa jenis koleksi harus memiliki metode publik yang disebut GetEnumerator, dan yang harus mengembalikan beberapa jenis yang memiliki pengambil properti publik yang disebut Currentdan metode publik MoveNextyang mengembalikan a bool. Jika kompiler dapat menentukan bahwa semua persyaratan tersebut terpenuhi maka kode dihasilkan untuk menggunakan metode tersebut. Hanya jika persyaratan tersebut tidak terpenuhi kami memeriksa untuk melihat apakah objek mengimplementasikan IEnumerableatau IEnumerable<T>.

Itu hal yang keren untuk diketahui. Saya bisa mengerti mengapa Eric tahu ini; dia ada di tim penyusun, jadi dia harus tahu. Tetapi bagaimana dengan mereka yang menunjukkan pengetahuan yang begitu dalam yang bukan orang dalam?

Bagaimana orang biasa (yang bukan anggota tim C #) mengetahui tentang hal-hal seperti ini?

Secara khusus, adakah metode yang digunakan orang-orang ini untuk secara sistematis membasmi pengetahuan seperti itu, menjelajahinya, dan menginternalisasikannya (menjadikannya milik mereka)?

Robert Harvey
sumber
10
Saya pikir ini terutama di mana perangkat lunak open source bersinar. Sangat menyenangkan untuk dapat masuk ke dalam kerangka / sistem / perpustakaan sepanjang jalan. Saya dulu memiliki cara yang lebih baik dalam memahami kerangka kerja saat saya bekerja dengan Qt daripada ketika saya bekerja dengan WinForms.
Vitor Py
2
Kapan Anda perlu tahu contoh khusus ini, selain tidak terlihat bodoh di depan kerumunan khusus? Mereka membuktikan ini dengan bodoh. Selain itu, seri C #, Java, C ++, dll. Efektif mungkin memiliki beberapa hal keren di dalamnya. Blog Eric Lippert adalah sumber yang baik juga. Secara umum, kita sering tidak tahu apa yang tidak tahu, jadi seperti yang mereka katakan "hidup selama 100 tahun, belajar selama 100 tahun dan mati bodoh".
Pekerjaan
26
Apakah ini sepadan dengan usaha? Saya bilingual dan mencoba mempelajari beberapa bahasa lisan lainnya. Saya telah mengambil beberapa kelas matematika tetapi tidak cukup banyak. Saya ingin belajar cara bermain tenis setengah sopan dan belajar berenang menggunakan stroke kupu-kupu. Saya ingin bepergian lebih banyak. Saya ingin belajar Clojure. Apa yang saya tidak inginkan adalah menjadi ahli dalam satu bahasa, memiliki gelar PhD dalam matematika, menghabiskan 30 jam per minggu di kumpulan seperti Michael Phelps, dll. Pengetahuan Lippert dan Skeet adalah karena fakta bahwa mereka menempatkan banyak upaya dalam satu (atau beberapa) hal sambil melewatkan pengalaman lain. Mungkin berganti pekerjaan?
Pekerjaan
10
"Aku bisa mengerti mengapa Eric tahu ini; dia ada di tim penyusun, jadi dia harus tahu." - kemungkinan dia tahu ini karena dia memikirkannya sejak awal . Saya ragu dia harus 'mencari tahu' bahwa itu bekerja seperti ini :)
Alex ten Brink
10
@Alex: Saya sebenarnya hanya bekerja pada C # karena kami mulai benar-benar membangun implementasi C # 3. Spesifikasi "foreach" ditulis lebih dari enam tahun sebelumnya. Saya masih menemukan hal-hal bersejarah yang gila tentang bahasa setiap hari. Sebagai contoh, saya belajar hari ini bahwa untuk delegasi, ((A + B) + C) - (A + C) = A + B + C, tetapi ((A + B) + C) - (B + C) = A Aneh!
Eric Lippert

Jawaban:

167

Pertama, terima kasih atas kata-kata baiknya.

Jika Anda ingin mendapatkan pengetahuan mendalam tentang C # itu tidak diragukan lagi merupakan keuntungan memiliki spesifikasi bahasa, sepuluh tahun catatan desain, kode sumber, basis data bug, dan Anders, Mads, Scott dan Peter di ujung lorong. Saya tentu beruntung, tidak ada pertanyaan tentang itu.

Namun, bahkan tanpa kelebihan itu masih mungkin untuk mendapatkan pengetahuan yang mendalam tentang subjek.

Kembali ketika saya mulai di Microsoft saya bekerja pada juru bahasa JScript yang dikirimkan dengan Internet Explorer 3. Manajer saya saat itu mengatakan kepada saya sesuatu yang merupakan beberapa saran terbaik yang pernah saya dapatkan. Dia mengatakan bahwa dia ingin saya menjadi ahli yang dikenal di Microsoft pada sintaks dan semantik bahasa JScript, dan saya harus membahas ini dengan mencari pertanyaan tentang aspek-aspek JScript dan menjawabnya. Terutama menjawab pertanyaan yang saya tidak tahu jawabannya, karena mereka adalah orang-orang yang akan saya pelajari.

Jelas StackOverflow dan forum Q&A publik lainnya seperti minum dari firehose untuk hal semacam itu. Saat itu, saya membaca comp.lang.javascript dan forum internal Microsoft "Pengguna JS" kami dengan religius dan mengikuti saran manajer saya: ketika saya melihat pertanyaan tentang semantik bahasa yang saya tidak tahu jawabannya, saya membuatnya bisnis saya untuk mencari tahu.

Jika Anda ingin melakukan "menyelam dalam" seperti itu, Anda harus memilih dengan hati-hati. Saya sampai hari ini sangat tidak tahu bagaimana model objek browser bekerja. Karena saya telah berkonsentrasi menjadi ahli bahasa C # beberapa tahun terakhir ini, saya sangat tidak tahu bagaimana berbagai kelas di perpustakaan kelas dasar bekerja. Saya beruntung karena saya memiliki pekerjaan yang menghargai pengetahuan mendalam yang spesifik; jika pekerjaan Anda atau bakat Anda lebih sejalan dengan menjadi seorang generalis, pergi jauh mungkin tidak bekerja untuk Anda.

Menulis blog juga sangat membantu; dengan meminta saya untuk menjelaskan topik yang kompleks kepada orang lain, saya dipaksa untuk menghadapi pemahaman saya sendiri yang tidak memadai tentang berbagai topik sepanjang waktu.

Eric Lippert
sumber
14
Bukan untuk menyeret ke luar topik ini, tetapi setelah membaca jawaban ini saya ingin tahu mengapa Anda belum mengajukan pertanyaan di sini atau di Stack Overflow. Apakah kolega, blog, dll. Anda cukup untuk saat ini? Apakah ada sumber daya yang lebih baik daripada SO yang harus kita ketahui?
Matius Baca
6
Mungkin Anda salah mengerti apa yang dia katakan. Sebaliknya, secara intuitif, ia tidak mengajukan pertanyaan untuk mempelajari banyak hal, ia menjawab pertanyaan.
jhocking
65

Setelah berada di sisi "guru" dari percakapan sekali atau dua kali, saya dapat memberi tahu Anda bahwa sering kali apa yang Anda anggap sebagai "pengetahuan yang mendalam" dari bahasa atau sistem pemrograman sering kali merupakan hasil dari "guru" yang baru-baru ini berjuang untuk sebulan untuk memecahkan masalah yang sama persis. Itu terutama berlaku di forum di mana orang dapat memilih pertanyaan mana yang akan mereka jawab. Bahkan orang-orang seperti Jon Skeet dan Eric Lippert harus belajar halo dunia pada satu titik. Mereka mengambil pengetahuan mereka satu konsep pada satu waktu, sama seperti orang lain.

Karl Bielefeldt
sumber
1
Poin yang sangat bagus. Saya sering menemukan ketika memulai penelitian yang lama yang saya temukan pertanyaan sekarang saya bisa menjawab karena hal-hal yang saya pelajari sebelumnya pada hari itu.
Matius Baca
47

Mengutip Yogi Bhajan:

"Jika Anda ingin mempelajari sesuatu, bacalah tentang hal itu; jika Anda ingin memahami sesuatu, tulislah tentang hal itu; jika Anda ingin menguasai sesuatu, programkanlah ."

Pemrograman seperti tantangan pengajaran utama. Mengajar komputer membutuhkan sesuatu, agar Anda tahu barang-barang Anda dengan sangat baik - atau Anda akan belajar menguasainya.

Misalnya, jika Anda ingin belajar fisika, tulis mesin fisika. Jika Anda ingin belajar catur, program permainan catur. Jika Anda ingin mempelajari pengetahuan C # dalam, tulislah kompiler C # (atau alat lain).

Maglob
sumber
2
Pemrograman juga merupakan upaya sederhana untuk menulis (untuk dibaca oleh orang, tentu saja) dengan cara yang paling jelas.
vpit3833
4
Kutipan itu terdengar sangat dalam sampai saya membaca contoh catur. Sayangnya pemrograman catur AI tidak akan membuat Anda menjadi pemain catur yang lebih baik (ini pada dasarnya adalah pencarian di pohon Min-Max). Masih memberi +1
bughi
1
@bughi Mungkin Anda bisa menguasai peraturan: D
Julio Rodrigues
@bughi, 'program it' adalah istilah yang sangat luas tidak selalu terkait dengan penulisan kode !! Pikirkan sedikit di luar kotak.
Nitesh Verma
25

Sejauh yang saya tahu, cara untuk mempelajari ini adalah:

  • Baca tentang itu dari seseorang seperti Eric Lippert
  • Mengalami dan kemudian memecahkan masalah secara langsung.

Cara kedua mungkin memakan waktu lebih lama tetapi mungkin akan menghasilkan pemahaman yang lebih dalam (tetapi tidak selalu).

FrustratedWithFormsDesigner
sumber
17
Atau keduanya. [15 karakter]
Michael K
23

Saya akan mengatakan melakukan hal berikut:

Setelah mempelajari setumpuk bahasa yang relatif berguna (yang Anda butuhkan untuk pekerjaan nyata) di tingkat di mana Anda dapat melakukan tugas-tugas yang paling umum, berhentilah belajar lebih banyak bahasa sampai Anda telah mempelajari setidaknya satu bahasa secara mendalam. Bagian dari masalah di industri kami saat ini, menurut pendapat saya, adalah bahwa orang hanya mempelajari 5-10% pertama dari bahasa sebelum pindah ke bahasa lain. Setelah Anda memiliki kemampuan untuk melakukan tugas-tugas paling umum dalam suatu pekerjaan, maka mulailah melihat satu hal secara mendalam. (Anda dapat kembali untuk mendapatkan luas setelah Anda mendapatkan kedalaman, lalu bolak-balik di antara keduanya.)

Sukarelawan untuk tugas-tugas yang lebih kompleks, lebih sulit, tugas-tugas yang membuat Anda harus mendalam untuk menyelesaikan masalah. Jika tidak ada tempat Anda bekerja, cari tugas sumber terbuka untuk dilakukan atau mulai mengerjakan proyek pribadi yang akan membuat Anda harus lebih mendalam. Jika pekerjaan Anda tidak memiliki masalah yang menarik, pertimbangkan untuk mencari pekerjaan yang lebih menantang.

Baca buku-buku lanjutan dalam satu bahasa (untuk SQl Server misalnya ini termasuk membaca tentang penyempurnaan kinerja dan internal basis data) alih-alih buku X belajar dalam 30 hari jenis buku.

Baca pertanyaan-pertanyaan menarik di sini dan tempat-tempat lain di mana mereka ditanya dan cobalah untuk menyelesaikannya sendiri. Jika Anda ingin belajar, cobalah untuk menyelesaikannya tanpa membaca jawaban yang lain terlebih dahulu. Bahkan jika pertanyaan sudah dijawab, Anda akan belajar lebih banyak jika Anda menemukan jawabannya sendiri. Anda bahkan mungkin menemukan jawaban yang lebih baik daripada jawaban pertanyaan itu.

Ajukan beberapa pertanyaan sulit. Evaluasilah jawaban yang Anda berikan, jangan hanya menggunakannya. Pastikan Anda memahami mengapa jawabannya akan atau tidak berhasil. Gunakan jawaban-jawaban itu sebagai tempat awal untuk meneliti.

Temukan beberapa blog teknis yang bagus dari para ahli yang dikenal di bidang ini dan baca mereka.

Berhentilah membuang pengetahuan Anda setelah Anda selesai dengan itu. Belajarlah untuk mempertahankan. Kebanyakan ahli tidak perlu mencari sintaksis yang umum. Mereka tidak harus menemukan kembali roda setiap kali mereka menghadapi masalah karena mereka ingat bagaimana mereka mendekati masalah serupa sebelumnya. Mereka dapat menghubungkan titik-titik dan melihat bagaimana masalah X yang mereka lakukan dua tahun lalu mirip dengan masalah Y yang mereka miliki saat ini (itu mengherankan saya betapa sedikit orang yang dapat membuat koneksi seperti itu). Akibatnya, mereka memiliki lebih banyak waktu yang tersedia untuk menghabiskan meneliti mata pelajaran yang lebih menarik.

HLGEM
sumber
Jawaban yang bagus. Tapi saya bertanya-tanya, bagaimana saya bisa lebih baik dalam mempertahankan pengetahuan dan menghubungkan titik-titik?
Saya sarankan Anda mencatat apa pun yang Anda pelajari. Saya mulai melakukan ini di Evernote saya, dan lebih dari beberapa tahun, saya menemukan bahwa saya dapat hidup dari catatan saya. Perlahan-lahan, saya juga sampai pada titik di mana catatan saya dapat dijadikan presentasi, yang siap saya presentasikan pada saat itu juga.
Shivasubramanian A
9

Anda dapat memulainya dengan mempelajari secara mendalam spesifikasi bahasa yang Anda cari sebagai ahli. Sebagai contoh:

Marcelo
sumber
3
Jawaban yang bagus - misalnya, bagian 15.8.4 dari spesifikasi C # tertaut mencakup implementasi foreach, dan menjabarkan perilaku yang dijelaskan dalam posting blog yang dikutip dari Eric Lippert. Jika ada yang mendapati diri mereka berpikir sesuatu seperti "Aku ingin tahu bagaimana cara kerjanya benar-benar .." ini akan menjadi tempat yang baik untuk mulai mencari.
Carson63000
6

Dapatkan Reflector atau decompiler lainnya (karena membayar sekarang), dan mulailah membuka beberapa perpustakaan .NET yang paling banyak digunakan untuk mempelajari cara kerja internal. Dikombinasikan dengan buku seperti CLR via C # Anda akan mendapatkan cukup dalam (lebih dalam dari kebanyakan dari kita akan pergi pada pekerjaan reguler mereka).

Bart
sumber
5
Saya benar-benar melakukan ini dengan BitConverterkelas - kelas, dan menemukan IsLittleEndianflag khusus sistem.
Robert Harvey
LOL. +1 untuk isLittleEndian
Rudy
4

Saya mengembangkan pengetahuan semacam itu di C ++ dengan nongkrong comp.lang.c++.moderatedselama beberapa tahun, meskipun saya tidak benar-benar bekerja keras untuk kode di dalamnya pada saat itu. Saya tidak yakin bagaimana guru saya bisa mengatakan saya.

Saya pikir ada dua jenis pengetahuan yang bisa diambil tentang bahasa pemrograman:

  1. Mengetahui hal-hal sepele tentang bahasa, dan mengetahui cara menghindari jebakan.
  2. Mengetahui cara memecahkan masalah secara efektif.

Nomor 2 hanya dapat dicapai dengan pemrograman dalam bahasa dan melihat kode orang lain, tetapi nomor 1 dapat dicapai dengan mengambil banyak waktu untuk membaca tentang bahasa di forum diskusi, melihat jenis pertanyaan yang diajukan orang, dan apa jawabannya adalah. StackOverflow juga merupakan tempat yang bagus untuk itu.

Ken Bloom
sumber
4

Pengetahuan yang mendalam dan keahlian pemrograman berarti merasa nyaman di semua level abstraksi. Yaitu

  • perpustakaan dan API
  • semantik bahasa
  • optimisasi kompiler
  • internal penyusun dan pembuatan kode
  • perilaku runtime dan pengumpul sampah
  • arsitektur dan set instruksi masalah

Semua yang saya lihat dalam 15 tahun terakhir menunjukkan bahwa hanya jika Anda benar-benar dapat masuk ke kompiler dan runtime, Anda memiliki peluang untuk menjadi sangat mahir. Anda mungkin harus memaksakan diri untuk mengambil langkah dan mulai menalar (dan membangun) perangkat lunak pada tingkat abstraksi berikutnya yang lebih rendah di tumpukan , tetapi itu satu-satunya cara untuk keahlian.

Yang kami miliki hanyalah bahasa untuk abstraksi. Anda harus memahami bagaimana bahasa pemrograman dirancang dan dibangun untuk benar-benar tahu apa yang dilakukan mesin.

Don Stewart
sumber
3

Baca Manual Baik Ini bukan pengetahuan yang mendalam. Ini diterbitkan di bagian spesifikasi bahasa C # 8.6.4. Anda harus membiasakan setidaknya membaca spesifikasi untuk bahasa yang Anda gunakan, serta membaca sekilas dokumentasi untuk semua perpustakaan bawaan.

Bagaimanapun, ini bukan ide saya tentang pengetahuan yang mendalam; itu hanya detail implementasi yang tidak menarik. Ini bisa lebih menarik jika desainer menjelaskan mengapa itu dilakukan dengan cara yang lebih dinamis ini, daripada hanya memeriksa bahwa objek mengimplementasikan Iterable.

kevin cline
sumber
1
Saya tidak berpikir ada yang namanya "membaca sekilas" spesifikasi bahasa C #.
Robert Harvey
@RobertHarvey: Anda dapat membaca sebagian besar bahasa formal yang mencakup hal-hal yang sudah Anda ketahui, seperti sintaksis presedensi dan deklarasi operator, dan fokus pada detail yang tak terduga tetapi bermanfaat, seperti perilaku tepat dari C # foreach atau konstruktor Java enum.
kevin cline
Anda dapat membeli versi standar yang beranotasi. Agak ketinggalan zaman sekarang tetapi komentarnya masih sangat menarik untuk bagian-bagian dari bahasa yang dibahas.
Jørgen Fogh