Vragen en antwoorden over Java String-interview

1. Inleiding

De Draad class is een van de meest gebruikte klassen in Java, wat taalontwerpers ertoe aanzette het speciaal te behandelen. Dit speciale gedrag maakt het een van de meest populaire onderwerpen in Java-interviews.

In deze tutorial bespreken we enkele van de meest voorkomende interviewvragen over Draad.

2. Draad Fundamentals

Dit gedeelte bestaat uit vragen die betrekking hebben op de Draad interne structuur en geheugen.

V1. Wat is een string in Java?

In Java is een Draad wordt intern vertegenwoordigd door een reeks byte waarden (of char waarden vóór JDK 9).

In versies tot en met Java 8 is een Draad was samengesteld uit een onveranderlijke reeks Unicode-tekens. De meeste tekens hebben echter slechts 8 bits nodig (1 byte) om ze weer te geven in plaats van 16 bits (char grootte).

Om het geheugengebruik en de prestaties te verbeteren, introduceerde Java 9 compacte strings. Dit betekent dat als een Draad bevat slechts 1-byte tekens en wordt weergegeven met Latijns-1 codering. Als een Draad bevat ten minste 1 multi-byte-teken, wordt dit weergegeven als 2 bytes per teken met behulp van UTF-16-codering.

In C en C ++, Draad is ook een reeks tekens, maar in Java is het een afzonderlijk object met een eigen API.

Q2. Hoe kunnen we een String-object maken in Java?

java.lang.String definieert 13 verschillende manieren om een Draad. Over het algemeen zijn er echter twee:

  • Via een Draad letterlijk:
    String s = "abc";
  • Door het nieuw trefwoord:
    String s = nieuwe String ("abc");

Alle letterlijke tekenreeksen in Java zijn exemplaren van de Draad klasse.

Q3. Is Draad een primitief of een afgeleid type?

Een touwtje is een afgeleid type omdat het staat en gedrag heeft. Het heeft bijvoorbeeld methoden zoals deelstring (), index van(), en is gelijk aan (), welke primitieven niet kunnen hebben.

Maar aangezien we het allemaal zo vaak gebruiken, heeft het een aantal speciale kenmerken waardoor het als een primitief aanvoelt:

  • Hoewel strings niet zoals primitieven in de call-stack worden opgeslagen, zijn ze dat wel opgeslagen in een speciaal geheugengebied, de stringpool genaamd
  • Net als primitieven kunnen we de + operator op strings
  • En nogmaals, net als primitieven, kunnen we een instantie van een Draad zonder de nieuw trefwoord

V4. Wat zijn de voordelen als snaren onveranderlijk zijn?

Volgens een interview door James Gosling zijn strings onveranderlijk om de prestaties en veiligheid te verbeteren.

En eigenlijk zien we verschillende voordelen van onveranderlijke strings:

  • De string-pool is alleen mogelijk als de strings, eenmaal gemaakt, nooit worden gewijzigd, zoals ze zouden moeten worden hergebruikt
  • De code kan veilig een string doorgeven aan een andere methode, wetende dat het niet kan worden gewijzigd door die methode
  • Onveranderlijk maakt deze klasse automatisch thread-safe
  • Omdat deze klasse thread-safe is, het is niet nodig om gemeenschappelijke gegevens te synchroniseren, wat op zijn beurt de prestaties verbetert
  • Omdat ze gegarandeerd niet veranderen, hun hashcode kan eenvoudig in de cache worden opgeslagen

V5. Hoe wordt een string in het geheugen opgeslagen?

Volgens de JVM-specificatie, Draad literals worden opgeslagen in een runtime constante pool, die wordt toegewezen vanuit het methodegebied van de JVM.

Hoewel het methodegebied logischerwijs deel uitmaakt van het heap-geheugen, dicteert de specificatie niet de locatie, de geheugengrootte of het garbage collection-beleid. Het kan implementatiespecifiek zijn.

Deze constante pool voor runtime voor een klasse of interface wordt samengesteld wanneer de klasse of interface wordt gemaakt door de JVM.

V6. Komen Interned Strings in aanmerking voor Garbage Collection in Java?

Ja alles Draads in de stringpool komen in aanmerking voor garbage collection als er geen referenties uit het programma zijn.

V7. Wat is de String Constant Pool?

De string-pool, ook wel bekend als de Draad constant zwembad of de Draad intern pool, is een speciale geheugenregio waar de JVM Draad gevallen.

Het optimaliseert de prestaties van de applicatie door te verminderen hoe vaak en hoeveel strings worden toegewezen:

  • De JVM slaat slechts één exemplaar van een bepaald exemplaar op Draad in het zwembad
  • Bij het aanmaken van een nieuw Draadzoekt de JVM in de pool naar een Draad met dezelfde waarde
  • Indien gevonden, retourneert de JVM de verwijzing daarnaar Draad zonder extra geheugen toe te wijzen
  • Indien niet gevonden, voegt de JVM het toe aan de pool (interns it) en retourneert de referentie

V8. Is String Thread-Safe? Hoe?

Snaren zijn inderdaad volledig draadveilig omdat ze onveranderlijk zijn. Elke klasse die onveranderlijk is, komt automatisch in aanmerking voor thread-veiligheid omdat de onveranderlijkheid ervan garandeert dat de instanties niet over meerdere threads worden gewijzigd.

Als een thread bijvoorbeeld de waarde van een string verandert, wordt een new Draad wordt gemaakt in plaats van de bestaande te wijzigen.

V9. Voor welke stringbewerkingen is het belangrijk om een ​​locale op te geven?

De Locale class stelt ons in staat om onderscheid te maken tussen culturele locaties en om onze inhoud op de juiste manier op te maken.

Als het gaat om de Draad class, we hebben het nodig bij het renderen van strings in formaat of bij snaren met een lagere of hogere behuizing.

Als we dit vergeten te doen, kunnen we in feite problemen tegenkomen met de draagbaarheid, beveiliging en bruikbaarheid.

V10. Wat is de onderliggende tekencodering voor tekenreeksen?

Volgens Draad's Javadocs voor versies tot en met Java 8, Strings worden intern in het UTF-16 formaat opgeslagen.

De char gegevenstype en java.lang.Character objecten zijn ook gebaseerd op de originele Unicode-specificatie, die tekens definieerde als 16-bits entiteiten met een vaste breedte.

Beginnend met JDK 9, Snaren die slechts 1-byte tekens bevatten, gebruiken Latijns-1 codering, terwijl Snaren met ten minste 1 multi-byte-teken UTF-16-codering gebruiken.

3. Het Draad API

In dit gedeelte bespreken we enkele vragen met betrekking tot de Draad API.

V11. Hoe kunnen we twee strings in Java vergelijken? Wat is het verschil tussen str1 == str2 en str1.Equals (str2)?

We kunnen strings op twee verschillende manieren vergelijken: door de operator gelijk aan (==) te gebruiken en door de is gelijk aan () methode.

Beide zijn behoorlijk verschillend van elkaar:

  • De operator (str1 == str2) controleert op referentiële gelijkheid
  • De methode (str1.equals (str2)) controleert op lexicale gelijkheid

Het is echter waar dat als twee strings lexicaal gelijk zijn, str1.intern () == str2.intern () is ook waar.

Meestal om twee te vergelijken Snaren voor hun inhoud zouden we altijd moeten gebruiken String. Is gelijk aan.

V12. Hoe kunnen we een string in Java splitsen?

De Draad klasse zelf biedt ons de Draad#splitsen methode, die een scheidingsteken voor reguliere expressies accepteert. Het geeft ons een Draad[] matrix:

String [] parts = "john, peter, mary" .split (","); assertEquals (nieuwe String [] {"john", "peter", "mary"}, delen);

Een lastig ding over splitsen is dat bij het splitsen van een lege string, kunnen we een niet-lege array krijgen:

assertEquals (new String [] {""}, "" .split (","));

Natuurlijk, splitsen is slechts een van de vele manieren om een ​​Java te splitsen Draad.

V13. Wat is Stringjoiner?

StringJoiner is een klasse geïntroduceerd in Java 8 voor het samenvoegen van afzonderlijke strings tot één, zoals een lijst met kleuren nemen en ze retourneren als een door komma's gescheiden tekenreeks. We kunnen zowel een scheidingsteken als een voorvoegsel en achtervoegsel opgeven:

StringJoiner joiner = nieuwe StringJoiner (",", "[", "]"); joiner.add ("Rood") .add ("Groen") .add ("Blauw"); assertEquals ("[Rood, Groen, Blauw]", joiner.toString ());

V14. Verschil tussen String, Stringbuffer en Stringbuilder?

Snaren zijn onveranderlijk. Dit betekent dat als we proberen zijn waarden te veranderen of te veranderen, dan creëert Java een absoluut nieuw Draad.

Als we bijvoorbeeld toevoegen aan een string str1 nadat het is gemaakt:

String str1 = "abc"; str1 = str1 + "def";

Dan de JVM, in plaats van te wijzigen str1, creëert een geheel nieuw Draad.

In de meeste eenvoudige gevallen gebruikt de compiler echter intern StringBuilder en optimaliseert de bovenstaande code.

Maar voor complexere code zoals loops, het zal een geheel nieuw creëren Draad, verslechterende prestaties. Dit is waar StringBuilder en StringBuffer zijn handig.

Beide StringBuilder en StringBuffer in Java objecten maken die een veranderlijke reeks tekens bevatten.StringBuffer is gesynchroniseerd en daarom thread-safe while StringBuilder is niet.

Sinds de extra synchronisatie in StringBuffer meestal niet nodig is, kunnen we vaak een prestatieverbetering krijgen door te selecteren StringBuilder.

V15. Waarom is het veiliger om wachtwoorden op te slaan in een tekenreeks [] dan in een tekenreeks?

Omdat strings onveranderlijk zijn, kunnen ze niet worden gewijzigd. Dit gedrag weerhoudt ons ervan de inhoud ervan te overschrijven, aan te passen of op nul te stellen, making Snaren ongeschikt voor het opslaan van gevoelige informatie.

We moeten op de garbage collector vertrouwen om de inhoud van een string te verwijderen. Bovendien werden in Java-versies 6 en lager strings opgeslagen in PermGen, wat betekent dat eens een Draad is gemaakt, het was nooit vuilnis verzameld.

Door een char [] array, we hebben volledige controle over die informatie.We kunnen het aanpassen of volledig wissen zonder zelfs maar te vertrouwen op de vuilnisman.

Gebruik makend van char [] over- Draad beveiligt de informatie niet volledig; het is slechts een extra maatregel die de kans verkleint dat de kwaadwillende gebruiker toegang krijgt tot gevoelige informatie.

V16. Wat doet de intern () -methode van String?

De methode intern() maakt een exacte kopie van een Draad object in de heap en slaat het op in het Draad constante pool, die de JVM onderhoudt.

Java interneert automatisch alle strings die zijn gemaakt met behulp van letterlijke tekenreeksen, maar als we een Draad met de nieuwe operator, bijvoorbeeld String str = nieuwe String ("abc"), dan voegt Java het toe aan de heap, net als elk ander object.

We kunnen de intern() methode om de JVM te vertellen om het toe te voegen aan de stringpool als het daar nog niet bestaat, en een verwijzing naar die geïnterneerde string terug te sturen:

String s1 = "Baeldung"; String s2 = nieuwe String ("Baeldung"); String s3 = nieuwe String ("Baeldung"). Intern (); assertThat (s1 == s2) .isFalse (); assertThat (s1 == s3) .isTrue ();

V17. Hoe kunnen we String naar geheel getal en geheel getal naar string in Java converteren?

De meest eenvoudige benadering om een Draad aan een Geheel getal is door te gebruiken Geheel getal#parseInt:

int num = Integer.parseInt ("22");

Om het omgekeerde te doen, kunnen we gebruiken Geheel getal#toString:

String s = Integer.toString (num);

V18. Wat is String.format () en hoe kunnen we het gebruiken?

Tekenreeks # formaat geeft een opgemaakte tekenreeks terug met de opgegeven opmaakstring en argumenten.

String title = "Baeldung"; String formatted = String.format ("Titel is% s", titel); assertEquals ("Titel is Baeldung", opgemaakt);

We moeten ook onthouden om het Land, tenzij we akkoord gaan met het accepteren van de standaardinstelling van het besturingssysteem:

Locale usersLocale = Locale.ITALY; assertEquals ("1.024", String.format (usersLocale, "Er zijn%, d shirts om uit te kiezen. Veel succes.", 1024))

V19. Hoe kunnen we een tekenreeks naar hoofdletters en kleine letters converteren?

Draad biedt impliciet Tekenreeks # toUpperCase om de hoofdletters te veranderen.

De Javadocs herinneren ons er echter aan dat we het L.ocale om de juistheid te verzekeren:

String s = "Welkom bij Baeldung!"; assertEquals ("WELCOME TO BAELDUNG!", s.toUpperCase (Locale.US));

Evenzo hebben we om naar kleine letters te converteren Tekenreeks # toLowerCase:

String s = "Welkom bij Baeldung!"; assertEquals ("welkom bij baeldung!", s.toLowerCase (Locale.UK));

V20. Hoe kunnen we een reeks tekens uit String krijgen?

Draad biedt toCharArray, die een kopie van zijn interne char array pre-JDK9 (en converteert het Draad naar een nieuw char matrix in JDK9 +):

char [] hallo = "hallo" .toCharArray (); assertArrayEquals (new String [] {'h', 'e', ​​'l', 'l', 'o'}, hallo);

V21. Hoe kunnen we een Java-string omzetten in een byte-array?

Standaard is de methode Tekenreeks # getBytes () codeert een string in een byte-array met behulp van de standaardtekenset van het platform.

En hoewel de API niet vereist dat we een tekenset specificeren, moeten we om de veiligheid en draagbaarheid te garanderen:

byte [] byteArray2 = "efgh" .getBytes (StandardCharsets.US_ASCII); byte [] byteArray3 = "ijkl" .getBytes ("UTF-8");

4. Draad-Gebaseerde algoritmen

In dit gedeelte bespreken we enkele programmeervragen met betrekking tot Draads.

V22. Hoe kunnen we controleren of twee strings anagrammen zijn in Java?

Een anagram is een woord dat wordt gevormd door de letters van een ander bepaald woord te herschikken, bijvoorbeeld "auto" en "boog".

Om te beginnen kijken we eerst of beide Snaren zijn even lang of niet.

Vervolgens converteren we ze naar char [] array, sorteer ze en controleer vervolgens op gelijkheid.

V23. Hoe kunnen we het aantal keren dat een bepaald personage in een string voorkomt, tellen?

Java 8 vereenvoudigt de aggregatietaken zoals deze:

long count = "hallo" .chars (). filter (ch -> (char) ch == 'l'). count (); assertEquals (2, count);

En er zijn ook verschillende andere geweldige manieren om de l's te tellen, inclusief loops, recursie, reguliere expressies en externe bibliotheken.

V24. Hoe kunnen we een string in Java omkeren?

Er kunnen veel manieren zijn om dit te doen, de meest eenvoudige benadering is om de omgekeerde methode van StringBuilder (of StringBuffer):

String reversed = nieuwe StringBuilder ("baeldung"). Reverse (). ToString (); assertEquals ("gnudleab", omgekeerd);

V25. Hoe kunnen we controleren of een string een palindroom is of niet?

Een palindroom is een reeks tekens die achterwaarts en voorwaarts hetzelfde leest, zoals "mevrouw", "radar" of "niveau".

Om te controleren of een string een palindroom is, kunnen we beginnen met het herhalen van de gegeven string in een enkele lus, één teken per keer. De lus wordt afgesloten bij de eerste mismatch.

5. Conclusie

In dit artikel hebben we enkele van de meest voorkomende besproken Draad interview vragen.

Alle codevoorbeelden die hier worden gebruikt, zijn beschikbaar op GitHub.