JavaRush /Курсы /Java Multithreading /Задачи на логические операторы

Задачи на логические операторы

Java Multithreading
10 уровень , 6 лекция
Открыта

— Привет, Амиго!

18
Задача
Java Multithreading, 10 уровень, 6 лекция
Недоступна
Fork/Join
Fork/Join
9
Задача
Java Multithreading, 10 уровень, 6 лекция
Недоступна
Такие хитрые исключения!
Такие хитрые исключения!
18
Задача
Java Multithreading, 10 уровень, 6 лекция
Недоступна
Битовые операции
Битовые операции
Комментарии (46)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Алексей Уровень 1
18 мая 2025
- Амиго, а давай мы тебе расскажем про логические операции. - А может лучше про ForkJoinPool? - Пф. Тут ты уж сам как-нибудь.
StrangeAngel Уровень 46
15 апреля 2023
Интересное задание, решение нашёл в интернете, разобрал его и вроде бы понял как это всё делается. Побольше надо лекций на побитовые операции.
Igoreek Уровень 43
30 сентября 2024
и где же ты их собрался применять? Думаю это пригодится только сеньору и то в очень специфических задачах...
Sitnikov Konstantin Уровень 36
24 декабря 2022
По поводу третьей задачи нашёл неплохое объяснение https://habr.com/ru/post/93172/ Там объясняется зачем мы делаем эти сдвиги, хотя последнее действие автор делает через вычитание, а не через "И НЕ". Также приводится несколько других вариантов решения задачи.
Ars Уровень 41
13 ноября 2021
Инфа по последней задаче: Вы решили задачу лучше, чем 4% учеников. Вам удалось ее решить с 4 попытки. Среднее количество попыток для этой задачи 1.64. Всего эту задачу решили 3539 учеников. Получается 96% решают за 3 попытки или меньше. То есть она настолько несложная для них? Да, можно проверять задачу до отправки решения. Но проверить так, что сразу всё правильно. Как-то с трудом верится. И у ресторана тоже выдавало, что сложные задачи многие решали всего с нескольких попыток. Хотя казалось с таким валидатором и комментариями про сложность среднее количество попыток должно быть в районе 10-15.
Jh-007 Уровень 28
15 декабря 2021
Просто, поиск выдает сразу алгоритм. В нем 5 строк.
22 сентября 2021
Вот с последней задачей - интересная потому-что непонятная надо будет детально ее изучить .
31 марта 2021
В первой задаче нет никакой выгоды от использования Fork/Join. Так как процесс вычислений не разбивается на параллельные вычисления, происходит последовательный вызов по одному binaryRepresentationMethod, в итоге вычисления становятся более длительными из-за создания и запуска трэдов. Так для преобразования Integer.MAX_VALUE на моем компе получились следующие времена: 1111111111111111111111111111111 - 2ms 1111111111111111111111111111111 - 21ms Новый метод работал на 19 миллисекунд дольше!
CyberBoar Уровень 1
16 августа 2022
Понятно, что 0 профита в использовании fork/join в этом примере. По видимому, он был нужен просто чтобы люди с этой темой столкнулись, и хоть сколько то разобрались.
Pig Man Уровень 41
4 января 2021
(Продублирую свой комментарий под 1 задачей) Реально заколебался искать информацию насчет этой темы. Посмотрел 4 видео, прочел несколько статей, долго пытался повторить увиденное. Напишу то, к чему пришел: Есть какая-то работа, которую можно разбить на куски и которая не зависит от последовательности выполнения этих кусков. Самый простой пример: посчитать сумму последовательности чисел. У нас есть массив array (у меня в коде это статическое поле класса). В этом массиве хранится последовательность чисел от 0 до 5000. Есть метод, который весьма тривиальным способом складывает числа с одного индекса по другой. Я добавил Thread.sleep(1); всего на 1мс при каждой итерации, чтобы побольше нагрузить по времени наш метод (ведь более сложная задача может занимать много времени). Вот, что получилось:

private static Long getSum(int start, int end) {
    long sum = 0;
    for (int i = start; i < end; i++) {
        try {
            Thread.sleep(1);
        } catch (InterruptedException ignored) {
        }
        sum += array[i];
    }

    return sum;
}
Даже по нехитрым расчетам можно понять, что исполнение займет больше 5 секунд, так как тред 5 секунд просто спит + еще исполнение остального кода. Запустим данный метод:

public static void main(String[] args) {
    long timeStart = new Date().getTime();
    System.out.println(getSum(0, 5000));
    System.out.printf("Time: %d sec", (new Date().getTime() - timeStart) / 1000);
}
// 12497500
// Time: 9 sec
А теперь переходим к ForkJoinTask (использую его разновидность RecursiveTask, который позволяет возвращать значение). Идея такая: Зачем нам один поток, который выполняет подсчет суммы, если можно запустить несколько потоков, каждый из которых будет подсчитывать сумму на выделенном ему участке и возвращать, а мы сложим эти суммы и получим общую.
Pig Man Уровень 41
4 января 2021
Вот мой класс:

private static class MyFork extends RecursiveTask<Long> {
    private final int start;
    private final int end;

    public MyFork(int start, int end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        if (end - start <= 1000) {
            return getSum(start, end);
        } else {
            int mid = (end + start) / 2;

            MyFork myFork1 = new MyFork(start, mid);
            MyFork myFork2 = new MyFork(mid, end);
            invokeAll(myFork1, myFork2);

            return myFork1.join() + myFork2.join();
        }
    }
}
Объект нашего класса знает, на каком участке ему выделили работу (поля start и end). Но он умнее, чем кажется. Он возьмется за подсчет суммы, только если его участок <= 1000. Если же выделенный участок слишком большой, то он решит позвать друзей (вспомнил чет мистеров Мисиксов сейчас): он посчитает середину своего участка и отправит на работу 2 новых объекта этого же класса в 2 параллельных тредах, дав одному участок от start до mid, а другому от mid до end, сам же он подождет, пока они ее оба завершат, сложит сумму и отправит в качестве своей работы. А магия тут в том, что так как он отправляет на работу объекты этого же класса, они могут точно так же отказаться от выполнения работы, если выделенный участок для них слишком велик и разделить ее на 2 других потока. Так что мы будем складывать работу нескольких тредов. Запустим код:

public static void main(String[] args) {
    long timeStart = new Date().getTime();
    System.out.println(new ForkJoinPool().invoke(new MyFork(0, 5000)));
    System.out.printf("Time: %d sec", (new Date().getTime() - timeStart) / 1000);
}
// 12497500
// Time: 3 sec
Как видим, он выполняется всего за 3 секунды, хотя должен был только спать 5 секунд
Pig Man Уровень 41
4 января 2021
Я продемонстрировал лишь общую идею данного подхода. Всякие нюансы исполнения еще сам не знаю. Вам в любом случае придется искать информацию обо всем этом, потому что мне было лень писать целую статью с объяснением каждой мелочи. Но глянте ссылки в комментариях к задаче, там все есть. Грустно, что тут не было объяснено ничего и приходится самому все раскапывать (как обычно, да)
Anonymous #838725 Уровень 1
22 февраля 2021
спасибо за потраченное время, и эффективные объяснения. вот так должны сложные темы быть объяснены. JRush действительно многое теряет из-за плохой (недостаточной) подачи теории.
Pig Man Уровень 41
22 февраля 2021
Да не за что, мне так самому лучше запоминается. А вообще, да, объяснений очень многих тем тут было сведено к минимуму или отсутствует вовсе. Хоть параллельно с этим курсом пиши статьи к каждой теме и в конце сможешь открыть свой более эффективный курс
Kes Уровень 41
26 июля 2021
Pig Man, спасибо за комменты.

sum += array[i];
я бы исправил на

sum += i;
а

            MyFork myFork1 = new MyFork(start, mid);
            MyFork myFork2 = new MyFork(mid, end);
на

            MyFork myFork1 = new MyFork(start, mid);
            MyFork myFork2 = new MyFork(mid + 1, end);
И так всё красиво работает. Есть какая-то работа, которую можно разбить на куски и которая не зависит от последовательности выполнения этих кусков. Самый простой пример: посчитать сумму последовательности чисел. Тоже долго копался с данной темой. Даже хотел статью написать, потом как обычно понял, что статья никому не нужна, она лишь только подогревает ЭГО. Мне кажется, в текущей ситуации у нас есть работа, которая может запустить точно такие же определенные "подработы" или вернуть результат, если мы добились хорошего уровня разбиения. Таким образом есть до хрена подзадач, которые надо выполнить именно в определенной иерархической последовательности. Этим и хорош ForkJoinPool Источник, который построил мои нейронные связи
Виталий Уровень 35
30 ноября 2020
Что то последние задачи совсем без интереса решаются, точнее особо не хочется даже разбираться в этой каше...потому что нет понимания для чего это всё...... Примерно таже история была в школе.институте, с интегралами,молекулярными уравнениями т .д. .. Когда не понимаешь когда это тебе и зачем пригодится,очень трудно дается обучение. Гораздо проще,когда столкнешься с этим в реальной жизни и там на месте разобраться, так как один фиг что сейчас тут пытаешься понять, перезаписывается в памяти новыми данными на следующих этапах обучения)) Я так считаю.
Alukard Уровень 37 Expert
5 декабря 2020
Чёт прям аналогично.
Алексей Мирный Уровень 41
10 декабря 2020
согласен!
Pig Man Уровень 41
4 января 2021
Ага, прочел формулировку последнего задания - до свидания. Понятия не имею, нужно ли такое вообще делать в реальной жизни, но звучит как "побрейте волосы на заду у великана" (шутка из старого сериала). Зачем..?
Mike Уровень 41
12 марта 2021
Ребят. Ну мы же учимся. Последняя задача, например, учит побитовым операциям (которые я до этого вообще не применял, например) и учит придумать алгоритм, который делает то, что нужно, без использования логических операторов. И она офигенная на самом деле - я потратил 4 часа, выдрал кучу волос на голове - мозг долгое время отказывался верить, что это возможно сделать, но в итоге две страницы в блокноте с единицами и нулями, куча тестов в JShell и я додумался до решения сам, без копаний в интернетах. Да, вряд ли что-то подобное встретится нам на будущей работе, но это сильно прокачивает наш мозк, а прокаченный мозк - пожалуй основной хард-скилл для девелопера как мне кажется. В общем все задачи хороши, просто вы неправильно их готовите))
Justinian Уровень 41 Master
19 июля 2021
все так, мне это напоминает бокс. Есть боксеры, которые интуитивно или вследствие опыта знают что делать, почему нужно в такой ситуации делать так, в такой сяк. Есть боксеры, которые в силу недостатка опыта могут не понимать, к чему это все, или как поступать, или почему, но они слушают тренера, тренер сказал, они выполнили установку - получили результат. Со временем поняли почему именно так. А есть те, кто и не видит, и не слушает. Ну что тут скажешь, если бы все делали, то что нужно, были бы эффективные на 100%, ни я, ни большинство учеников джава раша работу бы не нашли. А так, одни недорабатывают, а другие уходят вперед. А те, кто не дорабатывают, они даже не стоят на месте, они откатываются назад, предоставляя пространство под солнцем для тех кто сзади, те кто впереди и так уже за горизонт убежали. Но это жизнь, ничего такого нет, каждый из нас в чем-то больше, в чем-то меньше недорабатывает, но здесь конечно самая большая логическая ошибка это непринятие в расчет соотношение собственной экспертизы в джаве и преподавании джавы и авторов курса. Понятное дело, что даже доктор к примеру выпишет лекарство, и иногда его лучше не пить, но там ставка жизнь + наш организм имеет колоссальные резервы, мы можем пойти к другому доктору и тд. А здесь просто учебное упражнение которое делают многие, а базы и фундамента много не бывает. Еще одна логическая ошибка в фразе

роще,когда столкнешься с этим в реальной жизни и там на месте разобраться,
Проблема и ошибочность подхода очевидна - должна быть база, и когда будет вопрос конкретного применения, будут сроки, будут своих проблем миллион. Поэтому на работе не нужно все знать, но базу ставить там не будет времени, будут конкретные сроки и суть задачи будет в другом. Так и джаву можно не учить. Дадут таску, написать веб-сервер на 100 энтити, и сделать это за N времени, вот тогда можно и про ООП почитать, джаву начать учить. Но реально тогда будет не до базы.
Kes Уровень 41
26 июля 2021
Justinian Тут главное золотую середину найти. Можно лет пять изучать все тонкости и побитовых операций, особенностей работы сборщика мусора, все паттерны учить на зубок. Мне кажется каждому работодателю хочется найти своего человека, который глубже прошарил определенную тему, для этого и собеседования.
Justinian Уровень 41 Master
26 июля 2021
Согласен, об этом я ведь и писал - что нужна золотая середина, а не "какая-то тема, не понимаю зачем - в топку!". О пяти лет изучениях я не писал, но те же побитовые операции для программистов, это как 2 + 2 = 4 в контексте математики, это самая база, там нечего 5 лет тонкости изучать, есть основные моменты которые нужно проработать. Собесы нужны для того, чтобы выявить уровень техзнаний кандидата. Если говорить об уровне джунов, то никаких "глубоких" знаний не будет требоваться, там лишь бы хоть в какой-то мере проработать ) Просто у учеников часто бывает искривленное восприятие - они считают, что та или иная тема КОТОРАЯ ИМ НЕ НРАВИТСЯ (а не нравится то, что не понимают , либо то, что идет тяжело, гораздо приятнее посидеть на компе поиграться или видосики посмотреть, чем убраться в квартире) это просто ну слишком глубокая проработка. На их взгляд. Хотя те же паттерны базовые, простые как двери, и те кто прошел джава раш, разобрал основы джава ее, подготовился к собесам - и так те паттерны запомнит, битовые операции это базовые знания, кто-то в школе еще их проходит, их на собесах почти не принято спрашивать у джунов, но могут спросить у стажера, это просто как 2 + 2 =4, просто показатель уровня программиста, не все понимают их суть, не всем и нужно, но потом разбираьтся с ними просто не будет время, когда на таску дадут полдня, через несколько часов демо с кастомером, или лиду надо дать МР на ревью, не будет время зачищать свои хвосты. Знают знают, не знают не знают. Поэтому да, баланс, именно в этом и суть моего коммента, поскольку этот баланс бывает искривлен в сторону самомнения и нежелания проходить "неудобные" для себя темы. Но ничего плохого нет, у каждого своя стратегия обучения - кто-то не дорабатывает, понижает свою конкурентноспособность, и потом навряд он сможет ее выравнять, с мелочей все состоит, а кто-то наоборот, дожмет, и займет его месте. Программистов много, но они разные по уровню знаний и зп. Это определяет как выстраиваются ориентиры
Kes Уровень 41
26 июля 2021
Спасибо
Алексей Уровень 41
30 ноября 2020
Полезная ссылка на побитовые операции, которая поможет решить 3-ю и последующие задачи.
Даниил Уровень 41 Master
28 июня 2019
Как то весь этот уровень даже со старта нелегко даётся... И тут я понял что даже слабее чем я сам думал (а я думал о себе не очень...). Ну хоть гуглить научили чему доказательство осознал на этом уровне.