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. 15-ci hissə

Qrupda dərc edilmişdir
Salam Salam! Java tərtibatçısı nə qədər bilməlidir? Bu mövzuda uzun müddət mübahisə edə bilərsiniz, amma həqiqət budur ki, müsahibədə sizi nəzəriyyə tam şəkildə idarə edəcək. Hətta işinizdə istifadə etmək imkanınız olmayacaq bilik sahələrində belə. Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  15-1 hissəYaxşı, əgər siz başlanğıcsınızsa, nəzəri bilikləriniz çox ciddi qəbul ediləcəkdir. Təcrübə və böyük nailiyyətlər hələ olmadığından, bilik bazasının gücünü yoxlamaq qalır. Bu gün biz Java tərtibatçıları üçün ən populyar müsahibə suallarını araşdıraraq bu bazanı gücləndirməyə davam edəcəyik. Gəlin uçaq!

Java nüvəsi

9. Java-da statik və dinamik bağlama arasında fərq nədir?

Mən artıq bu məqalənin 18-ci sualında statik və dinamik polimorfizmlə bağlı bu suala cavab vermişəm , onu oxumağı məsləhət görürəm.

10. İnterfeysdə özəl və ya qorunan dəyişənlərdən istifadə etmək mümkündürmü?

Yox bacarmazsan. Çünki siz interfeys elan etdiyiniz zaman Java kompilyatoru avtomatik olaraq interfeys metodlarından əvvəl ictimaimücərrəd açar sözləri , məlumat üzvlərindən əvvəl isə ictimai , statikyekun açar sözləri əlavə edir. Əslində, private və ya protected əlavə etsəniz , konflikt yaranacaq və kompilyator giriş modifikatorundan şikayət edəcək: “Burada '<seçilmiş dəyişdirici>' dəyişdiricisinə icazə verilmir.” Nə üçün kompilyator ictimai , statikfinal əlavə edir. interfeysdəki dəyişənlər? Gəlin bunu anlayaq:
  • ictimai - interfeys müştəriyə obyektlə qarşılıqlı əlaqə yaratmağa imkan verir. Dəyişənlər açıq olmasaydı, müştərilərin onlara girişi olmazdı.
  • statik - interfeyslər yaradıla bilməz (daha doğrusu, onların obyektləri), buna görə də dəyişən statikdir.
  • final - interfeys 100% abstraksiyaya nail olmaq üçün istifadə edildiyi üçün dəyişən son formaya malikdir (və dəyişdirilməyəcək).

11. Classloader nədir və nə üçün istifadə olunur?

