שאלות ראיונות עם חריגות Java (+ תשובות)

מאמר זה הוא חלק מסדרה: • שאלות ראיונות בנושא אוספי Java

• שאלות בנושא ראיונות מערכת מסוג Java

• שאלות על ראיונות במקביל ל- Java (+ תשובות)

• שאלות על ראיונות מבנה כיתת Java ו אתחול

• Java 8 שאלות ראיונות (+ תשובות)

• ניהול זיכרון בשאלות ראיון עם Java (+ תשובות)

• שאלות ראיונות עם Java Generics (+ תשובות)

• שאלות ראיונות עם בקרת זרימת Java (+ תשובות)

• שאלות על ראיונות חריגים עם Java (+ תשובות) (מאמר נוכחי) • שאלות על ראיונות של Java הערות (+ תשובות)

• שאלות על ראיונות מסגרת האביב המובילה

1. סקירה כללית

חריגים הם נושא חיוני שכל מפתח Java צריך להכיר. מאמר זה מספק תשובות לכמה מהשאלות שעשויות לצוץ במהלך ראיון.

2. שאלות

שאלה 1. מהו חריג?

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

שאלה 2. מה המטרה של מילות המפתח לזרוק ולזרוק?

ה זורק מילת המפתח משמשת כדי לציין ששיטה עשויה להעלות חריג במהלך ביצועה. זה אוכף טיפול חריג מפורש בעת קריאה לשיטה:

public void simpleMethod () זורק חריג {// ...}

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

if (task.isTooComplicated ()) {זרוק TooComplicatedException חדש ("המשימה מסובכת מדי"); }

שאלה 3. כיצד ניתן להתמודד עם חריג?

באמצעות א נסה לתפוס סוף סוף הַצהָרָה:

נסה {// ...} לתפוס (ExceptionType1 ex) {// ...} לתפוס (ExceptionType2 ex) {// ...} סוף סוף {// ...}

גוש הקוד שבו עשוי להתרחש חריג מוקף ב לְנַסוֹת לַחסוֹם. חסימה זו נקראת גם קוד "מוגן" או "שמור".

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

ה סוף כל סוף החסימה מתבצעת תמיד לאחר לְנַסוֹת יציאה לחסימה, בין אם הושלך חריג או לא בתוכו.

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

ישנן שלוש דרכים לטיפול בחריגים מרובים בבלוק קוד.

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

נסה {// ...} לתפוס (לשעבר חריג) {// ...}

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

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

הדרך השנייה היא הטמעת מספר חסימות תפיסה:

נסה {// ...} לתפוס (FileNotFoundException לשעבר) {// ...} לתפוס (EOFException לשעבר) {// ...}

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

השלישי הוא להשתמש בבלוק רב-תפוס:

נסה לתפוס {// ...} (FileNotFoundException | EOFException ex) {// ...}

תכונה זו, שהוצגה לראשונה ב- Java 7; מפחית שכפול קוד ומקל על התחזוקה.

ש 5. מה ההבדל בין חריג בדוק לחריג?

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

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

כל החריגים הם חריגים מסומנים, למעט אלה המצוינים על ידי שְׁגִיאָה, חריגת זמן ריצה, וסוגי המשנה שלהם.

שאלה 6. מה ההבדל בין חריג לשגיאה?

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

כל השגיאות שנזרקו על ידי ה- JVM הן מקרים של שְׁגִיאָה או אחת מתתי קבוצות המשנה שלה, הנפוצות יותר כוללות אך אינן מוגבלות ל:

  • OutOfMemoryError - נזרק כאשר ה- JVM אינו יכול להקצות יותר אובייקטים מכיוון שהוא אינו בזיכרון, ואספן האשפה לא הצליח להנגיש יותר
  • StackOverflowError - מתרחש כאשר שטח הערימה של השרשור נגמר, בדרך כלל מכיוון שיישום חוזר עמוק מדי
  • ExceptionInInitializerError - מסמן כי התרחש חריג לא צפוי במהלך הערכת האתחול הסטטי
  • NoClassDefFoundError - נזרק כאשר מעמיס הכיתה מנסה לטעון את ההגדרה של כיתה ולא מצא אותה, בדרך כלל בגלל הנדרש מעמד קבצים לא נמצאו במסלול הכיתה
  • UnsupportedClassVersionError - מתרחש כאשר ה- JVM מנסה לקרוא א מעמד קובץ וקובע כי הגרסה בקובץ אינה נתמכת, בדרך כלל מכיוון שהקובץ נוצר עם גרסה חדשה יותר של Java

למרות שניתן לטפל בשגיאה באמצעות לְנַסוֹת הצהרה, זה אינו נוהג מומלץ מאחר ואין כל ערובה לכך שהתוכנית תוכל לעשות דבר בצורה מהימנה לאחר השלכת השגיאה.

ש 7. איזה יוצא מן הכלל ייזרק בביצוע חסימת הקוד הבאה?

מספר שלם [] [] ints = {{1, 2, 3}, {null}, {7, 8, 9}}; System.out.println ("value =" + ints [1] [1] .intValue ());

זה זורק אינדקס מערך מחוץ לתחום Exception מכיוון שאנחנו מנסים לגשת למיקום גדול מאורך המערך.

ש 8. מה זה שרשרת חריגים?

מתרחש כאשר חריג מושלך כתגובה לחריג אחר. זה מאפשר לנו לגלות את ההיסטוריה המלאה של הבעיה שהעלתה:

נסה את {task.readConfigFile (); } לתפוס (FileNotFoundException ex) {לזרוק TaskException חדש ("לא ניתן לבצע משימה", לשעבר); }

שאלה 9. מהי מסלול ערימה ואיך זה קשור לחריג?

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

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

ש 10. מדוע תרצה לסווג חריג בסיווג משנה?

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

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

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

שאלה 11. מהם יתרונות חריגים?

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

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

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

שאלה 12. האם אתה יכול לזרוק כל חריג בתוך גופו של ביטוי למבדה?

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

רשימת מספרים שלמים = Arrays.asList (3, 9, 7, 0, 10, 20); מספרים שלמים.forEach (i -> {if (i == 0) {זרוק IllegalArgumentException חדש ("אפס אסור");} System.out.println (Math.PI / i);});

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

@FunctionalInterface ממשק סטטי ציבורי CheckedFunction {void apply (T t) זורק חריג; }
תהליך הריק הציבורי משימות (רשימת taks, CheckedFunction בדק פונקציה) {עבור (משימת משימה: taks) {נסה {kontrolFunction.apply (משימה); } לתפוס (Exception e) {// ...}}} משימות תהליך (רשימת משימות, t -> {// ... לזרוק חריג חדש ("משהו קרה");});

ש 13. מהם הכללים שעלינו לעקוב כאשר אנו מבטלים שיטה המיידית חריג?

כמה כללים מכתיבים כיצד יש להכריז על חריגים בהקשר לירושה.

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

הנה קוד לדוגמא כדי להדגים זאת:

class הורה {void doSomething () {// ...}} class child מרחיב הורה {void doSomething () זורק IllegalArgumentException {// ...}}

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

class הורה {void doSomething () {// ...}} class Child מרחיב הורה {void doSomething () זורק IOException {// שגיאת קומפילציה}}

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

הנה קוד לדוגמא שעוקב אחר הכלל הקודם בהצלחה:

class Parent {void doSomething () זורק IOException, ParseException {// ...} void doSomethingElse () זורק IOException {// ...}} class Child מרחיב הורה {void doSomething () זורק IOException {// ...} בטל doSomethingElse () זורק FileNotFoundException, EOFException {// ...}}

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

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

class Parent {void doSomething () זורק FileNotFoundException {// ...}} class Child מרחיב הורה {void doSomething () זורק IOException {// שגיאת קומפילציה}}

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

הנה דוגמה שמכבדת את הכלל:

class Parent {void doSomething () זורק IllegalArgumentException {// ...}} class child מרחיב הורה {void doSomething () זורק ArithmeticException, BufferOverflowException {// ...}}

ש 14. האם יתקיים הקוד הבא?

בטל doSomething () {// ... לזרוק RuntimeException חדש (חריג חדש ("חריג משורשר")); }

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

ש 15. האם יש דרך לזרוק חריג בדוק משיטה שאין לה סעיף זורק?

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

ציבורי T sneakyTrow (זורק לשעבר) זורק T {לזרוק (T) לשעבר; } method void publicWithoutThrows () {this.sneakyThrow (חריג חדש ("חריג מסומן")); }

3. מסקנה

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

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

הַבָּא » שאלות ראיונות בהערות ג'אווה (+ תשובות) « שאלות ראיונות קודמות על בקרת זרימת Java (+ תשובות)