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 7

Diterbitkan dalam kumpulan
Hai semua! Pengaturcaraan penuh dengan perangkap. Dan hampir tidak ada topik di mana anda tidak akan tersandung dan mendapat benjolan. Ini adalah benar terutamanya untuk pemula. Satu-satunya cara untuk mengurangkan ini adalah dengan belajar. Khususnya, ini digunakan untuk analisis terperinci topik paling asas. Hari ini saya terus menganalisis 250+ soalan daripada temu bual pembangun Java, yang merangkumi topik asas dengan baik. Saya ingin ambil perhatian bahawa senarai itu juga mengandungi beberapa soalan bukan standard yang membolehkan anda melihat topik biasa dari sudut yang berbeza.Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 7 - 1

62. Apakah kolam rentetan dan mengapa ia diperlukan?

Dalam ingatan di Jawa (Timbunan, yang akan kita bincangkan kemudian) terdapat kawasan - Kolam rentetan , atau kolam rentetan. Ia direka untuk menyimpan nilai rentetan. Dengan kata lain, apabila anda mencipta rentetan tertentu, contohnya melalui petikan berganda:
String str = "Hello world";
semakan dibuat untuk melihat sama ada kolam rentetan mempunyai nilai yang diberikan. Jika ya, pembolehubah str diberikan rujukan kepada nilai itu dalam kumpulan. Jika tidak, nilai baharu akan dibuat dalam kolam dan rujukan kepadanya akan diberikan kepada pembolehubah str . Mari lihat contoh:
String firstStr = "Hello world";
String secondStr = "Hello world";
System.out.println(firstStr == secondStr);
true akan dipaparkan pada skrin . Kami ingat bahawa == membandingkan rujukan—bermaksud kedua-dua rujukan ini merujuk kepada nilai yang sama daripada kumpulan rentetan. Ini dilakukan agar tidak menghasilkan banyak objek yang sama jenis String dalam ingatan, kerana seperti yang kita ingat, String ialah kelas yang tidak boleh diubah, dan jika kita mempunyai banyak rujukan kepada nilai yang sama, tidak ada yang salah dengan itu. Ia tidak mungkin lagi untuk situasi di mana menukar nilai di satu tempat membawa kepada perubahan untuk beberapa pautan lain sekaligus. Namun begitu, jika kita membuat rentetan menggunakan new :
String str = new String("Hello world");
objek berasingan akan dibuat dalam ingatan yang akan menyimpan nilai rentetan ini (dan tidak kira sama ada kita sudah mempunyai nilai sedemikian dalam kolam rentetan). Sebagai pengesahan:
String firstStr = new String("Hello world");
String secondStr = "Hello world";
String thirdStr = new String("Hello world");
System.out.println(firstStr == secondStr);
System.out.println(firstStr == thirdStr);
Kami akan mendapat dua nilai palsu , yang bermaksud kami mempunyai tiga nilai berbeza di sini yang sedang dirujuk. Sebenarnya, inilah sebabnya disyorkan untuk mencipta rentetan hanya menggunakan petikan berganda. Walau bagaimanapun, anda boleh menambah (atau mendapatkan rujukan kepada) nilai ke dalam kumpulan rentetan apabila mencipta objek menggunakan new . Untuk melakukan ini, kami menggunakan kaedah kelas rentetan - intern() . Kaedah ini secara paksa mencipta nilai dalam kolam rentetan, atau mendapat pautan kepadanya jika ia sudah disimpan di sana. Berikut ialah contoh:
String firstStr = new String("Hello world").intern();
String secondStr = "Hello world";
String thirdStr = new String("Hello world").intern();
System.out.println(firstStr == secondStr);
System.out.println(firstStr == thirdStr);
System.out.println(secondStr == thirdStr);
Akibatnya, kami akan menerima tiga nilai sebenar dalam konsol , yang bermaksud bahawa ketiga-tiga pembolehubah merujuk kepada rentetan yang sama.Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 7 - 2

63. Apakah corak GOF yang digunakan dalam kolam rentetan?

Corak GOF jelas kelihatan dalam kumpulan rentetan - flyweight , atau dipanggil peneroka. Jika anda melihat templat lain di sini, kongsikannya dalam ulasan. Baiklah, mari bercakap tentang templat ringan. Ringan ialah corak reka bentuk struktur di mana objek yang menampilkan dirinya sebagai contoh unik di tempat yang berbeza dalam program, sebenarnya, tidak begitu. Lightweight menjimatkan memori dengan berkongsi keadaan objek yang dikongsi sesama mereka, bukannya menyimpan data yang sama dalam setiap objek. Untuk memahami intipati, mari kita lihat contoh paling mudah. Katakan kita mempunyai antara muka pekerja:
public interface Employee {
   void work();
}
Dan terdapat beberapa pelaksanaan, sebagai contoh, peguam:
public class Lawyer implements Employee {

   public Lawyer() {
       System.out.println("Юрист взят в штат.");
   }

   @Override
   public void work() {
       System.out.println("Решение юридических вопросов...");
   }
}
Dan akauntan:
public class Accountant implements Employee{

   public Accountant() {
       System.out.println("Бухгалтер взят в штат.");
   }

   @Override
   public void work() {
       System.out.println("Ведение бухгалтерского отчёта....");
   }
}
Kaedahnya sangat bersyarat: kita hanya perlu melihat bahawa ia dijalankan. Keadaan yang sama berlaku kepada pembina. Terima kasih kepada output konsol, kita akan melihat apabila objek baharu dicipta. Kami juga mempunyai jabatan pekerja, yang tugasnya adalah mengeluarkan pekerja yang diminta, dan jika dia tiada, ambil dia dan keluarkan sebagai tindak balas kepada permintaan:
public class StaffDepartment {
   private Map<String, Employee> currentEmployees = new HashMap<>();

   public Employee receiveEmployee(String type) throws Exception {
       Employee result;
       if (currentEmployees.containsKey(type)) {
           result = currentEmployees.get(type);
       } else {
           switch (type) {
               case "Бухгалтер":
                   result = new Accountant();
                   currentEmployees.put(type, result);
                   break;
               case "Юрист":
                   result = new Lawyer();
                   currentEmployees.put(type, result);
                   break;
               default:
                   throw new Exception("Данный сотрудник в штате не предусмотрен!");
           }
       }
       return result;
   }
}
Iaitu, logiknya mudah: jika terdapat unit yang diberikan, pulangkan; jika tidak, buatnya, letakkannya dalam storan (sesuatu seperti cache) dan berikannya kembali. Sekarang mari kita lihat bagaimana semuanya berfungsi:
public static void main(String[] args) throws Exception {
   StaffDepartment staffDepartment = new StaffDepartment();
   Employee empl1  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl2  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
   Employee empl3  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl4  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
   Employee empl5  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl6  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
   Employee empl7  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl8  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
   Employee empl9  = staffDepartment.receiveEmployee("Юрист");
   empl1.work();
   Employee empl10  = staffDepartment.receiveEmployee("Бухгалтер");
   empl2.work();
}
Dan dalam konsol, oleh itu, akan ada output:
Peguam telah diupah. Menyelesaikan isu undang-undang... Akauntan telah diupah. Menyelenggara laporan perakaunan.... Menyelesaikan isu undang-undang... Menyelenggara laporan perakaunan.... Menyelesaikan isu undang-undang... Menyelenggara laporan perakaunan.... Menyelesaikan isu undang-undang... Menyelenggara laporan perakaunan.... Menyelesaikan isu undang-undang... Menyelenggara laporan perakaunan...
Seperti yang anda lihat, hanya dua objek telah dicipta, yang digunakan semula berkali-kali. Contoh ini sangat mudah, tetapi ia jelas menunjukkan cara menggunakan templat ini boleh menjimatkan sumber kami. Seperti yang anda perhatikan, logik corak ini sangat serupa dengan logik kumpulan insurans. Anda boleh membaca lebih lanjut tentang jenis corak GOF dalam artikel ini .Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 7 - 3

64. Bagaimana untuk membelah tali kepada bahagian? Sila berikan contoh kod yang sepadan

Jelas sekali, soalan ini adalah mengenai kaedah split . Kelas String mempunyai dua variasi kaedah ini:
String split(String regex);
Dan
String split(String regex);
regex ialah pemisah baris - beberapa ungkapan biasa yang membahagikan rentetan kepada tatasusunan rentetan, contohnya:
String str = "Hello, world it's Amigo!";
String[] arr = str.split("\\s");
for (String s : arr) {
  System.out.println(s);
}
Yang berikut akan dikeluarkan kepada konsol:
Hello, dunia ini Amigo!
Iaitu, nilai rentetan kami dibahagikan kepada tatasusunan rentetan dan pemisah ialah ruang (untuk pemisahan, kami boleh menggunakan ungkapan biasa bukan ruang "\\s" dan hanya ungkapan rentetan " " ). Kaedah kedua, terlebih beban mempunyai argumen tambahan - had . had — nilai maksimum yang dibenarkan bagi tatasusunan yang terhasil. Iaitu, apabila rentetan itu telah dipecahkan kepada bilangan subrentetan maksimum yang dibenarkan, tidak akan ada pemisahan lagi dan elemen terakhir akan mempunyai "baki" rentetan yang mungkin terpecah. Contoh:
String str = "Hello, world it's Amigo!";
String[] arr = str.split(" ", 2);
for (String s : arr) {
  System.out.println(s);
}
Output konsol:
Hello, dunia ini Amigo!
Seperti yang kita dapat lihat, jika bukan untuk had = 2 kekangan , elemen terakhir tatasusunan boleh dibahagikan kepada tiga subrentetan.Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 7 - 4

65. Mengapakah tatasusunan aksara lebih baik daripada rentetan untuk menyimpan kata laluan?

Terdapat beberapa sebab untuk memilih tatasusunan daripada rentetan apabila menyimpan kata laluan: 1. Kumpulan rentetan dan rentetan kebolehubah. Apabila menggunakan tatasusunan ( char[] ), kami boleh memadamkan data secara eksplisit selepas kami selesai dengannya. Selain itu, kita boleh menulis semula tatasusunan seberapa banyak yang kita mahu, dan kata laluan yang sah tidak akan berada di mana-mana dalam sistem, walaupun sebelum pengumpulan sampah (ia sudah cukup untuk menukar beberapa sel kepada nilai tidak sah). Pada masa yang sama, String ialah kelas yang tidak boleh diubah. Iaitu, jika kita ingin menukar nilainya, kita akan mendapat yang baru, manakala yang lama akan kekal dalam kolam rentetan. Jika kita ingin mengalih keluar nilai String kata laluan, ini boleh menjadi tugas yang sangat sukar, kerana kita memerlukan pengumpul sampah untuk mengalih keluar nilai dari String pool , dan terdapat kebarangkalian tinggi bahawa nilai String ini akan kekal di sana selama masa yang lama. Iaitu, dalam situasi ini, String adalah lebih rendah daripada tatasusunan char dari segi keselamatan penyimpanan data. 2. Jika nilai String secara tidak sengaja dikeluarkan ke konsol (atau log), nilai itu sendiri akan dipaparkan:
String password = "password";
System.out.println("Пароль - " + password);
Output konsol:
Kata laluan
Pada masa yang sama, jika anda secara tidak sengaja mengeluarkan tatasusunan ke konsol:
char[] arr = new char[]{'p','a','s','s','w','o','r','d'};
System.out.println("Пароль - " + arr);
akan ada gobbledygook yang tidak dapat difahami dalam konsol:
Kata laluan - [C@7f31245a
Sebenarnya bukan gobbledygook, tetapi: [C ialah nama kelas ialah tatasusunan char , @ ialah pemisah, diikuti oleh 7f31245a ialah kod cincang heksadesimal. 3. Dokumen rasmi, Panduan Seni Bina Kriptografi Java, secara eksplisit menyebut menyimpan kata laluan dalam char[] dan bukannya String : “Nampaknya logik untuk mengumpul dan menyimpan kata laluan dalam objek jenis java.lang.String . Walau bagaimanapun, terdapat kaveat di sini: Objek rentetan tidak boleh diubah, iaitu, tiada kaedah yang ditentukan untuk membenarkan kandungan objek Rentetan diubah suai (ditulis ganti) atau dibatalkan selepas digunakan. Ciri ini menjadikan objek String tidak sesuai untuk menyimpan maklumat sensitif seperti kata laluan pengguna. Sebaliknya, anda harus sentiasa mengumpul dan menyimpan maklumat keselamatan sensitif dalam susunan aksara."Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 7 - 5

Enum

66. Berikan penerangan ringkas tentang Enum di Jawa

Enum ialah penghitungan, satu set pemalar rentetan yang disatukan oleh jenis biasa. Diisytiharkan melalui kata kunci - enum . Berikut ialah contoh dengan enum - peranan yang sah di sekolah tertentu:
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD
}
Perkataan yang ditulis dalam huruf besar adalah pemalar penghitungan yang sama yang diisytiharkan dengan cara yang dipermudahkan, tanpa menggunakan operator baharu . Menggunakan penghitungan sangat memudahkan kehidupan, kerana ia membantu mengelakkan kesilapan dan kekeliruan dalam penamaan (kerana hanya terdapat senarai nilai tertentu). Secara peribadi, saya mendapati mereka sangat mudah apabila digunakan dalam reka bentuk logik Switch .

67. Bolehkah Enum melaksanakan antara muka?

ya. Lagipun, penghitungan mesti mewakili lebih daripada koleksi pasif (seperti peranan). Di Java, ia boleh mewakili objek yang lebih kompleks dengan beberapa fungsi, jadi anda mungkin perlu menambah fungsi tambahan padanya. Ini juga akan membolehkan anda menggunakan keupayaan polimorfisme dengan menggantikan nilai enum di tempat di mana jenis antara muka yang dilaksanakan diperlukan.

68. Bolehkah Enum melanjutkan kelas?

Tidak, ia tidak boleh, kerana enum ialah subkelas lalai bagi kelas generik Enum <T> , dengan T mewakili jenis enum generik. Ia tidak lain hanyalah kelas asas biasa untuk semua jenis enum bahasa Java. Penukaran enum kepada kelas dilakukan oleh pengkompil Java pada masa penyusunan. Sambungan ini tidak dinyatakan secara eksplisit dalam kod, tetapi sentiasa tidak kelihatan.

69. Adakah mungkin untuk mencipta Enum tanpa contoh objek?

Bagi saya, soalannya agak pelik, atau saya tidak faham sepenuhnya. Saya mempunyai dua tafsiran: 1. Bolehkah ada enum tanpa nilai - ya sudah tentu ia akan menjadi sesuatu seperti kelas kosong - tidak bermakna:
public enum Role {
}
Dan memanggil:
var s = Role.values();
System.out.println(s);
Kami akan menerima dalam konsol:
[Lflyweight.Role;@9f70c54
(tatasusunan nilai Peranan kosong ) 2. Adakah mungkin untuk mencipta enum tanpa pengendali baharu - ya, sudah tentu. Seperti yang saya katakan di atas, anda tidak perlu menggunakan operator baru untuk nilai enum (penghitungan) , kerana ini adalah nilai statik.

70. Bolehkah kita mengatasi kaedah toString() untuk Enum?

Ya, sudah tentu anda boleh mengatasi kaedah toString() untuk menentukan cara khusus untuk memaparkan enum anda apabila memanggil kaedah toString (apabila menterjemah enum ke rentetan biasa, contohnya, untuk output ke konsol atau log).
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD;

   @Override
   public String toString() {
       return "Выбрана роль - " + super.toString();
   }
}
Itu sahaja untuk hari ini, sehingga bahagian seterusnya!Analisis soalan dan jawapan daripada temu bual untuk pembangun Java.  Bahagian 7 - 6
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION