יום מיונים- תיכנות- תאור מפורט

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

חלק א:

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

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

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

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

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

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

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

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

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

כמה דגשים: כמו בשאלה 1 גם כאן יש להגדיר משתנה פרטי מסוג מחלקת אנטי וירוס ולאתחל אותו בבנאי, חשוב לשים לב שהאתחול כולל גם new וגם קריאה לפונקציית setup (פונקציה של המחלקה) שהיא טוענת בסיס נתונים של הוירוסים וכך האובייקט אנטי וירוס מוכן לשימוש, אגב הצורה שבה הסריקה מתבצעת היא באמצעות ביטויים רגולרים אבל זה לא אמור לעניין אותכם, שימו לב שגם בקריאה אח"כ לפונקציית סריקת מסר מלבד המסר יש עוד כמה ערכים בוליאנים ששולחים אליה, יש ערך שנקרא fullscan שהוא צריך להיות false כי אם הוא true אז מה שיקרה זה שמסר שישלח יבדק כנגד כל הבסיס נתונים של הוירוסים שזה מיותר מכיוון שאם הוא false אז הוא סורק רק עד מציאת וירוס ראשון ואז מפסיק וזה ישפר לכם את הביצועים, יש עוד פרמטר (הראשון ביותר) שבכלל אין לו שימוש בתוך האנטי וירוס וסתם כתבו אותו כדי לבלבל, והפרמטר האחרון הוא loadviruses אך הוא יכול להיות true או false זה לא משנה, כי גם ככה בכל קריאה לסריקת מסר יש בדיקה האם הבסיס נתונים כבר נטען קודם ואם כן אז לא טוענים אותו גם האם הפרמטר הזה יהיה true.

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

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

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

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

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

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

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

חלק ב:

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

אנסה לפרט מה שאני זוכר שיש לעשות שם: דבר ראשון יש לבדוק כתובות ip של שתי המכונות, אחר כך לעשות פינג מהמכונה הראשונה לעצמה, אחר כך מהראשונה לשניה, להוריד קובץ tar/zip מהמכונה השניה לראשונה באמצעות ftp, הקובץ הוא למעשה התקנה של תוכנה בשם pure ftp, יש לפתוח אותו, לקמפל את התוכן שלו, להתקין את התוכנה, להריץ אותה, לעשות kill לתהליך שלה, לחפש בתוך אחד ה – headers שלה מסר מסוים (welcome to), לפתוח את המסר הזה ולהוסיף לו את המילה my, לקמפל שוב ולהתקין את התוכנה מחדש, לפתוח את התוכנה ולראות שהמסר שהיא מציגה בהתחלה השתנה בהצלחה.

כמה דגשים: כמו שקודם אמרתי רוב הדברים שיש לעשות רשום במסמך איזה פקודות צריך להקליד כך שאין צורך לזכור פקודות בעל פה, כשמחפשים את המסר שיש לשנות אז לחפש רק את המילים "welcome to" ולא את כל המסר (כי זה נראה לי מסר שמשורשר משני מקומות שונים) אם אני זוכר נכון זה נמצא בקובץ messages_en.h, את הקימפול הסטנדרטי אפשר לעשות עם gcc או make אבל אין צורך לשבור את הראש ולמצוא מה צריך לקמפל אלא יש שם קובץ טקסט שנקרא install, פותחים אותו עם עורך טקסט וישר בשורה הראשונה רשומות 3 פקודות שצריך להריץ, מריצים את 3 הפקודות אחת אחרי השניה והן גם מקמפלות וגם מתקינות את התוכנה, כדי להפעיל את התוכנה אני נכנסתי פשוט לתיקיית הקיצורי דרך לתוכנות מותקנות שהיא אם אני זוכר נכון usr/local/sbin (בכל מקרה כאשר מריצים את 3 הפקודות אז רשום לאיפה הוא מתקין אותה).

חלק ג:

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

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