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

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

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

103. Мұрагерлікте ерекшеліктерді тексеру ережелері қандай?

Егер мен сұрақты дұрыс түсінсем, олар мұрагерлік кезінде ерекше жағдайлармен жұмыс істеу ережелері туралы сұрайды және олар келесідей:
  • Тұқымдағы/іске асырудағы қайта анықталған немесе іске асырылған әдіс иерархияда суперкласс/интерфейс әдісіндегі ерекшеліктерге қарағанда жоғарырақ тексерілген ерекшеліктерді шығара алмайды.
Яғни, егер бізде IOException шығаратын әдіспен белгілі Animal интерфейсі болса :
public  interface Animal {
   void voice() throws IOException;
}
Бұл интерфейсті іске асыруда біз жалпы шығарылған ерекшелікті (мысалы, Exception , Throwable ) шығара алмаймыз, бірақ оны FileNotFoundException сияқты ұрпақты ерекшелікпен ауыстыра аламыз :
public class Cat implements Animal {
   @Override
   public void voice() throws FileNotFoundException {
// некоторая реализация
   }
}
  • Ішкі класс конструкторы an objectіні жасау кезінде шақырылатын суперкласс конструкторы шығарған барлық ерекшелік кластарын лақтыру блоктарына қосуы керек.
Animal класының конструкторы көптеген ерекшеліктерді шығарады делік :
public class Animal {
  public Animal() throws ArithmeticException, NullPointerException, IOException {
  }
Содан кейін сынып мұрагері оларды конструкторда көрсетуі керек:
public class Cat extends Animal {
   public Cat() throws ArithmeticException, NullPointerException, IOException {
       super();
   }
Немесе әдістер жағдайындағыдай, бірдей ерекшеліктерді емес, жалпыламаларды көрсетуге болады. Біздің жағдайда жалпы ерекшелікті көрсету жеткілікті болады - Ерекшелік , өйткені бұл қарастырылған барлық үш ерекшеліктің ортақ атасы:
public class Cat extends Animal {
   public Cat() throws Exception {
       super();
   }

104. Finally блогы орындалмайтын уақыттың codeын жаза аласыз ба?

Алдымен, ақыры не екенін еске түсірейік . Бұрын біз ерекше жағдайларды ұстау механизмін қарастырдық: try блогы ұстау аймағын белгілейді, ал ұстау блогы(лар) ы белгілі бір ерекшелік тасталған кезде жұмыс істейтін code болып табылады. Ақырында, codeтың үшінші блогы, ақырында, ол catch- пен ауыстырылады , бірақ бір-бірін жоққа шығармайды. Бұл блоктың мәні мынада: ондағы code әрқашан тырысу немесе ұстау нәтижесіне қарамастан жұмыс істейді (ерекшелік тасталды ма, жоқ па). Оның сәтсіздігі жағдайлары өте сирек кездеседі және олар қалыпты емес. Сәтсіздіктің ең қарапайым жағдайы жоғарыдағы codeта System.exit(0) әдісі шақырылады , ол бағдарламаны тоқтатады (оны өшіреді):
try {
   throw new IOException();
} catch (IOException e) {
   System.exit(0);
} finally {
   System.out.println("Данное сообщение не будет выведенно в консоль");
}
Соңында жұмыс істемейтін басқа да жағдайлар бар :
  • Жүйенің маңызды ақауларынан туындаған бағдарламаның қалыптан тыс аяқталуы немесе қолданбаны «бұзатын» кейбір Қатенің құлауы (қатенің мысалы стектің жады толып кеткен кезде пайда болатын бірдей StackOwerflowError болуы мүмкін).
  • Deamon жібі ry арқылы өткенде ... соңында блоктау және осыған параллель бағдарлама аяқталады. Өйткені, деамон жіпі фондық әрекеттерге арналған жіп болып табылады, яғни бұл басымдық және міндетті емес және қолданба өз жұмысының аяқталуын күтпейді.
  • try немесе catch ішіндегі ең кең таралған шексіз цикл , бір рет ағын сонда мәңгі қалады:

    try {
       while (true) {
       }
    } finally {
       System.out.println("Данное сообщение не будет выведенно в консоль");
    }

Бұл сұрақ жаңадан бастаушыларға арналған сұхбаттарда өте танымал, сондықтан осы ерекше жағдайлардың бірнешеуін есте ұстаған жөн. Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  12 - 3 бөлім

105. Бір catch блогында бірнеше ерекшеліктерді өңдеу мысалын жазыңыз

1) Мүмкін сұрақ қате қойылған шығар. Менің түсінуімше, бұл сұрақ бір сынақ блогы үшін бірнеше аулауды білдіреді :
try {
  throw new FileNotFoundException();
} catch (FileNotFoundException e) {
   System.out.print("Упс, у вас упало исключение - " + e);
} catch (IOException e) {
   System.out.print("Упс, у вас упало исключение - " + e);
} catch (Exception e) {
   System.out.print("Упс, у вас упало исключение - " + e);
}
Егер try блогында ерекше жағдай орын алса , онда catch блоктары кезекпен оны жоғарыдан төменге қарай ұстауға тырысады.Егер белгілі бір catch блогы сәтті болса, ол ерекше жағдайды өңдеу құқығын алады, ал төменде қалған блоктар енді болмайды. оны ұстауға тырысып, оны өзінше өңдеуге қабілетті. Сондықтан, тар ерекшеліктер аулау блок тізбегінде жоғарырақ , ал кеңірек ерекшеліктер төменірек орналастырылады. Мысалы, егер біздің бірінші catch блогында Exception класының ерекше жағдайы ұсталса , онда тексерілген ерекшеліктер қалған блоктарға кіре алмайды ( Exception ұрпақтары бар қалған блоктар мүлдем пайдасыз болады). 2) Сұрақ дұрыс қойылды.Бұл жағдайда өңдеуіміз келесідей болады:
try {
  throw new NullPointerException();
} catch (Exception e) {
   if (e instanceof FileNotFoundException) {
       // некоторая обработка с сужением типа (FileNotFoundException)e
   } else if (e instanceof ArithmeticException) {
       // некоторая обработка с сужением типа (ArithmeticException)e
   } else if(e instanceof NullPointerException) {
       // некоторая обработка с сужением типа (NullPointerException)e
   }
catch арқылы ерекше жағдайды анықтай отырып , біз an objectінің белгілі бір түрге жататынын тексеру үшін қолданылатын instanceof әдісі арқылы оның нақты түрін анықтауға тырысамыз , осылайша кейінірек оны теріс салдарсыз осы түрге дейін тарылта аламыз. Қарастырылған екі тәсілді де бір жағдайда қолдануға болады, бірақ мен сұрақтың дұрыс емес екенін айттым, өйткені мен екінші нұсқаны жақсы деп атамас едім және оны өз тәжірибемде ешқашан көрмегенмін, сонымен бірге мультикарттармен бірінші әдіс кеңінен таралған. назар аудару. Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  12 - 4 бөлім

106. Қай оператор ерекше жағдайды мәжбүрлеп шығаруға мүмкіндік береді? Мысал жаз

Мен оны жоғарыда бірнеше рет қолдандым, бірақ соған қарамастан мен бұл кілт сөзді қайталаймын - throw . Қолдану мысалы (ерекше жағдайды мәжбүрлеу):
throw new NullPointerException();

107. Негізгі әдіс лақтыратын ерекше жағдайды шығара ала ма? Олай болса, қайда аударылады?

Ең алдымен, мен негізгі қарапайым әдістен басқа ештеңе емес екенін атап өткім келеді, иә, оны виртуалды машина бағдарламаны орындауды бастау үшін шақырады, бірақ бұдан басқа оны кез келген басқа codeтан шақыруға болады. Яғни, ол тастағаннан кейін тексерілген ерекшеліктерді көрсетудің әдеттегі ережелеріне бағынады :
public static void main(String[] args) throws IOException {
Тиісінше, онда ерекшеліктер де болуы мүмкін. Егер main қандай да бір әдіспен шақырылмаса, бірақ бағдарламаны іске қосу нүктесі ретінде іске қосылған болса, онда ол шығарған ерекшелік .UncaughtExceptionHandler интерцепторы арқылы өңделеді . Бұл өңдегіш әр ағында бір (яғни әрбір ағында бір өңдеуші). Қажет болса, сіз өзіңіздің өңдегішті жасай аласыз және оны Thread нысанында шақырылған setDefaultUncaughtExceptionHandler әдісі арқылы орната аласыз .

Көп ағынды

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

108. Көп ағынмен жұмыс істеуге арналған қандай құралдарды білесіз?

Java-де көп ағынды пайдаланудың негізгі/негізгі құралдары:
  • Синхрондалған – басқа ағындардан ағын кірген кезде әдісті/блокты жабу (блоктау) механизмі.
  • Ұшқыш - әртүрлі ағындар арқылы айнымалыға дәйекті қол жеткізуді қамтамасыз ету механизмі, яғни айнымалыда осы модификатордың болуымен барлық тағайындау және оқу операциялары атомдық болуы керек. Басқаша айтқанда, ағындар бұл айнымалыны жергілікті жадына көшірмейді және оны өзгертпейді, бірақ оның бастапқы мәнін өзгертеді.
Құбылмалылық туралы толығырақ мына жерден оқыңыз .
  • Runnable - белгілі бір сыныпта іске асырылуы мүмкін интерфейс (атап айтқанда, оның іске қосу әдісі):
public class CustomRunnable implements Runnable {
   @Override
   public void run() {
       // некоторая логика
   }
}
Осы сыныптың an objectісін жасағаннан кейін, осы нысанды жаңа Thread нысанының конструкторында орнату және оның start() әдісін шақыру арқылы жаңа ағынды бастауға болады :
Runnable runnable = new CustomRunnable();
new Thread(runnable).start();
Бастау әдісі іске асырылған run() әдісін бөлек ағында іске қосады.
  • Thread - мұраға алатын класс ( іске қосу әдісін қайта анықтау кезінде ):
public class CustomThread extends Thread {
   @Override
   public void run() {
       // некоторая логика
   }
}
Осы сыныптың an objectісін жасау және оны start() әдісі арқылы іске қосу арқылы біз жаңа ағынды іске қосамыз:
new CustomThread().start();
  • Concurrency – көп ағынды ортада жұмыс істеуге арналған құралдары бар пакет.
Ол мыналардан тұрады:
  • Concurrent Collections – көп ағынды ортада жұмыс істеуге мамандандырылған жинақтар жиынтығы.
  • Кезектер – көп ағынды орта үшін мамандандырылған кезектер (блоктау және бұғаттамайтын).
  • Синхронизаторлар - көп ағынды ортада жұмыс істеуге арналған арнайы утorталар.
  • Орындаушылар жіп пулдарын құру механизмдері болып табылады.
  • Құлыптар - жіптерді синхрондау механизмдері (стандарттыларға қарағанда икемді - синхрондалған, күту, хабарлау, барлығын хабарлау).
  • Атомдар – көп ағынды орындау үшін оңтайландырылған сыныптар; әрбір операция атомдық болып табылады.
Бір мезгілде пакет туралы толығырақ мына жерден оқыңыз .

109. Жіптер арасындағы синхрондау туралы айту. wait(), notify() - notifyAll() join() әдістері не үшін қолданылады?

Сұрақты түсінуімше, ағындар арасындағы синхрондау кілт модификаторы туралы - синхрондалған . Бұл модификаторды тікелей блоктың жанында орналастыруға болады:
synchronized (Main.class) {
   // некоторая логика
}
Немесе тікелей әдіс қолтаңбасында:
public synchronized void move() {
   // некоторая логика}
Жоғарыда айтқанымдай, синхрондалған – бір ағын енгізілген кезде басқа ағындардан блокты/әдісті жабуға мүмкіндік беретін механизм. Блокты/әдісті бөлме ретінде қарастырыңыз. Кейбір ағындар оған келіп, оған кіріп, оны құлыптайды, ал басқа ағындар бөлмеге келіп, оның жабық екенін көріп, бос болғанша оның жанында күтеді. Өз ісін орындап, бірінші жіп бөлмеден шығып, кілтті босатады. Мен кілт туралы үнемі айтқаным бекер емес еді, өйткені ол шынымен бар. Бұл бос емес/бос күйі бар арнайы нысан. Бұл нысан әрбір Java нысанына бекітілген, сондықтан синхрондалған блокты пайдаланған кезде біз жақшаның ішінде мутексі есікті жапқымыз келетін нысанды көрсетуіміз керек:
Cat cat = new Cat();
synchronized (cat) {
   // некоторая логика
}
Сондай-ақ, бірінші мысалда ( Main.class ) жасағанымдай, класс мутексін пайдалануға болады. Әдіс бойынша синхрондауды пайдаланған кезде біз жабылғымыз келетін нысанды көрсетпейміз, солай ма? Бұл жағдайда, статикалық емес әдіс үшін ол this нысанының мутексінде , яғни осы сыныптың ағымдағы нысанында жабылады. Статикалық класс ағымдағы сыныптың мутексінде жабылады ( this.getClass(); ). Мутекс туралы толығырақ мына жерден оқи аласыз . Синхрондалған туралы мына жерден оқыңыз . Wait() – мутексті босатып, ағымдағы мониторға (зәкір сияқты нәрсе) қосылған сияқты ағымдағы ағынды күту режиміне қоятын әдіс. Осыған байланысты бұл әдісті тек синхрондалған блоктан немесе әдістен шақыруға болады (әйтпесе, ол нені босатуы керек және ол нені күтуі керек). Сондай-ақ, бұл Object класының әдісі екенін ескеріңіз . Дәлірек айтқанда, бір емес, тіпті үшеуі:
  • Wait() – ағымдағы ағынды басқа ағын осы нысан үшін notify() немесе notifyAll() әдісін шақырғанша күту режиміне қояды (бұл әдістер туралы кейінірек айтатын боламыз).

  • Күту (ұзақ күту уақыты) - басқа ағын осы нысандағы notify() немесе notifyAll() әдісін шақырғанша немесе көрсетілген күту уақыты біткенше ағымдағы ағынды күту режиміне қояды .

  • Күту (ұзақ күту уақыты, int nanos) - алдыңғыға ұқсас, тек нанос наносекундтарды көрсетуге мүмкіндік береді (нақтырақ уақыт параметрі).

  • Notify() - ағымдағы синхрондау блогының бір кездейсоқ ағынын оятуға мүмкіндік беретін әдіс. Тағы да, оны тек синхрондалған блокта немесе әдісте шақыруға болады (басқа жерлерде оны босату үшін ешкім болмайды).

  • NotifyAll() — ағымдағы монитордағы барлық күту ағындарын оятатын әдіс (сонымен қатар тек синхрондалған блокта немесе әдісте қолданылады).

110. Ағынды қалай тоқтатуға болады?

Бірінші айта кететін нәрсе, run() әдісі толығымен орындалғанда , ағын автоматты түрде жойылады. Бірақ кейде бұл әдіс аяқталмай тұрып, оны мерзімінен бұрын өлтіру керек. Сонда не істеуіміз керек? Thread нысанында stop() әдісі болуы керек шығар ? Қалай болса да! Бұл әдіс ескірген болып саналады және жүйенің бұзылуына әкелуі мүмкін. Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  12 - 6 бөлімАл, сонда ше? Мұны істеудің екі жолы бар: Біріншісі - ішкі логикалық жалауды пайдалану. Мысал қарастырайық. Бізде толығымен тоқтағанша экранда белгілі бір фразаны көрсетуі керек ағынды өзіміздің іске асыруымыз бар:
public class CustomThread extends Thread {
private boolean isActive;

   public CustomThread() {
       this.isActive = true;
   }

   @Override
   public void run() {
       {
           while (isActive) {
               System.out.println("Поток выполняет некую логику...");
           }
           System.out.println("Поток остановлен!");
       }
   }

   public void stopRunningThread() {
       isActive = false;
   }
}
stopRunning() әдісін пайдаланған кезде ішкі жалауша жалған болады және іске қосу әдісі жұмысын тоқтатады. Оны негізгі түрде іске қосайық :
System.out.println("Начало выполнения программы");
CustomThread thread = new CustomThread();
thread.start();
Thread.sleep(3);
// пока наш основной поток спит, вспомогательный  CustomThread работает и выводит в коноль своё сообщение
thread.stopRunningThread();
System.out.println("Конец выполнения программы");
Нәтижесінде біз консольде келесідей нәрсені көреміз:
Бағдарламаның орындалуының басталуы Жіп кейбір логиканы орындауда... Жіп кейбір логиканы орындауда... Жіп кейбір логиканы орындауда... Жіп кейбір логиканы орындауда... Жіп кейбір логиканы орындауда... жіп кейбір логиканы орындауда... Бағдарламаның орындалуының соңы Жіп тоқтатылды!
Бұл біздің ағынның жұмыс істеп, консольге белгілі бір хабарламалар санын шығарып, сәтті тоқтатылғанын білдіреді. Шығарылатын хабарлардың саны орындалудан іске дейін өзгеретінін ескеремін; кейде қосымша ағын тіпті ештеңе шығармайды. Менің байқағанымдай, бұл негізгі ағынның ұйқы уақытына байланысты, ол неғұрлым ұзақ болса, қосымша ағынның ештеңе шығармау мүмкіндігі соғұрлым аз. Ұйқы уақыты 1 мс болғанда хабарлар ешқашан шығарылмайды, бірақ оны 20 мс етіп орнатсаңыз, ол әрқашан дерлік жұмыс істейді. Мүмкін, уақыт аз болған кезде, жіптің жұмысын бастауға және бастауға уақыты жоқ және бірден тоқтатылады. Екінші әдіс - Thread нысанындағы interrupted() әдісін пайдалану , ол ішкі үзу жалауының мәнін қайтарады (бұл жалау әдепкі бойынша жалған ) және оның басқа interrupt() әдісі , бұл жалаушаны шын мәніне орнатады (бұл кезде жалауша шын болса , жіп өз жұмысын тоқтатуы керек). Мысал қарастырайық:
public class CustomThread extends Thread {

   @Override
   public void run() {
       {
           while (!Thread.interrupted()) {
               System.out.println("Поток выполняет некую логику...");
           }
           System.out.println("Поток остановлен!");
       }
   }
}
Негізгі бөлімде іске қосыңыз :
System.out.println("Начало выполнения программы");
Thread thread = new CustomThread();
thread.start();
Thread.sleep(3);
thread.interrupt();
System.out.println("Конец выполнения программы");
Орындау нәтижесі бірінші жағдайдағыдай болады, бірақ маған бұл тәсіл ұнайды: біз аз code жазамыз және дайын, стандартты функционалдылықты көбірек қолданамыз. Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  12 - 7 бөлімМіне, біз бүгін тоқталамыз.Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  12 - 8 бөлім
Сериядағы басқа материалдар:
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION