Java Guru 🤓
13.4K subscribers
938 photos
15 videos
793 links
Канал с вопросами и задачами с собеседований!

По сотрудничеству и рекламе: @NadikaKir

Канал в перечне РКН: https://vk.cc/cJrSQZ

Мы на бирже: telega.in/channels/javatasks/card?r=lcDuijdm
Download Telegram
Каким будет результат компиляции и выполнения следующего кода?
👍11
Каким будет результат компиляции и выполнения следующего кода?
Anonymous Quiz
31%
Вывод в консоль - null
19%
Вывод в консоль - 1
30%
Вывод в консоль - 2
20%
Исключение NullPointerException
👍19🍾1
Как передать runtime информацию о generic-типе?

Когда вы проектируете API-метод библиотеки, иногда логика его реализации может зависеть от указанного клиентом типа. Особенно часто с этой задачей встречаются при разработке парсеров. Например, библиотека Jackson превращает JSON в объект заданного класса. На интервью этот вопрос можно встретить в виде практической задачи.

Первое, что приходит в голову для решения – дженерик-параметр. Такой подход не сработает, потому что тип будет стёрт во время компиляции, а логика будет происходить позже, во время выполнения.

Решение, которое сработает для многих случаев – объявление в методе аргумента типа Class<T>. Пользователь будет передавать в него значение Foo.class или fooInstance.getClass(). Проблемы с ним начинаются, когда становится нужно передать generic-тип. Синтаксис .class не поддерживает дженерики, а .getClass() от экземпляров List<String> и List<Integer> вернет один и тот же объект-описание сырого типа List.

На помощь приходит техника, описанная в предыдущей
публикации.

1. Объявляется generic класс-обертка над типом: TypeInformation<T>;. Наш метод будет принимать информацию о типе в виде экземпляра этой обертки.

2. В обертку добавляется конструктор с видимостью protected. Теперь можно создавать объекты только наследников, но не самого этого типа.

3. Пользователь будет передавать экземпляр анонимного наследника обертки: new TypeInformation<List<String>>() {}.

4. Внутри вызов getClass().getGenericSuperclass() вернет ParameterizedType. Это будет описание типа родителя анонима, то есть самой обертки. Из него с помощью getActualTypeArguments() можно достать рантайм-информацию о значении дженерика (о List<String>).
👍24🔥61
Что выведет на экран следующая программа?
👍13🔥3🤩1
Что выведет на экран следующая программа?
Anonymous Quiz
30%
true
31%
false
9%
4/2=true
30%
4/2=false
👍315🔥3🍌3🤩1
Как Spring Framework реализует паттерн Dependency Injection?

Инверсия контроля (inversion of control, IoC) – принцип проектирования, по которому контроль над потоком управления передается фреймворку. Управляющий и прикладной код разделяются. При разработке модуля этот подход избавляет от необходимости знать о других модулях программы и деталях их взаимодействия. Такой код становится более переипользуемым и модульным, уменьшает связность.

Внедрение зависимостей (Dependency Injection, DI) – одна из реализаций IoC. При взаимодействии с другими модулями, программа оперирует высокоуровневыми абстракциями, тогда как конкретная её реализация поставляется фреймворком.

Стандартная реализация DI – фреймворк инстанциирует все сервисы, и складывает их в IoC-контейнер. При этом специальная сущность, Service Locator, занимается поиском соответствия реализаций абстракциям и их внедрением.

Spring – большой набор различных библиотек. DI реализуется одной из основных библиотек – Spring IoC.

Сущности бизнес-логики в Spring, как и в JavaEE называются beans. Бины объявляются различными способами, корни большинства из них лежат в понятии Configuration. В качестве контейнера бинов выступает ApplicationContext. Чтобы передать инициализацию зависимости контексту, она помечается аннотацией
@Autowired.
👍28🔥851
Каким будет результат компиляции и выполнения следующего кода?
🥴17👍7🤨5🌚2💔2
Какой у Spring бинов скоуп по умолчанию?

В Spring Framework во всех определениях бизнес-сущностей (bean) явно или неявно присутствует атрибут scope. В Java-конфигурации он передается в аннотации @Scope, в xml – в атрибуте scope тега <bean>.

Атрибут scope – это строка-идентификатор, которая ставит бину в соответствие экземпляр класса org.springframework.beans.factory.config.Scope. Скоуп – реализация паттерна «стратегия» для фабрик бинов, инструкция по созданию бизнес-объектов.

В простейшем Spring-приложении всегда существует два сокоупа:
• singleton – объект создается однажды, при последующих внедрениях переиспользуется. Полезен для большинства случаев: различные сервисы, объекты без состояния, неизменяемые объекты. Стоит заметить, это не класс-синглтон: при объявлении двух бинов одного класса их экземпляров будет два. Это скоуп по умолчанию.
• prototype – при каждом внедрении фабрика бинов создает новый объект. Нужен для изменяемых бинов с состоянием.

Spring Web добавляет 4 дополнительных скоупа, которые делают бин синглтоном в пределах обработки одного сетевого запроса (request), клиентской сессии (session), контекста сервлета (application) и вебсокет-сессии (websocket).

Разработчик может добавлять собственные скоупы. Пример реализации одного можно найти в самих исходниках Spring: SimpleThreadScope, который делает бин тред-локальным. Для использования его, как и пользовательские скоупы, нужно сначала зарегистрировать в BeanFactory.
👍24🔥72
Каким будет результат компиляции и выполнения следующего кода?
👍9
Каким будет результат компиляции и выполнения следующего кода?
Anonymous Quiz
17%
Вывод в консоль - "1 2 3 4 5"
48%
Вывод в консоль - "5 4 3 2"
29%
Вывод в консоль - "5 4 3 2 1"
5%
Вывод в консоль - "1 2 3 4"
👍251
Какие отличия между @⁠Component, @⁠Service, @⁠Repository и @⁠Controller?

@Component – простой способ сделать объявление класса объявлением Spring-бина. Из всех компонентов, которые попали в сканирование (о которых знает @ComponentScan), будут созданы бин-дефинишны.

Остальные аннотации – это алиасы аннотации
@Component. Сами по себе они не добавляют поведения, и технически в рамках ядра Spring Framework работают так же.

Эти аннотации называют «Stereotype annotations». Их главное отличие – семантика, логическая роль компонентов:
• @⁠Service – реализация бизнес-логики;
• @⁠Repository – хранилище данных: «репозиторий» из Domain-Driven Design или классический DAO;
• @⁠Controller – обработка веб-запросов (методы
@RequestMapping)

Сторонние компоненты могут пользоваться этой семантикой. Например, трансляция исключений Persistence API работает именно на компонентах стереотипа
@Repository. Таким образом, в отдельных случаях кроме семантики может меняться и поведение кода библиотек.
👍26🔥7🤔1
Какой результат будет получен после компиляции и выполнения данного кода?
👍7
Какие задачи решает Spring Data?

Это проект, который упрощает работу с системами доступа к данным: реляционными и нереляционными базами данных, map-reduce фреймворками и облачными хранилищами. Центральная концепция проекта – репозитории из предметно-ориентированного дизайна (Domain-driven design, DDD).

Spring Data состоит из множества отдельных библиотек для разных случаев жизни. Вот самые популярные из них:

• Spring Data JPA – адаптер для реализаций Java Persistence API, таких как Hibernate.
• Spring Data JDBC – более простой и ограниченный чем JPA адаптер для JDBC-драйверов.
• Spring Data REST – создание готовых hypermedia-driven RESTful сервисов на основе репозиториев.
• Spring Data KeyValue – работа с хранилищами типа ключ-значение.
• Библиотеки поддержки конкретных реализаций хранилищ: MongoDB, Redis, Cassandra, LDAP, и других.
👍303
Что будет выведено на консоль?
👍5
👍5
Сравните репозитории Spring Data

Основная часть работы в Spring Data строится вокруг интерфейса Repository. Это маркерный интерфейс. От него наследуются интерфейсы-специализации, которые уже содержат методы для работы с сущностями базы данных. Все эти интерфейсы параметризуются двумя типами: самой сущности и её идентификатора.

CrudRepository – базовый набор операций над сущностями: создание, чтение, изменение и удаление (CRUD).

PagingAndSortingRepository – добавляет к CRUD возможность постраничной загрузки данных с определенной сортировкой.

JpaRepository – расширение PagingAndSortingRepository, полноценно реализующее Java Persistence API. Добавляет ряд методов, таких как например flush и deleteInBatch.

MongoRepository – расширение PagingAndSortingRepository, специфичное для MongoDB.

Вспомогательные методы, специфичные для конкретной модели данных, добавляются в пользовательские интерфейсы-наследники. Основываясь на именах добавляемых методов, фреймворк сам создаёт их реализацию.
👍2621
Что произойдет в результате компиляции и выполнения кода?
👍9
Когда используют Aware интерфейсы в Spring?

В Spring Framework существует большое количество «глобальных» (в рамках какого-либо скоупа) сущностей-синглтонов, которые не являются бинами. Естественно, все сразу они не нужны ни одному бину, обычный механизм внедрения для них не работает. Но тем не менее, должен существовать способ воспользоваться их функциональностью.

Маркерный интерфейс Aware служит родителем большому количеству интерфейсов с именами *Aware. Каждый из них, при реализации, доставляет бину какую-то специфичную для себя сущность. Так, например, компонент, которому нужно обратиться к контексту приложения, должен реализовывать ApplicationContextAware.

Технически, сами интерфейсы ничего не делают. Интерфейс FooAware обычно объявляет единственный метод void setFoo(Foo value). Через этот метод связанный с интерфейсом BeanPostProcessor передаст в бин нужную сущность.

Если бин реализует ServletContextAware, то в процессе инициализации бина к нему придет ServletContextAwareProcessor, и вызовет setServletContext с контекстом сервлета в качестве параметра.
👍16🤨41