JavaRush /Blog Java /Random-MS /Analisis soalan dan jawapan daripada temu bual untuk pemb...

Analisis soalan dan jawapan daripada temu bual untuk pembangun Java. Bahagian 16

Diterbitkan dalam kumpulan
Hai kawan! Berapa lama masa yang diperlukan untuk menjadi pemaju? Saya bertanya kepada banyak orang yang berbeza dan mendengar banyak jawapan yang berbeza. Bagi sesetengah orang walaupun sebulan mungkin cukup, tetapi bagi orang lain walaupun setahun tidak akan mencukupi. Tetapi saya tahu pasti bahawa menjadi pembangun Java adalah jalan yang berduri dan panjang, tanpa mengira kebolehan awal anda. Lagipun, bukan kebolehan yang penting seperti kedegilan dan kerja keras. Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 1Oleh itu, hari ini kami terus menganalisis soalan temu bual yang paling popular untuk pembangun Java. Mempelajarinya secara beransur-ansur akan membawa anda lebih dekat kepada matlamat yang anda sayangi. Mari kita mulakan!

17. Berikan contoh penggunaan Optional yang berjaya dan tidak berjaya

Katakan kita mempunyai siri nilai tertentu yang melaluinya kita melalui aliran, dan pada akhirnya kita mendapat beberapa Pilihan sebagai hasilnya:
Optional<String> stringOptional = Stream.of("a", "ab", "abc", "abcd")
   .filter(str -> str.length() >= 3)
   .findAny();
Kami, seperti yang dijangkakan, perlu mendapatkan nilai daripada Pilihan ini . Hanya menggunakan get() adalah cara yang tidak baik:
String result = stringOptional.get();
Tetapi kaedah ini sepatutnya mendapatkan nilai daripada Pilihan dan mengembalikannya kepada kami? Ini, sudah tentu, benar, tetapi jika ia mempunyai makna. Nah, jika nilai dalam aliran berbeza, dan pada akhirnya kami menerima Optional kosong , apabila kami cuba mengambil nilai daripadanya menggunakan kaedah get() , perkara berikut akan dilemparkan: Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 2Mana yang tidak bagus. Dalam kes ini, lebih baik menggunakan pembinaan berikut:
  1. String result = null;
    if (stringOptional.isPresent()) {
     stringOptional.get();
    }

    Dalam kes ini, kami menyemak untuk melihat sama ada elemen berada dalam Pilihan . Jika tidak, rentetan yang terhasil mempunyai nilai lamanya.

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

    Dalam kes ini, kami menentukan beberapa nilai lalai, yang akan diberikan kepada rentetan yang terhasil dalam kes Pilihan kosong .

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

    Dalam kes ini, kami sendiri membuang pengecualian apabila Pilihan kosong .

Ini boleh menjadi mudah dalam aplikasi apabila, sebagai contoh, kaedah Spring JPA digunakan - findById() , yang mengembalikan nilai Pilihan . Dalam kes ini, dengan kaedah ini kami cuba mengambil nilai, dan jika ia tidak ada, kami membuang beberapa pengecualian Runtime , yang diproses pada tahap pengawal menggunakan ExceptionHandler dan ditukar kepada respons HTTP dengan status 404 - NOT FUND . Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 3

18. Adakah mungkin untuk mengisytiharkan kaedah utama sebagai muktamad?

Ya, sudah tentu, tiada apa yang menghalang kami daripada mengisytiharkan kaedah main() sebagai final . Pengkompil tidak akan menghasilkan ralat. Tetapi perlu diingat bahawa mana-mana kaedah selepas mengisytiharkannya sebagai muktamad akan menjadi kaedah terakhir - tidak ditindih. Walaupun, siapa yang akan mentakrifkan semula utama ??? Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 4

19. Adakah mungkin untuk mengimport pakej/kelas yang sama dua kali? Apakah akibatnya?

Ya awak boleh. Akibat? Kami akan mempunyai beberapa import yang tidak perlu yang Intelijj IDEA akan dipaparkan sebagai kelabu, i.e. tidak digunakan. Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 5Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 6

20. Apakah Casting? Bilakah kita boleh mendapatkan ClassCastException?

