JavaRush /Java Blogu /Random-AZ /Java tərtibatçısı üçün müsahibələrdən alınan sualların və...

Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili. 10-cu hissə

Qrupda dərc edilmişdir
Salam! Bir şeydə usta olmaq üçün neçə saat lazımdır? Mən tez-tez belə bir şey eşitmişəm: "Hər şeydə usta olmaq üçün 10.000 saat sərf etmək lazımdır." Dəhşətli rəqəm, elə deyilmi? Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  10-1 hissəBununla belə, görəsən, bu həqiqətdirmi? Və mən davamlı olaraq proqramlaşdırma sənətinə yiyələnmək üçün artıq neçə saat sərf etdiyimi anlamağa çalışıram. Və o əziz 10.000 saatı keçib ustad olanda bu fərqi hiss edəcəmmi? Yoxsa çoxdan fərqinə varmadan onların üstünə addım atmışam? Bu və ya digər şəkildə, proqramçı olmaq üçün bu qədər böyük vaxt sərf etmək lazım deyil. Əsas odur ki, ondan ağıllı istifadə edək. Əsas məqsədiniz müsahibədən keçməkdir. Yeni gələnlər üçün müsahibələr zamanı soruşduqları ilk şey nəzəriyyədir, ona görə də bunda güclü olmalısan. Əslində, müsahibəyə hazırlaşarkən sizin vəzifəniz Java tərtibatçısının əsas nəzəriyyəsindəki bütün boşluqlarınızı aşkar etmək və onları biliklərlə əhatə etməkdir. Və bu gün sizə bu məsələdə kömək edəcəyəm, çünki ən populyar sualları təhlil etməyə davam etmək üçün buradayam. Beləliklə, davam edək!

89. ArrayList LinkedList-dən nə ilə fərqlənir?

Bu, HashMap-ın daxili strukturu ilə bağlı sualla yanaşı ən populyar suallardan biridir . Heç bir müsahibə onsuz tamamlanmır və buna görə də ona cavab "dişlərinizdən sıçrayacaq". Aşkar olanlara əlavə olaraq - müxtəlif adlar - daxili quruluşda fərqlənirlər. Əvvəllər biz həm ArrayList , həm də LinkedList- in daxili strukturunu araşdırdıq , ona görə də onların həyata keçirilməsinin təfərrüatlarına varmayacağam. Xatırlatmaq istərdim ki, ArrayList daxili massiv əsasında həyata keçirilir və düstura uyğun olaraq lazım olduqda artırılır:
<размерТекущегоМассива> * 3 / 2  + 1
Eyni zamanda, LinkedList daxili ikiqat əlaqəli siyahı əsasında həyata keçirilir, yəni siyahının əvvəli/sonu olan dəyərlər istisna olmaqla, hər bir elementin əvvəlki və sonrakı ilə əlaqəsi var. İnsanlar sizi tutmaq ümidi ilə bu sualı "Hansı daha yaxşıdır - ArrayList və ya LinkedList ?" formatında verməyi sevirlər . Axı cavab olaraq onlardan birini göstərsəniz, səhv cavab olacaq. Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  10-2 hissəBunun əvəzinə, hansı konkret vəziyyətdən danışdığınızı aydınlaşdırmalısınız - indeks girişi və ya siyahının ortasına daxil edilməsi. Cavabdan asılı olaraq seçiminizi izah edə biləcəksiniz. ArrayListLinkedList-in bu və ya digər vəziyyətdə necə işlədiyini əvvəllər təsvir etmişdim . Müqayisə üçün onları eyni səhifəyə qoymaqla bunları ümumiləşdirək: Element əlavə etmək (əlavə etmək)
  1. Добавление нового element без указания индекса How местоположения будет происходить автоматически в конец обоих списков. В LinkedList новый элемент станет новым хвостом (происходит только перезаписывание пары ссылок — алгоритмическая сложность O(1)).

    В ArrayList будет добавлен новый элемент в последнюю пустую ячейку массива — O(1).

  2. Добавление element по индексу How правило подразумевает вставку примерно в середину списка. В LinkedList сперва будет вестись поиск нужного места с помощью перебора элементов с “хвоста” и “головы” — O(n/2), а после — вставка значения путем переопределения ссылок элементов, между которыми вставляется новый — O(1). Суммарная алгоритмическая сложность данного действия будет O(n/2).

    ArrayList в данной ситуации по индексу находит элемент — O(1), и все элементы справа (включая элемент, который уже хранится по данному индексу) двигаются на одну единицу вправо (при этом возможно понадобится создание нового списка и копирование элементов в него) — O(n/2). Суммарная сложность — O(n/2).

  3. Добавление element в начало списка в LinkedList будет ситуация схожая с добавлением в конец: новый элемент станет новой “головой” — O(1), в то же время когда ArrayList-у нужно будет двигать все элементы вправо — O(n).

Aşağı xətt: LinkedList -də alqoritmik mürəkkəblik O(1) ilə O(n/2) arasında dəyişəcək . Yəni, daxiletmə siyahının sonuna və ya əvvəlinə nə qədər yaxındırsa, bir o qədər sürətli olur. Eyni zamanda, ArrayList üçün O(1) -dən O(n) -a qədər dəyişir : daxiletmə siyahının sonuna nə qədər yaxındırsa, bir o qədər sürətli olur. Elementin (dəst) qurulması Bu əməliyyat, əgər varsa, əvvəlkinin üzərinə yazaraq, siyahıda göstərilən mövqeyə element yazır. LinkedList -də bu əməliyyat əlavə etməyə bənzəyəcək, çünki Burada ən böyük çətinlik elementi tapmaqdır. Elementin yenidən yazılması bir cüt keçidin yenidən yazılması ilə baş verəcək, ona görə də burada da alqoritmik mürəkkəblik siyahının sonundan və ya əvvəlindən mövqenin məsafəsindən asılı olaraq O(1) -dən O(n/2) -ə qədər dəyişəcək. O zaman bu indeks əməliyyatı üçün ArrayList- də tələb olunan xana tapılacaq və ona yeni element yazılacaq. İndeks axtarışı, bu əməliyyat kimi, O(1) alqoritmik mürəkkəbliyinə malikdir . Elementi indekslə götürün (alın) LinkedList -də elementin götürülməsi digər əməliyyatların axtarışı ilə eyni prinsipə əsasən baş verəcək - sondan və ya başlanğıcdan məsafədən asılı olaraq, yəni. O(1) -dən O(n/2) -ə qədər . ArrayList -də , daha əvvəl dediyim kimi, serialda elementi indekslə tapmaq O(1) mürəkkəbliyinə malikdir . Elementi indekslə çıxarın (sil) LinkedList üçün onun iş prinsipi də burada işləyir: əvvəlcə element tapılır, sonra keçidlər üzərinə yazılır - elementin qonşuları bu elementə istinadları itirərək bir-birinə istinad etməyə başlayır, sonradan zibil yığan şəxs tərəfindən silinəcək. Yəni, alqoritmik mürəkkəblik hələ də eynidir - O(1) -dən O(n/2) . ArrayList üçün bu əməliyyat yeni element əlavə etmək (əlavə etmək) əməliyyatına daha çox bənzəyir. Əvvəlcə tələb olunan element tapılır - O(1) , sonra çıxarılır və yaranan boşluğu bağlamaq üçün onun sağında olan bütün elementlər bir vahid sola köçürülür. Silmə əməliyyatı əlavə əməliyyatı ilə eyni alqoritmik mürəkkəbliyə malik olacaq - O(1) -dən O(n) -a qədər . Silinmə siyahının sonuna nə qədər yaxın olarsa, onun alqoritmik mürəkkəbliyi bir o qədər az olar. Əslində bütün bunlar əsas əməliyyatlar idi. Xatırladım: bu iki siyahını müqayisə edərkən konkret hansı vəziyyətdən bəhs etdiyimizi aydınlaşdırmaq lazımdır və bundan sonra verilən suala birmənalı cavab verə bilərsiniz.

90. ArrayList HashSet-dən nə ilə fərqlənir?

ArrayListLinkedList-i əməliyyatlar baxımından müqayisə etmək olarsa - bu daha yaxşıdır - ArrayList -i HashSet ilə müqayisə etmək o qədər də asan deyil , çünki bunlar tamamilə fərqli kolleksiyalardır. Bir şirin yeməyi digəri ilə müqayisə edə bilərsiniz, ancaq ət yeməyi ilə işləyəcək - onlar çox fərqlidir. Bununla belə, onlar arasında bəzi fərqlər verməyə çalışacağam:
  • ArrayList List interfeysini , HashSet isə Set interfeysini həyata keçirir ;

  • ArrayList -də giriş element indeksi ilə mümkündür: get əməliyyatı O(1) alqoritmik mürəkkəbliyə malikdir və HashSet- də tələb olunan element yalnız kobud qüvvə ilə əldə edilə bilər və bu O(1) -dən O(n) -a qədərdir. ;

  • ArrayList dublikat elementlərə imkan verir. HashSet -də bütün elementlər unikaldır: analoqu kolleksiyada artıq mövcud olan HashSet- ə element əlavə etmək işləməyəcək (dublikatlar hashcode istifadə edərək yoxlanılır, buna görə də bu kolleksiyanın adı);

  • ArrayList daxili massivdən istifadə etməklə həyata keçirilir və HashSet daxili HashMap istifadə edərək həyata keçirilir ;

  • ArrayList elementlərin daxil edilmə qaydasını saxlayır, HashSet isə sıralanmamış çoxluqdur və elementlərin sırasını saxlamır;

  • ArrayList istənilən sayda boş dəyərə imkan verir (null), HashSet- ə yalnız bir null dəyər daxil edilə bilər (hər şeydən sonra elementlərin unikallığı).

91. Nəyə görə Java-da bu qədər müxtəlif dinamik massiv tətbiqləri mövcuddur?

Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  10-3-cü hissəYaxşı, bu daha çox fəlsəfi sualdır. Yaxşı, niyə bu qədər fərqli yeni texnologiyalar ortaya qoyurlar? Rahatlıq üçün. Əslində, çoxlu sayda dinamik massiv tətbiqləri ilə eynidir. Onların heç birini ən yaxşı və ya ideal adlandırmaq olmaz. Hər birinin müəyyən bir vəziyyətdə üstünlüyü var. Və bizim vəzifəmiz onların fərqlərini, güclü/zəif tərəflərini bilməkdir: düzgün vəziyyətdə ən uyğununu istifadə edə bilmək üçün.

92. Java-da niyə bu qədər müxtəlif açar-dəyər saxlama tətbiqləri mövcuddur?

Burada vəziyyət dinamik massiv tətbiqləri ilə eynidir. Ən yaxşısı yoxdur: hər birinin güclü və zəif tərəfləri var. Və biz, əlbəttə ki, güclü tərəflərimizdən maksimum istifadə etməliyik. Nümunə: bir çox çox yivli texnologiyaları ehtiva edən paralel paketin öz Concurrent kolleksiyaları var. Eyni ConcurrentHashMap adi HashMap ilə müqayisədə verilənlərlə çox yivli işin təhlükəsizliyində üstünlüyə malikdir , lakin çox yivli olmayan mühitdə sürəti itirir. Yaxşı, heç bir vəziyyətdə ən güclü olmayan tətbiqlər tədricən istifadəni dayandırır. Nümunə: Hashtable əvvəlcə mövzu üçün təhlükəsiz HashMap olmaq üçün nəzərdə tutulmuşdu , lakin ConcurrentHashMap çox yivli mühitdə onu üstələyib və Hashtable nəhayət unudulub və artıq istifadə olunmayıb.

93. Elementlər toplusunu necə çeşidləmək olar?

Demək lazım olan ilk şey odur ki, kolleksiya element sinfi Comparable interfeysini və onun compareTo metodunu tətbiq etməlidir . Və ya sizə Comparator metodu ilə Comaprator tətbiq edən sinif lazımdır . Bu yazıda onlar haqqında daha çox oxuya bilərsiniz . Hər iki üsul müəyyən tipli obyektlərin necə müqayisə olunacağını müəyyənləşdirir. Çeşidləmə zamanı bu çox vacibdir, çünki elementlərin müqayisə oluna biləcəyi prinsipi başa düşməlisiniz. Bunun əsas yolu , birbaşa çeşidləmək istədiyiniz sinifdə həyata keçirilən Comparable tətbiqidir . Eyni zamanda, Comparator- dan istifadə daha az yaygındır. Tutaq ki, siz müqayisə edilə bilən tətbiqi olmayan bəzi kitabxananın sinifindən istifadə edirsiniz , lakin siz onu hansısa şəkildə çeşidləməlisiniz. Bu sinfin kodunu dəyişdirə bilmədən (onu genişləndirmək istisna olmaqla), siz bu sinfin obyektlərini hansı prinsiplə müqayisə etmək istədiyinizi bildirdiyiniz Comparator tətbiqini yaza bilərsiniz. Və daha bir misal. Tutaq ki, eyni tipli obyektlərin çeşidlənməsi üçün sizə müxtəlif prinsiplər lazımdır, ona görə də müxtəlif situasiyalarda istifadə etdiyiniz bir neçə Müqayisəçi yazırsınız. Bir qayda olaraq, qutudan kənar bir çox sinif artıq Müqayisəli interfeysi - eyni String tətbiq edir . Əslində, onlardan istifadə edərkən, onları necə müqayisə edəcəyiniz barədə narahat olmaq lazım deyil. Siz sadəcə onları götürün və istifadə edin. Birinci və ən açıq yol , element sinfi müqayisəçisinə uyğun olaraq elementləri artıq çeşidlənmiş qaydada saxlayan TreeSet və ya TreeMap tipli kolleksiyadan istifadə etməkdir . Unutmayın ki, TreeMap açarları çeşidləyir, lakin dəyərləri deyil. Comparable yerinə Comparator tətbiqindən istifadə etsəniz , yaradıldıqdan sonra onun obyektini kolleksiya konstruktoruna ötürməli olacaqsınız:
TreeSet treeSet = new TreeSet(customComparator);
Bəs fərqli bir kolleksiyanız varsa nə olacaq? Necə çeşidləmək olar? Bu halda Collections utility sinfinin ikinci metodu uyğun gəlir - sort() metodu . O, statikdir, ona görə də sizə lazım olan tək şey sinfin adı və tələb olunan siyahının ötürüldüyü metoddur. Misal üçün:
Collections.sort(someList);
Əgər siz Comparable istifadə etmirsinizsə , əksinə Comparator tətbiqini istifadə edirsinizsə , onu ikinci parametr kimi keçirməlisiniz:
Collections.sort(someList, customComparator);
Nəticədə, keçmiş siyahının elementlərinin daxili sırası dəyişəcək: element müqayisəçisinə uyğun olaraq sıralanacaq. Qeyd edim ki, ötürülən elementlərin siyahısı dəyişkən olmalıdır, yəni. dəyişdirilə bilər, əks halda metod işləməyəcək və UnsupportedOperationException atılacaq . Üçüncü üsul olaraq , müqayisə edilə bilən tətbiq istifadə edilərsə, kolleksiyanın elementlərini çeşidləyən Stream sort əməliyyatından istifadə edə bilərsiniz :
someList = someList.stream().sorted().collect(Collectors.toList());
Əgər müqayisəçi :
someList = someList.stream().sorted(customComparator).collect(Collectors.toList());
Bu məqalədə Stream haqqında ətraflı oxuya bilərsiniz . Dördüncü üsul, qabarcıq çeşidləmə və ya birləşmə sort kimi çeşidləməni əl ilə həyata keçirməkdir .

ClassObject. Bərabər və HashCode

94. Java-da sinif obyektinin qısa təsvirini verin

Təhlilin ikinci hissəsində biz artıq Object sinifinin metodları haqqında danışdıq və sizə xatırladacağam ki, Obyekt sinfi Java-da bütün siniflərin sələfidir. Onun 11 metodu var ki, bu da müvafiq olaraq bütün siniflər tərəfindən miras alınır. Bütün 11 üsul haqqında məlumatı müzakirənin ikinci hissəsindəJava tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  10-4-cü hissə tapa bilərsiniz .

95. Java-da Equals və HashCode nə üçün istifadə olunur?

hashCode() bütün siniflər tərəfindən miras qalan Obyekt sinifinin metodudur . Onun vəzifəsi müəyyən bir obyekti təmsil edən bəzi nömrələr yaratmaqdır. Bu metoddan istifadə nümunəsi , cütün saxlanacağı daxili massivin (kovanın) xanasını təyin edəcək yerli hashkodu daha da müəyyən etmək üçün onun əsas obyektdə HashMap- da istifadəsidir . Biz təhlilin 9-cu hissəsində HashMap- ın işi haqqında ətraflı danışdıq , ona görə də bu barədə çox dayanmayacağıq. Həmçinin, bir qayda olaraq, bu üsul obyektlərin eyniliyini təyin etmək üçün onun əsas vasitələrindən biri kimi equals() metodunda istifadə olunur. equals() işi obyektləri müqayisə etmək və onların bərabər olub-olmadığını müəyyən etmək olan Object sinifinin metodudur . Bu üsul obyektləri müqayisə etmək lazım olan hər yerdə istifadə olunur, çünki == istifadə edərək adi müqayisə obyektlər üçün uyğun deyil, çünki yalnız onlara olan keçidləri müqayisə edir. Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  10-5-ci hissə

96. Java-da Equals və HashCode arasındakı müqavilə haqqında bizə məlumat verin?

İlk deyəcəyim odur ki, equals()hashCode() metodlarının düzgün işləməsi üçün onların düzgün şəkildə ləğv edilməsi lazımdır. Bundan sonra onlar qaydalara əməl etməlidirlər:
  • Bərabər vasitəsilə müqayisənin doğru qaytardığı eyni obyektlərin eyni hash kodları olmalıdır ;
  • eyni hash kodları olan obyektlər həmişə bərabər olmaya bilər.
Bu nöqtədə təhlilin növbəti hissəsinə qədər fasilə verəcəyik!Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  10-6 hissə
Seriyadakı digər materiallar:
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION