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

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

להילחם ב Complexity או להכיל אותה

28/03/2023

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

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

יש שתי גישות להתמודד עם התהליך הבלתי נמנע הזה-

  1. אפשר להילחם ב Complexity - לשמור על מודולים קטנים, לשכתב בקיצוניות קוד ברגע שמתחיל להיות מסורבל, הביטוי Move fast and break things מתאר סוג כזה של פיתוח.

  2. אפשר להכיל את ה Complexity - לבנות ארכיטקטורות Object Oriented מורכבות, להשתמש ב Type System, לכתוב בדיקות, ללמוד לחיות עם זה שלעולם לא תצליח להבין כל פרט בקוד, ללמוד להשתמש ב Debugger, לכתוב המון תיעוד ו wikis ואפילו להיעזר ב AI כדי לקבל תשובות על הקוד.

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

עדכון מפתח ה RSA של גיטהאב

27/03/2023

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

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s.
Please contact your system administrator.
Add correct host key in /Users/ynonp/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/ynonp/.ssh/known_hosts:13
Host key for github.com has changed and you have requested strict checking.
Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

בואו נראה מה קרה ואיך מתקנים

המשך קריאה

היום למדתי: מצב גלישה פרטית ב bash

26/03/2023

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

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

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

$ echo $HISTCONTROL
ignoreboth

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

$ export HISTCONTROL=ignoreboth

ב zsh השליטה בפיצ'ר היא באמצעות Shell Option בשם hist_ignore_space. הפקודה setopt מדפיסה את כל האופציות המופעלות ואנחנו צריכים את histignorespace ברשימה:

$ setopt|grep histignorespace
histignorespace

אם זה לא שם תצטרכו לעדכן אותו עם (ורצוי גם בקובץ rc) עם:

$ setopt hist_ignore_space

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

$ echo one
one
$ history| tail -1
10010  echo one

ואז פקודה שמתחילה ברווח ובדקו שהיא לא ברשימה:

$  echo two
two
$ history | tail -1
10010 echo one

פי או סי

25/03/2023

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

אבל שנינו יודעים שזה לא נכון.

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

וכך אנחנו חוזרים ל POC-ים מהעולם שלנו ולשאלות שאנחנו מנסים לברר ביום יום:

  1. האם לעבור לענן או להישאר עם שרת פרטי? (או להיפך)

  2. האם לפתח מיקרו סרביסים או מונולית?

  3. האם לגייס מפתחים מקומיים או להיעזר בפרילאנסרים מהעולם?

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

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

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

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

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

לא חייבים לבזבז זמן על POC. זה אפשרי. עכשיו בואו נתחיל לעבוד.

גלאי עשן

24/03/2023

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

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

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

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

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

אקרופליפסה

23/03/2023

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

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

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

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

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

ולכן שתי מסקנות-

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

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

ברווז הגומי התחיל לענות

22/03/2023

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

ועכשיו ברווז הגומי גם עונה חזרה.

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

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

רק נראים עסוקים

21/03/2023

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

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

ההתאהבות בכלים וב Best Practices היא הרבה פעמים לרעתנו ועולה לנו באיכות המוצר. דוגמאות מפרויקטים אמיתיים:

  1. התעקשות לכתוב בדיקות יחידה עם 100% כיסוי קוד, והתוצאה היא בדיקות שלא בודקות כלום ושנכתבות רק בשביל "לעבור" איזה כלי אוטומטי.

  2. בחירה ב Micro Services למרות שהמוצר והצוות קטנים, שעולה בזמני פיתוח ארוכים יותר, רק בגלל "ככה עושים היום".

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

  4. הוספת עוד יכולות לפיצ'רים (Feature Creep) במקום שיחרור גירסאות ללקוחות.

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

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

המלצה על פרויקט - Helm Dashboard

20/03/2023

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

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

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

אתם יכולים למצוא את כל הפרטים על הפרויקט בקישור כאן: https://www.facebook.com/groups/frontendistim/permalink/913268943434540/

להפסיד משני העולמות (זמני טעינת אתר)

19/03/2023

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

בהרבה מערכות אחרות המידע הדינמי של העמוד הוא חלק בלתי נפרד ממנו, אבל בשביל לאפשר Scale גדול נבחר עדיין להשתמש בקבצי HTML/CSS/JS סטטיים, שימשכו את המידע הדינמי מהשרת בעליה דרך API. ההנחה היא שבמקרי קיצון משיכת מידע מ API תעמיס פחות על השרתים מאשר ייצור של Template מלא של ה HTML, ובנוסף קל יותר לפתח את המערכת עם הפרדה ברורה בין צוות ה Front End לצוות ה Back End.

בהרבה מערכות נוספות המידע הדינמי של העמוד הוא חלק בלתי נפרד ממנו אבל בגלל שהצוות קטן ומורכב ממתכנתי Full Stack, או שלא מתוכנן עומס של אלפי בקשות בשניה על ה API, שווה לנו לוותר על ה HTML הסטטי וליצור את ה HTML דינמית מתוך קוד צד שרת (לדוגמה קוד Rails או Django). דף HTML כזה שחוזר לדפדפן מכיל בטעינה הראשונית גם את כל המידע הדינמי של העמוד ואז הדפדפן יכול להציג את התוכן מיד איך שמקבל את התשובה לבקשה הראשונה. נכון, הפסדנו את היכולת להפיץ את ה HTML דרך CDN, אבל חסכנו צורך בבקשת רשת נוספת בשביל המידע הדינמי של העמוד.

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