67

I completed 100 Days of Java over 5 years and mapped the journey as a graph

Takes me back to simpler days when Java was THE language to learn and book like this was interesting. It seems the author took each day in the book as an inspiration for a blog post, which gives it value beyond the book itself.

a day agokristianp

I taught students in Java and Python and noticed that Python is actually harder. Things you don't even notice, like breathing, make a lot of confusion for newcomers.

The biggest one is types -- students think in terms of meaning, not types, e.g. "this my variable contains first name", but they don't realize it's a string. Or "this is products in checkout cart", but the variable is an integer, so it's products count, not a list of product. Once students get idea of getting an item of a collection and getting a field of that item, while watching every type along the way -- that's a major breakthrough during learning.

The easiest to learn would be a language where you have to define all variable types on top, like Pascal (a language created specifically for learning). But Java is still better than Python, as it doesn't even run wit messed types.

a day agodeepsun

Java would be fine if it and it's community wouldn't force OOP and GOF patterns everywhere.

20 hours agoDeathArrow

2003 called and wants its arguments against Java back.

Modern Java can be OOP, functional or procedural where useful. GoF patterns were never enforced by the language.

17 hours agobzzzt

I'd say GoF patterns were pretty enforced by the language if you include the standard libraries.

Or maybe that's even a bit rude to GoF. Some OO patterns - pretty questionable ones - were pushed pretty hard especially in Java EE.

17 hours agovintermann

Java EE is pretty darn retro right now, and it was never core Java

3 hours agopeterashford

Java EE practically reinvented itself over the last 20 years using the more popular frameworks as inspiration for better or worse.

Even then, you were never forced to use Java EE if you didn't need it.

12 hours agobzzzt

Unless you write everything from scratch, you are forced to deal with 20 years of bad design. I really wish people would just stop beating this dead horse.

16 hours agoahoka

A lot of de Java standard library is actually quite nice to program with. Of course there are less good parts, but Java is committed to compatibility so you can choose between dealing with an old design versus continually refactoring code to the standard of the day. I prefer having a choice.

As far as Java use in companies is an indicator, the horse is still running.

12 hours agobzzzt

Does the name of the class inside the file still break the wall and force what the name of the file needs to be?

17 hours agofragmede

There is an argument for that being an opinionated part of the Java language, and as i hear it, opinionated programming languages are all the rage.

Fwiw, I like that class names and file names must match. In python codebases I have had annoyances with this when I adopted others work.

13 hours agowhatisthiseven

Well I don't want to come along with you, as while Java might be an ok language, and a great runtime, the cultish Clean Code middle management, and design patterns, with intentionally obscure control flow paths thanks to stuff like dependency injection, and state smeared across dozens of objects (hidden behind interfaces ofc).

Javas biggest engineering upside was that its JIT compiler allowed the runtime to see through this mess and extract decent performance out of 5 layers of dynamic dispatch that shouldn't have been there in the first place.

Add to that the unclear licensing, which meant that there wasn't a single Linux distro that shipped it out of the box, and the development culture it fostered which required 10x the people each spending 10x the time to build features, and single-handedly was responsible for coining the term 'code monkey'.

As for the software - remember Eclipse? I sure do, but I haven't seen it in like half a decade or more, and that certainly doesnt make me sad.

10 hours agotorginus

What exactly is the intuition behind taking something inherently linear like a sequence of 100 days and presenting it as a graph with no information given about the rationale or reasoning behind the edges.

a day agogbnwl

Think of each day as a lesson, and then it makes more sense. E.g. Lesson 49 was useful for understanding Lessons 50 and 65.

18 hours agoelric

It's 100 days of Java, not 100 days of Visual Information Architecture.

21 hours agogowld

I completed 100 Days of Java and ended up and it took me roughly 5 years.

Made an interactive map/index of the posts, linked by related topics. I made it to make the series easier to browse by concept instead of only by day number.

3 days agocelurian92

Nice work! I appreciate the topic and search filters too.

a day agoevanjrowley

I looked around, but can't find the source information this was created off of -- where are the questions/topics for the 100 days listed?

a day agojacobrussell

This website is very confusing.

a day agofabiensanglard

would love to know how can i improve if you can give some feedback like which part is confusing.

17 hours agocelurian92

I personally am not sure what's the point of this, when the graph seems like doesn't give any real information + doesn't even work on mobile (no hover), but congrats on finishing up the series!

a day agodebesyla

sorry as UI was not optimized enough for mobile but my intention was to show the adventure of writing and learning more about java

20 hours agocelurian92

You should try rendering the graph in 3js. It’s pretty easy and so so beautiful.

Toto.tech has a decent example. You have flight controls with wasd + mouse

a day agoafunk

will try it this weekend. Thanks for the suggestion

19 hours agocelurian92

Your category names aren't rendering the "&" correctly as "&", might want to look into that (Chrome 147.0.7727.138, Windows)

18 hours agovoidUpdate

This looks interesting, I worked with Java some time ago, but haven't touched it for some time. I guess since the graph is really not that intuitive this really describes how complicated can be learning Java!

a day agoartenes_dev

Wait, foreach is slower then for loop? I did not know this.

19 hours agoMashimo

I'd be a bit skeptical of the result given the benchmark program:

    import java.util.ArrayList;
    import java.util.List;
    
    class Day06 {
        public static void main(String args[]) {
            List<String> fileTypeList = new ArrayList<>();
            for (int i = 0; i < 1000000; i++) {
                fileTypeList.add("fileType");
            }
    
            long beforeForLoop = System.currentTimeMillis();
            for (int i = 0; i < fileTypeList.size(); i++) {
                fileTypeList.get(i);
            }
            long afterForLoop = System.currentTimeMillis();
            System.out.println("Time took in millis for for " + (afterForLoop - beforeForLoop));
    
            long beforeForeachLoop = System.currentTimeMillis();
            for (String s : fileTypeList) {
            }
    
            long afterForeachLoop = System.currentTimeMillis();
            System.out.println("Time took in millis for foreach " + (afterForeachLoop - beforeForeachLoop));
        }
    }
Empty loops and no warmup (at a minimum!) make for a somewhat suboptimal benchmark, to say the least. To be honest I'm surprised the JIT didn't eliminate the loops altogether.

If you want proper results you probably want to use the Java Microbenchmark Harness [0]. You'd probably want some actual data/work as well so the JIT doesn't overspecialize on the benchmark.

Edit: Halfheartedly tried to adapt the LinkedIn benchmark to JMH. Still not a great benchmark and I'm rusty so I wouldn't be surprised if I messed something up, but it's hopefully better the original:

    package org.sample;

    import org.openjdk.jmh.annotations.*;
    import org.openjdk.jmh.runner.Runner;
    import org.openjdk.jmh.runner.RunnerException;
    import org.openjdk.jmh.runner.options.Options;
    import org.openjdk.jmh.runner.options.OptionsBuilder;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.TimeUnit;

    @State(Scope.Thread)
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public class MyBenchmark {

        List<String> fileTypeList = new ArrayList<>() {{
            for (int i = 0; i < 1000000; i++) {
                this.add("fileType");
            }
        }};

        @Benchmark
        public void baseline() {
        }

        @Benchmark
        public int measureFor() {
            int result = 0;
            for (int i = 0; i < fileTypeList.size(); i++) {
                result += (int)fileTypeList.get(i).charAt(0);
            }
            return result;
        }

        @Benchmark
        public int measureForEach() {
            int result = 0;
            for (String s : fileTypeList) {
                result += (int)s.charAt(0);
            }
            return result;
        }

        public static void main(String[] args) throws RunnerException {
            Options opt = new OptionsBuilder()
                    .include(MyBenchmark.class.getSimpleName())
                    .build();

            new Runner(opt).run();
        }

    }
And the result summary (run on Ubuntu via WSL2):

    # JMH version: 1.37
    # VM version: JDK 21.0.10, OpenJDK 64-Bit Server VM, 21.0.10+7-Ubuntu-124.04
    # VM invoker: /usr/lib/jvm/java-21-openjdk-amd64/bin/java
    # VM options: <none>
    # Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable)
    # Warmup: 5 iterations, 10 s each
    # Measurement: 5 iterations, 10 s each
    # Timeout: 10 min per iteration
    # Threads: 1 thread, will synchronize iterations
    # Benchmark mode: Average time, time/op

    Result "org.sample.MyBenchmark.baseline":
      0.254 ±(99.9%) 0.022 ns/op [Average]
      (min, avg, max) = (0.247, 0.254, 0.262), stdev = 0.006
      CI (99.9%): [0.232, 0.276] (assumes normal distribution)

    Result "org.sample.MyBenchmark.measureFor":
      693178.390 ±(99.9%) 60793.583 ns/op [Average]
      (min, avg, max) = (676266.480, 693178.390, 718114.554), stdev = 15787.901
      CI (99.9%): [632384.806, 753971.973] (assumes normal distribution)

    Result "org.sample.MyBenchmark.measureForEach":
      693756.240 ±(99.9%) 7549.769 ns/op [Average]
      (min, avg, max) = (691685.231, 693756.240, 696573.323), stdev = 1960.651
      CI (99.9%): [686206.470, 701306.009] (assumes normal distribution)
Doesn't look like a significant difference to me, though obviously the benchmark quality leaves something to be desired. [0]: https://github.com/openjdk/jmh
18 hours agoaw1621107

for each is syntactic sugar for a while loop with an iterator. It will always be slower than the classic for index loop over the same collection/array.

18 hours agoZardoz84

> Day 1: Comparing/ checking equality against multiple Strings.

Just use Apache Commons Lang Strings.CS.equalsAny . If not, List.of or Set.of (if N could be big) should be the best options. Streams are better when you chain many operations.