יום שני, 7 בספטמבר 2009

אנחנו מתכנתים אחרת

בזמן הפיתוח אנו נגררים להשתמש במה שאנו מכירים, כאשר הזמן משחק גורם עיקרי וכל ניסיון לעצור לשנייה מוריד את הסיכוי להיות החלוצים בתחום או לעמוד בתנאי הזמן הקשים של הלקוח. אבל האם משתלם לרוץ או שניתן לעשות דברים גם אחרת?

אותו הירוק

לכל בנאדם יש אוטומט שמנחה אותו לעשות את המובן מאליו ברגע שיתבקש לעשות כך, אך אותו אוטומט הוא זה שגורר אותנו לפעמים לעשיית דברים מיותרים, או מורכבים בצורה מיותרת, כשהפתרון הפשוט מונח לנו מתחת לאף ומחכה שנשלוף אותו.

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

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

הכל עניין של הסתכלות

ההנחה שמה שמולנו לא מובן מאליו ושיכול להיות אחרת, מובילה אותנו לנושא היום, שעוסק בתכנות בצורה שונה.
לכאורה קיבלנו בעיה כלשהי, הפתרון שלנו עבורה אולי מובן מאליו, אבל בלי שבחנו אותה לעומק לא נוכל לתת את הפתרון הטוב ביותר עבור הבעיה.

דוגמה יפה לבעיה שכזאת היא תרגיל בו נתון לנו מערך דו מימדי, כלומר מערך בתוך מערך, כאשר בכל אחד מהם 2n איברים, וכאשר נבחר בערך מסוים בתוך המערך הדו מימדי נקבל מספר, שמציין את מיקומו של האיבר.
לדוגמה:
array[0][0]; // 1
array[0][1]; //2
array[0][2n-1]; //2n
array[2n-1][2n-1]; //4n^2
כעת משימתנו היא בעזרת קבלת מספר, למצוא את המפתחות של האיברים המתאימים ב-2 המערכים.
הפתרון הפשוט למשימה זאת הוא כמובן שימוש בלולאה לצורך זה:
for ( int i = 0; i < array.length; i++ )
for ( int n = 0; n < array[i].length; n++ )
if ( array[i][n] == myNumber )
return Array (i,n);
הפתרון דרש מאיתנו במקרה הקיצוני לעבור על כל אותם 4n^2 נתונים.

מקומות שהטבלה יפה להם

הפתרון של הלולאות הוא אפשרי, אבל לא יעיל במקרה הזה, ואם נקדיש טיפה מחשבה נוכל למצוא פתרון יעיל יותר.
כעת נחשוב על הנתונים בצורת טבלה:
  • המערך החיצוני מציין את השורות, כל איבר במערך זה הוא שורה בפני עצמה.
  • המערכים הפנימיים מציינים את התאים, כל איבר במערכים אלו מציין תא בתוך אותה שורה.
כעת נוכל לחשוב על פתרון יעיל הרבה יותר, כאשר נתייחס אל כל שורה כ-y, ואל כל תא בשורה כ-x, נוכל ליצור משוואות שיזהו את המקום ע"פ המספר אותו נקבל על פי העיקרון הבא:
  • מציאת X - מקומו של האיבר הפנימי הוא שארית של החילוק ב-2n (כמותה איברים בכל שורה), כלומר אנו נאתר את כמות האיברים שנותרים לנו אחרי פעולת החילוק, נשים לב כי המפתח הראשון הינו 0 ולכן נפחית את המספר שקיבלנו ב-1.
  • מציאת Y - לאחר שמצאנו את X נוכל לחסר אותו מהמספר שאת מיקומו אנחנו בודקים, דבר שייתן לנו מספר המתחלק ב-2n ללא שארית ומציין את המפתח של השורה בה אנו נמצאים, כאשר שוב נזכור כי המפתחות מתחילים מ-0, ולכן נצטרך להוסיף בתחילה ל-X את מה שהורדנו בשלב הקודם.
כעת נכתוב זאת בצורת משוואות:
// array[y][x] = myNumber;
int x = ( myNumber - 1 ) % 2n; // פעולת שארית
int y = ( myNumber - ( x + 1 ) ) / 2n;
כמה שהנכם רואים, הפתרון יעיל יותר, ואינו כולל כלל שימוש בלולאות.

בלי פאניקה

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

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

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

משדרגים את עצמינו

אנשים משדרגים את עצמם על ידי למידה, בתחומים כמו רפואה או מחשבים הטכנולוגיות משתנות מהר, וכל הזמן יש את הצורך ללמוד דברים חדשים, להכיר את המוצר החדש בשוק, וללמוד להשתמש בתכונות החדשות ביותר שיצאו.

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

דרך נוספת לחדש את עצמינו היא לעזוב את ה"אני" ולהתמקד במה שסביבך, או במילים אחרות, לא להתבייש להתייעץ עם אנשים.
לאנשים יש מגוון דעות, יש שמכנים את זה פלורליזם, אני מכנה את זה במילה "הזדמנות", כי זה פותח בפניך דלת לראות את הדברים כפי שהם רואים זאת, לשמוע מהניסיון שלהם בתחום בו הם עוסקים מה דעתם על הפתרון המתאים עבורך, ואפילו ללמוד מההתנהלות שלהם ומהצורה בה הם חושבים.
אנשים אחרים גם יוכלו להצביע על נקודות שפספסת או על בעיות עליהן לא היית עולה על לשלב של הכתיבה או הרצת הקוד, בשלב בו לגלות שיש בעיה לוגית בפתרון יגזול ממך זמן יקר.

הקופסה של ההחלטות החשובות

שאלה נוספת שעולה בפנינו היא השאלה "האם אני צריך להחליט את זה כבר עכשיו?", ואנחנו צריכים לשאול את עצמינו האם אפיון טוב זה בהכרח אפיון שקובע כל פרט באתר?

התשובה לזה היא לא חד משמעית, אבל גישה שעוזרת בתכנות היא לא לפתח את המוצר, אלא את הכלים לפיתוח שלו.
הגישה הזאת יכולה לעכב את קבלת ההחלטות למועדים בהם נגיע לגשרים שונים, ותאפשר לנו להכריע ביתר קלות, כיוון שבזמן קבלת ההחלטה כבר יהיה לפנינו את צורת העבודה של המערכת, ויהיה לנו יותר קל לבחור, ואולי אף לשנות החלטה אם הצורה בה בנינו את המערכת מאפשרת גמישות זו.
דומה הדבר לחשיבה מחוץ לקופסה, בסיטואציה בה אנו מסתכלים על הקופסה עצמה, כאשר במקום לבחור את התכונות אותן נרצה במערכת ולהגדיר את רכיבי האתר, אנו נגדיר את האתר שיכיל אותן ויוכל להתרחב בהתאם לרצוננו.

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

סודות של תכנות

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

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

תכנות נעים.

5 תגובות:

אנונימי אמר/ה...

איתי בחור מוכשר מאוד וכתיבתו מהנה לקריאה . אהבתי לקרוא את הפוסט שלך ובהצלחה !

נ.ב.
פעם הבאה תתן דוגמאות יותר פשוטות כי לא כולנו מדעני טילים. חחחח.

כפיר אמר/ה...

מחזק (:

טל אמר/ה...

ממש אהבתי את הפוסט, אני חושב שזה הכי טוב שפירסמת :) כל הכבוד!

הדוגמה של הטבלה מסבירה היטב מדוע לומדים במדעי המחשב הרבה מתמטיקה ואלגוריתמים ופחות שפות תיכנות וטכניקות.

אנונימי אמר/ה...

אני גם בעד לתת דוגמאות פשוטות יותר, אבל נדמה לי שהוא ניסה לפנות לקהל יעד של מתכנתים רציניים.

בניית אתר אמר/ה...

רציתי להגיד שאיתי בחור מוכשר מאוד וכתיבתו מהנה לקריאה . אהבתי לקרוא את הפוסט שלך ובהצלחה
התחום של בניית אתר מתקדם