JavaRush /Java blogi /Random-UZ /Java dasturchisi uchun intervyudan olingan savollar va ja...

Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish. 12-qism

Guruhda nashr etilgan
Salom! Bilim - bu kuch. Birinchi suhbatdan oldin qanchalik ko'p bilimga ega bo'lsangiz, o'zingizni shunchalik ishonchli his qilasiz. Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish.  12-1-qismYaxshi bilimga ega bo'lsangiz, sizni chalkashtirib yuborish qiyin bo'ladi va shu bilan birga siz suhbatdoshingizni yoqimli ajablantira olasiz. Shuning uchun, bugungi kunda, biz ko'proq vaqt talab qilmasdan, Java dasturchisi uchun 250 dan ortiq savollarni o'rganish orqali sizning nazariy bazangizni mustahkamlashda davom etamiz . Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish.  12-2-qism

103. Merosda istisnolarni tekshirish qoidalari qanday?

Agar men savolni to'g'ri tushunsam, ular meros paytida istisnolar bilan ishlash qoidalari haqida so'rashadi va ular quyidagicha:
  • Avlod/amalga oshirishda bekor qilingan yoki amalga oshirilgan usul ierarxiyada yuqori sinf/interfeys usulidagi istisnolardan yuqori bo'lgan tekshirilgan istisnolarni tashlay olmaydi.
Ya'ni, agar bizda IOException ni tashlaydigan usul bilan ma'lum bir Animal interfeysi bo'lsa :
public  interface Animal {
   void voice() throws IOException;
}
Ushbu interfeysni amalga oshirishda biz umumiy istisnolardan voz kecholmaymiz (masalan, Exception , Throwable ), lekin biz uni FileNotFoundException kabi nasl istisno bilan almashtira olamiz :
public class Cat implements Animal {
   @Override
   public void voice() throws FileNotFoundException {
// некоторая реализация
   }
}
  • Subklass konstruktori ob'ektni yaratishda chaqiriladigan superklass konstruktori tomonidan tashlangan barcha istisno sinflarini o'z blokirovkalarini o'z ichiga olishi kerak.
Aytaylik, Animal sinfining konstruktori juda ko'p istisnolarni qo'yadi:
public class Animal {
  public Animal() throws ArithmeticException, NullPointerException, IOException {
  }
Keyin sinf vorisi ularni konstruktorda ham ko'rsatishi kerak:
public class Cat extends Animal {
   public Cat() throws ArithmeticException, NullPointerException, IOException {
       super();
   }
Yoki usullarda bo'lgani kabi, siz bir xil istisnolarni emas, balki umumiyroq narsalarni belgilashingiz mumkin. Bizning holatda, umumiy istisnoni ko'rsatish kifoya qiladi - Istisno , chunki bu ko'rib chiqilgan uchta istisnoning umumiy ajdodidir:
public class Cat extends Animal {
   public Cat() throws Exception {
       super();
   }

104. Finally bloki bajarilmasligi uchun kod yoza olasizmi?

Birinchidan, oxir-oqibat nima ekanligini eslaylik . Ilgari biz istisnolarni ushlash mexanizmini ko'rib chiqdik: try bloki tutib olish maydonini belgilaydi, tutash blok(lar) esa ma'lum bir istisno tashlanganida ishlaydigan koddir. Nihoyat, uchinchi kod bloki, nihoyat , catch bilan almashtirilishi mumkin , lekin bir-birini istisno qilmaydi. Ushbu blokning mohiyati shundan iboratki, undagi kod har doim sinab ko'rish yoki ushlash natijasidan qat'iy nazar ishlaydi (istisno tashlangan yoki yo'qligidan qat'iy nazar). Uning muvaffaqiyatsizligi holatlari juda kam uchraydi va ular g'ayritabiiydir. Muvaffaqiyatsizlikning eng oddiy holati yuqoridagi kodda System.exit(0) usuli chaqirilsa , dasturni tugatadi (uni o'chiradi):
try {
   throw new IOException();
} catch (IOException e) {
   System.exit(0);
} finally {
   System.out.println("Данное сообщение не будет выведенно в консоль");
}
Nihoyat ishlamaydigan boshqa holatlar ham mavjud :
  • Tizimning tanqidiy muammolari yoki dasturni "halokatga olib keladigan" ba'zi bir xatoning yiqilishiga olib keladigan dasturning g'ayritabiiy tugatilishi (xato misoli stek xotirasi to'lib ketganda yuzaga keladigan StackOwerflowError bo'lishi mumkin).
  • Deamon ipi ry orqali o'tganda ... nihoyat blokirovka qilinadi va shu bilan parallel ravishda dastur tugaydi. Axir, deamon ipi fondagi harakatlar uchun ipdir, ya'ni u ustuvor va majburiy emas va dastur o'z ishining tugashini kutmaydi.
  • try or catch dagi eng keng tarqalgan cheksiz tsikl , unda oqim abadiy qoladi:

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

Bu savol yangi boshlanuvchilar uchun intervyularda juda mashhur, shuning uchun bir nechta istisno vaziyatlarni esga olish kerak. Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish.  12-3-qism

105. Bir catch blokida bir nechta istisnolar bilan ishlashga misol yozing

1) Ehtimol, savol noto'g'ri berilgan. Men tushunganimdek, bu savol bitta sinash bloki uchun bir nechta ushlashni anglatadi :
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);
}
Agar try blokida istisno ro'y bersa , u holda catch bloklari navbatma-navbat uni yuqoridan pastgacha ushlab olishga harakat qiladi.Agar ma'lum bir catch bloki muvaffaqiyatli bo'lsa, u istisnoni boshqarish huquqiga ega bo'ladi, qolgan bloklar esa boshqa bo'lmaydi. uni qo'lga olishga va uni o'z yo'lida qayta ishlashga harakat qilishlari mumkin. Shuning uchun, torroq istisnolar ushlash bloklari zanjirida yuqoriroq joylashtiriladi va kengroq istisnolar pastroqda joylashtiriladi. Misol uchun, agar bizning birinchi catch blokimizda Exception sinfining istisnosi tutilgan bo'lsa , u holda tekshirilgan istisnolar qolgan bloklarga kira olmaydi ( Exception avlodlari bilan qolgan bloklar mutlaqo foydasiz bo'ladi). 2) Savol to'g'ri berilgan.Bu holda bizning ishlovimiz quyidagicha ko'rinadi:
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 orqali istisnoni qo'lga kiritganimizdan so'ng , biz ob'ektning ma'lum bir turga tegishli ekanligini tekshirish uchun ishlatiladigan instanceof usuli orqali uning o'ziga xos turini aniqlashga harakat qilamiz , shunda keyinchalik salbiy oqibatlarsiz uni shu turga qisqartirishimiz mumkin. Ikkala ko'rib chiqilgan yondashuvni bir xil vaziyatda qo'llash mumkin, lekin men savol noto'g'ri ekanligini aytdim, chunki men ikkinchi variantni yaxshi deb aytmayman va buni amaliyotimda hech qachon ko'rmaganman, shu bilan birga multicatches bilan birinchi usul keng tarqalgan. e'tibor. tarqalish. Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish.  12-4-qism

106. Qaysi operator istisnoni majburan tashlashga imkon beradi? Misol yozing

Men uni yuqorida bir necha marta ishlatganman, lekin shunga qaramay, men bu kalit so'zni takrorlayman - throw . Foydalanish misoli (istisnoni majburlash):
throw new NullPointerException();

107. Asosiy usulda tashlanishlar istisno qilishi mumkinmi? Agar shunday bo'lsa, u qayerga o'tkaziladi?

Avvalo shuni ta'kidlashni istardimki, main oddiy usuldan boshqa narsa emas va ha, u virtual mashina tomonidan dasturni bajarishni boshlash uchun chaqiriladi, lekin bundan tashqari, uni boshqa har qanday koddan chaqirish mumkin. Ya'ni, u otishdan keyin tekshirilgan istisnolarni ko'rsatish uchun odatiy qoidalarga ham bo'ysunadi :
public static void main(String[] args) throws IOException {
Shunga ko'ra, unda istisnolar ham bo'lishi mumkin. Agar main qandaydir usulda chaqirilmagan bo'lsa, lekin dasturni ishga tushirish nuqtasi sifatida ishga tushirilgan bo'lsa, u tomonidan berilgan istisno .UncaughtExceptionHandler interceptor tomonidan boshqariladi . Bu ishlov beruvchi har bir ipda bittadan (ya'ni har bir ipda bitta ishlov beruvchi). Agar kerak bo'lsa, siz o'zingizning ishlov beruvchingizni yaratishingiz va uni Thread obyektida chaqirilgan setDefaultUncaughtExceptionHandler usuli yordamida o'rnatishingiz mumkin .

Ko'p tarmoqli

Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish.  12-5-qism

108. Ko'p oqim bilan ishlash uchun qanday vositalarni bilasiz?

Java-da multithreadingdan foydalanish uchun asosiy/asosiy vositalar:
  • Sinxronlashtirilgan - bu boshqa iplardan ip kirganda usul/blokni yopish (bloklash) mexanizmi.
  • O'zgaruvchan - bu o'zgaruvchiga turli xil oqimlar tomonidan izchil kirishni ta'minlash mexanizmi, ya'ni o'zgaruvchida ushbu modifikator mavjudligi bilan barcha tayinlash va o'qish operatsiyalari atomik bo'lishi kerak. Boshqacha qilib aytganda, iplar bu o'zgaruvchini mahalliy xotirasiga ko'chirmaydi va uni o'zgartirmaydi, balki uning asl qiymatini o'zgartiradi.
Bu yerda uchuvchi haqida ko'proq o'qing .
  • Runnable - bu ma'lum bir sinfda amalga oshirilishi mumkin bo'lgan interfeys (xususan, uning ishga tushirish usuli):
public class CustomRunnable implements Runnable {
   @Override
   public void run() {
       // некоторая логика
   }
}
Va ushbu sinf ob'ektini yaratgandan so'ng, siz ushbu ob'ektni yangi Thread ob'ektining konstruktoriga o'rnatish va start() usulini chaqirish orqali yangi mavzuni boshlashingiz mumkin :
Runnable runnable = new CustomRunnable();
new Thread(runnable).start();
Boshlash usuli amalga oshirilgan run() usulini alohida ish zarrachasida ishga tushiradi.
  • Thread - bu sinf bo'lib, undan meros qilib olinadi ( yugurish usulini bekor qilganda ):
public class CustomThread extends Thread {
   @Override
   public void run() {
       // некоторая логика
   }
}
Va ushbu sinf ob'ektini yaratish va uni start() usuli yordamida ishga tushirish orqali biz yangi mavzuni ishga tushiramiz:
new CustomThread().start();
  • Concurrency - bu ko'p tarmoqli muhitda ishlash uchun asboblar to'plami.
U quyidagilardan iborat:
  • Concurrent Collections - ko'p tarmoqli muhitda ishlashga ixtisoslashgan to'plamlar to'plami.
  • Navbatlar - ko'p tarmoqli muhit uchun ixtisoslashtirilgan navbatlar (bloklanadigan va bloklanmaydigan).
  • Sinxronizatorlar ko'p tarmoqli muhitda ishlash uchun maxsus yordamchi dasturlardir.
  • Ijrochilar ip hovuzlarini yaratish mexanizmlari.
  • Qulflar - iplarni sinxronizatsiya qilish mexanizmlari (standartlardan ko'ra ko'proq moslashuvchan - sinxronlashtirilgan, kutish, xabar berish, barchani xabardor qilish).
  • Atomlar - bu ko'p tarmoqli bajarish uchun optimallashtirilgan sinflar; har bir operatsiya atomikdir.
Bir vaqtning o'zida to'plam haqida ko'proq ma'lumotni bu erda o'qing .

109. Tarmoqlar orasidagi sinxronizatsiya haqida gapiring. wait(), notify() - notifyAll() join() usullari nima uchun ishlatiladi?

Savolni tushunganimdek, mavzular orasidagi sinxronizatsiya kalit modifikatori - sinxronizatsiya haqida . Ushbu modifikator to'g'ridan-to'g'ri blokning yoniga joylashtirilishi mumkin:
synchronized (Main.class) {
   // некоторая логика
}
Yoki to'g'ridan-to'g'ri usul imzosida:
public synchronized void move() {
   // некоторая логика}
Yuqorida aytib o'tganimdek, sinxronlashtirilgan - bu bitta ip allaqachon kiritilgan bo'lsa, boshqa mavzulardan blok/usulni yopish imkonini beruvchi mexanizm. Blokni/usulni xona sifatida tasavvur qiling. Ba'zi oqimlar unga kelib, unga kirib, uni qulflaydilar, boshqa oqimlar esa xonaga kelib, uning yopiqligini ko'rib, bo'sh bo'lguncha uning yonida kutishadi. O'z ishini bajarib, birinchi ip xonani tark etadi va kalitni chiqaradi. Va men doimo kalit haqida gapirganim bejiz emas edi, chunki u haqiqatan ham mavjud. Bu band/erkin holatga ega bo'lgan maxsus ob'ekt. Ushbu ob'ekt har bir Java ob'ektiga biriktirilgan, shuning uchun sinxronlashtirilgan blokdan foydalanganda biz qavs ichida mutexi eshikni yopmoqchi bo'lgan ob'ektni ko'rsatishimiz kerak:
Cat cat = new Cat();
synchronized (cat) {
   // некоторая логика
}
Birinchi misolda ( Main.class ) qilganimdek, sinf mutexidan ham foydalanishingiz mumkin . Usul bo'yicha sinxronlashtirilgandan foydalanganda , biz yopmoqchi bo'lgan ob'ektni belgilamaymiz, to'g'rimi? Bunday holda, statik bo'lmagan usul uchun u ushbu ob'ektning mutexida , ya'ni ushbu sinfning joriy ob'ektida yopiladi. Statik sinf joriy sinfning mutexida yopiladi ( this.getClass(); ). Muteks haqida ko'proq ma'lumotni bu erda o'qishingiz mumkin . Xo'sh, sinxronizatsiya haqida bu erda o'qing . Wait() - bu muteksni chiqaradigan va joriy monitörga biriktirilgandek (langar kabi narsa) joriy ipni kutish rejimiga o'tkazadigan usul. Shu sababli, bu usulni faqat sinxronlashtirilgan blok yoki usuldan chaqirish mumkin (aks holda, u nimani ozod qilishi va nimani kutishi kerak). Shuni ham yodda tutingki, bu Object sinfining usuli . Aniqrog'i, bitta emas, hatto uchtasi:
  • Wait() - joriy ipni boshqa mavzu ushbu ob'ekt uchun notify() yoki notifyAll() usulini chaqirmaguncha kutish rejimiga o'tkazadi (bu usullar haqida keyinroq gaplashamiz).

  • Kutish (uzoq vaqt tugashi) - joriy mavzuni boshqa mavzu notify() yoki notifyAll() usulini chaqirmaguncha yoki belgilangan vaqt tugaguncha kutish rejimiga o'tkazadi .

  • Kutish (uzoq vaqt tugashi, int nanos) - avvalgisiga o'xshash, faqat nanos nanosoniyalarni belgilashga imkon beradi (vaqtni aniqroq sozlash).

  • Notify() - joriy sinxronizatsiya blokining bitta tasodifiy ipini uyg'otish imkonini beruvchi usul. Shunga qaramay, uni faqat sinxronlashtirilgan blok yoki usulda chaqirish mumkin (oxir-oqibat, boshqa joylarda muzdan tushirish uchun hech kim bo'lmaydi).

  • NotifyAll() joriy monitordagi barcha kutayotgan iplarni uyg'otadigan usuldir (shuningdek, faqat sinxronlashtirilgan blok yoki usulda qo'llaniladi).

110. Oqim qanday to'xtatiladi?

Aytish kerak bo'lgan birinchi narsa, run() usuli to'liq bajarilganda , ip avtomatik ravishda yo'q qilinadi. Ammo ba'zida bu usul tugashidan oldin uni muddatidan oldin o'ldirish kerak bo'ladi. Xo'sh, keyin nima qilishimiz kerak? Ehtimol, Thread ob'ektida stop() usuli bo'lishi kerakmi ? Qanday bo'lmasin! Ushbu usul eskirgan deb hisoblanadi va tizimning ishdan chiqishiga olib kelishi mumkin. Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish.  12-6-qismXo'sh, keyin nima? Buning ikki yo'li bor: Birinchisi , ichki mantiqiy bayroqdan foydalanish. Keling, bir misolni ko'rib chiqaylik. Bizda to'liq to'xtaguncha ekranda ma'lum bir iborani ko'rsatishi kerak bo'lgan mavzuni o'zimiz amalga oshirdik:
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() usulidan foydalanganda ichki bayroq noto'g'ri bo'ladi va ishga tushirish usuli ishlashni to'xtatadi. Keling, uni asosiyda ishga tushiramiz :
System.out.println("Начало выполнения программы");
CustomThread thread = new CustomThread();
thread.start();
Thread.sleep(3);
// пока наш основной поток спит, вспомогательный  CustomThread работает и выводит в коноль своё сообщение
thread.stopRunningThread();
System.out.println("Конец выполнения программы");
Natijada, biz konsolda shunga o'xshash narsani ko'ramiz:
Dasturning bajarilishini boshlash Mavzu ba'zi bir mantiqni bajarmoqda... Ip qandaydir mantiqni bajarmoqda... Mavzu qandaydir mantiqni bajarmoqda... Mavzu qandaydir mantiqni bajarmoqda... Mavzu qandaydir mantiqni bajarmoqda... ip ba'zi bir mantiqni bajarmoqda... Dastur bajarilishining oxiri Ish to'xtatildi!
Bu shuni anglatadiki, bizning ipimiz ishladi, konsolga ma'lum miqdordagi xabarlar chiqdi va muvaffaqiyatli to'xtatildi. Shuni ta'kidlaymanki, chiqadigan xabarlar soni ishga tushirishdan boshqasiga o'zgaradi; ba'zida qo'shimcha ish zarrachalari hech narsa chiqarmadi. Men sezganimdek, bu asosiy ipning uyqu vaqtiga bog'liq, u qanchalik uzoq bo'lsa, qo'shimcha ipning hech narsa chiqmasligi ehtimoli shunchalik kam. 1ms uyqu vaqti bilan xabarlar deyarli hech qachon chiqmaydi, lekin agar siz uni 20ms ga o'rnatsangiz, u deyarli har doim ishlaydi. Ehtimol, vaqt qisqa bo'lsa, ip oddiygina o'z ishini boshlash va boshlash uchun vaqt topolmaydi va darhol to'xtatiladi. Ikkinchi yo'l Thread ob'ektida interrupted() usulidan foydalanish bo'lib , u ichki uzilish bayrog'ining qiymatini qaytaradi (bu bayroq sukut bo'yicha noto'g'ri ) va uning boshqa interrupt() usuli , bu bayroqni rost (bu bo'lganda) bayroq rost bo'lsa , ip o'z ishini to'xtatishi kerak). Keling, bir misolni ko'rib chiqaylik:
public class CustomThread extends Thread {

   @Override
   public void run() {
       {
           while (!Thread.interrupted()) {
               System.out.println("Поток выполняет некую логику...");
           }
           System.out.println("Поток остановлен!");
       }
   }
}
Asosiy ishga tushirish :
System.out.println("Начало выполнения программы");
Thread thread = new CustomThread();
thread.start();
Thread.sleep(3);
thread.interrupt();
System.out.println("Конец выполнения программы");
Amalga oshirish natijasi birinchi holatda bo'lgani kabi bo'ladi, lekin menga bu yondashuv ko'proq yoqadi: biz kamroq kod yozamiz va ko'proq tayyor, standart funksiyalardan foydalanamiz. Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish.  12-7-qismMana bugun biz to'xtab qolamiz.Java dasturchisi uchun intervyudan olingan savollar va javoblarni tahlil qilish.  12-8-qism
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION