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

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

לא רקוב מספיק

04/09/2021

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

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

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

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

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

מדריך קצר לאגרגציות ב MongoDB

03/09/2021

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

המשך קריאה

שאלות מראיונות עבודה: כיווץ מחרוזות

02/09/2021

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

aaaabbccc

אז אנחנו מחליפים את רצף ה a-ים ב a4, את רצף ה b-ים ב b2 ואת רצף ה c-ים ב c3 ומקבלים:

a4b2c3

אם התוצאה ארוכה יותר מהמחרוזת המקורית יש להחזיר את המחרוזת המקורית, ואם התוצאה קצרה יותר יש להחזיר את התוצאה המכווצת.

המשך קריאה

התור בפוטו צפון

01/09/2021

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

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

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

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

קריטריון

31/08/2021

האם הוא פותר בעיות מהר?

האם הוא רואה את כל מקרי הקצה הרלוונטיים?

האם הפיתרונות שלה תמיד הכי יעילים?

האם התקשורת איתה טובה?

האם הוא יתאמץ לפתור בעיה בכוחות עצמו?

האם הוא ידע לבקש עזרה כשצריך?

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

האם היא לומדת מהר?

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

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

בואו נכתוב שרת GraphQL ב Node.JS כדי לראות איך זה עובד

30/08/2021

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

בפוסט היום אני רוצה לכתוב שרת GraphQL ב Node.JS ו Express כדי לראות איך זה עובד. הפרויקט הוא API למערכת ניהול משימות שמאפשר לנו לראות את המשימות הפתוחות במערכת ולעדכן סטטוס "בוצע" של כל משימה.

העליתי את כל הקוד בפוסט לפרויקט דוגמה בגיטהאב בקישור:

https://github.com/ynonp/express-graphql-demo

המשך קריאה

רגע, לא כולם משתמשים בקוברנטס???

29/08/2021

את הכותרת הבאה בהאקרניוז קלטתי מקילומטר: "עם עבודת 9 עד 5 ושני ילדים, הצלחתי לבנות את ה MVP הראשון שלי". בום. חייב לראות מה זה ומי זה ומה הקסם הסודי. שתי פיסקאות פנימה הגיעה רשימת הטכנולוגיות: Laravel, jQuery, MySQL ואיחסון על Digital Ocean. לפי המחיר של 5$ לחודש אני די בטוח שלא מדובר בקלאסטר הקוברנטס הנוצץ שלהם.

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

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

במקרה של Free Option Screener, אתר עם עיצוב מכוער הוא לא חיסרון אלא הזדמנות לשחק עם React ו AntD אחרי שאתה יודע בדיוק מה אתה רוצה לבנות. אתר שמאוחסן על VM הוא קורבן מעולה לניסוי במעבר ל Kubernetes, כי יש למה להשוות וכבר יש לך Workflow של פיתוח והעלאת גירסה.

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

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

מה ההבדל בין `docker compose` ל `docker-compose` ?

28/08/2021

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

הסיפור הרשמי של שתי הפקודות הוא פשוט - הכלי docker-compose הוא סקריפט פייתון, הוא היה שם קודם וקוד המקור שלו (אם מצאתי נכון) הוא כאן: https://github.com/docker/compose.

לעומתו docker compose מסומן בתור compose גירסה 2, כתוב ב go וקוד המקור שלו (בהנחה שמצאתי נכון) הוא כאן: https://github.com/docker/compose-cli.

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

  1. גירסה 2, כלומר docker compose תומכת ביצירת קונטיינרים בעננים של מייקרוסופט ואמזון באמצעות אינטגרציה מובנית. מספיק ליצור context, לכתוב docker compose up ויש לכם קונטיינרים באוויר ב ECS או ACI.

  2. על הלינוקס שלי, בגירסה 2 כשאני מעלה מכונות עם docker compose up ואז לוחץ Ctrl+C אני נשאר תקוע על איזה הודעת "המכונות עצרו". בגירסת docker-compose up לחיצה על Ctrl+C עוצרת את המכונות אבל גם מחזירה אותי למסוף.

  3. גירסה 1 כלומר docker-compose תומכת בכתיבת הלוג ל syslog ונראה שגירסה 2 לא. במילים אחרות קובץ קומפוז כזה:

version: '3'
services:
  worker:
    image: // image
    logging:
      driver: syslog
      options:
        syslog-address: "udp://XXX.papertrailapp.com:XXXX"
        tag: "{{.Name}}/{{.ID}}"

שמצאתי כאן בסטאק אוברפלו ובמקומות נוספים יעבוד עם docker-compose up אבל לא יעבוד עם docker compose up.

  1. קומפוז גירסה 2 (הגירסה בלי המקף) תומך ב Apple Silicon.

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

טיפ JavaScript: שדה אופציונאלי באוביקט

27/08/2021

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

const key = 'name';

const data = {
    [key]: 'bob'
};

שמחזיר את האוביקט עם המפתח name ובו הערך bob.

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

const words = ['one', 'two', 'three'];
const wordsObject = words.map(w => ({ [w]: true })).reduce((a, b) => ({ ...a, ...b }));

// now wordsObject = { one: true, two: true, three: true }

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

const s1 = getStatus(task1);
// returns { status: 'PROCESSING' }

const s2 = getStatus(task2);
// returns { status: 'DONE', result: 8 }

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

function getStatus(task) {
    return {
        status: task.status,
        ...(task.status === 'DONE' && { result: task.result }),
    };
}

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

// prints: { status: 'PROCESSING' }
console.log(getStatus({ status: 'PROCESSING', result: 7 }));

// prints: { status: 'DONE', result: 7 }
console.log(getStatus({ status: 'DONE', result: 7 }));

מדריך Vue למתחילים - חלק 7 - ניהול מידע גלובאלי

26/08/2021

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

פוסטים קודמים בסידרה:

  1. פרק 1 - פיתוח קומפוננטה ראשונה

  2. פרק 2 - תקשורת בין קומפוננטות

  3. פרק 3 - תבניות דינאמיות

  4. פרק 4 - ממשק ההרכבה Composition API

  5. פרק 5 - דוגמת פיתוח נגן YouTube ב Vue

  6. פרק 6 - יישומי Single Page Apps עם Vue Router

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

המשך קריאה