Binary Search: A new implementation that is up to 25% faster - <AUTHOR> https://github.com/scandum/binary_search <comment><USER2> The readme doesn't describe why it's faster. Looking at the code of the variant that is the fastest: [https://github.com/scandum/binary_search/blob/master/binary-...](https://github.com/scandum/binary_search/blob/master/binary- search.c#L201)

It seems like it's a quaternary search which seems like an arbitrary "magic number" of interior points. It's easy to understand what it does if you already know other variants like ternary search (cut search space into 3 to pick 2 interior points) or golden section search (same thing as ternary except in golden ratio). Here, quaternary search is just picking 3 interior points after dividing into 4 parts.

So the speed up is the same as how b-trees get their speedup: increase branching factor which costs more comparisons but reduces the depth. I might be wrong, but instead of quaternary it could also be 5-ary or 8-ary or any B-ary and any of these variants can also have the potential to perform better.

Just a tradeoff between: cost_of_divide * log_B(N) + cost_of_compare * (B - 1) * log_B(N)

EDIT: Thinking about it more, the divison doesn't seem like it should be the most expensive operation (especially relative to compares/branching). Anyone have any better ideas on why you would prefer more compares? Is it some pipelining thing?

<comment><USER3> Wider branching factors (3-ary, 4-ary, etc) are less efficient in the total number of comparisons, but give you more memory level parallelism, and large searches are dominated by memory access behavior and critical paths, not total comparisons or instruction throughput. So better MLP can make up for the inefficiency of higher arity searches... to a point.

E.g., with 4-ary search, your search tree is half the depth of binary search (effectively, you are doing two levels of binary search in one level), but you do 3x the number of comparisons, so 1.5x more in total.

However, the comparison (1 cycle) is very fast compared to the time to fetch the element from memory (5, ~12, ~40, ~200+ cycles for L1, L2, L3 and DRAM hit respectively). The 4-ary search can issue the 3 probes in parallel, and so if the total time is dominated by the memory access, you might expect it to be ~2x faster. In practice, things like branch mispredictions (if the search is branchy) complicate the picture.

<comment><USER4> Sounds right. I think the fastest solution (of this approach) would do something like: get the Lx-cache-row sized batch; check upper/lower end; depending on result: choose next batch by binary division, or do linear walk to find the match. Not sure if doing it precisely would be an improvement over the magic numbers in the example though.

Then again, I'd like to experiment with prefetch here as well. It may be possible to squeeze out even more performance.

<comment><USER3> I don't think the trick of checking each end of the cache line helps much, except perhaps at the very end of the search (where there are say low 100s of bytes left in the region).

When the region is large it just doesn't cut the search space down almost at all: it's a rounding error.

Now you might think it's basically free, but clogging up the OOOE structures with instructions can hurt MLP because fewer memory accesses fit in the window, even if the instructions always completely execute in the shadow of existing misses.

There is a similar trick with pages: you might try to favor not touching more pages than necessary, so it might be worth moving probe points slightly to avoid touching a new page. For example, if you just probed at bytes 0 and 8200, the middle is 4100, but that's a new 4k page (bytes 4096 thru 8191), so maybe you adjust it slightly to probe at 4090 since you already hit that page with your 0 probe.

Making all of these calculations dynamically is a bit annoying and maybe slow, so it's best if the whole search is unrolled so the probe points according to whatever rules can be calculated at compile time and embedded into the code.

Much more important than either of these things is avoiding overloading the cache sets. Some implementations have this habit of choosing their probe points such that only a very small number of sets in the L1, L2 are used so the caching behavior is terrible. Paul Khuong talks about this in detail on pvk.ca.

Doing a linear walk at the end definitely helps a bit though: SIMD is fastest for this part.

<comment><USER5> If you want to optimize a data structure for binary search, it sounds like it might be best to reorder the data itself in memory to make caching more effective.

For example the first access in a binary search will be the middle element, followed by the lower quartile or upper quartile. If you store all of those together in memory, a single cache line fetch can serve all those requests.

<comment><USER6> See user `fluffything`'s comment on this same thread: [https://news.ycombinator.com/item?id=23895629](https://news.ycombinator.com/item?id=23895629), describing this approach (Eytzinger layout).

</comment></comment></comment></comment></comment></comment><comment><USER7> I checked the plot against an old school project where I investigated binary search, and I got similar numbers for the "standard" binary search (std::lower_bound in my project): For N=1000,10000,100000 it took 713,925,1264 us (compare to the author's 750,960,1256 us).

In my project I didn't test "quaternary search", but instead the winner was the Eytzinger layout that others have discussed, with 570,808,1044 us (compare to author's quaternary search: 557,764,1009 us).

It would be interesting to try a 4-way Eytzinger layout.

My project report, if anyone's interested: [https://dl.strova.dk/ksb-manuel- rav-algorithm-engineering-20...](https://dl.strova.dk/ksb-manuel-rav- algorithm-engineering-20200317.pdf)

EDIT: I reuploaded the linked PDF since the first one I uploaded was missing the source code.

</comment><comment><USER8> Binary search can be implemented using conditional move instructions instead of branching. Given the branches are unpredictable, this yields a huge speedup. It can be implemented like this in pure C, if written in a way the compiler can recognize. In my experience this is the fastest binary search.

[1] [https://pvk.ca/Blog/2012/07/03/binary-search-star- eliminates...](https://pvk.ca/Blog/2012/07/03/binary-search-star-eliminates- star-branch-mispredictions/)

<comment><USER3> Actually cmov-based searches often (usually?) result in a slowdown unless non- obvious measures are taken.

A cmov-based search has the problem that the probes for each level are data- depedent on the prior level. So you cannot get any memory-level parallelism, because the address to probe at level n+1 isn't known until the comparison at level n completes.

Branchy search is at least right half the time (in the worst case) on the next direction, 25% of the time for 2 levels down, etc. So it gets about 1 additional useful access in parallel, on average in the worst case, compared to cmov search.

Except for very small searches which fit in the L1 cache, where misprediction cost dominate overall time, branchy is competitive and often faster.

Now you can take countermeasures to this problem with the cmov search. One is to increase the arity of the search as in the OP, another is explicit software prefetching, etc, which might put cmov back on top.

This has all been assuming the worst case of totally unpredictable branches. Real world searches might be expected to be less-than-random as some elements are hotter than others, etc. Any predictability of the branches helps out for branchy search.

<comment><USER8> As usual, it depends. I was doing binary search within btree nodes, which means small arrays that fit into the cache. Branchless search performed best there. Actually even the btree search itself was branchless (if nodes were in memory) until the end, as the pointer to the next node was just loaded via an index calculation and the loop continued with a binary search of the next node. I did a little software prefetching as well once I had the pointer to the next node.

<comment><USER3> Yes, tightly packed nodes or nodes which are all in L1 is one place where plain cmov can win.

The sweet spot is pretty small though, because it is not only squeezed from above by branchy which wins for less cached data, but also from below by linear vectorized search. You can't always apply vectorized search (e.g. if the keys are not contiguous), but when you can it can win up to dozens of elements.

When you throw the possibility of predictability on top, where branchy wins, that's why I usually reject unconditional statements that "cmov gives a huge speedup".

</comment></comment></comment></comment><comment><USER9> This is really cool!

About a decade ago I did research on sorting and searching, which was the same type of work going on here ([https://github.com/pbiggar/sorting-branches- caching](https://github.com/pbiggar/sorting-branches-caching)). I found it was extremely difficult to accurately say whether one algorithm is faster than another in the general case. I found a bunch of speed improvements that probably only apply in processors with very long pipelines (like the P4)).

Execution speed is probably the right metric here, but it makes it hard to understand _why_ it's faster.

PS. Looking at "boundless interpolated search" ([https://github.com/scandum/binary_search/blob/master/binary-...](https://github.com/scandum/binary_search/blob/master/binary- search.c#L234)), it seems it's missing a `++checks`. I initially thought this could be the cause of a misreporting it as being faster, but I see the benchmark is run-time based so that wouldn't cause it unless the incrementing itself is the bottleneck.

</comment><comment><USER10> It is nice to see benchmarks of elementary algorithms, but none of these is new. Benchmarking would be more convincing if more distributions were used. For example, we know that interpolated search is O(lglgn) for uniform distributions that are used here, but can be linear in pathological cases.

<comment><USER11> Exponentially distributed data is a great example of that. It's fun that the author picks 32-bit ints; I suspect that you just don't have enough dynamic range to really hobble interpolated search.

</comment></comment><comment><USER12> I've seen most real-world applications that use in-memory search, use balanced binary search trees. Are any of these improvements applicable to those data structures? AVL and Red-black trees come to mind.

<comment><USER13> AVL and Red-black trees are pretty terrible and can easily be improved upon by cache-friendlier data structures like for example B-trees.

</comment></comment><comment><USER14> On the topic of binary searches, I was wondering if they can be done without any branching so you can avoid branch misses and possibly parallelize it with SIMD instructions. I think I was able to get it with some optimizer flags and GCC built-ins.

[https://github.com/ehrmann/branchless-binary- search](https://github.com/ehrmann/branchless-binary-search)

<comment><USER3> Yes you can do it branch free, with only a single branch at the end (so your search actually terminates), but the benefits are not as obvious as you might thing per my other reply: [https://news.ycombinator.com/item?id=23894709](https://news.ycombinator.com/item?id=23894709)

<comment><USER14> You can avoid the branch at the end by computing your iteration count beforehand and using switch statement jump table where each case is a step in the search, and you iterate by falling through.

<comment><USER3> Yes, but this just swaps the terminating conditional branch for an indirect branch at the start, no?

In general my guideline is: for an algorithm which has variable input size, do you want to do a variable amount of work? If yes, you will have at least one branch, and this branch will be unpredictable with at least some distributions of unpredictable input sizes.

In this case I think you definitely want "variable work" because a search over four elements should be shorter than search over one million.

<comment><USER14> > Yes, but this just swaps the terminating conditional branch for an indirect > branch at the start, no?

Depends how you write it. The number of iterations is ceil(log2(n)). GCC's __builtin_clz essentially computes this, and it has support on most major architectures.

<comment><USER3> Yes, you can calculate the number of levels, but with a dynamic size that isn't going to let you avoid a branch. Say you calculate there are 10 levels in the search. What do you do now?

<comment><USER14> Do you consider a jump a branch? My impression was always the point of avoiding branches is so you don't have mispredictions, but that shouldn't be a problem for unconditional branches.

The other option is running all 32 (or 64) steps.

<comment><USER3> Perhaps I've been a bit loose in my language (and not everyone is consistent with branch vs jump). I really should have said something like "non-constant jump". That is, in my theorem (haha) above, I mean you cannot have non- constant work without at least one non-constant jump.

A non-constant jump is anything that can jump to at least 2 different locations in a data-dependent way. On x86, those would be something like [2]:

\- conditional jumps (jcc) aka branches

\- indirect calls

\- indirect jumps

Basically anything that either goes one of 2 ways based on a condition, or an indirect jump/call that can go to any of N locations.

Without one of those, you will execute the same series of instructions every time, so you can't do variable work [1].

So when you say "unconditional branches" I'm not sure if you are talking about _direct_ branches, which always go to the same place (these are usually called jumps), or _indirect branches_ , which (on x86) don't have an associated condition but can go anywhere since their target is taken from a register or memory location.

If you are talking about the former, I don't think you can implement your proposed strategy: you can't jump to the correct switch case with a fixed, direct branch. If you are talking about the latter (which I had assumed), you can – but it is subject to prediction and mispredicts in basically the same way as a conditional branch.

\---

[1] Here, "work" has a very specific meaning: instructions executed. There are meaningful ways you can do less work while executing the same instructions: e.g., you might have many fewer cache misses for smaller inputs. However, at some point the instructions executed will dominate.

[2] There are more obscure ways to get non-constant work, such as self- modifying code, but these cover 99% of the practical cases.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER15> If the data to be binary searched is static, that is, if it doesn't change, and if it fits entirely in RAM, then what I would do is as follows:

1) Pre-compute the first mid/center element, C1.

2) Move the data for this mid/center element to the first item in a new array.

3) Pre-compute the next two mid/center elements, that is, the ones between the start of the data and C1 (C2), and the one between C1 and the end of data (C3).

4) Move the data from C2 and C3 positions to the next positions in our array, the 2nd and 3rd position.

5) Keep repeating this pattern. For every iteration/split there are 2 times the amount of midpoints/data than the previous iteration. Order these linearly as the next items in our new array.

When you're done, two things will occur.

1) You will use a slightly different binary search algorithm.

That is because you _no longer need to compute a mid-point at every iteration_ , those are now _pre-computed_ in the ordered array.

2) Because the data is now ordered, it becomes possible to load the tip of that data into the CPU's L1, L2, and L3 cache. If let's say your binary search takes 16 iterations to complete, then you might get a good headstart of 5-8 iterations (or more, depending on cache size and data size) of that data being in cache RAM, which will make those iterations MUCH faster.

