JavaRush /Java блогы /Random-KK /Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жа...
Константин
Деңгей

Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау. 15-бөлім

Топта жарияланған
Сәлем Сәлем! Java әзірлеушісі қанша білуі керек? Сіз бұл мәселе бойынша ұзақ уақыт бойы дауласуға болады, бірақ шындық - сұхбатта сізді теория толығымен жетелейді. Сіздің жұмысыңызда қолдануға мүмкіндік болмайтын білім салаларында да. Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  15 - 1 бөлімАл, егер сіз бастаушы болсаңыз, сіздің теориялық біліміңіз өте маңызды болады. Әзірге тәжірибе мен үлкен жетістіктер болмағандықтан, білім базасының беріктігін тексеру ғана қалды. Бүгін біз Java әзірлеушілері үшін ең танымал сұхбат сұрақтарын қарастыру арқылы осы базаны нығайтуды жалғастырамыз. Ұшайық!

Java ядросы

9. Java тіліндегі статикалық және динамикалық байланыстырудың айырмашылығы неде?

Мен бұл сұраққа осы мақаланың 18-сұрағында статикалық және динамикалық полиморфизм туралы жауап бердім , мен оны оқуға кеңес беремін.

10. Интерфейсте жеке немесе қорғалған айнымалыларды қолдануға болады ма?

Жоқ болмайды. Интерфейсті жариялаған кезде Java компиляторы интерфейс әдістерінің алдында жалпы және дерексіз кілт сөздерді және деректер мүшелерінің алдында жалпы , статикалық және соңғы кілт сөздерді автоматты түрде қосады. Шын мәнінде, егер сіз private немесе protected қоссаңыз , қақтығыс туындайды және компилятор келесі хабармен қатынас модификаторына шағымданады: «'<таңдалған модификатор>' модификаторына бұл жерде рұқсат етілмейді. Неліктен компилятор public , static және final қосады. интерфейстегі айнымалылар? Оны анықтап көрейік:
  • public – интерфейс клиентке an objectімен әрекеттесуге мүмкіндік береді. Егер айнымалылар жалпыға қолжетімді болмаса, клиенттер оларға қол жеткізе алмас еді.
  • статикалық - интерфейстерді құру мүмкін емес (дәлірек айтқанда, олардың an objectілері), сондықтан айнымалы статикалық.
  • қорытынды - интерфейс 100% абстракцияға қол жеткізу үшін пайдаланылғандықтан, айнымалы өзінің соңғы түріне ие (және өзгертілмейді).

11. Classloader дегеніміз не және ол не үшін қолданылады?

Classloader - немесе Class Loader - Java сыныптарын жүктеуді қамтамасыз етеді. Дәлірек айтқанда, жүктеу оның ұрпақтарымен қамтамасыз етіледі - белгілі бір класты тиегіштер, өйткені ClassLoader өзі дерексіз. .class файлы жүктелген сайын, мысалы, конструкторды немесе сәйкес сыныптың статикалық әдісін шақырғаннан кейін, бұл әрекет ClassLoader класының ұрпақтарының бірі арқылы орындалады . Мұрагерлердің үш түрі бар:
  1. Bootstrap ClassLoader — JVM деңгейінде іске асырылған және орындалу ортасынан кері байланысы жоқ негізгі жүктеуші, өйткені ол JVM ядросының бөлігі және жергілікті codeта жазылған. Бұл жүктегіш барлық басқа ClassLoader даналарының ата-анасы ретінде қызмет етеді.

    Негізінен JDK ішкі сыныптарын, әдетте rt.jar және $JAVA_HOME/jre/lib каталогында орналасқан басқа негізгі кітапханаларды жүктеуге жауапты . Әртүрлі платформаларда осы класс жүктеушісінің әртүрлі іске асырулары болуы мүмкін.

  2. Extension Classloader - кеңейту жүктеушісі, негізгі жүктеуші класының ұрпағы. Стандартты Java базалық сыныптарының кеңейтімін жүктеуге қамқорлық жасайды. JDK кеңейтімдері каталогынан жүктеледі, әдетте $JAVA_HOME/lib/ext немесе java.ext.dirs жүйелік сипатында аталған кез келген басқа каталог (бұл опцияны кеңейтімдердің жүктелуін басқару үшін пайдалануға болады).

  3. System ClassLoader — JVM жүйесіне қолданба деңгейіндегі барлық сыныптарды жүктеуді қамтамасыз ететін JRE деңгейінде жүзеге асырылған жүйелік жүктеуші. Ол сынып ортасының айнымалы -classpath немесе -cp пәрмен жолы опциясында табылған файлдарды жүктейді.

Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  15 - 2 бөлімКласс жүктеушілері Java орындалу уақытының бөлігі болып табылады. JVM сыныпты сұраған кезде, сынып жүктеушісі сыныпты табуға және сыныптың толық жарамды атауын пайдаланып сынып анықтамасын орындау уақытына жүктеуге тырысады. java.lang.ClassLoader.loadClass() әдісі орындалу уақытында сынып анықтамасын жүктеуге жауап береді. Ол толық аты негізінде сыныпты жүктеуге тырысады. Егер сынып әлі жүктелмеген болса, ол сұрауды ата-аналық сынып жүктеушісіне береді. Бұл процесс рекурсивті түрде жүреді және келесідей көрінеді:
  1. System Classloader өзінің кэшінде сыныпты табуға тырысады.

    • 1.1. Егер сынып табылса, жүктеу сәтті аяқталды.

    • 1.2. Егер сынып табылмаса, жүктеу Extension Classloader-ге беріледі.

  2. Extension Classloader сыныпты өзінің кэшінде табуға тырысады.

    • 2.1. Егер сынып табылса, ол сәтті аяқталады.

    • 2.2. Егер сынып табылмаса, жүктеу Bootstrap Classloader-ге беріледі.

  3. Bootstrap Classloader сыныпты өзінің кэшінде табуға тырысады.

    • 3.1. Егер сынып табылса, жүктеу сәтті аяқталды.

    • 3.2. Егер сынып табылмаса, негізгі Bootstrap Classloader оны жүктеуге тырысады.

  4. Жүктеп жатса:

    • 4.1. Сәтті - сыныпты жүктеу аяқталды.

    • 4.2. Егер ол сәтсіз болса, басқару кеңейтім класс жүктеушісіне тасымалданады.

  5. 5. Extension Classloader сыныпты жүктеуге тырысады, ал егер жүктелсе:

    • 5.1. Сәтті - сыныпты жүктеу аяқталды.

    • 5.2. Егер ол сәтсіз болса, басқару Жүйе Класс жүктеушісіне тасымалданады.

  6. 6. System Classloader класты жүктеуге тырысады, ал егер жүктелсе:

    • 6.1. Сәтті - сыныпты жүктеу аяқталды.

    • 6.2. Сәтті өтпеді - ерекше жағдай жасалды - ClassNotFoundException.

Сынып жүктегіштері тақырыбы өте кең және оны назардан тыс қалдыруға болмайды. Онымен толығырақ танысу үшін мен сізге осы мақаланы оқуға кеңес беремін , және біз кідірмейміз және әрі қарай жүреміз.

12. Орындалу уақыты деректер аймақтары дегеніміз не?

Run-Time Data Ares - JVM орындалу уақытының деректер аймақтары. JVM бағдарламаны орындау кезінде қажет кейбір орындалу уақытының деректер аймақтарын анықтайды. Олардың кейбіреулері JVM іске қосылғанда жасалады. Басқалары ағынды жергілікті болып табылады және ағын жасалғанда ғана жасалады (және жіп жойылған кезде жойылады). JVM жұмыс уақыты деректер аймақтары келесідей көрінеді: Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  15 - 3 бөлім
  • ДК тізілімі әрбір ағынға жергілікті болып табылады және ағын қазіргі уақытта орындалып жатқан JVM нұсқаулығының мекенжайын қамтиды.

  • JVM Stack — жергілікті айнымалылар мен уақытша нәтижелерді сақтау ретінде пайдаланылатын жад аймағы. Әрбір ағынның өзінің жеке стекі бар: ағын аяқтала салысымен бұл стек де жойылады. Айта кету керек, стектің үймеден артықшылығы өнімділік, ал үйменің сақтау масштабында артықшылығы бар.

  • Native Method Stack - жергілікті (Java емес) әдістерді орындау үшін JVM стекіне ұқсас деректер элементтерін сақтайтын әр ағындық деректер аймағы.

  • Үйме – барлық ағындар орындалу уақытында жасалған нысандарды, класс метадеректерін, массивтерді және т.б. қамтитын қойма ретінде пайдаланылады. Бұл аймақ JVM іске қосылғанда жасалады және ол өшірілгенде жойылады.

  • Әдіс аймағы - бұл орындалу аймағы барлық ағындар үшін ортақ және JVM іске қосылғанда жасалады. Ол әр сыныпқа арналған құрылымдарды сақтайды, мысалы, Runtime Constant Pool, конструкторлар мен әдістерге арналған code, әдіс деректері және т.б.

13. Өзгермейтін an object дегеніміз не?

Мақаланың осы бөлігінде , 14 және 15-сұрақтарда бұл сұраққа жауап бар, сондықтан уақытты босқа өткізбей қараңыз.

14. String класының ерекшелігі неде?

Бұрын талдау барысында біз String-тің белгілі бір мүмкіндіктері туралы бірнеше рет айтқан болатынбыз (бұл үшін бөлек бөлім болған). Енді String мүмкіндіктерін қорытындылайық :
  1. Бұл Java тіліндегі ең танымал нысан және әртүрлі мақсаттарда қолданылады. Қолдану жиілігі бойынша ол тіпті қарабайыр түрлерден де кем түспейді.

  2. Бұл сыныптың an objectісін new кілт сөзін қолданбай-ақ жасауға болады - тікелей тырнақшалар арқылы String str = “string”; .

  3. Жол – өзгермейтін класс : осы класстың an objectісін жасау кезінде оның деректерін өзгерту мүмкін емес (белгілі бір жолға + «басқа жолды» қосқанда, нәтижесінде жаңа, үшінші жолды аласыз). String класының өзгермейтіндігі оны ағынды қауіпсіз етеді.

  4. String класы аяқталды ( соңғы модификаторы бар ), сондықтан оны мұраға алу мүмкін емес.

  5. Жолдың өз жолдық пулы, өзі жасайтын жол мәндерін кэштейтін үймедегі жады аймағы бар . Серияның осы бөлігінде , 62-сұрақта, мен жол пулын сипаттадым.

  6. Java-да String аналогтары бар , сонымен қатар жолдармен жұмыс істеуге арналған - StringBuilder және StringBuffer , бірақ айырмашылығы олар өзгермелі. Олар туралы толығырақ осы мақалада оқи аласыз .

Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  15 - 4 бөлім

15. Типтік ковариация дегеніміз не?

Ковариантты түсіну үшін мысалды қарастырамыз. Бізде жануарлар класы бар делік:
public class Animal {
 void voice() {
   System.out.println("*тишина*");
 }
}
Және кейбір ит класы оны кеңейтеді :
public class Dog extends Animal {