Penghantaran, atau hantaran jenis , ialah proses menukar satu jenis data kepada jenis data yang lain: secara manual (penghantaran tersirat) atau secara automatik (penghantaran jenis eksplisit). Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 7Penukaran automatik dilakukan oleh pengkompil, dan penukaran manual dilakukan oleh pembangun. Jenis tuangan untuk primitif dan kelas agak berbeza, jadi kami akan mempertimbangkannya secara berasingan. Jenis primitif Contoh pemutus automatik jenis primitif:
int value = 17;
double convertedValue = value;
Seperti yang anda lihat, tiada manipulasi tambahan selain tanda = diperlukan di sini. Contoh pemutus manual jenis primitif:
double value = 17.89;
int convertedValue = (int)value;
Dalam kes ini, kita boleh melihat cast manual, yang dilaksanakan menggunakan (int) , di mana bahagian selepas koma akan dibuang dan convertedValue akan mempunyai nilai - 17. Baca lebih lanjut tentang menghantar jenis primitif dalam artikel ini . Nah, sekarang mari kita beralih kepada objek. Jenis rujukan Untuk jenis rujukan, penghantaran automatik boleh dilakukan untuk kelas turunan kepada kelas induk. Ini juga dipanggil polimorfisme . Katakan kita mempunyai kelas Singa yang mewarisi daripada kelas Cat . Dalam kes ini, penukaran automatik akan kelihatan seperti ini:
Cat cat = new Lion();
Tetapi dengan pelakon yang jelas , segala-galanya agak rumit, kerana tiada fungsi untuk memotong lebihan, seperti dengan primitif. Dan hanya melakukan penukaran eksplisit borang:
Lion lion= (Lion)new Cat();
Anda akan mendapat ralat: Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 8Malah, anda boleh menambah kaedah kepada kelas keturunan Singa yang pada asalnya bukan dalam kelas Cat , dan kemudian cuba memanggilnya, kerana jenis objek anda akan menjadi Lion . Nah, tidak ada logik dalam hal ini. Oleh itu, penyempitan jenis hanya boleh dilakukan apabila objek asal adalah jenis Lion tetapi kemudiannya dihantar ke kelas induk:
Lion lion = new Lion();
Cat cat = lion;
Lion newLion = (Lion)cat;
Juga, untuk kebolehpercayaan yang lebih tinggi, pelakon penyempitan untuk objek disyorkan menggunakan instanceOf construct :
if (cat instanceof Lion) {
 newLion = (Lion)new Cat();
}
Baca lebih lanjut tentang hantaran jenis rujukan dalam artikel ini .

21. Mengapakah rangka kerja moden hanya menggunakan pengecualian yang tidak disemak sahaja?

Saya rasa ini semua kerana pengendalian pengecualian yang diperiksa masih merupakan kod spageti yang diulang di mana-mana, tetapi tidak benar-benar diperlukan dalam semua kes. Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 9Dalam kes sedemikian, lebih mudah untuk melakukan pemprosesan di dalam rangka kerja, supaya tidak sekali lagi mengalihkannya ke bahu pemaju. Ya, sudah tentu, situasi kecemasan mungkin timbul, tetapi pengecualian yang tidak disemak yang sama ini boleh dikendalikan dengan cara yang lebih mudah, tanpa mengganggu pemprosesan dalam tangkapan cuba dan tanpa meneruskannya lagi melalui kaedah. Cukup sekadar menukar pengecualian kepada beberapa respons HTTP dalam exceptionHandler .

22. Apakah import statik?

Apabila menggunakan data statik (kaedah, pembolehubah), anda tidak boleh mencipta objek itu sendiri, tetapi melakukannya dengan nama kelas, tetapi dalam kes ini kita memerlukan rujukan kepada kelas. Semuanya mudah dengannya: ia ditambah menggunakan import biasa. Tetapi bagaimana jika kita menggunakan kaedah statik tanpa menulis nama kelas, seolah-olah ia adalah kaedah statik kelas semasa? Ini boleh dilakukan dengan import statik! Dalam kes ini, kita mesti menulis import statik dan pautan ke kaedah itu. Seperti ini, sebagai contoh, kaedah statik kelas Matematik untuk mengira nilai kosinus:
import static java.lang.Math.cos;
Akibatnya, kita boleh menggunakan kaedah tanpa menyatakan nama kelas:
double result = cos(60);
Kami juga boleh memuatkan semua kaedah statik kelas sekaligus menggunakan import statik:
import static java.lang.Math.*;
Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 10

23. Apakah hubungan antara kaedah hashCode() dan equals()?

Menurut Oracle , peraturannya ialah: Jika dua objek adalah sama (iaitu kaedah equals() mengembalikan true ), ia mesti mempunyai kod cincang yang sama. Pada masa yang sama, jangan lupa bahawa dua objek berbeza boleh mempunyai kod cincang yang sama. Untuk memahami sebab equals() dan hashCode() sentiasa ditindih secara berpasangan, pertimbangkan kes berikut:
  1. Kedua-dua kaedah ditindih.

    Dalam kes ini, dua objek berbeza dengan keadaan dalaman yang sama akan mengembalikan equals() - true , manakala hashCode() akan mengembalikan nombor yang sama.

    Ternyata semuanya baik-baik saja, kerana peraturan itu dipatuhi.

  2. Kedua-dua kaedah tidak ditindih.

    Dalam kes ini, dua objek berbeza dengan keadaan dalaman yang sama akan mengembalikan false apabila equals() , kerana perbandingan adalah melalui rujukan melalui operator == .

    Kaedah hashCode() juga akan mengembalikan nilai yang berbeza (kemungkinan besar) kerana ia menghasilkan nilai ditukar alamat lokasi memori. Tetapi untuk objek yang sama nilai ini akan sama, sama seperti equals() dalam kes ini akan kembali benar hanya apabila rujukan menunjuk ke objek yang sama.

    Ternyata dalam kes ini semuanya ok dan peraturannya dipenuhi.

  3. Overridden equals() , bukan overridden hashCode() .

    Dalam kes ini, untuk dua objek berbeza dengan keadaan dalaman yang sama, equals() akan mengembalikan true , dan hashCode() akan mengembalikan (kemungkinan besar) nilai yang berbeza.

    Ini adalah pelanggaran peraturan, jadi tidak disyorkan untuk melakukan ini.

  4. equals() is not overridden , hashCode() is overridden .

    Dalam kes ini, untuk dua objek berbeza dengan keadaan dalaman yang sama, equals() akan mengembalikan false dan hashCode() akan mengembalikan nilai yang sama.

    Terdapat pelanggaran peraturan, jadi pendekatannya tidak betul.

Seperti yang anda lihat, peraturan hanya boleh dilaksanakan apabila equals() dan hashCode() kedua-duanya ditindih atau kedua-duanya tidak ditindih sama sekali. Baca Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 11lebih lanjut mengenai equals() dan hashCode() dalam artikel ini .

24. Bilakah kelas BufferedInputStream dan BufferedOutputStream digunakan?

InputStream digunakan untuk membaca bait demi bait data daripada beberapa sumber, dan OutputStream digunakan untuk menulis bait-bait data. Tetapi operasi bait demi bait boleh menjadi sangat menyusahkan dan memerlukan pemprosesan tambahan (untuk membaca/menulis teks seperti biasa). Sebenarnya, untuk memudahkan rekod bait tersebut, BufferedOutputStream telah diperkenalkan dan BufferedInputStream telah diperkenalkan untuk membaca . Kelas ini tidak lebih daripada penimbal yang mengumpul data, membolehkan anda bekerja dengan data bukan bait demi bait, tetapi dengan keseluruhan paket data (tatasusunan). Apabila dibuat, BufferedInputStream mengambil ke dalam pembinanya satu contoh jenis InputStream , dari mana data dibaca:
BufferedInputStream bufferedInputStream = new BufferedInputStream(System.in);
byte[] arr = new byte[100];
bufferedInputStream.read(arr);
System.in ialah objek InputStream yang membaca data daripada konsol. Iaitu, menggunakan objek BufferedInputStream ini , kita boleh membaca data daripada InputStream dengan menulisnya pada tatasusunan yang diluluskan. Ini ternyata sejenis pembungkus kelas InputStream . Tatasusunan arr daripada contoh ini ialah tatasusunan yang menerima data daripada BufferedInputStream . Itu, seterusnya, membaca data daripada InputStream dengan tatasusunan lain, yang secara lalai mempunyai saiz 2048 bait. Perkara yang sama berlaku untuk BufferedOutputStream : contoh jenis OutputStream mesti dihantar kepada constructor , di mana kami akan menulis data dalam keseluruhan tatasusunan:
byte[] arr = "Hello world!!!".getBytes();
BufferedOutputStream bufferedInputStream = new BufferedOutputStream(System.out);
bufferedInputStream.write(arr);
bufferedInputStream.flush();
System.out ialah objek OutputStream yang menulis data ke konsol. Kaedah flush() menghantar data daripada BufferedOutputStream ke OutputStream , membuang BufferedOutputStream dalam proses . Tanpa kaedah ini, tiada apa yang akan direkodkan. Dan serupa dengan contoh sebelumnya: arr ialah tatasusunan dari mana data ditulis ke BufferedOutputStream . Dari sana ia ditulis kepada OutputStream dalam tatasusunan yang berbeza, yang secara lalai mempunyai saiz 512 bait. Baca lebih lanjut mengenai dua kelas ini dalam artikel .

25. Apakah perbezaan antara kelas java.util.Collection dan java.util.Collections?

Koleksi ialah antara muka yang menjadi ketua hierarki koleksi. Ia memperkenalkan kelas yang membolehkan anda mencipta, mengandungi dan mengubah suai keseluruhan kumpulan objek. Terdapat banyak kaedah yang disediakan untuk ini, seperti add() , remove() , contains() dan lain-lain. Antara muka utama kelas Koleksi :
  • Set ialah antara muka yang menerangkan set yang mengandungi unsur unik (tidak berulang) tidak tertib.

  • Senarai ialah antara muka yang menerangkan struktur data yang menyimpan urutan objek yang tersusun. Objek ini menerima indeks (nombor) mereka sendiri, yang mana anda boleh berinteraksi dengannya: ambil, padam, tukar, tulis ganti.

  • Baris gilir ialah antara muka yang menerangkan struktur data dengan menyimpan elemen dalam bentuk baris gilir yang mengikut peraturan - FIFO - Mula-mula Masuk Dahulu Keluar .

Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 12Baca lebih lanjut mengenai Koleksi . Koleksi ialah kelas utiliti yang menyediakan banyak kaedah utiliti yang berbeza. Sebagai contoh:
  • addAll(Collection<? super T> collection, T...element) - menambah elemen lulus jenis T ke koleksi .

  • copy(List<? super T> dest, List<? extends T> src) - menyalin semua elemen daripada senarai src ke senarai dalam dest .

  • emptyList() - mengembalikan senarai kosong.

  • max(Collection<? extends T> collection, Comparator<? super T> comp) - Mengembalikan elemen maksimum koleksi yang diberikan mengikut susunan yang ditentukan oleh comparator yang ditentukan.

  • unmodifiableList(List<? extends T> list) - mengembalikan perwakilan yang tidak boleh diubahsuai bagi senarai yang diluluskan.

Dan terdapat banyak sekali pelbagai kaedah mudah sedemikian dalam Collections . Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 13Senarai lengkap kaedah ini boleh didapati di laman web Oracle . Ia bukan untuk apa-apa yang saya katakan bahawa mereka selesa. Lagipun, mereka semua statik. Iaitu, anda tidak perlu mencipta objek kelas ini setiap kali untuk memanggil kaedah yang diperlukan padanya. Anda hanya perlu memasukkan nama kelas, memanggil kaedah yang dikehendaki padanya dan lulus semua hujah yang diperlukan. Untuk meringkaskan, Koleksi ialah antara muka akar rangka kerja koleksi. Koleksi ialah kelas pembantu untuk pemprosesan objek yang lebih mudah milik jenis daripada struktur koleksi. Nah, itu sahaja untuk hari ini. Semua yang terbaik!Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 16 - 14
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION