JavaRush /Blog Java /Random-MS /Teras Java. Soalan untuk temuduga, bahagian 3
Vadim625
Tahap

Teras Java. Soalan untuk temuduga, bahagian 3

Diterbitkan dalam kumpulan
Dalam dua artikel sebelum ini, kami membincangkan beberapa soalan penting yang paling kerap ditanya kepada anda dalam temu bual. Sudah tiba masanya untuk meneruskan dan melihat soalan-soalan yang lain.
Teras Java.  Soalan temu bual, bahagian 3 - 1

Penyalinan mendalam dan penyalinan cetek

Salinan tepat yang asli ialah klonnya. Di Jawa, ini bermakna dapat mencipta objek dengan struktur yang serupa dengan objek asal. Kaedah ini clone()menyediakan fungsi ini. Penyalinan cetek maklumat sesedikit mungkin. Secara lalai, pengklonan dalam Java adalah cetek, i.e. Object classtidak tahu tentang struktur kelas yang ditirunya. Apabila mengklon, JVM melakukan perkara berikut:
  1. Jika kelas hanya mempunyai ahli jenis primitif, maka salinan objek yang sama sekali baru akan dibuat dan rujukan kepada objek itu akan dikembalikan.
  2. Jika kelas mengandungi bukan sahaja ahli jenis primitif, tetapi juga ahli mana-mana jenis kelas lain, maka rujukan kepada objek kelas ini akan disalin. Oleh itu, kedua-dua objek akan mempunyai rujukan yang sama.
Penyalinan mendalam menduplikasi segala-galanya. Penyalinan mendalam ialah dua koleksi, satu daripadanya menduplikasi semua elemen koleksi asal. Kami ingin membuat salinan supaya membuat perubahan pada mana-mana elemen salinan tidak akan menjejaskan koleksi asal. Pengklonan mendalam memerlukan peraturan berikut:
  1. Tidak perlu menyalin data primitif secara berasingan;
  2. Semua kelas ahli dalam kelas asal mesti menyokong pengklonan. Bagi setiap ahli kelas, mesti dipanggil super.clone()apabila kaedah ditindih clone();
  3. Jika mana-mana ahli kelas tidak menyokong pengklonan, maka dalam kaedah klon, anda perlu mencipta contoh baharu kelas itu dan menyalin setiap ahlinya dengan semua atribut ke objek kelas baharu, satu demi satu.
Ketahui lebih lanjut mengenai pengklonan di sini

Apakah penyegerakan? Penguncian peringkat objek dan penguncian peringkat kelas?

Penyegerakan merujuk kepada multithreading. Blok kod yang disegerakkan hanya boleh dilaksanakan oleh satu utas pada satu masa. Java membolehkan anda memproses berbilang benang secara serentak. Ini mungkin menyebabkan dua atau lebih utas ingin mengakses medan yang sama. Penyegerakan membantu mengelakkan ralat ingatan yang berlaku apabila sumber memori digunakan dengan tidak betul. Apabila kaedah diisytiharkan sebagai disegerakkan, benang memegang monitornya. Jika utas lain cuba mengakses kaedah yang disegerakkan pada masa ini, utas itu disekat dan menunggu monitor menjadi bebas. Penyegerakan dalam Java dicapai dengan kata kunci disegerakkan khas . Anda boleh menandakan blok atau kaedah individu dalam kelas anda dengan cara ini. Kata kunci yang disegerakkan tidak boleh digunakan bersama dengan pembolehubah kelas atau atribut. Penguncian peringkat objek ialah mekanisme apabila anda ingin menyegerakkan kaedah bukan statik atau blok kod bukan statik supaya hanya satu utas boleh melaksanakan blok kod pada contoh kelas tertentu. Ini hendaklah sentiasa dilakukan untuk memastikan urutan contoh kelas selamat. Penguncian peringkat kelas menghalang berbilang benang daripada memasuki blok yang disegerakkan untuk semua contoh kelas yang tersedia. Sebagai contoh, jika terdapat 100 kejadian kelas DemoClass, maka hanya 1 utas akan dapat melaksanakan demoMethod() menggunakan salah satu pembolehubah pada masa tertentu. Ini hendaklah sentiasa dilakukan untuk memastikan keselamatan benang statik. Ketahui lebih lanjut tentang penyegerakan di sini.

