پوشش جامع حوزههای آزمون
این بانک سوالات جامع به صورت سیستماتیک بر اساس حوزههای مهندسی واقعی که در مصاحبههای فنی سطح ارشد و ارزیابیهای معماری موبایل مورد سنجش قرار میگیرند، طراحی شده است:
مفاهیم هسته اندروید (۲۰٪)
مباحث پوشش داده شده:ماشینهای حالت چرخه حیات Activity و Fragment، مدیریت Deep-link از طریق Intentها، سرویسهای Foreground و Background، ثبت BroadcastReceiver و محیطهای ایزوله (Sandboxing) فرآیند اپلیکیشن.
کاتلین و برنامهنویسی (۱۵٪)
مباحث پوشش داده شده:ساختارهای پیشرفته سینتکس کاتلین، Coroutine Scopes، همروندی ساختاریافته (Structured Concurrency)، مدیریت جریانهای ناهمگام، گرافهای تزریق وابستگی سفارشی با Dagger/Hilt و الگوهای ساختاری سختگیرانه MVVM.
طراحی سیستم و معماری (۲۵٪)
مباحث پوشش داده شده:مقیاسپذیری اپلیکیشنهای چند-ماژوله، مدلهای کاهش مصرف باتری، طراحی کتابخانههای شبکه Offline-first، عملکرد ابزارهای UI سفارشی و اجرای دقیق معماری پاک.
ذخیرهسازی و مدیریت دادهها (۱۰٪)
مباحث پوشش داده شده:بهینهسازی کتابخانه Room، طراحی اسکیماهای رابطهای پیچیده SQLite، رمزنگاری تراکنشی دادهها در حالت سکون و پیکربندیهای پشتیبان خودکار.
امنیت و تست (۱۰٪)
مباحث پوشش داده شده:بهترین روشهای امنیتی اندروید، تستهای واحد (Unit Testing) محلی با Mockk/JUnit، الگوهای تایید یکپارچگی و تست UI خودکار با Espresso یا UI Automator.
بهینهسازی عملکرد (۵٪)
مباحث پوشش داده شده:مدیریت حافظه Heap در JVM/Art، شناسایی و رفع نشت حافظه با LeakCanary، ردیابی پروفایلهای CPU، تحلیل گلوگاههای شبکه و پروفایلینگ سیستماتیک اپلیکیشن.
Jetpack و توسعه مدرن اندروید (۵٪)
مباحث پوشش داده شده:درختهای لایوت Jetpack Compose، بهینهسازی recomposition، مدیریت وضعیت واکنشگرا با LiveData/StateFlow، الگوهای طراحی ViewModel و کامپوننتهای ناوبری (Navigation) Type-safe.
رفتاری و همکاری تیمی (۱۰٪)
مباحث پوشش داده شده:استراتژیهای همکاری مستقیم با تیم مهندسی، ارتباطات فنی شفاف، حل مسئله بین-وظیفهای و مدیریت چرخههای مقیاسپذیر بررسی کد (Code Review).
توضیحات دوره
موفقیت در مصاحبههای فنی برای موقعیتهای مهندسی موبایل سطح بالا، نیازمند چیزی فراتر از حفظ کردن APIهای پلتفرم یا چرخههای حیات پایه است. شرکتهای تراز اول، غریزه معماری شما، درک شما از مدیریت حافظه و توانایی شما در مهندسی سیستمهای موبایلی ماژولار، تستپذیر و با عملکرد بالا را ارزیابی میکنند. من این مخزن جامع سوالات را برای شبیهسازی ارزیابیهای ظریف و سناریو-محوری طراحی کردهام که توسط مدیران مهندسی و معماران فنی در مصاحبههای عمیق استفاده میشود.
با ۵۵۰ سوال فنی با دقت آماده شده، این پلتفرم تمرینی مفاهیم مهندسی ساختاری ضروری برای نقشهایی مانند توسعهدهنده اندروید، مهندس ارشد اندروید، مهندس نرمافزار موبایل و معمار سیستم اندروید را هدف قرار میدهد. هر سوال شامل تحلیلی دقیق است که مکانیسمهای دقیق دلیل برتری یک رویکرد خاص و دلیل شکست پیادهسازیهای جایگزین در سیستمهای عملیاتی را آشکار میکند.
به جای اطلاعات سطحی، شما سناریوهای واقعی شامل بلاکهای رشتهای ناهمگام، رفع نشت حافظه، همگامسازی مداوم پسزمینه و درختهای رندرینگ Composable را کالبدشکافی خواهید کرد. با مطالعه سیستماتیک این آزمونهای تمرینی، شهود عمیقی نسبت به پلتفرم کسب میکنید که برای تبیین با اعتمادبهنفس انتخابهای مهندسی، توضیح trade-offهای سیستم و قبولی در مصاحبههای آتی در اولین تلاش ضروری است.
پیشنمایش نمونه سوالات تمرینی
سوال ۱: هسته اندروید و کانتکست ناهمگام چرخه حیات
یک توسعهدهنده در حال پیادهسازی اپلیکیشنی است که دارای یک سرویس همگامسازی مداوم در پسزمینه (Long-polling) است که باید بدون نشت کانتکست پلتفرم، هنگام تغییرات پیکربندی UI مانند چرخش صفحه، به صورت ایمن اجرا شود. پیادهسازی اولیه، یک Coroutine را داخل یک Fragment با استفاده از lifecycleScope استاندارد آغاز میکند. هنگام چرخش صفحه چه اتفاقی میافتد و مکانیسم بنیادین پلتفرم در اینجا چیست؟
گزینهها:
A) کوروتین به صورت جداگانه در پسزمینه به اجرا ادامه میدهد زیرا lifecycleScope هنگام تغییرات سختافزاری به طور خودکار به کانتکست چرخه حیات سطح اپلیکیشن تغییر میکند.
B) کوروتین به طور خودکار لغو میشود زیرا lifecycleScope دقیقاً به چرخه حیات Fragment وابسته است، به این معنی که عملیات فعال پسزمینه هنگام تخریب سلسلهمراتب View در میانه اجرا متوقف میشود.
C) کوروتین اجرای خود را در میانه مسیر متوقف کرده و پس از اتمام پیکربندی چرخش و ایجاد نمونه جدید از Fragment، به طور خودکار از سر گرفته میشود.
D) کوروتین یک ConcurrentModificationException را پرتاب میکند زیرا رشته پسزمینه سعی میکند به عناصر لایوت دسترسی پیدا کند که دیگر در فضای مختصات فعلی صفحه نیستند.
E) کوروتین از تغییرات پیکربندی جان سالم به در میبرد اما باعث نشت حافظه شدید میشود زیرا یک ارجاع سخت (hard root) به عناصر View تخریب شده نگه میدارد.
F) اگر توسعهدهنده محدوده اجرا را به GlobalScope منتقل کند در حالی که پیکربندی Dispatcher رشته اصلی را حفظ کرده باشد، کوروتین بدون وقفه و ایمن اجرا میشود.
پاسخ صحیح:
B
توضیح:
چرا B صحیح است:lifecycleScope یک فرگمنت مستقیماً به حالت چرخه حیات خاص آن متصل است. وقتی تغییر پیکربندی رخ میدهد، فرگمنت کاملاً تخریب و دوباره ساخته میشود. در نتیجه، چرخه حیات آن به حالت destroyed میرود که به طور خودکار لغو تمام کوروتینهای فرزند در آن محدوده را فعال میکند. این کار از نشت حافظه جلوگیری میکند اما عمداً اجرای عملیات همگامسازی پسزمینه را متوقف میسازد.
چرا A غلط است:lifecycleScope هرگز خود را به یک کانتکست اپلیکیشن منتقل نمیکند. این دامنه به مالک چرخه حیاتی که در آن ایجاد شده متصل میماند تا اطمینان حاصل شود که منابع بلافاصله پس از پایان کامپوننت میزبان پاکسازی میشوند.
چرا C غلط است:فریمورک کوروتین اندروید مکانیسم کشینگ یا توقف خودکار در طول چرخههای حیات مختلف فرگمنت ندارد؛ تخریب باعث لغو کامل Job میشود نه توقف موقت.
چرا D غلط است:مکانیسم لغو، تعاملی است و از طریق CancellationException در فریمورک کوروتین کنترل میشود و باعث کرش اپلیکیشن با خطای تغییر همزمان لایوت نمیشود.
چرا E غلط است:چون lifecycleScope به درستی خودش را لغو میکند، Job از مرحله تخریب جان سالم به در نمیبرد، بنابراین ریشه سخت Garbage Collection یا نشت عناصر View تخریب شده ایجاد نمیکند.
چرا F غلط است:در حالی که استفاده از GlobalScope مانع از کشته شدن تسک در هنگام چرخش میشود، یک ضد-الگوی (Anti-pattern) معماری خطرناک را معرفی میکند. اگر تسک به هر متغیر یا کامپوننت محلی ارجاع دهد، میتواند باعث نشت حافظه شود زیرا GlobalScope خارج از محدوده Structured Concurrency عمل میکند.
سوال ۲: Jetpack Compose و بهینهسازی عملکرد Recomposition
یک مهندس در حال پروفایلینگ یک اپلیکیشن Feed پیچیده است که دادههای رمزنگاری شده آفلاین را از دیتابیس Room دریافت کرده و از طریق LazyColumn نمایش میدهد. در هنگام اسکرول سریع عمودی، مانیتور پروفایلینگ افت فریمهای مداوم (jank) و فعالیت شدید Garbage Collection (GC) را گزارش میکند. تحلیل کد نشان میدهد که عناصر لیست، یک مدل دامین خام و ناپایدار (unstable) شامل کالکشنهای بدون انوتیشن را میپذیرند. کدام تغییر این گلوگاه رندرینگ را حل میکند؟
گزینهها:
A) جایگزینی کامپوننت مدرن LazyColumn با یک ساختار Column سنتی که در یک Modifier اسکرول عمودی پیچیده شده است تا تخصیص پیشفرض کل درخت لایوت اجبار شود.
B) انوتیشن @Stable یا @Immutable را به مدل Wrapper وضعیت UI اضافه کرده و یک پارامتر کلید ساختاری منحصربهفرد به هر لایوت آیتم در حلقه LazyColumn اختصاص دهید.
C) افزایش دینامیک حداکثر اندازه Heap در زمان اجرای JVM در فایل Manifest ریشه اپلیکیشن با استفاده از پرچم largeHeap.
D) انتقال عملیات کوئری دیتابیس از فریمورک Room به رپرهای SQLite خام با استفاده از دستورات تراکنشی مدیریت نشده.
E) پیچاندن کل معماری لایوت LazyColumn در یک بلوک LaunchedEffect برای انتقال پاس ترکیب UI به یک Executor در استخر رشتههای پسزمینه IO.
F) انتقال معماری مدیریت وضعیت زنده به یک کامپوننت Android Service پسزمینه برای جداسازی انتشار مجموعه داده خام از لایه معماری اصلی.
پاسخ صحیح:
B
توضیح:
چرا B صحیح است:Compose برای رد کردن Recomposition به پایداری ورودیها متکی است. وقتی یک کلاس شامل انواع ناپایدار (مانند کالکشنهای استاندارد) باشد، کامپایلر Compose آن شیء را ناپایدار علامت میزند و آیتمهای لیست را مجبور میکند در هر رویداد اسکرول دوباره ترکیب شوند، حتی اگر داده تغییر نکرده باشد. انوتیشن @Stable یا @Immutable به کامپایلر اطلاع میدهد که ویژگیها به طور غیرمنتظره تغییر نخواهند کرد. علاوه بر این، افزودن یک کلید منحصربهفرد به آیتمها در LazyColumn از Recomposition موقعیتی جلوگیری کرده و به Compose اجازه میدهد آیتمهای بدون تغییر را به طور بهینه مجدداً استفاده کند و نوسانات GC را از بین ببرد.
چرا A غلط است:جایگزینی با Column استاندارد و Modifier اسکرول، باعث ایجاد آنی تمام عناصر لیست به صورت همزمان میشود که بهرهوری حافظه را کاملاً از بین برده و افت فریم را تشدید میکند.
چرا C غلط است:فعال کردن ویژگی largeHeap تنها ناکارآمدیهای ساختاری معماری را میپوشاند و آنها را حل نمیکند. علت ریشهای همچنان Recomposition بهینه نشده است که به اتلاف منابع سیستم ادامه میدهد.
چرا D غلط است:گلوگاه رندرینگ کاملاً از دینامیکهای Recomposition لایه UI ناشی میشود، نه از مکانیسم کوئری داخلی فریمورک Room. تغییر لایههای دیتابیس هیچ تاثیری در رفع باگهای Recomposition ندارد.
چرا E غلط است:پاس ترکیب در Jetpack Compose باید دقیقاً روی رابط رشته اصلی (Main Thread) اجرا شود. تلاش برای اجبار درختهای لایوت به Side-effectهای کوروتین پسزمینه باعث ایجاد Runtime Exception میشود.
چرا F غلط است:انتقال انتشار دادههای وضعیت به یک سرویس پسزمینه، پیچیدگی IPC غیرضروری اضافه میکند و مشکل اساسی نحوه پردازش و رندر مدلهای داده توسط لایه UI در حین اسکرول را حل نمیکند.
سوال ۳: امنیت دادهها و سیستمهای معماری سازمانی
شما در حال تعریف معماری ذخیرهسازی برای یک اپلیکیشن موبایل سازمانی هستید که توکنهای دسترسی، تنظیمات کاربر و هشهای شناسایی حساس را به صورت محلی کش میکند. الزامات امنیتی حکم میکند که این مقادیر در برابر تکنیکهای استخراج در دستگاههای compromised یا rooted محافظت شوند. کدام الگوی پیادهسازی با این دستورالعملها مطابقت دارد؟
گزینهها:
A) ذخیره توکنها در سیستم فایل Shared Preferences پیشفرض با استفاده از ابزارهای رمزگذاری ساده Base64.
B) ذخیره رشتههای توکن سریالایز شده مستقیماً در یک فایل متنی خام مخفی در دایرکتوری پارتیشن کش حافظه خارجی اپلیکیشن.
C) استفاده از کتابخانه EncryptedSharedPreferences با پشتیبانی سیستم Android Keystore و یک ارائهدهنده Master Key مبتنی بر سختافزار.
D) هاردکد کردن رشتههای توکن رمزنگاری شده مستقیماً در لایههای باینری کامپایل شده اپلیکیشن از طریق Android Native Development Kit (NDK).
E) ذخیره کلیدهای حساس در یک نمونه دیتابیس Room سفارشی رمزنگاری نشده که تنها برای فعالیت در فضاهای ذخیرهسازی In-memory پیکربندی شده است.
F) رمزنگاری رشتهها با استفاده از یک کلید AES هارد-کد شده مستقیماً در سازنده کلاس Application در طول بلوکهای مقداردهی اولیه زمان اجرا.
پاسخ صحیح:
C
توضیح:
چرا C صحیح است:کتابخانه Jetpack Security ابزار EncryptedSharedPreferences را ارائه میدهد که به طور خودکار کلیدها و مقادیر را با استفاده از یک سیستم رمزنگاری دو لایه رمزگذاری میکند. کلید اصلی (Master Key) به طور ایمن در سیستم Android Keystore ذخیره میشود که از محیطهای مبتنی بر سختافزار مانند Trusted Execution Environment (TEE) یا StrongBox در صورت موجود بودن استفاده میکند. این پیکربندی تضمین میکند که کلیدهای رمزنگاری حتی در دستگاههای rooted نیز به راحتی از سیستم فایل دستگاه استخراج نشوند.
چرا A غلط است:Base64 صرفاً یک مکانیسم کدگذاری (Encoding) است، نه یک روش رمزنگاری. هر کسی با دسترسی root یا دسترسی فیزیکی به بکآپ دستگاه میتواند یک رشته Base64 را فوراً رمزگشایی کند.
چرا B غلط است:ذخیره فایلها در دایرکتوریهای حافظه خارجی، دادههای حساس را در معرض سایر اپلیکیشنهایی قرار میدهد که مجوز دسترسی به حافظه دارند و یک آسیبپذیری امنیتی با ریسک بالا ایجاد میکند.
چرا D غلط است:دکامپایل کردن باینری اپلیکیشن اندروید یا استخراج رشتهها از اشیاء کتابخانه مشترک با استفاده از ابزارهای مهندسی معکوس استاندارد مانند APKTool یا JADX بسیار ساده است و کلیدهای هارد-کد شده را فاش میکند.
چرا E غلط است:دیتابیسهای In-memory به صورت رمزنگاری نشده در RAM ذخیره میشوند. اگرچه هنگام پایان فرآیند اپلیکیشن ناپدید میشوند، اما در حالی که اپلیکیشن فعال است، در برابر تکنیکهای Memory Dumping آسیبپذیر هستند.
چرا F غلط است:قرار دادن یک کلید رمزنگاری هارد-کد شده در سازنده کلاس Application از همان آسیبپذیری رویکرد NDK رنج میبرد. ابزارهای مهندسی معکوس میتوانند کلید استاتیک را از DEX bytecode استخراج کنند.
به آزمونهای سوالات مصاحبه خوش آمدید تا به شما در آماده شدن برای سوالات مصاحبه اندروید کمک کنیم.
شما میتوانید هر تعداد بار که بخواهید در آزمونها شرکت کنید.
این یک بانک سوالات عظیم و اورجینال است.
در صورت داشتن سوال، از پشتیبانی مدرسان بهرهمند میشوید.
هر سوال دارای یک توضیح دقیق است.
با اپلیکیشن Udemy کاملاً سازگار با موبایل است.
امیدوارم تا الان متقاعد شده باشید! و سوالات بسیار بیشتری در داخل دوره وجود دارد.
Interview Questions Tests
مربی در Udemy
نمایش نظرات