18 March 2014

Введение

Пару месяцев назад я сменил работу в московском офисе на удаленную работу в Toptal. Это был абсолютно новый для меня опыт, потому что мне еще не доводилось работать с американскими клиентами. Больше всего меня беспокоил языковой барьер, но по прошествии времени могу сказать, что навыки коммуникации быстро приобретаются при наличии практики и желания.

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

Что такое meta-классы в Питоне и зачем они нужны?

Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t.

- Tim Peters

Я, пожалуй, не буду копировать Интернеты и просто оставлю здесь несколько ссылок (потому что мне больно говорить об этом) :

  • Первым на помощь нам спешит Хабр: Метаклассы в Python
  • Хабровчане по своей старой привычке не указывают ссылки на оригиналы статьей. Вот она: All about the metaclasses in Python!
  • Очень хороша статья на PyPix: Metaprogramming in Python, она посвежее и лучше оформлена, а в конце есть множество ссылок на другие статьи по данной теме.
  • А началось все с вопроса на StackOverflow!

Да, и не путайте meta-классы в Питоне с классом Meta в Django

… как это сделал я!

Декораторы методов и классов в Python

Декораторы методов выступают в качестве “патчей”, который позволяют расширять поведение метода новыми возможностями. Звучит очень похоже на наследование, но технически все реализовано немного по другому.

Про декораторы классов информации мало, хотя они мало чем отличаются от декораторов методов и функций.

Вообще, про декораторы меня спрашивали практически везде, потому что это один из основных элементов языка, поэтому советую вам детально и ними разобраться.

Генераторы, итераторы и оператор yield

В питоне есть возможность итерировать объекты не загружая их все в память. Хорошим примером здесь являются функции близнецы range и xrange:

In [1]: range(3) 
Out[1]: [0, 1, 2]

In [2]: xrange(3)
Out[2]: xrange(3)

In [3]: a = xrange(3).__iter__()

In [4]: a.next()
Out[4]: 0

In [5]: a.next()
Out[5]: 1

In [6]: a.next()
Out[6]: 2

В данном случае range вернул нам список из чисел от 0 до 2, а xrange вернул нам генератор чисел от 0 до 2. Преимущество генераторов в том, что мы можем загружать объекты в память по мере необходимости, а не все сразу.

__slots__ для экономии память

В одном месте меня спросили про то, как можно сэкономить память при создании множества однотипных объектов. Как выяснилось, речь шла о переменной класса __slots__. Статей толковых про __slots__ я не встречал, потому что на практике это редко встречается.

Суть __slots__ можно продемонстрировать следующим примером:

    class Foo:
        __slots__ = ['x']
        def __init__(self, n):
            self.x = n
    
    y = Foo(1)
    print y.x  # prints "1"
    y.x = 2
    print y.x  # prints "2"
    y.z = 4    # Throws exception.
    print y.z

Этот массив жестко закрепляем список атрибутов экземпляра класса, и мы не можем добавить новые в процессе использования. Это позволяет интерпретатору оптимизировать объем памяти занимаемый экземпляром класса.

Вот что есть из доступных статей на эту тему:

Помимо __slots__ есть еще named tuples. Такой подход более распространен.

Модули threading and multiprocessing

Вопросы про потоки и процессы я слышал неоднократно, поэтому советую обратить на них особое внимание. Вопрос состоит из двух частей: понимание потоком и процессов в Unix в целом и интерфейс для работы с ними в Python.

Unix лучше изучить весь и стразу, потому что фундаментальные знания тоже очень важны. На английском языке могу посоветовать Linux System Programming: Talking Directly to the Kernel and C Library, эта книга имеет вменяемый объем и покрывает все основные аспекты.

Об интерфейсах в Python лучше читать в официальной документации:

В чем отличие open and fopen?

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

Что такое менеджеры контекста и как ими пользоваться?

Менеджеры контекста впервые появились в Python 2.5 с добавлением нового ключевого слова with (PEP 343). with можно сравнить с декоратором, который применяется для блоков кода. Суть этого оператора демонстрирует следующий пример:

    from contextlib import contextmanager

    @contextmanager
    def tag(name):
        print "<%s>" % name
        yield
        print "</%s>" % name
    
    >>> with tag("h1"):
    ...    print "foo"
    ...
    <h1>
    foo
    </h1>

На практике очень прижился вариант с open для работы с файлами:

    with open("file.txt", "r") as fd:
        foo = rd.read()

Сам я писал свои менеджеры контекста всего пару раз, это не что то встречается повсеместно. Вот пара ссылок с их развернутым описанием:

Какие структуры данных в питоне вы знаете и применяли на практике?

Тема про структуры данных, конечно, безграничная. В Python есть базовые структуры данных, типа tuple, list, dict, set, они используются везде и наверняка вы с ними знакомы. Сложность различных операция над этими структурами данных можно посмотреть здесь.

Еще есть стандартная библиотека, и модуль collections в частности, там есть deque, Counter, OrderedDict, defaultdict и др. Ну и разумеется, никто не запрещает написать что-нибудь свое или стащить чужое (GitHub вам в помощь) :).

Если говорить о более продвинутых структурах данных, то могу порекомендовать эту статью. Также, настоятельно рекомендую почитать Кормана, что бы лучше понимать откуда ноги расту. Эта книга очень популярна у Javистов и Сишников, а вот питонисты её незаслуженно обходят стороной. А зря, очень хорошая книга! …хотя местами нудная

Что нового в Python 3?

Версия питона 2.7 является завершающей и дальнейшее развитие второй версии языка не планируется, поэтому многие компании начинают активно присматриваться к третьей версии. Именно присматриваться, потому что реально на третью версию питона перешли единицы. Сам я только пару раз использовал Python 3, причем это всегда были небольшие тестовые проекты.

В Python 3 появились новые структуры данных, print стал функцией, input() убрали совсем, все строки теперь в Unicode и многое другое, но самое важное это то, что третья версия не имеет обратной совместимости со второй. Поэтому…

Первым делом лучше проверить Python 3 Wall of Superpowers, там находится список популярных библиотек, которые уже портированы на Python 3. Многие уже портированы, но вот некоторые зависли в неопределенном положении. Если вы не нашли своей любимой библиотеки, то придется искать аналог.

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

Цепи Маркова и машинное обучение

На собеседовании в Mail.RU меня попросили написать генератор бреда. Для этого нужно было использовать Цепи Маркова N-го порядка. С проектом я успешно справился и даже выложил его в открытый доступ.

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

К питону это пункт не имеет прямого отношения, так что решайте сами, интересно вам это или нет. Тема довольно обширная и парой ссылок на статьи тут не отделаешь - нужны фундаментальные знания.

Протокол HTTP

Протокол HTTP, без преувеличения, можно назвать одной из тех черепах, на которых стоит мир Интернета. Если вы занимаетесь веб-разработкой, то вы в какой-то степени с ним знакомы.

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

Как вводная, очень хороша статья на tuts+ HTTP: The Protocol Every Web Developer Must Know (Part 2). Подробное описание протокола можно прочесть в RFC2616, сам я правда его так и не прочел.

Еще есть довольно старая книга HTTP: The Definitive Guide с хорошими отзывами. Мне её тоже пару раз рекомендовали к прочтению.

Заключение

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

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

Ну и на последок еще одна ссылка на книгу Cracking the Coding Interview: 150 Programming Questions and Solutions, которая напрямую рассказывает о всех хитростях прохождения технических собеседований.

Удачи вам и успехов!



blog comments powered by Disqus

Fork me on GitHub