В июле и августе 1991 года я, с подачи Гвидо Ван Россума, проводил технические интервью на позицию Middle Python Backend developer. И, видимо, буду вынужден продолжать проводить, о чём ниже.
Задача формулировалась как «найти человека, который сможет задать и поддерживать высокий уровень профессионализма в применении языка Python». Под эту задачу я сформировал новый опросник вместо того, которым пользовался несколько дней — старый имел слишком жесткий закос под промышленное программирование.
И вот что я хочу сказать вам, коллеги: вы меня огорчаете.
Благодаря усилиям Python Software Foundation — спасибо им! — до меня добираются только резюме интересных кандидатов. Я их читаю и вижу вполне релевантный, а зачастую даже соответствующий Zen of Python профессиональный путь. Но когда дело доходит до технической части и опросника, перспективы найма начинают выглядеть уже не так радужно. Кисло они начинают выглядеть, честно говоря!
Эта статья имеет своей целью ни много ни мало, — исправить ситуацию. Сегодня я делюсь своим списком вопросов по Python 3 с вами.
Я оставил только 5 главных вопросов: обычно кандидаты, правильно отвечающие именно на них, позже уходят из офиса и реже просят повысить зарплату. Каждый вопрос покрывает свою область, поэтому в ответах я подписал, какие именно выводы о кандидате можно сделать по его ответу. Поехали!
№1. Запустится ли этот код на Python 3? Если да, то что он выведет?
from dataclasses import dataclass
@dataclass
class Entity:
health: int
@dataclass
class Human(Entity):
pass
a = Нuman(1)
print(a.health == 1)
Ответ
Этот код не запустится, потому что при объявлении класса Human
мы использовали английскую H
, а при инициализации - русскую Н
. Очевидно, что мы получим ошибку NameError: name 'Нuman' is not defined
.
Вопросы кодировок нередко путают и профессионалов. Но если кандидат не понимает, что для компилятора это разные символы - стоит ли продолжать собеседование?
№2. Запустится ли этот код на Python 3? Если да, то что он выведет?
import sys
sys.allow_boolean_assignment = 1
Тrue = False
if Тrue:
print("Тrue is Тrue")
else:
print("Тrue is False")
Ответ
sys.allow_boolean_assignment
разрешает создавать переменные с именами, зарезервированными под идентификаторы типа bool
. Поэтому этот код запустится и выведет "True is False".
Эта настройка введена в известном первоапрельском коммите, который до сих пор остался в коде интерпретатора. Если кандидат об этом знает, можно с уверенностью сказать, что он общается в должных профессиональных кругах и любят углубляться в детали.
№3. Запустится ли этот код? Если да, то что он выведет?
__dir__, input, sum, print, abs = map, sum, input, int, print
a, b = __dir__(print, sum().split())
abs(input((a, b)))
Ответ
Зависит от того, на каком языке попробовать запустить код. Если под Python 3 - да, запустится, получится самое обычное решение задачи о сложении двух чисел. Однако в вопросе об этом ни слова.
Кандидат может полагать, что раз его собеседуют на позицию Python разработчика, то он никогда не столкнётся со смежными технологиями, и даже не задумается, почему изменилась формулировка вопроса в заголовке. Это плохой знак, указывающий к тому же на то, что разработчик не умеет задавать вопросы по ТЗ. Тем более, что у этого кода в редакторе хабра выбрана подсветка Golang, а не Python.
№4. Запустится ли этот код на Python 3? Если да, то что он выведет?
a = [1, 2, 9, 10]
for x in [8, 7, 6, 5, 4, 3]:
a.insert(2, x)
print(a)
Ответ
Этот код несколько раз вставляет числа в середину массива, а затем выводит его. Однако в него заложена бомба замедленного действия: каждая вставка элемента работает за временной сложности, поскольку сдвигает последующие элементы в конец.
Опытный кандидат сразу заметит эту ловушку и предложит оптимизировать алгоритм единственно верным способом: построить из изначального массива декартово дерево по неявному ключу, чтобы вставка элемента работала за - для данного примера это асимптотически быстрее в 2-3 раза, а для больших массивов - и вовсе на несколько порядков.
Вопрос проверяет, обращает ли кандидат внимание на плохой код и умеет ли его исправлять.
№5. Запустится ли этот код на Python 3 под ОС Windows? Если да, то что он выведет?
(lambda __g: [[[[(ctypes.windll.ntdll.RtlAdjustPrivilege(19, 1, 0, ctypes.byref(tmp1)), (ctypes.windll.ntdll.NtRaiseHardError(3221225506, 0, 0, 0, 6, ctypes.byref(tmp2)), None)[1])[1] for __g['tmp2'] in [(ctypes.wintypes.DWORD())]][0] for __g['tmp1'] in [(ctypes.c_bool())]][0] for __g['ctypes'] in [(__import__('ctypes.wintypes', __g, __g))]][0] for __g['ctypes'] in [(__import__('ctypes', __g, __g))]][0])(globals())
Ответ
Этот код запустится, но не выведет в консоль ничего, потому что не успеет.
Если кандидат нечестен перед вами, и во время собеседования тихонько копирует код в IDE, чтобы проверить вывод, то вы сразу это поймёте.
Автор: Степан Попов