суббота, 13 марта 2010 г.

[work.management] Перлы от “успешных менеджеров”

Наткнулся на ссылку Кейс “Менеджер из не пойми кого” – история, рассказанная в “Клубе Успешных Менеджеров Программистов” с последующим обсуждением. История, в кратце, такова: некая девушка, выпускник филологического факультета, попала в софтверную компанию тестировщиком, а потом выросла до менеджера проекта. В этом проекте так же работали два сеньора-программиста и два студента. Программисты не умели общаться с заказчиком по-английски, поэтому предыдущий менеджер сначала привлекал к этой задаче вышеуказанную девушку, а потом общение с заказчиком полностью перешло к ней. Что и стало одной из причин ее назначения менеджером проекта. Такое назначение вызвало бурную реакцию одного из сеньоров, который в курилке матерно ругался, что его 8-мь лет работы в комании ничего не значили, и менеджером назначен не кто-то из сеньоров, а эта девушка.

Собственно, написать данную заметку меня заставила не сама история, а несколько фраз в комментариях (от не менее успешных менеджеров, я так полагаю).

Фраза первая:

Но не кажется ли Вам, что история о ПОТРЯСАЮЩИХ спецах по Java, абсолютно не разговаривающих по-английски и читатающих/пишуших со словарем - история из области фантастики?

Бля, мне не кажется. Речь же идет не о США, Великобритании или Австралии, а о России. Я, например, разговаривать по-английски не умею и читаю/пишу исключительно со словарем. Тем не менее.

Так что люди разные. В бывшем СССР знание Java вовсе не предполагает знания английского и наоборот. Менеджерам, претендующим на звание “успешных” не мешало бы это уразуметь.

Фраза вторая:

Не хочу общаться с клиентами потому что у меня плохой английский, лучше пусть кто-то вместо меня это делает (и вообще я программист, а не говорящая голова), но как только кого-то пропихивают не посоветовавшись со старичками - тут же начинаются сопли - как же так - мы же 8,10,12 лет и т.д. и т.п. (Кого интересует твои 8 лет?! За былые заслуги можно орден бумажный дать)

Человеку, который отработал в компании 8(!) лет и три года тянул проект нужно дать бумажный орден?! Этому “успешному менеджеру” лучше прямой в голову зарядить пару раз, для просветления. Люди, по определению, самый ценный ресурс, но тут-то еще и такой фактор нужно учитывать, как знания в голове этого разработчика. Если он в проекте с самого начала, то он владеет таким количеством нигде не зафиксированных деталей и подробностей, что его потеря в прямом смысле может стать невосполнимой.

PS. Бегло просмотрел остальные комментарии, вроде остальные выглядят вполне вменяемыми людьми (безотносительно практичности предлагаемых ими рекомендаций).

[prog.thoughts] Как же знание разных языков программирования делает нас лучшими программистами?

Существует такое старое изречение: “Хотите программировать лучше? Изучайте разные языки программирования!” Т.е. чем больше я знаю языков программирования, тем лучшим программистом я становлюсь.

Лично для меня это изречение до вчерашнего дня оставалось загадочным. Не понимал я до сих пор, как знание, например, Prolog-а, OCaml-а, С++ и Java может сделать меня лучшим программистом, чем знание только C++ и Java. Поскольку, в моем представлении, способности к программированию проявляются в таких вещах, как умение представлять задачу в виде последовательности элементарных действий, как умение выделять общие понятия, как умение устранять повторяющиеся последовательности одинаковых операций и т.д. Языки программирования к этим умениям имеют очень и очень далекое отношение.

Но вот вчера до меня, похоже, начал доходить смысл этой фразы. Вчера мои молодые коллеги устроили серьезный спор на тему (бес)полезности множественного наследования. Сам факт этого спора меня очень порадовал – это показатель того, что люди увлечены программированием, в таких условиях приятно работать. Хотя забавно наблюдать за спорщиками, которые о множественном наследовании имеют представление только из C++, имхо, нельзя рассуждать о (бес)полезности такого наследования не попрограммировав на Eiffel. Поэтому я старался в споре не принимать активного участия, а просто мастерски набрасывал очередную порцию дерьма на вентилятор… ;)

Да, так вот ближе к теме. Наблюдая за спорщиками я понял интересную штуку. Знание разных языков программирования полезно вовсе не тем, что у программиста расширяется кругозор и он может применять, скажем, в C++ подходы из OCaml или наоборот (кстати говоря, такие вещи могут быть как раз вредны). Полезность такого знания в том, чтобы считать принятые в каждом из языков решения и устоявшиеся идиомы нормальными. Т.е., нормально то, что в Java нет множественного наследования классов, и нормально то, что в C++ такое наследование есть. Так же нормально то, что в Ruby динамическая типизация, и так же нормально то, что в Haskell она статическая…

Вот именно эта способность, переключившись с C++ на Java, забыть об C++ных привычках, а перейдя с Java на Ruby забыть о Java-вских заморочках, и есть самое ценное. Ведь давно известно, что плохую программу на Fortran-е можно написать на любом языке. Поэтому плохой программист перейдя с C++ на Java будет писать плохие C++ные программы на Java или плохие Java программы на Ruby. А вот хороший программист, знакомый с разными языками программирования, будет писать плохие Java программы на Java и плохие Ruby программы на Ruby. Что уже значительно лучше ;)

Сухой остаток: каждый язык – это монастырь со своим уставом; знание разных языков позволяет комфортно чувствовать себя в любом из монастырей без попытки навязать ему свой собственный устав.

пятница, 12 марта 2010 г.

[life.work] Поговорить бы о причинах смены работы

В некоторых блогах/ЖЖ практикуются пятничные срачи флеш-мобы обсуждения. Не то, чтобы я хотел пойти по тому же пути :) Но в свете поиска сотрудников приходится задаваться вопросом “Что толкает людей на смену места работы?” А так как психолог и социолог из меня нулевой, то вместо фантазирования, я просто решил так прямо у своих читателей и спросить :)

Ну а что? Сегодня тяпница пятница, напряженная трудовая неделя почти позади, впереди (у некоторых счастливчиков) выходные. Почему бы не потрындеть за жизнь в блоге хорошего человека? ;)

Вот я и предлагаю читателям поделиться в комментариях своим мнением: что могло бы толкнуть вас на смену своего текущего места работы? Вопрос в первую очередь адресуется программистам и связанным с ИТ спецам (проджект-менеджерам, тестировщикам, тех.писателям, бизнес-аналитикам и т.д.), но я рад буду прочитать и мнения далеких от программирования людей.

И для затравки свое собственное мнение я опубликую первым комментарием к этой заметке.

четверг, 11 марта 2010 г.

[comp.prog] Amazon’s Dymano: репликация объектов и диагностирование сбоев

Продолжение рассказа о статье Dynamo: Amazon's Highly Available Key-value Store. Предыдущие части: Amazon's Dynamo: версионность объектов и Amazon's Dynamo: распределение объектов по узлам системы.

Одним из главных требований к Amazon Dynamo является высокая доступность. Как следствие, в Dynamo не используется традиционная система кворумов. Поскольку при сбое в системе кворум может не набраться – просто не будет достаточного количества живых узлов для репликации данных.

Поэтому в Dynamo используется т.н. sloppy quorum: все операции чтения и записи выполняются на первых N живых узлах из списка предпочтений. А эти узлы не обязательно будут первыми N узлами при последовательном обходе кольца узлов с диапазонами хеш-значений.

Например, пусть есть кольцо с узлами A, B, C, D, ..., Z и N=3 (N – это количество узлов, на которых должно быть зафиксировано значение объекта). Нужно сохранить ключ, который попадает в диапазон (Z,A]. Этот ключ должен храниться на узле A. Но если узел A сейчас недоступен, то его реплика может быть записана на узле D (поскольку N=3, то в обычное время реплика объекта попадает только на узлы A, B и C, но не D). При этом в метаданных реплики помечается, что она не принадлежит D и должна быть передана на узел A. Когда такая реплика попадает на узел D, он начинает периодически опрашивать узел A. И когда обнаруживает, что A опять вернулся в строй, то передает эту реплику узлу A, уничтожая ее у себя.

Такой подход позволяет Dynamo оставаться работоспособным даже при выходе из строя изрядного количества узлов. В некоторых случаях, для оптимизации быстродействия можно пойти даже на то, чтобы установить значение W (количество узлов, которые должны подтвердить запись объекта) равным 1. В таком случае запись будет завершаться успешно даже если в сети оказывается всего один узел, подтвердивший запись объекта.

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

Другой стороной системы репликации в Dynamo является снижение расходов на синхронизацию реплик после ввода отказавшего узла в строй. Поскольку каждый узел в Dynamo хранит большое количество объектов, то нужно быстро выбрать те из них, значение которых изменилось с момента последней репликации. Для этого в Dynamo используется механизм на основе хеш-деревьев (они же Merkle tree).

Смысл хэш-дерева в том, что значение родителя является хешем от значений его потомков. Т.е., если изменяется значение самого нижнего узла дерева (объекта), то изменяются хеши во всех родителях этого узла и, в конце-концов, в вершине дерева. Поскольку дерево состоит из нескольких независимых друг от друга поддеревьев, то это позволяет распараллеливать сравнение двух хэш-деревьев -- ведь их поддеревья можно сравнивать независимо друг от друга. Например, пусть есть два хэш-дерева у вершины которых два потомка. Если значение в вершине двух деревьев совпадают – значит деревья одинаковые (синхронизации реплик не требуется). Если не совпадает, значит можно отдельно сравнить левые поддеревья и правые поддеревья и т.д.

Этот принцип и используется в Dynamo: каждый узел хранит хэш-дерево для всех своих ключей. Когда приходит время синхронизации, узлы обмениваются сначала вершинами своих хэш-деревьев. Затем, при необходимости, вершинами поддеревьев и т.д. Такой механизм успешно работает. Однако для этого разработчикам Dynamo пришлось подумать над эффективной системой распределения ключей по узлам. Поскольку в худших случаях при перераспределении диапазонов (при вводе в строй новых узлов, например) перестройка хэш-деревьев оказывалась слишком дорогостящей операцией.

С темой репликации данных связана и еще одна тема – определение сбойных узлов во время работы Dynamo.

Ввод новых узлов и плановое отключение старых узлов выполняется в Dynamo только явным образом администратором: с помощью специального инструмента администратор подключает или отключает узел к кольцу. Получивший соответствующую команду узел использует Gossip-подобный протокол для извещения остальных узлов о своем статусе. Этот протокол позволяет узлам согласовывать свое видение текущего состояния кольца узлов. Так же каждый узел периодически связывается с любым другим случайным узлом для того, чтобы синхронизировать информацию о состоянии истории подключения/отключения узлов (почему-то эта история подлежит долговременному хранению и нуждается в синхронизации).

При обслуживании запросов пользователей узлы Dynamo используют только "локальное видение" состояния других узлов. Например, если A отсылает реплики узлам B и C, а получает ответ только от C, то A спокойно считает, что узел B вышел из строя. Даже если с узлом B все нормально и узел B успешно отвечает на запросы узла C. Для узла A все это не важно – узел B не ответил, значит он мертв. Узел A больше не будет адресовать запросы B, вместо этого он будет задействовать другие доступные узлы. Но узел A будет периодически пинговать B и, когда B ответит на пинг, узел A вновь занесет B в свой список живых узлов.

Для того, чтобы в Dynamo не произошло расщепления на несколько независимых колец (т.н. logical partition вследствие сбоев нескольких узлов, связывавших разные группы), используются т.н. seed-узлы. Это узлы с фиксированными именами, про которые знают все остальные узлы Dynamo. Периодически каждый узел должен связаться с одним из seed-ов и обменяться с ним информацией о доступных узлах. Благодаря этому узлы, оказавшиеся в независимых кольцах, узнают о существовании других колец и, тем самым, устраняется возникший разрыв.

В Dynamo используется децентрализованный протокол обнаружения сбоев, за деталями которого авторы статьи адресуют читателя к работе On Scalable and efficient distributed failure detectors.

За сим данную часть рассказа об Amazon Dynamo можно закончить. Пожалуй, затем последует еще одна маленькая заметка с несколькими моментами, которые меня в статье об Amazon Dymano зацепили.

среда, 10 марта 2010 г.

[prog.flame] В свое время похерили Java-апплеты, чтобы сейчас писать Flash-ы?

На работе иногда устраиваем с коллегой словесные перепалки по поводу современного программирования вообще (C++ отстой и Java – наше все, естественно :), и о Web-программировании в частности. Разговоры о Web-программировании меня особенно радуют – поскольку к Web-у я отношения не имею и наблюдаю за всем происходящим со стороны.

Лично я распространение Web-приложений считаю штукой очень неоднозначной. Имхо, это какой-то маразм. В обычных Web-приложениях раздражает постоянное смаргивание экрана и тормознутость. В AJAX-овских приложениях этого нет, зато есть большие объемы насыщенных JavaScript-ом страничек (помню, как я был поражен, когда обнаружил, что странички в нашем корпоративном Confluence весят более мегабайта).

Когда я десять лет назад оказался в Web-проекте (после многих лет программирования GUI под DOS-ом, Windows и OS/2), я был поражен примитивностью возможностей тогдашнего инструментария и жуткой смеси разных технологий на одной страничке: HTML+Java (которое JSP) + CSS + JavaScript + пляски с бубном для унификации поведения странички под разными браузерами. Сейчас, говорят, дело наладилось, но все равно с моей колокольни все это выглядит примитивно. Еще 20 лет тому в DOS-овских Norton-овских утилитах и MultiEdit-е были многоэтажные менюшки,  накладывающиеся друг на друга модальные диалоговые окна и везде были горячие клавиши. Повторение всего этого сейчас под Web-технологиями вряд ли вообще возможно. Может быть, лет через несколько :)

Собственно, насколько я могу судить, процесс по наращиванию возможностей Web-приложений идет в сторону отказа от текстово-разметочной структуры в сочетании с JavaScript-ом в пользу Flash-евых апплетов. Вот там простор для разработчика, достаточно посмотреть на то, что вытворяют создатели Flash-евых игр (из последнего увиденного впечатлила вот эта: SteamBird). И если уж динамичные игры Flash-евых возможностей достаточно, по почему бы не делать на Flash-е нормальные GUI-интерфейсы для Web-приложений (с менюшками, диалоговыми окнами, горячими клавишами и пр.)?

Но если Flash – это такая удобная штука для Web-программирования, то лично у меня возникает вопрос – а почему Flash, а не Java-апплеты? Ведь когда-то давным-давно, когда Sun представила Java широкой публике, Java-апплеты были главным местом приложения самой Java. Но почему-то не срослось…

Десять лет назад я спрашивал у коллег, а почему Web-приложения разрабатываются в виде JSP-страничек с JavaScript-ом внутри, а не в виде Java-апплетов. Не помню уже всех деталей, но история была такой – мои коллеги до этого писали программулину на Java-апплетах и апплеты получались очень большими по тем временам – около 500Kb и более. По сравнению с загрузкой 10Kb страничек загрузка на машину Java-апплета была гораздо более долгой операцией. Ну и плюс к тому, из Java-апплетов, насколько я помню, было неудобно взаимодействовать с серверной частью, поскольку AJAX-а тогда не было.

Но сейчас-то ситуация иная. 500Kb апплет – это очень немного (стартовая страница международной федерации биатлона весит больше (редиски!), а это всего лишь стартовая страница). Плюс Java работает гораздо быстрее, чем в 90-х годах, да и техника сейчас гораздо мощнее. Плюс взаимодействие с сервером практически стандартизировано для Web-приложений.

Казалось бы, сделать кэширование Java-апплетов на стороне клиента, чтобы не грузить его лишний раз, если его версия с прошлой загрузки не изменилась – и вообще всеобщее шасте будзе :) Как раз главный аргумент приверженцев Web-программирования – централизованное распространение новых версий приложения – сработает и здесь. Можно было бы пойти и дальше – браузер выбросить! В JDK входит appletviewer, который позволяет автономно воспроизводить апплеты. Вот развили бы его и сделали бы из него среду для работы апплетных приложений. Даешь ему URL-ик приложения, он проверяет кэш, и запускает либо ранее загруженный апплет, либо скачивает новый. В него же можно будет добавить и необходимые средства для обеспечения оффлайновой работы приложения (например, для сохранения данных на машине пользователя).

Но этого не происходит. Вместо этого все идет к тому, что на обычной машине будет две операционки – одна работает на голом железе и обеспечивает запуск десктопных приложений и браузера. А второй операционкой будет сам браузер – он будет средой для работы Web-приложений. В случае же Chromium OS нас вообще заставят забыть о том, что есть еще какая-то другая операционка, кроме браузера.

Не знаю, может кому-то все это кажется логичным, но не мне.

вторник, 9 марта 2010 г.

[comp.thoughts] Какой мобильности мне хочется

Хорошая вещь – ноутбук! Сам уже лет семь подряд работаю только на ноутбуках. За это время у меня их сменилось четыре штуки – сначала какой-то RoverBook на Celeron-е (гадость редкая, не советую никому покупать Rover-ы), затем Asus M3700N (вот была классная тачка!), затем Asus A8H00Sc, теперь здоровенная бандура Acer Aspire 8920.

Честно скажу, не представляю себе, как можно пересесть сейчас за стационарный компьютер. Я люблю дома работать, а в офис приезжать только по необходимости. С ноутбуком просто – взял и поехал, все рабочее окружение всегда с тобой. Со стационарным компьютером хуже.

Однако, не все хорошо с ноутбуками. Пятнадцатидюймовая матрица даже с разрешением 1440x900 – это слишком мало для комфортной работы. Я сейчас работаю на 18” экране с FullHD разрешением – вот это, имхо, самый необходимый минимум. Но большая матрица – это автоматически большой и тяжелый ноутбук. Скажем, мой Aspire 8920 сам по себе больше 4кг весит, плюс блок питания, плюс сумка с кучей разной мелочевки. Вот и таскаешь с собой здоровенный баул весом более 5кг. Мне-то еще ничего, я сам не маленький :)

Вес и размер ноутбука – это критически важные характеристики. Некоторые мои коллеги работают вообще на маленьких и легких 13” ноутбуках. А для того, чтобы не слепиться из-за маленького экрана, подключают свои ноутбуки к одному или двум нормальным мониторам (и полноразмерной внешней клавиатуре, при желании).

В принципе, это уже вполне хорошее решение – ставишь себе на работе и дома 20-22” мониторы, и используешь с ними какой-нибудь 12-13” ноутбук (вроде HP ProBook 4310s).

Но почему бы не пойти еще дальше? Ведь ноутбук – это т.н. single point of failure. Залипнет в нем кнопка на клавиатуре или перестанет звук работать – и что? Отвози в сервисный центр и жди пока его приведут в чувства. Тем временем все эти мониторы на рабочем месте и дома будут стоять мертвым грузом. И если уж мы сократили вес ноутбука с 4кг до 2кг, то почему бы не уменьшить его еще в несколько раз? Скажем, грамм до 500-600.

Т.е. чтобы возить только переносной винчестер.

В принципе, решение с винчестером вполне осуществимо уже сейчас. Покупаются две одинаковые машинки (два неттопа, к примеру), система устанавливается на внешний винт и загружается через USB. Поработал дома – заглушил систему, приехал на работу – воткнул USB шнурок и пошел работать дальше.

Плохо то, что машины должны быть полностью одинаковые – со всей одинаковой аппаратной начинкой, чтобы система одни и те же драйвера использовала. Было бы круче, если бы загрузчик ОС при старте считывал из BIOS-а какой-нибудь ID машины и в зависимости от его значения запускал бы ОС в той или иной конфигурации. Вот это была бы лепота!

Но можно пойти и дальше. А зачем, собственно, USB шнурок? Пусть вообще коробочка с внешним винтом вставляется в корпус неттопа как компакт-диск в привод :) Т.е. пришел на работу, воткнул в разъем коробочку и всех делов.

А проблему single point of failure можно решать так же как с ноутбуками сейчас – тотальным или выборочным backup-ом. С внешним винчестером даже проще будет, имхо. Там в одну коробочку сразу два винта можно засунуть – пускай они автоматом зеркалируются. Или по другому – в каждом неттопе стоит один резервный винт. Когда ты приходишь и вставляешь в неттоп переносной винт, неттоп автоматически (или по приказу) начинает его backup-ить на резервный. Выходит из строя переносной – информация восстанавливается с резервного.

Ну и возврат к истокам – к ноутбукам. Все таки ноутбуки – классная вещь! Даже дома мобильность ноутбука – это страшная сила ;) Захотел, взял с собой в кресло, захотел – улегся с ним на диване, зашипели на тебя домашние – пошел с ним на кухню. Не говоря уже о поездках в командировку и на отдых. Т.е. ноутбук нужен. А значит, он должен работать по той же схеме с внешним винчестером: коробочка с винчестером просто вставляется в соответствующий отсек ноутбука (как аккумуляторная батарея сейчас) и все. Вставил, включил и работай себе на кухне. Потом выключил, вытащил и поехал на работу. Лепота!