Classloader - və ya Class Loader - Java siniflərinin yüklənməsini təmin edir. Daha dəqiq desək, yüklənmə onun nəsilləri tərəfindən təmin edilir - xüsusi sinif yükləyiciləri, çünki ClassLoader özü mücərrəddir. Hər dəfə .class faylı yükləndikdə, məsələn, müvafiq sinfin konstruktoru və ya statik metodunu çağırdıqdan sonra bu hərəkət ClassLoader sinfinin nəsillərindən biri tərəfindən yerinə yetirilir . Üç növ varis var:
  1. Bootstrap ClassLoader əsas yükləyicidir, JVM səviyyəsində həyata keçirilir və JVM nüvəsinin bir hissəsi olduğundan və yerli kodda yazılmış olduğundan, işləmə zamanı mühiti ilə bağlı rəy yoxdur. Bu yükləyici bütün digər ClassLoader instansiyalarının valideyni kimi xidmət edir.

    Əsasən JDK daxili siniflərinin, adətən rt.jar və $JAVA_HOME/jre/lib kataloqunda yerləşən digər əsas kitabxanaların yüklənməsinə cavabdehdir . Fərqli platformalarda bu sinif yükləyicisinin fərqli tətbiqləri ola bilər.

  2. Extension Classloader , əsas yükləyici sinifinin nəslindən olan genişləndirici yükləyicidir. Standart Java baza siniflərinin genişləndirilməsinin yüklənməsinə diqqət yetirir. JDK genişləndirmələri kataloqundan yüklənir, adətən $JAVA_HOME/lib/ext və ya java.ext.dirs sistem mülkiyyətində qeyd olunan hər hansı digər kataloq (bu seçim genişləndirmələrin yüklənməsinə nəzarət etmək üçün istifadə edilə bilər).

  3. System ClassLoader bütün proqram səviyyəli siniflərin JVM-ə yüklənməsinə diqqət yetirən JRE səviyyəsində həyata keçirilən sistem yükləyicisidir. O, sinif mühiti dəyişəni -classpath və ya -cp komanda xətti seçimində tapılan faylları yükləyir.

Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  15-2-ci hissəSinif yükləyiciləri Java iş vaxtının bir hissəsidir. JVM bir sinif tələb etdiyi anda, sinif yükləyicisi sinfi tapmağa və sinfin tam adından istifadə edərək sinif tərifini işləmə müddətinə yükləməyə çalışır. java.lang.ClassLoader.loadClass() metodu iş vaxtında sinif tərifinin yüklənməsinə cavabdehdir. Tam adı əsasında sinfi yükləməyə çalışır. Sinif hələ yüklənməyibsə, o, sorğunu ana sinif yükləyicisinə həvalə edir. Bu proses rekursiv şəkildə baş verir və belə görünür:
  1. System Classloader öz keşində sinfi tapmağa çalışır.

    • 1.1. Sinif tapılarsa, yükləmə uğurla tamamlandı.

    • 1.2. Sinif tapılmadıqda, yükləmə Extension Classloader-ə həvalə edilir.

  2. Extension Classloader sinfi öz keşində tapmağa çalışır.

    • 2.1. Sinif tapılarsa, müvəffəqiyyətlə tamamlanır.

    • 2.2. Sinif tapılmazsa, yükləmə Bootstrap Classloader-ə həvalə edilir.

  3. Bootstrap Classloader sinfi öz keşində tapmağa çalışır.

    • 3.1. Sinif tapılarsa, yükləmə uğurla tamamlandı.

    • 3.2. Sinif tapılmadıqda, əsas Bootstrap Classloader onu yükləməyə çalışacaq.

  4. Yüklənirsə:

    • 4.1. Uğurlu - sinifin yüklənməsi tamamlandı.

    • 4.2. Əgər uğursuz olarsa, idarəetmə Extension Classloader-ə ötürülür.

  5. 5. Extension Classloader sinfi yükləməyə çalışır və əgər yüklənirsə:

    • 5.1. Uğurlu - sinifin yüklənməsi tamamlandı.

    • 5.2. Uğurlu olmadıqda, idarəetmə System Classloader-ə ötürülür.

  6. 6. System Classloader sinfi yükləməyə çalışır və əgər yüklənirsə:

    • 6.1. Uğurlu - sinifin yüklənməsi tamamlandı.

    • 6.2. Uğurla keçmədi - istisna yaradıldı - ClassNotFoundException.

Sinif yükləyiciləri mövzusu genişdir və laqeyd edilməməlidir. Bununla daha ətraflı tanış olmaq üçün sizə bu məqaləni oxumağı məsləhət görürəm və biz uzanmayacağıq və davam edəcəyik.

12. Run-Time Məlumat Sahələri hansılardır?

Run-Time Data Ares - JVM iş vaxtı məlumat sahələri. JVM proqramın icrası zamanı lazım olan bəzi iş vaxtı məlumat sahələrini müəyyənləşdirir. Onlardan bəziləri JVM işə salındıqda yaradılır. Digərləri ip-lokaldır və yalnız ip yaradıldıqda yaradılır (və iplik məhv edildikdə məhv edilir). JVM iş vaxtı məlumat sahələri belə görünür: Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  15-3-cü hissə
  • PC Qeydiyyatı hər bir başlıq üçün lokaldir və ipin hazırda icra etdiyi JVM təlimatının ünvanını ehtiva edir.

  • JVM Stack yerli dəyişənlər və müvəqqəti nəticələr üçün yaddaş kimi istifadə olunan yaddaş sahəsidir. Hər bir ipin öz ayrıca yığını var: iplik bitən kimi bu yığın da məhv olur. Qeyd etmək lazımdır ki, yığının yığın üzərində üstünlüyü performansdır, yığın isə saxlama miqyasında əlbəttə ki, üstünlüyə malikdir.

  • Native Method Stack - Doğma (Java olmayan) metodları yerinə yetirmək üçün JVM yığınına bənzər məlumat elementlərini saxlayan mövzu başına məlumat sahəsi.

  • Heap - bütün mövzular tərəfindən iş vaxtında yaradılan obyektləri, sinif metadatalarını, massivləri və s. ehtiva edən bir mağaza kimi istifadə olunur. Bu sahə JVM işə salındıqda yaradılır və bağlandıqda məhv edilir.

  • Metod sahəsi - Bu iş vaxtı sahəsi bütün mövzular üçün ümumidir və JVM işə salındıqda yaradılır. O, hər bir sinif üçün strukturları saxlayır, məsələn, Runtime Constant Pool, konstruktorlar və metodlar üçün kod, metod məlumatları və s.

13. Dəyişməz obyekt nədir?

Məqalənin bu hissəsində , 14 və 15-ci suallarda artıq bu sualın cavabı var, ona görə də vaxtınızı itirmədən nəzər salın.

