Комментарии 99
Правда два месяца — совсем немного. Я просидел 6 лет одновременно изучая UDK/UE4, программирование и игру-мечты которую хотел сделать в режиме ММО, я не хвастаюсь, тут нечем хвастаться, очень много времени потратил топчась на месте, ну хоть программировать научился, а игры делать — нет.
Как-то одновременно грустно и страшно, грустно что ошибся и не осилил, страшно признать свою ошибку, в теории там все просто, а вот на практике без опыта, анрил.
К сожалению мысли слишком идеализированны и абстрактны, мне показалось что скопировать готовую сингловую игру и потом уже как нибудь ее переделывать под свои хотелки несложно, к черту продумывание и документирование, на ходу решу, ага.
Смирился, решил зайти с другой стороны на которую изначально забил — геймдизайн.
Дубль 2, часть 1.
многие из них вязнут в большом проекте, это частая беда
даже опытные люди, выпустившие не одну игру, бывает, увязают в новой игре и не могут выпустить ее год, хотя по виду она — двухмерная простая фигня, которую так и хочется оценить максимум в 2 недели. В одну, если графика уже есть.
Особенно страшно это проявляется в работе над собственным проектом (ещё хуже, если в одиночку). Ты вроде бы пишешь, пишешь, а всё не идеально, а нужно, чтобы было лучше всех — не зря же старался! И ты никогда не закончишь, если не поймёшь, что идеального ничего не бывает, есть достаточно хорошее, чтобы быть идеальным.
Спасает одно — понимание, что не ты один такой. "Вон, люди даже в ядре Linux ошибки и баги допускают, а ты? Ты здесь написал лучше, чем они!" — говоришь себе, и успакаиваешься. Просто держишь планку, не опускаясь в совсем грязь, но и не пытаясь переплюнуть гору. Не быть же всегда идеальным.
У меня нет инстаграма!
Чуваки заново изобрели парное программирование. Поздравляю!
По поводу парного программирования, свежих взглядов, переработок, сопернической атмосферы в коллективе — все уже было описано в книге Роберта Мартина, «Идеальный Программист». И истории, кстати, очень похожие в книге представлены
Я вообще не программист. Но «подумать об кого-то» — это и правда обычно лучше всего помогает сдвинуть с места глыбу, об которую ты уже почти надорвался в одиночку.
Но меня вот смутили моменты "Код надо было писать на C#, с которым он никогда не работал, поэтому в голове промелькнуло — потрачу кучу времени бестолку." и "Из меня js-ник, как из гофера дженерик, но я действительно ему помог.". На senior-уровне удивительно видеть удивление, что один опытный разработчик может давать разумные советы разработчику на другом языке. Ладно, если бы хотя бы один из них писал на чем-то «радикальном-маргинальном», но почти все коммерческие ЯП (C#, Java, JS, Go, C и даже С++ иногда, Python, Ruby, PHP, Object Pascal, VB и даже 1С) на этом уровне очень-очень похожи. Да, «ревьюер» должен принять, что оформление кода и многие моменты реализации другие, не должен через слово повторять «а вот у нас в [моя платформа] всё было бы лучше», но это к этому моменту (senior же!) уже должно быть гигиеническим навыком. Иначе как такой «senior» будет адаптироваться к деталям code style и к коду «соседних» команд?
Ну да, конечно есть куча «непохожих»: функциональные, как Haskell, Lisp, F# и прочие OCamlы (а знаете как увольняют хаскель-программиста? «собирай свои монадки и уматывай!» (с) Башорг :) ), с непривычной системой типов, как в Scala, или, наоборот, низкоуровневые — ассемблер, с непривычной семантикой памяти (Rust), логические (Prolog), очень специфичные по предметной области (Verilog) и т.п. В этом случае барьер не столько языковой, сколько понятийный. Но и даже здесь есть ислючение — декларативный SQL, который так или иначе на базовом уровне знает не меньше половины программистов «традиционных» языков.
Так что для опытного разработчика не нужно удивляться, что другой опытный разработчик может прочитать код на другом языке и оценить решение.
С, С++, Java, C#, JS, PHP
Я в таких случаях сначала пишу так, чтобы работало, очень грязно и очень тупо :)
Если и это не помогает, то нужно переключиться на задачу с другой стороны — например, уйти от попытки выстраивать нижний слой абстракции и перейти сразу к верхнему, начать писать систему с другой стороны.
Как вариант — просто создать новый репозиторий и потихоньку подглядывать в старый (из говнокод-проектов примерно 10% кода оказались полезными, +понимание ограничений, с которыми можно столкнуться)
За говнокод действительно надо бить по рукам, только вот такой метод — реально работает. Когда ты пишешь что-то, что уже работает, но криво, в процессе в 99% случаев понимаешь как сделать это хотя бы немного лучше.
Многие вещи, о которых сразу и не подумаешь выползают уже на реализации. И наоборот, то чего сильнее всего опасался вообще не будет играть большой роли.
Сидеть и теоретизировать до бесконечности придумывая идеальное решение тоже не выход. Зачастую реализация может подсказывать пути хороших решений.
Так что нужен баланс.
Просто сидеть и придумывать идеальную архитектуру не написав ни единой строчки кода тоже не вариант.
Нужны итерации, пускай даже для себя.
Так должна вырисовываться хорошая архитектура.
На этапе прототипирования говнокод — единственный выход, особенно если решаешь задачу, с которой раньше не встречался. Если у вас заказчик здорового человека — он прекрасно понимает, что первые несколько написанных версий кода — говнокод в любом случае. Обычно в новой итерации я использую около 20-30% ранее написанного кода (покрытого тестами, естественно), что позволяет, с одной стороны, свежим взглядом посмотреть на архитектуру, а с другой — не переписывать код, который уже работает
А я в Groovy… «знаю что функции обьявляются словом def». Сели вместе разбирать. Он пытается в vim обьять необьятное, я говорю: «Не мучайся, закинь в IntellJ там навигация, сразу тебе покажет где какая функция вызвается.… Нет, никому не скажу.» Прощелкали все, он мне по ходу рассказывает как там контейнеры разворачиваются, я ему рассказываю, как тут замыкание в функцию передается. Слово за слово и скрипт кончился. Потратили не больше часа, а до этого у него аж волосы дыбом стояли от ступора.
Под кластером понимается тут конгломерат из контейнеров в которых живут сервисы и службы. Jenkins это серверное ПО для автоматизации в частности для сборки. Groovy — язык программирования широкого назначения.
По общему смыслу, скрипт настраивал все службы на топологию серверной части.
Docker позволяет запустить приложение в ограниченом окружении (т.н. контейнере) и отделить его от других приложений. Все приложения заворачиваются в контейнеры.
Чтобы построить полезный сервис для пользователя, там давно уже не только apache, php, mysql, там куча всяких серверных программ, нацеленных как на сам процесс разработки, jira, git, sonar и т.д. так и на обеспечение сервиса и его надежной работы: быстрый поиск, искуственный интеллект, репликация данных и т.д. Если архитектура на микросервисах, там вообще каждый микросервис в своем контейнере может жить. Этих контейнеров сотни тысяч могут быть. Ты ими в ручную уже не сможешь управлять. У тебя есть сервис для этого, навернулся контейнер — ты не выясняешь что с ним — выкинул, вставил новый, репликация данных, и оно снова работает. В течении минут. Примерно так работает современное айти. За подробностями о каждой отдельной технологии — в гугл, потому что тема невероятно обширная.
Docker позволяет запустить приложение в ограниченом окружении (т.н. контейнере) и отделить его от других приложений. Все приложения заворачиваются в контейнеры.А зачем это делается? И как приложению в такой песочнице работать?)
быстрый поиск, искуственный интеллект, репликация данных и т.д.Искусственный интелект — это что-то связанное с нейросетями, наверное? Быстрый поиск — он вроде бы средствами СУБД неплохо делается (во всяком случае, самописные костыли чаще всего работают хуже).
Про Git не понял. Он не для пользователя нужен, а для разработчика, и должен стоять на его машине, а не на сервере. Или мы говорим про тот Git, который будет делать деплой из репозитория?
Ты ими в ручную уже не сможешь управлять. У тебя есть сервис для этого, навернулся контейнер — ты не выясняешь что с ним — выкинул, вставил новый, репликация данных, и оно снова работает.Потерю данных могут предотвратить транзакции на уровне базы данных (если они поддерживаются движком и сервером). Про остальное — не понял толком :) Какого рода «навернулся» встречаются в реальной практике? Почему помогает простой перезапуск (обычно наворачивается что-то из-за бага в исходном коде)? Зачем заворачивать сервисы в контейнеры, если можно реализовать их как обычные скрипты на PHP/Perl/Python/Go, возвращающие JSON (и дёргающие по необходимости внутренние сервисы вроде тех же движков распознавания изображений, вычисления хэшей музыкальных файлов и прочего)?
Быстрый поиск — он вроде бы средствами СУБД неплохо делается (во всяком случае, самописные костыли чаще всего работают хуже).elasticsearch и пр. конечно же я имел ввиду. Может фрилансеры-школьники и пишут костыли, но все нормальные люди собирают приложение из готовых решений.
А зачем это делается? И как приложению в такой песочнице работать?)У контейнера есть доступ к ядру системы, и доступ к виртуальной файловой системе, но настроены только те папки которые приложению нужны. Обертка получается очень легковесная. Работает оно так же как работало бы на хосте.
Контейнер заворачивает сервис со всеми его зависимостями. Например одному приложению нужен PHP 4.х, другому PHP 5.x. чтобы избежать конфликтов, все пихают в контейнеры. В том же питоне есть virtualenv, та же самая причина, питон второй нужно отделить от третьего, а еще нужно три разных версии третьего питона, потому что не все библиотеки совместимы с последними версиями языка. Приложение пишут и сдают заказчику. Начинали писать на ангуляре 1, и закончили на ангуляре 1, заказчику не нужны новейшие версии фреймворка — ему нужно работающее приложение. Завернул его в контейнер и сдал. И оно точно будет работать как работало у разработчиков на машине. Не произойдет такого, что на целевой системе тут надо еще то да се установить, конфиги и системные переменные прописать — все уже в контейнере.
Другой пример. Какая нибудь фирма решила открыть филиал в другой стране. Ставят точно такой же дата-центр, делают репликацию контейнеризированной инфраструкуры, и из головного офиса управляют двумя идентичными дата-центрами.
На контейнерах можно делать A/B тесты — одной части пользователей сервис показывает обновленную версию интерфейса. Или урезанный сервис для стран третьего мира — наследуется контейнер базового приложения и перенастраивается.
Вам просто не виден масштаб. Возможно вы думаете что google работает на сервере а под ним база mysql, обернутая скриптами.
Какого рода «навернулся» встречаются в реальной практике?Жесткий диск сломался — перекинул контейнер на другую машину и запустил. Полная миграция дата-центра в течении одного часа — реальность.
Или новичок-программист случайно проапдейтил на node.js сервере зависимости пакетов — и все приложение легло. А завтра утром нужно показывать заказчику. Восстанавливают контейнер с рабочими версиями зависимостй и все.
Если интересно посмотрите это видео: Возможности программного обеспечения Docker (~1 ч.)
Зачем заворачивать сервисы в контейнеры, если можно реализовать их как обычные скрипты на PHP/Perl/Python/Go, возвращающие JSON (и дёргающие по необходимости внутренние сервисы вроде тех же движков распознавания изображений, вычисления хэшей музыкальных файлов и прочего)?Конечно сервис может быть так и устроен, но весь этот зоопарк оборачивают в контейнер, чтобы то, что работало вчера продолжало работать и завтра и послезавтра и через 10 лет. По принципу «never change a running system» — программный комплекс консервируют в контейнерах. На каких версиях подсистем приложение, написали на тех оно пусть и работает всю жизнь. Не надо ничего трогать.
Задача девопса не в том из каких компонент реализовать приложение, а в том как обеспечить работу команды разработчиков и эксплуатацию этого приложения заказчиком при постоянно меняющихся условиях в бизнесе с минимальными затратами.
Вообще-то это все оффтоп. Хотите оффтопить пишите в личку, а то еще минусов нахватаете.
но все нормальные люди собирают приложение из готовых решений
Какой тогда вообще в этом смысл? Чтобы что-то собрать из готовых решений, не надо вообще уметь писать код. Это как раз и школьник сможет сделать. Не вижу в этом особого творчества, если честно.
Например одному приложению нужен PHP 4.х
Серьёзно, такие ещё есть?) Я понимаю, что пример с потолка, но всё равно странно требование старой версии софта, тем более настолько.
На контейнерах можно делать A/B тесты — одной части пользователей сервис показывает обновленную версию интерфейса. Или урезанный сервис для стран третьего мира — наследуется контейнер базового приложения и перенастраивается.
Это можно сделать и без контейнеров, просто правкой конфигов на нодах, обслуживающих часть клиентов или отдельную страну. Но да, наверное, удобно.
Вам просто не виден масштаб. Возможно вы думаете что google работает на сервере а под ним база mysql, обернутая скриптами.
Гугл — уникальный случай, сервисов такой сложности и с такой нагрузкой в мире единицы. А вы рассказываете про нечто гораздо более распространённое, как я понимаю.
Жесткий диск сломался — перекинул контейнер на другую машину и запустил
А для такого есть виртуальные облака — Amazon например такую миграцию умеет по требованию или в случае неполадок :)
Восстанавливают контейнер с рабочими версиями зависимостй и все.
Ну для этого ведь надо сделать бэкап контейнера? А в случае его отсутствия мы бы файл с зависимостями забэкапили, меньше места под это нужно. Или там в само ПО управления контейнерами встроена система создания контрольных точек, и они весят мало?
Конечно сервис может быть так и устроен, но весь этот зоопарк оборачивают в контейнер, чтобы то, что работало вчера продолжало работать и завтра и послезавтра и через 10 лет. По принципу «never change a running system» — программный комплекс консервируют в контейнерах. На каких версиях подсистем приложение, написали на тех оно пусть и работает всю жизнь. Не надо ничего трогать.
Красивый подход) То есть выходит, если я пишу приложение, оно потащит за собой свою версию PHP, свою версию MySQL и так далее? Не выйдет ли так, что если на сервере работает много контейнеров, то всё это будет много весить и получится избыточное дублирование сущностей (то есть будет продублировано даже то, что и так работало бы нормально без сбоев в обычном режиме с одной общей версией ПО для разных приложений)?
В целом понятно, спасибо)
Какой тогда вообще в этом смысл? Чтобы что-то собрать из готовых решений, не надо вообще уметь писать код. Это как раз и школьник сможет сделать. Не вижу в этом особого творчества, если честно.
Суть программирования в автоматизации, причем автоматизации того, что еще не автоматизировано. И если уже есть адекватное готовое решение, то нужно задать себе вопрос «А могу ли я сделать лучше, за адекватное время», скорее всего ответ будет очевиден. И нет, школьник (в том контексте, в котором Вы написали) не сможет собрать нормальную инфраструктуру, конечно, если мы говорим о серьезных проектах и о бизнесе.
А творчество можно проявлять в логике, да и оркестрировать готовыми решениями и связывать их в общую структуру — это тоже творчество.
Суть программирования в автоматизации
Иногда суть программирования просто в том, чтобы решить интересную задачу. А способов решения как правило всегда несколько, и даже не факт, что способ, который придёт в голову именно Вам, уже был кем-то применён :)
Автоматизация — да, но её столькими разными способами можно сделать.
И нет, школьник (в том контексте, в котором Вы написали) не сможет собрать нормальную инфраструктуру, конечно, если мы говорим о серьезных проектах и о бизнесе.
Я утрировал, конечно же. Естественно, не сможет.
А творчество можно проявлять в логике, да и оркестрировать готовыми решениями и связывать их в общую структуру — это тоже творчество.
Тоже верно. Но всё-таки…
Вот только час назад читал статью по конфигурации ES для поиска данных в больших массивах. Тоже творчество, конечно. И вообще проектирование структуры любой БД — тоже творчество. Но как-то для меня это скучно. Ну не то совсем.
Понятно, что дешевле огородить, а потом при наличии свободного времени переписать.
А если это один проект — проблем с производительностью и стабильностью не будет из-за того, что он у нас на два контейнера разнесён?
Опять же, правка конфигов на целом кластере (да и в принципе управление конфигурацией сервисов) — это тоже нетривиальная задача.
Конфиг, затрагивающий такие серьёзные параметры, должен быть один на машину, имхо :)
Все версии образов уже хранятся в репозитории.
Вы про Git? Нам в вузе говорили, что хранение бинарников в репозиториях не привествуется, потому что это занимает много места, и вообще, теряется весь смысл использования системы контроля версий.
Контрольные точки не делают, потому что контейнеры не хранят долговременные данные.
Тогда как откатить данные, которые остались в промежуточном состоянии из-за падения контейнера? Чисто на транзакциях это решать?
Да, ещё глупый вопрос от чайника — если я привык разрабатывать код на винде, есть какое-то удобное приложение под Windows, чтобы рулить содержимым таких контейнеров, или не вариант?
физически отдельные экземпляры могут быть на разных машинах в разных дата-центрах или вообще в облаке
А как же время отклика между разными машинами при работе в связке? Или там каждая единица содержит всё, что нужно для обслуживания клиента?
Руками никто конфиги не раскладывает — это противоречит подходу devops.
А почему? Гораздо проще раскидать инстансы по физическим машинам так, чтобы одна машина обслуживала только одну целевую группу, и конфиг был один. Можно немного проиграть в количестве необходимых машин, но в целом это может окупиться.
Здесь возникает проблема управления распределёнными транзакциями. Это действительно сложная техническая задача.
И если просто использование контейнеров её не решает (а падать они могут часто)… То прелесть всего механизма как-то слегка теряется :(
Для Windows < 10, к сожалению, только Docker в Linux в VirtualBox
Я имею в виду не боевой сервер для продакшена. А просто, грубо говоря, скачать какой-то образ, потестить его, что-то поменять. Или запаковать собственную разработку в контейнер. Значит, мне понадобится виртуалка с любой версией Linux?
Потому что конфигурация тоже хранится в виде исходного кода.
Это вообще как?
И чем плохи стандартные INI или JSON конфиги? Код легко может их парсить, они удобно читаются человеком.
Да, можно поставить на любой. Docker Toolbox содержит урезанный Линукс исключительно для запуска Докера, но с ним не очень удобно работать и могут быть проблемы.
Как оно вообще выглядит? Как VirtualBox/VMware/etc.? То есть выбираем образ, стартуем, и… и что дальше? У нас стартуют сервисы, которые содержатся в контейнере — при этом основная ОС «не засоряется» ничем, и как только контейнер выключается, всё на хосте выглядит так же, как было?
А ещё интересно, как решают вопрос с СУБД. Её ведь нельзя обернуть в контейнер (иначе при перезапуске мы потеряем все изменения в данных БД)? Или там данные просто лежат в каталоге, который вне контейнера хранится)
А ещё интересно, как решают вопрос с СУБД. Её ведь нельзя обернуть в контейнер (иначе при перезапуске мы потеряем все изменения в данных БД)? Или там данные просто лежат в каталоге, который вне контейнера хранится)
Докеризация позволяет «монтировать» внутренние папки контейнера к внешним папкам хоста. Называется `volume`
Например одному приложению нужен PHP 4.х
Серьёзно, такие ещё есть?) Я понимаю, что пример с потолка, но всё равно странно требование старой версии софта, тем более настолько.
4.х не знаю, а 5.2.17 есть ((((
но мне нравилось работать в офисе: это прямой доступ к идеям, обсуждений, можно подсмотреть кто чем занимается, как решает задачи, и в конце концов — прямой доступ к телу других разработчиков… часто можно просто взять за рукав и утащить на часовой перекур и разного говорить\рассуждать\планировать… это не сравниться с скайпами и т.п. удаленными штуками… если вдвоем — еще так сяк, но когда несколько человек — часто бардак…
Коллектив, синергия, парное программирование, если кратко.
2. Что делать с тем, что я постоянно переписываю почти весь код?
Следуй принципам MVP в своей собственной работе, сдавай частями, рефактори работающее, если кратко.
Основным критерием оценки при расстановке приоритетов на очередной цикл реализации может выступить удовлетворённость пользователя.
Он начал задавать вопросы — почему тут так, это что такое, как эти вещи связаны. Работа закипела. Мы много спорили в процессе, но это как интерактивное код ревью, причем такое, которое делается на совесть
Не случайно существует Метод утенка, который я стараюсь внедрить в командах, где работаю. Просто вместо утенка обсуждайте таски, решение и другие технические вопросы с коллегами, даже если вам кажется, что человек не в теме и у него нет подходящей компетенции и опыта. Просто подсаживайтесь к кому-нибудь или к себе на рабочее место просите подойти. Непосвященный в детали человек может задать вам вопрос, после которого у вас будет озарение. К тому же вы можете прийти к решению уже в процессе объяснения проблемы собеседнику. В многих моих предыдущих командах это работало как для меня, так и для коллег.
концепция командной работы, которая есть сейчас — не работает. Когда тебе страшно быть слабым звеном, страшно осознавать, что твой вклад меньше, чем у других. Что если ты в чем-то слаб — команда тебя выкинет
У всех нас(извините, если кого-то обидела) есть пробелы знаний в каких-то областях. Но есть же и то, в чем вы настолько круты, что мало кто из команды может сравниться с вами в этом опыте и знании каких-то вопросов. Адекватные люди это понимают и будут вас ценить, даже если вы не идеальны в некоторых других вопросах, никто и не подумает что вы — «слабое звено». Лично мне это помогает в озвученной выше ситуации :)
Не случайно существует Метод утенка, который я стараюсь внедрить в командах, где работаю. Просто вместо утенка обсуждайте таски, решение и другие технические вопросы с коллегами, даже если вам кажется, что человек не в теме и у него нет подходящей компетенции и опыта. Просто подсаживайтесь к кому-нибудь или к себе на рабочее место просите подойти.
Есть ещё один мега-приём, который можно применять, если обсудить не с кем. Можно подробно и в деталях расписать проблему для самого себя — на бумаге или в текстовом документе. Мозг точно так же начинает находить "слепые зоны" в рассуждениях, которые не были видны раньше.
Я на эту тему писал статью, там метод изложен более подробно.
Это называется парное программирование. Придумали очень давно. Я всегда скидываю наброски дизайна, в котором не уверен на ревью команде. Не понимаю, почему нельзя показывать недописанных код.
А у меня не выходит признать нормальность такого метода на каком-то эмоциональном уровне. Мозгами я понимаю, что все знать невозможно и взгляд со стороны всегда полезен и нужен. Даже всем так говорю. Но сам почти не пользуюсь этим. Долбаный синдром самозванца ;(
Мы два самозванца, которые раздувают свою самооценку до астрономических масштабов, чтобы спастись от своей никчёмности.
Я стараюсь абстрагироваться обычно от мнения других, ведь главное — добиться работающего результата. И, конечно, внутренний перфекционизм очень этому мешает порой
Особенно когда за одним компьютером.
Как то раз у нас даже было трипл-программирование :). И оно прошло очень эффективно. Выработали хорошее решение для не самой тривиальной задачки. Остановили друг друга пару раз от ненужных решений и от того же зловредного «перфекционизма». Просто банально со стороны по другому иногда смотришь. И это помогает. Ты думаешь «тут ещё можно улучшить», а тебе так «забей, уже отлично». И тебе легчает)). И ещё понимаешь, что эти же люди могут и ревьюрить. И тебе ещё больше легчает. Ну и в конце появляется то удовлетворение, ради которого ты этой работой и занимаешься.
В общем на мой взгляд в 80% случаях это реально эффективно. Но это дополнительное время людей, нельзя злоупотреблять. Если не идёт, надо останавливаться. И из опыта понял, что это эффективно, когда уровень «партнёров» примерно одинаковый. Иначе это уже больше наставничество.
Что характерно, применимо после некоторой доработки напильником далеко не только к IT. Метод "засунь гордость подальше и пригласи бета-ридера", к примеру, может сдвинуть с мёртвой точки молодого писателя (проверено на себе).
а описание задачи — это 1% от дела
Думаю, вы неправильно описываете задачи ...
Я хотел бы высказать свое имхо по поводу первой части статьи.
Мне кажется что на уровне middle/senior плохого кода не бывает, бывает только плохое или неудачное но вполне рабочее решение.
За 9 лет разработки, я понял одну простую истину — никогда за одну итерацию не получится сделать хорошое решение, нужно несколько итераций что бы добиться хорошего решения, а вот кол-во итераций уже зависит от опыта, поэтому чем больше опыта тем меньше итераций делает разработчик. Чем быстрее ты пройдешь нужное кол-во итераций тем быстрее ты получишь тот результат на который расчитываешь.
я вам даже больше скажу — как только код удовлетворяет бизнес-требованиям, значит он готов к продакшену (и то, даже это слишком строгий критерий, т.к. это бывает в 30% случаев пуска код в продакшен, в случае внутреннего заказчика и в 90% — НЕ 100! когда был подписан контракт, так что ...)
Мы когда-то так в универе работы писали, командный дух.
Хорошо помогает code review не для галочки и политика минимальных самодостаточных изменений (одно проистекат из другого, потому что нормально отревьюить весь код для сколько-нибудь нетривиальной фичи зараз невозможно). Когда исчезает вариант «посижу ещё ночь и выкачу идеальный pull request на несколько тысяч строк», волей-неволей приходится выдавать промежуточные результаты.
Есть следующий уровень той же проблемы: застрять в попытке написать идеальный design document. Тут уже формальных решений меньше, только культура команды.
Исповедь одичалого интроверта.
Показать неготовый набросок — катастрофа. Как будто тебя увидят не просто голым, а без кожи, без черепа. Увидят все твои обычные несовершенные мысли, которые еще не оформились в умные решения.
Такая проблема не возникает если всё дробить на мелкие части, и часто делать коммит с маленьким но самодостаточным(работающим) кодом.
И дробить стоит с задачи.
В разработке — каждый сам за себя. Но иногда это приводит в тупик