Topik wawancara representatif

Wawancara Coding Go: Mengevaluasi new(expr) dan go fix pada Go 1.26

CodingSedang
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah tim sedang melakukan upgrade ke Go 1.26. Jelaskan new(expr), batasan generik rekursif, dan go fix yang baru, lalu rancang proses migrasi dan rollback yang aman.

Perintah dan konteks

Sebuah layanan Go beralih ke versi 1.26 untuk mengurangi boilerplate inisialisasi pointer dan memodernisasi API lama. Jelaskan new(expr), batasan generik yang mereferensikan diri sendiri (self-referential), dan go fix yang ditulis ulang, lalu rancang pipeline migrasi yang tidak menerapkan perubahan perilaku secara langsung ke produksi.

Topik ini cocok untuk peran backend Go, infrastruktur, dan developer-tool. Catatan rilis Go 1.26 mendefinisikan ekspresi nilai untuk new, batasan generik rekursif, dan modernizer berbasis go/analysis; Go Blog menambahkan detail migrasi API dan //go:fix inline. Artikel ini didasarkan pada sumber publik, bukan klaim tentang bank soal wawancara perusahaan tertentu.

Apa yang dievaluasi oleh pewawancara

Pewawancara memeriksa apakah Anda membedakan antara kemudahan sintaksis, ekspresivitas sistem tipe, dan risiko penulisan ulang otomatis. Jawaban yang kuat menjelaskan bahwa new(expr) menunjuk ke variabel baru yang telah diinisialisasi, batasan generik masih memerlukan method set, dan go fix hanya berlaku di bawah versi modul yang sesuai, disertai tinjauan diff, pengujian, dan peluncuran bertahap.

Pertanyaan klarifikasi

  • Berapa versi minimum Go untuk layanan ini dan apa direktif go pada modul?
  • Apakah field pointer berarti "hilang/tidak ada", atau apakah nilai nol (zero value) juga bermakna?
  • Apakah modernizer otomatis boleh mengubah API di berbagai paket?
  • Apakah migrasi harus mempertahankan kompatibilitas biner, kompatibilitas serialisasi, atau hanya perilaku pengujian?

Jawaban 30 detik

"Di Go 1.26, new(expr) membuat pointer yang diinisialisasi, berguna untuk field JSON atau protobuf opsional, tetapi tidak mengubah semantik nil versus zero-value. Batasan generik dapat merujuk ke tipe generik itu sendiri, yang mengekspresikan interface rekursif. go fix yang ditulis ulang menyediakan modernizer yang dapat diaudit. Saya akan mematok versi modul, membuat diff yang dapat ditinjau, menjalankan pengujian, pemeriksaan statis, dan pengujian kompatibilitas serialisasi, lalu melakukan canary release pada perubahan tersebut. Jika terjadi regresi, batalkan patch atau nonaktifkan satu fixer terkait."

Solusi langkah demi langkah

Properti utama dari new(expr) adalah inisialisasi nilai: p := new(300) membuat variabel baru dengan nilai 300; ini tidak mengembalikan alamat dari variabel yang sudah ada di dalam ekspresi. Hal ini berguna dalam struct literal dan argumen fungsi yang memerlukan pointer, seperti *int opsional. Protokol harus tetap membedakan nil, pointer ke nol, dan field yang diabaikan.

Go 1.26 memungkinkan tipe generik muncul dalam batasan parameter tipenya sendiri. Adder[A Adder[A]] dapat mengharuskan A untuk menyediakan Add(A) A. Ini memperluas ekspresivitas batasan tetapi tidak menjamin terminasi rekursi saat runtime; algoritma tetap harus menangani struktur kosong, kedalaman, dan implementasi metode konkret. Konfirmasikan versi compiler dan modul dependensi sebelum migrasi.

go fix yang baru menggunakan framework go/analysis yang sama dengan go vet, menyertakan modernizer bawaan, dan mendukung migrasi API tingkat kode sumber yang dideklarasikan dengan //go:fix inline. Tujuannya adalah mempertahankan perilaku, tetapi tim harus memperlakukan setiap patch sebagai bahan tinjauan: batasi cakupan direktori, patok toolchain, simpan diff, dan tolak pemformatan yang tidak terkait.

Pemeriksaan versi (version gates) menentukan apakah suatu fixer dapat dijalankan. Panduan resmi mengharuskan direktif go.mod pada modul atau constraint build memenuhi versi yang sesuai, mencegah modul lama mengadopsi sintaksis baru terlalu dini. Jalankan go fix pada branch terisolasi, lalu jalankan gofmt, go vet, pengujian unit dan integrasi, serta benchmark. Tambahkan perbandingan golden untuk JSON, protobuf, refleksi, dan kode yang banyak menggunakan unsafe.

Lakukan canary berdasarkan paket atau layanan dan pantau biner, tingkat kesalahan, byte yang diserialisasi, latensi, dan memori. Jika satu modernizer mengubah perilaku, kembalikan patch fixer tersebut alih-alih seluruh toolchain. Jika masalah berasal dari compiler atau runtime upgrade itu sendiri, lakukan rollback pada build image dan versi modul. Catat versi Go, nama fixer, diff, dan bukti pengujian.

Contoh jawaban

Saya akan menggunakan empat tahap: konfirmasi semantik, penulisan ulang otomatis, verifikasi, dan canary. Pertama, konfirmasikan bahwa new(expr) hanya mengubah inisialisasi pointer dan mempertahankan kontrak nil, zero-value, serta serialisasi; konfirmasikan bahwa generik rekursif hanya memperluas batasan. Jalankan go fix dengan versi modul yang dipatok dan simpan diff yang dapat diaudit. Setiap patch harus lolos gofmt, go vet, pengujian, benchmark, dan pengujian golden serialisasi sebelum peluncuran tingkat layanan dengan jalur rollback per-fixer.

Kesalahan umum

  • Kesalahan → menganggap new(0) sebagai pointer nil; Mengapa gagal → itu menunjuk ke variabel baru yang berisi nol; Solusi → pertahankan nil untuk ketiadaan nilai dan uji serialisasi.
  • Kesalahan → melakukan commit sintaksis baru di bawah go.mod lama; Mengapa gagal → toolchain lama tidak dapat mem-parsingnya dan fixer seharusnya tidak berjalan; Solusi → perbarui version gate dan patok CI.
  • Kesalahan → menjalankan go fix di seluruh repositori tanpa peninjauan; Mengapa gagal → API lintas paket dan pengeditan yang tidak terkait dapat ikut masuk; Solusi → batasi cakupan direktori, tinjau diff, dan lakukan canary untuk setiap fixer.
  • Kesalahan → hanya menjalankan pengujian unit; Mengapa gagal → regresi JSON/protobuf dan kinerja bisa lolos; Solusi → tambahkan pemeriksaan golden, integrasi, dan benchmark.

Pertanyaan lanjutan

Apa perbedaan antara new(expr) dan &expr?

Keduanya menghasilkan pointer, tetapi new(expr) mengalokasikan dan menginisialisasi variabel baru dari ekspresi nilai. &expr memerlukan ekspresi yang dapat dialamatkan (addressable) dan mengambil alamat dari variabel yang sudah ada. Tinjauan migrasi harus memeriksa masa pakai (lifetime), kemampuan beralamat (addressability), dan pembagian data yang tidak disengaja.

Bagaimana Anda membuktikan bahwa go fix mempertahankan perilaku?

Simpan satu diff per fixer, jalankan kompilasi, analisis statis, pengujian unit dan integrasi, lalu bandingkan output serialisasi, kode kesalahan, dan benchmark utama dengan pengujian golden atau ambang batas statistik. Kode yang banyak menggunakan refleksi dan unsafe juga menerima tinjauan manual dan canary kecil.

Apa risiko yang timbul dari batasan generik rekursif?

Fitur ini mengekspresikan interface rekursif tetapi dapat membuat batasan dan pesan kesalahan compiler lebih sulit dipahami, serta tidak menjamin terminasi algoritma. Batasi kompleksitas constraint, tambahkan pengujian compile-fail untuk metode yang hilang, dan sediakan alias tipe publik serta contoh yang jelas.

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