Petunjuk dan konteks
Platform ini memungkinkan plugin pihak ketiga memproses konversi file, validasi field, dan aturan khusus tenant. Plugin berasal dari berbagai bahasa yang berbeda dan tidak dapat dipercaya secara langsung; satu plugin yang tidak terkendali tidak boleh merusak proses host. Desain runtime Wasm Component Model yang mencakup definisi antarmuka, pemuatan (loading), isolasi, anggaran sumber daya, peningkatan yang kompatibel, dan pemulihan.
Component Model mendeskripsikan import dan export dengan komponen, antarmuka, dan world. WIT adalah bahasa definisi antarmuka (interface definition language), sedangkan Canonical ABI mendefinisikan bagaimana nilai tingkat tinggi melintasi batas bahasa. Wawancara ini menguji apakah Anda dapat mengubah standar tersebut menjadi platform plugin multi-tenant yang dapat dioperasikan.
Hal yang dievaluasi pewawancara
Cakup tata kelola antarmuka dan tipe data, prinsip hak akses terendah (least privilege), isolasi instance, anggaran CPU dan memori, batas waktu (timeout) dan pembatalan, penandatanganan serta asal-usul (provenance) komponen, kompatibilitas versi, reproduksibilitas, log dan metrik, canary, serta rollback.
Pertanyaan klarifikasi yang perlu diajukan
- Apakah plugin berjalan di dalam request sinkron atau asynchronous job, dan berapa anggaran latensi serta throughput?
- Kapabilitas file, jaringan, kunci, atau jam apa yang diperlukan, dan bagaimana tenant diisolasi?
- Bisakah antarmuka menggunakan resource, stream, dan future, atau hanya bounded value types?
- Apakah tenant lama harus tetap dapat direproduksi setelah pembaruan, dan berapa lama jendela kompatibilitasnya?
- Apakah pelanggaran atau timeout harus langsung menghentikan eksekusi, mencoba lagi (retry) dalam isolasi, atau menggunakan fallback host?
Jawaban 30 detik
“Definisikan world WIT yang terarah dan berversi, serta ekspos hanya kapabilitas bisnis yang diperlukan. Control plane memverifikasi provenance, tanda tangan, dan dependensi; data plane menjalankan instance Wasm yang terisolasi dengan batas CPU, memori, output, dan deadline. Periksa kompatibilitas antarmuka dan lakukan upgrade canary, sambil mencatat versi, tenant, konsumsi anggaran, dan ringkasan hasil. Timeout atau pelanggaran hanya akan menghentikan plugin tersebut dan mengembalikan nilai default host yang aman.”
Pembahasan mendalam langkah demi langkah
Langkah 1: Tentukan antarmuka WIT dan batasan data
Pilihlah record, variant, list, dan result yang berbatas (bounded) dengan enum error yang eksplisit, panjang maksimum, serta pengkodean (encoding). Jangan mengekspos objek host atau global state yang tersembunyi; setiap world hanya boleh berisi import dan export yang diperlukan oleh kelas plugin tersebut.
world transform-v2 {
export transform: func(input: record { bytes: list<u8>, mime: string }) -> result<list<u8>, transform-error>
}Registri antarmuka mencatat nama paket, versi, aturan kompatibilitas, dan versi toolchain binding. Definisikan antarmuka stream bertekanan balik (backpressured stream) terpisah untuk data besar daripada menyamarkan input tanpa batas sebagai sebuah list.
Langkah 2: Bangun isolasi kapabilitas dan tenant
Buat instance baru untuk setiap pemanggilan. Secara default, jangan berikan kapabilitas jaringan, sistem file, lingkungan, keacakan (randomness), atau kunci. Jika akses diperlukan, berikan host function eksplisit yang terikat pada identitas tenant, plugin, dan request.
Token kapabilitas harus berumur pendek, dapat diaudit, dan tidak dapat digunakan ulang (non-replayable) lintas tenant. Jaga agar API host tetap minimal; jangan pernah menyerahkan pointer proses host atau handle sistem yang tidak difilter ke plugin.
Langkah 3: Tetapkan anggaran dan penghentian
Tetapkan anggaran instruksi atau waktu, batas linear-memory, batas tabel dan stack, batas atas output, serta kuota konkurensi. Sebarkan pembatalan dengan deadline; hentikan instance yang melebihi anggarannya dan catat alasannya. Putuskan apakah retry aman dilakukan hanya setelah memeriksa idempotenitas.
Gunakan antrean asinkron dan lease untuk job berdurasi panjang alih-alih mempertahankan penantian tanpa batas di dalam request pengguna. Ukur (meter) dan terapkan rate-limit berdasarkan tenant dan plugin agar satu tenant tidak menghabiskan pool eksekusi bersama.
Langkah 4: Tangani kompatibilitas komponen dan ABI
Sebelum rilis, lakukan parsing pada world WIT dan dependensi, lalu periksa import dan export terhadap aturan kompatibilitas. Canonical ABI menstandarkan representasi nilai tetapi tidak menjamin kompatibilitas bisnis; penambahan enum, perubahan arti error, dan perubahan unit tetap memerlukan contract test.
Pertahankan executor dan binding untuk world lama dan biarkan plugin mendeklarasikan versi antarmuka yang didukung. Gunakan dual read atau eksekusi bayangan (shadow execution) untuk membandingkan hasil dan perubahan sumber daya sebelum beralih ke versi default.
Langkah 5: Verifikasi supply chain dan pemuatan
Hasilkan digest artefak yang tidak dapat diubah (immutable) dan tandatangani komponen, world WIT, lockfile dependensi, serta metadata build. Control plane hanya mengizinkan penandatangan tepercaya dan dependensi yang telah dipindai; proses pemuatan memeriksa ulang digest, tanda tangan, versi target runtime, dan status pencabutan (revocation).
Catat registrasi, persetujuan, pencabutan, dan rollback dalam audit log. Jangan pernah mengunduh komponen yang tidak terdaftar saat runtime. Beri alamat cache berdasarkan digest sehingga tag yang dipindahkan tidak dapat mengubah kode yang dieksekusi secara diam-diam.
Langkah 6: Observasi, canary, dan pemulihan
Catat digest plugin, versi antarmuka, tenant, latensi, penggunaan sumber daya, status hasil, dan kelas error untuk setiap pemanggilan. Log tidak boleh berisi payload pengguna atau kunci. Agregasikan metrik berdasarkan plugin dan tenant, termasuk timeout, kehabisan memori, dan tingkat penolakan.
Lakukan canary pada versi baru menggunakan traffic sintetis atau sebagian kecil tenant, lalu bandingkan selisih hasil dan tail latency. Jika terjadi regresi, hentikan dan cabut versi tersebut, lalu kembali ke digest sebelumnya. Host menyediakan nilai default yang aman sehingga kegagalan plugin tidak merambat ke logika bisnis inti.
Contoh jawaban yang kuat
Saya akan mendefinisikan world WIT yang terarah dan berversi dengan tipe data berbatas serta hanya memberikan kapabilitas host yang diperlukan. Setiap request mendapatkan instance terisolasi dengan batas CPU, memori, output, deadline, dan konkurensi; control plane memeriksa tanda tangan, digest, dependensi, dan pencabutan. Pembaruan melewati pemeriksaan kontrak, eksekusi bayangan, dan canary kecil. Observabilitas dipisahkan berdasarkan plugin, tenant, dan versi; timeout atau pelanggaran hanya mematikan instance tersebut dan mengembalikan nilai default host yang aman.
Kesalahan umum
- Mengekspos objek host secara langsung → eskalasi hak akses dan kebocoran antar-tenant → gunakan host function minimal.
- Membatasi memori tetapi tidak membatasi waktu → infinite loop tetap menghabiskan resource pool → tetapkan anggaran CPU, deadline, dan konkurensi.
- Menganggap Canonical ABI sebagai kompatibilitas bisnis → unit dan semantik error masih dapat merusak pemanggil → pertahankan contract test dan versi world.
- Melakukan caching berdasarkan mutable tag → tag yang berpindah menjalankan kode yang tidak diketahui → beri alamat berdasarkan digest dan tanda tangan immutable.
- Mencoba ulang (retry) setiap kegagalan → efek samping non-idempoten akan berulang → deklarasikan idempotenitas dan klasifikasikan error.
Pertanyaan lanjutan dan tanggapan
Pertanyaan lanjutan 1: Mengapa tidak menggunakan proses atau kontainer?
Itu tergantung pada model ancaman dan anggaran. Instance Wasm dimulai dengan cepat dan mengekspos antarmuka yang terkontrol, tetapi tidak menggantikan patching runtime, penguatan (hardening) host, atau defense in depth; plugin berisiko tinggi masih dapat berjalan di lapisan isolasi yang lebih kuat.
Pertanyaan lanjutan 2: Bagaimana Anda mendukung streaming file besar?
Definisikan antarmuka stream dengan backpressure beserta batasan konkurensi, ukuran chunk, dan output kumulatif. Gunakan asynchronous job untuk proses yang memakan waktu lama dan audit status pembatalan serta lease.
Pertanyaan lanjutan 3: Bagaimana Anda memutuskan apakah dua versi itu ekuivalen?
Jalankan korpus input tetap melalui eksekusi bayangan dan bandingkan hasil yang dinormalisasi, kelas error, latensi, dan penggunaan sumber daya. Izinkan perbedaan floating-point atau urutan yang telah dideklarasikan, dan tahan rilis jika terjadi delta yang tidak dapat diterima.
Pertanyaan lanjutan 4: Bagaimana jika plugin memerlukan akses jaringan?
Beri plugin tersebut kapabilitas proxy yang di-allowlist berdasarkan tenant dan domain dengan timeout, batas ukuran respons, dan catatan audit. Tolak alamat arbitrer secara default dan batalkan token kapabilitas segera setelah pencabutan.