הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

לא הסיפור הזה

23/12/2020

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

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

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

או הסיפור על היזם הסידרתי שלא וויתר ואחרי עשרות מוצרים הצליח לבנות משהו שאנשים אוהבים והפך ויראלי.

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

הבעיה שלפעמים על הסיפור היפה הזה מתלבש החבר הפחות-יפה שלו, הסיפור על הפשרות הכואבות שצריך לעשות בדרך להצלחה:

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

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

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

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

זמן התנעה

22/12/2020

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

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

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

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

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

שתי מסקנות קלות לקחת מהסיפור:

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

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

שלוש שעות ועשר שניות

21/12/2020

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

function padded(num) {
  return num > 10 ? String(num) : '0' + num;
}

נו, מביך והכל אבל פה בבלוג מותר לדבר על הכל, אפילו על טעויות Off By One. קודם כל הבאג למי שלא ראה מיד קשור לסימן ה"גדול מ-" שהיה צריך להיות "גדול-שווה" או גדול מ-9. עשר הוא גם מספר דו-ספרתי.

אבל יותר מעניין - איך מונעים שטויות כאלה בעתיד? הנה שלושה רעיונות:

  1. כיוון אחד יהיה לבדוק טוב יותר. כלומר לכתוב לכל פונקציה קטנה תוכנית בדיקה שתוודא שהפונקציה באמת תמיד עושה את מה שהיא אמורה לעשות. במקרה של padded כנראה שבבדיקה רגילה לא הייתי חושב לבדוק דווקא את 10 (כי אם הייתי חושב עליו כשכתבתי את הקוד ממילא הבאג לא היה קורה), ולכן צריך לחשוב על בדיקה שרצה בלולאה על כל המספרים מ-0 עד 99, שולחת אותם ל padded ומוודאת שהאורך של התוצאה הוא תמיד 2. הסיכוי לכתוב קוד בדיקה מהסוג הזה על כל פונקציה קטנה שאני כותב הוא באזור ה-0.

  2. כיוון שני יהיה להשתמש בספריה חיצונית. במקרה של padded הספריה החיצונית אפילו די מפורסמת ונקראת left-pad. הקוד היה נראה כך:

impor leftPad from 'left-pad';

function padded(num) {
    return leftPad(String(num), 2, '0');
}

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

  1. כיוון שלישי ספציפי למקרה הזה הוא להיזכר שאחרי הפארסה של left-pad כבר הוסיפו ל JavaScript את הפונקציונאליות והיום היה אפשר לכתוב את הקוד הזה:
function padded(num) {
    return String(num).padStart(2, '0');
}

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

function padded(num) {
    return ('0' + num).slice(-2);
}

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

בוא אני אסביר לך איך זה עובד

19/12/2020

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

אבל מבחינת אפקטיביות? תצטרכו לעבוד הרבה יותר קשה.

הדרכה אפקטיבית מתחילה בהקשבה:

  1. מה אתה מנסה לעשות?

  2. איך חשבת לגשת לזה?

  3. מה ניסית בינתיים?

  4. למה לדעתך זה לא עבד?

  5. מה הדבר הבא שחשבת לנסות?

  6. אולי תנסה גם את זה?

אבל מי יקרא את זה בכלל?

18/12/2020

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

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

  1. מתכנת רואה בעיה

  2. מתכנת מחפש בגוגל פיתרונות

  3. מתכנת מוצא פיתרון שעובד

  4. מתכנת ממשיך לבעיה הבאה

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

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

איך לשתף קוד באמצעות חבילות npm

17/12/2020

כולכם כבר יודעים להפעיל npm install כדי להתקין חבילות מהרשת, גם עבור פיתוח Backend ב node.js וגם עבור פיתוח Front End. אבל מה אתם עושים כשצריך לשתף קוד שלכם בין פרויקטים?

מסתבר שאפשר ואפילו קל להשתמש באותם הכלים של npm ובאותן שיטות עבודה שאתם מכירים. זה נראה כך:

המשך קריאה

למה קשה כל כך לסיים פרויקט תוכנה

16/12/2020

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

כי כל קומה שהם מסיימים בבניין היא קומה שהם סיימו. פה זה נגמר.

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

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

מותר להתחרט

15/12/2020

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

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

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

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

זה לא עוזר לחשוב יותר חזק

14/12/2020

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

האמת כמובן יותר מורכבת.

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

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

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