• Запутался в изучении JavaScript. С чего начать?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ни одна книжка или видео курс не позволит Вам освоить язык программирования. Хорошие книжки или видео курсы помогут усвоить хорошие практики, но только когда Вы уже что-то умеете. Притом без базовых знаний невозможно отличить хорошие книгу/курс от полностью отвратительных.

    Придумайте проект, который был бы полезен лично Вам или кому-то из близких/друзей/знакомых, и который Вам было бы интересно сделать. И просто начните его делать, гугля каждый раз, когда не знаете как сделать ту или иную вещь, а если не получается ничего нагуглить, то можно задать вопрос здесь. В начале Вы будете гуглить на каждый чих, это нормально. Но чем ближе Ваш проект будет к рабочему состоянию, тем реже Вам придется гуглить. Кроме того, если сразу делать такой проект фиксируя все изменения в git и выкладывая на githab, это сильно Вас выделит при поиске первой работы среди тысяч других новичков, но с проектами с курсов под копирку.
    Ответ написан
  • Как правильно собрать проект на nodeJs?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Бэк так же можно собирать сборщиками, у того же webpack есть пресет настроек под ноду.
    Насчет оптимизации, тот же terser.js, который включается при production билде по умолчанию, помимо сжатия делает ряд оптимизаций кода. Но для ноды работающей длительное время они могут оказаться менее значимыми, так как JIT v8 так же делает свои оптимизации, и многократно запускаемые функции наверняка будут им оптимизированы. Однако при возможности прогнать код через дополнительную оптимизацию, лучше это сделать.
    Насчет ejs, шаблоны нужно компилировать в js. В случае ноды это можно делать как при сборке, так и на старте приложения. Главное чтоб не происходило компиляции во время обработки запроса.
    Оптимизация картинок и css должна происходить при сборке клиентского кода, к ноде они вообще никакого отношения не имеют. Нода вообще не должна о них знать, максимум пути после сборки, чтобы вставить их в шаблон, хотя и это по хорошему решается сборкой. Отдаваться статика должна Nginx или аналогами.
    Ответ написан
    Комментировать
  • Как написать простейший webpack loader?

    bingo347
    @bingo347
    Crazy on performance...
    Первое, что нужно здесь понять, то что лоадер работает в compile-time, а Ваш js код где require - в run-time.
    Лоадер получает на вход исходный текст файла (или текст выданный предыдущим лоадером) и выдает свой текст на выход. Последний лоадер (в цепочке лоадеров webpack он стоит первым) должен выдавать валидный js.
    Ваш лоадер конечно может сгенерировать в выходном файле функцию, но на процесс компиляции она уже повлиять особо не сможет.
    Ответ написан
    Комментировать
  • Верно ли это утверждение?

    bingo347
    @bingo347
    Crazy on performance...
    Тут можно с разных сторон смотреть.

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

    Во-вторых, действительно успешные программисты - это, как правило, T-Shaped спецы. То есть это эксперты в небольшом количестве направлений, но с широким кругозором обо все что вокруг. И вот технологии и устройство компьютера относится как раз к этому вокруг. Опять же личный пример: моя сфера никак не связана с железом, операционками или чем-то еще низкоуровневым, но понимание как это все работает в купе с алгоритмами позволяет мне писать более быстрый код. Хотя кому-то может быть для этого достаточно, что коллега скажет, что массив работает значительно быстрее чем линкед лист, так как процессорный кэш больше похоже на массивы.
    Опять же, можно обойтись и без этого всего, но действительно успешным в профессии так вряд ли получится стать.

    Увлекаюсь программированием
    если действительно увлекаетесь, то есть Вам по кайфу сам процесс разработки, то можете не переживать, навыки они приобретаются и развиваются, а когда работа приносит удовольствие, то необходимые для нее навыки развивать в разы проще.
    Ответ написан
    2 комментария
  • Как дождаться загрузки iframe который формируется javascript?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ответ написан
    Комментировать
  • Возможно ли при ресайзе менять высоту обоих блоков с помощью CSS?

    bingo347
    @bingo347 Куратор тега HTML
    Crazy on performance...
    Добавьте к .wrapper
    display: flex;
    flex-flow: column nowrap;
    Ответ написан
    Комментировать
  • Как в строке удалить ненужный символ и при этом сократить саму строку?

    bingo347
    @bingo347
    Crazy on performance...
    ss = (char*)calloc(n, sizeof(char*)); // выделяем память под строку
    Здесь Вы выделяете гораздо больше байт, чем Вам нужно, sizeof(char*) будет равен 8 на 64 битных архитектурах, когда sizeof(char) - 1. Но при этом стоит не забывать про место под '\0' в конце строки.

    gets(ss);
    printf("Введите свое слово (не забываем про длину строки): ");
    scanf("%s", ss);
    ss = (char*)realloc(i, sizeof(char*));
    gets(ss);
    Почитайте, что делает функция gets. Опять же проблема с размерами символа. Ну и у realloc несколько другая сигнатура. И вообще realloc достаточно недешевая операция, не за чем ее делать в цикле много раз над одним указателем, достаточно 1 раз в конце.

    if (ss[i] != NULL) // проверка на нулевой указатель
    Проверку на NULL нужно делать сразу после аллокации памяти. А вот в цикле ее делать незачем.

    ss[j] = ss[j++];// здесь я заменял тот символ на следующий, тем самым перекидывая его в конец
    Операция j++ меняет j.

    for (int i = 0; i < sizeof(ss); i++)// ну а тут пытался поменять размер
    Операция sizeof(ss) даст размер char*, то есть размер указателя, что соответствует 8 на 64 битных архитектурах. Для вычисления длины строки (терминированной символом '\0') есть функция strlen. А в данном случае вообще можно посчитать количество удаленных символов и из него вычислить длину результирующей строки, что будет дешевле.

    Ну и по самому алгоритму. Все можно сделать за 1 проход, подсчетом удаляемых символов и перемещением текущего символа на количество удаленных символов назад.
    Ответ написан
    Комментировать
  • Как читать дженерики в TypeScript?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Данная функция принимает аргумент constructor любого типа T, который является подтипом типа { new (...args: any[]): {} }

    В свою очередь { new (...args: any[]): {} } - это абсолютно тоже самое, что и new (...args: any[]) => {}. Это сигнатура конструктора, с любым количеством любых элементов и инстанциирующий значение с типом {}.

    Ну и тип {} - это множество всех не нулевых значений (не только объектов), то есть по сути это как тип any, но без null | undefined и с не сломанной вариантностью. Здесь его безболезненно можно заменить на тип unknown, в отличии от тех же аргументов, где из-за контрвариантности аргументов функций (и конструкторов) предикаты на типах ломаются и без any нормально не сделать.

    В целом, под такой дженерик подойдет абсолютно любой конструктор
    Ответ написан
    2 комментария
  • Почему webpack не импортирует node_modules?

    bingo347
    @bingo347
    Crazy on performance...
    Все он импортирует, просто Вы не понимаете как работают модули:
    https://developer.mozilla.org/ru/docs/Web/JavaScri...
    Ответ написан
  • Как убрать такое выделение символов в vscode?

    bingo347
    @bingo347
    Crazy on performance...
    https://code.visualstudio.com/updates/v1_63#_unico...

    Фича вообще полезная, но стоит добавить кириллицу в editor.unicodeHighlight.allowedCharacters
    Ответ написан
    Комментировать
  • В чем моя ошибка stepik?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    произведение элементов массива
    let p = 1;
    // в цикле:
    p *= arr[i];


    кратных 3
    n % 3 === 0

    оканчивающихся на 5
    n % 10 === 5

    если таких элементов нет
    в общем случае делается введением флага:
    let hasElements = false;
    
    if (/* ... */) {
      hasElements = true;
    }
    Но конкретно в этом случае, так как 1 гарантированно не попадает под условия, а все остальные числа изменят произведение, можно проще p !== 1

    Вам осталось дело за малым, объединить эти кусочки знаний в единый алгоритм
    Ответ написан
    Комментировать
  • Что значат эти строки в коде на typescript?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    styled.li<{ menu?: any }>`

    Во-первых, к template string literal (``) можно применить функцию-тэг, она будет вызвана с массивом фиксированных строк и интерполируемыми значениями (`${/* вот этими */ value}`).
    Во-вторых, в TS функция может быть дженериком (принимать тип в качестве параметра), при вызове функции в дженерик можно передать конкретный тип (например { menu?: any }) или не передавать (тогда дженерик выведется автоматически из аргументов)
    В-третьих, так как тегирование template string literal по своей сути вызов функции, то и в него можно явно передавать дженерики.

    ${({ menu }) =>
        menu &&
        css
    А тут в качестве интерполируемого значения передается стрелочная функция, в которой деструктурирован первый аргумент. В данном случае это нормально, так как функция-тег получит данную функцию "как есть", без приведения к строке.
    Ответ написан
    1 комментарий
  • Почему определение инкапсуляции дают неправильно?

    bingo347
    @bingo347
    Crazy on performance...
    Цель инкапсуляции это объединение объектов
    кто Вам такое сказал?
    Само слово инкапсуляция происходит от латинского "in capsula", что можно перевести как "закрытый в коробке".
    Цель инкапсуляции - это сокрытие сложности. Не информации, не данных, не кода, а именно сложности.

    Вот представьте, у Вас есть лампочка с выключателем. Вы можете просто нажать на выключатель чтобы включить или выключить ее. Вам не нужно понимать электрические схемы внутри этого устройства, чтобы у Вас был свет. Вам достаточно пользоваться простым интерфейсом - выключателем. Это и есть инкапсуляция. Внутреннее устройство лампочки с выключателем инкапсулировано от Вас.
    Ответ написан
  • Почему так работают битовые сдвиги в Java?

    bingo347
    @bingo347
    Crazy on performance...
    Потому что 1 << 64 != 128 << 56, и вообще 1 << 64 в 64 бита не влазит
    Ответ написан
    2 комментария
  • Что сделать с большими аудиофайлами, чтобы их было удобно слушать на веб-странице?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Я бы пошел путем разбиения файла на куски, это кстати можно автоматизировать через ffmpeg.
    Так же лучше сохранять информацию о всех кусках и их продолжительности (например в json).

    Для непрерывного воспроизведения стоит создавать новый audio и вставлять его на страницу за некоторое время до окончания воспроизведения текущего куска. Отслеживать время можно через событие timeupdate.
    По завершению текущего куска (событие ended) запускать следующий, а элемент audio текущего удалять из страницы.

    Если нужен ползунок, эмулирующий полный файл, то можно сделать кастомный используя информацию из json. Хотя для личного пользования я лично не стал бы заморачиваться и просто вывел бы кнопки для переключения на нужный кусок, все так же на основе информации из json.
    Ответ написан
  • Почему не работает цикл?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Во-первых, у Вас ошибка синтаксиса
    https://developer.mozilla.org/ru/docs/Web/JavaScri...

    Во-вторых, а что Вы пытаетесь добиться, запуская setInterval в цикле, а в setInterval еще один setInterval?
    Ответ написан
  • Не понимаю последовательность выполнения цикла?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Для начала почитайте вот это:
    https://developer.mozilla.org/ru/docs/Web/JavaScri...

    Если после прочтения так сходу не понятно, то возьмите листочек с ручкой и распишите свой алгоритм по шагам.
    Ответ написан
    Комментировать
  • Почему JS меняет дату?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Дата не меняется, просто Вы оперируете датой в текущем часовом поясе (Московское время), а в консоль логируется в формате UTCString, а в UTC всегда используется время по Лондону.

    Ну и у строки нет метода setHours, нужно сначала создавать объект Date и уже на нем вызывать этот метод. Хотя для даты сделаной из такой строки этот вызов бессмысленный, так как устанавливаемые параметры и так будут 0
    Ответ написан
    2 комментария
  • Как упростить проверку числа на палиндром и увеличить скорость выполнения кода?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Задача проверки последовательности на палиндром решается за O(n/2). Но для этого нужно иметь последовательный доступ к обоим концам последовательности за O(1).
    Если такой возможности нет и имеется доступ только к одному из концов последовательности, то придется обойти всю последовательность, а это уже O(n). Один из таких, достаточно оптимальных алгоритмов для цифр целого числа уже представил WbICHA.

    Чтоб решить эту задачу за O(n/2) нужно понять, как получить крайние цифры числа за O(1).
    Крайнюю справа цифру можно получить простым остатком от деления на основание системы счисления, то есть, в случае десятичной системы счисления, на 10.
    Для получения крайней справа цифры нужно знать ее порядок (считая справа начиная с 0). Это можно сделать взяв целую часть от логарифма по основанию системы счисления (10). На JS такая операция будет выглядеть так:
    Math.trunc(Math.log10(num))
    Целая часть от деления числа на 10 в степени порядка правой цифры даст саму эту цифру. На JS это выражается так:
    Math.trunc(num / 10 ** Math.trunc(Math.log10(num)))

    Так же алгоритм требует равномерного перемещения по последовательности от краев к центру.
    Для правой цифры опять все просто, можно брать целую часть от деления числа на основание (10).
    Для левой нужно умножить ее на основание в степени порядка и вычесть результат из самого числа, то есть:
    num - leftDigit * 10 ** Math.trunc(Math.log10(num))


    Осталось учесть пограничные условия:
    1. Если крайний левый и крайний правый элемент не равны, то последовательность не является палиндромом
    2. Последовательность из одного элемента (число из одной цифры) всегда палиндром.
    3. При равенстве крайних элементов последовательность будет палиндромом если палиндромом так же является подпоследовательность без этих элементов.

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

    По итогу получим такую функцию:
    const isPalindrome = num => {
        let n = num;
        while (n >= 10) {
            const order = 10 ** Math.trunc(Math.log10(n));
            const leftDigit = Math.trunc(n / order);
            const rightDigit = n % 10;
            if (leftDigit !== rightDigit) return false;
            n -= leftDigit * order;
            n /= 10;
            n = Math.trunc(n);
        }
        return true;
    };


    P.S. варианты с приведением числа к строке, а тем более с последующим разбиением на массив чисел и разворотом его, просто отвратительны.
    Приведение числа к строке - это O(n) если не больше, так как в JS тип number - это по сути float64 и алгоритм приведения учитывает, что число может быть с дробной частью.
    Разбиение строки на массив символов (split) - O(n) и требует доп памяти под этот массив.
    Реверс массива - O(n/2)
    Склейка (join) - опять O(n)
    Сравнение строк - еще раз O(n)
    И хотя суммарная сложность останется O(n), количество проходов по цифрам числа будет в 5 раз больше, хотя даже на строках можно уложится в 1.5 обхода:
    const isPalindrome = num => {
        const s = String(num);
        for (let i = 0; i < s.length / 2; i++) {
            if (s[i] !== s[s.length - i - 1]) return false;
        }
        return true;
    };
    Ответ написан
    4 комментария