JavaRush /בלוג Java /Random-HE /Java Core. שאלות לראיון, חלק 3
Vadim625
רָמָה

Java Core. שאלות לראיון, חלק 3

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

העתקה עמוקה והעתקה רדודה

העתק מדויק של המקור הוא השיבוט שלו. ב-Java, זה אומר להיות מסוגל ליצור אובייקט עם מבנה דומה לאובייקט המקורי. השיטה clone()מספקת פונקציונליות זו. העתקה רדודה מעתיקה כמה שפחות מידע. כברירת מחדל, השיבוט בג'אווה הוא רדוד, כלומר. Object classלא יודע על מבנה המחלקה שהיא מעתיקה. בעת שיבוט, ה-JVM עושה את הפעולות הבאות:
  1. אם למחלקה יש רק איברים מסוגים פרימיטיביים, אזי ייווצר עותק חדש לגמרי של האובייקט והפניה לאותו אובייקט תוחזר.
  2. אם מחלקה מכילה לא רק חברים מסוגים פרימיטיביים, אלא גם חברים מכל סוג מחלקה אחר, הפניות לאובייקטים של מחלקות אלה מועתקות. לכן, לשני האובייקטים יהיו אותן הפניות.
העתקה עמוקה משכפלת הכל. העתקה עמוקה היא שני אוספים, שאחד מהם משכפל את כל מרכיבי האוסף המקורי. אנו רוצים ליצור עותק כך שביצוע שינויים ברכיב כלשהו של העותק לא ישפיע על האוסף המקורי. שיבוט עמוק דורש את הכללים הבאים:
  1. אין צורך להעתיק נתונים פרימיטיביים בנפרד;
  2. כל הכיתות החברים במחלקה המקורית חייבות לתמוך בשיבוט. עבור כל חבר בכיתה, יש לקרוא super.clone()כאשר השיטה מועברת clone();
  3. אם חבר כלשהו במחלקה אינו תומך בשיבוט, אז בשיטת השיבוט, עליך ליצור מופע חדש של אותה מחלקה ולהעתיק כל אחד מחבריה עם כל התכונות לאובייקט מחלקה חדש, אחד בכל פעם.
למידע נוסף על שיבוט כאן

מהו סנכרון? נעילה ברמת האובייקט ונעילה ברמת הכיתה?

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

מה ההבדל בין sleep() לבין wait()?

Sleep()היא שיטה המשמשת לעיכוב התהליך לכמה שניות. במקרה של wait(), השרשור נמצא במצב המתנה עד שנקרא לשיטת notify()או notifyAll(). ההבדל העיקרי הוא שהוא wait()משחרר את נעילת הצג בזמן שהוא sleep()לא משחרר את הנעילה. Wait()משמש עבור יישומים מרובי הליכי, sleep()המשמשים פשוט כדי להשהות את ביצוע השרשור. Thread.sleep()מכניס את השרשור הנוכחי למצב "לא ניתן להרצה" למשך פרק זמן מסוים. השרשור שומר את מצב המוניטור שהיה לפני שנקראה שיטה זו. אם שרשור אחר יתקשר t.interrupt(), השרשור ש"נרדם" יתעורר. שימו לב שזו sleep()שיטה סטטית, כלומר היא תמיד משפיעה על השרשור הנוכחי (זה שמבצע את השיטה sleep()). טעות נפוצה היא לקרוא t.sleep()איפה tעוד חוט; גם כאשר השרשור הנוכחי שקרא לשיטה sleep()אינו tשרשור. Object.wait()שולח את השרשור הנוכחי למצב "לא ניתן להרצה" לזמן מה, בדיוק כמו sleep(), אבל עם ניואנסים מסוימים. Wait()נקרא על חפץ, לא על חוט; אנו קוראים לאובייקט הזה "אובייקט מנעול". לפני הקריאה lock.wait(), יש לסנכרן את השרשור הנוכחי עם "אובייקט הנעילה"; wait()לאחר מכן, הוא משחרר את המנעול הזה, ומוסיף את השרשור ל"רשימת ההמתנה" הקשורה למנעול זה. מאוחר יותר, שרשור אחר יכול להסתנכרן עם אותו אובייקט נעילה ולקרוא ל- lock.notify(). שיטה זו "תעיר" את השרשור המקורי, שעדיין ממתין. באופן עקרוני, ניתן להשוות את wait()/ ל- / , רק שהשרשור הפעיל אינו צריך מצביע ישיר לחוט השינה, הוא רק צריך לדעת את אובייקט הנעילה המשותף. קרא את ההבדל המפורט כאן.notify()sleep()interrupt()

האם ניתן להקצות לזה null למשתנה התייחסות?

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

מה ההבדל בין && ל-&?

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

כיצד לעקוף את שיטות equals() ו-hachCode()?

hashCode()ושיטות equals()מוגדרות במחלקה Object, שהיא מחלקת האב עבור אובייקטי Java. מסיבה זו, כל אובייקטי Java יורשים את מימוש ברירת המחדל עבור שיטות. השיטה hashCode()משמשת להשגת מספר שלם ייחודי עבור אובייקט נתון. מספר שלם זה משמש לקביעת מיקומו של אובייקט כאשר אובייקט זה צריך להיות מאוחסן, למשל ל HashTable. כברירת מחדל, hashCode()מחזירה integerייצוג של הכתובת של מיקום הזיכרון שבו האובייקט מאוחסן. השיטה equls(), כפי ששמה מרמז, משמשת פשוט כדי לבדוק אם שני אובייקטים שווים. יישום ברירת המחדל בודק הפניות לאובייקט כדי לראות אם הם שווים. להלן הנחיות חשובות לטעינה מחדש של שיטות אלה:
  1. השתמש תמיד באותן תכונות אובייקט בעת יצירת hashCode()ו- equals();
  2. סִימֶטרִיָה. הָהֵן. xאם הוא מחזיר true עבור אובייקטים מסוימים y x.equals(y), אז הוא y.equals(x)אמור להחזיר true;
  3. רפלקסיביות. שכן כל אובייקט x x.equals(x)חייב להחזיר true;
  4. עֲקֵבִיוּת. עבור כל אובייקט xומחזיר y x.equals(y)את אותו הדבר אם המידע המשמש בהשוואות אינו משתנה;
  5. טרנזיטיביות. עבור אובייקטים כלשהם x, yואם zהוא x.equals(y)מחזיר true y.equals(z)ומחזיר true, אז הוא x.equals(z)צריך להחזיר true;
  6. בכל פעם שמתודה נקראת על אותו אובייקט במהלך הפעלת היישום, היא צריכה להחזיר את אותו המספר אלא אם כן המידע המשמש משתנה. hashCodeיכול להחזיר ערכים שונים עבור אובייקטים זהים במקרי יישומים שונים;
  7. אם שני אובייקטים שווים, לפי equals, אז hashCodeעליהם להחזיר את אותם ערכים;
  8. הדרישה ההפוכה היא אופציונלית. שני אובייקטים לא שווים יכולים להחזיר את אותו hashCode. עם זאת, כדי לשפר את הביצועים, עדיף שאובייקטים שונים יחזירו קודים שונים.
קרא עובדות מעניינות על שיטות אלה כאן.

ספר לנו על משנה גישה

למחלקות, שדות, בנאים ושיטות של Java יכול להיות אחד מארבעה משנה גישה שונים: פרטי אם שיטה או משתנה מסומנים פרטיים , אז רק קוד בתוך אותה מחלקה יכול לגשת למשתנה, או לקרוא לשיטה. קוד בתוך מחלקות משנה לא יכול לגשת למשתנה או שיטה, וגם לא יכול לגשת אליו מכל מחלקה אחרת. לרוב נעשה שימוש במשנה הגישה הפרטית עבור בנאים, שיטות ומשתנים. ברירת מחדל שינוי הגישה המוגדר כברירת מחדל מוצהר אם השינוי אינו צוין כלל. פירושו של שינוי זה הוא שניתן לקבל גישה לשדות, לבנאים ולשיטות של מחלקה נתונה על ידי קוד בתוך המחלקה עצמה, קוד בתוך מחלקות באותה חבילה. תת-מחלקות אינן יכולות לגשת לשיטות ומשתני איברים של מחלקת-על אם הם מוכרזים כברירת מחדל , אלא אם תת-המחלקה נמצאת באותה חבילה כמו מחלקת העל. protected השינוי המוגן פועל כמו ברירת המחדל , פרט לכך שתת-מחלקות יכולות גם לגשת לשיטות ולמשתנים מוגנות של מחלקת העל. הצהרה זו נכונה גם אם תת המחלקה אינה באותה חבילה כמו מחלקת העל. public פירושו של שינוי הגישה הציבורי הוא שכל הקוד יכול לגשת למחלקה, למשתנים, לבנאים או לשיטות שלה, ללא קשר למקום הקוד הזה. Java Core.  שאלות לראיון, חלק 3 - 2

מהו אספן אשפה? אפשר להתקשר אליו?

איסוף זבל הוא תכונה של ניהול זיכרון אוטומטי בשפות תכנות מודרניות רבות, כגון Java ושפות ב-NET.Framework. שפות המשתמשות באיסוף אשפה מפרשות לעתים קרובות איסוף אשפה במכונה וירטואלית כגון JVM. לאיסוף אשפה יש שתי מטרות: יש לשחרר כל זיכרון שאינו בשימוש, ואסור לשחרר זיכרון אם התוכנה עדיין משתמשת בו. האם אתה יכול להפעיל את איסוף האשפה באופן ידני? לא, System.gc()זה נותן לך כמה שיותר גישה. האפשרות הטובה ביותר היא לקרוא לשיטה System.gc(), שתרמז לאספן האשפה שהיא צריכה לפעול. אין דרך להפעיל אותו באופן מיידי מכיוון שאוסף האשפה אינו דטרמיניסטי. בנוסף, לפי התיעוד, OutOfMemoryErrorהוא לא יועבר אם המכונה הוירטואלית לא הצליחה לפנות זיכרון לאחר איסוף אשפה מלא. למידע נוסף על אספן אשפה כאן.

מה המשמעות של מילת המפתח המקורית? הסבר בפירוט

מילת המפתח המקורית משמשת כדי לציין שהשיטה מיושמת בשפת תכנות שאינה קובץ Java. בעבר נעשה שימוש בשיטות מקומיות . בגירסאות הנוכחיות של ג'אווה זה נחוץ בתדירות נמוכה יותר. נכון לעכשיו, יש צורך בשיטות מקוריות כאשר:
  1. עליך להתקשר לספרייה מג'אווה שכתובה בשפה אחרת.
  2. אתה צריך גישה למשאבי מערכת או חומרה שניתן לגשת אליהם רק באמצעות שפה אחרת (בדרך כלל C). למעשה, ניתן לקרוא לפונקציות מערכת רבות המקיימות אינטראקציה עם המחשב האמיתי (כגון דיסקים או נתוני רשת) רק בשיטה המקורית.
החסרונות של שימוש בספריות שיטה מקוריות הם גם משמעותיים:
  1. JNI/JNA יכול לערער את היציבות של ה-JVM, במיוחד אם אתה מנסה לעשות משהו מורכב. אם השיטה המקורית שלך עושה משהו לא בסדר, קיימת אפשרות שה-JVM קורס. כמו כן, דברים רעים יכולים לקרות אם השיטה המקורית שלך נקראת ממספר שרשורים. וכולי.
  2. קשה יותר לנפות באגים בתוכנית עם קוד מקורי .
  3. קוד מקורי דורש בנייה נפרדת של מסגרות, מה שעלול ליצור בעיות עם העברה לפלטפורמות אחרות.

מהי סדרה?

במדעי המחשב, בהקשר של אחסון ושידור נתונים, סדרה היא תהליך של תרגום מבנה נתונים או מצב של אובייקט לפורמט שניתן לאחסן ולאחזר מאוחר יותר בסביבת מחשוב אחרת. לאחר קבלת סדרה של ביטים, הם מחושבים מחדש לפי פורמט הסידרה, וניתן להשתמש בהם כדי ליצור שיבוט זהה מבחינה סמנטית של האובייקט המקורי. Java מספקת סדרה אוטומטית, הדורשת מהאובייקט ליישם את הממשק java.io.Serializable. יישום הממשק מסמן את המחלקה כ"ניתנת להמשכה". לממשק java.io.Serializable אין שיטות סריאליזציה, אך המחלקה הניתנת להמשכה יכולה להגדיר אופציונליות שיטות שייקראו כחלק מתהליך הסדרת/דיסריאליזציה. בעת ביצוע שינויים במחלקות, עליך לשקול אילו מהן יתאימו ולא יהיו תואמות לסריאליזציה. אתה יכול לקרוא את ההוראות המלאות כאן. אני אתן את הנקודות החשובות ביותר: שינויים לא תואמים:
  1. מחק שדה;
  2. העבר מחלקה למעלה או למטה בהיררכיה;
  3. שינוי שדה לא סטטי לסטטי או לא חולף לחולף;
  4. שינוי סוג הנתונים הפרימיטיבי המוצהר;
  5. שינוי השיטה WriteObjectכך ReadObjectשהם לא כותבים או קוראים שדות כברירת מחדל;
  6. שינוי מעמד Serializableאו Externalizableלהיפך;
  7. שינוי מחלקת enum ל- non-enum או להיפך;
  8. הסרה Serializableאו Externalizable;
  9. הוספת writeReplaceשיטה readResolveלמחלקה.
שינויים תואמים:
  1. הוספת שדות;
  2. הוספה/הסרה של שיעורים;
  3. הוספת שיטות WriteObject/ReadObject[שיטות defaultReadObjectאו defaultWriteObjectחייב להיקרא בהתחלה];
  4. הסרת שיטות WriteObject/ReadObject;
  5. חיבור java.io.Serializable;
  6. שינוי גישה לשדה;
  7. שינוי שדה סטטי ללא סטטי או חולף ללא חולף .
קישורים לחלקים קודמים: Java Core. שאלות ראיון, חלק 1 Java Core. שאלות ראיון, חלק ב' מאמר מקורי לימודים שמחים!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION