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

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

מצאו את המתחזים!

20/01/2023

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

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

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

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

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

  1. ספרי על הפרויקט האחרון שבנית.

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

  3. איזה פיצ'ר היה לך קשה לממש ולמה.

  4. איזה פיצ'ר היית בטוחה שהולך טוב, אבל נשבר בפרודקשן? מה קרה שם?

  5. ספרי על תקלת פרודקשן מעניינת שטיפלת בה.

  6. איך נראה תהליך פיתוח תוכנה אידאלי בינייך?

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

למה כל כך לאט?

19/01/2023

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

  1. לא מכירים מספיק את הטכנולוגיה.

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

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

  4. הפרויקט דורש שינויים בקוד קיים שלא בנוי לשינויים.

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

  1. אחרי שינוי אני לא יודע מה שברתי.

  2. שינוי במקום אחד דורש שינוי רוחב בעשרות מקומות נוספים.

  3. הקוד כולל מספר מנגנונים שונים כדי לעשות את אותו דבר (לדוגמה פרויקט ווב שגם כולל Inline Style בקומפוננטות ריאקט וגם CSS).

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

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

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

תשתית בתור קוד והחשיבות של הוראות

18/01/2023

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

מדריך מהיר יגיד לכם ליצור משאבים דרך ה AWS Console, עם משפטים כמו:

In the AWS Console, create a new WebSocket API

מדריך נכון יכלול קוד אוטומטי שיוצר את המשאבים:

policy = iam_resource.create_policy(
    PolicyName=f'{lambda_role_name}-{self.permission_policy_suffix}',
    PolicyDocument=json.dumps({
        'Version': '2012-10-17',
        'Statement': [{
            'Effect': 'Allow',
            'Action': ['execute-api:ManageConnections'],
            'Resource': self.api_arn}]}))
policy.attach_role(RoleName=lambda_role_name)

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

חדש באתר: שיעורי הרחבה (במקום וובינרים)

16/01/2023

הי חברים,

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

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

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

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

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

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

גם בעבודה עם ריאקט - Tailwind CSS היא רעיון מעולה

15/01/2023

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

והכח של טיילווינד ביישומי ריאקט הוא שזה פשוט פיתרון הרבה יותר קל והרבה יותר טוב מכתיבת Inline Styles.

בואו נראה איך זה עובד ואיך לשלב את טיילווינד ביישום שלכם.

המשך קריאה

קוד לשימוש חוזר

14/01/2023

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

דוגמה? בשמחה. קחו קוד פייתון שעושה יותר מדי עבודה על משפט:

import re

text = "one two three I want to see three four five I am alive"

# delete all spaces in sentences
text = re.sub(r'\s+', '', text)

# replace each letter by its ordinal value
text = [ord(c) for c in text]

# leave only values that are larger than what came before
new_text = [text[0]]
for value in text:
    if value > new_text[-1]:
        new_text.append(value)

text = new_text

print(sum(text))

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

גירסה מסוכנת יותר של הקוד הזה עשויה להיראות כך:

import re

def main():
    text = "one two three I want to see three four five I am alive"
    text = delete_all_spaces(text)
    text = change_to_ord_values(text)
    text = change_to_increasing(text)
    print_result(text)


def delete_all_spaces(text):
    # delete all spaces in sentences
    text = re.sub(r'\s+', '', text)
    return text

def change_to_ord_values(text):
    # replace each letter by its ordinal value
    text = [ord(c) for c in text]
    return text

def change_to_increasing(text):
    # leave only values that are larger than what came before
    new_text = [text[0]]
    for value in text:
        if value > new_text[-1]:
            new_text.append(value)

    text = new_text
    return text

def print_result(text):
    print(sum(text))


main()

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

רוב הסיכויים שלא.

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

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

מחקר ופיתוח

12/01/2023

בכל החברות אוהבים לקרוא למחלקת תוכנה R&D, קיצור של מחקר ופיתוח. הם רק שכחו להגיד לנו ששני הדברים האלה שונים ודורשים התנהלות שונה:

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

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

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

דו לשוני

11/01/2023

המוכרת בחנות הירקות בברצלונה הסתכלה עליי כאילו נחתתי מאיזה כוכב אחר - Cucmber? Que es eso? היא שאלה, והיה ברור לאן הגעתי. למרות שכל שלט, כל הודעה, כל מכונת כרטיסים וכל היבט אחר של החיים בעיר מתנהל ב-3 שפות (אנגלית, קטלאנית וספרדית), החוליה החלשה היא האנשים שכמו בכל מקום אוהבים את אזור הנוחות שלהם.

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

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

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