1358 просмотров
от 25 февраля 2024
Java

Вопросы и ответы с собеседований по Java

Вопросы и ответы с собеседований Java-разработчиков. Типы данных, предназначение JVM, объяснение bytecode, Reflection, модификаторы доступа, статические сущности, generics, Heap и Stack память, ООП в Java, сборка мусора и многое другое.

1

Какие типы данных в Java?

В Java существует 8 простых типов данных: 1. byte - 8-битное целое число со знаком (-128 до 127) 2. short - 16-битное целое число со знаком (-32,768 до 32,767) 3. int - 32-битное целое число со знаком (-2,147,483,648 до 2,147,483,647) 4. long - 64-битное целое число со знаком (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807) 5. float - 32-битное число с плавающей точкой (1.4E-45 до 3.4028235E+38) 6. double - 64-битное число с плавающей точкой (4.9E-324 до 1.7976931348623157E+308) 7. char - 16-битный символ Unicode ('\u0000' до '\uffff') 8. boolean - логическое значение (true или false) Также в Java есть объектные типы данных, которые являются экземплярами классов, и могут хранить некоторые данные и иметь методы. Объекты могут хранить данные разных типов, даже простых типов данных. Например, объект типа Integer может хранить целое число типа int. Разница между простыми типами данных и объектами заключается в способе хранения данных и доступе к ним. Простые типы данных хранятся в стеке, в то время как объекты - в куче. Объекты также могут иметь методы для обработки своих данных, тогда как простые типы данных этого не могут.

Комментарии
0/3000
2

Что такое JVM, JDK, JRE?

JVM, JDK и JRE - это три основных понятия в мире Java-разработки. JVM (Java Virtual Machine) - виртуальная машина Java , которая выполняет Java-байткод. Все программы на Java компилируются в байткод, который может быть выполнен на любой платформе, на которую установлена JVM. JDK (Java Development Kit) - это пакет разработчика Java , который включает в себя всё необходимое для разработки Java-приложений, включая компилятор javac, библиотеки классов, документацию, примеры кода и JVM. JRE (Java Runtime Environment) - это пакет для запуска Java-приложений, который включает в себя JVM, библиотеки классов и другие необходимые компоненты для запуска Java-приложений. Кратко говоря, если вы планируете разработку Java-приложений, то вам нужна JDK. Если же вы планируете только запускать Java-приложения, то вам достаточно установить JRE, которая включает в себя JVM.

Комментарии
0/3000
3

Зачем используют JVM?

JVM (виртуальная машина Java) — важнейший компонент языка программирования Java. Это абстрактная машина, предоставляющая среду выполнения, в которой может выполняться скомпилированный код Java. Вот несколько причин, почему JVM важна и широко используется в разработке программного обеспечения: 1. Переносимость: код Java можно написать один раз и запустить на любой платформе, на которой установлена ​​JVM, независимо от базового оборудования и операционной системы. Это делает Java-программы легко переносимыми и уменьшает количество кода, необходимого для конкретной платформы. 2. Управление памятью: JVM управляет распределением памяти и автоматически освобождает неиспользуемую память посредством сборки мусора. Это освобождает разработчиков от утомительной и чреватой ошибками задачи ручного управления памятью. 3. Безопасность. Поскольку JVM выполняет код Java в изолированной среде, это предотвращает причинение вреда базовой системе вредоносным кодом. Это делает Java популярным выбором для создания безопасных и надежных приложений. 4. Производительность: JVM создана для оптимизации выполнения кода Java и использует передовые методы, такие как своевременная компиляция, для достижения высокой производительности. В целом, JVM играет критическую роль в языке программирования Java, предоставляя многочисленные преимущества, которые делают его популярным выбором для создания надежных, безопасных и переносимых приложений.

Комментарии
0/3000
4

Что такое bytecode?

Java-программы компилируются в байт-код, который может быть распространен и загружен на любой машине, на которой установлено соответствующее окружение выполнения Java. После того, как байт-код загружается в виртуальную машину, он транслируется в машинный код и исполняется. Это позволяет программам Java быть переносимыми между различными платформами без необходимости перекомпилировать их на каждой платформе.

Комментарии
0/3000
5

Что такое Reflection?

Рефлексия (Reflection) - это механизм получения данных о программе во время её выполнения (runtime). В Java Reflection осуществляется с помощью Java Reflection API, состоящего из классов пакетов java.lang и java.lang.reflect. Возможности Java Reflection API: - Определение класса объекта; - Получение информации о модификаторах класса, полях, методах, конструкторах и суперклассах; - Определение интерфейсов, реализуемых классом; - Создание экземпляра класса; - Получение и установка значений полей объекта; - Вызов методов объекта; - Создание нового массива.

Комментарии
0/3000
6

Какие модификаторы доступа есть в Java?

1. private: члены класса доступны только внутри класса. 2. default, package-private, package level: видимость класса/членов класса только внутри пакета. Является модификатором доступа по умолчанию - специальное обозначение не требуется. 3. protected: члены класса доступны внутри пакета и в наследниках. 4. public: класс/члены класса доступны всем. Последовательность модификаторов по возрастанию уровня закрытости: public, protected, default, private. Во время наследования возможно изменения модификаторов доступа в сторону большей видимости (для поддержания соответствия принципу подстановки Барбары Лисков).

Комментарии
0/3000
7

Зачем нужен модификатор static?

static — модификатор, применяемый к полю, блоку, методу или внутреннему классу. Данный модификатор указывает на привязку субъекта к текущему классу.

Комментарии
0/3000
8

Что такое статический класс?

Это вложенный класс, объявленный с использованием ключевого слова static. К классам верхнего уровня модификатор static неприменим. По сути статический вложенный класс ничем не отличается от любого другого внутреннего класса за исключением того, что его объект не содержит ссылку на создавший его объект внешнего класса. Тем не менее, благодаря этому статический класс наиболее похож на обычный не вложенный, ведь единственное различие состоит в том, что он упакован в другой класс. В некоторых случаях для нас это преимущество, так как с него у нас есть доступ к приватным статическим переменным внешнего класса. Пример вложенного статического класса: public class Vehicle { public static class Car { public int km; } } Создание экземпляра данного класса и задание значения внутренней переменной: Vehicle.Car car = new Vehicle.Car(); car.km = 90; Для использования статических методов/переменных/класса нам не нужно создавать объект данного класса.

Комментарии
0/3000
9

Что такое статические поля?

При создании объектов класса для каждого объекта создается своя копия нестатических обычных полей. А статические поля являются общими для всего класса. Поэтому они могут использоваться без создания объектов класса. Например, создадим статическую переменную: public class Program{ public static void main(String[] args) { Person tom = new Person(); Person bob = new Person(); tom.displayId(); // Id = 1 bob.displayId(); // Id = 2 System.out.println(Person.counter); // 3 // изменяем Person.counter Person.counter = 8; Person sam = new Person(); sam.displayId(); // Id = 8 } } class Person{ private int id; static int counter=1; Person(){ id = counter++; } public void displayId(){ System.out.printf("Id: %d \n", id); } } Класс Person содержит статическую переменную counter, которая увеличивается в конструкторе и ее значение присваивается переменной id. То есть при создании каждого нового объекта Person эта переменная будет увеличиваться, поэтому у каждого нового объекта Person значение поля id будет на 1 больше чем у предыдущего. Так как переменная counter статическая, то мы можем обратиться к ней в программе по имени класса: System.out.println(Person.counter); // получаем значение Person.counter = 8; // изменяем значение Консольный вывод программы: Id = 1 Id = 2 3 Id = 8

Комментарии
0/3000
10

Что такое статические константы?

Также статическими бывают константы, которые являются общими для всего класса. public class Program{ public static void main(String[] args) { double radius = 60; System.out.printf("Radisu: %f \n", radius); // 60 System.out.printf("Area: %f \n", Math.PI * radius); // 188,4 } } class Math{ public static final double PI = 3.14; } Стоит отметить, что на протяжении всех предыдущих тем уже активно использовались статические константы. В частности, в выражении: System.out.println("hello"); out как раз представляет статическую константу класса System. Поэтому обращение к ней идет без создания объекта класса System.

Комментарии
0/3000
11

Что такое статические инициализаторы?

Статические инициализаторы предназначены для инициализации статических переменных, либо для выполнения таких действий, которые выполняются при создании самого первого объекта. Например, определим статический инициализатор: public class Program{ public static void main(String[] args) { Person tom = new Person(); Person bob = new Person(); tom.displayId(); // Id = 105 bob.displayId(); // Id = 106 } } class Person{ private int id; static int counter; static{ counter = 105; System.out.println("Static initializer"); } Person(){ id=counter++; System.out.println("Constructor"); } public void displayId(){ System.out.printf("Id: %d \n", id); } } Статический инициализатор определяется как обычный, только перед ним ставится ключевое слово static. В данном случае в статическом инициализаторе мы устанавливаем начальное значение статического поля counter и выводим на консоль сообщение. В самой программе создаются два объекта класса Person. Поэтому консольный вывод будет выглядеть следующим образом: Static initializer Constructor Constructor Id: 105 Id: 106 Стоит учитывать, что вызов статического инициализатора производится после загрузки класса и фактически до создания самого первого объекта класса.

Комментарии
0/3000
12

Что такое статические методы?

Статические методы также относятся ко всему классу в целом. Например, в примере выше статическая переменная counter была доступна извне, и мы могли изменить ее значение вне класса Person. Сделаем ее недоступной для изменения извне, но доступной для чтения. Для этого используем статический метод: public class Program{ public static void main(String[] args) { Person.displayCounter(); // Counter: 1 Person tom = new Person(); Person bob = new Person(); Person.displayCounter(); // Counter: 3 } } class Person{ private int id; private static int counter = 1; Person(){ id = counter++; } // статический метод public static void displayCounter(){ System.out.printf("Counter: %d \n", counter); } public void displayId(){ System.out.printf("Id: %d \n", id); } } Теперь статическая переменная недоступна извне, она приватная. А ее значение выводится с помощью статического метода displayCounter. Для обращения к статическому методу используется имя класса: Person.displayCounter(). При использовании статических методов надо учитывать ограничения: в статических методах мы можем вызывать только другие статические методы и использовать только статические переменные. Вообще методы определяются как статические, когда методы не затрагиют состояние объекта, то есть его нестатические поля и константы, и для вызова метода нет смысла создавать экземпляр класса. Например: public class Program{ public static void main(String[] args) { System.out.println(Operation.sum(45, 23)); // 68 System.out.println(Operation.subtract(45, 23)); // 22 System.out.println(Operation.multiply(4, 23)); // 92 } } class Operation { static int sum(int x, int y){ return x + y; } static int subtract(int x, int y){ return x - y; } static int multiply(int x, int y){ return x * y; } } В данном случае для методов sum, subtract, multiply не имеет значения, какой именно экземпляр класса Operation используется. Эти методы работают только с параметрами, не затрагивая состояние класса. Поэтому их можно определить как статические.

Комментарии
0/3000
13

Какие подводные камни есть у ключевого слова static?

1. Вы не можете получить доступ к нестатическим членам класса, внутри статического контекста, как вариант, метода или блока. Результатом компиляции приведенного ниже кода будет ошибка: public class Counter{ private int count; public static void main(String args[]){ System.out.println(count); //compile time error }} Это одна из наиболее распространённых ошибок, допускаемых программистами Java, особенно новичками. Так как метод main статичный, а переменная count - нет, в этом случае метод println внутри метода main выбросит “Compile time error”. 2. В отличие от локальных переменных статические поля и методы не потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая, что каждый экземпляр класса имеет одну и ту же копию статической переменной, такая переменная нуждается в защите — «залочивании» классом. Поэтому, при использовании статических переменных убедитесь, что они должным образом синхронизированы (synchronized) во избежание проблем, например, таких как «состояние гонки» (race condition). 3. Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый объект для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы как нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утилит (utility). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утилиты в Java финализированы (final). 4. Другим важным моментом является то, что вы не можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) вместо переопределения. Это явление известно как сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен как в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример: class Vehicle{ public static void kmToMiles(int km){ System.out.println("Внутри родительского класса/статического метода"); } } class Car extends Vehicle{ public static void kmToMiles(int km){ System.out.println("Внутри дочернего класса/статического метода "); } } public class Demo{ public static void main(String args[]){ Vehicle v = new Car(); v.kmToMiles(10); }} Вывод в консоль: "Внутри родительского класса/статического метода" Код наглядно демонстрирует: несмотря на то, что объект имеет тип Car, вызван статический метод из класса Vehicle, т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло! 5. Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны как «вложенные статические классы» (nested static class). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса — HashMap.Entry, который предоставляет структуру данных внутри HashMap. Стоит заметить, также как и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявили пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора (Comparator). Например, компаратор по возрасту (AgeComparator) в классе сотрудники (Employee). 6. Модификатор static также может быть объявлен в статичном блоке, более известном как «Статический блок инициализации» (Static initializer block), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок не может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике любое исключение, возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему. 7. Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных или не статических методов, которые связываются во время исполнения на реальном объекте. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности или необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утилиты хорошие образцы применения модификатора static. Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java», которая является обязательной для прочтения каждым программистом данного языка. 8. Важным свойством статического блока является инициализация. Статические поля или переменные инициализируются после загрузки класса в память. Порядок инициализации сверху вниз - в том же порядке, в каком они описаны в исходном файле Java класса. Поскольку статические поля инициализируются на потокобезопасный манер, это свойство также используется для реализации паттерна Singleton. Если вы не используется список Enum как Singleton по тем или иным причинам, то для вас есть хорошая альтернатива. Но в таком случае необходимо учесть, что это не «ленивая» инициализация. Это означает, что статическое поле будет проинициализировано ещё до того, как кто-нибудь об этом «попросит». Если объект ресурсоёмкий или редко используется, то инициализация его в статическом блоке сыграет не в вашу пользу. 9. Во время сериализации, также как и transient переменные, статические поля не сериализуются. Действительно, если сохранить любые данные в статическом поле, то после десериализации новый объект будет содержать его первичное (по-умолчанию) значение, например, если статическим полем была переменная типа int, то её значение после десериализации будет равно нулю, если типа float – 0.0, если типа Object – null. Честно говоря, это один из наиболее часто задаваемых вопросов касательно сериализации на собеседованиях по Java. Не храните наиболее важные данные об объекте в статическом поле! 10. static import. Данный модификатор имеет много общего со стандартным оператором import, но в отличие от него позволяет импортировать один или все статические члены класса. При импортировании статических методов к ним можно обращаться, как будто они определены в этом же классе. Аналогично при импортировании полей мы можем получить доступ без указания имени класса. Данная возможность появилась в Java версии 1.5 и при должном использовании улучшает читабельность кода. Наиболее часто данная конструкция встречается в тестах JUnit, т.к. почти все разработчики тестов используют static import для assert методов, например assertEquals() и для их перегруженных дубликатов.

Комментарии
0/3000
14

Что такое перегрузка методов?

Перегрузка метода (method overloading) в Java - это возможность определения нескольких методов с одним и тем же именем, но с разными параметрами. Компилятор определяет, какой из перегруженных методов нужно вызвать на основе типов аргументов, переданных в вызове. При определении перегруженных методов важно учитывать следующие правила: 1. Имена методов должны быть одинаковыми. 2. Число или тип параметров должны отличаться. 3. Тип возвращаемого значения может отличаться, но это не является обязательным условием. Например, рассмотрим следующий код для класса Calculator: public class Calculator { public int add(int a, int b) { return a + b; } public double add(double a, double b) { return a + b; } } В этом примере мы определили два метода add с одним и тем же именем, но с разными параметрами. Первый метод принимает два целых числа и возвращает их сумму, второй метод принимает два числа с плавающей точкой и также возвращает их сумму. При вызове метода add компилятор будет определять, какой метод нужно использовать, основываясь на типах аргументов. Например, если мы вызываем метод add с двумя целыми числами, то будет использован первый метод, который принимает два целых числа и возвращает целое число: Calculator calc = new Calculator(); int sum = calc.add(2, 3); Если бы мы вызывали метод add с двумя числами с плавающей точкой, то был бы использован второй метод, который принимает два числа с плавающей точкой и возвращает число с плавающей точкой: Calculator calc = new Calculator(); double sum = calc.add(2.5, 3.7); Перегрузка метода позволяет создавать более гибкий и удобный интерфейс для работы с классом, позволяя использовать одно имя метода для различных операций с разными типами данных.

Комментарии
0/3000
15

Что такое переопределение метода?

1

Переопределение метода (method overriding) в Java - это возможность заменить реализацию метода из базового класса (или интерфейса), который уже определен в производном классе, с тем же именем, списком аргументов и типом возвращаемого значения. Переопределение метода позволяет производному классу изменять поведение унаследованного метода без необходимости изменять его имя или сигнатуру. Для успешного переопределения метода нужно учитывать следующие правила: 1. Имя метода, список аргументов и тип возвращаемого значения должны быть точно такими же, как у метода в базовом классе (или интерфейсе). 2. Модификаторы доступа для переопределяемого метода должны быть такими же или менее строгими, чем в базовом классе (или интерфейсе). Например, если метод в базовом классе имеет модификатор доступа public, то метод в производном классе может иметь такой же модификатор или более ограничивающий модификатор доступа, например, protected или package-private. 3. Тип возвращаемого значения должен быть совместим с типом, указанным в базовом классе (или интерфейсе). Например, если метод в базовом классе возвращает объект типа Animal, то метод в производном классе должен также возвращать объект типа Animal или его производный класс. Рассмотрим следующий код для классов Animal и Cat: public class Animal { public void makeSound() { System.out.println("Animal is making a sound"); } } public class Cat extends Animal { @Override public void makeSound() { System.out.println("Meow!"); } } В этом примере мы переопределили метод makeSound из базового класса Animal в классе Cat. Метод makeSound в классе Animal выводит сообщение "Animal is making a sound", а метод makeSound в классе Cat выводит сообщение "Meow!". При вызове метода makeSound для экземпляра класса Cat будет использована переопределенная реализация метода, а не реализация из базового класса. Например, если мы создаем экземпляр класса Cat и вызываем его метод makeSound, то в консоль будет выведено сообщение "Meow!": Cat cat = new Cat(); cat.makeSound(); Переопределение метода позволяет производным классам изменять поведение унаследованных методов и адаптироваться к своим потребностям. Однако при переопределении методов нужно учитывать правила, чтобы избежать ошибок и неожиданного поведения программы.

Комментарии
0/3000
16

Как инициализируются переменные по умолчанию?

- Числа инициализируются 0 или 0.0; - char\u0000; - booleanfalse; - Объекты (в том числе String) — null.

Комментарии
0/3000
17

Что такое интерфейс?

Основное предназначение интерфейса - определять, каким образом мы можем использовать класс, который его реализует. Создатель интерфейса определяет имена методов, списки аргументов и типы возвращаемых значений, но не реализует их поведение. Все методы неявно объявляются как public. Начиная с Java 8 в интерфейсах разрешается размещать реализацию методов по умолчанию default и статических static методов. Интерфейс также может содержать и поля. В этом случае они автоматически являются публичными public, статическими static и неизменяемыми final.

Комментарии
0/3000
18

Почему в некоторых интерфейсах не определяют методов?

Это так называемые маркерные интерфейсы. Они просто указывают, что класс относится к определенному типу. Примером может послужить интерфейс Clonable, который указывает на то, что класс поддерживает механизм клонирования.

Комментарии
0/3000
19

Что такое абстрактный класс?

Абстрактный класс — класс, реализация которого описана не полностью. Понятие, в некотором смысле родственное интерфейсу, с разницей в том, что реализация интерфейса вообще не описана. Абстрактный класс может иметь поля, методы и абстрактные методы — методы, реализация которых не описана. public abstract class ArrayContainer implements Container { int[] numbers; @Override public void add(int a) { int[] tmp = new int[numbers.length + 1]; for (int i = 0; i < numbers.length; i++) { tmp[i] = numbers[i]; } tmp[numbers.length] = a; } @Override public int getLength() { return numbers.length; } @Override public int[] getAllValues() { return numbers.clone(); } abstract public int[] getSortedValues(); } Так, мы знаем, что у объекта такого типа должен быть getSortedValues(), возвращающий отсортированные значения.

Комментарии
0/3000
20

Чем абстрактный класс отличается от интерфейса?

1. Класс может одновременно реализовать несколько интерфейсов, но наследоваться только от одного класса. 2. Абстрактные классы используются только тогда, когда присутствует тип отношений «is a» (является). Интерфейсы могут реализоваться классами, которые не связаны друг с другом. 3. Абстрактный класс - средство, позволяющее избежать написания повторяющегося кода, инструмент для частичной реализации поведения. Интерфейс - это средство выражения семантики класса, контракт, описывающий возможности. Все методы интерфейса неявно объявляются как public abstract или (начиная с Java 8) default - методами с реализацией по-умолчанию, а поля - public static final. 4. Интерфейсы позволяют создавать структуры типов без иерархии. 5. Наследуясь от абстрактного, класс «растворяет» собственную индивидуальность. Реализуя интерфейс, он расширяет собственную функциональность. Абстрактные классы содержат частичную реализацию, которая дополняется или расширяется в подклассах. При этом все подклассы схожи между собой в части реализации, унаследованной от абстрактного класса, и отличаются лишь в части собственной реализации абстрактных методов родителя. Поэтому абстрактные классы применяются в случае построения иерархии однотипных, очень похожих друг на друга классов. В этом случае наследование от абстрактного класса, реализующего поведение объекта по умолчанию может быть полезно, так как позволяет избежать написания повторяющегося кода. Во всех остальных случаях лучше использовать интерфейсы.

Комментарии
0/3000
21

Что имеет более высокий уровень абстракции - класс, абстрактный класс или интерфейс?

Интерфейс.

Комментарии
0/3000
22

Зачем нужно ключевое слово abstract?

Класс, помеченный модификатором abstract, называется абстрактным классом. Такие классы могут выступать только предками для других классов. Создавать экземпляры самого абстрактного класса не разрешается. При этом наследниками абстрактного класса могут быть как другие абстрактные классы, так и классы, допускающие создание объектов. Метод, помеченный ключевым словом abstract - абстрактный метод, т.е. метод, который не имеет реализации. Если в классе присутствует хотя бы один абстрактный метод, то весь класс должен быть объявлен абстрактным. Использование абстрактных классов и методов позволяет описать некий шаблон объекта, который должен быть реализован в других классах. В них же самих описывается лишь некое общее для всех потомков поведение.

Комментарии
0/3000
23

Зачем нужно ключевое слово final?

Модификатор final может применяться к переменным, параметрам методов, полям и методам класса или самим классам. Модификатор имеет следующий эффект: - Класс не может иметь наследников; - Метод не может быть переопределен в классах наследниках; - Поле не может изменить свое значение после инициализации; - Параметры методов не могут изменять своё значение внутри метода; - Локальные переменные не могут быть изменены после присвоения им значения.

Комментарии
0/3000
24

Почему нельзя объявить метод интерфейса с модификатором final?

В случае интерфейсов указание модификатора final бессмысленно, т.к. все методы интерфейсов неявно объявляются как абстрактные, т.е. их невозможно выполнить, не реализовав где-то еще, а этого нельзя будет сделать, если у метода идентификатор final.

Комментарии
0/3000
25

Расскажите про Heap и Stack память в Java

Heap (куча) используется Java Runtime для выделения памяти под объекты и классы. Создание нового объекта также происходит в куче. Это же является областью работы сборщика мусора. Любой объект, созданный в куче, имеет глобальный доступ и на него могут ссылаться из любой части приложения. Stack (стек) - это область хранения данных, так же находящаяся в общей оперативной памяти. Всякий раз, когда вызывается метод, в памяти стека создается новый блок, который содержит примитивы и ссылки на другие объекты в методе. Как только метод заканчивает работу, блок также перестает использоваться, тем самым предоставляя доступ для следующего метода. Размер стековой памяти намного меньше объема памяти в куче. Стек в Java работает по схеме LIFO (Последний-зашел-Первый-вышел).

Комментарии
0/3000
26

Что вы знаете о функции main()?

public static void main(String[] args) {} Метод main() — точка входа в программу. В приложении может быть несколько таких методов. Если метод отсутствует, то компиляция возможна, но при запуске будет получена ошибка `Error: Main method not found`.

Комментарии
0/3000
27

Может ли объект получить доступ к private члену класса?

- Внутри класса доступ к приватной переменной открыт без ограничений; - Вложенный класс имеет полный доступ ко всем (в том числе и приватным) членам содержащего его класса; - Доступ к приватным переменным извне может быть организован через отличные от приватных методов, которые предоставлены разработчиком класса. Например: getX() и setX(). - Через механизм рефлексии (Reflection API)

Комментарии
0/3000
28

Что такое конструкторы?

Конструкторы - это методы класса в Java, которые вызываются при создании нового объекта этого класса. Их основная задача - инициализировать поля нового объекта. Существует два типа конструкторов в Java: 1. Конструктор по умолчанию - это конструктор без параметров, который создается компилятором, если в классе не определен ни один конструктор. Он просто инициализирует все поля значениями по умолчанию. 2. Пользовательский конструктор - это конструктор, который создается программистом и который может иметь параметры. Он может выполнять любой код и инициализировать поля объекта значениями, переданными в параметрах. Пример создания пользовательского конструктора в Java: public class MyClass { int x; // Пользовательский конструктор с одним параметром public MyClass(int x) { this.x = x; } } Этот конструктор принимает один параметр x и инициализирует поле класса значением этого параметра. Ключевое слово this используется для ссылки на текущий объект класса. Вы можете создавать любое количество пользовательских конструкторов с разными параметрами.

Комментарии
0/3000
29

Зачем нужны блоки инициализации?

Блоки инициализации представляют собой код, заключенный в фигурные скобки и размещаемый внутри класса вне объявления методов или конструкторов. - Существуют статические и нестатические блоки инициализации. - Блок инициализации выполняется перед инициализацией класса загрузчиком классов или созданием объекта класса с помощью конструктора. - Несколько блоков инициализации выполняются в порядке следования в коде класса. - Блок инициализации способен генерировать исключения, если их объявления перечислены в throws всех конструкторов класса. - Блок инициализации возможно создать и в анонимном классе.

Комментарии
0/3000
30

Зачем нужны статические блоки инициализации?

Статические блоки инициализация используются для выполнения кода, который должен выполняться один раз при инициализации класса загрузчиком классов, в момент, предшествующий созданию объектов этого класса при помощи конструктора. Такой блок (в отличие от нестатических, принадлежащих конкретном объекту класса) принадлежит только самому классу (объекту метакласса Class).

Комментарии
0/3000
31

Может ли статический метод быть переопределён или перегружен?

Перегружен - да. Всё работает точно так же, как и с обычными методами - 2 статических метода могут иметь одинаковое имя, если количество их параметров или типов различается. Переопределён - нет. Выбор вызываемого статического метода происходит при раннем связывании (на этапе компиляции, а не выполнения) и выполняться всегда будет родительский метод, хотя синтаксически переопределение статического метода - это вполне корректная языковая конструкция. В целом, к статическим полям и методам рекомендуется обращаться через имя класса, а не объект.

Комментарии
0/3000
32

Могут ли нестатические методы перегрузить статические?

Да. В итоге получится два разных метода. Статический будет принадлежать классу и будет доступен через его имя, а нестатический будет принадлежать конкретному объекту и доступен через вызов метода этого объекта.

Комментарии
0/3000
33

Как получить доступ к переопределенным методам родительского класса?

super.method(); С помощью ключевого слова super мы можем обратиться к любому члену родительского класса - методу или полю, если они не определены с модификатором private.

Комментарии
0/3000
34

Можно ли объявить метод абстрактным и статическим одновременно?

Нет. В таком случае компилятор выдаст ошибку: "Illegal combination of modifiers: ‘abstract’ and ‘static’". Модификатор abstract говорит, что метод будет реализован в другом классе, а static наоборот указывает, что этот метод будет доступен по имени класса.

Комментарии
0/3000
35

Что такое «локальный класс»?

Local inner class (Локальный класс) - это вложенный класс, который может быть декларирован в любом блоке, в котором разрешается декларировать переменные. Как и простые внутренние классы (Member inner class) локальные классы имеют имена и могут использоваться многократно. Как и анонимные классы, они имеют окружающий их экземпляр только тогда, когда применяются в нестатическом контексте. Локальные классы имеют следующие особенности: - Видны только в пределах блока, в котором объявлены; - Не могут быть объявлены как private/public/protected или static; - Не могут иметь внутри себя статических объявлений методов и классов, но могут иметь финальные статические поля, проинициализированные константой; - Имеют доступ к полям и методам обрамляющего класса; - Могут обращаться к локальным переменным и параметрам метода, если они объявлены с модификатором final.

Комментарии
0/3000
36

Что такое «анонимный класс»?

Это вложенный локальный класс без имени, который разрешено декларировать в любом месте обрамляющего класса, разрешающем размещение выражений. Создание экземпляра анонимного класса происходит одновременно с его объявлением. В зависимости от местоположения анонимный класс ведет себя как статический либо как нестатический вложенный класс - в нестатическом контексте появляется окружающий его экземпляр. Анонимные классы имеют несколько ограничений: - Их использование разрешено только в одном месте программы - месте его создания; - Применение возможно только в том случае, если после порождения экземпляра нет необходимости на него ссылаться; - Реализует лишь методы своего интерфейса или суперкласса, т.е. не может объявлять каких-либо новых методов, так как для доступа к ним нет поименованного типа. Анонимные классы обычно применяются для: - Создания объекта функции (function object), например, реализация интерфейса Comparator; - Создания объекта процесса (process object), такого как экземпляры классов Thread, Runnable и подобных; - В статическом методе генерации; - Инициализации открытого статического поля final, которое соответствует сложному перечислению типов, когда для каждого экземпляра в перечислении требуется отдельный подкласс.

Комментарии
0/3000
37

Как передаются переменные в методы - по значению или по ссылке?

В Java параметры всегда передаются только по значению, что определяется как «скопировать значение и передать копию». С примитивами это будет копия содержимого. С ссылками - тоже копия содержимого, т.е. копия ссылки. При этом внутренние члены ссылочных типов через такую копию изменить возможно, а вот саму ссылку, указывающую на экземпляр - нет.

Комментарии
0/3000
38

Для чего нужен сборщик мусора?

Сборщик мусора (Garbage Collector) должен делать всего две вещи: - Находить мусор - неиспользуемые объекты. (Объект считается неиспользуемым, если ни одна из сущностей в коде, выполняемом в данный момент, не содержит ссылок на него, либо цепочка ссылок, которая могла бы связать объект с некоторой сущностью приложения, обрывается); - Освобождать память от мусора. Существует два подхода к обнаружению мусора: - Reference counting; - Tracing

Комментарии
0/3000
39

Какие разновидности сборщиков мусора реализованы в HotSpot?

Java HotSpot VM предоставляет разработчикам на выбор четыре различных сборщика мусора: - Serial (последовательный) — самый простой вариант для приложений с небольшим объемом данных и не требовательных к задержкам. На данный момент используется сравнительно редко, но на слабых компьютерах может быть выбран виртуальной машиной в качестве сборщика по умолчанию. Использование Serial GC включается опцией -XX:+UseSerialGC. - Parallel (параллельный) — наследует подходы к сборке от последовательного сборщика, но добавляет параллелизм в некоторые операции, а также возможности по автоматической подстройке под требуемые параметры производительности. Параллельный сборщик включается опцией -XX:+UseParallelGC. - Concurrent Mark Sweep (CMS) — нацелен на снижение максимальных задержек путем выполнения части работ по сборке мусора параллельно с основными потоками приложения. Подходит для работы с относительно большими объемами данных в памяти. Использование CMS GC включается опцией -XX:+UseConcMarkSweepGC. - Garbage-First (G1) — создан для замены CMS, особенно в серверных приложениях, работающих на многопроцессорных серверах и оперирующих большими объемами данных. G1 включается опцией Java -XX:+UseG1GC.

Комментарии
0/3000
40

Что такое «пул строк»?

Пул строк – это набор строк, хранящийся в Heap. - Пул строк возможен благодаря неизменяемости строк в Java и реализации идеи интернирования строк; - Пул строк помогает экономить память, но по этой же причине создание строки занимает больше времени; - Когда для создания строки используются ", то сначала ищется строка в пуле с таким же значением, если находится, то просто возвращается ссылка, иначе создается новая строка в пуле, а затем возвращается ссылка на неё; - При использовании оператора new создаётся новый объект String. Затем при помощи метода intern() эту строку можно поместить в пул или же получить из пула ссылку на другой объект String с таким же значением; - Пул строк является примером паттерна «Приспособленец» (Flyweight).

Комментарии
0/3000
41

Чем отличаются final, finally и finalize()?

Модификатор final: - Класс не может иметь наследников; - Метод не может быть переопределен в классах наследниках; - Поле не может изменить свое значение после инициализации; - Локальные переменные не могут быть изменены после присвоения им значения; - Параметры методов не могут изменять своё значение внутри метода. Оператор finally гарантирует, что определенный в нём участок кода будет выполнен независимо от того, какие исключения были возбуждены и перехвачены в блоке try-catch. Метод finalize() вызывается перед тем как сборщик мусора будет проводить удаление объекта.

Комментарии
0/3000
42

Почему char[] предпочтительнее String для хранения пароля?

С момента создания строка остаётся в пуле, до тех пор, пока не будет удалена сборщиком мусора. Поэтому, даже после окончания использования пароля, он некоторое время продолжает оставаться доступным в памяти и способа избежать этого не существует. Это представляет определённый риск для безопасности, поскольку кто-либо, имеющий доступ к памяти сможет найти пароль в виде текста. В случае использования массива символов для хранения пароля имеется возможность очистить его сразу по окончанию работы с паролем, позволяя избежать риска безопасности, свойственного строке.

Комментарии
0/3000
43

Перечислите методы класса object

В Java все классы наследуются от класса Object. Некоторые методы, определенные в классе Object, включают в себя: 1. getClass(): возвращает объект Class, который представляет класс объекта 2. hashCode(): возвращает хэш-код объекта 3. equals(Object obj): определяет, равен ли данный объект указанному объекту 4. clone(): создает и возвращает копию данного объекта 5. toString(): возвращает строковое представление объекта 6. notify(): возобновляет выполнение потока, заблокированного на объекте 7. notifyAll(): возобновляет выполнение всех потоков, заблокированных на данном объекте 8. wait(): ожидает до тех пор, пока другой поток не уведомит о возможности продолжения выполнения 9. finalize(): вызывается сборщиком мусора перед тем, как объект будет удален Важно отметить, что эти методы могут быть переопределены в производных классах, если необходимо изменить их реализацию для совместимости с конкретными требованиями приложения.

Комментарии
0/3000
44

Чем equals() отличается от операции ==?

Метод equals() определяет отношение эквивалентности объектов. При сравнении объектов с помощью == сравнение происходит лишь между ссылками. При сравнении по переопределённому разработчиком equals() - по внутреннему состоянию объектов.

Комментарии
0/3000
45

Для чего нужен метод hashCode()?

Метод hashCode() необходим для вычисления хэш кода переданного в качестве входного параметра объекта. В Java это целое число, в более широком смысле - битовая строка фиксированной длины, полученная из массива произвольной длины. Этот метод реализован таким образом, что для одного и того же входного объекта, хэш код всегда будет одинаковым. Следует понимать, что в Java множество возможных хэш кодов ограничено типом int, а множество объектов ничем не ограничено. Из-за этого, вполне возможна ситуация, что хэш коды разных объектов могут совпасть: - если хэш коды разные, то и объекты гарантированно разные; - если хэш коды равны, то объекты не обязательно равны(могут быть разные). Метод hashCode() не гарантирует уникальность возвращаемого значения. Ситуация, когда у разных объектов одинаковые хэш коды называется коллизией. Вероятность возникновения коллизии зависит от используемого алгоритма генерации хэш кода.

Комментарии
0/3000
46

Опишите иерархию исключений.

Исключения делятся на несколько классов, но все они имеют общего предка — класс Throwable, потомками которого являются классы Exception и Error*. Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память доступная виртуальной машине. Исключения (Exceptions) являются результатом проблем в программе, которые в принципе решаемы, предсказуемы и последствия которых возможно устранить внутри программы. Например, произошло деление целого числа на ноль.

Комментарии
0/3000
47

Как написать собственное («пользовательское») исключение?

class CustomException extends Exception { public CustomException() { super(); } public CustomException(final String string) { super(string + " is invalid"); } public CustomException(final Throwable cause) { super(cause); } } Необходимо унаследоваться от базового класса требуемого типа исключений (например, от Exception или RuntimeException).

Комментарии
0/3000
48

Что такое generics?

Generics - это технический термин, обозначающий набор свойств языка позволяющих определять и использовать обобщенные типы и методы. Обобщенные типы или методы отличаются от обычных тем, что имеют типизированные параметры. Примером использования обобщенных типов может служить Java Collection Framework. Так, класс LinkedList<E> - типичный обобщенный тип. Он содержит параметр E, который представляет тип элементов, которые будут храниться в коллекции. Создание объектов обобщенных типов происходит посредством замены параметризированных типов реальными типами данных. Вместо того, чтобы просто использовать LinkedList, ничего не говоря о типе элемента в списке, предлагается использовать точное указание типа LinkedList<String>, LinkedList<Integer> и т.п.

Комментарии
0/3000
49

Что такое JavaBean?

JavaBeans - это классы в языке Java, которые следуют определенным правилам и используются для управления объектами в приложениях. Вот некоторые основные признаки JavaBean: 1. Класс должен иметь стандартный конструктор без параметров. 2. Свойства должны быть доступны через геттеры (get) и сеттеры (set) методы. 3. Имена геттеров и сеттеров должны соответствовать стандартной схеме: для свойства foo геттер должен иметь имя getFoo, а сеттер - setFoo. 4. Класс должен реализовывать java.io.Serializable интерфейс, чтобы его можно было сериализовать. Некоторые другие признаки включают использование аннотации @ManagedBean, наличие методов добавления и удаления для свойств типа коллекций и поддержку событий с помощью методов с именами типа add<EventListenerType>Listener и remove<EventListenerType>Listener.

Комментарии
0/3000
50

Что такое OutOfMemoryError?

OutOfMemoryError — это ошибка времени выполнения в языке программирования Java, которая возникает, когда виртуальная машина Java (JVM) не может выделить память для создания новых объектов, поскольку пространство кучи заполнено и больше нет места для хранения новых объектов. Куча — это пространство памяти, используемое JVM для выделения и освобождения объектов, созданных во время выполнения. Важно эффективно управлять использованием памяти в Java, чтобы избежать исключений OutOfMemoryError. Этого можно добиться путем оптимизации кода, сокращения потребления памяти и использования соответствующих методов управления памятью, таких как сборка мусора, эффективные структуры данных и шаблоны проектирования. Кроме того, вы можете увеличить максимальный размер кучи, доступный для JVM, используя такие параметры командной строки, как -Xmx, чтобы избежать нехватки памяти.

Комментарии
0/3000
51

Расскажите про try-with-resources

В Java try-with-resources - это новый способ работы с ресурсами, введенный в версии JDK 7. Он автоматически закрывает используемые ресурсы после того, как выполнение блока try завершится. Таким образом, вы можете избежать вручную закрытия ресурсов в блоке finally. Пример с try-with-resources: try (InputStream in = new FileInputStream("file.txt")) { // считывание данных из потока } catch (IOException e) { // обработка ошибок ввода/вывода } // здесь in будет автоматически закрыт В то время как в блоке try-catch-finally, блок finally выполняется после того, как выполнение блока try завершилось, но перед тем, как управление передается дальше по стеку вызовов. Это означает, что блок finally может использоваться для закрытия ресурсов, открытых в блоке try. Пример с try-catch-finally: InputStream in = null; try { in = new FileInputStream("file.txt"); // считывание данных из потока } catch (IOException e) { // обработка ошибок ввода/вывода } finally { if (in != null) { try { in.close(); } catch (IOException e) { // обработка ошибок ввода/вывода } } } Таким образом, try-with-resources упрощает и уменьшает количество кода при работе с ресурсами и обеспечивает безопасное закрытие использованных ресурсов, в то время как try-catch-finally позволяет закрыть ресурсы, если они были открыты в блоке try и выполнен блок catch, и выполняется в любом случае.

Комментарии
0/3000
52

Что такое immutable значения в Java?

В языке Java объекты классов String, Integer, Byte, Character, Short, Boolean, Long, Double и Float являются immutable. Это означает, что значения их полей не могут быть изменены после создания объекта. Таким образом, любые операции с ними, которые изменяют значение, на самом деле создают новый объект. Примером может быть метод substring() в классе String, который создает новый объект строки, содержащий подстроку из исходной строки. Кроме того, вы также можете создавать свои собственные immutable классы в Java, объявляя поля и устанавливая им значения только в конструкторе, а затем делая их final. Это гарантирует, что их значения не могут быть изменены после создания объекта.

Комментарии
0/3000
53

Что такое immutable objects?

Неизменяемые объекты (immutable objects) в Java - это объекты, которые нельзя изменить после их создания. Объекты, такие как строки (String) или числа (Integer), являются неизменяемыми. Когда вы создаете новое значение для такого объекта, на самом деле создается новый объект, и старый объект остается неизменяемым. Основное преимущество неизменяемых объектов - это их надежность и защита от изменений со стороны других частей программы. Также они обеспечивают безопасность многопоточного программирования, поскольку неизменяемые объекты могут быть разделены между несколькими потоками без риска изменений и ошибок. Также неизменяемые объекты помогают улучшить производительность программы, потому что их не нужно копировать или клонировать для сохранения неизменным. Например, вместо создания нового массива при изменении элемента в массиве, вы можете создать новый массив, который копирует все элементы и изменить нужный элемент в нем. Это будет более эффективным по времени и памяти, чем изменение изначального массива. В целом, неизменяемые объекты помогают упростить разработку и обеспечить надежность программы за счет уменьшения риска ошибок в результате непреднамеренных изменений объектов.

Комментарии
0/3000
Смежные категории
Computer Science
15 вопросов
Вопросы и ответы с собеседований по DDD
1527 просмотров
Базы данных
11 вопросов
Вопросы с собеседований про шардинг баз данных
1283 просмотра
Базы данных
60 вопросов
Вопросы и ответы с собеседований по SQL
2378 просмотров
Computer Science
28 вопросов
Объяснение паттернов проектирования с примерами
1424 просмотра
Computer Science
11 вопросов
Вопросы и ответы про интернет-протоколы
1466 просмотров
Docker
7 вопросов
Коллекция полезных команд для Docker
1322 просмотра
Рекомендуем
Computer Science
15 вопросов
Вопросы и ответы с собеседований по DDD
1527 просмотров
Computer Science
12 вопросов
Вопросы с собеседований про операционные системы
1062 просмотра
Git
20 вопросов
Вопросы и ответы с собеседований по Git
1784 просмотра
Базы данных
60 вопросов
Вопросы и ответы с собеседований по SQL
2378 просмотров
Computer Science
11 вопросов
Вопросы и ответы про интернет-протоколы
1466 просмотров
Computer Science
13 вопросов
Вопросы и ответы с собеседований про ООП
1231 просмотр
Другие разделы

Лента

Активность пользователей Девстанции

Перейти к ленте

Лидеры

Рейтинг самых результативных пользователей сообщества

Перейти к лидерам

Треды

Общение по интересам и связь с разработчиками

Перейти к тредам

Задачи

Решение алгоритмических задач с собеседований

Перейти к задачам

Вопросы

Ответы на вопросы с технических собеседований

Вы находитесь здесь

Викторины

Интерактивные викторины по вопросам с собеседований

Перейти к викторинам
Мы в Telegram
Новости проекта, общение с разработчиками, общение по интересам - присоединяйтесь!