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

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

אני רוצה להיות ...

24/11/2021

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

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

ויש המון סיבות לפער:

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

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

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

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

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

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

מעניין, מועיל, חשוב

22/11/2021

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

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

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

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

מעניין דואג לעצמו. זאת המשימה שלנו למצוא זמן ל"חשוב" ו"מועיל". המפתח להצלחה הוא בידיים שלהם.

מה יקרה אם?

21/11/2021

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

המשך קריאה

תרגומון Vue: שלוש דרכים לכתוב קומפוננטה

20/11/2021

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

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

המשך קריאה

הכי טובה בצוות

19/11/2021

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

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

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

מה לעשות כשגילית שיש דרך יותר טובה?

18/11/2021

התשובה הקלה- לשנות.

אין שום תירוץ להמשיך להשתמש ב componentDidUpdate, componentWillUnmount ו componentDidMount בריאקט אם אתה יודע איך להשתמש ב useEffect.

ואין שום תירוץ להמשיך לכתוב var אחרי שאתה יודע על let ו const.

ועדיין-

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

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

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

  1. פעם בחודש מקדישים יום לשדרוג תלויות.

  2. פעם בשבוע מקדישים שעתיים ל Refactoring של קוד כדי שיהיה קל יותר לשלב אותו בשיטות עבודה חדשות.

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

  4. כל יום מקדישים רבע-שעה לקריאת מאמר מקצועי כדי להיחשף לשיטות עבודה חדשות וטובות יותר.

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

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

מינימליזם

17/11/2021

איזה מזל, יש HDMI.

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

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

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

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

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

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

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

היום למדתי: שינוי שם ב git

16/11/2021

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

אני בתיקיה חדשה כותב:

$ git init .
$ echo hello > file1.txt
$ git add .
$ git commit -m 'initial commit'

ועכשיו נשנה לקובץ את השם:

$ git mv file1.txt file2.txt
$ git status

On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        renamed:    file1.txt -> file2.txt

$ git commit -m 'rename'

ואפשר לראות את שינוי השם גם בצפיה בלוג:

$ git log -p --oneline

25ccbd7 (HEAD -> main) rename
diff --git a/file1.txt b/file2.txt
similarity index 100%
rename from file1.txt
rename to file2.txt
0e6c0e3 initial commit
diff --git a/file1.txt b/file1.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/file1.txt
@@ -0,0 +1 @@
+hello

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

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

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

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

$ git log -p --oneline --no-renames
25ccbd7 (HEAD -> main) rename
diff --git a/file1.txt b/file1.txt

deleted file mode 100644
index ce01362..0000000
--- a/file1.txt
+++ /dev/null
@@ -1 +0,0 @@
-hello
diff --git a/file2.txt b/file2.txt

new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/file2.txt
@@ -0,0 +1 @@
+hello
0e6c0e3 initial commit
diff --git a/file1.txt b/file1.txt

new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/file1.txt
@@ -0,0 +1 @@
+hello

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

גם diff יכול לקבל אותו טיפול והנה שתי האפשרויות:

$ git diff --name-status HEAD~
R100    file1.txt       file2.txt

$ git diff --name-status --no-renames HEAD~
D       file1.txt
A       file2.txt

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

גבולות

15/11/2021

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

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

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

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