Also, (and this is just me), but if your program has appropriate permissions to temporarily shut off interrupts (x86 cli sti -- or OS API equivalent), then this search can be that much faster (well, depends on what the overhead for cli/sti and API calls are, but test, test, test! (also, always shut off the network and other threads when you're testing, as they can skewer the results!) <g>)

[https://en.wikipedia.org/wiki/Memory_hierarchy](https://en.wikipedia.org/wiki/Memory_hierarchy)

"Almost all programming can be viewed as an exercise in caching." \--Terje Mathisen

"Assume Nothing" \--Mike Abrash

Also, there is no such thing as the fastest binary search algorithm... there's always a better way to do them...

To paraphrase Bruce Lee:

 _" There are no mountain tops, there is only an endless series of plateaus, and you must ever seek to go beyond them..."_

<comment><USER15> Also, before I forget, if let's say english words were being stored, you could have an array of 1..26 pointers (representing letters 'A'..'Z') where each pointer points to one of 26 other similar arrays, representing the second character, etc. This pattern could repeat in memory. Would it be time/space efficient? Depends on the data. Also, this could be combined with the above. Maybe the first few letters of words are stored this way, and the rest are ordered such that a binary search can be performed, as above. Again, depends on data, storage, and speed requirements. Sure, you could use one or more hashing techniques, but then what's the speed/memory penalty, and what's the penalty for collisions? So, there are a lot of considerations to be made when selecting a technique for storing/searching data... there is no one-size fits all technique, as I said above, there's always a better way to do things...

<comment><USER16> You search the strings wordwide then, by 8 not by 1. You just need to represent the strings little or big endian, and construct the nested switches offline. About 20x faster than linear search via memcmp. [http://blogs.perl.org/users/rurban/2014/08/perfect-hashes- an...](http://blogs.perl.org/users/rurban/2014/08/perfect-hashes-and-faster- than-memcmp.html)</comment></comment></comment>


What GDPR means for your app or side project - <AUTHOR> https://stackshare.io/posts/what-gdpr-means-for-side-projects <comment><USER2> This article is very reassuring for me to read, as I own several side projects that store user accounts and send emails! Thank you so much!

</comment><comment><USER3> It's rather saddening to see it claimed that no engineers know how to read Pascal any more, given that Pascal was designed in part as a teaching language, that people should be able to learn.

</comment><comment><USER4> I got some small apps and side projects and honestly, i dont give a crap. Good luck hunting all these little websites.

</comment><comment><USER2> " You do need to have a privacy policy that discloses what data you're collecting, how you'll use that data, and provide someone signing up to your service with a means to consent to data collection. It can just be a checkbox "

</comment><comment><USER5> Great article

</comment><comment><USER6> Interesting contrast to all of the "doomsday" posts about side projects not being viable for fear of getting fined.</comment>


Is It Necessary For A-Listers to Get First Dibs? - <AUTHOR> http://shegeeks.net/is-it-necessary-for-a-listers-to-get-first-dibs/

<comment><USER2> I tried to follow the article but I just couldn't. I don't understand it at all.</comment>


Center of the universe - <AUTHOR> http://www.orangecoast.com/features/2013/09/23/center-of-the-universe <comment><USER2> Oh oh! I remember this technique from Cialdini's _Influence_. During the Korean war, the Chinese used the same technique on American POWs:

 _For instance, prisoners were frequently asked to make statements so mildly anti-American or pro-Communist as to seem inconsequential ("The United States is not perfect." "In a Communist country, unemployment is not a problem."). But once these minor requests were complied with, the men found themselves pushed to submit to related yet more substantive requests. A man who had just agreed with his Chinese interrogator that the United States is not perfect might then be asked to indicate some of the ways in which he thought this was the case. Once he had so explained himself, he might be asked to make a list of these "problems with America" and to sign his name to it. Later he might be asked to read his list in a discussion group with other prisoners. "After all, it's what you really believe, isn't it?" Still later he might be asked to write an essay expanding on his list and discussing these problems in greater detail._

<comment><AUTHOR> In retrospect, I'm pretty convinced he was going to try to get me to undress myself at his escalating suggestion w/out him ever touching me. He was extremely careful about not touching, "accidentally" brushing, etc, and keeping out of my personal space. I realize now that this was a survival mechanism for him, as if the spell were broken by some wrong move, he really could have gotten hurt badly in this sort of situation.

<comment><USER3> Some people seem to have an almost super-human level of charisma/ability to influence others (there is probably a D&D reference to be made here).

Certainly the trope is common in fiction. See: The Mentalist (both the protagonist and antagonist share this ability) and several Agatha Christie novels with similar storylines.

This guy sounds like a real-life Red John; able to subtly re-wire people's thinking so that they actually want to do what he suggests.

I have only ever experienced this in the formulaic pattern of dark-arts sales tactics. Israeli companies selling cosmetic products from the Dead Sea are notorious for making a superficial connection with their potential customers and then exploiting that connection for a sale. But those tactics aren't hard to see through and resist. Quite scary to think that someone who has mastered those techniques could actually alter my preferences simply with the power of suggestion.

<comment><USER4> I complety fell for one of those Israeli cosmetics things in the mall in my early 20's. My dad was in sales so I am accustomed to all the techniques of persuasion. But for some reason that day I bought $20 or so worth of skin care products I had no intention of using. When I got to my car, I was like, "what on EARTH just happened?!" I have never allowed myself to be so manipulated before or since. Creepy to think of those same techniques being applied to nefarious ends.

<comment><USER3> Tricking you into buying junk you don't need qualifies as a nefarious end in my book. But you're right; serial killers rarely have a cooling-off period or returns policy.

</comment></comment></comment></comment></comment><comment><USER5> I was impressed by the fact checking:

[http://www.orangecoast.com/webexclusives/2013/09/24/a-factch...](http://www.orangecoast.com/webexclusives/2013/09/24/a-factcheckers- journey-to-a-1980-afternoon)

<comment><USER6> I was as well, I'm glad they shared the process that they went through.

</comment></comment><comment><USER7> That's moderately horrifying. It's also a sad reminder - so many of us go through life having to chisel and scrape that kind of affection out of the world. I can see how having it freely given could be very enticing.

<comment><USER8> Parents of young children: the time to inoculate your children against this tool of sociopaths is _now_. Communicate your love with every word and embrace, and you'll fill a reservoir that will never go dry.

</comment></comment><comment><USER9> More facts: [https://en.wikipedia.org/wiki/Randy_Steven_Kraft](https://en.wikipedia.org/wiki/Randy_Steven_Kraft)

<comment><USER7> Jesus, it just goes on and on and on... and in the end, there's no heroic manhunt, no great victory. He was caught driving drunk with a corpse in the passenger seat, so used to murder that he'd gotten lazy about it.

You can't help but feel outrage that nobody stopped him... that the public wasn't sufficiently warned that any of these _boys_ , these _kids_ could have known there was a serial-killer stalking them.

<comment><USER10> Reading about Jeffrey Dahmer left me similarly shaken. One of his victims -- Konerak Sinthasomphone -- managed to escape out onto the street and contact some women who called the police.

When the police officers (John Balcerzak and Joseph Gabrish) arrived, Dahmer managed to convince the them that it was a gay lovers' quarrel and the officers let Dahmer take Sinthasomphone home again.

Can you imagine the horror of escaping torment and certain death, only to be handed right back to your tormenter by the police?

<comment><USER11> Holy shit. This victim, who 31 year old Dahmer claimed was his lover, was also _14 years old_ at the time, and the police returned him (naked and bleeding) despite his protests. (Sinthasomphone was disoriented at the time, having been drugged, but apparently still did protest.) At least the officer was fired: [https://en.wikipedia.org/wiki/John_Balcerzak](https://en.wikipedia.org/wiki/John_Balcerzak)

<comment><USER12> He was reinstated apparently upon appeal.

<comment><USER13> How is that even possible after such misconduct? Words fail me. Don't they even feel ashamed of appealing ?

</comment></comment></comment></comment></comment></comment><comment><USER14> Gives a different meaning to "Hacker News". But seriously: a very engaging, honest story.

<comment><USER15> psychopaths are pretty good social hackers :) to them a person is just a machine they have to act the right way towards to get some benefit

</comment></comment><comment><USER16> I'm not sure if this anything to do with why this is on HN but Jay Roberts is Jason Roberts's brother (Jason Roberts is co-host of the TechZing podcast).

</comment><comment><USER17> If any of your would like to read more about "underrated" serial killers after this harrowing story, Albert Fish comes to mind. Even just the wikipedia article is about as scary a horror tale as they come. Many friends have been unable to finish reading: [http://en.m.wikipedia.org/wiki/Albert_Fish](http://en.m.wikipedia.org/wiki/Albert_Fish)

<comment><USER18> Popular Crime by sabremetrician Bill James has a good chapter on Fish, plus some other American serial killers.

</comment></comment><comment><USER19> This story is for great (non-blockbuster) movie. Almodovar, but with good ending :-)

But it's interesting to think why is author still alive. Is killer possessive gay that is willing to kill guys that are ignoring/rejecting him? Because author didn't reject him as many others that are now in the grave?

Also, even if author is wrong, really interesting and non-intrusive emotional overview.

</comment><comment><USER20> I know there's a policy to keep the title of the source article, but if admins are going to blindly change post titles to remove all useful context and revert to meaningless, misleading headlines, can't they at least come up with a prefix for it? There's Ask HN, Show HN... in this case "Distract HN" might have been appropriate.

</comment><comment><USER21> Not sure if I'm excited that the first time I've seen an alum from my college (Claremont McKenna) at the top of Hacker News it is Randy Kraft...

</comment><comment><USER22> whoa, I used to work with Jay about 10 years ago. Small world.

<comment><AUTHOR> Hi Rob, hope all is well. I don't think any of us will ever forget those Adrenaline days.

</comment></comment><comment><USER23> Creepy and fascinating story. Thanks for sharing.

I do have two questions, though:

1\. Polaroid wasn't making a black and white integral film in 1980, and FujiFilm didn't make instant film until 1981. Kodak's instant film was color. So how did Kraft produce an instant B+W image?

2\. Did you really drink 2-3 beers and then get on a motorbike?

<comment><AUTHOR> 1) I really don't know. Maybe he had a stockpile? Maybe it really was color, but the room was somewhat dark/shaded, and I'm only remembering/assuming it as B&W?

2) We used to do a lot, lot, lot worse than that in the USMC in those pre-MADD days. Different era.

Fun fact - same motorcycle, I was struck by lightning on it several months later, riding home from California (to Ga) on I-70 in Missouri. This was following my discharge (actually, end of active service) in late August.

</comment></comment><comment><USER24> This'll get turned into a multi series drama on HBO.

</comment><comment><USER25> Somebody should extend this article: [http://en.wikipedia.org/wiki/Superficial_charm#Psychopathic_...](http://en.wikipedia.org/wiki/Superficial_charm#Psychopathic_charm)

</comment><comment><USER26> WOW! That's some powerful stuff! Lots to think about in the mind of a serial killing monster. This is a great premise for a indie drama.

</comment><comment><USER27> Isn't Randy Kraft still alive? I imagine the author has decided not to actually try to arrange some type of conversation with him?

<comment><USER28> In the comments under the article someone asks him whether he's contacted Kraft. He has by mail but got no response.

</comment></comment><comment><USER29> It's the Earth.

</comment><comment><USER30> Once again, some admin has changed the title from better to worse---it was "How I met a serial killer when I was a marine", which is considerably more descriptive.

<comment><USER31> Considering there is frequently space-related articles here, it is particularly misleading.

<comment><USER32> I have to concur. I clicked on this article wondering if there was some sort of new discovery in astronomy. Still an interesting read, but the old headline was much more appropriate.</comment></comment></comment>


Moto X 'always listening' phone launched by Google's Motorola - <AUTHOR> http://www.bbc.co.uk/news/technology-23536936

<comment><USER2> All 'smart' phones are always listening and watching.

Unless you take the battery out assume you are being monitored.

</comment><comment><AUTHOR> What could go wrong...</comment>


Mistakes startups make (and you should avoid) - <AUTHOR> http://alexblom.com/blog/2011/01/mistakes-startups-make-and-you-should-avoid/ <comment><USER2> [http://swombat.com/2011/1/20/how-to-write-good-startup- advic...](http://swombat.com/2011/1/20/how-to-write-good-startup-advice- articles)

 _> When writing a startup article, be very careful not to extrapolate from one experience that happened to you to a general rule for startup. "X startup mistakes" or "Y startup tips" are basically collections of generalisations based on personal experiences. Some of your points may even be correct by sheer luck, but the short-form nature of a list of tips means that even those don't have the necessary context to be really useful._

Please pick each of your points in this blog post, and give it its own article, and provide the context within which it applies, and how to action it effectively. Then you'll have a great series of articles that make a difference...</comment>


No One Is Self-Made – What Fatherhood Taught Me About the American Dream - <AUTHOR> http://mattmireles.com/two-americas/

<comment><USER2> This is also what I observed when I compared my life with my younger brother's life.

While growing up, I was surrounded by a peer group of high achievers. I had a generally stable home environment and my reading, math and writing abilities were better than class average.

My younger brother on the other hand never had that peer group. His best friends were bullies and destined to be jocks. He was never into reading, math and writing. This shows in his grades.

What really helped my brother not get sucked into the usual teen bullshit is a good home environment and constant reminder that other kids are not necessarily doing the right thing.

Peer group and family background are pretty much the strongest indicators of future success in life. Also, they are a great indicator of a potential mate. I pretty much use this as a yardstick while dating these days.

<comment><USER3> You had me until you said, _" Also, they are a great indicator of a potential mate. I pretty much use this as a yardstick while dating these days."_

Compare to a key point in the article: _Over the last 40 years, college- educated, rich Americans have clustered together, enjoying all manner of positive network effects much like the ones I just described. Americans without college degrees are living together too, suffering from the same sort of network effects, except in reverse: crime, drug use, low expectations and bad schools._

So by rejecting potential mates who are not so lucky as you, and even encouraging others to do the same, you are furthering the clustering of the lucky and the unlucky, furthering the gap in inequality, adding to the tragic Mathew Effect the defines our world.

<comment><USER4> > So by rejecting potential mates who are not so lucky as you, and even > encouraging others to do the same, you are furthering the clustering of the > lucky and the unlucky, furthering the gap in inequality, adding to the > tragic Mathew Effect the defines our world.

You're proposing we ought to 'take one for the team' and date people who we have nothing in common with and don't necessarily respect (in as much as their life hasn't led them to be as high achieving as them) ?

<comment><USER3> No, I'm saying look beyond the "indicators" and "peer groups", and look at the individual person.

I personally would have far more respect for someone who bucked the odds and fought for everything she had than for someone who is "high achieving" but got there relatively easily on a path well paved (if not paved with gold).

I also find that people who made it through a hard early life tend to be less spoiled and selfish, to be more sympathetic to the plights of others, and to have a greater capacity for love and trust, and to know what's really important in life.

</comment></comment></comment></comment><comment><USER5> Parenting is a huge job, you have to give this new person everything they need to survive life. This is pretty much all inclusive from tutoring, personal growth, overcoming issues, being successful in relationships, creating the scenarios their first accomplishments come under they feel are their own but really you set them up to be successful and gave them something that they could really chew on successfully setting them up for their next success, and their next success and so on.

</comment><comment><USER6> The graph demonstrating the different levels in education was interesting. At first I thought there most be some mistake, because one field was high school education or less and the other was college education or more, but the two lines didn't add up to 100%. I realized that the cause for this is people who started college but did not graduate. Because the bachelors degree or greater line stayed the same this must mean that less people have started college. I'm not entirely convinced that this is the case.</comment>


Why Does 8chan Exist at All? - <AUTHOR> https://medium.com/@DaleBeran/why-does-8chan-exist-at-all-33a8942dbeb2 <comment><USER2> It's not a convincing argument to say a society shouldn't fight unwanted behavior unless it can be completely eradicated. That's akin to saying there's no point advertising a product unless it results in 100% of the public buying it. If 80% of 8chan users "just go elsewhere" that could literally save a few lives.</comment>


A social annotating website? - <AUTHOR> https://annot.io/github.com/facebook/react <comment><USER2> I'm not sure about its identity but think that it's helpful to see annotated json file e.g. configuration [https://annot.io/github.com/mattermost/platform/blob/master/...](https://annot.io/github.com/mattermost/platform/blob/master/config/config.json)

</comment><comment><USER3> Because it is an interesting project, this submission would probably be better if the like were to the Annot.io homepage: [https://annot.io/](https://annot.io/)</comment>


How to fix URL-shorteners - <AUTHOR> http://www.scripting.com/stories/2009/08/19/howToFixUrlshorteners.html

<comment><USER2> "3. Twitter could and should obviate the need for URL-shorteners. Yes I know SMS messages are limited to 160 chars. So shorten the URLs at the SMS gateway and leave them long for communication over pathways that are not so limited. Any engineer could see this obvious solution."

Yep. Why should Twitter's implementation over SMS compromise the user experience of users not using SMS?</comment>


Java Doesn't Suck - <AUTHOR> http://www.jamesward.com/2014/12/03/java-doesnt-suck-youre-just-using-it-wrong <comment><USER2> > It would have been much better to utilize environment variables so the only > thing that changed between environments was those variables.

I strongly prefer commandline arguments to environment variables: They're more transparent, easier to reason about ("what's running on this server? `ps`... oh, that process there is running in the staging configuration instead of production"), and it saves useless sudos (/proc/<pid>/environ has mod bits 0400, so if the processes you're investigating are running as separate users (and they probably should be), you can't inspect the actual environment that the process has, so you end up sudo'ing to check the environment out when you should have all the information you need in the process list).

If the environment variables are just interpolated into the run script by the deploy and then all passed to the process as arguments, that works too.

<comment><USER3> On the other hand, environment variables are useful for things you specifically don't want showing up in ps. If you've got to supply credentials (passwords, tokens, certificates, etc) or anything else that requires a modicum of security, it's much better to pass those in as environment variables rather than command line arguments.

<comment><USER2> Please keep in mind this point called out by wereHamster elsewhere ( [https://news.ycombinator.com/item?id=8695887](https://news.ycombinator.com/item?id=8695887) ):

> env variables are inherited by children, which may be relevant if the app > forks

If your app forks (or any of the multitude of libraries that it may depend on, check and _pin_ your sources (so they don't add un-audited behaviors)), whatever process it execs probably will get a copy of the environment of your process.

Yes, it's possible to clean the environment between the fork and the exec/execve. Do all / most frameworks do so or make it easy to do so? I'm not sure, but would check before making any assumptions about it.

I was about to suggest that sensitive information like credentials would better be kept in files that are referred to by name in command line arguments, but... unprivileged users cannot fork/exec a process as a different user, so children could read all the same files as the parent.

I can hardly believe it, but a plug for my masters work [0] is actually relevant here. I was interested at the time in the intersection of HCI and security, so I made up this thing called sub-identities that let unprivileged unix users create sub-users. It's a really watered-down version of some actual research that's been around for a while, but the point was, it was easy(ish) for the average unix user to use. I don't pretend that it was anything but a toy, though.

All that said, it seems that passing sensitive information in environment variables, squirreling them away in the process space somewhere, then cleaning the environment (all right away, during initialization) would be a smart thing to do.

 _edit: see `man 3 unsetenv` for how to do this_

[0] [http://ccl.cse.nd.edu/research/pubs/snowberger- thesis.pdf](http://ccl.cse.nd.edu/research/pubs/snowberger-thesis.pdf)

<comment><USER4> > _" Yes, it's possible to clean the environment between the fork and the > exec/execve. Do all / most frameworks do so or make it easy to do so? I'm > not sure, but would check before making any assumptions about it."_

It might be better to wipe the contents of the environmental variable immediately after reading the value in it (presumably done at startup, or close to it).

</comment></comment></comment></comment><comment><USER5> TL;DR: Java as a language is not bad. The problem with Java is its bloatware ecosystem. Endemic to the Java world are uninstallability, Rube Goldberg machine code, and such heights of over-engineering that they're easily parodied:

[https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...](https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition)

I think the over-engineering is an unintended side effect of Java's most attractive features: incredibly stable standard ABIs, portable byte code, fantastic tooling, and a language that makes byzantine abstractions relatively easy to implement without the instability you get in C++ or the unmaintainability you get in dynamic languages. Sometimes you actually do need very high level complex abstractions, so this makes Java a fantastic language for those cases. But those cases are rare. Java makes it easy to build towers of babel that stand up, so they happen.

Java can be fine if you exercise discipline around complexity. Java coders need YAGNI and KISS tattooed on their inner eyelids more than coders in other languages.

<comment><USER6> Anything can be parodied by exaggeration. One could provide a github parodying any language:

C: pointers-to-pointers-to-functions, type puns, and quasi-opaque "types" with really_long_identifiers_t everywhere (among many other possibilities, and bonus points for numerous reimplementations of basic data structures tailored specifically for different types without significant performance gains)

C++: see Java, but in C++ form; or alternatively larded with metatemplate programming

perl: write any valid perl, because it parodies itself

python: mishmash classes, functions-as-stateful-objects, and n-levels of decorators everywhere, and toss in some metaclass programming for giggles

And so on.

(Note: my favorite language to program in is currently C++, and I'm well aware of the less desirable traits of the language and codebases that exist.)

<comment><USER7> The difference is that with Java, the tools available allow creating immense complexity very easily - and due to how that complexity manifests itself as the complexity of the entire application, each individual piece still looks simple. A parody Java application resembles a real one more than the others you mention, which are more in the "clearly obfuscated" category.

<comment><USER8> So what you're saying is that the tooling for Java is more advanced than the tooling for other languages. I'm not sure I see this as a negative. I did node dev for a while, it was horrible, no tools that were any good, got a memory leak? Have fun!

Had a memory leak happen in Java once, had the proper tools already, didn't have to interrupt a live server or anything, plus the tools were easy to use and well documented.

Really the problem is that when you program in Java, you need to restrain yourself. You could create another level of abstraction, or you could just solve the problem at hand and abstract it later when you find a concrete case for it. And guess what, when you get there, you've got excellent tools for it.

</comment></comment></comment></comment><comment><USER9> My company is doing most of these things (except it's more complex because we're polylingual, and don't use Java for web apps), but Java still sucks.

The reason it sucks has more to do with the language and the culture that has grown up around it, than the mechanics of building and deploying that this article talks about. These mechanics have to be solved for most languages. They're table stakes; mostly just a basic level of usability from which you can start to measure against other things.

If I had to name the single worst thing about Java, it would be the tendency for business code to degenerate into a 1:1:1 ratio of interface:class:public- method. For any significant piece of logic, it ends up living in a class on its own, with its dependencies injected either via constructor parameters or method parameters. Whether the constructor or method is used doesn't really matter, unless the method is to be called many times, in which case the constructor acts as a kind of partial application. And of course the class it lives in needs to be the only implementation of a corresponding interface, which only has a single method, the method in question. All other interesting methods this method calls must in turn be called via single-method interfaces, with these interfaces injected via parameters, one way or another.

The cause of this is a religion around a particular style of testing. The development driven by the need to create tests for everything leads to code that has very little cohesion, very little structure, and most closely resembles 80s procedural code, but with vastly more ceremony. Code is hard to browse and read because the link between method call and implementation is hidden in a runtime indirection via an interface reference. This lack of legibility in turn encourages doing more work in these methods (albeit broken out into private methods), and instead of an OO decomposition of the problem, you end up with a poorly factored procedural decomposition.

The biggest symptom is classes with names that are close anagrams of their primary method. For example: StaleJobsCleaner.cleanStaleJobs, StaleJobsFinder.findStaleJobs, JobDeleter.deleteJob, JobDepedencyFinder.findJobDependencies, etc.

<comment><USER10> _If I had to name the single worst thing about Java, it would be the tendency for business code to degenerate into a 1:1:1 ratio of interface:class:public- method._

I agree. It's ugly and hard to maintain. Most enterprise Java usages of "design patterns" are unnecessary cruft. This is where I step back and say, "what you really want is a function".

The argument I tend to make for functional programming is that it only has two design patterns: noun (immutable data) and verb (referentially transparent function). And even though it's very rare that pure functional programming is used, mutable references (e.g. TVars for STM, reference cells like IORefs) are just "noun-plus" and _actions_ (e.g. m a for some monad m) are just "verb- plus". It's easier (read: possible) to reason about the complex stuff if the simple stuff is done on a sound foundation.

<comment><USER11> Even object-oriented programming is made better by importing functional concepts. Python's take with "classes are simply functions that return objects" is much cleaner conceptually than the "everything is an object and objects do everything" pattern.

</comment></comment></comment><comment><USER12> I'm confused about the title of this. I've never heard an argument that went "Java sucks because you are forced to (thing on this list)".

It's always been "Java sucks because it lacks (thing it certainly lacks)" or "Java sucks because it forces you to (thing it certainly forces you to do)", or, closest to this article, "Java sucks because it encourages you to (bad practice, such as those mentioned in this article)". None of these does the article refute.

I've seen places that used Java, and had most of these, and places that used Java and had little of it. I've seen places that used other languages that had all of these, and other places that used those same other languages that had none of it. This seems kind of orthogonal, and as such a bit of a strawman; is it in response to some specific arguments I've just not heard?

</comment><comment><USER13> Java doesn't suck, not at all. I still find it to be the most productive language for developing systems big and small, mostly because it's well- understood, the pitfalls and traps are well-known, and the community is extensive and supportive, for the most part.

Java got a bad rep because in the late 90's, enterprises hired anyone who had the word "Java" on their resume, with no real assessment of their actual proficiency in the language or programming skills. As a result, there was probably more bad code written in Java than any other language in history (including VB- you just can't write as much bad code in VB as you can in Java if you really (don't) know what you're doing).

Much of this bad code ended up running flaky enterprise systems. So much bad code ended up in closed-source products (like Websphere, and like many JDBC drivers) that were sold to people who didn't really understand technology (but knew Java was sexy!) that Java itself got a bad name.

No, the language isn't perfect. But with all the lessons learned, and with the great developments in Java since Oracle took over (I cannot believe I wrote and believe that now), I contend it's perhaps the single best language for general purpose software in 2014.

The things James talks about in this article are all big problems that have less to do with the language than with the poor development practices that became so endemic to the community as a result of the rush to hire anyone with a pulse to be a Java programmer 15 years ago.

<comment><USER14> List<String> list = new ArrayList<String>()

Please make me type more redundant words.

<comment><USER15> It's a bit better since JDK1.7 introduced a modicum of type inference:

      List<String> list = new ArrayList<>()

</comment></comment></comment><comment><USER16> It's hard to imagine someone who wouldn't be turned off by the tone of this article. Kicker is the quote at the end: "If you are in a typical enterprise then maybe you are lucky and already doing most of this." I went looking for sarcasm twice and still couldn't find it.

Java enterprise shops are not using git and JRebel and Play Framework and continuous deployments and 2 week sprints and reactive development refactoring boilerplate into lambdas.

Nor are they "mocking" amazon web services for ease of local developer testing. And a request to your boss to write the next services layer in "Kotlin" is likely to be met with the slap it deserves.

<comment><USER17> The following companies are Java shops (i.e. they use it for all/most/huge or very large part of their coding effort): Google, Amazon, IBM, Oracle, Twitter, Netflix, NASA, LinkedIn, Boeing, Raytheon, Twilio, Box and the list goes on and on and on. In fact, you'll be hard pressed to find companies working on large scale projects that _don 't_ use Java in any way (Microsoft, GitHub and Stack Exchange are notable examples -- there aren't too many more). Even Facebook, which isn't a Java shop, uses Java quite a lot for their analytics.

Pretty much all air-traffic control and defense systems in the Western world are written in Java (those of them written in recent years). In fact, every piece of software you really rely on (probably without even knowing it), there's a very good chance it's written in Java. Hell, there's even embedded avionics software written in Java nowadays[1]. So you'll be surprised what many different kinds of tooling -- both modern, super-modern and less so -- is being used in Java shops. Some use hard realtime GCs, some use really advanced model checking (NASA has built an awesome Java model checker), and yeah, many use Git. And even if many of them don't -- the work they do is so important, that I could really care less whether their SCM is hip or not.

[1]: [http://www.atego.com/products/atego- perc/](http://www.atego.com/products/atego-perc/)

<comment><USER18> Twitter and LinkedIn are Scala shops, not Java shops.

<comment><USER19> I worked on a large Java application at LinkedIn so in my experience, LinkedIn is certainly not Scala-only.

</comment></comment></comment></comment><comment><USER20> The problem is not necessarily with Java or the JVM as a technology, but rather the "Java shop culture"[1] that often goes along with it. Although I would call it "Enterprise shop culture" instead, since it seems to stem from people who (sometimes unknowingly) perpetuate big company politics and a consultant attitude, even in startups.

I've found "Java shop culture" in non-Java places as well--C#/.NET for example.

1\. [http://michaelochurch.wordpress.com/2012/04/13/java-shop- pol...](http://michaelochurch.wordpress.com/2012/04/13/java-shop-politics/)

<comment><USER21> Yup.

Java as a runtime is a really nice piece of technology, Java as a language is pretty good, if a bit dry.

It is the heavy-weight anti-YAGNI ecosystems that grow around it (the AbstractFactoryFactoryManager APIs that these Java shop cultures tend to produce) that makes working with Java suck, in my experience.

And yes, that stuff can be avoided if you aren't stuck working on a maintenance project and you are really careful to smash down any signs of that sort of culture growing when you see it.

</comment></comment><comment><USER22> > The blocking model limits parallelism, horizontal scalability, and the > number of concurrent push connections.

[citation needed]

Seriously, where are the benchmarks? I see lots of claims of threads being slow and heavy (see also every time green threads comes up), yet... they are not. And every benchmark I've seen shows that, _gasp_ , kernals are really fucking good. And library-of-the-week's greenthread kernel is not.

The author then says you should use NIO. But, well, NIO is slower than blocking IO. A _lot_ slower: [http://www.mailinator.com/tymaPaulMultithreaded.pdf](http://www.mailinator.com/tymaPaulMultithreaded.pdf)

So if you're using NIO instead of blocking IO threads, well, say goodbye to 25-30% of your throughput. But at least you got to feel all clever using unnecessarily complex async programming, so that's worth it, right?

<comment><USER23> Each thread has a minimum stack size which can grow memory quickly if you're using 10k's of threads. Using an async framework like Netty gets you into 100k connections and beyond. (Not that it's always the right thing to do unless you have lots of long-lived requests)

<comment><USER22> Like all virtual memory the stack isn't actually allocated until it's used.

So, no, that doesn't grow memory quickly. And while it's great Netty will get you to 100k connections, you can totally have 100k real threads on Linux. In fact, as far back as 2.5 in 2003 starting & stopping 100,000 concurrent threads took just 2 seconds with the introduction of NPTL. CPUs & memory have gotten a smidge faster since the Pentium 4 days so that time has almost certainly dropped significantly.

<comment><USER23> But the stack _will_ be used for each request, especially in Java app servers where stacks are often dozens of frames deep. The lowest stack size I could get away with for Tomcat 6/JDK 1.6 was 128 KB.

Sure, you could do better with a lightweight C/C++ solution.

</comment></comment></comment></comment><comment><USER24> Why not, you have started it.)

Before down-voting and replying, please, copy and paste examples from the Rosetta Code website, which would prove my statements to be incorrect.

1\. Syntactic noise. 2\. Verbosity. These gives us lots of cryptic lines of code, full of design patterns and other kluges. This is also related to the two below: 3\. Over-abstraction. 4\. Everything must be a member of a class. These two are simple and straightforward. These few pages long stack traces is a result of these unnecessary method calls. 5\. Static typing makes our code safe. This nonsense results in even more lines of cryptic code ("generics") and even longer stack traces.

I am not talking about XML configs, over-"engineered" components (beans, servlets, etc.)

Here is a lemma: Any algorithm (at least those represented on the Rosetta Code website) could be coded with less lines of code, _less words per line_ , less "special symbols" (with much better readability) and executed with less memory waste (this one excluding scripting languages for obvious reasons) _in any other mainstream language_. Period.

Sure, Java does not suck. It is stupid us, who are unable to "get it".

<comment><USER4> Not that I typically defend Java, but I think that (going by your Rosetta Code algorithm comparison test) Java fairs well against a few mainstream languages:

Rosetta Code's Java Quicksort: [http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Jav...](http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Java)

Not great, that first line is a wreck in particular, but not terrible either.

Compare that to this though: [http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#C.2...](http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#C.2B.2B)

Really quite ugly looking code.

Now, this isn't entirely fair; one of C++'s faults/benefits is that depending on your shop and/or framework/libraries, "idiomatic" C++ can vary greatly. Template heavy C++ tends to look like vomit. C++ that uses Boost will typically be more unpleasant to look at than C++ that uses Qt (imho anyway).

Java really comes into it's own horrible self when you get beyond mere algorithm implementation. A quicksort method in Java will tend to be relatively fine, but for projects larger than that it becomes idiomatic to make your java code a real mess.

<comment><USER25> Quicksort looks significantly better in a functional style. Here's some Haskell, but it certainly doesn't use any Haskell-exclusive features:

        quicksort :: Ord a => [a] -> [a]
        quicksort []     = []
        quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
            where
                lesser  = filter (< p) xs
                greater = filter (>= p) xs

<comment><USER26> When is quicksort not quicksort? When it's not in-place: [http://augustss.blogspot.com/2007/08/quicksort-in-haskell- qu...](http://augustss.blogspot.com/2007/08/quicksort-in-haskell-quicksort- is.html)

I love me some Haskell, but this particular example is kind of a bait-and- switch.

</comment></comment></comment></comment><comment><USER27> I maintain 2 semi-big Play 2 web services (written in Java, not Scala) at work, and I just hate it.

      - SBT is super slow compared to maven
      - Compiling a play 2 app is slow
      - IDE integration is quite bad

After a year, I would definitely not recommend Play 2, or SBT on a Java project.

My choice when using Java today would be Dropwizard, although I haven't deployed anything in production using it, I tested it for a couple hours, and I think it's the best combination of libraries.

One thing I definitely agree on, is to use Docker if possible. We use it for almost everything at work, and it improves our deployment speed, it gives us more flexibility and local/CI testing is now super easy. In case you deploy with Docker, using only environment variables for configuration is great, that way you can control the configuration directly via the docker command line. With Java a good library for this use case is Typesafe's config, which can automatically use environment variables.

<comment><USER28> SBT is probably the best example of the total immaturity of the Scala community in terms of real-world engineering. Hey, we're building for the JVM, we've got Maven, it's arguably the best solution in any language for a very difficult problem that has stopped entire language ecosystems in their tracks. Let's rewrite it, from scratch, using unproven concepts! And put 'simple' in the title!

Afterwards, we'll call XML ugly and claim to be more 'functional', without even noticing that Maven's pom format is actually a nested s-expression structure that happens to use angle brackets.

<comment><USER29> > we've got Maven, it's arguably the best solution in any language for a very > difficult problem that has stopped entire language ecosystems in their > tracks

Wait wut? Are you drunk? :-)

My experience is that SBT works great, while Maven tries to fight you at every step. SBT developers try to help you get you work done, while questions in the Maven community are usually answered with bullshit responses.

Maven (like Eclipse) are a great example of what's wrong in the Java community.

<comment><USER28> Not yet. You wanna show me the better solution than Maven? Something that manages multi-module projects, with various versions of dependencies, and packaging as war/jar/tgz/whatever?

I've probably spent way more time cursing Maven than praising it, but that's the nature of a build/packaging/dependency tool, it's like a sysadmin, you're either not noticing it's there or cursing its parental lineage.

What's SBT offer over maven? Lack of XML, with more trendy markup and new bugs? Like I said, immature.

<comment><USER29> > What's SBT offer over maven? Lack of XML, with more trendy markup and new > bugs? Like I said, immature.

Maybe you should do some research and figure out the answer for yourself, then you wouldn't jump to weird conclusions.

<comment><USER28> If you're motivated to wade this far down the thread, but can't be bothered to explain one concrete benefit in one sentence, I've gotta assume it's pretty difficult to come up with one.

<comment><USER29> It's pretty easy to come up with multiple ones.

Just one, to not prevent you from doing your own research:

Type-checked build definitions.

I lost days to debugging broken Maven setups were some tags were misspelled or placed at the wrong position, and Maven just gave a shit about it.

SBT immediately tells you what's the issue.

Another one: It's completely painless to introduce new settings/keys/commands/tasks. Want to have a deployment step which moves some files to the right place after compilation? 3 lines of code. 3 lines, not a god damn Maven plugin.

<comment><USER28> Well, we seem to disagree on the usefulness of those items and the quality of SBT's solutions vs the pain of rebuilding an entire new build/deployment stack and fighting through all the bugs you've created.

We'll just have to see how history unfolds. IMO sbt already hit the high-water mark and is receding, lots of shops using scala today advocate using mvn.

EDIT: You inspired me to do some research. Apparently, senior engineers from typesafe do hour-long presentations named "Effective SBT" at Scala Dayz conferences. Truly the simplest of build tools.

<comment><USER29> > IMO sbt already hit the high-water mark and is receding, lots of shops using > scala today advocate using mvn.

I haven't seen that at all in practice. I think that's just a bit of noise on the internet.

SBT keeps getting better, and many shops which originally opted to stay with Maven are now moving to SBT, because it's just so much better than Maven.

Not sure what your problem is. Even back in the 0.7 days, SBT was better than Maven. I'll change profession before I ever move back to Maven.

Oh, let's have a look what that "senior Typesafe" guy has to say about SBT vs. Maven:

      Well, coming from first contributing to the maven-scala-
      plugin, then eclipse, then sbt itself, I can tell you that
      some of the things we do in sbt just fundamentally won't
      work in Maven, otherwise I'd have tried them.
      If you'd like my branch list of broken experiments, I can
      share them, but be assured that I personally was an sbt
      hater before learning the tool.

      All of the complaints of syntax and documentation DO
      represent a younger project vs. a more mature one.
      However, architecturally, I'm placing my money on sbt over
      maven.  THat's not to say sbt is perfect, but I think most
      of these complaints are adressible.

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER30> Someone could argue that Java and PHP suck because there are a lot of people who use them wrongly. Linus Torvalds made a similar argument for not using C++: [http://article.gmane.org/gmane.comp.version- control.git/5791...](http://article.gmane.org/gmane.comp.version- control.git/57918/)

<comment><USER31> I would agree with that, though perhaps more about PHP than Java. We like to say "use the right tool for the job" and "you can write bad code in any language", but that's just a way of seeming egalitarian and not really dealing with the issue. It feels bad to talk about shitty programmers but they're kind of a problem.

</comment></comment><comment><USER31> It is only tangentially related, but I recommend this video from Brian Geotz, a Java language architect. He breaks down the challenges of adding features to the language, in a room full of Clojure devs no less. Worth a watch: [https://www.youtube.com/watch?v=2y5Pv4yN0b0](https://www.youtube.com/watch?v=2y5Pv4yN0b0)

</comment><comment><USER32> Who said Java sucks? The Java "language" is just too verbose for my liking, but the Java as a toolset is very powerful. Been using it for Big Data.

<comment><USER33> Agreed about the verbosity and Java 8 is only making the situation worse. I've been a Clojure enthusiast for a number of years now, but I was hoping there would be less of a need to use other JVM languages with Java 8 and Streams. I find working with Streams to be 3 steps forward and 2 back. The syntax (as usual) is cumbersome, and add a layer of generics on top of that and you have somewhat of a mess. I also find interop with traditional Java Collections to be annoying though maybe I am not following (yet to be discovered) best practices for dealing with Streams.

Edit: Ohh and BTW, if you ever have the opportunity to see James Ward speak in person, do so. He is a great presenter, and a regular cast member at the Boulder Java User Group.

</comment></comment><comment><USER34> > If your app needs a relational database then use an in-memory db like hsql > or cloud services like Heroku Postgres, RDS, Redis Labs, etc. However one > risk with most in-memory databases is that they differ from what is used in > production. JPA / Hibernate try to hide this but sometimes bugs crop up due > to subtle differences. So it is best to mimic the production services for > developers even down to the version of the database.

The idea that you can develop locally or test against a different type of database then what you are (or will be) using in production is silly. I don't just think it "sometimes" is a bad idea, I reject it outright. You should always be using the exact same database (type and version).

For cloud deployments most XaaS providers have cheap or free dev tiers. For local development it's easy to use VMs. For any project that requires external resources (Postgres, Redis, RabbitMQ, etc) I have a VM that gets spun up via Vagrant[1]. Just "vagrant up" and all external resources required by the app should be available.

> So first… Use a build tool. It doesn't matter if you choose Ant + Ivy, > Maven, Gradle, or sbt. Just pick one and use it to automatically pull your > dependencies from Maven Central or your own Artifactory / Nexus server. With > WebJars you can even manage your JavaScript and CSS library dependencies. > Then get fancy by automatically denying SCM check-ins that include Jar > files.

Though I agree that it's a good idea to have dependencies externalized, it's not always possible. Some libraries (ex: third party JARs) are not available in public Maven repos and not everyone has a private one setup. In those situations it's fine to check in the JAR into the project itself.

I like the approach outlined by Heroku for dealing with unmanaged dependencies[2]. You declare them normally in your pom.xml but also include the path to a local directory (checked into SCM) with the JAR files. Anybody that clones your repo should be able to build the project with no manual steps. Works great!

[1]: [https://www.vagrantup.com/](https://www.vagrantup.com/)

[2]: [https://devcenter.heroku.com/articles/local-maven- dependenci...](https://devcenter.heroku.com/articles/local-maven-dependencies)

</comment><comment><USER35> I think an important lesson for web application development—mentioned in the article—is keeping the server stateless, moving state into the client, and using a real middleware like Redis for the session cache.

</comment><comment><USER36> I'm a .NET developer and I love C# & Visual Studio but have worked some with Java. Most of his arguments sounded to me like- "Just do _complex-sounding long list of steps_ , it's easy!" Java development seems like a massive pain, and too much time not actually spent on development.

<comment><USER37> Maybe it's my similar background, but that's how I read it as well.

My TL;DR summary of that article is "Java doesn't suck, as long as you use enough tools, libraries and workarounds to avoid actually using Java."

</comment></comment><comment><USER38> >Clojure: The lack of some OO constructs makes managing a large code base challenging

I would be intrested in what his problem is. The only thing that I can think of is subtyping and Im not sure how subtyping helps managing organisation.

Clojures namespacing is pretty nice, it might be a bit to complicated but it does everything you need.

<comment><USER39> And if you're just learning, sticking to the

        (ns hn.comment
           (:require [clojure.string :as str]))

syntax is a good bet.

</comment></comment><comment><USER40> all of his points except for one are related to the jvm in general, which most people agree doesn't suck, and then when it is time to address java he just says "scala, clojure.. are great" Yes, thats the point. The JVM is well liked, but Java as a language is not, and I don't think he did much to change anyones opinion.

<comment><USER41> I do not agree that JVM does not suck. It sucks badly. No tail calls support, no (optional and confined) unsafe pointer arithmetics, no value types and a pathetic limit on a method size makes it an extremely shitty target for any language other than Java. All the existing languages running on top of JVM are very, very inefficient, or have to pay a horrible price for being able to run reasonably fast (crap like `recur` in Clojure, for example).

edit: I suspect that none of the downvoters ever implemented a single compiler targeting JVM.

<comment><USER42> > No tail calls support

Is there a good reason for VMs to support TCO rather than having compilers perform it?

> no (optional and confined) unsafe pointer arithmetics

When do you want this? There's sun.misc.Unsafe#setMemory if you really need it.

> no value types

Might be added in JVMS 10 or some version thereafter.

> a pathetic limit on a method size makes it an extremely shitty target for > any language other than Java.

True.

> All the existing languages running on top of JVM are very, very inefficient, > or have to pay a horrible price for being able to run reasonably fast (crap > like `recur` in Clojure, for example).

Fair enough, but it wasn't designed as a general purpose compilation target like llvm.

<comment><USER41> > Is there a good reason for VMs to support TCO rather than having compilers > perform it?

Again this word! Proper tail calls handling is not an "optimisation". Optimisations are supposed to be optional, while tail calls handling makes a _semantic_ difference.

And, no, compilers cannot do it statically. You cannot statically resolve virtual calls, for example. Consider the following trivial case:

`(define (f g x) (g x))`

> When do you want this? There's sun.misc.Unsafe#setMemory if you really need > it.

Try implementing, say, an STG efficiently. Or even a WAM.

> Might be added in JVMS 10 or some version thereafter.

JVM may start to suck less at some point. But now it sucks.

> but it wasn't designed as a general purpose compilation target like llvm.

Exactly. And that's why it's inferior to the other VMs, which were designed with multiple source language semantics in mind. Including even CLR.

</comment></comment></comment></comment><comment><USER43> Java itself was once so popular that a completely unrelated programming language, javascript, had java in its name to ride the coat-tails of its popularity.

The culture and behaviors that have grown up around it though make it easy for people to fall into holes. (Both technical and non-technical, e.g. hiring culture)

It's like if a minefield existed via the path of Java and people said "There's no way through this minefield." And another retorts "Of course there is a path! Just go through it carefully, learn the topology, and it's just as fast as sprinting across an open meadow."

<comment><USER44> Are you talking of java? It reads like PHP to me

</comment></comment><comment><USER45> One of the few big problems I have with Java is that you can't use anonymous classes as real closures like it intuitively looks like you should be able to.

</comment><comment><USER46> I haven't used Java for a long time myself - and am not up to date with it's current featureset. I know I used to like coding in Java back in 2000/2001, but my professional career demanded switching to C/C++ - which I did and also said goodbye to a few years ago.

Anyway - something I posted yesterday in the "Java for everything" thread here:

> My view of Java may be a bit biased, since I also tend to look at things > from the sysadmin pov nowadays. I can only tell that I never disliked Java > until I had to take care of the monstrosities the Java developers bring to > life, and mind you - I started out as a Java dev back in 2000. > > The main > issue I have with Java is the JVM and memory usage and leaks. No matter what > people claim - no memory leaks in Java is a fairy-tale. We run both custom > C++ and Java services (about 50/50) on a few hundred servers - and I cannot > find a single issue in our ticketing system related to memory problems with > any of our C++ services. Java services? Every. Single. Week. When I get an > alert some JBoss unexpectedly died or became unresponsive - > "java.lang.OutOfMemoryError" is most likely going to be the problem. A lot > of those are permgen space errors, and yes you can try all the "fixes" like > increasing the permgenspace, permgensweeping, enabling class unloading, ... > but these don't always fix the problem and slow down your services. Every > time this happened in our own services, this had to be fixed by our > developers. It takes weeks to locate the problem, and you end up deploying > new versions, upgrading JBoss, JSF, Bouncycastle, ... whatever.

After a while dealing with crap like this - you start avoiding projects using the JVM (although elasticsearch is pretty nice)

</comment><comment><USER47> If I'm reading this correctly, it just boils down to "use the right tools and Java won't suck" which is something that can be argued for most programming languages. This is fine and all, but one of the problems for new programmers (the majority of languages comparers) is that learning what Java toolset to use is a huge hurdle. Java's diverse ecosystem and long history hurt its image by making it seem like a hulking monstrosity that is reserved for enterprises. Combine this with the verbose syntax and any cursory glance at Java will drive most new programmers away. Compare this with other languages that do not suffer from such a poor image and it becomes easy to see why people often say, "Java sucks."

What I wonder is if the following exists:

* A simple/clean tutorial that introduces a developer to the most common tool chain (perhaps various tutorials for different use cases - web, desktop apps, gamedev, etc.).

* Instructions that don't just name drop, as this article does, but instead gives concrete examples that lead to a fully functional work environment. Perhaps one that works as this author describes - scripts to setup dev environments, deployment, CI, etc.

* Advanced instructions that point you to documentation in the case that you need to go beyond a simple work environment.

* A comparison of various tools in the Java ecosystem that compares the use cases and, more importantly, gives examples of how various tools would be effectively used together.

One of the reasons why I personally find Java to "suck" is because the friction involved in getting up and running in an efficient manner is far greater than that of other programming languages. I think that rather than write such an article defending Java, it would be much better to create a beginner resource that can onboard developers easily.

</comment><comment><USER48> > _Servers That Take More Than 30 Seconds to Start Suck_

> _For developer productivity and so that scaling up can happen instantly, > servers should startup quickly._

Of course, a Java programmer takes it for granted that you restart things every time you change code. But that sucks.

Servers _should_ start up quickly. Well, what if they don't? What if they don't for some good reason?

<comment><USER49> > Of course, a Java programmer takes it for granted that you restart things > every time you change code. But that sucks.

Did you not read to the section about jRebel/Play and not needing to restart?

But I do agree with you that server startup time isn't as big a deal if you don't have to restart after each change.

<comment><USER50> These makes some debugging tricky because of the indirections the frameworks introduce and also comes with performance hit.

A long start up time makes more difficult your integration/functional tests that it should.

<comment><USER51> JRebel IDE plugins integrate with your IDE debugger to hide the indirection from you. Works for me. If it does not work for you (or the performance hit is non-negligible) then I suggest you contact their support, they usually fix stuff in couple of days (from my personal experience).

And, AFAIK, Play! is also fully debuggable. What's bothering you?

<comment><USER50> Yes, the IDE hides the indirections, but not in the bytecode. I mean when I need to profile or debug the binary and optimise e.g. the GC or the heap usage, I am stucked, right?

</comment></comment></comment></comment></comment><comment><USER52> " _Decoupled Schema & Code Changes: When schema changes and code changes depend on each other rollbacks are really hard. Decoupling the two isolates risk and makes it possible to go back to a previous version of an app without having to also figure out what schema changes need to be made at the same time._"

I'd really like to know how you do that.

<comment><USER53> Generally you would use an expand/contract migration pattern.

You deploy a schema expansion so that both the new and old code will run, deploy the new code, and once the new code has been validated you deploy a schema contraction.

[http://exortech.com/blog/2009/02/01/weekly-release- blog-11-z...](http://exortech.com/blog/2009/02/01/weekly-release-blog-11-zero- downtime-database-deployment/)

<comment><USER52> That's what I came up with, too. But it's still coupled: you can't "go back to a previous version of an app without having to also figure out what schema changes need to be made", post-validation, anyway.

</comment></comment></comment><comment><USER54> I love Java. When used correctly it's a very powerful language that is easy to run in many environments. I choose it for any personal project that I can see growing beyond a few small scripts.

I hate Java culture. Too much Enterprise Java is filled with SomeThingImpl, MyModelDAO, SomeShittyBean, and magical XML configurations. I don't know how things got this way (I haven't been around long enough) but there is no reason Java the language has to be attached to this nonsense. I totally understand why people take one look at a modern Java codebase and swear off the language forever.

For me though, Java is the mainstream language that I find makes me most likely to be correct the first time I write a program. Yes that comes with verbosity. Yes that means I have to use a RAM-hungry IDE. But I write code that runs fast and correctly the first time. I love that.

TL;DR - Java (The Language) != Java (The Culture)

<comment><USER55> Exactly. Java is fine if you just write plain-old classes. It's when you overuse patterns and try to make everything hyper pluggable/configurable with XML-based dependency injection that it becomes a disgusting slog.

I write Java that is 100% "Plain Old Java Objects" and it is just fine. Keep it simple.

</comment></comment><comment><USER56> "#1 Install the JDK"

No developer should install JDK, it's a mess, madness and risk for crapware. Just use the JDK zip/tar.gz for that one specific project.

Even for distributing java apps I find it much easier to bundle JRE with the app and never ask for the devop or end user install it separately. The license for bundling is quite permissive [1] and bundling can be also used for os x apps [2].

[1] [http://www.oracle.com/technetwork/java/javase/jre-8-readme-2...](http://www.oracle.com/technetwork/java/javase/jre-8-readme-2095710.html) [2] [https://docs.oracle.com/javase/jp/8/technotes/guides/jweb/pa...](https://docs.oracle.com/javase/jp/8/technotes/guides/jweb/packagingAppsForMac.html)

</comment><comment><USER57> > Groovy > * Great > * * Simple language with a few very useful features

Simple? Have you seen Codehaus Groovy's grammar?...

[http://svn.codehaus.org/groovy/trunk/groovy/groovy- core/src/...](http://svn.codehaus.org/groovy/trunk/groovy/groovy- core/src/main/org/codehaus/groovy/antlr/groovy.g)

That's from 2007 and more's been added since. What hasn't changed is it's still in Antlr 2 whereas the latest version of Antlr is version 4. Groovy's not simple, it's an obsolete dinosaur.

</comment><comment><USER58> _So first… Use a build tool. It doesn't matter if you choose Ant + Ivy, Maven, Gradle, or sbt_

To me, that's part of the problem. The Java ecosystem seems diverse to a fault.

<comment><USER59> Most platforms have pretty fragmented build tooling. I think an exception might be Go because it has the build tool built into the platform.

</comment></comment><comment><USER60> Suddenly I'm reading Java-come-back articles, which is nice. That convinced me to some extent I should learn Java more for serious coding, instead of spending the same time on php/python/javascript. Not saying the rest languages are bad, but life is too short to get good on all of them.

Also Java is important for android.

<comment><USER61> Satire?

</comment></comment><comment><USER62> I'm not sure about the "Useless Blocking Sucks" paragraph, it's very opinionated and using the play framework in production is nothing I would recommend for enterprise deployments. The technology is still very immature and I do not see that the overhead of an extra thread per request would matter.

<comment><USER63> How is it immature? It is used in enterprises already, and they seem to like it.

</comment></comment><comment><USER64> His last note should have been his first; it's the Java environment that doesn't suck in any magnitude more than other environments, and has oodles of benefits for getting Serious Business done. You now have your choice of language with which you can enjoy the rock-steady JVM/JDK-library environment.

</comment><comment><USER65> >>Spend a couple evenings or weekends working on implementing one of these items. Then show your manager what you did in your own time (that will convey how much you care) and then let them take the credit for the amazing new thing they thought of.

Why would someone want to do that , unless its someone's personal project?

<comment><USER66> If the expected cost of interviewing for and finding a new job where these things are already in place is greater than the cost of a couple evenings or weekends to add those features to the current work environment.

</comment></comment><comment><USER67> Java has some problems. I would contend that using the wrong tool for the job == using the tool wrong. Java has its place, but overall there is a better, more specialized solution in most instances that doesn't have some of Java's (pretty hideous) warts.

</comment><comment><USER68> This article reads like an advertisement for play2. I created apps with play 1 and when play 2 was released I was quite excited hoping for things to get even better. Unfortunately the authors like Guillaume Bort and some others found love for Scala. Now the core framework is written in scala and play feels like a scala framework even though they added some Java Apis. The last time I checked play2 out there were conceptual inconsistencies between scala and java flavors of play2. For example Java comes with a hipster ORM (ebean) and Scala has a completely different almost non ORM flavor called anorm. Also IDE Support for play2 java flavor sucks. The biggest advantage of playframework was to have an agile framework like rails in the java world. This advantage has gone.

</comment><comment><USER69> SharePoint doesn't suck you're just using it wrong..

</comment><comment><USER70> From the article:

        The Java Language Kinda Sucks

</comment><comment><USER71> Listed without no further _text_ on the Clojure's _bad parts_ : "Dynamic typing".

That's very very debatable, don't you think mr. Ward?

<comment><USER59> Definitely. Which is why I labelled that section as my opinions. :)

<comment><USER71> _Touche_ :)

I guess I just felt bad to see all those great bulleted itens with some nice phrasing around and then to see my dear _Dynamic Typing_ there, alone, without any adjective. No love, no hate, simply emotionless "Bad" :(

<comment><USER59> Good point. I should have put more details in there. I prefer static typing with good type inference because it allows me to have a compiler validate a lot of my code pre-runtime. Otherwise I'm left with tests and actually running all of the code to do that validation. The value of this for large code bases has been worth the tradeoffs in my experience. But since this is one of the most debated things in programming I don't expect to sway anyone. I'm happy to leave this as an item of "it depends" / personal preference.

</comment></comment></comment></comment><comment><USER72> As a side note, I can still remember how nice it felt to use Java in the mid- nineties coming from C++.

</comment><comment><USER73> People, we are in 2014 and still discussing what programming language is better.

<comment><USER74> 2014 is not the future. It's not even a big number.

The world we live in is actually quite primitive. That's why people who _care_ about things keep bringing them up.

<comment><USER73> I believe languages war is not a good problem to spend energy.

<comment><USER74> Every worthwhile achievement in human history has been as a result of our mastery of language.

</comment></comment></comment></comment><comment><USER75> totally agree. What about testing EJBs?, it was painful for me, it took me many hours.

<comment><USER76> People still use EJBs? What, are we still listening to Gorillaz?

<comment><USER77> I still listen to Gorillaz, but I don't use EJBs.

</comment></comment></comment><comment><USER78> Because we needed an article to clear this up.

:P

</comment><comment><USER79> No really, Java the language is bad. Terrible in fact.

The fact I need an IDE to make it workable (just) highlights this point. J2EE was terrible too, because it showed where things can go, if you let the Java astronaut architects lead.

Some of my most profitable projects were helping to rescue systems by migrating to to an alternative language on the JVM, or off it completely.

The worst part is the damage Java inflicted upon a generation of developers.

I have a problem, I think I will use Java, and Eclipse, and Maven, and all the rest. Now I have twenty thousand problems!

Edit - if you disagree, then say so. Bit spineless to downvote without a valid point to back it up!

<comment><USER80> Speaking of spineless, did you really need a throwaway just to say Java sucks?

<comment><USER81> As HN has grown it has attracted a more vocal contingent of Java developers. It's getting progressively harder to criticize the language without somebody shouting you down.

<comment><USER82> It seems the anti-Java ones are the more vocal ones most of the time. You see the anti-Java posts all the times.

<comment><USER81> Those of us who are recovering Java programmers might say there's a good reason for that. :-)

<comment><USER82> Are you insecure about your new found favorite language that you have to bash the old one that you didn't have much success with to justify your new choice? If you are really happy with your new favorite language, great. Do good work with it and move on. No need to keep smearing the old one.

<comment><USER81> Heh, no. Your comment didn't seem rhetorical so I was just providing an explanation for the phenomenon you've observed. However, we do engage in much spirited discussion throughout the software world about the relative merits of various languages and their features. There's no getting away from it, and Java's gonna get beat on until the end of time. Hope you don't take it personally.

<comment><USER82> None taken. If those frequent "spirited discussion" soothed your ego, by all means increase the weekly Java bashing. Meanwhile we just keep making software with it.

<comment><USER81> It's not about ego, it's about taste. Specifically the tastes of the majority of HN.

Sure, lots of software gets written in Java. And (less so) Cobol and Fortran. Every sensitive Java (and PHP, etc) user who is on HN and feels compelled to respond to every slight has to understand, though:

HN was founded by the guy who wrote Beating the Averages[0].

We're in PG's house. And he never liked Java.

So if Java fans come here with a chip on their shoulder about it and constantly take the bait and get into flamewars about how solid and adequate their language is, they should remember what forum they're in. Not that opinions in the forum can't be changed, but why bother when there's plenty of Java love out there elsewhere?

[0] [http://www.paulgraham.com/avg.html](http://www.paulgraham.com/avg.html)

<comment><USER82> So it's basically herd mentality with reinforced in-group cliche. Just because PG started HN, we all have to toe the party line to bash Java? If you think PG cared about everyone here has to agree and follow his opinion, you paint him a very shallow man.

And I think he's naive in that blog in using single language as a criteria to evaluate developers, but there's another story.

<comment><USER81> No, I'm just saying that like attracts like. If PG starts anything involving programmers, a lot of them are going to share a number of his opinions on the topic, because they self-select that way. So HN is naturally going to be dominated by those who dislike Java.

You can keep responding to that dislike, but on HN, given its natural audience, staking out much of a pro-Java position is doomed to futility.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER83> Yes, it does.

</comment><comment><USER84> > If you need some ammunition to prove to your management that your startup > times are killing your team's productivity then use the stopwatch on your > phone to count the total minutes per day wasted by waiting for the app to > start.

But... what about my sword-fighting

</comment><comment><USER85> Wow makes me dislike Java even more lol @jamesward

</comment><comment><USER31> I agree with the article -- as it says, "The Java Language Kinda Sucks" :)</comment>


Interview with entrepreneur turned venture capitalist Josh Kopelman - <AUTHOR> http://obsessedtv.com/2009/06/samantha-ettus-interviews-venture-capitalist-josh-kopelman/ <comment><USER2> This is a great story of Josh's career and worth watching. Especially the first 15 minutes which are stories I'd never heard before (and I live in Philadelphia).

I second his comments that Philadelphia is a fantastic place to live/work as an entrepreneur. The tech/startup community is humble, helpful, and extremely tight. This community combined with the art, history, and diversity of Philadelphia make it an awesome place to live.</comment>


Whats Going On, Amazon? - <AUTHOR> http://muchinlearning.com/blog/whats-going-on-amazon/ <comment><USER2> My guess would be that Amazon has some algorithm to flag reviewers with odd review patterns. Things like only reviewing products from one manufacturer, or only reviewing new products, or other things like that would potentially indicate a bot.

And so the bot makers have gotten around this by having their bots have a more human-like pattern of reviews. Reviewing a product that already has a lot of reviews makes the bot seem more human.

</comment><comment><AUTHOR> I was on Amazon to buy the book 'Getting Things Done' by David Allen. And I stumbled onto some really odd reviews that didn't make sense. So I parsed the reviews and did some basic analysis.</comment>


Happy Birthday, Objective-C - <AUTHOR> http://blog.securemacprogramming.com/?p=713

<comment><USER2> Error establishing a database connection...</comment>