שאלות ראיון ותשובות בנושא מחרוזות Java

הקדמה

String היא אחת מהמחלקות הנפוצות ביותר בשפת ג'אווה. מאמר זה מספק שאלות ותשובות על String כדי לעזור לך להתכונן לראיון.

בנוסף, ניתן לנסות את ה-חידון בג'אווה על מחרוזות כדי לבדוק את הידע שלך על מחלקת ה-String.

מהו מחלקת ה-String בג'אווה? האם String היא סוג נתונים?

String היא מחלקה בג'אווה והיא מוגדרת בחבילת java.lang. זו לא סוג נתונים פרימיטיבי כמו int ו־long. מחלקת ה-String מייצגת מחרוזות תווים. String משמשת בכמעט כל היישומים בג'אווה. String היא לא muttable ו-nal בג'אווה וה-JVM משתמש בבריכת מחרוזות כדי לאחסן את כל אובייקטי ה-String. ניתן ליצור אובייקט של String באמצעות ציטוטי כפול וניתן להעמיד העמסה על אופרטור ה-+ עבור חיבור.

אילו הפעולות השונות ליצירת אובייקט מחרוזת (String) ב-Java?

ניתן ליצור אובייקט מחרוזת (String) באמצעות אופרטור new, או באמצעות גרשיים כפולים. לדוגמה:

String str = new String("abc");
String str1 = "abc";

ישנם מספר בנאים זמינים במחלקת String ליצירת מחרוזת (String) ממערך תווים (char array), ממערך בתים (byte array), מ-StringBuffer, ומ-StringBuilder.

כאשר אתה יוצר מחרוזת (String) באמצעות גרשיים כפולים, ה-JVM מחפשת בבריכת המחרוזות לראות האם כבר קיימת מחרוזת אחרת עם אותו הערך. אם המחרוזת (String) כבר קיימת בבריכה, ה-JVM מחזירה את ההפניה לאותו אובייקט מחרוזת (String). אם המחרוזת החדשה אינה בבריכה, ה-JVM יוצרת אובייקט מחרוזת (String) חדש עם הערך הנתון ושומרת אותו בבריכת המחרוזות. כאשר אתה משתמש באופרטור new, ה-JVM יוצרת את אובייקט המחרוזת (String), אך אינה שומרת אותו בבריכת המחרוזות. ניתן להשתמש בשיטת intern() כדי לשמור את אובייקט המחרוזת (String) בבריכת המחרוזות או להחזיר את ההפניה אם כבר קיימת מחרוזת עם ערך זה בבריכה.

כתוב שיטה ב-Java כדי לבדוק אם מחרוזת הקלט היא פלינדרום.

A string is a palindrome if its value is the same when reversed. For example, aba is a palindrome string. The String class doesn’t provide any method to reverse the string but the StringBuffer and StringBuilder classes have a reverse() method that you can use to check whether a string is a palindrome. For example:

private static boolean isPalindrome(String str) {
    if (str == null)
        return false;
    StringBuilder strBuilder = new StringBuilder(str);
    strBuilder.reverse();
    return strBuilder.toString().equals(str);
}

לפעמים, ראיין עשוי לבקש שלא תשתמש בכל מחלקה אחרת כדי לבדוק פלינדרום. במקרה כזה, ניתן להשוות תווים במחרוזת משני הקצוות כדי לקבוע האם היא פלינדרום. לדוגמה:

private static boolean isPalindromeString(String str) {
    if (str == null)
        return false;
    int length = str.length();
    System.out.println(length / 2);
    for (int i = 0; i < length / 2; i++) {
         if (str.charAt(i) != str.charAt(length - i - 1))
            return false;
    }
    return true;
}

כתוב שיטה ב-Java שתסיר תו נתון מאובייקט מחרוזת.

ניתן להשתמש בשיטת replaceAll כדי להחליף את כל המופעים של מחרוזת במחרוזת אחרת. הנקודה החשובה לציין היא ש־replaceAll() מקבלת String כארגומנט, כך שניתן להשתמש במחלקת Character כדי ליצור מחרוזת ולהשתמש בה כדי להחליף את כל התווים במחרוזת ריקה.

private static String removeChar(String str, char c) {
    if (str == null)
        return null;
    return str.replaceAll(Character.toString(c), "");
}

כיצד ניתן להפוך מחרוזת לאותיות רישאות או קטנות ב-Java?

ניתן להשתמש במחלקת String בשיטות toUpperCase ו־toLowerCase כדי לקבל את אובייקט ה־String באותיות גדולות או קטנות. לשיטות אלו קיימת גרסה שמקבלת פרמטר מקומי ומשתמשת בחוקי הלוקל הנתונים כדי להמיר את המחרוזת לאותיות גדולות או קטנות.

מהו השיטה String subSequence?

בְּגרסת Java 1.4 הוצגה ממשק ה־CharSequence ומחלקת ה־String מיישמת את הממשק הזה, ולכן קיימת במחלקת String את השיטה subSequence. באופן פנימי, השיטה subSequence קוראת לשיטת String substring.

איך ניתן להשוות שתי מחרוזות בתוכנית Java?

איך אפשר להמיר מחרוזת (String) למערך תווים בשפת ג'אווה?

A String object is a sequence of characters, so you can’t convert it to a single character. You can use use the charAt method to get the character at given index or you can use the toCharArray() method to convert a string to character array. Learn more about converting a string to a character array.

איך אפשר להמיר מחרוזת (String) למערך בתי בשפת ג'אווה?

ניתן להשתמש בשיטת getBytes() כדי להמיר אובייקט מסוג String למערך של בתים, וניתן להשתמש בבנאי new String(byte[] arr) כדי להמיר מערך של בתים לאובייקט מסוג String. למד עוד על המרת מחרוזת למערך של בתים.

אפשר להשתמש ב- String בתנאי switch case ב-Java?

ב-Java 7 הוסיפה את יכולות ה- switch case ל- Strings; גרסאות קודמות של Java לא תומכות בזה. אם אתה מיישם זרימת תנאי עבור מחרוזות, ניתן להשתמש בתנאי if-else וניתן להשתמש ב- switch case אם אתה משתמש ב-Java 7 או גרסאות גבוהות יותר. למד עוד על switch case string ב-Java.

כתוב תוכנית Java להדפסת כל התפילות של מחרוזת.

תצטרך להשתמש ברקורסיה כדי למצוא את כל התצורות האפשריות של מחרוזת. לדוגמה, התצורות של AAB הן AAB, ABA ו־BAA. עליך גם להשתמש ב־Set כדי לוודא שאין ערכים כפולים. למד עוד על מציאת כל התצורות האפשריות של מחרוזת.

כתוב פונקציה בִּשְׂפַת ג'אווה למציאת הפלינדרום הארוך ביותר במחרוזת נתונה.

A string can contain palindrome substrings within it. Learn more about how to find the longest palindrome substring in a string.

מה ההבדלים בין String, StringBuffer, ו־StringBuilder בְּשַׂפַּת ג'אווה?

A String object is immutable and final in Java, so whenever you manipulate a String object, it creates a new String object. String manipulations are resource consuming, so Java provides two utility classes for string manipulations, StringBuffer and StringBuilder.

StringBuffer ו־StringBuilder הם מחלקות "mutable". פעולות ב־StringBuffer הן thread-safe ומסונכרנות, בעוד שפעולות ב־StringBuilder אינן thread-safe. יש להשתמש ב־StringBuffer בסביבת רצועות מרובות וב־StringBuilder בסביבת רצועה יחידה. ביצועי StringBuilder מהירים יותר מ־StringBuffer בשל חוסר הפרעה של סנכרון.

מידע נוסף על ההבחנה בין String, StringBuffer ו־StringBuilder ובדיקות ביצועים של StringBuffer ו־StringBuilder.

למה String הוא לא משנה ב־Java?

String הוא לא משנה ב־Java מכיוון שזה מציע מספר יתרונות:

  • אפשרות להשתמש בבריכת המחרוזות מתקיימת כי String אינו משנה ב־Java.
  • זה משפר את האבטחה מאחר וכל האקר פוגע באפשרותו לשנות את הערך שלה, והיא נעשית לשימוש באחסון מידע רגיש כמו שם משתמש או סיסמה לבסיס נתונים.
  • מאחר ש־String היא לא משנה, השימוש בה בסביבת רצועות מרובות אינו מצריך סנכרון.
  • מחרוזות משמשות בטועני המחלקות של ג'אווה ושמירת הקבועות מספקת הבטחה כי המחלקה הנכונה נטענת על ידי המחלקה ClassLoader.

למד עוד על למה מחרוזת היא בלתי משנה בג'אווה.

איך אפשר לפצל מחרוזת בג'אווה?

ניתן להשתמש בsplit(String regex) כדי לפצל את המחרוזת למערך מחרוזות על פי הביטוי הרגולרי הנתון.

למה מעדיפים מערך תווים על מחרוזת לאחסון סיסמאות בג'אווה?

A String object is immutable in Java and is stored in the string pool. Once it’s created it stays in the pool until garbage collection completes, so even though you’re done with the password it’s available in memory for longer duration. It’s a security risk because anyone having access to memory dump can find the password as clear text. If you use a character array to store password, you can set it to blank once you’re done with it. You can control for how long it’s available in memory and that avoids the security threat.

איך אפשר לבדוק אם שני מחרוזות שוות בג'אווה?

ישנם שני דרכים לבדיקה אם שני מחרוזות זהות. ניתן להשתמש באופרטור == או בשיטה equals(). כאשר אתה משתמש באופרטור ==, הוא בודק את ערך המחרוזת וגם את ההפניה לאובייקט. לעיתים קרובות בתכנות ב-Java רוצים לבדוק רק את שוויון הערך של המחרוזת. במקרה זה, עליך להשתמש בשיטה equals() כדי לבדוק האם שתי מחרוזות הן זהות. יש גם פונקציה נוספת בשם equalsIgnoreCase שאפשר להשתמש בה כדי להתעלם מהתחשבנות בגופן.

String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");

System.out.println("s1 == s2 ? " + (s1 == s2)); //true
System.out.println("s1 == s3 ? " + (s1 == s3)); //false
System.out.println("s1 equals s3 ? " + (s1.equals(s3))); //true

מהו בריכת המחרוזות ב-Java?

בריכת המחרוזות היא אוסף של אובייקטי String המאוחסנים בזיכרון ה-heap של Java. String הוא קלאס מיוחד ב-Java ואפשר ליצור אובייקט String באמצעות אופרטור new וגם על ידי ספק ערכים בגרשיים כפולים. למד עוד על בריכת המחרוזות ב-Java.

מה עושה שיטת String intern() של Java?

כאשר השיטה intern() מוזנת, אם הבריכה כבר מכילה מחרוזת ששווה למחרוזת זו על פי שיטת equals(Object), אז המחרוזת מהבריכה תוחזר. אחרת, מחרוזת זו נוספת לבריכה ומצביע לאובייקט מחרוזת זה יוחזר. השיטה תמיד מחזירה אובייקט מחרוזת שיש לו את אותם תוכן כמו במחרוזת המקורית, אך מובטח שהוא מבריכה של מחרוזות ייחודיות.

האם String הוא thread-safe ב-Java?

A String object is immutable, so you can’t change its value after creation. This makes the String object thread-safe and so it can be safely used in a multi-threaded environment. Learn more about thread Safety in Java.

מאחר שאובייקט מחרוזת String הוא לא ניתן לשינוי, הקוד שלו מאוחסן בזמן היצירה ואין צורך לחשב אותו שוב. זה עושה אותו לסוחף מעולה למפתח ב-Map מאחר והעיבוד שלו מהיר יותר מאובייקטי מפתח אחרים של HashMap.

נחש את הפלט

נסה לנחש את הפלט של קטעי הקוד ב-Java הבאים.

public class StringTest {
    
  	public static void main(String[] args) {
   		String s1 = new String("digitalocean");
   		String s2 = new String("DIGITALOCEAN");
   		System.out.println(s1 = s2);
   	}
    
}
Output
DIGITALOCEAN

הפלט הוא DIGITALOCEAN מכיוון שהקוד משוייך את הערך של String s2 ל-String s1. = הוא אופרטור השמה שמשוייך את הערך של y ל-x בתבנית (x = y). == הוא אופרטור השוואה שבודק האם אובייקט הפניה זהה עבור שתי המחרוזות.


public class Test {
    
   	 public void foo(String s) {
   	 System.out.println("String");
   	 }
    
   	 public void foo(StringBuffer sb) {
   	 System.out.println("StringBuffer");
   	 }
    
   	 public static void main(String[] args) {
   		new Test().foo(null);
   	}
    
}
Output
Test.java:12: error: reference to foo is ambiguous
   		new Test().foo(null);
   		           ^
  both method foo(String) in Test and method foo(StringBuffer) in Test match

קוד זה מכיל שגיאת זמן קומפילציה מכיוון ששני השיטות foo יש להן את אותו השם, והקריאה לשיטה foo ב-main מעבירה null. המהדר לא יודע איזו שיטה לקרוא. ניתן גם להסתכל על שגיאת אי ייבוא של מתודה X עבור הטיפוס Y.


String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2);
Output
false

הפלט הוא false מכיוון שהקוד משתמש באופרטור new כדי ליצור את אובייקט ה-String, לכן הוא נוצר בזיכרון ההשקה ול-s1 ול-s2 יש ייחודיות שונה. אם תיצור את המחרוזות רק באמצעות גרשיים כפולים, אז הן יהיו בבריכת המחרוזות והפלט יהיה true.


String s1 = "abc";
StringBuffer s2 = new StringBuffer(s1);
System.out.println(s1.equals(s2));
Output
false

הפלט הוא false מכיוון ש-s2 אינו מסוג String. יש במימוש של שיטת equals() במחלקת String אופרטור instanceof לבדיקה אם סוג האובייקט שנשלח הוא String ומחזיר false אם האובייקט אינו מסוג String.


String s1 = "abc";
String s2 = new String("abc");
s2.intern();
System.out.println(s1 == s2);
Output
false

הפלט הוא false. שיטת intern() מחזירה את הרפרנס של אובייקט ה-String מבריכת המחרוזות. עם זאת, הקוד לא משהה את ההקצאה ל-s2 ואין שינוי ב-s2, ולכן s1 ו-s2 יש רפרנס שונה. אם תשנה את הקוד בשורה 3 ל-s2 = s2.intern();, אז הפלט יהיה true.

כמה אובייקטי String נוצרים על ידי הקוד הבא?

String s1 = new String("Hello");  
String s2 = new String("Hello");
Answer

התשובה היא שלוש. הקוד בשורה 1 יוצר אובייקט String עם הערך Hello בבריכת המחרוזות (אובייקט ראשון) ואז יוצר אובייקט String חדש עם הערך Hello בזיכרון הערימה (אובייקט שני). הקוד בשורה 2 יוצר אובייקט String חדש עם הערך Hello בזיכרון הערימה (אובייקט שלישי) ומשתמש שוב במחרוזת Hello מבריכת המחרוזות.

מסקנה

במאמר זה סקרת כמה שאלות ראיון ב-Java בנושא String.

קריאה מומלצת:

שאלות תכנות ב-Java
תוכניות מחרוזת ב-Java

Source:
https://www.digitalocean.com/community/tutorials/java-string-interview-questions-and-answers