11 шагов к Senior Google User
Главный навык разработчика - умение пользоваться интернетом. Чтобы занять голову не регулярками и опциями докера, а действительно важными вещами. Вот несколько приёмов для быстрого и чёткого поиска.
1️⃣ Искать по-английски
Материала больше, обычно он приятнее и понятнее русских аналогов.
2️⃣ Кавычки для поиска конкретной фразы
"parse pdf to xml"
Чтобы пропустить часть фразы, используйте звёздочку:
"java regex * tutorial"
3️⃣ AND
Обязательное вхождение обоих слов / фраз
"Spring in Action" AND "Евгений Борисов"
4️⃣ OR
Для поиска одного из вариантов
"how to do java" OR "java for beginners"
5️⃣ Исключить ключевое слово через минус
java types -javascript
Работает и для сайтов:
как пройти собеседование -otvet.mail.ru
6️⃣ Поиск на конкретном сайте
NPE site:stackoverflow.com
7️⃣ Найти файлы
Удобно искать книжки, презентации к докладам
"effective java" filetype:pdf
8️⃣ Найти только свежие / старые материалы
thread safety before:2020
functional programming after:2020-12-20
9️⃣ Быстрый перевод
coherence in russian
resilience по русски
🔟 Сложный поиск
Чтобы не запоминать эти приёмчики, есть страница Advanced Search с формочками для всех критериев и опцией "Скрывать непристойные результаты".
🔸 Бонусный пункт для владельцев Android со связанным Google аккаунтом:
find my phone в строке поиска. Даже если звук на телефоне выключен, можно включить звонок и найти телефон.
Главный навык разработчика - умение пользоваться интернетом. Чтобы занять голову не регулярками и опциями докера, а действительно важными вещами. Вот несколько приёмов для быстрого и чёткого поиска.
1️⃣ Искать по-английски
Материала больше, обычно он приятнее и понятнее русских аналогов.
2️⃣ Кавычки для поиска конкретной фразы
"parse pdf to xml"
Чтобы пропустить часть фразы, используйте звёздочку:
"java regex * tutorial"
3️⃣ AND
Обязательное вхождение обоих слов / фраз
"Spring in Action" AND "Евгений Борисов"
4️⃣ OR
Для поиска одного из вариантов
"how to do java" OR "java for beginners"
5️⃣ Исключить ключевое слово через минус
java types -javascript
Работает и для сайтов:
как пройти собеседование -otvet.mail.ru
6️⃣ Поиск на конкретном сайте
NPE site:stackoverflow.com
7️⃣ Найти файлы
Удобно искать книжки, презентации к докладам
"effective java" filetype:pdf
8️⃣ Найти только свежие / старые материалы
thread safety before:2020
functional programming after:2020-12-20
9️⃣ Быстрый перевод
coherence in russian
resilience по русски
🔟 Сложный поиск
Чтобы не запоминать эти приёмчики, есть страница Advanced Search с формочками для всех критериев и опцией "Скрывать непристойные результаты".
🔸 Бонусный пункт для владельцев Android со связанным Google аккаунтом:
find my phone в строке поиска. Даже если звук на телефоне выключен, можно включить звонок и найти телефон.
Закулисье курса по многопоточке
19 апреля стартовал первый поток курса по многопоточному программированию на java. Хочу рассказать, что там происходит и поделиться мыслями по этому поводу.
О чём вообще речь.
В прошлом году я начала готовить курс по многопоточке на java. Тема важная и сложная, а хороших материалов очень мало. Получился двухмесячный концентрированный курс: уроки с заданиями выходят три раза в неделю. Три недели назад стартовал первый поток, поэтому можно уже поделиться результатами.
По цифрам:
🔹 Участники с опытом от года до 8 лет
🔹 33% выполняют задания к уроку в течение 2 дней
🔹 60% - в течение недели
🔹 Самая активное время сдачи ДЗ - с 22 до часу ночи🌚
🔹 1 человеку не подошёл формат, вернула деньги
Что говорят ребята:
❤️ Курс действительно заполняет пробелы. Интересна точка зрения опытного разработчика на проблемы
❤️ Большое спасибо, что вы находите время писать развернутые комментарии и отвечать на смежные вопросы!) Это круто)
❤️ Если говорить в целом - то я очень доволен курсом
❤️ Сложно конечно, много нового для меня, не всегда успеваю сразу сдавать. Но чувствую, что полезно))
В целом я довольна. Времени на обратную связь трачу много, но, кажется, не зря.
Поэтому в июле планирую повторить. Тоже с небольшой группой, не больше 20 учеников. В предварительном списке уже больше 40 человек! Если тоже хотите первыми узнать дату старта и условия, вписывайтесь сюда:
Предварительный список на двухмесячный курс по java.util.concurrent и смежным вопросам
19 апреля стартовал первый поток курса по многопоточному программированию на java. Хочу рассказать, что там происходит и поделиться мыслями по этому поводу.
О чём вообще речь.
В прошлом году я начала готовить курс по многопоточке на java. Тема важная и сложная, а хороших материалов очень мало. Получился двухмесячный концентрированный курс: уроки с заданиями выходят три раза в неделю. Три недели назад стартовал первый поток, поэтому можно уже поделиться результатами.
По цифрам:
🔹 Участники с опытом от года до 8 лет
🔹 33% выполняют задания к уроку в течение 2 дней
🔹 60% - в течение недели
🔹 Самая активное время сдачи ДЗ - с 22 до часу ночи🌚
🔹 1 человеку не подошёл формат, вернула деньги
Что говорят ребята:
❤️ Курс действительно заполняет пробелы. Интересна точка зрения опытного разработчика на проблемы
❤️ Большое спасибо, что вы находите время писать развернутые комментарии и отвечать на смежные вопросы!) Это круто)
❤️ Если говорить в целом - то я очень доволен курсом
❤️ Сложно конечно, много нового для меня, не всегда успеваю сразу сдавать. Но чувствую, что полезно))
В целом я довольна. Времени на обратную связь трачу много, но, кажется, не зря.
Поэтому в июле планирую повторить. Тоже с небольшой группой, не больше 20 учеников. В предварительном списке уже больше 40 человек! Если тоже хотите первыми узнать дату старта и условия, вписывайтесь сюда:
Предварительный список на двухмесячный курс по java.util.concurrent и смежным вопросам
Собеседование:
- Расскажите про enumerations.
- Ну, это набор констант
- Как их можно использовать в коде?
- Как набор констант (что им надо?)
- А как они реализованы в JVM?
- Как константы (спросите лучше про хэшмэп)
Чтобы не получилось такой ситуации, на этой неделе разберёмся с темой перечислений. Enum - очень полезные конструкции. С ними код становится проще и безопаснее. Если их использовать, конечно.
План такой:
Часть 1 - обзор enumerations
Часть 2 - как используется на практике
Часть 3 - разберём загрузку классов и душный вопрос с собеседования
- Расскажите про enumerations.
- Ну, это набор констант
- Как их можно использовать в коде?
- Как набор констант (что им надо?)
- А как они реализованы в JVM?
- Как константы (спросите лучше про хэшмэп)
Чтобы не получилось такой ситуации, на этой неделе разберёмся с темой перечислений. Enum - очень полезные конструкции. С ними код становится проще и безопаснее. Если их использовать, конечно.
План такой:
Часть 1 - обзор enumerations
Часть 2 - как используется на практике
Часть 3 - разберём загрузку классов и душный вопрос с собеседования
В enum Planet есть метод getRadius. В классе Meteor тоже он есть. Мы хотим сделать метод getInfo, который работает с обеими сущностями и вызывает их метод getRadius.
Вопрос: что будет вместо солнышка во входном параметре?
(щёлкните по картинке, чтобы открыть полностью)
Вопрос: что будет вместо солнышка во входном параметре?
(щёлкните по картинке, чтобы открыть полностью)
Что будет во входном параметре getInfo?
Anonymous Poll
10%
Базовый enum для Planet и Meteor
9%
Базовый класс для Planet и Meteor
50%
Общий интерфейс для Planet и Meteor
6%
Композитный класс, в который входит Planet и Meteor
4%
Вопрос некорректен, в енумах нельзя определять методы
21%
Это невозможно, нужны отдельные методы getInfo(Planet) и getInfo(Meteor)
Enumerations, часть 1: обзор
Внутри JVM нет такого понятия как enum. Енумы компилируются в обычный класс, а значения - в статические экземпляры:
Но есть нюансы:
🔸 Суперкласс Enum
От суперкласса Enum наследуются методы name(), ordinal() и статический метод values().
name() возвращает имя переменной, ordinal() - порядковый номер в списке. На практике эти методы достаточно бесполезны.
Метод values() используется чаще и возвращает массив всех объектов. Можно пройтись по нему в цикле:
Enum реализует три интерфейса: Comparable, Serializable, Constable.
Первые два всем знакомы. Интерфейс Constable определяет методы для размещения объектов в пуле констант внутри JVM.
🔸 Создание экземпляров
Этим занимается JVM на старте приложения. Экземпляры енума создаются через приватный конструктор, недоступный вне енума.
🔸 Поля
Указываются для каждого экземпляра, инициализируются в конcтрукторе:
▫️Обычные
В теории можно сделать set* метод и поменять поле у любого экземпляра. Но на практике так никто не делает. Когда объект доступен из любого места системы, то проще жить, если он неизменяемый.
▫️Абстрактные
Каждый экземпляр определяет свою реализацию:
Любой enum - это final класс с уже определённым суперклассом. Единственный шанс встроить enum в иерархию - добавить для него интерфейс.
Иногда это удобно. Если у енумов и классов один интерфейс, то с ними можно работать через один метод:
Внутри JVM нет такого понятия как enum. Енумы компилируются в обычный класс, а значения - в статические экземпляры:
public final class Planet extends Enum {Полноценные классы c конструкторами, методами, полями и статическими элементами. У экземпляров есть состояние и определённое поведение.
public static final Planet EARTH;
public static final Planet MARS;
}
Но есть нюансы:
🔸 Суперкласс Enum
От суперкласса Enum наследуются методы name(), ordinal() и статический метод values().
name() возвращает имя переменной, ordinal() - порядковый номер в списке. На практике эти методы достаточно бесполезны.
Метод values() используется чаще и возвращает массив всех объектов. Можно пройтись по нему в цикле:
for (Planet p : Planet.values()) {…}или через Stream API:
Arrays.stream(Planet.values()).forEach(…)🔸 Интерфейсы суперкласса
Enum реализует три интерфейса: Comparable, Serializable, Constable.
Первые два всем знакомы. Интерфейс Constable определяет методы для размещения объектов в пуле констант внутри JVM.
🔸 Создание экземпляров
Этим занимается JVM на старте приложения. Экземпляры енума создаются через приватный конструктор, недоступный вне енума.
🔸 Поля
Указываются для каждого экземпляра, инициализируются в конcтрукторе:
public enum Planet {🔸 Два типа методов
MARS(3389),
EARTH(6371);
int radius;
Planet(int radius) {
this.radius = radius;
}
}
▫️Обычные
public int getRadius()
Используется для геттеров и простых вычислений. В теории можно сделать set* метод и поменять поле у любого экземпляра. Но на практике так никто не делает. Когда объект доступен из любого места системы, то проще жить, если он неизменяемый.
▫️Абстрактные
Каждый экземпляр определяет свою реализацию:
public enum Planet {🔸 Наследование
MARS {
int distanceFrom(int) {…}
},
EARTH {
int distanceFrom(int) {…}
};
abstract int distanceFrom(int);
}
Любой enum - это final класс с уже определённым суперклассом. Единственный шанс встроить enum в иерархию - добавить для него интерфейс.
Иногда это удобно. Если у енумов и классов один интерфейс, то с ними можно работать через один метод:
interface SpaceObject
enum Planet implements SpaceObject
class Meteor implements SpaceObject
public void getInfo(SpaceObject so)
Вопрос
Enum Formatter занимается форматированием строк в заданные форматы. Во время работы было выполнено 50 форматирований в XML, в JSON - 30, в YAML - 5.
Что вернёт метод Formatter.JSON.getCount()?
Enum Formatter занимается форматированием строк в заданные форматы. Во время работы было выполнено 50 форматирований в XML, в JSON - 30, в YAML - 5.
Что вернёт метод Formatter.JSON.getCount()?
Что вернёт метод Formatter.JSON.getCount()?
Anonymous Quiz
36%
30
3%
80
43%
85
13%
Код не скомпилируется
4%
Ошибка времени выполнения
Enumerations, часть 2: практика
В прошлом посте разобрали, из чего сделан enum. В этом - разберёмся, как его использовать.
1️⃣ Набор констант
Самый простой и популярный случай. Используем enum как поле класса или локальную переменную. Проверяем значение через if / switch и делаем ветвления в коде:
Вообще синглтон - антипаттерн и антитренд. Если без него никак - рассмотрите вариант с enum. Если вы склонны к риску, можно сделать изменяемые поля.
✅ Может быть несколько объектов в рамках одного enum
✅ Доступ из любого места в коде
✅ Ленивая инициализация
3️⃣ Паттерн State
Более продвинутый вариант, чем "набор констант". Здесь фокус на данных: используются связанные значения, а не элемент enum сам по себе.
Пример: в статус пользователя вносим дополнительные поля - необходимость подтверждения личности и максимальный размер скидки:
Здесь фокус на разнице в поведении. Абстрактный метод переопределяется для каждого экземпляра:
✅ Простая иерархия, всё в одном классе
✅ Список всех значений доступен через values()
😐 Весь код в одном файле. Не всегда удобно
❌ Сложно связать с другими объектами
❌ Нарушается принцип open for extension but closed for modification
Получается специфическая альтернатива полиморфизму, но иногда ок.
Enum - не просто набор констант. Инструмент своеобразный, но полезно знать и такие реализации паттернов. Чем шире арсенал разработчика, тем выше шанс найти подходящее решение.
В прошлом посте разобрали, из чего сделан enum. В этом - разберёмся, как его использовать.
1️⃣ Набор констант
Самый простой и популярный случай. Используем enum как поле класса или локальную переменную. Проверяем значение через if / switch и делаем ветвления в коде:
if (state == UserState.NEW) {…}2️⃣ Паттерн Singleton
Вообще синглтон - антипаттерн и антитренд. Если без него никак - рассмотрите вариант с enum. Если вы склонны к риску, можно сделать изменяемые поля.
✅ Может быть несколько объектов в рамках одного enum
✅ Доступ из любого места в коде
✅ Ленивая инициализация
3️⃣ Паттерн State
Более продвинутый вариант, чем "набор констант". Здесь фокус на данных: используются связанные значения, а не элемент enum сам по себе.
Пример: в статус пользователя вносим дополнительные поля - необходимость подтверждения личности и максимальный размер скидки:
enum UserState {4️⃣ Паттерн Strategy
NEW(true, 10),
VALIDATED(false, 25),
FRAUD(true, 0);
boolean needConfirmation;
int maxDiscount;
}
Здесь фокус на разнице в поведении. Абстрактный метод переопределяется для каждого экземпляра:
NEW { boolean check(Order){…}},✅ Подойдёт для алгоритмов, конвертеров, сортировок
VALIDATED { boolean check(Order){…}};
abstract boolean check(Order order)
✅ Простая иерархия, всё в одном классе
✅ Список всех значений доступен через values()
😐 Весь код в одном файле. Не всегда удобно
❌ Сложно связать с другими объектами
❌ Нарушается принцип open for extension but closed for modification
Получается специфическая альтернатива полиморфизму, но иногда ок.
Enum - не просто набор констант. Инструмент своеобразный, но полезно знать и такие реализации паттернов. Чем шире арсенал разработчика, тем выше шанс найти подходящее решение.
Вопрос
В классе User хранится статус в виде enum State.
В каком порядке и как будут создаваться объекты при первом вызове User user = new User()?
В классе User хранится статус в виде enum State.
В каком порядке и как будут создаваться объекты при первом вызове User user = new User()?
В каком порядке и как будут создаваться объекты при первом вызове new User()?
Anonymous Poll
5%
А. enum VALIDATED(Init-Constr-Static), объект User (Constr-Init)
29%
B. enum VALIDATED(Static-Init-Constr), объект User (Init-Constr)
9%
C. Объект User(Init-Constr), enum VALIDATED(Static-Init-Constr)
7%
D. Объект User(Constr-Init), enum VALIDATED(Init-Constr-Static)
31%
E. enum NEW(Static-Init-Constr), enum VALIDATED(Static-Init-Constr), объект User (Init-Constr)
20%
G. enum NEW(Init-Constr), enum VALIDATED(Init-Constr), enum-Static, объект User (Init-Constr)
Enumerations, часть 3: загрузка классов
Мы уже разобрали, из чего состоит enum и как его использовать. Сегодня разберём, как загружаются классы и экземпляры enum. Поможет нам в этом душноватый вопрос с собеседований, который находится выше.
Классы в JVM загружаются по мере необходимости. Что происходит при первом вызове new User():
🔹 Загрузка класса User, создание экземпляра User.class
🔹 Инициализируются статические переменные и выполняются блоки static {...}
Дальше переходим к созданию объекта:
🔸 Создаются явно указанные поля и выполняются блоки { }
🔸 Вызов конструктора класса и суперклассов
Внутри инициализирующего блока понадобился класс State. Переходим к нему.
Enum State компилируется в такую штуку:
В такой ситуации JVM создаёт экземпляры NEW и VALIDATED перед статическими блоками. Получается такой порядок:
1️⃣ Создаём экземпляр State NEW:
▫️блок инициализации S-Init
▫️конструктор S-Constr
2️⃣ Повторяем тот же процесс для VALIDATED
3️⃣ Выполняем статический блок S-Static
Поэтому правильный ответ - G:
▫️enum NEW(Init-Constr)
▫️enum VALIDATED(Init-Constr)
▫️enum-Static
▫️объект User (Init-Constr)
Мы уже разобрали, из чего состоит 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 перед статическими блоками. Получается такой порядок:
1️⃣ Создаём экземпляр State NEW:
▫️блок инициализации S-Init
▫️конструктор S-Constr
2️⃣ Повторяем тот же процесс для VALIDATED
3️⃣ Выполняем статический блок S-Static
Поэтому правильный ответ - G:
▫️enum NEW(Init-Constr)
▫️enum VALIDATED(Init-Constr)
▫️enum-Static
▫️объект User (Init-Constr)
Анонс мероприятий
Реклама не за деньги, а по любви. Общалась со всеми организаторами, поэтому рекомендую с чистой совестью.
1️⃣ Integrity Solutions Tech Talks. Митап при участии JUG Ru Group
Когда: 24 мая, 18:00 (по МСК)
Участие: бесплатно
Формат: онлайн
Программа :
▫️ "Java Flight Recorder": что такое, чем полезен и когда его применять. На мой взгляд самый полезный доклад.
▫️"Переезд с PostgreSQL на Elasticsearch для гибкого поиска адресов"
▫️ "Использование Тhymeleaf для динамических SQL-запросов"
Подробности и регистрация
2️⃣ Онлайн-чемпионат от Совкомбанк
Для кого: junior-middle
Зачем: проверить свои знания и найти пробелы. Если у вас в резюме нет пет-проджекта, можно сделать на основе заданий чемпа. Есть шанс выиграть деньги и мерч.
Когда: 22-23 мая
Формат: онлайн
Подача заявки: сегодня последний день😨
Что будет:
22 мая: вопросы по Java core, Collections, веб-сервисы, очереди, БД и ORM, Maven, git
23 мая: сделать REST сервис с авторизацией и с кем-то интегрироваться. Чьё приложение пройдёт больше тестов и лучше выдержит нагрузку - тот победит.
Подробности и регистрация
3️⃣ Ночной онлайн-чемпионат Tech Monsters Night от М.Видео
Для кого: middle-senior
Зачем: проверить себя и побороться за мерч и технику. Организаторы обещают доставку пиццы всем участникам🍕
Когда: 4 июня, с 22 до 3 ночи
Формат: онлайн
Подача заявки: до 3 июня
Подробности и регистрация
Реклама не за деньги, а по любви. Общалась со всеми организаторами, поэтому рекомендую с чистой совестью.
1️⃣ Integrity Solutions Tech Talks. Митап при участии JUG Ru Group
Когда: 24 мая, 18:00 (по МСК)
Участие: бесплатно
Формат: онлайн
Программа :
▫️ "Java Flight Recorder": что такое, чем полезен и когда его применять. На мой взгляд самый полезный доклад.
▫️"Переезд с PostgreSQL на Elasticsearch для гибкого поиска адресов"
▫️ "Использование Тhymeleaf для динамических SQL-запросов"
Подробности и регистрация
2️⃣ Онлайн-чемпионат от Совкомбанк
Для кого: junior-middle
Зачем: проверить свои знания и найти пробелы. Если у вас в резюме нет пет-проджекта, можно сделать на основе заданий чемпа. Есть шанс выиграть деньги и мерч.
Когда: 22-23 мая
Формат: онлайн
Подача заявки: сегодня последний день😨
Что будет:
22 мая: вопросы по Java core, Collections, веб-сервисы, очереди, БД и ORM, Maven, git
23 мая: сделать REST сервис с авторизацией и с кем-то интегрироваться. Чьё приложение пройдёт больше тестов и лучше выдержит нагрузку - тот победит.
Подробности и регистрация
3️⃣ Ночной онлайн-чемпионат Tech Monsters Night от М.Видео
Для кого: middle-senior
Зачем: проверить себя и побороться за мерч и технику. Организаторы обещают доставку пиццы всем участникам🍕
Когда: 4 июня, с 22 до 3 ночи
Формат: онлайн
Подача заявки: до 3 июня
Подробности и регистрация
Ресурсы, идиома RAII и Java 9
Разработка - сложная штука c множеством идей и концептов. В этом посте я расскажу об идиоме RAII, разнице при работе с ресурсами в java и C++, блоке try-with-resources и изменениях java 9.
Начнём с основ. Ресурс - это сущность, для которой нужен эксклюзивный доступ. Их количество ограничено. Большинство ресурсов находятся за пределами JVM: файлы, соединения с БД, сокеты и т.д
Для корректной работы только один поток должен работать с ресурсом. Для этого нужно принять дополнительные меры. Обозначим их как "открыть" и "закрыть" ресурс:
🔸Открыть = получить эксклюзивный доступ.
🔸Закрыть = закончить работу. Теперь другой поток может работать с ресурсом.
Такой вот нехитрый жизненный цикл(ЖЦ).
RAII
или Resource Acquisition Is Initialization - одна из техник по работе с ресурсами. Другое название: SBRM - Scope-Bound Resource Management.
Суть: ассоциируем ресурс с объектом. Тогда ЖЦ ресурса совпадает с ЖЦ объекта. В идеале это выглядит так:
В java так не получится. Деструктор выполнится неизвестно когда, а ресурс - штука ценная. Поэтому в java нужно явно вызвать метод закрытия. В стандартных библиотеках это close().
В java 7 появилась специальная конструкция для ресурсов:
Но такой формат не идеален. Внутри try всегда определяется новый объект. Когда ресурсов два и больше, код становится громоздким:
С другой - после try остаются переменные с закрытыми ресурсами. Теперь нельзя сказать, что java реализует RAII.
Ну и ладно, никто не расстроился🙂 Языки разные, и классно замечать, как по-разному в них реализуются идеи, и как они меняются с течением времени.
Разработка - сложная штука c множеством идей и концептов. В этом посте я расскажу об идиоме RAII, разнице при работе с ресурсами в java и C++, блоке try-with-resources и изменениях java 9.
Начнём с основ. Ресурс - это сущность, для которой нужен эксклюзивный доступ. Их количество ограничено. Большинство ресурсов находятся за пределами JVM: файлы, соединения с БД, сокеты и т.д
Для корректной работы только один поток должен работать с ресурсом. Для этого нужно принять дополнительные меры. Обозначим их как "открыть" и "закрыть" ресурс:
🔸Открыть = получить эксклюзивный доступ.
🔸Закрыть = закончить работу. Теперь другой поток может работать с ресурсом.
Такой вот нехитрый жизненный цикл(ЖЦ).
RAII
или Resource Acquisition Is Initialization - одна из техник по работе с ресурсами. Другое название: SBRM - Scope-Bound Resource Management.
Суть: ассоциируем ресурс с объектом. Тогда ЖЦ ресурса совпадает с ЖЦ объекта. В идеале это выглядит так:
public void do() {RAII легко реализовать в С++. В конструкторе пишем логику "открытия" ресурса, а в деструкторе - "закрытия". Конструктор и деструктор явно прописываются, поэтому ЖЦ объекта и ресурса под контролем.
File f=new File("t.txt");
// Создаём объект File, ресурс "t.txt" теперь наш
// что-то делаем
}
// вышли из метода: объект f уже не нужен, ресурс "t.txt" освобождается
В java так не получится. Деструктор выполнится неизвестно когда, а ресурс - штука ценная. Поэтому в java нужно явно вызвать метод закрытия. В стандартных библиотеках это close().
В java 7 появилась специальная конструкция для ресурсов:
try (PrintWriter writer = new PrintWriter(…)) {Ресурс реализует интерфейс AutoCloseable, и после завершения блока для него вызовется close(). try-with-resources считается java реализацией RAII.
// что-то делаем
}
Но такой формат не идеален. Внутри try всегда определяется новый объект. Когда ресурсов два и больше, код становится громоздким:
try (DatagramChannel udpServer = …;В java 9 в блок try можно передать переменные:
Selector selector = …) {
// …
}
DatagramChannel udpServer = …;С одной стороны это удобно. Код выглядит приятно.
Selector selector = …;
try (udpServer;selector) {
// …
}
С другой - после try остаются переменные с закрытыми ресурсами. Теперь нельзя сказать, что java реализует RAII.
Ну и ладно, никто не расстроился🙂 Языки разные, и классно замечать, как по-разному в них реализуются идеи, и как они меняются с течением времени.
Почему на канале так много Java Core? Потому что это база для ежедневной работы, которую хорошо знать вдоль и поперёк. Но лично мой интерес лежит в другом. Мне нравится разбирать дизайн и разбираться, почему сделано так, а не иначе.
Тема этой недели - дженерики.
Часть 1: посмотрим реализацию в JVM
Часть 2: углубимся в wildcards и работу с подтипами
Тема этой недели - дженерики.
Часть 1: посмотрим реализацию в JVM
Часть 2: углубимся в wildcards и работу с подтипами
Generics, часть 1: история и корпоративные ценности
Вернёмся в 1998 год.
В java 1.2 появились интерфейсы Map, Set, List и основные реализации. В те времена они хранили только объекты:
❌ Можно запросто получить ClassCastException
❌ Надо помнить тип объектов
❌ Ошибки возникают только в рантайме
В java 5 появилась возможность указать тип через дженерики:
✅ Хорошо читается
✅ Компилятор проверяет типы
Как реализованы дженерики?
Примерим на себя должность архитектора java и прикинем, что можно сделать с ArrayList<T>:
1️⃣ Скомпилировать в класс с типом String
Все T заменяем на String:
2️⃣ Добавить в JVM параметризованный тип
<T> остаётся на уровне байт-кода и определяется для каждого объекта в рантайме.
3️⃣ Оставить на уровне JVM работу с объектами. Проверить все типы во время компиляции и привести один к другому там, где нужно.
Получаем один ArrayList.class и множество дополнительных конструкций по всему коду.
Для ArrayList<String> программист напишет:
Почти в каждом IT офисе на стенах висят слоганы и ценности компании. Что-то про качество работы, развитие сотрудников, гибкость и довольных клиентов. Из этого получается классный корпоративный мерч.
Ценности нормального человека определяют стратегию и дают ориентир для решения сложных ситуаций. "Ценности" java явно нигде не определены, но направление работы задано чётко. Например, кроссплатформенность и слоган Write Once, Run Anywhere заставляют разработчиков JDK поддерживать фичи даже для древних процессоров.
Бинарная совместимость - ещё один ориентир java. Поэтому для дженериков используется третий вариант: компилятор добавляет необходимые приведения типов в код и стирает информацию о дженериках. И код на java 5 теперь совместим с предыдущими версиями.
Ответ на вопрос перед постом
В консоли напечатаются оба значения. У списка tmp тип не задан, поэтому компилятор не мешает добавлять строки и передавать объекты в метод println.
Если в println передать список intList.get(0), где тип указан явно, то мы получим ошибку компиляции.
Вернёмся в 1998 год.
В java 1.2 появились интерфейсы Map, Set, List и основные реализации. В те времена они хранили только объекты:
List values = new ArrayList()Чтобы нормально работать, приходилось использовать явное приведение:
values.add("value");Главная проблема с коллекциями тех лет - type loss, потеря типа при компиляции и написании кода:
String s = (String) values.get(0);
❌ Можно запросто получить ClassCastException
❌ Надо помнить тип объектов
❌ Ошибки возникают только в рантайме
В java 5 появилась возможность указать тип через дженерики:
List<String> values = new ArrayList<String>();✅ Удобно пользоваться
values.add("p");
String v = values.get(0);
✅ Хорошо читается
✅ Компилятор проверяет типы
Как реализованы дженерики?
Примерим на себя должность архитектора java и прикинем, что можно сделать с ArrayList<T>:
1️⃣ Скомпилировать в класс с типом String
Все T заменяем на String:
void add(String str)В итоге создаём отдельный класс для каждого типа данных.
String get(int index)
2️⃣ Добавить в JVM параметризованный тип
<T> остаётся на уровне байт-кода и определяется для каждого объекта в рантайме.
3️⃣ Оставить на уровне JVM работу с объектами. Проверить все типы во время компиляции и привести один к другому там, где нужно.
Получаем один ArrayList.class и множество дополнительных конструкций по всему коду.
Для ArrayList<String> программист напишет:
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), где тип указан явно, то мы получим ошибку компиляции.
Какой результат выполнения этого кода?
Anonymous Poll
34%
Ошибка на этапе компиляции
4%
RuntimeException
12%
Напечатается Parent
50%
Напечатается Child