השאלות הם בדיוק כמו שמתואר פה. כל הכבוד אנשים טובים
תורי לחפור :
(אגב לצערי לא עברתי,
כל המבחן הלך מצויין(!) כצפוי אחרי שקוראים את כל השאלות פה,
ולצערי ישבתי שעתיים על באג בשאלה 3, ראו פרטים בהמשך)
הם לא אמרו שיש עדיפות ל ++C או שפה כלשהי, להפך החברה גדלה ויש הרבה משרות,
אבל זה כנראה אף פעם לא קבוע ומשתנה בהתאם לתקופה..
ל-4 השאלות הראשונות יש 4 שעות
אבל מומלץ 3, ואחרי זה יורד ניקוד בהדרגה (הכל מאחורי הקלעים, לא רואים ניקוד או משהו)
יש שעה שלמה לשאלה החמישית
מי שמסיים קודם מגניב ומקבל בונוס.
אל תסיימו מהר מדי שלא יחשדו..
יש יציאה חופשית לשירותים\מטבחון\מה שבא לכם
ואפשר להיות בשירותים עם טלפון (אבל אין צורך).
המחשב שעובדים עליו מוקשח, אין 'התחל', אין 'המחשב שלי' אין אינטרנט,
יש מולך תוכנה עם ו-5 מסכים, כל אחד מכיל הוראות (באנגלית)
וכפתור שפותח VISUAL-STUDIO (אם אתם C#) עם הפרוייקט הרלוונטי
אפשר כמובן "לדפדף" הלוך וחזור.
חשוב לשמור כי זה סוגר תפרוייקט הנוכחי כשמחליפים, זה גם מזכיר את זה כל פעם.
כל מסך שכזה מצג TIMER של כמה זמן אתם על השאלה הספציפית.
לא יודע אם זה משנה לכם או להם אבל אם עושים ALT_TAB בשביל לחזור מ VISUAL STUDIO
לתוכנה הזאת ואז עוברים למסך אחר, ה TIMER שלו ממשיך לרוץ ולא של השאלה שאתם עליה,
אולי אם בסוף יש משמעות לכמה שמן התעכבתם על כל שאלה , אז יש אפשרות לשחק עם זה,
תעבירו על כמה דקות מסך בתוכנה, ואז הזמנים יהיה שוום בין כל השאלות,
או שתשאירו רוב הזמן על תרגיל 3, כי לדעתי למצוא באגים אמור לקחת יותר זמן מלכתוב דברים
יחסית פשוטים
מוסבר הניקוד על השאלות הוא לפי הקריטריונים הבאים בסדר יורד :
1. שזה יעבוד נכון
2. שזה יעיל
3. הזמן שלוקח לך לעשות את זה (גם שם רשום מומלץ 3 שעות ל 4 השאלות הראשנות יחד)
4 . קריאות ושמות משתנים וכאלה...
5. לא זוכר ויכול להיות שזה בעצם ב 4 , אבל זה זניח
אז סיכומים\הערות שלי לפי שאלות :
----------------------------------------------------------------------------------
1.
כמו שאמרו פה, פונקציה שמקבלת אובייקט כלשהו מסוג message
שמכיל FROM, TO, PROTOCOL, DATA (נניח שכולם int, זה לא באמת משנה)
עבור כל message כזה, צריך לדחות את ההודעה (להחזיר ENUM כלשהו של דחייה)
אם ה TO או ה FROM מופיעים ברשימה שחורה
הרשימה נתונה בצורת עץ - ויש לנו את ה ROOT NODE שלו
אחרת לאשר את ההודעה (להחזיר ENUM כלשהו אחר)
כל NODE בעץ מכיל
DATA
LEFT (יכול להיות NULL)
RIGHT (יכול להיות NULL)
היעילות חשובה, ושמריצים הוא כנראה מריץ מלא פעמים תפונקציה ונותן
ציון על יעילות, שזה מספר שצריך לקרב אותו כמה שאפשר ל 1000
בפיתרון הכי טריויאלי בלי דגשים על יעילות זה מביא ציון שיותר קרוב ל 2000 אם אני זוכר נכון
זה די פשוט, אבל בכל זאת, פיתרון :
- כמו שאמרו פה (ורשמו גם איך),
למצוא את ה NODE הכי עמוק שהוא אב משואף של FROM ו TO
בשביל לא להריץ חיפוש מלא על העץ פעמיים
- לחפש מה NODE שמצאנו את FROM (למשל), אם נמצא להחזיר דחייה
- אחרת, לחפש מה NODE הנ"ל את TO, אם נמצא להחזיר דחייה
- אחרת, להחזיר אישור
למי שלא סגור על זה, לא צריך שום רקורסיה !
מעבר על עץ צריך להיות משהו בסגנון הבא : (ותעתיקו כי זה הורס פה תאנגלית-עברית)
currentNode = root;
while (currentNode != null)
{
if (ValueToFind == CurrentNode.Data.Get() )
return true;
else if (ValueToFInd > CurrentNode.Data.Get() )
currentNode = currentNode.Right
else
currentNode = currentNode.Left;
}
כן ויש להם קטע מוזר שבשביל לגשת ל PROPERTY
עושים Data.Get או Data.Set ולא פשוט DATA, או Data = 4
כנראה מועתק מ-JAVA.. אבל בקטנה..
----------------------------------------------------------------------------------
2.
מקבלים הודעה וצרכים לדחות או לאשר (כמו קודם)
בהתאם להאם היא מכילה וירוסים
משתמשים במחלקה שלהם עם שם ארוך שאני לא זוכר
קודם צריך ליצור MEMBER של זה,
לאתחל את זה ב CTOR, וגם לקרוא ל SETUP (פונקצית אתחול כלשהיא)
וצריך לקרוא לפונקציה של המחלקה הזאת ולשלוח לה את ההודעה
והיא מחזירה אם יש או אין וירוס
הפונקציה מקבלת כל מני פרמטרים נוספים ולא מתועדים ולא ברורים.
מהות השאלה הזאת היא לראות איך מתמודדים עם קוד לא מתועד ואם מבינים דברים לבד
ממה שאני זוכר :
1.אם נכנסים לקוד של הפונקציה רואים שהפרמטר הראשון לא בשימוש וקיים בשביל לבלבל
(חח קוראים לו "UseLast" או משהו כזה, ואני יושב וחושב "?!use last what" )
2. לשלוח FALSE בפרמטר של FULL_SCAN,
אחרת זה ימשיך לחפש גם אם כבר מצאנו וירוס כלשהו בהודעה (אחד מספיק בשביל לדחות אותה)
3. היה עוד פרמטר עם שם מבלבל בסוף, לא זוכר מה הקטע איתו,
הוא לא משפיע על כלום אם אני לא טועה..
ציון יעילות שקיבלתי היה בסביבות 1200,
קריאה לפונקציה עם פרמטרים בצורה שונה, רק מעלה את זה.
(אם אני לא טועה לא רשום באף מקום להגיע בדיוק ל 1000, רק להתקרב כמה שיותר)
----------------------------------------------------------------------------------
3.
איכס !, חד משמעית תשאירו לסוף,
ואם אתם בנאדם ולא רובוט, כנראה שתיכנסו אליה בהתחלה
סתם בשביל הסקרנות ולהעריך זמנים,
אבל אחרי זה פשוט תתעלמו ותחזרו שסיימתם תשאר.
(כמובן שהכל בגדר המלצה, אתם מכירים את עצמכם יותר ממני)
- צריך לפתור באגים ורשום שגם וטעויות קימפול וחוסר יעילות..
- גם כאן מהות המפונקציה היא שמקבלים הודעה וצריך לאשר או לדחות,
בהתאם להאם בהודעה יש מילים לא רצויות שנתונות ברשימה כלשהיא.
- כל הבאגים הם כמו שתוארו כאן, אני לא יחזור.
(הקטע שממש רשום בהערה "אם ההודעה ריקה אז צריך פשוט לאשר אותה"
ואז הם בעצם עושים הפוך קצת הצחיק אותי)
אז ככה :
להודעה יש DATA , שזה STRING כלשהו
להודעה יש גם סוג, והוא אחד מ-3 ערכים אפשריים
לכל הודעה צריך לעבור על ה DATA
ולחפש אם מופיעות שם מילים לא רצויות, יש פונקציה שעושה את זה.
הDATA בהודעות מסוג SMTP אמור להראות ככה :
"SUBJECT:blablabla BODY:blablalba"
להודעות מסוג SMTP צריך לחפש מילים לא בכל ה-string
אלה רק בחלקים מסוימים ממנו, כמו שתואר פה כבר.
הבעיה שלי שהטקסט של כל הודעה שהפונקציה קיבלה
(סתם בהתחלה, עוד לפני השלב שמחליטים איזה סוג הודעה זה ומה לעשות עם זה)
לא היה בפורמט הנ"ל, לא היה בפורמט כלשהו, לא היה קריא בכלל,
אלה היה מבולגן ומזובל, משהו בסגנון : "SA@#!$# AO G32$%@HDF@ iRC5"
נדמה שזה שמר בין הודעות על הסדר של הרווחים וכמות אותיות בכל "מילה"
או שזה יום רע ממש, וזה מהבאגים שהולכים לישון ובבוקר שאחרי ישר פותרים
כי בדיוק פיספסתי איזה נקודה פסיק או משהו שולי,
או שחמאס חיבלו במבחן שלי.
דברים שניסיתי :
- חיפשתי במחלקות שלהם ולא היה זכר לאיזה משהו שיפענח את זה לפורמט נכון
- לא עשיתי משהו שאולי בעקבות זה זה נהיה ככה, פשוט לשים BREAKPOINT, ולבדוק
- בדקתי לכל ההודעות, לא היתה אחת נורמלית
- היה שם אופציה לעשות SERIALIZE \ DESERIALIZE להודעה, זה לא קשור
שתדעו למקרה שאתם נתקלים בזה
- שמריצים את התונית אז דוח שגיאה עם מידע קצר על ההודעה הראשונה שהטיפול בה נכשל,
מתוך מלא הודעות שהם מריצים את זה עליהם, ושם מופיע ה-DATA בפורמט קריא.
- גם אם כוונת המשורר היא לא לחטט להם מאחורי הקלעים, הרי מתישהו
הטקסט של אובייקט ההודעה שהם שוליחים לפונקציה שלנו נהיה קריא ומודפס בדוח שגיאה,
אז אמרתי שווה לבדוק מה עושה את זה..
- לכן דיבגתי גם "מאחורי הקלעים" וזה בכוונה מבולגן ולא קריא ומלא פונקציות ותנאים שלא
עושים כלום וקיימים בשביל להטעות, ומשתנים לא קריאים וכו'...
זה לא סתם קוד שמתכנת מתחיל כתב, בברור מדובר על קוד שתוכנן להיות לא קריא.
(ועולים לי קונספירציות בראש, אם זה בשביל שלא נרמה ונשנה את מה שבודק את הקוד,
או כי הבעיה באמת שם ורוצים לראות איך מתמודדים עם קוד שנכתב ע"י השטן...)
קשה להבין משהו בקוד המבולגן הזה וזה גזל לי זמן.
עשיתי עוד מלא מלא דברים .. אבל בגדול לא מצאתי איך להפוך את זה למה שצריך
די מבאס שעל זה ישבתי שעתיים ובעצם שאר 99% מהמבחן פתרתי בצ'יק..
אם אתם מוצאים מה הבעיה, שטפו !!!
שאלתי בסוף את המשיח אבל לא הוא זה שכתב תמבחן ויודע מה הולך שם לעומק.
חח אז קשה להסביר לו שבשאלה של למצוא באגים אולי יש באג..
הקטע הוא שלא לכולם הזה את זה ולכן אני חושד.
אבל יצא לי לשאול אנשים שלא נבחנו ב C#, אז הכל יכול להיות.
(אני כבר לא זוכר באיזה שפה הם עשו את המבחן, נרא לי C)
----------------------------------------------------------------------------------
4.
יש פונקציה שמקבלת הודעה, ונזכור לשהודעה יש כתובת שולח
יש פונקציה שצריכה להחזיר את כל כתובות השולחים שמהם נשלחו יותר מ 10%
מההודעות עד עכשיו.
רשום שהפונקציה של השנייה נקראת הרבה פעמים (אחת לכל הודעה)
ולא סתם כמה פעמים רנדומלים וזהו..
הפיתרון הפשוט הוא :
-----------------------
- צריך כמובן משתנה סטטי שסופר את כמות ההודעות הכוללת
- צריך Dictionary כך שKEY זה כתובת שולח ו ה VALUE זה כמות ההודעות מהשולח הזה
- בפונקציה שמקבלת הודעה :
* אם השולח עוד לא ב DICTIONARY להוסיף, עם ערך 1
* אם קיים, אז להגדיל את הערך ב 1
- בפונקציה שמחזירה את השולחים יותר מ 10% :
- לחשב את כמות ההודעות שצריך לעבור בצורה הבאה: m_totalMessageCount * 0.1
אין יותר פשוט מזה ! (כמובן להמיר ל DOUBLE)
- לעבור על ה DICTIONARY ולהוסיף ל HASH_SET שאותו מחזירים
כתובות של אלה שכמות ההודעות שלהם עברה את הנ"ל
זה פשוט, ובציון של היעילות זה נותן 1000 שזה מה שרשום שהם מחפשים
אם בא לכם ,יש דרך לשפר את זה,
( אישית לא ניסיתי כי הגעתי ל-1000 והעדפתי להתרכז על שאלה 3
אם הייתי פותר את 3, חד משמעית הייתי מנסה לשפר את 4)
המלצות שלי, בהשראת מה שנכתב פה בעבר :
--------------------------------------------------
לא צריך לעבור על כל ה DICTIONARY זה מיותר.
ובעולם האמיתי יש מצב של מליוני שולחים ואז גם זה יהיה לא יעיל.
אם היינו צריכים למשל להחזיר את אלה ששלחו יותר מ 50%
אז יש מקסימום 2 כאלה ,אם בכלל, תחשבו על זה.
אם 25%, אז מקסימום 4 כאלה..
במקרה שלנו זה מקסימום 10, אבל נחשוב גנרי
ואפשר בהינתן אחוז הרצוי, לחשב את המספר מקסימלי של השולחים
(תמצאו לבד כי העברית-אנגלית פה הורס את זה ואני מעדיף לא להטעות)
- אפשר ליצור DICTIONARY נוסף, או כל COLLECTION של KeyValuePairs בגודל שקיבלנו
או 2 מערכים (אני פחות אוהב, כי זה בגודל קבוע, ומה אם מחר נחליט לשנות את האחוז)
במטרה לאחסן שם בכל רגע נתון את השולחים עם הכי הרבה הודעות
- בשביל הנוחות, לתחזר משתנה שאומר מה הערך המינימאלי באוסף הזה
- בפונקציה שמקבלת הודעה :
* נעלה ב-1 את כמות ההודעות ב DICTIONARY הרגיל כמו קודם,
* אם כמות ההודעות של השולח הזה עוברת את המינימום באוסף שלנו
אז נתרח לעדכן את האוסף כך שיכלול את השולח הזה במקום מישהו שכבר לא מגניב מספיק.
- בפונקציה שמחזירה את השולחים מעל אחוז מסוים :
נעבור רק על האוסף שלנו, ונחזיר מתוכו את אלה שעוברים את האחוז
שימו לב לא להחזיר את כל האוסף כי הוא אמנם הוא מכיל את אלה ששלחו הכי הרבה
אבל לא כולם עוברים את האחוז
בכל מקרה הפונקציה עברה להיות מתלויה בגודל המילון למהירה הרבה יותר
את האוסף הזה, המשתנה של המימינום, וכל התפעול הזה הייתי שם ב CLASS פנימי
בשביל הסדר והקריאות וכאלה,
הייתי עושה שם פונקציה UPDATE שמקבלת הודעה ומעדכנת אם צריך.
----------------------------------------------------------------------------------
5.
התבלבתי ממה שכתוב פה, מדובר על תת-קבוצות ולא פרמוטציות
כלומר עבור {a,b,c} התוצאה צריכה להיות משהו בסגנון הזה :
{ABC}
{AB}
{AC}
{BC}
{A}
{B}
{C}
{קבוצה ריקה}
אין משמעות לסדר, כלומר AB ו- BA זה אותו איבר
נבחנתי ב- C#
מבחינה טכנית הפונקציה מקבלת string
וצריכה להחזיר IEnumarable (כרצונכם, נגיד List) שמכיל IEnumarables
(כי מה שבודק את זה זה אוטומטי ולא בנאדם)
להלן מימוש ישן שלי לא בטוח לגבי היעילות של זה (איכס עברית-אנגלית) :
כתוב ב- #C
private static List<List<string>> Subgroups2(params string items)
{
// Definitions
List<List<string>> result = new List<List<string>>();
bool usedItems = new bool;
// Adding empty group
result.Add(new List<string>()); // for the empty group
// Adding sub groups by size
for (int groupSize = 1; groupSize <= items.Length; groupSize++)
{
Subgroups2(items, result, groupSize, new List<string>(), usedItems);
}
/////////////////////////////
foreach (var list in result)
{
Console.WriteLine(string.Join(" ", list));
}
/////////////////////////////
return result;
}
private static void Subgroups2(string items,
List<List<string>> result,
int groupSize,
List<string> currentGroup,
bool usedItems,
int currentSlot = 0,
int indexOfLastItem = -1
)
{
if (currentSlot >= groupSize)
{
// copy current group to new item in result
List<string> newGroup = new List<string>();
newGroup.AddRange(currentGroup);
// Add new group
result.Add(newGroup);
}
else
{
for (int currentItemIndex = 0; currentItemIndex < items.Length; currentItemIndex++)
{
if (usedItems == true)
continue;
if (currentItemIndex <= indexOfLastItem)
continue;
usedItems = true;
currentGroup.Add(items);
Subgroups2(items, result, groupSize, currentGroup, usedItems, currentSlot + 1, currentItemIndex);
currentGroup.RemoveAt(currentGroup.Count-1);
usedItems = false;
}
}
}
שימו לב שבפונקציה השנייה, אם מורידים את התנאי עם IndexOfLastItem
אז מקבלים גם את כל הפרמוטציות של כל תתי הקבוצות,
(וזה לא מה שהם מחפשים, אבל תראו פשוט תהבדל)
------------------------------------------------------------------------------------------
וזהו ,
תהיו נחמדים ותשטפו ראיונות,
יש אנשים שישקיעו ולימדו ויצליחו בעבודה וחבל שזה יתפספס,
למי שחושב אחרת, ברור, צריך ששזה יהיה הוגן כלפי החברה ושהעובד ידע מה הוא עושה,
ואנשים צרכים ללמוד ולהשקיע, אבל מבחנים כאלה זה פשוט לא הדרך.
שונא ראיונות עם מבחנים אוטומטים כאלה במקום שיחה עם בנאדם.
לא לדעת מה זה עץ בינארי זה משהו אחד, אבל להתקע על באג שכזה לא מייצג.
ואני אומר את זה בתור תוכניתן מנוסה שעבד בכמה פרוייקטים גדולים, אז הינה P:
יהיה בסדר !
בהצלחה חברים !!!!!!!!!