Честно говоря, даже не рассчитывал на такой отклик на мой предыдущий пост. 30 подписчиков на Youtube, ценные комментарии и советы, да и просто слова поддержки!
К сожалению, охват моих видео пока не очень большой, хотя видео про STAR приняли очень тепло, судя по лайкам.
На самом деле, затевая эксперимент "Кодим с ChatGPT", я был почти уверен, что сколь-нибудь значимых результатов я не получу. Но похоже, я начинаю сам себя опровергать. Чатбот сумел не просто предложить решение проблемы (например, "сделать форму авторизации"), но и решить абстрактную задачу "сделать форму красивой".
Кроме того, он неплохо разбирается в существующих библиотеках и сумел предложить мне два очень приличных варианта с полнофункциональным календарем. И это притом, что я использую версию 3.5, а не 4. В общем, мне кажется, из всего этого выйдет неплохой результат, но посмотрим. До работающего приложения еще очень далеко.
Одно могу сказать точно: если бы я писал код с нуля, я бы потратил на него раз в 5 больше времени, с учетом исправления всех ошибок, которые иногда допускает chatGPT.
Ну и немного внутренней кухни (кажется, эта рубрика становится постоянной):
Тема для видеоблога выбрана весьма непростая для новичка, ведь мне недоступна опция "перезаписать видео", если в процессе записи что-то пошло не так. Это же chatGPT, который запоминает контекст. То есть, я:
а) не могу просто как ни в чем не бывало заново его просить делать то, о чем уже просил (потому что он "знает", что я уже задавал этот вопрос и его ответ будет учитывать предыдущие ответы)
б) не могу начать новый чат с нуля, потому что для записи следующего ролика мне нужно, чтобы ИИ знал контекст предыдущего.
Приходится танцевать с бубном. Например, после записи я понял, что у меня был косяк с гарнитурой и звук был фиговый. Пришлось на имеющийся видеоряд с записью экрана накладывать новый аудио-видео ряд с голосом и миниатюрной головой. Это вылилось в адок на монтаже, общее время монтажа 17-минутного ролика составило часов 15. Всё для вас, дорогие будущие зрители :)
Спасибо за поддержку, буду рад новым подпискам на канал и идеям по развитию!
Так исторически сложилось, что у нас на проекте нет юнит тестов, только интеграционные и e2e.
Эволюция написания тестов
Иногда в тестах приходится подчищать за собой — удалять созданные во время выполнения теста объекты в базе, чтобы не влиять на результат других тестов. Это конечно, лишь ухудшает читабельность кода.
Мы прошли некоторая эволюция подходов для создания и удаления объектов:
1. Мы использовали try/finally, где все созданные объекты удаляются внутри блока finally. Выглядит сомнительно, когда нужно городить подобную конструкцию во многих тестах. 2. Перешли к использованию функций с колбэками. Утилитная функция создаёт и удаляет объект, а мы передаём лишь колбэк, в котором описываем логику теста и нужные нам проверки. 3. Внедрили IDisposable классы, которые мы называем Creator’ами. Они делают то же самое, что и функции с колбэками, но не добавляют ненужную вложенность, что улучшает читаемость кода. Они чем-то напоминают PageObjectModel в e2e тестах.
Использование паттерна с классами IDisposable также подходит для активации определенной настройки только в рамках одного теста и отключения её по завершении теста.
Такой подход не ограничивается только лишь C# — в TypeScript 5.2. уже появилась поддержка using и, возможно, скоро она появится и в JavaScript.
В своем предыдущем посте я рассказал про проект, который сделал чтобы (в том числе) доказать самому себе, что могу что-то сделать с нуля и до конечного результата. Прошло 6 месяцев с начала запуска и решил подвести некоторые итоги. К тому же и год заканчивается – тоже повод.
Для ЛЛ: сделал сайт и рассказываю с какими проблема столкнулся, какие ошибки допустил, чего добился.
Как не старался написать кратко, но все ровно вышла «простыня». Видимо, нет у меня таланта излагать свои мысли кратко. Пардоньте.
Начну с проблем. Все же писать про позитив легко, а признавать ошибки бывает сложнее.
Проблемы
Как я рассказал ранее, я сильно упростил первоначальную идею и сделал почти классический «джоббоард» (оказывается, есть такой термин среди HR). Так вот, для тех, кто хочет создать подобный проект, знайте – это не лучшая идея. Пообщавшись с HR скажу, что это даже глупая идея в 2023 году. Если уж так хочется играться с вакансиями, то смотрите в сторону HR-агентства. Хотя и там полно своих подводных (и порой острых) камней. В джоббоард большая конкуренция и очень сложно отожрать хотя бы какой-то значимый кусок. Мой западный аналог имеет донора в виде мощной рассылки на десятки тысяч подписчиков. Наличие такого ресурса позволяет работодателю получить не только размещение на сайте, но еще и быть прорекламированным в профессиональном сообществе. За что, кстати, готов произвести оплату. У меня такого ресурса нет и на его построение уйдут годы, если вообще получится сделать нечто подобное.
Признаюсь, что был сильно удивлен тому факту, что буквально через пару дней на сайт полезли боты. Нет, я был готов к тому, что придут всякие поисковики, но вот они как раз и не пришли сразу. А налетели всякие сканеры, накрутчики и прочая мерзость. Через неделю доля паразитного трафика была примерно под 98%. Пришлось заниматься не свойственной для себя работой – «сисдаминством». Поставил и настроил fail2ban, прикрутил к нему несколько фильтров, допилил движок проекта под перманентные баны всех, кто запрашивает страницы, которых у меня нет и никогда не будет, но которые используются для взлома или аутентификации на сайте. В целом, много кого победил, но искоренить зло полностью не получится. Есть море упертых ботов, которые лезут через прокси и пытаются что-то сделать.
Разочаровал Яндекс, который совсем не борется или хотя бы фильтрует роботов, которые работают на понижение поведенческих факторов. В Метрике куча левака, которое можно было бы отсеять. Уходить за Cloudflare не хочется. Тоже надо думать, что с этим делать (или не делать).
Пережил многодневную «атаку» со стороны какого-то левого скрипта, размещенного на Амазоновских серверах. Почему я был ему интересен до сих пор не понимаю. Паразит каждую минуту выкачивал весь сайт с разных ip или долбил его разными запросами. Это на DDOS не похоже, сервер нагрузку держал без проблем, но к чему была такая активность – не понял. Написал саппорту AWS, приложил логи, но там сказали, что ничего криминального не видят. На второй день снова им написал, что скрипт работает по расписанию, что выкачивает весь сайт и все это не нормально. Ответили вопросом, о том, что я хочу от них услышать? Попросил их проверить, что это за ерунда такая и вообще надо бы на кол посадить того, кто так делает. Обещали подумать и разобраться. Я же задолбался смотреть логи с IP от AWS и забанил все их сетки, которые нашел. Через несколько дней трафик от AWS исчез, а саппорт отписался, что поговорил со своим клиентом. На этом все закончилось.
Запросы, которыми был забит почти весь лог-файл.
Идем далее, от нытья к реальным проблемам. Одна из них – нет полной автоматизации по поиску и размещению вакансий. На размещение/модераторство у меня уходит не более 30 минут в день. Тем не менее, я думаю над тем, чтобы тратить на это не более 5 минут в день. Добиться не просто, так как часто цепляю реально не интересные вакансии, в которых нет описания того, что будет делать кандидат или нет вообще информации о работодателе/проекте. Бывают дни, когда вообще нет ничего интересного и это проблема, которую я решил, но пока в ручном режиме и способа автоматизации пока не вижу.
Вообще, я думал, что проект будет интересен компаниям, т.к. они бесплатно смогут разместить свои вакансии, но они на проект не пришли. Хочется надеяться, что пока не пришли. Если придут, то это решит проблему, описанную чуть выше. Повторю все же то, что написал выше: высокая конкуренция и определенная ниша – это не всегда способствует росту. Тот же hh будет интересен работодателю куда больше, чем мой специализированный проект пусть и с полностью целевой аудиторией. Пока компании не могут оценить потенциал моей аудитории и не готовы тратить на нее даже время, не говоря уже про деньги.
Отсюда получаем еще одну задачу: надо раскрутиться! Банальный совет, который лежит на поверхности и который так же банально требует денег. Я делал разные прикидки по бюджету, но в согласие с самим собой пока не пришел. Впереди 2-3 месяца стагнации на рынке труда из-за праздников. Так что пока активно в рекламу вкладываться не хочу. К тому же, я не маркетолог и слить первый бюджет это «как два пальца об асфальт». Много чего уже прочитал, посмотрел Ютуб (а где же еще учиться?) и пока раздираем сомнениями. У кого-то есть идеи на этот счет? Только условия как всегда самые лучшие: денег нет, а результат нужен =)
Ошибки
Когда делал дизайн первой страницы, то ориентировался больше на западный аналог. Проблема только в том, что ресурс у них уже раскрученный и они не нуждаются в некоторых вещах, которые нужны мне для нормальной индексации поисковиками или чтобы пользователи проходили в глубь сайта. Так что первую страницу я загубил, сам занизил ее роль для всех, кто приходит на сайт. Уже внес некоторые корректировки в дизайн, навигацию, но считаю это не достаточным. Здесь еще нужно хорошенько поработать.
Я не делал акцент на телеграм-канале. Считал его нечто дополнительным к сайту. По факту, посмотрел конкурентов из похожих тематик и у многих все наоборот: сайт – это дополнение к телеграм-каналу. Например, у больших тг-кагалов по нескольку постов в день, информация в таком потоке теряется. А на сайте легко найти какую-то статью, она же индексируется поисковиками, ее можно положить в закладки, ее же рекламируют в телеге. И при этом она же может быть и трафиком для тг-канала. Так что и здесь надо поработать. Правда нагрузка вырастает, т.к. вести тг-канал – это, как оказалось, тоже весьма затратное по времени дело. Меня пока спасает автоматизация, т.к. все вакансии с сайта автоматом идут в телегу.
Скромные результаты телеграм-канала.
Далее напишу важную, как мне кажется, вещь. Она тоже на поверхности и описана во многих книгах в том или ином виде. Я ее озвучу так, как это получилось со мной. И я считаю, что ошибка мне сейчас обходится дороже всего. Напомню, что проект мы хотели сделать вчетвером: менеджер и три программиста (фронт и два быка бэка). Менеджер не только принес идею, но еще имел знания по раскрутке проектов, их продвижении. Да и язык у него подвешен правильно. Если надо, то мог уговорить сделать что-то нужное, а может и про инвестиции что-то в голове имел, мог что-то придумать и на этот счет. Фронт мог колдовать не только с кодом, но и с SEO. Ну, а остальные два мушкетера могли и с основным кодом шаманить, и немного в админство поиграть. Что в итоге: проект сделал один человек, который не может сразу заменить всех четверых. Я, конечно, мудак молодец, что сделал проект в одиночку. А как теперь его тянуть одному? Осознание этого приносит понимание того, что проект будет долгим. Просто потому, что ты один впахиваешь за четверых. Поиграть в Д'артаньяна, конечно, получилось. Но без команды все куда сложнее. И моя ошибка в том, что не поговорил хотя бы еще с одним из членом нашей могучей кучки и не предложил ему присоединиться, когда заканчивал проект. Так что вывод: если хотите сделать проект, то не старайтесь все делать в одиночку. В книжках пишут про то, что должно быть минимум 3 человека в команде с разными компетенциями и я с этим сейчас (потирая шишку на лбу) полностью согласен. Да, я делал проект чтобы доказать одно. Но по факту шагнул немного дальше и теперь имею все шансы заработать «орден сутулого». А знаете, что еще плохо в работе одного человека? Тебе не с кем обсудить идею! Второе или третье мнение могут как-то трансформировать идею или вовсе ее отбросить. Иначе ты что-то придумываешь себе, веришь в это, убеждаешь себя в этом, тратишь силы на реализацию, а по факту это все никому не нужно. Некому тебя оставить, одернуть или наоборот - предложить что-то такое, о чем ты сам не думаешь.
Так же сейчас задаюсь вопросом про окупаемость проекта. Раньше думал, что надо просто сделать сайт. Теперь же хочется добиться самоокупаемости. Звучит как очередной вызов, получение некой ачивки. Это не очень больше деньги, так как основные траты — это оплата хостинга. Свою работу пока не считаю. Пожалуй, размещение рекламы спасло бы ситуацию, но трафика не хватает, чтобы получить прописку на приличной площадке для контекстной рекламы. А продавать всякие «казино» совсем не хочется.
Позитив
То, что есть позитив – это основное, что позволяет не бросить это все в корзину.
Главное - проект работает. И даже есть свои достижения. Например, аудитория телеграм-канала выросла в 3 раза! Согласитесь, звучит солидно. Есть только одно маленькое «но»: (Гусары! Не ржать!) рост составил с двух человек до шести =) Прямо так и вижу слайд какой-нибудь мощной презентации с графиком о трех кратном росте и маленькой подписью внизу о реальных цифрах. Все как в рекламных проспектах.
Сделал несколько улучшений, добавил пару разделов, поработал с SEO. В Яндексе стал вылезать по дополнительным запросам. Конечно, это не сильно делает погоду, но это все же трафик. Так же появились идеи для пары других разделов. Это плюс, потому что если будут изменения на сайте, будет рост количества страниц, то это все будет отмечено поисковиками. Пока основную ставку делаю на них. Еще бы добиться того, чтобы Яндекс более лояльно относился к сайту и вообще нормально будет. Пока Гугл ведет более качественную и основную аудиторию.
Из последних крупных обновлений в этом году – раздел с тестами по HTML, CSS, JavaScript и фреймворкам. Еще нужно поработать над несколькими вопросами, возможно, что-то добавить или заменить. Но в целом считаю, что раздел получился. Вопросов достаточно, чтобы они не повторялись, а ответы не идут по порядку. Так что можно проходить тест несколько раз подряд. База вопросов может без проблем дополняться или изменяться. У вопросов есть уровень сложности, но я пока это выключил. Надо над сложными вопросами подольше поработать, чтобы они больше соответствовали уровню знаний сильного кандидата. Из минусов, пожалуй, то, что не показываю правильных ответов. Решил сейчас этого не делать. Бонусом добавил две мульки, которые не видел у других: во-первых, я считаю время, которое потратил человек на тест, а во-вторых, если тестируемый уходит с активной вкладки браузера, то я это фиксирую и в конце теста выдаю ему сообщение. Это все мелочи, но лучше с ними, чем без них.
От проекта получил отклик, который вообще не предполагал. Дело в том, что с текущим местом работы прощаюсь. Это никак не связано с описываемым сайтом. Просто пришло время двигаться дальше (и глубже, ага). И вот один из коллег узнал о моих планах и посоветовал меня знакомым, которые ищут разработчика. Договорились просто устроить разговор между технарями (мной и их тимлидом), а если все срастется, то уже еще раз встретится и сделать все, как полагается. В подробности разговора вдаваться не буду, тут ничего интересного кроме того, что спросили (а кого из нас не спрашивали), что ты делал ранее и можешь ли ты показать свой код. Не будь у меня этой джобборды, я бы показать ничего не мог. Просто потому, что последние годы работы — это все то, что не видят простые люди (т.е. внутренние разработки компании). А код так вообще под всякими NDA и за закрытыми Git’ами живет. Так что показал то, что сделал. Дал доступ к своему гиту, показал код. Тимлид по нему побегал, задавал вопросы по типу «почему здесь так, а не иначе?». После просмотра проекта даже других вопросов не было. Тем более, что ответы мои были не только с позиции разработчика, но и менеджера, сисадмина. Возможно, что ничего в этом такого нет. И обычный фулл-стак разраб легко ответит на все вопросы и по фронту, и по бэку. Но все же мне хочется верить, что мои знания не так безнадежны, как я думал о них ранее. Это интервью несколько подняло (в очередной раз) мою самооценку. В любом случае, очень приятно рассказывать о том, что ты сделал сам и это оценивают те, кто тебя слушают. Жаль только мы по зарплате не договорились: предложили меньше, чем я зарабатываю сейчас. Рынок уже как-то остывает к большим з/п программистам, если смотреть вакансии на сайтах.
Еще сайт подарил мне одну идею. Обдумываю ее уже которую неделю, но делать не рвусь. Очень легко сразу ринуться в код, а потом снова переписывать, менять подходы. Так что рисую стрелочки, кубики, прикидываю все моменты. А уже потом начну действовать.
Хочу сказать огромное спасибо всем пикабушникам, которые перешли по ссылке на сайт из прошлого поста (вас было 64 человека), и кто написал комментарии с советами. Первые показали мне ошибки в навигации сайта и прочее, о чем я писал выше. Вторые дали дельные советы и я к ним прислушался. Мерси вам всем от (так по тексту получилось) Д’артаньяна и его проекта!
P.S. мой единственный (первый) подписчик, кто бы ты ни был, тебе отдельная благодарность просто за то, что ты есть =)
Замыкание (closure) в JavaScript - это функция, которая имеет доступ к своему собственному лексическому окружению, а также к окружениям внешних функций, в которых она была определена.
Это позволяет функции сохранять значения переменных и параметров из внешнего контекста, даже после того, как внешняя функция завершила свое выполнение.
Замыкание создается, когда внутренняя функция ссылается на переменные из внешней функции. Например:
function outerFunction() {
var outerVariable = 10;
function innerFunction() {
console.log(outerVariable);
}
return innerFunction;
}
var closure = outerFunction();
closure(); // Выведет 10
В данном примере функция innerFunction является замыканием, так как она ссылается на переменную outerVariable из внешней функции outerFunction. Даже после того, как outerFunction завершила свое выполнение и переменная outerVariable вышла из области видимости, замыкание все еще имеет доступ к этой переменной.
Замыкания часто используются в JavaScript для создания приватных переменных и методов. Они позволяют скрыть внутренние детали реализации и предоставить только необходимый интерфейс для работы с объектом.
Однако, использование замыканий может привести к утечкам памяти, если замыкание хранит ссылку на большой объем данных. Поэтому важно быть внимательным при работе с замыканиями и осознавать потенциальные проблемы производительности.
Интересные факты и фичи языков программирования у нас в канале, заходи :)
Как будет отсортирован следующий массив [-1, 0, 1, 2, -1, -4, -2, -3, 3, 0, 4].sort()?
🥱 Предыстория
На выходных я решал литкод, и в задаче 3sum было необходимо отсортировать массив по возрастанию, перед тем как перейти к основной реализации алгоритма.
Я написал решение, подебажил на бумаге — всё работает, отправляю код на проверку — не работает 🤷♂️. Перепроверяю всё глазами — ну должно же работать!
Сдаюсь и начинаю дебажить в VS Code и вижу, что сортировка массива работает не так как я ожидал.
ℹ️ Объяснение
Если перейти на MDN и прочитать документацию Array.prototype.sort(), то станет всё понятно.
Метод sort() в JavaScript преобразует элементы в строки и затем сравнивает их последовательности значений кодов UTF-16. Это означает, что при сортировке числа рассматриваются как строки.
Таким образом, числа в данном случае сортируются на основе их строкового представления. Например, '-10' будет идти перед '-2', потому что строка '10' идет перед строкой '2' в лексикографическом порядке.
Чтобы выполнить числовую сортировку массива, нужно предоставить функцию сравнения методу sort(), как показано здесь:
[-1, 0, 1, 2, -1, -4, -2, -3, 3, 0, 4].sort((a, b) => a - b);
Каррирование и частичное применение — две концепции из функционального программирования, которые очень часто путают из-за их схожести (а я пишу этот пост, чтобы наконец-то запомнить).
И частичное применение, и каррирование, реализуются как функции, принимающие в качестве параметра другую функцию.
1️⃣ Частичное применение — функция partialApply, принимающая первым параметром функцию — fn, а остальные параметры — часть параметров функции fn. Функция partialApply возвращает функцию, которая в качестве параметров принимает недостающие аргументы функции fn.
2️⃣ Каррирование — функция curry, которая принимает единственный параметр — функцию fn, и возвращает каррированную функцию fn. Можно сказать, что каррированная функция fn — функция аккумулятор, которая будет накапливать переданные аргументы до тех пор, пока не будет передано достаточно параметров для вызова исходной функции. Параметры можно передавать в любом количестве.