34 odabrana Java pitanja za intervju👍
1. Predstavimo Javu
Java je open-source, višeplatformski, objektno-orijentisani programski jezik.

Višeplatformska je jer se Java class fajlovi izvršavaju na virtuelnoj mašini, koja je sama po sebi višeplatformska, a virtuelna mašina ima različite verzije za različite platforme, zato se kaže da je Java višeplatformska.
Objektno-orijentisano programiranje ima nekoliko karakteristika:

- 1.Enkapsulacija
- Dva značenja: prvo značenje je da se svojstva i ponašanje objekta posmatraju kao neraskidiva celina, pa se obe ovo 'enkapsuliraju' u nezavisnu jedinicu (odnosno objekat).
- Drugo značenje je 'sakrivanje informacija': sakrivaju se informacije koje ne treba da budu poznate spoljašnjem svetu. Neka svojstva i ponašanja objekta dozvoljeno je spoljnim korisnicima da znaju ili koriste, ali ne i da menjaju, dok druga svojstva ili ponašanja nije dozvoljeno znati, ili je dozvoljeno samo korišćenje funkcionalnosti objekta uz što veće sakrivanje detalja implementacije funkcije objekta.
Prednosti:
- Dobra enkapsulacija može da smanji spregnutost, u skladu sa stremljenjem programiranja ka 'visokoj koheziji, niskoj spregnutosti'.
- Struktura unutar klase se može slobodno menjati.
- Može se vršiti preciznija kontrola nad varijablama članicama.
- Sakrivanje informacija i detalja implementacije.
- 2.Nasleđivanje
- Nasleđivanje znači da podklasa nasleđuje karakteristike i ponašanje nadklase, tako da objekat podklase (instanca) ima polja instanci i metode nadklase, ili da podklasa nasleđuje metode iz nadklase, čime podklasa dobija isto ponašanje kao nadklasa.
Prednosti:
- Povećava ponovnu iskoristivost koda klase
- Povećava održivost koda
- 3.Polimorfizam
- Polimorfizam je sposobnost istog ponašanja da ima više različitih formi ili oblika. U Java jeziku postoje dva oblika polimorfizma: preopterećenje metoda i polimorfizam objekata:
- 1.Preopterećenje metoda (overloading): unutar jedne klase dozvoljeno je više metoda da koristi isto ime, ali sa različitim parametrima, pa i funkcionalnost koju obavljaju je različita.
- 2.Polimorfizam objekata: objekti podklase mogu da se konvertuju sa objektima nadklase, i u zavisnosti od toga koja se podklasa koristi, funkcionalnost je različita (prepisivanje metode nadklase).
- Polimorfizam je sposobnost istog ponašanja da ima više različitih formi ili oblika. U Java jeziku postoje dva oblika polimorfizma: preopterećenje metoda i polimorfizam objekata:
Prednosti
- Uklanja spregnutost između tipova
- Zamenjivost
- Proširivost
- Interfejsnost
- Fleksibilnost
- Jednostavnost
2. Koje tipove podataka ima Java?

Java uglavnom ima dva tipa podataka
- 1.Osnovni tipovi podataka
- Osnovnih tipova podataka ima osam,
- bajt, short, int, long pripadaju celobrojnom tipu unutar numeričkih tipova
- float, double pripadaju tipu sa pokretnim zarezom unutar numeričkih tipova
- char pripada znakovnom tipu
- boolean pripada bulovom tipu
- Osnovnih tipova podataka ima osam,
- 2.Referentni tipovi podataka
- Referentnih tipova podataka ima tri, i to klasa, interfejs i niz
3. Koja je razlika između interfejsa i apstraktne klase?
- Interfejs je varijanta apstraktne klase, sve metode u interfejsu su apstraktne. Apstraktna klasa je klasa koja deklariše postojanje metoda ali ih ne implementira.
- Interfejs može da nasleđuje više interfejsa, apstraktna klasa ne može.
- Interfejs definiše metode i ne može da ih implementira, podrazumevano su public abstract, dok apstraktna klasa može da implementira deo metoda.
- U interfejsu osnovni tipovi podataka su public static final i mora im se dati početna vrednost, dok apstraktna klasa to ne zahteva.
4. Koja je razlika između preopterećenja (overloading) i prepisivanja (overriding)?
Prepisivanje (overriding):
- Lista parametara mora biti potpuno ista kao kod prepisane metode, inače se ne naziva prepisivanjem već preopterećenjem.
- Povratni tip mora uvek biti isti kao povratni tip prepisane metode, inače se ne naziva prepisivanjem već preopterećenjem.
- Ograničenje modifikatora pristupa mora biti manje restriktivno od modifikatora pristupa prepisane metode.
- Prepisana metoda ne sme da baci novi proveravani izuzetak niti širi izuzetak od onog koji deklariše prepisana metoda.
Preopterećenje (overloading):
- Mora imati različitu listu parametara;
- Može imati različit povratni tip, dok god je lista parametara različita;
- Može imati različite modifikatore pristupa;
- Može da baci različite izuzetke;
5. Koje su najčešće izuzeci?
- NullPointerException — izuzetak null pokazivača
- ArrayIndexOutOfBoundsException — izuzetak prekoračenja granica indeksa
- InputFormatException — neusklađenost tipa unosa
- SQLException — SQL izuzetak
- IllegalArgumentException — nevažeći argument
- NumberFormatException — izuzetak pri konverziji tipa i tako dalje....
6. Kako rešiti izuzetke?
Java standardna biblioteka ugrađuje neke opšte izuzetke, ove klase imaju Throwable kao vršnju nadklasu.
Throwable zatim izvodi klasu Error i klasu Exception.
Greška: Instance klase Error i njenih podklasa predstavljaju greške same JVM. Greške ne može programer da obradi kroz kod, Error se retko pojavljuje. Zato bi programer trebalo da se fokusira na različite klase izuzetaka u grani čija je nadklasa Exception.
Izuzetak: Exception i njegove podklase predstavljaju različite neočekivane događaje koji se dese tokom izvršavanja programa. Može da ih koristi Java mehanizam za obradu izuzetaka i on je jezgro obrade izuzetaka.
Metode obrade:
- 1.try()catch(){}
try{
// programski kod
}catch(ExceptionName e1){
// Catch blok
}- 2.throw
- Uloga ključne reči throw je da baci izuzetak; prilikom bacanja baca se instanca klase izuzetka. U obradi izuzetaka, try naredba želi da uhvati objekat izuzetka, pa taj objekat izuzetka možemo i sami da bacimo.
- 3.throws
- Prilikom definisanja metode može se koristiti ključna reč throws za deklaraciju. Metoda deklarisana sa ključnom reči throws znači da ona sama ne obrađuje izuzetak, već ga prosleđuje mestu poziva metode na obradu.
7. Koja je razlika između ArrayList i LinkedList?

- ArrayList je implementiran na osnovu niza, prostor za pohranu je neprekidan. LinkedList je zasnovan na povezanoj listi, prostor za pohranu nije neprekidan. (LinkedList je dvostruko povezana lista.)
- Za slučajni pristup get i set, ArrayList je znatno bolji od LinkedList, jer LinkedList mora da pomeri pokazivač.
- Za operacije dodavanja i brisanja add i remove, LinkedList je u prednosti, jer ArrayList mora da pomera podatke.
- Za istu količinu podataka LinkedList može da zauzme manje prostora, jer ArrayList treba da rezerviše prostor za naknadno povećanje podataka, dok LinkedList za dodavanje podataka treba samo da doda jedan čvor.
8. Koja je razlika između HashMap 1.7 i HashMap 1.8?
Beležimo samo ključne tačke
| Razlika | hashMap 1.7 | hashMap 1.8 |
|---|---|---|
| Struktura podataka | niz + povezana lista | niz + povezana lista + crveno-crno stablo |
| Način umetanja podataka | umetanje sa glave | umetanje sa repa |
| Način izračunavanja hash vrednosti | 9 smetnji (4 bitske operacije + 5 XOR) | 2 smetnje (1 bitska operacija + 1 XOR) |
| Strategija proširenja | proširenje pre umetanja | proširenje nakon umetanja |
9. Gde se manifestira nesigurnost HashMap niti?
Prilikom proširenja kapaciteta u HashMap 1.7, pošto se koristi umetanje sa glave, može se pojaviti kružna povezana lista, što dovodi do problema sa podacima. U verziji 1.8. je ovo ispravljeno i promenjeno na umetanje sa repa.
U bilo kojoj verziji HashMap, ako prilikom umetanja podataka više niti pogodi isti slot, može doći do prepisivanja podataka, što uzrokuje nesigurnost niti.
10. Kako onda rešiti problem nesigurnosti niti HashMap?

