Sunday 11 March 2012

Офисное чтиво

Перерыв на обед – нет!

В одной известной компании свёл меня случай с одним коллегой по офису. Звали его Джон. С первого взгляда очень солидный мужчина, умный вид, семейный, уже растут дети. Биоритмы мои с ним совпадали, порою я даже умудрялся приходить раньше его на офис и даже уходить раньше, что для рядового сотрудника было бы настоящим состязанием. По утрам он имел привычку делать себе мюсли: в принесённую на офис тарелку он засыпал мохнатые хлопья, заливал волшебным молоком и аппетитно хрумкал минут пять. После этого Джонни делал себе ароматный чай, который непременно дополнял вафлями или печеньем. Всё это утреннее время мне работалось не шибко сильно. Его же завтрак, я так думаю, проходил за чтением утренних новостей, поскольку ничем другим решительно невозможно заниматься с ложкой в одной руке и кружкой – в другой. Спустя некоторое время после опустошения и осушения нахлынивало рабочее настроение, и мы погружались в работу. В перерывах между завтраком и обедом в ход шли хрустящие яблоки и бананы, которые обязательно присутствовали на полке для головных уборов, превращённую безапелляционно в мини-склад фруктового магазина. На обед он ходил когда-как, видимо, пытаясь чутка сэкономить: всё-таки бремя ипотеки (может даже не одной) давало о себе знать. Вместо этого он покупал экспресс-суп наподобие Ролтона, заливал его водой и подогревал в микроволновке на кухне. Но вместо того, чтобы присесть за столиком тут же, на кухне (где ему никто и слова наперекор бы не сказал), и насладиться вкусом сего мессива, он (нетрудно догадаться) нёс его в наш офис, в котором через мгновение по расплывался приятный запах макарон, шампиньонов и чего-то-там (запах производителям продукта удалось синтезировать "на пять"). Вот скажите мне, почему я должен нюхать это весь следующий час?
Унылая муторная работа в послеобеденное время очень быстро понижала жизненный тонус Джон и тогда он открывал сайт с анекдотами и читал их, едва сдерживая смех сквозь зубы, иногда прихихикивая и прикрывая рот кулаком. Подкрепление желудка в послеобеденное время всегда проходило под лозунгом "съешь ещё этих божественных хрустящих сухариков", причём так как эти ненавистные мне сухарики были к тому же расфасованы в небольшенькие фольгированные пакетики, то весь ритуал начинался с шумного разрывания одного-двух таких пакетиков, высыпания в освободившуюся после завтрака тарелку, затем пакетики комкались и находили упокоение в мусорке. Всё это, сами понимаете, происходило настолько "абсолютно беззвучно", что кроме грома и молний в своём собственном мозгу ничего слышно не было.

Возвращение бумеранга

Мой коллега любил забирать свой рабочий ноут с собой уходя из офиса. Конечно, это не запрещено правилами, но что-то подсказывало мне, что он откроет его дома на своём диване совсем не для того, чтобы закончить отчёт. Просто этот жмот не мог выделить из своего бюджета каких-то $200, которые бы, воплощённые в БУшный ноут, с лихвой покрыли бы все его потребности. Однажды утром, приволоча с собой этот затасканный рабочий ноут, Джон обнаружил, что он не включается. Точнее, на экран выскакивает та самая надпись, от которой прошибает в пот: "Operating system not found". Это был уже второй аналогичный случай за последний месяц, когда у него слетел винт. Ситуация малоприятная в принципе, поскольку всё приходилось начинать сначала, а бакупов он вряд ли делал. На этот раз мой коллега не поленился поинтересоваться у менеджера, за какое время должна отработать служба поддержки и принести ему новый винт. После часа ничегонеделания, он позвонил в службу поддержки дабы сообщить им, что из-за их, мягко говоря, нерасторопности, он не может выполнять свою наивысочайшую функцию в компании. А просто книжку почитать или газетку у него не возникало желания. Когда же наконец в нашей комнате появился несчастный одинокий технарь, Джон строгим голосом спросил:
— Ты можешь показать мне винт, что ты принёс?
Тот протягивает винт.
— Почему он не в упаковке? Где тут дата изготовления?
Оба начинают рассматривать винт в поисках желанной маркировки.
— Так ты мне юзаный винт принёс. Конечно они через месяц выходят из строя!
— У нас такая политика: мы не выбрасываем винты, мы их переформатируем и возвращаем в оборот.
— Если он опять упадёт, что мне делать?
— Послушайте, коллега. Я лишь делаю свою маленькую работу. Если вы не довольны тем, как я её делаю, вы можете сообщить об этом моему менеджеру.
После непродолжительной перепалки на повышенных тонах, технарь всё-таки смог заменить винт и ушёл. Но Джон не мог оставить всё это на самотёк, и решил преподать неказистому технарю урок, а именно, пойти и пожаловаться. Но стоило ему переступить порог, как его споймал наш менеджер и сообщил, что только что ему позвонил начальник технического отдела и сказал, что Джон был груб в беседе и не давал другим выполнять свои обязанности. Технарь, холера, сработал на опережение.

Солдат спит, а служба идёт

Семья моего коллеги не жила с ним в той же стране, где он работал. Джон снимал квартиру для ночлега недалеко от офиса, и почти на каждые выходные уезжал домой, в свою страну. Машины у него своей не было и денег на билет на самолёт тоже. Вариант его был самый экономный: посредством форума находить водилу, который едет в нужном ему направлении, и за небольшую договорную цену составлять ему компанию. Понятно, что часть рабочего времени на неделе уходило на прозвонку дальнобойщиков и выяснения того, когда отправляется машина, где его смогут подобрать и где лучше выбросить. График на пятницу у Джона напрямую зависел от машины и частенько в пятницу его не было, что не могло нравится нашему менеджеру. Гибкий график работы в офисе позволял работать overtime, и при некоторой усидчивости и доступности интернета можно было продержаться лишние два часа на работе с понедельника по четверг, что как раз и накручивало нужные восемь пятничных часов. Это не нравилось нашему менеджеру ещё больше, и тот в связи с этим ввёл ограничения на overtime (абсурд для менеджеров в некоторых других компаниях, в которых мне довелось работать, но с другой стороны приятно, что о твоём состоянии заботятся):
  • Если ты честно отработал 40 часов в неделею, то тебе положено 5 часов overtime
  • Если ты отработал 32 часа, то только 3.
  • ... и далее по убывающей
Прогнуться, к сожалению, пришлось всей команде, поскольку если правилами не злоупотреблять открыто и часто, то замечаний практически не делали, а немножко пожульничать иногда бывало на руку и одновременно полезно для общего дела.

Алё,  Асисяй?!

Джону с завидной периодичностью на рабочий телефон звонила его жена. Иногда он ей звонил, несмотря на то, что звонок, в общем-то, международный. Но однажды я непроизвольно стал пассивным свидетелем весьма неприятного разговора. Один прекрасным утром Джон звонит в свой банк (а банк его был в его родной стране), и разговор идёт приблизительно в таком русле (ответов из трубки я не слышал, поэтому пофантазирую):
Джон: — Здравствуйте. Есть ли у вас для меня новости, касательно денег, пропавших с моего счёта?
Банк: — Здравствуйте. Пока новостей нет, но мы выясняем причину.
— Я вам сообщил об этом ещё на прошлой неделе. Имеет место финансовое преступление. Надо звонить в полицию, а вы ничего не сделали!
— Мистер, мы делаем всё, что в наших силах.
— Скажите мне ваше имя и фамилию и дайте мне телефон вашего менеджера. Я хочу разговаривать с вашим начальством касательно сложившейся ситуации.
— Да, меня зовут Ребекка Смит. Номер телефона менеджера я вам дать не могу, это против наших правил. Но я могу вас на него переключить. Желаете?
— Да, переключайте.
Возникает пауза на несколько минут, в течение которой Джонни напрасно посылает сигналы своим мозгом на тот конец провода: трубку никто не берёт. Он с досадой бросает свою трубку и говорит мне: "Совсем эти клерки распоясались. Их просто некому поставить на место!"

Мастер-ломастер

Уж не знаю, насколько Джону удавалось удовлетворять запросы нашего менеджера, но в плане какой он талантливый программист мне пришлось проверить на собственном опыте. А дело было так. Моему коллеге нужно было получить некоторые данные из RESTful сервиса, который возвращал ответ в XML формате. Тот наваял какую-то Java программулинку, которая работала в 99 случаях и в одном почему-то накрывалась с исключением SaxParseException "Invalid UTF-8 character at position X". Сервис, к которому он обращался, был написал давно и откатан хорошо, поэтому вероятность того, что именно мой коллега был претендентом на приз "лучший баголов недели" была крайне мала. Практически ничтожна. Когда он уже занёс руку над телефоном, чтобы звонить в службу поддержки этого сервиса и жаловаться, что у них сервис работает из рук вон плохо, как меня передёрнуло от одной только мысли, что история-то повторяется и мне придётся быть волей-неволей свидетелем новой истории. Я, как истинный коллега, предложил свою помощь с решением проблемы. Когда я подошёл к его монитору, меня несколько всколыхнуло, как от удара звуковой волны. Во-первых, мой коллега, каким-то чудом всё-таки сумевший скачать и поставить себе Eclipse, подключил в проект только JRE (искать у него JDK у меня не было никакой охоты), а следовательно, ни исходников ни Javadoc  у него не было. "В таком режиме работают лишь истинные профессионалы" подумал я и взглянул на код. А предстало перед моими очами следующее:
InputStream is = serviceUrl.openStream();

BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line;

while (line = reader.readLine() != null) {
    sb.append(line);
}

System.out.println("XML: " + sb.toString());

Document doc = documentBuilder.parse(new InputSource(new StringReader(sb.toString())));

Node node = doc.getChildNodes().item(5);
и далее по коду было жёстокое порно с участием getChildNodes() и doc.getElementsByTagName("..."). Ошибка тут очевидна: DOM парсеру надо было передавать "сырой" InputStream, а не выворачивать его в строку. Рассказав это тут же, я, не заметив зачем же ему всё-таки понадобилась эта строка, спросил, а нельзя ли обойтись без StringBuffer? В ответ получил, что хотелось бы выдать ответ сервиса на экран. Ну что делать: раз хочешь, то хочешь. Я уже ничего не говорил о многоэкранной мастурбации с DOM-деревом, которую можно было заменить на xPath (для моего коллеги это явно была инопланетная технология). По идее самым простым решением было бы задать кодовую страницу new BufferedReader(new InputStreamReader(is), "UTF-8"), поскольку, как известно, по умолчанию используется кодовая страница файловой системы ОС, что в нашем мелкомягком случае было "CP-1252". Но мой мозг всё-таки приучен мыслить "как правильно", а не "как быстрее" и поэтому моим решением "на скорую, но более адекватную руку" было создать массив подходящего размера "на глаз", зачитать в него весь ответ, вывести на экран и скормить парсеру:
URL serviceUrl = null;
InputStream is = serviceUrl.openStream();

byte[] buf = new byte[20 * 1024];

int len = is.read(buf);

System.out.println("XML: " + new String(buf, 0, len));

