• Где можно прокачать ES6-8?

    Можете глянуть freecodecamp, целый раздел посвящен es6.
    Так же можно просто писать знакомые задачи с возможностями es6+
    Ps вот кстати статья, мало ли: ES6 по-человечески
    Ответ написан
    8 комментариев
  • Где можно прокачать ES6-8?

    Stalker_RED
    @Stalker_RED
    Делай задачки на codewars и потом сравнивай свои решения с топовыми.

    Когда видишь что какой-то js-ниндзя сделал в три строчки, а у тебя почему-то получилось 20 - разбирай его код на кусочки и все непонятное пробивай по MDN.
    Ответ написан
    Комментировать
  • Что написать для тренировки на js с нуля?

    @vazonov
    Javascript developer
    Смотря сколько времени хотите потратить.
    Можно создать проект с нуля. Например, сервис для хранения собственных заметок. Определяете цели, которые будет выполнять приложение (создать заметку, удалить, редактировать, искать по категории). Можете и API написать (welcome to node.js), если хотите сохранять заметки на сервере. Не хотите писать API - можете использовать другие сервисы, которые дадут возможность делать "серверную" работу за Вас, Вам лишь надо с ними "общаться" с клиентской стороны (например, Google Firebase). Если не хотите и этого - можно сохранять заметки локально в браузере (localStorage, IndexedDB). Создавая проект Вы и столкнетесь с написанием и модалок, и кнопок, и пагинации, и очень много всего другого, что пригодится в реальной работе.
    Еще варианты:
    - Приложение для хранения просмотренных фильмов (и фильмов, которые хочется посмотреть. Впечатления, личная оценка)
    - PWA приложение, которое копирует функционал какого-то мобильного приложения (смотрите Google Play, AppStore)
    - API, которое будет выдавать сгенерированные (фейковые) данные (faker.js)
    - WhatApp / Viber / Telegram / Facebook bot для отправки актуальной погоды / курса валют, пр.

    Можете написать то, что пригодится Вам. Например, телеграм бот, который бы присылал Вам новинки фильмов, которые появились на торрентах. Это node.js.

    Можете написать игру на canvas. Можете не на canvas. Просто JS + CSS.
    Еще Варианты:
    - 2048
    - Лабиринт, где что-то куда-то двигается
    - Угадай число (скрипт "загадывает" число, ты вводишь свое - он тебе говорит, больше оно или меньше и пока не угадаешь)
    - Любая другая с использованием популярных js-движков для игр (https://github.com/collections/javascript-game-engines)


    Можете переписать какую-то JS-библиотеку (смотрите на Гитхабе).
    Можете написать свою библиотеку. Начните с малого: допустим, она будет генерировать случайные строки. Или имена, фамилии и эмайлы.
    Еще варианты:
    - Редактор текста
    - Проверка паролей на устойчивость
    - Валидация (паролей, имен, фамилий, телефонов, эмайлов) - привет, регулярные выражения
    - Генерация случайных пикселей на canvas
    - Библиотека-helper: пишете свои функции-велосипеды при работе с данными (спарсить json, склонировать объект, пр.)


    Вариантов очень много.
    Вы можете выбрать как стек технологий для написания чего-то, так и всего лишь идею для проекта, а на каких технологиях - разобраться потом, в зависимости от того, что нужно.
    Ответ написан
    Комментировать
  • Что написать для тренировки на js с нуля?

    shmatuan
    @shmatuan
    8 year of Web, 5 years of Vue
    Из того, что часто может пригодится в вебе

    • Паралакс
    • слайдер
    • генерацию таблиц из js
    • сортировку таблиц
    • общение с сервером
    • Плеер (аудио/видео)
    • Работа со временем (momentjs)
    • Подгрузка постов при скроле
    • Движение блоков при скроле
    • Пагинация
    • Модалка
    • Взаимодействие с изображениями (фильтр, обрезка, ...)
    • Кастомные селекты, датапикеры
    • Табы


    + можешь поискать топ сайтов и попробовать повторить интересные штуки из них
    + jQuery
    + фрейморки, например Vue
    + node js
    Ответ написан
    Комментировать
  • Книга или курс начальной и дискретной математики?

    sgjurano
    @sgjurano
    Разработчик
    Сначала убедитесь, что у вас всё в порядке со школьной математикой, лучше всего для этого подходят учебники Киселёва.

    Потом на базовом уровне осознайте математический анализ (например по книге "Как выжить после предельного перехода?" Пантаева), затем поднимите линейную алгебру (для этого достаточно учебника Куроша "Курс высшей алгебры"), останется лишь добавить немного теории вероятностей (первого тома Феллера для этого более чем достаточно).

    Если хочется именно дискретной математики, то можно курс "Дискретные структуры" Дайняка на степике порешать, если захочется ещё, то "Конкретную математику" Кнута :)
    Ответ написан
    2 комментария
  • Книга или курс начальной и дискретной математики?

    longclaps
    @longclaps
    Ответ написан
    Комментировать
  • Сервер и его настройка под API?

    Sanes
    @Sanes
    Потенциально длительные операции надо делать через очереди. Что произойдет при обрыве соединения с клиентом проверяли?
    Ответ от API должен быть мгновенным и не ставить клиент в ступор.
    Ответ написан
    Комментировать
  • Сервер и его настройка под API?

    saboteur_kiev
    @saboteur_kiev Куратор тега Веб-разработка
    software engineer
    А почему бы не воспользоваться ajax, и генерировать уникальный ID запроса, передавать его клиенту сразу, затем на стороне клиента крутить анимацию ожидания и периодически дергать сервер по поводу получения инфы готов результат или нет?
    Ответ написан
    4 комментария
  • Оценка своего уровня. Как улучшить код?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Используйте const вместо let для определения переменных которые не переопределяются в коде. Это помогает снизить когнитивную нагрузку с человека читающего код и негласный стандарт в React разработке.

    2. Такие вещи как globalStyles и конфигурацию store лучше вынести в отдельные файлы. Они могут со временем хорошо разрастись.
    По поводу globalStyles, вы вообще можете вынести их в отдельный css файл.

    3. Вместо:
    {
      isModal
      ? <Route path="/auth" component={AuthPopup} />
      : null
    }

    лучше:
    {isModal && <Route path="/auth" component={AuthPopup} />}


    4. Вместо:
    function mapDispatchToProps(dispatch) {
        return {
            autoLogin: () => dispatch(autoLogin()),
            getBrowser: () => dispatch(getBrowser()),
            getMedia: () => dispatch(getMedia())
        }
    }


    лучше:
    const mapDispatchToProps = {
      autoLogin,
      getBrowser,
      getMedia,
    };


    5. Точки с запятыми в конце то есть, то нет. Определитесь и приведите код к одному виду.

    6.
    & label {}
    & input {}
    & span {}

    Это не очень хороший подход. Во-первых ваши стили не изолированные, что может приводить к неожиданным результатам. Во-вторых у вас очень много дублирования стилей. Определите Input и Label как базовые компоненты и используйте в разных местах, то же с остальным если есть.

    7. Почему папка со страницами называется Containers? Дань бойлерплейтам?

    8. Использование trailing comma является хорошей практикой.

    9.
    import {combineReducers} from 'redux';
    import photoReducer from './photoReducer';
    import authReducer from './authReducer';
    import globalReducer from './globalReducer';
    
    export default combineReducers({
        photoReducer, authReducer, globalReducer
    })


    Все таки приятней работать с хранилищем в котором ключи не имеют в названии слова reducer:
    import {combineReducers} from 'redux';
    import photo from './photoReducer';
    import auth from './authReducer';
    import global from './globalReducer';
    
    export default combineReducers({
      photo, 
      auth,
      global,
    });


    10. Забудьте вообще, что в языке есть возможность использовать вложенный тернарный оператор:
    return e === 'invalid-email' ? 'Неверно указан e-mail'
        : e === 'user-not-found' ? 'Указанный e-mail на найден'
        : e === 'wrong-password' ? 'Неверный пароль'
        : e === 'email-already-in-use' ? 'Указанный e-mail уже используется'
        : e === 'network-request-failed' ? 'Нет подключения к интернету'
        : e === 'operation-not-allowed' ? 'Произошла ошибка, попробуйте снова'
        : e === 'popup-closed-by-user' ? 'Окно авторизации закрыто пользователем'
        : e === 'account-exists-with-different-credential' ? 'Аккаунт уже существует с другими данными, используйте другой способ авторизации'
        : e

    Это одна из самых худших практик в JavaScript разработке. Тут лучше подойдет конструкция switch case

    11. Константы actionTypes лучше вынести в папку constants и разложить по разным файлам, иначе со временем у вас там будет свалка.

    12. Вместо:
    import {SET_ACTIVE, CHANGE_VALUE, SET_DEFAULT, UPLOAD, UPDATE_IMAGE, SET_IMAGE_ERROR, SET_LIKE, SET_COMMENT, ADD_ARTICLE_SUCCESS, FETCH_ARTICLES_START, FETCH_ARTICLES_SUCCESS, FETCH_ARTICLES_ERROR} from '../actions/actionTypes';

    Лучше:
    import {
      SET_ACTIVE,
      CHANGE_VALUE,
      SET_DEFAULT, UPLOAD,  
      UPDATE_IMAGE,
      SET_IMAGE_ERROR,
      SET_LIKE,
      SET_COMMENT,
      ADD_ARTICLE_SUCCESS,
      FETCH_ARTICLES_START,
      FETCH_ARTICLES_SUCCESS,
      FETCH_ARTICLES_ERROR,
    } from '../actions/actionTypes';


    13. Попробуйте внедрить библиотеку reselect. И для получения значения из store вместо записи вида:
    function mapStateToProps(state) {
        return {
            browser: state.globalReducer.browser
        }
    }


    использовать селектор:
    const mapStateToProps = state => ({
      browser: browserSelector(state),
    });
    Ответ написан
    12 комментариев
  • Чем опытнее разработчик, тем меньше соблюдается принцип KISS?

    Adamos
    @Adamos
    Чем опытнее разработчик, тем чаще, выполняя конкретную задачу, он понимает, что примерно такую уже решал. Поэтому опытный разработчик видит уровни абстракции, общие для многих решений. И описывает их так, чтобы потом, при решении очередной конкретной задачи, использовать написанное ранее с минимумом дополнительных усилий.
    Вы, не имея такого опыта, просто не понимаете, что все эти лееры, провайдеры и трейты - прекрасная возможность написать две строчки и быть уверенным в их работе там, где вы угробите два дня на написание "простого" решения, а потом еще неделю будете отлавливать его глюки.
    Ответ написан
    6 комментариев
  • Чем опытнее разработчик, тем меньше соблюдается принцип KISS?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Принцип KISS не означает что надо использовать самые примитивные инструменты.
    Он означает, что не надо переусложнять систему без нужды.
    Если так рассуждать, так и высшее образование не нужно: "Дед отличные бани строил, хотя вовсе был неграмотный. Я и без сопромата небоскреб построю!"
    Если вы пока ещё не понимаете назначение всех этих "лееров, провайдеров и репозиториев", это не значит, что они вообще никому не нужны.

    Для того, чтобы упростить управление системой, её надо усложнить.
    Этот принцип относится к любой области человеческой деятельности, от постройки ракет до управления государствами.
    Чем сложнее система, тем больше накладные расходы на ее управление. Хоумпейдж с котиками можно и нужно делать примитивными средствами. В большом проекте надо сразу закладываться на будущую расширяемость. То есть, заранее делить ответственность между "леерами".

    И кстати. Код, в котором "всё друг на друге завязано" - это очень плохой код. Собственно, предназначение всех этих "лееров, провайдеров и репозиториев" как раз в том, чтобы компоненты были как можно более независимы друг от друга.
    Ответ написан
    1 комментарий
  • Как правильно наследовать?

    SwoDs
    @SwoDs
    PHP YII2
    Методы не наследуются, все методы родителя доступны классу который его наследует.

    В вашем случае я бы просто расширил функционал класса Book, так как работа связана с ним.

    Если у вас был бы класс "Печатная продукция", то большая часть методов была там, а классы Book, Newspaper и т.д.
    наследовались от него. В этих класса была бы реализация только того что относится к ним, к примеру у книги есть автор, а у газеты нет... как то так
    Ответ написан
    Комментировать
  • Как организовать роли в Symfony?

    BoShurik
    @BoShurik Куратор тега Symfony
    Symfony developer
    security.yml
    security:
        access_control:
            - { path: ^/ }

    RequestVoter.php
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
    use Symfony\Component\Security\Core\Security;
    
    class RequestVoter implements VoterInterface
    {
        /**
         * @var Security
         */
        private $security;
    
        public function __construct(Security $security)
        {
            $this->security = $security;
        }
    
        /**
         * @inheritDoc
         */
        public function vote(TokenInterface $token, $subject, array $attributes)
        {
            if (!$subject instanceof Request) {
                return self::ACCESS_ABSTAIN;
            }
    
            $route = $subject->attributes->get('_route');
            $routeRole = $this->getRoleByRoute($route);
    
            if ($this->security->isGranted($routeRole)) {
                return self::ACCESS_GRANTED;
            }
    
            return self::ACCESS_DENIED;
        }
    
        protected function getRoleByRoute(string $route): string
        {
            // ...
        }
    }
    Ответ написан
    3 комментария
  • Как работает подход Unit of Work?

    @Flying
    Unit of Work - это паттерн определяющий логическую транзакцию т.е. атомарную синхронизацию изменений в объектах, помещённых в объект UoW с хранилищем (базой данных).

    Если обратиться к исходному описанию этого паттерна у Мартина Фаулера - то видно что объект, реализующий этот паттерн отвечает за накопление информации о том какие объекты входят в транзакцию и каковы их изменния относительно исходных значений в хранилище. Основная работа производится в методе commit() который отвечает за вычисление изменений в сохранённых в UoW объектах и синхронизацию этих изменений с хранилищем (базой данных).

    Паттерн Unit of Work как правило не является полностью самостоятельным, он обычно тесно связан с паттерном Identity Map, задача которого - сохранение карты созданных объектов, взятых из хранилища с тем чтобы гарантировать что одна единица информации из хранилища представлена ровно одним экземпляром объекта данных в приложении. Это позволяет избежать конфликтов изменений т.к. не допускает ситуации когда два объекта, представляющих один и тот же элемент данных в хранилище, изменены по-разному. Информация из Identity Map используется в методе commit() паттерна Unit of Work для вычисления разницы между исходными данными и накопленными изменениями.

    Поскольку для вычисления разницы (и, соответственно, определения того что и каким образом должно быть изменено в хранилище) необходимо знать какие данные и как именно хранятся в объектах - как правило необходима также реализация паттерна Metadata Mapping, описывающего связь между содержимым хранилища (к примеру таблицами и столбцами базы данных) и классами / свойствами объектов.

    Также, если данные в хранилище не являются независимыми (к примеру связи между таблицами в базе данных) - может потребоваться реализации ряда паттернов, отвечающих за сохранение информации о связях между данными (это паттерны раздела Object-Relational Structural Patterns в каталоге паттернов).

    Подводя итог: сам по себе Unit of Work довольно прост в своём внешнем интерфейсе, но реализация его корректной работы требует предоставления множества дополнительных данных, поэтому миниатюрных примеров привести не могу.

    Если говорить о PHP - то лучшей реализацией этих паттернов на PHP безусловно является Doctrine ORM. В частности в разделе Working with Objects документации Doctrine можно найти хорошее описание и множество примеров использования паттернов, описанных выше.
    Ответ написан
    6 комментариев
  • Литература по стеку Docker - Kubernetes - Prometheus?

    Evgenym
    @Evgenym
    По Docker мне понравилась книга Russ McKendrick, Scott Gallagher "Mastering Docker" от издательства Packt
    Параллельно смотрел курс на Udemy https://www.udemy.com/docker-mastery/ Когда-то урвал бесплатно по купону.
    Ответ написан
    Комментировать
  • Как ускорить выкатывание изменений в большом проекте (монолит)?

    @InOdinWeTrust
    Возможно, вы доросли до большого проекта. Значит, без аналитики не разобраться.
    Нужно четкое представление сколько времени тратится на каждый шаг вашего процесса релиза.
    Если нет однозначных метрик - покрывайте. Нужно не на глаз сколько минут, а четко статистика по каждой задаче - сколько времени собиралась, тестировалась, сколько релиз, сколько проверка бизнесом, и тд и тп. Метрик мало не бывает.
    Затем по собранным данным рисовать графики, диаграммы, анализировать, на что тратится больше всего времени.
    Затем думать, где можно оптимизировать.
    Анализировать и оптимизировать не имея на руках цифр и картинок с диаграммами - это путь вникуда. Можете угадать с оптимизацией, можете не угадать.

    Когда все данные на руках есть, можете оптимизировать.

    Чаще всего помогает:
    - Исключить из процессов или минимизировать участие людей (CI, CD, автотесты и тд)
    - Распараллелить множественные однообразные процессы (мержи, запуски тестов на задачах, запуски тестов на билде, и тд)
    - Группировать (тестировать билд один раз после того, как в него попали все нужные бизнессу задачи)
    Ответ написан
    1 комментарий
  • Как ускорить выкатывание изменений в большом проекте (монолит)?

    @ponaehal
    Процедуры сборки, развертывания, тестирования автоматизировали?
    В моем понимании, если Вы утром следующего дня прийдете на работу и увидите развернутую на тестовом сервере версию с отчетом о прохождении тестов, то время с dev до prod сокращается до 2 дней (утром стабилизируете и после обеда получаете стабильный релиз).
    Проверено на практике. Собирали мы не раз в две недели а каждую ночь. Базовые проверки проходили ночью, а функционал аналитики проверяли только при подготовке обновления у заказчика.

    Важно: на prod накатывать не результирующую сборку, а все сборки ровно в том последовательности в которой накатывали на stage (сначала нестабильный релиз, потом фиксы до стабильного). Это нужно что бы исключить ошибки при повторной сборке.
    Ответ написан
    Комментировать
  • Прокомментируете тестовое на react?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Хотелось бы видеть в проекте использование redux. react+redux - это самый распространенный и востребованный стек в React разработке.

    2. Почему все хандлеры и состояния находятся в App, а не в Main? Как вы потом эту кашу собираетесь масштабировать? Переносите все, что связанно только с Main в Main. По-хорошему смотрите пункт 1.

    3. Слишком много функциональных компонентов. Подумайте их где можно заменить на классы с реализованным shouldComponentUpdate или на PureComponent, чтобы убрать лишние вызовы render этих компонентов.

    4. import Logo from 'images/Logo.png';
    называть пути к ресурсам с заглавной буквы неправильно.

    5. Вместо:
    const StyledLogo = styled.img.attrs({
      src: Logo,
      alt: 'Aviasales'
    })`
      width: 60px;
      height: 61px;
    `;

    Удобней в использовании:
    const StyledLogo = styled.img`
      width: 60px;
      height: 61px;
    `;

    и:
    <StyledLogo src={logo} alt="Aviasales" />

    6.
    const Error = ({ text }) => (
      <StyledError dangerouslySetInnerHTML={{__html: text}} />
    );

    зачем тут html?
    Для сохранения переносов строки есть css правило:
    white-space: pre-line;

    7. Вместо:
    let element;
    
    if (error && !isLoading) {
      element = <Error text={error} />;
    }
    if (!error && isLoading) {
      element = <Loader />;
    }
    if (!error && !isLoading) {
      element = (
        <>
        <Heading />
        <Main
        isCurrencyExchanging={isCurrencyExchanging}
        activeCurrency={activeCurrency}
        handleCurrencyChange={this.handleCurrencyChange}
        ticketsFilteredByStops={ticketsFilteredByStops}
        stops={stops}
        handleStopsChange={this.handleStopsChange}
        handleUncheckOther={this.handleUncheckOther}
        />
        </>
      );
    }
    return element;

    Лучше:
    if (isLoading) return <Loader />;
    
    if (error) return <Error text={error} />;
    
    return (
      <>
        <Heading />
        <Main
          isCurrencyExchanging={isCurrencyExchanging}
          activeCurrency={activeCurrency}
          handleCurrencyChange={this.handleCurrencyChange}
          ticketsFilteredByStops={ticketsFilteredByStops}
          stops={stops}
          handleStopsChange={this.handleStopsChange}
          handleUncheckOther={this.handleUncheckOther}
        />
      </>
    );


    8. Вместо:
    filterTickets = (tickets, stops) => {
      return tickets.filter((ticket) => {
        return values(stops).indexOf(ticket.stops) !== -1;
      });
    };

    Лучше:
    filterTickets = (tickets, stops) => tickets.filter(
      ticket => values(stops).includes(ticket.stops),
    );


    9. Не пропускайте отступы между методами и между вложенными свойствами css.

    10. Вместо:
    componentsDidMount() {
      // много кода
    }


    Лучше:
    componentsDidMount() {
      this.fetchSomeData();
    }


    11. Директории и индексные файлы для каждого компонента, имхо, лишнее. Лучше компоненты определять в одноименном файле и только когда возникнет необходимость в его декомпозиции, заменять на директорию и index.

    12. Loader и Error самое место в директории components/core или что-то вроде того. Там же, по-хорошему, должны находиться базовые компоненты: кнопки, инпуты, табы, чекбоксы.

    13. Styled компоненты, имхо, лучше писать в файле с компонентом, где они применяются. Так анализ кода происходит гораздо быстрей и легче поддерживать. Исключение - переиспользуемые компоненты.
    Даже если вам больше нравится выносить, называть файл style неправильно, вы там описываете компоненты, а не просто стили.
    Ответ написан
    3 комментария
  • Откуда разработчики знают как именно что то реализовать?

    Ваша проблема в том, что вы слишком сильно задаетесь сложными вопросами. Примерно как пытаться понять, почему машина двигается "влоб".

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

    Когда вам нужно сверстать страницу, вы что-то там себе пишете. Вот все, страница готова. Далее вам говорят. А сделайте регистрацию. Первое что вы делаете - лезете в гугл с запросом "как написать регистрацию на php". Вы видите кучу каши о каких-то запросах, базах, каких-то защитах, шифрованиях и тд. Все вместе прямо сейчас вам не понятно. Но разобравшись поэтапно в каждом из них вы уже можете написать простую регистрацию. Потом ваш сайт поломали к чертям, потому что при написании регистрации вы вообще не думали о безопасности. Вам дали по шапке и вот теперь новый опыт, в след раз все вещи вы будете стараться защитить.

    Уже имея опыт работы с базой (так как вы писали модуль регистрации), вы, формально, можете поковыряться и сделать возможность добавлять в базу новости на сайт, а потом их выводить на этом же сайте. И внезапно, вы уже понимаете как реализовать кривой-косой блог.

    В ходе решения любой задачи возникает масса проблем, которые вы вынуждены будете решать. Это и есть опыт. И чем больше таких задач вы решаете, тем проще вам будет решать все последующие проблемы.

    P.S. Как говорилось людьми выше, есть такой инструмент как "поиск гугл", на худой конец "товаращи по цеху" помогут.
    Ответ написан
    Комментировать