שאלות ותשובות על ראיונות עם Java String

1. הקדמה

ה חוּט class הוא אחד השיעורים הנפוצים ביותר ב- Java, מה שגרם למעצבי השפות לטפל בו במיוחד. התנהגות מיוחדת זו הופכת אותו לאחד הנושאים החמים ביותר בראיונות Java.

במדריך זה נעבור כמה משאלות הראיון הנפוצות ביותר בנושא חוּט.

2. חוּט יסודות

חלק זה מורכב משאלות הנוגעות ל חוּט מבנה וזיכרון פנימיים.

שאלה 1. מהי מחרוזת בג'אווה?

בג'אווה, א חוּט מיוצג באופן פנימי על ידי מערך של בתים ערכים (או לְהַשְׁחִיר ערכים לפני JDK 9).

בגרסאות עד וכוללות Java 8, א חוּט הורכב ממערך בלתי משתנה של דמויות יוניקוד. עם זאת, רוב התווים דורשים 8 סיביות בלבד (1 בייט) לייצג אותם במקום 16 ביטים (לְהַשְׁחִיר גודל).

לשיפור צריכת הזיכרון והביצועים, ג'אווה 9 הציגה מיתרים קומפקטיים. משמעות הדבר היא שאם א חוּט מכיל תווים של בת אחד בלבד, הוא יוצג באמצעות לטינית -1 הַצפָּנָה. אם חוּט מכיל לפחות תו רב בתים אחד, הוא יוצג כשני בתים לכל תו באמצעות קידוד UTF-16.

ב- C ו- C ++, חוּט הוא גם מערך של תווים, אבל ב- Java, זה אובייקט נפרד עם API משלו.

שאלה 2. כיצד נוכל ליצור אובייקט מחרוזת בג'אווה?

מיתר מגדיר 13 דרכים שונות ליצור a חוּט. באופן כללי, לעומת זאת, ישנם שניים:

  • דרך א חוּט מילולי:
    מחרוזת s = "abc";
  • דרך ה חָדָשׁ מילת מפתח:
    מחרוזת s = מחרוזת חדשה ("abc");

כל מילולי המיתרים ב- Java הם מקרים של חוּט מעמד.

שאלה 3. האם חוּט פרימיטיבי או סוג נגזר?

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

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

  • אמנם מחרוזות אינן מאוחסנות בערמת השיחות כמו פרימיטיביים, אך הן כן מאוחסן באזור זיכרון מיוחד הנקרא מאגר המיתרים
  • כמו פרימיטיבים, אנו יכולים להשתמש ב- + מפעיל על חוטים
  • ושוב, כמו פרימיטיבים, אנו יכולים ליצור מופע של חוּט בלי ה חָדָשׁ מילת מפתח

שאלה 4. מה היתרונות של מיתרים להיות בלתי ניתנים לשינוי?

על פי ראיון של ג'יימס גוסלינג, המיתרים אינם משתנים לשיפור הביצועים והביטחון.

ולמעשה, אנו רואים כמה יתרונות שיש חוטים בלתי ניתנים לשינוי:

  • מאגר המיתרים אפשרי רק אם המחרוזות, לאחר שנוצרו, מעולם לא משתנות, כפי שהם אמורים לעשות בהם שימוש חוזר
  • הקוד יכול להעביר מחרוזת בבטחה לשיטה אחרת, בידיעה שאי אפשר לשנות את זה בשיטה זו
  • ללא שינוי הופך את הכיתה הזו לבטוחה באופן אוטומטי
  • מכיוון שהשיעור הזה מוגן בחוטים, אין צורך לסנכרן נתונים נפוצים, אשר בתורו משפר ביצועים
  • מכיוון שמובטח שהם לא ישתנו, ניתן לשמר בקלות את ה- hashcode שלהם

ש 5. כיצד שומרים מחרוזת בזיכרון?

על פי מפרט JVM, חוּט מילוליות מאוחסנות במאגר קבוע של זמן ריצה, המוקצה מאזור השיטה של ​​ה- JVM.

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

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

שאלה 6. האם מחרוזות כלולות כשירות לאיסוף זבל בג'אווה?

כן הכל חוּטs במאגר המיתרים זכאים לאיסוף אשפה אם אין הפניות מהתוכנית.

ש 7. מהי הבריכה המתמדת במיתרים?

בריכת המיתרים, המכונה גם חוּט בריכה קבועה או חוּט בריכת מתמחים, הוא אזור זיכרון מיוחד בו חנויות JVM חוּט מקרים.

זה מייעל את ביצועי היישומים על ידי הקטנת התדירות וכמה המחרוזות המוקצות:

  • ה- JVM מאחסן רק עותק אחד של מסוים חוּט בבריכה
  • בעת יצירת חדש חוּט, ה- JVM מחפש בבריכה a חוּט בעל אותו ערך
  • אם נמצא, ה- JVM מחזיר את ההפניה לכך חוּט מבלי להקצות זיכרון נוסף
  • אם לא נמצא, ה- JVM מוסיף אותו לבריכה (מתמחה בו) ומחזיר את הפניה

ש 8. האם חוט מחרוזת בטוח? אֵיך?

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

לדוגמא, אם שרשור משנה ערך של מחרוזת, חדש חוּט נוצר במקום לשנות את הקיים.

שאלה 9. לאילו פעולות מיתרים חשוב לספק מקום?

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

כשמדובר ב חוּט בכיתה, אנחנו צריכים את זה כשמגישים מחרוזות פנימה פוּרמָט או כאשר מיתרי מעטפת תחתונה או עליונה.

למעשה, אם נשכח לעשות זאת, אנו יכולים להיתקל בבעיות ניידות, אבטחה ושימושיות.

ש 10. מהו קידוד הדמות הבסיסי עבור מיתרים?

לפי חוּט's Javadocs עבור גרסאות עד וכוללות Java 8, מיתרים מאוחסנים בפורמט UTF-16 באופן פנימי.

ה לְהַשְׁחִיר סוג נתונים ו- java.lang. דמות אובייקטים מבוססים גם על המפרט המקורי של Unicode, שהגדיר תווים כישויות 16 סיביות ברוחב קבוע.

החל מ- JDK 9, מיתרים המכילים תווים של בת אחד בלבד לטינית -1 קידוד, בעוד מיתרים עם לפחות תו רב בתים אחד השתמש בקידוד UTF-16.

3. ה חוּט ממשק API

בחלק זה נדון בכמה שאלות הקשורות ל- חוּט ממשק API.

שאלה 11. כיצד נוכל להשוות בין שני מיתרים בג'אווה? מה ההבדל בין str1 == str2 ו- str1.Equals (str2)?

אנו יכולים להשוות מחרוזות בשתי דרכים שונות: באמצעות שווה ל- operator (==) ועל ידי שימוש ב- שווים() שיטה.

שניהם די שונים זה מזה:

  • המפעיל (str1 == str2) בודק שוויון התייחסותי
  • השיטה (str1.equals (str2)) בודק שוויון מילוני

אם כי, נכון שאם שני מחרוזות שווים באופן מילולי, אז str1.intern () == str2.intern () גם נָכוֹן.

בדרך כלל, לשם השוואה בין שניים מיתרים עבור התוכן שלהם, אנחנו צריכים להשתמש תמיד String.equals.

שאלה 12. כיצד נוכל לפצל מחרוזת בג'אווה?

ה חוּט הכיתה עצמה מספקת לנו את חוּט#לְפַצֵל שיטה, המקבלת תיחום ביטוי רגולרי. זה מחזיר לנו א חוּט[] מַעֲרָך:

מחרוזת [] חלקים = ​​"ג'ון, פיטר, מרי" .split (","); assertEquals (מחרוזת חדשה [] {"ג'ון", "פיטר", "מרי"}, חלקים);

דבר מסובך אחד לגבי לְפַצֵל זה שכאשר מפצלים מחרוזת ריקה, אנו עשויים לקבל מערך שאינו ריק:

assertEquals (מחרוזת חדשה [] {""}, "" .split (","));

כמובן, לְפַצֵל היא רק אחת מדרכים רבות לפצל Java חוּט.

ש 13. מה זה מחרוזת?

StringJoiner הוא מחלקה שהוצגה ב- Java 8 להצטרפות מיתרים נפרדים לאחד, כמו לקיחת רשימת צבעים והחזרתם כמחרוזת תווית פסיקים. אנו יכולים לספק תיחום כמו גם קידומת וסיומת:

מצטרף StringJoiner = StringJoiner חדש (",", "[", "]"); joiner.add ("אדום") .add ("ירוק") .add ("כחול"); assertEquals ("[אדום, ירוק, כחול]", joiner.toString ());

ש 14. ההבדל בין String, Stringbuffer ו- Stringbuilder?

מיתרים הם בלתי ניתנים לשינוי. זה אומר ש אם ננסה לשנות או לשנות את ערכיו, אז ג'אווה יוצרת חדש לחלוטין חוּט.

לדוגמא, אם נוסיף למחרוזת str1 לאחר שנוצר:

מחרוזת str1 = "abc"; str1 = str1 + "def";

ואז ה- JVM, במקום לשנות str1, יוצר חדש לגמרי חוּט.

עם זאת, ברוב המקרים הפשוטים, המהדר משתמש באופן פנימי StringBuilder ומייעל את הקוד לעיל.

אבל, עבור קוד מורכב יותר כמו לולאות, זה ייצור חדש לגמרי חוּט, ביצועים מתדרדרים. זה איפה StringBuilder ו StringBuffer שימושיים.

שניהם StringBuilder ו StringBuffer ב- Java צור אובייקטים המכילים רצף דמויות משתנה.StringBuffer מסונכרן ולכן בטוח בחוטים ואילו StringBuilder לא.

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

ש 15. מדוע בטוח יותר לאחסן סיסמאות בתו [] מערך מאשר מחרוזת?

מכיוון שהמחרוזות אינן ניתנות לשינוי, הן אינן מאפשרות שינוי. התנהגות זו מונעת מאיתנו להחליף, לשנות או לאפס את תוכנו ולהכין אותו מיתרים לא מתאים לאחסון מידע רגיש.

עלינו להסתמך על אספן האשפה שיסיר את תוכן המחרוזת. יתר על כן, בגרסאות Java 6 ומטה, מחרוזות נשמרו ב- PermGen, כלומר פעם אחת חוּט נוצר, זה מעולם לא נאסף אשפה.

באמצעות א לְהַשְׁחִיר[] מערך, יש לנו שליטה מלאה על המידע הזה.אנו יכולים לשנות אותו או לנגב אותו לחלוטין בלי להסתמך אפילו על גובה האשפה.

באמצעות לְהַשְׁחִיר[] על חוּט אינו מאבטח לחלוטין את המידע; זה רק אמצעי נוסף שמצמצם את הזדמנות המשתמש הזדוני לקבל גישה למידע רגיש.

ש 16. מה עושה המתודה () של המתמחה ()?

השיטה מתמחה () יוצר עותק מדויק של חוּט חפץ בערימה ומאחסן אותו בתוך חוּט בריכה מתמדת, אשר ה- JVM מקיים.

ג'אווה מתמנית אוטומטית בכל המחרוזות שנוצרו באמצעות מילולי מחרוזות, אך אם ניצור א חוּט באמצעות המפעיל החדש, למשל, מחרוזת str = מחרוזת חדשה ("abc")ואז ג'אווה מוסיפה אותו לערימה, בדיוק כמו כל אובייקט אחר.

אנחנו יכולים להתקשר ל מתמחה () שיטה להגיד ל- JVM להוסיף אותו למאגר המיתרים אם הוא כבר לא קיים שם, ולהחזיר הפניה למחרוזת המתמחה הזו:

מחרוזת s1 = "Baeldung"; מחרוזת s2 = מחרוזת חדשה ("באלדונג"); מחרוזת s3 = מחרוזת חדשה ("באלדונג"). מתמחה (); assertThat (s1 == s2) .isFalse (); assertThat (s1 == s3) .isTrue ();

ש 17. איך נוכל להמיר מחרוזת לשלם ומלא למחרוזות בג'אווה?

הגישה הכי פשוטה להמיר א חוּט ל מספר שלם הוא באמצעות מספר שלם#מזויף:

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

כדי לעשות את ההפך, נוכל להשתמש מספר שלם#toString:

מחרוזת s = Integer.toString (num);

ש 18. מה זה String.format () וכיצד נוכל להשתמש בו?

פורמט # מחרוזת מחזיר מחרוזת מעוצבת באמצעות מחרוזת הפורמט והארגומנטים שצוינו.

כותרת מחרוזת = "באלדונג"; מחרוזת מעוצבת = String.format ("הכותרת היא% s", הכותרת); assertEquals ("הכותרת היא Baeldung", מעוצב);

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

משתמשים מקומיים Locale = מקומי. ITALY; assertEquals ("1.024", String.format (usersLocale, "יש%, d חולצות לבחירה. בהצלחה.", 1024))

ש 19. כיצד נוכל להמיר מחרוזת לאותיות רישיות וקטנות?

חוּט מרומז מספק מחרוזת # toUpperCase כדי לשנות את המעטפת לרישיות.

למרות זאת, ה- Javadocs מזכירים לנו שעלינו לציין את המשתמש לאוקלה כדי להבטיח נכונות:

מחרוזת s = "ברוך הבא לבלדונג!"; assertEquals ("WELCOME TO BAELDUNG!", s.toUpperCase (Locale.US));

באופן דומה, כדי להמיר לאותיות קטנות, יש לנו מחרוזת # toLowerCase:

מחרוזת s = "ברוך הבא לבלדונג!"; assertEquals ("ברוכים הבאים לביילדונג!", s.toLowerCase (Locale.UK));

ש 20. איך נוכל להשיג מערך תווים ממחרוזת?

חוּט מספק toCharArray, שמחזיר עותק מהפנימי שלו לְהַשְׁחִיר מערך מראש JDK9 (וממיר את חוּט לחדש לְהַשְׁחִיר מערך ב- JDK9 +):

char [] שלום = "שלום" .toCharArray (); assertArrayEquals (מחרוזת חדשה [] {'h', 'e', ​​'l', 'l', 'o'}, שלום);

ש 21. איך היינו ממירים מחרוזת Java למערך בתים?

כברירת מחדל, השיטה מחרוזת # getBytes () מקודד מחרוזת למערך בתים באמצעות ערכת ברירת המחדל של הפלטפורמה.

ולמרות שממשק ה- API אינו דורש לציין ערכת תווים, עלינו להבטיח אבטחה וניידות:

בתים [] byteArray2 = "efgh" .getBytes (StandardCharsets.US_ASCII); בתים [] byteArray3 = "ijkl" .getBytes ("UTF-8");

4. חוּט-אלגוריתמים מבוססים

בחלק זה נדון בכמה שאלות תכנות הקשורות ל חוּטס.

ש 22. כיצד נוכל לבדוק אם שני מיתרים הם אנגרמות בג'אווה?

אנגרמה היא מילה שנוצרה על ידי סידור מחדש של האותיות של מילה נתונה אחרת, למשל, "מכונית" ו"קשת ".

כדי להתחיל, ראשית נבדוק האם שניהם מיתרים באורך שווה או לא.

ואז אנחנו ממירים אותם ל לְהַשְׁחִיר[] מערך, מיין אותם ואז בדוק אם קיימת שוויון.

ש 23. כיצד ניתן למנות את מספר המופעים של דמות נתונה במחרוזת?

Java 8 ממש מפשט משימות צבירה כמו אלה:

ספירה ארוכה = "שלום". צ'ארס (). פילטר (ch -> (char) ch == 'l'). ספירה (); assertEquals (2, count);

וישנן עוד כמה דרכים נהדרות לספור את ה- l, כולל לולאות, רקורסיה, ביטויים רגולריים וספריות חיצוניות.

ש 24. כיצד נוכל להפוך מחרוזת בג'אווה?

יכולות להיות דרכים רבות לעשות זאת, והגישה הפשוטה ביותר היא להשתמש ב- לַהֲפוֹך שיטה מ StringBuilder (אוֹ StringBuffer):

מחרוזת הפוכה = StringBuilder חדש ("baeldung"). הפוך (). ToString (); assertEquals ("gnudleab", הפוך);

ש 25. כיצד נוכל לבדוק אם מחרוזת היא פלינדרום או לא?

פלינדרום הוא כל רצף של תווים שקוראים אותו לאחור כמו קדימה, כמו "גברת", "מכ"ם" או "רמה".

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

5. מסקנה

במאמר זה עברנו כמה מהנפוצים ביותר חוּט שאלות ראיון.

כל דגימות הקוד המשמשות כאן זמינות ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found