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

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

היכרות עם Stimulus.js

30/08/2018

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

המשך קריאה

עריכה

29/08/2018

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

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

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

מה תעשו כשהקוד שלכם יתיישן?

28/08/2018

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

מה תעשו כשזה יקרה?

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

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

  3. אפשר לשמור את המערכת בקופסת שימורים ולהמשיך להשתמש בה גם הרבה אחרי תאריך התפוגה.

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

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

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

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

ככה לא כותבים בדיקות תקינות

27/08/2018

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

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

$ hebcal 4 2059
4/1/2059 Pesach IV (CH''M)
4/2/2059 Pesach V (CH''M)
4/3/2059 Pesach VI (CH''M)
4/4/2059 Pesach VII
4/5/2059 Pesach VIII
4/10/2059 Yom HaShoah
4/13/2059 Rosh Chodesh Iyyar
4/14/2059 Rosh Chodesh Iyyar
4/16/2059 Yom HaZikaron
4/17/2059 Yom HaAtzma'ut
4/27/2059 Pesach Sheni

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

$ hebcal 99999 2059
Segmentation fault: 11

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

https://github.com/hebcal/hebcal

הפונקציה הראשונה שצריכה להטריד אותנו היא זו שמופעלת כדי לפענח את הפרמטרים (הקובץ start.c) ושם אנחנו פוגשים את הקטע הבא:

startAbs = greg2abs(tempDate);
tempDate.dd = MonthLengths[LEAP(theYear)][theMonth];
endAbs = greg2abs(tempDate);

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

 theMonth = atoi(remain[0]);

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

       if (theMonth > 12)
               die("The month must be less than 13", "");

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

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

tempDate.dd = MonthLengths[LEAP(theYear)][theMonth];

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

int getMonthLength(int year, int month)
{
    if (month < 0 || month > 13)
    {
        return 0;
    }
    return MonthLengths[LEAP (year)][month];
}

עכשיו אפשר יהיה לשנות את שאר הקוד בתוכנית כך שכל הגישות למערך MonthLengths יהיו דרך הפונקציה.

אפשר לראות את השינויים המלאים שהצעתי לפרויקט ב Pull Request שהעליתי כאן:

https://github.com/hebcal/hebcal/pull/157/files

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

רעיונות לא טובים

26/08/2018

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

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

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

אל תשכחו למלא מים

25/08/2018

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

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

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

נ.ב. הפוסט הזה לא באמת היה על מגהצים. טוב אולי קצת.

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

רוצים לזכות במנוי לשנה במתנה לאתר?

24/08/2018

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

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

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

(סיפור רקע- אתמול התארח כאן יניב ארד לספר על node.js והחוויה היתה טובה גם לי, גם ליניב ואני מקווה שגם למי שבא והקשיב. אני חושב שלתת במה ליותר אנשים יעשה טוב לפרויקט).

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

מחכה לשמוע מכם ינון

פתוח-סגור

23/08/2018

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

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

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

זה ההבדל המהותי בין תוכנה חופשית לתוכנה קניינית (או בשמות הרחוב שלהן בין קוד פתוח לקוד סגור):

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

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

למה אנשים לא רוצים לגייס פרילאנסרים (ומה בכל זאת אפשר לעשות)

22/08/2018

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

והעניין שלנו היום בהליכי גיוס הוא היחס לפרילאנסרים.

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

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

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

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

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

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

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

זחילת פיצ'רים

21/08/2018

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

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

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

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

0 7 * * 0,1,2,3,4,5 /home/ynon/bin/cron/daily_blog.sh
0 21 * * 6 /home/ynon/bin/cron/daily_blog.sh

למי שעדיין לא לקח את קורס Linux שלנו (איך עדיין לא לקחתם את קורס Linux?! הוא מעולה. קחו את קורס Linux) המשמעות היא שבימים ראשון עד שישי המייל יישלח בשבע בבוקר וביום שבת בתשע בערב אחרי צאת שבת.

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

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