Эпиграф:
Встретились как-то в лесу Ёжик и Медвежонок.
— Здравствуй, Ёжик!
— Здравствуй, Медвежонок!
Так, слово за слово, шутка за шуткой, и получил Ёжик от Медвежонка по морде …
Под катом рассуждения нашего тимлида, а также директора по развитию продукта RAS — Игоря Марната о специфике рабочих конфликтов и возможных методах управления ими.
![image](https://habrastorage.org/r/w1560/webt/6u/c_/0r/6uc_0r08xggqsqzo6bqcjqdgi0g.png)
Большинство конфликтов, с которыми мы сталкиваемся на работе, развиваются по сценарию, похожему на описанный выше в эпиграфе. Есть несколько участников, изначально настроенных друг к другу вполне благожелательно, они пытаются решить какой-то вопрос, но в итоге проблема так и остаётся нерешённой, да и отношения между участниками обсуждения почему-то оказываются испорчены.
Жизнь — многообразна, в описанном выше сценарии случаются вариации. Иногда отношения между участниками бывают не очень хорошими изначально, иногда нет даже вопроса, требующего непосредственного решения (как, например, в эпиграфе), иногда после обсуждения отношения остаются такими же, что и до его начала, но вопрос в итоге так и не решён.
Что же есть общего во всех ситуациях, которые можно определить как ситуация рабочего конфликта?
![image](https://habrastorage.org/r/w780q1/webt/r_/le/pw/r_lepw3svgxx6uwrkq8llwh3qkw.jpeg)
Во-первых, это наличие двух или более сторон. Эти стороны могут занимать различное место в организации, находиться в отношениях равенства (коллеги в команде), или на разных уровнях иерархии (начальник — подчинённый), быть индивидуальными (сотрудник) или групповыми (в случаях конфликта между сотрудником и командой или двумя командами), и так далее. На вероятность конфликта и простоту его разрешения очень влияет уровень доверия между участниками. Чем лучше стороны знают друг друга, чем выше уровень доверия, тем выше шанс, что они договорятся. К примеру, сотрудники распределённой команды, которые никогда не общались лично, с большей вероятностью войдут в ситуацию конфликта при решении простого рабочего вопроса, чем люди, которые хотя бы несколько раз общались лично. Поэтому, работая в распределённых командах, очень важно обеспечить периодические личные встречи всех членов команды друг с другом.
Во-вторых, в ситуации конфликта на работе стороны находятся в ситуации решения какого-то вопроса, важного для какой-то из сторон, для них обеих или для организации в целом. При этом, в силу специфики ситуации, стороны обычно имеют достаточно времени и разнообразных способов его решения (формальных, неформальных, встречи, письма, решения руководства, наличия целей и планов команды, факт наличия иерархии, и т.д.). В этом отличие от ситуации решения рабочего (или не рабочего) вопроса в организации от, к примеру, решения важного вопроса: “Э, пацан, ты из какого района?!” на улице, или конфликта из эпиграфа. В случае решения рабочего вопроса имеют значение качество рабочего процесса и культура решения вопросов в команде.
В третьих, определяющим фактором конфликта (с точки зрения нашего обсуждения) является тот факт, что стороны процесса не могут самостоятельно прийти к решению вопроса, устраивающему все стороны. Ситуация требует вмешательства третьей стороны, внешнего арбитра. Этот пункт может показаться спорным, но, в сущности, если конфликтная ситуация успешно разрешилась без вмешательства внешнего арбитра, вопрос решён успешно и отношения сторон не ухудшились, это та ситуация, к которой нужно стремиться. Мы о таком конфликте даже, скорее всего, и не узнаем, или узнаем случайно после его разрешения. Чем больше вопросов команда может решить самостоятельно, тем более эффективно она будет работать.
Ещё одна характерная черта конфликта, которой стоит коснуться — степень эмоционального накала при решении. Конфликт не обязательно связан с высоким эмоциональным градусом. Участникам не обязательно кричать и махать руками, чтобы ситуация была, в сущности, конфликтной. Вопрос не решается, определённое эмоциональное напряжение при этом присутствует (возможно, оно не выражено вовне явно), значит, перед нами ситуация конфликта.
Нужно ли вообще вмешиваться в конфликтные ситуации, или лучше пустить их решение на самотёк и ждать, когда проблема рассосётся сама? Нужно. Не всегда в вашей власти или компетенции решить конфликт полностью, но в любой ситуации, в конфликте любого масштаба, вы можете занять взрослую позицию, тем самым выведя на неё ещё несколько человек вокруг себя, смягчить негативные последствия конфликта и поспособствовать его решению.
Перед тем как рассмотреть несколько примеров конфликтных ситуаций, остановимся на нескольких важных моментах, общих для всех конфликтов.
При решении конфликта важно быть над схваткой, а не внутри её (это ещё называют “занять метапозицию”), то есть, не оказаться в процессе решения в составе одной из сторон. В противном случае из внешнего арбитра, помогающего решению, вы лишь усилите позицию одной из сторон в ущерб другой стороне. При принятии решения важно, чтобы оно было морально принято всеми сторонами, как говорится, «куплено». Чтобы, даже если стороны и не были в восторге от принятого решения, они хотя бы были искренне согласны его исполнять. Что называется, быть в состоянии disagree and commit. Иначе конфликт просто изменит вид, тлеющий огонь останется под торфяником и в какой-то момент неизбежно разгорится снова.
Второй момент, отчасти связанный с первым — если вы уж взялись участвовать в решении конфликта, отнеситесь к этому максимально серьёзно с точки зрения коммуникаций и изучения контекста. Поговорите лично с каждой из сторон. Отдельно с каждой, для начала. Не довольствуйтесь почтой. В случае распределённой команды — поговорите хотя бы по видеосвязи. Не довольствуйтесь слухами и пересказами свидетелей. Поймите историю, чего хочет каждая из сторон, почему она этого хочет, чего ожидает, пробовали ли решить этот вопрос раньше, что будет, если он не будет решён, какие варианты решения они видят, как представляют позицию другой стороны, что, на их взгляд, правильно или неправильно, и т.д. Загрузите в свою голову весь возможной контекст, непредвзято, предполагая, что все правы. Вы не внутри конфликта, вы снаружи него, в метапозиции. Если контекст доступен только в почтовом треде — хотя бы прочитайте целиком его и относящиеся к нему обсуждению треды и документы. После того как прочитали — все равно поговорите голосом. Почти гарантированно вы услышите что-нибудь важное, чего нет в почте.
Третий важный момент — общий подход к общению. Это обычные вещи, ничего космического, но они имеют очень большое значение. Не пытаемся сэкономить время, разговариваем со всеми участниками, критикуем не человека, а рассматриваем последствия его действий (не “ты груб”, а “пожалуй, ребята могут на эту штуку обидеться”), даём возможность сохранить лицо, обсуждения проводим лично, а не перед строем.
Конфликты обычно бывают вызваны одной из двух причин. Первая связана с тем, находится ли человек в момент конфликта в позиции взрослого или в позиции ребёнка (об этом ниже). Это связано с его эмоциональной зрелостью, способностью управлять своими эмоциями (что, кстати, совсем не всегда связано с его возрастом). Вторая распространённая причина — несовершенство рабочего процесса, которое создаёт ситуации серых зон, в которой ответственность размазана между участниками, ожидания сторон не прозрачны друг для друга, роли в процессе размыты.
Соответственно, в решении конфликта (как и любого другого вопроса) менеджер должен иметь в виду три перспективы: краткосрочную — решить вопрос/конфликт здесь и сейчас, среднесрочную — минимизировать вероятность возникновения другого конфликта по такой же причине, и долгосрочную — воспитание в команде культуры взрослого человека.
В каждом из нас есть внутренний ребёнок, примерно трёх-четырёх лет. Большую часть времени на работе он спит, но иногда просыпается и берёт управление на себя. У ребёнка свои приоритеты. Ему важно настоять на том, что это его песочница, мама любит его больше, его машинка лучше всех (дизайн лучше всех, он программирует лучше всех, …). В ситуации конфликта ребёнок может прижимать игрушки, топать ногами и треснуть лопаткой, но он не может решать взрослые вопросы (архитектура решения, подходы к автоматическому тестированию, сроки релиза, и т.д), он не мыслит в терминах пользы для команды. Ребёнка в конфликте можно ободрить, утешить и отправить спать, попросив его позвать своего взрослого. Перед началом обсуждения в условиях конфликта убедитесь, что вы сейчас разговариваете со взрослым, а не с ребёнком, и сами стоите на позиции взрослого. Если ваша честная цель в данный момент — решить серьёзный вопрос, вы на позиции взрослого человека. Если ваша цель — топать ногами и треснуть лопаткой — это детская позиция. Отправьте своего внутреннего ребёнка спать и позовите взрослого, или перенесите обсуждение. Человек принимает эмоциональное решение, а затем подыскивает ему рациональное обоснование. Решение, принятое ребёнком, исходя из детских приоритетов, не будет оптимальным.
Кроме поведения в момент конфликта, детская или взрослая позиция характеризуется так же уровнем ответственности, которую человек готов взять на себя. В крайних проявлениях, детская позиция программиста, которую я встречал неоднократно, выглядит так: я код написал, отправил его на ревью — моя работа закончена. Ревьюеры должны его просмотреть и смёржить, QA должны его проверить, если будут проблемы — они мне сообщат. Как ни странно, даже довольно взрослые и опытные люди иногда ведут себя подобным образом. Другой край шкалы — человек считает себя ответственным за то, чтобы его код работал, был покрыт тестами, был проверен лично им, успешно прошёл ревью (если нужно, нет проблем попинговать ревьюеров, обсудить вопросы голосом, и т.д.) и был смёржен, QA при необходимости будет оказана помощь, описаны сценарии тестирования, и т.д. В нормальных случаях программист либо изначально находится ближе ко взрослому краю шкалы, либо смещается туда по мере накопления опыта (при условии, что в команде культивируется правильная культура). В экстремальных же случаях он продолжает работать, занимая обычно детскую позицию, тогда у него и команды периодически возникают проблемы и конфликты.
Воспитание в команде правильной, взрослой культуры — важная задача любого менеджера. Она требует длительного времени и ежедневных усилий, но результат того стоит. Есть два способа повлиять на культуру команды — личный пример (которому обязательно будут следовать, команда всегда смотрит на лидера) и обсуждение и поощрение правильного поведения. Здесь тоже нет ничего заумного или сильно формального, просто при обсуждении проблем замечайте, что здесь можно было бы сделать так-то, подчеркивайте, что заметили, когда решено правильно, похвалите, отмечайте на разборе релиза, и т.д.
Рассмотрим несколько типичных конфликтных ситуаций, от простого к сложному:
![image](https://habrastorage.org/r/w780q1/webt/px/1g/mn/px1gmnl91hrmxi9dd58cvaozsom.jpeg)
Конфликты, не связанные с рабочими вопросами
Довольно часто на работе случаются конфликты, не связанные с рабочими вопросами. Их возникновение и лёгкость разрешения обычно напрямую связаны с уровнем эмоционального интеллекта участников, уровнем их взрослости, и не связаны с совершенством или несовершенством рабочего процесса.
Типичные примеры — кто-то недостаточно часто пользуется стиральной машиной или душем, что не нравится окружающим, кому-то душно, а другому дует, если открывать окно, кто-то слишком шумный, а окружающим нужна тишина для работы, ну и так далее. С решением конфликтов такого рода лучше не затягивать и не пускать на самотёк. Сами собой они не рассосутся и будут ежедневно отвлекать от работы и отравлять атмосферу в команде. По счастью, решить их обычно больших проблем не составляет — достаточно спокойно поговорить (разумеется, один на один) с коллегой, пренебрегающим гигиеной, обеспечить комфортную рассадку людей, которые предпочитают тишину/прохладу, купить звукопоглощающие наушники или поставить перегородки, и т.д.
Другой пример, который встречался мне за время работы несколько раз — психологическая несовместимость членов команды. По каким-то причинам люди просто не могут работать вместе, каждое общение заканчивается скандалом. Иногда это связано с тем, что люди придерживаются полярных взглядов по какому-то животрепещущему вопросу (обычно политическому) и не умеют оставлять их за пределами работы. Убеждать их потерпеть друг друга или изменить своё поведение — занятие достаточно бесперспективное. Единственное исключение, которое я встречал — молодые коллеги с открытым восприятием, их поведение еще можно постепенно изменить периодическими разговорами. Обычно вопрос успешно решается разведением их по разным командам, или, по крайней мере, обеспечением возможности крайне редко пересекаться по работе.
Во всех приведённых ситуациях со всеми участниками стоит поговорить персонально, обсудить ситуацию, поинтересоваться, видят ли они вообще проблему в данном случае, спросить, какие, по их мнению, есть пути решения, обеспечить их участие в принятии этого решения.
С точки зрения оптимизации рабочего процесса (среднесрочная перспектива, о которой я упоминал), сделать здесь можно не очень много, единственный момент для оптимизации — учитывать фактор совместимости при формировании команды и заранее не ставить вместе людей, которые будут конфликтовать.
С точки зрения культуры команды, такие ситуации возникают намного реже в командах с взрослой культурой, где люди уважают команду и коллег и умеют решать вопросы самостоятельно. Кроме того, такие конфликты решаются намного проще (часто автоматически) в командах, где высок уровень доверия, люди давно работают вместе и/или часто общаются вне работы.
Конфликты, связанные с рабочими вопросами:
Такие конфликты вызваны обычно обеими причинами сразу, и эмоциональной (тем, что кто-то из участников не находится на позиции взрослого), и несовершенством самого рабочего процесса. Самый, пожалуй, частый вид конфликтов, который я встречал — конфликты в процессе ревью кода или обсуждения архитектуры между разработчиками.
Я бы выделил здесь два типичных случая:
1) В первом случае разработчик не может добиться ревью кода от коллеги. Патч отправлен на ревью, и ничего не происходит. На первый взгляд, явного конфликта между двумя сторонами нет, но, если вдуматься, это вполне себе конфликт. Рабочий вопрос не решается, одна из сторон (ожидающая ревью) испытывает явный дискомфорт. Экстремальный подвид такого случая — разработка в коммьюнити или в разных командах, при этом ревьюер может быть не заинтересован в этом конкретном коде, в силу загрузки или других обстоятельств может вообще не обращать внимания на запрос на ревью, и внешнего арбитра (общего для обеих сторон менеджера) может вообще не быть.
Подход к решению, который помогает в такой ситуации, относится как раз к долгосрочной перспективе, культуре взрослого человека. Во-первых, работает разумная активность. Не стоит ожидать, что висящий на ревью код обратит на себя внимание ревьюера сам. Нужно помочь ревьюерам его заметить. Пингани пару человек, задай вопрос на синкапе, участвуй в обсуждениях. Очевидно, что назойливость скорее повредит, чем поможет, нужно включать здравый смысл. Во-вторых, хорошо работает предварительная подготовка. Если команда понимает, что и почему происходит, зачем этот код вообще нужен, дизайн был обсуждён и согласован заранее со всеми, люди скорее обратят внимание на такой код и примут его в работу. В третьих, работает авторитет. Если ты хочешь, чтобы тебя ревьюили — делай много ревью сам. Делай качественные ревью, с реальными проверками, реальными тестами, полезными комментариями. Если твой ник известен в команде с хорошей стороны, больше шансов, что на твой код обратят внимание.
С точки зрения рабочего процесса, возможные улучшения здесь — правильная расстановка приоритетов, направленная на то, чтобы помочь разработчику достигать своих целей и целей команды (делать ревью других, писать письма в коммьюнити, сопровождать код описанием архитектуры, документацией, тестами, участвовать в обсуждениях с коммьюнити, и т.д.), не допускать слишком долгого зависания патчей в очереди, и так далее.
2) Второй распространённый случай конфликтов при ревью кода или дизайна — разные взгляды на технические вопросы, стиль кодирования, выбор инструментария. Огромное значение при этом имеет уровень доверия между участниками, принадлежность к одной команде, опыт совместной работы. Тупик наступает тогда, когда кто-то из участников занимает детскую позицию, не пытается услышать, что ему хочет донести собеседник. Часто при этом и подход, предложенный другой стороной, и подход, предложенный изначально, вполне могут успешно работать и не имеет принципиального значения, какой именно выбрать.
Как-то раз программист из моей команды (назовём его Паша) подготовил патч с изменениями в систему развёртывания пакетов, которую разработали и поддерживали коллеги из соседнего департамента. У одного из них (Игоря) было своё сильное мнение относительно того, как именно нужно настраивать сервисы Линукса при развёртывании пакетов. Это мнение отличалось от подхода, предложенного в патче, и договориться у них не получалось. Как обычно, сроки поджимали, и было нужно прийти к какому-то решению, нужно было, чтобы кто-то из них занял взрослую позицию. Паша признавал, что оба подхода имеют право на жизнь, но ему хотелось, чтобы его вариант прошёл, т.к. явных технических преимуществ не было ни у одного, ни у второго варианта.
Наше обсуждение выглядело примерно так (весьма схематично, конечно, разговор был на полчаса):
— Паша, у нас через несколько дней feature freeze. Важно, чтобы мы всё собрали и начали тестирование как можно скорее. Как бы нам пройти через Игоря?
— Он хочет настраивать сервисы по другому, комментариев там налепил мне …
— И что там, большие переделки, много возни?
— Да нет, там работы на пару часов, но в итоге разницы ведь нет, и так, и так будет работать, зачем это нужно? Я сделал работающую вещь, давай её и примем.
— Слушай, а сколько уже вы это всё обсуждаете?
— Да уже недели полторы топчемся.
— Эм … мы можем за пару часов решить вопрос, который уже занял полторы недели, и не делаем этого?
— Ну, да, но мне не хочется, чтобы Игорь подумал, что я прогнулся …
— Слушай, а тебе самому что важнее, релиз выпустить, вместе с твоим решением внутри, или Игоря забороть? Можем забороть, тогда, правда, есть хороший шанс пролететь с релизом.
— Ну … было бы прикольно, конечно, нос Игорьку утереть, но ладно, релиз важнее, согласен.
— Тебе реально так важно, что думает Игорь? Честно говоря, ему вообще более-менее по барабану, он просто хочет единого подхода в разных местах той штуки, за которую он отвечает.
— Ну, ок, давай я сделаю так, как он просит в комментариях, и начнём тестирование.
— Спасибо, Паша! Я был уверен, что из вас двоих ты окажешься взрослее, хотя Игорёк и старше тебя:)
Вопрос решился, релиз выпустили в срок, Паша особого недовольства не испытывал, т.к. он сам предложил решение и реализовал его. Игорь вообще был доволен, т.к. его мнение учли и сделали так, как он предлагал.
Другой вид такого же, в сущности, конфликта — выбор между техническими решениями/библиотеками/подходами в проекте, особенно в распределённой команде. В одном из проектов, который позиционировался, как использующий C/C++, в итоге оказалось, что технический менеджмент проекта категорически против использования STL (Standard Template Library). Это стандартная библиотека языка, которая упрощает разработку, наша команда к ней очень привыкла. Оказалось, что проект намного ближе к C, чем к C++, что не очень вдохновляло команду, т.к. менеджмент постарался и набрал реально крутых плюсовиков. При этом, американская часть команды, и инженеры, и менеджеры, работали в компании давно, привыкли к существующему положению вещей, их всё устраивало. Российскую же часть команды собрали вместе совсем недавно, за несколько недель (в том числе и меня). Российская часть команды категорически не желала отказываться от привычного подхода к разработке.
Начались бесконечные письменные обсуждения между двумя континентами, письма по три-четыре экрана летали туда-сюда, в групповой рассылке и личные, от программистов — программистам и менеджерам. Как это обычно бывает, письма такого размера никто, кроме авторов и их горячих сторонников, не читал. Чаты поскрипывали от напряжения, передавая в разные стороны многоэкранные соображения относительно технических преимуществ STL, насколько хорошо она протестирована, безопасна, и вообще, как прекрасна жизнь с ней, и как ужасна без неё.
Длилось это всё довольно долго, до тех пор, пока я наконец не понял, что мы обсуждаем технические стороны вопроса, а проблема-то в реальности не техническая. Проблема не в достоинствах или недостатках STL или сложности работы без неё. Проблема скорее организационная. Нам нужно было просто понять, как устроена компания, в которой мы работали. Раньше ни у кого из нас опыта работы в такой компании не было. Дело было в том, что после разработки кода и выпуска его в production, поддержкой занимались совершенно другие люди из других команд, из других стран. Эта огромная инженерная команда из нескольких десятков тысяч инженеров (в совокупности) могла себе позволить только совершенно базовый минимум технических средств, так сказать, minimum minimorum. Всё, что выходило за рамки инженерного стандарта, сложившегося в компании, физически не могло быть поддержано в дальнейшем. Уровень команды определяется уровнем слабейших её членов. После того как мы поняли реальную мотивацию действий американской части команды, этот вопрос был снят с повестки дня, и мы все вместе успешно разработали и выпустили продукт, используя стандарты, принятые в компании. Письма и чаты в этом случае работали плохо, чтобы прийти к общему знаменателю, понадобилось несколько поездок и много личного общения.
С точки зрения рабочего процесса, в этом конкретном случае, помогло бы наличие описания используемых средств, требования к ним, ограничения на добавление новых, обоснование таких ограничений. Такие документы примерно соответствуют описанным в пунктах Reuse Strategy и Development Environment руководства “Manager's Handbook for Software Development”, разработанного в NASA. Несмотря на свой возраст, он прекрасно описывает все основные активности и этапы планирования разработки ПО подобного рода. Наличие подобных документов очень упрощает процесс обсуждения того, какие компоненты и подходы могут быть использованы в продукте, и почему.
С точки зрения культуры же, очевидно, при более взрослой позиции, при которой стороны пытаются услышать и понять реальную мотивацию действий коллег и действуют исходя из приоритетов проекта и команды, а не личного эго, конфликт бы решился проще и быстрее.
В другом конфликте из-за выбора технического решения мне тоже понадобилось заметное время, чтобы понять мотивацию одной из сторон (очень уж необычный был случай), но, после того как мотивация была ясна, решение было очевидно.
Ситуация такая: в команде из примерно 20 человек появляется новый разработчик, назовём его Стас. Нашим стандартным инструментом для общения в команде был на тот момент скайп. Как потом выяснилось, Стас был большим фанатом открытых стандартов и опенсорсного ПО, и пользовался только инструментами и операционными системами, исходники которых доступны публично, и которые используют описанные публично протоколы. Скайп к таким инструментам не относится. Мы потратили уйму времени на обсуждения достоинств и недостатков этого подхода, попыток запуска аналогов скайпа на разных операционных системах, попытках Стаса убедить команду перейти на другие стандарты, писать ему персонально по почте, звонить ему персонально по телефону, купить ему второй компьютер специально для скайпа, и т.д. Наконец я понял, что это проблема, в сущности, не техническая и не организационная, она скорее мировоззренческая, даже, можно сказать, религиозная (для Стаса). Даже если бы мы в итоге соединили Стаса и скайп (на что уже ушло несколько месяцев), на любом следующем инструменте проблема возникла бы снова. У меня в распоряжении не было реальных средств изменить мировоззрение Стаса, и не было оснований пытаться изменить мировоззрение команды, которая прекрасно работала в этом окружении. Человек и компания просто были ортогональны по мировоззрению. В подобных ситуациях хороший вариант решения — организационный. Мы перевели Стаса в другую команду, где он был более органичен.
Причина этого конфликта, на мой взгляд, в несоответствии личной культуры конкретного человека (у которого есть сильное мнение, не позволяющее ему идти на компромиссы), культуре компании. В данном случае это, конечно, ошибка менеджера. Было изначально неправильно брать его на проект подобного рода. Стас в итоге перешёл на проект по разработке открытого ПО и прекрасно там преуспел.
Хороший пример конфликта, вызванный одновременно детской позицией разработчика и недостатками рабочего процесса — ситуация, в которой в отсутствие definition of done у разработчика и QA команды есть разные ожидания относительно готовности фичи, переданной в QA. Разработчик считал, что достаточно написать код и перекинуть фичу через забор в QA — там разберутся. Довольно взрослый и опытный, кстати, программист, но такой уж у него был внутренний порог качества. QA с этим были несогласны и требовали показать и описать им, что он проверил сам, и требовали сценарий тестирования для них. Они уже имели в прошлом проблемы с функционалом от этого разработчика и не хотели тратить своё время зря ещё раз. Кстати, они были правы — фича действительно не работала, код перед передачей в QA он не проверил.
Для решения ситуации я попросил его показать мне, что всё действительно работает (оно не работало, и ему пришлось чинить), мы проговорили с командой и с QA definition of done (делать его письменным не стали, т.к. не хотели слишком бюрократизировать процесс), ну а с этим специалистом мы вскоре расстались (к общему облегчению).
С точки зрения рабочего процесса возможные улучшения в данном случае — наличие definition of done, требования к сопровождению каждой фичи юнит и интеграционными тестами, описание тестирования, проведённого разработчиком. В одном из проектов мы замеряли уровень покрытия кода тестами во время CI и в случае, если уровень покрытия после добавления патча, падал, тесты помечались как непройденные, т.е. любой новый код мог быть добавлен только при наличии новых тестов для него.
Ещё один типичный пример конфликта, тесно связанного с организацией рабочего процесса. У нас есть продукт, команда разработки этого продукта, команда поддержки и заказчик. У заказчика возникают проблемы с продуктом, он обращается к поддержке. Поддержка анализирует проблему и понимает, что проблема в продукте, передаёт проблему продуктовой команде. У продуктовой команды горячая пора, релиз на подходе, поэтому тикет с проблемой от заказчика, затерявшийся среди остальных тикетов у разработчика, которому он назначен, висит несколько недель без внимания. Поддержка думает, что разработчик работает над проблемой заказчика. Заказчик ждёт и надеется, что над его проблемой работают. В реальности ничего пока не происходит. Через несколько недель заказчик, наконец, решает поинтересоваться прогрессом и спрашивает у поддержки, как дела. Поддержка спрашивает разработку. Разработчик вздрагивает, просматривает список тикетов и обнаруживает там тикет от заказчика. Читая тикет от заказчика он понимает, что информации для решения проблемы недостаточно, и ему нужны ещё логи и дампы. Поддержка запрашивает дополнительную информацию от заказчика. И тут заказчик понимает, что над его проблемой всё это время никто не работал. И грянет гром …
В этой ситуации решение самого конфликта довольно очевидно и линейно (починить продукт, обновить документацию и тесты, умиротворить заказчика, выпустить хотфикс, и т.д). Важно проанализировать рабочий процесс и понять, кто несёт ответственность за организацию взаимодействия между двумя командами, почему такая ситуация вообще стала возможной. Понятно, что нужно починить в процессе — кто-то должен мониторить общую картину без напоминаний от заказчиков, проактивно. Тикеты от заказчика должны выделяться среди остальных тикетов у разработчиков. Поддержка должна видеть, работает ли разработка над её тикетами в настоящий момент, если нет — когда сможет начать работать, когда можно ожидать результата. Поддержка и разработка должны периодически общаться и обсуждать статус тикетов, сбор нужной для отладки информации должен быть максимально автоматизирован, и т.д.
Как на войне противник старается ударить в стык между двумя подразделениями, так и в работе самым тонким и уязвимым местом обычно оказывается взаимодействие между командами. Если менеджеры поддержки и разработки достаточно взрослые, они смогут починить процесс самостоятельно, если нет — процесс будет продолжать генерировать конфликты и проблемы, пока не вмешается менеджер, который сможет починить ситуацию.
Другой характерный пример, который я встречал неоднократно в разных компаниях — ситуация, в которой продукт пишется одной командой, автоматические интеграционные тесты для него — второй командой, инфраструктура, на которой это всё эксплуатируется, сопровождается третьей командой. Проблемы при прогонах тестов возникают постоянно, и причиной проблем в них может быть как продукт, так и тесты и инфраструктура. Проблематичным обычно бывает договориться, кто должен производить первичный анализ проблем, файлить баги, парсить логи продукта, тестов и инфраструктуры, и т.д. Конфликты здесь весьма часты, и, в то же время, единообразны. В случае высокого эмоционального накала участники часто сваливаются в детскую позицию и начинаются обсуждения из серии: “почему я должен с этим ковыряться”, “у них чаще ломается”, и т.д.
С точки зрения рабочего процесса конкретные шаги для решения вопроса зависят от состава команд, вида тестов и продукта, и т.д. В одном из проектов мы ввели периодические дежурства, при которых команды следили за тестами по очереди, по неделе. В другом первичный анализ всегда проводили разработчики тестов, но при этом анализ был весьма базовый и продукт достаточно стабилен, так что это неплохо работало. Главное — обеспечить прозрачность процесса, ясность ожиданий для всех сторон и ощущение справедливости ситуации для всех.
Является ли вообще конфликт в организации проблемой, плохой ли это признак, что в вашей команде часто (или просто периодически) случаются конфликты? В целом, нет, ведь если происходит рост, развитие, есть какая-то динамика, то возникают вопросы, которые никогда не решались раньше, при их решении могут возникать конфликты. Это индикатор того, что на какие-то области нужно обратить внимание, что есть области для улучшений. Плохо, если конфликты возникают очень часто, решаются трудно или долго. Это, скорее всего, признак недостаточно отлаженных рабочих процессов и недостаточной взрослости команды.
Встретились как-то в лесу Ёжик и Медвежонок.
— Здравствуй, Ёжик!
— Здравствуй, Медвежонок!
Так, слово за слово, шутка за шуткой, и получил Ёжик от Медвежонка по морде …
Под катом рассуждения нашего тимлида, а также директора по развитию продукта RAS — Игоря Марната о специфике рабочих конфликтов и возможных методах управления ими.
![image](https://habrastorage.org/webt/6u/c_/0r/6uc_0r08xggqsqzo6bqcjqdgi0g.png)
Большинство конфликтов, с которыми мы сталкиваемся на работе, развиваются по сценарию, похожему на описанный выше в эпиграфе. Есть несколько участников, изначально настроенных друг к другу вполне благожелательно, они пытаются решить какой-то вопрос, но в итоге проблема так и остаётся нерешённой, да и отношения между участниками обсуждения почему-то оказываются испорчены.
Жизнь — многообразна, в описанном выше сценарии случаются вариации. Иногда отношения между участниками бывают не очень хорошими изначально, иногда нет даже вопроса, требующего непосредственного решения (как, например, в эпиграфе), иногда после обсуждения отношения остаются такими же, что и до его начала, но вопрос в итоге так и не решён.
Что же есть общего во всех ситуациях, которые можно определить как ситуация рабочего конфликта?
![image](https://habrastorage.org/webt/r_/le/pw/r_lepw3svgxx6uwrkq8llwh3qkw.jpeg)
Во-первых, это наличие двух или более сторон. Эти стороны могут занимать различное место в организации, находиться в отношениях равенства (коллеги в команде), или на разных уровнях иерархии (начальник — подчинённый), быть индивидуальными (сотрудник) или групповыми (в случаях конфликта между сотрудником и командой или двумя командами), и так далее. На вероятность конфликта и простоту его разрешения очень влияет уровень доверия между участниками. Чем лучше стороны знают друг друга, чем выше уровень доверия, тем выше шанс, что они договорятся. К примеру, сотрудники распределённой команды, которые никогда не общались лично, с большей вероятностью войдут в ситуацию конфликта при решении простого рабочего вопроса, чем люди, которые хотя бы несколько раз общались лично. Поэтому, работая в распределённых командах, очень важно обеспечить периодические личные встречи всех членов команды друг с другом.
Во-вторых, в ситуации конфликта на работе стороны находятся в ситуации решения какого-то вопроса, важного для какой-то из сторон, для них обеих или для организации в целом. При этом, в силу специфики ситуации, стороны обычно имеют достаточно времени и разнообразных способов его решения (формальных, неформальных, встречи, письма, решения руководства, наличия целей и планов команды, факт наличия иерархии, и т.д.). В этом отличие от ситуации решения рабочего (или не рабочего) вопроса в организации от, к примеру, решения важного вопроса: “Э, пацан, ты из какого района?!” на улице, или конфликта из эпиграфа. В случае решения рабочего вопроса имеют значение качество рабочего процесса и культура решения вопросов в команде.
В третьих, определяющим фактором конфликта (с точки зрения нашего обсуждения) является тот факт, что стороны процесса не могут самостоятельно прийти к решению вопроса, устраивающему все стороны. Ситуация требует вмешательства третьей стороны, внешнего арбитра. Этот пункт может показаться спорным, но, в сущности, если конфликтная ситуация успешно разрешилась без вмешательства внешнего арбитра, вопрос решён успешно и отношения сторон не ухудшились, это та ситуация, к которой нужно стремиться. Мы о таком конфликте даже, скорее всего, и не узнаем, или узнаем случайно после его разрешения. Чем больше вопросов команда может решить самостоятельно, тем более эффективно она будет работать.
Ещё одна характерная черта конфликта, которой стоит коснуться — степень эмоционального накала при решении. Конфликт не обязательно связан с высоким эмоциональным градусом. Участникам не обязательно кричать и махать руками, чтобы ситуация была, в сущности, конфликтной. Вопрос не решается, определённое эмоциональное напряжение при этом присутствует (возможно, оно не выражено вовне явно), значит, перед нами ситуация конфликта.
Нужно ли вообще вмешиваться в конфликтные ситуации, или лучше пустить их решение на самотёк и ждать, когда проблема рассосётся сама? Нужно. Не всегда в вашей власти или компетенции решить конфликт полностью, но в любой ситуации, в конфликте любого масштаба, вы можете занять взрослую позицию, тем самым выведя на неё ещё несколько человек вокруг себя, смягчить негативные последствия конфликта и поспособствовать его решению.
Перед тем как рассмотреть несколько примеров конфликтных ситуаций, остановимся на нескольких важных моментах, общих для всех конфликтов.
При решении конфликта важно быть над схваткой, а не внутри её (это ещё называют “занять метапозицию”), то есть, не оказаться в процессе решения в составе одной из сторон. В противном случае из внешнего арбитра, помогающего решению, вы лишь усилите позицию одной из сторон в ущерб другой стороне. При принятии решения важно, чтобы оно было морально принято всеми сторонами, как говорится, «куплено». Чтобы, даже если стороны и не были в восторге от принятого решения, они хотя бы были искренне согласны его исполнять. Что называется, быть в состоянии disagree and commit. Иначе конфликт просто изменит вид, тлеющий огонь останется под торфяником и в какой-то момент неизбежно разгорится снова.
Второй момент, отчасти связанный с первым — если вы уж взялись участвовать в решении конфликта, отнеситесь к этому максимально серьёзно с точки зрения коммуникаций и изучения контекста. Поговорите лично с каждой из сторон. Отдельно с каждой, для начала. Не довольствуйтесь почтой. В случае распределённой команды — поговорите хотя бы по видеосвязи. Не довольствуйтесь слухами и пересказами свидетелей. Поймите историю, чего хочет каждая из сторон, почему она этого хочет, чего ожидает, пробовали ли решить этот вопрос раньше, что будет, если он не будет решён, какие варианты решения они видят, как представляют позицию другой стороны, что, на их взгляд, правильно или неправильно, и т.д. Загрузите в свою голову весь возможной контекст, непредвзято, предполагая, что все правы. Вы не внутри конфликта, вы снаружи него, в метапозиции. Если контекст доступен только в почтовом треде — хотя бы прочитайте целиком его и относящиеся к нему обсуждению треды и документы. После того как прочитали — все равно поговорите голосом. Почти гарантированно вы услышите что-нибудь важное, чего нет в почте.
Третий важный момент — общий подход к общению. Это обычные вещи, ничего космического, но они имеют очень большое значение. Не пытаемся сэкономить время, разговариваем со всеми участниками, критикуем не человека, а рассматриваем последствия его действий (не “ты груб”, а “пожалуй, ребята могут на эту штуку обидеться”), даём возможность сохранить лицо, обсуждения проводим лично, а не перед строем.
Конфликты обычно бывают вызваны одной из двух причин. Первая связана с тем, находится ли человек в момент конфликта в позиции взрослого или в позиции ребёнка (об этом ниже). Это связано с его эмоциональной зрелостью, способностью управлять своими эмоциями (что, кстати, совсем не всегда связано с его возрастом). Вторая распространённая причина — несовершенство рабочего процесса, которое создаёт ситуации серых зон, в которой ответственность размазана между участниками, ожидания сторон не прозрачны друг для друга, роли в процессе размыты.
Соответственно, в решении конфликта (как и любого другого вопроса) менеджер должен иметь в виду три перспективы: краткосрочную — решить вопрос/конфликт здесь и сейчас, среднесрочную — минимизировать вероятность возникновения другого конфликта по такой же причине, и долгосрочную — воспитание в команде культуры взрослого человека.
В каждом из нас есть внутренний ребёнок, примерно трёх-четырёх лет. Большую часть времени на работе он спит, но иногда просыпается и берёт управление на себя. У ребёнка свои приоритеты. Ему важно настоять на том, что это его песочница, мама любит его больше, его машинка лучше всех (дизайн лучше всех, он программирует лучше всех, …). В ситуации конфликта ребёнок может прижимать игрушки, топать ногами и треснуть лопаткой, но он не может решать взрослые вопросы (архитектура решения, подходы к автоматическому тестированию, сроки релиза, и т.д), он не мыслит в терминах пользы для команды. Ребёнка в конфликте можно ободрить, утешить и отправить спать, попросив его позвать своего взрослого. Перед началом обсуждения в условиях конфликта убедитесь, что вы сейчас разговариваете со взрослым, а не с ребёнком, и сами стоите на позиции взрослого. Если ваша честная цель в данный момент — решить серьёзный вопрос, вы на позиции взрослого человека. Если ваша цель — топать ногами и треснуть лопаткой — это детская позиция. Отправьте своего внутреннего ребёнка спать и позовите взрослого, или перенесите обсуждение. Человек принимает эмоциональное решение, а затем подыскивает ему рациональное обоснование. Решение, принятое ребёнком, исходя из детских приоритетов, не будет оптимальным.
Кроме поведения в момент конфликта, детская или взрослая позиция характеризуется так же уровнем ответственности, которую человек готов взять на себя. В крайних проявлениях, детская позиция программиста, которую я встречал неоднократно, выглядит так: я код написал, отправил его на ревью — моя работа закончена. Ревьюеры должны его просмотреть и смёржить, QA должны его проверить, если будут проблемы — они мне сообщат. Как ни странно, даже довольно взрослые и опытные люди иногда ведут себя подобным образом. Другой край шкалы — человек считает себя ответственным за то, чтобы его код работал, был покрыт тестами, был проверен лично им, успешно прошёл ревью (если нужно, нет проблем попинговать ревьюеров, обсудить вопросы голосом, и т.д.) и был смёржен, QA при необходимости будет оказана помощь, описаны сценарии тестирования, и т.д. В нормальных случаях программист либо изначально находится ближе ко взрослому краю шкалы, либо смещается туда по мере накопления опыта (при условии, что в команде культивируется правильная культура). В экстремальных же случаях он продолжает работать, занимая обычно детскую позицию, тогда у него и команды периодически возникают проблемы и конфликты.
Воспитание в команде правильной, взрослой культуры — важная задача любого менеджера. Она требует длительного времени и ежедневных усилий, но результат того стоит. Есть два способа повлиять на культуру команды — личный пример (которому обязательно будут следовать, команда всегда смотрит на лидера) и обсуждение и поощрение правильного поведения. Здесь тоже нет ничего заумного или сильно формального, просто при обсуждении проблем замечайте, что здесь можно было бы сделать так-то, подчеркивайте, что заметили, когда решено правильно, похвалите, отмечайте на разборе релиза, и т.д.
Рассмотрим несколько типичных конфликтных ситуаций, от простого к сложному:
![image](https://habrastorage.org/webt/px/1g/mn/px1gmnl91hrmxi9dd58cvaozsom.jpeg)
Конфликты, не связанные с рабочими вопросами
Довольно часто на работе случаются конфликты, не связанные с рабочими вопросами. Их возникновение и лёгкость разрешения обычно напрямую связаны с уровнем эмоционального интеллекта участников, уровнем их взрослости, и не связаны с совершенством или несовершенством рабочего процесса.
Типичные примеры — кто-то недостаточно часто пользуется стиральной машиной или душем, что не нравится окружающим, кому-то душно, а другому дует, если открывать окно, кто-то слишком шумный, а окружающим нужна тишина для работы, ну и так далее. С решением конфликтов такого рода лучше не затягивать и не пускать на самотёк. Сами собой они не рассосутся и будут ежедневно отвлекать от работы и отравлять атмосферу в команде. По счастью, решить их обычно больших проблем не составляет — достаточно спокойно поговорить (разумеется, один на один) с коллегой, пренебрегающим гигиеной, обеспечить комфортную рассадку людей, которые предпочитают тишину/прохладу, купить звукопоглощающие наушники или поставить перегородки, и т.д.
Другой пример, который встречался мне за время работы несколько раз — психологическая несовместимость членов команды. По каким-то причинам люди просто не могут работать вместе, каждое общение заканчивается скандалом. Иногда это связано с тем, что люди придерживаются полярных взглядов по какому-то животрепещущему вопросу (обычно политическому) и не умеют оставлять их за пределами работы. Убеждать их потерпеть друг друга или изменить своё поведение — занятие достаточно бесперспективное. Единственное исключение, которое я встречал — молодые коллеги с открытым восприятием, их поведение еще можно постепенно изменить периодическими разговорами. Обычно вопрос успешно решается разведением их по разным командам, или, по крайней мере, обеспечением возможности крайне редко пересекаться по работе.
Во всех приведённых ситуациях со всеми участниками стоит поговорить персонально, обсудить ситуацию, поинтересоваться, видят ли они вообще проблему в данном случае, спросить, какие, по их мнению, есть пути решения, обеспечить их участие в принятии этого решения.
С точки зрения оптимизации рабочего процесса (среднесрочная перспектива, о которой я упоминал), сделать здесь можно не очень много, единственный момент для оптимизации — учитывать фактор совместимости при формировании команды и заранее не ставить вместе людей, которые будут конфликтовать.
С точки зрения культуры команды, такие ситуации возникают намного реже в командах с взрослой культурой, где люди уважают команду и коллег и умеют решать вопросы самостоятельно. Кроме того, такие конфликты решаются намного проще (часто автоматически) в командах, где высок уровень доверия, люди давно работают вместе и/или часто общаются вне работы.
Конфликты, связанные с рабочими вопросами:
Такие конфликты вызваны обычно обеими причинами сразу, и эмоциональной (тем, что кто-то из участников не находится на позиции взрослого), и несовершенством самого рабочего процесса. Самый, пожалуй, частый вид конфликтов, который я встречал — конфликты в процессе ревью кода или обсуждения архитектуры между разработчиками.
Я бы выделил здесь два типичных случая:
1) В первом случае разработчик не может добиться ревью кода от коллеги. Патч отправлен на ревью, и ничего не происходит. На первый взгляд, явного конфликта между двумя сторонами нет, но, если вдуматься, это вполне себе конфликт. Рабочий вопрос не решается, одна из сторон (ожидающая ревью) испытывает явный дискомфорт. Экстремальный подвид такого случая — разработка в коммьюнити или в разных командах, при этом ревьюер может быть не заинтересован в этом конкретном коде, в силу загрузки или других обстоятельств может вообще не обращать внимания на запрос на ревью, и внешнего арбитра (общего для обеих сторон менеджера) может вообще не быть.
Подход к решению, который помогает в такой ситуации, относится как раз к долгосрочной перспективе, культуре взрослого человека. Во-первых, работает разумная активность. Не стоит ожидать, что висящий на ревью код обратит на себя внимание ревьюера сам. Нужно помочь ревьюерам его заметить. Пингани пару человек, задай вопрос на синкапе, участвуй в обсуждениях. Очевидно, что назойливость скорее повредит, чем поможет, нужно включать здравый смысл. Во-вторых, хорошо работает предварительная подготовка. Если команда понимает, что и почему происходит, зачем этот код вообще нужен, дизайн был обсуждён и согласован заранее со всеми, люди скорее обратят внимание на такой код и примут его в работу. В третьих, работает авторитет. Если ты хочешь, чтобы тебя ревьюили — делай много ревью сам. Делай качественные ревью, с реальными проверками, реальными тестами, полезными комментариями. Если твой ник известен в команде с хорошей стороны, больше шансов, что на твой код обратят внимание.
С точки зрения рабочего процесса, возможные улучшения здесь — правильная расстановка приоритетов, направленная на то, чтобы помочь разработчику достигать своих целей и целей команды (делать ревью других, писать письма в коммьюнити, сопровождать код описанием архитектуры, документацией, тестами, участвовать в обсуждениях с коммьюнити, и т.д.), не допускать слишком долгого зависания патчей в очереди, и так далее.
2) Второй распространённый случай конфликтов при ревью кода или дизайна — разные взгляды на технические вопросы, стиль кодирования, выбор инструментария. Огромное значение при этом имеет уровень доверия между участниками, принадлежность к одной команде, опыт совместной работы. Тупик наступает тогда, когда кто-то из участников занимает детскую позицию, не пытается услышать, что ему хочет донести собеседник. Часто при этом и подход, предложенный другой стороной, и подход, предложенный изначально, вполне могут успешно работать и не имеет принципиального значения, какой именно выбрать.
Как-то раз программист из моей команды (назовём его Паша) подготовил патч с изменениями в систему развёртывания пакетов, которую разработали и поддерживали коллеги из соседнего департамента. У одного из них (Игоря) было своё сильное мнение относительно того, как именно нужно настраивать сервисы Линукса при развёртывании пакетов. Это мнение отличалось от подхода, предложенного в патче, и договориться у них не получалось. Как обычно, сроки поджимали, и было нужно прийти к какому-то решению, нужно было, чтобы кто-то из них занял взрослую позицию. Паша признавал, что оба подхода имеют право на жизнь, но ему хотелось, чтобы его вариант прошёл, т.к. явных технических преимуществ не было ни у одного, ни у второго варианта.
Наше обсуждение выглядело примерно так (весьма схематично, конечно, разговор был на полчаса):
— Паша, у нас через несколько дней feature freeze. Важно, чтобы мы всё собрали и начали тестирование как можно скорее. Как бы нам пройти через Игоря?
— Он хочет настраивать сервисы по другому, комментариев там налепил мне …
— И что там, большие переделки, много возни?
— Да нет, там работы на пару часов, но в итоге разницы ведь нет, и так, и так будет работать, зачем это нужно? Я сделал работающую вещь, давай её и примем.
— Слушай, а сколько уже вы это всё обсуждаете?
— Да уже недели полторы топчемся.
— Эм … мы можем за пару часов решить вопрос, который уже занял полторы недели, и не делаем этого?
— Ну, да, но мне не хочется, чтобы Игорь подумал, что я прогнулся …
— Слушай, а тебе самому что важнее, релиз выпустить, вместе с твоим решением внутри, или Игоря забороть? Можем забороть, тогда, правда, есть хороший шанс пролететь с релизом.
— Ну … было бы прикольно, конечно, нос Игорьку утереть, но ладно, релиз важнее, согласен.
— Тебе реально так важно, что думает Игорь? Честно говоря, ему вообще более-менее по барабану, он просто хочет единого подхода в разных местах той штуки, за которую он отвечает.
— Ну, ок, давай я сделаю так, как он просит в комментариях, и начнём тестирование.
— Спасибо, Паша! Я был уверен, что из вас двоих ты окажешься взрослее, хотя Игорёк и старше тебя:)
Вопрос решился, релиз выпустили в срок, Паша особого недовольства не испытывал, т.к. он сам предложил решение и реализовал его. Игорь вообще был доволен, т.к. его мнение учли и сделали так, как он предлагал.
Другой вид такого же, в сущности, конфликта — выбор между техническими решениями/библиотеками/подходами в проекте, особенно в распределённой команде. В одном из проектов, который позиционировался, как использующий C/C++, в итоге оказалось, что технический менеджмент проекта категорически против использования STL (Standard Template Library). Это стандартная библиотека языка, которая упрощает разработку, наша команда к ней очень привыкла. Оказалось, что проект намного ближе к C, чем к C++, что не очень вдохновляло команду, т.к. менеджмент постарался и набрал реально крутых плюсовиков. При этом, американская часть команды, и инженеры, и менеджеры, работали в компании давно, привыкли к существующему положению вещей, их всё устраивало. Российскую же часть команды собрали вместе совсем недавно, за несколько недель (в том числе и меня). Российская часть команды категорически не желала отказываться от привычного подхода к разработке.
Начались бесконечные письменные обсуждения между двумя континентами, письма по три-четыре экрана летали туда-сюда, в групповой рассылке и личные, от программистов — программистам и менеджерам. Как это обычно бывает, письма такого размера никто, кроме авторов и их горячих сторонников, не читал. Чаты поскрипывали от напряжения, передавая в разные стороны многоэкранные соображения относительно технических преимуществ STL, насколько хорошо она протестирована, безопасна, и вообще, как прекрасна жизнь с ней, и как ужасна без неё.
Длилось это всё довольно долго, до тех пор, пока я наконец не понял, что мы обсуждаем технические стороны вопроса, а проблема-то в реальности не техническая. Проблема не в достоинствах или недостатках STL или сложности работы без неё. Проблема скорее организационная. Нам нужно было просто понять, как устроена компания, в которой мы работали. Раньше ни у кого из нас опыта работы в такой компании не было. Дело было в том, что после разработки кода и выпуска его в production, поддержкой занимались совершенно другие люди из других команд, из других стран. Эта огромная инженерная команда из нескольких десятков тысяч инженеров (в совокупности) могла себе позволить только совершенно базовый минимум технических средств, так сказать, minimum minimorum. Всё, что выходило за рамки инженерного стандарта, сложившегося в компании, физически не могло быть поддержано в дальнейшем. Уровень команды определяется уровнем слабейших её членов. После того как мы поняли реальную мотивацию действий американской части команды, этот вопрос был снят с повестки дня, и мы все вместе успешно разработали и выпустили продукт, используя стандарты, принятые в компании. Письма и чаты в этом случае работали плохо, чтобы прийти к общему знаменателю, понадобилось несколько поездок и много личного общения.
С точки зрения рабочего процесса, в этом конкретном случае, помогло бы наличие описания используемых средств, требования к ним, ограничения на добавление новых, обоснование таких ограничений. Такие документы примерно соответствуют описанным в пунктах Reuse Strategy и Development Environment руководства “Manager's Handbook for Software Development”, разработанного в NASA. Несмотря на свой возраст, он прекрасно описывает все основные активности и этапы планирования разработки ПО подобного рода. Наличие подобных документов очень упрощает процесс обсуждения того, какие компоненты и подходы могут быть использованы в продукте, и почему.
С точки зрения культуры же, очевидно, при более взрослой позиции, при которой стороны пытаются услышать и понять реальную мотивацию действий коллег и действуют исходя из приоритетов проекта и команды, а не личного эго, конфликт бы решился проще и быстрее.
В другом конфликте из-за выбора технического решения мне тоже понадобилось заметное время, чтобы понять мотивацию одной из сторон (очень уж необычный был случай), но, после того как мотивация была ясна, решение было очевидно.
Ситуация такая: в команде из примерно 20 человек появляется новый разработчик, назовём его Стас. Нашим стандартным инструментом для общения в команде был на тот момент скайп. Как потом выяснилось, Стас был большим фанатом открытых стандартов и опенсорсного ПО, и пользовался только инструментами и операционными системами, исходники которых доступны публично, и которые используют описанные публично протоколы. Скайп к таким инструментам не относится. Мы потратили уйму времени на обсуждения достоинств и недостатков этого подхода, попыток запуска аналогов скайпа на разных операционных системах, попытках Стаса убедить команду перейти на другие стандарты, писать ему персонально по почте, звонить ему персонально по телефону, купить ему второй компьютер специально для скайпа, и т.д. Наконец я понял, что это проблема, в сущности, не техническая и не организационная, она скорее мировоззренческая, даже, можно сказать, религиозная (для Стаса). Даже если бы мы в итоге соединили Стаса и скайп (на что уже ушло несколько месяцев), на любом следующем инструменте проблема возникла бы снова. У меня в распоряжении не было реальных средств изменить мировоззрение Стаса, и не было оснований пытаться изменить мировоззрение команды, которая прекрасно работала в этом окружении. Человек и компания просто были ортогональны по мировоззрению. В подобных ситуациях хороший вариант решения — организационный. Мы перевели Стаса в другую команду, где он был более органичен.
Причина этого конфликта, на мой взгляд, в несоответствии личной культуры конкретного человека (у которого есть сильное мнение, не позволяющее ему идти на компромиссы), культуре компании. В данном случае это, конечно, ошибка менеджера. Было изначально неправильно брать его на проект подобного рода. Стас в итоге перешёл на проект по разработке открытого ПО и прекрасно там преуспел.
Хороший пример конфликта, вызванный одновременно детской позицией разработчика и недостатками рабочего процесса — ситуация, в которой в отсутствие definition of done у разработчика и QA команды есть разные ожидания относительно готовности фичи, переданной в QA. Разработчик считал, что достаточно написать код и перекинуть фичу через забор в QA — там разберутся. Довольно взрослый и опытный, кстати, программист, но такой уж у него был внутренний порог качества. QA с этим были несогласны и требовали показать и описать им, что он проверил сам, и требовали сценарий тестирования для них. Они уже имели в прошлом проблемы с функционалом от этого разработчика и не хотели тратить своё время зря ещё раз. Кстати, они были правы — фича действительно не работала, код перед передачей в QA он не проверил.
Для решения ситуации я попросил его показать мне, что всё действительно работает (оно не работало, и ему пришлось чинить), мы проговорили с командой и с QA definition of done (делать его письменным не стали, т.к. не хотели слишком бюрократизировать процесс), ну а с этим специалистом мы вскоре расстались (к общему облегчению).
С точки зрения рабочего процесса возможные улучшения в данном случае — наличие definition of done, требования к сопровождению каждой фичи юнит и интеграционными тестами, описание тестирования, проведённого разработчиком. В одном из проектов мы замеряли уровень покрытия кода тестами во время CI и в случае, если уровень покрытия после добавления патча, падал, тесты помечались как непройденные, т.е. любой новый код мог быть добавлен только при наличии новых тестов для него.
Ещё один типичный пример конфликта, тесно связанного с организацией рабочего процесса. У нас есть продукт, команда разработки этого продукта, команда поддержки и заказчик. У заказчика возникают проблемы с продуктом, он обращается к поддержке. Поддержка анализирует проблему и понимает, что проблема в продукте, передаёт проблему продуктовой команде. У продуктовой команды горячая пора, релиз на подходе, поэтому тикет с проблемой от заказчика, затерявшийся среди остальных тикетов у разработчика, которому он назначен, висит несколько недель без внимания. Поддержка думает, что разработчик работает над проблемой заказчика. Заказчик ждёт и надеется, что над его проблемой работают. В реальности ничего пока не происходит. Через несколько недель заказчик, наконец, решает поинтересоваться прогрессом и спрашивает у поддержки, как дела. Поддержка спрашивает разработку. Разработчик вздрагивает, просматривает список тикетов и обнаруживает там тикет от заказчика. Читая тикет от заказчика он понимает, что информации для решения проблемы недостаточно, и ему нужны ещё логи и дампы. Поддержка запрашивает дополнительную информацию от заказчика. И тут заказчик понимает, что над его проблемой всё это время никто не работал. И грянет гром …
В этой ситуации решение самого конфликта довольно очевидно и линейно (починить продукт, обновить документацию и тесты, умиротворить заказчика, выпустить хотфикс, и т.д). Важно проанализировать рабочий процесс и понять, кто несёт ответственность за организацию взаимодействия между двумя командами, почему такая ситуация вообще стала возможной. Понятно, что нужно починить в процессе — кто-то должен мониторить общую картину без напоминаний от заказчиков, проактивно. Тикеты от заказчика должны выделяться среди остальных тикетов у разработчиков. Поддержка должна видеть, работает ли разработка над её тикетами в настоящий момент, если нет — когда сможет начать работать, когда можно ожидать результата. Поддержка и разработка должны периодически общаться и обсуждать статус тикетов, сбор нужной для отладки информации должен быть максимально автоматизирован, и т.д.
Как на войне противник старается ударить в стык между двумя подразделениями, так и в работе самым тонким и уязвимым местом обычно оказывается взаимодействие между командами. Если менеджеры поддержки и разработки достаточно взрослые, они смогут починить процесс самостоятельно, если нет — процесс будет продолжать генерировать конфликты и проблемы, пока не вмешается менеджер, который сможет починить ситуацию.
Другой характерный пример, который я встречал неоднократно в разных компаниях — ситуация, в которой продукт пишется одной командой, автоматические интеграционные тесты для него — второй командой, инфраструктура, на которой это всё эксплуатируется, сопровождается третьей командой. Проблемы при прогонах тестов возникают постоянно, и причиной проблем в них может быть как продукт, так и тесты и инфраструктура. Проблематичным обычно бывает договориться, кто должен производить первичный анализ проблем, файлить баги, парсить логи продукта, тестов и инфраструктуры, и т.д. Конфликты здесь весьма часты, и, в то же время, единообразны. В случае высокого эмоционального накала участники часто сваливаются в детскую позицию и начинаются обсуждения из серии: “почему я должен с этим ковыряться”, “у них чаще ломается”, и т.д.
С точки зрения рабочего процесса конкретные шаги для решения вопроса зависят от состава команд, вида тестов и продукта, и т.д. В одном из проектов мы ввели периодические дежурства, при которых команды следили за тестами по очереди, по неделе. В другом первичный анализ всегда проводили разработчики тестов, но при этом анализ был весьма базовый и продукт достаточно стабилен, так что это неплохо работало. Главное — обеспечить прозрачность процесса, ясность ожиданий для всех сторон и ощущение справедливости ситуации для всех.
Является ли вообще конфликт в организации проблемой, плохой ли это признак, что в вашей команде часто (или просто периодически) случаются конфликты? В целом, нет, ведь если происходит рост, развитие, есть какая-то динамика, то возникают вопросы, которые никогда не решались раньше, при их решении могут возникать конфликты. Это индикатор того, что на какие-то области нужно обратить внимание, что есть области для улучшений. Плохо, если конфликты возникают очень часто, решаются трудно или долго. Это, скорее всего, признак недостаточно отлаженных рабочих процессов и недостаточной взрослости команды.