Craft & Process · مهارت و فرایند پایهBeginner ~75 دقیقه مطالعه~69 min read
مهارت مصاحبه و مسیر شغلیInterview Craft & Career
از شکل واقعی یک فرایند استخدام بکاند و سیگنالی که هر راند میسنجد تا رزومهی اثرمحور و کمّیشده، راهبرد take-home و پروتکل پنجفازی کدنویسی زنده و خروج از بنبست، ساختار روایت در راند طراحی سیستم، روش STAR با نمونههای کامل برای مالکیت و تعارض و فشار و پشیمانی، روایت باورپذیر یک incident، سؤالهایی که خودت باید بپرسی، انگلیسیِ مصاحبهی فنی، مذاکرهی محترمانهی حقوق و ارزیابی کل آفر، پرچمهای قرمز، و ذهنیت رشد بعد از استخدام.From the real shape of a backend hiring process and the signal each round measures to an impact-driven, quantified resume, take-home strategy and the five-phase live-coding protocol with a recovery drill, narration structure for the system design round, STAR with fully worked answers for ownership, conflict, pressure and regret, telling a production incident convincingly, the questions you should ask, English for technical interviews, respectful compensation negotiation and whole-offer evaluation, red flags, and the senior growth mindset after you are hired.
تو میتوانی یک سیستم توزیعشده را درست طراحی کنی، JMM را بفهمی، یک query کند را با نگاه به execution plan نجات بدهی — و باز هم در مصاحبه رد شوی. نه چون کم بلدی؛ چون نیمهی دیگر ماجرا را هیچکس به تو یاد نداده است: اینکه آدمِ روبهرو در هر راند دقیقاً دنبال چه سیگنالی میگردد، چطور کارِ انجامشدهات را طوری روایت کنی که ارزشش دیده شود، چطور وقتی گیر میکنی امتیاز از دست ندهی، و چطور دربارهی پول حرف بزنی بدون اینکه رابطه خراب شود.
این فصل همان نیمه است و دقیقاً بهاندازهی فصلهای فنی جدی گرفته میشود. نه «انگیزشی» است و نه مجموعهای از ترفندهای بیریشه. مثل هر فصل دیگر با مدل ذهنی شروع میکنیم، بعد ساختار میسازیم، بعد جملههای واقعی و قابل استفاده مینویسیم، و در پایان میبینیم هرکدام در دنیای واقعی کجا میشکند.
یک نکتهی مهم پیش از شروع: هدف این فصل «فریب دادن مصاحبهگر» نیست. اگر مهارتی را نداری، هیچ جملهبندیای نجاتت نمیدهد و اگر هم بدهد، شش ماه بعد در شغلی گیر افتادهای که نمیتوانی در آن موفق شوی. هدف این است که فاصلهی بین «آنچه واقعاً بلدی» و «آنچه از تو دیده میشود» را به صفر برسانی. اکثر مهندسهای خوب این فاصله را دارند و همین فاصله است که آفر میسوزاند.
اول میبینیم چرا استخدام یک مسئلهی مهندسی است (تصمیم پرریسک با اطلاعات ناقص) و شکل واقعی یک فرایند استخدام بکاند چیست: تماس اولیه، راند فنی، تمرین کد یا take-home، راند طراحی سیستم، راند رفتاری و گفتگوی پایانی — و هر کدام واقعاً چه چیزی را میسنجند. بعد یاد میگیریم آگهی شغلی را مثل یک spec بخوانیم. بعد رزومه و پروفایل: نوشتن بر اساس اثر بهجای فهرست وظایف، کمّیکردن نتیجه، تطبیق با آگهی بدون دروغ، خطاهایی که رزومه را حذف میکنند، و راهحل وقتی کدت مالکیت شرکت است. بعد راهبرد کدنویسی زنده و take-home، شامل پروتکل خروج از بنبست و پاسخ صادقانهای که هنوز امتیاز میگیرد. بعد ساختار روایت در راند طراحی سیستم. بعد راند رفتاری با روش STAR و چند نمونهی کامل برای شایستگیهایی که آگهیها اسم میبرند: مالکیت، کار تیمی، تعارض، یادگیری، فشار، مخالفت با یک تصمیم، یک incident واقعی، و تصمیمی که از آن پشیمانی. بعد سؤالهایی که تو باید بپرسی و پاسخها چه چیزی را لو میدهند. بعد انگلیسیِ مصاحبهی فنی: واژگان و الگوهای جمله برای توضیح معماری و trade-off و حفظ خونسردی در زبان دوم. بعد حقوق: بازهها چطور تعیین میشوند، کِی و چطور عدد بگویی، مذاکرهی محترمانه و ارزیابی کل بستهی آفر. بعد پرچمهای قرمز در آگهی و در مصاحبه. و در پایان ذهنیت senior بعد از استخدام: ۹۰ روز اول، یادگیری در ملأعام، mentoring و ساختن سابقهی قابل اثبات.
۱. چرا نیمهی بدونکدِ استخدام هم مهندسی است
فرض کن باید بین دو دیتابیس یکی را برای ده سال آینده انتخاب کنی، ولی فقط اجازه داری چهار ساعت با هرکدام کار کنی و اجازهی تست بار هم نداری. چه میکنی؟ سراغ سیگنالهای غیرمستقیم میروی: مستندات، رفتار در حالتهای لبهای، اینکه وقتی چیزی خراب میشود چه پیامی میدهد، اینکه سازندگانش دربارهی محدودیتها صادقاند یا نه. استخدام دقیقاً همین است. مصاحبهگر باید دربارهی همکاری چندساله با تو تصمیم بگیرد و کل دادهاش چهار پنج ساعت گفتگو است. پس او هم به سیگنالهای غیرمستقیم تکیه میکند. کار تو این است که این سیگنالها را بشناسی و بهجای پنهان کردنشان، شفاف و صادقانه تولیدشان کنی.
سه واقعیت که کل این فصل روی آنها بنا شده است:
یک — استخدام اشتباه گران است. برای شرکت هزینهی یک استخدام بد چند ماه حقوق، وقت تیم، و آسیب به کد است. برای تو هزینهی یک شغل بد یک سال از عمر حرفهای است. پس این یک بازی برد-باخت نیست؛ هر دو طرف دنبال «تطابق»اند. این تغییر نگاه، اضطراب را هم کم میکند: تو در جایگاه متهم نیستی، در جایگاه ارزیاب متقابل هستی.
دو — مصاحبهگر ذهنخوان نیست. هر چیزی که به زبان نیاوری، وجود ندارد. اگر در ذهنت به سه راهحل فکر کردی و یکی را انتخاب کردی ولی فقط نتیجه را گفتی، نمرهی «قدرت trade-off» نمیگیری. سطح senior تقریباً همیشه از طریق «فرایند فکری بیانشده» سنجیده میشود نه از طریق جواب نهایی.
سه — همهی راندها یک چیز مشترک را میسنجند: ریسک. پشت هر سؤال، این سؤال خوابیده است: «اگر این آدم را استخدام کنیم، چه چیزی ممکن است بد پیش برود؟» آیا کد بیکیفیت تولید میکند؟ آیا وقتی گیر میکند سکوت میکند؟ آیا با review کنار میآید؟ آیا وقتی production میخوابد خونسرد میماند؟ آیا شش ماه دیگر میرود؟ هر پاسخ خوبی یکی از این ریسکها را کم میکند.
«من مسئولیتپذیرم» یک ادعاست و ارزش اطلاعاتی صفر دارد، چون هیچکس نمیگوید «من مسئولیتپذیر نیستم». «سه هفته پیش متوجه شدم job شبانهی ما بیصدا رد میشود؛ چون مالک مشخصی نداشت خودم برداشتمش، alert اضافه کردم و runbook نوشتم» یک سیگنال است. قانون ساده: هر صفتی که دربارهی خودت میگویی باید بلافاصله با یک رویداد قابل تأیید و تاریخدار پشتیبانی شود، وگرنه نگو.
۲. شکل واقعی یک فرایند استخدام بکاند
فرایندها در جزئیات فرق دارند، اما اسکلت مشترکی دارند. شناختن این اسکلت یعنی در هر لحظه بدانی «الان دارند چه چیزی را میسنجند» — و همین یک چیز، بیشتر از هر تکنیک دیگری در این فصل، نتیجه را عوض میکند.
قیف استخدام و هدف هر مرحله — the hiring funnel and what each stage filters for.
flowchart TD
A[Application / referral] --> B[Recruiter screen<br/>20-30 min]
B --> C[Hiring manager call<br/>scope and motivation]
C --> D{Coding assessment}
D -->|Take-home| E[Async exercise + debrief]
D -->|Live| F[Pair coding session]
E --> G[Technical deep dive<br/>your stack, your past work]
F --> G
G --> H[System design round]
H --> I[Behavioural / values round]
I --> J[Final conversation + offer]
J --> K[References and contract]
جدول زیر را حفظ نکن؛ بفهم. ستون «سیگنال اصلی» همان چیزی است که ارزیاب در فرم بازخوردش مینویسد.
| راند | مدت معمول | سیگنال اصلی که میسنجد | خطای رایج داوطلب |
|---|---|---|---|
| تماس recruiter | ۲۰–۳۰ دقیقه | تطابق پایه، انگیزه، بازهی حقوق، زمانبندی | معرفی نامنسجم و طولانی؛ نداشتن عدد آماده برای حقوق |
| گفتگو با hiring manager | ۳۰–۴۵ دقیقه | آیا سطح و حوزهی کارت با نیاز تیم میخورد | حرف زدن دربارهی «ما» بهجای «من»؛ ندانستن جزئیات کار خودت |
| تمرین کد (take-home یا زنده) | ۱–۴ ساعت | کیفیت کد، تست، خوانایی، مدیریت محدوده | بهینهسازی زودرس؛ نبود تست؛ نخواندن صورت مسئله |
| راند فنی عمقی | ۴۵–۶۰ دقیقه | عمق واقعی در stack خودت، صداقت دربارهی مرزها | جواب حفظی سطحی؛ بلوف زدن روی چیزی که نمیدانی |
| طراحی سیستم | ۴۵–۶۰ دقیقه | ساختار فکری، trade-off، شناخت محدودیتها | پریدن به راهحل بدون روشن کردن نیازمندی |
| رفتاری / ارزشها | ۴۵ دقیقه | همکاری، مالکیت، رفتار زیر فشار، خودآگاهی | داستان مبهم و بدون نتیجه؛ سرزنش دیگران |
| گفتگوی پایانی | ۳۰ دقیقه | جدیت، سؤالهای خوب، تطابق دوطرفه | نداشتن سؤال؛ سؤالهای فقط دربارهی مزایا |
تیمهای کوچکتر گاهی همهی اینها را در دو جلسه فشرده میکنند و برخی شرکتها بهکلی take-home ندارند. برعکس، بعضی جاها یک راند «bar raiser» یا مصاحبهی متقاطع با تیم دیگر هم دارند. اگر تعداد و ترتیب راندها را از recruiter بپرسی، کسی به تو نمرهی منفی نمیدهد — و این اطلاعات برنامهی آمادهسازیات را کاملاً عوض میکند.
در بسیاری از شرکتها خروجی مصاحبه دوتایی نیست (قبول/رد)، بلکه یک سطح است: mid، senior، staff. یک پاسخ درست ولی بدون عمق ممکن است تو را قبول کند اما یک پله پایینتر بنشاند — که یعنی حقوق کمتر و اختیار کمتر. به همین دلیل «جواب درست دادن» کافی نیست؛ باید عمق و trade-off را هم نشان بدهی. جملهی کوتاهی که سطح را بالا میبرد: «کار میکند، ولی زیر بار X میشکند؛ آنجا سراغ Y میروم چون ...».
«بله. دوست دارم بدانم بعد از این جلسه چند راند دیگر هست و هرکدام روی چه چیزی تمرکز دارد — مثلاً آیا راند طراحی سیستم دارید و آیا انتظار دارید روی دامنهی خودتان طراحی کنم یا یک مسئلهی عمومی؟ همچنین میخواهم بدانم تصمیم نهایی را چه کسی میگیرد و بازهی زمانی معمولتان چقدر است. دلیل این سؤالها ساده است: میخواهم برای هر راند درست آماده شوم و وقت تیم شما را با آمادگی ناقص هدر ندهم.» — این پاسخ سه سیگنال میدهد: احترام به وقت دیگران، برنامهریزی، و اینکه تو هم داری ارزیابی میکنی. هیچ تیم سالمی از این سؤال بدش نمیآید؛ اگر بدش آمد، خودش یک داده است.
۳. آگهی شغلی را مثل یک spec بخوان
آگهی شغلی یک سند مهندسی بد نوشتهشده است: بخشی از آن نیازمندی واقعی است، بخشی آرزو، و بخشی متن کپیشده. مهارت اول، جدا کردن این سه لایه است.
آگهی را در سه ستون بازنویسی کن:
- هسته (core): چیزهایی که در عنوان شغل، در دو بند اول شرح وظایف و در مصاحبهها تکرار میشوند. اگر آگهی میگوید «طراحی و توسعهی سرویسهای REST با Spring Boot و PostgreSQL»، هسته همین است و ۷۰٪ سؤالها از اینجا میآید.
- جانبی (adjacent): ابزارهایی که تیم استفاده میکند ولی انتظار تسلط ندارد — مثلاً «آشنایی با Kubernetes». برای اینها باید بتوانی «مدل ذهنی + یک تجربهی واقعی هرچند کوچک» ارائه کنی.
- آرزو (wish list): فهرست بلندبالای ۱۵ تکنولوژی که هیچ انسانی همه را در سطح عمیق ندارد. نبودِ چند مورد از اینها دلیل نفرستادن رزومه نیست.
اگر هسته را داری و اکثر جانبیها را میفهمی، اپلای کن — حتی اگر نصف فهرست آرزو را نداری. تیمهای باتجربه میدانند فهرست آگهی را HR بلند میکند. آنچه واقعاً رد میشود، نداشتن هسته است. برعکس، اگر هسته را نداری، اپلای کردن هزینهی روانی دارد و چیزی یاد نمیگیری؛ بهتر است سه ماه روی همان هسته کار کنی و بعد برگردی.
از هر آگهی، سه چیز استخراج کن و در یک فایل کنار رزومهات نگه دار: (۱) واژگان دقیقی که استفاده کردهاند (اگر آنها میگویند «سرویسگرا» و تو میگویی «microservice»، همزبان شدن کمک میکند — البته فقط وقتی واقعاً همان چیز را انجام دادهای)؛ (۲) دامنهی کسبوکار (پرداخت، لجستیک، سلامت...) که به تو میگوید کدام NFR برایشان حیاتی است؛ (۳) سیگنالهای مقیاس (تعداد کاربر، حجم تراکنش، تعداد مهندس) که به تو میگوید در راند طراحی روی چه چیزی تمرکز کنی.
چند الگو که تقریباً همیشه معنای بدی دارند: عنوان «مهندس full-stack DevOps DBA» برای یک نفر (یعنی تیم زیرساخت ندارد و تو قرار است همهی حفرهها را پر کنی)؛ تأکید مکرر بر «کار در محیط پرفشار و توانایی کار تحت deadline فشرده» (یعنی برنامهریزی خراب است و اضافهکاری عادی شده)؛ «مثل یک خانواده هستیم» بدون هیچ اشارهای به فرایند مهندسی؛ آگهیای که هیچ چیزی دربارهی محصول یا تیم نمیگوید و فقط فهرست تکنولوژی است؛ و آگهیای که ماههاست تکرار میشود (نرخ خروج بالا). هیچکدام بهتنهایی حکم قطعی نیست، اما هر کدام یک سؤال مشخص برای مصاحبه به تو میدهد.
۴. رزومه: از فهرست وظایف به اثر
تفاوت رزومهی متوسط و رزومهی خوب، تفاوت fix stuff با یک changelog درست است. رزومهی متوسط میگوید چه کارهایی «انجام دادی» (Responsible for developing APIs). رزومهی خوب میگوید بعد از کار تو چه چیزی در دنیا عوض شد و چقدر. خوانندهی رزومه دقیقاً مثل کسی است که دارد دنبال یک regression در تاریخچهی git میگردد: وقت ندارد همه چیز را بخواند، دنبال جملههایی است که سیگنال دارند.
۴.۱ فرمول جملهی اثرمحور
هر بند رزومه را با این اسکلت بنویس:
[فعل کنشی] + [چه چیزی] + [چطور / با چه فناوری] + [نتیجهی قابل اندازهگیری] + [چرا مهم بود]
مثال، بازنویسی سه بند واقعینما:
❌ Responsible for backend development of the ordering service.
✅ Rebuilt the order-submission path in Spring Boot, replacing
synchronous fan-out calls with an event-driven flow on Kafka;
p99 latency dropped from 2.4 s to 380 ms and checkout timeouts
fell to near zero during peak hours.
❌ Worked on database performance.
✅ Cut the nightly settlement job from 6 h to 40 min by rewriting
three N+1 access paths into set-based SQL and adding two covering
indexes, which moved the job out of the business-hours window.
❌ Used Docker and Kubernetes.
✅ Containerised eight services and moved builds to a shared CI
pipeline, reducing "works on my machine" defects and taking
average deploy time from ~50 min of manual steps to 7 min.
سه نکتهی ظریف در همین مثالها: عدد قبل و بعد («از ۲.۴ ثانیه به ۳۸۰ میلیثانیه») همیشه قویتر از عدد تنهاست؛ مکانیزم («با تبدیل fan-out همزمان به جریان رویدادمحور») نشان میدهد تو فهمیدی چرا بهتر شد نه اینکه شانسی بهتر شد؛ و پیامد کسبوکاری («خارج شدن job از ساعات کاری») نشان میدهد تو زبان مدیر را هم میفهمی.
اغراق در رزومه دقیقاً همانجایی میشکند که بیشترین هزینه را دارد: وسط راند فنی، وقتی کسی میپرسد «چطور اندازه گرفتی؟». اگر متریک دقیق نداری، سه راه صادقانه داری: بازه بده («حدود ۴ تا ۵ برابر سریعتر در محیط staging»)، مقیاس بده («سرویسی با حدود ۲۰۰ درخواست در ثانیه در ساعت اوج»)، یا اثر کیفی و قابل تأیید بده («تعداد تیکتهای پشتیبانی مربوط به این جریان بهطور محسوس کم شد؛ عدد دقیقش دست تیم پشتیبانی بود»). گفتن «نمیدانم دقیقاً چقدر، ولی اینطور اندازه میگرفتم» صد برابر بهتر از یک عدد ساختگی است.
۴.۲ چیزهایی که رزومه را حذف میکنند
- بیش از دو صفحه برای کمتر از ده سال سابقه. خواننده وقت ندارد.
- فهرست ۴۰تایی تکنولوژی بدون سطح. وقتی همه چیز در یک ردیف است، هیچ چیز برجسته نیست — و بدتر: مصاحبهگر حق دارد از هر کدام بپرسد.
- درصد تسلط با نمودار میلهای. «Java: ۹۰٪» یعنی چه؟ هیچ. حذفش کن.
- ضمیر «ما» در توضیح دستاورد. اگر مشخص نکنی سهم خودت چه بوده، ارزیاب محافظهکارانه فرض میکند سهمت کم بوده.
- شکافهای زمانی بدون توضیح. یک جمله کافی است؛ سکوت بدتر از توضیح است.
- رزومهی یکسان برای همهی آگهیها. تطبیق یعنی جابهجا کردن ترتیب و برجسته کردن مرتبطها، نه اختراع تجربه.
- فایل با فرمت عجیب. PDF با متن قابل انتخاب (نه تصویر) بفرست و اسم فایل را معنادار بگذار:
Firstname-Lastname-Backend-Engineer.pdf.
(۱) ترتیب بندها را عوض کن تا مرتبطترین تجربه اول بیاید. (۲) در بخش مهارتها فقط چیزهایی را نگه دار که در آگهی هست یا واقعاً برجستهای؛ بقیه را حذف کن. (۳) یک خط خلاصهی بالای رزومه بنویس که دقیقاً به هستهی آن آگهی اشاره کند، مثلاً: «مهندس بکاند با ۵ سال کار روی سرویسهای تراکنشی با Java و Spring Boot؛ تمرکز روی پایداری و کارایی PostgreSQL». همین سه حرکت نرخ پاسخ را بهطور محسوس بالا میبرد و هیچکدام دروغ نیست.
بسیاری از شرکتها رزومه را داخل یک ATS (سامانهی مدیریت متقاضی) نگه میدارند و روی متن آن جستجو میکنند. این یعنی: متن باید قابل استخراج باشد (PDF متنی، نه اسکن)، ساختار ساده باشد (جدولهای تودرتو و ستونبندی عجیب گاهی بد استخراج میشوند)، و اصطلاح استاندارد را کنار اختصار بیاوری («Continuous Integration (CI)»). این حرف بهمعنای پر کردن رزومه از کلیدواژه نیست؛ بهمعنای خوانا بودن برای ماشین است.
۴.۳ وقتی نمیتوانی کد را نشان بدهی
بیشتر کار جدی بکاند در مخزنهای خصوصی است و قرارداد محرمانگی هم دارد. این یک مانع واقعی است، ولی راهحل دارد: تو حق نداری کد یا دادهی کارفرما را منتشر کنی، اما حق داری دربارهی معماری، مسئله و تصمیمهایت بهصورت عمومی صحبت کنی — به شرطی که نام مشتری، اعداد محرمانه و جزئیات اختصاصی را حذف کنی.
چهار جایگزین قوی:
- نوشتار معماری بینام (sanitised design note). یک صفحه: مسئله، محدودیتها، دو راهحل بررسیشده، انتخاب و دلیلش، نتیجه. بدون اسم شرکت، بدون شماتیک دقیق داخلی. این سند در راند طراحی سیستم طلاست.
- بازسازی کوچک و عمومی. همان الگوی مسئله را با دادهی ساختگی در یک مخزن کوچک پیاده کن؛ ۳۰۰ خط کد تمیز با تست بهتر از یک پروژهی نیمهکارهی ۵۰۰۰ خطی است.
- مشارکت در پروژههای متنباز. حتی یک PR کوچکِ mergeشده، سیگنال «میتواند در کد بیگانه کار کند و review را تحمل کند» میدهد.
- نوشتن. یک یادداشت فنی دربارهی چیزی که واقعاً حل کردهای، بیشتر از ده خط رزومه اعتبار میسازد.
اگر در مصاحبه شروع کنی به گفتن اعداد دقیق درآمد کارفرمای فعلی، معماری اختصاصی، یا نام مشتریان، مصاحبهگر خوشحال نمیشود — نتیجهگیری میکند که با اطلاعات او هم همین کار را خواهی کرد. جملهی حرفهای این است: «جزئیات عددیاش محرمانه است؛ اجازه بده مقیاس تقریبی و شکل معماری را بگویم که تصمیمها را بشود فهمید.» این جمله بهجای امتیاز منفی، امتیاز مثبت میگیرد.
۴.۴ دفترچهی دستاورد (brag document)
بزرگترین دلیل رزومههای ضعیف، فراموشی است. کاری که هجده ماه پیش کردی را یادت نمیآید. راهحل، یک فایل ساده است که هر جمعه دو دقیقه بهروزش میکنی — و بعداً هم برای ارزیابی عملکرد و درخواست ارتقا استفاده میشود.
# 2026-Q3 — work log
## Shipped
- Reworked retry policy in the payment adapter (idempotency key + capped
exponential backoff). Duplicate charge tickets: 12/month -> 0 in 3 months.
- Split the monolithic `report` endpoint into a queued job + polling API.
Request timeouts on the reports page went away; p95 6.1 s -> 220 ms.
## Influence / people
- Wrote the ADR for choosing outbox-based publishing over dual writes;
adopted by two other teams.
- Onboarded a new joiner: paired 3x/week for a month, they shipped
their first production change in week 2.
## Incidents
- 2026-08-02, partial outage 34 min: connection pool exhaustion after a
slow downstream. I was on call, mitigated by lowering the pool timeout
and shedding load; wrote the postmortem and the bulkhead follow-up.
## Learned / still weak
- Learned enough about query planner statistics to fix two bad plans.
- Weak: Kubernetes networking. Reading, but would not claim it in an interview.
دقت کن ستون آخر («هنوز ضعیفم») هم هست. این ستون برای خودت است، ولی دقیقاً همان چیزی است که وقتی مصاحبهگر میپرسد «در چه چیزی میخواهی رشد کنی؟» یک جواب واقعی و مشخص به تو میدهد بهجای جواب کلیشهای.
۵. تماس اولیه: سی دقیقهای که اکثر آدمها هدر میدهند
تماس اول معمولاً با یک recruiter است، نه مهندس. او دنبال عمق فنی نیست؛ دنبال چهار چیز است: آیا کاری که کردهای با نیاز میخورد، چرا دنبال تغییری، چه زمانی آمادهای، و آیا انتظار حقوقیات در بازهی آنها هست. اگر این تماس را جدی نگیری، بهترین مهندسها هم همینجا حذف میشوند.
معرفی ۹۰ ثانیهای را از قبل بنویس و بلند بخوان تا روان شود. ساختارش:
- حال (۱۵ ثانیه): الان چه میکنی و در چه مقیاسی. «پنج سال است بکاند کار میکنم؛ الان روی سرویسهای تراکنشی با Java و Spring Boot، تیم هشتنفره، حدود ۳۰۰ درخواست بر ثانیه در اوج.»
- برجسته (۴۵ ثانیه): یک یا دو دستاورد مشخص با عدد و مکانیزم — همان بندهای رزومه که قبلاً ساختی.
- جهت (۲۰ ثانیه): چرا این نقش. «دنبال جایی هستم که مسئلهی دادهی سنگینتری داشته باشد و بتوانم در طراحی زودتر از مرحلهی کدنویسی وارد شوم.»
- پل (۱۰ ثانیه): توپ را برگردان. «کدام بخش را باز کنم؟»
حتی اگر واقعاً محیط بدی بوده، هر جملهای که مدیر یا همکار قبلی را تخریب کند، مستقیم به این استنباط تبدیل میشود: «شش ماه دیگر همین را دربارهی ما میگوید». فرمول امن، «بهسوی» است نه «از». بهجای «مدیریت افتضاح بود و هیچ فرایندی نداشتیم» بگو: «تیم در فاز رشد سریع بود و تمرکز روی تحویل سریع؛ من الان دنبال محیطی هستم که کیفیت و طراحی بلندمدت وزن بیشتری داشته باشد.» هر دو جمله یک واقعیت را میگویند، ولی یکی دربارهی تو اطلاعات مثبت میدهد.
«سه سال است روی یک دامنه کار میکنم و آن دامنه را خوب یاد گرفتهام؛ الان بیشترِ کارهای من تکرار الگوهایی است که خودم قبلاً ساختهام. دنبال جایی هستم که دو چیز داشته باشد: مسئلههای دادهای و مقیاس بزرگتر، و فرهنگی که در آن مهندس زودتر از مرحلهی نیازمندی وارد بحث طراحی میشود. آگهی شما هر دو را دارد — بهخصوص اینکه نوشتهاید مهندسها ADR مینویسند. جای فعلیام را با احترام ترک میکنم؛ کار انتقالیام را هم برنامهریزی کردهام تا تیم بیپشتیبان نماند.» — این پاسخ سه سیگنال دارد: انگیزهی مثبت بهجای فرار، تحقیق واقعی دربارهی شرکت، و مسئولیتپذیری نسبت به تیم فعلی.
۶. راند فنی عمقی: عمق را چطور نشان میدهند
این راند معمولاً دربارهی همان چیزی است که خودت در رزومه نوشتهای. مصاحبهگر باتجربه از یک سؤال ساده شروع میکند و بعد نردبان عمق را بالا میرود تا به لبهی دانش تو برسد. این کار سنگدلی نیست؛ تنها راه سنجیدن سطح است. نکتهی حیاتی این است: رسیدن به لبه، شکست نیست — چگونگی رفتار تو در لبه، همان چیزی است که نمره دارد.
نردبان عمق یک سؤال — how one question escalates to find your ceiling.
flowchart LR
Q1[What is it?<br/>definition] --> Q2[How does it work?<br/>mechanism]
Q2 --> Q3[When does it fail?<br/>limits and edge cases]
Q3 --> Q4[What would you choose instead?<br/>trade-offs]
Q4 --> Q5[Have you hit this in production?<br/>lived experience]
Q5 --> Q6[Beyond your knowledge<br/>honest boundary]
الگوی پاسخ چهارلایهای که تقریباً همیشه جواب میدهد: تعریف کوتاه → مکانیزم → حالت شکست → تجربهی خودت. مثلاً برای سؤالی دربارهی connection pool: «pool مجموعهای از اتصالهای از پیش باز شده است؛ چون هر اتصال TCP و احراز هویت هزینه دارد. مکانیزمش یعنی thread درخواستکننده اتصال میگیرد و اگر آزاد نبود تا timeout صبر میکند. جایی که میشکند این است: اگر یک downstream کند شود، اتصالها آزاد نمیشوند و صف رشد میکند تا کل سرویس بخوابد — یعنی مشکل جای دیگری است ولی علامت اینجا ظاهر میشود. من دقیقاً همین را داشتم؛ راهحلمان کاهش timeout و جدا کردن pool مسیرهای بحرانی بود.»
«بستگی دارد به …، بگذار فرضهایم را روشن کنم.» / «این کار میکند تا وقتی که …؛ بعد از آن باید سراغ … برویم.» / «من این را در production ندیدهام، پس فقط از روی مدل ذهنی حرف میزنم — اینطور تستش میکردم: …» / «راه سادهتری هم هست که ۸۰٪ فایده را میدهد و یکدهم پیچیدگی دارد؛ اول آن را انتخاب میکنم.» هر چهارتا یک چیز مشترک دارند: نشان میدهند تو مرزها و هزینهها را میبینی، نه فقط راهحل را.
مصاحبهگر معمولاً دقیقاً میداند جواب چیست. وقتی چیزی را که نمیدانی با اعتماد بهنفس میگویی، فقط یک سؤال را از دست نمیدهی — کل بقیهی جوابهایت هم بیاعتبار میشود، چون دیگر معلوم نیست کدامشان واقعی است. یک «نمیدانم» درستساخت هزینهی تقریباً صفر دارد؛ یک بلوفِ لو رفته میتواند کل مصاحبه را از بین ببرد.
۶.۱ «نمیدانم»ی که هنوز امتیاز میگیرد
فرمول سهبخشی:
مرز را صادقانه بگو → نزدیکترین چیزی که میدانی را وصل کن → بگو چطور جوابش را پیدا میکردی.
نمونه: «مکانیزم دقیق X را نمیدانم و نمیخواهم حدس بزنم. چیزی که میدانم این است که مسئلهی همخانوادهاش Y است و آنجا معمولاً trade-off بین تأخیر و سازگاری است؛ حدس اولیهام این است که اینجا هم همان است. اگر امروز به این برخورد میکردم، اول مستند رسمی همان بخش را میخواندم، بعد یک آزمایش کوچک با بار مصنوعی میساختم تا رفتار واقعی را ببینم، و قبل از تصمیم با کسی که این را در production داشته مشورت میکردم.» این پاسخ سه سیگنال قوی میدهد: صداقت، توانایی انتقال دانش بین دامنهها، و روشمندی.
«بله، دو مورد. اول Kubernetes در سطح عملیاتی: من با سرویسهای containerised کار کردهام و manifest نوشتهام، اما هیچوقت مسئولیت شبکه و اشکالزدایی cluster با من نبوده — پس نمیگویم مسلطم. دوم، تجربهی مستقیم با Cassandra ندارم؛ مدل دادهی مبتنی بر partition key را میفهمم و میدانم چرا query الگوی دسترسی را دیکته میکند، ولی در production اجرا نکردهام. چیزی که بهجایش دارم این است که سه بار در پنج سال گذشته وارد فناوریای شدهام که بلد نبودم و ظرف چند هفته به سطح تحویل رسیدهام — آخرین بارش X بود که با خواندن مستند رسمی، یک prototype کوچک و review گرفتن از یک نفر باتجربهتر شروع شد. اگر این نقش نیاز دارد که سریع Kubernetes را بالا بیاورم، مسیر یادگیریام همین است.» — این پاسخ ریسک را کم میکند: صداقت + شواهد یادگیری سریع.
۷. تمرین کد: take-home در برابر کدنویسی زنده
| معیار | take-home (تمرین خانگی) | کدنویسی زنده (live / pairing) |
|---|---|---|
| چه چیزی را خوب میسنجد | کیفیت کد، تست، ساختار، مستندسازی، مدیریت محدوده | فرایند فکری، ارتباط، رفتار در گیر افتادن |
| چه چیزی را بد میسنجد | سرعتِ فکر و همکاری؛ اصالتِ کار قابل تضمین نیست | کیفیت واقعی کد در شرایط عادی؛ آدمهای مضطرب را جریمه میکند |
| زمان معقول | ۲ تا ۴ ساعت کار واقعی، با مهلت چند روزه | ۴۵ تا ۹۰ دقیقه |
| ریسک اصلی برای تو | باز شدن بیپایان محدوده و سوختن آخر هفته | بلوکه شدن ذهنی و سکوت |
| حرکت برنده | محدوده را خودت ببند و در README توضیح بده | بلند فکر کردن و تست کردن کد خودت |
اگر تمرینی رسید که برای انجام «کامل» آن به دو روز کار نیاز است، این خودش یک سیگنال دربارهی نحوهی برخورد آن تیم با وقت آدمهاست. حرکت حرفهای: بپرس «چند ساعت کار برایش در نظر گرفتهاید؟»، همانقدر وقت بگذار، و در README دقیقاً بنویس چه چیزی را نساختی و چرا. جملهی نمونه: «Timeboxed to ~3 hours. Out of scope by choice: authentication, pagination, and container packaging — the design leaves seams for each; see Trade-offs.» ارزیاب باتجربه این را نقطهی مثبت میبیند، چون دقیقاً همان مهارتی است که در sprint واقعی لازم است.
۷.۱ چکلیست تحویل take-home
آنچه واقعاً امتیاز میآورد، الگوریتم هوشمندانه نیست؛ اینهاست:
- دقیقاً همان چیزی که خواستهاند — پیش از هر چیز، صورت مسئله را دو بار بخوان و ورودی/خروجی خواستهشده را مو به مو رعایت کن.
- اجرای یکخطی. اگر ارزیاب نتواند پروژه را در دو دقیقه بالا بیاورد، بقیهی کیفیت کد دیده نمیشود.
- تستهای معنادار — چند تست که رفتار و حالتهای لبهای را میسنجند، نه بیست تست تکراری برای getter و setter. (جزئیات ابزار در فصل تست آمده؛ اینجا فقط بحث سیگنال است.)
- مرزبندی تمیز — دامنه، ورودی/خروجی و لایهی داده جدا باشند تا خواننده معماری را از روی نام پوشهها بفهمد.
- README کوتاه و صادق.
# Order intake service — take-home
## Run
./mvnw test # unit + integration tests (Testcontainers)
./mvnw spring-boot:run
curl -X POST localhost:8080/orders -H 'Content-Type: application/json' \
-d '{"customerId":"c-1","items":[{"sku":"a-1","qty":2}]}'
## Design in one paragraph
HTTP layer is thin and only maps DTOs; all rules live in the domain package,
which has no framework imports. Persistence is behind a repository port so the
in-memory implementation used by tests and the JDBC one share a contract.
## Trade-offs I made deliberately
- Idempotency: implemented via a unique constraint on (customerId, requestId)
rather than a distributed lock. Simpler, and correct for a single database.
- No pagination on GET /orders: out of scope for the stated 3-hour budget.
- Chose plain JDBC over an ORM here because the mapping is trivial; with more
aggregates I would revisit that.
## What I would do next with more time
Error taxonomy + problem+json responses, load test the write path, and add a
retry policy with jitter around the payment adapter.
این بخش، همان چیزی است که یک تمرین «درست» را به تمرینِ یک آدم senior تبدیل میکند. کد درست را خیلیها مینویسند؛ کسی که مینویسد «این را عمداً ساده گرفتم، چون …» نشان میدهد در ذهنش یک مدل هزینه/فایده دارد. اگر جلسهی debrief هم باشد، بحث دقیقاً از همین بخش شروع میشود و تو زمین بازی را انتخاب کردهای.
امروز اکثر تیمها فرض میکنند از ابزار کمکی استفاده میکنی و بعضی صریحاً اجازه میدهند یا ممنوع میکنند؛ اول قانونشان را بپرس. خطر واقعی این نیست که کمک گرفتهای، این است که نتوانی از کدِ تحویلیات دفاع کنی. در جلسهی debrief معمول است که بپرسند «چرا اینجا این ساختار؟» یا «اگر ورودی خالی بیاید چه میشود؟». اگر کدی در مخزنت هست که خطبهخط نمیفهمی، حذفش کن یا بازنویسیاش کن. صداقت ساده است: «این بخش را با کمک ابزار نوشتم، بعد اینطور بازبینی و تستش کردم.»
۸. کدنویسی زنده: یک پروتکل، نه معجزه
کدنویسی زنده یک ارزیابی مهارت خالص نیست؛ یک شبیهسازی همکاری است. مصاحبهگر دارد تصور میکند دو ساعت با تو pair کند چه حسی دارد. پس حرف زدن جزئی از راهحل است، نه حواسپرتی از آن.
خلبانها حتی وقتی همه چیز عادی است، مدام وضعیت را بلند اعلام میکنند: ارتفاع، سرعت، قصد بعدی. نه برای اینکه خودشان یادشان بماند؛ برای اینکه هر کس دیگری در حلقه بتواند زودتر از فاجعه جلوی خطا را بگیرد. در کدنویسی زنده تو خلبانی و مصاحبهگر برج مراقبت است. اگر سکوت کنی، او نمیداند مسیر را گم کردهای یا داری فکر میکنی — و کمکی هم نمیتواند بکند.
۸.۱ پنج فاز
فاز ۱ — روشنسازی (۳ تا ۵ دقیقه). هیچوقت مستقیم کد نزن. سؤالهای استاندارد: ورودی چقدر بزرگ است؟ داده مرتب است؟ مقدار تکراری داریم؟ ورودی نامعتبر چه رفتاری باید داشته باشد — استثنا یا مقدار خنثی؟ حافظه محدود است یا سرعت مهمتر است؟ آیا این تابع از چند thread صدا زده میشود؟ بعد یک جمله جمعبندی کن: «پس مسئله این است: … . درست فهمیدم؟»
فاز ۲ — مثال و طرح (۳ تا ۵ دقیقه). یک مثال کوچک دستی بزن، بعد رویکرد را با یک جمله بگو و پیچیدگی زمانی/حافظهاش را تخمین بزن (تحلیل پیچیدگی در فصل مربوطه آمده؛ اینجا فقط باید بلند بگوییاش). اگر راه سادهی کندتر بلدی، همان را اعلام کن: «راه ساده O(n²) است؛ اول همان را مینویسم که چیز درستی داشته باشیم، بعد اگر وقت بود به O(n log n) میرسانم.» این حرکت تقریباً همیشه امتیاز مثبت دارد، چون رفتار مهندسی واقعی است.
فاز ۳ — کدنویسی با روایت. نامهای معنادار بگذار، از حالت لبهای که هنوز مدیریت نکردهای با یک TODO نام ببر، و همانطور که مینویسی بگو چرا. اگر مسیر را عوض کردی، اعلام کن: «اینطور که پیش میروم دو حلقهی تودرتو میشود؛ برمیگردم و با یک map یکبار عبور میکنم.»
فاز ۴ — تست کردنِ کدِ خودت. این فاز جایی است که اکثر داوطلبها امتیاز از دست میدهند. بعد از نوشتن، خودت با صدای بلند سه سناریو را از کد رد کن: حالت عادی، حالت خالی/صفر، و حالت مرزی (بزرگترین مقدار، تکراری، null). اگر باگ پیدا کردی و خودت درستش کردی، نمرهات بالاتر از کسی است که از اول بیباگ نوشته ولی تست نکرده — چون تیمها به آدمی که کد خودش را بیرحمانه بررسی میکند بیشتر اعتماد دارند.
فاز ۵ — بازبینی و بهبود (۲ دقیقه). بگو در کد production چه چیزی اضافه میکردی: اعتبارسنجی ورودی، log ساختاریافته، محدودیت اندازه، رفتار در برابر ورودی مخرب.
نمونهی یک راهحل «تمامشده» به سبک مصاحبه — همان چیزی که در فاز ۳ و ۵ مینویسی:
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/** Finds the first character that appears exactly once, or null if none. */
public final class FirstUnique {
private FirstUnique() { }
public static Character firstUnique(String input) {
Objects.requireNonNull(input, "input"); // fail fast, documented contract
Map<Character, Integer> counts = new HashMap<>(); // LinkedHashMap not needed: we rescan
for (int i = 0; i < input.length(); i++) {
counts.merge(input.charAt(i), 1, Integer::sum); // O(n) pass 1
}
for (int i = 0; i < input.length(); i++) { // O(n) pass 2 keeps original order
char c = input.charAt(i);
if (counts.get(c) == 1) {
return c;
}
}
return null; // edge case: no unique char
}
}
و تستهایی که در فاز ۴ بلند میخوانی — حتی اگر وقت نکردی بنویسی، گفتنشان هم امتیاز دارد:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class FirstUniqueTest {
@Test void returnsFirstNonRepeating() {
assertEquals('c', FirstUnique.firstUnique("aabbcdc"));
}
@Test void returnsNullWhenEveryCharRepeats() {
assertNull(FirstUnique.firstUnique("aabb"));
}
@Test void handlesEmptyInput() {
assertNull(FirstUnique.firstUnique(""));
}
@Test void rejectsNull() {
assertThrows(NullPointerException.class, () -> FirstUnique.firstUnique(null));
}
}
کد بالا روی char کار میکند، یعنی روی واحد UTF-16. برای متن خارج از Basic Multilingual Plane (مثل بسیاری از emoji) هر «کاراکتر» واقعی با دو char نمایش داده میشود و این پیادهسازی نتیجهی بیمعنی میدهد. حرکت درست در مصاحبه این نیست که حتماً حلش کنی؛ این است که بگویی میبینیاش: «اگر ورودی میتواند Unicode کامل باشد، باید روی code point کار کنم — input.codePoints() — وگرنه surrogate pairها را نصفه میشمارم.» همین یک جمله نشان میدهد به دادهی واقعی فکر میکنی نه به مسئلهی اسباببازی.
۸.۲ وقتی گیر میکنی: پروتکل خروج از بنبست
بنبست اتفاق میافتد و خودش نمرهی منفی ندارد؛ سکوتِ طولانی نمرهی منفی دارد. این ماشین حالت را تمرین کن تا در لحظه خودکار شود:
ماشین حالت خروج از بنبست در کدنویسی زنده — the recovery state machine when you get stuck.
stateDiagram-v2
[*] --> Coding
Coding --> Stuck: no progress ~60s
Stuck --> SayItOutLoud: name the blocker
SayItOutLoud --> Simplify: solve a smaller version
SayItOutLoud --> Example: walk a concrete example by hand
Simplify --> Coding: brute force first, optimise later
Example --> Coding: pattern spotted
SayItOutLoud --> AskHint: ask a targeted question
AskHint --> Coding
Coding --> Done: tests pass
Done --> [*]
جملههای آماده برای هر حالت: «یک لحظه بلند فکر کنم — مشکلم این است که نمیدانم چطور حالت تکراریها را بدون مرتبسازی مدیریت کنم.» / «بگذار حالت سادهتر را حل کنم: فرض کنم ورودی مرتب است.» / «مثال کوچک را دستی جلو میبرم تا الگو را ببینم.» / «سؤال هدفمند: انتظار دارید ترتیب اولیه حفظ شود یا مهم نیست؟» — سؤال هدفمند بسیار بهتر از «راهنمایی میکنید؟» است، چون نشان میدهد دقیقاً میدانی کجا گیر کردهای.
وقتی مصاحبهگر سرنخ میدهد، بدترین کار این است که وانمود کنی خودت به آن رسیدهای. بگو: «خب، این نکته را جا انداخته بودم — پس اگر از یک set برای دیدهشدهها استفاده کنم، عبور دوم لازم نیست.» پذیرفتن ورودی دیگران و ساختن روی آن، دقیقاً همان رفتاری است که در pair programming واقعی ارزش دارد و ارزیابها آن را «coachable» علامت میزنند.
۸.۳ اگر تمرین زنده SQL باشد
بسیاری از مصاحبههای بکاند یک تمرین کوتاه SQL دارند. الگوی رایج: «برای هر دسته، سه ردیف برتر را بده». روش درست، window function است — و بلند گفتن اینکه چرا نه زیرکوئری همبسته، بخشی از نمره است.
-- top 3 salaries per department, ties share a rank (DENSE_RANK)
SELECT department_id, employee_id, salary
FROM (
SELECT department_id,
employee_id,
salary,
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk <= 3
ORDER BY department_id, salary DESC;-- identical logic; Oracle has had analytic functions since 8i
SELECT department_id, employee_id, salary
FROM (
SELECT department_id,
employee_id,
salary,
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk <= 3
ORDER BY department_id, salary DESC;و وقتی میپرسند «چطور مطمئن میشوی که کند نیست؟»، جملهی درست این است که به plan اشاره کنی، نه به حدس:
EXPLAIN (ANALYZE, BUFFERS) SELECT ... ;EXPLAIN PLAN FOR SELECT ... ;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);عمق SQL و tuning در فصلهای «تسلط بر SQL» و «تنظیم کارایی RDBMS» آمده و تفاوتهای دو موتور در فصل مربوط به Oracle و PostgreSQL باز شده است. چیزی که این فصل اضافه میکند فقط این است: در مصاحبه، گفتن روش تأیید (نگاه به plan، تست با دادهی واقعیمقیاس) بهاندازهی خود query امتیاز دارد. اگر نمیدانی داده چقدر بزرگ است، بپرس — انتخاب بین window function و رویکرد دیگر به همین بستگی دارد.
۹. راند طراحی سیستم: ساختار روایت
محتوای طراحی سیستم در فصلهای «مبانی طراحی سیستم»، «نظریهی سیستمهای توزیعشده» و «نمونههای عملی طراحی» آمده است. آنچه اینجا اضافه میکنیم چیز دیگری است: مدیریت زمان و روایت. اکثر شکستها در این راند از ندانستن نیست، از بیساختاری است — داوطلب ۳۵ دقیقه دربارهی انتخاب دیتابیس حرف میزند و هیچوقت به مقیاسپذیری و حالت خرابی نمیرسد.
بودجهی زمانی یک جلسهی ۴۵ دقیقهای — the time budget of a 45-minute design round.
flowchart LR
R[Requirements<br/>5-8 min] --> E[Estimates<br/>3-5 min]
E --> A[High-level design<br/>10-12 min]
A --> D[Deep dive on 1-2 parts<br/>10-12 min]
D --> F[Failure modes and scaling<br/>5-8 min]
F --> W[Wrap up: trade-offs<br/>2-3 min]
| فاز | چه چیزی را باید بلند بگویی | اشتباه رایج |
|---|---|---|
| نیازمندی | کارکردی، غیرکارکردی، آنچه خارج از محدوده میگذاری | پریدن مستقیم به معماری |
| تخمین | ترتیب بزرگی: کاربر، QPS، اندازهی رکورد، رشد سالانه | اعداد دقیق و ساختگی |
| طراحی کلان | مسیر داده از کاربر تا ذخیرهسازی، مرزهای سرویس | کشیدن ده جعبه بدون جریان |
| عمیقشدن | یک بخش را عمیق کن: مدل داده یا مسیر نوشتن | عمق سطحی روی همهی اجزا |
| خرابی و مقیاس | چه چیزی اول میشکند، چطور میفهمی، چطور جبران میکنی | فرض اینکه همه چیز سالم است |
| جمعبندی | دو trade-offی که آگاهانه پذیرفتی | تمام شدن وقت بدون نتیجه |
«قبل از رسم چیزی، اجازه بده محدوده را ببندم و بعد ترتیب کارم را بگویم: اول نیازمندیها و آنچه بیرون میگذارم، بعد یک تخمین درشت، بعد طراحی کلان، بعد روی یکی دو بخش عمیق میشوم و آخر دربارهی حالتهای خرابی حرف میزنم. اگر جایی خواستید مسیر را عوض کنیم، بگویید.» — این سی ثانیه دو کار میکند: نشان میدهد ساختار داری، و به مصاحبهگر اجازه میدهد تو را به سمت چیزی که برایش مهم است هدایت کند، پس وقتت هدر نمیرود.
هر ادعای کیفی را به یک کمیت بچسبان: «سریع» یعنی «هدف p99 زیر ۲۰۰ میلیثانیه برای مسیر خواندن»؛ «مقیاسپذیر» یعنی «افزایش خطی تا ۵ برابر بار فعلی با اضافه کردن نمونه، چون این مسیر stateless است و گلوگاهش دیتابیس نیست». مصاحبهگرهای باتجربه دقیقاً همینجا تفاوت mid و senior را علامت میزنند.
«سیستم دریافت سفارش. با محدودیتها شروع میکنم چون تصمیمها از آنها آمد: حدود ۳۰۰ درخواست در ثانیه در اوج، الزام اینکه یک سفارش هرگز دوباره پردازش نشود، و وابستگی به یک سرویس پرداخت بیرونی که گاهی چند ثانیه کند میشد. طراحی سه تکه بود: یک لایهی HTTP نازک که فقط اعتبارسنجی میکرد، یک دامنهی بدون وابستگی به framework، و انتشار رویداد از طریق الگوی outbox بهجای نوشتن همزمان در دیتابیس و broker — چون آن حالت دوم هیچ تضمین اتمی بودن ندارد و در قطعی شبکه داده گم میشود. برای تکرارناپذیری، بهجای قفل توزیعشده از یک قید یکتایی روی (customerId, requestId) استفاده کردیم؛ سادهتر بود و برای تکدیتابیس درست. trade-offی که آگاهانه پذیرفتیم: پردازش نهایی سفارش ناهمگام شد، یعنی کاربر بلافاصله «ثبت شد» میبیند نه «تأیید شد»؛ در عوض کندی سرویس پرداخت دیگر مسیر ورودی را نمیخواباند. چیزی که اگر دوباره میساختم عوض میکردم، زودتر اضافه کردن متریک صف بود؛ اولین بار که عقبافتادگی صف داشتیم، از شکایت کاربر فهمیدیم نه از dashboard.»
۱۰. راند رفتاری: روش STAR
یک گزارش باگ خوب دقیقاً چهار چیز دارد: محیط، کاری که کردی، آنچه دیدی، آنچه انتظار داشتی. بدون اینها هیچکس نمیتواند بازتولیدش کند. پاسخ رفتاری هم همین است: بدون بستر، وظیفه، اقدام و نتیجه، شنونده نمیتواند «مهارت» را از داستان استخراج کند. STAR فقط قالب گزارش باگ برای تجربههای انسانی است.
STAR سرواژهی Situation (بستر)، Task (وظیفهی مشخصِ تو)، Action (کاری که خودت کردی) و Result (نتیجه) است؛ چارچوبی که از دههی ۱۹۷۰ در مصاحبهی رفتاری استفاده میشود و مبنای منطقیاش این است که رفتار گذشته بهترین پیشبینیکنندهی رفتار آینده است. به همین دلیل سؤالها با «یک زمانی که …» شروع میشوند، نه «اگر روزی …».
نسبت زمانی درست: بستر ۱۵٪، وظیفه ۱۰٪، اقدام ۵۰٪، نتیجه ۲۵٪. اکثر آدمها این نسبت را وارونه میکنند و پنج دقیقه بستر تعریف میکنند.
(۱) فرضی: «معمولاً در چنین شرایطی من …» — این رفتار گذشته نیست، نظر است. همیشه یک رویداد مشخص و تاریخدار بگو. (۲) جمعی: «ما تصمیم گرفتیم، ما پیاده کردیم» — ارزیاب نمیتواند سهم تو را جدا کند، پس محافظهکارانه کم فرض میکند. بگو «تیم تصمیم گرفت X؛ سهم من این بود که …». (۳) بینتیجه: داستانی که با «و بعد پروژه ادامه پیدا کرد» تمام میشود. اگر نتیجهی عددی نداری، حداقل یک تغییر قابل مشاهده بگو: «آن checklist هنوز بعد از یک سال استفاده میشود.»
پاسخهای سطح senior معمولاً STAR + Learning هستند: یک جمله در آخر که میگوید این تجربه چه چیزی را در رفتار بعدی تو عوض کرد. «از آن به بعد، هر بار که تغییری روی مسیر پرداخت میگذارم، اول متریک و alertش را میسازم و بعد کد را.» این جمله نشان میدهد تو از تجربه سیستم میسازی، نه فقط داستان.
۱۰.۱ بانک داستان: با شش داستان همهی سؤالها را پوشش بده
بهجای حفظ کردن پاسخ برای بیست سؤال، شش رویداد واقعی از دو سال اخیر انتخاب کن و هرکدام را کامل بنویس. تقریباً هر سؤال رفتاری از یکی از اینها قابل بازروایت است:
| داستان | شایستگیهایی که پوشش میدهد |
|---|---|
| یک تحویل سخت با محدودیت زمانی | فشار، اولویتبندی، مذاکرهی محدوده |
| یک incident در production | مالکیت، خونسردی، ارتباط در بحران |
| یک اختلاف فنی با همکار یا مدیر | تعارض، مخالفت محترمانه، اقناع با داده |
| ورود به فناوریای که بلد نبودی | یادگیری، ابتکار |
| کمک به رشد یک نفر دیگر | کار تیمی، mentoring، تأثیرگذاری بدون اختیار |
| تصمیمی که اشتباه بود | خودآگاهی، پاسخگویی، اصلاح مسیر |
«بستر: تیم ما یک job شبانه داشت که فایل تسویه را برای امور مالی تولید میکرد. مالک مشخصی نداشت؛ کسی که نوشته بودش تیم را ترک کرده بود. وظیفه: مسئولیت رسمی من نبود، اما دو ماه پشت سر هم امور مالی صبح دوشنبه پیام میداد که فایل نیامده و هر بار یک نفر دستی اجرایش میکرد. تصمیم گرفتم این را ببندم. اقدام: اول اندازهگیری کردم — سه هفته log جمع کردم و دیدم job در ۴۰٪ شبها بهخاطر timeout یک سرویس بالادستی شکست میخورد و چون خروجیاش را کسی نمیپایید، بیصدا رد میشد. سه کار کردم: retry با backoff و سقف مشخص اضافه کردم، یک alert روی «عدم تولید فایل تا ساعت ۶ صبح» گذاشتم که به کانال تیم میرفت، و یک runbook یکصفحهای نوشتم که آدم کشیک بدون دانش قبلی بتواند مشکل را حل کند. قبل از اجرا با مدیرم هماهنگ کردم که این کار حدود دو روز از sprint میگیرد و چرا ارزشش را دارد. نتیجه: در سه ماه بعد صفر مورد اجرای دستی داشتیم و امور مالی دیگر پیگیری نکرد. یادگیری: یاد گرفتم کارِ بیمالک همیشه هزینهی پنهان دارد؛ حالا وقتی چنین چیزی میبینم، بهجای دور زدنش، مالکیتش را رسمی میکنم — حتی اگر مالکش خودم نشوم.»
«بستر: در بازطراحی یک سرویس، پیشنهاد شد برای همگامسازی داده بین دو سرویس، هر دو مستقیماً روی یک دیتابیس مشترک بنویسند، چون سریعتر تحویل میشد. وظیفه: من فکر میکردم این تصمیم شش ماه بعد ما را زمین میزند، ولی تصمیمگیرنده هم دلیل معتبری داشت: فشار زمانی واقعی بود. اقدام: بهجای بحث در جلسه، دو کار کردم. اول جای مخالفتم را عوض کردم: نوشتم که با هدف موافقم (تحویل سریع) و اختلاف فقط سر هزینهی بلندمدت است. بعد بهجای نظر، داده آوردم: یک سند نیمصفحهای نوشتم با سه سناریوی مشخص که در آنها مالکیت مشترک schema باعث قفل شدن استقرار دو تیم میشد، و یک گزینهی میانی پیشنهاد دادم — نگه داشتن مالکیت نوشتن در یک سرویس و انتشار رویداد برای دیگری، که فقط دو روز بیشتر کار داشت. نتیجه: بخشی از پیشنهادم پذیرفته شد؛ گزینهی میانی را گرفتیم ولی با schema سادهتر از چیزی که من میخواستم. یادگیری: دو چیز. اول اینکه مخالفت وقتی مؤثر است که به هدف مشترک وصل شود نه به سلیقه. دوم اینکه اگر تصمیم برخلاف نظرم هم گرفته میشد، وظیفهی من اجرای کامل آن بود؛ در همان سند نوشتم اگر مسیر اول را برویم چه هشدارهایی باید بگذاریم تا زودتر بفهمیم اشتباه بوده. تعهد بعد از اختلاف، بخشی از حرفهای بودن است.»
«بستر: دو هفته مانده به یک الزام قانونی، مشخص شد گزارشی که باید تحویل میدادیم، سه فیلد دادهای لازم دارد که اصلاً در سیستم ذخیره نمیشد. وظیفه: من مسئول همان سرویس بودم و باید تصمیم میگرفتم چه چیزی واقعاً شدنی است. اقدام: اولین کارم این بود که بهجای قول دادن، محدوده را شفاف کنم. کار را به سه بخش شکستم: (الف) شروع ذخیرهی دادهی جدید از امروز — یک روز کار؛ (ب) بازتولید دادهی تاریخی از log — سه تا پنج روز با ریسک؛ (ج) خودکارسازی کامل گزارش — حداقل دو هفته. با ذینفع نشستم و پرسیدم کدامها واقعاً الزام قانونیاند. معلوم شد (ج) لازم نیست و گزارش دستی ماهانه قابل قبول است. پس (الف) را همان روز فرستادیم، (ب) را با یک اسکریپت یکبارمصرف و بازبینی نتیجه انجام دادیم، و برای (ج) یک راهکار موقتِ مستندشده گذاشتیم. اضافهکاری داشتیم، اما دو شب، نه دو هفته. نتیجه: مهلت را با یک روز فاصله رد کردیم و بدهی فنیاش را در sprint بعد بهصورت تیکت رسمی بستیم. یادگیری: زیر فشار، گرانترین اشتباه، کد زدن سریعتر است؛ کار مؤثر، مذاکرهی محدوده در ساعت اول است. حالا اولین سؤالم در هر بحران این است: «کدام بخش واقعاً غیرقابلمذاکره است؟»
«بستر: تیم تصمیم گرفت مسیر گزارشگیری را از دیتابیس رابطهای جدا کند و انتخاب به یک ذخیرهساز ستونمحور رسید که من هیچ تجربهای با آن نداشتم. وظیفه: من مسئول مهاجرت مسیر نوشتن شدم، با یک ماه زمان. اقدام: روشم را عمداً ساختاردار کردم چون قبلاً یاد گرفته بودم «خواندن تصادفی» وقت میسوزاند. سه روز اول فقط مستند رسمی مدل داده و محدودیتها را خواندم و یک صفحه نوشتم از «چیزهایی که این ابزار عمداً نمیدهد» — این مهمترین بخش بود، چون تصمیمهای بعدی همه از همان محدودیتها آمد. بعد یک prototype کوچک با دادهی واقعیمقیاس ساختم و اندازهگیری کردم، نه حدس. بعد سند طراحیام را به دو نفر که تجربه داشتند نشان دادم و دو اشتباه مدلسازیام همانجا گرفته شد. آخر هم یافتهها را در یک صفحه برای تیم نوشتم. نتیجه: مهاجرت با یک هفته تأخیر نسبت به برنامه انجام شد و آن یادداشت هنوز نقطهی شروع هر کسی است که وارد آن بخش میشود. یادگیری: سریعترین راه یادگیری یک فناوری، خواندن محدودیتهایش است نه قابلیتهایش؛ و نشان دادن زودهنگام کار ناقص به آدم باتجربه، هفتهها صرفهجویی میکند.»
«بستر: در یک ارزیابی، مدیرم گفت reviewهای من از نظر فنی دقیقاند ولی لحنشان باعث میشود آدمهای تازهوارد PR بزرگ نفرستند و کارشان کند شود. وظیفه: واکنش اولم دفاعی بود — فکر کردم دارم کیفیت را حفظ میکنم. اما دو نمونهی مشخص نشانم داد و حق با او بود. اقدام: سه تغییر مشخص دادم: اول، هر نظر را به سه دسته برچسب زدم — blocking، suggestion، nit — تا نویسنده بداند کدام واقعاً مانع merge است. دوم، بهجای دستور، دلیل و گزینه نوشتم: «اینجا اگر ورودی خالی باشد NPE میگیریم؛ یا Optional برگردانیم یا صریح رد کنیم — کدام با بقیهی ماژول سازگارتر است؟» سوم، برای مسائل بزرگ بهجای رشتهی طولانی کامنت، یک تماس ۱۰ دقیقهای گذاشتم. نتیجه: در ارزیابی بعدی همان همکارها گفتند review گرفتن از من دیگر ترسناک نیست، و زمان چرخهی PR در تیم محسوس کوتاهتر شد. یادگیری: کیفیت فنی و لحن رقیب هم نیستند؛ reviewای که باعث شود آدم کمتر PR بفرستد، در عمل کیفیت را پایین میآورد.»
«بستر: یک همکار مدام PRهای من را چند روز بدون review میگذاشت و کار من قفل میشد؛ من هم کمکم شروع کردم به دور زدنش و از دیگران review گرفتن، که وضع را بدتر کرد. وظیفه: باید این را حل میکردم بدون اینکه تبدیل به شکایت به مدیر شود. اقدام: یک گفتگوی خصوصی و بدون اتهام گذاشتم و با فرض حسن نیت شروع کردم: «متوجه شدم PRهای من چند روز منتظر میمانند و میخواهم بفهمم از سمت من چه چیزی این را سخت میکند.» معلوم شد PRهای من ۸۰۰ خطی بودند و او برای هرکدام نصف روز وقت لازم داشت که در برنامهاش نبود. توافق کردیم: من PRها را زیر ۴۰۰ خط و با توضیح «چه چیزی و چرا» بفرستم، و او تا ۲۴ ساعت کاری نگاه کند یا بگوید نمیرسد. نتیجه: زمان انتظار به کمتر از یک روز رسید و بعداً همین توافق را بهعنوان قاعدهی تیمی نوشتیم. یادگیری: بیشتر «مشکل با آدمها» در واقع مشکل فرایند است که لباس آدم پوشیده؛ اولین سؤالی که حالا میپرسم این است که سهم خودم در ایجاد اصطکاک چیست.»
۱۱. روایت یک incident واقعی، بهگونهای که باورپذیر باشد
سؤال «از یک قطعی که مدیریت کردی بگو» یکی از پرسیگنالترین سؤالهاست، چون همزمان دانش فنی، خونسردی، ارتباط و بلوغ فرهنگی را میسنجد. ساختار روایت باید همان ساختار واقعی یک incident باشد:
چرخهی زندگی یک incident و آنچه در هر مرحله باید بگویی — the incident lifecycle you narrate.
stateDiagram-v2
[*] --> Detect: alert or user report
Detect --> Triage: severity, blast radius
Triage --> Communicate: stakeholders informed
Communicate --> Mitigate: stop the bleeding
Mitigate --> Diagnose: find the real cause
Diagnose --> Fix: durable change
Fix --> Postmortem: blameless write-up
Postmortem --> Prevent: action items with owners
Prevent --> [*]
سه نکتهای که روایت را از «داستان» به «شواهد» تبدیل میکند: تفکیک mitigation از fix (اول خونریزی را بند میآوری — rollback، کاهش بار، بستن feature flag — بعد دنبال علت میگردی؛ کسی که این دو را قاطی میکند نشان میدهد در بحران واقعی نبوده)؛ گفتن اینکه چطور فهمیدی (alert؟ کاربر؟ اگر کاربر، خودش یک یافته است)؛ و زبان بدون سرزنش («تغییر X باعث شد» نه «فلانی خراب کرد»).
«مقصر تیم دیگری بود.» حتی اگر واقعیت داشته باشد، شنونده فقط یک چیز میشنود: این آدم وقتی سیستم میخوابد دنبال مقصر میگردد. روایت بالغ این است: «علت مستقیم در سرویس بالادستی بود، اما چیزی که ما باید بهتر میکردیم این بود که تأخیر آن سرویس نباید thread pool ما را میخورد؛ بعد از آن bulkhead و timeout گذاشتیم.» همیشه بخشی از مسئولیت را به سیستم خودت برگردان — این دقیقاً همان چیزی است که فرهنگ postmortem بدون سرزنش میسنجد.
«بستر: کشیک بودم؛ ساعت ۱۰ شب alert نرخ خطای ۵xx روی سرویس سفارش بالا رفت — حدود ۴۰٪ درخواستها خطا میدادند، ولی سرویس کاملاً پایین نبود. وظیفه: تصمیمگیرندهی اولیه من بودم: تعیین شدت، اطلاعرسانی و مهار. اقدام: اول شدت را زدم و در کانال incident نوشتم چه میبینم و چه کسی را لازم دارم؛ همان جمله را هر ۱۵ دقیقه بهروزرسانی میکردم تا مدیر محصول لازم نباشد بپرسد. از dashboard دیدم تأخیر سرویس پرداخت از ۲۰۰ میلیثانیه به بالای ۵ ثانیه رفته و connection poolها اشباع شدهاند؛ یعنی علامت پیش ما بود ولی علت جای دیگر. مهار قبل از درمان: timeout مسیر پرداخت را از ۱۰ ثانیه به ۱.۵ ثانیه آوردم و circuit breaker را فعال کردم تا درخواستها سریع رد شوند بهجای اینکه pool را نگه دارند؛ نرخ خطا ظرف چند دقیقه به زیر ۵٪ برگشت و بقیهی سایت سالم ماند. بعد با تیم پرداخت تماس گرفتم که خودشان در حال rollback یک تغییر بودند. نتیجه: مدت اثر روی کاربر حدود ۳۴ دقیقه بود. فردا postmortem بدون سرزنش نوشتم با سه اقدام دارای مالک و تاریخ: جداسازی pool مسیرهای بحرانی، alert روی اشباع pool بهجای فقط نرخ خطا، و تست بار روی سناریوی «downstream کند». یادگیری: بزرگترین درسم این بود که سیستم ما وابستگی کند را بدتر از وابستگی خراب تحمل میکرد — و اینکه ارتباط منظم در حین incident، بیشتر از سرعت رفع مشکل، اعتماد میسازد.» (جزئیات فنی این الگوها در فصلهای «تابآوری» و «رصدپذیری» آمده است.)
«من در تیمی بودهام که کشیک رسمی نداشت» یک واقعیت است، نه ضعف اخلاقی. بلافاصله نزدیکترین تجربهی واقعیات را بده: یک باگ دادهای که باعث خروجی اشتباه شد، یک استقرار که برگرداندی، یک job که خراب کار میکرد. همان ساختار (کشف، مهار، علت، پیشگیری) را روی آن سوار کن و در آخر بگو چه چیزی دربارهی کشیک میدانی و آمادهی یادگیریاش هستی. ارزیاب دنبال «قهرمان قطعی» نیست؛ دنبال کسی است که وقتی چیزی خراب میشود روش دارد.
۱۲. تصمیمی که از آن پشیمانی
این سؤال تله نیست، اما اکثر آدمها آن را خراب میکنند: یا یک پشیمانی تقلبی میگویند («زیادی کمالگرا بودم») یا یک فاجعهی بیدرس. پاسخ خوب چهار چیز دارد: تصمیم مشخص، دلیل معقولی که آن موقع داشتی (نشان میدهد بیفکر نبودی)، هزینهی واقعی، و قاعدهای که از آن ساختی.
«حدود دو سال پیش برای یک ماژول گزارشگیری، بهجای استفاده از همان دیتابیس رابطهای موجود، یک ذخیرهساز جدید اضافه کردم. استدلالم آن موقع بیپایه نبود: queryهای تجمیعی کند بودند و آن ابزار دقیقاً برای همین ساخته شده بود. کاری که نکردم این بود که هزینهی عملیاتی را حساب کنم — پشتیبانگیری، بهروزرسانی نسخه، دانش تیم، و مهمتر از همه یک منبع حقیقت دوم که باید همگام میماند. سه ماه بعد بیشتر وقت ما صرف رفع ناهمگامی داده بود تا خود گزارش. در نهایت جمعش کردیم و با چند materialized view و ایندکس درست، ۹۰٪ فایده را با یکدهم پیچیدگی گرفتیم. هزینهاش حدود شش هفته کار تیم بود. قاعدهای که از آن ساختم و هنوز استفاده میکنم: پیش از اضافه کردن هر مؤلفهی زیرساختی جدید، باید بنویسم چه کسی نگهش میدارد، چطور پشتیبانگیری و بازیابی میشود، و اگر سادهترین راهحل موجود را تا مرزش فشار بدهیم چقدر جلو میرویم. جالب اینکه همین سؤال آخر، دو بار بعد از آن جلوی اضافه کردن مؤلفهی غیرضروری را گرفت.»
۱۳. سؤالهایی که تو باید بپرسی
پایان هر راند، پنج تا ده دقیقه به سؤالهای تو میرسد. این بخش دو کارکرد دارد: هم آخرین سیگنالی است که از تو ثبت میشود، هم تنها فرصت واقعیات برای فهمیدن اینکه کار کردن آنجا چه شکلی است. سؤال خوب، سؤالی است که پاسخ کلیشهای نمیپذیرد — یعنی بهجای «آیا کیفیت کد برایتان مهم است؟» (که همه بله میگویند) بپرسی «آخرین باری که بهخاطر کیفیت، یک تحویل را عقب انداختید کِی بود؟».
| سؤال | چه چیزی را واقعاً میسنجد | نشانهی نگرانکننده در پاسخ |
|---|---|---|
| یک روز کاری معمولی یک مهندس در تیم چطور میگذرد؟ | نسبت کد به جلسه، میزان قطعشدگی تمرکز | «بستگی دارد» بدون هیچ جزئیات |
| از commit تا production چقدر طول میکشد و چند مرحله دارد؟ | بلوغ CI/CD و اختیار مهندس | «تیم دیگری استقرار میدهد، ما دسترسی نداریم» |
| آخرین incidentتان چه بود و بعدش چه تغییر کرد؟ | فرهنگ postmortem و یادگیری سازمانی | «مشکل خاصی نداریم» یا اسم بردن از یک مقصر |
| کشیک چطور کار میکند و شبها چند بار بیدار میشوید؟ | سلامت عملیاتی و احترام به زمان شخصی | ابهام یا خندهی عصبی |
| بدهی فنی چطور وارد برنامه میشود؟ | آیا کیفیت بودجه دارد یا فقط شعار است | «هر وقت وقت اضافه داشته باشیم» |
| تصمیمهای معماری چطور و توسط چه کسی گرفته میشود؟ | میزان اختیار مهندس، وجود ADR | تصمیمها از بیرون تیم دیکته میشود |
| کسی که در این نقش موفق است، شش ماه بعد چه چیزی را تحویل داده؟ | آیا انتظارات روشن است | ناتوانی در پاسخ مشخص |
| چرا این جایگاه باز شده؟ | رشد یا خروج نیرو | مکث طولانی، پاسخ مبهم |
| چه چیزی در این تیم را دوست داری تغییر بدهی؟ | صداقت مصاحبهگر | «هیچ چیز؛ همه چیز عالی است» |
«از زمانی که اینجا هستی، چه چیزی دربارهی تیم غافلگیرت کرد — خوب یا بد؟» این سؤال محترمانه است، حمله نیست، و تقریباً همیشه یک پاسخ واقعی میگیرد چون از قالب «فروختن شرکت» خارج است. اگر مصاحبهگر نتواند حتی یک چیز واقعی بگوید، یعنی یا خیلی تازهوارد است یا فضا برای صراحت وجود ندارد.
۱۴. انگلیسیِ مصاحبهی فنی
اگر مصاحبه به انگلیسی است و زبان دومت است، دو مسئلهی جدا داری: واژگان و خونسردی. واژگان با تمرین حل میشود؛ خونسردی با ساختار.
قاعدهی اول: سرعت را کم کن. انگلیسیِ کندِ روشن، بینهایت بهتر از انگلیسیِ سریعِ درهم است — و مصاحبهگر هم اصلاً دنبال روان بودن تو نیست، دنبال فهمیدن است. قاعدهی دوم: از الگوهای جملهی از پیش تمرینشده استفاده کن تا ظرفیت ذهنیات صرف محتوا شود نه گرامر.
| موقعیت | الگوی آماده |
|---|---|
| وقت خریدن | "That's a good question — let me think for a few seconds." |
| روشن کردن سؤال | "Just to make sure I understood: are you asking about X or about Y?" |
| اعلام ساختار پاسخ | "I'll answer in three parts: what it is, how it fails, and what I'd choose." |
| بیان trade-off | "The trade-off here is between A and B: we gain …, but we pay for it with …" |
| توجیه انتخاب | "I'd go with A, mainly because …; I'd revisit that if … changed." |
| ابراز عدم قطعیت | "I'm not certain about the exact mechanism, so I'd rather not guess. What I do know is …" |
| بیان محدودیت | "This holds as long as … ; beyond that point it breaks because …" |
| نفهمیدن سؤال | "Sorry, could you rephrase that? I want to make sure I answer the right question." |
| اصلاح خود | "Let me correct something I said earlier — I said X, but it's actually Y." |
| جمعبندی | "So, to summarise: the design is …, the main risk is …, and the next thing I'd measure is …" |
یک بار در ابتدا گفتن «English isn't my first language — please stop me if anything is unclear» کاملاً حرفهای است و حتی همدلی میسازد. اما تکرار «sorry, my English is bad» بعد از هر جمله، توجه شنونده را از محتوا به زبان میبرد و اعتماد به تواناییات را کم میکند — چیزی که هیچ ربطی به مهارت واقعی تو ندارد. یک بار بگو، بعد فقط توضیح بده.
یک تایمر سه دقیقهای بگذار و با صدای بلند به انگلیسی توضیح بده که آخرین چیزی که ساختی چه بود، چه محدودیتهایی داشت و چه چیزی را trade کردی. ضبطش کن و گوش بده. سه بار در هفته، شش هفته. مشکل اکثر مهندسها دانش واژگان نیست — بازیابی سریع واژه زیر استرس است، و این فقط با تولید گفتار تمرین میشود، نه با خواندن.
۱۵. حقوق: بازهها چطور ساخته میشوند و چطور دربارهشان حرف بزنی
اول مکانیزم، چون بدون آن مذاکره تبدیل به چانهزنی بازاری میشود. اکثر شرکتهای ساختاریافته سطح (level) دارند — مثلاً مهندس، مهندس ارشد، staff — و برای هر سطح یک بازه (band) با سه نقطه: کف، میانه، سقف. جای تو در بازه معمولاً از سه چیز میآید: سطحی که مصاحبهها به آن رأی دادهاند، عدالت داخلی نسبت به کسانی که همان کار را میکنند، و بودجهی آن جایگاه. یعنی مذاکرهی مؤثر اغلب مذاکره روی سطح است، نه فقط روی عدد؛ بالا بردن سطح، هم حقوق را میبرد بالا هم مسیر رشد را.
در ایالات متحده تا سال ۲۰۲۶ حدود ۱۸ ایالت بهعلاوهی واشنگتن دیسی قوانین شفافیت پرداخت دارند و بسیاری از آنها (از جمله کلرادو بهعنوان اولین، از ۲۰۲۱، و کالیفرنیا با SB 1162 از ۲۰۲۳) درج بازهی حقوق در آگهی را الزامی میکنند. در اتحادیهی اروپا هم Directive (EU) 2023/970 کشورهای عضو را موظف کرده بود تا ۷ ژوئن ۲۰۲۶ آن را به قانون ملی تبدیل کنند؛ این دستورالعمل کارفرما را ملزم میکند حقوق شروع یا بازه را پیش از مصاحبه به داوطلب بدهد و پرسیدن سابقهی حقوق قبلی را ممنوع میکند. عملاً یعنی: خواستن بازه از کارفرما نهتنها بیادبانه نیست، در بسیاری از حوزههای قضایی حق توست.
ترتیب حرکتها در گفتگوی حقوق — the order of moves in a compensation conversation.
sequenceDiagram
participant C as Candidate
participant R as Recruiter
R->>C: What are your expectations?
C->>R: Ask for the band for this level first
R->>C: Shares range (or refuses)
C->>R: Give a researched range, top-anchored
Note over C,R: Interviews happen — value is established
R->>C: Verbal offer
C->>R: Thank you - may I see the full package in writing?
C->>R: One clear, justified counter
R->>C: Revised offer or firm no
C->>R: Accept in writing, or decline gracefully
دو قاعدهی عملی. اول: تا جای ممکن، اول آنها عدد بدهند. جملهی مؤدبانه: «برای اینکه وقت هر دومان را هدر ندهیم، ممکن است بازهی تعیینشده برای این سطح را بگویید؟ من با بازهی منصفانهی بازار مشکلی ندارم و اگر بخورد، ادامه بدهیم.» دوم: اگر مجبور شدی اول بگویی، بازه بده نه یک عدد، بازه را بر اساس تحقیق واقعی بساز، و بدان که عدد پایین بازهات همان چیزی است که خواهی گرفت — پس کف بازهات باید عددی باشد که با آن راضی هستی.
«آفر شفاهی» یعنی هیچ. تا وقتی نامه یا قرارداد با جزئیات (حقوق پایه، پاداش، شرایط پرداخت، تاریخ شروع، عنوان، سطح، محل کار، دورهی آزمایشی) به دستت نرسیده، استعفا نده. و اگر چیزی که شفاهی گفته شده در متن نیست، همانجا و مؤدبانه بپرس — نه بعد از امضا. این توصیهی بدبینانه نیست؛ تجربهی مشترک آدمهایی است که یک بار سوختهاند.
حقوق پایه فقط یکی از هفت مؤلفه است: پاداش (و اینکه تضمینی است یا وابسته به عملکرد جمعی)، سهام یا اختیار خرید و برنامهی واگذاریاش، بیمه، مرخصی و سیاست کار از راه دور، بودجهی یادگیری و سختافزار، امنیت شغلی و سلامت مالی شرکت، و مهمتر از همه چیزی که در برگه نمیآید: کیفیت کاری که یاد میگیری. یک آفر با ۱۵٪ حقوق بیشتر که تو را دو سال در نگهداری یک سیستم قدیمی بدون فرایند نگه دارد، از نظر ارزش بلندمدت گرانتر است.
«قبل از عدد گفتن، دوست دارم مطمئن شوم دربارهی یک چیز حرف میزنیم: بازهی تعیینشدهی خودتان برای این سطح چقدر است؟ اگر ترجیح میدهید من شروع کنم، مشکلی نیست: بر اساس تحقیقی که برای این نقش و این سطح و این شهر کردهام، بازهی X تا Y منطقی بهنظر میرسد و انتظار من در همان محدوده است. اما صادقانه بگویم عدد تنها معیار من نیست؛ کل بسته و بهخصوص محدودهی مسئولیت برایم مهم است. اگر بعد از راندهای فنی به این نتیجه رسیدید که سطح متفاوتی مناسب است، خوشحال میشوم دربارهی هر دو با هم حرف بزنیم.» — نکته: بازه را واقعی و پژوهششده بگو، و هیچوقت حقوق فعلیات را داوطلبانه اعلام نکن؛ آن عدد سقف تو را تعیین میکند، در حالی که آنچه باید تعیینکننده باشد ارزش این نقش است.
«ممنونم — از تیم و مسئله خوشم آمده و علاقهمندم. اجازه بدهید دو روز وقت بگیرم تا کل بسته را با دقت ببینم و بعد یک بار، شفاف و کامل، اگر درخواستی داشتم بگویم. [پس از بررسی] یک درخواست دارم و بقیهی شرایط برایم روشن است: حقوق پایه را از A به B برسانیم. دلیلم این است که در راندها روی طراحی سیستم و مسئولیت کشیک بحث کردیم و اینها بخش قابلتوجهی از نقشاند، و بازهی بازار برای همین ترکیب مسئولیتها بالاتر است. اگر حقوق پایه انعطاف ندارد، من به گزینههای دیگری هم باز هستم — مثلاً بازبینی زودهنگامتر در شش ماه یا بودجهی آموزش. اگر جواب نه باشد، اشکالی ندارد و تصمیمم را روی همین آفر میگیرم.» — سه اصل: یک درخواست نه پنج تا، دلیل مبتنی بر ارزش نه نیاز شخصی، و گفتن اینکه با «نه» رابطه خراب نمیشود.
دو الگو رابطه را خراب میکنند، حتی اگر پول بیشتری بگیرند: چانهزنی تدریجی (هر بار که موافقت میکنند، درخواست جدیدی اضافه میشود) و قبول کردن و بعد پس گرفتن. اگر گفتی «اگر به B برسد قبول میکنم» و رسید، قبول کن. اعتبار حرفهای در بازار کوچک است و مدیرهای فنی همدیگر را میشناسند.
۱۶. پرچمهای قرمز در خود مصاحبه
مصاحبه یک نمونهی رفتاری از فرهنگ آن شرکت است. آنچه اینجا میبینی، در روز کاری عادی بدتر است، نه بهتر.
- بیاحترامی به وقت: تأخیر بدون عذرخواهی، جابهجایی مکرر، یا فاصلهی چندهفتهای بین راندها بدون خبر.
- مصاحبهگر نیامده آماده: رزومهات را نخوانده و میپرسد «خب، از خودت بگو» چون چیزی نمیداند.
- سؤال تلهای برای تحقیر: جایی که هدف نشان دادن برتری است، نه سنجیدن. توجه کن وقتی جواب نمیدانی، رفتارشان چطور میشود — این دقیقاً پیشنمایش review گرفتن از آنهاست.
- ابهام دربارهی نقش: هر مصاحبهگر تعریف متفاوتی از این جایگاه میدهد.
- بیجواب ماندن سؤالهای عملیاتی: نمیتوانند بگویند از commit تا production چه اتفاقی میافتد، یا تست خودکار دارند یا نه.
- فوریت مصنوعی: «تا فردا باید جواب بدهی» فشار فروش است، نه فرایند استخدام سالم.
- پرسیدن مکرر حقوق فعلی با وجود اینکه گفتهای ترجیح میدهی دربارهی ارزش نقش حرف بزنی.
- کار رایگان: تمرینی که خروجیاش دقیقاً یک قابلیت واقعی محصول آنهاست.
یک مصاحبهگر خسته در یک روز بد، دادهی ضعیفی است. اما اگر سه نفر از چهار نفر ندانند نقش دقیقاً چیست، آن دیگر تصادف نیست: یعنی سازمان خودش هم نمیداند و تو قرار است در ابهام کار کنی. قاعدهی ساده: بهجای قضاوت از روی یک لحظه، دنبال تکرار الگو در چند نقطهی مستقل بگرد — دقیقاً همان کاری که در اشکالزدایی میکنی.
۱۷. گفتگوی پایانی، آفر و خروج حرفهای
گفتگوی پایانی معمولاً با یک مدیر ارشدتر است و کمتر فنی است. سنجهاش ساده است: آیا تو میدانی چرا اینجایی، و آیا آدمی هستی که تیم دوست دارد در جلسهی سخت کنارش باشد. سه چیز آماده داشته باش: یک جمله دربارهی اینکه چه چیزی این مسئله را برای تو جالب میکند، یک سؤال جدی دربارهی جهت محصول یا تیم، و یک جمعبندی صادق از آنچه یاد گرفتهای و آنچه هنوز نمیدانی.
اگر رد شدی، یک پیام کوتاه و بدون گله بفرست و بازخورد بخواه. بخشی از شرکتها نمیدهند (سیاست حقوقی)، ولی همانها هم اسم تو را با یادداشت مثبت نگه میدارند و شش ماه بعد وقتی جایگاه مناسبتری باز شد، همین رفتار برمیگردد. اگر پذیرفتی، آفرهای دیگر را با یک پیام روشن و سریع ببند — معطل نگه داشتن دیگران هزینهی اعتباری دارد. و در شغل فعلی، دورهی اطلاع قراردادی را رعایت کن، مستندات انتقالی بنویس و در آخرین هفته هم مثل هفتهی اول کار کن. بازار کوچک است و همکار امروز، مصاحبهگر یا مرجع فردای توست.
۱۸. بعد از استخدام: مسیر رشد senior
استخدام پایان بازی نیست؛ نقطهی شروع دورهای است که در آن اعتبار میسازی یا از دست میدهی.
۳۰ روز اول — یاد بگیر و اعتماد بساز. سیستم را از مسیر داده بشناس نه از نمودار: یک درخواست واقعی را از ورودی تا دیتابیس دنبال کن. محیط توسعه را روز اول بالا بیاور و هر جا گیر کردی، سند راهاندازی را همانجا اصلاح کن — این اولین سهم مفید و کمریسک توست. یک تغییر کوچک اما واقعی را در هفتهی اول به production برسان تا کل زنجیرهی تحویل را لمس کنی. زیاد سؤال بپرس و جوابها را جایی بنویس که بقیه هم ببینند.
۶۰ روز — سهم مستقل. حالا یک کار متوسط را کامل تحویل بده. اولین باری که چیزی خراب میشود، رفتارت بیشتر از کدت دیده میشود: زود اعلام کن، کوچکش نکن، و درستش کن.
۹۰ روز و بعد — تأثیر فراتر از تیکت خودت. چیزی را که مکرر آدمها را زمین میزند پیدا کن و ببند (یک تست شکننده، یک مرحلهی دستی در استقرار، یک runbook گمشده). اینجا جایی است که «مهندس خوب» به «مهندس ارشد» تبدیل میشود.
مسیر رشد بعد از استخدام — the growth loop after you are hired.
stateDiagram-v2
[*] --> Learn: ship small, ask a lot
Learn --> Own: end-to-end delivery of a feature
Own --> Influence: ADRs, reviews, design input
Influence --> Multiply: mentoring, docs, tooling
Multiply --> Track: brag doc, promo packet
Track --> Own: bigger scope
یادگیری در ملأعام سادهتر از چیزی است که بهنظر میرسد و بیشترین بازده را دارد: بعد از هر مسئلهی سختی که حل کردی، ده خط بنویس — مسئله، چیزی که امتحان کردی و کار نکرد، چیزی که جواب داد. اگر داخلی باشد، سرمایهی تیم میشود؛ اگر عمومی باشد، سابقهی قابل استناد توست. Mentoring هم صرفاً «آموزش» نیست؛ سریعترین راه رسیدن خودت به سطح بعدی است، چون مجبورت میکند دانش ضمنیات را صریح کنی و همانجا میفهمی کجاها را واقعاً نفهمیدهای.
هیچکس با یک کار بزرگ senior نمیشود. آنچه در جلسهی ارتقا یا مصاحبهی بعدی وزن دارد، یک الگوی تکرارشونده است: چند تحویل با اثر قابل اندازهگیری، چند تصمیم مستند (ADR)، چند نفر که بهخاطر تو سریعتر رشد کردند، و چند مسئله که بعد از تو دیگر تکرار نشد. همان brag document بخش ۴.۴ دقیقاً برای همین است — بدون آن، ۸۰٪ این شواهد فراموش میشود.
«عنوان برایم هدف نیست؛ نوع مسئله هست. میخواهم جایی باشم که مسئلهها را زودتر از مرحلهی نیازمندی میبینم و مسئولیت یک حوزهی فنی را دارم — یعنی مسیر مهندسی ارشد یا staff، نه لزوماً مدیریت، هرچند مدیریت را هم رد نمیکنم اگر معلوم شود آنجا اثر بیشتری دارم. برای رسیدن به آن، دو شکاف مشخص در خودم میبینم: تجربهی عملیاتی عمیقتر در محیطهای container و توانایی راهبری تصمیمهای معماری بین چند تیم، نه فقط داخل تیم خودم. برنامهام برای دومی این است که در تصمیمهای بینتیمی داوطلب نوشتن سند شوم، چون تجربهام این بوده که نویسندهی سند، عملاً هماهنگکنندهی تصمیم هم میشود. چیزی که برایم مهم است این است که این رشد در جایی اتفاق بیفتد که کار واقعی و مسئلهی سخت داشته باشد.» — سیگنالها: خودآگاهی، برنامهی مشخص، و ربط دادن رشد شخصی به ارزش برای تیم.
۱۹. برگهی تقلب: هفتهی مصاحبه
| زمان | کار | خروجی مشخص |
|---|---|---|
| ۷ روز قبل | فرایند و راندها را از recruiter بپرس | فهرست راندها و تمرکز هرکدام |
| ۶ روز قبل | آگهی را به سه ستون هسته/جانبی/آرزو بشکن | فهرست موضوعاتی که باید مرور کنی |
| ۵ روز قبل | شش داستان STAR را بنویس (نه حفظ کن) | فایل بانک داستان |
| ۴ روز قبل | معرفی ۹۰ ثانیهای را بلند تمرین و ضبط کن | نسخهی روان زیر ۱۰۰ ثانیه |
| ۳ روز قبل | یک تمرین کد زنده با تایمر و صدای بلند | تمرین پروتکل پنجفازی |
| ۲ روز قبل | یک طراحی سیستم را با بودجهی زمانی تمرین کن | رعایت شش فاز در ۴۵ دقیقه |
| ۱ روز قبل | سؤالهای خودت را بنویس؛ بازهی حقوق را نهایی کن | ۵ سؤال + بازهی عددی |
| صبح روز مصاحبه | تست دوربین/میکروفن/اینترنت؛ مرور یکصفحهای | آب، کاغذ، محیط ساکت |
| حین جلسه | روشنسازی → بلند فکر کردن → تست → جمعبندی | یادداشت از سؤالهای خودشان |
| بعد از جلسه | یادداشت آنچه پرسیدند و آنچه لنگ زدی | بهروزرسانی فایل آمادهسازی |
| ۲۴ ساعت بعد | پیام تشکر کوتاه و مشخص | یک اشاره به نکتهی واقعی جلسه |
خواندن صد سؤال و جواب حس آمادگی میدهد ولی تقریباً بیاثر است، چون در مصاحبه باید تولید کنی نه تشخیص بدهی. قاعدهی جایگزین: هر چیزی که یاد میگیری را با صدای بلند و بدون نگاه کردن به متن، در حداکثر دو دقیقه توضیح بده. اگر نتوانستی، هنوز یاد نگرفتهای. همین یک تغییر، بیشتر از هر منبع دیگری نتیجه را عوض میکند.
استخدام یک تصمیم پرریسک با اطلاعات ناقص است؛ کار تو کم کردن ریسکِ محسوسِ استخدام کردن توست، نه بازی کردن نقش. هر راند سیگنال متفاوتی میسنجد و دانستن اینکه کدام، مهمترین مزیت توست. رزومه را بر اساس اثرِ کمّیشده و مکانیزم بنویس، نه فهرست وظایف؛ و وقتی کد محرمانه است، سند طراحی بینام و بازسازی کوچک جایش را میگیرد. در کدنویسی زنده، پروتکل پنجفازی و بلند فکر کردن و تست کردن کد خودت از هوشمندی الگوریتمی مهمتر است، و در بنبست، نام بردن از مانع بهترین حرکت است. در طراحی سیستم، ساختار و بودجهی زمانی مقدم بر دانش است. در راند رفتاری، شش داستان واقعی با ساختار STAR و یک جملهی «یادگیری» تقریباً همهی سؤالها را پوشش میدهد؛ داستان incident را با تفکیک مهار از درمان و با زبان بدون سرزنش بگو، و پشیمانیات را با دلیل معقولِ آنروز و قاعدهای که ساختی روایت کن. «نمیدانم»ی که مرز را روشن میکند و روش پیدا کردن جواب را نشان میدهد، امتیاز میگیرد؛ بلوف کل مصاحبه را میسوزاند. سؤالهای خودت را طوری بساز که پاسخ کلیشهای نپذیرند و به الگوها نگاه کن نه به یک لحظه. دربارهی حقوق، اول بازه و سطح را بفهم، بازهی پژوهششده بده، یک بار و با دلیل مذاکره کن و کل بسته را ارزیابی کن. و بعد از استخدام، همان چیزی که تو را استخدام کرد ادامه میدهد: تحویل قابل اندازهگیری، تصمیمهای مستند، کمک به رشد دیگران و یک دفترچهی دستاورد که فراموشی را شکست میدهد.
You can design a distributed system correctly, reason about the JMM, and rescue a slow query by reading its execution plan — and still get rejected. Not because you know too little, but because nobody ever taught you the other half of the job: what exactly the person across the table is looking for in each round, how to narrate work you have already done so its value is visible, how to avoid losing points when you get stuck, and how to talk about money without damaging the relationship.
This chapter is that other half, and it is treated exactly as seriously as the technical chapters. It is not motivational fluff and it is not a bag of rootless tricks. Like every other chapter, we start with a mental model, then build structure, then write real usable sentences, and then look at where each one breaks in the real world.
One thing before we start: the goal here is not to fool an interviewer. If you don't have a skill, no phrasing saves you — and if it does, six months later you are trapped in a job you cannot succeed at. The goal is to reduce the gap between what you actually know and what is visible to others to zero. Most good engineers carry that gap, and it is exactly that gap that burns offers.
First, why hiring is an engineering problem (a high-risk decision made with incomplete data) and what a real backend hiring process looks like: screening call, technical round, coding exercise or take-home, system design round, behavioural round and the final conversation — and what each one truly measures. Then reading a job posting like a spec. Then the resume and profile: writing by impact instead of task lists, quantifying results, tailoring to a posting without lying, the mistakes that get a resume discarded, and what to do when your code belongs to your employer. Then live-coding and take-home strategy, including a protocol for recovering when you are stuck and the honest answer that still scores. Then narration structure for the system design round. Then the behavioural round with the STAR method and several fully worked examples for the competencies postings name: ownership, teamwork, conflict, learning, pressure, disagreeing with a decision, a production incident, and a decision you regret. Then the questions you should ask and what the answers reveal. Then English for technical interviews: the vocabulary and sentence patterns for explaining architecture and trade-offs, and keeping composure in a second language. Then compensation: how ranges are set, when and how to say a number, respectful negotiation, and evaluating the whole offer. Then red flags in postings and in interviews. And finally the senior mindset after you are hired: the first 90 days, learning in public, mentoring, and building a provable track record.
1. Why the non-code half of hiring is engineering too
Imagine you must pick one of two databases to live with for ten years, but you are only allowed four hours of hands-on time with each and no load testing. What do you do? You fall back on indirect signals: the documentation, the behaviour at edge cases, the message it prints when something breaks, whether the authors are honest about limitations. Hiring is exactly that. The interviewer must decide about years of collaboration with you, and their entire dataset is four or five hours of conversation. So they lean on indirect signals too. Your job is to know those signals and produce them openly and honestly instead of hiding them.
Three facts this whole chapter rests on:
One — a bad hire is expensive. For the company, it costs months of salary, team time and damage to the codebase. For you, a bad job costs a year of your professional life. So this is not a win-lose game; both sides are looking for fit. That reframing also lowers anxiety: you are not the defendant, you are the other evaluator.
Two — interviewers cannot read minds. Anything you don't say out loud does not exist. If you considered three approaches in your head and picked one but only stated the result, you get no credit for "reasons about trade-offs". Seniority is almost always measured through externalised thinking, not through the final answer.
Three — every round measures the same thing: risk. Behind every question sits this question: "if we hire this person, what could go wrong?" Will they produce low-quality code? Will they go silent when stuck? Can they handle review? Will they stay calm when production is down? Will they leave in six months? Every good answer removes one of those risks.
"I'm very responsible" is a claim with zero information content, because nobody ever says the opposite. "Three weeks ago I noticed our nightly job was failing silently; it had no owner, so I took it, added an alert and wrote a runbook" is a signal. Simple rule: every adjective you apply to yourself must be immediately backed by a verifiable, dated event — otherwise don't say it.
2. What a backend hiring process actually looks like
Processes differ in the details but share a skeleton. Knowing that skeleton means knowing, at every moment, what is being measured right now — and that single thing changes outcomes more than any other technique in this chapter.
The hiring funnel and what each stage filters for — قیف استخدام و هدف هر مرحله.
flowchart TD
A[Application / referral] --> B[Recruiter screen<br/>20-30 min]
B --> C[Hiring manager call<br/>scope and motivation]
C --> D{Coding assessment}
D -->|Take-home| E[Async exercise + debrief]
D -->|Live| F[Pair coding session]
E --> G[Technical deep dive<br/>your stack, your past work]
F --> G
G --> H[System design round]
H --> I[Behavioural / values round]
I --> J[Final conversation + offer]
J --> K[References and contract]
Don't memorise the table below; understand it. The "primary signal" column is literally what the evaluator writes in their feedback form.
| Round | Typical length | Primary signal it measures | Common candidate mistake |
|---|---|---|---|
| Recruiter screen | 20–30 min | Basic fit, motivation, salary band, timing | Rambling introduction; no salary number ready |
| Hiring manager call | 30–45 min | Whether your level and scope match the team's need | Saying "we" instead of "I"; not knowing your own details |
| Coding exercise (take-home or live) | 1–4 h | Code quality, tests, readability, scope control | Premature optimisation; no tests; not reading the brief |
| Technical deep dive | 45–60 min | Real depth in your own stack, honesty about limits | Memorised surface answers; bluffing |
| System design | 45–60 min | Structure of thought, trade-offs, awareness of limits | Jumping to a solution before clarifying requirements |
| Behavioural / values | 45 min | Collaboration, ownership, behaviour under pressure, self-awareness | Vague stories with no result; blaming others |
| Final conversation | 30 min | Seriousness, good questions, mutual fit | Having no questions; asking only about perks |
Smaller teams often compress all of this into two sessions, and some companies have no take-home at all. Conversely, some add a "bar raiser" round or a cross-team interview. Asking the recruiter how many rounds there are and what each covers costs you nothing — and it completely changes how you prepare.
In many companies the outcome is not binary (pass/fail) but a level: mid, senior, staff. A correct but shallow answer can pass you one level down, which means less money and less autonomy. That is why "getting the right answer" is not enough; you must show depth and trade-offs. One short sentence that raises your level: "This works, but it breaks under X; at that point I'd move to Y because …".
"Yes. I'd like to know how many rounds come after this one and what each focuses on — for example, do you have a system design round, and would you expect me to design in your domain or a generic problem? I'd also like to know who makes the final decision and what your usual timeline is. The reason I'm asking is simple: I want to prepare properly for each round rather than waste your team's time by showing up half-prepared." — this answer sends three signals: respect for other people's time, planning, and the fact that you are evaluating too. No healthy team dislikes this question; if one does, that itself is data.
3. Read the job posting like a spec
A job posting is a badly written engineering document: part real requirement, part wish, part copy-paste. The first skill is separating those three layers.
Rewrite the posting into three columns:
- Core: what appears in the job title, in the first two bullets of the responsibilities, and repeatedly during interviews. If the posting says "design and build REST services with Spring Boot and PostgreSQL", that is the core, and 70% of the questions come from there.
- Adjacent: tools the team uses but doesn't expect mastery in — for example "familiarity with Kubernetes". For these you need "a mental model plus one real, however small, experience".
- Wish list: the 15-technology laundry list that no human holds at depth. Missing several of these is not a reason to skip applying.
If you have the core and understand most of the adjacent items, apply — even if you have half the wish list. Experienced teams know HR inflates the list. What actually gets rejected is missing the core. Conversely, if you don't have the core, applying has a psychological cost and teaches you nothing; better to spend three months on that core and come back.
Extract three things from every posting and keep them in a file next to your resume: (1) the exact vocabulary they use (if they say "service-oriented" and you say "microservices", speaking their language helps — but only when you genuinely did the same thing); (2) the business domain (payments, logistics, health…), which tells you which NFRs are critical to them; (3) scale signals (users, transaction volume, engineer count), which tell you what to focus on in the design round.
Some patterns almost always mean something bad: the title "full-stack DevOps DBA engineer" for one person (there is no platform team and you will be plugging every hole); repeated emphasis on "working in a high-pressure environment under tight deadlines" (planning is broken and overtime is normalised); "we're like a family" with no mention of any engineering process; a posting that says nothing about the product or the team and is only a technology list; and a posting that has been re-run for months (high attrition). None of these is a verdict on its own, but each hands you a specific question to ask in the interview.
4. The resume: from task list to impact
The difference between an average resume and a good one is the difference between fix stuff and a proper changelog. The average resume says what you "were responsible for" (Responsible for developing APIs). The good one says what changed in the world after your work, and by how much. A resume reader is exactly like someone hunting a regression in git history: they have no time to read everything, they are scanning for lines with signal.
4.1 The impact-bullet formula
Write every bullet on this skeleton:
[action verb] + [what] + [how / with what] + [measurable result] + [why it mattered]
Three realistic bullets, before and after:
❌ Responsible for backend development of the ordering service.
✅ Rebuilt the order-submission path in Spring Boot, replacing
synchronous fan-out calls with an event-driven flow on Kafka;
p99 latency dropped from 2.4 s to 380 ms and checkout timeouts
fell to near zero during peak hours.
❌ Worked on database performance.
✅ Cut the nightly settlement job from 6 h to 40 min by rewriting
three N+1 access paths into set-based SQL and adding two covering
indexes, which moved the job out of the business-hours window.
❌ Used Docker and Kubernetes.
✅ Containerised eight services and moved builds to a shared CI
pipeline, reducing "works on my machine" defects and taking
average deploy time from ~50 min of manual steps to 7 min.
Three subtleties are hiding in those examples: before-and-after numbers ("from 2.4 s to 380 ms") always beat a single number; the mechanism ("by replacing synchronous fan-out with an event-driven flow") proves you understand why it improved rather than that it improved by luck; and the business consequence ("moved the job out of business hours") shows you also speak the language of the person funding the work.
Resume inflation breaks in exactly the most expensive place: mid-way through the technical round, when someone asks "how did you measure that?". If you lack an exact metric you have three honest options: give a range ("roughly 4–5× faster in staging"), give the scale ("a service handling around 200 requests per second at peak"), or give a verifiable qualitative effect ("support tickets for that flow dropped noticeably; the exact count lived with the support team"). Saying "I don't know the exact figure, but here's how I measured it" is a hundred times better than a fabricated number.
4.2 What gets a resume discarded
- More than two pages for under ten years of experience. The reader has no time.
- A 40-item technology list with no proficiency levels. When everything is on one line, nothing stands out — and worse, the interviewer is entitled to ask about any of it.
- Skill percentage bars. What does "Java: 90%" mean? Nothing. Delete them.
- The pronoun "we" in achievements. If your own contribution isn't explicit, evaluators conservatively assume it was small.
- Unexplained employment gaps. One sentence is enough; silence is worse than an explanation.
- The same resume for every posting. Tailoring means reordering and highlighting, not inventing experience.
- Odd file formats. Send a PDF with selectable text (not a scan) and name the file meaningfully:
Firstname-Lastname-Backend-Engineer.pdf.
(1) Reorder bullets so the most relevant experience comes first. (2) In the skills section, keep only what the posting mentions or what you're genuinely strong in; delete the rest. (3) Write a one-line summary at the top that speaks directly to that posting's core, e.g. "Backend engineer, 5 years on transactional services in Java and Spring Boot; focused on reliability and PostgreSQL performance." Those three moves measurably raise response rates and none of them is a lie.
Many companies keep resumes in an ATS (applicant tracking system) and search across their text. That means: the text must be extractable (a text PDF, not a scan), the layout must be simple (nested tables and exotic multi-column layouts sometimes extract badly), and you should spell out standard terms alongside abbreviations ("Continuous Integration (CI)"). This is not a licence to keyword-stuff; it is about being machine-readable.
4.3 When you cannot show the code
Most serious backend work lives in private repositories under an NDA. That is a real obstacle, but it has a solution: you may not publish your employer's code or data, but you may talk publicly about the problem, the architecture and your decisions — as long as you strip client names, confidential figures and proprietary specifics.
Four strong substitutes:
- A sanitised design note. One page: the problem, the constraints, two options considered, the choice and why, the outcome. No company name, no internal schematics. This document is gold in a design round.
- A small public reconstruction. Rebuild the same problem shape with synthetic data in a small repository; 300 clean lines with tests beat a half-finished 5,000-line project.
- Open-source contributions. Even one merged small PR signals "can work inside a foreign codebase and survive review".
- Writing. One technical note about something you genuinely solved builds more credibility than ten resume lines.
If you start reciting your current employer's exact revenue figures, proprietary architecture or client names, the interviewer is not delighted; they conclude you will do the same with their information. The professional sentence is: "The exact numbers are confidential; let me give you the approximate scale and the shape of the architecture so the decisions make sense." That sentence earns points instead of losing them.
4.4 The brag document
The biggest cause of weak resumes is forgetting. You cannot remember what you did eighteen months ago. The fix is a plain file you spend two minutes on every Friday — and which later feeds your performance review and promotion case.
# 2026-Q3 — work log
## Shipped
- Reworked retry policy in the payment adapter (idempotency key + capped
exponential backoff). Duplicate charge tickets: 12/month -> 0 in 3 months.
- Split the monolithic `report` endpoint into a queued job + polling API.
Request timeouts on the reports page went away; p95 6.1 s -> 220 ms.
## Influence / people
- Wrote the ADR for choosing outbox-based publishing over dual writes;
adopted by two other teams.
- Onboarded a new joiner: paired 3x/week for a month, they shipped
their first production change in week 2.
## Incidents
- 2026-08-02, partial outage 34 min: connection pool exhaustion after a
slow downstream. I was on call, mitigated by lowering the pool timeout
and shedding load; wrote the postmortem and the bulkhead follow-up.
## Learned / still weak
- Learned enough about query planner statistics to fix two bad plans.
- Weak: Kubernetes networking. Reading, but would not claim it in an interview.
Note the last section ("still weak"). It is for you, but it is also exactly what gives you a real, specific answer when an interviewer asks "what do you want to grow in?" instead of a canned one.
5. The screening call: thirty minutes most people waste
The first call is usually with a recruiter, not an engineer. They are not looking for technical depth; they are checking four things: does what you've done match the need, why are you looking, when are you available, and is your expectation inside their band. Take this call lightly and the best engineers get filtered right here.
Write your 90-second introduction in advance and read it aloud until it flows. Structure:
- Now (15 s): what you do and at what scale. "Five years in backend; currently transactional services in Java and Spring Boot, team of eight, about 300 requests per second at peak."
- Highlight (45 s): one or two concrete achievements with a number and a mechanism — the resume bullets you already built.
- Direction (20 s): why this role. "I'm looking for a heavier data problem and a place where I get involved in design earlier than the coding stage."
- Bridge (10 s): hand the ball back. "Which part would be most useful to expand on?"
Even if the environment genuinely was bad, any sentence that attacks a former manager or colleague converts directly into: "in six months they will say this about us." The safe formula is towards, not away from. Instead of "management was a disaster and we had no process", say: "the team was in a fast growth phase and the focus was on shipping quickly; I'm now looking for an environment where quality and long-term design carry more weight." Both sentences describe the same reality, but one of them gives positive information about you.
"I've been in the same domain for three years and I've learned it well; at this point most of my work is repeating patterns I built myself. I'm looking for two things: bigger data and scale problems, and a culture where engineers join the design discussion before requirements are frozen. Your posting has both — especially the line about engineers writing ADRs. I'm leaving my current role respectfully; I've already planned the handover so the team isn't left unsupported." — three signals here: a positive motivation instead of an escape, genuine research about the company, and responsibility toward the team you're leaving.
6. The technical deep dive: how depth is actually shown
This round is usually about whatever you put on your resume. An experienced interviewer starts with a simple question and then climbs the depth ladder until they reach the edge of your knowledge. That is not cruelty; it is the only way to measure level. The critical point: reaching the edge is not failure — how you behave at the edge is what gets scored.
How one question escalates to find your ceiling — نردبان عمق یک سؤال.
flowchart LR
Q1[What is it?<br/>definition] --> Q2[How does it work?<br/>mechanism]
Q2 --> Q3[When does it fail?<br/>limits and edge cases]
Q3 --> Q4[What would you choose instead?<br/>trade-offs]
Q4 --> Q5[Have you hit this in production?<br/>lived experience]
Q5 --> Q6[Beyond your knowledge<br/>honest boundary]
A four-layer answer pattern that almost always works: short definition → mechanism → failure mode → your own experience. For a question about connection pools: "A pool is a set of pre-opened connections, because each connection costs a TCP handshake and authentication. Mechanically, a requesting thread borrows a connection and waits up to a timeout if none is free. Where it breaks: if a downstream service slows down, connections aren't returned, the queue grows and the whole service stalls — meaning the problem is elsewhere but the symptom shows up here. I hit exactly that; our fix was lowering the timeout and separating the pool for critical paths."
"It depends on … — let me state my assumptions." / "This works until …; past that point we need …" / "I haven't run this in production, so I'm reasoning from a model — here's how I'd test it: …" / "There's a simpler option that gets 80% of the benefit for a tenth of the complexity; I'd start there." All four share one property: they show you see boundaries and costs, not just solutions.
The interviewer usually knows the answer exactly. When you confidently state something you don't know, you don't just lose one question — every other answer you gave becomes suspect, because now nobody knows which ones were real. A well-built "I don't know" costs almost nothing; an exposed bluff can end the interview.
6.1 The "I don't know" that still scores
A three-part formula:
State the boundary honestly → connect to the nearest thing you do know → say how you would find the answer.
Example: "I don't know the exact mechanism of X and I'd rather not guess. What I do know is that Y is the same family of problem, and there the trade-off is usually between latency and consistency; my first guess is that it's the same here. If I hit this today, I'd read the official documentation for that component first, then build a small experiment with synthetic load to observe the real behaviour, and I'd check with someone who has run it in production before deciding." Three strong signals: honesty, transferring knowledge across domains, and method.
"Yes, two things. First, Kubernetes at an operational level: I've worked with containerised services and written manifests, but cluster networking and debugging were never my responsibility — so I won't claim mastery. Second, I have no direct production experience with Cassandra; I understand partition-key-driven modelling and why the query dictates the data model, but I haven't operated it. What I do have instead: three times in the last five years I've entered a technology I didn't know and reached delivery level within weeks — most recently X, which started with the official docs, a small prototype and getting review from someone more experienced. If this role needs me to come up to speed on Kubernetes, that's the path I'd use." — this reduces risk: honesty plus evidence of fast learning.
7. The coding exercise: take-home versus live
| Criterion | Take-home | Live / pairing session |
|---|---|---|
| Measures well | Code quality, tests, structure, documentation, scope control | Thinking process, communication, behaviour when stuck |
| Measures badly | Speed of thought and collaboration; authorship is unverifiable | Real code quality under normal conditions; penalises anxiety |
| Reasonable time | 2–4 hours of real work, with a multi-day deadline | 45–90 minutes |
| Main risk to you | Unbounded scope and a burned weekend | Freezing and going silent |
| Winning move | Close the scope yourself and explain it in the README | Think out loud and test your own code |
If an exercise would take two days to complete "fully", that itself says something about how the team treats people's time. The professional move: ask "how many hours did you intend this to take?", spend exactly that, and state in the README precisely what you did not build and why. Sample line: "Timeboxed to ~3 hours. Out of scope by choice: authentication, pagination, and container packaging — the design leaves seams for each; see Trade-offs." An experienced evaluator reads that as a positive, because it is exactly the skill a real sprint requires.
7.1 Take-home delivery checklist
What actually earns points is not a clever algorithm; it is this:
- Exactly what was asked. Read the brief twice and honour the requested inputs and outputs literally.
- One-command run. If the evaluator can't start the project in two minutes, none of your code quality is seen.
- Meaningful tests — a handful that cover behaviour and edge cases, not twenty repetitive ones for getters and setters. (Tooling detail lives in the testing chapter; here we care about the signal.)
- Clean boundaries — domain, I/O and persistence separated so the reader can infer the architecture from the folder names.
- A short, honest README.
# Order intake service — take-home
## Run
./mvnw test # unit + integration tests (Testcontainers)
./mvnw spring-boot:run
curl -X POST localhost:8080/orders -H 'Content-Type: application/json' \
-d '{"customerId":"c-1","items":[{"sku":"a-1","qty":2}]}'
## Design in one paragraph
HTTP layer is thin and only maps DTOs; all rules live in the domain package,
which has no framework imports. Persistence is behind a repository port so the
in-memory implementation used by tests and the JDBC one share a contract.
## Trade-offs I made deliberately
- Idempotency: implemented via a unique constraint on (customerId, requestId)
rather than a distributed lock. Simpler, and correct for a single database.
- No pagination on GET /orders: out of scope for the stated 3-hour budget.
- Chose plain JDBC over an ORM here because the mapping is trivial; with more
aggregates I would revisit that.
## What I would do next with more time
Error taxonomy + problem+json responses, load test the write path, and add a
retry policy with jitter around the payment adapter.
This section is what turns a "correct" exercise into a senior engineer's exercise. Plenty of people write correct code; the person who writes "I deliberately kept this simple, because …" shows they carry a cost/benefit model in their head. And if there is a debrief session, the discussion starts from that section — meaning you chose the playing field.
Most teams today assume you use assistive tooling, and some explicitly allow or forbid it; ask about their policy first. The real danger is not that you got help, it is being unable to defend the code you submitted. Debriefs routinely ask "why this structure here?" or "what happens if the input is empty?". If there is code in your repository you cannot explain line by line, delete it or rewrite it. Honesty is easy: "I drafted that part with tooling, then reviewed and tested it like this."
8. Live coding: a protocol, not a miracle
Live coding is not a pure skill assessment; it is a simulation of collaboration. The interviewer is imagining what two hours of pairing with you feels like. So talking is part of the solution, not a distraction from it.
Pilots call out their state constantly even when everything is normal: altitude, speed, next intention. Not so they remember it themselves, but so anyone else in the loop can catch an error before it becomes a disaster. In live coding you are the pilot and the interviewer is the tower. If you go silent, they cannot tell whether you're lost or thinking — and they cannot help either.
8.1 The five phases
Phase 1 — Clarify (3–5 min). Never start typing immediately. Standard questions: how large is the input? Is it sorted? Can there be duplicates? What should invalid input do — throw or return a neutral value? Is memory constrained or is speed the priority? Will this be called from multiple threads? Then summarise in one sentence: "So the problem is …. Did I get that right?"
Phase 2 — Example and plan (3–5 min). Work one small example by hand, then state the approach in a sentence and estimate its time and memory complexity (complexity analysis lives in its own chapter; here the point is saying it out loud). If you know a simpler, slower approach, announce it: "The naive version is O(n²); I'll write that first so we have something correct, then improve it to O(n log n) if we have time." This move almost always scores, because it is real engineering behaviour.
Phase 3 — Code with narration. Use meaningful names, mark any edge case you haven't handled yet with a TODO and say it out loud, and explain why as you type. If you change direction, announce it: "The way I'm going this becomes two nested loops; I'll back up and do a single pass with a map."
Phase 4 — Test your own code. This is where most candidates lose points. After writing, walk three scenarios through the code out loud: the normal case, the empty/zero case, and the boundary case (largest value, duplicates, null). If you find a bug and fix it yourself, you score higher than someone who wrote it bug-free but never checked — because teams trust the person who audits their own work ruthlessly.
Phase 5 — Review and improve (2 min). Say what you'd add for production: input validation, structured logging, size limits, behaviour against hostile input.
A "finished" interview-grade solution — what you produce in phases 3 and 5:
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/** Finds the first character that appears exactly once, or null if none. */
public final class FirstUnique {
private FirstUnique() { }
public static Character firstUnique(String input) {
Objects.requireNonNull(input, "input"); // fail fast, documented contract
Map<Character, Integer> counts = new HashMap<>(); // LinkedHashMap not needed: we rescan
for (int i = 0; i < input.length(); i++) {
counts.merge(input.charAt(i), 1, Integer::sum); // O(n) pass 1
}
for (int i = 0; i < input.length(); i++) { // O(n) pass 2 keeps original order
char c = input.charAt(i);
if (counts.get(c) == 1) {
return c;
}
}
return null; // edge case: no unique char
}
}
And the tests you read out loud in phase 4 — even naming them scores if you run out of time to write them:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class FirstUniqueTest {
@Test void returnsFirstNonRepeating() {
assertEquals('c', FirstUnique.firstUnique("aabbcdc"));
}
@Test void returnsNullWhenEveryCharRepeats() {
assertNull(FirstUnique.firstUnique("aabb"));
}
@Test void handlesEmptyInput() {
assertNull(FirstUnique.firstUnique(""));
}
@Test void rejectsNull() {
assertThrows(NullPointerException.class, () -> FirstUnique.firstUnique(null));
}
}
The code above works on char, i.e. on UTF-16 code units. For text outside the Basic Multilingual Plane (many emoji, for instance) one real character is represented by two char values and this implementation produces nonsense. The right move in an interview is not necessarily to solve it; it is to show you see it: "If the input can be full Unicode, I need to work on code points — input.codePoints() — otherwise I'm counting surrogate pairs as halves." That one sentence shows you think about real data rather than toy problems.
8.2 When you get stuck: the recovery protocol
Getting stuck happens and costs nothing by itself; long silence is what costs. Rehearse this state machine until it becomes automatic:
The recovery state machine when you get stuck — ماشین حالت خروج از بنبست در کدنویسی زنده.
stateDiagram-v2
[*] --> Coding
Coding --> Stuck: no progress ~60s
Stuck --> SayItOutLoud: name the blocker
SayItOutLoud --> Simplify: solve a smaller version
SayItOutLoud --> Example: walk a concrete example by hand
Simplify --> Coding: brute force first, optimise later
Example --> Coding: pattern spotted
SayItOutLoud --> AskHint: ask a targeted question
AskHint --> Coding
Coding --> Done: tests pass
Done --> [*]
Ready-made sentences for each state: "Let me think out loud for a second — my blocker is that I don't see how to handle duplicates without sorting." / "Let me solve the easier version first and assume the input is sorted." / "I'll walk a small example by hand to spot the pattern." / "Targeted question: do you expect the original order to be preserved, or doesn't it matter?" — a targeted question is far better than "can you give me a hint?", because it shows you know exactly where you are stuck.
When the interviewer offers a clue, the worst move is pretending you got there yourself. Say: "Right, I'd skipped that — so if I keep a set of seen values, the second pass isn't needed." Taking input from others and building on it is precisely the behaviour that matters in real pairing, and evaluators mark it as "coachable".
8.3 If the live exercise is SQL
Many backend interviews include a short SQL exercise. A common shape: "give me the top three rows per category." The right tool is a window function — and saying out loud why not a correlated subquery is part of the score.
-- top 3 salaries per department, ties share a rank (DENSE_RANK)
SELECT department_id, employee_id, salary
FROM (
SELECT department_id,
employee_id,
salary,
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk <= 3
ORDER BY department_id, salary DESC;-- identical logic; Oracle has had analytic functions since 8i
SELECT department_id, employee_id, salary
FROM (
SELECT department_id,
employee_id,
salary,
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk <= 3
ORDER BY department_id, salary DESC;And when they ask "how do you know it isn't slow?", the correct answer points at the plan, not at intuition:
EXPLAIN (ANALYZE, BUFFERS) SELECT ... ;EXPLAIN PLAN FOR SELECT ... ;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);SQL depth and tuning live in the "SQL mastery" and "RDBMS tuning" chapters, and engine differences are covered in the Oracle/PostgreSQL dialects chapter. What this chapter adds is only this: in an interview, stating how you would verify (reading the plan, testing with realistically sized data) scores as much as the query itself. If you don't know how big the data is, ask — the choice between a window function and other approaches depends on it.
9. The system design round: narration structure
Design content itself lives in the "system design fundamentals", "distributed systems theory" and "design walkthroughs" chapters. What we add here is different: time management and narration. Most failures in this round come not from lack of knowledge but from lack of structure — the candidate spends 35 minutes on the database choice and never reaches scaling or failure modes.
The time budget of a 45-minute design round — بودجهی زمانی یک جلسهی ۴۵ دقیقهای.
flowchart LR
R[Requirements<br/>5-8 min] --> E[Estimates<br/>3-5 min]
E --> A[High-level design<br/>10-12 min]
A --> D[Deep dive on 1-2 parts<br/>10-12 min]
D --> F[Failure modes and scaling<br/>5-8 min]
F --> W[Wrap up: trade-offs<br/>2-3 min]
| Phase | What you must say out loud | Common mistake |
|---|---|---|
| Requirements | Functional, non-functional, and what you put out of scope | Jumping straight to architecture |
| Estimates | Orders of magnitude: users, QPS, record size, yearly growth | Precise, invented numbers |
| High-level design | The data path from user to storage, service boundaries | Ten boxes with no flow |
| Deep dive | Go deep on one part: the data model or the write path | Uniform shallowness everywhere |
| Failure and scale | What breaks first, how you'd know, how you'd recover | Assuming everything stays healthy |
| Wrap up | Two trade-offs you consciously accepted | Time runs out with no conclusion |
"Before I draw anything, let me close the scope and then tell you my running order: requirements and what I'm excluding, a rough estimate, the high-level design, then a deep dive on one or two parts, and finally failure modes. If you want to redirect me at any point, please do." — those thirty seconds do two things: they prove you have structure, and they let the interviewer steer you toward what they care about, so you don't waste your time.
Attach a quantity to every qualitative claim: "fast" means "target p99 under 200 ms on the read path"; "scalable" means "linear to about 5× current load by adding instances, because this path is stateless and the bottleneck isn't the database". This is precisely where experienced interviewers mark the difference between mid and senior.
"An order intake system. I'll start with the constraints, because the decisions came from them: about 300 requests per second at peak, a hard requirement that an order must never be processed twice, and a dependency on an external payment provider that occasionally took seconds. The design had three parts: a thin HTTP layer that only validated, a domain with no framework dependencies, and event publishing through the outbox pattern rather than writing to the database and the broker at the same time — because that second option has no atomicity guarantee and loses data during a network partition. For idempotency, instead of a distributed lock we used a unique constraint on (customerId, requestId); simpler, and correct for a single database. The trade-off we consciously accepted: final order processing became asynchronous, so the user immediately sees 'received' rather than 'confirmed'; in exchange, a slow payment provider no longer stalls the intake path. What I'd change if I built it again: adding queue metrics earlier — the first time we had consumer lag, we learned about it from a customer complaint rather than from a dashboard."
10. The behavioural round: the STAR method
A good bug report has exactly four things: the environment, what you did, what you saw, what you expected. Without them nobody can reproduce it. A behavioural answer is the same: without situation, task, action and result, the listener cannot extract a skill from your story. STAR is simply the bug-report format applied to human experience.
STAR stands for Situation, Task (your specific responsibility), Action (what you did) and Result — a framework used in behavioural interviewing since the 1970s, whose underlying logic is that past behaviour is the best predictor of future behaviour. That is why the questions start with "tell me about a time when …", not "what would you do if …".
The right time split: situation 15%, task 10%, action 50%, result 25%. Most people invert it and spend five minutes on the situation.
(1) Hypothetical: "Usually in that situation I would …" — that's an opinion, not past behaviour. Always give one specific, dated event. (2) Collective: "we decided, we implemented" — the evaluator can't isolate your contribution, so they conservatively assume it was small. Say "the team decided X; my part was …". (3) Resultless: a story ending with "and then the project continued". If you have no numeric result, at least give a visible change: "that checklist is still in use a year later."
Senior-level answers are usually STAR + Learning: one closing sentence about what the experience changed in your later behaviour. "Since then, whenever I touch the payment path, I build the metric and the alert before I write the code." That sentence shows you turn experience into systems, not just stories.
10.1 A story bank: cover every question with six stories
Instead of memorising answers to twenty questions, pick six real events from the last two years and write each one out fully. Almost any behavioural question can be re-narrated from one of these:
| Story | Competencies it covers |
|---|---|
| A hard delivery under a time constraint | Pressure, prioritisation, scope negotiation |
| A production incident | Ownership, composure, communication in a crisis |
| A technical disagreement with a peer or manager | Conflict, respectful dissent, persuading with data |
| Entering a technology you didn't know | Learning, initiative |
| Helping someone else grow | Teamwork, mentoring, influence without authority |
| A decision that turned out wrong | Self-awareness, accountability, course correction |
"Situation: our team had a nightly job that produced a settlement file for finance. It had no owner; the person who wrote it had left. Task: it wasn't formally mine, but for two months running finance pinged us on Monday morning saying the file hadn't arrived, and each time somebody ran it by hand. I decided to close this. Action: I measured first — I collected three weeks of logs and found the job failed on about 40% of nights due to an upstream timeout, and because nobody watched its output it failed silently. I did three things: added retry with capped backoff, added an alert on 'no file produced by 6 a.m.' routed to the team channel, and wrote a one-page runbook so the on-call person could fix it with no prior knowledge. Before starting, I checked with my manager that this would take about two days of the sprint and why it was worth it. Result: zero manual runs in the following three months and finance stopped chasing us. Learning: I learned that ownerless work always carries a hidden cost; now when I see something like that I make ownership explicit instead of routing around it — even if the owner isn't me."
"Situation: during a service redesign, the proposal was that two services both write directly to a shared database to keep data in sync, because it shipped faster. Task: I believed that decision would hurt us six months later, but the decision-maker had a valid reason too: the time pressure was real. Action: instead of arguing in the meeting, I did two things. First I moved the location of my disagreement: I wrote that I agreed with the goal (ship fast) and that the difference was only about long-term cost. Then I brought data instead of opinion: a half-page note with three concrete scenarios where shared schema ownership would block two teams' deployments, plus a middle option — keeping write ownership in one service and publishing events to the other — which only cost two extra days. Result: part of my proposal was accepted; we took the middle option but with a simpler schema than I wanted. Learning: two things. First, dissent only works when it is attached to a shared goal rather than to taste. Second, if the decision had gone against me, my job was to execute it fully; in the same note I wrote which alarms we should add if we went the first way so we'd learn early that it was wrong. Committing after disagreement is part of being professional."
"Situation: two weeks before a regulatory deadline, we discovered that a report we owed required three data fields the system never stored at all. Task: I owned that service and had to decide what was genuinely feasible. Action: my first move was to make the scope explicit instead of making promises. I split the work into three parts: (a) start capturing the new data from today — one day of work; (b) reconstruct historical data from logs — three to five days with risk; (c) fully automate the report — two weeks minimum. I sat with the stakeholder and asked which parts were actually the legal requirement. It turned out (c) wasn't; a monthly manual report was acceptable. So we shipped (a) the same day, did (b) with a one-off script plus result review, and left a documented manual workaround for (c). We did work extra hours, but two evenings, not two weeks. Result: we met the deadline with a day to spare and filed the technical debt as a real ticket in the next sprint. Learning: under pressure, the most expensive mistake is coding faster; the effective work is negotiating scope in the first hour. My first question in any crunch now is: 'which part is genuinely non-negotiable?'"
"Situation: the team decided to move the reporting path off the relational database, and the choice landed on a column-oriented store I had zero experience with. Task: I owned the write-path migration, with a month to do it. Action: I deliberately structured my approach, because I'd learned before that random reading burns time. The first three days I read only the official docs on the data model and the limitations, and wrote a one-pager of 'things this tool deliberately does not give you' — that was the most valuable part, because every later decision came from those constraints. Then I built a small prototype with realistically sized data and measured rather than guessed. Then I showed my design note to two people with experience and two of my modelling mistakes were caught right there. Finally I wrote up the findings in one page for the team. Result: the migration landed a week behind plan, and that note is still the starting point for anyone entering that area. Learning: the fastest way to learn a technology is to read its limitations, not its features — and showing incomplete work early to an experienced person saves weeks."
"Situation: in a review, my manager told me my code reviews were technically accurate but their tone made newer joiners avoid sending large PRs, which slowed them down. Task: my first reaction was defensive — I thought I was protecting quality. But he showed me two specific examples and he was right. Action: I made three concrete changes. First, I labelled every comment as blocking, suggestion or nit so the author knew what actually prevented merge. Second, instead of commands I wrote the reason and options: 'if the input is empty we NPE here; either return an Optional or reject explicitly — which fits the rest of the module better?' Third, for large issues I booked a 10-minute call instead of a long comment thread. Result: at the next review the same colleagues said getting reviewed by me was no longer intimidating, and the team's PR cycle time dropped noticeably. Learning: technical rigour and tone are not competitors; a review that makes people send fewer PRs lowers quality in practice."
"Situation: a colleague repeatedly left my PRs unreviewed for days and my work stalled; I started routing around him and asking others, which made it worse. Task: I needed to fix this without escalating it into a complaint to a manager. Action: I booked a private, non-accusatory conversation and started by assuming good intent: 'I've noticed my PRs wait several days and I want to understand what makes them hard from your side.' It turned out my PRs were 800 lines each and he needed half a day per review, which wasn't in his plan. We agreed: I'd send PRs under 400 lines with a 'what and why' description, and he'd look within one working day or say he couldn't. Result: wait time dropped below a day and we later wrote the agreement up as a team norm. Learning: most 'people problems' are process problems wearing a person's clothes; the first question I now ask is what my own share in creating the friction is."
11. Narrating a real production incident convincingly
"Tell me about an outage you handled" is one of the highest-signal questions there is, because it simultaneously measures technical knowledge, composure, communication and cultural maturity. Your narration should mirror the real structure of an incident:
The incident lifecycle you narrate — چرخهی زندگی یک incident.
stateDiagram-v2
[*] --> Detect: alert or user report
Detect --> Triage: severity, blast radius
Triage --> Communicate: stakeholders informed
Communicate --> Mitigate: stop the bleeding
Mitigate --> Diagnose: find the real cause
Diagnose --> Fix: durable change
Fix --> Postmortem: blameless write-up
Postmortem --> Prevent: action items with owners
Prevent --> [*]
Three things turn the story from anecdote into evidence: separating mitigation from fix (first you stop the bleeding — rollback, shed load, kill a feature flag — and only then hunt the cause; someone who conflates the two reveals they haven't been in a real crisis); saying how you found out (an alert? a customer? if a customer, that's a finding in itself); and blameless language ("change X caused it", not "so-and-so broke it").
"It was the other team's fault." Even if true, the listener hears one thing only: this person looks for someone to blame when the system is down. The mature narration is: "The direct cause was in an upstream service, but what we should have done better is that their latency should never have consumed our thread pool; afterwards we added bulkheads and timeouts." Always route part of the responsibility back to your own system — that is exactly what a blameless postmortem culture is testing for.
"Situation: I was on call; at 10 p.m. the 5xx error-rate alert fired on the order service — about 40% of requests failing, though the service was not fully down. Task: I was the initial decision-maker: set severity, communicate, mitigate. Action: first I set the severity and posted in the incident channel what I was seeing and who I needed; I repeated that update every 15 minutes so the product manager never had to ask. From the dashboard I saw payment-provider latency had gone from 200 ms to over 5 s and our connection pools were saturated — the symptom was ours, the cause was elsewhere. Mitigation before cure: I dropped the payment path timeout from 10 s to 1.5 s and enabled the circuit breaker so requests failed fast instead of holding pool connections; the error rate fell below 5% within minutes and the rest of the site stayed healthy. Then I contacted the payments team, who were already rolling back a change. Result: customer impact lasted about 34 minutes. The next day I wrote a blameless postmortem with three action items, each with an owner and a date: pool isolation for critical paths, an alert on pool saturation rather than only error rate, and a load test for the 'slow downstream' scenario. Learning: my biggest takeaway was that our system tolerated a broken dependency far better than a slow one — and that steady communication during an incident builds more trust than raw speed of repair." (The technical patterns behind this live in the resilience and observability chapters.)
"I've worked on teams without a formal on-call rotation" is a fact, not a moral failing. Immediately offer your nearest real experience: a data bug that produced wrong output, a deployment you rolled back, a job that was silently misbehaving. Put the same structure on it (detect, mitigate, cause, prevent) and close by saying what you know about on-call and that you're ready to learn it. Evaluators aren't looking for an outage hero; they're looking for someone with a method when things break.
12. A decision you regret
This question isn't a trap, but most people ruin it: either with a fake regret ("I was too much of a perfectionist") or with a lesson-free disaster. A good answer has four parts: a specific decision, the reasonable rationale you had at the time (proving you weren't careless), the real cost, and the rule you built from it.
"About two years ago, for a reporting module, instead of using the existing relational database I introduced a new store. My reasoning wasn't baseless: the aggregate queries were slow and that tool was built for exactly this. What I failed to do was count the operational cost — backups, version upgrades, team knowledge, and above all a second source of truth that had to stay in sync. Three months later we were spending more time fixing data divergence than working on the reports themselves. In the end we rolled it back and got 90% of the benefit for a tenth of the complexity with a few materialized views and proper indexes. The cost was roughly six weeks of team time. The rule I built from it, and still use: before adding any new infrastructure component, I have to write down who maintains it, how it is backed up and restored, and how far the simplest existing option gets us if we push it to its limit. Interestingly, that last question has twice since stopped us from adding a component we didn't need."
13. The questions you should ask
Every round ends with five to ten minutes for your questions. That block does two jobs: it is the last signal recorded about you, and it is your only real chance to learn what working there is like. A good question is one that doesn't accept a canned answer — instead of "is code quality important to you?" (everyone says yes), ask "when was the last time you delayed a release for quality reasons?".
| Question | What it actually measures | Worrying answer |
|---|---|---|
| What does a normal working day look like for an engineer here? | Ratio of coding to meetings, interruption load | "It depends" with no detail |
| How long does it take from commit to production, and how many steps? | CI/CD maturity and engineer autonomy | "Another team deploys; we have no access" |
| What was your last incident and what changed afterwards? | Postmortem culture and organisational learning | "We don't really have those" or naming a culprit |
| How does on-call work and how often do people get paged at night? | Operational health and respect for personal time | Vagueness or a nervous laugh |
| How does technical debt enter the plan? | Whether quality has a budget or is just a slogan | "Whenever we have spare time" |
| How and by whom are architecture decisions made? | Engineer autonomy, existence of ADRs | Decisions dictated from outside the team |
| What has someone successful in this role delivered after six months? | Whether expectations are clear | Inability to answer concretely |
| Why is this position open? | Growth versus attrition | Long pause, vague answer |
| What would you change about this team? | The interviewer's honesty | "Nothing, everything is great" |
"Since you joined, what surprised you about the team — good or bad?" It is respectful rather than confrontational, and it almost always produces a real answer because it steps outside the "sell the company" frame. If the interviewer cannot name a single real thing, either they are very new or there is no room for candour.
14. English for technical interviews
If the interview is in English and English is your second language, you have two separate problems: vocabulary and composure. Vocabulary is solved by practice; composure is solved by structure.
Rule one: slow down. Slow clear English is infinitely better than fast tangled English — and the interviewer isn't grading your fluency anyway, they're trying to understand you. Rule two: use pre-rehearsed sentence patterns so your mental capacity goes to content instead of grammar.
| Situation | Ready-made pattern |
|---|---|
| Buying time | "That's a good question — let me think for a few seconds." |
| Clarifying the question | "Just to make sure I understood: are you asking about X or about Y?" |
| Announcing your structure | "I'll answer in three parts: what it is, how it fails, and what I'd choose." |
| Stating a trade-off | "The trade-off here is between A and B: we gain …, but we pay for it with …" |
| Justifying a choice | "I'd go with A, mainly because …; I'd revisit that if … changed." |
| Expressing uncertainty | "I'm not certain about the exact mechanism, so I'd rather not guess. What I do know is …" |
| Stating a limit | "This holds as long as … ; beyond that point it breaks because …" |
| Not understanding | "Sorry, could you rephrase that? I want to make sure I answer the right question." |
| Self-correcting | "Let me correct something I said earlier — I said X, but it's actually Y." |
| Summarising | "So, to summarise: the design is …, the main risk is …, and the next thing I'd measure is …" |
Saying once at the start, "English isn't my first language — please stop me if anything is unclear", is entirely professional and even builds rapport. But repeating "sorry, my English is bad" after every sentence moves the listener's attention from content to language and erodes confidence in your ability — which has nothing to do with your actual skill. Say it once, then just explain.
Set a three-minute timer and explain out loud, in English, what you last built, what constraints it had and what you traded away. Record it and listen back. Three times a week for six weeks. Most engineers' problem isn't vocabulary knowledge — it's fast word retrieval under stress, and that is trained only by producing speech, not by reading.
15. Compensation: how ranges are built and how to talk about them
Mechanism first, because without it negotiation degenerates into haggling. Most structured companies have levels — engineer, senior, staff — and each level has a band with three points: minimum, midpoint, maximum. Where you land in the band usually comes from three things: the level the interviews voted for, internal equity relative to people doing the same work, and the budget for that headcount. Which means effective negotiation is often negotiating the level, not just the number; raising the level raises both the pay and the growth path.
In the United States, as of 2026 roughly 18 states plus Washington, D.C. have pay transparency laws, and many of them (including Colorado, the first, from 2021, and California under SB 1162 from 2023) require a salary range in the job posting itself. In the EU, Directive (EU) 2023/970 required member states to transpose it into national law by 7 June 2026; it obliges employers to give the applicant the starting salary or range before the interview and prohibits asking about your salary history. Practically: asking the employer for the range is not rude — in many jurisdictions it is your right.
The order of moves in a compensation conversation — ترتیب حرکتها در گفتگوی حقوق.
sequenceDiagram
participant C as Candidate
participant R as Recruiter
R->>C: What are your expectations?
C->>R: Ask for the band for this level first
R->>C: Shares range (or refuses)
C->>R: Give a researched range, top-anchored
Note over C,R: Interviews happen — value is established
R->>C: Verbal offer
C->>R: Thank you - may I see the full package in writing?
C->>R: One clear, justified counter
R->>C: Revised offer or firm no
C->>R: Accept in writing, or decline gracefully
Two practical rules. First: as far as possible, let them give the number first. The polite line: "So we don't waste either of our time, could you tell me the band set for this level? I'm comfortable with a fair market range, and if it fits, let's continue." Second: if you must go first, give a range, not a point, build it from real research, and know that the bottom of your range is what you will get — so your floor must be a number you'd genuinely accept.
A "verbal offer" is nothing. Until a letter or contract with the details (base, bonus, payment terms, start date, title, level, location, probation period) is in your hands, do not resign. And if something said verbally is missing from the document, ask politely right then — not after signing. This is not cynicism; it is the shared experience of everyone who has been burned once.
Base salary is one of seven components: bonus (and whether it is guaranteed or tied to collective performance), equity or options and their vesting schedule, insurance, leave and remote-work policy, learning and hardware budget, job security and the company's financial health, and above all the thing that never appears on the sheet: the quality of the work you will learn from. An offer with 15% more base that parks you for two years maintaining a legacy system with no process is, in long-run value, the more expensive one.
"Before I give a number, I'd like to make sure we're talking about the same thing: what's the band you've set for this level? If you'd rather I go first, that's fine: based on my research for this role, this level and this city, a range of X to Y seems reasonable and my expectation sits in there. Honestly though, the number isn't my only criterion; the whole package and especially the scope of responsibility matter to me. If after the technical rounds you conclude a different level fits better, I'm happy to discuss both together." — the point: make the range real and researched, and never volunteer your current salary; that number sets your ceiling, when the thing that should set it is the value of this role.
"Thank you — I like the team and the problem and I'm interested. Let me take two days to go through the whole package carefully, and then I'll come back once, clearly and completely, if I have any request. [After review] I have one request and the rest of the terms are clear to me: raising the base from A to B. My reasoning is that we discussed system design and on-call responsibility during the rounds, and those are a significant part of the role, and the market range for that combination of responsibilities is higher. If base is not flexible, I'm open to other options — for example an earlier review at six months or a training budget. And if the answer is no, that's fine; I'll make my decision on this offer as it stands." — three principles: one request rather than five, a value-based rather than need-based rationale, and making clear that a "no" won't damage the relationship.
Two patterns damage the relationship even when they win more money: incremental haggling (every time they agree, a new request appears) and accepting then retracting. If you said "if it reaches B I'll accept" and it reached B, accept. Professional reputation travels in a small market and engineering managers know each other.
16. Red flags inside the interview itself
An interview is a behavioural sample of that company's culture. What you see here will be worse on an ordinary working day, not better.
- Disrespect for your time: lateness without apology, repeated rescheduling, or weeks of silence between rounds.
- An unprepared interviewer: hasn't read your resume and opens with "so, tell me about yourself" because they know nothing.
- Gotcha questions meant to humiliate: where the goal is showing superiority rather than measuring. Watch how they behave when you don't know something — that is a preview of being reviewed by them.
- Ambiguity about the role: every interviewer defines the position differently.
- No answers to operational questions: they can't describe what happens between commit and production, or whether automated tests exist.
- Artificial urgency: "we need your answer by tomorrow" is sales pressure, not a healthy hiring process.
- Repeatedly asking your current salary after you've said you'd rather discuss the value of the role.
- Free work: an exercise whose output is precisely a real feature of their product.
A tired interviewer on a bad day is weak data. But if three of four people cannot say what the role actually is, that is not coincidence: the organisation itself doesn't know, and you will be working in ambiguity. Simple rule: instead of judging from one moment, look for the pattern repeating across independent points — exactly what you'd do when debugging.
17. The final conversation, the offer, and leaving well
The final conversation is usually with a more senior manager and is less technical. Its measure is simple: do you know why you're here, and are you someone the team would want beside them in a hard meeting? Have three things ready: one sentence on what makes this problem interesting to you, one serious question about the direction of the product or team, and an honest summary of what you've learned and what you still don't know.
If you're rejected, send a short, ungrudging message and ask for feedback. Some companies won't give it (legal policy), but even those keep your name with a positive note, and six months later when a better-fitting role opens, that behaviour comes back to you. If you accept, close your other offers quickly and clearly — leaving people hanging has a reputational cost. And in your current job, honour the contractual notice period, write handover documentation, and work the last week like the first. The market is small, and today's colleague is tomorrow's interviewer or reference.
18. After you're hired: the path to senior
Getting hired is not the end of the game; it is the start of the period in which you build or lose credibility.
First 30 days — learn and build trust. Understand the system through the data path, not the diagram: follow one real request from ingress to database. Get the development environment running on day one, and wherever you get stuck, fix the setup document right there — that is your first useful, low-risk contribution. Ship one small but real change to production in your first week so you touch the whole delivery chain. Ask a lot of questions and write the answers somewhere others can see them.
60 days — independent contribution. Now deliver one medium piece end to end. The first time something breaks, your behaviour is more visible than your code: raise it early, don't minimise it, and fix it.
90 days and beyond — impact beyond your own tickets. Find the thing that repeatedly trips people up and close it (a flaky test, a manual deployment step, a missing runbook). This is where "good engineer" turns into "senior engineer".
The growth loop after you are hired — مسیر رشد بعد از استخدام.
stateDiagram-v2
[*] --> Learn: ship small, ask a lot
Learn --> Own: end-to-end delivery of a feature
Own --> Influence: ADRs, reviews, design input
Influence --> Multiply: mentoring, docs, tooling
Multiply --> Track: brag doc, promo packet
Track --> Own: bigger scope
Learning in public is easier than it sounds and has the highest return: after every hard problem you solve, write ten lines — the problem, what you tried that didn't work, what did. Internally it becomes team capital; publicly it becomes a citable track record. Mentoring is not merely teaching either; it is the fastest route to your own next level, because it forces you to make tacit knowledge explicit, and that is exactly where you discover what you never really understood.
Nobody becomes senior through one big thing. What carries weight in a promotion discussion or the next interview is a repeated pattern: several deliveries with measurable impact, several documented decisions (ADRs), several people who grew faster because of you, and several problems that stopped recurring after you. The brag document from section 4.4 exists precisely for this — without it, 80% of that evidence is forgotten.
"Titles aren't my goal; the type of problem is. I want to be somewhere I see problems earlier than the implementation stage and own a technical area — so the senior or staff engineering track, not necessarily management, though I wouldn't rule management out if it turned out to be where I have more impact. To get there I see two specific gaps in myself: deeper operational experience in containerised environments, and the ability to lead architecture decisions across teams rather than only inside my own. My plan for the second is to volunteer to write the document in cross-team decisions, because in my experience the person who writes the document effectively becomes the coordinator of the decision. What matters to me is that this growth happens somewhere with real work and hard problems." — signals: self-awareness, a concrete plan, and tying personal growth to value for the team.
19. Cheat sheet: interview week
| When | Do | Concrete output |
|---|---|---|
| 7 days before | Ask the recruiter about the process and rounds | List of rounds and each one's focus |
| 6 days before | Split the posting into core / adjacent / wish list | List of topics to revise |
| 5 days before | Write (don't memorise) your six STAR stories | Story bank file |
| 4 days before | Practise and record the 90-second introduction | A fluent version under 100 seconds |
| 3 days before | One timed live-coding exercise, out loud | Rehearsal of the five-phase protocol |
| 2 days before | Practise one system design with the time budget | Six phases inside 45 minutes |
| 1 day before | Write your questions; finalise your salary range | 5 questions + a numeric range |
| Interview morning | Test camera/mic/network; review your one-pager | Water, paper, a quiet room |
| During the session | Clarify → think aloud → test → summarise | Notes on the questions they asked |
| After the session | Note what they asked and where you stumbled | Update your preparation file |
| Within 24 hours | Short, specific thank-you message | One reference to a real point from the session |
Reading a hundred questions and answers feels like preparation but is nearly useless, because in an interview you must produce, not recognise. The replacement rule: everything you learn, explain out loud in at most two minutes without looking at the text. If you can't, you haven't learned it yet. That single change moves the outcome more than any other resource.
Hiring is a high-risk decision made with incomplete data; your job is to reduce the perceived risk of hiring you, not to play a character. Each round measures a different signal, and knowing which one is your biggest advantage. Write your resume from quantified impact and mechanism rather than task lists; when the code is confidential, a sanitised design note and a small reconstruction take its place. In live coding, the five-phase protocol, thinking aloud and testing your own code matter more than algorithmic brilliance, and when stuck, naming the blocker is the best move. In system design, structure and a time budget come before knowledge. In the behavioural round, six real stories in STAR form plus one "learning" sentence cover almost every question; tell the incident story by separating mitigation from cure in blameless language, and narrate your regret with the reasonable rationale you had at the time and the rule you built afterwards. An "I don't know" that marks the boundary and shows your method for finding the answer scores; a bluff burns the whole interview. Build your own questions so they can't be answered with a cliché, and judge patterns rather than moments. On compensation, understand the band and the level first, give a researched range, negotiate once with a reason, and evaluate the whole package. And after you're hired, the same things that got you the job keep working: measurable delivery, documented decisions, helping others grow, and a brag document that defeats forgetting.