Тема 5.1
Объектно-ориентированное программирование
Понятие класса, поля и методы, ссылочные переменные, инкапсуляция, наследование, полиморфизм и динамическое связывание — вопросы билетов №6, №18.
Понятие класса и объекта
Класс — чертёж дома: на нём указано, что у дома есть площадь и этажность (поля) и что в доме можно «открыть дверь» (метод). Объект — конкретный построенный дом: чертёж один, домов по нему — сколько угодно, и площадь у каждого своя.
Синтаксис и структура класса (на Java-подобном языке):
class Point {
// поля (данные объекта)
private double x;
private double y;
// конструктор — вызывается при создании экземпляра
Point(double x, double y) { this.x = x; this.y = y; }
// методы (операции над данными)
double dist() { return Math.sqrt(x*x + y*y); }
void moveTo(double nx, double ny) { x = nx; y = ny; }
}
- Описание полей — как объявление переменных, но внутри класса; каждое поле имеет тип и модификатор доступа.
- Описание методов — функции внутри класса; им доступны все поля «своего» объекта (через
this/self). - Модификаторы доступа:
public— виден всем;private— только внутри класса;protected— внутри класса и наследников. - Создание экземпляра:
Point p = new Point(3, 4);— выделяется память в куче, вызывается конструктор. - Доступ к полям и вызов методов — через точку:
p.dist(),p.moveTo(0, 0).
Ссылочные переменные
В большинстве ООП-языков (Java, C#, Python, JavaScript) переменная типа «класс» хранит не сам объект, а ссылку на него: объект живёт в куче (heap), а переменная — лишь «адрес» этого объекта.
Два имени — один объект.
Point p1 = new Point(3, 4);
Point p2 = p1; // копируется ССЫЛКА, а не объект!
p2.moveTo(0, 0);
// p1.dist() == 0 — p1 и p2 указывают на ОДИН объект
Следствия: присваивание и передача объекта в метод — дешёвые (копируется только адрес); сравнение p1 == p2 сравнивает адреса, а не содержимое (для содержимого — equals); переменная может быть «пустой» (null / None); объекты, на которые не осталось ссылок, уничтожает сборщик мусора.
Три принципа ООП
- Инкапсуляция — объединение данных и методов в классе и сокрытие внутреннего устройства: поля закрыты (
private), доступ — через методы (геттеры/сеттеры), которые могут проверять корректность. Внешний код зависит только от интерфейса класса — внутренности можно менять свободно. - Наследование — создание нового класса (производного, наследника) на основе существующего (базового): наследник получает все поля и методы родителя, добавляет свои и может переопределять унаследованные методы. Выражает отношение «является» (круг — это фигура).
- Полиморфизм — возможность работать с объектами разных классов через общий интерфейс базового класса: один и тот же вызов
fig.draw()выполняет разный код в зависимости от фактического класса объекта.
Полиморфизм и динамическое связывание
Механизм: для класса с виртуальными методами компилятор строит таблицу виртуальных методов (vtable) — массив адресов реализаций. Каждый объект хранит указатель на таблицу своего класса. Вызов fig.draw() превращается в «взять из таблицы объекта адрес метода draw и перейти по нему» — поэтому один и тот же код обходит массив фигур, а рисуется каждая по-своему.
Figure[] figs = { new Circle(...), new Square(...), new Triangle(...) };
for (Figure f : figs)
f.draw(); // тип переменной — Figure, но вызывается
// Circle.draw / Square.draw / Triangle.draw
В Java методы виртуальны по умолчанию, в C++ нужно слово virtual, в Python всякий вызов метода — позднее связывание (поиск по имени в словаре класса). Полиморфное поведение методов — основа расширяемости: добавив класс Star с собственным draw(), мы не меняем ни строчки в цикле рисования.
Figure[], но в нём вперемешку круги, квадраты и треугольники. Цикл вызывает у всех один и тот же метод draw() — а таблица виртуальных методов у каждого объекта своя, поэтому каждая фигура рисует себя сама. Под фигурой подписан фактический класс, чей код выполнился.Вопросы к собеседованию
Что такое класс и что такое объект?
Класс — описание нового типа данных, объединяющее поля (данные) и методы (операции над ними); это «чертёж». Объект (экземпляр) — конкретная переменная этого типа, созданная по чертежу: у каждого объекта свои значения полей, методы — общие для всех экземпляров класса.
Как описываются поля и методы класса и как к ним обращаться?
Поля объявляются внутри класса как переменные с типом и модификатором доступа; методы — как функции внутри класса, которым доступны поля своего объекта через this/self. Экземпляр создаётся оператором new (вызывается конструктор), доступ к полям и вызов методов — через точку: obj.field, obj.method(). Модификаторы: public — всем, private — только внутри класса, protected — классу и наследникам.
В чём особенность ссылочных переменных?
Переменная хранит не объект, а ссылку (адрес) на объект в куче. Присваивание копирует ссылку, поэтому две переменные могут указывать на один объект — изменение через одну видно через другую. Сравнение == сравнивает адреса, для сравнения содержимого нужен equals. Ссылка может быть пустой (null); объекты без ссылок удаляет сборщик мусора.
Что такое инкапсуляция и зачем она нужна?
Объединение данных и методов в классе с сокрытием внутреннего устройства: поля закрываются (private), работа с ними — через открытые методы, которые контролируют корректность (инварианты). Внешний код зависит только от интерфейса, поэтому реализацию можно менять, не ломая пользователей класса.
Что даёт наследование?
Производный класс получает все поля и методы базового, добавляет свои и может переопределять унаследованные. Это повторное использование кода и выражение отношения «является» (круг — фигура): везде, где ожидается базовый класс, можно передать наследника. Иерархии наследования — основа полиморфизма.
Что такое полиморфизм и динамическое связывание?
Полиморфизм — работа с объектами разных классов через общий интерфейс базового: вызов fig.draw() выполняет код фактического класса объекта. Обеспечивается динамическим (поздним) связыванием: адрес метода выбирается во время выполнения по таблице виртуальных методов объекта, а не по типу переменной на этапе компиляции. Это позволяет добавлять новые классы, не меняя существующий код.
Чем раннее связывание отличается от позднего?
Раннее (статическое) — компилятор жёстко подставляет адрес метода по типу переменной; быстро, но поведение фиксировано. Позднее (динамическое) — метод выбирается во время выполнения по фактическому классу объекта (через vtable); чуть дороже, но даёт полиморфное поведение. В C++ позднее связывание включается словом virtual, в Java работает по умолчанию, в Python — всегда.
Тема 5.2
Python: классы и графический интерфейс
ООП в Python и библиотеки для настольных GUI-приложений — вопросы билетов №3, №12, №13.
ООП в Python
В Python всё — объект: числа, строки, функции, модули и сами классы. Класс объявляется словом class; первый параметр каждого метода — self, ссылка на текущий экземпляр (аналог this, но передаётся явно).
class Vector:
dim = 2 # атрибут КЛАССА (общий для всех)
def __init__(self, x, y): # конструктор
self.x = x # атрибуты ЭКЗЕМПЛЯРА
self.y = y
def length(self): # обычный метод
return (self.x**2 + self.y**2) ** 0.5
def __add__(self, other): # перегрузка оператора +
return Vector(self.x + other.x, self.y + other.y)
def __str__(self): # строковое представление
return f"({self.x}; {self.y})"
v = Vector(3, 4) + Vector(1, 0)
print(v, v.length()) # (4; 4) 5.656...
- Атрибуты класса и экземпляра:
dimодин на всех,self.x— у каждого объекта свой. Атрибуты можно добавлять динамически. - Магические методы (
__init__,__str__,__add__,__eq__,__len__…) встраивают класс в синтаксис языка: операторы, печать, сравнение, len(). - Наследование:
class Circle(Figure):; вызов родительской реализации —super().__init__(...). Поддерживается множественное наследование (порядок поиска — MRO). - Инкапсуляция — соглашением: «приватные» имена начинают с подчёркивания
_x(или__x— имя искажается), настоящих модификаторов доступа нет. Контролируемый доступ — декоратор@property: снаружи это поле, внутри — метод с проверками. - Утиная типизация: полиморфизм без общего базового класса — подойдёт любой объект, у которого есть нужный метод («если крякает как утка — это утка»). Проверка типов происходит в момент вызова.
Полиморфизм по-питоновски — иерархия не обязательна:
class Circle:
def draw(self): print("круг")
class Star: # НЕ наследует Circle и вообще ничего
def draw(self): print("звезда")
for f in [Circle(), Star()]:
f.draw() # работает: у обоих есть draw()
В Java такой цикл не скомпилируется без общего интерфейса; в Python достаточно совпадения «повадок» — это и есть утиная типизация.
GUI-библиотеки Python
Все настольные GUI строятся по одной схеме: окно из виджетов (кнопки, поля, списки) + цикл обработки событий (event loop), который ждёт действий пользователя и вызывает привязанные обработчики. Библиотеки отличаются происхождением и лицензией:
| Библиотека | Основа | Особенности |
|---|---|---|
| Tkinter | Tk, входит в стандартную поставку Python | Ничего не нужно устанавливать; простые учебные и служебные интерфейсы; менеджеры компоновки pack / grid / place |
| PyQt / PySide | C++-фреймворк Qt | Самый богатый набор виджетов, визуальный редактор Qt Designer, механизм «сигналы–слоты» для связи событий с обработчиками; промышленные приложения |
| wxPython | wxWidgets | «Родной» внешний вид на каждой ОС |
| Kivy | собственный движок (OpenGL) | Мультитач, один код для настольных и мобильных платформ |
Минимальное приложение на Tkinter — окно, поле, кнопка, обработчик:
import tkinter as tk
def on_click():
lbl["text"] = "Привет, " + entry.get()
root = tk.Tk() # главное окно
entry = tk.Entry(root); entry.pack()
tk.Button(root, text="OK", command=on_click).pack()
lbl = tk.Label(root); lbl.pack()
root.mainloop() # цикл обработки событий
Схема одна во всех библиотеках: создать виджеты → скомпоновать → привязать обработчики → запустить event loop. В PyQt та же связка называется «сигнал clicked подключён к слоту on_click».
Вопросы к собеседованию
Как устроен класс в Python? Что такое self?
Класс объявляется словом class; конструктор — метод __init__. self — явная ссылка на текущий экземпляр, первый параметр каждого метода: через него методы читают и создают атрибуты объекта (self.x = x). При вызове obj.method() Python сам подставляет obj в self.
Чем атрибут класса отличается от атрибута экземпляра?
Атрибут класса объявлен в теле класса и общий для всех экземпляров (одно значение на класс); атрибут экземпляра создаётся через self (обычно в __init__) и у каждого объекта свой. При чтении Python ищет имя сначала в экземпляре, потом в классе, потом в базовых классах.
Как в Python работает наследование?
Базовые классы указываются в скобках: class Circle(Figure). Наследник получает все атрибуты и методы, может переопределять их; родительская реализация доступна через super() (обычно super().__init__() в конструкторе). Поддерживается множественное наследование, порядок поиска методов задаёт MRO (method resolution order).
Что такое магические методы? Приведите примеры.
Методы с двойными подчёркиваниями, которые Python вызывает неявно, встраивая объект в синтаксис языка: __init__ — создание, __str__ — печать, __add__ — оператор +, __eq__ — сравнение ==, __len__ — len(), __getitem__ — индексация []. Перегрузив их, свой класс делают «как встроенный тип».
Что такое утиная типизация?
Полиморфизм без обязательного общего базового класса: коду важно не «кем объект является», а «что он умеет» — подойдёт любой объект с нужным методом. Пригодность проверяется в момент вызова во время выполнения. Отсюда название: «если ходит как утка и крякает как утка — это утка».
Какие библиотеки для GUI на Python вы знаете?
Tkinter — стандартная (обёртка Tk), проста, менеджеры pack/grid/place. PyQt/PySide — обёртки Qt: богатые виджеты, Qt Designer, сигналы-слоты, промышленный уровень. wxPython — нативный вид на каждой ОС. Kivy — мультитач и мобильные платформы. Все строятся на цикле обработки событий и дереве виджетов.
Как устроено событийное GUI-приложение?
Программа создаёт окно и виджеты, привязывает к событиям обработчики (command в Tkinter, сигналы-слоты в Qt) и передаёт управление циклу событий (mainloop): он ждёт действий пользователя, превращает их в события и вызывает нужные обработчики. Логика приложения «живёт» в обработчиках, а не в линейном коде.
Тема 5.3
Веб-технологии: HTML, CSS, JavaScript
Теговая разметка и структура документа, применение CSS и селекторы, объектная модель документа — вопросы билетов №1, №17.
HTML: теговая разметка и структура документа
Принцип теговой разметки: содержимое документа размечается парными тегами <тег атрибут="значение">…</тег> (есть и одиночные: <img>, <br>, <input>). Теги задают структуру и смысл частей документа, а не внешний вид — вид определяет CSS. Теги могут вкладываться, образуя дерево.
<!DOCTYPE html> <!-- тип документа: HTML5 -->
<html lang="ru">
<head> <!-- служебная часть: не отображается -->
<meta charset="utf-8">
<title>Заголовок вкладки</title>
<link rel="stylesheet" href="style.css">
</head>
<body> <!-- видимое содержимое -->
<h1>Заголовок</h1>
<p class="note">Абзац с <a href="…">ссылкой</a>.</p>
</body>
</html>
- Типы html-документов задаёт декларация
<!DOCTYPE>: современный HTML5 (<!DOCTYPE html>) против исторических HTML 4.01 и XHTML (строгий XML-синтаксис) с длинными DTD-декларациями. DOCTYPE переключает браузер в стандартный режим разбора. - Основные группы тегов: структурные (
div,header,section), текстовые (h1–h6,p,ul/ol/li,table), гипертекст (a), медиа (img,video), формы (form,input,select,textarea). - Глобальные атрибуты
id(уникальное имя элемента) иclass(метка группы) — «крючки», за которые элемент цепляют CSS и JavaScript.
CSS: способы применения и селекторы
Синтаксис CSS: правило = селектор { свойство: значение; … }. Три способа применить стили к документу:
- Внешняя таблица стилей —
<link rel="stylesheet" href="style.css">: один файл на весь сайт, кэшируется браузером — основной способ. - Внутренняя — правила в теге
<style>в head данной страницы. - Встроенный стиль — атрибут
style="color:red"у конкретного элемента: самый высокий приоритет, но смешивает структуру с оформлением.
Виды селекторов:
| Селектор | Пример | Что выбирает |
|---|---|---|
| Универсальный | * | все элементы |
| По тегу | p | все абзацы |
| По классу | .note | элементы с class="note" |
| По идентификатору | #top | элемент с id="top" (один) |
| По атрибуту | input[type="text"] | элементы с данным атрибутом/значением |
| Потомок | div p | абзацы на любой глубине внутри div |
| Дочерний | div > p | абзацы — непосредственные дети div |
| Соседний | h2 + p | абзац сразу после h2 |
| Псевдокласс | a:hover, li:first-child | состояние или позиция элемента |
| Псевдоэлемент | p::first-line | часть элемента |
Если элементу подходят несколько правил, побеждает более специфичный селектор (id > класс/атрибут/псевдокласс > тег), при равенстве — то, что объявлено позже (каскад). Часть свойств (шрифт, цвет) наследуется потомками.
div p и div > p: потомок против непосредственного ребёнка.JavaScript и объектная модель документа (DOM)
document JavaScript читает и изменяет это дерево, и браузер немедленно перерисовывает страницу.- Отношения элементов: у узла есть родитель (
parentNode), дети (children,firstElementChild,lastElementChild) и соседи (previousElementSibling/nextElementSibling) — по дереву можно ходить в любую сторону. - Методы поиска элементов:
document.getElementById('top')— по id;getElementsByTagName,getElementsByClassName— живые коллекции; универсальныеquerySelector(css)/querySelectorAll(css)— по любому CSS-селектору. - Свойства элементов:
innerHTML(разметка внутри),textContent(только текст),value(у полей форм),style(встроенные стили),classList(add / remove / toggleклассов), атрибуты —getAttribute / setAttribute. - Создание и управление:
document.createElement('li')→ наполнить → вставить:parent.append(el),parent.prepend(el),ref.before(el)/ref.after(el); переместить — просто append в новое место (узел один, он переезжает); удалить —el.remove(). - События:
el.addEventListener('click', fn)— браузер вызовет fn при клике; события всплывают от элемента к корню, обработчик получает объект события.
Вопросы к собеседованию
Какова структура html-документа?
Декларация <!DOCTYPE html> (тип документа), корневой <html>, внутри — <head> со служебной информацией (кодировка, title, подключение стилей и скриптов) и <body> с видимым содержимым. Содержимое размечается вложенными парными тегами и образует дерево элементов.
В чём принцип теговой разметки? Какие бывают типы документов?
Содержимое оборачивается тегами <тег атрибут="значение">…</тег>, которые описывают структуру и смысл (заголовок, абзац, таблица), а не внешний вид; вид задаёт CSS. Тип документа объявляет DOCTYPE: HTML5 — короткое <!DOCTYPE html>, исторические HTML 4.01 и XHTML (XML-синтаксис) — длинные DTD-декларации. DOCTYPE включает стандартный режим разбора браузера.
Какими способами CSS применяется к документу?
Три способа: внешняя таблица стилей через <link rel="stylesheet"> (основной — один файл на сайт, кэшируется); внутренняя — правила в теге <style> в head; встроенный стиль — атрибут style у элемента (самый высокий приоритет). Синтаксис правила: селектор { свойство: значение; }.
Перечислите виды селекторов CSS.
Универсальный *, по тегу (p), по классу (.note), по id (#top), по атрибуту (input[type="text"]); комбинаторы — потомок (div p), дочерний (div > p), соседний (h2 + p); псевдоклассы (:hover, :first-child) и псевдоэлементы (::first-line). При конфликте побеждает более специфичный селектор: id > класс > тег; при равенстве — последнее правило (каскад).
Что такое DOM?
Объектная модель документа: браузер разбирает HTML в дерево объектов-узлов (элементы, атрибуты, текст) и даёт JavaScript доступ к нему через объект document. Изменение дерева (добавление, удаление, правка узлов) немедленно отражается на странице. У каждого узла есть родитель, дети и соседи — по дереву можно перемещаться.
Какие есть методы поиска элементов в документе?
document.getElementById(id) — один элемент по id; getElementsByTagName / getElementsByClassName — живые коллекции по тегу или классу; querySelector(css) — первый элемент по любому CSS-селектору, querySelectorAll(css) — все совпадения. Современный код обычно использует querySelector/All как универсальные.
Как создать, вставить, переместить и удалить элемент?
Создание: document.createElement('li'), наполнение через textContent/innerHTML/setAttribute. Вставка: parent.append/prepend, ref.before/after. Перемещение — повторный append в новое место: узел существует в дереве один раз и переезжает. Удаление: el.remove(). Всё это сразу перерисовывается браузером.
Какие свойства элементов используются чаще всего?
innerHTML — разметка внутри элемента; textContent — только текст; value — содержимое полей форм; style — встроенные стили; classList с методами add/remove/toggle — управление классами; getAttribute/setAttribute — произвольные атрибуты; parentNode/children/nextElementSibling — навигация по дереву.
Как JavaScript реагирует на действия пользователя?
Через события: el.addEventListener('click', handler) регистрирует обработчик, браузер вызывает его при событии и передаёт объект события (координаты, клавиша, целевой элемент). События всплывают от целевого элемента вверх по дереву, что позволяет вешать один обработчик на общего родителя (делегирование).
Тема 5.4
Серверная сторона: PHP и MySQL
Обработка данных на сервере, передача данных форм, работа с СУБД — вопросы билетов №14, №15.
PHP: обработка данных на сервере
PHP — интерпретируемый язык, выполняющийся на сервере: браузер запрашивает страницу → веб-сервер передаёт файл интерпретатору PHP → тот выполняет код и формирует HTML → браузеру уходит уже готовая разметка (кода PHP клиент никогда не видит). Код встраивается в HTML вставками <?php … ?>.
Методы передачи данных из формы на сервер:
- GET — данные в строке адреса:
search.php?q=SQL&page=2. Виден в адресе, можно сохранить в закладки, ограничен по длине. Для запросов, которые ничего не меняют (поиск, фильтры). - POST — данные в теле HTTP-запроса: не видны в адресе, размер практически не ограничен. Для изменения данных, паролей, загрузки файлов.
Суперглобальные массивы доступны в любом месте программы: $_GET и $_POST — данные соответствующего метода (ключ — имя поля формы), $_REQUEST — объединение обоих, $_FILES — загруженные файлы, $_SESSION и $_COOKIE — состояние между запросами, $_SERVER — сведения о запросе и сервере.
Форма и её обработка:
<form action="hello.php" method="post">
<input type="text" name="user">
<input type="submit" value="Отправить">
</form>
<?php // hello.php
$name = $_POST['user'] ?? 'гость'; // данные поля user
echo "Привет, " . htmlspecialchars($name);
?>
Значение поля попадает в $_POST['user'] по атрибуту name. Перед выводом пользовательские данные пропускают через htmlspecialchars() — иначе присланный «текст» <script>…</script> выполнится у других посетителей (XSS-атака).
PHP и MySQL
Для работы с СУБД в PHP есть расширение mysqli и универсальный интерфейс PDO (работает с разными СУБД). Схема всегда одна: соединиться → выполнить запрос → обработать результат → закрыть.
<?php
// 1. соединение с сервером БД: хост, пользователь, пароль, база
$db = new mysqli("localhost", "root", "secret", "userdata");
// 2а. добавление (модификация, удаление — так же)
$db->query("INSERT INTO users(name, city) VALUES('Иван', 'Тамбов')");
$db->query("UPDATE users SET city='Москва' WHERE id=3");
$db->query("DELETE FROM users WHERE id=7");
// 2б. выборка и обработка результатов
$res = $db->query("SELECT name, city FROM users");
while ($row = $res->fetch_assoc()) { // строка → ассоц. массив
echo $row['name'] . " — " . $row['city'] . "<br>";
}
$db->close();
?>
Подготовленные выражения обязательны, когда в запрос попадают данные пользователя: запрос с плейсхолдерами компилируется один раз, значения передаются отдельно и не могут изменить текст SQL — это защита от SQL-инъекций (ввод вида ' OR 1=1 -- в наивно склеенном запросе вернул бы всю таблицу).
$st = $db->prepare("SELECT * FROM users WHERE city = ?");
$st->bind_param("s", $_GET['city']); // s — строковый параметр
$st->execute();
$res = $st->get_result();
Вопросы к собеседованию
Как PHP обрабатывает запрос? Чем серверный код отличается от клиентского?
PHP выполняется на сервере: веб-сервер передаёт файл интерпретатору, тот выполняет вставки <?php…?> и формирует готовый HTML, который отправляется браузеру — клиент кода не видит. JavaScript, напротив, исполняется в браузере у клиента. Серверный код имеет доступ к БД и файлам сервера; клиентский — к DOM страницы.
Чем метод GET отличается от POST?
GET передаёт данные в строке адреса (?q=…&page=…): виден, ограничен по длине, можно закладку — для запросов чтения. POST передаёт данные в теле HTTP-запроса: не виден в адресе, без практических ограничений размера, поддерживает файлы — для изменения данных и паролей. В PHP данные попадают в $_GET и $_POST соответственно.
Что такое суперглобальные массивы?
Встроенные массивы, доступные в любой области видимости: $_GET, $_POST — данные формы (ключ — атрибут name поля), $_REQUEST — их объединение, $_FILES — загруженные файлы, $_COOKIE и $_SESSION — состояние между запросами, $_SERVER — информация о запросе. Через них серверный сценарий получает всё, что прислал клиент.
Как из PHP работать с MySQL?
Через mysqli или PDO: установить соединение (хост, пользователь, пароль, база) — new mysqli(...); выполнять запросы query(): INSERT/UPDATE/DELETE для изменения, SELECT для выборки; результат выборки обходить в цикле fetch_assoc() (строка как ассоциативный массив по именам столбцов); закрыть соединение close().
Что такое SQL-инъекция и как от неё защищаются?
Атака, при которой пользовательский ввод, склеенный в текст запроса, меняет сам запрос (классика: ' OR 1=1 --). Защита — подготовленные выражения: запрос с плейсхолдерами (?) компилируется отдельно, значения привязываются bind_param и попадают в запрос только как данные. Дополнительно — проверка типов и минимальные права пользователя БД.
Зачем нужен htmlspecialchars при выводе данных?
Функция заменяет спецсимволы HTML (<, >, &, кавычки) на безопасные сущности. Без неё присланный пользователем «текст» со вставкой <script> выполнится в браузерах других посетителей (XSS-атака — межсайтовый скриптинг). Правило: всё, что пришло от пользователя, экранируется при выводе.
Тема 5.5
Архитектура мобильных приложений: Android
Слои платформы, компоненты приложения, жизненный цикл — вопрос билета №9.
Слои платформы Android
Android построен «слоёным пирогом» — каждый уровень пользуется службами нижнего:
- Ядро Linux — процессы, память, драйверы устройств, энергопитание; каждое приложение — отдельный Linux-пользователь в своей «песочнице».
- HAL и нативные библиотеки (C/C++) — доступ к камере, сенсорам, звуку; графика (OpenGL ES/Vulkan), SQLite, WebView.
- ART (Android Runtime) — среда выполнения: код на Java/Kotlin компилируется в байт-код, ART выполняет его с JIT/AOT-компиляцией; у каждого приложения — свой экземпляр виртуальной машины.
- Java API Framework — «кирпичи» для приложений: система окон и представлений (View), менеджеры активностей, уведомлений, пакетов, доступ к данным.
- Приложения — системные и установленные; распространяются пакетами APK.
Компоненты приложения и жизненный цикл
Android-приложение — не одна «программа с main()», а набор компонентов, которые система запускает по необходимости; все они объявляются в манифесте (AndroidManifest.xml) вместе с разрешениями:
- Activity — один экран с интерфейсом; приложение — стопка активностей (навигация назад = снятие со стека);
- Service — длительная работа без интерфейса (музыка, синхронизация в фоне);
- Broadcast Receiver — реакция на широковещательные события (сеть появилась, батарея разряжена);
- Content Provider — предоставление данных другим приложениям через единый интерфейс (контакты, галерея).
Компоненты связываются интентами (Intent) — «намерение» запустить экран или действие, своё или чужое («открыть камеру», «поделиться текстом»).
Жизненный цикл Activity — цепочка обратных вызовов, которыми система сообщает экрану о смене состояния: onCreate (создание, построение интерфейса) → onStart (виден) → onResume (в фокусе, работает) → onPause (перекрыт) → onStop (не виден) → onDestroy (уничтожен). При повороте экрана активность пересоздаётся — поэтому состояние хранят вне её.
Современная рекомендуемая архитектура (Jetpack): слой интерфейса — разметка/Compose + ViewModel (хранит состояние экрана, переживает пересоздание Activity) — слой данных — Repository, объединяющий локальную БД (Room/SQLite) и сеть. Данные текут к интерфейсу реактивно (LiveData/Flow), длинные списки рисует RecyclerView, переиспользующий ячейки. Схема близка к MVVM: View ↔ ViewModel ↔ Model.
Вопросы к собеседованию
Из каких слоёв состоит платформа Android?
Снизу вверх: ядро Linux (процессы, память, драйверы, песочницы приложений); HAL и нативные библиотеки C/C++ (графика, SQLite); среда выполнения ART, исполняющая байт-код Java/Kotlin с JIT/AOT; Java API Framework (View, менеджеры системных служб); прикладной слой — приложения в пакетах APK.
Назовите четыре компонента Android-приложения.
Activity — экран с интерфейсом; Service — длительная фоновая работа без интерфейса; Broadcast Receiver — реакция на широковещательные события системы; Content Provider — предоставление данных другим приложениям. Все объявляются в манифесте; связываются и запускаются через Intent.
Опишите жизненный цикл Activity.
Система уведомляет экран обратными вызовами: onCreate (создание, инициализация интерфейса) → onStart (стал видим) → onResume (получил фокус) → onPause (частично перекрыт) → onStop (не виден) → onDestroy (уничтожение). При повороте экрана Activity пересоздаётся, поэтому состояние хранят во ViewModel или сохраняют в onSaveInstanceState.
Что такое Intent и манифест?
Intent — «намерение», объект-сообщение для запуска компонента или действия: явный (конкретный класс своего приложения) или неявный («открыть камеру», «поделиться» — система подберёт обработчика). AndroidManifest.xml — паспорт приложения: перечень всех компонентов, требуемые разрешения (камера, сеть), фильтры интентов.
Как устроена рекомендуемая архитектура Android-приложения?
Разделение на слои (близко к MVVM): интерфейс (View/Compose) наблюдает за ViewModel, которая хранит состояние экрана и переживает пересоздание Activity; данные даёт Repository, скрывающий источники — локальную БД (Room) и сеть. Поток данных реактивный (LiveData/Flow); списки — RecyclerView с переиспользованием ячеек.