Матрица компетентности программиста

Как пользоваться таблицей

Таблица характеризует уровень профессионализма программиста (столбцы) в конкретном языке программирования, оценивая этот уровень в контексте различных видов практической программистской деятельности (строки).

Данная таблица составлена по образцу таблицы CEFR (Общеевропейская система языковой компетенции), предназначенной для оценки степени владения естественными языками. Подобно CEFR, эта таблица подразделяет обучающихся на три широкие категории: «Элементарное владение» (А), «Самодостаточное владение» (B) и «Профессиональное владение» (C). Каждая из этих крупных категорий делится на уровни (A1, A2, B1, B2, C1, C2), при переходе на каждый следующий уровень сдаётся специальный экзамен, контролирующий степень владения языком.

Эту таблицу можно использовать несколькими способами, например:

– Строка за строкой – для оценки уровня профессионализма в конкретном виде деятельности (возможно, что специалист будет в разной степени владеть различными практическими навыками).

– Столбец за столбцом в порядке слева направо – для определения собственного минимального уровня владения языком программирования (правый край соответствует уровню, при котором специалист удовлетворяет всем требованиям не только данного столбца, но и всех столбцов, расположенных левее).

– Столбец за столбцом справа налево – для определения того, какой навык развит у специалиста наиболее хорошо (правый край соответствует уровню, при котором специалист удовлетворяет всем требованиям конкретного столбца).

– Язык за языком – для оценки относительной степени владения различными языками программирования.

Возможности применения таблицы

1. Отслеживание собственного прогресса при обучении программированию.

Например: за этот год я прошел с A2 до B2 в C++. В Java мой уровень – B1 по пониманию кода, но писать код Java мне по-прежнему удается только на уровне A2.

2. Рассказ о собственном наборе профессиональных навыков коллегам или потенциальным работодателям.

Например: Мой уровень – C1 в Python, B2 в O'Caml и A2 в Haskell.

3. Выбор курса по программированию, оптимально соответствующего профессиональному уровню.

Например: мой текущий уровень A2, но для этого курса требуется B1, поэтому мне нужно немного подучиться, прежде, чем приступать к данному курсу.

  A1
Начинающий специалист
A2
Начинающий специалист
B1
Продвинутый специалист
B2
Продвинутый специалист
C1
Опытный специалист
C2
Опытный специалист
Кодирование
Написание кода Могу правильно и без посторонней помощи написать реализацию простой функции при наличии подробной спецификации желаемого поведения и интерфейса. Могу определить подходящий интерфейс и написать правильную реализацию, имея примерную спецификацию простой функции, без посторонней помощи. Могу разбить спецификацию сложной функции на описания более мелких и простых функций. Могу оценить пространственно-временные потребности на выполнение моего кода в процессе работы. Могу эмпирически сравнить различные реализации одной спецификации конкретной функции при наличии подробно описанных параметров, в частности, с указанием времени исполнения и объёма занимаемой памяти. Выражаю в коде инварианты с применением предусловий, утверждений и постусловий. Использую заглушки для обеспечения гибкости порядка реализации. Осознанно и продуктивно использую типизацию и интерфейсы для структурирования и заблаговременного планирования работы с кодом. Могу самостоятельно проектировать и реализовывать целые программы, имея подробные спецификации внешнего ввода и вывода. Систематически пытаюсь унифицировать функции для того, чтобы их было удобнее повторно использовать. Могу систематически распознавать в спецификациях несогласованные или конфликтующие требования. Могу разбить архитектуру сложной программы на небольшие компоненты, каждый из которых можно реализовать отдельно, а также поручить такую реализацию другому специалисту. Могу пользоваться имеющимися предметно-ориентированными языками (в том числе языками выражений) или паттернами метапрограммирования для повышения продуктивности своей работы. Могу уверенно определить, намеренно или случайно спецификация была сделана неполной. Могу эксплуатировать пробелы в спецификации для повышения собственной продуктивности нетривиальными способами. Могу разрабатывать новые предметно-ориентированные языки (в том числе языки выражений) или создавать новые паттерны метапрограммирования для повышения собственной продуктивности и продуктивности других программистов.
Рефакторинг При возникновении небольших изменений в спецификации могу адаптировать к ним свой код, не переписывая его полностью, при условии, что изменения являются несущественными. Могу изменить свой код, получив подробную консультацию у более опытного программиста. Могу самостоятельно изменить, является ли небольшое изменение спецификации несущественным, либо потребует серьезного рефакторинга. Могу самостоятельно изменять свой код, получив общие инструкции от более опытного программиста. Могу самостоятельно разработать стратегию рефакторинга для собственного кода при возникновении относительно небольших изменений в спецификации. Могу менять код, написанный другими, получая подробные инструкции от человека, уже знакомого с данным кодом. Могу точно спрогнозировать, какой объём работы потребуется выполнить для адаптации моей базы кода к новой спецификации. Могу придерживаться заданной стратегии при рефакторинге чужого кода. Могу взять на себя полную ответственность за интеграцию чужого патча в мой код. Могу выполнить реинжиниринг кода, опираясь на исходную спецификацию, а также точно спрогнозировать, какой объём работ потребуется для адаптации данного кода к новой спецификации. Могу выполнить реинжиниринг кода без исходной спецификации и точно спрогнозировать, какой объём работ потребуется для адаптации данного кода к новой спецификации.
Встраивание в более крупную систему Знаю входные и конечные точки того кода, который пишу. Могу использовать основные каналы ввода/вывода моего языка для ввода и вывода простого текста и чисел. Мне знакомы рекомендуемые механизмы приёма программных опций/параметров от среды выполнения, а также сигнальных ошибок. Умею пользоваться этой информацией при написании кода. Могу делегировать функцию внешнему процессу во время выполнения. Знаю, как продуктивно использовать поточность и буферизацию для работы с большими множествами данных и как использовать их в моём коде. Имею представление о локальности и использую её при доработке моих реализаций. Мне знаком как минимум один API для двунаправленной коммуникации с другими процессами во время выполнения. Могу писать клиентский код для простых протоколов Интернета. Знаю наиболее распространённые требования, предъявляемые к упаковке и редистрибуции как минимум на одной платформе, использую их в собственных проектах. Могу использовать заранее определённые паттерны программирования, чтобы эффективно использовать платформенный параллелизм в моём коде. Могу реализовывать как клиентское, так и серверное ПО по спецификациям любых протоколов. Могу дать точную количественную оценку пространственных и временных издержек, связанных с различными механизмами коммуникации (например, с системными вызовами, каналами, сокетами). Знаком с аппаратными архитектурами и могу спрогнозировать, как будут работать последовательные программы при внесении изменений в аппаратное обеспечение. Могу оценить масштабируемость фрагментов кода, параллельно выполняемых на заданной платформе. Знаком с большинством программных архитектур, используемых в тех системах, для которых я программирую. Могу работать в паре с системным архитектором для обоюдного согласования архитектуры моей программы с общей архитектурой большой системы. Знаком с большинством компромиссов «затраты/выгоды», существующих на уровне проектирования и эксплуатации тех систем, для которых я программирую.
  A1
Начинающий специалист
A2
Начинающий специалист
B1
Продвинутый специалист
B2
Продвинутый специалист
C1
Опытный специалист
C2
Опытный специалист
Понимание
Повторное использование кода Могу собирать фрагменты программы, переименовывая переменные, до тех пор, пока вся система не станет сбалансированной и отвечающей поставленным требованиям. Имея библиотеку, состоящую в основном из чистых функций, а также подробную документацию по API, могу продуктивно повторно использовать эту библиотеку в моем коде. Могу распознавать ситуации, когда для повторного использования имеющегося кода требуется конкретная общая архитектура (например, наличие цикла событий). Могу заранее адаптировать мой код к требованиям нескольких отдельных библиотек, которые я планирую повторно использовать. Могу распознавать и извлекать из большой базы кода компоненты, пригодные для повторного использования, затем применять их в собственной работе, даже если автор изначально не предусматривал такого повторного использования. Умею упаковывать, документировать и распространять программную библиотеку, чтобы ею могли пользоваться другие. Могу сочетать код, не сохраняющий состояния, взятый из разных языков программирования. Умею систематически удалять из имеющегося кода такие ограничения, которые не предписаны спецификацией, для обеспечения максимальной универсальности. Читаю и понимаю код, который использует наиболее распространенные API из моей предметной области, не обращаясь к документации. Могу сочетать код, взятый из разных языков программирования и имеющий характерную операционную семантику. Могу выявлять и надёжно использовать недокументированное или непредусмотренное поведение любого кода, написанного на известном мне языке, в частности, такого кода, который писал не я.
Объяснение и обсуждение кода Могу читать написанный мной код и объяснять его значение более опытному коллеге. Могу читать код коллеги, который сопоставим со мной или немного уступает мне в профессионализме, объяснять, что значит этот код. Могу распознавать и объяснять простые несоответствия между спецификацией и реализацией моего кода либо кода коллеги, чей уровень сопоставим с моим или ниже моего. Могу демонстрировать и объяснять фрагменты кода, написанные мной в императивном или декларативном стиле, кому-либо, кто знает другой язык программирования, в котором применяется такой же стиль. Этот человек после моих объяснений сможет воспроизвести такой же функционал на своём языке программирования. Могу объяснить мои структуры данных, алгоритмы и архитектурные паттерны коллеге, используя при этом стандартную терминологию моей предметной области и не обращаясь непосредственно к коду. Могу оценить профессиональный уровень моей аудитории и соответствующим образом скорректировать беседу с этими коллегами. Понимаю, когда объяснение является поверхностным или недостаточно подробным для данной аудитории и соответствующим образом реагировать на ситуацию. Без труда могу принимать участие в любой дискуссии о языке, на котором я программирую, хорошо знаком с идиоматическими конструкциями. Могу без подготовки писать верные и наглядные примеры кода для иллюстрации любых концепций, которые мы обсуждаем с коллегами.
  A1
Начинающий специалист
A2
Начинающий специалист
B1
Продвинутый специалист
B2
Продвинутый специалист
C1
Опытный специалист
C2
Опытный специалист
Взаимодействие
Исследования, самообучение Различаю приглашение командной строки в оболочке и приглашение для ввода в программу, запускаемую из этой оболочки. Могу читать онлайновые руководства без посторонней помощи и достигать планируемого результата. Умею находить текст распространённых сообщений об ошибках и использовать для решения поставленных передо мной задач опыт других людей. Различаю общеязыковые возможности и возможности, специфичные для конкретной реализации на языке. Могу без посторонней помощи читать текст сообщений об ошибках, понимаю, что он означает. Могу читать справочную документацию по языку (языкам) или API, с которыми я работаю, обращаться к такой документации и разбираться в произвольных фрагментах кода. Понимаю общие концепции, рассматриваемые в статьях и презентациях, написанных экспертами. Могу отслеживать и определять, кто отвечает за произвольный фрагмент кода в системе, которую я использую или для которой программирую. Могу логически выводить абстрактный алгоритм работы API или библиотеки по интерфейсу, не обращаясь к документации. Могу писать небольшие тестовые программы для проверки того, насколько точна моя модель. Распознаю случаи, в которых документация по языку или API является неполной или не соответствует справочной реализации. Читаю и понимаю большинство экспертных работ по тем языкам, которыми я пользуюсь. Понимаю, какие академические инновации применимы в моей предметной области и умею адаптировать их к использованию в собственных проектах. Умею распознавать и использовать неявные допущения, содержащиеся в экспертной литературе, посвящённой моей предметной области. Уверенно определяю, когда рассказ о программистском достижении или его описание является ложным или дезориентирующим, не выполняя для этого специального тестирования.
Степень владения средой разработки Использую обычную среду разработки, поэтапно следую обычным процедурам тестирования и запуска программы. Могу интегрировать мои файлы исходников в среде разработки, автоматизирующей большие фрагменты моего рабочего процесса при программировании. Использую контроль версий для отслеживания прогресса моей работы и для возможности отката к стабильной версии, если внесённые изменения оказались неудачными. Отмечаю и использую отслеживание зависимостей в моей среде разработки во избежание лишних (повторных) вычислений в моих циклах разработки. Могу использовать при контроле версий различные ветки разработки для решения разных практических задач. Использую разные потоки задач в разных проектах, умею выбирать различные компромиссы между исходными установочными издержками и долгосрочными издержками, связанными с технической поддержкой программы. Могу входить в чужую среду разработки, если уровень этого коллеги сопоставим с моим или ниже моего, после минимального обучения дописывать код в этой среде. Модифицирую мою среду разработки, приспосабливая её под мой персональный стиль, могу количественно оценивать, как эти изменения сказываются на моей продуктивности. Могу эффективно использовать любую среду разработки, в которой предпочитают работать как минимум 80% программистов сопоставимого со мной или более низкого уровня. Уверенно умею распознавать и количественно оценивать нестыковки, возникающие в работе других программистов и связанные с тем, какие среды разработки они предпочитают. Могу заметно повысить производительность труда коллег, помогая им подогнать среду разработки под их персональные стили программирования.
Устранения неполадок Различаю правильный и неправильный вывод в моих собственных программах. Владею этикетом, принятым при обращении за помощью к специалистам в моей предметной области. Уверенно отличаю неверный вывод, обусловленный неверным вводом, и неверный вывод, вызванный программной ошибкой. Могу локализовать место возникновения ошибки в сложной программе до конкретного модуля или функции. Могу находить и исправлять борбаги в моем собственном коде. Могу излагать точные знания или спецификации инвариантов в виде утверждений об ограничениях типов в моём коде. Могу отслеживать состояние программы во время выполнения и проверять, соответствует ли оно известному инварианту. При необходимости могу писать и использовать модульные тесты. Могу свести программную ошибку к простейшей демонстрационной программе, в которой возникает такая ошибка. Имею одну или более рабочих стратегий для отслеживания и устранения гейзенбагов в коде, который понимаю. Пишу и использую регрессионные тесты для кода, с которым непосредственно работаю. Могу разрабатывать систематические стратегии для отслеживания и устранения мандельбагов в коде, который понимаю. Могу распознать в системе такой аппаратный баг, возникновение которого, в основном, обусловлено написанной мной программой. Могу отслеживать и определять ответственность за большинство неожиданных/нежелательных поведений в тех системах, для которых я программирую. Могу отслеживать и находить в системе аппаратные ошибки, если имею доступ ко всему исходному коду этой системы.

Методология разработки таблицы

Как уже упоминалось, таблица была разработана в соответствии с методологией CEFR:

В начале были распознаны различные варианты модальности (производство, восприятие, взаимодействие, посредничество). Затем виды деятельности были сгруппированы по признаку модальности в кластеры, объединяемые по признаку сходной мотивации и акторов. Полученные таким образом множества образовали строки в матрице.

Далее были сформулированы требования для уровней А. Они призваны выделить пользователей, которые могут работать с языком под контролем или персональным руководством коллег.

Требования для уровней B выделяют пользователей, способных работать с языком без контроля или руководства со стороны коллег, обращаясь к коллегам за минимальной помощью.

Требования для уровней C – пользователей, способных работать языком совершенно самостоятельно и демонстрировать высокие профессиональные (экспертные) навыки по сравнению с большинством других пользователей, работающих с этим языком.

Автор: программист, математик и преподаватель Амстердамского университета Рафаэль Посс.
Первоисточник: science.raphael.poss.name