איך להסביר קוד בראיון בלי להקריא אותו
מהקלט והאילוצים, דרך בחירת מבנה הנתונים, ועד בדיקת נכונות וסיבוכיות. מדריך לתרגול בקול.
בזמן ראיון קל להתרכז כל כך בכתיבה, עד שהמראיין רואה רק אדם ששותק מול עורך. בקצה השני יש הסבר שמפרט כל תו ולא משאיר מקום לחשיבה. המטרה היא לתת חלון לתהליך קבלת ההחלטות: מה הבנתם, מה בחרתם לבדוק ואיך אתם יודעים שהפתרון עומד בדרישות.
הסבר טוב אינו דורש אוצר מילים מפואר. הוא דורש מבנה. אפשר לתרגל אותו גם לבד על פונקציה קצרה, ורצוי לעשות זאת לפני שמוסיפים לחץ של זמן או שאלות. אם אתם לא מצליחים להסביר פתרון מוכר, עוד עשר שאלות חדשות כנראה לא יטפלו בפער הזה.
מגדירים את החוזה לפני המימוש
נניח שמבקשים למצוא את הערך הראשון שמופיע פעמיים ברשימה. ״ראשון״ יכול להתייחס למיקום ההופעה הראשונה או לרגע שבו מזוהה ההופעה השנייה. ברשימה מסוימת אלה תשובות שונות. צריך להבהיר את המשמעות לפני שמתחילים לבחור מבנה נתונים.
שאלו גם אילו טיפוסי ערכים מתקבלים, מה מחזירים כשאין כפילות ומה מגבלת הזיכרון. לא כל שאלה תזכה לתשובה מפורטת. במקרה כזה הציעו הנחה מפורשת: ״אניח שהערכים ניתנים לגיבוב ושצריך את הכפילות הראשונה שמתגלה בסריקה״. כעת אפשר לבדוק את הפתרון ביחס לחוזה מוסכם.
מתחילים בפתרון פשוט ומזהים את העבודה החוזרת
אפשר להשוות כל ערך לכל הבאים אחריו. זה מסביר את הבעיה, אבל מבצע הרבה בדיקות. אם שומרים את הערכים שכבר ראינו, אפשר לבדוק כל ערך במהלך הסריקה. הסבירו איזה מידע נשמר ומדוע הוא מספיק, ולא רק ש־set הוא ״מהיר״.
def first_repeated(values):
seen = set()
for value in values:
if value in seen:
return value
seen.add(value)
return None
הדוגמה מניחה ערכים ניתנים לגיבוב, וש־None מתאים כסמן להיעדר תוצאה. אם None הוא ערך תקין בקלט וצריך להבחין בינו לבין היעדר תוצאה, נדרש חוזה אחר, למשל זוג של דגל וערך. זה פרט קטן שמראה שאתם בוחנים את ה־API ולא רק את הלולאה.
מסבירים מה נשאר נכון בכל שלב
לפני כל איטרציה, seen מכיל את הערכים שנראו קודם. אם הערך הנוכחי כבר שם, מצאנו כפילות לפי סדר הסריקה. אם לא, מוסיפים אותו כדי לשמר את אותה תכונה לאיטרציה הבאה. זהו הסבר נכונות קצר שלא תלוי בהקראת הקוד.
אפשר לעבור ידנית על דוגמה אחת, אבל היא אינה הוכחה לכל הקלטים. השתמשו בה כדי להמחיש את הטענה, ואז הסבירו למה המבנה נשמר. אם המראיין מציע מקרה קצה, שלבו אותו באותו ניתוח במקום לזנוח מיד את כל הפתרון.
סיבוכיות צריכה לציין הנחות
במימוש המבוסס על hash set, פעולות חיפוש והוספה הן בממוצע קבועות בתנאים המקובלים, ולכן הסריקה ממוצעת ליניארית במספר הערכים. הזיכרון הנוסף עשוי להיות ליניארי במספר הערכים הייחודיים. אל תציגו עלות ממוצעת כערבות גורפת לכל מבנה או קלט.
אם הזיכרון מוגבל, אפשר לבדוק חלופות. מיון עשוי לשנות את סדר הקלט, ולכן אינו מחליף ישירות את אותה דרישת ״ראשון״. בחירה בחלופה דורשת לבדוק שוב את החוזה. זאת בדיוק השיחה שמעניין לשמוע: מה הרווחתם ומה איבדתם.
בדיקות הן חלק מההסבר
בדקו רשימה ריקה, ערך יחיד, כל הערכים שונים וכפילות סמוכה. הוסיפו דוגמה שמבדילה בין שתי משמעויות המילה ״ראשון״. אלה בדיקות של הדרישה, לא רק של שורות הקוד. אם טיפוסים מעורבים אינם מותרים, ציינו זאת במקום להעמיד פנים שהפונקציה תומכת בהם.
הקפידו לומר מתי אתם מגלים בעיה. ״שמתי לב שהסמן שבחרתי מתנגש עם קלט חוקי״ עדיף על ניסיון להסתיר טעות. תיקון מנומק מראה שאתם יודעים לעבוד עם משוב ולחדד הגדרה.
תרגול של רבע שעה
הקליטו הסבר בלי להציג את הקוד. אחרי דקה, בדקו אם המאזין יודע מה הקלט, מה מחזירים ואיזה מידע נשמר. אחר כך הוסיפו את הקוד והסבירו רק החלטות שאינן ברורות מהמימוש.
לתרגול רחב יותר אפשר להיעזר בחוברת הג׳וניורים. ואם האתגר הוא דווקא לספר על מערכת שכבר בניתם, עברו למדריך על הצגת פרויקט Backend. בשני המקרים המיומנות דומה: לאפשר לאדם אחר לעקוב אחר החשיבה שלכם.
להפוך הבנה לתרגול.
עוד כלים ללמידה עצמאית, או ליווי אישי שעובד על האתגרים שלכם.
עוד כיוון למחשבה.
איך מציגים פרויקט Backend בלי ללכת לאיבוד בפרטים
מסגרת מעשית להצגת פרויקט: מהבעיה העסקית, דרך ההחלטות שלך, ועד לתוצאות ולשאלות העומק.
לקריאת המאמרראיון System Design: השאלות שכדאי לשאול לפני שמציירים
איך הופכים בקשה עמומה למערכת שאפשר לתכנן, בלי לבזבז את כל הראיון על איסוף דרישות.
לקריאת המאמרמה הופך Ownership ליותר מ״אני אחראי על השירות״
אחריות הנדסית נמדדת גם בהגדרת הבעיה, בתיאום, בתפעול ובהעברת הידע — לא רק בכמות המשימות שסוגרים.
לקריאת המאמר