Анализ 100 классических вопросов JAVA-интервью в 2019 году

Java

2019 год подходит к концу, и я собрал 100 самых классических вопросов для интервью в этом году.На каждый вопрос есть развернутый ответ, сбор основ java, контейнеры, многопоточность, отражение, копирование объектов, Java Web, исключения, сеть, паттерны проектирования , Spring / Spring MVC и другие темы классических вопросов интервью и детального анализа. Ни одна тема не объяснена подробно, статья слишком длинная, вы должны терпеливо читать ее.

1. Основы Java

1. В чем разница между JDK и JRE?

  • JDK: Аббревиатура для Java Development Kit, комплект для разработки Java, который предоставляет среду разработки и среду выполнения Java.
  • JRE: сокращение от Java Runtime Environment, среда выполнения java обеспечивает необходимую среду для работы java.

В частности, JDK фактически включает в себя JRE, а также компилятор javac для компиляции исходного кода Java, а также множество инструментов для отладки и анализа программ Java. Проще говоря: если вам нужно запускать java-программы, просто установите JRE, а если вам нужно написать java-программы, вам нужно установить JDK.

2. В чем разница между == и equals?

== Интерпретация

Эффект == отличается для примитивных типов и ссылочных типов следующим образом:

  • Базовые типы: сравните, совпадают ли значения;
  • Тип ссылки: сравнение заключается в том, является ли ссылка такой же;

Пример кода:

String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true

Интерпретация кода: поскольку x и y указывают на одну и ту же ссылку, == также является истинным, а новый метод String() переписан, чтобы освободить место в памяти, поэтому результат == является ложным, а equals всегда сравнивает значение, так что все результаты верны.

равнозначная интерпретация

equals по существу ==, за исключением того, что String и Integer переопределяют метод equals и превращают его в сравнение значений. См. код ниже, чтобы понять.

Давайте сначала посмотрим, что по умолчанию equals сравнивает объект с одинаковым значением, код выглядит следующим образом:

class Cat {
 public Cat(String name) {
 this.name = name;
 }
 
 private String name;
 
 public String getName() {
 return name;
 }
 
 public void setName(String name) {
 this.name = name;
 }
}
 
Cat c1 = new Cat;
Cat c2 = new Cat;
System.out.println(c1.equals(c2)); // false

Вывод неожиданный, он ложный? Что происходит? Вы можете увидеть исходный код equals. Исходный код выглядит следующим образом:

public boolean equals(Object obj) {
 return (this == obj);
}

Оказывается, equals по сути ==.

Эта проблема возникает, два объекта String с одинаковым значением, почему TRUE? код показывает, как показано ниже:

String s1 = new String("老王");
String s2 = new String("老王");
System.out.println(s1.equals(s2)); // true

Точно так же, когда мы вводим метод equals для String и находим ответ, код выглядит следующим образом:

public boolean equals(Object anObject) {
 if (this == anObject) {
 return true;
 }
 if (anObject instanceof String) {
 String anotherString = (String)anObject;
 int n = value.length;
 if (n == anotherString.value.length) {
 char v1[] = value;
 char v2[] = anotherString.value;
 int i = 0;
 while (n-- != 0) {
 if (v1[i] != v2[i])
 return false;
 i++;
 }
 return true;
 }
 }
 return false;
}

Оказывается, String переопределяет метод equals объекта Object и изменяет сравнение ссылок на сравнение значений.

Суммировать:== — это сравнение значений для базовых типов и ссылка для ссылочных типов, а equals — это сравнение ссылок по умолчанию, но многие классы имеют методы повторного равенства, такие как String, Integer и т. д. equals сравнивает, равны ли значения.

3. Если hashCode() двух объектов один и тот же, тогда equals() тоже должно быть истинным, верно?

Нет, hashCode() двух объектов один и тот же, и equals() не обязательно истинен.

Пример кода:

String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d", str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));

Результат выполнения:

str1:1179395 | str2:1179395

false

Интерпретация кода: очевидно, что hashCode() для «вызова» и «тяжелого места» одинаковы, но equals() ложно, потому что в хэш-таблице hashCode() равен, то есть значения хеш-функции из двух пар ключ-значение равны, но ha Если значение равно, это не обязательно приводит к равенству пары ключ-значение.

4. Какова роль final в java?

  • Класс, украшенный final, называется окончательным классом, который не может быть унаследован.
  • Окончательно декорированные методы не могут быть переопределены.
  • Переменные, измененные с помощью final, называются константами.Константы должны быть инициализированы, и после инициализации их значение не может быть изменено.

5. Что такое Math.round(-1.5) в Java?

Он равен -1, потому что при взятии значения на числовой прямой среднее значение (0,5) округляется вправо, поэтому положительное 0,5 округляется в большую сторону, а отрицательное 0,5 напрямую отбрасывается.

6. Является ли String фундаментальным типом данных?

String не является базовым типом, существует 8 основных типов: byte, boolean, char, short, int, float, long, double и String — это объект.

7. Какие есть классы для работы со строками в java? В чем разница между ними?

Классы, которые работают со строками: String, StringBuffer, StringBuilder.

Разница между String и StringBuffer и StringBuilder заключается в том, что String объявляет неизменяемый объект.Каждая операция будет генерировать новый объект String, а затем указывать указатель на новый объект String, в то время как StringBuffer и StringBuilder могут работать на основе исходного объекта. Поэтому лучше не использовать String, когда содержимое строки часто изменяется.

Самая большая разница между StringBuffer и StringBuilder заключается в том, что StringBuffer является потокобезопасным, а StringBuilder — нет, но производительность StringBuilder выше, чем у StringBuffer, поэтому StringBuilder рекомендуется использовать в однопоточной среде, а StringBuffer рекомендуется в многопоточной среде. многопоточная среда.

8. Является ли строка str="i" такой же, как строка str=new String("i")?

Не то же самое, потому что память распределяется по-разному. String str="i", виртуальная машина Java выделит его в пул констант, а String str=new String("i") будет выделена в куче памяти.

9. Как перевернуть строку?

Используйте метод reverse() StringBuilder или stringBuffer.

Образец кода:

// StringBuffer reverse
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("abcdefg");
System.out.println(stringBuffer.reverse()); // gfedcba
// StringBuilder reverse
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("abcdefg");
System.out.println(stringBuilder.reverse()); // gfedcba

10. Каковы общие методы класса String?

  • indexOf(): возвращает индекс указанного символа.
  • charAt(): возвращает символ по указанному индексу.
  • replace(): замена строки.
  • trim(): удалить пробелы с обоих концов строки.
  • split(): разбивает строку и возвращает массив разделенных строк.
  • getBytes(): возвращает байтовый массив строк.
  • length(): возвращает длину строки.
  • toLowerCase(): преобразовать строку в строчные буквы.
  • toUpperCase(): преобразовать строку в символы верхнего регистра.
  • substring(): строка перехвата.
  • equals(): сравнение строк.

11. Должен ли абстрактный класс иметь абстрактные методы?

Нет, абстрактные классы не обязательно имеют абстрактные методы.

Образец кода:

abstract class Cat {
 public static void sayHi() {
 System.out.println("hi~");
 }
}

В приведенном выше коде абстрактный класс не имеет абстрактных методов, но работает отлично.

12. В чем разница между обычным классом и абстрактным классом?

  • Обычные классы не могут содержать абстрактные методы, абстрактные классы могут содержать абстрактные методы.
  • Абстрактные классы не могут быть созданы напрямую, обычные классы могут быть созданы напрямую.

13. Можно ли абстрактные классы украшать окончательными?

Нет, определение абстрактного класса позволяет наследовать другие классы. Если класс определен как окончательный, класс не может быть унаследован, что приведет к конфликту друг с другом, поэтому окончательный не может изменять абстрактный класс. Как показано на рисунке ниже, редактор также выдаст сообщение об ошибке:

14. В чем разница между интерфейсом и абстрактным классом?

  • Реализация: подклассы абстрактных классов используют расширения для наследования; интерфейсы должны использовать реализации для реализации интерфейсов.
  • Конструктор: абстрактный класс может иметь конструктор, а интерфейс — нет.
  • Основной метод: абстрактный класс может иметь основной метод, и мы можем его запустить; у интерфейса не может быть основного метода.
  • Количество реализаций: класс может реализовывать множество интерфейсов, однако он может наследоваться только от одного абстрактного класса.
  • Модификатор доступа: методы в интерфейсе по умолчанию обозначаются как public; методы в абстрактном классе могут иметь любой модификатор доступа.

15. Что такое потоки ввода-вывода в java?

Разделенные по функциям: входной поток (input), выходной поток (output).

Разделяется по типу: поток байтов и поток символов.

Разница между потоком байтов и потоком символов заключается в том, что поток байтов передает входные и выходные данные в единицах байтов по 8 битам, а поток символов передает входные и выходные данные в единицах символов по 16 битам.

16. В чем разница между BIO, NIO и AIO?

  • BIO: блочный ввод-вывод Синхронный блокирующий ввод-вывод — это традиционный ввод-вывод, который мы обычно используем, он характеризуется простым режимом, удобством использования и низким уровнем параллельной обработки.
  • NIO: новый синхронный неблокирующий ввод-вывод — это обновление традиционного ввода-вывода.Клиент и сервер взаимодействуют через канал (канал) для достижения мультиплексирования.
  • AIO: асинхронный ввод-вывод — это обновление NIO, также называемое NIO2, которое реализует асинхронный неблокирующий ввод-вывод.Работа асинхронного ввода-вывода основана на событиях и механизмах обратного вызова.

17. Каковы общие методы файлов?

  • Files.exists(): проверяет, существует ли путь к файлу.
  • Files.createFile(): создать файл.
  • Files.createDirectory(): создать папку.
  • Files.delete(): удалить файл или каталог.
  • Files.copy(): копирование файлов.
  • Files.move(): переместить файлы.
  • Files.size(): просмотр количества файлов.
  • Files.read(): прочитать файл.
  • Files.write(): записать файл.

2. Контейнеры

18. Что такое java-контейнеры?

Каталог часто используемых контейнеров:

19. В чем разница между Collection и Collections?

  • java.util.Collection — это интерфейс коллекции (интерфейс верхнего уровня для классов коллекций). Он предоставляет общие методы интерфейса для основных операций с объектами коллекции. Интерфейс Collection имеет множество конкретных реализаций в библиотеке классов Java. Значение интерфейса Collection состоит в том, чтобы обеспечить максимально унифицированный метод работы для различных конкретных коллекций, а его интерфейсы прямого наследования включают List и Set.
  • Коллекции — это класс инструментов/вспомогательный класс класса коллекции, который предоставляет ряд статических методов для сортировки, поиска и обеспечения безопасности потоков элементов в коллекции.

20. В чем разница между List, Set, Map?

21. В чем разница между HashMap и Hashtable?

  • Метод hashMap содержит удаленную HashTable, но с методами containsValue() и containsKey().
  • HashTable синхронна, а HashMap асинхронна, поэтому эффективность выше, чем у hashTable.
  • hashMap допускает нулевые значения ключа, а hashTable — нет.

22. Как решить, использовать HashMap или TreeMap?

HashMap — лучший выбор для таких операций, как вставка, удаление и поиск элементов на карте. Однако, если вам нужно обойти упорядоченный набор ключей, TreeMap — лучший выбор. В зависимости от размера вашей коллекции может быть быстрее добавить элементы в HashMap и заменить карту на TreeMap для упорядоченного обхода ключей.

23. Расскажите о принципе реализации HashMap?

Обзор HashMap: HashMap — это асинхронная реализация интерфейса Map на основе хеш-таблицы. Эта реализация предоставляет все необязательные операции с картами и допускает нулевые значения и нулевые ключи. Этот класс не гарантирует порядок карты, в частности не гарантирует, что порядок будет постоянным.

Структура данных HashMap: в языке программирования Java есть две основные структуры: одна представляет собой массив, а другая представляет собой аналоговый указатель (ссылка). Все структуры данных могут быть построены с использованием этих двух основных структур. HashMap также не является исключением. HashMap на самом деле является структурой данных «хеш связанного списка», то есть комбинацией массива и связанного списка.

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

Следует отметить, что реализация HashMap оптимизирована в Jdk 1.8.Когда данные узла в связанном списке превышают восемь, связанный список будет преобразован в красно-черное дерево для повышения эффективности запросов из исходного O (n) в O(logn)

24. Расскажите о принципе реализации HashSet?

  • Нижний слой HashSet реализуется HashMap.
  • Значение HashSet хранится в ключе HashMap.
  • Значение HashMap унифицировано как НАСТОЯЩЕЕ

25. В чем разница между ArrayList и LinkedList?

Наиболее очевидная разница заключается в том, что базовая структура данных ArrayList представляет собой массив, который поддерживает произвольный доступ, в то время как базовая структура данных LinkedList представляет собой дважды циклически связанный список, который не поддерживает произвольный доступ. Используя индексы для доступа к элементу, временная сложность ArrayList составляет O (1), а LinkedList — O (n).

26. Как реализовать преобразование между массивом и списком?

  • Преобразование списка в массив: вызовите метод toArray класса ArrayList.
  • Массивы преобразуются в списки: вызовите метод asList массива.

27. В чем разница между ArrayList и Vector?

  • Vector синхронизируется, а ArrayList — нет. Однако, если вы хотите внести изменения в список во время итерации, вы должны использовать CopyOnWriteArrayList.
  • ArrayList быстрее Vector, не перегружается из-за синхронизации.
  • ArrayList является более общим, потому что мы можем легко получить синхронизированные списки и списки только для чтения, используя служебный класс Collections.

28. В чем разница между Array и ArrayList?

  • Array может содержать примитивные типы и объекты, а ArrayList может содержать только объекты.
  • Массив имеет заданный размер, а размер ArrayList фиксирован.
  • Array не предоставляет столько функций, как ArrayList, таких как addAll, removeAll и итератор.

29. В чем разница между poll() и remove() в Queue?

И poll(), и remove() берут элемент из очереди, но poll() вернет пустое значение, если ему не удастся получить элемент, но выдаст исключение, если remove() не удастся.

30. Какие классы коллекций являются потокобезопасными?

  • Vector: Существует еще один механизм синхронизации (потокобезопасность), чем arraylist, из-за низкой эффективности использовать его сейчас не рекомендуется. В веб-приложениях, особенно на интерфейсных страницах, эффективность (отзывчивость страницы) часто является приоритетом.
  • стек: класс стека, первый пришел последним.
  • hashtable: более потокобезопасен, чем hashmap.
  • перечисление: перечисление, эквивалентное итератору.

31. Что такое итератор?

Итератор — это шаблон проектирования, это объект, который может перемещаться и выбирать объекты в последовательности, при этом разработчику не нужно знать основную структуру последовательности. Итераторы часто называют «легковесными» объектами, поскольку их создание обходится дешево.

32. Как использовать итератор? Каковы характеристики?

Функция Iterator в Java относительно проста и может двигаться только в одном направлении:

(1) Использование метода iterator() требует, чтобы контейнер возвращал итератор. При первом вызове метода next() Итератора он возвращает первый элемент последовательности. Примечание: метод iterator() — это интерфейс java.lang.Iterable, который наследуется Collection.

(2) Используйте next() для получения следующего элемента в последовательности.

(3) использование hasNext() для проверки наличия элементов в последовательности.

(4) Используйте remove() для удаления только что возвращенного элемента итератора.

Итератор — это простейшая реализация итератора Java. ListIterator, разработанный для List, имеет больше функций. Он может проходить по списку с двух сторон, а также может вставлять и удалять элементы из списка.

33. В чем разница между Iterator и ListIterator?

  • Iterator можно использовать для обхода коллекций Set и List, а ListIterator можно использовать только для обхода List.
  • Итератор может перемещаться по коллекции только вперед, а ListIterator может перемещаться вперед или назад.
  • ListIterator реализует интерфейс Iterator и содержит другие функции, такие как: добавление элементов, замена элементов, получение индекса предыдущего и следующего элементов и так далее.

3. Многопоточность

35. В чем разница между параллелизмом и параллелизмом?

  • Параллелизм — это когда два или более события происходят одновременно, тогда как параллелизм — это когда два или более события происходят в один и тот же интервал времени.
  • Параллелизм — это несколько событий в разных объектах, параллелизм — несколько событий в одном объекте.
  • Несколько задач обрабатываются «одновременно» на одном процессоре, а несколько задач обрабатываются одновременно на нескольких процессорах. Например, распределенный кластер Hadoop.

Таким образом, цель параллельного программирования состоит в том, чтобы полностью использовать каждое ядро ​​процессора для достижения максимальной производительности обработки.

36. В чем разница между потоком и процессом?

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

37. Что такое поток демона?

Поток демона (то есть поток демона) — это служебный поток, если быть точным, он обслуживает другие потоки.

38. Какие существуют способы создания темы?

① Наследуйте класс Thread, чтобы создать класс потока.

  • Определите подкласс класса Thread и переопределите метод run этого класса.Тело метода метода run представляет задачу, которую должен выполнить поток. Поэтому метод run() называется исполнителем.
  • Создание экземпляра подкласса Thread создает объект потока.
  • Вызовите метод start() объекта потока, чтобы запустить поток.

② Создайте класс потока через интерфейс Runnable.

  • Определите класс реализации исполняемого интерфейса и переопределите метод интерфейса run().Тело метода run() также является телом выполнения потока.
  • Создайте экземпляр класса реализации Runnable и используйте этот экземпляр в качестве цели Thread для создания объекта Thread, который является реальным объектом потока.
  • Вызовите метод start() объекта потока, чтобы запустить поток.

③. Создавайте темы через Callable и Future.

  • Создайте класс реализации интерфейса Callable и реализуйте метод call().Метод call() будет действовать как тело выполнения потока и иметь возвращаемое значение.
  • Создайте экземпляр класса реализации Callable и используйте класс FutureTask для создания оболочки объекта Callable, который инкапсулирует возвращаемое значение метода call() объекта Callable.
  • Создайте и запустите новый поток, используя объект FutureTask в качестве цели объекта Thread.
  • Вызовите метод get() объекта FutureTask, чтобы получить возвращаемое значение после завершения выполнения дочернего потока.

39. В чем разница между runnable и callable?

Это немного глубокий вопрос, и он также показывает широту знаний, которые может получить Java-программист.

  • Возвращаемое значение метода run() в интерфейсе Runnable равно void, и он просто выполняет код в методе run();
  • вызов Callable interface () метод возвращает значение, является универсальным, и Future, FutureTask может использоваться для получения результатов асинхронно с выполнением.

40. Каковы состояния потока?

Потоки обычно имеют пять состояний: создано, готово, выполняется, заблокировано и мертво.

  • Создать состояние. Когда создается объект потока, не вызывается метод запуска объекта, который является создаваемым потоком.
  • состояние готовности. Когда вызывается метод запуска объекта потока, поток переходит в состояние готовности, но планировщик потоков в это время не установил поток в качестве текущего потока, и в это время он находится в состоянии готовности. После того, как поток запущен, он также находится в состоянии готовности после выхода из ожидания или сна.
  • Рабочий статус. Планировщик потоков устанавливает поток в состоянии готовности в качестве текущего потока.В это время поток переходит в состояние выполнения и начинает выполнять код в функции запуска.
  • блокирующее состояние. Когда поток выполняется, он приостанавливается, обычно для ожидания наступления определенного времени (например, готовности ресурса), прежде чем продолжить выполнение. Спящий режим, приостановка, ожидание и другие методы могут привести к блокировке потока.
  • состояние смерти. Если метод запуска потока завершается или вызывается метод остановки, поток умирает. Для потока, который умер, метод запуска больше нельзя использовать для его подготовки.

41. В чем разница между sleep() и wait()?

sleep(): метод представляет собой статический метод класса потока (Thread), который переводит вызывающий поток в состояние сна и дает возможность выполнения другим потокам.По истечении времени сна поток переходит в состояние готовности и конкурирует с другими потоками на время выполнения ЦП. Поскольку sleep() является статическим методом, он не может изменить машинную блокировку объекта.Когда метод sleep() вызывается в синхронизированном блоке, хотя поток переходит в спящий режим, машинная блокировка объекта не снимается, и другие потоки по-прежнему не могут получить к нему доступ.

wait(): wait() — это метод класса Object.Когда поток выполняет метод ожидания, он входит в пул ожидания, связанный с объектом, и освобождает машинную блокировку объекта, чтобы другие потоки могли получить к нему доступ. Методы notifyAll для пробуждения ожидающих потоков.

42. В чем разница между notify() и notifyAll()?

  • Если поток вызывает метод wait() объекта, поток будет находиться в пуле ожидания объекта, и потоки в пуле ожидания не будут конкурировать за блокировку объекта.
  • Когда поток вызывает метод объекта notifyAll() (пробуждает все потоки ожидания) или метод notify() (пробуждает только один поток ожидания случайным образом), пробужденный поток входит в пул блокировок объекта, а блокировка пул в пуле блокировок Потоки будут конкурировать за блокировку объекта. Другими словами, после вызова notify только один поток войдет в пул блокировок из пула ожидания, а notifyAll переместит все потоки из пула ожидания объектов в пул блокировок, ожидая конкуренции за блокировку.
  • Потоки с высоким приоритетом имеют высокую вероятность конкуренции за блокировку объекта. Если поток не конкурирует за блокировку объекта, он останется в пуле блокировок. Только когда поток снова вызовет метод wait(), он вернется к бассейн ожидания средний. Поток, который конкурирует за блокировку объекта, будет продолжать выполняться до тех пор, пока не будет выполнен блок синхронизированного кода, и он снимет блокировку объекта.В это время потоки в пуле блокировок продолжат конкурировать за блокировку объекта.

43. В чем разница между run() и start() потока?

Каждый поток завершает свою работу с помощью метода run(), соответствующего конкретному объекту Thread, и метод run() называется телом потока. Поток запускается вызовом метода start() класса Thread.

Метод start() запускает поток, который действительно реализует многопоточную работу. В это время нет необходимости ждать завершения выполнения кода тела метода запуска, и вы можете напрямую продолжить выполнение следующего кода; в это время поток находится в состоянии готовности и не выполняется. Затем вызовите метод run() через класс Thread, чтобы завершить его рабочее состояние, где метод run() вызывает тело потока, которое содержит содержимое потока, который должен быть выполнен, метод Run завершается, и поток завершается. Затем ЦП планирует другие потоки.

Метод run() находится в этом потоке, просто функция в потоке, а не многопоточная. Если вы напрямую вызываете run(), это фактически эквивалентно вызову обычной функции.Непосредственно резервный метод run() должен дождаться выполнения метода run() для завершения выполнения следующего кода, поэтому остается только один путь выполнения, а потока вообще нет, поэтому используйте метод start() вместо метода run() при многопоточном выполнении.

44. Какие существуют способы создания пула потоков?

①.newFixedThreadPool(int nThreads)

Создайте пул потоков фиксированной длины, создайте поток каждый раз при отправке задачи, пока не будет достигнуто максимальное количество пулов потоков, при этом размер потока не изменится, а когда поток завершится с неожиданной ошибкой, поток Пул будет пополняться новым потоком.

②. newCachedThreadPool()

Создайте кэшируемый пул потоков. Если размер пула потоков превышает потребность в обработке, простаивающие потоки будут автоматически перезапущены, а когда потребность возрастет, новые потоки могут быть автоматически добавлены. Размер пула потоков не ограничен.

③.newSingleThreadExecutor()

Это однопоточный Executor, который создает один рабочий поток для выполнения задач, и если этот поток аварийно завершается, то создается новый взамен; его особенность заключается в том, чтобы задачи выполнялись последовательно в том порядке, в котором они стоят в очереди.

④.newScheduledThreadPool(int corePoolSize)

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

45. В каком состоянии находится пул потоков?

Пул потоков имеет 5 состояний: Выполняется, Выключение, Остановка, Уборка, Прекращение.

Кадровая диаграмма каждого переключения состояния пула потоков:

46. ​​В чем разница между методами submit() и execute() в пуле потоков?

  • Полученные параметры отличаются
  • submit имеет возвращаемое значение, а execute нет
  • submit удобен для обработки исключений

47. Как обеспечить безопасность многопоточности в java-программе?

Безопасность потоков отражается в трех аспектах:

  • Атомарность: обеспечивает взаимоисключающий доступ, только один поток может работать с данными одновременно (атомарный, синхронизированный);
  • Видимость: изменения потока в основной памяти могут быть видны другим потокам во времени (синхронизированные, энергозависимые);
  • Упорядоченный: поток наблюдает за порядком выполнения инструкций в других потоках.Из-за переупорядочивания инструкций результаты наблюдения, как правило, неупорядочены и неупорядочены (принцип «происходит раньше»).

48. Каков принцип обновления многопоточных замков?

В Java есть 4 состояния блокировки, а уровни от низкого до высокого: блокировки без состояния, предвзятые блокировки, облегченные блокировки и тяжелые блокировки, Эти состояния будут постепенно обостряться с конкуренцией. Замки можно улучшать, но нельзя понижать.

Схематический процесс эскалации блокировки:

49. Что такое тупик?

Взаимная блокировка — это явление, при котором два или более процессов блокируются из-за конкуренции за ресурсы или из-за связи друг с другом во время процесса выполнения.Если нет внешней силы, они не смогут продвигаться вперед. В это время говорят, что система находится в состоянии взаимоблокировки или в системе существует взаимоблокировка, и эти процессы, которые всегда ждут друг друга, называются процессами взаимоблокировки. Это ошибка на уровне операционной системы, сокращение от process deadlock. Впервые она была предложена Дейкстрой в 1965 году при изучении алгоритма банкира. Это одна из самых сложных проблем в компьютерных операционных системах и даже во всем параллельном программировании. поле.

50. Как предотвратить взаимоблокировку?

Четыре необходимых условия взаимоблокировки:

  • Условие взаимного исключения: процесс не позволяет другим процессам обращаться к выделенному ресурсу.Если другие процессы обращаются к ресурсу, они могут только ждать, пока процесс, занимающий ресурс, освободит ресурс после его использования.
  • Запрос и условия хранения: после процесса получения некоторых ресурсов, но также делает запрос на дополнительные ресурсы, но ресурсы могут быть заняты другим процессом, вопрос блокирует запрос, но удерживал собственные ресурсы.
  • Неотъемлемое условие: относится к ресурсу, полученному процессом, его нельзя лишить до того, как он будет использован, и он может быть освобожден сам по себе только после того, как он будет израсходован.
  • Состояние ожидания цикла: относится к формированию отношения ресурсов ожидания цикла «голова к хвосту» между несколькими процессами после возникновения взаимоблокировки процесса.

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

Понимая причины взаимоблокировок, особенно четыре необходимых условия для взаимоблокировок, можно избежать, предотвратить и устранить взаимоблокировки в максимально возможной степени.

Поэтому при проектировании системы, планировании процессов и т. д. обратите внимание на то, как предотвратить выполнение этих четырех необходимых условий и как определить разумный алгоритм распределения ресурсов, чтобы предотвратить постоянное занятие системных ресурсов процессами.

Более того, мы должны предотвратить возможность потребляет ресурсы без государства ожидания. Следовательно, распределение ресурсов должно быть предоставлено разумным планом.

51. Что такое ThreadLocal? Каковы сценарии использования?

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

52. Расскажите мне об основном принципе реализации synchronized?

Synchronized может гарантировать, что при выполнении метода или блока кода только один метод может одновременно войти в критическую секцию, а также может обеспечить видимость в памяти общих переменных.

Каждый объект в Java можно использовать в качестве блокировки, что является основой для синхронизированного для достижения синхронизации:

  • Общий метод синхронизации, замком является текущий экземпляр объекта
  • Статический метод синхронизации, замок является объектом класса текущего класса
  • Блок синхронизированного метода, блокировка — это объект в скобках

53. В чем разница между синхронизированным и изменчивым?

  • Суть volatile в том, чтобы сообщить jvm, что значение текущей переменной в регистре (рабочей памяти) неопределенно и его нужно считать из основной памяти; synchronized блокирует текущую переменную, доступ к переменной может получить только текущий поток, и другие темы заблокированы.
  • volatile можно использовать только на уровне переменных, а synchronized можно использовать на уровне переменных, методов и классов.
  • Volatile может обеспечить только видимость модификации переменных и не может гарантировать атомарность, в то время как синхронизация может гарантировать видимость модификации и атомарность переменных.
  • Volatile не приведет к блокировке потока, а synchronized может привести к блокировке потока.
  • Переменные, помеченные как volatile, не оптимизируются компилятором; переменные, помеченные как синхронизированные, могут быть оптимизированы компилятором.

54. В чем разница между синхронизированным и заблокированным?

  • Во-первых, synchronized — это встроенное ключевое слово Java На уровне jvm Lock — это класс Java;
  • Synchronized не может определить, следует ли получить статус блокировки, Lock может определить, следует ли получить блокировку;
  • synchronized автоматически снимет блокировку (поток снимет блокировку после выполнения кода синхронизации; b снимет блокировку, если во время выполнения потока возникнет исключение), Lock необходимо вручную снять блокировку, наконец (метод unlock() освобождает блокировку), в противном случае поток легко может умереть Lock;
  • Используя ключевое слово synchronized как для потока 1, так и для потока 2, если текущий поток 1 получает блокировку, поток потока 2 ожидает. Если поток 1 заблокирован, поток 2 будет ждать все время, и блокировка Lock не обязательно будет ждать.Если вы попытаетесь получить блокировку, поток может завершиться без ожидания все время;
  • Синхронизированные блокировки являются повторными, непрерываемыми и несправедливыми, в то время как блокировки Lock являются повторными, оценивающими и справедливыми (оба варианта возможны);
  • Блокировки блокировки подходят для проблем синхронизации с большим количеством синхронизируемых кодов, а синхронизированные блокировки подходят для проблем синхронизации с небольшим объемом кода.

55. В чем разница между синхронизированным и ReentrantLock?

Synchronized — это то же ключевое слово, что и if, else, for, while, а ReentrantLock — это класс, что является существенным различием между ними. Поскольку ReentrantLock является классом, он предоставляет более гибкие возможности, чем синхронизированный.Он может наследоваться, иметь методы и может иметь различные переменные класса.Расширяемость ReentrantLock по сравнению с синхронизированным отражается в нескольких моментах:

  • ReentrantLock может устанавливать время ожидания для получения блокировок, что позволяет избежать взаимоблокировок.
  • ReentrantLock может получать информацию о различных блокировках
  • ReentrantLock может гибко реализовать несколько уведомлений

Кроме того, механизм блокировки у них на самом деле разный: нижний уровень ReentrantLock вызывает метод парковки Unsafe для блокировки, а синхронизированная операция должна быть словом-меткой в ​​заголовке объекта.

56. Расскажите о принципе атомарности?

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

Все основные методы в классах Atomic вызывают несколько нативных методов в небезопасном классе. Прежде всего, нам нужно знать о классе Unsafe, полное имя которого: sun.misc.Unsafe. Этот класс содержит множество операций над кодом C, в том числе множество прямых выделений памяти и вызовов атомарных операций, а также причину, по которой он помечен как небезопасный, означает, что большое количество вызовов методов в этой области будет иметь риски безопасности, и использовать их нужно осторожно, иначе это приведет к серьезным последствиям, например, при выделении памяти через небезопасные , если вы укажете определенные области самостоятельно, это может привести к некоторому похожему C++ Проблема выхода указателя на другой процесс.

4. Отражение

57. Что такое отражение?

Отражение в основном относится к способности программы получать доступ, обнаруживать и изменять свое собственное состояние или поведение.

Отражение Java:

Можете ли вы узнать, какие свойства и методы у этого класса есть в среде выполнения Java для любого класса? Для любого объекта может быть вызван любой его метод

Механизм отражения Java в основном предоставляет следующие функции:

  • Определяет класс, к которому принадлежит любой объект во время выполнения.
  • Создает объект любого класса во время выполнения.
  • Определите переменные-члены и методы любого класса во время выполнения.
  • Вызов метода для любого объекта во время выполнения.

58. Что такое сериализация Java? Когда требуется сериализация?

Проще говоря, это сохранение состояния различных объектов в памяти (то есть переменных экземпляра, а не методов) и чтение сохраненного состояния объекта. Хотя вы можете сохранять состояния объектов различными способами, Java предоставляет вам механизм для сохранения состояний объектов, который должен быть лучше, чем ваш собственный, — это сериализация.

Когда сериализовать:

а) Когда вы хотите сохранить состояние объекта в памяти в файл или базу данных;

б) Когда вы хотите использовать объект передачи разъема в сети;

в) когда вы хотите передать объекты через RMI;

59. Что такое динамический прокси? Какие приложения есть?

Динамический прокси:

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

Применение динамического прокси:

  • Весенний АОП
  • Плюс дела
  • Взвешенный лимит
  • добавить журнал

60. Как реализовать динамический прокси?

Сначала должен быть определен интерфейс и класс-обработчик InvocationHandler (которому передается объект класса, реализующего интерфейс). Есть еще один инструментальный класс Proxy (его принято называть прокси-классом, потому что вызов его newInstance() может генерировать прокси-объект, по сути, он просто инструментальный класс, генерирующий прокси-объект). Используя InvocationHandler, соедините исходный код прокси-класса, скомпилируйте его для создания двоичного кода прокси-класса, загрузите его с помощью загрузчика, создайте его экземпляр для создания прокси-объекта и, наконец, верните.

5. Копия объекта

61. Зачем использовать клон?

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

62. Как добиться клонирования объекта?

Есть два способа:

1) Реализовать интерфейс Cloneable и переопределить метод clone() в классе Object;

2) Реализуйте интерфейс Serializable и реализуйте клон посредством сериализации и десериализации объекта, который может реализовать настоящий глубокий клон.Код выглядит следующим образом:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
public class MyUtil {
 
 private MyUtil() {
 throw new AssertionError();
 }
 
 @SuppressWarnings("unchecked")
 public static <T extends Serializable> T clone(T obj) throws Exception {
 ByteArrayOutputStream bout = new ByteArrayOutputStream();
 ObjectOutputStream oos = new ObjectOutputStream(bout);
 oos.writeObject(obj);
 
 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
 ObjectInputStream ois = new ObjectInputStream(bin);
 return (T) ois.readObject();
 
 // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义
 // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
 }
}

Вот тестовый код:

import java.io.Serializable;
 
/**
 * 人类
 * @author nnngu
 *
 */
class Person implements Serializable {
 private static final long serialVersionUID = -9102017020286042305L;
 
 private String name; // 姓名
 private int age; // 年龄
 private Car car; // 座驾
 
 public Person(String name, int age, Car car) {
 this.name = name;
 this.age = age;
 this.car = car;
 }
 
 public String getName() {
 return name;
 }
 
 public void setName(String name) {
 this.name = name;
 }
 
 public int getAge() {
 return age;
 }
 
 public void setAge(int age) {
 this.age = age;
 }
 
 public Car getCar() {
 return car;
 }
 
 public void setCar(Car car) {
 this.car = car;
 }
 
 @Override
 public String toString() {
 return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
 }
 
}/**
 * 小汽车类
 * @author nnngu
 *
 */
class Car implements Serializable {
 private static final long serialVersionUID = -5713945027627603702L;
 
 private String brand; // 品牌
 private int maxSpeed; // 最高时速
 
 public Car(String brand, int maxSpeed) {
 this.brand = brand;
 this.maxSpeed = maxSpeed;
 }
 
 public String getBrand() {
 return brand;
 }
 
 public void setBrand(String brand) {
 this.brand = brand;
 }
 
 public int getMaxSpeed() {
 return maxSpeed;
 }
 
 public void setMaxSpeed(int maxSpeed) {
 this.maxSpeed = maxSpeed;
 }
 
 @Override
 public String toString() {
 return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]";
 }
 
}


class CloneTest {
 
 public static void main(String[] args) {
 try {
 Person p1 = new Person("郭靖", 33, new Car("Benz", 300));
 Person p2 = MyUtil.clone(p1); // 深度克隆
 p2.getCar().setBrand("BYD");
 // 修改克隆的Person对象p2关联的汽车对象的品牌属性
 // 原来的Person对象p1关联的汽车不会受到任何影响
 // 因为在克隆Person对象时其关联的汽车对象也被克隆了
 System.out.println(p1);
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
}

Примечание: Клонирование на основе сериализации и десериализации — это не только глубокое клонирование, но, что более важно, с помощью универсальной квалификации вы можете проверить, поддерживает ли клонируемый объект сериализацию.Эта проверка выполняется компилятором, а не во время выполнения. Это решение значительно лучше, чем использование метода clone класса Object для клонирования объекта. Всегда лучше выявлять проблему во время компиляции, чем оставлять ее во время выполнения.

63. В чем разница между глубокой копией и мелкой копией?

  • Неглубокая копия просто копирует ссылочный адрес объекта, два объекта указывают на один и тот же адрес памяти, поэтому измените любое из значений, другое значение изменится, это поверхностная копия (например: assign())
  • Глубокая копия копирует объект и его значение, два объекта изменяют любое значение, а другое значение не изменяется, это глубокая копия (например: JSON.parse() и JSON.stringify(), но этот метод не может копировать функции тип)

6. Веб-сайт Java

64. В чем разница между jsp и сервлетом?

  1. После того, как jsp скомпилирован, он становится сервлетом (Суть JSP — это сервлет, JVM может распознавать только классы java, но не код JSP. Веб-контейнер компилирует код JSP в классы java, которые JVM может распознать )
  2. Jsp лучше отображает страницы, а сервлет лучше управляет логикой.
  3. Нет встроенных объектов сервлета, JSP в встроенных объектах необходимы, объекты httpservletresponse httpservlet и объекты, полученные объектом httpservletrequest.
  4. Jsp - это упрощение сервлета. Использование Jsp необходимо только для завершения содержимого, которое программист должен вывести на клиент. Как вставить сценарий Java в Jsp в класс, завершается контейнером Jsp. Сервлет — это полный класс Java, метод службы этого класса используется для генерации ответа клиенту.

65. Какие встроенные объекты jsp? Каковы функции?

JSP имеет 9 встроенных объектов:

  • запрос: инкапсулирует запрос клиента, который содержит параметры из запроса GET или POST;
  • ответ: инкапсулирует ответ сервера клиенту;
  • pageContext: через этот объект можно получить другие объекты;
  • сеанс: объект, который инкапсулирует пользовательский сеанс;
  • Приложение: Объект инкапсулирующего сервера эксплуатируется;
  • out: объект потока вывода ответа сервера вывода;
  • config: объект конфигурации веб-приложения;
  • page: сама страница JSP (эквивалентно этому в программе Java);
  • Исключение: страница пакета, бросающаяся исключение.

66. Расскажите мне о 4-х областях jsp?

JSP в четырех часах включают страницу, запрос, сеанс и приложение, в частности:

  • page представляет объекты и свойства, связанные со страницей.
  • request представляет объекты и атрибуты, связанные с запросом, выданным веб-клиентом. Запрос может охватывать несколько страниц и включать несколько веб-компонентов; в эту область можно поместить временные данные, которые необходимо отобразить на странице.
  • сеанс представляет объекты и атрибуты, связанные с сеансом, установленным пользователем с сервером. Данные, относящиеся к пользователю, должны быть размещены в собственном сеансе пользователя.
  • application представляет объекты и свойства, связанные со всем веб-приложением, которое по сути представляет собой глобальную область действия для всего веб-приложения, включая несколько страниц, запросов и сеансов.

67. В чем разница между сеансом и файлом cookie?

  • Поскольку протокол HTTP - это протокол без природы, когда сервер должен записать состояние пользователя, необходимо использовать механизм для идентификации конкретного пользователя. Этот механизм является сеансом. Типичный сценарий - это корзина для покупок, когда вы нажимаете Кнопка заказа, потому что протокол HTTP является нестандартным, он не знает, какой пользователь работает, поэтому сервер должен создать определенный сеанс для конкретного пользователя, который используется для идентификации пользователя и отслеживать пользователя, чтобы узнать, как Многие в корзине. Книга. Эта сессия хранится на сервере и имеет уникальный идентификатор. Есть много способов сохранения сеансов на сервере, включая память, базу данных и файлы. Передача сеанса также должна рассматриваться при кластеризации. На больших веб-сайтах, как правило, необходимо, как правило, выделенный кластер серверов сеанса для сохранения сеансов пользователей. В это время используется информация о сеансе в памяти, а некоторые сервисы кэширования, такие как memcached. Сессия.
  • Подумайте, как сервер идентифицирует конкретный клиент? В это время печенье дебютировала. Когда каждый запрос HTTP запрашивается, клиент отправит соответствующую информацию файла cookie на сервер. Фактически, большинство приложений используют файлы cookie для реализации отслеживания сеанса. Когда вы впервые создаете сеанс, сервис будет сообщить клиенту в протоколе HTTP, вам необходимо записать идентификатор сеанса в cookie, и вы запрашиваете это позже. Сеанс ID отправляется на сервер, я знаю, кто вы есть. Кто-то спросил, что если браузер клиента отключено файлы cookie? В этом случае методика, называемая перезаписью URL, будет использоваться для выполнения отслеживания сеанса, то есть каждое внутреннее взаимодействие HTTP, URL прикреплен к параметру, такому как SID = XXXXX, и служба основана на этом для идентификации пользователя.
  • На самом деле, файлы cookie также могут использоваться в некоторых удобных для пользователя сценариях.Предположим, вы вошли на веб-сайт один раз, но не хотите снова входить в свою учетную запись при следующем входе.Что вам следует делать? Эта информация может быть записана в куки, при посещении сайта скрипт страницы сайта может прочитать эту информацию и автоматически подставить вам имя пользователя, что удобно пользователю. Это также происхождение имени файла cookie, немного сладкого для пользователя. Итак, резюмируя: Сессия — это структура данных, сохраняемая на стороне сервера для отслеживания статуса пользователей, и эти данные могут сохраняться в кластерах, базах данных и файлах; Куки — это механизм, используемый клиентом для сохранения информации о пользователе. запись некоторой информации о пользователе также является способом реализации сеанса.

68. Расскажите о принципе работы сеанса?

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

69. Если клиент запрещает файлы cookie, может ли сеанс все еще использовать?

Куки и сессия обычно считаются двумя независимыми вещами.Сеанс принимает схему поддержания состояния на стороне сервера, а Куки использует схему поддержания состояния на стороне клиента. Но почему я не могу получить сеанс после отключения файлов cookie? Поскольку сеанс использует идентификатор сеанса для определения сеанса сервера, соответствующего текущему диалогу, а идентификатор сеанса передается через файл cookie, отключение файла cookie эквивалентно потере идентификатора сеанса, и поэтому сеанс не может быть получен.

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

  1. Установите файл конфигурации php.ini «session.use_trans_sid = 1» или «Открыть», чтобы открыть параметр времени компиляции «--enable-trans-sid», чтобы PHP автоматически распространял передаваемый идентификатор сеанса.
  2. Вручную передайте значение через URL-адрес и передайте идентификатор сеанса через скрытую форму.
  3. Сохраните идентификатор сеанса в виде файла, базы данных и т. д., вызовите его вручную во время кросс-страницы.

70. В чем разница между Spring MVC и распорками?

  • Различные механизмы перехвата

Struts2 — это перехват на уровне класса.Действие создается для каждого запроса.При интеграции со Spring областью внедрения ActionBean Struts2 является прототип режима прототипа, а затем данные запроса внедряются в свойство через сеттеры и геттеры. В Struts2 действие соответствует контексту запроса и ответа.При получении параметров его можно получить через атрибуты, что означает, что параметры атрибута совместно используются несколькими методами. Метод Action в Struts2 может соответствовать URL-адресу, но его атрибуты класса являются общими для всех методов, поэтому невозможно использовать аннотации или другие методы для идентификации метода, которому он принадлежит, и он может быть разработан только как несколько экземпляров. .

SpringMVC — это перехват на уровне метода, а метод соответствует контексту запроса, поэтому метод в основном независим и имеет эксклюзивные данные запроса и ответа. И каждый метод одновременно соответствует URL-адресу, и передача параметров напрямую внедряется в метод, который уникален для метода. Результат обработки возвращается во фреймворк через ModeMap. Во время интеграции Spring компонент контроллера SpringMVC по умолчанию находится в режиме Singleton, поэтому по умолчанию для всех запросов будет создан только один контроллер, и не должно быть общих свойств, поэтому он является потокобезопасным.Если вы хотите изменить область действия по умолчанию, Необходимо добавить модификацию аннотации @Scope.

STRUTS2 Перехватчик InterCechnor имеет свои собственные механизмы, SpringMVC, который представляет собой отдельный путь AOP, это привело к файлу конфигурации больше, чем количество StrUTS2 SpringMVC.

  • Различия в базовой структуре

Struts2 реализуется фильтром (StrutsPrepareAndExecuteFilter), а SpringMVC (DispatcherServlet) реализуется сервлетом. Фильтр инициализируется после запуска контейнера, падает после остановки службы, позже сервлета. Сервлет инициализируется при вызове перед вызовом Filter и уничтожается после остановки службы.

  • Представление

Struts2 — это перехват на уровне класса. Каждый раз, когда запрашивается новое действие для соответствующего экземпляра, необходимо загрузить все инъекции значений атрибутов. SpringMVC реализует нулевую конфигурацию. Из-за перехвата на основе методов SpringMVC загружается внедрение bean-компонента в одноэлементном режиме однажды. Поэтому эффективность и производительность разработки SpringMVC выше, чем у Struts2.

  • Конфигурация

Spring MVC и Spring бесшовны. Управление и безопасность этого проекта также выше, чем у Struts2.

71. Как избежать инъекций SQL?

  1. PreparedStatement (простой и эффективный метод)
  2. Фильтровать входящие параметры с помощью регулярных выражений
  3. Строковый фильтр
  4. Вызовите эту функцию в JSP, чтобы проверить, содержит ли пакет недопустимые символы.
  5. Код оценки страницы JSP

72. Что такое XSS-атака и как ее избежать?

Атака XSS, также известная как CSS, полное название Cross Site Script (атака Cross Site Scripting), ее принцип заключается в том, что злоумышленник вводит вредоносный HTML-код на веб-сайт с XSS-уязвимостью, когда пользователь просматривает веб-сайт, этот HTML-код будет выполняется автоматически для достижения цели атаки. Атаки XSS аналогичны атакам с внедрением SQL.В атаках с внедрением SQL операторы SQL используются в качестве пользовательского ввода для запроса/изменения/удаления данных.В атаках xss вредоносные сценарии вставляются для управления браузером пользователя и получения некоторой информации о пользователе. XSS — распространенная уязвимость в веб-программах, XSS — метод пассивной атаки, используемый на стороне клиента.

Общая идея предотвращения XSS заключается в фильтрации ввода (и параметров URL) и кодировании вывода.

73. Что такое CSRF-атака и как ее избежать?

CSRF (подделка межсайтовых запросов) также известна как атака в один клик или подделка сеансов.Полное название на китайском языке — подделка межсайтовых запросов. Вообще говоря, злоумышленник отправляет запрос на веб-сайт, который пользователь аутентифицировал для посещения, подделывая запрос браузера пользователя, так что целевой веб-сайт получает и ошибочно полагает, что это реальная операция пользователя, и выполняет команду. Его часто используют для кражи аккаунтов, перевода денег, отправки ложных сообщений и т. д. Злоумышленник использует уязвимость веб-сайта для проверки запроса для проведения такой атаки.Веб-сайт может подтвердить, что запрос исходит из браузера пользователя, но не может проверить, исходит ли запрос из истинных желаний пользователя.

Как избежать:

1. Проверьте поле HTTP Regerer

Поле реферала в заголовке HTTP записывает исходный адрес HTTP-запроса. При нормальных обстоятельствах запросы, которые доступа к безопасной ограниченной странице приходят с того же веб-сайта, и если хакеры делают на них хакеры, он может построить только запрос на свой собственный веб-сайт. Следовательно, атака CSRF может быть опровергнута путем проверки значения реферата.

2. Используйте код подтверждения

Страница ключевой операции добавляется с проверочным кодом.После того, как фон получает запрос, он может защищаться от CSRF, оценивая проверочный код. Но этот метод не очень удобен для пользователя.

3. Добавьте токен к адресу запроса и проверьте

Причина, по которой CSRF-атака успешна, заключается в том, что хакер может полностью подделать запрос пользователя.Вся информация об аутентификации пользователя в запросе содержится в файле cookie, поэтому хакер может напрямую использовать собственный файл cookie пользователя, не зная информации об аутентификации. проверка безопасности. Ключом к защите от CSRF является размещение в запросе информации, которую хакер не может подделать, и этой информации нет в файле cookie. В HTTP-запрос может быть добавлен случайно сгенерированный токен в виде параметра, а на стороне сервера может быть установлен перехватчик для проверки токена.Если в запросе нет токена или содержание токена неверно, считается, что это может быть CSRF-атака, и запрос отклонен. Этот способ более безопасный, чем проверка Referer.Токен может быть сгенерирован после авторизации пользователя и помещен в сессию, а затем токен выносится из сессии при каждом запросе и сравнивается с токеном в запросе, но это сложность этого метода заключается в том, как добавить токен в качестве параметра запроса. Для запросов GET токен будет добавлен к адресу запроса, так что URL-адрес станет http://url?csrftoken=tokenvalue. Для запросов POST добавьте в конце формы, чтобы токен добавлялся в запрос в качестве параметра.

4. Настройте свойства в заголовках HTTP и проверьте

Этот метод также использует токен и выполняет проверку.Отличие от предыдущего метода заключается в том, что токен не помещается в HTTP-запрос в качестве параметра, а размещается в пользовательском атрибуте в HTTP-заголовке. Через класс XMLHttpRequest можно добавить атрибут заголовка HTTP csrftoken ко всем запросам этого типа одновременно, и поместить в него значение токена. Это решает неудобство добавления токена в запрос в предыдущем способе, при этом запрашиваемый через XMLHttpRequest адрес не будет записываться в адресную строку браузера, и можно не беспокоиться об утечке токена другим веб-сайты через Referer.

7. Ненормальный

74. В чем разница между броском и броском?

throws используется для объявления всей информации об исключении, которую может выдать метод, throws — для объявления исключения, но не для его обработки, а для загрузки исключения, и тот, кто меня вызывает, будет его обрабатывать. И throw относится к определенному типу исключения, которое выбрасывается.

75. В чем разница между final, finally и finalize?

  • Final может изменять классы, переменные и методы.Измененный класс означает, что класс не может быть унаследован, модифицированный метод означает, что метод нельзя переопределить, а измененная переменная означает, что переменная является константой и не может быть переназначена.
  • Наконец, обычно действует в блоке кода try-catch.При работе с исключениями мы обычно помещаем метод кода, который должен быть выполнен, в блоке кода finally, указывая, что блок кода будет выполняться независимо от того, есть исключение или нет, и обычно используется для хранения некоторых закрытых ресурсов кода.
  • finalize — это метод, который принадлежит классу Object, а класс Object является родительским классом для всех классов. Этот метод обычно вызывается сборщиком мусора. Когда мы вызываем метод gc() системы, сборщик мусора вызывает finalize. (), перерабатывать мусор.

76. Какая часть в try-catch-finally пропущена?

Ответ: catch можно не указывать

причина:

На самом деле более строгое утверждение: try подходит только для обработки исключений времени выполнения, а try+catch подходит для обработки исключений времени выполнения + обычных исключений. То есть, если вы используете только try для обработки обычных исключений и не обрабатываете их с помощью catch, компиляция не пройдет, потому что компилятор жестко оговаривает, что если вы решите перехватывать обычные исключения, вы должны явно объявить их с помощью catch для дальнейшая обработка. Исключение времени выполнения не указывается во время компиляции, поэтому catch можно опустить и добавить к нему компилятор catch.

Теоретически компилятор не видит никакого кода, приятного глазу, и думает, что могут быть потенциальные проблемы, поэтому даже если вы добавите try ко всему коду, код просто добавляет слой скина на основе нормальной работы на время выполнения. Но как только вы добавляете попытку к фрагменту кода, вы явно обещаете компилятору перехватывать исключения, которые могут быть вызваны этим кодом, а не создавать их. Если это обычное исключение, компилятор требует, чтобы оно было перехвачено с помощью catch для дальнейшей обработки; если перехватывается исключение времени выполнения, то оно отбрасывается и +finally завершается для обработки или добавляется с помощью catch для дальнейшей обработки.

Что касается добавления, наконец, это процесс «зачистки хвоста», который должен выполняться независимо от того, поймано ли исключение или нет.

77. В try-catch-finally, если в catch будет return, будет ли finally выполнен?

Ответ: Он будет выполнен, и он будет выполнен до возврата.

Пример кода 1:

/* * java面试题--如果catch里面有return语句,finally里面的代码还会执行吗? */public class FinallyDemo2 { public static void main(String[] args) { System.out.println(getInt()); } public static int getInt() { int a = 10; try { System.out.println(a / 0); a = 20; } catch (ArithmeticException e) { a = 30; return a; /* * return a 在程序执行到这一步的时候,这里不是return a 而是 return 30;这个返回路径就形成了 * 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40 * 再次回到以前的路径,继续走return 30,形成返回路径之后,这里的a就不是a变量了,而是常量30 */ } finally { a = 40; }// return a; }}

Результат выполнения: 30

Пример кода 2:

package com.java_02;/* * java面试题--如果catch里面有return语句,finally里面的代码还会执行吗? */public class FinallyDemo2 { public static void main(String[] args) { System.out.println(getInt()); } public static int getInt() { int a = 10; try { System.out.println(a / 0); a = 20; } catch (ArithmeticException e) { a = 30; return a; /* * return a 在程序执行到这一步的时候,这里不是return a 而是 return 30;这个返回路径就形成了 * 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40 * 再次回到以前的路径,继续走return 30,形成返回路径之后,这里的a就不是a变量了,而是常量30 */ } finally { a = 40; return a; //如果这样,就又重新形成了一条返回路径,由于只能通过1个return返回,所以这里直接返回40 }// return a; }}

Результат исполнения: 40

78. Каковы общие классы исключений?

  • NullPointerException: вызывается, когда приложение пытается получить доступ к нулевому объекту.
  • SQLException: Исключение, которое предоставляет информацию об ошибках доступа к базе данных или других ошибках.
  • IndexOutOfBoundsException: вызывается, когда индекс сортировки (например, сортировка массива, строки или вектора) выходит за пределы.
  • NumberFormatException: возникает, когда приложение пытается преобразовать строку в числовой тип, но строку не удается преобразовать в соответствующий формат.
  • FileNotFoundException: вызывается при неудачной попытке открыть файл, представленный указанным путем.
  • IOException: это исключение возникает, когда возникает какое-либо исключение ввода-вывода. Этот класс является универсальным классом для исключений, генерируемых неудачными или прерванными операциями ввода-вывода.
  • ClassCastException: вызывается при попытке привести объект к подклассу, который не является экземпляром.
  • ArrayStoreException: Возникает при попытке сохранить объект неправильного типа в массиве объектов.
  • IllegalArgumentException: Возникшее исключение указывает на то, что методу был передан недопустимый или неверный параметр.
  • ARITHMETECECEXCECTION: это исключение брошено, когда происходит ненормальное рабочее состояние. Например, экземпляр этого класса брошен, когда целое число «разделено на ноль».
  • NegativeArraySizeException: вызывается, если приложение пытается создать массив отрицательного размера.
  • NoSuchMethodException: это исключение возникает, когда определенный метод не может быть найден.
  • SecurityException: Исключение, созданное диспетчером безопасности для указания на нарушение безопасности.
  • UnsupportedOperationException: вызывается, когда запрошенная операция не поддерживается.
  • RuntimeException RuntimeException: это суперкласс тех исключений, которые могут быть вызваны во время нормальной работы виртуальной машины Java.

8. Сеть

79. Что представляют собой коды ответа http 301 и 302? Какая разница?

Ответ: 301 и 302 — это коды состояния HTTP, которые означают, что URL-адрес был передан.

разница:

  • 301 редирект: 301 означает постоянное перемещение.
  • 302 Redirect: 302 означает временное перемещение.

80. В чем разница между переадресацией и переадресацией?

Forward и Redirect представляют два метода переадресации запросов: прямую переадресацию и косвенную переадресацию.

Прямая переадресация (вперед), клиент и браузер отправляют только запрос, сервлет, HTML, JSP или другие информационные ресурсы, второй информационный ресурс отвечает на запрос, в запросе объекта запроса сохраненный объект используется совместно для каждого информационного ресурса.

Косвенная переадресация (Redirect)По сути, это два HTTP-запроса.Когда сервер отвечает на первый запрос, он просит браузер отправить запрос на другой URL-адрес, чтобы достичь цели переадресации.

Возьмем простой пример:

Прямая переадресация эквивалентна: «A просит B одолжить деньги, B говорит «нет», B просит C одолжить деньги, и если ему не удастся занять деньги, он передаст сообщение A»;

Непрямая экспедиция эквивалентна: «А спрашивает B одолжить деньги, B говорит нет, и просит спросить С, чтобы заимствовать».

81. Кратко опишите разницу между tcp и udp?

  • TCP-ориентированные на соединение (например, подключение к коммутируемому вызовам, установлено первым вызовом); UDP UDP является подключением, то есть без установления соединения перед отправкой данных.
  • TCP обеспечивает надежный сервис. То есть данные, передаваемые по TCP-соединению, безошибочны, не теряются, не дублируются и поступают последовательно; UDP делает все возможное для доставки, то есть не гарантирует надежной доставки.
  • Tcp обеспечивает надежную передачу с помощью контрольной суммы, управления повторной передачей, идентификации серийного номера, скользящего окна и подтверждения. Например, когда пакет потерян, управление повторной передачей также может использоваться для управления последовательностью пакетов, которые вышли из строя.
  • UDP имеет лучшую производительность в реальном времени и более высокую эффективность работы, чем TCP, и подходит для высокоскоростной передачи и связи в реальном времени или широковещательной связи.
  • Каждое TCP-соединение может быть только двухточечным; UDP поддерживает интерактивную связь «один-к-одному», «один-ко-многим», «многие-к-одному» и «многие-ко-многим».
  • TCP требует больше системных ресурсов, а UDP требует меньше системных ресурсов.

82. Почему TCP нужно трижды пожать друг другу руки, но не дважды? Зачем?

Чтобы обеспечить надежную передачу данных, как по протоколу TCP, мы должны поддерживать серийный номер для идентификации отправленных пакетов данных, которые уже получены другой стороной. Трехстороннее рукопожатие — это процесс, когда взаимодействующие стороны сообщают каждому начальное значение серийного номера и подтверждают, что они получили необходимое начальное значение серийного номера шага.

Если имеется только два рукопожатия, то может быть подтвержден не более чем начальный порядковый номер инициатора соединения, а порядковый номер, выбранный другой стороной, не может быть подтвержден.

83. Подскажите, как формируется липкий пакет tcp?

①.Отправитель генерирует пакет палочек

Клиент и сервер, использующие протокол TCP для передачи данных, часто имеют длительное соединение (первое соединение с пакетом данных отсутствует), в случае, когда соединение не должно быть, оба данных были переданы, но пакеты передаются слишком долго. , то протокол TCP включен по умолчанию алгоритм Nagle, эти меньшие пакеты данных (процесс передачи данных представляет собой давление буфера кучи) отправляются слиянием; процесс слияния выполняется в буфере отправки, а также то, что данные отправляются, это уже состояние из упаковки стика.

② Приемник генерирует липкие пакеты

Процесс, когда приемник использует протокол TCP для получения данных, выглядит следующим образом: данные передаются приемнику из нижней части сетевой модели на транспортный уровень.Обработка протокола TCP транспортного уровня заключается в размещении их в приемном буфер, а затем прикладной уровень будет активно его получать (язык C использует такие функции, как recv, read и т. д.); в это время будет проблема, то есть функция чтения данных, которую мы вызываем в программе, не может вовремя вынимаем данные в буфер, а следующие данные приходят снова и какими-то частями Конец буфера помещается в него липким пакетом, когда мы читаем данные. (скорость размещения данных> скорость получения данных прикладного уровня)

84. Что представляют собой семиуровневые модели OSI?

  1. Прикладной уровень: интерфейс между сетевыми службами и конечными пользователями.
  2. Уровень представления: представление данных, безопасность, сжатие.
  3. Сеансовый уровень: устанавливать, управлять и завершать сеансы.
  4. Транспортный уровень: определяет номер порта протокола для передачи данных, а также управления потоком и проверки ошибок.
  5. Сетевой уровень: выполнение логической адресации для реализации выбора пути между различными сетями.
  6. Ссылка на канал данных: создание логического соединения, адреса адресов оборудования, проверка ошибок и других функций.
  7. Физический уровень: установка, обслуживание и отключение физических соединений.

85. В чем разница между запросами GET и POST?

  • GET безвреден, когда браузер отступает, а POST снова отправляет запрос.
  • URL-адрес, сгенерированный GET, может быть добавлен в закладки, а POST — нет.
  • Запросы GET будут активно кэшироваться браузером, а запросы POST — нет, если только они не установлены вручную.
  • Запрос GET можно использовать только для кодирования URL, тогда как POST поддерживает несколько методов кодирования.
  • Получить параметры запроса будут полностью сохранены в истории браузера, в то время как параметры сообщения не будут сохранены.
  • Параметры, отправляемые в URL-адресе для запросов GET, ограничены по длине, а POST — нет.
  • Для типов данных параметра GET принимает только символы ASCII, а POST не имеет ограничений.
  • GET менее безопасен, чем POST, поскольку параметры отображаются непосредственно в URL-адресе, поэтому его нельзя использовать для передачи конфиденциальной информации.
  • Параметры GET передаются через URL-адрес, а POST помещается в тело запроса.

86. Как добиться кросс-доменности?

Метод 1: Ping изображения или междоменный тег сценария

пинг изображенияЧасто используется для отслеживания кликов пользователей на страницах или показов динамической рекламы.

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

Способ 2: кросс-доменный JSONP

JSONP (JSON with Padding) — это «шаблон использования» формата данных JSON, который позволяет веб-страницам запрашивать данные из других доменов. В соответствии с тем, что на объект XmlHttpRequest распространяется та же политика происхождения, и с помощью этой открытой политики элемента

недостаток:

  • Можно использовать только GET-запрос
  • Вы не можете зарегистрировать функции прослушивателя событий, такие как успех и ошибка, и вы не можете легко определить, не прошел ли запрос JSONP.
  • JSONP загружает код из других доменов и уязвим для атак с подделкой межсайтовых запросов, и его безопасность не может быть гарантирована.

Способ 3: КОРС

Совместное использование ресурсов между источниками (CORS) — это спецификация технологии браузера, которая предоставляет веб-службам метод передачи сценариев песочницы из разных доменов, чтобы избежать политики браузера в отношении одного и того же источника и обеспечить безопасную передачу данных между доменами. Современные браузеры используют CORS в контейнерах API, таких как XMLHttpRequest, чтобы уменьшить источник риска для HTTP-запросов. В отличие от JSONP, CORS также поддерживает другие HTTP-запросы в дополнение к методу запроса GET. Обычно серверу необходимо добавить один или несколько из следующих заголовков ответа:

Access-Control-Allow-Origin: *Access-Control-Allow-Methods: POST, GET, OPTIONSAccess-Control-Allow-Headers: X-PINGOTHER, Content-TypeAccess-Control-Max-Age: 86400

Междоменные запросы по умолчанию не передают информацию о файлах cookie. Если вам нужно ее передать, настройте следующие параметры:

"Access-Control-Allow-Credentials": true// Ajax设置"withCredentials": true

Четыре способа: window.name + iframe

window.name (обычно создается динамически i) для загрузки HTML-файла, который будет играть роль в междоменном iframe. Затем файл HTML будет передан реквестеру строкового содержимого, назначенному для window.name. Затем запрашивающая сторона может получить значение window.name в качестве ответа.

  • Междоменные возможности тегов iframe;
  • Способность значения свойства window.name все еще существовать после обновления документа (максимально допустимое значение составляет около 2M).

У каждого iframe есть окно, которое его обертывает, и это окно является дочерним по отношению к верхнему окну. Свойство contentWindow возвращает объект Window элемента

<!-- 下述用端口 10000表示:domainA 10001表示:domainB--><!-- localhost:10000 --><script> var iframe = document.createElement('iframe'); iframe.style.display = 'none'; // 隐藏 var state = 0; // 防止页面无限刷新 iframe.onload = function() { if(state === 1) { console.log(JSON.parse(iframe.contentWindow.name)); // 清除创建的iframe iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); } else if(state === 0) { state = 1; // 加载完成,指向当前域,防止错误(proxy.html为空白页面) // Blocked a frame with origin "http://localhost:10000" from accessing a cross-origin frame. iframe.contentWindow.location = 'http://localhost:10000/proxy.html'; } }; iframe.src = 'http://localhost:10001'; document.body.appendChild(iframe);</script><!-- localhost:10001 --><!DOCTYPE html>...<script>window.name = JSON.stringify({a: 1, b: 2});</script></html>

Пять способов: window.postMessage()

Новая функция HTML5, которую можно использовать для отправки сообщений всем другим оконным объектам. Следует отметить, что мы должны убедиться, что все скрипты выполнены перед отправкой MessageEvent, Если он вызывается во время выполнения функции, он делает последующую функцию тайм-аутом и не может быть выполнен.

Следующий код реализует междоменное хранилище localStorage.

<!-- 下述用端口 10000表示:domainA 10001表示:domainB--><!-- localhost:10000 --><iframe src="http://localhost:10001/msg.html" name="myPostMessage" style="display:none;"></iframe><script> function main() { LSsetItem('test', 'Test: ' + new Date()); LSgetItem('test', function(value) { console.log('value: ' + value); }); LSremoveItem('test'); } var callbacks = {}; window.addEventListener('message', function(event) { if (event.source === frames['myPostMessage']) { console.log(event) var data = /^#localStorage#(\d+)(null)?#([\S\s]*)/.exec(event.data); if (data) { if (callbacks[data[1]]) { callbacks[data[1]](data[2] === 'null' ? null : data[3]); } delete callbacks[data[1]]; } } }, false); var domain = '*'; // 增加 function LSsetItem(key, value) { var obj = { setItem: key, value: value }; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); } // 获取 function LSgetItem(key, callback) { var identifier = new Date().getTime(); var obj = { identifier: identifier, getItem: key }; callbacks[identifier] = callback; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); } // 删除 function LSremoveItem(key) { var obj = { removeItem: key }; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); }</script><!-- localhost:10001 --><script> window.addEventListener('message', function(event) { console.log('Receiver debugging', event); if (event.origin == 'http://localhost:10000') { var data = JSON.parse(event.data); if ('setItem' in data) { localStorage.setItem(data.setItem, data.value); } else if ('getItem' in data) { var gotItem = localStorage.getItem(data.getItem); event.source.postMessage( '#localStorage#' + data.identifier + (gotItem === null ? 'null#' : '#' + gotItem), event.origin ); } else if ('removeItem' in data) { localStorage.removeItem(data.removeItem); } } }, false);</script>

Обратите внимание на Safari, он сообщит об ошибке:

Фрейму с источником "http://localhost:10001" заблокирован доступ к кадру с источником "http://localhost:10000". Протоколы, домены и порты должны совпадать.

Чтобы избежать этой ошибки, вы можете проверить меню «Разработка» ==> «Отключить междоменные ограничения» в браузере Safari. Или это может быть реализовано только путем дампа на стороне сервера, потому что браузер Safari по умолчанию поддерживает только междоменные запросы CORS.

Способ 6: измените document.domain на несколько поддоменов

Условие: эти два доменных имени должны принадлежать одному и тому же основному доменному имени!И используемые протоколы и порты должны быть одинаковыми, в противном случае document.domain нельзя использовать для междоменного использования, поэтому он может пересекать только субдомены.

В рамках корневого домена разрешено устанавливать значение атрибута домена в его родительский домен. Например, в домене «aaa.xxx.com» домен может быть установлен как «xxx.com», но не как «XXX.com Porn - Free PORNO videos» или «com».

В настоящее время существует два доменных имени aaa.xxx.com и bbb.xxx.com. Страница, которая встраивает bbb в aaa, не может работать с js bbb в aaa, поскольку ее имя document.name несовместимо. Вы можете установить document.name = 'xxx.com'; таким же образом через js под aaa и bbb добиться взаимного доступа.

Способ 7: веб-сокет

Протокол WebSocket — это новый протокол в HTML5. Он реализует полнодуплексную связь между браузером и сервером, обеспечивая при этом междоменную связь, что является отличной реализацией технологии push-уведомлений сервера. Связанные статьи см. в: WebSocket, WebSocket-SockJS.

Примечание. Объекты WebSocket не поддерживают прослушиватели событий DOM уровня 2, каждое событие должно быть определено отдельно с использованием синтаксиса DOM уровня 0.

Способ 8: агент

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

Клиент домена A (браузер) ==> сервер домена A ==> сервер домена B ==> клиент домена A (браузер)

Источник: blog.csdn.net/ligang2585116/article/details/73072868.

87. Расскажите о принципе реализации JSONP?

jsonp — это json+padding, который динамически создает тег скрипта и использует атрибут src тега скрипта для получения js-скриптов в любом домене.Благодаря этой фиче (или лазейке) сервер не возвращает товары в формате json, а возвращает вызов определенного js-кода функции вызывается в src, таким образом реализуя междоменный доступ.

9. Шаблоны проектирования

88. Расскажите мне о шаблонах проектирования, с которыми вы знакомы?

Ссылка: Сводка часто используемых шаблонов проектирования, очень подробная!

89. В чем разница между простой фабрикой и абстрактной фабрикой?

Простой заводской шаблон:

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

Он состоит из трех ролей:

  • Роль фабрики: это ядро ​​этой модели.Она содержит определенную бизнес-логику и логику суждений.В зависимости от логики создаются определенные фабричные продукты. Например, класс Driver в примере.
  • Роль абстрактного продукта: обычно это родительский класс, наследуемый конкретным продуктом или реализованным интерфейсом. Реализуется интерфейсом или абстрактным классом. Например, автомобильный интерфейс.
  • Конкретная роль продукта: объект, созданный фабричным классом, является экземпляром этой роли. Он реализован конкретным классом в java, таким как классы Benz и BMW в примере.

Чтобы отношения между ними с диаграммами классов четко представлены в:

Абстрактный заводской шаблон:

Давайте сначала разберемся, что такое семейство продуктов: семейство продуктов, расположенных в разных структурах иерархии продуктов со связанными функциями.

BmwCar и BenzCar на рисунке представляют собой два дерева продуктов (иерархия продуктов), а BenzSportsCar и BmwSportsCar, как показано на рисунке, представляют собой семейство продуктов. Все они вписываются в семейство спортивных автомобилей, поэтому функциональность актуальна. Точно так же BmwBusinessCar и BenzBusinessCar также являются семейством продуктов.

Можно сказать, что разница между ним и фабричным методом заключается в сложности объектов, которые необходимо создать. И шаблон абстрактной фабрики является наиболее абстрактным и общим из трех. Цель шаблона абстрактной фабрики — предоставить клиенту интерфейс для создания объектов продукта в нескольких семействах продуктов.

А для использования абстрактного фабричного шаблона должны быть выполнены следующие условия:

  1. В системе есть несколько семейств продуктов, и система может одновременно использовать только одно из этих семейств.
  2. Для их использования используются продукты, принадлежащие к одному семейству продуктов.

Давайте взглянем на различные роли абстрактного фабричного шаблона (так же, как фабричный метод):

  • Роль абстрактной фабрики: это ядро ​​шаблона фабричного метода, не зависящее от приложения. Это интерфейс, который должна реализовать конкретная фабричная роль, или родительский класс, который должен быть унаследован. В java это реализуется абстрактными классами или интерфейсами.
  • Роль, специфичная для завода: она содержит определенный код и связанную бизнес-логику. Объект вызывается приложением для создания соответствующих конкретных продуктов. В java реализован свой конкретный класс.
  • Роль абстрактного продукта: это родительский класс, который наследует конкретный продукт, или интерфейс, который он реализует. В java обычно есть абстрактные классы или интерфейсы для реализации.
  • Определенная роль продукта: объекты, созданные определенной ролью фабрики, являются экземплярами этой роли. Он реализован конкретными классами в java.

10. Весна/Весна MVC

90. Зачем использовать пружину?

1. Введение

  • Цель: решить проблемы разработки корпоративных приложений.
  • Особенности: Использует базовые компоненты JavaBeans вместо EJB и предоставляет дополнительные функциональные возможности корпоративных приложений.
  • Область применения: любое Java-приложение.

Проще говоря, Spring — это облегченная структура контейнеров Inversion of Control (IoC) и Aspect Oriented (AOP).

2. Легкий

Пружина легкая с точки зрения размера и накладных расходов. Полную среду Spring можно распространять в виде файла JAR размером чуть более 1 МБ. И накладные расходы на обработку, требуемые Spring, также тривиальны. Более того, Spring не является навязчивым: обычно объекты в приложении Spring не зависят от специфичных для Spring классов.

3. Инверсия управления

Spring способствует слабой связи с помощью метода, называемого инверсией управления (IoC). Когда применяется IoC, другие объекты, от которых зависит объект, передаются пассивно, а не сам объект, создающий или находящий зависимые объекты. Вы можете думать о IoC как о противоположности JNDI: вместо того, чтобы объект искал зависимости от контейнера, контейнер проактивно передает ему зависимости, когда объект инициализируется, не дожидаясь, пока объект запросит его.

4. Лицом к лицу

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

5. Контейнеры

Spring содержит и управляет конфигурацией и жизненным циклом объектов приложения в том смысле, что это контейнер, в котором вы можете настроить способ создания каждого из ваших bean-компонентов — на основе настраиваемого прототипа ваш bean-компонент может создавать отдельные экземпляры или порождать новый экземпляр. каждый раз, когда вам это нужно - и как они соотносятся друг с другом. Однако Spring не следует путать с традиционными тяжеловесными EJB-контейнерами, которые часто бывают громоздкими, громоздкими и сложными в использовании.

6. Каркас

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

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

91. Объясните, что такое аоп?

Можно сказать, что АОП (аспектно-ориентированное программирование, аспектно-ориентированное программирование) добавлено и улучшено ООП (объектно-ориентированное программирование, объектно-ориентированное программирование). Концепции ООП представили инкапсуляцию, наследование и полиморфизм для установления иерархии объектов, чтобы имитировать набор общих поведений. Когда нам нужно ввести общее поведение для разбросанных объектов, ООП выглядят бессильными. Другими словами, ООП позволяет определять отношения сверху вниз, но не подходит для определения отношений слева направо. Например, ведение журнала. Лог-код имеет тенденцию распространяться на все уровни объектной иерархии, основная функция объекта, к которой он распространяться не имеет никакого отношения. Для других типов кода, таких как безопасность, обработка исключений и непрерывная прозрачность. Такой разбросанный по несвязанному коду в ООП-дизайне называется поперечным (сквозным) кодом, что приводило к большому количеству повторного использования кода в ущерб каждому модулю.

Технология АОП как раз противоположна. Она использует технологию, называемую «сквозной», чтобы анализировать внутреннюю часть инкапсулированного объекта и инкапсулировать те общедоступные поведения, которые влияют на несколько классов, в повторно используемый модуль и дать ему имя. Для «Аспекта» то есть аспект. Проще говоря, так называемый «аспект» заключается в том, чтобы инкапсулировать логику или обязанности, которые не связаны с бизнесом, но обычно называются бизнес-модулями, что удобно для сокращения повторяющегося кода системы, уменьшения степени связанности. между модулями и способствует будущему развитию, работоспособности и ремонтопригодности. АОП представляет горизонтальные отношения. Если «объект» представляет собой полый цилиндр, заключающий в себе свойства и поведение объекта, то метод аспектно-ориентированного программирования подобен острому лезвию, разрезающему эти полые цилиндры, чтобы получить свое внутреннее сообщение. Вырезанный участок – это так называемое «лицо». Затем своими искусными руками восстановил эти вырезы, не оставив следов.

Используя «сквозные» методы, АОП делит программную систему на две части: основные задачи и сквозные задачи. Основной поток бизнес-процессов является основной задачей, а менее важная часть — сквозной задачей. Характерной чертой сквозных проблем является то, что они часто встречаются в нескольких местах основной проблемы, но в основном одинаковы везде. Например, аутентификация авторизации, ведение журнала, обработка транзакций. Роль АОП состоит в том, чтобы разделить различные задачи в системе, отделив основные задачи от сквозных задач. Как выразился Адам Маги, старший архитектор решений в Avanade, основная идея АОП состоит в том, чтобы «отделить бизнес-логику в приложении от общих сервисов, которые его поддерживают».

92. Объясните, что такое ioc?

IOC - это аббревиатура от Inversion of Control, и в большинстве книг это переводится как «Inversion of Control».

В 1996 году Майкл Маттсон в статье об объектно-ориентированном фреймворке для изучения впервые предложил концепцию IOC. Что касается основной идеи объектно-ориентированного проектирования и программирования, мы уже много говорили и не повторяемся, короче говоря, это разбить сложные системы на объекты взаимного сотрудничества, эти классы объектов в будущем через пакет, внутренняя реализация прозрачна для внешней, что снижает сложность решения проблемы, но также обеспечивает гибкость повторного использования и расширения.

IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。 Как показано ниже:

Как вы можете видеть, из-за введения «третьей стороны» в средней позиции, то есть контейнер IOC, четыре объекта A, B, C и D не имеют отношения связи, а передача между шестернями всех полагаться на «третью сторону». Контроль всех объектов передается на «третьей стороне» контейнера IOC. Следовательно, контейнер МОК стал ключевым ядром всей системы. Это действует как «клей», чтобы клей Все объекты в системе. Для функционирования вместе, без этого «клея» объекты будут терять контакт друг с другом, поэтому некоторые люди сравнивают контейнер IOC к «клею».

Давайте проведем еще один эксперимент: удалим контейнер IOC в середине картинки выше, а затем посмотрим на систему:

Картина, которую мы видим сейчас, — это все, что нам нужно сделать для реализации всей системы. В настоящее время нет связи между четырьмя объектами A, B, C и D, и нет связи друг с другом. В этом случае, когда вы реализуете A, вам не нужно учитывать B, C , и вообще D. Зависимости между объектами сведены к минимуму. Поэтому, если IOC-контейнер действительно можно будет реализовать, это будет замечательная вещь для разработки системы.Каждому участнику, участвующему в разработке, нужно реализовать только свой класс, и он не имеет ничего общего с другими!

Давайте еще раз посмотрим, почему Inversion of Control (IOC) так называется? Давайте сравним:

Прежде чем программная система представит контейнер IOC, как показано на рисунке 1, объект A зависит от объекта B, поэтому, когда объект A инициализируется или выполняется до определенного момента, он должен активно создавать объект B или использовать уже созданный объект B. Независимо от того, создается или используется объект B, контроль находится в его собственных руках.

После внедрения IOC-контейнера в программную систему эта ситуация полностью изменилась.Как показано на рисунке 3, из-за добавления IOC-контейнера прямая связь между объектом A и объектом B теряется.Поэтому, когда объект A выполняется до точки, где требуется объект B. В то время контейнер IOC будет активно создавать объект B и внедрять его в то место, где он нужен объекту A.

Путем сравнения до и после нетрудно увидеть, что процесс получения объектом А зависимого объекта В изменился от активного поведения к пассивному поведению, а права управления поменялись местами. контроль".

93. Каковы основные модули весны?

На данный момент Spring framework интегрировал более 20 модулей. Эти модули в основном делятся на основной контейнер, доступ к данным/интеграцию, веб, АОП (аспектно-ориентированное программирование), инструменты, модули сообщений и тестовые модули, как показано на рисунке ниже.

Дополнительная информация: Учебные пособия по Spring — HowToDoInJava

94. Весной обычно используемый метод инъекции Что?

Spring реализует IOC (инверсию управления) через DI (внедрение зависимостей).Существует три основных метода внедрения:

  1. Конструктор инъекции
  2. инъекция сеттера
  3. Внедрение на основе аннотаций

95. Являются ли bean-компоненты в Spring потокобезопасными?

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

96. Сколько областей действия bean-компонентов поддерживает Spring?

Когда экземпляр Bean создается с помощью контейнера Spring, может быть завершено не только создание экземпляра Bean, но также может быть указана конкретная область действия для Bean. Spring поддерживает следующие пять областей:

  • Singleton: режим Singleton, во всем контейнере весна IOC, фасоль, определенный с помощью Singleton, будет иметь только один экземпляр
  • Прототип: режим прототипа, каждый раз, когда Bean, определенный прототипом, получается с помощью метода getBean контейнера, будет сгенерирован новый экземпляр Bean.
  • request: для каждого HTTP-запроса будет генерироваться новый экземпляр Bean-компонента, определенного с помощью запроса, то есть каждый HTTP-запрос будет генерировать другой экземпляр Bean-компонента. Эта область действительна только при использовании Spring в веб-приложении.
  • сеанс: для каждого сеанса HTTP создается новый экземпляр с использованием Bean Soymilk, определенного сеансом. Также эта область действительна только при использовании Spring в веб-приложении.
  • globalsession: для каждого глобального HTTP-сеанса будет создан новый экземпляр Bean-компонента, определенный с использованием сеанса. Обычно это работает только при использовании контекста портлета. Также эта область действительна только при использовании Spring в веб-приложении.

其中比较常用的是singleton和prototype两种作用域。对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。 Bean container is responsible for tracking state instances, Bean instance is responsible for maintaining the life cycle of behavior; if a prototype is set to Bean scope, the id of each program requests Bean, Spring will create a new Bean instance, and then returns to программа.在这种情况下,Spring容器仅仅使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。

Если вы не укажете области Bean, Spring по умолчанию использует одноэлементную область. При создании Java-экземпляра потребность в выделении памяти; при уничтожении экземпляра необходимо выполнить сборку мусора, эти усилия приведут к увеличению накладных расходов. Таким образом, создание прототипа Бин объем затрат на уничтожение относительно велик. Один раз созданную область экземпляра Bean можно использовать повторно. Поэтому, если нет необходимости избегать, Bean будет установлен в область прототипа.

97. Пружинная фасоль автоматическая сборка каким образом?

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

Есть два способа сборки фасоли весной:

  • Неявный механизм обнаружения bean-компонентов и автоматическое связывание
  • Отображение конфигурации в коде Java или XML

Конечно, эти методы также могут быть использованы в комбинации.

98. Осмотр весенних дел Что?

  1. Программное управление транзакциями — единственный вариант для приложений на основе POJO. Нам нужно вызвать в коде beginTransaction(), commit(), rollback() и другие методы, связанные с управлением транзакциями, что является программным управлением транзакциями.
  2. Декларативное управление транзакциями на основе TransactionProxyFactoryBean
  3. Декларативное управление транзакциями на основе @Transactional
  4. Настройка транзакций на основе Aspectj AOP

99. Расскажите мне об изоляции транзакций Spring?

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

  • Грязное чтение: данные об обновлении транзакции читают еще одну незафиксированные транзакции.
  • Фантомное чтение: например, первая транзакция изменяет данные в таблице, например, эта модификация затрагивает «все строки данных» в таблице. В то же время вторая транзакция также изменяет данные в этой таблице, вставляя в таблицу «новую строку данных». Затем случится так, что пользователь, выполняющий первую транзакцию, обнаружит, что в таблице все еще есть неизмененные строки данных, как будто произошла иллюзия.
  • Неповторяющееся чтение: например, два идентичных оператора select выполняются последовательно в одной и той же транзакции, во время которой в этой транзакции не выполнялся ни один оператор DDL, но полученные последовательно результаты несовместимы, что является неповторяемым чтением.

100. Расскажите мне о запущенном процессе Spring MVC?

Блок-схема работы Spring MVC:

Описание процесса запуска Spring:

1. Пользователь отправляет запрос на сервер, запрошенный интерфейсной частью Spring, для управления захватом ServelT DispatcherServlet;

2. ДиспетченерВервут запросить URL-анализ для получения запрошенного идентификатора ресурса (URI). Согласно этому, тогда УРИ, доступ ко всем соответствующим обрабатыванию обработчика по техническому обслуживанию объекта (включая обработчик объектов и обработчика, соответствующим перехватчику), и, наконец, возвращается в виде объекта HandlexecuteChain;

3. DispatcherServlet выбирает подходящий HandlerAdapter в соответствии с полученным Handler (Примечание: если HandlerAdapter успешно получен, в это время будет выполнен метод preHandler(...) перехватчика)

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

  • HttpMessageConveter: преобразование сообщения запроса (например, Json, XML и других данных) в объект и преобразование объекта в указанную информацию ответа.
  • Преобразование данных: выполните преобразование данных в сообщении запроса. Например, преобразование строк в Integer, Double и т. д.
  • Форматирование корня данных: форматирование данных сообщения запроса. Например, преобразование строк в форматированные числа или форматированные даты и т. д.
  • Проверка данных: проверьте достоверность данных (длину, формат и т. д.) и сохраните результат проверки в BindingResult или Error.

5. Обработчик после завершения выполнения, возврат к объекту DispatcherServlet ModelandView;

6. Выберите подходящий ViewResolver (должен быть зарегистрирован в ViewResolver, который был зарегистрирован в контейнере Spring) в соответствии с возвращенными ModelandView;

7. ViewResolver объединяет модель и представление для визуализации представлений;

8. Вернуть результат рендеринга клиенту.

101. Каковы компоненты Spring MVC?

Основные компоненты весны MVC:

  1. DispatcherServlet: центральный контроллер, перенаправляет запросы к определенным классам управления.
  2. Контроллер: контроллер, который специально обрабатывает запрос
  3. HandlerMapping: процессор сопоставления, отвечающий за сопоставление стратегии сопоставления, когда центральный процессор перенаправляется на контроллер.
  4. ModelandView: данные, возвращаемые службой и классом пакета уровня представления.
  5. ViewResolver: преобразователь представлений, разрешает определенные представления.
  6. Перехватчики: Перехватчики, отвечающие за перехват определяемых нами запросов и их обработку.

102. Какова роль @RequestMapping?

RequestMapping — это аннотация для обработки сопоставления адресов запросов, которую можно использовать в классах или методах. Используется в классе, указывая, что все методы класса, отвечающие на запросы, используют этот адрес в качестве родительского пути.

Аннотация RequestMapping имеет шесть атрибутов, для описания разделим их на три категории.

значение, метод:

  • значение: указывает фактический адрес запроса, указанный адрес может быть в режиме шаблона URI (будет объяснен позже);
  • метод: указывает тип метода запроса, GET, POST, PUT, DELETE и т. д.;

потребляет, производит

  • потребляет: указывает тип отправленного контента (Content-Type) запроса на обработку, например, application/json, text/html;
  • производит: указывает возвращаемый тип содержимого, который возвращается только в том случае, если тип (Accept) в заголовке запроса содержит указанный тип;

Парми, заголовки

  • params: указывает, что запрос должен содержать определенные значения параметров для обработки этим методом.
  • заголовки: указывает, что запрос должен содержать определенные указанные значения заголовка, чтобы этот метод мог обработать запрос.

103. @Autowired Какова роль?

"@ @Autovired Информация о использовании"

Суммировать:

Для сводного и аналитического 2019 года 100 классических интервью Женти, чтобы взять интервью у всех в будущем, небольшая помощь в пути, более интересные статьи и интервью, пожалуйста, обратите внимание на Женти: общедоступный номер микроканала: сбор программистов Java


350 реальных вопросов для интернет-интервью первой линии:

1080 распространенных вопросов на собеседовании в 2019 году: