Topik wawancara representatif

Wawancara coding C++: Bagaimana cara mengevaluasi refleksi statis C++26 tanpa memperlakukan sebuah proposal sebagai ABI yang stabil?

CodingSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah tim ingin menggunakan refleksi statis C++26 untuk menghasilkan string enum dan kode serialisasi. Jelaskan model waktu kompilasi P2996, mengapa ini bukan refleksi runtime atau janji ABI yang stabil, dan bagaimana Anda akan merancang fallback, pengujian, serta matriks rilis.

Konteks dan prompt

Sebuah tim menginginkan refleksi statis C++26 untuk menghapus percabangan manual untuk nama-nama enum, pemeriksaan konfigurasi, dan serialisasi. Kandidat harus menjelaskan model WG21 P2996R13, bagaimana meta-informasi waktu kompilasi berpartisipasi dalam instansiasi template, dan bagaimana cara merilis kode saat dukungan kompiler belum lengkap. Jawaban yang kuat memisahkan proposal bahasa, kode yang dihasilkan, dan kompatibilitas ABI.

Hal yang diuji oleh pewawancara

  • Apakah kandidat mengetahui bahwa P2996 adalah proposal WG21, bukan fitur kompiler yang stabil secara universal.
  • Apakah mereka membedakan antara refleksi waktu kompilasi, informasi tipe runtime (RTTI), dan makro teks.
  • Apakah mereka dapat menjelaskan penyuntikan kembali entitas yang direfleksikan ke dalam deklarasi, termasuk kontrol akses dan biaya instansiasi.
  • Apakah mereka mengenali risiko layout, simbol, dan ABI lintas-kompiler yang dihasilkan.
  • Apakah mereka dapat mengusulkan fallback yang dapat diuji daripada menyajikan sintaksis sebagai solusinya.

Pertanyaan klarifikasi yang diajukan terlebih dahulu

  1. Kompiler, library standar, tingkat bahasa, dan tombol fitur (feature switches) apa saja yang didukung?
  2. Apakah kode yang dihasilkan hanya digunakan pada waktu build, atau proses harus memuat tipe yang tidak diketahui saat runtime?
  3. Haruskah artefak tetap stabil di berbagai kompiler, shared library, atau bahasa yang berbeda?
  4. Apakah refleksi harus mengekspos metadata hanya-baca (read-only), atau menghasilkan akses anggota, serialisasi, dan fungsi validasi?
  5. Batasan anggaran apa yang ada untuk waktu build, ukuran biner, dan diagnostik?

Jawaban 30 detik

“P2996R13 menjelaskan refleksi statis waktu kompilasi: nilai refleksi menghitung tipe dan anggota selama kompilasi, lalu sintaksis splicing dapat menghasilkan deklarasi. Ini bukan pemindai runtime dan tidak menjanjikan ABI lintas-kompiler. Saya akan mengunci matriks dukungan kompiler, menjaga refleksi di dalam batas pembuatan sumber kode, mempertahankan fallback manual atau yang dihasilkan, serta menguji semantik, layout, dan biaya build. ABI publik tetap menjadi antarmuka eksplisit; detail implementasi tidak boleh bocor melalui layout yang direfleksikan.”

Jawaban mendalam langkah demi langkah

1. Pisahkan tiga model refleksi

Refleksi runtime menanyakan tipe saat program berjalan. RTTI mengekspos bentuk terbatas dari informasi tipe dinamis. Refleksi statis memperlakukan metadata sebagai entitas waktu kompilasi. P2996 bertujuan agar kompiler dapat menelusuri tipe, anggota, dan atribut selama evaluasi konstanta serta menghasilkan deklarasi C++ biasa. Ini tidak dapat membuat biner yang sudah di-deploy menemukan kelas baru.

2. Tunjukkan maksud proposal dengan sintaksis

Berikut ini bersifat konseptual; implementasi persisnya harus sesuai dengan revisi proposal yang didukung oleh kompiler. ^^ memperoleh informasi refleksi dan [: ... :] menyambungkan (splice) kembali hasil refleksi ke dalam sebuah deklarasi. Token ini tidak boleh disajikan sebagai sintaksis produksi yang diterima oleh setiap toolchain.

cpp
enum class Color { red, green, blue };

consteval auto names() {
  constexpr auto r = ^^Color;
  // Pseudocode: enumerate members and build a compile-time string table.
  return make_enum_name_table(r);
}

constexpr auto color_names = names();

Poin wawancara kuncinya adalah aliran data: kompiler membuat metadata, template atau fungsi konstanta memprosesnya, dan artefak akhir tetap berupa data dan fungsi statis biasa.

3. Jelaskan splicing deklarasi dan batasan akses

Splicing dapat menempatkan tipe atau anggota yang direfleksikan kembali ke dalam deklarasi, tetapi tidak melewati kontrol akses, masa pakai (lifetime), atau pemeriksaan tipe. Akses anggota yang dihasilkan tetap mematuhi aturan private, protected, kelas dasar, dan pencarian nama. Mengubah anggota private yang tidak dapat diakses menjadi field berserialisasi publik mengubah kontrak keamanan.

4. Perkirakan biaya template dan build

