• Как фронтенд понимает, что мы авторизованы?

    bingo347
    @bingo347
    Crazy on performance...
    2. Сервер присылает нам ответ, если он позитивный, то возвращает set-cookie, где устанавливает в cookie бразуера сессионный ключ;
    Притом set-cookie он возвращает с флагами secure (доступно только по https) и http-only (недоступно из js). Это единственный доступный вариант хранить сессионный ключ, чтоб его не угнали.

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

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const arr = ['utmTerm=java', 'utmTerm=javascript', 'utmTerm=swift'];
    const res = arr.reduce((acc, item) => {
        const [key, value] = item.split('=', 2);
        (acc[key] ??= []).push(value);
        return acc;
    }, {});
    console.log(res);
    Ответ написан
    Комментировать
  • Несколько языков в портфолио и как сделать выбор в направлении?

    bingo347
    @bingo347
    Crazy on performance...
    1. Стоит ли продолжать изучение front-end, если данное направление реально нравится или ситуация действительно такая, что там уже не нужны новые люди?
    Новых людей особо нигде не жалуют. Но пробиться всегда есть варианты:
    1. Большие компании иногда могут нанимать стажеров по абсолютно любым направлениям и обучать их. Работа будет больше рутинная, но для старта можно и потерпеть.
    2. Есть маленькие компании, у которых туго с деньгами, но разрабатывать им надо, соответственно нанимают того кто по карману. Развития здесь скорее всего не будет, но для первой строчки в резюме пойдет, если с 1 вариантом не получилось.

    2. Если уровень подготовки будет выше, чем описанные требования к джуну, то нормально ли будет подавать отклик на вакансии мидла или это плохой тон и мидл это не просто уровень знаний, но и обязательно опыт работы?
    Попробовать конечно можно, за попытку никто Вам ничего плохого не сделает.
    Но вообще джун-мидл-синьер - это вообще не про уровень знаний в программировании, это больше про софт скилы, которые приобретаются только с опытом работы. Условно я бы так разделил:
    Джун - умеет писать код под достаточно конкретные задачи, умеет гуглить если что-то не знает, умеет спросить если не сумел загуглить.
    Мидл - как джун + умеет декомпозировать более абстрактную задачу, при необходимости задать по ней правильные вопросы, умеет работать в команде (обсудить проблему, поревьювить чужой код, позаботиться чтоб собственный код был удобен остальным).
    Синьер - как мидл + умеет решать проблемы бизнеса с помощью кода.

    1. Делать простой бек для своих проектов на nodejs, чтобы проекты были более интересными и показывали мои навыки в js. Будет ли базовое знание nodejs плюсом для front-end разработчика?
    Будет, большинство инструментария написано на node и конфигурируется js кодом. Ну и уметь накидать себе заглушку на express пока нормальное api в разработке тоже будет плюсом.

    2. Как вообще поступить, если на данном этапе мне хочется попробовать себя в бекенде и подстраховаться на случай того, если не получится найти работу во front-end? Создать второй гитхаб и там выкладывать что-то на других языках или пока нахожусь на стадии обучения и выбора, то просто делать все в одном профиле и потом скрыть?
    Не заморачиваться и делать все в одном github. Лучше заморочиться тем как этот github оформлен, например сделать readme для профиля. Нормально оформлять коммиты. Не плодить кучу форков разных чужих проектов. Если есть форк чужого проекта, обязательно должен быть пул реквест туда, ну или хотя бы собственные коммиты в форке.

    3. Если я выберу nodejs и буду добавлять его к своим проектам, то нормально ли тогда будет подавать отклик и к фронт и к бек вакансиям?
    Нормально. Как и нормально изредка менять направление, а значит и не знать что больше по душе пока не работал. Нормально будет, если полгода-год поработали с одной технологией, а потом несколько лет с другой, но плохо, если менее чем за 2 года смените 3+ стэка.
    Я например начинал с php, через год ушел в node.js, еще через пару лет добавил фронт не убирая node.js, еще через 4 года добавил Rust.
    Ответ написан
    1 комментарий
  • Что такое signature и implementation?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Сигнатура функции - это по сути ее тип, который состоит из списка аргументов с типами и типа возвращаемого значения.
    Имплементация функции - это функция с телом.
    То есть следующие строки - это сигнатуры:
    function position(): MyPosition
    function position(a:number, b:number): MyPosition
    function position(a:number): MyPositionWithDefault

    Это тоже сигнатура: function position(a?: number, b?:number), но она так же является частью имплементации:
    function position(a?: number, b?:number) {
        if (!a && !b) {
            return {x: undefined, b: undefined}
        }
        if(a && !b) {
            return {x: a, b: undefined, default: a.toString()}
        }
        return {x: a, y: b}
    }


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

    Еще один важный момент для данного примера - это вывод типов. Если где-то тип не указать, то TS попробует его вывести, но делает он это весьма топорно - из первого значения которое будет присвоено переменной, ну и из первого return если речь идет о выводе возвращаемого значения функции.
    В Вашем случае TS выведет возвращаемое значение имплементации из следующей строчки: return {x: undefined, b: undefined}
    Тип такого значения будет:
    interface ReturnTypeOfPosition {
      x: undefined
      b: undefined
    }
    Проблема тут в двух вещах, во-первых в поле b вместо поля y, во-вторых в отсутствии поля default.
    Если исправить так:
    function position(): MyPosition
    function position(a: number, b: number): MyPosition
    function position(a: number): MyPositionWithDefault
    function position(a?: number, b?: number): MyPosition | MyPositionWithDefault {
        if (!a && !b) {
            return {x: undefined, y: undefined}
        }
        if(a && !b) {
            return {x: a, y: undefined, default: a.toString()}
        }
        return {x: a, y: b}
    }
    то все будет ок

    Ну и еще важный момент про перегрузки, TS использует в месте вызова ту перегрузку, которая первой подошла по аргументам, пробуя их в том порядке, как они записаны у Вас в коде, сверху вниз. Соответственно остальные типы в месте вызова будут выводится из данного факта.

    P.S. у меня в профиле есть ссылка на доклад по системе типов TS, про перегрузки там тоже есть. Система типов в TS полностью построена на математике множеств, если понять эту математику, то поймете и TS.
    Ответ написан
    2 комментария
  • Как отобразить процесс работы в терминале?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    setTimeout(function f(percent) {
        if (!process.stdout.isTTY) return;
        if (percent > 100) {
            process.stdout.write('\n');
            return;
        }
        const FILL = 9608;
        const SHADE = 9617;
        const progressSize = process.stdout.columns / 2;
        const fillSize = Math.ceil(progressSize * percent / 100);
        const shadeSize = Math.floor(progressSize) - fillSize;
        const fillText = String.fromCharCode(FILL).repeat(fillSize);
        const shadeText = shadeSize > 0
            ? String.fromCharCode(SHADE).repeat(shadeSize)
            : '';
        process.stdout.clearLine();
        process.stdout.write(`\r${fillText}${shadeText} ${percent}%`);
        setTimeout(f, 250, percent + 1);
    }, 100, 0);

    https://nodejs.org/dist/latest-v18.x/docs/api/tty.html
    https://unicode-table.com/en/blocks/block-elements/
    Ответ написан
    Комментировать
  • Как webpack собирает импорты и экспорты?

    bingo347
    @bingo347
    Crazy on performance...
    Есть 2 основных подхода для решения проблемы изоляции имен в модулях:
    - подход webpack до 4 версии включительно - завернуть каждый исходный модуль в свою функцию и переложить эту задачу на средства языка js;
    - подход rollup и последователей типа vite - произвести переименование сущностей так, чтоб разные сущности из разных модулей названные одинаково назывались по разному, а одни и те же сущности названные по разному в разных модулей назывались одинаково.

    У каждого из подходов есть свои плюсы и минусы.
    В подходе webpack с одной стороны получается очень надежная изоляция, так как работают средства самого языка, но с другой на выходе получается больше кода, так как добавляются обертки + некий рантайм для взаимодействия виртуальных модулей. Так же такой код хуже оптимизируется на постобработке, так как тулзы вроде terser банально не могут восстановить связи между разными модулями. Хотя тот же рантайм позволяет гибко разбивать код на чанки и эмулировать динамические импорты.
    В подходе rollup возможны ошибки на промежуточной обработке (сам rollup предусматривает большинство из них, а вот плагины могут накосячить, особенно на больших проектах), зато нет дополнительного кода и тулзы вроде terser могут обрабатывать весь бандл целиком со всеми межмодульными связями, а значит делать более эффективные оптимизации.

    В webpack 5 был использован гибридный подход. Модули все так же изолируются средствами языка и соединяются посредством рантайма. Но часть модулей могут быть соединены в один по принципу rollup, что улучшает общий размер бандла и оптимизацию на постобработке.

    P.S. сделайте небольшой проект из примерно 10 модулей, соберите его webpack/rollup в dev режиме и посмотрите что получается на выходе, очень многое станет понятно, если просто почитать код получившегося бандла.
    Ответ написан
    1 комментарий
  • Как скопировать текст из iframe в переменную js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если в iframe загружена страница с того же origin (протокол + домен + порт) откуда загружена текущая - то Вы имеете полный доступ к его window через свойство contentWindow. Соответственно можете обращаться к его DOM, глобальным переменным, менять их и т.д.

    Если в iframe будет страница с другого origin, то ничего этого нет, с ней можно лишь общаться через postMessage api, но если страница не Ваша, то и скрипт для обработки postMessage + каких-либо еще действий Вы туда не вставите.

    Если сторонний сайт отдает нормальные CORS заголовки при запросе с Вашего сайта (что судя по вопросу не так, но все же), то можно скачать страницу как текст через fetch api и распарсить ее через DOMParser.

    В противном случае остается только делать прослойку у себя на сервере, тут простор фантазии может быть очень широким, от банального reverse proxy прямо в nginx до чего-то более умного на любом серверном ЯП.
    Ответ написан
    Комментировать
  • Какой тип данных у переменной a?

    bingo347
    @bingo347
    Crazy on performance...
    У переменной a указан тип встроенный массив [T; n]. Но у такого типа нет метода get_unchecked_mut(). Он есть у среза на массив [T]
    Тут нужно понять как в Rust работает оператор точка.

    Во-первых, мало кто пишет, но операторов точка на самом деле в Rust целых 2:
    - Доступ к полю структуры/кортежа/юниона
    - Вызов метода
    Rust различает их по наличию круглых скобок:
    struct S {
        a: i32,
        f: fn(),
    }
    
    impl S {
        fn a(&self) {}
    }
    
    let s = S { a: 0, f: || {} };
    s.a; // Доступ к полю
    s.a(); // Вызов метода
    (s.f)(); // Вызов функции по указателю, который лежит в поле f

    С доступом к полю все просто, компилятор преобразует его в смещение в памяти где это поле лежит относительно самой структуры.
    А вот с вызовом метода все интереснее, Rust пытается рассахарить его в одну из следующих конструкций в следующем порядке:
    S::a(s);
    S::a(&s);
    S::a(&mut s);
    <S as Deref>::Target::a(S::deref(&s));
    <S as DerefMut>::Target::a(S::deref_mut(&mut s));
    <<S as Deref>::Target as Deref>::Target::a(<S as Deref>::Target::deref(S::deref(&s)));
    <<S as DerefMut>::Target as DerefMut>::Target::a(<S as DerefMut>::Target::deref_mut(S::deref_mut(&mut s)));
    // ...
    и так пока либо не найдет вариант, который компилируется, либо пока не обнаружит что для очередного типа не реализован трейт Deref.
    Подробнее можно почитать тут: https://doc.rust-lang.org/stable/nomicon/dot-opera...

    У всех массивов есть Deref к слайсу, в core библиотеке прописано что-то вроде:
    impl<T, const N: usize> Deref for [T; N] {
        type Target = [T];
        fn deref(&self) -> &[T] {
            // ...
        }
    }
    За счет этого все массивы (а так же векторы, у которых тоже Deref к слайсу) получают методы слайса. И по тому же принципу String получает методы str.

    Ну и кстати, неявный вызов deref может еще происходить при взятии ссылки.

    Ну и из комментов к вопросу:
    Что тут делает unsafe код как раз понятно
    Однозначно понятно, он здесь делает UB так как обращается к памяти владелец которой неизвестен.
    Ответ написан
    1 комментарий
  • Как подружить VS Code + Remote SSH + WSL?

    bingo347
    @bingo347
    Crazy on performance...
    Ваша проблема в том, то Вы абсолютно не понимаете как работает WSL. Давайте немного объясню.

    Начиная с WSL2 подсистема Linux крутится в полноценной виртуальной машине. И винда кстати тоже. Это работает следующим образом: когда Вы запускаете свой компьютер первой загружается на самом деле не винда, а гипервизор HyperV. Для пользователя происходит все прозрачно, так как HyperV настроен сразу запускать 2 виртуальные машины - с виндой и с линем. В машину с виндой HyperV сразу прокидывает все Ваши устройства (видеокарту, USB и прочее). Так же HyperV поднимает виртуальную сеть между этими двумя виртуалками. В машине с линем еще не Ваша Ubuntu, там легковесная ОС состоящая только из ядра и оркестратора LXC контейнерами (с ней кстати можно по взаимодействовать по сети, как это делает Docker Desktop например, ну или утилита wsl.exe). Ваша Ubuntu запускается в контейнере, так попросту быстрее ее запускать и останавливать, ибо ядро всегда висит в памяти. Опционально в линь монтируются папки (диски) из винды, делается это посредством патча ядра Linux от Microsoft. Обратный доступ предоставляется из винды посредством сетевого ресурса wsl$.
    Главное что тут стоит понять - винда и линь в WSL по сути работают на разных компах, пусть и виртуальных.

    Теперь ответьте на вопрос, на каком из этих компов работает Ваш VSCode?
    Правильный ответ на винде. А значит и взаимодействовать он будет с виндой. И искать ключи для подключения к ssh будет в домашней папке юзера в винде.

    Можете просто скопировать ключи из линя на винду и все заработает.
    Ответ написан
    2 комментария
  • Как передать объект в класс js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Можно записать объект в свойство prototype временной функции и наследоваться от нее:
    function fromPrototype(proto) {
        function F() {}
        F.protoype = proto;
        return F;
    }
    
    const obj = {
        _sayHi() {
            console.log(`Hello, my name is ${this.name}!`);
        },
    };
    
    class Person extends fromPrototype(obj) {
        constructor(name, age) {
            this.name = name;
            this.age = age;
          
           if (this.age < 0 ) {
                this.age = 0;
            }
        }
    }
    Ответ написан
    2 комментария
  • Как подключить и использовать json конфиг в rust?

    bingo347
    @bingo347
    Crazy on performance...
    В константах как не странно можно использовать только константы.
    Варианта 2:
    1. Написать процедурный макрос, который прочитает нужный JSON в компайл-тайм и сгенерирует код константы, так кстати и саму структуру можно генерировать.
    2. Зашить байты JSON в бинарь через макрос include_bytes!, а парсить при старте программы или в lazy_static.

    Но вообще у меня есть ощущение, что Вы в принципе неправильно решаете свою задачу. Константы - это по своей сути компайл-тайм сущности, а смысл конфига обычно - получить параметры в ран-тайм.
    Скорее всего Вам достаточно будет простого lazy_static
    Ответ написан
    5 комментариев
  • Как удалить папку WSL?

    bingo347
    @bingo347
    Crazy on performance...
    Не отключая WSL - никак, потому что это не папка, а специальный шорткат проводника на виртуальную сеть WSL.
    Ну и да, начиная с win11 WSL включен по умолчанию, так как в планах запуск андроид приложений, а андроид как не странно - это Linux.
    Но по идее, если отключить WSL в системных компонентах, то и шорткат из проводника должен исчезнуть.
    Ответ написан
    Комментировать
  • Как сделать, чтобы событие вызывалось один раз?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Проблема вот тут:
    const remove = this.on(events

    Метод on у Вас ничего не возвращает, соответственно в remove будет undefined, функции там взяться неоткуда.
    Переменной events нет в скоупе данного метода, очевидно имелась в виду eventName

    А вообще, вместо массива колбэков для события лучше использовать Set, так метод off будет работать за O(1), а не за O(n) как сейчас.

    В методе once можно подписываться на событие через метод on, и отписываться через метод off при его наступлении (так например делает EventEmitter из node.js). Но стоит учесть момент, что off должен работать и для once событий, а у Вас будет записан колбэк созданный в once, а не тот, что передал пользователь. Вообще проще хранить 2 коллекции: для многоразовых для одноразовых событий, ну или параметризовать колбэки (тогда лучше хранить их в Map, где ключи - колбэки, а значения - их параметры).

    Ну и еще обратите внимание, что у Вас в методах emit и once колбэк пользователя вызывается по разному:
    callback.apply(this, args) и callback.call(null, args)
    Ответ написан
    1 комментарий
  • Как итерировать несколько объектов в одном цикле RUST?

    bingo347
    @bingo347
    Crazy on performance...
    let a = [1, 2];
    let b = [3, 4];
    for (a, b) in a.into_iter().zip(b.into_iter()) {
        println!("{a}, {b}");
    }

    Метод zip есть у любого объекта реализующего трэйт итератора
    https://doc.rust-lang.org/std/iter/trait.Iterator....
    Ответ написан
    Комментировать
  • Какой нужен фреймворк для js, под мою задачу?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ответ написан
    Комментировать
  • Как отменить несколько коммитов в форкнутом репозитории?

    bingo347
    @bingo347
    Crazy on performance...
    git checkout <хэш нужного коммита>
    git checkout -b <имя новой ветки>

    И продолжаем разработку в этой ветке.
    Или если просто собрать приложение, то можно и без новой ветки
    Ответ написан
    Комментировать
  • Какая есть идиома для проверки [null]?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Мне нужно из: [null] получить просто []

    Если таких null много в вперемешку с полезными значениями, то можно отфильтровать:arr = arr.filter(el => el !== null);
    Ответ написан
    Комментировать