Раздел 5 / 5 · 09.04.01.02

Прикладное программирование и веб-технологии

Тема 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(), мы не меняем ни строчки в цикле рисования.

демоПолиморфизм: один вызов 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), который ждёт действий пользователя и вызывает привязанные обработчики. Библиотеки отличаются происхождением и лицензией:

БиблиотекаОсноваОсобенности
TkinterTk, входит в стандартную поставку PythonНичего не нужно устанавливать; простые учебные и служебные интерфейсы; менеджеры компоновки pack / grid / place
PyQt / PySideC++-фреймворк QtСамый богатый набор виджетов, визуальный редактор Qt Designer, механизм «сигналы–слоты» для связи событий с обработчиками; промышленные приложения
wxPythonwxWidgets«Родной» внешний вид на каждой ОС
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: правило = селектор { свойство: значение; … }. Три способа применить стили к документу:

  1. Внешняя таблица стилей<link rel="stylesheet" href="style.css">: один файл на весь сайт, кэшируется браузером — основной способ.
  2. Внутренняя — правила в теге <style> в head данной страницы.
  3. Встроенный стиль — атрибут 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 > класс/атрибут/псевдокласс > тег), при равенстве — то, что объявлено позже (каскад). Часть свойств (шрифт, цвет) наследуется потомками.

демоТренажёр селекторов: кто попадёт под правило?
выберите селектор
Мини-документ показан рамками: каждая рамка — элемент с его тегом, классом или id. Нажмите селектор — подсветятся все элементы, которые он выбирает, а справа появится специфичность в виде (id, классы, теги). Сравните div p и div > p: потомок против непосредственного ребёнка.

JavaScript и объектная модель документа (DOM)

DOM (Document Object Model) — представление html-документа в виде дерева объектов: каждый тег, атрибут и текст — узел дерева. Через глобальный объект 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 при клике; события всплывают от элемента к корню, обработчик получает объект события.
демоЖивое DOM-дерево: документ и его дерево синхронны
кликните элемент или кнопку
Слева — «страница» (вложенные рамки-элементы), справа — её DOM-дерево. Кликните любой элемент: подсветится он, его родитель (пунктиром) и дети. Кнопки выполняют настоящие DOM-операции над песочницей — смотрите, как документ и дерево меняются одновременно, а в статусе появляется выполненный код.

Вопросы к собеседованию

Какова структура 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 построен «слоёным пирогом» — каждый уровень пользуется службами нижнего:

  1. Ядро Linux — процессы, память, драйверы устройств, энергопитание; каждое приложение — отдельный Linux-пользователь в своей «песочнице».
  2. HAL и нативные библиотеки (C/C++) — доступ к камере, сенсорам, звуку; графика (OpenGL ES/Vulkan), SQLite, WebView.
  3. ART (Android Runtime) — среда выполнения: код на Java/Kotlin компилируется в байт-код, ART выполняет его с JIT/AOT-компиляцией; у каждого приложения — свой экземпляр виртуальной машины.
  4. Java API Framework — «кирпичи» для приложений: система окон и представлений (View), менеджеры активностей, уведомлений, пакетов, доступ к данным.
  5. Приложения — системные и установленные; распространяются пакетами 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 с переиспользованием ячеек.