או: מה עושים כשמרטיבים את הידיים והתלמידים מגלים שהמים קצת ג'יפה.
את המחשבות שלנו על יצירת המוק נתחיל מליישם על פרק נבחר כהוכחת היתכנות למודל כולו. במקרה שלנו, בחרנו את פרק 3, שעוסק במבני נתונים.
בזמן בניית הסילבוס, התרגילים שירתו את הפרק ונועדו לתרגל אותו, אבל שם סדר המעמדות הזה הסתיים: ברמת תכנון החומר המדויק, אנחנו חושבים על הפרק כמשרת את התרגיל. חומר שלא יתורגל יישכח, וכמובן שחומר שנדרש לתרגיל אבל חסר יהפוך אותו למתסכל (קרי: סוף היחסים בין הצופה והקורס). עם זאת, בפלטפורמה הזו אנחנו אוהבים לחשוב שאנחנו יכולים להרשות לעצמנו (ואף מצופים) לשמור על רמת תרגילים גבוהה מבלי להימנע מסוגיות עומק, ותרגיל 3 הוא דוגמה טובה לכך.
מי שלא מתעניין בסוגיות טכניות, מוזמן לקפוץ ל-***.
בזמן שהפרק עוסק במבני הנתונים עצמם, התרגיל מתקשר גם לתחום הנפרד של תזמון מיקרו-פעולות, חלקן אורכות כ-10 מליארדיות השניה. זה דבר שצריך לעשות בזהירות בכל הקשר: להקטין ככל הניתן את העומס על מערכת ההפעלה כדי להקטין שונות בין בדיקות, לבחור את מספר האיטרציות, ולקחת בחשבון את תקורת החישוב. זה מורכב עוד יותר בג'אווה, שמבוססת על מודל ה-hotspot compilation. המודל מניח שבתכנית אופיינית יש חלק קטן יחסית מהקוד שמהווה הרבה מזמן הריצה בפועל. בזמן שלא משתלם לקמפל מראש את כל ה-bytecode לשפת מכונה אלא לעשות לרובו אינטרפרטציה, ה-JVM עושה שימוש נרחב ב-JIT (just-in-time) Compiler שמקמפל בזמן ריצה חלקים נבחרים מהקוד לכדי שיפור הביצועים בסדרי גודל. אבל בשביל לדעת איזה חלקים, ולאיזה קוד מכונה בדיוק אופטימלי לקמפל אותם, ה-JVM צריך ללמוד את דפוסי הריצה של קטע הקוד שחוזר על עצמו. לעתים הוא אף מקמפל חלק קוד בצורה ראשונית, ואז מקמפל אותו שוב פעם שניה או שלישית, כאשר קיבל מושג טוב יותר על קוד המכונה המדויק שקטע הקוד המסוים מריץ באופן אופייני. בהקשר של תזמון, ראוי לקחת בחשבון את פעולת ה-JIT Compiler - הוא משפיע על זמן הריצה של הקוד שאנחנו מריצים בעודו רץ, ולא ניתן אפילו לכבות אותו, כי מה נמדוד אז? מעניין אותנו זמן הריצה של קוד כפי שהיה רץ בתכנית אופיינית, ולא במצב בו תוקעים לג'אווה מקלות בגלגלים כדי לעשות לה דווקא.
***
עבור תלמידים בשבוע השלישי לקורס, אלה הרבה פרטים על סוגיות שהם לא מבינים עד הסוף אפילו בפשט: מה זה אינטרפרטציה לעומת קומפילציה? אמרתם פעם משהו על bytecode, זה זה שכולל 8 ביטים נכון? מה זה JVM? איך ואיפה רצים כל הקימפולים האלה שמתרחשים במקביל להרצת התכנית? ובכל זאת, עבור מהנדסי תכנה לעתיד, אין לנו רצון לוותר על תרגיל רק מפני שהוא נהיה טכני ברגע שהולכים מהתיאוריה למעשה; "בעולם האמיתי" של תכנות יש מעט מאוד מקרים שלא הופכים למאוד טכנים, מאוד מהר, כשמרטיבים את הידיים. יש מי שימצא את זה מסקרן ויימשך לכך, ויש מי שיידחה ויחליט שתכנות רציני זה לא בשבילו (ויברח just in time). עם כל זאת: כבר בשבוע השלישי?
כנראה שדרך המלך כאן תהיה להזכיר את הנושא, גם אם מאוד בקצרה, ולהדריך את התלמידים מה לעשות כדי להיתקל בכמה שפחות artifacts בתזמונים שלהם. בזמן שלא ניתן לצפות מהם להתמודד עם האתגר בעצמם, כן אפשר ליידע אותם על JIT compilation באופן כללי ואיך אפשר להתמודד איתו. לעזרתנו בא פרק ה-Java Stream שמציג מתכנת כותב קוד תוך שהוא עונה לשאלות "בזמן אמת". בקלות ניתן לשתול בו שאלות מנחות שחורגות מהנושא ונכנסות לאמירות סוגריים. גם "טיפים מצביקה" מאפשר לנו לזרוק הערות שיכינו אותם קוגניטיבית למורכבות מסוימת שהולכת לעלות בתרגיל.
לסיכום: סוגיית הדיסוננס בין הצורך בפשטנות והרצון בעומק (או להיפך?) משותפת כמעט לכל קורס אקדמי שעובר ל-MOOC. הדיסוננס מתווסף לקושי אינטגרלי ב-MOOC באשר הוא: בזמן פתרון התרגיל, כמעט אין לתלמידים מענה. על ידי הקפדת יתר על הליכה אחורה מהתרגיל אל השיעור, ננסה להקטין את חוסר האונים של התלמיד בזמן ביצוע התרגיל, תוך שאנחנו שומרים עליו ברמה גבוהה. רק לאחר הכנת התרגיל (דבר שאני במהלכו), ניגש להכנת תסריט הפרק.
Comments