14. String sinfinin özəlliyi nədir?

Əvvəllər təhlildə biz String-in müəyyən xüsusiyyətləri haqqında dəfələrlə danışdıq (bunun üçün ayrıca bölmə var idi). İndi String xüsusiyyətlərini ümumiləşdirək :
  1. Java-da ən populyar obyektdir və müxtəlif məqsədlər üçün istifadə olunur. İstifadə tezliyi baxımından o, hətta ibtidai növlərdən də geri qalmır.

  2. Bu sinfin obyekti new açar sözündən istifadə etmədən yaradıla bilər - birbaşa dırnaqlar vasitəsilə String str = “string”; .

  3. String dəyişməz bir sinifdir : bu sinfin obyektini yaratarkən onun məlumatlarını dəyişdirmək olmaz (müəyyən bir sətirə + “başqa sətir” əlavə etdikdə, nəticədə yeni, üçüncü sətir əldə edəcəksiniz). String sinifinin dəyişməzliyi onu iplə təhlükəsiz edir.

  4. String sinfi yekunlaşdırılıb ( son dəyişdiriciyə malikdir ), ona görə də onu miras almaq mümkün deyil.

  5. String öz simli hovuzuna, yaratdığı sətir dəyərlərini önbelleğe alan yığında yaddaş sahəsinə malikdir . Serialın bu hissəsində 62-ci sualda simli hovuzu təsvir etdim.

  6. Java-da sətirlərlə işləmək üçün nəzərdə tutulmuş String analoqları var - StringBuilderStringBuffer , lakin onların dəyişkən olması fərqi ilə. Bu məqalədə onlar haqqında daha çox oxuya bilərsiniz .

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

15. Tip kovariantlığı nədir?

Kovariantlığı başa düşmək üçün bir nümunəyə baxacağıq. Deyək ki, bizim heyvan sinifimiz var:
public class Animal {
 void voice() {
   System.out.println("*тишина*");
 }
}
Və onu genişləndirən bəzi İt sinfi :
public class Dog extends Animal {

 @Override
 public void voice() {
   System.out.println("Гав, гав, гав!!!");
 }
}
Xatırladığımız kimi, varis tipli obyektləri ana tipə asanlıqla təyin edə bilərik:
Animal animal = new Dog();
Bu polimorfizmdən başqa bir şey olmayacaq. Rahat, çevik, elə deyilmi? Yaxşı, bəs heyvanların siyahısı? Ümumi Heyvanlı siyahıya İt obyektləri olan siyahı verə bilərikmi ?
List<Dog> dogs = new ArrayList<>();
List<Animal> animals = dogs;
Bu halda, itlərin siyahısını heyvanlar siyahısına təyin etmək üçün sətir qırmızı rənglə vurğulanacaq, yəni. kompilyator bu kodu ötürməyəcək. Bu tapşırığın kifayət qədər məntiqli görünməsinə baxmayaraq (axı biz Animal tipli dəyişənə Dog obyektini təyin edə bilərik ), bunu etmək mümkün deyil. Bunun səbəbi, icazə verildiyi təqdirdə, siyahıda yalnız İtlərimizin olduğunu düşünərkən, ilkin olaraq İt olmaq üçün nəzərdə tutulmuş siyahıya Heyvan obyektini daxil edə bilərik . Və sonra, məsələn, itlər siyahısından obyekti götürmək üçün get() metodundan istifadə edəcəyik , bunun it olduğunu düşünərək, Heyvanda olmayan It obyektinin hansısa metodunu çağıracağıq . Və başa düşdüyünüz kimi, bu mümkün deyil - bir səhv baş verəcəkdir. Ancaq xoşbəxtlikdən, tərtibçi nəsillərin siyahısını valideynlər siyahısına (və əksinə) təyin etməklə bu məntiqi səhvi qaçırmır. Java-da siz yalnız uyğun generiklərlə dəyişənlərin siyahısına siyahı obyektləri təyin edə bilərsiniz. Buna invariasiya deyilir. Əgər bunu edə bilsəydilər, buna kovariasiya deyilirdi. Yəni, biz ArrayList<İt> tipli obyekti List<Animal> tipli dəyişənə təyin edə bilsək, kovariasiyadır . Belə çıxır ki, Java-da kovariasiya dəstəklənmir? Necə olursa olsun! Ancaq bu, özünəməxsus şəkildə edilir. Dizayn nə üçün istifadə olunur ? Heyvanı uzadır . O, siyahı obyektini təyin etmək istədiyimiz dəyişənin ümumisi ilə, nəslin ümumisi ilə yerləşdirilir. Bu ümumi konstruksiya Heyvan növünün nəslindən olan hər hansı bir növün edəcəyini bildirir (və Heyvan növü də bu ümumiləşdirməyə aiddir). Öz növbəsində Heyvan təkcə sinif deyil, həm də interfeys ola bilər ( genişlənir açar sözünə aldanmayın ). Əvvəlki tapşırığımızı belə edə bilərik: Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  15-5-ci hissə
List<Dog> dogs = new ArrayList<>();
List<? extends Animal> animals = dogs;
Nəticədə siz IDE-də görəcəksiniz ki, kompilyator bu konstruksiyadan şikayət etməyəcək. Bu dizaynın funksionallığını yoxlayaq. Tutaq ki, ona keçən bütün heyvanların səs çıxarmasına səbəb olan bir üsulumuz var:
public static void animalsVoice(List<? extends Animal> animals) {
 for (Animal animal : animals) {
   animal.voice();
 }
}
Gəlin ona itlərin siyahısını verək:
List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog());
dogs.add(new Dog());
dogs.add(new Dog());
animalsVoice(dogs);
Konsolda aşağıdakı çıxışı görəcəyik:
vay vay vay!!! vay vay vay!!! vay vay vay!!!
Bu o deməkdir ki, kovariasiyaya bu yanaşma uğurla işləyir. Qeyd edim ki, bu generik siyahıya daxildir ? genişləndirir Animal biz heç bir növ yeni məlumat daxil edə bilmərik: nə İt növü , nə də Heyvan tipi :
List<Dog> dogs = new ArrayList<>();
List<? extends Animal> animals = dogs;
animals.add(new Dog());
dogs.add(new Animal());
Əslində, son iki sətirdə kompilyator qırmızı rəngdə obyektlərin daxil edilməsini vurğulayacaqdır. Bu onunla əlaqədardır ki, biz ümumi <? uzadılır Animal> . Mən kontravariasiyaJava tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  15-6 hissə haqqında da danışmaq istərdim , çünki adətən bu anlayış həmişə kovariasiya ilə birlikdə gedir və bir qayda olaraq onlar haqqında birlikdə soruşulur. Bu konsept kovariasiyanın bir qədər əksidir, çünki bu konstruksiya varis tipindən istifadə edir. Tutaq ki, biz Dog obyektinin əcdadları olmayan tipli obyektlərin siyahısı təyin edilə bilən siyahı istəyirik . Lakin onların konkret hansı növlər olacağını əvvəlcədən bilmirik. Bu halda, forma bir tikinti ? bütün növlərin uyğun olduğu super it - İt sinifinin əcdadları :
List<Animal> animals = new ArrayList<>();
List<? super Dog> dogs = animals;
dogs.add(new Dog());
dogs.add(new Dog());
Belə bir ümumi ilə siyahıya Dog tipli obyektləri etibarlı şəkildə əlavə edə bilərik , çünki hər halda onun əcdadlarından hər hansı birinin tətbiq edilmiş bütün üsulları var. Ancaq Heyvan tipli bir obyekt əlavə edə bilməyəcəyik , çünki içəridə bu tip obyektlərin olacağına əminlik yoxdur, məsələn, İt deyil . Axı biz bu siyahının bir elementindən Animal- da olmayan Dog sinfinin metodunu tələb edə bilərik . Bu halda kompilyasiya xətası baş verəcək. Həmçinin, əvvəlki metodu tətbiq etmək istəsək, lakin bu ümumi ilə:
public static void animalsVoice(List<? super Dog> dogs) {
 for (Dog dog : dogs) {
   dog.voice();
 }
}
for loopunda tərtib xətası alacağıq , çünki qaytarılan siyahıda Dog tipli obyektlərin olduğuna və onun metodlarından istifadə etməkdə sərbəst olduğuna əmin ola bilmərik . Bu siyahıda dogs.get(0) metodunu çağırsaq . - Object tipli bir obyekt alacağıq . Yəni, animalsVoice() metodunun işləməsi üçün ən azı tip məlumatlarını daraltmaqla kiçik manipulyasiyalar əlavə etməliyik:
public static void animalsVoice(List<? super Dog> dogs) {
 for (Object obj : dogs) {
   if (obj instanceof Dog) {
     Dog dog = (Dog) obj;
     dog.voice();
   }
 }
}
Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  15-7 hissə

16. Object sinfində necə metodlar var?

Seriyanın bu hissəsində , 11-ci bənddə, mən bu suala artıq cavab vermişəm, ona görə də, hələ etməmisinizsə, oxumağınızı şiddətlə tövsiyə edirəm. Bu günümüzü burada bitirəcəyik. Növbəti hissədə görüşənədək! Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  15-8 hissə
Seriyadakı digər materiallar:
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION