CodeGym /בלוג Java /Random-HE /בחינת שאלות ותשובות מראיון עבודה למשרת מפתח Java. חלק 6
John Squirrels
רָמָה
San Francisco

בחינת שאלות ותשובות מראיון עבודה למשרת מפתח Java. חלק 6

פורסם בקבוצה
שלום עולם! זה חיוני לכל מפתח שלא יפסיק לצמוח. אחרי הכל, אם תפסיק, אתה מסתכן בנפילה מביקוש וליפול לגמרי משוק העבודה. עולם ה-IT מתפתח כל הזמן ומתקדם - אתה צריך להתקדם איתו. אבל יחד עם זאת, אתה לא יכול פשוט תמיד להסתובב בטכנולוגיות החדישות ביותר שמא תשכח את ה"קלאסיקות" (נושאים קלאסיים לפיתוח תוכנה). היום אני רוצה להמשיך את הדיון שלי ב"נושאים קלאסיים" למפתחי Java. בחינת שאלות ותשובות מראיון עבודה למשרת מפתח Java.  חלק 6 - 1אציין שהתשובות שלי אינן המילה האחרונה. הם רק השקפתי לגבי התשובות הנכונות - אולי אתה לא מסכים עם חלק מהן. זה בסדר גמור, אז אל תהסס לשתף את דעתך בתגובות. תוכל למצוא קישורים לחלקים הקודמים של הסקירה בסוף המאמר. בחינת שאלות ותשובות מראיון עבודה למשרת מפתח Java.  חלק 6 - 2

ספריות ותקנים

52. מה זה Hibernate? מה ההבדל בין JPA לבין Hibernate?

כדי לענות על השאלה הזו, אני חושב שאנחנו צריכים קודם כל להבין מה זה JPA. זהו מפרט המתאר מיפוי יחסי אובייקט של אובייקטי Java פשוטים ומספק API לאחסון, אחזור ותפעול אובייקטים כאלה. כלומר, מסדי נתונים יחסיים (DBs) מיוצגים כקבוצה של טבלאות מחוברות. ו-JPA הוא תקן מאומץ נרחב שמתאר כיצד אובייקטים יכולים לקיים אינטראקציה עם מסדי נתונים יחסיים. כפי שאתה יכול לראות, JPA הוא משהו מופשט ובלתי מוחשי. זה כמו הרעיון עצמו, הגישה. בחינת שאלות ותשובות מראיון עבודה למשרת מפתח Java.  חלק 6 - 3אבל Hibernate היא ספרייה ספציפית המיישמת פרדיגמות של JPA. במילים סדר, אתה יכול להשתמש בספרייה זו כדי לעבוד עם מסד נתונים יחסי באמצעות אובייקטים המייצגים נתונים במסד הנתונים (Entity). אומרים שהספרייה הזו קרובה מאוד לאידיאלים של ה-JPA. אולי בגלל זה זה הפך פופולרי. כפי שאתה יכול לדמיין, הפופולריות שלו הצדיקה פיתוח ושיפורים נוספים. בנוסף, השימוש הנרחב נובע מקהילה עצומה שכבר חקרה כל שאלה אפשרית ובלתי אפשרית הקשורה לכלי זה. Hibernate נחקר ביסודיות, וכפי שמתברר, הוא אמין. יש סיבה טובה לכך שאפילו היישום האידיאלי של JPA באביב משתמש בדרך כלל במצב Hibernate מתחת למכסה המנוע.

53. מה זה מדורג? איך משתמשים בו במצב Hibernate?

כפי שאמרתי קודם, תקשורת במצב Hibernate מתרחשת באמצעות אובייקטי נתונים הנקראים ישויות. ישויות אלו מייצגות טבלאות ספציפיות במסד הנתונים, וכפי שאתם זוכרים, מחלקות Java יכולות להכיל הפניות למחלקות אחרות. קשרים אלו באים לידי ביטוי גם במסד הנתונים. ככלל, הם מפתחות זרים (עבור קשרי גומלין של OneToOne, OneToMany, ManyToOne) או טבלאות ביניים (עבור קשרי גומלין של ManyToMany). כאשר לישות שלך יש הפניות לישויות קשורות אחרות, הערות ממוקמות מעל הפניות אלה כדי לציין את סוג הקשר: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany. אתה יכול לציין את סוג המפל עבור קשר זה במאפיין המפל של ההערות. ל-JPA יש שיטות ספציפיות לאינטראקציה עם ישויות (להתמיד, לשמור, להתמזג...). סוגי אשד משמשים כדי להראות כיצד נתונים קשורים צריכים להתנהג; שיטות אלה משמשות על ישות יעד. אז מהן אסטרטגיות המדרגות (סוגי אשד)? תקן JPA מספק שימוש בשישה סוגי מפל:
  • PERSIST - פעולות השמירה מתרחשות במפל (עבור המתודות save() ו- persist() ). במילים אחרות, אם אנחנו שומרים ישות שמשויכת לישויות אחרות, אז הישויות האלה נשמרות גם במסד הנתונים (אם הן לא כבר שם)

  • MERGE - פעולות עדכון מתרחשות במפל (עבור שיטת המיזוג() )

  • REMOVE - פעולות המחיקה מתרחשות במפל ( שיטת remove() )

  • ALL — מכיל שלוש פעולות מדורגות בבת אחת — PERSISTMERGEREMOVE

ל-JPA יש את הרעיון של ישות מתמשכת - ישות הקשורה לנתונים שלה במסד הנתונים ונשלטת על ידי הפגישה הנוכחית (חיבור). אם תשנה אותו מבלי לשמור את השינויים במסד הנתונים, נתוני הישות במסד הנתונים עדיין ישתנו.
  • DETACH - ישויות קשורות אינן מנוהלות על ידי ההפעלה ( שיטת detach() ). כלומר, כאשר הנתונים של הגופים הקשורים משתנים, הנתונים במסד הנתונים אינם מתעדכנים אוטומטית - הם מומרים מתמיד למנותק (כלומר, הישות אינה מנוהלת על ידי JPA)

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

בחינת שאלות ותשובות מראיון עבודה למשרת מפתח Java.  חלק 6 - 4Hibernate תומך בכל פעולות המדורגות הסטנדרטיות הללו ומציג גם שלוש משלה:
  • REPLICATE - משמש כאשר יש לנו יותר ממקור נתונים אחד ואנו רוצים שהנתונים יסונכרנו (שיטת השכפול של Hibernate). לכל הישויות חייבות להיות מזהים (מזהה) כדי להבטיח שניתן ליצור אותן ללא בעיות (כדי להבטיח שלאותה ישות אין מזהים שונים עבור מסדי נתונים שונים)

  • SAVE_UPDATE - שמירה/מחיקה מדורגת (עבור שיטת saveOrUpdate של Hibernate)

  • LOCK - ההפך מפעולת DETACHED : ממירה ישות מנותקת חזרה למצב מתמשך, כלומר, ההפעלה הנוכחית תעקוב אחר הישות שוב

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

54. האם מחלקת ישות יכולה להיות מופשטת?

לפי 2.1 מחלקת הישות של מפרט JPA , " מחלקות מופשטות וגם מחלקות קונקרטיות יכולות להיות ישויות. " לכן, התשובה היא כן, מחלקה מופשטת יכולה להיות ישות וניתן לסמן אותה עם ההערה @Entity.

55. מהו מנהל ישות? על מה זה אחראי?

קודם כל, אני רוצה לציין ש- EntityManager הוא מרכיב מכריע ב- JPA . הוא משמש לאינטראקציה של ישויות עם מסד הנתונים. באופן כללי, שיטות לאינטראקציה של הישות עם מסד הנתונים נקראות על הישות (persist, merge, remove, detach)... אבל אני גם מציין שרכיב זה לרוב אינו יחיד עבור האפליקציה כולה. לעתים קרובות הוא קל משקל, אחד נמחק, ואחד חדש נוצר באמצעות EntityManagerFactory . אם נצייר הקבלה ל- JDBC , שבו EntityManagerFactory הוא אנלוגי ל- DataSource , אז EntityManager הוא אנלוגי ל- Connection . קודם לכן, ציינתי שישות מתמשכת היא ישות המנוהלת על ידי החיבור הנוכחי. ישות זו מנוהלת על ידי EntityManager , אשר קשור קשר הדוק לחיבור הנוכחי, ו- TransactionManager , אשר אחראי על פתיחת/סגירת עסקאות. באיור למטה, ניתן לראות את מחזור החיים של הישות: בחינת שאלות ותשובות מראיון עבודה למשרת מפתח Java.  חלק 6 - 5ה- EntityManager מנהל את הישות כאשר היא בשלב המנוהל (כאשר היא מתמשכת, מכיוון שיש לה קשר עם ה- EntityManager ). כלומר, זה לא חדש וגם לא הוסר. כאשר ישות חדשה או הוסרה, אנו יכולים לומר שהיא גם מנותקת, כי ה- EntityManager לא מנהל אותה. ישנן אסטרטגיות שונות עבור EntityManager . אתה יכול לקבל יחידת EntityManager עבור כל האפליקציה או ליצור אחד חדש בכל פעם עבור כל חיבור. אם אתה משתמש ב-Spring, היצירה/מחיקה של EntityManager מנוהלת אוטומטית מתחת למכסה המנוע (אבל זה לא אומר שאתה לא יכול להתאים אותו לעצמך ^^). אני צריך להזכיר ש-EntityManagers אחד או יותר יוצרים הקשר התמדה . Consistence context הוא סביבה שבה מופעים של ישויות מסונכרנים עם ישויות דומות במסד הנתונים (כפי שאמרתי, זה עובד רק עבור ישויות מתמשכות). אם תעמיקו ב- JPA (שאני ממליץ בחום), תיתקלו במושג הזה לעיתים קרובות מאוד.

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

לא שמעתי על מחלקה כזו ב- JPA , אז אניח שהשאלה הזו מתייחסת למחלקה שנמצאת בספריית JUnit המשמשת למבחני יחידות. בספרייה זו, המחלקה Assert משמשת לבדיקת התוצאות של ביצוע קוד (כאן assert פירושו קביעה שיש לך מצב/נתונים ספציפיים במיקום ספציפי בקוד). לדוגמה, נניח שאתה בודק שיטה שאמורה ליצור חתול. אתה מפעיל את השיטה ומקבל תוצאה כלשהי:
Cat resultOfTest = createCat();
אבל אתה צריך לוודא שהוא נוצר בצורה נכונה, נכון? אז אתה יוצר ידנית חתול ספציפי ( expectCat ) עם בדיוק הפרמטרים שאתה מצפה לראות בחתול המתקבל בשיטת createCat() . לאחר מכן אתה משתמש במחלקה Assert כדי לאמת את התוצאות:
Assert.assertEquals(resultOfTest, expectedCat);
אם החתולים שונים, אזי תזרק AssertionError , שאומרת לנו שלא קיבלנו את התוצאות הצפויות. למחלקה Assert יש שיטות רבות ושונות המכסות מגוון פעולות המסייעות באימות התוצאות הצפויות. הנה כמה מהם:
  • assertTrue(<boolean>) - הערך המועבר כארגומנט צפוי להיות נכון

  • assertFalse(<boolean>) - הערך המועבר כארגומנט צפוי להיות שקר

  • assertNotEquals(<object1>, <object2>) - האובייקטים המועברים כארגומנטים חייבים להיות שונים בהשוואה באמצעות שווים ( false )

  • assertThrows(<ClassNameOfException>.class, <exceptionObject>) - הארגומנט השני צפוי להיות חריג שנזרק על ידי הארגומנט הראשון (כלומר הארגומנט השני הוא בדרך כלל קריאת מתודה שאמורה לזרוק חריג מהסוג הנדרש)

חוּט

57. תאר את מחלקת ה-String של Java

מחרוזת היא מחלקה סטנדרטית של ג'אווה האחראית על אחסון ומניפולציה של ערכי מחרוזת (רצפים של תווים). זהו מחלקה בלתי ניתנת לשינוי (כתבתי על immutable בעבר כאן ), כלומר, לא ניתן לשנות את הנתונים של אובייקטים של מחלקה זו לאחר יצירתם. ברצוני לציין מיד שהמחלקות StringBuilder ו- StringBuffer זהות במהותן - ההבדל היחיד הוא שאחת מהן מיועדת לשימוש בסביבה מרובת הליכים ( StringBuffer ). מחלקות אלו דומות למחרוזת , אך שונות בכך שהן ניתנות לשינוי . גם לאחר שהם נוצרו, הם מאפשרים לך לשנות את המחרוזות שהם מייצגים, מבלי ליצור אובייקט חדש. השיטות שלהם שונות משיטות ה-String הסטנדרטיות והן מיועדות למניפולציה של מחרוזות (יש סיבה שהם קוראים לזה בונה).

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

הדרך הנפוצה ביותר ליצור מחרוזת היא לציין את הערך שאנו רוצים במרכאות כפולות בפשטות:
String str = "Hello World!";
אתה יכול גם לעשות זאת במפורש באמצעות חדש :
String str = new String("Hello World!");
אתה יכול גם ליצור מחרוזת ממערך של תווים:
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
נוכל לעשות זאת על ידי קריאה למתודה toString על אובייקט כלשהו:
String str = someObject.toString();
נוכל לעשות זאת על ידי קריאה לכל שיטה אחרת שמחזירה מחרוזת. דוגמא:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine();
אתה מבין שיכולות להיות הרבה מאוד דרכים ליצור מחרוזת. כאשר אובייקט String נוצר, הוא מאוחסן במאגר מחרוזות , שעליו נדון ביתר פירוט באחת השאלות שלהלן.

59. איך משווים בין שתי מחרוזות Java, ואיך ממיינים אותן?

Java משתמשת בסימן שווה כפול ( == ) כדי לבצע השוואות. אם אנחנו צריכים להשוות ערכים פשוטים כמו ints, נשתמש בזה. אבל שיטה זו אינה מתאימה להשוואת אובייקטים מן המניין. זה ישווה רק הפניות, כלומר אם ההפניות מצביעות על אותו אובייקט או לא. זה אומר שאם נשווה שני אובייקטים עם אותם ערכי שדה באמצעות == , נקבל false . לשדות יש אותם ערכים, אבל האובייקטים עצמם תופסים מיקומים שונים בזיכרון. חפצי מחרוזת , למרות פשטותם המתעתעת, הם עדיין חפצים. גם השוואה ביניהם באמצעות == אינה מתאימה (למרות נוכחותה של בריכת מיתר). הפתרון המתאים הוא שיטת ה-standard equals של מחלקת Object , אותה יש לעקוף כדי לעבוד כהלכה (כברירת מחדל, היא משתמשת ב -== לצורך השוואות). המחלקה String עוקפת אותו, אז אנחנו פשוט משתמשים ביישום שלה:
String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
בחינת שאלות ותשובות מראיון עבודה למשרת מפתח Java.  חלק 6 - 6דיברנו על השוואות לשוויון. כעת נבין השוואות למיון. אחרי הכל, אם אנחנו מתכוונים למיין משהו, אנחנו צריכים לדעת באיזה עיקרון נשתמש כדי למיין. לשם כך, אתה יכול להשתמש ב-TreeSet , סט ממוין סטנדרטי. מבנה נתונים זה מסתמך על אלגוריתם העץ האדום-שחור וממיין את הסט לפי עקרון מיון מוגדר. כפי שאמרתי קודם, אתה צריך להבין איך למיין אובייקטים מסוג מסוים. כדי להקצות את שיטת ההשוואה למיון, השתמש בהשוואות . אתה בדרך כלל צריך ליישם אותם עבור מחלקות שאתה רוצה למיין, אבל במקרה של String , הם כבר מיושמים. בהתאם לכך, אנו פשוט מוסיפים את המחרוזות שלנו ל- TreeSet , והוא ימיין אותם עבורנו:
TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
פלט מסוף:
א ב ג

60. ספק אלגוריתם להמרת מחרוזת לתווים. כתוב את הקוד המתאים

כפי שאמרתי קודם, לאובייקטי מחרוזת יש הרבה שיטות שימושיות שונות. אחד מהם הוא toCharArray . שיטה זו ממירה מחרוזת למערך תווים:
String str = "Hello world";
char[] charArr = str.toCharArray();
לאחר מכן, יש לנו מערך של תווים שנוכל להתייחס אליהם לפי אינדקס:
char firstChar = charArr[0]; // H

61. איך ממירים מחרוזת למערך בתים ובחזרה? כתוב את הקוד המתאים

למחלקה String יש מתודה getBytes , הדומה לשיטת toCharArray ומחזירה את המחרוזת כמערך בתים:
String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
הגענו למסקנה ההגיונית של הסקירה שלנו היום. תודה שקראת!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION