JavaRush /Java блогу /Random-KY /Java иштеп чыгуучусу үчүн интервьюдан алынган суроолордун...
Константин
Деңгээл

Java иштеп чыгуучусу үчүн интервьюдан алынган суроолордун жана жооптордун анализи. 15-бөлүк

Группада жарыяланган
Салам Салам! Java иштеп чыгуучусу канча бorши керек? Сиз бул маселе боюнча көпкө чейин талаша аласыз, бирок чындык, интервьюда сиз толугу менен теорияга жетесиз. Ал тургай, сиздин ишиңизде колдонууга мүмкүнчүлүк болбой турган бorмдин тармактарында. Java иштеп чыгуучусу үчүн интервьюдан алынган суроолордун жана жооптордун анализи.  15-1-бөлүкОоба, эгер сиз башталгыч болсоңуз, сиздин теориялык бorмиңиз абдан олуттуу кабыл алынат. Азырынча тажрыйба жана чоң жетишкендиктер жок болгондуктан, бorм базасынын күчүн текшерүү гана калды. Бүгүн биз Java иштеп чыгуучулары үчүн эң популярдуу интервью суроолорун карап чыгуу менен ушул базаны бекемдөөнү улантабыз. учуп кетели!

Java Core

9. Javaдагы статикалык жана динамикалык байланыштын ортосунда кандай айырма бар?

Мен бул суроого ушул макалада статикалык жана динамикалык полиморфизм жөнүндө 18-суроодо жооп бердим , мен сизге аны окууну сунуштайм.

10. Интерфейсте купуя же корголгон өзгөрмөлөрдү колдонуу мүмкүнбү?

Жок болбойт. Анткени сиз интерфейсти жарыялаганыңызда, Java компилятору автоматтык түрдө интерфейстин методдорунун алдында жалпы жана абстрактуу ачкыч сөздөрдү жана маалымат мүчөлөрүнүн алдында жалпы , статикалык жана акыркы ачкыч сөздөрдү кошот. Чынында, эгерде сиз купуя же корголгон кошсоңуз , конфликт пайда болот жана компилятор төмөнкү билдирүү менен кирүү модификаторуна даттанат: “Бул жерде '<тандалган өзгөрткүч>' модификаторуна уруксат жок.” Эмне үчүн компилятор public , static жана final кошот. интерфейстеги өзгөрмөлөр? Аны аныктап көрөлү:
  • коомдук - интерфейс кардар an object менен өз ара аракеттенүүгө мүмкүндүк берет. Эгерде өзгөрмөлөр жалпыга ачык болбосо, кардарлар аларга кире алмак эмес.
  • статикалык - интерфейстерди түзүү мүмкүн эмес (же тагыраак айтканда, алардын an objectилери), ошондуктан өзгөрмө статикалык.
  • акыркы - интерфейс 100% абстракцияга жетүү үчүн колдонулгандыктан, өзгөрмө өзүнүн акыркы формасына ээ (жана өзгөртүлбөйт).

11. Classloader деген эмне жана ал эмне үчүн колдонулат?

Classloader - же Class Loader - Java класстарын жүктөөнү камсыз кылат. Тагыраак айтканда, жүктөө анын тукумдары менен камсыз кылынат - конкреттүү класс жүктөгүчтөр, анткени ClassLoader өзү абстракттуу. .class файлы жүктөлгөн сайын, мисалы, конструкторду же тиешелүү класстын статикалык ыкмасын чакыргандан кийин, бул аракет ClassLoader классынын тукумдарынын бири тарабынан аткарылат . Мураскорлордун үч түрү бар:
  1. Bootstrap ClassLoader бул JVM деңгээлинде ишке ашырылган негизги жүктөгүч жана иштөө чөйрөсүнөн эч кандай пикири жок, анткени ал JVM ядросунун бир бөлүгү жана жергorктүү codeдо жазылган. Бул жүктөгүч бардык башка ClassLoader инстанцияларынын ата-энеси катары кызмат кылат.

    Негизинен JDK ички класстарын, адатта rt.jar жана $JAVA_HOME/jre/lib каталогунда жайгашкан башка негизги китепканаларды жүктөө үчүн жооптуу . Ар кандай платформаларда бул класс жүктөгүчтүн ар кандай ишке ашырылышы болушу мүмкүн.

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

  3. System ClassLoader - бул JRE деңгээлинде ишке ашырылган тутум жүктөгүч, ал бардык колдонмо деңгээлиндеги класстарды JVMге жүктөөгө кам көрөт. Ал класс чөйрөсүнүн өзгөрмөлүү -classpath же -cp буйрук сабында табылган файлдарды жүктөйт.

Java иштеп чыгуучусу үчүн интервьюдан алынган суроолордун жана жооптордун анализи.  15-2-бөлүкКласс жүктөөчүлөр Java иштөө убактысынын бир бөлүгү болуп саналат. JVM классты сураган учурда, класс жүктөөчү классты табууга жана класстын толук квалификациялуу аталышын колдонуу менен класстын аныктамасын иштөө убактысына жүктөөгө аракет кылат. Java.lang.ClassLoader.loadClass() методу класс аныктамасын аткаруу убагында жүктөө үчүн жооп берет. Ал классты анын толук аталышынын негизинде жүктөөгө аракет кылат. Эгерде класс жүктөлө элек болсо, ал сурамды ата-эне класс жүктөөчүсүнө өткөрүп берет. Бул процесс рекурсивдүү түрдө ишке ашат жана төмөнкүдөй көрүнөт:
  1. System Classloader классты кэштен табууга аракет кылат.

    • 1.1. Эгерде класс табылса, жүктөө ийгorктүү аяктады.

    • 1.2. Эгерде класс табылбаса, жүктөө Extension Classloader'ге өткөрүлүп берилет.

  2. Extension Classloader классты өзүнүн кэшинде табууга аракет кылат.

    • 2.1. Эгерде класс табылса, ал ийгorктүү аяктайт.

    • 2.2. Эгер класс табылбаса, жүктөө Bootstrap Classloaderге өткөрүлүп берилет.

  3. Bootstrap Classloader классты өзүнүн кэшинде табууга аракет кылат.

    • 3.1. Эгерде класс табылса, жүктөө ийгorктүү аяктады.

    • 3.2. Эгер класс табылбаса, негизги Bootstrap Classloader аны жүктөөгө аракет кылат.

  4. Жүктөө болсо:

    • 4.1. Ийгorктүү - классты жүктөө аяктады.

    • 4.2. Эгер ал ишке ашпай калса, башкаруу Кеңейтүү Класстык жүктөгүчкө өткөрүлүп берилет.

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

    • 5.1. Ийгorктүү - классты жүктөө аяктады.

    • 5.2. Эгер ал ишке ашпай калса, башкаруу Система Класстык жүктөөчүгө өткөрүлүп берилет.

  6. 6. Системалык класс жүктөгүч классты жүктөөгө аракет кылат жана жүктөлүп жатса:

    • 6.1. Ийгorктүү - классты жүктөө аяктады.

    • 6.2. Ийгorктүү өткөн жок - өзгөчө кырдаал түзүлдү - ClassNotFoundException.

Класстык жүктөгүчтөрдүн темасы абдан чоң жана көңүл бурбай коюуга болбойт. Аны менен кененирээк таанышуу үчүн, мен сизге бул макаланы окуп чыгууну сунуштайм , жана биз көпкө созулбайбыз жана улантабыз.

12. Run-Time маалымат аймактары деген эмне?

Run-Time Data Ares - JVM иштөө убактысынын маалымат аймактары. JVM программаны аткаруу учурунда зарыл болгон кээ бир иштөө убактысынын маалымат аймактарын аныктайт. Алардын айрымдары JVM башталганда түзүлөт. Башкалары жип-локалдык жана жип түзүлгөндө гана түзүлөт (жана жип жок кылынганда жок). JVM Runtime маалымат аймактары төмөнкүдөй көрүнөт: Java иштеп чыгуучусу үчүн интервьюдан алынган суроолордун жана жооптордун анализи.  15-3-бөлүк
  • PC реестри ар бир жип үчүн локалдык болуп саналат жана жип учурда аткарып жаткан JVM нускамасынын дарегин камтыйт.

  • JVM Stack - бул жергorктүү өзгөрмөлөр жана убактылуу натыйжалар үчүн сактагыч катары колдонулган эс тутум аймагы. Ар бир жиптин өзүнүн өзүнчө стеки бар: жип бүтөөрү менен бул стек да жок кылынат. Айта кетчү нерсе, үймөктүн үстүнөн стектин артыкчылыгы - бул аткаруу, ал эми үймөктүн сактоо масштабында артыкчылыгы бар.

  • Native Method Stack - жергorктүү (Java эмес) методдорду аткаруу үчүн JVM стекине окшош маалымат элементтерин сактаган ар бир жипке берилүүчү маалымат аймагы.

  • Үймөк - бардык жиптер тарабынан an objectтерди, класстын метаберorштерин, массивдерди ж.б. камтыган дүкөн катары колдонулат, алар аткаруу убагында түзүлгөн. Бул аймак JVM башталганда түзүлөт жана ал өчүрүлгөндө жок кылынат.

  • Метод аймагы - Бул иштөө убактысынын аймагы бардык жиптер үчүн жалпы жана JVM башталганда түзүлөт. Ал ар бир класс үчүн структураларды сактайт, мисалы Runtime Constant Pool, конструкторлор жана методдор үчүн code, метод маалыматтары ж.б.

13. Өзгөрбөс an object деген эмне?

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

14. String классынын өзгөчөлүгү эмнеде?

Буга чейин талдоодо, биз бир нече жолу Stringдин айрым өзгөчөлүктөрү жөнүндө айтканбыз (бул үчүн өзүнчө бөлүм бар болчу). Эми String өзгөчөлүктөрүн жалпылап көрөлү :
  1. Бул Javaдагы эң популярдуу an object жана ар кандай максаттарда колдонулат. Колдонуу жыштыгы боюнча ал примитивдүү түрлөрдөн да кем калышпайт.

  2. Бул класстын an objectисин жаңы ачкыч сөздү колдонбостон түзсө болот - түз тырмакчалар аркылуу String str = “string”; .

  3. String өзгөрүлгүс класс : бул класстын an objectин түзүүдө анын берorштерин өзгөртүү мүмкүн эмес (белгилүү бир сапка + "башка сапты" кошкондо, натыйжада жаңы, үчүнчү сапты аласыз). String классынын өзгөрбөстүгү аны жипти коопсуз кылат.

  4. String классы жыйынтыкталды ( акыркы модификатору бар ), андыктан аны мурастоого болбойт.

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

  6. Javaда String аналогдору бар , алар ошондой эле саптар менен иштөө үчүн иштелип чыккан - StringBuilder жана StringBuffer , бирок айырмасы алар өзгөрүлмөлүү. Бул макалада алар жөнүндө көбүрөөк окуй аласыз .

Java иштеп чыгуучусу үчүн интервьюдан алынган суроолордун жана жооптордун анализи.  15-4-бөлүк

15. Тип ковариациясы деген эмне?

Ковариацияны түшүнүү үчүн биз бир мисалды карап чыгабыз. Бизде жаныбарлардын классы бар дейли:
public class Animal {
 void voice() {
   System.out.println("*тишина*");
 }
}
Ал эми кээ бир Dog классы аны кеңейтет :
public class Dog extends Animal {

 @Override
 public void voice() {
   System.out.println("Гав, гав, гав!!!");
 }
}
Эсибизде, биз мураскор түрдөгү an objectтерди ата-эне түрүнө оңой эле дайындай алабыз:
Animal animal = new Dog();
Бул полиморфизмден башка эч нерсе болбойт. Ыңгайлуу, ийкемдүү эмеспи? Ооба, жаныбарлардын тизмеси жөнүндө эмне айтууга болот? Жалпы жаныбар менен тизмеге Dog an objectилери менен тизме бере алабызбы ?
List<Dog> dogs = new ArrayList<>();
List<Animal> animals = dogs;
Мында жаныбарлардын тизмесине иттердин тизмесин ыйгаруу үчүн сызык кызыл түс менен сызылат, б.а. компилятор бул codeду өткөрбөйт. Бул тапшырма абдан логикалык көрүнгөнүнө карабастан (анткени, биз Dog an objectисин Animal түрүндөгү өзгөрмөгө дайындай алабыз ), аны аткаруу мүмкүн эмес. Себеби, эгер ага уруксат берилсе, биз жаныбарлардын an objectисин башында ит болууга арналган тизмеге киргизе алмакпыз , ал эми тизмеде иттер гана бар деп ойлойбуз . Анан, мисалы, биз get() ыкмасын колдонуп, иттердин тизмесинен an objectти алып , аны ит деп ойлойбуз жана андагы Dog an objectинин кандайдыр бир ыкмасын чакырабыз, ал Animal жок . Жана сиз түшүнгөндөй, бул мүмкүн эмес - ката пайда болот. Бирок, бактыга жараша, компилятор ата-энелердин тизмесине урпактардын тизмесин ыйгаруу менен бул логикалык катаны өткөрүп жибербейт (жана тескерисинче). Java'да сиз тизме an objectтерин гана дал келген генериктери бар өзгөрмөлөрдүн тизмесине дайындай аласыз. Бул инвариация деп аталат. Эгерде алар муну жасай алышса, анда ал ковариация деп аталмак. Башкача айтканда, эгер ArrayList<Dog> түрүндөгү an objectти List<Animal> түрүндөгү өзгөрмөгө орното алсак, ковариация болот . Javaда ковариация колдоого алынbyte экен? Кандай болбосун! Бирок бул өзүнүн өзгөчө жолу менен жасалат. Дизайн эмне үчүн колдонулат ? Animal узартат . Ал биз тизме an objectисин орноткубуз келген өзгөрмөнүн генерикасы менен, тукумдун жалпылыгы менен жайгаштырылат. Бул жалпы конструкция Animal түрүнүн тукуму болгон ар кандай түрү жасай турганын билдирет (жана Жаныбардын түрү да ушул жалпылаштырууга кирет). Өз кезегинде, Animal класс гана эмес, интерфейс да болушу мүмкүн ( extens ачкыч сөзүнө алданбаңыз ). Биз мурунку тапшырмабызды төмөнкүдөй аткара алабыз: Java иштеп чыгуучусу үчүн интервьюдан алынган суроолордун жана жооптордун анализи.  15-5-бөлүк
List<Dog> dogs = new ArrayList<>();
List<? extends Animal> animals = dogs;
Натыйжада, IDEде компилятор бул курулушка нааразы болбой турганын көрөсүз. Келгиле, бул дизайндын функционалдуулугун текшерип көрөлү. Ага өткөн бардык жаныбарлардын үн чыгарышына себеп болгон бир ыкмабыз бар дейли:
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);
Консолдо биз төмөнкү жыйынтыкты көрөбүз:
Уф уфф!!! Уф уфф!!! Уф уфф!!!
Бул ковариацияга бул ыкма ийгorктүү иштейт дегенди билдирет. Бул генерик тизмеге киргендигин белгилей кетейин ? extends Animal биз эч кандай типтеги жаңы маалыматтарды киргизе албайбыз: Dog түрү да , ал тургай Жаныбар түрү да :
List<Dog> dogs = new ArrayList<>();
List<? extends Animal> animals = dogs;
animals.add(new Dog());
dogs.add(new Animal());
Чынында, акыркы эки сапта компилятор an objectтерди кызыл түс менен киргизүүнү баса белгилейт. Мунун себеби, биз жалпы <? узартат Animal> . Мен контрвариансJava иштеп чыгуучусу үчүн интервьюдан алынган суроолордун жана жооптордун анализи.  15-6-бөлүк жөнүндө да айткым келет , анткени, адатта, бул түшүнүк дайыма ковариация менен бирге жүрөт жана эреже катары, алар жөнүндө чогуу суралат. Бул концепция ковариацияга бир аз карама-каршы келет, анткени бул конструкция мураскер түрүн колдонот. Биз Dog an objectинин ата-бабалары болбогон типтеги an objectтердин тизмеси ыйгарыла турган тизмени каалайбыз дейли . Бирок, алар кандай конкреттүү түрлөрү болорун алдын ала биле албайбыз. Бул учурда, форманын курулушу ? супер Dog , анын бардык түрлөрү ылайыктуу - Dog классынын тукумдары :
List<Animal> animals = new ArrayList<>();
List<? super Dog> dogs = animals;
dogs.add(new Dog());
dogs.add(new Dog());
Биз мындай генерик менен Dog тибиндеги an objectтерди тизмеге коопсуз кошсок болот , анткени кандай болгон күндө да анын ата-бабаларынын бардык ишке ашырылган ыкмалары бар. Бирок биз Animal түрүндөгү an objectти кошо албайбыз , анткени, мисалы, Dog эмес, ичинде ушул типтеги an objectтер болоруна эч кандай ишенич жок . Акыры, биз бул тизменин элементинен Dog классынын ыкмасын сурасак болот, ал Animal жок болот . Бул учурда, компиляция катасы пайда болот. Ошондой эле, эгерде биз мурунку ыкманы ишке ашырууну кааласак, бирок бул жалпы менен:
public static void animalsVoice(List<? super Dog> dogs) {
 for (Dog dog : dogs) {
   dog.voice();
 }
}
for циклинде компиляция катасын алабыз , анткени кайтарылган тизмеде Dog түрүндөгү an objectтер бар экенине жана анын ыкмаларын колдонууга эркин экенине ишене албайбыз . Бул тизмедеги dogs.get(0) ыкмасын чакырсак. - биз Object түрүндөгү an objectти алабыз . Башкача айтканда, animalVoice() методу иштеши үчүн , биз жок дегенде типтеги маалыматтарды тарытуу менен кичинекей манипуляцияларды кошуубуз керек:
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