הפרדת רשויות: מדוע להשקיע ב DTOs ו Entities?

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

תוכנה מתחילה למות ביום בו מפסיקים לשנות אותה.

עקרון תכנותיקה

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

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

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

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

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

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

מדוע לבצע הפרדת רשויות?

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

  • ב APIs או Events – כדי להעביר מידע אודות Person למערכות אחרות.
    • לפעמים ע״י serialization של המחלקה ל JSON
    • לפעמים אנחנו משתמשים במחלקה על מנת להפיק (generate) ייצוג ב IDL (שפת ביניים)
  • ב Business Logic – בכדי להעביר מידע אודות Person בין חלקים שונים של ה business logic.
  • בשכבת העבודה של בסיס הנתונים – בכדי לשמות מידע של Person בבסיס הנתונים לאורך זמן.
    • לפעמים ע״י serialization של המחלקה ל JSON (למשל: Document databases, או semi-document DB כמו mySQL או Postgres).
    • לפעמים דרך ORMs כמו Active Records או Hibernate (שיצרו סכמת בסיס נתונים בהתבסס על מבנה האובייקט).

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

  • האובייקטים, הרבה פעמים, יהיו זהים ביום היצירה שלהם? אז למה לשכפל קוד?
  • למה לתרגם בין אובייקטים זהים (נניח: ברגע שאוביקט ב Business Logic צריך לעזוב את המערכת כחלק מ Event / קריאת API)

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

Entity Object
(e.g. PersonEntity)
Model
(e.g. Person,
no suffix)
Data Transfer Object (e.g PersonDTO)
שמות מקובלים אחריםPersonDBEntity (clarify the direct relation to DB).PersonModel, PersonDomain, PersonBL (= Business Logic)None I know of.
סיבה להשתנותהוספת מידע שנדרש לצורך שמירה בלבד: ID, זמן / תאריך שמירה או שינוי. שדה נוסף שיקל על פעולת אינדוקס.
אולי רוצים לפצל את שמירת הנתונים ל-2 טבלאות או פורמט אחר לצורך שיפור ביצועים.
העשרת ה BL בשדות / תכונות נוספות שפנימיות למערכת.
שינוי שמות שדות בעקבות תובנות ואפשרות לתאר אותם בצורה נכונה יותר, ייצוג נתונים באופן שקל יותר למערכת לעבוד איתו. למשל LocalDate ולא מחרוזת של תאריך, Money ולא Integer.
התאמת מבנה נתונים ללקוח, נניח אפליקציות FE שייהנו ממבנים ידידותיים יותר ל JS.הוספת שדות מחושבים שלא נמצאים במודל, אך יקלו על הלקוחות (BE או FE).
כיצד משתנה בצורה תואמת-לאחור
(למשל הוספת שדה חדש שניתן לקבוע לו default value)
תאימות לאחור חשובה כי ייתכן ונרצה לקרוא מחר מידע שנשמר לפני שנה-שנתיים. ללא תאימות לאחור – לא נוכל לאחזר מידע ישן.גמישות רבה בשינויים, כי אובייקט המודל לא נשמר ולכן כל אתחול של המערכת (deploy) יכול לעבוד עם גרסה חדשה.תאימות לאחור חשובה כי ישנם לקוחות שימשיכו לצפות ולשדר את המבנה בגרסאות קודמות שלו – ואין לנו שליטה עליהם (אם הלקוחות הם שירותים שלנו – עדיין יש צורך בשינוי הדרגתי).
כיצד משתנה בצורה שאינה תואמת-לאחוראפשרות א: תיקון כל הנתונים בבסיס הנתונים (migration) כך שיתאים ל entity החדש. זה שינוי שיכול להיות קשה, יקר, ומועד-לטעויות יקרות. כיף!אפשרות ב: ליצור גרסאות של ייצוג בבסיס הנתונים, ולהחזיק קוד שמזהה את הגרסה – ויותר לטפל בכל גרסה באופן שונה.אפשרי ברמת הקוד בלבד (refactoring). כל עוד הקוד מתקמפל, והבדיקות עוברות – כנראה מאוד שאנחנו בסדר.לרוב נאלץ לפתור גרסה חדשה של ה API / event (למשל V2) בו יש את המבנה החדש, ולהעביר לקוחות לגרסה החדשה. עבור לקוחות שאין לנו שליטה עליהם – זה יכול להיות תהליך של חודשים הכולל פשרות מסוימות.
הערותלפעמים אנשים מבלבלים בין Entity ו DAO:
Entity – ה object שחוזר.
DAO – הממשק שממנו שולפים את ה Entity.
לא פעם מכיל מתודות / פונקציות – ולא רק נתונים.
מומלץ מאוד שאלו יהיו רק מתודות המקלות על גישה / פענוח הנתונים (מה שנקרא access logic), ולא Business Logic של ממש.
לא פעם מקובל להגדיר Coarse-grained DTO (אובייקט ״גדול״ יותר) – על מנת לצמצם את מספר הקריאות ברשת.
השוואה בין ההבדלים החשובים בין Entity, Model, ו DTO.

דוגמאת קוד

המודל:

@JsonIgnoreType
public class Person {
  @JsonIgnore public final String name;
  @JsonIgnore public final LocalDate birthDate;

  private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PersonDTO.birthDateFormat);

  public Person(String name, LocalDate birthDate) {
    this.name = name;
    this.birthDate = birthDate;
  }

  public PersonDTO toDTO() {
    return new PersonDTO(name, birthDate.format(formatter));
  }

  static public Person fromDTO(PersonDTO dto) {
    return new Person(dto.name, LocalDate.parse(dto.birthDate, formatter));
  }
}

הערות:

  • לא השתמשתי ב record, בהנחה שזה מבנה פחות מוכר, אז למה לבלבל.
    • שימוש ב public members עבור Entities – הוא דבר שעשיתי בתחילת שנות האלפיים, ותמיד האמנתי שהוא נכון (למרות מעט ביקורת מצד תאורטיקני ג׳אווה שתמיד רצו getters).
  • שורות 1, 3, ו4: JsonIgnoreType@ ו JsonIgnore@ הם ביטחונות של ספריית Jackson (ל seralize/deseralize JSON) שהמחלקה לא תסורייל (seralized) ל JSON ושהמידע שלה לא יישמר/ישלח איכשהו. אנשים נוטים לשכוח שיש DTO ו/או Entity – וחשוב להגן בפני הטעויות הללו. אם התחלנו לשמור את המודל לבסיס הנתונים – התיקון עלול להיות יקר.
    • האם שניהם נחוצים? (ולא מספיק אחד) – אני לא בטוח, אבל Better be safe than sorry.
    • לא כולם משתמשים ב Jackson כמובן – עליכם למצוא את הפתרונות שלכם להגן על המודל שלא ייצא מגבולות ה business Logic ולא יישמר באופן שיחסום אתכם לשינויים עתידיים.
    • האם יש משהו לא-אלגנטי שדווקא המחלקה שאמורה להיות ״הנקיה ביותר״ צריכה להשתמש בתלות לספריית ה serialization ולהצהיר – שהיא ״לא במשחק״? בהחלט לא אלגנטי – אם תמצאו פרונות אלגנטיים יותר אך מעשיים – לכו עליהם.
  • שורות 13 ו 17: אנו רוצים פונקציות עזר פשוטות בכדי להמיר בין מודל ו DTO.
    • לרוב קוד ה DTO יאוכסן בספריה נפרדת, כחלק מה API של המיקרו-שירות / המערכת – ולכן ל DTO לא תהיה גישה ל Model (והגיוני שכך). קוד ההמרה חייב לשבת במודל.

ה (Data Transfer Object (DTO:

public class PersonDTO {
  public final String name;
  public final String birthDate;

  @JsonIgnore public static final String birthDateFormat = "dd/MM/yyyy";

  public PersonDTO(String name, String birthDate) {
    this.name = name;
    this.birthDate = birthDate;
  }
}

הערות:

  • שורה 5 – הפורמט שבו ה DTO שומר את התאריך כמחרוזת (נניח: פורמט שקל לצרוך מתוך JavaScript) הוא פרט מומחיות שלו, ולכן יושב על ה DTO ולא על מחלקת המודל.
    • בהנחה שאנו עובדים עם Jackson – לא נרצה שפרט זה יעבור על הרשת כחלק מהאובייקט – ולכן השימוש ב JsonIgnore@.

ה Entity:

class PersonEntity {
  public final String name;
  public final String birthDate;

  private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

  PersonEntity(String name, String birthDate) {
    this.name = name;
    this.birthDate = birthDate;
  }

  public Person toModel() {
    return new Person(name, LocalDate.parse(birthDate, formatter));
  }

  static public PersonEntity fromModel(Person model) {
    return new PersonEntity(model.name, model.birthDate.format(formatter));
  }

}

הערות:

  • שורות 12 ו 16 – ה Entity הוא זה שמכיר את המודל, כי נרצה שמי שיעשה את ההמרה הוא שכבת ה Data Access ולא ה business Logic. למשל: DAO או Repository המקבלים את המודל ושומרים אותו, או שולפים אובייקט מודל לפי שאילתה נתונה.
  • שורה 5 – הפורמט שבו אנחנו שומרים את התאריך (נניח: פורמט ידידותי ל DATE column בבסיס הנתונים) הוא מידע פרטי של ה Entity.
    • לא הוספתי JsonIgnore@ – כי זה שדה פרטי.

סיכום התלויות:

סיכום

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

שאלה גדולה היא מתי לעשות את זה?

  • לכל מחלקה במערכת?
  • לפעמים (חסר קריטריון: מתי כן ומתי לא?)
  • לעולם לא – חבל על 10 דקות עכשיו, נסתדר בעתיד?

ברור לי ששתי הקיצוניות הן לא נכונות. היו תקופות שפיתחתי ״J2EE״ וכתבנו Enity ו DTO ל 100% מהמחלקות, גם APIs שוליים שרק ביקשו מידע קטן, והיה להן צרכן יחיד – זה מיותר ומחליש את הבנת/חשיבות הצורך.

ברור לי שלאובייקטי הליבה במערכת שלכם (אלו שמשתמשים בהם המון, אלו שמעורבים בלוגיקה המורכבת והמשמעותית של המערכת) – חשוב מאוד ליצור Entity ו DTO.

מה עם אובייקטים חצי-חשובים? בשימוש לא-קטן אבל גם לא כבד? זה כבר עניין של ניהול סיכונים ותרבות ארגונית. למרות שמבחינת חישוב ROI פשוט (נשקיע השקעה קטנה בכתיבת Entity+DTO ל 20 מחלקות, אבל אחת שתידרש לזה באמת – תחזיר את ההשקעה בכתיבת 20 צמדים כאלו, כי זה חסך לנו Refactoring אחד גדול וקשה) ההשקעה משתלמת, קשה לפעמים לאנשים לראות את הערך ביחסי השקעה שכאלו.

לפעמים שווה להשקיע במקומות המסוכנים בלבד, ולספוג מעט ״נזק״ – אבל לשמר את העובדים עם תחושת ערך ברורה. שהם מבינים בבירור מדוע במחלקה מסוימת ההשקעה משתלמת – ושם משקיעים. פעם בכמה חודשים שיהיה Refactoring יקר (אבל לא מדי – כי זה לא אובייקט ליבה) – יזכיר לאנשים את הערך ב DTO+Entity.

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

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

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

הערה אחרונה: אפשר לכתוב גם לפעמים רק Entity או אולי רק DTO. אם אתם יודעים לאבחן מתי – אדרבא.

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

שיהיה בהצלחה!

———

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

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

נתבקשתי ע״י אפרת וולפנר-תורג'מן (ידידה ותיקה) ודור מצפי, שמקימים בימים אלה את גילדת התוכנה בחברת סמסונג – לבוא ולדבר קצת על תכנון תוכנה (Software Design).

האתגר שלהם: מגוון רחב מאוד של אנשי תוכנה: FE, BE – קל להבין, אבל בגילדה שלהם יש גם אנשי Data Science / ML, Data Engineers, Embedded, ו Firmware. כולם כותבים קוד, אבל באמת צורות העבודה של המקצועות הללו היא שונה דייה, כך שלא קל למצוא ברמת הקוד דוגמאות הרלוונטיות לכולם.

האם דזיין הוא שונה? האם אפשר באמת להגדיר כללים זהים שיתאימו גם למפתחי FrontEnd, גם לאנשי Machine Learning, וגם לאנשי Firmware.

לקחתי על עצמי את האתגר – והאמת שהוא לא היה קשה.

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

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

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

כמה נקודות במצגת ששוות להתייחסות נוספת

למה אפשר לצפות מדזיין טוב?

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

איך נראה דזיין טוב?

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

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

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

דזיין הוא תהליך – ולא מסמך

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

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

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

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

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

מקווה שתמצאו פוסט זה שימוש!

בלוקצ׳יין – מעבר לבאזז

בפוסט זה אני רוצה לדבר על הבלוקצ׳יין (Blockchain) ולפזר מעט ערפל / דיסאינפורמציה שקל ללקט מהעיתונות הכללית. הבלוקצ׳יין, בבסיס, הוא סוג של של רשת Peer-to-Peer לצורך אחסון נתונים. הבלוקצ׳יין הוא דיי חדשני, כפי ש Casandra או DynamoDB היו בזמנו – וקשה להשוות אותו למערכות קיימות אחרות. בפוסט, בעיקר ננסה להבין את הרעיונות העיקריים שעומדים מאחוריו.

בפוסט:

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

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

נתחיל לדייק בכך שבלוקצ׳יין אמנם הוא המונח שמתייחס למבנה-נתונים (״שרשרת של בלוקים״ = Blockchain) בו מאוחסן מידע כ״ספר חשבונות״ (Ledger), אך כאשר אנחנו מדברים על ״בלוקצ׳יין״ אנו מתכוונים לרוב לתאר פרוטוקול ורשת Peer-to-Peer החיה מסביבו.

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

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

בעצם כל ״מטבע״ מהנ״ל הוא בלוקצ׳יין, והמטבע הוא רק חלק או נגזר מהפרוטוקול. המונח ״ביטקוין״ מתאר גם את המטבע הדיגיטלי (₿) וגם את הרשת/פרוטוקול – ומכאן הבלבול, אך אתריום הוא שם הבלוקצ׳יין (המטבע: Ether), וסולנה גם הוא שם של בלוקצ׳יין (המטבע: SOL). דוג׳קוין הוא, כמו ביטקוין, גם שם של מטבע וגם שם של בלוקצ׳יין. הוא החל בתור בדיחה – אך נסחר לאורך השנתיים האחרונות בשווי מצרפי של עשרות מיליארדי דולר – מה שמעלה שאלות עקרוניות לגבי האופן שבו מטבעות דיגיטליים פועלים.

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

א-ריכוזיות (Decentralization)

התכונה הכי משמעותית של פרוטוקולי הבלוקצ׳יין היא הא-ריכוזיות שבה => decentralization. נקודה ראשונה שנרצה להבהיר היא ההבדל המהותי בין התכונות: ״distributed״ ו ״decentralized״.

רגע של עברית: לרוע המזל, המונח העברי מְבֻזָּר כבר ״נתפס״ לתיאור המונח האנגלי distributed – מערכת שמורכבת מחלקים שונים במיקומים שונים. נותרנו, דוברי העברית, בלי מונח ראוי לתאר את המונח decentralized. אני אשתמש בפוסט במונח אֲ-רִכּוּזִי, שאינו נפוץ / מקובל (עדיין).
הייתי שמח לחזור לשנות ה-80, ולשנות את המינוחים ל: distributed=מפוצל, ו decentralized=מבוזר. אם אתם מכירים אמצעי יעיל וזול למסע בזמן – אנא כתבו לי בתגובות.

תכונת הא-ריכוזיות משמע שהמערכת מאפשרת בעלות משותפת. כלומר: ניתן שלא יהיה גוף יחיד (חברה, מוסד, ממשלה, ארגון) המנהל את המערכת כרצונו – אלא המערכת מנוהלת ומשותפת ע״י מספר של גורמים לא-מאוגדים. כמובן שכל מערכת זקוקה לניהול, אך הניהול אינו פרי של החלטה או מדיניות אנושית: הניהול ״צרוב״ כמערכת כללים המוטמעים בפרוטוקול. להלן הביטוי: Code is law (הסרטון בקישור המצורף מדבר על Smart Contracts – שהם הרחבה של הרעיון הזה).

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

אתם בוודאי מבינים, שיש היבטים חברתיים עמוקים למערכת המבוססת רק על חוקים ממוחשבים, וללא הנהלה אנושית. למשל: מה קורה עם יוצאים מן הכלל? (בעיקרון: אין). מה קורה אם מישהו מוצא ומנצל פרצה בחוקים לטובתו בצורה שנחשבת ״אנושית״ לא הוגנת אך לא מפרה את הכללים? (לוקח הביתה 80$ מיליון, מבלי שברור אם ניתן לבצע אכיפה). מה קורה כאשר חוקים צריכים להשתנות (יש מנגנוני הצבעה על שינוי חוקים, שלעתים מסתיימים בפיצול הרשת ל-2, Fork, כאשר אין הסכמה גורפת). זהו נושא בפני עצמו – נמשיך הלאה.

א-ריכוזיות היא לא ערך מוחלט, שחור/לבן, כפי ש distribution הוא לא עניין מוחלט – אלא קשת של אפשרויות. בבלוקצ׳ינים רבים, מנסים להשיג רמה גבוה מאוד של א-ריכוזיות, כזו שלא תסתמך על קבלת החלטות אנושיות, והבעייתיות שלהן (למשל: הפד ״הדפיס״ 8 טריליון דולר מאז המשבר של 2008, מה שמשרת גופים מסוימים יותר מאחרים).

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

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

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

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

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

האינטרנט שינה את העניין הזה: אין כסף מזומן באינטרנט. העברות כספים מתרחשות דרך גופים ריכוזיים (בנקים, מסלקות, חברות אשראי) המנהלים את המסחר. מערכת SWIFT היא מערכת המנוהלת ע״י חברה בלגית המפוקחת / מנוהלת ע״י בעלי האחזקות בה (בנקים שונים) + הבנקים המרכזיים של מדינות ה G-10. לכאורה מדובר במודל שיתופי, אך זה לא מודל א-ריכוזי => בעיקר בגלל שהגורמים השולטים במערכת הם מאוגדים. בהסכמה ביניהם, הם יכולים לפעול ע״פ האינטרסים שלהם עצמם (ונגד טובת הכלל): כמו ניתוק של מדינה מהרשת, או שינוי הכללים ברשת באופן כזה או אחר. הבנק המרכזי של מדינת ישראל, או של יוון – לא יכולים להצטרף לניהול ה SWIFT. זהו מועדון סגור.

The one thing that's missing, but that will soon be developed, is a reliable e-cash – a method whereby on the Internet you can transfer funds from A to B without A knowing B or B knowing A

Milton Friedman – 1999

השאיפה ״לחזור״ למערכות מסחר א-ריכוזיות באינטרנט אינה חדשה. יש דיון ער האם זו שאיפה בעיקר של אלו שנדחקו לשוליים (מסחר במטבעות קריפטוגרפים פורח באפריקה [מערכת בנקאות רעועה], תורכיה, ויאטנם [מדינות במשבר], ובקרב גורמים פליליים/מפוקפקים) – או שזה אינטרס של כולם, שיעשה את העולם למקום טוב יותר?

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

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

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

הדרך – עוד ארוכה.

מבט טכני

בלוקצ׳יין מוגדר כ Distributed Ledger Technology (בקיצור: DLT) – ספר חשבונות מבוזר, והוא ה DLT המוכר והמשפיע בעולם, נכון להיום.

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

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

התכונות הטכניות העיקריות של הבלוקצ׳ין הן:

  • Decentralized – א-ריכוזיות: כמו שתיארתי למעלה.
  • Distributed – מבוזרות, הנגזרת במידה רבה מתוך תכונת האי-הריכוזיות.
  • Permanent – מידע רק נוסף לבלו׳ציין, ולעולם לא נמחק / משתנה בו. אפשר לומר: Immutable ו write-only (דרישת ליבה של ספרי-חשבונות).
  • Permissionless – כל אחד יכול לגשת ולקרוא את כל המידע בבלוקצ׳׳ין. כל אחד יכול להוסיף לבלוקצ׳יין טרנזקציות (תחת עמידה בכללים מסוימים).
    • מוביל ל Transparent (שקיפות) – כל מה שקורה על הבלוקצ׳יין פתוח לכל החברים ברשת. דמיינו מערכת שכל המסמכים והפעולות של הבנקים / חברות-האשראי פתוחים לכל: לבקרה וביקורת של כל עיתונאי או גורם בעולם.
    • עם הזמן, עושים הבחנה בין בלוקצ׳יין שהם ״ציבוריים״ (ולכן: Permissionless) לבין כאלו שהם ״פרטיים״ (ולכן, אין להם את תכונת ה Permissionless ו/או Transparency).
  • Consistent – עקביות: על אף שגורמים שונים ולא מתואמים רושמים לבלוקצ׳יין – הרישום יהיה אחד ויוסכם על כולם. ייתכנו רגעים קצרים של חוסר עקביות – שיתוקנו בזמן קצר.
  • Global Scale – הבלוקצ׳יין תוכנן להיות מערכת גלובלית, באופן דומה לזה שהאינטרנט הוא מערכת גלובאלית. יש כיום כ 1000 בלוקצ׳יין גלובאלים אך ניתן להשתמש בבלוק׳ציין כמערכת פרטית / מקומית, ויש לא מעט ספקים שיעזרו לכם להקים ״Blockchain ארגוני״ (למשל: יבמ, AWS, Linux foundation, ועוד).

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

Node ברשת הבלוק׳ציין כולל קבוצה של פונקציות שהרצת נדרשת על מנת להשתתף ברשת. לכל Node ברשת הביטקוין יש רכיב רשת ורכיב ״בסיס-נתונים״, פונקציות ה mining וה wallet הן אופציונליות ע״פ השימוש.

חלק מה Nodes ברשת יחזיקו את הבלוקצ׳יין (״בסיס הנתונים״) המלא: כל הבלוקים שאי פעם נוספו לבלוקצ׳יין. ה Nodes הללו נקראים "Full Nodes״ והם בעצם ה backbone של הרשת / מערכת הבלוקצ׳יין.

בלוקים נוספים יחזיקו חלק מה Blockchain (ההיסטוריה הקרובה), וגם הם (בנוסף ל full nodes) מסוגלים לאמת טרנזקציות – הם נקראים Lightweight nodes. אם Lightweight node רוצה להוסיף בלוק לבלוקצ׳יין (״ספר החשבונות״) הוא יעזר ב Full Node לצורך התהליך.

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

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

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

בנוסף ל nodes העיקריים ברשת הביטקוין שעתה ציינו, יש עוד שרתים המריצים פרוטוקולים תומכים: Mining Pools Protocols ו lightweight access protocols – שלא נעסוק בהם בפוסט.

תהליך הקונצנזוס

הבלוקצ׳יין, כפי שציינו, הוא write-only, ולכן הפעולה החשובה ביותר בו – היא פעולה של כתיבה. הכתיבה נעשית ע״י הוספת בלוקים חדשים לשרשרת וכל Node עם יכולות של Miner יכול לעשות זאת. האתגר הגדול הוא לוודא שאותו כורה אנונימי, שאנחנו לא סומכים עליו – יוסיף בלוק ע״פ כללי הפרוטוקול, בלי לשגות ובלי לרמות. בניגוד למערכות מבוזרות ״רגילות״ בהן כל ה nodes עובדים על בסיס אותו הקוד / מתוך אמון הדדי – הנחת היסוד של מערכת א-ריכוזית היא שכל node ברשת הוא פוטנציאלית עויין – וינסה לרמות.

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

ברשת יש אלפים רבים של nodes, שאפשר להניח שחלקם (אולי אפילו רבים מהם) היו מעוניינים לרמות. איך אנחנו בוחרים ב node שיכתוב את הבלוק הבא?

במערכות מבוזרות קיימים אלגוריתמים של Leader Election שמתמודדים עם מגוון בעיות ותקלות – אך לא עם רמייה מכוונת. רשת הבלוקצ׳יין הייתה צריכה למצוא אלגוריתם חדש, שיתמודד גם עם רמייה.

יש מגוון אלגוריתמים של Consensus במערכות בלוקצ׳יין, והמשותף לכולם הוא הצורך ב״יישור התמריצים״ (Incentive alignment): שלכל Node ברשת יהיה משתלם הרבה יותר לנהוג ע״פ הפרוטוקול – מאשר להפר אותו. המחירים הנדרשים ליישור תמריצים שכזה הם כיום גבוהים מאוד. ספויילר: כמות החשמל (עבור חישוביות) שרשת הביטקוין דורשת בכדי ליצר קונזנוס שווה לתצרוכת החשמל של כל מדינת תאילנד (כסדר גודל יותר מ AWS, למשל). עולם הבלוקצ׳יין מפתח ועובר בהדרגה לאלגוריתמים יעילים יותר אנרגטית – ובשאיפה הבזבוז האדיר הזה ייפסק בשלב כלשהו.

לפני שנעבור לתיאור תהליך הכרייה עצמו, אציין עוד מגבלות עקרוניות של מערכות הבלוקצ׳יין (כפי שהם כיום):

  • Not Scalable – למרות שבלוקצ׳יין תוכננה כרשת גלובאלית, ואין לה מגבלה טכנית על כמות החברים ברשת או כמות המידע שייכת, קצב כתיבת המידע הוא מוגבל:
    • לא ניתן לרשום בקצב מהיר יותר ממה ש miner node יחיד מסוגל לכתוב. ברשת ביטקוין זה בלוק של 1MB כל עשר דקות. בביטקוין הרשת יכולה להוסיף כ 7 טרנזקציות בשנייה. זה קצב מאוד נמוך יחסית למערכות אחרות (למשל: VISA יכולה לעבד 65K טרנזקציות בשנייה).
    • מרגע שהרשת הופכת לפופולארית, ויש תחרות עזה על ביצוע ה Mining – הכח החישובי הנדרש על מנת להשיג קונצנזוס – מרקיע שחקים.
    • יש מגוון של פיתוחים שאמורים לשפר את ה Scalability של הרשת: גם את אלגוריתם הקונזצנוס שידרוש פחות חישוביות (סולנה – וגם את היכולת לכתוב יותר טרנזקציות בפרק זמן נתון לבלוקצ׳יין. השיפורים הקרובים אמורים לשפר את שני המדדים בסדרי גודל.
    • בלי שיפורים משמעותיים ב Scalability, הרעיון של מערכת בלוקצ׳יין – תקוע.
  • Privacy Concerns – רשתות בלוקצ׳יין הן Permissionless ו Transparent – שזו אחת התכונות המוערכות בהן. מצד שני, כאשר הן ציבוריות – משמע שיש חשש גדול פרטיות.
    • אמנם הטרנזקציות ברשת ביטקוין (לדוגמה) נרשמות ע״פ Address שאף אחד לא יודע לקשר לאדם מסוים, אולם אם ה Address הזה זולג ויודעים שהכתובת abcd היא אני – כולם יכולם לעקוב ולראות בדיוק אלו תשלומים ביצעתי / קיבלתי. מכיוון שהבלוקצ׳יין הוא Permanent – לא ניתן למחוק את המידע או to obfuscate it בכדי להגן על הפרטיות שלי מרגע החשיפה.
    • קישור של אדם לכתובת יכול להתבצע גם ללא דליפה ישירה. למשל התפרסם שקיבלתי כמות ביטקוין מגורם מסוים. זכייה בפרס, למשל. אפשר לעשות reverse engineering על הבלוקצ׳יין ולהתחיל לצמצם אפשרויות ולהבין מה הכתובת שלי.
  • BlockChain interoperability – מערכת הבלוקצ׳יין היא מערכת סגורה: בתוך המערכת היא יודעת לוודא את השלמות של הנתונים. לו היה רק בלוקצ׳יין אחד עולמי – לא הייתה בעיה. אל מכיוון שהמגמה היא של ריבוי בלוקצ׳יינס – בשלב מסיום נרצה לבצע ״טרנזקציות״ ופעולות בין כמה בלוקצ׳יין. איך עושים את זה בצורה אמינה? מה הטעם בבלוקצ׳יינים אמינים, אם כל פעולה ביניהם – חוזרת להיות לא אמינה?

תהליך הכרייה, בגדול, כולל את הצעדים הבאים (לוגית* – לא מה שקורה בפועל):

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

בפועל מה שקורה הוא תהליך כזה:

  • כל ה Miner nodes הפעילים ברשת כותבים את הבלוק הבא – מקומית.
  • ה Miner nodes מתחרים ביניהם מי הראשון שישיג ״חתימה תקינה״ לבלוק שלו – בעזרת פעולת ״כרייה״: ביצוע חישוב מתמטי מורכב שלוקח, בממוצע, כ 10 דקות עד ש Miner ראשון בעולם מסיים אותו.
  • ה Miner שסיים ראשון – שולח לכלל הרשת את הבלוק המעודכן (והחתום) שלו. כל Node ברשת מאמת את החתימה (הקריפטוגרפית) – ומוודא שהיא תקינה, ואז מוסיף את הבלוק לעותק המקומי של הבלוקצ׳יין.
  • התהליך מסתיים שכל (או כמעט כל, הרי זו מערכת מבוזרת) ה Nodes ברשת קבלו את העדכון והוסיפו את הבלוק החדש לבלוקצ׳יין.

תהליך הקונצנזוס, אם כן, מתרחש בשלבים 2 + 3: פתרון הבעיה המתמטית – ואימות התשובה. תוך כדי פעולה, Miner nodes סוררים יכולים לשלוח עדכונים של בלוקים עם חתימה ״מזויפת״ – אך כל ה Nodes שיקבלו אותם – יתעלמו מהם.

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

גם כאן, יש תהליך של תיקון, ועם הזמן (לא אכנס לפרטים במסגרת הפוסט) – הרשת (בהתבסס על הפרוטוקול) תחליט איזה מהבלוקים התקינים הוא זה שימשיך הלאה – ושאר הבלוקים התקינים יוסרו מהבלוקצ׳יין. תהליך התיקון של הרשת בפני "רישום סותר של בלוקים״ עשוי לקחת מספר מחזורים של רישום בלוק (בביטקוין: מחזור ארוך יחסית של 10 דקות). התהליך הוא סטטיסטי, אך מקובל להניח שתוך 6 מחזורים (כשעה) – סתירות בין בלוקים יסתדרו. ההסתברות לכך היא כ 95% (תלוי במודל החיזוי שנעשה בו שימוש. גורמים ״חיצוניים״, כגון אמינות הרשת וה latency בין nodes שונים – משפיעים על התוצאה).

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

אלגוריתמי קונצנזוס

אלגוריתם הקונצנזוס של בלוקצ׳יין הביטקוין, נקרא Proof of Work (בקיצור PoW. יש שיאמרו שזה קיצור של "Proof of waste״ – בשל האנרגיה הרבה שנדרשת לחישוביות שלו).

בגדול, כל Miner node יוצר את ״הבלוק הבא״ ואז חותם אותו ב SHA-256 (פונקציית Hash קריפטוגרפית) ובודק את התוצאה. הפרוטוקול מגדיר יעד (להלן: target) של ביטים של אפסים שיופיעו בתוצאה. למשל: 10 ביטים ראשונים ב Hash צריכים להיות אפס כדי לקבל ״חתימה תקינה״.

הבלוק, להזכיר, מכיל Header ו Body (הטרנזקציות עצמן):

מבנה בלוק של בלוקצ׳יין של ביטקוין

את הטרנזקציות משדרים ה Nodes השונים ברחבי הרשת והם נשמרות במבנה מקומי שנקרא memPool. ייתכן (ואפילו סביר) ש Miners nodes שונים ירכיבו ״Next Block״ שמכיל טרנזקציות מעט שונות. זה תקין, ובכל מקרה רק בלוק אחד יתקבל בסופו של דבר. הטרנזקציות שלא נכללו, ייכנסו לבלוק מאוחר יותר.

בנינו את הבלוק שלנו, והעברנו אותו בפונקציית SHA-256 (אפילו פעמיים!), אבל מה… לא יצאו לנו אפסים בכלל! ה Hash שלנו יצא:
e56d336922eaab3be8c1244dbaa713e134a8eba50ddbd4f50fd2fe18d72595cd

להזכיר ש SHA-256 היא פונקציית Hash קריפטוגרפית, כלומר:

  • בעלת Diffusion: שינוי ב bit אחד ב input – ישנה לפחות כחצי מהביטים בתוצאה של ה Hash. כלומר: כל שינוי קטן ב Input ״מערבל״ Hash חדש לחלוטין.
  • Collision resistant: אין דרך (ידועה) ל״הנדס״ את ה Hash שייצא. איני יכול למצוא Input נוסף שייצור אותו Hash כמו Hash שקיבלתי. הדרך היעילה ביותר לקבל Hash מסוים היא לעבוד ב Brute Force ולנסות עוד ועוד Inputs. להזכיר שה Hash הוא של 256bit (כלומר: יש לי כ 1077 אפשרויות ל Hashes שונים), והיכולת למצוא Input שייצור Hash מסוים – אינה סבירה חישובית.
    • מציאת Hash מסוים היא בעיה בלתי-סבירה חישובית (כיום), אך מציאת Hash עם 10 ביטים ראשונים שהם 0 => היא בעיה חישובית אפשרית. עלי לנסות יותר ממיליון אפשרויות (הסתברותית) על מנת להגיע ל Input מתאים.

בתוך ה Header של הבלוק יש שדה בשם Nonce (פירוש: ״מקרה בודד״). זהו בעצם Counter של 32 ביט שמאפשר לי לרוץ על 4 מיליארד איטרציות שונות, בניסיון לקלוע לערך שיביא את ה Hash ל 10 ביטים ראשונים שהם אפס.

בעוד פעולת החיפוש אחרי Hash שעומד ב Target היא פעולה קשה, הדורשת דקות של עבודה מאומצת מחוות שרתים בת אלפי מחשבים – פעולת האימות של ה Hash היא פעולה קלה: אני מריץ פעולה יחידה של Hash על הבלוק – וסופר את מספר הביטים עם ערך 0. אם הם 10 או יותר – הבלוק תקין. האימות מתבצע ע״י כל ה Nodes ברשת הבלוק׳ציין – על מנת לאמת שבלוק הוא תקין / נבחר בצורה תקינה. יש עוד מנגנון קריפטוגרפי שמאמת שהטרנזקציות עצמן תקינות – לא אכסה אותו בפוסט.

ככל שכוח המחשוב של רשת הביטקוין גדל, מציאת Hash שעומד ב Target הוא תהליך שהולך ומתקצר. כל כשבועיים, פרוטוקול הבלוקצ׳יין של ביטקויין משנה את ערך ה Target (מספר הביטים שהינם אפס) לערך שייקח בממוצע לרשת כ 10 דקות לחשב. הדרישה למציאת Hash עם 11 או 12 אפסים – תקשה את הבעיה פי 2 או 4. לא בביטים ככל שכוח המחשוב גדל – הבעיה המתמטית נעשית קשה יותר, כך שזו תמשיך להיות ״בעיה קשה״. בעת כתיבת הפוסט הדרישה של הפרוטוקול היא ל 80 אפסים (כלומר: bits) – וכוח המחשוב שעומל על פתרון הבעיה, כל 10 דקות מסביב לשעון – הוא חסר תקדים. ה nonce, אם תהיתם – כבר אינו מספיק, וכורים משתמשים בכמה תרגילים (כמו ״משחק״ בזמן הטרנזקציה) על מנת שיוכלו לנסות יותר וריאציות.

מעבר ל Proof of Work

לא כיסינו את כל ההיבטים של אלגוריתם ה Proof of Work אך יש לו בעיות ברורות. בעיה אחת היא צריכת אנרגיה הולכת וגוברת ככל שיש יותר Nodes ברשת.

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

כשהפרוטוקול הוגדר, היה קשה לדמיין מצב שבו 51% מה Miner nodes מתאגדים. כיום, בשל אופי אלגוריתם ה Proof of Work ש״מעניש״ שחקנים קטנים – ישנן התאגדויות כרייה בשם Miner Pools. חוות כרייה רבות מצטרפות לאיגוד המתחלק ברווחים (מטבעות ביטקוין המתקבלים בעקבות רישום של כל בלוק) – ע״פ יחס כוח החישוב של החברים, כך שגם חוות כרייה קטנה יחסית (מאות מחשבים בלבד) – יכולה להיות רווחית.

הא-ריכוזיות של ביטקוין – נמצאת במגמת ירידה. הפתרון לשתי הבעיות הללו הוא אלגוריתם בשם Proof of Stake (בקיצור: PoS) בו אין צורך לבצע חישוב מתמטי מורכב על מנת להיבחר לכתוב את ״הבלוק הבא״ אלא כל Miner מציע כמות של מטבעות כערובה לרצון שלו לכתוב בלוק. ככל שההצעה הכספית (Stake) גבוהה יותר – כך הסיכויים ״לזכות״ בכתיבת הבלוק הבא – גדלים. מצד שני, אם הבלוק שייכתב לא יהיה תקין המטבעות שהצבתי כערובה (Stake) – יילקחו ממני.

Proof of Stake אמור לצמצם דרמטית את דרישות החישוב של פרוטוקול הבלוקצ׳יין, וגם לייתר את הצורך בהתאגדויות של Mining Pools. הוא עדיין לא מושלם – ויש וריאציות רבות שלו, שבלוקצ׳יינס שונים מנסים.

ביטקוין עצמו נחשב בלוקצ׳יין שמרני מאוד, ולא נראה שיעבור ל PoS בקרוב, אך בלוקצ׳יין אתריום נחשב למאמץ נלהב של חידושים, ומזמן הכריז על מעבר ל PoS. מסיבות טכניות (מערכת מורכבת => שינויים הם קשים) המעבר הזה נדחה, וכרגע במקום היעד של יוני 2022, נראה שהמעבר יסתיים רק ב 2023.

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

סיכום

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

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

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

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

על מובילות-הנדסית

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

מדוע אני לא מתרגם את המונח ל״מנהיגות טכנולוגית״?

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

למה לכתוב פוסט על הנושא?

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

"ליאור, ה Tech Leadership זה התפקיד של ה Tech Lead בחברה, נכון? זה שלהם?״

חחח.. 😄😄

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

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

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

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

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

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

בואו נצלול ונדבר בפירוט על כל התנהגות.

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

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

סימן ראשוני חיובי לפוטנציאל (יָכְלָה בעברית) להובלה הנדסית היא הנטייה לשאול ״שאלות טובות״: שאלות שמראות עומק, סקרנות, הבנה, והשתחררות מדּוֹגְמוֹת חשיבה מקובלות.

⚠️ מנהלים לפעמים מזהים את התכונה הזו – ו״פוטרים״ אותה: ״הוא שואל שאלות מעניינות, אבל הוא עדיין ג׳וניור…״. זה פספוס!
כדאי לאתר את האנשים שמציגים את ההתנהגות הזו (במידה והיא חוזרת על עצמה, ואינה חד-פעמית), לשים לב אליהם, ולנסות לאתגר אותם בהתנהגות הבאה: סיכום ופיזור ידע.

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

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

  • האדם מראה התעניינות כנה בנושאים שונים במערכת / עבודה, גם כאלו שאינם זקוק להם לצורך המשימות השוטפות. בנוסף: הוא מראה עניין בנושאים שעשויים להיות רלוונטיים.
    • אין משהו רע בהתעניינות בקריפטו, ב Deep Learning, או מחשוב קוואנטי. מצד שני: אם אלו אינם נושאים שקשורים לעבודה שלכם – הסקרנות הזו כנראה תמשיך להיות מקבילה לעבודה, ולא כדאי להסיק ממנה על התנהגות האדם בנושאי-עבודה.
  • האדם מפתיע ב״שאלות טובות״, במיוחד אם לא ציפינו שהניסיון שלו ו/או הידע שלו מספיק כדי לשאול אותן.
  • האדם קשוב לתשובות, ויכול לשנות את דעתו – אבל גם להמשיך ולפתח את הרעיון ולהמשיך לשאול שאלות טובות בהמשך הדיון (כלומר: אינו "one trick pony״).

סימנים מחלישים:

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

התנהגות ליבה: לזקק ולפשט ידע – ולפזר אותו לאחרים.

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

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

⚠️ אם אתם מנהלים ואתם מקדמים למרכז הבמה את ה״מרשימנים״ (שהרבה פעמים הם אנשים אינטליגנטים ובאמת מרשימים) ולא את ״המפשטים״ – שהופכים נושאים גדולים => לעניינים קטנים ומובנים, אזי אתם עושים עוול לא רק ל״מפשטים״, אלא גם לארגון.

סימנים מחזקים:

  • לאדם יש יכולת לתמצת דברים בכל מסגרת זמן נתונה: רבע שעה, דקה, או משפט. כתרגיל מחשבתי: בקשו מהם להסביר בציוץ טוויטר משהו – והם יכולים לעשות זאת.
    • היכולת הזו אינה מובנת מאליה בכלל, וחשוב להעריך ולפתח אותה. מי שיודע לפעמים לתמצת – בקשו ממנו לעשות את זה יותר. בהתחלה זו עבודה קשה, אבל עם הזמן מיומנות התמצות והביאור משתפרת – וזה הופך לתהליך קל, טבעי, ואפילו – אוטומטי.
Thread מוצלח, מעבר לדוגמה שבתמציתיות
  • כשהאדם מעביר ידע, הוא לא מעביר אותו בדיוק כפי שקיבל אותו – אלא מוסיף לו ערך ע״י תימצות, המחשה, דוגמאות משופרות, וכו׳.
    • היכולת של Martin Folwer לקחת את ספר ה UML User Guide בן 500 עמודים, ולהפוך אותו לספר קליל של 200 עמודים. לצמצם את מספר סוגי הדיאגרמות לשימוש ב UML מ 14 ל 8 => זה פישוט אמיתי. הספר UML Distilled הפך מיד למקור המקובל ל UML, וסיפק המון ערך לכלל התעשייה.
  • הרצון הכן, לא לשמור ידע בבטן, אלא להפיץ את הידע לאחרים – שעשויים ליהנות ממנו.
  • דוגמה טבעית מאוד ליכולת לזקק ידע ולהפיץ אותו – היא הנטייה לשפר קוד, ולא קוד שהאדם הוא דווקא הכותב המקורי שלו: שינוי קוד מורכב כך שיהיה פשוט יותר, החלפת שמות משתנים לשמות משמעותיים יותר, שימוש בקונבנציות ברורות יותר, וכו׳.

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

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

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

סימנים מחלישים:

  • האדם טוען לא פעם את הטענות ש ״הנושא הזה מסובך מדי כדי להבין״ ו/או ״חבל על הזמן שלך לנסות להבין את זה״.
    • למרות שהדבר יכול להתפרש שדאגה כנה לזמן והבריאות הקונטיבית של המאזין, לרוב מדובר בחוסר יכולת לפשט ולהסביר נושאים, ו/או חוסר עניין לשתף לעומק. פעמים רבות, זה נעשה באופן מאוד נחמד וידידותי, שמקשה עלינו להצביע על הבעיה.
    • ככל שנושא מסובך יותר – כל יש יותר ערך בפישוט שלו. אדם בעל נטייה לפשט לא יוותר על ההזדמנות הנהדרת כזו להשתמש ביכולות שלו ולספק ערך.
  • חוסר יכולת לארגן ידע, בעל-פה ו/או בכתב – הוא אינדקטור שלילי ברור. אם מישהו לא מסוגל לכתוב פסקה שתיים על נושא, ליצור דיאגרמה פשוטה שמסבירה את העניין – גם לאורך ימים, כנראה שהוא: א. לא יודע, ולא מודע לזה מספיק טוב. ב. בעל קושי ״לארגן את הדברים בראש״, יכולת מאוד חשובה להתמודדויות מורכבות בהנדסת תוכנה. לפעמים זה עניין של מיומנות, ולעתים עניין של יכולת.
  • ארגון מידע טרחני, לפעמים נתפס כ״יכולת לארגון ידע״ – אך הוא לא אותו הדבר. האדם שכותב מסמכים של עשרות עמודים היכן שהיה ניתן להסתפק במסמך באורך מספר חד-ספרתי של עמודים, מפספס משהו. אולי יש לו רצון כן לשתף ידע, אך ללא יכולת זיקוק, ארגון, ושיפור הידע – הערך קטן משמעותית. הסיבה לכך היא שזיקוק ידע מוביל ליעילות גבוהה יותר, וגם לפריצות דרך וחדשנות. פישוט + פישוט + פישוט => פריצת דרך אפשרית.
    • אני לא טוען שארגון ידע ״טרחני״ הוא חסר ערך. הוא פשוט בעל ערך נמוך יותר. זו לא המיומנות שאנו שואפים אליה.
  • בקוד: הנטייה להציג פתרונות קוד סבוכים ומרשימים (Clever but not very clear) – היא סימן אזהרה למישהו שאין לו יכולות או מוטיבציה לפישוט. לא פעם יהיה בקוד הזה רעיון מתוחכם (רקורסיה משולשת שחוסכת את הצורך ב storage) או מרשים (פיתחתי שפה ל Dependency Injection) – אבל זו רק הסוואה לחוסר היכולת לפתור את הבעיה בעזרת ארגון מידע – ושימוש בכלים פשוטים וסטנדרטיים של שפת התכנות.
    • לפעמים זה עניין של מוטיבציה: הרצון להרשים שגדול יותר מהרצון באמת לעזור לאחרים (במחיר קוד לא מובן / קשה לשינוי => עוול).
    • כאשר יש רצון אמיתי ותמידי לפשט דברים, גם קוד מסובך (כי לא הצלחנו לכתוב קוד פשוט בסיבוב הראשון) – הופך לפשוט (refactoring) עם הזמן.

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

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

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

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

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

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

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

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

יש את ה "Beneficial Clerks״ – אנשים המכירים את הנהלים / סטנדרטים / מערכת / ארגון / ביזנס, אכפת להם מהמתרחש והם יפעלו לפעול לפי הכללים וגם לשפר אותם. הם בהחלט מועילים וחשובים לארגון – אך פחות משמעותיים מאלו שמאתגרים את המערכת. Benefitial Clerks הם לא מובילים טכנולוגיים, או לפחות כאלו רק במידה הפחותה של המושג. מיקרו-מובילים.

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

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

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

סימנים חיוביים:

  • נטייה של האדם לשפר דברים שונים שהוא ״נוגע״ בהם. זה יכול להיות דברים קטנים כמו: קוד, מסמכים, ארגון סביבת העבודה וכאלו – אבל אם האדם הצליח לשפר היכן שמסתובבים רבים אחרים שלא זיהו את ההזדמנות ולא שיפרו – זה סימן חיובי מובהק.
  • נטייה של האדם להשמיע את דעתו (speak out) – ובצורה עניינית.
    • אם הדברים של האדם הם לא נכונים או נאיביים – זו לא אינדיקטור לחוסר מובילות, אלא יותר לחוסר חיבור למידע. בוודאי אם מדובר במפתח בצוות, ולא בתפקיד רוחבי או בכיר יותר.
    • לא-פעם מובילים שנתקלתי בהם נתפסו כאנשים שליליים: ״מלאי ביקורת״, ״תמיד רואים את חצי הכוס הריקה״, ״לא מרפים״. אני משתדל מאוד להתעלות מעל האינסטינקט להתבאס, ולהבין האם בצד הביקורת באה הצעה עניינית לשיפור. אם כן – אני מוקיר את האדם, ולומד ״לסנן רעשים״. לפעמים אפשר לעזור גם לאדם לשפר את הסגנון שלו לפחות שלילי – אבל זה לוקח זמן.
      • אישית, אני מעדיף לעבוד בסביבה בה אני צריך לסנן ולהכיל אמירות מבאסות או סגנון ביקורתי חזק, מאשר בסביבה בה אנשים לא מזהים הזדמנויות שיפור ו/או לא אכפת להם מספיק. אני יודע שלא כולם שותפים להעדפה הזו, אבל מבחינתי זה ROI positive לחלוטין: בלי ביקורת, קשה מאוד להשתפר, ולעשות טוב יותר. סגנון שלילי אפשר לרכך לאורך זמן, חוסר מעורבות – הרבה יותר קשה.
  • יכולת ביצוע, אינה תנאי מספיק – אך זהו לרוב תנאי הכרחי. העולם נבנה ע״י אנשי-מעשה, ולא ע״י תאורטיקנים (שגם להם יש תפקיד).
    • עוד מדד מעניין מבחינתי הוא היכולת לבצע ״משהו חיובי״ במסגרת זמן קצרה מאוד. אנשים שמסוגלים לספק ״משהו חיובי״ (רעיון, מסמך, דוגמאת קוד) בכמה שעות – הם בעלי סיכוי הרבה יותר גבוה להגיע לאימפקט תדיר מאלו שצריכים ״לפחות יומיים״ כדי להתארגן ולהציג ״משהו חיובי״ (ואז, אולי הוא יהיה גדול מדי).

סימנים מחלישים:

  • נטייה של האדם להשמיע את קולו בצורה לא עניינית, ללא חשיבה לפחות על ״הצעד הבא״ עלולה לבלבל: האם יש פה מובילות לא בשלה? או שלאדם חשוב יותר להישמע מאשר להשפיע?
    • קשה לי לענות בצורה גנרית, אבל אני נוטה לראות בהשמעת קול ללא התעמקות כסימן מחליש. עקבתי אחרי מספר אנשים כאלו לאורך שנים, שלמרות התקווה שיתפתחו להיות מובילים איכותיים – זה פשוט לא קרה. נראה התעמקות היא לא יכולת לא שגְּדֵֵלָה מעצמה ב cubicals של משרדי הייטק, והיא זקוקה משהו מעבר.
  • אנשים שמתלוננים בדיעבד על מה שנעשה – לפעמים רק רוצים לשחרר תסכולים. אם לא הגיבו בזמן שהדברים קרו, והם באים עם תלונה / תסכול – אך ללא תוכנית פעולה / רעיון לשיפור, יותר סביר שאתם חוזים בסגנון של שחרור קיטור, ולא בניצנים של מובילות.
  • לא מעט מנהלים מנסים לשמר את ״האווירה השלווה בצוות״, ותוך כדי כך מתנגדים לביקורת, מתוך היותה ביקורת. סביבה בה מנהלים שמים יותר משקל ומאמץ על ״שלווה״ מאשר על ״מצוינות״ – היא סביבה בה קשה במיוחד למובילים להתפתח.
    • מנהלים שמעדיפים ״שלווה״, כמובן, ינסו לנמק ולשכנע שזה הצעד הניהולי הנכון, וירבו להדגיש רגישויות של עובדים בצוות, כשיקול העיקרי לעניין.

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

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

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

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

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

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

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

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

סימנים מחזקים:

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

סימנים מחלישים:

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

סיכום

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

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

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

שיהיה בהצלחה!

על Engineering Managers (חלק ב')

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

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

"מנהל טכנולוגי" מול "מנהל אנשים"

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

בהיתוך הזה יש Tradeoff בין שתי חלופות קיצוניות:

  • לשכור ארבעה מנהלים => משכורת מנהל × 4, אבל יותר גרוע: תקורת התקשורת וההסכמה בין 4 מנהלים לגבי פעילות הצוות => קבלת החלטות איטית יותר, והחלטות פחות אמיצות (כי צריך לפשר בין כולם).
  • לתת את כל העבודה למנהל יחיד, משמע קושי ממשי למצוא אדם בעל כל היכולות (קושי בהשמה / גיוס). בנוסף: אותו האדם יעמוד בעומס גדול מאוד של נושאים בהם הוא צריך לטפל / להתמקצע (ולהישאר מעודכן).

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

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

הקונצנזוס הוא בהחלט על מומחיות המוצר, בדמות Product Manager / Expert כתפקיד נפרד. חשוב עדיין למנהל ההנדסי להבין ולדעת על המוצר – אבל הוא לא יוביל ולא יהיה המומחה הראשי לראיית המוצר. לעתים יש נטייה להעביר למנהל המוצר גם ניהול פרויקטים – מה שלרוב עובד לא-טוב. כתבתי על זה בפוסט על DevProd.

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

התחום שיש לגביו את הקונצנזוס שבכל מקרה עליו להישאר אצל המנהל ההנדסי הוא תחום ניהול האנשים. מלבד SCRUM שבתאוריה דורשת שה SCRUM Master לא ינהל אנשים (מה שלא קורה לרוב בפועל, לפחות לא בחברות ישראליות) – בכל הגישות המקובלות האחרות – ניהול האנשים נותר בידי המנהל ההנדסי. אין מה לעשות: להיות המנהל של המהנדסים נותן למנהל Leverage משמעותי בהשפעה על חברי-הצוות. שווה לציין ש SCRUM הולך ונעלם מהחברות המובילות ונותר (ביחד עם וריאנטים כמו SAFE) בעיקר בחברות פחות-טכנולוגיות / סוכנויות ייעוץ. הנה סקירה 1 וסקירה 2 של המגמות האלו (בקישורים דנים גם בנושא הפוסט: כיצד לחלק את ההיבטים השונים של הניהול ההנדסי). על דעיכת הסקראם בחברות המובילות כתבתי בעבר (עוד לפני שהבנתי שזו מגמה רחבה) בפוסט על NoSCRUM.

אז ניהול האנשים נותר בידי המנהל ההנדסי, ולרוב הוא מקבל תמיכה בתפקיד הזה מהמנהל שלו ו/או מחלקת ה People/HR בדמות תפקיד שנקרא Busines Partner. סיכום ביניים:

  • ניהול אנשים נמצא בידי המנהל ההנדסי – בתמיכה קלה מבחוץ (Coaching/Mentoring)
  • ניהול המוצר – נמצא לרוב בחוץ, אך נדרש מהמנהל ההנדסי להבין בתחום בכדי להיות חוליה מקשרת משמעותית של הצוות לניהול המוצר.
  • נשארו שני תחומים שהם באזור האפור / לא חד-משמעי: ניהול פרויקטים והובלה טכנולוגית.

אולי הכי טבעי להפריד את ניהול הפרויקטים? הרי יש תפקיד כזה בתעשייה: "מנהל פרויקטים" (Project manage).

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

החלופה שכן נראה שמצליחה לעבוד היא תפקיד בשם מנהל פרויקטים טכנולוגי (Technical Project Managers או TPM): מהנדס בעל יכולות ניהול פרויקטים שמבצע ניהול פרויקטים טכנולוגי (בקיא ומבין את ההיבטים הטכנולוגים של הפרויקט והעשייה ההנדסית בכלל) – וכך מוריד עומס מהמנהל ההנדסי. TPM, לא פעם, זו עבודה במשרה מלאה – כלומר: ה TPM, למרות שהוא מהנדס לא ישתתף בכתיבת קוד – אך בהחלט ישתתף בדיונים טכניים שנוגעים לפרויקט (אינטגרציות, צווארי בקבוק, וכו').

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

כדרך אגב: מודל נוסף ששווה לציין הוא ה Single Threaded Owner (בקיצור STO), מודל שהגיע מאמזון ובו המנהל ההנדסי הוא אחראי על כל פעילות הצוות (כל 4 התחומים), אבל ע"פ הצורך – הוא ממנה איש מוצר או TPM בכדי לעזור לו. הכוונה היא ליצור צוות אוטונומי באמת, בלי תלות בגורמים חיצוניים, רעיון שמתחבר חזק עם תרבות ה DevProd.

התפקיד השני שיכול להוריד מעמסה מהמנהל ההנדסי ולתמוך בו הוא תפקיד המוביל הטכנולוגי (Tech Lead) – תפקיד שיש לו וריאציות רבות (חבר צוות, מקביל לראשי הצוותים, וכו'), וננסה לתת דגשים כיצד הוא יכול לעבוד ולתמוך בראש צוות פחות טכנולוגי.

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

המנהל ההנדסי הטכנולוגי לרוב לא יהיה פנוי לניהול פרויקטים מורכבים, ולכן יסתייע ב TPM. זה יכול להיות חבר צוות (מהנדס) שמונה להוביל פרויקט קטן (או כמה כאלו במקביל), או מישהו בתפקיד שלם כזה (נתקלתי בטייטלים כמו Flow Owner, Feature Owner או Squad Lead – שבפועל היו דומים מאוד ל TPM). כמובן שאין צורך ב TPM ייעודי לניהול כל פרויקט – רק פרויקטים מורכבים שמעבר ליכולתו של חבר-צוות לנהל. ניהול של פרויקטים פנימיים של הצוות / קטנים ע"י TPM, הם bad smell של חוסר delegation של המנהל ההנדסי. ברגע שיש TPM במשרה מלאה, שעושה את עבודתו היטב, הוא יכול להדריך / לחנוך מפתחים בצוות שרוצים עוד אחריות, וללוות אותם בהובלת פרויקטים קטנים.

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

מודל שני: המנהל ההנדסי הפרויקטאלי (בנקרא בחוסר דיוק: People Manager – אבל שימו לב שהם לרוב מקדישים תשומת לב העיקרית שלהם לניהול פרויקטים, ולא לצדדים "האנושיים"):

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

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

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

מה עם מנהלים הנדסיים שעובדים מצד אחד עם TPM, ומצד שני עם Tech Lead – והם מתמקדים רק בניהול האנשים, הבנה מוצרית, ומנהיגות? זה נראה אפשרי (ואולי נחוץ) ברמת ה Executive (נניח VP R&D) – אך תפל וחסר טעם ברמה של מנהל זוטר או דרג ביניים. עובדים בכל הרמות זקוקים למישהו שיבין לעומק מה הם עושים, יציב להם מראה ופערים היכן יכלו לעשות טוב יותר – וילווה אותם לשיפור. אם המנהל שלי לא תורם לי בזה, וכל הפידבק המשמעותי שאני מקבל מגיע מאנשים אחרים (מפתחים אחרים, TPM, Tech Lead) – נראה לי שמשהו גדול חסר. למה אני כעובד, או הארגון – זקוקים למנהל שרק מנהל "תנאי שירות"?!

ברצינות?! זה הכול? [אכזבה צפויה]

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

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

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

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

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

איך לעשות את זה נכון?

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

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

  • "הראש צוות הזה לא מבין מהחיים שלו. בסדר, הוא ימשיך לטעון שאין פה בעיה וכל המוצר הזה לא יעבוד יהיו טונות של באגים. הוא מוביל לזה – שיאכל את התוצאות (נאמר ע"י Tech Lead)".
  • "חחחח… לא. זה עניין של ניהול פרויקטים. דברו עם ה TPM ותסתדרו איתו. לא עובד? אנא פנו ל chief TPM. אני לא הכתובת (נאמר ע"י מנהל הנדסי)".
  • "תגיד בדיוק מה הדרישות הטכנולוגיות שלך – ונעשה אותן, אבל אני צריך הכול רשום עד לראשון לחודש – ובלי חרטות ושינויים (נאמר ע"י מנהל הנדסי למוביל הטכני)".

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

חשוב שתהיה שותפות אמיתית ואחריות משותפת. גבולות אחריות מעט מטושטשים – זה דווקא דבר בריא בקשר בין מנהל הנדסי ומנהל-תומך (TPM, Tech Lead).

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

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

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

בואו ננסה לעשות את אותו התרגיל למנהלים הנדסיים פרויקטליים המלווים במוביל טכני (Tech Lead):

צלעהתנהלות בקצה הנמוךהתנהלות בקצה הגבוה
הבנה מקצועית
(המנהל הפרויקטלי נסמך אל מוביל מקצועי, אך הוא צריך להבין ולבקר אותו כל הזמן, ולא להיות "לקוח שבוי או נרפה".)
* מתמקד ב Delivery ומגדיל בעקביות חוב-טכני עמוק על מנת לקדם אג'נדה עסקית קצרת טווח.
* מוותר על הצלע המקצועית, ואינו מעורב בצד המקצועי של עבודת הצוות. עושה "מיקור חוץ" של הטכנולוגיה למוביל הטכנולוגי – ולא מבין שזה תנאי מספיק לעשות "מיקור חוץ" לו עצמו, כמנהל הנדסי 🙂
* לא מודע למגבלות שלו ולוקח החלטות טכנולוגיות בלי גיבוי / בדיקה מספיקה מהיועץ הנאמן שלו. "זו החלטה ניהולית" – היא לא גישה טובה.
* בונה קשר פעיל ופורה עם המוביל הטכנולוגי, ונותן לו מקום להשפעה אמיתית בצוות. דורש ממנו, ומגבה אותו היכן שצריך.
* דואג שהצוות מאוזן בין deliveries, פשטות הארכיטקטורה וחוב-טכני.
* עוקב ומקשה על המוביל הטכנולוגי – מוודא שהוא מעורב בנקודות הקריטיות, ומאמת / מצליב את דבריו והחלטותיו מול המהנדסים.
אחריות להדרכה מקצועית
(המנהל אינו מקצועי בעצמו, אך זו אחריות שלו שהעובדים שלו יפותחו מקצועית, וברמה גבוהה)
* לא לוקח אחריות אמתית על הפיתוח המקצועי של העובדים שלו. מוסר את הנושא למוביל הטכנולוגי, במתכונת "שגר ושכח". מוריד מעצמו אחריות.
* עובדים תחת המנהל המקצועי לא משתפרים – בראייה של הצוותים הסובבים אותם. תלונות על חברי צוות חוזרות על עצמן לאורך זמן.
* מוודא שהעובדים תחתיו זוכים לפידבק משמעותי ותכוף מהמוביל הטכנולוגי – פידבק שהעובדים יודעים להעריך ככזה. דואג לעקוב ולהבין את הפידבק ומוודא שהעובדים "עובדים" על הפידבק בצורה יעילה.
* מעורב בפניות ודילמות לגבי מקצועיות של העובדים, ומוודא שהן מטופלות כמו שצריך: עובדים שיש להם פערים – מודעים לזה ועובדים על הנקודות הנתונות. הטרדה של עובדים בתלונות שווא – מזוהות ונהדפות.

מה עדיף? מנהלים הנדסיים טכנולוגיים או פרויקטליים?

נניח ואין ברשותנו מספיק מנהלים הנדסיים "well rounded" – מה עדיף? להתמקד במנהלים הנדסיים טכנולוגיים או פרויקטליים? את מי לקדם? מה לגייס?

אין כמובן תשובה אחת, נכונה בהחלט, וכוללנית – אבל נראה שהמפתח הוא איזון + התאמה לצרכים.

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

לגבי התאמה לצרכים: יש ארגונים שהם יותר טכנולוגיים מאחרים ב core business שלהם. הארגון שמפתח את בסיס הנתונים MySQL כנראה זקוק להטיה טכנולוגית חזקה יותר מחברה שעוסקת בבילינג (הרבה פרויקטים מול לקוחות ספציפיים, פחות hardcore technlogy). מצד שני יש גם עניין של ביקוש והיצע: היינו מעדיפים מנהלים הנדסיים "well rounded" לכל תפקיד – אך אין לנו. לפעמים אנחנו מעדיפים מנהלים טכנולוגים – אבל לא מוצאים אותם. פעמים אחרות אנחנו מעדיפים מנהלים פרויקטליים – אך מתקשים למצוא אותם (בארגון או בראיונות).

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

  • מהנדסים נוטים להעריך יותר, ולהיות מרוצים יותר תחת מנהלים שמבינים היטב, ומעורבים – בעבודה שלהם.
  • ניהול ישיר הוא עמדה עדיפה ל Mentoring / Coaching מאשר Tech Lead רוחבי. אולי זה עניין של מחויבות של המנהל לעובדים שלו, מול החלופה של Tech Lead שיותר חופשי עם מי נוח לו לעבוד?
  • "תרבות הנדסית" (Engineering Culture) הוא דבר חמקמק שקשה יותר לטפח מדרגים גבוהים. אם המנהלים הישירים של המהנדסים לא "חיים", משדרים, ומדגימים את תרבות הנדסית – הסיכוי של הארגון לטפח "תרבות הנדסית" ברמה-גבוהה – הרבה יותר נמוך.

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

ביקוש והיצע – וכיצד הארגון משפיע עליהם?

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

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

כלומר: גם אם א-פריורית ישנם 50% מהנדסים שיהפכו למנהלים טכנולוגים ו 50% מהנדסים שיהפכו למנהלים פרויקטליים – יש סיכוי טוב שכמות המהנדסים בעלי פוטנציאל בצד הפרויקטלי שיביעו עניין במשרת ראש צוות היא גדולה יותר (אנחש: 50-100% גבוהה יותר). אם בתרבות הארגונית ראשי צוותים נמדדים פחות על הובלה טכנולוגיות ו/או מנטורינג טכנולוגי משמעותי של עובדים – הנטייה יכולה לגדול אפילו יותר.

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

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

סיכום

בחלק השני, ניסיתי להתמודד עם הדילמות:

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

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