I agree in theory. But in practice that specific caller's code bug was so widespread and Timsort broke so much existing code that it warranted offering a "-Djava.util.Arrays.useLegacyMergeSort=true" option.
The specific line from the Javadoc you're alluding to [0] is:
> The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y.
The problem is the second implied half of that statement: Pre-Timsort it was ", and if you don't, results might not be sorted in the correct order" while with Timsort it was ", and if you don't, you will get a RuntimeException."
It's way too easy to accidentally violate that condition: System.currentTimeMillis(), incorrect null handling, random numbers. Sometimes not even in the Comparator itself. The condition I posted, plus the other two:
> The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.
> Finally, the implementor must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.
Are just way too easy for someone to inadvertently violate to justify a RuntimeException when it occurs.
And then 3 years later we have [0] and 6 years after that we have [1]. I appreciate Masters of the Universe types like Bloch and Lea contributing wickedly-efficient code, but somehow it's always mere mortals who end up mopping things up after the fact. Whether it's a bug in the actual algorithm or a "Comparison method violates its general contract!" exception that happens once in a blue moon, I think putting TimSort in Java was a mistake.
Dynamic Ad Insertion wreaks havoc with this. Podcast eps can have different lengths and segments can have different start times depending on the ad profile of the listener.
And that's just at a single point in time: It's not uncommon for episodes to be re-edited and re-uploaded, or ads to be changed up (with different lengths) over time.
Overcast is an interesting case study on optimizing for listeners vs. creators.
The app developer, Marco Arment, is also co-host of Accidental Tech Podcast. One cool feature in Overcast is chapter markers: You can embed ID3v2 chapter frames in your RSS feed's MP3 files indicating when different segments start. This lets the listener jump between segments, it's a pretty slick experience.
Unsurprisingly, ATP uses this functionality. Advertising chapters are labelled as such, but the timecodes are always deliberately skewed so that skipping to the next chapter after an ad still gives you the last 15 seconds or so of the ad read.
I suppose this is a slightly better user experience than disabling the Skip Next button altogether on an ad segment, but it still irks me to be on the losing end of a conflict of interest.
...says the guy (me) complaining about a free podcast being played in a free podcast app.
> The identity "Me while I'm visiting nytimes.com" is distinct from the identity "Me while visiting cnn.com".
Trying to solve this through purely technical means is futile. If you block it at the user-agent, sites will share data at the back-end to create a super-profile.
Right now it's really convenient for advertisers to run an ad auction right in the user's web browser because all the context is there -- take that away and you'll see user data aggregated on the back-end instead.
Absent some type of regulation and enforcement, I really don't see how this puts a dent in the "reads a lot of articles on NY times about dogs, sees a lot of ads on cnn.com for dog food" profile aggregation.
Without knowing more about the "sophisticated anti-piracy system" employed by the app author, it's hard to determine if Google's claim of malicious behaviour is valid.
This could be something as simple as bytecode obfuscation, or something as complex as scraping every bit of personal information available through possibly-questionable means and sending to an insecure server. Copy protection schemes are notoriously user-hostile.
I agree 100%, perhaps I could have phrased that better. I try to use it as a teachable moment: "Hey, instead of using base64decode.org did you know you could use atob and btoa in a web inspector?"
Security-related scanners are a tough one though. Free XSS scanners, free TLS cert checkers: The best intentions can result in unintended disclosure. Developers have it constantly beaten into their head "Security! Security! Security!" and are often given nothing more than an OWASP cheat-sheet, so I can totally understand and empathize with the thought process that leads someone to plug a company URL into a free web-hosted XSS scanner.
Still too dangerous, and I don't trust new developers to make that determination. Once you get into the habit of pasting development details into random website textboxes hosted who-knows-where with who-knows-what ad networks, you're one keystroke away from leaking sensitive details that are correlated to your employer's IP range.
Or maybe I'm a crank and need to lighten up. That's why I'm asking.
I had a junior dev show me a neat site where you can paste in a Java thread dump and it performs an analysis. After explaining why it's a bad practice to send diagnostic details to an un-trusted third party I think he understood, but it seems like every week I'm finding people using ngrok, unauthorized password managers, grammarly, JWT parsers, Base64 encoders, and all manner of questionable tools.
I too wonder if I'm out of touch, if I'm tilting at windmills.
> Among other things, that resulted in us cooperating around monitoring potential hate sites on our network and notifying law enforcement when there was content that contained an indication of potential violence.
That indicates deep inspection of traffic going through CloudFlare.
The specific line from the Javadoc you're alluding to [0] is:
> The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y.
The problem is the second implied half of that statement: Pre-Timsort it was ", and if you don't, results might not be sorted in the correct order" while with Timsort it was ", and if you don't, you will get a RuntimeException."
It's way too easy to accidentally violate that condition: System.currentTimeMillis(), incorrect null handling, random numbers. Sometimes not even in the Comparator itself. The condition I posted, plus the other two:
> The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.
> Finally, the implementor must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.
Are just way too easy for someone to inadvertently violate to justify a RuntimeException when it occurs.
[0] https://docs.oracle.com/javase/7/docs/api/java/lang/Comparab...