1. Java / Говнокод #23368

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    class Functions //здесь функции
    {
      static void PrintInfo(String[] args) //инфа из стандартного ввода
      {
        try( BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) )
        {
          int lines=0;
          int words=0;
          int symbols=0;
          String s;
          while( (s=br.readLine()) != null )
          {
            lines++;
            words+=Functions.NumberWords(s);
            symbols+=Functions.NumberSymbols(s);
          }
          if(args.length == 0) {
            System.out.format("%7d%7d%7d\n", --lines, words, --symbols);
          }
        }
        catch(IOException e) {
          System.out.println("Ошибка: "+e);
        }
      }
    
      static int NumberWords(String s) //количество слов в строке
      {
        char c='-';
        int num=0;
        boolean change=false; //сделано чтобы пустые строки не прибавляли значение num
        
        for(int i=0; i<s.length(); i++) {
          if( s.charAt(i)==' ' && (c!=' ' && c!='\t')
              || s.charAt(i)=='\t' && (c!=' ' && c!='\t') ) num++; //новое слово
          c = s.charAt(i);
          if(!change ) change=true;
        }
        if(change && c!=' ') num++; //последнее слово
        return num;
      }
      
      static int NumberSymbols(String s)
      {
        int count=0;
        for(int i=0; i<=s.length(); i++)
          count++;
        return count;
      }
      
      static void getInfo()
      {
        try( BufferedReader b = new BufferedReader(new FileReader("help")) )
        {
          String s;
          while( (s=b.readLine()) != null )
            System.out.println(s);
        }
        catch(IOException e) {
          System.out.println("Файл справки отсутствует");
        }
      }
    }

    Переписываю все программы из linux на java, это говно-наработки

    Запостил: GOVNOCODER-SYKA, 28 Сентября 2017

    Комментарии (36) RSS

    • > s.charAt(i)=='\t' && (c!=' ' && c!='\t') ) num++;
      Какой замечательный пример Java-style и следования философии Java!

      > class Functions //здесь функции
      Блядь. Вот не понимаю я этого. class Functions, блядь. Functions - это класс. Класс чего, сука? Какой объект описывает класс Functions? Вот нахуя писать код, семантика которого полностью, мать его, контринтуитивна? Говно какое-то, пидоры, блядь, ебанные! Всех разъебал бы!
      Извините, накипело.
      Ответить
      • Разъебать тут надо прежде всего джава-философов, которые почему-то пришли к выводу, что свободные функции нинужны. В итоге все, включая разрабов стандартной либы, вынуждены городить эти уебанские классы-неймспейсы.
        Ответить
        • Я у себя на работке и в плюсах видел классы-неймспейсы.
          Ответить
        • oop-адепты предлагают смишные алтернативы
          http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html
          Лишь бы не признавать, что ООП в принципе невыразительное УГ.
          Ответить
          • > int max = new Max(10, 5).intValue();
            mdaaa..
            Ответить
            • 1. Создаём заведомо ненужный экземпляр класса.
              2. Засираем оперативку лишними копиями входных данных.
              3. Бизнес-логику внедряем в совершенно неподходящий по семантике метод intValue.
              4. Экземпляр класса отдаём на съедение мусоросборщику.
              5. Отравляем жизнь пользователям библиотеки уродским синтаксисом (необходимостью писать «new» и всё такое).

              Всё посчитал или что-то забыл?
              Ответить
              • 6. Отравляем жизнь потомкам, которым это ебанутое творение придется поддерживать.

                А жава не умеет оптимизировать 1, 2 и 4? В плюсах от этого всего остается просто сравнение https://godbolt.org/g/spFscH
                Ответить
                • Стандартный javac из оракловского JDK ничего не оптимизирует:
                  int i = (new Max(10, 5)).intValue();
                      //    0    0:new             #2   <Class Max>
                      //    1    3:dup             
                      //    2    4:bipush          10
                      //    3    6:iconst_5        
                      //    4    7:invokespecial   #3   <Method void Max(int, int)>
                      //    5   10:invokevirtual   #4   <Method int Max.intValue()>
                      //    6   13:istore_1


                  Либо я не умею им пользоваться...
                  Ответить
                  • И не будет. В жабе, емнип, оптимизации или на уровне jit'a или пост-обработкой байткода. А конпелятор всегда генерит дословный байткод.
                    Ответить
                    • Проверил, gcj генерирует байт-в-байт такую же питушню, как javac (если выбрать генерацию байткода для JVM, а не нативного, разумеется).

                      Значит, шансы найти оптимизирующий компилятор малы по причине идеологии Java?
                      Ответить
                      • А как жаба будет километровые бектрейсы рисовать, если там все будет оптимизировано и заинлайнено?
                        Ответить
                        • Так же как плюсы рисуют. В чем проблема?
                          Ответить
                          • И как же он инлайнового петуха распетушит? Как номера строк в стеке покажет и имена функций?
                            Ответить
                            • У конпелятора же все ходы записаны в отладочную инфу.

                              И по этим таблицам и текущему instruction pointer'у вполне можно воссоздать подразумеваемые фреймы заинлайненных функций.

                              Разве что оптимизация хвостовой рекурсии необратимо портит бектрейс.
                              Ответить
                            • До инлайна:
                              f(a, b):
                                r = a
                                r += 2
                                r /= b
                                return r
                              
                              g():
                                a = 1
                                b = 0
                                c = f(a, b)
                                c *= 2
                                return c


                              После инлайна:
                              g():
                                a = 1
                                b = 0
                                // begin f()
                                c = a
                                c += 2
                                c /= b // Oops, devided by zero
                                // end f()
                                c *= 2
                                return c


                              Из отладочной инфы отладчик знает, куда компилятор заинлайнил функцию f. Если он видит, что деление на ноль произошло между '// begin f()' и '// end f()', то может добавить вызов f() в стектрейс. Очевидно же.
                              Ответить
                              • Ну не всё так очевидно - код от f() и g() может перемешаться в кучу, инструкции от нескольких функций могут смёржиться в одну, а функции в духе void h() { return g();} вообще остаются без кода...

                                Но как первое приближение - сойдёт.
                                Ответить
                                • З.Ы. Cursor dance во время пошаговой отладки оптимизнутого кода, когда курсор улетает на 5 строк вверх, хаотично скачет между тремя строками линейного кода и улетает в конец совершенно левой ветки - это незабываемо.
                                  Ответить
                              • С отладчиком всё ясно, но жаба должна уметь рисовать бектрейсы прямо в рантайме на продакшоне. В таком случае отладочную инфу придется всегда таскать с собой и распердоливать оригинальный бектрейс на каждый throw (а их в жабе тысячи, ООП же, хули), и тут уже вопрос, останется ли после этого эффект от всех оптимизаций...
                                Ответить
                                • Во время каждого throw не надо - только для тех, где реально выводится бектрейс. А отладочная инфа - это ж просто маппинг нативной инструкции на одну или несколько строк в коде... В принципе, если jit детерминированный, он может её на лету построить, когда она реально понадобится.
                                  Ответить
                                  • > только для тех, где реально выводится бектрейс
                                    А вот определить такие уже задача не такая тривиальная, учитывая что ыксепшн может перехватываться в какой-нибудь другой библиотеке.
                                    Ответить
                                    • А throw и не надо определять - во время unwind'а запоминаешь адреса, которые размотал со стека. Если стектрейс понадобился - вот только тогда резольвишь их в строки. Не понадобился - ну и хуй с ним, адреса собрать было не так уж дорого.
                                      Ответить
                                    • З.ы. Емнип, жаба стеки парсит ещё и для проверки привилегий (на открытии файлов и т.п.)
                                      Ответить
                        • Ну она же исходный байткод не выбросила, так что сможет восстановить картину. Из необратимых оптимизаций в голову приходит разве что tail call.
                          Ответить
                          • Почему tail call необратим?
                            Ответить
                            • Потому что он перетирает последний стекфрейм.

                              f(x):
                                if x % 5 == 0: return f(x + 2)
                                else: return f(x + 3)


                              В примере выше информация о том, какой из двух рекурсивных вызовов сработал на каждой итерации, будет потеряна при оптимизации хвостовой рекурсии.
                              Ответить
                              • Да и даже информация о том, были ли они вообще. Только косвенно по значению x можно догадаться.
                                Ответить
                                • В теории для каждой хвостовой рекурсии можно хранить на стеке счётчик глубины вызовов. Это решает проблему "были ли они вообще", но не решает проблему "какой из двух рекурсивных вызовов сработал".
                                  Ответить
                                  • > счётчик глубины вызовов
                                    А если там разные функции tail call'ятся - то и счётчик будет сложно хранить.
                                    Ответить
                                    • > А если там разные функции tail call'ятся

                                      Согласен. Кстати, в Scala/Clojure такая оптимизация не работает, там trampolines приходится использовать. Скала, правда, никакие счётчики для генерации стек-трейсов они не хранит, просто превращают рекурсию в цикл в байткоде.
                                      Ответить
                              • > f(x)

                                Что-то у вас, батенька, пример расходящийся
                                let rec f k = function
                                  | 1 -> k
                                  | n when n mod 2 == 0 -> f (k + 1) (n / 2)
                                  | n -> f (k + 1) (3 * n + 1)
                                Ответить
                                • Всмысле? Что бесконечная рекурсия? Просто иллюстрация же.
                                  Ответить
          • Остаётся прикрутить DI, ведь если создавать экземпляр Max() по месту, то его нельзя будет подменить для тестирования.
            Ответить
            • Max max = BeanLookupManager.getInstance().getBean( MaxFactory.class).createMax(0, 10);
              MaxToIntConvertStrategy str = BeanLookupManager.getInstance().getBean( MaxToIntConvertStrategy.class);
              MaxConvertedToInt toInt = str.convert(max);
              int foo = toInt.asInt();
              Ответить
              • use SimplePHPEasyPlus\Number\NumberCollection;
                use SimplePHPEasyPlus\Number\SimpleNumber;
                use SimplePHPEasyPlus\Number\CollectionItemNumberProxy;
                use SimplePHPEasyPlus\Parser\SimpleNumberStringParser;
                use SimplePHPEasyPlus\Iterator\CallbackIterator;
                use SimplePHPEasyPlus\Operator\AdditionOperator;
                use SimplePHPEasyPlus\Operation\ArithmeticOperation;
                use SimplePHPEasyPlus\Operation\OperationStream;
                use SimplePHPEasyPlus\Engine;
                use SimplePHPEasyPlus\Calcul\Calcul;
                use SimplePHPEasyPlus\Calcul\CalculRunner;
                
                
                $numberCollection = new NumberCollection();
                
                $numberParser = new SimpleNumberStringParser();
                
                $firstParsedNumber = $numberParser->parse('1');
                $firstNumber = new SimpleNumber($firstParsedNumber);
                $firstNumberProxy = new CollectionItemNumberProxy($firstNumber);
                
                $numberCollection->add($firstNumberProxy);
                
                $secondParsedNumber = $numberParser->parse('1');
                $secondNumber = new SimpleNumber($secondParsedNumber);
                $secondNumberProxy = new CollectionItemNumberProxy($secondNumber);
                
                $numberCollection->add($secondNumberProxy);
                
                $addition = new AdditionOperator('SimplePHPEasyPlus\Number\SimpleNumber');
                
                $operation = new ArithmeticOperation($addition);
                
                $engine = new Engine($operation);
                
                $calcul = new Calcul($engine, $numberCollection);
                
                $runner = new CalculRunner();
                
                $runner->run($calcul);
                
                $result = $calcul->getResult();
                $numericResult = $result->getValue(); // 2
                Ответить
                • ой, да нет. Это же пхп.

                  <? if ($a > $b)
                  {echo "<b>это число больше</b>"}?>
                  <? if ($a < $b)
                  {echo "<b>это число меньше</b>"}?>
                  Ответить
          • >> In an object-oriented paradigm, we should
            >> instantiate and compose objects, thus letting them
            >> manage data when and how they desire. Instead of calling
            >> supplementary static functions, we should create objects
            >> that are capable of exposing the behavior we are seeking

            Дали обезьяне молоток, обезьяна постучала по кокосу, попила молоко — вкусно!
            С тех пор бегает она с одним молотком в лапе и пытается разжечь им костёр — ну, чтобы эволюционировать в человека. Пока не получилось — ни первого, ни второго.
            Ответить

    Добавить комментарий