Gesaan dan konteks
Soalan pengekodan ini menguji penjadualan konkurensi dan bukannya sekadar meletakkan setiap janji ke dalam Promise.all. Calon mesti menentukan kontrak untuk daya pemprosesan, susunan, penyebaran ralat, pembatalan, dan input kosong, kemudian menunjukkan bahawa had tersebut tidak pernah dilangkaui dan tiada item yang digunakan dua kali.
Perkara yang dinilai oleh penemu duga
- Sama ada worker tetap atau penjadual yang setara mengekalkan paling banyak N tugas aktif.
- Sama ada hasil ditulis mengikut indeks input supaya susunan penyiapan tidak menyusun semula output.
- Sama ada semantik fail-fast dan pengumpulan ralat dinyatakan secara jelas, termasuk tugas yang sudah berjalan.
- Sama ada N tidak sah, input kosong, lemparan segerak, pembatalan, dan nilai mapper bukan Promise berfungsi dengan betul.
Soalan penjelasan untuk ditanya
Sahkan sama ada tugas boleh diteruskan selepas pembatalan, sama ada fail-fast menunggu pembersihan, sama ada hasil separa dikembalikan, dan sama ada mapper menerima AbortSignal. Tanya tentang percubaan semula, konkurensi dinamik, dan mengekalkan identiti objek ralat asal.
Rangka kerja jawapan 30 saat
Saya akan mencipta tidak lebih daripada N worker yang berkongsi pembilang indeks seterusnya. Setiap worker mengambil indeks, membungkus pulangan dan lemparan segerak dengan Promise.resolve, dan menulis mengikut indeks. Fail-fast menyebarkan ralat pertama yang diperhatikan dan menghentikan penghantaran baharu; mod kumpul merekodkan setiap status. Pembatalan menghentikan tuntutan indeks baharu dan menghantar isyarat kepada mapper. Kerja adalah O(items), ruang hasil dan status adalah O(items), dan kerja aktif dihadkan oleh O(N).
Perbincangan mendalam langkah demi langkah
1. Tentukan kontrak hasil dan ralat
Hasil mengekalkan susunan input. Mod kumpul mengembalikan status fulfilled atau rejected dengan nilai atau sebab asal; undefined tidak boleh menjadi penanda kejayaan. Fail-fast mengembalikan ralat pertama yang diperhatikan, sambil mengambil perhatian bahawa JavaScript tidak boleh menamatkan janji yang telah dimulakan secara paksa. Mapper yang menerima isyarat boleh bekerjasama dengan pembatalan.
2. Gunakan worker tetap dan peruntukan indeks
Kekalkan indeks seterusnya dalam keadaan kongsi. Setiap worker berulang sehingga indeks berada di luar julat, pembatalan ditetapkan, atau fail-fast menghentikan penghantaran. Tambahkan indeks sebelum memulakan tugas supaya satu item hanya boleh dituntut sekali sahaja. Gunakan min(N, items.length) worker untuk mengelakkan janji terbiar.
3. Kendalikan lemparan segerak dan susunan penyiapan
Tangkap lemparan mapper segerak dan normalkan kedua-dua nilai dan janji dengan Promise.resolve. Tulis kejayaan atau kegagalan pada indeks asal; jangan sekali-kali menolak (push) dari panggilan balik penyiapan. Sebaik sahaja satu worker selesai, ia menuntut indeks seterusnya, mengekalkan daya pemprosesan tanpa meningkatkan kerja aktif.
4. Sebarkan pembatalan dan hentikan penghantaran
Jika isyarat telah dibatalkan terlebih dahulu, tolak atau kembalikan ralat pembatalan yang didokumentasikan sebelum memulakan kerja. Tugas yang sedang berjalan menerima isyarat yang sama. Penjadual menunggu worker keluar sebelum menyelesaikan janji utamanya, supaya pemanggil tidak melihat penyiapan semasa gelung latar belakang masih terus menghantar tugas. Pembatalan dan ralat perniagaan memerlukan punca yang boleh dibezakan.
5. Sahkan kes pinggir dan kerumitan
Uji tatasusunan kosong, N bersamaan sifar, N lebih besar daripada input, nilai dan lemparan segerak, kelewatan yang berbeza-beza, kegagalan pertama, pelbagai kegagalan, dan pembatalan semasa berjalan. Gunakan pembilang aktif untuk menegaskan ia tidak pernah melebihi N dan cangkuk untuk mengesahkan setiap indeks berjalan sekali. Panggilan mapper adalah O(items), ruang hasil adalah O(items), dan konkurensi penjadual adalah O(N).
Contoh jawapan yang kukuh
Saya mengesahkan bahawa N ialah integer positif, mencipta min(N, items.length) worker, dan berkongsi pembilang indeks seterusnya. Worker menuntut indeks, memanggil mapper melalui Promise.resolve supaya nilai dan lemparan segerak mengikut laluan yang sama, dan menulis hasil mengikut indeks. Fail-fast menetapkan bendera henti-penghantaran dan menyebarkan ralat pertama; mod kumpul mengekalkan setiap status. Pembatalan menghalang tuntutan baharu dan menghantar isyarat kepada mapper yang aktif, kemudian menunggu worker keluar. Ujian merangkumi kelewatan yang tidak teratur, ralat segerak, input kosong, sempadan N, dan pembatalan, dengan penegasan bahawa kerja aktif tidak pernah melebihi N.
Kesilapan lazim
- Memanggil
Promise.all(items.map(mapper))dan memulakan setiap tugas sekali gus. - Menolak (push) hasil supaya output mengikut susunan penyiapan dan bukannya susunan input.
- Hanya menangkap penolakan janji dan terlepas lemparan mapper segerak.
- Meneruskan penghantaran selepas fail-fast, atau menganggap penolakan membatalkan kerja yang sedang berjalan secara automatik.
- Menganggap pembatalan sebagai ralat perniagaan biasa sehingga pemanggil tidak boleh memilih tingkah laku percubaan semula.
- Melangkau pengesahan untuk N, input kosong, dan nilai mapper bukan Promise biasa.
Soalan susulan dan jawapan
Mengapakah tidak memulakan item seterusnya secara rekursif?
Rekursi boleh menyatakan rantai bersiri, tetapi ia juga mesti mengekalkan konkurensi, ralat, dan pembatalan. Worker tetap menjadikan bukti tugas aktif lebih jelas dan mengelakkan rekursi mendalam atau penghantaran pendua.
Apakah yang berlaku kepada tugas yang sedang berjalan semasa fail-fast?
Janji JavaScript tidak mempunyai primitif penamatan paksa secara umum. Hentikan penghantaran baharu dan panggil abort apabila mapper bekerjasama dengan AbortSignal; jika tidak, biarkan tugas selesai tanpa menulis pada hasil yang diselesaikan secara luaran.
Bagaimanakah mod kumpul harus mewakili ralat?
Kembalikan objek status bagi setiap item yang membezakan fulfilled dan rejected sambil mengekalkan nilai atau sebab asal. Nilai sentinel tidak selamat kerana nilai yang berjaya itu sendiri mungkin undefined atau null.
Bagaimanakah anda melaraskan konkurensi secara dinamik?
Jejaki had maksimum yang dikonfigurasikan secara berasingan daripada kerja aktif dan tambah atau hentikan tuntutan pada sempadan yang selamat. Pelarasan dinamik menambah kos bukti dan ujian, jadi gunakan had tetap melainkan keperluan secara eksplisit memerlukan penyesuaian.