Резюме интервью по Java
1. Какие классы коллекций вы использовали?
Любимые вопросы на собеседовании по коллекциям Java для крупных компаний
40 вопросов и ответов на собеседовании по коллекциям Java
java.util.Collections — это класс-оболочка. Он содержит различные статические полиморфные методы для операций с коллекциями.
java.util.Collection — это интерфейс коллекции. Он предоставляет общие методы интерфейса для основных операций с объектами коллекции.
Collection
├Список
│├Связанный список
│├СписокМассивов
│└Вектор
│ └Стек
└Установить
Map
├Хеш-таблица
├HashMap
└WeakHashMap
Классы ArrayList, HashMap, TreeMap и HashTable обеспечивают произвольный доступ к элементам.
потокобезопасность
Vector
HashTable (не допускает нули)
Не потокобезопасный
ArrayList
LinkedList
HashMap (позволяет вставлять нулевые значения)
HashSet
TreeSet
TreeMap (реализация карты на основе красно-черного дерева)
2. Вы говорите о разнице между arraylist и linkedlist?
И ArrayList, и LinkedList реализуют интерфейс List, но между ними есть некоторые различия.
(1) ArrayList — это структура данных на основе индексов, поддерживаемая Array, поэтому она обеспечивает произвольный доступ к элементам.
(2) Вставка, добавление и удаление элемента в LinkedList будет выполняться быстрее по сравнению с ArrayList.
(3) LinkedList потребляет больше памяти, чем ArrayList, потому что каждый узел в LinkedList хранит ссылку на предыдущий и предыдущий узлы.
3. Как реализован нижний слой HashMap? Что еще есть для обработки хеш-коллизий?
Как обрабатывать коллизии хэшей:
Как правило, нет особенно хорошего способа решить HashMap: либо увеличить емкость и повторно хэшировать, либо оптимизировать структуру конфликтующего связанного списка.
1. Метод открытых адресов - метод линейного обнаружения
2. Метод открытого адреса - метод исследования квадрата
3. Решение со связанными списками — красно-черное дерево можно использовать для повышения эффективности поиска.
Введение в HashMap
HashMap — это хеш-таблица, в которой хранится карта значений ключа.
HashMap наследуется от AbstractMap и реализует интерфейсы Map, Cloneable и java.io.Serializable.
Реализация HashMap не синхронизирована, что означает, что она не является потокобезопасной, но метод synchronizedMap Collections можно использовать для обеспечения потокобезопасности HashMap.Его ключ и значение могут быть нулевыми. Кроме того, отображение в HashMap не упорядочено.
HashMap У экземпляра есть два параметра, влияющих на его производительность: «начальная мощность» и «коэффициент загрузки».Начальная емкость по умолчанию равна 16. Коэффициент загрузки по умолчанию равен 0,75,Это компромисс между временными и пространственными затратами. Высокий коэффициент загрузки снижает объем пространства, но также увеличивает стоимость запросов.
HashMap реализован массив + связанный список + красно-черное дерево (JDK1.8 добавляет красно-черную часть дерева), когда длина связанного списка слишком велика (по умолчанию превышает 8), связанный список преобразуется в красно-черное дерево.
Переосмысление HashMap в серии Java8
Реализация функции - метод
- Определите позицию индекса массива хеш-баг: Алгоритм хеширования здесь, по сути, состоит из трех шагов: получение значения ключа hashCode, операция высокого порядка и операция по модулю.
方法一:
static final int hash(Object key) { //jdk1.8 & jdk1.7
int h;
// h = key.hashCode() 为第一步 取hashCode值
// h ^ (h >>> 16) 为第二步 高位参与运算
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
方法二:
static int indexFor(int h, int length) { //jdk1.7的源码,jdk1.8没有这个方法,但是实现原理一样的
return h & (length-1); //第三步 取模运算
}
4. С какими алгоритмами вы знакомы и говорите об их временной сложности?
5. Базовый код ArrayList и Vector и их стратегии роста, как они расширяются?
Размер массива по умолчанию для ArrayList равен 10, из которых расширенный параметр sureCapacity, размер trimToSize настроен на умеренную емкость, а размер расширенного массива равен ((исходная длина массива 1,5) и больше из переданных параметров.
Расширение Vector может указать коэффициент расширения.В то же время стратегия расширения Vector: 1. 2-кратное увеличение исходной емкости, 2. исходная емкость + значение параметра расширения.
*Подробности можно прочитать в исходном коде
6. Принцип JVM. Разделение рабочей области программы
В: Область данных среды выполнения Java?
Ответ: включая счетчик программ, стек JVM, собственный стек методов, область методов, кучу.
В: Что хранится в области методов?
Стек собственных методов. Подобно роли, которую играет стек jvm, разница заключается в том, что стек jvm обслуживает выполнение java-метода (байт-кода) для jvm, а стек собственных методов обслуживает собственный метод, используемый jvm.
Стек JVM: таблица локальных переменных, стек операндов, динамическая ссылка, выход из метода.
Область метода: используется для хранения информации о классе, которая была загружена виртуальной машиной, констант, статических переменных, кода, скомпилированного компилятором JIT и т. д.
Куча: хранит экземпляры объектов.
7. Когда будут запущены минорный сборщик мусора и полный сборщик мусора? . Какой алгоритм сборки мусора используется? Краткое введение в алгоритм
GC (или Minor GC): Соберите молодняк с коротким жизненным циклом.
Полный сборщик мусора (или основной сборщик мусора): Соберите область с коротким жизненным циклом (Молодая область) и область с более длинным жизненным циклом (Старая область), чтобы выполнить сборку мусора во всей куче.新生代
Обычно время выживания невелико.На основе алгоритма копирования доступная память делится на два блока одинакового размера, и только один блок используется в каждый момент времени, когда этот блок израсходован, объекты, которые еще живы, удаляются. копируется в другой блок, а затем очищается используемая память. В HotSpot, учитывая, что у большинства объектов короткое время выживания, память делится на Эдем и двух Выживших, а соотношение по умолчанию 8:1:1. Цена в том, что есть некоторая трата памяти, которая пригодна для использования в новом поколении;老年代
и新生代
Разные, объекты в старости долго сохраняются и относительно стабильны, поэтому для утилизации используется алгоритм Марка.Так называемая метка заключается в сканировании уцелевших объектов, а затем переработке немаркированных объектов.Пространство либо объединены или помечены для следующего выделения.Короче говоря, цель состоит в том, чтобы уменьшить потерю эффективности, вызванную фрагментацией памяти.
По механизму выполнения JVM предоставляет последовательный GC (Serial GC). MSC), параллельный сборщик мусора (Parallel MSC) и параллельный сборщик мусора (CMS).
Условие запуска Minor GC, Full GC
-
Условие срабатывания Minor GC: когда область Eden заполнена, срабатывает Minor GC.
-
Полное условие триггера GC:
- (1) При вызове System.gc система рекомендует выполнить полную сборку мусора, но это не обязательно
- (2) Недостаток места в пожилом возрасте
- (3) Метод перехода в космос недостаточен
- (4) Средний размер старого поколения после прохождения Minor GC больше, чем доступная память старого поколения
- (5) При копировании из области Эдема и из области Космоса в область Космоса, если размер объекта больше, чем доступная память В Космос, объект переносится в старый возраст, а доступная память старого возраста меньше, чем размер объекта
8. Принцип реализации HashMap
В языке программирования java есть две основные структуры, одна представляет собой массив, а другая представляет собой аналоговый указатель (ссылка).Все структуры данных могут быть построены с использованием этих двух основных структур, и HashMap не является исключением. HashMap на самом деле является структурой данных «хеш связанного списка», то есть комбинацией массива и связанного списка.
9. Какие из них использовались в пакете java.util.concurrent
1. Очередь на блокировкуОчередь на блокировку(
ArrayBlockingQueue
,DelayQueue
,LinkedBlockingQueue
,SynchronousQueue
,LinkedTransferQueue
,LinkedBlockingDeque
)
2.ConcurrentHashMap
3.Semaphore
-сигнал
4.CountDownLatch
-атрезия
5.CyclicBarrier
- Изгородь
6.Exchanger
-выключатель
7.Executor
->ThreadPoolExecutor
,ScheduledThreadPoolExecutor
Semaphore semaphore = new Semaphore(1);
//critical section
semaphore.acquire();
...
semaphore.release();
8. Замок-
ReentrantLock
,ReadWriteLock
,Condition
,LockSupport
Lock lock = new ReentrantLock();
lock.lock();
//critical section
lock.unlock();
10. Разница между concurrentMap и HashMap
1.hashMap может иметь нулевые ключи, concurrentMap не может иметь
2. HashMap небезопасен для потоков. Для многопоточности требуется Collections.synchronizedMap(hashMap). ConcurrentMap использует повторные блокировки для обеспечения безопасности потоков.
3. При удалении элементов два алгоритма разные.ConcurrentHashMap
иHashtable
Основное отличие заключается в степени детализации блокировки и в том, как ее заблокировать, что можно просто понять как разложение большой HashTable на несколько блокировок для формирования разделения блокировок.
11. Что такое семафор и как им пользоваться?Что такое ключевое слово volatile?
信号量-semaphore
: механизм синхронизации, предложенный известным голландским ученым-компьютерщиком Дейкстрой в 1965 году. Это средство, используемое в многопоточной среде, которое отвечает за координацию различных потоков, чтобы гарантировать, что они могут правильно и разумно использовать общие ресурсы.
Целочисленный семафор: представляет состояние общего ресурса и может быть изменен только с помощью специальных атомарных операций.同步与互斥
: Подобные процессы взаимоисключающие (проблема с принтером), а разные процессы синхронизированы (потребитель-производитель).
Использование ключевого слова volatile является эффективным средством решения проблем синхронизации. Ключевое слово java volatile указывает, что переменная всегда "хранится в основной памяти". Более точное выражение состоит в том, что каждый раз при чтении volatile-переменной она будет считываться из основной памяти, а не из кеша ЦП. Точно так же каждый раз, когда записывается volatile переменная, она записывается обратно в основную память, а не только в кеш ЦП.
Java гарантирует, что ключевое слово volatile гарантирует, что изменения в переменных видны отдельным потокам.
12. Вы понимаете очередь блокировки? как пользоваться
BlockingQueue — важная структура данных в пакете Java util.concurrent.BlockingQueue обеспечивает потокобезопасный метод доступа к очереди: когда блокирующая очередь вставляет данные, если очередь заполнена, поток блокируется и ждет, пока очередь не заполнится. ; При выборке данных из блокирующей очереди, если очередь пуста, поток заблокируется и будет ждать, пока очередь не станет пустой. Реализация многих расширенных классов синхронизации в параллельном пакете основана на BlockingQueue.
Взяв в качестве примера ArrayBlockingQueue, давайте сначала посмотрим на код:
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
}
}
отput
Из реализации метода видно, что он сначала получает блокировку и получает прерываемую блокировку, а затем оценивает, равно ли текущее количество элементов длине массива.notFull.await()
Подожди, когда тебя разбудят другие потоки,enqueue(e)
Метод вставляет элемент и, наконец, разблокирует его.
/**
* Inserts element at current put position, advances, and signals.
* Call only when holding lock.
*/
private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length) putIndex = 0;
count++;
notEmpty.signal();
}
После успешной вставки разбудите поток, ожидающий извлечения элемента через notEmpty.
13. Что такое NIO, BIO и AIO в Java?
Методы IO обычно делятся на несколько типов, синхронный блокирующий BIO, синхронный неблокирующий NIO, асинхронный неблокирующий AIO.
1.BIO, Синхронный блокирующий ввод-вывод, простое понимание: одно соединение и один поток. Метод BIO подходит для архитектуры с относительно небольшим количеством соединений и фиксированным числом соединений. Этот метод имеет относительно высокие требования к ресурсам сервера, а параллелизм ограничен. к приложениям.Единственный выбор перед JDK1.4, но программа интуитивно понятна и проста для понимания.
До JDK1.4 при написании сетевого запроса на Java устанавливался ServerSocket.Затем, когда клиент устанавливал Socket, он спрашивал, есть ли поток для его обработки.Если нет, то либо ждал, либо отклонялся. То есть: соединение, требующее, чтобы Сервер соответствовал потоку обработки.
2.NIO, Синхронный неблокирующий ввод-вывод, простое понимание: один запрос для одного потока.Метод NIO подходит для архитектур с большим количеством подключений и относительно короткими подключениями (легкие операции), такими как чат-серверы, параллелизм ограничен приложениями, и программирование более сложное, начиная с поддержки JDK1.4.
Сам NIO основан на идеях, управляемых событиями, и его основная цель — решить большую проблему параллелизма BIO: в сетевых приложениях, использующих синхронный ввод-вывод, если вы хотите обрабатывать несколько клиентских запросов одновременно или когда потребности клиента Для одновременной связи с несколькими серверами необходимо использовать многопоточность. То есть назначьте каждый клиентский запрос потоку для индивидуальной обработки. Хотя это может удовлетворить наши требования, в то же время это принесет еще одну проблему. Потому что каждый раз, когда создается поток, для потока должен быть выделен определенный объем памяти (также называемый рабочей памятью), а сама операционная система также имеет определенный лимит на общее количество потоков. Если от клиента поступает слишком много запросов, серверная программа может быть перегружена и отклонить запрос клиента, или даже сервер может быть парализован.
3.AIO, Асинхронный неблокирующий ввод-вывод, простое понимание: один эффективный запрос для одного потока.Метод AIO используется для архитектур с большим количеством подключений и длительным подключением (тяжелая операция), например сервер фотоальбомов, который полностью вызывает ОС для участия в параллельных операциях, а программирование более сложное, начиная с поддержки JDK7.
14. Что такое механизм загрузки классов
Загрузка классов в JVM реализована с помощью ClassLoader и его подклассов Java ClassLoader является важным компонентом системы времени выполнения Java. Он отвечает за поиск и загрузку классов файла классов во время выполнения.
Пять процессов загрузки класса: загрузка, проверка, подготовка, разбор, инициализация.
С момента загрузки класса в память виртуальной машины, до момента его выгрузки из памяти весь его жизненный цикл делится на 7 этапов: Загрузка, Проверка, Подготовка, Разрешение, Инициализация (Initialization), Использование (Using). , Разгрузка (Разгрузка). Три части проверки, подготовки и синтаксического анализа в совокупности называются соединением.
15. Что такое идемпотентность
Проще говоря, так называемая идемпотентность означает, что результат нескольких обращений к интерфейсу такой же, как и результат одного обращения.
Так зачем же нам нужны идемпотентные интерфейсы? Представьте себе следующую ситуацию:
- При оформлении заказа в приложении, после нажатия подтвердить, нет ответа, поэтому нажимал несколько раз. В этом случае, если идемпотентность интерфейса не может быть гарантирована, возникнет проблема повторного выставления ордера.
- Когда сообщение получено, отправка сообщения повторяется. Если интерфейс, обрабатывающий сообщение, не может быть гарантированно идемпотентным, влияние повторного использования сообщения может быть очень большим.
16. Какой у вас опыт настройки JVM?
Сводка параметров JVM:linfengying.com/?p=2470
内存参数
параметр | эффект | |
---|---|---|
-Xmx | Максимальный размер кучи. Кучи современных основных виртуальных машин масштабируемы. | |
-Xms | Минимальный размер кучи. Может быть установлено то же значение, что и -Xmx | |
-Xmn | Размер молодого поколения. Современные виртуальные машины являются «поколенческими», поэтому пространство кучи состоит из молодых и старых поколений. По мере увеличения молодого поколения, старое поколение соответственно уменьшается. Sun официально рекомендует, чтобы на новое поколение приходилось 3/8 всей кучи | |
-Xss | Размер стека на поток. Это значение влияет на максимальное количество потоков, которые может создать машина. | |
-XX:MaxPermSize= | Максимальное значение постоянной генерации. Постоянная генерация уникальна для HotSpot, и HotSpot использует постоянную генерацию для реализации области метода. | |
-XX:PermSize= | Минимальное значение постоянной генерации. Может быть установлено то же значение, что и -XX:MaxPermSize. | |
-XX:SurvivorRatio= | Отношение Эдема к Выжившему. Сборщик мусора на основе "копии" разделит новое поколение на один Эдем и два Выживших, если параметр равен 8, значит Эдем | 80% нового поколения и по 10% у двух Выживших. По умолчанию 8 |
-XX:PretenureSizeThreshold= | Продвижение непосредственно к размеру объекта старого поколения. Объекты больше этого параметра будут размещаться непосредственно в старом поколении. Значение по умолчанию равно 0, что означает, что он не включен. | |
-XX:HandlePromotionFailure= | Разрешить ли сбои гарантии распределения. Этот параметр устарел, начиная с JDK 6 Update 24. | |
-XX:MaxTenuringThreshold= | Субъект продвигается до возраста старшего поколения. Возраст объекта увеличивается на 1 после каждого Minor GC, и когда он превышает это значение, он входит в старость. По умолчанию 15 | |
-XX:MaxDirectMemorySize= | Максимальное значение прямой памяти. Для приложений, часто использующих nio, этот параметр следует задавать явно, значение по умолчанию равно 0. |
GC参数
уборщик мусора | параметр | Примечание |
---|---|---|
Серийный (новое поколение) | -XX:+UseSerialGC | Значение по умолчанию для виртуальной машины в клиентском режиме, после включения этого переключателя используется сборочная комбинация Serial + Serial Old. Serial — это однопоточный сборщик |
ParNew (Новое поколение) | -XX:+UseParNewGC | Принудительное использование ParNew, когда этот переключатель включен, используется комбинация коллектора ParNew + Serial Old. ParNew — это многопоточный сборщик и предпочтительный сборщик нового поколения в режиме сервера. |
-XX:ParallelGCThreads= | Количество потоков для сборки мусора | |
Parallel Scavenge (новое поколение) | -XX:+UseParallelGC | Значение по умолчанию виртуальной машины в режиме сервера.После включения этого переключателя используется сборочная комбинация Parallel Scavenge + Serial Old. |
-XX:MaxGCPauseMillis= | В миллисекундах сборщик пытается обеспечить, чтобы время паузы одной коллекции памяти не превышало это значение. | |
-XX:GCTimeRatio= | Общее время, потраченное на gc в процентах от приложения, этот параметр используется для управления пропускной способностью программы. | |
-XX:+UseAdaptiveSizePolicy | После установки этого параметра больше не нужно указывать размер молодого поколения (-Xmn), соотношение Эдема и Супервизора (-XX:SurvivorRatio) и возраст объектов для продвижения старого поколения (-XX: PretenureSizeThreshold), так как коллектор будет автоматически корректироваться в соответствии с текущими условиями работы системы. Конечно, предполагается, что первыми устанавливаются первые два параметра. | |
Серийный старый | никто | Serial Old — это старая версия Serial, которая в основном используется для сбора данных старого поколения в режиме клиента, а также является резервным решением для CMS в случае сбоя параллельного режима. |
Параллельный старый | -XX:+UseParallelOldGC | Когда этот переключатель включен, используется комбинация коллекторов Parallel Scavenge + Parallel Old. Parallel Old – это старая версия Parallel Scavenge. Эта комбинация может быть приоритетной в приложениях, где важны пропускная способность и ресурсы ЦП. |
CMS (старый возраст) | -XX:+UseConcMarkSweepGC | Когда этот переключатель включен, используется комбинация коллекторов ParNew + CMS. |
-XX:CMSInitiatingOccupancyFraction= | Сборщик CMS запускает сборку мусора после того, как много места старого поколения используется | |
-XX:+UseCMSCompactAtFullCollection | Делать ли дефрагментацию памяти после завершения сборки мусора | |
-XX:CMSFullGCsBeforeCompaction= | После нескольких сборок мусора происходит только одна дефрагментация памяти. |
Рисунок: Комбинации коллекторов, которые можно использовать вместе
Сверху расположены 7 коллекторов, которые разделены на две части: верхний — коллектор нового поколения, а нижний — коллектор старого поколения. Если между двумя коллекторами есть связь, их можно использовать вместе.
其他参数
параметр | эффект |
---|---|
-verbose:class | процесс загрузки класса печати |
-XX:+PrintGCDetails | Выводить журнал gc при сборке мусора, этот параметр автоматически принимает -verbose:gc и -XX:+PrintGC |
-XX:+PrintGCDateStamps / -XX:+PrintGCTimeStamps | Распечатать событие триггера gc, можно смешивать с -XX:+PrintGC и -XX:+PrintGCDetails |
-Xloggc: | путь журнала gc |
-XX:+HeapDumpOnOutOfMemoryError | Создавайте снимки памяти для последующего анализа, когда происходит OOM |
-XX:HeapDumpPath= | путь к файлу моментального снимка дампа кучи |
17. Вы понимаете распределенную CAP?
Последовательность
Доступность
Допуск перегородки
18. Если значением ключа HashMap в Java является объект класса, каким условиям должен соответствовать класс?
Вам необходимо переопределить как метод hashCode() этого класса, так и его метод equals().
Когда программа пытается поместить пару ключ-значение в HashMap, программа сначала определяет место хранения Entry в соответствии с возвращаемым значением hashCode() ключа: если возвращаемое значение hashCode() Ключи двух записей одинаковы, то и место их хранения одинаковое. Если ключи этих двух Записей возвращают значение true при сравнении на равенство, значение вновь добавленной Записи перезапишет значение исходной Записи в коллекции, а ключ — нет. Если ключи этих двух Entry pass равны Сравнение возвращает false, вновь добавленная запись образует цепочку записей с исходной записью в коллекции, а вновь добавленная запись находится во главе цепочки записей — подробности см. в описании метода addEntry(). .
19. Будут ли в сборке мусора Java неперерабатываемые объекты? Как решить проблему с утечкой памяти? Как найти источник проблемы?
Как правило, невосстановимых объектов не будет, поскольку текущий сборщик мусора вернет недоступную память.
20. Сколько существует способов завершить поток? Почему переменная маркера завершения потока имеет тип valotile?
1. Поток выполняется нормально и нормально завершается
2. Отслеживание определенных условий и завершение непрерывного выполнения потока
3. Используйте метод прерывания для завершения потока
При определении выхода используется ключевое слово Java volatile, предназначенное для синхронизации выхода, то есть только один поток может одновременно изменять значение выхода.
21. Какие параллельные структуры данных вы использовали? Какова функция циклического барьера? роль семафора? Как решить блокировку чтения и записи базы данных
- В основном это механизмы блокировки, а затем параллельный пакет на основе CAS.
- CyclicBarrier буквально означает перерабатываемый (Циклический) барьер (Барьер). Что он делает, так это блокирует группу потоков, когда они достигают барьера (также называемого точкой синхронизации), до тех пор, пока последний поток не достигнет барьера, барьер откроет дверь, и все потоки, заблокированные барьером, продолжат работу. Конструктор CyclicBarrier по умолчанию — CyclicBarrier(int party), а его параметр указывает количество потоков, перехваченных барьером.Каждый поток вызывает метод await, чтобы сообщить CyclicBarrier, что я достиг барьера, после чего текущий поток блокируется.
Счетчик CountDownLatch можно использовать только один раз. Счетчик CyclicBarrier можно сбросить с помощью метода reset(). - Семафор (semaphore) используется для управления количеством потоков, одновременно обращающихся к определенному ресурсу, обеспечивает рациональное использование общих ресурсов за счет координации каждого потока.В течение многих лет мне было трудно буквально понимать смысл семафора.Я могу сравнить его только со светофором для управления движением.Например, XX дорога должна ограничивать движение и разрешать только сто транспортных средств на этой дороге в Во время тренировки остальные должны ждать на перекрестке, поэтому первые 100 автомобилей увидят зеленый свет и смогут выехать на эту дорогу, а следующие автомобили увидят красный свет и не смогут выехать на ХХ дорогу, но если первые 100 автомобилей Есть пять автомобилей, которые сошли с дороги XX, значит, на дорогу разрешено выехать 5 автомобилям. Автомобиль в данном примере — поток. Въезд на дорогу означает, что поток выполняется, а выезд на дорогу означает, что поток Индикатор указывает на то, что поток заблокирован и не может быть выполнен.
22. О связи между абстрактными классами и интерфейсами
Короче говоря, абстрактный класс — это класс, который не полностью функционален, а интерфейс — это просто набор объявлений абстрактных методов и статических данных, которые нельзя изменить, ни один из которых не может быть создан.
В некотором смысле интерфейс — это особая форма абстрактного класса. В языке Java абстрактный класс представляет отношение наследования. Класс может наследоваться только от одного абстрактного класса, но класс может реализовывать несколько интерфейсов. Интерфейсы действительно могут заменить абстрактные классы во многих случаях, если вам не нужно преднамеренно выражать наследование свойств.
23. Разница между памятью кучи и памятью стека
регистр: внутренний виртуальный регистр JVM, скорость доступа очень высокая, программа неуправляема.
куча: Сохранение значения локальной переменной включает в себя: 1. Сохранение значения базового типа данных 2. Сохранение ссылочной переменной, то есть ссылки (указателя) объекта кучи. Также может использоваться для сохранения кадров при загрузке методов.
куча: используется для хранения динамически генерируемых данных, таких как новые объекты. Обратите внимание, что созданные объекты содержат только свои собственные переменные-члены, а не методы-члены. Поскольку объекты одного и того же класса имеют свои собственные переменные-члены и хранятся в своих собственных кучах, но они совместно используют методы класса, методы-члены не копируются каждый раз при создании объекта.
постоянный пул: JVM поддерживает пул констант для каждого загруженного типа, который представляет собой упорядоченный набор констант, используемых этим типом. Включая прямые константы (примитивные типы, String) и символические ссылки на другие типы, методы, поля (1). Доступ к данным в пуле осуществляется по индексу, как и к массиву. Поскольку пул констант содержит все символические ссылки типа на другие типы, методы и поля, пул констант играет центральную роль в динамической компоновке Java. Постоянный пул существует в куче.
фрагмент кода: используется для хранения исходного кода, считанного с жесткого диска.
сегмент данных: используется для хранения статических членов, измененных статическими (роль статических в java заключается в том, чтобы указать, принадлежит ли переменная, метод или блок кода классу или экземпляру).
24. Объяснение внутренних классов файлов Java? Что такое анонимный внутренний класс? Как я могу получить доступ к переменной, определенной за ее пределами?
Сводка внутренних классов в java
Статический внутренний класс не может получить доступ к нестатическим членам внешнего класса###25. Разница между перегрузкой и перезаписью
Перегрузка — это перегрузка, которая представляет собой другую конкретную реализацию того же имени метода в классе. Тогда переопределение является переопределением, то есть методом в родительском классе, который переопределяется подклассом.
26. Разница между String, StringBuffer и StringBuilder
1. Сравнение скорости выполнения трех: StringBuilder > StringBuffer > String
Строка: строковая константа
StringBuffer: строковая переменная
StringBuilder: строковая переменная2.StringBuilder: потоконебезопасный, StringBuffer: потокобезопасный
Краткое изложение использования трех:
1. Если вы хотите манипулировать небольшим количеством данных, используйте = String
2. Однопоточная работа строкового буфера для работы с большим объемом данных = StringBuilder
3. Многопоточная работа строкового буфера для работы с большим объемом данных = StringBuffer
27. В чем сходство и различие между исключениями времени выполнения и общими исключениями? Общее исключение
Java предоставляет два основных типа исключений: исключение времени выполнения и проверенное исключение.
Общие исключения: NullPointerException, IndexOutOfBoundsException, ClassNotFoundException, IllegalArgumentException, ClassCastException (исключение преобразования типа данных)
### 28. В чем разница между ошибкой и исключением?
ошибка указывает на серьезную проблему, восстановление которой не невозможно, а затруднено. Например, нехватка памяти. Невозможно ожидать, что программа справится с такой ситуацией.
исключение указывает на проблему проектирования или реализации. То есть он представляет собой то, чего никогда бы не произошло, если бы программа работала правильно.
###29.Механизм обработки исключений Java
1. Перехватывать исключения: пробовать, перехватывать и наконец
2. Сгенерировать исключение
2.1 выдает исключение
methodname throws Exception1,Exception2,..,ExceptionN
{ }
30. Сколько способов реализовать поток в Java?
Многопоточное обучение Java (сверхдетальное резюме кровавой рвоты)
40 Сводка проблем многопоточности в Java
1.class Thread1 расширяет Thread{}, затем переписывает метод запуска
2.class Thread2 реализует Runnable{}, затем переписываете метод запуска
3.класс Thread3 реализует Callable {}, затем новый FutureTask(thread3), а затем оберните его новым Thread(future).
class Thread1 extends Thread {
private String name;
public Thread1(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "运行--->>>" + i);
}
}
public static void main(String[] args) {
Thread1 mTh11=new Thread1("A");
Thread1 mTh12=new Thread1("B");
mTh1.start();
mTh2.start();
}
}
class Thread2 implements Runnable {
private String name;
private int count = 15;
public Thread2() {
}
public Thread2(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "运行 : " + count--);
}
}
public static void main(String[] args) {
Thread2 mTh2 = new Thread2();
new Thread(mTh2, "C").start();
new Thread(mTh2, "D").start();
}
}
class MyCallableThread implements Callable<Integer>{
public Integer call() throws Exception {
int i = 0;
for(;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+" "+i);
}
return i;
}
public static void main(String[] args) {
MyCallableThread mct = new MyCallableThread();
FutureTask<Integer> ft = new FutureTask<Integer>(mct);
for(int i = 0;i < 100;i++)
{
System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);
if(i==20)
{
new Thread(ft,"有返回值的线程").start();
}
}
try
{
System.out.println("子线程的返回值:"+ft.get());
} catch (InterruptedException e)
{
e.printStackTrace();
} catch (ExecutionException e)
{
e.printStackTrace();
}
}
}
Если класс наследует Thread, он не подходит для совместного использования ресурсов. Но если реализован интерфейс Runable, легко добиться совместного использования ресурсов.
31. Часто используемые классы, пакеты и интерфейсы в Java.
класс: «Дата», «Система», «Календарь», «Математика», «ArrayList», «HashMap»
пакет: 'java.lang', 'java.util', 'java.io', 'java.sql', 'java.net'
интерфейс: «Коллекция», «Карта», «Список», «Запускаемый», «Вызываемый»
32. Когда java обрабатывает синхронизацию потоков, общие методы:
1. Синхронизированное ключевое слово.
2. Блокировка дисплея.
3. Семафор.
4. Алгоритм CAS
5. Параллельный пакет
33. Весенний МОК/АОП?
Ответил на концепции IOC/DI и АОП.
АОП (аспектно-ориентированное программирование, аспектно-ориентированное программирование) можно назвать дополнением и улучшением ООП (объектно-ориентированное программирование, объектно-ориентированное программирование).
ООП вводит такие понятия, как инкапсуляция, наследование и полиморфизм, чтобы установить иерархию объектов, которая имитирует набор общих поведений. Когда нам нужно ввести общее поведение для распределенных объектов, ООП бессилен.
То есть ООП позволяет определять отношения сверху вниз, но не подходит для определения отношений слева направо. Например, функция журнала. Код ведения журналов имеет тенденцию распространяться горизонтально по всем иерархиям объектов, независимо от основной функциональности объектов, на которые он распространяется.
То же самое верно и для других типов кода, таких как безопасность, обработка исключений и прозрачное сохранение. Этот посторонний код, разбросанный вокруг, называется сквозным кодом,
В ООП-дизайне это приводит к большому дублированию кода, что не способствует повторному использованию отдельных модулей.
Внедрение зависимости Injection) и Inversion of Control (Инверсия управления) — это одно и то же понятие.
Когда роли (например, экземпляру Java, вызывающему объекту) требуется помощь другой роли (другого экземпляра Java, вызываемого объекта), в традиционном программировании обычно вызывающий объект создает экземпляр вызываемого объекта.
Но в Spring работа по созданию вызываемого объекта больше не выполняется вызывающим, поэтому это называется инверсией управления; работа по созданию экземпляра вызываемого объекта обычно выполняется контейнером Spring, а затем внедряется в вызывающий объект. поэтому это также называется внедрением зависимостей.
Будь то внедрение зависимостей или инверсия управления, это показывает, что Spring использует динамичный и гибкий способ управления различными объектами. Конкретные реализации между объектами и объектами прозрачны друг для друга.
Прежде чем понять внедрение зависимостей, посмотрите, как решается следующая проблема в различных социальных формах: человеку (экземпляр Java, вызывающий объект) нужен топор (экземпляр Java, вызываемый объект).
34. Понимание мусора JVM?
Роль сборщика мусора заключается в том, чтобы находить и перерабатывать (очищать) бесполезные объекты. Чтобы позволить JVM более эффективно использовать память.
35. Разница между процессом и потоком и способы взаимодействия
Разница между потоками и процессами и способ их взаимодействия
разница
1. В программе есть хотя бы один процесс, а в процессе есть хотя бы один поток.
2. Процессы имеют независимые блоки памяти во время выполнения, в то время как несколько потоков совместно используют память.
3. Поток — это сущность процесса и основная единица планирования и диспетчеризации ЦП.
- межпроцессного взаимодействия
1.管道(Pipe)及有名管道(named pipe)
2.信号(Signal)
3.消息队列(Message)
4.共享内存
5.信号量(semaphore)
6.套接口(Socket)
36. Как JVM GC, новое поколение, старое поколение, постоянное поколение, что хранится?
Алгоритмы GC JVM:引用计数器算法
,根搜索方法
Вновь сгенерированные объекты сначала помещаются в молодое поколение. Цель молодого поколения - как можно быстрее собрать недолговечные предметы.
Объекты, пережившие N сборок мусора в молодом поколении, помещаются в старое поколение. Поэтому можно считать, что некоторые объекты с длительным жизненным циклом сохраняются в старом поколении.
Постоянное поколение в основном хранит информацию о классах классов Java.
37. На какие области разделена JVM и что делает каждая область?
В: Область данных среды выполнения Java?
Ответ: включая счетчик программ, стек JVM, собственный стек методов, область методов, кучу.
В: Что хранится в области методов?
Стек собственных методов. Подобно роли, которую играет стек jvm, разница заключается в том, что стек jvm обслуживает выполнение java-метода (байт-кода) для jvm, а стек собственных методов обслуживает собственный метод, используемый jvm.
Стек JVM: таблица локальных переменных, стек операндов, динамическая ссылка, выход из метода.
Область метода: используется для хранения информации о классе, которая была загружена виртуальной машиной, констант, статических переменных, кода, скомпилированного компилятором JIT и т. д.
Куча: хранит экземпляры объектов.
38. В алгоритме анализа достижимости ссылок, используемом GC, какие объекты могут использоваться в качестве объектов GC Roots?
- Объекты, на которые есть ссылки в стеке виртуальной машины (таблица локальных переменных во фрейме стека);
- Объект, на который ссылается статическое свойство класса в области метода;
- Объект, на который ссылается константа в области метода;
- Объект, на который ссылается JNI (то есть собственный метод в целом) в локальном стеке методов
39. Какой инструмент используется для отладки программы? jmap, jstack, JConsole, вы использовали это?
Мониторинг и настройка производительности виртуальных машин в действии — Блог
40. Использовали ли вы пул потоков?
Пул потоков — сеть параллельного программирования — ifeve.com
Пулы потоков полезны для ограничения количества потоков, одновременно выполняющихся в приложении. Поскольку каждый запуск нового потока будет иметь соответствующую нагрузку на производительность, каждый поток должен выделить часть памяти для стека и так далее.
Вместо того, чтобы запускать новый поток для каждой параллельно выполняемой задачи, мы можем передать параллельно выполняющиеся задачи в пул потоков. Пока в пуле есть незанятые потоки, задача будет назначена потоку для выполнения. Внутри пула потоков задачи вставляются в очередь блокировки (Blocking Queue), и потоки в пуле потоков будут извлекать задачи из этой очереди. Когда в очередь вставляется новая задача, бездействующий поток успешно извлекает задачу из очереди и выполняет ее.
41. Как операционная система выполняет планирование пейджинга? –Чтобы пройти тест LRU
1. Больше всего говорят о принципе замены - ОПТ
2. Принцип «первым пришел — первым вышел» — FIFO
3. Наименее недавно использовавшийся алгоритм перестановки — LRU
4. Алгоритм перестановки часов
//扩展一下LinkedHashMap这个类,让他实现LRU算法
class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V>{
//定义缓存的容量
private int capacity;
private static final long serialVersionUID = 1L;
//带参数的构造器
LRULinkedHashMap(int capacity){
//调用LinkedHashMap的构造器,传入以下参数
super(16,0.75f,true);
//传入指定的缓存最大容量
this.capacity=capacity;
}
//实现LRU的关键方法,如果map里面的元素个数大于了缓存最大容量,则删除链表的顶端元素
@Override
public boolean removeEldestEntry(Map.Entry<K, V> eldest){
System.out.println(eldest.getKey() + "=" + eldest.getValue());
return size()>capacity;
}
}
42. Расскажите о LinkedHashMap
LinkedHashMap реализуется через хэш-таблицу и связанный список.Он поддерживает связанный список, чтобы обеспечить порядок итераций хэш-таблицы, и этот порядок относится к порядку, в котором вставляются пары ключ-значение.
Общая реализация LinkedHashMap показана на рисунке ниже.Конечно, одни и те же пары ключ-значение в связанном списке и хеш-таблице указывают на один и тот же объект, и здесь они нарисованы отдельно, чтобы представить более четкую структуру.
LinkedHashMap — это реализация хэш-таблицы и связанного списка, которая опирается на двусвязный список, чтобы гарантировать, что порядок итерации соответствует порядку вставки.
Три ключевые функции
Следующие определения упоминаются в HashMap:
// Callbacks to allow LinkedHashMap post-actions
//1.把当前节点e移至链表的尾部。因为使用的是双向链表,所以在尾部插入可以以O(1)的时间复杂度来完成。并且只有当accessOrder设置为true时,才会执行这个操作。在HashMap的putVal方法中,就调用了这个方法。
void afterNodeAccess(Node<K,V> p) { }
//2.afterNodeInsertion方法是在哈希表中插入了一个新节点时调用的,它会把链表的头节点删除掉,删除的方式是通过调用HashMap的removeNode方法。通过afterNodeInsertion方法和afterNodeAccess方法,是不是就可以简单的实现一个基于最近最少使用(LRU)的淘汰策略了?当然,我们还要重写removeEldestEntry方法,因为它默认返回的是false。
void afterNodeInsertion(boolean evict) { }
//3.这个方法是当HashMap删除一个键值对时调用的,它会把在HashMap中删除的那个键值对一并从链表中删除,保证了哈希表和链表的一致性。
void afterNodeRemoval(Node<K,V> p) { }
LinkedHashMap наследуется от HashMap, поэтому эти три функции также переопределены.Как следует из названия, функции этих трех функций: делать что-то после доступа к узлу, после вставки узла и после удаления узла.
43. Связь между синхронизацией потоков и блокировкой? Синхронизация обязательно блокирует? Должна ли блокировка синхронизироваться? , В чем разница между синхронным и асинхронным?
Синхронный и асинхронный: в основном гарантированоВзаимоисключающий доступ к критически важным ресурсамСлучай
Блокировка и неблокировка: в основном с точки зрения потребления ЦП
44. Разница между int и Integer, в каких случаях использовать
1、Integer是int提供的封装类,而int是Java的基本数据类型
2、Integer默认值是null,而int默认值是0;
3、声明为Integer的变量需要实例化,而声明为int的变量不需要实例化;
4、Integer是对象,用一个引用指向这个对象,而int是基本类型,直接存储数值。
int
является основным типом данных,Integer
Это класс-оболочка. Такие структуры, как HashMap, должны использовать классы-оболочки. Поскольку классы-оболочки наследуются от Object, все они должны реализовывать HashCode, чтобы их можно было использовать в структурах данных, таких как HashMap.
45. Подробный процесс RPC
Основными направлениями RPC являются:
动态代理
,в основномinvoke
принцип отражения序列化
,использоватьThrift
высокая эффективность通信方式
,использоватьNetty
изNIO
может повысить эффективность服务发现
,использоватьzookeeper
может быть реализован
- 1) Потребитель услуги (клиент) вызывает услугу в режиме местного вызова;
- 2) после того, как клиентская заглушка получает вызов, она отвечает за сборку методов, параметров и т. д. в тело сообщения, которое может быть передано по сети;
- 3) клиентская заглушка находит адрес службы и отправляет сообщение на сервер;
- 4) Серверная заглушка декодирует сообщение после его получения;
- 5) Серверная заглушка вызывает локальную службу в соответствии с результатом декодирования;
- 6) Локальный сервис выполняется и возвращает результат на сервер-заглушку;
- 7) серверная заглушка упаковывает возвращенный результат в сообщение и отправляет его потребителю;
- 8) клиентская заглушка получает сообщение и декодирует его;
- 9) Потребитель услуги получает конечный результат.
- Для связи или большего количества контента, пожалуйста, обратите внимание на мой общедоступный номер:nezha_blog
- Мой технический блог:nezha.github.io