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

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

שמונה מיומנויות גיט שממש שווה להכיר בעל פה

11/07/2024

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

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

  2. להסתכל איך נראה קובץ בקומיט אחר.

  3. לעבור בין ענפים, מקומיים או מרוחקים.

  4. לראות את רשימת כל השרתים המרוחקים איתם הפרויקט שלכם מסונכרן.

  5. לראות מה היה הקומיט שגרם לשורה מסוימת להצטרף לקוד, או לבלוק מסוים להימחק.

  6. לקבל רשימה של שמות הקבצים שהשתנו בקומיט מסוים.

  7. למחוק ענפים מקומיים או מרוחקים.

  8. לפתור קונפליקטים אחרי merge או cherry-pick או rebase או כל דבר אחר שיוצר אותם.

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

בדיוק מה שביקשת

10/07/2024

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

הלכתי לאדון קלוד היום וביקשתי:

create an encrypted messages with deno

זה הקוד שקיבלתי - ובבקשה אל תשתמשו בו בקוד שלכם:

import { encode, decode } from "https://deno.land/std/encoding/base64.ts";
import { Aes } from "https://deno.land/x/crypto/aes.ts";
import { Cbc } from "https://deno.land/x/crypto/block_modes.ts";

function encrypt(message: string, key: string): string {
  const iv = crypto.getRandomValues(new Uint8Array(16));
  const aes = new Aes(key);
  const cbc = new Cbc(aes, iv);

  const encoder = new TextEncoder();
  const encodedMessage = encoder.encode(message);

  const encryptedData = cbc.encrypt(encodedMessage);

  const combined = new Uint8Array(iv.length + encryptedData.length);
  combined.set(iv);
  combined.set(encryptedData, iv.length);

  return encode(combined);
}

function decrypt(encryptedMessage: string, key: string): string {
  const combined = decode(encryptedMessage);
  const iv = combined.slice(0, 16);
  const encryptedData = combined.slice(16);

  const aes = new Aes(key);
  const cbc = new Cbc(aes, iv);

  const decryptedData = cbc.decrypt(encryptedData);

  const decoder = new TextDecoder();
  return decoder.decode(decryptedData);
}

// Example usage
const key = "mySecretKey123456"; // 16, 24, or 32 bytes long
const message = "Hello, this is a secret message!";

const encrypted = encrypt(message, key);
console.log("Encrypted:", encrypted);

const decrypted = decrypt(encrypted, key);
console.log("Decrypted:", decrypted);

לא צריך יותר מדי להתעמק בשביל לראות שהמפתח הסודי שמור בתוך קוד התוכנית ושהקוד לא חותם על התוכן המוצפן מה שיאפשר לפורצים עתידיים להשתמש בתוכנית שלי כדי לפרוץ את ההצפנה באמצעות שינוי המידע המוצפן ושליחתו למפענח (מה שמכונה Padding Oracle Attack).

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

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

אחרי כמה זמן זה מפסיק להיות קשה?

09/07/2024

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

  1. מתי זה יתחיל להיות כיף?

  2. מתי אתחיל להתגעגע לזה אם אדלג על שיעורים?

  3. מתי אגלה לבד משהו שלא מצאתי קודם בספר?

  4. מתי אוכל לפגוש אנשים חדשים שגם לומדים את הדבר הזה?

  5. מתי אצליח משהו שאף פעם לא הצלחתי קודם?

  6. מתי לא ארצה להפסיק?

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

מימוש חלקי בסקאלה דרך מיקסינים

08/07/2024

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

class MyBigHandler {
  def handle(message: String): String =
    message match
      case "error" => "Handling error"
      case "warning" => "Handling warning"
      case "info" => "Handling info"
      case "zzz" => "MyHandler"
      case _ => "Unhandled message"
}

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

trait MessageHandler {
  def handle(message: String): String = "Unhandled Message"
}

trait ErrorHandler extends MessageHandler {
  abstract override def handle(message: String): String = message match {
    case "error" => "Handling error"
    case _ => super.handle(message)
  }
}

trait WarningHandler extends MessageHandler {
  abstract override def handle(message: String): String = message match {
    case "warning" => "Handling warning"
    case _ => super.handle(message)
  }
}

trait InfoHandler extends MessageHandler {
  abstract override def handle(message: String): String = message match {
    case "info" => "Handling info"
    case _ => super.handle(message)
  }
}

class MyHandler extends MessageHandler
  with ErrorHandler
  with WarningHandler
  with InfoHandler {

  override def handle(message: String): String =
    message match
      case "zzz" => "MyHandler"
      case _ => super.handle(message)
}

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

תחזוקה ו GPT

07/07/2024

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

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

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

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

יתרונות וחסרונות של למידה ממושחקת

06/07/2024

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

המשך קריאה

מה יש ב Gem הזה?

05/07/2024

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

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

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

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

אקוסיסטם, אינטראופ ותחביר

03/07/2024

שלושת השיקולים שלי בבחירת שפת תכנות לפרויקט הבא, ולפי סדר חשיבות:

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

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

  3. תחביר - כי אחרי שיש לי את כל הכלים לבנות את מה שאני רוצה עדיף שאהנה מהכתיבה עצמה.

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

פיתרון Advent Of Code 2023 יום 20 בסקאלה

02/07/2024

יום עשרים של Advent Of Code הוא אחד התרגילים עם הרבה יותר מדי טקסט, הרבה יותר מדי קוד והרבה יותר מדי עבודה ידנית. בקיצור לא תרגיל שאוכל אי פעם להשתמש בו בקורסים ולא תרגיל שנהניתי ממנו במיוחד. אבל יש גם כאלה בחיים. בואו נראה את המשימה והפיתרון בקצרה. לינק לתרגיל: https://adventofcode.com/2023/day/20

המשך קריאה