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

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

בניינים ודרכים

23/06/2019

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

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

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

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

old image of herzel street

שתים עשרה עצות מהירות לשיפור זמן הטעינה של האתר שלכם

22/06/2019

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

המשך קריאה

אין לי איך לעזור לך

21/06/2019

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

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

מה היה קורה אם במקום להגיד שנעשה משהו שכולם יודעים שלא נעשה נגיד במקום ״אין לי איך לעזור לך עם זה״:

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

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

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

איך הפסקתי לדאוג וזרקתי את כל ה Mock-ים לפח

20/06/2019

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

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

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

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

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

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

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

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

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

הבחירה שהכי קשה להתמיד בה

19/06/2019

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

  1. הזרקות קוד - רובן מזוהות אוטומטית על ידי הכלי Brakeman

  2. מתקפות XSS - רובן מזוהות אוטומטית על ידי הכלי Brakeman, ונפתרות אוטומטית על ידי שימוש ב CSP.

  3. ניהול שבור של Sessions

  4. בעיית Insecure Direct Object Reference - נפתרת אוטומטית על ידי הג'ם cancancan וניהול הרשאות מסודר

  5. בעיית CSRF - ריילס כולל מנגנון שמופעל כברירת מחדל להגנה ממתקפה זו.

  6. הגדרות אבטחה לא נכונות (לדוגמא בסיס נתונים בלי סיסמא וכו'). ניתן לזהות בעזרת כלים אוטומטיים.

  7. איחסון לא מאובטח של סודות - ריילס כולל מנגנון לניהול סודות שמצפין אוטומטית את כל הסיסמאות.

  8. יצירת URL-ים סודיים שהכניסה אליהם לא מוגבלת - נפתר על ידי הג'ם cancancan וניהול נרשאות מסודר.

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

  10. ביצוע Redirect לפי ערך שהגיע מהמשתמש - מזוהה אוטומטית באמצעות brakeman.

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

אנחנו יודעים טוב למה.

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

למי אכפת מה Critical Rendering Path

18/06/2019

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

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

הנה דוגמא קצרה להמחשה - נניח שיש לנו קובץ HTML שנראה כך:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link href="https://fonts.googleapis.com/css?family=Rubik&display=swap" rel="stylesheet">

        <title>Demo</title>
<style>
p { font-family: 'Rubik', sans-serif; display: none; }
</style>
    </head>
    <body>
    <script src="demo.js"></script>
    </body>
</html>

והוא טוען קובץ JavaScript בשם demo.js שנראה כך:

setTimeout(function() {
  const div = document.createElement('div');
  div.style.fontFamily = 'Rubik';
  div.textContent = "hello world";
  document.body.appendChild(div);
}, 1000);

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

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

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

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

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

אם אתם רוצים ללמוד יותר על Critical Rendering Path ולראות דוגמאות למציאתו ושיפורו באתרים אמיתיים מוזמנים להצטרף אליי ביום חמישי לוובינר של שעה בנושא. הרישום בקישור:

https://www.tocode.co.il/workshops/79

בביצועים צריך גם לדעת לוותר

17/06/2019

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

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

הנה דוגמא קצרה מהאתר היום - לאחרונה שמתי לב שלוקח לאתר המון זמן להיפתח. מבט מהיר בלוגים הראה שהבעיה במנגנון ה Server Side Rendering. זה המנגנון שגורם לזה שכשאתם פותחים דף באתר השרת ישלח לכם קובץ HTML תקני שייפתח גם אם ה JavaScript מבוטל אצלכם על המכונה. אני מאוד אוהב את הרעיון שהפוסטים נפתחים גם בלי JavaScript ומנגנון ה SSR היה תנאי סף מבחינתי לשילוב React במערכת. והנה המשחק של התקציב נותן את המכה שלו, כי עכשיו האפשרויות הן:

  1. למצוא למה SSR עובד לאט ולתקן אותו (לא בטוח שאפשר, בטוח שהחיפוש ייקח זמן).

  2. להוסיף מנגנון Caching בצד השרת לתוצאה של ה SSR (יעבוד אבל ייקח יותר זיכרון בשרת, ייקח זמן למימוש ואולי יביא בעיות אחרות)

  3. לוותר על SSR

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

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

אגב ביום חמישי הקרוב אעביר כאן וובינר על ביצועים ביישומי ווב בדגש על Front End. נדבר על Critical Rendering Path, נראה איך לזהות אותו באמצעות כלי הפיתוח של הדפדפן ואיך להשתמש במידע כדי לשפר את החוויה של רוב הגולשים שלכם. אולי אפילו נצליח למצוא יחד עוד כמה דרכים לשפר את מהירות הטעינה של טוקוד. אם בא לכם להצטרף רק צריך ללחוץ על הקישור:

https://www.tocode.co.il/workshops/79

הזמן הנכון ללמוד מונחים מקצועיים

16/06/2019

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

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

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

מחירים שלא רואים

15/06/2019

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

אבל לכל פיצ'ר במערכת יש גם את המחיר שלא רואים - בדוגמא שלי הבחירה לבנות את הפיצ'ר של הוובינרים הגיעה על חשבון פיצ'ר אחר באתר שלא פיתחתי.

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

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

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

ידע שנשאר

14/06/2019

לפני עשרים שנה הייתי בראיון עבודה והתמודדתי עם שאלות בנושא SQL. זה היה בדיוק כמה ימים אחרי שקראתי את הספר "למד את עצמך SQL ב 24 שעות", או במילים אחרות לא ידעתי כלום. דמיינו כמה הייתי מופתע אם מישהו היה אומר לי אז באותו ראיון שעשרים שנה אחרי עוד אמשיך לעבוד ב SQL, ללמד SQL ולהתבלבל בין Outer Joins ל Inner Joins.

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

  1. הלינוקס שלמדתי בתיכון עדיין עוזר לי גם היום.

  2. ה SQL שלמדתי לפני עשרים שנה ממשיך להיות חלק בלתי נפרד מהחיים שלי כמתכנת.

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

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