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

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

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

26/02/2020

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

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

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

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

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

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

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

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

הטיעון נגד פייתון3

25/02/2020

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

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

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

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

"יש לי כבר את כל החומרים ב Python2 וכרגע לא באג'נדה שלי להעלות קורס חדש ב Python3"

"אני לא מכיר Angular, וכרגע לא באג'נדה שלי ללמוד אותו"

"לא ניסיתי עדיין לכתוב קוד ב React Native, אבל אני די מהיר ב Swift ומעדיף לעבוד על כלים שאני כבר מכיר"

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

מה אתה מודד?

24/02/2020

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

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

  1. כמה Refactoring מוצלחים עשיתי החודש? וכמה כושלים?

  2. עד כמה הכלים ושיטות העבודה שפיתחתי החודש עוזרים לי לפתור בעיות מהר יותר?

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

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

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

  6. איזה רעיונות חדשים ושיטות עבודה חדשות הצלחתי לשלב בתהליך הפיתוח בארגון שהשפיעו לטובה על תרבות העבודה?

רק בגלל שקל למדוד משהו לא אומר שזה כדאי.

שתי הודעות קומיט

23/02/2020

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

Fixed some stuff

והשניה:

Disabled server-side rendering because it was too slow.

In the future before turning this back on make sure to add caching support so we'll be able to reuse server-side rendered fragments between requests.

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

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

טיפ JavaScript: שמירת אוביקטים ב Map ו Set

22/02/2020

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

const text = "one two three one two one";
const wordCount = {};

for (let word of text.split(/\W+/)) {
  if (wordCount[word] == null) {
    wordCount[word] = 0;
  }
  wordCount[word] += 1;
}

console.log(wordCount);

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

const text = "hello toString world";
const wordCount = {};

for (let word of text.split(/\W+/)) {
  if (wordCount[word] == null) {
    wordCount[word] = 0;
  }
  wordCount[word] += 1;
}

console.log(wordCount);

פלט התוכנית:

{ hello: 1,
  toString: 'function toString() { [native code] }1',
  world: 1 }

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

מתכנתים טובים ידעו לעקוף את הבעיה באמצעות שימוש ב Object.create באופן הבא:

const text = "hello toString world";
const wordCount = Object.create(null);

for (let word of text.split(/\W+/)) {
  if (wordCount[word] == null) {
    wordCount[word] = 0;
  }
  wordCount[word] += 1;
}

console.log(wordCount);

אבל ממילא אף פעם לא היה קל למצוא מתכנתים טובים.

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

אני יכול לתקן את תוכנית הספירה שלי באמצעות Map די בקלות:

const text = "hello toString world";
const wordCount = new Map();

for (let word of text.split(/\W+/)) {
  const value = wordCount.get(word) || 0;
  wordCount.set(word, value + 1);
}

console.log(wordCount);

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

בחזרה לתוכנית הספירה - הקוד הבא לא יצליח לזהות שהמערך [2, 5] מופיע 3 פעמים בקלט:

const data = [[1, 2], [2, 3], [5, 2], [5, 2], [5, 2], [2, 3]];
const count = new Map();

for (let item of data) {
  const value = count.get(item) || 0;
  count.set(item, value + 1);
}

console.log(count);

וידפיס את זה:

Map {
  [ 1, 2 ] => 1,
  [ 2, 3 ] => 1,
  [ 5, 2 ] => 1,
  [ 5, 2 ] => 1,
  [ 5, 2 ] => 1,
  [ 2, 3 ] => 1 }

אבל אם נחליף את ה Map באוביקט רגיל הקוד יעבוד בלי בעיה:

const data = [[1, 2], [2, 3], [5, 2], [5, 2], [5, 2], [2, 3]];
const count = {};

for (let item of data) {
  if (!count[item]) {
    count[item] = 0;
  }
  count[item] += 1;
}

console.log(count);

וידפיס:

{ '1,2': 1, '2,3': 2, '5,2': 3 }

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

const data = [[1, 2], [2, 3], [5, 2], [5, 2], [5, 2], [2, 3]];
const count = new Map();

for (let iitem of data) {
  const item = String(iitem);
  const value = count.get(item) || 0;
  count.set(item, value + 1);
}

console.log(count);

אבל לא בטוח שזה שווה את המאמץ.

מובאקס (MobX) בעשר דקות

21/02/2020

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

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

המשך קריאה

אוף סיזן

20/02/2020

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

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

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

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

ממעורב למחויב

19/02/2020

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

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

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

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

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

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

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

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

מעגלים

18/02/2020

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

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

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

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

חידת שיפור ביצועים ב React

17/02/2020

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

ועם הרמז הזה אני שולח אתכם לקוד בקישור: https://codesandbox.io/s/sparkling-framework-zc8c1.

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

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

בהצלחה. ינון