המטרה של הראיון
לפי התיאור, זה נשמע כמו ראיון חצי טכני חצי אישי. כנראה לא רק רוצים לבדוק אם אתה יודע תחביר, אלא אם אתה מתאים לצוות תשתיות, יודע לעבוד בסביבה מורכבת, מתקשר ברור, לומד מהר, ולא נבהל ממערכות גדולות.
המסר שאתה רוצה להעביר: “אני יודע לבנות קוד מסודר, להבין מערכות, ללמוד טכנולוגיות חדשות, ולעבוד בצוות בלי לשבור דברים לאחרים.”
הצגה עצמית של דקה וחצי
אני מפתח תוכנה עם ניסיון ב־.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 אצלכם?
- מה ייחשב הצלחה בתפקיד אחרי שלושה חודשים?
רשימת הכנה לערב לפני
- להסביר בעל פה מה זה Docker, Kubernetes ו־Microservices.
- להכין פרויקט אחד שאתה יכול להסביר: בעיה, פתרון, טכנולוגיות, אתגר ומה למדת.
- לרענן SQL: joins, indexes, transactions.
- לרענן async/await ו־Dependency Injection.
- להכין תשובה למה המשרה מעניינת אותך.
- להכין תשובה רגועה לגבי הנסיעות לדימונה וירושלים.
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 בלי לנהל שרתים |
| GKE | Kubernetes מנוהל ב־Google |
| Cloud SQL | DB מנוהל |
| 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 וביצועים.