Микроклоны — это дублированные фрагменты кода очень маленького размера — всего несколько инструкций или строк.
В этой статье мы рассмотрим «эффект последней строки» — явление, при котором последняя строка или инструкция в микроклоне с гораздо большей вероятностью будет содержать ошибку, чем предыдущие строки или инструкции.
Для этого мы изучили 219 проектов с открытым исходным кодом и 263 предупреждения о дефектных микроклонах, а также опросили шесть авторов реальных приложений, допустивших подобные ошибки в своем коде.
Наша междисциплинарная работа также исследует психологические механизмы, лежащие в основе относительно тривиальных ошибок этого типа.
На основе результатов опроса и дальнейшего технического анализа мы предполагаем, что ключевую роль в существовании эффекта последней строки играют так называемые «ошибки последовательности»: при копировании кода внимание разработчиков отвлекается на другие задачи из-за отвлекающих факторов и монотонности.
характер самой этой процедуры.
При этом все микроклоны, происхождение которых нам удалось определить, были обнаружены в необычно больших коммитах.
Знание этого эффекта имеет два полезных последствия для программистов: 1) им будет легче распознавать ситуации, в которых особенно велика вероятность допустить ошибку в микроклонах; 2) они смогут использовать автоматический детектор микроклонов/PVS-Studio, что упростит обнаружение ошибок такого типа.
Ключевые слова
Микроклоны, клоны кода, обнаружение клонов кода, эффект последней строки, психология, междисциплинарные исследования.
1. Введение
Разработчикам программного обеспечения часто приходится дублировать одну и ту же строку кода несколько раз подряд с небольшими изменениями, как в следующем примере из проекта TrinityCore: Пример 1 ТринитиЯдроВ поля, соответствующие координатам x, y, z, добавляются пространственные координаты другого объекта, но последняя строка этого фрагмента из трех однотипных строк содержит ошибку: к z-координате добавляется координата y. координировать.
На самом деле последняя строка должна выглядеть так:
Следующий пример взят из популярного веб-браузера Chromium и демонстрирует проявление рассматриваемого эффекта в однотипных инструкциях в одну строку: Пример 2
Хром
Вместо двойной проверки того, что хост равен пустой строке, следует выполнить вторую проверку для port_str:
Строки 1-3 примера 1 похожи друг на друга, как и условия оператора if в строке 3 примера 2. Такие чрезвычайно короткие блоки кода, состоящие из практически одинаковых повторяющихся строк или инструкций, мы будем называть микроклонами.
Наш собственный опыт разработки и консультирования по вопросам качества программного обеспечения интуитивно подсказал нам, что последняя строка или инструкция в микроклоне с гораздо большей вероятностью будет содержать ошибку, чем предыдущие строки или инструкции.
Целью данной работы является проверка истинности нашего ощущения, и именно эта цель определяет два вопроса, поставленные в рамках данного исследования:
- 1 номер Правда ли, что последняя строка многострочного микроклона с большей вероятностью будет содержать ошибку?
- 2-й номер Правда ли, что последняя инструкция в однострочном микроклоне с большей вероятностью будет содержать ошибку?
Если мы сможем доказать, что последняя из нескольких последовательных инструкций одного и того же типа более подвержена ошибкам, авторы кода и инспекторы будут знать, на какие области следует обратить особое внимание, что поможет улучшить качество программы за счет уменьшения количества ошибок.
.
Копирование и вставка — один из естественных способов создания кода, подобного примерам 1 и 2. Поработав над определением происхождения кода среди дубликатов в выбранных нами примерах, мы пришли к выводу, что разработчики используют ряд механических приемов для их создание, из которых наиболее важными являются построчное копирование и вставка и «клонирование» участков кода.
Эти методы являются одними из наиболее распространенных идиом программирования (Ким и др.
, 2004), они требуют минимальных физических и временных затрат и поэтому дешевы; Кроме того, известно, что такой код работает. Хотя копирование небольших частей кода часто рассматривается как плохая практика (Капсер и Годфри, 2008), иногда это единственный способ добиться желаемого поведения программы, как в примерах, рассмотренных выше.
Было разработано несколько инструментов для обнаружения и, где это возможно, устранения микроклонов (Беллон и др.
, 2007; Рой и др.
, 2009).
Хотя эти инструменты продемонстрировали впечатляющие результаты вплоть до уровня метода, они плохо подходят для распознавания микроклонов на практике из-за слишком большого количества ложных срабатываний.
После того как мы опубликовали статью об эффекте последней строки в научно-популярном блоге, ее быстро и с энтузиазмом процитировали на других форумах.
Многие программисты согласились с нашими наблюдениями и предположили, что обсуждаемый эффект имеет психологические причины.
Это подводит нас к третьему и последнему вопросу данного исследования:
- 3-й номер Каковы причины существования дефектных микроклонов вообще и эффекта последней линии в частности?
Изучая явления, которые уже давно наблюдаются в когнитивной психологии, мы увидим, можно ли их использовать для объяснения эффекта последней строки в микроклонах кода.
Основываясь на наших предыдущих исследованиях эффекта последней строки (Beller et al., 2015), мы сделали следующие дополнения:
- Они ввели термин «микроклон» и дали ему определение.
- Мы представили диагностику, используемую автоматическим инструментом статического анализа (Beller 2016) PVS-Studio для обнаружения дефектных микроклонов, которые невозможно обнаружить традиционными методами.
- Мы отдельно изучили каждую ошибку во всех 263 микроклонах, выбранных из 219 популярных проектов с открытым исходным кодом на основе 1891 предупреждения анализатора.
- Мы провели предварительный анализ психологических механизмов, лежащих в основе эффекта последней линии.
- Мы взяли интервью у шести разработчиков реальных проектов, допустивших ошибки в микроклонах.
- Мы изучили репозитории четырех популярных проектов с открытым исходным кодом на основе результатов опроса, которые указали на связь между ошибками и аномально большими размерами коммитов.
Нам кажется, что существование этого явления обусловлено не технической сложностью микроклонов, а психологическими причинами, которые, в свою очередь, в основном сводятся к перегрузке кратковременной памяти программистов.
Предварительное исследование на основе пяти проектов показало, что все микроклоны с ошибками были написаны аномально большими коммитами в нестандартное рабочее время.
Знание этих особенностей и помощь нашего автоматизированного статического анализатора PVS-Studio помогут уменьшить количество тривиальных ошибок, связанных с эффектом последней строки, за счет их автоматического обнаружения.
2 План обучения
Наша работа состоит из двух частей: эмпирических исследований C1 и C2. В этом разделе мы опишем порядок проведения исследования и его объекты.
2.1 Дизайн исследования C1: Распространенность и распространенность эффекта последней линии в микроклонах
В исследовании C1, состоящем из пяти легко воспроизводимых этапов, мы провели статистический анализ распространенности эффекта последней линии в микроклонах.Более того, в попытке пролить свет на процесс создания микроклонов мы провели дополнительную работу по идентификации оригинальных участков кода и их копий.
- Провести статический анализ объектов исследования с помощью инструмента PVS-Studio со всеми включенными диагностиками.
PVS-Studio — коммерческий статический анализатор, разработанный российской компанией ООО «Системы программной верификации» и включающий в себя десятки диагностических правил — от обнаружения клонированных блоков кода до программирования антипаттернов с использованием специфических библиотечных функций языка C. Желающие воспроизвести наше исследование могут воспользоваться бесплатной демо-версией PVS-Studio в открытом доступе.
- Изучите отчет PVS-Studio и удалите ложные срабатывания, а также сообщения, не относящиеся к микроклонам.
- Для каждого дефектного микроклона подсчитайте общее количество строк кода (RQ 1) или инструкций (RQ 2) и укажите, какие строки или инструкции содержат ошибку.
Если возможно, определите исходный фрагмент кода и его копию (например, в примере 6 оригинал — строка 2, а копия — строка 3).
- При запуске исследования по умолчанию исходим из предположения, что в дефектном микроклоне длиной n строк вероятность ошибки для каждой строки равна 1/n независимо от ее количества внутри рассматриваемого фрагмента (нулевая гипотеза H0 ).
Например, строки 1 и 2 в блоке из 2 строк имеют одинаковую вероятность ошибки 0,5. Однако если на этапе (3) удастся показать, что распределение ошибок по строкам существенно отличается от равномерного распределения с уровнем значимости
, мы отвергнем нулевую гипотезу и признаем, что ошибки распределены неравномерно.Для каждой длины n строк используется критерий согласия Пирсона.
со степенью свободы n - 1 для установления соответствия между наблюдаемыми данными и нулевой гипотезой (распределение 1/n). - Если шаг (4) выявит значительное расхождение между расчетным и фактическим распределениями, мы рассчитаем отношение шансов между ними как интуитивную меру интенсивности эффекта последней линии (Бланд и Альтман (2000)).
2.2 Дизайн исследования C2: анализ причин эффекта последней линии
Установив существование эффекта последней линии в исследовании C1, мы должны теперь попытаться определить его основные причины (вопрос 3).Для этого мы разработали первоначальную гипотезу, основанную на исследованиях в области когнитивной психологии, с помощью профессора когнитивной психологии Рольфа Цваана.
Чтобы подтвердить нашу гипотезу, а также собрать доказательства от разработчиков, мы взяли интервью у программистов, ответственных за создание микроклонов, обнаруженных в исследовании C1. Их комментарии и наблюдения помогут нам разработать предварительную оценку эффекта последней линии.
Сужение круга опрашиваемых исключительно лицами, авторство дефектных микроклонов которых четко установлено, позволяет: (1) сосредоточить внимание на конкретных примерах, к которым опрашиваемые имеют непосредственное отношение; (2) получить максимально полезные ответы, поскольку мы точно знаем, что именно разработчики отвечали за написание рассматриваемых микроклонов.
На рис.
1 показан общий план нашего исследования.
Основная задача — наладить контакт с авторами микроклонов (во многих случаях дефектный код находится не в последней версии проекта).
План включает в себя четыре основных этапа:
- Проекты и примеры микроклонов выбираются случайным образом, поскольку работа над исследованием С2 — трудоемкий процесс, предполагающий контакты с авторами примеров и проведение индивидуальных интервью.
Принимая стандартную долю ответов на холодные звонки в 30%, мы можем рассчитывать на три успешных опроса, которые должны дать нам достаточно информации, чтобы сформулировать первоначальную гипотезу, объясняющую существование эффекта последней очереди с точки зрения когнитивной психологии.
При анализе каждого микроклона необходимо ознакомиться с правилами разработки, принятыми в этом проекте, и изучить репозиторий.
- Затем мы находим микроклон в дереве исходного кода проекта.
Поскольку многие ошибки были исправлены с тех пор, как наши предыдущие наблюдения были опубликованы и не включены в текущую ветку, на этом этапе мы вынуждены использовать другие стратегии поиска.
Сначала мы исследуем репозиторий, относящийся ко дню проведения C1. В случае сбоя — например, если код, соседний с микроклоном, был рефакторизован (или история изменений была перезаписана) — мы ищем в баг-трекере проекта коммит, в котором было сделано исправление.
Если этот шаг не принес результата, прибегаем к полнотекстовому поиску (с помощью инструмента ag) по всем коммитам проекта.
- При обнаружении оригинального микроклона мы отслеживаем его историю с помощью инструмента git Assessment, чтобы получить информацию о внесенных исправлениях, а также указать авторство кода.
- Наконец, мы узнаем адрес электронной почты разработчика с помощью команды git Assessment -e. Чтобы добиться более высокого уровня ответов, мы собираем дополнительную информацию о респондентах посредством онлайн-поиска, чтобы помочь нам определить, актуален ли адрес электронной почты.
Чтобы наши ответы были максимально честными, мы заверяем респондентов, что не будем раскрывать их личную информацию.
Затем мы отправляем каждому разработчику электронное письмо с текстом его микроклона, историей его модификации/исправления, контекстом ошибки, а также объяснением причины проведения опроса и прикрепляем анкету.
Рис.
1 - План исследования C2
2.3 Объекты исследования
Чтобы облегчить тиражирование нашей работы другими исследователями, мы отдали предпочтение известным проектам с открытым исходным кодом.Среди 219 проектов, изученных нами в рамках исследования C1, ошибочные микроклоны были обнаружены в таких известных проектах, как аудиоредактор Audacity (1 пример), веб-браузеры Chromium (9) и Firefox (9), XML-библиотека libxml (1), Базы данных MySQL (1) и MongoDB (1), компилятор языка C clang (14), шутеры от первого лица Quake III (3) и Unreal 4 (25), пакет для создания компьютерной графики Blender (4), программа 3D-моделирования и визуализации VTK (8) ), сетевые протоколы Samba (4) и OpenSSL (2), видеоредактор VirtualDub (3), а также язык программирования PHP (1).
Для исследования C2 мы выбрали 10 микроклонов из проектов Chromium, libjingle, Mesa 3D и LibreOffice.
2.4 Примечания по повторению исследования
Чтобы облегчить работу другим исследователям, мы подготовили специальный пакет, включающий все исходные данные и диагностику.В него входят все нефильтрованные сообщения PVS-Studio, сгруппированные в две директории: выводы_старый/ , который содержит старые данные, использованные в нашей статье для Международной конференции по наглядности программ (ICPC) (Beller et al. 2015), и выводы_новое/ с более свежими данными, использованными в этой статье.
Кроме того, в комплект поставки входят проанализированные нами и отсортированные по проектам микроклоны ( анализируемые_данные.
csv ), электронная таблица с оценкой данных ( оценка.
ods ) и результаты анализа репозиториев из исследований C1 и C2. Мы также включили сценарии R для воспроизведения результатов и диаграмм из этой статьи.
Наконец, пакет содержит шаблон анкеты с вопросами для респондентов.
3 Методы обнаружения микроклонов
В этом разделе мы рассмотрим традиционные методы обнаружения повторяющихся фрагментов кода, объясним, почему они не подходят для поиска микроклонов, и покажем, как нам удалось обойти эту проблему с помощью собственной диагностики статического анализа.Кроме того, мы покажем, как определялись оригинальные регионы и копии в микроклонах и как учитывались размеры коммитов.
3.1 Почему современные средства обнаружения клонов кода не подходят для нашей задачи
Как показывают примеры 1 и 2, фрагменты кода, обсуждаемые в этой статье, либо совершенно одинаковы по тексту, либо содержат «клоны с одинаковой синтаксической структурой, отличающиеся только идентификаторами переменных, типов или функций» (Koschke 2007).По этой причине они являются клонами 1 или 2 тип чрезвычайно маленький по размеру (обычно менее 5 строк/инструкций) — это то, что мы называем микроклоны .
Традиционные методы обнаружения дублированного кода включают сравнение токенов, строк кода, узлов абстрактного синтаксического дерева (AST) или графов (Koschke 2007).
Однако на практике любой из этих подходов требует определения минимального размера клона в условных единицах измерения (будь то токены, инструкции, строки или узлы ASD), чтобы снизить процент ложных срабатываний.
Как правило, это значение принимают в районе 5-10 единиц (Bellon et al. 2007; Juergens et al. 2009), что значительно превышает размеры рассматриваемых нами микроклонов (2-5 единиц) и делает невозможным их поиск.
Итак, в примере 1 строки 1-3 представляют класс микроклонов.
Поскольку строк три, в этом примере этот класс представлен в трех экземплярах.
В свою очередь, каждый экземпляр состоит из переменной, операции присваивания, присвоенного объекта и его поля и, таким образом, имеет длину 4 единицы.
3.2 Методы, которые мы используем для обнаружения дефектных микроклонов
Поскольку традиционные методы поиска на практике не позволяют достоверно обнаружить микроклоны, мы использовали собственный подход. Наша задача — не обнаружить какие-то микроклоны, а только те, которые содержат ошибки.Учитывая это дополнительное ограничение, мы смогли разработать целый набор мощных средств диагностики, которые обнаруживают микроклоны на основе простого посимвольного совпадения.
Данная диагностика способна найти дефектные участки кода, которые, скорее всего, появились в результате копирования небольших фрагментов.
В таблице 1 перечислены и описаны все двенадцать диагностик, выявивших ошибки в микроклонах в данном исследовании.
В последнем столбце указано соотношение количества одно- и многострочных клонов к общему количеству предупреждений данного типа.
Например, диагностика V501 просто определяет, идентичны ли операнды определенных логических операторов.
Если ответ положительный, то в лучшем случае это просто лишний код, который может затруднить поддержку программы в будущем, в худшем — это настоящая ошибка.
Другие диагностики не столь узкоспециализированы по отношению к микроклонам, как V501. Мы изучили каждое из 526 предупреждений и выбрали для нашего исследования только 272 случая реальных микроклонов.
Из таблицы 1 также видно, что 78% микроклонов были обнаружены одним диагностиком (V501) с очень низким уровнем ложноположительных результатов - 3%.
Другие диагностические программы с большей вероятностью сработают на участках кода, которые не являются микроклонами.
Таблица 1 – Типы ошибок, обнаруживаемых PVS-Studio, и их распределение по 219 открытым проектам
3.3 Как определяли происхождение ошибочных микроклонов
Чтобы грамотно рассуждать о причинах существования эффекта последней строки, в ответ на вопрос 3 мы также обнаружили в каждом классе микроклонов исходный экземпляр кода и экземпляр, предположительно скопированный с него.Хотя такой эмпирический анализ не дает 100% уверенности в том, что процедура копирования пошла в этом направлении, у нас есть достаточно доказательств того, что по крайней мере некоторые разработчики механически клонируют код таким способом (см.
ВОПРОС 3).
В большинстве случаев можно сразу определить, какая из двух копий микроклона является оригиналом, а какая копией.
Так, в примере 1 в строке 3, содержащей ошибку, присутствуют следы кода из строки 2, что подразумевает влияние строки 2 (оригинала) на строку 3 (копию).
Подобный естественный порядок исходных строк и копий наблюдается в большинстве микроклонов — будь то лексикографический порядок, например, в последовательности переменных х, у, г в примере 1 или числовое: Пример 3
Cmake
Даже в тех случаях, когда естественный порядок исходной копии и копии не выражен явно, как в примерах 1 и 3, его можно реконструировать по контексту, как в примере 2: комната port_str первое место и хозяин вторая в строке 3 противоречит порядку, в котором эти переменные были определены ранее, что означает первую инструкцию хост != buzz::STR_EMPTY это оригинал, а второй это копия.
В процессе установления происхождения копии в рассматриваемых примерах мы сталкиваемся с двумя проблемами, а именно: 1) размер копируемой области может меняться; 2) микроклоны длиной более 4-х дубликатов представлены меньшим количеством примеров.
Однако чтобы иметь возможность обобщить данные для разных размеров микроклонов, для каждого микроклона я мы рассчитываем
, что дает нам степень расстояния
.
Расстояние 1 указывает на копию непосредственно предшествующей строки/инструкции, как в примере 4. Значение 0: ошибка произошла в той же строке микроклона.
Значение -1 указывает обратный порядок копирования: от второго блока к первому: Пример 4
UnrealEngine4
В этом примере в строке 1 естественно ожидать cx().
isRelative вместо cy().
isRelative , что указывает на возможное копирование со второй строки.
Логика использования переменных со схожими именами, а также порядок строк 3 и 4 подсказывает, что копирование должно начинаться с вернуть cx().
isRelative() в первой строке.
Отсюда получаем степень удаленности
или
, что указывает на непосредственную близость двух дубликатов либо на одной строке, либо на двух соседних, независимо от общего размера клонируемой области.
3.4 Как учитываются размеры коммитов
Чтобы вычислить и представить соотношение размера каждого из коммитов, содержащих дефектные микроклоны, к остальным коммитам, мы сначала вычисляем вариативность для каждого коммита в репозитории.Для этого воспользуемся инструментом журнал git , который позволяет строить упорядоченные графики всех коммитов (исключая слияния) в репозитории, определяя таким образом количество добавленных и удаленных строк кода в каждом коммите.
Сумма этих чисел дает общее количество измененных строк, то есть величину вариативности для каждого коммита.
Затем мы сравниваем изменчивость коммитов, содержащих дефектные микроклоны, с распределением этого параметра в остальных коммитах и, в частности, с его медианой.
Хотя наша выборка (десять примеров) слишком мала для достоверного статистического анализа, такой подход все же позволяет сделать разумные выводы о возможных различиях в размерах коммитов.
Мы используем медиану (а не среднее значение, например), потому что имеем дело с асимметричными распределениями; Медиана — это независимая реальная величина, с которой мы сравниваем другие подобные значения.
4 результатов
В этом разделе мы более подробно исследуем дефектные микроклоны, рассматривая примеры и проводя статистические оценки.
4.1 Общее описание результатов
В таблице 2 приведены основные статистические данные по результатам исследования С2. За период с середины 2011 по июль 2015 года мы использовали полный набор диагностики PVS-Studio на 219 выбранных нами open source проектах.Андрей Карпов, специализирующийся на консалтинге по разработке программного обеспечения, проанализировал все эти проекты, используя последние версии PVS-Studio, доступные на момент проверки каждого конкретного проекта.
Он отфильтровал ложные срабатывания, оставив 1891 предупреждение, указывающее на потенциальные недостатки в коде.
Эти предупреждения были сгруппированы в 162 диагностических сообщения.
Затем мы изучили каждое сообщение и обнаружили, что 272 из них были выданы двенадцатью диагностами и относились к микроклонам.
В девяти случаях сообщения дублировались, в результате чего осталось 263 микроклона.
Статистический анализ на уровне проектов показывает, что наша диагностика смогла выявить дефектные клоны в половине отобранных проектов.
Почти все эти случаи (92%) содержат хотя бы один пример эффекта последней строки.
Таблица 2 – Статистика по результатам исследования
В таблице 3 представлена сводка обнаруженных ошибок в 263 микроклонах.
В общей сложности 74% многострочных клонов содержат ошибку в последней строке, а 90% однострочных клонов содержат ошибку в последней инструкции.
Таблица 3. Краткое изложение результатов исследования
4.2 Детальный анализ результатов
Для более полного понимания принципов работы диагностики, которую мы использовали для обнаружения микроклонов, ниже мы рассмотрим некоторые наиболее наглядные примеры 263 предупреждений PVS-Studio, связанных с микроклонами и выявляющих наиболее распространенные ошибки из таблицы.
1.
4.2.1 V501 — Идентичные подвыражения
Как видно из табл.
1, большинство предупреждений микроклонов было выдано диагностическим V501. Ниже типичный пример такой ошибки браузера Chromium: Пример 5
Хром
Это однострочный микроклон, в котором второе и третье подвыражения совершенно одинаковы, но соединены логическим оператором ИЛИ ( || ), что делает выражение излишним.
Вообще-то надо было проверить фамилию( NAME_LAST ) — так выглядит эффект последней строки в этом блоке из трёх юнитов.
4.2.2 V517 — Те же условные выражения
Диагностика V517 обнаруживает одинаковые условия для двух ветвей оператора if. Пример 6 Linux-3.18.1Тело оператора еще если после третьего микроклона в строке 9 — мертвый код, поскольку поток выполнения никогда не достигнет его.
Случай, когда значение слот равно 0, будет обработано уже в первом условии.
4.2.3 V519 — Присвоение одинаковых значений переменной
Присвоение двух значений переменной подряд обычно является либо просто избыточной операцией (и, следовательно, создает проблемы в сопровождении кода, затрудняя его понимание, поскольку первое присвоение недопустимо), либо откровенной ошибкой, поскольку правая операнд должен был иметь другое значение.В следующем примере проекта MTASA переменная m_ucRed присваивается значение дважды, а переменной m_ucBlue Забыл присвоить значение.
Пример 7
МТАСА
Ди
Теги: #программирование #психология #рефакторинг #качество кода #ошибки кода #психология программирования #копипаста
-
Китайский Чайный Куст
19 Oct, 24 -
Как Заниматься Онлайн-Шопингом
19 Oct, 24 -
Подкаст Appleinsider [18]
19 Oct, 24