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

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

חידת JavaScript: המרות נתונים

21/07/2021

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

const express = require('express')
const app = express()
const port = 3000

const foods = [
    'Humus',
    'Fried Tofu',
    'Eggplant Frittata',
];

app.get('/:id', (req, res) => {
  const index = req.params.id;
  const data = foods[index];
  res.send(data);
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

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

const express = require('express')
const app = express()
const port = 3000

const foods = [
    { id: 9412, likes: 'Humus' },
    { id: 9121, likes: 'Fried Tofu' },
    { id: 8123, likes: 'Eggplant Frittata' },
];

app.get('/:id', (req, res) => {
  const data = foods.find(item => item.id === req.params.id);
  res.send(data);
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

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

מבלי להריץ את הקוד נסו לזהות מה נשבר ואיך הייתם מתקנים?

אילוצים לא טכנולוגיים

20/07/2021

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

לפני כמה שנים יצא לי לעבוד על רצף של פרויקטים שכל תכליתם היתה תרגום מערכות: תרגום מ perl ל python; תרגום מ Silverlight ל JavaScript, מ jQuery ל React ואפילו תרגום מ Rails ל Node.JS. בכל המקרים האילוצים שהביאו את הלקוחות לתרגום לא היו אילוצים טכנולוגיים.

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

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

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

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

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

19/07/2021

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

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

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

כשהתיעוד משקר

18/07/2021

לא מזמן חבר הראה לי את הטריק הבא מסטאק אוברפלו כדי לייצר Directive ב Vue שמדמה את v-if ועושה אותו קצת יותר מתוחכם: https://stackoverflow.com/questions/43003976/a-custom-directive-similar-to-v-if-in-vuejs

זה הקוד המעניין מתוך השאלה שם:

Vue.directive('permission', (el, binding, vnode) => {
  if (!isUserGranted(binding.value)) {
    // replace HTMLElement with comment node
    const comment = document.createComment(' ');
    Object.defineProperty(comment, 'setAttribute', {
      value: () => undefined,
    });
    vnode.elm = comment;
    vnode.text = ' ';
    vnode.isComment = true;
    vnode.context = undefined;
    vnode.tag = undefined;
    vnode.data.directives = undefined;

    if (vnode.componentInstance) {
      vnode.componentInstance.$el = comment;
    }

    if (el.parentNode) {
      el.parentNode.replaceChild(comment, el);
    }
  }
});

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

Apart from el, you should treat these arguments as read-only and never modify them. If you need to share information across hooks, it is recommended to do so through element’s dataset.

עכשיו - מי צודק? התיעוד או Stack Overflow? ואם מישהו נתקל בתשובה בסטאק אוברפלו בלי שהכיר קודם את התיעוד?

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

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

חמישה פיצ'רים שעדיף ליישם לפני שהמערכת שלכם הופכת פופולרית

17/07/2021

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

המשך קריאה

שתי טעויות עם הצעות נכנסות

16/07/2021

שתי טעויות נפוצות שאנחנו עושים עם הצעות נכנסות (הצעות עבודה, הצעות לפרויקטים):

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

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

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

מ Monolith ל Micro Services

15/07/2021

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

המשך קריאה

בשביל מה זה טוב?

14/07/2021

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


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


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

טיפ פרילאנס: למצוא לקוחות טובים יותר

13/07/2021

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

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

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

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

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

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

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

חידת Node.JS ו Winston

12/07/2021

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

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

const winston = require('winston');
require('winston-syslog').Syslog;


// creates a new Winston Logger
const logger = winston.createLogger({
  level: 'debug',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.printf(({ level, message, timestamp }) => (
      `${timestamp} ${level}: ${message}`
    )),
  ),
  transports: [
    new winston.transports.Syslog({
      host: process.env.SYSLOG_NG_HOST,
      app_name: process.env.SYSLOG_NG_APPNAME,
    }),
  ],
});

logger.stream = {
  write(message, _encoding) {
    logger.info(message);
  }
};

module.exports = logger;

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