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

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

תרבות עבודה

12/04/2018

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

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

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

מסקנות?

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

תבניות מחשבה ושפות תכנות

11/04/2018

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

public class a {
  public static String checkSecurity(String [] people) {
    String found = "";
    int i=0;
    while (i < people.length && found.equals("")) {
      if (people[i].equals("Don")) {
        // report Don
        found = "Don";
      }
      if (people[i].equals("John")) {
        // report John
        found = "John";
      }
      i += 1;
    }
    return found;
  }

  public static void main(String [] args) {
    String res = checkSecurity(args);
    System.out.println(String.join(", ", args));
    if (res != "") {
      System.out.println("Found intruder: " + res);
    }
  }
}

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

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

interface StringPredicate {
  boolean check(String candidate);
}

public class b {
  public static String find_first(String [] people, StringPredicate p) {
    for (int i=0; i < people.length; i++) {
      if (p.check(people[i])) {
        return people[i];
      }
    }
    return null;
  }

  public static String checkSecurity(String [] people) {
    return find_first(people, (name) -> (name.equals("John") || name.equals("Don")));
  }

  public static void main(String [] args) {
    String res = checkSecurity(args);
    System.out.println(String.join(", ", args));
    if (res != "") {
      System.out.println("Found intruder: " + res);
    }
  }
}

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

def find_first(items)
  items.each do |item|
    break item if yield(item)
  end
end

found = find_first(ARGV) { |name| %w[John Don].include?(name) }
puts "Found Intruder: #{found}"

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

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

אויבים טבעיים של מערכות תוכנה

10/04/2018

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

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

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

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

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

  5. ורק בסוף אחרי כל הנזקים שאנחנו עושים לעצמנו יושבים ה״האקרים״, מסתכלים בהנאה על חורי האבטחה שאנחנו בונים עבורם.

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

דברים ש POC לא בודק

09/04/2018

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

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

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

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

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

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

טעויות מול שטויות

08/04/2018

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

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

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

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

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

יוניקוד בקטנה

07/04/2018

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

המשך קריאה

חמש המלצות קריאה מהקינדל שלי

06/04/2018

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

  1. הספר Social Architecture של פיטר הינצ'נס- פיטר הוא המייסד של חברת iMatix המפתחת מוצר קוד פתוח פופולרי בשם ZeroMQ. בספר הוא מספר על האג'נדה של פיתוח קוד פתוח והמכניקה של איך מגייסים, מובילים ומנהלים צוותי מתנדבים לפיתוח המוצר. אחרי שקראתי את Social Architecture אני מבין הרבה יותר טוב את הדינמיקה וההיגיון של עולם הקוד הפתוח. קישור: https://www.amazon.com/Social-Architecture-Building-line-Communities/dp/1533112452

  2. הספר Cryptography Engineering של ניל פרגוסון, ברוס שנייר וטדיושי קונו- ספרים על קריפטוגרפיה הם בדרך כלל משעממים כי הם אוהבים להתמקד בפרטים ופחות בתמונה הגדולה. הספר הזה לא מתקמצן על פרטים אבל לפני שמגיע אליהם הוא עוצר להסביר בצורה מאוד יסודית ומסודרת את התמונה הגדולה ואת ההיגיון של כל פרוטוקול קריפטוגרפי. ספר חובה למתכנתים, אלגוריתמיקאים ובכלל לכל מי שרוצה להבין איך תקשורת מודרנית עובדת. קישור: https://www.amazon.com/Cryptography-Engineering-Principles-Practical-Applications/dp/0470474246

  3. הספר Refactoring של מרתין פולרספרים על תכנות נוטים להתיישן מהר מאוד. לא כך הספר Rקכשבאםרןמע שלמרות שכולל דוגמאות קוד Jשהש משנת 1999, עדיין נשאר רלוונטי ביותר גם היום. הספר לימד אותי לחשוב על קוד של מערכות גדולות כדבר נזיל. הוא לימד אותי לא לפחד לשנות קוד תשתית ונתן לי הרבה מאוד כלים לגשת לשינויים כאלה. אגב יש דיבור שבקיץ יוצאת מהדורה חדשה ומעודכנת. קישור: https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672

  4. הספר Rails Test Prescriptions של נואל רפין- לימד אותי לכתוב בדיקות יחידה, ונתן לי את הביטחון לכתוב כאלה לפרויקטים שלי. זה הספר הכי טוב על בדיקות שקראתי וקצת חבל שהוא ממוקד ריילס. אם במקרה אתם גם עובדים בריילס שווה מאוד לקרוא אותו. קישור: https://pragprog.com/book/nrtest3/rails-5-test-prescriptions

  5. הספר Twenty Four Deadly Sins of Software Security של מייקל הווארד, דייויד לבלנק וג'ון ויגה- הוא ספר מקיף ומדויק עם המון דוגמאות לבעיות אבטחה בתוכנה. הספר לא מנסה להפוך אתכם להאקרים אלא פשוט מציג דוגמאות קוד פגיעות ומסביר לעומק מה הבעיות בהן. יש פה המון דוגמאות מפרויקטים אמיתיים ולכן אם אתם רוצים להבין יותר טוב את העולם של פריצות ולמה מערכות נשברות זה המקום להתחיל בו. קישור: https://www.amazon.com/Deadly-Sins-Software-Security-Programming/dp/0071626751

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

05/04/2018

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

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

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

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

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

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

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

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

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

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

פייסבוק. קיץ 2008.

04/04/2018

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

// from facebook.com at 2008
// https://web.archive.org/web/20080709203613/http://www.facebook.com/

function show_birthday_help(){
  birthday_popup=new pop_dialog('birthday_warning_popup');
  html='<div class="dialog_body">'
    +tx('sre22')+
    '<br /><br />'+
    tx('sre23')+
    ' <a href="/pages/create.php" title="Create a Page">'+
    tx('sre24')+
    '</a>.'+
    '</div>'+
    '<div id="dialog_buttons" class="dialog_buttons">' +
    '<input type="button" class="inputsubmit" id="dialog_button1" onclick="birthday_popup.hide();" value="'+
    tx('sre26')+'"/></div>';
  birthday_popup.show_prompt(tx('sre25'),html);
}

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

מי צודק?

03/04/2018

גווידו ון רוסום הוא היוצר של שפת Python. ב 2009 הוא פירסם מניפסט שיוצא כנגד Tail Recursion Elimination. הטענה שלו שזה מעודד הרגלי תכנות גרועים ולכן אסור להכניס יכולת כזו לשפה. ב 2011 חוזה ואלים כתב שפת תכנות בשם Elixir שמתבססת על הרעיון של Tail Recursion Elimination. חוזה טען שרקורסיה ולכן TRE הם המבנים הבסיסיים ביותר בתכנות, שהם עוזרים לייצר קוד קריא ויציב יותר ושלולאות הן האויב (כי לולאות משתמשות ב Mutable Data שהוא הרבה יותר גרוע).

בעולם מקביל, ספריית הקוד הכי פופולרית לבניית אתרים מאז ומעולם נקראת jQuery. שנים ארוכות היא היתה האפשרות הטובה ביותר וכמעט היחידה לפיתוח אתרים. ואז איפשהו ב 2009 לאנשים התחיל להימאס מ jQuery - ב 2010 ג'רמי אשכנז משחרר את Backbone ומישקו הברה את אנגולר: שתי ספריות ששינו ב 180 מעלות את התפיסה של פיתוח Web. בעולם של jQuery התפיסה המקובלת היתה ש JavaScript עובד על מידע ששמור ב DOM. בעולם של Backbone ועוד יותר מזה Angular, קוד JavaScript הוא זה ששמר את המידע וכתב אותו ל DOM כשהיה צריך. לימים React, Vue ו Angular2 המשיכו את הכיוון שטוען שהמידע נשמר ב JavaScript; ולאחרונה DHH שיחרר פריימוורק בשם Stimulus שחוזר לרעיון הישן שהמידע צריך להישמר ב DOM.

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