Topik wawancara representatif

Wawancara coding: Kapan sebaiknya Anda menggunakan file sumber kompak (compact source files) Java 25?

CodingSedang
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Setelah melakukan upgrade ke Java 25, sebuah tim ingin menggunakan file sumber kompak (compact source files) untuk utilitas kecil. Jelaskan pemilihan titik masuk (entry point), anggota dari kelas yang dideklarasikan secara implisit, batasan impor otomatis, dan bagaimana Anda memutuskan apakah akan mengadopsi fitur ini di produksi.

Pertanyaan dan ruang lingkup

Setelah melakukan upgrade ke Java 25, sebuah tim ingin menggunakan file sumber kompak (compact source files) untuk utilitas kecil. Jelaskan pemilihan titik masuk (entry point), anggota dari kelas yang dideklarasikan secara implisit, batasan impor otomatis, dan bagaimana Anda memutuskan apakah akan mengadopsi fitur ini di produksi.

JEP 512 memfinalisasi Compact Source Files dan Instance Main Methods setelah rilis preview. Sebuah file dapat menghilangkan deklarasi kelas tingkat atas (top-level class); field, method, dan deklarasi bersarang (nested) tingkat atas menjadi anggota dari kelas yang dideklarasikan secara implisit, sementara launcher tetap mengikuti protokol yang ditentukan untuk menemukan method main yang dapat dijalankan.

Hal yang diuji oleh pewawancara

Mencakup model kelas yang sebenarnya di balik language sugar ini, perbedaan antara titik masuk tanpa argumen dan argumen-array, impor on-demand java.base dan batasan IO, perintah kompilasi dan eksekusi, batasan dokumentasi dan debugging, serta strategi adopsi bertahap.

Jawaban 30 detik

"Saya akan memosisikan fitur ini sebagai pengurangan boilerplate untuk skrip satu file, contoh pembelajaran, dan perkakas sekali pakai. Kompiler secara implisit mendeklarasikan kelas yang memperluas Object; anggota tingkat atas menjadi anggotanya. Launcher pertama-tama memilih void main(String[]) yang dapat diakses, dan jika tidak ada, memilih void main() yang dapat diakses; titik masuk instance dipanggil setelah konstruktor default berjalan. Java 25 mengimpor tipe tingkat atas publik yang diekspor oleh java.base sesuai kebutuhan (on demand), tetapi static method IO tidak diimpor secara implisit. Saya akan tetap menggunakan kelas eksplisit untuk pustaka publik dan layanan kompleks, dengan memvalidasi JDK target, build tools, dan pipeline dokumentasi terlebih dahulu."

Solusi langkah demi langkah

Langkah 1: Mengidentifikasi kelas yang dideklarasikan secara implisit

File sumber tanpa deklarasi kelas pembungkus mendeklarasikan kelas secara implisit. Kelas ini memperluas Object, memiliki konstruktor default tanpa argumen, dan menerima nama yang dipilih oleh host yang tidak dapat dirujuk langsung oleh kode sumber lain. Field, method, dan deklarasi bersarang di dalam file tersebut menjadi anggota dari kelas tersebut.

Langkah 2: Menentukan titik masuk yang dapat dijalankan

Launcher pertama-tama mencari void main yang dapat diakses dengan parameter array-String. Jika tidak ada, launcher akan mencari void main yang dapat diakses tanpa parameter. Ketika method yang dipilih adalah instance method, launcher membuat instance dari kelas implisit sebelum memanggilnya.

java
void main(String[] args) {
    IO.println("hello " + args[0]);
}

Langkah 3: Memahami impor otomatis

File sumber kompak bertindak seolah-olah mengimpor tipe tingkat atas publik yang diekspor oleh java.base secara on demand, sehingga tipe seperti Map dan Stream biasanya tidak memerlukan impor eksplisit. Ini tidak mengimpor modul arbitrer, dan static method IO tidak diimpor secara implisit; panggil IO.println atau tambahkan static import eksplisit.

Langkah 4: Membedakan mode run dan compile

Anda dapat menjalankan java Hello.java, yang memungkinkan launcher mengompilasi dan mengeksekusi file tersebut, atau menjalankan javac Hello.java diikuti oleh kelas yang dihasilkan. Eksekusi sumber langsung sangat nyaman untuk skrip pendek; build yang dapat diulang (repeatable builds), caching, dan pipeline rilis sebaiknya tetap mengompilasi secara eksplisit ke dalam direktori output yang telah ditentukan.

Langkah 5: Menganalisis status dan siklus hidup

Field tingkat atas menjadi field dari kelas implisit, sehingga instance main dapat membaca status instance. Launcher menggunakan konstruktor default, sehingga injeksi argumen konstruktor eksternal bukan bagian dari protokol ini. Inisialisasi kompleks, beberapa titik masuk, atau siklus hidup eksplisit lebih mudah ditinjau dalam kelas yang bernama.

Langkah 6: Mengevaluasi batasan perkakas

Kelas yang dideklarasikan secara implisit tidak memiliki nama tingkat sumber yang stabil untuk dirujuk oleh kelas lain, dan javadoc tidak dapat menghasilkan API konvensional untuknya. IDE, penganalisis statis, alat cakupan kode (coverage tools), dan debugger mungkin mendukung sintaksis ini pada versi yang berbeda; validasi JDK target dan plugin build secara bersamaan.

Langkah 7: Merancang migrasi dan rollback

Pindahkan skrip atau contoh pembelajaran ke direktori terpisah terlebih dahulu dan simpan versi kelas eksplisit sebagai rollback. Kunci versi Java 25 di CI, pastikan versi java dan javac cocok, dan verifikasi bahwa pengemasan (packaging), log, trace pengecualian, dan perintah kontainer tidak bergantung pada nama kelas implementasi.

Langkah 8: Menentukan batasan adopsi

Adopsi bergantung pada apakah kode memerlukan API yang stabil, dependency injection, titik masuk yang dapat diamati, atau penggunaan kembali lintas modul. Alat operasi satu file dapat menjadi lebih jelas dengan upacara kode yang lebih sedikit; pustaka bersama, layanan yang berjalan lama, atau API yang terdokumentasi biasanya lebih diuntungkan dengan kelas eksplisit.

Pertimbangan dan batasan

Kesederhanaan atau kemudahan penemuan (discoverability)

File kompak menjaga contoh untuk pemula tetap dekat dengan tujuannya, tetapi nama implisit dan aturan impor meningkatkan jumlah pengetahuan perkakas yang diperlukan. Batasi fitur ini pada direktori dengan kopling rendah dan dokumentasikan batasan tersebut dalam standar pengodean.

Instance main atau static main

Instance main dapat langsung menggunakan field dan instance method, yang cocok untuk demonstrasi berstatus (stateful). Static main mengikuti jalur peluncuran Java tradisional secara lebih dekat. Apa pun pilihannya, jaga agar signature titik masuk tidak ambigu sehingga launcher tidak melaporkan beberapa kandidat.

Impor otomatis atau impor eksplisit

Aturan on-demand java.base menghilangkan impor dari kode pembelajaran, tetapi tipe dari modul lain tetap memerlukan modul eksplisit atau impor biasa. Kode produksi bersama sebaiknya menyatakan dependensi secara jelas daripada mengandalkan pembaca untuk mengingat aturan implisit.

Latihan kegagalan dan evolusi

Beberapa kandidat main

Tambahkan titik masuk tanpa argumen dan titik masuk array-String, lalu verifikasi bahwa bentuk array yang dipilih. Ubah tipe kembalian atau visibilitas, lalu verifikasi perilaku kesalahan dan fallback dari launcher.

Bergantung pada nama kelas implisit

Buat file sumber kedua merujuk ke nama kelas yang dihasilkan, konfirmasikan bahwa kompilasi gagal, dan pindahkan logika bersama ke dalam kelas yang dinamai secara eksplisit.

Rantai perkakas (toolchain) yang tidak konsisten

Kompilasi file yang sama dengan JDK yang lebih lama dan Java 25. CI harus langsung gagal pada ketidakcocokan tingkat bahasa alih-alih menunda kegagalan sintaksis ke runtime.

Kesalahan umum dan tindak lanjut

Kesalahan 1: Menganggap file tersebut tidak memiliki kelas

Tindak lanjut: Di mana method dan field tingkat atas berada? Mereka adalah anggota dari kelas implisit yang dihasilkan kompiler dan tetap mengikuti aturan anggota serta siklus hidup instance.

Kesalahan 2: Menganggap semua impor bersifat otomatis

Tindak lanjut: Mengapa IO.println harus menyebutkan nama kelasnya? Static method IO tidak diimpor secara implisit; tipe tingkat atas publik java.base diimpor secara on demand.

Kesalahan 3: Memperlakukan sintaksis skrip sebagai API yang stabil

Tindak lanjut: Dapatkah modul lain bergantung pada kelas implisit? Modul lain tidak dapat bergantung pada nama implementasi; API yang dapat digunakan kembali harus berada dalam kelas yang dinamai secara eksplisit.

Tindak lanjut lebih mendalam dan contoh jawaban

Mengapa instance main memerlukan konstruktor default?

Setelah memilih titik masuk instance, launcher menginstansiasi kelas yang dideklarasikan secara implisit lalu memanggil method tersebut. File kompak tidak memiliki protokol argumen konstruktor, sehingga injeksi eksternal memerlukan kelas eksplisit.

Apa perbedaan eksekusi sumber langsung dengan kompilasi terlebih dahulu?

Eksekusi langsung memungkinkan launcher java mengompilasi secara sementara dan menjalankan sumbernya, yang cocok untuk skrip pendek. Mengompilasi dengan javac terlebih dahulu memberikan artefak yang stabil, caching, dan diagnostik untuk CI dan sistem rilis.

Kapan Anda harus kembali ke kelas eksplisit?

Gunakan kelas bernama yang eksplisit saat Anda memerlukan nama tipe yang stabil, API publik, javadoc, dependency injection, beberapa jalur konstruksi, atau penggunaan kembali lintas modul, meskipun bentuk satu file memiliki lebih banyak boilerplate.

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