Python вопросы с собеседований
24.7K subscribers
507 photos
14 videos
17 files
401 links
Вопросы с собеседований по Python

@workakkk - админ

@machinelearning_interview - вопросы с собесдований по Ml

@pro_python_code - Python

@data_analysis_ml - анализ данных на Python

@itchannels_telegram - 🔥 главное в ит

РКН: clck.ru/3FmrFd
Download Telegram
Что такое пустой класс и как он используется?

Пустой класс – класс, который не имеет реализацию каких-то методов или же свойств. При пустом классе используется ключевое слово pass для того, чтобы не выдавало ошибок.

Пример использования на картинке.

@python_job_interview
Освобождается ли вся память при выходе из Python?

Ответ:

Выход из Python освобождает все, кроме:

1. модулей с циклическими ссылками;

2. объектов, на которые ссылаются глобальные пространства имен;

3. части памяти, зарезервированной библиотекой C.

➡️ Как работает память в Python

@python_job_interview
✒️ Как передаются аргументы – значения или ссылка?

Ответ:

В Python аргументы передаются по ссылке, т. е. передается ссылка на реальный объект. Но есть два вида передачи объекта в аргументах.

По значению: Передается копия реального объекта. Изменение значения копии объекта не приведет к изменению значения исходного объекта.

По ссылке: Передается ссылка на реальный объект. Изменение значения нового объекта изменит значение исходного объекта.

Пример использования на картинке.

@python_job_interview
🔘 Реализуйте алгоритм сортировки слиянием (Merge Sort) на Python

Сортировка слиянием (Merge Sort) — один из самых известных алгоритмов сортировки. Если вы изучаете информатику, Merge Sort вместе с Quick Sort, вероятно, является первым эффективным алгоритмом сортировки общего назначения, о котором вы слышали. Также классический пример алгоритма «разделяй и властвуй» (divide-and-conquer).

Суть сортировки:

1 Сортируемый массив разбивается на две части примерно одинакового размера.

2 Каждая из получившихся частей сортируется отдельно, например, тем же самым алгоритмом.

3 Два упорядоченных массива половинного размера соединяются в один.

➡️ Подробнее


@python_job_interview
🧲 Напишите программу для проверки и возврата пар заданного массива A, суммарное значение которых равно заданному значению N.

Ответ на картинке

@python_job_interview
Где быстрее поиск: в словарях или списках?

Ответ
Поиск значения в списке занимает O(n) времени, потому что нужно пройти весь список.

Поиск ключа в словаре занимает O(1) времени, потому что это хэш-таблица.

Разница во времени может быть огромной, если значений много, поэтому для производительности обычно рекомендуют словари. Но у них есть другие ограничения, такие как необходимость уникальных ключей.

@python_job_interview
Назовите пример режимов обработки файлов с помощью Python?
Существуют следующие режимы:

Режим только для чтения (‘r’): открыть файл для чтения. Это режим по умолчанию.
Режим только для записи (‘w’): открыть файл для записи. Если файл содержит данные, они будут потеряны. Создается новый файл.
Режим чтения-записи (‘rw’): открыть файл для чтения, режим записи. Это режим обновления.
Режим добавления (‘a’): открыть для записи, добавить в конец файла, если файл существует.

@python_job_interview
Напишите код, который будет рассчитывать угол между часовой и минутной стрелкой в заданное время. Данная задача покажет логическое мышление кандидата, и как быстро он сможет придумать решение.

Ответ на картинке

@python_job_interview
Загрузка из «плохого» API большого количества данных и их синхронизация с табличкой в БД (например, Postgres). Считаем, что на входе мы скачиваем JSON-массив из N (>100k) объектов (dict) заданной структуры (primary key поле + некоторое количество строковых полей). Считаем, что нам надо раз в некоторое время запускать функцию, которая создаст записи, которые есть в JSON, но их нет в базе, а далее обновит строковые поля там, где что-то поменялось, и пометить удаленными записи, которых нет в JSON, но они все еще есть в базе.

Решение

Есть 3 простых решения. Первое — просто перебрать записи из JSON, выбирая из базы записи по одной по pk, но тогда мы получим N запросов в базу, что может приводить к неконтролируемой пиковой нагрузке. Второе — выбрать из базы полностью таблицу и сравнить 2 массива, что будет работать, скорее всего, быстрее других вариантов, но будет максимально неэффективно по памяти (упрощаем решение задачи выделением дополнительных ресурсов, но, опять же, есть вероятность, что из-за неожиданно большого объема данных памяти может не хватить и выполнение таска прервется). Компромиссный вариант по производительности, нагрузке на базу и памяти — проходить циклом по JSON (или записям базы, но там есть нюансы) бачами по 100-1000 шт., накапливая обработанные id. Это сократит количество запросов на 2-3 порядка, не потребует загрузки в память всех текущих данных, но при этом будет всё ещё достаточно быстро. Также тут можно обсудить варианты реализации чисто средствами базы (временные таблицы, bulk upsert-ы и т.д.)

@python_job_interview
Что такое итераторы/генераторы/генераторные выражения, чем они отличаются и когда и как все это нужно использовать.

Ответ
Здесь важно, чтобы кандидат понимал различие и мог с той или иной степенью погружения рассказать про эти различия. Если кратко, то итератор в Python – это любой объект, который использует метод next() для получения следующего значения последовательности. Генератор – функция, которая производит или выдает последовательность значений с использованием метода yield. Концептуально, итератор — это механизм поэлементного обхода данных, а генератор позволяет отложено создавать результат при итерации. Генератор может создавать результат на основе какого-то алгоритма или брать элементы из источника данных (коллекция, файлы, сетевое подключения и др.) и изменять их.

Подробности доступны в очень большом количестве статей с той или иной степенью погружения в детали, например, здесь.
#junior

@python_job_interview
Что такое абстрактная фабрика, как ее реализовать и зачем ее применяют?

Ответ

Абстрактная фабрика — порождающий шаблон проектирования, предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.

Допустим у нас есть 2 операционные системы Mac Os и Linux, нам необходимо реализовать произвольное окно с кнопкой или кнопками в каждой из этих операционных систем. Естественно окна и кнопки в MacOs и linux выглядят по разному, так сказать имеют разные стили оформления.

Наша задача состоит в том, что бы создать универсальный интерфейс который будет создавать окно с кнопкой в не зависимости от того на какой операционной системе запущенна программа.


Т.е. функции которая будет конструировать окно с кнопкой, будет работать вне зависимости от того какое окно мы захотим создать

Для начала опишем класс абстрактной фабрики картинка1.

Обратите внимание на строки return cls.Window(name) и return cls.Button(name), как видите в обоих случаях мы возвращаем некий класс(cls) у которого есть подкласс Window\Button, но в настоящий момент мы не описали ни класс Window, ни класс Button, давайте это сделаем.

➡️ Читать дальше

@python_job_interview
Что такое цикломатическая сложность ? Какие бывают метрики для измерения сложности кода ?

Ответ

Цикломатическая сложность — это мера количества независимых путей кода в вашем приложении. Путь — это последовательность операторов, которой интерпретатор может следовать, чтобы добраться до конца приложения.

Один из способов думать о цикломатической сложности и путях кода — это представить, что ваш код в виде железнодорожной сети.

Для поездки вам может понадобиться смена поезда, чтобы добраться до пункта назначения. Железнодорожная система метрополитена Лиссабона в Португалии проста и удобна для навигации. Цикломатическая сложность любой поездки равна количеству линий, по которым вам нужно пройти.

Метрики для измерения сложности
Вот некоторые метрики сложности для языков программирования. Они применимы ко многим языкам, а не только к Python.

Количество строк кода
LOC ( Lines of Code), или Количество строк, является самой грубой мерой сложности. Это спорный вопрос , есть ли прямая связь между количеством строк кода и сложностью приложения, но косвенная корреляция очевидна. В конце концов, программа с 5 строками, вероятно, проще, чем программа с 5 миллионами.

При просмотре метрик Python мы стараемся игнорировать пустые строки и строки, содержащие комментарии.

Количество строк кода можно подсчитать с помощью команды wc в Linux и Mac OS, где file.py — это имя файла, который вы хотите измерить:

$ wc -l file.py
Если вы хотите подсчитать строки во всех файлах в папке путем рекурсивного поиска в файлах *.py, вы можете объединить wc с командой find:

$ find . -name \*.py | xargs wc -l

В ответе вы увидите общее количество строк.

Почему строки кода используются для количественной оценки объема кода в вашем приложении? Предполагается, что строка кода примерно соответствует одной операцией.

В Python рекомендуется размещать по одной инструкции в каждой строке.

➡️ Читать дальше

@python_job_interview
Зачем нужен __new__ в Python и каково его практическое применение?

Ответ

Когда вы создаете экземпляр класса, Python сначала вызывает метод __new() для создания объекта, а затем вызывает метод init() __для инициализации атрибутов объекта.

__new() — это статический метод класса объекта. Он имеет следующую сигнатуру:
object.new(class, *args, **kwargs)__

Первый аргумент метода new — это класс нового объекта, который вы хотите создать. Параметры *args и **kwargs должны совпадать с параметрами init() класса. Метод new() также их использует.

Чтобы создать объект класса, нужно вызывать метод super().new().

Практическое применение new

Как правило, init() используется для инициализации вновь созданного объекта, а new() для управления способом создания объекта. Мы также можем использовать new() для инициализации атрибутов объекта, но по логике это должно быть внутри init().

Однако одним из частых практических применений new() является ограничение количества объектов, созданных из класса.

Примеры частных случаев использования new

Создание одноэлементного шаблона (хотя это не единственный способ).
Динамическое расширение классов из внешних модулей без фактического редактирования исходного кода.
Настройка классов в метаклассе (аналогично использованию call)
Расширение неизменяемого класса datetime.datetime. Это нужно, чтобы вернуть текущее время, если он создается без аргументов, и результат вызова strptime для аргумента, если он вызывается с одним строковым аргументом.

@python_job_interview
Расскажите про асинхронный режим в сравнении с многопоточностью на Python?

Ответ

Для асинхронного программирования в Python помимо зеленых потоков, сопрограмм и обратных вызовов используется мощная библиотека Asyncio. Библиотека доступна для использования с версии Python 3.5. Удобно и то, что она полностью встроена в ядро.

Асинхронный режим в сравнении с многопоточностью имеет ряд преимуществ:

- Функции асинхронности намного легче потоков. Это значит, что сотни и тысячи асинхронных операций, выполняемых одновременно, будут расходовать гораздо меньше ресурсов, чем сотни и тысячи потоков.

- По сравнению с потоками асинхронными операциями намного легче управлять. Например, их можно отменять, задействовав объект Task — asyncio.create_task().
В цикле асинхронных событий задачи выполняются в одном потоке, их проще понимать, контролировать и отслеживать.

- Фактически асинхронность идет рука об руку с многопроцессорностью в Python. Есть возможность использовать asyncio.run_in_executor() для задач, которые интенсивно используют центральный процессор. Также асинхронность решает проблемы потоков:

- Библиотека Asyncio осуществляет переключение контекста на уровне программы, а не процессора. Используется цикл событий.

- Отсутствие состояние гонки. Поскольку с Asyncio переключение контекста осуществляется в заранее созданных точках, код не испытывает проблему гонки.

- Запускается одна сопрограмма, которая переключается только в заданных вами точках.

- Гораздо меньшее ресурсное голодание. Конечно, в Asyncio имеется пул потоков, который может влиять на расходование ресурсов (запуск большого количества процессов). Но тем не менее запуск сопрограмм в одном потоке задействует гораздо меньше памяти на выполнение процессов.

Взаимная блокировка. Отсутствие гонки потоков практически сводит к нулю различного рода блокировки.
Есть и небольшие недостатки использования асинхронной библиотеки Asyncio. Во избежание блокировки цикла событий и временных потерь на выполнении асинхронных функций весь код также должен быть асинхронным.

Тем не менее мы можем наблюдать динамику увеличения количества асинхронных библиотек и специального программного обеспечения, предоставляющего асинхронные неблокирующие версии баз данных, сетевых протоколов. Например, репозиторий aio-libs — набор библиотек, созданный на основе Asyncio, в котором представлена асинхронная библиотека aiohttp для веб-доступа. Или же в каталоге пакетов Python также много библиотек с async.

Даже такие монстры как Facebook, Twitter, фреймворк React Native и база данных RocksDB используют асинхронность.

@python_job_interview
Почему в Python-сообществе называют способ передачи аргументов передачей через присваивание, а не передачей ссылок по значению?

Чем принципиально имя переменной в Python отличается от ссылки на объект в Java? Поведение не выглядит даже немного отличающимся

Ответ
«Переменная» в Python — это не традиционная переменная. Вместо этого это привязка к объекту. По сути, указатель, но на объект, а не на ячейку памяти. Со списком это легко увидеть .

Вот что происходит под капотом, более или менее:

Вы создаете объект списка со значением [1, 2, 3, 4]. Мы назовем этот идентификатор объекта 1. Затем вы привяжете имя «list_one» к идентификатору объекта 1. Вы говорите ему привязать «list_two» к тому же объекту, к которому привязан «list_one». На данный момент они оба привязаны к идентификатору объекта 1. Вы изменяете объект с идентификатором 1. Поскольку список является изменяемым (mutable), содержимое может измениться, и оба имени могут оставаться привязанными к идентификатору 1. Поскольку и «list_one», и «list_two» связаны с идентификатором объекта 1 , печать любого из них возвращает [1, 2, 3, 4, 5].

Что делать с такими вещами, как целые числа и строки? Почему они не ведут себя так же?

Происходит то же самое, но тип объекта имеет значение Рисунок 2.

Вы создаете целочисленный объект со значением 1. Мы назовем этот объект с идентификатором 1. Затем вы привяжете имя «int_one» к объекту с идентификатором 1. Вы говорите ему привязать «int_two» к тому же объекту, на который указывает «int_one».

Они оба связаны с идентификатором объекта 1. Вы пытаетесь изменить идентификатор объекта 1, но он неизменяем (immutable), поэтому вы не можете изменить содержимое. Из-за этого он просматривает значение объекта с идентификатором 1, добавляет к нему 10, чтобы получить 11, и создает новый целочисленный объект (идентификатор 2) со значением 11. Затем он повторно привязывает «int_two» к объекту с идентификатором 2, но оставляет «int_one» в покое. Поскольку «int_one» и «int_two» теперь привязаны к разным объектам, их печать даст разные результаты.Если вы снова измените значение «int_two», будет создан третий объект с новым значением, а второй объект останется в памяти без привязок. Не беспокойтесь о потраченной впустую памяти - нужна сборка мусора.

===========================================

В Python аргументы передаются путем присваивания.(official guide)

Фактические параметры (аргументы) вызова функции вводятся в локальную таблицу символов вызываемой функции при ее вызове; таким образом, аргументы передаются с использованием вызова по значению, «где значение всегда является ссылкой на объект, а не значением объекта», там же сноска добавляет:

На самом деле, «вызов по ссылке на объект» был бы лучшим описанием, поскольку, если передается изменяемый (mutable) объект, вызывающая сторона увидит любые изменения, внесенные в нее вызываемой стороной (элементы, вставленные в список).

@python_job_interview
✒️ Собеседование Middle Python Engineer

00:00 - Опыт Разработки
06:08 - План Интервью
07:00 - _slots__
07:41 - match/case
08:24 - _call__
08:55 - Конструктор класса
10:10 - hash/hash table
11:12 - Доступ к элементам словаря
11:56 - Генераторы и итераторы
13:57 - Контекстные менеджеры
16:05 - Инкапсуляция
20:00 - Django vs DRF
22:07 - SerializerMethodField
22:40 - to_internal_value/to_representation
25:05 - Какой способ построения api с помощью DRF более удобный
25:57 - Миксины
27:34 - Django ORM
30:26 - @sync_to_async/@async_to_sync
31:23 - n+1
32:25 - django-debug-toolbar
33:27 - Когда prefetch_related увеличивает количество запросов
35:40 - Когда queryset делает запрос
38:01 - Онлайн кодинг
53:40 - БД
01:02:40 - Асинхронность, многопоточность, многопроцессорность
01:07:26 - Фидбек

https://www.youtube.com/watch?v=nbSbjbAwg9M

@python_job_interview
Расскажите о ПО позволяющее создавать виртуальное окружение в Python.

Ответ

Программное обеспечение, которое позволяет создавать виртуальные окружения в Python можно разделить на те, что входят в стандартную библиотеку Python и не входят в нее. Сделаем краткий обзор доступных инструментов (хороший пост на эту тем есть на stackoverflow).

Начнем с инструментов, которые входят в PyPI. Если кто не знает PyPI – это Python Package Index (PyPI) – репозиторий пакетов Python, доступный для любого разработчика и пользователя Python ().

virtualenv

Это, наверное, одни из самых популярных инструментов, позволяющих создавать виртуальные окружения. Он прост в установке и использовании. В сети довольно много руководств по virtualenv, самые интересные, на наш взгляд, будут собраны в конце урока в разделе “Полезные ссылки”. В общем, этот инструмент нужно обязательно освоить, как минимум, потому что описание развертывания и использования многих систем, созданных с использованием Python, включает в себя процесс создания виртуального окружения с помощью virtualenv.

pyenv

Инструмент для изоляции версий Python. Чаще всего применяется, когда на одной машине вам нужно иметь несколько версий интерпретатора для тестирования на них разрабатываемого вами ПО.

virtualenvwrapper

Virtualenvwrapper – это обертка для virtualenv позволяющая хранить все изолированные окружения в одном месте, создавать их, копировать и удалять. Предоставляет удобный способ переключения между окружениями и возможность расширять функционал за счет plug-in’ов.

Существуют ещё инструменты и plug-in’ы, выполняющие работу по изоляции частей системы Python, но мы их не будем рассматривать.

Инструменты, входящие в стандартную библиотеку Python.

venv

Этот модуль появился в Python3 и не может быть использован для решения задачи изоляции в Python2. По своему функционалу очень похож на virtualenv. Если вы работаете с третьим Python, то можете смело использовать данный инструмент.

➡️ Подробнее

@python_job_interview
Интервью Junior Python разработчик. Лайф кодинг

https://www.youtube.com/watch?v=c4nysYAufF0

@python_job_interview
С помощью чего можно получить логический xor двух переменных в Python?

Ответ

В Пайтоне есть оператор побитового XOR, который также отлично работает с логическими значениями, но его поведение легко повторить.
Исключающее "или" ведёт себя как обычное "или" за одним исключением — два True на входе даёт результат False.

Можно так и поступить — возвращать False в этом особом случае, во всех остальных использовать or.

Однако, если мы внимательно посмотрим на результаты, то окажется, что нам нужно True если значения не равны. Поэтому реализацию XOR можно записать проще (картинка 2).


@python_job_interview