суббота, 29 февраля 2020 г.

Как достичь цели

Несколько полезных для начинающих разработчиков статей:
Как разработчику понять, что он готов искать первую работу
Как 65 разработчиков-новичков без опыта в программировании получили свою первую работу
Как найти первую работу в IT: план действий для начинающих
Как разработчику-самоучке найти первую работу
Как стать Java разработчиком за 1,5 года
Поиск первой работы: советы разработчику
Первая работа в IT: получаем должность без опыта
Как научиться программировать с нуля и найти первую работу. Большой FAQ от Reddit
Мои странные правила, благодаря которым я получил работу

В статьях много и несколько туманно пишут о том, что можно изложить в трёх пунктах:

1. Составь план. 
Любой. Пусть он будет самым общим, без конкретных цифр. Лишь бы он был реальным и следование ему вело тебя к цели.

2. Следуй плану.
Без активных действий с твоей стороны - никак. Под лежачий камень вода не течёт. Путь в тысячу лье начинается с одного шага. И т.д. Не будешь следовать плану, не сможешь его выполнить.
Есть одна притчу про один шаг вперёд и два шага назад. Так вот, каждый день, когда ты следуешь плану - это шаг вперёд к твоей цели. Каждый день, который ты не следовал плану - это два шага назад.
Если при следовании плану ты понимаешь, что нужно скорректировать план - это нормально. Корректируй и следуй ему дальше. Главное при этом - видеть свою цель и понимать, что корректировка плана не отдаляет тебя от цели.

3. Учись.
Учись всегда и везде тому, что нужно для выполнения твоего плана и его корректровки. Постоянная практика - часть учёбы. Без практики, изучение только теории малоэффективно. Если цель - изучить язык программирования, то решай задачи, пиши мини-проекты. Чем больше практики, тем лучше.

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

Должен ли я читать книги?


Оно мне вообще надо - читать книги?
Конечно надо! На собеседованиях постоянно просят наизусть декламировать отдельные определения или даже целые главы из "Чистого кода", "Чистой архитектуры", книг "Банды Четырёх" и других классических трудов.
Шучу.
Ну, кому ещё это может понадобиться, кроме преподавателей-теоретиков в вузе? Хотя, у меня пару раз на собеседованиях придирались к неточным формулировкам.
Так что, не боись теории, но и "булки не расслабляй".


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

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

Книги - и всё, этого достаточно?
Нет. Книги - это теория. Иногда, в книге на 600 страниц может быть поверхностно рассмотрен только один какой-нибудь вопрос. Для получения ответа на вопрос "как это использовать" нужно читать документацию. Книга - это чуть более подробный и широкий, чем статья, обзор технологии. Или что-то вроде сборника статей на одну тему.
Искать то, как использовать те или иные аспекты определённой технологии, лучше всего в официальной документации по этой технологии. Если она есть.

А что читать?
Вот тут обсуждается список книг, которые должен прочитать каждый программист.
Если коротко, то это:
1. The Pragmatic Programmer by David Thomas & Andrew Hunt (67% recommended)
2. Clean Code by Robert C. Martin (66% recommended)
3. Code Complete by Steve McConnell (42% recommended)
4. Refactoring by Martin Fowler (35% recommended)
5. Head First Design Patterns by Eric Freeman / Bert Bates / Kathy Sierra / Elisabeth Robson (29.4% recommended)
6. The Mythical Man-Month by Frederick P. Brooks Jr (27.9% recommended)
7. The Clean Coder by Robert Martin (27.9% recommended)
8. Working Effectively with Legacy Code by Michael Feathers (26.4% recommended)
9. Design Patterns by by Erich Gamma / Richard Helm / Ralph Johnson / John Vlissides (25% recommended)
10. Cracking the Coding Interview by Gayle Laakmann McDowell (22% recommended)
11. Soft Skills by John Sonmez (22% recommended)
12. Don’t Make Me Think by Steve Krug (19.1% recommended)
13. Code by Charles Petzold (19.1% recommended)
14. Introduction to Algorithms by Thomas H. Cormen / Charles E. Leiserson / Ronald L. Rivest / Clifford Stein (17.6% recommended)
15. Peopleware by Tom DeMarco & Tim Lister (17.6% recommended)
16. Programming Pearls by Jon Bentley (16.1% recommended)
17. Patterns of Enterprise Application Architecture by Martin Fowler (14.7% recommended)
18. Structure and Interpretation of Computer Programs by Harold Abelson / Gerald Jay Sussman / Julie Sussman (13.2% recommended)
19. The Art of Computer Programming by Donald E. Knuth(10.2% recommended)
20. Domain-Driven Design by Eric Evans (10.2% recommended)
21. Coders at Work by Peter Seibel (10.2% recommended)
22. Rapid Development by Steve McConnell (8.8% recommended)
23. The Self-Taught Programmer by Cory Althoff (8.8% recommended)
24. Algorithms by Robert Sedgewick & Kevin Wayne (8.8% recommended)
25. Continuous Delivery by Jez Humble & David Farley (8.8% recommended)
На каком языке читать?
На английском - если хорошо его знаешь, хочешь прокачать или никуда не торопишься.
На твоём родном - во всех остальных случаях.

понедельник, 24 февраля 2020 г.

Кто я: junior, middle, senior?

Если меня спрашивают, какого уровня я разработчик, что мне ответить? 
Во времена моей молодости была популярной реклама одного безалкогольного напитка: "Имидж - ничто, жажда - всё". Этой фразой можно ответить на часть вопроса в том смысле, что неважно, как меня назовут (на какую должность примут на работу), хоть пряником, главное - сколько мне за это будут платить.
Понятие уровня разработчика - относительное. В одной компании можно числиться несколько лет синьором и получать ХХХ рублей в месяц, а потом перейти в другую компанию на должность джуна и получать 2 х ХХХ рублей в месяц.
Обычно, вопрос о том, к какому уровню ты себя относишь, задают HR-ы в тот момент, когда приходит пора обсудить размер зарплаты, или начинающие программисты, когда неуверены в своих силах и хотят найти себе ментора или понять, насколько их знания широки и глубоки. Для HR-ов это имеет значение потому, что они привязывают такой уровень к размеру зарплаты и прочим "плюшкам", предоставляемым компанией в зависимости от уровня. Для начинающих программистов уровень имеет значение потому, что они, по причине своей неопытности, считают этот уровень синонимом знаний и опыта.
Приведу пример.
Когда я в первый раз искал работу программистом, было у меня несколько собеседований, по итогам которых интервьюеры сразу давали обратную связь. Обычно, такие собеседования проводились с участием технических (разработчики, тех.лиды) и нетехнических (HR, менеджер) специалистов. Когда HR/менеджер в конце собеседования задавал техническому специалисту вопрос, какого я уровня как  разработчик, те, иногда задумавшись на пару секунд, иногда сразу, отвечали "крепкий/средний middle". Мне это льстило, т.к. к тому времени я только окончил курс java-разработчика, был неопытным и считал, что я, скорее всего, junior. Все же должны начинать с junior-а!
Позже, когда я искал своё следующее место работы, мне так же по результатам собеседований иногда говорили, что я "крепкий/средний middle". Я обижался, т.к. постоянно много учился, читал книги, статьи и смотрел обучающие видео по программированию. Поэтому такого просто не могло быть, чтобы мои навыки и знания не сдвинулись ни на шаг с места под названием "крепкий/средний middle" и я не стал хотя бы "младшим senior-ом" или кем-то вроде того.
Позже я понял, что звание/должность - это вопрос, скорее, денежный, чем реально отражающий знания и опыт программиста. В каждой организации есть свой бюджет и своя тарифная сетка. И звание "middle" или "senior" означает лишь, что компания готова тебе платить XXX или YYY рублей в месяц и это не всегда зависит от твоих знаний ил опыта. Это как кодовые фразы, которыми обмениваются нетехнический (НТС) и технический (ТС) специалисты:
НТС: "Кандидат хочет ХХХ рублей в месяц. Мы потянем?"
ТС: "Бюджет трещит по швам. Попробуй поторговаться?"
Конечно, же речь в этом случае может идти не только о деньгах, но и об опыте, знаниях, личных качествах кандидата.
Поэтому теперь мои собственные давние переживания по поводу того, как меня называют, кажутся мне смешными.

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