Apakah perbezaan antara sleep() dan wait()?

Sleep()adalah kaedah yang digunakan untuk menangguhkan proses selama beberapa saat. Dalam kes wait(), benang berada dalam keadaan menunggu sehingga kita memanggil kaedah notify()atau notifyAll(). Perbezaan utama ialah wait()ia melepaskan kunci monitor manakala ia sleep()tidak melepaskan kunci. Wait()digunakan untuk aplikasi berbilang benang, sleep()digunakan hanya untuk menjeda pelaksanaan benang. Thread.sleep()meletakkan utas semasa dalam keadaan "Tidak Boleh Dijalankan" untuk jangka masa tertentu. Benang menyimpan keadaan monitor yang sebelum kaedah ini dipanggil. Jika utas lain memanggil t.interrupt(), utas yang "tertidur" akan terjaga. Ambil perhatian bahawa ini sleep()ialah kaedah statik, bermakna ia sentiasa mempengaruhi utas semasa (yang melaksanakan kaedah sleep()). Kesilapan biasa ialah memanggil t.sleep()di mana tada benang lain; walaupun benang semasa yang memanggil kaedah itu sleep()bukan tbenang. Object.wait()menghantar benang semasa ke dalam keadaan "Tidak Boleh Dijalankan" untuk seketika, sama seperti sleep(), tetapi dengan sedikit nuansa. Wait()dipanggil pada objek, bukan benang; kami memanggil objek ini "objek kunci". Sebelum memanggil lock.wait(), benang semasa mesti disegerakkan dengan "objek kunci"; wait()selepas itu, ia melepaskan kunci ini, dan menambahkan utas pada "senarai tunggu" yang dikaitkan dengan kunci ini. Kemudian, benang lain boleh menyegerakkan dengan objek kunci yang sama dan memanggil lock.notify(). Kaedah ini akan "membangunkan" benang asal, yang masih menunggu. Pada dasarnya, wait()/ notify()boleh dibandingkan dengan sleep()/ interrupt(), hanya benang aktif tidak memerlukan penunjuk langsung ke benang tidur, ia hanya perlu mengetahui objek kunci yang dikongsi. Baca perbezaan terperinci di sini.

Adakah mungkin untuk memberikan null kepada ini kepada pembolehubah rujukan?

Tidak, awak tak boleh. Di Java, bahagian kiri pengendali tugasan mestilah pembolehubah. "Ini" ialah kata kunci khas yang sentiasa memberikan contoh semasa kelas. Ia bukan sebarang pembolehubah. Begitu juga, null tidak boleh diberikan kepada pembolehubah menggunakan kata kunci "super" atau mana-mana kata kunci serupa yang lain.

Apakah perbezaan antara && dan &?

&- bitwise dan &&- logik.
  1. &menilai kedua-dua belah operasi;
  2. &&menilai bahagian kiri operasi. Jika benar, ia terus menilai sebelah kanan.
Lihat di sini untuk pemahaman yang lebih mendalam.

Bagaimana untuk mengatasi kaedah equals() dan hachCode()?

