Дженерики в исключениях – что можно, а что нельзя?
1. Можно выбрасывать исключение generic-типа.
Тип-параметр T может использоваться в throws, переменная типа T может использоваться в throw. Недавно мы уже говорили об этом.
2. Нельзя использовать дженерик в catch.
Множественные блоки catch должны идти без повторений, в определенном порядке – от специфичного класса к более базовому. Стирание типов-параметров в связи с этими правилами добавило бы путаницу, не неся особой пользы.
3. Нельзя параметризовать класс-исключение типами.
Если вы попытаетесь скомпилировать конструкцию вида class MyException<T> extends Throwable {}, то увидете ошибку generic class may not extend java.lang.Throwable.
4. Можно реализовывать исключением generic-интерфейс.
Исключение вполне может быть например Comparable или Iterable. Механизм обработки исключений работает на классах, никак не затрагивая интерфейсы.
Java Guru🤓 #java
1. Можно выбрасывать исключение generic-типа.
Тип-параметр T может использоваться в throws, переменная типа T может использоваться в throw. Недавно мы уже говорили об этом.
2. Нельзя использовать дженерик в catch.
Множественные блоки catch должны идти без повторений, в определенном порядке – от специфичного класса к более базовому. Стирание типов-параметров в связи с этими правилами добавило бы путаницу, не неся особой пользы.
3. Нельзя параметризовать класс-исключение типами.
Если вы попытаетесь скомпилировать конструкцию вида class MyException<T> extends Throwable {}, то увидете ошибку generic class may not extend java.lang.Throwable.
4. Можно реализовывать исключением generic-интерфейс.
Исключение вполне может быть например Comparable или Iterable. Механизм обработки исключений работает на классах, никак не затрагивая интерфейсы.
Java Guru🤓 #java
❤11👍3🔥3
Наш чатик с вакансиями и резюме, присоединяйся: https://t.iss.one/job_java
Telegram
Java Job - Вакансии и резюме
Наш канал по Java @javalib
Вакансии Java, также можете скидывать свои резюме!
Купить звёзды: @PremiumBot
Вакансии Java, также можете скидывать свои резюме!
Купить звёзды: @PremiumBot
👍4❤3🔥2
Как ограничить upcasting типа-параметра?
Задача: запретить этому методу принимать параметры разных типов:
То есть, нужно разрешить вызывать pair(Foo, Foo), но запретить pair(Foo, Bar).
Upcasting – приведение к типу-родителю. String → Object, Integer → Number.
Дело в том, что у любых двух классов есть общий предок: как минимум Object. Если вызвать этот метод с параметрами String и Boolean – согласно правилам вычисления типа-границы, параметр T будет стерт в Object.
Использовать super тоже не поможет: для этого нужно знать заранее, какой именно тип будет передаваться.
Фокус в том, что на этапе компиляции это невозможно. Объект любого типа всегда является объектом типа-родителя (отношение is a). Это фундаментальное правило ООП, которое невозможно нарушить. К тому же, подобный метод нарушал бы принцип подстановки Лисков.
Единственная возможность добиться желаемого поведения – с помощью getClass() сравнивать классы объектов в рантайме.
Java Guru🤓 #java
Задача: запретить этому методу принимать параметры разных типов:
<T> void pair(T a, T b) {}
То есть, нужно разрешить вызывать pair(Foo, Foo), но запретить pair(Foo, Bar).
Upcasting – приведение к типу-родителю. String → Object, Integer → Number.
Дело в том, что у любых двух классов есть общий предок: как минимум Object. Если вызвать этот метод с параметрами String и Boolean – согласно правилам вычисления типа-границы, параметр T будет стерт в Object.
Использовать super тоже не поможет: для этого нужно знать заранее, какой именно тип будет передаваться.
Фокус в том, что на этапе компиляции это невозможно. Объект любого типа всегда является объектом типа-родителя (отношение is a). Это фундаментальное правило ООП, которое невозможно нарушить. К тому же, подобный метод нарушал бы принцип подстановки Лисков.
Единственная возможность добиться желаемого поведения – с помощью getClass() сравнивать классы объектов в рантайме.
Java Guru🤓 #java
🔥7❤4👍3🤔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>).
Java Guru🤓 #java
Когда вы проектируете 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>).
Java Guru🤓 #java
👍10🔥7❤2😱2
взаимодействуют через сеть?
Хотите научиться подбирать правильные протоколы для вашей системы?
Откройте для себя все особенности работы с сетевыми протоколами на открытом уроке курса «System Design».
Мы подробно рассмотрим HTTP/2, HTTP/3, gRPC и WebSocket, а также научим выбирать оптимальные технологии для вашего проекта.
Пройдите урок и получите навыки, которые улучшат архитектуру ваших решений.
Урок проходит в преддверие старта курса «System Design».
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2🔥2
Зачем нужна Java Serialization? Как сделать класс сериализуемым?
Сериализация – это сохранение типа и состояния объекта в бинарном виде для последующего сохранения/передачи и десериализации. Для сериализации используется интерфейс Serializable (Externalizable), и цель записи/источник чтения ObjectInputStream/ObjectOutputStream (ObjectInput/ObjectOutput).
Класс сериализуем, если:
🟢 Реализует маркерный интерфейс Serializable;
🟢 Все поля сериализуемые или помечены модификатором transient (иначе рантайм выбросит NotSerializableException).
Протокол стандартной сериализации описан в документации.
Сериализационная форма может, и в некоторых случаях для корректной работы должна быть кастомизирована. Правильная форма содержит только логическое представление данных, без деталей о физической реализации.
Для описания полей сериализационной формы в javadoc-документации используется тэг @serial. Для документации генерирующего нестандартную сериализационную форму метода используется @serialData. Эти тэги имеют смысл и для приватных членов, так как эффективно такие члены – часть публичного API.
Нестатические внутренние классы не должны быть сериализуемыми. Статические поля как поля класса а не инстанса несериализуемы.
Java Guru🤓 #java
Сериализация – это сохранение типа и состояния объекта в бинарном виде для последующего сохранения/передачи и десериализации. Для сериализации используется интерфейс Serializable (Externalizable), и цель записи/источник чтения ObjectInputStream/ObjectOutputStream (ObjectInput/ObjectOutput).
Класс сериализуем, если:
Протокол стандартной сериализации описан в документации.
Сериализационная форма может, и в некоторых случаях для корректной работы должна быть кастомизирована. Правильная форма содержит только логическое представление данных, без деталей о физической реализации.
Для описания полей сериализационной формы в javadoc-документации используется тэг @serial. Для документации генерирующего нестандартную сериализационную форму метода используется @serialData. Эти тэги имеют смысл и для приватных членов, так как эффективно такие члены – часть публичного API.
Нестатические внутренние классы не должны быть сериализуемыми. Статические поля как поля класса а не инстанса несериализуемы.
Java Guru🤓 #java
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥4👍2
🔍Тестовое собеседование с Java-разработчиком из Т1 Иннотех уже завтра
4 июня(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Илья Аров, старший разработчик в Т1, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Илья будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Илье
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqvnnNkd
4 июня(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Илья Аров, старший разработчик в Т1, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Илья будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Илье
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqvnnNkd
❤2👍2🔥2
Зачем используется Serial Version UID? Что если не определить его?
Сериализуемый класс явно или неявно, но всегда имеет serialVersionUID. Это число типа long, которое представляет собой «версию» сериализационной формы класса. Если при сериализации/десериализации значения serialVersionUID не совпадают – будет выброшено InvalidClassException.
Для совпадающих версий работает мощная поддержка эволюции класса – совместимые изменения, такие как добавление или удаление полей, не приводят к InvalidClassException.
Неявное значение вычисляется автоматически в рантайме, и включает в себя информацию о имени типа, списке родителей и полей (с точностью до коллизии). По смыслу это похоже на хэш-сумму класса. Соответственно, при любом изменении класса значение изменится, и поддержка эволюции окажется бесполезной.
Всегда лучше явно указывать любое значение serialVersionUID, и изменять только в тех редких случаях, когда требуется сломать совместимость с предыдущими версиями. Стандартная утилита JDK serialver умеет «угадывать» авто-генерированное значение. Она используется чтобы зафиксировать значение для включения поддержки эволюции созданного ранее класса.
Явное значение устанавливается в переменную static final long serialVersionUID.
Java Guru🤓 #java
Сериализуемый класс явно или неявно, но всегда имеет serialVersionUID. Это число типа long, которое представляет собой «версию» сериализационной формы класса. Если при сериализации/десериализации значения serialVersionUID не совпадают – будет выброшено InvalidClassException.
Для совпадающих версий работает мощная поддержка эволюции класса – совместимые изменения, такие как добавление или удаление полей, не приводят к InvalidClassException.
Неявное значение вычисляется автоматически в рантайме, и включает в себя информацию о имени типа, списке родителей и полей (с точностью до коллизии). По смыслу это похоже на хэш-сумму класса. Соответственно, при любом изменении класса значение изменится, и поддержка эволюции окажется бесполезной.
Всегда лучше явно указывать любое значение serialVersionUID, и изменять только в тех редких случаях, когда требуется сломать совместимость с предыдущими версиями. Стандартная утилита JDK serialver умеет «угадывать» авто-генерированное значение. Она используется чтобы зафиксировать значение для включения поддержки эволюции созданного ранее класса.
Явное значение устанавливается в переменную static final long serialVersionUID.
Java Guru🤓 #java
👍7❤4🔥3
На курсе «Java Developer. Professional» вы научитесь создавать современные Java-приложения, освоите Spring WebFlux и Kafka, а также разберётесь в работе JVM изнутри.
Пройдите тест, проверьте, достаточно ли у вас знаний для обучения на курсе:.
На курсе вас ждёт практическая работа с кодом, детальные разборы, ревью от экспертов и подходы, позволяющие писать эффективный и чистый код.
Начните свой путь к уровню Middle+ и используйте Java на 100%.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2🔥2
Какими методами настраивается сериализация?
Интерфейс Serializable пуст, но есть ряд методов, добавив которые в сериализуемый класс можно добиться изменения этапов процесса сериализации и десериализации.
readObjectNoData() используется для инициализации класса-родителя, который при сериализации оригинального объекта еще не был родителем. Подробное объяснение.
readObject(ObjectInputStream s) переопределяет стандартную десериализацию.
Методы readObject* похожи на конструктор. Как и конструктор, они подвержены проблеме виртуального вызова. Как и конструктор, они используются для поддержания инвариантов класса (только для случая десериализации).
writeObject(ObjectOutputStream s) используется для записи собственной сериализационной формы.
Object readResolve() может использоваться для реализации какого-либо порождающего паттерна при десериализации. Даже при его использовании объект сначала будет десериализован, поэтому рекомендуется вместе с этим методом помечать все поля transient. Видимость этого метода для наследника определяет, будет ли наследник вызывать его.
Для подмены объекта при записи добавляется симметричный метод Object writeReplace().
Интерфейс Externalizable дает инструмент полной подмены реализации сериализации. Рассмотрим его в следующих постах.
Java Guru🤓 #java
Интерфейс Serializable пуст, но есть ряд методов, добавив которые в сериализуемый класс можно добиться изменения этапов процесса сериализации и десериализации.
readObjectNoData() используется для инициализации класса-родителя, который при сериализации оригинального объекта еще не был родителем. Подробное объяснение.
readObject(ObjectInputStream s) переопределяет стандартную десериализацию.
Методы readObject* похожи на конструктор. Как и конструктор, они подвержены проблеме виртуального вызова. Как и конструктор, они используются для поддержания инвариантов класса (только для случая десериализации).
writeObject(ObjectOutputStream s) используется для записи собственной сериализационной формы.
Object readResolve() может использоваться для реализации какого-либо порождающего паттерна при десериализации. Даже при его использовании объект сначала будет десериализован, поэтому рекомендуется вместе с этим методом помечать все поля transient. Видимость этого метода для наследника определяет, будет ли наследник вызывать его.
Для подмены объекта при записи добавляется симметричный метод Object writeReplace().
Интерфейс Externalizable дает инструмент полной подмены реализации сериализации. Рассмотрим его в следующих постах.
Java Guru🤓 #java
👍4🔥4❤3
Узнай, кто ты на самом деле!
🤟На нашем вебинаре «Ты не тимлид, ты просто старший разработчик» мы разберем, что отличает инженера от настоящего лидера, а также как перейти на новый уровень и стать эффективным тимлидом: регистрация
Что будет на вебинаре?
- Почему тимлид — это не инженер, а менеджер
- Как перестроиться в роль тимлида и поменять ожидания коллег
- Где искать помощь и как развиваться в новой роли
Кому этот вебинар полезен?
- Начинающим тимлидам
- Старшим разработчикам, которые хотят стать лидерами
- Всем, кто хочет понять, как выровнять свое понимание позиции
Понравится занятие - приходите на курс «Team Lead в IT» со скидкой по промокоду TL6.
👉Регистрируйтесь сейчас - напомним перед вебинаром: https://vk.cc/cMyoZz
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🤟На нашем вебинаре «Ты не тимлид, ты просто старший разработчик» мы разберем, что отличает инженера от настоящего лидера, а также как перейти на новый уровень и стать эффективным тимлидом: регистрация
Что будет на вебинаре?
- Почему тимлид — это не инженер, а менеджер
- Как перестроиться в роль тимлида и поменять ожидания коллег
- Где искать помощь и как развиваться в новой роли
Кому этот вебинар полезен?
- Начинающим тимлидам
- Старшим разработчикам, которые хотят стать лидерами
- Всем, кто хочет понять, как выровнять свое понимание позиции
Понравится занятие - приходите на курс «Team Lead в IT» со скидкой по промокоду TL6.
👉Регистрируйтесь сейчас - напомним перед вебинаром: https://vk.cc/cMyoZz
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
❤3👍2🔥2🤣1
Как сериализация работает с наследованием?
Когда Serializable класс имеет цепочку родителей, пока эти родители тоже Serializable, десериализация объекта идет от родителя к наследнику, в обход конструктора. Вместо него вызываются методы readObject (readObjectNoData). Но как только встречается первый предок, не реализующий интерфейс Serializable, инициализация для него возвращается в нормальное русло – вместо readObject вызывается конструктор без аргументов. Если такого конструктора нет, или он объявлен private, исполнение выбросит InvalidClassException.
При сериализации несериализуемые предки просто игнорируются.
Если класс несериализуемый и не предоставляет достаточного доступа к своему логическому состоянию для наследников, правильно реализовать его наследника сериализуемым может быть невозможно.
Популярный вопрос на тему – как когда сериализуешь объект класса-наследника, избежать сериализации его родительской части. Единственный способ добиться этого – кастомизировать сериализационную форму, определив собственную реализацию writeObject(), либо используя интерфейс Externalizable.
Открытость класса для наследования делает неприменимым паттерн serialization proxy (который рассмотрим позднее).
Java Guru🤓 #java
Когда Serializable класс имеет цепочку родителей, пока эти родители тоже Serializable, десериализация объекта идет от родителя к наследнику, в обход конструктора. Вместо него вызываются методы readObject (readObjectNoData). Но как только встречается первый предок, не реализующий интерфейс Serializable, инициализация для него возвращается в нормальное русло – вместо readObject вызывается конструктор без аргументов. Если такого конструктора нет, или он объявлен private, исполнение выбросит InvalidClassException.
При сериализации несериализуемые предки просто игнорируются.
Если класс несериализуемый и не предоставляет достаточного доступа к своему логическому состоянию для наследников, правильно реализовать его наследника сериализуемым может быть невозможно.
Популярный вопрос на тему – как когда сериализуешь объект класса-наследника, избежать сериализации его родительской части. Единственный способ добиться этого – кастомизировать сериализационную форму, определив собственную реализацию writeObject(), либо используя интерфейс Externalizable.
Открытость класса для наследования делает неприменимым паттерн serialization proxy (который рассмотрим позднее).
Java Guru🤓 #java
🔥6❤4👍1
В чем разница между Serializable и Externalizable?
При записи Serializable класса весь контроль над сериализацией достается JVM. С помощью определения специальных методов можно кастомизировать его части. Метод readObject при этом обычно начинается с вызова стандартной части сериализации – ObjectInputStream.defaultReadObject().
Интерфейс Externalizable расширяет Serializable и добавляет методы записи и чтения writeExternal и readExternal. Входной и выходной потоки-аргументы в них представлены более абстрактно чем в специальных методах – интерфейсами ObjectInput и ObjectOutput.
Этот интерфейс позволяет реализовать полностью свой механизм сериализации, стандартно запишется только идентификатор класса. Никакой автоматической работы с классом-родителем также не предусмотрено. Методы readObject и writeObject игнорируются. Ключевое слово transient эффекта на Externalizable не имеет.
Externalizable объект в отличие от Serializable десерализуется не в обход конструктора, так что должен иметь конструктор без аргументов.
Java Guru🤓 #java
При записи Serializable класса весь контроль над сериализацией достается JVM. С помощью определения специальных методов можно кастомизировать его части. Метод readObject при этом обычно начинается с вызова стандартной части сериализации – ObjectInputStream.defaultReadObject().
Интерфейс Externalizable расширяет Serializable и добавляет методы записи и чтения writeExternal и readExternal. Входной и выходной потоки-аргументы в них представлены более абстрактно чем в специальных методах – интерфейсами ObjectInput и ObjectOutput.
Этот интерфейс позволяет реализовать полностью свой механизм сериализации, стандартно запишется только идентификатор класса. Никакой автоматической работы с классом-родителем также не предусмотрено. Методы readObject и writeObject игнорируются. Ключевое слово transient эффекта на Externalizable не имеет.
Externalizable объект в отличие от Serializable десерализуется не в обход конструктора, так что должен иметь конструктор без аргументов.
Java Guru🤓 #java
👍9🔥5❤1
Что такое serialization proxy?
Serialization proxy (посредник сериализации) – это паттерн, который дает простой способ определить собственную сериализационную форму.
1️⃣ Внутри целевого класса объявляется вложенный класс-посредник;
2️⃣ В посреднике объявляются поля, описывающие логическую структуру объекта (собственно, сериализационную форму);
3️⃣ Добавляется конструктор посредника, принимающий экземпляр оригинального класса и инициализирующий все эти поля;
4️⃣ Оба класса помечаются интерфейсом Serializable;
5️⃣ В методе writeReplace оригинального класса инстанциируется и возвращается прокси от this;
6️⃣ Симметричные действия совершаются для чтения – в классе-посреднике реализуется метод readResolve;
7️⃣ В основном классе добавляется readObject, который выбрасывает исключение – это защитит от чтения без прокси.
Пример кода реализации.
Java Guru🤓 #java
Serialization proxy (посредник сериализации) – это паттерн, который дает простой способ определить собственную сериализационную форму.
Пример кода реализации.
Java Guru🤓 #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥5❤3🌭1
📚 Эффективное сжатие текста: код Хаффмана в действии
Приглашаем на открытый урок.
🗓 11 июня в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Алгоритмы и структуры данных».
На этом вебинаре мы продолжим разработку архиватора, реализовав код Хаффмана.
✔️ Рассмотрим, как построить дерево кодов, где частота появления символов определяет их битовое представление.
✔️ Интегрируем алгоритм в наш архиватор и проведем сравнительное тестирование с RLE.
✔️ Увидим, как эффективно работает код Хаффмана на текстовых файлах и других типах данных.
Отличная возможность изучить продвинутые древовидные структуры данных на практическом примере.
Развивайте алгоритмическое мышление, увеличивайте производительность программ.
🎁 Всем участникам вебинара дарим промокод, который дает скидку на обучение - Algo5
👉 Регистрация на вебинар: https://vk.cc/cMzz5v
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Приглашаем на открытый урок.
🗓 11 июня в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Алгоритмы и структуры данных».
На этом вебинаре мы продолжим разработку архиватора, реализовав код Хаффмана.
Отличная возможность изучить продвинутые древовидные структуры данных на практическом примере.
Развивайте алгоритмическое мышление, увеличивайте производительность программ.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2🔥2
Назовите проблемы стандартной сериализации
Стандартная сериализация Java при всей своей гибкости обладает рядом проблем.
Дефолтная сериализация фактически добавляет все приватные поля в экспортируемый интерфейс, и ограничивает будущую гибкость реализации. От этого спасает serialization proxy.
Десериализация работает как скрытый конструктор, мимо настоящего, который обеспечивает консистентность состояния. Не сработают даже инициализаторы: поле, определенное как int foo=42, после десериализации будет хранить значение 0.
Сериализация усложняет тестирование – между разными версиями класса должна соблюдаться семантическая совместимость. Эта проблема актуальна для любой реализации персистентного хранения объектов.
Неаккуратно определенная десериализация создает дыры в безопасности. Например, сериализация объекта со слишком глубоким графом объектов-полей может привести к StackOverflowError. Злоумышленник положит вашу систему, подставив такой искусственный объект. Для защиты от различных уязвимостей в Java 8 добавлен механизм сериализационного фильтрования.
Встроенная реализация сериализует все классы одинаково хорошо. Естественно, за универсальность нужно платить, и для каждого частного случая производительность не идеальна и может быть улучшена частной реализацией.
Java Guru🤓 #java
Стандартная сериализация Java при всей своей гибкости обладает рядом проблем.
Дефолтная сериализация фактически добавляет все приватные поля в экспортируемый интерфейс, и ограничивает будущую гибкость реализации. От этого спасает serialization proxy.
Десериализация работает как скрытый конструктор, мимо настоящего, который обеспечивает консистентность состояния. Не сработают даже инициализаторы: поле, определенное как int foo=42, после десериализации будет хранить значение 0.
Сериализация усложняет тестирование – между разными версиями класса должна соблюдаться семантическая совместимость. Эта проблема актуальна для любой реализации персистентного хранения объектов.
Неаккуратно определенная десериализация создает дыры в безопасности. Например, сериализация объекта со слишком глубоким графом объектов-полей может привести к StackOverflowError. Злоумышленник положит вашу систему, подставив такой искусственный объект. Для защиты от различных уязвимостей в Java 8 добавлен механизм сериализационного фильтрования.
Встроенная реализация сериализует все классы одинаково хорошо. Естественно, за универсальность нужно платить, и для каждого частного случая производительность не идеальна и может быть улучшена частной реализацией.
Java Guru🤓 #java
👍5🔥4❤3
Как в Java разобрать JSON?
JSON – на ряду с XML, самый популярный текстовый формат передачи данных. Существует великое множество библиотек для работы с ним, здесь перечислены самые популярные.
🟢 Gson – решение от Google. В простом случае, максимально просто в применении. Популярно в Android.
🟢 org.json – Простое решение для работы с атрибутами из JSON-строки. Не умеет сериализовать из объекта в JSON и обратно.
🟢 Jackson – библиотека, знакомая всем любителям Spring Framework. Широкий простор конфигурации. Может использоваться в Java EE (в составе JAX-RS), хорошо подходит для сложных web-приложений.
🟢 JSONP – один из компонентов Java EE. Есть как стриминговая версия (экономит память при больших документах), так и обычная (когда нужно работать с документом целиком). Можно взять реализацию Glassfish, или любого другого сервера приложений. Решение «от производителя», как часто бывает, не самое популярное.
На разных данных эти решения могут показывать различную производительность, поэтому чтобы выбрать библиотеку исходя из быстродействия, нужно замерять скорость работы на конкретном приложении. Большинство готовых сравнений, которые вы найдете, заангажированы в пользу библиотеки автора этого сравнения.
Java Guru🤓 #java
JSON – на ряду с XML, самый популярный текстовый формат передачи данных. Существует великое множество библиотек для работы с ним, здесь перечислены самые популярные.
На разных данных эти решения могут показывать различную производительность, поэтому чтобы выбрать библиотеку исходя из быстродействия, нужно замерять скорость работы на конкретном приложении. Большинство готовых сравнений, которые вы найдете, заангажированы в пользу библиотеки автора этого сравнения.
Java Guru🤓 #java
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤2👍1
Чем отличается блокирующее чтение от неблокирующего?
В контексте Java речь в этом вопросе идет о блокирующем/неблокирующем чтении из потоков данных.
Классы блокирующего чтения находятся в пакете java.io. Вы наверняка много раз сталкивались с ними, работая с файлами и консольным вводом-выводом (классы Reader, IOException, InputStream). При блокирующем чтении тред останавливается, пока не получит из потока необходимые данные. Для этих самых распространенных случаев использование неблокирующего чтения не несет пользы, потому что сама запись пользователем консоли и жестким диском будет последовательной.
Чтение данных из сетевого подключения – другое дело. Обычно программа обрабатывает данные быстрее, чем работает сеть. Возникают паузы, в которые поток блокирующего чтения стоит в ожидании, не принося пользы. К тому же серверное приложение работает со многими параллельными подключениями.
Блокирующее чтение можно распараллеливать на потоки, читая в пулле. Но делать это нужно вручную, а количество одновременных подключений будет всё ещё ограничено количеством потоков-обработчиков, потоки буду всё ещё останавливаться без дела.
Для случаев, когда в вашем приложении ожидается большое количество подключений, был добавлен пакет стандартной библиотеки java.nio. С помощью NIO один тред может обслуживать несколько сетевых соединений одновременно, и переключаться между ними не теряя времени на ожидание данных.
IO использует потоки. данные приходят последовательно, и сами нигде не сохраняются. Если вы не обеспечили буферизацию вручную, нет возможности откатиться назад и прочитать уже пришедшие данные еще раз.
NIO сразу читает данные в буфер. Вы можете перемещаться по этому буферу перечитывая уже прочитанную ранее информацию. Плата за это – необходимость вручную следить, что буфер заполнен достаточным объемом данных для обработки, и что он не переполнился.
В этой статье приводится показательная аналогия. Блокирующее чтение – это телефонный разговор, неблокирующее – переписка в чате. Делая телефонный звонок, вы ждете пока собеседник ответит, можете «обрабатывать» только один звонок одновременно, получаете ответы сразу и не можете переслушать услышанный но забытый ответ. В мессенджере вы ведете несколько чатов одновременно, обращаетесь к истории переписки, но ответы на ваши сообщения приходят не всегда сразу, а порядок их получения неоднозначен.
Java Guru🤓 #java
В контексте Java речь в этом вопросе идет о блокирующем/неблокирующем чтении из потоков данных.
Классы блокирующего чтения находятся в пакете java.io. Вы наверняка много раз сталкивались с ними, работая с файлами и консольным вводом-выводом (классы Reader, IOException, InputStream). При блокирующем чтении тред останавливается, пока не получит из потока необходимые данные. Для этих самых распространенных случаев использование неблокирующего чтения не несет пользы, потому что сама запись пользователем консоли и жестким диском будет последовательной.
Чтение данных из сетевого подключения – другое дело. Обычно программа обрабатывает данные быстрее, чем работает сеть. Возникают паузы, в которые поток блокирующего чтения стоит в ожидании, не принося пользы. К тому же серверное приложение работает со многими параллельными подключениями.
Блокирующее чтение можно распараллеливать на потоки, читая в пулле. Но делать это нужно вручную, а количество одновременных подключений будет всё ещё ограничено количеством потоков-обработчиков, потоки буду всё ещё останавливаться без дела.
Для случаев, когда в вашем приложении ожидается большое количество подключений, был добавлен пакет стандартной библиотеки java.nio. С помощью NIO один тред может обслуживать несколько сетевых соединений одновременно, и переключаться между ними не теряя времени на ожидание данных.
IO использует потоки. данные приходят последовательно, и сами нигде не сохраняются. Если вы не обеспечили буферизацию вручную, нет возможности откатиться назад и прочитать уже пришедшие данные еще раз.
NIO сразу читает данные в буфер. Вы можете перемещаться по этому буферу перечитывая уже прочитанную ранее информацию. Плата за это – необходимость вручную следить, что буфер заполнен достаточным объемом данных для обработки, и что он не переполнился.
В этой статье приводится показательная аналогия. Блокирующее чтение – это телефонный разговор, неблокирующее – переписка в чате. Делая телефонный звонок, вы ждете пока собеседник ответит, можете «обрабатывать» только один звонок одновременно, получаете ответы сразу и не можете переслушать услышанный но забытый ответ. В мессенджере вы ведете несколько чатов одновременно, обращаетесь к истории переписки, но ответы на ваши сообщения приходят не всегда сразу, а порядок их получения неоднозначен.
Java Guru🤓 #java
👍7🔥6❤3
Какой метод интерфейса Мар возвращает множество ключей из карты?
Anonymous Quiz
13%
keys()
13%
entryKeys()
19%
getKeys()
44%
keySet()
11%
entrySet()
👍7🔥4❤3🌭2
Какое из утверждений о класcе LinkedList верное?
Anonymous Quiz
14%
LinkedList допускает ключи null
4%
LinkedList cортирует элементы по возрастанию
58%
LinkedList реализует интерфейсы List и Deque
7%
LinkedList является потокобезопасным
18%
LinkedList не допускает значения null
👍7🔥5🤔3