Получи случайную криптовалюту за регистрацию!

Java: fill the gaps

Логотип телеграм канала @java_fillthegaps — Java: fill the gaps J
Логотип телеграм канала @java_fillthegaps — Java: fill the gaps
Адрес канала: @java_fillthegaps
Категории: Технологии
Язык: Русский
Количество подписчиков: 10.33K
Описание канала:

Привет! Меня зовут Диана, и я занимаюсь java разработкой с 2013г.
Делюсь опытом/знаниями по темам:
- Java Core
- Вопросы с собеседований
- Best practices
Комплименты, вопросы, предложения: @utki_letyat

Рейтинги и Отзывы

4.50

2 отзыва

Оценить канал java_fillthegaps и оставить отзыв — могут только зарегестрированные пользователи. Все отзывы проходят модерацию.

5 звезд

1

4 звезд

1

3 звезд

0

2 звезд

0

1 звезд

0


Последние сообщения 16

2021-06-11 10:15:00 ​Какой результат выполнения этого кода?
1.4K views07:15
Открыть/Комментировать
2021-06-08 09:00:38 Generics, часть 1: история и корпоративные ценности

Вернёмся в 1998 год.

В java 1.2 появились интерфейсы Map, Set, List и основные реализации. В те времена они хранили только объекты:

List values = new ArrayList()

Чтобы нормально работать, приходилось использовать явное приведение:

values.add("value");
String s = (String) values.get(0);

Главная проблема с коллекциями тех лет - type loss, потеря типа при компиляции и написании кода:
Можно запросто получить ClassCastException
Надо помнить тип объектов
Ошибки возникают только в рантайме

В java 5 появилась возможность указать тип через дженерики:

List values = new ArrayList();
values.add("p");
String v = values.get(0);

Удобно пользоваться
Хорошо читается
Компилятор проверяет типы

Как реализованы дженерики?

Примерим на себя должность архитектора java и прикинем, что можно сделать с ArrayList>:

Скомпилировать в класс с типом String
Все T заменяем на String:

void add(String str)
String get(int index)

В итоге создаём отдельный класс для каждого типа данных.

Добавить в JVM параметризованный тип

остаётся на уровне байт-кода и определяется для каждого объекта в рантайме.

Оставить на уровне JVM работу с объектами. Проверить все типы во время компиляции и привести один к другому там, где нужно.
Получаем один ArrayList.class и множество дополнительных конструкций по всему коду.

Для ArrayList программист напишет:

String value = list.get(0)

Компилятор преобразует это в

String value = (String) list.get(0);

Все варианты адекватные и имеют право на жизнь. Что же выбрать?

Почти в каждом IT офисе на стенах висят слоганы и ценности компании. Что-то про качество работы, развитие сотрудников, гибкость и довольных клиентов. Из этого получается классный корпоративный мерч.

Ценности нормального человека определяют стратегию и дают ориентир для решения сложных ситуаций. "Ценности" java явно нигде не определены, но направление работы задано чётко. Например, кроссплатформенность и слоган Write Once, Run Anywhere заставляют разработчиков JDK поддерживать фичи даже для древних процессоров.

Бинарная совместимость - ещё один ориентир java. Поэтому для дженериков используется третий вариант: компилятор добавляет необходимые приведения типов в код и стирает информацию о дженериках. И код на java 5 теперь совместим с предыдущими версиями.

Ответ на вопрос перед постом

В консоли напечатаются оба значения. У списка tmp тип не задан, поэтому компилятор не мешает добавлять строки и передавать объекты в метод println.

Если в println передать список intList.get(0), где тип указан явно, то мы получим ошибку компиляции.
1.4K views06:00
Открыть/Комментировать
2021-06-08 09:00:37 ​Какой результат выполнения этого кода?
1.4K views06:00
Открыть/Комментировать
2021-06-08 09:00:37 Почему на канале так много Java Core? Потому что это база для ежедневной работы, которую хорошо знать вдоль и поперёк. Но лично мой интерес лежит в другом. Мне нравится разбирать дизайн и разбираться, почему сделано так, а не иначе.

Тема этой недели - дженерики.
Часть 1: посмотрим реализацию в JVM
Часть 2: углубимся в wildcards и работу с подтипами
1.4K views06:00
Открыть/Комментировать
2021-05-28 09:00:35 Ресурсы, идиома RAII и Java 9

Разработка - сложная штука c множеством идей и концептов. В этом посте я расскажу об идиоме RAII, разнице при работе с ресурсами в java и C++, блоке try-with-resources и изменениях java 9.

Начнём с основ. Ресурс - это сущность, для которой нужен эксклюзивный доступ. Их количество ограничено. Большинство ресурсов находятся за пределами JVM: файлы, соединения с БД, сокеты и т.д

Для корректной работы только один поток должен работать с ресурсом. Для этого нужно принять дополнительные меры. Обозначим их как "открыть" и "закрыть" ресурс:
Открыть = получить эксклюзивный доступ.
Закрыть = закончить работу. Теперь другой поток может работать с ресурсом.

Такой вот нехитрый жизненный цикл(ЖЦ).

RAII
или Resource Acquisition Is Initialization - одна из техник по работе с ресурсами. Другое название: SBRM - Scope-Bound Resource Management.

Суть: ассоциируем ресурс с объектом. Тогда ЖЦ ресурса совпадает с ЖЦ объекта. В идеале это выглядит так:

public void do() {
File f=new File("t.txt");
// Создаём объект File, ресурс "t.txt" теперь наш
// что-то делаем
}
// вышли из метода: объект f уже не нужен, ресурс "t.txt" освобождается

RAII легко реализовать в С++. В конструкторе пишем логику "открытия" ресурса, а в деструкторе - "закрытия". Конструктор и деструктор явно прописываются, поэтому ЖЦ объекта и ресурса под контролем.

В java так не получится. Деструктор выполнится неизвестно когда, а ресурс - штука ценная. Поэтому в java нужно явно вызвать метод закрытия. В стандартных библиотеках это close().

В java 7 появилась специальная конструкция для ресурсов:
try (PrintWriter writer = new PrintWriter(…)) {
// что-то делаем
}

Ресурс реализует интерфейс AutoCloseable, и после завершения блока для него вызовется close(). try-with-resources считается java реализацией RAII.

Но такой формат не идеален. Внутри try всегда определяется новый объект. Когда ресурсов два и больше, код становится громоздким:

try (DatagramChannel udpServer = …;
Selector selector = …) {
// …
}

В java 9 в блок try можно передать переменные:

DatagramChannel udpServer = …;
Selector selector = …;

try (udpServer;selector) {
// …
}

С одной стороны это удобно. Код выглядит приятно.

С другой - после try остаются переменные с закрытыми ресурсами. Теперь нельзя сказать, что java реализует RAII.

Ну и ладно, никто не расстроился Языки разные, и классно замечать, как по-разному в них реализуются идеи, и как они меняются с течением времени.
1.5K views06:00
Открыть/Комментировать
2021-05-25 09:00:42 Спаси и сохрани: stash and shelve

Иногда во время работы над одной задачей нужно переключиться на другую: поправить пул реквест или сделать хотфикс. Если текущие изменения не готовы для полноценного коммита, можно использовать stash или shelve.

Stash
Изменения сохранятся в локальном git репозитории, а текущая ветка почистится. Можно спокойно переключаться на другую задачу.

git stash save "stash name"

В IDEA: VCS → Git → Stash Changes...

Вернуть изменения на место:
git stash apply "stash name"
и оставить stash в локальном репозитории

git stash pop "stash name"
и удалить стэш

В IDEA: VCS → Git → Unstash Changes...

Что важно:
Сохраняются ВСЕ текущие изменения в ветке
Обратно применяются ВСЕ изменения в стэше
Изменения хранятся в локальном git репозитории

Shelve
Удобная фича IDEA для сохранения части изменений:

VCS → Shelve Changes...
Галочками отмечаем, что сохранить.

Чтобы вернуть обратно:
Вкладка Git (Alt + 9 или найдите внизу) Shelve.
Отмечайте, какие изменения применить к коду.

Можно выбрать, что сохранять
Можно указать, что восстановить
Изменения хранятся в локальном IDEA проекте
1.1K viewsedited  06:00
Открыть/Комментировать
2021-05-21 17:45:00 Анонс мероприятий

Реклама не за деньги, а по любви. Общалась со всеми организаторами, поэтому рекомендую с чистой совестью.

Integrity Solutions Tech Talks. Митап при участии JUG Ru Group

Когда: 24 мая, 18:00 (по МСК)
Участие: бесплатно
Формат: онлайн

Программа :
"Java Flight Recorder": что такое, чем полезен и когда его применять. На мой взгляд самый полезный доклад.
"Переезд с PostgreSQL на Elasticsearch для гибкого поиска адресов"
"Использование Тhymeleaf для динамических SQL-запросов"

Подробности и регистрация

Онлайн-чемпионат от Совкомбанк

Для кого: junior-middle
Зачем: проверить свои знания и найти пробелы. Если у вас в резюме нет пет-проджекта, можно сделать на основе заданий чемпа. Есть шанс выиграть деньги и мерч.
Когда: 22-23 мая
Формат: онлайн
Подача заявки: сегодня последний день

Что будет:
22 мая: вопросы по Java core, Collections, веб-сервисы, очереди, БД и ORM, Maven, git
23 мая: сделать REST сервис с авторизацией и с кем-то интегрироваться. Чьё приложение пройдёт больше тестов и лучше выдержит нагрузку - тот победит.

Подробности и регистрация

Ночной онлайн-чемпионат Tech Monsters Night от М.Видео

Для кого: middle-senior
Зачем: проверить себя и побороться за мерч и технику. Организаторы обещают доставку пиццы всем участникам
Когда: 4 июня, с 22 до 3 ночи
Формат: онлайн
Подача заявки: до 3 июня

Подробности и регистрация
376 views14:45
Открыть/Комментировать
2021-05-21 09:00:11 Enumerations, часть 3: загрузка классов

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

Классы в JVM загружаются по мере необходимости. Что происходит при первом вызове new User():

Загрузка класса User, создание экземпляра User.class
Инициализируются статические переменные и выполняются блоки static {...}

Дальше переходим к созданию объекта:

Создаются явно указанные поля и выполняются блоки { }
Вызов конструктора класса и суперклассов

Внутри инициализирующего блока понадобился класс State. Переходим к нему.

Enum State компилируется в такую штуку:

public final class State extends Enum {
public static final State NEW;
public static final State VALIDATED;

// init блок
State() {...}
// static блок
}

Возникла проблема. Перед вызовом конструктора надо закончить со статическими полями. А статические поля - экземпляры этого же класса. Замкнутый круг.

В такой ситуации JVM создаёт экземпляры NEW и VALIDATED перед статическими блоками. Получается такой порядок:

Создаём экземпляр State NEW:
блок инициализации S-Init
конструктор S-Constr

Повторяем тот же процесс для VALIDATED

Выполняем статический блок S-Static

Поэтому правильный ответ - G:
enum NEW(Init-Constr)
enum VALIDATED(Init-Constr)
enum-Static
объект User (Init-Constr)
1.3K views06:00
Открыть/Комментировать