על 4 סגנונות ניהול

הפוסט נכתב בשיתוף עם יהודה גרנות – CTO & CO-Founder at Fincheck.

 

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

יש לו מספר וריאציות.

בווריאציה הפשוטה ביותר (מקור: Rensselaer Polytechnic Institute. Retrieved 24 May 2012) מגדירים שני סגנונות בלבד:

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

 

איננו מסכימים איתו! אולי לאחר קריאת הפוסט – גם אתם לא.

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

 

האם אתם יכולים לחשוב על מנהלים שאתם מכירים / עבדתם איתם – ולהבין לאיזו אסכולה הם שייכים?

מקור: Cinetropolis
 

להכיר את סגנונות הניהול

הוריאציה הקצת-יותר-מורכבת (מקור: Leadership & the One Minute Manager) מדברת על 4 סגנונות ניהול:

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

 

במידה ואתם בעצמכם מנהלים – איזה סגנון מאפיין אתכם?

 

 

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

 

אם תתקלו בהן, אז הנה שמות נרדפים לסגנונות: הגישה המעורבת נקראת גם Consultative, הגישה התומכת נקראת גם Democratic, והגישה הסומכת נקראת גם לסה-פר (Laissez-faire, שמשמעו "תנו לעשות, תנו לעבור").

מודל סגנונות הניהול, וריאציית חמשת הסגנונות.
 

בחן את עצמך (למנהלים): סגנונות הניהול השונים

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

מקרה #1 – אתה רוצה לבצע שינוי ארגוני משמעותי. ביצועי הארגון / צוות טובים – אך השינוי נחוץ. מה תעשה?

א. אתן לצוות להשתתף ולהשפיע על דרך הכנסת השינוי.

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

 

מקרה #2 – הצוות מפגין לאחרונה ירידה בביצועים: איחור ביום משימות, והאיכות ״לא משהו״. מה תעשה?

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

.
מקרה #3 – אתה מתוודע לשני חברי צוות שלא מסתדרים ביניהם במידה מזיקה. מה תעשה?

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

 

ובכן, הנה תוצאות ההדגמה:

  • הסגנון הסמכותי הוא ג, ד, א – בהתאמה.
  • הסגנון המעורב הוא בב, ד – בהתאמה.
  • הסגנון התומך הוא א, ג, ג – בהתאמה.
  • הסגנון הסומך הוא דא, ב – בהתאמה.
 
נד סטארק. מנהיג פנטסטי!

איזה סגנון ניהולי הוא המוצלח ביותר?

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

השאלה שעולה מיד לראש היא: "האם הסגנון שלי מוצלח, או לא?"
״האם סגנון הניהול הדומיננטי אצלי – הוא הסגנון הטוב ביותר?״

למנהלים – העניין הזה תופס מקום חשוב ורגיש במיוחד: "אולי אני צריך לשנות סגנון מ-A ל-B?"

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

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

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

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

ע"פ "מודל הצרכים" (לא לבלבל עם פרמידת הצרכים של מאסלו) על המנהל:

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

"Nothing is so unequal – as the equal treatment of unequals"

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

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

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

צרכי העובדים

את מודל הצרכים ניתן לתאר באופן הפשטני הבא:

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

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

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

ע"פ המודל, מחלקים את העובדים ל-4 רמות של התפתחות בסיטואציה הנתונה (פרויקט, צוות, משימה, וכו'):

 

 

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

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

בהינתן התאמה של עובד לקטגוריה D1 – D4, סגנון הניהול המומלץ הוא:

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

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

 

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

 

ההשפעות השונות של סגנונות הניהול השונים

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

  • סגנון הניהול הסמכותי, מתבטא לעתים בתקיפות, דרישה רבה, והחלטיות. הוא עוזר למקד את העובדים ולהשליט משמעת וסדר – אף הוא עלול לגרום למרמור של עובדים, איבוד האכפתיות (כי מישהו אחר "דואג" לדברים), ושחיקה.
    • מנהלים רבים נמנעים מהגישה הזו כליל – כי הם חוששים מעימותים, ומביקורת מצד הצוות.
  • סגנון הניהול המעורב, היא גישה משקיענית מצד המנהל: מעורבות גבוהה בפרטים, דוגמה אישית, דאגה ואכפתיות לעובדים ומה שהם עושים. החיסרון העיקרי בסגנון הזה עבור המנהל הוא יצירת תלות של העובדים במנהל, מה שיכביד בסופו של דבר על המנהל – ויצר את צעדיו. כמו כן, העצמאות והיוזמה של העובדים יכולים לפחות בעקבות שימוש לא מתאים בסגנון הזה. לא תמיד למנהל יש מספיק ידע מקצועי / בפרטים על מנת ליישם סגנון זה.
  • סגנון הניהול התומך עוזר לייצר יחסים מצוינים עם העובדים, אולם שימוש לא נכון או מוגזם בסגנון עלול לגרום לפתח אצל העובדים מחויבות הולכת ופחותת למשימה – ולגרום להם להתמקד בעצמם: "?What is it for me" – שאלה לגיטימית, אך לא תמיד הפעולות נעשות לטובת העובד. כלל-הארגון הוא חשוב יותר.
    • מנהלים לעתים נמנעים מגישה זו כי הם חוששים להחליש את הסמכותיות שלהם מול העובדים.
  • סגנון הניהול הסומך הוא לכאורה הקל ביותר למנהל: עליו להישאר בצד, להתעניין רק לפעמים, ולפרגן לעובדים. זה קל – אם כי לא לכל המנהלים. שימוש מוגזם / לא מתאים בגישה הזו יכול להיות הרסני – ולהביא למצב של חלקי צוות או אפילו צוות שלם שלא מתפקד. צוותים מפותחים ועצמאיים – יכולים לפרוח תחת הגישה הזו, ואז המנהל יכול להתפנות למשימות נוספות. בכל מקרה, על המנהל להישאר עם הבנה מספיקה על מה שקורה בצוות. גם להנהלת חברה, שאמורה להיות מוכשרת ועצמאית מאין כמוה – יש עדיין board מפקח.
    • מנהלים רבים מפרשים את הסגנון הסומך כ"שגר ושכח". חשוב למצוא את האיזון הבריא בין עצמאות הצוות, והיכולת של המנהל לספק פידבק וערך אמיתי נוסף לצוות (לעשות רק יחסי ציבור לצוות – לא נחשב).

סיכום

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

עוד שאלות שעולות בתמונת ה "מנהל סומך על 100% מהאנשים, 100% מהמשימות" הן: כמה זמן יחזיק ציון לשבח ממישהו שאינו בפרטים? (מנהל סומך)
האם כתיבת קוד יעיל ואלגנטי – הוא משהו שמנהל שלקח "צעד או שניים אחורה" יוכל לזהות בצורה נכונה?
מה עם דיון מעמיק ומאתגר על העבודה שביצע העובד?
אולי הפידבקים האלו מפסיקים להגיע מהמנהל – ומגיעים מה peers?!

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

מה שנדרש ממני הוא גישה מעורבת במשימות 2,1 ו 3, וגישה סומכת במשימות 5,4, ו 6.
לפעמים קל לשכוח את זה.

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

קוטלין (Kotlin) למפתחי ג'אווה ותיקים – חלק א': הבסיס

קוטלין?!

קוטלין (על שם האי קוטלין) היא שפה static-typed, עם תחביר מודרני, הרצה מעל ה JVM. היא פותחה ע"י JetBrains – חברת ה IDEs הנודעת מרוסיה.

החבר'ה של JetBrains כתבו הרבה קוד בג'אווה כחלק מפיתוח ה IDEs שלהם. התחושה – שהקוד verbose מדי. הם התלבטו בין Ceylon (של RedHat, המתקמפלת גם לג'אווהסקריפט) וסקאלה, אבל ממספר סיבות – החליטו שאף אחת מהשתיים אינה מתאימה להם.

הפתרון: לפתח שפה בעצמם.

שש שנים אחרי, חברות טכנולוגיות כמו Uber, Netflix, Pinterest ועוד – משתמשות בקוטלין: בצד השרת, ובאנדרואיד.
קוטלין היא דיי חדשה, ה GA שלה הוא החל מפברואר 2016.

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

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

בקצרה:

  • לקוטלין יש תחביר דומה מאוד לג'אווה – אבל מודרני ומינימליסטי. אלמנטים רבים בתחביר שלה מזכירים את השפה האחרונה שסקרתי בבלוג – Go.
  • פונקציות הן First Class Citizens. שמעתי טענה ש Kotlin היא "שפת Object-Oriented ו Functional" – טענה מוגזמת לטעמי: immutability ו pure functions הן לא משהו מפותח בשפה.
  • לקוטלין יש Interoperability טוב מאוד עם ג'אווה – הרבה יותר טוב מסקאלה.
  • לקוטלין יש coroutines (יכולת שהיא עדיין ניסיונית) – היכולת להריץ תהליכים רזים ברמת ה runtime של השפה, עם כלים פשוטים לטיפול במקביליות, כמו async, yield ו await.
  • לקוטלין יש IDE מצוין – עם תמיכה מתקדמת. זה חשוב.
  • קוטלין יכולה להתקמפל לג'אווהסקריפט. שימו לב שלא כל תוכן הספריות הסטנדרטיות תומכות גם ב JVM וגם ב JS – ויש סימון מתאים. ה Interoperability עם ג'אווהסקריפט הוא קצת יותר מורכב, בשל האופן הדינאמי של ג'אווהסקריפט.
  • בדומה ל Swift – הגבילו בשפה את השימוש ב Null.
  • אין Checked Exceptions (יששש!)
מצד שני:
  • קוטלין היא שפה עשירה ולא פשוטה. היא יותר מורכבת מג'אווה – אם כי יותר פשוטה מסקאלה.
  • קוטלין מתקמפלת מעט לאט יותר מג'אווה (היינו רוצים שהתהליך יהיה מהיר יותר).

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

שלום, קוטלין!

תודו שפאן (fun) נשמע הרבה יותר טוב מדף' (def – נשמע כמו מוות)

הנה ה Hello World של קוטלין.

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

הקוד בקוטלין מתקמפל ל bytecode של ה JVM (עם הסיומת kt לשם קובץ ה class.):

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

את ה class שנוצר בקומפליציה לא ניתן להריץ, ללא ה runtime של קוטלין: kotlin-runtime.jar.

אם עובדים עם command line הכי פשוט לארוז את הפרויקט ב jar עם הקומפיילר של קוטלין, לצרף את ה runtime – ואז להריץ:

$ kotlinc -include-runtime -d
$ java -jar
משתנים והשמות
  1. משתנה מגדירים בעזרת המילה השמורה var. קודם מופיע שם המשתנה – ורק אז הטיפוס (הפוך מג'אווה או C).
  2. ניתן באותה השורה גם לאתחל ערך.
  3. בעצם, ונראה את זה שוב ושוב: מה שהקומפיילר יכול להסיק לבד – לא צריך להגדיר לו. c יוכר כ Int כי זה הערך שהשמנו לו.
    var אינו "כלי קיבול גנרי". c מעתה והלאה – הוא static type מסוג Int.
  4. המילה השמורה val מגדירה ערכים שהם "immutable" (ליתר דיוק: פשוט לא ניתן לקבוע ערך אחר – בדומה ל final בג'אווה).
    בדומה לרובי, ניתן להשתמש במספר בקו תחתון, בכדי להקל על קריאת אלפים (או כל חלוקה אחרת שתרצו).
  5. בדומה לג'אווה, אני יכול להכריז שערך הוא מטיפוס Long ע"י הוספת האות "L" בסוף המספר.
  6. זו שגיאת קומפילציה. מדוע?
    כי המשתנה a לא אותחל, וקוטלין לא מקבלת השמה לערך שאינו מוגדר. אין אתחול באפס או null.
    בקוטלין כל המספרים הם אובייקטים. אין פרמיטיביים.
    אובייקטים לא יכולים לקבל ערך null, אלא אם הגדרתי אותם ככאלו (על כך בפוסט המשך).
  7. גם זו שגיאת קומפילציה! מדוע?
    אם אני מציב Long ב Integer (או להיפך) – עלי להצהיר על הטרנספורציה במפורש.
    אין casting, ואופן הצרנספורמציה הוא שימוש בפונקציה שהתנהגותה מוגדר היטב.
  8. כך צריך לבצע את ההמרה. להזכיר: b הוא אובייקט לכל דבר – אין פה autoboxing.

מחרוזות

  1. מחרוזת היא עוד אובייקט בקוטלין, כאשר יש ערך – לא צריך להכריז על טיפוס.
  2. כמו בפייטון (או עוד שפות) ניתן להגדיר Raw String בעזרת מרכאות משולשות.
    1. Raw Strings לא מקבלות escaping: הביטוי n\\ הוא מחרוזת, ולא שורה חדשה.
    2. כמו בשפות אחרות, ה margin הוא חלק מהמחרוזת.
    3. בכדי לצמצם margin ניתן לסמן את ה margin הרצוי בעזרת סימן "|" בתחילת כל שורה, ולקרוא ל ()trimMargin.
  3. בקוטלין יש interpolation למחרוזות בעזרת סימן ה $. כאשר הביטוי שם אטומי (יחיד) של משתנה – מספיק רק סימן הדולר.
  4. כאשר הביטוי הוא יותר מאטום אחד – יש לעטוף אותו בסוגריים מסולסלים.
  5. אם רוצים פשוט להקליד $ – יש לעשות לו escaping.
  6. בקוטלין יש custom operators, והשוואה בין מחרוזות מתרחש באמצעות האופרטור == (המקביל ל ()equals)

למען הסר ספק, הנה הפלט של הקוד לעיל:

לולאות

  1. כמו בפייטון, ניתן להשתמש ב range.
    rangeTo (כלומר: ..) הוא בעצם אופרטור של אובייקט ה Int, המחזיר אובייקט מסוג IntRange שהוא <Iterable<Int.
  2. ניתן, כמובן, לעשות איטרציה גם על <Iterable<T. דאא.
    מעניין לציין ש Iterable הוא לא Lazy, והופך לרשימה מלאה בעת ה evaluation שלו. השיקול: ביצועים. זיכרון רציף יעיל יותר לגישה ע"י המעבד.
  3. אפשר גם לספור לאחור, בעזרת downTo ויש גם step.
    downTo ו step הן לא מלים שמורות בשפה, אלא infix functions – כלי דומה לאופרטור, ששווה להסביר עליו בפוסט המשך.
  4. ()listOf היא פונקציה גנרית שמקבל רשימה (varargs) של ארגומנטים – ומחזיר אותם כרשימה <List<T. כמובן ש List, הוא גם Iterable.
  5. אם אני רוצה לבצע איטרציה ולעבוד עם אינדקס – זה התחביר.
  6. אם אני רוצה להתעלם ממשתנה (להימנע ב wanrnings / קוד קריא יותר), כמו בשפת Go – אני מחליף את המשתנה שלא אשתמש בו ב _ .
    (כמובן שבמקרה הזה שלב 4 הוא הדרך הפשוטה לכתוב את הקוד).

הנה הפלט:

נמשיך עוד קצת:

בזריזות:

  1. יש while.
  2. יש do {} while.
  3. בקוטלין אפשר להגדיר Label (מסתיים ב @) אליו אפשר להתייחס בלולאות מקוננות.
    כמה פשוט ונוח לומר: "אני רוצה להפעיל continue, אבל לא ללולאה הפנימית – אלא ללולאה החיצונית".
    הפקודה הן <break@<Label או <continue@<Label.
  4. יש גם repeat. האנוטציה ":times" היא של ה IDE – ואינה חלק מהקוד.
    זה מה שנקרא: "Five Whys".
הנה הפלט:
קצת על Control Flow
 
  1. בקוטלין אין ternary operator, קרי: v = cond ? a: b.
    הדרך המקבילה הכי פשוטה היא one liner if..else.
  2. משהו נחמד הוא ש if..else נחשב כ expression.
    1. אם, ורק אם יש לנו גם if וגם else (הרי אנחנו רוצים להימנע מ null / ערך לא מוגדר) – ניתן "לאסוף" את הערך מתוך ה expression.
    2. הערך הוא תוצאת ה evaluation של השורה האחרונה בכל בלוק – ממש כמו בשפת רובי.
    3. זה בעצם מה שמתרחש בסעיף #1 – רק שסעיף #1 הוא הצורה הפשוטה יותר לתבנית הזו.
  3. במקום switch, יש בקטולין את when.
    1. כפי שאתם רואים אפשר להשתמש במגוון ביטויים.
    2. בניגוד ל switch, ה evaluation של התנאים יפסיקו ברגע שימצא התנאי הראשון שהוא אמת. לכן הפלט יהיה ש "5 הוא ספרה בודדת", אף על פי ש 5 הוא גם מספר ראשוני, ואינו בסדרת ה 20.
הנה הפלט:

סיכום

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

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

—-

לינקים רלוונטיים

Cheat Sheet למעבר בין ג'אווה לקוטלין. https://github.com/MindorksOpenSource/from-java-to-kotlin

Infrastructure as a Service: Terraform

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

Terraform הוא כלי שמנסה לספק כמה מטרות:

  • לספק תמונה אחת לכל תשתית המערכת שלנו.
  • לתמוך בתצורות production מודרניות (ענן, וכו\')
  • לספק אופן צפוי ובטוח לעדכן את תצורת התשתית שלנו.
  • לספק Workflow אחיד לעבודה מול ספקי-תשתיות שונים.
    • משום מה, אנשים נוטים להניח ש Terraform מאפשר להגדיר תצורה לספק ענן אחד (נניח גוגל) ואז להפעיל אותה על ענן אחר (נניח Azure). זה בהחלט לא המצב! זה לכל היותר מיתוס!

נפתח בדוגמה

מה ש Terraform (מעתה אשתמש בקיצור: טרה) מאפשר – הוא להגדיר תצורה רצויה בצורה פשוטה – ו\"לגרום לה לקרות\".

את הגדרת התצורה עושים בקבצים עם סיומת  tf. כמו זה:

\"היי!\" – אתם עשויים לומר, גם בעזרת  aws-cli , או סתם סקריפט פייטון שמשתמש ב AWS SDK – אני יכול להרים instance בצורה פשוטה למדי! אז מה ההבדל?

יש כמה הבדלים:

  • בעזרת טרה, אני משתמש באותה שפה ואותו תהליך אני יכול להגדיר תצורה על תשתיות שונות: AWS, גוגל, Dyn, Cloudflare – ועוד. זה קצת יותר פשוט מלהתחיל לעבוד עם כלים שונים ו SDKs שונים.
  • טרה מוסיף \"חוכמה\" של חישוב המסלול הנכון להגיע למצב הרצוי: טרה בודק מה המצב הקיים, ומחשב אלו שינויים יש לבצע בכדי להגיע לתצורה הרצויה. לעשות את זה לבד – זו הרבה מאוד עבודה!

נמשיך:
לאחר שיצרתי את קובץ הגדרת התצורה שלי, אני מקליד את הפקודה

$ terraform plan
ומקבל את הפלט הבא:

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

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

הפלט מופיע בתצורה של diff:

  • + – על משאב חדש שנוצר.
  • – על משאב שמבוטל.
  • ~ – על משאב שעובר שינויי תצורה.
  • -/+ – על משאב שמבוטל, ומוחלף במשאב אחר.

ניתן גם:

  • להעשיר את הפלט בצורה מותאמת אישית, בעזרת פקודות output (או פונקציות כמו count) בהגדרת התצורה. למשל: אני רוצה לדעת איזה IP ה ELB שלי הולך לקבל, או כמה instances מסוג מסוים יהיו על מכונות spot.
  • להשתמש בפקודה terraform graph על מנת לקבל גרף המתאר את סדר הפעולות המתוכנן. טרה עובד עם פורמט גרפים סטנדרטי, ואת הפלט של הפקודה ניתן לטעון ל webgraphviz.com – על מנת לצפות בגרף בצורה ויזואלית.
    • הפלט של פקודת plan מסודר ע\"פ סדר הא\"ב על מנת לספק יכולת סריקה מהירה של התוכן.
  • לשמור את תוצאת התכנון, בעזרת הפרמטר out=path-, כך שיובטח שבעת הפעולה תרוץ התוכנית שבחנתי.

כאשר אני מקליד:

$ terraform apply

עברה כחצי דקה ואני מקבל את ההודעה הבאה:

אני יכול גם להסתכל ולראות את ה instance שנוצר ב console

או פשוט לקרוא ל \"aws ec2 describe-instances\" ולראות אותו ב console.

לאחר ביצוע קבוצת ה apply, טרה יצר לנו שני קבצים: קובץ tfstate. וקובץ tfstate.backup.

הקבצים הללו (יש להם תוכן שונה זה מזה) מתארים את ה last-known-state של התצורה המרוחקת (כלומר: מה שקורה בפועל), והם ישמשו אותנו לפעולות הבאות.

במקרה שלנו הקבצים נוצרו רק לאחר פעולת ה apply (כי נוצר מצב שלא ניתן לשחזר בעזרת ה API של AWS בלבד), אבל גם בהרצת פקודת plan ייתכן והקבצים הללו ייווצרו / יתעדכנו.

את הקבצים הללו אני אוסיף ל gitignore. כך שלא יגיעו ל source control. מדוע – אסביר בהמשך.

נמשיך:

נעשה שינוי קטן בכדי לראות את ניהול הדלתאות של טרה:

ביצעתי שני שינויים. קראתי ל terraform plan וקיבלתי:

האמת שהייתי מצפה בשינוי instance_type שזו תהיה פעולת +/- – אבל כנראה בגלל שספציפית באמזון השוני בין t2.micro  ל t2.nano הוא רק ב CPU capping – אני מניח שה instance לא מוחלף פיסית. אם הייתי משנה AMI, למשל – זו הייתה פעולת +/-.

לאחר terraform apply אקבל:

הפעולה לקחה קצת יותר זמן ממה שציפיתי – אבל הזמן הזה קשור לאמזון ולא לטרה.

כמובן שלאחר ה apply אני מעדכן את הקוד בגיט: אני מאוד רוצה snapshot נכון של התצורה שהפעלתי בכל רגע: אנחנו מדברים הרי על infrastructure as code. אולי שווה אפילו לעשות מקרו שלאחר apply מוצלח דואג להכניס לעדכן commit – שלא אשכח…

והנה המצב ב Aws Console:

ניסוי אחרון, נעשה שינוי אפילו פחות מהותי ב instance:

נריץ plan:

נריץ apply:

הפעם השינוי היה מהיר מאוד. זה רק שינוי של metadata ופה בכל מקרה לא ישתנה לי ה instance ID.

נכניס את הקוד לגיט. נבדוק את ה console עכשיו:

כדי שלא נשלם הרבה $$, בואו נסגור את ה landscape שיצרנו:

פקדנו terraform destroy, אימתנו שזה לא בטעות – yes, וזהו. תוך כמה שניות כל המכונות (כלומר: instance אחד בגודל nano) – למטה.

אם אני מעוניין בניתוח של מה המשמעות של destroy אני יכול לפקוד: terraform plan -destroy – ולקבל הדמייה / הערכה.
destroy כמובן לא ייגע במשאבים שלא הוגדרו ע\"י טרה.

Great Success!

מה קרה כאן, בעצם?

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

הקובץ הוא בפורמט HCL (קיצור של HashiCorp Configuration Language) ומתאר בצורה דקלרטיבית קונפיגורציה של Infrastructure. הוא מבוסס על פורמט \"רזה\" של JSON בשם UCL בה משתמשים בקונפיגורציה של nginx.
אפשר לכתוב את הקבצים בצורה ה JSON-ית ה\"כבדה\" (מרכאות מסביב לכל אלמנט, וסוגריים מסולסלים מסביב לכל Key-Value pair) – או בצורה ה\"רזה\". אנחנו, כמובן, ניצמד לצורה ה\"הרזה\".

1. בתור התחלה אנחנו מגדירים עם איזה (provider(s. קובץ טרה יכול לעבוד עם כמה ספקי-תשתיות שונים במקביל.

  • טרה תומך בעשרות \"ספקי תשתיות\", כולל Cloudflare, New Relic, MailGun, ועוד. 
  • בתוך provider מסוג aws\' עלי לספק את ה region. בחרתי region זול (בכל זאת, לבלוג אין הרבה תקציבים…)
  • צורת העבודה, והשפה (HCL) הם אחידים עבור כל ספק תשתיות – אבל הערכים שזמינים לכל ספק הם שונים לחלוטין. ל Dyn אין בכלל regions, אבל נדרשים לתאר את שם הלקוח (שלכם). בענן של גוגל יש לתאר region אבל גם project.

    2. בכל ספק תשתיות, ניתן להגדיר כמות וסוגים שונים של resources. לכל סוג resource – הגדרות משלו.
    הפורמט הוא:

    resource  \"_\" \"\" {
     
    }
    כאשר: 
    • provider צריך לתאום ל provider שהגדרנו בתחילת הקובץ
    • ה type הוא ערך מתוך מרחב ערכים שמוגדל לכל provider. למשל ל dyn יש resource בשם \"dyn_record\"
    • ה resource_name הוא שם שיזהה בצורה ייחודית את המשאב הזה בתוך ההגדרות של טרה.
    • ה config הוא רשימה של שדות, שמרחב הערכים מוגדר ע\"פ הצמד provider ו type.

    3. AMI, כפי שאתם בוודאי מכירים הוא Amazon Machine Image. מאיפה בוחרים AMI, אם לא שלכם? אני בוחר בעזרת ה AMI Locator של אובונטו (רק AMIs של אובונטו). שווה להכיר ש:

    • ל regions שונים יש AMI ID שונים: ה AMI של אובונטו בצפון וריגיניה וזה של אורגון אולי יהיה זהים ברמת הביטים – אבל יהיה להם ID אחר.
    • במכונה מסוג t2.micro או t2.nano אני יכול להשתמש רק ב AMI שעובד עם hvm (וירטואליזציה) ו ebs (אחסון). סתם שווה להכיר.
    • אפשר לקבל במהירות עוד מידע על AMI בעזרת הפקודה הבאה:
      aws ec2 describe-images –image-ids ami-a60c23b0

    בגלל שה id של ה image לא אומר לי כלום – אני מוסיף הערה. Infra as Code משמעו גם להתייחס לקונפיגורציה שלכם ברצינות שמתייחסים לקוד Production שהולך ומזדקן עם הזמן.

    4. בתוך ה config של resource type מסוים יכולים להיות אובייקטים מקוננים, כמו אובייקט ה tags.
    tags מסוימים, כמו Name – הם משמעותיים מאוד ב AWS.

    ב HCL מגדירים:

    • ארגומנט (כמו אלו של ה resource) כקלט לקונפיגורציה. משהו שאנחנו יודעים ומציבים בקונפיגורציה.
    • Attribute (\"תכונה\") כפלט של הקונפיגורציה בעת ההרצה – פקודת apply. משהו שלא ידענו לספק בעצמנו אבל מתאר את התצורה. למשל: כאשר אני יוצר instance ב AWS אני לא יודע איזה כתובת IP הוא יקבל – אבל ייתכן והכתובת הזו צריכה לשמש אותי לקונפיגורציה בהמשך, למשל: בכדי ליצור רשומת DNS.
      • ה attributes הם חלק חשוב מה state – שנגדיר אותו מייד.
    כאשר אנו מתכננים plan, טרה מאחורי הקלעים יוצר גרף (מסוג DAG) של תוכנית הפעולה להגעה למצב הרצוי. הקונפיגורציה עצמה לא מתארת את סדר הפעולות (אלא אם נוסיף אילוץ – depends_on) – טרה מחשב אותו בעצמו.
    טרה ידע מתי הוא יכול למקבל פעולות – והוא ינסה לעשות זאת ככל האפשר, אבל יימנע ממקבול מתי שהוא מסוכן. למשל: כאשר אני מחליף instance ממכונה קטנה לגדולה – טרה לא יודע מה המשמעות של כמה השניות שהמכונות הללו יחיו במקביל. בגלל שזה עלול להיות מזיק – הוא יימנע מכך ויעשה את סדר הפעולות סדרתי.
    קונספט חשוב נוסף הוא ה State
    בטרה מדברים על:
    • Last known state – המורכב מהארגומנטים השונים, משתני הסביבה בעת ההרצה, וכו\' – כל מה שטרה עשוי להשתמש בו בעתיד. הוא נשמר בקבצי terraform.tfstate ו terraform.tfstate.backup.
    • Actual state – המצב בפועל של התשתית שלנו. זהו מצב לא ידוע כי ייתכן ויש שינויים שלא נעשו ע\"י טרה, או אפילו לא ע\"י העותק הנוכחי של טרה.
    לפני שטרה מבצע תוכנית או apply הוא פונה ל APIs ולומד מה שהוא יכול על ה actual state. אנחנו בהחלט רוצים להימנע מטעויות.

    הוא גם ייעזר ב local state על מנת לבצע:

    • מיפוי נכון, למשל ה resource x הוא בעצם instance עם id כזה וכזה ב EC2
    • לשפר את מהירות הפעולה: אם instance id קיים – אני יכול להניח שכמה attributes שלו לא השתנו.

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

    • מישהו, מתישהו, הולך להפעיל את טרה עם קבצי state שאינם up-to-date (למשל: שכח לעשות git pull לפני). אתם יודעים, כל טעות בפרודקשיין עשויה להיות אסון. לא טוב!
    • כל קבצי ה state נשמרים כ plain text וכוללים את כל משתני הסביבה. יש סיכוי טוב שסודות (ססמאות, keys, וכו\') יכנסו לתוכן הקבצים. אתם לא מכניסים ססמאות לתוך ה source control שלכם – אני מקווה!
    בקיצור: ההמלצה הגורפת היא להכניס את הקבצים הללו ל gitignore. ולא לעדכן אותם לתוך ה source control.
    אז מה עושים בקבוצה?

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

    Remote State דורש קצת עבודת הגדרות – אבל הוא בהחלט הדרך הנכונה לעבוד!

    דוגמה ל folder structure של פרויקט טרה. מקור

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

    למשל: קבצים גדולים? חס וחלילה – קשה להתמצא ולקרוא את הקוד.
    טרה מעודדת לפרק את הקוד לקבצים קטנים יותר: כל הקבצים בסיומת tf. ו/או tf.json. בתוך אותה התיקיה – יעברו merge לפני שיורצו.

    יש כאלו שמפרקים את הפרויקט לקבצים כמו: variables, output ו main – חלוקה בהחלט לא scalable מבחינת ניהול קוד.
    תצורה עדיפה היא חלוקה ע\"פ תוכן: dns, instances, launch_configurations, security_groups, וכו\'.

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

    כלים נוספים בשפת ה HCL הם:

    מודולים

    אם יש לכם 100 שירותים בפרודקשיין, אני מקווה בשבילכם שאתם לא מנהלים 100 עותקים מאוד דומים של קוד!
    אתם רוצים להגדיר מודול של service_instance, של service_elb, של service_db וכו\' – ולשכפל מעט עד כמה שאפשר קוד.

    Interpolation (התייחסות למשאבים אחרים)

    בעזרת תחביר ה interpolation אנחנו יכולים לקצר ולייעל את הקוד שלנו (וגם להשיג דברים – שאחרת פשוט לא יכולנו). התחביר נקרא לעתים גם \"dirty money\" והוא נראה כך:

    אני מגדיר בתוך רשומת ה DNS את כתובת ה IP של ה ec2 instance בשם example. ערך שאי אפשר לדעת לפני הריצה.
    ה interpolation הוא, כמובן, כלי עיקרי לטרה לקבוע את סדר הפעולות ההרצה.

    משתנים

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

    סיכום

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

    לאורך הפוסט ניסיתי להדגיש גם את האלמנטים של Infrastructure as Code.

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

    —-

    לינקים רלוונטיים

    מדריך לכתיבת מודולים בטרה: https://linuxacademy.com/howtoguides/posts/show/topic/12369-how-to-introduction-to-terraform-modules

    Terraform Comprehensive Training – מצגת שנראה שמקיפה הרבה נקודות:
    https://www.slideshare.net/brikis98/comprehensive-terraform-training

    על סביבת הריצה החדשה: ה Docker Orchestration

    מהפכה מתרחשת מסביבנו: מהפכת הקונטיינרים.

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

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

    משם המשכנו לענן – ופתאום סביבת הריצה המשמעותית השתנתה פעם נוספת:
    Autoscaling, התנהגות בוירטואליזציה, תקשורת בין Availability Zones או בתוכם? רשת משותפת? VPC? Spot instances? – כל השיקולים הללו התווספו לסביבת הריצה של האפליקציה שלנו.

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

    סביבת הריצה העכשווית של מערכות צד-שרת

    —-

    תזכורת קצרה על Docker

    מי שמכיר – שידלג.

    להלן 2 דרכים מקובלות להעביר קוד ממכונת הפיתוח לפרודקשיין:

    דרך #1 (המקובלת יותר): להעביר את קוד המקור (או ה binary המקומפל) למכונה.

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

    דרך #2: ליצור Virtual Machine ולהריץ אותו על Hypervisor / ספק ענן

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

    הקשיים: ה image הוא לרוב גדול (כמה GB) ולוקח זמן להוריד ולאתחל אותו.
    לבדוק את ה image על מכונת פיתוח – לא כ\"כ נוח: צריך הרבה זיכרון וזו מערכת הפעלה נפרדת לחלוטין, מה שמקשה מעט על תהליך debugging / בדיקת לוגים וכו׳.

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

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

    מקור

    גישת ה Containerization (להלן Docker) היא גישת אמצע:

    • נארוז את כל ה user space של המכונה: ה distro של מערכת ההפעלה + ספריות שהותקנו + קוד האפליקציה ל docker image.
    • את ה docker image נעביר למערכת המארחת בה יש hypervisor וגם Linux Kernel.
      • שימו לב ש docker image שנבנה היום עלול לא לרוץ כשורה עוד כ 5 שנים: ה Kernel (של המערכת המארחת) מתעדכן עם הזמן, ואז קריאות מערכת (system calls) – עלולות להפסיק ולהיתמך. הנה דוגמה להמחשה.
      • מכיוון שכל ה user space ארוז ב docker image – אין בעיה להריץ הפצות שונות זו לצד זו: Debian לצד OpenSUSE, לצד CentOS.
    • ה docker image ירוץ כ container על המכונה המארחת:
      • יכולת ה Linux Containers (בקיצור LXC – זו שהחלה את המפכה) מאפשרת להריץ תהליך נפרד עם isolation מסוים ברמת מערכת ההפעלה: 
        • namespaces – הפרדה ברמת המודעות לתהליכים אחרים, תקשורת, ומערכת קבצים. pid, hostname, וה ip שהתהליך ייחשף אליהם הם וירטואליים – ומבודדים משאר העולם.
        • cgroups – הגבלה ברמת צריכת המשאבים. לא ייתכן שתהליך שנמצא ב cgroup אחר ישמש ביותר מ %x של CPU.
      • Docker הוסיפה אבסטרקציה נוספת למערכת הקבצים ול Network stack.
    • ה overhead של כל container שרץ הוא זניח: כמעט ורק זיכרון (בניגוד ל VM). אין בעיה להריץ 15 וגם 50 containers על אותה המכונה ביעילות – ממש כפי שניתן להריץ 15 או 50 תהליכים על אותה המכונה ביעילות.

    ה tradeoff של פחות isolation (יחסית ל VM) – אבל ניצולת גבוהה של משאבים קוסמת מאוד לחברות השונות: \"על ה images שלנו אנחנו סומכים!\". כל עוד המערכת המארחת מריצה רק containers שלי – הדאגה מבחינת אבטחה ו/או \"חטיפת משאבים\" היא נסבלת לחלוטין.

    עוד דבר נחמד ש Docker עושה הוא בנייה של ה docker image בשכבות.

    כאשר דוקר הוריד למכונה את ה docker image של שירות #1, הוא הוריד כל שכבה בנפרד. כעת, את שירות #2 הוא יכול להוריד במהירות, ממש כמו התקנה של source code / binary – כי רק השכבה של MyService 2 השתנתה.

    כנ\"ל לגבי שירות #3 – שעושה שימוש חוזר ב layer הגדול של אובונטו.

    גישה זו היא יפה, אבל צריך גם לדעת איך לעבוד איתה. למשל:

    • שכבה שדורשת עדכון – תגרור הבאה מחדש של כל השכבות מעליה (כי מדובר בדלתאות), ולכן יעיל יותר להגדיר את השכבות באופן שמירב העדכונים יהיו בשכבות העליונות.
    • שכבה שמסירה קבצים, גדולים ומיותרים ככל שיהיו, לא תחסוך את הורדת הקבצים הללו – שוב, כי מדובר בדלתא. אם הקובץ גדול כדאי לבנות image ייעודי ורזה יותר של מערכת ההפעלה / אותה שכבה עם קבצים מיותרים.
    • ה docker images של מערכות ההפעלה השונות הם מינימליים ולרוב כוללים סט כלים מצומצם ביותר (bash, grep, package manager, ורק מעט מעבר) ולכן יהיה עליכם להוסיף שכבות משלכם.

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

    • ניצול טוב יותר של משאבים – ובמיוחד בסביבה של מיקרו-שירותים. 
      • חשבו על שירות הגיוני ונחוץ, אך שצורך לא יותר מ 1% CPU ממכונה קטנה של ספק הענן שלכם.
    • שיפור תהליך ה Continuous Deployment – כאשר יש פחות סבירות לתקלות שנובעות מחוסר התאמה בין סביבות הפיתוח, הבדיקות, והפרודקשיין. למשל: \"אופס! שכחנו לעדכן ב deployment script עדכון של libssl שאיזו ספרייה שלנו משתמשת בה\"
      • עקרון חשוב כאן הוא immutable infrastructure (או servers) – אותה הסברתי בפוסט נפרד.
    • Easier) Multi-Cloud deployment) – אם לצורך גיבוי, פריסה גאוגרפית טובה יותר, זמינות שאינה תלויה בספק ענן יחיד, גישה לשירותים של ספקי ענן שונים (למשל: BigQuery) או לצורך צמצום ה Lock-in.
    הסיכונים, גם הם קיימים:
    • קונספט חדש, שעדיין לא הבשיל לרמה של הקונספטים הקיימים.
    • שיתוף משאבים הוא נהדר, אבל לא לכל טכנולוגיה. למשל: 
      • ברובי on ריילס צריכת הזיכרון היא גבוהה למדי – מה שמגביל על הרצה של הרבה containers על אותה המכונה. 
      • ג\'אווה אגב, גם לא טמנה את ידה בצלחת: ובשל שיקול תכנוני שנראה נכון בזמנו – גם תהליך פשוט של ג\'אווה יכול לצרוך מאות MB של זיכרון.
      • מערכות שעושות שימוש אינטנסיבי בזיכרון (Redis, בסיסי נתונים in-memory)
      • מערכות שעושות שימוש אינטנסיבי ב I/O (למשל: בסיסי נתונים. אפרט עוד בהמשך).
    • עלויות מעבר והתאמות הנדרשות לסביבה החדשה: התאמה של תהליכי deploy, תהליכי CI/CD וה debugging. עד שלא תעבדו חודשיים-שלושה עם Docker בפרודקשיין – לא תגלו הכל.
    סיימנו עם דוקר, ובחזרה לפוסט…

    —-

    הכירו את ה Container Orchestration Frameworks

    Docker עצמו אינו מספיק, במיוחד לא לסביבת production מורכבת.

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

    ה\"מישהו\" הזה – נקרא בימנו Container Orchestration Framework.

    נכון, Docker הוא כ\"כ דומיננטי כיום, שאני בכלל לא מתייחס לאלטרנטיבות, ובראשן rkt (נקרא כמו: \"rock-it\") של coreOS. בהמשך ארחיב על קוברנטיס – Framework שמספק גם תמיכה ניסיונית ב rkt. גם Lock-In לדוקר הוא משהו שיש ומנסים להימנע ממנו.

    Container Orchestration Frameworks (בקיצור: COF) יש כבר לא מעט – והן מתפתחות במהירות:

    • הכל התחיל ב Kubernetes ו Mesos, כך נדמה לי.
    • אמזון ומייקרוסופט נבהלו שהנה \"אובד\" ה Lock-in לעננים שלהן, ומיהרו לפתח את ECS ו ACS – בהתאמה.
    • HashiCorp, בעלי המוניטין המרשים בעולם ה DevOps הציגו את Nomad – החזון שלהם לעולם ה COF.
    • Docker, שמאחוריה חברה מסחרית הבינה שהפוטנציאל המסחרי נמצא ב COF הרבה יותר מאשר הוא נמצא ב Docker – והצטרפה לחגיגה בעזרת Swarm, הממותג כ ״COF הרשמי\".

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

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

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

    קדימה לדרך, קוברנטיס!

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

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

    Pod – היא יחידת ה deploy הקטנה ביותר. בד\"כ זה יהיה קונטיינר יחיד, אבל יכולים גם להיות 2 או יותר קונטיינרים בפוד – שרוצים להריץ אותם ביחד.

    Service – הוא הפשטה לקבוצה לוגית של Pods (מסוג זהה) והמדיניות המתירה גישה אליהם. לקוח של המערכת ניגש ל virtual IP של ה service ומשם המערכת מבצעת routing + load balancing ל pod מתאים כלשהו.

    Volume – הוא בעצם Mount של Storage ל Pod. ב Docker יש קונספט של Volume, אבל הוא פחות או יותר mount של folder מה host – ואינו כולל lifecycle מנוהל (למשל: ניקוי הנתונים לאחר שה Container ירד). קוברנטיס מציעה Persistent Volume שיחייה גם לאחר שה Pod ירד.

    Namespace – יחידה לוגית שמרכזת משאבים כמו הנ\"ל (Pods, שירות, ו Replica Set), ומבודדת אשכולים שונים שלהם זה מזה. למשל: production ו staging.

    הנה תרשים ויזואלי של האלמנטים הללו:

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

    חשוב להדגיש שזהו תרשים גנרי:

    • לקוברנטיס יש תצורות מעט שונות בעננים השונים: Azure, AWS EC2, IBM Blumix, GCE, Open Stack  ועוד.
    • יש לא מעט מקום לגמישות ו customization, אני אנסה לתאר תצורה פשוטה וסטנדרטית ככל האפשר.

    הרכיבים הכחולים הם רכיבי Runtime, בעוד הרכיבים האדומים הם רכיבי Management

    ה Kubernetes Cluster מורכב מ Nodes ו Master. המכונות עצמן מנוהלות ו provisioned ע\"י פתרון הענן / פתרון שאינו קוברנטיס. ברגע שה Master עולה ומזהה ברשת את ה kubelets המותקנים על ה nodes – הוא מתחיל לפעול.
    ה Master עושה scheduling של ה pods שנדרשים ממנו ל nodes השונים, ע\"פ כללים שונים. הוא מעביר לכל kubelet את ה podspecs הרלוונטיים (בד\"כ: קבצי xxx_pod.yaml) וה kubelet פועל מול ה container engine (בד\"כ: Docker) על מנת להוריד את ה docker images המתאימים, לקנפג אותם, לחבר להם volumes – אם קיימים, ולהריץ אותם.
    ל Kubelet יש עצמאות לעשות restart ל containers שאינם מגיבים.
    כל ה Pods על אותו node יכולים לתקשר זה עם זה בעזרת localhost או IPC. קונטיינרים באותו ה pod משתפים ביניהם גם storage.
    ה Pods השונים מזוהים ע\"י Labels (צמד key/value – לצורך זיהוי) ו Annotations (מחרוזות המשמשות כ metadata לצורך קלות הניהול).
    Replica-Set מוגדרת כקבוצה של Pods התואמים ל Label Selector, או פרדיקט, בנוסח:
    role = webserver, application != honeypot.
    כאשר role ו application הם ה keys של ה Labels, ו webserver ו honeypot – הם ערכים אפשריים.
    המערכת תדאג שה Replica-Set תשאר בגודל הרצוי – ואם למשל נפל node וחסרים Pods ב replica-set – המערכת תשלים אותם אוטומטית.

    מי שמנהל מרכזית את ה Replica-Set הוא רכיב בשם Controller Manager – הרץ כחלק מה Master. ה Master נדרש בעיקר לשינויים ולא לריצה שוטפת. אם הוא נופל, אי אפשר יהיה לבצע שינויי קונפיגורציה – אבל ההתנהלות בתוך ה nodes תמשיך לפעול כרגיל. עבור צרכים של Higher Availability, ניתן להפעיל יותר מ Master אחד.

    הרכיבים המרכזיים ב Master הם:

    • API Service, החושף את ה REST API בו משתמשים ה kubectl ו/או ה Management UI של קוברנטיס. הוא אחראי ל input validation ובדיקה שהתצורה המבוקשת תמיד תקינה.
    • ה Controller Manager הוא רכיב הניהול המרכזי. הוא רץ בלופ תמידי שבודק את מצב המערכת (נתונים מגיעים מה cAdvisors דרך ה Kubelet וה API Service) מול התצורה הרצויה וכל הזמן מנסה להביא את המצב הקיים למצב הרצוי.
      • Replication Controller, Endpoints Controller, Namespace Controller, וכו\' – הם תתי הרכיבים של ה Controller Manager.
    • ה Scheduler שהוא רכיב המנהל שורה של כללים עסקיים (\"Policies\") ומבצע שינויי תצורה ב Cluster בכדי לספק High Availability, ביצועים מספיק טובים, ו Quality of Service. כאן בעצם מגיבים למצב המערכת (high / low load, ביצועים לא מספיקים, מחסור במשאבים וכו\') – ומשנים את התצורה הרצויה בכדי לשפר את תגובת המערכת.
    • etcd – פרויקט אחר של גוגל לניהול key/value בצורה מבוזרת המשמש לאחסון כל ה state של ה cluster.
      • ניתן להריץ את ה etcd או על המאסטר או כ cluster נפרד (עבור higher availability). אני בחרתי לצייר אותו בתרשים מחוץ ל Master.
    עבור צרכני המערכת, מה שנגיש הוא ה Services. הם אלו שדרכם ניגשים ל APIs / Endpoints של המערכת.
    את ה load balancing / service discovery הראשוני של ה services נעשה בעזרת DNS. קוברנטיס מספקת DNS משלה שהוא bulit-in בשם Kube-DNS. ניתן להשתמש בחלופות אחרות ל service discovery ו load balancing – אבל Kube-DNS היא הדרך הפשוטה.

    בתוך ה Node, יהיו פעמים רבות מספר Pods מאותו הסוג (המזוהים ע\"י אותם ה Labels). את ה load balancing והחיווט הפנימי בתוך ה Node – עושה רכיב בשם ה kube-proxy.

    אם יש פתרון multi-cloud (ולכן multi-kubernetes-cluster) – אזי load balancing מוקדם יותר יעשה ע״י DNS חיצוני, למשל כמו זה של Dyn או Akamai.

    Kubernetes Management Dashboard. מקור: Kubernetes

    מדוע Stateful Pods הם בעייתים בקוברנטיס?

    אחד הרעיונות הדומינטטים בקוברנטיס ו Docker בכלל הם Stateless Services: שירותים שיכולים ליפול ולעלות בכל רגע, בלי לפגוע בשירות.
    מה קורה כאשר אנחנו רוצים שירות שהוא לא כזה? למשל: Database?

    ל Database בקוברנטיס (וב Docker בכלל) יש כמה בעיות. קוברנטיס פותרת כמה בעיות, כמו היכולת לנהל lifecycle מורכב יותר ל Pod – אבל זה רחוק מלהספיק:

    • שיתוף של דיסק בין כמה Pods הוא בעייתי. ה Database זקוק למקסימום I/O בכדי לפעול. אפשר לחשוב על דיסק משותף כ Bandwith משותף שמתחלק – אבל זה יהיה לא מדויק בכלל. הבעיה היא ב latency. אם מדובר בדיסק מכאני, שבו ה Database צריך להתחרות על התור בהזזת הראש המגנטי – מצב ה latency יהיה חמור, אבל גם ב SDD – יש עניין של latency כאשר יש ריבוי קריאות. רבות מהאופטימיזציות של ה Databases היום – לא יעבדו בצורה טובה בכלל, כאשר הדיסק משותף עם עוד Pods.
    • אפשר להגדיר Pods \"ענק\" שרץ לבד על המכונה – וכך פותרים את בעיית שיתוף הדיסק. מצד שני – זה לא מצב טבעי (היום) בקוברנטיס, וזה פותח פתח לקונפיגורציות מורכבות יותר לאורך כל המערכת.
    • מה קורה כאשר רוצים לעשות Replicas לבסיס הנתונים (מצב דיי שכיח)? – הקוניפוגרציות של קוברנטיס גם לא חינניות למצב הזה – והן הולכות להסתבך עוד יותר. 
    • נפילה של master ו/או Replica היא לא עניין זניח – ופה כמה הנחות יסוד של קוברנטיס לא עובדות יפה.
    בקיצור: ההמלצה הגורפת היא לא לנהל בסיסי נתונים בקוברנטיס ו/או Docker – במיוחד לא ב Production. כנ\"ל לגבי מערכות שהן memory hungry וזקוקות למלוא רוחב ה memory bus על מנת לפעול בצורה יעילה.

    שווה להזכיר את Minikube – סביבת הרצה לקוברנטיס שאפשר להריץ על המחשב האישי. המגבלה: יש רק Node אחד. היא מתאימה לפיתוח ולבדיקות פונקציונליות.

    סיכום

    Container Orchestration Frameworks לוקחים את עולם ה Containers לרמה הבאה – והמאוד מוחשית. ה Frameworks הללו מציעים כמה יתרונות חשובים – אבל הם עדיין לא הגיעו לרמת הבגרות של פתרונות הענן הקיימים.

    קוברנטיס, שקצת יותר סקרנו לעומק – הוא ה Framework הבשל והמפותח ביותר כיום. אחד הרשמים החשובים, שאני מקווה שהצלחתי להעביר, הוא שהוא לא משהו פשוט. קוברנטיס הוא לא עוד AWS Lambda, אלא פתרון ברמת מורכבות של… חצי ספק ענן. אם ללמוד לעבוד עם עוד ספק ענן לוקח X מאמץ, לעבוד עם קוברנטיס עשוי לקחת X/2 מאמץ.

    ה Sweet Spot הנוכחי של קוברנטיס (או Frameworks אחרים) הוא מערכת של Stateless Services, ללא בסיסי נתונים, וללא תלויות מורכבות בין השירותים ו/או ה Pods השונים.
    רבים מאלו שמאמצים Container Orchestration Frameworks היום, עדיין משתמשים בהם רק בסביבות הפיתוח והבדיקות – ועדיין לא בפרודקשיין.

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

    "האם הבחור הזה מתאים לנו?" (על מודל החשילות)

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

    נפתח בציטטה:

    מקור. Dee Hock הוא המייסד והמנכ\"ל האגדי של חברת ויזה, והוגה דעות חשוב בתחום הניהול.

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

    \"ניסיון קל לרכוש וליישם בצורה נכונה – כאשר התכונות האחרות נתונות\". ההיפך – לא בהכרח נכון.
    או כמו שאומרים בעגה הצבאית: \"קשור חמור לעמוד כמה שנים – והוא יהפוך לרב-סרן\" [א].

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

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

    האם שינוי הוא קשה?

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

    מודל החשילות בא לסייע בדילמה: \"הבחור הזה נראה לי ממש מתאים חוץ מא\' וב\' – כמה סביר שהוא יתאים את עצמו לתפקיד?\"

    כמטאפורה:

    • הענפים והעלים הם החלק הכי פשוט לשינוי בעץ: לדוגמה – העץ משיר את עליו ע\"פ עונות השנה המשתנות.
    • הגזע הוא קצת יותר קשה לעיצוב: אבל אור שמש ורוחות, יכולים לגרום לגזע להתעקל עם הזמן – לצורה שתטיב עם העץ.
    • השורשים מחופרים היטב באדמה, וכמעט כמעט שלא משתנים לאחר שצמחו. במקרים קיצוניים בלבד – ייתכן בהם שינוי.
    התכונות הבאות, נחשבות כ\"עלים\":
    • הכרת המוצר
    • הכרות עם החברה, והבנת הדינמיקה הארגונית שלה
    • הכרות עם טכנולוגיות / סביבת פיתוח
    • אחריות אישית
    • מיומנות תכנון / ארגון אישי
    • מיומנות להנחות אנשים אחרים
    • התמקדות ביעדים הנכונים לחברה
    כל אלו הן תכונות שאם הן חסרות למועמד – לא כדאי לפסול אותו בגללן. קל יחסית להשלים אותן.
    התכונות הבאות, נחשבות כ\"ענפים\":
    • הכרת השוק / התחום
    • יכולת הקשבה
    • יכולת הסבר טובה
    • יכולת האצלת סמכויות (למנהלים)
    • יכולת לגייס ולקדם עובדים טובים (למנהלים)
    • פיתוח מודעות עצמית גבוהה יותר
    אלו הן תכונות שרק מעט יותר קשה לשנות – ועדיין לא כדאי לוותר עד מועמד שחסר אותן.
    התכונות הבאות, נחשבות כ\"גזע\":
    • יכולת לחשיבה אסטרטגית
    • יכולת להיכנס ולהתעמק בפרטים
    • יכולת מיקוד – במספר מצומצם של נושאים.
    • פתיחות לקבלת פידבק או רעיונות אחרים
    • שיקול דעת
    • החלטיות
    • גמישות
    • יוזמה / פרואקטיביות
    • ביטחון עצמי
    • בניית קשרים טובים עם אנשים
    • עבודת צוות / שיתוף פעולה / עבודה למען מטרות משותפות
    • השפעה / השפעה ללא סמכות
    • התמודדות עם \"פוליטיקה\" / דינאמיקה ארגונית
    • גילוי אמפתיה לאחרים
    • היכולת לעורר השארה באחרים / ליטוע בהם מוטיבציה ואנרגיה
    • מצוינות / raise the bar
    • טיפול בעובדים חלשים (למנהלים)
    • לדעת ליחצן את העבודה של הצוות (למנהלים)
    אלו הן תכונות שאינן קלות לשינוי. אם אתם מתלבטים לגבי מועמד בשל תכונות מהרשימה – קחו בחשבון את האפשרות שעל אף הבעת רצון, התכונות הללו לא ישתנו.
    התכונות הבאות, נחשבות כ\"שורשים\":
    • אינטליגנציה / חדות
    • שיטתיות / יכולות אנליטיות
    • יצירתיות
    • Drive – החשק לעשות דברים
    • הרצון להשפיע וחולל שינוי
    • קבלת אתגרים גדולים / לקיחת סיכונים
    • התמדה
    • כמות ההשקעה במקום העבודה
    • שליטה עצמית
    • כנות / יושרה
    • אסרטיביות
    • כבוד לזולת / קבלת האחר
    אל תבנו על כך התכונות הללו שישתנו, באמת שלא…
    אם היה לכם מועמד שהצליח לשנות אחת מהתכונות הללו – זכיתם! אנא ספרו על כך בהערה לפוסט 🙂
    שיהיה בהצלחה!

    נ.ב. – הפוסט נכתב בלשון זכר, רק מכיוון שזה מפשט את הכתיבה / קריאה.

    —-
    [א] – גילוי נאות: אני בעל 15 שנות ניסיון בתעשייה, ובאמת שאין לי תמריץ \"לזלזל\" בחשיבות הניסיון.