סיכום - מאגר עובדים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 66 מתוך 107.
אתגר
קלבואו נבנה מערכת לעיבוד משימות באמצעות תבנית מאגר העובדים! תיצור מאגר עובדים שיעבדו במקביל על משימות חישוביות, ותדגים כיצד ערוצים, goroutines ו-WaitGroups פועלים יחד כדי לטפל בעומסי עבודה ביעילות.
תארגן את הקוד שלך בשני קבצים:
pool.go: הגדר את רכיבי מאגר העובדים ואת הלוגיקה שלהם.צור מבנה
Taskעם השדותID(int) ו-Value(int), המייצגים את העבודה שיש לבצע.צור מבנה
Resultעם השדותTaskID(int) ו-Computed(int), המייצגים עבודה שהושלמה.ממש פונקציה
Workerשמקבלת מזהה עובד (int), ערוץ משימות לקריאה בלבד (<-chan Task), ערוץ תוצאות לכתיבה בלבד (chan<- Result) ומצביע ל-sync.WaitGroup. כל עובד צריך:- להשתמש ב-
defer wg.Done()כדי לסמן שהעבודה הושלמה - לעבור על ערוץ המשימות כדי לעבד כל משימה
- לחשב את ריבוע הערך של כל משימה
- לשלוח Result עם ה-TaskID והריבוע שחושב
ממש פונקציה
RunPoolשמקבלת את מספר העובדים (int) ופרוסה של משימות. הפונקציה צריכה:- ליצור ערוצים עם מאגר עבור המשימות והתוצאות (להשתמש במספר המשימות כגודל המאגר)
- להפעיל את מספר העובדים שצוין בתור goroutines
- לשלוח את כל המשימות לערוץ המשימות, ואז לסגור אותו
- להשתמש ב-goroutine עם ה-WaitGroup כדי לסגור את ערוץ התוצאות לאחר שכל העובדים מסיימים
- לאסוף את כל התוצאות לפרוסה ולהחזיר אותה
- להשתמש ב-
main.go: קרא את הקלט ותאם בין רכיבי מאגר העובדים.קרא את מספר העובדים, ואז את מספר המשימות. עבור כל משימה, קרא את המזהה ואת הערך שלה. קרא ל-
RunPoolעם העובדים והמשימות, ואז הדפס כל תוצאה בפורמט:Task [TaskID]: [Computed]הדפס את התוצאות ממוינות לפי TaskID בסדר עולה.
הקלטים הבאים יסופקו:
- שורה 1: מספר העובדים (מספר שלם)
- שורה 2: מספר המשימות (מספר שלם)
- השורות הבאות: עבור כל משימה, שתי שורות — מזהה המשימה (מספר שלם), ואז הערך שלה (מספר שלם)
לדוגמה, עבור:
2
4
1
3
2
5
3
2
4
7הפלט שלך צריך להיות:
Task 1: 9
Task 2: 25
Task 3: 4
Task 4: 49העובדים מעבדים משימות במקביל (3 בריבוע הם 9, 5 בריבוע הם 25 וכן הלאה), והתוצאות נאספות ומוצגות לפי סדר מזהי המשימות. כש-2 עובדים מטפלים ב-4 משימות, העבודה מתחלקת ביעילות בין העובדים במאגר.
נסו בעצמכם
package main
import (
"fmt"
"sort"
)
func main() {
// קרא את מספר העובדים
var numWorkers int
fmt.Scanln(&numWorkers)
// קרא את מספר המשימות
var numTasks int
fmt.Scanln(&numTasks)
// קרא את המשימות
tasks := make([]Task, numTasks)
for i := 0; i < numTasks; i++ {
var id, value int
fmt.Scanln(&id)
fmt.Scanln(&value)
tasks[i] = Task{ID: id, Value: value}
}
// TODO: קרא ל-RunPool עם העובדים והמשימות
// TODO: מיין את התוצאות לפי TaskID בסדר עולה
// TODO: הדפס כל תוצאה בפורמט: Task [TaskID]: [Computed]
}
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות OOP ב-Go
קבצים חיצונייםסביבת העבודה והמודולים של Goחבילות וייבואשמות מיוצאים לעומת שמות לא מיוצאיםמבוא ל-OOP ב-GoStructs כמחלקותהגדרת מתודות עבור Structsמקבלי Pointer לעומת Valueאתחול Structפונקציות Constructorחזרה – מחשבון פשוט4ממשקים
מבוא לממשקיםמימוש משתמעממשק כחוזהממשק ריק (any)אימות טיפוסמתג טיפוסיםהרכבת ממשקיםממשקי Stringer ו-Errorסיכום – מחשבון צורות7כימוס
שדות מיוצאים לעומת שדות לא מיוצאיםכימוס ברמת החבילהמתודות Getter ו-Setterהסתרת מידע ב-Goסיכום – רשומות תלמידים10Generics (Go 1.18 ומעלה)
מבוא ל־Genericsפרמטרים של טיפוסיםאילוצי טיפוסיםמבנים גנרייםפתרון עוקף למתודות גנריותסיכום – אוסף גנרי2העמקה בסוגים וב-Structs
סוגים בסיסיים ומורכביםהגדרות של סוגים מותאמים אישיתתגיות StructStructs אנונימייםStructs מקונניםערכי אפס וברירות מחדלסיכום – ספר אנשי קשר5קומפוזיציה במקום ירושה
למה ב-Go אין ירושהיסודות הטמעת Structקידום מתודותהטמעת כמה Structsהטמעה לעומת אגרגציההסתרת מתודות מוטמעותסיכום – היררכיית עובדים8טיפול בשגיאות ו-OOP
ממשק errorסוגי שגיאות מותאמים אישיתעטיפת שגיאות (fmt.Errorf)שגיאות Sentinelerrors.Is() ו-errors.As()Panic, Defer ו-Recoverסיכום – מנתח קבצים11ספרייה סטנדרטית ותכנות מונחה עצמים
io.Reader ו-io.Writersort.Interfaceהממשק fmt.Stringerencoding/json עם מבניםהממשק http.Handlerסיכום – מודלים של REST API3מצביעים וזיכרון
יסודות המצביעים ב-Goמצביעים למבניםהעברה לפי ערך לעומת לפי הפניההפונקציה new()איסוף אשפה ב-Goסיכום - בונה רשימה מקושרת6פולימורפיזם ב-Go
פולימורפיזם באמצעות ממשקיםטיפוס ברווז ב-Goכללי התאמה לממשקאוספים פולימורפייםהזרקת תלויותסיכום - מעבד תשלומים9מקביליות ו-OOP
יסודות GoroutinesChannels ותקשורתChannel עם חוצץ לעומת ללא חוצץפקודת Selectsync.Mutex ו-sync.RWMutexsync.WaitGroupתכנון Struct בטוח לשימוש במקבילסיכום - מאגר עובדים12מושגים מתקדמים בתכנות מונחה עצמים
דפוס האפשרויות הפונקציונליותדפוס Builder ב-Goשרשור מתודותכינויי טיפוסים לעומת הגדרותיסודות Reflectionסקירה כללית של יצירת קודתרגלו בעצמכם: קומפיילר Go אונליין