Психология разработки: как когнитивные искажения влияют на архитектурные решения и качество кода (часть 2). C++.. C++. когнитивные искажения.. C++. когнитивные искажения. Программирование.
Психология разработки: как когнитивные искажения влияют на архитектурные решения и качество кода (часть 2) - 1

Качество вашего кода начинается с качества вашего мышления о коде.

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

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

Когнитивные искажения и качество кода

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

Психология разработки: как когнитивные искажения влияют на архитектурные решения и качество кода (часть 2) - 2

Эффект владения: “Мой код — мое дитя”

Эффект владения — это когнитивное искажение, при котором мы склонны ценить то, чем владеем (или что создали), существенно выше, чем аналогичные вещи, которыми не владеем. В контексте разработки ПО это проявляется в чрезмерной эмоциональной привязанности к собственному коду и инстинктивном сопротивлении его изменению, улучшению или удалению.

Пример из практики: Опытный разработчик написал сложный кастомный аллокатор, специально предназначенный для конкретного паттерна нагрузки. Когда другой член команды предложил заменить его на популярный аллокатор общего назначения, автор оригинального кода активно сопротивлялся: “Мое решение учитывает множество краевых случаев, которые ваша библиотека не обрабатывает”. После долгих дискуссий команда все же удалила кастомный аллокатор из кодовой базы, после чего проект стал не только быстрее, но и надежнее, как раз из-за некорректной обработки краевых случаев в кастомном аллокаторе.

Нейробиологи обнаружили, что эффект владения имеет глубокие эволюционные корни и связан с территориальным поведением, характерным для многих видов. Мы часто воспринимаем свой код как “территорию”, которую необходимо защищать. Нейробиологические исследования показывают частичное перекрытие активации в островковой коре и вентромедиальной префронтальной коре при оценке ценности созданных нами объектов, хотя эта реакция не идентична реакции на физическую угрозу имуществу.

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

Как проявляется эффект владения в командной разработке:

  1. Защитная реакция на код-ревью: “Это не баг, это фича. Вы просто не понимаете всей глубины реализации.”

  2. Сопротивление удалению кода: “Давайте оставим этот код закомментированным, он может пригодиться в будущем” (даже если код явно устарел или больше никогда не будет использован).

  3. Профессиональная территориальность: “Не трогайте этот модуль, я его написал, я буду его поддерживать. Работайте над своей частью.”

  4. Эмоциональная реакция на критику: Критические замечания к коду воспринимаются как личное оскорбление, вызывая непропорционально острую эмоциональную реакцию.

Психология разработки: как когнитивные искажения влияют на архитектурные решения и качество кода (часть 2) - 3

Эффект “уже вложенных средств” (Sunk Cost Fallacy): “Нельзя бросать, мы столько уже вложили…”

Эффект “уже вложенных средств” (или ловушка невозвратных инвестиций) — это когнитивное искажение, при котором мы склонны продолжать начатое дело или использовать ресурс только потому, что уже вложили в него время, усилия или деньги, даже если объективно лучше было бы остановиться и выбрать альтернативный путь.

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

Это искажение значительно усиливается в условиях публичной приверженности решению. Когда разработчик публично защищал определенный подход, вероятность иррационального упорства в нем возрастает многократно из-за связанного когнитивного искажения — самосогласованности (commitment and consistency bias), когда мы стремимся сохранять последовательность своих действий и слов.

История из практики: Старший C++ программист потратил более четырех месяцев на создание специализированного физического движка для гоночного симулятора, уверяя, что коммерческие решения недостаточно реалистичны. По мере разработки проявлялись проблемы со стабильностью и производительностью, но программист убеждал: “У нас уже большая часть готова, выбрасывать такой объем работы нерационально”. Команда продолжала работу над физикой еще полгода, откладывая другие аспекты игры. Когда был проведен сравнительный анализ с PhysX, выяснилось, что кастомное решение потребляло в три раза больше вычислительных ресурсов при менее реалистичных результатах. После болезненного решения и всего трех недель интеграции игра была переведена на готовый физический движок, что позволило наконец сосредоточиться на геймплее и других элементах проекта.

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

Как проявляется эффект “уже вложенных средств”:

  1. Упорство в бесперспективных технических решениях: “Мы уже потратили три месяца на эту архитектуру, давайте доведем её до ума, а не начинаем заново” (даже когда очевидно, что архитектура фундаментально неправильна).

  2. Нежелание отказываться от устаревших технологий: “Мы столько времени потратили на изучение этого фреймворка и адаптацию нашей кодовой базы, нельзя просто взять и перейти на другой” (даже когда новое решение предлагает критические преимущества).

  3. Оправдание дополнительных инвестиций в проблемный проект: “Если мы добавим еще два разработчика и еще месяц работы, то сможем решить все проблемы” (бесконечный цикл “еще немного ресурсов”).

  4. Игнорирование объективно лучших альтернатив: “Да, это новое решение выглядит эффективнее, но мы уже столько вложили в текущее… Давайте придерживаться выбранного пути.”

Психология разработки: как когнитивные искажения влияют на архитектурные решения и качество кода (часть 2) - 4

Предвзятость оптимизма: “Этот код настолько прост, что не нуждается в тестах”

Предвзятость оптимизма (optimism bias) — это когнитивное искажение, при котором мы систематически переоцениваем вероятность положительных событий и недооцениваем вероятность негативных. Это одно из самых распространенных и устойчивых когнитивных искажений, которое проявляется в излишней уверенности в своем коде, недооценке сложности задач, игнорировании потенциальных проблем и пренебрежении лучшими практиками вроде тестирования и код-ревью. “У меня всё получится с первого раза”, “Что здесь может пойти не так?” — эти мысли редко произносятся вслух, но имеют огромное влияние на качество создаваемого ПО.

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

Взаимосвязь между опытом и оптимистической предвзятостью нелинейна и модулируется многими факторами. У специалистов высшего уровня часто наблюдается “калиброванная уверенность” — более точная оценка вероятностей успеха и риска. Однако у разработчиков среднего уровня оптимистическая предвзятость часто работает в тандеме с эффектом Даннинга-Крюгера (тенденция людей с низким уровнем квалификации переоценивать свои способности, и наоборот – недооценивать у людей с высоким уровнем квалификации), создавая особенно опасную комбинацию.

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

Как проявляется предвзятость оптимизма:

  1. Систематическое пренебрежение тестированием: “Этот код слишком прост, чтобы в нем были ошибки. Писать для него тесты — пустая трата времени.”

  2. Хроническая недооценка сложности и сроков: “Это простое добавление одного поля в форму, максимум час работы” (превращается в три дня разбирательств со сложной логикой валидации и каскадными изменениями в API).

  3. Избирательное игнорирование краевых случаев: “Никто никогда не будет использовать систему таким образом” (пока клиент не сделает именно это на следующий день после релиза).

  4. Необоснованная уверенность в понимании кода: “Я абсолютно точно знаю, как работает этот модуль, не нужно тратить время на чтение документации или изучение зависимостей.”

  5. “Эффект вечера пятницы”: Внесение изменений в последний момент перед выходными или отпуском с мыслью “что может пойти не так за выходные/пока меня не будет?”.

Психология разработки: как когнитивные искажения влияют на архитектурные решения и качество кода (часть 2) - 5

Эффект проклятия знания: “Это же очевидно, зачем объяснять?”

Эффект проклятия знания (curse of knowledge) — это когнитивное искажение, при котором человек, обладающий информацией, испытывает фундаментальные трудности в понимании того, как выглядит мир для людей, не обладающих этой информацией. Проще говоря — как только мы что-то узнали, мы не можем представить, каково это — не знать этого.

В разработке ПО проклятие знания проявляется в создании запутанного, недокументированного кода, который кажется “очевидным” его автору, но становится головоломкой для других разработчиков. Это также приводит к нереалистичным ожиданиям от коллег и неэффективной коммуникации с заказчиками и пользователями.

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

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

Пример: В одной независимой студии старший программист создал “революционную” систему многопоточности для in-house игрового движка. Архитектура основывалась на сложном взаимодействии lock-free структур данных, атомарных операций и тонкой синхронизации с использованием memory barriers. Код содержал лишь минимум комментариев: “// Pad up to 64 bytes” или “// Thread-safe function”. Когда один из разработчиков попросил подробно объяснить, как это работает, автор самоуверенно ответил: “Это стандартный producer-consumer, только lock-free.”. Полгода спустя, когда количество игровых серверов выросло, система стала регулярно демонстрировать неуловимые баги и странные race conditions. Старший разработчик заявил, что ему надоело возиться с одним и тем же проектом и ушел в другую компанию, а оставшиеся члены команды не могли разобраться, как безопасно использовать существующую многопоточную инфраструктуру. В итоге команда потратила месяцы на попытки исправления этого кода, а закончилось все переписыванием с применением мьютексов из abseil.

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

Как проявляется проклятие знания:

  1. Минимальное документирование: “Зачем писать комментарии или документацию? Код самодокументируемый! Любой, кто посмотрит на эту функцию, сразу поймет, что она делает”.

  2. Использование неинформативных имен переменных и функций: x, Do(), tmp, helper вместо осмысленных имен, отражающих семантику.

  3. Нереалистичные ожидания от других членов команды: “Как ты можешь не понимать, как это работает? Это же элементарно!”.

  4. Пропуск критических деталей при объяснении: Упущение ключевых шагов или предположений при объяснении кода или архитектурных решений, потому что они кажутся “само собой разумеющимися”.

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

Психология разработки: как когнитивные искажения влияют на архитектурные решения и качество кода (часть 2) - 6

Эффект Даннинга-Крюгера: “Я могу переписать весь игровой движок за месяц”

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

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

Пример: В команду разрабатывающую стратегию реального времени пришел талантливый молодой программист с опытом в области машинного обучения и нейросетей, но без опыта в геймдеве. На втором месяце работы, изучив базовую AI-систему противников, он уверенно заявил на совещании: “Этот ИИ примитивен и предсказуем. Я могу реализовать небольшую нейронную сеть, которая будет учиться на действиях игрока и создавать по-настоящему адаптивных противников”.

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

В итоге пришлось вернуться к исходной системе на основе конечных автоматов и продолжить её развитие, ведь в играх ИИ — это не демонстрация технологического совершенства, а инструмент для создания увлекательного игрового опыта, он должен красиво проиграть игроку и легко настраиваться.

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

Как проявляется эффект Даннинга-Крюгера:

  1. Недооценка сложности разрабатываемых систем: “Физический движок? Это просто набор формул из школьной физики” (игнорируя численную стабильность, оптимизацию и краевые случаи).

  2. Пренебрежение оптимизацией: “Мой код работает правильно, зачем его оптимизировать?” (не понимая влияния на производительность и опыт пользователя).

  3. Игнорирование существующих решений: “Библиотеки слишком сложные и избыточные, я напишу свою, только то, что нам нужно” (недооценивая причины, по которым существующие решения стали “сложными”).

  4. Узкий фокус на знакомых аспектах: “Я отлично знаю С++, поэтому создание игры — просто вопрос написания достаточного количества кода” (не учитывая все аспекты гейм-дизайна, пользовательского опыта и технических ограничений платформ).

  5. Сопротивление комплексному обучению: “Зачем изучать эти продвинутые паттерны? Мой код и так работает” (не понимая, как быстро растут проблемы с масштабированием кодовой базы в игровых проектах).

Особенно опасно сочетание эффекта Даннинга-Крюгера с другими когнитивными искажениями, например, предвзятостью оптимизма (“Я справлюсь с этим за выходные”) или эффектом сверхуверенности (“Конечно, я знаю, как работает многопоточность”).

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

Заключение: Осознанность как ключ к качеству кода

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

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

Автор: GlacialExpert

Источник

Рейтинг@Mail.ru
Rambler's Top100