Topik wawancara representatif

Wawancara Frontend: Bagaimana Anda mengevaluasi backpressure dan fallback WebSocketStream?

FrontendSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Halaman kolaboratif menerima event frekuensi tinggi dan mengirimkan hasil edit ke server. Evaluasi apakah WebSocketStream cocok, jelaskan bagaimana backpressure Streams, penutupan, dan pembatalan mencegah penumpukan pesan, serta rancang fallback untuk browser yang tidak didukung.

Petunjuk dan cakupan

Halaman kolaboratif menerima event frekuensi tinggi dan mengirimkan hasil edit ke server. Evaluasi apakah WebSocketStream cocok, jelaskan bagaimana backpressure Streams, penutupan, dan pembatalan mencegah penumpukan pesan, serta rancang fallback untuk browser yang tidak didukung.

WebSocketStream adalah Web API eksperimental dan non-standar. API ini mengekspos koneksi sebagai objek ReadableStream dan WritableStream, memungkinkan backpressure Streams untuk mengatur pembacaan dan penulisan. MDN secara eksplisit merekomendasikan untuk memeriksa kompatibilitas browser sebelum penggunaan produksi. Wawancara ini membahas tentang desain protokol stream dan penilaian risiko.

Hal yang diuji oleh pewawancara

Mencakup siklus hidup ReadableStream dan WritableStream, bagaimana backpressure mencegah antrean tak terbatas, kunci reader dan writer, perbedaan antara abort dan close, urutan pesan dan idempotensi, heartbeat dan rekoneksi, penggunaan Worker, deteksi kapabilitas, dan fallback.

Jawaban 30 detik

“Pertama, saya mengonfirmasi bahwa WebSocketStream bukanlah kapabilitas yang distandardisasi secara luas dan hanya mengaktifkannya setelah feature detection. Saya mengelola readable dan writable secara independen, membiarkan backpressure merambat alih-alih melakukan buffering pada array tak terbatas, dan menjadikan close, pembatalan, serta kesalahan jaringan sebagai state yang dapat diobservasi. AbortSignal membawa siklus hidup komponen ke dalam pekerjaan asinkron. Produksi tetap mempertahankan adaptor WebSocket klasik dengan protokol pesan, antrean terbatas, reconnect backoff, dan penekanan duplikat yang sama.”

Solusi langkah demi langkah

Langkah 1: Konfirmasi kapabilitas dan batasan

Periksa apakah runtime mengekspos WebSocketStream sebelum mengaktifkannya. Fitur ini bersifat eksperimental dan non-standar, sehingga dukungan dalam satu build Chrome tidak menjamin dukungan di setiap browser, WebView, atau lingkungan enterprise. Pemeriksaan kapabilitas yang gagal akan langsung memilih implementasi yang stabil.

Langkah 2: Buka koneksi dan stream

Konstruksikan WebSocketStream dan tunggu promise opened untuk mendapatkan informasi readable, writable, protokol, dan ekstensi. Konsumsi sisi readable melalui reader dan tulis melalui writer; laporkan penutupan koneksi melalui promise closed.

js
const socket = new WebSocketStream(url);
const { readable, writable } = await socket.opened;
const reader = readable.getReader();
const writer = writable.getWriter();

Langkah 3: Gunakan backpressure

Jangan memasukkan setiap event ke dalam array biasa. Biarkan highWaterMark dari TransformStream atau WritableStream downstream membatasi antrean, tunggu writer.ready sebelum mengirim, dan panggil read sesuai kecepatan konsumen. Backpressure mengatur stream klien; server tetap memerlukan rate limit tingkat protokol.

Langkah 4: Tentukan pengurutan pesan

Berikan nomor urut, versi dokumen, dan kunci idempotensi pada setiap hasil edit. Setelah terhubung kembali, jangan berasumsi bahwa pesan terakhir di stream lama telah dipersistensikan. Minta gap atau snapshot berversi dari server sebelum menerapkan event baru, dan buat lapisan rendering serta transport mengenali duplikat.

Langkah 5: Tangani pembatalan dan penutupan

Ketika pengguna meninggalkan atau berpindah dokumen, hentikan pembacaan dan penulisan, lalu tutup atau batalkan stream terkait. AbortSignal menghubungkan siklus hidup komponen ke pekerjaan asinkron. Penutupan normal, pembatalan aktif, kesalahan protokol, dan kehilangan jaringan harus menjadi state yang berbeda sehingga logika rekoneksi hanya berlaku untuk kegagalan jaringan yang sebenarnya.

Langkah 6: Lindungi memori dan UI

Pisahkan penguraian (parsing), validasi, dan rendering; pindahkan decoding atau pemrosesan batch ke Worker jika diperlukan. Tetapkan ukuran pesan maksimum, jumlah event tertunda, dan waktu batch. Di atas ambang batas, jeda langganan, gabungkan atau buang event perantara yang dapat direkonstruksi, atau minta snapshot server alih-alih mengumpulkannya tanpa batas.

Langkah 7: Rancang rekoneksi dan pemulihan

Gunakan exponential backoff dengan jitter dan sertakan versi dokumen terakhir yang dikonfirmasi. Setelah server mengembalikan event yang hilang atau snapshot, lanjutkan live stream. ID idempotensi yang dibuat oleh klien mencegah penulisan yang terputus dikirimkan dua kali.

Langkah 8: Terapkan fallback dan observabilitas

Gunakan WebSocket klasik sebagai fallback default dengan message envelope dan state machine yang sama. Catat hasil kapabilitas, latensi opened dan closed, kedalaman antrean, waktu tunggu backpressure, jumlah rekoneksi, event yang dibuang, dan tingkat pemulihan snapshot. Rincikan berdasarkan browser, jenis jaringan, dan versi halaman sebelum memperluas eksperimen.

Trade-off dan batasan

WebSocketStream atau WebSocket

WebSocketStream menyediakan stream backpressure dan sinyal siklus hidup berbasis Promise, namun dukungan dan standardisasinya terbatas. WebSocket klasik tersedia secara luas tetapi mengharuskan aplikasi untuk membatasi pekerjaan onmessage dan antrean pengiriman. Satu abstraksi protokol dapat mendukung kedua transport.

Buang event atau minta snapshot

Event yang dapat direkonstruksi seperti pergerakan kursor dapat digabungkan atau dibuang saat antrean penuh. Hasil edit dokumen tidak dapat dibuang secara diam-diam; jeda konsumsi dan minta snapshot berversi. Pilihan ini bergantung pada komutativitas, pengurutan, dan dukungan replay server.

Main thread atau Worker

Pesan kecil dan rendering berkecepatan rendah cocok untuk main thread. Decoding biner frekuensi tinggi, kompresi, dan penggabungan batch dapat dipindahkan ke Worker. Worker tidak menghilangkan batas total memori, sehingga antrean transport dan pembatalan tetap memerlukan batasan eksplisit.

Latihan kegagalan dan evolusi

Browser tidak mendukung API

Matikan cabang kapabilitas dan verifikasi bahwa WebSocket klasik dapat terhubung, mengonsumsi pesan yang sama, dan melaporkan metrik kompatibilitas.

Konsumen melambat

Perlambat rendering secara artifisial dan verifikasi bahwa waktu tunggu backpressure meningkat, antrean tetap terbatas, dan jalur pemulihan snapshot terpicu pada ambang batas alih-alih mengalami crash.

Koneksi terputus di tengah proses penulisan

Putuskan koneksi segera setelah mengirimkan hasil edit. Verifikasi bahwa ID idempotensi, versi terakhir yang dikonfirmasi, dan reconnect backoff memulihkan state tanpa menerapkan hasil edit dua kali.

Kesalahan umum dan tindak lanjut

Kesalahan 1: Mengasumsikan Streams menyelesaikan throttling server

Tindak lanjut: Apa yang dikendalikan oleh backpressure? Backpressure mengendalikan produksi dan konsumsi di dalam stream klien; fitur ini tidak menggantikan kuota server, batas koneksi, atau batching bisnis.

Kesalahan 2: Memperlakukan close, cancel, dan abort sebagai hal yang identik

Tindak lanjut: Apa yang terjadi saat komponen di-unmount? Catat penutupan normal, pembatalan baca, dan abort asinkron secara terpisah sehingga logika rekoneksi menargetkan kegagalan jaringan yang sebenarnya.

Kesalahan 3: Hanya merilis WebSocketStream

Tindak lanjut: Bagaimana dengan WebView atau browser lama? Pemeriksaan kapabilitas yang gagal akan memilih adaptor WebSocket klasik, sementara protokol pesan dan state machine tetap sama.

Tindak lanjut lebih dalam dan contoh jawaban

Mengapa harus await writer.ready?

Ini memungkinkan pengirim menunggu kapasitas WritableStream di bawah backpressure alih-alih membuat promise atau array yang tidak terbatas. Batasan rate limit dan ukuran pesan server tetap diperlukan.

Kapan klien harus meminta snapshot?

Ketika antrean event melebihi batasnya, terjadi sequence gap, atau klien tidak dapat mengonfirmasi versi yang berurutan, snapshot berversi lebih aman daripada menebak urutan event.

Bagaimana cara meluncurkan API eksperimental?

Kelompokkan berdasarkan kapabilitas, versi browser, dan versi halaman, lalu aktifkan untuk persentase kecil. Bandingkan kedalaman antrean, pemulihan disconnect, tingkat kesalahan, dan latensi render; nonaktifkan flag dan kembali ke WebSocket klasik ketika metrik mengalami regresi.

Sumber publik

Pertanyaan terkait