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

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

מחט בערימת שחת

23/07/2019

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

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

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

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

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

טיפ לקיץ - אוביקטים קפואים ב JavaScript

22/07/2019

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

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

> const x = { foo: 10 };
> Object.freeze(x);

> x.foo = 20
> x.bar = 30
> console.log(x);
{ foo: 10 }

> Object.isFrozen(x)
true

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

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

> const x = { foo: [] }
> Object.freeze(x)
> x.foo.push(10)
> console.log(x)

{ foo: [ 10 ] }

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

> const x = 'hello'
> Object.isFrozen(x)
true

> x.foo = 10
> console.log(x.foo)
undefined

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

שיטות והיקף לימוד

21/07/2019

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

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

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

גם תיעוד גרוע הוא הזדמנות למידה

20/07/2019

״הכלי מעולה אבל התיעוד לוקה בחסר״ ״לקח לי יותר משעה למצוא דוגמא נורמלית שעובדת״ ״אני מנסה ללמוד דג'נגו והתיעוד רץ ב 100 קמ"ש ובלי שום תמונות״

אני יודע שזה מתסכל להתחיל לקרוא תיעוד על ספריה ולא להבין כלום. זה קרה לי עם NumPy וגם עם Active Records בהתחלה וכמובן בכל מה שקשור ל CSS. הבעיה היא אף פעם לא היעדר תיעוד (אף אחד לא מתלונן על תיעוד ה API של iCount), אלא ספריות עם תיעוד ארוך, קיים, שאני פשוט לא מבין אותו.

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

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

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

גישה לבסיסי נתונים יחסיים באמצעות Sequelize

19/07/2019

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

המשך קריאה

תרגול הבטחות ב JavaScript

18/07/2019

חושבים שאתם יודעים מה זה Promise, מה עושה async ו await ואיך לשלב את כל זה ב Node.JS? הנה ההזדמנות שלכם להוכיח את זה. מוזמנים לפתור ולשתף את הפיתרונות שלכם בתגובות (או לתרגל בבית בחושך כשמשעמם).

המשך קריאה

ניטרול מנגנוני הגנה

17/07/2019

בהודעה מפורסמת ב Stack Overflow מ 2011 אחד הגולשים שאל איך לשתף Session Cookie בין ASP.NET ל Java Applet. התשובה עם ה-וי שם המליצה לו לנטרל את מנגנון ההגנה שנקרא HTTP Only Cookie. זאת ההתכתבות:

https://stackoverflow.com/questions/201699/sharing-asp-net-session-cookies-with-a-java-applet/656465

העצה עובדת אבל המחיר אני חושב גדול מהתועלת. ניטרול מנגנוני הגנה בלי לבנות מנגנון אחר במקומם הוא רעיון רע: בסיטואציה כמו שתוארה מנגנון ההגנה שנקרא HTTP Only Cookie אמור לשמור על הגולש ממתקפת XSS שתגנוב לו את ה Session Token.

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

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

בורח להרים

16/07/2019

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

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

  2. אה רגע זה מעניין, למה הם כתבו כאן את הפונקציה הזאת ולא את ההיא?

  3. מה הולך פה?! איך לא ראיתי את כל ערימת התיעוד הזאת עד עכשיו? אין מצב שאצליח ללמוד את כל זה בחודשיים (או אפילו בשנתיים)... חייב לברוח להרים.

  4. אה ככה זה עובד. עכשיו אני מבין. בעצם זה לא כזה שונה מהדבר ההוא שאני כבר מכיר.

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

  6. יצאה אחלה מצגת. אני שמח שלקחתי את הפרויקט הזה ולא ברחתי להרים.

והדבר המדהים כאן הוא שהפחד והרצון לברוח להרים לא נעלם, גם אחרי אלף מצגות. באנגלית יש משפט "The only way out is through". אז נסו גם אתם לרוץ בתוך ולא לברוח להרים. ואם אתם ממש חייבים לברוח אז לפחות קחו משהו לשמוע בדרך:

ומה אם?

15/07/2019

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

def fib(n):
    if n == 0 or n == 1: return 1

    return fib(n-1) + fib(n-2)

ועכשיו נשאל -

  1. ומה אם n הוא שלילי?
  2. ומה אם n הוא בכלל לא מספר?
  3. ומה אם n הוא מספר גדול מאוד?
  4. ומה אם אני צריך לחשב סכום של 10 מספרי פיבונאצ'י?
  5. ומה אם אני צריך לשפר ביצועים ולהעביר חלק מהחישובים לתהליכון נפרד?
  6. ומה אם הקוד שלי צריך לרוץ על מכונה שאין בה הרבה זיכרון?

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

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

למה הכל מסובך כאן?

14/07/2019

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

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

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

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