CodeGym /Java Blog /Acak /Menjelajahi pertanyaan dan jawaban dari wawancara kerja u...
John Squirrels
Level 41
San Francisco

Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java. Bagian 10

Dipublikasikan di grup Acak
Hai! Berapa jam yang dibutuhkan untuk menjadi ahli dalam suatu hal? Saya sering mendengar sesuatu seperti: "Untuk menjadi ahli dalam segala hal, Anda perlu menghabiskan 10.000 jam untuk itu." Itu angka yang menakutkan bukan? Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 10 - 1Tetap saja, saya bertanya-tanya apakah itu benar. Dan saya terus-menerus mencoba mencari tahu berapa jam yang telah saya investasikan untuk menguasai seni pemrograman. Dan ketika saya melewati batas khusus 10.000 jam itu dan menjadi seorang master, akankah saya merasakan perbedaannya? Atau apakah saya sudah melewati batas itu sejak lama tanpa menyadarinya? Apa pun yang terjadi, Anda tidak perlu menginvestasikan banyak waktu untuk menjadi seorang programmer. Yang penting adalah menggunakan waktu Anda dengan bijak. Tujuan utama Anda adalah mendapatkan wawancara. Dan dalam wawancara, calon pengembang software ditanya terlebih dahulu tentang teori, sehingga perlu menjadi kekuatan. Faktanya, saat Anda mempersiapkan wawancara, tugas Anda adalah menemukan semua kesenjangan dalam pengetahuan teori dasar Java dan kemudian mengisinya. Hari ini saya di sini untuk membantu Anda melakukan hal itu, karena hari ini kami akan melanjutkan tinjauan kami terhadap pertanyaan wawancara paling populer. Baiklah, ayo lanjutkan!

89. Apa perbedaan ArrayList dengan LinkedList?

Ini adalah salah satu pertanyaan paling populer, bersama dengan pertanyaan tentang struktur internal HashMap . Tidak ada wawancara yang lengkap tanpanya, jadi jawaban Anda akan langsung keluar dari lidah Anda. Selain yang sudah jelas (mereka memiliki nama berbeda), mereka juga berbeda dalam struktur internalnya. Sebelumnya, kita membahas struktur internal ArrayList dan LinkedList , jadi saya tidak akan mendalami detail implementasinya. Saya hanya akan mengingatkan Anda bahwa ArrayList diimplementasikan menggunakan array internal yang ukurannya bertambah secara dinamis sesuai dengan rumus ini:
<size of the current array> * 3 / 2 + 1
Selain itu, penerapan LinkedList menggunakan daftar tertaut ganda internal, yaitu setiap elemen memiliki referensi ke elemen sebelumnya dan berikutnya, kecuali elemen di awal dan akhir daftar. Pewawancara suka menanyakan pertanyaan seperti ini, "Mana yang lebih baik, ArrayList atau LinkedList ?" berharap untuk menangkapmu. Lagi pula, jika Anda mengatakan yang satu lebih baik, maka Anda memberikan jawaban yang salah. Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 10 - 2Sebaliknya, Anda harus memperjelas situasi spesifik yang Anda bicarakan: mengakses elemen berdasarkan indeks atau menyisipkannya di tengah daftar. Kemudian, berdasarkan jawaban mereka, Anda bisa menjelaskan mana yang lebih baik. Saya sebelumnya menjelaskan cara kerja ArrayList dan LinkedList di setiap situasi. Mari kita rangkum dengan menempatkannya dalam satu baris sebagai perbandingan: Menambahkan elemen (menambahkan)
  1. Jika indeks tidak ditentukan, maka item baru akan secara otomatis ditambahkan ke akhir untuk kedua jenis daftar. Dalam LinkedList , elemen baru akan menjadi ekor baru (hanya sepasang referensi yang akan ditulis ulang, sehingga kompleksitas algoritmiknya adalah O(1) ).

    Metode add menambahkan elemen ke sel kosong terakhir dalam array ( O(1) ).

  2. Menambahkan item berdasarkan indeks biasanya berarti menyisipkannya di suatu tempat di tengah daftar. Dalam LinkedList , metode pertama-tama akan mencari lokasi yang diinginkan dengan mengulangi elemen dari tail dan head ( O(n/2) ) dan kemudian akan memasukkan nilai dengan menimpa referensi elemen di kedua sisi tempat elemen baru dimasukkan ( O(1) ). Kompleksitas algoritmik keseluruhan dari operasi ini adalah O(n/2) .

    Dalam situasi yang sama (menambahkan berdasarkan indeks), ArrayList menemukan lokasi yang diinginkan ( O(1) ) dan kemudian menggeser semua elemen yang terletak di sebelah kanan (termasuk elemen yang sudah disimpan pada indeks yang ditentukan) ke kanan sebanyak satu (yang mungkin memerlukan pembuatan array internal baru dan menyalin elemen ke dalamnya) ( O(n/2) ). Kompleksitas keseluruhannya adalah O(n/2) .

  3. Menambahkan elemen ke awal LinkedList mirip dengan menambahkan elemen ke akhir: elemen baru menjadi kepala baru ( O(1) ). Namun untuk ArrayList, operasi tersebut memerlukan pemindahan semua elemen ke kanan ( O(n) ).

Intinya adalah bahwa untuk LinkedList kompleksitas algoritmik akan berkisar dari O(1) hingga O(n/2) . Pengamatan lain adalah semakin dekat penyisipan ke akhir atau awal daftar, semakin cepat penyisipannya. Untuk ArrayList , kompleksitas algoritmik berkisar dari O(1) hingga O(n) , dan semakin dekat penyisipan ke akhir daftar, semakin cepat penyisipannya. Mengatur elemen (set) Operasi ini menulis elemen ke posisi tertentu dalam daftar, menimpa elemen yang ada. Dalam LinkedList , operasi ini mirip dengan penambahan, karena tantangan terbesar di sini adalah menemukan lokasi elemen. Elemen yang ada ditimpa dengan memperbarui sepasang referensi, jadi sekali lagi kita memiliki kompleksitas algoritmik yang bervariasi dari O(1) hingga O(n/2) , bergantung pada jarak posisi yang diinginkan dari akhir atau awal daftar. Namun untuk ArrayList , operasi ini menemukan sel yang diinginkan berdasarkan indeks dan menulis elemen baru di sana. Seperti operasi himpunan, pencarian berdasarkan indeks memiliki kompleksitas algoritmik O(1) . Mendapatkan elemen berdasarkan indeks (dapatkan) Mendapatkan elemen dari LinkedList mengikuti prinsip pencarian yang sama yang digunakan dalam operasi lainnya. Kompleksitasnya bergantung pada jarak dari akhir atau awal, yaitu bervariasi dari O(1) hingga O(n/2) . Seperti disebutkan sebelumnya, untuk ArrayList , menemukan elemen berdasarkan indeks dalam array internal memiliki kompleksitas O(1) . Menghapus elemen berdasarkan indeks (remove) Untuk LinkedList , prinsip yang sama berlaku sekali lagi. Pertama, elemen tersebut ditemukan, dan kemudian referensi ditulis ulang, tetangga elemen yang dihapus sekarang saling merujuk, menghilangkan referensi ke elemen yang dihapus, yang selanjutnya akan dibersihkan oleh pengumpul sampah. Dengan kata lain, kompleksitas algoritmiknya masih sama — bervariasi dari O(1) hingga O(n/2) . Bagi ArrayList , operasi ini lebih seperti menambahkan elemen baru (add). Pertama, metode menemukan elemen yang diinginkan ( O(1) ), menghapusnya, dan kemudian semua elemen yang terletak di sebelah kanan digeser satu langkah ke kiri untuk menutup celah yang diciptakan oleh penghapusan tersebut. Menghapus elemen memiliki kompleksitas algoritmik yang sama dengan operasi penambahan — dari O(1) hingga O(n). Semakin dekat elemen yang dihapus ke akhir daftar, semakin rendah kompleksitas algoritmik operasi ini. Dan sekarang kami telah membahas semua operasi utama. Izinkan saya mengingatkan Anda bahwa ketika membandingkan kedua jenis daftar ini, Anda perlu memperjelas situasi spesifik yang digunakannya. Hanya dengan begitu Anda dapat menjawab pertanyaan pewawancara dengan tegas.

90. Apa perbedaan ArrayList dengan HashSet?

Jika kita dapat membandingkan ArrayList dan LinkedList berdasarkan operasi demi operasi untuk menentukan mana yang lebih baik, kita tidak akan mudah membuat perbandingan antara ArrayList dan HashSet , karena keduanya merupakan kumpulan yang sangat berbeda. Anda dapat membandingkan satu makanan penutup dengan makanan penutup lainnya, tetapi membandingkan makanan penutup dan hidangan gurih adalah sebuah tantangan — keduanya sangat berbeda. Namun, saya akan mencoba menunjukkan beberapa perbedaan di antara keduanya:
  • ArrayList mengimplementasikan antarmuka Daftar sementara HashSet mengimplementasikan antarmuka Set .

  • ArrayList memungkinkan Anda mengakses elemen berdasarkan indeks: operasi get memiliki kompleksitas algoritmik O(1) , tetapi HashSet hanya memungkinkan Anda mengakses elemen yang diinginkan berdasarkan iterasi, yang menghasilkan kompleksitas algoritmik mulai dari O(1) hingga O(n) .

  • ArrayList memungkinkan elemen duplikat. Dalam HashSet , semua elemennya unik: setiap upaya untuk menambahkan elemen yang sudah ada dalam HashSet akan gagal (duplikat diperiksa dengan kode hash, itulah nama koleksi ini).

  • ArrayList diimplementasikan menggunakan array internal, tetapi HashSet diimplementasikan menggunakan HashMap internal .

  • ArrayList mempertahankan urutan penyisipan elemen, tetapi HashSet adalah himpunan tidak berurutan dan tidak mempertahankan urutan elemen.

  • ArrayList mengizinkan sejumlah nilai null, tetapi Anda hanya dapat menambahkan satu nilai null ke HashSet ( bagaimanapun juga, elemennya harus unik).

91. Mengapa Java memiliki begitu banyak implementasi array dinamis yang berbeda?

Ini lebih merupakan pertanyaan filosofis. Kita juga bisa bertanya mengapa mereka memunculkan begitu banyak teknologi baru dan beragam? Untuk kenyamanan. Dan hal yang sama juga berlaku pada sejumlah besar implementasi array dinamis. Tak satu pun dari mereka dapat disebut sebagai implementasi terbaik atau ideal. Masing-masing mempunyai kelebihan dalam situasi tertentu. Tugas kita adalah mengetahui perbedaan dan kekuatan/kelemahannya agar dapat menggunakan koleksi yang paling sesuai untuk situasi tertentu.

92. Mengapa Java memiliki begitu banyak implementasi penyimpanan nilai kunci yang berbeda?

Di sini situasinya sama dengan implementasi array dinamis. Tidak ada satu pun yang secara universal lebih baik dari yang lain: masing-masing mempunyai kekuatan dan kelemahan. Dan tentu saja kita harus memanfaatkan kekuatan mereka sebaik-baiknya. Contoh: paket serentak, yang memiliki banyak kelas multithread, memiliki koleksi serentak sendiri . Kelas ConcurrentHashMap memiliki keunggulan dibandingkan HashMap standar dalam hal keamanan saat bekerja dengan data dalam lingkungan multi-thread, namun hal ini mengakibatkan kinerja yang lebih lambat. Dan implementasi yang bukan merupakan pilihan terbaik dalam situasi apa pun secara bertahap tidak lagi digunakan. Misalnya: Hashtable , yang awalnya dimaksudkan sebagai HashMap yang aman untuk thread , telah dilupakan dan tidak lagi digunakan, karena ConcurrentHashMap bahkan lebih baik daripada Hashtable ketika bekerja di lingkungan multi-thread.

93. Bagaimana cara mengurutkan kumpulan elemen?

Hal pertama yang harus dikatakan adalah bahwa kelas yang mewakili elemen koleksi harus mengimplementasikan antarmuka Comparable , yang terdiri dari metode bandingkanTo . Atau Anda memerlukan kelas yang mengimplementasikan antarmuka Comparator , termasuk metode perbandingannya . Kedua metode menunjukkan cara membandingkan objek dari tipe tertentu. Hal ini penting ketika melakukan pengurutan, karena algoritme pengurutan perlu memahami prinsip apa yang digunakan untuk membandingkan elemen. Hal ini terutama dilakukan dengan mengimplementasikan Comparable secara langsung di kelas yang ingin Anda urutkan. Penggunaan Komparator kurang umum. Misalkan Anda menggunakan kelas dari beberapa perpustakaan dan tidak mengimplementasikan Comparable , tetapi Anda perlu mengurutkan kumpulan objeknya. Karena Anda tidak dapat mengubah kode kelas ini (kecuali dengan memperluasnya), Anda dapat menulis implementasi Comparator yang menunjukkan cara membandingkan objek kelas. Dan satu contoh lagi. Jika Anda perlu mengurutkan objek bertipe sama dengan cara berbeda, Anda dapat menulis beberapa implementasi Komparator untuk digunakan dalam situasi berbeda. Biasanya, banyak kelas out-of-the-box, misalnya String , sudah mengimplementasikan antarmuka Comparable . Artinya, Anda tidak perlu khawatir tentang cara membandingkan kelas-kelas ini. Anda bisa melanjutkan dan menggunakannya. Cara pertama dan paling jelas adalah dengan menggunakan kelas TreeSet atau TreeMap . Kelas-kelas ini menyimpan elemen dalam urutan yang diurutkan berdasarkan pembanding yang diterapkan oleh elemen kelas. Jangan lupa bahwa TreeMap mengurutkan kunci, bukan nilai. Jika Anda menggunakan Comparator dan bukan Comparable , Anda harus meneruskan objek Comparator ke konstruktor koleksi saat Anda membuatnya:
TreeSet treeSet = new TreeSet(customComparator);
Namun bagaimana jika Anda memiliki jenis koleksi yang berbeda? Bagaimana Anda mengurutkannya? Dalam hal ini, cara kedua kelas utilitas Koleksi — metode sort() — cocok. Metode ini statis, jadi yang Anda perlukan hanyalah menambahkan nama kelas di awal dan kemudian memasukkan daftar yang akan diurutkan. Misalnya:
Collections.sort(someList);
Jika Anda menggunakan implementasi Comparator daripada Comparable , Anda harus meneruskannya sebagai argumen kedua:
Collections.sort(someList, customComparator);
Operasi ini akan mengubah urutan internal elemen dalam daftar yang diteruskan: daftar akan diurutkan menggunakan pembanding. Perhatikan bahwa daftar yang diteruskan harus dapat diubah, jika tidak, metode ini akan gagal dan memunculkan UnsupportedOperationException . Opsi ketiga adalah menggunakan metode sortir kelas Stream , yang mengurutkan elemen koleksi. Jika kita menggunakan Comparable :
someList = someList.stream().sorted().collect(Collectors.toList());
Jika kita menggunakan Comparator :
someList = someList.stream().sorted(customComparator).collect(Collectors.toList());
Cara keempat adalah dengan mengimplementasikan algoritma pengurutan secara manual, misalnya bubble sort atau merge sort .

Kelas objek. sama dengan() dan kode hash()

94. Berikan penjelasan singkat tentang kelas Object di Java.

Pada ulasan bagian kedua , kita telah membahas metode kelas Object . Di sini saya akan mengingatkan Anda bahwa kelas Object adalah nenek moyang dari setiap kelas di Java. Ini memiliki 11 metode, yang pada gilirannya diwarisi oleh semua kelas. Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 10 - 3

95. Untuk apa equal() dan hashCode() digunakan di Java?

hashCode() adalah metode kelas Objek yang diwarisi oleh semua kelas. Tugasnya adalah menghasilkan angka yang mewakili objek tertentu. Contoh penerapan metode ini dapat ditemukan di HashMap , di mana metode ini dipanggil pada objek kunci untuk mendapatkan kode hash lokal, yang akan menentukan di keranjang mana (sel array internal) pasangan nilai kunci akan disimpan. Selain itu, metode ini umumnya digunakan dalam metode sama dengan() sebagai salah satu cara utamanya untuk mengidentifikasi objek. sama dengan() adalah metode kelas Object yang tugasnya membandingkan objek dan menentukan apakah objek tersebut setara. Metode ini digunakan dimanapun kita perlu membandingkan objek, karena operator perbandingan == standar tidak cocok untuk objek, karena hanya membandingkan referensi objek.

96. Beritahu kami tentang kontrak antara sama dengan() dan kode hash() di Java?

Pertama, izinkan saya mengatakan bahwa agar metode sama dengan() dan kode hash() berfungsi dengan benar, metode tersebut harus diganti dengan benar. Implementasi barunya harus mengikuti aturan berikut:
  • Objek identik yang menghasilkan nilai true harus memiliki kode hash yang sama.
  • Objek dengan kode hash yang sama belum tentu sama.
Sekarang sepertinya saat yang tepat untuk berhenti sejenak hingga ulasan bagian selanjutnya!
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION