20 вопросов и ответов из интервью на позицию Python-разработчика

1
38154
Добавить в избранное

Статья нацелена на помощь в подготовке к собеседованию на должность Python-разработчика. Поможет в подготовке как новичкам, так и профессионалам!

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

После прочтения этих сложных Python-вопросов, вы легко сможете задавать объектные типы и множественные типы в Python.

Какие есть способы написания функции, которая  использует передачу параметров по ссылке?

Аргументы в Python передаются по значению. Значение создается путем присваивания, результатом которого является объект, который не имеет никаких связей между именем аргумента на входе и выходе. Процедура написания функции, которая использует передачу параметров по ссылке, включает в себя:

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

  • Использование глобальных переменных позволяет обратится к функции по ссылке, однако такой метод не является безопасным по отношению к любой функции;
  • Применение изменяемых объектов (обычно, это классы, состоящие их изменяемых объектов), необходимо для передачи параметров по ссылке.

Какие команды используются для копирования объектов в Python?

Команда, используемая для копирования объектов в Python, включает в себя:

  • Функцию copy(): Данная операция копирует объект из исходного места в запрашиваемое. Функция возвращает поверхностную копию передаваемого аргумента;
  • deepcopy(): Эта операция также копирует файл из исходного места в запрашиваемое. Отличие в том, что данная операция возвращает полную копию передаваемого аргумента.
Словарь состоит из всех объектов и метода copy(), который используется, как показано ниже:

Оператор присваивания не копирует объекты, но он создает связь между искомым объектом и объектом, который используется изменяемыми элементами. Целью копирования, как ни странно, является хранение копии объекта. Для этого метод copy() использует соответствующие модули, которые дают возможность делать полное и поверхностное копирование.

В чем заключается разница между полным и поверхностным копированием?

  1. Поверхностное копирование используется в случаях, когда создается экземпляр нового типа и необходимо значение, хранящееся в этом экземпляре, копировать в новый экземпляр. В то время как полное копирование используется для хранения значений, которые уже были копированы.
  2. Поверхностное копирование используется для копирования ссылок на объекты, механизм копирования аналогичен копированию значения объекта. Ссылки на исходные объекты и изменения, которые были совершены над ними любым членом класса, влияют на исходную копию. В то время как полное копирование не копирует ссылки на объекты. Полное копирование создает ссылку на объект и новый объект, на который ссылаются другие объекты, сохраняется. Изменения с исходным объектом никак не влияют на другие копии, использующие этот объект.
  3. При использовании поверхностного копирования, программа выполняется быстрее, но это также зависит и от размера, используемых (копируемых) данных. В то время как при полном копировании программа работает медленнее из-за того, что создается конкретная копия каждого вызванного объекта.

Напишите программу для того, чтобы узнать имя объекта в Python.

Объекты не имеют имен, поэтому нет способа узнать имя объекта. Операция присвоения используется для связывания имени и значения, которое включает в себя имя объекта, к которому должно быть привязано значение. Если к этому значению можно обратиться, то результатом присвоения будет true, то следующая программа может использоваться для поиска ссылочного имени объекта.

Класс состоит из имени, а имена вызываются с помощью переменной B, это создает экземпляр класса try. Суть метода заключается в том, чтобы среди всех областей видимости определить, что объект существует, и уже после этого вывести его имя.

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

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

Тернарный оператор имеет самый низкий приоритет, используемый для принятия решения, которое основано на значении условия, будет оно истинно или ложно. В нашем примере, выражение “если x<y, иначе y” будет вычисляться так: в случае, если x будет меньше чем y, то возвращаемым значением будет big=x, в случае если это не так, возвращаемым значением будет big=y.

Как строка может быть преобразована в число?

Для того чтобы преобразовать строку в число можно использовать встроенные функции языка Python, например, с помощью int() конструктора. Таким способом можно преобразовывать данные типа: int (‘1’) == 1.

Функция float() также может быть использована для того, чтобы показать число в формате float(‘1’)=1.

По умолчанию, все числа представлены в виде десятичных, это означает, что если вы попробуете выполнить преобразование подобным образом: int(‘0x1’), то вы получите сообщение об ошибке «ValueError». Связано это с тем, что функции int(string,base)  входные параметры предназначены для преобразования строки в число, процесс преобразования выглядит примерно так: int(‘0x1’,16)==16. Если параметр (base) будет определен как 0, то это показывает, что число будет восьмеричным, а если как 0x, то это будет означать, что число шестнадцатеричное.

Также существует функция eval(), которая может быть использована для преобразования строки в число, но работает она немного медленнее и порождает множество проблем с безопасностью, например, __import__(‘os’).system(«rm -rf$HOME»)  — использование этого приведет к удалению домашней директории системы.

Какова функция/предназначение отрицательного индекса?

Любые последовательности в Python проиндексированы, и они состоят как из положительных индексов, так и из отрицательных. Индексация положительных чисел начинается с ‘0’, то есть первый элемент ‘0’, а второй ‘1’ и так далее. Индексация отрицательных чисел начинается с ‘-1’, этот индекс обозначает последний элемент в последовательности, а ‘-2’ обозначает предпоследний элемент, и далее индексация идет вперед по аналогии с положительными числами. Отрицательные индексы используются для того, чтобы удалить лишние пробелы из строки, а также дать строке возможность пропускать последний символ, который представлен, как: S[:-1]. Также отрицательные индексы используются для того, чтобы показать, что индексация в строке идет в правильном порядке.

Напишите программы, которая будет проверять принадлежность объекта классу или подклассу.

Существует встроенный метод для определения принадлежности объекта классу, который состоят из множества классов, представляющих кортеж в таблице записей вместо отдельных классов. Представленный метод в кратце выглядит так: isinstance(obj,cls), а более детально так:

isinstance(obj, (class1, class2, …)), этот метода как раз и используется для проверки принадлежности объекта одному из классов. Встроенные типа также могут иметь несколько подобных данной функции форматов, например,  isinstance(obj, str) или isinstance(obj, (int, long, float, complex)).

Не рекомендуется использовать данный класс вместо пользовательских классов, которые позволяют легко объектно-ориентированному стилю определять поведение класса объекта. Так как они выполняют разные задачи, основанные на одном классе. Функция в каждом классе реализована по-разному. Для определения принаддежности объекта определенному классу моно использовать следующую программу:

Объясните процесс делегирования в Python

Делегирование – это объектно-ориентированный метод, также называемый паттерном проектирования. Давайте представим, что у вас есть объект x, и вы хотите изменить поведение только одного из его методов. Вы можете создать новый класс, в котором этот метод будет переопределен, но вы заинтересованы в изменении и делегировании всех остальных методов, соответствующему методу x. В примере ниже, показан класс, охватывающий поведение файла и преобразующий данные из нижнего в верхний регистр:

Метод write(), который располагается в классе верхнего регистра, используется для преобразования строки из нижнего в верхний регистр до того как будут вызваны другие методы. Собственно сама делегация осуществляется за счет использования объекта self._out.

 Для чего нужен “self” в функциях?

“Self” – это переменная, обозначающая принадлежность объекта самому себе. В большинстве объектно-ориентированных языков, данная переменная передается в качестве скрытого параметра методов, которые определяются объектами. Но в Python это определение и передача осуществляется явно. В первом аргументе, который создается в экземпляре класса A, происходит автоматическая передача параметров метода. Происходит обращение к отдельным экземплярам переменной для каждого отдельного объекта. Это первый аргумент, который используется в экземпляре класса, а метод «self» определен явно для всех используемых и существующих методов. Название переменных происходит вот по такому образцу: “self.xxx”.

Как в методе можно явно определить “self”?

“Self” – это ссылочная переменная и атрибут экземпляра, который используется вместо локальной переменной внутри класса. Функция или переменная self, такая как self.x или self.meth(), могут использоваться в том случае, если класс неизвестен. У такого класса нет переменных, объявленных как локальные. У него отсутствует какой-либо синтаксис, но в нем можно производить явную передачу ссылки или вызвать метод, который используется этим классом. Использование writebaseclass.methodname(self, <argument list>) показывает, что метод _init_()  может быть расширен до базовых методов класса. Это также решает синтаксическую проблему, которая возникала между оператором присваивания и локальными переменными. Такой подход указывает интерпретатору, когда будут использоваться переменные экземпляра класса, а когда локальные переменные. Явное использование переменной self.var решает вышеупомянутую проблему.

Почему метод join() чаще используется при работе со строками, а не со списками и кортежами?

Для обеспечения полного функционала всех методов и функций в string используется string модуль. Представленный string модуль использует метод join():

Используемая переменная типа string дает возможность фиксированным строковым константам использовать имена, которые нужны для связывания строк между собой. Метод join() – это строковый метод, который предоставляет разделительную строку, чтобы можно было использовать функцию над последовательностью строки, то есть для того, чтобы можно было вставлять необходимую строку в нужное место. Метод может принимать любое количество аргументов, которые соответствуют некоторым требованиям, которые устанавливаются для объектов последовательности, а они уже определяются внутри своего класса. Join() используется в работе string модуля для объединения символов строки в одну строку, как это показано в программе ниже. Пример выглядит так:

Объясните процесс работы компилятора и ссылок в Python

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

Для этого необходимо предпринять следующие шаги:
  • Создать файл с любым именем на любом языке, который поддерживается компилятором вашей операционной системы. Например, c;
  • Поместить этот файл в директорию «Modules» используемого дистрибутива;
  • Добавить строку в файл Setup.local, который располагается в директории «Modules»;
  • Запустите файл, используя spam comp.o;
  • После удачного запуска необходимо перестроить интерпретатор с помощью команды make в каталоге верхнего уровня;
  • При изменении файла запустите rebuildMakefile с помощью подобной команды  ‘make Makefile’.

Объясните процесс извлечения значений из объекта в Python.

Для того извлечения значения необходимо чтобы был известен тип объекта, и только после этого можно будет получить его значения.

Значения будут извлекаться следующим образом:
  • Если объект является кортежем, то метод PyTuple_Size() возвращает количество значений, а метод PyTuple_GetItem() возвращает элемент данных, который хранится по определённому индексу;
  • Если объект является списком, то для него есть метод PyListSize(), который полностью аналогичен методу для кортежей PyTuple_GetItem(), который также возвращает элемент данных, который также хранится по определённому индексу;
  • Строки используют метод PyString_Size() для возврата количества значений и метод PyString_AsString(), который возвращает указатель на их значения;
  • Для проверки типа объекта и извлечения значений можно использовать следующие методы: PyString_Check(), PyTuple_Check(), PyList_Check(), и т.д.

Опишите свою последовательность действий по созданию скрипта, выполняемого на Unix.

Для создания скрипта, который будет выполняться на Unix, необходимо выполнить следующие шаги:

  • Вначале создайте файл скрипта и напишите код, который хотите, чтобы выполнялся в Unix;
  • Делаем из этого файла выполняемый файл, путем установки специального режима с помощью добавления к первой строке #! данную строку считывает Python-интерпретатор;
  • Устанавливаем необходимые полномочия файлу, используя команду chmod +x file. Файл сперва будет считывать самую главную строчку:
    #!/usr/local/bin/python
  • Эта строка указывает путь, который передается интерпретатору Python, и он не зависит от программной среды;
  • Python-интерпретатор сможет выполнить файл только по полному пути к нему. Ниже приведен пример:

Как мутация глобального значения используется в потокобезопасности?

Глобальная блокировка интерпретатора используется для того, чтобы по очереди запускать потоки, то есть не все сразу. Работает это все исключительно внутри программы и используется для того чтобы функция выполнялась на всех виртуальных машинах. Python позволяет переключаться между потоками для более высокой производительности, за счет использования инструкций байт-кода, который, в свою очередь, используется для обеспечения платформенной независимости. Метод sys.setcheckinterval() предназначен для переключения во время реализации программы и инструкции. Это дает понимание того, как работает самый нижний уровень архитектуры и то, что можно использовать байт-код в вашей реализации, чтобы сделать ее более платформенно независимой. За счет свойства атомарности можно использовать общие переменные в качестве встроенных типов данных.

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

Модуль, предназначенный для чтения и записи двоичных данных, известен более как struct. Этот модуль предоставляет функционал, в котором половина всего состоит из классов string. Данные классы содержат двоичные данные, которые представлены в виде чисел, которые преобразованы в python-объекты для дальнейшего использования и наоборот. Программа, которая может считывать и записывать двоичные данные, представлена ниже:

Знак ‘>’ используется для того, чтобы показать формат строки, что позволяет преобразовывать строку в «перевернутую» (запись строки в обратном порядке) форму данных. Для однородности списка данных можно воспользоваться модулем для работы с массивами, что даст вам возможность более структурированно хранить свои данные.

Опишите процесс запуска под-процесса с помощью двунаправленных каналов.

Модуль popen2() используется для запуска под-процессов, но из-за сложности таких процессов, как: блокировка потоков, которая блокирует процесс, что приводит к ожиданию выходных данных от «потомка», а «потомок», в свою очередь, ждет данные на вход. Дэдлоки возникают из-за плохой синхронизации «родителя» и «потомка», что приводит к ожиданию обоих на получение доступа к процессу, чтобы предоставить ресурсы друг другу. Использование метода popen3() дает возможность чтения таких потоков, как: stdout и stderr для того, чтобы занимать появившееся в буфере место, и в те моменты, когда чтение не происходит (read() не срабатывает), распределять ресурсы. Метод popen2() предотвращает дэдлоки, за счет такиех методов, как: wait() и waitpid(), который сперва завершает процесс, и в момент, когда приходит запрос, то он передается на ожидающий процесс.

Ниже приведен пример программы, которая создает и запускает процесс:

Какие существуют, различные методы генерации рандомных чисел?

Модуль random – это стандартный модуль, который используется для генерации рандомных чисел.

Этот метод определяется так:

Конструкция метода random.random() числа с плавающей точкой в диапазоне [0, 1). Функция генерирует рандомные числа с плавающей точкой. Методы, которые используются с random-классом являются связанными методами скрытых экземпляров. Экземпляры класса Random можно использовать в многопоточных программах, в которых для каждого потока создается отдельный экземпляр. Далее представлены другие генераторы рандомных чисел:

  • randrange(a, b): Данный метод выбирает и определяет числа в диапазоне [a, b). Он возвращает рандомные элементы из заданной области. Метод не создает объект диапазона;
  • uniform(a, b): Метод выбирает и определяет числа с плавающей точкой в диапазоне [a, b). Возвращает число с плавающей точкой из заданной области;
  • normalvariate(mean, sdev): Используется для нормального распределения, где mean – это мю, а sdev – это сигма, которые используются при нормальном распределении;
  • Класс Random используется для создания экземпляра, который независимые генераторы случайных чисел.

Приведите пример паттерна singleton в Python.

Singleton – это паттерн, предназначенный для того, чтобы ограничивать количество экземпляров, которые могут быть использованы одним классом. Также этот паттерн позволяет расшаривать один и тот же объект среди многих других частей кода. Это позволяет использовать глобальные переменные, поскольку фактически используемые данные скрыты интерфейсом класса singleton. Интерфейс класса singleton имеет только один публичный член класса и один метод этого класса Handle. Приватные конструкторы не используются для создания объектов, которые используются вне класса. Процесс ждет статического члена функции для того, чтобы создать новый экземпляр и вернуть singleton-объект:

Ниже приведен пример кода, который обращается к singleton объекту:

Ссылка на оригинальную статью
Перевод: Александр Давыдов

Другие статьи по теме

Трюки и советы по Python, которые облегчат вашу жизнь

Мобильная разработка на Python: обзор двух фреймворков

Интересуетесь программированием на Python?

Подпишитесь на нашу рассылку, чтобы получать больше интересных материалов:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




Добавить комментарий