JavaRush /Java Blog /Random-ID /Analisis tanya jawab dari wawancara untuk pengembang Java...

Analisis tanya jawab dari wawancara untuk pengembang Java. Bagian 16

Dipublikasikan di grup Random-ID
Halo teman! Berapa lama untuk menjadi seorang pengembang? Saya bertanya kepada banyak orang berbeda dan mendengar banyak jawaban berbeda. Bagi sebagian orang, satu bulan saja mungkin cukup, namun bagi sebagian lainnya, satu tahun saja tidaklah cukup. Namun saya tahu pasti bahwa menjadi seorang pengembang Java adalah jalan yang sulit dan panjang, terlepas dari kemampuan awal Anda. Lagi pula, yang penting bukanlah kemampuan, melainkan kekeraskepalaan dan kerja keras. Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 1Oleh karena itu, hari ini kami terus menganalisis pertanyaan wawancara paling populer untuk pengembang Java. Mempelajarinya secara bertahap akan membawa Anda lebih dekat ke tujuan yang Anda hargai. Mari kita mulai!

17. Berikan contoh keberhasilan dan kegagalan penggunaan Opsional

Misalkan kita memiliki serangkaian nilai tertentu yang melaluinya kita melewati aliran tersebut, dan pada akhirnya kita mendapatkan beberapa Opsional sebagai hasilnya:
Optional<String> stringOptional = Stream.of("a", "ab", "abc", "abcd")
   .filter(str -> str.length() >= 3)
   .findAny();
Kita, seperti yang diharapkan, perlu mendapatkan nilai dari Optional ini . Hanya menggunakan get() adalah cara yang buruk:
String result = stringOptional.get();
Tapi metode ini seharusnya mendapatkan nilai dari Opsional dan mengembalikannya kepada kami? Tentu saja ini benar, tetapi jika itu ada artinya. Nah, jika nilai dalam aliran berbeda, dan pada akhirnya kita menerima Optional kosong , ketika kita mencoba mengambil nilai darinya menggunakan metode get() , yang berikut akan muncul: Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 2Mana yang tidak bagus. Dalam hal ini, lebih baik menggunakan konstruksi berikut:
  1. String result = null;
    if (stringOptional.isPresent()) {
     stringOptional.get();
    }

    Dalam hal ini, kami memeriksa untuk melihat apakah elemen tersebut ada di Optional . Jika tidak, string yang dihasilkan memiliki nilai lama.

  2. String result = stringOptional.orElse("default value");

    Dalam hal ini, kami menentukan beberapa nilai default, yang akan diberikan ke string yang dihasilkan jika Optional kosong .

  3. String result = stringOptional.orElseThrow(() -> new CustomException());

    Dalam hal ini, kami sendiri memberikan pengecualian ketika Optional kosong .

Hal ini dapat memudahkan dalam aplikasi ketika, misalnya, metode Spring JPA digunakan - findById() , yang mengembalikan nilai Opsional . Dalam hal ini, dengan metode ini kami mencoba mengambil nilainya, dan jika tidak ada, kami membuang beberapa pengecualian Runtime , yang diproses di tingkat pengontrol menggunakan ExceptionHandler dan diubah menjadi respons HTTP dengan status 404 - NOT FOUND . Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 3

18. Apakah mungkin untuk mendeklarasikan metode utama sebagai metode final?

Ya, tentu saja, tidak ada yang menghalangi kami untuk mendeklarasikan metode main() sebagai final . Kompiler tidak akan menghasilkan kesalahan. Namun perlu diingat bahwa metode apa pun setelah dinyatakan final akan menjadi metode terakhir - tidak ditimpa. Meskipun demikian, siapa yang akan mendefinisikan ulang main ??? Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 4

19. Apakah mungkin mengimpor paket/kelas yang sama dua kali? Apa konsekuensinya?

Ya kamu bisa. Konsekuensi? Kami akan memiliki beberapa impor yang tidak perlu yang akan ditampilkan Intelijj IDEA sebagai abu-abu, yaitu. tidak terpakai. Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 5Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 6

20. Apa itu Transmisi? Kapan kita bisa mendapatkan ClassCastException?

Casting, atau type casting , adalah proses mengubah satu tipe data ke tipe data lain: secara manual (casting implisit) atau otomatis (casting tipe eksplisit). Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 7Konversi otomatis dilakukan oleh kompiler, dan konversi manual dilakukan oleh pengembang. Jenis casting untuk primitif dan kelas agak berbeda, jadi kami akan mempertimbangkannya secara terpisah. Tipe primitif Contoh casting otomatis tipe primitif:
int value = 17;
double convertedValue = value;
Seperti yang Anda lihat, tidak diperlukan manipulasi tambahan selain tanda = di sini. Contoh casting manual tipe primitif:
double value = 17.89;
int convertedValue = (int)value;
Dalam hal ini, kita dapat mengamati cast manual, yang diimplementasikan menggunakan (int) , di mana bagian setelah koma akan dibuang dan convertValue akan memiliki nilai - 17. Baca lebih lanjut tentang casting tipe primitif di artikel ini . Nah, sekarang mari beralih ke objek. Tipe referensi Untuk tipe referensi, transmisi otomatis dimungkinkan untuk kelas turunan ke kelas induk. Ini juga disebut polimorfisme . Katakanlah kita memiliki kelas Lion yang mewarisi dari kelas Cat . Dalam hal ini, konversi otomatis akan terlihat seperti ini:
Cat cat = new Lion();
Tetapi dengan pemeran eksplisit , semuanya menjadi lebih rumit, karena tidak ada fungsi untuk memotong kelebihan, seperti pada primitif. Dan hanya melakukan konversi eksplisit dari bentuk:
Lion lion= (Lion)new Cat();
Anda akan mendapatkan kesalahan: Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 8Faktanya, Anda dapat menambahkan metode ke kelas turunan Lion yang awalnya tidak ada di kelas Cat , lalu mencoba memanggilnya karena tipe objek Anda akan menjadi Lion . Ya, tidak ada logika dalam hal ini. Oleh karena itu, penyempitan tipe hanya mungkin terjadi ketika objek aslinya bertipe Lion tetapi kemudian dimasukkan ke kelas induk:
Lion lion = new Lion();
Cat cat = lion;
Lion newLion = (Lion)cat;
Selain itu, untuk keandalan yang lebih baik, direkomendasikan untuk mempersempit objek menggunakan konstruksi instanceOf :
if (cat instanceof Lion) {
 newLion = (Lion)new Cat();
}
Baca lebih lanjut tentang tipe referensi gips di artikel ini . .

21. Mengapa kerangka kerja modern hanya menggunakan pengecualian yang tidak dicentang?

Saya rasa ini semua karena penanganan pengecualian yang dicentang masih berupa kode spageti yang diulangi di mana-mana, tetapi tidak terlalu diperlukan di semua kasus. Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 9Dalam kasus seperti itu, lebih mudah untuk melakukan pemrosesan di dalam kerangka kerja, agar tidak sekali lagi mengalihkan tanggung jawab ini ke pundak pengembang. Ya, tentu saja, situasi darurat mungkin muncul, tetapi pengecualian yang tidak dicentang ini dapat ditangani dengan cara yang lebih mudah, tanpa mengganggu pemrosesan dalam try-catch dan tanpa meneruskannya lebih jauh melalui metode. Cukup dengan mengubah pengecualian menjadi beberapa respons HTTP di pengecualianHandler .

22. Apa yang dimaksud dengan impor statis?

Saat menggunakan data statis (metode, variabel), Anda tidak dapat membuat objek itu sendiri, tetapi melakukannya dengan nama kelas, tetapi meskipun demikian kita memerlukan referensi ke kelas tersebut. Semuanya sederhana dengan itu: ditambahkan menggunakan impor biasa. Tetapi bagaimana jika kita menggunakan metode statis tanpa menulis nama kelas, seolah-olah itu adalah metode statis dari kelas saat ini? Hal ini dimungkinkan dengan impor statis! Dalam hal ini, kita harus menulis impor statis dan link ke metode tersebut. Seperti ini misalnya metode statis kelas Math untuk menghitung nilai kosinus:
import static java.lang.Math.cos;
Hasilnya, kita dapat menggunakan metode ini tanpa menentukan nama kelas:
double result = cos(60);
Kita juga dapat memuat semua metode statis suatu kelas sekaligus menggunakan impor statis:
import static java.lang.Math.*;
Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 10

23. Apa hubungan antara metode hashCode() dan sama dengan()?

Menurut Oracle , aturannya adalah: Jika dua objek sama (yaitu metode sama dengan() mengembalikan true ), keduanya harus memiliki kode hash yang sama. Pada saat yang sama, jangan lupa bahwa dua objek berbeda mungkin memiliki kode hash yang sama. Untuk memahami mengapa sama dengan() dan kode hash() selalu diganti secara berpasangan, pertimbangkan kasus berikut:
  1. Kedua metode tersebut ditimpa.

    Dalam hal ini, dua objek berbeda dengan status internal yang sama akan mengembalikan equal() - true , sedangkan hashCode() keduanya akan mengembalikan angka yang sama.

    Ternyata semuanya baik-baik saja, karena aturannya dipatuhi.

  2. Kedua metode tersebut tidak dapat dikesampingkan.

    Dalam hal ini, dua objek berbeda dengan status internal yang sama akan mengembalikan false ketika sama dengan() , karena perbandingannya dilakukan dengan referensi melalui operator == .

    Metode hashCode() juga akan mengembalikan nilai yang berbeda (kemungkinan besar) karena menghasilkan nilai konversi dari alamat lokasi memori. Namun untuk objek yang sama nilainya akan sama, seperti halnya sama dengan() dalam hal ini akan mengembalikan nilai true hanya ketika referensi menunjuk ke objek yang sama.

    Ternyata dalam hal ini semuanya baik-baik saja dan aturannya terpenuhi.

  3. Diganti sama dengan() , bukan ditimpa hashCode() .

    Dalam hal ini, untuk dua objek berbeda dengan status internal yang sama, equal() akan mengembalikan true , dan hashCode() (kemungkinan besar) akan mengembalikan nilai yang berbeda.

    Ini merupakan pelanggaran aturan, jadi tidak disarankan untuk melakukan hal ini.

  4. sama dengan() tidak diganti , kode hash() diganti .

    Dalam hal ini, untuk dua objek berbeda dengan status internal yang sama, sama dengan() akan mengembalikan false dan hashCode() akan mengembalikan nilai yang sama.

    Ada pelanggaran aturan, sehingga pendekatannya salah.

Seperti yang Anda lihat, aturan hanya dapat dijalankan ketika sama dengan() dan hashCode() keduanya diganti atau keduanya tidak diganti sama sekali. Baca Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 11lebih lanjut tentang equal() dan hashCode() di artikel ini .

24. Kapan kelas BufferedInputStream dan BufferedOutputStream digunakan?

