понедельник, 24 октября 2011 г.

Как эффективно читать корпоративную почту

Как ужиться программисту с потоком электронных писем которые приходят к нему в течении рабочего дня? Особенно это актуально в больших компаниях где существуют много рассылок, оповещений и просто спама от сотрудников :)

Дано: программист - т.е. ИТ-инженер основная обязанность которого - писать код. У программиста есть почтовый клиент в который время от времени падает почта.

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

Решение (абсолютно субъективное):

1) Оповещение
Отключаем визуальное оповещение в почтовом клиенте о новых письмах. Никаких всплывающих окон, никакого мигания в системном трее (или упаси Боже в панели задач), ни-че-го. При этом выставляем интервал проверки почты в минимум (1 мин как правило). Читаем почту только тогда, когда сами этого хотим - а не по воле нотификатора :). Для этого и нужно всего-то запустить / открыть почтовый клиент. Малый интервал проверки необходим для актуального отображения состояние почты - чтобы не нужно было совершать мануальных действий для проверки. Такая модель позволяет не прерываться во время работы в потоке.

2) Сортировка
Как за один взгляд на почтовый ящик понять - есть в нем важное / критичное письмо или нет? Есть способ который приблизит нас к идеалу. Вероятность того, что письмо требует ответного действия повышается по степени адресованности письма. То есть, если письмо только вам и никому больше (вы в To:) - очевидно от вас ждут ответ. Ситуация обостряется если в копии стоит начальник (т.е. он теперь тоже знает что от вас ждут ответ). Ну и совсем критично если в копии стоит взвод начальств разного ранга и ответственности. Поэтому можно задать просто правило - высший приоритет - в адресате только вы, отправитель начальник. Далее в адресате вы, в копии начальник. Далее в адресате вы в копии много разных людей. И наконец в адресате только вы (письмо один на один).
Степень критичности резко понижается если вы стоите в копии (CC:)/ Как правила это письма "for your information" и действий не требуют. Однако, имеет смысл в них все равно вникать - вас же туда не зря поставили :)
Письма, на которые вообще редко приходится реагировать - это всевозможные рассылки. Определить их достаточно просто - они высылаются на групповой адрес в который вас внесли. Самый низкий приоритет (я их могу не читать по 1-2 недели).
Стоит отметить отдельностоящие письма от роботов - вроде баг-трекера или билд-агента. Здесь сложно сказать что-то про приоритет - зависит от ситуации и состояния проекта в который вы вовлечены. Отдали фичу на тестирование - нотификация от багтрекера должна иметь наивысший приоритет. Начальник повесил таску которую нужно начать делать через месяц - ответ очевиден.

3) Написание ответа
Читаем новое письмо. Требуется ли от нас какие-то ответные действия? Если нет - отмечаем письмо как прочитанное. Если да - оцениваем время которое требуется на написание ответа. Если оно меньше, чем время которое мы уже потратили на чтение этого письма, то пишем и отправляем ответ прямо сейчас. Если больше, оставляем непрочитанным (как бы кладем его в список todo). В определенное время (отведенное у вас на почту - например после обеда или сразу после прихода на работу утром) идем от самых старых писем к новым. Учитывая приоритет конечно.

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

воскресенье, 23 октября 2011 г.

Зачем нужен iPhone?

Исключительно из исторических побуждений хочется зафиксировать историю использования iPhone. Потому что я вижу, что девайс остается тем же, а использовать я его начинаю по-другому. На данный момент я им пользуюсь уже 2,5 года (да, это iPhone 3G).


1) Книжка
Первая и самая используемая программа. ShortBook. Читает книжки в формате fb2 (а другой и не нужен на самом деле). Сам умеет ходить в интернет и книжки скачивать. Цитаты, закладки, все дела. Мое первое платное приложение. Ни разу не жалко.

2) Газета
Да-да, именно газета. Причем составленная из колонок по моему вкусу. Утром за чашечкой чая перед рабочим днем очень занимательно почитывать колкие статьи Колесникова о Путине, рассматривать фотографии медведей с Камчатки, следить за анонсами концертов любимых групп, читать литературную юмористику. Да, как вы уже догадались, речь идет о RSS-рассылках и iPhone нужен исключительно как агрегатор всех подписок. Причем желательно с "лайками" и "прочту потом". С эти успешно справляется Google Reader и MobileRSS. Google Reader агрегирует, задержек не замечено. MobileRSS синхронизирует, быстро скачивает новые посты, кэширует картинки и способен работать в оффлайне. При этом стабилен и не тормозит.
Второе платное приложение. Год пользовался халявной версией (немного рекламы вверху), потом понял что пора отдать долг разработчикам.
Особняком стоит Коммерсантъ. Бесплатно имеешь последнюю версию газеты в телефоне. Удобно, но реализация программы на 2ку. После 1-2 мес использования нужно переустанавливать - перестает запускаться. А так, коммерсант как коммерсант. К слову, Ведомости, АиФ и Комсомолка унылы чуть менее чем полностью.


3) Навигация
Сначала это была стандартная Google Maps. Более чем достаточно чтобы бродить по мегаполисам (опробованы лично: Москва, Петербург, Лондон, Берлин). К сожалению в мобильной версии не показывает маршруты общественного транспорта, хотя значки остановок стоят. Должны исправить, функционал очевиден.
Metropolitan. Использовал для Москвы - сам находит ближайшую станцию. Платная версия показывает на карте входы в метро, но сам не пользовался - научился их и так находить. Прога оказалась настолько крутой, что разработчика взяли в Яндекс где он ее скопипастил под новым именем. Яйца те же.
Яндекс.Карты. Должна быть у каждого автомобилиста со смартфоном (да, Android версия тоже есть). Прокладывает маршрут с учетом пробок, знает переулки / проезды по дворам, имеет бесплатный трафик у Мегафона и Билайна. Пока от навигатора отличается только отсутствием голосовой поддержки и менее информативном (из-за размера) экраном. На 3G наблюдаются периодические тормоза из-за объема файла базы данных с локациями владельца iPhone. Лечится исключительно iPhone-нными плясками с бубном (напишу об этом отдельно).
MyBank. Показывает на карте банкоматы и отделения практически всех крупных российских банков. Полезность средняя, так как много банкоматов в офисах к которым без пропуска не подойти.

4) Прочее
GymGoal. Для занятия фитнесом - журнал тренировок, подбор программы. Наверное, лучшая в своем классе.
SafeWallet. Просто чтобы хранить секретную информацию (паспорта, банковские карты, и т.п.) не в заметках.
AccuWeather. Бесплатно но подробно о погоде. Вроде угадывает :)
Skype + домашний Wifi превращает iPhone в междупланетный телефон.

Чего я не делаю на своем iPhone так это не смотрю видео. Время дает о себе знать, иногда и youtube тормозит. А видео через iTunes загруженное, iPhone вообще не видит. Особо не копал, но вообще это странно.

Вот интересно что может дать из всего вышеперечисленного iPad. И насколько лучше/хуже?

четверг, 21 июля 2011 г.

Неодушевленные люди

То, чем я сейчас занимаюсь на работе называет "resource manager". Казалось бы, это про ресурсы. А про какие ресурсы? Какие вообще могут быть ресурсы в ИТ компании? Рабочие компы, сервера? Конечно нет. Их три. Деньги, время и люди. Дык вот я занимаюсь последними двумя.

Особенно конечно - людьми. Есть пул задач, к ним есть пул заинтересованных лиц (которые хотят эти задачи сделать как можно быстрее). Есть пул разработчиков с разными скилами, которые эти задачи могут выполнять. Еще есть график отпусков, зависимости от соседних команд и индивидуальных особенности всех участников процесса. Собственно моя роль - соотнести один пул на другой, причем так, чтобы это всех устроило.

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



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

Я свою стратегию выбрал. Назовем её так "счастливый малыш - счастливая мама".
Думаю что всегда стоит добавить в копоративный двигатель масла человеческого отношения к людям. Тогда - может и мощность увеличится...

воскресенье, 27 марта 2011 г.

Найм талантливого разработчика по-Спольски

Продолжаю тему найма, которая сейчас для нас актуальна.

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

Главная идея - действительно хороших программистов на рынке труда просто нет. У них всегда есть работа, причем интересная им самим прежде всего. Отличие хорошего программиста от простого описываются примером:

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

Общая цель при отборе - понять может ли кандидат (не удержусь от языка оригинала) get things done (доводить дело до конца) и способен ли.

Важно уметь отличать эти два качества. Примеры:

Люди которые способны, но не доводят дело до конца часто имеют ученую степень. Вместо того чтобы решить проблемы вовремя они они будут придумывать какой-то ее научный аспект. Например в день когда вам нужно выпускать бета-версию программы, они появляются в вашем офисе с кружкой кофе и пытаются начать долгий разговор о том, что же лучше - библиотеки СОМ-типов или самоанализ языка Java. Я про себя таких называют "философы". Работать с ними - сущий ад особенно когда вы работаете в одном проекте и ваша работа взаимосвязана.

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

Первое - где хороших разработчиков найти?

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

Конференции, мастер-классы и прочие профессиональные сообщества могут быть отличным источником. Здесь главное попасть в масштаб и специализацию (не искать PHP-разработчиков на конференции системных программистов).

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

Второе - идеальные условия работы для разработчика

Идея в том, что имея лучшие условия работы при прочих равных, люди будут выбирать вас. Собственно, условия

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

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

Отличная цитата про разработчиков в инвест-банкинге (почти правда) "Чтобы удержать лучших программистов, в инвестиционных банках применяют две стратегии: платят море денег и разрешают программистам фактически свободно все переписывать на любом из новых языков программирования... А не переписать ли на Ruby то финансовое приложение? Да, что угодно, только принеси мне этот чертов чизбургер".

Программисты не должны беспокоится о деньгах. "Если вы начинаете слышать жалобы насчет зарплат там, где никогда их не слышали, то обычно это признак того, что на самом деле людям не нравится их работа". Кроме того, "предложение высоких зарплат будет на удивление неэффективным инструментом в решении таких проблем, как, например, то, что программистам выдают 15-дюймовые мониторы, что на них все время вопят продавцы и что работа ведет к созданию атомного ружья на детенышей тюленей". Важна мысль что, ЗП не должна быть ниже среднего по рынку - потому что как только она такой становится - тогда никого уже не удержать ничем. Но при равной ЗП в ход идет все "мелкое и приятное" что имеется у нас в арсенале и не обязательно при этом ее (ЗП) сильно задирать.

Дальше Джоэл нахваливал свой "бионический офис" - тут только "wow!" можно сказать.

Третье. Собеседование по-Спольски

Общая идеология - лучше не нанять хорошего чем нанять плохого (у нас эту проблему решает испытательный срок). Итак:

  • потратив на собеседования меньше часа вы не примете правильного решения;
  • не можете ничего сказать о кандидате после интерьвю - значит не нанимать;
  • что-то смущает - не нанимать;
  • хороший признак способного кандидата - вам не приходится что-то повторно объяснять;
  • важно не свести собеседование к опросу тривиальных фактов о программировании которые можно нагуглить за 15 секунд;
  • скорость с которой кандидат решает задачу так же важна как и решение;
  • не задавайте головоломных вопросов (как из 6-ти спичек построить четыре одинаковых правильных треугольника). Это вопросы из разряда "Ага!" т.е. ответ на них вам либо известен либо нет.


пятница, 25 марта 2011 г.

Новый проект - новая команда. Какая она?

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

Итак, когда в команде открываются вакансии?

1. Команда расширяется революционно

При численности N набирает A ~ N сотрудников. Выделится среди коллег легко, что больше больше подходит для самостоятельных и проактивных личностей.
Если используемые технологии вам знакомы - то все карты в вам руки, так как времени заниматься вами особо ни у кого не будет. А если последовательно начнете выполнять задачи (причем даже в том ключе который нравится вам, а не тот который принят в команде) - потом может оказаться что ваш подход имеет наибольшее покрытие в коде. Таким образом вы закроете своей экспертизой большой кусок функциональности - а это всегда очень ценится.
Если технологии незнакомы - то либо вы их срочно изучаете в процессе работы (и тогда см. выше), либо долго вы там не продержитесь потому что быстро окажетесь в аутсайдерах среди новичков.





2. Команда расширяется итерационно

При численности N набирает A < < N новых специалистов. Грубо говоря вы будете одним из немногих (если не единственным) новичком. Это значит что на первых порах команда сможет уделять вам достаточно много времени чтобы обучить и поделится опытом / технологиями / традициями / лучшими практиками. Так у вас всегда будет более опытный коллега который подстрахует в случае чего - то есть ваш уровень ответственности будет невысок. Идеальное место для изучения новых технологий и/или предметной области.
В то же время выделится будет очень непросто на фоне более опытных коллег и для этого нужно будет серьезно поработать - возможно лучшим вариантом было бы найти пробел в какой-нибудь области и начать его устранять собственными силами.


3. Команда стагнирует


Численность постоянна N = N. Вы претендуете как замена ушедшего [на повышение?] члена команды. Здесь важно знать контекст.
Если команда / продукт достаточно старые и уже прошли стадию "дойной коровы" - то скорее всего она сейчас находится в состоянии, когда хорошие спецы из нее уходят. При этом поддержка все равно нужна - как следствие набираются смена. В долгосрочной перспективе - уровень экспертизы в команде падает, звезды даже если в команду и попадают - достаточно быстро ее покидают ибо стагнирующий проект им не интересен. В общем, надо быть осторожным.
Возможен конечно вариант когда участник команду ушел на повышение/уволился - а проект вполне себе перспективный. Наверное, первое от второго можно отличить вопросом "сколько лет проекту?" Возможно, вполне честно ответят на вопрос "какие дальнейшие шаги по развитию проекта?". Идеальным вариантом было бы иметь инсайдера, который сможет рассказать историю проекта с самого начала.


4. Команда регрессирует

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

воскресенье, 23 января 2011 г.

Java: Вызов переопределенных методов в конструкторе

Подобная проблема, по-моему описывалась Блохом, но я изложу ее на русском и со своей стороны. Имеем родительский класс с полем, значение которого инициализируется в конструкторе (логика обычно простая). По правилам хорошего тона эта логика вынесена в отдельный метод. Поле после инициализации больше не используется для записи и поэтому final.
Спустя какое-то время появляется наследник класса у которого логика инициализации поля field другая. Для этого модификатор доступа меняется на protected, чтобы дать возможность наследнику заложить туда свою логику. Итак, получаем:
  1. static class Parent {
  2.         private final String field;
  3.  
  4.         Parent() {
  5.             field = createField();
  6.         }
  7.  
  8.         protected String createField() {
  9.             return "Parent-impl";
  10.         }
  11.  
  12.         @Override
  13.         public String toString() {
  14.             return getClass().getSimpleName() + field;
  15.         }
  16.     }
  17.  
  18.  
  19.     static class Child extends Parent {
  20.         private final String leftPart, rightPart;
  21.  
  22.         Child(String left, String right) {
  23.             leftPart = left;
  24.             rightPart = right;
  25.         }
  26.  
  27.         @Override
  28.         protected String createField() {
  29.             return leftPart + rightPart;
  30.         }
  31.     }
  32.  
  33.     public static void main(String[] args) {
  34.         System.out.println(new Child("AB", "CD"));

По результатам кажется что main должен вернуть ABCD. Однако это не так. Проблема в том, что в логике переопределенного метода createField() не должны участвовать состояния как наследника, так и родителя. Проще говоря можно использовать только константы (statiс final), хотя и с ними надо быть осторожным. Почему? Дело в том, что на момент вызова метода поля его + родительские поля создаваемого экземпляра еще не до конца созданы. В данном примере в момент вызова Child.createField() поля leftPart и rightPart ещё не проинициализированы (хотя они и final) и равны null.

Как теперь это исправить?
Есть несколько способов, я предпочитаю работать вместо поля с методом и как следствие вынести инициализацию в "ленивую" секцию. Как-то так:
  1. static class Parent {
  2.         private final String field;
  3.  
  4.         Parent() {
  5.             field = createField();
  6.         }
  7.  
  8.         private String createField() {
  9.             return "Parent-impl";
  10.         }
  11.  
  12.         protected String getField() {
  13.             return field;
  14.         }
  15.  
  16.         @Override
  17.         public String toString() {
  18.             return getClass().getSimpleName() + getField();
  19.         }
  20.     }
  21.  
  22.  
  23.     static class Child extends Parent
  24.  
  25.     {
  26.         private final String leftPart, rightPart;
  27.  
  28.         Child(String left, String right) {
  29.             leftPart = left;
  30.             rightPart = right;
  31.         }
  32.  
  33.         @Override
  34.         protected String getField
  35.                 () {
  36.             return leftPart + rightPart;
  37.         }
  38.     }
  39.  
  40.     public static void main(String[] args) {
  41.         System.out.println(new Child("AB", "CD"));

вторник, 18 января 2011 г.

GSM 5G что хотелось бы иметь

Что бы я добавил в стандарт сотовой связи GCM 5G.


1. Автоматический перевод телефонов в режим вибрации в театрах, кино, залах конференций и подобных местах. В общем, там, где все время просят их отключить, но всегда кто-нибудь да забудет или проигнорирует. Сота шлет сигнал телефону - мол, заткнись - и он затыкается. В идеале конечно позиционировать абонента и делать это именно когда он находится непосредственно в "тихом" помещении - чтобы в коридоре "громкий" режим телефона возвращался обратно.

2. Как продолжение предыдущего пункта, сота должна уметь выключать GSM модуль в самолетах / больницах и других серьезных местах. Возникает правда вопрос - а как его обратно автоматически включить, если GSM модуль отключен? Как вариант, сота сообщает телефону через какое количество времени телефон должен вернуться в строй. Для самолетов такое точно бы работало, для больниц - не знаю...


3. Способность GSM модулям телефонов связываться напрямую друг с другом если они в пределах досягаемости одной соты. Такой peer-2-peer для соседей. Телефон тогда бы отсылал на соту только тарификационные данные - поговорил с абонентом таким-то столько-то минут и секунд. Это бы решило проблему связи в большой толпе когда все друг другу звонят. Ну и конечно снизило нагрузку на соты в какой-то мере.

4. В адресной книге - статусы абонентов как в аське / скайпе. Чтобы не звонить и слышать "абонент временно недоступен" - видеть сразу что человека нет в сети. В статусе также можно было бы писать имя оператора, местоположение, в роуминге ли абонент или нет, ну и много чего еще интересного.

5. Ну и то, что уже наверняка есть на Android - автоподключение к халявным Wi-Fi сетям поблизости. Иметь базу городских точек с бесплатным Wi-Fi и просто определать их по местоположению.