Som et udbredt pro­gram­me­rings­sprog er Java og dets unikke funk­tio­ner velkendte for re­k­rut­te­rings­ansvar­li­ge. Derfor stilles der ofte spørgsmål om for­skel­li­ge aspekter af Java i de tidlige faser af en job­sam­ta­le. Vi har samlet en liste over ti ofte stillede spørgsmål til Java-udviklere og har også in­klu­de­ret svar på hvert enkelt spørgsmål.

Denne artikel giver et overblik over de spørgsmål, du kan blive stillet om Java i en job­sam­ta­le som udvikler. Afhængigt af det krævede niveau af er­hverv­ser­fa­ring til stil­lin­gen kan nogle spørgsmål være mere de­tal­je­re­de. I job­sam­ta­ler til se­ni­o­r­stil­lin­ger præ­sen­te­res der un­der­ti­den scenarier, der in­de­hol­der bevidste fejl eller er klart vild­le­den­de for at teste den tekniske viden hos den person, der ansøger om stil­lin­gen. Derfor er det vigtigt at være godt forberedt til din job­sam­ta­le.

Spørgsmål 1: Hvad er Java’s særlige egen­ska­ber, og hvilke fordele tilbyder pro­gram­me­rings­spro­get?

Java er et kraft­fuldt og udbredt sprog, hvilket har gjort det til et populært pro­gram­me­rings­sprog at lære. Flere unikke funk­tio­ner gør Java til noget særligt, især i forhold til hvordan det bruges. En vigtig fordel ved Java er, at dets kode kan køre på for­skel­li­ge ope­ra­tiv­sy­ste­mer uden ændringer.

Denne flek­si­bi­li­tet mu­lig­gø­res af Java Virtual Machine, som sikrer, at udvikling og an­ven­del­se ikke er begrænset til en bestemt platform, hvilket gør det muligt at bruge koden på flere platforme. Dette sikrer, at pro­gram­mer kører flek­si­belt og effektivt på for­skel­li­ge enheder.

En anden fordel ved Java er den au­to­ma­ti­ske hukom­mel­ses­sty­ring, som Garbage Collector leverer, hvilket forenkler styringen af hukom­mel­ses­res­sour­cer og reducerer po­ten­ti­el­le fejl. Derudover frem­skyn­der Javas om­fat­ten­de stan­dard­bi­bli­o­te­ker med mange færdige funk­tio­ner ud­vik­lin­gen af ap­pli­ka­tio­ner.

Som et ob­jekt­o­ri­en­te­ret pro­gram­me­rings­sprog udmærker Java sig, ligesom andre sprog i denne kategori, ved at softwa­re­kom­po­nen­ter lettere kan mo­del­le­res, og koden kan genbruges gentagne gange.

Spørgsmål 2: Hvordan håndterer Java multiple arv?

I prin­cip­pet un­der­støt­ter Java ikke multiple arv af klasser. Det betyder, at klasser kun kan arve fra en enkelt klasse. Multiple arv kan have en negativ ind­virk­ning på koden i ob­jekt­o­ri­en­te­ret pro­gram­me­ring, hvor et velkendt problem er di­a­mant­pro­ble­met.

Selvom multiple arv ikke er muligt for klasser i Java, kan dette løses ved hjælp af græn­se­fla­der. Da en klasse kan im­ple­men­te­re flere græn­se­fla­der i Java, kan den arve funk­tio­na­li­te­ter fra for­skel­li­ge kilder. Denne opgave sikrer, at funk­tio­ner­ne er klart de­fi­ne­re­de, og at der ikke kan opstå problemer med multiple arv.

Spørgsmål 3: Hvad er for­skel­len mellem en abstrakt klasse og en græn­se­fla­de i Java?

Både abstrakte klasser og græn­se­fla­der bruges i Java til at definere abstrakte typer, som derefter kan im­ple­men­te­res af andre klasser. Der er væ­sent­li­ge forskelle, især når det gælder ar­vereg­ler:

  • Arv: I Java kan en klasse kun arve fra en abstrakt klasse. Abstrakte klasser kan til gengæld ikke udføre multiple arv, hvilket betyder, at flere græn­se­fla­der skal im­ple­men­te­res for dette.
  • Klas­se­for­hold: Da en klasse kun kan arve fra en abstrakt klasse, er brugen af abstrakte klasser velegnet til ‘er en’-forhold, mens græn­se­fla­der er bedre egnet til ‘kan’-forhold.
  • Kon­kret­hed: En abstrakt klasse kan indeholde abstrakte (ikke-im­ple­men­te­re­de) og konkrete (im­ple­men­te­re­de) metoder og kan også have in­stansva­ri­ab­ler. Derimod kan græn­se­fla­der kun definere abstrakte metoder og kon­stan­ter. Alle metoder i en græn­se­fla­de er implicit abstrakte og of­fent­li­ge.
  • Funk­tio­na­li­tet: Abstrakte klasser er afhængige af at dele en fælles im­ple­men­te­ring (og im­ple­men­te­re flere græn­se­fla­der). Græn­se­fla­der er derimod designet til at deklarere spe­ci­fik­ke funk­tio­ner, som derefter im­ple­men­te­res i for­skel­li­ge klasser.

Spørgsmål 4: Hvad er for­skel­len mellem in­stansva­ri­ab­ler og lokale variabler?

Den væ­sent­lig­ste forskel mellem in­stansva­ri­ab­ler og lokale variabler ligger i deres omfang og levetid. In­stansva­ri­ab­ler er ho­ved­sa­ge­ligt egen­ska­ber ved et objekt inden for en klasse. Lokale variabler re­præ­sen­te­rer mid­ler­ti­digt oprettede værdier inden for et bestemt omfang.

In­stansva­ri­ab­ler

  • In­stansva­ri­ab­ler er variabler, der er de­kla­re­ret på klas­se­trin­net uden for metoder, kon­struk­tø­rer og blokke.
  • Hvert objekt i en klasse har sin egen kopi af en in­stansva­ri­a­bel.
  • In­stansva­ri­ab­ler tilgås via en klasses instans. Værdierne kan variere for hvert objekt i klassen.

Lokale variabler

  • Lokale variabler de­kla­re­res inden for en metode, en kon­struk­tør eller en blok. Deres gyldighed er begrænset til dette de­fi­ne­re­de område.
  • Disse variabler skal ini­ti­a­li­se­res eksplicit før brug og ek­si­ste­rer kun, mens ko­de­blok­ken udføres.
  • De er ikke synlige uden for den kodeblok, hvor de blev de­kla­re­ret.

Spørgsmål 5: Hvad betyder ud­tryk­ke­ne JVM, JDK og JRE, og hvordan adskiller de sig fra hinanden?

Selvom disse termer kan synes ens, når de forkortes, er deres un­der­lig­gen­de opgaver og an­ven­del­ses­om­rå­de inden for Java fun­da­men­talt for­skel­li­ge.

Java Virtual Machine (JVM)

  • Java Virtual Machine (JVM) er en virtuel maskine, der fungerer som græn­se­fla­de mellem Java-pro­gram­met og den un­der­lig­gen­de hardware eller det un­der­lig­gen­de ope­ra­tiv­sy­stem og udfører Java-bytecode.
  • JVM er afgørende, fordi den som runtime-miljø kan udføre den samme bytecode på for­skel­li­ge ope­ra­tiv­sy­ste­mer, forudsat at den er til­gæn­ge­lig på de respek­ti­ve platforme. Dette bidrager væ­sent­ligt til Java’s po­rta­bi­li­tet.
  • Denne po­rta­bi­li­tet mu­lig­gø­res af Java-kom­pi­la­to­ren, der over­sæt­ter Java-kildekode til bytecode, som JVM derefter fortolker.

Java De­ve­l­op­ment Kit (JDK)

  • Java De­ve­l­op­ment Kit (JDK) er den komplette ud­vik­lings­pak­ke, der in­de­hol­der for­skel­li­ge værktøjer, der hjælper med ud­vik­lin­gen af Java-ap­pli­ka­tio­ner. Den in­de­hol­der værktøjer til op­ret­tel­se, kom­pi­le­ring og fejl­find­ing af ap­pli­ka­tio­ner.
  • JDK in­de­hol­der Java-kom­pi­la­to­ren, Java Virtual Machine (JVM), Java-fejl­find­ings­værk­tø­jet og Java-pro­fi­le­rings­værk­tø­jet.
  • Ud over disse værktøjer in­de­hol­der JDK et stort antal for­ud­de­fi­ne­re­de klasser og græn­se­fla­der til ofte anvendte funk­tio­ner, der er til­gæn­ge­li­ge i Java API eller Java-klas­se­bi­bli­o­te­ket.

Java Runtime En­viron­ment (JRE)

  • Java Runtime En­viron­ment (JRE) leverer et reduceret miljø, hvor Java-ap­pli­ka­tio­ner kan køres.
  • JRE in­de­hol­der Java Virtual Machine (JVM) og Java API, som begge er nød­ven­di­ge for at starte og køre ap­pli­ka­tio­ner.
  • Ud­vik­lings­værk­tø­jer, såsom Java-kom­pi­la­to­ren, er ikke in­klu­de­ret i JRE, så det in­stal­le­res typisk af slut­bru­ger­ne.

Spørgsmål 6: Hvad er sam­lings­klas­ser i Java, og hvad bruges de til?

I Java refererer udtrykket sam­lings­klas­se normalt til klasser, der er en del af Java Col­lections Framework. Dette framework giver en stan­dar­di­se­ret måde at gemme, or­ga­ni­se­re og ma­ni­p­u­le­re grupper af objekter på. Det består af for­skel­li­ge græn­se­fla­der og konkrete im­ple­men­te­rin­ger af da­ta­struk­tu­rer.

Ind­sam­lings­klas­ser bruges til for­skel­li­ge formål:

  • Da­ta­or­ga­ni­se­ring: De muliggør effektiv or­ga­ni­se­ring af data i lister, sæt eller kort.
  • Da­ta­ma­ni­pu­la­tion: De giver metoder til at tilføje, fjerne og søge efter elementer.
  • Generisk pro­gram­me­ring: Brugen af generiske typer i sam­lings­klas­ser gør det muligt at oprette gen­an­ven­de­lig og ty­pe­sik­ker kode.
  • Al­go­rit­mer: Ram­me­vær­ket in­de­hol­der også al­go­rit­mer, der opererer på da­ta­struk­tu­rer (f.eks. sortering eller søgning).

Spørgsmål 7: Hvad er for­skel­len mellem == og equals() i Java?

== og equals() er to for­skel­li­ge me­ka­nis­mer eller ope­ra­to­rer, der bruges til at sam­men­lig­ne objekter:

  • Ope­ra­to­ren == sam­men­lig­ner ob­jek­ter­nes re­fe­ren­cer, ikke deres ind­holds­vær­di­er. Når den bruges med objekter, kon­trol­le­rer ==, om de to re­fe­ren­cer peger på det samme objekt (dvs. om de henviser til det samme hukom­mel­ses­om­rå­de). I mod­sæt­ning hertil sam­men­lig­ner ope­ra­to­ren værdierne med primitive datatyper (f.eks. char, int eller byte).
  • Med equals() kan du sam­men­lig­ne indholdet i objekter for at afgøre, om ob­jek­ter­ne er de samme, selvom de befinder sig på for­skel­li­ge hukom­mel­ses­pla­ce­rin­ger. Som standard opfører equals() sig som == og arver re­fe­ren­ce­sam­men­lig­nings­lo­gik­ken fra Object-klassen. Det skal dog normalt over­skri­ves i bru­ger­de­fi­ne­re­de klasser for at muliggøre me­nings­fuld ind­holds­sam­men­lig­ning.

Spørgsmål 8: Hvad bruges kon­struk­tø­rer til?

Kon­struk­tø­rer er specielle metoder inden for en klasse, der bruges til at in­stan­si­e­re og ini­ti­a­li­se­re objekter. Kon­struk­tø­rer­nes fire ho­ved­op­ga­ver er:

  • Ob­jek­ti­ni­ti­a­li­se­ring: Kon­struk­to­rer bruges primært til at sætte et objekt i en gyldig og ini­ti­a­li­se­ret tilstand, så snart det er oprettet. At­tri­but­ter ini­ti­a­li­se­res, og de nød­ven­di­ge res­sour­cer allokeres.
  • Pa­ra­me­te­r­over­før­sel: Kon­struk­to­rer kan acceptere parametre for at oprette for­skel­li­ge instanser af klassen med for­skel­li­ge egen­ska­ber, hvilket gør det muligt at oprette objekter med spe­ci­fik­ke at­tri­but­vær­di­er.
  • Ko­desty­ring: Brug af kon­struk­to­rer forbedrer kodens læsbarhed, da ob­jek­ti­ni­ti­a­li­se­ring kan udføres direkte i kon­struk­to­ren. Dette forenkler også ko­de­ved­li­ge­hol­del­se, da ændringer i ini­ti­a­li­se­rings­lo­gik­ken kun skal foretages ét sted.
  • Arv: Kon­struk­to­rer spiller en vigtig rolle i ar­ve­hie­rar­ki­et. En afledt klasse kalder typisk kon­struk­to­ren for ba­se­klas­sen for at håndtere dens ini­ti­a­li­se­ring, inden den udfører sine egne ini­ti­a­li­se­rin­ger.

Spørgsmål 9: Java bruger en række for­skel­li­ge streng­ty­per. Hvilke er det, og hvordan adskiller de sig fra hinanden?

I Java re­præ­sen­te­res streng­ty­pen af klassen java.lang.String. Denne klasse er den primære måde at re­præ­sen­te­re tegn­stren­ge på. Den tilbyder også for­skel­li­ge mu­lig­he­der for streng­ma­ni­pu­la­tion og -be­hand­ling:

  • String­Bu­il­der: Denne klasse bruges til effektivt at oprette æn­drings­ba­re strenge i Java. I mod­sæt­ning til den ufor­an­der­li­ge String-klasse tillader den ændringer uden at generere en ny instans.
  • String-literal: Dette refererer til tegn­stren­ge, der er skrevet i dobbelte an­før­sels­tegn, for eksempel "Nice to see you!". Identiske string-literaler deler en instans i string-puljen for at optimere hukom­mel­ses­for­bru­get.
  • String-objekter: Disse kan oprettes som en ny instans ved hjælp af nøg­le­or­det new, for eksempel som new string ("Nice to see you!"). Instansen oprettes uaf­hæn­gigt af indholdet.
  • String­Buf­fer: Ligesom String­Bu­il­der opretter denne klasse æn­drings­ba­re strenge. Den væ­sent­lig­ste forskel er, at String­Buf­fer er trå­dsik­ker, mens String­Bu­il­der ikke er det.

Spørgsmål 10: Hvad adskiller throw fra throws?

I Java bruges nøg­le­or­de­ne throw og throws begge til at håndtere und­ta­gel­ser. På trods af denne lighed tjener de for­skel­li­ge formål og anvendes i for­skel­li­ge sam­men­hæn­ge:

  • throw bruges til at kaste en und­ta­gel­se manuelt. Udviklere kan bruge dette til at generere en und­ta­gel­se og vi­de­re­gi­ve den til det kaldende program.
  • I mod­sæt­ning hertil angiver throws, at en metode er i stand til at kaste en bestemt und­ta­gel­se. Det bruges i me­to­de­de­kla­ra­tio­nen til at angive, hvilke und­ta­gel­ser der ikke kan håndteres af metoden, men i stedet vi­de­re­gi­ves til den kaldende part til hånd­te­ring, så koden kan reagere i over­ens­stem­mel­se hermed.
Gå til ho­ved­me­nu­en