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

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

טיפ ריאקט: רינדור רשימות ארוכות

28/10/2021

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

המשך קריאה

פרודוקטיביות

27/10/2021

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

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

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

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

התמדה בימי קורונה

25/10/2021

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

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

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

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

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

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

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

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

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

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

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

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

למחוק!? ואם אצטרך את זה בעתיד?

24/10/2021

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

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

נו, אז בואו נדבר על כמה זה באמת עולה:

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

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

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

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

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

טיפ Node ו Docker - השתמשו ב wait-on כדי לחכות לקונטיינרים אחרים

23/10/2021

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

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

אני מקווה שאתם כבר מכירים את הסקריפט wait-for-it שגם מגיע עם דביאן וגם אפשר להוסיף בקלות להתקנה של כל קונטיינר ופותר בדיוק את הבעיה הזאת. ובכל מקרה אם המערכת שלכם כתובה ב Node.JS שווה להכיר שיש פיתרון יותר מוצלח שמשתלב באפליקציה והוא המודול wait-on.

מודול wait-on מאפשר לקבל רשימה של משאבים מכל מיני סוגים ויודע לחכות עד שכל המשאבים יהיו באוויר. הסוגים הנתמכים כוללים: קובץ, נתיבי רשת (http ו https), חיבור tcp וחיבור socket.

בהמתנה לקובץ התוכנית תמשיך רק כשהקובץ יהיה במקום שאתם צריכים אותו. בהמתנה לנתיבי רשת הקוד ישלח בקשת HTTP Head ויחכה לקבל תשובת HTTP 200, ובהמתנה ל tcp או socket הוא יחכה שיווצר חיבור. אפשר לשלוט גם בכל הפרמטרים של ההמתנה באמצעות אופציות שמעבירים לפונקציה ושווה להסתכל בתיעוד כדי לראות את הרשימה המלאה.

הנה דוגמה פשוטה לתוכנית Node.JS שמחכה ששרת redis יעלה על localhost ורק אז מתחברת אליו ומעלה ערך של מפתח בשם count:

const redis = require('redis');
const port = 3000;

const waitOn = require('wait-on');
const resources = [
  'tcp:localhost:6379'
];

waitOn({ resources }, () => {
  // here everything's ready
    console.log('ready!');

    const client = redis.createClient({
      port      : 6379,
      host      : 'localhost',
    });

  client.get('count', (err, count) => {
    if (err) return next(err);
    console.log(`count = ${count}`);
    client.incr('count', () => {
        client.quit();
    });
  });
});

וכמה אפליקציות יצאו מאז?

22/10/2021

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

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

אז עזבתי והמשכתי לעשות דברים אחרים.

ושנתיים אחרי, ב 2013, Nguyễn Hà Đông פירסם את פלאפי בירד וזכה להצלחה פנומנלית.

וב 2014 גבְּריאֶלֶה צ'ירולי פירסם את 2048 שהפך ללהיט ממכר.

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

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

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

השלב הראשון בפיתרון בעיה

21/10/2021

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

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

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

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

השלב הראשון בפיתרון בעיה הוא להבין שאפשר לפתור את זה, אבל לא בטוח שבדרך שאתה רוצה.

היום למדתי: איך לגרום לחלונות קופצים להישאר

20/10/2021

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

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

אז אם אתם בכרום וה Dropdown שלכם ידידותי, למשל כמו זה שכאן: https://developer.microsoft.com/en-us/azure-devops/components/dropdown

תוכלו להיכנס לכלי הפיתוח, ללחוץ Ctrl+Shift+p ולבחור באפשרות Emulate a Focused Page. אפשרות זו גורמת ל Dropdown לחשוב שהוא עדיין בפוקוס ולכן להישאר פתוח, גם אחרי שלוחצים על כפתור ימני ו Inspect Element.

נ.ב. הטריק הזה לא עובד בכל מקום לדוגמה על react-select כאן: https://react-select.com/home לא הצלחתי לגרום לו לעבוד. בכל מקרה שווה לנסות אותו - יש סיכוי מסוים שהוא יחסוך גם לכם עבודה.

אבל מה עושים עם הבדיקות?

19/10/2021

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

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

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

אני רואה רק שתי דרכים להתקדם:

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

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

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