CodeGym /Blog Java /rawak /Meneroka soalan dan jawapan daripada temu duga kerja untu...
John Squirrels
Tahap
San Francisco

Meneroka soalan dan jawapan daripada temu duga kerja untuk jawatan pembangun Java. Bahagian 7

Diterbitkan dalam kumpulan
Hai semua! Pengaturcaraan penuh dengan perangkap. Dan hampir tidak ada satu topik yang tidak akan menyebabkan anda tersandung dan tersandung kaki anda. Ini adalah benar terutamanya untuk pemula. Satu-satunya cara untuk menyelamatkan jari kaki anda adalah dengan belajar. Khususnya, anda perlu menyelami topik yang paling asas. Hari ini, kami akan meneruskan semakan soalan paling popular semasa temu bual untuk pembangun Java. Soalan temu bual ini melakukan kerja yang sangat baik untuk merangkumi topik asas. Ambil perhatian bahawa senarai itu juga termasuk beberapa soalan yang tidak begitu standard yang membolehkan anda mendekati isu biasa secara berbeza. Meneroka soalan dan jawapan daripada temu duga kerja untuk jawatan pembangun Java.  Bahagian 7 - 1

62. Apakah kolam rentetan, dan mengapa ia diperlukan?

Sebahagian daripada memori yang disediakan untuk program Java dipanggil timbunan (yang akan kita bincangkan kemudian), dan sebahagian daripada timbunan dipanggil kolam String . Ia adalah untuk menyimpan nilai rentetan. Dengan kata lain, apabila anda membuat rentetan, sebagai contoh, menggunakan petikan berganda seperti ini:
String str = "Hello world";
JVM menyemak sama ada kumpulan rentetan sudah mempunyai nilai yang ditentukan. Jika ia berlaku, maka pembolehubah str diberikan rujukan kepada nilai tersebut dalam kumpulan. Jika tidak, nilai baharu dibuat dalam kolam dan rujukan kepadanya diberikan kepada pembolehubah str . Mari kita pertimbangkan contoh:
String firstStr = "Hello world";
String secondStr = "Hello world";
System.out.println(firstStr == secondStr);
true akan dipaparkan pada skrin. Ingat bahawa == membandingkan rujukan, dan kedua-dua pembolehubah ini menunjukkan nilai yang sama dalam kumpulan rentetan. Ini membantu untuk mengelakkan daripada menghasilkan banyak objek String yang sama dalam ingatan. Kami boleh melakukan ini kerana, seperti yang anda ingat, String ialah kelas yang tidak boleh diubah, jadi tidak ada yang salah dengan mempunyai berbilang rujukan kepada nilai yang sama. Kini adalah mustahil untuk mempunyai situasi di mana menukar nilai di satu tempat mengakibatkan perubahan kepada beberapa rujukan lain. Namun, jika kita membuat rentetan menggunakan new :
String str = new String("Hello world");
maka objek yang berasingan dicipta dalam ingatan dan menyimpan nilai rentetan yang ditentukan (tidak kira jika nilai itu sudah ada dalam kolam rentetan). Untuk mengesahkan pernyataan ini, pertimbangkan ini:
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 baris yang menunjukkan false , yang bermaksud bahawa kami mempunyai tiga rentetan berasingan. Pada asasnya, inilah sebabnya anda perlu membuat rentetan hanya menggunakan petikan berganda. Walau bagaimanapun, adalah mungkin untuk menambah (atau mendapatkan rujukan kepada) nilai dalam kumpulan rentetan walaupun semasa membuat objek menggunakan kata kunci baharu . Untuk melakukan ini, kami menggunakan kaedah intern() kelas String . Kaedah ini memastikan bahawa kami sama ada mencipta nilai dalam kumpulan rentetan atau kami mendapat rujukan kepadanya jika ia sudah ada. 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);
Kod ini mengeluarkan kebenaran kepada konsol tiga kali, yang memberitahu kita bahawa ketiga-tiga pembolehubah merujuk kepada rentetan yang sama dalam ingatan.

63. Apakah corak reka bentuk GoF yang digunakan dalam kumpulan rentetan?

Dalam kumpulan rentetan, corak reka bentuk GoF ialah corak flyweight . Jika anda perasan corak reka bentuk lain di sini, kongsi dalam komen. Di sini kita akan bercakap tentang corak reka bentuk flyweight. Ia adalah corak reka bentuk struktur di mana objek yang mewakili dirinya sebagai contoh unik di tempat yang berbeza dalam program sebenarnya tidak unik. Flyweight menjimatkan memori dengan menyimpan keadaan kongsi objek dan bukannya menyimpan data yang sama dalam setiap objek. Untuk memahami intipati, pertimbangkan contoh asas ini. Katakan kami mempunyai antara muka Pekerja :
public interface Employee {
   void work();
}
Dan ia mempunyai beberapa pelaksanaan, seperti kelas Peguam :
public class Lawyer implements Employee {

   public Lawyer() {
       System.out.println("A lawyer was hired.");
   }

   @Override
   public void work() {
       System.out.println("Settling legal issues...");
   }
}
Dan kelas Akauntan :
public class Accountant implements Employee {

   public Accountant() {
       System.out.println("An accountant was hired.");
   }

   @Override
   public void work() {
       System.out.println("Keeping accounting records...");
   }
}
Kaedah ini adalah sewenang-wenangnya - untuk contoh ini, kita hanya perlu melihat bahawa ia sedang dilaksanakan. Perkara yang sama berlaku tentang pembina. Output konsol memberitahu kita apabila objek baharu dicipta. Kami juga mempunyai jabatan sumber manusia yang tugasnya adalah untuk memulangkan pekerja yang diminta. Jika pekerja itu belum lagi menjadi kakitangan, maka mereka diambil bekerja dan jabatan HR mengembalikan pekerja baharu:
public class HumanResourcesDepartment {
   private Map<String, Employee> currentEmployees = new HashMap<>();

   public Employee getEmployee(String type) throws Exception {
       Employee result;
       if (currentEmployees.containsKey(type)) {
           result = currentEmployees.get(type);
       } else {
           switch (type) {
               case "Accountant":
                   result = new Accountant();
                   currentEmployees.put(type, result);
                   break;
               case "Lawyer":
                   result = new Lawyer();
                   currentEmployees.put(type, result);
                   break;
               default:
                   throw new Exception("This employee is not on the staff!");
           }
       }
       return result;
   }
}
Jadi, logiknya mudah: jika objek yang dikehendaki wujud, kembalikannya; jika tidak, buatnya, letakkannya dalam storan (sesuatu seperti cache), dan kembalikannya. Sekarang mari kita lihat bagaimana semuanya berfungsi:
public static void main(String[] args) throws Exception {
   HumanResourcesDepartment humanResourcesDepartment = new HumanResourcesDepartment();
   Employee empl1 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl2 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
   Employee empl3 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl4 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
   Employee empl5 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl6 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
   Employee empl7 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl8 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
   Employee empl9 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl10 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
}
Inilah yang akan kita lihat dalam konsol:
Seorang peguam telah diupah. Menyelesaikan isu undang-undang... Akauntan telah diupah. Menyimpan rekod perakaunan... Menyelesaikan isu undang-undang... Menyimpan rekod perakaunan... Menyelesaikan isu undang-undang... Menyimpan rekod perakaunan... Menyelesaikan isu undang-undang... Menyimpan rekod perakaunan... Menyelesaikan isu undang-undang... Menyimpan perakaunan rekod…
Seperti yang anda lihat, kami hanya mencipta dua objek dan menggunakannya semula berkali-kali. Contohnya sangat mudah, tetapi ia menunjukkan cara corak reka bentuk ini boleh menjimatkan sumber kami. Seperti yang anda mungkin perasan, logik corak ini sangat serupa dengan logik kumpulan insurans. Meneroka soalan dan jawapan daripada temu duga kerja untuk jawatan pembangun Java.  Bahagian 7 - 2

64. Bagaimanakah kita membahagikan rentetan kepada bahagian? Berikan contoh kod yang berkaitan

Jelas sekali, soalan ini adalah mengenai kaedah split . Kelas String mempunyai dua variasi kaedah ini:
String split(String regex);
dan
String split(String regex);
Parameter regex ialah pembatas — beberapa ungkapan biasa yang digunakan untuk memisahkan 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);
}
Konsol akan memaparkan:
Hello, dunia ini Amigo!
Jadi, rentetan kami dipecahkan kepada tatasusunan rentetan, menggunakan ruang sebagai pembatas (bukannya ungkapan biasa "\\s" , kami juga boleh menggunakan ungkapan rentetan biasa " " ). Varian kedua, terlebih beban, mempunyai parameter had tambahan . had ialah saiz maksimum yang dibenarkan bagi tatasusunan yang terhasil. Dalam erti kata lain, apabila rentetan itu telah dipecahkan kepada bilangan subrentetan maksimum yang dibenarkan, pemisahan itu berhenti dan elemen terakhir akan mengandungi sebarang "sisa" daripada rentetan yang mungkin tidak terbelah. 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 limit = 2 , elemen terakhir tatasusunan boleh dibahagikan kepada tiga subrentetan.

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. Kolam rentetan dan kebolehubahan rentetan.

Apabila menggunakan tatasusunan ( char[] ), kami boleh memadamkan data secara eksplisit setelah kami selesai bekerja dengannya. Kita juga boleh menulis ganti tatasusunan seberapa banyak yang kita mahu, menghapuskan kata laluan daripada sistem walaupun sebelum pengumpulan sampah (ia mencukupi untuk menukar beberapa sel kepada nilai tidak sah). Sebaliknya, String ialah kelas yang tidak boleh diubah. Ini bermakna jika kita ingin menukar nilai objek String , kita akan mendapat yang baru, tetapi yang lama akan kekal dalam kolam rentetan. Jika kami ingin mengalih keluar String yang mengandungi kata laluan, kami menghadapi tugas yang rumit kerana kami memerlukan pemungut sampah untuk mengalih keluar nilai itu daripada kolam rentetan, tetapi String itu mungkin akan kekal di sana untuk jangka masa yang lama. Iaitu, apabila ia datang untuk menyimpan data dengan selamat, String adalah lebih rendah daripada tatasusunan char .

2. Jika kita mengeluarkan nilai String ke konsol (atau log), maka kita mendapat:

String password = "password";
System.out.println("Password - " + password);
Output konsol:
Kata laluan - kata laluan
Dan jika anda kebetulan mencetak tatasusunan ke konsol:
char[] arr = new char[]{'p','a','s','s','w','o','r','d'};
System.out.println("Password - " + arr);
konsol akan memaparkan omong kosong yang tidak dapat difahami:
Kata laluan - [C@7f31245a
Malah, ia bukan omong kosong. Begini cara untuk memahami perkara yang anda lihat: [C ialah nama kelas - tatasusunan char , @ ialah pembatas, dan kemudian 7f31245a ialah kod cincang heksadesimal.

3. Panduan Rujukan Java Cryptography Architecture (JCA) rasmi 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, inilah kaveatnya: Objek jenis String tidak boleh diubah, iaitu, tiada kaedah yang ditentukan yang membolehkan anda menukar (timpa) atau kosongkan kandungan String selepas penggunaan. Ciri ini menjadikan objek String tidak sesuai untuk menyimpan maklumat sensitif keselamatan seperti kata laluan pengguna. Anda harus sentiasa mengumpul dan menyimpan maklumat sensitif keselamatan dalam tatasusunan aksara." Meneroka soalan dan jawapan daripada temu duga kerja untuk jawatan pembangun Java.  Bahagian 7 - 3

Enum

66. Berikan penerangan ringkas tentang Enum di Jawa

Enum ialah singkatan untuk penghitungan, iaitu satu set pemalar rentetan yang disatukan oleh jenis biasa. Kami mengisytiharkan satu menggunakan kata kunci enum . Berikut ialah contoh dengan enum : peranan yang dibenarkan di beberapa kampus sekolah:
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD
}
Perkataan yang ditulis dengan huruf besar ialah pemalar penghitungan. Mereka diisytiharkan dengan cara yang dipermudahkan, tanpa pengendali baharu . Menggunakan penghitungan menjadikan hidup lebih mudah kerana ia membantu mengelakkan ralat dan kekeliruan dalam nama (kerana senarai mentakrifkan satu-satunya nilai yang sah). Bagi saya, mereka sangat mudah dalam binaan suis .

67. Bolehkah Enum melaksanakan antara muka (menggunakan kata kunci implement)?

ya. Lagipun, enum harus mewakili lebih daripada set pasif (seperti peranan di kampus sekolah). Di Java, ia boleh mewakili objek yang lebih kompleks, jadi anda mungkin perlu menambah fungsi tambahan padanya. Ini juga membolehkan anda memanfaatkan polimorfisme dengan menggantikan nilai enum di tempat di mana jenis antara muka yang dilaksanakan diperlukan.

68. Bolehkah Enum melanjutkan kelas (menggunakan kata kunci extends)?

Tidak, ia tidak boleh, kerana enum ialah subkelas bagi kelas Enum<T> lalai , dengan T ialah jenis enum. Ini tidak lebih daripada kelas asas biasa untuk semua jenis enum dalam bahasa Java. Penukaran daripada enum kepada kelas dilakukan oleh pengkompil Java pada masa penyusunan. Sambungan tidak dinyatakan secara eksplisit dalam kod, tetapi ia sentiasa tersirat.

69. Adakah mungkin untuk mencipta Enum tanpa sebarang contoh objek?

Soalan ini agak mengelirukan, dan saya tidak pasti saya memahaminya sepenuhnya. Saya mempunyai dua tafsiran: 1. Bolehkah anda mempunyai enum tanpa sebarang nilai? Ya, sudah tentu, tetapi ia akan menjadi seperti kelas kosong — sia-sia, mis
public enum Role {
}
Dan jika kita memanggil:
var s = Role.values();
System.out.println(s);
Kami mendapat yang berikut dalam konsol:
[Lflyweight.Role;@9f70c54
(tatasusunan kosong nilai Peranan ) 2. Adakah mungkin untuk mencipta enum tanpa pengendali baharu ? Ya sudah tentu. Seperti yang saya katakan di atas, anda tidak menggunakan operator baharu untuk nilai enum, kerana ia adalah nilai statik.

70. Bolehkah kita mengatasi kaedah toString() Enum?

Ya, sudah tentu anda boleh mengatasi kaedah toString() untuk menentukan cara memaparkan enum anda apabila kaedah toString dipanggil (apabila menukar enum kepada rentetan biasa, sebagai contoh, untuk mengeluarkannya ke konsol atau log).
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD;

   @Override
   public String toString() {
       return "Selected role - " + super.toString();
   }
}
Itu sahaja untuk saya hari ini. Sehingga bahagian seterusnya!
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION