JavaRush /בלוג Java /Random-HE /ניתוח שאלות ותשובות מראיונות למפתח Java. חלק 2

ניתוח שאלות ותשובות מראיונות למפתח Java. חלק 2

פורסם בקבוצה
שוב שלום לכולם! אנו ממשיכים לחפש תשובות ל -250+ שאלות למפתחים זוטרים, בינוניים ובכירים. השאלות די מעניינות, ואני בעצמי אוהב לנתח אותן: ברגעים כאלה אפשר לגלות פערים בידע התיאורטי, ובמקומות הכי לא צפויים. ניתוח שאלות ותשובות בראיון.  חלק 2 - 1את החלק הקודם ניתן למצוא במאמר זה . אבל לפני שנתחיל, אני רוצה להזכיר לך ש:
  1. אדלג על שאלות שמצטלבות בסדרת המאמרים הזו כדי לא לשכפל מידע פעם נוספת. אני ממליץ לקרוא חומרים אלה, מכיוון שהם מכילים את שאלות הראיונות הנפוצות ביותר (הפופולריות) של Java Core.
  2. שאלות על DOU מוצגות באוקראינית, אבל הכל יהיה לי כאן ברוסית.
  3. אפשר לתאר את התשובות בפירוט רב יותר, אבל אני לא, שכן אז התשובה לכל שאלה יכולה לקחת מאמר שלם. והם לא ישאלו אותך בפירוט כזה בשום ראיון.
במידת הצורך, אשאיר קישורים ללימוד מעמיק יותר. בוא נעוף!

11. שמות את כל המתודות של המחלקה Object

למחלקה Object יש 11 שיטות:
  • Class<?> getClass() - קבלת המחלקה של האובייקט הנוכחי;
  • int hashCode() - קבלת קוד ה-hash של האובייקט הנוכחי;
  • boolean equals​(Object obj) - השוואה של האובייקט הנוכחי עם אחר;
  • Object clone() - יצירה והחזרה של עותק של האובייקט הנוכחי;
  • String toString() - קבלת ייצוג מחרוזת של אובייקט;
  • void notify() - התעוררות שרשור אחד ממתין בצג של אובייקט זה (בחירת השרשור היא אקראית);
  • void notifyAll() - מעורר את כל השרשורים הממתינים בצג של אובייקט זה;
  • void wait() - מעביר את השרשור הנוכחי למצב המתנה (מקפיא אותו) בצג הנוכחי, עובד רק בבלוק מסונכרן עד שחלק מודיע או מודיע.All מעיר את השרשור;
  • void wait (זמן קצוב ארוך) - גם מקפיא את השרשור הנוכחי בצג הנוכחי (במסונכרן הנוכחי), אך עם טיימר ליציאה ממצב זה (או שוב: עד להודיע ​​או להודיע ​​כל מתעורר);
  • void wait (פסק זמן ארוך, int nanos) - שיטה דומה לזו שתוארה לעיל, אך עם טיימרים מדויקים יותר ליציאה מהקפאה;
  • void finalize() - לפני מחיקת האובייקט הזה, אוסף הזבל קורא לשיטה זו (סוף סוף). הוא משמש לניקוי משאבים תפוסים.
כדי להשתמש נכון בשיטות hashCode , equals​ , clone , toString וסופיות, יש להגדיר אותן מחדש, תוך התחשבות במשימה ובנסיבות הנוכחיות.

12. מה ההבדל בין נסה-עם-משאבים ונסה-לתפוס-סוף סוף כשעוסקים במשאבים?

בדרך כלל, בעת שימוש ב- try-catch-finally, הבלוק הסופי שימש לסגירת משאבים. Java 7 הציגה סוג חדש של אופרטור try-with-resources , אנלוגי של try-catch-finally לשחרור משאבים, אך קומפקטי וקריא יותר. בואו נזכור איך נראה סוף סוף לנסות-לתפוס :
String text = "some text......";
BufferedWriter bufferedWriter = null;
try {
   bufferedWriter = new BufferedWriter(new FileWriter("someFileName"));
   bufferedWriter.write(text);
} catch (IOException e) {
   e.printStackTrace();
} finally {
   try {
       bufferedWriter.close();
   } catch (IOException e) {
       e.printStackTrace();
   }
}
כעת הבה נשכתב את הקוד הזה, אך באמצעות נסה עם משאבים :
String text = "some text......";
try(BufferedWriter bufferedWriter =new BufferedWriter(new FileWriter("someFileName"))) {
   bufferedWriter.write(text);
} catch (IOException e) {
   e.printStackTrace();
}
זה איכשהו נהיה קל יותר, אתה לא חושב? בנוסף לפישוט, יש כמה נקודות:
  1. ב- try-with-resources , משאבים המוצהרים בסוגריים (שייסגרו) חייבים ליישם את הממשק AutoCloseable ואת השיטה היחידה שלו, close() .

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

    אבל, סביר להניח, לעתים רחוקות תכתוב את יישומי המשאבים שלך ואת שיטת הסגירה שלהם.

  2. רצף של ביצוע בלוק:

    1. נסה לחסום .
    2. סוף סוף מרומז .
    3. בלוק תפיסה שתופס חריגים בשלבים קודמים.
    4. סוף סוף מפורש .

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

תאר לעצמך מצב שבו בעת השימוש ב-try-catch-סוף סוף מתרחש חריג ב- try . בהתאם לכך, בלוק catch ספציפי מתחיל מיד לבצע , שבו אתה כותב חריג נוסף (לדוגמה, עם הודעה שמתארת ​​את השגיאה ביתר פירוט), ואתה רוצה שהשיטה תזרוק את החריג הזה הלאה. לאחר מכן מגיעה ביצוע החסימה הסופית , וגם בו נזרק חריג. אבל זה שונה. איזה משני יוצאי דופן אלה תשליך בסופו של דבר שיטה זו? חריג שנזרק על ידי החסימה לבסוף ! אבל יש גם נקודה אחת עם נסה עם משאבים . עכשיו בואו נסתכל על ההתנהגות של נסה עם משאבים באותו מצב. אנו מקבלים חריג בבלוק try כאשר אנו מנסים לסגור משאבים בשיטת close() , כלומר, ב-implicit finally . איזה מהחריגים האלה יתפוס ? זה שנזרק על ידי בלוק הניסיון ! יתעלם חריג מ-implicit finally (מתוך close() ) . התעלמות זו נקראת גם דיכוי חריג.

13. מהן פעולות סיביות?

פעולות סיביות הן פעולות על מחרוזות סיביות הכוללות פעולות לוגיות והזזות סיביות. פעולות לוגיות:
  • AND - משווה ערכי סיביות , ותוך כדי כך, כל ביט שהוגדר ל-0 (false) מגדיר את הביט המקביל בתוצאה כ-0. כלומר, אם בשני הערכים שמשווים הביט היה 1 (true), התוצאה תהיה גם 1.

    מסומן כ- AND , &

    דוגמה: 10111101 & 01100111 = 00100101

  • OR היא הפעולה ההפוכה של הקודמת . כל ביט שהוגדר ל-1 מגדיר ביט דומה בתוצאה ל-1. ובהתאם לכך, אם הביט היה 0 בשני הערכים שהשוו, גם הביט המתקבל יהיה 0.

    מסומן כ- OR , |

    דוגמה: 10100101 | 01100011 = 11100111

  • לא בשיטת bitwise - מוחל על ערך אחד, הופך (הופך) את הביטים. כלומר, אותם סיביות שהיו 1 יהפכו ל-0; ואלו שהיו 0 יהפכו ל-1.

    מסומן כ- NOT , ~

    דוגמה: ~10100101 = 01011010

  • Exclusive bitwise OR - משווה ערכי סיביות, ואם בשני הערכים הביט שווה ל-1, אז התוצאה תהיה 0, ואם בשני הערכים הביט הוא 0, התוצאה תהיה 0. כלומר, כדי שהתוצאה תהיה שווה ל-1, רק אחד מהסיביות חייב היה שווה ל-1, והשני היה שווה ל-0.

    מסומן כ- XOR , ^

    דוגמה: 10100101 ^ 01100011 = 11000110

העברות סיביות - >> או << מעבירים את הביטים של ערך בכיוון שצוין, במספר שצוין. המשרות המתפנות מלאות באפסים. לדוגמה:
  1. 01100011 >> 4 = 00000110
  2. 01100011 << 3 = 00011000
יש גם חריג כאשר מעבירים ימינה מספר שלילי. כזכור, הביט הראשון אחראי על הסימן, ואם סיביות זו שווה ל-1, אז המספר הוא שלילי. אם תזיז מספר שלילי, המיקומים שהתפנו כבר לא יתמלאו באפסים, אלא באחדים, שכן יש צורך לשמור על סיביות הסימן. לדוגמא: 10100010 >> 2 = 11101000 במקביל, בג'אווה ישנו אופרטור משמרת ימני ללא סימן נוסף >>> אופרטור זה הוא אנלוגי של >>, בעת ההסטה, התפקידים המתפנים מתמלאים ב-0, ללא קשר אם המספר שלילי או חיובי. לדוגמה: 10100010 >>> 2 = 00101000 קרא עוד על פעולות סיביות כאן . ניתוח שאלות ותשובות בראיון.  חלק 2 - 2כדוגמאות לשימוש בהעברות סיביות ב-Java, אתה יכול לצטט את שיטת ה-hash() של HashMap, המשמשת לקביעת קוד hash פנימי מיוחד עבור מפתח: ניתוח שאלות ותשובות בראיון.  חלק 2 - 3שיטה זו מאפשרת לך להפיץ נתונים באופן שווה ב-HashMap כדי למזער מספר ההתנגשויות.

14. אילו מחלקות סטנדרטיות בלתי ניתנות לשינוי הן אובייקטים ב-Java?

Immutable הוא אובייקט שלא מאפשר לשנות את הפרמטרים המקוריים שלו. יכול להיות שיש לו שיטות שמחזירות אובייקטים חדשים מסוג נתון, עם פרמטרים שרצית לשנות. כמה אובייקטים סטנדרטיים בלתי ניתנים לשינוי:
  • ללא ספק האובייקט הבלתי ניתן לשינוי המפורסם ביותר ב-Java הוא String;
  • מופעים של מחלקות עטיפה העוטפות סוגים סטנדרטיים: בוליאנית, תו, בייט, קצר, מספר שלם, ארוך, כפול, צף;
  • אובייקטים המשמשים בדרך כלל למספרים גדולים במיוחד - BigInteger ו-BigDecimal;
  • אובייקט שהוא יחידה ב-stacktraces (לדוגמה, ב-stacktrace חריג) StackTraceElement;
  • אובייקט של המחלקה File - יכול לשנות קבצים, אך יחד עם זאת הוא עצמו בלתי ניתן לשינוי;
  • UUID - המשמש לעתים קרובות כמזהה ייחודי לאלמנטים;
  • כל אובייקטי המחלקה של חבילת java.time;
  • Locale - משמש להגדרת אזור גיאוגרפי, פוליטי או תרבותי.

15. מהם היתרונות של אובייקט בלתי משתנה על פני אובייקטים רגילים?

  1. חפצים כאלה בטוחים בשימוש בסביבה מרובת הליכים . על ידי שימוש בהם, אינך צריך לדאוג מאובדן נתונים עקב תנאי מרוץ חוטים. בניגוד לעבודה עם חפצים רגילים: במקרה זה, תצטרכו לחשוב היטב ולבנות את מנגנוני השימוש באובייקט בסביבה מקבילה.
  2. אובייקטים בלתי ניתנים לשינוי הם מפתחות טובים במפה, מכיוון שאם אתה משתמש באובייקט שניתן לשינוי ואז האובייקט משנה את מצבו, זה יכול להיות מבלבל בעת שימוש ב-HashMap: האובייקט עדיין יהיה קיים, ואם אתה משתמש ב- containsKey() ייתכן שהוא לא להימצא.
  3. אובייקטים בלתי ניתנים לשינוי הם מצוינים לאחסון נתונים בלתי ניתנים לשינוי (קבוע) שאסור לשנות אותם בזמן שהתוכנית פועלת.
  4. "אטומיות לכישלון" - אם אובייקט בלתי ניתן לשינוי זורק חריג, הוא עדיין לא יישאר במצב לא רצוי (שבור).
  5. קל לבדוק את השיעורים האלה.
  6. אין צורך במנגנונים נוספים כגון בנאי העתקות ויישום שיבוט.

שאלות על OOP

ניתוח שאלות ותשובות בראיון.  חלק 2 - 4

16. מהם היתרונות של OOP באופן כללי ובהשוואה לתכנות פרוצדורלי?

אז, היתרונות של OOP:
  1. קל יותר לכתוב יישומים מורכבים מאשר תכנות פרוצדורלי, שכן הכל מפורק למודולים קטנים - אובייקטים המקיימים אינטראקציה זה עם זה - וכתוצאה מכך, התכנות מסתכם ביחסים בין אובייקטים.
  2. יישומים שנכתבו באמצעות OOP הם הרבה יותר קלים לשינוי (כל עוד עוקבים אחר מושגי העיצוב).
  3. מכיוון שהנתונים והפעולות עליו מהווים ישות אחת, הם אינם נמרחים לאורך האפליקציה (מה שקורה לרוב בתכנות פרוצדורלי).
  4. עטיית מידע מגינה על הנתונים הקריטיים ביותר מהמשתמש.
  5. אפשר לעשות שימוש חוזר באותו קוד עם נתונים שונים, כי מחלקות מאפשרות ליצור אובייקטים רבים, שלכל אחד מהם יש ערכי תכונה משלו.
  6. ירושה ופולימורפיזם גם מאפשרים לך לעשות שימוש חוזר ולהרחיב את הקוד הקיים (במקום לשכפל פונקציונליות דומה).
  7. הרחבה קלה יותר של יישום מאשר בגישה פרוצדורלית.
  8. גישת OOP מאפשרת הפשטה מפרטי יישום.

17. ספר לנו אילו חסרונות יש ב-OOP

למרבה הצער, הם גם נוכחים:
  1. OOP דורש הרבה ידע תיאורטי שצריך לשלוט בו לפני שתוכל לכתוב משהו.ניתוח שאלות ותשובות בראיון.  חלק 2 - 5
  2. הרעיונות של OOP אינם כל כך קלים להבנה ויישום בפועל (אתה צריך להיות קצת פילוסוף בנשמה).
  3. בשימוש ב-OOP, ביצועי התוכנה מופחתים מעט עקב הארגון המורכב יותר של המערכת.
  4. גישת OOP דורשת יותר זיכרון, שכן הכל מורכב ממחלקות, ממשקים, מתודות, שתופסים הרבה יותר זיכרון ממשתנים רגילים.
  5. הזמן הנדרש לניתוח הראשוני גדול יותר מאשר לניתוח הפרוצדורלי.

18. מהו פולימורפיזם סטטי ודינמי

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

19. הגדירו את עקרון ההפשטה ב-OOP

הפשטה ב-OOP היא דרך להדגיש קבוצה של מאפיינים משמעותיים של אובייקט, למעט פרטים לא חשובים. כלומר, כשמעצבים תוכנית בגישת OOP, מתמקדים במודלים באופן כללי, מבלי להתעמק בפרטי היישום שלהם. ב-Java, ממשקים אחראים להפשטה . לדוגמה, יש לך מכונה, וזה יהיה הממשק. ואינטראקציות שונות איתו – למשל התנעת המנוע, שימוש בתיבת ההילוכים – אלו פונקציות שאנו משתמשים בהן מבלי להיכנס לפרטי יישום. הרי ברגע שאתה נוהג במכונית אתה לא חושב איך בדיוק תיבת ההילוכים ממלאת את ייעודה, או איך המפתח מתניע את המנוע, או איך בדיוק ההגה מסובב את הגלגלים. וגם אם היישום של אחת מהפונקציונליות הזו מוחלף (לדוגמה, המנוע), ייתכן שלא תבחין בכך. זה לא משנה לך: אתה לא נכנס לפרטי היישום. חשוב לך שהפעולה תתבצע. למעשה, זו הפשטה מפרטי יישום. כאן נעצור היום: להמשך!ניתוח שאלות ותשובות בראיון.  חלק 2 - 6
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION