הכנה לראיון עבודה - מפתח/ת .NET

דף רענון ממוקד לראיון עבור משרת .NET בצוות תשתיות פיתוח, עם Angular, Docker, Kubernetes, GCP, Microservices, SQL ו־Git/Azure DevOps.

תפקידמפתח/ת תוכנה .NET
לקוחשע"מ - שירות עיבודים ממוחשבים
מיקוםדימונה, היברידי, ירושלים פעם ב־3 שבועות
מטרהלעבור לשלב הבא בתהליך

המטרה של הראיון

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

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

הצגה עצמית של דקה וחצי

אני מפתח תוכנה עם ניסיון ב־.NET, עבודה מול בסיסי נתונים, Git, פיתוח צד שרת, ועניין חזק במערכות תשתית ומערכות מורכבות. אני אוהב להבין לא רק את הקוד עצמו אלא גם איך הוא רץ, איך פורסים אותו, איך מתחזקים אותו, ואיך עושים אותו יציב וברור לצוות.
מה שמעניין אותי במשרה הזאת זה שהיא לא רק CRUD רגיל, אלא עבודה על רכיבי תשתית, פתרונות רוחביים וסביבה עם Microservices, Docker/Kubernetes וענן.

נושאים טכניים שחובה לרענן

.NET / C#

  • Dependency Injection
  • async/await
  • REST API
  • Middleware
  • Controllers מול Minimal APIs
  • Configuration ו־Environment Variables
  • Logging וטיפול בשגיאות
  • LINQ ו־Entity Framework
  • DTO מול Entity
  • SOLID ושכבות בקוד

Angular

  • Components
  • Services
  • Dependency Injection
  • Routing
  • Reactive Forms
  • RxJS ו־Observables
  • HttpClient
  • Interceptors
  • Guards
  • Standalone Components ו־Signals

Docker / Kubernetes

  • Image מול Container
  • Dockerfile
  • Multi-stage build
  • Ports, volumes, env vars
  • Pod, Deployment, Service
  • ConfigMap ו־Secret
  • Liveness ו־Readiness probes
  • Rolling updates

SQL / Git / ענן

  • JOINs
  • Indexes
  • Transactions
  • N+1 problem
  • Git branches ו־Pull Requests
  • CI/CD
  • Azure DevOps Pipelines
  • GCP: GKE, Cloud Run, Cloud SQL, IAM

שאלות אישיות שסביר שישאלו

ספר על עצמך

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

למה אתה רוצה את המשרה?

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

מה החולשה שלך?

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

איך אתה מתמודד עם טכנולוגיה שלא עבדת איתה?

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

איך אתה עם נסיעות לדימונה/ירושלים?

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

אם אין ניסיון מלא בכל הטכנולוגיות

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

שאלות טובות לשאול אותם בסוף

  • איך נראה יום עבודה טיפוסי בצוות?
  • האם רוב העבודה היא פיתוח רכיבי תשתית חדשים או תחזוקה ושיפור של קיימים?
  • כמה הצוות מעורב ב־Docker/Kubernetes ו־GCP בפועל, לעומת צוות DevOps נפרד?
  • איך נראה תהליך ה־code review וה־deployment אצלכם?
  • מה ייחשב הצלחה בתפקיד אחרי שלושה חודשים?

רשימת הכנה לערב לפני

  1. להסביר בעל פה מה זה Docker, Kubernetes ו־Microservices.
  2. להכין פרויקט אחד שאתה יכול להסביר: בעיה, פתרון, טכנולוגיות, אתגר ומה למדת.
  3. לרענן SQL: joins, indexes, transactions.
  4. לרענן async/await ו־Dependency Injection.
  5. להכין תשובה למה המשרה מעניינת אותך.
  6. להכין תשובה רגועה לגבי הנסיעות לדימונה וירושלים.

1. .NET / ASP.NET Core

ב־ASP.NET Core בונים לרוב Web APIs. המבנה המקובל:

  • Controller או Minimal API מקבל בקשה מהלקוח.
  • Service מכיל לוגיקה עסקית.
  • Repository או Data Access מדבר עם בסיס הנתונים.
  • DTOs משמשים להעברת מידע פנימה והחוצה.
  • Dependency Injection מפחית coupling ומקל על בדיקות.
ב־.NET אני משתדל לבנות Controller דק שמקבל request ומחזיר response, ואת הלוגיקה לשים ב־Service. אם יש גישה ל־DB, אני מפריד אותה לשכבת data access או repository. אני משתמש ב־Dependency Injection כדי להזריק services ולא ליצור coupling חזק.

Dependency Injection

public UsersController(IUserService userService)
{
    _userService = userService;
}
builder.Services.AddScoped<IUserService, UserService>();
Lifetimeמשמעות
Singletonמופע אחד לכל חיי האפליקציה
Scopedמופע אחד לכל request
Transientמופע חדש בכל בקשה

2. async / await

async/await משמש לפעולות שלא כדאי לחסום בהן thread, כמו DB, API, קבצים ורשת.

public async Task<UserDto> GetUserAsync(int id)
{
    var user = await _db.Users.FindAsync(id);
    return new UserDto(user.Id, user.Name);
}
אני משתמש ב־async/await בעיקר בפעולות I/O כמו DB או HTTP calls. זה לא בהכרח הופך פעולה למהירה יותר בפני עצמה, אבל זה מאפשר לשרת לא לבזבז thread בזמן המתנה, ולכן הוא יכול לטפל ביותר בקשות במקביל.
להימנע מ־.Result או .Wait() על פעולות async כי זה עלול לגרום לחסימות ובעיות.

3. REST API

פעולהHTTP Verb
שליפהGET
יצירהPOST
עדכון מלאPUT
עדכון חלקיPATCH
מחיקהDELETE
ב־REST אני משתדל לשמור על URLs שמייצגים משאבים, להשתמש נכון ב־HTTP verbs, להחזיר status codes מתאימים, ולא לחשוף entities פנימיים ישירות אלא להשתמש ב־DTOs.
Status Codeמשמעות
200הצלחה
201נוצר בהצלחה
400בקשה לא תקינה
401לא מזוהה
403אין הרשאה
404לא נמצא
500שגיאת שרת

4. Middleware

Middleware הוא רכיב שיושב ב־pipeline של הבקשה. כל request עובר דרך שרשרת של רכיבים.

  • Authentication
  • Authorization
  • Logging
  • Exception handling
  • CORS
  • Routing
Middleware מאפשר לטפל בבקשות בצורה רוחבית לפני או אחרי שהן מגיעות ל־Controller. לדוגמה, לוגים, טיפול בשגיאות, הרשאות או CORS.

5. SOLID בקצרה

עיקרוןהסבר פשוט
Sמחלקה צריכה אחריות אחת ברורה
Oלהרחיב בלי לשבור קוד קיים
Lמחלקת בן צריכה להתאים לשימוש במקום האב
Iלא להכריח interface ענק
Dלעבוד מול abstraction ולא מול מימוש קשיח
אני לא מנסה לדקלם SOLID, אבל בפועל אני משתדל לכתוב מחלקות עם אחריות ברורה, לעבוד מול interfaces כשזה נותן ערך, ולהימנע ממצב שבו שינוי קטן גורר שינוי בהרבה מקומות.

6. Angular

Angular הוא framework לבניית אפליקציות web. המבנה המרכזי:

  • Component מציג UI.
  • Template הוא ה־HTML של הקומפוננטה.
  • Service מכיל לוגיקה משותפת או קריאות API.
  • Router מנהל מעבר בין מסכים.
  • HttpClient משמש לקריאות ל־backend.
  • Interceptor משמש לדברים רוחביים כמו token או טיפול בשגיאות.
ב־Angular אני משתדל לשמור על קומפוננטות שאחראיות בעיקר על תצוגה ואינטראקציה, ואת הקריאות ל־API או לוגיקה משותפת לשים ב־services. התקשורת מול backend נעשית בדרך כלל דרך HttpClient, והניווט דרך Angular Router.
@Injectable({ providedIn: 'root' })
export class UsersService {
  constructor(private http: HttpClient) {}

  getUsers() {
    return this.http.get<User[]>('/api/users');
  }
}

7. RxJS / Observable

ב־Angular הרבה פעולות מחזירות Observable, במיוחד קריאות HTTP או streams של נתונים.

this.usersService.getUsers().subscribe(users => {
  this.users = users;
});
Observable מתאים לעבודה עם נתונים אסינכרוניים, במיוחד ב־Angular. בקריאות HTTP הוא מחזיר ערך אחד ואז מסתיים, אבל באירועים או streams הוא יכול להמשיך להוציא ערכים לאורך זמן.
מושגמשמעות
subscribeהרשמה לקבלת הערכים
pipeשרשור פעולות
mapשינוי הערך
filterסינון
switchMapמעבר לקריאה חדשה וביטול הקודמת
catchErrorטיפול בשגיאות

8. Docker

מושגהסבר
Imageתבנית מוכנה להרצה
Containerמופע רץ של image
Dockerfileהוראות לבניית image
Volumeאחסון חיצוני/קבוע
Port mappingחיבור פורט פנימי לחיצוני
Docker עוזר לוודא שהאפליקציה רצה באותה צורה בפיתוח, בדיקות ופרודקשן. במקום להסתמך על מה שמותקן על המכונה, אורזים את האפליקציה וה־dependencies שלה לתוך image.
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app

FROM mcr.microsoft.com/dotnet/aspnet:10.0
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.dll"]
Multi-stage build מאפשר לבנות את האפליקציה בשלב אחד ולהעתיק רק את התוצר הסופי ל־image קטן ונקי יותר.

9. Kubernetes

Kubernetes מנהל containers בסביבה אמיתית: פריסה, scaling, health checks, networking ו־service discovery.

מושגהסבר
Podיחידת הריצה הקטנה ביותר
Deploymentמנהל Pods וגרסאות
Serviceחושף Pods דרך endpoint יציב
ConfigMapהגדרות לא סודיות
Secretמידע רגיש כמו סיסמאות או tokens
Ingressכניסה חיצונית לשירותים
Namespaceהפרדה לוגית בתוך cluster
Docker מריץ container. Kubernetes מנהל הרבה containers בסביבה אמיתית: הוא דואג לפריסה, scaling, health checks, rolling updates, networking ו־service discovery.
Probeלמה משמש
Livenessהאם האפליקציה חיה או צריך להפעיל מחדש
Readinessהאם האפליקציה מוכנה לקבל traffic
Readiness אומר אם השירות מוכן לקבל בקשות. Liveness אומר אם הוא תקוע וצריך restart.

10. Microservices

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

יתרונות

  • קל לעשות scale לשירות ספציפי.
  • צוותים יכולים לעבוד עצמאית.
  • Deployment נפרד.
  • כשל בשירות אחד לא בהכרח מפיל הכול.

חסרונות

  • תקשורת בין שירותים מסובכת יותר.
  • Debugging קשה יותר.
  • Latency ו־distributed failures.
  • Versioning בין APIs.
  • צריך logging ו־monitoring טובים.
Microservices זה לא רק לפצל פרויקט לכמה APIs. צריך להגדיר גבולות נכונים בין שירותים, אחרת מקבלים מונולית מבוזר שקשה יותר לתחזוקה.

11. GCP בקצרה

מושגשימוש
Compute Engineמכונות וירטואליות
Cloud Runהרצת containers בלי לנהל שרתים
GKEKubernetes מנוהל ב־Google
Cloud SQLDB מנוהל
Cloud Storageאחסון קבצים
IAMהרשאות
Cloud Loggingלוגים
Secret Managerניהול secrets
אני מכיר את העקרונות של עבודה בענן: הפרדה בין compute, storage, networking, permissions ו־managed services. ב־GCP ספציפית אני מכיר את המושגים המרכזיים כמו GKE, Cloud Run, Cloud SQL, IAM ו־Logging, ואני יודע לגשת לזה בצורה מסודרת.

12. SQL Server / PostgreSQL

  • SELECT, JOIN, GROUP BY
  • Indexes
  • Transactions
  • Foreign keys
  • Stored procedures
  • Views
  • Performance
  • Migrations
SELECT u.Name, o.OrderDate
FROM Users u
INNER JOIN Orders o ON u.Id = o.UserId;
JOINמשמעות
INNER JOINרק רשומות שיש התאמה בשני הצדדים
LEFT JOINכל צד שמאל, גם אם אין התאמה
RIGHT JOINכל צד ימין
FULL JOINהכול משני הצדדים

Index

Index עוזר ל־DB למצוא נתונים מהר יותר, כמו אינדקס בספר. מצד שני, הוא תופס מקום ומאט insert/update/delete כי צריך לעדכן גם את האינדקס.

קודם הייתי בודק execution plan, האם יש indexes מתאימים, האם יש JOIN כבד, האם הפילטרים משתמשים באינדקס, האם יש בעיית N+1 מה־ORM, והאם יש locking או עומס על DB.

Transaction

BEGIN TRANSACTION;

UPDATE Accounts SET Balance = Balance - 100 WHERE Id = 1;
UPDATE Accounts SET Balance = Balance + 100 WHERE Id = 2;

COMMIT;
Transaction חשובה כשיש כמה פעולות שחייבות להצליח יחד. לדוגמה העברת כסף, יצירת הזמנה ועדכון מלאי.

13. Entity Framework

ORM שמאפשר לעבוד עם DB דרך אובייקטים ב־C#.

var users = await _db.Users
    .Where(u => u.IsActive)
    .ToListAsync();

יתרונות

  • פחות SQL ידני
  • Productivity גבוה
  • Migrations
  • LINQ

חסרונות

  • לפעמים יוצר שאילתות לא יעילות
  • צריך להבין מה קורה מאחורי הקלעים
  • סכנת N+1
ב־EF חשוב לבדוק שה־LINQ לא מייצר שאילתות גרועות. אם יש N+1, אפשר להשתמש ב־Include, projection ל־DTO, או שאילתה מפורשת יותר.

14. Git / Azure DevOps

מושגהסבר
branchענף עבודה נפרד
commitשמירת שינוי
pull requestבקשה למזג קוד
merge conflictהתנגשות בין שינויים
pipelineתהליך אוטומטי של build/test/deploy
CIבדיקה ובנייה אוטומטית
CDפריסה אוטומטית
אני אוהב לעבוד עם branch נפרד לכל משימה, commits קטנים וברורים, pull request מסודר, ו־code review. במערכות גדולות זה חשוב כדי לשמור על איכות ולא לשבור דברים לצוותים אחרים.
Pipeline בדרך כלל עושה restore/build/test, לפעמים גם static analysis, ואז יוצר artifact או image, ובשלב הבא פורס לסביבה כמו dev/test/prod.

שאלות קצרות ותשובות מוכנות

מה ההבדל בין interface ל־class?

Class הוא מימוש. Interface מגדיר חוזה. כשעובדים מול interface קל יותר להחליף מימוש, לבדוק עם mock, ולהקטין coupling.

מה ההבדל בין abstract class ל־interface?

Interface מגדיר יכולות או חוזה. Abstract class יכולה להכיל גם מימוש חלקי ושדות. אם אני צריך רק חוזה, אבחר interface. אם יש בסיס משותף אמיתי, abstract class יכולה להתאים.

מה זה DTO?

DTO הוא אובייקט להעברת מידע בין שכבות או החוצה ל־API. הוא מונע חשיפה ישירה של Entity פנימי ומאפשר לשלוט בדיוק מה הלקוח מקבל או שולח.

למה לא להחזיר Entity ישירות מה־API?

כי Entity מייצג את מבנה ה־DB ולא בהכרח את החוזה מול הלקוח. זה יכול לחשוף שדות מיותרים, ליצור coupling, ולגרום בעיות כשמבנה DB משתנה.

מה זה Repository Pattern?

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

מה ההבדל בין Authentication ל־Authorization?

Authentication זה לזהות מי המשתמש. Authorization זה לבדוק מה מותר לו לעשות.

מה זה CORS?

CORS הוא מנגנון אבטחה בדפדפן שמגדיר מאילו domains מותר לקרוא ל־API. אם frontend ו־backend יושבים על origins שונים, צריך להגדיר CORS נכון.

סיכום לשינון לפני הראיון

ב־.NET אני בונה API בשכבות: Controller דק, Service ללוגיקה, Data Access ל־DB ו־DTOs לחוזה מול הלקוח. אני משתמש ב־DI כדי להקטין coupling. ב־Angular אני מפריד UI לקומפוננטות ו־API calls ל־services. Docker אורז את האפליקציה ל־container, ו־Kubernetes מנהל containers בפרודקשן עם deployments, services ו־health checks. ב־Microservices חשוב להגדיר גבולות נכונים בין שירותים ולא ליצור distributed monolith. ב־SQL אני שם לב ל־indexes, joins, transactions וביצועים.