JavaRush /Java блогы /Random-KK /Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жа...
Константин
Деңгей

Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау. 14-бөлім

Топта жарияланған
Отшашу! Әлем үнемі қозғалыста, ал біз үнемі қозғаламыз. Бұрын Java әзірлеушісі болу үшін аздап Java синтаксисін білу жеткілікті еді, ал қалғаны келетін. Уақыт өте келе Java әзірлеушісі болу үшін қажетті білім деңгейі, сондай-ақ талап етілетін білімнің төменгі жолағын жоғары көтеруді жалғастыратын бәсекелестік айтарлықтай өсті. Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  14 - 1 бөлімЕгер сіз шынымен де әзірлеуші ​​болғыңыз келсе, оны әдеттегідей қабылдап, сіз сияқты жаңадан бастағандар арасында ерекшелену үшін мұқият дайындалуыңыз керек. Бүгін біз не істейміз, атап айтқанда, біз 250+ сұрақты талдауды жалғастырамыз . Алдыңғы мақалаларда біз кіші деңгейдің барлық сұрақтарын қарастырдық, ал бүгін біз орта деңгей сұрақтарын қарастырамыз. Бұл 100% орта деңгейлі сұрақтар емес екенін атап өтсем де, сіз олардың көпшілігімен кіші деңгейдегі сұхбатта кездесе аласыз, өйткені дәл осындай сұхбаттарда сіздің теориялық базаңыз егжей-тегжейлі зерттеледі, ал орта деңгейдегі студент үшін сұрақтар оның тәжірибесін зерттеуге көбірек бағытталған. Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  14 - 2 бөлімБірақ, көп ұзамай, бастайық.

Орташа

Жалпы

1. Процедуралық/функционалдық бағдарламалаумен салыстырғанда OOP артықшылықтары мен кемшіліктері қандай?

Джуниордың сұрақтарын талдауда бұл сұрақ болды, мен оған жауап бердім. Бұл сұрақты және оның жауабын мақаланың осы бөлігіндегі 16 және 17 сұрақтардан іздеңіз .

2. Агрегацияның құрамнан айырмашылығы неде?

OOP-те an objectілер арасындағы өзара әрекеттестіктің бірнеше түрі бар, олар жалпы «Қарым-қатынасы бар» ұғымымен біріктірілген. Бұл қатынас бір an objectінің басқа an objectінің құрамдас бөлігі екенін көрсетеді. Сонымен бірге бұл қатынастың екі ішкі түрі бар: Құрам – бір an object басқа an objectіні жасайды және басқа an objectінің өмір сүру уақыты жасаушының өмір сүру уақытына байланысты. Агрегация – an object құрылыс процесінде басқа an objectіге сілтеме (көрсеткіш) алады (бұл жағдайда басқа an objectінің қызмет ету мерзімі жасаушының өмір сүру уақытына байланысты емес). Жақсырақ түсіну үшін нақты мысалды қарастырайық. Бізде белгілі бір автомобиль класы бар - Car , ол өз кезегінде түрдегі ішкі өрістерге ие - Қозғалтқыш және жолаушылар тізімі - List<Passenger> , сонымен қатар қозғалысты бастау әдісі бар - startMoving() :
public class Car {

 private Engine engine;
 private List<Passenger> passengers;

 public Car(final List<Passenger> passengers) {
   this.engine = new Engine();
   this.passengers = passengers;
 }

 public void addPassenger(Passenger passenger) {
   passengers.add(passenger);
 }

 public void removePassengerByIndex(Long index) {
   passengers.remove(index);
 }

 public void startMoving() {
   engine.start();
   System.out.println("Машина начала своё движение");
   for (Passenger passenger : passengers) {
     System.out.println("В машине есть пассажир - " + passenger.getName());
   }
 }
}
Бұл жағдайда Композиция Автомобиль мен Қозғалтқыш арасындағы байланыс болып табылады , өйткені автомобильдің өнімділігі қозғалтқыш an objectісінің болуына тікелей байланысты, өйткені қозғалтқыш = null болса, онда біз NullPointerException аламыз . Өз кезегінде қозғалтқыш машинасыз өмір сүре алмайды (бізге машинасыз қозғалтқыш не үшін керек?) және бір уақытта бірнеше машинаға тиесілі бола алмайды. Бұл дегеніміз, егер біз Car нысанын жойсақ, Engine нысанына бұдан былай сілтемелер болмайды және ол жақын арада қоқыс жинаушы арқылы жойылады . Көріп отырғаныңыздай, бұл қарым-қатынас өте қатал (күшті). Агрегация - бұл Автокөлік пен Жолаушы арасындағы байланыс , өйткені Автомобильдің өнімділігі Жолаушы түріндегі нысандарға және олардың санына ешқандай тәуелді емес . Олар көлікті қалдыра алады - removePassengerByIndex(Long index) немесе жаңаларын енгізе алады - addPassenger(Жолаушы жолаушы) , соған қарамастан автомобиль дұрыс жұмыс істей береді. Өз кезегінде, Passenger нысандары Car нысанынсыз өмір сүре алады . Түсінгеніңіздей, бұл композицияда көргеннен әлдеқайда әлсіз байланыс. Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  14 - 3 бөлімБірақ мұнымен бітпейді, бірігу арқылы екіншісімен байланысқан an objectінің сол уақытта басқа an objectілермен де берілген байланысы болуы мүмкін. Мысалы, сіз Java тілінің студенті ретінде бір уақытта ағылшын, OOP және логарифмдер курстарына тіркелдіңіз, бірақ сонымен бірге сіз олардың маңызды бөлігі емессіз, оларсыз қалыпты жұмыс істеу мүмкін емес (мысалы, ұстаз).

3. Сіз тәжірибеде қандай GoF үлгілерін қолдандыңыз? Мысалдар келтіріңіз.

Мен бұл сұраққа бұрын жауап бердім, сондықтан мен талдауға сілтеме қалдырамын , бірінші сұрақты қараңыз. Мен сондай-ақ дизайн үлгілері туралы тамаша алдау парағы мақаласын таптым , мен оны қолымда ұстауды ұсынамын.

4. Прокси an objectісі дегеніміз не? Мысалдар келтір

Прокси - нақты нысандардың орнына арнайы алмастырғыш нысандарды немесе басқаша айтқанда, прокси нысандарды ауыстыруға мүмкіндік беретін құрылымдық дизайн үлгісі. Бұл прокси нысандары бастапқы нысанға қоңырауларды тоқтатады, бұл қоңырау түпнұсқаға жіберілгенге дейін немесе кейін кейбір логиканы енгізуге мүмкіндік береді . Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  14 - 4 бөлімПрокси нысанды пайдалану мысалдары:
  • Қашықтағы прокси ретінде - жергілікті түрде ұсынылуы қажет қашықтағы нысан (басқа мекенжай кеңістігіндегі нысан) қажет болғанда пайдаланылады. Бұл жағдайда прокси қосылым жасауды, codeтауды, деcodeтауды және т.б. өңдейді, ал клиент оны жергілікті кеңістікте орналасқан бастапқы нысан сияқты пайдаланады.

  • Виртуалды прокси ретінде – ресурстарды көп қажет ететін нысан қажет болғанда қолданылады. Бұл жағдайда прокси нысаны әлі жоқ нақты нысанның кескіні сияқты қызмет етеді. Осы нысанға нақты сұраныс (әдіс шақыруы) жіберілгенде ғана бастапқы нысан жүктеледі және әдіс орындалады. Бұл тәсіл кешіктірілген инициализация деп те аталады; бұл өте ыңғайлы болуы мүмкін, себебі кейбір жағдайларда бастапқы нысан пайдалы болмауы мүмкін, содан кейін оны жасау үшін ешқандай шығын болмайды.

  • Қауіпсіздік проксиі ретінде - клиент құқықтарына негізделген кейбір нысанға кіруді басқару қажет болғанда пайдаланылады. Яғни, кіру құқығы жоқ клиент бастапқы нысанға кіруге әрекеттенсе, прокси оны ұстап алады және оған рұқсат бермейді.

Виртуалды проксидің мысалын қарастырайық: Бізде өңдеуші интерфейсі бар:
public interface Processor {
 void process();
}
Іске асыру тым көп ресурстарды пайдаланады, бірақ сонымен бірге ол қолданба іске қосылған сайын пайдаланылмауы мүмкін:
public class HiperDifficultProcessor implements Processor {
 @Override
 public void process() {
   // некоторый сверхсложная обработка данных
 }
}
Прокси класы:
public class HiperDifficultProcessorProxy implements Processor {
private HiperDifficultProcessor processor;

 @Override
 public void process() {
   if (processor == null) {
     processor = new HiperDifficultProcessor();
   }
   processor.process();
 }
}
Оны негізгі түрде іске қосайық :
Processor processor = new HiperDifficultProcessorProxy();
// тут тяжеловсеного оригинального an object, ещё не сущетсвует
// но при этом есть an object, который его представляет и у которого можно вызывать его методы
processor.process(); // лишь теперь, an object оригинал был создан
Мен көптеген фреймворктер прокси-serverді қолданатынын ескертемін, көктем үшін бұл негізгі үлгі (Көктем онымен ішке және сыртқа тігілген). Бұл үлгі туралы толығырақ мына жерден оқыңыз . Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  14 - 5 бөлім

5. Java 8-де қандай жаңалықтар жарияланды?

Java 8 ұсынған инновациялар келесідей:
  • Функционалдық интерфейстер қосылды, бұл қандай жануар екенін осы жерден оқыңыз .

  • Функционалдық интерфейстермен тығыз байланысты ламбда өрнектері олардың қолданылуы туралы толығырақ осы жерден оқыңыз .

  • Деректер жинақтарын ыңғайлы өңдеу үшін Stream API қосылды , толығырақ осы жерден оқыңыз .

  • Әдістерге сілтемелер қосылды .

  • Iterable интерфейсіне forEach() әдісі қосылды .

  • Java.time бумасында жаңа күн мен уақыт API қосылды , егжей-тегжейлі талдау осында .

  • Жақсартылған Concurrent API .

  • Нөлдік мәндерді дұрыс өңдеу үшін пайдаланылатын Қосымша қаптама класын қосу арқылы осы тақырып бойынша тамаша мақаланы осы жерден таба аласыз .

  • Интерфейстердің статикалық және әдепкі әдістерді пайдалану мүмкіндігін қосу (бұл іс жүзінде Java тілін бірнеше мұраға жақындатады), толығырақ осында .

  • Collection(removeIf(), spliterator()) сыныбына жаңа әдістер қосылды .

  • Java Core жүйесіне аздаған жақсартулар.

Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  14 - 6 бөлім

6. Жоғары когезия және төмен байланыс дегеніміз не? Мысалдар келтіріңіз.

Жоғары когезия немесе жоғары когезия - бұл белгілі бір сыныпта бір-бірімен тығыз байланысты және олардың мақсаты бойынша біріктірілген элементтерді қамтитын ұғым. Мысалы, User класындағы барлық әдістер пайдаланушы әрекетін көрсетуі керек. Сыныпта байланысы жоқ элементтер болса, оның үйлесімділігі төмен болады. Мысалы, электрондық пошта мекенжайын тексеру әдісін қамтитын Пайдаланушы сыныбы:
public class User {
private String name;
private String email;

 public String getName() {
   return this.name;
 }

 public void setName(final String name) {
   this.name = name;
 }

 public String getEmail() {
   return this.email;
 }

 public void setEmail(final String email) {
   this.email = email;
 }

 public boolean isValidEmail() {
   // некоторая логика валидации емейла
 }
}
Пайдаланушы класы пайдаланушының электрондық пошта мекенжайын сақтауға жауапты болуы мүмкін, бірақ оны тексеру немесе электрондық поштаны жіберу үшін емес. Сондықтан жоғары үйлесімділікке қол жеткізу үшін біз валидация әдісін бөлек утorталар класына ауыстырамыз:
public class EmailUtil {
 public static boolean isValidEmail(String email) {
   // некоторая логика валидации емейла
 }
}
Және біз оны қажетінше пайдаланамыз (мысалы, пайдаланушыны сақтамас бұрын). Төмен байланыстыру немесе төмен байланыстыру бағдарламалық модульдер арасындағы төмен өзара тәуелділікті сипаттайтын тұжырымдама. Негізінде, өзара тәуелділік - бұл біреуін өзгерту екіншісін өзгертуді қажет етеді. Екі класс, егер олар тығыз байланысты болса, күшті муфтаға (немесе тығыз байланыстыруға) ие. Мысалы, бір-біріне сілтемелерді сақтайтын және бір-бірінің әдістерін шақыратын екі нақты сынып. Біріктірілген сыныптарды дамыту және қолдау оңайырақ. Олар бір-бірінен тәуелсіз болғандықтан, оларды параллельді түрде әзірлеуге және сынауға болады. Сонымен қатар, оларды бір-біріне әсер етпестен өзгертуге және жаңартуға болады. Мықты байланысқан сыныптардың мысалын қарастырайық. Бізде бірнеше студенттік сынып бар:
public class Student {
 private Long id;
 private String name;
 private List<Lesson> lesson;
}
Онда сабақтар тізімі бар:
public class Lesson {
 private Long id;
 private String name;
 private List<Student> students;
}
Әр сабақта қатысушы студенттерге сілтеме бар. Керемет күшті ұстау, қалай ойлайсыз? Оны қалай азайтуға болады? Алдымен, студенттерде пәндер тізімі емес, олардың идентификаторларының тізімі бар екеніне көз жеткізейік:
public class Student {
 private Long id;
 private String name;
 private List<Long> lessonIds;
}
Екіншіден, сабақ сыныбына барлық оқушылар туралы білу қажет емес, сондықтан олардың тізімін толығымен жойайық:
public class Lesson {
 private Long id;
 private String name;
}
Осылайша, бұл әлдеқайда жеңіл болды және байланыс әлдеқайда әлсіреді, солай емес пе? Java әзірлеушісіне арналған сұхбаттардағы сұрақтар мен жауаптарды талдау.  14 - 7 бөлім

OOP

7. Java тілінде бірнеше мұраны қалай жүзеге асыруға болады?

Бірнеше мұрагерлік - бұл сынып бірнеше ата-аналық сыныптан қасиеттерді иелене алатын an objectіге бағытталған тұжырымдаманың ерекшелігі. Мәселе супер класста да, қосалқы сыныпта да бірдей қолтаңбасы бар әдістер болған кезде туындайды. Әдісті шақырған кезде компилятор қандай класс әдісін шақыру керектігін анықтай алмайды, тіпті басымдылыққа ие класс әдісін шақырғанда да. Сондықтан Java бірнеше мұраға қолдау көрсетпейді! Бірақ бұл жерде бір саңылау бар, ол туралы кейінірек айтатын боламыз. Жоғарыда айтқанымдай, Java 8 шығарылымымен интерфейстерге әдепкі әдістерге ие болу мүмкіндігі қосылды . Интерфейсті жүзеге асыратын сынып бұл әдісті жоққа шығармаса, онда бұл әдепкі енгізу пайдаланылады (дерексіз әдісті енгізу сияқты әдепкі әдісті қайта анықтау қажет емес). Бұл жағдайда бір сыныпта әртүрлі интерфейстерді жүзеге асыруға және олардың әдепкі әдістерін қолдануға болады. Мысал қарастырайық. Бізде әдепкі fly() әдісі бар флайер интерфейсі бар :
public interface Flyer {
 default void fly() {
   System.out.println("Я лечу!!!");
 }
}
Әдепкі walk() әдісімен жаяу жүргінші интерфейсі :
public interface Walker {
 default void walk() {
   System.out.println("Я хожу!!!");
 }
}
Swimmer интерфейсі, swim() әдісімен :
public interface Swimmer {
 default void swim() {
   System.out.println("Я плыву!!!");
 }
}
Енді мұның бәрін бір үйрек сыныбында жүзеге асырайық:
public class Duck implements Flyer, Swimmer, Walker {
}
Ал үйректің барлық әдістерін іске асырайық:
Duck donald = new Duck();
donald.walk();
donald.fly();
donald.swim();
Консольде біз мыналарды аламыз:
Мен барып жүрмін!!! Мен ұшамын!!! Мен жүземін!!!
Бұл біз бірнеше мұраны дұрыс бейнелегенімізді білдіреді, дегенмен бұл олай емес. Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 14 - 8Сондай-ақ, егер сынып осы әдістерде бірдей әдіс атаулары және бірдей дәлелдері бар әдепкі әдістермен интерфейстерді жүзеге асырса, онда компилятор сәйкессіздікке шағымдана бастайды, өйткені ол шын мәнінде қандай әдісті қолдану керектігін түсінбейді. Шығудың бірнеше жолы бар:
  • Интерфейстердегі әдістерді бір-бірінен ерекшеленетіндей етіп қайта атаңыз.
  • Іске асыру сыныбында осындай даулы әдістерді қайта анықтаңыз.
  • Осы қарама-қайшылықты әдістерді жүзеге асыратын сыныптан мұра алыңыз (сонда сіздің сынып оны жүзеге асыруды дәл пайдаланады).

8. Final, finally және finalize() әдістерінің айырмашылығы неде?

финал — классқа, әдіске немесе айнымалыға шектеу қою үшін қолданылатын кілт сөз, шектеу мағынасы:
  • Айнымалы үшін - бастапқы инициализациядан кейін айнымалы мәнді қайта анықтау мүмкін емес.
  • Әдіс үшін әдісті ішкі сыныпта (ізбасар класында) қайта анықтау мүмкін емес.
  • Класс үшін - сыныпты мұраға алуға болмайды.
finally - code блогының алдындағы кілт сөз, ерекше жағдайларды өңдеу кезінде try блогымен бірге және catch блогымен бірге (немесе өзара ауыстырылады). Бұл блоктағы code ерекше жағдайдың шығарылғанына немесе тасталмағанына қарамастан, кез келген жағдайда орындалады. Мақаланың осы бөлігінде 104 сұрақта осы блок орындалмайтын ерекше жағдайлар талқыланады. finalize() - әрбір нысанды қоқыс жинаушы жоймас бұрын шақырылатын Object сыныбының әдісі , бұл әдіс (соңғы) деп аталады және бос тұрған ресурстарды тазалау үшін пайдаланылады. Әрбір нысан иеленетін Object класының әдістері туралы қосымша ақпаратты мақаланың осы бөлігіндегі 11-сұрақты қараңыз. Жарайды, бүгінгі жұмысымызды осымен аяқтаймыз. Келесі бөлімде кездескенше! Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 14 - 9
Сериядағы басқа материалдар:
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION