Кодеры за работой. Размышления о ремесле программиста
Шрифт:
Затем Python. Из старых - Scheme. Будет неплохо несколько месяцев поизучать “Structure and Interpretation of Computer Programs” вместе с сыном. Говорят, это отличная книга. В качестве первого шага я купил ее. Но для освоения нужно время.
Сейбел: Сегодня многие озабочены созданием программ, которые бы в полной мере использовали возможности многоядерных процессоров. Java стал первым крупным языком, в котором появились встроенные механизмы для многопоточной работы. Как вы считаете, приспособлен ли он к многоядерному миру?
Блох: Скажу больше: думаю, у него лучшие средства, чем у любого другого языка.
Сейбел: Что это за конкуренты?
Блох: Как я считаю, C++ и С#.
Сейбел: А как насчет Erlang или транзакционной памяти?
Блох: Насколько я знаю, транзакционной памяти в рабочем виде пока еще нет ни в одном из крупных языков. Если окажется, что это того стоит, то, наверное, она появится и в Java не позже, чем в прочих языках.
У Erlang свой подход к параллелизму - акторы: если они окажутся успешной находкой, то могут быть реализованы во многих языках. Как вы знаете, Одерски с компанией уже реализовали их в Scala. Пока я не уверен, что акторы - лучшее из придуманного для многоядерного параллелизма, но если все же это так, то и в Java вы скоро увидите их.
Сейбел: Итак, Java, по вашим словам, имеет блоки, позволяющие получить портируемый доступ к параллельным потокам, предоставляемым операционной системой, а также конструкции более высокого уровня в рамках API Java.util.concurrent. Но все равно, это ведь средства довольно низкого уровня в сравнении с Erlang или транзакционной памятью?
Блох: Не уверен. Некоторые конструктивные блоки в Java действительно низкоуровневые, например Atomiclnteger; есть среднеуровневые, например CyclicBarrier, и наконец высокоуровневые - ConcurrentHash-Мар и ThreadPoolExecutor. Уверен, что транзакционная память и акторы найдут свое место в наших конструктивных блоках для многопоточных задач, как только народ убедится, что эти новинки работают хорошо. Если, конечно, они будут работать хорошо.
Некоторые виды транзакционной памяти могут получить значение в будущем, например конструктивные блоки для разработчиков параллельных библиотек. Но мне кажется, транзакционная память не избавит создателей приложений от заботы о блокировках. Она не введет нас в счастливый мир, где потоки не мешают друг другу.
Тому есть несколько причин. Первая из них состоит в том, что если вы пытаетесь делать автоматическую блокировку или оптимистичное управление параллелизмом, основываясь только на чтении и записи на уровне байтов, то между потоками происходит “мнимый конфликт”: физические конфликты не соответствуют логическим. Если вам нужны блокировки, то убедитесь, что захвачены лишь те, которые помогают решить логические конфликты.
Так, например, если у вас есть два потока и оба прибавляют значения для счетчика, они должны выполняться параллельно. Они могут обращаться к одному и тому же участку памяти, но при этом не конфликтуют в логическом плане. Если один поток считывает значение счетчика, а другой увеличивает его, то есть конфликт. Но ведь у вас может быть множество потоков,
Вторая проблема с транзакционной памятью в том, что внутри нее осуществляются не все операции, например операция ввода/вывода. А вот третья проблема: некоторые виды транзакционной памяти позволяют “обреченным транзакциям” видеть память в неустойчивых состояниях - потенциально это крайне опасно. С этими проблемами мы уже сражались, когда строили транзакционные системы общего назначения. Решения есть, но все они усложняют систему или снижают скорость работы.
Так или иначе, насколько мне известно, транзакционная память еще не вышла из стадии исследований. Прекрасно, что этим занимаются. Но по-моему, она не решит разом все проблемы параллельности - по крайней мере, в обозримом будущем.
Сейбел: Сменим тему. Каков ваш стиль работы в команде?
Блох: Я довольно уживчив, предпочитаю “приятельское программирование” - когда работаешь вместе с кем-то, но не за одной клавиатурой. Вы пишете разные части программы, обмениваетесь кодом. Можно вообще пребывать в разных полушариях. Мы с Дугом Ли таким образом плотно работали несколько лет. Один писал интерфейс, другой говорил: “Все отлично, но я поправил там кое-что, вот погляди”.
Наконец получался интерфейс, который нас устраивал. Я реализовы-вал однопоточную версию, Дуг - многопоточную, во время работы мы обнаруживали разные просчеты и снова поправляли интерфейс. Мы читали код друг друга, Дуг обычно говорил: “Ты можешь сделать вот так - все заработает гораздо быстрее”, - а я отвечал: “Дуг, это ты можешь”. Он был очень силен во всем, что ускоряло работу системы, - виртуальные машины были для него как друзья. Этот вид программирования я очень люблю, он как бы сам подталкивает к удаленному сотрудничеству.
Мне нравится сидеть с кем-нибудь за одним терминалом и работать над кодом, но таким образом я сделал не много программ с нуля. Обычно это случается, когда я делаю ревизию кода; если вижу, что код надо сильно править, то предлагаю человеку посидеть вместе. Это полезно во многих отношениях, например как средство обучения, способ передать знания старшего поколения младшему.
А работать совсем в одиночку мне не нравится. Когда я пишу программу и обдумываю какое-нибудь сложное проектное решение, мне нужно с кем-то советоваться. Везде, где я работал, рядом был кто-нибудь, с кем я мог поделиться. Для меня это очень важно - обратная связь.
Сейбел: Так что же важнее - обратная связь или просто шанс проговорить задачу вместе?
Блох: И то и другое. Мы делаем очень хитрые вещи - часто есть не одно правильное решение или одно, но которого никто до тебя не нашел. Надо полагаться на свой инстинкт, но иногда полезно выслушать того, кто смотрит на вещи по-другому.
Я знаю тех, кто любит программировать в вакууме, но это, по-моему, им вредит. Надо замечать ошибки как можно раньше, выявлять недостатки структуры, пока они не отразились на коде. И если вы экспериментируете с разными подходами или просто с разными свойствами, то нужно обсуждать их с другими. При этом не стоит слепо верить никому - мнения могут быть разными, а за свою работу отвечаете только вы.