Месяц назад я получил уведомление от github, что я могу бесплатно использовать github copilot в течение одного месяца. Примерно через год в списке ожидания пришло время протестировать его и изучить его возможности.

Я протестировал его на трех случаях с использованием javascript, так как это один из языков, на котором второй пилот хорошо играет.
Первый случай — это алгоритмические вопросы из leetcode, один простой и один сложный.
Во втором случае я хотел увидеть решения для более ориентированных на проекты вещей в простом javascript (без использования какой-либо структуры).
Третий случай — это снова вопросы, ориентированные на проект, на этот раз с использованием фреймворка. Я использовал фреймворк React.
Поэтому я добавлю сгенерированный Copilot код с пояснениями/предложениями с моей стороны.
Кроме того, в конце каждого случая я буду оценивать его как неудачно или пройдено, в зависимости от того, насколько я был удовлетворен решениями. (Этот шаг не предпринимать Это слишком серьезно)
Первый случай — алгоритмические упражнения
Легко: проверьте, является ли число палиндромом, то есть остается ли число тем же, когда его цифры переставлены местами.
Решение Github Copilot:

Как мы видим, в этом коде происходит много всего.
Во-первых, используются два if, поэтому создаются два ветвления вместо одного. Что-то, что влияет на процессор и работает медленнее.
Предпринимается дополнительный шаг для преобразования числа в строку и сохранения этого значения в памяти, а позже то же самое происходит с размером строки, которая также хранится в памяти.
Из цикла while мы можем понять, что алгоритм имеет временную сложность O(n).
Человеческое решение:

Временная сложность проверки того, является ли число палиндромом, составляет O(log10(n)).
Потому что мы делим число на 10 на каждой итерации.
Таким образом, можно сказать, что временная сложность равна количеству цифр в числе.
Также не используются два if и не делается лишнее преобразование числа в строку.
Сложно: учитывая заголовок связанного списка, переверните узлы списка k за раз и верните измененный список.
Решение Github Copilot:

Представьте, что у вас есть связанный список с 9 узлами в голове:
голова вар; // начало списка
/* Узел связанного списка */
class Node {
конструктор(val) {
this.data = val;
this.next = null;
}
}
function push(new_data) {
/*
1 и 2: выделить узел и вставить данные
*/
new_node = new Node(new_data);
/* 3. Сделать следующий из новых узлов головным */
new_node.next = head;
/* 4. Переместите голову так, чтобы она указывала на новый узел */
head = new_node;
}
И мы нажимаем на список в этом порядке, чтобы получить следующий сконструированный список:
1-›2-›3-›4-›5-›6-›7-›8-›9-›нуль
push(9);
push(8);
push(7);
push(6);
push(5);
push(4);
push(3);
push(2);
push(1);
В решении второго пилота мы видим, что есть ошибки, но давайте по порядку с логикой.
Устанавливает переменную next равной следующему узлу текущего узла.
следующий = текущий.следующий;
Позже он устанавливает current.next в null.
current.next = null;
Это неверно, правильно current.next равно prev, поэтому:
текущий.следующий = предыдущий
А ниже, если мы видим, в коде много логических ошибок, в которых нет особого смысла.
Очень важно сказать, что мы говорим о функции, которая переворачивает первые k узлов, а не обсуждаем всю реализацию.
Такая вещь выходит за рамки и, возможно, решение будет проанализировано в следующей статье.
Итак, вот правильное решение для обратной функции:
Человеческое решение:

Таким образом, результатом первого случая будет:

Второй случай — проектно-ориентированные упражнения с простым JS
В этом случае я подумал о создании четырех примеров, которые могут понадобиться разработчику javascript в его повседневной жизни.
Я хотел посмотреть, как ведет себя второй пилот в вещах, связанных с проектом.
Поэтому я выбрал несколько самых популярных областей, существующих на данный момент, таких как машинное обучение, разработка игр, преобразование данных и модульное тестирование.
Давайте рассмотрим их по порядку:
Проект машинного обучения – Прогноз цен на биткойны
Для предсказания биткойнов Copilot генерирует приведенный выше код, который еще не полностью функционален, потому что в нем упущены некоторые важные части, о которых нам нужно подумать.
Прежде всего мы должны создать csv с данными с необходимыми ключами и значениями.
Это снова достаточно просто с помощью второго пилота:

Вторая проблема в том, что мы не знаем, какую библиотеку он использует для обучения модели, конкретно в строке:
var model = ml.regression.linear(features, labels);
С одной стороны, это правильно, потому что показывает, что следует использовать линейную регрессию, поскольку в этом типе задач линейный регрессионный анализ используется для прогнозирования значения переменной на основе значения другой переменной,но мы не знаем, какую библиотеку следует использовать.
Поэтому нам нужно будет выполнить ручную работу, чтобы либо создать функцию (https://blog.oliverjumpertz.dev/simple-linear-regression-theory-math-and-implementation-in-javascript), либо интегрировать соответствующую библиотеку. например TensorFlow(https://towardsdatascience.com/linear-regression-with-tensorflow-js-e7b39713572).
Итак, в заключение мы хотели бы сказать, что второй пилот дает вам хороший скелет и создает достаточно хороший логический дизайн, чтобы иметь хорошую отправную точку, но разработчику определенно потребуется много исследований, чтобы реализовать относительно хорошее решение и принять с учетом других параметров.
Простая разработка игр — создайте игру в понг
Мы видим, что здесь была проделана лучшая работа с точки зрения описания и построения функций и объектов.
Тем не менее, и здесь следует поработать над пользовательской частью и случаями того, что происходит, когда он нажимает стрелки.
Пример:
if (e.key == ‘Enter’) { gameState = gameState == ‘start’ ? «играть» : «начать»;}
Простое управление данными

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

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

Третий случай — REACT
На этом этапе мы проведем три эксперимента, и степень сложности будет скалярной:

Здесь, как мы видим, второй пилот сделал именно то, что мы ему сказали.
То есть создать функциональный компонент и компонент класса реакции, а затем экспортировать один из двух.
Ниже мы протестируем создание конкретного компонента, начиная с самого простого случая до чего-то более сложного, а затем оценим его.
Создание очень простого компонента реакции:

Создание более динамичного компонента реакции:

Создание гораздо более динамичного компонента реакции с использованием состояния:

Мы заметили, что, даже если в некоторых случаях необходимо добавить какие-то функции в прослушиватели onChange и т. д., результат получается достаточно хорошим.
Итак, в целом для реакции мы можем сказать, что второй пилот:

Заключение
Github Copilot в большинстве случаев представляет собой очень продвинутое автозаполнение.
Он может создавать очень продвинутые скелеты, но вы должны быть достаточно опытны, чтобы иметь возможность судить о качестве решений, которые вам дают.
Спасибо, что прочитали!
Ура!