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

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

הנחות עבודה לגבי אבטחת מידע

01/09/2019

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

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

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

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

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

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

  1. חומות הגנה בין יישומים שונים ובין Services שונים.

  2. מנגנונים של זיהוי אוטומטי כש Service או מכונה מתחילים להתנהג בצורה חשודה.

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

לא בדיוק כמו בהוראות

31/08/2019

גם כשממש מנסים לעקוב אחרי הוראות מהרשת החיים יכולים להפתיע-

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

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

באיזה מודולים הסקריפט שלי משתמש

30/08/2019

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

קחו את התוכנית הבאה לדוגמא:

import re
import sys

for line in sys.stdin:
    if re.search(r'\b[A-Z][a-z]*\b', line):
        sys.stdout.write(line)
    else:
        print("No interesting words found")

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

from modulefinder import ModuleFinder
from stdlib_list import stdlib_list
libraries = stdlib_list("3.7")
import sys
finder = ModuleFinder()
finder.run_script('hello.py')

print('Loaded modules:')
for name, mod in finder.modules.items():
    if '.' in name: continue
    if name in sys.builtin_module_names: continue

    print('%s: ' % name, end='')
    if name in libraries:
        print("Builtin module")
    else:
        print("External module")

כמה הערות:

  1. בשביל להשתמש ב modulefinder אנחנו צריכים בסך הכל להריץ את הסקריפט עם finder.run_script ואחרי זה לקרוא את הרשימה מ finder.modules.

  2. אני משתמש בשתי היוריסטיקות כדי לדעת אם מודול הוא חלק מפייתון. זה מכסה חלק מהמקרים אבל עדיין לא את כולם. הספריה stdlib_list לוקחת מהאתר של פייתון את רשימת המודולים ששייכים לגירסא מסוימת, והמשתנה sys.builtin_module_names מכיל את רשימת המודולים שבנויים לתוך פייתון. עדיין יש מודולים שהם חלק ממודול אחר, לדוגמא _ssl שהוא חלק ממודול ssl ואותם הסקריפט לא מזהה כמודולים פנימיים. רעיונות להיפטר ממודולים אלה יתקבלו בברכה.

מה פייתון עושה באמת

29/08/2019

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

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

def main():
    print("Hello World")

נוסיף את המודול dis לתוכנית ונבקש ממנו לפרק את הפונקציה כך שהתוכנית המלאה תיראה כך:

import dis

def main():
    print("Hello World")

dis.dis(main)

והפלט:

  4           0 LOAD_GLOBAL              0 (print)
              2 LOAD_CONST               1 ('Hello World')
              4 CALL_FUNCTION            1
              6 POP_TOP
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

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

נראה אחד יותר מורכב:

import dis

def greet(n):
    for i in range(n):
        print("hello world")


dis.dis(greet)

והפלט:

  4           0 SETUP_LOOP              24 (to 26)
              2 LOAD_GLOBAL              0 (range)
              4 LOAD_FAST                0 (n)
              6 CALL_FUNCTION            1
              8 GET_ITER
        >>   10 FOR_ITER                12 (to 24)
             12 STORE_FAST               1 (i)

  5          14 LOAD_GLOBAL              1 (print)
             16 LOAD_CONST               1 ('hello world')
             18 CALL_FUNCTION            1
             20 POP_TOP
             22 JUMP_ABSOLUTE           10
        >>   24 POP_BLOCK
        >>   26 LOAD_CONST               0 (None)
             28 RETURN_VALUE

כאן כבר יש לנו שתי שורות קוד שהופכות ל-15 פקודות מכונה. שימו לב לפקודת ה JUMP_ABSOLUTE ול FOR_ITER שיחד מייצרות את הלולאה ולקריאה לפונקציה range בשביל לקבל את הטווח.

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

import dis

counter = 0

def one():
    counter += 1
    print(counter)

dis.dis(one)

הפונקציה מוסיפה 1 למשתנה גלובאלי, אבל רק כשאנחנו מסתכלים עליה ב dis אפשר לראות שהפעולה += בעצם מורכבת ממספר פעולות:

  6           0 LOAD_FAST                0 (counter)
              2 LOAD_CONST               1 (1)
              4 INPLACE_ADD
              6 STORE_FAST               0 (counter)

  7           8 LOAD_GLOBAL              0 (print)
             10 LOAD_FAST                0 (counter)
             12 CALL_FUNCTION            1
             14 POP_TOP
             16 LOAD_CONST               0 (None)
             18 RETURN_VALUE

קודם כל טוענים את counter לזיכרון, אחרי זה מוסיפים 1 ובסוף שומרים חזרה את התוצאה. זה מעניין כי עכשיו שראינו את זה אנחנו יודעים להיזהר ולא להפעיל את האופרטור מתוך מספר Threads במקביל, אחרת אנחנו עלולים לקבל Race Condition ולסיים עם תוצאה לא נכונה.

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

הפקודה cpulimit והודעות אזהרה מלינוד

28/08/2019

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

אחרי קצת חיטוט בשרת מצאתי שאחד מתהליכי הרקע התחיל להשתולל ולאכול CPU Time. התהליך רץ ב nice לכן זה לא ממש מפריע לאף אחד, כי אם יש עומס אמיתי על השרת ממילא תהליך זה יוקפא. אבל מסתבר שללינוד זה עדיין מפריע: כשהשרת ב idle אותו תהליך כבד לוקח 99% מזמן המעבד וזה מדליק את נורות האזהרה.

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

$ apt-get install cpulimit

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

sudo cpulimit -b -l 50 -p 27085

המתג -b גורם ל cpulimit לרוץ ברקע, המתג -l מקבל מספר וזה אחוז המעבד המקסימלי שהתהליך יקבל והמתג -p מקבל מזהה תהליך לנטר.

ובשביל להשתמש ב nice וב cpulimit יחד אנחנו יכולים לכתוב סקריפט קצר בסגנון הבא:

nice my_busy_script.py &
pid=$!
cpulimit -b -l 50 -p "$pid"
wait

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

בניתי לבד

27/08/2019

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

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

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

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

שתי פקודות גיט חדשות בשבילכם

26/08/2019

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

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

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

$ git init
$ date > one.txt
$ git add .
$ git commit -m 'initial commit'

ועכשיו אפשר ליצור ענף חדש עם switch:

$ git switch -c dev
Switched to a new branch 'dev'

לחזור לענף master:

$ git switch master
Switched to branch 'master'

ולחזור שוב ל dev סתם בשביל המשחק:

$ git switch -
Switched to branch 'dev'

סוויצ' עושה עוד כמה דברים ובשביל זה ממליץ לכם לקרוא את התיעוד עליו עם man git-switch.

הפקודה השניה restore גם ממש פשוטה. באותו מאגר נקלקל את הקובץ שלנו:

$ rm one.txt

ועכשיו אפשר להחזיר אותו עם:

$ git restore one.txt
$ ls
one.txt

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

$ rm *
$ git restore '*'
$ ls
one.txt

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

רשימה מלאה של כל הפינוקים והשינויים בגיט החדש אפשר למצוא בהודעת המערכת על שחרורו בקישור https://public-inbox.org/git/xmqqy2zszuz7.fsf@gitster-ct.c.googlers.com/

איך לקרוא את התיעוד על HTML ו CSS

25/08/2019

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

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

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

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

אנחנו מתחילים עם דף נחיתה או תבנית של אתר שמצאנו ברשת, זה יכול להיות אתר קיים שאנחנו רוצים לשכפל את ההתנהגות שלו או תבנית עיצוב מ Themeforest. מתחילים במימוש התבנית בתור HTML ו CSS, ואז מתחילים לבדוק את התוצאה על כמה שיותר דפדפנים וכמה שיותר מכשירים. ככל שתתקדמו תראו שהדף שבניתם נשבר כשעוברים לדפדפנים ישנים או למכשירים אחרים (למשל טלפונים ישנים), ובאותו זמן תתקלו בהתנהגות מסוימת שיהיה לכם קשה לממש (למשל Push Notifications). עכשיו יש לכם נקודת התחלה:

  1. הולכים לקרוא את התיעוד המלא על כל יכולת שהשתמשתם בה במהלך הפיתוח, על כל פקודת CSS ועל כל אלמנט HTML שבחרתם.

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

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

  4. הכל עובד? ממשיכים לבנות אתר נוסף.

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

ללמוד בעל פה או ללמוד עם הלב

24/08/2019

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

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

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

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

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

  1. מבטלים את ההשלמה האוטומטית ב IDE. הכתיבה החוזרת מכניסה את הידע לאצבעות והופכת את הכתיבה להרבה יותר אינטואיטיבית.

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

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

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

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

שתי שאלות שבטוח יופיעו בראיון העבודה הבא שלך

23/08/2019

״על מה עבדת בעבודה הקודמת?״

״עם מי?״

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

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

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