 @Override
 public void voice() {
   System.out.println("Гав, гав, гав!!!");
 }
}
Еске салсақ, мұрагер түрінің нысандарын ата-ана түріне оңай тағайындай аламыз:
Animal animal = new Dog();
Бұл полиморфизмнен басқа ештеңе болмайды. Ыңғайлы, икемді емес пе? Ал, жануарлардың тізімі ше? Жалпы Animal бар тізімге Dog нысандары бар тізім бере аламыз ба ?
List<Dog> dogs = new ArrayList<>();
List<Animal> animals = dogs;
Бұл жағдайда жануарлар тізіміне иттердің тізімін тағайындау жолының асты қызыл түспен сызылады, яғни. компилятор бұл codeты өткізбейді. Бұл тапсырма әбден қисынды болып көрінгенімен (ақыр соңында, Animal түріндегі айнымалыға Dog нысанын тағайындай аламыз ), оны орындау мүмкін емес. Себебі, рұқсат етілсе, біз тізімде тек иттер бар деп ойлай отырып, бастапқыда ит болуға арналған тізімге Animal нысанын енгізе алатын едік . Содан кейін, мысалы, ит деп ойлап, иттер тізімінен нысанды алу үшін get() әдісін қолданамыз және ондағы Dog нысанының жануарда жоқ қандай да бір әдісін шақырамыз . Сіз түсінгендей, бұл мүмкін емес - қате пайда болады. Бірақ, бақытымызға орай, компилятор ата-аналар тізіміне ұрпақтар тізімін тағайындау арқылы бұл логикалық қатені жіберіп алмайды (және керісінше). Java тілінде сәйкес генериктері бар айнымалылар тізіміне тізім нысандарын ғана тағайындай аласыз. Бұл инвариация деп аталады. Егер олар мұны істей алса, ол ковариация деп аталады. Яғни, егер ArrayList<Dog> түріндегі нысанды List<Animal> түріндегі айнымалыға орната алатын болсақ, ковариация болып табылады . Java-да ковариацияға қолдау көрсетілмейді екен? Қалай болса да! Бірақ бұл өзіндік ерекше жолмен жасалады. Дизайн не үшін қолданылады ? Жануарды ұзартады . Ол тізім нысанын орнатқымыз келетін айнымалының жалпы белгісімен, ұрпақтың жалпыламасымен орналастырылған. Бұл жалпы құрылым Animal түрінің ұрпағы болып табылатын кез келген түр жасайтынын білдіреді (және Animal түрі де осы жалпыламаға жатады). Өз кезегінде Animal тек сынып қана емес, сонымен қатар интерфейс болуы мүмкін ( extens кілт сөзіне алданып қалмаңыз ). Алдыңғы тапсырмамызды келесідей орындай аламыз: Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  15 - 5 бөлім
List<Dog> dogs = new ArrayList<>();
List<? extends Animal> animals = dogs;
Нәтижесінде IDE-де компилятор бұл құрылысқа шағымданbyteынын көресіз. Осы дизайнның функционалдығын тексерейік. Бізде оған өткен барлық жануарлардың дыбыс шығаруына себеп болатын әдіс бар делік:
public static void animalsVoice(List<? extends Animal> animals) {
 for (Animal animal : animals) {
   animal.voice();
 }
}
Оған иттердің тізімін берейік:
List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog());
dogs.add(new Dog());
dogs.add(new Dog());
animalsVoice(dogs);
Консольде біз келесі нәтижені көреміз:
Уф уфф!!! Уф уфф!!! Уф уфф!!!
Бұл ковариацияның бұл тәсілі сәтті жұмыс істейтінін білдіреді. Айта кетейін, бұл генерик тізімге енгізілген ? extensions Animal біз кез келген түрдегі жаңа деректерді енгізе алмаймыз: ит түрі де, жануар түрі де емес :
List<Dog> dogs = new ArrayList<>();
List<? extends Animal> animals = dogs;
animals.add(new Dog());
dogs.add(new Animal());
Шын мәнінде, соңғы екі жолда компилятор нысандарды қызыл түспен кірістіруді ерекшелейді. Бұл қандай типтегі нысандар тізімі жалпы <<? Animal> кеңейтеді . Мен контрварианстықJava әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  15 - 6 бөлім туралы да айтқым келеді , өйткені әдетте бұл ұғым әрқашан коварианспен бірге жүреді және әдетте олар туралы бірге сұралады. Бұл концепция коварианттыққа біршама қарама-қарсы, өйткені бұл құрылым мұрагер түрін пайдаланады. Біз Dog нысанының ата-бабалары болып табылмайтын типтік нысандардың тізімін тағайындауға болатын тізімді алғымыз келеді делік . Дегенмен, олардың нақты қандай түрлері болатынын алдын ала білмейміз. Бұл жағдайда пішіннің құрылысы ? супер ит , оның барлық түрлері қолайлы - ит класының тектері :
List<Animal> animals = new ArrayList<>();
List<? super Dog> dogs = animals;
dogs.add(new Dog());
dogs.add(new Dog());
Біз Dog типті нысандарды тізімге осындай генерикпен қауіпсіз түрде қоса аламыз , өйткені кез келген жағдайда оның кез келген ата-бабаларының барлық енгізілген әдістері бар. Бірақ біз Animal түріндегі нысанды қоса алмаймыз , өйткені оның ішінде, мысалы, Dog емес, осы түрдегі нысандар болатынына сенімділік жоқ . Ақыр соңында, біз осы тізімнің элементінен Animal- да жоқ Dog класының әдісін сұрай аламыз . Бұл жағдайда компиляция қатесі орын алады. Сондай-ақ, егер біз алдыңғы әдісті жүзеге асырғымыз келсе, бірақ осы жалпы әдіспен:
public static void animalsVoice(List<? super Dog> dogs) {
 for (Dog dog : dogs) {
   dog.voice();
 }
}
for циклінде компиляция қатесін алатын едік , өйткені қайтарылған тізімде Dog түріндегі нысандар бар екеніне және оның әдістерін еркін пайдалануға болатынына сенімді бола алмаймыз. Бұл тізімдегі dogs.get(0) әдісін шақырсақ . - Object типті an objectіні аламыз . Яғни, animalsVoice() әдісі жұмыс істеуі үшін , кем дегенде, деректер түрін тарылту арқылы шағын манипуляцияларды қосу керек:
public static void animalsVoice(List<? super Dog> dogs) {
 for (Object obj : dogs) {
   if (obj instanceof Dog) {
     Dog dog = (Dog) obj;
     dog.voice();
   }
 }
}
Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  15 - 7 бөлім

16. Object класында әдістер қалай бар?

Серияның осы бөлігінде , 11-параграфта мен бұл сұраққа жауап бердім, сондықтан мен оны әлі жасамаған болсаңыз, оны оқуға кеңес беремін. Міне, бүгінгі жұмысымызды аяқтаймыз. Келесі бөлімде кездескенше! Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  15 - 8 бөлім
Сериядағы басқа материалдар:
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION