JavaRush /وبلاگ جاوا /Random-FA /تجزیه و تحلیل پرسش و پاسخ از مصاحبه برای توسعه دهنده جاوا...

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

در گروه منتشر شد
سلام دنیا! ادامه توسعه برای هر توسعه دهنده ای بسیار مهم است. به هر حال، اگر متوقف شوید، خطر بی ادعا شدن و خروج کامل از بازار وجود دارد: دنیای فناوری اطلاعات دائما در حال توسعه و پیشرفت است، و شما باید با آن حرکت کنید. اما حتی در عین حال، نمی توان تنها بر فناوری های جدید و تازه تمرکز کرد تا به اصطلاح کلاسیک ها (موضوعات کلاسیک) را فراموش نکنید. امروز می خواهم به تجزیه و تحلیل سوالات خود در مورد موضوعات "کلاسیک" برای یک توسعه دهنده جاوا ادامه دهم. تجزیه و تحلیل پرسش و پاسخ از مصاحبه برای توسعه دهنده جاوا.  قسمت 6 - 1متذکر می شوم که پاسخ های من مرجع نهایی نیستند - من پاسخ های صحیح به این سوالات را اینگونه می بینم و ممکن است شما با برخی از آنها موافق نباشید. این کاملاً طبیعی خواهد بود، بنابراین در نظرات خود را به اشتراک بگذارید. لینک بخش هایی از تجزیه و تحلیل در انتهای مقاله موجود است.تجزیه و تحلیل پرسش و پاسخ از مصاحبه برای توسعه دهنده جاوا.  قسمت 6 - 2

کتابخانه ها و استانداردها

52. Hibernate چیست؟ تفاوت بین JPA و Hibernate چیست؟

من فکر می کنم برای پاسخ به این سوال، ابتدا باید بفهمیم JPA چیست . JPA مشخصاتی است که نگاشت شی-رابطه ای اشیاء ساده جاوا را توصیف می کند و یک API برای ذخیره، بازیابی و دستکاری چنین اشیایی ارائه می دهد. یعنی همانطور که به یاد داریم پایگاه های داده رابطه ای (DB) در قالب جداول به هم پیوسته زیادی ارائه می شوند. و JPA یک استاندارد به طور گسترده پذیرفته شده است که نحوه تعامل اشیاء با پایگاه داده های رابطه ای را توصیف می کند. همانطور که می بینید، JPA چیزی انتزاعی و ناملموس است. این مانند خود ایده، رویکرد است. تجزیه و تحلیل پرسش و پاسخ از مصاحبه برای توسعه دهنده جاوا.  قسمت 6 - 3در عین حال، Hibernate یک کتابخانه خاص است که پارادایم های JPA را پیاده سازی می کند . یعنی با کمک این کتابخانه می توانید از طریق اشیایی که داده های پایگاه داده (Entity) را نشان می دهند، با یک پایگاه داده رابطه ای کار کنید. همانطور که می گویند این کتابخانه بسیار به ایده آل های JPA نزدیک است و شاید به همین دلیل محبوب شده است. و همانطور که می دانید، محبوبیت استفاده استدلال خوبی برای توسعه و پیشرفت بیشتر است. علاوه بر این، در پشت استفاده مکرر از آن یک جامعه بزرگ وجود دارد که قبلاً تمام سؤالات ممکن و غیرممکن مربوط به این ابزار را مرتب کرده است. در اینجا نمونه ای از کتابی است که تمام زوایای تاریک این فناوری را با جزئیات بررسی می کند. یعنی Hibernate تا حد امکان مورد مطالعه قرار گرفته است و معلوم است که قابل اعتماد است. در واقع، بی جهت نیست که حتی اجرای ایده آل JPA در سمت Spring معمولاً از Hibernate در زیر هود استفاده می کند.

53. آبشاری چیست؟ چگونه در Hibernate استفاده می شود؟

همانطور که قبلاً گفتم، در Hibernate ارتباطات از طریق اشیاء داده ای به نام entities انجام می شود . این موجودیت ها نشان دهنده برخی جداول خاص در پایگاه داده هستند و همانطور که به یاد دارید، کلاس های جاوا می توانند ارجاعاتی به کلاس های دیگر داشته باشند. این روابط در پایگاه داده منعکس می شود. در یک پایگاه داده، به عنوان یک قاعده، اینها یا کلیدهای خارجی (برای OneToOne، OneToMany، ManyToOne) یا جداول میانی (برای ManyToMany) هستند. می توانید در این مقاله درباره رابطه بین موجودیت ها بیشتر بخوانید . هنگامی که موجودیت شما پیوندهایی به سایر موجودیت های مرتبط دارد، حاشیه نویسی در بالای این پیوندها قرار می گیرد تا نوع اتصال را نشان دهد: @OneToOne، @OneToMany، @ManyToOne، @ManyToMane، که در پارامترهای آنها می توانید مقدار ویژگی - cascade - را مشخص کنید. نوع آبشار برای این اتصال. JPA روش‌های خاصی برای تعامل با موجودیت‌ها (تداوم، ذخیره، ادغام...) دارد . انواع آبشاری دقیقاً برای نشان دادن نحوه رفتار داده های مرتبط هنگام استفاده از این روش ها در موجودیت هدف استفاده می شود. بنابراین، استراتژی های آبشاری (انواع آبشاری) چیست؟ استاندارد JPA به استفاده از شش نوع آبشاری اشاره دارد:
  • PERSIST - عملیات ذخیره به صورت آبشاری (برای متدهای save() و persist() رخ خواهد داد . یعنی اگر موجودی مرتبط با سایر موجودیت ها را ذخیره کنیم، آنها نیز در پایگاه داده ذخیره می شوند (اگر قبلاً وجود نداشته باشند)

  • MERGE - عملیات به روز رسانی به صورت آبشاری (برای روش merge() ) رخ می دهد.

  • REMOVE - عملیات حذف در آبشار ( روش remove() ) رخ می دهد.

  • ALL - شامل سه عملیات آبشاری به طور همزمان - PERSIST - MERGE - REMOVE

JPA مفهوم یک موجودیت پایدار را دارد - یک موجودیت مرتبط با داده های آن در پایگاه داده، که توسط جلسه فعلی (اتصال) کنترل می شود . اگر آن را تغییر دهید، اما تغییرات را در پایگاه داده ذخیره نکنید، داده های آن در پایگاه داده همچنان تغییر می کند.
  • نهادهای مرتبط با DETACH توسط جلسه ( روش detach() ) مدیریت نخواهند شد. یعنی زمانی که آنها تغییر می کنند، هیچ تغییر خودکاری در داده های آنها در پایگاه داده ایجاد نمی شود - آنها از حالت ماندگاری به حالت جدا منتقل می شوند (موجودی که توسط JPA مدیریت نمی شود)

  • REFRESH - هر بار که یک موجودیت با داده های پایگاه داده به روز می شود ( refresh() - اشیاء جدا شده را به روز می کند)، موجودیت های مرتبط به همان روش به روز می شوند. به عنوان مثال، شما به نوعی داده های گرفته شده از پایگاه داده را تغییر داده اید و می خواهید مقادیر اصلی آن را برگردانید. در این صورت این عملیات برای شما مفید خواهد بود.

تجزیه و تحلیل پرسش و پاسخ از مصاحبه برای توسعه دهنده جاوا.  قسمت 6 - 4Hibernate از تمام این عملیات آبشاری استاندارد پشتیبانی می کند، اما سه مورد از خود را نیز معرفی می کند:
  • RePLICATE - زمانی استفاده می شود که بیش از یک منبع داده داریم و می خواهیم داده ها همگام شوند (روش Hibernate - Replicate). همه موجودیت ها باید شناسه (id) داشته باشند تا مشکلی در تولید آنها وجود نداشته باشد (به طوری که یک موجودیت شناسه های مختلف برای پایگاه داده های مختلف نداشته باشد)

  • SAVE_UPDATE - ذخیره/حذف آبشاری (برای روش Hibernate - saveOrUpdate )

  • LOCK عملیات معکوس به DETACHED است : موجودیت جدا شده را به حالت پایداری ، یعنی. نهاد دوباره توسط جلسه فعلی ردیابی می شود

اگر نوع آبشاری انتخاب نشود، هیچ عملیاتی بر روی یک موجودیت تأثیری بر سایر موجودیت‌های مرتبط با آن نخواهد داشت.

54. آیا یک کلاس Entity می تواند انتزاعی باشد؟

در مشخصات JPA در پاراگراف 2.1، کلاس Entity یک خط وجود دارد: " کلاس انتزاعی و ملموس می توانند موجودیت باشند ." بنابراین پاسخ این است که بله، یک کلاس انتزاعی می تواند یک موجودیت باشد و می تواند با @Entity حاشیه نویسی شود.

55. مدیر نهاد چیست؟ او مسئول چه چیزی است؟

اول از همه، من می خواهم توجه داشته باشم که EntityManager یکی از اجزای کلیدی JPA است که برای تعامل موجودیت ها با پایگاه داده استفاده می شود. به طور کلی، روش‌های تعامل بین موجودیت و پایگاه داده را فراخوانی می‌کند (ماندگاری، ادغام، حذف، جدا کردن)... اما همچنین باید توجه داشته باشم که این مؤلفه، به عنوان یک قاعده، برای کل برنامه کاربردی نیست: اغلب اوقات سبک است و اغلب حذف می شود و یک مورد جدید با استفاده از EntityManagerFactory ایجاد می شود . اگر یک موازی با JDBC ترسیم کنیم ، جایی که EntityManagerFactory آنالوگ DataSource خواهد بود ، EntityManager نیز به نوبه خود، آنالوگ Connection خواهد بود . قبلاً به یک موجودیت پایدار اشاره کردم ، به عنوان موجودی که توسط اتصال فعلی کنترل می شود. بنابراین: این نهاد دقیقاً توسط EntityManager که ارتباط نزدیکی با اتصال فعلی دارد و TransactionManager که مسئولیت باز کردن/بستن تراکنش ها را بر عهده دارد مدیریت می شود. بیشتر در شکل زیر می توانید چرخه حیات یک موجودیت را مشاهده کنید: Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 5EntityManager زمانی که موجودیت در مرحله Managed باشد آن را مدیریت می کند (در این زمان پایدار است، زیرا با EntityManager ارتباط دارد). یعنی دیگر جدید نیست و هنوز حذف نشده است. می توان گفت که وقتی یک موجود جدید یا حذف شده است، آن نیز جدا می شود، زیرا توسط EntityManager مدیریت نمی شود. استراتژی های مختلفی برای EntityManager وجود دارد. یعنی می‌توان یک EntityManager تک‌تنه برای کل برنامه وجود داشته باشد، یا هر بار برای هر اتصال، یک EntityManager جدید ایجاد شود. اگر از Spring استفاده می‌کنید، ایجاد/حذف EntityManager به‌طور خودکار در زیر هود کنترل می‌شود (اما این بدان معنا نیست که نمی‌توانید آن را سفارشی کنید ^^). شایان ذکر است که یک یا چند EntityManager زمینه پایداری را تشکیل می دهند . زمینه ماندگاری محیطی است که در آن نمونه‌های موجودیت‌ها با موجودیت‌های مشابه در پایگاه داده همگام‌سازی می‌شوند (همانطور که گفتم، این فقط برای موجودیت‌های پایدار کار می‌کند). اگر عمیق‌تر به JPA بپردازید (که من به شدت توصیه می‌کنم)، معمولاً با این مفاهیم روبرو خواهید شد.

56- کلاس Assert چیست؟ چرا از آن استفاده کنید؟

من در مورد چنین کلاسی در JPA نشنیده ام ، بنابراین فرض می کنم که این به کلاس JUnit کتابخانه مربوط می شود که برای تست واحد کد استفاده می شود. کلاس این کتابخانه، Assert ، برای بررسی نتایج اجرای کد استفاده می شود . به عنوان مثال، شما در حال آزمایش روشی هستید که باید یک گربه ایجاد کند. شما یک روش را اجرا می کنید و نتیجه می گیرید:
Cat resultOfTest = createCat();
اما باید مطمئن شوید که درست ایجاد شده است، درست است؟ بنابراین، شما قبلاً یک cat خاص - expectedCat - را به صورت دستی با پارامترهایی که از cat بدست آمده از متد ()createCat انتظار دارید ایجاد کرده اید . در مرحله بعد، از کلاس Assert برای تأیید نتایج استفاده می کنید :
Assert.assertEquals(resultOfTest, expectedCat);
اگر گربه ها متفاوت باشند، یک استثنای AssertionError ایجاد می شود که به ما می گوید نتایج مورد انتظار همگرا نیستند. کلاس Assert روش‌های مختلفی دارد که بسیاری از وظایف تأیید نتایج مورد انتظار را پوشش می‌دهد. در اینجا به برخی از آنها اشاره می کنیم:
  • assertTrue(<boolean>) - مقدار مورد انتظار دریافت شده به عنوان آرگومان باید درست باشد

  • assertFalse(<boolean>) - مقدار مورد انتظار دریافت شده به عنوان آرگومان باید نادرست باشد

  • assertNotEquals(<object1>، <object2>) - اشیاء دریافت شده به عنوان آرگومان باید در مقایسه با برابر با ( نادرست ) متفاوت باشند.

  • assertThrows(<ClassNameOfException>.class، <exceptionObject>) - انتظار می رود آرگومان دوم یک استثنا از کلاس مشخص شده توسط آرگومان اول باشد (یعنی به عنوان یک قاعده، به جای آرگومان دوم، متدی فراخوانی می شود که باید یک استثنا از نوع مورد نیاز را پرتاب کنید)

رشته

57. مشخص کردن رشته در جاوا

String یک کلاس استاندارد در جاوا است که وظیفه ذخیره و دستکاری مقادیر رشته ها (توالی کاراکترها) را بر عهده دارد، یک کلاس تغییرناپذیر است (من قبلاً در مورد تغییرناپذیر نوشتم )، به عنوان مثال. داده های اشیاء این کلاس پس از ایجاد قابل تغییر نیستند. می‌خواهم فوراً متذکر شوم که کلاس‌های StringBuilder و StringBuffer دو کلاس تقریباً یکسان هستند با تنها تفاوت این که یکی از آنها برای استفاده در یک محیط چند رشته‌ای (StringBuffer) در نظر گرفته شده است. این کلاس ها مشابه String هستند، اما بر خلاف آن، قابل تغییر هستند . به این معنی که اشیاء، پس از ایجاد، اجازه می‌دهند رشته‌ای را که نشان می‌دهند بدون ایجاد یک شی جدید تغییر دهند. در واقع، متدها با متدهای استاندارد String متفاوت هستند و هدفشان رفع نیازهای تغییر رشته است (بیهوده نیست که آنها را سازنده می نامند). در این مقاله درباره String ، StringBuffer و StringBuilder بیشتر بخوانید .

58. راه های مختلف ایجاد یک شی String چیست؟ کجا ایجاد می شود؟

رایج ترین راه برای ایجاد یک رشته این است که به سادگی مقدار مورد نیاز خود را در دو براکت مشخص کنیم:
String str = "Hello World!";
همچنین می توانید این کار را مستقیماً از طریق new انجام دهید :
String str = new String("Hello World!");
می توانید رشته ای ایجاد کنید که از مجموعه ای از کاراکترها شروع می شود:
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
در نتیجه متد toString که روی برخی از شی اجرا می شود:
String str = someObject.toString();
مانند نتیجه هر روش دیگری، نمایش رشته ای را برمی گرداند. مثلا:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str =  reader.readLine();
همانطور که می دانید، راه های بسیار بسیار زیادی برای ایجاد یک رشته وجود دارد. هنگامی که یک شی String ایجاد می شود، در استخر رشته ذخیره می شود که در یکی از سوالات زیر در مورد آن با جزئیات بیشتر صحبت خواهیم کرد.

59. چگونه دو رشته را در جاوا مقایسه کنیم و چگونه آنها را مرتب کنیم؟

جاوا از علامت دو برابر == برای مقایسه مقادیر استفاده می کند . اگر نیاز به مقایسه چند مقدار ساده مانند int داشتیم ، از آن استفاده می کردیم. اما این روش برای مقایسه اشیاء تمام عیار قابل اجرا نیست. در این مورد، این فقط مقایسه مراجع خواهد بود - چه آنها به یک شی اشاره کنند یا نه. یعنی هنگام مقایسه دو شی با مقادیر میدان های داخلی دقیقاً یکسان، مقایسه از طریق == نتیجه نادرست می دهد : با وجود فیلدهای یکسان اشیاء، خود اشیا سلول های حافظه متفاوتی را اشغال می کنند. و اشیاء از کلاس String ، با وجود سادگی فریبنده، هنوز هم شی هستند. و مقایسه از طریق == نیز برای آنها قابل اجرا نیست (حتی با وجود وجود استخر رشته). در اینجا متد استاندارد کلاس Object وارد عمل می شود - برابر است ، که باید در کلاس override شود تا به درستی کار کند (در غیر این صورت، به طور پیش فرض با استفاده از == مقایسه می شود ). در کلاس String رد شده است ، بنابراین ما فقط آن را می گیریم و از آن استفاده می کنیم:
String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 6ما در مورد مقایسه‌های تطبیقی ​​صحبت کردیم، حالا بیایید مرتب‌سازی مقایسه‌ها را بررسی کنیم. از این گذشته، برای مرتب کردن چیزی باید بدانیم که بر اساس چه اصولی مرتب کنیم. برای انجام این کار، می توانید از یک مجموعه مرتب شده استاندارد - TreeSet استفاده کنید . در این مقاله می توانید اطلاعات بیشتری در مورد مجموعه های مختلف در جاوا بخوانید . این لیست بر اساس الگوریتم درخت قرمز-سیاه کار می کند و مجموعه را مطابق با اصل مرتب سازی مشخص شده مرتب می کند. همانطور که قبلاً گفتم، باید بدانید که چگونه اشیاء از یک نوع خاص را مرتب کنید. مقایسه کننده ها برای تنظیم روش مقایسه برای مرتب سازی استفاده می شوند . معمولاً اینها باید برای کلاس‌هایی که می‌خواهید مرتب کنید پیاده‌سازی شوند، اما در مورد String قبلاً پیاده‌سازی شده‌اند. بنابراین، ما به سادگی ردیف های مورد نیاز خود را به TreeSet اضافه می کنیم و آنها را مرتب می کنیم:
TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
خروجی کنسول:
A B C

60. الگوریتمی برای تبدیل رشته به کاراکتر ارائه دهید. کد مناسب را بنویسید

همانطور که قبلاً گفتم، اشیاء کلاس String متدهای مفید زیادی دارند. یکی از اینها toCharArray است . این روش یک رشته را به یک آرایه کاراکتری تبدیل می کند:
String str = "Hello world";
char[] charArr = str.toCharArray();
در مرحله بعد آرایه ای از کاراکترها را داریم که می توانیم آنها را با فهرست فراخوانی کنیم:
char firstChar = charArr[0]; // H

61. چگونه یک رشته را به آرایه بایتی تبدیل کنیم و برگردانیم؟ کد مناسب را بنویسید

مشابه متد toCharArray ، کلاس String یک متد getBytes دارد که یک آرایه بایتی از رشته را برمی‌گرداند:
String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
بخش امروز تحلیل به پایان منطقی خود رسیده است. با تشکر از توجه شما!Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 7
سایر مواد این سری:
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION