- Стек работает по схеме LIFO (последним вошел, первым вышел). Всякий раз, когда вызывается новый метод, содержащий примитивные значения или ссылки на объекты, то на вершине стека под них выделяется блок памяти. Из этого можно сделать вывод, что стек хранит значения примитивных переменных, создаваемых в методах, а также ссылки на объекты в куче на которые ссылается метод.
Когда метод завершает выполнение, блок памяти (frame), отведенный для его нужд, очищается, и пространство становится доступным для следующего метода. При этом поток выполнения программы возвращается к месту вызова этого метода с последующим переходом к следующей строке кода. - Куча. Эта область памяти используется для динамического выделения памяти для объектов и классов JRE во время выполнения. Новые объекты всегда создаются в куче, а ссылки на них хранятся в стеке.
Эти объекты имеют глобальный доступ и могут быть получены из любого места программы.
- Young Generation — область где размещаются недавно созданные объекты. Когда она заполняется, происходит быстрая сборка мусора
- Old (Tenured) Generation — здесь хранятся долгоживущие объекты. Когда объекты из Young Generation достигают определенного порога «возраста», они перемещаются в Old Generation
- Permanent Generation — эта область содержит метаинформацию о классах и методах приложения, но начиная с Java 8 данная область памяти была упразднена.
-
- JDK (Java Development Kit) - это полный пакет для разработчиков Java, который включает в себя JRE (Java Runtime Environment) и компилятор Java (javac), а также другие инструменты, необходимые для разработки Java-приложений, такие как документирование (javadoc) и инструмент для архивации (jar). JDK позволяет разрабатывать и тестировать Java-приложения.
- JRE (Java Runtime Environment) - это часть программного обеспечения, которая используется для запуска Java-приложений. Она включает в себя JVM (Java Virtual Machine), библиотеки классов и другие файлы, необходимые для выполнения программ, написанных на языке Java. JRE необходима для запуска, но не для разработки Java-приложений.
- JVM (Java Virtual Machine) - это виртуальная машина, которая исполняет байт-код Java. Она отвечает за загрузку кода, проверку кода на безопасность, его выполнение и предоставление среды выполнения, которая изолирует приложение от операционной системы. JVM делает Java платформо-независимым языком, так как байт-код может выполняться на любой машине, на которой установлена JVM.
- JIT (Just-In-Time Compiler) - это компонент JVM, который увеличивает скорость выполнения Java-приложений, компилируя байт-код в родной машинный код во время выполнения программы. Вместо интерпретации байт-кода на лету, JIT компилирует часто выполняемые части кода в машинный код для увеличения производительности.
- ClassLoader - это часть JVM, которая загружает классы Java во время выполнения. ClassLoader загружает байт-код из файлов классов (.class) в Java Runtime Environment. Он играет важную роль в концепции безопасности Java, так как разделяет пространство имен классов в соответствии с их источниками (например, классы из локальной файловой системы и классы из сетевых источников).
-
ООП (Объектно-Ориентированное Программирование) в
Javaвключает в себя четыре основных концепта:- Инкапсуляция: Сокрытие внутренней реализации класса и защита его данных.
- Наследование: Создание новых классов на основе существующих.
- Полиморфизм: Один и тот же метод может работать по-разному в зависимости от объекта, где он вызван, и данных, которые ему передали.
- Абстракция: это когда мы сосредотачиваемся только на существенных для задачи деталях и игнорируем всё остальное. В ООП абстракция означает, что для каждого объекта мы задаём минимальное количество методов, полей и описаний, которые позволят нам решить задачу. Чем меньше характеристик, тем лучше абстракция, но ключевые характеристики убирать нельзя.
-
- Абстрактный класс - это класс, который содержит как конкретные, так и абстрактные методы (методы без реализации). Абстрактный метод должен быть реализован подклассами абстрактного класса. Абстрактные классы не могут быть инстанцированы и должны быть расширены для использования. Наследовать можно только 1 абстрактный класс.
- Интерфейс подобен чертежу/контракту класса (или его можно рассматривать как класс с методами, но без их реализации). Он содержит пустые методы, которые представляют, что должно быть общим у всех его подклассов. Подклассы обеспечивают реализацию каждого из этих методов. Интерфейсы реализуются. Наследовать можно сколько угодно интерфейсов.
-
- Перегрузка метода (Method Overloading): Это когда несколько методов в одном классе имеют одно и то же имя, но различаются по типу и/или количеству параметров.
- Переопределение метода (Method Overriding): Это когда подкласс заменяет метод своего суперкласса.
-
В
Javaсуществует четыре модификатора доступа (от строжайшего к наиболее либеральному):privateпеременные, методы, конструкторы или внутренние классы видны только внутри своего класса и его методов. Этот модификатор чаще всего используется, например, для доступа к переменным только через геттеры и сеттеры или для скрытия внутренней реализации классов, которые не должны использоваться пользователем, тем самым поддерживая инкапсуляцию. Конструктор Singleton также помечается как private, чтобы избежать нежелательного инстанцирования извне.Default(ключевое слово не используется) этот модификатор может быть применен к классам, переменным, конструкторам и методам и позволяет доступ из классов и методов внутри того же пакета.protectedможет использоваться для переменных, методов и конструкторов, тем самым разрешая доступ только подклассам и классам внутри того же пакета, что и класс защищенных членов.publicмодификатор широко используется для классов, переменных, конструкторов и методов для предоставления доступа из любого класса и метода где угодно. Его не следует использовать повсеместно, поскольку это подразумевает, что данные, помеченные как public, не являются чувствительными и не могут быть использованы для нанесения вреда программе.
-
Да, интерфейс может реализовать другой интерфейс (и более одного), но ему нужно использовать ключевое слово
extends, а неimplements. И хотя вы не можете удалять методы из родительского интерфейса, вы можете свободно добавлять новые к своему подинтерфейсу. -
- Полиморфизм: Это способность одного и того же кода вести себя по-разному в зависимости от контекста, в основном достигается через переопределение метода.
- Наследование: Это механизм в
Java, позволяющий одному классу использовать поля и методы другого класса.
-
- Arrays: Простые, фиксированной длины структуры данных для хранения элементов одного типа.
- ArrayLists: Реализация изменяемого массива в
Java, которая может автоматически увеличиваться и уменьшаться.
-
ArrayList это динамический массив, оптимизированный для быстрого доступа к элементам, а LinkedList — как список со связями между элементами, оптимизированный для операций вставки и удаления. Сценарии использования: если вам часто нужен доступ к элементам по индексу, выбирайте ArrayList; если в приоритете вставка и удаление, то LinkedList.
-
HashMap — это структура данных на основе хеш-таблицы для хранения пар ключ-значение, обеспечивающая быстрый доступ O(1) к элементам. Ключи уникальны, и каждый ключ соответствует одному значению. Внутренне HashMap использует массив бакетов для хранения элементов, где индекс каждого бакета определяется хеш-функцией от ключа. В случае коллизий, когда разные ключи приводят к одному индексу, используются связные списки (до Java 8) или красно-черные деревья (с Java 8), что позволяет эффективно управлять множественными элементами в одном бакете и сохранять производительность поиска. HashMap автоматически перестраивается при росте числа элементов для оптимизации производительности, но не гарантирует порядок элементов.
-
- HashSet: Реализация множества, использующая хеш-таблицу для хранения элементов. Не гарантирует порядка элементов.
- TreeSet: Реализация множества, основанная на красно-черном дереве, которая поддерживает упорядоченность элементов по возрастанию.
-
- HashMap: Коллекция, использующая пары ключ-значение для хранения данных, где каждый ключ уникален.
- Set: Интерфейс, представляющий коллекцию уникальных элементов, не допускающий дублирования.
-
Дженерики в
Javaпозволяют программистам использовать типы (классы и интерфейсы) в качестве параметров при определении классов, интерфейсов и методов. Они обеспечивают строгую проверку типов во время компиляции и поддерживают обобщенное программирование, что делает код более безопасным и легче читаемым.
-
В
Javaнет примитивного варианта классаString- все строки являются просто обертками вокруг базового массива символов, который объявлен как final. Это означает, что, как только объектStringсоздан, он не может быть изменен с помощью обычных инструментов языка (Reflection все еще может ужасно все испортить, потому что вJavaникакой объект на самом деле не является полностью неизменяемым). Именно поэтому переменные классаStringявляются первыми кандидатами для использования, когда вы хотите переопределить hashCode() и equals() вашего класса - вы можете быть уверены, что все их требуемые контракты будут выполнены. -
Это означает, что после создания объекта
String, его содержимое (массив символов) не может быть изменено. Любые операции, которые кажутся изменяющими строку, на самом деле создают новый объектString. -
Это корневой класс в иерархии классов Java. Все классы наследуются от Object. Ключевые методы класса Object включают
equals(),hashCode(),toString(),getClass(),clone(),notify(),notifyAll(), иwait(). -
В Java хэш-код объекта — это целое число, используемое для распределения объектов в хэш-таблице. Если метод
hashCode()не переопределен, класс Object предоставляет реализацию, которая преобразует внутренний адрес объекта в целое число. -
byteshortintlongfloatdoublecharboolean
-
- Числовые типы: byte (8 бит), short (16 бит), int (32 бита), long (64 бита) представляют целочисленные значения разного размера. float (32 бита) и double (64 бита) представляют числа с плавающей точкой.
- Логический тип: boolean представляет значения истина/ложь.
- Символьный тип: char (16 бит) представляет символы в Unicode.
-
- int: примитивный тип данных, представляющий целочисленные значения.
- Integer: класс-обертка, предоставляющий методы для работы с объектами, содержащими целочисленные значения, и позволяющий использовать
intв качестве объектов.
-
В
Javaвсе параметры передаются по значению. Для объектов значение ссылки на объект копируется в параметр метода. -
Когда объект в Java становится недостижимым (т.е., на него не остается активных ссылок), он становится кандидатом на сборку мусора, что означает, что память, занимаемая этим объектом, может быть освобождена.
-
https://javarush.com/quests/lectures/questservlets.level18.lecture03
Сборщик мусора вJavaавтоматически удаляет объекты, на которые больше нет ссылок, тем самым освобождая память для повторного использования. Все объекты размещаются в куче, управляемой JVM. Пока на объект ссылаются, JVM считает его живым. Как только на объект больше не ссылаются и, следовательно, он недоступен для кода приложения, сборщик мусора удаляет его и освобождает неиспользуемую память.
В контексте GC важно понятие "графа достижимости" (reachability graph). В этом графе объекты представляются узлами, а ссылки между объектами — рёбрами. Корни этого графа — это набор "живых" объектов, доступных напрямую (например, локальные переменные стека, активные потоки выполнения, статические поля классов и т.п.). Объект считается "живым" и не подлежит удалению GC, если он достижим, то есть до него можно добраться по цепочке ссылок от одного из корней. -
- Strong Reference (Сильная ссылка): Обычная ссылка, предотвращающая сбор мусора для объекта, пока существует сильная ссылка.
- Soft Reference (Мягкая ссылка): Сбор мусора для таких объектов происходит только в случае нехватки памяти.
- Weak Reference (Слабая ссылка): Объект может быть собран мусором при следующей сборке мусора, даже если есть слабые ссылки.
- Phantom Reference (Фантомная ссылка): Объект, на который есть только фантомные ссылки, будет собран мусором, но перед этим будет помещен в очередь ссылок, что позволяет системе очистить его ресурсы.
-
Утечка памяти происходит, когда программа постоянно использует больше памяти, чем освобождает, что в конечном итоге приводит к исчерпанию доступной памяти. При переполнении памяти программа может замедлиться или аварийно завершиться.
-
В контексте сборки мусора (GC) в Java, GC Roots (корни сборки мусора) представляют собой набор объектов, которые являются отправной точкой для сборщика мусора при его работе. Эти объекты считаются "живыми" и не могут быть собраны сборщиком мусора. Сборщик мусора использует корни GC как начальные точки для определения доступных (достижимых) объектов. Любой объект, который можно достичь, пройдя от корней GC через цепочку ссылок, также считается живым и, следовательно, не подлежит уничтожению.
GC Roots включают в себя:-
Локальные переменные: Переменные, находящиеся в стеке вызовов (то есть переменные, принадлежащие активным методам).
-
Активные потоки: Объекты потока, которые все еще выполняются.
-
Статические поля: Переменные класса, поскольку они принадлежат классу, который находится в области PermGen (до Java 8) или Metaspace (начиная с Java 8) и доступен из любой точки приложения.
-
JNI (Java Native Interface) ссылки: Объекты, на которые ссылаются из нативного кода.
Эти корни формируют основу для графа достижимости — структуры данных, которую сборщик мусора использует для определения, какие объекты в куче живы и какие можно уничтожить. Процесс определения достижимых объектов начинается с этих корней и рекурсивно проходит через все объекты, на которые имеются ссылки. Объекты, до которых невозможно добраться от корней GC, считаются недостижимыми и могут быть собраны сборщиком мусора, тем самым освобождая ресурсы и память, которые они занимали.
-
-
- Deadlock возникает, когда два или более потоков в системе ожидают ресурсов, занятых друг другом, в результате чего они вечно ждут и не могут продолжить выполнение.
- Livelock – это ситуация, аналогичная deadlock, но потоки не заблокированы; они активно пытаются разрешить вопрос, но так и не достигают прогресса, постоянно меняя своё состояние в ответ на состояние друг друга.
-
Ситуация в многопоточной программе, когда несколько потоков пытаются одновременно изменить общие данные, и конечный результат зависит от того, какой поток завершит свою работу первым. Это может привести к непредсказуемым и ошибочным результатам.
-
Ключевое слово
synchronizedиспользуется для обозначения методов или блоков кода, которые могут быть выполнены только одним потоком одновременно для предотвращения проблем совместного доступа. Это помогает предотвратить race conditions при доступе к общим ресурсам. -
Классы из пакета java.util.concurrent.atomic, которые поддерживают атомарные операции на одном значении без использования синхронизации. Благодаря использованию низкоуровневых атомарных инструкций процессора, такие операции могут быть выполнены без блокировок, что делает их очень быстрыми и эффективными.
-
ThreadPoolExecutor- это реализация пула потоков вJava, которая управляет пулом рабочих потоков, позволяя эффективно выполнять множество асинхронных задач. -
Указывает компилятору и виртуальной машине Java, что значение переменной может изменяться разными потоками. Это обеспечивает, что значение переменной будет считываться из основной памяти, а не из кэша CPU, гарантируя, что чтение переменной всегда дает последнее записанное значение.
-
Классы в пакете atomic предоставляют общий набор методов: get, set, lazyset, compareAndSet, и weakCompareAndSet.
- get: возвращает текущее значение.
- set: устанавливает новое значение.
- lazyset: устанавливает новое значение с гарантией порядка изменений только в однопоточных контекстах.
- compareAndSet: атомарно устанавливает новое значение, если текущее значение соответствует ожидаемому.
- weakCompareAndSet: вариант
compareAndSetс возможностью неудачи в некоторых ситуациях для улучшения производительности.
-
- try{}: блок кода, в котором могут возникнуть исключения.
- catch{}: блок кода, обрабатывающий исключение, возникшее в блоке try.
- finally{}: блок кода, который выполняется после блоков try/catch, независимо от того, возникло исключение или нет.
-
- Проверяемые исключения (Checked Exceptions): это исключения, которые должны быть явно перехвачены или объявлены в методе.
- Непроверяемые исключения (Unchecked Exceptions): это исключения, которые не требуют явного перехвата или объявления в методе.
-
Сериализация - это процесс преобразования объекта в последовательность битов для сохранения или передачи. В
Javaэто можно реализовать с помощью интерфейсаSerializable. -
Модификатор
transientиспользуется для исключения полей класса при сериализации. -
Анонимные классы - это классы без имени, объявленные и инициализированные одновременно, обычно используются для создания экземпляров простых интерфейсов или классов на месте.
-
- ==: проверяет равенство ссылок на объекты.
- .equals(): проверяет равенство содержимого объектов.
-
Методы
hashCode()иequals()используются для сравнения объектов.hashCode()возвращает хеш-код объекта, аequals()проверяет, равны ли два объекта. -
Ключевое слово
finalиспользуется для объявления констант, переменных, которые не могут быть изменены после инициализации. -
- final: используется для объявления констант, методов, которые не могут быть переопределены, и классов, которые не могут быть наследованы.
- finally: блок кода, который выполняется после блока try/catch в конструкции обработки исключений, независимо от того, было ли исключение.
- finalize(): метод, вызываемый перед утилизацией объекта сборщиком мусора.
-
- throw: используется для явного выброса исключения.
- throws: указывает на то, что метод может выбросить исключение, и требует его обработки или дальнейшего объявления.
-
Ключевое слово
staticиспользуется для объявления членов класса, которые могут быть доступны без создания экземпляра класса. -
Статические методы не могут быть переопределены в том смысле, как переопределяются обычные методы. Они могут быть "скрыты" в подклассе, если в подклассе объявлен статический метод с тем же именем.
-
Статический блок выполняется при первой загрузке класса в JVM.
-
Рефлексия в
Javaпозволяет программе исследовать или "размышлять" о себе самой, изменять свое поведение во время выполнения. -
Внедрение зависимостей - это дизайн-паттерн, который позволяет классам получать свои зависимости извне, вместо их создания внутри себя, улучшая модульность и тестируемость.
-
- StringBuffer: потокобезопасная версия изменяемой последовательности символов.
- StringBuilder: не потокобезопасная версия, более быстрая по сравнению с
StringBufferпри выполнении операций в однопоточном режиме.
-
Быстро-сбойные итераторы немедленно выдают
ConcurrentModificationException, если коллекция была изменена после создания итератора любым способом, кроме самого итератора. Это предназначено для обнаружения ошибок в многопоточных программах. Безопасно-сбойные итераторы используют механизмы, такие как копирование коллекции, что позволяет итераторам проходить по коллекции без выбрасывания исключения, даже если основная коллекция была изменена во время итерации. -
Монитор в
Java- это механизм, обеспечивающий возможность синхронизированного доступа к блоку кода или методу, так что в каждый момент времени только один поток может исполнять блок кода или метод, помеченный какsynchronized. Синхронизация используется для предотвращения проблем совместного доступа и состояния гонки, обеспечивая, чтобы только один поток мог выполнить определенный участок кода, работающий с общими ресурсами, в данный момент времени.