InputStream digunakan untuk membaca data byte demi byte dari beberapa sumber daya, dan OutputStream digunakan untuk menulis data byte demi byte. Namun operasi byte-byte bisa sangat merepotkan dan memerlukan pemrosesan tambahan (agar dapat membaca/menulis teks secara normal). Sebenarnya, untuk menyederhanakan catatan byte tersebut, BufferedOutputStream diperkenalkan , dan BufferedInputStream diperkenalkan untuk membaca . Kelas-kelas ini tidak lebih dari buffer yang mengumpulkan data, memungkinkan Anda bekerja dengan data bukan byte demi byte, tetapi seluruh paket data (array). Saat dibuat, BufferedInputStream memasukkan ke dalam konstruktornya sebuah instance dari tipe InputStream , dari mana data dibaca:
BufferedInputStream bufferedInputStream = new BufferedInputStream(System.in);
byte[] arr = new byte[100];
bufferedInputStream.read(arr);
System.in adalah objek InputStream yang membaca data dari konsol. Artinya, dengan menggunakan objek BufferedInputStream ini , kita dapat membaca data dari InputStream dengan menuliskannya ke array yang diteruskan. Ini ternyata menjadi semacam pembungkus kelas InputStream . Array arr dari contoh ini adalah array yang menerima data dari BufferedInputStream . Itu, pada gilirannya, membaca data dari InputStream dengan array lain, yang secara default berukuran 2048 byte. Hal yang sama berlaku untuk BufferedOutputStream : sebuah instance dari tipe OutputStream harus diteruskan ke konstruktor , ke mana kita akan menulis data di seluruh array:
byte[] arr = "Hello world!!!".getBytes();
BufferedOutputStream bufferedInputStream = new BufferedOutputStream(System.out);
bufferedInputStream.write(arr);
bufferedInputStream.flush();
System.out adalah objek OutputStream yang menulis data ke konsol. Metode flush() mengirimkan data dari BufferedOutputStream ke OutputStream , membuang BufferedOutputStream dalam prosesnya . Tanpa metode ini, tidak ada yang akan direkam. Dan mirip dengan contoh sebelumnya: arr adalah array tempat data ditulis ke BufferedOutputStream . Dari sana mereka ditulis ke OutputStream dalam array berbeda, yang secara default berukuran 512 byte. Baca lebih lanjut tentang kedua kelas ini di artikel .

25. Apa perbedaan antara kelas java.util.Collection dan java.util.Collections?

Koleksi adalah antarmuka yang merupakan kepala hierarki koleksi. Ini memperkenalkan kelas yang memungkinkan Anda membuat, memuat, dan memodifikasi seluruh kelompok objek. Ada banyak metode yang disediakan untuk ini, seperti add() , hapus() , berisi() dan lain-lain. Antarmuka utama kelas Koleksi :
  • Himpunan adalah antarmuka yang mendeskripsikan himpunan yang berisi elemen unik yang tidak berurutan (tidak berulang).

  • Daftar adalah antarmuka yang menggambarkan struktur data yang menyimpan urutan objek yang diurutkan. Objek-objek ini menerima indeks (angka) mereka sendiri, yang dengannya Anda dapat berinteraksi dengannya: mengambil, menghapus, mengubah, menimpa.

  • Antrian merupakan antarmuka yang menggambarkan suatu struktur data dengan elemen penyimpanan berupa antrian yang mengikuti aturan - FIFO - First In First Out .

Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 12Baca lebih lanjut tentang Koleksi . Koleksi adalah kelas utilitas yang menyediakan banyak metode utilitas berbeda. Misalnya:
  • addAll(Collection<? super T> collection, T...element) - menambahkan elemen tipe T yang diteruskan ke collection .

  • copy(List<? super T> dest, List<? extends T> src) - menyalin semua elemen dari daftar src ke daftar di dest .

  • blankList() - mengembalikan daftar kosong.

  • max(Collection<? extends T> collection, Comparator<? super T> comp) - Mengembalikan elemen maksimum dari koleksi tertentu sesuai dengan urutan yang ditentukan oleh komparator yang ditentukan.

  • unmodifiedList(List<? extends T> list) - mengembalikan representasi daftar yang diteruskan yang tidak dapat dimodifikasi.

Dan ada banyak sekali metode yang mudah digunakan di Collections . Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 13Daftar lengkap metode ini dapat ditemukan di situs Oracle . Bukan tanpa alasan saya mengatakan bahwa mereka nyaman. Bagaimanapun, semuanya statis. Artinya, Anda tidak perlu membuat objek kelas ini setiap saat untuk memanggil metode yang diperlukan di dalamnya. Anda hanya perlu memasukkan nama kelas, memanggil metode yang diinginkan dan meneruskan semua argumen yang diperlukan. Ringkasnya, Collection adalah antarmuka root dari kerangka koleksi. Koleksi adalah kelas pembantu untuk pemrosesan objek milik suatu tipe dari struktur koleksi dengan lebih mudah. Baiklah, itu saja untuk hari ini. Semua yang terbaik!Analisis tanya jawab dari wawancara untuk pengembang Java.  Bagian 16 - 14
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION