CodeGym /وبلاگ جاوا /Random-FA /بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه...
John Squirrels
مرحله
San Francisco

بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا. قسمت 10

در گروه منتشر شد
سلام! چند ساعت طول می کشد تا در چیزی استاد شوید؟ من اغلب چنین چیزی شنیده ام: "برای اینکه در هر کاری استاد شوید، باید 10000 ساعت را صرف آن کنید." این یک عدد ترسناک است، اینطور نیست؟ بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 10 - 1با این حال، من تعجب می کنم که آیا این حقیقت دارد. و من دائماً در تلاش هستم تا بفهمم چند ساعت برای تسلط بر هنر برنامه نویسی سرمایه گذاری کرده ام. و وقتی از آن خط ویژه 10000 ساعتی عبور کنم و استاد شوم، آیا تفاوت را احساس خواهم کرد؟ یا خیلی وقت پیش بدون اینکه متوجه باشم از آن خط گذشتم؟ در هر صورت، برای برنامه نویس شدن نیازی به صرف زمان زیادی ندارید. نکته مهم این است که از زمان خود عاقلانه استفاده کنید. هدف اصلی شما گرفتن مصاحبه است. و در مصاحبه‌ها، ابتدا از توسعه‌دهندگان نرم‌افزار در مورد تئوری سؤال می‌شود، بنابراین این باید یک نقطه قوت باشد. در واقع، همانطور که برای مصاحبه آماده می شوید، وظیفه شما این است که تمام شکاف های موجود در دانش تئوری پایه جاوا را کشف کنید و سپس آنها را پر کنید. امروز من اینجا هستم تا به شما در انجام این کار کمک کنم، زیرا امروز به بررسی محبوب ترین سوالات مصاحبه ادامه خواهیم داد. خب ادامه بدیم!

89. ArrayList چه تفاوتی با LinkedList دارد؟

این یکی از پرطرفدارترین سوالات به همراه سوال در مورد ساختار داخلی HashMap است . هیچ مصاحبه ای بدون آن کامل نمی شود، بنابراین پاسخ شما باید به راحتی از زبان شما خارج شود. علاوه بر بدیهیات (اسامی متفاوتی دارند)، در ساختار درونی آنها نیز متفاوت است. پیش از این، ساختار داخلی هر دو ArrayList و LinkedList را مورد بحث قرار دادیم ، بنابراین من به جزئیات اجرای آنها نمی پردازم. فقط به شما یادآوری می کنم که ArrayList با استفاده از یک آرایه داخلی که اندازه آن طبق این فرمول به صورت پویا افزایش می یابد پیاده سازی می شود:
<size of the current array> * 3 / 2 + 1
علاوه بر این، اجرای LinkedList از یک لیست داخلی با پیوند مضاعف استفاده می کند، یعنی هر عنصر به جز عناصر در ابتدا و انتهای لیست، ارجاعی به عناصر قبلی و بعدی دارد. مصاحبه کنندگان دوست دارند این سوال را به این صورت بپرسند، " ArrayList یا LinkedList کدام بهتر است ؟" به امید گرفتن تو به هر حال، اگر بگویید یکی یا دیگری بهتر است، پس جواب اشتباهی داده اید. بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 10 - 2در عوض، باید وضعیت خاصی را که در مورد آن صحبت می کنید، روشن کنید: دسترسی به عناصر با فهرست یا درج در وسط لیست. سپس با توجه به پاسخ آنها می توانید توضیح دهید که کدام یک بهتر است. قبلا توضیح دادم که ArrayList و LinkedList در هر موقعیتی چگونه کار می کنند. بیایید این را با قرار دادن آنها در یک ردیف برای مقایسه خلاصه کنیم: افزودن یک عنصر (افزودن)
  1. اگر نمایه ای مشخص نشده باشد، یک مورد جدید به طور خودکار برای هر دو نوع لیست به انتهای آن اضافه می شود. در LinkedList ، عنصر جدید به دنباله جدید تبدیل می شود (فقط یک جفت مرجع بازنویسی می شود، بنابراین پیچیدگی الگوریتمی O(1) است ).

    متد add یک عنصر را به آخرین سلول خالی آرایه ( O(1) ) اضافه می کند.

  2. افزودن یک مورد بر اساس نمایه معمولاً به معنای درج آن در جایی در وسط لیست است. در LinkedList ، متد ابتدا مکان مورد نظر را با تکرار بر روی عناصر از دم و سر ( O(n/2) ) جستجو می کند و سپس با بازنویسی ارجاعات عناصر در هر دو طرف آن مقدار را وارد می کند. عنصر جدید درج شده است ( O(1) ). پیچیدگی کلی الگوریتمی این عملیات O(n/2) خواهد بود .

    در شرایط مشابه (افزودن بر اساس شاخص)، یک ArrayList مکان مورد نظر ( O(1) ) را پیدا می کند و سپس تمام عناصر واقع شده به سمت راست (از جمله عنصری که قبلاً در نمایه مشخص شده ذخیره شده است) را به سمت راست یک به سمت راست تغییر می دهد. ممکن است نیاز به ایجاد یک آرایه داخلی جدید و کپی کردن عناصر در آن باشد) ( O(n/2) ). پیچیدگی کلی O(n/2) است .

  3. افزودن یک عنصر به ابتدای LinkedList مشابه افزودن یک عنصر به انتهای آن است: عنصر جدید به سر جدید تبدیل می شود ( O(1) ). اما برای یک ArrayList، این عملیات مستلزم حرکت تمام عناصر به سمت راست ( O(n) ) است.

نکته اصلی این است که برای LinkedList پیچیدگی الگوریتمی از O(1) تا O(n/2) متغیر است . مشاهده دیگر این است که هرچه درج به انتهای یا ابتدای لیست نزدیکتر باشد، سریعتر است. برای ArrayList ، پیچیدگی الگوریتمی از O(1) تا O(n) متغیر است و هرچه درج به انتهای لیست نزدیک‌تر باشد، سریع‌تر است. تنظیم یک عنصر (مجموعه) این عملیات یک عنصر را در موقعیت مشخص شده در لیست می نویسد و هر عنصر موجود را بازنویسی می کند. در LinkedList ، این عملیات شبیه به افزودن است، زیرا بزرگترین چالش در اینجا یافتن مکان عنصر است. عنصر موجود با به‌روزرسانی یک جفت مرجع بازنویسی می‌شود، بنابراین دوباره یک پیچیدگی الگوریتمی داریم که بسته به فاصله موقعیت مورد نظر از انتهای یا ابتدای لیست، از O(1) تا O(n/2) متغیر است. اما برای یک ArrayList ، این عملیات سلول مورد نظر را با شاخص پیدا می کند و عنصر جدید را در آنجا می نویسد. مانند عملیات مجموعه، جستجو بر اساس شاخص دارای پیچیدگی الگوریتمی O(1) است . دریافت یک عنصر بر اساس فهرست (get) دریافت یک عنصر از LinkedList از همان اصل جستجو پیروی می کند که در سایر عملیات استفاده می شود. پیچیدگی بستگی به فاصله از انتها یا ابتدا دارد، یعنی از O(1) تا O(n/2) متغیر است . همانطور که قبلا ذکر شد، برای ArrayList ، یافتن یک عنصر با شاخص در آرایه داخلی دارای پیچیدگی O(1) است . حذف یک عنصر با شاخص (حذف) برای LinkedList ، یک بار دیگر همین اصل اعمال می شود. ابتدا عنصر قرار می گیرد و سپس مراجع بازنویسی می شوند، همسایگان عنصر حذف شده اکنون به یکدیگر ارجاع می دهند و ارجاعات به عنصر حذف شده را حذف می کنند، که متعاقباً توسط جمع کننده زباله پاک می شود. به عبارت دیگر، پیچیدگی الگوریتمی همچنان یکسان است - از O(1) تا O(n/2) متغیر است . برای ArrayList ، این عملیات بیشتر شبیه افزودن یک عنصر جدید (افزودن) است. ابتدا، روش عنصر مورد نظر ( O(1) ) را پیدا می کند، آن را حذف می کند و سپس تمام عناصر واقع در سمت راست یک مرحله به چپ منتقل می شوند تا شکاف ایجاد شده توسط حذف بسته شود. حذف یک عنصر همان پیچیدگی الگوریتمی عملیات افزودن را دارد - از O(1) تا O(n). هر چه عنصر حذف شده به انتهای لیست نزدیکتر باشد، پیچیدگی الگوریتمی این عملیات کمتر می شود. و اکنون ما تمام عملیات اصلی را پوشش داده ایم. اجازه دهید به شما یادآوری کنم که هنگام مقایسه این دو نوع لیست، باید موقعیت خاصی را که آنها در آن استفاده می‌شوند، روشن کنید.

90. یک ArrayList چه تفاوتی با HashSet دارد؟

اگر بتوانیم ArrayList و LinkedList را بر اساس عملیات به عمل مقایسه کنیم تا مشخص کنیم کدام یک بهتر است، انجام چنین مقایسه ای بین ArrayList و HashSet چندان آسان نخواهیم بود ، زیرا آنها مجموعه های کاملاً متفاوتی هستند. شما می توانید یک دسر را با دسر دیگری مقایسه کنید، اما مقایسه یک دسر و یک غذای خوش طعم یک چالش است - آنها به طرز دردناکی متفاوت هستند. با این حال، سعی می کنم به برخی از تفاوت های آنها اشاره کنم:
  • ArrayList رابط List را پیاده سازی می کند در حالی که HashSet رابط Set را پیاده سازی می کند .

  • ArrayList به شما امکان می دهد به یک عنصر بر اساس شاخص دسترسی داشته باشید: عملیات get دارای پیچیدگی الگوریتمی O(1) است ، اما HashSet فقط به شما امکان می دهد با تکرار به عنصر مورد نظر دسترسی داشته باشید که پیچیدگی الگوریتمی از O(1) تا O(n) را ایجاد می کند .

  • ArrayList اجازه می دهد تا عناصر تکراری. در یک HashSet ، همه عناصر منحصر به فرد هستند: هر تلاشی برای افزودن عنصری که قبلاً در HashSet وجود دارد با شکست مواجه می‌شود (موارد تکراری با هش کد بررسی می‌شوند، از این رو نام این مجموعه است).

  • ArrayList با استفاده از یک آرایه داخلی پیاده سازی می شود، اما HashSet با استفاده از HashMap داخلی پیاده سازی می شود .

  • ArrayList ترتیب درج عناصر را حفظ می کند، اما HashSet یک مجموعه نامرتب است و ترتیب عناصر را حفظ نمی کند.

  • ArrayList به هر تعداد از مقادیر تهی اجازه می دهد، اما شما فقط می توانید یک مقدار null را به HashSet اضافه کنید (در نهایت، عناصر باید منحصر به فرد باشند).

91. چرا جاوا این همه پیاده سازی آرایه پویا متفاوت دارد؟

این بیشتر یک سوال فلسفی است. همچنین می‌توانیم بپرسیم چرا آن‌ها این همه فناوری جدید و متنوع ارائه می‌کنند؟ برای آسودگی. و همین موضوع در مورد تعداد زیادی از پیاده سازی آرایه های پویا صادق است. هیچ کدام را نمی توان بهترین یا ایده آل ترین پیاده سازی نامید. هر کدام مزایای خود را در موقعیت های خاص دارد. وظیفه ما این است که تفاوت ها و نقاط قوت / ضعف آنها را بشناسیم تا بتوانیم از مجموعه ای که برای هر موقعیتی مناسب تر است استفاده کنیم.

92. چرا جاوا این همه پیاده سازی ذخیره سازی کلید-مقدار مختلف دارد؟

در اینجا وضعیت مانند اجرای آرایه پویا است. قطعاً هیچ‌یک وجود ندارد که به طور کلی بهتر از دیگران باشد: هر کدام نقاط قوت و ضعفی دارند. و البته ما باید از نقاط قوت آنها نهایت استفاده را ببریم. مثال: بسته همزمان، که دارای کلاس های چند رشته ای بسیاری است، مجموعه های همزمان خود را دارد . کلاس ConcurrentHashMap نسبت به HashMap استاندارد از نظر ایمنی هنگام کار با داده ها در یک محیط چند رشته ای یک مزیت دارد، اما این به قیمت عملکرد کندتر است . و پیاده سازی هایی که در هر شرایطی بهترین انتخاب نیستند، به تدریج استفاده نمی شوند. به عنوان مثال: Hashtable که در ابتدا در نظر گرفته شده بود تا یک HashMap ایمن باشد ، فراموش شده و از استفاده خارج شده است، زیرا ConcurrentHashMap هنگام کار در یک محیط چند رشته ای حتی بهتر از Hashtable است.

93. چگونه مجموعه ای از عناصر را مرتب کنم؟

اولین چیزی که باید بگوییم این است که کلاسی که عناصر مجموعه را نشان می دهد باید رابط Comparable را پیاده سازی کند که از متد compareTo تشکیل شده است . یا به کلاسی نیاز دارید که رابط Comparator را پیاده سازی کند، از جمله روش مقایسه آن . هر دو روش نحوه مقایسه اشیاء از یک نوع معین را نشان می دهند. این هنگام مرتب‌سازی بسیار مهم است، زیرا الگوریتم مرتب‌سازی باید بفهمد که از چه اصل برای مقایسه عناصر استفاده کند. این کار عمدتاً با پیاده سازی Comparable به طور مستقیم در کلاسی که می خواهید مرتب کنید انجام می شود. استفاده از Comparator کمتر رایج است. فرض کنید از یک کلاس از یک کتابخانه استفاده می کنید و Comparable را پیاده سازی نمی کند ، اما باید مجموعه ای از اشیاء آن را مرتب کنید. از آنجایی که نمی توانید کد این کلاس را تغییر دهید (به جز با گسترش آن)، می توانید یک پیاده سازی از Comparator بنویسید که نحوه مقایسه اشیاء کلاس را نشان می دهد. و یک مثال دیگر. اگر نیاز دارید که اشیاء از یک نوع را به روش‌های مختلف مرتب کنید، می‌توانید چندین پیاده‌سازی Comparator را برای استفاده در موقعیت‌های مختلف بنویسید. به عنوان یک قاعده، بسیاری از کلاس های خارج از جعبه، به عنوان مثال String ، از قبل رابط Comparable را پیاده سازی می کنند . این بدان معناست که شما نیازی به نگرانی در مورد نحوه مقایسه این کلاس ها ندارید. شما فقط می توانید جلو بروید و از آنها استفاده کنید. اولین و واضح ترین راه استفاده از کلاس TreeSet یا TreeMap است . این کلاس ها عناصر را به ترتیب مرتب شده بر اساس مقایسه کننده پیاده سازی شده توسط عناصر کلاس ذخیره می کنند. فراموش نکنید که TreeMap کلیدها را مرتب می کند، نه مقادیر. اگر از Comparator به جای Comparable استفاده می کنید ، باید یک شی Comparator را هنگام ایجاد مجموعه به سازنده آن ارسال کنید:
TreeSet treeSet = new TreeSet(customComparator);
اما اگر نوع متفاوتی از مجموعه داشته باشید چه؟ چگونه آن را مرتب می کنید؟ در این مورد، راه دوم کلاس ابزار Collections - متد sort() - مناسب است. متد ثابت است، بنابراین تنها چیزی که نیاز دارید این است که نام کلاس را از قبل اضافه کنید و سپس در لیست قرار دهید تا مرتب شود. مثلا:
Collections.sort(someList);
اگر از پیاده سازی Comparator به جای Comparable استفاده می کنید ، باید آن را به عنوان آرگومان دوم ارسال کنید:
Collections.sort(someList, customComparator);
این عملیات ترتیب داخلی عناصر موجود در لیست ارسال شده را تغییر می دهد: لیست با استفاده از مقایسه کننده مرتب می شود. توجه داشته باشید که لیست ارسال شده باید قابل تغییر باشد، در غیر این صورت متد با شکست مواجه می شود و UnsupportedOperationException را پرتاب می کند . گزینه سوم استفاده از روش مرتب شده کلاس Stream است که عناصر مجموعه را مرتب می کند. اگر از Comparable استفاده می کنیم :
someList = someList.stream().sorted().collect(Collectors.toList());
اگر از Comparator استفاده می کنیم :
someList = someList.stream().sorted(customComparator).collect(Collectors.toList());
راه چهارم اجرای دستی یک الگوریتم مرتب سازی است، به عنوان مثال، مرتب سازی حباب یا مرتب سازی ادغام .

کلاس شی. برابر () و hashCode()

94. توضیح مختصری از کلاس Object در جاوا ارائه دهید.

در قسمت دوم بررسی، قبلاً در مورد متدهای کلاس Object بحث کردیم . در اینجا به شما یادآوری می کنم که کلاس Object اجداد هر کلاس در جاوا است. دارای 11 متد است که به نوبه خود توسط همه کلاس ها به ارث می رسد. بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 10 - 3

95. ()quals و hashCode() برای چه مواردی در جاوا استفاده می شود؟

hashCode() متدی از کلاس Object است که توسط همه کلاس ها به ارث می رسد. وظیفه آن تولید عددی است که نشان دهنده یک شی خاص باشد. نمونه‌ای از این روش در عمل را می‌توان در HashMap پیدا کرد، جایی که از روی اشیاء کلیدی فراخوانی می‌شود تا کد هش‌کد محلی را دریافت کند، که تعیین می‌کند جفت کلید-مقدار در کدام سطل (سلول آرایه داخلی) ذخیره شود. این روش به طور کلی در متد ()quals به عنوان یکی از راه های اصلی آن برای شناسایی اشیا استفاده می شود. () quals متدی از کلاس Object است که وظیفه آن مقایسه اشیاء و تعیین برابری آنهاست. این روش در هر جایی که نیاز به مقایسه اشیاء داشته باشیم استفاده می شود، زیرا عملگر استاندارد == برای اشیاء مناسب نیست، زیرا فقط مراجع اشیاء را با هم مقایسه می کند.

96. در مورد قرارداد بین ()quals و hashCode() در جاوا بگویید؟

ابتدا اجازه دهید بگویم برای اینکه متدهای ()quals و hashCode() به درستی کار کنند، باید به درستی override شوند. اجرای جدید آنها باید از این قوانین پیروی کند:
  • اشیاء یکسانی که برابر با آنها true است باید کدهای هش یکسانی داشته باشند.
  • اشیاء با کدهای هش یکسان لزوماً برابر نیستند.
اکنون مکان خوبی برای مکث تا قسمت بعدی بررسی به نظر می رسد!
بیشتر بخوانید:
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION