CodeGym /Blog Java /Aleatoriu /Explorarea întrebărilor și răspunsurilor de la un intervi...
John Squirrels
Nivel
San Francisco

Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java. Partea 1

Publicat în grup
Bună! CodeGym a reunit un grup divers de oameni. Unii dintre noi nu doresc altceva decât să devină dezvoltatori Java și investim mult timp și efort în dezvoltare. Alții sunt deja dezvoltatori Java. În ambele cazuri, trebuie să fii pregătit să fii testat în interviuri tehnice. Acestea nu sunt ușoare. Ele necesită pregătire atât emoțională, cât și tehnică. Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 1Am dat de curând peste câteva liste mari de întrebări de interviu pentru posturile de dezvoltator Java. Întrebările sunt împărțite pe diferite niveluri: junior, mediu și senior. Nu vă alarmați: nu toate întrebările sunt ușoare, dar cele cu asterisc sunt rar adresate. Întrebările sunt bune și aș dori să încerc să răspund la majoritatea dintre ele. În mod clar, toate acestea nu vor încadra într-un singur articol. La urma urmei, există o mulțime de întrebări acolo. Asta înseamnă că va exista o serie întreagă de articole cu răspunsuri la aceste întrebări de interviu. Permiteți-mi să subliniez imediat câteva puncte: răspunsurile vor fi scurte, deoarece răspunsurile scrise în detaliu pot fi extrase într-un articol separat. De asemenea, la interviuri nu se doresc răspunsuri super detaliate și voluminoase, pentru că intervievatorul tău are doar o oră să te intervieveze pe subiecte esențiale (și,

Întrebări și răspunsuri pentru un post de dezvoltator junior

Intrebari generale

1. Ce modele de design cunoașteți? Povestește-ne despre două modele de design pe care le-ai folosit în munca ta.

Există o mare varietate de modele. Pentru cei dintre voi care doresc să se familiarizeze temeinic cu modelele de design, recomand să citească cartea „Head First. Design Patterns”. Vă va ajuta să învățați cu ușurință detaliile celor mai elementare modele de design. În ceea ce privește modelele de design pe care le-ați putea menționa într-un interviu de angajare, vă vin în minte următoarele:
  • Builder — un șablon folosit frecvent, o alternativă la abordarea clasică a creării de obiecte;
  • Strategie — un model care reprezintă în esență polimorfismul. Adică avem o singură interfață, dar comportamentul programului se modifică în funcție de implementarea specifică a interfeței transmisă funcției (modelul de strategie este acum folosit aproape peste tot în aplicațiile Java).
Dacă nu îți este suficient, fii atent la Spring (dacă ești deja familiarizat cu ea), pentru că este o întreagă platformă de cadre, care, la rândul lor, sunt pătrunse de tipare de la început până la sfârșit. Iată câteva exemple despre ceea ce vorbesc:
  • Factory — acest model poate fi găsit în ApplicationContext (sau în BeanFactory);
  • Singleton — toate boabele sunt singleton în mod implicit;
  • Proxy — practic, totul în Spring folosește acest model într-un fel sau altul, de exemplu, AOP;
  • Lanț de responsabilitate — un model care stă la baza Securității de primăvară;
  • Șablon - folosit în Spring JDBC.

Java Core

Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 2

2. Ce tipuri de date există în Java?

Java are următoarele tipuri de date primitive:
  • octet — numere întregi cuprinse între -128 și 127, ocupă 1 octet;
  • scurt - numere întregi cuprinse între -32768 și 32767, ocupă 2 octeți;
  • int — numere întregi cuprinse între -2147483648 și 2147483647, ocupă 4 octeți;
  • lung — numere întregi de la 9223372036854775808 la 9223372036854775807, ocupă 8 octeți;
  • float — numere în virgulă mobilă care variază de la -3,4E+38 la 3,4E+38, ocupă 4 octeți;
  • dublu — numere în virgulă mobilă care variază de la -1,7E+308 la 1,7E+308, ocupă 8 octeți;
  • char — caractere simple în UTF-16, ocupă 2 octeți;
  • valori booleene adevărate/false, ocupă 1 octet.
Și există tipuri de date de referință care indică obiecte din heap.

3. Cum diferă un obiect de tipurile de date primitive?

Prima diferență este cantitatea de memorie ocupată: primitivele ocupă foarte puțin, deoarece conțin doar propria lor valoare, dar obiectele pot conține o mulțime de valori diferite - atât primitive, cât și referințe la alte obiecte. O a doua diferență este aceasta: Java este un limbaj orientat pe obiecte, așa că totul în Java funcționează este o interacțiune între obiecte. Primitivele nu se potrivesc prea bine aici. De fapt, de aceea Java nu este un limbaj 100% orientat pe obiecte. A treia diferență, care decurge din a doua este că, deoarece Java se concentrează pe interacțiunile cu obiectele, există multe mecanisme diferite pentru gestionarea obiectelor. De exemplu, constructori, metode, excepții (care funcționează în primul rând cu obiecte), etc. Și pentru a permite primitivilor să lucreze cumva în acest mediu orientat pe obiecte, creatorii Java au venit cuwrapper-uri pentru tipurile primitive ( Integer , Character , Double , Boolean ...)

4. Care este diferența dintre transmiterea argumentelor prin referință și după valoare?

Câmpurile primitive își stochează valoarea: de exemplu, dacă setăm int i = 9; , atunci câmpul i stochează valoarea 9. Când avem o referință la un obiect, înseamnă că avem un câmp cu o referință la obiect. Cu alte cuvinte, avem un câmp care stochează adresa obiectului în memorie.

Cat cat = new Cat();
Aceasta înseamnă că câmpurile cu referință la un obiect stochează și valori . Valorile lor sunt adrese de memorie. Adică, cat stochează adresa de memorie a noului obiect Cat() . Când trecem un argument unei metode, valoarea acestuia este copiată. În cazul unei primitive, valoarea primitivei este copiată. În consecință, metoda funcționează cu copie. Când copia este schimbată, originalul nu este afectat. În cazul unui tip de referință, se copiază valoarea adresei de memorie. În consecință, ambele variabile de referință vor stoca adrese care indică același obiect. Și dacă folosim această nouă referință pentru a schimba obiectul, atunci vom descoperi că este schimbată și pentru referința veche. La urma urmei, amândoi indică același obiect.

5. Ce este JVM, JDK și JRE?

JVM înseamnă Java Virtual Machine , care rulează bytecode Java pregenerat de compilator. JRE înseamnă Java Runtime Environment . Practic, este un mediu pentru rularea aplicațiilor Java. Include JVM, biblioteci standard și alte componente pentru rularea applet-urilor și aplicațiilor scrise în limbajul de programare Java. Cu alte cuvinte, JRE este un pachet cu tot ce este necesar pentru a rula un program Java compilat, dar nu include instrumente și utilitare precum compilatoare sau depanare pentru dezvoltarea aplicațiilor. JDK înseamnă Java Development Kit , care este o extensie a JRE. Adică este un mediu nu numai pentru rularea aplicațiilor Java, ci și pentru dezvoltarea acestora. JDK conține tot ce este în JRE, plus diverse instrumente suplimentare - compilatoare și depanare - necesare pentru a crea aplicații Java (include documente Java). Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 3

6. De ce să folosiți JVM-ul?

După cum sa menționat mai sus, Java Virtual Machine este o mașină virtuală care rulează bytecode Java care a fost pre-generat de compilator. Aceasta înseamnă că JVM nu înțelege codul sursă Java. Deci, mai întâi, compilam fișiere .java . Fișierele compilate au .classextensie și sunt acum sub formă de bytecode, pe care JVM-ul îl înțelege. JVM-ul este diferit pentru fiecare sistem de operare. Când JVM rulează fișiere bytecode, le adaptează pentru sistemul de operare pe care rulează. De fapt, deoarece există JVM-uri diferite, JDK-ul (sau JRE) diferă și pentru diferite sisteme de operare (fiecare versiune are nevoie de propriul JVM). Să ne amintim cum funcționează dezvoltarea în alte limbaje de programare. Scrieți un program, apoi codul acestuia este compilat în codul mașinii pentru un anumit sistem de operare și apoi îl puteți rula. Cu alte cuvinte, trebuie să scrieți versiuni diferite ale programului pentru fiecare platformă. Dar procesarea dublă a codului de către Java (compilarea codului sursă în bytecode și apoi procesarea bytecode de către JVM) vă permite să vă bucurați de beneficiile unei soluții multiplatforme. Creăm codul o dată și îl compilăm în bytecode. Apoi îl putem duce pe orice sistem de operare, iar JVM-ul nativ îl poate rula. Și acesta este tocmai legenda lui Javafuncția scrie o dată, rulează oriunde .Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 4

7. Ce este bytecode?

După cum am spus mai sus, compilatorul convertește codul Java în bytecode intermediar (trecem de la fișierele cu extensia .java la fișierele cu extensia .class). În multe privințe, bytecode este similar cu codul mașină, cu excepția faptului că setul său de instrucțiuni nu este pentru un procesor real, ci pentru unul virtual. Acestea fiind spuse, poate include secțiuni concepute pentru un compilator JIT, care optimizează execuția comenzii pentru procesorul real pe care rulează programul. Compilarea JIT, numită și compilare on-the-fly, este o tehnologie care mărește performanța unui program de cod de octet prin compilarea codului de octet în codul mașinii sau alt format în timp ce programul rulează. După cum probabil ați ghicit, JVM utilizează compilatorul JIT atunci când rulează bytecode. Să aruncăm o privire la un exemplu de bytecode: Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 5Nu prea lizibil, nu? Vestea bună este că această instrucțiune nu este destinată nouă. Este pentru JVM.

8. Care sunt caracteristicile unui JavaBean?

Un JavaBean este o clasă Java care urmează anumite reguli. Iată câteva dintre regulile pentru scrierea unui JavaBean :
  1. Clasa trebuie să conțină un constructor gol (fără argument) cu modificatorul de acces public . Acest constructor face posibilă crearea unui obiect al clasei fără probleme inutile (astfel încât să nu existe nicio manipulare inutilă cu argumente).

  2. Câmpurile interne sunt accesate prin metodele de instanță get și set , care ar trebui să aibă implementarea standard. De exemplu, dacă avem un câmp de nume , atunci ar trebui să avem getName și setName , etc. Acest lucru permite diferitelor instrumente (cadre) să obțină și să stabilească automat conținutul de fasole fără nicio dificultate.

  3. Clasa trebuie să suprascrie metodele equals() , hashCode() și toString() .

  4. Clasa trebuie să fie serializabilă. Adică trebuie să aibă interfața marker Serializable sau să implementeze interfața Externalizable . Acest lucru este astfel încât starea boabelor să poată fi salvată, stocată și restaurată în mod fiabil.

Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 6

9. Ce este un OutOfMemoryError?

OutOfMemoryError este o eroare critică de rulare legată de Java Virtual Machine (JVM). Această eroare apare atunci când JVM-ul nu poate aloca un obiect deoarece nu există suficientă memorie pentru acesta, iar colectorul de gunoi nu poate aloca mai multă memorie. Câteva tipuri de OutOfMemoryError :
  • OutOfMemoryError: spațiu heap Java — obiectul nu poate fi alocat pe heap Java din cauza memoriei insuficiente. Această eroare poate fi cauzată de o scurgere de memorie sau de o dimensiune implicită a heap-ului care este prea mică pentru aplicația curentă.

  • OutOfMemoryError: Limita GC Overhead a fost depășită — deoarece datele aplicației abia se încadrează în heap, colectorul de gunoi rulează tot timpul, ceea ce face ca programul Java să ruleze foarte lent. În consecință, limita generală a colectorului de gunoi este depășită și aplicația se blochează cu această eroare.

  • OutOfMemoryError: Mărimea matricei solicitată depășește limita VM - aceasta indică faptul că aplicația a încercat să aloce memorie pentru o matrice care depășește dimensiunea heap. Din nou, acest lucru poate însemna că memoria insuficientă a fost alocată implicit.

  • OutOfMemoryError: Metaspace — heap-ul a rămas fără spațiu alocat pentru metadate (metadatele sunt instrucțiuni pentru clase și metode).

  • OutOfMemoryError: solicitați dimensiunea octeților din motiv. Spațiu de swap epuizat — a apărut o eroare când s-a încercat să aloce memorie din heap și, ca urmare, heap-ului îi lipsește spațiu suficient.

10. Ce este o urmă de stivă? Cum îl primesc?

O urmărire a stivei este o listă a claselor și metodelor care au fost apelate până în acest moment în execuția unei aplicații. Puteți obține urmărirea stivei într-un anumit punct al aplicației făcând acest lucru:

StackTraceElement[] stackTraceElements =Thread.currentThread().getStackTrace();
Acest lucru ne aduce o serie de StackTraceElements aranjate în ordinea Last In First Out (LIFO) . Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 7În Java, când oamenii vorbesc despre o urmărire a stivei, de obicei se referă la o urmă a stivei afișată pe consolă atunci când apare o eroare (sau o excepție). Puteți obține urmărirea stivei de la excepții ca aceasta:

StackTraceElement[] stackTraceElements;
try{
                ...
} catch (Exception e) {
   stackTraceElements = e.getStackTrace();
}
Și dacă vrem să afișăm urmărirea stivei unei excepții pe consolă:

try{
                ...
} catch (Exception e) {
  e.printStackTrace();
}
În plus, dacă apare o eroare, o excepție neverificată sau o excepție verificată netratată , atunci obținem automat urmărirea stivei excepției pe consolă atunci când aplicația se blochează. Iată un mic exemplu de urmărire a stivei pe consolă: Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 8Și pe această notă, vom încheia discuția noastră despre acest subiect astăzi.Explorarea întrebărilor și răspunsurilor de la un interviu de angajare pentru un post de dezvoltator Java.  Partea 1 - 9
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION