שלום לכולם,
פוסט ראשון אז אתחיל במילה וחצי על עצמי. MVP בתחום מדיה דיגיטלית, מרצה מוסמך של WinCE 6, ספר Expert one on one Visual C++ שעוד לא יצא מתוך עצלנות לעשות review על ה- 600 עמודים שקיימים. סטארט אפ בתחום ניהול רשת, ונסיון בפיתוח של חומרה ותוכנה.
עוד קצת עלי: http://www.facebook.com/profile.php?id=524097405
לא היה לי הרבה זמן לכתוב עד עכשיו. תקופה לחוצה עם הרבה דברים במקביל ובעיקר כשחודש הבא יש שבוע חגים, שבוע TechED ושבוע בסיאטל עם צוותי הפיתוח. על כל אלה צריך להוסיף שבוע מילואים שהיה שבוע שעבר.. הכל חוויות.
ואם בחוויות עסקינן, העלתי תמונות מהמילואים ל- facebook. לא משהוא סוויג (המצאתי עכשיו - שניתן לסיווג בטחוני). במסגרת החוויה המעניינת היינו צריכים להזכר איך מקפלים אוהל של נגמ"ש. למי שמסתקרן התשובה היתה חצי - רבע - שמינית ואז לגלגל על הנגמ"ש. כשהמשפט הזה נאמר הגעתי לתובנה מעניינת. חצי - רבע - שמינית זאת הדרך המתמטית לתאר את הפתרון, זה התיאור הטכנולוגי של הפתרון לבעיה. אפשר לומר שזהו התיאור האקדמי של הפתרון. מנגד קיים התיאור הפרקטי שהוא חצי - חצי - חצי, כיוון שבכל פעם שאתה מקפל אתה מקפל את מה שמולך לחצי.
תובנה מעניינת. אני זוכר קורס בנושא שימושיות (usability - איך לתכן מוצר שיהיה שמיש). בקורס הוזכר מספר פעמים העקרון שאומר ש-'מצב' או state של האפליקציה חייב להיות ברור למשתמש ואמור להשתקף ב- GUI. לדוגמא מקש Enter משמש אותי כדי לרדת לשורה חדשה, וכשאני בתפריט אותו המקש בדיוק משמש אותי לבחירה. אלו הם שני מצבים שונים של התוכנה: מצב עריכה ומצב פקודה. למעשה כל תפריט הוא מצב שונה כיוון שבתפריט File לחיצה על A תבצע Save As ובתפריט Edit לחיצה על אותו המקש תבצע Select All.
כאשר אנחנו אומרים למי שמקפל אוהל חצי - רבע - שמינית הוא חייב לזכור את המצב של האוהל אולם המצב הזה לא לגמרי ברור לעין. קשה לי לזהות שאני כרגע מקפל אוהל שכבר נמצא ברבע מהגודל המלא שלו. לעומת זאת לקבל לחצי 3 פעמים הרבה יותר קל.
במילים אחרות הרבה יותר קל לבצע עבודה שלא צריך לזכור בה מצבים.
אם לחזור לעולם התכנות (כן, לחזור.. ) אז קשה לנו מאד לראות מצבים והרבה מאד פעמים אנחנו לא בודקים אותם. הנה דוגמא למצב שהרבה פעמים לא בודקים:
משתנה מסוג מצביע ב- C/++ או אובייקט nullable ב- C#. יש לו שני מצבים בסיסיים: בראשון יש לו תוכן או הוא מצביע אל אובייקט, ובשני הוא NULL ואינו מצביע על אובייקט. לא תמיד מתכנתים מודעים למצבים האלה או מתייחסים אליהם. אם לחזור למשפט החצאים אז הדבר שקול לקיפול אוהל מתוך הנחה שהוא אינו מקופל מבלי לוודא.
למען האמת יש הרבה יותר מצבים למשתנה כזה למשל כשהוא מצביע על אובייקט מסוגו, מסוג שיורש ממנו, על אובייקט מסוג אחר (ושגוי) וכד'.
הבעיה עם כל המצבים האלה היא שהם מתקיימים בזמן ריצה ולא בזמן הקידוד.
שפות התכנות כבר מזמן התייאשו מהמתכנתים ולכן כל התנהגות שעלולה להעיד על שימוש לא מתאים תחת מצב מסויים גוררת מיד Exception. למשל בשפת C++ הקצאת זכרון אף פעם לא מחזירה NULL כיוון שנזרק Exception לפני כן. גם המרות למיניהן, שימוש באובייקטים מסוג לא נכון ב- C# וכן הלאה.
סוג אחר של 'מצב' או state הוא משתנים גלובליים. משתנה גלובלי הוא State של האפליקציה כולה ולכן מומלץ מאד שלא להשתמש בהם כיוון שבסופו של דבר יבוא המתכנת שיתעלם מאותו המצב או ישתמש בו לא נכון.
מצבים דורשים ניהול. במקרה של אובייקטים ומצביעים צריך לנהל את האפשרויות הקיימות (בדיקת NULL וכד') והדרך של שפות התכנות לחייב את זה היא על ידי שימוש ב- Exception-ים שמאלצים אותנו לנהל את המצבים אחרת הקוד קורס.
במקרה של משתנים גלובליים משתמשים באובייקט שמנהל את המשאב המשותף - המשתנה הגלובלי. קיימים פאטרנים רבים דוגמת Singleton וכד' שתפקידם ניהול אובייקטים גלובליים.
עכשיו אני מגיע לבעיה:
לאפליקציה יש מחסנית - stack שמשוייכת ל- thread הראשי. תפקידה של ה- stack הוא לייצר scope לכל מקטע של קוד. במילים אחרות יש רק state אחד והוא מתחיל בתחילת הפונקציה. כל מה שהיה קיים לפני כן מוסתר. בסיום הפונקציה חוזרים ל- state של הפונקציה המוסתרת. באופן זה כל פונקציה פועלת עצמאית ואינה תלויה בפונקציה שקראה לה.
הבעיה היא שכאשר יש מספר thread-ים באפליקציה יש מספר state-ים שונים בו זמנית. והכל נהיה בעייתי.
הפתרונות שלנו היום הם להוסיף שימוש ב- Critical Section וב- MUTEX שהם בעצמם אובייקטים גלובליים שדורשים ניהול ובכך אנחנו רק מעלים את הסיבוכיות של המערכת ואת הסיכון לשגיאות כי בסופו של דבר יבוא המתכנת שיתעלם מה- state של האובייקטים האלה... אולי אפילו אני כשאני עייף מספיק...
הפתרון הוא בשינוי תפיסה של עולם המושגים שלנו היום.
אם הצלחנו להבין את הבעיה אז עשינו חצי דרך אל הפתרון. (נשארו רק חצי - חצי , לגלגל ולקשור)
הרשו לי להפתיע אתכם בהרצאה שלי ב- TechEd בשם "Multiprocessing and the .Net Parallel Extensions"
עד אז תוכלו לבקר באתר שהקמתי לנושא: http://AsyncOp.com
בברכה,
אסף