Блог пользователя ajxu2

Автор ajxu2, история, 12 месяцев назад, По-английски

Recently, I participated in Codeforces Round 873 (Div. 2). I was doing well, and in the last 5 minutes of the contest I solved problem D1, putting me at rank 200 and with CM performance. I was happy with myself until this happened:

I saw that I got TLE on test case 13 and quickly realized what happened. I chose to use Java in this round, and I had somehow fallen in another one of Java's traps. Now, I've decided to compile a comprehensive list of these pitfalls so no one can FST to them again. (Hopefully after you see this you'll be convinced to just use C++.)

1. Array sorting

Problem
Solution 1
Solution 2
Solution 3

2. String concatenation

Problem
Solution

3. Input/output

Problem
Solution

4. Comparing objects

Problem
Solution

5. Stacks

Problem
Solution

In conclusion, you should just use C++, because this is just too much stuff to remember. With C++, none of these are even issues.

If you have any more Java pitfalls, feel free to comment about them!

  • Проголосовать: нравится
  • +130
  • Проголосовать: не нравится

»
12 месяцев назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

In conclusion, you should just use C++, because this is just too much stuff to remember. With C++, none of these are even issues.

Java is good enough to get you a decent rank. There are quite a number of red coders who use Java.

If you use a programming language without understanding what you are doing, then you will obviously run into this sort of problems. C++ has its pitfalls too.

For example in C++: for(int i = 0; i < n; i++) c = c + a; can potentially be much slower than for(int i = 0; i < n; i++) c += a;

where c and a are strings.

But then again, C++ is indeed faster than Java given that you use both languages correctly. But don't think that you can get away with slipshod understanding by using a faster programming language.

  • »
    »
    12 месяцев назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    I agree that C++ has issues too, but in general, it has fewer issues, and the main ones (I/O, unordered_map) are really easy to fix. Therefore, it's less likely that you'll FST or get hacked with a C++ submission. On the other hand, it's really easy to fall into "black magic death traps" in Java that you didn't even know existed, especially considering most problems are made by C++ coders.

    Java is definitely good enough to get you a decent rank though (see SecondThread) and if you'd like to use Java then by all means go ahead.

»
12 месяцев назад, # |
Rev. 5   Проголосовать: нравится +1 Проголосовать: не нравится

Thanks for the helpful blog.


  • Set Long set = new HashSet<>();
  • long x = 5;
  • set.add(x);
  • out.println(set.contains(5));

  • Answer is false

  • Soln

  • out.println(set.contains(5L));
  • // true
  • Because of small stack size in java , many times DFS gives runtime error Is there any solution for it other than using BFS?

    for point 4 , instead of using equals , converting to int from integer than using == is much cleaner.

    • »
      »
      12 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
    • »
      »
      10 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Could you explain what this is and why that problem is occurring? I'm still a little confused about what the runtime error is, and why stack size has anything to do with this. This is probably due to my ignorance of Java docs, so any explanation would be appreciated!

      • »
        »
        »
        10 месяцев назад, # ^ |
        Rev. 2   Проголосовать: нравится +1 Проголосовать: не нравится

        Actually DFS uses recursion and recursion uses stack and there is a size limit of stack , so when the recursion goes deep the stack requires more memory , so by default it less and we can change it.

        e.g
        This Problem.
        This gives run time error and this passes after adjusting the stack size by adding this line

        new Thread(null, new Main(), "whatever", 1<<27).start();

        • »
          »
          »
          »
          10 месяцев назад, # ^ |
            Проголосовать: нравится +1 Проголосовать: не нравится

          oh, I see now thanks for the explanation. Your comment on longs was separate from your comment on stack size. I thought something about stack size was affecting the ==s operator on longs

    »
    12 месяцев назад, # |
      Проголосовать: нравится 0 Проголосовать: не нравится

    If the reference is compared, then shouldn't a==b have the same problem as c==d. why does one return true but the other return false? a, b, c, d are all Integers aren't they?

    • »
      »
      12 месяцев назад, # ^ |
      Rev. 2   Проголосовать: нравится +15 Проголосовать: не нравится

      there is some random java bullshit about numbers below 128 and numbers above iirc, maybe i remember the wrong border though

    • »
      »
      12 месяцев назад, # ^ |
        Проголосовать: нравится +13 Проголосовать: не нравится

      Java has something weird they do with small enough Integer values called auto-boxing.

      Auto-boxing is the idea of automatically converting a primitive (e.g. int) and its corresponding wrapper (e.g. Integer).

      Basically, $$$a$$$ and $$$b$$$ will both point to the same reference as they're small enough in absolute value ($$$-128 \le a,b \le 127$$$ if I remember correctly), whereas $$$c$$$ and $$$d$$$ are big enough that they'll be equal in value (c.equals(d) is true) but not in reference (c == d is false).

      • »
        »
        »
        12 месяцев назад, # ^ |
          Проголосовать: нравится +1 Проголосовать: не нравится

        I see. Im guessing they store all the number from [-128, 127] in memory and then create a reference to it when creating the variable?

    »
    12 месяцев назад, # |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    as a non-java coder, I am asking myself... why TF doesn't Java offer an easy way to compare two numbers (using = or == or whatever) and instead you must use the ugly .equals()?

    • »
      »
      12 месяцев назад, # ^ |
      Rev. 5   Проголосовать: нравится 0 Проголосовать: не нравится

      Integer is a pointer in Java. The value type is int.

      == has been already defined on all pointers as comparing object id (kind of memory address), and Integer doesn't want to break this.

      If you use int (it's a more common case), you use ==. But however, you will be unable to assign null to the variable since it's not a pointer.

      int a = 1; // Ok
      Integer b = 1; // Ok, notice that it cast an `int` to a pointer, usually this is rejected by compilers of most languages, but Java provides a compiler feature called `autoboxing`, which will expand this line to `Integer b = Integer.valueOf(1);`
      int c = null; // Compile error, c is not a pointer
      Integer d = null; // Ok
      

      null is important for collections in Java, since the value may not be always present. For example.


      var map = ... // The keyword `var` in Java is something like `auto` in C++ Integer value = map.get("key"); if (value != null) { // If the value is found in the map // Do something } else { // If the value is not found in the map // Do something else }
    • »
      »
      12 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      we must use the ugly .equals() for java strings too. unless they are interned

      • »
        »
        »
        10 месяцев назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        oh, I never knew about that! Is there ever an application of using ".intern" in java for competitive programming?

    »
    12 месяцев назад, # |
      Проголосовать: нравится 0 Проголосовать: не нравится

    1.arrays.solution-3 , how does that work?

    »
    12 месяцев назад, # |
      Проголосовать: нравится 0 Проголосовать: не нравится

    For 5, you can use Dequeue also. It has the same complexity as of ArrayList.

    »
    12 месяцев назад, # |
      Проголосовать: нравится 0 Проголосовать: не нравится

    As you mentioned in the solution, all of the problems you mentioned with JJava can be bypassed effortlessly. Don't motivate people to leave Java. C++ also has issues like initializing randomly for primitive data type arrays. Java uses default values for them (0 for int[] and false for boolean[]).

    Also, Java does not provide Segmentation fault, which I like about Java.