Рассмотрим вопросы, а ответы будут в конце статьи. Перед тем как прочитать ответы, подумайте, как бы на эти вопросы ответили вы.
1. Методы REST API
- Какие основные методы REST API вы знаете?
- В каких ситуациях применяются методы GET, POST, PUT, DELETE?
- Как реализовать идемпотентность для методов API, и почему это важно?
2. Паттерны программирования (для автотестов), Singleton, Builder
- Какой паттерн проектирования вы считаете наиболее полезным при написании автотестов и почему?
- Можете объяснить паттерн Singleton? Как его реализовать на практике?
- Как работает паттерн Builder? Приведите пример, когда его использование оправдано.
3. Аннотация @Data (Lombok)
- Что делает аннотация @Data в Lombok? Какие методы она автоматически генерирует?
- Какие плюсы и минусы использования Lombok в проекте вы видите?
- Как избежать проблем с сериализацией объектов, использующих Lombok?
4. SQL: Primary Key и записи
- Что такое Primary Key в SQL и зачем он нужен?
- Чем отличается уникальный ключ от Primary Key?
- Как вы работаете с большими наборами данных в SQL? Как оптимизировать запросы?
- Что такое записи в SQL?
5. Реляционные и нереляционные базы данных
- В чем основные различия между реляционными и нереляционными базами данных?
- Когда лучше использовать реляционные базы данных, а когда нереляционные?
- Приведите примеры популярных реляционных и нереляционных баз данных.
6. Задача: Найти повторяющиеся слова в строке типа:
String str = "one two one three four five two";
Не важно сколько раз повторяются слова.
7. Как получить доступ к элементу по XPath?
8. Spring Boot
- Какие основные компоненты Spring Boot вы использовали?
- Как работает механизм автоконфигурации в Spring Boot?
- Как настроить и использовать профили в Spring Boot для разных окружений (development, production)?
9. Разделитель строки split()
- Как работает метод split() в Java? Какие параметры он принимает?
- Что произойдет, если в метод split() передать регулярное выражение, и как это повлияет на результат?
10. Перегрузка методов
- Что такое перегрузка методов в Java?
- Когда перегрузка методов может быть полезной в проекте?
- Какие ограничения существуют для перегрузки методов?
11. Переопределение методов
- В чем разница между перегрузкой и переопределением методов?
- Какую роль играет аннотация @Override при переопределении методов?
- Какие правила нужно соблюдать при переопределении методов?
12. Модификатор final
- Что означает модификатор final в Java? Как его можно применить к переменным, методам и классам?
- Можете привести пример, когда использование final является хорошей практикой?
13. Stream API
- Что такое Stream API в Java, и для чего оно используется?
- В чем различие между конечными и промежуточными операциями в Stream API?
- Какие типы операций в Stream API могут быть ленивыми, а какие - жадными?
14. Конечные и промежуточные методы Stream API
- Можете привести примеры промежуточных и конечных методов Stream API?
- Почему промежуточные методы являются "ленивыми"?
- Как работает метод collect() в Stream API? Какие типы коллекций можно собирать?
15. Сериализация/десериализация
- Что такое сериализация и десериализация в Java? Какие библиотеки вы использовали для этого?
- Какие проблемы могут возникнуть при сериализации сложных объектов?
- Как обеспечить обратную совместимость при изменении структуры класса, который сериализуется?
16. Структура HTTP-запроса
- Какова структура типичного HTTP-запроса? Какие основные компоненты он содержит?
- Чем отличается GET-запрос от POST-запроса с точки зрения структуры?
- Что такое заголовки HTTP, и какие из них чаще всего используются?
Что ж, это все вопросы.
Удалось ответить на все? Были какие-то сложными?
Давайте будем отвечать вместе:
1) Методы REST API
1. Какие основные методы REST API вы знаете?
GET: Получение данных с сервера.
POST: Создание новых данных на сервере.
PUT: Полное обновление существующих данных на сервере.
PATCH: Частичное обновление данных.
DELETE: Удаление данных на сервере.
2. В каких ситуациях применяются методы GET, POST, PUT, DELETE?
GET: Используется для получения информации (например, получение списка пользователей).
POST: Применяется для создания новых ресурсов (например, создание нового пользователя).
PUT: Применяется для обновления всего ресурса (например, обновление данных пользователя).
DELETE: Используется для удаления ресурса (например, удаление пользователя).
3. Как реализовать идемпотентность для методов API, и почему это важно
Идемпотентность означает, что повторное выполнение одного и того же запроса приводит к одному и тому же результату.
GET, PUT, DELETE должны быть идемпотентными по стандарту.
Например, повторный вызов DELETE для одного и того же ресурса должен вернуть одинаковое состояние (удалённый ресурс или его отсутствие).
Идемпотентность важна для обеспечения стабильности и предсказуемости в системе, особенно в условиях сбоев и повторных запросов.
2) Паттерны программирования (для автотестов), Singleton, Builder
1. Какой паттерн проектирования вы считаете наиболее полезным при написании автотестов и почему?
Page Object: Это паттерн, который упрощает работу с веб-страницами в тестах. Он инкапсулирует взаимодействие с элементами страниц, делая тесты более читаемыми и поддерживаемыми.
Паттерн Page Factory используется в автоматизации тестирования веб-приложений для упрощения взаимодействия с элементами веб-страниц. Он является расширением паттерна Page Object Model (POM) и предназначен для более эффективного создания объектов страниц и управления веб-элементами. Основное предназначение Page Factory — это улучшение структуры тестов и повышение их читаемости и поддержки.
2. Можете объяснить паттерн Singleton? Как его реализовать на практике
Паттерн Singleton гарантирует, что у класса будет только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру.
3. Как работает паттерн Builder? Приведите пример, когда его использование оправдано.
- Builder нужен для пошаговой сборки сложных объектов, избегая перегруженности конструкторов.
3) Аннотация @Data (Lombok)
1. Что делает аннотация @Data в Lombok? Какие методы она автоматически генерирует?
Аннотация @Data из библиотеки Lombok автоматически генерирует следующие методы для класса:
- getter и setter для всех полей,
- toString() метод,
- equals() и hashCode() методы,
- конструктор для всех final полей.
Пример использования:
2. Какие плюсы и минусы использования Lombok в проекте вы видите?
Плюсы:
Сокращение объема шаблонного кода.
Уменьшение вероятности ошибок при ручной реализации методов.
Минусы:
Усложненная отладка и рефлексия.
Зависимость от сторонней библиотеки.
3. Как избежать проблем с сериализацией объектов, использующих Lombok?
Можно использовать аннотацию @NoArgsConstructor и @AllArgsConstructor для создания конструкторов, совместимых с сериализацией.
4) SQL: Primary Key и записи
1. Что такое Primary Key в SQL и зачем он нужен?
Primary Key — это уникальный идентификатор записи, который не может быть NULL. Он гарантирует уникальность каждой строки в таблице.
2. Чем отличается уникальный ключ от Primary Key?
Primary Key: Единственный ключ в таблице, не допускающий NULL.
Unique Key: Может быть несколько в таблице, допускает NULL.
3. Как вы работаете с большими наборами данных в SQL? Как оптимизировать запросы?
Использование индексов, партиционирование таблиц, денормализация данных (в некоторых случаях), использование лимитов, оптимизация джоинов, кэширование запросов.
4. Что такое записи в SQL?
- Записи — это строки в таблице базы данных. Каждая запись содержит значения для всех колонок (атрибутов) таблицы.
5) Реляционные и нереляционные базы данных
Базы данных — это основа для хранения, организации и управления данными в различных приложениях и системах. В зависимости от структуры данных и требований к их обработке, базы данных делятся на два основных типа: реляционные и нереляционные. Рассмотрим более подробно их различия, преимущества и примеры использования.
1. Основные различия между реляционными и нереляционными базами данных
1. Структура данных
- Реляционные базы данных (РБД) хранят данные в виде таблиц, где каждая таблица состоит из строк (записей) и столбцов (полей). Каждая строка представляет собой одну запись, а каждый столбец — определённый тип данных. Таблицы могут быть связаны между собой с помощью ключей (первичных и внешних), что позволяет создавать сложные структуры данных.
Пример: Таблица с информацией о клиентах может быть связана с таблицей заказов через уникальный идентификатор клиента.
- Нереляционные базы данных (NoSQL) не используют традиционные таблицы для хранения данных. Вместо этого они могут использовать различные структуры, такие как:
Документы (например, JSON или BSON в MongoDB),
Ключ-значение (например, Redis),
Графы (например, Neo4j),
Колонночные базы (например, Cassandra).
В нереляционных базах данных структура данных более гибкая, и она не обязательно должна соответствовать фиксированной схеме.
Пункт на счет более гибкая неоднозначен. Читайте ниже и в комментариях.
2. Схема данных
- Реляционные БД требуют строгого определения схемы данных. Это значит, что перед тем, как добавить данные, необходимо определить структуру таблиц: какие поля существуют, какие типы данных они должны содержать, какие есть ограничения (например, уникальность, обязательные поля и т.д.). Это обеспечивает целостность и согласованность данных.
- Нереляционные БД обычно не требуют предварительного определения схемы. Структура данных может меняться "на лету", что позволяет гибко добавлять новые поля и изменять текущие. Это особенно полезно в тех случаях, когда данные могут иметь разную структуру (например, разные документы в MongoDB могут иметь разные поля).
3. Запросы и операции
- Реляционные БД используют язык запросов SQL (Structured Query Language) для манипуляции данными. SQL предлагает мощные возможности для выполнения сложных операций, таких как объединение (JOIN) данных из нескольких таблиц, агрегация и сортировка.
- Нереляционные БД используют различные методы для взаимодействия с данными. Например, в документно-ориентированных базах данных, таких как MongoDB, данные можно искать с помощью запросов на основе структуры документа (например, с использованием JSON). В базах данных ключ-значение, таких как Redis, операции часто сводятся к простым командам для получения и сохранения данных по ключам.
4. Масштабируемость
- Реляционные БД традиционно следуют вертикальному масштабированию (увеличение мощности одного сервера), что может стать узким местом при увеличении нагрузки. Однако современные реляционные базы данных также поддерживают кластеризацию и репликацию для горизонтального масштабирования (распределение нагрузки между несколькими серверами), но это может быть более сложным процессом.
- Нереляционные БД изначально проектировались для горизонтального масштабирования, что делает их отличным выбором для распределённых систем и работы с большими объёмами данных. Они легко масштабируются на множество серверов, что позволяет обрабатывать огромные объёмы данных и обеспечивать высокую доступность.
5. Целостность данных
- Реляционные БД обеспечивают строгую целостность данных за счёт ACID-транзакций (Atomicity, Consistency, Isolation, Durability). Это гарантирует, что все операции с данными выполняются надлежащим образом и в согласованном состоянии.
- Нереляционные БД часто жертвуют строгой целостностью данных в пользу производительности и масштабируемости. Многие нереляционные базы данных поддерживают модель BASE (Basically Available, Soft state, Eventual consistency), что означает, что данные могут быть временно неконсистентными, но в конечном итоге они придут к согласованному состоянию.
2. Когда лучше использовать реляционные, а когда нереляционные базы данных?
Когда использовать реляционные базы данных:
1. Строгие связи и согласованность: Если данные сильно связаны между собой и необходимо поддерживать целостность и сложные отношения (например, банковские или бухгалтерские системы), то реляционные базы данных — лучший выбор.
2. Четкая схема данных: Если структура данных известна заранее и редко меняется, реляционные базы данных обеспечат надёжное хранение и доступ к данным.
3. Транзакции: Если критично важно, чтобы все операции выполнялись в одной транзакции (например, переводы денег между счетами), ACID-транзакции реляционных баз данных обеспечат требуемую согласованность.
Примеры: банковские системы, системы управления запасами, ERP-системы.
Когда использовать нереляционные базы данных:
1. Гибкость структуры данных (этот пункт требует оговорки): Если структура данных динамическая и может часто меняться (например, в системах, где работают с разнородными данными от разных пользователей), то нереляционные базы данных обеспечат нужную гибкость.
Понятие гибкости всегда зависит от специфики задачи. Нереляционные базы данных действительно могут быть более гибкими в определенных сценариях (например, для хранения неструктурированных данных или данных, слабо привязанных к строгим схемам). Однако, если задача требует строгой структуры и сложных запросов, реляционная модель может показаться более гибкой и удобной.
2. Высокая производительность и масштабируемость: Если требуется быстрая обработка больших объёмов данных и их масштабирование на множество серверов (например, в социальных сетях или системах рекомендаций), нереляционные базы данных обеспечат высокую скорость чтения/записи.
3. Отказ от сложных связей: Если система не требует сложных связей между сущностями (например, кеширование, хранение сессий), то нереляционные базы данных (например, ключ-значение) могут быть более эффективными.
Примеры: социальные сети, приложения для больших данных (Big Data), системы рекомендаций, IoT-приложения.
3. Примеры популярных реляционных и нереляционных баз данных
Реляционные базы данных:
1.MySQL: Одна из самых популярных реляционных баз данных с открытым исходным кодом. Широко используется в веб-приложениях.
2. PostgreSQL: Продвинутая реляционная база данных с поддержкой расширенных возможностей (например, работы с JSON, географическими данными).
3. Oracle: Коммерческая реляционная база данных, используемая в корпоративных системах для обработки критически важных данных.
4. Microsoft SQL Server: Коммерческая база данных от Microsoft, часто используемая в бизнес-приложениях.
Нереляционные базы данных:
1. MongoDB: Документно-ориентированная база данных, которая хранит данные в формате JSON-подобных документов. Популярна в веб-разработке и для хранения неструктурированных данных.
2. Cassandra: Колонночная база данных, разработанная для работы с большими объёмами данных и масштабирования на множество серверов. Широко используется в распределённых системах.
3. Redis: База данных ключ-значение, используемая для кеширования, хранения сессий и других высокопроизводительных задач.
4. Neo4j: Графовая база данных, которая хранит данные в виде узлов и рёбер. Идеальна для работы с графами, такими как социальные сети или системы рекомендаций.
6) Задача: Найти повторяющиеся слова в строке типа: String str = "one two one three four five two";
Одно из хороших решение, это решение через Set
Мы можем решить эту задачу с использованием двух множеств (Set):
- Одно множество будет хранить все уникальные слова.
- Другое множество будет накапливать повторяющиеся слова.
Алгоритм:
1. Разделим строку на слова.
2. Пройдемся по каждому слову:
Если слово уже есть в множестве уникальных слов, добавим его в множество повторяющихся слов.
Если его там нет, добавим его в уникальные слова.
3. В конце выведем все слова, которые есть в множестве повторяющихся слов.
Код решения:
Объяснение:
1. split("\\s+") — разбивает строку по одному или более пробелам.
2. Set<String> uniqueWords — множество для хранения уникальных слов. Если слово уже есть в этом множестве, оно не будет добавлено повторно.
3. Set<String> duplicateWords — множество для хранения повторяющихся слов. Слово добавляется в это множество, если оно уже присутствовало в uniqueWords.
4. uniqueWords.add(word) — метод возвращает false, если элемент уже присутствует в множестве, что позволяет легко определить повторяющиеся слова.
Пример работы программы:
Для строки "one two one three two four" вывод будет:
Повторяющиеся слова: [one, two]
Для строки без повторений, например "one two three four":
Нет повторяющихся слов.
Преимущества использования Set:
- O(1) время на добавление и проверку существования элемента.
- Простота реализации и высокая производительность для задач с проверкой уникальности и поиска дубликатов.
7) Как получить доступ к элементу по XPath?
1. По абсолютному пути: "/html/body/div[1]/div[2]/div[3]".
2. По относительному пути: "//div[@class='example']".
3. По атрибутам: "//input[@id='username']".
4. По тексту: "//button[text()='Submit']".
5. По частичному совпадению атрибутов: "//input[contains(@name, 'user')]"
8) Spring Boot
Spring Boot — это фреймворк для создания приложений на Java, использующий Spring Framework. Он упрощает процесс разработки приложений, предлагая автоконфигурацию и встроенные серверы (например, Tomcat). Основные компоненты:
- @SpringBootApplication
- Встроенные серверы — Tomcat, Jetty
- Автоконфигурация (Auto Configuration)
- Spring Initializr для быстрого создания проектов
1. Какие основные компоненты Spring Boot вы использовали?
Spring Boot Starter: набор зависимостей для быстрого начала работы (например, spring-boot-starter-web, spring-boot-starter-data-jpa).
Spring Boot Actuator: предоставляет информацию о состоянии приложения (метрики, состояние здоровья).
Spring Boot DevTools: инструменты для улучшения производительности разработки (автоперезагрузка, кэширование шаблонов и т.д.).
Spring Boot Security: используется для внедрения методов аутентификации и авторизации.
2. Как работает механизм автоконфигурации в Spring Boot?
Spring Boot использует аннотацию @EnableAutoConfiguration (или аннотацию @SpringBootApplication, которая включает в себя автоконфигурацию).
Это позволяет автоматически настраивать компоненты приложения на основе зависимостей, указанных в проекте.
Например, если в проекте есть зависимость от spring-boot-starter-data-jpa, Spring автоматически сконфигурирует JPA и базу данных.
3. Как настроить и использовать профили в Spring Boot для разных окружений (development, production)?
Использование аннотации @Profile для указания, в каком профиле должен работать конкретный компонент.
Настройка различных файлов конфигурации в зависимости от профиля (например, application-dev.properties для разработки и application-prod.properties для продакшена).
Выбор профиля через параметры командной строки или переменные окружения: --spring.profiles.active=dev.
9) Разделитель строки split()
1. Как работает метод split() в Java? Какие параметры он принимает?
Метод split() разделяет строку на массив подстрок по регулярному выражению (разделителю).
Пример:
String[] parts = "apple,banana,orange".split(",");
вернет массив {"apple", "banana", "orange"}.
В Java метод split() является методом класса String и используется для разделения строки на подстроки на основе заданного регулярного выражения (regex). Метод может принимать один или два параметра:
split(String regex)
- Описание: Разделяет строку на подстроки на основе регулярного выражения regex.
- Параметры: regex — регулярное выражение, по которому строка будет разделена.
- Возвращаемое значение: Массив строк, содержащий части исходной строки, разделенные по регулярному выражению.
- Пример:
split(String regex, int limit)
- Описание: Разделяет строку на подстроки на основе регулярного выражения regex, но с ограничением на количество частей, определяемое параметром limit.
- Параметры:
regex — регулярное выражение.
limit — максимальное количество частей, на которые будет разделена строка:
Если limit > 0, строка будет разделена на максимум limit частей. Последняя часть будет содержать остаток строки, даже если в ней еще есть разделители.
Если limit == 0, пустые строки в конце массива будут удалены.
Если limit < 0, строка будет разделена на все возможные части без удаления пустых строк.
- Возвращаемое значение: Массив строк с частями, на которые была разделена исходная строка.
- Пример:
2. Что произойдет, если в метод split() передать регулярное выражение, и как это повлияет на результат?
Если передать регулярное выражение, разделение будет происходить по указанному шаблону.
Например,
"one1two2three".split("\\d")
разделит строку по цифрам и вернет массив {"one", "two", "three"}.
10) Перегрузка методов
1. Что такое перегрузка методов в Java?
Перегрузка методов — это создание нескольких методов с одинаковым именем, но с разными типами или количеством параметров.
2. Когда перегрузка методов может быть полезной в проекте?
Перегрузка может быть полезной, когда нужно предоставить разные способы вызова метода в зависимости от типа или количества параметров. Например, метод, который может принимать как массив, так и коллекцию.
3. Какие ограничения существуют для перегрузки методов?
Нельзя перегружать методы, опираясь только на возвращаемый тип.
Обязательно должны отличаться параметры (по количеству или типу).
11) Переопределение методов
1. В чем разница между перегрузкой и переопределением методов
Перегрузка: методы с одинаковым именем, но разными параметрами в одном классе.
Переопределение: метод с тем же именем и параметрами в подклассе, который заменяет реализацию метода родительского класса.
2. Какую роль играет аннотация @Override при переопределении методов
Аннотация @Override сигнализирует компилятору, что метод является переопределением метода родительского класса. Если метод не соответствует сигнатуре родительского метода, произойдет ошибка компиляции.
3. Какие правила нужно соблюдать при переопределении методов?
Метод должен иметь ту же сигнатуру (имя, параметры и возвращаемый тип).
Модификатор доступа может быть более открытым, но не более закрытым.
Переопределенный метод не может бросать исключения, которые не указаны в базовом методе.
12) Модификатор final
1. Что означает модификатор final в Java? Как его можно применить к переменным, методам и классам?
final переменная: значение переменной не может быть изменено после инициализации.
final метод: метод не может быть переопределен в подклассе.
final класс: класс не может быть унаследован.
2. Можете привести пример, когда использование final является хорошей практикой?
Использование final для переменных, которые должны быть неизменными после инициализации (например, константы), или для классов, которые не должны быть расширены (например, классы, обеспечивающие безопасность).
13) Stream API
1. Что такое Stream API в Java, и для чего оно используется?
Stream API — это способ работы с коллекциями данных (например, списками) через функциональные операции, такие как фильтрация, сортировка, преобразование и агрегация. Он позволяет писать более декларативный и читабельный код.
1. В чем различие между конечными и промежуточными операциями в Stream API?
Промежуточные операции возвращают новый поток и являются ленивыми (например, filter(), map()).
Конечные операции запускают цепочку операций и возвращают результат (например, forEach(), collect()).
2. Какие типы операций в Stream API могут быть ленивыми, а какие — жадными?
Ленивые операции: промежуточные операции, такие как filter(), map(), которые выполняются только при вызове конечной операции.
Жадные операции: конечные операции, такие как collect(), forEach(), которые приводят к выполнению всех предыдущих операций.
14) Конечные и промежуточные методы Stream API
1. Можете привести примеры промежуточных и конечных методов Stream API?
Промежуточные методы: map(), filter(), sorted(), distinct().
Конечные методы: collect(), forEach(), reduce().
2. Почему промежуточные методы являются "ленивыми"?
Промежуточные методы не выполняются сразу. Они накапливаются до тех пор, пока не будет вызвана конечная операция, которая запускает выполнение всей цепочки.
3. Как работает метод collect() в Stream API? Какие типы коллекций можно собирать?
collect() — это конечная операция, которая собирает элементы потока в коллекцию или другой контейнер. С помощью Collectors можно собирать данные в List, Set, Map и другие структуры.
15) Сериализация/десериализация
1. Что такое сериализация и десериализация в Java? Какие библиотеки вы использовали для этого?
Сериализация — это процесс преобразования объекта в поток байтов для сохранения или передачи.
Десериализация — это обратный процесс, преобразование потока байтов обратно в объект.
Популярные библиотеки: Jackson, Gson (для JSON), Java Serialization (стандартная библиотека).
2. Какие проблемы могут возникнуть при сериализации сложных объектов?
Проблемы с версионностью классов (если структура класса меняется).
Потеря данных, если сериализуется объект с transient полями.
Проблемы с сериализацией циклических зависимостей.
3. Как обеспечить обратную совместимость при изменении структуры класса, который сериализуется?
Использование serialVersionUID для контроля версий класса.
Добавление методов для обработки обновленной структуры при десериализации (например, readObject).
16) Структура HTTP-запроса
Пример запроса (POST):
POST /submit-form HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
name=John+Doe&email=john%40example.com
Пояснение:
- POST /submit-form HTTP/1.1 — это строка запроса. Она состоит из:POST — метод запроса, который используется для отправки данных на сервер.
/submit-form — путь к ресурсу на сервере, который обработает данные (например, скрипт на сервере, который обрабатывает форму).
HTTP/1.1 — версия протокола HTTP. - User-Agent: Mozilla/5.0... — заголовок, содержащий информацию о клиенте (браузере), который отправляет запрос.
- Content-Type: application/x-www-form-urlencoded — заголовок, который указывает, что данные будут переданы в формате формы (URL-кодированные данные). Это формат, который обычно используется при отправке HTML-форм.
- Content-Length: 42 — заголовок, указывающий длину тела запроса в байтах (в данном случае 42 байта).
- Accept: text/html,application/xhtml+xml,... — заголовок, указывающий, какие типы данных клиент готов принять в ответ.
- Accept-Language: en-US,en;q=0.5 — заголовок, указывающий предпочтительные языки ответа (в данном случае английский).
- Connection: keep-alive — заголовок, указывающий, что клиент предлагает серверу поддерживать соединение открытым для возможных последующих запросов.
- Тело запроса: В данном случае тело запроса содержит данные, которые отправляются на сервер:name=John+Doe — поле формы с именем "name" и значением "John Doe".
email=john%40example.com — поле формы с email "john@example.com" (символ @ закодирован как %40).
1. Какова структура типичного HTTP-запроса? Какие основные компоненты он содержит?
Строка запроса (Request line): метод запроса (GET, POST и т.д.), URI, версия протокола HTTP.
Заголовки (Message Headers): метаданные запроса (например, Content-Type, Authorization).
Тело запроса (Entity body): для методов, которые передают данные, таких как POST).
2. Чем отличается GET-запрос от POST-запроса с точки зрения структуры?GET-запрос: данные передаются в URL (в строке запроса), обычно не имеет тела.
POST-запрос: данные передаются в теле запроса.
3. Что такое заголовки HTTP, и какие из них чаще всего используются?
Заголовки HTTP — это метаданные запроса или ответа, которые помогают серверу и клиенту обмениваться информацией.
Примеры популярных заголовков:
- Content-Type: указывает тип данных в теле (например, application/json).
- Authorization: используется для передачи токенов или других данных аутентификации.
- Accept: указывает, какие типы данных клиент ожидает от сервера.
Если Вам интересно, что еще можно найти на канале QA Helper, прочитайте статью: Вместо оглавления. Что вы найдете на канале QA Helper - справочник тестировщика?
Не забудьте подписаться на канал, чтобы не пропустить полезную информацию: QA Helper - справочник тестировщика
Пишите в комментариях какой пункт было бы интересно рассмотреть более подробно.
Обязательно прочитайте: Что должен знать и уметь тестировщик
Также будет интересно почитать: Вопросы которые задают на собеседовании тестировщикам