پوشش تفصیلی حوزههای آزمون
این مخزن تستهای تمرینی دقیقاً برای شبیهسازی توزیعهای فنی دنیای واقعی در مصاحبههای سطح سازمانی کاتلین و اندروید ساختار یافته است.
مبانی کاتلین (۲۰٪): Null Safety پیشرفته، مکانیسمهای Smart Cast، توابع Extension، ساختار داخلی Data Classes و Enum Classes سفارشی.
همروندی و کوروتینها (۱۸٪): Coroutine scopes، الگوهای async/await، همروندی ساختاریافته، جریانهای سرد ناهمگام با Flow و یکپارچگی LiveData.
برنامهنویسی تابعی (۱۵٪): توابع مرتبه بالا، عبارات لامبدا بهینه شده، توابع inline، ساختارهای داده تغییرناپذیر و اصول برنامهنویسی تابعی.
برنامهنویسی شیگرا (۱۲٪): کلاسهای سفارشی، اعلانهای Object، اشیاء companion، ارثبری ساختاری، چندریختی (Polymorphism) و استراتژیهای انتزاع.
اکوسیستم و فریمورکهای کاتلین (۱۰٪): سیستمهای بکاند با Ktor، Spring Boot سازمانی با کاتلین، معماریهای Android Jetpack و سریالسازی از طریق Kotlinx.
حل مسئله و چالشهای کدنویسی (۱۰٪): مسائل الگوریتمی، ساختارهای داده اصلی، دیباگ زمان اجرا و بهینهسازی کد با تمرکز بر حافظه.
الگوهای طراحی و معماری (۵٪): الگوهای معماری پاک شامل MVC، MVVM، الگوهای Repository مجزا و تزریق وابستگی مدرن (Hilt/Koin).
بهترین تجربیات و کیفیت کد (۱۰٪): پروتکلهای جامع بررسی کد (Code Review)، شناسایی Code Smells، بازسازی پیشدستانه (Refactoring) و متدولوژیهای Unit Testing.
درباره دوره
موفق شدن در یک مصاحبه پیشرفته کاتلین مستلزم چیزی فراتر از دانستن نحوه جلوگیری از NullPointerException است. تیمهای مهندسی مدرن به دنبال توسعهدهندگانی هستند که درک عمیقی از انتشار کانتکست کوروتین، شبکههای جریان ناهمگام، بهینهسازی برنامهنویسی تابعی و الگوهای طراحی معماری پاک در هر دو سیستم موبایل و بکاند داشته باشند. من این بانک سوالات گسترده را طراحی کردم تا شکاف بین سینتکس پایه و سناریوهای پیچیدهای که مصاحبهکنندگان ارشد شما را با آن به چالش میکشند، پر کنم.
با ۵۵۰ سوال اصلی و بسیار دقیق، این دوره بسیار فراتر از سناریوهای استاندارد کتابهای درسی میرود. من قطعات کد در سطح تولید (Production-grade)، گلوگاههای همروندی، معماهای نشت حافظه و سبک-سنگین کردنهای عملکردی را کالبدشکافی میکنم. هر سوال با یک تحلیل فنی جامع پشتیبانی میشود که دقیقاً توضیح میدهد چرا گزینه صحیح درست است و چرا گزینههای جایگزین در شرایط فشار شکست میخورند. چه هدف شما جایگاه توسعهدهنده اندروید در یک شرکت در حال رشد باشد، چه آماده شدن برای بکاند ابری مبتنی بر کاتلین یا تسلط بر الگوهای طراحی سیستم قبل از یک ارزیابی کدنویسی زنده، این منبع تمرین استراتژیک لازم برای گذراندن مراحل فنی در اولین تلاش را فراهم میکند.
نمونهای از سوالات تمرینی
برای درک عمق و سبک توضیحات ارائه شده در این بانک سوالات، این سه نمونه سوال با کیفیت بالا را بررسی کنید.
سوال ۱: مکانیسمهای کانتکست کوروتین و همروندی ساختاریافته
یک توسعهدهنده یک محاسبه طولانیمدت را در یک CoroutineScope سفارشی با استفاده از val job = scope.launch(Dispatchers. Default) { ... } اجرا میکند. داخل این کوروتین، یک کوروتین فرزند از طریق launch(Dispatchers. IO) { ... } ایجاد میشود. اگر کوروتین والد در حین اجرا با یک استثنای مدیریتنشده مواجه شود، چه اتفاقی برای کوروتین فرزند میافتد؟
الف) کوروتین فرزند بدون تغییر به اجرا ادامه میدهد زیرا روی دیسپچر متفاوتی (Dispatchers. IO) اجرا میشود.
ب) کوروتین فرزند فوراً لغو میشود زیرا خطا به سمت بالای اسکوپ والد منتشر شده و به طور پیشفرض تمام فرزندان را لغو میکند.
ج) کوروتین فرزند اجرا را متوقف کرده و وارد حالت تعلیق (Suspended) میشود تا زمانی که اسکوپ والد صراحتاً بازیابی شود.
د) کوروتین فرزند به طور خودکار ارتقا یافته و به یک کوروتین ریشه تحت GlobalScope تبدیل میشود.
ه) محیط اجرا کل پروسه اپلیکیشن را فوراً کرش میدهد و از اجرای هرگونه روتین پاکسازی جلوگیری میکند.
و) کوروتین فرزند بلوک اجرای فعلی خود را به پایان میرساند اما از ارسال هرگونه مقدار به یک جریان Cold Flow منع میشود.
پاسخ صحیح و توضیحات:
پاسخ صحیح: ب
چرا صحیح است: طبق قوانین همروندی ساختاریافته در کاتلین، انتشار استثنا به طور پیشفرض دوطرفه است مگر اینکه از SupervisorJob استفاده شود. وقتی یک کوروتین والد با استثنای مدیریتنشده مواجه میشود، فوراً خودش را لغو کرده و سیگنال لغو را به تمام کوروتینهای فرزند فعال خود ارسال میکند، صرفنظر از اینکه آنها روی دیسپچر متفاوتی مانند Dispatchers. IO در حال اجرا باشند.
چرا گزینههای دیگر نادرست هستند:
گزینه الف نادرست است: دیسپچرها فقط رشتهها (Threads) را تخصیص میدهند؛ آنها سلسلهمراتب ساختاری جابها و قوانین اسکوپینگ را نمیشکنند.
گزینه ج نادرست است: کوروتینهای فرزند متوقف یا معلق نمیشوند؛ آنها یک سیگنال لغو صریح دریافت کرده و اجرای خود را متوقف میکنند.
گزینه د نادرست است: کوروتینها هرگز اسکوپ والد ساختاری خود را به طور پویا در حین اجرا تغییر نمیدهند.
گزینه ه نادرست است: پروسه اپلیکیشن تنها در صورتی کرش میکند که استثنا در سطح ریشه UncaughtExceptionHandler کاملاً مدیریتنشده باقی بماند، اما همروندی ساختاریافته ابتدا لغو سازمانیافته را تضمین میکند.
گزینه و نادرست است: فرزند اجرای خود را به پایان نمیرساند؛ بلکه در اولین نقطه تعلیق (Suspension point) موجود، زودتر خاتمه مییابد.
سوال ۲: بهینهسازی حافظه و رفتار کپی در Data Class
یک data class در کاتلین را به صورت data class UserProfile(val id: Int, val details: MutableList<String>) در نظر بگیرید. توسعهدهندهای یک نمونه ایجاد کرده و آن را با دستور val updatedProfile = originalProfile.copy(id = 101) بروزرسانی میکند. اگر توسعهدهنده متعاقباً لیست details را در updatedProfile تغییر دهد، این کار چه تاثیری بر originalProfile دارد؟
الف) پروفایل اصلی بدون تغییر میماند زیرا data classهای کاتلین در هنگام فراخوانی .copy() به طور خودکار Deep-copy میشوند.
ب) اپلیکیشن خطای ConcurrentModificationException میدهد زیرا ویژگیهای data class به طور ضمنی تغییرناپذیر هستند.
ج) لیست details در پروفایل اصلی نیز تغییر میکند زیرا تابع .copy() یک Shallow copy از انواع مرجع (Reference types) انجام میدهد.
د) تغییر به درستی انجام میشود اما باعث ایجاد هشدار کامپایلر در مورد تکهتکه شدن آدرسهای حافظه (Memory fragmentation) میشود.
ه) کامپایلر این عملیات را مسدود میکند زیرا ساختارهای تغییرپذیر در پارامترهای data class اکیداً ممنوع هستند.
و) پروفایل اصلی به محض ایجاد مرجع به نمونه جدید، توسط Garbage Collector از حافظه پاک میشود.
پاسخ صحیح و توضیحات:
پاسخ صحیح: ج
چرا صحیح است: متد .copy() تولید شده در یک data class کاتلین، یک کپی سطحی (Shallow copy) انجام میدهد. برای انواع اولیه (Primitive) و رشتههای تغییرناپذیر، این رفتار مانند یک کپی مستقل است. اما برای انواع مرجع مانند MutableList، هر دو نمونه قدیمی و جدید به یک شیء لیست فیزیکی یکسان در حافظه Heap اشاره میکنند. تغییر محتویات لیست از طریق یک مرجع، وضعیت مشترکی را که مرجع دیگر میبیند تغییر میدهد.
چرا گزینههای دیگر نادرست هستند:
گزینه الف نادرست است: کاتلین کپیهای عمیق (Deep copy) تولید نمیکند؛ شما باید منطق کپی سفارشی را برای مراجع تغییرپذیر به صورت دستی پیاده کنید.
گزینه ب نادرست است: هیچ استثنایی در زمان اجرا رخ نمیدهد؛ کپیهای سطحی از دیدگاه اجرای JVM کاملاً معتبر هستند.
گزینه د نادرست است: کامپایلر این الگو را بدون هیچ هشداری اجازه میدهد، اگرچه با اهداف برنامهنویسی تابعی پاک در تضاد است.
گزینه ه نادرست است: ویژگیهای تغییرپذیر در data classها کاملاً مجاز هستند، هرچند استفاده از انواع تغییرناپذیر (List به جای MutableList) توصیه صنعتی است.
گزینه و نادرست است: پروفایل اصلی یک مرجع فعال در اسکوپ متغیر خود حفظ میکند، به این معنی که Garbage Collector به آن دست نخواهد زد.
سوال ۳: انتشار Flow در مقابل پردازش چرخه حیات Cold Stream
یک توسعهدهنده از یک جریان سرد ناهمگام برای انتشار مقادیر با فراخوانی بلوک builder flow { ... } استفاده میکند. یک Collector با استفاده از flow.collect { value -> println(value) } به این جریان مشترک میشود. اگر چندین Collector مستقل متد collect را روی همین متغیر flow فراخوانی کنند، موتور flow چگونه اجرا را مدیریت میکند؟
الف) جریان به یک Hot stream تبدیل شده و دقیقاً همان مقادیر منتشر شده را به طور همزمان برای تمام Collectorها پخش میکند.
ب) جریان بلوک builder را برای هر Collector از ابتدا اجرا میکند و هر کدام کاملاً مستقل عمل میکنند.
ج) سیستم خطای IllegalStateException میدهد زیرا Cold flowها جریانهای تکبار مصرف هستند که مانع از جمعآوریهای متعدد میشوند.
د) موتور flow اولین مجموعه داده منتشر شده را کش کرده و حالت حافظه ذخیره شده را به تمام مشترکین بعدی منتقل میکند.
ه) موتور با توزیع انتشارها به صورت Round-robin بین مشترکین فعال، بار را متوازن میکند.
و) اولین Collector اجرای خود را به پایان میرساند، در حالی که دومین Collector برای آزادسازی رشته (Thread) برای همیشه معلق میماند.
پاسخ صحیح و توضیحات:
پاسخ صحیح: ب
چرا صحیح است: طبق تعریف، Flowهای استاندارد کاتلین جریانهای سرد (Cold streams) هستند. بلوک اجرا داخل builder flow { ... } تا زمانی که یک اپراتور نهایی مانند collect فراخوانی نشود، فعال یا اجرا نمیشود. هر Collector متمایز، اجرای مستقل خود را از بلوک builder فعال میکند، به این معنی که چرخه تولید داده برای هر مشترک جداگانه از نو اجرا میشود.
چرا گزینههای دیگر نادرست هستند:
گزینه الف نادرست است: Flowها به طور خودکار به Hot stream تبدیل نمیشوند؛ این رفتار نیازمند اپراتورهای تبدیل صریح مانند shareIn یا stateIn است.
گزینه ج نادرست است: Cold flowها دقیقاً برای این طراحی شدهاند که در چندین عملیات جمعآوری (Collection) قابل استفاده باشند.
گزینه د نادرست است: هیچ رفتار کشینگ داخلی یا Replay در سازنده خام Cold flow وجود ندارد.
گزینه ه نادرست است: توزیع Round-robin ویژگی کانالهای چند-مصرفکننده (Multi-consumer channels) است، نه Cold flowهای متوالی.
گزینه و نادرست است: Collectorها بسته به اسکوپ کوروتین فراخواننده خود، به صورت همزمان یا متوالی اجرا میشوند و یکدیگر را مسدود یا معلق نمیکنند.
چه انتظاراتی داشته باشید
به تستهای سوالات مصاحبه خوش آمدید تا شما را برای ارزیابی سوالات مصاحبه کاتلین آماده کنیم.
میتوانید آزمونها را هر چند بار که بخواهید تکرار کنید
این یک بانک سوالات اصلی و بسیار گسترده است
در صورت داشتن سوال، از پشتیبانی مدرسان بهرهمند میشوید
هر سوال دارای یک توضیح تفصیلی است
سازگار با موبایل از طریق اپلیکیشن Udemy
امیدواریم تا الان متقاعد شده باشید! سوالات بسیار بیشتری در داخل دوره وجود دارد.
Interview Questions Tests
مربی در Udemy
نمایش نظرات