Prompt dan cakupan
Sebuah platform event memiliki writer dan reader Avro yang dimiliki oleh tim yang berbeda. Satu perubahan hanya mengedit whitespace JSON atau doc; perubahan lain menambahkan field dengan nilai default. Registri harus mengidentifikasi skema dengan arti pembacaan yang sama sambil menolak perubahan yang tidak kompatibel. Rancang kanonikalisasi, fingerprint, compatibility gate, dan negosiasi cache.
Ini menguji pengetahuan spesifikasi Apache Avro. Perlakukan fingerprint sebagai pengidentifikasi, bukan tanda tangan keamanan, dan jangan berasumsi bahwa setiap binding bahasa mengekspos API registri yang sama.
Apa yang sedang diuji oleh pewawancara
- Membedakan Parsing Canonical Form, resolusi skema, dan nomor versi bisnis.
- Menyebutkan atribut mana yang dihapus, diurutkan, atau dinormalisasi.
- Memilih fingerprint 64-bit, 128-bit, atau SHA-256 menggunakan risiko tabrakan dan skala.
- Merancang release gate, cache hit, kegagalan negosiasi, dan observabilitas rollback.
Pertanyaan klarifikasi
- Apakah fingerprint ditujukan untuk kunci cache lokal, negosiasi lintas layanan, atau identitas audit dan supply-chain?
- Apakah registri menyimpan skema writer, dan dapatkah consumer mengambil berdasarkan fingerprint?
- Apakah kompatibilitas bersifat backward, forward, atau bidirectional?
- Pada tabrakan, dapatkah sistem melakukan fallback untuk membandingkan byte kanonikal lengkap?
- Versi spesifikasi Avro mana yang digunakan klien, dan apakah ada kanonikalisator kustom?
Jawaban 30 detik
“Saya mengubah skema yang valid menjadi Avro Parsing Canonical Form, lalu membuat fingerprint dari byte kanonikal tersebut. Aturan ini menghapus atribut non-parsing seperti doc, menormalisasi urutan kunci objek, dan menghilangkan whitespace JSON yang tidak relevan. Fingerprint hanya berfungsi sebagai indeks cache dan negosiasi; registri tetap menjadi otoritas untuk skema lengkap, dan kompatibilitas diperiksa dengan resolusi writer/reader. Saya menggunakan fingerprint Rabin 64-bit untuk cache kecil, 128-bit atau SHA-256 pada skala yang lebih besar, dan membandingkan byte kanonikal setelah terjadi hit untuk menangani tabrakan. Setiap jalur rilis dan runtime mencatat versi spesifikasi, fingerprint, hasil resolusi, dan alasan fallback.”
Desain langkah demi langkah
1. Menghasilkan byte kanonikal
Input harus berupa JSON Avro UTF-8 yang valid. Konversikan skema primitif ke bentuk sederhana, ekspansi nama lengkap, dan hapus namespace yang redundan. Simpan hanya atribut parsing seperti type, name, fields, symbols, items, values, dan size. Urutkan kunci objek, unescape string JSON, hapus tanda kutip dan leading zero dari literal integer, serta hapus whitespace di luar string.
2. Memisahkan identitas dari kompatibilitas
Teks kanonikal yang sama berarti reader tidak dapat membedakan skema untuk parsing; ini tidak membuktikan bahwa setiap versi dapat saling dibaca. Gate tetap menjalankan resolusi skema: field record dicocokkan berdasarkan nama, field khusus writer dapat diabaikan, field yang ditambahkan reader memerlukan default, dan promosi numerik mengikuti spesifikasi.
3. Memilih panjang fingerprint
Fingerprint Rabin 64-bit cocok untuk cache sekitar satu juta skema; digest 128-bit cocok untuk koleksi yang jauh lebih besar, dan SHA-256 menyediakan pengidentifikasi yang lebih panjang. Avro secara eksplisit menyatakan bahwa fingerprint tidak memberikan jaminan keamanan, jadi gunakan tanda tangan, otorisasi, dan pemeriksaan integritas secara terpisah. Registri menyimpan byte kanonikal lengkap dan skema sebagai otoritas.
valid schema -> canonical bytes -> fingerprint
| |
registry value cache / handshake key4. Membangun release gate
Pada saat commit, hitung byte kanonikal dan fingerprint. Pertama, klasifikasikan perubahan hanya sebagai doc, redundansi namespace, atau whitespace; kemudian jalankan resolusi writer/reader terhadap kumpulan consumer produksi. Gate harus melaporkan “bentuk kanonikal sama”, “kompatibel tetapi bentuk kanonikal berbeda”, atau “tidak kompatibel”, daripada membandingkan teks JSON mentah. Simpan fingerprint, skema lengkap, versi kanonikalisator, dan laporan kompatibilitas secara bersamaan.
5. Negosiasi saat runtime dan pemulihan dari tabrakan
Consumer mengirimkan fingerprint; kondisi hit mengembalikan atau mengonfirmasi skema yang di-cache, sementara miss melakukan kueri ke registri. Jika byte kanonikal yang berbeda memiliki fingerprint pendek yang sama, bandingkan byte lengkap dan kembalikan konflik daripada menggunakan kembali cache secara diam-diam. Kunci cache dapat menggabungkan fingerprint dengan panjang kanonikal atau digest konten kedua untuk mengurangi hit yang tidak disengaja.
6. Mengamati upgrade dan pemulihan
Catat producer, consumer, fingerprint, versi kanonikalisator, hasil resolusi, latensi registri, miss, konflik, dan fallback; jangan pernah mencatat payload event. Saat meng-upgrade kanonikalisator, hitung ulang skema lama secara offline dan lakukan pembacaan ganda (dual-read) terhadap kunci lama dan baru. Beralihlah hanya setelah hit rate dan laporan kompatibilitas stabil, sambil mempertahankan pemetaan lama untuk rollback.
Model jawaban berkualitas tinggi
“Saya memperlakukan skema Avro sebagai input terstruktur dan menghasilkan byte kanonikal: menghapus doc dan atribut non-parsing lainnya, mengekspansi nama lengkap, memperbaiki urutan kunci, dan menormalisasi string, integer, serta whitespace. Bentuk kanonikal yang sama hanya berarti reader tidak dapat membedakan skema; release gate tetap menjalankan resolusi writer/reader, terutama nilai default untuk field yang ditambahkan reader, pencocokan nama, dan promosi numerik. Fingerprint mendukung caching dan negosiasi protokol, bukan keamanan. Saya menggunakan Rabin 64-bit pada skala kecil dan 128-bit atau SHA-256 pada skala yang lebih besar, membandingkan byte lengkap setelah hit, dan menyimpan skema lengkap di registri. Telemetri mencakup fingerprint, versi kanonikalisator, kompatibilitas, miss, dan konflik sehingga upgrade dapat di-dual-read dan di-rollback.”
Kesalahan umum
- Melakukan hash pada JSON mentah → whitespace atau urutan kunci menciptakan versi palsu → kanonikalisasi terlebih dahulu.
- Memperlakukan bentuk kanonikal yang sama sebagai kompatibilitas universal → default reader dan promosi dilewati → tetap jalankan resolusi skema.
- Memperlakukan fingerprint 64-bit sebagai tanda tangan keamanan → tidak dapat menahan pemalsuan atau manipulasi → gunakan tanda tangan dan kontrol akses secara terpisah.
- Hanya menyimpan fingerprint pendek → miss atau tabrakan tidak dapat memulihkan skema → simpan byte kanonikal lengkap.
- Mengganti kanonikalisator secara langsung di tempat → kunci cache lama dan baru terpisah → lakukan dual-read dan amati sebelum beralih.
Pertanyaan lanjutan dan tanggapan
Mengapa mengubah doc dapat membiarkan bentuk kanonikal tidak berubah?
doc tidak relevan untuk parsing dan dihapus oleh aturan bentuk kanonikal. Dokumentasi produk, jejak audit, dan metadata kode yang dihasilkan mungkin masih memerlukan skema asli dan catatan perubahan yang disimpan secara terpisah.
Bagaimana Anda membuktikan bahwa tabrakan tidak men-decode skema yang salah?
Gunakan fingerprint pendek hanya sebagai indeks. Bandingkan byte kanonikal lengkap saat terjadi hit; jika berbeda, kembalikan konflik, ambil skema lengkap, buat peringatan, dan blokir decoding otomatis.
Mengapa tidak hanya menggunakan nomor versi bisnis?
Versi bisnis mengekspresikan maksud rilis tetapi tidak dapat melakukan deduplikasi skema yang setara di seluruh tim atau representasi JSON. Menggabungkan fingerprint, skema lengkap, dan laporan resolusi mendukung deduplikasi, negosiasi, dan audit.