Анализ точек знаний Java Interview (1) — базовые знания

Java
Анализ точек знаний Java Interview (1) — базовые знания

(1) Очки базовых знаний Java

1) Каковы характеристики объектно-ориентированного?

Ответ: инкапсуляция, наследование и полиморфизм.(Это следует считать еще одним, то есть абстракцией)

  • Инкапсуляция относится к сокрытию деталей реализации объекта и последующему раскрытию функций объекта с помощью общедоступных методов.
    Но инкапсуляция - это больше, чем просто приват + геттер/сеттер. Используя инкапсуляцию, вы можете настроить сеттер на более глубоком уровне. Например, вы можете указать объект, который выполняет метод, вы также можете задать определенные требования к данным, и вы может делать преобразование типов и так далее.Использование инкапсуляции не только безопасно, но и упрощает работу.(Расширение инкапсуляции гласит:Одна из трех основных особенностей объектно-ориентированной oc.)

  • Наследование является важным методом повторного использования объектно-ориентированного программного обеспечения.Когда подкласс наследует родительский класс, подкласс является специальным родительским классом, который может прямо или косвенно получать члены родительского класса.
    Недостатки наследства:1)Наследование — это сильное связующее отношение, и родительский класс также должен изменяться при изменении дочернего класса;2)Наследование нарушает инкапсуляцию, и детали его реализации прозрачны для подклассов родительского класса.

  • Короче говоря, полиморфизм — это способность иметь несколько различных проявлений или форм одного и того же поведения.
    Например, если есть стакан с водой, я не знаю, теплый он, ледяной или горячий, но я узнаю это, как только прикоснусь к нему Действие прикосновения к стакану с водой даст разные результаты для разных температур воды.Это полиморфизм.
    полиморфное состояние:1)наследовать;2)переписать;3)Трансформация вверх.
    Преимущества полиморфизма: когда различные объекты подкласса рассматриваются как типы родительского класса,Различия в реализации между объектами разных подклассов могут быть замаскированы,Таким образом, написание общего кода для достижения общего программирования, чтобы адаптироваться к изменяющимся потребностям. (Расширение полиморфизма гласит:Переосмысление java (5) ---- объектно-ориентированный полиморфизм (преобразование вверх и преобразование вниз))

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

2) В чем разница между объектно-ориентированным и процессно-ориентированным?

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

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

  • Дефекты, ориентированные на процесс:
    Процессно-ориентированный дизайнИспользуйте нисходящий дизайн, на этапе проектирования необходимо продумать, на какие подмодули должен быть декомпозирован каждый модуль, каждый подмодуль подразделяется на более мелкие подмодули и так далее, пока модуль не будет доработан до функций.
  • вопрос:1) Дизайн недостаточно интуитивен и не соответствует привычному человеческому мышлению; 2) Системное программное обеспечение имеет плохую адаптивность, плохую масштабируемость и низкие эксплуатационные расходы.

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

Объектно-ориентированный — это новая идея программирования, основанная на процессно-ориентированном подходе.Своеобразное мышление с точки зрения объектаИдея разумного размещения нескольких функций в разных объектах,Акцент делается на объекты с определенными функциями.

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

Я видел интересную цитату на Zhihu:

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

Ориентированность на процесс: хронология;
Объектно-ориентированный: стиль цзи-чуань.

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

Дальнейшее чтение:Ориентация на процесс и ориентация на объект

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

Анализ: это для изучения некоторых основных концепций

Ответ: Среда выполнения Java (JRE-Java Runtime Environment), которая включает в себя виртуальную машину Java, библиотеку основных классов Java и вспомогательные файлы, но не включает инструменты разработки (JDK-Java Development Kit) — компилятор, отладчик и другие инструменты.

Java Development Kit (JDK) — это полный комплект для разработки программного обеспечения Java, включающий JRE, компилятор и другие инструменты (такие как JavaDoc, отладчик Java), которые позволяют разработчикам разрабатывать, компилировать и выполнять приложения Java.

  • Есть и другие существительные, на которые вы также можете обратить внимание:

4) Что означает переопределение и перегрузка в Java?

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

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

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

Интервьюер: Так каковы условия перегрузки?

Ответ: Разные типы параметров, разное количество параметров и разный порядок параметров.

Интервьюер: Могут ли функции с разными возвращаемыми значениями вызывать перегрузку? Почему?

Ответ: Нет, потому что вызов функции в Java не требует принуждения. Пример выглядит следующим образом:

Следующие два метода:

void f(){}
int f(){ return 1; }

Пока компилятор может четко определить семантику из контекста, например, вint x = f();, то перегруженные методы действительно можно отличить соответствующим образом. Однако иногда вас не волнует возвращаемое значение метода, вам нужны другие эффекты вызова метода (это часто называют «вызовом побочных эффектов»), тогда вы можете вызвать метод и игнорировать его возвращаемое значение, поэтому Если вызывается следующим образом:

f();

На данный момент, как Java может определить, какой из них вызывается?f()Шерстяная ткань? Как другие понимают этот код? Таким образом, различение перегруженных методов на основе возвращаемого значения метода не работает.

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

отвечать:

  1. В абстрактном классе не может быть абстрактных методов, методы в интерфейсе должны быть абстрактными методами;
  2. Абстрактный класс может иметь обычные переменные-члены, переменные в интерфейсе должны иметь тип static final и должны быть инициализированы, в интерфейсе есть только константы и никаких переменных.
  3. Абстрактный класс может наследовать только от одного родителя, а интерфейс может наследовать от нескольких родительских интерфейсов;
  4. В Java 8 в интерфейсах будут методы по умолчанию, то есть методы могут быть реализованы.

Интервьюер: Как выбрать абстрактный класс и интерфейс?

отвечать:

  1. Если вы хотите создать базовый класс без каких-либо определений методов и переменных-членов, вам следует выбрать интерфейс вместо абстрактного класса.

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

6) Различия между Java и C++:

Анализ: Хотя мы мало что знаем о C++, мы задаем этот вопрос, особенно в трехстороннем (на уровне директора) интервью.

отвечать:

  1. Оба являются объектно-ориентированными языками и оба поддерживают инкапсуляцию, наследование и полиморфизм.

  2. Указатели: Java не предоставляет указатели для прямого доступа к памяти, программа более безопасна.

  3. Наследование: классы Java наследуются одиночно, а C++ поддерживает множественное наследование; Java реализует множественное наследование в C++ путем реализации нескольких интерфейсов в одном классе; классы в Java не могут иметь множественного наследования, но! ! ! Интерфейсы могут иметь множественное наследование

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

7) Что означает ключевое слово "static"?

Ответ. Ключевое слово "static" указывает, что к переменной-члену или методу-члену можно получить доступ без переменной экземпляра класса, к которому он принадлежит.

Интервьюер: Можно ли переопределить частный или статический метод в Java?

Ответ. Статические методы в Java нельзя переопределить, поскольку переопределение методов основано на динамической привязке во время выполнения, а статические методы статически привязываются во время компиляции. Статический метод не связан ни с одним экземпляром класса, поэтому концептуально он неприменим.

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

Дальнейшее чтение:Новое понимание java (6) ---- Альтернатива в java: статическое ключевое слово (со знанием блока кода)

8) Является ли Java передачей по значению или передаче по ссылке?

Анализ: Для этого типа вопроса интервьюер напишет пример, чтобы вы могли рассказать о результате выполнения функции.

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

Принято считать, что в Java передача осуществляется по значению, передача объектов-экземпляров в Java — по ссылке, а в Java — по значению!

  • Сначала рассмотрим пример:

Это классический пример, мы хотим поменять местами значения arg1 и arg2 после вызова метода swap(), но этого не происходит, почему это происходит?

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

  • Давайте посмотрим на другой пример:

Мы определили внутренний класс Person, который имеет только одно свойство age типа int, а затем имеет getter/setter, мы хотим изменить свойство age объекта Person с помощью функции changeAge(), почему на этот раз это удалось?

Еще можно понять, что функция main копирует человека в функцию changeAge, а в итоге только меняет значение скопированного параметра в changeAge, причем меняется не исходный параметр, а тот, что в changeAge Копия и исходный параметр указывают на одну и ту же область памяти!

9) Какие пакеты обычно используются в JDK?

Ответ: java.lang, java.util, java.io, java.net, java.sql.

10) Какая связь и разница между JDK, JRE и JVM?

О: JDK — это Java Development Kit, основной компонент среды разработки Java, который предоставляет все инструменты, исполняемые и двоичные файлы, необходимые для компиляции, отладки и запуска программы Java, и является программным обеспечением для конкретной платформы.

JRE — это среда выполнения Java, реализация JVM, которая предоставляет платформу для запуска программ Java. JRE включает в себя JVM, но не включает инструменты разработки, такие как компилятор/отладчик Java.

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

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

разница:

  1. JDK используется для разработки, а JRE используется для запуска Java-программ;
  2. JVM включена как в JDK, так и в JRE;
3. JVM является ядром языка программирования Java и не зависит от платформы.

11) Механизм кэширования Integer

Анализ: проверяет знакомство с исходным кодом

  • См. пример:

Первый возвращает true, это легко понять, как упоминалось выше, a и b указывают на один и тот же адрес.

Почему второй возвращает false? Это связано с тем, что Integer имеет механизм кэширования, который кэширует все числа в диапазоне от -128 до 127 в начале запуска JVM.

Третий возвращает false, поскольку ключевое слово new используется для открытия нового пространства, а два объекта i и j соответственно указывают на два пространства памяти в области кучи.

Мы можем проследить исходный код Integer, чтобы увидеть, что происходит. В IDEA вам нужно только удерживать Ctrl, а затем нажать Integer, он автоматически введет соответствующий файл класса в пакет jar.

Проследите до более чем 700 строк файла, вы увидите такой абзац, вы можете прочитать его внимательно, если вам интересно, не беда, если вам не нужно его читать, потому что вам нужно знать только то, что это это механизм кэширования в Java. Внутренний класс класса Integer кэширует все числа от -128 до 127. (На самом деле верхнюю границу кеша класса Integer можно изменить, модифицировав систему, просто поймите, вникать не надо.)

12) Сколько объектов Sring создается следующими двумя методами?

// 第一种:直接赋一个字面量
String str1 = "ABCD";
// 第二种:通过构造器创建
String str2 = new String("ABCD");

Разбор: проверяет знание объектов String и разбиения памяти JVM.

отвечать:String str1 = "ABCD";Создается не более одного объекта String, и по крайней мере не создается ни одного объекта String. Если в пуле констант есть «ABCD», то на str1 ссылаются напрямую, и в это время объект String не создается. В противном случае «ABCD» пространство памяти сначала создается в пуле констант, а затем на него ссылаются.

String str2 = new String("ABCD");Создайте не более двух объектов String и не менее одного объекта String. Ключевое слово new определенно создает новую область памяти в пространстве кучи, поэтому создается по крайней мере один объект String.

Давайте посмотрим на картинку, чтобы понять:

  • При выполнении первого предложения в пул констант будет добавлен новый символ ABCD, а str1 указывает на ABCD пула констант.
  • Когда выполняется второе предложение, из-за нового оператора в пространстве кучи будет открыто новое пространство для хранения новых объектов String, поскольку в это время в константном пуле уже есть символы ABCD, поэтому объекты String в куче Указывает на ABCD в пуле констант, а str2 указывает на объект String в пространстве кучи.

Объект String — это особое существование, и есть много моментов, на которые следует обратить внимание.Вот ссылка на подробное объяснение String, написанное ранее:порталВключенные вопросы, вероятно, следующие:1) Как соединять строки с помощью "+" 2) Сравнение строк 3) Разница между StringBuilder/StringBuffer/String;

13) В чем разница между i++ и ++i?

Анализ: Для разницы между ними, знакомое выражение: передний ++ должен сначала добавить 1 к значению переменной, а затем использовать значение после добавления 1 для участия в операции, в то время как пост ++ использовать значение для участия в операции сначала, Затем добавить к значению 1. Но на самом деле,Префикс++ и постфикс++ добавят 1 к значению переменной перед участием в операции

Ответ: На самом деле, будь то предваряющий ++ или пост++, значение переменной сначала увеличивается на 1, а затем продолжается вычисление.Настоящая разница между ними заключается в том, что pre-++ заключается в том, чтобы добавить 1 к значению переменной и использовать переменную с добавленной стоимостью для работы, в то время как post-++ должен сначала присвоить переменную временной переменной, а затем к значению переменной. Значение увеличивается на 1, а затем операция выполняется с использованием этой временной переменной.

14) Три способа поменять местами переменные

отвечать:

  • Первый: через третью переменную
public class Test{
    public static void main(String[] args) {
        int x = 5;
        int y = 10;
        swap(x,y);
        System.out.println(x);
        System.out.println(y);

        Value v = new Value(5,10);
        swap(v);
        System.out.println(v.x);
        System.out.println(v.y);
    }

    // 无效的交换:形参的改变无法反作用于实参
    public static void swap(int x,int y) {
        int temp = x;
        x = y;
        y = temp;
    }

    // 有效的交换:通过引用(变量指向一个对象)来修改成员变量
    public static void swap(Value value) {
        int temp = value.x;
        value.x = value.y;
        value.y = temp;
    }
}

class Value{
    int x;
    int y;

    public Value(int x,int y) {
        this.x = x;
        this.y = y;
    }
}

Результат вывода:
5
10
10
5

Это чем-то похоже на указатели в языке C/C++, но относительно безопаснее.

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

Второй: путем добавления (один и тот же класс Value не будет отображаться повторно)

public class Test{
    public static void main(String[] args) {
        Value v1 = new Value(5,10);
        swap(v1);
        System.out.println("v1交换之后的结果为:");
        System.out.println(v1.x);
        System.out.println(v1.y);
    }

    public static void swap(Value v) {
        v.x = v.x + v.y;
        v.y = v.x - v.y;
        v.x = v.x - v.y;
    }
}

Результат вывода:
Результат обмена на v1:
10
5

Основным алгоритмом является метод swap:

v.x = v.x + v.y;    // 把v.x与v.y的和存储在v.x中
v.y = v.x - v.y;    // v.x减掉v.y本来的值即为v.x
v.x = v.x - v.y;    // v.x减掉v.y的值也就是以前x.y的值

Таким образом, цель обмена двумя переменными может быть достигнута без использования временных переменных.Если вышеуказанный метод не прост для понимания, мы также можем использовать другой параметр z для представления вышеуказанного процесса:

int z = v.x + v.y;    // 把v.x与v.y的和存储在z中
v.y = z - v.y;        // z减掉以前的v.y就等于v.x
v.x = z - v.y;        // z减掉现在的v.y即以前的v.x,即为v.y

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

  • Третий способ: XOR:

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

public class Test{
    public static void main(String[] args) {
        Value v1 = new Value(5,10);
        swap(v1);
        System.out.println("v1交换之后的结果为:");
        System.out.println(v1.x);
        System.out.println(v1.y);
    }

    public static void swap(Value v) {
        v.x = v.x ^ v.y;
        v.y = v.x ^ v.y;
        v.x = v.x ^ v.y;
    }
}

Результат вывода:
Результат после свопа v1:
10
5

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

15) Порядок инициализации объекта Java?

Ответ: Независимо от инициализации статических членов, при вызове конструктора объекта программаСначала вызовите конструктор родительского класса(можно указать конструктор родительского класса через ключевое слово super, иначе по умолчанию вызывается конструктор без параметров, и вызывать его нужно в первой строке конструктора дочернего класса),После этого функции инициализации и статические блоки инициализации статических переменных-членов выполняются в соответствии с порядком в коде., если переменная-член не имеет указанного значения, ей будет присвоено значение по умолчанию, то есть базовый тип данных равен 0 или false и т. д., а объект равен нулю;Наконец, вызовите собственный конструктор.

  • Мы можем написать программу для простой проверки порядка инициализации:
public class Derive extends Base
{
    private Member m1 = new Member("Member 1");
    {
        System.out.println("Initial Block()");
    }

    public Derive() {
        System.out.println("Derive()");
    }

    private Member m2 = new Member("Member 2");
    private int i = getInt();

    private int getInt()
    {
        System.out.println("getInt()");
        return 2;
    }

    public static void main(String[] args)
    {
        new Derive();
    }
}

class Base
{
    public Base()
    {
        System.out.println("Base()");
    }
}

class Member
{
    public Member(String m)
    {
        System.out.println("Member() "+m);
    }
}

Вывод программы:
Base()
Member() Member 1
Initial Block()
Member() Member 2
getInt()
Derive()

16) Верные, ложные и нулевые ключевые слова?

Ответ: нет. true и false — литеральные константы логического типа, а null — литеральная константа ссылочного типа.

Интервьюер: А как насчет goto и const?

Ответ: Да. И goto, и const являются зарезервированными ключевыми словами в языке Java, то есть без применения синтаксиса.

17) В чем разница между исключением и ошибкой?

Ответ: И исключение, и ошибка являются подклассами Throwable. исключение используется для исключительных ситуаций, которые может перехватить пользовательская программа; ошибка определяет исключения, которые, как ожидается, не будут перехвачены пользовательской программой.

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

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

Ответ. Ключевое слово throw используется для явного создания исключений в программе, тогда как оператор throws используется для указания исключений, которые метод не может обработать. Каждый метод должен указывать, какие исключения не могут быть обработаны, чтобы вызывающая сторона метода могла гарантировать обработку возможных исключений.Несколько исключений разделяются запятыми.

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

(2) Общие коллекции в Java

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

1) Какие общие коллекции?

Ответ. Интерфейс карты и интерфейс коллекции являются родительскими интерфейсами всех фреймворков коллекций:

  1. Подинтерфейсы интерфейса коллекции включают в себя: интерфейс установки и интерфейс списка.
  2. Классы реализации интерфейса карты в основном включают: HashMap, TreeMap, Hashtable, ConcurrentHashMap и свойства и т. д.
  3. Классы реализации интерфейса Set в основном включают: HashSet, TreeSet, LinkedHashSet и т. д.
  4. Классы реализации интерфейса List в основном включают в себя: ArrayList, LinkedList, Stack и Vector и т. д.

2) В чем разница между HashMap и Hashtable? (обязательный)

отвечать:

  1. HashMap не учитывает синхронизацию и не является потокобезопасным, Hashtable использует ключевое слово synchronized и является потокобезопасным;

  2. Первый допускает значение null в качестве ключа; последний не позволяет использовать значение null в качестве ключа.

3) Знаете ли вы базовую реализацию HashMap?

О: До Java8 основной реализацией был массив + реализация связанного списка, в Java8 — массив + связанный список + реализация красно-черного дерева. На этом этапе вы можете просто нарисовать анализ на бумаге:

4) В чем разница между ConcurrentHashMap и Hashtable? (обязательный)

Ответ: ConcurrentHashMap сочетает в себе преимущества HashMap и HashTable. HashMap не учитывает синхронизацию, HashTable учитывает синхронизацию. Но HashTable блокирует всю структуру каждый раз, когда выполняется синхронизация. Способ блокировки ConcurrentHashMap несколько детализирован. ConcurrentHashMap делит хеш-таблицу на 16 сегментов (значение по умолчанию), а общие операции, такие как получение, установка, удаление, блокируют только те сегменты, которые необходимы в данный момент.

Интервьюер: Вы знаете конкретную реализацию ConcurrentHashMap?

отвечать:

1. Этот класс содержит два статических внутренних класса HashEntry и Segment: первый используется для инкапсуляции пары ключ-значение таблицы сопоставления, а второй используется в качестве блокировки;

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

5) Почему длина HashMap равна степени двойки?

отвечать:

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

2. Если длина является степенью двойки, преобразование длины-1 в двоичную форму должно быть в виде 11111..., потому что двоичная и рабочая эффективность h будет очень быстрой, и пространство не будет потрачено впустую; если длина не является степенью 2, например, если длина равна 15, то длина - 1 равна 14, а соответствующее двоичное значение равно 1110. В операции h и последний бит равен 0 и 0001, 0011 , 0101, 1001, 1011, 0111, 1101 Эти позиции никогда не могут быть Элементы сохраняются, и тратится достаточно много места Что еще хуже, в этом случае доступная позиция массива намного меньше, чем длина массива , а это значит, что вероятность коллизии еще больше возрастает, а эффективность запроса снижается! Это приведет к пустой трате места.

6) В чем разница между списком и набором?

Ответ: элементы списка упорядочены и могут повторяться; элементы множества неупорядочены и не могут повторяться.

7) Начальная емкость и коэффициент загрузки List, Set и Map:

отвечать:

1. List

  • Начальная емкость ArrayList — 10, коэффициент загрузки — 0,5, приращение расширения: 0,5 умноженное на исходную емкость + 1, длина после одного расширения — 16.

  • Вектор имеет начальную емкость 10 и коэффициент загрузки 1. Шаг расширения: в 1 раз больше исходной емкости.Например, емкость Вектора равна 10, а емкость после одного расширения равна 20.

2. Set

HashSet, начальная емкость равна 16, а коэффициент загрузки равен 0,75; приращение расширения: в 1 раз превышает исходную емкость; например, емкость HashSet равна 16, а емкость после одного расширения равна 32.

3. Map

HashMap, начальная емкость равна 16, а коэффициент загрузки равен 0,75; приращение расширения: в 1 раз превышает исходную емкость; например, емкость HashMap равна 16, а емкость после одного расширения равна 32.

8) В чем разница между интерфейсом Comparable и интерфейсом Comparator?

отвечать:

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

2. Последнему не нужно модифицировать исходный код, настраивать компаратор и реализовывать собственный метод сравнения. Справочный блог по конкретному анализу:Платформа коллекции Java — набор

9) «отказоустойчивый» механизм для коллекций Java

отвечать:

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

Например: предположим, что есть два потока (поток 1, поток 2), поток 1 проходит элементы в наборе A через итератор, и в какой-то момент поток 2 изменяет структуру набора A (это модификация структуры, а не простое изменение содержимого элемента коллекции), то в это время программа выдаст исключение ConcurrentModificationException, что приведет к отказоустойчивому механизму.

Причина: итератор напрямую обращается к содержимому коллекции при обходе и использует переменную modCount во время обхода. Если содержимое коллекции изменится во время ее обхода, значение modCount изменится. Всякий раз, когда итератор использует hashNext()/next() для перехода к следующему элементу, он проверяет, является ли переменная modCount ожидаемым значением modCount, и если да, возвращает результат обхода; в противном случае генерирует исключение и завершает обход.

Решение:

1. В процессе обхода добавить synchronized во все места, связанные с изменением значения modCount.

2. Используйте CopyOnWriteArrayList для замены ArrayList

10) Разница между ArrayList и Vector

отвечать:

Оба этих двух класса реализуют интерфейс List (интерфейс List наследует интерфейс Collection), и оба они являются упорядоченными коллекциями, то есть позиции элементов, хранящихся в двух коллекциях, упорядочены, что эквивалентно динамическому массиву. Мы можем получить элемент по индексу позиции в будущем, и данные в нем разрешено повторять. Это самое большое отличие от коллекции, такой как HashSet. Коллекция, такая как HashSet, не может получить свои элементы по номеру индекса. Дублирующиеся элементы также не допускаются.

Разница между ArrayList и Vector в основном заключается в двух аспектах:

  1. Синхронизация:
    Vector является потокобезопасным, что означает, что его методы синхронизируются с потоком (с ключевым словом synchronized), в то время как ArrayList не является потокобезопасным, и его методы не синхронизируются с потоком. Если к коллекции будет обращаться только один поток, то лучше использовать ArrayList, так как он не рассматривает вопрос безопасности потоков, поэтому будет эффективнее; если к коллекции будут обращаться несколько потоков, лучше использовать Vector, т.к. это не так. Нам нужно думать и писать потокобезопасный код самостоятельно.

  2. Рост данных:
    И ArrayList, и Vector имеют начальный размер емкости. Когда количество элементов, хранящихся в них, превышает емкость, пространство для хранения ArrayList и Vector необходимо увеличивать. Вместо этого добавляются несколько единиц хранения, и количество единиц хранения добавляется каждый время должно быть сбалансировано между использованием памяти и эффективностью программы. Когда данные заполнены (коэффициент загрузки 1), Vector увеличивается в два раза по сравнению с исходным размером (шаг расширения: 1 раз превышает исходную емкость), а ArrayList увеличивается до исходной емкости, когда объем данных достигает половины емкости (коэффициент загрузки 0,5). . 0,5 раза + 1 пробел.

Интервьюер: В чем разница между ArrayList и LinkedList?

отвечать:

  1. LinkedList реализует интерфейсы List и Deque, обычно известные как двусвязный список;
  2. LinkedList более эффективен при вставке и удалении данных, а ArrayList более эффективен при поиске данных по определенному индексу;
  3. LinkedList требует больше памяти, чем ArrayList;

Интервьюер: В чем разница между Array и ArrayList? Когда следует использовать Array вместо ArrayList?

Ответ: Разница между ними заключается в следующем:

  1. Массив может содержать примитивные типы и типы объектов, ArrayList может содержать только типы объектов.
  2. Размер Array фиксирован, а размер ArrayList изменяется динамически.
  3. ArrayList предоставляет больше методов и функций, таких как: addAll(), removeAll(), iterator() и так далее.

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

11) Как удалить повторяющиеся элементы в векторной коллекции?

отвечать:

Vector newVector = new Vector();
for (int i = 0; i < vector.size(); i++) {
    Object obj = vector.get(i);
    if (!newVector.contains(obj)) {
        newVector.add(obj);
    }
}

Также есть простой способ воспользоваться тем фактом, что Set не допускает дублирования элементов:

HashSet set = new HashSet(vector);

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

12) Каков компромисс между использованием неупорядоченного массива или упорядоченного массива?

Ответ. Самым большим преимуществом упорядоченных массивов является то, что временная сложность поиска составляет O(log n), а неупорядоченных массивов — O(n). Недостатком отсортированных массивов является то, что временная сложность операции вставки составляет O(n), поскольку элемент с большим значением необходимо переместить назад, чтобы освободить место для нового элемента. Напротив, сложность времени вставки неупорядоченного массива постоянна O (1).

Суммировать

о... это действительно кисло после обзора.... предстоит долгий путь...