---
title: Структуры данных
seo:
  title: Структуры данных — QA
  description: Тема «Структуры данных» для собеседования QA. Что такое PageObject и PageFactory? Какая иерархия Collections?
---

[Все темы QA](/qa)

## <strong>Что такое</strong> <code>PageObject</code> <strong>и</strong> <code>PageFactory</code><strong>?</strong> [#q-14bee738d69b814381a5d9a6ad80c09e]

<code>PageObject</code> и <code>PageFactory</code> — это концепции, используемые
в автоматизации тестирования веб-приложений, особенно с использованием
фреймворка Selenium.

{/* prettier-ignore */}
1. <code>PageObject</code>&#58;

    - <strong>Определение</strong>&#58; Это шаблон проектирования, который используется для абстрагирования веб-страницы или её части в отдельные классы, которые называются PageObject. Каждая страница (или фрагмент страницы) имеет свой собственный класс, который содержит методы для взаимодействия с элементами на этой странице.

    - <strong>Пример</strong>&#58; Класс <code>LoginPage</code>, который содержит методы для заполнения полей логина и пароля, а также кнопки входа.

1. <code>PageFactory</code>&#58;

    - <strong>Определение</strong>&#58; Это вспомогательный класс в Selenium, который помогает инициализировать элементы на веб-странице в PageObject. Он предоставляет аннотации для элементов на странице, которые автоматически инициализируются при вызове PageFactory.initElements(driver, this).

    - <strong>Пример</strong>&#58; Аннотация <code>&#64;FindBy</code> используется для поиска элементов на странице по селектору (CSS, XPath и т. д.) и их инициализации.

<strong>Пример использования</strong>&#58;

```java
public class LoginPage {

    @FindBy(id = "username")
    private WebElement usernameInput;

    @FindBy(id = "password")
    private WebElement passwordInput;

    @FindBy(id = "login-button")
    private WebElement loginButton;

    public LoginPage(WebDriver driver) {
        PageFactory.initElements(driver, this);
    }

    public void enterUsername(String username) {
        usernameInput.sendKeys(username);
    }

    public void enterPassword(String password) {
        passwordInput.sendKeys(password);
    }

    public void clickLoginButton() {
        loginButton.click();
    }
}
```

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

:::note[Ссылки для изучения]

1. [Что такое PageObject и PageFactory](https://kaze.gitbook.io/qa-theory/teoriya-avtomatizirovannogo-testirovaniya/obshie-voprosy/chto-takoe-pageobject-i-pagefactory)
   :::

---

## <strong>Какая иерархия</strong> <code>Collections</code><strong>?</strong> [#q-14bee738d69b811eabe9e8f928d06e40]

Иерархия коллекций в Java представляет собой иерархию классов и интерфейсов, предназначенных для хранения и манипуляций с данными. Основные элементы иерархии включают&#58;

{/* prettier-ignore */}
1. <strong>Интерфейс</strong> <code>Collection</code>&#58;

    - <strong>Наследники</strong>&#58; List, Set, Queue.

    - <strong>Основные методы</strong>&#58; add, remove, size, isEmpty, contains и другие для базовых операций с элементами коллекции.

1. <strong>Интерфейс</strong> <code>List</code>&#58;

    - <strong>Наследники</strong>&#58; ArrayList, LinkedList, Vector.

    - <strong>Основные методы</strong>&#58; get, set, add, remove, indexOf и другие для работы с упорядоченными коллекциями с возможностью дублирования элементов.

1. <strong>Интерфейс</strong> <code>Set</code>&#58;

    - <strong>Наследники</strong>&#58; HashSet, TreeSet, LinkedHashSet.

    - <strong>Основные методы</strong>&#58; add, remove, contains, size и другие для работы с коллекциями, которые не содержат дублирующихся элементов.

1. <strong>Интерфейс</strong> <code>Queue</code>&#58;

    - <strong>Наследники</strong>&#58; LinkedList, PriorityQueue.

    - <strong>Основные методы</strong>&#58; add, remove, element, offer, poll и другие для реализации структур данных очереди.

1. <strong>Интерфейс</strong> <code>Map</code>&#58;

    - <strong>Наследники</strong>&#58; HashMap, TreeMap, LinkedHashMap.

    - <strong>Основные методы</strong>&#58; put, get, remove, containsKey, containsValue и другие для работы с отображениями (ключ-значение).

Эта иерархия позволяет выбирать наиболее подходящий тип коллекции в зависимости от требований к хранению данных и типа операций, которые необходимо выполнить.

:::note[Ссылки для изучения]

1. [Разбор вопросов и ответов на Java Developer](https://javarush.com/groups/posts/3434-razbor-voprosov-i-otvetov-s-sobesedovaniy-na-java-razrabotchika-chastjh-9)
   :::

---

## <strong>Какая разница между</strong> <code>Thread class</code> <strong>и</strong> <code>Runnable interface</code><strong>?</strong> [#q-14bee738d69b81dabe9adb58668cb359]

В Java разница между классом <code>Thread</code> и интерфейсом <code>Runnable</code> связана с тем, как реализуются параллельные задачи&#58;

{/* prettier-ignore */}
- <code>Thread</code> <strong>класс</strong>&#58;

    - <strong>Наследование</strong>&#58; Класс Thread сам по себе является потоком исполнения (Thread).

    - <strong>Реализация</strong>&#58; При использовании класса Thread вы создаёте новый поток путём наследования от Thread и переопределения метода <code>run&#40;&#41;</code>.

    - <strong>Ограничения</strong>&#58; Использование Thread ограничено одиночным наследованием, так как Java поддерживает только одиночное наследование классов.

Пример использования&#58;

```java
class MyThread extends Thread {
    public void run() {
        // Код, выполняемый в отдельном потоке
    }
}
```

{/* prettier-ignore */}
- <code>Runnable</code> <strong>интерфейс</strong>&#58;

    - <strong>Реализация</strong>&#58; Интерфейс Runnable предоставляет альтернативный способ создания потока, отделяя задачу исполнения от самого потока.

    - <strong>Использование</strong>&#58; Вы можете реализовать интерфейс Runnable и передать его экземпляр в конструктор Thread или в исполнитель (Executor).

    - <strong>Преимущества</strong>&#58; Использование интерфейса Runnable упрощает повторное использование кода и повышает гибкость, так как не требует наследования.

Пример использования&#58;

```java
class MyRunnable implements Runnable {
    public void run() {
        // Код, выполняемый в отдельном потоке
    }
}

// Создание потока на основе Runnable
Thread thread = new Thread(new MyRunnable());
```

Runnable отделяет задачу от способа её выполнения. Объект можно передать Thread или Executor; сам по себе Runnable не создаёт поток. Для запуска нового Thread нужен start(), прямой вызов run() выполняется в текущем потоке.

:::note[Ссылки для изучения]

1. [В чём отличие класса Thread и Runnable](https://dzen.ru/a/ZIBaslxstWJkGhk8#:~:text=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D0%BE%D0%B5%20%D0%BE%D1%82%D0%BB%D0%B8%D1%87%D0%B8%D0%B5%20%D0%BC%D0%B5%D0%B6%D0%B4%D1%83%20%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%BE%D0%BC%20Thread,%D0%BF%D1%80%D0%B8%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B5%20%D1%81%20%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%BE%D0%BC%20%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%B2)
   :::

---

## <strong>Какая разница между</strong> <code>String</code><strong>,</strong> <code>Stringbuffer</code> <strong>и</strong> <code>Stringbuilder</code><strong>?</strong> [#q-14bee738d69b81a5a58ce5a91f2d0c2d]

В Java есть три основных класса для работы с текстовыми строками&#58; <code>String</code>, <code>StringBuffer</code> и <code>StringBuilder</code>. Вот их основные различия&#58;

{/* prettier-ignore */}
1. <code>String</code>&#58;

    - <strong>Неизменяемость</strong>&#58; Объекты класса <code>String</code> неизменяемы, что означает, что после создания строки её нельзя изменить.

    - <strong>Потокобезопасность</strong>&#58; Строки являются потокобезопасными (thread-safe), так как не могут быть изменены из разных потоков.

    ```java
    String str = "Hello";
    str += " World"; // Создаётся новая строка "Hello World"
    ```

1. <code>StringBuffer</code>&#58;

    - <strong>Изменяемость</strong>&#58; <code>StringBuffer</code> предназначен для работы с изменяемыми строками.

    - <strong>Потокобезопасность</strong>&#58; <code>StringBuffer</code> является потокобезопасным (thread-safe) благодаря синхронизированным методам.

    ```java
    StringBuffer sb = new StringBuffer("Hello");
    sb.append(" World"); // Изменяет текущий объект StringBuffer
    ```

1. <code>StringBuilder</code>&#58;

    - <strong>Изменяемость</strong>&#58; <code>StringBuilder</code> также предназначен для работы с изменяемыми строками, но не синхронизирован.

    - <strong>Производительность</strong>&#58; <code>StringBuilder</code> обычно быстрее, чем <code>StringBuffer</code>, потому что не имеет накладных расходов на синхронизацию.

    ```java
    StringBuilder sb = new StringBuilder("Hello");
    sb.append(" World"); // Изменяет текущий объект StringBuilder
    ```

<strong>Выбор между ними</strong>&#58;

- Используйте <code>String</code>, когда строка не будет изменяться.

- Используйте <code>StringBuffer</code>, когда потребуется многопоточный доступ к изменяемой строке.

- Используйте <code>StringBuilder</code> в однопоточных приложениях, где требуется эффективная работа с изменяемыми строками.

:::note[Ссылки для изучения]

1. [Разница между String, Stringbuffer и Stringbuilder](https://stackoverflow.com/questions/2971315/string-stringbuffer-and-stringbuilder#:~:text=String%20-%20%D1%8D%D1%82%D0%BE%20%D0%BD%D0%B5%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D1%8F%D0%B5%D0%BC%D1%8B%D0%B9%20%D0%BA%D0%BB%D0%B0%D1%81%D1%81%3B,%D1%8D%D1%82%D0%BE%20%D0%B8%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D0%B0%D1%8F%20%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F%20%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8F%20StringBuilder)
   :::

---

## <strong>Разница между</strong> <code>final</code><strong>,</strong> <code>finally</code> <strong>и</strong> <code>finalize</code><strong>?</strong> [#q-14bee738d69b81639a04fbc66c279552]

В Java <code>final</code>, <code>finally</code>, и <code>finalize</code> выполняют разные функции&#58;

{/* prettier-ignore */}
1. <code>final</code>&#58;

    - <strong>Ключевое слово</strong>&#58; Используется для объявления констант, запрета наследования классов и запрета переопределения методов.

    - <strong>Примеры использования</strong>&#58;

        - Для переменной&#58; <code>final int number &#61; 42&#59;</code> — переменная <code>number</code> не может быть изменена после инициализации.

        - Для класса&#58; <code>final class MyFinalClass &#123;&#125;</code> — класс <code>MyFinalClass</code> не может быть унаследован.

        - Для метода&#58; <code>final void myMethod&#40;&#41; &#123;&#125;</code> — метод <code>myMethod</code> не может быть переопределен в подклассах.

1. <code>finally</code>&#58;

    - <strong>Блок кода</strong>&#58; Часть конструкции <code>try&#45;catch</code>, который выполняется после блоков <code>try</code> и <code>catch</code>, независимо от того, произошло исключение или нет.

    - <strong>Назначение</strong>&#58; Обычно используется для очистки ресурсов, например, закрытия файлов или баз данных вне зависимости от успешного или ошибочного завершения кода в блоке <code>try</code>.

    - <strong>Пример использования</strong>&#58;

        ```java
        try {
            // код, который может вызвать исключение
        } catch (Exception e) {
            // обработка исключения
        } finally {
            // код, который выполняется после try/catch
        }
        ```

1. <code>finalize</code>&#58;

    - Метод finalize() относится к устаревшему механизму финализации; начиная с Java 18 он помечен для удаления. Его выполнение и своевременность не гарантированы.

    - <strong>Назначение</strong>&#58; Предназначен для освобождения ресурсов, которые не управляются системой сборки мусора (например, нативные ресурсы).

    - <strong>Использование</strong>&#58; Использование метода <code>finalize&#40;&#41;</code> не рекомендуется, так как вызов метода не гарантирован и может привести к непредсказуемому поведению. Вместо него предпочтительнее использовать <code>try&#45;with&#45;resources</code> или явное закрытие ресурсов.

    - <strong>Пример</strong>&#58;

        ```java
        @Override
        protected void finalize() throws Throwable {
            // очистка перед уничтожением
            super.finalize();
        }
        ```

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

:::note[Ссылки для изучения]

1. [Как используются final, finally, finalize в Java](https://javarush.com/groups/posts/3837-kofe-breyk-134-chego-sleduet-izbegatjh-pri-napisanii-java-koda-kak-v-java-ispoljhzujutsja-final)
   :::
