18 years ago the industry was questioning the longevity of Java … and it’s still going strong

In the April 2002 edition of the Java Developer Journal (which at that time was a major monthly publication in the Java world), the magazine editor wrote a column titled “There may be trouble ahead”, questioning how long Java had left. Funny thing is, this really does seem to be a perpetual question that gets asked every few years, and yet here we are 18 years later after this article was written, and Java has been going strong for 25 years.

This year Oracle in their role as stewards for the language (after Oracle bought Sun Microsystems in 2010), celebrated Java’s 25th year with a #MovedByJava social media campaign, looking back and encouraging others to share their stories and experiences from using Java over the past 25 years.

Java Developer Journal April 2002 – page 5
Java Developer Journal April 2002 – page 98

This column really has some dire predictions for the time, notably this prediction:

… 5 years? Wow.

Admittedly, the threat at that time that Microsoft’s .NET and the C# language in particular was going to take over the world was real, although Java still lived on to dominate severside processing for many years.

It sounds like at this time, Mono, the open source framework the article refers to was still in development, but even now that’s come and been around for a number of years this threat really came to nothing:

Even as Microsoft themselves have developed their own cross platform runtime for .NET apps on Windows, MacOS and Linux (.NET Core) clearly cashing in on the interest in Mono and Java’s own cross platform support with JVMs for every platform, again… this threat has still come to not much.

At the time this article was written in 2002 Java J2SE 1.4 was just released, and 18 years later we’re getting new major releases every 6 months and Java 15 was just released in September 2020, there’s clearly life in a 25 year old language yet.

Organizational policy and culture can either enable or hinder desired outcomes

Let’s say you make a bold statement like “we need to encourage more innovation!” – that’s an inspirational goal and encourages your people to look for more effective solutions to problems, great! Let’s also say this organization has an established culture that can be described as “we must succeed at all costs, failure is not an option”. Ok, in some circumstances that would also make sense.

The trouble is, this already established culture does not support innovation at all, in fact it prevents any attempt to try something new that may or may not be a possible improvement. In order to innovate you have to accept that not every idea will be successful, that’s what innovation is all about. You pursue different ideas, some seemingly wild and improbable, but at some point out of experimentation you find ideas that are better, more effective, more efficient, than previous solutions. Not all ideas result in successful outcomes, in fact most will completely fail.

Sometimes it’s not enough to decide that you need to change your desired outcomes, you need to change your culture and policies that enable or support the outcomes you’re looking for. In fact, changing your culture so that it encourages the outcomes you’re looking for will often result in the desired outcome occurring by itself organically.

More FS2020 Scenery issues: New York (part 2)

Continuing from part 1, here’s more examples of fascinating glitches in the photogrammetry rendered scenery around New York and surrounding area.

Flying West from Floyd Bennet Field, here’s an unusual road traffic pattern at Gerritsen Inlet Bridge, Brooklyn, complete with some find of stone spire:

Continuing West to Coney Island, it looks like it’s been decimated by a hurricane. I love that the Ferris Wheel is rendered as a solid disk (to the right of the window opening):

Apparently it’s been so long that Coney Island has been closed under COVID-19 lockdown that the coaster has become overgrown with trees:

As a comparison with FSX, Coney Island has a modeled scenery object for the ferris wheel and the wooden coaster, but the rest of the amusement park is covered with autogen trees:

Back to FS 2020, the Steeplechase Pier is partially underwater, but odd that the end of the pier is actually rendered as a solid object:

Coney Island rail yard is also overgrown with trees:

Continuing towards the south edge of New Jersey port area, there’s some melty dock scenery, and docked ships are spouting some trees:

The Bayonne Bridge is looking a bit solid:

This whole dock area is full of some of my favorite scenery glitches in FS 2020 so far (I had a few screenshots in my earlier post), solid cranes – there’s plenty here:

Flying towards Newark Airport, Port Newark has plenty of cranes that are all rendered in the same solid style:

There’s also plenty of ships fully loaded with trees, and other pointy things:

The railyard along side the airport also has trains full of trees:

This area around New York is full of interesting scenery glitches, I’ll continue with another post shortly.

Using my Sudoku Solver to generate new puzzles (part 2)

Following on from Part 1, I’ve been looking at some alternative approaches to generating new Sudoku puzzles. It turns out that having a working and effective solver is essential in generating new puzzles, because you need to know if you’ve generated a valid puzzle, meaning a puzzle with only a single solution.

The generally accepted approach to creating new puzzles is to generate a completed grid and then remove values from cells, checking at each step that you still have a valid puzzle and then stop at a point where you’ve generated a puzzle with the required difficulty. Grading a puzzle ‘easy’ through ‘difficult’ is another topic unto itself, so I’ll come back to this later.

Here’s a summary of possible (but not exhaustive) approaches to generate a completed grid:

Brute force approach with backtracking

  • fill each cell with a random number
  • check puzzle is valid
  • if puzzle is not valid, go back to previous cell and try another random number

Although this approach would work, it’s obviously not the most efficient approach. Brute force algorithms usually take advantage of the speed of today’s CPUs to offset the inefficiency of trying every combination until you get what you’re looking for.

Running a solver against an empty grid

  • run solver against empty grid
  • ensure solver is picking a random candidate column from it’s exact cover matrix (see previous posts for how this is used by the solver)

This approach is interesting as it reuses the Solver, and instead of solving a puzzle with a limited number of givens, the puzzle has zero givens. My Solver uses the same approach with Knuth’s Algorithm X to ‘solve’ an empty grid, it doesn’t make much difference whether there’s a minimum of 17 givens for a valid puzzle or zero puzzle, it will still fill the grid.

The downside of my current Solver approach though is that it will always fill the grid with the same combination of numbers due to the way it always picks the next value based on the next unmet constraint with the least number of remaining possible candidates. While this approach sames significant time solving a valid puzzle, it does mean the approach has a predictable result and doesn’t produce random filled grids. This could be updated to add some randomness, but I think there’s an easier approach.

Run solver against a partially populated grid

  • Populate row 1 in the grid with a random combination of 1 through 9
  • Run the solver against this ‘seeded’ grid

Like the previous approach, this reuses the solver. However, by ‘seeding’ the first row with a random combination of 1 through 9, this does result in different grids being generated. Without any closer investigation however, due to the predictable results from my Solver, I think at best this probably means this approach will only generate 9! combinations (362880). While this is enough puzzles to keep you busy for a least a few weeks (!), there still has to be a better approach.

Conclusions

Since I already have a working solver, I’m going to use the ‘seeded’ partially populated grid approach, run my seeder against it, then remove a number of candidates, then run a ‘difficulty grader’ against it. I’ve been working on the ‘grader’ for a while now, I’ll post an update on the approach I’m taking with that in another post.