שאלות מראיונות עבודה: משולש כוכבים
את השאלה הזאת נתתי בתרגיל באחד הקורסים והפתיע אותי לגלות שיותר אנשים מסתבכים איתה ממה שחשבתי שיקרה. בואו נראה את השאלה, כמה כיוונים לא נכונים ואז את הכיוון הנכון.
טיפים קצרים וחדשות למתכנתים
את השאלה הזאת נתתי בתרגיל באחד הקורסים והפתיע אותי לגלות שיותר אנשים מסתבכים איתה ממה שחשבתי שיקרה. בואו נראה את השאלה, כמה כיוונים לא נכונים ואז את הכיוון הנכון.
אם היה בית ספר לפרילאנסרים הוא בטוח היה נראה אחרת לגמרי מבתי הספר שיש לנו היום, ואולי שם גם היו מספרים לכם את הכלל הפשוט של פרילאנסרים שאף אחד לא סיפר לי - וזה שמסלול הקידום של פרילאנסרים שונה ממש ממסלול הקידום של שכירים.
בדרך כלל כשאנשים מהדור שלי חושבים על קריירה אנחנו מדמיינים מסלול שמתחיל במשרה זוטרה באיזה חברה, ואז לאט לאט מתקדמים: ממתכנת לראש צוות, מראש צוות לראש קבוצה, וכך הלאה במעלה ההיררכיה האין סופית. כל שלב נוסף שעלית בהיררכיה מעניק שכר גבוה יותר, חיים נוחים יותר והטבות מפנקות יותר בהשוואה לזה שלפניו.
אבל לפרלאנסריות (ופרילאנסרים) זה לא עובד ככה.
בהיעדר מסלול קידום מסודר הדרך היחידה של פרילאנסרית להתקדם ל"שלב" הבא תהיה לשנות משהו מהותי בהתנהלות שלה: לשנות את הגישה ללקוחות, לקחת עובדים, להוסיף אוטומציה או למצוא לקוחות אחרים. הבעיה ששינוי כזה כמעט תמיד יגרור תקופה של הסתגלות לשינוי בה תרוויחי פחות ממה שהרווחת בעבר. זה כאילו אנחנו לוקחים כמה צעדים אחורה בשביל לקחת תנופה ולקפוץ קדימה. והתנופה הכרחית. מתכנתת פרילאנסרית שעד עכשיו בנתה אתרים ומרגישה (בצדק) שהיא תרוויח יותר מייעוץ לחברות, תצטרך קודם להפסיק לבנות אתרים ולפנות לה זמן כדי למצוא את החברה הראשונה שתסכים לשלם לה על ייעוץ. ואז בחודשים הקרובים אותה פרילאנסרית צריכה לבנות את עצמה מאפס בנישה החדשה, וכך בונים את התנופה. כן, אחרי הקפיצה יהיו לה לקוחות טובים יותר שישלמנו יותר על כל שעה, אבל התהליך לא היה לינארי.
צעד אחורה, שניים קדימה. זה הטנגו ההפוך של הפרילאנסרים וכדאי להתרגל אליו אם אתם מתכננים להתקדם במסלול הזה.
כשאתם נתקלים בבעיה קשה יש לכם שתי דרכים מרכזיות להמשיך - הראשונה היא לפתור אותה, והשניה למצוא מעקף (לפעמים אפשר גם לוותר ולחזור לזה אחר כך. אבל לא תמיד).
ברוב המקרים אפשר למצוא מעקף הרבה יותר מהר מאשר למצוא את הפיתרון האמיתי של הבעיה. לדוגמא כשהמערכת מגישה תוכן ישן הכי קל לבטל או לנקות את ה Cache. כשצריכת הזיכרון עולה הכי קל לסגור ולפתוח את השרת, או כשמנגנון אבטחת מידע מסוים מפריע לנו לכתוב את הקוד שאנחנו רוצים הכי קל לכבות את המנגנון. הרבה פעמים בתוך הלחץ של הדדליינים אנחנו שמים את המעקף רק כפיתרון זמני ומקווים לחזור לפיתרון האמיתי כשיהיה זמן. זה נקרא חוב טכני ומסתבר שאנחנו די גרועים בלהחזיר אותו, כי אף פעם אין זמן.
האלטרנטיבה לא יותר קלה - לרוץ עם הראש בקיר ולקוות שהקיר (כלומר הבעיה) יישבר לפני הראש. בעיות קשות באמת יכולות לקחת ימים וגם שבועות עד שפותרים אותן. היתרון? בהנחה שהראש שלכם נשאר בחתיכה אחת, תוכלו ללמוד די הרבה מהתהליך ולהפוך למתכנתים הרבה יותר מקצועיים לקראת הקיר הבא.
בן אדם קם בבוקר ומחליט לפתוח סטארט-אפ. או לפחות חושב על זה, כי היום עם כל הסטארט אפים מסביב לכל אחד יש חבר שמכר סטארט אפ. בקיצור בן אדם קם בבוקר ואומר ״כמו שלהוא הלך ולהיא הלך, וואלה גם אני יכול״. ובתשעים ותשעה אחוזים מהמקרים עד הצהריים זה עובר.
אותה תופעה אגב קורית גם כשהחלטת להקליט קורס וידאו חדש, להתחיל ללמוד נושא חדש מאפס או ללכת למכון כושר. אנחנו ממש גרועים בלהתחיל דברים חדשים ולהתמיד בהם עד שרואים תוצאות.
אז מה עושים? הנה כמה טריקים שעוזרים לי, מוזמנים לנסות אותם וגם להוסיף את שלכם בתגובות:
למצוא לקוח (או מאמן כושר), כלומר מישהו שישב לכם על הווריד עד שדברים יתקדמו.
לרשום התקדמות גם כשהיא לא שם - לדוגמא במקום להתבאס שאתם לא מצליחים להתקדם בכתיבת הספר שאתם רוצים, אפשר לרשום כל יום כמה שעות עבדתם בטבלת אקסל ולצייר אימוג'ים חמודים כל X שעות.
להשקיע בתהליך ולא בתוצאה - לדוגמא במקום להחליט שאתם מתחילים היום ללמוד פייתון תחליטו שאתם מתחילים היום להשקיע שעה ביום בפיתרון תרגילים בשפת תכנות שאתם לא מכירים, והראשונה תהיה פייתון. ברגע שהתהליך הוא אינסופי אנחנו פחות מתבאסים כשההתקדמות היא איטית מדי.
ליצור תשתית בספרינטים - לדוגמא כשהחלטתי להתחיל לכתוב בלוג הדבר הראשון שעשיתי היה להגדיר את עורך הטקסט כך שבלחיצת כפתור הפוסט יגיע מהעורך לאתר. זה לקח כמה שעות של עבודה אבל נתן את התשתית שמאפשרת לי לכתוב בצורה עקבית.
לנסות כמה פעמים - הכי חשוב לא להתבאס כשאתם מוצאים את עצמכם שהתחלתם ללמוד משהו חדש ואז הפסקתם לכמה חודשים כי היה עומס. זה קורה לכולם. עכשיו אפשר לנסות שוב.
יש קטע למתכנתים שאנחנו אוהבים לקטר כמה השפה החדשה שאנחנו באים ללמוד מסובכת או מוזרה כי היא שונה מהדבר הקודם. יש וידאו מפורסם שמקטר על JavaScript שנקרא wat ואתם בטח מכירים אבל אם לא זה הקישור:
https://www.destroyallsoftware.com/talks/wat
אבל עזבו הרבה לפני אנשים קיטרו שבפרל פעולת החיבור לא אינטואיטיבית כי היא מנסה תמיד להמיר את האופרנדים למספרים ולכן הקוד הבא מדפיס אפס:
my $x = 'one';
my $y = 'two';
print($x + $y, "\n");
או שב Rails יש הבדל משמעותי בביצועים בין הפקודה count ל size, או על איך שבפייתון תחום ההגדרה של משתנים הוא פונקציה ולא בלוק ולכן הקוד הבא מדפיס 9 (אפילו שההדפסה כתובה אחרי הלולאה):
for i in range(10):
pass
print(i)
ולכולכם יש לי רק דבר אחד להגיד - תפסיקו להאשים את השפה. אין בזה היגיון וזה גם לא מעניין. במקום זה קחו את הזמן שצריך בשביל ללמוד את השפה לעומק, להבין את הסיבות לבחירות שנראות לכם היום מוזרות ולראות את היתרונות והחסרונות של בחירות אלה בהשוואה לדברים שאתם רגילים אליהם מהשפה שלכם.
הזדמנויות הלמידה הכי מעניינות שלי מגיעות מרגעי Wat של שפה וההבדלים בין השפות הם שהופכים את המשחק למעניין.
השאלה הכי חשובה כשבאים ללמוד כל נושא היא "בשביל מה צריך את זה?". זאת גם השאלה שתלמידים מרגישים הכי לא בנוח לשאול, ואני הכי אוהב לשמוע.
קשה מאוד להבין את Git בלי להבין את הבעיות של פיתוח פרויקט קוד פתוח גדול. או בדוגמא אחרת - כדאי מאוד שתבינו את הבעיות בירושה ואת הסכנה של דריסת משתני מחלקה לפני שתקראו על ההתנהגות המוזרה של פייתון כשמגדירים משתנה מחלקה שמתחיל בקו תחתון כפול.
אם אתם לא מבינים בשביל מה צריך את זה אין טעם לקרוא עוד. קחו צעד אחורה, תבינו מה הבעיה שאתם מנסים לפתור ורק אחר כך תמשיכו ללמוד על הפיתרון.
אחד הדברים הנחמדים שאנחנו מקבלים משימוש בביטויים רגולאריים בתוך שפת תכנות הוא היכולת להריץ קוד כחלק מתהליך החלפת הטקסט שביטוי רגולארי זיהה.
בפייתון הפונקציה re.sub
היא שעוזרת לנו להחליף את הטקסט שהתאים לביטוי רגולארי מסוים בטקסט אחר. למשל הפונקציה הבאה מקבלת טקסט עם סימן קו תחתי שמפריד בין המילים והופכת כל קו תחתי לרווח:
import re
def underscore_to_spaces(text):
pat = re.compile('_')
return pat.sub(' ', text)
אבל מה אם נרצה בנוסף גם להחליף את האות הראשונה בכל מילה באות גדולה? פה יש בעיה כי כל מילה יכולה להתחיל באות אחרת.
בדיוק בשביל זה הפונקציה re.sub
מספקת לנו גם נקודת התערבות בדיוק אחרי שהיא מוצאת התאמה ומאפשרת לנו להחליף את ההתאמה שנמצאה בתוצאת הפעלת פונקציה.
אותה פונקציה מקבלת כפרמטר אוביקט שנקרא Match Object. אוביקט זה יודע לספר לנו כל מיני דברים לגבי ההתאמה שנמצאה, למשל איפה היתה ההתאמה ומה היה הטקסט שהתאים. באמצעות שימוש ב Match Object אנחנו יכולים בצורה דינמית לחשב את הטקסט שנרצה לכתוב במקום ההתאמה.
בדוגמא שלנו בשביל לכתוב את האות הבאה במילה כאות גדולה נוכל להשתמש בפונקציה capitalize של פייתון. הביטוי הבא מחליף כל מילה (שבאה אחרי קו תחתי) באותה מילה אחרי הפעלת capitalize עליה:
def almost_uppercase_words(text):
pat = re.compile('_')
return pat.sub(lambda m: m.group().capitalize(), text)
זה עדיין לא מספיק בשביל לכתוב אות גדולה בתחילת כל אחת מהמילים מאחר והערך של m.group
כולל גם את הקו התחתי.
דרך קלה להתגבר על זה היא להחליף קודם את כל הקווים התחתיים בסימן רווח, ואחרי זה להחליף את האות הראשונה בכל מילה לאות גדולה:
import re
def ucfirst_each_word(text):
each_word = re.compile(r'(\w+)')
return each_word.sub(lambda m: m.group().capitalize(), re.sub('_', ' ', text))
print(ucfirst_each_word("mad_mad_world"))
וכמובן אם פונקציית ה lambda מתחילה להיות ארוכה תמיד אפשר להגדיר אותה בצורה חיצונית ולהעביר את הפונקציה כפרמטר.
אם השכונה שלכם מספיק ישנה ותלכו להסתכל בתמונות ישנות שלה סביר להניח שלא תוכלו לזהות אף אחד מהבניינים. הבניינים הישנים נהרסו ואחרים חדשים נבנו במקומם. מצד שני סיכוי טוב שתצליחו לזהות את הרחובות עצמם והשבילים שבין הבניינים.
בתל אביב רחוב הרצל הוקם ב 1909 ולמרות שכל הבתים שלאורכו השתנו, טוואי הרחוב עצמו נשאר כמעט אותו דבר כבר מאה שנה. היציבות של הרחובות היא שמאפשרת לבניינים סביבם להשתנות ולעיר עצמה לגדול.
מערכות תוכנה משתנות כמובן הרבה יותר מהר מערים, ובכל זאת אני אוהב לחשוב על הבדיקות במערכת בתור אנלוגיה טובה לרחובות. כל עוד לא שינינו בדיקות המשתמשים יוכלו להתמצא במערכת ולא ירגישו את השינויים שאנחנו עושים בקוד. מנגד שינוי שמחייב עדכון של הבדיקות הוא כמו הזזת טוואי של רחוב - גם המשתמשים שהיו רגילים ללכת בדרך מסוימת צריכים עכשיו להתרגל למסלול החדש. הבדיקות שמות במסגרת את הקוד ועוזרות לנו להבין על איזה סוג שינוי או עדכון אנחנו עובדים.
והנה בשביל הנוסטלגיה רחוב הרצל בתחילת המאה העשרים (מתוך ויקיפדיה):
אנשים אוהבים אתרים שנטענים מהר ומחקרים כבר הוכיחו שהאהבה הזאת מתרגמת לכסף. באתרים רבים שבדקו גילו שה Conversion Rate של עולה ביחס ישר לזמן טעינת הדפים בהם. הנה 12 עצות זריזות שיעזרו לכם להתחיל להסתכל על ולשפר את זמן הטעינה של האתר שלכם:
משפט אחד קטן היה יכול לשנות את כל החיים שלנו וזה הולך ככה ״אין לי איך לעזור לך כרגע״. כי כל אחד שעובד בחברה מקבל הרבה יותר משימות ממה שהזמן מאפשר לסיים (וזה בכוונה), כי אין אף אחד מעליכם בהיררכיה שמארגן בשבילכם את המשימות וממיין את הדברים בשבילכם, וכי זה אנחנו שצריכים להחליט מה עושים היום מתוך ידיעה ברורה שבסוף היום יהיו משימות שלא יבוצעו.
ובמקום להיות ברורים לגבי זה כולנו משחקים את המשחק שהולך בערך כך: כן, אשמח לפתור לך גם את הבאג הזה. כן, אשמח להכין לך את המסמך איפיון ההוא. כן, ברור שאשמח לכתוב את התיעוד. לשבת עם ה QA לעזור לו בבאג מסתורי? כן בכיף. פגישת חברה היום? אני בא!
מה היה קורה אם במקום להגיד שנעשה משהו שכולם יודעים שלא נעשה נגיד במקום ״אין לי איך לעזור לך עם זה״:
״אני מבין שאתה צריך את המסמך למחר. אין לי איך לעזור לך עם זה. האמת שגם עוד שבועיים לא אוכל לכתוב אותו. תצטרך למצוא מישהו אחר״.
״אני מבין שיש באג קריטי במודול הזה. הבעיה שיש גם באגים קריטיים בשלושה מודולים אחרים וצריך לבחור איזה מהם לפתור. את יכולה לשלוח לי את הפרטים אבל לפני ספטמבר אני לא אגיע להסתכל על זה״.
זה קשה לשקף לבוסים עד כמה אתם עמוסים, ואין לי ספק שהבוסים מעדיפים לא לשמוע על הצרות שלכם. ובכל זאת אם אתם תקועים בהרגשה שכל הזמן לא מספיקים כלום ופוחדים ללכת לפגישות סטטוס, אולי זו גישה ששווה לנסות.