Document doc = documentBuilder.parse(new InputSource(new ByteArrayInputStream(buf, 0, len))); 
Мой фатальной ошибкой в этом коду было то, что я, как и Билли, повёлся на то, что "64K ought to be enough for everyone", а именно, размер буфера может оказаться маловат. Но я об этом сказал коллеге, что, по хорошему, надо зачитывать ответ кусками, и что не нужно изобретать велосипед, а взять IOUtils.toByteArray(is). Сейчас, глядя на этот код, вижу ещё одну, на мой взгляд малозначительную непринципиальную ошибку (напиши о ней в комментарии, дорогой мой читатель), во всяком случае, с парсингом всё в порядке. На следующий день я как-бы ненавязчиво спросил Джонни, а дописал ли он свой мега-код, на что он повёл себя неадекватно, взъерепенился и буркнул, что это не моё дело, сколько времени он будет писать этот код. Я совсем не против, путь пишет его хоть неделю. "Просто помочь хотел", – ответил я ему. На что он ответил, что не упала ему такая помощь: [я] простоял у его спины вчера целых 15 минут, а работающего кода не написал. Оказалось, что для части запросов буфера всё-таки не хватило, но я ему напомнил, что я сказал об этом ещё вчера. Далее и без того натянутый разговор завернулся в сторону, которую я совсем не ожидал: мой коллега спросил меня, а сколько лет я в IT? Я ответил, что пять (хотя на самом деле больше, но я же скромный). И тут Джонни, торжествуя, выложил: "А я – 15", что лично я расценил как "заткнись, и смотри в свой монитор", что я и сделал, не имея никакого желания объяснять человеку, не понимающего разницу между SOAP и REST, что такое буфер и что такое UTF-8. Вот такое вот "спасибо" я получил взамен на свой (бесспорно не работающий) код.

Мыльный пузырь

Сами понимаете, что моё практически безграничное терпение и дружелюбие в определённый закончились. И в одно прекрасное утро я выложил на стол всё, как есть. А именно, после очередной продолжительной беседы, когда он положил трубку, я сказал, что не соблаговолит ли многоуважаемый сэр свои личные вопросы решать в коридоре по сотовому или в нерабочее время. Ответом я был просто ошарашен. Джон говорит мне: "А что тут такого? Одень наушники и слушай, что тебе нравиться". То есть, понимаете ситуацию: когда его высочество говорит по телефону, я должен что-то себе поставить на фон. Я очень не люблю ябедничать, но в данном случае я счёл уместным подойти к менеджеру и послушать его совет касательно того, как лучше быть. Придя к менеджеру, я как есть рассказал часть истории (далеко не всё, пару фактов). Я предложил такой вариант: если есть возможность переместить меня в другую комнату, чтобы сэр Джон мог насладиться своими проблемами в одиночестве, то я буду только рад. Заметьте, я тактично предложил пожертвовать именно собой. К моему удивлению, менеджер был категорически против. Он сказал так: "А что если Джонни завтра станет закидывать ноги на стол?" и потом добавил, что он намерен уволить Джонни по истечение месяца. Испугавшись, я поинтересовался, не был ли наш только что состоявшийся разговор тому основанием (всё-таки не хочется быть причиной чьего-либо увольнения). Менеджер сказал, что сигналы к нему поступали из разных мест, и он не однократно пробовал разговаривать с Джонни, однако, безрезультатно. В свой последний день Джонни сказал мне: "Видишь, как наш менеджер легко может уволить человека. Это – мафия, тут все друг за друга, а мы с тобой – не удел. Вот посмотришь, кто будет следующим". Так вот, Джонни, прошло уже много времени, а наша команда всё та же. И, надеюсь, тебе хорошо там, где ты сейчас, кто бы тебя не приютил.

Апупеоз

Самое интересное я, конечно же, припас на самый конец моей истории, дорогой мой читатель. История только-ведь начинается! Приходит ко мне какое-то время назад мой менеджер и говорит, что Джонни подал против него иск в связи с неправомочными действиями (увольнение сотрудника без каких-либо веских причин). И, чёрт побери, ему юридическая поддержка не стоит ни копейки, поскольку на стороне сотрудников в этом случае выступает профсоюз (иначе бы он сварился в собственной желчи от бессилия, уверяю вас). Мне жалко менеджера, но тут ничего не поделаешь. Похоже, определённый урок будет всем. Менеджер попросил меня быть независимым свидетелем по этому делу, если это понадобиться. Я тут же дал своё согласие. Именно поэтому (а вы думали, что потехи ради?) я и написал этот пост, который и будет моей вечной памятью событий не так давно минувших лет.

3 comments:

  1. new String(buf, 0, len) -> new String(buf, 0, len, "UTF-8")

    ReplyDelete
  2. Гнать таких джонов сраной метлой из профессии!

    ReplyDelete