user8126985

На Пикабу
105 рейтинг 0 подписчиков 4 подписки 3 поста 0 в горячем

Интерфейсы и абстрактные классы

Случилась со мной такая история ...

Недавно проходил собеседование на Java разработчика, как и на всех собеседованиях, задали вопрос про интерфейсы и абстрактные классы. Конечно, ответил, но все же решил перепроверить информацию на эту тему, так что здесь будет вся моя выдержка за это время

Давайте начнем с базовых ответов по теме интерфейс и абстрактный класс.

На вопрос: "Причем тут абстрактный класс?", отвечу так: "На собеседованиях эти вопросы идут рядом и в целом чем-то они похожи".

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

В те времена можно было наследовать много абстрактных классов и Василий не был исключением, наследовали его и всех его родственников. Но так получилось, что множественное наследование приводило к ошибкам наследования (одинаковые методы классов постоянно сорились) тогдв многие абстрактные классы иммигрировали в другие страны, а вместо них к Василию иммигрировали интерфейсы из public abstract Ифрики (нельзя наследовать много классов, но можно реализовывать много интерфейсов)

Таким образом Василий познакомился с интерфесом Амбалой. Амбала рассказал Василию, что он не содержит конструктора и реализовать его нельзя соответственно Методы интерфейса public и abstract по умолчанию

interface SomeInterface {

int SOME_THING = 11;

int foo();

}

Еще Амбала рассказал Василию, что содержит поле, но его поля только публичные, константные и статические, тогда как у Василия поля могут быть какими угодно. Но так было у предков Амбалы, тогда сам Амбала может содержать методы по умолчанию - медоты имеющие реализацию

interface SomeInterface {

default int foo() {

System.out.println("foo");

}

}

Также Амбала может иметь и статические методы, а обращаться к ним можно также как и к статическим методам класс

interface SomeInterface {

static int foo() {

System.out.println("foo");

}

}

public static void main(String[] args) {

SomeInterface.foo();

}

Шли годы и у Амбалы появились дети (jdk 9), они уже умели делать свои методы приватными и эти приватные методы могут быть как статическими так и нет.

Также к Амбале приехали родственники из Ифрики, оказалось, что они не содержат ни методов ни полей. "Как так получилось" - спросил Василий: "Что они умеют делать???".

Родственники рассказали Василию про таинственный полиморфизм: когда пустые интерфейсы используются, для пометки класса, реализующий этот интерфейс, чтобы использовать после этот класс в качестве реализации методов

interface Printable { }

class SomeClass implements Printable {

private int magicNumber = 3;

public int getMagicNumber() {

return magicNumber;

}

@override

public String toString() {

return String.valueOf(magicNumber);

}

}

public class Main {

public static void main(String[] args) {

var someClass = new SomeClass();

print(someClass);

}

public static void print(Printable printable) {

System.out.println(printable);

}

}

Суть в том, что тема интерфейсов оказалось гораздо интереснее чем я думал.

P.S помимо прочего веду телеграмм-канал и буду рад если поддержите IT-литературу.

Показать полностью

Будь как все говорили они ...

Всем привет. Немного душераздирающая и, вероятно, печальная тема.

Недавно слушал стрим на канале Anton Glad о качестве текста, рекомендую всем. На этом стриме он выдал интересную идею, которую я везде слышал и не понимал.

Вот Антон на стриме сказал: "Если звучишь как все, то и попадешь в банерную слепоту как все. Если выглядишь как предложения, от которых отказываются, то и от твоего тоже откажутся". И вот тут у меня произошло некое озарение.

Я уже давно учусь на программиста самостоятельно (без университета, курсов). И вот сейчас меня уже готовы взять на работу. Все это время родилели говорили мне: "У тебя нет вышки, да и образование не математическое, ты дурак, ни кто тебя не возьмет, просто так тратишь время". А недавно прошел собеседование и мне говорят: "берем, давай паспорт".

Когда родители в очередной раз начали говорить: "где тебе это пригодится", я сказал, что меня уже берут на работу ... Их реакция это что-то с чем-то: "Всмысле, без вышки???!!! А так можно?"

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

Я не говорю за всех, вероятно, только у меня такая ситуация, но у меня в жизни было столько случаев когда я спрашивал, а может вот так попробуем, а мне отвечали: "Нет, так не работает". А почему не работает? - "Ты еще маленький, юношеский максимализм, да и молоко на губах не обсохло", а еще лучше: "А что подумают люди". Как будто какой-то закостеневший слой, толщенная бетонная стена прямо на дороге. Им самим же эти убеждения мешают жить, им предлагали хорошие должности, но они отказывались, потому что придумали себе свою историю, свой мир и живут в нем.

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

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

Кстати, вот мой телеграмм-канал, в нем я обсуждаю похожие темы, программирование, IT и жизнь.

Показать полностью
9

Гав, мяу, JVM, JDK, JRE и все такое (немного Java в ленту)

Проще всего понять о чем говорим посмотреть на эту картинку. Более подробно в этом телеграмм-канале

Гав, мяу, JVM, JDK, JRE и все такое (немного Java в ленту)

В чем суть и различие?

JDK (Java Development Kit) - включает в себя Java Development Tools и среду выполнения Java - JRE (Java Runtime Environment).

JDT (Java development tools) - включают в себя около 40 различных инструментов: javac (компилятор), java (лаунчер для приложений), javap (java class file disassembler), jdb (java debugger) и др.

JRE - это пакет всего необходимого для запуска скомпилированной Java-программы. Включает в себя виртуальную машину JVM и библиотеку классов Java Class Library.

Резюмируем. Есть JDK для ведения разработки, которое содержит JRE и интсрументы разработки (тот же компилятор и дебаггер). Дальше сам JRE содержит какую-то JVM и библиотеку непонятных классов

Непосредственно JVM

JVM (Java Virtual Machine) - программа предназначенная для выполнения байт-кода. Благодрая которой, Java может работать на всех платформах. Раньше программы писали под определенную платформу, а теперь можно написать на Java и работать программа будет везде. Собственно JVM существует масса как комерческих, так и с открытым исходным кодом. А для чего пишется столько различных JVM? Нуу... Чтобы на какой-нибудь операционке работало быстрее, так же можно написать свою JVM для каких-либо своих целей

Что делает? Отвечает за загрузку классов, выполнение байт-кода, управление памятью и очисткой мусора (знаменитый сборщик мусора)

А что за байт-код? Когда мы компилирует программу мы получаем на выходе файлы с расширением .class. Это и есть файлы с байт-кодом

Есть вопрос гораздо интереснее, а как это файлы JVM находит? Что за сущность, которая говорит JVM: "О смотри что нашел, тебе нужно?". Сие носит название как Class loader

Class Loader

Загрузчики классов - это классы, часть JVM, они отдают классы в JVM, а дальше она делает с классами что захочет, но перед этим классы должны быть загружены. Загружаются классы не все разом, а по мере необходимости

Загрузчики:

1) Bootstrap classloader загружает основные библиотеки Java, расположенные в папке <JAVA_HOME>/jre/lib. Этот загрузчик является частью ядра JVM, написан на нативном коде (C, C++). Когда JVM загружает классы из rt.jar, она не выполняет все этапы проверки, которые выполняются при загрузке любого другого класс-файла т.к. JVM изначально известно, что все эти классы уже проверены. Поэтому, включать в этот архив какие-либо свои файлы не стоит, в отличие от наших классов, их JVM проверяет

2) Extension classloader загружает код в каталоги расширений (<JAVA_HOME>/jre/lib/ext, или любой другой каталог, указанный системным свойством java.ext.dirs). Если нужно, чтобы какой-то класс загружался каждый раз при старте Java машины, можешь скопировать исходный файл класса в эту папку, и он будет автоматически загружаться

3) System classloader загружает код, найденный в java.class.path, который сопоставляется с переменной среды CLASSPATH. Это реализуется классом sun.misc.Launcher$AppClassLoader.

Загрузчик классов выполняет в строгом порядке:

1) загрузка - находит и импортирует двоичные данные для типа.

2) связывание - выполняет проверку, подготовку и (необязательно) разрешение.

3) проверка - обеспечивает правильность импортируемого типа.

4) подготовка - выделяет память для переменных класса и инициализация памяти значениями по умолчанию.

5) разрешение - преобразует символические ссылки из типа в прямые ссылки.

6) инициализация - вызывает код Java, который инициализирует переменные класса их правильными начальными значениями.

Немного о проверке корректности .class

Файл скомпилированного класса (.class) содержит дополнительную информацию о классе: имя, модификаторы, супер-класс, супер-интерфейсы, поля, методы и атрибуты

Так при загрузке класса:

1) происходит чтение класс-файла, т.е проверка корректности формата

2) создается представление класса в Constant pool (Meta space, область памяти для такого рода делов)

3) грузятся супер-классы и супер-интерфейсы. Если они не будут загружены, то и сам класс не будет загружен

Загрузчик классов написан на Java. Поэтому возможно создать свой собственный загрузчик классов, не понимая тонких деталей JVM. У каждого загрузчика классов Java есть родительский загрузчик классов, определенный при создании экземпляра нового загрузчика классов или в качестве системного загрузчика классов по умолчанию для виртуальной машины

И это не все

Java нужно как-то интерпретировать байт-код, для этого есть угадайте что, интерпретатор, работает он быстро, но его недостатком является медленное выполнение. Если функция выполняется много раз он каждый раз заново компилирует байт-код в машинный код. Такую проблему решает JIT

JIT (just in time) - компилятор, который использует интерпретатор когда увидит функцию, использующую несколько раз. Т.е. интерпретатор видит повторяющийся код => отдает его на съедение JIT, а после использует сразу скомпилированный код от JIT (нативный код) и ему не нужно заново компилировать байт-код

Области тьмы (памяти)

JVM использует множество областей памяти для работы, одни области сооздаются при запуске программы и работают пока она не закончится, другие существуют поменьше

1) Heap (куча) - создается при запуске и работает пока программа не завершится. В ней хранятся объекты доступные для всех потоков из всех участков программы (не нужные объекты чистит сборщик мусора). Может быть фиксированного размера и определяться по мере выполнения программы

2) Run-Time Constant Pool - область хранения класса или интерфейса в рантайме. Хранит информацию о классе, константы (числовые литералы, ссылки на методы и поля)

3) Native Method Stacks - стеки для поддержки нативных методов, написанных не на Java

4) Java Virtual Machine Stacks - стек для потоков, т.е. каждый поток имеет свой стек. Стеки могут быть как фиксированного размера, так и динамически изменяться

5) Program Counter Register (PCR) - каждый поток имеет такую область памяти, в ней хранится адрес инструкции на которой поток завершился, чтобы потом начать с этой инструкции

Frame - новый frame создается каждый раз, когда вызывается метод. Frame уничтожается, когда завершается вызов метода. Соответсвенно раз фрэйм создается для создания метода, каждый фрейм имеет свои константы, локальные переменные. А фрейм, который выполняетсяв данный момент называется текущим, т.к. работать может только один фрейм во всей программе.
Каждый frame содержит ссылку на run-time constant pool для поддержки динамического связывания метода. Динамическое связывание загружает классы по мере необходимости. Позднее связывание методов и переменных вносит изменения в другие классы, которые метод использует с меньшей вероятностью нарушить этот код.

Почитать о том как я проходил собеседования, об IT и жизни можешь в этом телеграмм-канале

Показать полностью 1
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества