Questions et réponses d'entrevue Java String

1. Introduction

La classe String est l'une des classes les plus utilisées en Java, ce qui a incité les concepteurs de langage à la traiter spécialement. Ce comportement particulier en fait l'un des sujets les plus chauds des entretiens Java.

Dans ce didacticiel, nous allons passer en revue certaines des questions d'entretien les plus courantes sur String .

2. Fondamentaux des cordes

Cette section se compose de questions qui concernent la structure interne et la mémoire de String .

Q1. Qu'est-ce qu'une chaîne en Java?

En Java, une chaîne est représentée en interne par un tableau de valeurs d' octets (ou de valeurs char avant JDK 9).

Dans les versions jusqu'à et y compris Java 8, une chaîne était composée d'un tableau immuable de caractères Unicode. Cependant, la plupart des caractères ne nécessitent que 8 bits (1 octet) pour les représenter au lieu de 16 bits ( taille de caractère).

Pour améliorer la consommation de mémoire et les performances, Java 9 a introduit des chaînes compactes. Cela signifie que si une chaîne ne contient que des caractères de 1 octet, elle sera représentée en utilisant le codage Latin-1 . Si une chaîne contient au moins 1 caractère multi-octets, elle sera représentée comme 2 octets par caractère en utilisant le codage UTF-16.

En C et C ++, String est également un tableau de caractères, mais en Java, c'est un objet séparé avec sa propre API.

Q2. Comment créer un objet chaîne en Java ?

java.lang.String définit 13 façons différentes de créer une chaîne . En général, cependant, il y en a deux:

  • Via un littéral String :
    String s = "abc";
  • Grâce au nouveau mot-clé:
    String s = new String("abc");

Tous les littéraux String en Java sont des instances de la classe String .

Q3. La chaîne est-elle un type primitif ou dérivé?

Une chaîne est un type dérivé car elle a un état et un comportement. Par exemple, il a des méthodes comme substring () , indexOf () et equals (), que les primitives ne peuvent pas avoir.

Mais, comme nous l'utilisons tous si souvent, il a des caractéristiques spéciales qui lui donnent l'impression d'être un primitif:

  • Bien que les chaînes ne soient pas stockées sur la pile d'appels comme les primitives, elles sont stockées dans une région mémoire spéciale appelée pool de chaînes
  • Comme les primitives, nous pouvons utiliser l' opérateur + sur les chaînes
  • Et encore une fois, comme les primitives, nous pouvons créer une instance d'une chaîne sans le nouveau mot-clé

Q4. Quels sont les avantages du fait que les chaînes sont immuables?

Selon une interview de James Gosling, les chaînes sont immuables pour améliorer les performances et la sécurité.

Et en fait, nous voyons plusieurs avantages à avoir des chaînes immuables:

  • Le pool de chaînes n'est possible que si les chaînes, une fois créées, ne sont jamais modifiées, car elles sont censées être réutilisées
  • Le code peut passer en toute sécurité une chaîne à une autre méthode , sachant qu'elle ne peut pas être modifiée par cette méthode
  • Rend immuablement automatiquement cette classe thread-safe
  • Étant donné que cette classe est thread-safe, il n'est pas nécessaire de synchroniser les données communes , ce qui améliore les performances
  • Comme ils sont garantis de ne pas changer, leur hashcode peut être facilement mis en cache

Q5. Comment une chaîne est-elle stockée en mémoire?

Selon la spécification JVM, les littéraux de chaîne sont stockés dans un pool de constantes d'exécution, qui est alloué à partir de la zone de méthodes de la JVM.

Bien que la zone de méthode fasse logiquement partie de la mémoire du tas, la spécification ne dicte pas l'emplacement, la taille de la mémoire ou les stratégies de garbage collection. Cela peut être spécifique à la mise en œuvre.

Ce pool de constantes d'exécution pour une classe ou une interface est construit lorsque la classe ou l'interface est créée par la JVM.

Q6. Les chaînes internées sont-elles éligibles pour le nettoyage de la mémoire en Java?

Oui, toutes les cordes s dans la piscine de chaîne sont admissibles à la collecte des ordures s'il n'y a pas de références du programme.

Q7. Qu'est-ce que le pool de constantes de chaîne?

Le pool de chaînes, également appelé pool de constantes String ou pool interne String , est une région mémoire spéciale dans laquelle la JVM stocke les instances String .

Il optimise les performances des applications en réduisant la fréquence et le nombre de chaînes allouées:

  • La machine virtuelle Java ne stocke qu'une seule copie d'une chaîne particulière dans le pool
  • Lors de la création d'une nouvelle chaîne , la JVM recherche dans le pool une chaîne ayant la même valeur
  • S'il est trouvé, la JVM renvoie la référence à cette chaîne sans allouer de mémoire supplémentaire
  • S'il n'est pas trouvé, la JVM l'ajoute au pool (l'internes) et renvoie sa référence

Q8. Est-ce que String Thread-Safe? Comment?

Les chaînes sont en effet complètement thread-safe car elles sont immuables. Toute classe immuable se qualifie automatiquement pour la sécurité des threads, car son immuabilité garantit que ses instances ne seront pas modifiées sur plusieurs threads.

Par exemple, si un thread modifie la valeur d'une chaîne, une nouvelle chaîne est créée au lieu de modifier l'existante.

Q9. Pour quelles opérations de chaîne est-il important de fournir un paramètre régional?

La classe Locale nous permet de différencier les paramètres régionaux culturels ainsi que de formater notre contenu de manière appropriée.

En ce qui concerne la classe String , nous en avons besoin lors du rendu des chaînes au format ou lorsque des chaînes en majuscules ou minuscules.

En fait, si nous oublions de faire cela, nous pouvons rencontrer des problèmes de portabilité, de sécurité et d'utilisabilité.

Q10. Quel est le codage de caractère sous-jacent pour les chaînes?

According to String's Javadocs for versions up to and including Java 8, Strings are stored in the UTF-16 format internally.

The char data type and java.lang.Character objects are also based on the original Unicode specification, which defined characters as fixed-width 16-bit entities.

Starting with JDK 9, Strings that contain only 1-byte characters use Latin-1 encoding, while Strings with at least 1 multi-byte character use UTF-16 encoding.

3. The String API

In this section, we'll discuss some questions related to the String API.

Q11. How Can We Compare Two Strings in Java? What’s the Difference Between str1 == str2 and str1.Equals(str2)?

We can compare strings in two different ways: by using equal to operator ( == ) and by using the equals() method.

Both are quite different from each other:

  • The operator (str1 == str2) checks for referential equality
  • The method (str1.equals(str2)) checks for lexical equality

Though, it's true that if two strings are lexically equal, then str1.intern() == str2.intern() is also true.

Typically, for comparing two Strings for their content, we should always use String.equals.

Q12. How Can We Split a String in Java?

The String class itself provides us with the String#split method, which accepts a regular expression delimiter. It returns us a String[] array:

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

One tricky thing about split is that when splitting an empty string, we may get a non-empty array:

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

Of course, split is just one of many ways to split a Java String.

Q13. What Is Stringjoiner?

StringJoiner is a class introduced in Java 8 for joining separate strings into one, like taking a list of colors and returning them as a comma-delimited string. We can supply a delimiter as well as a prefix and suffix:

StringJoiner joiner = new StringJoiner(",", "[", "]"); joiner.add("Red") .add("Green") .add("Blue"); assertEquals("[Red,Green,Blue]", joiner.toString());

Q14. Difference Between String, Stringbuffer and Stringbuilder?

Strings are immutable. This means that if we try to change or alter its values, then Java creates an absolutely new String.

For example, if we add to a string str1 after it has been created:

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

Then the JVM, instead of modifying str1, creates an entirely new String.

However, for most of the simple cases, the compiler internally uses StringBuilder and optimizes the above code.

But, for more complex code like loops, it will create an entirely new String, deteriorating performance. This is where StringBuilder and StringBuffer are useful.

Both StringBuilder and StringBuffer in Java create objects that hold a mutable sequence of characters.StringBuffer is synchronized and therefore thread-safe whereas StringBuilder is not.

Since the extra synchronization in StringBuffer is typically unnecessary, we can often get a performance boost by selecting StringBuilder.

Q15. Why Is It Safer to Store Passwords in a Char[] Array Rather Than a String?

Since strings are immutable, they don't allow modification. This behavior keeps us from overwriting, modifying, or zeroing out its contents, making Strings unsuitable for storing sensitive information.

We have to rely on the garbage collector to remove a string's contents. Moreover, in Java versions 6 and below, strings were stored in PermGen, meaning that once a String was created, it was never garbage collected.

By using a char[] array, we have complete control over that information.We can modify it or wipe it completely without even relying on the garbage collector.

Using char[] over String doesn't completely secure the information; it's just an extra measure that reduces an opportunity for the malicious user to gain access to sensitive information.

Q16. What Does String’s intern() Method Do?

The method intern() creates an exact copy of a String object in the heap and stores it in the String constant pool, which the JVM maintains.

Java automatically interns all strings created using string literals, but if we create a String using the new operator, for example, String str = new String(“abc”), then Java adds it to the heap, just like any other object.

We can call the intern() method to tell the JVM to add it to the string pool if it doesn't already exist there, and return a reference of that interned string:

String s1 = "Baeldung"; String s2 = new String("Baeldung"); String s3 = new String("Baeldung").intern(); assertThat(s1 == s2).isFalse(); assertThat(s1 == s3).isTrue();

Q17. How Can We Convert String to Integer and Integer to String in Java?

The most straightforward approach to convert a String to an Integer is by using Integer#parseInt:

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

To do the reverse, we can use Integer#toString:

String s = Integer.toString(num);

Q18. What Is String.format() and How Can We Use It?

String#format returns a formatted string using the specified format string and arguments.

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

We also need to remember to specify the user's Locale, unless we are okay with simply accepting the operating system default:

Locale usersLocale = Locale.ITALY; assertEquals("1.024", String.format(usersLocale, "There are %,d shirts to choose from. Good luck.", 1024))

Q19. How Can We Convert a String to Uppercase and Lowercase?

String implicitly provides String#toUpperCase to change the casing to uppercase.

Though, the Javadocs remind us that we need to specify the user's Locale to ensure correctness:

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

Similarly, to convert to lowercase, we have String#toLowerCase:

String s = "Welcome to Baeldung!"; assertEquals("welcome to baeldung!", s.toLowerCase(Locale.UK));

Q20. How Can We Get a Character Array from String?

String provides toCharArray, which returns a copy of its internal char array pre-JDK9 (and converts the String to a new char array in JDK9+):

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

Q21. How Would We Convert a Java String into a Byte Array?

By default, the method String#getBytes() encodes a String into a byte array using the platform’s default charset.

And while the API doesn't require that we specify a charset, we should in order to ensure security and portability:

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

4. String-Based Algorithms

In this section, we'll discuss some programming questions related to Strings.

Q22. How Can We Check If Two Strings Are Anagrams in Java?

An anagram is a word formed by rearranging the letters of another given word, for example, “car” and “arc”.

To begin, we first check whether both the Strings are of equal length or not.

Then we convert them to char[] array, sort them, and then check for equality.

Q23. How Can We Count the Number of Occurrences of a Given Character in a String?

Java 8 really simplifies aggregation tasks like these:

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

And, there are several other great ways to count the l's, too, including loops, recursion, regular expressions, and external libraries.

Q24. How Can We Reverse a String in Java?

There can be many ways to do this, the most straightforward approach being to use the reverse method from StringBuilder (or StringBuffer):

String reversed = new StringBuilder("baeldung").reverse().toString(); assertEquals("gnudleab", reversed);

Q25. How Can We Check If a String Is a Palindrome or Not?

A palindrome is any sequence of characters that reads the same backward as forward, such as “madam”, “radar” or “level”.

To check if a string is a palindrome, we can start iterating the given string forward and backward in a single loop, one character at a time. The loop exits at the first mismatch.

5. Conclusion

Dans cet article, nous avons passé en revue certaines des questions d'entrevue String les plus courantes .

Tous les exemples de code utilisés ici sont disponibles sur GitHub.