JavaRush /Java Blog /Random-TL /Pagsusuri ng mga tanong at sagot mula sa mga panayam para...

Pagsusuri ng mga tanong at sagot mula sa mga panayam para sa developer ng Java. Bahagi 4

Nai-publish sa grupo
Kumusta sa lahat, ngayon ay patuloy akong nagsusuri ng 250+ mga tanong sa panayam para sa developer ng Java. Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 1Mga nakaraang bahagi ng pagsusuri: una , pangalawa , pangatlo . Kaya't magpatuloy tayo.

29. Posible bang gumamit ng return sa isang constructor?

Maaari mo, ngunit wala ang return value sa kanan ng return . Iyon ay, maaari mong gamitin ang return; bilang isang pandiwang pantulong na konstruksyon sa panahon ng mga kalkulasyon sa konstruktor upang mapilit na tapusin (i-interrupt) ang pagpapatupad ng karagdagang code at kumpletuhin ang pagsisimula ng bagay. Halimbawa, mayroon kaming klase na Cat , at kung walang tahanan si Cat - isHomeless = true , kailangan naming tapusin ang pagsisimula at huwag punan ang iba pang mga field (pagkatapos ng lahat, hindi namin kilala ang mga ito, dahil ang pusa ay walang tirahan):
public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
Ngunit pagdating sa mga partikular na halaga, hindi maaaring gumamit ang isang tagabuo ng return upang ibalik ang isang halaga dahil:
  • kapag nagdedeklara ng isang constructor hindi ka magkakaroon ng anumang bagay na kahawig ng isang uri ng pagbabalik;
  • Karaniwan, ang constructor ay tinatawag na implicitly sa panahon ng instantiation;
  • Ang isang constructor ay hindi isang paraan: ito ay isang hiwalay na mekanismo na ang tanging layunin ay upang simulan ang mga variable ng instance, at ang bagong operator ay responsable para sa paglikha ng isang object .
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 2

30. Posible bang magtapon ng exception mula sa isang constructor?

Ang mga konstruktor ay nakikitungo sa mga pagbubukod sa eksaktong parehong paraan tulad ng mga pamamaraan. At kung ang mga pamamaraan ay nagpapahintulot sa amin na maghagis ng mga eksepsiyon sa pamamagitan ng pagsulat ng mga throws <ExceptionType> sa method header , kung gayon ang tagabuo ay nagpapahintulot sa amin na gawin ito, at gayundin kapag nagmana at nagtukoy ng isang tagapagmana na tagabuo, maaari naming palawakin ang uri ng pagbubukod. Halimbawa, IOException -> Exception (ngunit hindi vice versa). Bilang halimbawa para sa paghahagis ng exception ng isang constructor, kunin natin ang Cat class . Sabihin nating kapag nililikha ito, gusto nating ilagay ang pangalan at edad mula sa console:
public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
Dahil naghagis ang reader.readLine() ng IOException, tinukoy namin ito sa header bilang posibleng itinapon na exception.

31. Anong mga elemento ang binubuo ng header ng klase? Sumulat ng isang halimbawa

Sa pagsasalita tungkol sa mga elemento na bumubuo sa header ng klase, tingnan natin ang isang maliit na diagram:
  • Ang mga mandatoryong bahagi ay nasa mga bracket <>
  • opsyonal - sa {}
{class access modifier}{class staticity}{class finality}{class abstraction} <class name>{inheritance from Parent class} {implementation of interfaces} Итак, что мы имеем: {модификатор доступа класса} — для класса доступны лишь модификаторы public и отсутствующий модификатор доступа, то есть default. {статичность класса}static — модификатор, который указывает, что данный класс статичен, применим только к внутренним классам (классам внутри других классов). {финальность класса} — How мы помним, это модификатор final, при наличии которого класс стает не наследуемым (пример из коробки — String). {абстрактность класса} — модификатор — abstract, который указывает на то, что данный класс может иметь нереализованные методы. Этот модификатор конфликтует с модификатором final, то есть в заголовке класса может быть только один из них, так How модификатор abstract подразумевает, что данный класс будет унаследован и будут реализованы его абстрактные части. А final указывает на то, что это финальная (окончательная) version класса, и унаследован он быть не может. Собственно, одновременное использование обоих модификаторов будет абсурдным, и компилятор не даст нам этого сделать. <class> — ключевое обязательное слово, которое указывает на объявление класса. <Name класса> — простое Name класса, которое является идентификатором конкретного Java класса. Полное Name класса состоит из полного составного имени пакета + . + простое Name класса. {наследование от класса Родителя} — указание класса родителя (если таковой имеется) с помощью ключевого слова extends. Например, .. extends ParentClass. {реализация интерфейсов} — указание интерфейсов, которые данный класс реализует (если они имеются) с помощью ключевого слова implements. Например: … implements FirstInterface, SecondInterface… Ну и в качестве примера заголовка класса рассмотрим заголовок класса Lion, который наследуется от Cat и реализует интерфейс WildAnimal:
public final class Lion extends Cat implements WildAnimal
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 3

32. Из Howих элементов состоит заголовок метода? Напишите пример

Опять же, при рассмотрении элементов, из которых состоит заголовок метода, рассмотрим небольшую схему, в которой:
  • обязательные составляющие —в скобках <>
  • необязательные — в {}
{модификатор доступа}{статичность метода}{абстрактность метода}{финальность метода}{модификатор синхронизации} {модификатор native}<возвращаемое meaning><Name метода> <(> {аргументы метода} <)>{бросаемые исключения} {модификатор доступа} — для метода доступны все модификаторы доступа — public, protected, default, private. {статичность метода}static — модификатор, который указывает, что данный метод статичен, то есть привязан не к an objectу, а к классу. {абстрактность метода} — модификатор abstract, который указывает на то, что реализация (тело) метода отсутствует. Для корректной работы также нужен модификатор abstract у класса, в котором приведен метод. Как и в заголовке класса, данный модификатор конфликтует с модификатором final, но помимо него конфликтует и с модификатором static, т.к. абстрактный метод подразумевает переопределение метода в наследнике, а статические методы не переопределяются. {финальность метода}final — модификатор, указывающий на то, что данный метод нельзя переопределить. {модификатор синхронизации}synchronized — модификатор, который означает, что данный метод защищен от одновременного доступа к нему из разных потоков. Если метод не статический, он закрывается на мьютекc this an object. Если метод статический, он закрывается на мьютекс текущего класса. {модификатор native}native — данный модификатор указывает на то, что метод написан на другом языке программирования. <возвращаемое meaning> — тип значения, который должен вернуть метод. Если он не должен ничего возвращать — void. <Name метода> — Name метода, его идентификатор его в системе. {аргументы метода} — аргументы (параметры), которые принимает метод: они необходимы для реализации его функционала. {бросаемые исключения}throws ТипИсключения — перечисление проверяемых исключений, которые может бросать данный метод. И в качестве примера заголовка метода приведу этот:
public static void main(String[] args) throws IOException

33. Создайте в an objectе-наследнике конструктор по умолчанию, если в базовом он не определен (но определен другой конструктор)

Я не до конца понимаю сам вопрос, но возможно имеется в виду, что, к примеру, в родителе у нас есть некоторый кастомный конструктор:
public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
Поэтому в классе предке нам обязательно нужно определить конструктор, который будет заполнять (вызывать) родительский конструктор:
public  class Lion extends Cat {

   public Lion(int age, String name) {
       super(age, name);
   }
}
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 4

34. Когда применяется ключевое слово this?

В Java this используется в двух разных значениях. 1. Как link на текущий an object, типа this.age = 9. То есть this ссылается на an object, в котором была вызвана и к которому относится code, использующий this. Главная функция — повысить читабельность codeа и избежать неоднозначности. Например, при одинаковом имени внутреннего поля класса и аргумента метода:
public void setName(String name) {
   this.name = name;
}
То есть, this.name — поле an object name — аргумент метода Ссылка this не может использоваться в статических методах. 2. this можно применять в конструкторе в форме вызова метода, типа this(value). В таком случае это будет вызов другого конструктора этого же класса. Словом, можно вызвать сразу два конструктора при создании an object:
public Cat(int age, String name) {
   this(name);
   this.age = age;
}

public Cat(String name) {
   this.name = name;
}
При создании an object Cat и вызове первого конструктора будут вызваны оба поля an object и успешно проинициализированы. Есть пара нюансов:
  1. this() работает только в конструкторе.
  2. Ссылка на другой конструктор должна находиться в первой строке блока (тела) конструктора. Поэтому в одном конструкторе более одного (другого) конструктора данного класса вызвать нельзя.
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 5Больше примеров — в этой статье.

35. What такое инициализатор?

Насколько я понимаю, в данном вопросе речь идет об обычных и статистических блоках инициализации. Для начала давайте вспомним, что такое инициализация. Инициализация — это создание, активация, подготовка к работе, определение параметров. Приведение программы or компонента в состояние готовности к использованию. Как вы помните, во время создания an object переменную класса можно инициализировать непосредственно при объявлении:
class Cat {
   private int age = 9;
   private  String name = "Tom";
Или задавать извне через конструктор:
class Cat {
   private int age;
   private  String name;

   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
Но есть и ещё один способ: задавать внутреннюю переменную an object через блок инициализации, который имеет вид фигурных скобок { } внутри класса, без имени (How у метода or конструктора):
class Cat {
   private int age;
   private  String name;

   {
       age = 10;
       name = "Tom";
   }
То есть блок инициализации — это часть codeа, которая загружается при создании an object. Как правило такие блоки используются для выполнения некоторых сложных вычислений, которые необходимы при загрузке класса. Результаты этих вычислений можно задавать How значения для переменных. Также помимо обычных блоков инициализации существуют статические, которые выглядят так же, но перед фигурной скобкой имеют ключевое слово static:
class Cat {
   private static int age;
   private static String name;

   static{
       age = 10;
       name = "Tom";
   }
Этот блок в точности такой же, How и предыдущий. Но если обычный срабатывает при инициализации каждого an object, то статический отработает лишь однажды, при загрузке класса. В таком блоке, How правило, тоже производят некоторые сложные вычисления для последующей инициализации статических переменных класса. Для статического блока действуют те же ограничения, что и для статических методов: в нем нельзя использовать не статические данные, How и ссылку на текущий an object — this.Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 6Далее мы с вами можем увидеть порядок инициализации класса (вместе с его предком) для лучшего понимания момента, когда срабатывают блоки инициализации.

36. Для наследования класса public class Child extends Parent напишите порядок инициализации an object

При загрузке класса Child будет следующий порядок инициализации:
  1. Статические поля класса Parent.
  2. Статический блок инициализации класса Parent.
  3. Статические поля класса Сhild.
  4. Статический блок инициализации класса Child.
  5. Не статические поля класса Parent.
  6. Не статический блок инициализации класса Parent.
  7. Конструктор класса Parent.
  8. Не статические поля класса Сhild.
  9. Не статический блок инициализации класса Сhild.
  10. Конструктор класса Сhild.
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 7Вот небольшая статья, которая на практике объясняет порядок инициализации.

37. Какие вы знаете отношения между классами (an objectми)?

Между классами в Java есть два вида отношений:
  • отношения IS-A
Принцип IS-A в ООП основан на наследовании классов or реализации интерфейсов. К примеру, если класс Lion наследует Cat, мы говорим, что Lion является Cat:
Lion IS-A Cat
(но не всякий Cat является Lion-ом) Точно такая же ситуация с интерфейсами. Если класс Lion реализует интерфейс WildAnimal, то они также находятся в отношении:
Lion IS-A WildAnimal
  • отношения HAS-A
Данный тип отношений основан на использовании классов другими классами, ещё называемый “ассоциация”. Ассоциация — это один класс ссылается на другой класс (or даже друг на друга). Например, класс Car может ссылаться на класс Passenger, и это будет отношение:
Car HAS-A Passenger
И наоборот: если Passenger имеет ссылку на Car, то это будет отношение:
Passenger HAS-A Car

38. Какие ассоциативные связи между an objectми вы знаете?

Агрегация и композиция — не что иное, How частные случаи ассоциации. Агрегация — отношение, когда один an object является частью другого. Например, пассажир может находиться в машине. Также пассажиров может быть несколько or не быть вовсе (если мы говорим про теслу, то и водитель не обязателен). Например:
public class Car {
   private List passengers = new ArrayList<>();

 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }

   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Перевозка пассажира - " + passenger.toString());
       }
       passengers.clear();
   }
}
То есть нам не важно количество пассажиров (и есть ли они вообще): от этого функционал класса Car не зависит. Также агрегация подразумевает, что при использовании an object другим an objectом первый можно использовать еще в других an objectх. Например, один и тот же студент может входить и в кружок вязания, и в музыкальную группу рокеров, и при этом ходить в группу изучающих английских. Как вы поняли, агрегация — это более свободные ассоциативные отношения классов.Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 8Композиция — еще более жесткое отношение, когда an object не только является частью другого an object, но и работа другого an object очень зависит от первого. Например, двигатель у машины. Хоть двигатель и может быть без машины, но вне ее он бесполезен. Ну и машина не может работать без двигателя:
public class Car {
   private Engine engine;

   public Car(Engine engine) {
       this.engine = engine;
   }

   void startMoving() {
       engine.start();
           ...
   }
Также композиция подразумевает, что при использовании an object другим an objectом первый не может принадлежать кому-либо другому. Если вернуться к нашему примеру, двигатель может принадлежать только одной машине, но ниHow не двум or более одновременно. На этом сегодня, пожалуй, и сделаем остановочку.Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 4 - 9
Другие материалы серии:
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION