• Как получить родительскую категорию у подкатегории?

    @Akela_wolf
    Extreme Programmer
    Если у вас неограниченная вложенность, то только через рекурсивный запрос. MySQL 8 научился их делать. Это позволит вам рекурсивно собрать в одном из полей запроса данные из зависимых таблиц. Вот документация

    Вот пример:
    CREATE TABLE cat(
      id INT NOT NULL PRIMARY KEY,
      title VARCHAR(100) NOT NULL,
      parent_id INT NULL
    );
    
    INSERT INTO cat VALUE (1, 'Root1', NULL), (2, 'Root2', NULL), (3, 'Child1', 1),
    (4, 'Child2', 3), (5, 'Child3', 2);
    
    WITH RECURSIVE rcat(id, title, path) AS (
      SELECT cat.id, cat.title, CAST(cat.id AS CHAR(200)) FROM cat WHERE parent_id IS NULL
      UNION ALL
      SELECT cat.id, cat.title, CONCAT(rcat.path, ',', cat.id) FROM cat JOIN rcat ON cat.parent_id=rcat.id
    )
    SELECT * FROM rcat WHERE id=4;


    Пример
    Ответ написан
    7 комментариев
  • Как записать json который содержать массив объектов в pojo?

    @Akela_wolf
    Extreme Programmer
    Скажите, а вас разный регистр буковок в запросе и в ответе (хотя там одни и те же DTO) ни на какие мысли не наталкивает?

    А меня вот наталкивает, что Jackson сериализует и десериализует поля с именами из маленьких буковок. Либо сконфигурируйте Jackson чтобы он понимал большие - либо шлите запрос с маленькими буковками.
    Ответ написан
    Комментировать
  • Зачем делать проверку подключения модуля, если я итак его хочу подключить?

    @Akela_wolf
    Extreme Programmer
    Открываем документацию и видим:
    Возвращает "true", если модуль установлен, иначе - "false".

    Иначе говоря, вызов этой функции не гарантирует что модуль будет успешно подключен. И вот именно для того чтобы убедиться что он подключился и добавляют проверку.

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

    @Akela_wolf
    Extreme Programmer
    В случае обычной формы браузер не передает информацию о порядке выбора чекбоксов.
    Чтобы сделать так как вы хотите нужно городить на фронте Javascript, который будет отслеживать порядок "щелканья" по чекбоксам и каким-то образом передавать эту информацию серверу. Предположу, что в вашем случае это означает значительную переделку системы.

    Стоит ли данная "свистелка" таких усилий - решать вам.
    Ответ написан
  • Как правильно написать путь до DIV?

    @Akela_wolf
    Extreme Programmer
    Если метод find умеет в CSS selectors то:
    shopProducts = shop.find('#ProductBrowser-1 .div-который-мне-нужен');


    Это явно какая-то библиотека, так как DOM API не имеет метода find. Так что читайте документацию на библиотеку. Если это jQuery - то должно работать, у нее find умеет в селекторы.
    Ответ написан
  • JOIN всегда делает декартово произведение?

    @Akela_wolf
    Extreme Programmer
    Если вас интересует это в плане получаемого результата - то да, можно рассматривать это так: декартово произведение + фильтр строк по условию (и добавление NULL-ов в случае LEFT JOIN).

    Если интересует как это устроено внутри СУБД - то там далеко не всегда будет декартово произведение, потому что это довольно затратная операция. Какие конкретно операции будет выполнять СУБД можно увидеть по EXPLAIN-у - это называется план запроса. Там может быть и NESTED LOOP (вложенный цикл) и MERGE JOIN и другие операции, которые планировщик запроса сочтет подходящими для данного конкретного сочетания таблиц в данном конкретном запросе (на это влияет структура запроса, наличие индексов, собранная по таблицам статистика и пр. факторы, углубляться в которые я сейчас не буду).
    Ответ написан
    Комментировать
  • Есть ли сейчас смысл использования redux-saga, если есть async/await?

    @Akela_wolf
    Extreme Programmer
    Redux-saga является middleware для redux, обеспечивающим асинхронную обработку.
    Если хотите написать аналогичные middleware самостоятельно (учитывая что сам по себе Redux не умеет в асинхронный код и в любом случае какое-то middleware вам потребуется) - никто вам этого запретить не может.

    Вообще правильная архитектура здесь выглядит примерно так, как сделали в MVICore (фреймворк для Котлина):
    (Action + State) -> actor -> (Effect(s) + State) -> reducer -> State
    Первая часть (actor) работает асинхронно и порождает эффекты (может ни одного, может несколько). Вторая часть (reducer) работает синхронно и порождает изменения состояния. Redux обеспечивает только работу reducer, предлагая первую часть реализовывать какими-то middleware, самописными или библиотечными. Так что, наличие в языке async/await эту проблему Redux не решает.
    Ответ написан
  • Как правильно логировать базу данных?

    @Akela_wolf
    Extreme Programmer
    Логировать в БД (в отдельную таблицу) спринг вполне может. Но это, обычно, не очень хорошее решение. В промышленном использовании все-таки лучше логировать в файл, затем logstash -> elastic -> grafana/kibana или аналогичный стек. Можно graylog - решений в общем-то много и смысла нагружать именно реляционную БД логами обычно мало.
    Ответ написан
    1 комментарий
  • Как спроектировать базу для приложения заметочника?

    @Akela_wolf
    Extreme Programmer
    Если вся таблица из БД прилетает в браузер, а затем браузер с этим миллионом разбирается - это неправильно.
    Браузер шлет запрос, типа "дай мне заметки с такими-то тегами, 50 штук", "дай мне заметки за февраль, 3 страница, 50 штук" и т.п. А сервер разбирается и строит запрос в БД. При нормальном АПИ вы сможете менять структуру данных в БД без необходимости переделывать клиент.

    Сейчас, возможно и нет смысла разносить все данные по разным таблицам: категории, теги и пр. На масштабах до миллиона строк нормальная СУБД перелопатит одну таблицу со вполне приличной скоростью, в режиме "приложение для себя" вы вряд ли заметите тормоза. Разнесение данных по отдельным таблицам дает:
    а) упрощение управления всем этим (например получить список категорий или список тегов, переименовать тег и т.п.)
    б) опыт подобной нормализации БД.

    Но в целом, для того чтобы пользоваться подобным приложением в личных целях это необязательно.
    Ответ написан
    Комментировать
  • Проблема с объединением нескольких таблиц MySQL?

    @Akela_wolf
    Extreme Programmer
    Во-первых, стрелки на диаграмме принято рисовать в другую сторону - это таблица связи ссылается на таблицу продуктов и на таблицу фотографий.
    Во-вторых, то чего вы хотите, сделать можно но это неправильный путь. Правильных путей тут два:
    1. Построить запрос, который выбирает продукты по определенному условию и присоединяет к ним картинки. В этом случае у вас будет несколько записей на один продукт, отличающихся только картинками (это, я так понимаю, вы сумели сделать). Обрабатывать это не очень удобно, но зато один запрос в БД.
    2. Выбрать сначала продукты, а затем к продуктам выбрать фотографии. Потребуется сопоставить фотографии с продуктами (по ID) на уровне приложения. Зато два запроса в БД и каждый возвращает свой набор требуемых данных.


    Третий правильный путь - использовать ORM, которая возьмет на себя извлечение данных из БД.

    Неправильный (на мой взгляд) путь - использовать агрегирующие функции, как-то так:
    SELECT p.*, JSON_ARRAYAGG(f.filename) AS files FROM product p
    LEFT JOIN product2file p2f ON p2f.product_id=p.id
    LEFT JOIN file f ON p2f.file_id=f.id
    GROUP BY p.id;

    Пример

    Но я считаю этот путь неправильным, потому что: с ростом сложности БД сложность подобных запросов быстро растет и тут начинают вылазить ошибки. А еще потому что вытащить из подчиненной таблицы 2 колонки можно, но порядок элементов в функции JSON_ARRAYAGG не определен, поэтому начинается возня с тем чтобы все это сопоставить. GROUP_CONCAT тоже имеет проблемы (в первую очередь ограничение длины).

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

    @Akela_wolf
    Extreme Programmer
    Дальше учиться на практике. Берете проект, который хотите сделать, например игру. Начните с чего-нибудь простого, тот же классический арканоид или тетрис. Сразу же возникнет уйма вопросов: а как это? А как тут? А как тогда здесь? И через решение этих проблем будете поднимать свой скилл. Для подобных игр не нужно каких-то сложных библиотек (единственная библиотека, которая необходима - это та, которая позволяет рисовать на экране линии, квадратики и кружки). А потенциал для развития - на полгода минимум. Добавление уровней, режимов, бонусов, таблицы рекордов и т.д. Затем, например, изучение на примере этой игры более серьезной графической библиотеки (тот же OpenGL): псевдотрехмерность, текстурирование, освещение и т.д. В конечном итоге может получиться вполне симпатично выглядящая игра и большое количество опыта в разработке реального проекта.

    Разумеется, вместо игры можно взять любой другой проект, который вам интересен. Хоть программу для расчета рейтинга шахматистов по итогам турнира (это другая тема, тут придется изучать другие вещи) и совершенствовать эту тему, пока чувствуешь что есть еще что-то что можно сделать, но не знаешь как именно. Вот это постижение "как именно" и называется совершенствованием навыков.
    Ответ написан
    Комментировать
  • Как взломать линейный конгруэнтный генератор случайных чисел от 0 до 36?

    @Akela_wolf
    Extreme Programmer
    Что вы подразумеваете под "вскрыть"? Научиться предсказывать следующее значение? ГПСЧ - в принципе детерминированная функция, предыдущее значение однозначно определяет следующее (рекуррентная функция).

    Если же речь идет об определении коэффициентов a и c, то это делается элементарно: делаете seed=0, следующее значение генератора равно c. Делаете seed = 1 - следующее значение генератора равно (a+c) % m, откуда, при известном m и c вычисляется a.
    Ответ написан
  • Как спроектировать календарь занятий?

    @Akela_wolf
    Extreme Programmer
    Таблица под типы занятий (если она тебе нужна): тренировка, встреча, визит к врачу и т.д.
    Таблица под конкретные занятия - содержит ссылку на тип занятия и конкретную дату и время
    Таблица под расписание повторяющихся занятий - содержит ссылку на тип занятия и расписание (каждый понедельник, каждую третью среду и т.д.)

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

    @Akela_wolf
    Extreme Programmer
    Пробуйте. Вообще запрета брать на работу программистов со средним образованием в законодательстве нет. Так что все на усмотрение конкретного работодателя. Некоторые, разумеется, отсеют вашу кандидатуру на основе формального признака - отсутствие высшего образования. Но кто-то будет смотреть на опыт работы (а он у вас есть). Плюс техническое собеседование. Не скажу что будет легко, но шансы вполне есть. Возможно придется разослать не один десяток резюме, вполне вероятно будут отказы. Но такого что "вообще не возьмут, в принципе не возьмут" я утверждать не стану.
    Ответ написан
    Комментировать
  • Что происходит с током в момент замыкания цепи?

    @Akela_wolf
    Extreme Programmer
    как будто бы часть которая после резисторов должна двигаться быстрее т.к у неё на пути нет препятствий, а часть которая идет через резисторы - идет медленнее. Это верно?

    Нет. Скорость движения электронов (количество заряда проходящее через сечение провода в единицу времени) постоянна. Если быть точным - после замыкания цепи очень быстро становится постоянной, переходным процессом, как правило, можно пренебречь.

    Препятствие на пути электронов (резистор) выражается в том, что на соответствующем участке цепи действует большая разность потенциалов (напряжение). U1, U2, U3 пропорциональны номиналам резисторов (по закону Ома).
    Ответ написан
    3 комментария
  • Можно ли нагружать ноутбук?

    @Akela_wolf
    Extreme Programmer
    Опасаться не надо. Несколько часов - это вообще ни о чем. Если не перегревается - то срок службы сокращается незначительно. Вентилятор на максимальную скорость - чем холоднее железо тем ему лучше, особенно при продолжительной нагрузке. Регулярно чистить от пыли (с какой периодичностью - зависит от количества пыли в месте эксплуатации)
    Ответ написан
    Комментировать
  • Как в результатах запроса колонку превратить в строку?

    @Akela_wolf
    Extreme Programmer
    Если известно количество устройств (и соответственно количество колонок в итоговой таблице) - можно. Пример для 4 устройств:
    CREATE TABLE data(
      device INT NOT NULL,
      date DATETIME NOT NULL,
      metric NUMERIC(10,2) NOT NULL
    );
    
    INSERT INTO data VALUES (1, '2022-01-01 00:00:00', 2.34),
    (2, '2022-01-01 00:00:00', 1.23),
    (3, '2022-01-01 00:00:00', 3.82), 
    (4, '2022-01-01 00:00:00', 0.45),
    (1, '2022-01-01 01:00:00', 2.00),
    (2, '2022-01-01 01:00:00', 1.82),
    (3, '2022-01-01 01:00:00', 3.09);
    
    SELECT date, SUM(d1), SUM(d2), SUM(d3), SUM(d4) FROM (
    SELECT date,
    CASE WHEN device=1 THEN metric ELSE NULL END AS d1,
    CASE WHEN device=2 THEN metric ELSE NULL END AS d2,
    CASE WHEN device=3 THEN metric ELSE NULL END AS d3,
    CASE WHEN device=4 THEN metric ELSE NULL END AS d4
    FROM data
    ) nested
    GROUP BY date;


    https://sqlize.online/sql/mysql80/68e677a2fc577e6c...
    Ответ написан
    2 комментария
  • Как получить значение определенного ключа многомерного массива?

    @Akela_wolf
    Extreme Programmer
    $func = function(array $arr): string {
      return $arr['driver_profile']['id']
    }
    
    $temp = array_map($func, $input['driver_profiles'])
    Ответ написан
    6 комментариев
  • Какой оптимальный алгоритм для однозначного определения слагаемых в сумме?

    @Akela_wolf
    Extreme Programmer
    Самое простое - шифруйте последние 2 цифры номера заказа как копейки в сумме платежа. Или 3 цифры - как последняя цифра рублевой суммы + копейки. Уникальности не будет, но сократить количество кандидатов в 100-1000 раз может оказаться вполне достаточно для вашей задачи.

    Но это такое себе решение. Вообще у наложенного платежа (а бланк наложенного платежа, по идее, готовите вы как отправляющая сторона) есть поле "назначение". И почта обязана вам его отдавать вместе с платежом. Что мешает вписать в назначение номер заказа в вашей системе? "Оплата заказа #XXX-YYY-ZZZZ" или как-то так.
    Ответ написан
    Комментировать
  • С чего начать изучение программирования школьнику?

    @Akela_wolf
    Extreme Programmer
    Насчет линукса. Да, на мой взгляд однозначно стоит. Опыт работы в линуксе даст тебе более глубокое понимание как функционирует операционная система, возможность заглянуть "под капот", увидеть на практике такую вещь как разные реализации одного и того же (например разные оконные менеджеры - суть у них одна, но каждый реализует это задачу разными путями). Поэтому советую что-нибудь "конфигурябельное", типа ArchLinux (Gentoo - это уже совсем-совсем хардкор, новичку с ней будет тяжко). Что касается повседневных задач - да нет там никаких непреодолимых трудностей, если не брать какую-то прям специфику. Браузер - есть. Просмотр видео, прослушивание музыки - есть. Работа с документами - есть. Работа с графикой и 3D-моделированием - есть. Игры - тоже есть, хоть иногда и с приколами (но сказано что игры не интересуют, поэтому не так важно).

    Насчет языка. Вообще язык программирования выбирают под задачу. Если хочется заниматься, например, системным программированием (драйверы, файловые системы, загрузчики, ядро ОС, виртуальные машины/гипервизоры, СУБД и пр.) - то это C/C++. Если хочется заниматься нейросетками - там хорош Питон. Фронтендом - без Javascript/Typescript сейчас никуда. Но если говорить об языке программирования общего назначения (на котором можно написать множество прикладных программ), то я рекомендовал бы следующие критерии:
    • Статически типизированный. Особенно важно, на мой взгляд, в начале обучения, так как закладывает базу - навык писать код строго. Динамически типизированные языки, такие как PHP, Python, Javascript и пр. позволяют программисту писать код "как попало", что чревато трудноуловимыми ошибками, формируют "плохие привычки", которые потом будут мешать.
    • Поощряющий декларативный (функциональный) стиль программирования. Функциональный стиль программирования сейчас набирает популярность, так как позволяет писать более сложные программы и проще тестировать их по отдельным частям.
    • Кроссплатформенность. То есть возможность создавать программы для Windows, Linux, MacOS, Android и т.д. Это не столько про язык сам по себе, сколько про его окружение - наличие кроссплатформенных библиотек и инструментов для разработки.
    • Востребованность. Ну тут все просто - учить, например, Паскаль сейчас вряд ли целесообразно - реальную разработку на нем практически не ведут. Поэтому лучше изучать что-то с чем потом будешь сталкиваться на практике (в чужих проектах) и с которым легче будет найти единомышленников чтобы совместно разрабатывать большие проекты. И, в перспективе, строить карьеру в этой области.

    Итак, смотрим что у нас есть на этот счет:
    1. C/C++. Статически типизированный и довольно строгий. Очень сложный. На нем можно писать программы в любом стиле, включая метапрограммирование. Кроссплатформенный до жути. Позволяет решать задачи, максимально близко к "железу". Востребован ограниченно. Уникальная ниша - системное программирование и программирование микроконтроллеров. В силу его очень большой сложности - лично я не рекомендую.
    2. Javascript/Typescript. Динамически типизированный (у Typescript есть статическая типизация, но с приколами унаследованными от Javascript). Поддерживает как императивное, так и декларативное программирование. В первую очередь предназначен для браузеров, хотя сейчас есть кроссплатформенная платформа node.js. Востребован в первую очередь на фронте. Так что к нему стоит сразу присоединять в плане обучения HTML/CSS и какой-нибудь фронтовый фреймворк: Angular/React/Vue и т.п. Также пригоден для написания бэкэнда (node.js), десктопных приложений (Electron), мобильных приложений (React Native). Перспективное направление, но лично я не рекомендовал бы как первый язык из-за определенного бардака в экосистеме. В этом направлении легко нахвататься "плохих привычек".
    3. С#. Статически типизированный, поддерживает декларативное программирование, имеет реализацию для Linux (Mono), но в целом заточен на Windows. Вполне востребован, в частности используется в Unity (движок для разработки игр). Насчет него не имею личного мнения, так как не использую в своей работе.
    4. Java. Статически типизированный, поддерживает декларативное программирование, запускается на всем где есть JVM (включая Android). Write once, run anywhere. Востребован в основном в суровом энтерпрайзе, в больших проектах для серьезного бизнеса. Также применяется в вебе.
    5. Kotlin. Улучшенная Java, разработка фирмы jetBrains. Статически типизированный, очень хорошо поддерживает декларативное программирование. Позволяет легко писать асинхронный код (корутины). Запускается там же где и Java (так как использует ту же JVM), плюс имеет возможность компиляции в JavaScript и в native код для Windows/Linux/MacOS. Kotlin для JVM - вполне зрелое решение, Kotlin Multiplatform - пока еще нет, но быстро развивается. Является официальным языком для разработки под Android. Востребован пока не очень (в основном в области мобильной разработки), но его популярность растет и он начинает теснить Java в её традиционном сегменте. В перспективе может стать языком способным охватить большую часть сфер прикладного программирования: backend, frontend, десктопные и мобильные приложения. На мой взгляд - перспективно.
    6. Scala. Еще одна улучшенная Java. Статически типизированный, очень хорошо поддерживает декларативное программирование. Кроссплатформенный как и Java (сейчас вроде появился компилятор в JS, как и Котлина). Сложный. Очень легко написать конструкции в которых "без поллитры не разберешься". В силу сложности востребован мало. Есть уникальные фичи, но не так много по сравнению с Котлином (большая часть реально востребованных фич Скалы в Котлине есть). Ознакомиться в перспективе стоит, рекомендовать как основной язык не буду.
    7. Haskell. Статически типизированный, декларативный язык (не просто поддерживает декларативное программирование - на нем сложно писать иначе). Кроссплатформенный. Востребован в специфических областях. С моей точки зрения - король функционального программирования и в силу этого сложный (математические абстракции в полный рост). Ознакомиться также стоит, просто чтобы почувствовать всю мощь функционального программирования - мозг переворачивает очень хорошо и позволяет глубже понимать другие языки. Как основной язык - рекомендовать не буду.
    8. Python. Динамически типизированный, поддерживает декларативное программирование, кроссплатформенный. Вполне востребован в вебе, в научных исследованиях (нейросети). Опыта работы с ним имею мало, но рекомендовать бы не стал из-за динамической типизации.
    9. PHP. Динамически типизированный, поддерживает декларативное программирование, кроссплатформенный. Весьма востребован, но практически только в вебе (разработка сайтов). Очень низкий порог вхождения, из-за чего очень много плохого кода (хотя сейчас появились достойные фреймворки - Symfony, Laravel, Doctrine и т.д.). Как язык для изучения - не рекомендую.

    Конечно есть и другие языки, которые я не упомянул в силу того что не знаком (или плохо знаком) с ними.
    Из приведенного списка я бы в первую очередь выделил C#, Typescript, Kotlin. Мой личный выбор на данном этапе карьеры - Котлин, но думать, сравнивать и выбирать, разумеется, вам.

    Еще в перспективе стоит познакомиться с такой темой как СУБД и язык запросов SQL. В вебе, как я уже писал, пригодится HTML/CSS. Ну и далее конкретные специфичные вещи, подбираемые уже под конкретную задачу.

    Теперь о книгах. Книги по языкам рекомендовать не буду. Но назову несколько книг, которые, по моему мнению, обязательно стоит прочитать любому программисту:
    1. Э. Хант, Д. Томас. Программист-прагматик
    2. Р. Мартин. Чистый код.
    3. По мере набора опыта: Р. Мартин. Чистая архитектура
    4. При желании стать профессиональным программистом: Р. Мартин. Идеальный программист
    5. Сложная, но тем не менее умная книга: С. Макконнелл. Совершенный код

    Это то что пригодится в любом случае. А дальше - все зависит от выбранного языка и области его использования.
    Ответ написан
    12 комментариев