Важно сделать образовательный процесс интересным и по возможности интерактивным.
Особенно когда дело касается техники - гораздо полезнее, когда у тебя есть возможность не просто написать какой-то код, но потом получить ответ от рецензента, мол, молодец, все хорошо, и на лету посмотреть, все ли работает. для вас, где ошибки и насколько в целом вы справились хорошо.
В попытке сделать что-то подобное мы однажды запустили в Яндексе веб-симулятор MVP, в котором пользователь мог писать код, скрипты и все остальное на разных вкладках, а рядом с ним все это отображалось как конечный результат.
MVP показал себя хорошо, и мы подняли веб-симулятор до уровня полноценного инструмента для проверки знаний наших студентов в Яндекс.
Мастерская .
Меня зовут Артем, и я расскажу вам, как мы сделали симулятор для обучения веб-разработке, как он работает и что умеет. Со стороны кажется, что здесь все просто — запихнул весь пользовательский код в iframe, выложил через постсообщение, потом нарисовал любым возможным способом, и все работает. Это слегка обновленная онлайн-предварительная версия кода.
Но есть нюансы.
Как все работает
На старте мы отметили возможную проблему: если развернуть симулятор на домене Яндекса (как, например, сам Мастерская), то есть ненулевая вероятность, что пользователи будут чуть более любознательны.А именно, они возьмут и кинут в симулятор какой-то код, который симулятор с энтузиазмом начнет обрабатывать.
А код окажется мошенническим и заберет существующий cookie Яндекса, вставит его в какой-нибудь сторонний сервис, после чего мошенник получит доступ к личному кабинету пользователя в Яндексе и всем личным данным.
Это довольно легко реализовать, если данный iframe находится в домене yandex.ru. Поэтому специально для симулятора мы сделали отдельный домен на yandex.net и назвали его «Фейнман».
В честь Ричард , Да.
Как правило, наш симулятор хранит файлы, которые мы отправляем на серверную часть, в виде обычного текста, формата json и base64 для изображений.
Затем они конвертируются в реальные файлы и распространяются как статические файлы, которые мы можем поместить в iframe для рендеринга.
Но мы здесь не просто играемся с подсветкой синтаксиса, мы используем симулятор для проверки знаний.
Поэтому нам нужно тестировать и проверять этот код на лету, то есть как-то вклиниваться в процесс iframe и смотреть, все ли правильно сделал пользователь, скажем, как назвал переменную, или с дивами все в порядке.
.
И здесь мы снова сталкиваемся с доменами.
Пользовательский код, как я уже писал, размещается в симуляторе на фейнмановском домене, и мы проверяем его с яндекса, с домена praktikum.yandex.ru .
Политика браузера того же происхождения он просто стоит на страже и не позволяет вам вмешиваться во внутренности iframe, если у вас разные домены.
Поэтому мы решили запихнуть iframe в iframe.
Вот ситуация:
- Мы создаем iframe, который сначала пуст.
- Он рисует какую-то пустую страницу.
- Мы отправляем сообщение с фронта со ссылкой на то, что дал нам Фейнман (откуда он размещает статические данные).
- Первый iframe берет эту ссылку и вставляет ее в источник внутреннего iframe.
Не только тестами
Потом нам захотелось добавить несколько полезных функций: терминал, консоль, возможность отображать данные пользователя о том, что он написал в журнале и прочие радости.Конечно, мы сделали полноценный адаптивный режим, чтобы пользователь мог видеть, как результат будет выглядеть на смартфонах и планшетах.
Для этого была написана специальная библиотека, загружающая все необходимые стили и эмулирующая адаптивный режим.
Также мы немного меняем наш исходный iframe и добавляем в него все, что позволяет пользователю отображать на экране его console.log, причем не только какие-то простые объекты, но и полноценные dom-деревья документа.
Помимо этого мы научились проводить предварительные тесты.
Это полезно, потому что существует множество тестов, проверяющих примерно одно и то же — например, не переборщил ли пользователь с циклами в коде, не увлекся ли вложенностью и тому подобное.
Описывать это в каждом тесте отдельно нет особого смысла, поэтому мы написали тестовую библиотеку, имеющую набор специальных методов предварительного тестирования, проверяющих код. Если на этом этапе все хорошо, то проверяются основной тест и решенные задачи, после чего пользователю показывается результат. Чтобы выдать пользователю результат предварительного тестирования, мы также используем postmessage — отправляем через него сообщения, были ли найдены какие-то ошибки или всё круто.
Кстати, код ученика в веб-тренере тоже проверяется через линтер es-lint с переводом на русский язык и всегда подсвечивает синтаксические ошибки.
Проблемы с ревью кода (и не только)
Если на странице были какие-либо системные или браузерные уведомления, например, было предложено что-то ввести, то зачастую при запуске нашего теста пользователь продолжал видеть окна браузера с уведомлениями и запросами на ввод данных.Нам пришлось сделать так: когда пользователь просто запускает страницу со своим кодом, чтобы посмотреть, как все работает, нам нужно, чтобы это оповещение тоже работало.
И когда тест запускает этот код для проверки, нам больше не нужно, чтобы оповещения продолжали появляться на экране пользователя.
По сути, мы заменили все эти оповещения собственными заглушками для тестов (макетами), переопределив оповещения, подсказки и подтверждения внутри окна.
Если вы этого не сделаете, вы можете получить цикл или пустое предупреждение, которое ничего не делает. Кстати, о бесконечных циклах.
Основная проблема здесь заключалась в том, что пользователь мог сознательно написать код, который попадал бы в бесконечный цикл (в браузере есть только один поток javascript), и в результате весь браузер уходил бы спать.
Чтобы бороться с этим, мы научились сначала отслеживать такие бесконечные циклы, прежде чем отправлять код на проверку.
Для этого нам пришлось как-то доработать пользовательский скрипт, поэтому мы пошли по такому пути:
- Мы добавляем в каждый цикл определенную функцию, которая подсчитывает количество вызовов.
- Если это количество вызовов превысит 100 000, мы немедленно выдадим исключение, которое также отправим обратно через пост-сообщение.
Плюс на всякий случай проверяем еще и таймаут, если цикл выполняется более 10 секунд.
- Попутно следим, что раз произошло исключение, значит, что-то здесь не так, и сам тест запускать уже нет смысла — код зацикливается.
Допустим, у пользователя могут быть некоторые ссылки внутри его кода, которые должны открываться в новой вкладке при нажатии, например, его портфолио или учетная запись github. И нам не нужно, чтобы такие ссылки открывались непосредственно внутри iframe — иначе вместо iframe откроется страница с его ссылкой.
Открывать такие вещи нужно в новой вкладке, через Tab. Обычно, чтобы открыть ссылку не внутри iframe, а в родительском фрейме, достаточно указывать цель="_родитель".
Но в нашем случае нам нужно было добавить обработчик, определяющий, является ли ссылка внешней.
И для всех ссылок мы написали специальный обработчик: если мы видим, что ссылка внешняя, то мы отправляем постсообщение, завершаем сам обработчик ссылки (предотвращаем дефолт), и постсообщение возвращается к нам на передний план.
Видим, что у нас здесь внешняя ссылка, и показываем уведомление — неужели мы идём на внешний сайт? И после этого открываем новые вкладки.
А еще якоря, с ними все было гораздо проще.
Они просто не работали внутри iframe. Совсем.
Поэтому в качестве небольшого хака мы подписывались на события кликов по любой ссылке — если у нее был якорь, мы делали прокруткуIntoView на конкретном элементе.
Мы также отправляем все метаданные (например, если у пользователя был значок значка или определенный заголовок на HTML-странице) через почтовое сообщение после загрузки iframe. Используя querySelector, мы получаем эти два тега, отправляем их обратно на фронт через postmessage, а фронт сам вставляет все эти значки куда нужно.
Вроде бы мелочь, но у пользователя складывается впечатление, что у него внутри браузера полноценный браузер.
Попытки обойти симулятор
Наш веб-симулятор, в отличие от симуляторов, которые мы создали для Python, SQL и других, для проверок использует фронтальную часть, а не серверную часть.Поэтому, когда пользователь правильно завершает тесты, на бэкэнд отправляется соответствующий POST-запрос.
В принципе, пользователь при должной квалификации может сделать то же самое и отправить такой запрос вручную.
Это палка о двух концах.
С одной стороны, круто, что человек достаточно интересуется технологиями и базовыми хаками, чтобы этим заниматься.
С другой стороны, это немного похоже на выстрел в ногу, потому что у нас тренажер не для того, чтобы формально получать от него «ОК, ты молодец, ты все сделал», а для того, чтобы научиться нормально работать, замечать свои ошибки.
и исправьте их.
В общем, это то же самое, что пойти в спортзал, посидеть 5 минут на скамье для жима лежа, а потом написать в Фейсбуке «Я сделал 3 подхода со ста килограммами»: потешишь свое эго, но на этом и достижения.
останавливаться.
Собственно, поэтому мы и не переносим эту проверку на бэкенд, это решило бы аналогичную проблему.
Люди приходят учиться, чтобы получить реальную работу (может быть, в самой Мастерской), а не виртуальные достижения.
Мы постоянно совершенствуем веб-симулятор, используя как собственный список пожеланий, так и отзывы пользователей, поэтому продолжим рассказывать вам о его разработке.
Сейчас он дорабатывается с учетом потребностей студентов с запросами на конкретные технологии, например, мы добавили работу с React и NodeJS. Веб-тренер на сегодняшний день является самым популярным из всех, за ним следует тренер Python — по большей части это связано как с более низким входным барьером, так и с популярностью самих технологий.
Помимо технической части, внутри тренажера также есть много механик для работы с интерактивной теорией (а ее достаточно на всех наших курсах).
Отдельного симулятора нет только по специальности QA; там мы сделали специальный набор викторин+стендов, на которых учатся тестировщики.
Кстати, пара тестировщиков, которые сейчас помогают нам проводить Мастер-класс, являются выпускниками нашего Курс контроля качества .
Симуляторы для C++ и симуляторы машинного обучения более сложны; если вам интересно, мы постараемся рассказать о них в следующих постах.
Спасибо за прочтение, если у вас есть вопросы по нашим тренажерам или по Мастерской в целом - пишите, ответим.
Теги: #Карьера в IT-индустрии #программирование #Образовательный процесс в IT #JavaScript #обучение #веб-разработка #Яндекс-мастерская #интерактивное обучение #веб-тренер
-
Зима – Самое Жаркое Время Для Фрилансеров
19 Oct, 24 -
Идея Для Капчи. Генерация Шрифтов.
19 Oct, 24 -
Geforce За 59 Долларов
19 Oct, 24 -
Зимняя Матрица...
19 Oct, 24