Python: вопросы на собеседовании. Часть III. Senior

Мы уже рассмотрели списки вопросов с собеседований для программистов уровня Junior и Middle. Переходим к самым сложным вопросам, для сеньоров. Все вопросы — из коллекции, собранной на основе реальных интервью.

Все части нашей «трилогии»:

  1. Python: вопросы собеседования. Часть I. Junior
  2. Python: вопросы собеседования. Часть II. Middle
  3. Python: вопросы собеседования. Часть III. Senior

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

Вопросы

  1. Возможно ли использовать конструкцию True = False?
  2. Когда в конструкции try...except...else может быть исполнен блок кода else ?
  3. Что такое обезьяний патч (Monkey patch)? Как его можно использовать в Python? Приведите примеры. А вообще это хорошая идея?
  4. Как dict и set реализованы внутри Python?
  5. Что такое порядок разрешения методов (Method Resolution Order — MRO) в Python? Как он работает?
  6. В Python есть оператор присваивания?
  7. Что такое дескрипторы? Есть ли разница между дескриптором и декоратором?
  8. Как в Python передаются аргументы, по значению или по ссылке?
  9. Какие инструменты помогают вам находить червоточину в коде или производить статический анализ кода? Что еще вы умеете делать, чтобы код был читаемым и поддерживаемым?
  10. Почему, когда Python завершает работу, освобождается не вся память?
  11. Возможно ли, чтобы поток производителя, читающий из сети, и поток потребителя, пишущий в файл, работали одновременно? И как насчет GIL (Global Interpreter Lock)?
  12. Что такое GIL? И почему GIL до сих пор существует?
  13. Что из себя представляют процессы компиляции и линковки в Python?
  14. Как создавать пакеты в Python? Какие пакетные менеджеры вы знаете?
  15. Как работать с переходными зависимостями?
  16. Что такое wheel и eggs в Python? Какая между ними разница?
  17. Как распространять код на Python?
  18. Как упаковывать бинарные зависимости?
  19. Что такое пакетный менеджер? Каким вы пользуетесь и почему?
  20. Что такое Cython?
  21. Как ускорить уже написанный код Python?
  22. Как изолировать код Python? Что такое virtualenvs? Что такое docker?
  23. Python поддерживает парадигму функционального программирования? Обозначьте требования к коду, написанному в такой парадигме.
  24. Определите подводные камни и ограничения функционального кода.
  25. Объясните, как получить доступ к модулю, написанному на Python, из C. А наоборот?
  26. Что такое файлы с расширением .pth?
  27. Каковы преимущества массивов NumPy перед списками Python (в частности, вложенными списками)?
  28. Что такое CUDA?
  29. Что представляет из себя платформа Anaconda? Зачем она нужна?
  30. Что делает флаг PYTHONOPTIMIZE?

Вопросы с кодом

  1. Приведите примеры работы функций filter и reduce с итерируемым объектом.
  2. У вас есть функция, которая принимает другую функцию в качестве аргумента. Как проверить значение аргумента?
  3. Расскажите, как поменять порядок работы генератора.
  4. Вам нужно реализовать функцию, которая будет использовать статическую переменную (например, счетчик вызовов). Вы не можете писать никакого кода вне этой функции, к тому же у вас нет никакой информации о внешних переменных (вне вашей функции). Как это сделать?
  5. У вас есть функция, которая принимает аргумент, находящийся в заданных рамках [a, b]. Установите параметры реализации теста так, чтобы увеличить скорость тестирования. Варианты данного задания:
    • аргумент находится в списке [a, b];
    • a <= argument <= b;
    • a in range(a, b + 1);
  1. Какие методы и в каком порядке вызываются при выполнении данного выражения: print (A() + B()) ?
  2. Каким будет результат выполнения данной функции?
def Foo(): 
    yield 42;
    return 666
  1. Что будет в результате выполнения данного кода?
a = [[]]*3
a[1].append(1)
print(a)  # [[1], [1], [1]
  1. Расположите данные функции в порядке их быстродействия. Обоснуйте ответ.
def f1(lIn):
    l1 = sorted(lIn)
    l2 = [i for i in l1 if i<0.5]
    return [i*i for i in l2]
def f2(lIn):
    l1 = [i for i in lIn if i<0.5]
    l2 = sorted(l1)
    return [i*i for i in l2]
def f3(lIn):
    l1 = [i*i for i in lIn]
    l2 = sorted(l1)
    return [i for i in l1 if i<(0.5*0.5)]
  1. Напишите однострочный код для вычисления всех заглавных букв в файле. Ваш код должен работать, даже если файл слишком велик, чтобы целиком поместиться в памяти.
  2. Каким будет результат? Почему? И есть ли здесь наследование?
class C:
    pass
type (C ())
type (C)
  1. Какой результат мы получим, запустив следующий код?
big_num_1   = 1000
big_num_2   = 1000
small_num_1 = 1
small_num_2 = 1
big_num_1 is big_num_2
small_num_1 is small_num_2
  1. Как такое возможно?
_MangledGlobal__mangled = 23

class MangledGlobal:
     def test(self):
         return __mangled

>>> MangledGlobal().test()
23
  1. Какой будет результат?

print(_)

  1. Вы видите только следующий кусок кода. Что с ним не так? И для чего такой код нужен?
if __debug__:
    assert False, ("error")

Предыдущие статьи:
Python: вопросы собеседования. Часть I. Junior
Python: вопросы собеседования. Часть II. Middle