Rumah >hujung hadapan web >tutorial js >Jurang Yang Sebenarnya Diisi JavaScript Hari-hari LeetCode
Kebanyakan cabaran pengekodan mengajar anda untuk menyelesaikan teka-teki. Pelan kajian JavaScript 30 Hari LeetCode melakukan sesuatu yang berbeza: ia menunjukkan kepada anda cara kepingan teka-teki boleh berubah menjadi batu bata, bersedia untuk membina projek dunia sebenar.
Perbezaan ini penting. Apabila anda menyelesaikan masalah algoritma biasa, anda sedang melatih minda anda untuk berfikir secara abstrak. Tetapi apabila anda melaksanakan fungsi1 nyahlantun atau membina pemancar peristiwa2, anda sedang mempelajari cara perisian sebenar berfungsi.
Saya menemui perkara ini semasa menangani cabaran itu sendiri. Pengalaman itu kurang seperti menyelesaikan pengusik otak dan lebih seperti arkeologi - mendedahkan konsep JavaScript moden yang khusus. Setiap bahagian memfokuskan pada satu lagi ciri moden JS.
Perkara yang unik tentang rancangan kajian ini ialah ia tidak akan mengajar anda JavaScript. Malah, saya percaya anda perlu sudah mengetahui JavaScript dengan munasabah untuk mendapat manfaat daripadanya. Apa yang diajarnya ialah cara JavaScript sebenarnya digunakan untuk menyelesaikan masalah kejuruteraan sebenar.
Pertimbangkan cabaran Memoize3. Di permukaan, ini mengenai hasil fungsi caching. Tetapi perkara yang anda benar-benar pelajari ialah mengapa perpustakaan seperti React memerlukan penghafalan untuk mengendalikan pemaparan komponen dengan cekap. Atau ambil masalah Debounce1 - ia bukan hanya tentang melaksanakan kelewatan; ia membantu anda memahami, secara langsung, mengapa setiap rangka kerja bahagian hadapan moden, lif, dan pada asasnya mana-mana sistem dengan UI interaktif, memerlukan corak ini.
Tumpuan pada corak praktikal dan bukannya asas bahasa ini mewujudkan kekangan yang menarik; anda perlu berada dalam satu daripada dua kedudukan untuk mendapat manfaat:
Sesuatu yang ganjil berlaku antara mempelajari sains komputer dan mempraktikkan kejuruteraan perisian. Peralihan itu terasa seperti mempelajari teori catur selama bertahun-tahun, hanya untuk mendapati diri anda bermain permainan yang berbeza sepenuhnya - yang peraturannya terus berubah dan kebanyakan pergerakan tiada dalam mana-mana buku.
Dalam CS, anda mempelajari cara pokok binari berfungsi. Dalam kejuruteraan perisian, anda menghabiskan berjam-jam menyahpepijat API anda, cuba memahami sebab caching respons tidak berfungsi. Dari jauh, pertindihan antara dunia ini mungkin kelihatan jauh lebih besar daripada yang sebenarnya. Terdapat jurang di sana, dan ia sering boleh mengejutkan graduan CS apabila mereka memulakan kerjaya mereka. Malangnya, kebanyakan sumber pendidikan gagal untuk merapatkannya. Ia sama ada kekal secara teori semata-mata ("begini cara quicksort berfungsi") atau praktikal semata-mata ("begini cara untuk menggunakan apl React").
Apa yang menjadikan rancangan kajian JavaScript ini menarik bukan kerana ia direka dengan baik - tetapi ia mewujudkan hubungan antara dunia ini. Ambil masalah hafalan: 2623. Memoize3. Dalam istilah CS, ini mengenai caching nilai yang dikira. Tetapi melaksanakannya memaksa anda untuk bergelut dengan keanehan JavaScript di sekitar rujukan objek, konteks fungsi dan pengurusan memori. Tiba-tiba,
anda bukan sahaja mempelajari algoritma - anda mula memahami mengapa sesuatu seperti Redis wujud.
Gaya ini berulang sepanjang cabaran. Pelaksanaan Pemancar Acara2 bukan hanya mengenai corak pemerhati buku teks - anda boleh melihatnya sebagai sebab mengapa mengeluarkan enjin V8 daripada penyemak imbas dan membina Node.js di sekelilingnya, sebenarnya masuk akal . The Promise Pool4 menangani pelaksanaan selari, a.k.a., sebab pangkalan data anda memerlukan pengehadan sambungan.
Jujukan masalah dalam rancangan kajian ini bukan secara rawak. Ia membina model mental JavaScript moden, lapisan demi lapisan.
Ia bermula dengan penutupan. Bukan kerana penutupan ialah konsep yang paling mudah - ia sangat mengelirukan - tetapi kerana ia adalah asas kepada cara JavaScript mengurus keadaan.
function createCounter(init) { let count = init; return function() { return count++; } } const counter1 = createCounter(10); console.log(counter1()); // 10 console.log(counter1()); // 11 console.log(counter1()); // 12 // const counter1 = createCounter(10); // when this^ line executes: // - createCounter(10) creates a new execution context // - local variable count is initialized to 10 // - a new function is created and returned // - this returned function maintains access // to the count variable in its outer scope // - this entire bundle // (function (the inner one) + its access to count) // is what we call a closure
Corak ini ialah benih semua pengurusan negeri dalam JavaScript. Sebaik sahaja anda memahami cara kaunter ini berfungsi, anda memahami cara useState React berfungsi di bawah hud. Anda faham sebab corak modul muncul dalam JavaScript pra-ES6.
Kemudian rancangan bergerak ke transformasi berfungsi. Ini mengajar anda hiasan fungsi - di mana fungsi membalut fungsi lain untuk mengubah suai tingkah laku mereka. Ini bukan sekadar helah teknikal; begitulah cara perisian tengah Express berfungsi, cara komponen tertib tinggi React beroperasi,
dan juga cara penghias TypeScript berfungsi.
Apabila anda mencapai cabaran tak segerak, anda bukan sahaja belajar tentang Janji - anda akan menemui sebab JavaScript memerlukannya sejak awal. Masalah The Promise Pool4 tidak mengajar anda konsep JS yang inovatif dan unik; ia menunjukkan kepada anda sebab pengumpulan sambungan wujud dalam setiap enjin pangkalan data.
Berikut ialah pemetaan kasar bahagian rancangan kajian kepada konsep kejuruteraan perisian dunia sebenar:
Mari kita rungkai beberapa masalah yang mempamerkan nilai sebenar rancangan kajian ini.
Pertimbangkan cabaran Memoize. Apa yang saya suka tentangnya, ialah hakikat bahawa penyelesaian terbaik (yang saya dapat buat)
sangat mudah, seolah-olah kod itu sendiri memberitahu anda dengan lembut apa yang dilakukannya (masih, saya sertakan beberapa ulasan).
Ini tidak menjadikan #2623 masalah mudah, dengan apa cara sekalipun. Saya memerlukan 2 lelaran sebelumnya untuk menjadikannya sebersih ini:
function createCounter(init) { let count = init; return function() { return count++; } } const counter1 = createCounter(10); console.log(counter1()); // 10 console.log(counter1()); // 11 console.log(counter1()); // 12 // const counter1 = createCounter(10); // when this^ line executes: // - createCounter(10) creates a new execution context // - local variable count is initialized to 10 // - a new function is created and returned // - this returned function maintains access // to the count variable in its outer scope // - this entire bundle // (function (the inner one) + its access to count) // is what we call a closure
Bayangkan anda berada di dalam lif, dan ada seseorang yang terkial-kial menekan butang "tutup pintu" berulang kali.
tekan tekan tekan tekan tekan
Tanpa melenting: Lif akan cuba menutup pintu pada setiap kali ditekan, menjadikan mekanisme pintu berfungsi dengan tidak cekap dan mungkin pecah.
Dengan nyahlantun: Lif menunggu sehingga orang itu berhenti menekan untuk masa tertentu (katakan 0.5 saat) sebelum benar-benar cuba menutup pintu. Ini adalah lebih cekap.
Ini satu lagi senario:
Bayangkan anda sedang melaksanakan ciri carian yang mengambil hasil sebagai jenis pengguna:
Tanpa melenting:
/** * @param {Function} fn * @return {Function} */ function memoize(fn) { // Create a Map to store our results const cache = new Map(); return function(...args) { // Create a key from the arguments const key = JSON.stringify(args); // If we've seen these arguments before, return cached result if (cache.has(key)) { return cache.get(key); } // Otherwise, calculate result and store it const result = fn.apply(this, args); cache.set(key, result); return result; } } const memoizedFn = memoize((a, b) => { console.log("computing..."); return a + b; }); console.log(memoizedFn(2, 3)); // logs "computing..." and returns 5 console.log(memoizedFn(2, 3)); // just returns 5, no calculation console.log(memoizedFn(3, 4)); // logs "computing..." and returns 7 // Explanantion: // It's as if our code had access to an external database // Cache creation // const cache = new Map(); // - this^ uses a closure to maintain the cache between function calls // - Map is perfect for key-value storage // Key creation // const key = JSON.stringify(args); // - this^ converts arguments array into a string // - [1,2] becomes "[1,2]" // - we are now able to use the arguments as a Map key // Cache check // if (cache.has(key)) { // return cache.get(key); // } // - if we've seen these arguments before, return cached result; // no need to recalculate
Ini akan membuat 10 panggilan API. Kebanyakannya tidak berguna kerana pengguna masih menaip.
Dengan nyahlantun (kelewatan 300ms):
// typing "javascript" 'j' -> API call 'ja' -> API call 'jav' -> API call 'java' -> API call 'javas' -> API call 'javasc' -> API call 'javascr' -> API call 'javascri' -> API call 'javascrip' -> API call 'javascript' -> API call
Menyahlantun adalah seperti memberitahu kod anda: "Tunggu sehingga pengguna berhenti melakukan sesuatu selama X milisaat sebelum benar-benar menjalankan fungsi ini."
Inilah penyelesaian untuk LeetCode #2627:
// typing "javascript" 'j' 'ja' 'jav' 'java' 'javas' 'javasc' 'javascr' 'javascri' 'javascrip' 'javascript' -> API call (only one call, 300ms after user stops typing)
Kes penggunaan dunia nyata biasa lain untuk nyahlantun (selain daripada bar carian):
Saya berharap, daripada nada positif keseluruhan artikel ini, pendapat saya tentang 30 Hari JS telah menjadi jelas sekarang.
Tetapi tiada sumber pendidikan yang sempurna, dan, apabila melibatkan batasan, kejujuran adalah berharga. Pelan kajian ini mempunyai beberapa titik buta yang patut diteliti.
Pertama, rancangan pengajian mengambil tahap pengetahuan sedia ada.
Jika anda belum selesa dengan JavaScript, beberapa cabaran boleh menjadi berat. Ini boleh mengecewakan bagi pemula yang mungkin mempunyai jangkaan lain daripada rancangan pengajian.
Kedua, cabaran dibentangkan secara terpencil.
Ini masuk akal pada mulanya, tetapi boleh menjadi perkara yang mengecewakan untuk disedari semasa anda meneruskan rancangan. Masalah dunia sebenar selalunya memerlukan gabungan pelbagai corak dan teknik. Pelan kajian boleh mendapat manfaat daripada cabaran yang lebih bersepadu yang memerlukan penggunaan beberapa konsep bersama-sama (pengecualian: kami menggunakan penutupan sepanjang rancangan). Ini boleh dimuatkan dengan baik dalam bahagian Bonus (yang telah dikhaskan kepada pengguna premium).
Akhirnya, kelemahan utama set cabaran ini terletak pada penjelasan konsepnya. Datang daripada pengaturcaraan kompetitif,
Saya sudah biasa mengosongkan takrif istilah dan konsep baharu dalam penyataan masalah. Walau bagaimanapun, penerangan LeetCode selalunya tidak perlu rumit - memahami penjelasan mereka tentang fungsi nyahlantun adalah lebih sukar daripada melaksanakan penyelesaian sebenar.
Walaupun kekurangannya, rancangan kajian adalah sumber yang berharga untuk memahami JavaScript moden.
Memahami corak ini hanyalah permulaan.
Cabaran sebenar ialah mengenali masa dan cara menggunakannya dalam kod pengeluaran. Inilah yang saya temui selepas menemui corak ini di alam liar.
Pertama, corak ini jarang muncul secara berasingan. Pangkalan kod sebenar menggabungkannya dengan cara yang tidak dapat diterokai oleh cabaran. Pertimbangkan ciri carian, dilaksanakan dari awal. Anda mungkin mendapati diri anda menggunakan:
Semua corak ini berinteraksi, mewujudkan kerumitan yang tiada satu cabaran pun menyediakan anda. Tetapi, setelah melaksanakan setiap bahagian sendiri, anda mendapat gambaran umum tentang bagaimana keseluruhan pelaksanaan sepatutnya berfungsi.
Sebaliknya, kemahiran paling berharga yang akan anda perolehi bukanlah melaksanakan corak ini - ia mengiktirafnya dalam kod orang lain.
Selepas melengkapkan rancangan kajian ini, temu bual pengekodan bukan satu-satunya tempat anda akan mengenali corak ini.
Anda akan melihatnya dalam kod sumber terbuka, dalam permintaan tarik rakan sekerja anda dan mungkin mula menyedarinya dalam projek anda yang lalu. Anda mungkin telah melaksanakannya sebelum ini, tanpa menyedarinya. Paling penting, anda akan faham sebab mereka ada.
Apa yang bermula sebagai penyelesaian teka-teki berubah menjadi pemahaman yang lebih mendalam tentang ekosistem JavaScript moden.
Itulah jurang yang diisi oleh rancangan pengajian ini: merapatkan pengetahuan teori dengan kebijaksanaan kejuruteraan praktikal.
2627. Debounce (Janji dan Masa) ↩
2694. Pemancar Acara (Kelas) ↩
2623. Memoize (Transformasi Fungsi) ↩
2636. Kolam Janji (Bonus) ↩
Atas ialah kandungan terperinci Jurang Yang Sebenarnya Diisi JavaScript Hari-hari LeetCode. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!