در این مقاله مهمترین سوالات مصاحبه برنامه نویسی #C در سطحهای مختلف مبتدی، متوسط و پیشرفته مورد بررسی قرار میگیرند. افراد به واسطه مطالعه این مقاله میتوانند خود را برای مصاحبههای کاری برنامه نویسی آماده کنند و از آن به عنوان یک روش کمکی برای ارتقای مهارتهای خود و مرور بیشتر مطالب استفاده کنند.
زبان برنامه نویسی #C چیست؟
#C به عنوان یک زبان برنامه نویسی همه منظوره برای اجرا بر روی پلتفرمهای مایکروسافت نیاز به NET Framework. دارد. همچنین این زبان مدرن برگرفته از تکنولوژیهای زبانهای برنامه نویسی C و ++C میباشد. ساخت بازی، برنامههای دسکتاپ تحت ویندوز، برنامه توسعه وب و همچنین برنامه تحت موبایل از جمله مواردی هستند که میتوان توسط زبان #C پیاده سازی نمود. همچنین با استفاده از ابزار Xamarin میتوان برنامههای نوشته شده به زبان #C را بر روی هر دستگاهی موبایلی اجرا کرد.
زبان #C به کمک پشتیبانی قوی شرکت مایکروسافت بسرعت توسعه یافت و توانست طرفدارن بیشماری را برای خودش جلب کند. این زبان در حال حاضر یکی از محبوبترین زبانها در کل دنیا است.
سوالات مصاحبه برنامه نویسی #C برای مبتدیها
در این قسمت به «سوالات مصاحبه #C برای مبتدیها» پرداختیم که مناسب افراد کم سابقه و مبتدی هست. هدف، ارزیابی دانش اولیه و درک بنیادی زبان سیشارپ است.
-
زبان برنامه نویسی #C را معرفی کنید؟
#C یک زبان برنامه نویسی شی گرا (OOP) به حساب میآید که در سال ۱۳۷۸ (۲۰۰۰ میلادی) توسط شرکت مایکروسافت ارائه شده است. #C با هدف ایجاد یک زبان برنامه نویسی همه منظوره ساخته شده است که میتوان از آن جهت توسعه انواع نرم افزارها برای پلتفرمهای (سکوهای) مختلفی از جمله ویندوز، وب و موبایل استفاده کرد. امروزه زبان #C یکی از محبوبترین زبانهای برنامه نویسی در دنیا به حساب میآید و هزاران توسعه دهنده نرم افزار از زبان برنامه نویسی C# برای ساخت انواع نرم افزارها استفاده میکنند.
-
وراثت چیست؟ آیا #C از وراثت چندگانه پشتیبانی میکند؟
وراثت یکی از ارکان مهم برنامهنویسی شیءگرا (OOP) است. در زبان سیشارپ، وراثت مکانیزمی است که به یک کلاس اجازه میدهد تا ویژگیهای (میدانها و متدها) کلاس دیگری را به ارث ببرد.
- کلاس پایه (Superclass): کلاسی که ویژگیهایش به ارث میرسد، کلاس پایه (یا کلاس فوق یا کلاس والد) نامیده میشود.
- کلاس مشتقشده (Subclass): کلاسی که ویژگیهای کلاس دیگری را به ارث میبرد، کلاس مشتقشده (یا کلاس فرزند، کلاس توسعهیافته یا کلاس زیرکلاس) نامیده میشود. کلاس مشتقشده میتواند علاوه بر میدانها و متدهای کلاس پایه، میدانها و متدهای خاص خود را نیز اضافه کند.
- استفاده مجدد (Reusability): وراثت مفهوم «استفاده مجدد» را پشتیبانی میکند. به این معنی که اگر بخواهیم کلاس جدیدی ایجاد کنیم و کلاسی از قبل وجود دارد که بخشی از کد مورد نیاز ما را شامل میشود، میتوانیم کلاس جدید خود را از کلاس موجود مشتق کنیم. با این کار، از میدانها و متدهای کلاس موجود مجدداً استفاده میکنیم.
-
تفاوت ساختار و کلاس در #C چیست؟
کلاس، طرح یا نمونه اولیهای است که توسط کاربر تعریف میشود و از آن، اشیاء ساخته میشوند. در اصل، کلاس، فیلدها (متغیرها) و متدها (توابع عضو که اعمال را تعریف میکنند) را در یک واحد ترکیب میکند. ساختار (struct)، مجموعهای از متغیرها با انواع دادههای مختلف است که تحت یک واحد قرار میگیرند. ساختار تقریباً مشابه کلاس است، زیرا هر دو نوع دادهای هستند که توسط کاربر تعریف میشوند و هر دو مجموعهای از انواع دادههای مختلف را در خود نگه میدارند.
-
منظور از آرایههای دندانهدار در #C چیست؟
در #C، آن دسته از آرایههایی که عناصر آن هم خود از نوع آرایه هستند، با نام «آرایههای دندانهدار» (Jagged Arrays) شناخته میشوند. عناصر آرایه دندانهدار میتوانند در ابعاد و اندازههای مختلفی باشند. همچنین میتوان این نوع از آرایهها را «آرایهای از آرایهها» نیز خطاب کرد.
-
زمان اجرای زبان مشترک چیست؟
زمان اجرای زبان مشترک (CLR | Common Language Runtime) یک موتور اجرایی است که رسیدگی به اجرای برنامه را برای زبانهای مختلف از جمله #C انجام میدهد. به واسطه معماری زبان اجرای مشترک، مواردی مانند مدیریت حافظه (Memory Management)، بازیافت حافظه و مدیریت و رسیدگی به مسائل امنیتی انجام میشوند.
-
تفاوت بین “ثابت” (constant) و “فقط خواندنی” (read-only) در #C چیست؟
در #C، از کلمهی کلیدی const برای تعریف فیلدهای ثابت و متغیرهای محلی ثابت استفاده میشود. مقدار یک فیلد ثابت در کل برنامه یکسان است؛ به عبارت دیگر، پس از مقداردهی اولیه، مقدار این فیلد دیگر تغییر نمیکند. در #C، فیلدهای ثابت و متغیرهای محلی ثابت، متغیر نیستند؛ یک ثابت میتواند یک عدد، رشته، مرجع تهی (null) یا یک مقدار بولی باشد.
کلمهی کلیدی readonly برای تعریف یک متغیر فقط خواندنی استفاده میشود. این کلمهی کلیدی نشان میدهد که شما فقط میتوانید در هنگام تعریف متغیر یا در سازندهی همان کلاسی که متغیر در آن تعریف شده است، به آن مقدار بدهید.
-
تفاوت زبان برنامه نویسی C# با زبان C چیست؟
C و #C هر دو زبان برنامهنویسی قدرتمند هستند، اما برای اهداف متفاوتی طراحی شدهاند. C زبانی سطح پایینتر و رویهای است که کنترل دقیقی روی حافظه و سختافزار به برنامهنویس میدهد. این ویژگی آن را برای برنامهنویسی سیستم، برنامههای تعبیهشده و جاهایی که راندمان و بهینهسازی در اولویت هستند، ایدهآل میکند. در مقابل، #C یک زبان سطح بالاتر و شیءگراست که روی سادگی و قابلیت نگهداری تمرکز دارد.
#C از NET Framework. و NET. استفاده میکند که مجموعهای از کتابخانهها و فریمورکها را برای توسعه برنامههای متنوع، از دسکتاپ و وب تا موبایل، در اختیار قرار میدهد. در واقع، C اغلب برای نوشتن بخشهای پرفورمنس بالا از یک برنامه استفاده میشود، در حالی که #C برای بخشهای سطح بالاتر و رابط کاربری به کار میرود. انتخاب بین این دو زبان بستگی به نیازهای پروژه، سطح دسترسی مورد نیاز به سخت افزار، اولویتهای راندمان و تجربه برنامهنویس دارد.
سوالات مصاحبه برنامه نویسی #C برای پیشرفتهها
در این بخش به «سوالات مصاحبه برنامه نویسی #C برای پیشرفتهها» پرداخته شده که نیازمند درک عمیق از مفاهیم شیگرایی، الگوهای طراحی و ساختارهای داده پیشرفته است. این سطح از سوالات برای برنامهنویسان با تجربه و متخصص مناسب است. همچنین این سوالات نیازمند درک و تجربه عملی در پروژههای پیچیده و استفاده از تکنیکهای پیشرفته در برنامهنویسی هستند.
-
فرآیند کامپایلر JIT چیست؟
کامپایلر JIT (Just-In-Time) بخشی از محیط اجرای مشترک (CLR) در دات نت است که مسئول اجرای برنامههای دات نت، صرف نظر از زبان برنامهنویسی مورد استفاده در آنها، میباشد. یک کامپایلر مخصوص هر زبان، کد منبع را به زبان میانی (Intermediate Language یا IL) تبدیل میکند. سپس، کامپایلر JIT این زبان میانی را به کد ماشین تبدیل میکند. این کد ماشین مخصوص محیط کامپیوتری است که کامپایلر JIT در آن اجرا میشود.
-
جمعآوری زباله (Garbage Collection) در #C به چه معناست؟
مدیریت خودکار حافظه از طریق جمعآوری زباله در فریمورک NET. امکانپذیر است. هنگامی که یک شیء از کلاس در زمان اجرا ایجاد میشود، به آن در حافظه Heap یک فضای مشخص تخصیص داده میشود. اما پس از اینکه تمام فعالیتهای مرتبط با آن شیء در برنامه به پایان رسید، فضای تخصیص داده شده به آن بیاستفاده میشود و دیگر قابل استفاده نیست. در اینجا جمعآوری زباله بسیار مفید است زیرا بهطور خودکار فضای حافظه را تبرک میکند، وقتی که دیگر به آن نیاز نیست.
جمعآوری زباله همیشه روی حافظه مدیریتشده (Managed Heap) انجام میشود و دارای یک موتور داخلی به نام موتور بهینهسازی (Optimization Engine) است. جمعآوری زباله زمانی انجام میشود که یکی از شرایط زیر رخ دهد:
- اگر سیستم حافظه فیزیکی کمی داشته باشد، جمعآوری زباله ضروری است.
- اگر فضای اختصاص دادهشده به شیءهای مختلف در حافظه Heap از یک آستانه از پیش تعیین شده تجاوز کند، جمعآوری زباله انجام میشود.
- اگر متد GC.Collect فراخوانی شود، جمعآوری زباله انجام میشود. البته این متد معمولاً در شرایط غیرعادی فراخوانی میشود، زیرا جمعآورنده زباله معمولاً بهصورت خودکار اجرا میشود.
-
کلاسهای System.String و System.Text.StringBuilder در#C به چه معنا هستند؟
کلاس StringBuilder در #C مشابه با StringBuilder در جاوا است. به یاد داشته باشید که یک شیء از نوع String (رشته) غیرقابل تغییر است، یعنی پس از ایجاد، نمیتوان آن را تغییر داد. هر بار که یکی از متدهای کلاس System.String را مورد استفاده قرار میدهید، یک شیء جدید رشته در حافظه ایجاد میشود. به عنوان مثال، رشته «GeeksForGeeks» در حافظه Heap ذخیره میشود. حال اگر تصمیم بگیرید که رشته اولیه «GeeksForGeeks» را به «GFG» تغییر دهید، یک شیء جدید رشته در حافظه Heap ساخته خواهد شد و رشته اولیه در همان مکان حافظه تغییر نخواهد کرد. در موقعیتهایی که نیاز دارید بارها و بارها روی یک رشته تغییرات ایجاد کنید، به کلاس StringBuilder نیاز دارید.
برای جلوگیری از ایجاد یک شیء جدید در حافظه هنگام تغییر، اضافه کردن، حذف یا وارد کردن رشتههای جدید به رشته اصلی، #C مفهوم StringBuilder را معرفی میکند. StringBuilder یک شیء پویا است. این کلاس یک شیء جدید در حافظه ایجاد نمیکند، بلکه حافظه مورد نیاز را به طور دینامیک گسترش میدهد تا رشتههای تغییر یافته یا جدید را در خود نگه دارد.
-
کلاسهای جزئی (Partielle Klassen) در #C به چه معنا هستند؟
یک کلاس جزئی یک ویژگی خاص در #C است که امکان میدهد عملکرد یک کلاس واحد در چندین فایل پیادهسازی شود. تمام این فایلها هنگام کامپایل برنامه به یک فایل کلاس واحد ترکیب میشوند. یک کلاس جزئی با استفاده از کلمه کلیدی partial ایجاد میشود. این کلمه کلیدی همچنین برای تقسیم عملکرد متدها، رابطها یا ساختارها به چندین فایل مفید است.
به عنوان مثال، یک کلاس جزئی به این شکل تعریف میشود:
public partial class ClassName { // کد }
-
LINQ در #C به چه معناست؟
LINQ که بهعنوان Language Integrated Query شناخته میشود، در NET 3.5. و Visual Studio 2008 معرفی شد. یکی از مزایای LINQ این است که به زبانهای NET. مانند #C و VB.NET این امکان را میدهد که کوئریهایی برای بازیابی دادهها از منابع داده ایجاد کنند. به عنوان مثال، یک برنامه میتواند اطلاعاتی از سوابق دانشجویان یا سوابق کارکنان را دریافت کند. در سالهای گذشته، اینگونه دادهها در یک پایگاه داده جداگانه از برنامه ذخیره میشدند و شما باید زبانهای مختلفی مانند SQL یا XML را برای دسترسی به این دادهها یاد میگرفتید. همچنین، امکان ایجاد کوئری با زبان #C یا هر زبان دیگرNET. وجود نداشت.
-
کلاسهای یخزده (Versiegelte Klassen) در #C به چه معنا هستند؟
کلاسهای یخزده برای جلوگیری از وراثتپذیری توسط کاربران استفاده میشوند. یک کلاس میتواند با استفاده از کلمه کلیدی sealed یخزده شود. این کلمه کلیدی به کامپایلر اعلام میکند که کلاس یخزده است و بنابراین نمیتوان آن را گسترش داد. هیچ کلاسی نمیتواند از یک کلاس یخزده مشتق شود.
سینتکس تعریف یک کلاس یخزده به شکل زیر است:
sealed class ClassName { // اعضای داده // متدها . . . }
-
چگونه الگوی طراحی Singleton را در #C پیادهسازی کنیم؟
ما میتوانیم الگوی طراحی Singleton را در #C به روشهای زیر پیادهسازی کنیم:
-
Singleton غیر ایمن از نظر چند رشتهای (Thread Safe): پیادهسازی ساده که در آن ممکن است چندین رشته به طور همزمان به نمونه Singleton دسترسی پیدا کنند و باعث ایجاد چندین نمونه شوند.
-
Singleton ایمن از نظر چند رشتهای (Thread-safe Singleton): در این روش، با استفاده از مکانیزمهایی مانند قفلگذاری (Locking) از ایجاد چندین نمونه جلوگیری میشود.
-
ایمنی رشتهای بدون قفل (Thread-safe بدون Lock): در این حالت، از تکنیکهایی بدون استفاده از قفل برای دستیابی به ایمنی رشتهای استفاده میشود.
-
یک متد مجازی (virtual method) در#C چیست؟
در #C، متد مجازی راهی است که امکان تغییر نهاد (پیادهسازی) آن در کلاسهای مشتقشده وجود دارد. ما میتوانیم متد مجازی را در کلاس پایه و همچنین در کلاس مشتقشده پیادهسازی کنیم. این متد زمانی استفاده میشود که عملکرد اصلی یک متد مشابه باشد، اما کلاس مشتقشده در برخی موارد نیاز به عملکردهای اضافی دارد.
در کلاس والد، یک متد مجازی تعریف میشود که میتواند در کلاس فرزند (مشتقشده) بازنویسی (override) شود. ما با استفاده از کلمه کلیدی “virtual” در کلاس پایه یک متد مجازی ایجاد میکنیم و این متد در کلاس مشتقشده با استفاده از کلمه کلیدی “override” بازنویسی میشود. لازم نیست هر کلاس مشتقشده یک متد مجازی را به ارث ببرد، اما متد مجازی باید در کلاس پایه ایجاد شود. به همین دلیل، متد مجازی همچنین به عنوان پلیمورفیسم (Polymorphism) شناخته میشود.
-
انواع کلاس در C# کدامند؟
#C دارای چهار نوع کلاس است که در ادامه فهرست شدهاند:
- کلاس ایستا (Static Class): این کلاس با کلمه کلیدی «static» تعریف میشود و در آن ارثبری (Inheritance) مجاز نیست. به همین دلیل امکان ایجاد کلاس دیگری بر اساس یک کلاس ایستا وجود ندارد. به منظور درک بهتر نحوه اعلان یک کلاس ایستا در #C، در ادامه یک کلاس از این نوع با عنوان classname ارائه شده است:
static class classname { //static data members //static methods }
- کلاس جزئی (Partial Class): کلاس جزئی یا همان Partial با استفاده از کلمه کلیدی «partial» تعریف میشود و به اعضای خود این امکان را میدهد که فایلهای منبع (.cs) را به صورت جزئی تقسیمبندی کنند یا به اشتراک بگذارند.
- کلاس انتزاعی (Abstract Class): این دسته از کلاسهای #C در بخشهایی که امکان ساخت اشیا نیست، قابلیت نمونهبرداری شدن ندارند. عملکر کلاسهای انتزاعی پیرامون مفاهیم شیگرایی مربوط به انتزاع است. انتزاع به منظور استخراج جزییات ضروری و در نقطه مقابل، پنهان کردن اطلاعات غیرضروری به کار میروند.
- کلاس مهر و موم شده (Sealed Class): این کلاسها قابلیت به ارث برده شدن را ندارند. با استفاده از کلمه کلیدی «sealed» میتوان دسترسی کاربران برای به ارث بردن آن کلاس خاص را محدود کرد.
سوالات مصاحبه برنامه نویسی #C برای افراد با تجربه
در این بخش از مقاله «سوالات مصاحبه برنامه نویسی #C برای افراد با تجربه»، به آن دسته از سوالات مصاحبه برنامه نویسی #C پرداخته شده است که درجه سختی آنها در سطح پیشرفته و مناسب افراد با سابقه هست.
-
ژنریکها (Generics) در #C چیستند؟
ژنریکها در #C کلاسهایی هستند که به برنامهنویس اجازه میدهند کلاسها و متدها را با استفاده از پارامترهای نوع (Type Parameters) تعریف کند. ژنریکها از نسخه ۲٫۰ زبان #C اضافه شدند. ایده اصلی استفاده از ژنریکها، امکان استفاده از انواع داده (مثل int، string و انواع دادهی تعریفشده توسط کاربر) به عنوان پارامتر برای متدها، کلاسها و رابطها است. به عنوان مثال:
class DataStore<T> { public T Data { get; set; } }
-
جعبهبندی (Boxing) و بازکردن جعبهبندی (Unboxing) در #C چیست؟
جعبهبندی و بازکردن جعبهبندی مفاهیم مهمی در #C هستند. سیستم نوعبندی #C شامل سه نوع داده است: انواع مقداری (Value Types) مانند int ، char و غیره، انواع مرجعی (Reference Types) مانند object و انواع اشاره گر (Pointer Types). در اصل، جعبهبندی و بازکردن جعبهبندی، تبدیل یک نوع مقداری به یک نوع مرجعی و بالعکس است. این دو مکانیسم، یک دیدگاه یکپارچه از سیستم نوعبندی را فراهم میکنند که در آن هر مقداری با هر نوعی میتواند به عنوان یک شیء (object) رفتار شود.
- جعبهبندی (Boxing) در #C: فرآیند تبدیل یک نوع مقداری (مانند char ، int و غیره) به یک نوع مرجعی (مانند object ) را جعبهبندی مینامند.جعبهبندی یک فرایند تبدیل ضمنی (Implicit) است که از نوع object (نوع فراگیر یا سوپر نوع) استفاده میکند. نوع مقداری همیشه در Stack (پشته) ذخیره میشود. نوع مرجعی در Heap (هیپ) ذخیره میشود.
- بازکردن جعبهبندی (Unboxing) در#C: عملکرد تبدیل نوع مرجعی به نوع مقداری را بازکردن جعبهبندی مینامند. این یک فرایند تبدیل صریح (Explicit) است.
-
تفاوت بین متدهای ()Dispose و ()Finalize در #C چیست؟
تفاوت اصلی بین این دو متد این است که از متد ()Dispose برای آزادسازی منابع غیرمدیریتی (Unmanaged Resources) یک شیء استفاده میشود، در حالی که ()Finalize نیز برای همین منظور استفاده میشود، اما تضمینی برای جمعآوری زباله (Garbage Collection) شیء وجود ندارد. تفاوت مهم دیگر این است که متد()Dispose به طور صریح توسط برنامهنویس فراخوانی میشود، در حالی که متد ()Finalize توسط جمعآوری کنندهی زباله (Garbage Collector) درست قبل از نابودی شیء فراخوانی میشود.
-
منظور از رفلکشن در C# چیست ؟
Reflection در #C به منظور استخراج «فراداده» (Metadata) از نوعهای داده، در حین زمان اجرا به کار میرود. برای اضافه کردن Reflection در فریم ورک NET.، میتوان به سادگی از فضای نام System.Refelction در برنامه استفاده کرد. بدین طریق، میتوان هر نوع خاصی از دادهها را بازیابی کرد. در ادامه انواع این دادههای قابل بازیابی فهرست شدهاند:
- اسمبلی (Assembly)
- ماژول (Module)
- نوع شمارشی (Enum)
- MethodInfo
- ConstructorInfo
- MemberInfo
- ParameterInfo
- نوع (Type)
- EventInfo
- PropertyInfo
منظور از سازنده در #C چیست؟
سازنده (Constructor) تابع عضوی (Member Function) در یک کلاس به حساب میآید که نام آن دقیقاً با نام آن کلاس یکسان است. زمانی که یک شی از کلاس ایجاد میشود، سازنده به صورت خودکار فراخوانی خواهد شد. همزمان با راهاندازی اولیه کلاس، مقادیر اعضای دادهها با استفاده از سازنده، ایجاد میشوند.
مسئلههای کدنویسی سوالات مصاحبه برنامه نویسی #C
در این قسمت با برخی از سوالات کدنویسی متداول برنامه نویسی #C در مصاحبه آشنا می شویم.
- چگونه ترتیب کلمات را در یک رشته معکوس کنیم؟
internal static void ReverseWordOrder(string str) { int i; StringBuilder reverseSentence = new StringBuilder(); int Start = str.Length - 1; int End = str.Length - 1; while (Start > 0) { if (str[Start] == ' ') { i = Start + 1; while (i <= End) { reverseSentence.Append(str[i]); i++; } reverseSentence.Append(' '); End = Start - 1; } Start--; } for (i = 0; i <= End; i++) { reverseSentence.Append(str[i]); } Console.WriteLine(reverseSentence.ToString()); }
- چگونه کاراکترهای تکراری را از یک رشته حذف کنیم؟
internal static void removeduplicate(string str) { string result = string.Empty; for (int i = 0; i < str.Length; i++) { if (!result.Contains(str[i])) { result += str[i]; } } Console.WriteLine(result); }
چگونه مجموع ارقام یک عدد صحیح مثبت را پیدا کنیم؟
internal static void SumOfDigits(int num) { int sum = 0; while (num > 0) { sum += num % 10; num /= 10; } Console.WriteLine(sum); }
چگونه یک آرایه یک بعدی را به یک آرایه دو بعدی تبدیل کنیم؟
internal static void SingleToMulti(int[] array, int row, int column) { int index = 0; int[,] multi = new int[row, column]; for (int y = 0; y < row; y++) { for (int x = 0; x < column; x++) { multi[y, x] = array[index]; index++; Console.Write(multi[y, x] + " "); } Console.WriteLine(); } }
جمعبندی
#C به عنوان یکی از چندمنظورهترین و قدرتمندترین زبانهای برنامهنویسی شناخته شده است و بنابراین برای مبتدیان و توسعهدهندگان باتجربه به طرز قابلتوجهی ضروری میباشد. این راهنما شامل سوالات مصاحبه #C است و فهرستی کامل از سوالات مصاحبه مرتبط با #C را ارائه میدهد که دامنه وسیعی از موضوعات مانند برنامهنویسی شیگرا (OOP)، فریمورکNET.، مدیریت استثناها و موارد دیگر را پوشش میدهد. چه شما تازهکار باشید و چه سالها تجربه داشته باشید، مرور این سوالات میتواند به شما کمک کند تا اعتماد به نفس بیشتری پیدا کرده و به طور مؤثری برای مصاحبه C# بعدیتان آماده شوید.