hashCode()dan equals()kaedah ditakrifkan dalam class Object, iaitu kelas induk untuk objek Java. Atas sebab ini, semua objek Java mewarisi pelaksanaan lalai untuk kaedah. Kaedah ini hashCode()digunakan untuk mendapatkan integer unik untuk objek tertentu. Integer ini digunakan untuk menentukan lokasi objek apabila objek itu perlu disimpan, contohnya kepada HashTable. Secara lalai, hashCode()mengembalikan integerperwakilan alamat lokasi memori tempat objek disimpan. Kaedah equls(), seperti namanya, digunakan untuk menguji sama ada dua objek adalah sama. Pelaksanaan lalai menyemak rujukan objek untuk melihat sama ada ia sama. Berikut ialah garis panduan penting untuk memuat semula kaedah ini:
  1. Sentiasa gunakan atribut objek yang sama apabila menjana hashCode()dan equals();
  2. simetri. Itu. xjika ia mengembalikan true untuk beberapa objects y x.equals(y), maka ia y.equals(x)harus mengembalikan true;
  3. Reflekstiviti. Untuk mana-mana objek x x.equals(x)mesti kembali benar;
  4. Konsisten. Untuk sebarang objek xdan y x.equals(y)mengembalikan perkara yang sama jika maklumat yang digunakan dalam perbandingan tidak berubah;
  5. Transitiviti. Untuk sebarang objek x, ydan z, jika x.equals(y)ia mengembalikan benar dan y.equals(z)mengembalikan benar, maka ia x.equals(z)harus kembali benar;
  6. Setiap kali kaedah dipanggil pada objek yang sama semasa pelaksanaan aplikasi, ia harus mengembalikan nombor yang sama melainkan maklumat yang digunakan berubah. hashCodeboleh mengembalikan nilai yang berbeza untuk objek yang sama dalam keadaan aplikasi yang berbeza;
  7. Jika dua objek adalah sama, mengikut equals, maka ia hashCodemesti mengembalikan nilai yang sama;
  8. Keperluan yang bertentangan adalah pilihan. Dua objek yang tidak sama boleh mengembalikan hashCode yang sama. Walau bagaimanapun, untuk meningkatkan prestasi, adalah lebih baik untuk mempunyai objek yang berbeza mengembalikan kod yang berbeza.
Baca fakta menarik tentang kaedah ini di sini.

Beritahu kami tentang pengubah suai akses

Kelas, medan, pembina dan kaedah Java boleh mempunyai salah satu daripada empat pengubah akses berbeza: persendirian Jika kaedah atau pembolehubah ditandakan persendirian , maka hanya kod dalam kelas yang sama boleh mengakses pembolehubah atau memanggil kaedah tersebut. Kod di dalam subkelas tidak boleh mengakses pembolehubah atau kaedah, dan juga tidak boleh mengaksesnya dari mana-mana kelas lain. Pengubah suai akses peribadi paling kerap digunakan untuk pembina, kaedah dan pembolehubah. lalai Pengubahsuai capaian lalai diisytiharkan jika pengubahsuai tidak dinyatakan sama sekali. Pengubah suai ini bermakna akses kepada medan, pembina dan kaedah kelas tertentu boleh diperolehi melalui kod di dalam kelas itu sendiri, kod di dalam kelas dalam pakej yang sama. Subkelas tidak boleh mengakses kaedah dan pembolehubah ahli superclass jika ia diisytiharkan sebagai lalai , melainkan subkelas berada dalam pakej yang sama dengan superclass. protected Pengubah suai dilindungi berfungsi sama seperti lalai , kecuali subkelas juga boleh mengakses kaedah dan pembolehubah yang dilindungi kelas super. Pernyataan ini adalah benar walaupun subkelas tidak berada dalam pakej yang sama dengan superclass. awam Pengubah suai capaian awam bermaksud semua kod boleh mengakses kelas, pembolehubah, pembina atau kaedahnya, tidak kira di mana kod itu berada. Teras Java.  Soalan untuk temuduga, bahagian 3 - 2

Apakah pemungut sampah? Boleh kita panggil dia?

Pengumpulan sampah ialah ciri pengurusan memori automatik dalam banyak bahasa pengaturcaraan moden, seperti Java dan bahasa dalam NET.Framework. Bahasa yang menggunakan pengumpulan sampah sering mentafsir pengumpulan sampah dalam mesin maya seperti JVM. Pengumpulan sampah mempunyai dua tujuan: sebarang memori yang tidak digunakan harus dibebaskan, dan memori tidak boleh dibebaskan jika program masih menggunakannya. Bolehkah anda menjalankan kutipan sampah secara manual? Tidak, System.gc()ia memberi anda akses sebanyak mungkin. Pilihan terbaik ialah memanggil kaedah System.gc(), yang akan memberi petunjuk kepada pemungut sampah bahawa ia perlu dijalankan. Tidak ada cara untuk menjalankannya dengan segera kerana pemungut sampah tidak menentukan. Di samping itu, menurut dokumentasi, OutOfMemoryErroria tidak akan dimajukan jika mesin maya gagal membebaskan memori selepas kutipan sampah penuh. Ketahui lebih lanjut mengenai pemungut sampah di sini.

Apakah maksud kata kunci asli? Terangkan secara terperinci

Kata kunci asli digunakan untuk menunjukkan bahawa kaedah itu dilaksanakan dalam bahasa pengaturcaraan selain daripada fail Java. Kaedah asli telah digunakan pada masa lalu. Dalam versi Java semasa ini diperlukan kurang kerap. Pada masa ini, kaedah asli diperlukan apabila:
  1. Anda mesti memanggil perpustakaan dari Java yang ditulis dalam bahasa lain.
  2. Anda memerlukan akses kepada sumber sistem atau perkakasan yang hanya boleh diakses menggunakan bahasa lain (biasanya C). Sebenarnya, banyak fungsi sistem yang berinteraksi dengan komputer sebenar (seperti cakera atau data rangkaian) hanya boleh dipanggil dengan kaedah asli.
Kelemahan menggunakan perpustakaan kaedah asli juga penting:
  1. JNI/JNA boleh menjejaskan kestabilan JVM, terutamanya jika anda cuba melakukan sesuatu yang kompleks. Jika kaedah asli anda melakukan sesuatu yang salah, terdapat kemungkinan JVM ranap. Selain itu, perkara buruk boleh berlaku jika kaedah asli anda dipanggil daripada berbilang rangkaian. Dan sebagainya.
  2. Lebih sukar untuk nyahpepijat program dengan kod asli .
  3. Kod asli memerlukan pembinaan rangka kerja yang berasingan, yang boleh menimbulkan masalah dengan pemindahan ke platform lain.

Apakah serialisasi?

Dalam sains komputer, dalam konteks penyimpanan dan penghantaran data, bersiri ialah proses menterjemah struktur data atau keadaan objek ke dalam format yang boleh disimpan dan kemudian diambil semula dalam persekitaran pengkomputeran yang lain. Selepas menerima satu siri bit, ia dikira semula mengikut format bersiri, dan boleh digunakan untuk mencipta klon yang sama secara semantik bagi objek asal. Java menyediakan siri automatik, yang memerlukan objek untuk melaksanakan antara muka java.io.Serializable. Pelaksanaan antara muka menandakan kelas sebagai "boleh bersiri". Antara muka java.io.Serializable tidak mempunyai kaedah bersiri, tetapi kelas boleh bersiri boleh secara pilihan menentukan kaedah yang akan dipanggil sebagai sebahagian daripada proses bersiri/diserialisasi. Apabila membuat perubahan pada kelas, anda perlu mempertimbangkan yang mana yang akan dan tidak akan serasi dengan penyirian. Anda boleh membaca arahan penuh di sini. Saya akan memberikan perkara yang paling penting: Perubahan tidak serasi:
  1. Padamkan medan;
  2. Gerakkan kelas ke atas atau ke bawah dalam hierarki;
  3. Menukar medan bukan statik kepada statik atau tidak sementara kepada sementara;
  4. Menukar jenis data primitif yang diisytiharkan;
  5. Menukar kaedah WriteObjectsama ada ReadObjectsupaya mereka tidak lagi menulis atau membaca medan secara lalai;
  6. Menukar kelas Serializablekepada Externalizableatau sebaliknya;
  7. Menukar kelas enum kepada bukan enum atau sebaliknya;
  8. Mengeluarkan Serializableatau Externalizable;
  9. Menambah writeReplacekaedah readResolvepada kelas.
Perubahan yang serasi:
  1. Menambah medan;
  2. Menambah/mengalih keluar kelas;
  3. Menambah kaedah WriteObject/ReadObject[kaedah defaultReadObjectatau defaultWriteObjectmesti dipanggil pada permulaan];
  4. Mengalih keluar kaedah WriteObject/ReadObject;
  5. Tambahan java.io.Serializable;
  6. Menukar akses medan;
  7. Menukar medan statik kepada bukan statik atau sementara kepada bukan sementara .
Pautan ke bahagian sebelumnya: Java Core. Soalan temu bual, bahagian 1 Java Core. Soalan temuduga, bahagian 2 Artikel asal Selamat belajar!
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION