Topik wawancara representatif

Wawancara coding: Bagaimana Anda membangun lazy pipeline dengan JavaScript Iterator Helpers?

CodingSedang
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Implementasikan lazy pipeline yang memfilter, mentransformasi, dan mengambil N hasil pertama dari sumber berhalaman (paged source). Jelaskan Iterator Helpers versus array, konsumsi tunggal (single consumption), dan penghentian dini (early termination).

1. Pertanyaan dan konteks

Anda harus memproses iterator sinkron yang mungkin berisi jutaan data: memfilter baris yang tidak valid, memetakannya ke view model, mengambil 100 data pertama, dan menghitung jumlah totalnya. Kode asli menyebarkan (spread) sumber ke dalam array sebelum memanggil map, filter, dan reduce, yang menyebabkan lonjakan memori tinggi. Tulis ulang dengan JavaScript Iterator Helpers dan jelaskan sifat lazy (kemalasan), protokol iterator, penghentian dini, pembersihan, dan fallback untuk runtime versi lama.

2. Apa yang dievaluasi oleh pewawancara

  • Apakah Anda memahami perbedaan antara Iterator dan Iterable, dan bahwa Iterator Helpers mengembalikan iterator yang dapat terus dikonsumsi.
  • Apakah Anda dapat menyusun map, filter, take, find, reduce, dan toArray ke dalam sebuah lazy pipeline.
  • Apakah Anda mengetahui bahwa sebuah iterator bersifat stateful dan biasanya hanya bergerak maju sekali, serta bahwa penghentian dini memberi kesempatan bagi metode return yang mendasarinya untuk melakukan pembersihan.
  • Apakah Anda menangani sumber tak terbatas atau mahal, pengecualian (exceptions), kompatibilitas, dan batas di mana materialisasi array tepat dilakukan.

3. Klarifikasi yang perlu ditanyakan sebelum menjawab

  1. Apakah sumbernya berupa Iterator sinkron, Iterable, atau API berhalaman asinkron?
  2. Haruskah hasilnya dikembalikan sebagai satu array, atau dapatkah pemanggil terus mengonsumsinya sebagai stream?
  3. Setelah mengambil N hasil, haruskah kursor jaringan, file, atau database ditutup?
  4. Apakah versi Node dan browser target menyediakan Iterator Helpers bawaan, dan apakah polyfill diizinkan?

4. Kerangka jawaban 30 detik

Saya akan menormalisasi Iterable menjadi Iterator, lalu merangkaikan filter, map, dan take, serta memanggil toArray hanya pada batas yang benar-benar membutuhkan array. map dan filter tidak langsung melakukan iterasi; reduce dan toArray memulai proses konsumsi. Begitu take mencapai batasnya, pipeline harus berhenti menarik data dan menggunakan penutupan iterator agar sumber daya dapat dilepaskan. Iterator bersifat stateful dan tidak boleh dibagikan sembarangan di antara konsumen. Runtime yang lebih lama dapat menggunakan polyfill terkontrol atau implementasi generator dengan semantik yang sama, yang telah diuji terhadap pengecualian, penghentian dini, dan penggunaan memori pada sumber yang besar.

5. Jawaban mendalam langkah demi langkah

Langkah 1: Membedakan Iterator dan Iterable

Iterable menyediakan metode Symbol.iterator yang dapat menghasilkan Iterator; Iterator menyediakan next dan mengembalikan done serta value. Iterator.from menormalisasi input yang mengikuti protokol iterasi. Iterator Helpers beroperasi pada iterator dan membuat helper yang bersifat lazy; helper ini tidak secara otomatis menyalin seluruh sumber ke dalam array.

Langkah 2: Membangun pipeline lazy untuk map, filter, dan take

Fungsi di bawah ini membaca sumber hanya saat hasilnya dikonsumsi. filter memeriksa baris, map mentransformasikannya, dan take berhenti setelah jumlah yang diminta tercapai sehingga rekaman yang tidak terkait tidak akan ditarik.

js
function topAmounts(source, limit) {
  return Iterator.from(source)
    .filter((row) => row.status === "paid")
    .map((row) => ({ id: row.id, amount: row.cents / 100 }))
    .take(limit);
}

const firstHundred = topAmounts(records(), 100).toArray();

Langkah 3: Memahami waktu konsumsi dan status satu kali jalan (one-pass)

Membuat helper tidak langsung mengeksekusi callback. Menarik data dengan next, atau memanggil forEach, find, reduce, atau toArray, akan mengonsumsi nilai sumber. Iterator menyimpan posisi saat ini; konsumen pertama mengubah statusnya dan konsumen kedua mungkin menemukan iterator yang sudah habis. Buat iterator sumber baru untuk hasil yang independen alih-alih berbagi instance yang sudah terkonsumsi.

Langkah 4: Menangani penghentian dini, return, dan pengecualian

Operasi seperti take dan find dapat berhenti setelah memperoleh suatu hasil. Jika iterator yang mendasarinya menyediakan return, helper harus memberinya kesempatan untuk menutup sumber daya saat selesai atau gagal, seperti handle file atau kursor halaman. Kode bisnis tetap harus melepaskan sumber daya miliknya di dalam blok finally, dan memverifikasi pembersihan saat callback melempar error atau konsumen berhenti lebih awal.

Langkah 5: Memilih batas materialisasi dan fallback

toArray mematerialisasi sisa hasil, jadi letakkan fungsi ini hanya di tempat di mana akses acak, serialisasi, atau rendering batch benar-benar membutuhkan array. Iterator tak terbatas, halaman besar, dan komputasi mahal harus tetap dibiarkan lazy. Jika runtime tidak memiliki Iterator Helpers bawaan, gunakan polyfill terkontrol atau pembungkus generator untuk map, filter, dan take. Pertahankan konsumsi satu kali jalan, penghentian dini, dan propagasi pengecualian; jangan diam-diam mengubah setiap sumber menjadi array.

6. Contoh jawaban berkualitas tinggi

Saya akan menormalisasi input dengan Iterator.from, lalu merangkaikan filter, map, dan take, serta memanggil toArray hanya pada batas keluaran yang membutuhkan array. Callback helper berjalan selama proses konsumsi, sehingga sumber yang besar tidak diekspansi lebih awal; take atau find harus berhenti menarik data dan menggunakan return agar kursor yang mendasarinya dapat ditutup. Iterator bersifat stateful dan biasanya hanya sekali pakai, sehingga hasil yang independen membutuhkan iterator sumber yang baru. Untuk Node atau browser versi lama, saya akan menggunakan polyfill atau implementasi generator dengan semantik lazy dan penutupan yang sama, serta menguji pengecualian, penghentian dini, pelepasan sumber daya, dan lonjakan memori.

7. Kesalahan umum

  • Menyebarkan (spreading) sumber terlebih dahulu → seluruh sumber termaterialisasi → pertahankan toArray hanya pada batas yang benar-benar membutuhkan array.
  • Menganggap bahwa pembuatan map langsung mengeksekusi callback → efek samping tidak muncul selama penyiapan → jelaskan bahwa konsumsi yang memicu penarikan data.
  • Menggunakan kembali satu iterator → hasil kedua kosong atau parsial → buat sumber baru untuk setiap konsumen.
  • Tetap meminta halaman setelah take → jaringan dan sumber daya terbuang sia-sia → verifikasi bahwa penghentian dini memanggil return yang mendasarinya.
  • Polyfill yang hanya menyalin hasil array → semantik sumber tak terbatas dan pengecualian berubah → pertahankan sifat lazy, status satu kali jalan, dan propagasi pengecualian.

8. Pertanyaan lanjutan dan respons

Pertanyaan lanjutan 1: Apa perbedaan utama antara Iterator Helpers dan metode array?

Metode array beroperasi pada array yang sudah dimaterialisasi dan biasanya langsung melakukan iterasi. Iterator Helpers menerima iterator dan melakukan transformasi lazy seperti map, filter, dan take, hanya menarik elemen yang diminta oleh konsumen.

Pertanyaan lanjutan 2: Kapan Anda masih harus memanggil toArray?

Panggil fungsi ini saat suatu batasan membutuhkan pengindeksan acak, serialisasi, API batch yang hanya menerima array, atau rendering satu kali berskala kecil. Hindari materialisasi untuk sumber yang sangat besar atau tak terbatas dan tetap konsumsi secara lazy.

Pertanyaan lanjutan 3: Mengapa iterator tidak boleh digunakan kembali secara sembarangan?

Iterator menyimpan kursor, dan next mengubah status internalnya. Setelah satu konsumen membacanya, konsumen kedua akan menerima posisi yang tersisa. Untuk memutar ulang, diperlukan iterator baru yang dihasilkan dari Iterable.

Pertanyaan lanjutan 4: Bagaimana Anda memverifikasi bahwa penghentian dini melepaskan sumber daya?

Gunakan iterator uji yang menghitung tarikan data dan mencatat pemanggilan return. Setelah take atau find, pastikan penarikan berhenti dan return berjalan, lalu cakup kasus pengecualian callback dan gangguan pada konsumen.

Sumber publik

Pertanyaan terkait

Alat wawancara terkait

Gunakan Tangkapan Layar untuk perintah coding

Ambil tangkapan layar soal, lalu telusuri batasan, solusi, kode, edge case, dan kompleksitas secara berurutan.

Lihat alat