- Prvo, HashMap-u se direktno doda brava da bi se osigurala sigurnost niti.
- Drugo, koristi se HashTable, efikasnije od prvog načina, suština je da su njene metode zaštićene synchronized bravom.
- Treće, koristi se ConcurrentHashMap, bilo u verziji 1.7 ili 1.8, suština je u smanjenju granularnosti brave i smanjenju nadmetanja niti čime se osigurava visoka efikasnost.
11. Koja je razlika između ConcurrentHashMap 1.7 i 1.8?
Beležimo samo ključne tačke
| Razlika | concurrentHashMap 1.7 | concurrentHashMap 1.8 |
|---|---|---|
| Granularnost brave | zasnovano na segmentu | zasnovano na entry čvorovima |
| Brava | reentrantLock | synchronized |
| Donja struktura | Segment + HashEntry + Unsafe | Synchronized + CAS + Node + Unsafe |
12. Predstavimo HashSet

Na gornjoj slici je ukupna struktura familije set.
set nasleđuje interfejs Collection i to je kolekcija koja ne dozvoljava duplikate i neuredna je.
HashSet je implementiran na osnovu HashMap, i u donjem sloju koristi HashMap za čuvanje elemenata.
Hash vrednost elementa se dobija preko metode hashcode elementa. HashSet prvo poredi hash vrednosti dva elementa; ako su hash vrednosti iste, zatim poredi metodom equals. Ako je rezultat equals true, HashSet ih smatra istim elementom. Ako je equals false, nisu isti element.
13. Šta su generici (generics)?
Generici: odlaganje određivanja tipa do trenutka kreiranja objekta ili poziva metode, kada se tek izričito određuje specifični tip.
14. Šta je brisanje generika (type erasure)?
Pošto se generici zapravo implementiraju samo u kompajleru, a virtuelna mašina ne prepoznaje generičke tipove, potrebno je obrisati generičke tipove u virtuelnoj mašini. Odnosno, u fazi kompilacije se koriste generici, a u fazi izvršavanja se uklanjaju, što je brisanje. Brisanje zamenjuje generički tip njegovom nadklasom, npr. String postaje Object itd. Prilikom upotrebe i dalje se vrši konverzija sa eksplicitnim kastovanjem, ali je to sigurnija konverzija jer je u fazi kompilacije već osigurana konzistentnost podataka.
15. Koja je razlika između procesa i niti?
Proces je osnovna jedinica za alokaciju i raspoređivanje resursa sistema, može da se izvršava konkurentno čime se povećava iskorišćenost resursa sistema.
Nit je manja od procesa, osnovna jedinica koja može da radi nezavisno. Troškovi kreiranja, uništavanja i promene konteksta su manji nego kod procesa, što može da smanji vremenske i prostorne troškove pri konkurentnom izvršavanju programa i operativnom sistemu pruži bolju konkurentnost.
16. Koja je uloga volatile?

- 1. Garantuje vidljivost u memoriji
- Vidljivost se odnosi na vidljivost između niti: stanje koje jedna nit izmeni vidljivo je drugoj niti. Odnosno, rezultat izmene jedne niti druga nit može odmah da vidi.
- 2. Zabranjuje preređivanje instrukcija
- CPU komunicira sa kešom, ali pošto je efikasnost rada CPU-a previsoka, ne čeka rezultat trenutne instrukcije nego nastavlja sa izvršavanjem sledeće instrukcije, pa može doći do izvršavanja van redosleda.
17. Šta su omotačke klase (wrapper classes) i zašto su potrebne?
U Javi postoji 8 osnovnih tipova, sa po jednom odgovarajućom omotačkom klasom za svaki.
- bajt -- Byte
- boolean -- Boolean
- short -- Short
- char -- Character
- int -- Integer
- long -- Long
- float -- Float
- double -- Double
Zašto su potrebne omotačke klase:
- Osnovni tipovi podataka su zgodni, jednostavni i efikasni, ali ih generici ne podržavaju, niti kao elemente kolekcija.
- Ne slažu se sa objektno-orijentisanim načinom razmišljanja.
- Omotačke klase pružaju mnogo metoda koje olakšavaju upotrebu, kao što su Integer klasa sa metodama toHexString(int i), parseInt(String s) itd.
18. Za Integer a = 1000, Integer b = 1000, koji je rezultat a==b? A šta ako su i a i b jednaki 1, koji je tada rezultat?
Za Integer a = 1000, Integer b = 1000, a==b rezultat je false.
Za Integer a = 1, Integer b = 1, a==b rezultat je true.
Ovo pitanje uglavnom proverava opseg keširanja Integer omotačke klase: vrednosti između -128 i 127 se keširaju, pa se porede direktno keširani podaci, dok se van tog opsega porede objekti.
19. Šta je JMM?

JMM je Java model memorije (java memory model). Pošto pod različitim proizvođačima hardvera i različitim operativnim sistemima postoji izvesna razlika u pristupu memoriji, ista kôd može na različitim sistemima da prouzrokuje različite probleme. Zato Java model memorije (JMM) maskira razlike u pristupu memoriji između različitih hardvera i operativnih sistema, kako bi se postiglo da Java programi na svim platformama ostvare dosledne efekte konkurentnosti.
Java model memorije propisuje da se sve promenljive čuvaju u glavnoj memoriji, uključujući promenljive instanci i statičke promenljive, ali ne i lokalne promenljive i parametre metoda. Svaka nit ima svoju radnu memoriju; radna memorija niti čuva promenljive koje ta nit koristi i kopije iz glavne memorije, a operacije niti nad promenljivama se obavljaju u radnoj memoriji. Nit ne može direktno da čita i piše promenljive u glavnoj memoriji.
Radna memorija svake niti je nezavisna, nit može da opslužuje podatke samo u radnoj memoriji, a zatim ih vraća u glavnu memoriju. To je osnovni način rada niti koji definiše Java model memorije.
20. Koji su načini kreiranja objekata
Postoji pet načina za kreiranje objekata.
- new ključna reč
Person p1 = new Person();- Class.newInstance
Person p1 = Person.class.newInstance();- Constructor.newInstance
Constructor<Person> constructor = Person.class.getConstructor();
Person p1 = constructor.newInstance();- clone
Person p1 = new Person();
Person p2 = p1.clone();- Deserijalizacija
Person p1 = new Person();
byte[] bytes = SerializationUtils.serialize(p1);
Person p2 = (Person)SerializationUtils.deserialize(bytes);21. Pričajmo o lenjom singleton obrascu (lazy singleton)
Evo koda direktno:
// Lenji način (lazy)
public class Singleton {
// Odloženo učitavanje garantuje bezbednost niti
Private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}- volatile se koristi da bi se sprečilo preređivanje instrukcija i garantovala vidljivost objekta, sprečavajući čitanje objekta u polu-inicijalizovanom stanju.
- Prvi nivo if(singleton == null) služi da spreči da više niti kreira objekat istovremeno.
- synchronized dodaje bravu da bi sprečio da više niti istovremeno uđe u metodu i kreira objekat.
- Drugi nivo if(singleton == null) sprečava situaciju u kojoj više niti istovremeno čeka na bravu, pa kada jedna završi, sledeća nastavlja izvršavanje.
Za dvostruku proveru brave (double-checked locking) pogledajte
22. Koja je uloga volatile

- Garantuje vidljivost u memoriji
- Kada promenljivu modifikovanu ključnom reči volatile jedna nit izmeni, druge niti mogu odmah da dobiju izmenjeni rezultat. Kada jedna nit upiše podatke u promenljivu modifikovanu ključnom reči volatile, virtuelna mašina je prisiljava da osveži vrednost u glavnu memoriju. Kada jedna nit čita vrednost modifikovanu ključnom reči volatile, virtuelna mašina je prisiljava da čita iz glavne memorije.
- Zabranjuje preređivanje instrukcija
- Preređivanje instrukcija je sredstvo kojim kompajler i procesor optimizuju program radi veće efikasnosti. CPU komunicira sa memorijom, a efikasnost CPU-a je mnogo veća od memorije, pa CPU, kada to ne utiče na konačni rezultat, ne čeka povratni rezultat već direktno prelazi na naredne instrukcije. volatile na odgovarajući kôd dodaje memorijsku barijeru, pa je unutar barijere zabranjeno preređivanje instrukcija.
23. Kako garantovati sigurnost niti?
- synchronized ključna reč
- Može se koristiti za blok koda, metodu (statička metoda, brava za sinhronizaciju je trenutni objekat bajtkoda; metoda instance, brava za sinhronizaciju je objekat instance).
- lock mehanizam brave
Lock lock = new ReentrantLock();
lock. lock();
try {
System. out. println("Dobijena brava");
} catch (Exception e) {
} finally {
System. out. println("Brava oslobođena");
lock. unlock();
}24. Proces nadgradnje synchronized brave
U verzijama pre Java 1.6, synchronized je bio teška brava, sa niskom efikasnošću. Brava je za CPU resurs celog nivoa, svako pribavljanje brave zahteva zahtev ka CPU-u, što jako troši performanse.
Nakon JDK 1.6, Java je zvanično znatno optimizovala synchronized sa nivoa JVM-a, pa je sada efikasnost synchronized brave prilično dobra. Posle JDK 1.6, da bi se smanjio pad performansi koji donosi pribavljanje i otpuštanje brave, uvedene su biasovana brava i laka brava, dodat je proces nadgradnje brave: bez brave -> biasovana brava -> spin brava -> teška brava. 
Dodavanje procesa nadgradnje brave uglavnom smanjuje prebacivanje iz korisničkog u kernel režim, povećava efikasnost brave i optimizuje bravu sa nivoa JVM-a.
25. Šta je CAS?
CAS se zove CompareAndSwap, poređenje i zamena. Koristi se na mnogim mestima, na primer u nadgradnji brave koristi se za spin bravu. Suština je da se instrukcijom procesora garantuje atomičnost operacije. Sadrži uglavnom tri promenljive:
- 1. Memorijska adresa promenljive
- 2. Stara očekivana vrednost A
- 3. Nova vrednost B koja se postavlja
Kada jedna nit treba da izmeni vrednost deljene promenljive, da bi se završila ova operacija najpre se uzima vrednost deljene promenljive i dodeljuje A; zatim se na osnovu A vrši izračunavanje i dobija nova vrednost B; potom se očekivana originalna vrednost A poredi sa vrednošću deljene promenljive u memoriji, i ako su iste smatra se da druge niti nisu vršile izmenu, pa se nova vrednost upisuje u memoriju.

Nedostaci CAS-a
CPU troškovi su relativno veliki: u uslovima visoke konkurentnosti, ako mnogo niti uzastopno pokušava da ažurira neku promenljivu, ali uvek neuspešno, pošto tokom spin-a stalno zauzimaju CPU, ako CAS stalno neuspešno ažurira stalno će zauzimati CPU, uzrokujući rasipanje CPU resursa.
ABA problem: na primer, nit A izmeni vrednost 1 i uspešno je izmenila, ali je u međuvremenu i nit B izmenila tu vrednost, pri čemu je rezultat izmene i dalje 1, pa to ne utiče na operaciju niti A — a to predstavlja problem. Može se rešiti pomoću broja verzije.
Može garantovati atomičnost samo jedne deljene promenljive.
26. Pričajmo o ReentrantLock-u
ReentrantLock znači reentrant brava. Kada se priča o ReentrantLock-u mora se pomenuti i AQS, jer je njegov donji sloj implementiran korišćenjem AQS-a.
ReentrantLock ima dva režima: jedan je fer brava, a drugi nefer brava.
- U fer režimu, niti koje čekaju, pošto uđu u red, izvršavaju se striktno po redosledu reda.
- U nefer režimu, niti koje čekaju, pošto uđu u red, mogu da preskoče red.
Fer brava

- Prvi korak: dobavlja se vrednost state statusa
- Ako je state=0, to znači da bravu ne drži druga nit, pa se prelazi na drugi korak.
- Ako je state!=0, to znači da druga nit drži bravu, pa se prelazi na treći korak.
- Drugi korak: proverava se da li u redu ima niti koje čekaju
- Ako ne postoji, vlasnik brave se direktno postavlja na trenutnu nit i ažurira se status state.
- Ako postoji, ulazi u red.
- Treći korak: proverava se da li je vlasnik brave trenutna nit
- Ako jeste, ažurira se vrednost statusa state.
- Ako nije, nit ulazi u red i čeka.
Nefer brava

- Dobavlja se vrednost state statusa.
- Ako je state=0, to znači da bravu ne drži druga nit, pa se trenutni držač brave postavlja na trenutnu nit; ova operacija se obavlja pomoću CAS-a.
- Ako nije 0 ili postavljanje ne uspe, to znači da je brava zauzeta pa se prelazi na sledeći korak.
- Sada se dobavlja vrednost state.
- Ako jeste, state se povećava za 1 i dobija se brava.
- Ako nije, ulazi se u red i čeka.
- Ako je 0, to znači da je nit upravo otpustila bravu, pa se držač brave postavlja na sebe.
- Ako nije 0, proverava se da li je držač brave trenutna nit.
27. Koji su načini kreiranja više niti?
- Nasleđivanje klase Thread, prepisivanje metode run()
public class Demo extends Thread{
// Prepisuje se run() nadklase Thread
public void run() {
}
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
d1.start();
d2.start();
}
}- Implementacija interfejsa Runnable, prepisivanje run()
public class Demo2 implements Runnable{
// Prepisuje se run() interfejsa Runnable
public void run() {
}
public static void main(String[] args) {
Thread t1 = new Thread(new Demo2());
Thread t2 = new Thread(new Demo2());
t1.start();
t2.start();
}
}- Implementacija interfejsa Callable
public class Demo implements Callable<String>{
public String call() throws Exception {
System.out.println("Izvršava se zadatak nove niti");
Thread.sleep(2000);
return "rezultat";
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
Demo d = new Demo();
FutureTask<String> task = new FutureTask<>(d);
Thread t = new Thread(task);
t.start();
// Dobavlja se rezultat koji vraća zadatak nakon izvršenja
String result = task.get();
}
}- Kreiranje pomoću bazena niti
public class Demo {
public static void main(String[] args) {
Executor threadPool = Executors.newFixedThreadPool(5);
for(int i = 0 ;i < 10 ; i++) {
threadPool.execute(new Runnable() {
public void run() {
//todo
}
});
}
}
}28. Koje parametre ima bazen niti?
1.corePoolSize: broj jezgarnih niti, broj niti u bazenu koje su uvek žive.
2.maximumPoolSize: maksimalan broj niti, maksimalan broj niti dozvoljen u bazenu.
3.keepAliveTime: vreme preživljavanja, najduže vreme koliko nit može da ostane bez zadatka pre nego što se terminira.
4.unit: jedinica, vremenska jedinica za parametar keepAliveTime, 7 opcija.
5.workQueue: blokirajući red koji se koristi za čuvanje zadataka koji čekaju izvršenje, sve su bezbedne za niti, 7 opcija.
6.threadFactory: fabrika niti, uglavnom se koristi za kreiranje niti, podrazumeva normalan prioritet i niti koje nisu démon.
7.handler: strategija odbijanja, strategija pri odbijanju obrade zadatka, 4 opcije, podrazumevano AbortPolicy.
29. Tok izvršavanja bazena niti?

- Proverava se da li je broj niti u bazenu veći od podešenog broja jezgarnih niti.
- Ako je manji, kreira se jedna jezgarna nit da izvrši zadatak.
- Ako je veći, proverava se da li je baferirani red pun.
- Ako nije pun, stavlja se u red i čeka da nit bude slobodna pa da izvrši zadatak.
- Ako je red već pun, proverava se da li je dostignut maksimalan broj niti podešen za bazen.
- Ako nije dostignut, kreira se nova nit da izvrši zadatak.
- Ako je maksimalan broj niti dostignut, izvršava se navedena strategija odbijanja.
30. Koje su strategije odbijanja bazena niti?
- AbortPolicy: direktno odbacuje zadatak i baca izuzetak, ovo je podrazumevana strategija.
- CallerRunsPolicy: zadatak obrađuje samo nit u kojoj je pozivalac.
- DiscardOldestPolicy: odbacuje najstariji zadatak u redu čekanja i izvršava trenutni zadatak.
- DiscardPolicy: direktno odbacuje zadatak, bez bacanja izuzetka.
31. Predstavimo četiri tipa referenci
- Jaka referenca (StrongReference)
Object obj = new Object();
// Dok god obj pokazuje na Object objekat, Object objekat neće biti prikupljenSakupljač smeća neće da prikupi referencirani objekat; čak i kada memorija ponestane, JVM će direktno baciti OutOfMemoryError, osim ako mu se ne dodeli vrednost null.
- Meka referenca (SoftReference)
Meka referenca služi da opiše neke neobavezne ali još uvek korisne objekte. Kada ima dovoljno memorije, objekti meke reference se ne prikupljaju; samo kada memorije ponestane, sistem prikuplja objekte meke reference. Ako i nakon prikupljanja objekata meke reference i dalje nema dovoljno memorije, tek se tada baca izuzetak prelivanja memorije.
- Slaba referenca (WeakReference)
Jačina slabe reference je još manja od meke reference; bez obzira na to da li ima dovoljno memorije, čim JVM počne sa sakupljanjem smeća, svi objekti povezani slabom referencom biće prikupljeni.
- Fantomna referenca (PhantomReference)
Fantomna referenca je najslabiji tip referentnog odnosa; ako objekat drži samo fantomnu referencu, onda je to isto kao da nema nikakvu referencu — može biti prikupljen u svakom trenutku. Od JDK 1.2 nadalje predstavlja se klasom PhantomReference; pregledom izvornog koda te klase vidi se da ima samo jedan konstruktor i jednu get() metodu, pri čemu get() metoda samo vraća null, odnosno nikada se ne može dobiti objekat preko fantomne reference. Fantomna referenca mora da se koristi zajedno sa referentnim redom ReferenceQueue; van-heap memorija NIO-a se upravo njome upravlja.
32. Šta su duboko i plitko kopiranje?
- Plitko kopiranje nije stvarno kopiranje, samo kopira pokazivač koji ukazuje na određeni objekat, a ne i sam objekat; stari i novi objekat i dalje dele istu memoriju.
- Duboko kopiranje će dodatno napraviti identičan objekat; novi objekat ne deli memoriju sa originalom, pa izmena novog objekta neće promeniti original.
33. Pričajmo o ThreadLocal-u
- ThreadLocal je zapravo lokalna promenljiva niti; on u svakoj niti kreira jednu kopiju, pa nitima preostaje samo da pristupaju svojoj unutrašnjoj kopiji promenljive, čime se postiže međusobna izolacija niti.

- ThreadLocal ima statičku unutrašnju klasu ThreadLocalMap; ThreadLocalMap zatim sadrži jedan Entry niz, a sam Entry je slaba referenca. Njegov ključ je slaba referenca koja ukazuje na ThreadLocal, a svrha slabe reference je da se spreči curenje memorije: da je jaka referenca, osim ako se nit ne završi, ne bi moglo da se terminira, pa postoji rizik od curenja memorije.
- Ali čak i tako i dalje postoji problem curenja memorije: nakon što se ključ i ThreadLocal objekat prikupe, u entry-ju ostaje entry objekat čiji je ključ null, ali value ima vrednost, do kojeg se nikada ne može doći, osim ako se nit ne završi. Rešenje je da se pozove remove metoda koja briše entry objekat.
34. Kako izgleda memorijski raspored jednog objekta?

- 1. Zaglavlje objekta: Zaglavlje objekta se deli na dva dela: MarkWord i Class Pointer.
- MarkWord: sadrži niz oznaka, kao što su oznaka lake brave, oznaka biasovane brave, gc informacije evidentiranja itd.
- ClassPointer: pokazuje na memorijsku adresu Class objekta koji odgovara objektu (njegovom objektu metapodataka). Na 32-bitnom sistemu zauzima 4 bajta, a na 64-bitnom sistemu 8 bajtova.
- 2.Length: postoji samo kod objekata niza, služi da zabeleži dužinu niza i zauzima 4 bajta.
- 3.Instance data: Stvarni podaci objekta; stvarni podaci objekta obuhvataju sve promenljive članice objekta, a njihovu veličinu određuje veličina svake promenljive članice. (Ovde ne spadaju statičke promenljive članice, pošto se one održavaju u prostoru metoda.)
- 4.Padding: Java objekti su poravnati na 8 bajtova, odnosno broj bajtova koje zauzimaju svi Java objekti mora biti umnožak od 8. Razlog je taj što, kada iz diska uzmemo podatak, ne uzimamo bajt po bajt kako poželimo, već uzimamo blok po blok, pri čemu je veličina tog bloka 8 bajtova; radi potpunosti, uloga padding-a je da dopuni bajtove i garantuje da je objekat umnožak od 8 bajtova.
Autor: moon-ov tehnološki blog, link za preuzimanje: https://mp.weixin.qq.com/s/aTWtqPyMQ-6P_c8iuMVrkg