Grafik tipe yang besar dapat menginstansiasi logika refleksi secara berulang di banyak unit translasi, meningkatkan waktu build dan gangguan diagnostik. Jaga refleksi tetap berada di balik satu batas generasi, simpan tabel yang dihasilkan dalam cache, dan ukur memori puncak dengan build inkremental. Jangan membungkus setiap template bisnis dengan refleksi sampai terbukti bahwa duplikasi kode dan biaya pemeliharaan benar-benar berkurang.

5. Pisahkan ABI dari kode yang dihasilkan

Urutan field, nama, dan layout yang direfleksikan dapat berubah tergantung kompiler, library standar, atau revisi proposal. Antarmuka lintas-shared-library harus menggunakan DTO yang stabil, serialisasi berversi, dan simbol eksplisit; refleksi harus menghasilkan adapter di sisi implementasi. Mengubah anggota private tidak boleh secara tidak sengaja mengubah ABI publik.

6. Rancang matriks fallback kompiler

Gunakan deteksi kemampuan atau opsi build untuk memilih implementasi refleksi dan implementasi manual, tetapi pastikan keduanya berbagi pengujian perilaku yang sama. CI harus mencakup kompiler eksperimental dengan dukungan proposal, toolchain stabil, dan build dengan refleksi yang dinonaktifkan. Catat versi kompiler dan library, tombol fitur, hash generasi, dan pemeriksaan antarmuka biner di setiap artefak.

Contoh jawaban berkualitas tinggi

“Saya akan mengevaluasi P2996R13 sebagai kapabilitas bahasa waktu kompilasi. Proposal ini mengubah tipe dan anggota menjadi metadata waktu kompilasi dan menggunakan template serta splicing untuk menghasilkan deklarasi biasa; ini bukan pemindai kelas runtime dan tidak menyelesaikan ABI lintas-kompiler. Contoh ^^ dan splicing harus divalidasi hanya pada toolchain yang secara eksplisit mendukung revisi proposal tersebut. Dalam produksi, saya akan menjaga refleksi di balik batas pembuatan internal, menggunakan DTO yang stabil dan format berversi untuk antarmuka publik, serta mempertahankan fallback manual. Matriks pengujian membandingkan nama enum, byte yang diserialisasi, perilaku kesalahan, waktu build, dan simbol publik sebelum mengaktifkannya secara bertahap.”

Kesalahan umum

  • Menyebut proposal sebagai standar yang dirilis secara luas → dukungan dan revisi kompiler berbeda-beda → kunci versi dan pertahankan fallback.
  • Memperlakukan refleksi statis sebagai sistem plugin runtime → metadata waktu kompilasi tidak dapat menemukan tipe pasca-deployment → gunakan protokol registrasi eksplisit untuk plugin.
  • Membiarkan refleksi mendefinisikan layout publik → perubahan anggota dapat merusak ABI → isolasi kode implementasi yang dihasilkan di balik DTO yang stabil.
  • Mengabaikan kontrol akses → generator tidak dapat membaca anggota private sembarangan secara legal → jadikan eksposur field sebagai trait atau kebijakan yang eksplisit.
  • Hanya melihat pengurangan baris kode sumber → instansiasi template dapat memperlambat build → ukur waktu, memori, dan ukuran biner.

Pertanyaan lanjutan dan tanggapan

Apa bedanya ini dengan kode yang dihasilkan oleh makro?

Makro mengganti token secara leksikal dan tidak memiliki semantik tipe serta pencarian nama normal. Refleksi statis memproses metadata setelah kompiler memahami tipe tersebut, sehingga dapat menggunakan kembali sistem tipe dan evaluasi konstanta. Fitur ini masih bergantung pada dukungan kompiler dan biaya build, dan tidak ada satu pun dari kedua mekanisme tersebut yang menciptakan ekstensi runtime dengan sendirinya.

Bagaimana Anda menghasilkan pemetaan enum-ke-string?

Refleksikan anggota enum dan hasilkan array atau tabel pencarian pada waktu kompilasi, dengan percabangan unknown eksplisit untuk nilai dasar yang tidak valid. Uji setiap anggota, bilangan bulat di luar jangkauan, kebijakan nama duplikat, dan hasil fallback; konversi ke string bukanlah kompatibilitas protokol.

Bagaimana Anda memverifikasi konsistensi lintas-kompiler?

Masukkan output yang dihasilkan ke dalam pengujian acuan yang sama (golden tests) dan bandingkan byte yang diserialisasi, kode kesalahan, serta simbol publik alih-alih representasi metadata internal. Kunci revisi proposal per kompiler, dan gunakan fallback ke kode manual dengan peringatan yang terlihat ketika matriks gagal.

Kapan Anda harus menghindari refleksi statis?

Hindari ketika pemuatan modul yang tidak diketahui pada saat runtime diperlukan, ABI publik harus bertahan lama, toolchain tidak dapat dikunci, atau refleksi hanya menghemat beberapa baris kode tetapi meningkatkan biaya build secara signifikan. Registrasi eksplisit, generator kode, atau adapter manual lebih mudah untuk diaudit.

Sumber publik

Pertanyaan terkait

Alat wawancara terkait

Gunakan Tangkapan Layar untuk perintah coding

Ambil tangkapan layar soal, lalu telusuri batasan, solusi, kode, edge case, dan kompleksitas secara berurutan.

Lihat alat