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

Qrupda dərc edilmişdir
Salam! Bilik gücdür. İlk müsahibədən əvvəl nə qədər çox bilik əldə etsəniz, bir o qədər inamlı olacaqsınız. Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  12-1 hissəYaxşı bir bilik miqdarı ilə sizi çaşdırmaq çətin olacaq və eyni zamanda müsahibinizi xoş təəccübləndirə biləcəksiniz. Buna görə də, bu gün, daha çox uzatmadan, Java tərtibatçısı üçün 250+ sualı araşdıraraq nəzəri bazanızı gücləndirməyə davam edəcəyik . Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  12-2 hissə

103. Vərəsəlikdə istisnaların yoxlanılması qaydaları hansılardır?

Əgər sualı düzgün başa düşdümsə, miraslıq zamanı istisnalarla işləmə qaydalarını soruşurlar və bunlar aşağıdakılardır:
  • Nəsildə/tətbiqdə ləğv edilmiş və ya həyata keçirilmiş metod iyerarxiyada supersinif/interfeys metodundakı istisnalardan daha yüksək olan yoxlanılmış istisnaları ata bilməz.
Yəni, IOException atan bir üsulla müəyyən bir Animal interfeysimiz varsa :
public  interface Animal {
   void voice() throws IOException;
}
Bu interfeysin həyata keçirilməsində biz daha ümumi bir istisna ata bilmərik (məsələn, Exception , Throwable ), lakin onu FileNotFoundException kimi nəsil istisna ilə əvəz edə bilərik :
public class Cat implements Animal {
   @Override
   public void voice() throws FileNotFoundException {
// некоторая реализация
   }
}
  • Alt sinif konstruktoru obyekti yaratarkən çağırılan supersinif konstruktoru tərəfindən atılan bütün istisna siniflərini atış bloklarına daxil etməlidir.
Tutaq ki, Animal sinifinin konstruktoru bir çox istisnalar atır:
public class Animal {
  public Animal() throws ArithmeticException, NullPointerException, IOException {
  }
Sonra sinif varisi onları konstruktorda da göstərməlidir:
public class Cat extends Animal {
   public Cat() throws ArithmeticException, NullPointerException, IOException {
       super();
   }
Yaxud, metodlarda olduğu kimi, eyni istisnaları deyil, daha ümumi olanları qeyd edə bilərsiniz. Bizim vəziyyətimizdə daha ümumi bir istisna - İstisna - qeyd etmək kifayətdir , çünki bu, nəzərdən keçirilən hər üç istisnanın ortaq əcdadıdır:
public class Cat extends Animal {
   public Cat() throws Exception {
       super();
   }

104. Finally blokunun icra olunmayacağının kodunu yaza bilərsinizmi?

Əvvəlcə nəhayət nə olduğunu xatırlayaq . Əvvəllər biz istisnaların tutulması mexanizminə baxmışdıq: try bloku tutma sahəsini təsvir edir, tutma blok(lar) ı isə konkret istisna atıldıqda işləyəcək koddur. Nəhayət, tutma ilə əvəz edilə bilən , lakin bir-birini istisna edən üçüncü kod blokudur . Bu blokun mahiyyəti ondan ibarətdir ki, içindəki kod cəhd və ya tutma nəticəsindən asılı olmayaraq (istisnanın atılıb-atılmamasından asılı olmayaraq) həmişə işləyir. Onun uğursuzluq halları çox nadirdir və anormaldır. Ən sadə uğursuzluq halı yuxarıdakı kodda System.exit(0) metodunun çağırılmasıdır ki , bu da proqramı dayandırır (onu söndürür):
try {
   throw new IOException();
} catch (IOException e) {
   System.exit(0);
} finally {
   System.out.println("Данное сообщение не будет выведенно в консоль");
}
Nəhayət işləməyəcək bəzi digər vəziyyətlər də var :
  • Kritik sistem problemlərinin səbəb olduğu proqramın qeyri-normal dayandırılması və ya tətbiqi "çökə biləcək" bəzi Xətanın düşməsi ( sətə yaddaşın daşması zamanı baş verən eyni StackOwerflowError xəta nümunəsi ola bilər).
  • Deamon ipi ry- dən keçəndə ... nəhayət bloklayın və bununla paralel olaraq proqram bitir. Axı, deamon ipi fon hərəkətləri üçün bir ipdir, yəni prioritet və məcburi deyil və tətbiq işinin bitməsini gözləməyəcək.
  • Ən çox yayılmış sonsuz döngə, try or catch , bir dəfə axın orada əbədi qalacaq:

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

Bu sual yeni başlayanlar üçün müsahibələrdə olduqca populyardır, buna görə də bu müstəsna hallardan bir neçəsini xatırlamağa dəyər. Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  12-3-cü hissə

105. Bir tutma blokunda çoxlu istisnaların işlənməsi nümunəsini yazın

1) Ola bilsin ki, sual səhv verilib. Mən başa düşdüyüm qədər, bu sual bir sınaq bloku üçün birdən çox tutma deməkdir :
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);
}
Əgər try blokunda istisna baş verərsə , onda tutma blokları növbə ilə onu yuxarıdan aşağı tutmağa çalışır.Müəyyən tutma bloku uğur qazanarsa, o, istisnanı idarə etmək hüququ əldə edir, aşağıda qalan bloklar isə artıq olmayacaq. onu tutmağa və öz yolu ilə emal etməyə cəhd edə bilərlər. Buna görə də, tutma blok zəncirində daha dar istisnalar daha yüksək , daha geniş istisnalar isə aşağı yerləşdirilir. Məsələn, əgər ilk tutma blokumuzda İstisna sinifinin bir istisnası tutulursa , yoxlanılan istisnalar qalan bloklara daxil ola bilməyəcək ( İstisna nəsli ilə qalan bloklar tamamilə yararsız olacaq). 2) Sual düzgün verildi. Bu halda bizim emalımız aşağıdakı kimi görünəcək:
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 vasitəsilə bir istisna tutaraq , obyektin müəyyən bir növə aid olub-olmadığını yoxlamaq üçün istifadə edilən instanceof metodu ilə onun xüsusi növünü öyrənməyə çalışırıq ki, sonradan mənfi nəticələr olmadan onu bu tipə qədər daralda bilək. Hər iki nəzərdən keçirilən yanaşma eyni vəziyyətdə istifadə edilə bilər, lakin sualın düzgün olmadığını söylədim, çünki ikinci variantı yaxşı adlandırmazdım və təcrübəmdə heç vaxt görməmişəm, eyni zamanda multicatches ilə birinci üsul geniş yayılmışdır. diqqət.yaymaq. Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  12-4-cü hissə

106. İstisnanı atmağa məcbur etməyə hansı operator icazə verir? Bir nümunə yazın

Yuxarıda bir neçə dəfə istifadə etmişəm, amma yenə də bu açar sözü təkrarlayacağam - atmaq . İstifadə nümunəsi (istisna məcbur etmək):
throw new NullPointerException();

107. Əsas metod atışlar istisnasını ata bilərmi? Əgər belədirsə, o, hara köçürüləcək?

Əvvəlcə qeyd etmək istəyirəm ki, main adi metoddan başqa bir şey deyil və bəli, proqramı icra etməyə başlamaq üçün virtual maşın tərəfindən çağırılır, lakin bundan əlavə, onu istənilən başqa koddan çağırmaq olar. Yəni, atışlardan sonra yoxlanılan istisnaların müəyyən edilməsi üçün adi qaydalara da tabedir :
public static void main(String[] args) throws IOException {
Buna uyğun olaraq, istisnalar da ola bilər. Əgər main hansısa üsulla çağırılmayıbsa, lakin proqramın işə salınma nöqtəsi kimi işə salınıbsa, onun atdığı istisna .UncaughtExceptionHandler interceptoru tərəfindən idarə olunacaq . Bu işləyici hər mövzuda birdir (yəni hər iplikdə bir işləyici). Lazım gələrsə, siz öz işləyicinizi yarada və onu Thread obyektində çağırılan setDefaultUncaughtExceptionHandler metodundan istifadə edərək təyin edə bilərsiniz .

Çox iş parçacığı

Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  12-5-ci hissə

108. Çoxilliklərlə işləmək üçün hansı alətləri bilirsiniz?

Java-da Multithreading istifadə üçün əsas/əsas alətlər:
  • Sinxronlaşdırılmış, bir iplik daxil olduqda, digər mövzulardan bir metodun/blokun bağlanması (bloklanması) mexanizmidir.
  • Dəyişən, müxtəlif mövzular tərəfindən dəyişənə ardıcıl girişi təmin etmək üçün bir mexanizmdir, yəni dəyişəndə ​​bu dəyişdiricinin olması ilə bütün təyinat və oxu əməliyyatları atomik olmalıdır. Başqa sözlə, mövzular bu dəyişəni öz yerli yaddaşına köçürməyəcək və onu dəyişdirməyəcək, lakin onun orijinal dəyərini dəyişəcək.
Uçucu haqqında daha çox oxuyun .
  • Runnable müəyyən bir sinifdə həyata keçirilə bilən interfeysdir (xüsusən də onun işləmə metodu):
public class CustomRunnable implements Runnable {
   @Override
   public void run() {
       // некоторая логика
   }
}
Və bu sinifin obyektini yaratdıqdan sonra siz bu obyekti yeni Thread obyektinin konstruktorunda təyin edərək və onun start() metodunu çağıraraq yeni mövzuya başlaya bilərsiniz :
Runnable runnable = new CustomRunnable();
new Thread(runnable).start();
Başlanğıc metodu həyata keçirilən run() metodunu ayrı bir mövzuda işlədir .
  • Thread bir sinifdir, ondan miras qalır ( çalışma metodunu ləğv edərkən ):
public class CustomThread extends Thread {
   @Override
   public void run() {
       // некоторая логика
   }
}
Və bu sinifin obyektini yaradaraq və onu start() metodundan istifadə etməklə işə salmaqla , biz bununla da yeni başlıq açacağıq:
new CustomThread().start();
  • Paralellik çox yivli mühitdə işləmək üçün alətlər paketidir.
O, ibarətdir:
  • Concurrent Collections - çox yivli mühitdə işləmək üçün ixtisaslaşmış kolleksiyalar toplusu.
  • Queues - çox yivli mühit üçün ixtisaslaşdırılmış növbələr (bloklayan və bloklanmayan).
  • Sinxronizatorlar çox yivli mühitdə işləmək üçün xüsusi yardımçı proqramlardır.
  • İcraçılar iplik hovuzlarının yaradılması mexanizmləridir.
  • Kilidlər - mövzu sinxronizasiya mexanizmləri (standart olanlardan daha çevik - sinxronizasiya, gözləyin, bildirin, xəbərdar edin).
  • Atomlar çox yivli icra üçün optimallaşdırılmış siniflərdir; hər bir əməliyyat atomikdir.
Paralel paket haqqında ətraflı burada oxuyun .

109. Mövzular arasında sinxronizasiya haqqında danışın. wait(), notify() - notifyAll() join() metodları nə üçün istifadə olunur?

Sualı başa düşdüyüm qədər, mövzular arasında sinxronizasiya açar dəyişdirici ilə əlaqəlidir - sinxronizasiya . Bu dəyişdirici birbaşa blokun yanında yerləşdirilə bilər:
synchronized (Main.class) {
   // некоторая логика
}
Və ya birbaşa metod imzasında:
public synchronized void move() {
   // некоторая логика}
Daha əvvəl dediyim kimi, sinxronizasiya , bir ip artıq daxil olduqda, başqa mövzulardan bloku/metodunu bağlamağa imkan verən mexanizmdir. Bloku/metodunu otaq kimi düşünün. Oraya gələn bəzi axın içəri girib onu bağlayacaq, digər axınlar otağa gəlib onun bağlı olduğunu görüb boş olana qədər yanında gözləyəcək. İşini gördükdən sonra ilk ip otaqdan çıxır və açarı buraxır. Həmişə açar haqqında danışmağım əbəs yerə deyildi, çünki o, həqiqətən mövcuddur. Bu, məşğul/sərbəst vəziyyətə malik olan xüsusi obyektdir. Bu obyekt hər bir Java obyektinə əlavə olunur, ona görə də sinxronlaşdırılmış blokdan istifadə edərkən biz mötərizədə mutexi ilə qapını bağlamaq istədiyimiz obyekti göstərməliyik:
Cat cat = new Cat();
synchronized (cat) {
   // некоторая логика
}
Siz həmçinin birinci misalda etdiyim kimi sinif mutexindən istifadə edə bilərsiniz ( Main.class ). Metodda sinxronizasiyadan istifadə edərkən , bağlamaq istədiyimiz obyekti göstərmirik, elə deyilmi? Bu halda, qeyri-statik metod üçün bu obyektin mutexində , yəni bu sinfin cari obyektində bağlanacaq. Statik olan cari sinfin mutexində bağlanacaq ( this.getClass(); ). Muteks haqqında daha ətraflı burada oxuya bilərsiniz . Yaxşı, sinxronizasiya haqqında burada oxuyun . Wait() mutexi buraxan və cari ipi cari monitora qoşulmuş kimi gözləmə rejiminə keçirən bir üsuldur (lövbər kimi bir şey). Buna görə də, bu metodu yalnız sinxronlaşdırılmış blokdan və ya metoddan çağırmaq olar (əks halda, nə pulsuz olmalıdır və nə gözləməlidir). Onu da qeyd edək ki, bu Object sinifinin metodudur . Daha doğrusu, bir yox, hətta üç:
  • Wait() - başqa mövzu bu obyekt üçün notify() və ya notifyAll() metodunu çağırana qədər cari ipi gözləmə rejiminə qoyur (bu üsullar haqqında daha sonra danışacağıq).

  • Gözləyin (uzun zaman aşımı) - başqa bir başlıq bu obyektdə notify() və ya notifyAll() metodunu çağırana qədər və ya müəyyən edilmiş fasilə müddəti bitənə qədər cari başlığı gözləmə rejiminə qoyur .

  • Gözləyin (uzun fasilə, int nanos) - əvvəlkinə bənzər, yalnız nanos nanosaniyələri təyin etməyə imkan verir (daha dəqiq vaxt təyini).

  • Notify() cari sinxronizasiya blokunun bir təsadüfi ipini oyatmağa imkan verən bir üsuldur. Yenə də onu yalnız sinxronlaşdırılmış blokda və ya metodda çağırmaq olar (axı, başqa yerlərdə onu açmaq üçün heç kim olmayacaq).

  • NotifyAll() cari monitorda bütün gözləyən ipləri oyandıran bir üsuldur (həmçinin yalnız sinxronlaşdırılmış blok və ya metodda istifadə olunur).

110. Axını necə dayandırmaq olar?

Demək lazım olan ilk şey budur ki, run() metodu tam icra edildikdə , ip avtomatik olaraq məhv edilir. Ancaq bəzən bu üsul başa çatmazdan əvvəl onu vaxtından əvvəl öldürmək lazımdır. Bəs onda nə etməliyik? Bəlkə Thread obyektində stop() metodu olmalıdır ? Necə olursa olsun! Bu üsul köhnəlmiş hesab olunur və sistemin çökməsinə səbəb ola bilər. Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  12-6 hissəYaxşı, bəs onda? Bunun iki yolu var: Birincisi , daxili boolean bayrağınızdan istifadə etməkdir. Bir nümunəyə baxaq. Tamamilə dayanana qədər ekranda müəyyən bir ifadəni göstərməli olan bir mövzunun öz tətbiqimiz var:
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() metodundan istifadə edərkən daxili bayraq false olur və run metodu işləməyi dayandırır. Gəlin onu əsas işə salaq :
System.out.println("Начало выполнения программы");
CustomThread thread = new CustomThread();
thread.start();
Thread.sleep(3);
// пока наш основной поток спит, вспомогательный  CustomThread работает и выводит в коноль своё сообщение
thread.stopRunningThread();
System.out.println("Конец выполнения программы");
Nəticədə, konsolda belə bir şey görəcəyik:
Proqramın icrasının başlanması Mövzu bəzi məntiqi yerinə yetirir... Mövzu bəzi məntiqi icra edir... Mövzu bəzi məntiqi yerinə yetirir... Mövzu bəzi məntiqi icra edir... Mövzu bəzi məntiqi yerinə yetirir... mövzu bəzi məntiqi icra edir... Proqramın icrasının sonu Mövzu dayandırıldı!
Bu o deməkdir ki, ipimiz işlədi, konsola müəyyən sayda mesaj çıxdı və uğurla dayandırıldı. Qeyd edim ki, buraxılan mesajların sayı qaçışdan qaçışa dəyişəcək; bəzən əlavə başlıq heç bir nəticə vermədi. Qeyd etdiyim kimi, bu, əsas ipin yuxu müddətindən asılıdır, nə qədər uzun olarsa, əlavə ipin heç bir nəticə verməməsi şansı bir o qədər azdır. 1ms-lik yuxu müddəti ilə mesajlar demək olar ki, heç vaxt çıxmır, lakin onu 20ms-ə təyin etsəniz, demək olar ki, həmişə işləyir. Ola bilsin ki, vaxt qısa olduqda, ipin sadəcə işə başlamaq və başlamaq üçün vaxtı yoxdur və dərhal dayandırılır. İkinci yol, Thread obyektində daxili kəsmə bayrağının dəyərini qaytaran interrupted() metodundan (bu bayraq defolt olaraq yanlışdır ) və bu bayrağı doğru olaraq təyin edən digər interrupt() metodundan istifadə etməkdir (bu zaman bayraq doğrudur, ip öz işini dayandırmalıdır). Bir misala baxaq:
public class CustomThread extends Thread {

   @Override
   public void run() {
       {
           while (!Thread.interrupted()) {
               System.out.println("Поток выполняет некую логику...");
           }
           System.out.println("Поток остановлен!");
       }
   }
}
Əsas işə salın :
System.out.println("Начало выполнения программы");
Thread thread = new CustomThread();
thread.start();
Thread.sleep(3);
thread.interrupt();
System.out.println("Конец выполнения программы");
İcra nəticəsi birinci halda olduğu kimi olacaq, amma bu yanaşma daha çox xoşuma gəlir: biz daha az kod yazırıq və daha çox hazır, standart funksionallıqdan istifadə edirik. Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  12-7 hissəBu gün burada dayanacağıq.Java tərtibatçısı üçün müsahibələrdən alınan sualların və cavabların təhlili.  12-8 hissə
Seriyadakı digər materiallar:
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION