Topik wawancara representatif

Wawancara rekayasa data: Bagaimana cara mengembangkan skema event tanpa merusak consumer?

DataSedang
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah event pesanan dikonsumsi oleh belasan layanan dan beberapa pipeline data. Anda harus menambahkan field wajib fulfillment_mode dan memecah nilai status lama menjadi enum yang lebih terperinci. Bagaimana Anda akan mengembangkan skema event tersebut tanpa membuat consumer lama crash, merusak pemutaran ulang historis, atau membuat producer baru dan lama tidak kompatibel?

Perintah dan konteks

Pertanyaan rekayasa data ini menguji evolusi kontrak event jangka panjang. Intinya bukan menghafal definisi backward atau forward, melainkan menyusun rencana yang aman dari reader nyata, writer, format serialisasi, data historis, dan urutan peluncuran. Anda perlu menjelaskan sasaran kompatibilitas, semantik field, registrasi dan pengujian, pengoperasian dua versi, serta kondisi untuk pembersihan akhir.

Hal yang dinilai oleh pewawancara

  • Apakah Anda membedakan skema writer, skema reader, dan kombinasi saat deployment.
  • Apakah Anda memilih batasan backward, forward, full, atau transitive berdasarkan urutan peluncuran consumer.
  • Apakah Anda menangani field wajib, perubahan enum, nilai default, nilai yang tidak dikenal, dan pemutaran ulang historis.
  • Apakah tata kelola registry, uji kontrak, pemantauan, rollback, dan kepemilikan menjadi bagian dari proses rilis.

Pertanyaan klarifikasi yang perlu diajukan

Buat daftar format event, topik atau tabel, setiap producer dan consumer, pelanggan eksternal atau lintas tim, serta kecepatan peningkatan (upgrade) setiap consumer. Perjelas apakah fulfillment_mode memiliki arti baru atau dapat diturunkan tanpa kehilangan data dari status lama, dan apakah enum baru mengizinkan nilai yang tidak dikenal. Tanyakan juga apakah event historis harus diputar ulang, apakah data lake menyimpan payload mentah, siapa yang memiliki kebijakan kompatibilitas, dan apakah dua versi dapat berjalan bersamaan secara singkat.

Kerangka jawaban 30 detik

Saya akan menyusun inventaris consumer dan urutan peluncuran reader/writer, memilih arah kompatibilitas, dan menerapkannya dalam sebuah registry. Tambahkan field baru sebagai opsional atau dengan nilai default yang stabil, gunakan representasi enum yang dapat diperluas, dan minta producer menuliskan field lama serta baru sementara consumer bermigrasi sesuai kapabilitasnya. Tentukan pemetaan dan perilaku nilai yang tidak dikenal untuk pemutaran ulang, lalu validasi dengan uji kontrak, sampel pemutaran ulang, dan pemantauan runtime. Hapus field atau versi lama hanya setelah setiap consumer selesai bermigrasi dan jendela retensi ditutup.

Pembahasan mendalam langkah demi langkah

1. Buat matriks reader/writer dan sasaran kompatibilitas

Buat daftar writer lama dengan reader lama, writer lama dengan reader baru, writer baru dengan reader lama, dan writer baru dengan reader baru. Jika consumer dapat di-upgrade terlebih dahulu, Anda memerlukan kompatibilitas forward; jika producer di-upgrade terlebih dahulu, Anda memerlukan kompatibilitas backward; deployment bertahap (rolling deployment) biasanya memerlukan keduanya selama masa transisi. Pemutaran ulang historis di banyak versi juga memerlukan pemeriksaan transitive daripada hanya membandingkan dengan skema terbaru.

2. Jadikan semantik field dapat diperluas dengan aman

Jangan langsung menjadikan field baru sebagai field wajib bagi setiap reader lama. Untuk format seperti Avro, gunakan nullable union atau nilai default jika sesuai; untuk JSON, tentukan perbedaan antara field yang hilang (missing), null, dan tidak dikenal (unknown). Saat memperluas enum, pastikan consumer lama memiliki percabangan nilai unknown yang aman alih-alih mengasumsikan hanya nilai saat ini yang akan tiba. Jika status lama tidak dapat dipetakan tanpa kehilangan data, tambahkan versi event baru atau field paralel daripada mengubah artinya secara diam-diam.

3. Gunakan registry dan uji kontrak untuk memblokir rilis yang tidak kompatibel

Daftarkan skema berdasarkan subjek atau tipe event dan tentukan penamaan, tingkat kompatibilitas, serta pemiliknya. Periksa skema baru selama proses build producer. Pada CI consumer, lakukan deserialisasi sampel nyata lama dan baru serta uji perilaku bisnisnya. Uji nilai default, enum yang tidak dikenal, semantik waktu dan unit, nilai null, serta perilaku setelah penghapusan field, bukan hanya keberhasilan parsing. Pemeriksaan yang gagal akan memblokir rilis alih-alih menjadi kesalahan consumer secara online.

4. Luncurkan dengan dual write dan bertahap

Rilis consumer yang dapat membaca kedua format terlebih dahulu. Kemudian minta producer mengisi field baru sambil tetap mempertahankan field lama. Pantau versi consumer, kesalahan parsing, penggunaan nilai default, dan lag event; pipeline data juga harus memverifikasi tipe tabel, partisi, dan backfill. Untuk enum atau struktur yang tidak kompatibel, buat tipe event atau topik baru, gunakan bridge untuk memublikasikan keduanya, dan berikan pemilik serta tanggal penghentian untuk setiap jalur.

5. Tentukan kondisi pemutaran ulang, rollback, dan pembersihan

Lakukan parsing event historis dengan skema writer-nya, lalu gunakan pemetaan berversi yang eksplisit untuk membuat model saat ini. Jangan diam-diam menerapkan nilai default hari ini pada fakta masa lalu. Pertahankan skema lama dan baru, kode konversi, serta snapshot sampel. Selama rollback producer, verifikasi bahwa versi lama dapat membaca event yang telah ditulis. Hapus field lama atau topik bridge hanya setelah semua consumer bermigrasi, pembacaan field lama mencapai nol, pemeriksaan pemutaran ulang dan kualitas berhasil, serta jendela pemberitahuan ditutup.

Contoh jawaban yang kuat

Saya akan mendata belasan consumer dan beberapa pipeline data, memetakan empat kombinasi reader/writer selama rolling deployment, dan menentukan apakah fulfillment_mode dapat diturunkan tanpa kehilangan data dari status lama atau merupakan fakta baru. Jika dapat diturunkan, saya akan membuat field tersebut opsional dengan nilai default yang stabil dan mempertahankan status lama; enum akan menyertakan percabangan unknown yang aman. Saya akan merilis consumer yang membaca kedua format, lalu meminta producer melakukan dual-write sementara registry menegakkan kompatibilitas. CI akan menguji event lama dan baru, field yang hilang, enum yang tidak dikenal, dan pemutaran ulang historis, sementara pemantauan produksi melacak kegagalan parsing, penggunaan nilai default, versi consumer, dan kualitas tabel. Jika strukturnya benar-benar tidak kompatibel, saya akan membuat versi event baru dan menjembatani kedua jalur tersebut. Hanya setelah setiap consumer bermigrasi, pembacaan field lama mencapai nol, validasi pemutaran ulang berhasil, dan jendela rollback ditutup, barulah saya menghapus field lama dan bridge.

Kesalahan umum

  • Mengatakan "aktifkan kompatibilitas backward" tanpa membuat daftar urutan peluncuran producer dan consumer.
  • Menambahkan field wajib tanpa nilai default, aturan field yang hilang, atau jalur aman untuk reader lama.
  • Memperluas enum sehingga consumer lama melempar exception atau memperlakukan nilai yang tidak dikenal sebagai status bisnis yang salah.
  • Hanya memeriksa apakah skema terdaftar alih-alih menguji sampel lama yang nyata, pemutaran ulang, tipe tabel, dan hasil bisnis.
  • Menimpa arti field sehingga pemutaran ulang historis ditafsirkan secara keliru.
  • Mempertahankan dual write dan kode bridge selamanya tanpa pemilik, pemantauan, tanggal penghentian, atau kondisi rollback.

Pertanyaan lanjutan dan jawaban

Bagaimana Anda memilih kompatibilitas backward, forward, atau full?

Gunakan urutan peluncuran dan pola konsumsi. Peluncuran producer terlebih dahulu mengharuskan reader lama membaca data baru, jadi utamakan kompatibilitas backward. Peluncuran consumer terlebih dahulu mengharuskan reader baru membaca data lama, jadi utamakan kompatibilitas forward. Jika urutan tidak terkontrol atau kedua arah harus berfungsi, gunakan full. Untuk semua versi historis, gunakan transitive dan konfirmasikan aturan format yang sebenarnya.

Mengapa field baru biasanya harus memiliki nilai default?

Event lama tidak memilikinya, sehingga pembacaan data lama memerlukan perilaku yang eksplisit. Nilai default memungkinkan reader melakukan parsing, tetapi harus berarti tidak diketahui atau tidak disediakan daripada berpura-pura menjadi fakta historis. Tanpa default yang bermakna, gunakan tipe nullable, versi event baru, atau backfill eksplisit.

Bagaimana Anda menangani enum baru selama pemutaran ulang historis?

Pertahankan skema writer, parsing semantik asli terlebih dahulu, dan petakan ke dalam model saat ini dengan konversi berversi. Arahkan nilai yang tidak dapat dipetakan ke karantina atau penanganan manual beserta alasannya; jangan membuang event atau secara diam-diam menerapkan status default saat ini.

Kapan Anda dapat menghapus field lama?

Setelah setiap producer dan consumer bermigrasi, pembacaan dan penulisan field lama bernilai nol, uji pemutaran ulang, kualitas, dan kontrak berhasil, jendela pemberitahuan pelanggan atau subscriber eksternal ditutup, serta materi rollback dan audit tetap tersedia. Hapus secara bertahap.

Sumber publik

Pertanyaan terkait