Dacă vrei să ieși câștigător din procesul de recrutare pentru un viitor rol de programator în care Java este o parte esențială a jobului, este important să te pregătești serios pentru interviul cu angajatorul. Domeniul IT este unul extrem de competitiv și vei concura cu o mulțime de alți candidați care își doresc același job.
Fie că ai studiat programare la școală, la cursuri sau pe cont propriu, este ceva normal să te încerce sentimente de nesiguranță și emoție când vine vorba de interviul de angajare. Dar le poți transforma în emoții constructive care să te ajute să te pregătești în avans, să-ți cunoști punctele forte, dar și sincopele din formare, pentru a evita să mergi nepregătit și să primești refuzuri interviu după interviu.
Ți-am pregătit 50 de întrebări pentru un interviu tehnic Java în care angajatorul urmărește să afle cât de bine cunoști acest limbaj de programare – sunt întrebări și exerciții pe care și noi, la Software Development Academy, le urmărim și evaluăm în procesul de pregătire al studenților pentru interviurile și job-urile pe care le garantăm.
Îți dăm desigur și răspunsurile, dar sfatul nostru nu este să memorezi întrebările și răspunsurile din acest articol, ci să le folosești pentru a te pregăti cât mai bine pentru interviul tehnic Java. Completează răspunsurile cu exemple din proiectele la care ai lucrat, mai mult decât partea teoretică, pentru că angajatorii apreciază abilitatea de a pune noțiunile în aplicare.
Să începem!
Java este un limbaj de programare high level, orientat pe obiecte, robust, sigur, independent de platformă, multithreaded și portabil. A fost dezvoltat de James Gosling în iunie 1991. Poate fi cunoscut și ca platformă, deoarece oferă propriul JRE și API.
Independența platformei înseamnă că executarea programului nu depinde de tipul de sistem de operare, poate fi oricare: Linux, Windows, Mac, etc. Așadar, codul este compilat o singură dată și poate rula pe orice sistem.
Java este un limbaj de programare atât compilator (javac), cât și interpret (jvm) iar codul sursă este universal și este disponibil în toate sistemele de operare pe care este instalat.
Limbajul de programare Java are următoarele caracteristici:
De asemenea, acceptă funcții din limbile sale native, adică C și C++.
Final keyword în Java este utilizat pentru a restricționa utilizarea variabilei, clasei și metodei.
Acest keyword din Java este o variabilă de referință care este utilizată pentru a face referire la obiectele clasei părinte. Cuvântul cheie „super” a apărut prin asocierea cu conceptul de inheritance. Ori de câte ori creezi instanța unei subclase, se creează implicit o instanță a clasei părinte, adică menționată de variabila super referință.
Super keyword este folosit pentru:
Java Virtual Machine, așa cum indică și numele, este o mașină virtuală care permite computerului să ruleze programul Java. JVM acționează ca un motor de rulare care apelează metoda principală prezentă în codul Java. JVM este specificația care trebuie implementată în sistemul informatic. Codul Java este compilat de JVM pentru a fi un Bytecode care este independent de device și apropiat de codul nativ.
String este o clasă imutabilă, asta înseamnă că nu îi poți modifica conținutul odată creat. În timp ce StringBuffer este o clasă modificabilă, unde este posibilă schimbarea conținutul mai târziu. Ori de câte ori modifici conținutul obiectului String, acesta creează un șir nou la care se face referire, nu se modifică cel existent. Acesta este motivul pentru care performanța cu StringBuffer este mai bună decât cu String.
Inheritance, sau moștenirea în traducere, este un mecanism prin care un obiect dobândește toate proprietățile și comportamentul altui obiect dintr-o altă clasă.
Este folosit pentru Code Reusability și Method Overriding. Ideea din spatele moștenirii în Java este că poți crea clase noi care sunt construite pe clasele existente. Când moștenești dintr-o clasă existentă, poți reutiliza metode și câmpuri clasei părinte. Mai mult, poți adăuga noi metode și câmpuri și în clasa curentă. Moștenirea reprezintă relația IS-A care este cunoscută și ca relația parent-child.
Există cinci tipuri de moștenire în Java:
Java acceptă multiple inheritance, dar nu prin clase, ci doar prin interfețele sale. Motivul este evitarea conflictului și complexității care pot să apară și menținerea Java la nivel de limbaj simplu orientat pe obiecte.
Există diverse avantaje ale utilizării moștenirii în Java, iată câteva dintre acestea:
În Java, clasele de nivel superior nu pot fi private sau protejate, dar clasele interioare da. Motivul pentru care o clasă de nivel superior nu poate fi privată este foarte evident – nimeni nu poate vedea o clasă privată și, prin urmare, nu o poate folosi. Declararea unei clase ca protejată nu are nici un sens.
Singura diferență între vizibilitatea implicită și vizibilitatea protejată este că o putem folosi în orice pachet, moștenind-o. Deoarece în Java nu există un astfel de concept de moștenire a pachetelor, definirea unei clase ca protejată nu diferă de cea implicită.
Diferențele dintre aceste 2 keywords sunt următoarele:
În Java nu este nevoie să distrugi obiecte în mod explicit – „Garbage Collector” face asta în mod automat. Garbage Collector verifică dacă nu există referințe la un obiect și presupune că acel obiect nu mai este necesar iar memoria ocupată de obiect poate fi eliberată.
Uneori, un obiect poate conține resurse non-java, cum ar fi conexiunea la baza de date, atunci trebuie să te asiguri că aceste resurse sunt eliberate înainte ca obiectul să fie distrus. Pentru a efectua o astfel de operație Java furnizează “protected void finalize ()” în clasa obiect. Poți înlocui această metodă și poți efectua sarcinile necesare. Chiar înainte ca un obiect să fie eliberat, timpul de rulare Java aplică metoda finalize () pe acel obiect.
Set și List sunt ambele derivate din interfața Collection. List poate conține valori duplicat, dar Set nu permite acest lucru. În List datele interfeței sunt prezente în ordinea pe care ai inserat-o, dar în cazul Set ordinea de inserare nu este păstrată.
Apelând System.exit (0) în blocul try sau catch, poți sări peste blocul final. Metoda System.exit (int) poate arunca SecurityException. Dacă System.exit (0) iese din JVM fără a arunca acea excepție, atunci blocul nu se va executa în cele din urmă. Dar, dacă System.exit (0) aruncă o excepție de securitate, atunci blocul va fi executat.
Suprascrierea este legată de polimorfismul în timpul rulării. O subclasă (sau o clasă derivată) oferă o implementare specifică a unei metode în superclasă (sau clasă de bază) în timp de execuție.
Supraîncărcarea este legată de polimorfismul de timp (sau static) de compilare. Această caracteristică permite diferitelor metode să aibă același nume, dar semnături diferite, în special numărul și tipul parametrilor de intrare.
Poți supraîncărca metodele statice? Răspunsul este da. Poți avea două metode statice cu același nume, dar diferențe în parametrii de intrare.
Poți anula metodele statice în Java? Poți declara metode statice cu aceeași semnătură în subclasă, dar nu este considerată prioritară, deoarece nu va exista polimorfism în timpul rulării. Prin urmare, răspunsul este „Nu”. Metodele statice nu pot fi suprascrise, deoarece suprascrierea metodei are loc numai în contextul căutării dinamice (adică în timpul rulării) a metodelor. Metodele statice (după numele lor) sunt căutate în mod static (adică la compilare).
Metoda este statică pentru că altfel ar exista ambiguitate: care constructor ar trebui numit? Mai ales dacă clasa arată astfel:
public class JavaClass
{
protected JavaClass(int x)
{ }
public void main(String[ ] args)
{
}
}
Programul se compilează cu succes. Dar în timpul rulării apare o eroare „NoSuchMethodError”.
În cadrul unei metode de instanță sau a unui constructor, “this” este o referință la obiectul curent – obiectul a cărui metodă sau constructor este apelat. Poți face referire la orice membru al obiectului curent dintr-o metodă de instanță sau un constructor folosind cuvântul cheie “this”.
Utilizarea acestui cuvânt cheie:
Clasele abstracte sunt clase care conțin una sau mai multe metode abstracte. O metodă abstractă este o metodă care este declarată, dar nu conține nicio implementare. Este posibil ca aceste clasele abstracte să nu fie instanțiate și să necesite subclasele pentru a furniza implementări pentru metodele abstracte.
În Java, putem avea o clasă abstractă fără nicio metodă abstractă. Acest lucru permite crearea de clase care nu pot fi instanțiate, ci doar moștenite.
Principala metodă în Java este la fel ca orice altă metodă și poate fi supraîncărcată într-un mod similar, JVM caută întotdeauna semnătura metodei pentru a lansa programul.
Clonarea obiectelor înseamnă crearea unei copii exacte a obiectului original. Dacă o clasă trebuie să accepte clonarea, trebuie să implementeze interfața java.lang.Cloneable și să anuleze metoda clone () din clasa Object. Sintaxa metodei clone () este:
protected Object clone() throws CloneNotSupportedException
Dacă clasa obiectului nu implementează interfața Cloneable, atunci lansează o excepție „CloneNotSupportedException”.
În Java, funcțiile nu pot fi supraîncărcate dacă diferă doar în ceea ce privește tipul de returnare. Tipul de funcții returnat nu este o parte a numelui modificat care este generat de compilator pentru identificarea unică a fiecărei funcții. Numărul de argumente, Tipul de argumente și Secvența argumentelor sunt parametrii care sunt utilizați pentru a genera numele unic modificat pentru fiecare funcție. Pe baza acestor nume unice, compilatorul poate înțelege ce funcție trebuie apelată chiar dacă numele sunt aceleași (supraîncărcare).
Nu, o metodă privată nu poate fi anulată, deoarece nu este vizibilă din nicio altă clasă.
O variabilă finală în Java poate primi o valoare o singură dată, poți atribui o valoare fie în declarație, fie ulterior.
final int i = 10;
i = 30; // Error because i is final.
O variabilă finală goală în Java este o variabilă finală care nu este inițializată în timpul declarației. Iată un exemplu simplu de blank final variable:
// A simple blank final example
final int i;
i = 30;
În Java, toate obiectele sunt alocate dinamic pe Heap. Atunci când declari doar o variabilă de tip clasă, se creează doar o referință iar memoria nu este alocată pentru obiect. Pentru a aloca memorie unui obiect, se folosește new (). Deci obiectului i se alocă întotdeauna memorie pe Heap.
Compilatorul Just-In-Time (JIT) este folosit pentru a îmbunătăți performanța. JIT compilează părți ale bytecode-ului care au funcționalități similare în același timp și, prin urmare, reduce timpul necesar pentru compilare. Aici termenul „compilator” se referă la un traducător de la setul de instrucțiuni al unei mașini virtuale Java (JVM) la setul de instrucțiuni al unui anumit CPU.
Da, Java permite salvarea fișierului java numai prin .java – este nevoie să-l compilezi prin javac .java și să rulezi prin java classname. Iată un exemplu simplu:
//save by .java only
class A{
public static void main(String args[]){
System.out.println(„Hello java”);
}
}
//compile by javac .java
//run by java A
JVM este acronimul pentru Java Virtual Machine – o mașină abstractă care oferă mediul de rulare în care poate fi executat bytecode Java. JVM-urile sunt disponibile pentru multe platforme hardware și software (deci JVM depinde de platformă). Este o instanță de rulare care este creată atunci când rulezu clasa Java. Există trei noțiuni ale JVM: specificație, implementare și instanță.
JRE înseamnă Java Runtime Environment și reprezintă un set de instrumente software care sunt utilizate pentru dezvoltarea aplicațiilor Java. Este folosit pentru a furniza mediul de rulare. Este implementarea JVM și conține un set de biblioteci + alte fișiere pe care JVM le folosește în timpul execuției.
JDK este un acronim pentru Java Development Kit. Este un mediu de dezvoltare software care este folosit pentru a dezvolta aplicații și applet-uri Java. Conține instrumente de dezvoltare JRE +.
Bytecode-ul. Compilatorul Java convertește programele Java în fișierul de clasă (Byte Code) care este limbajul intermediar între codul sursă și codul mașină. Acest bytecode nu este specific platformei și poate fi executat pe orice computer.
În Java, specificatorii de acces sunt cuvintele cheie care sunt utilizate pentru a defini domeniul de acces al metodei, clasei sau al unei variabile. În Java, există patru specificatori de acces:
Metodele sau variabilele definite ca statice sunt partajate între toate obiectele clasei. Statica este partea clasei și nu a obiectului. Variabilele statice sunt stocate în zona de clasă și nu este nevoie să creezi obiectul pentru a accesa astfel de variabile. Prin urmare, static este folosit în cazul în care trebuie să definești variabile sau metode care sunt comune tuturor obiectelor clasei.
De exemplu, în clasa care simulează colecția studenților dintr-o facultate, numele colegiului este atributul comun tuturor studenților. Prin urmare, numele colegiului va fi definit ca fiind static.
Există diverse avantaje ale definirii pachetelor în Java, de exemplu:
Constructorul poate fi definit ca tipul special de metodă care este folosită pentru a inițializa starea unui obiect. Este invocat atunci când clasa este instanțiată, iar memoria este alocată obiectului. De fiecare dată când un obiect este creat folosind cuvântul cheie nou, constructorul implicit al clasei este apelat. Numele constructorului trebuie să fie similar cu numele clasei. Constructorul nu trebuie să aibă un tip de returnare explicit.
Pe baza parametrilor trecuți în constructori, există două tipuri de constructori în Java:
Scopul constructorului default este de a atribui obiectelor valoarea implicită. Compilatorul Java creează implicit un constructor implicit dacă nu există niciun constructor în clasă.
Da, constructorii pot fi supraîncărcați prin modificarea numărului de argumente acceptate de constructor sau prin modificarea tipului de date al parametrilor.
Nu există un copy constructor în Java, cu toate acestea, putem copia valorile de la un obiect la altul.
Există multe modalități de a copia valorile unui obiect în altul în Java, se poate face:
Nu, deoarece this() și super() trebuie să fie prima instrucțiune din constructorul clasei.
Dacă o subclasă oferă o implementare specifică a unei metode care este deja furnizată de clasa sa părinte, aceasta este cunoscută sub numele de Method Overriding. Este folosită pentru polimorfismul runtime și pentru implementarea metodelor de interfață.
Regulile pentru înlocuirea metodei sunt:
Se datorează faptului că metoda statică este o parte a clasei și este legată de clasă. În timp ce metoda instanței este legată de obiect, iar static primește memorie în zona clasei, iar instanța primește memorie într-un heap.
Constructorul nu poate fi niciodată declarat ca final deoarece nu este niciodată moștenit. Constructorii nu sunt metode obișnuite; prin urmare, nu are sens să declari constructori ca finali. Cu toate acestea, dacă încerci să faci acest lucru, compilatorul va arunca o eroare.
Nu, nu putem declara o interfață ca finală, deoarece interfața trebuie implementată de o clasă pentru a oferi definiția acesteia. Dacă vei încerca să faci acest lucru, compilatorul va afișa o eroare.
Polimorfismul runtime sau trimiterea dinamică a metodei este un proces în care un apel la o metodă suprascrisă este rezolvat în timpul rulării, mai degrabă decât întimpul compilării. În acest proces, o metodă suprascrisă este apelată prin variabila de referință a unei superclase. Determinarea metodei care trebuie apelată se bazează pe obiectul la care se referă variabila de referință.
O clasă poate fi creată doar pentru scriere, făcând toate câmpurile private. Clasa write-only va avea numai metode setter care stabilesc valoarea transmisă de la metoda principală la câmpurile private. Nu poți citi proprietățile clasei deoarece nu există o metodă getter în această clasă.
Există, în principal, două tipuri de excepții: bifate și nebifate. Aici, o eroare este considerată o excepție neverificată. Potrivit Oracle, există trei tipuri de excepții:
Pornim de la zero și în câteva luni te echipăm cu un set complet de abilități tehnice dar și acele soft skills de care ai nevoie ca programator – organizare, concentrare, comunicare și muncă în echipă. Iar la final, poți accesa un job de programator junior prin ofertele de muncă pe care ți le vom trimite în fiecară săptămână.
Cele două școli și-au unit forțele! Împreună, oferim:
Înscrie-te acum în programul SDAcademy x Codecool și primește coaching personalizat pentru cariera ta în IT!