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

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

אנחנו בונים

19/11/2024

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

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

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

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

כמה באמת עולה כרטיס לוטו?

18/11/2024

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

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

  1. "אם לא תנסה איך תזכה"

  2. "זה רק 20 ש"ח, חבל לא לנסות"

  3. "ממילא אין לי משהו אחר לעשות עם הכסף"

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

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

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

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

סקאלת הישגיות - סקרנות

17/11/2024

  • הולך ל Chat GPT ומבקש פיתרון.

  • הולך ל Chat GPT ומבקש 3 פיתרונות, עם יתרונות וחסרונות של כל אחד כדי שאוכל לבחור את הטוב ביותר.

  • הולך ל Chat GPT ומבקש כיוון כללי לפיתרון. את השאר אמצא בגוגל ובתיעוד.

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

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

  • כותב לבד קוד אמיתי אחרי מחקר וכתיבת POC, ואז מוסיף בדיקות ותיעוד.

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

קל מדי זה לא סימן טוב

16/11/2024

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

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

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

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

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

ארבעה דברים שממש אהבתי ב Nuxt

14/11/2024

נוקסט היא גירסת ה Full Stack של Vue המאפשרת פיתוח יישומים מלאים עם Server Side Rendering. אני חייב להודות שכשהתחלתי לשחק עם הפריימוורק הייתי בטוח שאני הולך לפגוש עוד next.js ושמחתי למצוא מספר פיצ'רים ייחודיים שמיד עשו חשק ללמוד יותר. אלה הדברים שכבר ממבט ראשון על nuxt אהבתי במיוחד:

  1. יבוא אוטומטי - כן אני יודע VS Code משלים פקודות import בלי מאמץ ובכל זאת אין קוד תמיד עדיף על קוד שנכתב מהר. קטע כזה עובד ב nuxt בלי שנצטרך להוסיף שום פקודת import:
<script setup lang="ts">
/* ref() and computed() are auto-imported */
const count = ref(1)
const double = computed(() => count.value * 2)
</script>
  1. מערכת מודולים מובנית - לקח לי שתי לחיצות להוסיף את Tailwind לאפליקציית ה nuxt שבניתי דרך מנגנון המודולים שלהם. יש מודולים לחיבור לבסיסי נתונים, לחיבור לפורטלי תשלום, לניהול משתמשים, מוניטורינג של האפליקציה ועוד.

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

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

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

זהירות פלסטר - מתוקן

12/11/2024

המתכון הוא פשוט-

  1. כותבים קוד תשתית.

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

  3. מתקנים את התשתית.

  4. בונים את הפיצ'ר עם התשתית החדשה.

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

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

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

לא שוב טייפסקריפט

11/11/2024

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

<script setup lang="ts">
const props = defineProps<
  | {number: number}
  | {text1: string, text2: string}>();

const text1 = "number" in props ? String(props.number) : props.text1;
const text2 = "number" in props ? "Great Number!" : props.text2;
</script>

<template>
  <p>{{ text1 }}</p>
  <p>{{ text2 }}</p>
</template>

והקריאה לקומפוננטה עשויה להיראות כך:

<Demo :number="5" />
<Demo text1="hello" text2="world" />

זה עבד מבחינת טייפסקריפט אבל הקוד עצמו נכשל. בהגדרת props עם defineProps ב Vue, אוביקט הפרופס תמיד מכיל את כל הפרופס האפשריים, כלומר בשתי ההפעלות הוא יקבל גם את number, גם את text1 וגם את text2, פשוט בהפעלה הראשונה number מקבל את הערך 5 והטקסטים יהיו undefined ובהפעלה השניה זה number שיהיה undefined והטקסטים מקבלים את הערכים הנכונים שלהם.

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

const text1 = props.number ? String(props.number) : props.text1;
const text2 = props.number ? "Great Number!" : props.text2;

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

const props = defineProps<
  | {number: number, text1?: never, text2?: never}
  | {number?: never, text1: string, text2: string}>();

const text1 = props.number ? String(props.number) : props.text1;
const text2 = props.number ? "Great Number!" : props.text2;

הקוד הזה עובד ובנוסף יש לנו בדיקת טייפסקריפט טובה. שתי השורות האלה תקינות:

<Demo :number="5" />
<Demo text1="hello" text2="world" />

ושלושת אלה מראות פס אדום על הקומפוננטה כדי שנזהה הפעלה לא נכונה:

<Demo :number="5" text1="hello" text2="world"  />
<Demo text1="hello"  />
<Demo  />

הבעיה עם עצות גרועות

10/11/2024

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

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

  1. עצה גרועה תשתמש בז'ארגון לא מובן ותנצל פערי ידע בין היועץ למקבל העצה.

  2. עצה גרועה הרבה פעמים כן תפתור בעיה, פשוט לא את הבעיה שלך (זה מה שגורם לה להיות מבלבלת).

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

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

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

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