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

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

באגים של אחרים

11/09/2019

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

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

{
  "name": "myapp",
  "version": "1.1.0",
  "dependencies": {
    "actioncable": "^5.1.1",
    "babel-core": "6.26.3",
    "babel-eslint": "^10.0.1",
    "babel-loader": "^8.0.5",
    "babel-plugin-react-transform": "^3.0.0",
    "babel-polyfill": "^6.8.0",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0",
    "babel-runtime": "^6.6.1",
    "body-parser": "^1.15.1",
    "classnames": "^2.2.5",
    "create-react-class": "15.6.3",
    "css-loader": "^2.1.1",
    "es5-shim": "^4.5.8",
    "es6-promise": "^4.1.0",
    "eslint-plugin-import": "^2.3.0",
    "eslint-plugin-jsx-a11y": "^6.2.1",
    "exports-loader": "^0.7.0",
    "expose-loader": "^0.7.1",
    "github-api": "^3.0.0",
    "history": "4.9.0",
    "immutable": "^4.0.0-rc.12",
    "imports-loader": "^0.8.0",
    "isomorphic-fetch": "^2.2.1",
    "jquery": "^3.2.1",
    "jquery-ui": "^1.10.5",
    "jquery-ujs": "^1.2.1",
    "loader-utils": "^1.1.0",
    "mirror-creator": "1.1.0",
    "nighthawk": "2.2.0",
    "null-loader": "^1.0.0",
    "prop-types": "^15.7.2",
    "query-string": "^6.5.0",
    "react": "^16.8.6",
    "react-addons-linked-state-mixin": "^15.0.2",
    "react-bootstrap": "^1.0.0-beta.8",
    "react-burger-menu": "^2.0.2",
    "react-dom": "^16.8.6",
    "react-dropzone": "^10.1.4",
    "react-immutable-proptypes": "^2.1.0",
    "react-on-rails": "11.2.2",
    "react-quill": "^1.0.0-rc.2",
    "react-redux": "^7.0.3",
    "react-scroll": "^1.0.16",
    "react-sticky": "^6.0.1",
    "react-transition-group": "^4.0.0",
    "redux": "^4.0.1",
    "redux-batched-subscribe": "^0.1.6",
    "redux-promise": "^0.6.0",
    "redux-thunk": "^2.1.0",
    "router": "^1.1.4",
    "scriptjs": "^2.5.8",
    "strftime": "^0.10.0",
    "underscore": "^1.8.3",
    "url-parse": "^1.1.1"
  },
  "devDependencies": {
    "@babel/core": "^7.6.0",
    "@babel/plugin-proposal-class-properties": "^7.5.5",
    "@babel/preset-env": "^7.6.0",
    "@babel/preset-react": "^7.0.0",
    "bootstrap-sass": "^3.3.6",
    "bootstrap-sass-loader": "^1.0.10",
    "eslint": "^5.16.0",
    "eslint-config-airbnb": "17.1.0",
    "eslint-plugin-react": "^7.0.1",
    "esprima-fb": "^15001.1001.0-dev-harmony-fb",
    "express": "^4.13.4",
    "file-loader": "^3.0.1",
    "jade": "^1.11.0",
    "jscs": "^3.0.3",
    "node-sass": "^4.5.3",
    "react-transform-hmr": "^1.0.4",
    "sass-loader": "^7.1.0",
    "speed-measure-webpack-plugin": "^1.3.1",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.39.3",
    "webpack-bundle-analyzer": "^3.4.1",
    "webpack-cli": "^3.3.8"
  }
}

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

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

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

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

שברת שילמת

10/09/2019

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

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

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

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

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

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

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

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

שברת -> שילמת -> תיקנת -> למדת.

שלוש טעויות שכבר לא תעשו ב Python אחרי שתוסיפו Type Hints

09/09/2019

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

המשך קריאה

בואו נמצא פודקסטים מעניינים עם פייתון

08/09/2019

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

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

המשך קריאה

על ההבדל בין ״לא אופנתי״ ל״לא חשוב״

07/09/2019

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

ובכל זאת מתכנתים כותבים SQL כל יום (למרות שכולם מדברים על NoSQL או על ORM).

ובכל זאת רוב ה APIs שתעבדו מולם עדיין בנויים על REST (למרות שכולם מדברים על GraphQL).

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

ולמרות שרוב קוד ה JavaScript החדש שנכתב היום משתמש בכתיב Object Oriented ובכל היכולות החדשות של השפה, כל מתכנתי ה JavaScript הרציניים שאני מכיר יודעים איך לעבוד עם Prototype, יודעים מה זה bind ו apply וישמחו לספר לכם למה אף פעם לא כדאי להשתמש ב document.write.

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

ללכת עד הקצה

06/09/2019

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

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

$ git checkout -b my-new-feature

ואז לעבוד, לעשות את הקומיטים ובסוף למזג.

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

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

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

  3. לנסות דרכים אחרות ליצור את הענף (למשל עם switch או עם branch), ולקרוא בתיעוד מה ההבדל בין הדרכים.

  4. לנסות ליצור ענף בשם לא נכון ואז לתקן לו את השם.

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

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

מי צריך Module Bundler

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

המשך קריאה

גבולות התפקיד

04/09/2019

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

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

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

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

האם אני רוצה להיות החבר שמביא את הכלי החדש?

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

האם אני מוכן להשקיע רק כשאני רואה שהכלי הזה באמת נותן יותר ערך?

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

ממליצים

03/09/2019

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

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

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

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

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

למה בחרת להיות פרילאנסרית?

02/09/2019

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

האם רצית להרוויח הכי הרבה שאת יכולה?

האם רצית יותר גמישות כדי להיות עם הילדים?

האם חלמת לעבוד מכל מקום בעולם?

האם כדי לקדם נושא שקרוב ללבך?

או שסוג העבודה שאת חולמת לעשות לא זמין לשכירים?

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

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

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

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