Skip to content

Latest commit

 

History

History

General_theory

Теоретическая информация о Python

  1. Язык программирования Python, его особенности. Python - интерпретируемый, высокоуровневый язык с строгой динамической типизацей. Интерпретируемость значит, что при каждом запуске код на лету компилируется (преобразуется в байт-код, который удобен для интерпретатора, то есть создается файл .pyc) и лишь затем он выполняется встроенным интерпретатором. Динамическая типизация позволяет ранее объявленную переменную одного типа переопредилить как переменную другого типа (a = 5; a = 'five'). Строгая типизация накладывает ограничения на работу с разными типами данных, так, невозможно сложить число и строку ('five' + 5 => error).

  2. Модули и пакеты. Модуль в Python - это обычный файл с расширением .py, а пакет - это директория, которая содержит в себе модули.

  3. Парадигмы, парадигма ООП. Парадигма - это совокупность правил, которые необходимо соблюлать при написании кода. Таким образом, парадигма позволяет стандартизировать написание кода. ООП - объектно-ориентированное программирование, одна из парадигм, в которой рассматриваются объекты, обладающие своими данными и определенным набором доступных действий. ООП имеет следующую структуру:

    • Класс - шаблон для создания объекта;
    • Объект - экземпляр класса, который обладает методами и атрибутами;
    • Метод - функция внутри объекта или класса;
    • Атрибут - характеристика объекта (цена, имя и т.д.).
  4. Основные принципы ООП:

    • Инкапсуляция - принцип, согласно которому информация (в том числе методы), которая необходима для работы конкретного объекта хранится только внутри этого объекта. Данный принцип позволяет избежать ошибок при случайных зависимостях, когда меняя один объект мы случайно меняем другой.
    • Наследование. Из названия принципа очевидно, что смысл данного принципа заключается в том, что каждый дочерний элемент может наследовать свойства (методы и атрибуты) родительского класса, а также, очевидно, добавлять свои. Профит в том, что не нужно каждый раз заново прописывать методы и атрибуты для новых классов.
    • Полиморфизм - принцип, позволяющий одному и тому же методу работать по-разному в зависимости от места и данных, с которыми он работает. Пример полиморфизма в Python: 5 + 5 = 10 и '5' + '5' = '55'.
  5. Типы данных: изменяемые и неизменяемые.

    • изменяемые - такой тип данных, которы мы можем, как ни странно, изменять. К изменяемым типам данным относятся: список (list), словарь (dict), множество (set) и байтовые массивы (byte arrays);
    • неизменяемые - такой тип данных, который мы не можем изменить. К неизменяемы относятся все остальные: числа (int, float, complex), булевы значения (bool), строки (str) и кортежи (tuple).
  6. Асимптотическая сложность алгоритмов и структур данных. По большому счету это время и память, которые понадобятся программа в процессе работы. При реализации алгоритмов лучше избегать сложности O(N^2) и выше. При больших N справедливо следующее неравенство: 1 < log(n) < n < nlog(n) < n^2 < n!. Асимптотика поиска элемента в списке O(N), а в словаре - O(1), так как для ключей словаря используется алгоритм хеширования. Работа с множеством (set) и кортежем (tuple), а именно вхождение или поиск элемента происходит за константное время O(1) за счёт хэширования каждого элемента структуры по аналогии со словарями. Примеры сложности некоторых алгоритмов:

    • Поиск элемента обычным перебором - O(N);
    • Поиск элемента бинарным поиском - O(logN);
    • Сортировка списка методом пузырька - O(N^2);
    • Сортировка встроенным методом sorted() - O(NlogN)
    • Вхождение элемента из списка A в список B (A и B - сортированные списки интов) простым перебором - O(N*K) = O(N^2)
    • Вхождение элемента из списка A в список B с использованием двойных указателей - O(N+K) и т.д.
  7. Контекстный менеджер - представляет собой коснтрукцию вида 'with ... as' и позволяет автоматичеки обрабатывать исключения, и в случае сбоя программы используемый ресурс будет автоматичеки освобожден. При вызове контекстного менеджера вызывается магический метод __enter__, а при выходе из него вызывается магический метод __exit__.

  8. Декоратор - это функция, которая принимает функцию и возвращает функцию. Декораторы используются для расширения функционала функции без изменения ее структуры. Декоратор может быть вызван выражением decorator = decorator(any_func) или с использованием синтаксического сахара @decorator перед объявлением функции.

  9. Итераторы и генераторы.

    • Генератор - это функция, в которой есть оператор yield. Оператор yield как и оператор return возвращает значение из функции, НО не прерывает ее! Генераторы полезны, когда нужно итерироваться по большому количеству значений, но мы не хотим нагружать память, запоминая все эти значения.
    • Итератор - это не есть итерируемый объект (list, str, dict и т.д.), на самом деле это объект, который образуется в результате вызова магического метода __iter__(). Метод __iter__() может быть вызван циклом for. Итерируемые объекты не имеют метода __next__(), а итератор - имеет!
  10. Области видимости переменных:

    • Глобальная перменная - такая перменная, которая определена вне функции и доступна, как вне функции, так и в ней и для этого даже не нужно передавать переменную в качестве аргумента функции.
    • Локальная переменная - переменная, которая определяется внутри функции и доступна только в ней.
    • Нелокальная переменная - переменная, перед которой указывается выражение nonlocal. Обычно используется в случае вложенных функций, когда для переменной внутренней функции нужно взять значение переменной с тем же названием из внешней функции.
    • Если глобальная и локальная переменная имеют одинаковые наименования, то внутри функции приоритет будет иметь локальное определение.
  11. Правила именования в Pyhton.

    • Переменные, методы, модули и пакеты именуются в стиле snake_case (все слова строчными буквами и разделены символом подчеркивания _);
    • Классы именуются в стиле CamalCase (первая буква каждого слова пишется заглавной);
    • Константы именуются только заглавными буквами в стиле SNAKE_CASE.
  12. Виды методов. В Python выделяют статический метод и метод класса.

    • Статический метод (@staticmethod) - метод, который реализует некоторый функционал внутри класса не по отношению к объекту (экземпляру класса), а по всему классу. Пример.
    • Метод класса (@classmethod) - метод, который не привязан к конкретному экземпляру, но в тоже время вовлекает в свою работу сам класс. Метод принимает на вход первым атрибутом сам класс cls, а затем ввод пользователя. Он возвращает экземпляр класса, таким образом, это альтернативный способ создания класса. Пример.
  13. Property.

  14. Магические методы __str__ и __repr__.

  15. Анонимная функция (lambda-функция) - это функция, которая не имеет имени и определяется без литерала def. Lambda-функция используется тогда, когда нам нужно единственный раз реализовать небольшую функцию и больше она нам нигде не понадобится. Пример squares_list = list(map(lambda x: x ** 2, range(1, 5)))

  16. Принципы проекторования SOLID.

  17. HTTP-запросы, их виды и особенности (безопасность, что можем передать и т.д.). HTTP (HyperText Transfer Protocol) - протокол передечаи гипертекста(обычный текст + ссылки на другие источники). При работе с HTTP можно как отправить запрос (HTTP-Request), так и получить ответ (HTTP-Response). Основные виды HTTP-запросов:

    • GET - метод, позволяющий запросить ресурс с сервера. Передает данные в ссылке в виде пар 'переменная=значение', то есть данные видны всем в адресной строке бразуера, более того данные могут кэшированы, а сама страница может быть проиндексирована поисковыми системами. Вывод: логин и пароль таким методом передавать не надо! Длина запроса ограничена 2048 символами. Файлы не могут быть отправлены.
    • POST - метод для отправки/загрузки данных на сайт. Передает данные в теле запроса. Таким образом, страница не может быть кэширована, проиндексирована или добавлена в закладки. Вывод: данный метод лучше всего подходит для передачи важной информации. Более того, POST поддерживает возможность отправки файлов.
    • HEAD - метод для получения только заголовков ответа (без тела) сервера.
    • PUT - метод для создания нового ресурса на сервере.
    • DELETE - метод для удаления ресурсов на сервере.
    • PATCH - метод для внесения частичных изменений в ресурс на сервере.
    • OPTIONS - метод для получения информации о сервере, например, какие методы у него разрешены.
  18. URL (Uniform Resource Locator) - строка, в которой указывается запрашиваемый ресурс и параметры запроса. Основные компоненты URL:

    • Поле Scheme - здесь указывается используемый протокол 'http'/'https' (80/443), а в конце добавляется конструкция вида '://'.
    • Host - ip сервера или доменное имя.
    • Port - порт, по которому можно обратиться к серверу. Не всегда нужно указывать, обычно по дефолту выбирается порт, соответсвующий протоколу.
    • Path - указатель на ресурс, к которому производится обращение. Если не указан явно, то чаще всего сервер вернет дефолтный указатель (например, на страницу index.html).
    • Поле Query String - поле, в котором после знака '?' парами указываются параметр и значение, разделенные знаком '='. Чтобы задать несколько параметров, можно использовать символ амперсанд '&'. Пример: http://my-server.ru:80/main/example.html?group_id=53&device_id=1 .
  19. Коды состояния HTTP:

    • 100-199 - информационные коды (вряд ли придется на них обращать внимание);
    • 200-299 - успешные коды (все ОК, запрос выполнен успешно).
    • 300-399 - коды перенаправления (например, URl был изменен).
    • 400-499 - клиентские ошибки (неверный запрос, нет доступа и т.д.).
    • 500-599 - серверные ошибки (сервер выключен или не может обработать запрос).
  20. Виды наследования. Проблема наследования.

  21. Сериализация и десериализация. Pickling и Unpickling. Сериализация (pickling - dump) представляет собой процесс преобразования структуры данных в последовательность байтов. Для этого в Python может быть использован модуль pickle. Десериализация - обратный процесс сериализации, при котором последовательность байтов превращается в структуру данных (unpickling - load). Для чего это нужно? Например, можно сохранить состояние обученной нейронной модели. Процесс обучения нейронной сети занимает значительно большее время, чем загрузка ранее обученной модели.

Здесь приведен перечень теоретических вопросов для собеседования на должность Junior Python разработчика.