Perintah dan konteks
Sebuah platform harus memuat plugin yang dikompilasi dari berbagai bahasa dan menyusunnya dalam beberapa runtime. Jelaskan cara mendefinisikan antarmuka dalam WIT, menyusun komponen, menangani string dan sumber daya (resources), serta menguji Canonical ABI, kesalahan (errors), dan evolusi versi.
Hal yang diuji oleh pewawancara
- Membedakan lapisan modul inti (core module) WebAssembly dari lapisan antarmuka Component Model.
- Memahami WIT sebagai deskripsi antarmuka yang netral bahasa dan Canonical ABI sebagai representasi lintas komponen untuk tipe tingkat tinggi.
- Menjelaskan kepemilikan sumber daya (resource ownership), peminjaman (borrowing), kesalahan bertipe result, dan masa pakai asinkron.
- Memperhitungkan versi komponen, isolasi kapabilitas, adaptor, perbedaan runtime, dan pengujian kompatibilitas.
Pertanyaan klarifikasi yang perlu diajukan
- Tipe data apa yang melintasi batas plugin: file besar, stream, handle, atau sumber daya berumur panjang?
- Kapabilitas WASI apa yang diberikan oleh runtime, dan apakah plugin harus diisolasi dari file, jaringan, atau kunci enkripsi?
- Apakah panggilan bersifat sinkron atau asinkron, dan apakah kesalahan harus dipulihkan, dicoba ulang, atau menghentikan komponen?
- Bagaimana versi WIT dipublikasikan, dapatkah komponen lama disusun dengan host baru, dan siapa yang mengelola matriks kompatibilitas?
Jawaban 30 detik
Saya akan menulis kontrak lintas bahasa terkecil dalam WIT dan menghasilkan binding untuk setiap bahasa. Komponen bertukar string, list, result, dan resource melalui antarmuka Component Model dan Canonical ABI, bukan dengan mengekspos tata letak memori suatu bahasa. Runtime hanya memberikan kapabilitas file atau jaringan yang diperlukan; host mengelola pembatalan (cancellation), batas waktu (deadlines), pemetaan kesalahan, dan pembersihan (cleanup). Evolusi versi menggunakan field tambahan (additive) dan pengujian kompatibilitas, sementara detail ABI modul inti tetap bersifat spesifik untuk implementasi.
Pembahasan mendalam langkah demi langkah
1. Memisahkan modul inti dari antarmuka komponen
Modul inti mengekspos memori linier, fungsi, dan tipe numerik. Component Model membangun antarmuka tingkat lebih tinggi, dependensi, dan komposisi di atasnya. API lintas bahasa harus berhenti pada antarmuka komponen, tidak mengekspos alamat memori kompilator, tata letak struct, atau nama fungsi yang diekspor sebagai kontrak publik.
2. Mengekspresikan tipe netral bahasa dalam WIT
WIT mendeskripsikan antarmuka, world, resource, dan result error; berbagai alat bantu menghasilkan binding untuk Rust, Go, dan bahasa lainnya. Contoh ini menunjukkan sebuah resource handle; validasi sintaksis yang tepat dengan toolchain target:
package example:plugin;
interface store {
resource session;
open: func(name: string) -> result<session, string>;
read: func(s: borrow<session>) -> result<list<u8>, string>;
}Antarmuka mengekspos semantik bisnis sementara penyimpanan, threading, dan alokasi memori tetap menjadi detail implementasi.
3. Memahami Canonical ABI dan masa pakai sumber daya
Canonical ABI menentukan bagaimana string, list, result, dan nilai tingkat tinggi lainnya melintasi batas komponen menggunakan representasi WebAssembly inti. Model komponen mengelola kepemilikan dan peminjaman resource; host harus menentukan penutupan, pembatalan, dan pembersihan. Handle numerik bukanlah pointer abadi. Untuk data berukuran besar, evaluasi biaya penyalinan, streaming, dan backpressure.
4. Merancang kesalahan, kapabilitas, dan versi
Modelkan kegagalan bisnis yang diperkirakan sebagai nilai result atau enum kesalahan eksplisit, yang membedakan kesalahan yang dapat dicoba ulang dari kegagalan otorisasi. Berikan hanya kapabilitas WASI yang diperlukan dan batasi waktu eksekusi, memori, konkurensi, serta ukuran output. Kembangkan WIT secara aditif jika memungkinkan, pertahankan pengujian kompatibilitas untuk world lama, dan gunakan adaptor untuk konversi versi tanpa menyembunyikan perubahan semantik.
Jawaban teladan
Saya akan mendefinisikan antarmuka world netral bahasa terkecil dalam WIT dan menghasilkan binding. Komponen disusun melalui Component Model, sedangkan Canonical ABI merepresentasikan string, list, result, dan resource pada batas pemisah; memori dan ekspor modul inti tetap menjadi detail implementasi. Resource menggunakan peminjaman dan semantik penutupan eksplisit, dengan host yang mengontrol pembatalan, batas waktu, kapabilitas, dan pembersihan. Kesalahan menggunakan tipe result yang dapat dibedakan dan kapabilitas mengikuti hak istimewa terendah (least privilege). Setiap perubahan WIT menjalankan matriks kompatibilitas lintas bahasa, dengan adaptor yang menangani konversi versi sehingga komponen lama tidak secara diam-diam terikat pada semantik baru.
Kesalahan umum
- Berbagi memori linier modul inti atau struct bahasa secara langsung dan melewati antarmuka komponen.
- Memperlakukan WIT sebagai file header satu bahasa tertentu dan mengabaikan binding yang dihasilkan serta semantik tipe data.
- Memperlakukan resource handle sebagai pointer mentah tanpa aturan peminjaman, penutupan, pembatalan, dan pembersihan.
- Hanya menguji skenario sukses (happy path) dan mengabaikan result error, backpressure, batas waktu, serta kapabilitas yang ditolak.
- Memberikan akses seluruh sistem file atau jaringan kepada plugin alih-alih menerapkan batas hak istimewa terendah.
- Hanya mengompilasi host setelah perubahan WIT dan melewatkan pengujian kompatibilitas komponen lama dengan host baru.
Pertanyaan lanjutan dan tanggapan
Kapan Anda akan menggunakan stream daripada byte list?
Gunakan stream ketika data berpotensi besar, harus diproses secara bertahap (inkremental), atau memerlukan batas puncak penggunaan memori. Tentukan backpressure, penyelesaian, dan pembatalan. Konfigurasi atau hasil berukuran kecil dan terbatas dapat menggunakan list setelah memvalidasi ukuran dan masa pakainya.
Bagaimana Anda mencegah plugin berbahaya menghabiskan sumber daya?
Batasi kapabilitas, memori, waktu eksekusi, konkurensi, dan ukuran output pada runtime, serta sediakan isolasi dan pembatalan dari host. Pantau durasi panggilan, tingkat kesalahan, dan kuota; hentikan dan bersihkan jika terjadi pelanggaran.
Bagaimana perubahan WIT tetap kompatibel?
Utamakan antarmuka atau field opsional dan pertahankan arti dari tipe data yang ada. Pertahankan versi world lama dan pengujian lintas bahasa, serta gunakan adaptor saat dibutuhkan. Menghapus atau mengubah semantik memerlukan versi baru dan batas waktu migrasi.