воскресенье, 23 февраля 2020 г.

Если я без опыта, то вакансии с какой зарплатой мне искать?

Формула, проверенная поколениями программистов:
Зарплата = сумма расходов в месяц + ещё не менее 30%

Только нужно помнить, что "расходы в месяц" - это не только расходы на метро, 2 кг. гречки и 3 десятка яиц.
Да-да, были энтузиасты, которые считали, что вполне себе реально первые год - полтора поработать в Москве на зарплату в 25 - 30 т.р. в месяц и только потом искать работу с более высокой зарплатой.
Поверь, это не так.  На такую зарплату ты долго не протянешь.Поэтому "сумма расходов в месяц" - это размер расходов, которые ежемесячно несёт обычный средний работник в том городе, где тебе предстоит работать. Они включают в себя:
- проезд,
- питание,
- лекарства,
- одежду,
- обувь,
- и другие подобные расходы на тебя и членов твоей семьи (семья - на первом месте).
С размером таких расходов проще всего определиться тем, кто уже работает и знает, сколько его семья тратит в месяц.
Для тех, кто никогда не работал и не знает - спросить у мамки/папки/друзей. )

30% - это нередвиденные расходы. А они всегда будут. К тому же, в чём смысл идти работать на зарплату, которая покроет только минимальные потребности и не позволит, например, сводить детей в кино, а жену - в театр?

Почему не стоит соглашаться на меньшее?
Зачем? Какой в этом смысл? Мы ж не биороботы, предназначенные только для того, чтобы за наш счёт хорошо жил кто-то другой?
Проводя большую часть сознательной жини на работе, мы должны иметь возможность чем-то это компенсировать. Для кого-то это будет возможность играть влюбимые игры, для кого-то путешествовать, заниматься спортом, ходить на культурные меропрития.

Авторы книг и статей, посвящённых торгам о зарплате, сходятся в одном мнении: всегда нужно пробовать торговаться по зарплате. Каждые 10_000 руб. в месяц, бороться за которые ты не стал, в течение года превратяться в 120_000 руб... Всегда помни об этом.

Рыночные отношения

Рынок труда - это слова, обозначающие не только сферу отношений, входя в которую одни люди становтся работниками, другие - работодателями.
Исходя из буквального значения слова, рынок - это также место, где торгуются. Работники и работодатели торгуются относительно стоимости и качества работы.

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

Быть конкурентоспособным.
Это значит: иметь знания и опыт, которые помогут лучше выделиться среди остальных кандидатов. Знания - это результат учёбы в любом виде (самостоятельно, с ментором, на курсах, в ВУЗе, на практике). Опыт - это не то, сколько лет ты просидел на работе с 9 до 18. Это то, какие проблемы ты умеешь решать.
Знать фреймворк - это одно. Уметь с его помощью решать конкретные проблемы - это немного другое. Отсюда, основной способ повысить свою конкурентоспособность - изучать нужные рынку технологиии и писать на них свои мини-проекты.

Соответствие ожиданиям рынка.
Почти никому не нужно будет твоё умение написать код на Бэйсике.
И очень многие захотят нанять тебя, если ты знаешь Java.
Как понять, что сейчас востребовано?
Идём на любой ресурс для поисска работы и смотрим, в каких работниках нуждается рынок.

Устанавливать на свой товар адекватную цену.
Это сложный процесс, в ходе которого возникает много дополнительных вопросов:

Как узнать, сколько стоит товар?
Спросить, помониторить рынок, сходить на несколько пробных собеседований и вывести среднее значение или минимум-максимум.

Как понять, что мой товар - этот, про который везде пишут и говорят, что он стоит ХХХ рублей в месяц?
Только практическим путём: ходить на собеседования, получать предложения о работе, торговаться.

А что, если с моим товаром всё хорошо, но мне предлагают за него на YYY рублей в месяц меньше?
Торговаться.
Теме торгов я посвящу одну из следующих статей.

Шуточная лямбда


public class HowToBecomeProgrammer {
    public static void main(String[] args) {
        JavaDeveloper developer = Arrays.stream(someMan) 
            .filter(c -> !"kishka tonka".equals(c.getProperty()))
            .map(JavaDeveloperCourse::createDeveloper)
            .findFirst()
            .orElseThrow(() -> new RuntimeException("YOU ARE NOT READY YET")); 
    } 
}

Про "интересные" задачи на собеседованиях

Одно время очень популярными на собеседованиях были так называемые задачи "с подвохом".
Например:
Как изменить код программы, чтобы она компилировалась и выводила в консоль "Right", при этом не изменяя код первого метода.
public class Main {
    public static void main(String[] args) {
        System.out.println("Wrong");
    }
    public static void main(String[] args) {
        System.out.println("Right");
    }
}

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

(с) Вячеслав
Я уже прочитал ответ. Эта задачка попала бы в доклад на джокере упоротые вопросы для собеседования)
(с) Сергей
 Задача, чтобы посмотреть:
1) насколько адекватна реакция кандидата на тупой вопрос,
2) читал ли кандидат статью "Как пройти собеседование в ${company-name}"
(с) Михаил
Мне такие задачи напоминают модные в школах в начале 1990-х "задачи на логику". Вот одна из них, правда, из анекдота:
"Летят 3 гуся: 1 серый и 2 белых. Сколько мне лет?"
Когда задают такой вопрос, в голове крутится только один вопрос: "Что?"
Чтобы на интервью решить такую задачу "правильно", нужно предварительно прочитать ту самую статью про "Как пройти собеседование...".
Кстати, у задачи про гусей есть правильный ответ: 22. Чтобы узнать почему 22, нужно найти и прочитать анекдот.

Работа на "серую" компанию

В интернетах часто возникают вопросы про работу на компанию, в которой зарплата выплачивается по "серой" схеме.

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

Если получать деньги за код - это всё, что тебе нужно и других вариантов нет, то такая компания - может оказаться неплохим вариантом.

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

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

Карьерный рост в такой компании - штука относительная. У нас в должности Java Architect работал системный администратор без высшего образования, с опытом работы пару лет и самостоятельно нахватавшийся основ Java. После банкротства он никуда архитектором, естественно, не устроился. Нашёл работу то ли системным администратором, то ли инженером по DevOps. 

Отношения между мной и работой

Раз уж так сложилось, что у меня есть работа, а у работы есть я, то какие между нами отношения?
Работу мне даёт бизнес. Что нужно мне от работы, я уже писал раньше.
Но, что нужно от меня бизнесу (работе) и, как я могу ему в этом помочь без ущерба для себя?
Бизнесу нужен доход (прибыль). Нужно, чтобы то, что я делаю, приносило бизнесу прибыль. Этот вывод простой и сложный, одновременно.

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

Конечно, все понимают, что ключевыми словами для большинства из перечисленного являются:
- качественно,
- правильно,
- для проекта.

Если эти слова можно подставить в описание того, что я делаю для работы и смысл написанного не изменится, значит, я не зря получаю свои деньги.

Зачем мне нужна работа

Иногда случается задуматься над вещами, которые кажутся очевидными.

Зачем мне нужна работа?
Можно жить, не работая. Я проверял. Раходы снижаются до минимума. Но они всё равно есть, даже если жить своим хозяйством или за счёт родственников. Т.е. очевидный и правильный ответ на этот вопрос: чтобы были деньги, на которые можно... и т.д.

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

И всё-таки, почему мне нужна именно эта работа?
В сутках 24 часа, из которых:
- 8 часов - это установленная медициной средняя оптимальная продолжительность сна,
- 9 часов - установленное законом время работы (включая 1 час на обед),
- 7 часов - время, которое остаётся на семью, на дорогу к месту работы и обратно, на подготовку к работе, отдых после работы, учёбу, хобби и т.д.
Выходит, что на работу человек выделяет больше времени, чем на любое другое занятие. И так происходит 5 (или 6) дней в неделю и около 250 дней в году.

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

Неуловимый баг

Давно не писал сюда. Было много дел и интересных проектов. Нужно было прочитать много интересных книг и найти новую работу.

Надеюсь, найду время рассказать тут обо всём самом интересном.
Сегодня решил поделиться забавным случаем: как я искал неуловимый баг.

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

Понедельник. Видим, что тест упал в воскресенье.
По результатам исследования логов вижу, что один из сервисов выбрасывает исключение OptimisticLockingException. Такое исключение выбрасывает Hibernate, когда разные потоки пытаются одновременно внести изменения в какую-нибудь сущность и сохранить их в базе данных.
В сервисе, выбросившем исключение, вперемежку используются синхронные (REST) и асинхронные (Apache Kafka) вызовы.
Предполагаю, что асинхронно вызванный метод конфликтует с синхронно вызванным методом за изменение одной из сущностей и сохранение её в базу данных.
Добавляю между двумя тестами паузу, прогоняю несолько раз "зелёные" тесты, рапортую об исправлении бага.

Вторник. Ночью упал тот же самый тест, что и в прошлый раз.
Возможно, паузы между тестами тут не при чём...
Запускаю сервисы и тесты локально и удалённо, читаю скудные логи сервисов и тестов, развёрнутых на dev и staging площадках.
"Брутфорс" не даёт результатов.
Добавляю в ответственные участки кода тестов и сервиса логирование каждого шага и жду нового падения тестов.
Тесты весь день "зелёные". Начинаю подумывать об исправлении бага за счёт "эффекта наблюдателя" (добавил логи).

Среда. Ночное падение тестов.
Читаю логи. Вижу проблему: один из сервисов получает от другого сервиса 1 запрос и возвращает на него 2 идентичных ответа. Через Кафку возвращает. Асинхронно.
Как говорил Шерлок Холмс: отбросьте невозможное и оставшееся, каким бы невероятным оно ни было, и будет ответом на ваш вопрос.
Сыщик из меня неочень хороший. Поэтому первая моя рабочая гипотеза была такой: где-то в сервисе завёлся поток-призрак (или процесс), который возвращает второй ответ. Невероятно? Ещё бы! Следовательно, по Конан Дойлю, это и есть правильный ответ.
Задвигаю сомнения подальше, начинаю с энтузиазмом прорабатывать свою невероятную версию.
Не нахожу ответа. Внимательно смотрю в логи. Вижу то, что меня смущает: в ответ возвращается сущность, сохранённая в базу данных под уникальным ID и в ответах-близнецах ID возвращаемой сущности всегда одинаковый. Да, быть такого не может, чтобы 2 раза отработавший метод сохранил одну и ту же сущность в базу данных под одним и тем же ID!
Лезу ещё раз в код метода...

Итог оказался таким: код метода, ответственный за возвращение ответа, был продублирован. Произошло это, судя по всему, при разрешении мерж-конфликта.
Тесты этого не видели, т.к. не проверяли, сколько раз этот метод дёргает другие методы и, сколько ответов возвращает.

Выводы?
Побольше логов на стадии отладки.
Внимательно разрешать мерж-конфликты.
Писать тесты, проверяющие не только выдачу методом правильного ответа, но и всё остальное поведение кода: какой код и сколько раз вызывается из метода.