fa
Feedback
ToCode

ToCode

رفتن به کانال در Telegram

טיפים קצרים למתכנתים מאת ינון פרק

نمایش بیشتر
1 419
مشترکین
اطلاعاتی وجود ندارد24 ساعت
اطلاعاتی وجود ندارد7 روز
اطلاعاتی وجود ندارد30 روز
آرشیو پست ها
ToCode
1 419
# יש לך טכנאי מזגנים מומלץ? - יש לך הנדימן להמליץ לי? - יש לך טכנאי מזגנים טוב להמליץ? - יש לך טכנאי מזגנים שמכיר טוב מזגני טורנדו? - יש לך טכנאי מזגנים שמכיר טוב מזגני טורנדו ישנים? - יש לך טכנאי מזגנים שמכיר טוב מזגני LG תעשייתיים משנת 2008? שימו לב איך כל שאלה הופכת להיות יותר ספציפית ושימו לב לתחושה שלנו כשאנחנו קוראים את השאלה. ככל שיורדים למטה ברשימה יהיו פחות ספקים שיכולים לעזור לי, ולכן מחיר התיקון יעלה משמעותית. בתור פרילאנסרים בתוכנה אתם יכולים לבחור את המשבצת שלכם. במקום להיות "מתכנתת Mobile" את יכולה לבחור להיות: - זאת שיודעת למצוא ולתקן זליגות זיכרון ביישומי Objective C - זאת שיודעת להתאים את הקוד לכל מכשירי Android שיצאו אי פעם - זאת שיודעת לכתוב פלאגינים ל React Native כדי לחבר יותר יכולות של המכשיר לאפליקציות RN - זאת שיודעת איך לתקן את הקוד כדי שאפל יסכימו להכניס את האפליקציה לחנות הבחירה לעשות משהו מאוד ספציפי שמורה לפרילאנסרים בלבד וזאת ההזדמנות שלנו בהשוואה לשכירים. אם כבר החלטתם להיות פרילאנסרים יהיה לכם הרבה יותר משתלם לשחק את המשחק ולהגיע הכי ממוקדים שאתם יכולים.

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

ToCode
1 419
# הפונקציה reduce וסימן חלוקה ב 19 אחד הפוסטים שעלה היום בהאקרניוז סיפר על סימן חלוקה חמוד ב 19: 1. מסתכלים על מספר מימין לשמאל (סיפרה אחרי סיפרה) 2. כופלים את הסיפרה הימנית ביותר ב 2 ומחברים לה את הסיפרה הבאה 3. את התוצאה כופלים ב 2 ומחברים לה את הסיפרה הבאה 4. וכך ממשיכים עד שהגענו למספר קטן יותר, שאולי לגביו נדע אם הוא מתחלק ב-9. בקוד זה נראה כך:
function reduceMod19(n) {
  let accumulator = 0;
  while (n > 0) {
    let digit = n % 10;
    accumulator = accumulator * 2 + digit;
    n = Math.floor(n / 10);
  }

  return accumulator;
}
הקוד עושה בדיוק מה שהוא צריך לעשות אבל מבחינת קריאות אני חושב שאפשר לשפר: כשאני מסתכל על הלולאה במבט ראשון לא ברור שזו לולאה שרצה על כל הספרות של המספר מימין לשמאל. זה משהו שאני צריך לקרוא ממש את הקוד בשביל להבין אותו. המטרה של פקודת reduce היא להוציא החוצה את הסיפור הזה. לבוא ולהגיד לקורא - שמע יש פה משהו שרץ על כל האלמנטים של הרשימה אחד אחד. יותר מזה, הדבר הזה יחזיר לך תוצאה בודדת שתהיה מושפעת קצת מכל אלמנט. במילים אחרות reduce לוקחת את כל הקוד והופכת אותו למשפט:
digits.reduce((acc, val) => acc * 2 + val, 0);
אני הולך לעבור על כל הרשימה שנקראת digits אחד-אחד, ועבור כל אלמנט אני אכפול את מה שחישבתי עד עכשיו ב-2 ואוסיף את הדבר החדש. כמובן בשביל שזה יעבוד אני צריך להפוך את המספר לרשימה של ספרות מהסוף להתחלה וסך הכל שיכתוב הפונקציה נראה כך:
function reduceMod19(n) {
  let digits = String(n).split('').map(d => Number(d));
  return digits.reverse().reduce((acc, val) => acc * 2 + val, 0);
}
התוצאה היא קוד שמספר טוב יותר את הסיפור שלו: במקום להציג לולאה כללית בה אני צריך להתאמץ כדי להבין מה המבנה, אני מקבל כאן מבנה מאוד ספציפי וצריך להתאמץ רק בשביל להבין מה עושים עם כל אלמנט. כמובן שמשיקולי ביצועים קשה להאמין שהייתי כותב קוד כזה בעולם האמיתי בהקשר הזה של סימן חלוקה ב 19, ובכל זאת שווה להתרגל לשתי הגישות ולהתיחס ל reduce בתור עוד סוג של לולאה - לולאה שמספרת סיפור יותר משמעותי מעוד לולאת for.

ToCode
1 419
# איך להפוך את כתיבת ה CSS לקצת פחות מתסכלת מתכנתים לא אוהבים לכתוב CSS ויש לזה כל מיני סיבות. אפילו אנשי Front End רבים שפגשתי העדיפו להתמקד בצד הטכני יותר של פיתוח JavaScript או React ולהשאיר את ה CSS למעצבים. במקביל ככל שהעולם של ה CSS התפתח כך זה רק עוד יותר הפחיד רבים מאיתנו: עכשיו ללמוד Flexbox ו grid? ובאיזה דפדפנים כל דבר עובד? וממילא מה שאני לא אעשה זה לא יראה טוב אז בשביל מה להתאמץ. צריך להגיד לכתוב CSS כשלא יודעים CSS זו באמת חוויה קשה, וגם כשיודעים CSS יש בכתיבה שלו אתגרים שונים מאלה של כתיבת קוד. הנה כמה טיפים שעוזרים לי להיות פחות מתוסכל כשאני כותב CSS ואני מקווה שיעזרו גם לכם: ## חברו עוד מסך כתיבת CSS היא תהליך ויזואלי זה אומר שאנחנו חייבים לראות את התוצאה בזמן שכותבים את הקוד. אם אתם כל הזמן עוברים בין החלון של ה IDE לחלון של הדפדפן יהיה לכם קשה להתרכז ותתעייפו יותר מהר. בכתיבת CSS כדאי להשתמש מינימום בשני מסכים (אם יש יותר זה תמיד טוב): אחד לדפדפן והשני ל IDE. אני לא אוהב להשתמש בדפדפן בתור IDE למרות שכלי הפיתוח של דפדפנים היום די טובים, אבל אם אתם כן אוהבים זה בסדר - פשוט הפרידו את כלי הפיתוח לחלון נפרד מהדפדפן ושימו אותם על המסך השני. טריק נוסף שעוזר לא לעייף את העיניים הוא כפתור Device Mode בכלי הפיתוח: במקום להגדיל ולהקטין את החלון אתם פותחים Device Mode ומגדילים ומקטינים רק את החלק שמראה את האתר. כך גם שאר הטאבים שלכם נשארים בגודל הרגיל וגם אתם רואים תמיד את הגודל האמיתי עליו אתם מפתחים. ## הפעילו Hot Reloading בהנחה שאתם משתמשים ב IDE חיצוני הדבר האחרון שאתם רוצים זה ללחוץ F5 אחרי כל שינוי. חברו את החוטים כדי לקבל Hot Reloading כלומר שכל פעם שאתם שומרים בצורה מיידית חלון הדפדפן מתעדכן. היום יש ל Webpack כבר מנגנון שאפילו לא טוען מחדש את העמוד כשה CSS מתעדכן, כך שאתם יכולים לשנות CSS ולראות את ההשפעה מיד בלי לאבד פעולות שעשיתם ב JavaScript או טקסט שהכנסתם בשדות. ## אל תשתמשו ב Framework אחת הסיבות המרכזיות לתיסכול בכתיבת CSS היא הצורך לריב עם הפריימוורק או יותר נכון לנהל ציפיות. כולם אומרים שעם Twitter Bootstrap תוכלי לבנות אתר תוך רגע, והנה את כבר שלושה ימים מנסה לארגן את הגריד שיראה כמו שצריך. סיבה שניה לתסכול היא שיש כל כך הרבה Frameworks כך שכשלא הולך עם אחד אנחנו מתפתים לנסות עוד אחד ועוד אחד וככה במקום לבנות אתר אנחנו רק נתקעים על בחירת פריימוורק. האמת שעם היכולות של CSS היום צריך מעט מאוד האקים כדי שדברים יעבדו ויראו טוב. אם אתם יודעים להשתמש כמו שצריך ביכולות של CSS יהיה לכם יחסית קל לבנות כל עיצוב שאתם צריכים. ## לימדו CSS וכאן אנחנו מגיעים לאחד הטיפים הכי חשובים: קשה מאוד לכתוב קוד כשלא מכירים את השפה (אתם כבר יודעים את זה בתור מתכנתים) - ואותו הכלל תופס גם לגבי CSS. לכל פסיק ב CSS יש משמעות והסבר. ואני יודע ש CSS זה אוקיינוס ויש הרבה יכולות והרבה מאפיינים עם שהמשמעות שלהם לא אינטואיטיבית (היוש z-index); ועדיין העצה לגבי קוד תופסת כאן: מצאתם פוסט או תשובה ב Stack Overflow שמסבירים איך לעשות משהו? עכשיו לכו לקרוא בתיעוד ב MDN מה כל מילה בפיתרון אומרת כדי שתוכלו לכתוב את ה CSS הזה אצלכם וגם להתאים אותו לאתר שלכם. (מחפשים בסיס טוב ב CSS ואל בטוחים איפה להתחיל? נו יש לנו קורס לזה. הוא נקרא Front End ויש בו פרק די טוב על CSS, כולל היסודות וגם הנושאים החדשים כמו flexbox ו grid). יש לכם טיפים נוספים שהופכים את כתיבת ה CSS לחוויה נעימה יותר? ספרו לי בתגובות כדי שגם לי יהיה קל בחיים.

ToCode
1 419
# לא להאמין ש C++ קיבלה את האופרטור הזה לפני JavaScript כבר שנים שמדברים על אופרטור ה Pipeline ב JavaScript שיהפוך את הכתיבה הפונקציונאלית בשפה לקלה יותר, אבל נכון להיום הוא עדיין ב stage 1 ולא נראה שמתקדם. והנה פתאום פגשתי את המשפט הבא בתיעוד על ranges של C++20: > Range adaptors accept viewable range as their first arguments and return a view. If an adaptor takes only one argument, it can also be called using the pipe operator: if C is a range adaptor object and R is a viewable_range, these two expressions are equivalent: ואם אתם לא בטוחים מה זה אומר הם גם נותנים שם את דוגמת הקוד הבאה להמחשה:
#include <vector>
#include <ranges>
#include <iostream>
 
int main()
{
    std::vector<int> ints{0,1,2,3,4,5};
    auto even = [](int i){ return 0 == i % 2; };
    auto square = [](int i) { return i * i; };
 
    for (int i : ints | std::views::filter(even) | std::views::transform(square)) {
        std::cout << i << ' ';
    }
}
שימו לב לקו האנכי: 1. מתחילים בוקטור של המספרים מ-0 עד 5. 2. שולחים אותו לפונקציה filter כדי להשאיר רק את המספרים הזוגיים. 3. את התוצאה שולחים לפונקציה transform (שבכל מקום אחר היינו קוראים לה map) ומפעילים את square על כל אחד מהמספרים הזוגיים שקיבלנו סך הכל יודפס:
0 4 16
נו, אז האם C++ הולכת להיות מגניבה שוב? קשה לי לראות את זה קורה. ועדיין נחמד לראות תבניות שאני אוהב מוצאות את דרכן לעוד שפות.

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

ToCode
1 419
# אליאס לקובץ האחרון הרבה פעמים אני מוצא את עצמי רוצה להגיד משהו על הקובץ העדכני ביותר, דוגמה פשוטה היא כניסה לתיקיית ההורדות ושם אני רוצה לפתוח את הקובץ האחרון שהרגע הורדתי. בסייר הקבצים היינו יכולים בקלות לסדר את הקבצים לפי תאריך יצירה ופשוט ללחוץ על הקובץ הראשון או האחרון ברשימה. אבל מה עושים משורת הפקודה? הפקודה הראשונה שקופצת לראש היא ls -t שמסדרת את רשימת הקבצים לפי תאריכי עדכון. הפקודה הבאה מציגה את 3 הקבצים העדכניים ביותר בתיקיה:
$ ls -rtlh | tail -3
אבל זה עדיין דורש copy-paste אם רוצים "לעשות משהו" עם הקובץ האחרון. עד שאנחנו נזכרים בסימן ה $() המופלא של bash. אם הדבר העדכני ביותר הוא תיקיה אז הפקודה הבאה תיכנס אליה:
cd $(ls -rt | tail -1)
ובשביל שיהיה קל יותר להשתמש ברצף אני יוצר עבורו alias:
alias latest='ls -rt | tail -1'
ועכשיו אפשר לכתוב פקודות כמו:
rm $(latest)
כדי למחוק את הקובץ האחרון שהורדתי, או:
$ xdg-open $(latest)
כדי להריץ אותו בתוכנית ברירת המחדל של המערכת.

ToCode
1 419
# הצהרת כוונות יותר מדי פעמים ובמיוחד בשפות דינמיות אנחנו משתמשים בקוד גנרי מדי בלי להצהיר על הכוונות שלנו - מה שמוביל לבאגים לא צפויים שלפעמים גם קשה למצוא אותם. הסיפור שלנו היום קשור לתרגיל רדוקציית פולימרים. המשימה בתרגיל היא לקבל מחרוזת של אותיות באנגלית ולחפש בה רצפים של אות גדולה ומיד אחריה אותה אות בקטן, או ההיפך, אות קטנה ומיד אחריה אותה אות בגדול - לדוגמה aA, Bb, fF וכן הלאה. כל פעם שמוצאים רצף כזה יש למחוק אותו ואז להמשיך בלולאה לחפש רצפים במחרוזת החדשה שהתקבלה. בעזרת while וגישה דרך אינדקס למחרוזת הפיתרון עשוי להיראות פשוט:
def reduce_polymer(polymer):
    i = 0
    while i < len(polymer) - 1:
        if reducts_with(polymer[i], polymer[i+1]):
            polymer = polymer[0:i] + polymer[i+2:]
            i -= 1
            continue

        i += 1

    return polymer
    

def reducts_with(unit1, unit2):
    return abs(ord(unit1) - ord(unit2)) == 32
ובגלל שאני אחד שתמיד טועה באינדקסים הלכתי גם לכתוב תוכנית בדיקה קצרה:
from aoc2018day5 import reduce_polymer


def test_aA():
    assert reduce_polymer("aA") == ""


def test_bug():
    assert reduce_polymer("aAff") == "ff"


def test_abBA():
    assert reduce_polymer("abBA") == ""


def test_abAB():
    assert reduce_polymer("abAB") == "abAB"


def test_dabAcCaCBAcCcaDA():
    assert reduce_polymer("dabAcCaCBAcCcaDA") == "dabCBAcaDA"
שעברה בלי בעיה. עכשיו קחו רגע לחזור להסתכל על הפיתרון ונסו למצוא את הבאג. ... עוד לא מצאתם? שימו לב לאינדקסים ... הבעיה היא כמובן השורה i -= 1. אם הרדוקציה מופיעה בתו הראשון במחרוזת, i הופך שלילי ואז הפעם הבאה שנחפש תווים נסתכל על אלמנטים מהסוף וכל הלוגיקה תישבר. הקוד הבא למשל מכניס את הפונקציה ללולאה אינסופית:
if __name__ == "__main__":
    print(len(reduce_polymer("aAaAffaA")))
כשאני מסתכל על קוד כזה מה שמטריד אותי הרבה לפני שאני ניגש לתקן את הבאג זה איך להפוך את הבאג הזה ליותר ברור, איך לשנות את הקוד כך שיהיה ברור שיש שם בעיה הרבה לפני הלולאה האינסופית. וכאן אנחנו מגיעים לדבר על הצהרת כוונות: 1. בשורת התנאי אנחנו בונים על זה ש i אינו שלילי, אבל לא מוודאים את זה. 2. בשורת המחיקה אנחנו בונים על זה ש i אינו שלילי, ושוב לא דואגים לספר על זה לאף אחד. שינוי ראושן של הקוד יקרב אותנו לכתיבה נכונה גם בלי לפתור את הבעיה:
def reduce_polymer(polymer: str) -> str:
    i = 0
    while i < len(polymer) - 1:
        if has_reduction(polymer, i):
            polymer = remove_reduction(polymer, i)
            i -= 1
            continue
        i += 1
    return polymer


def has_reduction(polymer: str, i: int):
    if not 0 <= i < len(polymer) - 1:
        raise ValueError(f"Index should be >= 0, got {i}")
    unit1 = polymer[i]
    unit2 = polymer[i + 1]
    return abs(ord(unit1) - ord(unit2)) == 32


def remove_reduction(polymer: str, i: int):
    if not 0 <= i < len(polymer) - 1:
        raise ValueError(f"Index should be >= 0, got {i}")
    return polymer[0:i] + polymer[i+2:]
עכשיו אותה תוכנית בדיקה שקודם עברה בלי בעיה כבר נכשלת עם הודעת שגיאה על האינדקס השלילי - וזה מעולה, כי כשהבדיקה נכשלת אנחנו כבר ב 90% מהפיתרון. והלקח הכללי יותר מהסיפור? בעבודה עם פונקציות שילוב של Type Hints עם בדיקת קלט בכניסה לפונקציה יכול לעזור לנו למצוא בעיות בקוד הרבה יותר מהר.

ToCode
1 419
# איך לשמור שלא יוסיפו לכם Attribute בטעות למחלקה בפייתון בפוסט שעלה לא מזמן ב Python Tips הציע יהונתן להגדיר slots כדי לבנות אוביקטים קטנים יותר. תוצאת לוואי מעניינת של הפיצ'ר היא שהוא מונע מאנשים להוסיף בטעות Attribite לאוביקט. אם אתם משתמשים ב Type Hints (מה זה אם!? ברור שאתם משתמשים ב Type Hints), תשמחו לשמוע שיש דרך פשוטה יותר לקבל את אותה תוצאת לוואי בצורה שגם מסתדרת טוב עם ירושה, גם מאפשרת וידוא טיפוסים וגם כוללת כמה פינוקים ברמת הקוד. אני מדבר על הדקורטור dataclass. בואו נראה איך הוא עובד. נניח שיש לנו מחלקה בשם Person ולכל אוביקט מסוג Person אנחנו רוצים להגדיר את השדות: 1. שדה id מסוג int. 2. שדה name מסוג str. 3. שדה friends מסוג מערך של Person. הקוד באמצעות Type Hints יראה כך:
from typing import List

class Person:
    id: int
    name: str
    friends: List['Person']
ורק עד לפה אנחנו כבר מקבלים המון עזרה מ mypy כשמנסים לעשות שטויות שאסור עם Person:
p = Person()
x = Person()
y = Person()

# Works great
p.id = 0
p.name = 'test'
p.friends = [x, y]

# Fails: 10 is not a Person
p.friends.append(10)

# Fails: foo is not a valid attribute
p.foo = 'bar'
הפעלה של mypy על הקוד נותנת:
a.py:22: error: Argument 1 to "append" of "list" has incompatible type "int"; expected "Person"
a.py:25: error: "Person" has no attribute "foo"
ואפשר היה לסיים פה את הפוסט אבל מה שבאמת משדרג את הגישה זה הדקורייטור dataclass. ברגע שאוסיף אותו אני מקבל: 1. פונקציית __init__ אוטומטית שמקבלת את כל הפרמטרים שהגדרתי למחלקה 2. פונקציית __repr__ אוטומטית שמחזירה ייצוג ידידותי של האוביקט 3. פונקציית __eq__ שבודקת שיוויון לפי כל אחד מהשדות 4. פונקציה בשם dataclasses.asdict שלוקחת כל Data Class ומחזירה dict עם כל המאפיינים שלו. סך הכל אחרי המרה לשימוש ב dataclass המחלקה שלי נראית כך:
from typing import List
from dataclasses import dataclass, field
import dataclasses


@dataclass
class Person:
    id: int
    name: str
    friends: List['Person'] = field(default_factory=list)


p = Person(0, 'foo')
x = Person(1, 'bar')
y = Person(2, 'buz')

print(dataclasses.asdict(p))
בזכות פונקציית __init__ שנוצרה אוטומטית אני יכול ליצור אוביקטים של Person ולהעביר אליהם את כל הפרמטרים עבורם לא מוגדר ערך ברירת מחדל (ויש Type Hint שמוודא את זה), ואני יכול לקרוא ל asdict כדי לקבל את id, name ו friends בתוך dict. למידע נוסף על dataclasses שווה לקרוא את דף התיעוד בקישור: https://docs.python.org/3/library/dataclasses.html

ToCode
1 419
# למה לא מזמינים אותי לראיון עבודה כשאנחנו שולחים קורות חיים למשרה הבן אדם שמקבל את הדף לא יודע עלינו כמעט כלום, ואם זה לא מספיק קשוח אותו בן אדם בצד השני של הקו בדרך כלל יצטרך לעבור על עשרות קורות חיים ביום כדי לסנן ולגייס. לכן מגייסים (אנשי HR וגם מנהלים טכניים) למדו לחלק לעצמם בראש את המועמדים לקטגוריות. מה שחשוב לזכור בחלוקה לקטגוריות זה שהיא קורית ממש מהר, ומשפיעה על האופן בו יקראו את כל קורות החיים שלכם. הנה רשימה קצרה של קטגוריות לדוגמה כדי שנבין על מה אנחנו מדברים כאן (הכל מנוסח בלשון זכר בשביל שיהיה נוח לכתוב, גם נשים נופלות בדיוק לאותן קטגוריות אל תדאגו): ## הנינג'ה הנינג'ה התחיל ללמוד לתכנת עוד בתור ילד, פתח את הסטארט-אפ הראשון בתיכון ולאוניברסיטה הוא הלך כי עניין אותו ללמוד על אלגוריתמים וסיבוכיות. בצבא הוא היה ב 8200 כמובן ובשנים האחרונות עבד בחברות ההייטק המפורסמות ברף הקבלה הגבוה שלהן. לנינג'ה יש ניסיון בדיוק בטכנולוגיה שאתם מחפשים, הוא כבר הוכיח את עצמו בתפקידים דומים והוא יכול לבד לבנות מוצר שביום רגיל היה דורש צוות של 5. חסרונות? הוא מחוץ לתקציב שלכם ורגיל לתרבות העבודה בגוגל. ## החרגול החרגול הוא מתכנת טוב שבגלל צירוף נסיבות ומזל רע יצא שעבד ב-5 מקומות שונים בשנתיים האחרונות: חברה אחת נסגרה, באחרת סגרו את הפרויקט שהוא עבד עליו, בשלישית היה לו בוס מהגיהנום, באמצע העבודה בחברה הרביעית נולד לו ילד ראשון והוא רצה להקדיש יותר זמן למשפחה והמעסיק האחרון הוציא אותו לחל"ת בגלל הקורונה. החרגול מגיע עם ניסיון רלוונטי ונראה שעבד על פרויקטים מעניינים. הרבה פעמים יהיה לו גם פרויקט צד טוב להראות, כל הסיבות בגללן כמעט אפשר יהיה לשכוח מההיסטוריה הבעייתית שלו. ## המשקיען המשקיען יגיע אליכם אחרי שסיים בהצטיינות תואר שני ועם המלצות טובות מהמעסיקים הקודמים שלו. זה הבן אדם שנשאר תמיד יותר שעות במשרד, מתעקש להכניס שיטות עבודה מודרניות ואף פעם לא יכתוב Fixed some stuff בהודעת קומיט. ## הנתקע הנתקע בדיוק עזב מקום עבודה מאוד נוח אחרי עשר שנים ועכשיו מחפש את האתגר הבא שלו. על הנייר יש לו את הניסיון שאתם מחפשים אבל לא בדיוק מתאים בגירסאות - הוא עבד עשר שנים ב CSS אבל עדיין לא מכיר פלקסבוקס כי המוצר שלהם היה מיועד לשוק הארגוני ודרש תמיכה בדפדפני IE ישנים. הבעיה המרכזית של הנתקע היא שהוא עדיין לא מבין את הפער בין הכלים שהוא מכיר לכלים שאתם צריכים - ומבחינתו ES6 זה רק עוד Syntax ללמוד ("לא עבדנו עם זה ביום יום אבל קראתי קצת ואני מכיר את המילים החדשות"). חסרונות? הפער הרבה יותר גדול ממה שהוא מדמיין. ## הצעיר הנלהב קורות החיים של המועמד הצעיר הנלהב מלאים ב Buzz Words: הוא כבר כתב פרויקטים ב React, Angular, Vue וגם ב Svelte. הוא השתמש ב Node.JS, כתב Lambda Functions, שמר מידע על S3 וב Redshift והשתמש ב SNS כמובן. יש לו 5 פרויקטי צד על גיטהאב הכוללים שימוש באינסוף פריימוורקים וחבילות תוכנה. אם מישהו כתב על זה פוסט ב Hackernews תהיו בטוחים שזה יופיע אצלו בקוד. אם תישבו בקסמיו הצעיר הנלהב הולך להיכנס לפרויקט שלכם כרוח סערה ויתבל את הפרויקט במיקרו סרביסים ואינסוף ספריות קוד וכמובן Design שמתכנן עשר שנים קדימה. חסרונות? בהיעדר ניסיון אמיתי והבנה רצינית של הבסיס, הצעיר הנלהב יעשה טעויות שיעלו לכם הון. בואו נגיד שאני לא הייתי מתנדב לתחזק את הקוד שלו. ## למי אכפת ומה עושים אם אתם לא מצליחים לקבל זימונים לראיונות סיבה אחת יכולה להיות שהקורות חיים שלכם מקוטלגים בקטגוריה הלא נכונה. אם רוב האנשים שקוראים את הקורות חיים שלכם מרגישים שעומד מולם הצעיר הנלהב, אז לא משנה כמה פרויקטי-צד ו Buzzwords תוסיפו זה פשוט לא יעזור לכם. למעשה אתם רק מחמירים את המצב. מצד שני אם מי שקורא את הקורות חיים מרגיש שמולו יושב המשקיען או הנינג'ה אולי הוא יחוש מאוים מרשימת ההישגים ויחשוב שאתם Over Qualified. ואם בטעות קיטלגו אתכם בתור חרגול הסיכוי שיזמינו אתכם לראיון הוא שוב לא גבוה כי אנשים פוחדים להיות האקס הבא שלכם. אז מה עושים? קודם כל צריך להיות מודעים. אין אף אחד בתעשיה שיגיד "מצטער לא התקבלת כי אתה מקפץ בין עבודות", תמיד יהיו לאנשים דרכים יפות להתנסח. אבל ברגע שאתם מודעים לחלוקה אתם יכולים לנסות לזהות איך אנשים תופסים אתכם, לנסות לנחש כמו מה הקורות חיים שלי נראים? את מי הם מזכירים? אחרי זה אפשר להתקדם ל"את מי אני רוצה שהם יזכירו?" ומה אני צריך לעשות כדי שקורות החיים שלי יהיו יותר דומים לקטגוריה אליה אני רוצה להשתייך.