Инженерный тур. 1 этап
В профиле Разработка мобильных приложений через всю Олимпиаду проходит «Деловая Стажировка». Итак, представим, что участник Олимпиады хочет летом попасть на стажировку в компанию S-Mobile на должность Android-разработчика, а для этого ему предстоит пройти конкурсный отбор. Отбор будет состоять из двух этапов: индивидуальное собеседование и практическое задание.
Вначале предстоит пройти индивидуальное собеседование. У компании S-Mobile есть свой онлайн-магазин с названием S-Store. Кандидату на должность предстоит разобраться в его устройстве и ответить на вопросы. Начнем...
Любой онлайн-магазин обязательно хранит много информации: о товарах, продавцах, покупателях и многом другом. Такая информация чаще всего содержится в реляционной базе данных. В нашем случае — в базе данных SQLite. Дан фрагмент схемы базы данных магазина S-Store: https://drawsql.app/teams/myteam-1108/diagrams/e-store-database.
Задача: продемонстрировать навыки работы с реляционной базой данных с помощью SQL (https://en.wikipedia.org/wiki/SQL), а именно, базовые CRUD-операции (https://en.wikipedia.org/wiki/Create,_read,_update_and_delete).
Составьте SQL-запрос на выборку названия товара с первичным ключом, равным 5.
Элементы для заполнения пропусков: SELECT, UPDATE, INSERT, FROM, WHERE, name, products, id, 5.
products.
.id =
Запрос на выборку осуществляется с помощью команды SELECT.
Указание таблиц, из которых происходит выборка данных, осуществляется с помощью команды FROM.
Указания условий, которым должны удовлетворять выбираемые записи, осуществляется с помощью ключевого слова WHERE.
SELECT products.name
FROM products
WHERE products.id = 5
Определите количество товаров с ценой в диапазоне от A до B.
Запрос на выборку осуществляется с помощью команды SELECT.
Указание таблиц, из которых происходит выборка данных, осуществляется с помощью команды FROM.
Указания условий, которым должны удовлетворять выбираемые записи, осуществляется с помощью ключевого слова WHERE.
Для объединения условий используются логические операции AND, OR, NOT.
SELECT *
FROM products
WHERE products.price >= A AND products.price <= B
После этого можно посчитать количество строк, которые вернул запрос.
Также можно воспользоваться агрегирующей функциейCOUNT. Тогда запрос будет выглядеть так: SELECT COUNT(*)
FROM products
WHERE products.price >= A AND products.price <= B
Составьте SQL-запрос, который добавит в базу данных новый продукт со следующими характеристиками.
- Название продукта:
NAME(задается случайно). - Описание продукта:
DESC(задается случайно). - Цена:
PRICE(задается случайно). - Категория товара:
CATEGORY_NAME(задается случайно).
Никаких других записей НЕ нужно добавлять, модифицировать или удалять.
SELECT *
FROM CATEGORY_NAME
WHERE name = CATEGORY_NAME
Здесь уточнение условий, которым должны удовлетворять выбираемые записи, осуществляется с помощью ключевого слова WHERE.
Запрос на добавление данных осуществляется с помощью команды INSERT INTO, за которой указывается название таблицы и полей.
Значения полей указывается после команды VALUES.
INSERT INTO product (name, description, price, category_id)
VALUES(NAME, DESC, PRICE, category_id);
Составьте SQL-запрос на изменение в базе данных цены продукта, который создали в прошлом задании. Новая цена продукта должна стать NEW_PRICE.
Никаких других записей не нужно добавлять, модифицировать или удалять.
Запрос на обновление данных осуществляется с помощью команды UPDATE.
Поля и их новые значения указываются после команды SET.
WHERE. UPDATE products
SET price = NEW_PRICE
WHERE id = ID
Составьте SQL-запрос на удаление из базы данных продукта, который создали ранее в задаче 1.3.
Запрос на удаление данных осуществляется с помощью команды DELETE FROM.
WHERE. DELETE FROM product
WHERE id = ID
Бэкенд онлайн-магазина S-Store предоставляет данные клиентскому Android-приложению в формате JSON (https://en.wikipedia.org/wiki/JSON). Поэтому следующий блок вопросов нашего собеседования будет посвящен именно этому стандарту обмена данными.
Представьте информацию о товаре с ID, равным 70, из базы данных в формате JSON.
Элементы для перемещения: 1, 2, name, inventory_id, 799.99, 899.99, 2024-08-09T12:00:00, created_at, 2025-08-09T12:00:00.
{
"___": 70,
"___": "Smartphone XYZ",
"description": "Latest model with advanced features.",
"SKU": "ELEC-001",
"category_id": 1,
"___": 1,
"price": ___,
"discount_id": null,
"___": "___",
"modified_at": "2024-08-09T12:00:00"
}
Получаем информацию аналогично решению в задании 1.1 и составляем JSON этого объекта.
{
"id": 70,
"name": "Smartphone XYZ",
"description": "Latest model with advanced features.",
"SKU": "ELEC-001",
"category_id": 1,
"inventory_id": 1,
"price": 799.99,
"discount_id": null,
"created_at": "2024-08-09T12:00:00",
"modified_at": "2024-08-09T12:00:00"
}
Android-приложение S-Store написано на языке программирования Kotlin с использованием Android SDK. Ниже представлен data-класс, представляющий ИМЯ_СУЩНОСТИ (рандомно). Составьте JSON-описание, соответствующее этому классу. Значения свойств задать произвольно.
Пример одного из вариантов.
data class User(
val id: Int,
val username: String?,
val password: String?,
val firstName: String?,
val lastName: String?,
val telephone: Int?,
val createdAt: LocalDateTime?,
val modifiedAt: LocalDateTime?,
val createdBy: Int
)
В соответствии с кодом класса выбираем необходимые типы данных и составляем JSON.
{
"id": 1,
"username": "johndoe",
"password": "securepassword123",
"firstName": "John",
"lastName": "Doe",
"telephone": 1234567890,
"createdAt": "2024-08-09T12:00:00",
"modifiedAt": "2024-08-09T12:30:00",
"createdBy": 100
}
Бэкенд магазина разработан на языке Java с использованием фреймворка Spring Boot. Вот JSON, представляющий ИМЯ_СУЩНОСТИ (задается случайно). Составьте класс на языке программирования Java, соответствующий этому JSON. Все поля должны быть с модификатором доступа private. Каждому полю должен соответствовать getter и setter с модификатором доступа public.
Далее пример одного из вариантов.
{
"id": 1,
"username": "johndoe",
"password": "securepassword123",
"firstName": "John",
"lastName": "Doe",
"telephone": 1234567890,
"createdAt": "2024-08-09T12:00:00",
"modifiedAt": "2024-08-09T12:30:00",
"createdBy": 100
}
В соответствии с кодом JSON выбираем необходимые типы данных и составляем код класса на языке Java.
Ниже представлено решение на языке Java.
public class User {
private int id;
private String username;
private String password;
private String firstName;
private String lastName;
private Integer telephone;
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
private int createdBy;
// Default constructor
public User() {
}
// Constructor with all fields
public User(int id, String username, String password, String firstName, String lastName, Integer telephone, LocalDateTime createdAt, LocalDateTime modifiedAt, int createdBy) {
this.id = id;
this.username = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.telephone = telephone;
this.createdAt = createdAt;
this.modifiedAt = modifiedAt;
this.createdBy = createdBy;
}
// Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getTelephone() {
return telephone;
}
public void setTelephone(Integer telephone) {
this.telephone = telephone;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getModifiedAt() {
return modifiedAt;
}
public void setModifiedAt(LocalDateTime modifiedAt) {
this.modifiedAt = modifiedAt;
}
public int getCreatedBy() {
return createdBy;
}
public void setCreatedBy(int createdBy) {
this.createdBy = createdBy;
}
// toString method
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", telephone=" + telephone +
", createdAt=" + createdAt +
", modifiedAt=" + modifiedAt +
", createdBy=" + createdBy +
'}';
}
}
Бэкенд магазина S-Store предоставляет клиентскому Android-приложению API. По ссылке можно найти Swagger (https://en.wikipedia.org/wiki/Swagger_(software)) документацию API для работы с пользователями. Изучив документацию, составьте HTTP-запросы, которые реализуют CRUD-операции. Эти запросы можно составлять и отправлять, например, с помощью Postman: https://www.postman.com.
Составить HTTP-запрос на выборку пользователя с первичным ключом, равным ID (задается случайно). В качестве ответа укажите фамилию пользователя.
Анализируем документацию API, находим соответствующий запрос и составляем его.
Зависит от случайно сгенерированного параметра ID.
Общий ответ для всех вариантов:
ФАМИЛИЯ
Например, если ID=1, то ответ будет:
Doe
Добавьте в базу данных нового пользователя со следующими характеристиками:
- Название продукта:
name. - Описание продукта:
desc. - Цена:
price. - Категория товара:
category_name.
Анализируем документацию API, находим соответствующий запрос, составляем его и отправляем с помощью Postman.
Правильность выполнения определяется конечным состоянием базы данных после выполнения запроса, составленного участником. Задача считается решенной верно, если после этого в базе данных присутствует запись, которую необходимо было добавить в соответствии с условием задачи.
Измените в базе данных контактный телефон пользователя, который создали в задаче 3.2. Новый телефон должен стать new_telephone (рандомно).
Анализируем документацию API, находим соответствующий запрос, составляем его и отправляем с помощью Postman.
Правильность выполнения определяется конечным состоянием базы данных после выполнения запроса, составленного участником. Задача считается решенной верно, если после этого в базе данных присутствует запись, которую необходимо было изменить в соответствии с условием задачи.
Удалите из базы данных пользователя, которого создали ранее в задаче 3.2.
Анализируем документацию API, находим соответствующий запрос, составляем его и отправляем с помощью Postman.
Правильность выполнения определяется конечным состоянием базы данных после выполнения запроса, составленного участником. Задача считается решенной верно, если после этого в базе данных присутствует запись, которую необходимо было добавить в соответствии с условием задачи.
Составить HTTP-запрос на выборку пользователя с первичным ключом, равным id (задается случайно). В качестве ответа укажите фамилию пользователя.
Проверяется автоматически, что в профиле пользователя заполнено нужное поле и оно содержит ссылку на github-аккаунт.
Методика проверки
Баллы не зачисляются.
Склонируйте ветку BRANCH_NAME (задается случайно) репозитория, в котором находится код мобильного приложения S-Store в свой аккаунт и откройте код в Android Studio.
Данное задание не проверяется и не оценивается. Это руководство к действию.
Попробуем запустить приложение. Очевидно, что программа завершилась ошибкой. Так и было задумано!
При программировании под Android ошибки можно увидеть в специальном журнале (LogCat). По нему программист определяет, какая произошла ошибка и в какой строке.
Укажите файл, строку, в которой произошла ошибка и вид ошибки.
Ошибка содержалась в файле (MainActivity.kt, AndroidManifest.xml, buil.gradle.kts) в строке (одно число).
Причиной этого стало (арифметическая операция, переполнение стека, нехватка памяти, зависание программы, обращение к несуществующему объекту).
В зависимости от BRANCH_NAME, которую надо было клонировать, возможны разные ошибки.
Ошибка содержалась в файле MainActivity.kt в строке 34. Причиной этого стало (арифметическая операция, переполнение стека, нехватка памяти, зависание программы, обращение к несуществующему объекту).
Android SDK активно использует XML для хранения различных данных приложения, например, разметку интерфейса, темы интерфейса, систему навигации, иконки, строковые ресурсы, информацию, которую приложение предоставляет операционной системе Android (манифест приложения) и многое другое. В этом блоке нужно найти в xml-файлах приложения S-Store необходимую информацию о приложении.
Определите, какие разрешения может запросить у операционной системы приложение S-Store. В качестве ответа сопоставьте название разрешения с его описанием. Если разрешение отсутствует в манифесте, укажите это.
Варианты зависят от BRANCH_NAME, которую нужно было клонировать. Здесь представлен вариант для ветки BRANCH_NAME=var1.
| Разрешения | Варианты описания разрешений (порядок в учебной системе будет рандомный) |
|---|---|
BLUETOOTH |
Позволяет приложениям подключаться к сопряженным устройствам Bluetooth |
ACCESS_NETWORK_STATE |
Позволяет приложениям получать доступ к информации о сетях |
ACTIVITY_RECOGNITION |
Позволяет приложению распознавать физическую активность |
INTERNET |
Позволяет приложениям открывать сетевые сокеты |
READ_CONTACTS |
Позволяет приложению считывать контактные данные пользователя |
| Разрешение отсутствует в манифесте |
Надо открыть файл манифеста и определить, какие разрешение запрашивает приложение. В разных BRANCH_NAME будут разные разрешения.
| Разрешения | Описание разрешения |
|---|---|
BLUETOOTH |
Позволяет приложениям подключаться к сопряженным устройствам Bluetooth |
ACCESS_NETWORK_STATE |
Позволяет приложениям получать доступ к информации о сетях |
ACTIVITY_RECOGNITION |
Позволяет приложению распознавать физическую активность |
INTERNET |
Разрешение отсутствует в манифесте |
READ_CONTACTS |
Разрешение отсутствует в манифесте |
Определите цвет основного ELEMENT (задается случайно) приложения в THEME_COLOR теме (задается случайно). Ответ представьте в виде четырех чисел, введенных через пробел, представляющих компоненты Red, Green, Blue и Alpha соответственно. Каждое число должно быть в десятичной системе счисления, в диапазоне от 0 до 255.
Надо открыть XML-файлы темы и цветов, сопоставить их и определить цвет, после чего перевести его в десятичную систему счисления.
Зависит от случайно сгенерированной пары (ELEMENT, THEME_COLOR).
Общий ответ для всех вариантов:
R G B A
Например, если (ELEMENT, THEME_COLOR)=(Action bar, Dark), то ответ для BRANCH_NAME=var1 будет:
47 91 237 0
Интерфейс Android приложение магазина S-Store может отображаться на двух языках: русском и английском. Однако перевод приложения на английский язык еще не завершен. Составьте фрагмент XML, который бы позволил отображаться на английском языке строковый ресурс RESOURCE_NAME (задается случайно).
Надо открыть XML строковых ресурсов и перевести на английский язык соответствующий элемент, после чего составить необходимый XML-элемент для этого же ресурса на английском языке.
Зависит от случайно сгенерированного параметра RESOURCE_NAME.
Общий ответ для всех вариантов:
<string name="RESOURCE_NAME"> RESOURCE_NAME_TRANSLATION</string>
Например, если RESOURCE_NAME=security, то ответ будет:
<string name="security">Security</string>
