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

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

אם יש לך שעה ללמד נושא גדול

13/11/2020

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

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

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

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

איך למשוך מידע מהשרת בכל מעבר נתיב עם Reach Router

12/11/2020

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

  1. בגישת HTML לשרת, כל נתיב יחזיר בדיוק את אותו קוד צד-לקוח.

  2. דף ה HTML יכיל מידע ראשוני בו אפשר יהיה להשתמש כדי להציג את הדף וכך לא נצטרך בקשת Ajax נוספת אחרי טעינת העמוד. המידע הראשוני נשמר ב HTML בתור JSON.

  3. בגישת Ajax לכל נתיב השרת שולח רק את המידע בלי דף ה HTML שמסביבו.

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

חדי העין שבין הקוראים יכולים לזהות את ה Anti Pattern בארכיטקטורה: ריאקט ראוטר לא אוהב שמנסים להריץ קוד "הכנה" לפני שעוברים נתיב. בסופו של דבר ההרפתקה ההיא הסתיימה בזה שזרקתי את React Router ובחרתי ב Router יותר גמיש (נקרא nighthawk ומאוד לא מתוחזק) שדווקא נתן לי לבנות בדיוק את המנגנון שרציתי.

ארבע שנים קדימה ואני שוב בונה ארכיטקטורת צד שרת דומה. הפעם מייקל ג'קסון וריאן פלורנס כבר לא עובדים ביחד והראוטר החדש של ריאן פלורנס נקרא Reach Router. ריאקט עברה להשתמש ב Hooks ואני כבר למדתי שעדיף להריץ את קוד ה Ajax אחרי שנכנסים לנתיב החדש, ולבנות את קוד הקומפוננטות כך שידע לטפל טוב במצב שאין לו עדיין Data להציג. שילוב כל הרעיונות האלה התחבר לקוד הבא עבור הקומפוננטה הראשית:

function App(props) {
  const location = useLocation();
  const loadedUrl = useSelector(state => state.url);
  const dispatch = useDispatch();

  useEffect(function() {
    let active = true;

    if (location.pathname === loadedUrl) {
      return;
    }
    axios.get(location.pathname).then(function(response) {
      if (active) {
        const data = response.data;
        dispatch(actions.newAppstateReceived(data));
      }
    });
    return function abort() {
      active = false;
    }
  }, [location.pathname, loadedUrl]);

  return (
    <Router>
      <Home path="/" />
      <Post path="/posts/:id" />
    </Router>
  )
}

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

  1. כל מה שזז נמצא בקוד הקומפוננטה בעזרת useEffect. אני מחזיק הרבה פחות Middlewares וכמעט שלא משתמש ב thunk.

  2. למרות של axios יש מנגנון ביטול בקשות, אני מעדיף להשתמש במשתנה פשוט ב useEffect. הקוד פחות תלוי בממשק של axios, וזה כל כך פשוט.

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

  4. אני בכוונה לא שומר Cache של המידע. אם בעתיד זה יידרש אפשר לשלב את axios-cache-plugin או פיתרון Cache אחר בצד הלקוח. ככל שהקוד בתוך האפקט ילך ויסתבך אפשר להוציא אותו ל Custom Hook.

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

לימוד פאסיבי או אקטיבי

11/11/2020

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

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

  2. לימוד פאסיבי צריך סילבוס או לפחות מאפשר אותו. זה בעצם הדיל: אני אעשה מה שתגידו לי ובסוף אדע לעשות את הדברים שלימדתם אותי.

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

  4. לימוד פאסיבי Gets you off the hook (אני לא מכיר גירסה עברית לביטוי הזה). הכל טוב, אני עושה מה שאומרים לי ובסוף אצליח. זה הופך את תהליך הלימוד להרבה פחות מתסכל.

  5. לימוד פאסיבי מאפשר את כל מערכת החינוך כמו שאנחנו מכירים אותה.

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

  1. הרבה אנשים לא נהנים מהמסלול.

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

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

הנה מה שכתב לי תלמיד באתר לפני כמה ימים:

ב 2013 סיימתי קורס בג'אבה בהצלחה בגיון ברייס קבלתי ציון גבוה אך לא הצלחתי למצוא עבודה ללא ניסיון ומאז לא נגעתי בפיתוח.

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

אז מה האלטרנטיבה?

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

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

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

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

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

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

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

שלושה לקחים מסקירת בסיס נתונים ישן

10/11/2020

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

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

המשך קריאה

חידת פייתון ו C

09/11/2020

דני תוכניתני חשב שיוכל לחשב מספרי פיבונאצ'י הרבה יותר מהר אם יעביר את פונקציית החישוב מ Python ל C. הפונקציה ב Python נראתה כך:

def fib(n):
    x, y = 0, 1
    for i in range(n):
        x, y = y, x + y

    return y

ודני שכבר יודע דבר או שניים על חיבור פייתון ל C הלך ותירגם את הקוד ל C באופן הבא:

static PyObject *
spam_fib(PyObject *self, PyObject *args)
{
  int n;
  if (!PyArg_ParseTuple(args, "i", &n))
    return NULL;

  unsigned long x = 0, y = 1;
  unsigned long temp;

  for (int i=0; i < n; i++) {
    temp = x;
    x = y;
    y = temp + x;
  }

  return PyLong_FromUnsignedLong(y);
}

אחרי קומפילציה ובדיקה קצרה של הקוד הבא:

import spam

print(spam.fib(5))

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

מה דני שבר?

התנהגות ברירת מחדל

08/11/2020

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

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

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

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

השנה 2020, ואני עדיין כותב עברית הפוך

07/11/2020

הקוד הבא ב pyglet מציג את הטקסט בעברית בכתב מראה:

import pyglet
from pyglet import shapes

window = pyglet.window.Window(960, 540)

label = pyglet.text.Label('שלום עולם',
                          font_name='Times New Roman',
                          font_size=36,
                          x=window.width//2, y=window.height//2,
                          anchor_x='center', anchor_y='center')

@window.event
def on_draw():
    window.clear()
    label.draw()


pyglet.app.run()

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

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

הפונקציה getByRole ב react-testing-library

06/11/2020

אחד הדברים שהכי קשה להכיל במעבר ל react-testing-library הוא החשיבות הגדולה שמפתחי הספריה מעניקים ל Accessibility Roles. בעוד רוב ספריות הבדיקה נותנות לנו להגיע לאלמנטים באיזו צורה שאנחנו רוצים (דרך CSS או אפילו XPath), כשמגיעים ל react-testing-library מגלים ש getByCSS זו לא פונקציה אמיתית שם.

השינוי הטכני הזה נובע משינוי תפיסה לגבי תפקיד הבדיקה ומה אנחנו רוצים לבדוק: בעוד ספריות בדיקה מסורתיות רוצות לבדוק שדברים מגיעים ל DOM בצורה נכונה, ב react-testing-library אנחנו רוצים לבדוק יותר מזה, אנחנו רוצים לבדוק שאנחנו מבינים את העמוד שלנו כמו שמשתמש מבין אותו. המעבר ל getByRole מהווה שינוי בנקודת המבט.

שימו לב לקטע הבא לדוגמה שהצגתי בוובינר אתמול:

export default function SimpleList({ items }) {
  const [filter, setFilter] = useState('');

  return (
    <>
      <input
        type="search"
        value={filter}
        onChange={(e) => setFilter(e.target.value)}
        name="filter-list"
      />
      <ul>
        {items.filter(item => item.text.includes(filter)).map((item, idx) => (
          <li
            key={item.id}
            className={(idx + 1) % 2 === 0 ? "even" : "odd"}
          >
            {item.text}
          </li>
        ))}
      </ul>
    </>
  );
}

בספריית בדיקות רגילה הייתי יכול להשתמש ב CSS כדי להגיע לאלמנט ה input ולמשל לקרוא ל:

document.querySelector('input[name="filter-list"]')

אבל במעבר ל react-testing-library ובפרט אם אני מוכן לקבל את השגעונות שלהם ולהשתמש ב getByRole אני אגלה שקשה לי לתפוס את אלמנט ה input הזה. הקוד הבא יעבוד:

const el = screen.getByRole('searchbox');

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

המעבר ל getByRole מכריח אותי לחשוב כמו המשתמש - איך המשתמש יודע על איזו תיבה מדובר? איך המשתמש יודע איפה להכניס את הקלט? משתמש לא רואה את המאפיין name או את הקלאסים של התיבה. הוא יכול לראות את הטקסט שרשום בה אבל בדרך כלל הוא יראה את ה Label שמשויך לתיבת הקלט. וכבר אנחנו רואים את הבעיה בקומפוננטה: ל input אין label שמסביר מה היא עושה.

תיקון של הקוד והוספת label נראה כך:

export default function SimpleList({ items }) {
  const [filter, setFilter] = useState('');

  return (
    <>
      <label>Filter List

        <input
          type="search"
          value={filter}
          onChange={(e) => setFilter(e.target.value)}
        />
      </label>

      <ul>
        {items.filter(item => item.text.includes(filter)).map((item, idx) => (
          <li
            key={item.id}
            className={(idx + 1) % 2 === 0 ? "even" : "odd"}
          >
            {item.text}
          </li>
        ))}
      </ul>
    </>
  );
}

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

screen.getByRole('searchbox', { name: 'Filter List' } );

אלבום בכל שנה

05/11/2020

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

וזה נכון. ייקח לנו עוד שנתיים עד שנוכל לשמוע את Thriller.

אבל אז אתה נזכר גם ש Help ו Rubber Soul יצאו באותה שנה ושנה אחריהם הביטלס הוציאו את Revolver, עוד שנה קדימה אנחנו עם Sgt. Perpper ועם Magical Mystery Tour, שנה אחריו ב 1968 מגיע האלבום הלבן ו 1969 הביאה את Abbey Road.

איך הם עשו את זה? מה הביטלס ראו שמייקל ג'קסון לא ראה? ומה הם יכולים להראות לנו?

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

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

דבר אחד טוב

04/11/2020

בן אדם מחפש עבודה ורואה מודעה שאומרת:

דרוש/ה מתכנת/ת:

  1. שלוש שנות ניסיון בפיתוח NodeJS

  2. ניסיון משמעותי עם Angular/React/Vue

  3. ניסיון מעמיק עם Rest API

  4. ניסיון מעמיק עם AWS

  5. יתרון לניסיון עם Docker ו Kubernetes

ואז הבן אדם אומר לעצמו - טוב, אני יודע לכתוב Full Stack, כתבתי קצת Node ו React בתפקיד הקודם, נראה משרה בשבילי, אבל עדיין אני לא 100% עומד בדרישות, וגם בעבודה הקודמת שלי עבדתי רק שנתיים בפיתוח נוד. אני יודע! אני יכול לכתוב פרויקט שישתמש בכל הטכנולוגיות ברשימה ואז הם יראו כמה אני מוכשר ומיד יגייסו אותי.

ומכאן המצב רק מתדרדר.

כי אי אפשר לפתח לבד מערכת עם קוד צד-שרת ב Node.JS, צד לקוח ב React, תקשורת ב REST API (בעצם אם כבר אני בונה עכשיו משהו בשביל לעשות רושם אז מה פתאום REST עדיף GraphQL) ואז להעלות את כל זה ל AWS בתוך קונטיינרים. אפילו אם הייתם מכירים את הטכנולוגיות ברמה טובה. הדברים האלה לוקחים זמן ולוקחים צוות. בלי זה העבודה תצא חובבנית.

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

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

ועם זה בראש שווה ללכת לבנות את פרויקט הדוגמה שלכם במטרה להראות רמה מקצועית גבוהה בדבר אחד ספציפי: אפליקציית Next.JS פשוטה (בלי אותנטיקציה, בלי ניהול משתמשים, בלי טיפול בעומסים בצד השרת) אבל עם קוד Front End שבנוי טוב עם בדיקות יחידה תעבוד ממש טוב כפרויקט דוגמה למשרה הזאת ולעוד רבות אחרות.